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