Merge branch 'master' into issue_438
This commit is contained in:
commit
30be8a0dc1
|
@ -1,4 +1,6 @@
|
|||
* add test for Observation conversion from 10 to 40
|
||||
* add procedures conversion form dstu2 to r4
|
||||
* add medication conversion from dstu2 to r4
|
||||
* add copy of extension field for Enumeration fieldtype by Resource.copy
|
||||
* add copy of extension field for Enumeration fieldtype by Resource.copy
|
||||
* minor fixes in code generators for R4B
|
||||
* add default value to Medication Request during conversion from dstu2 to r4
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>org.hl7.fhir.core</artifactId>
|
||||
<version>5.2.21-SNAPSHOT</version>
|
||||
<version>5.3.7-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -967,7 +967,7 @@ public class VersionConvertor_40_50 {
|
|||
if (src == null) return null;
|
||||
org.hl7.fhir.r5.model.DataRequirement tgt = new org.hl7.fhir.r5.model.DataRequirement();
|
||||
copyElement(src, tgt);
|
||||
if (src.hasType()) tgt.setType(org.hl7.fhir.r5.model.Enumerations.FHIRAllTypes.fromCode(src.getType()));
|
||||
if (src.hasType()) tgt.setType(org.hl7.fhir.r5.model.Enumerations.FHIRAllTypes.fromCode(convertResourceName4to5(src.getType())));
|
||||
for (org.hl7.fhir.r4.model.CanonicalType t : src.getProfile()) tgt.getProfile().add(convertCanonical(t));
|
||||
if (src.hasSubject()) tgt.setSubject(convertType(src.getSubject()));
|
||||
for (org.hl7.fhir.r4.model.StringType t : src.getMustSupport()) tgt.getMustSupport().add(convertString(t));
|
||||
|
@ -981,11 +981,12 @@ public class VersionConvertor_40_50 {
|
|||
return tgt;
|
||||
}
|
||||
|
||||
|
||||
public static org.hl7.fhir.r4.model.DataRequirement convertDataRequirement(org.hl7.fhir.r5.model.DataRequirement src) throws FHIRException {
|
||||
if (src == null) return null;
|
||||
org.hl7.fhir.r4.model.DataRequirement tgt = new org.hl7.fhir.r4.model.DataRequirement();
|
||||
copyElement(src, tgt);
|
||||
if (src.hasType()) tgt.setType(src.getType().toCode());
|
||||
if (src.hasType()) tgt.setType(convertResourceName5to4(src.getType().toCode()));
|
||||
for (org.hl7.fhir.r5.model.CanonicalType t : src.getProfile()) tgt.getProfile().add(convertCanonical(t));
|
||||
if (src.hasSubject()) tgt.setSubject(convertType(src.getSubject()));
|
||||
for (org.hl7.fhir.r5.model.StringType t : src.getMustSupport()) tgt.getMustSupport().add(convertString(t));
|
||||
|
@ -999,6 +1000,22 @@ public class VersionConvertor_40_50 {
|
|||
return tgt;
|
||||
}
|
||||
|
||||
private static String convertResourceName4to5(String name) {
|
||||
if (name == null) return null;
|
||||
if (name.equals("MedicationStatement")) {
|
||||
return "MedicationUsage";
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
private static String convertResourceName5to4(String name) {
|
||||
if (name == null) return null;
|
||||
if (name.equals("MedicationUsage")) {
|
||||
return "MedicationStatement";
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
public static org.hl7.fhir.r5.model.DataRequirement.DataRequirementCodeFilterComponent convertDataRequirementCodeFilterComponent(org.hl7.fhir.r4.model.DataRequirement.DataRequirementCodeFilterComponent src) throws FHIRException {
|
||||
if (src == null) return null;
|
||||
org.hl7.fhir.r5.model.DataRequirement.DataRequirementCodeFilterComponent tgt = new org.hl7.fhir.r5.model.DataRequirement.DataRequirementCodeFilterComponent();
|
||||
|
|
|
@ -18,6 +18,8 @@ public class MedicationRequest10_40 {
|
|||
tgt.setAuthoredOnElement(VersionConvertor_10_40.convertDateTime(src.getDateWrittenElement()));
|
||||
if (src.hasStatus())
|
||||
tgt.setStatus(org.hl7.fhir.r4.model.MedicationRequest.MedicationRequestStatus.fromCode(src.getStatus().toCode()));
|
||||
else
|
||||
tgt.setStatus(org.hl7.fhir.r4.model.MedicationRequest.MedicationRequestStatus.UNKNOWN);
|
||||
if (src.hasPatient())
|
||||
tgt.setSubject(VersionConvertor_10_40.convertReference(src.getPatient()));
|
||||
if (src.hasPrescriber())
|
||||
|
|
|
@ -167,11 +167,14 @@ public class ConceptMap40_50 extends VersionConvertor_40_50 {
|
|||
if (src.hasCode())
|
||||
tgt.setCodeElement(convertCode(src.getCodeElement()));
|
||||
if (src.hasDisplay())
|
||||
tgt.setDisplayElement(convertString(src.getDisplayElement()));
|
||||
for (org.hl7.fhir.r4.model.ConceptMap.TargetElementComponent t : src.getTarget()) if (t.getEquivalence() == org.hl7.fhir.r4.model.Enumerations.ConceptMapEquivalence.UNMATCHED) {
|
||||
tgt.setDisplayElement(convertString(src.getDisplayElement()));
|
||||
for (org.hl7.fhir.r4.model.ConceptMap.TargetElementComponent t : src.getTarget()) {
|
||||
if (t.getEquivalence() == org.hl7.fhir.r4.model.Enumerations.ConceptMapEquivalence.UNMATCHED) {
|
||||
tgt.setNoMap(true);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
tgt.addTarget(convertTargetElementComponent(t));
|
||||
}
|
||||
}
|
||||
return tgt;
|
||||
}
|
||||
|
@ -222,6 +225,8 @@ public class ConceptMap40_50 extends VersionConvertor_40_50 {
|
|||
tgt.setDisplayElement(convertString(src.getDisplayElement()));
|
||||
if (src.hasRelationship())
|
||||
tgt.setEquivalenceElement(convertConceptMapEquivalence(src.getRelationshipElement()));
|
||||
else
|
||||
tgt.setEquivalence(ConceptMapEquivalence.RELATEDTO);
|
||||
if (src.hasComment())
|
||||
tgt.setCommentElement(convertString(src.getCommentElement()));
|
||||
for (org.hl7.fhir.r5.model.ConceptMap.OtherElementComponent t : src.getDependsOn()) tgt.addDependsOn(convertOtherElementComponent(t));
|
||||
|
|
|
@ -210,6 +210,9 @@ public class Enumerations40_50 extends VersionConvertor_40_50 {
|
|||
case _4_0_1:
|
||||
tgt.setValue(org.hl7.fhir.r5.model.Enumerations.FHIRVersion._4_0_1);
|
||||
break;
|
||||
case _4_1_0:
|
||||
tgt.setValue(org.hl7.fhir.r5.model.Enumerations.FHIRVersion._4_1_0);
|
||||
break;
|
||||
default:
|
||||
tgt.setValue(org.hl7.fhir.r5.model.Enumerations.FHIRVersion.NULL);
|
||||
break;
|
||||
|
@ -292,6 +295,9 @@ public class Enumerations40_50 extends VersionConvertor_40_50 {
|
|||
case _4_0_1:
|
||||
tgt.setValue(org.hl7.fhir.r4.model.Enumerations.FHIRVersion._4_0_1);
|
||||
break;
|
||||
case _4_1_0:
|
||||
tgt.setValue(org.hl7.fhir.r4.model.Enumerations.FHIRVersion._4_1_0);
|
||||
break;
|
||||
default:
|
||||
tgt.setValue(org.hl7.fhir.r4.model.Enumerations.FHIRVersion.NULL);
|
||||
break;
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
package org.hl7.fhir.convertors.misc;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import org.hl7.fhir.exceptions.FHIRFormatError;
|
||||
import org.hl7.fhir.utilities.Utilities;
|
||||
import org.hl7.fhir.utilities.json.JsonTrackingParser;
|
||||
import org.hl7.fhir.utilities.npm.NpmPackage;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
public class CorePackageTools {
|
||||
|
||||
public static void main(String[] args) throws FHIRFormatError, FileNotFoundException, IOException {
|
||||
if ("-xml".equals(args[0])) {
|
||||
new CorePackageTools().buildXml(args[1], args[2], args[3]);
|
||||
}
|
||||
if ("-pack".equals(args[0])) {
|
||||
new CorePackageTools().buildPackage(args[1], args[2]);
|
||||
}
|
||||
}
|
||||
|
||||
private void buildPackage(String path, String output) throws IOException {
|
||||
NpmPackage npm = NpmPackage.fromFolder(path);
|
||||
npm.loadAllFiles();
|
||||
npm.save(new FileOutputStream(output));
|
||||
|
||||
}
|
||||
|
||||
private void buildXml(String json, String xml, String version) throws FHIRFormatError, FileNotFoundException, IOException {
|
||||
for (File f : new File(Utilities.path(json, "package")).listFiles()) {
|
||||
if (f.getName().endsWith(".json")) {
|
||||
JsonObject j = new JsonTrackingParser().parseJson(f);
|
||||
if (j.has("resourceType")) {
|
||||
if ("1.4".equals(version)) {
|
||||
String n = f.getName();
|
||||
System.out.println(n);
|
||||
String xn = Utilities.changeFileExt(n, ".xml");
|
||||
org.hl7.fhir.dstu2016may.model.Resource r = new org.hl7.fhir.dstu2016may.formats.JsonParser().parse(new FileInputStream(f));
|
||||
new org.hl7.fhir.dstu2016may.formats.XmlParser().setOutputStyle(org.hl7.fhir.dstu2016may.formats.IParser.OutputStyle.NORMAL).compose(new FileOutputStream(Utilities.path(xml, "package", xn)), r);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -6,16 +6,28 @@ import org.hl7.fhir.convertors.misc.IGR2ConvertorAdvisor;
|
|||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class MedicationRequest10_40Test {
|
||||
@Test
|
||||
private static Stream<Arguments> filesPaths() {
|
||||
return Stream.of(
|
||||
Arguments.of("/0_medication_request_10.json", "/0_medication_request_40.json"),
|
||||
Arguments.of("/1_medication_request_10.json", "/1_medication_request_40.json")
|
||||
);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("filesPaths")
|
||||
@DisplayName("Test 10_40 MedicationRequest conversion")
|
||||
public void testMedicationRequestConversion() throws IOException {
|
||||
InputStream dstu2_input = this.getClass().getResourceAsStream("/0_medication_request_10.json");
|
||||
InputStream r4_exepected_input = this.getClass().getResourceAsStream("/0_medication_request_40.json");
|
||||
public void testMedicationRequestConversion(String dstu2_path, String r4_path) throws IOException {
|
||||
InputStream dstu2_input = this.getClass().getResourceAsStream(dstu2_path);
|
||||
InputStream r4_exepected_input = this.getClass().getResourceAsStream(r4_path);
|
||||
|
||||
org.hl7.fhir.dstu2.model.MedicationOrder dstu2 = (org.hl7.fhir.dstu2.model.MedicationOrder) new org.hl7.fhir.dstu2.formats.JsonParser().parse(dstu2_input);
|
||||
VersionConvertorAdvisor40 advisor = new IGR2ConvertorAdvisor();
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
{"resourceType": "MedicationOrder",
|
||||
"dateWritten": "2016-11-13",
|
||||
"id": "T5YI1tCzs--JEvCICFbx8zgB",
|
||||
"identifier": [{"use": "usual",
|
||||
"system": "urn:oid:1.2.840.114350.1.13.0.1.7.2.798268",
|
||||
"value": "988736"},
|
||||
{"use": "usual",
|
||||
"system": "urn:oid:1.2.840.114350.1.13.0.1.7.3.798268.801",
|
||||
"value": "988736:2150291843"}],
|
||||
"patient": {"display": "Jason Argonaut",
|
||||
"reference": "https://open-ic.epic.com/Argonaut/api/FHIR/DSTU2/Patient/Tbt3KuCY0B5PSrJvCu2j-PlK.aiHsu2xUjUM8bWpetXoB"},
|
||||
"prescriber": {"display": "Historical Provider, MD",
|
||||
"reference": "https://open-ic.epic.com/Argonaut/api/FHIR/DSTU2/Practitioner/T-kmjPGEVPAmnBfmx56HsKgB"},
|
||||
"medicationReference": {"display": "amitriptyline 10 MG tablet",
|
||||
"reference": "https://open-ic.epic.com/Argonaut/api/FHIR/DSTU2/Medication/T0eKLT7EB2ApMM8HCEURdMAB"},
|
||||
"dosageInstruction": [{"text": "Take 10 mg by mouth nightly.",
|
||||
"asNeededBoolean": "False",
|
||||
"route": {"text": "Oral",
|
||||
"coding": [{"system": "urn:oid:1.2.840.114350.1.13.0.1.7.4.698288.330",
|
||||
"code": "15",
|
||||
"display": "Oral"}]},
|
||||
"method": {"text": "Take",
|
||||
"coding": [{"system": "urn:oid:1.2.840.114350.1.13.0.1.7.4.798268.8600",
|
||||
"code": "11",
|
||||
"display": "Take"}]},
|
||||
"timing": {"repeat": {"frequency": 1,
|
||||
"period": 1.0,
|
||||
"periodUnits": "d",
|
||||
"boundsPeriod": {"start": "2016-11-15T00:00:00Z",
|
||||
"end": "2016-11-23T00:00:00Z"}}},
|
||||
"doseQuantity": {"value": 10.0,
|
||||
"unit": "mg",
|
||||
"code": "mg",
|
||||
"system": "http://unitsofmeasure.org"}}],
|
||||
"dispenseRequest": {"validityPeriod": {"start": "2016-11-15T00:00:00Z",
|
||||
"end": "2016-11-23T00:00:00Z"}}}
|
|
@ -0,0 +1,38 @@
|
|||
{"resourceType": "MedicationRequest",
|
||||
"id": "T5YI1tCzs--JEvCICFbx8zgB",
|
||||
"identifier": [{"use": "usual",
|
||||
"system": "urn:oid:1.2.840.114350.1.13.0.1.7.2.798268",
|
||||
"value": "988736"},
|
||||
{"use": "usual",
|
||||
"system": "urn:oid:1.2.840.114350.1.13.0.1.7.3.798268.801",
|
||||
"value": "988736:2150291843"}],
|
||||
"status": "unknown",
|
||||
"intent": "order",
|
||||
"medicationReference": {"reference": "https://open-ic.epic.com/Argonaut/api/FHIR/DSTU2/Medication/T0eKLT7EB2ApMM8HCEURdMAB",
|
||||
"display": "amitriptyline 10 MG tablet"},
|
||||
"subject": {"reference": "https://open-ic.epic.com/Argonaut/api/FHIR/DSTU2/Patient/Tbt3KuCY0B5PSrJvCu2j-PlK.aiHsu2xUjUM8bWpetXoB",
|
||||
"display": "Jason Argonaut"},
|
||||
"authoredOn": "2016-11-13T00:00:00",
|
||||
"requester": {"reference": "https://open-ic.epic.com/Argonaut/api/FHIR/DSTU2/Practitioner/T-kmjPGEVPAmnBfmx56HsKgB",
|
||||
"display": "Historical Provider, MD"},
|
||||
"dosageInstruction": [{"text": "Take 10 mg by mouth nightly.",
|
||||
"timing": {"repeat": {"boundsPeriod": {"start": "2016-11-15T00:00:00Z",
|
||||
"end": "2016-11-23T00:00:00Z"},
|
||||
"frequency": 1,
|
||||
"period": 1.0,
|
||||
"periodUnit": "d"}},
|
||||
"asNeededBoolean": "False",
|
||||
"route": {"coding": [{"system": "urn:oid:1.2.840.114350.1.13.0.1.7.4.698288.330",
|
||||
"code": "15",
|
||||
"display": "Oral"}],
|
||||
"text": "Oral"},
|
||||
"method": {"coding": [{"system": "urn:oid:1.2.840.114350.1.13.0.1.7.4.798268.8600",
|
||||
"code": "11",
|
||||
"display": "Take"}],
|
||||
"text": "Take"},
|
||||
"doseAndRate": [{"doseQuantity": {"value": 10.0,
|
||||
"unit": "mg",
|
||||
"system": "http://unitsofmeasure.org",
|
||||
"code": "mg"}}]}],
|
||||
"dispenseRequest": {"validityPeriod": {"start": "2016-11-15T00:00:00Z",
|
||||
"end": "2016-11-23T00:00:00Z"}}}
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>org.hl7.fhir.core</artifactId>
|
||||
<version>5.2.21-SNAPSHOT</version>
|
||||
<version>5.3.7-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>org.hl7.fhir.core</artifactId>
|
||||
<version>5.2.21-SNAPSHOT</version>
|
||||
<version>5.3.7-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>org.hl7.fhir.core</artifactId>
|
||||
<version>5.2.21-SNAPSHOT</version>
|
||||
<version>5.3.7-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>org.hl7.fhir.core</artifactId>
|
||||
<version>5.2.21-SNAPSHOT</version>
|
||||
<version>5.3.7-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -10032,6 +10032,10 @@ The primary difference between a medication statement and a medication administr
|
|||
* added to help the parsers
|
||||
*/
|
||||
_4_0_1,
|
||||
/**
|
||||
* R4B - manually added
|
||||
*/
|
||||
_4_1_0,
|
||||
NULL;
|
||||
public static FHIRVersion fromCode(String codeString) throws FHIRException {
|
||||
if (codeString == null || "".equals(codeString))
|
||||
|
@ -10082,6 +10086,8 @@ The primary difference between a medication statement and a medication administr
|
|||
return _4_0_0;
|
||||
if ("4.0.1".equals(codeString))
|
||||
return _4_0_1;
|
||||
if ("4.1.0".equals(codeString))
|
||||
return _4_1_0;
|
||||
throw new FHIRException("Unknown FHIRVersion code '"+codeString+"'");
|
||||
}
|
||||
@Override
|
||||
|
@ -10113,6 +10119,7 @@ The primary difference between a medication statement and a medication administr
|
|||
case _3_5_0: return "3.5.0";
|
||||
case _4_0_0: return "4.0.0";
|
||||
case _4_0_1: return "4.0.1";
|
||||
case _4_1_0: return "4.1.0";
|
||||
case NULL: return null;
|
||||
default: return "?";
|
||||
}
|
||||
|
@ -10142,6 +10149,7 @@ The primary difference between a medication statement and a medication administr
|
|||
case _3_5_0: return "http://hl7.org/fhir/FHIR-version";
|
||||
case _4_0_0: return "http://hl7.org/fhir/FHIR-version";
|
||||
case _4_0_1: return "http://hl7.org/fhir/FHIR-version";
|
||||
case _4_1_0: return "http://hl7.org/fhir/FHIR-version";
|
||||
case NULL: return null;
|
||||
default: return "?";
|
||||
}
|
||||
|
@ -10171,6 +10179,7 @@ The primary difference between a medication statement and a medication administr
|
|||
case _3_5_0: return "R4 Ballot #2.";
|
||||
case _4_0_0: return "FHIR Release 4 (Normative + STU).";
|
||||
case _4_0_1: return "FHIR Release 4 Technical Correction #1.";
|
||||
case _4_1_0: return "FHIR Release 4B";
|
||||
case NULL: return null;
|
||||
default: return "?";
|
||||
}
|
||||
|
@ -10200,6 +10209,7 @@ The primary difference between a medication statement and a medication administr
|
|||
case _3_5_0: return "3.5.0";
|
||||
case _4_0_0: return "4.0.0";
|
||||
case _4_0_1: return "4.0.1";
|
||||
case _4_1_0: return "4.1.0";
|
||||
case NULL: return null;
|
||||
default: return "?";
|
||||
}
|
||||
|
@ -10263,6 +10273,8 @@ The primary difference between a medication statement and a medication administr
|
|||
return FHIRVersion._4_0_0;
|
||||
if ("4.0.1".equals(codeString))
|
||||
return FHIRVersion._4_0_1;
|
||||
if ("4.1.0".equals(codeString))
|
||||
return FHIRVersion._4_1_0;
|
||||
throw new IllegalArgumentException("Unknown FHIRVersion code '"+codeString+"'");
|
||||
}
|
||||
public Enumeration<FHIRVersion> fromType(Base code) throws FHIRException {
|
||||
|
@ -10319,6 +10331,8 @@ The primary difference between a medication statement and a medication administr
|
|||
return new Enumeration<FHIRVersion>(this, FHIRVersion._4_0_0);
|
||||
if ("4.0.1".equals(codeString))
|
||||
return new Enumeration<FHIRVersion>(this, FHIRVersion._4_0_1);
|
||||
if ("4.1.0".equals(codeString))
|
||||
return new Enumeration<FHIRVersion>(this, FHIRVersion._4_1_0);
|
||||
throw new FHIRException("Unknown FHIRVersion code '"+codeString+"'");
|
||||
}
|
||||
public String toCode(FHIRVersion code) {
|
||||
|
@ -10368,6 +10382,8 @@ The primary difference between a medication statement and a medication administr
|
|||
return "4.0.0";
|
||||
if (code == FHIRVersion._4_0_1)
|
||||
return "4.0.1";
|
||||
if (code == FHIRVersion._4_1_0)
|
||||
return "4.1.0";
|
||||
return "?";
|
||||
}
|
||||
public String toSystem(FHIRVersion code) {
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>org.hl7.fhir.core</artifactId>
|
||||
<version>5.2.21-SNAPSHOT</version>
|
||||
<version>5.3.7-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -636,6 +636,9 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
}
|
||||
baseSnapshot = cloneSnapshot(baseSnapshot, base.getType(), derivedType);
|
||||
}
|
||||
// if (derived.getId().equals("2.16.840.1.113883.10.20.22.2.1.1")) {
|
||||
// debug = true;
|
||||
// }
|
||||
processPaths("", derived.getSnapshot(), baseSnapshot, diff, baseCursor, diffCursor, baseSnapshot.getElement().size()-1,
|
||||
derived.getDifferential().hasElement() ? derived.getDifferential().getElement().size()-1 : -1, url, webUrl, derived.present(), null, null, false, base.getUrl(), null, false, null, null, new ArrayList<ElementRedirection>(), base);
|
||||
checkGroupConstraints(derived);
|
||||
|
@ -1053,7 +1056,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
baseCursor = indexOfFirstNonChild(base, currentBase, baseCursor+1, baseLimit);
|
||||
} else {
|
||||
if (outcome.getType().size() == 0) {
|
||||
throw new DefinitionException(context.formatMessage(I18nConstants._HAS_NO_CHILDREN__AND_NO_TYPES_IN_PROFILE_, diffMatches.get(0).getPath(), differential.getElement().get(diffCursor).getPath(), profileName));
|
||||
throw new DefinitionException(context.formatMessage(I18nConstants._HAS_NO_CHILDREN__AND_NO_TYPES_IN_PROFILE_, cpath, differential.getElement().get(diffCursor).getPath(), profileName));
|
||||
}
|
||||
boolean nonExtension = false;
|
||||
if (outcome.getType().size() > 1) {
|
||||
|
@ -1072,7 +1075,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
}
|
||||
StructureDefinition dt = outcome.getType().size() > 1 ? context.fetchTypeDefinition("Element") : getProfileForDataType(outcome.getType().get(0));
|
||||
if (dt == null) {
|
||||
throw new DefinitionException(context.formatMessage(I18nConstants.UNKNOWN_TYPE__AT_, outcome.getType().get(0), diffMatches.get(0).getPath()));
|
||||
throw new DefinitionException(context.formatMessage(I18nConstants.UNKNOWN_TYPE__AT_, outcome.getType().get(0), cpath));
|
||||
}
|
||||
contextName = dt.getUrl();
|
||||
int start = diffCursor;
|
||||
|
@ -1388,7 +1391,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
// (but you might do that in order to split up constraints by type)
|
||||
throw new DefinitionException(context.formatMessage(I18nConstants.ATTEMPT_TO_A_SLICE_AN_ELEMENT_THAT_DOES_NOT_REPEAT__FROM__IN_, currentBase.getPath(), currentBase.getPath(), contextName, url, diffMatches.get(0).getId(), sliceNames(diffMatches)));
|
||||
if (!diffMatches.get(0).hasSlicing() && !isExtension(currentBase)) // well, the diff has set up a slice, but hasn't defined it. this is an error
|
||||
throw new DefinitionException(context.formatMessage(I18nConstants.DIFFERENTIAL_DOES_NOT_HAVE_A_SLICE__B_OF_____IN_PROFILE_, currentBase.getPath(), baseCursor, baseLimit, diffCursor, diffLimit, url));
|
||||
throw new DefinitionException(context.formatMessage(I18nConstants.DIFFERENTIAL_DOES_NOT_HAVE_A_SLICE__B_OF_____IN_PROFILE_, currentBase.getPath(), baseCursor, baseLimit, diffCursor, diffLimit, url, cpath));
|
||||
|
||||
// well, if it passed those preconditions then we slice the dest.
|
||||
int start = 0;
|
||||
|
@ -1792,7 +1795,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
removeStatusExtensions(outcome);
|
||||
// --- LM Added this
|
||||
diffCursor = differential.getElement().indexOf(diffItem)+1;
|
||||
if (!outcome.getType().isEmpty() && (/*outcome.getType().get(0).getCode().equals("Extension") || */differential.getElement().size() > diffCursor) && outcome.getPath().contains(".") && isDataType(outcome.getType())) { // don't want to do this for the root, since that's base, and we're already processing it
|
||||
if (!outcome.getType().isEmpty() && (/*outcome.getType().get(0).getCode().equals("Extension") || */differential.getElement().size() > diffCursor) && outcome.getPath().contains(".")/* && isDataType(outcome.getType())*/) { // don't want to do this for the root, since that's base, and we're already processing it
|
||||
if (!baseWalksInto(base.getElement(), baseCursor)) {
|
||||
if (differential.getElement().size() > diffCursor && pathStartsWith(differential.getElement().get(diffCursor).getPath(), diffMatches.get(0).getPath()+".")) {
|
||||
if (outcome.getType().size() > 1)
|
||||
|
@ -4625,7 +4628,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
erow.getSubRows().add(row);
|
||||
Cell c = gen.new Cell();
|
||||
row.getCells().add(c);
|
||||
c.addPiece(gen.new Piece((ed.getBase().getPath().equals(ed.getPath()) ? ref+ed.getPath() : corePath+(VersionUtilities.isThisOrLater("4.1", context.getVersion()) ? "types-definitions.html#"+ed.getBase().getPath() : "element-definitions.html#"+ed.getBase().getPath())), t.getName(), null));
|
||||
c.addPiece(gen.new Piece((ed.getBase().getPath().equals(ed.getPath()) ? ref+ed.getPath() : corePath+(VersionUtilities.isR5Ver(context.getVersion()) ? "types-definitions.html#"+ed.getBase().getPath() : "element-definitions.html#"+ed.getBase().getPath())), t.getName(), null));
|
||||
c = gen.new Cell();
|
||||
row.getCells().add(c);
|
||||
c.addPiece(gen.new Piece(null, null, null));
|
||||
|
|
|
@ -978,7 +978,7 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
|
|||
}
|
||||
if (vs != null) {
|
||||
if (isTxCaching && cacheId != null && cached.contains(vs.getUrl()+"|"+vs.getVersion())) {
|
||||
pin.addParameter().setName("url").setValue(new UriType(vs.getUrl()+"|"+vs.getVersion()));
|
||||
pin.addParameter().setName("url").setValue(new UriType(vs.getUrl()+(vs.hasVersion() ? "|"+vs.getVersion() : "")));
|
||||
} else {
|
||||
pin.addParameter().setName("valueSet").setResource(vs);
|
||||
cached.add(vs.getUrl()+"|"+vs.getVersion());
|
||||
|
|
|
@ -6568,7 +6568,7 @@ The primary difference between a medicationusage and a medicationadministration
|
|||
*/
|
||||
NULL;
|
||||
|
||||
public static final FHIRVersion R4B = FHIRVersion._4_0_1;
|
||||
public static final FHIRVersion R4B = FHIRVersion._4_1_0;
|
||||
|
||||
public static FHIRVersion fromCode(String codeString) throws FHIRException {
|
||||
if (codeString == null || "".equals(codeString))
|
||||
|
@ -6824,6 +6824,10 @@ public String toCode(int len) {
|
|||
public String toString() {
|
||||
return toCode();
|
||||
}
|
||||
|
||||
public boolean isR4B() {
|
||||
return toCode().startsWith("4.1");
|
||||
}
|
||||
// end addition
|
||||
}
|
||||
|
||||
|
|
|
@ -67,10 +67,12 @@ public class GraphQLSchemaGenerator {
|
|||
private static final String INNER_TYPE_NAME = "gql.type.name";
|
||||
IWorkerContext context;
|
||||
private ProfileUtilities profileUtilities;
|
||||
private String version;
|
||||
|
||||
public GraphQLSchemaGenerator(IWorkerContext context) {
|
||||
public GraphQLSchemaGenerator(IWorkerContext context, String version) {
|
||||
super();
|
||||
this.context = context;
|
||||
this.version = version;
|
||||
profileUtilities = new ProfileUtilities(context, null, null);
|
||||
}
|
||||
|
||||
|
@ -87,7 +89,7 @@ public class GraphQLSchemaGenerator {
|
|||
tl.put(sd.getName(), sd);
|
||||
}
|
||||
}
|
||||
writer.write("# FHIR GraphQL Schema. Version "+Constants.VERSION+"\r\n\r\n");
|
||||
writer.write("# FHIR GraphQL Schema. Version "+version+"\r\n\r\n");
|
||||
writer.write("# FHIR Defined Primitive types\r\n");
|
||||
for (String n : sorted(pl.keySet()))
|
||||
generatePrimitive(writer, pl.get(n));
|
||||
|
@ -107,7 +109,7 @@ public class GraphQLSchemaGenerator {
|
|||
|
||||
public void generateResource(OutputStream stream, StructureDefinition sd, List<SearchParameter> parameters, EnumSet<FHIROperationType> operations) throws IOException, FHIRException {
|
||||
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(stream));
|
||||
writer.write("# FHIR GraphQL Schema. Version "+Constants.VERSION+"\r\n\r\n");
|
||||
writer.write("# FHIR GraphQL Schema. Version "+version+"\r\n\r\n");
|
||||
writer.write("# import the types from 'types.graphql'\r\n\r\n");
|
||||
generateType(writer, sd);
|
||||
if (operations.contains(FHIROperationType.READ))
|
||||
|
|
|
@ -276,6 +276,8 @@ public class NPMPackageGenerator {
|
|||
return "hl7.fhir.r3.core";
|
||||
if (v.startsWith("4.0"))
|
||||
return "hl7.fhir.r4.core";
|
||||
if (v.startsWith("4.1"))
|
||||
return "hl7.fhir.r4b.core";
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
|
@ -183,6 +183,7 @@ public class ToolingExtensions {
|
|||
public static final String EXT_MUST_SUPPORT = "http://hl7.org/fhir/StructureDefinition/elementdefinition-type-must-support";
|
||||
public static final String EXT_TRANSLATABLE = "http://hl7.org/fhir/StructureDefinition/elementdefinition-translatable";
|
||||
public static final String EXT_PATTERN = "http://hl7.org/fhir/StructureDefinition/elementdefinition-pattern";
|
||||
public static final String EXT_BINDING_METHOD = "http://hl7.org/fhir/StructureDefinition/elementdefinition-binding-method";
|
||||
|
||||
// specific extension helpers
|
||||
|
||||
|
|
|
@ -111,7 +111,7 @@ public class TypesUtilities {
|
|||
res.add(new WildcardInformation("id", TypeClassification.PRIMITIVE));
|
||||
res.add(new WildcardInformation("instant", TypeClassification.PRIMITIVE));
|
||||
res.add(new WildcardInformation("integer", TypeClassification.PRIMITIVE));
|
||||
if (!version.startsWith("4.0")) {
|
||||
if (!version.startsWith("4.1")) {
|
||||
res.add(new WildcardInformation("integer64", TypeClassification.PRIMITIVE));
|
||||
}
|
||||
res.add(new WildcardInformation("markdown", TypeClassification.PRIMITIVE));
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>org.hl7.fhir.core</artifactId>
|
||||
<version>5.2.21-SNAPSHOT</version>
|
||||
<version>5.3.7-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>org.hl7.fhir.core</artifactId>
|
||||
<version>5.2.21-SNAPSHOT</version>
|
||||
<version>5.3.7-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -465,4 +465,5 @@ public class VersionUtilities {
|
|||
return null;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -361,6 +361,8 @@ public class I18nConstants {
|
|||
public static final String SD_ED_BIND_UNKNOWN_VS = "SD_ED_BIND_UNKNOWN_VS";
|
||||
public static final String SD_ED_BIND_NOT_VS = "SD_ED_BIND_NOT_VS";
|
||||
public static final String SD_ED_BIND_NO_BINDABLE = "SD_ED_BIND_NO_BINDABLE";
|
||||
public static final String SD_VALUE_TYPE_IILEGAL = "SD_VALUE_TYPE_IILEGAL";
|
||||
public static final String SD_NO_TYPES_OR_CONTENTREF = "SD_NO_TYPES_OR_CONTENTREF";
|
||||
public static final String SEARCHPARAMETER_BASE_WRONG = "SEARCHPARAMETER_BASE_WRONG";
|
||||
public static final String SEARCHPARAMETER_EXP_WRONG = "SEARCHPARAMETER_EXP_WRONG";
|
||||
public static final String SEARCHPARAMETER_NOTFOUND = "SEARCHPARAMETER_NOTFOUND";
|
||||
|
@ -386,9 +388,9 @@ public class I18nConstants {
|
|||
public static final String TERMINOLOGY_TX_CODE_VALUESETMAX = "Terminology_TX_Code_ValueSetMax";
|
||||
public static final String TERMINOLOGY_TX_CODE_VALUESET_EXT = "Terminology_TX_Code_ValueSet_Ext";
|
||||
public static final String TERMINOLOGY_TX_CODING_COUNT = "Terminology_TX_Coding_Count";
|
||||
public static final String TERMINOLOGY_TX_CONFIRM_1 = "Terminology_TX_Confirm_1";
|
||||
public static final String TERMINOLOGY_TX_CONFIRM_2 = "Terminology_TX_Confirm_2";
|
||||
public static final String TERMINOLOGY_TX_CONFIRM_3 = "Terminology_TX_Confirm_3";
|
||||
public static final String TERMINOLOGY_TX_CONFIRM_1_CC = "Terminology_TX_Confirm_1_CC";
|
||||
public static final String TERMINOLOGY_TX_CONFIRM_2_CC = "Terminology_TX_Confirm_2_CC";
|
||||
public static final String TERMINOLOGY_TX_CONFIRM_3_CC = "Terminology_TX_Confirm_3_CC";
|
||||
public static final String TERMINOLOGY_TX_CONFIRM_4a = "Terminology_TX_Confirm_4a";
|
||||
public static final String TERMINOLOGY_TX_CONFIRM_4b = "Terminology_TX_Confirm_4b";
|
||||
public static final String TERMINOLOGY_TX_CONFIRM_5 = "Terminology_TX_Confirm_5";
|
||||
|
@ -398,7 +400,7 @@ public class I18nConstants {
|
|||
public static final String TERMINOLOGY_TX_ERROR_CODEABLECONCEPT_MAX = "Terminology_TX_Error_CodeableConcept_Max";
|
||||
public static final String TERMINOLOGY_TX_ERROR_CODING1 = "Terminology_TX_Error_Coding1";
|
||||
public static final String TERMINOLOGY_TX_ERROR_CODING2 = "Terminology_TX_Error_Coding2";
|
||||
public static final String TERMINOLOGY_TX_NOVALID_1 = "Terminology_TX_NoValid_1";
|
||||
public static final String TERMINOLOGY_TX_NOVALID_1_CC = "Terminology_TX_NoValid_1_CC";
|
||||
public static final String TERMINOLOGY_TX_NOVALID_10 = "Terminology_TX_NoValid_10";
|
||||
public static final String TERMINOLOGY_TX_NOVALID_11 = "Terminology_TX_NoValid_11";
|
||||
public static final String TERMINOLOGY_TX_NOVALID_12 = "Terminology_TX_NoValid_12";
|
||||
|
@ -408,8 +410,8 @@ public class I18nConstants {
|
|||
public static final String TERMINOLOGY_TX_NOVALID_16 = "Terminology_TX_NoValid_16";
|
||||
public static final String TERMINOLOGY_TX_NOVALID_17 = "Terminology_TX_NoValid_17";
|
||||
public static final String TERMINOLOGY_TX_NOVALID_18 = "Terminology_TX_NoValid_18";
|
||||
public static final String TERMINOLOGY_TX_NOVALID_2 = "Terminology_TX_NoValid_2";
|
||||
public static final String TERMINOLOGY_TX_NOVALID_3 = "Terminology_TX_NoValid_3";
|
||||
public static final String TERMINOLOGY_TX_NOVALID_2_CC = "Terminology_TX_NoValid_2_CC";
|
||||
public static final String TERMINOLOGY_TX_NOVALID_3_CC = "Terminology_TX_NoValid_3_CC";
|
||||
public static final String TERMINOLOGY_TX_NOVALID_4 = "Terminology_TX_NoValid_4";
|
||||
public static final String TERMINOLOGY_TX_NOVALID_5 = "Terminology_TX_NoValid_5";
|
||||
public static final String TERMINOLOGY_TX_NOVALID_6 = "Terminology_TX_NoValid_6";
|
||||
|
|
|
@ -64,26 +64,37 @@ public abstract class BasePackageCacheManager implements IPackageCacheManager {
|
|||
protected InputStreamWithSrc loadFromPackageServer(String id, String version) {
|
||||
|
||||
for (String nextPackageServer : getPackageServers()) {
|
||||
PackageClient packageClient = myClientFactory.apply(nextPackageServer);
|
||||
try {
|
||||
if (Utilities.noString(version)) {
|
||||
version = packageClient.getLatestVersion(id);
|
||||
if (okToUsePackageServer(nextPackageServer, id)) {
|
||||
PackageClient packageClient = myClientFactory.apply(nextPackageServer);
|
||||
try {
|
||||
if (Utilities.noString(version)) {
|
||||
version = packageClient.getLatestVersion(id);
|
||||
}
|
||||
if (version.endsWith(".x")) {
|
||||
version = packageClient.getLatestVersion(id, version);
|
||||
}
|
||||
InputStream stream = packageClient.fetch(id, version);
|
||||
String url = packageClient.url(id, version);
|
||||
return new InputStreamWithSrc(stream, url, version);
|
||||
} catch (IOException e) {
|
||||
ourLog.info("Failed to resolve package {}#{} from server: {}", id, version, nextPackageServer);
|
||||
}
|
||||
if (version.endsWith(".x")) {
|
||||
version = packageClient.getLatestVersion(id, version);
|
||||
}
|
||||
InputStream stream = packageClient.fetch(id, version);
|
||||
String url = packageClient.url(id, version);
|
||||
return new InputStreamWithSrc(stream, url, version);
|
||||
} catch (IOException e) {
|
||||
ourLog.info("Failed to resolve package {}#{} from server: {}", id, version, nextPackageServer);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
// hack - we have a hacked 1.4.0 out there. Only packages2.fhir.org has it.
|
||||
// this is not a long term thing, but it's not clear how to release patches for
|
||||
// 1.4.0
|
||||
private boolean okToUsePackageServer(String server, String id) {
|
||||
if ("http://packages.fhir.org".equals(server) && "hl7.fhir.r2b.core".equals(id)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public abstract NpmPackage loadPackageFromCacheOnly(String id, @Nullable String version) throws IOException;
|
||||
|
||||
@Override
|
||||
|
@ -107,7 +118,7 @@ public abstract class BasePackageCacheManager implements IPackageCacheManager {
|
|||
|
||||
private String getPackageUrl(String packageId, String server) throws IOException {
|
||||
PackageClient pc = myClientFactory.apply(server);
|
||||
List<PackageClient.PackageInfo> res = pc.search(packageId, null, null, false);
|
||||
List<PackageInfo> res = pc.search(packageId, null, null, false);
|
||||
if (res.size() == 0) {
|
||||
return null;
|
||||
} else {
|
||||
|
@ -135,12 +146,12 @@ public abstract class BasePackageCacheManager implements IPackageCacheManager {
|
|||
return null;
|
||||
}
|
||||
PackageClient pc = myClientFactory.apply(server);
|
||||
List<PackageClient.PackageInfo> res = pc.search(null, canonical, null, false);
|
||||
List<PackageInfo> res = pc.search(null, canonical, null, false);
|
||||
if (res.size() == 0) {
|
||||
return null;
|
||||
} else {
|
||||
// this is driven by HL7 Australia (http://hl7.org.au/fhir/ is the canonical url for the base package, and the root for all the others)
|
||||
for (PackageClient.PackageInfo pi : res) {
|
||||
for (PackageInfo pi : res) {
|
||||
if (canonical.equals(pi.getCanonical())) {
|
||||
return pi.getId();
|
||||
}
|
||||
|
|
|
@ -53,12 +53,10 @@ import java.io.FileNotFoundException;
|
|||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.RandomAccessFile;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.nio.channels.FileChannel;
|
||||
import java.nio.channels.FileLock;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.sql.Timestamp;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
|
@ -207,8 +205,8 @@ public class FilesystemPackageCacheManager extends BasePackageCacheManager imple
|
|||
|
||||
private void listSpecs(Map<String, String> specList, String server) throws IOException {
|
||||
CachingPackageClient pc = new CachingPackageClient(server);
|
||||
List<PackageClient.PackageInfo> matches = pc.search(null, null, null, false);
|
||||
for (PackageClient.PackageInfo m : matches) {
|
||||
List<PackageInfo> matches = pc.search(null, null, null, false);
|
||||
for (PackageInfo m : matches) {
|
||||
if (!specList.containsKey(m.getId())) {
|
||||
specList.put(m.getId(), m.getUrl());
|
||||
}
|
||||
|
|
|
@ -10,8 +10,6 @@ import org.hl7.fhir.utilities.VersionUtilities;
|
|||
import org.hl7.fhir.utilities.json.JSONUtil;
|
||||
import org.hl7.fhir.utilities.json.JsonTrackingParser;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
@ -25,51 +23,6 @@ import java.util.Set;
|
|||
|
||||
public class PackageClient {
|
||||
|
||||
public class PackageInfo {
|
||||
private String id;
|
||||
private String version;
|
||||
private String fhirVersion;
|
||||
private String description;
|
||||
private String url;
|
||||
private String canonical;
|
||||
|
||||
public PackageInfo(String id, String version, String fhirVersion, String description, String url, String canonical) {
|
||||
super();
|
||||
this.id = id;
|
||||
this.version = version;
|
||||
this.fhirVersion = fhirVersion;
|
||||
this.description = description;
|
||||
this.url = url;
|
||||
if (url == null && id != null && version != null) {
|
||||
url = Utilities.pathURL(address, id, version);
|
||||
}
|
||||
this.canonical = canonical;
|
||||
}
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
public String getVersion() {
|
||||
return version;
|
||||
}
|
||||
public String getFhirVersion() {
|
||||
return fhirVersion;
|
||||
}
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
public String getUrl() {
|
||||
return url;
|
||||
}
|
||||
|
||||
public String getCanonical() {
|
||||
return canonical;
|
||||
}
|
||||
@Override
|
||||
public String toString() {
|
||||
return id+"#"+(version == null ? "?pc-pi?" : version)+(fhirVersion == null ? "": " ("+canonical+") for FHIR "+fhirVersion)+(url == null ? "" : " @"+url)+(description == null ? "" : " '"+description+"'");
|
||||
}
|
||||
}
|
||||
|
||||
private String address;
|
||||
private String cacheFolder;
|
||||
|
||||
|
@ -124,7 +77,13 @@ public class PackageClient {
|
|||
if (versions != null) {
|
||||
for (String v : sorted(versions.keySet())) {
|
||||
JsonObject obj = versions.getAsJsonObject(v);
|
||||
res.add(new PackageInfo(JSONUtil.str(obj, "name"), JSONUtil.str(obj, "version"), JSONUtil.str(obj, "FhirVersion"), JSONUtil.str(obj, "description"), JSONUtil.str(obj, "url"), JSONUtil.str(obj, "canonical")));
|
||||
res.add(new PackageInfo(JSONUtil.str(obj, "name"),
|
||||
JSONUtil.str(obj, "version"),
|
||||
JSONUtil.str(obj, "FhirVersion"),
|
||||
JSONUtil.str(obj, "description"),
|
||||
JSONUtil.str(obj, "url"),
|
||||
JSONUtil.str(obj, "canonical"),
|
||||
address));
|
||||
}
|
||||
}
|
||||
} catch (FileNotFoundException e) {
|
||||
|
@ -158,7 +117,13 @@ public class PackageClient {
|
|||
JsonArray json = fetchJsonArray(Utilities.pathURL(address, "catalog?")+params.toString());
|
||||
for (JsonElement e : json) {
|
||||
JsonObject obj = (JsonObject) e;
|
||||
res.add(new PackageInfo(JSONUtil.str(obj, "Name", "name"), JSONUtil.str(obj, "Version", "version"), JSONUtil.str(obj, "FhirVersion", "fhirVersion"), JSONUtil.str(obj, "Description", "description"), JSONUtil.str(obj, "url"), JSONUtil.str(obj, "canonical")));
|
||||
res.add(new PackageInfo(JSONUtil.str(obj, "Name", "name"),
|
||||
JSONUtil.str(obj, "Version", "version"),
|
||||
JSONUtil.str(obj, "FhirVersion", "fhirVersion"),
|
||||
JSONUtil.str(obj, "Description", "description"),
|
||||
JSONUtil.str(obj, "url"),
|
||||
JSONUtil.str(obj, "canonical"),
|
||||
address));
|
||||
}
|
||||
} catch (IOException e1) {
|
||||
}
|
||||
|
@ -199,10 +164,10 @@ public class PackageClient {
|
|||
if (list.isEmpty()) {
|
||||
throw new IOException("Package not found: "+id);
|
||||
} else {
|
||||
String v = list.get(0).version;
|
||||
String v = list.get(0).getVersion();
|
||||
for (PackageInfo p : list) {
|
||||
if (VersionUtilities.isThisOrLater(v, p.version)) {
|
||||
v = p.version;
|
||||
if (VersionUtilities.isThisOrLater(v, p.getVersion())) {
|
||||
v = p.getVersion();
|
||||
}
|
||||
}
|
||||
return v;
|
||||
|
@ -216,8 +181,8 @@ public class PackageClient {
|
|||
} else {
|
||||
String v = majMinVersion;
|
||||
for (PackageInfo p : list) {
|
||||
if (VersionUtilities.isMajMinOrLaterPatch(v, p.version)) {
|
||||
v = p.version;
|
||||
if (VersionUtilities.isMajMinOrLaterPatch(v, p.getVersion())) {
|
||||
v = p.getVersion();
|
||||
}
|
||||
}
|
||||
return v;
|
||||
|
@ -259,7 +224,7 @@ public class PackageClient {
|
|||
}
|
||||
}
|
||||
if (version != null) {
|
||||
result.add(new PackageInfo(id, version, fVersion, description, url, pcanonical));
|
||||
result.add(new PackageInfo(id, version, fVersion, description, url, pcanonical, address));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,6 +35,8 @@ import java.io.IOException;
|
|||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.hl7.fhir.utilities.TextFile;
|
||||
import org.hl7.fhir.utilities.Utilities;
|
||||
|
@ -109,20 +111,29 @@ public class PackageGenerator {
|
|||
object.addProperty("version", value);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public PackageGenerator toolsVersion(int value) {
|
||||
object.addProperty("tools-version", value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public PackageGenerator fhirVersions(List<String> versions) {
|
||||
JsonArray fhirVersionsArray = new JsonArray();
|
||||
for (String version : versions) {
|
||||
fhirVersionsArray.add(version);
|
||||
}
|
||||
object.add("fhirVersions", fhirVersionsArray);
|
||||
return this;
|
||||
}
|
||||
|
||||
public PackageGenerator description(String value) {
|
||||
object.addProperty("description", value);
|
||||
return this;
|
||||
return this;
|
||||
}
|
||||
|
||||
public PackageGenerator license(String value) {
|
||||
object.addProperty("license", value);
|
||||
return this;
|
||||
return this;
|
||||
}
|
||||
|
||||
public PackageGenerator homepage(String value) {
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
package org.hl7.fhir.utilities.npm;
|
||||
|
||||
import org.hl7.fhir.utilities.Utilities;
|
||||
|
||||
public class PackageInfo {
|
||||
private final String id;
|
||||
private final String version;
|
||||
private final String fhirVersion;
|
||||
private final String description;
|
||||
private final String url;
|
||||
private final String canonical;
|
||||
|
||||
public PackageInfo(String id, String version, String fhirVersion, String description, String url, String canonical) {
|
||||
this(id, version, fhirVersion, description, url, canonical, null);
|
||||
}
|
||||
|
||||
public PackageInfo(String id, String version, String fhirVersion, String description, String url, String canonical, String address) {
|
||||
super();
|
||||
this.id = id;
|
||||
this.version = version;
|
||||
this.fhirVersion = fhirVersion;
|
||||
this.description = description;
|
||||
if (url == null && id != null && version != null) {
|
||||
this.url = Utilities.pathURL(address, id, version);
|
||||
} else {
|
||||
this.url = url;
|
||||
}
|
||||
this.canonical = canonical;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
public String getFhirVersion() {
|
||||
return fhirVersion;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public String getUrl() {
|
||||
return url;
|
||||
}
|
||||
|
||||
public String getCanonical() {
|
||||
return canonical;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return id + "#" + (version == null ? "?pc-pi?" : version) + (fhirVersion == null ? "" : " (" + canonical + ") for FHIR " + fhirVersion) + (url == null ? "" : " @" + url) + (description == null ? "" : " '" + description + "'");
|
||||
}
|
||||
}
|
|
@ -111,7 +111,7 @@ public class XmlGenerator {
|
|||
}
|
||||
|
||||
private void processElement(Element element) throws IOException, FHIRException {
|
||||
if (!xml.getDefaultNamespace().equals(element.getNamespaceURI()))
|
||||
if (xml.getDefaultNamespace() == null || !xml.getDefaultNamespace().equals(element.getNamespaceURI()))
|
||||
xml.setDefaultNamespace(element.getNamespaceURI());
|
||||
|
||||
processAttributes(element);
|
||||
|
|
|
@ -133,9 +133,9 @@ Terminology_TX_Code_ValueSet = No code provided, and a code is required from the
|
|||
Terminology_TX_Code_ValueSetMax = No code provided, and a code must be provided from the value set {0} (max value set {1})
|
||||
Terminology_TX_Code_ValueSet_Ext = No code provided, and a code should be provided from the value set {0} ({1})
|
||||
Terminology_TX_Coding_Count = Expected {0} but found {1} coding elements
|
||||
Terminology_TX_Confirm_1 = Could not confirm that the codes provided are in the value set {0} and a code from this value set is required (class = {1})
|
||||
Terminology_TX_Confirm_2 = Could not confirm that the codes provided are in the value set {0} and a code should come from this value set unless it has no suitable code (the validator cannot judge what is suitable) (class = {1})
|
||||
Terminology_TX_Confirm_3 = Could not confirm that the codes provided are in the value set {0} and a code is recommended to come from this value set (class = {1})
|
||||
Terminology_TX_Confirm_1_CC = Could not confirm that the codings provided are in the value set {0} and a coding from this value set is required (class = {1})
|
||||
Terminology_TX_Confirm_2_CC = Could not confirm that the codings provided are in the value set {0} and a coding should come from this value set unless it has no suitable code (the validator cannot judge what is suitable) (class = {1})
|
||||
Terminology_TX_Confirm_3_CC = Could not confirm that the codings provided are in the value set {0} and a coding is recommended to come from this value set (class = {1})
|
||||
Terminology_TX_Confirm_4a = The code provided ({2}) is not in the value set {0}, and a code from this value set is required: {1}
|
||||
Terminology_TX_Confirm_4b = The codes provided ({2}) are not in the value set {0}, and a code from this value set is required: {1}
|
||||
Terminology_TX_Confirm_5 = Could not confirm that the codes provided are in the value set {0}, and a code should come from this value set unless it has no suitable code (the validator cannot judge what is suitable)
|
||||
|
@ -145,18 +145,18 @@ Terminology_TX_Error_CodeableConcept = Error {0} validating CodeableConcept
|
|||
Terminology_TX_Error_CodeableConcept_Max = Error {0} validating CodeableConcept using maxValueSet
|
||||
Terminology_TX_Error_Coding1 = Error {0} validating Coding
|
||||
Terminology_TX_Error_Coding2 = Error {0} validating Coding: {1}
|
||||
Terminology_TX_NoValid_1 = None of the codes provided are in the value set {0} ({1}), and a code from this value set is required) (codes = {2})
|
||||
Terminology_TX_NoValid_1_CC = None of the codings provided are in the value set {0} ({1}), and a coding from this value set is required) (codes = {2})
|
||||
Terminology_TX_NoValid_10 = The code provided is not in the maximum value set {0} ({1}), and a code from this value set is required) (code = {2}#{3})
|
||||
Terminology_TX_NoValid_11 = The code provided is not in the maximum value set {0} ({1}{2})
|
||||
Terminology_TX_NoValid_12 = The Coding provided ({2}) is not in the value set {0}, and a code is required from this value set. {1}
|
||||
Terminology_TX_NoValid_13 = The Coding provided ({2}) is not in the value set {0}, and a code should come from this value set unless it has no suitable code (the validator cannot judge what is suitable). {1}
|
||||
Terminology_TX_NoValid_13 = The Coding provided ({2}) is not in the value set {0}, and a code should come from this value set unless it has no suitable code (note that the validator cannot judge what is suitable). {1}
|
||||
Terminology_TX_NoValid_14 = The Coding provided ({2}) is not in the value set {0}, and a code is recommended to come from this value set. {1}
|
||||
Terminology_TX_NoValid_15 = The value provided (''{0}'') could not be validated in the absence of a terminology server
|
||||
Terminology_TX_NoValid_16 = The value provided (''{0}'') is not in the value set {1} ({2}), and a code is required from this value set){3}
|
||||
Terminology_TX_NoValid_17 = The value provided (''{0}'') is not in the value set {1} ({2}), and a code should come from this value set unless it has no suitable code and the validator cannot judge what is suitable) {3}
|
||||
Terminology_TX_NoValid_17 = The value provided (''{0}'') is not in the value set {1} ({2}), and a code should come from this value set unless it has no suitable code (note that the validator cannot judge what is suitable) {3}
|
||||
Terminology_TX_NoValid_18 = The value provided (''{0}'') is not in the value set {1} ({2}), and a code is recommended to come from this value set){3}
|
||||
Terminology_TX_NoValid_2 = None of the codes provided are in the value set {0} ({1}), and a code should come from this value set unless it has no suitable code and the validator cannot judge what is suitable) (codes = {2})
|
||||
Terminology_TX_NoValid_3 = None of the codes provided are in the value set {0} ({1}), and a code is recommended to come from this value set) (codes = {2})
|
||||
Terminology_TX_NoValid_2_CC = None of the codings provided are in the value set {0} ({1}), and a coding should come from this value set unless it has no suitable code (note that the validator cannot judge what is suitable) (codes = {2})
|
||||
Terminology_TX_NoValid_3_CC = None of the codings provided are in the value set {0} ({1}), and a coding is recommended to come from this value set) (codes = {2})
|
||||
Terminology_TX_NoValid_4 = The Coding provided ({2}) is not in the value set {0}, and a code is required from this value set {1}
|
||||
Terminology_TX_NoValid_5 = The Coding provided ({2}) is not in the value set {0}, and a code should come from this value set unless it has no suitable code (the validator cannot judge what is suitable) {1}
|
||||
Terminology_TX_NoValid_6 = The Coding provided ({2}) is not in the value set {0}, and a code is recommended to come from this value set {1}
|
||||
|
@ -325,7 +325,7 @@ Adding_wrong_path_in_profile___vs_ = Adding wrong path in profile {0}: {1} vs {2
|
|||
_has_no_children__and_no_types_in_profile_ = {0} has no children ({1}) and no types in profile {2}
|
||||
not_done_yet = not done yet
|
||||
Did_not_find_single_slice_ = Did not find single slice: {0}
|
||||
Differential_does_not_have_a_slice__b_of_____in_profile_ = Differential does not have a slice: {0}/ (b:{1} of {2} / {3}/ {4}) in profile {5}
|
||||
Differential_does_not_have_a_slice__b_of_____in_profile_ = Differential in profile {5} does not have a slice at {6} (on {0}, position {1} of {2} / {3} / {4})
|
||||
Attempt_to_a_slice_an_element_that_does_not_repeat__from__in_ = Attempt to a slice an element that does not repeat: {0}/{1} from {2} in {3}, at element {4} (slice = {5})
|
||||
Unable_to_resolve_reference_to_ = Unable to resolve reference to {0}
|
||||
Unable_to_find_element__in_ = Unable to find element {0} in {1}
|
||||
|
@ -639,3 +639,5 @@ TYPE_SPECIFIC_CHECKS_DT_CANONICAL_TYPE = Canonical URL ''{0}'' refers to a resou
|
|||
CODESYSTEM_CS_NO_SUPPLEMENT = CodeSystem {0} is a supplement, so can't be used as a value in Coding.system
|
||||
CODESYSTEM_CS_SUPP_CANT_CHECK = CodeSystem {0} cannot be found, so can't check if concepts are valid
|
||||
CODESYSTEM_CS_SUPP_INVALID_CODE = The code ''{1}'' is not declared in the base CodeSystem {0} so is not valid in the supplement
|
||||
SD_VALUE_TYPE_IILEGAL = The element {0} has a {1} of type {2}, which is not in the list of allowed types ({3})
|
||||
SD_NO_TYPES_OR_CONTENTREF = The element {0} has no assigned types, and no content reference
|
||||
|
|
|
@ -128,9 +128,9 @@ Terminology_TX_Code_ValueSet=Es wird kein Code gesetzt, und es ist ein Code aus
|
|||
Terminology_TX_Code_ValueSetMax=Kein Code gesetzt, und es muss ein Code aus ValueSet {0} (max. Wertemenge {1}) gesetzt werden
|
||||
Terminology_TX_Code_ValueSet_Ext=Kein Code gesetzt, und es sollte ein Code aus ValueSet{0} ({1}) gesetzt werden
|
||||
Terminology_TX_Coding_Count=Erwartete {0}, aber gefundene {1} coding elements
|
||||
Terminology_TX_Confirm_1=Konnte nicht bestätigen, dass die angegebenen Codes im ValueSet {0} enthalten sind und ein Code aus diesem ValueSet ist erforderlich (class = {1})
|
||||
Terminology_TX_Confirm_2=Konnte nicht bestätigen, dass die angegebenen Codes im ValueSet {0} enthalten sind und ein Code aus diesem ValueSet stammen sollte. Es sei denn, es enthält keinen geeigneten Code (class = {1})
|
||||
Terminology_TX_Confirm_3=Konnte nicht bestätigen, dass die angegebenen Codes im ValueSet {0} enthalten sind, und es wird empfohlen einen Code aus diesem ValueSet zu verwenden (Klasse = {1})
|
||||
Terminology_TX_Confirm_1_CC=Konnte nicht bestätigen, dass die angegebenen Codes im ValueSet {0} enthalten sind und ein Code aus diesem ValueSet ist erforderlich (class = {1})
|
||||
Terminology_TX_Confirm_2_CC=Konnte nicht bestätigen, dass die angegebenen Codes im ValueSet {0} enthalten sind und ein Code aus diesem ValueSet stammen sollte. Es sei denn, es enthält keinen geeigneten Code (class = {1})
|
||||
Terminology_TX_Confirm_3_CC=Konnte nicht bestätigen, dass die angegebenen Codes im ValueSet {0} enthalten sind, und es wird empfohlen einen Code aus diesem ValueSet zu verwenden (Klasse = {1})
|
||||
Terminology_TX_Confirm_4=Konnte nicht bestätigen, dass die angegebenen Codes im ValueSet {0} enthalten sind, und ein Code aus diesem ValueSet ist erforderlich
|
||||
Terminology_TX_Confirm_5=Konnte nicht bestätigen, dass die angegebenen Codes im ValueSet {0} enthalten sind, und ein Code sollte aus diesem ValueSet stammen. Es sei denn, er hat enthält keinen geeigneten Code
|
||||
Terminology_TX_Confirm_6=Konnte nicht bestätigen, dass die angegebenen Codes im ValueSet {0} enthalten sind, und es wird empfohlen, einen Code aus diesem ValueSet zu verwenden.
|
||||
|
@ -139,7 +139,7 @@ Terminology_TX_Error_CodeableConcept=Fehler {0} bei der Validierung des Codeable
|
|||
Terminology_TX_Error_CodeableConcept_Max=Fehler {0} bei der Validierung des CodeableConcepts mit maxValueSet
|
||||
Terminology_TX_Error_Coding1=Fehler {0} bei der Validierung des Coding
|
||||
Terminology_TX_Error_Coding2=Fehler {0} bei der Validierung des Coding: {1}
|
||||
Terminology_TX_NoValid_1=Keiner der bereitgestellten Codes ist im ValueSet {0} ({1}, und ein Code aus diesem ValueSet ist erforderlich) (Codes = {2})
|
||||
Terminology_TX_NoValid_1_CC=Keiner der bereitgestellten Codes ist im ValueSet {0} ({1}, und ein Code aus diesem ValueSet ist erforderlich) (Codes = {2})
|
||||
Terminology_TX_NoValid_10=Der bereitgestellte Code ist nicht im maximum ValueSet {0} ({1}, und ein Code aus diesem ValueSet ist erforderlich) (Code = {2}#{3})
|
||||
Terminology_TX_NoValid_11=Der bereitgestellte Code ist nicht im maximum value set {0} ({1}{2}
|
||||
Terminology_TX_NoValid_12=Die angegebene Codierung ist nicht im ValueSet {0} enthalten, und es wird ein Code aus diesem ValueSet benötigt. {1}
|
||||
|
@ -149,8 +149,8 @@ Terminology_TX_NoValid_15=Der angegebene Wert ("{0}") konnte in Ermangelung eine
|
|||
Terminology_TX_NoValid_16=Der angegebene Wert ("{0}") ist nicht im ValueSet {1} ({2}, und ein Code aus diesem Valueset ist erforderlich){3}
|
||||
Terminology_TX_NoValid_17=Der angegebene Wert ("{0}") ist nicht im Valueset {1} ({2}, und ein Code sollte aus diesem Valueset stammen, es sei denn, er hat enthält geeigneten Code){3}
|
||||
Terminology_TX_NoValid_18=Der angegebene Wert ("{0}") ist nicht im Valueset {1} ({2}, und es wird empfohlen, einen Code aus diesem Valueset zu verwenden){3}
|
||||
Terminology_TX_NoValid_2=Keiner der angegebenen Codes ist im Valueset {0} ({1}, und ein Code sollte aus diesem Valueset stammen, es sei denn, er enthält keinen geeigneten Code) (Codes = {2})
|
||||
Terminology_TX_NoValid_3=Keiner der angegebenen Codes ist im Valueset {0} ({1}, und es wird empfohlen, einen Code aus dieserm Valueset zu verwenden) (Codes = {2})
|
||||
Terminology_TX_NoValid_2_CC=Keiner der angegebenen Codes ist im Valueset {0} ({1}, und ein Code sollte aus diesem Valueset stammen, es sei denn, er enthält keinen geeigneten Code) (Codes = {2})
|
||||
Terminology_TX_NoValid_3_CC=Keiner der angegebenen Codes ist im Valueset {0} ({1}, und es wird empfohlen, einen Code aus dieserm Valueset zu verwenden) (Codes = {2})
|
||||
Terminology_TX_NoValid_4=Die bereitgestellte Codierung ist nicht im Valueset {0}, und es wird ein Code aus diesem Valueset benötigt{1}
|
||||
Terminology_TX_NoValid_5=Die angegebene Codierung ist nicht im Valueset {0}, und ein Code sollte aus diesem Valueset stammen, es sei denn, er enthält keinen geeigneten Code{1}
|
||||
Terminology_TX_NoValid_6=Die bereitgestellte Codierung ist nicht im Valueset {0} enthalten, und es wird empfohlen, einen Code aus diesem Valueset zu verwenden{1}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package org.hl7.fhir.utilities.tests;
|
||||
|
||||
import org.hl7.fhir.utilities.npm.CachingPackageClient;
|
||||
import org.hl7.fhir.utilities.npm.PackageClient.PackageInfo;
|
||||
import org.hl7.fhir.utilities.npm.PackageInfo;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>org.hl7.fhir.core</artifactId>
|
||||
<version>5.2.21-SNAPSHOT</version>
|
||||
<version>5.3.7-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>org.hl7.fhir.core</artifactId>
|
||||
<version>5.2.21-SNAPSHOT</version>
|
||||
<version>5.3.7-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
@ -100,6 +100,11 @@
|
|||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpclient</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-collections4</artifactId>
|
||||
<version>4.4</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.fhir</groupId>
|
||||
<artifactId>ucum</artifactId>
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package org.hl7.fhir.validation;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import lombok.Getter;
|
||||
import org.hl7.fhir.convertors.*;
|
||||
import org.hl7.fhir.exceptions.FHIRException;
|
||||
|
@ -15,12 +16,15 @@ import org.hl7.fhir.utilities.IniFile;
|
|||
import org.hl7.fhir.utilities.TextFile;
|
||||
import org.hl7.fhir.utilities.Utilities;
|
||||
import org.hl7.fhir.utilities.VersionUtilities;
|
||||
import org.hl7.fhir.utilities.json.JSONUtil;
|
||||
import org.hl7.fhir.utilities.json.JsonTrackingParser;
|
||||
import org.hl7.fhir.utilities.npm.FilesystemPackageCacheManager;
|
||||
import org.hl7.fhir.utilities.npm.NpmPackage;
|
||||
import org.hl7.fhir.utilities.turtle.Turtle;
|
||||
import org.hl7.fhir.utilities.xml.XMLUtil;
|
||||
import org.hl7.fhir.validation.cli.utils.Common;
|
||||
import org.hl7.fhir.validation.cli.utils.VersionSourceInformation;
|
||||
import org.w3c.dom.Document;
|
||||
|
||||
import java.io.*;
|
||||
import java.net.HttpURLConnection;
|
||||
|
@ -61,7 +65,7 @@ public class IgLoader {
|
|||
|
||||
public void loadIg(List<ImplementationGuide> igs,
|
||||
Map<String, byte[]> binaries,
|
||||
String src,
|
||||
String src,
|
||||
boolean recursive) throws IOException, FHIRException {
|
||||
NpmPackage npm = src.matches(FilesystemPackageCacheManager.PACKAGE_VERSION_REGEX_OPT) && !new File(src).exists() ? getPackageCacheManager().loadPackage(src, null) : null;
|
||||
if (npm != null) {
|
||||
|
@ -143,7 +147,7 @@ public class IgLoader {
|
|||
* @throws IOException
|
||||
**/
|
||||
public Map<String, byte[]> loadIgSource(String src,
|
||||
boolean recursive,
|
||||
boolean recursive,
|
||||
boolean explore) throws FHIRException, IOException {
|
||||
// src can be one of the following:
|
||||
// - a canonical url for an ig - this will be converted to a package id and loaded into the cache
|
||||
|
@ -199,6 +203,43 @@ public class IgLoader {
|
|||
versions.see(readInfoVersion(source.get("version.info")), "version.info in " + src);
|
||||
}
|
||||
|
||||
public void scanForVersions(List<String> sources, VersionSourceInformation versions) throws FHIRException, IOException {
|
||||
List<String> refs = new ArrayList<String>();
|
||||
ValidatorUtils.parseSources(sources, refs, context);
|
||||
for (String ref : refs) {
|
||||
Content cnt = loadContent(ref, "validate", false);
|
||||
String s = TextFile.bytesToString(cnt.focus);
|
||||
if (s.contains("http://hl7.org/fhir/3.0")) {
|
||||
versions.see("3.0", "Profile in " + ref);
|
||||
}
|
||||
if (s.contains("http://hl7.org/fhir/1.0")) {
|
||||
versions.see("1.0", "Profile in " + ref);
|
||||
}
|
||||
if (s.contains("http://hl7.org/fhir/4.0")) {
|
||||
versions.see("4.0", "Profile in " + ref);
|
||||
}
|
||||
if (s.contains("http://hl7.org/fhir/1.4")) {
|
||||
versions.see("1.4", "Profile in " + ref);
|
||||
}
|
||||
try {
|
||||
if (s.startsWith("{")) {
|
||||
JsonObject json = JsonTrackingParser.parse(s, null);
|
||||
if (json.has("fhirVersion")) {
|
||||
versions.see(VersionUtilities.getMajMin(JSONUtil.str(json, "fhirVersion")), "fhirVersion in " + ref);
|
||||
}
|
||||
} else {
|
||||
Document doc = ValidatorUtils.parseXml(cnt.focus);
|
||||
String v = XMLUtil.getNamedChildValue(doc.getDocumentElement(), "fhirVersion");
|
||||
if (v != null) {
|
||||
versions.see(VersionUtilities.getMajMin(v), "fhirVersion in " + ref);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// nothing
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected Map<String, byte[]> readZip(InputStream stream) throws IOException {
|
||||
Map<String, byte[]> res = new HashMap<>();
|
||||
ZipInputStream zip = new ZipInputStream(stream);
|
||||
|
@ -521,7 +562,7 @@ public class IgLoader {
|
|||
for (File ff : f.listFiles()) {
|
||||
if (ff.isDirectory() && recursive) {
|
||||
res.putAll(scanDirectory(ff, true));
|
||||
} else if (!isIgnoreFile(ff)) {
|
||||
} else if (!ff.isDirectory() && !isIgnoreFile(ff)) {
|
||||
Manager.FhirFormat fmt = ResourceChecker.checkIsResource(getContext(), isDebug(), ff.getAbsolutePath());
|
||||
if (fmt != null) {
|
||||
res.put(Utilities.changeFileExt(ff.getName(), "." + fmt.getExtension()), TextFile.fileToBytes(ff.getAbsolutePath()));
|
||||
|
@ -645,7 +686,7 @@ public class IgLoader {
|
|||
else if (fn.endsWith(".json") && !fn.endsWith("template.json"))
|
||||
r = new JsonParser().parse(new ByteArrayInputStream(content));
|
||||
else if (fn.endsWith(".txt"))
|
||||
r = new StructureMapUtilities(context, null, null).parse(TextFile.bytesToString(content), fn);
|
||||
r = new StructureMapUtilities(getContext(), null, null).parse(TextFile.bytesToString(content), fn);
|
||||
else if (fn.endsWith(".map"))
|
||||
r = new StructureMapUtilities(null).parse(new String(content), fn);
|
||||
else
|
||||
|
|
|
@ -193,49 +193,12 @@ public class ValidationEngine implements IValidatorResourceFetcher, IPackageInst
|
|||
igLoader = new IgLoader(getPcm(), getContext(), getVersion(), isDebug());
|
||||
}
|
||||
|
||||
public ValidationEngine(String src, FhirPublication version, String vString, TimeTracker tt) throws FHIRException, IOException, URISyntaxException {
|
||||
public ValidationEngine(String src, String vString, TimeTracker tt) throws FHIRException, IOException, URISyntaxException {
|
||||
loadCoreDefinitions(src, false, tt);
|
||||
setVersion(vString);
|
||||
igLoader = new IgLoader(getPcm(), getContext(), getVersion(), isDebug());
|
||||
}
|
||||
|
||||
public void scanForVersions(List<String> sources, VersionSourceInformation versions) throws FHIRException, IOException {
|
||||
List<String> refs = new ArrayList<String>();
|
||||
ValidatorUtils.parseSources(sources, refs, context);
|
||||
for (String ref : refs) {
|
||||
Content cnt = igLoader.loadContent(ref, "validate", false);
|
||||
String s = TextFile.bytesToString(cnt.focus);
|
||||
if (s.contains("http://hl7.org/fhir/3.0")) {
|
||||
versions.see("3.0", "Profile in " + ref);
|
||||
}
|
||||
if (s.contains("http://hl7.org/fhir/1.0")) {
|
||||
versions.see("1.0", "Profile in " + ref);
|
||||
}
|
||||
if (s.contains("http://hl7.org/fhir/4.0")) {
|
||||
versions.see("4.0", "Profile in " + ref);
|
||||
}
|
||||
if (s.contains("http://hl7.org/fhir/1.4")) {
|
||||
versions.see("1.4", "Profile in " + ref);
|
||||
}
|
||||
try {
|
||||
if (s.startsWith("{")) {
|
||||
JsonObject json = JsonTrackingParser.parse(s, null);
|
||||
if (json.has("fhirVersion")) {
|
||||
versions.see(VersionUtilities.getMajMin(JSONUtil.str(json, "fhirVersion")), "fhirVersion in " + ref);
|
||||
}
|
||||
} else {
|
||||
Document doc = ValidatorUtils.parseXml(cnt.focus);
|
||||
String v = XMLUtil.getNamedChildValue(doc.getDocumentElement(), "fhirVersion");
|
||||
if (v != null) {
|
||||
versions.see(VersionUtilities.getMajMin(v), "fhirVersion in " + ref);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// nothing
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void loadCoreDefinitions(String src, boolean recursive, TimeTracker tt) throws FHIRException, IOException {
|
||||
NpmPackage npm = getPcm().loadPackage(src, null);
|
||||
if (npm != null) {
|
||||
|
@ -252,7 +215,7 @@ public class ValidationEngine implements IValidatorResourceFetcher, IPackageInst
|
|||
initContext(tt);
|
||||
}
|
||||
|
||||
public void initContext(TimeTracker tt) throws IOException, FileNotFoundException {
|
||||
public void initContext(TimeTracker tt) throws IOException {
|
||||
context.setCanNoTS(true);
|
||||
context.setCacheId(UUID.randomUUID().toString());
|
||||
context.setAllowLoadingDuplicates(true); // because of Forge
|
||||
|
|
|
@ -94,6 +94,8 @@ public class ValidatorCli {
|
|||
public static final String JAVA_DISABLED_PROXY_SCHEMES = "jdk.http.auth.proxying.disabledSchemes";
|
||||
public static final String JAVA_USE_SYSTEM_PROXIES = "java.net.useSystemProxies";
|
||||
|
||||
private static ValidationService validationService = new ValidationService();
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
TimeTracker tt = new TimeTracker();
|
||||
TimeTracker.Session tts = tt.start("Loading");
|
||||
|
@ -181,42 +183,42 @@ public class ValidatorCli {
|
|||
private static void doLeftRightComparison(String[] args, CliContext cliContext, TimeTracker tt) throws Exception {
|
||||
Display.printCliArgumentsAndInfo(args);
|
||||
if (cliContext.getSv() == null) {
|
||||
cliContext.setSv(ValidationService.determineVersion(cliContext));
|
||||
cliContext.setSv(validationService.determineVersion(cliContext));
|
||||
}
|
||||
String v = VersionUtilities.getCurrentVersion(cliContext.getSv());
|
||||
String definitions = VersionUtilities.packageForVersion(v) + "#" + v;
|
||||
ValidationEngine validator = ValidationService.getValidator(cliContext, definitions, tt);
|
||||
ValidationEngine validator = validationService.initializeValidator(cliContext, definitions, tt);
|
||||
ComparisonService.doLeftRightComparison(args, Params.getParam(args, Params.DESTINATION), validator);
|
||||
}
|
||||
|
||||
private static void doValidation(TimeTracker tt, TimeTracker.Session tts, CliContext cliContext) throws Exception {
|
||||
if (cliContext.getSv() == null) {
|
||||
cliContext.setSv(ValidationService.determineVersion(cliContext));
|
||||
cliContext.setSv(validationService.determineVersion(cliContext));
|
||||
}
|
||||
System.out.println("Loading");
|
||||
// Comment this out because definitions filename doesn't necessarily contain version (and many not even be 14 characters long).
|
||||
// Version gets spit out a couple of lines later after we've loaded the context
|
||||
String definitions = VersionUtilities.packageForVersion(cliContext.getSv()) + "#" + VersionUtilities.getCurrentVersion(cliContext.getSv());
|
||||
ValidationEngine validator = ValidationService.getValidator(cliContext, definitions, tt);
|
||||
ValidationEngine validator = validationService.initializeValidator(cliContext, definitions, tt);
|
||||
tts.end();
|
||||
switch (cliContext.getMode()) {
|
||||
case TRANSFORM:
|
||||
ValidationService.transform(cliContext, validator);
|
||||
validationService.transform(cliContext, validator);
|
||||
break;
|
||||
case NARRATIVE:
|
||||
ValidationService.generateNarrative(cliContext, validator);
|
||||
validationService.generateNarrative(cliContext, validator);
|
||||
break;
|
||||
case SNAPSHOT:
|
||||
ValidationService.generateSnapshot(cliContext, validator);
|
||||
validationService.generateSnapshot(cliContext, validator);
|
||||
break;
|
||||
case CONVERT:
|
||||
ValidationService.convertSources(cliContext, validator);
|
||||
validationService.convertSources(cliContext, validator);
|
||||
break;
|
||||
case FHIRPATH:
|
||||
ValidationService.evaluateFhirpath(cliContext, validator);
|
||||
validationService.evaluateFhirpath(cliContext, validator);
|
||||
break;
|
||||
case VERSION:
|
||||
ValidationService.transformVersion(cliContext, validator);
|
||||
validationService.transformVersion(cliContext, validator);
|
||||
break;
|
||||
case VALIDATION:
|
||||
case SCAN:
|
||||
|
@ -232,7 +234,7 @@ public class ValidatorCli {
|
|||
Scanner validationScanner = new Scanner(validator.getContext(), validator.getValidator(), validator.getIgLoader(), validator.getFhirPathEngine());
|
||||
validationScanner.validateScan(cliContext.getOutput(), cliContext.getSources());
|
||||
} else {
|
||||
ValidationService.validateSources(cliContext, validator);
|
||||
validationService.validateSources(cliContext, validator);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -18,11 +18,19 @@ public class ValidationRequest {
|
|||
return cliContext;
|
||||
}
|
||||
|
||||
@JsonProperty("sessionId")
|
||||
public String sessionId;
|
||||
|
||||
public ValidationRequest() {}
|
||||
|
||||
public ValidationRequest(CliContext cliContext, List<FileInfo> filesToValidate) {
|
||||
this(cliContext, filesToValidate, null);
|
||||
}
|
||||
|
||||
public ValidationRequest(CliContext cliContext, List<FileInfo> filesToValidate, String sessionToken) {
|
||||
this.cliContext = cliContext;
|
||||
this.filesToValidate = filesToValidate;
|
||||
this.sessionId = sessionToken;
|
||||
}
|
||||
|
||||
@JsonProperty("cliContext")
|
||||
|
@ -42,6 +50,17 @@ public class ValidationRequest {
|
|||
return this;
|
||||
}
|
||||
|
||||
@JsonProperty("sessionId")
|
||||
public String getSessionId() {
|
||||
return sessionId;
|
||||
}
|
||||
|
||||
@JsonProperty("sessionId")
|
||||
public ValidationRequest setSessionId(String sessionId) {
|
||||
this.sessionId = sessionId;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String listSourceFiles() {
|
||||
List<String> fileNames = new ArrayList<>();
|
||||
for (FileInfo fp : filesToValidate) {
|
||||
|
|
|
@ -10,10 +10,18 @@ public class ValidationResponse {
|
|||
@JsonProperty("outcomes")
|
||||
public List<ValidationOutcome> outcomes = new ArrayList<>();
|
||||
|
||||
@JsonProperty("sessionId")
|
||||
public String sessionId;
|
||||
|
||||
public ValidationResponse() {}
|
||||
|
||||
public ValidationResponse(List<ValidationOutcome> outcomes) {
|
||||
this(outcomes, null);
|
||||
}
|
||||
|
||||
public ValidationResponse(List<ValidationOutcome> outcomes, String sessionId) {
|
||||
this.outcomes = outcomes;
|
||||
this.sessionId = sessionId;
|
||||
}
|
||||
|
||||
@JsonProperty("outcomes")
|
||||
|
@ -27,6 +35,17 @@ public class ValidationResponse {
|
|||
return this;
|
||||
}
|
||||
|
||||
@JsonProperty("sessionId")
|
||||
public String getSessionId() {
|
||||
return sessionId;
|
||||
}
|
||||
|
||||
@JsonProperty("sessionId")
|
||||
public ValidationResponse setSessionId(String sessionId) {
|
||||
this.sessionId = sessionId;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ValidationResponse addOutcome(ValidationOutcome outcome) {
|
||||
if (outcomes == null) {
|
||||
outcomes = new ArrayList<>();
|
||||
|
|
|
@ -0,0 +1,95 @@
|
|||
package org.hl7.fhir.validation.cli.services;
|
||||
|
||||
import org.apache.commons.collections4.map.PassiveExpiringMap;
|
||||
import org.hl7.fhir.validation.ValidationEngine;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* SessionCache for storing and retrieving ValidationEngine instances, so callers do not have to re-instantiate a new
|
||||
* instance for each validation request.
|
||||
*/
|
||||
public class SessionCache {
|
||||
|
||||
protected static final long TIME_TO_LIVE = 60;
|
||||
protected static final TimeUnit TIME_UNIT = TimeUnit.MINUTES;
|
||||
|
||||
private final PassiveExpiringMap<String, ValidationEngine> cachedSessions;
|
||||
|
||||
public SessionCache() {
|
||||
cachedSessions = new PassiveExpiringMap<>(TIME_TO_LIVE, TIME_UNIT);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param sessionLength the constant amount of time an entry is available before it expires. A negative value results
|
||||
* in entries that NEVER expire. A zero value results in entries that ALWAYS expire.
|
||||
* @param sessionLengthUnit the unit of time for the timeToLive parameter, must not be null
|
||||
*/
|
||||
public SessionCache(long sessionLength, TimeUnit sessionLengthUnit) {
|
||||
cachedSessions = new PassiveExpiringMap<>(sessionLength, sessionLengthUnit);
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores the initialized {@link ValidationEngine} in the cache. Returns the session id that will be associated with
|
||||
* this instance.
|
||||
* @param validationEngine {@link ValidationEngine}
|
||||
* @return The {@link String} id associated with the stored instance.
|
||||
*/
|
||||
public String cacheSession(ValidationEngine validationEngine) {
|
||||
String generatedId = generateID();
|
||||
cachedSessions.put(generatedId, validationEngine);
|
||||
return generatedId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores the initialized {@link ValidationEngine} in the cache with the passed in id as the key. If a null key is
|
||||
* passed in, a new key is generated and returned.
|
||||
* @param sessionId The {@link String} key to associate with this stored {@link ValidationEngine}
|
||||
* @param validationEngine The {@link ValidationEngine} instance to cache.
|
||||
* @return The {@link String} id that will be associated with the stored {@link ValidationEngine}
|
||||
*/
|
||||
public String cacheSession(String sessionId, ValidationEngine validationEngine) {
|
||||
if(sessionId == null) {
|
||||
sessionId = cacheSession(validationEngine);
|
||||
} else {
|
||||
cachedSessions.put(sessionId, validationEngine);
|
||||
}
|
||||
return sessionId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the passed in {@link String} id exists in the set of stored session id.
|
||||
* @param sessionId The {@link String} id to search for.
|
||||
* @return {@link Boolean#TRUE} if such id exists.
|
||||
*/
|
||||
public boolean sessionExists(String sessionId) {
|
||||
return cachedSessions.containsKey(sessionId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the stored {@link ValidationEngine} associated with the passed in session id, if one such instance exists.
|
||||
* @param sessionId The {@link String} session id.
|
||||
* @return The {@link ValidationEngine} associated with the passed in id, or null if none exists.
|
||||
*/
|
||||
public ValidationEngine fetchSessionValidatorEngine(String sessionId) {
|
||||
return cachedSessions.get(sessionId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the set of stored session ids.
|
||||
* @return {@link Set} of session ids.
|
||||
*/
|
||||
public Set<String> getSessionIds() {
|
||||
return cachedSessions.keySet();
|
||||
}
|
||||
|
||||
/**
|
||||
* Session ids generated internally are UUID {@link String}.
|
||||
* @return A new {@link String} session id.
|
||||
*/
|
||||
private String generateID() {
|
||||
return UUID.randomUUID().toString();
|
||||
}
|
||||
}
|
|
@ -1,26 +1,20 @@
|
|||
package org.hl7.fhir.validation.cli.services;
|
||||
|
||||
import java.io.FileOutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.hl7.fhir.r5.context.SimpleWorkerContext;
|
||||
import org.hl7.fhir.r5.context.TerminologyCache;
|
||||
import org.hl7.fhir.r5.elementmodel.Manager;
|
||||
import org.hl7.fhir.r5.formats.IParser;
|
||||
import org.hl7.fhir.r5.formats.JsonParser;
|
||||
import org.hl7.fhir.r5.formats.XmlParser;
|
||||
import org.hl7.fhir.r5.model.Bundle;
|
||||
import org.hl7.fhir.r5.model.DomainResource;
|
||||
import org.hl7.fhir.r5.model.FhirPublication;
|
||||
import org.hl7.fhir.r5.model.OperationOutcome;
|
||||
import org.hl7.fhir.r5.model.Resource;
|
||||
import org.hl7.fhir.r5.model.StructureDefinition;
|
||||
import org.hl7.fhir.r5.model.*;
|
||||
import org.hl7.fhir.r5.model.StructureDefinition.StructureDefinitionKind;
|
||||
import org.hl7.fhir.r5.utils.ToolingExtensions;
|
||||
import org.hl7.fhir.utilities.TextFile;
|
||||
import org.hl7.fhir.utilities.TimeTracker;
|
||||
import org.hl7.fhir.utilities.Utilities;
|
||||
import org.hl7.fhir.utilities.VersionUtilities;
|
||||
import org.hl7.fhir.utilities.npm.FilesystemPackageCacheManager;
|
||||
import org.hl7.fhir.utilities.npm.ToolsVersion;
|
||||
import org.hl7.fhir.utilities.validation.ValidationMessage;
|
||||
import org.hl7.fhir.validation.IgLoader;
|
||||
import org.hl7.fhir.validation.ValidationEngine;
|
||||
|
@ -29,14 +23,32 @@ import org.hl7.fhir.validation.cli.model.*;
|
|||
import org.hl7.fhir.validation.cli.utils.EngineMode;
|
||||
import org.hl7.fhir.validation.cli.utils.VersionSourceInformation;
|
||||
|
||||
import java.io.FileOutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class ValidationService {
|
||||
|
||||
public static ValidationResponse validateSources(ValidationRequest request) throws Exception {
|
||||
private final SessionCache sessionCache;
|
||||
|
||||
public ValidationService() {
|
||||
sessionCache = new SessionCache();
|
||||
}
|
||||
|
||||
protected ValidationService(SessionCache cache) {
|
||||
this.sessionCache = cache;
|
||||
}
|
||||
|
||||
public ValidationResponse validateSources(ValidationRequest request) throws Exception {
|
||||
if (request.getCliContext().getSv() == null) {
|
||||
request.getCliContext().setSv(ValidationService.determineVersion(request.getCliContext()));
|
||||
String sv = determineVersion(request.getCliContext(), request.sessionId);
|
||||
request.getCliContext().setSv(sv);
|
||||
}
|
||||
|
||||
String definitions = VersionUtilities.packageForVersion(request.getCliContext().getSv()) + "#" + VersionUtilities.getCurrentVersion(request.getCliContext().getSv());
|
||||
ValidationEngine validator = ValidationService.getValidator(request.getCliContext(), definitions, new TimeTracker());
|
||||
|
||||
String sessionId = initializeValidator(request.getCliContext(), definitions, new TimeTracker(), request.sessionId);
|
||||
ValidationEngine validator = sessionCache.fetchSessionValidatorEngine(sessionId);
|
||||
|
||||
if (request.getCliContext().getProfiles().size() > 0) {
|
||||
System.out.println(" .. validate " + request.listSourceFiles() + " against " + request.getCliContext().getProfiles().toString());
|
||||
|
@ -44,7 +56,8 @@ public class ValidationService {
|
|||
System.out.println(" .. validate " + request.listSourceFiles());
|
||||
}
|
||||
|
||||
ValidationResponse response = new ValidationResponse();
|
||||
ValidationResponse response = new ValidationResponse().setSessionId(sessionId);
|
||||
|
||||
for (FileInfo fp : request.getFilesToValidate()) {
|
||||
List<ValidationMessage> messages = new ArrayList<>();
|
||||
validator.validate(fp.getFileContent().getBytes(), Manager.FhirFormat.getFhirFormat(fp.getFileType()),
|
||||
|
@ -56,23 +69,25 @@ public class ValidationService {
|
|||
return response;
|
||||
}
|
||||
|
||||
public static VersionSourceInformation scanForVersions(CliContext cliContext) throws Exception {
|
||||
public VersionSourceInformation scanForVersions(CliContext cliContext) throws Exception {
|
||||
VersionSourceInformation versions = new VersionSourceInformation();
|
||||
ValidationEngine ve = new ValidationEngine();
|
||||
IgLoader igLoader = new IgLoader(ve.getPcm(), ve.getContext(), ve.getVersion(), ve.isDebug());
|
||||
IgLoader igLoader = new IgLoader(
|
||||
new FilesystemPackageCacheManager(true, ToolsVersion.TOOLS_VERSION),
|
||||
SimpleWorkerContext.fromNothing(),
|
||||
null);
|
||||
for (String src : cliContext.getIgs()) {
|
||||
igLoader.scanForIgVersion(src, cliContext.isRecursive(), versions);
|
||||
}
|
||||
ve.scanForVersions(cliContext.getSources(), versions);
|
||||
igLoader.scanForVersions(cliContext.getSources(), versions);
|
||||
return versions;
|
||||
}
|
||||
|
||||
public static void validateSources(CliContext cliContext, ValidationEngine validator) throws Exception {
|
||||
|
||||
public void validateSources(CliContext cliContext, ValidationEngine validator) throws Exception {
|
||||
long start = System.currentTimeMillis();
|
||||
List<ValidationRecord> records = new ArrayList<>();
|
||||
Resource r = validator.validate(cliContext.getSources(), cliContext.getProfiles(), records);
|
||||
int ec = 0;
|
||||
System.out.println("Done. "+validator.getContext().clock().report());
|
||||
System.out.println("Done. " + validator.getContext().clock().report());
|
||||
System.out.println();
|
||||
|
||||
if (cliContext.getOutput() == null) {
|
||||
|
@ -98,24 +113,24 @@ public class ValidationService {
|
|||
s.close();
|
||||
}
|
||||
if (cliContext.getHtmlOutput() != null) {
|
||||
String html = new HTMLOutputGenerator(records).generate(System.currentTimeMillis()-start);
|
||||
String html = new HTMLOutputGenerator(records).generate(System.currentTimeMillis() - start);
|
||||
TextFile.stringToFile(html, cliContext.getHtmlOutput());
|
||||
System.out.println("HTML Summary in "+cliContext.getHtmlOutput());
|
||||
System.out.println("HTML Summary in " + cliContext.getHtmlOutput());
|
||||
}
|
||||
System.exit(ec > 0 ? 1 : 0);
|
||||
}
|
||||
|
||||
public static void convertSources(CliContext cliContext, ValidationEngine validator) throws Exception {
|
||||
public void convertSources(CliContext cliContext, ValidationEngine validator) throws Exception {
|
||||
System.out.println(" ...convert");
|
||||
validator.convert(cliContext.getSources().get(0), cliContext.getOutput());
|
||||
}
|
||||
|
||||
public static void evaluateFhirpath(CliContext cliContext, ValidationEngine validator) throws Exception {
|
||||
public void evaluateFhirpath(CliContext cliContext, ValidationEngine validator) throws Exception {
|
||||
System.out.println(" ...evaluating " + cliContext.getFhirpath());
|
||||
System.out.println(validator.evaluateFhirPath(cliContext.getSources().get(0), cliContext.getFhirpath()));
|
||||
}
|
||||
|
||||
public static void generateSnapshot(CliContext cliContext, ValidationEngine validator) throws Exception {
|
||||
public void generateSnapshot(CliContext cliContext, ValidationEngine validator) throws Exception {
|
||||
StructureDefinition r = validator.snapshot(cliContext.getSources().get(0), cliContext.getSv());
|
||||
System.out.println(" ...generated snapshot successfully");
|
||||
if (cliContext.getOutput() != null) {
|
||||
|
@ -123,7 +138,7 @@ public class ValidationService {
|
|||
}
|
||||
}
|
||||
|
||||
public static void generateNarrative(CliContext cliContext, ValidationEngine validator) throws Exception {
|
||||
public void generateNarrative(CliContext cliContext, ValidationEngine validator) throws Exception {
|
||||
DomainResource r = validator.generate(cliContext.getSources().get(0), cliContext.getSv());
|
||||
System.out.println(" ...generated narrative successfully");
|
||||
if (cliContext.getOutput() != null) {
|
||||
|
@ -131,7 +146,7 @@ public class ValidationService {
|
|||
}
|
||||
}
|
||||
|
||||
public static void transform(CliContext cliContext, ValidationEngine validator) throws Exception {
|
||||
public void transform(CliContext cliContext, ValidationEngine validator) throws Exception {
|
||||
if (cliContext.getSources().size() > 1)
|
||||
throw new Exception("Can only have one source when doing a transform (found " + cliContext.getSources() + ")");
|
||||
if (cliContext.getTxServer() == null)
|
||||
|
@ -166,7 +181,7 @@ public class ValidationService {
|
|||
}
|
||||
}
|
||||
|
||||
public static void transformVersion(CliContext cliContext, ValidationEngine validator) throws Exception {
|
||||
public void transformVersion(CliContext cliContext, ValidationEngine validator) throws Exception {
|
||||
if (cliContext.getSources().size() > 1) {
|
||||
throw new Exception("Can only have one source when converting versions (found " + cliContext.getSources() + ")");
|
||||
}
|
||||
|
@ -189,44 +204,54 @@ public class ValidationService {
|
|||
}
|
||||
}
|
||||
|
||||
public static ValidationEngine getValidator(CliContext cliContext, String definitions, TimeTracker tt) throws Exception {
|
||||
tt.milestone();
|
||||
System.out.print(" Load FHIR v" + cliContext.getSv() + " from " + definitions);
|
||||
FhirPublication ver = FhirPublication.fromCode(cliContext.getSv());
|
||||
ValidationEngine validator = new ValidationEngine(definitions, ver, cliContext.getSv(), tt);
|
||||
IgLoader igLoader = new IgLoader(validator.getPcm(), validator.getContext(), validator.getVersion(), validator.isDebug());
|
||||
System.out.println(" - "+validator.getContext().countAllCaches()+" resources ("+tt.milestone()+")");
|
||||
igLoader.loadIg(validator.getIgs(), validator.getBinaries(), "hl7.terminology", false);
|
||||
System.out.print(" Terminology server " + cliContext.getTxServer());
|
||||
String txver = validator.setTerminologyServer(cliContext.getTxServer(), cliContext.getTxLog(), ver);
|
||||
System.out.println(" - Version "+txver+" ("+tt.milestone()+")");
|
||||
validator.setDebug(cliContext.isDoDebug());
|
||||
for (String src : cliContext.getIgs()) {
|
||||
igLoader.loadIg(validator.getIgs(), validator.getBinaries(), src, cliContext.isRecursive());
|
||||
}
|
||||
System.out.print(" Get set... ");
|
||||
validator.setQuestionnaireMode(cliContext.getQuestionnaireMode());
|
||||
validator.setDoNative(cliContext.isDoNative());
|
||||
validator.setHintAboutNonMustSupport(cliContext.isHintAboutNonMustSupport());
|
||||
validator.setAnyExtensionsAllowed(cliContext.isAnyExtensionsAllowed());
|
||||
validator.setLanguage(cliContext.getLang());
|
||||
validator.setLocale(cliContext.getLocale());
|
||||
validator.setSnomedExtension(cliContext.getSnomedCTCode());
|
||||
validator.setAssumeValidRestReferences(cliContext.isAssumeValidRestReferences());
|
||||
validator.setNoExtensibleBindingMessages(cliContext.isNoExtensibleBindingMessages());
|
||||
validator.setSecurityChecks(cliContext.isSecurityChecks());
|
||||
validator.setCrumbTrails(cliContext.isCrumbTrails());
|
||||
validator.setShowTimes(cliContext.isShowTimes());
|
||||
validator.setFetcher(new StandAloneValidatorFetcher(validator.getPcm(), validator.getContext(), validator));
|
||||
validator.getBundleValidationRules().addAll(cliContext.getBundleValidationRules());
|
||||
TerminologyCache.setNoCaching(cliContext.isNoInternalCaching());
|
||||
validator.prepare(); // generate any missing snapshots
|
||||
System.out.println(" go ("+tt.milestone()+")");
|
||||
|
||||
return validator;
|
||||
public ValidationEngine initializeValidator(CliContext cliContext, String definitions, TimeTracker tt) throws Exception {
|
||||
return sessionCache.fetchSessionValidatorEngine(initializeValidator(cliContext, definitions, tt, null));
|
||||
}
|
||||
|
||||
public static int displayOperationOutcome(OperationOutcome oo, boolean hasMultiples) {
|
||||
public String initializeValidator(CliContext cliContext, String definitions, TimeTracker tt, String sessionId) throws Exception {
|
||||
tt.milestone();
|
||||
if (!sessionCache.sessionExists(sessionId)) {
|
||||
System.out.println("No such cached session exists for session id " + sessionId + ", re-instantiating validator.");
|
||||
System.out.print(" Load FHIR v" + cliContext.getSv() + " from " + definitions);
|
||||
ValidationEngine validator = new ValidationEngine(definitions, cliContext.getSv(), tt);
|
||||
sessionId = sessionCache.cacheSession(validator);
|
||||
|
||||
FhirPublication ver = FhirPublication.fromCode(cliContext.getSv());
|
||||
IgLoader igLoader = new IgLoader(validator.getPcm(), validator.getContext(), validator.getVersion(), validator.isDebug());
|
||||
System.out.println(" - " + validator.getContext().countAllCaches() + " resources (" + tt.milestone() + ")");
|
||||
igLoader.loadIg(validator.getIgs(), validator.getBinaries(), "hl7.terminology", false);
|
||||
System.out.print(" Terminology server " + cliContext.getTxServer());
|
||||
String txver = validator.setTerminologyServer(cliContext.getTxServer(), cliContext.getTxLog(), ver);
|
||||
System.out.println(" - Version " + txver + " (" + tt.milestone() + ")");
|
||||
validator.setDebug(cliContext.isDoDebug());
|
||||
for (String src : cliContext.getIgs()) {
|
||||
igLoader.loadIg(validator.getIgs(), validator.getBinaries(), src, cliContext.isRecursive());
|
||||
}
|
||||
System.out.print(" Get set... ");
|
||||
validator.setQuestionnaireMode(cliContext.getQuestionnaireMode());
|
||||
validator.setDoNative(cliContext.isDoNative());
|
||||
validator.setHintAboutNonMustSupport(cliContext.isHintAboutNonMustSupport());
|
||||
validator.setAnyExtensionsAllowed(cliContext.isAnyExtensionsAllowed());
|
||||
validator.setLanguage(cliContext.getLang());
|
||||
validator.setLocale(cliContext.getLocale());
|
||||
validator.setSnomedExtension(cliContext.getSnomedCTCode());
|
||||
validator.setAssumeValidRestReferences(cliContext.isAssumeValidRestReferences());
|
||||
validator.setNoExtensibleBindingMessages(cliContext.isNoExtensibleBindingMessages());
|
||||
validator.setSecurityChecks(cliContext.isSecurityChecks());
|
||||
validator.setCrumbTrails(cliContext.isCrumbTrails());
|
||||
validator.setShowTimes(cliContext.isShowTimes());
|
||||
validator.setFetcher(new StandAloneValidatorFetcher(validator.getPcm(), validator.getContext(), validator));
|
||||
validator.getBundleValidationRules().addAll(cliContext.getBundleValidationRules());
|
||||
TerminologyCache.setNoCaching(cliContext.isNoInternalCaching());
|
||||
validator.prepare(); // generate any missing snapshots
|
||||
System.out.println(" go (" + tt.milestone() + ")");
|
||||
} else {
|
||||
System.out.println("Cached session exists for session id " + sessionId + ", returning stored validator session id.");
|
||||
}
|
||||
return sessionId;
|
||||
}
|
||||
|
||||
public int displayOperationOutcome(OperationOutcome oo, boolean hasMultiples) {
|
||||
int error = 0;
|
||||
int warn = 0;
|
||||
int info = 0;
|
||||
|
@ -240,29 +265,29 @@ public class ValidationService {
|
|||
else
|
||||
info++;
|
||||
}
|
||||
|
||||
|
||||
if (hasMultiples) {
|
||||
System.out.print("-- ");
|
||||
System.out.print(file);
|
||||
System.out.print(" --");
|
||||
System.out.println(Utilities.padLeft("", '-', Integer.max(38, file.length()+6)));
|
||||
System.out.println(Utilities.padLeft("", '-', Integer.max(38, file.length() + 6)));
|
||||
}
|
||||
System.out.println((error == 0 ? "Success" : "*FAILURE*") + ": " + Integer.toString(error) + " errors, " + Integer.toString(warn) + " warnings, " + Integer.toString(info)+" notes");
|
||||
System.out.println((error == 0 ? "Success" : "*FAILURE*") + ": " + Integer.toString(error) + " errors, " + Integer.toString(warn) + " warnings, " + Integer.toString(info) + " notes");
|
||||
for (OperationOutcome.OperationOutcomeIssueComponent issue : oo.getIssue()) {
|
||||
System.out.println(getIssueSummary(issue));
|
||||
}
|
||||
if (hasMultiples) {
|
||||
System.out.print("---");
|
||||
System.out.print(Utilities.padLeft("", '-', file.length()));
|
||||
System.out.print(Utilities.padLeft("", '-', file.length()));
|
||||
System.out.print("---");
|
||||
System.out.println(Utilities.padLeft("", '-', Integer.max(38, file.length()+6)));
|
||||
System.out.println(Utilities.padLeft("", '-', Integer.max(38, file.length() + 6)));
|
||||
System.out.println();
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
private static String getIssueSummary(OperationOutcome.OperationOutcomeIssueComponent issue) {
|
||||
String loc = null;
|
||||
private String getIssueSummary(OperationOutcome.OperationOutcomeIssueComponent issue) {
|
||||
String loc;
|
||||
if (issue.hasExpression()) {
|
||||
int line = ToolingExtensions.readIntegerExtension(issue, ToolingExtensions.EXT_ISSUE_LINE, -1);
|
||||
int col = ToolingExtensions.readIntegerExtension(issue, ToolingExtensions.EXT_ISSUE_COL, -1);
|
||||
|
@ -277,12 +302,16 @@ public class ValidationService {
|
|||
return " " + issue.getSeverity().getDisplay() + " @ " + loc + " : " + issue.getDetails().getText();
|
||||
}
|
||||
|
||||
public static String determineVersion(CliContext cliContext) throws Exception {
|
||||
public String determineVersion(CliContext cliContext) throws Exception {
|
||||
return determineVersion(cliContext, null);
|
||||
}
|
||||
|
||||
public String determineVersion(CliContext cliContext, String sessionId) throws Exception {
|
||||
if (cliContext.getMode() != EngineMode.VALIDATION) {
|
||||
return "current";
|
||||
}
|
||||
System.out.println("Scanning for versions (no -version parameter):");
|
||||
VersionSourceInformation versions = ValidationService.scanForVersions(cliContext);
|
||||
VersionSourceInformation versions = scanForVersions(cliContext);
|
||||
for (String s : versions.getReport()) {
|
||||
if (!s.equals("(nothing found)")) {
|
||||
System.out.println(" " + s);
|
||||
|
|
|
@ -87,7 +87,7 @@ public class Common {
|
|||
|
||||
public static ValidationEngine getValidationEngine(String version, String txServer, String definitions, String txLog, TimeTracker tt) throws Exception {
|
||||
System.out.println("Loading (v = " + version + ", tx server -> " + txServer + ")");
|
||||
ValidationEngine ve = new ValidationEngine(definitions, FhirPublication.fromCode(version), version, tt);
|
||||
ValidationEngine ve = new ValidationEngine(definitions, version, tt);
|
||||
ve.connectToTSServer(txServer, txLog, FhirPublication.fromCode(version));
|
||||
return ve;
|
||||
}
|
||||
|
|
|
@ -8,8 +8,8 @@ import java.util.List;
|
|||
|
||||
public class VersionSourceInformation {
|
||||
|
||||
private List<String> report = new ArrayList<>();
|
||||
private List<String> versions = new ArrayList<>();
|
||||
private final List<String> report = new ArrayList<>();
|
||||
private final List<String> versions = new ArrayList<>();
|
||||
|
||||
public void see(String version, String src) {
|
||||
version = VersionUtilities.getMajMin(version);
|
||||
|
|
|
@ -1023,28 +1023,28 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
}
|
||||
} else if (vr.getErrorClass() != null && vr.getErrorClass().isInfrastructure()) {
|
||||
if (binding.getStrength() == BindingStrength.REQUIRED)
|
||||
txWarning(errors, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_CONFIRM_1, describeReference(binding.getValueSet()), vr.getErrorClass().toString());
|
||||
txWarning(errors, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_CONFIRM_1_CC, describeReference(binding.getValueSet()), vr.getErrorClass().toString());
|
||||
else if (binding.getStrength() == BindingStrength.EXTENSIBLE) {
|
||||
if (binding.hasExtension("http://hl7.org/fhir/StructureDefinition/elementdefinition-maxValueSet"))
|
||||
checkMaxValueSet(errors, path, element, profile, ToolingExtensions.readStringExtension(binding, "http://hl7.org/fhir/StructureDefinition/elementdefinition-maxValueSet"), cc, stack);
|
||||
else if (!noExtensibleWarnings)
|
||||
txWarningForLaterRemoval(element, errors, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_CONFIRM_2, describeReference(binding.getValueSet()), vr.getErrorClass().toString());
|
||||
txWarningForLaterRemoval(element, errors, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_CONFIRM_2_CC, describeReference(binding.getValueSet()), vr.getErrorClass().toString());
|
||||
} else if (binding.getStrength() == BindingStrength.PREFERRED) {
|
||||
if (baseOnly) {
|
||||
txHint(errors, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_CONFIRM_3, describeReference(binding.getValueSet()), vr.getErrorClass().toString());
|
||||
txHint(errors, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_CONFIRM_3_CC, describeReference(binding.getValueSet()), vr.getErrorClass().toString());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (binding.getStrength() == BindingStrength.REQUIRED)
|
||||
txRule(errors, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_NOVALID_1, describeReference(binding.getValueSet()), valueset.getUrl(), ccSummary(cc));
|
||||
else if (binding.getStrength() == BindingStrength.EXTENSIBLE) {
|
||||
if (binding.getStrength() == BindingStrength.REQUIRED) {
|
||||
txRule(errors, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_NOVALID_1_CC, describeReference(binding.getValueSet()), valueset.getUrl(), ccSummary(cc));
|
||||
} else if (binding.getStrength() == BindingStrength.EXTENSIBLE) {
|
||||
if (binding.hasExtension("http://hl7.org/fhir/StructureDefinition/elementdefinition-maxValueSet"))
|
||||
checkMaxValueSet(errors, path, element, profile, ToolingExtensions.readStringExtension(binding, "http://hl7.org/fhir/StructureDefinition/elementdefinition-maxValueSet"), cc, stack);
|
||||
if (!noExtensibleWarnings)
|
||||
txWarningForLaterRemoval(element, errors, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_NOVALID_2, describeReference(binding.getValueSet()), valueset.getUrl(), ccSummary(cc));
|
||||
txWarningForLaterRemoval(element, errors, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_NOVALID_2_CC, describeReference(binding.getValueSet()), valueset.getUrl(), ccSummary(cc));
|
||||
} else if (binding.getStrength() == BindingStrength.PREFERRED) {
|
||||
if (baseOnly) {
|
||||
txHint(errors, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_NOVALID_3, describeReference(binding.getValueSet()), valueset.getUrl(), ccSummary(cc));
|
||||
txHint(errors, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_NOVALID_3_CC, describeReference(binding.getValueSet()), valueset.getUrl(), ccSummary(cc));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1137,28 +1137,28 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
bindingsOk = false;
|
||||
if (vr.getErrorClass() != null && vr.getErrorClass().isInfrastructure()) {
|
||||
if (binding.getStrength() == BindingStrength.REQUIRED)
|
||||
txWarning(errors, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_CONFIRM_1, describeReference(binding.getValueSet()), vr.getErrorClass().toString());
|
||||
txWarning(errors, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_CONFIRM_1_CC, describeReference(binding.getValueSet()), vr.getErrorClass().toString());
|
||||
else if (binding.getStrength() == BindingStrength.EXTENSIBLE) {
|
||||
if (binding.hasExtension("http://hl7.org/fhir/StructureDefinition/elementdefinition-maxValueSet"))
|
||||
checkMaxValueSet(errors, path, element, profile, ToolingExtensions.readStringExtension(binding, "http://hl7.org/fhir/StructureDefinition/elementdefinition-maxValueSet"), cc, stack);
|
||||
else if (!noExtensibleWarnings)
|
||||
txWarningForLaterRemoval(element, errors, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_CONFIRM_2, describeReference(binding.getValueSet()), vr.getErrorClass().toString());
|
||||
txWarningForLaterRemoval(element, errors, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_CONFIRM_2_CC, describeReference(binding.getValueSet()), vr.getErrorClass().toString());
|
||||
} else if (binding.getStrength() == BindingStrength.PREFERRED) {
|
||||
if (baseOnly) {
|
||||
txHint(errors, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_CONFIRM_3, describeReference(binding.getValueSet()), vr.getErrorClass().toString());
|
||||
txHint(errors, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_CONFIRM_3_CC, describeReference(binding.getValueSet()), vr.getErrorClass().toString());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (binding.getStrength() == BindingStrength.REQUIRED)
|
||||
txRule(errors, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_NOVALID_1, describeReference(binding.getValueSet()), valueset.getUrl(), ccSummary(cc));
|
||||
txRule(errors, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_NOVALID_1_CC, describeReference(binding.getValueSet()), valueset.getUrl(), ccSummary(cc));
|
||||
else if (binding.getStrength() == BindingStrength.EXTENSIBLE) {
|
||||
if (binding.hasExtension("http://hl7.org/fhir/StructureDefinition/elementdefinition-maxValueSet"))
|
||||
checkMaxValueSet(errors, path, element, profile, ToolingExtensions.readStringExtension(binding, "http://hl7.org/fhir/StructureDefinition/elementdefinition-maxValueSet"), cc, stack);
|
||||
if (!noExtensibleWarnings)
|
||||
txWarningForLaterRemoval(element, errors, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_NOVALID_2, describeReference(binding.getValueSet()), valueset.getUrl(), ccSummary(cc));
|
||||
txWarningForLaterRemoval(element, errors, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_NOVALID_2_CC, describeReference(binding.getValueSet()), valueset.getUrl(), ccSummary(cc));
|
||||
} else if (binding.getStrength() == BindingStrength.PREFERRED) {
|
||||
if (baseOnly) {
|
||||
txHint(errors, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_NOVALID_3, describeReference(binding.getValueSet()), valueset.getUrl(), ccSummary(cc));
|
||||
txHint(errors, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_NOVALID_3_CC, describeReference(binding.getValueSet()), valueset.getUrl(), ccSummary(cc));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2220,6 +2220,9 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
* 2. This code doesn't actually decode, which is much easier on memory use for big payloads
|
||||
*/
|
||||
private boolean isValidBase64(String theEncoded) {
|
||||
if (theEncoded == null) {
|
||||
return false;
|
||||
}
|
||||
int charCount = 0;
|
||||
boolean ok = true;
|
||||
for (int i = 0; i < theEncoded.length(); i++) {
|
||||
|
@ -4678,8 +4681,11 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
if (ed.getMin() > 0) {
|
||||
if (problematicPaths.contains(ed.getPath()))
|
||||
hint(errors, IssueType.NOTSUPPORTED, element.line(), element.col(), stack.getLiteralPath(), count >= ed.getMin(), I18nConstants.VALIDATION_VAL_PROFILE_NOCHECKMIN, profile.getUrl(), ed.getPath(), ed.getId(), ed.getSliceName(),ed.getLabel(), stack.getLiteralPath(), Integer.toString(ed.getMin()));
|
||||
else
|
||||
rule(errors, IssueType.STRUCTURE, element.line(), element.col(), stack.getLiteralPath(), count >= ed.getMin(), I18nConstants.VALIDATION_VAL_PROFILE_MINIMUM, profile.getUrl(), ed.getPath(), ed.getId(), ed.getSliceName(),ed.getLabel(), stack.getLiteralPath(), Integer.toString(ed.getMin()), Integer.toString(count));
|
||||
else {
|
||||
if (count < ed.getMin()) {
|
||||
rule(errors, IssueType.STRUCTURE, element.line(), element.col(), stack.getLiteralPath(), false, I18nConstants.VALIDATION_VAL_PROFILE_MINIMUM, profile.getUrl(), ed.getPath(), ed.getId(), ed.getSliceName(),ed.getLabel(), stack.getLiteralPath(), Integer.toString(ed.getMin()), Integer.toString(count));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ed.hasMax() && !ed.getMax().equals("*")) {
|
||||
if (problematicPaths.contains(ed.getPath()))
|
||||
|
|
|
@ -146,6 +146,31 @@ public class StructureDefinitionValidator extends BaseValidator {
|
|||
// String bt = boundType(typeCodes);
|
||||
// hint(errors, IssueType.BUSINESSRULE, stack.getLiteralPath(), !snapshot || bt == null, I18nConstants.SD_ED_SHOULD_BIND, element.getNamedChildValue("path"), bt);
|
||||
}
|
||||
// in a snapshot, we validate that fixedValue, pattern, and defaultValue, if present, are all of the right type
|
||||
if (snapshot && element.getIdBase().contains(".")) {
|
||||
if (rule(errors, IssueType.EXCEPTION, stack.getLiteralPath(), !typeCodes.isEmpty() || element.hasChild("contentReference"), I18nConstants.SD_NO_TYPES_OR_CONTENTREF, element.getIdBase())) {
|
||||
/*
|
||||
TODO Grahame, this is breaking the ig publisher for implementers
|
||||
https://chat.fhir.org/#narrow/stream/215610-shorthand/topic/The.20element.20Extension.2Eurl.20has.20a.20fixed.20of.20type.20uri
|
||||
https://chat.fhir.org/#narrow/stream/179252-IG-creation/topic/BUG.3A.20The.20element.20Extension.2Eurl.20has.20a.20fixed.20of.20type.20uri
|
||||
https://github.com/HL7/fhir-ig-publisher/issues/240
|
||||
This was brought up to Wayne, so I'm commenting it out for now. When you get back we can discuss how to
|
||||
put the changes back in.
|
||||
*/
|
||||
// Element v = element.getNamedChild("defaultValue");
|
||||
// if (v != null) {
|
||||
// rule(errors, IssueType.EXCEPTION, stack.push(v, -1, null, null).getLiteralPath(), typeCodes.contains(v.fhirType()), I18nConstants.SD_VALUE_TYPE_IILEGAL, element.getIdBase(), "defaultValue", v.fhirType(), typeCodes);
|
||||
// }
|
||||
// v = element.getNamedChild("fixed");
|
||||
// if (v != null) {
|
||||
// rule(errors, IssueType.EXCEPTION, stack.push(v, -1, null, null).getLiteralPath(), typeCodes.contains(v.fhirType()), I18nConstants.SD_VALUE_TYPE_IILEGAL, element.getIdBase(), "fixed", v.fhirType(), typeCodes);
|
||||
// }
|
||||
// v = element.getNamedChild("pattern");
|
||||
// if (v != null) {
|
||||
// rule(errors, IssueType.EXCEPTION, stack.push(v, -1, null, null).getLiteralPath(), typeCodes.contains(v.fhirType()), I18nConstants.SD_VALUE_TYPE_IILEGAL, element.getIdBase(), "pattern", v.fhirType(), typeCodes);
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private String boundType(Set<String> typeCodes) {
|
||||
|
@ -166,6 +191,12 @@ public class StructureDefinitionValidator extends BaseValidator {
|
|||
if (Utilities.existsInList(tc, "string", "uri", "CodeableConcept", "Quantity", "CodeableReference")) {
|
||||
return tc;
|
||||
}
|
||||
StructureDefinition sd = context.fetchTypeDefinition(tc);
|
||||
if (sd != null) {
|
||||
if (sd.hasExtension(ToolingExtensions.EXT_BINDING_METHOD)) {
|
||||
return tc;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ import org.hl7.fhir.utilities.VersionUtilities;
|
|||
import org.hl7.fhir.utilities.npm.CachingPackageClient;
|
||||
import org.hl7.fhir.utilities.npm.FilesystemPackageCacheManager;
|
||||
import org.hl7.fhir.utilities.npm.NpmPackage;
|
||||
import org.hl7.fhir.utilities.npm.PackageClient.PackageInfo;
|
||||
import org.hl7.fhir.utilities.npm.PackageInfo;
|
||||
import org.hl7.fhir.utilities.npm.ToolsVersion;
|
||||
|
||||
public class PackageValidator {
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
package org.hl7.fhir.validation.cli.services;
|
||||
|
||||
import org.hl7.fhir.validation.ValidationEngine;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
class SessionCacheTest {
|
||||
|
||||
@Test
|
||||
@DisplayName("test session expiration works")
|
||||
void expiredSession() throws IOException, InterruptedException {
|
||||
final long EXPIRE_TIME = 5L;
|
||||
SessionCache cache = new SessionCache(EXPIRE_TIME, TimeUnit.SECONDS);
|
||||
ValidationEngine testEngine = new ValidationEngine();
|
||||
String sessionId = cache.cacheSession(testEngine);
|
||||
TimeUnit.SECONDS.sleep(EXPIRE_TIME + 1L);
|
||||
Assertions.assertNull(cache.fetchSessionValidatorEngine(sessionId));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("test session caching works")
|
||||
void cachedSession() throws IOException {
|
||||
final long EXPIRE_TIME = 5L;
|
||||
SessionCache cache = new SessionCache(EXPIRE_TIME, TimeUnit.SECONDS);
|
||||
ValidationEngine testEngine = new ValidationEngine();
|
||||
String sessionId = cache.cacheSession(testEngine);
|
||||
Assertions.assertEquals(testEngine, cache.fetchSessionValidatorEngine(sessionId));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("test session exists")
|
||||
void sessionExists() throws IOException {
|
||||
SessionCache cache = new SessionCache();
|
||||
ValidationEngine testEngine = new ValidationEngine();
|
||||
String sessionId = cache.cacheSession(testEngine);
|
||||
Assertions.assertTrue(cache.sessionExists(sessionId));
|
||||
Assertions.assertFalse(cache.sessionExists(UUID.randomUUID().toString()));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("test null session test id returns false")
|
||||
void testNullSessionExists() {
|
||||
SessionCache cache = new SessionCache();
|
||||
Assertions.assertFalse(cache.sessionExists(null));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,67 @@
|
|||
package org.hl7.fhir.validation.cli.services;
|
||||
|
||||
import org.apache.commons.io.Charsets;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.hl7.fhir.r5.elementmodel.Manager;
|
||||
import org.hl7.fhir.validation.ValidationEngine;
|
||||
import org.hl7.fhir.validation.cli.model.CliContext;
|
||||
import org.hl7.fhir.validation.cli.model.FileInfo;
|
||||
import org.hl7.fhir.validation.cli.model.ValidationRequest;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.ArgumentMatchers;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
class ValidationServiceTest {
|
||||
|
||||
@Test
|
||||
void validateSources() throws Exception {
|
||||
SessionCache sessionCache = Mockito.spy(new SessionCache());
|
||||
ValidationService myService = new ValidationService(sessionCache);
|
||||
|
||||
String resource = IOUtils.toString(getFileFromResourceAsStream("detected_issues.json"), StandardCharsets.UTF_8);
|
||||
List<FileInfo> filesToValidate = new ArrayList<>();
|
||||
filesToValidate.add(new FileInfo().setFileName("test_resource.json").setFileContent(resource).setFileType(Manager.FhirFormat.JSON.getExtension()));
|
||||
|
||||
ValidationRequest request = new ValidationRequest().setCliContext(new CliContext()).setFilesToValidate(filesToValidate);
|
||||
// Validation run 1...nothing cached yet
|
||||
myService.validateSources(request);
|
||||
Mockito.verify(sessionCache, Mockito.times(1)).cacheSession(ArgumentMatchers.any(ValidationEngine.class));
|
||||
|
||||
Set<String> sessionIds = sessionCache.getSessionIds();
|
||||
if (sessionIds.stream().findFirst().isPresent()) {
|
||||
// Verify that after 1 run there is only one entry within the cache
|
||||
Assertions.assertEquals(1, sessionIds.size());
|
||||
myService.validateSources(request);
|
||||
// Verify that the cache has been called on once with the id created in the first run
|
||||
Mockito.verify(sessionCache, Mockito.times(1)).fetchSessionValidatorEngine(sessionIds.stream().findFirst().get());
|
||||
} else {
|
||||
// If no sessions exist within the cache after a run, we auto-fail.
|
||||
fail();
|
||||
}
|
||||
}
|
||||
|
||||
private InputStream getFileFromResourceAsStream(String fileName) {
|
||||
// The class loader that loaded the class
|
||||
ClassLoader classLoader = getClass().getClassLoader();
|
||||
InputStream inputStream = classLoader.getResourceAsStream(fileName);
|
||||
|
||||
// the stream holding the file content
|
||||
if (inputStream == null) {
|
||||
throw new IllegalArgumentException("file not found! " + fileName);
|
||||
} else {
|
||||
return inputStream;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"resourceType": "DetectedIssue",
|
||||
"identifier": [ {
|
||||
"system": "http://covidcare.au/app/checkin",
|
||||
"value": "7"
|
||||
} ],
|
||||
"status": "final",
|
||||
"patient": "Patient/4912",
|
||||
"identifiedDateTime": "3020-10-27T13:33:15+11:00",
|
||||
"code": {
|
||||
"coding": [ {
|
||||
"system": "http://covidcare.au/app/alert",
|
||||
"code": "trendNegative",
|
||||
"display": "CovidCare: Vital signs trend negative alert: re-check recommended"
|
||||
} ],
|
||||
"text": "CovidCare alert"
|
||||
}
|
||||
}
|
25
pom.xml
25
pom.xml
|
@ -14,13 +14,14 @@
|
|||
HAPI FHIR
|
||||
-->
|
||||
<artifactId>org.hl7.fhir.core</artifactId>
|
||||
<version>5.2.21-SNAPSHOT</version>
|
||||
<version>5.3.7-SNAPSHOT</version>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<properties>
|
||||
<hapi_fhir_version>5.1.0</hapi_fhir_version>
|
||||
<validator_test_case_version>1.1.57-SNAPSHOT</validator_test_case_version>
|
||||
<junit_jupiter_version>5.6.2</junit_jupiter_version>
|
||||
<validator_test_case_version>1.1.58-SNAPSHOT</validator_test_case_version>
|
||||
<junit_jupiter_version>5.7.1</junit_jupiter_version>
|
||||
<junit_platform_launcher_version>1.7.1</junit_platform_launcher_version>
|
||||
<maven_surefire_version>3.0.0-M4</maven_surefire_version>
|
||||
<jacoco_version>0.8.5</jacoco_version>
|
||||
<info_cqframework_version>1.5.1</info_cqframework_version>
|
||||
|
@ -125,6 +126,24 @@
|
|||
<artifactId>txtmark</artifactId>
|
||||
<version>0.13</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.platform</groupId>
|
||||
<artifactId>junit-platform-launcher</artifactId>
|
||||
<version>${junit_platform_launcher_version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-engine</artifactId>
|
||||
<version>${junit_jupiter_version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.vintage</groupId>
|
||||
<artifactId>${junit_jupiter_version}</artifactId>
|
||||
<version>5.7.1</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
|
|
Loading…
Reference in New Issue