001/**
002 * The 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.
004 * You may obtain a copy of the License at http://www.mozilla.org/MPL/
005 * Software distributed under the License is distributed on an "AS IS" basis,
006 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the
007 * specific language governing rights and limitations under the License.
008 *
009 * The Original Code is "AbstractPrimitive.java".  Description:
010 * "Base class for Primitives.  Performs validation in setValue()."
011 *
012 * The Initial Developer of the Original Code is University Health Network. Copyright (C)
013 * 2001-2005.  All Rights Reserved.
014 *
015 * Contributor(s): ______________________________________.
016 *
017 * Alternatively, the contents of this file may be used under the terms of the
018 * GNU General Public License (the  �GPL�), in which case the provisions of the GPL are
019 * applicable instead of those above.  If you wish to allow use of your version of this
020 * file only under the terms of the GPL and not to allow others to use your version
021 * of this file under the MPL, indicate your decision by deleting  the provisions above
022 * and replace  them with the notice and other provisions required by the GPL License.
023 * If you do not delete the provisions above, a recipient may use your version of
024 * this file under either the MPL or the GPL.
025 *
026 */
027
028package ca.uhn.hl7v2.model;
029
030import java.util.Collection;
031
032import ca.uhn.hl7v2.HL7Exception;
033import ca.uhn.hl7v2.Location;
034import ca.uhn.hl7v2.parser.EncodingCharacters;
035import ca.uhn.hl7v2.parser.Parser;
036import ca.uhn.hl7v2.validation.PrimitiveTypeRule;
037import ca.uhn.hl7v2.validation.ValidationContext;
038import ca.uhn.hl7v2.validation.ValidationException;
039
040/**
041 * Base class for Primitives.  Performs validation in setValue().
042 *    
043 * @author Bryan Tripp
044 */
045@SuppressWarnings("serial")
046public abstract class AbstractPrimitive extends AbstractType implements Primitive {
047    
048    /**
049     * @param message message to which this type belongs
050     */
051    public AbstractPrimitive(Message message) {
052        super(message);
053    }
054
055    private String myValue;
056    
057    /** 
058     * Returns the value of getValue() 
059     * @see java.lang.Object#toString 
060     */
061    public String toString() {
062        return this.getValue();
063    }
064    
065    /**
066     * @see ca.uhn.hl7v2.model.Primitive#getValue()
067     */
068    public String getValue() {
069        return myValue;
070    }
071
072    /**
073     * Sets the value of this Primitive, first performing validation as specified 
074     * by <code>getMessage().getValidationContext()</code>.  No validation is performed 
075     * if getMessage() returns null. 
076     * <p>
077     * Note: as of the next HAPI release, the ValidationContext will be retrieved
078     * from getParser().getValidationContext(), which ultimately is the ValidationContext
079     * of the active HapiContext.
080     * 
081     * @see ca.uhn.hl7v2.model.Primitive#setValue(String)
082     */    
083    public void setValue(String theValue) throws DataTypeException {
084        Message message = getMessage();
085
086        if (message != null) {
087                // Note: this will change in future to reuse the Parser's/HapiContext's
088                // ValidationContext.
089            ValidationContext context = message.getValidationContext();
090            String version = message.getVersion();
091
092            if (context != null) {
093                Collection<PrimitiveTypeRule> rules = context.getPrimitiveRules(version, getName(), this); 
094        
095                for (PrimitiveTypeRule rule : rules) {
096                    theValue = rule.correct(theValue);
097                    ValidationException[] ve = rule.apply(theValue);
098                    if (ve.length > 0) {
099                        throw new DataTypeException(ve[0]);
100                    }
101                }
102            }
103        }
104        
105        myValue = theValue;
106    }
107
108    
109    /**
110     * {@inheritDoc }
111     */
112    @Override
113    public String encode() throws HL7Exception {
114        Parser p = getMessage().getParser();
115        return p.doEncode(this, EncodingCharacters.getInstance(getMessage()));
116    }
117
118
119    /**
120     * {@inheritDoc }
121     */
122    @Override
123    public void parse(String string) throws HL7Exception {
124        if (string == null) {
125                clear();
126                return;
127        }
128        
129        EncodingCharacters encodingCharacters = EncodingCharacters.getInstance(getMessage());
130        char subc = encodingCharacters.getSubcomponentSeparator();
131        char cmpc = encodingCharacters.getComponentSeparator();
132
133        clear();
134        
135        // If the string contains subcomponent delimiters, parse
136        // these as extra components
137        int subcIndex = string.indexOf(subc);
138        int cmpcIndex = string.indexOf(cmpc);
139        if (subcIndex != -1 || cmpcIndex != -1) {
140            
141            //Object ancestor = AbstractMessage.findAncestorOf(this);
142            
143            int index;
144            char escapeChar;
145            if (cmpcIndex != -1) {
146                index = cmpcIndex;
147                escapeChar = cmpc;
148            } else {
149                        index = subcIndex;
150                        escapeChar = subc;
151            }
152            
153                        setValue(string.substring(0, index));
154            while (index != -1) {
155                int prevIndex = index + 1;
156                index = string.indexOf(escapeChar, prevIndex);
157                if (index != -1) {
158                    String nextSubComponent = string.substring(prevIndex, index);
159                    getExtraComponents().getComponent(getExtraComponents().numComponents()).parse(nextSubComponent);
160                } else {
161                    String nextSubComponent = string.substring(prevIndex);
162                    if (nextSubComponent.length() > 0) {
163                        getExtraComponents().getComponent(getExtraComponents().numComponents()).parse(nextSubComponent);
164                    }
165                }
166            }
167            
168        } else {
169        
170                String escaped = getMessage().getParser().getParserConfiguration()
171                .getEscaping().unescape(string, encodingCharacters);
172            setValue(escaped);
173        
174        }
175    }
176
177
178    /**
179     * {@inheritDoc }
180     */
181    @Override
182    public void clear() {
183        super.clear();
184        myValue = null;
185    }
186
187        @Override
188        public boolean isEmpty() throws HL7Exception {
189                return (myValue == null || myValue.length() == 0) && super.isEmpty();
190        }
191
192    public boolean accept(MessageVisitor visitor, Location location) throws HL7Exception {
193        return visitor.visit(this, location);
194    }  
195    
196}