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