001package org.hl7.fhir.r4.model;
002
003/*
004  Copyright (c) 2011+, HL7, Inc.
005  All rights reserved.
006  
007  Redistribution and use in source and binary forms, with or without modification, 
008  are permitted provided that the following conditions are met:
009    
010   * Redistributions of source code must retain the above copyright notice, this 
011     list of conditions and the following disclaimer.
012   * Redistributions in binary form must reproduce the above copyright notice, 
013     this list of conditions and the following disclaimer in the documentation 
014     and/or other materials provided with the distribution.
015   * Neither the name of HL7 nor the names of its contributors may be used to 
016     endorse or promote products derived from this software without specific 
017     prior written permission.
018  
019  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 
020  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
021  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
022  IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
023  INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
024  NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
025  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
026  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
027  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
028  POSSIBILITY OF SUCH DAMAGE.
029  
030 */
031
032import java.io.IOException;
033import java.io.Serializable;
034import java.util.ArrayList;
035import java.util.HashMap;
036import java.util.List;
037import java.util.Map;
038
039import org.hl7.fhir.exceptions.FHIRException;
040import org.hl7.fhir.instance.model.api.IBase;
041import org.hl7.fhir.r4.elementmodel.Element;
042import org.hl7.fhir.r4.elementmodel.ObjectConverter;
043import org.hl7.fhir.utilities.Utilities;
044import org.hl7.fhir.utilities.xhtml.XhtmlComposer;
045import org.hl7.fhir.utilities.xhtml.XhtmlNode;
046import org.hl7.fhir.utilities.xhtml.XhtmlParser;
047
048import ca.uhn.fhir.model.api.IElement;
049
050public abstract class Base implements Serializable, IBase, IElement {
051
052  /**
053   * User appended data items - allow users to add extra information to the class
054   */
055  private Map<String, Object> userData;
056
057  /**
058   * Round tracking xml comments for testing convenience
059   */
060  private List<String> formatCommentsPre;
061
062  /**
063   * Round tracking xml comments for testing convenience
064   */
065  private List<String> formatCommentsPost;
066
067  public Object getUserData(String name) {
068    if (userData == null)
069      return null;
070    return userData.get(name);
071  }
072
073  public void setUserData(String name, Object value) {
074    if (userData == null)
075      userData = new HashMap<String, Object>();
076    userData.put(name, value);
077  }
078
079  public void clearUserData(String name) {
080    if (userData != null)
081      userData.remove(name);
082  }
083
084  public void setUserDataINN(String name, Object value) {
085    if (value == null)
086      return;
087
088    if (userData == null)
089      userData = new HashMap<String, Object>();
090    userData.put(name, value);
091  }
092
093  public boolean hasUserData(String name) {
094    if (userData == null)
095      return false;
096    else
097      return userData.containsKey(name);
098  }
099
100  public String getUserString(String name) {
101    Object ud = getUserData(name);
102    if (ud == null)
103      return null;
104    if (ud instanceof String)
105      return (String) ud;
106    return ud.toString();
107  }
108
109  public int getUserInt(String name) {
110    if (!hasUserData(name))
111      return 0;
112    return (Integer) getUserData(name);
113  }
114
115  public boolean hasFormatComment() {
116    return (formatCommentsPre != null && !formatCommentsPre.isEmpty())
117        || (formatCommentsPost != null && !formatCommentsPost.isEmpty());
118  }
119
120  public List<String> getFormatCommentsPre() {
121    if (formatCommentsPre == null)
122      formatCommentsPre = new ArrayList<String>();
123    return formatCommentsPre;
124  }
125
126  public List<String> getFormatCommentsPost() {
127    if (formatCommentsPost == null)
128      formatCommentsPost = new ArrayList<String>();
129    return formatCommentsPost;
130  }
131
132  // these 3 allow evaluation engines to get access to primitive values
133  public boolean isPrimitive() {
134    return false;
135  }
136
137  public boolean isBooleanPrimitive() {
138    return false;
139  }
140
141  public boolean hasPrimitiveValue() {
142    return isPrimitive();
143  }
144
145  public String primitiveValue() {
146    return null;
147  }
148
149  public boolean isDateTime() {
150    return false;
151  }
152
153  public BaseDateTimeType dateTimeValue() {
154    return null;
155  }
156
157  public abstract String fhirType();
158
159  public boolean hasType(String... name) {
160    String t = fhirType();
161    for (String n : name)
162      if (n.equalsIgnoreCase(t))
163        return true;
164    return false;
165  }
166
167  protected abstract void listChildren(List<Property> result);
168
169  public Base setProperty(String name, Base value) throws FHIRException {
170    throw new FHIRException("Attempt to set unknown property " + name);
171  }
172
173  public void removeChild(String name, Base value) throws FHIRException {
174    throw new FHIRException("Attempt to set remove an unknown child " + name);
175  }
176
177  public Base addChild(String name) throws FHIRException {
178    throw new FHIRException("Attempt to add child with unknown name " + name);
179  }
180
181  /**
182   * Supports iterating the children elements in some generic processor or browser
183   * All defined children will be listed, even if they have no value on this
184   * instance
185   * 
186   * Note that the actual content of primitive or xhtml elements is not iterated
187   * explicitly. To find these, the processing code must recognise the element as
188   * a primitive, typecast the value to a {@link Type}, and examine the value
189   * 
190   * @return a list of all the children defined for this element
191   */
192  public List<Property> children() {
193    List<Property> result = new ArrayList<Property>();
194    listChildren(result);
195    return result;
196  }
197
198  public Property getChildByName(String name) {
199    List<Property> children = new ArrayList<Property>();
200    listChildren(children);
201    for (Property c : children)
202      if (c.getName().equals(name))
203        return c;
204    return null;
205  }
206
207  public List<Base> listChildrenByName(String name) throws FHIRException {
208    List<Base> result = new ArrayList<Base>();
209    for (Base b : listChildrenByName(name, true))
210      if (b != null)
211        result.add(b);
212    return result;
213  }
214
215  public Base[] listChildrenByName(String name, boolean checkValid) throws FHIRException {
216    if (name.equals("*")) {
217      List<Property> children = new ArrayList<Property>();
218      listChildren(children);
219      List<Base> result = new ArrayList<Base>();
220      for (Property c : children)
221        result.addAll(c.getValues());
222      return result.toArray(new Base[result.size()]);
223    } else
224      return getProperty(name.hashCode(), name, checkValid);
225  }
226
227  public boolean isEmpty() {
228    return true; // userData does not count
229  }
230
231  public boolean equalsDeep(Base other) {
232    return other != null;
233  }
234
235  public boolean equalsShallow(Base other) {
236    return other != null;
237  }
238
239  public static boolean compareDeep(String s1, String s2, boolean allowNull) {
240    if (allowNull) {
241      boolean noLeft = s1 == null || Utilities.noString(s1);
242      boolean noRight = s2 == null || Utilities.noString(s2);
243      if (noLeft && noRight) {
244        return true;
245      }
246    }
247    if (s1 == null || s2 == null)
248      return false;
249    return s1.equals(s2);
250  }
251
252  public static boolean compareDeep(List<? extends Base> e1, List<? extends Base> e2, boolean allowNull) {
253    if (noList(e1) && noList(e2) && allowNull)
254      return true;
255    if (noList(e1) || noList(e2))
256      return false;
257    if (e1.size() != e2.size())
258      return false;
259    for (int i = 0; i < e1.size(); i++) {
260      if (!compareDeep(e1.get(i), e2.get(i), allowNull))
261        return false;
262    }
263    return true;
264  }
265
266  private static boolean noList(List<? extends Base> list) {
267    return list == null || list.isEmpty();
268  }
269
270  public static boolean compareDeep(Base e1, Base e2, boolean allowNull) {
271    if (allowNull) {
272      boolean noLeft = e1 == null || e1.isEmpty();
273      boolean noRight = e2 == null || e2.isEmpty();
274      if (noLeft && noRight) {
275        return true;
276      }
277    }
278    if (e1 == null || e2 == null)
279      return false;
280    if (e2.isMetadataBased() && !e1.isMetadataBased()) // respect existing order for debugging consistency; outcome must
281                                                       // be the same either way
282      return e2.equalsDeep(e1);
283    else
284      return e1.equalsDeep(e2);
285  }
286
287  public static boolean compareDeep(XhtmlNode div1, XhtmlNode div2, boolean allowNull) {
288    if (div1 == null && div2 == null && allowNull)
289      return true;
290    if (div1 == null || div2 == null)
291      return false;
292    return div1.equalsDeep(div2);
293  }
294
295  public static boolean compareValues(List<? extends PrimitiveType> e1, List<? extends PrimitiveType> e2,
296      boolean allowNull) {
297    if (e1 == null && e2 == null && allowNull)
298      return true;
299    if (e1 == null || e2 == null)
300      return false;
301    if (e1.size() != e2.size())
302      return false;
303    for (int i = 0; i < e1.size(); i++) {
304      if (!compareValues(e1.get(i), e2.get(i), allowNull))
305        return false;
306    }
307    return true;
308  }
309
310  public static boolean compareValues(PrimitiveType e1, PrimitiveType e2, boolean allowNull) {
311    boolean noLeft = e1 == null || e1.isEmpty();
312    boolean noRight = e2 == null || e2.isEmpty();
313    if (noLeft && noRight && allowNull) {
314      return true;
315    }
316    if (noLeft != noRight)
317      return false;
318    return e1.equalsShallow(e2);
319  }
320
321  // -- converters for property setters
322
323  public Type castToType(Base b) throws FHIRException {
324    if (b == null) {
325      return null;
326    }
327    if (b instanceof Type)
328      return (Type) b;
329    else if (b.isMetadataBased())
330      return ((org.hl7.fhir.r4.elementmodel.Element) b).asType();
331    else
332      throw new FHIRException("Unable to convert a " + b.getClass().getName() + " to a Reference");
333  }
334
335  public BooleanType castToBoolean(Base b) throws FHIRException {
336    if (b == null) {
337      return null;
338    }
339    if (b instanceof BooleanType)
340      return (BooleanType) b;
341    else
342      throw new FHIRException("Unable to convert a " + b.getClass().getName() + " to a Boolean");
343  }
344
345  public IntegerType castToInteger(Base b) throws FHIRException {
346    if (b == null) {
347      return null;
348    }
349    if (b instanceof IntegerType)
350      return (IntegerType) b;
351    else
352      throw new FHIRException("Unable to convert a " + b.getClass().getName() + " to a Integer");
353  }
354
355  public DecimalType castToDecimal(Base b) throws FHIRException {
356    if (b == null) {
357      return null;
358    }
359    if (b instanceof DecimalType)
360      return (DecimalType) b;
361    else if (b.hasPrimitiveValue())
362      return new DecimalType(b.primitiveValue());
363    else
364      throw new FHIRException("Unable to convert a " + b.getClass().getName() + " to a Decimal");
365  }
366
367  public Base64BinaryType castToBase64Binary(Base b) throws FHIRException {
368    if (b == null) {
369      return null;
370    }
371    if (b instanceof Base64BinaryType)
372      return (Base64BinaryType) b;
373    else
374      throw new FHIRException("Unable to convert a " + b.getClass().getName() + " to a Base64Binary");
375  }
376
377  public InstantType castToInstant(Base b) throws FHIRException {
378    if (b == null) {
379      return null;
380    }
381    if (b instanceof InstantType)
382      return (InstantType) b;
383    else
384      throw new FHIRException("Unable to convert a " + b.getClass().getName() + " to a Instant");
385  }
386
387  public StringType castToString(Base b) throws FHIRException {
388    if (b == null) {
389      return null;
390    }
391    if (b instanceof StringType)
392      return (StringType) b;
393    else if (b.hasPrimitiveValue())
394      return new StringType(b.primitiveValue());
395    else
396      throw new FHIRException("Unable to convert a " + b.getClass().getName() + " to a String");
397  }
398
399  public UriType castToUri(Base b) throws FHIRException {
400    if (b == null) {
401      return null;
402    }
403    if (b instanceof UriType)
404      return (UriType) b;
405    else if (b.hasPrimitiveValue())
406      return new UriType(b.primitiveValue());
407    else
408      throw new FHIRException("Unable to convert a " + b.getClass().getName() + " to a Uri");
409  }
410
411  public UrlType castToUrl(Base b) throws FHIRException {
412    if (b == null) {
413      return null;
414    }
415    if (b instanceof UrlType)
416      return (UrlType) b;
417    else if (b.hasPrimitiveValue())
418      return new UrlType(b.primitiveValue());
419    else
420      throw new FHIRException("Unable to convert a " + b.getClass().getName() + " to a Uri");
421  }
422
423  public CanonicalType castToCanonical(Base b) throws FHIRException {
424    if (b == null) {
425      return null;
426    }
427    if (b instanceof CanonicalType)
428      return (CanonicalType) b;
429    else if (b.hasPrimitiveValue())
430      return new CanonicalType(b.primitiveValue());
431    else
432      throw new FHIRException("Unable to convert a " + b.getClass().getName() + " to a Uri");
433  }
434
435  public DateType castToDate(Base b) throws FHIRException {
436    if (b == null) {
437      return null;
438    }
439    if (b instanceof DateType)
440      return (DateType) b;
441    else if (b.hasPrimitiveValue())
442      return new DateType(b.primitiveValue());
443    else
444      throw new FHIRException("Unable to convert a " + b.getClass().getName() + " to a Date");
445  }
446
447  public DateTimeType castToDateTime(Base b) throws FHIRException {
448    if (b == null) {
449      return null;
450    }
451    if (b instanceof DateTimeType)
452      return (DateTimeType) b;
453    else if (b.fhirType().equals("dateTime"))
454      return new DateTimeType(b.primitiveValue());
455    else
456      throw new FHIRException("Unable to convert a " + b.getClass().getName() + " to a DateTime");
457  }
458
459  public TimeType castToTime(Base b) throws FHIRException {
460    if (b == null) {
461      return null;
462    }
463    if (b instanceof TimeType)
464      return (TimeType) b;
465    else
466      throw new FHIRException("Unable to convert a " + b.getClass().getName() + " to a Time");
467  }
468
469  public CodeType castToCode(Base b) throws FHIRException {
470    if (b == null) {
471      return null;
472    }
473    if (b instanceof CodeType)
474      return (CodeType) b;
475    else if (b instanceof PrimitiveType<?>)
476      return new CodeType(b.primitiveValue(), (PrimitiveType<?>) b);
477    else if (b.isPrimitive())
478      return new CodeType(b.primitiveValue());
479    else
480      throw new FHIRException("Unable to convert a " + b.getClass().getName() + " to a Code");
481  }
482
483  public OidType castToOid(Base b) throws FHIRException {
484    if (b == null) {
485      return null;
486    }
487    if (b instanceof OidType)
488      return (OidType) b;
489    else
490      throw new FHIRException("Unable to convert a " + b.getClass().getName() + " to a Oid");
491  }
492
493  public IdType castToId(Base b) throws FHIRException {
494    if (b == null) {
495      return null;
496    }
497    if (b instanceof IdType)
498      return (IdType) b;
499    else
500      throw new FHIRException("Unable to convert a " + b.getClass().getName() + " to a Id");
501  }
502
503  public UnsignedIntType castToUnsignedInt(Base b) throws FHIRException {
504    if (b == null) {
505      return null;
506    }
507    if (b instanceof UnsignedIntType)
508      return (UnsignedIntType) b;
509    else
510      throw new FHIRException("Unable to convert a " + b.getClass().getName() + " to a UnsignedInt");
511  }
512
513  public PositiveIntType castToPositiveInt(Base b) throws FHIRException {
514    if (b == null) {
515      return null;
516    }
517    if (b instanceof PositiveIntType)
518      return (PositiveIntType) b;
519    else
520      throw new FHIRException("Unable to convert a " + b.getClass().getName() + " to a PositiveInt");
521  }
522
523  public MarkdownType castToMarkdown(Base b) throws FHIRException {
524    if (b == null) {
525      return null;
526    }
527    if (b instanceof MarkdownType)
528      return (MarkdownType) b;
529    else if (b.hasPrimitiveValue())
530      return new MarkdownType(b.primitiveValue());
531    else
532      throw new FHIRException("Unable to convert a " + b.getClass().getName() + " to a Markdown");
533  }
534
535  public Annotation castToAnnotation(Base b) throws FHIRException {
536    if (b == null) {
537      return null;
538    }
539    if (b instanceof Annotation)
540      return (Annotation) b;
541    else
542      throw new FHIRException("Unable to convert a " + b.getClass().getName() + " to an Annotation");
543  }
544
545  public Dosage castToDosage(Base b) throws FHIRException {
546    if (b == null) {
547      return null;
548    }
549    if (b instanceof Dosage)
550      return (Dosage) b;
551    else
552      throw new FHIRException("Unable to convert a " + b.getClass().getName() + " to an DosageInstruction");
553  }
554
555  public Attachment castToAttachment(Base b) throws FHIRException {
556    if (b == null) {
557      return null;
558    }
559    if (b instanceof Attachment)
560      return (Attachment) b;
561    else
562      throw new FHIRException("Unable to convert a " + b.getClass().getName() + " to an Attachment");
563  }
564
565  public Identifier castToIdentifier(Base b) throws FHIRException {
566    if (b == null) {
567      return null;
568    }
569    if (b instanceof Identifier)
570      return (Identifier) b;
571    else
572      throw new FHIRException("Unable to convert a " + b.getClass().getName() + " to an Identifier");
573  }
574
575  public CodeableConcept castToCodeableConcept(Base b) throws FHIRException {
576    if (b == null) {
577      return null;
578    }
579    if (b instanceof CodeableConcept)
580      return (CodeableConcept) b;
581    else if (b instanceof Element) {
582      return ObjectConverter.readAsCodeableConcept((Element) b);
583    } else if (b instanceof CodeType) {
584      CodeableConcept cc = new CodeableConcept();
585      cc.addCoding().setCode(((CodeType) b).asStringValue());
586      return cc;
587    } else
588      throw new FHIRException("Unable to convert a " + b.getClass().getName() + " to a CodeableConcept");
589  }
590
591  public Population castToPopulation(Base b) throws FHIRException {
592    if (b == null) {
593      return null;
594    }
595    if (b instanceof Population)
596      return (Population) b;
597    else
598      throw new FHIRException("Unable to convert a " + b.getClass().getName() + " to a Population");
599  }
600
601  public Coding castToCoding(Base b) throws FHIRException {
602    if (b == null) {
603      return null;
604    }
605    if (b instanceof Coding)
606      return (Coding) b;
607    else if (b instanceof Element) {
608      ICoding c = ((Element) b).getAsICoding();
609      if (c == null)
610        throw new FHIRException("Unable to convert a " + b.getClass().getName() + " to a Coding");
611      return new Coding().setCode(c.getCode()).setSystem(c.getSystem()).setVersion(c.getVersion())
612          .setDisplay(c.getDisplay());
613    } else if (b instanceof ICoding) {
614      ICoding c = (ICoding) b;
615      return new Coding().setCode(c.getCode()).setSystem(c.getSystem()).setVersion(c.getVersion())
616          .setDisplay(c.getDisplay());
617    } else
618      throw new FHIRException("Unable to convert a " + b.getClass().getName() + " to a Coding");
619  }
620
621  public Quantity castToQuantity(Base b) throws FHIRException {
622    if (b == null) {
623      return null;
624    }
625    if (b instanceof Quantity)
626      return (Quantity) b;
627    else
628      throw new FHIRException("Unable to convert a " + b.getClass().getName() + " to an Quantity");
629  }
630
631  public Money castToMoney(Base b) throws FHIRException {
632    if (b == null) {
633      return null;
634    }
635    if (b instanceof Money)
636      return (Money) b;
637    else
638      throw new FHIRException("Unable to convert a " + b.getClass().getName() + " to an Money");
639  }
640
641  public Duration castToDuration(Base b) throws FHIRException {
642    if (b == null) {
643      return null;
644    }
645    if (b instanceof Duration)
646      return (Duration) b;
647    else
648      throw new FHIRException("Unable to convert a " + b.getClass().getName() + " to an Duration");
649  }
650
651  public SimpleQuantity castToSimpleQuantity(Base b) throws FHIRException {
652    if (b == null) {
653      return null;
654    }
655    if (b instanceof SimpleQuantity)
656      return (SimpleQuantity) b;
657    else if (b instanceof Quantity) {
658      Quantity q = (Quantity) b;
659      SimpleQuantity sq = new SimpleQuantity();
660      sq.setValueElement(q.getValueElement());
661      sq.setComparatorElement(q.getComparatorElement());
662      sq.setUnitElement(q.getUnitElement());
663      sq.setSystemElement(q.getSystemElement());
664      sq.setCodeElement(q.getCodeElement());
665      return sq;
666    } else
667      throw new FHIRException("Unable to convert a " + b.getClass().getName() + " to an SimpleQuantity");
668  }
669
670  public Range castToRange(Base b) throws FHIRException {
671    if (b == null) {
672      return null;
673    }
674    if (b instanceof Range)
675      return (Range) b;
676    else
677      throw new FHIRException("Unable to convert a " + b.getClass().getName() + " to a Range");
678  }
679
680  public Period castToPeriod(Base b) throws FHIRException {
681    if (b == null) {
682      return null;
683    }
684    if (b instanceof Period)
685      return (Period) b;
686    else
687      throw new FHIRException("Unable to convert a " + b.getClass().getName() + " to a Period");
688  }
689
690  public Ratio castToRatio(Base b) throws FHIRException {
691    if (b == null) {
692      return null;
693    }
694    if (b instanceof Ratio)
695      return (Ratio) b;
696    else
697      throw new FHIRException("Unable to convert a " + b.getClass().getName() + " to a Ratio");
698  }
699
700  public SampledData castToSampledData(Base b) throws FHIRException {
701    if (b == null) {
702      return null;
703    }
704    if (b instanceof SampledData)
705      return (SampledData) b;
706    else
707      throw new FHIRException("Unable to convert a " + b.getClass().getName() + " to a SampledData");
708  }
709
710  public Signature castToSignature(Base b) throws FHIRException {
711    if (b == null) {
712      return null;
713    }
714    if (b instanceof Signature)
715      return (Signature) b;
716    else
717      throw new FHIRException("Unable to convert a " + b.getClass().getName() + " to a Signature");
718  }
719
720  public HumanName castToHumanName(Base b) throws FHIRException {
721    if (b == null) {
722      return null;
723    }
724    if (b instanceof HumanName)
725      return (HumanName) b;
726    else
727      throw new FHIRException("Unable to convert a " + b.getClass().getName() + " to a HumanName");
728  }
729
730  public Address castToAddress(Base b) throws FHIRException {
731    if (b == null) {
732      return null;
733    }
734    if (b instanceof Address)
735      return (Address) b;
736    else
737      throw new FHIRException("Unable to convert a " + b.getClass().getName() + " to a Address");
738  }
739
740  public ContactDetail castToContactDetail(Base b) throws FHIRException {
741    if (b == null) {
742      return null;
743    }
744    if (b instanceof ContactDetail)
745      return (ContactDetail) b;
746    else
747      throw new FHIRException("Unable to convert a " + b.getClass().getName() + " to a ContactDetail");
748  }
749
750  public Contributor castToContributor(Base b) throws FHIRException {
751    if (b == null) {
752      return null;
753    }
754    if (b instanceof Contributor)
755      return (Contributor) b;
756    else
757      throw new FHIRException("Unable to convert a " + b.getClass().getName() + " to a Contributor");
758  }
759
760  public UsageContext castToUsageContext(Base b) throws FHIRException {
761    if (b == null) {
762      return null;
763    }
764    if (b instanceof UsageContext)
765      return (UsageContext) b;
766    else
767      throw new FHIRException("Unable to convert a " + b.getClass().getName() + " to a UsageContext");
768  }
769
770  public RelatedArtifact castToRelatedArtifact(Base b) throws FHIRException {
771    if (b == null) {
772      return null;
773    }
774    if (b instanceof RelatedArtifact)
775      return (RelatedArtifact) b;
776    else
777      throw new FHIRException("Unable to convert a " + b.getClass().getName() + " to a RelatedArtifact");
778  }
779
780  public ContactPoint castToContactPoint(Base b) throws FHIRException {
781    if (b == null) {
782      return null;
783    }
784    if (b instanceof ContactPoint)
785      return (ContactPoint) b;
786    else
787      throw new FHIRException("Unable to convert a " + b.getClass().getName() + " to a ContactPoint");
788  }
789
790  public Timing castToTiming(Base b) throws FHIRException {
791    if (b == null) {
792      return null;
793    }
794    if (b instanceof Timing)
795      return (Timing) b;
796    else
797      throw new FHIRException("Unable to convert a " + b.getClass().getName() + " to a Timing");
798  }
799
800  public Reference castToReference(Base b) throws FHIRException {
801    if (b == null) {
802      return null;
803    }
804    if (b instanceof Reference)
805      return (Reference) b;
806    else if (b.isPrimitive() && Utilities.isURL(b.primitiveValue()))
807      return new Reference().setReference(b.primitiveValue());
808    else if (b instanceof org.hl7.fhir.r4.elementmodel.Element && b.fhirType().equals("Reference")) {
809      org.hl7.fhir.r4.elementmodel.Element e = (org.hl7.fhir.r4.elementmodel.Element) b;
810      return new Reference().setReference(e.getChildValue("reference")).setDisplay(e.getChildValue("display"));
811    } else
812      throw new FHIRException("Unable to convert a " + b.getClass().getName() + " to a Reference");
813  }
814
815  public Meta castToMeta(Base b) throws FHIRException {
816    if (b == null) {
817      return null;
818    }
819    if (b instanceof Meta)
820      return (Meta) b;
821    else
822      throw new FHIRException("Unable to convert a " + b.getClass().getName() + " to a Meta");
823  }
824
825  public MarketingStatus castToMarketingStatus(Base b) throws FHIRException {
826    if (b == null) {
827      return null;
828    }
829    if (b instanceof MarketingStatus)
830      return (MarketingStatus) b;
831    else
832      throw new FHIRException("Unable to convert a " + b.getClass().getName() + " to a MarketingStatus");
833  }
834
835  public ProductShelfLife castToProductShelfLife(Base b) throws FHIRException {
836    if (b == null) {
837      return null;
838    }
839    if (b instanceof ProductShelfLife)
840      return (ProductShelfLife) b;
841    else
842      throw new FHIRException("Unable to convert a " + b.getClass().getName() + " to a ProductShelfLife");
843  }
844
845  public ProdCharacteristic castToProdCharacteristic(Base b) throws FHIRException {
846    if (b == null) {
847      return null;
848    }
849    if (b instanceof ProdCharacteristic)
850      return (ProdCharacteristic) b;
851    else
852      throw new FHIRException("Unable to convert a " + b.getClass().getName() + " to a ProdCharacteristic");
853  }
854
855  public SubstanceAmount castToSubstanceAmount(Base b) throws FHIRException {
856    if (b == null) {
857      return null;
858    }
859    if (b instanceof SubstanceAmount)
860      return (SubstanceAmount) b;
861    else
862      throw new FHIRException("Unable to convert a " + b.getClass().getName() + " to a SubstanceAmount");
863  }
864
865  public Extension castToExtension(Base b) throws FHIRException {
866    if (b == null) {
867      return null;
868    }
869    if (b instanceof Extension)
870      return (Extension) b;
871    else
872      throw new FHIRException("Unable to convert a " + b.getClass().getName() + " to a Extension");
873  }
874
875  public Resource castToResource(Base b) throws FHIRException {
876    if (b == null) {
877      return null;
878    }
879    if (b instanceof Resource)
880      return (Resource) b;
881    else
882      throw new FHIRException("Unable to convert a " + b.getClass().getName() + " to a Resource");
883  }
884
885  public Narrative castToNarrative(Base b) throws FHIRException {
886    if (b == null) {
887      return null;
888    }
889    if (b instanceof Narrative)
890      return (Narrative) b;
891    else
892      throw new FHIRException("Unable to convert a " + b.getClass().getName() + " to a Narrative");
893  }
894
895  public ElementDefinition castToElementDefinition(Base b) throws FHIRException {
896    if (b == null) {
897      return null;
898    }
899    if (b instanceof ElementDefinition)
900      return (ElementDefinition) b;
901    else
902      throw new FHIRException("Unable to convert a " + b.getClass().getName() + " to a ElementDefinition");
903  }
904
905  public DataRequirement castToDataRequirement(Base b) throws FHIRException {
906    if (b == null) {
907      return null;
908    }
909    if (b instanceof DataRequirement)
910      return (DataRequirement) b;
911    else
912      throw new FHIRException("Unable to convert a " + b.getClass().getName() + " to a DataRequirement");
913  }
914
915  public Expression castToExpression(Base b) throws FHIRException {
916    if (b == null) {
917      return null;
918    }
919    if (b instanceof Expression)
920      return (Expression) b;
921    else
922      throw new FHIRException("Unable to convert a " + b.getClass().getName() + " to a Expression");
923  }
924
925  public ParameterDefinition castToParameterDefinition(Base b) throws FHIRException {
926    if (b == null) {
927      return null;
928    }
929    if (b instanceof ParameterDefinition)
930      return (ParameterDefinition) b;
931    else
932      throw new FHIRException("Unable to convert a " + b.getClass().getName() + " to a ParameterDefinition");
933  }
934
935  public TriggerDefinition castToTriggerDefinition(Base b) throws FHIRException {
936    if (b == null) {
937      return null;
938    }
939    if (b instanceof TriggerDefinition)
940      return (TriggerDefinition) b;
941    else
942      throw new FHIRException("Unable to convert a " + b.getClass().getName() + " to a TriggerDefinition");
943  }
944
945  public XhtmlNode castToXhtml(Base b) throws FHIRException {
946    if (b == null) {
947      return null;
948    }
949    if (b instanceof Element) {
950      return ((Element) b).getXhtml();
951    } else if (b instanceof XhtmlType) {
952      return ((XhtmlType) b).getValue();
953    } else if (b instanceof StringType) {
954      try {
955        return new XhtmlParser().parseFragment(((StringType) b).asStringValue());
956      } catch (IOException e) {
957        throw new FHIRException(e);
958      }
959    } else
960      throw new FHIRException("Unable to convert a " + b.getClass().getName() + " to XHtml");
961  }
962
963  public String castToXhtmlString(Base b) throws FHIRException {
964    if (b == null) {
965      return null;
966    }
967    if (b instanceof Element) {
968      return ((Element) b).getValue();
969    } else if (b instanceof XhtmlType) {
970      try {
971        return new XhtmlComposer(true).compose(((XhtmlType) b).getValue());
972      } catch (IOException e) {
973        return null;
974      }
975    } else if (b instanceof StringType) {
976      return ((StringType) b).asStringValue();
977    } else
978      throw new FHIRException("Unable to convert a " + b.getClass().getName() + " to XHtml string");
979  }
980
981  protected boolean isMetadataBased() {
982    return false;
983  }
984
985  public Base[] getProperty(int hash, String name, boolean checkValid) throws FHIRException {
986    if (checkValid)
987      throw new FHIRException("Attempt to read invalid property '" + name + "' on type " + fhirType());
988    return null;
989  }
990
991  public Base setProperty(int hash, String name, Base value) throws FHIRException {
992    throw new FHIRException("Attempt to write to invalid property '" + name + "' on type " + fhirType());
993  }
994
995  public Base makeProperty(int hash, String name) throws FHIRException {
996    throw new FHIRException("Attempt to make an invalid property '" + name + "' on type " + fhirType());
997  }
998
999  public String[] getTypesForProperty(int hash, String name) throws FHIRException {
1000    throw new FHIRException("Attempt to get types for an invalid property '" + name + "' on type " + fhirType());
1001  }
1002
1003  public static boolean equals(String v1, String v2) {
1004    if (v1 == null && v2 == null)
1005      return true;
1006    else if (v1 == null || v2 == null)
1007      return false;
1008    else
1009      return v1.equals(v2);
1010  }
1011
1012  public boolean isResource() {
1013    return false;
1014  }
1015
1016  public abstract String getIdBase();
1017
1018  public abstract void setIdBase(String value);
1019
1020  public Property getNamedProperty(String _name) throws FHIRException {
1021    return getNamedProperty(_name.hashCode(), _name, false);
1022  }
1023
1024  public Property getNamedProperty(int _hash, String _name, boolean _checkValid) throws FHIRException {
1025    if (_checkValid)
1026      throw new FHIRException("Attempt to read invalid property '" + _name + "' on type " + fhirType());
1027    return null;
1028  }
1029
1030  public XhtmlNode getXhtml() {
1031    return null;
1032  }
1033
1034  public abstract Base copy();
1035
1036  public void copyValues(Base dst) {
1037  }
1038
1039}