001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.data;
003
004import static org.openstreetmap.josm.tools.I18n.tr;
005
006import java.io.IOException;
007import java.io.InputStream;
008import java.util.Map.Entry;
009import java.util.Properties;
010
011import org.openstreetmap.josm.Main;
012import org.openstreetmap.josm.tools.LanguageInfo;
013
014/**
015 * Provides basic information about the currently used JOSM build.
016 *
017 */
018public class Version {
019    /** constant to indicate that the current build isn't assigned a JOSM version number */
020    public static final int JOSM_UNKNOWN_VERSION = 0;
021
022    /** the unique instance */
023    private static Version instance;
024
025    /**
026     * Replies the unique instance of the version information
027     *
028     * @return the unique instance of the version information
029     */
030    public static synchronized Version getInstance() {
031        if (instance == null) {
032            instance = new Version();
033            instance.init();
034        }
035        return instance;
036    }
037
038    private int version;
039    private String releaseDescription;
040    private String time;
041    private String buildName;
042    private boolean isLocalBuild;
043
044    /**
045     * Initializes the version infos from the revision resource file
046     *
047     * @param revisionInfo the revision info from a revision resource file as InputStream
048     */
049    protected void initFromRevisionInfo(InputStream revisionInfo) {
050        if (revisionInfo == null) {
051            this.releaseDescription = tr("UNKNOWN");
052            this.version = JOSM_UNKNOWN_VERSION;
053            this.time = null;
054            return;
055        }
056
057        Properties properties = new Properties();
058        try {
059            properties.load(revisionInfo);
060            revisionInfo.close();
061        } catch (IOException e) {
062            Main.warn(tr("Error reading revision info from revision file: {0}", e.getMessage()));
063        }
064        String value = properties.getProperty("Revision");
065        if (value != null) {
066            value = value.trim();
067            try {
068                version = Integer.parseInt(value);
069            } catch (NumberFormatException e) {
070                version = 0;
071                Main.warn(tr("Unexpected JOSM version number in revision file, value is ''{0}''", value));
072            }
073        } else {
074            version = JOSM_UNKNOWN_VERSION;
075        }
076
077        // the last changed data
078        //
079        time = properties.getProperty("Last Changed Date");
080        if (time == null) {
081            time = properties.getProperty("Build-Date");
082        }
083
084        // is this a local build ?
085        //
086        isLocalBuild = false;
087        value = properties.getProperty("Is-Local-Build");
088        if (value != null && "true".equalsIgnoreCase(value.trim()))  {
089            isLocalBuild = true;
090        }
091
092        // is this a specific build ?
093        //
094        buildName = null;
095        value = properties.getProperty("Build-Name");
096        if (value != null && !value.trim().isEmpty())  {
097            buildName = value.trim();
098        }
099
100        // the revision info
101        //
102        StringBuilder sb = new StringBuilder();
103        for (Entry<Object, Object> property: properties.entrySet()) {
104            sb.append(property.getKey()).append(':').append(property.getValue()).append('\n');
105        }
106        releaseDescription = sb.toString();
107    }
108
109    /**
110     * Initializes version info
111     */
112    public void init() {
113        InputStream stream = Main.class.getResourceAsStream("/REVISION");
114        if (stream == null) {
115            Main.warn(tr("The revision file ''/REVISION'' is missing."));
116            version = 0;
117            releaseDescription = "";
118            return;
119        }
120        initFromRevisionInfo(stream);
121    }
122
123    /**
124     * Replies the version string. Either the SVN revision "1234" (as string) or the
125     * the I18n equivalent of "UNKNOWN".
126     *
127     * @return the JOSM version
128     */
129    public String getVersionString() {
130        return  version == 0 ? tr("UNKNOWN") : Integer.toString(version);
131    }
132
133    /**
134     * Replies a text with the release attributes
135     *
136     * @return a text with the release attributes
137     */
138    public String getReleaseAttributes() {
139        return releaseDescription;
140    }
141
142    /**
143     * Replies the build date as string
144     *
145     * @return the build date as string
146     */
147    public String getTime() {
148        return time;
149    }
150
151    /**
152     * Replies the JOSM version. Replies {@link #JOSM_UNKNOWN_VERSION} if the version isn't known.
153     * @return the JOSM version
154     */
155    public int getVersion() {
156        return version;
157    }
158
159    /**
160     * Replies true if this is a local build, i.e. an inofficial development build.
161     *
162     * @return true if this is a local build, i.e. an inofficial development build.
163     */
164    public boolean isLocalBuild() {
165        return isLocalBuild;
166    }
167
168    /**
169     * Returns the User-Agent string
170     * @return The User-Agent
171     */
172    public String getAgentString() {
173        return getAgentString(true);
174    }
175
176    /**
177     * Returns the User-Agent string, with or without OS details
178     * @param includeOsDetails Append Operating System details at the end of the User-Agent
179     * @return The User-Agent
180     * @since 5956
181     */
182    public String getAgentString(boolean includeOsDetails) {
183        int v = getVersion();
184        String s = (v == JOSM_UNKNOWN_VERSION) ? "UNKNOWN" : Integer.toString(v);
185        if (buildName != null) {
186            s += ' ' + buildName;
187        }
188        if (isLocalBuild() && v != JOSM_UNKNOWN_VERSION) {
189            s += " SVN";
190        }
191        String result = "JOSM/1.5 ("+ s+' '+LanguageInfo.getJOSMLocaleCode()+")";
192        if (includeOsDetails && Main.platform != null) {
193            result += ' ' + Main.platform.getOSDescription();
194        }
195        return result;
196    }
197
198    /**
199     * Returns the full User-Agent string
200     * @return The User-Agent
201     * @since 5868
202     */
203    public String getFullAgentString() {
204        return getAgentString() + " Java/"+System.getProperty("java.version");
205    }
206}