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            ValidationContext context = message.getParser().getValidationContext();
088            String version = message.getVersion();
089
090            if (context != null) {
091                Collection<PrimitiveTypeRule> rules = context.getPrimitiveRules(version, getName(), this); 
092        
093                for (PrimitiveTypeRule rule : rules) {
094                    theValue = rule.correct(theValue);
095                    ValidationException[] ve = rule.apply(theValue);
096                    if (ve.length > 0) {
097                        throw new DataTypeException(ve[0]);
098                    }
099                }
100            }
101        }
102        
103        myValue = theValue;
104    }
105
106    
107    /**
108     * {@inheritDoc }
109     */
110    @Override
111    public String encode() throws HL7Exception {
112        Parser p = getMessage().getParser();
113        return p.doEncode(this, EncodingCharacters.getInstance(getMessage()));
114    }
115
116
117    /**
118     * {@inheritDoc }
119     */
120    @Override
121    public void parse(String string) throws HL7Exception {
122        if (string == null) {
123                clear();
124                return;
125        }
126        
127        EncodingCharacters encodingCharacters = EncodingCharacters.getInstance(getMessage());
128        char subc = encodingCharacters.getSubcomponentSeparator();
129        char cmpc = encodingCharacters.getComponentSeparator();
130
131        clear();
132        
133        // If the string contains subcomponent delimiters, parse
134        // these as extra components
135        int subcIndex = string.indexOf(subc);
136        int cmpcIndex = string.indexOf(cmpc);
137        if (subcIndex != -1 || cmpcIndex != -1) {
138            
139            //Object ancestor = AbstractMessage.findAncestorOf(this);
140            
141            int index;
142            char escapeChar;
143            if (cmpcIndex != -1) {
144                index = cmpcIndex;
145                escapeChar = cmpc;
146            } else {
147                        index = subcIndex;
148                        escapeChar = subc;
149            }
150            
151                        setValue(string.substring(0, index));
152            while (index != -1) {
153                int prevIndex = index + 1;
154                index = string.indexOf(escapeChar, prevIndex);
155                if (index != -1) {
156                    String nextSubComponent = string.substring(prevIndex, index);
157                    getExtraComponents().getComponent(getExtraComponents().numComponents()).parse(nextSubComponent);
158                } else {
159                    String nextSubComponent = string.substring(prevIndex);
160                    if (nextSubComponent.length() > 0) {
161                        getExtraComponents().getComponent(getExtraComponents().numComponents()).parse(nextSubComponent);
162                    }
163                }
164            }
165            
166        } else {
167        
168                String escaped = getMessage().getParser().getParserConfiguration()
169                .getEscaping().unescape(string, encodingCharacters);
170            setValue(escaped);
171        
172        }
173    }
174
175
176    /**
177     * {@inheritDoc }
178     */
179    @Override
180    public void clear() {
181        super.clear();
182        myValue = null;
183    }
184
185        @Override
186        public boolean isEmpty() throws HL7Exception {
187                return (myValue == null || myValue.length() == 0) && super.isEmpty();
188        }
189
190    public boolean accept(MessageVisitor visitor, Location location) throws HL7Exception {
191        return visitor.visit(this, location);
192    }  
193    
194}