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