001/** 002The contents of this file are subject to the Mozilla Public License Version 1.1 003(the "License"); you may not use this file except in compliance with the License. 004You may obtain a copy of the License at http://www.mozilla.org/MPL/ 005Software distributed under the License is distributed on an "AS IS" basis, 006WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the 007specific language governing rights and limitations under the License. 008 009The Original Code is "Version.java". Description: 010"An enumeration of supported HL7 versions" 011 012The Initial Developer of the Original Code is University Health Network. Copyright (C) 0132012. All Rights Reserved. 014 015Contributor(s): ______________________________________. 016 017Alternatively, the contents of this file may be used under the terms of the 018GNU General Public License (the "GPL"), in which case the provisions of the GPL are 019applicable instead of those above. If you wish to allow use of your version of this 020file only under the terms of the GPL and not to allow others to use your version 021of this file under the MPL, indicate your decision by deleting the provisions above 022and replace them with the notice and other provisions required by the GPL License. 023If you do not delete the provisions above, a recipient may use your version of 024this file under either the MPL or the GPL. 025 */ 026package ca.uhn.hl7v2; 027 028import java.io.IOException; 029import java.io.InputStream; 030import java.util.*; 031 032import ca.uhn.hl7v2.model.GenericMessage; 033import ca.uhn.hl7v2.parser.ModelClassFactory; 034import ca.uhn.hl7v2.parser.Parser; 035 036public enum Version { 037 038 V21("2.1"), // - 039 V22("2.2"), // - 040 V23("2.3"), // - 041 V231("2.3.1"), // - 042 V24("2.4"), // - 043 V25("2.5"), // - 044 V251("2.5.1"), // - 045 V26("2.6"), // - 046 V27("2.7"), // - 047 V271("2.7.1"), // - 048 V28("2.8"), // - 049 V281("2.8.1"); // - 050 051 private final String version; 052 private static ArrayList<Version> ourVersionsOnClasspath; 053 private static final Map<Version, Boolean> ourIsOnClasspath = new HashMap<>(); 054 055 Version(String version) { 056 this.version = version; 057 } 058 059 /** 060 * Returns a version string (e.g. "2.1", or "2.5.1") 061 */ 062 public String getVersion() { 063 return version; 064 } 065 066 public String getPackageVersion() { 067 return "v" + version.replace(".", ""); 068 } 069 070 /** 071 * Returns <code>true</code> if theVersion is a valid HL7 072 * version string representing a known version, e.g. "2.4", "2.6" 073 */ 074 public static boolean supportsVersion(String theVersion) { 075 return versionOf(theVersion) != null; 076 } 077 078 /** 079 * @param version The version string, e.g. "2.1" or "2.6" 080 */ 081 public static Version versionOf(String version) { 082 for (Version v : Version.values()) { 083 if (v.getVersion().equals(version)) { 084 return v; 085 } 086 } 087 return null; 088 } 089 090 /** 091 * @param someVersions set of versions to be tested 092 * @return <code>true</code> if someVersions contain all supported HL7 versions 093 */ 094 public static boolean allVersions(Set<Version> someVersions) { 095 return someVersions != null && someVersions.size() == values().length; 096 } 097 098 /** 099 * Returns true if this version is greater than the specified version 100 */ 101 public boolean isGreaterThan(Version theVersion) { 102 return compareTo(theVersion) > 0; 103 } 104 105 /** 106 * Returns the newest available version of the message structure classes 107 * on the classpath, or <code>null</code> if none are found 108 */ 109 public static Version latestVersion() { 110 Version[] versions = Version.values(); 111 if (versions.length > 0) { 112 return versions[versions.length - 1]; 113 } else { 114 return null; 115 } 116 } 117 118 public static Version[] asOf(Version v) { 119 List<Version> versions = new ArrayList<>(); 120 for (Version version : Version.values()) { 121 if (version.compareTo(v) >= 0) 122 versions.add(version); 123 } 124 return versions.toArray(new Version[0]); 125 } 126 127 public static Version[] except(Version... v) { 128 Set<Version> versions = new HashSet<>(Arrays.asList(Version.values())); 129 for (Version version : v) { 130 versions.remove(version); 131 } 132 return versions.toArray(new Version[0]); 133 } 134 135 public static Version[] before(Version v) { 136 List<Version> versions = new ArrayList<>(); 137 for (Version version : Version.values()) { 138 if (version.compareTo(v) < 0) 139 versions.add(version); 140 } 141 return versions.toArray(new Version[0]); 142 } 143 144 public String modelPackageName() { 145 String classname = getClass().getName(); 146 String p = classname.substring(0, classname.lastIndexOf(".")); 147 return String 148 .format("%s.model.%s.", p, getPackageVersion()); 149 } 150 151 /** 152 * Returns <code>true</code> if the structure 153 * classes for this particular version are available 154 * on the classpath. 155 */ 156 public synchronized boolean available() { 157 Boolean retVal = ourIsOnClasspath.get(this); 158 if (retVal == null) { 159 String resource = "ca/uhn/hl7v2/parser/eventmap/" + getVersion() + ".properties"; 160 try (InputStream in = Parser.class.getClassLoader().getResourceAsStream(resource)) { 161 retVal = in != null; 162 ourIsOnClasspath.put(this, retVal); 163 } catch (IOException e) { 164 throw new RuntimeException(e); 165 } 166 // Ignore 167 } 168 return retVal; 169 } 170 171 /** 172 * Returns a list of all versions for which the structure JARs have been 173 * found on the classpath. 174 */ 175 public static synchronized List<Version> availableVersions() { 176 if (ourVersionsOnClasspath == null) { 177 ourVersionsOnClasspath = new ArrayList<>(); 178 for (Version next : values()) { 179 if (next.available()) { 180 ourVersionsOnClasspath.add(next); 181 } 182 } 183 } 184 return ourVersionsOnClasspath; 185 } 186 187 /** 188 * <p> 189 * Returns the lowest version for which the structure classes are found 190 * on the classes. For instance, if <code>hapi-structures-v24-[version].jar</code> 191 * is the only structure JAR on the current JVM classpath, {@link Version#V24} will 192 * be returned. 193 * <p> 194 * <p> 195 * Returns <code>null</code> if none are found 196 * </p> 197 */ 198 public static Version lowestAvailableVersion() { 199 List<Version> availableVersions = availableVersions(); 200 if (availableVersions.size() >0) { 201 return availableVersions.get(0); 202 } else { 203 return null; 204 } 205 } 206 207 /** 208 * <p> 209 * Returns the highest version for which the structure classes are found 210 * on the classes. For instance, if <code>hapi-structures-v24-[version].jar</code> 211 * is the only structure JAR on the current JVM classpath, {@link Version#V24} will 212 * be returned. 213 * <p> 214 * </> 215 * If no structure JARs at all are found, returns a default value of 216 * {@link Version#V25} 217 * </p> 218 */ 219 public static Version highestAvailableVersionOrDefault() { 220 List<Version> availableVersions = availableVersions(); 221 if (availableVersions.size() >0) { 222 return availableVersions.get(availableVersions.size() - 1); 223 } else { 224 return Version.V25; 225 } 226 } 227 228 /** 229 * Construct and return a new {@link GenericMessage} for the given version 230 */ 231 public GenericMessage newGenericMessage(ModelClassFactory mcf) { 232 switch (this) { 233 case V21: 234 return new GenericMessage.V21(mcf); 235 case V22: 236 return new GenericMessage.V22(mcf); 237 case V23: 238 return new GenericMessage.V23(mcf); 239 case V231: 240 return new GenericMessage.V231(mcf); 241 case V24: 242 return new GenericMessage.V24(mcf); 243 case V25: 244 return new GenericMessage.V25(mcf); 245 case V251: 246 return new GenericMessage.V251(mcf); 247 case V26: 248 return new GenericMessage.V26(mcf); 249 case V27: 250 return new GenericMessage.V27(mcf); 251 case V271: 252 return new GenericMessage.V271(mcf); 253 case V28: 254 return new GenericMessage.V28(mcf); 255 case V281: 256 return new GenericMessage.V281(mcf); 257 default: 258 throw new Error("Unknown version (this is a HAPI bug): " + this.getVersion()); 259 } 260 } 261 262}