001package org.hl7.fhir.r5.utils;
002
003import java.io.File;
004import java.io.FileOutputStream;
005import java.io.IOException;
006import java.util.List;
007
008import org.hl7.fhir.r5.formats.IParser.OutputStyle;
009import org.hl7.fhir.utilities.CommaSeparatedStringBuilder;
010import org.hl7.fhir.utilities.FileUtilities;
011import org.hl7.fhir.utilities.MarkedToMoveToAdjunctPackage;
012import org.hl7.fhir.utilities.Utilities;
013import org.hl7.fhir.utilities.json.JsonException;
014import org.hl7.fhir.utilities.json.model.JsonElement;
015import org.hl7.fhir.utilities.json.model.JsonObject;
016import org.hl7.fhir.utilities.json.model.JsonProperty;
017import org.hl7.fhir.utilities.json.parser.JsonParser;
018
019@MarkedToMoveToAdjunctPackage
020public class JsonResourceTemplateFixer {
021
022  public static void main(String[] args) throws JsonException, IOException {
023  new JsonResourceTemplateFixer().execute(
024      "/Users/grahamegrieve/work/fhir-tx-ecosystem-ig/tests",
025      "/Users/grahamegrieve/temp/tx-tests", "");
026  }
027
028  private void execute(String source, String dest, String path) throws JsonException, IOException {
029    File src = new File(source);
030    for (File f : src.listFiles()) {
031      if (f.isDirectory()) {
032        execute(f.getAbsolutePath(), dest, "".equals(path) ? f.getName() : Utilities.path(path, f.getName()));
033      } else if (f.getName().endsWith(".json")) {
034        JsonObject j = JsonParser.parseObject(f);
035        if (j.has("resourceType")) {
036          FileUtilities.createDirectory(Utilities.path(dest, "in", path));
037          JsonParser.compose(j, new File(Utilities.path(dest, "in", path, f.getName())), true);
038          checkJsonObject(j);
039          FileUtilities.createDirectory(Utilities.path(dest, "out", path));
040          File tgt = new File(Utilities.path(dest, "out", path, f.getName()));
041          JsonParser.compose(j, tgt, true);
042          try {
043            var res = new org.hl7.fhir.r5.formats.JsonParser().parse(FileUtilities.fileToBytes(tgt));
044            new org.hl7.fhir.r5.formats.JsonParser().setOutputStyle(OutputStyle.PRETTY).compose(new FileOutputStream(tgt), res);
045          } catch (Exception e) {
046            System.out.println("Error reading "+tgt.getAbsolutePath()+": "+e.getMessage());
047          }
048        }
049      }
050    } 
051  }
052
053  private void checkJsonObject(JsonObject j) {
054    if (j.has("$optional-properties$")) {
055      List<String> names = j.getJsonArray("$optional-properties$").asStrings();
056      j.remove("$optional-properties$");
057      addExtension(j, "optional-properties", "string", CommaSeparatedStringBuilder.join(",", names));
058//      for (String n : names) {
059//        if (j.hasObject(n)) {
060//          addExtension(j.getJsonObject(n), "optional", true);
061//        } else {
062////          addExtension(j.forceObject("_"+n), "optional", true);
063//          addExtension(j, "optional-property", "code", n);
064//        }
065//      }
066    }
067    if (j.has("$optional$")) {
068      j.remove("$optional$");
069      addExtension(j, "optional", true);
070      
071    }
072    if (j.has("$count-arrays$")) {
073      List<String> names = j.getJsonArray("$count-arrays$").asStrings();
074      j.remove("$count-arrays$");
075      addExtension(j, "count-arrays", "string", CommaSeparatedStringBuilder.join(",", names));
076//      for (String n : names) {
077//        addExtension(j, "count-array", "code", n);
078//      }
079    }
080
081    for (int i = j.getProperties().size() -1; i >= 0; i--) {
082      JsonProperty p = j.getProperties().get(i);
083       if (p.getValue().isJsonArray()) {
084         for (JsonElement e : p.getValue().asJsonArray()) {
085            checkJsonElement(j, p.getName(), e);
086         }
087      } else {
088        checkJsonElement(j, p.getName(), p.getValue());
089      }
090    }
091  }
092
093  public void addExtension(JsonObject j, String url, String type, String value) {
094    JsonObject ext = new JsonObject();
095    ext.set("url", "http://hl7.org/fhir/uv/tools/StructureDefinition/test-template-"+url);
096    ext.set("value"+Utilities.capitalize(type), value);
097    j.forceArray(0, "extension").add(ext);
098  }
099
100  public void addExtension(JsonObject j, String url, boolean value) {
101    JsonObject ext = new JsonObject();
102    ext.set("url", "http://hl7.org/fhir/uv/tools/StructureDefinition/test-template-"+url);
103    ext.set("valueBoolean", value);
104    j.forceArray(0, "extension").add(ext);
105  }
106
107  public void addNamedExtension(JsonObject parent, String name, String url, String type, String value) {
108    JsonObject k = parent.getJsonObject("_"+name);
109    if (k == null) {
110      k = new JsonObject();
111      parent.add("_"+name, k);
112    }
113    JsonObject ext = new JsonObject();
114    ext.set("url", "http://hl7.org/fhir/uv/tools/StructureDefinition/test-template-"+url);
115    ext.set("value"+Utilities.capitalize(type), value);
116    k.forceArray("extension").add(ext);
117  }
118  
119  private void checkJsonElement(JsonObject parent, String name, JsonElement value) {
120    if (value.isJsonObject()) {
121      checkJsonObject(value.asJsonObject());
122    } else if (value.isJsonPrimitive()) {
123      checkJsonPrimitive(parent, name, value.asString());
124    } else {
125      // ignore?
126      System.out.println("What?");
127    }
128  }
129
130  private void checkJsonPrimitive(JsonObject parent, String name, String value) {
131    if (true) {
132      return;
133    }
134    if (value.startsWith("$")) {
135      parent.remove(name);
136      switch (value) {
137      case "$$" : 
138        addNamedExtension(parent, name, "value-rule", "string", "string");
139        break;
140      case "$id$" :
141        addNamedExtension(parent, name, "value-rule", "string", "id");
142        break;
143      case "$semver$" : 
144        addNamedExtension(parent, name, "value-rule", "string", "semver");
145        break;
146      case "$url$" : 
147        addNamedExtension(parent, name, "value-rule", "string", "url");
148        break;
149      case "$token$" : 
150        addNamedExtension(parent, name, "value-rule", "string", "token");
151        break;
152      case "$string$" : 
153        addNamedExtension(parent, name, "value-rule", "string", "string");
154        break;
155      case "$date$" : 
156        addNamedExtension(parent, name, "value-rule", "string", "date");
157        break;
158      case "$version$" : 
159        addNamedExtension(parent, name, "value-rule", "string", "version");
160        break;
161      case "$uuid$" : 
162        addNamedExtension(parent, name, "value-rule", "string", "uuid");
163        break;
164      case "$instant$" : 
165        addNamedExtension(parent, name, "value-rule", "string", "instant");
166        break;
167      default:
168        if (value.startsWith("$choice:")) {
169          String[] list = value.substring(8).replace("$", "").split("\\|");
170          for (String n : list) {
171            addNamedExtension(parent, name, "value-choice", "string", n);
172          }
173        } else {
174          System.out.println("not handled yet: "+value);
175        }
176      }
177    } else {
178    }
179    
180  }
181}