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