Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||
AbstractSegment |
|
| 3.8214285714285716;3.821 |
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 "AbstractSegment.java". Description: | |
10 | "Provides common functionality needed by implementers of the Segment interface. | |
11 | Implementing classes should define all the fields for the segment they represent | |
12 | in their constructor" | |
13 | ||
14 | The Initial Developer of the Original Code is University Health Network. Copyright (C) | |
15 | 2001. All Rights Reserved. | |
16 | ||
17 | Contributor(s): ______________________________________. | |
18 | ||
19 | Alternatively, the contents of this file may be used under the terms of the | |
20 | GNU General Public License (the �GPL�), in which case the provisions of the GPL are | |
21 | applicable instead of those above. If you wish to allow use of your version of this | |
22 | file only under the terms of the GPL and not to allow others to use your version | |
23 | of this file under the MPL, indicate your decision by deleting the provisions above | |
24 | and replace them with the notice and other provisions required by the GPL License. | |
25 | If you do not delete the provisions above, a recipient may use your version of | |
26 | this file under either the MPL or the GPL. | |
27 | ||
28 | */ | |
29 | ||
30 | package ca.uhn.hl7v2.model; | |
31 | ||
32 | import java.lang.reflect.InvocationTargetException; | |
33 | import java.util.ArrayList; | |
34 | import java.util.List; | |
35 | ||
36 | import ca.uhn.hl7v2.HL7Exception; | |
37 | import ca.uhn.hl7v2.Location; | |
38 | import ca.uhn.hl7v2.parser.EncodingCharacters; | |
39 | import ca.uhn.hl7v2.parser.ModelClassFactory; | |
40 | ||
41 | /** | |
42 | * <p> | |
43 | * Provides common functionality needed by implementers of the Segment | |
44 | * interface. | |
45 | * </p> | |
46 | * <p> | |
47 | * Implementing classes should define all the fields for the segment they | |
48 | * represent in their constructor. The add() method is useful for this purpose. | |
49 | * </p> | |
50 | * <p> | |
51 | * For example the constructor for an MSA segment might contain the following | |
52 | * code:<br> | |
53 | * <code>this.add(new ID(), true, 2, null);<br> | |
54 | * this.add(new ST(), true, 20, null);<br>...</code> | |
55 | * </p> | |
56 | * | |
57 | * @author Bryan Tripp (bryan_tripp@sourceforge.net) | |
58 | */ | |
59 | public abstract class AbstractSegment extends AbstractStructure implements | |
60 | Segment { | |
61 | ||
62 | /** | |
63 | * Do not use | |
64 | */ | |
65 | static final String ERROR_MSH_1_OR_2_NOT_SET = "Can not invoke parse(String) on a segment if the encoding characters (MSH-1 and MSH-2) are not already correctly set on the message"; | |
66 | ||
67 | private static final long serialVersionUID = -6686329916234746948L; | |
68 | ||
69 | private List<List<Type>> fields; | |
70 | private List<Class<? extends Type>> types; | |
71 | private List<Boolean> required; | |
72 | private List<Integer> length; | |
73 | private List<Object> args; | |
74 | private List<Integer> maxReps; | |
75 | private List<String> names; | |
76 | ||
77 | /** | |
78 | * Calls the abstract init() method to create the fields in this segment. | |
79 | * | |
80 | * @param parent | |
81 | * parent group | |
82 | * @param factory | |
83 | * all implementors need a model class factory to find datatype | |
84 | * classes, so we include it as an arg here to emphasize that | |
85 | * fact ... AbstractSegment doesn't actually use it though | |
86 | */ | |
87 | public AbstractSegment(Group parent, ModelClassFactory factory) { | |
88 | 186906 | super(parent); |
89 | 186906 | this.fields = new ArrayList<List<Type>>(); |
90 | 186906 | this.types = new ArrayList<Class<? extends Type>>(); |
91 | 186906 | this.required = new ArrayList<Boolean>(); |
92 | 186906 | this.length = new ArrayList<Integer>(); |
93 | 186906 | this.args = new ArrayList<Object>(); |
94 | 186906 | this.maxReps = new ArrayList<Integer>(); |
95 | 186906 | this.names = new ArrayList<String>(); |
96 | 186906 | } |
97 | ||
98 | /** | |
99 | * Iterates over the contained fields and calls the visitor for each | |
100 | * of them. | |
101 | * | |
102 | * @param visitor MessageVisitor instance to be called back. | |
103 | * @param location location of the group | |
104 | * @return true if visiting shall continue, false if not | |
105 | * @throws HL7Exception | |
106 | */ | |
107 | public boolean accept(MessageVisitor visitor, Location location) throws HL7Exception { | |
108 | 80 | if (visitor.start(this, location)) { |
109 | 80 | String[] names = getNames(); |
110 | 1935 | for (int i = 1; i <= names.length; i++) { |
111 | 1855 | Field f = new Field(getField(i), getMaxCardinality(i)); |
112 | 1855 | Location nextLocation = f.provideLocation(location, i, -1); |
113 | 1855 | if (!f.accept(visitor, nextLocation)) |
114 | 0 | break; |
115 | } | |
116 | } | |
117 | 80 | return visitor.end(this, location); |
118 | } | |
119 | ||
120 | public Location provideLocation(Location location, int index, int repetition) { | |
121 | 160 | return new Location(location) |
122 | 80 | .withSegmentName(getName()) |
123 | 80 | .withSegmentRepetition(repetition); |
124 | } | |
125 | ||
126 | /** | |
127 | * Returns an array of Field objects at the specified location in the | |
128 | * segment. In the case of non-repeating fields the array will be of length | |
129 | * one. Fields are numbered from 1. | |
130 | */ | |
131 | public Type[] getField(int number) throws HL7Exception { | |
132 | 333152 | List<Type> retVal = getFieldAsList(number); |
133 | 333152 | return retVal.toArray(new Type[retVal.size()]); // note: fields are |
134 | // numbered from 1 from | |
135 | // the user's | |
136 | // perspective | |
137 | } | |
138 | ||
139 | /** | |
140 | * @see ca.uhn.hl7v2.model.Segment#isEmpty() | |
141 | */ | |
142 | public boolean isEmpty() throws HL7Exception { | |
143 | 3870 | for (int i = 1; i <= numFields(); i++) { |
144 | 3800 | Type[] types = getField(i); |
145 | 3800 | for (Type type : types) { |
146 | 695 | if (!type.isEmpty()) return false; |
147 | } | |
148 | } | |
149 | 70 | return true; |
150 | } | |
151 | ||
152 | /** | |
153 | * Returns an array of a specific type class | |
154 | */ | |
155 | protected <T extends Type> T[] getTypedField(int number, T[] array) { | |
156 | try { | |
157 | 40 | List<Type> retVal = getFieldAsList(number); |
158 | @SuppressWarnings("unchecked") | |
159 | 40 | List<T> cast = (List<T>) retVal; |
160 | 40 | return cast.toArray(array); |
161 | 0 | } catch (ClassCastException cce) { |
162 | 0 | log.error("Unexpected problem obtaining field value. This is a bug.", cce); |
163 | 0 | throw new RuntimeException(cce); |
164 | 0 | } catch (HL7Exception he) { |
165 | 0 | log.error("Unexpected problem obtaining field value. This is a bug.", he); |
166 | 0 | throw new RuntimeException(he); |
167 | } | |
168 | } | |
169 | ||
170 | ||
171 | protected int getReps(int number) { | |
172 | try { | |
173 | 15 | return getFieldAsList(number).size(); |
174 | 0 | } catch (HL7Exception he) { |
175 | 0 | log.error("Unexpected problem obtaining field value. This is a bug.", he); |
176 | 0 | throw new RuntimeException(he); |
177 | } | |
178 | } | |
179 | ||
180 | private List<Type> getFieldAsList(int number) throws HL7Exception { | |
181 | 333207 | ensureEnoughFields(number); |
182 | ||
183 | 333207 | if (number < 1 || number > fields.size()) { |
184 | 0 | throw new HL7Exception("Can't retrieve field " + number |
185 | 0 | + " from segment " + this.getClass().getName() |
186 | 0 | + " - there are only " + fields.size() + " fields."); |
187 | } | |
188 | ||
189 | 333207 | return fields.get(number - 1); |
190 | ||
191 | } | |
192 | ||
193 | /** | |
194 | * Returns a specific repetition of field at the specified index. If there | |
195 | * exist fewer repetitions than are required, the number of repetitions can | |
196 | * be increased by specifying the lowest repetition that does not yet exist. | |
197 | * For example if there are two repetitions but three are needed, the third | |
198 | * can be created and accessed using the following code: <br> | |
199 | * <code>Type t = getField(x, 3);</code> | |
200 | * | |
201 | * @param number | |
202 | * the field number (starting at 1) | |
203 | * @param rep | |
204 | * the repetition number (starting at 0) | |
205 | * @throws HL7Exception | |
206 | * if field index is out of range, if the specified repetition | |
207 | * is greater than the maximum allowed, or if the specified | |
208 | * repetition is more than 1 greater than the existing # of | |
209 | * repetitions. | |
210 | */ | |
211 | public Type getField(int number, int rep) throws HL7Exception { | |
212 | ||
213 | 158849 | ensureEnoughFields(number); |
214 | ||
215 | 158849 | if (number < 1 || number > fields.size()) { |
216 | 0 | throw new HL7Exception("Can't get field " + number + " in segment " |
217 | 0 | + getName() + " - there are currently only " |
218 | 0 | + fields.size() + " reps."); |
219 | } | |
220 | ||
221 | 158849 | List<Type> arr = fields.get(number - 1); |
222 | ||
223 | // check if out of range ... | |
224 | 158849 | if (rep > arr.size()) |
225 | 0 | throw new HL7Exception("Can't get repetition " + rep |
226 | + " from field " + number + " - there are currently only " | |
227 | 0 | + arr.size() + " reps."); |
228 | ||
229 | // add a rep if necessary ... | |
230 | 158849 | if (rep == arr.size()) { |
231 | 102484 | Type newType = createNewType(number); |
232 | 102484 | arr.add(newType); |
233 | } | |
234 | ||
235 | 158849 | return arr.get(rep); |
236 | } | |
237 | ||
238 | /** | |
239 | * Returns a specific repetition of field with concrete type at the specified index | |
240 | */ | |
241 | protected <T extends Type> T getTypedField(int number, int rep) { | |
242 | try { | |
243 | 2210 | @SuppressWarnings("unchecked") T retVal = (T)getField(number, rep); |
244 | 2210 | return retVal; |
245 | 0 | } catch (ClassCastException cce) { |
246 | 0 | log.error("Unexpected problem obtaining field value. This is a bug.", cce); |
247 | 0 | throw new RuntimeException(cce); |
248 | 0 | } catch (HL7Exception he) { |
249 | 0 | log.error("Unexpected problem obtaining field value. This is a bug.", he); |
250 | 0 | throw new RuntimeException(he); |
251 | } | |
252 | } | |
253 | ||
254 | /** | |
255 | * <p> | |
256 | * Attempts to create an instance of a field type without using reflection. | |
257 | * </p> | |
258 | * <p> | |
259 | * Note that the default implementation just returns <code>null</code>, and | |
260 | * it is not neccesary to override this method to provide any particular | |
261 | * behaviour. When a new field instance is needed within a segment, this | |
262 | * method is tried first, and if it returns <code>null</code>, reflection is | |
263 | * used instead. Implementations of this method is auto-generated by the | |
264 | * source generator module. | |
265 | * </p> | |
266 | * | |
267 | * @return Returns a newly instantiated type, or <code>null</code> if not | |
268 | * possible | |
269 | * @param field | |
270 | * Field number - Note that this is zero indexed! | |
271 | */ | |
272 | protected Type createNewTypeWithoutReflection(int field) { | |
273 | 0 | return null; |
274 | } | |
275 | ||
276 | /** | |
277 | * Creates a new instance of the Type at the given field number in this | |
278 | * segment. | |
279 | */ | |
280 | private Type createNewType(int field) throws HL7Exception { | |
281 | 102494 | Type retVal = createNewTypeWithoutReflection(field - 1); |
282 | 102494 | if (retVal != null) { |
283 | 101914 | return retVal; |
284 | } | |
285 | ||
286 | 580 | int number = field - 1; |
287 | 580 | Class<? extends Type> c = this.types.get(number); |
288 | ||
289 | Type newType; | |
290 | try { | |
291 | 580 | Object[] args = getArgs(number); |
292 | 580 | Class<?>[] argClasses = new Class[args.length]; |
293 | 1160 | for (int i = 0; i < args.length; i++) { |
294 | 580 | if (args[i] instanceof Message) { |
295 | 580 | argClasses[i] = Message.class; |
296 | } else { | |
297 | 0 | argClasses[i] = args[i].getClass(); |
298 | } | |
299 | } | |
300 | 580 | newType = c.getConstructor(argClasses).newInstance(args); |
301 | 0 | } catch (IllegalAccessException iae) { |
302 | 0 | throw new HL7Exception("Can't access class " + c.getName() + " (" |
303 | 0 | + iae.getClass().getName() + "): " + iae.getMessage()); |
304 | 0 | } catch (InstantiationException ie) { |
305 | 0 | throw new HL7Exception("Can't instantiate class " + c.getName() |
306 | 0 | + " (" + ie.getClass().getName() + "): " + ie.getMessage()); |
307 | 0 | } catch (InvocationTargetException ite) { |
308 | 0 | throw new HL7Exception("Can't instantiate class " + c.getName() |
309 | 0 | + " (" + ite.getClass().getName() + "): " |
310 | 0 | + ite.getMessage()); |
311 | 0 | } catch (NoSuchMethodException nme) { |
312 | 0 | throw new HL7Exception("Can't instantiate class " + c.getName() |
313 | 0 | + " (" + nme.getClass().getName() + "): " |
314 | 0 | + nme.getMessage()); |
315 | 580 | } |
316 | 580 | return newType; |
317 | } | |
318 | ||
319 | // defaults to {this.getMessage} | |
320 | private Object[] getArgs(int fieldNum) { | |
321 | Object[] result; | |
322 | ||
323 | 580 | Object o = this.args.get(fieldNum); |
324 | 580 | if (o != null && o instanceof Object[]) { |
325 | 20 | result = (Object[]) o; |
326 | } else { | |
327 | 560 | result = new Object[] { getMessage() }; |
328 | } | |
329 | ||
330 | 580 | return result; |
331 | } | |
332 | ||
333 | /** | |
334 | * Returns true if the given field is required in this segment - fields are | |
335 | * numbered from 1. | |
336 | * | |
337 | * @throws HL7Exception | |
338 | * if field index is out of range. | |
339 | */ | |
340 | public boolean isRequired(int number) throws HL7Exception { | |
341 | 0 | if (number < 1 || number > required.size()) { |
342 | 0 | throw new HL7Exception("Can't retrieve optionality of field " |
343 | 0 | + number + " from segment " + this.getClass().getName() |
344 | 0 | + " - there are only " + fields.size() + " fields."); |
345 | } | |
346 | ||
347 | try { | |
348 | 0 | return required.get(number - 1); |
349 | 0 | } catch (Exception e) { |
350 | 0 | throw new HL7Exception("Can't retrieve optionality of field " |
351 | 0 | + number + ": " + e.getMessage()); |
352 | } | |
353 | } | |
354 | ||
355 | /** | |
356 | * Returns the maximum length of the field at the given index, in characters | |
357 | * - fields are numbered from 1. | |
358 | * | |
359 | * @throws HL7Exception | |
360 | * if field index is out of range. | |
361 | */ | |
362 | public int getLength(int number) throws HL7Exception { | |
363 | 0 | if (number < 1 || number > length.size()) { |
364 | 0 | throw new HL7Exception("Can't retrieve max length of field " |
365 | 0 | + number + " from segment " + this.getClass().getName() |
366 | 0 | + " - there are only " + fields.size() + " fields."); |
367 | } | |
368 | ||
369 | try { | |
370 | 0 | return length.get(number - 1); // fields #d from 1 to user |
371 | 0 | } catch (Exception e) { |
372 | 0 | throw new HL7Exception("Can't retrieve max length of field " |
373 | 0 | + number + ": " + e.getMessage()); |
374 | } | |
375 | ||
376 | } | |
377 | ||
378 | /** | |
379 | * Returns the number of repetitions of this field that are allowed. | |
380 | * | |
381 | * @throws HL7Exception | |
382 | * if field index is out of range. | |
383 | */ | |
384 | public int getMaxCardinality(int number) throws HL7Exception { | |
385 | 1855 | if (number < 1 || number > length.size()) { |
386 | 0 | throw new HL7Exception("Can't retrieve cardinality of field " |
387 | 0 | + number + " from segment " + this.getClass().getName() |
388 | 0 | + " - there are only " + fields.size() + " fields."); |
389 | } | |
390 | ||
391 | try { | |
392 | 1855 | return maxReps.get(number - 1); // fields #d from 1 to user |
393 | 0 | } catch (Exception e) { |
394 | 0 | throw new HL7Exception("Can't retrieve max repetitions of field " |
395 | 0 | + number + ": " + e.getMessage()); |
396 | } | |
397 | } | |
398 | ||
399 | /** | |
400 | * @deprecated Use {@link #add(Class, boolean, int, int, Object[], String)} | |
401 | */ | |
402 | protected void add(Class<? extends Type> c, boolean required, int maxReps, | |
403 | int length, Object[] constructorArgs) throws HL7Exception { | |
404 | 12285 | add(c, required, maxReps, length, constructorArgs, null); |
405 | 12285 | } |
406 | ||
407 | /** | |
408 | * Adds a field to the segment. The field is initially empty (zero | |
409 | * repetitions). The field number is sequential depending on previous add() | |
410 | * calls. Implementing classes should use the add() method in their | |
411 | * constructor in order to define fields in their segment. | |
412 | * | |
413 | * @param c | |
414 | * the class of the datatype for the field - this should inherit | |
415 | * from {@link Type} | |
416 | * @param required | |
417 | * whether a value for the field is required in order for the | |
418 | * segment to be valid | |
419 | * @param maxReps | |
420 | * The maximum number of repetitions for the field. Note that 0 implies that there is no | |
421 | * limit, and 1 implies that the field may not repeat. | |
422 | * @param length | |
423 | * the maximum length of each repetition of the field (in | |
424 | * characters) | |
425 | * @param constructorArgs | |
426 | * This parameter provides an array of objects that will be used | |
427 | * as constructor arguments | |
428 | * if new instances of this class are created (use null for | |
429 | * zero-arg constructor). To determine the appropriate value for | |
430 | * this parameter, consult the javadoc for the specific datatype class | |
431 | * passed to the first argument of this method, and provide an array | |
432 | * which satisfies the requirements of its constructor. For example, most | |
433 | * datatypes take a single {@link Message} argument in their constructor. | |
434 | * In that case, the appropriate value for this argument is as follows: | |
435 | * <code>new Object[]{ getMessage() }</code> | |
436 | * @param name | |
437 | * A textual description of the name of the field | |
438 | * @throws HL7Exception | |
439 | * if the given class does not inherit from Type or if it can | |
440 | * not be instantiated. | |
441 | */ | |
442 | protected void add(Class<? extends Type> c, boolean required, int maxReps, | |
443 | int length, Object[] constructorArgs, String name) | |
444 | throws HL7Exception { | |
445 | 3654667 | List<Type> arr = new ArrayList<Type>(); |
446 | 3654667 | this.types.add(c); |
447 | 3654667 | this.fields.add(arr); |
448 | 3654667 | this.required.add(required); |
449 | 3654667 | this.length.add(length); |
450 | 3654667 | this.args.add(constructorArgs); |
451 | 3654667 | this.maxReps.add(maxReps); |
452 | 3654667 | this.names.add(name); |
453 | 3654667 | } |
454 | ||
455 | /** | |
456 | * Called from getField(...) methods. If a field has been requested that | |
457 | * doesn't exist (eg getField(15) when only 10 fields in segment) adds | |
458 | * Varies fields to the end of the segment up to the required number. | |
459 | */ | |
460 | private void ensureEnoughFields(int fieldRequested) { | |
461 | 492056 | int fieldsToAdd = fieldRequested - this.numFields(); |
462 | 492056 | if (fieldsToAdd < 0) { |
463 | 468559 | fieldsToAdd = 0; |
464 | } | |
465 | ||
466 | try { | |
467 | 504341 | for (int i = 0; i < fieldsToAdd; i++) { |
468 | 12285 | this.add(Varies.class, false, 0, 65536, null); // using 65536 |
469 | // following | |
470 | // example of | |
471 | // OBX-5 | |
472 | } | |
473 | 0 | } catch (HL7Exception e) { |
474 | 0 | log.error( |
475 | "Can't create additional generic fields to handle request for field " | |
476 | + fieldRequested, e); | |
477 | 492056 | } |
478 | 492056 | } |
479 | ||
480 | public static void main(String[] args) { | |
481 | /* | |
482 | * try { Message mess = new TestMessage(); MSH msh = new MSH(mess); | |
483 | * | |
484 | * //get empty array Type[] ts = msh.getField(1); | |
485 | * System.out.println("Got Type array of length " + ts.length); | |
486 | * | |
487 | * //get first field Type t = msh.getField(1, 0); | |
488 | * System.out.println("Got a Type of class " + t.getClass().getName()); | |
489 | * | |
490 | * //get array now Type[] ts2 = msh.getField(1); | |
491 | * System.out.println("Got Type array of length " + ts2.length); | |
492 | * | |
493 | * //set a value ST str = (ST)t; str.setValue("hello"); | |
494 | * | |
495 | * //get first field Type t2 = msh.getField(1, 0); | |
496 | * System.out.println("Got a Type of class " + t.getClass().getName()); | |
497 | * System.out.println("It's value is " + ((ST)t2).getValue()); | |
498 | * | |
499 | * msh.getFieldSeparator().setValue("thing"); | |
500 | * System.out.println("Field Sep: " + | |
501 | * msh.getFieldSeparator().getValue()); | |
502 | * | |
503 | * msh.getConformanceStatementID(0).setValue("ID 1"); | |
504 | * msh.getConformanceStatementID(1).setValue("ID 2"); | |
505 | * System.out.println("Conf ID #2: " + | |
506 | * msh.getConformanceStatementID(1).getValue()); | |
507 | * | |
508 | * ID[] cid = msh.getConformanceStatementID(); | |
509 | * System.out.println("CID: " + cid); for (int i = 0; i < cid.length; | |
510 | * i++) { System.out.println("Conf ID element: " + i + ": " + | |
511 | * cid[i].getValue()); } | |
512 | * msh.getConformanceStatementID(3).setValue("this should fail"); | |
513 | * | |
514 | * | |
515 | * } catch (HL7Exception e) { e.printStackTrace(); } | |
516 | */ | |
517 | 0 | } |
518 | ||
519 | /** | |
520 | * Returns the number of fields defined by this segment (repeating fields | |
521 | * are not counted multiple times). | |
522 | */ | |
523 | public int numFields() { | |
524 | 515493 | return this.fields.size(); |
525 | } | |
526 | ||
527 | /** | |
528 | * Returns the class name (excluding package). | |
529 | * | |
530 | * @see Structure#getName() | |
531 | */ | |
532 | public String getName() { | |
533 | 317393 | String fullName = this.getClass().getName(); |
534 | 634786 | return fullName.substring(fullName.lastIndexOf('.') + 1, |
535 | 317393 | fullName.length()); |
536 | } | |
537 | ||
538 | /** | |
539 | * Sets the segment name. This would normally be called by a Parser. | |
540 | */ | |
541 | /* | |
542 | * public void setName(String name) { this.name = name; } | |
543 | */ | |
544 | ||
545 | /** | |
546 | * {@inheritDoc} | |
547 | */ | |
548 | public String[] getNames() { | |
549 | 80 | return names.toArray(new String[names.size()]); |
550 | } | |
551 | ||
552 | /** | |
553 | * {@inheritDoc } | |
554 | * | |
555 | * <p> | |
556 | * <b>Note that this method will not currently work to parse an MSH segment | |
557 | * if the encoding characters are not already set. This limitation should be | |
558 | * resolved in a future version</b> | |
559 | * </p> | |
560 | */ | |
561 | public void parse(String string) throws HL7Exception { | |
562 | 2020 | if (string == null) { |
563 | 5 | throw new NullPointerException("String can not be null"); |
564 | } | |
565 | ||
566 | EncodingCharacters encodingCharacters; | |
567 | try { | |
568 | 2015 | encodingCharacters = EncodingCharacters.getInstance(getMessage()); |
569 | 5 | } catch (HL7Exception e) { |
570 | 5 | throw new HL7Exception(ERROR_MSH_1_OR_2_NOT_SET); |
571 | 2010 | } |
572 | 2010 | clear(); |
573 | 2010 | getMessage().getParser().parse(this, string, encodingCharacters); |
574 | 2010 | } |
575 | ||
576 | /** | |
577 | * {@inheritDoc } | |
578 | */ | |
579 | public String encode() throws HL7Exception { | |
580 | 3910 | return getMessage().getParser().doEncode(this, |
581 | 1955 | EncodingCharacters.getInstance(getMessage())); |
582 | } | |
583 | ||
584 | /** | |
585 | * Removes a repetition of a given field by name. For example, if a PID | |
586 | * segment contains 10 repetitions a "Patient Identifier List" field and | |
587 | * "Patient Identifier List" is supplied with an index of 2, then this call | |
588 | * would remove the 3rd repetition. | |
589 | * | |
590 | * @return The removed structure | |
591 | * @throws HL7Exception | |
592 | * if the named Structure is not part of this Group. | |
593 | */ | |
594 | public Type removeRepetition(int fieldNum, int index) | |
595 | throws HL7Exception { | |
596 | 0 | if (fieldNum < 1 || fieldNum > fields.size()) { |
597 | 0 | throw new HL7Exception("The field " + fieldNum |
598 | + " does not exist in the segment " | |
599 | 0 | + this.getClass().getName()); |
600 | } | |
601 | ||
602 | 0 | String name = names.get(fieldNum - 1); |
603 | 0 | List<Type> list = fields.get(fieldNum - 1); |
604 | 0 | if (list.size() == 0) { |
605 | 0 | throw new HL7Exception("Invalid index: " + index + ", structure " |
606 | + name + " has no repetitions"); | |
607 | } | |
608 | 0 | if (list.size() <= index) { |
609 | 0 | throw new HL7Exception("Invalid index: " + index + ", structure " |
610 | 0 | + name + " must be between 0 and " + (list.size() - 1)); |
611 | } | |
612 | ||
613 | 0 | return list.remove(index); |
614 | } | |
615 | ||
616 | /** | |
617 | * Inserts a repetition of a given Field into repetitions of that field by | |
618 | * name. | |
619 | * | |
620 | * @return The newly created and inserted field | |
621 | * @throws HL7Exception | |
622 | * if the named Structure is not part of this Group. | |
623 | */ | |
624 | public Type insertRepetition(int fieldNum, int index) | |
625 | throws HL7Exception { | |
626 | 10 | if (fieldNum < 1 || fieldNum > fields.size()) { |
627 | 0 | throw new HL7Exception("The field " + fieldNum |
628 | + " does not exist in the segment " | |
629 | 0 | + this.getClass().getName()); |
630 | } | |
631 | ||
632 | 10 | List<Type> list = fields.get(fieldNum - 1); |
633 | 10 | Type newType = createNewType(fieldNum); |
634 | ||
635 | 10 | list.add(index, newType); |
636 | ||
637 | 10 | return newType; |
638 | } | |
639 | ||
640 | /** | |
641 | * Clears all data from this segment | |
642 | */ | |
643 | public void clear() { | |
644 | 2010 | for (List<Type> next : fields) { |
645 | 45530 | next.clear(); |
646 | 45530 | } |
647 | 2010 | } |
648 | ||
649 | } |