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