| 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 | } |