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 "StructureDefinition.java".  Description: 
010    "A definition element" 
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    package ca.uhn.hl7v2.parser;
028    
029    import java.util.ArrayList;
030    import java.util.HashSet;
031    import java.util.Set;
032    
033    /**
034     * Defines
035     * 
036     * @author James
037     * 
038     */
039    public class StructureDefinition implements IStructureDefinition {
040    
041        private HashSet<String> myAllChildrenNames;
042        private HashSet<String> myAllFirstLeafNames;
043        private ArrayList<StructureDefinition> myChildren = new ArrayList<StructureDefinition>();
044        private IStructureDefinition myFirstSibling;
045        private boolean myFirstSiblingIsSet;
046        private Boolean myIsFinalChildOfParent;
047        private boolean myIsRepeating;
048        private boolean myIsRequired;
049        private boolean myIsSegment;
050        private String myName;
051        private String myNameAsItAppearsInParent;
052        private Set<String> myNamesOfAllPossibleFollowingLeaves;
053        private IStructureDefinition myNextLeaf;
054        private IStructureDefinition myNextSibling;
055        private IStructureDefinition myParent;
056        private int myPosition;
057    
058    
059        /**
060         * Constructor
061         */
062        public StructureDefinition() {
063        }
064    
065    
066        /**
067         * Setter
068         */
069        void addChild(StructureDefinition theChild) {
070            myChildren.add(theChild);
071        }
072    
073    
074        /**
075         * {@inheritDoc }
076         */
077        @Override
078        public boolean equals(Object theObj) {
079            if (theObj == null || !(theObj instanceof StructureDefinition)) {
080                return false;
081            }
082            StructureDefinition o = (StructureDefinition) theObj;
083            return o.myName.equals(myName) && o.myPosition == myPosition;
084        }
085    
086    
087        /**
088         * {@inheritDoc }
089         */
090        public HashSet<String> getAllChildNames() {
091            if (myAllChildrenNames == null) {
092                myAllChildrenNames = new HashSet<String>();
093                for (IStructureDefinition next : myChildren) {
094                    myAllChildrenNames.add(next.getName());
095                    myAllChildrenNames.addAll(next.getAllChildNames());
096                }
097            }
098    
099            return myAllChildrenNames;
100        }
101    
102    
103        /**
104         * {@inheritDoc }
105         */
106        public HashSet<String> getAllPossibleFirstChildren() {
107            if (myAllFirstLeafNames == null) {
108                myAllFirstLeafNames = new HashSet<String>();
109                for (IStructureDefinition next : myChildren) {
110                    myAllFirstLeafNames.addAll(next.getAllPossibleFirstChildren());
111                    if (next.isRequired()) {
112                        break;
113                    }
114                }
115    
116                myAllFirstLeafNames.add(getName());
117            }
118    
119            return myAllFirstLeafNames;
120        }
121    
122    
123        /**
124         * {@inheritDoc }
125         */
126        public ArrayList<StructureDefinition> getChildren() {
127            return myChildren;
128        }
129    
130    
131        /**
132         * {@inheritDoc }
133         */
134        public IStructureDefinition getFirstChild() {
135            return myChildren.get(0);
136        }
137    
138    
139        /**
140         * {@inheritDoc }
141         */
142        public IStructureDefinition getFirstSibling() {
143            if (!myFirstSiblingIsSet) {
144                if (myParent == null) {
145                    myFirstSibling = null;
146                } else if (myParent.getChildren().get(0) == this) {
147                    myFirstSibling = null;
148                } else {
149                    myFirstSibling = myParent.getChildren().get(0);
150                }
151                myFirstSiblingIsSet = true;
152            }
153    
154            return myFirstSibling;
155        }
156    
157    
158        /**
159         * {@inheritDoc }
160         */
161        public String getName() {
162            return myName;
163        }
164    
165    
166        /**
167         * {@inheritDoc}
168         */
169        public String getNameAsItAppearsInParent() {
170            return myNameAsItAppearsInParent;
171        }
172    
173    
174        /**
175         * {@inheritDoc }
176         */
177        public Set<String> getNamesOfAllPossibleFollowingLeaves() {
178            if (myNamesOfAllPossibleFollowingLeaves != null) {
179                return myNamesOfAllPossibleFollowingLeaves;
180            }
181    
182            myNamesOfAllPossibleFollowingLeaves = new HashSet<String>();
183    
184            IStructureDefinition nextLeaf = getNextLeaf();
185            if (nextLeaf != null) {
186                myNamesOfAllPossibleFollowingLeaves.add(nextLeaf.getName());
187                myNamesOfAllPossibleFollowingLeaves.addAll(nextLeaf.getNamesOfAllPossibleFollowingLeaves());
188            }
189    
190            IStructureDefinition parent = myParent;
191            while (parent != null) {
192                if (parent.isRepeating()) {
193                    myNamesOfAllPossibleFollowingLeaves.addAll(parent.getAllPossibleFirstChildren());
194                }
195                parent = parent.getParent();
196            }
197    
198            return myNamesOfAllPossibleFollowingLeaves;
199    
200        }
201    
202    
203        /**
204         * {@inheritDoc }
205         */
206        public IStructureDefinition getNextLeaf() {
207            return myNextLeaf;
208        }
209    
210    
211        /**
212         * {@inheritDoc }
213         */
214        public IStructureDefinition getNextSibling() {
215            if (myNextSibling != null) {
216                return myNextSibling;
217            }
218    
219            if (isFinalChildOfParent()) {
220                throw new IllegalStateException("Final child");
221            }
222    
223            myNextSibling = myParent.getChildren().get(myPosition + 1);
224            return myNextSibling;
225        }
226    
227    
228        /**
229         * {@inheritDoc }
230         */
231        public IStructureDefinition getParent() {
232            return myParent;
233        }
234    
235    
236        /**
237         * {@inheritDoc }
238         */
239        public int getPosition() {
240            return myPosition;
241        }
242    
243    
244        /**
245         * {@inheritDoc }
246         */
247        public boolean hasChildren() {
248            return myChildren.isEmpty() == false;
249        }
250    
251    
252        /**
253         * {@inheritDoc }
254         */
255        @Override
256        public int hashCode() {
257            return 17 * myName.hashCode() * myPosition;
258        }
259    
260    
261        /**
262         * {@inheritDoc }
263         */
264        public boolean isFinalChildOfParent() {
265            if (myIsFinalChildOfParent != null) {
266                return myIsFinalChildOfParent;
267            }
268    
269            if (myParent == null) {
270                myIsFinalChildOfParent = true;
271            } else {
272                myIsFinalChildOfParent = (myPosition == (myParent.getChildren().size() - 1));
273            }
274    
275            return myIsFinalChildOfParent;
276        }
277    
278    
279        /**
280         * {@inheritDoc }
281         */
282        public boolean isRepeating() {
283            return myIsRepeating;
284        }
285    
286    
287        /**
288         * {@inheritDoc }
289         */
290        public boolean isRequired() {
291            return myIsRequired;
292        }
293    
294    
295        /**
296         * {@inheritDoc }
297         */
298        public boolean isSegment() {
299            return myIsSegment;
300        }
301    
302    
303        /**
304         * Setter
305         */
306        void setName(String theName) {
307            myName = theName;
308        }
309    
310    
311        /**
312         * Setter
313         */
314        void setNameAsItAppearsInParent(String theName) {
315            myNameAsItAppearsInParent = theName;
316        }
317    
318    
319        /**
320         * Setter
321         */
322        void setNextLeaf(IStructureDefinition theNextLeaf) {
323            myNextLeaf = theNextLeaf;
324        }
325    
326    
327        /**
328         * Setter
329         */
330        void setParent(IStructureDefinition theParent) {
331            myParent = theParent;
332        }
333    
334    
335        /**
336         * Setter
337         */
338        void setPosition(int thePosition) {
339            myPosition = thePosition;
340        }
341    
342    
343        /**
344         * Setter
345         */
346        void setRepeating(boolean theIsRepeating) {
347            myIsRepeating = theIsRepeating;
348        }
349    
350    
351        /**
352         * Setter
353         */
354        void setRequired(boolean theIsRequired) {
355            myIsRequired = theIsRequired;
356        }
357    
358    
359        /**
360         * Setter
361         */
362        void setSegment(boolean theIsSegment) {
363            myIsSegment = theIsSegment;
364        }
365    
366    
367        /**
368         * {@inheritDoc }
369         */
370        @Override
371        public String toString() {
372            return "StructureDefinition[" + getName() + "]";
373        }
374    }