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