001package org.hl7.fhir.r5.utils;
002
003import java.util.List;
004
005import org.hl7.fhir.r5.elementmodel.Element;
006import org.hl7.fhir.r5.model.CanonicalResource;
007import org.hl7.fhir.r5.model.CompartmentDefinition;
008import org.hl7.fhir.r5.model.Constants;
009import org.hl7.fhir.r5.model.ContactDetail;
010import org.hl7.fhir.r5.model.ContactPoint;
011import org.hl7.fhir.r5.model.ContactPoint.ContactPointSystem;
012import org.hl7.fhir.utilities.HL7WorkGroups;
013import org.hl7.fhir.utilities.VersionUtilities;
014import org.hl7.fhir.utilities.xml.XMLUtil;
015
016public class CanonicalResourceUtilities {
017
018  public static void setHl7WG(CanonicalResource cr, String wgc) {
019    var wg = HL7WorkGroups.find(wgc);
020    if (wg == null) {
021      throw new Error("Unknown WG "+wgc);
022    }
023    ToolingExtensions.setCodeExtension(cr, ToolingExtensions.EXT_WORKGROUP, wg.getCode());
024    cr.setPublisher("HL7 International / "+wg.getName());
025    boolean found = false;
026    for (ContactDetail c : cr.getContact()) {
027      for (ContactPoint t : c.getTelecom()) {
028        if ((t.getSystem() == ContactPointSystem.URL) && wg.getLink().equals(t.getValue())) {
029          found = true;
030        }
031      }
032    }
033    if (!found) {
034      cr.addContact().addTelecom().setSystem(ContactPointSystem.URL).setValue(wg.getLink());
035    }
036  }
037
038  public static void setHl7WG(CanonicalResource cr) {
039    String wgc = ToolingExtensions.readStringExtension(cr, ToolingExtensions.EXT_WORKGROUP);
040    if (wgc == null) {
041      wgc = "fhir";      
042    }
043    var wg = HL7WorkGroups.find(wgc);
044    if (wg == null) {
045      throw new Error("Unknown WG '"+wgc+"' in "+cr.fhirType()+"/"+cr.getIdBase());
046    }
047    ToolingExtensions.setCodeExtension(cr, ToolingExtensions.EXT_WORKGROUP, wg.getCode());
048    cr.setPublisher("HL7 International / "+wg.getName());
049    boolean found = false;
050    for (ContactDetail c : cr.getContact()) {
051      for (ContactPoint t : c.getTelecom()) {
052        if ((t.getSystem() == ContactPointSystem.URL) && wg.getLink().equals(t.getValue())) {
053          found = true;
054        }
055      }
056    }
057    if (!found) {
058      cr.addContact().addTelecom().setSystem(ContactPointSystem.URL).setValue(wg.getLink());
059    }
060  }
061
062  public static void setHl7WG(Element res, String code) {
063    if (VersionUtilities.getExtendedCanonicalResourceNames(res.getFHIRPublicationVersion().toCode()).contains(res.fhirType())) {
064      var wg = HL7WorkGroups.find(code);
065      if (wg == null) {
066        throw new Error("Unknown WG "+code);
067      }
068      
069      Element ext = res.getExtension(ToolingExtensions.EXT_WORKGROUP);
070      if (ext == null) {
071        ext = res.addElement("extension");
072        ext.setChildValue("url", ToolingExtensions.EXT_WORKGROUP);
073      }
074      ext.setChildValue("valueCode", code);
075      res.setChildValue("publisher", "HL7 International / "+wg.getName());
076      while (res.hasChild("contact")) {
077        res.removeChild("contact");
078      }
079      Element c = res.addElement("contact");
080      Element t = c.addElement("telecom");
081      t.setChildValue("system", "url");
082      t.setChildValue("value", wg.getLink());
083    }    
084  }
085
086  /**
087   * for use in the core build where the context is not fully populated. Only known safe for R6 resources
088   * 
089   * @param res
090   * @param code
091   */
092  public static void setHl7WG(org.w3c.dom.Element res, String code) {
093    String rt = res.getNodeName();
094    if (VersionUtilities.getExtendedCanonicalResourceNames("5.0.0").contains(rt)) {
095      var wg = HL7WorkGroups.find(code);
096      if (wg == null) {
097        throw new Error("Unknown WG "+code);
098      }
099      
100      List<org.w3c.dom.Element> extensions = XMLUtil.getNamedChildren(res, "extension");
101      org.w3c.dom.Element wgext = null;
102      for (org.w3c.dom.Element ext : extensions) {
103        String url = ext.getAttribute("url");
104        if (ToolingExtensions.EXT_WORKGROUP.equals(url)) {
105          wgext = ext;
106        }
107      }
108      if (wgext == null) {
109        wgext = res.getOwnerDocument().createElementNS(Constants.NS_FHIR_ROOT, "extension");
110        wgext.setAttribute("url", ToolingExtensions.EXT_WORKGROUP);
111        org.w3c.dom.Element after = XMLUtil.getLastChild(res, "id", "meta", "text", "implicitRules", "language", "text", "contained");
112        if (after != null) {
113          after = XMLUtil.getNextSibling(after);
114        }
115        res.insertBefore(wgext, after);
116        res.insertBefore(res.getOwnerDocument().createTextNode("\n  "), after);
117      }
118      XMLUtil.clearChildren(wgext);
119      org.w3c.dom.Element valueCode = res.getOwnerDocument().createElementNS(Constants.NS_FHIR_ROOT, "valueCode"); 
120      wgext.appendChild(valueCode);
121      valueCode.setAttribute("value", code);
122      
123      org.w3c.dom.Element pub = XMLUtil.getNamedChild(res, "publisher");
124      if (pub == null) {
125        pub = res.getOwnerDocument().createElementNS(Constants.NS_FHIR_ROOT, "publisher");
126        org.w3c.dom.Element after = XMLUtil.getLastChild(res, "id", "meta", "text", "implicitRules", "language", "text", "contained", "extension", "modifierExtension", 
127            "url", "identifier", "version", "versionAlgorithmString", "versionAlgorithmCoding", "name", "title", "status", "experimental", "date", ("EvidenceReport".equals(rt) ? "subject" : "xx"));
128        if (after != null) {
129          after = XMLUtil.getNextSibling(after);
130        }
131        res.insertBefore(pub, after);
132        res.insertBefore(res.getOwnerDocument().createTextNode("\n  "), after);
133      }
134      pub.setAttribute("value", "HL7 International / "+wg.getName());
135
136      org.w3c.dom.Element contact = XMLUtil.getNamedChild(res, "contact");
137      if (contact == null) {
138        contact = res.getOwnerDocument().createElementNS(Constants.NS_FHIR_ROOT, "contact");
139        res.insertBefore(contact, XMLUtil.getNextSibling(pub));
140        res.insertBefore(res.getOwnerDocument().createTextNode("\n  "), contact.getNextSibling());
141      }
142
143      org.w3c.dom.Element telecom = XMLUtil.getNamedChild(contact, "telecom");
144      if (telecom == null) {
145        contact.appendChild(res.getOwnerDocument().createTextNode("\n    "));
146        telecom = res.getOwnerDocument().createElementNS(Constants.NS_FHIR_ROOT, "telecom");
147        contact.appendChild(telecom);
148        contact.appendChild(res.getOwnerDocument().createTextNode("\n  "));
149      }
150      
151      org.w3c.dom.Element system = XMLUtil.getNamedChild(telecom, "system");
152      if (system == null) {
153        system = res.getOwnerDocument().createElementNS(Constants.NS_FHIR_ROOT, "system");
154        org.w3c.dom.Element after = XMLUtil.getLastChild(telecom, "id", "extension");
155        if (after != null) {
156          after = XMLUtil.getNextSibling(after);
157        }
158        telecom.insertBefore(system, after);
159        telecom.insertBefore(res.getOwnerDocument().createTextNode("\n      "), after);
160      }
161      system.setAttribute("value", "url");
162    
163
164      org.w3c.dom.Element value = XMLUtil.getNamedChild(telecom, "value");
165      if (value == null) {
166        value = res.getOwnerDocument().createElementNS(Constants.NS_FHIR_ROOT, "value");
167        org.w3c.dom.Element after = XMLUtil.getLastChild(telecom, "id", "extension", "system");
168        if (after != null) {
169          after = XMLUtil.getNextSibling(after);
170        }
171        telecom.insertBefore(system, after);
172        telecom.insertBefore(res.getOwnerDocument().createTextNode("\n      "), after);
173      }
174      value.setAttribute("value", wg.getLink());
175    }
176  }
177}