001package org.hl7.fhir.r4.terminologies;
002
003import javax.net.ssl.SSLEngineResult.HandshakeStatus;
004
005import org.hl7.fhir.exceptions.FHIRException;
006import org.hl7.fhir.r4.context.IWorkerContext;
007import org.hl7.fhir.r4.model.CanonicalType;
008import org.hl7.fhir.r4.model.CodeSystem;
009import org.hl7.fhir.r4.model.Identifier;
010import org.hl7.fhir.r4.model.Meta;
011import org.hl7.fhir.r4.model.UriType;
012import org.hl7.fhir.r4.model.ValueSet;
013import org.hl7.fhir.r4.model.ValueSet.ConceptSetComponent;
014import org.hl7.fhir.r4.utils.ToolingExtensions;
015import org.hl7.fhir.utilities.StandardsStatus;
016import org.hl7.fhir.utilities.Utilities;
017
018public class ValueSetUtilities {
019
020  public static ValueSet makeShareable(ValueSet vs) {
021    if (!vs.hasMeta())
022      vs.setMeta(new Meta());
023    for (UriType t : vs.getMeta().getProfile()) 
024      if (t.getValue().equals("http://hl7.org/fhir/StructureDefinition/shareablevalueset"))
025        return vs;
026    vs.getMeta().getProfile().add(new CanonicalType("http://hl7.org/fhir/StructureDefinition/shareablevalueset"));
027    return vs;
028  }
029
030  public static void checkShareable(ValueSet vs) {
031    if (!vs.hasMeta())
032      throw new Error("ValueSet "+vs.getUrl()+" is not shareable");
033    for (UriType t : vs.getMeta().getProfile()) {
034      if (t.getValue().equals("http://hl7.org/fhir/StructureDefinition/shareablevalueset"))
035        return;
036    }
037    throw new Error("ValueSet "+vs.getUrl()+" is not shareable");    
038  }
039
040  public static boolean hasOID(ValueSet vs) {
041    return getOID(vs) != null;
042  }
043
044  public static String getOID(ValueSet vs) {
045    for (Identifier id : vs.getIdentifier()) {
046      if ("urn:ietf:rfc:3986".equals(id.getSystem()) && id.hasValue() && id.getValue().startsWith("urn:oid:"))
047        return id.getValue().substring(8);
048    }
049    return null;
050  }
051
052  public static void setOID(ValueSet vs, String oid) {
053    if (!oid.startsWith("urn:oid:"))
054      oid = "urn:oid:" + oid;
055    for (Identifier id : vs.getIdentifier()) {
056      if ("urn:ietf:rfc:3986".equals(id.getSystem()) && id.hasValue() && id.getValue().startsWith("urn:oid:")) {
057        id.setValue(oid);
058        return;
059      }
060    }
061    vs.addIdentifier().setSystem("urn:ietf:rfc:3986").setValue(oid);
062  }
063
064  public static void markStatus(ValueSet vs, String wg, StandardsStatus status, String pckage, String fmm, IWorkerContext context) throws FHIRException {
065    if (vs.hasUserData("external.url"))
066      return;
067    
068    if (wg != null) {
069      if (!ToolingExtensions.hasExtension(vs, ToolingExtensions.EXT_WORKGROUP) || 
070          (!Utilities.existsInList(ToolingExtensions.readStringExtension(vs, ToolingExtensions.EXT_WORKGROUP), "fhir", "vocab") && Utilities.existsInList(wg, "fhir", "vocab"))) {
071        ToolingExtensions.setCodeExtension(vs, ToolingExtensions.EXT_WORKGROUP, wg);
072      }
073    }
074    if (status != null) {
075      StandardsStatus ss = ToolingExtensions.getStandardsStatus(vs);
076      if (ss == null || ss.isLowerThan(status)) 
077        ToolingExtensions.setStandardsStatus(vs, status);
078      if (pckage != null) {
079        if (!vs.hasUserData("ballot.package"))        
080          vs.setUserData("ballot.package", pckage);
081        else if (!pckage.equals(vs.getUserString("ballot.package")))
082          if (!"infrastructure".equals(vs.getUserString("ballot.package")))
083          System.out.println("Value Set "+vs.getUrl()+": ownership clash "+pckage+" vs "+vs.getUserString("ballot.package"));
084      }
085      if (ss == StandardsStatus.NORMATIVE)
086        vs.setExperimental(false);
087    }
088    if (fmm != null) {
089      String sfmm = ToolingExtensions.readStringExtension(vs, ToolingExtensions.EXT_FMM_LEVEL);
090      if (Utilities.noString(sfmm) || Integer.parseInt(sfmm) < Integer.parseInt(fmm)) 
091        ToolingExtensions.setIntegerExtension(vs, ToolingExtensions.EXT_FMM_LEVEL, Integer.parseInt(fmm));
092    }
093    if (vs.hasUserData("cs"))
094      CodeSystemUtilities.markStatus((CodeSystem) vs.getUserData("cs"), wg, status, pckage, fmm);
095    else if (status == StandardsStatus.NORMATIVE && context != null) {
096      for (ConceptSetComponent csc : vs.getCompose().getInclude()) {
097        if (csc.hasSystem()) {
098          CodeSystem cs = context.fetchCodeSystem(csc.getSystem());
099          if (cs != null) {
100            CodeSystemUtilities.markStatus(cs, wg, status, pckage, fmm);
101          }
102        }
103      }
104    }
105  }
106
107  private static int ssval(String status) {
108    if ("Draft".equals("status")) 
109      return 1;
110    if ("Informative".equals("status")) 
111      return 2;
112    if ("External".equals("status")) 
113      return 3;
114    if ("Trial Use".equals("status")) 
115      return 3;
116    if ("Normative".equals("status")) 
117      return 4;
118    return -1;
119  }
120
121}