001package org.hl7.fhir.dstu3.terminologies;
002
003import java.util.List;
004
005import org.hl7.fhir.dstu3.model.BooleanType;
006import org.hl7.fhir.dstu3.model.CodeSystem;
007import org.hl7.fhir.dstu3.model.CodeSystem.ConceptDefinitionComponent;
008import org.hl7.fhir.dstu3.model.CodeSystem.ConceptPropertyComponent;
009import org.hl7.fhir.dstu3.model.CodeSystem.PropertyComponent;
010import org.hl7.fhir.dstu3.model.CodeSystem.PropertyType;
011import org.hl7.fhir.dstu3.utils.ToolingExtensions;
012import org.hl7.fhir.dstu3.model.DateTimeType;
013import org.hl7.fhir.dstu3.model.Identifier;
014import org.hl7.fhir.dstu3.model.Meta;
015import org.hl7.fhir.dstu3.model.UriType;
016import org.hl7.fhir.exceptions.FHIRException;
017import org.hl7.fhir.utilities.Utilities;
018
019public class CodeSystemUtilities {
020
021  public static boolean isDeprecated(CodeSystem cs, ConceptDefinitionComponent def) {
022    for (ConceptPropertyComponent p : def.getProperty()) {
023      if (p.getCode().equals("deprecated") && p.hasValue() && p.getValue() instanceof BooleanType) 
024        return ((BooleanType) p.getValue()).getValue();
025    }
026    return false;
027  }
028
029  public static boolean isNotSelectable(CodeSystem cs, ConceptDefinitionComponent def) {
030    for (ConceptPropertyComponent p : def.getProperty()) {
031      if (p.getCode().equals("notSelectable") && p.hasValue() && p.getValue() instanceof BooleanType) 
032        return ((BooleanType) p.getValue()).getValue();
033    }
034    return false;
035  }
036
037  public static void setNotSelectable(CodeSystem cs, ConceptDefinitionComponent concept) {
038    defineNotSelectableProperty(cs);
039    concept.addProperty().setCode("notSelectable").setValue(new BooleanType(true));    
040  }
041
042  public static void setInactive(CodeSystem cs, ConceptDefinitionComponent concept) {
043    defineInactiveProperty(cs);
044    concept.addProperty().setCode("inactive").setValue(new BooleanType(true));    
045  }
046
047  public static void setDeprecated(CodeSystem cs, ConceptDefinitionComponent concept, DateTimeType date) {
048    defineDeprecatedProperty(cs);
049    concept.addProperty().setCode("deprecated").setValue(date);    
050  }
051
052  public static void defineNotSelectableProperty(CodeSystem cs) {
053    defineCodeSystemProperty(cs, "notSelectable", "Indicates that the code is abstract - only intended to be used as a selector for other concepts", PropertyType.BOOLEAN);
054  }
055
056  public static void defineInactiveProperty(CodeSystem cs) {
057    defineCodeSystemProperty(cs, "inactive", "True if the concept is not considered active - e.g. not a valid concept any more", PropertyType.BOOLEAN);
058  }
059
060  public static void defineDeprecatedProperty(CodeSystem cs) {
061    defineCodeSystemProperty(cs, "deprecated", "The date at which a concept was deprecated. Concepts that are deprecated but not inactive can still be used, but their use is discouraged", PropertyType.DATETIME);
062  }
063
064  public static void defineCodeSystemProperty(CodeSystem cs, String code, String description, PropertyType type) {
065    for (PropertyComponent p : cs.getProperty()) {
066      if (p.getCode().equals(code))
067        return;
068    }
069    cs.addProperty().setCode(code).setDescription(description).setType(type).setUri("http://hl7.org/fhir/concept-properties#"+code);
070  }
071
072  public static String getCodeDefinition(CodeSystem cs, String code) {
073    return getCodeDefinition(cs.getConcept(), code);
074  }
075
076  private static String getCodeDefinition(List<ConceptDefinitionComponent> list, String code) {
077    for (ConceptDefinitionComponent c : list) {
078      if (c.getCode().equals(code))
079        return c.getDefinition();
080      String s = getCodeDefinition(c.getConcept(), code);
081      if (s != null)
082        return s;
083    }
084    return null;
085  }
086
087  public static CodeSystem makeShareable(CodeSystem cs) {
088    if (!cs.hasMeta())
089      cs.setMeta(new Meta());
090    for (UriType t : cs.getMeta().getProfile()) 
091      if (t.getValue().equals("http://hl7.org/fhir/StructureDefinition/shareablecodesystem"))
092        return cs;
093    cs.getMeta().getProfile().add(new UriType("http://hl7.org/fhir/StructureDefinition/shareablecodesystem"));
094    return cs;
095  }
096
097  public static void setOID(CodeSystem cs, String oid) {
098    if (!oid.startsWith("urn:oid:"))
099       oid = "urn:oid:" + oid;
100    if (!cs.hasIdentifier())
101      cs.setIdentifier(new Identifier().setSystem("urn:ietf:rfc:3986").setValue(oid));
102    else if ("urn:ietf:rfc:3986".equals(cs.getIdentifier().getSystem()) && cs.getIdentifier().hasValue() && cs.getIdentifier().getValue().startsWith("urn:oid:"))
103      cs.getIdentifier().setValue(oid);
104    else
105      throw new Error("unable to set OID on code system");
106    
107  }
108
109  public static boolean hasOID(CodeSystem cs) {
110    return getOID(cs) != null;
111  }
112
113  public static String getOID(CodeSystem cs) {
114    if (cs.hasIdentifier() && "urn:ietf:rfc:3986".equals(cs.getIdentifier().getSystem()) && cs.getIdentifier().hasValue() && cs.getIdentifier().getValue().startsWith("urn:oid:"))
115        return cs.getIdentifier().getValue().substring(8);
116    return null;
117  }
118
119  public static boolean isInactive(CodeSystem cs, ConceptDefinitionComponent def) throws FHIRException {
120    for (ConceptPropertyComponent p : def.getProperty()) {
121      if (p.getCode().equals("status") && p.hasValueStringType()) 
122        return "inactive".equals(p.getValueStringType());
123    }
124    return false;
125  }
126  
127  public static boolean isInactive(CodeSystem cs, String code) throws FHIRException {
128    ConceptDefinitionComponent def = findCode(cs.getConcept(), code);
129    if (def == null)
130      return true;
131    return isInactive(cs, def);
132  }
133
134  private static ConceptDefinitionComponent findCode(List<ConceptDefinitionComponent> list, String code) {
135    for (ConceptDefinitionComponent c : list) {
136      if (c.getCode().equals(code))
137        return c;
138      ConceptDefinitionComponent s = findCode(c.getConcept(), code);
139      if (s != null)
140        return s;
141    }
142    return null;
143  }
144
145  public static void markStatus(CodeSystem cs, String wg, String status, String fmm) {
146  }
147
148  private static int ssval(String status) {
149    if ("Draft".equals("status")) 
150      return 1;
151    if ("Informative".equals("status")) 
152      return 2;
153    if ("External".equals("status")) 
154      return 3;
155    if ("Trial Use".equals("status")) 
156      return 3;
157    if ("Normative".equals("status")) 
158      return 4;
159    return -1;
160  }
161
162}