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 "SegmentPointer.java".  Description: 
010    "A SegmentPointer is used when parsing traditionally encoded HL7 messages" 
011    
012    The Initial Developer of the Original Code is University Health Network. Copyright (C) 
013    2001.  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    
028    /*
029     * Created on October 15, 2001, 3:19 PM
030     */
031    
032    package ca.uhn.hl7v2.parser;
033    
034    import org.slf4j.Logger;
035    import org.slf4j.LoggerFactory;
036    
037    import ca.uhn.hl7v2.HL7Exception;
038    import ca.uhn.hl7v2.model.Group;
039    import ca.uhn.hl7v2.model.Segment;
040    
041    /**
042     * A SegmentPointer is used when parsing traditionally encoded HL7 messages. 
043     * It acts as a placeholder for a unique segment "slot" in a message structure. 
044     * There is one SegmentPointer per unique segment path (even if the segment 
045     * repeats, and regardless of whether any instances exist).  
046     *
047     * @deprecated PipeParser now uses MessageIterator
048     * @author Bryan Tripp (bryan_tripp@sourceforge.net)
049     */
050    public class SegmentPointer extends Pointer {
051    
052        private static final Logger log = LoggerFactory.getLogger(SegmentPointer.class);
053        private PipeParser parser;
054        private Group parent;
055        private String name;
056        private EncodingCharacters encodingChars;
057        private boolean repeating;
058        private Segment currSegment = null;
059        private boolean currSegmentFull = true;
060    
061        /** 
062         * Creates new SegmentPointer 
063         * @param parser the PipeParser used to parse segments 
064         * @param parent the Group object that would be the parent of any instances of the 
065         *      Segment underlying this SegmentPointer
066         * @param position the position (among siblings; from 0) of the underlying Segment 
067         * @param encodingChars array of encoding characters, starting w/ field delim
068         */
069        public SegmentPointer(PipeParser parser, Group parent, int position, EncodingCharacters encodingChars)
070            throws HL7Exception {
071            this.parser = parser;
072            this.parent = parent;
073            this.encodingChars = encodingChars;
074            this.name = parent.getNames()[position];
075            this.repeating = parent.isRepeating(this.name);
076    
077        }
078    
079        /**
080         * Parses the given String, which must contain a single traditionally encoded 
081         * message segment, into the current repetition of the message Structure 
082         * underlying this Pointer.  See Pointer static fields for return values. 
083         * @throws HL7Exception if there is an error during parsing 
084         */
085        public int setSegment(String segment, boolean correctOrder) throws HL7Exception {
086            int status = Pointer.FILL_FAILED_WRONG_SEGMENT;
087    
088            //make sure segment is right kind
089            if (segment.substring(0, 3).equals(this.name)) {
090                if (correctOrder) {
091                    //make sure empty rep exists
092                    if (prepEmptyInstance()) {
093                        try {
094                            this.parser.parse(this.currSegment, segment, this.encodingChars);
095                        }
096                        catch (HL7Exception e) {
097                            //add segment name info and re-throw
098                            e.setSegmentName(this.name);
099                            throw e;
100                        }
101                        this.currSegmentFull = true;
102                        status = Pointer.FILL_OK;
103                    }
104                    else {
105                        status = Pointer.FILL_FAILED_FULL;
106                    }
107                }
108                else {
109                    status = Pointer.FILL_FAILED_OUT_OF_ORDER;
110                }
111            }
112            log.debug(
113                "Attempt to put segment " + segment.substring(0, 3) + " in " + this.name + ": code = " + status);
114            return status;
115        }
116    
117        /** 
118         * Ensures that there is an empty repetition of the underlying message Structure.  
119         * @returns true if successful, false if structure is non-repeating and full. 
120         */
121        private boolean prepEmptyInstance() throws HL7Exception {
122            boolean success = false;
123    
124            if (this.currSegment == null || (this.repeating && this.currSegmentFull)) {
125                int numExisting = parent.getAll(this.name).length;
126                this.currSegment = (Segment) parent.get(this.name, numExisting); //get next rep            
127                this.currSegmentFull = false;
128                success = true;
129            }
130            else if (!this.currSegmentFull) {
131                success = true;
132            }
133    
134            return success;
135        }
136    
137    }