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 getChildValueByName(String name) {
216    Property p = getChildByName(name);
217    if (p != null && p.hasValues()) {
218      if (p.getValues().size() > 1) {
219        throw new Error("Too manye values for "+name+" found");
220      } else {
221        return p.getValues().get(0);        
222      }
223    }
224    return null;
225  }
226  public Base[] listChildrenByName(String name, boolean checkValid) throws FHIRException {
227    if (name.equals("*")) {
228      List<Property> children = new ArrayList<Property>();
229      listChildren(children);
230      List<Base> result = new ArrayList<Base>();
231      for (Property c : children)
232        result.addAll(c.getValues());
233      return result.toArray(new Base[result.size()]);
234    } else
235      return getProperty(name.hashCode(), name, checkValid);
236  }
237
238  public boolean isEmpty() {
239    return true; // userData does not count
240  }
241
242  public boolean equalsDeep(Base other) {
243    return other != null;
244  }
245
246  public boolean equalsShallow(Base other) {
247    return other != null;
248  }
249
250  public static boolean compareDeep(String s1, String s2, boolean allowNull) {
251    if (allowNull) {
252      boolean noLeft = s1 == null || Utilities.noString(s1);
253      boolean noRight = s2 == null || Utilities.noString(s2);
254      if (noLeft && noRight) {
255        return true;
256      }
257    }
258    if (s1 == null || s2 == null)
259      return false;
260    return s1.equals(s2);
261  }
262
263  public static boolean compareDeep(List<? extends Base> e1, List<? extends Base> e2, boolean allowNull) {
264    if (noList(e1) && noList(e2) && allowNull)
265      return true;
266    if (noList(e1) || noList(e2))
267      return false;
268    if (e1.size() != e2.size())
269      return false;
270    for (int i = 0; i < e1.size(); i++) {
271      if (!compareDeep(e1.get(i), e2.get(i), allowNull))
272        return false;
273    }
274    return true;
275  }
276
277  private static boolean noList(List<? extends Base> list) {
278    return list == null || list.isEmpty();
279  }
280
281  public static boolean compareDeep(Base e1, Base e2, boolean allowNull) {
282    if (allowNull) {
283      boolean noLeft = e1 == null || e1.isEmpty();
284      boolean noRight = e2 == null || e2.isEmpty();
285      if (noLeft && noRight) {
286        return true;
287      }
288    }
289    if (e1 == null || e2 == null)
290      return false;
291    if (e2.isMetadataBased() && !e1.isMetadataBased()) // respect existing order for debugging consistency; outcome must
292                                                       // be the same either way
293      return e2.equalsDeep(e1);
294    else
295      return e1.equalsDeep(e2);
296  }
297
298  public static boolean compareDeep(XhtmlNode div1, XhtmlNode div2, boolean allowNull) {
299    if (div1 == null && div2 == null && allowNull)
300      return true;
301    if (div1 == null || div2 == null)
302      return false;
303    return div1.equalsDeep(div2);
304  }
305
306  public static boolean compareValues(List<? extends PrimitiveType> e1, List<? extends PrimitiveType> e2,
307      boolean allowNull) {
308    if (e1 == null && e2 == null && allowNull)
309      return true;
310    if (e1 == null || e2 == null)
311      return false;
312    if (e1.size() != e2.size())
313      return false;
314    for (int i = 0; i < e1.size(); i++) {
315      if (!compareValues(e1.get(i), e2.get(i), allowNull))
316        return false;
317    }
318    return true;
319  }
320
321  public static boolean compareValues(PrimitiveType e1, PrimitiveType e2, boolean allowNull) {
322    boolean noLeft = e1 == null || e1.isEmpty();
323    boolean noRight = e2 == null || e2.isEmpty();
324    if (noLeft && noRight && allowNull) {
325      return true;
326    }
327    if (noLeft != noRight)
328      return false;
329    return e1.equalsShallow(e2);
330  }
331
332  // -- converters for property setters
333
334  public Type castToType(Base b) throws FHIRException {
335    if (b == null) {
336      return null;
337    }
338    if (b instanceof Type)
339      return (Type) b;
340    else if (b.isMetadataBased())
341      return ((org.hl7.fhir.r4.elementmodel.Element) b).asType();
342    else
343      throw new FHIRException("Unable to convert a " + b.getClass().getName() + " to a Reference");
344  }
345
346  public BooleanType castToBoolean(Base b) throws FHIRException {
347    if (b == null) {
348      return null;
349    }
350    if (b instanceof BooleanType)
351      return (BooleanType) b;
352    else
353      throw new FHIRException("Unable to convert a " + b.getClass().getName() + " to a Boolean");
354  }
355
356  public IntegerType castToInteger(Base b) throws FHIRException {
357    if (b == null) {
358      return null;
359    }
360    if (b instanceof IntegerType)
361      return (IntegerType) b;
362    else
363      throw new FHIRException("Unable to convert a " + b.getClass().getName() + " to a Integer");
364  }
365
366  public DecimalType castToDecimal(Base b) throws FHIRException {
367    if (b == null) {
368      return null;
369    }
370    if (b instanceof DecimalType)
371      return (DecimalType) b;
372    else if (b.hasPrimitiveValue())
373      return new DecimalType(b.primitiveValue());
374    else
375      throw new FHIRException("Unable to convert a " + b.getClass().getName() + " to a Decimal");
376  }
377
378  public Base64BinaryType castToBase64Binary(Base b) throws FHIRException {
379    if (b == null) {
380      return null;
381    }
382    if (b instanceof Base64BinaryType)
383      return (Base64BinaryType) b;
384    else
385      throw new FHIRException("Unable to convert a " + b.getClass().getName() + " to a Base64Binary");
386  }
387
388  public InstantType castToInstant(Base b) throws FHIRException {
389    if (b == null) {
390      return null;
391    }
392    if (b instanceof InstantType)
393      return (InstantType) b;
394    else
395      throw new FHIRException("Unable to convert a " + b.getClass().getName() + " to a Instant");
396  }
397
398  public StringType castToString(Base b) throws FHIRException {
399    if (b == null) {
400      return null;
401    }
402    if (b instanceof StringType)
403      return (StringType) b;
404    else if (b.hasPrimitiveValue())
405      return new StringType(b.primitiveValue());
406    else
407      throw new FHIRException("Unable to convert a " + b.getClass().getName() + " to a String");
408  }
409
410  public UriType castToUri(Base b) throws FHIRException {
411    if (b == null) {
412      return null;
413    }
414    if (b instanceof UriType)
415      return (UriType) b;
416    else if (b.hasPrimitiveValue())
417      return new UriType(b.primitiveValue());
418    else
419      throw new FHIRException("Unable to convert a " + b.getClass().getName() + " to a Uri");
420  }
421
422  public UrlType castToUrl(Base b) throws FHIRException {
423    if (b == null) {
424      return null;
425    }
426    if (b instanceof UrlType)
427      return (UrlType) b;
428    else if (b.hasPrimitiveValue())
429      return new UrlType(b.primitiveValue());
430    else
431      throw new FHIRException("Unable to convert a " + b.getClass().getName() + " to a Uri");
432  }
433
434  public CanonicalType castToCanonical(Base b) throws FHIRException {
435    if (b == null) {
436      return null;
437    }
438    if (b instanceof CanonicalType)
439      return (CanonicalType) b;
440    else if (b.hasPrimitiveValue())
441      return new CanonicalType(b.primitiveValue());
442    else
443      throw new FHIRException("Unable to convert a " + b.getClass().getName() + " to a Uri");
444  }
445
446  public DateType castToDate(Base b) throws FHIRException {
447    if (b == null) {
448      return null;
449    }
450    if (b instanceof DateType)
451      return (DateType) b;
452    else if (b.hasPrimitiveValue())
453      return new DateType(b.primitiveValue());
454    else
455      throw new FHIRException("Unable to convert a " + b.getClass().getName() + " to a Date");
456  }
457
458  public DateTimeType castToDateTime(Base b) throws FHIRException {
459    if (b == null) {
460      return null;
461    }
462    if (b instanceof DateTimeType)
463      return (DateTimeType) b;
464    else if (b.fhirType().equals("dateTime"))
465      return new DateTimeType(b.primitiveValue());
466    else
467      throw new FHIRException("Unable to convert a " + b.getClass().getName() + " to a DateTime");
468  }
469
470  public TimeType castToTime(Base b) throws FHIRException {
471    if (b == null) {
472      return null;
473    }
474    if (b instanceof TimeType)
475      return (TimeType) b;
476    else
477      throw new FHIRException("Unable to convert a " + b.getClass().getName() + " to a Time");
478  }
479
480  public CodeType castToCode(Base b) throws FHIRException {
481    if (b == null) {
482      return null;
483    }
484    if (b instanceof CodeType)
485      return (CodeType) b;
486    else if (b instanceof PrimitiveType<?>)
487      return new CodeType(b.primitiveValue(), (PrimitiveType<?>) b);
488    else if (b.isPrimitive())
489      return new CodeType(b.primitiveValue());
490    else
491      throw new FHIRException("Unable to convert a " + b.getClass().getName() + " to a Code");
492  }
493
494  public OidType castToOid(Base b) throws FHIRException {
495    if (b == null) {
496      return null;
497    }
498    if (b instanceof OidType)
499      return (OidType) b;
500    else
501      throw new FHIRException("Unable to convert a " + b.getClass().getName() + " to a Oid");
502  }
503
504  public IdType castToId(Base b) throws FHIRException {
505    if (b == null) {
506      return null;
507    }
508    if (b instanceof IdType)
509      return (IdType) b;
510    else
511      throw new FHIRException("Unable to convert a " + b.getClass().getName() + " to a Id");
512  }
513
514  public UnsignedIntType castToUnsignedInt(Base b) throws FHIRException {
515    if (b == null) {
516      return null;
517    }
518    if (b instanceof UnsignedIntType)
519      return (UnsignedIntType) b;
520    else
521      throw new FHIRException("Unable to convert a " + b.getClass().getName() + " to a UnsignedInt");
522  }
523
524  public PositiveIntType castToPositiveInt(Base b) throws FHIRException {
525    if (b == null) {
526      return null;
527    }
528    if (b instanceof PositiveIntType)
529      return (PositiveIntType) b;
530    else
531      throw new FHIRException("Unable to convert a " + b.getClass().getName() + " to a PositiveInt");
532  }
533
534  public MarkdownType castToMarkdown(Base b) throws FHIRException {
535    if (b == null) {
536      return null;
537    }
538    if (b instanceof MarkdownType)
539      return (MarkdownType) b;
540    else if (b.hasPrimitiveValue())
541      return new MarkdownType(b.primitiveValue());
542    else
543      throw new FHIRException("Unable to convert a " + b.getClass().getName() + " to a Markdown");
544  }
545
546  public Annotation castToAnnotation(Base b) throws FHIRException {
547    if (b == null) {
548      return null;
549    }
550    if (b instanceof Annotation)
551      return (Annotation) b;
552    else
553      throw new FHIRException("Unable to convert a " + b.getClass().getName() + " to an Annotation");
554  }
555
556  public Dosage castToDosage(Base b) throws FHIRException {
557    if (b == null) {
558      return null;
559    }
560    if (b instanceof Dosage)
561      return (Dosage) b;
562    else
563      throw new FHIRException("Unable to convert a " + b.getClass().getName() + " to an DosageInstruction");
564  }
565
566  public Attachment castToAttachment(Base b) throws FHIRException {
567    if (b == null) {
568      return null;
569    }
570    if (b instanceof Attachment)
571      return (Attachment) b;
572    else
573      throw new FHIRException("Unable to convert a " + b.getClass().getName() + " to an Attachment");
574  }
575
576  public Identifier castToIdentifier(Base b) throws FHIRException {
577    if (b == null) {
578      return null;
579    }
580    if (b instanceof Identifier)
581      return (Identifier) b;
582    else
583      throw new FHIRException("Unable to convert a " + b.getClass().getName() + " to an Identifier");
584  }
585
586  public CodeableConcept castToCodeableConcept(Base b) throws FHIRException {
587    if (b == null) {
588      return null;
589    }
590    if (b instanceof CodeableConcept)
591      return (CodeableConcept) b;
592    else if (b instanceof Element) {
593      return ObjectConverter.readAsCodeableConcept((Element) b);
594    } else if (b instanceof CodeType) {
595      CodeableConcept cc = new CodeableConcept();
596      cc.addCoding().setCode(((CodeType) b).asStringValue());
597      return cc;
598    } else
599      throw new FHIRException("Unable to convert a " + b.getClass().getName() + " to a CodeableConcept");
600  }
601
602  public Population castToPopulation(Base b) throws FHIRException {
603    if (b == null) {
604      return null;
605    }
606    if (b instanceof Population)
607      return (Population) b;
608    else
609      throw new FHIRException("Unable to convert a " + b.getClass().getName() + " to a Population");
610  }
611
612  public Coding castToCoding(Base b) throws FHIRException {
613    if (b == null) {
614      return null;
615    }
616    if (b instanceof Coding)
617      return (Coding) b;
618    else if (b instanceof Element) {
619      ICoding c = ((Element) b).getAsICoding();
620      if (c == null)
621        throw new FHIRException("Unable to convert a " + b.getClass().getName() + " to a Coding");
622      return new Coding().setCode(c.getCode()).setSystem(c.getSystem()).setVersion(c.getVersion())
623          .setDisplay(c.getDisplay());
624    } else if (b instanceof ICoding) {
625      ICoding c = (ICoding) b;
626      return new Coding().setCode(c.getCode()).setSystem(c.getSystem()).setVersion(c.getVersion())
627          .setDisplay(c.getDisplay());
628    } else
629      throw new FHIRException("Unable to convert a " + b.getClass().getName() + " to a Coding");
630  }
631
632  public Quantity castToQuantity(Base b) throws FHIRException {
633    if (b == null) {
634      return null;
635    }
636    if (b instanceof Quantity)
637      return (Quantity) b;
638    else
639      throw new FHIRException("Unable to convert a " + b.getClass().getName() + " to an Quantity");
640  }
641
642  public Money castToMoney(Base b) throws FHIRException {
643    if (b == null) {
644      return null;
645    }
646    if (b instanceof Money)
647      return (Money) b;
648    else
649      throw new FHIRException("Unable to convert a " + b.getClass().getName() + " to an Money");
650  }
651
652  public Duration castToDuration(Base b) throws FHIRException {
653    if (b == null) {
654      return null;
655    }
656    if (b instanceof Duration)
657      return (Duration) b;
658    else
659      throw new FHIRException("Unable to convert a " + b.getClass().getName() + " to an Duration");
660  }
661
662  public SimpleQuantity castToSimpleQuantity(Base b) throws FHIRException {
663    if (b == null) {
664      return null;
665    }
666    if (b instanceof SimpleQuantity)
667      return (SimpleQuantity) b;
668    else if (b instanceof Quantity) {
669      Quantity q = (Quantity) b;
670      SimpleQuantity sq = new SimpleQuantity();
671      sq.setValueElement(q.getValueElement());
672      sq.setComparatorElement(q.getComparatorElement());
673      sq.setUnitElement(q.getUnitElement());
674      sq.setSystemElement(q.getSystemElement());
675      sq.setCodeElement(q.getCodeElement());
676      return sq;
677    } else
678      throw new FHIRException("Unable to convert a " + b.getClass().getName() + " to an SimpleQuantity");
679  }
680
681  public Range castToRange(Base b) throws FHIRException {
682    if (b == null) {
683      return null;
684    }
685    if (b instanceof Range)
686      return (Range) b;
687    else
688      throw new FHIRException("Unable to convert a " + b.getClass().getName() + " to a Range");
689  }
690
691  public Period castToPeriod(Base b) throws FHIRException {
692    if (b == null) {
693      return null;
694    }
695    if (b instanceof Period)
696      return (Period) b;
697    else
698      throw new FHIRException("Unable to convert a " + b.getClass().getName() + " to a Period");
699  }
700
701  public Ratio castToRatio(Base b) throws FHIRException {
702    if (b == null) {
703      return null;
704    }
705    if (b instanceof Ratio)
706      return (Ratio) b;
707    else
708      throw new FHIRException("Unable to convert a " + b.getClass().getName() + " to a Ratio");
709  }
710
711  public SampledData castToSampledData(Base b) throws FHIRException {
712    if (b == null) {
713      return null;
714    }
715    if (b instanceof SampledData)
716      return (SampledData) b;
717    else
718      throw new FHIRException("Unable to convert a " + b.getClass().getName() + " to a SampledData");
719  }
720
721  public Signature castToSignature(Base b) throws FHIRException {
722    if (b == null) {
723      return null;
724    }
725    if (b instanceof Signature)
726      return (Signature) b;
727    else
728      throw new FHIRException("Unable to convert a " + b.getClass().getName() + " to a Signature");
729  }
730
731  public HumanName castToHumanName(Base b) throws FHIRException {
732    if (b == null) {
733      return null;
734    }
735    if (b instanceof HumanName)
736      return (HumanName) b;
737    else
738      throw new FHIRException("Unable to convert a " + b.getClass().getName() + " to a HumanName");
739  }
740
741  public Address castToAddress(Base b) throws FHIRException {
742    if (b == null) {
743      return null;
744    }
745    if (b instanceof Address)
746      return (Address) b;
747    else
748      throw new FHIRException("Unable to convert a " + b.getClass().getName() + " to a Address");
749  }
750
751  public ContactDetail castToContactDetail(Base b) throws FHIRException {
752    if (b == null) {
753      return null;
754    }
755    if (b instanceof ContactDetail)
756      return (ContactDetail) b;
757    else
758      throw new FHIRException("Unable to convert a " + b.getClass().getName() + " to a ContactDetail");
759  }
760
761  public Contributor castToContributor(Base b) throws FHIRException {
762    if (b == null) {
763      return null;
764    }
765    if (b instanceof Contributor)
766      return (Contributor) b;
767    else
768      throw new FHIRException("Unable to convert a " + b.getClass().getName() + " to a Contributor");
769  }
770
771  public UsageContext castToUsageContext(Base b) throws FHIRException {
772    if (b == null) {
773      return null;
774    }
775    if (b instanceof UsageContext)
776      return (UsageContext) b;
777    else
778      throw new FHIRException("Unable to convert a " + b.getClass().getName() + " to a UsageContext");
779  }
780
781  public RelatedArtifact castToRelatedArtifact(Base b) throws FHIRException {
782    if (b == null) {
783      return null;
784    }
785    if (b instanceof RelatedArtifact)
786      return (RelatedArtifact) b;
787    else
788      throw new FHIRException("Unable to convert a " + b.getClass().getName() + " to a RelatedArtifact");
789  }
790
791  public ContactPoint castToContactPoint(Base b) throws FHIRException {
792    if (b == null) {
793      return null;
794    }
795    if (b instanceof ContactPoint)
796      return (ContactPoint) b;
797    else
798      throw new FHIRException("Unable to convert a " + b.getClass().getName() + " to a ContactPoint");
799  }
800
801  public Timing castToTiming(Base b) throws FHIRException {
802    if (b == null) {
803      return null;
804    }
805    if (b instanceof Timing)
806      return (Timing) b;
807    else
808      throw new FHIRException("Unable to convert a " + b.getClass().getName() + " to a Timing");
809  }
810
811  public Reference castToReference(Base b) throws FHIRException {
812    if (b == null) {
813      return null;
814    }
815    if (b instanceof Reference)
816      return (Reference) b;
817    else if (b.isPrimitive() && Utilities.isURL(b.primitiveValue()))
818      return new Reference().setReference(b.primitiveValue());
819    else if (b instanceof org.hl7.fhir.r4.elementmodel.Element && b.fhirType().equals("Reference")) {
820      org.hl7.fhir.r4.elementmodel.Element e = (org.hl7.fhir.r4.elementmodel.Element) b;
821      return new Reference().setReference(e.getChildValue("reference")).setDisplay(e.getChildValue("display"));
822    } else
823      throw new FHIRException("Unable to convert a " + b.getClass().getName() + " to a Reference");
824  }
825
826  public Meta castToMeta(Base b) throws FHIRException {
827    if (b == null) {
828      return null;
829    }
830    if (b instanceof Meta)
831      return (Meta) b;
832    else
833      throw new FHIRException("Unable to convert a " + b.getClass().getName() + " to a Meta");
834  }
835
836  public MarketingStatus castToMarketingStatus(Base b) throws FHIRException {
837    if (b == null) {
838      return null;
839    }
840    if (b instanceof MarketingStatus)
841      return (MarketingStatus) b;
842    else
843      throw new FHIRException("Unable to convert a " + b.getClass().getName() + " to a MarketingStatus");
844  }
845
846  public ProductShelfLife castToProductShelfLife(Base b) throws FHIRException {
847    if (b == null) {
848      return null;
849    }
850    if (b instanceof ProductShelfLife)
851      return (ProductShelfLife) b;
852    else
853      throw new FHIRException("Unable to convert a " + b.getClass().getName() + " to a ProductShelfLife");
854  }
855
856  public ProdCharacteristic castToProdCharacteristic(Base b) throws FHIRException {
857    if (b == null) {
858      return null;
859    }
860    if (b instanceof ProdCharacteristic)
861      return (ProdCharacteristic) b;
862    else
863      throw new FHIRException("Unable to convert a " + b.getClass().getName() + " to a ProdCharacteristic");
864  }
865
866  public SubstanceAmount castToSubstanceAmount(Base b) throws FHIRException {
867    if (b == null) {
868      return null;
869    }
870    if (b instanceof SubstanceAmount)
871      return (SubstanceAmount) b;
872    else
873      throw new FHIRException("Unable to convert a " + b.getClass().getName() + " to a SubstanceAmount");
874  }
875
876  public Extension castToExtension(Base b) throws FHIRException {
877    if (b == null) {
878      return null;
879    }
880    if (b instanceof Extension)
881      return (Extension) b;
882    else
883      throw new FHIRException("Unable to convert a " + b.getClass().getName() + " to a Extension");
884  }
885
886  public Resource castToResource(Base b) throws FHIRException {
887    if (b == null) {
888      return null;
889    }
890    if (b instanceof Resource)
891      return (Resource) b;
892    else
893      throw new FHIRException("Unable to convert a " + b.getClass().getName() + " to a Resource");
894  }
895
896  public Narrative castToNarrative(Base b) throws FHIRException {
897    if (b == null) {
898      return null;
899    }
900    if (b instanceof Narrative)
901      return (Narrative) b;
902    else
903      throw new FHIRException("Unable to convert a " + b.getClass().getName() + " to a Narrative");
904  }
905
906  public ElementDefinition castToElementDefinition(Base b) throws FHIRException {
907    if (b == null) {
908      return null;
909    }
910    if (b instanceof ElementDefinition)
911      return (ElementDefinition) b;
912    else
913      throw new FHIRException("Unable to convert a " + b.getClass().getName() + " to a ElementDefinition");
914  }
915
916  public DataRequirement castToDataRequirement(Base b) throws FHIRException {
917    if (b == null) {
918      return null;
919    }
920    if (b instanceof DataRequirement)
921      return (DataRequirement) b;
922    else
923      throw new FHIRException("Unable to convert a " + b.getClass().getName() + " to a DataRequirement");
924  }
925
926  public Expression castToExpression(Base b) throws FHIRException {
927    if (b == null) {
928      return null;
929    }
930    if (b instanceof Expression)
931      return (Expression) b;
932    else
933      throw new FHIRException("Unable to convert a " + b.getClass().getName() + " to a Expression");
934  }
935
936  public ParameterDefinition castToParameterDefinition(Base b) throws FHIRException {
937    if (b == null) {
938      return null;
939    }
940    if (b instanceof ParameterDefinition)
941      return (ParameterDefinition) b;
942    else
943      throw new FHIRException("Unable to convert a " + b.getClass().getName() + " to a ParameterDefinition");
944  }
945
946  public TriggerDefinition castToTriggerDefinition(Base b) throws FHIRException {
947    if (b == null) {
948      return null;
949    }
950    if (b instanceof TriggerDefinition)
951      return (TriggerDefinition) b;
952    else
953      throw new FHIRException("Unable to convert a " + b.getClass().getName() + " to a TriggerDefinition");
954  }
955
956  public XhtmlNode castToXhtml(Base b) throws FHIRException {
957    if (b == null) {
958      return null;
959    }
960    if (b instanceof Element) {
961      return ((Element) b).getXhtml();
962    } else if (b instanceof XhtmlType) {
963      return ((XhtmlType) b).getValue();
964    } else if (b instanceof StringType) {
965      try {
966        return new XhtmlParser().parseFragment(((StringType) b).asStringValue());
967      } catch (IOException e) {
968        throw new FHIRException(e);
969      }
970    } else
971      throw new FHIRException("Unable to convert a " + b.getClass().getName() + " to XHtml");
972  }
973
974  public String castToXhtmlString(Base b) throws FHIRException {
975    if (b == null) {
976      return null;
977    }
978    if (b instanceof Element) {
979      return ((Element) b).getValue();
980    } else if (b instanceof XhtmlType) {
981      try {
982        return new XhtmlComposer(true).compose(((XhtmlType) b).getValue());
983      } catch (IOException e) {
984        return null;
985      }
986    } else if (b instanceof StringType) {
987      return ((StringType) b).asStringValue();
988    } else
989      throw new FHIRException("Unable to convert a " + b.getClass().getName() + " to XHtml string");
990  }
991
992  protected boolean isMetadataBased() {
993    return false;
994  }
995
996  public Base[] getProperty(int hash, String name, boolean checkValid) throws FHIRException {
997    if (checkValid)
998      throw new FHIRException("Attempt to read invalid property '" + name + "' on type " + fhirType());
999    return null;
1000  }
1001
1002  public Base setProperty(int hash, String name, Base value) throws FHIRException {
1003    throw new FHIRException("Attempt to write to invalid property '" + name + "' on type " + fhirType());
1004  }
1005
1006  public Base makeProperty(int hash, String name) throws FHIRException {
1007    throw new FHIRException("Attempt to make an invalid property '" + name + "' on type " + fhirType());
1008  }
1009
1010  public String[] getTypesForProperty(int hash, String name) throws FHIRException {
1011    throw new FHIRException("Attempt to get types for an invalid property '" + name + "' on type " + fhirType());
1012  }
1013
1014  public static boolean equals(String v1, String v2) {
1015    if (v1 == null && v2 == null)
1016      return true;
1017    else if (v1 == null || v2 == null)
1018      return false;
1019    else
1020      return v1.equals(v2);
1021  }
1022
1023  public boolean isResource() {
1024    return false;
1025  }
1026
1027  public abstract String getIdBase();
1028
1029  public abstract void setIdBase(String value);
1030
1031  public Property getNamedProperty(String _name) throws FHIRException {
1032    return getNamedProperty(_name.hashCode(), _name, false);
1033  }
1034
1035  public Property getNamedProperty(int _hash, String _name, boolean _checkValid) throws FHIRException {
1036    if (_checkValid)
1037      throw new FHIRException("Attempt to read invalid property '" + _name + "' on type " + fhirType());
1038    return null;
1039  }
1040
1041  public XhtmlNode getXhtml() {
1042    return null;
1043  }
1044
1045  public abstract Base copy();
1046
1047  public void copyValues(Base dst) {
1048  }
1049
1050}