001package org.hl7.fhir.convertors.misc;
002
003import java.io.File;
004import java.io.FileInputStream;
005import java.io.FileNotFoundException;
006import java.io.IOException;
007import java.util.ArrayList;
008import java.util.HashMap;
009import java.util.List;
010import java.util.Map;
011import java.util.Map.Entry;
012
013import javax.naming.ldap.StartTlsRequest;
014import javax.xml.parsers.ParserConfigurationException;
015
016import org.hl7.fhir.exceptions.FHIRFormatError;
017import org.hl7.fhir.utilities.Utilities;
018import org.hl7.fhir.utilities.json.JsonTrackingParser;
019import org.xml.sax.SAXException;
020
021import com.google.gson.JsonArray;
022import com.google.gson.JsonElement;
023import com.google.gson.JsonObject;
024
025public class XVerPackegeFixer {
026  
027  private static final String R5_FOLDER = "C:\\work\\org.hl7.fhir\\packages\\hl7.fhir.rX\\hl7.fhir.r5.core\\package";
028  private static final String R4_FOLDER = "C:\\work\\org.hl7.fhir\\packages\\hl7.fhir.rX\\hl7.fhir.r4.core\\package";
029  private static final String R3_FOLDER = "C:\\work\\org.hl7.fhir\\packages\\hl7.fhir.rX\\hl7.fhir.r3.core\\package";
030  private static final String R2B_FOLDER = "C:\\work\\org.hl7.fhir\\packages\\hl7.fhir.rX\\hl7.fhir.r2b.core\\package";
031  private static final String R2_FOLDER = "C:\\work\\org.hl7.fhir\\packages\\hl7.fhir.rX\\hl7.fhir.r2.core\\package";
032  private static int mod;
033  
034  private static Map<String, org.hl7.fhir.r5.model.StructureDefinition> map5 = new HashMap<>();
035  private static Map<String, org.hl7.fhir.r4.model.StructureDefinition> map4 = new HashMap<>();
036  private static Map<String, org.hl7.fhir.dstu3.model.StructureDefinition> map3 = new HashMap<>();
037  private static Map<String, org.hl7.fhir.dstu2.model.StructureDefinition> map2 = new HashMap<>();
038  private static Map<String, org.hl7.fhir.dstu2016may.model.StructureDefinition> map2b = new HashMap<>();
039
040  public static void main(String[] args) throws FileNotFoundException, ParserConfigurationException, SAXException, IOException {
041    mod = 0;
042    for (File f : new File(args[0]).listFiles()) {
043      if (f.getName().startsWith("xver-")) {
044        JsonObject j = JsonTrackingParser.parseJson(f);
045        fixUp(j, f.getName());
046        JsonTrackingParser.write(j, f, true);
047      }
048    }
049    System.out.println("all done: "+mod+" modifiers");
050  }
051
052  private static void fixUp(JsonObject j, String name) throws FHIRFormatError, FileNotFoundException, IOException {
053    name = name.replace(".json",  "");
054    System.out.println("Process "+name);
055    String version = name.substring(name.lastIndexOf("-")+1);
056    int i = 0;
057    for (Entry<String, JsonElement> e : j.entrySet()) {
058      if (i == 50) {
059        i = 0;
060        System.out.print(".");
061      }
062      i++;
063      String n = e.getKey();
064      JsonObject o = ((JsonObject) e.getValue());
065      boolean ok = (o.has("types") && o.getAsJsonArray("types").size() > 0) || (o.has("elements") && o.getAsJsonArray("elements").size() > 0);
066      if (!ok) {
067        List<String> types = new ArrayList<>(); 
068        List<String> elements = new ArrayList<>();
069        getElementInfo(version, n, types, elements);
070        if (elements.size() > 0) {
071          JsonArray arr = o.getAsJsonArray("elements");
072          if (arr == null) {
073            arr = new JsonArray();
074            o.add("elements", arr);
075          }
076          for (String s : types) {
077            arr.add(s);
078          }
079        } else if (types.size() > 0) {
080          JsonArray arr = o.getAsJsonArray("types");
081          if (arr == null) {
082            arr = new JsonArray();
083            o.add("types", arr);
084          }
085          for (String s : types) {
086            arr.add(s);
087          }
088        }
089      }
090    }    
091    System.out.println("done");
092  }
093
094  private static boolean getElementInfo(String version, String n, List<String> types, List<String> elements) throws FHIRFormatError, FileNotFoundException, IOException {
095    if ("contained".equals(n.substring(n.indexOf(".")+1))) {
096      return false;
097    }
098    switch (version) {
099    case "4.6": return getElementInfoR5(n, types, elements);
100    case "4.0": return getElementInfoR4(n, types, elements);
101    case "3.0": return getElementInfoR3(n, types, elements);
102    case "1.4": return getElementInfoR2B(n, types, elements);
103    case "1.0": return getElementInfoR2(n, types, elements);
104    }
105    return false;
106  }
107
108  private static Object tail(String value) {
109    return value.contains("/") ? value.substring(value.lastIndexOf("/")+1) : value;
110  }
111
112  private static boolean getElementInfoR5(String n, List<String> types, List<String> elements) throws FHIRFormatError, FileNotFoundException, IOException {    
113    String tn = n.substring(0, n.indexOf("."));
114    org.hl7.fhir.r5.model.StructureDefinition sd = null;
115    if (map5.containsKey(tn)) {
116      sd = map5.get(tn);
117    } else {
118      sd = (org.hl7.fhir.r5.model.StructureDefinition) new org.hl7.fhir.r5.formats.JsonParser().parse(new FileInputStream(Utilities.path(R5_FOLDER, "StructureDefinition-"+tn+".json")));
119      map5.put(tn, sd);
120    }
121    for (org.hl7.fhir.r5.model.ElementDefinition ed : sd.getSnapshot().getElement()) {
122      if (ed.getPath().equals(n)) {
123        List<org.hl7.fhir.r5.model.ElementDefinition> children = listChildrenR5(sd.getSnapshot().getElement(), ed);
124        if (children.size() > 0) {
125          for (org.hl7.fhir.r5.model.ElementDefinition c : children) {
126            String en = c.getPath().substring(ed.getPath().length()+1);
127            elements.add(en);
128          }
129        } else {
130          for (org.hl7.fhir.r5.model.ElementDefinition.TypeRefComponent t : ed.getType()) {
131            if (t.hasTargetProfile()) {
132              StringBuilder b = new StringBuilder();
133              b.append(t.getWorkingCode());
134              b.append("(");
135              boolean first = true;
136              for (org.hl7.fhir.r5.model.CanonicalType u : t.getTargetProfile()) {
137                if (first) first = false; else b.append("|");
138                b.append(tail(u.getValue()));
139              }
140              b.append(")");
141              types.add(b.toString());
142            } else {
143              types.add(t.getWorkingCode());
144            }
145          }
146        }
147      }
148    }
149    return false;
150  }
151
152
153  private static List<org.hl7.fhir.r5.model.ElementDefinition> listChildrenR5(List<org.hl7.fhir.r5.model.ElementDefinition> list, org.hl7.fhir.r5.model.ElementDefinition ed) {
154    List<org.hl7.fhir.r5.model.ElementDefinition> res = new ArrayList<>();
155    for (org.hl7.fhir.r5.model.ElementDefinition t : list) {
156      String p = t.getPath();
157      if (p.startsWith(ed.getPath()+".")) {
158        p = p.substring(ed.getPath().length()+1);
159        if (!p.contains(".")) {
160          res.add(t);
161        }
162      }
163    }
164    return res;
165  }
166  
167  private static boolean getElementInfoR4(String n, List<String> types, List<String> elements) throws FHIRFormatError, FileNotFoundException, IOException {    
168    String tn = n.substring(0, n.indexOf("."));
169    org.hl7.fhir.r4.model.StructureDefinition sd = null;
170    if (map4.containsKey(tn)) {
171      sd = map4.get(tn);
172    } else {
173      sd = (org.hl7.fhir.r4.model.StructureDefinition) new org.hl7.fhir.r4.formats.JsonParser().parse(new FileInputStream(Utilities.path(R4_FOLDER, "StructureDefinition-"+tn+".json")));
174      map4.put(tn, sd);
175    }
176    for (org.hl7.fhir.r4.model.ElementDefinition ed : sd.getSnapshot().getElement()) {
177      if (ed.getPath().equals(n)) {
178        List<org.hl7.fhir.r4.model.ElementDefinition> children = listChildrenR4(sd.getSnapshot().getElement(), ed);
179        if (children.size() > 0) {
180          for (org.hl7.fhir.r4.model.ElementDefinition c : children) {
181            String en = c.getPath().substring(ed.getPath().length()+1);
182            elements.add(en);
183          }
184        } else {
185          for (org.hl7.fhir.r4.model.ElementDefinition.TypeRefComponent t : ed.getType()) {
186            if (t.hasTargetProfile()) {
187              StringBuilder b = new StringBuilder();
188              b.append(t.getWorkingCode());
189              b.append("(");
190              boolean first = true;
191              for (org.hl7.fhir.r4.model.CanonicalType u : t.getTargetProfile()) {
192                if (first) first = false; else b.append("|");
193                b.append(tail(u.getValue()));
194              }
195              b.append(")");
196              types.add(b.toString());
197            } else {
198              types.add(t.getWorkingCode());
199            }
200          }
201        }
202      }
203    }
204    return false;
205  }
206
207
208  private static List<org.hl7.fhir.r4.model.ElementDefinition> listChildrenR4(List<org.hl7.fhir.r4.model.ElementDefinition> list, org.hl7.fhir.r4.model.ElementDefinition ed) {
209    List<org.hl7.fhir.r4.model.ElementDefinition> res = new ArrayList<>();
210    for (org.hl7.fhir.r4.model.ElementDefinition t : list) {
211      String p = t.getPath();
212      if (p.startsWith(ed.getPath()+".")) {
213        p = p.substring(ed.getPath().length()+1);
214        if (!p.contains(".")) {
215          res.add(t);
216        }
217      }
218    }
219    return res;
220  }
221 
222
223  private static boolean getElementInfoR3(String n, List<String> types, List<String> elements) throws FHIRFormatError, FileNotFoundException, IOException {    
224    String tn = n.substring(0, n.indexOf("."));
225    org.hl7.fhir.dstu3.model.StructureDefinition sd = null;
226    if (map3.containsKey(tn)) {
227      sd = map3.get(tn);
228    } else {
229      sd = (org.hl7.fhir.dstu3.model.StructureDefinition) new org.hl7.fhir.dstu3.formats.JsonParser().parse(new FileInputStream(Utilities.path(R3_FOLDER, "StructureDefinition-"+tn+".json")));
230      map3.put(tn, sd);
231    }
232    for (org.hl7.fhir.dstu3.model.ElementDefinition ed : sd.getSnapshot().getElement()) {
233      if (ed.getPath().equals(n)) {
234        List<org.hl7.fhir.dstu3.model.ElementDefinition> children = listChildrenR3(sd.getSnapshot().getElement(), ed);
235        if (children.size() > 0) {
236          for (org.hl7.fhir.dstu3.model.ElementDefinition c : children) {
237            String en = c.getPath().substring(ed.getPath().length()+1);
238            elements.add(en);
239          }
240        } else {
241          for (org.hl7.fhir.dstu3.model.ElementDefinition.TypeRefComponent t : ed.getType()) {
242            if (t.hasTargetProfile()) {
243              StringBuilder b = new StringBuilder();
244              b.append(t.getCode());
245              b.append("(");
246              b.append(tail(t.getTargetProfile()));
247              b.append(")");
248              types.add(b.toString());
249            } else {
250              types.add(t.getCode());
251            }
252          }
253        }
254      }
255    }
256    return false;
257  }
258
259
260  private static List<org.hl7.fhir.dstu3.model.ElementDefinition> listChildrenR3(List<org.hl7.fhir.dstu3.model.ElementDefinition> list, org.hl7.fhir.dstu3.model.ElementDefinition ed) {
261    List<org.hl7.fhir.dstu3.model.ElementDefinition> res = new ArrayList<>();
262    for (org.hl7.fhir.dstu3.model.ElementDefinition t : list) {
263      String p = t.getPath();
264      if (p.startsWith(ed.getPath()+".")) {
265        p = p.substring(ed.getPath().length()+1);
266        if (!p.contains(".")) {
267          res.add(t);
268        }
269      }
270    }
271    return res;
272  }
273  
274
275  private static boolean getElementInfoR2(String n, List<String> types, List<String> elements) throws FHIRFormatError, FileNotFoundException, IOException {    
276    String tn = n.substring(0, n.indexOf("."));
277    org.hl7.fhir.dstu2.model.StructureDefinition sd = null;
278    if (map2.containsKey(tn)) {
279      sd = map2.get(tn);
280    } else {
281      sd = (org.hl7.fhir.dstu2.model.StructureDefinition) new org.hl7.fhir.dstu2.formats.JsonParser().parse(new FileInputStream(Utilities.path(R2_FOLDER, "StructureDefinition-"+tn+".json")));
282      map2.put(tn, sd);
283    }
284    for (org.hl7.fhir.dstu2.model.ElementDefinition ed : sd.getSnapshot().getElement()) {
285      if (ed.getPath().equals(n)) {
286        List<org.hl7.fhir.dstu2.model.ElementDefinition> children = listChildrenR2(sd.getSnapshot().getElement(), ed);
287        if (children.size() > 0) {
288          for (org.hl7.fhir.dstu2.model.ElementDefinition c : children) {
289            String en = c.getPath().substring(ed.getPath().length()+1);
290            elements.add(en);
291          }
292        } else {
293          for (org.hl7.fhir.dstu2.model.ElementDefinition.TypeRefComponent t : ed.getType()) {
294            if (t.hasProfile()) {
295              StringBuilder b = new StringBuilder();
296              b.append(t.getCode());
297              b.append("(");
298              boolean first = true;
299              for (org.hl7.fhir.dstu2.model.UriType u : t.getProfile()) {
300                if (first) first = false; else b.append("|");
301                b.append(tail(u.getValue()));
302              }
303              b.append(")");
304              types.add(b.toString());
305            } else {
306              types.add(t.getCode());
307            }
308          }
309        }
310      }
311    }
312    return false;
313  }
314
315
316  private static List<org.hl7.fhir.dstu2.model.ElementDefinition> listChildrenR2(List<org.hl7.fhir.dstu2.model.ElementDefinition> list, org.hl7.fhir.dstu2.model.ElementDefinition ed) {
317    List<org.hl7.fhir.dstu2.model.ElementDefinition> res = new ArrayList<>();
318    for (org.hl7.fhir.dstu2.model.ElementDefinition t : list) {
319      String p = t.getPath();
320      if (p.startsWith(ed.getPath()+".")) {
321        p = p.substring(ed.getPath().length()+1);
322        if (!p.contains(".")) {
323          res.add(t);
324        }
325      }
326    }
327    return res;
328  }
329  
330
331  private static boolean getElementInfoR2B(String n, List<String> types, List<String> elements) throws FHIRFormatError, FileNotFoundException, IOException {    
332    String tn = n.substring(0, n.indexOf("."));
333    org.hl7.fhir.dstu2016may.model.StructureDefinition sd = null;
334    if (map2b.containsKey(tn)) {
335      sd = map2b.get(tn);
336    } else {
337      sd = (org.hl7.fhir.dstu2016may.model.StructureDefinition) new org.hl7.fhir.dstu2016may.formats.JsonParser().parse(new FileInputStream(Utilities.path(R2B_FOLDER, "StructureDefinition-"+tn+".json")));
338      map2b.put(tn, sd);
339    }
340    for (org.hl7.fhir.dstu2016may.model.ElementDefinition ed : sd.getSnapshot().getElement()) {
341      if (ed.getPath().equals(n)) {
342        List<org.hl7.fhir.dstu2016may.model.ElementDefinition> children = listChildrenR2B(sd.getSnapshot().getElement(), ed);
343        if (children.size() > 0) {
344          for (org.hl7.fhir.dstu2016may.model.ElementDefinition c : children) {
345            String en = c.getPath().substring(ed.getPath().length()+1);
346            elements.add(en);
347          }
348        } else {
349          for (org.hl7.fhir.dstu2016may.model.ElementDefinition.TypeRefComponent t : ed.getType()) {
350            if (t.hasProfile()) {
351              StringBuilder b = new StringBuilder();
352              b.append(t.getCode());
353              b.append("(");
354              boolean first = true;
355              for (org.hl7.fhir.dstu2016may.model.UriType u : t.getProfile()) {
356                if (first) first = false; else b.append("|");
357                b.append(tail(u.getValue()));
358              }              
359              b.append(")");
360              types.add(b.toString());
361            } else {
362              types.add(t.getCode());
363            }
364          }
365        }
366      }
367    }
368    return false;
369  }
370
371
372  private static List<org.hl7.fhir.dstu2016may.model.ElementDefinition> listChildrenR2B(List<org.hl7.fhir.dstu2016may.model.ElementDefinition> list, org.hl7.fhir.dstu2016may.model.ElementDefinition ed) {
373    List<org.hl7.fhir.dstu2016may.model.ElementDefinition> res = new ArrayList<>();
374    for (org.hl7.fhir.dstu2016may.model.ElementDefinition t : list) {
375      String p = t.getPath();
376      if (p.startsWith(ed.getPath()+".")) {
377        p = p.substring(ed.getPath().length()+1);
378        if (!p.contains(".")) {
379          res.add(t);
380        }
381      }
382    }
383    return res;
384  }
385  
386
387}