001/**
002The 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. 
004You may obtain a copy of the License at http://www.mozilla.org/MPL/ 
005Software distributed under the License is distributed on an "AS IS" basis, 
006WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the 
007specific language governing rights and limitations under the License. 
008
009The Original Code is "Location.java".  Description: 
010"Location of an validated message element" 
011
012The Initial Developer of the Original Code is University Health Network. Copyright (C) 
0132012.  All Rights Reserved. 
014
015Contributor(s): ______________________________________. 
016
017Alternatively, the contents of this file may be used under the terms of the 
018GNU General Public License (the "GPL"), in which case the provisions of the GPL are 
019applicable instead of those above.  If you wish to allow use of your version of this 
020file only under the terms of the GPL and not to allow others to use your version 
021of this file under the MPL, indicate your decision by deleting  the provisions above 
022and replace  them with the notice and other provisions required by the GPL License.  
023If you do not delete the provisions above, a recipient may use your version of 
024this file under either the MPL or the GPL. 
025 */
026package ca.uhn.hl7v2;
027
028import java.util.Stack;
029
030/**
031 * Location class to determine the location of an element
032 * 
033 * @author Christian Ohr
034 */
035public class Location {
036
037    private Stack<GroupLocation> groups = new Stack<GroupLocation>();
038        private String segmentName = null;
039        private int segmentRepetition = -1;
040        private int field = -1;
041        private int fieldRepetition = -1;
042        private int component = -1;
043        private int subcomponent = -1;
044
045        public static final Location UNKNOWN = new Location();
046
047        public Location() {
048        }
049
050        public Location(Location l) {
051        this.groups = new Stack<GroupLocation>();
052        groups.addAll(l.groups);
053                this.segmentName = l.segmentName;
054                this.segmentRepetition = l.segmentRepetition;
055                this.field = l.field;
056                this.fieldRepetition = l.fieldRepetition;
057                this.component = l.component;
058                this.subcomponent = l.subcomponent;
059        }
060        
061        public boolean isUnknown() {
062            return this == UNKNOWN;
063        }
064
065    public Location pushGroup(String name, int rep) {
066        groups.push(new Location.GroupLocation(name, rep));
067        return this;
068    }
069
070    public void popGroup() {
071        groups.pop();
072    }
073
074        public String getSegmentName() {
075                return segmentName;
076        }
077
078        public Location withSegmentName(String segmentName) {
079                this.segmentName = segmentName;
080                return this;
081        }
082
083        public int getSegmentRepetition() {
084                return segmentRepetition;
085        }
086
087        public Location withSegmentRepetition(int segmentRepetition) {
088                this.segmentRepetition = segmentRepetition;
089                return this;
090        }
091
092        public int getField() {
093                return field;
094        }
095
096        public Location withField(int field) {
097                this.field = field;
098                return this;
099        }
100
101        public int getFieldRepetition() {
102                return fieldRepetition;
103        }
104
105        public Location withFieldRepetition(int fieldRepetition) {
106                this.fieldRepetition = fieldRepetition;
107                return this;
108        }
109
110        public int getComponent() {
111                return component;
112        }
113
114        public Location withComponent(int component) {
115                this.component = component;
116                return this;
117        }
118
119        public int getSubcomponent() {
120                return subcomponent;
121        }
122
123        public Location withSubcomponent(int subcomponent) {
124                this.subcomponent = subcomponent;
125                return this;
126        }
127
128        /**
129         * Bulk setter for field indices
130         * 
131         * @param indices integer array as returned by Terser#getIndices
132         */
133        public Location withFieldIndizes(int[] indices) {
134                field = indices[0];
135                fieldRepetition = indices[1];
136                component = indices[2];
137                subcomponent = indices[3];
138                return this;
139        }
140
141
142        
143        @Override
144        public String toString() {
145                StringBuilder sb = new StringBuilder();
146        if (!groups.isEmpty()) {
147            sb.append('/');
148            for (GroupLocation gl : groups) {
149                sb.append(gl.groupName);
150                if (gl.repetition >= 0) {
151                    sb.append('(')
152                    .append(gl.repetition)
153                    .append(")");
154                }
155                sb.append("/");
156            }
157        }
158                if (segmentName != null) {
159                        sb.append(segmentName);
160                        if (segmentRepetition > 0) {
161                                sb.append("(").append(segmentRepetition).append(")");
162                        }
163                        if (field > 0) {
164                                sb.append("-").append(field);
165                                if (fieldRepetition >= 0) {
166                                        sb.append("(").append(fieldRepetition).append(")");
167                                }
168                                if (component > 0) {
169                                        sb.append("-").append(component);
170                                        if (subcomponent > 0) {
171                                                sb.append("-").append(subcomponent);
172                                        }
173                                }
174                        }
175                } else {
176                        if (sb.length() == 0) sb.append("unknown location");
177                }
178                return sb.toString();
179        }
180
181        @Override
182        public int hashCode() {
183                final int prime = 31;
184                int result = 1;
185        result = prime * result + ((groups == null) ? 0 : groups.hashCode());
186                result = prime * result + component;
187                result = prime * result + field;
188                result = prime * result + fieldRepetition;
189                result = prime * result + ((segmentName == null) ? 0 : segmentName.hashCode());
190                result = prime * result + segmentRepetition;
191                result = prime * result + subcomponent;
192                return result;
193        }
194
195        @Override
196        public boolean equals(Object obj) {
197                if (this == obj)
198                        return true;
199                if (obj == null)
200                        return false;
201                if (getClass() != obj.getClass())
202                        return false;
203                Location other = (Location) obj;
204                if (groups == null) {
205                    if (other.groups != null)
206                        return false;
207                } else if (!groups.equals(other.groups))
208                    return false;
209                if (component != other.component)
210                        return false;
211                if (field != other.field)
212                        return false;
213                if (fieldRepetition != other.fieldRepetition)
214                        return false;
215                if (segmentName == null) {
216                        if (other.segmentName != null)
217                                return false;
218                } else if (!segmentName.equals(other.segmentName))
219                        return false;
220                if (segmentRepetition != other.segmentRepetition)
221                        return false;
222                if (subcomponent != other.subcomponent)
223                        return false;
224                return true;
225        }
226
227    private class GroupLocation {
228        String groupName;
229        int repetition;
230
231        private GroupLocation(String groupName, int repetition) {
232            this.groupName = groupName;
233            this.repetition = repetition;
234        }
235    }
236
237}