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 = 0;
040        private int field = -1;
041        private int fieldRepetition = 0;
042        private int component = -1;
043        private int subcomponent = -1;
044
045    private boolean componentLevel;
046
047        public static final Location UNKNOWN = new Location();
048
049        public Location() {
050        }
051
052        public Location(Location l) {
053        this.groups = new Stack<GroupLocation>();
054        groups.addAll(l.groups);
055                this.segmentName = l.segmentName;
056                this.segmentRepetition = l.segmentRepetition;
057                this.field = l.field;
058                this.fieldRepetition = l.fieldRepetition;
059                this.component = l.component;
060                this.subcomponent = l.subcomponent;
061        }
062
063
064        
065        public boolean isUnknown() {
066            return this == UNKNOWN;
067        }
068
069    public Location pushGroup(String name, int rep) {
070        groups.push(new Location.GroupLocation(name, rep));
071        return this;
072    }
073
074    public void popGroup() {
075        groups.pop();
076    }
077
078    public GroupLocation getGroupLocation() {
079        return groups.peek();
080    }
081
082        public String getSegmentName() {
083                return segmentName;
084        }
085
086        public Location withSegmentName(String segmentName) {
087                this.segmentName = segmentName;
088                return this;
089        }
090
091    public boolean isComponentLevel() {
092        return componentLevel;
093    }
094
095    public Location atComponentLevel(boolean componentLevel) {
096        this.componentLevel = componentLevel;
097        return this;
098    }
099
100        public int getSegmentRepetition() {
101                return segmentRepetition;
102        }
103
104        public Location withSegmentRepetition(int segmentRepetition) {
105                this.segmentRepetition = segmentRepetition;
106                return this;
107        }
108
109        public int getField() {
110                return field;
111        }
112
113        public Location withField(int field) {
114                this.field = field;
115                return this;
116        }
117
118        public int getFieldRepetition() {
119                return fieldRepetition;
120        }
121
122        public Location withFieldRepetition(int fieldRepetition) {
123                this.fieldRepetition = fieldRepetition;
124                return this;
125        }
126
127        public int getComponent() {
128                return component;
129        }
130
131        public Location withComponent(int component) {
132                this.component = component;
133                return this;
134        }
135
136        public int getSubcomponent() {
137                return subcomponent;
138        }
139
140        public Location withSubcomponent(int subcomponent) {
141                this.subcomponent = subcomponent;
142                return this;
143        }
144
145        /**
146         * Bulk setter for field indices
147         * 
148         * @param indices integer array as returned by Terser#getIndices
149         */
150        public Location withFieldIndizes(int[] indices) {
151                field = indices[0];
152                fieldRepetition = indices[1];
153                component = indices[2];
154                subcomponent = indices[3];
155                return this;
156        }
157
158
159        
160        @Override
161        public String toString() {
162                StringBuilder sb = new StringBuilder();
163        if (!groups.isEmpty()) {
164            sb.append('/');
165            for (GroupLocation gl : groups) {
166                sb.append(gl.groupName);
167                if (gl.repetition >= 0) {
168                    sb.append('(')
169                    .append(gl.repetition)
170                    .append(")");
171                }
172                sb.append("/");
173            }
174        }
175                if (segmentName != null) {
176                        sb.append(segmentName);
177                        if (segmentRepetition > 0) {
178                                sb.append("(").append(segmentRepetition).append(")");
179                        }
180                        if (field > 0) {
181                                sb.append("-").append(field);
182                                if (fieldRepetition >= 0) {
183                                        sb.append("(").append(fieldRepetition).append(")");
184                                }
185                                if (component > 0) {
186                                        sb.append("-").append(component);
187                                        if (subcomponent > 0) {
188                                                sb.append("-").append(subcomponent);
189                                        }
190                                }
191                        }
192                } else {
193                        if (sb.length() == 0) sb.append("unknown location");
194                }
195                return sb.toString();
196        }
197
198        @Override
199        public int hashCode() {
200                final int prime = 31;
201                int result = 1;
202        result = prime * result + ((groups == null) ? 0 : groups.hashCode());
203                result = prime * result + component;
204                result = prime * result + field;
205                result = prime * result + fieldRepetition;
206                result = prime * result + ((segmentName == null) ? 0 : segmentName.hashCode());
207                result = prime * result + segmentRepetition;
208                result = prime * result + subcomponent;
209                return result;
210        }
211
212        @Override
213        public boolean equals(Object obj) {
214                if (this == obj)
215                        return true;
216                if (obj == null)
217                        return false;
218                if (getClass() != obj.getClass())
219                        return false;
220                Location other = (Location) obj;
221                if (groups == null) {
222                    if (other.groups != null)
223                        return false;
224                } else if (!groups.equals(other.groups))
225                    return false;
226                if (component != other.component)
227                        return false;
228                if (field != other.field)
229                        return false;
230                if (fieldRepetition != other.fieldRepetition)
231                        return false;
232                if (segmentName == null) {
233                        if (other.segmentName != null)
234                                return false;
235                } else if (!segmentName.equals(other.segmentName))
236                        return false;
237                if (segmentRepetition != other.segmentRepetition)
238                        return false;
239                if (subcomponent != other.subcomponent)
240                        return false;
241                return true;
242        }
243
244    private static class GroupLocation {
245        String groupName;
246        int repetition;
247
248        private GroupLocation(String groupName, int repetition) {
249            this.groupName = groupName;
250            this.repetition = repetition;
251        }
252
253        public String getGroupName() {
254            return groupName;
255        }
256
257        public int getRepetition() {
258            return repetition;
259        }
260    }
261
262}