001 package org.vmdb.hl7; 002 003 /** 004 * <p><Title:> Observation/Result (OBX) Segment. </p> 005 * <p>Description: HL7 Network Connectivity For VMDB. </p> 006 * <p>Copyright: Copyright (c) 2002-2003. </p> 007 * <p>Company: Veterinary Medical Database (VMDB). </p> 008 * <p>The OBX segment is used to transmit a single observation or observation 009 * fragment. It represents the smallest indivisible unit of a visit summary 010 * report. The OBX segment identifies the specific type of observation result 011 * being reported (OBX-3) and the specific value of the observation (OBX-5).</p> 012 * <p>Reporting to the VMDB focuses on OBX-3 and OBX-5 as the most informative 013 * elements of the message and thus, full effort should be made to make OBX-3 014 * and OBX-5 as valid and unambiguous as possible. Because of its flexible 015 * nature, observations of nearly all types can be transmitted through a series 016 * of OBX segments. Because each segment identifies a separate unique value 017 * for an observation type-observation value pair, there is no limit to the 018 * number of observations that may be transmitted in a single ORU message. 019 * For VMDB reporting a minimum of one diagnosis OBX segment is required.</p> 020 * <p>See HL7 Standard Chapter 7 for details.</p> 021 * @author Michael K. Martin 022 * @version 1.0 023 */ 024 025 public class OBXSegment extends HL7Segment { 026 private String sNm = "OBX"; 027 private String sRl = 028 "DT[SI]ID CE[ST]*[CE][ST][IS][NM][ID]ID[TS]" + 029 "[ST][TS][CE][XCN][CE][EI][TS]"; 030 031 /** 032 * Construct an empty observation result segment. 033 */ 034 public OBXSegment() { 035 setName( sNm ); 036 setRule( sRl ); 037 } 038 039 /** 040 * Construct an empty observation result segment, setting its containing message 041 * object. 042 * @param msgParent HL7SegmentContainer (normally a loop) object that 043 * contains this segment. 044 */ 045 public OBXSegment( HL7SegmentContainer msgParent ) { 046 super( msgParent ); 047 setName( sNm ); 048 setRule( sRl ); 049 } 050 051 void initialize() { 052 super.initialize(); 053 // Default required by HL7 and almost never changed by us. 054 setResultStatus( "F" ); 055 } 056 057 /** 058 * Override HL7Segment processField to deal with the exceptional case of 059 * OBX 6 Which has type conditional on the value of OBX 2 060 * Let the super class do the heavy lifting by calling it first 061 * @param sField String field name to process 062 * @param sType String with data type of field 063 * @param bRepeatable boolean true if this field <i>may</i> repeat. 064 */ 065 boolean processField( String sField, String sType, boolean bRepeatable ) 066 throws MalformedFieldException, 067 MalformedSegmentException { 068 // OBX.5 Type is specified in OBX.2 instead of in the rule 069 if( sField.equalsIgnoreCase( "OBX.5") ) { 070 sType = ((HL7Element)vFields.elementAt(2)).getValue(); 071 } 072 return super.processField( sField, sType, bRepeatable ); 073 }// End processFields 074 075 // The following implement direct type-specific get/set pairs based upon position 076 077 /** 078 * Set the observation set id used to distinguish individual OBX's. 079 * @param sSubId String with 1, 2, 3, etc. 080 */ 081 public void setSetId( String sSetId ) 082 { 083 try { 084 setField( sSetId, 1 ); 085 } 086 catch( ArrayIndexOutOfBoundsException ae ) { 087 ae.printStackTrace(); 088 } 089 } 090 091 /** 092 * Get the observation set id 093 * @return String with set id 094 */ 095 public String getSetId() { 096 HL7Element e = getField(1); 097 if( e != null ) 098 return e.getValue(); 099 else 100 return ""; 101 } 102 103 /** 104 * Set the type of OBX.5 as one of the HL7 data types. For now, we only 105 * allow those types that we have implemented. 106 * @param sType String with CE, SN, NM, or ST value 107 */ 108 public void setObservationValueType( String sType ) 109 throws org.vmdb.hl7.MalformedFieldException 110 { 111 if( sType == null || 112 // TODO: Expand this list to every type allowed keep in order of 113 // most frequent to least so it will short-circuit the string compares 114 ( !sType.equalsIgnoreCase( "CE" ) && 115 !sType.equalsIgnoreCase( "SN" ) && 116 !sType.equalsIgnoreCase( "NM" ) && 117 !sType.equalsIgnoreCase( "ST" ) ) ) 118 { 119 throw new MalformedFieldException( "Type " + sType + 120 " not implemented in ObsType" ); 121 } 122 getField (2).setValue( sType.toUpperCase() ); 123 } 124 125 /** 126 * Get the HL7 data type of OBX.5. 127 * @return String with type code 128 */ 129 public String getObservationValueType() { 130 HL7Element e = getField(2); 131 if( e != null ) 132 return e.getValue(); 133 else 134 return ""; 135 } 136 137 /** 138 * Set the type of observation as a LOINC coded CE element. 139 * @param ceObsId a constructed CEElement coding for the observation identifier. 140 * Normally this will be a preconstructed constant for one of the VMDB 141 * pre-LOINC-coded identifiers. 142 */ 143 public void setObservationIdentifier( CEElement ceObsId ) { 144 try { 145 setField( ceObsId, 3 ); 146 } 147 catch( ArrayIndexOutOfBoundsException ae ) { 148 ae.printStackTrace(); 149 } 150 catch( MalformedSegmentException mfe ) { 151 mfe.printStackTrace(); 152 } 153 } 154 155 /** 156 * Get the observation identifier as a CEElement. 157 * @return CEElement with identifier. Use getText() to retrieve human-readable form. 158 */ 159 public CEElement getObservationIdentifier() { return (CEElement)getField(3); } 160 161 /** 162 * Set the observation sub id used to relate two or more OBX's as part of the 163 * same observation such as a modifier added to a term.<br><br> 164 * Normally, it is best to leave this to the logic coded into the 165 * {@link org.vmdb.hl7.ORUMessage#modifyObservation(OBXSegment,CEElement,CEElement) modifyObservation} 166 * method of the ORU message class. 167 * @param sSubId String with 1.1, 1.2, 2.1, etc. 168 */ 169 public void setSubId( String sSubId ) 170 { 171 try { 172 setField( sSubId, 4 ); 173 } 174 catch( ArrayIndexOutOfBoundsException ae ) { 175 ae.printStackTrace(); 176 } 177 } 178 179 /** 180 * Get the observation sub id. 181 * @return String with sub id value. 182 */ 183 public String getSubId() { 184 HL7Element e = getField(4); 185 if( e != null ) 186 return e.getValue(); 187 else 188 return ""; 189 } 190 191 /** 192 * Set the observation value.<br><br> 193 * Since OBX.5 is polymorphic, we use the base 194 * class HL7Element as the input. The actual value supplied should be the 195 * appropriate subtype as specified in setValueType above. 196 * @param eNewValue HL7Element (or subclass) with value. 197 */ 198 public void setObservationValue( HL7Element eNewValue ) { 199 try { 200 setField( eNewValue, 5 ); 201 } 202 catch( ArrayIndexOutOfBoundsException ae ) { 203 ae.printStackTrace(); 204 } 205 catch( MalformedSegmentException mfe ) { 206 mfe.printStackTrace(); 207 } 208 } 209 210 /** 211 * Set the observation value.<br><br> 212 * This version takes a string representing any of the simple HL7 types. 213 * @param sNewValue String with value of simple data type. 214 */ 215 public void setObservationValue( String sNewValue ) { 216 try { 217 setField( sNewValue, 5 ); 218 } 219 catch( ArrayIndexOutOfBoundsException ae ) { 220 ae.printStackTrace(); 221 } 222 } 223 224 /** 225 * Get the observation value as base class HL7Element 226 * @return HL7Element containing value. Cast to appropriate subclass to 227 * extract human-readable form. 228 */ 229 public HL7Element getObservationValue() { 230 return getField( 5 ); 231 } 232 233 /** 234 * Set the Units as preformed CEElement.<br><br> 235 * Normally will use a precoded ISO or ANSI coded units. 236 * @param eUnits CEElement with units coded as ISO+ or ANS+ 237 */ 238 public void setUnits( CEElement eUnits ) { 239 try { 240 setField( eUnits, 6 ); 241 } 242 catch( ArrayIndexOutOfBoundsException ae ) { 243 ae.printStackTrace(); 244 } 245 catch( MalformedSegmentException mfe ) { 246 mfe.printStackTrace(); 247 } 248 } 249 250 /** 251 * Set the Units as String.<br><br> 252 * Should normally will use a precoded ISO or ANSI coded units but this method 253 * allows use of arbitrary strings for units. 254 * @param sUnits String with units 255 */ 256 public void setUnits( String sUnits ) { 257 try { 258 setField( sUnits, 6 ); 259 } 260 catch( ArrayIndexOutOfBoundsException ae ) { 261 ae.printStackTrace(); 262 } 263 } 264 265 /** 266 * Get the units as a CEElement 267 * @return CEElement with coded units 268 */ 269 public CEElement getUnits() { 270 return (CEElement)getField(6); 271 } 272 273 /** 274 * Set the result status.<br><br> 275 * This will almost always retain the default of 276 * "F" for final results. See HL7 2.4 chapter 7 for usage of other codes. 277 * @param sCode String with result status (normally "F") 278 */ 279 public void setResultStatus( String sCode ) { 280 try { 281 setField( sCode, 11 ); 282 } 283 catch( ArrayIndexOutOfBoundsException ae ) { 284 ae.printStackTrace(); 285 } 286 } 287 288 }// End class OBXSegment 289