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 Initial Developer of the Original Code is University Health Network. Copyright (C) 0102001. All Rights Reserved. 011 012Contributor(s): ______________________________________. 013 014Alternatively, the contents of this file may be used under the terms of the 015GNU General Public License (the "GPL"), in which case the provisions of the GPL are 016applicable instead of those above. If you wish to allow use of your version of this 017file only under the terms of the GPL and not to allow others to use your version 018of this file under the MPL, indicate your decision by deleting the provisions above 019and replace them with the notice and other provisions required by the GPL License. 020If you do not delete the provisions above, a recipient may use your version of 021this file under either the MPL or the GPL. 022*/ 023package ca.uhn.hl7v2.parser; 024 025import java.io.IOException; 026import java.io.InputStream; 027import java.util.Collections; 028import java.util.HashMap; 029import java.util.Map; 030import java.util.Properties; 031 032import ca.uhn.hl7v2.HL7Exception; 033import ca.uhn.hl7v2.Version; 034 035/** 036 * Abstract base class for {@link ModelClassFactory} implementations that read event maps from the 037 * file system. 038 * <p> 039 * The directory can be set using {@link #setEventMapDirectory(String)} and defaults to 040 * <code>ca/uhn/hl7v2/parser/eventmap/</code>. The file itself is a property file named after the 041 * HL7 version (e.g. <code>2.4.properties</code>). 042 * </p> 043 * 044 * 045 * @author Christian Ohr 046 */ 047@SuppressWarnings("serial") 048public abstract class AbstractModelClassFactory implements ModelClassFactory { 049 050 protected static final String DEFAULT_EVENT_MAP_DIRECTORY = "ca/uhn/hl7v2/parser/eventmap/"; 051 052 private String eventMapDirectory = DEFAULT_EVENT_MAP_DIRECTORY; 053 private Map<Version, Map<String, String>> eventMap; 054 055 /** 056 * @return the directory where to read the eventmap file from 057 */ 058 public String getEventMapDirectory() { 059 return eventMapDirectory; 060 } 061 062 /** 063 * @param eventMapPrefix the directory where to read the eventmap file from 064 */ 065 public void setEventMapDirectory(String eventMapPrefix) { 066 this.eventMapDirectory = eventMapPrefix; 067 } 068 069 /** 070 * @see ca.uhn.hl7v2.parser.ModelClassFactory#getMessageStructureForEvent(java.lang.String, 071 * ca.uhn.hl7v2.Version) 072 */ 073 public String getMessageStructureForEvent(String name, Version version) throws HL7Exception { 074 Map<String, String> p = getEventMapForVersion(version); 075 if (p == null) 076 throw new HL7Exception("No map found for version " + version 077 + ". Only the following are available: " + getEventMap().keySet()); 078 return p.get(name); 079 } 080 081 /** 082 * Returns the event map for a given HL7 version. In this map, the key is a message 083 * type and trigger event in the form <code>[type]_[trigger]</code>, for example: 084 * <code>ADT_A04</code>, and the values are the corresponding structure for this trigger, 085 * for example: <code>ADT_A01</code>. 086 * 087 * @param version the HL7 version 088 * @return Returns <code>null</code> if no event map is found for the given version 089 * @throws HL7Exception if the HL7 version is unknown 090 */ 091 public Map<String, String> getEventMapForVersion(Version version) throws HL7Exception { 092 return getEventMap().get(version); 093 } 094 095 /** 096 * Initializes the event map once and returns it. 097 * <p> 098 * This method is package private for testing reasons. 099 * 100 * @return the event map 101 * @throws HL7Exception 102 */ 103 synchronized Map<Version, Map<String, String>> getEventMap() throws HL7Exception { 104 if (eventMap == null) { 105 try { 106 eventMap = loadMessageStructures(); 107 } catch (IOException e) { 108 throw new HL7Exception("Could not load event map", e); 109 } 110 } 111 return eventMap; 112 } 113 114 /** 115 * Load event map from a external resource 116 * 117 * @return the event map 118 * @throws IOException 119 */ 120 protected Map<Version, Map<String, String>> loadMessageStructures() throws IOException { 121 Map<Version, Map<String, String>> map = new HashMap<Version, Map<String, String>>(); 122 for (Version v : Version.values()) { 123 String resource = getEventMapDirectory() + v.getVersion() + ".properties"; 124 InputStream in = getResource(resource); 125 if (in != null) { 126 try { 127 Properties structures = new Properties(); 128 structures.load(in); 129 130 Map<String, String> structureMap = new HashMap<String, String>(); 131 for(Map.Entry<Object, Object> next : structures.entrySet()) { 132 structureMap.put((String)next.getKey(), (String)next.getValue()); 133 } 134 135 map.put(v, Collections.unmodifiableMap(structureMap)); 136 } finally { 137 in.close(); 138 } 139 } 140 } 141 return map; 142 } 143 144 private InputStream getResource(String resource) { 145 InputStream in = null; 146 ClassLoader loader = Thread.currentThread().getContextClassLoader(); 147 if (loader != null) { 148 in = loader.getResourceAsStream(resource); 149 } 150 if (in == null) { 151 loader = AbstractModelClassFactory.class.getClassLoader(); 152 if (loader != null) { 153 in = loader.getResourceAsStream(resource); 154 } 155 } 156 if (in == null) { 157 in = ClassLoader.getSystemResourceAsStream(resource); 158 } 159 return in; 160 } 161 162}