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