001 package org.vmdb.hl7;
002
003 import java.util.*;
004
005 /**
006 * <p><Title:> Base Class for All Types of HL7 Segments. </p>
007 * <p>Description: HL7 Network Connectivity For VMDB. </p>
008 * <p>Copyright: Copyright (c) 2002-2003. </p>
009 * <p>Company: Veterinary Medical Database (VMDB). </p>
010 * <p>A segment is a collection of related fields whose positions are specified
011 * in the segment rule. The primary function of the base class is to handle the
012 * complex processes of parsing and building segments from and to HL7 and XML.
013 * Each derived class provides a rule. The base class passes that rule to a
014 * RuleParser object which acts as a director with calls back to this object to
015 * read the input string, add fields, etc.. </p>
016 * <p>The base segment class also provides the mechanics for accessing fields by
017 * position based upon an index. Most of the class is made up of a huge variety
018 * of methods for getting, setting, and listing fields. These are normally intended
019 * to be used by derived classes to implement named accessor methods.
020 * In most cases, an application should use these higher-level set, get,
021 * and list methods that provide more segment and message specific access. The
022 * base getField() and setField() methods are made public to provide the ability to
023 * extend messages to any of the infinite possible variations allowed under HL7.</p>
024 * @author Michael K. Martin
025 * @version 1.0
026 */
027
028 public class HL7Segment extends HL7Object{
029 protected Vector vFields;
030 protected int iMaxFields;
031 protected HL7SegmentContainer msgParent;
032 protected String sNextField;
033 protected StringList slFields;
034 private String sNm = "ZZZ";
035 private String sRl = "DT{*}";
036
037 protected HL7Segment() {
038 vFields = new Vector();
039 setName( sNm );
040 setRule( sRl );
041 }
042
043 /**
044 * Construct a segment as part of a specific message or loop.
045 * @param msgParent HL7SegmentContainer to allow this segment to make
046 * calls to its parent message or loop.
047 */
048 public HL7Segment( HL7SegmentContainer msgParent ) {
049 vFields = new Vector();
050 this.msgParent = msgParent;
051 setName( sNm );
052 setRule( sRl );
053 }
054
055 protected void setParent( HL7SegmentContainer msgParent ) {
056 this.msgParent = msgParent;
057 }
058
059 protected boolean addField( HL7Element fField ) {
060 if( fField != null ) {
061 vFields.add( fField );
062 return true;
063 }
064 else
065 return false;
066 }
067
068 /**
069 * Get an Iterator over the HL7Element derived objects that make up
070 * this segment.
071 * @return Iterator over all the Elements in this segment.
072 */
073 public Iterator iterator() {
074 if( vFields == null ) return null;
075 else return vFields.iterator();
076 }
077
078 /**
079 * Factory method to read an HL7 segment as a delimited string and
080 * produce a segment object of appropriate subclass.
081 * @param sSegment String with whole row
082 * @param msgParent parent Message
083 * @return HL7Segment or subclass or null if not parsable.
084 */
085 static HL7Segment fromString( String sSegment, HL7SegmentContainer msgParent ) {
086 if( sSegment == null ) {
087 return null;
088 }
089 // Read separators from MSH segment
090 if( sSegment.substring(0,3).equalsIgnoreCase( "MSH" ) ) {
091 MSHSegment mshSeg = new MSHSegment( msgParent );
092 String sSeparators = sSegment.substring(3,8);
093 if( msgParent != null )
094 msgParent.setSeparators( sSeparators );
095 mshSeg.setSeparators( sSeparators );
096 mshSeg.readString( sSegment );
097 return mshSeg;
098 // Read other separators.
099 }
100 else {
101 if( msgParent == null || msgParent.getSeparators() == null ) return null;
102 HL7Segment sSeg;
103 try {
104 Class c = Class.forName( "org.vmdb.hl7." + sSegment.substring(0,3) + "Segment" );
105 sSeg = (HL7Segment)c.newInstance();
106 sSeg.setParent( msgParent );
107 }
108 catch( Exception e ) {
109 // Generic HL7Segment not working quite right yet.
110 sSeg = new HL7Segment( msgParent );
111 sSeg.setName( sSegment.substring(0,3) );
112 }
113 // Actually do specific classes once available.
114 sSeg.setSeparators( msgParent.getSeparators() );
115 sSeg.readString( sSegment );
116 return sSeg;
117 }
118 }
119
120 boolean readString( String sSegment ) {
121 // need to read tokens themselves so we can account for empty fields
122 char cEsc = getSeparator( ESC_SEP );
123 // hack to avoid being confused by the escape character in MSH:3
124 if( getName().equalsIgnoreCase( "MSH" ) ) cEsc = StringList.NONE;
125 slFields = new StringList( sSegment, getSeparator( FIELD_SEP ) );
126 if( slFields.hasMoreStrings() ) {
127 sNextField = slFields.nextString();
128 initialize();
129 // Pass this pointer so parser knows to call my processSegment method.
130 RuleParser p = new RuleParser();
131 try {
132 if( p.parseFields( getRule(), this ) > 0 )
133 return true;
134 }
135 catch( Exception e ) {
136 System.err.println( e.toString() );
137 e.printStackTrace();
138 }
139 }
140 return false;
141 }
142
143 void initialize() {
144 // need to read tokens themselves so we can account for empty fields
145 char cEsc = getSeparator( ESC_SEP );
146 // hack to avoid being confused by the escape character in MSH:3
147 if( getName().equalsIgnoreCase( "MSH" ) ) cEsc = StringList.NONE;
148 RuleParser p = new RuleParser();
149 try {
150 iMaxFields = p.initializeFields( getRule(), this );
151 }
152 catch( Exception e ) {
153 System.err.println( e.toString() );
154 e.printStackTrace();
155 }
156 ((HL7Element)getField( 0 )).setValue( getName() );
157 }
158
159 protected void addEmptyFields( int iFieldNo ) {
160 // need to read tokens themselves so we can account for empty fields
161 char cEsc = getSeparator( ESC_SEP );
162 // hack to avoid being confused by the escape character in MSH:3
163 if( getName().equalsIgnoreCase( "MSH" ) ) cEsc = StringList.NONE;
164 RuleParser p = new RuleParser();
165 try {
166 p.addFields( getRule(), this, vFields.size(), iFieldNo );
167 }
168 catch( Exception e ) {
169 System.err.println( e.toString() );
170 e.printStackTrace();
171 }
172 //((SimpleElement)getField( 0 )).setValue( getName() );
173 }
174
175 /**
176 * Output this segment as an HL7 String.
177 * @return String with segment and all contained fields as delimited HL7.
178 */
179 public String toString() {
180 Iterator i = vFields.iterator();
181 StringBuffer sb = new StringBuffer();
182 while( i.hasNext() ) {
183 HL7Element eNext = (HL7Element)i.next();
184 sb.append( eNext.toString() );
185 sb.append( getSeparator( FIELD_SEP ) );
186 }
187 sb.append( "\n" );
188 return sb.toString();
189 }
190
191 /**
192 * Output the this segment as XML.<br><br>
193 * Output is the DOM element for that segment and all its contained objects.
194 * @param iDepth int value for the number of spaces to indent this object. Used just
195 * to make the XML easier to read as unformatted text.
196 * @return foratted XML text.
197 */
198 public String toXML( int iDepth ) {
199 Iterator i = vFields.iterator();
200 StringBuffer sb = new StringBuffer();
201 int iField = 0;
202 for( int x = 0; x < iDepth; x++ ) sb.append( " " );
203 sb.append( '<' );
204 sb.append( sName );
205 sb.append( ">\n" );
206 while( i.hasNext() ) {
207 HL7Element eNext = (HL7Element)i.next();
208 if( iField++ > 0 ) // Be sure to skip zero element with name.
209 sb.append( eNext.toXML( iDepth + 1 ) );
210 }
211 for( int x = 0; x < iDepth; x++ ) sb.append( " " );
212 sb.append( "</" );
213 sb.append( sName );
214 sb.append( ">\n" );
215 return sb.toString();
216 }
217
218 boolean segmentComplete() {
219 return( !slFields.hasMoreStrings() );
220 }
221
222 /**
223 * Add a new field in the specified name and type, at the specified location.<br>
224 * This is <i>only</i> to be called by the rule parser object acting as director
225 * to add a field of the correct type and name based on the rule string. Lacking
226 * a "friend" access permission setting, this is restricted to package access.
227 *
228 * @param sFieldName String with field name based on segment and position. Example:
229 * "PID.3"
230 * @param sFieldType String with HL7 data type. Example: "CX"
231 * @param bRepeatable Boolean true if this is a repeatable field. If so, the added
232 * field will be either be added to inside a RepeatElement object.
233 */
234 void addField( String sFieldName, String sFieldType, boolean bRepeatable ) {
235 HL7Element e = null;
236 if( bRepeatable ) {
237 e = new RepeatElement();
238 e.setName( sFieldName );
239 e.setType( sFieldType );
240 }
241 else {
242 e = HL7Element.makeElement( HL7Element.FIELD, getSeparators(), sFieldType, sFieldName );
243 }
244 vFields.add( e );
245 }
246
247
248 /**
249 * Add a new field in the specified name and type, at the specified location
250 * with the data read from the input data stream.<br>
251 * This is <i>only</i> to be called by the rule parser object acting as director
252 * to add a field of the correct type and name based on the rule string. Lacking
253 * a "friend" access permission setting, this is restricted to package access.
254 *
255 * @param sFieldName String with field name based on segment and position. Example:
256 * "PID.3"
257 * @param sFieldType String with HL7 data type. Example: "CX"
258 * @param bRepeatable Boolean true if this is a repeatable field. If so, the added
259 * field will be either be added to inside a RepeatElement object.
260 * @return boolean true if data fitting the field type were found and added, or
261 * false if the next field could not be parsed as the data type specified in sType
262 */
263 boolean processField( String sField, String sType, boolean bRepeatable )
264 throws MalformedFieldException,
265 MalformedSegmentException {
266 boolean bRetVal = false;
267 if( sType == null || sType.length() == 0 || sNextField == null )
268 bRetVal = false;
269 else {
270 if( sField != null && sField.equals( "OBX.5" ) && getField(2) != null ) {
271 sType = getField( 2 ).getValue();
272 }
273 StringList sl = new StringList( sNextField, getSeparator( REP_SEP ) );
274 if( !bRepeatable && sl.size() > 1 ) {
275 throw new MalformedFieldException( "Repeat character in non-repeatable field:\n" + sNextField );
276 }
277 HL7Element e = null;
278 while( sl.hasMoreStrings() ) {
279 String sValue = sl.nextString();
280 e = HL7Element.makeElement( HL7Element.FIELD, getSeparators(), sType, sField );
281 e.readString( sValue );
282 setField( e, sField, bRepeatable );
283 }
284 bRetVal = true;
285 if( slFields.hasMoreStrings() )
286 sNextField = slFields.nextString();
287 else
288 sNextField = null;
289 }
290 return bRetVal;
291 }// End processFields
292
293 /**
294 * Set the field at position specified to the HL7Element derived object
295 * provided.<br><br>
296 * The following allow set and get by position and will be used by named
297 * segment subclasses for their setters and accessors.
298 * Based on HL7 field number i.e., 1 based index.
299 * @param eField The specific object to be inserted by reference.
300 * @param sFieldName String with field name based on segment and position. Example:
301 * "PID.3"
302 * @param bRepeatable Boolean true if this is a repeatable field.
303 * @throws NumberFormatException if the string in sFieldName cannot be
304 * parsed to a string segment name plus a period and an integer.
305 * @throws ArrayIndexOutOfBoundsException if the field specified in sFieldName is
306 * either zero or less or greater than the number of fields.
307 * @throws MalformedSegmentException if the HL7Element provided as eField does not
308 * have the type required by rule for this field or when attempting to add to
309 * a non-repeatable field.
310 */
311 public void setField( HL7Element eField, String sFieldName, boolean bRepeatable )
312 throws NumberFormatException,
313 ArrayIndexOutOfBoundsException,
314 MalformedSegmentException
315 {
316 int iFieldNo = -1;
317 try {
318 String sName = sFieldName.substring(0,sFieldName.indexOf("."));
319 String sNum = sFieldName.substring(sFieldName.indexOf(".")+1);
320 iFieldNo = Integer.parseInt( sNum );
321 }
322 catch( NumberFormatException e ) {
323 throw new NumberFormatException( "Cannot parse " + sFieldName
324 + " as Seg.integer for field number.\n"
325 + e.getMessage() );
326 }
327 setField( eField, iFieldNo );
328 }
329
330 /**
331 * Set the field at position specified to the HL7Element derived object
332 * provided.<br><br>
333 * The following allow set and get by position and will be used by named
334 * segment subclasses for their setters and accessors.
335 * Based on HL7 field number i.e., 1 based index.
336 * @param eField The specific object to be inserted by reference.
337 * @param sFieldName String with field name based on segment and position. Example:
338 * "PID.3"
339 * @throws NumberFormatException if the string in sFieldName cannot be
340 * parsed to a string segment name plus a period and an integer.
341 * @throws ArrayIndexOutOfBoundsException if the field specified in sFieldName is
342 * either zero or less or greater than the number of fields.
343 * @throws MalformedSegmentException if the HL7Element provided as eField does not
344 * have the type required by rule for this field.
345 */
346 public void setField( HL7Element eField, String sFieldName )
347 throws NumberFormatException,
348 ArrayIndexOutOfBoundsException,
349 MalformedSegmentException
350 {
351 setField( eField, sFieldName, false );
352 }
353
354 /**
355 * Set the field at position specified to a SimpleElement with the value
356 * provided.<br><br>
357 * The following allow set and get by position and will be used by named
358 * segment subclasses for their setters and accessors.
359 * Based on HL7 field number i.e., 1 based index.
360 * @param sField String value for any of the simple types.
361 * @param sFieldName String with field name based on segment and position. Example:
362 * "PID.3"
363 * @param bRepeatable Boolean true if this is a repeatable field.
364 * @throws NumberFormatException if the string in sFieldName cannot be
365 * parsed to a string segment name plus a period and an integer.
366 * @throws ArrayIndexOutOfBoundsException if the field specified in sFieldName is
367 * either zero or less or greater than the number of fields.
368 * @throws MalformedSegmentException if the HL7Element provided as eField does not
369 * have the type required by rule for this field.
370 */
371 public void setField( String sField, String sFieldName )
372 throws NumberFormatException,
373 ArrayIndexOutOfBoundsException,
374 MalformedSegmentException
375 {
376 int iFieldNo = -1;
377 try {
378 String sName = sFieldName.substring(0,sFieldName.indexOf("."));
379 String sNum = sFieldName.substring(sFieldName.indexOf(".")+1);
380 iFieldNo = Integer.parseInt( sNum );
381 }
382 catch( NumberFormatException e ) {
383 throw new NumberFormatException( "Cannot parse " + sFieldName
384 + " as Seg.integer for field number.\n"
385 + e.getMessage() );
386 }
387 setField( sField, iFieldNo );
388 }
389
390 /**
391 * Set the field at position specified to the HL7Element derived object
392 * provided.<br><br>
393 * The following allow set and get by position and will be used by named
394 * segment subclasses for their setters and accessors.
395 * Based on HL7 field number i.e., 1 based index.
396 * @param eField The specific object to be inserted by reference.
397 * @param iFieldNo Integer field number.
398 * @param bRepeatable Boolean true if this is a repeatable field.
399 * @throws ArrayIndexOutOfBoundsException if iFieldNo points to a field
400 * less than zero or greater than the number of fields allowed in the message
401 * rule
402 * @throws MalformedSegmentException if the HL7Element provided as eField does not
403 * have the type required by rule for this field or when attempting to add to
404 * a non-repeatable field.
405 */
406 public void setField( HL7Element eField, int iFieldNo, boolean bAdd )
407 throws ArrayIndexOutOfBoundsException,
408 MalformedSegmentException
409 {
410 eField.setName( getName() + "." + iFieldNo );
411 if( iFieldNo < 0 || iFieldNo >= iMaxFields )
412 throw new ArrayIndexOutOfBoundsException();
413 else if( vFields.size() > iFieldNo ){
414 Object o = vFields.elementAt( iFieldNo );
415 if( o instanceof RepeatElement ) {
416 RepeatElement re = (RepeatElement)o;
417 if( !bAdd )
418 re.clear();
419 re.addElement( eField );
420 }
421 else {
422 if( bAdd )
423 throw new MalformedSegmentException( "Attempt to add to non-repeatable field" );
424 String sType = getField( iFieldNo ).getType();
425 if( !sType.equals("*") && !sType.equalsIgnoreCase( eField.getType() ) ) {
426 throw new MalformedSegmentException( "Found field type " + eField.getType() +
427 " but expected " + sType );
428 }
429 vFields.setElementAt( eField, iFieldNo );
430 }
431 }
432 else if( iFieldNo <= iMaxFields ) {
433 addEmptyFields( iFieldNo );
434 String sType = getField( iFieldNo ).getType();
435 if( !sType.equals("*") && !sType.equalsIgnoreCase( eField.getType() ) ) {
436 throw new MalformedSegmentException( "Found field type " + eField.getType() +
437 " but expected " + sType );
438 }
439 Object o = vFields.elementAt( iFieldNo );
440 if( o instanceof RepeatElement ) {
441 RepeatElement re = (RepeatElement)o;
442 re.addElement( eField );
443 }
444 else {
445 vFields.setElementAt( eField, iFieldNo );
446 }
447 }
448 }
449
450 /**
451 * Set the field at position specified to the HL7Element derived object
452 * provided.<br><br>
453 * The following allow set and get by position and will be used by named
454 * segment subclasses for their setters and accessors.
455 * Based on HL7 field number i.e., 1 based index.
456 * @param eField The specific object to be inserted by reference.
457 * @param iFieldNo Integer field number.
458 * @throws ArrayIndexOutOfBoundsException if iFieldNo points to a field
459 * less than zero or greater than the number of fields allowed in the message
460 * rule
461 * @throws MalformedSegmentException if the HL7Element provided as eField does not
462 * have the type required by rule for this field.
463 */
464 public void setField( HL7Element eField, int iFieldNo )
465 throws ArrayIndexOutOfBoundsException,
466 MalformedSegmentException
467 {
468 setField( eField, iFieldNo, false );
469 }
470
471 /**
472 * Set the field at position specified to a SimpleElement with the value
473 * provided.<br><br>
474 * The following allow set and get by position and will be used by named
475 * segment subclasses for their setters and accessors.
476 * Based on HL7 field number i.e., 1 based index.
477 * @param sField String value for any of the simple types.
478 * @param iFieldNo Integer field number.
479 * @param bAdd Boolean true to add rather than replace an existing value in
480 * a repeatable field.
481 * @throws ArrayIndexOutOfBoundsException if iFieldNo points to a field
482 * less than zero or greater than the number of fields allowed in the message
483 * rule
484 * @throws MalformedSegmentException if attempting to add to a non-repeatable field.
485 */
486 public void setField( String sValue, int iFieldNo, boolean bAdd )
487 throws ArrayIndexOutOfBoundsException,
488 MalformedSegmentException
489 {
490 if( iFieldNo < 0 || iFieldNo >= iMaxFields )
491 throw new ArrayIndexOutOfBoundsException();
492 else if( vFields.size() > iFieldNo ){
493 }
494 else if( iFieldNo <= iMaxFields ) {
495 addEmptyFields( iFieldNo );
496 }
497 Object o = vFields.elementAt( iFieldNo );
498 if( o instanceof RepeatElement ) {
499 RepeatElement re = (RepeatElement)o;
500 if( !bAdd )
501 re.clear();
502 String sType = getField( iFieldNo ).getType();
503 String sName = getField( iFieldNo ).getName();
504 HL7Element e = HL7Element.makeElement( HL7Element.FIELD, getSeparators(), sType, sName );
505 e.setValue( sValue );
506 re.addElement( e );
507 }
508 else {
509 if( bAdd )
510 throw new MalformedSegmentException( "Attempt to add to non-repeatable field" );
511 HL7Element eField = (HL7Element)o;
512 eField.setValue( sValue );
513 }
514 }
515
516
517 /**
518 * Set the field at position specified to a SimpleElement with the value
519 * provided.<br><br>
520 * The following allow set and get by position and will be used by named
521 * segment subclasses for their setters and accessors.
522 * Based on HL7 field number i.e., 1 based index.
523 * @param sField String value for any of the simple types.
524 * @param iFieldNo Integer field number.
525 * @throws ArrayIndexOutOfBoundsException if iFieldNo points to a field
526 * less than zero or greater than the number of fields allowed in the message
527 * rule
528 */
529 public void setField( String sValue, int iFieldNo )
530 throws ArrayIndexOutOfBoundsException
531 {
532 try {
533 setField( sValue, iFieldNo, false );
534 } catch( MalformedSegmentException mse ) {
535 System.err.println( "Impossible malformed segment exception!" );
536 mse.printStackTrace();
537 }
538 }
539
540 /**
541 * Clear the value in the specified field and remove any components and
542 * subcomponents.
543 * @param iFieldNo One based index (zero is the segment name) of field to clear.
544 * @throws ArrayIndexOutOfBoundsException if iFieldNo points to a field
545 * less than zero or greater than the number of fields allowed in the message
546 * rule
547 */
548 public void clearField( int iFieldNo )
549 throws ArrayIndexOutOfBoundsException
550 {
551 if( iFieldNo < 0 || iFieldNo >= iMaxFields )
552 throw new ArrayIndexOutOfBoundsException();
553 else if( vFields.size() > iFieldNo ){
554 Object o = vFields.elementAt( iFieldNo );
555 if( o instanceof HL7Element ) {
556 HL7Element he = (HL7Element)o;
557 he.clear();
558 }
559 }
560 else if( iFieldNo < iMaxFields ) {
561 // This makes sense but since the field hasn't been set
562 // we don't need to do anything.
563 }
564 }
565
566 /**
567 * Get Field in Segment by position as named in HL7, i.e., 1 based
568 * index (zero is the segment name).<br><br>
569 * If this is a repeating field, returns the first value.
570 * @param iFieldNo One based index (zero is the segment name) of field.
571 * @return The element at position iFieldNo as an HL7Element derived object.
572 * @throws ArrayIndexOutOfBoundsException if iFieldNo points to a field
573 * less than zero or greater than the number of fields allowed in the message
574 * rule
575 */
576 public HL7Element getField( int iFieldNo )
577 throws ArrayIndexOutOfBoundsException
578 {
579 if( iFieldNo < 0 || iFieldNo >= iMaxFields )
580 throw new ArrayIndexOutOfBoundsException();
581 else if( vFields.size() > iFieldNo ){
582 HL7Element hE = (HL7Element)vFields.elementAt( iFieldNo );
583 if( hE == null )
584 return null;
585 else {
586 if( hE instanceof RepeatElement ){
587 return ((RepeatElement)hE).firstElement();
588 }
589 else
590 return hE;
591 }
592 }
593 else {
594 return null;
595 }
596 }
597
598 /**
599 * Get Iterator over all instances of a repeatable Field in Segment by
600 * position as named in HL7, i.e., 1 based index (zero is the segment name).<br><br>
601 * @param iFieldNo One based index (zero is the segment name) of field.
602 * @return Iterator over the elements at position iFieldNo as an HL7Element derived objects.
603 * @throws ArrayIndexOutOfBoundsException if iFieldNo points to a field
604 * less than zero or greater than the number of fields allowed in the message
605 * rule
606 */
607 public Iterator listFields( int iFieldNo )
608 throws ArrayIndexOutOfBoundsException
609 {
610 if( iFieldNo < 0 || iFieldNo >= iMaxFields )
611 throw new ArrayIndexOutOfBoundsException();
612 else if( vFields.size() > iFieldNo ){
613 HL7Element hE = (HL7Element)vFields.elementAt( iFieldNo );
614 if( hE == null )
615 return null;
616 else {
617 if( hE instanceof RepeatElement )
618 return ((RepeatElement)hE).iterator();
619 // This should just be a convenience in case called against
620 // a non-repeatable Field.
621 else {
622 Vector vMatch = new Vector();
623 vMatch.add( hE );
624 return vMatch.iterator();
625 }
626 }
627 }
628 else {
629 return null;
630 }
631 }
632
633 /**
634 * Get Field Value in Segment by position as named in HL7, i.e., 1 based index.
635 * @param iFieldNo One based index (zero is the segment name) of field.
636 * @return String value of the field or the first componet of the field
637 * specified.
638 * @throws ArrayIndexOutOfBoundsException if iFieldNo points to a field
639 * less than zero or greater than the number of fields allowed in the message
640 * rule
641 */
642 public String getFieldValue( int iFieldNo )
643 throws ArrayIndexOutOfBoundsException
644 {
645 if( iFieldNo < 0 || iFieldNo >= iMaxFields )
646 throw new ArrayIndexOutOfBoundsException();
647 else if( vFields.size() > iFieldNo ){
648 if( vFields.elementAt( iFieldNo ) != null )
649 return ((HL7Element)vFields.elementAt( iFieldNo )).getValue();
650 else
651 return "";
652 }
653 else {
654 return "";
655 }
656 }
657
658 } // End class HL7Segment
659