
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.HashSet; 010import java.util.List; 011import java.util.Map; 012import java.util.Map.Entry; 013import java.util.Set; 014 015import javax.xml.parsers.ParserConfigurationException; 016 017import org.hl7.fhir.dstu2.model.ElementDefinition; 018import org.hl7.fhir.dstu2.model.StructureDefinition; 019import org.hl7.fhir.dstu2.model.StructureDefinition.StructureDefinitionSnapshotComponent; 020import org.hl7.fhir.exceptions.FHIRFormatError; 021import org.hl7.fhir.utilities.Utilities; 022import org.hl7.fhir.utilities.json.JsonTrackingParser; 023import org.xml.sax.SAXException; 024 025import com.google.gson.JsonArray; 026import com.google.gson.JsonElement; 027import com.google.gson.JsonObject; 028 029public class XVerPackegeFixer { 030 031 public static class References { 032 private boolean modifier; 033 private boolean inherited; 034 035 public boolean getModifier() { 036 return modifier; 037 } 038 039 public void setModifier(boolean value) { 040 this.modifier = value; 041 } 042 043 public boolean getInherited() { 044 return inherited; 045 } 046 047 public void setInherited(boolean inherited) { 048 this.inherited = inherited; 049 } 050 051 } 052 053 054 private static final String R5_FOLDER = "/Users/grahamegrieve/work/packages/hl7.fhir.rX/hl7.fhir.r5.core/package"; 055 private static final String R4_FOLDER = "/Users/grahamegrieve/work/packages/hl7.fhir.rX/hl7.fhir.r4.core/package"; 056 private static final String R3_FOLDER = "/Users/grahamegrieve/work/packages/hl7.fhir.rX/hl7.fhir.r3.core/package"; 057 private static final String R2B_FOLDER = "/Users/grahamegrieve/work/packages/hl7.fhir.rX/hl7.fhir.r2b.core/package"; 058 private static final String R2_FOLDER = "/Users/grahamegrieve/work/packages/hl7.fhir.rX/hl7.fhir.r2.core/package"; 059 private static int modCount; 060 061 private static Map<String, org.hl7.fhir.r5.model.StructureDefinition> map5 = new HashMap<>(); 062 private static Map<String, org.hl7.fhir.r4.model.StructureDefinition> map4 = new HashMap<>(); 063 private static Map<String, org.hl7.fhir.dstu3.model.StructureDefinition> map3 = new HashMap<>(); 064 private static Map<String, org.hl7.fhir.dstu2.model.StructureDefinition> map2 = new HashMap<>(); 065 private static Map<String, org.hl7.fhir.dstu2016may.model.StructureDefinition> map2b = new HashMap<>(); 066 067 public static void main(String[] args) throws FileNotFoundException, ParserConfigurationException, SAXException, IOException { 068 modCount = 0; 069 for (File f : new File(args[0]).listFiles()) { 070 if (f.getName().startsWith("xver-") && f.getName().contains("1.0")) { 071 JsonObject j = JsonTrackingParser.parseJson(f); 072 fixUp(j, f.getName()); 073 JsonTrackingParser.write(j, f, true); 074 } 075 } 076 System.out.println("all done: "+modCount+" modifiers"); 077 } 078 079 private static void fixUp(JsonObject j, String name) throws FHIRFormatError, FileNotFoundException, IOException { 080 name = name.replace(".json", ""); 081 System.out.println("Process "+name); 082 String version = name.substring(name.lastIndexOf("-")+1); 083 Set<String> pr = new HashSet<>(); 084 085 int i = 0; 086 for (Entry<String, JsonElement> e : j.entrySet()) { 087 if (i == 50) { 088 i = 0; 089 System.out.print("."); 090 } 091 i++; 092 String n = e.getKey(); 093 JsonObject o = ((JsonObject) e.getValue()); 094 // boolean ok = (o.has("types") && o.getAsJsonArray("types").size() > 0) || (o.has("elements") && o.getAsJsonArray("elements").size() > 0); 095// if (!ok) { 096 if (o.has("types")) { 097 o.remove("types"); 098 } 099 if (o.has("elements")) { 100 o.remove("elements"); 101 } 102 if (o.has("modifier")) { 103 o.remove("modifier"); 104 } 105 List<String> types = new ArrayList<>(); 106 List<String> elements = new ArrayList<>(); 107 References mod = new References(); 108 getElementInfo(version, n, types, elements, mod); 109 if (mod.getInherited()) { 110 pr.add(n); 111 } 112 if (elements.size() > 0) { 113 JsonArray arr = o.getAsJsonArray("elements"); 114 if (arr == null) { 115 arr = new JsonArray(); 116 o.add("elements", arr); 117 } 118 for (String s : elements) { 119 arr.add(s); 120 } 121 } else if (types.size() > 0) { 122 JsonArray arr = o.getAsJsonArray("types"); 123 if (arr == null) { 124 arr = new JsonArray(); 125 o.add("types", arr); 126 } 127 for (String s : types) { 128 arr.add(s); 129 } 130 } 131 if (mod.getModifier()) { 132 o.addProperty("modifier", true); 133 modCount++; 134 } 135// } 136 } 137 for (String s : pr) { 138 j.remove(s); 139 } 140 System.out.println("done"); 141 } 142 143 private static boolean getElementInfo(String version, String n, List<String> types, List<String> elements, References mod) throws FHIRFormatError, FileNotFoundException, IOException { 144// if ("contained".equals(n.substring(n.indexOf(".")+1))) { 145// return false; 146// } 147 switch (version) { 148 case "4.6": return getElementInfoR5(n, types, elements, mod); 149 case "4.0": return getElementInfoR4(n, types, elements, mod); 150 case "3.0": return getElementInfoR3(n, types, elements, mod); 151 case "1.4": return getElementInfoR2B(n, types, elements, mod); 152 case "1.0": return getElementInfoR2(n, types, elements, mod); 153 } 154 return false; 155 } 156 157 private static String tail(String value) { 158 return value.contains("/") ? value.substring(value.lastIndexOf("/")+1) : value; 159 } 160 161 private static boolean getElementInfoR5(String n, List<String> types, List<String> elements, References mod) throws FHIRFormatError, FileNotFoundException, IOException { 162 String tn = n.substring(0, n.indexOf(".")); 163 org.hl7.fhir.r5.model.StructureDefinition sd = null; 164 if (map5.containsKey(tn)) { 165 sd = map5.get(tn); 166 } else { 167 sd = (org.hl7.fhir.r5.model.StructureDefinition) new org.hl7.fhir.r5.formats.JsonParser().parse(new FileInputStream(Utilities.path(R5_FOLDER, "StructureDefinition-"+tn+".json"))); 168 map5.put(tn, sd); 169 } 170 for (org.hl7.fhir.r5.model.ElementDefinition ed : sd.getSnapshot().getElement()) { 171 if (ed.getPath().equals(n)) { 172 mod.setModifier(ed.getIsModifier()); 173 List<org.hl7.fhir.r5.model.ElementDefinition> children = listChildrenR5(sd.getSnapshot().getElement(), ed); 174 if (children.size() > 0) { 175 for (org.hl7.fhir.r5.model.ElementDefinition c : children) { 176 String en = c.getPath().substring(ed.getPath().length()+1); 177 elements.add(en); 178 } 179 } else { 180 for (org.hl7.fhir.r5.model.ElementDefinition.TypeRefComponent t : ed.getType()) { 181 if (t.hasTargetProfile()) { 182 StringBuilder b = new StringBuilder(); 183 b.append(t.getWorkingCode()); 184 b.append("("); 185 boolean first = true; 186 for (org.hl7.fhir.r5.model.CanonicalType u : t.getTargetProfile()) { 187 if (first) first = false; else b.append("|"); 188 b.append(tail(u.getValue())); 189 } 190 b.append(")"); 191 types.add(b.toString()); 192 } else { 193 types.add(t.getWorkingCode()); 194 } 195 } 196 } 197 } 198 } 199 return false; 200 } 201 202 203 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) { 204 List<org.hl7.fhir.r5.model.ElementDefinition> res = new ArrayList<>(); 205 for (org.hl7.fhir.r5.model.ElementDefinition t : list) { 206 String p = t.getPath(); 207 if (p.startsWith(ed.getPath()+".")) { 208 p = p.substring(ed.getPath().length()+1); 209 if (!p.contains(".")) { 210 res.add(t); 211 } 212 } 213 } 214 return res; 215 } 216 217 private static boolean getElementInfoR4(String n, List<String> types, List<String> elements, References mod) throws FHIRFormatError, FileNotFoundException, IOException { 218 String tn = n.substring(0, n.indexOf(".")); 219 org.hl7.fhir.r4.model.StructureDefinition sd = null; 220 if (map4.containsKey(tn)) { 221 sd = map4.get(tn); 222 } else { 223 sd = (org.hl7.fhir.r4.model.StructureDefinition) new org.hl7.fhir.r4.formats.JsonParser().parse(new FileInputStream(Utilities.path(R4_FOLDER, "StructureDefinition-"+tn+".json"))); 224 map4.put(tn, sd); 225 } 226 for (org.hl7.fhir.r4.model.ElementDefinition ed : sd.getSnapshot().getElement()) { 227 if (ed.getPath().equals(n)) { 228 mod.setModifier(ed.getIsModifier()); 229 List<org.hl7.fhir.r4.model.ElementDefinition> children = listChildrenR4(sd.getSnapshot().getElement(), ed); 230 if (children.size() > 0) { 231 for (org.hl7.fhir.r4.model.ElementDefinition c : children) { 232 String en = c.getPath().substring(ed.getPath().length()+1); 233 elements.add(en); 234 } 235 } else { 236 for (org.hl7.fhir.r4.model.ElementDefinition.TypeRefComponent t : ed.getType()) { 237 if (t.hasTargetProfile()) { 238 StringBuilder b = new StringBuilder(); 239 b.append(t.getWorkingCode()); 240 b.append("("); 241 boolean first = true; 242 for (org.hl7.fhir.r4.model.CanonicalType u : t.getTargetProfile()) { 243 if (first) first = false; else b.append("|"); 244 b.append(tail(u.getValue())); 245 } 246 b.append(")"); 247 types.add(b.toString()); 248 } else { 249 types.add(t.getWorkingCode()); 250 } 251 } 252 } 253 } 254 } 255 return false; 256 } 257 258 259 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) { 260 List<org.hl7.fhir.r4.model.ElementDefinition> res = new ArrayList<>(); 261 for (org.hl7.fhir.r4.model.ElementDefinition t : list) { 262 String p = t.getPath(); 263 if (p.startsWith(ed.getPath()+".")) { 264 p = p.substring(ed.getPath().length()+1); 265 if (!p.contains(".")) { 266 res.add(t); 267 } 268 } 269 } 270 return res; 271 } 272 273 274 private static boolean getElementInfoR3(String n, List<String> types, List<String> elements, References mod) throws FHIRFormatError, FileNotFoundException, IOException { 275 String tn = n.substring(0, n.indexOf(".")); 276 org.hl7.fhir.dstu3.model.StructureDefinition sd = null; 277 if (map3.containsKey(tn)) { 278 sd = map3.get(tn); 279 } else { 280 sd = (org.hl7.fhir.dstu3.model.StructureDefinition) new org.hl7.fhir.dstu3.formats.JsonParser().parse(new FileInputStream(Utilities.path(R3_FOLDER, "StructureDefinition-"+tn+".json"))); 281 map3.put(tn, sd); 282 } 283 for (org.hl7.fhir.dstu3.model.ElementDefinition ed : sd.getSnapshot().getElement()) { 284 if (ed.getPath().equals(n)) { 285 mod.setModifier(ed.getIsModifier()); 286 List<org.hl7.fhir.dstu3.model.ElementDefinition> children = listChildrenR3(sd.getSnapshot().getElement(), ed); 287 if (children.size() > 0) { 288 for (org.hl7.fhir.dstu3.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.dstu3.model.ElementDefinition.TypeRefComponent t : ed.getType()) { 294 if (t.hasTargetProfile()) { 295 StringBuilder b = new StringBuilder(); 296 b.append(t.getCode()); 297 b.append("("); 298 b.append(tail(t.getTargetProfile())); 299 b.append(")"); 300 types.add(b.toString()); 301 } else { 302 types.add(t.getCode()); 303 } 304 } 305 } 306 } 307 } 308 return false; 309 } 310 311 312 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) { 313 List<org.hl7.fhir.dstu3.model.ElementDefinition> res = new ArrayList<>(); 314 for (org.hl7.fhir.dstu3.model.ElementDefinition t : list) { 315 String p = t.getPath(); 316 if (p.startsWith(ed.getPath()+".")) { 317 p = p.substring(ed.getPath().length()+1); 318 if (!p.contains(".")) { 319 res.add(t); 320 } 321 } 322 } 323 return res; 324 } 325 326 327 private static boolean getElementInfoR2(String n, List<String> types, List<String> elements, References mod) throws FHIRFormatError, FileNotFoundException, IOException { 328 String tn = n.substring(0, n.indexOf(".")); 329 org.hl7.fhir.dstu2.model.StructureDefinition sd = null; 330 sd = loadType(tn); 331 mod.setInherited(isInherited(n, sd)); 332 for (org.hl7.fhir.dstu2.model.ElementDefinition ed : sd.getSnapshot().getElement()) { 333 if (ed.getPath().equals(n)) { 334 mod.setModifier(ed.getIsModifier()); 335 List<org.hl7.fhir.dstu2.model.ElementDefinition> children = listChildrenR2(sd.getSnapshot().getElement(), ed); 336 if (children.size() > 0) { 337 for (org.hl7.fhir.dstu2.model.ElementDefinition c : children) { 338 String en = c.getPath().substring(ed.getPath().length()+1); 339 elements.add(en); 340 } 341 } else { 342 boolean isReference = false; 343 StringBuilder r = new StringBuilder(); 344 r.append("Reference("); 345 for (org.hl7.fhir.dstu2.model.ElementDefinition.TypeRefComponent t : ed.getType()) { 346 if (t.hasProfile()) { 347 if ("Reference".equals(t.getCode())) { 348 for (org.hl7.fhir.dstu2.model.UriType u : t.getProfile()) { 349 if (isReference) 350 r.append("|"); 351 r.append(tail(u.getValue())); 352 isReference = true; 353 } 354 } else { 355 StringBuilder b = new StringBuilder(); 356 b.append(t.getCode()); 357 b.append("("); 358 boolean first = true; 359 for (org.hl7.fhir.dstu2.model.UriType u : t.getProfile()) { 360 if (first) first = false; else b.append("|"); 361 b.append(tail(u.getValue())); 362 } 363 b.append(")"); 364 types.add(b.toString()); 365 } 366 } else { 367 types.add(t.getCode()); 368 } 369 } 370 if (isReference) { 371 r.append(")"); 372 types.add(r.toString()); 373 } 374 } 375 } 376 } 377 return false; 378 } 379 380 private static org.hl7.fhir.dstu2.model.StructureDefinition loadType(String tn) 381 throws IOException, FileNotFoundException { 382 org.hl7.fhir.dstu2.model.StructureDefinition sd; 383 if (map2.containsKey(tn)) { 384 sd = map2.get(tn); 385 } else { 386 sd = (org.hl7.fhir.dstu2.model.StructureDefinition) new org.hl7.fhir.dstu2.formats.JsonParser().parse(new FileInputStream(Utilities.path(R2_FOLDER, "StructureDefinition-"+tn+".json"))); 387 map2.put(tn, sd); 388 } 389 return sd; 390 } 391 392 393 private static boolean isInherited(String n, StructureDefinition sd) throws FileNotFoundException, IOException { 394 String tail = n.substring(n.indexOf(".")+1); 395 while (sd != null) { 396 sd = sd.hasBase() ? loadType(tail(sd.getBase())) : null; 397 if (sd != null && hasPath(sd.getSnapshot(), sd.getName()+"."+tail)) { 398 return true; 399 } 400 } 401 return false; 402 } 403 404 private static boolean hasPath(StructureDefinitionSnapshotComponent snapshot, String path) { 405 for (ElementDefinition ed : snapshot.getElement()) { 406 if (ed.getPath().equals(path)) { 407 return true; 408 } 409 } 410 return false; 411 } 412 413 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) { 414 List<org.hl7.fhir.dstu2.model.ElementDefinition> res = new ArrayList<>(); 415 for (org.hl7.fhir.dstu2.model.ElementDefinition t : list) { 416 String p = t.getPath(); 417 if (p.startsWith(ed.getPath()+".")) { 418 p = p.substring(ed.getPath().length()+1); 419 if (!p.contains(".")) { 420 res.add(t); 421 } 422 } 423 } 424 return res; 425 } 426 427 428 private static boolean getElementInfoR2B(String n, List<String> types, List<String> elements, References mod) throws FHIRFormatError, FileNotFoundException, IOException { 429 String tn = n.substring(0, n.indexOf(".")); 430 org.hl7.fhir.dstu2016may.model.StructureDefinition sd = null; 431 if (map2b.containsKey(tn)) { 432 sd = map2b.get(tn); 433 } else { 434 sd = (org.hl7.fhir.dstu2016may.model.StructureDefinition) new org.hl7.fhir.dstu2016may.formats.JsonParser().parse(new FileInputStream(Utilities.path(R2B_FOLDER, "StructureDefinition-"+tn+".json"))); 435 map2b.put(tn, sd); 436 } 437 for (org.hl7.fhir.dstu2016may.model.ElementDefinition ed : sd.getSnapshot().getElement()) { 438 if (ed.getPath().equals(n)) { 439 mod.setModifier(ed.getIsModifier()); 440 List<org.hl7.fhir.dstu2016may.model.ElementDefinition> children = listChildrenR2B(sd.getSnapshot().getElement(), ed); 441 if (children.size() > 0) { 442 for (org.hl7.fhir.dstu2016may.model.ElementDefinition c : children) { 443 String en = c.getPath().substring(ed.getPath().length()+1); 444 elements.add(en); 445 } 446 } else { 447 for (org.hl7.fhir.dstu2016may.model.ElementDefinition.TypeRefComponent t : ed.getType()) { 448 if (t.hasProfile()) { 449 StringBuilder b = new StringBuilder(); 450 b.append(t.getCode()); 451 b.append("("); 452 boolean first = true; 453 for (org.hl7.fhir.dstu2016may.model.UriType u : t.getProfile()) { 454 if (first) first = false; else b.append("|"); 455 b.append(tail(u.getValue())); 456 } 457 b.append(")"); 458 types.add(b.toString()); 459 } else { 460 types.add(t.getCode()); 461 } 462 } 463 } 464 } 465 } 466 return false; 467 } 468 469 470 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) { 471 List<org.hl7.fhir.dstu2016may.model.ElementDefinition> res = new ArrayList<>(); 472 for (org.hl7.fhir.dstu2016may.model.ElementDefinition t : list) { 473 String p = t.getPath(); 474 if (p.startsWith(ed.getPath()+".")) { 475 p = p.substring(ed.getPath().length()+1); 476 if (!p.contains(".")) { 477 res.add(t); 478 } 479 } 480 } 481 return res; 482 } 483 484 485}