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