001    package org.vmdb.hl7;
002    
003    /**
004     * <p><Title:> Single Implementation for All Simple HL7 Data Types. </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>This one class handles all the data types that consist of a single
009     * string.  The actual type is set by the calling program with the constructor
010     * or setType() method.  Validity checking is left to the calling routine.</p>
011     * @author Michael K. Martin
012     * @version 1.0
013     */
014    
015    public class SimpleElement extends HL7Element {
016       protected String sValue = null;
017       private String sNm = "ZZ";
018       private String sRl = "*";
019    
020       /**
021        * Construct an Element using the name and type specified in its sNm and sRl
022        * constants.
023        * @param iLevel One of the constants for specifying level as FIELD, COMPONENT, or
024        * SUBCOMPONENT.  Default FIELD.
025        */
026       public SimpleElement( int iLevel ) {
027          this.iLevel = iLevel;
028          setName( sNm );
029          setRule( sRl );
030    // Setting type is left to calling routine for generic class objects
031       }
032    
033       /**
034        * Construct an Element using the name and type specified in its sNm and sRl
035        * constants.  And at the level of a Field.
036        */
037       public SimpleElement() {
038          this.iLevel = FIELD;
039          setName( sNm );
040          setRule( sRl );
041       }
042    
043       /**
044        * Construct an Element of given name and type.<br><br>
045        * @param sName The name of this element relative to its container.  Example:
046        * "PID.1" for the segquenceID in the pid segment.
047        * @param sType The HL7 data type abbreviation.  Example "ST" for string or
048        * "NM" for numeric.  Note: Both of these would be instatiated as SimpleElement
049        * objects in this library.
050        */
051       public SimpleElement( String sName, String sType ) {
052          this.iLevel = FIELD;
053          setName( sName );
054          setType( sType );
055          setRule( sRl );
056       }
057    
058       /**
059        * Set the value of this element.
060        * @param sValue String representing the value.  For numeric and coded
061        * types, validation is left to the calling routine.
062        */
063       public void setValue( String sValue ) {
064          this.sValue = sValue;
065       }
066    
067       /**
068        * Get the value stored in this element as a simple string.
069        * @return String with value or an empty string object if not set.
070        */
071       public String getValue()
072       {
073          if( empty() )
074             return "";
075          else
076             return sValue;
077       }
078    
079       /**
080        * Get component based on one based index position.
081        * @param iLoc location in element to get (one based index).
082        * @return Reference to the HL7Element derived object at the specified location
083        * or null if the location does not yet exist.
084        * @throws ArrayIndexOutOfBoundsException if iLoc points to a field
085        * less than one or greater than the number of components allowed
086        * in the message rule.
087        */
088       public HL7Element getComponent( int iLoc ) {
089          if( iLoc != 1 )
090             throw new ArrayIndexOutOfBoundsException();
091          return this;
092       }
093    
094       /**
095        * Test to see if a value has been set for this simple element.<br><br>
096        * This is the simplest case of the more complex empty() method inherited from
097        * HL7Element.
098        * @return true if value is not set.
099        */
100       public boolean empty() {
101          if( sValue == null || sValue.length() == 0 )
102             return true;
103          else
104             return false;
105       }
106    
107       /**
108        * Return the number of components in this element.<br><br>
109        * Because this is defined as a single string, the values returned are limite
110        * to zero if no value has been set or one if it has a value.  This is a simple
111        * case of the size() method inherited from HL7Element.
112        * @return integer one if it has a value or integer zero if empty.
113        */
114       public int size() {
115          if( sValue == null || sValue.length() == 0 )
116             return 0;
117          else
118             return 1;
119       }
120    
121       boolean readString( String sElement ) {
122          if( sElement != null || sElement.length() > 0 ) {
123             setValue( deEscape( sElement ) );
124          }
125          return true;
126       }
127    
128       /**
129        * Output the value of this element as a string.<br><br>
130        * This is the simplest case of the more general toString() inherited from
131        * HL7Object.  Ultimately all data end up expressed as SimpleElements and
132        * output here.  The layers around just organize them via delimiters, XML tags,
133        * etc..<br><br>
134        * TODO: Check value for anything that needs to be converted to escape sequences.
135        * @return String with value or an empty string if not set.
136        */
137       public String toString() {
138          if( sValue != null )
139             // Should do escape sequence handling here!
140             return sValue;
141          else
142             return "";
143       }
144    
145       /**
146        * Output the value of this element as a string with HL7 escape
147        * sequences.<br><br>
148        * This is the simplest case of the more general toString() inherited from
149        * HL7Object.  Ultimately all data end up expressed as SimpleElements and
150        * output here.
151        * @return String with value or an empty string if not set.
152        */
153       public String toHL7String() {
154          if( sValue != null )
155             return escape( sValue );
156          else
157             return "";
158       }
159    
160       private String escape( String sIn ) {
161          StringBuffer sOut = new StringBuffer();
162          for( int i = 0; i < sIn.length(); i++ ) {
163             if( sIn.charAt(i) == getSeparator( FIELD_SEP ) ) {
164                sOut.append( getSeparator( ESC_SEP ) );
165                sOut.append( 'F' );
166                sOut.append( getSeparator( ESC_SEP ) );
167             }
168             else if( sIn.charAt(i) == getSeparator( COMP_SEP ) ) {
169                sOut.append( getSeparator( ESC_SEP ) );
170                sOut.append( 'S' );
171                sOut.append( getSeparator( ESC_SEP ) );
172             }
173             else if( sIn.charAt(i) == getSeparator( REP_SEP ) ) {
174                sOut.append( getSeparator( ESC_SEP ) );
175                sOut.append( 'R' );
176                sOut.append( getSeparator( ESC_SEP ) );
177             }
178             else if( sIn.charAt(i) == getSeparator( ESC_SEP ) ) {
179                sOut.append( getSeparator( ESC_SEP ) );
180                sOut.append( 'E' );
181                sOut.append( getSeparator( ESC_SEP ) );
182             }
183             else if( sIn.charAt(i) == getSeparator( SUB_SEP ) ) {
184                sOut.append( getSeparator( ESC_SEP ) );
185                sOut.append( 'T' );
186                sOut.append( getSeparator( ESC_SEP ) );
187             }
188             else {
189                sOut.append( sIn.charAt(i) );
190             }
191          }
192          return sOut.toString();
193       }
194    
195       private String deEscape( String sIn ) {
196          StringBuffer sOut = new StringBuffer();
197          String sSeq = "";
198          for( int i = 0; i < sIn.length(); i++ ) {
199             if( sIn.charAt(i) == getSeparator( ESC_SEP ) ) {
200                StringBuffer sbSeq = new StringBuffer();
201                while( ++i < sIn.length() && sIn.charAt(i) != getSeparator( ESC_SEP ) ) {
202                   sbSeq.append( sIn.charAt(i) );
203                }
204                sSeq = sbSeq.toString();
205                if( sSeq == "F" )
206                   sOut.append( getSeparator( FIELD_SEP ) );
207                else if( sSeq == "S" )
208                   sOut.append( getSeparator( COMP_SEP ) );
209                else if( sSeq == "R" )
210                   sOut.append( getSeparator( REP_SEP ) );
211                else if( sSeq == "E" )
212                   sOut.append( getSeparator( ESC_SEP ) );
213                else if( sSeq == "T" )
214                   sOut.append( sSeparators.charAt(4) );
215                else if( sSeq.length() > 2 && sSeq.startsWith("0x") ) {
216                   // Handle hex
217                   sOut.append( sSeq );
218                }
219                else if( sSeq.length() > 1 && sSeq.startsWith("U") ) {
220                   // Handle unicode
221                   sOut.append( sSeq );
222                }
223                else if( sSeq.length() > 1 && sSeq.startsWith("W") ) {
224                   // Handle wide character
225                   sOut.append( sSeq );
226                }
227             }
228             else {
229                sOut.append( sIn.charAt(i) );
230             }
231          }
232          return sOut.toString();
233       }
234    
235       /**
236        * Output the element as XML.<br><br>
237        * Outputs the DOM element.
238        * @param iDepth int value for the number of spaces to indent this object.  Used just
239        * to make the XML easier to read as unformatted text.
240        * @return foratted XML text.
241        */
242       public String toXML ( int iDepth ) {
243          if( empty() ) {
244             return "";
245          }
246          else  {
247             // Do any other required escaping here
248             StringBuffer sb = new StringBuffer();
249             String sXMLValue = getValue();
250             if( sXMLValue.indexOf("&") >= 0 ) {
251                StringBuffer sb2 = new StringBuffer();
252                for( int i = 0; i < sValue.length(); i++ ) {
253                   char cNext = sXMLValue.charAt(i);
254                   if( cNext == '&' )
255                      sb2.append( "&" );
256                   else
257                      sb2.append( cNext );
258                }
259                sXMLValue = sb2.toString();
260             }
261             for( int x = 0; x < iDepth; x++ ) sb.append( " " );
262             sb.append( '<' );
263             sb.append( getName() );
264             sb.append( ">" );
265             sb.append( sXMLValue );
266             sb.append( "</" );
267             sb.append( getName() );
268             sb.append( ">\n" );
269             return sb.toString();
270          }
271       } // End toXML()
272    
273    } // End class SimpleElement