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 }