diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index e69de29b..d1c39a0e 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -0,0 +1,26 @@ + +* Loader: Significant Performance improvements parsing JSON resources + other performance improvements +* Loader: New Parameters apply-wg and default-wg +* NpmPackages: Start generating .index.db as well as .index.json in packages for faster package reading +* Validator: Refactor Type handling for faster performance +* Validator: Validate the stated publisher/WG/contacts for HL7 published resources +* Validator: Better error message when diff contains bad paths +* Validator: Pass dependent resources to server and make sure cache-id is filled out properly in all contexts +* Validator: Fix error in FML parser parsing parameters +* Validator: Fix issue with dom-6 and contained elements (Internal ChildMap synchro issues) +* Validator: Better handling of errors from tx.fhir.org +* Validator: Fix bug checking for implicit value sets +* Validator: Fix bug checking of mixing snomed display types +* Validator: Reduce size of validatable concept map to 500 - for now + better handling of errors on server batches +* Validator: Improve UCUM validation BP rule +* Validator: set example status when valdiating +* Validator: don't check examples for deprecated / withdrawn content +* Renderer: Fix up handling of includes in liquid templates +* Renderer: Fix up rendering of profile names for abstract profile instantiations +* Renderer: Improved rendering of codes in include when rendering valuesets +* Renderer: Fix problem caching look up of implied value sets +* Renderer: Display workgroup in extension summary table +* QA: Report max memory used +* Publication Process: fix issues generating and releasing templates +* Publication Process: Fix typo in version default logic +* XIG: Start rewrite (phase 1) diff --git a/org.hl7.fhir.publisher.core/src/main/java/org/hl7/fhir/igtools/publisher/IGPublisherLiquidTemplateServices.java b/org.hl7.fhir.publisher.core/src/main/java/org/hl7/fhir/igtools/publisher/IGPublisherLiquidTemplateServices.java index 88a55b6d..ae314be0 100644 --- a/org.hl7.fhir.publisher.core/src/main/java/org/hl7/fhir/igtools/publisher/IGPublisherLiquidTemplateServices.java +++ b/org.hl7.fhir.publisher.core/src/main/java/org/hl7/fhir/igtools/publisher/IGPublisherLiquidTemplateServices.java @@ -49,7 +49,10 @@ public void load(String path) throws FileNotFoundException, IOException { String fn = f.getName(); fn = fn.substring(0, fn.indexOf(".")); templates.put(fn.toLowerCase(), TextFile.fileToString(f)); - } + } else if (f.getName().endsWith(".html")) { + String fn = f.getName(); + templates.put(fn, TextFile.fileToString(f)); + } } } diff --git a/org.hl7.fhir.publisher.core/src/main/java/org/hl7/fhir/igtools/publisher/Publisher.java b/org.hl7.fhir.publisher.core/src/main/java/org/hl7/fhir/igtools/publisher/Publisher.java index 8ab47ec0..02beb407 100644 --- a/org.hl7.fhir.publisher.core/src/main/java/org/hl7/fhir/igtools/publisher/Publisher.java +++ b/org.hl7.fhir.publisher.core/src/main/java/org/hl7/fhir/igtools/publisher/Publisher.java @@ -772,9 +772,11 @@ public enum GenerationTool { private SPDXLicense licenseInfo; private String publisher; private String businessVersion; + private String wgm; private List defaultContacts; private List defaultContexts; private String defaultCopyright; + private String defaultWgm; private List defaultJurisdictions; private SPDXLicense defaultLicenseInfo; private String defaultPublisher; @@ -919,6 +921,7 @@ public void setNoSushi(boolean noSushi) { private List translationLangs = new ArrayList<>(); private List translationSupplements = new ArrayList<>(); private int validationLogTime = 0; + private long maxMemory = 0; private class PreProcessInfo { private String xsltName; @@ -1011,7 +1014,7 @@ private void packageTemplate() throws IOException { File od = new File(outputDir); FileUtils.cleanDirectory(od); npm = new NPMPackageGenerator(Utilities.path(outputDir, "package.tgz"), templateInfo, execTime.getTime(), !publishing); - npm.loadFiles(rootDir, new File(rootDir), ".git", "output", "package"); + npm.loadFiles(rootDir, new File(rootDir), ".git", "output", "package", "temp"); npm.finish(); TextFile.stringToFile(makeTemplateIndexPage(), Utilities.path(outputDir, "index.html"), false); @@ -1038,6 +1041,7 @@ private void packageTemplate() throws IOException { zip.addFileSource("index.html", REDIRECT_SOURCE, false); zip.close(); Utilities.copyFile(Utilities.path(tempDir, "full-ig.zip"), Utilities.path(outputDir, "full-ig.zip")); + new File(Utilities.path(tempDir, "full-ig.zip")).delete(); // registering the package locally log("Finished. "+DurationUtil.presentDuration(endTime - startTime)+". Output in "+outputDir); @@ -1060,10 +1064,10 @@ private String makeTemplateIndexPage() { } private String makeTemplateJekyllIndexPage() { - String page = "---"+ - "layout: page"+ - "title: {{npm}}"+ - "---"+ + String page = "---\r\n"+ + "layout: page\r\n"+ + "title: {{npm}}\r\n"+ + "---\r\n"+ "

Template {{npm}}

\r\n"+ "

You can download the template, though you should not need to; just refer to the template as {{npm}} in your IG configuration.

\r\n"+ "

A full version history is published

\r\n"; @@ -1071,7 +1075,7 @@ private String makeTemplateJekyllIndexPage() { } private String makeTemplateQAPage() { - String page = "Template QA Page

Template {{npm}}

You can download the template, though you should not need to; just refer to the template as {{npm}} in your IG configuration.

"; + String page = "Template QA Page

Template {{npm}} QA

No useful QA on templates - if you see this page, the template buitl ok.

"; return page.replace("{{npm}}", templateInfo.asString("name")); } @@ -1141,7 +1145,7 @@ public void createIg() throws Exception, IOException, EOperationOutcome, FHIRExc log("Validation output in "+val.generate(sourceIg.getName(), errors, fileList, Utilities.path(destDir != null ? destDir : outputDir, "qa.html"), suppressedMessages)); } recordOutcome(null, val); - log("Finished"); + log("Finished. Max Memory Used = "+Utilities.describeSize(maxMemory)); } catch (Exception e) { try { recordOutcome(e, null); @@ -1396,6 +1400,7 @@ private void recordOutcome(Exception ex, ValidationPresenter val) { j.add("template", templatePck); } j.add("tool", Constants.VERSION+" ("+ToolsVersion.TOOLS_VERSION+")"); + j.add("maxMemory", maxMemory); String json = org.hl7.fhir.utilities.json.parser.JsonParser.compose(j, true); TextFile.stringToFile(json, Utilities.path(destDir != null ? destDir : outputDir, "qa.json"), false); @@ -2705,6 +2710,11 @@ private void initializeFromIg(IniFile ini) throws Exception { businessVersion = sourceIg.getVersion(); } break; + case "apply-wg": + if (p.getValue().equals("true")) { + wgm = ToolingExtensions.readStringExtension(sourceIg, ToolingExtensions.EXT_WORKGROUP); + } + break; case "default-contact": if (p.getValue().equals("true")) { defaultContacts = sourceIg.getContact(); @@ -2740,6 +2750,11 @@ private void initializeFromIg(IniFile ini) throws Exception { defaultBusinessVersion = sourceIg.getVersion(); } break; + case "default-wg": + if (p.getValue().equals("true")) { + defaultWgm = ToolingExtensions.readStringExtension(sourceIg, ToolingExtensions.EXT_WORKGROUP); + } + break; case "generate-version": generateVersions.add(p.getValue()); break; @@ -4431,6 +4446,9 @@ private boolean load() throws Exception { publishedIg.addFhirVersion(FHIRVersion.fromCode(version)); if (!publishedIg.hasVersion() && businessVersion != null) publishedIg.setVersion(businessVersion); + if (!publishedIg.hasExtension(ToolingExtensions.EXT_WORKGROUP) && wgm != null) { + publishedIg.addExtension(ToolingExtensions.EXT_WORKGROUP, new CodeType(wgm)); + } String id = npmName; if (npmName.startsWith("hl7.")) { @@ -5559,8 +5577,8 @@ private void loadConformance() throws Exception { loadDepInfo(); log("Load Info"); loadInfo(); + log("Load Resources"); for (String s : metadataResourceNames()) { - log("Load "+s); load(s); } log("Load Paths"); @@ -6342,20 +6360,31 @@ private void load(String type) throws Exception { } CommaSeparatedStringBuilder b = new CommaSeparatedStringBuilder(); if (businessVersion != null) { - if (!bc.hasVersion()) { + altered = true; + b.append("version="+businessVersion); + bc.setVersion(businessVersion); + } else if (defaultBusinessVersion != null && !bc.hasVersion()) { + altered = true; + b.append("version="+defaultBusinessVersion); + bc.setVersion(defaultBusinessVersion); + } + + if (wgm != null) { + if (!bc.hasExtension(ToolingExtensions.EXT_WORKGROUP)) { altered = true; - b.append("version="+businessVersion); - bc.setVersion(businessVersion); - } else if (!bc.getVersion().equals(businessVersion)) { + b.append("wg="+wgm); + bc.addExtension(ToolingExtensions.EXT_WORKGROUP, new CodeType(wgm)); + } else if (!wgm.equals(ToolingExtensions.readStringExtension(bc, ToolingExtensions.EXT_WORKGROUP))) { altered = true; - b.append("version="+businessVersion); - bc.setVersion(businessVersion); + b.append("wg="+wgm); + bc.getExtensionByUrl(ToolingExtensions.EXT_WORKGROUP).setValue(new CodeType(wgm)); } - } else if (defaultBusinessVersion != null && !bc.getVersionElement().isEmpty()) { + } else if (defaultWgm != null && !bc.hasExtension(ToolingExtensions.EXT_WORKGROUP)) { altered = true; - b.append("version="+defaultBusinessVersion); - bc.setVersion(defaultBusinessVersion); + b.append("wg="+defaultWgm); + bc.addExtension(ToolingExtensions.EXT_WORKGROUP, new CodeType(defaultWgm)); } + if (contacts != null && !contacts.isEmpty()) { altered = true; b.append("contact"); @@ -7054,7 +7083,7 @@ private FetchedFile findFileForResource(FetchedResource r) { public void validateSD(FetchedFile f, FetchedResource r) { StructureDefinition sd = (StructureDefinition) r.getResource(); - if (!sd.getAbstract()) { + if (!sd.getAbstract() && !isClosing(sd)) { if (sd.getKind() == StructureDefinitionKind.RESOURCE) { int cE = countStatedExamples(sd.getUrl()); int cI = countFoundExamples(sd.getUrl()); @@ -7085,6 +7114,18 @@ public void validateSD(FetchedFile f, FetchedResource r) { } } + private boolean isClosing(StructureDefinition sd) { + StandardsStatus ss = ToolingExtensions.getStandardsStatus(sd); + if (ss == StandardsStatus.DEPRECATED || ss == StandardsStatus.WITHDRAWN) { + return true; + } + if (sd.getStatus() == PublicationStatus.RETIRED) { + return true; + } + return false; + } + + private int countUsages(String fixedUrl) { int res = 0; for (FetchedFile f : fileList) { @@ -7162,6 +7203,7 @@ private void validate(FetchedFile file, FetchedResource r) throws Exception { List errs = new ArrayList(); r.getElement().setUserData("igpub.context.file", file); r.getElement().setUserData("igpub.context.resource", r); + validator.setExample(r.isExample()); if (r.isValidateAsResource()) { Resource res = r.getResource(); if (res instanceof Bundle) { @@ -11530,8 +11572,6 @@ public void setLogger(ILoggingService logger) { public String getQAFile() throws IOException { return Utilities.path(outputDir, "qa.html"); } - - private String lastMsg; @Override public void logMessage(String msg) { @@ -11544,12 +11584,15 @@ public void logMessage(String msg) { long totalMemory = runtime.totalMemory(); long freeMemory = runtime.freeMemory(); long usedMemory = totalMemory - freeMemory; + if (usedMemory > maxMemory) { + maxMemory = usedMemory; + } String s = msg; if (tt == null) { - System.out.println(Utilities.padRight(s, ' ', 190)); + System.out.println(Utilities.padRight(s, ' ', 100)); } else { // if (tt.longerThan(4)) { - System.out.println(Utilities.padRight(s, ' ', 190)+" ("+tt.milestone()+" / "+tt.clock()+", "+Utilities.describeSize(usedMemory)+")"); + System.out.println(Utilities.padRight(s, ' ', 100)+" ("+tt.milestone()+" / "+tt.clock()+", "+Utilities.describeSize(usedMemory)+")"); } if (killFile != null && killFile.exists()) { killFile.delete(); diff --git a/org.hl7.fhir.publisher.core/src/main/java/org/hl7/fhir/igtools/publisher/R4ToR4BAnalyser.java b/org.hl7.fhir.publisher.core/src/main/java/org/hl7/fhir/igtools/publisher/R4ToR4BAnalyser.java index b9455c7f..58d07f57 100644 --- a/org.hl7.fhir.publisher.core/src/main/java/org/hl7/fhir/igtools/publisher/R4ToR4BAnalyser.java +++ b/org.hl7.fhir.publisher.core/src/main/java/org/hl7/fhir/igtools/publisher/R4ToR4BAnalyser.java @@ -431,7 +431,7 @@ private void genSameVersionPackage(String pid, String source, String dest, boole private void processFileSame(NPMPackageGenerator gen, String folder, String filename, byte[] content, Map exemptions, String ver, String pver) { try { if (Utilities.existsInList(folder, "package", "example")) { - if (!Utilities.existsInList(filename, "package.json", ".index.json")) { + if (!Utilities.existsInList(filename, "package.json", ".index.json", ".index.db")) { org.hl7.fhir.r4b.model.Resource res = new org.hl7.fhir.r4b.formats.JsonParser().parse(content); boolean exempt = (exemptions.containsKey(res.fhirType()+"/"+res.getIdBase()) || ((res instanceof org.hl7.fhir.r4b.model.CanonicalResource) && exemptions.containsKey(((org.hl7.fhir.r4b.model.CanonicalResource) res).getUrl()))); @@ -501,7 +501,7 @@ private void genOtherVersionPackage(String pid, String source, String dest, Stri // we use R4B here, whether it's r4 or r4b - if the content is in the differences, we won't get to the this point private void processFileOther(NPMPackageGenerator gen, String folder, String filename, byte[] content, String ver, String pver, String nver, Map exemptions, String pathS, String pathT) throws IOException { if (Utilities.existsInList(folder, "package", "example")) { - if (!Utilities.existsInList(filename, "package.json", ".index.json")) { + if (!Utilities.existsInList(filename, "package.json", ".index.json", ".index.db")) { org.hl7.fhir.r4b.model.Resource res = new org.hl7.fhir.r4b.formats.JsonParser().parse(content); boolean exempt = (exemptions.containsKey(res.fhirType()+"/"+res.getId()) || ((res instanceof org.hl7.fhir.r4b.model.CanonicalResource) && exemptions.containsKey(((org.hl7.fhir.r4b.model.CanonicalResource) res).getUrl()))); diff --git a/org.hl7.fhir.publisher.core/src/main/java/org/hl7/fhir/igtools/publisher/SimpleFetcher.java b/org.hl7.fhir.publisher.core/src/main/java/org/hl7/fhir/igtools/publisher/SimpleFetcher.java index dc1cd2b6..33c84439 100644 --- a/org.hl7.fhir.publisher.core/src/main/java/org/hl7/fhir/igtools/publisher/SimpleFetcher.java +++ b/org.hl7.fhir.publisher.core/src/main/java/org/hl7/fhir/igtools/publisher/SimpleFetcher.java @@ -34,7 +34,7 @@ import org.hl7.fhir.r5.context.IWorkerContext.ILoggingService; import org.hl7.fhir.r5.context.IWorkerContext.ILoggingService.LogCategory; import org.hl7.fhir.r5.elementmodel.FmlParser; -import org.hl7.fhir.r5.elementmodel.ParserBase.NamedElement; +import org.hl7.fhir.r5.elementmodel.ValidatedFragment; import org.hl7.fhir.r5.formats.FormatUtilities; import org.hl7.fhir.r5.model.CanonicalType; import org.hl7.fhir.r5.model.DataType; @@ -342,7 +342,7 @@ public List scan(String sourceDir, IWorkerContext context, boolean } if (!ok && !Utilities.existsInList(ext, "xml", "ttl", "html", "txt", "fml")) { try { - List el = new org.hl7.fhir.r5.elementmodel.JsonParser(context).parse(new FileInputStream(fn)); + List el = new org.hl7.fhir.r5.elementmodel.JsonParser(context).parse(new FileInputStream(fn)); if (el.size() == 1) { addFile(res, f, el.get(0).getElement(), "application/fhir+json"); count++; diff --git a/org.hl7.fhir.publisher.core/src/main/java/org/hl7/fhir/igtools/publisher/SpecMapManager.java b/org.hl7.fhir.publisher.core/src/main/java/org/hl7/fhir/igtools/publisher/SpecMapManager.java index 58f7d8e2..37c4670c 100644 --- a/org.hl7.fhir.publisher.core/src/main/java/org/hl7/fhir/igtools/publisher/SpecMapManager.java +++ b/org.hl7.fhir.publisher.core/src/main/java/org/hl7/fhir/igtools/publisher/SpecMapManager.java @@ -70,6 +70,7 @@ public enum SpecialPackageType { private String version; private NpmPackage pi; private SpecialPackageType special; + private int key; private SpecMapManager() { @@ -428,4 +429,13 @@ public String toString() { return "SpecMapManager [base=" + base + ", name=" + name + ", pi=" + pi + "]"; } + public int getKey() { + return key; + } + + public void setKey(int key) { + this.key = key; + } + + } diff --git a/org.hl7.fhir.publisher.core/src/main/java/org/hl7/fhir/igtools/publisher/loaders/AdjunctFileLoader.java b/org.hl7.fhir.publisher.core/src/main/java/org/hl7/fhir/igtools/publisher/loaders/AdjunctFileLoader.java index 22a3aec5..c17b6f32 100644 --- a/org.hl7.fhir.publisher.core/src/main/java/org/hl7/fhir/igtools/publisher/loaders/AdjunctFileLoader.java +++ b/org.hl7.fhir.publisher.core/src/main/java/org/hl7/fhir/igtools/publisher/loaders/AdjunctFileLoader.java @@ -18,6 +18,7 @@ import org.hl7.fhir.r5.model.Property; import org.hl7.fhir.r5.model.RelatedArtifact.RelatedArtifactType; import org.hl7.fhir.r5.model.Resource; +import org.hl7.fhir.utilities.NamedItemList; import org.hl7.fhir.utilities.TextFile; import org.hl7.fhir.utilities.Utilities; import org.hl7.fhir.utilities.validation.ValidationMessage; @@ -253,7 +254,7 @@ private List makeListOfAttachments(Element element) { return res; } - private void listAttachments(List res, List children, String path) { + private void listAttachments(List res, NamedItemList children, String path) { String lastName = ""; int c = -1; for (int i = 0; i < children.size(); i++) { diff --git a/org.hl7.fhir.publisher.core/src/main/java/org/hl7/fhir/igtools/publisher/realm/USRealmBusinessRules.java b/org.hl7.fhir.publisher.core/src/main/java/org/hl7/fhir/igtools/publisher/realm/USRealmBusinessRules.java index ec351627..d9d79689 100644 --- a/org.hl7.fhir.publisher.core/src/main/java/org/hl7/fhir/igtools/publisher/realm/USRealmBusinessRules.java +++ b/org.hl7.fhir.publisher.core/src/main/java/org/hl7/fhir/igtools/publisher/realm/USRealmBusinessRules.java @@ -227,7 +227,7 @@ public void finishChecks() throws DefinitionException, FHIRFormatError, IOExcept ComparisonSession session = new ComparisonSession(context, context, "Comparison of "+name+" with US-Core", pkp, pkp); // session.setDebug(true); for (ProfilePair c : comparisons) { - System.out.println("US Core Comparison: compare "+c.local+" to "+c.uscore); +// System.out.println("US Core Comparison: compare "+c.local+" to "+c.uscore); session.compare(c.uscore, c.local); } Utilities.createDirectory(Utilities.path(dstDir, "us-core-comparisons")); diff --git a/org.hl7.fhir.publisher.core/src/main/java/org/hl7/fhir/igtools/publisher/utils/TemplateReleaser.java b/org.hl7.fhir.publisher.core/src/main/java/org/hl7/fhir/igtools/publisher/utils/TemplateReleaser.java index 54b5516e..e4bb2f56 100644 --- a/org.hl7.fhir.publisher.core/src/main/java/org/hl7/fhir/igtools/publisher/utils/TemplateReleaser.java +++ b/org.hl7.fhir.publisher.core/src/main/java/org/hl7/fhir/igtools/publisher/utils/TemplateReleaser.java @@ -232,6 +232,7 @@ private void build(String source, VersionDecision vd, List vers } } Publisher.publishDirect(Utilities.path(source, vd.getId())); + vd.built = true; } private void updateVersions(String source, VersionDecision vd, List versionsList) throws FileNotFoundException, IOException { @@ -509,6 +510,13 @@ private void release(String dest, String source, VersionDecision vd, SimpleDateF Utilities.copyDirectory(Utilities.path(source, vd.getId(), "output"), Utilities.path(dest, npm.name(), npm.version()), null); Utilities.copyDirectory(Utilities.path(source, vd.getId(), "output"), Utilities.path(dest, npm.name()), null); Utilities.copyFile(Utilities.path(source, vd.getId(), "package-list.json"), Utilities.path(dest, npm.name(), "package-list.json")); + + // create history page + JsonObject jh = JsonParser.parseObjectFromFile(Utilities.path(source, vd.getId(), "package-list.json")); + String history = TextFile.fileToString(Utilities.path(dest, "history.template")); + history = history.replace("{{id}}", vd.getId()); + history = history.replace("{{pl}}", JsonParser.compose(jh, false)); + TextFile.stringToFile(history, Utilities.path(dest, vd.getId(), "history.html")); // update rss feed Element item = rss.createElement("item"); diff --git a/org.hl7.fhir.publisher.core/src/main/java/org/hl7/fhir/igtools/publisher/xig/XIGDatabaseBuilder.java b/org.hl7.fhir.publisher.core/src/main/java/org/hl7/fhir/igtools/publisher/xig/XIGDatabaseBuilder.java new file mode 100644 index 00000000..ab4995d5 --- /dev/null +++ b/org.hl7.fhir.publisher.core/src/main/java/org/hl7/fhir/igtools/publisher/xig/XIGDatabaseBuilder.java @@ -0,0 +1,399 @@ +package org.hl7.fhir.igtools.publisher.xig; + +import java.io.BufferedOutputStream; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.PreparedStatement; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.zip.Deflater; + +import org.apache.commons.compress.compressors.gzip.GzipCompressorOutputStream; +import org.apache.commons.compress.compressors.gzip.GzipParameters; +import org.hl7.fhir.convertors.advisors.impl.BaseAdvisor_10_50; +import org.hl7.fhir.convertors.analytics.PackageVisitor.IPackageVisitorProcessor; +import org.hl7.fhir.convertors.factory.VersionConvertorFactory_10_50; +import org.hl7.fhir.convertors.factory.VersionConvertorFactory_14_50; +import org.hl7.fhir.convertors.factory.VersionConvertorFactory_30_50; +import org.hl7.fhir.convertors.factory.VersionConvertorFactory_40_50; +import org.hl7.fhir.convertors.factory.VersionConvertorFactory_43_50; +import org.hl7.fhir.exceptions.FHIRException; +import org.hl7.fhir.igtools.publisher.IGR2ConvertorAdvisor5; +import org.hl7.fhir.igtools.publisher.SpecMapManager; +import org.hl7.fhir.r5.formats.JsonParser; +import org.hl7.fhir.r5.model.CanonicalResource; +import org.hl7.fhir.r5.model.CodeSystem; +import org.hl7.fhir.r5.model.CodeSystem.ConceptDefinitionComponent; +import org.hl7.fhir.r5.model.PackageInformation; +import org.hl7.fhir.r5.model.Resource; +import org.hl7.fhir.r5.model.StructureDefinition; +import org.hl7.fhir.r5.model.StructureDefinition.StructureDefinitionKind; +import org.hl7.fhir.r5.model.ValueSet; +import org.hl7.fhir.r5.model.ValueSet.ConceptSetComponent; +import org.hl7.fhir.r5.utils.EOperationOutcome; +import org.hl7.fhir.utilities.TextFile; +import org.hl7.fhir.utilities.Utilities; +import org.hl7.fhir.utilities.VersionUtilities; +import org.hl7.fhir.utilities.json.model.JsonArray; +import org.hl7.fhir.utilities.json.model.JsonObject; +import org.hl7.fhir.utilities.npm.NpmPackage; +import org.hl7.fhir.utilities.npm.PackageHacker; + +public class XIGDatabaseBuilder implements IPackageVisitorProcessor { + + + private Connection con; + + private PreparedStatement psqlP; + private int pckKey; + private PreparedStatement psqlR; + private int resKey; + private PreparedStatement psqlC; + private PreparedStatement psqlRI; + private PreparedStatement psqlCI; + private Set vurls = new HashSet<>(); + private int lastMDKey; + + private Map smmList = new HashMap<>(); + + public XIGDatabaseBuilder(String dest, String date) throws IOException { + super(); + try { + con = connect(dest, date); + + psqlP = con.prepareStatement("Insert into Packages (PackageKey, PID, Id, Date, Title, Canonical, Web, Version, R2, R2B, R3, R4, R4B, R5, R6, Realm, Auth, Package) Values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"); + psqlR = con.prepareStatement("Insert into Resources (ResourceKey, PackageKey, ResourceType, ResourceTypeR5, Id, R2, R2B, R3, R4, R4B, R5, R6, Web, Url, Version, Status, Date, Name, Title, Experimental, Realm, Description, Purpose, Copyright, CopyrightLabel, Kind, Type, Supplements, Content) Values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"); + psqlC = con.prepareStatement("Insert into Contents (ResourceKey, Json, JsonR5) Values (?, ?, ?)"); + psqlRI = con.prepareStatement("Insert into ResourceFTS (ResourceKey, Name, Title, Description, Narrative) Values (?, ?, ?, ?, ?)"); + psqlCI = con.prepareStatement("Insert into CodeSystemFTS (ResourceKey, Code, Display, Definition) Values (?, ?, ?, ?)"); + } catch (Exception e) { + throw new IOException(e); + } + } + + private Connection connect(String filename, String date) throws IOException, SQLException { + new File(filename).delete(); + Connection con = DriverManager.getConnection("jdbc:sqlite:"+filename); + makeMetadataTable(con); + makePackageTable(con); + makeResourcesTable(con); + makeContentsTable(con); + makeResourceIndex(con); + makeCodeIndex(con); + PreparedStatement psql = con.prepareStatement("Insert into Metadata (key, name, value) values (?, ?, ?)"); + psql.setInt(1, ++lastMDKey); + psql.setString(2, "date"); + psql.setString(3, date); + psql.executeUpdate(); + return con; + } + + + private void makeMetadataTable(Connection con) throws SQLException { + Statement stmt = con.createStatement(); + stmt.execute("CREATE TABLE Metadata (\r\n"+ + "Key integer NOT NULL,\r\n"+ + "Name nvarchar NOT NULL,\r\n"+ + "Value nvarchar NOT NULL,\r\n"+ + "PRIMARY KEY (Key))\r\n"); + } + + private void makeResourceIndex(Connection con) throws SQLException { + Statement stmt = con.createStatement(); + stmt.execute("CREATE VIRTUAL TABLE ResourceFTS USING fts5(ResourceKey, Name, Title, Description, Narrative)"); + } + + + private void makeCodeIndex(Connection con) throws SQLException { + Statement stmt = con.createStatement(); + stmt.execute("CREATE VIRTUAL TABLE CodeSystemFTS USING fts5(ResourceKey, Code, Display, Definition)"); + } + + private void makePackageTable(Connection con) throws SQLException { + Statement stmt = con.createStatement(); + stmt.execute("CREATE TABLE Packages (\r\n"+ + "PackageKey integer NOT NULL,\r\n"+ + "PID nvarchar NOT NULL,\r\n"+ + "Id nvarchar NOT NULL,\r\n"+ + "Date nvarchar NULL,\r\n"+ + "Title nvarchar NULL,\r\n"+ + "Canonical nvarchar NULL,\r\n"+ + "Web nvarchar NULL,\r\n"+ + "Version nvarchar NULL,\r\n"+ + "R2 INTEGER NULL,\r\n"+ + "R2B INTEGER NULL,\r\n"+ + "R3 INTEGER NULL,\r\n"+ + "R4 INTEGER NULL,\r\n"+ + "R4B INTEGER NULL,\r\n"+ + "R5 INTEGER NULL,\r\n"+ + "R6 INTEGER NULL,\r\n"+ + "Realm nvarchar NULL,\r\n"+ + "Auth nvarchar NULL,\r\n"+ + "Package BLOB NULL,\r\n"+ + "PRIMARY KEY (PackageKey))\r\n"); + } + + + private void makeResourcesTable(Connection con) throws SQLException { + Statement stmt = con.createStatement(); + stmt.execute("CREATE TABLE Resources (\r\n"+ + "ResourceKey integer NOT NULL,\r\n"+ + "PackageKey integer NOT NULL,\r\n"+ + "ResourceType nvarchar NOT NULL,\r\n"+ + "ResourceTypeR5 nvarchar NOT NULL,\r\n"+ + "Id nvarchar NOT NULL,\r\n"+ + "R2 INTEGER NULL,\r\n"+ + "R2B INTEGER NULL,\r\n"+ + "R3 INTEGER NULL,\r\n"+ + "R4 INTEGER NULL,\r\n"+ + "R4B INTEGER NULL,\r\n"+ + "R5 INTEGER NULL,\r\n"+ + "R6 INTEGER NULL,\r\n"+ + "Core INTEGER NULL,\r\n"+ + "Web nvarchar NULL,\r\n"+ + "Url nvarchar NULL,\r\n"+ + "Version nvarchar NULL,\r\n"+ + "Status nvarchar NULL,\r\n"+ + "Date nvarchar NULL,\r\n"+ + "Name nvarchar NULL,\r\n"+ + "Title nvarchar NULL,\r\n"+ + "Experimental INTEGER NULL,\r\n"+ + "Realm nvarchar NULL,\r\n"+ + "Description nvarchar NULL,\r\n"+ + "Purpose nvarchar NULL,\r\n"+ + "Copyright nvarchar NULL,\r\n"+ + "CopyrightLabel nvarchar NULL,\r\n"+ + "Content nvarchar NULL,\r\n"+ + "Type nvarchar NULL,\r\n"+ + "Supplements nvarchar NULL,\r\n"+ + "Kind nvarchar NULL,\r\n"+ + "PRIMARY KEY (ResourceKey))\r\n"); + } + + + private void makeContentsTable(Connection con) throws SQLException { + Statement stmt = con.createStatement(); + stmt.execute("CREATE TABLE Contents (\r\n"+ + "ResourceKey integer NOT NULL,\r\n"+ + "Json BLOB NOT NULL,\r\n"+ + "JsonR5 BLOB NULL,\r\n"+ + "PRIMARY KEY (ResourceKey))\r\n"); + + } + + public void finish() throws IOException { + try { + con.close(); + } catch (Exception e) { + throw new IOException(e); + } + } + + @Override + public void processResource(String pid, NpmPackage npm, String version, String type, String id, byte[] content) throws FHIRException, IOException, EOperationOutcome { + if (!isCoreDefinition(pid)) { + + try { + SpecMapManager smm = smmList.get(pid); + if (smm == null) { + smm = npm.hasFile("other", "spec.internals") ? new SpecMapManager( TextFile.streamToBytes(npm.load("other", "spec.internals")), npm.fhirVersion()) : SpecMapManager.createSpecialPackage(npm); + pckKey++; + smm.setName(npm.name()); + smm.setBase(npm.canonical()); + smm.setBase2(PackageHacker.fixPackageUrl(npm.url())); + smm.setKey(pckKey); + smmList.put(pid, smm); + + psqlP.setInt(1, pckKey); + psqlP.setString(2, pid); + psqlP.setString(3, npm.name()); + psqlP.setString(4, npm.date()); + psqlP.setString(5, npm.title()); + psqlP.setString(6, npm.canonical()); + psqlP.setString(7, npm.getWebLocation()); + psqlP.setString(8, npm.version()); + psqlP.setInt(9, hasVersion(npm.fhirVersionList(), "1.0")); + psqlP.setInt(10, hasVersion(npm.fhirVersionList(), "1.4")); + psqlP.setInt(11, hasVersion(npm.fhirVersionList(), "3.0")); + psqlP.setInt(12, hasVersion(npm.fhirVersionList(), "4.0")); + psqlP.setInt(13, hasVersion(npm.fhirVersionList(), "4.3")); + psqlP.setInt(14, hasVersion(npm.fhirVersionList(), "5.0")); + psqlP.setInt(15, hasVersion(npm.fhirVersionList(), "6.0")); + psqlP.setString(16, getRealm(pid)); + psqlP.setString(17, getAuth(pid)); + psqlP.setBytes(18, org.hl7.fhir.utilities.json.parser.JsonParser.composeBytes(npm.getNpm())); + psqlP.execute(); + } + + Resource r = loadResource(pid, version, type, id, content); + if (r != null && r instanceof CanonicalResource) { + CanonicalResource cr = (CanonicalResource) r; + if (!vurls.contains(cr.getUrl())) { + vurls.add(cr.getUrl()); + JsonObject j = org.hl7.fhir.utilities.json.parser.JsonParser.parseObject(content); + String narrative = cr.getText().getDiv().allText(); + cr.setText(null); + resKey++; + + psqlR.setInt(1, resKey); + psqlR.setInt(2, pckKey); + psqlR.setString(3, type); + psqlR.setString(4, r.fhirType()); + psqlR.setString(5, r.hasId() ? r.getId() : id.replace(".json", "")); + psqlR.setInt(6, hasVersion(npm.fhirVersionList(), "1.0")); + psqlR.setInt(7, hasVersion(npm.fhirVersionList(), "1.4")); + psqlR.setInt(8, hasVersion(npm.fhirVersionList(), "3.0")); + psqlR.setInt(9, hasVersion(npm.fhirVersionList(), "4.0")); + psqlR.setInt(10, hasVersion(npm.fhirVersionList(), "4.3")); + psqlR.setInt(11, hasVersion(npm.fhirVersionList(), "5.0")); + psqlR.setInt(12, hasVersion(npm.fhirVersionList(), "6.0")); + psqlR.setString(13, Utilities.pathURL(smm.getBase(), smm.getPath(cr.getUrl(), null, cr.fhirType(), cr.getIdBase()))); + psqlR.setString(14, cr.getUrl()); + psqlR.setString(15, cr.getVersion()); + psqlR.setString(16, cr.getStatus().toCode()); + psqlR.setString(17, cr.getDateElement().primitiveValue()); + psqlR.setString(18, cr.getName()); + psqlR.setString(19, cr.getTitle()); + psqlR.setBoolean(20, cr.getExperimental()); + psqlR.setString(21, getRealm(pid)); + psqlR.setString(22, cr.getDescription()); + psqlR.setString(23, cr.getPurpose()); + psqlR.setString(24, cr.getCopyright()); + psqlR.setString(25, cr.getCopyrightLabel()); + psqlR.setString(26, j.asString("kind")); + psqlR.setString(27, j.asString("type")); + psqlR.setString(28, j.asString("supplements")); + psqlR.setString(29, j.asString("content")); + psqlR.execute(); + + psqlC.setInt(1, resKey); + psqlC.setBytes(2, gzip(content)); + psqlC.setBytes(3, gzip(new JsonParser().composeBytes(cr))); + psqlC.execute(); + + psqlRI.setInt(1, resKey); + psqlRI.setString(2, cr.getName()); + psqlRI.setString(3, cr.getTitle()); + psqlRI.setString(4, cr.getDescription()); + psqlRI.setString(5, narrative); + psqlRI.execute(); + + if (cr instanceof CodeSystem) { + processCodes(((CodeSystem) cr).getConcept()); + } + } + } + + } catch (Exception e) { + throw new IOException(e); + } + } + } + + private void processCodes(List concepts) throws SQLException { + for (ConceptDefinitionComponent concept : concepts) { + psqlCI.setInt(1, resKey); + psqlCI.setString(2, concept.getCode()); + psqlCI.setString(3, concept.getDisplay()); + psqlCI.setString(4, concept.getDefinition()); + psqlCI.execute(); + processCodes(concept.getConcept()); + } + } + + private byte[] gzip(byte[] bytes) throws IOException { + ByteArrayOutputStream bOut = new ByteArrayOutputStream(); + + GzipParameters gp = new GzipParameters(); + gp.setCompressionLevel(Deflater.BEST_COMPRESSION); + GzipCompressorOutputStream gzip = new GzipCompressorOutputStream(bOut, gp); + gzip.write(bytes); + gzip.flush(); + gzip.close(); + return bOut.toByteArray(); + } + + private int hasVersion(String fhirVersionList, String ver) { + return fhirVersionList.startsWith(ver) || fhirVersionList.contains(","+ver) ? 1 : 0; + } + + private boolean isCoreDefinition(String pid) { + return Utilities.startsWithInList(pid, "hl7.fhir.r2", "hl7.fhir.r2b", "hl7.fhir.r3", "hl7.fhir.r4", "hl7.fhir.r4b", "hl7.fhir.r5", "hl7.fhir.r6", "hl7.fhir.xver"); + } + + private Resource loadResource(String pid, String parseVersion, String type, String id, byte[] source) { + try { + if (parseVersion.equals("current")) { + return null; + } + if (VersionUtilities.isR3Ver(parseVersion)) { + org.hl7.fhir.dstu3.model.Resource res; + res = new org.hl7.fhir.dstu3.formats.JsonParser(true).parse(source); + return VersionConvertorFactory_30_50.convertResource(res); + } else if (VersionUtilities.isR4Ver(parseVersion)) { + org.hl7.fhir.r4.model.Resource res; + res = new org.hl7.fhir.r4.formats.JsonParser(true, true).parse(source); + return VersionConvertorFactory_40_50.convertResource(res); + } else if (VersionUtilities.isR2BVer(parseVersion)) { + org.hl7.fhir.dstu2016may.model.Resource res; + res = new org.hl7.fhir.dstu2016may.formats.JsonParser(true).parse(source); + return VersionConvertorFactory_14_50.convertResource(res); + } else if (VersionUtilities.isR2Ver(parseVersion)) { + org.hl7.fhir.dstu2.model.Resource res; + res = new org.hl7.fhir.dstu2.formats.JsonParser(true).parse(source); + + BaseAdvisor_10_50 advisor = new IGR2ConvertorAdvisor5(); + return VersionConvertorFactory_10_50.convertResource(res, advisor); + } else if (VersionUtilities.isR4BVer(parseVersion)) { + org.hl7.fhir.r4b.model.Resource res; + res = new org.hl7.fhir.r4b.formats.JsonParser(true).parse(source); + return VersionConvertorFactory_43_50.convertResource(res); + } else if (VersionUtilities.isR5Plus(parseVersion)) { + return new JsonParser(true, true).parse(source); + } else if (Utilities.existsInList(parseVersion, "4.6.0", "3.5.0", "1.8.0")) { + return null; + } else { + throw new Exception("Unsupported version "+parseVersion); + } + + } catch (Exception e) { + System.out.println("Error loading "+type+"/"+id+" from "+pid+"("+parseVersion+"):" +e.getMessage()); + e.printStackTrace(); + return null; + } + } + + private String getAuth(String pid) { + if (pid.startsWith("hl7.") || pid.startsWith("fhir.") || pid.startsWith("ch.fhir.")) { + return "hl7"; + } + if (pid.startsWith("ihe.")) { + return "ihe"; + } + return null; + } + + private String getRealm(String pid) { + if (pid.startsWith("hl7.fhir.")) { + return pid.split("\\.")[2]; + } + if (pid.startsWith("fhir.") || pid.startsWith("us.")) { + return "us"; + } + if (pid.startsWith("ch.fhir.")) { + return "ch"; + } + + return null; + } +} diff --git a/org.hl7.fhir.publisher.core/src/main/java/org/hl7/fhir/igtools/publisher/xig/XIGGatherer.java b/org.hl7.fhir.publisher.core/src/main/java/org/hl7/fhir/igtools/publisher/xig/XIGGatherer.java deleted file mode 100644 index d448a69c..00000000 --- a/org.hl7.fhir.publisher.core/src/main/java/org/hl7/fhir/igtools/publisher/xig/XIGGatherer.java +++ /dev/null @@ -1,180 +0,0 @@ -package org.hl7.fhir.igtools.publisher.xig; - -import java.io.FileOutputStream; -import java.io.IOException; -import java.util.HashMap; -import java.util.Map; - -import org.hl7.fhir.convertors.advisors.impl.BaseAdvisor_10_50; -import org.hl7.fhir.convertors.analytics.PackageVisitor.IPackageVisitorProcessor; -import org.hl7.fhir.convertors.factory.VersionConvertorFactory_10_50; -import org.hl7.fhir.convertors.factory.VersionConvertorFactory_14_50; -import org.hl7.fhir.convertors.factory.VersionConvertorFactory_30_50; -import org.hl7.fhir.convertors.factory.VersionConvertorFactory_40_50; -import org.hl7.fhir.convertors.factory.VersionConvertorFactory_43_50; -import org.hl7.fhir.exceptions.FHIRException; -import org.hl7.fhir.igtools.publisher.IGR2ConvertorAdvisor5; -import org.hl7.fhir.igtools.publisher.SpecMapManager; -import org.hl7.fhir.r5.formats.JsonParser; -import org.hl7.fhir.r5.model.CanonicalResource; -import org.hl7.fhir.r5.model.PackageInformation; -import org.hl7.fhir.r5.model.Resource; -import org.hl7.fhir.r5.model.StructureDefinition; -import org.hl7.fhir.r5.model.StructureDefinition.StructureDefinitionKind; -import org.hl7.fhir.r5.model.ValueSet; -import org.hl7.fhir.r5.model.ValueSet.ConceptSetComponent; -import org.hl7.fhir.r5.utils.EOperationOutcome; -import org.hl7.fhir.utilities.TextFile; -import org.hl7.fhir.utilities.Utilities; -import org.hl7.fhir.utilities.VersionUtilities; -import org.hl7.fhir.utilities.json.model.JsonArray; -import org.hl7.fhir.utilities.json.model.JsonObject; -import org.hl7.fhir.utilities.npm.NpmPackage; -import org.hl7.fhir.utilities.npm.PackageHacker; - -public class XIGGatherer implements IPackageVisitorProcessor { - - private JsonObject registry; - private JsonArray packages; - private JsonArray resources; - - private String dest; - private Map smmList = new HashMap<>(); - - public XIGGatherer(String dest) { - super(); - this.registry = new JsonObject(); - packages = new JsonArray(); - resources = new JsonArray(); - registry.add("packages", packages); - registry.add("resources", resources); - this.dest = dest; - } - - public void finish() throws IOException { - org.hl7.fhir.utilities.json.parser.JsonParser.compose(registry, Utilities.pathFile(dest, "cache.json"), true); - } - - @Override - public void processResource(String pid, NpmPackage npm, String version, String type, String id, byte[] content) - throws FHIRException, IOException, EOperationOutcome { - - SpecMapManager smm = smmList.get(pid); - if (smm == null) { - smm = npm.hasFile("other", "spec.internals") ? new SpecMapManager( TextFile.streamToBytes(npm.load("other", "spec.internals")), npm.fhirVersion()) : SpecMapManager.createSpecialPackage(npm); - smm.setName(npm.name()); - smm.setBase(npm.canonical()); - smm.setBase2(PackageHacker.fixPackageUrl(npm.url())); - smmList.put(pid, smm); - JsonObject p = new JsonObject(); - packages.add(p); - p.addIfNotNull("pid", pid); - p.addIfNotNull("id", npm.name()); - p.addIfNotNull("date", npm.date()); - p.addIfNotNull("title", npm.title()); - p.addIfNotNull("canonical", npm.canonical()); - p.addIfNotNull("web", npm.getWebLocation()); - p.addIfNotNull("version", npm.version()); - p.addIfNotNull("fhirVersion", npm.fhirVersionList()); - p.addIfNotNull("fver", npm.fhirVersion()); - p.addIfNotNull("realm", getRealm(pid)); - p.addIfNotNull("auth", getAuth(pid)); - p.addIfNotNull("src", npm.getNpm()); - } - - Resource r = loadResource(pid, version, type, id, content); - if (r != null && r instanceof CanonicalResource) { - r.setSourcePackage(new PackageInformation(npm)); - CanonicalResource cr = (CanonicalResource) r; - if (cr.getUrl() != null) { - boolean core = isCoreDefinition(cr, pid); - if (!core) { - cr.setText(null); - String base = (cr.fhirType()+"-"+pid.substring(0, pid.indexOf("#"))+"-"+cr.getId()).toLowerCase(); - String tgt = Utilities.path(dest, base+".json"); - - JsonObject p = new JsonObject(); - resources.add(p); - p.add("file", base); - p.add("url", cr.getUrl()); - p.add("version", cr.getVersion()); - p.add("pid", pid); - p.add("web", Utilities.pathURL(smm.getBase(), smm.getPath(cr.getUrl(), null, cr.fhirType(), cr.getIdBase()))); - FileOutputStream fo = new FileOutputStream(tgt); - new JsonParser().compose(fo, r); - fo.close(); - } - } - } - } - - private boolean isCoreDefinition(CanonicalResource cr, String pid) { - return Utilities.startsWithInList(pid, "hl7.fhir.r2", "hl7.fhir.r2b", "hl7.fhir.r3", "hl7.fhir.r4", "hl7.fhir.r4b", "hl7.fhir.r5", "hl7.fhir.r6", "hl7.fhir.xver"); - } - - private Resource loadResource(String pid, String parseVersion, String type, String id, byte[] source) { - try { - if (parseVersion.equals("current")) { - return null; - } - if (VersionUtilities.isR3Ver(parseVersion)) { - org.hl7.fhir.dstu3.model.Resource res; - res = new org.hl7.fhir.dstu3.formats.JsonParser(true).parse(source); - return VersionConvertorFactory_30_50.convertResource(res); - } else if (VersionUtilities.isR4Ver(parseVersion)) { - org.hl7.fhir.r4.model.Resource res; - res = new org.hl7.fhir.r4.formats.JsonParser(true, true).parse(source); - return VersionConvertorFactory_40_50.convertResource(res); - } else if (VersionUtilities.isR2BVer(parseVersion)) { - org.hl7.fhir.dstu2016may.model.Resource res; - res = new org.hl7.fhir.dstu2016may.formats.JsonParser(true).parse(source); - return VersionConvertorFactory_14_50.convertResource(res); - } else if (VersionUtilities.isR2Ver(parseVersion)) { - org.hl7.fhir.dstu2.model.Resource res; - res = new org.hl7.fhir.dstu2.formats.JsonParser(true).parse(source); - - BaseAdvisor_10_50 advisor = new IGR2ConvertorAdvisor5(); - return VersionConvertorFactory_10_50.convertResource(res, advisor); - } else if (VersionUtilities.isR4BVer(parseVersion)) { - org.hl7.fhir.r4b.model.Resource res; - res = new org.hl7.fhir.r4b.formats.JsonParser(true).parse(source); - return VersionConvertorFactory_43_50.convertResource(res); - } else if (VersionUtilities.isR5Plus(parseVersion)) { - return new JsonParser(true, true).parse(source); - } else if (Utilities.existsInList(parseVersion, "4.6.0", "3.5.0", "1.8.0")) { - return null; - } else { - throw new Exception("Unsupported version "+parseVersion); - } - - } catch (Exception e) { - System.out.println("Error loading "+type+"/"+id+" from "+pid+"("+parseVersion+"):" +e.getMessage()); - e.printStackTrace(); - return null; - } - } - - private String getAuth(String pid) { - if (pid.startsWith("hl7.") || pid.startsWith("fhir.") || pid.startsWith("ch.fhir.")) { - return "hl7"; - } - if (pid.startsWith("ihe.")) { - return "ihe"; - } - return null; - } - - private String getRealm(String pid) { - if (pid.startsWith("hl7.fhir.")) { - return pid.split("\\.")[2]; - } - if (pid.startsWith("fhir.") || pid.startsWith("us.")) { - return "us"; - } - if (pid.startsWith("ch.fhir.")) { - return "ch"; - } - - return null; - } -} diff --git a/org.hl7.fhir.publisher.core/src/main/java/org/hl7/fhir/igtools/publisher/xig/XIGGenerator.java b/org.hl7.fhir.publisher.core/src/main/java/org/hl7/fhir/igtools/publisher/xig/XIGGenerator.java index 41c95d3c..dce13034 100644 --- a/org.hl7.fhir.publisher.core/src/main/java/org/hl7/fhir/igtools/publisher/xig/XIGGenerator.java +++ b/org.hl7.fhir.publisher.core/src/main/java/org/hl7/fhir/igtools/publisher/xig/XIGGenerator.java @@ -1,5 +1,6 @@ package org.hl7.fhir.igtools.publisher.xig; +import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.net.URISyntaxException; @@ -32,8 +33,6 @@ public class XIGGenerator { private String target; private String cache; - private XIGInformation info = new XIGInformation(); - private FilesystemPackageCacheManager pcm; private String date; @@ -48,195 +47,52 @@ public XIGGenerator(String target, String cache) throws FHIRException, IOExcepti this.cache = cache; Utilities.createDirectory(cache); pcm = new FilesystemPackageCacheManager(org.hl7.fhir.utilities.npm.FilesystemPackageCacheManager.FilesystemPackageCacheMode.USER); - NpmPackage npm = pcm.loadPackage("hl7.fhir.r5.core#5.0.0"); - info.setCtxt(new SimpleWorkerContext.SimpleWorkerContextBuilder().fromPackage(npm, new PublisherLoader(npm, SpecMapManager.fromPackage(npm), npm.getWebLocation(), null).makeLoader(), false)); - info.getCtxt().setAllowLazyLoading(false); - info.getCtxt().setAllowLoadingDuplicates(true); -// this.ctxt.connectToTSServer(TerminologyClientFactory.makeClient(Servers., "fhir/publisher", FhirPublication.R5), null); - info.getCtxt().setExpansionProfile(buildExpansionProfile()); String ds = new SimpleDateFormat("dd MMM yyyy", new Locale("en", "US")).format(Calendar.getInstance().getTime()); String dl = new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ssZ", new Locale("en", "US")).format(Calendar.getInstance().getTime()); - date = ""+ds+""; - - info.getJson().add("date", date); - JsonObject doco = new JsonObject(); - info.getJson().add("_doco", doco); - doco.add("packages", "An object containing of all the packages found, with {id}#{version} : package.json contents"); - doco.add("canonicals", "An array of all the canonical resources found, with details"); - addDoco(doco); - - info.getJson().add("packages", new JsonObject()); - info.getJson().add("canonicals", new JsonArray()); - } - - private void addDoco(JsonObject doco) { - JsonObject docoC = new JsonObject(); - doco.add("canonicalDetails", docoC); - docoC.add("pid", "package where this resource was found"); - docoC.add("fver", "version of FHIR for this resource"); - docoC.add("published", "true if this is from a published package (as oppoosed to the ci-build"); - docoC.add("filebase", "the name of the file (same directory as this json file). Both .json and .html exist"); - docoC.add("path", "Where to find the HTML publication of this resource"); - docoC.add("resourceType", "the type of this resource"); - docoC.add("id", "id of the resource in the source package"); - docoC.add("canonical", "canonical URL, if there is one"); - docoC.add("version", "business version, if there is one"); - docoC.add("status", "status, if there is one"); - docoC.add("publisher", "stated publisher, if there is one"); - docoC.add("name", "name, if there is one"); - docoC.add("title", "title, if there is one"); - docoC.add("date", "stated date, if there is one"); - docoC.add("experimental", "whether the resource is marked experimental"); - docoC.add("description", "description, if there is one"); - docoC.add("copyright", "stated copyright, if there is one"); - docoC.add("jurisdiction", "stated jurisdiction, if there is one"); - - - docoC.add("abstract", "abstract, if stated (StructureDefinition)"); - docoC.add("affectsState", "affectsState, if stated (OperationDefinition)"); - docoC.add("base", "base, if stated (OperationDefinition, StructureDefinition)"); - docoC.add("caseSensitive", "caseSensitive, if stated (CodeSystem)"); - docoC.add("code", "code, if stated (OperationDefinition, SearchParameter)"); - docoC.add("compositional", "compositional, if stated (CodeSystem)"); - docoC.add("content", "content, if stated (CodeSystem)"); - docoC.add("contextInvs", "array of contextInvs in the resource (StructureDefinition)"); - docoC.add("contexts", "array of contexts (type:expression in the resource (StructureDefinition)"); - docoC.add("derivation", "derivation, if stated (StructureDefinition)"); - docoC.add("fhirVersion", "Stated version in the resource (CapabilityStatement, StructureDefinition)"); - docoC.add("formats", "array of formats and patchFormats in the resource (CapabilityStatement)"); - docoC.add("hierarchyMeaning", "hierarchyMeaning, if stated (CodeSystem)"); - docoC.add("immutable", "immutable, if stated (ValueSet)"); - docoC.add("implementationGuides", "array of implementationGuides in the resource (CapabilityStatement)"); - docoC.add("imports", "array of imports in the resource (CapabilityStatement)"); - docoC.add("instance", "instance, if stated (OperationDefinition)"); - docoC.add("instantiates", "array of instantiates claims in the resource (CapabilityStatement)"); - docoC.add("keywords", "array of keywords in the resource (StructureDefinition)"); - docoC.add("kind", "kind, if stated (CapabilityStatement, NamingSystem, StructureDefinition)"); - docoC.add("languages", "array of languages in the resource (CapabilityStatement)"); - docoC.add("resources", "array of base resource, in the resource (OperationDefinition)"); - docoC.add("resourcesSP", "array of base resource, in the resource (SearchParameter)"); - docoC.add("sourceScope", "sourceScope, if stated (ConceptMap"); - docoC.add("sources", "array of sources in the resource (ConceptMap"); - docoC.add("supplements", "supplements, if stated (CodeSystem)"); - docoC.add("system", "system, if stated (OperationDefinition)"); - docoC.add("targetScope", "targetScope, if stated (ConceptMap"); - docoC.add("targets", "array of targets in the resource (ConceptMap"); - docoC.add("type", "type, if stated (NamingSystem, OperationDefinition, SearchParameter, StructureDefinition)"); - docoC.add("valueSet", "valueSet, if stated (CodeSystem)"); - docoC.add("versionNeeded", "versionNeeded, if stated (CodeSystem)"); - } - - private Parameters buildExpansionProfile() { - Parameters res = new Parameters(); - res.addParameter("profile-url", "urn:uuid:"+UUID.randomUUID().toString().toLowerCase()); - res.addParameter("excludeNested", false); - res.addParameter("includeDesignations", true); - // res.addParameter("activeOnly", true); - res.addParameter("system-version", "http://snomed.info/sct|http://snomed.info/sct/"+SNOMED_EDITION); // value sets are allowed to override this. for now - return res; + date = ""+ds+""; } public void execute(String step) throws IOException, ParserConfigurationException, SAXException, FHIRException, EOperationOutcome, ParseException { ProfileUtilities.setSuppressIgnorableExceptions(true); - - if (step.equals("step1")) { - long ms = System.currentTimeMillis(); - - Utilities.clearDirectory(target); - PackageVisitor pv = new PackageVisitor(); - pv.getResourceTypes().add("CapabilityStatement"); - pv.getResourceTypes().add("SearchParameter"); - pv.getResourceTypes().add("OperationDefinition"); - pv.getResourceTypes().add("StructureDefinition"); - pv.getResourceTypes().add("ValueSet"); - pv.getResourceTypes().add("CodeSystem"); - pv.getResourceTypes().add("ConceptMap"); - pv.getResourceTypes().add("StructureMap"); - pv.getResourceTypes().add("NamingSystem"); - pv.getResourceTypes().add("GraphDefinition"); - pv.getResourceTypes().add("ActivityDefinition"); - pv.getResourceTypes().add("ConditionDefinition"); - pv.getResourceTypes().add("DeviceDefinition"); - pv.getResourceTypes().add("EventDefinition"); - pv.getResourceTypes().add("ObservationDefinition"); - pv.getResourceTypes().add("PlanDefinition"); - pv.getResourceTypes().add("Questionnaire"); - pv.getResourceTypes().add("SpecimenDefinition"); - pv.getResourceTypes().add("ExampleScenario"); - pv.getResourceTypes().add("ActorDefinition"); - pv.getResourceTypes().add("Requirements"); - - pv.setCache(cache); - pv.setOldVersions(false); - pv.setCorePackages(false); - XIGGatherer gather = new XIGGatherer(target); - pv.setProcessor(gather); - pv.setCurrent(true); - pv.visitPackages(); - gather.finish(); - - System.out.println("Finished Step 1: "+Utilities.describeDuration(System.currentTimeMillis() - ms)); - } else if (step.equals("step2")) { - long ms = System.currentTimeMillis(); - XIGLoader loader = new XIGLoader(info); - loader.loadFromCache(target); - System.out.println("Finished Step 2 A: "+Utilities.describeDuration(System.currentTimeMillis() - ms)); - info.buildUsageMap(); - System.out.println("Finished Step 2 B: "+Utilities.describeDuration(System.currentTimeMillis() - ms)); - System.out.println("Finished Step 2 C: "+Utilities.describeDuration(System.currentTimeMillis() - ms)); printSummary(); - new XIGRenderer(info, target, date).produce(pcm); - System.out.println("Finished Step 2 D: "+Utilities.describeDuration(System.currentTimeMillis() - ms)); - } else { - PackageVisitor pv = new PackageVisitor(); - pv.getResourceTypes().add("CapabilityStatement"); - pv.getResourceTypes().add("SearchParameter"); - pv.getResourceTypes().add("OperationDefinition"); - pv.getResourceTypes().add("StructureDefinition"); - pv.getResourceTypes().add("ValueSet"); - pv.getResourceTypes().add("CodeSystem"); - pv.getResourceTypes().add("ConceptMap"); - pv.getResourceTypes().add("StructureMap"); - pv.getResourceTypes().add("NamingSystem"); - pv.getResourceTypes().add("GraphDefinition"); - pv.getResourceTypes().add("ActivityDefinition"); - pv.getResourceTypes().add("ConditionDefinition"); - pv.getResourceTypes().add("DeviceDefinition"); - pv.getResourceTypes().add("EventDefinition"); - pv.getResourceTypes().add("ObservationDefinition"); - pv.getResourceTypes().add("PlanDefinition"); - pv.getResourceTypes().add("Questionnaire"); - pv.getResourceTypes().add("SpecimenDefinition"); - pv.getResourceTypes().add("ExampleScenario"); - pv.getResourceTypes().add("ActorDefinition"); - pv.getResourceTypes().add("Requirements"); - - pv.setOldVersions(false); - pv.setCorePackages(false); - pv.setProcessor(new XIGLoader(info)); - pv.setCurrent(true); - pv.visitPackages(); - - info.buildUsageMap(); - - new XIGRenderer(info, target, date).produce(pcm); - printSummary(); - } - } - private void printSummary() throws FileNotFoundException, IOException { - info.getExtensionHandler().finish(target); - System.out.println(""); - System.out.println("IGs: "+info.getPid().size()); - int i = 0; - for (String s : Utilities.sorted(info.getCounts().keySet())) { - i = i + info.getCounts().get(s).size(); - System.out.println(s+": "+info.getCounts().get(s).size()); - } - System.out.println("Total: "+i); - System.out.println("SD Error List:"); - for (String s : info.getSDErrors()) { - System.out.println(" "+s); - } + long ms = System.currentTimeMillis(); + + new File(target).delete(); + + PackageVisitor pv = new PackageVisitor(); + pv.getResourceTypes().add("CapabilityStatement"); + pv.getResourceTypes().add("SearchParameter"); + pv.getResourceTypes().add("OperationDefinition"); + pv.getResourceTypes().add("StructureDefinition"); + pv.getResourceTypes().add("ValueSet"); + pv.getResourceTypes().add("CodeSystem"); + pv.getResourceTypes().add("ConceptMap"); + pv.getResourceTypes().add("StructureMap"); + pv.getResourceTypes().add("NamingSystem"); + pv.getResourceTypes().add("GraphDefinition"); + pv.getResourceTypes().add("ActivityDefinition"); + pv.getResourceTypes().add("ConditionDefinition"); + pv.getResourceTypes().add("DeviceDefinition"); + pv.getResourceTypes().add("EventDefinition"); + pv.getResourceTypes().add("ObservationDefinition"); + pv.getResourceTypes().add("PlanDefinition"); + pv.getResourceTypes().add("Questionnaire"); + pv.getResourceTypes().add("SpecimenDefinition"); + pv.getResourceTypes().add("ExampleScenario"); + pv.getResourceTypes().add("ActorDefinition"); + pv.getResourceTypes().add("Requirements"); + + pv.setCache(cache); + pv.setOldVersions(false); + pv.setCorePackages(true); + XIGDatabaseBuilder gather = new XIGDatabaseBuilder(target, new SimpleDateFormat("dd MMM yyyy", new Locale("en", "US")).format(Calendar.getInstance().getTime())); + pv.setProcessor(gather); + pv.setCurrent(true); + pv.visitPackages(); + gather.finish(); + + System.out.println("Finished Step 1: "+Utilities.describeDuration(System.currentTimeMillis() - ms)); + System.out.println("File size is "+Utilities.describeSize(new File(target).length())); } } diff --git a/org.hl7.fhir.publisher.core/src/main/java/org/hl7/fhir/igtools/publisher/xig/XIGRenderer.java b/org.hl7.fhir.publisher.core/src/main/java/org/hl7/fhir/igtools/publisher/xig/XIGRenderer.java index 73bde5b1..ca26440c 100644 --- a/org.hl7.fhir.publisher.core/src/main/java/org/hl7/fhir/igtools/publisher/xig/XIGRenderer.java +++ b/org.hl7.fhir.publisher.core/src/main/java/org/hl7/fhir/igtools/publisher/xig/XIGRenderer.java @@ -337,7 +337,7 @@ public boolean isDatatype(String typeSimple) { @Override public boolean isPrimitiveType(String name) { - return new ContextUtilities(info.getCtxt()).isPrimitiveDatatype(name); + return info.getCtxt().isPrimitiveType(name); } diff --git a/org.hl7.fhir.publisher.core/src/main/java/org/hl7/fhir/igtools/renderers/CanonicalRenderer.java b/org.hl7.fhir.publisher.core/src/main/java/org/hl7/fhir/igtools/renderers/CanonicalRenderer.java index 7d7c9495..22622f00 100644 --- a/org.hl7.fhir.publisher.core/src/main/java/org/hl7/fhir/igtools/renderers/CanonicalRenderer.java +++ b/org.hl7.fhir.publisher.core/src/main/java/org/hl7/fhir/igtools/renderers/CanonicalRenderer.java @@ -1,5 +1,6 @@ package org.hl7.fhir.igtools.renderers; +import java.util.ArrayList; import java.util.List; import java.util.Set; @@ -8,11 +9,15 @@ import org.hl7.fhir.igtools.publisher.SpecMapManager; import org.hl7.fhir.r5.context.IWorkerContext; import org.hl7.fhir.r5.model.CanonicalResource; +import org.hl7.fhir.r5.model.ContactDetail; +import org.hl7.fhir.r5.model.ContactPoint; +import org.hl7.fhir.r5.model.ContactPoint.ContactPointSystem; import org.hl7.fhir.r5.model.DateTimeType; import org.hl7.fhir.r5.model.Enumerations.PublicationStatus; import org.hl7.fhir.r5.renderers.DataRenderer; import org.hl7.fhir.r5.renderers.utils.RenderingContext; import org.hl7.fhir.r5.utils.ToolingExtensions; +import org.hl7.fhir.utilities.CommaSeparatedStringBuilder; import org.hl7.fhir.utilities.MarkDownProcessor; import org.hl7.fhir.utilities.Utilities; import org.hl7.fhir.utilities.npm.NpmPackage; @@ -81,7 +86,7 @@ private void genSummaryCore1(StringBuilder b, Set rows) { } if (hasSummaryRow(rows, "publisher")) { if (cr.hasPublisher()) - b.append(" "+translate("cr.summary", "Publisher")+":"+Utilities.escapeXml(gt(cr.getPublisherElement()))+"\r\n"); + b.append(" "+translate("cr.summary", "Publisher")+":"+buildPublisherLinks(cr)+"\r\n"); } if (hasSummaryRow(rows, "committee")) { if (cr.hasExtension(ToolingExtensions.EXT_WORKGROUP)) { @@ -100,6 +105,55 @@ private void genSummaryCore1(StringBuilder b, Set rows) { } } + private String buildPublisherLinks(CanonicalResource cr) { + CommaSeparatedStringBuilder b = new CommaSeparatedStringBuilder(". "); + boolean useName = false; + for (ContactDetail cd : cr.getContact()) { + if (!cd.hasName()) { + useName = true; + } + } + if (!useName) { + b.append(Utilities.escapeXml(cr.getPublisher())); + } + for (ContactDetail cd : cr.getContact()) { + String name = cd.hasName() ? cd.getName() : cr.getPublisher(); + b.append(renderContact(name, cd.getTelecom())); + } + return b.toString(); + } + + private String renderContact(String name, List telecom) { + List urls = new ArrayList<>(); + for (ContactPoint t : telecom) { + if (t.getSystem() == ContactPointSystem.URL && t.hasValue()) { + urls.add(t.getValue()); + } + } + StringBuilder b = new StringBuilder(); + if (urls.size() == 1) { + b.append(""+Utilities.escapeXml(name)+""); + } else if (urls.size() == 1) { + b.append(Utilities.escapeXml(name)); + } + for (ContactPoint t : telecom) { + b.append(", "); + if (t.getSystem() == ContactPointSystem.URL && t.hasValue() && urls.size() > 1) { + b.append("Link"); + } + if (t.getSystem() == ContactPointSystem.EMAIL && t.hasValue()) { + b.append("Email"); + } + if (t.getSystem() == ContactPointSystem.PHONE && t.hasValue()) { + b.append(Utilities.escapeXml(t.getValue())); + } + if (t.getSystem() == ContactPointSystem.FAX && t.hasValue()) { + b.append("Fax:"+Utilities.escapeXml(t.getValue())); + } + } + return b.toString(); + } + protected boolean hasSummaryRow(Set rows, String name) { return rows.isEmpty() || rows.contains(name); } diff --git a/org.hl7.fhir.publisher.core/src/main/java/org/hl7/fhir/igtools/renderers/CrossViewRenderer.java b/org.hl7.fhir.publisher.core/src/main/java/org/hl7/fhir/igtools/renderers/CrossViewRenderer.java index f82f7b3f..08580c30 100644 --- a/org.hl7.fhir.publisher.core/src/main/java/org/hl7/fhir/igtools/renderers/CrossViewRenderer.java +++ b/org.hl7.fhir.publisher.core/src/main/java/org/hl7/fhir/igtools/renderers/CrossViewRenderer.java @@ -40,6 +40,8 @@ import org.hl7.fhir.r5.utils.FHIRPathEngine; import org.hl7.fhir.r5.utils.ResourceSorters.CanonicalResourceSortByUrl; import org.hl7.fhir.r5.utils.ToolingExtensions; +import org.hl7.fhir.utilities.HL7WorkGroups; +import org.hl7.fhir.utilities.HL7WorkGroups.HL7WorkGroup; import org.hl7.fhir.utilities.StandardsStatus; import org.hl7.fhir.utilities.Utilities; import org.hl7.fhir.utilities.validation.ValidationOptions; @@ -115,7 +117,6 @@ public class ExtensionDefinition extends StructureDefinitionNote { public List baseTypes = new ArrayList<>(); public List baseExtTypes = new ArrayList<>(); public String corePath; - private ContextUtilities cu; private FHIRPathEngine fpe; private List searchParams = new ArrayList<>(); @@ -126,7 +127,6 @@ public CrossViewRenderer(String canonical, String canonical2, IWorkerContext con this.worker = context; this.corePath = corePath; getBaseTypes(); - cu = new ContextUtilities(context); fpe = new FHIRPathEngine(context); } @@ -736,11 +736,11 @@ private Set getExtensionContext(StructureDefinitionContextComponent ctxt if (s.contains(".")) { s = s.substring(0, s.indexOf(".")); } - if (cu.isPrimitiveDatatype(s)) { + if (worker.isPrimitiveType(s)) { set.add("primitives"); s = null; } - if (cu.isDatatype(s)) { + if (worker.isDataType(s)) { set.add("datatypes"); } if (s != null) { @@ -794,6 +794,7 @@ private String buildExtensionTable(String type, List defini tr.td().b().ah(Utilities.pathURL(worker.getSpecUrl(), "defining-extensions.html#cardinality")).tx("Conf."); tr.td().b().tx("Type"); tr.td().b().ah(Utilities.pathURL(worker.getSpecUrl(), "defining-extensions.html")+"#context").tx("Context"); + tr.td().b().tx("WG"); tr.td().b().ah(Utilities.pathURL(worker.getSpecUrl(), "versions.html")+"#std-process").tx("Status"); if (context.getChangeVersion() != null) { tr.td().b().tx("Δ v"+context.getChangeVersion()); @@ -936,7 +937,6 @@ private boolean forAncestor(List ancestors, ExtensionDefinition sd) { private void genExtensionRow(XhtmlNode tbl, StructureDefinition ed) throws Exception { StandardsStatus status = ToolingExtensions.getStandardsStatus(ed); - String pstatus = ed.getStatus().toCode(); XhtmlNode tr; if (status == StandardsStatus.DEPRECATED) { tr = tbl.tr().style("background-color: #ffeeee"); @@ -995,20 +995,31 @@ else if (l > 60) { } } + String wg = ToolingExtensions.readStringExtension(ed, ToolingExtensions.EXT_WORKGROUP); + if (wg == null) { + tr.td(); + } else { + HL7WorkGroup wgd = HL7WorkGroups.find(wg); + if (wgd == null) { + tr.td().tx(wg); + } else { + tr.td().ah(wgd.getLink()).tx(wg); + } + } String fmm = ToolingExtensions.readStringExtension(ed, ToolingExtensions.EXT_FMM_LEVEL); td = tr.td(); if (status == StandardsStatus.NORMATIVE) { - td.ahWithText(pstatus+" / ", Utilities.pathURL(corePath, "versions.html")+"#std-process", "Normative", "Normative", null).attribute("class", "normative-flag"); + td.ahWithText("", Utilities.pathURL(corePath, "versions.html")+"#std-process", "Normative", "Normative", null).attribute("class", "normative-flag"); } else if (status == StandardsStatus.DEPRECATED) { - td.ahWithText(pstatus+" / ", Utilities.pathURL(corePath, "versions.html")+"#std-process", "Deprecated", "Deprecated", null).attribute("class", "deprecated-flag"); + td.ahWithText("", Utilities.pathURL(corePath, "versions.html")+"#std-process", "Deprecated", "Deprecated", null).attribute("class", "deprecated-flag"); } else if (status == StandardsStatus.INFORMATIVE) { - td.ahWithText(pstatus+" / ", Utilities.pathURL(corePath, "versions.html")+"#std-process", "Informative", "Informative", null).attribute("class", "informative-flag"); + td.ahWithText("", Utilities.pathURL(corePath, "versions.html")+"#std-process", "Informative", "Informative", null).attribute("class", "informative-flag"); } else if (status == StandardsStatus.DRAFT) { - td.ahWithText(pstatus+" / ", Utilities.pathURL(corePath, "versions.html")+"#std-process", "Draft", "Draft", null).attribute("class", "draft-flag"); + td.ahWithText("", Utilities.pathURL(corePath, "versions.html")+"#std-process", "Draft", "Draft", null).attribute("class", "draft-flag"); } else { - td.ahWithText(pstatus+" / ", Utilities.pathURL(corePath, "versions.html")+"#std-process", "Trial-Use", "Trial-Use", null).attribute("class", "trial-use-flag"); + td.ahWithText("", Utilities.pathURL(corePath, "versions.html")+"#std-process", "Trial-Use", "Trial-Use", null).attribute("class", "trial-use-flag"); } - tr.td().tx(Utilities.noString(fmm) ? "" : ": FMM"+fmm+""); + td.tx(Utilities.noString(fmm) ? "" : ": FMM"+fmm+""); if (context.getChangeVersion() != null) { renderStatusSummary(ed, tr.td(), "status"); } diff --git a/org.hl7.fhir.publisher.core/src/main/java/org/hl7/fhir/igtools/renderers/DBBuilder.java b/org.hl7.fhir.publisher.core/src/main/java/org/hl7/fhir/igtools/renderers/DBBuilder.java index b00d977a..ee07ea40 100644 --- a/org.hl7.fhir.publisher.core/src/main/java/org/hl7/fhir/igtools/renderers/DBBuilder.java +++ b/org.hl7.fhir.publisher.core/src/main/java/org/hl7/fhir/igtools/renderers/DBBuilder.java @@ -462,10 +462,10 @@ private void makeDesignationsTable(Connection con) throws SQLException { "Key integer NOT NULL,\r\n"+ "ResourceKey integer NOT NULL,\r\n"+ "ConceptKey integer NOT NULL,\r\n"+ - "UseSystem varchar NOT NULL,\r\n"+ - "UseCode varchar NOT NULL,\r\n"+ - "Lang varchar NOT NULL,\r\n"+ - "Value text NOT NULL,\r\n"+ + "UseSystem varchar NULL,\r\n"+ + "UseCode varchar NULL,\r\n"+ + "Lang varchar NULL,\r\n"+ + "Value text NULL,\r\n"+ "PRIMARY KEY (Key))\r\n"); } @@ -474,13 +474,13 @@ private void makeMappingsTable(Connection con) throws SQLException { stmt.execute("CREATE TABLE ConceptMappings (\r\n"+ "Key integer NOT NULL,\r\n"+ "ResourceKey integer NOT NULL,\r\n"+ - "SourceSystem varchar NOT NULL,\r\n"+ - "SourceVersion varchar NOT NULL,\r\n"+ - "SourceCode varchar NOT NULL,\r\n"+ - "Relationship varchar NOT NULL,\r\n"+ - "TargetSystem varchar NOT NULL,\r\n"+ - "TargetVersion varchar NOT NULL,\r\n"+ - "TargetCode varchar NOT NULL,\r\n"+ + "SourceSystem varchar NULL,\r\n"+ + "SourceVersion varchar NULL,\r\n"+ + "SourceCode varchar NULL,\r\n"+ + "Relationship varchar NULL,\r\n"+ + "TargetSystem varchar NULL,\r\n"+ + "TargetVersion varchar NULL,\r\n"+ + "TargetCode varchar NULL,\r\n"+ "PRIMARY KEY (Key))\r\n"); } diff --git a/org.hl7.fhir.publisher.core/src/main/java/org/hl7/fhir/igtools/templates/Template.java b/org.hl7.fhir.publisher.core/src/main/java/org/hl7/fhir/igtools/templates/Template.java index 1695717f..9bd9d19a 100644 --- a/org.hl7.fhir.publisher.core/src/main/java/org/hl7/fhir/igtools/templates/Template.java +++ b/org.hl7.fhir.publisher.core/src/main/java/org/hl7/fhir/igtools/templates/Template.java @@ -281,11 +281,11 @@ private void loadModifiedIg(ImplementationGuide modIg, ImplementationGuide ig) t int oc = ig.getDefinition().getResource().size(); int nc = modIg.getDefinition().getResource().size(); if (oc != nc) - throw new FHIRException("This template is not allowed to modify the resources ("+oc+"/"+nc+")"); + throw new FHIRException("Templates are not allowed to modify the resources ("+oc+"/"+nc+")"); for (ImplementationGuideDefinitionResourceComponent or : ig.getDefinition().getResource()) { ImplementationGuideDefinitionResourceComponent nr = getMatchingResource(modIg, or.getReference()); if (nr == null) - throw new FHIRException("This template is not allowed to modify the resources - didn't find '"+or.getReference()+"'"); + throw new FHIRException("Templates are not allowed to modify the resources - didn't find '"+or.getReference()+"'"); } ig.setDefinition(modIg.getDefinition()); ig.getManifest().setPage(modIg.getManifest().getPage()); diff --git a/pom.xml b/pom.xml index 56d9d3ed..899cc87e 100644 --- a/pom.xml +++ b/pom.xml @@ -24,7 +24,7 @@ 1.4.7-SNAPSHOT - 6.1.6 + 6.1.7 3.0.0-M5 5.2.1 4.11.0