View Javadoc

1   /**
2   The contents of this file are subject to the Mozilla Public License Version 1.1
3   (the "License"); you may not use this file except in compliance with the License.
4   You may obtain a copy of the License at http://www.mozilla.org/MPL/
5   Software distributed under the License is distributed on an "AS IS" basis,
6   WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the
7   specific language governing rights and limitations under the License.
8   
9   The Initial Developer of the Original Code is University Health Network. Copyright (C)
10  2001.  All Rights Reserved.
11  
12  Contributor(s): ______________________________________.
13  
14  Alternatively, the contents of this file may be used under the terms of the
15  GNU General Public License (the  "GPL"), in which case the provisions of the GPL are
16  applicable instead of those above.  If you wish to allow use of your version of this
17  file only under the terms of the GPL and not to allow others to use your version
18  of this file under the MPL, indicate your decision by deleting  the provisions above
19  and replace  them with the notice and other provisions required by the GPL License.
20  If you do not delete the provisions above, a recipient may use your version of
21  this file under either the MPL or the GPL.
22  */
23  package ca.uhn.hl7v2.parser;
24  
25  import java.io.IOException;
26  import java.io.InputStream;
27  import java.util.Collections;
28  import java.util.HashMap;
29  import java.util.Map;
30  import java.util.Properties;
31  
32  import ca.uhn.hl7v2.HL7Exception;
33  import ca.uhn.hl7v2.Version;
34  
35  /**
36   * Abstract base class for {@link ModelClassFactory} implementations that read event maps from the
37   * file system.
38   * <p>
39   * The directory can be set using {@link #setEventMapDirectory(String)} and defaults to
40   * <code>ca/uhn/hl7v2/parser/eventmap/</code>. The file itself is a property file named after the
41   * HL7 version (e.g. <code>2.4.properties</code>).
42   * </p>
43   * 
44   * 
45   * @author Christian Ohr
46   */
47  @SuppressWarnings("serial")
48  public abstract class AbstractModelClassFactory implements ModelClassFactory {
49  
50  	protected static final String DEFAULT_EVENT_MAP_DIRECTORY = "ca/uhn/hl7v2/parser/eventmap/";
51  
52  	private String eventMapDirectory = DEFAULT_EVENT_MAP_DIRECTORY;
53  	private Map<Version, Map<String, String>> eventMap;
54  
55  	/**
56  	 * @return the directory where to read the eventmap file from
57  	 */
58  	public String getEventMapDirectory() {
59  		return eventMapDirectory;
60  	}
61  
62  	/**
63  	 * @param eventMapPrefix the directory where to read the eventmap file from
64  	 */
65  	public void setEventMapDirectory(String eventMapPrefix) {
66  		this.eventMapDirectory = eventMapPrefix;
67  	}
68  
69  	/**
70  	 * @see ca.uhn.hl7v2.parser.ModelClassFactory#getMessageStructureForEvent(java.lang.String,
71  	 *      ca.uhn.hl7v2.Version)
72  	 */
73  	public String getMessageStructureForEvent(String name, Version version) throws HL7Exception {
74  		Map<String, String> p = getEventMapForVersion(version);
75  		if (p == null)
76  			throw new HL7Exception("No map found for version " + version
77  					+ ". Only the following are available: " + getEventMap().keySet());
78  		return p.get(name);
79  	}
80  
81  	/**
82  	 * Returns the event map for a given HL7 version. In this map, the key is a message
83  	 * type and trigger event in the form <code>[type]_[trigger]</code>, for example:
84  	 * <code>ADT_A04</code>, and the values are the corresponding structure for this trigger,
85  	 * for example: <code>ADT_A01</code>.
86  	 *
87       * @param version the HL7 version
88  	 * @return Returns <code>null</code> if no event map is found for the given version
89       * @throws HL7Exception if the HL7 version is unknown
90  	 */
91  	public Map<String, String> getEventMapForVersion(Version version) throws HL7Exception {
92  		return getEventMap().get(version);
93  	}
94  
95  	/**
96  	 * Initializes the event map once and returns it.
97  	 * <p>
98  	 * This method is package private for testing reasons.
99  	 *  
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 }