001/**
002The contents of this file are subject to the Mozilla Public License Version 1.1
003(the "License"); you may not use this file except in compliance with the License.
004You may obtain a copy of the License at http://www.mozilla.org/MPL/
005Software distributed under the License is distributed on an "AS IS" basis,
006WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the
007specific language governing rights and limitations under the License.
008
009The Original Code is "EncodingCharacters.java".  Description:
010"Represents the set of special characters used to encode traditionally encoded HL7 messages."
011
012The Initial Developer of the Original Code is University Health Network. Copyright (C)
0132001.  All Rights Reserved.
014
015Contributor(s): ______________________________________.
016
017Alternatively, the contents of this file may be used under the terms of the
018GNU General Public License (the  "GPL"), in which case the provisions of the GPL are
019applicable instead of those above.  If you wish to allow use of your version of this
020file only under the terms of the GPL and not to allow others to use your version
021of this file under the MPL, indicate your decision by deleting  the provisions above
022and replace  them with the notice and other provisions required by the GPL License.
023If you do not delete the provisions above, a recipient may use your version of
024this file under either the MPL or the GPL.
025
026*/
027package ca.uhn.hl7v2.parser;
028
029import ca.uhn.hl7v2.HL7Exception;
030import ca.uhn.hl7v2.model.Message;
031
032/**
033 * Represents the set of special characters used to encode traditionally
034 * encoded HL7 messages.
035 *
036 * @author Bryan Tripp (bryan_tripp@sourceforge.net)
037 */
038
039public class EncodingCharacters implements Cloneable {
040    
041    private char fieldSep;
042    private char[] encChars;
043    
044    /**
045     * Creates new EncodingCharacters object with the given character
046     * values. If the encodingCharacters argument is null, the default
047     * values are used.
048     *
049     * @param fieldSeparator field seperator
050     * @param encodingCharacters consists of the characters that appear in
051     *      MSH-2 (see section 2.8 of the HL7 spec).  The characters are
052     *      Component Separator, Repetition Separator, Escape Character,
053     *      Subcomponent Separator, and, as of v2.7, the Truncation Character 
054     *      (in that order).
055     */
056    
057    public EncodingCharacters(char fieldSeparator, String encodingCharacters) {
058        this.fieldSep = fieldSeparator;
059        this.encChars = new char[5];
060        
061        if (encodingCharacters == null) {
062            setComponentSeparator('^');            
063            setRepetitionSeparator('~');            
064            setEscapeCharacter('\\');
065            setSubcomponentSeparator('&');
066            setTruncationCharacter('#');
067        } else {
068            encodingCharacters.getChars(0, 4, this.encChars, 0);
069            // Add truncation character if available
070            if (encodingCharacters.length() > 4) {
071                char extraChar = encodingCharacters.charAt(4);
072                if (extraChar != fieldSeparator) {
073                    setTruncationCharacter(extraChar);
074                }
075            }
076        }
077        
078    }
079
080    /**
081     * Returns an instance using the MSH-1 and MSH-2 values of the given message
082     *
083     * @param message the message
084     * @return the encoding characters for this message
085     * @throws HL7Exception If either MSH-1 or MSH-2 are not populated
086     * @since 1.0
087     */
088    public static EncodingCharacters getInstance(Message message) throws HL7Exception {
089
090        final String encodingCharactersValue = message.getEncodingCharactersValue();
091        if (encodingCharactersValue == null || encodingCharactersValue.length() == 0) {
092            throw new HL7Exception("encoding characters not populated");
093        }
094
095        final Character fieldSeparatorValue = message.getFieldSeparatorValue();
096        if (fieldSeparatorValue == null) {
097            throw new HL7Exception("Field separator not populated");
098        }
099
100        return new EncodingCharacters(fieldSeparatorValue, encodingCharactersValue);
101    }
102
103    
104    
105    public EncodingCharacters(char fieldSeparator, char componentSeparator, char repetitionSeparator,
106                              char escapeCharacter, char subcomponentSeparator) {
107        this(fieldSeparator, String.valueOf(componentSeparator) + repetitionSeparator + 
108                escapeCharacter + subcomponentSeparator);
109    }
110
111    public EncodingCharacters(char fieldSeparator, char componentSeparator, char repetitionSeparator,
112                              char escapeCharacter, char subcomponentSeparator, char truncationCharacter) {
113        this(fieldSeparator, String.valueOf(componentSeparator) + repetitionSeparator + 
114                escapeCharacter + subcomponentSeparator + truncationCharacter);
115    }    
116    
117    /** copies contents of "other" */
118    
119    public EncodingCharacters(EncodingCharacters other) {
120        this.fieldSep = other.getFieldSeparator();
121        this.encChars = new char[5];
122        setComponentSeparator(other.getComponentSeparator());
123        setRepetitionSeparator(other.getRepetitionSeparator());
124        setEscapeCharacter(other.getEscapeCharacter());
125        setSubcomponentSeparator(other.getSubcomponentSeparator());
126        setTruncationCharacter(other.getTruncationCharacter());
127    }
128    
129    /**
130     * Returns the field separator.
131     *
132     * @return the field separator
133     */
134    public char getFieldSeparator() {
135        return this.fieldSep;
136    }
137    
138    /**
139     * Returns the component separator.
140     *
141     * @return the component separator
142     */
143    public char getComponentSeparator() {
144        return this.encChars[0];
145    }
146    
147    /**
148     * Returns the repetition separator.
149     *
150     * @return the repetition separator
151     */
152    public char getRepetitionSeparator() {
153        return this.encChars[1];
154    }
155    
156    /**
157     * Returns the escape character.
158     *
159     * @return the escape character
160     */
161    public char getEscapeCharacter() {
162        return this.encChars[2];
163    }
164    
165    /**
166     * Returns the subcomponent separator.
167     *
168     * @return the subcomponent separator
169     */
170    public char getSubcomponentSeparator() {
171        return this.encChars[3];
172    }
173
174    /**
175     * Returns the truncation character.
176     *
177     * @return the truncation character
178     */
179    public char getTruncationCharacter() {
180        return this.encChars[4];
181    }
182    
183    /**
184     * Returns the encoding characters (not including field separator)
185     * as a string.
186     */
187    public String toString() {
188        return String.valueOf(encChars);
189    }
190    
191    public Object clone() throws CloneNotSupportedException
192    {
193        super.clone();
194        return new EncodingCharacters(this);
195    }
196    
197    public void setFieldSeparator(char newFieldSep) {
198        this.fieldSep = newFieldSep;
199    }
200    
201    public void setComponentSeparator(char newComponentSep) {
202        this.encChars[0] = newComponentSep;
203    }
204    
205    public void setRepetitionSeparator(char newRepetitionSep) {
206        this.encChars[1] = newRepetitionSep;
207    }
208    
209    public void setEscapeCharacter(char newEscapeChar) {
210        this.encChars[2] = newEscapeChar;
211    }
212    
213    public void setSubcomponentSeparator(char newSubcomponentSep) {
214        this.encChars[3] = newSubcomponentSep;
215    }
216
217    public void setTruncationCharacter(char newTruncationChar) {
218        this.encChars[4] = newTruncationChar;
219    }
220    
221    /** @see java.lang.Object#equals */
222    public boolean equals(Object o) {
223        if (o instanceof EncodingCharacters) {
224            EncodingCharacters other = (EncodingCharacters) o;
225            return (this.getFieldSeparator() == other.getFieldSeparator()
226                && this.getComponentSeparator() == other.getComponentSeparator()
227                && this.getEscapeCharacter() == other.getEscapeCharacter() 
228                && this.getRepetitionSeparator() == other.getRepetitionSeparator()
229                && this.getSubcomponentSeparator() == other.getSubcomponentSeparator()
230                && this.getTruncationCharacter() == other.getTruncationCharacter());
231        } else {
232            return false;
233        }   
234    }
235    
236    /** @see java.lang.Object#hashCode */
237    public int hashCode() {
238        return 7 * (int) this.getComponentSeparator()
239            * (int) this.getEscapeCharacter()
240            * (int) this.getFieldSeparator()
241            * (int) this.getRepetitionSeparator()
242            * (int) this.getSubcomponentSeparator()
243            * (int) this.getTruncationCharacter();
244    }  
245
246    /**
247     * Returns an instance of encoding characters with the standard ER7 encoding characters
248     * defined: |^~\&
249     *
250     * @return a default instance of encoding characters
251     */
252        public static EncodingCharacters defaultInstance() {
253                return new EncodingCharacters('|', null);
254        }
255    
256}
257