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