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}