001package org.hl7.fhir.r4.terminologies;
002
003/*-
004 * #%L
005 * org.hl7.fhir.r4
006 * %%
007 * Copyright (C) 2014 - 2019 Health Level 7
008 * %%
009 * Licensed under the Apache License, Version 2.0 (the "License");
010 * you may not use this file except in compliance with the License.
011 * You may obtain a copy of the License at
012 * 
013 *      http://www.apache.org/licenses/LICENSE-2.0
014 * 
015 * Unless required by applicable law or agreed to in writing, software
016 * distributed under the License is distributed on an "AS IS" BASIS,
017 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
018 * See the License for the specific language governing permissions and
019 * limitations under the License.
020 * #L%
021 */
022
023import org.hl7.fhir.exceptions.FHIRException;
024import org.hl7.fhir.r4.context.IWorkerContext;
025import org.hl7.fhir.r4.model.CanonicalType;
026import org.hl7.fhir.r4.model.CodeSystem;
027import org.hl7.fhir.r4.model.Enumerations.PublicationStatus;
028import org.hl7.fhir.r4.model.Identifier;
029import org.hl7.fhir.r4.model.Meta;
030import org.hl7.fhir.r4.model.UriType;
031import org.hl7.fhir.r4.model.ValueSet;
032import org.hl7.fhir.r4.model.ValueSet.ConceptSetComponent;
033import org.hl7.fhir.r4.utils.ToolingExtensions;
034import org.hl7.fhir.utilities.StandardsStatus;
035import org.hl7.fhir.utilities.Utilities;
036
037public class ValueSetUtilities {
038
039  public static ValueSet makeShareable(ValueSet vs) {
040    if (!vs.hasMeta())
041      vs.setMeta(new Meta());
042    for (UriType t : vs.getMeta().getProfile()) 
043      if (t.getValue().equals("http://hl7.org/fhir/StructureDefinition/shareablevalueset"))
044        return vs;
045    vs.getMeta().getProfile().add(new CanonicalType("http://hl7.org/fhir/StructureDefinition/shareablevalueset"));
046    return vs;
047  }
048
049  public static void checkShareable(ValueSet vs) {
050    if (!vs.hasMeta())
051      throw new Error("ValueSet "+vs.getUrl()+" is not shareable");
052    for (UriType t : vs.getMeta().getProfile()) {
053      if (t.getValue().equals("http://hl7.org/fhir/StructureDefinition/shareablevalueset"))
054        return;
055    }
056    throw new Error("ValueSet "+vs.getUrl()+" is not shareable");    
057  }
058
059  public static boolean hasOID(ValueSet vs) {
060    return getOID(vs) != null;
061  }
062
063  public static String getOID(ValueSet vs) {
064    for (Identifier id : vs.getIdentifier()) {
065      if ("urn:ietf:rfc:3986".equals(id.getSystem()) && id.hasValue() && id.getValue().startsWith("urn:oid:"))
066        return id.getValue().substring(8);
067    }
068    return null;
069  }
070
071  public static void setOID(ValueSet vs, String oid) {
072    if (!oid.startsWith("urn:oid:"))
073      oid = "urn:oid:" + oid;
074    for (Identifier id : vs.getIdentifier()) {
075      if ("urn:ietf:rfc:3986".equals(id.getSystem()) && id.hasValue() && id.getValue().startsWith("urn:oid:")) {
076        id.setValue(oid);
077        return;
078      }
079    }
080    vs.addIdentifier().setSystem("urn:ietf:rfc:3986").setValue(oid);
081  }
082
083  public static void markStatus(ValueSet vs, String wg, StandardsStatus status, String pckage, String fmm, IWorkerContext context, String normativeVersion) throws FHIRException {
084    if (vs.hasUserData("external.url"))
085      return;
086    
087    if (wg != null) {
088      if (!ToolingExtensions.hasExtension(vs, ToolingExtensions.EXT_WORKGROUP) || 
089          (!Utilities.existsInList(ToolingExtensions.readStringExtension(vs, ToolingExtensions.EXT_WORKGROUP), "fhir", "vocab") && Utilities.existsInList(wg, "fhir", "vocab"))) {
090        ToolingExtensions.setCodeExtension(vs, ToolingExtensions.EXT_WORKGROUP, wg);
091      }
092    }
093    if (status != null) {
094      StandardsStatus ss = ToolingExtensions.getStandardsStatus(vs);
095      if (ss == null || ss.isLowerThan(status)) 
096        ToolingExtensions.setStandardsStatus(vs, status, normativeVersion);
097      if (pckage != null) {
098        if (!vs.hasUserData("ballot.package"))        
099          vs.setUserData("ballot.package", pckage);
100        else if (!pckage.equals(vs.getUserString("ballot.package")))
101          if (!"infrastructure".equals(vs.getUserString("ballot.package")))
102          System.out.println("Value Set "+vs.getUrl()+": ownership clash "+pckage+" vs "+vs.getUserString("ballot.package"));
103      }
104      if (status == StandardsStatus.NORMATIVE) {
105        vs.setExperimental(false);
106        vs.setStatus(PublicationStatus.ACTIVE);
107      }
108    }
109    if (fmm != null) {
110      String sfmm = ToolingExtensions.readStringExtension(vs, ToolingExtensions.EXT_FMM_LEVEL);
111      if (Utilities.noString(sfmm) || Integer.parseInt(sfmm) < Integer.parseInt(fmm)) 
112        ToolingExtensions.setIntegerExtension(vs, ToolingExtensions.EXT_FMM_LEVEL, Integer.parseInt(fmm));
113    }
114    if (vs.hasUserData("cs"))
115      CodeSystemUtilities.markStatus((CodeSystem) vs.getUserData("cs"), wg, status, pckage, fmm, normativeVersion);
116    else if (status == StandardsStatus.NORMATIVE && context != null) {
117      for (ConceptSetComponent csc : vs.getCompose().getInclude()) {
118        if (csc.hasSystem()) {
119          CodeSystem cs = context.fetchCodeSystem(csc.getSystem());
120          if (cs != null) {
121            CodeSystemUtilities.markStatus(cs, wg, status, pckage, fmm, normativeVersion);
122          }
123        }
124      }
125    }
126  }
127
128  private static int ssval(String status) {
129    if ("Draft".equals("status")) 
130      return 1;
131    if ("Informative".equals("status")) 
132      return 2;
133    if ("External".equals("status")) 
134      return 3;
135    if ("Trial Use".equals("status")) 
136      return 3;
137    if ("Normative".equals("status")) 
138      return 4;
139    return -1;
140  }
141
142}