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 Original Code is ""  Description:
10   * ""
11   *
12   * The Initial Developer of the Original Code is University Health Network. Copyright (C)
13   * 2001.  All Rights Reserved.
14   *
15   * Contributor(s): ______________________________________.
16   *
17   * Alternatively, the contents of this file may be used under the terms of the
18   * GNU General Public License (the  "GPL"), in which case the provisions of the GPL are
19   * applicable instead of those above.  If you wish to allow use of your version of this
20   * file only under the terms of the GPL and not to allow others to use your version
21   * of this file under the MPL, indicate your decision by deleting  the provisions above
22   * and replace  them with the notice and other provisions required by the GPL License.
23   * If you do not delete the provisions above, a recipient may use your version of
24   * this file under either the MPL or the GPL.
25   */
26  package ca.uhn.hl7v2.testpanel.model.conf;
27  
28  import java.lang.reflect.InvocationTargetException;
29  
30  import org.apache.commons.lang.Validate;
31  
32  import ca.uhn.hl7v2.HL7Exception;
33  import ca.uhn.hl7v2.Version;
34  import ca.uhn.hl7v2.conf.ProfileException;
35  import ca.uhn.hl7v2.conf.spec.message.Component;
36  import ca.uhn.hl7v2.conf.spec.message.Field;
37  import ca.uhn.hl7v2.conf.spec.message.ProfileStructure;
38  import ca.uhn.hl7v2.conf.spec.message.Seg;
39  import ca.uhn.hl7v2.conf.spec.message.SegGroup;
40  import ca.uhn.hl7v2.conf.spec.message.StaticDef;
41  import ca.uhn.hl7v2.conf.spec.message.SubComponent;
42  import ca.uhn.hl7v2.model.AbstractMessage;
43  import ca.uhn.hl7v2.model.DoNotCacheStructure;
44  import ca.uhn.hl7v2.model.GenericSegment;
45  import ca.uhn.hl7v2.model.Group;
46  import ca.uhn.hl7v2.model.Message;
47  import ca.uhn.hl7v2.model.Segment;
48  import ca.uhn.hl7v2.model.Structure;
49  import ca.uhn.hl7v2.model.Type;
50  import ca.uhn.hl7v2.parser.ModelClassFactory;
51  
52  @DoNotCacheStructure
53  public class ConformanceMessage extends AbstractMessage implements ConformanceStructureHolder {
54  
55  	private final StaticDef myConfDefinition;
56  	private ConformanceStructureHolderSupport mySupport;
57  	private String myTablesId;
58  
59  	public ConformanceMessage(StaticDef theConfDefinition) {
60  		super(new NullModelClassFactory());
61  
62  		mySupport = new ConformanceStructureHolderSupport(this, theConfDefinition);
63  		myConfDefinition = theConfDefinition;
64  	}
65  
66  	public ConformanceMessage(StaticDef theConfDefinition, ConformanceStructureHolderSupport theSupport) {
67  		this(theConfDefinition);
68  
69  		mySupport = theSupport;
70  	}
71  
72  	/**
73  	 * Internal method for adding child structures
74  	 */
75  	public void addChild(ConformanceStructure<?> theStructure, String theName, short theMinReps, short theMaxReps) throws HL7Exception {
76  		int num = mySupport.getChildCount();
77  		mySupport.addChild(theStructure, theName, theMinReps, theMaxReps);
78  		super.insert(theStructure.getClass(), mySupport.isRequired(theName), mySupport.isRepeating(theName), num, theName);
79  	}
80  
81  	/**
82  	 * {@inheritDoc}
83  	 */
84  	@Override
85  	public Structure get(String theName, int theRep) throws HL7Exception {
86  		Validate.notEmpty(theName);
87  		
88  		Structure retVal = mySupport.getNonStandardSegmentIfNameExists(theName, theRep);
89  		if (retVal != null) {
90  			return retVal;
91  		}
92  		
93  		Structure[] currentReps = getAll(theName);
94  		int currentRepsNum = currentReps.length;
95  		if (theRep > currentRepsNum) {
96  			throw new HL7Exception("Can't create rep " + theRep + " as there are currently only " + currentRepsNum);
97  		}
98  
99  		if (theRep < currentRepsNum) {
100 			return super.get(theName, theRep);
101 		}
102 
103 		if (getClass(theName) == GenericSegment.class) {
104 			retVal = super.get(theName, theRep);
105 		} else {
106 			retVal = mySupport.get(theName, theRep);
107 			insertRepetition(theName, retVal, theRep);
108 		}
109 		return retVal;
110 	}
111 
112 	/**
113 	 * {@inheritDoc}
114 	 */
115 	@Override
116 	public Structure[] getAll(String theName) throws HL7Exception {
117 		Structure[] retVal = mySupport.getAllNonStandardSegmentsIfNameExists(theName);
118 		if (retVal == null) {
119 			return super.getAll(theName);
120 		}
121 		return retVal;
122 	}
123 
124 	/**
125 	 * @return the confDefinition
126 	 */
127 	public StaticDef getConfDefinition() {
128 		return myConfDefinition;
129 	}
130 
131 	
132 	@Override
133 	public ConformanceMessage getMessage() {
134 		return this;
135 	}
136 
137 //	/**
138 //	 * {@inheritDoc}
139 //	 */
140 //	@Override
141 //	public String addNonstandardSegment(String theName) throws HL7Exception {
142 //		String segment = mySupport.addNonstandardSegment(theName);
143 //		return segment;
144 //	}
145 //
146 //	/**
147 //	 * {@inheritDoc}
148 //	 */
149 //	@Override
150 //	public String addNonstandardSegment(String theName, int theIndex) throws HL7Exception {
151 //		return mySupport.addNonstandardSegment(theName, theIndex);
152 //	}
153 
154 	/**
155 	 * {@inheritDoc}
156 	 */
157 	@Override
158 	public String getName() {
159 		return myConfDefinition.getMsgStructID();
160 	}
161 
162 	/**
163 	 * @return the tablesId
164 	 */
165 	public String getTablesId() {
166 		return myTablesId;
167 	}
168 
169 //	/**
170 //	 * {@inheritDoc}
171 //	 */
172 //	@Override
173 //	public String[] getNames() {
174 //		String[] retVal = mySupport.getNames();
175 //		return retVal;
176 //	}
177 
178 	private void setTablesId(String theTablesId) {
179 		myTablesId = theTablesId;
180 	}
181 
182 	/**
183 	 * {@inheritDoc}
184 	 */
185 	@Override
186 	protected Structure tryToInstantiateStructure(Class<? extends Structure> theC, String theName) throws HL7Exception {
187 		if (theC.equals(GenericSegment.class)) {
188 			try {
189 				return theC.getConstructor(Group.class, String.class).newInstance(this, theName);
190 			} catch (InstantiationException e) {
191 				throw new HL7Exception(e);
192 			} catch (IllegalAccessException e) {
193 				throw new HL7Exception(e);
194 			} catch (IllegalArgumentException e) {
195 				throw new HL7Exception(e);
196 			} catch (SecurityException e) {
197 				throw new HL7Exception(e);
198 			} catch (InvocationTargetException e) {
199 				throw new HL7Exception(e);
200 			} catch (NoSuchMethodException e) {
201 				throw new HL7Exception(e);
202 			}
203 		}
204 		return mySupport.get(theName, 0);
205 	}
206 
207 	private static void addChildren(ConformanceStructureHolder theParent, Seg theChildDef) throws HL7Exception {
208 		ConformanceSegment segment = new ConformanceSegment(theParent, theChildDef);
209 		theParent.addChild(segment, theChildDef.getName(), theChildDef.getMin(), theChildDef.getMax());
210 
211 		for (int i = 0; i < theChildDef.getFields(); i++) {
212 			Field fieldDef = theChildDef.getField(i + 1);
213 			if (fieldDef.getComponents() == 0) {
214 				addPrimitive(segment, fieldDef);
215 			} else {
216 				ConformanceComposite field = new ConformanceComposite(((ConformanceMessage) theParent.getMessage()), fieldDef);
217 
218 				for (int j = 0; j < fieldDef.getComponents(); j++) {
219 					Component componentDef = fieldDef.getComponent(j + 1);
220 					if (componentDef.getSubComponents() == 0) {
221 						addPrimitive(field, componentDef);
222 					} else {
223 
224 						ConformanceComposite component = new ConformanceComposite(((ConformanceMessage) theParent.getMessage()), componentDef);
225 						for (int k = 0; k < componentDef.getSubComponents(); k++) {
226 							SubComponent subComponentDef = componentDef.getSubComponent(k + 1);
227 							ConformancePrimitive subComponent = new ConformancePrimitive(theParent.getMessage(), subComponentDef);
228 							component.addChild(subComponent, subComponentDef.getName());
229 						}
230 
231 						field.addChild(component, componentDef.getName());
232 					}
233 				}
234 
235 				segment.addChild(field, fieldDef.getName(), fieldDef.getMin(), fieldDef.getMax(), (int) fieldDef.getLength());
236 			}
237 		}
238 
239 	}
240 
241 	private static void addChildren(ConformanceStructureHolder theParent, SegGroup theChildDef) throws HL7Exception {
242 
243 		if (theChildDef.getChildren() == 1 && theChildDef.getChild(1) instanceof SegGroup) {
244 			SegGroup child = (SegGroup) theChildDef.getChild(1);
245 			try {
246 				if (theChildDef.getMin() == 0) {
247 					child.setMin(theChildDef.getMin());
248 				}
249 				if (theChildDef.getMax() == -1) {
250 					child.setMax(theChildDef.getMax());
251 				}
252 				if (theChildDef.getName().length() > child.getName().length()) {
253 					child.setName(theChildDef.getName());
254 				}
255 			} catch (ProfileException e) {
256 				throw new HL7Exception(e);
257 			}
258 			theChildDef = child;
259 		}
260 
261 		ConformanceGroup child = new ConformanceGroup(theParent, theChildDef);
262 		theParent.addChild(child, theChildDef.getName(), theChildDef.getMin(), theChildDef.getMax());
263 
264 		for (int i = 0; i < theChildDef.getChildren(); i++) {
265 			ProfileStructure childDef = theChildDef.getChild(i + 1);
266 			if (childDef instanceof Seg) {
267 				addChildren(child, (Seg) childDef);
268 			} else {
269 				addChildren(child, (SegGroup) childDef);
270 			}
271 		}
272 
273 	}
274 
275 	private static void addPrimitive(ConformanceComposite theComposite, Component theChild) {
276 		ConformancePrimitive primitive = new ConformancePrimitive(theComposite.getMessage(), theChild);
277 		theComposite.addChild(primitive, theChild.getName());
278 	}
279 
280 	private static void addPrimitive(ConformanceSegment theSegment, Field theField) throws HL7Exception {
281 		ConformancePrimitive primitive = new ConformancePrimitive(theSegment.getMessage(), theField);
282 		theSegment.addChild(primitive, theField.getName(), theField.getMin(), theField.getMax(), (int) theField.getLength());
283 	}
284 
285 	public static ConformanceMessage newInstanceFromStaticDef(StaticDef theStaticDef, String theTablesId) throws HL7Exception {
286 		ConformanceMessage retVal = new ConformanceMessage(theStaticDef);
287 
288 		for (int i = 0; i < theStaticDef.getChildren(); i++) {
289 			ProfileStructure childDef = theStaticDef.getChild(i + 1);
290 			if (childDef instanceof Seg) {
291 				addChildren(retVal, (Seg) childDef);
292 			} else {
293 				addChildren(retVal, (SegGroup) childDef);
294 			}
295 		}
296 
297 		retVal.setTablesId(theTablesId);
298 		
299 		return retVal;
300 	}
301 
302 	/**
303 	 * Null implementation of MCF - Always throws UnsupportedOperationException
304 	 */
305 	private static class NullModelClassFactory implements ModelClassFactory {
306 
307 		public Class<? extends Group> getGroupClass(String theName, String theVersion) throws HL7Exception {
308 			throw new UnsupportedOperationException();
309 		}
310 
311 		public Class<? extends Message> getMessageClass(String theName, String theVersion, boolean theIsExplicit) throws HL7Exception {
312 			throw new UnsupportedOperationException();
313 		}
314 
315 		public Class<? extends Message> getMessageClassInASpecificPackage(String theName, String theVersion, boolean theIsExplicit, String thePackageName) throws HL7Exception {
316 			throw new UnsupportedOperationException();
317 		}
318 
319 		public Class<? extends Segment> getSegmentClass(String theName, String theVersion) throws HL7Exception {
320 			return GenericSegment.class;
321 		}
322 
323 		public Class<? extends Type> getTypeClass(String theName, String theVersion) throws HL7Exception {
324 			throw new UnsupportedOperationException();
325 		}
326 
327 		public String getMessageStructureForEvent(String theEventName, Version theVersion) throws HL7Exception {
328 			throw new UnsupportedOperationException();
329 		}
330 
331 	}
332 
333 }