001package org.hl7.fhir.r5.utils;
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.util.ArrayList;
035import java.util.Arrays;
036import java.util.HashSet;
037import java.util.List;
038
039import org.hl7.fhir.utilities.MarkedToMoveToAdjunctPackage;
040import org.hl7.fhir.utilities.VersionUtilities;
041
042
043@MarkedToMoveToAdjunctPackage
044public class TypesUtilities {
045  private static final HashSet<String> primitiveTypes = new HashSet<>(Arrays.asList("boolean", "integer", "integer64", "string", "decimal", "uri", "url", "canonical", "base64Binary", "instant", "date", "dateTime", "time", "code", "oid", "id", "uuid", "markdown", "unsignedInt", "positiveInt", "xhtml"));
046
047  public enum TypeClassification {
048    PRIMITIVE, DATATYPE, METADATATYPE, SPECIAL;
049
050    public String toDisplay() {
051      switch (this) {
052      case DATATYPE: return "Datatype";
053      case METADATATYPE: return "MetaDataType";
054      case PRIMITIVE: return "Primitive Type";
055      case SPECIAL: return "Special Type";
056      }
057      return "?tu-class?";
058    }
059  }
060
061  public static class WildcardInformation {
062    private TypeClassification classification;
063    private String typeName;
064    private String comment;
065    public WildcardInformation(String typeName, String comment, TypeClassification classification) {
066      super();
067      this.typeName = typeName;
068      this.comment = comment;
069      this.classification = classification;
070    }
071    public WildcardInformation(String typeName, TypeClassification classification) {
072      super();
073      this.typeName = typeName;
074      this.classification = classification;
075    }
076    public String getTypeName() {
077      return typeName;
078    }
079    public String getComment() {
080      return comment;
081    }
082    public TypeClassification getClassification() {
083      return classification;
084    }
085    
086  }
087  
088  public static List<String> wildcardTypes(String version) {
089    List<String> res = new ArrayList<String>();
090    for (WildcardInformation wi : wildcards(version))
091      res.add(wi.getTypeName());
092    return res;
093  }
094  
095  // this is the master list for what data types are allowed where the types = *
096  // that this list is incomplete means that the following types cannot have fixed values in a profile:
097  //   Narrative
098  //   Meta
099  //   Any of the IDMP data types
100  // You have to walk into them to profile them.
101  //
102  public static List<WildcardInformation> wildcards(String version) {
103    if (version.startsWith("_")) {
104      throw new Error("underscore");
105    }
106    List<WildcardInformation> res = new ArrayList<WildcardInformation>();
107
108    // primitive types
109    res.add(new WildcardInformation("base64Binary", TypeClassification.PRIMITIVE));
110    res.add(new WildcardInformation("boolean", TypeClassification.PRIMITIVE));
111    res.add(new WildcardInformation("canonical", TypeClassification.PRIMITIVE));
112    res.add(new WildcardInformation("code", "(only if the extension definition provides a <a href=\"terminologies.html#code\">fixed</a> binding to a suitable set of codes)", TypeClassification.PRIMITIVE));
113    res.add(new WildcardInformation("date", TypeClassification.PRIMITIVE));
114    res.add(new WildcardInformation("dateTime", TypeClassification.PRIMITIVE));
115    res.add(new WildcardInformation("decimal", TypeClassification.PRIMITIVE));
116    res.add(new WildcardInformation("id", TypeClassification.PRIMITIVE));
117    res.add(new WildcardInformation("instant", TypeClassification.PRIMITIVE));
118    res.add(new WildcardInformation("integer", TypeClassification.PRIMITIVE));
119    if (!VersionUtilities.isR4BVer(version)) {
120      res.add(new WildcardInformation("integer64", TypeClassification.PRIMITIVE));
121    }
122    res.add(new WildcardInformation("markdown", TypeClassification.PRIMITIVE));
123    res.add(new WildcardInformation("oid", TypeClassification.PRIMITIVE));
124    res.add(new WildcardInformation("positiveInt", TypeClassification.PRIMITIVE));
125    res.add(new WildcardInformation("string", TypeClassification.PRIMITIVE));
126    res.add(new WildcardInformation("time", TypeClassification.PRIMITIVE));
127    res.add(new WildcardInformation("unsignedInt", TypeClassification.PRIMITIVE));
128    res.add(new WildcardInformation("uri", TypeClassification.PRIMITIVE));
129    res.add(new WildcardInformation("url", TypeClassification.PRIMITIVE));
130    res.add(new WildcardInformation("uuid", TypeClassification.PRIMITIVE));
131
132    // Complex general purpose data types
133    res.add(new WildcardInformation("Address", TypeClassification.DATATYPE));
134    res.add(new WildcardInformation("Age", TypeClassification.DATATYPE));
135    res.add(new WildcardInformation("Annotation", TypeClassification.DATATYPE));
136    res.add(new WildcardInformation("Attachment", TypeClassification.DATATYPE));
137    res.add(new WildcardInformation("CodeableConcept", TypeClassification.DATATYPE));
138    res.add(new WildcardInformation("CodeableReference", TypeClassification.DATATYPE));
139    res.add(new WildcardInformation("Coding", TypeClassification.DATATYPE));
140    res.add(new WildcardInformation("ContactPoint", TypeClassification.DATATYPE));
141    res.add(new WildcardInformation("Count", TypeClassification.DATATYPE));
142    res.add(new WildcardInformation("Distance", TypeClassification.DATATYPE));
143    res.add(new WildcardInformation("Duration", TypeClassification.DATATYPE));
144    res.add(new WildcardInformation("HumanName", TypeClassification.DATATYPE));
145    res.add(new WildcardInformation("Identifier", TypeClassification.DATATYPE));
146    res.add(new WildcardInformation("Money", TypeClassification.DATATYPE));
147    res.add(new WildcardInformation("Period", TypeClassification.DATATYPE));
148    res.add(new WildcardInformation("Quantity", TypeClassification.DATATYPE));
149    res.add(new WildcardInformation("Range", TypeClassification.DATATYPE));
150    res.add(new WildcardInformation("Ratio", TypeClassification.DATATYPE));
151    res.add(new WildcardInformation("RatioRange", TypeClassification.DATATYPE));
152    res.add(new WildcardInformation("Reference", " - a reference to another resource", TypeClassification.DATATYPE));
153    res.add(new WildcardInformation("SampledData", TypeClassification.DATATYPE));
154    res.add(new WildcardInformation("Signature", TypeClassification.DATATYPE));
155    res.add(new WildcardInformation("Timing", TypeClassification.DATATYPE));
156    
157    // metadata types
158    res.add(new WildcardInformation("ContactDetail", TypeClassification.METADATATYPE));
159    res.add(new WildcardInformation("DataRequirement", TypeClassification.METADATATYPE));
160    res.add(new WildcardInformation("Expression", TypeClassification.METADATATYPE));
161    res.add(new WildcardInformation("ParameterDefinition", TypeClassification.METADATATYPE));
162    res.add(new WildcardInformation("RelatedArtifact", TypeClassification.METADATATYPE));
163    res.add(new WildcardInformation("TriggerDefinition", TypeClassification.METADATATYPE));
164    res.add(new WildcardInformation("UsageContext", TypeClassification.METADATATYPE));
165    res.add(new WildcardInformation("Availability", TypeClassification.METADATATYPE));
166    res.add(new WildcardInformation("ExtendedContactDetail", TypeClassification.METADATATYPE));
167    
168    // special cases
169    res.add(new WildcardInformation("Dosage", TypeClassification.SPECIAL));
170    if (!VersionUtilities.isR4BVer(version)) {
171      res.add(new WildcardInformation("Meta", TypeClassification.SPECIAL));
172    }
173    return res;
174  }
175
176  public static boolean isPrimitive(String code) {
177    return primitiveTypes.contains(code);
178  }
179}