001package org.hl7.fhir.dstu2016may.model; 002 003import java.io.Serializable; 004import java.util.ArrayList; 005import java.util.HashMap; 006import java.util.List; 007import java.util.Map; 008 009import org.hl7.fhir.exceptions.FHIRException; 010import org.hl7.fhir.instance.model.api.IBase; 011import org.hl7.fhir.utilities.xhtml.XhtmlNode; 012 013import ca.uhn.fhir.model.api.IElement; 014 015public abstract class Base implements Serializable, IBase, IElement { 016 017 /** 018 * User appended data items - allow users to add extra information to the class 019 */ 020private Map<String, Object> userData; 021 022 /** 023 * Round tracking xml comments for testing convenience 024 */ 025 private List<String> formatCommentsPre; 026 027 /** 028 * Round tracking xml comments for testing convenience 029 */ 030 private List<String> formatCommentsPost; 031 032 033 public Object getUserData(String name) { 034 if (userData == null) 035 return null; 036 return userData.get(name); 037 } 038 039 public void setUserData(String name, Object value) { 040 if (userData == null) 041 userData = new HashMap<String, Object>(); 042 userData.put(name, value); 043 } 044 045 public void setUserDataINN(String name, Object value) { 046 if (value == null) 047 return; 048 049 if (userData == null) 050 userData = new HashMap<String, Object>(); 051 userData.put(name, value); 052 } 053 054 public boolean hasUserData(String name) { 055 if (userData == null) 056 return false; 057 else 058 return userData.containsKey(name); 059 } 060 061 public String getUserString(String name) { 062 return (String) getUserData(name); 063 } 064 065 public int getUserInt(String name) { 066 if (!hasUserData(name)) 067 return 0; 068 return (Integer) getUserData(name); 069 } 070 071 public boolean hasFormatComment() { 072 return (formatCommentsPre != null && !formatCommentsPre.isEmpty()) || (formatCommentsPost != null && !formatCommentsPost.isEmpty()); 073 } 074 075 public List<String> getFormatCommentsPre() { 076 if (formatCommentsPre == null) 077 formatCommentsPre = new ArrayList<String>(); 078 return formatCommentsPre; 079 } 080 081 public List<String> getFormatCommentsPost() { 082 if (formatCommentsPost == null) 083 formatCommentsPost = new ArrayList<String>(); 084 return formatCommentsPost; 085 } 086 087 // these 3 allow evaluation engines to get access to primitive values 088 public boolean isPrimitive() { 089 return false; 090 } 091 092 public boolean hasPrimitiveValue() { 093 return isPrimitive(); 094 } 095 096 public String primitiveValue() { 097 return null; 098 } 099 100 public abstract String fhirType() ; 101 102 public boolean hasType(String... name) { 103 String t = fhirType(); 104 for (String n : name) 105 if (n.equals(t)) 106 return true; 107 return false; 108 } 109 110 protected abstract void listChildren(List<Property> result) ; 111 112 public void setProperty(String name, Base value) throws FHIRException { 113 throw new FHIRException("Attempt to set unknown property "+name); 114 } 115 116 public Base addChild(String name) throws FHIRException { 117 throw new FHIRException("Attempt to add child with unknown name "+name); 118 } 119 120 /** 121 * Supports iterating the children elements in some generic processor or browser 122 * All defined children will be listed, even if they have no value on this instance 123 * 124 * Note that the actual content of primitive or xhtml elements is not iterated explicitly. 125 * To find these, the processing code must recognise the element as a primitive, typecast 126 * the value to a {@link Type}, and examine the value 127 * 128 * @return a list of all the children defined for this element 129 */ 130 public List<Property> children() { 131 List<Property> result = new ArrayList<Property>(); 132 listChildren(result); 133 return result; 134 } 135 136 public Property getChildByName(String name) { 137 List<Property> children = new ArrayList<Property>(); 138 listChildren(children); 139 for (Property c : children) 140 if (c.getName().equals(name)) 141 return c; 142 return null; 143 } 144 145 public List<Base> listChildrenByName(String name) throws FHIRException { 146 List<Base> result = new ArrayList<Base>(); 147 for (Base b : listChildrenByName(name, true)) 148 if (b != null) 149 result.add(b); 150 return result; 151 } 152 153 public Base[] listChildrenByName(String name, boolean checkValid) throws FHIRException { 154 if (name.equals("*")) { 155 List<Property> children = new ArrayList<Property>(); 156 listChildren(children); 157 List<Base> result = new ArrayList<Base>(); 158 for (Property c : children) 159 if (name.equals("*") || c.getName().equals(name) || (c.getName().endsWith("[x]") && c.getName().startsWith(name))) 160 result.addAll(c.getValues()); 161 return result.toArray(new Base[result.size()]); 162 } 163 else 164 return getProperty(name.hashCode(), name, checkValid); 165 } 166 167 public boolean isEmpty() { 168 return true; // userData does not count 169 } 170 171 public boolean equalsDeep(Base other) { 172 return other == this; 173 } 174 175 public boolean equalsShallow(Base other) { 176 return other == this; 177 } 178 179 public static boolean compareDeep(List<? extends Base> e1, List<? extends Base> e2, boolean allowNull) { 180 if (noList(e1) && noList(e2) && allowNull) 181 return true; 182 if (noList(e1) || noList(e2)) 183 return false; 184 if (e1.size() != e2.size()) 185 return false; 186 for (int i = 0; i < e1.size(); i++) { 187 if (!compareDeep(e1.get(i), e2.get(i), allowNull)) 188 return false; 189 } 190 return true; 191 } 192 193 private static boolean noList(List<? extends Base> list) { 194 return list == null || list.isEmpty(); 195 } 196 197 public static boolean compareDeep(Base e1, Base e2, boolean allowNull) { 198 if (e1 == null && e2 == null && allowNull) 199 return true; 200 if (e1 == null || e2 == null) 201 return false; 202 if (e2.isMetadataBased() && !e1.isMetadataBased()) // respect existing order for debugging consistency; outcome must be the same either way 203 return e2.equalsDeep(e1); 204 else 205 return e1.equalsDeep(e2); 206 } 207 208 public static boolean compareDeep(XhtmlNode div1, XhtmlNode div2, boolean allowNull) { 209 if (div1 == null && div2 == null && allowNull) 210 return true; 211 if (div1 == null || div2 == null) 212 return false; 213 return div1.equalsDeep(div2); 214 } 215 216 217 public static boolean compareValues(List<? extends PrimitiveType> e1, List<? extends PrimitiveType> e2, boolean allowNull) { 218 if (e1 == null && e2 == null && allowNull) 219 return true; 220 if (e1 == null || e2 == null) 221 return false; 222 if (e1.size() != e2.size()) 223 return false; 224 for (int i = 0; i < e1.size(); i++) { 225 if (!compareValues(e1.get(i), e2.get(i), allowNull)) 226 return false; 227 } 228 return true; 229 } 230 231 public static boolean compareValues(PrimitiveType e1, PrimitiveType e2, boolean allowNull) { 232 if (e1 == null && e2 == null && allowNull) 233 return true; 234 if (e1 == null || e2 == null) 235 return false; 236 return e1.equalsShallow(e2); 237 } 238 239 // -- converters for property setters 240 241 242 public BooleanType castToBoolean(Base b) throws FHIRException { 243 if (b instanceof BooleanType) 244 return (BooleanType) b; 245 else 246 throw new FHIRException("Unable to convert a "+b.getClass().getName()+" to a Boolean"); 247 } 248 249 public IntegerType castToInteger(Base b) throws FHIRException { 250 if (b instanceof IntegerType) 251 return (IntegerType) b; 252 else 253 throw new FHIRException("Unable to convert a "+b.getClass().getName()+" to a Integer"); 254 } 255 256 public DecimalType castToDecimal(Base b) throws FHIRException { 257 if (b instanceof DecimalType) 258 return (DecimalType) b; 259 else 260 throw new FHIRException("Unable to convert a "+b.getClass().getName()+" to a Decimal"); 261 } 262 263 public Base64BinaryType castToBase64Binary(Base b) throws FHIRException { 264 if (b instanceof Base64BinaryType) 265 return (Base64BinaryType) b; 266 else 267 throw new FHIRException("Unable to convert a "+b.getClass().getName()+" to a Base64Binary"); 268 } 269 270 public InstantType castToInstant(Base b) throws FHIRException { 271 if (b instanceof InstantType) 272 return (InstantType) b; 273 else 274 throw new FHIRException("Unable to convert a "+b.getClass().getName()+" to a Instant"); 275 } 276 277 public StringType castToString(Base b) throws FHIRException { 278 if (b instanceof StringType) 279 return (StringType) b; 280 else if (b.hasPrimitiveValue()) 281 return new StringType(b.primitiveValue()); 282 else 283 throw new FHIRException("Unable to convert a "+b.getClass().getName()+" to a String"); 284 } 285 286 public UriType castToUri(Base b) throws FHIRException { 287 if (b instanceof UriType) 288 return (UriType) b; 289 else if (b.hasPrimitiveValue()) 290 return new UriType(b.primitiveValue()); 291 else 292 throw new FHIRException("Unable to convert a "+b.getClass().getName()+" to a Uri"); 293 } 294 295 public DateType castToDate(Base b) throws FHIRException { 296 if (b instanceof DateType) 297 return (DateType) b; 298 else if (b.hasPrimitiveValue()) 299 return new DateType(b.primitiveValue()); 300 else 301 throw new FHIRException("Unable to convert a "+b.getClass().getName()+" to a Date"); 302 } 303 304 public DateTimeType castToDateTime(Base b) throws FHIRException { 305 if (b instanceof DateTimeType) 306 return (DateTimeType) b; 307 else if (b.fhirType().equals("dateTime")) 308 return new DateTimeType(b.primitiveValue()); 309 else 310 throw new FHIRException("Unable to convert a "+b.getClass().getName()+" to a DateTime"); 311 } 312 313 public TimeType castToTime(Base b) throws FHIRException { 314 if (b instanceof TimeType) 315 return (TimeType) b; 316 else 317 throw new FHIRException("Unable to convert a "+b.getClass().getName()+" to a Time"); 318 } 319 320 public CodeType castToCode(Base b) throws FHIRException { 321 if (b instanceof CodeType) 322 return (CodeType) b; 323 else if (b.isPrimitive()) 324 return new CodeType(b.primitiveValue()); 325 else 326 throw new FHIRException("Unable to convert a "+b.getClass().getName()+" to a Code"); 327 } 328 329 public OidType castToOid(Base b) throws FHIRException { 330 if (b instanceof OidType) 331 return (OidType) b; 332 else 333 throw new FHIRException("Unable to convert a "+b.getClass().getName()+" to a Oid"); 334 } 335 336 public IdType castToId(Base b) throws FHIRException { 337 if (b instanceof IdType) 338 return (IdType) b; 339 else 340 throw new FHIRException("Unable to convert a "+b.getClass().getName()+" to a Id"); 341 } 342 343 public UnsignedIntType castToUnsignedInt(Base b) throws FHIRException { 344 if (b instanceof UnsignedIntType) 345 return (UnsignedIntType) b; 346 else 347 throw new FHIRException("Unable to convert a "+b.getClass().getName()+" to a UnsignedInt"); 348 } 349 350 public PositiveIntType castToPositiveInt(Base b) throws FHIRException { 351 if (b instanceof PositiveIntType) 352 return (PositiveIntType) b; 353 else 354 throw new FHIRException("Unable to convert a "+b.getClass().getName()+" to a PositiveInt"); 355 } 356 357 public MarkdownType castToMarkdown(Base b) throws FHIRException { 358 if (b instanceof MarkdownType) 359 return (MarkdownType) b; 360 else 361 throw new FHIRException("Unable to convert a "+b.getClass().getName()+" to a Markdown"); 362 } 363 364 public Annotation castToAnnotation(Base b) throws FHIRException { 365 if (b instanceof Annotation) 366 return (Annotation) b; 367 else 368 throw new FHIRException("Unable to convert a "+b.getClass().getName()+" to an Annotation"); 369 } 370 371 public Attachment castToAttachment(Base b) throws FHIRException { 372 if (b instanceof Attachment) 373 return (Attachment) b; 374 else 375 throw new FHIRException("Unable to convert a "+b.getClass().getName()+" to an Attachment"); 376 } 377 378 public Identifier castToIdentifier(Base b) throws FHIRException { 379 if (b instanceof Identifier) 380 return (Identifier) b; 381 else 382 throw new FHIRException("Unable to convert a "+b.getClass().getName()+" to an Identifier"); 383 } 384 385 public CodeableConcept castToCodeableConcept(Base b) throws FHIRException { 386 if (b instanceof CodeableConcept) 387 return (CodeableConcept) b; 388 else if (b instanceof CodeType) { 389 CodeableConcept cc = new CodeableConcept(); 390 cc.addCoding().setCode(((CodeType) b).asStringValue()); 391 return cc; 392 } else 393 throw new FHIRException("Unable to convert a "+b.getClass().getName()+" to a CodeableConcept"); 394 } 395 396 public Coding castToCoding(Base b) throws FHIRException { 397 if (b instanceof Coding) 398 return (Coding) b; 399 else 400 throw new FHIRException("Unable to convert a "+b.getClass().getName()+" to a Coding"); 401 } 402 403 public Quantity castToQuantity(Base b) throws FHIRException { 404 if (b instanceof Quantity) 405 return (Quantity) b; 406 else 407 throw new FHIRException("Unable to convert a "+b.getClass().getName()+" to an Quantity"); 408 } 409 410 public Money castToMoney(Base b) throws FHIRException { 411 if (b instanceof Money) 412 return (Money) b; 413 else 414 throw new FHIRException("Unable to convert a "+b.getClass().getName()+" to an Money"); 415 } 416 417 public Duration castToDuration(Base b) throws FHIRException { 418 if (b instanceof Duration) 419 return (Duration) b; 420 else 421 throw new FHIRException("Unable to convert a "+b.getClass().getName()+" to an Duration"); 422 } 423 424 public SimpleQuantity castToSimpleQuantity(Base b) throws FHIRException { 425 if (b instanceof SimpleQuantity) 426 return (SimpleQuantity) b; 427 else if (b instanceof Quantity) { 428 Quantity q = (Quantity) b; 429 SimpleQuantity sq = new SimpleQuantity(); 430 sq.setValueElement(q.getValueElement()); 431 sq.setComparatorElement(q.getComparatorElement()); 432 sq.setUnitElement(q.getUnitElement()); 433 sq.setSystemElement(q.getSystemElement()); 434 sq.setCodeElement(q.getCodeElement()); 435 return sq; 436 } else 437 throw new FHIRException("Unable to convert a "+b.getClass().getName()+" to an SimpleQuantity"); 438 } 439 440 public Range castToRange(Base b) throws FHIRException { 441 if (b instanceof Range) 442 return (Range) b; 443 else 444 throw new FHIRException("Unable to convert a "+b.getClass().getName()+" to a Range"); 445 } 446 447 public Period castToPeriod(Base b) throws FHIRException { 448 if (b instanceof Period) 449 return (Period) b; 450 else 451 throw new FHIRException("Unable to convert a "+b.getClass().getName()+" to a Period"); 452 } 453 454 public Ratio castToRatio(Base b) throws FHIRException { 455 if (b instanceof Ratio) 456 return (Ratio) b; 457 else 458 throw new FHIRException("Unable to convert a "+b.getClass().getName()+" to a Ratio"); 459 } 460 461 public SampledData castToSampledData(Base b) throws FHIRException { 462 if (b instanceof SampledData) 463 return (SampledData) b; 464 else 465 throw new FHIRException("Unable to convert a "+b.getClass().getName()+" to a SampledData"); 466 } 467 468 public Signature castToSignature(Base b) throws FHIRException { 469 if (b instanceof Signature) 470 return (Signature) b; 471 else 472 throw new FHIRException("Unable to convert a "+b.getClass().getName()+" to a Signature"); 473 } 474 475 public HumanName castToHumanName(Base b) throws FHIRException { 476 if (b instanceof HumanName) 477 return (HumanName) b; 478 else 479 throw new FHIRException("Unable to convert a "+b.getClass().getName()+" to a HumanName"); 480 } 481 482 public Address castToAddress(Base b) throws FHIRException { 483 if (b instanceof Address) 484 return (Address) b; 485 else 486 throw new FHIRException("Unable to convert a "+b.getClass().getName()+" to a Address"); 487 } 488 489 public ContactPoint castToContactPoint(Base b) throws FHIRException { 490 if (b instanceof ContactPoint) 491 return (ContactPoint) b; 492 else 493 throw new FHIRException("Unable to convert a "+b.getClass().getName()+" to a ContactPoint"); 494 } 495 496 public Timing castToTiming(Base b) throws FHIRException { 497 if (b instanceof Timing) 498 return (Timing) b; 499 else 500 throw new FHIRException("Unable to convert a "+b.getClass().getName()+" to a Timing"); 501 } 502 503 public Reference castToReference(Base b) throws FHIRException { 504 if (b instanceof Reference) 505 return (Reference) b; 506 else 507 throw new FHIRException("Unable to convert a "+b.getClass().getName()+" to a Reference"); 508 } 509 510 public Meta castToMeta(Base b) throws FHIRException { 511 if (b instanceof Meta) 512 return (Meta) b; 513 else 514 throw new FHIRException("Unable to convert a "+b.getClass().getName()+" to a Meta"); 515 } 516 517 public Extension castToExtension(Base b) throws FHIRException { 518 if (b instanceof Extension) 519 return (Extension) b; 520 else 521 throw new FHIRException("Unable to convert a "+b.getClass().getName()+" to a Extension"); 522 } 523 524 public Resource castToResource(Base b) throws FHIRException { 525 if (b instanceof Resource) 526 return (Resource) b; 527 else 528 throw new FHIRException("Unable to convert a "+b.getClass().getName()+" to a Resource"); 529 } 530 531 public Narrative castToNarrative(Base b) throws FHIRException { 532 if (b instanceof Narrative) 533 return (Narrative) b; 534 else 535 throw new FHIRException("Unable to convert a "+b.getClass().getName()+" to a Narrative"); 536 } 537 538 539 public ElementDefinition castToElementDefinition(Base b) throws FHIRException { 540 if (b instanceof ElementDefinition) 541 return (ElementDefinition) b; 542 else 543 throw new FHIRException("Unable to convert a "+b.getClass().getName()+" to a ElementDefinition"); 544 } 545 546 public ModuleMetadata castToModuleMetadata(Base b) throws FHIRException { 547 if (b instanceof ModuleMetadata) 548 return (ModuleMetadata) b; 549 else 550 throw new FHIRException("Unable to convert a "+b.getClass().getName()+" to a ModuleMetadata"); 551 } 552 553 public ActionDefinition castToActionDefinition(Base b) throws FHIRException { 554 if (b instanceof ActionDefinition) 555 return (ActionDefinition) b; 556 else 557 throw new FHIRException("Unable to convert a "+b.getClass().getName()+" to a ActionDefinition"); 558 } 559 560 public DataRequirement castToDataRequirement(Base b) throws FHIRException { 561 if (b instanceof DataRequirement) 562 return (DataRequirement) b; 563 else 564 throw new FHIRException("Unable to convert a "+b.getClass().getName()+" to a DataRequirement"); 565 } 566 567 public ParameterDefinition castToParameterDefinition(Base b) throws FHIRException { 568 if (b instanceof ParameterDefinition) 569 return (ParameterDefinition) b; 570 else 571 throw new FHIRException("Unable to convert a "+b.getClass().getName()+" to a ParameterDefinition"); 572 } 573 574 public TriggerDefinition castToTriggerDefinition(Base b) throws FHIRException { 575 if (b instanceof TriggerDefinition) 576 return (TriggerDefinition) b; 577 else 578 throw new FHIRException("Unable to convert a "+b.getClass().getName()+" to a TriggerDefinition"); 579 } 580 581 protected boolean isMetadataBased() { 582 return false; 583 } 584 585 public Base[] getProperty(int hash, String name, boolean checkValid) throws FHIRException { 586 if (checkValid) 587 throw new FHIRException("Attempt to read invalid property '"+name+"' on type "+fhirType()); 588 return null; 589 } 590 591 public void setProperty(int hash, String name, Base value) throws FHIRException { 592 throw new FHIRException("Attempt to write to invalid property '"+name+"' on type "+fhirType()); 593 } 594 595 public Base makeProperty(int hash, String name) throws FHIRException { 596 throw new FHIRException("Attempt to make an invalid property '"+name+"' on type "+fhirType()); 597 } 598 599 public static boolean equals(String v1, String v2) { 600 if (v1 == null && v2 == null) 601 return true; 602 else if (v1 == null || v2 == null) 603 return false; 604 else 605 return v1.equals(v2); 606 } 607 608 609}