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}