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 } catch (IOException e) { 061 Main.warn(e, tr("Error reading revision info from revision file: {0}", e.getMessage())); 062 } 063 String value = properties.getProperty("Revision"); 064 if (value != null) { 065 value = value.trim(); 066 try { 067 version = Integer.parseInt(value); 068 } catch (NumberFormatException e) { 069 version = 0; 070 Main.warn(tr("Unexpected JOSM version number in revision file, value is ''{0}''", value)); 071 } 072 } else { 073 version = JOSM_UNKNOWN_VERSION; 074 } 075 076 // the last changed data 077 // 078 time = properties.getProperty("Last Changed Date"); 079 if (time == null) { 080 time = properties.getProperty("Build-Date"); 081 } 082 083 // is this a local build ? 084 // 085 isLocalBuild = false; 086 value = properties.getProperty("Is-Local-Build"); 087 if (value != null && "true".equalsIgnoreCase(value.trim())) { 088 isLocalBuild = true; 089 } 090 091 // is this a specific build ? 092 // 093 buildName = null; 094 value = properties.getProperty("Build-Name"); 095 if (value != null && !value.trim().isEmpty()) { 096 buildName = value.trim(); 097 } 098 099 // the revision info 100 // 101 StringBuilder sb = new StringBuilder(); 102 for (Entry<Object, Object> property: properties.entrySet()) { 103 sb.append(property.getKey()).append(':').append(property.getValue()).append('\n'); 104 } 105 releaseDescription = sb.toString(); 106 } 107 108 /** 109 * Initializes version info 110 */ 111 public void init() { 112 try (InputStream stream = Main.class.getResourceAsStream("/REVISION")) { 113 if (stream == null) { 114 Main.warn(tr("The revision file ''/REVISION'' is missing.")); 115 version = 0; 116 releaseDescription = ""; 117 return; 118 } 119 initFromRevisionInfo(stream); 120 } catch (IOException e) { 121 Main.warn(e); 122 } 123 } 124 125 /** 126 * Replies the version string. Either the SVN revision "1234" (as string) or the 127 * the I18n equivalent of "UNKNOWN". 128 * 129 * @return the JOSM version 130 */ 131 public String getVersionString() { 132 return version == 0 ? tr("UNKNOWN") : Integer.toString(version); 133 } 134 135 /** 136 * Replies a text with the release attributes 137 * 138 * @return a text with the release attributes 139 */ 140 public String getReleaseAttributes() { 141 return releaseDescription; 142 } 143 144 /** 145 * Replies the build date as string 146 * 147 * @return the build date as string 148 */ 149 public String getTime() { 150 return time; 151 } 152 153 /** 154 * Replies the JOSM version. Replies {@link #JOSM_UNKNOWN_VERSION} if the version isn't known. 155 * @return the JOSM version 156 */ 157 public int getVersion() { 158 return version; 159 } 160 161 /** 162 * Replies true if this is a local build, i.e. an inofficial development build. 163 * 164 * @return true if this is a local build, i.e. an inofficial development build. 165 */ 166 public boolean isLocalBuild() { 167 return isLocalBuild; 168 } 169 170 /** 171 * Returns the User-Agent string 172 * @return The User-Agent 173 */ 174 public String getAgentString() { 175 return getAgentString(true); 176 } 177 178 /** 179 * Returns the User-Agent string, with or without OS details 180 * @param includeOsDetails Append Operating System details at the end of the User-Agent 181 * @return The User-Agent 182 * @since 5956 183 */ 184 public String getAgentString(boolean includeOsDetails) { 185 int v = getVersion(); 186 String s = (v == JOSM_UNKNOWN_VERSION) ? "UNKNOWN" : Integer.toString(v); 187 if (buildName != null) { 188 s += ' ' + buildName; 189 } 190 if (isLocalBuild() && v != JOSM_UNKNOWN_VERSION) { 191 s += " SVN"; 192 } 193 String result = "JOSM/1.5 ("+ s+' '+LanguageInfo.getJOSMLocaleCode()+')'; 194 if (includeOsDetails && Main.platform != null) { 195 result += ' ' + Main.platform.getOSDescription(); 196 } 197 return result; 198 } 199 200 /** 201 * Returns the full User-Agent string 202 * @return The User-Agent 203 * @since 5868 204 */ 205 public String getFullAgentString() { 206 return getAgentString() + " Java/"+System.getProperty("java.version"); 207 } 208}