001 /** 002 The 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. 004 You may obtain a copy of the License at http://www.mozilla.org/MPL/ 005 Software distributed under the License is distributed on an "AS IS" basis, 006 WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the 007 specific language governing rights and limitations under the License. 008 009 The Initial Developer of the Original Code is University Health Network. Copyright (C) 010 2001. All Rights Reserved. 011 012 Contributor(s): ______________________________________. 013 014 Alternatively, the contents of this file may be used under the terms of the 015 GNU General Public License (the ???GPL???), in which case the provisions of the GPL are 016 applicable instead of those above. If you wish to allow use of your version of this 017 file only under the terms of the GPL and not to allow others to use your version 018 of this file under the MPL, indicate your decision by deleting the provisions above 019 and replace them with the notice and other provisions required by the GPL License. 020 If you do not delete the provisions above, a recipient may use your version of 021 this file under either the MPL or the GPL. 022 023 */ 024 package ca.uhn.hl7v2.parser; 025 026 /** 027 * 028 * @author James 029 */ 030 import ca.uhn.hl7v2.HL7Exception; 031 032 import java.util.Map; 033 import org.apache.commons.logging.Log; 034 import org.apache.commons.logging.LogFactory; 035 import ca.uhn.hl7v2.model.Type; 036 import ca.uhn.hl7v2.model.Segment; 037 import ca.uhn.hl7v2.model.Message; 038 import ca.uhn.hl7v2.model.Group; 039 import java.util.HashMap; 040 041 /** 042 * ModelClassFactory which allows custom packages to search to be specified. 043 * These packages will be searched first, and if nothing is found for a particular 044 * structure, DefaultModelClassFactory is used. 045 * 046 * @author Based on implementation by Christian Ohr 047 * @since 1.0 048 */ 049 public class CustomModelClassFactory implements ModelClassFactory { 050 051 private static final long serialVersionUID = 1; 052 private ModelClassFactory defaultFactory; 053 private Map<String, String[]> customModelClasses; 054 private static Log LOG = LogFactory.getLog(CustomModelClassFactory.class); 055 056 /** 057 * Constructor which just delegated to {@link DefaultModelClassFactory} 058 */ 059 public CustomModelClassFactory() { 060 this((Map<String, String[]>)null); 061 } 062 063 064 /** 065 * Constructor 066 * 067 * @param packageName The base package name to use. 068 * <p> 069 * When searching, package specified here will be appended with .[version].[structure type]. 070 * </p> 071 * <p> 072 * So, for instance, when looking for a v2.5 segment object, if "<code>com.foo</code>" is passed in, HAPI will look in "<code>com.foo.v25.segment.*</code>" 073 * </p> 074 */ 075 public CustomModelClassFactory(String packageName) { 076 defaultFactory = new DefaultModelClassFactory(); 077 customModelClasses = new HashMap<String, String[]>(); 078 079 if (!packageName.endsWith(".")) { 080 packageName += "."; 081 } 082 083 for (String nextVersion : Parser.getValidVersions()) { 084 final String packageVersion = "v" + nextVersion.replace(".", ""); 085 customModelClasses.put(nextVersion, new String[] {packageName + packageVersion}); 086 } 087 } 088 089 090 /** 091 * Constructor 092 * @param map Map of packages to include. 093 * <p> 094 * Keys are versions of HL7, e.g. "v25". 095 * </p> 096 * <p> 097 * Values are an array of packages to search in for custom model classes. 098 * When searching, the package name here will be appended with "<b>.[structure type]</b>". 099 * So, for example, to specify a custom message type, you could create the class 100 * <code>foo.example.v23.message.ZRM_Z01</code>, and pass in the string "<code>foo.example.v23</code>". 101 * </p> 102 */ 103 public CustomModelClassFactory(Map<String, String[]> map) { 104 defaultFactory = new DefaultModelClassFactory(); 105 customModelClasses = map; 106 } 107 108 109 /** 110 * {@inheritDoc } 111 */ 112 public Class<? extends Message> getMessageClass(String name, String version, boolean isExplicit) throws HL7Exception { 113 if (!isExplicit) { 114 name = Parser.getMessageStructureForEvent(name, version); 115 } 116 Class<? extends Message> retVal = (Class<? extends Message>) findClass("message", name, version); 117 if (retVal == null) { 118 retVal = defaultFactory.getMessageClass(name, version, isExplicit); 119 } 120 return retVal; 121 } 122 123 /** 124 * {@inheritDoc } 125 */ 126 public Class<? extends Group> getGroupClass(String name, String version) throws HL7Exception { 127 Class<? extends Group> retVal = (Class<? extends Group>) findClass("group", name, version); 128 if (retVal == null) { 129 retVal = defaultFactory.getGroupClass(name, version); 130 } 131 return retVal; 132 } 133 134 /** 135 * {@inheritDoc } 136 */ 137 public Class<? extends Segment> getSegmentClass(String name, String version) throws HL7Exception { 138 Class<? extends Segment> retVal = (Class<? extends Segment>) findClass("segment", name, version); 139 if (retVal == null) { 140 retVal = defaultFactory.getSegmentClass(name, version); 141 } 142 return retVal; 143 } 144 145 /** 146 * {@inheritDoc } 147 */ 148 public Class<? extends Type> getTypeClass(String name, String version) throws HL7Exception { 149 Class<? extends Type> retVal = (Class<? extends Type>) findClass("datatype", name, version); 150 if (retVal == null) { 151 retVal = defaultFactory.getTypeClass(name, version); 152 } 153 return retVal; 154 } 155 156 /** 157 * Finds appropriate classes to be loaded for the given structure/type 158 */ 159 protected Class<?> findClass(String subpackage, String name, String version) throws HL7Exception { 160 if (!Parser.validVersion(version)) { 161 throw new HL7Exception("HL7 version " + version + " is not supported", 162 HL7Exception.UNSUPPORTED_VERSION_ID); 163 } 164 Class<?> classLoaded = null; 165 if (customModelClasses != null) { 166 if (customModelClasses.containsKey(version)) { 167 for (String next : customModelClasses.get(version)) { 168 if (!next.endsWith(".")) { 169 next += "."; 170 } 171 String fullyQualifiedName = next + subpackage + '.' + name; 172 try { 173 classLoaded = Class.forName(fullyQualifiedName); 174 LOG.debug("Found " + fullyQualifiedName + " in custom HL7 model"); 175 } catch (ClassNotFoundException e) { 176 // ignore 177 } 178 } 179 } 180 } 181 return classLoaded; 182 } 183 }