diff --git a/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/misc/NpmPackageVersionConverter.java b/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/misc/NpmPackageVersionConverter.java index 251e7461b..2c9a4f102 100644 --- a/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/misc/NpmPackageVersionConverter.java +++ b/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/misc/NpmPackageVersionConverter.java @@ -51,16 +51,19 @@ public class NpmPackageVersionConverter { private final List errors = new ArrayList<>(); private String currentVersion; - public NpmPackageVersionConverter(String source, String dest, String version) { + private String packageId; + + public NpmPackageVersionConverter(String source, String dest, String version, String packageId) { super(); this.source = source; this.dest = dest; this.vCode = version; + this.packageId = packageId; this.version = VersionUtilities.versionFromCode(version); } public static void main(String[] args) throws IOException { - NpmPackageVersionConverter self = new NpmPackageVersionConverter(args[0], args[1], args[2]); + NpmPackageVersionConverter self = new NpmPackageVersionConverter(args[0], args[1], args[2], args[3]); self.execute(); System.out.println("Finished"); for (String s : self.errors) { @@ -181,6 +184,7 @@ public class NpmPackageVersionConverter { JsonObject json = JsonParser.parseObject(cnt); currentVersion = json.getJsonArray("fhirVersions").get(0).asString(); String name = json.asString("name"); + assert(packageId.equals(name + "." + vCode)); json.remove("name"); json.add("name", name + "." + vCode); json.remove("fhirVersions"); @@ -197,6 +201,7 @@ public class NpmPackageVersionConverter { private byte[] convertSpec(byte[] cnt) throws IOException { JsonObject json = JsonParser.parseObject(cnt); json.set("ig-version", version); + json.set("npm-name", packageId); return JsonParser.composeBytes(json, true); } @@ -307,6 +312,7 @@ public class NpmPackageVersionConverter { org.hl7.fhir.r4.model.ImplementationGuide ig = (org.hl7.fhir.r4.model.ImplementationGuide) res; ig.getFhirVersion().clear(); ig.getFhirVersion().add(new org.hl7.fhir.r4.model.Enumeration<>(new org.hl7.fhir.r4.model.Enumerations.FHIRVersionEnumFactory(), version)); + ig.setPackageId(packageId); } } @@ -315,6 +321,7 @@ public class NpmPackageVersionConverter { ImplementationGuide ig = (ImplementationGuide) res; ig.getFhirVersion().clear(); ig.getFhirVersion().add(new Enumeration<>(new FHIRVersionEnumFactory(), version)); + ig.setPackageId(packageId); } } diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/conformance/ProfileUtilities.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/conformance/ProfileUtilities.java index 3ca7780a5..eb600cbbe 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/conformance/ProfileUtilities.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/conformance/ProfileUtilities.java @@ -5140,18 +5140,28 @@ public class ProfileUtilities extends TranslatingUtilities { } // generate a CSV representation of the structure definition - public void generateCsvs(OutputStream dest, StructureDefinition structure, boolean asXml) throws IOException, DefinitionException, Exception { + public void generateCsv(OutputStream dest, StructureDefinition structure, boolean asXml) throws IOException, DefinitionException, Exception { if (!structure.hasSnapshot()) throw new DefinitionException(context.formatMessage(I18nConstants.NEEDS_A_SNAPSHOT)); CSVWriter csv = new CSVWriter(dest, structure, asXml); for (ElementDefinition child : structure.getSnapshot().getElement()) { - csv.processElement(child); + csv.processElement(null, child); } csv.dump(); } + // generate a CSV representation of the structure definition + public void addToCSV(CSVWriter csv, StructureDefinition structure) throws IOException, DefinitionException, Exception { + if (!structure.hasSnapshot()) + throw new DefinitionException(context.formatMessage(I18nConstants.NEEDS_A_SNAPSHOT)); + + for (ElementDefinition child : structure.getSnapshot().getElement()) { + csv.processElement(structure, child); + } + } + private class Slicer extends ElementDefinitionSlicingComponent { String criteria = ""; diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/spreadsheets/CanonicalSpreadsheetGenerator.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/spreadsheets/CanonicalSpreadsheetGenerator.java index 4a5cd4e22..4993e2f5f 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/spreadsheets/CanonicalSpreadsheetGenerator.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/spreadsheets/CanonicalSpreadsheetGenerator.java @@ -20,13 +20,16 @@ public class CanonicalSpreadsheetGenerator extends SpreadsheetGenerator { super(context); } - protected Sheet renderCanonicalResource(CanonicalResource cr) { - Sheet sheet = makeSheet("Metadata"); + protected Sheet renderCanonicalResource(CanonicalResource cr, boolean forMultiple) { + Sheet sheet = forMultiple && hasSheet("Metadata") ? getSheet("Metadata") : makeSheet("Metadata"); - Row headerRow = sheet.createRow(0); + Row headerRow = sheet.createRow(forMultiple ? sheet.getLastRowNum()+1 : 0); addCell(headerRow, 0, "Property", styles.get("header")); addCell(headerRow, 1, "Value", styles.get("header")); + if (forMultiple) { + addMetadataRow(sheet, "ID", cr.getId()); + } addMetadataRow(sheet, "URL", cr.getUrl()); for (Identifier id : cr.getIdentifier()) { addMetadataRow(sheet, "Identifier", dr.display(id)); diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/spreadsheets/CodeSystemSpreadsheetGenerator.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/spreadsheets/CodeSystemSpreadsheetGenerator.java index 9097fc8dc..235193e99 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/spreadsheets/CodeSystemSpreadsheetGenerator.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/spreadsheets/CodeSystemSpreadsheetGenerator.java @@ -42,7 +42,7 @@ public class CodeSystemSpreadsheetGenerator extends CanonicalSpreadsheetGenerato if (cs == null) { System.out.println("no code system!"); } - addCodeSystemMetadata(renderCanonicalResource(cs), cs); + addCodeSystemMetadata(renderCanonicalResource(cs, false), cs); if (cs.hasProperty()) { addProperties(cs.getProperty()); diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/spreadsheets/ConceptMapSpreadsheetGenerator.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/spreadsheets/ConceptMapSpreadsheetGenerator.java index d255fbb53..550f51aab 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/spreadsheets/ConceptMapSpreadsheetGenerator.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/spreadsheets/ConceptMapSpreadsheetGenerator.java @@ -22,7 +22,7 @@ public class ConceptMapSpreadsheetGenerator extends CanonicalSpreadsheetGenerato } public ConceptMapSpreadsheetGenerator renderConceptMap(ConceptMap cm) { - addConceptMapMetadata(renderCanonicalResource(cm), cm); + addConceptMapMetadata(renderCanonicalResource(cm, false), cm); int i = 0; for (ConceptMapGroupComponent grp : cm.getGroup()) { renderGroup(grp, i); diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/spreadsheets/SpreadsheetGenerator.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/spreadsheets/SpreadsheetGenerator.java index 49a50dc77..18a7e22cf 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/spreadsheets/SpreadsheetGenerator.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/spreadsheets/SpreadsheetGenerator.java @@ -65,7 +65,7 @@ public class SpreadsheetGenerator { protected Map styles; protected DataRenderer dr; - private List sheetNames = new ArrayList<>(); + private Map sheetNames = new HashMap<>(); public SpreadsheetGenerator(IWorkerContext context) { super(); @@ -80,20 +80,37 @@ public class SpreadsheetGenerator { outStream.close(); } + protected boolean hasSheet(String name) { + if (name.length() > MAX_SENSITIVE_SHEET_NAME_LEN - 2) { + name = name.substring(0, MAX_SENSITIVE_SHEET_NAME_LEN - 2); + } + String s = fixSheetNameChars(name); + return sheetNames.containsKey(s); + } + + protected Sheet getSheet(String name) { + if (name.length() > MAX_SENSITIVE_SHEET_NAME_LEN - 2) { + name = name.substring(0, MAX_SENSITIVE_SHEET_NAME_LEN - 2); + } + String s = fixSheetNameChars(name); + return sheetNames.get(s); + } + protected Sheet makeSheet(String name) { if (name.length() > MAX_SENSITIVE_SHEET_NAME_LEN - 2) { name = name.substring(0, MAX_SENSITIVE_SHEET_NAME_LEN - 2); } String s = fixSheetNameChars(name); - if (sheetNames.contains(s)) { + if (sheetNames.containsKey(s)) { int i = 1; do { i++; s = name+" "+Integer.toString(i); - } while (sheetNames.contains(s)); + } while (sheetNames.containsKey(s)); } - sheetNames.add(s); - return wb.createSheet(s); + Sheet res = wb.createSheet(s); + sheetNames.put(s, res); + return res; } private String fixSheetNameChars(String name) { diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/spreadsheets/StructureDefinitionSpreadsheetGenerator.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/spreadsheets/StructureDefinitionSpreadsheetGenerator.java index b7e34eca4..e1b33501c 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/spreadsheets/StructureDefinitionSpreadsheetGenerator.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/spreadsheets/StructureDefinitionSpreadsheetGenerator.java @@ -38,6 +38,7 @@ import org.apache.poi.ss.util.CellRangeAddress; import org.apache.poi.xssf.usermodel.XSSFRow; import org.apache.poi.xssf.usermodel.XSSFSheet; import org.apache.poi.xssf.usermodel.XSSFWorkbook; +import org.checkerframework.common.reflection.qual.ForName; import org.hl7.fhir.r5.formats.IParser.OutputStyle; import org.hl7.fhir.r5.context.IWorkerContext; import org.hl7.fhir.r5.context.SimpleWorkerContext; @@ -88,28 +89,34 @@ public class StructureDefinitionSpreadsheetGenerator extends CanonicalSpreadshee this.hideMustSupportFalse = hideMustSupportFalse; } - public StructureDefinitionSpreadsheetGenerator renderStructureDefinition(StructureDefinition sd) throws Exception { + public StructureDefinitionSpreadsheetGenerator renderStructureDefinition(StructureDefinition sd, boolean forMultiple) throws Exception { if (sd == null) { System.out.println("no structure!"); } if (!sd.hasSnapshot()) { throw new DefinitionException(context.formatMessage(I18nConstants.NEEDS_A_SNAPSHOT)); } - addStructureDefinitionMetadata(renderCanonicalResource(sd), sd); - Sheet sheet = makeSheet("Elements"); + addStructureDefinitionMetadata(renderCanonicalResource(sd, forMultiple), sd); + Sheet sheet = forMultiple && hasSheet("Elements") ? getSheet("Elements") : makeSheet("Elements"); - Row headerRow = sheet.createRow(0); - for (int i = 0; i < titles.length; i++) { - addCell(headerRow, i, titles[i], styles.get("header")); + if (sheet.getLastRowNum() == 0) { + Row headerRow = sheet.createRow(0); + int coffset = forMultiple ? 1 : 0; + for (int i = 0; i < titles.length; i++) { + if (forMultiple) { + addCell(headerRow, 0, "ID", styles.get("header")); + } + addCell(headerRow, i+coffset, titles[i], styles.get("header")); + } + int i = titles.length - 1; + for (StructureDefinitionMappingComponent map : sd.getMapping()) { + i++; + addCell(headerRow, i+coffset, "Mapping: " + map.getName(), styles.get("header")); + } } - int i = titles.length - 1; - for (StructureDefinitionMappingComponent map : sd.getMapping()) { - i++; - addCell(headerRow, i, "Mapping: " + map.getName(), styles.get("header")); - } for (ElementDefinition child : sd.getSnapshot().getElement()) { - processElement(sheet, sd, child); + processElement(sheet, sd, child, forMultiple); } configureSheet(sheet, sd); return this; @@ -136,9 +143,12 @@ public class StructureDefinitionSpreadsheetGenerator extends CanonicalSpreadshee } - public void processElement(Sheet sheet, StructureDefinition sd, ElementDefinition ed) throws Exception { + public void processElement(Sheet sheet, StructureDefinition sd, ElementDefinition ed, boolean forMultiple) throws Exception { Row row = sheet.createRow(sheet.getLastRowNum()+1); int i = 0; + if (forMultiple) { + addCell(row, i++, sd.getId(), styles.get("body")); + } addCell(row, i++, ed.getPath(), styles.get("body")); addCell(row, i++, ed.getSliceName()); addCell(row, i++, itemList(ed.getAlias())); diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/spreadsheets/ValueSetSpreadsheetGenerator.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/spreadsheets/ValueSetSpreadsheetGenerator.java index dec177b1a..d7227204e 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/spreadsheets/ValueSetSpreadsheetGenerator.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/spreadsheets/ValueSetSpreadsheetGenerator.java @@ -35,7 +35,7 @@ public class ValueSetSpreadsheetGenerator extends CanonicalSpreadsheetGenerator if (vs == null) { System.out.println("no valueset!"); } - addValueSetMetadata(renderCanonicalResource(vs), vs); + addValueSetMetadata(renderCanonicalResource(vs, false), vs); for (ConceptSetComponent inc : vs.getCompose().getInclude()) { genInclude(vs, inc, "Include"); } diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/formats/CSVWriter.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/formats/CSVWriter.java index 5ffff2214..c768f2463 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/formats/CSVWriter.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/formats/CSVWriter.java @@ -150,6 +150,51 @@ public class CSVWriter extends TextStreamWriter { } } + public CSVWriter(OutputStream out, boolean asXml) throws UnsupportedEncodingException { + super(out); + this.asXml = asXml; + this.def = null; + CSVLine header = new CSVLine(); + lines.add(header); + header.addString("Profile"); // + header.addString("Id"); // + header.addString("Path"); //A + header.addString("Slice Name"); //B + header.addString("Alias(s)"); //C + header.addString("Label"); //D + header.addString("Min"); //E + header.addString("Max"); //F + header.addString("Must Support?"); //G + header.addString("Is Modifier?"); //H + header.addString("Is Summary?"); //I + header.addString("Type(s)"); //J + header.addString("Short"); //K + header.addString("Definition"); //L + header.addString("Comments"); //M + header.addString("Requirements"); //N + header.addString("Default Value"); //O + header.addString("Meaning When Missing"); //P + header.addString("Fixed Value"); //Q + header.addString("Pattern"); //R + header.addString("Example"); //S + header.addString("Minimum Value"); //T + header.addString("Maximum Value"); //U + header.addString("Maximum Length"); //V + header.addString("Binding Strength"); //W + header.addString("Binding Description"); //X + header.addString("Binding Value Set"); //Y + header.addString("Code"); //Z + header.addString("Slicing Discriminator");//AA + header.addString("Slicing Description"); //AB + header.addString("Slicing Ordered"); //AC + header.addString("Slicing Rules"); //AD + header.addString("Base Path"); //AE + header.addString("Base Min"); //AF + header.addString("Base Max"); //AG + header.addString("Condition(s)"); //AH + header.addString("Constraint(s)"); //AI + } + /* private void findMapKeys(StructureDefinition def, List maps, IWorkerContext context) { maps.addAll(def.getMapping()); if (def.getBaseDefinition()!=null) { @@ -158,9 +203,12 @@ public class CSVWriter extends TextStreamWriter { } }*/ - public void processElement(ElementDefinition ed) throws Exception { + public void processElement(StructureDefinition sd, ElementDefinition ed) throws Exception { CSVLine line = new CSVLine(); lines.add(line); + if (def == null) { + line.addString(sd.getId()); + } line.addString(ed.getId()); line.addString(ed.getPath()); line.addString(ed.getSliceName()); @@ -218,10 +266,12 @@ public class CSVWriter extends TextStreamWriter { } line.addString(itemList(ed.getCondition())); line.addString(itemList(ed.getConstraint())); - for (StructureDefinitionMappingComponent mapKey : def.getMapping()) { - for (ElementDefinitionMappingComponent map : ed.getMapping()) { - if (map.getIdentity().equals(mapKey.getIdentity())) - line.addString(map.getMap()); + if (def != null) { + for (StructureDefinitionMappingComponent mapKey : def.getMapping()) { + for (ElementDefinitionMappingComponent map : ed.getMapping()) { + if (map.getIdentity().equals(mapKey.getIdentity())) + line.addString(map.getMap()); + } } } } diff --git a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/npm/NpmPackage.java b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/npm/NpmPackage.java index 67b1df1f2..bb59e01c7 100644 --- a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/npm/NpmPackage.java +++ b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/npm/NpmPackage.java @@ -179,7 +179,7 @@ public class NpmPackage { } public boolean readIndex(JsonObject index) { - if (!index.has("index-version") || (index.asInteger("index-version") != 1)) { + if (!index.has("index-version") || (index.asInteger("index-version") != NpmPackageIndexBuilder.CURRENT_INDEX_VERSION)) { return false; } this.index = index; diff --git a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/npm/NpmPackageIndexBuilder.java b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/npm/NpmPackageIndexBuilder.java index 57c735456..9fcfde2c3 100644 --- a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/npm/NpmPackageIndexBuilder.java +++ b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/npm/NpmPackageIndexBuilder.java @@ -18,12 +18,13 @@ import org.hl7.fhir.utilities.json.parser.JsonParser; */ public class NpmPackageIndexBuilder { + public static final Integer CURRENT_INDEX_VERSION = 2; private JsonObject index; private JsonArray files; public void start() { index = new JsonObject(); - index.add("index-version", 1); + index.add("index-version", CURRENT_INDEX_VERSION); files = new JsonArray(); index.add("files", files); } @@ -56,6 +57,9 @@ public class NpmPackageIndexBuilder { if (json.hasPrimitive("supplements")) { fi.add("supplements", json.asString("supplements")); } + if (json.hasPrimitive("content")) { + fi.add("content", json.asString("content")); + } } } catch (Exception e) { System.out.println("Error parsing "+name+": "+e.getMessage()); diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/services/ValidationService.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/services/ValidationService.java index 6a6928680..47c16604a 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/services/ValidationService.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/services/ValidationService.java @@ -463,7 +463,7 @@ public class ValidationService { CanonicalResource cr = validator.loadCanonicalResource(cliContext.getSources().get(0), cliContext.getSv()); boolean ok = true; if (cr instanceof StructureDefinition) { - new StructureDefinitionSpreadsheetGenerator(validator.getContext(), false, false).renderStructureDefinition((StructureDefinition) cr).finish(new FileOutputStream(cliContext.getOutput())); + new StructureDefinitionSpreadsheetGenerator(validator.getContext(), false, false).renderStructureDefinition((StructureDefinition) cr, false).finish(new FileOutputStream(cliContext.getOutput())); } else if (cr instanceof CodeSystem) { new CodeSystemSpreadsheetGenerator(validator.getContext()).renderCodeSystem((CodeSystem) cr).finish(new FileOutputStream(cliContext.getOutput())); } else if (cr instanceof ValueSet) {