From 1239bd2c24bc3ba51bdf893bdc24114ccb59f1fc Mon Sep 17 00:00:00 2001 From: dotasek Date: Fri, 14 Jul 2023 15:09:45 -0400 Subject: [PATCH 01/19] Add urn prefix to rref special cases --- .../main/java/org/hl7/fhir/igtools/publisher/HTMLInspector.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/org.hl7.fhir.publisher.core/src/main/java/org/hl7/fhir/igtools/publisher/HTMLInspector.java b/org.hl7.fhir.publisher.core/src/main/java/org/hl7/fhir/igtools/publisher/HTMLInspector.java index 3c7465ca6..c433674a9 100644 --- a/org.hl7.fhir.publisher.core/src/main/java/org/hl7/fhir/igtools/publisher/HTMLInspector.java +++ b/org.hl7.fhir.publisher.core/src/main/java/org/hl7/fhir/igtools/publisher/HTMLInspector.java @@ -677,7 +677,7 @@ private boolean checkResolveLink(String filename, Location loc, String path, Str } if (!resolved) { - if (rref.startsWith("http://") || rref.startsWith("https://") || rref.startsWith("ftp://") || rref.startsWith("tel:")) { + if (rref.startsWith("http://") || rref.startsWith("https://") || rref.startsWith("ftp://") || rref.startsWith("tel:") || rref.startsWith("urn:")) { resolved = true; if (specs != null) { for (SpecMapManager spec : specs) { From cccfd76fe7d73651f1def246c64a19cb6fb42eb2 Mon Sep 17 00:00:00 2001 From: Grahame Grieve Date: Sat, 22 Jul 2023 22:03:26 +1000 Subject: [PATCH 02/19] start work on Publisher documentation --- documentation.md | 76 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 documentation.md diff --git a/documentation.md b/documentation.md new file mode 100644 index 000000000..c8537649f --- /dev/null +++ b/documentation.md @@ -0,0 +1,76 @@ +# IG Publisher User Documentation + +## Introduction + +This is the documentation for the IG Publisher. + +## IG Requirements + +Supported Implementation Guides that the IG publisher can publish are always contained in directories that +contain a file named ```ig.ini``` with the following content: + +```ini +[IG] +ig = {path} +template = {template-id} +``` +Other entries are allowed, but not used by the IG-Publisher. ig - the path to the ImplementationGuide resource +that defines. + +You can either run the Publisher with a default directory of the folder that contains the ig.ini, or use the ```-ig``` parameter. + +See [Location?](todo) for documentation about the content of the IG to be built. + +## Command Line Parameters + +Run mode: +* ```-help``` - produce the command line help +* ```-go-publish`` - publication mode, see below` +* ```-gui``` - run the GUI (not really supported) + +Command line build mode parameters +* ```-ig``` {folder} - the folder that contains the IG +* ```-prompt``` - ask which ig to run (default to last) +* ```-source``` - run with standard template. this is publishing lite (just a set of conformance resource, IG publisher autobuilds an IG) ?supported +* ```-fhir-settings``` - see next section +* ```-debug``` - turn on debugging (extra logging, can be verbose) +* ```-proxy``` - proxy to use if it must be set manually (host:port) +* ```-tx``` - alternative tx server to tx.fhir.org (but still most be the same software, see [running your own copy of tx.fhir.org](https://confluence.hl7.org/display/FHIR/Running+your+own+copy+of+tx.fhir.org)) +* ```-no-network``` - turn of all network access - any attempt to use the network will generate an error (offline build mode) +* ```-no-sushi``` - don't run sushi before build IG (if it's there to be run) +* ```-generation-off``` - turn narrative generation off completely to make for faster local run time +* ```-no-narrative``` - comma list of resources (type/id) to not generate narrative for (e.g. faster run) +* ```-validation-off``` - turn validation off completely to make for faster local run time +* ```-no-validate``` - comma list of resources (type/id) to not validate (e.g. faster run) +* ```-resetTx``` - clear the local terminology cache before running +* ```-resetTxErrors``` - remove any errors from the local cache but leave other content there +* ```-auto-ig-build``` - used by the ci-build (see below) to switch on some ci-build integration features +* ```-simplifier``` - used by simplifier when running the IG publisher internally (under development) +* ```-jekyll``` - path to Jekyll (but use config, see below) +* ```-cacheVersion``` - ?not supported anymore? +* ```-spec``` - path to old spec file (deprecated and not supported) +* ```-publish``` - ?not supported anymore? + +## Configuration File + +## Go Publish + +(todo) + +## CI-build integration + +See https://github.com/FHIR/auto-ig-builder#quick-start-guide + +## UI mode + +This exists but isn't well documented. + +## Shell Integration + +### Windows + +To do + +### OSX + +To do From cee70f7c8cbbb55dbe45d23ccca645e1604111ee Mon Sep 17 00:00:00 2001 From: Grahame Grieve Date: Sat, 22 Jul 2023 22:04:24 +1000 Subject: [PATCH 03/19] add qa.txt for packages (for consistency) --- .../main/java/org/hl7/fhir/igtools/publisher/Publisher.java | 6 ++++++ 1 file changed, 6 insertions(+) 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 8ae768e1d..8b7b97153 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 @@ -975,9 +975,13 @@ private void packageTemplate() throws IOException { Utilities.createDirectory(outputDir); long startTime = System.nanoTime(); JsonObject qaJson = new JsonObject(); + StringBuilder txt = new StringBuilder(); qaJson.add("url", templateInfo.asString("canonical")); + txt.append("url = "+templateInfo.asString("canonical")+"\r\n"); qaJson.add("package-id", templateInfo.asString("name")); + txt.append("package-id = "+templateInfo.asString("name")+"\r\n"); qaJson.add("ig-ver", templateInfo.asString("version")); + txt.append("ig-ver = "+templateInfo.asString("version")+"\r\n"); qaJson.add("date", new SimpleDateFormat("EEE, dd MMM, yyyy HH:mm:ss Z", new Locale("en", "US")).format(execTime.getTime())); qaJson.add("version", Constants.VERSION); qaJson.add("tool", Constants.VERSION+" ("+ToolsVersion.TOOLS_VERSION+")"); @@ -999,10 +1003,12 @@ private void packageTemplate() throws IOException { } catch (Exception e) { e.printStackTrace(); qaJson.add("exception", e.getMessage()); + txt.append("exception = "+e.getMessage()+"\r\n"); } long endTime = System.nanoTime(); String json = org.hl7.fhir.utilities.json.parser.JsonParser.compose(qaJson, true); TextFile.stringToFile(json, Utilities.path(outputDir, "qa.json"), false); + TextFile.stringToFile(txt.toString(), Utilities.path(outputDir, "qa.txt"), false); Utilities.createDirectory(tempDir); ZipGenerator zip = new ZipGenerator(Utilities.path(tempDir, "full-ig.zip")); From d18c6029786422c87f94fc88770f4348d9f0ede9 Mon Sep 17 00:00:00 2001 From: Grahame Grieve Date: Sat, 22 Jul 2023 22:04:55 +1000 Subject: [PATCH 04/19] Fix bug where dicom package grabs all unknown urls --- .../hl7/fhir/igtools/publisher/SpecMapManager.java | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) 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 134b4ceb4..2e6f41736 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 @@ -185,7 +185,16 @@ public String getPath(String url, String def, String rt, String id) throws FHIRE } case Examples: return str(spec, "webUrl")+"/"+rt.toLowerCase()+"-"+id.toLowerCase()+".html"; - case DICOM: return url; + case DICOM: + try { + if (pi.hasFile("package", Utilities.urlTail(url)+"json") || pi.hasCanonical(url)) { + return url; + } else { + return null; + } + } catch (IOException e) { + return null; + } } } if (url.matches(Constants.URI_REGEX)) { From 39244056e9883485f6795795863eea5772b31493 Mon Sep 17 00:00:00 2001 From: Grahame Grieve Date: Sat, 22 Jul 2023 22:05:25 +1000 Subject: [PATCH 05/19] fix rendering issue --- .../fhir/igtools/renderers/StructureDefinitionRenderer.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/org.hl7.fhir.publisher.core/src/main/java/org/hl7/fhir/igtools/renderers/StructureDefinitionRenderer.java b/org.hl7.fhir.publisher.core/src/main/java/org/hl7/fhir/igtools/renderers/StructureDefinitionRenderer.java index 5b295f174..d59ba0cb1 100644 --- a/org.hl7.fhir.publisher.core/src/main/java/org/hl7/fhir/igtools/renderers/StructureDefinitionRenderer.java +++ b/org.hl7.fhir.publisher.core/src/main/java/org/hl7/fhir/igtools/renderers/StructureDefinitionRenderer.java @@ -1501,7 +1501,8 @@ private StringBuilder describeJson(ElementDefinition d) { private String describeObligations(ElementDefinition d, boolean root) throws IOException { ObligationsRenderer obr = new ObligationsRenderer(corePath, sd, d.getPath(), gen, this, sdr); - obr.seeObligations(d.getExtension()); + obr.seeObligations(d.getExtensionsByUrl(ToolingExtensions.EXT_OBLIGATION)); + obr.seeRootObligations(d.getId(), sd.getExtensionsByUrl(ToolingExtensions.EXT_OBLIGATION)); if (obr.hasObligations() || (root && (sd.hasExtension(ToolingExtensions.EXT_OBLIGATION_PROFILE_FLAG) || sd.hasExtension(ToolingExtensions.EXT_OBLIGATION_INHERITS)))) { StringBuilder s = new StringBuilder(); XhtmlNode ul = new XhtmlNode(NodeType.Element, "ul"); From f54550ac8f49bfddea694a8f144aaa508247d86f Mon Sep 17 00:00:00 2001 From: Grahame Grieve Date: Sat, 22 Jul 2023 22:05:40 +1000 Subject: [PATCH 06/19] refactor all guides tests --- .../src/test/java/tests/AllGuidesTests.java | 11 ++++------- pom.xml | 2 +- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/org.hl7.fhir.publisher.core/src/test/java/tests/AllGuidesTests.java b/org.hl7.fhir.publisher.core/src/test/java/tests/AllGuidesTests.java index 30f6a97fc..653dbca99 100644 --- a/org.hl7.fhir.publisher.core/src/test/java/tests/AllGuidesTests.java +++ b/org.hl7.fhir.publisher.core/src/test/java/tests/AllGuidesTests.java @@ -49,16 +49,13 @@ private void testIg(String id, String path) throws Exception { System.out.println("===== Analysis ======================================================================"); // to make diff programs easy to run - IOUtils.copy(new FileInputStream(Utilities.path(FhirSettings.getTestIgsPath(), id, "output", "qa.json")), new FileOutputStream(Utilities.path(FhirSettings.getTestIgsPath(), "records", id+"-qa-gen.json"))); - IOUtils.copy(new FileInputStream(Utilities.path(FhirSettings.getTestIgsPath(), id, "output", "qa.html")), new FileOutputStream(Utilities.path(FhirSettings.getTestIgsPath(), "records", id+"-qa-gen.html"))); - if (new File(Utilities.path(FhirSettings.getTestIgsPath(), id, "output", "qa.txt")).exists()) { - IOUtils.copy(new FileInputStream(Utilities.path(FhirSettings.getTestIgsPath(), id, "output", "qa.txt")), new FileOutputStream(Utilities.path(FhirSettings.getTestIgsPath(), "records", id+"-qa-gen.txt"))); - } + IOUtils.copy(new FileInputStream(Utilities.path(FhirSettings.getTestIgsPath(), id, "output", "qa.json")), new FileOutputStream(Utilities.path(FhirSettings.getTestIgsPath(), "records", "json", id+"-new.json"))); + IOUtils.copy(new FileInputStream(Utilities.path(FhirSettings.getTestIgsPath(), id, "output", "qa.txt")), new FileOutputStream(Utilities.path(FhirSettings.getTestIgsPath(), "records", id+"-new.txt"))); JsonObject current = JsonParser.parseObject(new FileInputStream(Utilities.path(FhirSettings.getTestIgsPath(), id, "output", "qa.json"))); JsonObject previous = null; - if (new File(Utilities.path(FhirSettings.getTestIgsPath(), "records", id+"-qa.json")).exists()) { - previous = JsonParser.parseObject(new FileInputStream(Utilities.path(FhirSettings.getTestIgsPath(), "records", id+"-qa.json"))); + if (new File(Utilities.path(FhirSettings.getTestIgsPath(), "records", "json", id+"-old.json")).exists()) { + previous = JsonParser.parseObject(new FileInputStream(Utilities.path(FhirSettings.getTestIgsPath(), "records", "json", id+"-old.json"))); } else { previous = new JsonObject(); } diff --git a/pom.xml b/pom.xml index e0f8a2d5f..a4649219f 100644 --- a/pom.xml +++ b/pom.xml @@ -24,7 +24,7 @@ 1.3.24-SNAPSHOT - 6.0.21 + 6.0.22-SNAPSHOT 3.0.0-M5 5.2.1 4.10.0 From 87c60448ffedacfe8e4fe008a2ca6aa3df532752 Mon Sep 17 00:00:00 2001 From: Grahame Grieve Date: Sat, 22 Jul 2023 22:09:09 +1000 Subject: [PATCH 07/19] release notes --- RELEASE_NOTES.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index e69de29bb..c341a5d9c 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -0,0 +1,17 @@ + +* Loader: Add support for private NPM registries requiring authentication +* Loader: Workaround ClinicalImpression definition problem in core spec +* Version Conversion: Fix missing extensions when converting value set properties +* Version Conversion: ExampleScenario conversion (R4/R5) significantly bulked up +* Terminology System: Add provisional support for alternate codes +* Validator: Don't check FHIRPaths on differentials - not enough type info to test reliably +* Validator: Fix bugs in FHIRPath handling of logical models +* Validator: Fix minor bugs in type handling for Logical Models and R3 Profile validation +* Validator: Add value set qa checking +* Validator: Fix up bi-di warning message +* Validator: Fix to get context variables right when running invariants + fix for parent not always being populated + check type in derived profiles +* Validator: Fix checking FHIRPath statements on inner elements of type slices +* Validator: Fix scan of naming systems (error validating namespaces) +* Validator: Fix issue checking invariant expressions in R5 +* Validator: FHIRPath: Strip returned IIdType of qualifier, version, and resourceType +* Renderer: Fix obligation rendering message From 42f968774b41fb470bbfc9975d6489e9ff9535a4 Mon Sep 17 00:00:00 2001 From: dotasek Date: Sat, 22 Jul 2023 18:09:31 -0400 Subject: [PATCH 08/19] Bump core to 6.0.22 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index a4649219f..13f108e5c 100644 --- a/pom.xml +++ b/pom.xml @@ -24,7 +24,7 @@ 1.3.24-SNAPSHOT - 6.0.22-SNAPSHOT + 6.0.22 3.0.0-M5 5.2.1 4.10.0 From 43257b1e940a1f28709777eda1386ae0044d25df Mon Sep 17 00:00:00 2001 From: markiantorno Date: Sat, 22 Jul 2023 22:33:36 +0000 Subject: [PATCH 09/19] Release: v1.3.24 * Loader: Add support for private NPM registries requiring authentication * Loader: Workaround ClinicalImpression definition problem in core spec * Version Conversion: Fix missing extensions when converting value set properties * Version Conversion: ExampleScenario conversion (R4/R5) significantly bulked up * Terminology System: Add provisional support for alternate codes * Validator: Don't check FHIRPaths on differentials - not enough type info to test reliably * Validator: Fix bugs in FHIRPath handling of logical models * Validator: Fix minor bugs in type handling for Logical Models and R3 Profile validation * Validator: Add value set qa checking * Validator: Fix up bi-di warning message * Validator: Fix to get context variables right when running invariants + fix for parent not always being populated + check type in derived profiles * Validator: Fix checking FHIRPath statements on inner elements of type slices * Validator: Fix scan of naming systems (error validating namespaces) * Validator: Fix issue checking invariant expressions in R5 * Validator: FHIRPath: Strip returned IIdType of qualifier, version, and resourceType * Renderer: Fix obligation rendering message ***NO_CI*** --- org.hl7.fhir.publisher.cli/pom.xml | 2 +- org.hl7.fhir.publisher.core/pom.xml | 2 +- pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/org.hl7.fhir.publisher.cli/pom.xml b/org.hl7.fhir.publisher.cli/pom.xml index 677360690..1f26bc1ab 100644 --- a/org.hl7.fhir.publisher.cli/pom.xml +++ b/org.hl7.fhir.publisher.cli/pom.xml @@ -5,7 +5,7 @@ org.hl7.fhir.publisher org.hl7.fhir.publisher - 1.3.24-SNAPSHOT + 1.3.24 ../pom.xml 4.0.0 diff --git a/org.hl7.fhir.publisher.core/pom.xml b/org.hl7.fhir.publisher.core/pom.xml index bc9a88d18..cd77f759d 100644 --- a/org.hl7.fhir.publisher.core/pom.xml +++ b/org.hl7.fhir.publisher.core/pom.xml @@ -5,7 +5,7 @@ org.hl7.fhir.publisher org.hl7.fhir.publisher - 1.3.24-SNAPSHOT + 1.3.24 ../pom.xml 4.0.0 diff --git a/pom.xml b/pom.xml index 13f108e5c..63ed7f699 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ - 1.3.24-SNAPSHOT + 1.3.24 6.0.22 From 096b921e8ca49e0d7ba01b4d8552d3f91dd12fdb Mon Sep 17 00:00:00 2001 From: markiantorno Date: Sat, 22 Jul 2023 22:45:26 +0000 Subject: [PATCH 10/19] Updating version to: 1.3.25-SNAPSHOT --- RELEASE_NOTES.md | 17 ----------------- org.hl7.fhir.publisher.cli/pom.xml | 2 +- org.hl7.fhir.publisher.core/pom.xml | 2 +- pom.xml | 2 +- 4 files changed, 3 insertions(+), 20 deletions(-) diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index c341a5d9c..e69de29bb 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -1,17 +0,0 @@ - -* Loader: Add support for private NPM registries requiring authentication -* Loader: Workaround ClinicalImpression definition problem in core spec -* Version Conversion: Fix missing extensions when converting value set properties -* Version Conversion: ExampleScenario conversion (R4/R5) significantly bulked up -* Terminology System: Add provisional support for alternate codes -* Validator: Don't check FHIRPaths on differentials - not enough type info to test reliably -* Validator: Fix bugs in FHIRPath handling of logical models -* Validator: Fix minor bugs in type handling for Logical Models and R3 Profile validation -* Validator: Add value set qa checking -* Validator: Fix up bi-di warning message -* Validator: Fix to get context variables right when running invariants + fix for parent not always being populated + check type in derived profiles -* Validator: Fix checking FHIRPath statements on inner elements of type slices -* Validator: Fix scan of naming systems (error validating namespaces) -* Validator: Fix issue checking invariant expressions in R5 -* Validator: FHIRPath: Strip returned IIdType of qualifier, version, and resourceType -* Renderer: Fix obligation rendering message diff --git a/org.hl7.fhir.publisher.cli/pom.xml b/org.hl7.fhir.publisher.cli/pom.xml index 1f26bc1ab..1096cd836 100644 --- a/org.hl7.fhir.publisher.cli/pom.xml +++ b/org.hl7.fhir.publisher.cli/pom.xml @@ -5,7 +5,7 @@ org.hl7.fhir.publisher org.hl7.fhir.publisher - 1.3.24 + 1.3.25-SNAPSHOT ../pom.xml 4.0.0 diff --git a/org.hl7.fhir.publisher.core/pom.xml b/org.hl7.fhir.publisher.core/pom.xml index cd77f759d..17625e86c 100644 --- a/org.hl7.fhir.publisher.core/pom.xml +++ b/org.hl7.fhir.publisher.core/pom.xml @@ -5,7 +5,7 @@ org.hl7.fhir.publisher org.hl7.fhir.publisher - 1.3.24 + 1.3.25-SNAPSHOT ../pom.xml 4.0.0 diff --git a/pom.xml b/pom.xml index 63ed7f699..e9e9b9e25 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ - 1.3.24 + 1.3.25-SNAPSHOT 6.0.22 From d8a82ad7784c7f726e917e2e3394d3b29ae51424 Mon Sep 17 00:00:00 2001 From: dotasek Date: Tue, 25 Jul 2023 12:31:23 -0400 Subject: [PATCH 11/19] Don't test twice in master-branch-pipeline.yml --- master-branch-pipeline.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/master-branch-pipeline.yml b/master-branch-pipeline.yml index e26dadd13..8ded30fdf 100644 --- a/master-branch-pipeline.yml +++ b/master-branch-pipeline.yml @@ -99,7 +99,7 @@ steps: inputs: mavenPomFile: '$(System.DefaultWorkingDirectory)/pom.xml' goals: deploy - options: '--settings $(System.DefaultWorkingDirectory)/settings.xml -DdeployToSonatype -e' + options: '--settings $(System.DefaultWorkingDirectory)/settings.xml -Dmaven.test.skip -DdeployToSonatype -e' publishJUnitResults: false # Deploy the SNAPSHOT artifact to GitHub packages. From c1c66265d5f3c3f76269f7fb8027a5dbdd01eadd Mon Sep 17 00:00:00 2001 From: dotasek Date: Wed, 26 Jul 2023 13:05:58 -0400 Subject: [PATCH 12/19] Fix invalid filename path check --- .../fhir/igtools/publisher/SpecMapManager.java | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) 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 2e6f41736..c43b2f8c6 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 @@ -22,6 +22,8 @@ import java.io.IOException; +import java.nio.file.InvalidPathException; +import java.nio.file.Paths; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Calendar; @@ -187,7 +189,10 @@ public String getPath(String url, String def, String rt, String id) throws FHIRE return str(spec, "webUrl")+"/"+rt.toLowerCase()+"-"+id.toLowerCase()+".html"; case DICOM: try { - if (pi.hasFile("package", Utilities.urlTail(url)+"json") || pi.hasCanonical(url)) { + final String fileName = Utilities.urlTail(url) + "json"; + + if ((isValidFilename(fileName) && pi.hasFile("package", fileName)) + || pi.hasCanonical(url)) { return url; } else { return null; @@ -214,6 +219,15 @@ public String getPath(String url, String def, String rt, String id) throws FHIRE return null; } + public boolean isValidFilename(String filename) { + try { + Paths.get(filename); + } catch (InvalidPathException e) { + return false; + } + return true; + } + // hack around things missing in spec.internals private String getSpecialPath(String url) { if ("http://hl7.org/fhir/ValueSet/iso3166-1-3".equals(url)) { From fea5cd1d63cce957523ba48c5944598ee0c41a5b Mon Sep 17 00:00:00 2001 From: Grahame Grieve Date: Thu, 27 Jul 2023 17:57:17 +1000 Subject: [PATCH 13/19] Compile fix --- .../publisher/CodeSystemValidator.java | 82 +++++++++++++++++++ .../hl7/fhir/igtools/publisher/Publisher.java | 49 ++++++----- pom.xml | 2 +- 3 files changed, 112 insertions(+), 21 deletions(-) create mode 100644 org.hl7.fhir.publisher.core/src/main/java/org/hl7/fhir/igtools/publisher/CodeSystemValidator.java diff --git a/org.hl7.fhir.publisher.core/src/main/java/org/hl7/fhir/igtools/publisher/CodeSystemValidator.java b/org.hl7.fhir.publisher.core/src/main/java/org/hl7/fhir/igtools/publisher/CodeSystemValidator.java new file mode 100644 index 000000000..d3552a9fd --- /dev/null +++ b/org.hl7.fhir.publisher.core/src/main/java/org/hl7/fhir/igtools/publisher/CodeSystemValidator.java @@ -0,0 +1,82 @@ +package org.hl7.fhir.igtools.publisher; + +/* + Copyright (c) 2011+, HL7, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, + are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name of HL7 nor the names of its contributors may be used to + endorse or promote products derived from this software without specific + prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + */ + + + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.hl7.fhir.r5.context.IWorkerContext; +import org.hl7.fhir.r5.model.CodeSystem; +import org.hl7.fhir.r5.model.CodeSystem.ConceptDefinitionComponent; +import org.hl7.fhir.r5.utils.XVerExtensionManager; +import org.hl7.fhir.utilities.validation.ValidationMessage; +import org.hl7.fhir.utilities.validation.ValidationMessage.IssueType; +import org.hl7.fhir.validation.BaseValidator; + +/** + * This is defunct, I think? All this checking happens in the main code system validator? + * + * @author grahamegrieve + * + */ +public class CodeSystemValidator extends BaseValidator { + + public CodeSystemValidator(IWorkerContext context, XVerExtensionManager xverManager) { + super(context, xverManager, false); + } + + public List validate(CodeSystem cs, boolean forBuild) { + List errors = new ArrayList(); + + // this is an invariant on CodeSystem, but the invariant is wrong in R3, and doesn't work + checkCodesUnique(cs, errors); + return errors; + } + + private void checkCodesUnique(CodeSystem cs, List errors) { + Set codes = new HashSet(); + checkCodes(codes, cs.getConcept(), "CodeSystem.where(id = '"+cs.getId()+"')", errors); + } + + private void checkCodes(Set codes, List list, String path, List errors) { + for (ConceptDefinitionComponent cc : list) { + String npath = path+".concept.where(code = '"+cc.getCode()+"')"; + if (codes.contains(cc.getCode())) { + rule(errors, NO_RULE_DATE, IssueType.BUSINESSRULE, npath, false, "Duplicate Code "+cc.getCode()); + } + codes.add(cc.getCode()); + checkCodes(codes, cc.getConcept(), npath, errors); + } + } +} \ No newline at end of file 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 8b7b97153..71e203b0a 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 @@ -354,7 +354,6 @@ import org.hl7.fhir.utilities.xml.XMLUtil; import org.hl7.fhir.utilities.xml.XmlEscaper; import org.hl7.fhir.validation.ValidatorUtils; -import org.hl7.fhir.validation.codesystem.CodeSystemValidator; import org.hl7.fhir.validation.instance.InstanceValidator; import org.hl7.fhir.validation.instance.utils.ValidatorHostContext; import org.hl7.fhir.validation.profile.ProfileValidator; @@ -1059,6 +1058,16 @@ private void processTxLog(String path) throws FileNotFoundException, IOException PrintStream f = new PrintStream(new FileOutputStream(path)); String title = "Terminology Server Log"; f.println(""+title+"

"+title+"

");
+      for (String s : tx.split("\\r?\\n|\\r")) {
+        if (s.startsWith("---") && s.endsWith("---")) {
+          f.println("

"); + String id = s.replace("-", "").trim(); + f.println("

"+id+"

"); + f.println("
");
+        } else {
+          f.println(s);
+        }
+      }
       f.print(tx);
       f.println("
"); f.close(); @@ -11321,14 +11330,14 @@ public static void main(String[] args) throws Exception { NpmPackage npm = pcm.loadPackage(p); System.out.println("OK: "+npm.name()+"#"+npm.version()+" for FHIR version(s) "+npm.fhirVersionList()+" with canonical "+npm.canonical()); } - } else if (hasNamedParam(args, "-dicom-gen")) { - DicomPackageBuilder pgen = new DicomPackageBuilder(); - pgen.setSource(getNamedParam(args, "src")); - pgen.setDest(getNamedParam(args, "dst")); - if (hasNamedParam(args, "-pattern")) { - pgen.setPattern(getNamedParam(args, "-pattern")); - } - pgen.execute(); +// } else if (hasNamedParam(args, "-dicom-gen")) { +// DicomPackageBuilder pgen = new DicomPackageBuilder(); +// pgen.setSource(getNamedParam(args, "src")); +// pgen.setDest(getNamedParam(args, "dst")); +// if (hasNamedParam(args, "-pattern")) { +// pgen.setPattern(getNamedParam(args, "-pattern")); +// } +// pgen.execute(); } else if (hasNamedParam(args, "-help") || hasNamedParam(args, "-?") || hasNamedParam(args, "/?") || hasNamedParam(args, "?") || args.length == 0) { System.out.println(""); System.out.println("To use this publisher to publish a FHIR Implementation Guide, run "); @@ -11372,16 +11381,16 @@ public static void main(String[] args) throws Exception { System.out.println("or you can configure the proxy using -Dhttp.proxyHost= -Dhttp.proxyPort= -Dhttps.proxyHost= -Dhttps.proxyPort="); System.out.println(""); System.out.println("For additional information, see https://confluence.hl7.org/display/FHIR/IG+Publisher+Documentation"); - } else if (hasNamedParam(args, "-convert")) { - // convert a igpack.zip to a package.tgz - IGPack2NpmConvertor conv = new IGPack2NpmConvertor(); - conv.setSource(getNamedParam(args, "-source")); - conv.setDest(getNamedParam(args, "-dest")); - conv.setPackageId(getNamedParam(args, "-npm-name")); - conv.setVersionIg(getNamedParam(args, "-version")); - conv.setLicense(getNamedParam(args, "-license")); - conv.setWebsite(getNamedParam(args, "-website")); - conv.execute(); +// } else if (hasNamedParam(args, "-convert")) { +// // convert a igpack.zip to a package.tgz +// IGPack2NpmConvertor conv = new IGPack2NpmConvertor(); +// conv.setSource(getNamedParam(args, "-source")); +// conv.setDest(getNamedParam(args, "-dest")); +// conv.setPackageId(getNamedParam(args, "-npm-name")); +// conv.setVersionIg(getNamedParam(args, "-version")); +// conv.setLicense(getNamedParam(args, "-license")); +// conv.setWebsite(getNamedParam(args, "-website")); +// conv.execute(); } else if (hasNamedParam(args, "-delete-current")) { if (!args[0].equals("-delete-current")) { throw new Error("-delete-current must have the format -delete-current {root}/{realm}/{code} -history {history} (first argument is not -delete-current)"); @@ -11549,7 +11558,7 @@ public static void main(String[] args) throws Exception { self.setSourceDir(getNamedParam(args, "-source")); self.setDestDir(getNamedParam(args, "-destination")); self.specifiedVersion = getNamedParam(args, "-version"); - } else if(!hasNamedParam(args, "-ig") && args.length == 1 && new File(args[0]).exists()) { + } else if (!hasNamedParam(args, "-ig") && args.length == 1 && new File(args[0]).exists()) { self.setConfigFile(determineActualIG(args[0], IGBuildMode.MANUAL)); } else if (hasNamedParam(args, "-prompt")) { IniFile ini = new IniFile("publisher.ini"); diff --git a/pom.xml b/pom.xml index e9e9b9e25..8c7fb4e95 100644 --- a/pom.xml +++ b/pom.xml @@ -24,7 +24,7 @@ 1.3.25-SNAPSHOT - 6.0.22 + 6.0.23-SNAPSHOT 3.0.0-M5 5.2.1 4.10.0 From 0f5f912979117f840f378423ddd62d50885ea237 Mon Sep 17 00:00:00 2001 From: Grahame Grieve Date: Thu, 27 Jul 2023 23:45:49 +1000 Subject: [PATCH 14/19] Compile fix (#728) Co-authored-by: Grahame Grieve --- .../publisher/CodeSystemValidator.java | 82 +++++++++++++++++++ .../hl7/fhir/igtools/publisher/Publisher.java | 49 ++++++----- pom.xml | 2 +- 3 files changed, 112 insertions(+), 21 deletions(-) create mode 100644 org.hl7.fhir.publisher.core/src/main/java/org/hl7/fhir/igtools/publisher/CodeSystemValidator.java diff --git a/org.hl7.fhir.publisher.core/src/main/java/org/hl7/fhir/igtools/publisher/CodeSystemValidator.java b/org.hl7.fhir.publisher.core/src/main/java/org/hl7/fhir/igtools/publisher/CodeSystemValidator.java new file mode 100644 index 000000000..d3552a9fd --- /dev/null +++ b/org.hl7.fhir.publisher.core/src/main/java/org/hl7/fhir/igtools/publisher/CodeSystemValidator.java @@ -0,0 +1,82 @@ +package org.hl7.fhir.igtools.publisher; + +/* + Copyright (c) 2011+, HL7, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, + are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name of HL7 nor the names of its contributors may be used to + endorse or promote products derived from this software without specific + prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + */ + + + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.hl7.fhir.r5.context.IWorkerContext; +import org.hl7.fhir.r5.model.CodeSystem; +import org.hl7.fhir.r5.model.CodeSystem.ConceptDefinitionComponent; +import org.hl7.fhir.r5.utils.XVerExtensionManager; +import org.hl7.fhir.utilities.validation.ValidationMessage; +import org.hl7.fhir.utilities.validation.ValidationMessage.IssueType; +import org.hl7.fhir.validation.BaseValidator; + +/** + * This is defunct, I think? All this checking happens in the main code system validator? + * + * @author grahamegrieve + * + */ +public class CodeSystemValidator extends BaseValidator { + + public CodeSystemValidator(IWorkerContext context, XVerExtensionManager xverManager) { + super(context, xverManager, false); + } + + public List validate(CodeSystem cs, boolean forBuild) { + List errors = new ArrayList(); + + // this is an invariant on CodeSystem, but the invariant is wrong in R3, and doesn't work + checkCodesUnique(cs, errors); + return errors; + } + + private void checkCodesUnique(CodeSystem cs, List errors) { + Set codes = new HashSet(); + checkCodes(codes, cs.getConcept(), "CodeSystem.where(id = '"+cs.getId()+"')", errors); + } + + private void checkCodes(Set codes, List list, String path, List errors) { + for (ConceptDefinitionComponent cc : list) { + String npath = path+".concept.where(code = '"+cc.getCode()+"')"; + if (codes.contains(cc.getCode())) { + rule(errors, NO_RULE_DATE, IssueType.BUSINESSRULE, npath, false, "Duplicate Code "+cc.getCode()); + } + codes.add(cc.getCode()); + checkCodes(codes, cc.getConcept(), npath, errors); + } + } +} \ No newline at end of file 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 8b7b97153..71e203b0a 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 @@ -354,7 +354,6 @@ import org.hl7.fhir.utilities.xml.XMLUtil; import org.hl7.fhir.utilities.xml.XmlEscaper; import org.hl7.fhir.validation.ValidatorUtils; -import org.hl7.fhir.validation.codesystem.CodeSystemValidator; import org.hl7.fhir.validation.instance.InstanceValidator; import org.hl7.fhir.validation.instance.utils.ValidatorHostContext; import org.hl7.fhir.validation.profile.ProfileValidator; @@ -1059,6 +1058,16 @@ private void processTxLog(String path) throws FileNotFoundException, IOException PrintStream f = new PrintStream(new FileOutputStream(path)); String title = "Terminology Server Log"; f.println(""+title+"

"+title+"

");
+      for (String s : tx.split("\\r?\\n|\\r")) {
+        if (s.startsWith("---") && s.endsWith("---")) {
+          f.println("

"); + String id = s.replace("-", "").trim(); + f.println("

"+id+"

"); + f.println("
");
+        } else {
+          f.println(s);
+        }
+      }
       f.print(tx);
       f.println("
"); f.close(); @@ -11321,14 +11330,14 @@ public static void main(String[] args) throws Exception { NpmPackage npm = pcm.loadPackage(p); System.out.println("OK: "+npm.name()+"#"+npm.version()+" for FHIR version(s) "+npm.fhirVersionList()+" with canonical "+npm.canonical()); } - } else if (hasNamedParam(args, "-dicom-gen")) { - DicomPackageBuilder pgen = new DicomPackageBuilder(); - pgen.setSource(getNamedParam(args, "src")); - pgen.setDest(getNamedParam(args, "dst")); - if (hasNamedParam(args, "-pattern")) { - pgen.setPattern(getNamedParam(args, "-pattern")); - } - pgen.execute(); +// } else if (hasNamedParam(args, "-dicom-gen")) { +// DicomPackageBuilder pgen = new DicomPackageBuilder(); +// pgen.setSource(getNamedParam(args, "src")); +// pgen.setDest(getNamedParam(args, "dst")); +// if (hasNamedParam(args, "-pattern")) { +// pgen.setPattern(getNamedParam(args, "-pattern")); +// } +// pgen.execute(); } else if (hasNamedParam(args, "-help") || hasNamedParam(args, "-?") || hasNamedParam(args, "/?") || hasNamedParam(args, "?") || args.length == 0) { System.out.println(""); System.out.println("To use this publisher to publish a FHIR Implementation Guide, run "); @@ -11372,16 +11381,16 @@ public static void main(String[] args) throws Exception { System.out.println("or you can configure the proxy using -Dhttp.proxyHost= -Dhttp.proxyPort= -Dhttps.proxyHost= -Dhttps.proxyPort="); System.out.println(""); System.out.println("For additional information, see https://confluence.hl7.org/display/FHIR/IG+Publisher+Documentation"); - } else if (hasNamedParam(args, "-convert")) { - // convert a igpack.zip to a package.tgz - IGPack2NpmConvertor conv = new IGPack2NpmConvertor(); - conv.setSource(getNamedParam(args, "-source")); - conv.setDest(getNamedParam(args, "-dest")); - conv.setPackageId(getNamedParam(args, "-npm-name")); - conv.setVersionIg(getNamedParam(args, "-version")); - conv.setLicense(getNamedParam(args, "-license")); - conv.setWebsite(getNamedParam(args, "-website")); - conv.execute(); +// } else if (hasNamedParam(args, "-convert")) { +// // convert a igpack.zip to a package.tgz +// IGPack2NpmConvertor conv = new IGPack2NpmConvertor(); +// conv.setSource(getNamedParam(args, "-source")); +// conv.setDest(getNamedParam(args, "-dest")); +// conv.setPackageId(getNamedParam(args, "-npm-name")); +// conv.setVersionIg(getNamedParam(args, "-version")); +// conv.setLicense(getNamedParam(args, "-license")); +// conv.setWebsite(getNamedParam(args, "-website")); +// conv.execute(); } else if (hasNamedParam(args, "-delete-current")) { if (!args[0].equals("-delete-current")) { throw new Error("-delete-current must have the format -delete-current {root}/{realm}/{code} -history {history} (first argument is not -delete-current)"); @@ -11549,7 +11558,7 @@ public static void main(String[] args) throws Exception { self.setSourceDir(getNamedParam(args, "-source")); self.setDestDir(getNamedParam(args, "-destination")); self.specifiedVersion = getNamedParam(args, "-version"); - } else if(!hasNamedParam(args, "-ig") && args.length == 1 && new File(args[0]).exists()) { + } else if (!hasNamedParam(args, "-ig") && args.length == 1 && new File(args[0]).exists()) { self.setConfigFile(determineActualIG(args[0], IGBuildMode.MANUAL)); } else if (hasNamedParam(args, "-prompt")) { IniFile ini = new IniFile("publisher.ini"); diff --git a/pom.xml b/pom.xml index e9e9b9e25..8c7fb4e95 100644 --- a/pom.xml +++ b/pom.xml @@ -24,7 +24,7 @@ 1.3.25-SNAPSHOT - 6.0.22 + 6.0.23-SNAPSHOT 3.0.0-M5 5.2.1 4.10.0 From a410a3829f9234f64c100fc7162c170016a7f805 Mon Sep 17 00:00:00 2001 From: dotasek Date: Thu, 27 Jul 2023 09:47:36 -0400 Subject: [PATCH 15/19] Update RELEASE_NOTES.md --- RELEASE_NOTES.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index e69de29bb..ff9b7fcd5 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -0,0 +1,3 @@ +* Update of core libraries to 6.0.23 +* Fixed checks for non-existent DICOM files on Windows +* Fixed inspection check for urn in link From dace138701e575da6fad656b4527bcebb5c703fe Mon Sep 17 00:00:00 2001 From: dotasek Date: Thu, 27 Jul 2023 10:33:29 -0400 Subject: [PATCH 16/19] Bump core dependency to 6.0.23 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 8c7fb4e95..0e53ace62 100644 --- a/pom.xml +++ b/pom.xml @@ -24,7 +24,7 @@ 1.3.25-SNAPSHOT - 6.0.23-SNAPSHOT + 6.0.23 3.0.0-M5 5.2.1 4.10.0 From f3caba05f705d437a3c61a8b793d29a8221b560c Mon Sep 17 00:00:00 2001 From: markiantorno Date: Thu, 27 Jul 2023 15:09:43 +0000 Subject: [PATCH 17/19] Release: v1.3.25 * Update of core libraries to 6.0.23 * Fixed checks for non-existent DICOM files on Windows * Fixed inspection check for urn in link ***NO_CI*** --- org.hl7.fhir.publisher.cli/pom.xml | 2 +- org.hl7.fhir.publisher.core/pom.xml | 2 +- pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/org.hl7.fhir.publisher.cli/pom.xml b/org.hl7.fhir.publisher.cli/pom.xml index 1096cd836..a7d84f712 100644 --- a/org.hl7.fhir.publisher.cli/pom.xml +++ b/org.hl7.fhir.publisher.cli/pom.xml @@ -5,7 +5,7 @@ org.hl7.fhir.publisher org.hl7.fhir.publisher - 1.3.25-SNAPSHOT + 1.3.25 ../pom.xml 4.0.0 diff --git a/org.hl7.fhir.publisher.core/pom.xml b/org.hl7.fhir.publisher.core/pom.xml index 17625e86c..f1496869b 100644 --- a/org.hl7.fhir.publisher.core/pom.xml +++ b/org.hl7.fhir.publisher.core/pom.xml @@ -5,7 +5,7 @@ org.hl7.fhir.publisher org.hl7.fhir.publisher - 1.3.25-SNAPSHOT + 1.3.25 ../pom.xml 4.0.0 diff --git a/pom.xml b/pom.xml index 0e53ace62..aacb6cebc 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ - 1.3.25-SNAPSHOT + 1.3.25 6.0.23 From d8cfaa7a726f8d897593f8ae5517eeab537468d9 Mon Sep 17 00:00:00 2001 From: markiantorno Date: Thu, 27 Jul 2023 15:22:40 +0000 Subject: [PATCH 18/19] Updating version to: 1.3.26-SNAPSHOT --- RELEASE_NOTES.md | 3 --- org.hl7.fhir.publisher.cli/pom.xml | 2 +- org.hl7.fhir.publisher.core/pom.xml | 2 +- pom.xml | 2 +- 4 files changed, 3 insertions(+), 6 deletions(-) diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index ff9b7fcd5..e69de29bb 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -1,3 +0,0 @@ -* Update of core libraries to 6.0.23 -* Fixed checks for non-existent DICOM files on Windows -* Fixed inspection check for urn in link diff --git a/org.hl7.fhir.publisher.cli/pom.xml b/org.hl7.fhir.publisher.cli/pom.xml index a7d84f712..e5b5a9ab7 100644 --- a/org.hl7.fhir.publisher.cli/pom.xml +++ b/org.hl7.fhir.publisher.cli/pom.xml @@ -5,7 +5,7 @@ org.hl7.fhir.publisher org.hl7.fhir.publisher - 1.3.25 + 1.3.26-SNAPSHOT ../pom.xml 4.0.0 diff --git a/org.hl7.fhir.publisher.core/pom.xml b/org.hl7.fhir.publisher.core/pom.xml index f1496869b..b05b8ad0f 100644 --- a/org.hl7.fhir.publisher.core/pom.xml +++ b/org.hl7.fhir.publisher.core/pom.xml @@ -5,7 +5,7 @@ org.hl7.fhir.publisher org.hl7.fhir.publisher - 1.3.25 + 1.3.26-SNAPSHOT ../pom.xml 4.0.0 diff --git a/pom.xml b/pom.xml index aacb6cebc..48652a8d8 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ - 1.3.25 + 1.3.26-SNAPSHOT 6.0.23 From 23fbab77d15282d2e5cd32d809c26671a64e05f4 Mon Sep 17 00:00:00 2001 From: dotasek Date: Fri, 28 Jul 2023 14:38:05 -0400 Subject: [PATCH 19/19] Various GUI fixes Refactors UI initialization Adds scrollpane for output resizing Fixes button alignment Allows selection of IG directories --- .../hl7/fhir/igtools/publisher/Publisher.java | 22 +- .../fhir/igtools/ui/GraphicalPublisher.java | 6 + .../hl7/fhir/igtools/ui/IGPublisherFrame.java | 327 ++++++++++-------- .../src/main/resources/favicon.ico | Bin 0 -> 102134 bytes 4 files changed, 194 insertions(+), 161 deletions(-) create mode 100644 org.hl7.fhir.publisher.core/src/main/resources/favicon.ico 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 71e203b0a..4db9383cb 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 @@ -20,7 +20,6 @@ * #L% */ -import java.awt.EventQueue; import java.io.BufferedReader; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; @@ -63,7 +62,6 @@ import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; -import javax.swing.UIManager; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; @@ -76,7 +74,7 @@ import org.apache.commons.lang3.NotImplementedException; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.SystemUtils; -import org.apache.xmlbeans.XmlOptionCharEscapeMap; + import org.checkerframework.checker.nullness.qual.NonNull; import org.hl7.fhir.convertors.advisors.impl.BaseAdvisor_10_50; import org.hl7.fhir.convertors.factory.VersionConvertorFactory_10_50; @@ -85,7 +83,7 @@ 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.convertors.misc.DicomPackageBuilder; + import org.hl7.fhir.convertors.misc.NpmPackageVersionConverter; import org.hl7.fhir.convertors.txClient.TerminologyClientFactory; import org.hl7.fhir.exceptions.DefinitionException; @@ -318,9 +316,7 @@ import org.hl7.fhir.utilities.ZipGenerator; import org.hl7.fhir.utilities.i18n.I18nConstants; import org.hl7.fhir.utilities.i18n.JsonLangFileProducer; -import org.hl7.fhir.utilities.i18n.JsonLangFileProducer.JsonLangProducerSession; -import org.hl7.fhir.utilities.i18n.LanguageFileProducer.LanguageProducerLanguageSession; -import org.hl7.fhir.utilities.i18n.LanguageFileProducer.LanguageProducerSession; + import org.hl7.fhir.utilities.i18n.LanguageFileProducer.TranslationUnit; import org.hl7.fhir.utilities.i18n.PoGetTextProducer; import org.hl7.fhir.utilities.i18n.XLIFFProducer; @@ -11173,17 +11169,7 @@ public String getConfigFile() { } private static void runGUI() throws InterruptedException, InvocationTargetException { - EventQueue.invokeLater(new Runnable() { - public void run() { - try { - UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); - GraphicalPublisher window = new GraphicalPublisher(); - window.frame.setVisible(true); - } catch (Exception e) { - e.printStackTrace(); - } - } - }); + GraphicalPublisher.launchUI(); } public void setTxServer(String s) { diff --git a/org.hl7.fhir.publisher.core/src/main/java/org/hl7/fhir/igtools/ui/GraphicalPublisher.java b/org.hl7.fhir.publisher.core/src/main/java/org/hl7/fhir/igtools/ui/GraphicalPublisher.java index 92e9956d5..a9db375f3 100644 --- a/org.hl7.fhir.publisher.core/src/main/java/org/hl7/fhir/igtools/ui/GraphicalPublisher.java +++ b/org.hl7.fhir.publisher.core/src/main/java/org/hl7/fhir/igtools/ui/GraphicalPublisher.java @@ -21,6 +21,7 @@ */ +import javax.swing.*; import java.awt.EventQueue; import java.io.IOException; @@ -32,9 +33,14 @@ public class GraphicalPublisher { * Launch the application. */ public static void main(String[] args) { + launchUI(); + } + + public static void launchUI() { EventQueue.invokeLater(new Runnable() { public void run() { try { + UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); GraphicalPublisher window = new GraphicalPublisher(); window.frame.setVisible(true); } catch (Exception e) { diff --git a/org.hl7.fhir.publisher.core/src/main/java/org/hl7/fhir/igtools/ui/IGPublisherFrame.java b/org.hl7.fhir.publisher.core/src/main/java/org/hl7/fhir/igtools/ui/IGPublisherFrame.java index 2b485d0d3..74bb5803c 100644 --- a/org.hl7.fhir.publisher.core/src/main/java/org/hl7/fhir/igtools/ui/IGPublisherFrame.java +++ b/org.hl7.fhir.publisher.core/src/main/java/org/hl7/fhir/igtools/ui/IGPublisherFrame.java @@ -32,10 +32,8 @@ import java.io.IOException; import java.util.List; -import javax.swing.JFileChooser; -import javax.swing.JFrame; -import javax.swing.JOptionPane; -import javax.swing.SwingWorker; +import javax.swing.*; +import javax.swing.filechooser.FileNameExtensionFilter; import org.hl7.fhir.igtools.publisher.Publisher; import org.hl7.fhir.igtools.publisher.Publisher.CacheOption; @@ -49,16 +47,15 @@ public class IGPublisherFrame extends javax.swing.JFrame { private static final String LOG_PREFIX = "--$%^^---"; - private javax.swing.JButton btnExecute; - private javax.swing.JButton btnChoose; - private javax.swing.JButton btnGetHelp; - private javax.swing.JButton btnQA; - private javax.swing.JButton btnIG; - private javax.swing.JPanel jPanel1; - private javax.swing.JTextArea txtLog; - private javax.swing.JTextArea txtValidation; - private javax.swing.JComboBox cbxIGName; - private javax.swing.JToolBar jToolBar1; + private javax.swing.JButton executeButton; + private javax.swing.JButton chooseIGButton; + private javax.swing.JButton debugSummaryButton; + private javax.swing.JButton viewQAButton; + private javax.swing.JButton viewIgButton; + private javax.swing.JPanel mainPanel; + private javax.swing.JTextArea txtLogTextArea; + private javax.swing.JComboBox igNameComboBox; + private javax.swing.JToolBar mainToolBar; private IniFile ini; private BackgroundPublisherTask task; @@ -71,14 +68,16 @@ public class IGPublisherFrame extends javax.swing.JFrame { */ public IGPublisherFrame() throws IOException { ini = new IniFile(Utilities.path(System.getProperty("user.home"), "fhir-ig.ini")); - initComponents(); + + createComponents(); + createLayout(); } @SuppressWarnings("unchecked") - private void initComponents() { + private void createLayout() { setTitle("FHIR Implementation Guide Publisher"); - setIconImage(Toolkit.getDefaultToolkit().getImage("C:\\work\\org.hl7.fhir\\build\\tools\\html\\assets\\ico\\favicon.png")); + setIconImage(Toolkit.getDefaultToolkit().getImage(getClass().getResource("/favicon.ico"))); setBounds(100, 100, 785, 449); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); addWindowListener(new WindowAdapter() { @@ -87,120 +86,57 @@ public void windowClosing(WindowEvent e) { } }); - jToolBar1 = new javax.swing.JToolBar(); - btnExecute = new javax.swing.JButton(); - btnChoose = new javax.swing.JButton(); - cbxIGName = new javax.swing.JComboBox(); - jPanel1 = new javax.swing.JPanel(); - btnGetHelp = new javax.swing.JButton(); - btnQA = new javax.swing.JButton(); - btnIG = new javax.swing.JButton(); - txtLog = new javax.swing.JTextArea(); - txtValidation = new javax.swing.JTextArea(); + mainPanel = new javax.swing.JPanel(); setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); - jToolBar1.setRollover(true); - jToolBar1.setFocusable(false); - - btnExecute.setFocusable(false); - btnExecute.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); - btnExecute.setLabel("Execute"); - btnExecute.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); - btnExecute.addActionListener(new java.awt.event.ActionListener() { - public void actionPerformed(java.awt.event.ActionEvent evt) { - btnExecuteClick(evt); - } - }); - jToolBar1.add(btnExecute); - - btnChoose.setFocusable(false); - btnChoose.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); - btnChoose.setLabel("Choose"); - btnChoose.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); - btnChoose.addActionListener(new java.awt.event.ActionListener() { - public void actionPerformed(java.awt.event.ActionEvent evt) { - btnChooseClick(evt); - } - }); - jToolBar1.add(btnChoose); + mainToolBar = new javax.swing.JToolBar(); + mainToolBar.setRollover(true); + mainToolBar.setFocusable(false); - if (ini.getProperties("igs") != null && ini.getProperties("igs").containsKey("selected")) { - for (int i = 0; i < ini.getIntegerProperty("igs", "count"); i++) - cbxIGName.addItem(ini.getStringProperty("igs", "file"+Integer.toString(i))); - cbxIGName.setSelectedIndex(ini.getIntegerProperty("igs", "selected")); - } - cbxIGName.addActionListener(new java.awt.event.ActionListener() { - public void actionPerformed(java.awt.event.ActionEvent evt) { - cbxIGNameChange(evt); - } - }); - jToolBar1.add(cbxIGName); + mainToolBar.add(executeButton); + mainToolBar.add(chooseIGButton); + mainToolBar.add(igNameComboBox); - btnGetHelp.setText("Debug Summary"); - btnGetHelp.setEnabled(false); - btnGetHelp.addActionListener(new java.awt.event.ActionListener() { - public void actionPerformed(java.awt.event.ActionEvent evt) { - btnGetHelpClick(evt); - } - }); - btnQA.setText("View QA"); - btnQA.setEnabled(false); - btnQA.addActionListener(new java.awt.event.ActionListener() { - public void actionPerformed(java.awt.event.ActionEvent evt) { - btnQAClick(evt); - } - }); - btnIG.setText("View IG"); - btnIG.setEnabled(false); - btnIG.addActionListener(new java.awt.event.ActionListener() { - public void actionPerformed(java.awt.event.ActionEvent evt) { - btnIGClick(evt); - } - }); - - - javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1); - jPanel1.setLayout(jPanel1Layout); - jPanel1Layout.setHorizontalGroup( - jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(jPanel1Layout.createSequentialGroup() + javax.swing.GroupLayout mainPanelLayout = new javax.swing.GroupLayout(mainPanel); + mainPanel.setLayout(mainPanelLayout); + mainPanelLayout.setHorizontalGroup( + mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(mainPanelLayout.createSequentialGroup() .addContainerGap() - .addComponent(btnGetHelp) - .addComponent(btnQA) - .addComponent(btnIG) + .addComponent(debugSummaryButton) + .addComponent(viewQAButton) + .addComponent(viewIgButton) .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); - jPanel1Layout.setVerticalGroup( - jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(jPanel1Layout.createSequentialGroup() - .addComponent(btnGetHelp) - .addComponent(btnQA) - .addComponent(btnIG) + mainPanelLayout.setVerticalGroup( + mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(mainPanelLayout.createParallelGroup() + .addComponent(debugSummaryButton) + .addComponent(viewQAButton) + .addComponent(viewIgButton) .addGap(0, 13, Short.MAX_VALUE)) ); - txtLog.setColumns(20); - txtLog.setRows(5); - txtLog.setEditable(false); - txtLog.getCaret().setVisible(false); + + JScrollPane logScrollPane = new JScrollPane(txtLogTextArea); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); getContentPane().setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(jToolBar1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(txtLog, javax.swing.GroupLayout.DEFAULT_SIZE, 627, Short.MAX_VALUE) + .addComponent(mainToolBar, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(mainPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(logScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 627, Short.MAX_VALUE) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() - .addComponent(jToolBar1, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(mainToolBar, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(txtLog, javax.swing.GroupLayout.DEFAULT_SIZE, 175, Short.MAX_VALUE) + .addComponent(logScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 175, Short.MAX_VALUE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(mainPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) ); pack(); @@ -209,34 +145,139 @@ public void actionPerformed(java.awt.event.ActionEvent evt) { setSize(ini.getIntegerProperty("layout", "W"), ini.getIntegerProperty("layout", "H")); } - } + } + + private void createComponents() { + txtLogTextArea = createTxLogTextArea(); + + executeButton = createExecuteButton(); + chooseIGButton = createChooseIGButton(); + igNameComboBox = createIgNameComboBox(); + + debugSummaryButton = createDebugSumaryButton(); + viewQAButton = createViewQAButton(); + viewIgButton = createViewIGButton(); + } + + private JComboBox createIgNameComboBox() { + JComboBox igNameComboBox = new javax.swing.JComboBox(); + if (ini.getProperties("igs") != null && ini.getProperties("igs").containsKey("selected")) { + for (int i = 0; i < ini.getIntegerProperty("igs", "count"); i++) + igNameComboBox.addItem(ini.getStringProperty("igs", "file"+Integer.toString(i))); + igNameComboBox.setSelectedIndex(ini.getIntegerProperty("igs", "selected")); + } + igNameComboBox.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + changeIGName(evt); + } + }); + return igNameComboBox; + } + + private JButton createChooseIGButton() { + JButton chooseIGButton = new javax.swing.JButton(); + chooseIGButton.setFocusable(false); + chooseIGButton.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); + chooseIGButton.setLabel("Choose"); + chooseIGButton.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); + chooseIGButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + btnChooseClick(evt); + } + }); + return chooseIGButton; + } + + private JButton createViewQAButton() { + JButton viewQAButton = new javax.swing.JButton(); + viewQAButton.setText("View QA"); + viewQAButton.setEnabled(false); + viewQAButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + btnQAClick(evt); + } + }); + return viewQAButton; + } + + private JButton createViewIGButton() { + JButton viewIgButton =new javax.swing.JButton(); + viewIgButton.setText("View IG"); + viewIgButton.setEnabled(false); + viewIgButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + btnIGClick(evt); + } + }); + return viewIgButton; + } + + private JTextArea createTxLogTextArea() { + JTextArea txtLogTextArea = new javax.swing.JTextArea(); + txtLogTextArea.setColumns(20); + txtLogTextArea.setRows(5); + txtLogTextArea.setEditable(false); + txtLogTextArea.getCaret().setVisible(false); + return txtLogTextArea; + } + + private JButton createDebugSumaryButton() { + JButton button = new javax.swing.JButton(); + button.setText("Debug Summary"); + button.setEnabled(false); + button.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + btnGetHelpClick(evt); + } + }); + return button; + } + + private JButton createExecuteButton() { + JButton executeButton = new javax.swing.JButton(); + executeButton.setFocusable(false); + executeButton.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); + executeButton.setLabel("Execute"); + executeButton.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); + executeButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + btnExecuteClick(evt); + } + }); + return executeButton; + } - private void btnChooseClick(java.awt.event.ActionEvent evt) { - JFileChooser jfc = new JFileChooser(); - if (cbxIGName.getSelectedItem() != null) - jfc.setCurrentDirectory(new File(Utilities.getDirectoryForFile((String) cbxIGName.getSelectedItem()))); - if (jfc.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) { + JFileChooser igFileChooser = new JFileChooser(); + igFileChooser.setFileFilter(new FileNameExtensionFilter("IG ini file or IG Directory", "ini")); + igFileChooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES); + if (igNameComboBox.getSelectedItem() != null) + igFileChooser.setCurrentDirectory(new File(Utilities.getDirectoryForFile((String) igNameComboBox.getSelectedItem()))); + if (igFileChooser.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) { int index = -1; - String s = jfc.getSelectedFile().getAbsolutePath(); - for (int i = 0; i < cbxIGName.getItemCount(); i++) { - if (s.equals(cbxIGName.getItemAt(i))) + + String selectedFile = igFileChooser.getSelectedFile().isDirectory() + ? igFileChooser.getSelectedFile().getAbsolutePath() + File.separatorChar + "ig.ini" + : igFileChooser.getSelectedFile().getAbsolutePath(); + + for (int i = 0; i < igNameComboBox.getItemCount(); i++) { + if (selectedFile.equals(igNameComboBox.getItemAt(i))) index = i;; } if (index == -1) { index = ini.getProperties("igs") == null ? 0 : ini.getIntegerProperty("igs", "count"); - ini.setStringProperty("igs", "file"+Integer.toString(index), s, null); + ini.setStringProperty("igs", "file"+Integer.toString(index), selectedFile, null); ini.setIntegerProperty("igs", "count", index+1, null); - cbxIGName.addItem(ini.getStringProperty("igs", "file"+Integer.toString(index))); + igNameComboBox.addItem(ini.getStringProperty("igs", "file"+Integer.toString(index))); } ini.setIntegerProperty("igs", "selected", index, null); - cbxIGName.setSelectedIndex(ini.getIntegerProperty("igs", "selected")); + igNameComboBox.setSelectedIndex(ini.getIntegerProperty("igs", "selected")); } } - private void cbxIGNameChange(java.awt.event.ActionEvent evt) { - int index = cbxIGName.getSelectedIndex(); + private void changeIGName(java.awt.event.ActionEvent evt) { + int index = igNameComboBox.getSelectedIndex(); ini.setIntegerProperty("igs", "selected", index, null); } @@ -257,7 +298,7 @@ public class BackgroundPublisherTask extends SwingWorker impleme public String doInBackground() { qa = null; Publisher pu = new Publisher(); - pu.setConfigFile((String) cbxIGName.getSelectedItem()); + pu.setConfigFile((String) igNameComboBox.getSelectedItem()); pu.setLogger(this); pu.setCacheOption(CacheOption.LEAVE); try { @@ -288,22 +329,22 @@ protected void process(List msgs) { if (msg.startsWith(LOG_PREFIX)) { fullLog.append(msg.substring(LOG_PREFIX.length())+"\r\n"); } else { - txtLog.append(msg+"\r\n"); + txtLogTextArea.append(msg+"\r\n"); fullLog.append(msg+"\r\n"); } } - txtLog.setCaretPosition(txtLog.getText().length() - 1); + txtLogTextArea.setCaretPosition(txtLogTextArea.getText().length() - 1); } @Override protected void done() { - btnExecute.setEnabled(true); - btnChoose.setEnabled(true); - cbxIGName.setEnabled(true); - btnGetHelp.setEnabled(true); - btnQA.setEnabled(true); - btnIG.setEnabled(true); - btnExecute.setLabel("Execute"); + executeButton.setEnabled(true); + chooseIGButton.setEnabled(true); + igNameComboBox.setEnabled(true); + debugSummaryButton.setEnabled(true); + viewQAButton.setEnabled(true); + viewIgButton.setEnabled(true); + executeButton.setLabel("Execute"); } @Override @@ -315,21 +356,21 @@ public boolean isDebugLogging() { } private void btnExecuteClick(java.awt.event.ActionEvent evt) { - btnExecute.setEnabled(false); - btnChoose.setEnabled(false); - cbxIGName.setEnabled(false); - btnGetHelp.setEnabled(false); - btnQA.setEnabled(false); - btnIG.setEnabled(false); - btnExecute.setLabel("Running"); - txtLog.setText(""); + executeButton.setEnabled(false); + chooseIGButton.setEnabled(false); + igNameComboBox.setEnabled(false); + debugSummaryButton.setEnabled(false); + viewQAButton.setEnabled(false); + viewIgButton.setEnabled(false); + executeButton.setLabel("Running"); + txtLogTextArea.setText(""); fullLog.setLength(0); task = new BackgroundPublisherTask(); task.execute(); } private String folder() { - return Utilities.getDirectoryForFile((String) cbxIGName.getSelectedItem()); + return Utilities.getDirectoryForFile((String) igNameComboBox.getSelectedItem()); } protected void btnQAClick(ActionEvent evt) { @@ -357,7 +398,7 @@ protected void btnIGClick(ActionEvent evt) { protected void btnGetHelpClick(ActionEvent evt) { try { - String text = Publisher.buildReport((String) cbxIGName.getSelectedItem(), null, fullLog.toString(), qa == null ? null : Utilities.changeFileExt(qa, ".txt"), FhirSettings.getTxFhirProduction()); + String text = Publisher.buildReport((String) igNameComboBox.getSelectedItem(), null, fullLog.toString(), qa == null ? null : Utilities.changeFileExt(qa, ".txt"), FhirSettings.getTxFhirProduction()); StringSelection stringSelection = new StringSelection(text); Clipboard clpbrd = Toolkit.getDefaultToolkit().getSystemClipboard(); clpbrd.setContents(stringSelection, null); diff --git a/org.hl7.fhir.publisher.core/src/main/resources/favicon.ico b/org.hl7.fhir.publisher.core/src/main/resources/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..be11df33a9205a36d0c105c0498919a3278e6aaf GIT binary patch literal 102134 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 literal 0 HcmV?d00001