Merge branch 'master' of https://github.com/hapifhir/org.hl7.fhir.core into Branch_685ea98d
This commit is contained in:
commit
4c82c9c738
|
@ -4,4 +4,4 @@
|
||||||
|
|
||||||
## Other code changes
|
## Other code changes
|
||||||
|
|
||||||
* fix various rendering issues from core spec
|
* no changes
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>org.hl7.fhir.core</artifactId>
|
<artifactId>org.hl7.fhir.core</artifactId>
|
||||||
<version>5.6.35</version>
|
<version>5.6.38-SNAPSHOT</version>
|
||||||
<relativePath>../pom.xml</relativePath>
|
<relativePath>../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,189 @@
|
||||||
|
package org.hl7.fhir.convertors.misc;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import org.hl7.fhir.utilities.json.JsonTrackingParser;
|
||||||
|
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
|
|
||||||
|
public class JsonProcessor {
|
||||||
|
public static void main(String[] args) throws Exception {
|
||||||
|
new JsonProcessor().process(args[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void process(String source) throws IOException {
|
||||||
|
JsonObject json = JsonTrackingParser.parseJsonFile(source);
|
||||||
|
process(json);
|
||||||
|
JsonTrackingParser.write(json, new File(source), true);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void process(JsonObject json) {
|
||||||
|
process(json, "ActivityDefinition.status");
|
||||||
|
process(json, "CapabilityStatement.status");
|
||||||
|
process(json, "CodeSystem.status");
|
||||||
|
process(json, "CompartmentDefinition.status");
|
||||||
|
process(json, "ConceptMap.status");
|
||||||
|
process(json, "DataElement.status");
|
||||||
|
process(json, "ExpansionProfile.status");
|
||||||
|
process(json, "GraphDefinition.status");
|
||||||
|
process(json, "ImplementationGuide.status");
|
||||||
|
process(json, "Library.status");
|
||||||
|
process(json, "Measure.status");
|
||||||
|
process(json, "MessageDefinition.status");
|
||||||
|
process(json, "OperationDefinition.status");
|
||||||
|
process(json, "PlanDefinition.status");
|
||||||
|
process(json, "Questionnaire.status");
|
||||||
|
process(json, "SearchParameter.status");
|
||||||
|
process(json, "ServiceDefinition.status");
|
||||||
|
process(json, "StructureDefinition.status");
|
||||||
|
process(json, "StructureMap.status");
|
||||||
|
process(json, "TestScript.status");
|
||||||
|
process(json, "ValueSet.status");
|
||||||
|
process(json, "ActivityDefinition.experimental");
|
||||||
|
process(json, "CapabilityStatement.experimental");
|
||||||
|
process(json, "CodeSystem.experimental");
|
||||||
|
process(json, "CompartmentDefinition.experimental");
|
||||||
|
process(json, "ConceptMap.experimental");
|
||||||
|
process(json, "DataElement.experimental");
|
||||||
|
process(json, "ExpansionProfile.experimental");
|
||||||
|
process(json, "GraphDefinition.experimental");
|
||||||
|
process(json, "ImplementationGuide.experimental");
|
||||||
|
process(json, "Library.experimental");
|
||||||
|
process(json, "Measure.experimental");
|
||||||
|
process(json, "MessageDefinition.experimental");
|
||||||
|
process(json, "OperationDefinition.experimental");
|
||||||
|
process(json, "PlanDefinition.experimental");
|
||||||
|
process(json, "Questionnaire.experimental");
|
||||||
|
process(json, "SearchParameter.experimental");
|
||||||
|
process(json, "ServiceDefinition.experimental");
|
||||||
|
process(json, "StructureDefinition.experimental");
|
||||||
|
process(json, "StructureMap.experimental");
|
||||||
|
process(json, "TestScript.experimental");
|
||||||
|
process(json, "ValueSet.experimental");
|
||||||
|
process(json, "Identifier.use");
|
||||||
|
process(json, "Quantity.comparator");
|
||||||
|
process(json, "Address.use");
|
||||||
|
process(json, "ContactPoint.use");
|
||||||
|
process(json, "HumanName.use");
|
||||||
|
process(json, "BackboneElement.modifierExtension");
|
||||||
|
process(json, "DomainResource.modifierExtension");
|
||||||
|
process(json, "Resource.implicitRules");
|
||||||
|
process(json, "Account.status");
|
||||||
|
process(json, "AllergyIntolerance.clinicalStatus");
|
||||||
|
process(json, "AllergyIntolerance.verificationStatus");
|
||||||
|
process(json, "Appointment.status");
|
||||||
|
process(json, "AppointmentResponse.participantStatus");
|
||||||
|
process(json, "Basic.code");
|
||||||
|
process(json, "BodySite.active");
|
||||||
|
process(json, "CarePlan.status");
|
||||||
|
process(json, "CarePlan.intent");
|
||||||
|
process(json, "CarePlan.activity.detail.status");
|
||||||
|
process(json, "CarePlan.activity.detail.prohibited");
|
||||||
|
process(json, "CareTeam.status");
|
||||||
|
process(json, "ChargeItem.status");
|
||||||
|
process(json, "Claim.status");
|
||||||
|
process(json, "ClaimResponse.status");
|
||||||
|
process(json, "ClinicalImpression.status");
|
||||||
|
process(json, "Communication.status");
|
||||||
|
process(json, "Communication.notDone");
|
||||||
|
process(json, "CommunicationRequest.status");
|
||||||
|
process(json, "Composition.status");
|
||||||
|
process(json, "Composition.confidentiality");
|
||||||
|
process(json, "Composition.section.mode");
|
||||||
|
process(json, "ConceptMap.group.element.target.equivalence");
|
||||||
|
process(json, "Condition.clinicalStatus");
|
||||||
|
process(json, "Condition.verificationStatus");
|
||||||
|
process(json, "Consent.status");
|
||||||
|
process(json, "Contract.status");
|
||||||
|
process(json, "Coverage.status");
|
||||||
|
process(json, "DetectedIssue.status");
|
||||||
|
process(json, "Device.status");
|
||||||
|
process(json, "DeviceRequest.status");
|
||||||
|
process(json, "DeviceRequest.intent");
|
||||||
|
process(json, "DeviceUseStatement.status");
|
||||||
|
process(json, "DiagnosticReport.status");
|
||||||
|
process(json, "DocumentManifest.status");
|
||||||
|
process(json, "DocumentReference.status");
|
||||||
|
process(json, "DocumentReference.relatesTo");
|
||||||
|
process(json, "EligibilityRequest.status");
|
||||||
|
process(json, "EligibilityResponse.status");
|
||||||
|
process(json, "Encounter.status");
|
||||||
|
process(json, "Endpoint.status");
|
||||||
|
process(json, "EnrollmentRequest.status");
|
||||||
|
process(json, "EnrollmentResponse.status");
|
||||||
|
process(json, "EpisodeOfCare.status");
|
||||||
|
process(json, "ExplanationOfBenefit.status");
|
||||||
|
process(json, "FamilyMemberHistory.status");
|
||||||
|
process(json, "FamilyMemberHistory.notDone");
|
||||||
|
process(json, "FamilyMemberHistory.estimatedAge");
|
||||||
|
process(json, "Flag.status");
|
||||||
|
process(json, "Goal.status");
|
||||||
|
process(json, "Group.characteristic.exclude");
|
||||||
|
process(json, "GuidanceResponse.status");
|
||||||
|
process(json, "HealthcareService.active");
|
||||||
|
process(json, "Immunization.status");
|
||||||
|
process(json, "Immunization.notGiven");
|
||||||
|
process(json, "List.status");
|
||||||
|
process(json, "List.mode");
|
||||||
|
process(json, "List.entry.deleted");
|
||||||
|
process(json, "Location.status");
|
||||||
|
process(json, "Location.mode");
|
||||||
|
process(json, "MeasureReport.status");
|
||||||
|
process(json, "MedicationAdministration.status");
|
||||||
|
process(json, "MedicationAdministration.notGiven");
|
||||||
|
process(json, "MedicationDispense.status");
|
||||||
|
process(json, "MedicationRequest.status");
|
||||||
|
process(json, "MedicationRequest.intent");
|
||||||
|
process(json, "MedicationRequest.substitution.allowed");
|
||||||
|
process(json, "MedicationStatement.status");
|
||||||
|
process(json, "MedicationStatement.taken");
|
||||||
|
process(json, "NamingSystem.status");
|
||||||
|
process(json, "NutritionOrder.status");
|
||||||
|
process(json, "Observation.status");
|
||||||
|
process(json, "OperationOutcome.issue.severity");
|
||||||
|
process(json, "Organization.active");
|
||||||
|
process(json, "Patient.active");
|
||||||
|
process(json, "Patient.deceased[x]");
|
||||||
|
process(json, "Patient.animal");
|
||||||
|
process(json, "Patient.link");
|
||||||
|
process(json, "PaymentNotice.status");
|
||||||
|
process(json, "PaymentReconciliation.status");
|
||||||
|
process(json, "Person.active");
|
||||||
|
process(json, "Procedure.status");
|
||||||
|
process(json, "Procedure.notDone");
|
||||||
|
process(json, "ProcedureRequest.status");
|
||||||
|
process(json, "ProcedureRequest.intent");
|
||||||
|
process(json, "ProcedureRequest.doNotPerform");
|
||||||
|
process(json, "ProcessRequest.status");
|
||||||
|
process(json, "ProcessResponse.status");
|
||||||
|
process(json, "Questionnaire.item.enableWhen");
|
||||||
|
process(json, "QuestionnaireResponse.status");
|
||||||
|
process(json, "ReferralRequest.status");
|
||||||
|
process(json, "ReferralRequest.intent");
|
||||||
|
process(json, "RelatedPerson.active");
|
||||||
|
process(json, "RequestGroup.status");
|
||||||
|
process(json, "RequestGroup.intent");
|
||||||
|
process(json, "ResearchStudy.status");
|
||||||
|
process(json, "ResearchSubject.status");
|
||||||
|
process(json, "Schedule.active");
|
||||||
|
process(json, "Specimen.status");
|
||||||
|
process(json, "Subscription.status");
|
||||||
|
process(json, "SupplyDelivery.status");
|
||||||
|
process(json, "SupplyRequest.status");
|
||||||
|
process(json, "TestReport.status");
|
||||||
|
process(json, "ValueSet.compose.include.filter");
|
||||||
|
process(json, "VisionPrescription.status");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void process(JsonObject json, String name) {
|
||||||
|
JsonObject j = json.getAsJsonObject(name);
|
||||||
|
if (j == null) {
|
||||||
|
System.out.println("Can't find "+name);
|
||||||
|
} else {
|
||||||
|
j.addProperty("modifier", true);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -6,13 +6,19 @@ import java.io.FileNotFoundException;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import javax.naming.ldap.StartTlsRequest;
|
import javax.naming.ldap.StartTlsRequest;
|
||||||
import javax.xml.parsers.ParserConfigurationException;
|
import javax.xml.parsers.ParserConfigurationException;
|
||||||
|
|
||||||
|
import org.hl7.fhir.convertors.misc.XVerPackegeFixer.References;
|
||||||
|
import org.hl7.fhir.dstu2.model.ElementDefinition;
|
||||||
|
import org.hl7.fhir.dstu2.model.StructureDefinition;
|
||||||
|
import org.hl7.fhir.dstu2.model.StructureDefinition.StructureDefinitionSnapshotComponent;
|
||||||
import org.hl7.fhir.exceptions.FHIRFormatError;
|
import org.hl7.fhir.exceptions.FHIRFormatError;
|
||||||
import org.hl7.fhir.utilities.Utilities;
|
import org.hl7.fhir.utilities.Utilities;
|
||||||
import org.hl7.fhir.utilities.json.JsonTrackingParser;
|
import org.hl7.fhir.utilities.json.JsonTrackingParser;
|
||||||
|
@ -24,12 +30,35 @@ import com.google.gson.JsonObject;
|
||||||
|
|
||||||
public class XVerPackegeFixer {
|
public class XVerPackegeFixer {
|
||||||
|
|
||||||
private static final String R5_FOLDER = "C:\\work\\org.hl7.fhir\\packages\\hl7.fhir.rX\\hl7.fhir.r5.core\\package";
|
public static class References {
|
||||||
private static final String R4_FOLDER = "C:\\work\\org.hl7.fhir\\packages\\hl7.fhir.rX\\hl7.fhir.r4.core\\package";
|
private boolean modifier;
|
||||||
private static final String R3_FOLDER = "C:\\work\\org.hl7.fhir\\packages\\hl7.fhir.rX\\hl7.fhir.r3.core\\package";
|
private boolean inherited;
|
||||||
private static final String R2B_FOLDER = "C:\\work\\org.hl7.fhir\\packages\\hl7.fhir.rX\\hl7.fhir.r2b.core\\package";
|
|
||||||
private static final String R2_FOLDER = "C:\\work\\org.hl7.fhir\\packages\\hl7.fhir.rX\\hl7.fhir.r2.core\\package";
|
public boolean getModifier() {
|
||||||
private static int mod;
|
return modifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setModifier(boolean value) {
|
||||||
|
this.modifier = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean getInherited() {
|
||||||
|
return inherited;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setInherited(boolean inherited) {
|
||||||
|
this.inherited = inherited;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static final String R5_FOLDER = "/Users/grahamegrieve/work/packages/hl7.fhir.rX/hl7.fhir.r5.core/package";
|
||||||
|
private static final String R4_FOLDER = "/Users/grahamegrieve/work/packages/hl7.fhir.rX/hl7.fhir.r4.core/package";
|
||||||
|
private static final String R3_FOLDER = "/Users/grahamegrieve/work/packages/hl7.fhir.rX/hl7.fhir.r3.core/package";
|
||||||
|
private static final String R2B_FOLDER = "/Users/grahamegrieve/work/packages/hl7.fhir.rX/hl7.fhir.r2b.core/package";
|
||||||
|
private static final String R2_FOLDER = "/Users/grahamegrieve/work/packages/hl7.fhir.rX/hl7.fhir.r2.core/package";
|
||||||
|
private static int modCount;
|
||||||
|
|
||||||
private static Map<String, org.hl7.fhir.r5.model.StructureDefinition> map5 = new HashMap<>();
|
private static Map<String, org.hl7.fhir.r5.model.StructureDefinition> map5 = new HashMap<>();
|
||||||
private static Map<String, org.hl7.fhir.r4.model.StructureDefinition> map4 = new HashMap<>();
|
private static Map<String, org.hl7.fhir.r4.model.StructureDefinition> map4 = new HashMap<>();
|
||||||
|
@ -38,21 +67,23 @@ public class XVerPackegeFixer {
|
||||||
private static Map<String, org.hl7.fhir.dstu2016may.model.StructureDefinition> map2b = new HashMap<>();
|
private static Map<String, org.hl7.fhir.dstu2016may.model.StructureDefinition> map2b = new HashMap<>();
|
||||||
|
|
||||||
public static void main(String[] args) throws FileNotFoundException, ParserConfigurationException, SAXException, IOException {
|
public static void main(String[] args) throws FileNotFoundException, ParserConfigurationException, SAXException, IOException {
|
||||||
mod = 0;
|
modCount = 0;
|
||||||
for (File f : new File(args[0]).listFiles()) {
|
for (File f : new File(args[0]).listFiles()) {
|
||||||
if (f.getName().startsWith("xver-")) {
|
if (f.getName().startsWith("xver-") && f.getName().contains("1.0")) {
|
||||||
JsonObject j = JsonTrackingParser.parseJson(f);
|
JsonObject j = JsonTrackingParser.parseJson(f);
|
||||||
fixUp(j, f.getName());
|
fixUp(j, f.getName());
|
||||||
JsonTrackingParser.write(j, f, true);
|
JsonTrackingParser.write(j, f, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
System.out.println("all done: "+mod+" modifiers");
|
System.out.println("all done: "+modCount+" modifiers");
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void fixUp(JsonObject j, String name) throws FHIRFormatError, FileNotFoundException, IOException {
|
private static void fixUp(JsonObject j, String name) throws FHIRFormatError, FileNotFoundException, IOException {
|
||||||
name = name.replace(".json", "");
|
name = name.replace(".json", "");
|
||||||
System.out.println("Process "+name);
|
System.out.println("Process "+name);
|
||||||
String version = name.substring(name.lastIndexOf("-")+1);
|
String version = name.substring(name.lastIndexOf("-")+1);
|
||||||
|
Set<String> pr = new HashSet<>();
|
||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (Entry<String, JsonElement> e : j.entrySet()) {
|
for (Entry<String, JsonElement> e : j.entrySet()) {
|
||||||
if (i == 50) {
|
if (i == 50) {
|
||||||
|
@ -62,18 +93,31 @@ public class XVerPackegeFixer {
|
||||||
i++;
|
i++;
|
||||||
String n = e.getKey();
|
String n = e.getKey();
|
||||||
JsonObject o = ((JsonObject) e.getValue());
|
JsonObject o = ((JsonObject) e.getValue());
|
||||||
boolean ok = (o.has("types") && o.getAsJsonArray("types").size() > 0) || (o.has("elements") && o.getAsJsonArray("elements").size() > 0);
|
// boolean ok = (o.has("types") && o.getAsJsonArray("types").size() > 0) || (o.has("elements") && o.getAsJsonArray("elements").size() > 0);
|
||||||
if (!ok) {
|
// if (!ok) {
|
||||||
|
if (o.has("types")) {
|
||||||
|
o.remove("types");
|
||||||
|
}
|
||||||
|
if (o.has("elements")) {
|
||||||
|
o.remove("elements");
|
||||||
|
}
|
||||||
|
if (o.has("modifier")) {
|
||||||
|
o.remove("modifier");
|
||||||
|
}
|
||||||
List<String> types = new ArrayList<>();
|
List<String> types = new ArrayList<>();
|
||||||
List<String> elements = new ArrayList<>();
|
List<String> elements = new ArrayList<>();
|
||||||
getElementInfo(version, n, types, elements);
|
References mod = new References();
|
||||||
|
getElementInfo(version, n, types, elements, mod);
|
||||||
|
if (mod.getInherited()) {
|
||||||
|
pr.add(n);
|
||||||
|
}
|
||||||
if (elements.size() > 0) {
|
if (elements.size() > 0) {
|
||||||
JsonArray arr = o.getAsJsonArray("elements");
|
JsonArray arr = o.getAsJsonArray("elements");
|
||||||
if (arr == null) {
|
if (arr == null) {
|
||||||
arr = new JsonArray();
|
arr = new JsonArray();
|
||||||
o.add("elements", arr);
|
o.add("elements", arr);
|
||||||
}
|
}
|
||||||
for (String s : types) {
|
for (String s : elements) {
|
||||||
arr.add(s);
|
arr.add(s);
|
||||||
}
|
}
|
||||||
} else if (types.size() > 0) {
|
} else if (types.size() > 0) {
|
||||||
|
@ -86,30 +130,37 @@ public class XVerPackegeFixer {
|
||||||
arr.add(s);
|
arr.add(s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
if (mod.getModifier()) {
|
||||||
|
o.addProperty("modifier", true);
|
||||||
|
modCount++;
|
||||||
|
}
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
for (String s : pr) {
|
||||||
|
j.remove(s);
|
||||||
}
|
}
|
||||||
System.out.println("done");
|
System.out.println("done");
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean getElementInfo(String version, String n, List<String> types, List<String> elements) throws FHIRFormatError, FileNotFoundException, IOException {
|
private static boolean getElementInfo(String version, String n, List<String> types, List<String> elements, References mod) throws FHIRFormatError, FileNotFoundException, IOException {
|
||||||
if ("contained".equals(n.substring(n.indexOf(".")+1))) {
|
// if ("contained".equals(n.substring(n.indexOf(".")+1))) {
|
||||||
return false;
|
// return false;
|
||||||
}
|
// }
|
||||||
switch (version) {
|
switch (version) {
|
||||||
case "4.6": return getElementInfoR5(n, types, elements);
|
case "4.6": return getElementInfoR5(n, types, elements, mod);
|
||||||
case "4.0": return getElementInfoR4(n, types, elements);
|
case "4.0": return getElementInfoR4(n, types, elements, mod);
|
||||||
case "3.0": return getElementInfoR3(n, types, elements);
|
case "3.0": return getElementInfoR3(n, types, elements, mod);
|
||||||
case "1.4": return getElementInfoR2B(n, types, elements);
|
case "1.4": return getElementInfoR2B(n, types, elements, mod);
|
||||||
case "1.0": return getElementInfoR2(n, types, elements);
|
case "1.0": return getElementInfoR2(n, types, elements, mod);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Object tail(String value) {
|
private static String tail(String value) {
|
||||||
return value.contains("/") ? value.substring(value.lastIndexOf("/")+1) : value;
|
return value.contains("/") ? value.substring(value.lastIndexOf("/")+1) : value;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean getElementInfoR5(String n, List<String> types, List<String> elements) throws FHIRFormatError, FileNotFoundException, IOException {
|
private static boolean getElementInfoR5(String n, List<String> types, List<String> elements, References mod) throws FHIRFormatError, FileNotFoundException, IOException {
|
||||||
String tn = n.substring(0, n.indexOf("."));
|
String tn = n.substring(0, n.indexOf("."));
|
||||||
org.hl7.fhir.r5.model.StructureDefinition sd = null;
|
org.hl7.fhir.r5.model.StructureDefinition sd = null;
|
||||||
if (map5.containsKey(tn)) {
|
if (map5.containsKey(tn)) {
|
||||||
|
@ -120,7 +171,8 @@ public class XVerPackegeFixer {
|
||||||
}
|
}
|
||||||
for (org.hl7.fhir.r5.model.ElementDefinition ed : sd.getSnapshot().getElement()) {
|
for (org.hl7.fhir.r5.model.ElementDefinition ed : sd.getSnapshot().getElement()) {
|
||||||
if (ed.getPath().equals(n)) {
|
if (ed.getPath().equals(n)) {
|
||||||
List<org.hl7.fhir.r5.model.ElementDefinition> children = listChildrenR5(sd.getSnapshot().getElement(), ed);
|
mod.setModifier(ed.getIsModifier());
|
||||||
|
List<org.hl7.fhir.r5.model.ElementDefinition> children = listChildrenR5(sd.getSnapshot().getElement(), ed);
|
||||||
if (children.size() > 0) {
|
if (children.size() > 0) {
|
||||||
for (org.hl7.fhir.r5.model.ElementDefinition c : children) {
|
for (org.hl7.fhir.r5.model.ElementDefinition c : children) {
|
||||||
String en = c.getPath().substring(ed.getPath().length()+1);
|
String en = c.getPath().substring(ed.getPath().length()+1);
|
||||||
|
@ -164,7 +216,7 @@ public class XVerPackegeFixer {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean getElementInfoR4(String n, List<String> types, List<String> elements) throws FHIRFormatError, FileNotFoundException, IOException {
|
private static boolean getElementInfoR4(String n, List<String> types, List<String> elements, References mod) throws FHIRFormatError, FileNotFoundException, IOException {
|
||||||
String tn = n.substring(0, n.indexOf("."));
|
String tn = n.substring(0, n.indexOf("."));
|
||||||
org.hl7.fhir.r4.model.StructureDefinition sd = null;
|
org.hl7.fhir.r4.model.StructureDefinition sd = null;
|
||||||
if (map4.containsKey(tn)) {
|
if (map4.containsKey(tn)) {
|
||||||
|
@ -175,6 +227,7 @@ public class XVerPackegeFixer {
|
||||||
}
|
}
|
||||||
for (org.hl7.fhir.r4.model.ElementDefinition ed : sd.getSnapshot().getElement()) {
|
for (org.hl7.fhir.r4.model.ElementDefinition ed : sd.getSnapshot().getElement()) {
|
||||||
if (ed.getPath().equals(n)) {
|
if (ed.getPath().equals(n)) {
|
||||||
|
mod.setModifier(ed.getIsModifier());
|
||||||
List<org.hl7.fhir.r4.model.ElementDefinition> children = listChildrenR4(sd.getSnapshot().getElement(), ed);
|
List<org.hl7.fhir.r4.model.ElementDefinition> children = listChildrenR4(sd.getSnapshot().getElement(), ed);
|
||||||
if (children.size() > 0) {
|
if (children.size() > 0) {
|
||||||
for (org.hl7.fhir.r4.model.ElementDefinition c : children) {
|
for (org.hl7.fhir.r4.model.ElementDefinition c : children) {
|
||||||
|
@ -220,7 +273,7 @@ public class XVerPackegeFixer {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static boolean getElementInfoR3(String n, List<String> types, List<String> elements) throws FHIRFormatError, FileNotFoundException, IOException {
|
private static boolean getElementInfoR3(String n, List<String> types, List<String> elements, References mod) throws FHIRFormatError, FileNotFoundException, IOException {
|
||||||
String tn = n.substring(0, n.indexOf("."));
|
String tn = n.substring(0, n.indexOf("."));
|
||||||
org.hl7.fhir.dstu3.model.StructureDefinition sd = null;
|
org.hl7.fhir.dstu3.model.StructureDefinition sd = null;
|
||||||
if (map3.containsKey(tn)) {
|
if (map3.containsKey(tn)) {
|
||||||
|
@ -231,6 +284,7 @@ public class XVerPackegeFixer {
|
||||||
}
|
}
|
||||||
for (org.hl7.fhir.dstu3.model.ElementDefinition ed : sd.getSnapshot().getElement()) {
|
for (org.hl7.fhir.dstu3.model.ElementDefinition ed : sd.getSnapshot().getElement()) {
|
||||||
if (ed.getPath().equals(n)) {
|
if (ed.getPath().equals(n)) {
|
||||||
|
mod.setModifier(ed.getIsModifier());
|
||||||
List<org.hl7.fhir.dstu3.model.ElementDefinition> children = listChildrenR3(sd.getSnapshot().getElement(), ed);
|
List<org.hl7.fhir.dstu3.model.ElementDefinition> children = listChildrenR3(sd.getSnapshot().getElement(), ed);
|
||||||
if (children.size() > 0) {
|
if (children.size() > 0) {
|
||||||
for (org.hl7.fhir.dstu3.model.ElementDefinition c : children) {
|
for (org.hl7.fhir.dstu3.model.ElementDefinition c : children) {
|
||||||
|
@ -272,17 +326,14 @@ public class XVerPackegeFixer {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static boolean getElementInfoR2(String n, List<String> types, List<String> elements) throws FHIRFormatError, FileNotFoundException, IOException {
|
private static boolean getElementInfoR2(String n, List<String> types, List<String> elements, References mod) throws FHIRFormatError, FileNotFoundException, IOException {
|
||||||
String tn = n.substring(0, n.indexOf("."));
|
String tn = n.substring(0, n.indexOf("."));
|
||||||
org.hl7.fhir.dstu2.model.StructureDefinition sd = null;
|
org.hl7.fhir.dstu2.model.StructureDefinition sd = null;
|
||||||
if (map2.containsKey(tn)) {
|
sd = loadType(tn);
|
||||||
sd = map2.get(tn);
|
mod.setInherited(isInherited(n, sd));
|
||||||
} else {
|
|
||||||
sd = (org.hl7.fhir.dstu2.model.StructureDefinition) new org.hl7.fhir.dstu2.formats.JsonParser().parse(new FileInputStream(Utilities.path(R2_FOLDER, "StructureDefinition-"+tn+".json")));
|
|
||||||
map2.put(tn, sd);
|
|
||||||
}
|
|
||||||
for (org.hl7.fhir.dstu2.model.ElementDefinition ed : sd.getSnapshot().getElement()) {
|
for (org.hl7.fhir.dstu2.model.ElementDefinition ed : sd.getSnapshot().getElement()) {
|
||||||
if (ed.getPath().equals(n)) {
|
if (ed.getPath().equals(n)) {
|
||||||
|
mod.setModifier(ed.getIsModifier());
|
||||||
List<org.hl7.fhir.dstu2.model.ElementDefinition> children = listChildrenR2(sd.getSnapshot().getElement(), ed);
|
List<org.hl7.fhir.dstu2.model.ElementDefinition> children = listChildrenR2(sd.getSnapshot().getElement(), ed);
|
||||||
if (children.size() > 0) {
|
if (children.size() > 0) {
|
||||||
for (org.hl7.fhir.dstu2.model.ElementDefinition c : children) {
|
for (org.hl7.fhir.dstu2.model.ElementDefinition c : children) {
|
||||||
|
@ -290,28 +341,76 @@ public class XVerPackegeFixer {
|
||||||
elements.add(en);
|
elements.add(en);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
boolean isReference = false;
|
||||||
|
StringBuilder r = new StringBuilder();
|
||||||
|
r.append("Reference(");
|
||||||
for (org.hl7.fhir.dstu2.model.ElementDefinition.TypeRefComponent t : ed.getType()) {
|
for (org.hl7.fhir.dstu2.model.ElementDefinition.TypeRefComponent t : ed.getType()) {
|
||||||
if (t.hasProfile()) {
|
if (t.hasProfile()) {
|
||||||
StringBuilder b = new StringBuilder();
|
if ("Reference".equals(t.getCode())) {
|
||||||
b.append(t.getCode());
|
for (org.hl7.fhir.dstu2.model.UriType u : t.getProfile()) {
|
||||||
b.append("(");
|
if (isReference)
|
||||||
boolean first = true;
|
r.append("|");
|
||||||
for (org.hl7.fhir.dstu2.model.UriType u : t.getProfile()) {
|
r.append(tail(u.getValue()));
|
||||||
if (first) first = false; else b.append("|");
|
isReference = true;
|
||||||
b.append(tail(u.getValue()));
|
}
|
||||||
|
} else {
|
||||||
|
StringBuilder b = new StringBuilder();
|
||||||
|
b.append(t.getCode());
|
||||||
|
b.append("(");
|
||||||
|
boolean first = true;
|
||||||
|
for (org.hl7.fhir.dstu2.model.UriType u : t.getProfile()) {
|
||||||
|
if (first) first = false; else b.append("|");
|
||||||
|
b.append(tail(u.getValue()));
|
||||||
|
}
|
||||||
|
b.append(")");
|
||||||
|
types.add(b.toString());
|
||||||
}
|
}
|
||||||
b.append(")");
|
|
||||||
types.add(b.toString());
|
|
||||||
} else {
|
} else {
|
||||||
types.add(t.getCode());
|
types.add(t.getCode());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (isReference) {
|
||||||
|
r.append(")");
|
||||||
|
types.add(r.toString());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static org.hl7.fhir.dstu2.model.StructureDefinition loadType(String tn)
|
||||||
|
throws IOException, FileNotFoundException {
|
||||||
|
org.hl7.fhir.dstu2.model.StructureDefinition sd;
|
||||||
|
if (map2.containsKey(tn)) {
|
||||||
|
sd = map2.get(tn);
|
||||||
|
} else {
|
||||||
|
sd = (org.hl7.fhir.dstu2.model.StructureDefinition) new org.hl7.fhir.dstu2.formats.JsonParser().parse(new FileInputStream(Utilities.path(R2_FOLDER, "StructureDefinition-"+tn+".json")));
|
||||||
|
map2.put(tn, sd);
|
||||||
|
}
|
||||||
|
return sd;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static boolean isInherited(String n, StructureDefinition sd) throws FileNotFoundException, IOException {
|
||||||
|
String tail = n.substring(n.indexOf(".")+1);
|
||||||
|
while (sd != null) {
|
||||||
|
sd = sd.hasBase() ? loadType(tail(sd.getBase())) : null;
|
||||||
|
if (sd != null && hasPath(sd.getSnapshot(), sd.getName()+"."+tail)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean hasPath(StructureDefinitionSnapshotComponent snapshot, String path) {
|
||||||
|
for (ElementDefinition ed : snapshot.getElement()) {
|
||||||
|
if (ed.getPath().equals(path)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
private static List<org.hl7.fhir.dstu2.model.ElementDefinition> listChildrenR2(List<org.hl7.fhir.dstu2.model.ElementDefinition> list, org.hl7.fhir.dstu2.model.ElementDefinition ed) {
|
private static List<org.hl7.fhir.dstu2.model.ElementDefinition> listChildrenR2(List<org.hl7.fhir.dstu2.model.ElementDefinition> list, org.hl7.fhir.dstu2.model.ElementDefinition ed) {
|
||||||
List<org.hl7.fhir.dstu2.model.ElementDefinition> res = new ArrayList<>();
|
List<org.hl7.fhir.dstu2.model.ElementDefinition> res = new ArrayList<>();
|
||||||
|
@ -328,7 +427,7 @@ public class XVerPackegeFixer {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static boolean getElementInfoR2B(String n, List<String> types, List<String> elements) throws FHIRFormatError, FileNotFoundException, IOException {
|
private static boolean getElementInfoR2B(String n, List<String> types, List<String> elements, References mod) throws FHIRFormatError, FileNotFoundException, IOException {
|
||||||
String tn = n.substring(0, n.indexOf("."));
|
String tn = n.substring(0, n.indexOf("."));
|
||||||
org.hl7.fhir.dstu2016may.model.StructureDefinition sd = null;
|
org.hl7.fhir.dstu2016may.model.StructureDefinition sd = null;
|
||||||
if (map2b.containsKey(tn)) {
|
if (map2b.containsKey(tn)) {
|
||||||
|
@ -339,6 +438,7 @@ public class XVerPackegeFixer {
|
||||||
}
|
}
|
||||||
for (org.hl7.fhir.dstu2016may.model.ElementDefinition ed : sd.getSnapshot().getElement()) {
|
for (org.hl7.fhir.dstu2016may.model.ElementDefinition ed : sd.getSnapshot().getElement()) {
|
||||||
if (ed.getPath().equals(n)) {
|
if (ed.getPath().equals(n)) {
|
||||||
|
mod.setModifier(ed.getIsModifier());
|
||||||
List<org.hl7.fhir.dstu2016may.model.ElementDefinition> children = listChildrenR2B(sd.getSnapshot().getElement(), ed);
|
List<org.hl7.fhir.dstu2016may.model.ElementDefinition> children = listChildrenR2B(sd.getSnapshot().getElement(), ed);
|
||||||
if (children.size() > 0) {
|
if (children.size() > 0) {
|
||||||
for (org.hl7.fhir.dstu2016may.model.ElementDefinition c : children) {
|
for (org.hl7.fhir.dstu2016may.model.ElementDefinition c : children) {
|
||||||
|
|
|
@ -72,7 +72,7 @@ public class TerminologyClientR3 implements TerminologyClient {
|
||||||
@Override
|
@Override
|
||||||
public ValueSet expandValueset(ValueSet vs, Parameters p, Map<String, String> params) throws FHIRException {
|
public ValueSet expandValueset(ValueSet vs, Parameters p, Map<String, String> params) throws FHIRException {
|
||||||
org.hl7.fhir.dstu3.model.ValueSet vs2 = (org.hl7.fhir.dstu3.model.ValueSet) VersionConvertorFactory_30_50.convertResource(vs);
|
org.hl7.fhir.dstu3.model.ValueSet vs2 = (org.hl7.fhir.dstu3.model.ValueSet) VersionConvertorFactory_30_50.convertResource(vs);
|
||||||
org.hl7.fhir.dstu3.model.ExpansionProfile p2 = (org.hl7.fhir.dstu3.model.ExpansionProfile) VersionConvertorFactory_30_50.convertResource(p);
|
org.hl7.fhir.dstu3.model.Parameters p2 = (org.hl7.fhir.dstu3.model.Parameters) VersionConvertorFactory_30_50.convertResource(p);
|
||||||
vs2 = client.expandValueset(vs2, p2, params); // todo: second parameter
|
vs2 = client.expandValueset(vs2, p2, params); // todo: second parameter
|
||||||
return (ValueSet) VersionConvertorFactory_30_50.convertResource(vs2);
|
return (ValueSet) VersionConvertorFactory_30_50.convertResource(vs2);
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>org.hl7.fhir.core</artifactId>
|
<artifactId>org.hl7.fhir.core</artifactId>
|
||||||
<version>5.6.35</version>
|
<version>5.6.38-SNAPSHOT</version>
|
||||||
<relativePath>../pom.xml</relativePath>
|
<relativePath>../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>org.hl7.fhir.core</artifactId>
|
<artifactId>org.hl7.fhir.core</artifactId>
|
||||||
<version>5.6.35</version>
|
<version>5.6.38-SNAPSHOT</version>
|
||||||
<relativePath>../pom.xml</relativePath>
|
<relativePath>../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>org.hl7.fhir.core</artifactId>
|
<artifactId>org.hl7.fhir.core</artifactId>
|
||||||
<version>5.6.35</version>
|
<version>5.6.38-SNAPSHOT</version>
|
||||||
<relativePath>../pom.xml</relativePath>
|
<relativePath>../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -2219,7 +2219,7 @@ public class FHIRPathEngine {
|
||||||
|
|
||||||
if (!Utilities.noString(f)) {
|
if (!Utilities.noString(f)) {
|
||||||
|
|
||||||
if (exp.getParameters().size() != 2) {
|
if (exp.getParameters().size() == 2) {
|
||||||
|
|
||||||
String t = convertToString(execute(context, focus, exp.getParameters().get(0), true));
|
String t = convertToString(execute(context, focus, exp.getParameters().get(0), true));
|
||||||
String r = convertToString(execute(context, focus, exp.getParameters().get(1), true));
|
String r = convertToString(execute(context, focus, exp.getParameters().get(1), true));
|
||||||
|
|
|
@ -0,0 +1,61 @@
|
||||||
|
package org.hl7.fhir.dstu3.utils;
|
||||||
|
|
||||||
|
import org.hl7.fhir.dstu3.context.IWorkerContext;
|
||||||
|
import org.hl7.fhir.dstu3.model.Base;
|
||||||
|
import org.hl7.fhir.dstu3.model.ExpressionNode;
|
||||||
|
import org.hl7.fhir.dstu3.model.StringType;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.Mockito;
|
||||||
|
import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
|
import static org.mockito.Mockito.times;
|
||||||
|
|
||||||
|
@ExtendWith(MockitoExtension.class)
|
||||||
|
public class FhirPathTests {
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
IWorkerContext iWorkerContext;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
Object appContext;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
Base resource;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
Base base;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFuncReplaceParamSize() {
|
||||||
|
FHIRPathEngine engine = Mockito.spy(new FHIRPathEngine(iWorkerContext));
|
||||||
|
|
||||||
|
ExpressionNode expressionNode = new ExpressionNode(0);
|
||||||
|
expressionNode.setKind(ExpressionNode.Kind.Function);
|
||||||
|
expressionNode.setFunction(ExpressionNode.Function.Replace);
|
||||||
|
|
||||||
|
ExpressionNode expressionNodeB = new ExpressionNode(1);
|
||||||
|
expressionNodeB.setKind(ExpressionNode.Kind.Function);
|
||||||
|
expressionNodeB.setFunction(ExpressionNode.Function.Empty);
|
||||||
|
|
||||||
|
ExpressionNode expressionNodeC = new ExpressionNode(2);
|
||||||
|
expressionNodeC.setKind(ExpressionNode.Kind.Function);
|
||||||
|
expressionNodeC.setFunction(ExpressionNode.Function.Empty);
|
||||||
|
|
||||||
|
expressionNode.getParameters().add(expressionNodeB);
|
||||||
|
expressionNode.getParameters().add(expressionNodeC);
|
||||||
|
List<Base> result = engine.evaluate(appContext, resource, base, expressionNode);
|
||||||
|
|
||||||
|
assertEquals(1, result.size());
|
||||||
|
Base onlyResult = result.get(0);
|
||||||
|
assertTrue(onlyResult instanceof StringType);
|
||||||
|
assertEquals("base", ((StringType)result.get(0)).asStringValue());
|
||||||
|
Mockito.verify(engine, times(2)).convertToString(any());
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>org.hl7.fhir.core</artifactId>
|
<artifactId>org.hl7.fhir.core</artifactId>
|
||||||
<version>5.6.35</version>
|
<version>5.6.38-SNAPSHOT</version>
|
||||||
<relativePath>../pom.xml</relativePath>
|
<relativePath>../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -49,7 +49,7 @@ public enum FhirPublication {
|
||||||
R4;
|
R4;
|
||||||
|
|
||||||
public static FhirPublication fromCode(String v) {
|
public static FhirPublication fromCode(String v) {
|
||||||
if (VersionUtilities.isR4Ver(v))
|
if (VersionUtilities.isR2Ver(v))
|
||||||
return FhirPublication.DSTU2;
|
return FhirPublication.DSTU2;
|
||||||
if ("1.0".equals(v))
|
if ("1.0".equals(v))
|
||||||
return FhirPublication.DSTU2;
|
return FhirPublication.DSTU2;
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>org.hl7.fhir.core</artifactId>
|
<artifactId>org.hl7.fhir.core</artifactId>
|
||||||
<version>5.6.35</version>
|
<version>5.6.38-SNAPSHOT</version>
|
||||||
<relativePath>../pom.xml</relativePath>
|
<relativePath>../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -45,14 +45,14 @@ public class ProfileComparer extends CanonicalResourceComparer {
|
||||||
|
|
||||||
public class ProfileComparison extends CanonicalResourceComparison<StructureDefinition> {
|
public class ProfileComparison extends CanonicalResourceComparison<StructureDefinition> {
|
||||||
|
|
||||||
private StructuralMatch<ElementDefinition> combined;
|
private StructuralMatch<ElementDefinitionNode> combined;
|
||||||
|
|
||||||
public ProfileComparison(StructureDefinition left, StructureDefinition right) {
|
public ProfileComparison(StructureDefinition left, StructureDefinition right) {
|
||||||
super(left, right);
|
super(left, right);
|
||||||
combined = new StructuralMatch<ElementDefinition>(); // base
|
combined = new StructuralMatch<ElementDefinitionNode>(); // base
|
||||||
}
|
}
|
||||||
|
|
||||||
public StructuralMatch<ElementDefinition> getCombined() {
|
public StructuralMatch<ElementDefinitionNode> getCombined() {
|
||||||
return combined;
|
return combined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,7 +79,21 @@ public class ProfileComparer extends CanonicalResourceComparer {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private class ElementDefinitionNode {
|
||||||
|
private ElementDefinition def;
|
||||||
|
private StructureDefinition src;
|
||||||
|
private ElementDefinitionNode(StructureDefinition src, ElementDefinition def) {
|
||||||
|
super();
|
||||||
|
this.src = src;
|
||||||
|
this.def = def;
|
||||||
|
}
|
||||||
|
public ElementDefinition getDef() {
|
||||||
|
return def;
|
||||||
|
}
|
||||||
|
public StructureDefinition getSrc() {
|
||||||
|
return src;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private ProfileUtilities utilsLeft;
|
private ProfileUtilities utilsLeft;
|
||||||
private ProfileUtilities utilsRight;
|
private ProfileUtilities utilsRight;
|
||||||
|
@ -127,7 +141,7 @@ public class ProfileComparer extends CanonicalResourceComparer {
|
||||||
if (left.getType().equals(right.getType())) {
|
if (left.getType().equals(right.getType())) {
|
||||||
DefinitionNavigator ln = new DefinitionNavigator(session.getContextLeft(), left);
|
DefinitionNavigator ln = new DefinitionNavigator(session.getContextLeft(), left);
|
||||||
DefinitionNavigator rn = new DefinitionNavigator(session.getContextRight(), right);
|
DefinitionNavigator rn = new DefinitionNavigator(session.getContextRight(), right);
|
||||||
StructuralMatch<ElementDefinition> sm = new StructuralMatch<ElementDefinition>(ln.current(), rn.current());
|
StructuralMatch<ElementDefinitionNode> sm = new StructuralMatch<ElementDefinitionNode>(new ElementDefinitionNode(left, ln.current()), new ElementDefinitionNode(right, rn.current()));
|
||||||
compareElements(res, sm, ln.path(), null, ln, rn);
|
compareElements(res, sm, ln.path(), null, ln, rn);
|
||||||
res.combined = sm;
|
res.combined = sm;
|
||||||
}
|
}
|
||||||
|
@ -147,7 +161,7 @@ public class ProfileComparer extends CanonicalResourceComparer {
|
||||||
throw new DefinitionException("StructureDefinition snapshot is empty ("+name+": "+sd.getName()+")");
|
throw new DefinitionException("StructureDefinition snapshot is empty ("+name+": "+sd.getName()+")");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void compareElements(ProfileComparison comp, StructuralMatch<ElementDefinition> res, String path, String sliceName, DefinitionNavigator left, DefinitionNavigator right) throws DefinitionException, FHIRFormatError, IOException {
|
private void compareElements(ProfileComparison comp, StructuralMatch<ElementDefinitionNode> res, String path, String sliceName, DefinitionNavigator left, DefinitionNavigator right) throws DefinitionException, FHIRFormatError, IOException {
|
||||||
assert(path != null);
|
assert(path != null);
|
||||||
assert(left != null);
|
assert(left != null);
|
||||||
assert(right != null);
|
assert(right != null);
|
||||||
|
@ -190,7 +204,7 @@ public class ProfileComparer extends CanonicalResourceComparer {
|
||||||
subset.setExample(left.current().hasExample() ? left.current().getExample() : right.current().getExample());
|
subset.setExample(left.current().hasExample() ? left.current().getExample() : right.current().getExample());
|
||||||
|
|
||||||
if (left.current().getMustSupport() != right.current().getMustSupport()) {
|
if (left.current().getMustSupport() != right.current().getMustSupport()) {
|
||||||
vm(IssueSeverity.ERROR, "Elements differ in definition for mustSupport:\r\n \""+left.current().getMustSupport()+"\"\r\n \""+right.current().getMustSupport()+"\"", path, comp.getMessages(), res.getMessages());
|
vm(IssueSeverity.WARNING, "Elements differ in definition for mustSupport: '"+left.current().getMustSupport()+"' vs '"+right.current().getMustSupport()+"'", path, comp.getMessages(), res.getMessages());
|
||||||
|
|
||||||
}
|
}
|
||||||
subset.setMustSupport(left.current().getMustSupport() || right.current().getMustSupport());
|
subset.setMustSupport(left.current().getMustSupport() || right.current().getMustSupport());
|
||||||
|
@ -198,15 +212,20 @@ public class ProfileComparer extends CanonicalResourceComparer {
|
||||||
|
|
||||||
|
|
||||||
// compare and intersect
|
// compare and intersect
|
||||||
superset.setMin(unionMin(left.current().getMin(), right.current().getMin()));
|
int leftMin = left.current().getMin();
|
||||||
superset.setMax(unionMax(left.current().getMax(), right.current().getMax()));
|
int rightMin = right.current().getMin();
|
||||||
subset.setMin(intersectMin(left.current().getMin(), right.current().getMin()));
|
int leftMax = "*".equals(left.current().getMax()) ? Integer.MAX_VALUE : Integer.parseInt(left.current().getMax());
|
||||||
subset.setMax(intersectMax(left.current().getMax(), right.current().getMax()));
|
int rightMax = "*".equals(right.current().getMax()) ? Integer.MAX_VALUE : Integer.parseInt(right.current().getMax());
|
||||||
rule(comp, res, subset.getMax().equals("*") || Integer.parseInt(subset.getMax()) >= subset.getMin(), path, "Cardinality Mismatch: "+card(left)+"/"+card(right));
|
|
||||||
|
checkMinMax(comp, res, path, leftMin, rightMin, leftMax, rightMax);
|
||||||
|
superset.setMin(unionMin(leftMin, rightMin));
|
||||||
|
superset.setMax(unionMax(leftMax, rightMax, left.current().getMax(), right.current().getMax()));
|
||||||
|
subset.setMin(intersectMin(leftMin, rightMin));
|
||||||
|
subset.setMax(intersectMax(leftMax, rightMax, left.current().getMax(), right.current().getMax()));
|
||||||
|
|
||||||
superset.getType().addAll(unionTypes(comp, res, path, left.current().getType(), right.current().getType()));
|
superset.getType().addAll(unionTypes(comp, res, path, left.current().getType(), right.current().getType()));
|
||||||
subset.getType().addAll(intersectTypes(comp, res, subset, path, left.current().getType(), right.current().getType()));
|
subset.getType().addAll(intersectTypes(comp, res, subset, path, left.current().getType(), right.current().getType()));
|
||||||
rule(comp, res, !subset.getType().isEmpty() || (!left.current().hasType() && !right.current().hasType()), path, "Type Mismatch:\r\n "+typeCode(left)+"\r\n "+typeCode(right));
|
rule(comp, res, !subset.getType().isEmpty() || (!left.current().hasType() && !right.current().hasType()), path, "Type Mismatch: "+typeCode(left)+" vs "+typeCode(right));
|
||||||
// <fixed[x]><!-- ?? 0..1 * Value must be exactly this --></fixed[x]>
|
// <fixed[x]><!-- ?? 0..1 * Value must be exactly this --></fixed[x]>
|
||||||
// <pattern[x]><!-- ?? 0..1 * Value must have at least these property values --></pattern[x]>
|
// <pattern[x]><!-- ?? 0..1 * Value must have at least these property values --></pattern[x]>
|
||||||
superset.setMaxLengthElement(unionMaxLength(left.current().getMaxLength(), right.current().getMaxLength()));
|
superset.setMaxLengthElement(unionMaxLength(left.current().getMaxLength(), right.current().getMaxLength()));
|
||||||
|
@ -283,7 +302,8 @@ public class ProfileComparer extends CanonicalResourceComparer {
|
||||||
// return null;
|
// return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void compareChildren(ProfileComparison comp, StructuralMatch<ElementDefinition> res, String path, DefinitionNavigator left, DefinitionNavigator right) throws DefinitionException, IOException, FHIRFormatError {
|
|
||||||
|
private void compareChildren(ProfileComparison comp, StructuralMatch<ElementDefinitionNode> res, String path, DefinitionNavigator left, DefinitionNavigator right) throws DefinitionException, IOException, FHIRFormatError {
|
||||||
List<DefinitionNavigator> lc = left.children();
|
List<DefinitionNavigator> lc = left.children();
|
||||||
List<DefinitionNavigator> rc = right.children();
|
List<DefinitionNavigator> rc = right.children();
|
||||||
// it's possible that one of these profiles walks into a data type and the other doesn't
|
// it's possible that one of these profiles walks into a data type and the other doesn't
|
||||||
|
@ -299,10 +319,10 @@ public class ProfileComparer extends CanonicalResourceComparer {
|
||||||
DefinitionNavigator r = findInList(rc, l);
|
DefinitionNavigator r = findInList(rc, l);
|
||||||
if (r == null) {
|
if (r == null) {
|
||||||
comp.getUnion().getSnapshot().getElement().add(l.current().copy());
|
comp.getUnion().getSnapshot().getElement().add(l.current().copy());
|
||||||
res.getChildren().add(new StructuralMatch<ElementDefinition>(l.current(), vmI(IssueSeverity.INFORMATION, "Removed this element", path)));
|
res.getChildren().add(new StructuralMatch<ElementDefinitionNode>(new ElementDefinitionNode(l.getStructure(), l.current()), vmI(IssueSeverity.INFORMATION, "Removed this element", path)));
|
||||||
} else {
|
} else {
|
||||||
matchR.add(r);
|
matchR.add(r);
|
||||||
StructuralMatch<ElementDefinition> sm = new StructuralMatch<ElementDefinition>(l.current(), r.current());
|
StructuralMatch<ElementDefinitionNode> sm = new StructuralMatch<ElementDefinitionNode>(new ElementDefinitionNode(l.getStructure(), l.current()), new ElementDefinitionNode(r.getStructure(), r.current()));
|
||||||
res.getChildren().add(sm);
|
res.getChildren().add(sm);
|
||||||
compareElements(comp, sm, l.path(), null, l, r);
|
compareElements(comp, sm, l.path(), null, l, r);
|
||||||
}
|
}
|
||||||
|
@ -310,7 +330,7 @@ public class ProfileComparer extends CanonicalResourceComparer {
|
||||||
for (DefinitionNavigator r : rc) {
|
for (DefinitionNavigator r : rc) {
|
||||||
if (!matchR.contains(r)) {
|
if (!matchR.contains(r)) {
|
||||||
comp.getUnion().getSnapshot().getElement().add(r.current().copy());
|
comp.getUnion().getSnapshot().getElement().add(r.current().copy());
|
||||||
res.getChildren().add(new StructuralMatch<ElementDefinition>(vmI(IssueSeverity.INFORMATION, "Added this element", path), r.current()));
|
res.getChildren().add(new StructuralMatch<ElementDefinitionNode>(vmI(IssueSeverity.INFORMATION, "Added this element", path), new ElementDefinitionNode(r.getStructure(), r.current())));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -324,7 +344,7 @@ public class ProfileComparer extends CanonicalResourceComparer {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ruleEqual(ProfileComparison comp, StructuralMatch<ElementDefinition> res, DataType vLeft, DataType vRight, String name, String path) throws IOException {
|
private void ruleEqual(ProfileComparison comp, StructuralMatch<ElementDefinitionNode> res, DataType vLeft, DataType vRight, String name, String path) throws IOException {
|
||||||
if (vLeft == null && vRight == null) {
|
if (vLeft == null && vRight == null) {
|
||||||
// nothing
|
// nothing
|
||||||
} else if (vLeft == null) {
|
} else if (vLeft == null) {
|
||||||
|
@ -338,7 +358,7 @@ public class ProfileComparer extends CanonicalResourceComparer {
|
||||||
|
|
||||||
private String toString(DataType val, boolean left) throws IOException {
|
private String toString(DataType val, boolean left) throws IOException {
|
||||||
if (val instanceof PrimitiveType)
|
if (val instanceof PrimitiveType)
|
||||||
return "\"" + ((PrimitiveType) val).getValueAsString()+"\"";
|
return "'" + ((PrimitiveType) val).getValueAsString()+"'";
|
||||||
|
|
||||||
IParser jp = left ? session.getContextLeft().newJsonParser() : session.getContextRight().newJsonParser();
|
IParser jp = left ? session.getContextLeft().newJsonParser() : session.getContextRight().newJsonParser();
|
||||||
return jp.composeString(val, "value");
|
return jp.composeString(val, "value");
|
||||||
|
@ -356,14 +376,14 @@ public class ProfileComparer extends CanonicalResourceComparer {
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean rule(ProfileComparison comp, StructuralMatch<ElementDefinition> res, boolean test, String path, String message) {
|
private boolean rule(ProfileComparison comp, StructuralMatch<ElementDefinitionNode> res, boolean test, String path, String message) {
|
||||||
if (!test) {
|
if (!test) {
|
||||||
vm(IssueSeverity.ERROR, message, path, comp.getMessages(), res.getMessages());
|
vm(IssueSeverity.ERROR, message, path, comp.getMessages(), res.getMessages());
|
||||||
}
|
}
|
||||||
return test;
|
return test;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String mergeText(ProfileComparison comp, StructuralMatch<ElementDefinition> res, String path, String name, String left, String right, boolean isError) {
|
private String mergeText(ProfileComparison comp, StructuralMatch<ElementDefinitionNode> res, String path, String name, String left, String right, boolean isError) {
|
||||||
if (left == null && right == null)
|
if (left == null && right == null)
|
||||||
return null;
|
return null;
|
||||||
if (left == null)
|
if (left == null)
|
||||||
|
@ -375,7 +395,7 @@ public class ProfileComparer extends CanonicalResourceComparer {
|
||||||
if (left.equalsIgnoreCase(right))
|
if (left.equalsIgnoreCase(right))
|
||||||
return left;
|
return left;
|
||||||
if (path != null) {
|
if (path != null) {
|
||||||
vm(isError ? IssueSeverity.ERROR : IssueSeverity.WARNING, "Elements differ in "+name+":\r\n \""+left+"\"\r\n \""+right+"\"", path, comp.getMessages(), res.getMessages());
|
vm(isError ? IssueSeverity.ERROR : IssueSeverity.WARNING, "Elements differ in "+name+": '"+left+"' vs '"+right+"'", path, comp.getMessages(), res.getMessages());
|
||||||
}
|
}
|
||||||
return "left: "+left+"; right: "+right;
|
return "left: "+left+"; right: "+right;
|
||||||
}
|
}
|
||||||
|
@ -429,6 +449,36 @@ public class ProfileComparer extends CanonicalResourceComparer {
|
||||||
return right;
|
return right;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void checkMinMax(ProfileComparison comp, StructuralMatch<ElementDefinitionNode> res, String path, int leftMin, int rightMin, int leftMax, int rightMax) {
|
||||||
|
if (leftMin != rightMin) {
|
||||||
|
if (leftMin == 0) {
|
||||||
|
vm(IssueSeverity.INFORMATION, "Element minimum cardinalities differ: '"+leftMin+"' vs '"+rightMin+"'", path, comp.getMessages(), res.getMessages());
|
||||||
|
} else if (rightMin == 0) {
|
||||||
|
vm(IssueSeverity.INFORMATION, "Element minimum cardinalities differ: '"+leftMin+"' vs '"+rightMin+"'", path, comp.getMessages(), res.getMessages());
|
||||||
|
} else {
|
||||||
|
vm(IssueSeverity.INFORMATION, "Element minimum cardinalities differ: '"+leftMin+"' vs '"+rightMin+"'", path, comp.getMessages(), res.getMessages());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (leftMax != rightMax) {
|
||||||
|
if (leftMax == Integer.MAX_VALUE) {
|
||||||
|
vm(IssueSeverity.INFORMATION, "Element maximum cardinalities differ: '"+leftMax+"' vs '"+rightMax+"'", path, comp.getMessages(), res.getMessages());
|
||||||
|
} else if (rightMax == Integer.MAX_VALUE) {
|
||||||
|
vm(IssueSeverity.INFORMATION, "Element maximum cardinalities differ: '"+leftMax+"' vs '"+rightMax+"'", path, comp.getMessages(), res.getMessages());
|
||||||
|
} else {
|
||||||
|
vm(IssueSeverity.INFORMATION, "Element maximum cardinalities differ: '"+leftMax+"' vs '"+rightMax+"'", path, comp.getMessages(), res.getMessages());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// rule(comp, res, subset.getMax().equals("*") || Integer.parseInt(subset.getMax()) >= subset.getMin(), path, "Cardinality Mismatch: "+card(left)+"/"+card(right));
|
||||||
|
|
||||||
|
// cross comparison - if max > min in either direction, there can be no instances that are valid against both
|
||||||
|
if (leftMax < rightMin) {
|
||||||
|
vm(IssueSeverity.ERROR, "Element minimum cardinalities conflict: '"+leftMin+".."+leftMax+"' vs '"+rightMin+".."+rightMax+"': No instances can be valid against both profiles", path, comp.getMessages(), res.getMessages());
|
||||||
|
}
|
||||||
|
if (rightMax < leftMin) {
|
||||||
|
vm(IssueSeverity.ERROR, "Element minimum cardinalities conflict: '"+leftMin+".."+leftMax+"' vs '"+rightMin+".."+rightMax+"': No instances can be valid against both profiles", path, comp.getMessages(), res.getMessages());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private int unionMin(int left, int right) {
|
private int unionMin(int left, int right) {
|
||||||
if (left > right)
|
if (left > right)
|
||||||
return right;
|
return right;
|
||||||
|
@ -436,18 +486,14 @@ public class ProfileComparer extends CanonicalResourceComparer {
|
||||||
return left;
|
return left;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String intersectMax(String left, String right) {
|
private String intersectMax(int l, int r, String left, String right) {
|
||||||
int l = "*".equals(left) ? Integer.MAX_VALUE : Integer.parseInt(left);
|
|
||||||
int r = "*".equals(right) ? Integer.MAX_VALUE : Integer.parseInt(right);
|
|
||||||
if (l < r)
|
if (l < r)
|
||||||
return left;
|
return left;
|
||||||
else
|
else
|
||||||
return right;
|
return right;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String unionMax(String left, String right) {
|
private String unionMax(int l, int r, String left, String right) {
|
||||||
int l = "*".equals(left) ? Integer.MAX_VALUE : Integer.parseInt(left);
|
|
||||||
int r = "*".equals(right) ? Integer.MAX_VALUE : Integer.parseInt(right);
|
|
||||||
if (l < r)
|
if (l < r)
|
||||||
return right;
|
return right;
|
||||||
else
|
else
|
||||||
|
@ -480,7 +526,7 @@ public class ProfileComparer extends CanonicalResourceComparer {
|
||||||
return Integer.toString(defn.current().getMin())+".."+defn.current().getMax();
|
return Integer.toString(defn.current().getMin())+".."+defn.current().getMax();
|
||||||
}
|
}
|
||||||
|
|
||||||
private Collection<? extends TypeRefComponent> unionTypes(ProfileComparison comp, StructuralMatch<ElementDefinition> res, String path, List<TypeRefComponent> left, List<TypeRefComponent> right) throws DefinitionException, IOException, FHIRFormatError {
|
private Collection<? extends TypeRefComponent> unionTypes(ProfileComparison comp, StructuralMatch<ElementDefinitionNode> res, String path, List<TypeRefComponent> left, List<TypeRefComponent> right) throws DefinitionException, IOException, FHIRFormatError {
|
||||||
List<TypeRefComponent> result = new ArrayList<TypeRefComponent>();
|
List<TypeRefComponent> result = new ArrayList<TypeRefComponent>();
|
||||||
for (TypeRefComponent l : left)
|
for (TypeRefComponent l : left)
|
||||||
checkAddTypeUnion(comp, res, path, result, l, session.getContextLeft());
|
checkAddTypeUnion(comp, res, path, result, l, session.getContextLeft());
|
||||||
|
@ -489,7 +535,7 @@ public class ProfileComparer extends CanonicalResourceComparer {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkAddTypeUnion(ProfileComparison comp, StructuralMatch<ElementDefinition> res, String path, List<TypeRefComponent> results, TypeRefComponent nw, IWorkerContext ctxt) throws DefinitionException, IOException, FHIRFormatError {
|
private void checkAddTypeUnion(ProfileComparison comp, StructuralMatch<ElementDefinitionNode> res, String path, List<TypeRefComponent> results, TypeRefComponent nw, IWorkerContext ctxt) throws DefinitionException, IOException, FHIRFormatError {
|
||||||
boolean pfound = false;
|
boolean pfound = false;
|
||||||
boolean tfound = false;
|
boolean tfound = false;
|
||||||
nw = nw.copy();
|
nw = nw.copy();
|
||||||
|
@ -586,7 +632,7 @@ public class ProfileComparer extends CanonicalResourceComparer {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Collection<? extends TypeRefComponent> intersectTypes(ProfileComparison comp, StructuralMatch<ElementDefinition> res, ElementDefinition ed, String path, List<TypeRefComponent> left, List<TypeRefComponent> right) throws DefinitionException, IOException, FHIRFormatError {
|
private Collection<? extends TypeRefComponent> intersectTypes(ProfileComparison comp, StructuralMatch<ElementDefinitionNode> res, ElementDefinition ed, String path, List<TypeRefComponent> left, List<TypeRefComponent> right) throws DefinitionException, IOException, FHIRFormatError {
|
||||||
List<TypeRefComponent> result = new ArrayList<TypeRefComponent>();
|
List<TypeRefComponent> result = new ArrayList<TypeRefComponent>();
|
||||||
for (TypeRefComponent l : left) {
|
for (TypeRefComponent l : left) {
|
||||||
if (l.hasAggregation())
|
if (l.hasAggregation())
|
||||||
|
@ -665,7 +711,7 @@ public class ProfileComparer extends CanonicalResourceComparer {
|
||||||
return b.toString();
|
return b.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean compareBindings(ProfileComparison comp, StructuralMatch<ElementDefinition> res, ElementDefinition subset, ElementDefinition superset, String path, ElementDefinition lDef, ElementDefinition rDef) throws FHIRFormatError, DefinitionException, IOException {
|
private boolean compareBindings(ProfileComparison comp, StructuralMatch<ElementDefinitionNode> res, ElementDefinition subset, ElementDefinition superset, String path, ElementDefinition lDef, ElementDefinition rDef) throws FHIRFormatError, DefinitionException, IOException {
|
||||||
assert(lDef.hasBinding() || rDef.hasBinding());
|
assert(lDef.hasBinding() || rDef.hasBinding());
|
||||||
if (!lDef.hasBinding()) {
|
if (!lDef.hasBinding()) {
|
||||||
subset.setBinding(rDef.getBinding());
|
subset.setBinding(rDef.getBinding());
|
||||||
|
@ -801,7 +847,7 @@ public class ProfileComparer extends CanonicalResourceComparer {
|
||||||
}
|
}
|
||||||
|
|
||||||
// we can't really know about constraints. We create warnings, and collate them
|
// we can't really know about constraints. We create warnings, and collate them
|
||||||
private List<ElementDefinitionConstraintComponent> unionConstraints(ProfileComparison comp, StructuralMatch<ElementDefinition> res, String path, List<ElementDefinitionConstraintComponent> left, List<ElementDefinitionConstraintComponent> right) {
|
private List<ElementDefinitionConstraintComponent> unionConstraints(ProfileComparison comp, StructuralMatch<ElementDefinitionNode> res, String path, List<ElementDefinitionConstraintComponent> left, List<ElementDefinitionConstraintComponent> right) {
|
||||||
List<ElementDefinitionConstraintComponent> result = new ArrayList<ElementDefinitionConstraintComponent>();
|
List<ElementDefinitionConstraintComponent> result = new ArrayList<ElementDefinitionConstraintComponent>();
|
||||||
for (ElementDefinitionConstraintComponent l : left) {
|
for (ElementDefinitionConstraintComponent l : left) {
|
||||||
boolean found = false;
|
boolean found = false;
|
||||||
|
@ -829,7 +875,7 @@ public class ProfileComparer extends CanonicalResourceComparer {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private StructureDefinition resolveProfile(ProfileComparison comp, StructuralMatch<ElementDefinition> res, String path, String url, String name, IWorkerContext ctxt) {
|
private StructureDefinition resolveProfile(ProfileComparison comp, StructuralMatch<ElementDefinitionNode> res, String path, String url, String name, IWorkerContext ctxt) {
|
||||||
StructureDefinition sd = ctxt.fetchResource(StructureDefinition.class, url);
|
StructureDefinition sd = ctxt.fetchResource(StructureDefinition.class, url);
|
||||||
if (sd == null) {
|
if (sd == null) {
|
||||||
ValidationMessage vm = vmI(IssueSeverity.WARNING, "Unable to resolve profile "+url+" in profile "+name, path);
|
ValidationMessage vm = vmI(IssueSeverity.WARNING, "Unable to resolve profile "+url+" in profile "+name, path);
|
||||||
|
@ -841,7 +887,7 @@ public class ProfileComparer extends CanonicalResourceComparer {
|
||||||
return binding.getStrength() == BindingStrength.EXAMPLE || binding.getStrength() == BindingStrength.PREFERRED;
|
return binding.getStrength() == BindingStrength.EXAMPLE || binding.getStrength() == BindingStrength.PREFERRED;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ElementDefinitionBindingComponent unionBindings(ProfileComparison comp, StructuralMatch<ElementDefinition> res, String path, ElementDefinitionBindingComponent left, ElementDefinitionBindingComponent right) throws FHIRFormatError, DefinitionException, IOException {
|
private ElementDefinitionBindingComponent unionBindings(ProfileComparison comp, StructuralMatch<ElementDefinitionNode> res, String path, ElementDefinitionBindingComponent left, ElementDefinitionBindingComponent right) throws FHIRFormatError, DefinitionException, IOException {
|
||||||
ElementDefinitionBindingComponent union = new ElementDefinitionBindingComponent();
|
ElementDefinitionBindingComponent union = new ElementDefinitionBindingComponent();
|
||||||
if (left.getStrength().compareTo(right.getStrength()) < 0)
|
if (left.getStrength().compareTo(right.getStrength()) < 0)
|
||||||
union.setStrength(left.getStrength());
|
union.setStrength(left.getStrength());
|
||||||
|
@ -881,17 +927,17 @@ public class ProfileComparer extends CanonicalResourceComparer {
|
||||||
return gen.generate(model, prefix, 0, null);
|
return gen.generate(model, prefix, 0, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void genElementComp(String defPath, HierarchicalTableGenerator gen, List<Row> rows, StructuralMatch<ElementDefinition> combined, String corePath, String prefix, Row slicingRow, boolean root) throws IOException {
|
private void genElementComp(String defPath, HierarchicalTableGenerator gen, List<Row> rows, StructuralMatch<ElementDefinitionNode> combined, String corePath, String prefix, Row slicingRow, boolean root) throws IOException {
|
||||||
Row originalRow = slicingRow;
|
Row originalRow = slicingRow;
|
||||||
Row typesRow = null;
|
Row typesRow = null;
|
||||||
|
|
||||||
List<StructuralMatch<ElementDefinition>> children = combined.getChildren();
|
List<StructuralMatch<ElementDefinitionNode>> children = combined.getChildren();
|
||||||
|
|
||||||
Row row = gen.new Row();
|
Row row = gen.new Row();
|
||||||
rows.add(row);
|
rows.add(row);
|
||||||
String path = combined.either().getPath();
|
String path = combined.either().getDef().getPath();
|
||||||
row.setAnchor(path);
|
row.setAnchor(path);
|
||||||
row.setColor(utilsRight.getRowColor(combined.either(), false));
|
row.setColor(utilsRight.getRowColor(combined.either().getDef(), false));
|
||||||
if (eitherHasSlicing(combined))
|
if (eitherHasSlicing(combined))
|
||||||
row.setLineColor(1);
|
row.setLineColor(1);
|
||||||
else if (eitherHasSliceName(combined))
|
else if (eitherHasSliceName(combined))
|
||||||
|
@ -917,7 +963,7 @@ public class ProfileComparer extends CanonicalResourceComparer {
|
||||||
row.setIcon("icon_choice.gif", HierarchicalTableGenerator.TEXT_ICON_CHOICE);
|
row.setIcon("icon_choice.gif", HierarchicalTableGenerator.TEXT_ICON_CHOICE);
|
||||||
typesRow = row;
|
typesRow = row;
|
||||||
}
|
}
|
||||||
} else if (combined.either().hasContentReference())
|
} else if (combined.either().getDef().hasContentReference())
|
||||||
row.setIcon("icon_reuse.png", HierarchicalTableGenerator.TEXT_ICON_REUSE);
|
row.setIcon("icon_reuse.png", HierarchicalTableGenerator.TEXT_ICON_REUSE);
|
||||||
else if (isPrimitive(combined))
|
else if (isPrimitive(combined))
|
||||||
row.setIcon("icon_primitive.png", HierarchicalTableGenerator.TEXT_ICON_PRIMITIVE);
|
row.setIcon("icon_primitive.png", HierarchicalTableGenerator.TEXT_ICON_PRIMITIVE);
|
||||||
|
@ -927,7 +973,7 @@ public class ProfileComparer extends CanonicalResourceComparer {
|
||||||
row.setIcon("icon_datatype.gif", HierarchicalTableGenerator.TEXT_ICON_DATATYPE);
|
row.setIcon("icon_datatype.gif", HierarchicalTableGenerator.TEXT_ICON_DATATYPE);
|
||||||
else
|
else
|
||||||
row.setIcon("icon_resource.png", HierarchicalTableGenerator.TEXT_ICON_RESOURCE);
|
row.setIcon("icon_resource.png", HierarchicalTableGenerator.TEXT_ICON_RESOURCE);
|
||||||
String ref = defPath == null ? null : defPath + combined.either().getId();
|
String ref = defPath == null ? null : defPath + combined.either().getDef().getId();
|
||||||
String sName = tail(path);
|
String sName = tail(path);
|
||||||
String sn = getSliceName(combined);
|
String sn = getSliceName(combined);
|
||||||
if (sn != null)
|
if (sn != null)
|
||||||
|
@ -937,23 +983,23 @@ public class ProfileComparer extends CanonicalResourceComparer {
|
||||||
String leftColor = !combined.hasLeft() ? COLOR_NO_ROW_LEFT : combined.hasErrors() ? COLOR_DIFFERENT : null;
|
String leftColor = !combined.hasLeft() ? COLOR_NO_ROW_LEFT : combined.hasErrors() ? COLOR_DIFFERENT : null;
|
||||||
String rightColor = !combined.hasRight() ? COLOR_NO_ROW_LEFT : combined.hasErrors() ? COLOR_DIFFERENT : null;
|
String rightColor = !combined.hasRight() ? COLOR_NO_ROW_LEFT : combined.hasErrors() ? COLOR_DIFFERENT : null;
|
||||||
if (combined.hasLeft()) {
|
if (combined.hasLeft()) {
|
||||||
nc = utilsRight.genElementNameCell(gen, combined.getLeft(), "??", true, corePath, prefix, root, false, false, null, typesRow, row, false, ext, used , ref, sName);
|
nc = utilsRight.genElementNameCell(gen, combined.getLeft().getDef(), "??", true, corePath, prefix, root, false, false, combined.getLeft().getSrc(), typesRow, row, false, ext, used , ref, sName);
|
||||||
} else {
|
} else {
|
||||||
nc = utilsRight.genElementNameCell(gen, combined.getRight(), "??", true, corePath, prefix, root, false, false, null, typesRow, row, false, ext, used , ref, sName);
|
nc = utilsRight.genElementNameCell(gen, combined.getRight().getDef(), "??", true, corePath, prefix, root, false, false, combined.getRight().getSrc(), typesRow, row, false, ext, used , ref, sName);
|
||||||
}
|
}
|
||||||
if (combined.hasLeft()) {
|
if (combined.hasLeft()) {
|
||||||
frame(utilsRight.genElementCells(gen, combined.getLeft(), "??", true, corePath, prefix, root, false, false, null, typesRow, row, false, ext, used , ref, sName, nc, false), leftColor);
|
frame(utilsRight.genElementCells(gen, combined.getLeft().getDef(), "??", true, corePath, prefix, root, false, false, combined.getLeft().getSrc(), typesRow, row, true, ext, used , ref, sName, nc, false, false), leftColor);
|
||||||
} else {
|
} else {
|
||||||
frame(spacers(row, 4, gen), leftColor);
|
frame(spacers(row, 4, gen), leftColor);
|
||||||
}
|
}
|
||||||
if (combined.hasRight()) {
|
if (combined.hasRight()) {
|
||||||
frame(utilsRight.genElementCells(gen, combined.getRight(), "??", true, corePath, prefix, root, false, false, null, typesRow, row, false, ext, used, ref, sName, nc, false), rightColor);
|
frame(utilsRight.genElementCells(gen, combined.getRight().getDef(), "??", true, corePath, prefix, root, false, false, combined.getRight().getSrc(), typesRow, row, true, ext, used, ref, sName, nc, false, false), rightColor);
|
||||||
} else {
|
} else {
|
||||||
frame(spacers(row, 4, gen), rightColor);
|
frame(spacers(row, 4, gen), rightColor);
|
||||||
}
|
}
|
||||||
row.getCells().add(cellForMessages(gen, combined.getMessages()));
|
row.getCells().add(cellForMessages(gen, combined.getMessages()));
|
||||||
|
|
||||||
for (StructuralMatch<ElementDefinition> child : children) {
|
for (StructuralMatch<ElementDefinitionNode> child : children) {
|
||||||
genElementComp(defPath, gen, row.getSubRows(), child, corePath, prefix, originalRow, false);
|
genElementComp(defPath, gen, row.getSubRows(), child, corePath, prefix, originalRow, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -978,47 +1024,47 @@ public class ProfileComparer extends CanonicalResourceComparer {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getSliceName(StructuralMatch<ElementDefinition> combined) {
|
private String getSliceName(StructuralMatch<ElementDefinitionNode> combined) {
|
||||||
// TODO Auto-generated method stub
|
// TODO Auto-generated method stub
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isDataType(StructuralMatch<ElementDefinition> combined) {
|
private boolean isDataType(StructuralMatch<ElementDefinitionNode> combined) {
|
||||||
// TODO Auto-generated method stub
|
// TODO Auto-generated method stub
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean hasTarget(StructuralMatch<ElementDefinition> combined) {
|
private boolean hasTarget(StructuralMatch<ElementDefinitionNode> combined) {
|
||||||
// TODO Auto-generated method stub
|
// TODO Auto-generated method stub
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isPrimitive(StructuralMatch<ElementDefinition> combined) {
|
private boolean isPrimitive(StructuralMatch<ElementDefinitionNode> combined) {
|
||||||
// TODO Auto-generated method stub
|
// TODO Auto-generated method stub
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean allAreReference(StructuralMatch<ElementDefinition> combined) {
|
private boolean allAreReference(StructuralMatch<ElementDefinitionNode> combined) {
|
||||||
// TODO Auto-generated method stub
|
// TODO Auto-generated method stub
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean hasChoice(StructuralMatch<ElementDefinition> combined) {
|
private boolean hasChoice(StructuralMatch<ElementDefinitionNode> combined) {
|
||||||
// TODO Auto-generated method stub
|
// TODO Auto-generated method stub
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean elementIsComplex(StructuralMatch<ElementDefinition> combined) {
|
private boolean elementIsComplex(StructuralMatch<ElementDefinitionNode> combined) {
|
||||||
// TODO Auto-generated method stub velement.hasType() && element.getType().get(0).hasProfile() && extensionIsComplex(element.getType().get(0).getProfile().get(0).getValue()
|
// TODO Auto-generated method stub velement.hasType() && element.getType().get(0).hasProfile() && extensionIsComplex(element.getType().get(0).getProfile().get(0).getValue()
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean eitherHasSliceName(StructuralMatch<ElementDefinition> combined) {
|
private boolean eitherHasSliceName(StructuralMatch<ElementDefinitionNode> combined) {
|
||||||
// TODO Auto-generated method stub
|
// TODO Auto-generated method stub
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean eitherHasSlicing(StructuralMatch<ElementDefinition> combined) {
|
private boolean eitherHasSlicing(StructuralMatch<ElementDefinitionNode> combined) {
|
||||||
// TODO Auto-generated method stub
|
// TODO Auto-generated method stub
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -549,7 +549,17 @@ public class ProfileUtilities extends TranslatingUtilities {
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<ElementDefinition> getChildList(StructureDefinition structure, ElementDefinition element) {
|
public List<ElementDefinition> getChildList(StructureDefinition structure, ElementDefinition element) {
|
||||||
return getChildList(structure, element.getPath(), element.getId(), false);
|
if (element.hasContentReference()) {
|
||||||
|
ElementDefinition target = element;
|
||||||
|
for (ElementDefinition t : structure.getSnapshot().getElement()) {
|
||||||
|
if (t.getId().equals(element.getContentReference().substring(1))) {
|
||||||
|
target = t;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return getChildList(structure, target.getPath(), target.getId(), false);
|
||||||
|
} else {
|
||||||
|
return getChildList(structure, element.getPath(), element.getId(), false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateMaps(StructureDefinition base, StructureDefinition derived) throws DefinitionException {
|
public void updateMaps(StructureDefinition base, StructureDefinition derived) throws DefinitionException {
|
||||||
|
@ -613,174 +623,178 @@ public class ProfileUtilities extends TranslatingUtilities {
|
||||||
}
|
}
|
||||||
derived.setUserData("profileutils.snapshot.generating", true);
|
derived.setUserData("profileutils.snapshot.generating", true);
|
||||||
snapshotStack.add(derived.getUrl());
|
snapshotStack.add(derived.getUrl());
|
||||||
|
|
||||||
if (!Utilities.noString(webUrl) && !webUrl.endsWith("/"))
|
|
||||||
webUrl = webUrl + '/';
|
|
||||||
|
|
||||||
if (defWebRoot == null)
|
|
||||||
defWebRoot = webUrl;
|
|
||||||
derived.setSnapshot(new StructureDefinitionSnapshotComponent());
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
checkDifferential(derived.getDifferential().getElement(), typeName(derived.getType()), derived.getUrl());
|
|
||||||
checkDifferentialBaseType(derived);
|
|
||||||
|
|
||||||
// so we have two lists - the base list, and the differential list
|
if (!Utilities.noString(webUrl) && !webUrl.endsWith("/"))
|
||||||
// the differential list is only allowed to include things that are in the base list, but
|
webUrl = webUrl + '/';
|
||||||
// is allowed to include them multiple times - thereby slicing them
|
|
||||||
|
|
||||||
// our approach is to walk through the base list, and see whether the differential
|
if (defWebRoot == null)
|
||||||
// says anything about them.
|
defWebRoot = webUrl;
|
||||||
int baseCursor = 0;
|
derived.setSnapshot(new StructureDefinitionSnapshotComponent());
|
||||||
int diffCursor = 0; // we need a diff cursor because we can only look ahead, in the bound scoped by longer paths
|
|
||||||
|
try {
|
||||||
|
checkDifferential(derived.getDifferential().getElement(), typeName(derived.getType()), derived.getUrl());
|
||||||
|
checkDifferentialBaseType(derived);
|
||||||
|
|
||||||
|
// so we have two lists - the base list, and the differential list
|
||||||
|
// the differential list is only allowed to include things that are in the base list, but
|
||||||
|
// is allowed to include them multiple times - thereby slicing them
|
||||||
|
|
||||||
|
// our approach is to walk through the base list, and see whether the differential
|
||||||
|
// says anything about them.
|
||||||
|
int baseCursor = 0;
|
||||||
|
int diffCursor = 0; // we need a diff cursor because we can only look ahead, in the bound scoped by longer paths
|
||||||
|
|
||||||
|
|
||||||
for (ElementDefinition e : derived.getDifferential().getElement())
|
for (ElementDefinition e : derived.getDifferential().getElement())
|
||||||
e.clearUserData(GENERATED_IN_SNAPSHOT);
|
e.clearUserData(GENERATED_IN_SNAPSHOT);
|
||||||
|
|
||||||
// we actually delegate the work to a subroutine so we can re-enter it with a different cursors
|
// we actually delegate the work to a subroutine so we can re-enter it with a different cursors
|
||||||
StructureDefinitionDifferentialComponent diff = cloneDiff(derived.getDifferential()); // we make a copy here because we're sometimes going to hack the differential while processing it. Have to migrate user data back afterwards
|
StructureDefinitionDifferentialComponent diff = cloneDiff(derived.getDifferential()); // we make a copy here because we're sometimes going to hack the differential while processing it. Have to migrate user data back afterwards
|
||||||
StructureDefinitionSnapshotComponent baseSnapshot = base.getSnapshot();
|
StructureDefinitionSnapshotComponent baseSnapshot = base.getSnapshot();
|
||||||
if (derived.getDerivation() == TypeDerivationRule.SPECIALIZATION) {
|
if (derived.getDerivation() == TypeDerivationRule.SPECIALIZATION) {
|
||||||
String derivedType = derived.getType();
|
String derivedType = derived.getType();
|
||||||
if (StructureDefinitionKind.LOGICAL.equals(derived.getKind()) && derived.getType().contains("/")) {
|
if (StructureDefinitionKind.LOGICAL.equals(derived.getKind()) && derived.getType().contains("/")) {
|
||||||
derivedType = derivedType.substring(derivedType.lastIndexOf("/")+1);
|
derivedType = derivedType.substring(derivedType.lastIndexOf("/")+1);
|
||||||
|
}
|
||||||
|
baseSnapshot = cloneSnapshot(baseSnapshot, base.getType(), derivedType);
|
||||||
}
|
}
|
||||||
baseSnapshot = cloneSnapshot(baseSnapshot, base.getType(), derivedType);
|
// if (derived.getId().equals("2.16.840.1.113883.10.20.22.2.1.1")) {
|
||||||
}
|
// debug = true;
|
||||||
// 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);
|
||||||
processPaths("", derived.getSnapshot(), baseSnapshot, diff, baseCursor, diffCursor, baseSnapshot.getElement().size()-1,
|
checkGroupConstraints(derived);
|
||||||
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);
|
if (derived.getDerivation() == TypeDerivationRule.SPECIALIZATION) {
|
||||||
checkGroupConstraints(derived);
|
for (ElementDefinition e : diff.getElement()) {
|
||||||
if (derived.getDerivation() == TypeDerivationRule.SPECIALIZATION) {
|
if (!e.hasUserData(GENERATED_IN_SNAPSHOT)) {
|
||||||
for (ElementDefinition e : diff.getElement()) {
|
ElementDefinition outcome = updateURLs(url, webUrl, e.copy());
|
||||||
if (!e.hasUserData(GENERATED_IN_SNAPSHOT)) {
|
e.setUserData(GENERATED_IN_SNAPSHOT, outcome);
|
||||||
ElementDefinition outcome = updateURLs(url, webUrl, e.copy());
|
derived.getSnapshot().addElement(outcome);
|
||||||
e.setUserData(GENERATED_IN_SNAPSHOT, outcome);
|
}
|
||||||
derived.getSnapshot().addElement(outcome);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (derived.getKind() != StructureDefinitionKind.LOGICAL && !derived.getSnapshot().getElementFirstRep().getType().isEmpty())
|
if (derived.getKind() != StructureDefinitionKind.LOGICAL && !derived.getSnapshot().getElementFirstRep().getType().isEmpty())
|
||||||
throw new Error(context.formatMessage(I18nConstants.TYPE_ON_FIRST_SNAPSHOT_ELEMENT_FOR__IN__FROM_, derived.getSnapshot().getElementFirstRep().getPath(), derived.getUrl(), base.getUrl()));
|
throw new Error(context.formatMessage(I18nConstants.TYPE_ON_FIRST_SNAPSHOT_ELEMENT_FOR__IN__FROM_, derived.getSnapshot().getElementFirstRep().getPath(), derived.getUrl(), base.getUrl()));
|
||||||
updateMaps(base, derived);
|
updateMaps(base, derived);
|
||||||
|
|
||||||
setIds(derived, false);
|
setIds(derived, false);
|
||||||
if (debug) {
|
if (debug) {
|
||||||
System.out.println("Differential: ");
|
|
||||||
for (ElementDefinition ed : derived.getDifferential().getElement())
|
|
||||||
System.out.println(" "+ed.getId()+" : "+typeSummaryWithProfile(ed)+"["+ed.getMin()+".."+ed.getMax()+"]"+sliceSummary(ed)+" "+constraintSummary(ed));
|
|
||||||
System.out.println("Snapshot: ");
|
|
||||||
for (ElementDefinition ed : derived.getSnapshot().getElement())
|
|
||||||
System.out.println(" "+ed.getId()+" : "+typeSummaryWithProfile(ed)+"["+ed.getMin()+".."+ed.getMax()+"]"+sliceSummary(ed)+" "+constraintSummary(ed));
|
|
||||||
}
|
|
||||||
CommaSeparatedStringBuilder b = new CommaSeparatedStringBuilder();
|
|
||||||
//Check that all differential elements have a corresponding snapshot element
|
|
||||||
int ce = 0;
|
|
||||||
for (ElementDefinition e : diff.getElement()) {
|
|
||||||
if (!e.hasUserData("diff-source"))
|
|
||||||
throw new Error(context.formatMessage(I18nConstants.UNXPECTED_INTERNAL_CONDITION__NO_SOURCE_ON_DIFF_ELEMENT));
|
|
||||||
else {
|
|
||||||
if (e.hasUserData(DERIVATION_EQUALS))
|
|
||||||
((Base) e.getUserData("diff-source")).setUserData(DERIVATION_EQUALS, e.getUserData(DERIVATION_EQUALS));
|
|
||||||
if (e.hasUserData(DERIVATION_POINTER))
|
|
||||||
((Base) e.getUserData("diff-source")).setUserData(DERIVATION_POINTER, e.getUserData(DERIVATION_POINTER));
|
|
||||||
}
|
|
||||||
if (!e.hasUserData(GENERATED_IN_SNAPSHOT)) {
|
|
||||||
b.append(e.hasId() ? "id: "+e.getId() : "path: "+e.getPath());
|
|
||||||
ce++;
|
|
||||||
if (e.hasId()) {
|
|
||||||
String msg = "No match found in the generated snapshot: check that the path and definitions are legal in the differential (including order)";
|
|
||||||
messages.add(new ValidationMessage(Source.ProfileValidator, ValidationMessage.IssueType.VALUE, url+"#"+e.getId(), msg, ValidationMessage.IssueSeverity.ERROR));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!Utilities.noString(b.toString())) {
|
|
||||||
String msg = "The profile "+derived.getUrl()+" has "+ce+" "+Utilities.pluralize("element", ce)+" in the differential ("+b.toString()+") that don't have a matching element in the snapshot: check that the path and definitions are legal in the differential (including order)";
|
|
||||||
System.out.println("Error in snapshot generation: "+msg);
|
|
||||||
if (!debug) {
|
|
||||||
System.out.println("Differential: ");
|
System.out.println("Differential: ");
|
||||||
for (ElementDefinition ed : derived.getDifferential().getElement())
|
for (ElementDefinition ed : derived.getDifferential().getElement())
|
||||||
System.out.println(" "+ed.getId()+" = "+ed.getPath()+" : "+typeSummaryWithProfile(ed)+"["+ed.getMin()+".."+ed.getMax()+"]"+sliceSummary(ed)+" "+constraintSummary(ed));
|
System.out.println(" "+ed.getId()+" : "+typeSummaryWithProfile(ed)+"["+ed.getMin()+".."+ed.getMax()+"]"+sliceSummary(ed)+" "+constraintSummary(ed));
|
||||||
System.out.println("Snapshot: ");
|
System.out.println("Snapshot: ");
|
||||||
for (ElementDefinition ed : derived.getSnapshot().getElement())
|
for (ElementDefinition ed : derived.getSnapshot().getElement())
|
||||||
System.out.println(" "+ed.getId()+" = "+ed.getPath()+" : "+typeSummaryWithProfile(ed)+"["+ed.getMin()+".."+ed.getMax()+"]"+sliceSummary(ed)+" "+constraintSummary(ed));
|
System.out.println(" "+ed.getId()+" : "+typeSummaryWithProfile(ed)+"["+ed.getMin()+".."+ed.getMax()+"]"+sliceSummary(ed)+" "+constraintSummary(ed));
|
||||||
}
|
}
|
||||||
if (exception)
|
CommaSeparatedStringBuilder b = new CommaSeparatedStringBuilder();
|
||||||
throw new DefinitionException(msg);
|
//Check that all differential elements have a corresponding snapshot element
|
||||||
else
|
int ce = 0;
|
||||||
messages.add(new ValidationMessage(Source.ProfileValidator, ValidationMessage.IssueType.VALUE, url, msg, ValidationMessage.IssueSeverity.ERROR));
|
for (ElementDefinition e : diff.getElement()) {
|
||||||
}
|
if (!e.hasUserData("diff-source"))
|
||||||
// hack around a problem in R4 definitions (somewhere?)
|
throw new Error(context.formatMessage(I18nConstants.UNXPECTED_INTERNAL_CONDITION__NO_SOURCE_ON_DIFF_ELEMENT));
|
||||||
for (ElementDefinition ed : derived.getSnapshot().getElement()) {
|
else {
|
||||||
for (ElementDefinitionMappingComponent mm : ed.getMapping()) {
|
if (e.hasUserData(DERIVATION_EQUALS))
|
||||||
if (mm.hasMap()) {
|
((Base) e.getUserData("diff-source")).setUserData(DERIVATION_EQUALS, e.getUserData(DERIVATION_EQUALS));
|
||||||
mm.setMap(mm.getMap().trim());
|
if (e.hasUserData(DERIVATION_POINTER))
|
||||||
|
((Base) e.getUserData("diff-source")).setUserData(DERIVATION_POINTER, e.getUserData(DERIVATION_POINTER));
|
||||||
}
|
}
|
||||||
}
|
if (!e.hasUserData(GENERATED_IN_SNAPSHOT)) {
|
||||||
for (ElementDefinitionConstraintComponent s : ed.getConstraint()) {
|
b.append(e.hasId() ? "id: "+e.getId() : "path: "+e.getPath());
|
||||||
if (s.hasSource()) {
|
ce++;
|
||||||
String ref = s.getSource();
|
if (e.hasId()) {
|
||||||
if (!Utilities.isAbsoluteUrl(ref)) {
|
String msg = "No match found in the generated snapshot: check that the path and definitions are legal in the differential (including order)";
|
||||||
if (ref.contains(".")) {
|
messages.add(new ValidationMessage(Source.ProfileValidator, ValidationMessage.IssueType.VALUE, url+"#"+e.getId(), msg, ValidationMessage.IssueSeverity.ERROR));
|
||||||
s.setSource("http://hl7.org/fhir/StructureDefinition/"+ref.substring(0, ref.indexOf("."))+"#"+ref);
|
|
||||||
} else {
|
|
||||||
s.setSource("http://hl7.org/fhir/StructureDefinition/"+ref);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
if (!Utilities.noString(b.toString())) {
|
||||||
if (derived.getDerivation() == TypeDerivationRule.SPECIALIZATION) {
|
String msg = "The profile "+derived.getUrl()+" has "+ce+" "+Utilities.pluralize("element", ce)+" in the differential ("+b.toString()+") that don't have a matching element in the snapshot: check that the path and definitions are legal in the differential (including order)";
|
||||||
|
System.out.println("Error in snapshot generation: "+msg);
|
||||||
|
if (!debug) {
|
||||||
|
System.out.println("Differential: ");
|
||||||
|
for (ElementDefinition ed : derived.getDifferential().getElement())
|
||||||
|
System.out.println(" "+ed.getId()+" = "+ed.getPath()+" : "+typeSummaryWithProfile(ed)+"["+ed.getMin()+".."+ed.getMax()+"]"+sliceSummary(ed)+" "+constraintSummary(ed));
|
||||||
|
System.out.println("Snapshot: ");
|
||||||
|
for (ElementDefinition ed : derived.getSnapshot().getElement())
|
||||||
|
System.out.println(" "+ed.getId()+" = "+ed.getPath()+" : "+typeSummaryWithProfile(ed)+"["+ed.getMin()+".."+ed.getMax()+"]"+sliceSummary(ed)+" "+constraintSummary(ed));
|
||||||
|
}
|
||||||
|
if (exception)
|
||||||
|
throw new DefinitionException(msg);
|
||||||
|
else
|
||||||
|
messages.add(new ValidationMessage(Source.ProfileValidator, ValidationMessage.IssueType.VALUE, url, msg, ValidationMessage.IssueSeverity.ERROR));
|
||||||
|
}
|
||||||
|
// hack around a problem in R4 definitions (somewhere?)
|
||||||
for (ElementDefinition ed : derived.getSnapshot().getElement()) {
|
for (ElementDefinition ed : derived.getSnapshot().getElement()) {
|
||||||
if (!ed.hasBase()) {
|
for (ElementDefinitionMappingComponent mm : ed.getMapping()) {
|
||||||
ed.getBase().setPath(ed.getPath()).setMin(ed.getMin()).setMax(ed.getMax());
|
if (mm.hasMap()) {
|
||||||
}
|
mm.setMap(mm.getMap().trim());
|
||||||
}
|
|
||||||
}
|
|
||||||
// last, check for wrong profiles or target profiles
|
|
||||||
for (ElementDefinition ed : derived.getSnapshot().getElement()) {
|
|
||||||
for (TypeRefComponent t : ed.getType()) {
|
|
||||||
for (UriType u : t.getProfile()) {
|
|
||||||
StructureDefinition sd = context.fetchResource(StructureDefinition.class, u.getValue());
|
|
||||||
if (sd == null) {
|
|
||||||
if (xver != null && xver.matchingUrl(u.getValue()) && xver.status(u.getValue()) == XVerExtensionStatus.Valid) {
|
|
||||||
sd = xver.makeDefinition(u.getValue());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (sd == null) {
|
}
|
||||||
if (messages != null) {
|
for (ElementDefinitionConstraintComponent s : ed.getConstraint()) {
|
||||||
messages.add(new ValidationMessage(Source.ProfileValidator, ValidationMessage.IssueType.VALUE, url+"#"+ed.getId(), "The type of profile "+u.getValue()+" cannot be checked as the profile is not known", IssueSeverity.WARNING));
|
if (s.hasSource()) {
|
||||||
}
|
String ref = s.getSource();
|
||||||
} else {
|
if (!Utilities.isAbsoluteUrl(ref)) {
|
||||||
String wt = t.getWorkingCode();
|
if (ref.contains(".")) {
|
||||||
if (ed.getPath().equals("Bundle.entry.response.outcome")) {
|
s.setSource("http://hl7.org/fhir/StructureDefinition/"+ref.substring(0, ref.indexOf("."))+"#"+ref);
|
||||||
wt = "OperationOutcome";
|
} else {
|
||||||
}
|
s.setSource("http://hl7.org/fhir/StructureDefinition/"+ref);
|
||||||
if (!sd.getType().equals(wt)) {
|
|
||||||
boolean ok = isCompatibleType(wt, sd);
|
|
||||||
if (!ok) {
|
|
||||||
String smsg = "The profile "+u.getValue()+" has type "+sd.getType()+" which is not consistent with the stated type "+wt;
|
|
||||||
if (exception)
|
|
||||||
throw new DefinitionException(smsg);
|
|
||||||
else
|
|
||||||
messages.add(new ValidationMessage(Source.ProfileValidator, ValidationMessage.IssueType.VALUE, url+"#"+ed.getId(), smsg, IssueSeverity.ERROR));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (derived.getDerivation() == TypeDerivationRule.SPECIALIZATION) {
|
||||||
|
for (ElementDefinition ed : derived.getSnapshot().getElement()) {
|
||||||
|
if (!ed.hasBase()) {
|
||||||
|
ed.getBase().setPath(ed.getPath()).setMin(ed.getMin()).setMax(ed.getMax());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// last, check for wrong profiles or target profiles
|
||||||
|
for (ElementDefinition ed : derived.getSnapshot().getElement()) {
|
||||||
|
for (TypeRefComponent t : ed.getType()) {
|
||||||
|
for (UriType u : t.getProfile()) {
|
||||||
|
StructureDefinition sd = context.fetchResource(StructureDefinition.class, u.getValue());
|
||||||
|
if (sd == null) {
|
||||||
|
if (xver != null && xver.matchingUrl(u.getValue()) && xver.status(u.getValue()) == XVerExtensionStatus.Valid) {
|
||||||
|
sd = xver.makeDefinition(u.getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (sd == null) {
|
||||||
|
if (messages != null) {
|
||||||
|
messages.add(new ValidationMessage(Source.ProfileValidator, ValidationMessage.IssueType.VALUE, url+"#"+ed.getId(), "The type of profile "+u.getValue()+" cannot be checked as the profile is not known", IssueSeverity.WARNING));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
String wt = t.getWorkingCode();
|
||||||
|
if (ed.getPath().equals("Bundle.entry.response.outcome")) {
|
||||||
|
wt = "OperationOutcome";
|
||||||
|
}
|
||||||
|
if (!sd.getType().equals(wt)) {
|
||||||
|
boolean ok = isCompatibleType(wt, sd);
|
||||||
|
if (!ok) {
|
||||||
|
String smsg = "The profile "+u.getValue()+" has type "+sd.getType()+" which is not consistent with the stated type "+wt;
|
||||||
|
if (exception)
|
||||||
|
throw new DefinitionException(smsg);
|
||||||
|
else
|
||||||
|
messages.add(new ValidationMessage(Source.ProfileValidator, ValidationMessage.IssueType.VALUE, url+"#"+ed.getId(), smsg, IssueSeverity.ERROR));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
// if we had an exception generating the snapshot, make sure we don't leave any half generated snapshot behind
|
||||||
|
derived.setSnapshot(null);
|
||||||
|
derived.clearUserData("profileutils.snapshot.generating");
|
||||||
|
throw e;
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} finally {
|
||||||
// if we had an exception generating the snapshot, make sure we don't leave any half generated snapshot behind
|
|
||||||
derived.setSnapshot(null);
|
|
||||||
derived.clearUserData("profileutils.snapshot.generating");
|
derived.clearUserData("profileutils.snapshot.generating");
|
||||||
throw e;
|
snapshotStack.remove(derived.getUrl());
|
||||||
}
|
}
|
||||||
derived.clearUserData("profileutils.snapshot.generating");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void checkDifferentialBaseType(StructureDefinition derived) throws Error {
|
public void checkDifferentialBaseType(StructureDefinition derived) throws Error {
|
||||||
|
@ -1077,6 +1091,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
||||||
ElementDefinition outcome = updateURLs(url, webUrl, currentBase.copy());
|
ElementDefinition outcome = updateURLs(url, webUrl, currentBase.copy());
|
||||||
outcome.setPath(fixedPathDest(contextPathDst, outcome.getPath(), redirector, contextPathSrc));
|
outcome.setPath(fixedPathDest(contextPathDst, outcome.getPath(), redirector, contextPathSrc));
|
||||||
updateFromBase(outcome, currentBase);
|
updateFromBase(outcome, currentBase);
|
||||||
|
updateConstraintSources(outcome, srcSD.getUrl());
|
||||||
markDerived(outcome);
|
markDerived(outcome);
|
||||||
if (resultPathBase == null)
|
if (resultPathBase == null)
|
||||||
resultPathBase = outcome.getPath();
|
resultPathBase = outcome.getPath();
|
||||||
|
@ -1132,7 +1147,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
||||||
processPaths(indent+" ", result, base, differential, nbc, start, nbl-1, diffCursor-1, url, webUrl, profileName, tgt.getElement().getPath(), outcome.getPath(), trimDifferential, contextName, resultPathBase, false, null, null, redirectorStack(redirector, outcome, cpath), srcSD);
|
processPaths(indent+" ", result, base, differential, nbc, start, nbl-1, diffCursor-1, url, webUrl, profileName, tgt.getElement().getPath(), outcome.getPath(), trimDifferential, contextName, resultPathBase, false, null, null, redirectorStack(redirector, outcome, cpath), srcSD);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
StructureDefinition dt = outcome.getType().size() > 1 ? context.fetchTypeDefinition("Element") : getProfileForDataType(outcome.getType().get(0));
|
StructureDefinition dt = outcome.getType().size() > 1 ? context.fetchTypeDefinition("Element") : getProfileForDataType(outcome.getType().get(0), webUrl);
|
||||||
if (dt == null) {
|
if (dt == null) {
|
||||||
throw new DefinitionException(context.formatMessage(I18nConstants.UNKNOWN_TYPE__AT_, outcome.getType().get(0), cpath));
|
throw new DefinitionException(context.formatMessage(I18nConstants.UNKNOWN_TYPE__AT_, outcome.getType().get(0), cpath));
|
||||||
}
|
}
|
||||||
|
@ -1285,7 +1300,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
||||||
processPaths(indent+" ", result, base, differential, nbc, start - 1, nbl-1, diffCursor - 1, url, webUrl, profileName, tgt.getElement().getPath(), diffMatches.get(0).getPath(), trimDifferential, contextName, resultPathBase, false, null, null, redirectorStack(redirector, outcome, cpath), srcSD);
|
processPaths(indent+" ", result, base, differential, nbc, start - 1, nbl-1, diffCursor - 1, url, webUrl, profileName, tgt.getElement().getPath(), diffMatches.get(0).getPath(), trimDifferential, contextName, resultPathBase, false, null, null, redirectorStack(redirector, outcome, cpath), srcSD);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
StructureDefinition dt = outcome.getType().size() == 1 ? getProfileForDataType(outcome.getType().get(0)) : getProfileForDataType("Element");
|
StructureDefinition dt = outcome.getType().size() == 1 ? getProfileForDataType(outcome.getType().get(0), webUrl) : getProfileForDataType("Element");
|
||||||
if (dt == null)
|
if (dt == null)
|
||||||
throw new DefinitionException(context.formatMessage(I18nConstants._HAS_CHILDREN__FOR_TYPE__IN_PROFILE__BUT_CANT_FIND_TYPE, diffMatches.get(0).getPath(), differential.getElement().get(diffCursor).getPath(), typeCode(outcome.getType()), profileName));
|
throw new DefinitionException(context.formatMessage(I18nConstants._HAS_CHILDREN__FOR_TYPE__IN_PROFILE__BUT_CANT_FIND_TYPE, diffMatches.get(0).getPath(), differential.getElement().get(diffCursor).getPath(), typeCode(outcome.getType()), profileName));
|
||||||
contextName = dt.getUrl();
|
contextName = dt.getUrl();
|
||||||
|
@ -1496,7 +1511,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
||||||
if (baseHasChildren(base, currentBase)) { // not a new type here
|
if (baseHasChildren(base, currentBase)) { // not a new type here
|
||||||
throw new Error("This situation is not yet handled (constrain slicing to 1..1 and fix base slice for inline structure - please report issue to grahame@fhir.org along with a test case that reproduces this error (@ "+cpath+" | "+currentBase.getPath()+")");
|
throw new Error("This situation is not yet handled (constrain slicing to 1..1 and fix base slice for inline structure - please report issue to grahame@fhir.org along with a test case that reproduces this error (@ "+cpath+" | "+currentBase.getPath()+")");
|
||||||
} else {
|
} else {
|
||||||
StructureDefinition dt = getTypeForElement(differential, diffCursor, profileName, diffMatches, outcome);
|
StructureDefinition dt = getTypeForElement(differential, diffCursor, profileName, diffMatches, outcome, webUrl);
|
||||||
contextName = dt.getUrl();
|
contextName = dt.getUrl();
|
||||||
diffCursor++;
|
diffCursor++;
|
||||||
start = diffCursor;
|
start = diffCursor;
|
||||||
|
@ -1562,7 +1577,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
||||||
processPaths(indent+" ", result, base, differential, baseCursor+1, diffCursor, baseLimit, diffLimit, url, webUrl, profileName, contextPathSrc, contextPathDst, trimDifferential, contextName, resultPathBase, false, null, null, redirector, srcSD);
|
processPaths(indent+" ", result, base, differential, baseCursor+1, diffCursor, baseLimit, diffLimit, url, webUrl, profileName, contextPathSrc, contextPathDst, trimDifferential, contextName, resultPathBase, false, null, null, redirector, srcSD);
|
||||||
baseCursor = indexOfFirstNonChild(base, currentBase, baseCursor, baseLimit);
|
baseCursor = indexOfFirstNonChild(base, currentBase, baseCursor, baseLimit);
|
||||||
} else {
|
} else {
|
||||||
StructureDefinition dt = getTypeForElement(differential, diffCursor, profileName, diffMatches, outcome);
|
StructureDefinition dt = getTypeForElement(differential, diffCursor, profileName, diffMatches, outcome, webUrl);
|
||||||
contextName = dt.getUrl();
|
contextName = dt.getUrl();
|
||||||
int start = diffCursor;
|
int start = diffCursor;
|
||||||
while (differential.getElement().size() > diffCursor && pathStartsWith(differential.getElement().get(diffCursor).getPath(), cpath+"."))
|
while (differential.getElement().size() > diffCursor && pathStartsWith(differential.getElement().get(diffCursor).getPath(), cpath+"."))
|
||||||
|
@ -1763,7 +1778,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
||||||
if (base.getElement().get(baseCursor).getType().size() != 1) {
|
if (base.getElement().get(baseCursor).getType().size() != 1) {
|
||||||
throw new Error(context.formatMessage(I18nConstants.DIFFERENTIAL_WALKS_INTO____BUT_THE_BASE_DOES_NOT_AND_THERE_IS_NOT_A_SINGLE_FIXED_TYPE_THE_TYPE_IS__THIS_IS_NOT_HANDLED_YET, cpath, diffMatches.get(0).toString(), base.getElement().get(baseCursor).typeSummary()));
|
throw new Error(context.formatMessage(I18nConstants.DIFFERENTIAL_WALKS_INTO____BUT_THE_BASE_DOES_NOT_AND_THERE_IS_NOT_A_SINGLE_FIXED_TYPE_THE_TYPE_IS__THIS_IS_NOT_HANDLED_YET, cpath, diffMatches.get(0).toString(), base.getElement().get(baseCursor).typeSummary()));
|
||||||
}
|
}
|
||||||
StructureDefinition dt = getProfileForDataType(base.getElement().get(baseCursor).getType().get(0));
|
StructureDefinition dt = getProfileForDataType(base.getElement().get(baseCursor).getType().get(0), webUrl);
|
||||||
if (dt == null) {
|
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), diffMatches.get(0).getPath()));
|
||||||
}
|
}
|
||||||
|
@ -1879,7 +1894,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
||||||
diffCursor - 1, url, webUrl, profileName+pathTail(diffMatches, 0), base.getElement().get(0).getPath(), base.getElement().get(0).getPath(), trimDifferential, contextName, resultPathBase, false, null, null, redirector, srcSD);
|
diffCursor - 1, url, webUrl, profileName+pathTail(diffMatches, 0), base.getElement().get(0).getPath(), base.getElement().get(0).getPath(), trimDifferential, contextName, resultPathBase, false, null, null, redirector, srcSD);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
StructureDefinition dt = getProfileForDataType(outcome.getType().get(0));
|
StructureDefinition dt = getProfileForDataType(outcome.getType().get(0), webUrl);
|
||||||
// if (t.getCode().equals("Extension") && t.hasProfile() && !t.getProfile().contains(":")) {
|
// if (t.getCode().equals("Extension") && t.hasProfile() && !t.getProfile().contains(":")) {
|
||||||
// lloydfix dt =
|
// lloydfix dt =
|
||||||
// }
|
// }
|
||||||
|
@ -1913,6 +1928,15 @@ public class ProfileUtilities extends TranslatingUtilities {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void updateConstraintSources(ElementDefinition ed, String url) {
|
||||||
|
for (ElementDefinitionConstraintComponent c : ed.getConstraint()) {
|
||||||
|
if (!c.hasSource()) {
|
||||||
|
c.setSource(url);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
private Set<String> getListOfTypes(ElementDefinition e) {
|
private Set<String> getListOfTypes(ElementDefinition e) {
|
||||||
Set<String> result = new HashSet<>();
|
Set<String> result = new HashSet<>();
|
||||||
for (TypeRefComponent t : e.getType()) {
|
for (TypeRefComponent t : e.getType()) {
|
||||||
|
@ -1922,7 +1946,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
||||||
}
|
}
|
||||||
|
|
||||||
public StructureDefinition getTypeForElement(StructureDefinitionDifferentialComponent differential, int diffCursor, String profileName,
|
public StructureDefinition getTypeForElement(StructureDefinitionDifferentialComponent differential, int diffCursor, String profileName,
|
||||||
List<ElementDefinition> diffMatches, ElementDefinition outcome) {
|
List<ElementDefinition> diffMatches, ElementDefinition outcome, String webUrl) {
|
||||||
if (outcome.getType().size() == 0) {
|
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_, diffMatches.get(0).getPath(), differential.getElement().get(diffCursor).getPath(), profileName));
|
||||||
}
|
}
|
||||||
|
@ -1932,7 +1956,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
||||||
throw new DefinitionException(context.formatMessage(I18nConstants._HAS_CHILDREN__AND_MULTIPLE_TYPES__IN_PROFILE_, diffMatches.get(0).getPath(), differential.getElement().get(diffCursor).getPath(), typeCode(outcome.getType()), profileName));
|
throw new DefinitionException(context.formatMessage(I18nConstants._HAS_CHILDREN__AND_MULTIPLE_TYPES__IN_PROFILE_, diffMatches.get(0).getPath(), differential.getElement().get(diffCursor).getPath(), typeCode(outcome.getType()), profileName));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
StructureDefinition dt = getProfileForDataType(outcome.getType().get(0));
|
StructureDefinition dt = getProfileForDataType(outcome.getType().get(0), webUrl);
|
||||||
if (dt == null)
|
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), diffMatches.get(0).getPath()));
|
||||||
return dt;
|
return dt;
|
||||||
|
@ -2087,6 +2111,8 @@ public class ProfileUtilities extends TranslatingUtilities {
|
||||||
|
|
||||||
private void removeStatusExtensions(ElementDefinition outcome) {
|
private void removeStatusExtensions(ElementDefinition outcome) {
|
||||||
outcome.removeExtension(ToolingExtensions.EXT_FMM_LEVEL);
|
outcome.removeExtension(ToolingExtensions.EXT_FMM_LEVEL);
|
||||||
|
outcome.removeExtension(ToolingExtensions.EXT_FMM_SUPPORT);
|
||||||
|
outcome.removeExtension(ToolingExtensions.EXT_FMM_DERIVED);
|
||||||
outcome.removeExtension(ToolingExtensions.EXT_STANDARDS_STATUS);
|
outcome.removeExtension(ToolingExtensions.EXT_STANDARDS_STATUS);
|
||||||
outcome.removeExtension(ToolingExtensions.EXT_NORMATIVE_VERSION);
|
outcome.removeExtension(ToolingExtensions.EXT_NORMATIVE_VERSION);
|
||||||
outcome.removeExtension(ToolingExtensions.EXT_WORKGROUP);
|
outcome.removeExtension(ToolingExtensions.EXT_WORKGROUP);
|
||||||
|
@ -2402,10 +2428,16 @@ public class ProfileUtilities extends TranslatingUtilities {
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
private StructureDefinition getProfileForDataType(TypeRefComponent type) {
|
private StructureDefinition getProfileForDataType(TypeRefComponent type, String webUrl) {
|
||||||
StructureDefinition sd = null;
|
StructureDefinition sd = null;
|
||||||
if (type.hasProfile()) {
|
if (type.hasProfile()) {
|
||||||
sd = context.fetchResource(StructureDefinition.class, type.getProfile().get(0).getValue());
|
sd = context.fetchResource(StructureDefinition.class, type.getProfile().get(0).getValue());
|
||||||
|
if (sd == null) {
|
||||||
|
if (xver != null && xver.matchingUrl(type.getProfile().get(0).getValue()) && xver.status(type.getProfile().get(0).getValue()) == XVerExtensionStatus.Valid) {
|
||||||
|
sd = xver.makeDefinition(type.getProfile().get(0).getValue());
|
||||||
|
generateSnapshot(context.fetchTypeDefinition("Extension"), sd, sd.getUrl(), webUrl, sd.getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
if (sd == null)
|
if (sd == null)
|
||||||
System.out.println("Failed to find referenced profile: " + type.getProfile());
|
System.out.println("Failed to find referenced profile: " + type.getProfile());
|
||||||
}
|
}
|
||||||
|
@ -2475,19 +2507,19 @@ public class ProfileUtilities extends TranslatingUtilities {
|
||||||
if (webUrl != null) {
|
if (webUrl != null) {
|
||||||
// also, must touch up the markdown
|
// also, must touch up the markdown
|
||||||
if (element.hasDefinition())
|
if (element.hasDefinition())
|
||||||
element.setDefinition(processRelativeUrls(element.getDefinition(), webUrl, baseSpecUrl(), context.getResourceNames(), masterSourceFileNames));
|
element.setDefinition(processRelativeUrls(element.getDefinition(), webUrl, baseSpecUrl(), context.getResourceNames(), masterSourceFileNames, true));
|
||||||
if (element.hasComment())
|
if (element.hasComment())
|
||||||
element.setComment(processRelativeUrls(element.getComment(), webUrl, baseSpecUrl(), context.getResourceNames(), masterSourceFileNames));
|
element.setComment(processRelativeUrls(element.getComment(), webUrl, baseSpecUrl(), context.getResourceNames(), masterSourceFileNames, true));
|
||||||
if (element.hasRequirements())
|
if (element.hasRequirements())
|
||||||
element.setRequirements(processRelativeUrls(element.getRequirements(), webUrl, baseSpecUrl(), context.getResourceNames(), masterSourceFileNames));
|
element.setRequirements(processRelativeUrls(element.getRequirements(), webUrl, baseSpecUrl(), context.getResourceNames(), masterSourceFileNames, true));
|
||||||
if (element.hasMeaningWhenMissing())
|
if (element.hasMeaningWhenMissing())
|
||||||
element.setMeaningWhenMissing(processRelativeUrls(element.getMeaningWhenMissing(), webUrl, baseSpecUrl(), context.getResourceNames(), masterSourceFileNames));
|
element.setMeaningWhenMissing(processRelativeUrls(element.getMeaningWhenMissing(), webUrl, baseSpecUrl(), context.getResourceNames(), masterSourceFileNames, true));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return element;
|
return element;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String processRelativeUrls(String markdown, String webUrl, String basePath, List<String> resourceNames, Set<String> filenames) {
|
public static String processRelativeUrls(String markdown, String webUrl, String basePath, List<String> resourceNames, Set<String> filenames, boolean processRelatives) {
|
||||||
StringBuilder b = new StringBuilder();
|
StringBuilder b = new StringBuilder();
|
||||||
int i = 0;
|
int i = 0;
|
||||||
while (i < markdown.length()) {
|
while (i < markdown.length()) {
|
||||||
|
@ -2515,7 +2547,14 @@ public class ProfileUtilities extends TranslatingUtilities {
|
||||||
} else {
|
} else {
|
||||||
b.append("](");
|
b.append("](");
|
||||||
// disabled 7-Dec 2021 GDG - we don't want to fool with relative URLs at all?
|
// disabled 7-Dec 2021 GDG - we don't want to fool with relative URLs at all?
|
||||||
// b.append(webUrl);
|
// re-enabled 11-Feb 2022 GDG - we do want to do this. At least, $assemble in davinci-dtr, where the markdown comes from the SDC IG, and an SDC local reference must be changed to point to SDC. in this case, it's called when generating snapshots
|
||||||
|
// added processRelatives parameter to deal with this (well, to try)
|
||||||
|
if (processRelatives && webUrl != null) {
|
||||||
|
// System.out.println("Making "+url+" relative to '"+webUrl+"'");
|
||||||
|
b.append(webUrl);
|
||||||
|
} else {
|
||||||
|
// System.out.println("Not making "+url+" relative to '"+webUrl+"'");
|
||||||
|
}
|
||||||
i = i + 1;
|
i = i + 1;
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
|
@ -2773,7 +2812,9 @@ public class ProfileUtilities extends TranslatingUtilities {
|
||||||
profile = source.getType().size() == 1 && source.getTypeFirstRep().hasProfile() ? context.fetchResource(StructureDefinition.class, source.getTypeFirstRep().getProfile().get(0).getValue()) : null;
|
profile = source.getType().size() == 1 && source.getTypeFirstRep().hasProfile() ? context.fetchResource(StructureDefinition.class, source.getTypeFirstRep().getProfile().get(0).getValue()) : null;
|
||||||
if (profile != null) {
|
if (profile != null) {
|
||||||
ElementDefinition e = profile.getSnapshot().getElement().get(0);
|
ElementDefinition e = profile.getSnapshot().getElement().get(0);
|
||||||
base.setDefinition(e.getDefinition());
|
String webroot = profile.getUserString("webroot");
|
||||||
|
|
||||||
|
base.setDefinition(processRelativeUrls(e.getDefinition(), webroot, baseSpecUrl(), context.getResourceNames(), masterSourceFileNames, true));
|
||||||
base.setShort(e.getShort());
|
base.setShort(e.getShort());
|
||||||
if (e.hasCommentElement())
|
if (e.hasCommentElement())
|
||||||
base.setCommentElement(e.getCommentElement());
|
base.setCommentElement(e.getCommentElement());
|
||||||
|
@ -3502,7 +3543,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
||||||
List<TypeRefComponent> types = e.getType();
|
List<TypeRefComponent> types = e.getType();
|
||||||
if (!e.hasType()) {
|
if (!e.hasType()) {
|
||||||
if (root) { // we'll use base instead of types then
|
if (root) { // we'll use base instead of types then
|
||||||
StructureDefinition bsd = context.fetchResource(StructureDefinition.class, profile.getBaseDefinition());
|
StructureDefinition bsd = profile == null ? null : context.fetchResource(StructureDefinition.class, profile.getBaseDefinition());
|
||||||
if (bsd != null) {
|
if (bsd != null) {
|
||||||
if (bsd.hasUserData("path")) {
|
if (bsd.hasUserData("path")) {
|
||||||
c.getPieces().add(gen.new Piece(Utilities.isAbsoluteUrl(bsd.getUserString("path")) ? bsd.getUserString("path") : imagePath +bsd.getUserString("path"), bsd.getName(), null));
|
c.getPieces().add(gen.new Piece(Utilities.isAbsoluteUrl(bsd.getUserString("path")) ? bsd.getUserString("path") : imagePath +bsd.getUserString("path"), bsd.getName(), null));
|
||||||
|
@ -3584,7 +3625,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
||||||
c.addPiece(checkForNoChange(tl, gen.new Piece(null,", ", null)));
|
c.addPiece(checkForNoChange(tl, gen.new Piece(null,", ", null)));
|
||||||
}
|
}
|
||||||
|
|
||||||
ref = pkp.getLinkForProfile(profile, p.getValue());
|
ref = pkp == null ? null : pkp.getLinkForProfile(profile, p.getValue());
|
||||||
if (ref != null) {
|
if (ref != null) {
|
||||||
String[] parts = ref.split("\\|");
|
String[] parts = ref.split("\\|");
|
||||||
if (parts[0].startsWith("http:") || parts[0].startsWith("https:")) {
|
if (parts[0].startsWith("http:") || parts[0].startsWith("https:")) {
|
||||||
|
@ -3665,7 +3706,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private String codeForAggregation(AggregationMode a) {
|
public static String codeForAggregation(AggregationMode a) {
|
||||||
switch (a) {
|
switch (a) {
|
||||||
case BUNDLED : return "b";
|
case BUNDLED : return "b";
|
||||||
case CONTAINED : return "c";
|
case CONTAINED : return "c";
|
||||||
|
@ -3674,7 +3715,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private String hintForAggregation(AggregationMode a) {
|
public static String hintForAggregation(AggregationMode a) {
|
||||||
if (a != null)
|
if (a != null)
|
||||||
return a.getDefinition();
|
return a.getDefinition();
|
||||||
else
|
else
|
||||||
|
@ -3683,7 +3724,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
||||||
|
|
||||||
|
|
||||||
private String checkPrepend(String corePath, String path) {
|
private String checkPrepend(String corePath, String path) {
|
||||||
if (pkp.prependLinks() && !(path.startsWith("http:") || path.startsWith("https:")))
|
if (pkp != null && pkp.prependLinks() && !(path.startsWith("http:") || path.startsWith("https:")))
|
||||||
return corePath+path;
|
return corePath+path;
|
||||||
else
|
else
|
||||||
return path;
|
return path;
|
||||||
|
@ -4055,7 +4096,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
||||||
if (logicalModel && element.hasRepresentation(PropertyRepresentation.XMLATTR))
|
if (logicalModel && element.hasRepresentation(PropertyRepresentation.XMLATTR))
|
||||||
sName = "@"+sName;
|
sName = "@"+sName;
|
||||||
Cell nc = genElementNameCell(gen, element, profileBaseFileName, snapshot, corePath, imagePath, root, logicalModel, allInvariants, profile, typesRow, row, hasDef, ext, used, ref, sName);
|
Cell nc = genElementNameCell(gen, element, profileBaseFileName, snapshot, corePath, imagePath, root, logicalModel, allInvariants, profile, typesRow, row, hasDef, ext, used, ref, sName);
|
||||||
genElementCells(gen, element, profileBaseFileName, snapshot, corePath, imagePath, root, logicalModel, allInvariants, profile, typesRow, row, hasDef, ext, used, ref, sName, nc, mustSupport);
|
genElementCells(gen, element, profileBaseFileName, snapshot, corePath, imagePath, root, logicalModel, allInvariants, profile, typesRow, row, hasDef, ext, used, ref, sName, nc, mustSupport, true);
|
||||||
if (element.hasSlicing()) {
|
if (element.hasSlicing()) {
|
||||||
if (standardExtensionSlicing(element)) {
|
if (standardExtensionSlicing(element)) {
|
||||||
used.used = true; // doesn't matter whether we have a type, we're used if we're setting up slicing ... element.hasType() && element.getType().get(0).hasProfile();
|
used.used = true; // doesn't matter whether we have a type, we're used if we're setting up slicing ... element.hasType() && element.getType().get(0).hasProfile();
|
||||||
|
@ -4183,7 +4224,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
||||||
|
|
||||||
public List<Cell> genElementCells(HierarchicalTableGenerator gen, ElementDefinition element, String profileBaseFileName, boolean snapshot, String corePath,
|
public List<Cell> genElementCells(HierarchicalTableGenerator gen, ElementDefinition element, String profileBaseFileName, boolean snapshot, String corePath,
|
||||||
String imagePath, boolean root, boolean logicalModel, boolean allInvariants, StructureDefinition profile, Row typesRow, Row row, boolean hasDef,
|
String imagePath, boolean root, boolean logicalModel, boolean allInvariants, StructureDefinition profile, Row typesRow, Row row, boolean hasDef,
|
||||||
boolean ext, UnusedTracker used, String ref, String sName, Cell nameCell, boolean mustSupport) throws IOException {
|
boolean ext, UnusedTracker used, String ref, String sName, Cell nameCell, boolean mustSupport, boolean allowSubRows) throws IOException {
|
||||||
List<Cell> res = new ArrayList<>();
|
List<Cell> res = new ArrayList<>();
|
||||||
Cell gc = gen.new Cell();
|
Cell gc = gen.new Cell();
|
||||||
row.getCells().add(gc);
|
row.getCells().add(gc);
|
||||||
|
@ -4209,7 +4250,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
||||||
if (extDefn == null) {
|
if (extDefn == null) {
|
||||||
res.add(genCardinality(gen, element, row, hasDef, used, null));
|
res.add(genCardinality(gen, element, row, hasDef, used, null));
|
||||||
res.add(addCell(row, gen.new Cell(null, null, "?gen-e1? "+element.getType().get(0).getProfile(), null, null)));
|
res.add(addCell(row, gen.new Cell(null, null, "?gen-e1? "+element.getType().get(0).getProfile(), null, null)));
|
||||||
res.add(generateDescription(gen, row, element, (ElementDefinition) element.getUserData(DERIVATION_POINTER), used.used, profile == null ? "" : profile.getUrl(), eurl, profile, corePath, imagePath, root, logicalModel, allInvariants, snapshot, mustSupport));
|
res.add(generateDescription(gen, row, element, (ElementDefinition) element.getUserData(DERIVATION_POINTER), used.used, profile == null ? "" : profile.getUrl(), eurl, profile, corePath, imagePath, root, logicalModel, allInvariants, snapshot, mustSupport, allowSubRows));
|
||||||
} else {
|
} else {
|
||||||
String name = urltail(eurl);
|
String name = urltail(eurl);
|
||||||
nameCell.getPieces().get(0).setText(name);
|
nameCell.getPieces().get(0).setText(name);
|
||||||
|
@ -4222,7 +4263,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
||||||
else // if it's complex, we just call it nothing
|
else // if it's complex, we just call it nothing
|
||||||
// genTypes(gen, row, extDefn.getSnapshot().getElement().get(0), profileBaseFileName, profile);
|
// genTypes(gen, row, extDefn.getSnapshot().getElement().get(0), profileBaseFileName, profile);
|
||||||
res.add(addCell(row, gen.new Cell(null, null, "("+translate("sd.table", "Complex")+")", null, null)));
|
res.add(addCell(row, gen.new Cell(null, null, "("+translate("sd.table", "Complex")+")", null, null)));
|
||||||
res.add(generateDescription(gen, row, element, extDefn.getElement(), used.used, null, extDefn.getUrl(), profile, corePath, imagePath, root, logicalModel, allInvariants, valueDefn, snapshot, mustSupport));
|
res.add(generateDescription(gen, row, element, extDefn.getElement(), used.used, null, extDefn.getUrl(), profile, corePath, imagePath, root, logicalModel, allInvariants, valueDefn, snapshot, mustSupport, allowSubRows));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
res.add(genCardinality(gen, element, row, hasDef, used, null));
|
res.add(genCardinality(gen, element, row, hasDef, used, null));
|
||||||
|
@ -4230,7 +4271,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
||||||
res.add(addCell(row, gen.new Cell()));
|
res.add(addCell(row, gen.new Cell()));
|
||||||
else
|
else
|
||||||
res.add(genTypes(gen, row, element, profileBaseFileName, profile, corePath, imagePath, root, mustSupport));
|
res.add(genTypes(gen, row, element, profileBaseFileName, profile, corePath, imagePath, root, mustSupport));
|
||||||
res.add(generateDescription(gen, row, element, (ElementDefinition) element.getUserData(DERIVATION_POINTER), used.used, null, null, profile, corePath, imagePath, root, logicalModel, allInvariants, snapshot, mustSupport));
|
res.add(generateDescription(gen, row, element, (ElementDefinition) element.getUserData(DERIVATION_POINTER), used.used, null, null, profile, corePath, imagePath, root, logicalModel, allInvariants, snapshot, mustSupport, allowSubRows));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
res.add(genCardinality(gen, element, row, hasDef, used, null));
|
res.add(genCardinality(gen, element, row, hasDef, used, null));
|
||||||
|
@ -4238,7 +4279,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
||||||
res.add(genTypes(gen, row, element, profileBaseFileName, profile, corePath, imagePath, root, mustSupport));
|
res.add(genTypes(gen, row, element, profileBaseFileName, profile, corePath, imagePath, root, mustSupport));
|
||||||
else
|
else
|
||||||
res.add(addCell(row, gen.new Cell()));
|
res.add(addCell(row, gen.new Cell()));
|
||||||
res.add(generateDescription(gen, row, element, (ElementDefinition) element.getUserData(DERIVATION_POINTER), used.used, null, null, profile, corePath, imagePath, root, logicalModel, allInvariants, snapshot, mustSupport));
|
res.add(generateDescription(gen, row, element, (ElementDefinition) element.getUserData(DERIVATION_POINTER), used.used, null, null, profile, corePath, imagePath, root, logicalModel, allInvariants, snapshot, mustSupport, allowSubRows));
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
@ -4289,12 +4330,12 @@ public class ProfileUtilities extends TranslatingUtilities {
|
||||||
|
|
||||||
private boolean isBaseCondition(IdType c) {
|
private boolean isBaseCondition(IdType c) {
|
||||||
String key = c.asStringValue();
|
String key = c.asStringValue();
|
||||||
return key.startsWith("ele-") || key.startsWith("res-") || key.startsWith("ext-") || key.startsWith("dom-") || key.startsWith("dr-");
|
return key != null && key.startsWith("ele-") || key.startsWith("res-") || key.startsWith("ext-") || key.startsWith("dom-") || key.startsWith("dr-");
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isBaseConstraint(ElementDefinitionConstraintComponent con) {
|
private boolean isBaseConstraint(ElementDefinitionConstraintComponent con) {
|
||||||
String key = con.getKey();
|
String key = con.getKey();
|
||||||
return key.startsWith("ele-") || key.startsWith("res-") || key.startsWith("ext-") || key.startsWith("dom-") || key.startsWith("dr-");
|
return key != null && key.startsWith("ele-") || key.startsWith("res-") || key.startsWith("ext-") || key.startsWith("dom-") || key.startsWith("dr-");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void makeChoiceRows(List<Row> subRows, ElementDefinition element, HierarchicalTableGenerator gen, String corePath, String profileBaseFileName, boolean mustSupportMode) {
|
private void makeChoiceRows(List<Row> subRows, ElementDefinition element, HierarchicalTableGenerator gen, String corePath, String profileBaseFileName, boolean mustSupportMode) {
|
||||||
|
@ -4544,11 +4585,11 @@ public class ProfileUtilities extends TranslatingUtilities {
|
||||||
&& element.getSlicing().getRules() != SlicingRules.CLOSED && element.getSlicing().getDiscriminator().size() == 1 && element.getSlicing().getDiscriminator().get(0).getPath().equals("url") && element.getSlicing().getDiscriminator().get(0).getType().equals(DiscriminatorType.VALUE);
|
&& element.getSlicing().getRules() != SlicingRules.CLOSED && element.getSlicing().getDiscriminator().size() == 1 && element.getSlicing().getDiscriminator().get(0).getPath().equals("url") && element.getSlicing().getDiscriminator().get(0).getType().equals(DiscriminatorType.VALUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Cell generateDescription(HierarchicalTableGenerator gen, Row row, ElementDefinition definition, ElementDefinition fallback, boolean used, String baseURL, String url, StructureDefinition profile, String corePath, String imagePath, boolean root, boolean logicalModel, boolean allInvariants, boolean snapshot, boolean mustSupportOnly) throws IOException, FHIRException {
|
private Cell generateDescription(HierarchicalTableGenerator gen, Row row, ElementDefinition definition, ElementDefinition fallback, boolean used, String baseURL, String url, StructureDefinition profile, String corePath, String imagePath, boolean root, boolean logicalModel, boolean allInvariants, boolean snapshot, boolean mustSupportOnly, boolean allowSubRows) throws IOException, FHIRException {
|
||||||
return generateDescription(gen, row, definition, fallback, used, baseURL, url, profile, corePath, imagePath, root, logicalModel, allInvariants, null, snapshot, mustSupportOnly);
|
return generateDescription(gen, row, definition, fallback, used, baseURL, url, profile, corePath, imagePath, root, logicalModel, allInvariants, null, snapshot, mustSupportOnly, allowSubRows);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Cell generateDescription(HierarchicalTableGenerator gen, Row row, ElementDefinition definition, ElementDefinition fallback, boolean used, String baseURL, String url, StructureDefinition profile, String corePath, String imagePath, boolean root, boolean logicalModel, boolean allInvariants, ElementDefinition valueDefn, boolean snapshot, boolean mustSupportOnly) throws IOException, FHIRException {
|
private Cell generateDescription(HierarchicalTableGenerator gen, Row row, ElementDefinition definition, ElementDefinition fallback, boolean used, String baseURL, String url, StructureDefinition profile, String corePath, String imagePath, boolean root, boolean logicalModel, boolean allInvariants, ElementDefinition valueDefn, boolean snapshot, boolean mustSupportOnly, boolean allowSubRows) throws IOException, FHIRException {
|
||||||
Cell c = gen.new Cell();
|
Cell c = gen.new Cell();
|
||||||
row.getCells().add(c);
|
row.getCells().add(c);
|
||||||
|
|
||||||
|
@ -4564,7 +4605,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (root) {
|
if (root) {
|
||||||
if (profile.getAbstract()) {
|
if (profile != null && profile.getAbstract()) {
|
||||||
if (!c.getPieces().isEmpty()) { c.addPiece(gen.new Piece("br")); }
|
if (!c.getPieces().isEmpty()) { c.addPiece(gen.new Piece("br")); }
|
||||||
c.addPiece(gen.new Piece(null, "This is an abstract profile", null));
|
c.addPiece(gen.new Piece(null, "This is an abstract profile", null));
|
||||||
}
|
}
|
||||||
|
@ -4659,7 +4700,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
||||||
if (binding!=null && !binding.isEmpty()) {
|
if (binding!=null && !binding.isEmpty()) {
|
||||||
if (!c.getPieces().isEmpty())
|
if (!c.getPieces().isEmpty())
|
||||||
c.addPiece(gen.new Piece("br"));
|
c.addPiece(gen.new Piece("br"));
|
||||||
BindingResolution br = pkp.resolveBinding(profile, binding, definition.getPath());
|
BindingResolution br = pkp == null ? makeNullBr(binding) : pkp.resolveBinding(profile, binding, definition.getPath());
|
||||||
c.getPieces().add(checkForNoChange(binding, gen.new Piece(null, translate("sd.table", "Binding")+": ", null).addStyle("font-weight:bold")));
|
c.getPieces().add(checkForNoChange(binding, gen.new Piece(null, translate("sd.table", "Binding")+": ", null).addStyle("font-weight:bold")));
|
||||||
c.getPieces().add(checkForNoChange(binding.getValueSetElement(), gen.new Piece(br.url == null ? null : Utilities.isAbsoluteUrl(br.url) || !pkp.prependLinks() ? br.url : corePath+br.url, br.display, null)));
|
c.getPieces().add(checkForNoChange(binding.getValueSetElement(), gen.new Piece(br.url == null ? null : Utilities.isAbsoluteUrl(br.url) || !pkp.prependLinks() ? br.url : corePath+br.url, br.display, null)));
|
||||||
if (binding.hasStrength()) {
|
if (binding.hasStrength()) {
|
||||||
|
@ -4668,7 +4709,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
||||||
c.getPieces().add(checkForNoChange(binding.getStrengthElement(), gen.new Piece(null, ")", null)));
|
c.getPieces().add(checkForNoChange(binding.getStrengthElement(), gen.new Piece(null, ")", null)));
|
||||||
}
|
}
|
||||||
if (binding.hasExtension(ToolingExtensions.EXT_MAX_VALUESET)) {
|
if (binding.hasExtension(ToolingExtensions.EXT_MAX_VALUESET)) {
|
||||||
br = pkp.resolveBinding(profile, ToolingExtensions.readStringExtension(binding, ToolingExtensions.EXT_MAX_VALUESET), definition.getPath());
|
br = pkp == null ? makeNullBr(binding) : pkp.resolveBinding(profile, ToolingExtensions.readStringExtension(binding, ToolingExtensions.EXT_MAX_VALUESET), definition.getPath());
|
||||||
c.addPiece(gen.new Piece("br"));
|
c.addPiece(gen.new Piece("br"));
|
||||||
c.getPieces().add(checkForNoChange(binding, gen.new Piece(corePath+"extension-elementdefinition-maxvalueset.html", translate("sd.table", "Max Binding")+": ", "Max Value Set Extension").addStyle("font-weight:bold")));
|
c.getPieces().add(checkForNoChange(binding, gen.new Piece(corePath+"extension-elementdefinition-maxvalueset.html", translate("sd.table", "Max Binding")+": ", "Max Value Set Extension").addStyle("font-weight:bold")));
|
||||||
c.getPieces().add(checkForNoChange(binding, gen.new Piece(br.url == null ? null : Utilities.isAbsoluteUrl(br.url) || !pkp.prependLinks() ? br.url : corePath+br.url, br.display, null)));
|
c.getPieces().add(checkForNoChange(binding, gen.new Piece(br.url == null ? null : Utilities.isAbsoluteUrl(br.url) || !pkp.prependLinks() ? br.url : corePath+br.url, br.display, null)));
|
||||||
|
@ -4683,6 +4724,13 @@ public class ProfileUtilities extends TranslatingUtilities {
|
||||||
c.getPieces().add(gen.new Piece(null, ": ", null));
|
c.getPieces().add(gen.new Piece(null, ": ", null));
|
||||||
c.addMarkdownNoPara(PublicationHacker.fixBindingDescriptions(context, binding.getDescriptionElement()).asStringValue(), checkForNoChange(PublicationHacker.fixBindingDescriptions(context, binding.getDescriptionElement())));
|
c.addMarkdownNoPara(PublicationHacker.fixBindingDescriptions(context, binding.getDescriptionElement()).asStringValue(), checkForNoChange(PublicationHacker.fixBindingDescriptions(context, binding.getDescriptionElement())));
|
||||||
}
|
}
|
||||||
|
if (binding.hasExtension(ToolingExtensions.EXT_BINDING_ADDITIONAL)) {
|
||||||
|
c.addPiece(gen.new Piece("br"));
|
||||||
|
c.getPieces().add(checkForNoChange(binding, gen.new Piece(null, translate("sd.table", "Additional Bindings")+": ", null).addStyle("font-weight:bold")));
|
||||||
|
for (Extension ext : binding.getExtensionsByUrl(ToolingExtensions.EXT_BINDING_ADDITIONAL)) {
|
||||||
|
renderAdditionalBinding(gen, c, ext);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
for (ElementDefinitionConstraintComponent inv : definition.getConstraint()) {
|
for (ElementDefinitionConstraintComponent inv : definition.getConstraint()) {
|
||||||
if (!inv.hasSource() || profile == null || inv.getSource().equals(profile.getUrl()) || allInvariants) {
|
if (!inv.hasSource() || profile == null || inv.getSource().equals(profile.getUrl()) || allInvariants) {
|
||||||
|
@ -4704,7 +4752,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
||||||
if (definition.hasFixed()) {
|
if (definition.hasFixed()) {
|
||||||
if (!c.getPieces().isEmpty()) { c.addPiece(gen.new Piece("br")); }
|
if (!c.getPieces().isEmpty()) { c.addPiece(gen.new Piece("br")); }
|
||||||
c.getPieces().add(checkForNoChange(definition.getFixed(), gen.new Piece(null, translate("sd.table", "Fixed Value")+": ", null).addStyle("font-weight:bold")));
|
c.getPieces().add(checkForNoChange(definition.getFixed(), gen.new Piece(null, translate("sd.table", "Fixed Value")+": ", null).addStyle("font-weight:bold")));
|
||||||
if (!useTableForFixedValues || definition.getFixed().isPrimitive()) {
|
if (!useTableForFixedValues || !allowSubRows || definition.getFixed().isPrimitive()) {
|
||||||
String s = buildJson(definition.getFixed());
|
String s = buildJson(definition.getFixed());
|
||||||
String link = null;
|
String link = null;
|
||||||
if (Utilities.isAbsoluteUrl(s))
|
if (Utilities.isAbsoluteUrl(s))
|
||||||
|
@ -4722,7 +4770,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
||||||
} else if (definition.hasPattern()) {
|
} else if (definition.hasPattern()) {
|
||||||
if (!c.getPieces().isEmpty()) { c.addPiece(gen.new Piece("br")); }
|
if (!c.getPieces().isEmpty()) { c.addPiece(gen.new Piece("br")); }
|
||||||
c.getPieces().add(checkForNoChange(definition.getPattern(), gen.new Piece(null, translate("sd.table", "Required Pattern")+": ", null).addStyle("font-weight:bold")));
|
c.getPieces().add(checkForNoChange(definition.getPattern(), gen.new Piece(null, translate("sd.table", "Required Pattern")+": ", null).addStyle("font-weight:bold")));
|
||||||
if (!useTableForFixedValues || definition.getPattern().isPrimitive())
|
if (!useTableForFixedValues || !allowSubRows || definition.getPattern().isPrimitive())
|
||||||
c.getPieces().add(checkForNoChange(definition.getPattern(), gen.new Piece(null, buildJson(definition.getPattern()), null).addStyle("color: darkgreen")));
|
c.getPieces().add(checkForNoChange(definition.getPattern(), gen.new Piece(null, buildJson(definition.getPattern()), null).addStyle("color: darkgreen")));
|
||||||
else {
|
else {
|
||||||
c.getPieces().add(checkForNoChange(definition.getPattern(), gen.new Piece(null, "At least the following", null).addStyle("color: darkgreen")));
|
c.getPieces().add(checkForNoChange(definition.getPattern(), gen.new Piece(null, "At least the following", null).addStyle("color: darkgreen")));
|
||||||
|
@ -4762,6 +4810,30 @@ public class ProfileUtilities extends TranslatingUtilities {
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void renderAdditionalBinding(HierarchicalTableGenerator gen, Cell c, Extension ext) {
|
||||||
|
// <nsbp>2 <sp> purpose <sp> value-set-link ([context]) {documentation}
|
||||||
|
String purpose = ext.getExtensionString("purpose");
|
||||||
|
String valueSet = ext.getExtensionString("valueSet");
|
||||||
|
String doco = ext.getExtensionString("documentation");
|
||||||
|
//UsageContext usage = (ext.hasExtension("usage")) ? ext.getExtensionByUrl("usage").getValueUsageContext() : null;
|
||||||
|
//
|
||||||
|
// purpose: code - defines how the binding is used
|
||||||
|
// usage : UsageContext - defines the contexts in which this binding is used for it's purpose
|
||||||
|
// valueSet : canonical(ValueSet)
|
||||||
|
// documentation : markdown
|
||||||
|
// !!
|
||||||
|
// c.getPieces().add(checkForNoChange(inv, gen.new Piece(null, inv.getKey()+": ", null).addStyle("font-weight:bold")));
|
||||||
|
// c.getPieces().add(checkForNoChange(inv, gen.new Piece(null, gt(inv.getHumanElement()), null)));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private BindingResolution makeNullBr(ElementDefinitionBindingComponent binding) {
|
||||||
|
BindingResolution br = new BindingResolution();
|
||||||
|
br.url = "http://none.none/none";
|
||||||
|
br.display = "todo";
|
||||||
|
return br;
|
||||||
|
}
|
||||||
|
|
||||||
private ElementDefinitionBindingComponent makeUnifiedBinding(ElementDefinitionBindingComponent binding, ElementDefinition element) {
|
private ElementDefinitionBindingComponent makeUnifiedBinding(ElementDefinitionBindingComponent binding, ElementDefinition element) {
|
||||||
if (!element.hasUserData(DERIVATION_POINTER)) {
|
if (!element.hasUserData(DERIVATION_POINTER)) {
|
||||||
return binding;
|
return binding;
|
||||||
|
|
|
@ -6169,9 +6169,9 @@ The primary difference between a medication statement and a medication administr
|
||||||
return _4_1_0;
|
return _4_1_0;
|
||||||
if ("4.2.0".equals(codeString))
|
if ("4.2.0".equals(codeString))
|
||||||
return _4_2_0;
|
return _4_2_0;
|
||||||
if ("4.3.0-snapshot1".equals(codeString))
|
if ("4.3.0-snapshot1".equalsIgnoreCase(codeString))
|
||||||
return _4_3_0SNAPSHOT1;
|
return _4_3_0SNAPSHOT1;
|
||||||
if ("4.3.0-cibuild".equals(codeString))
|
if ("4.3.0-cibuild".equalsIgnoreCase(codeString))
|
||||||
return _4_3_0CIBUILD;
|
return _4_3_0CIBUILD;
|
||||||
throw new FHIRException("Unknown FHIRVersion code '"+codeString+"'");
|
throw new FHIRException("Unknown FHIRVersion code '"+codeString+"'");
|
||||||
}
|
}
|
||||||
|
@ -6434,9 +6434,9 @@ public String toCode(int len) {
|
||||||
return FHIRVersion._4_1_0;
|
return FHIRVersion._4_1_0;
|
||||||
if ("4.2.0".equals(codeString))
|
if ("4.2.0".equals(codeString))
|
||||||
return FHIRVersion._4_2_0;
|
return FHIRVersion._4_2_0;
|
||||||
if ("4.3.0-snapshot1".equals(codeString))
|
if ("4.3.0-snapshot1".equalsIgnoreCase(codeString))
|
||||||
return FHIRVersion._4_3_0SNAPSHOT1;
|
return FHIRVersion._4_3_0SNAPSHOT1;
|
||||||
if ("4.3.0-cibuild".equals(codeString))
|
if ("4.3.0-cibuild".equalsIgnoreCase(codeString))
|
||||||
return FHIRVersion._4_3_0CIBUILD;
|
return FHIRVersion._4_3_0CIBUILD;
|
||||||
throw new IllegalArgumentException("Unknown FHIRVersion code '"+codeString+"'");
|
throw new IllegalArgumentException("Unknown FHIRVersion code '"+codeString+"'");
|
||||||
}
|
}
|
||||||
|
@ -6498,9 +6498,9 @@ public String toCode(int len) {
|
||||||
return new Enumeration<FHIRVersion>(this, FHIRVersion._4_1_0);
|
return new Enumeration<FHIRVersion>(this, FHIRVersion._4_1_0);
|
||||||
if ("4.2.0".equals(codeString))
|
if ("4.2.0".equals(codeString))
|
||||||
return new Enumeration<FHIRVersion>(this, FHIRVersion._4_2_0);
|
return new Enumeration<FHIRVersion>(this, FHIRVersion._4_2_0);
|
||||||
if ("4.3.0-snapshot1".equals(codeString))
|
if ("4.3.0-snapshot1".equalsIgnoreCase(codeString))
|
||||||
return new Enumeration<FHIRVersion>(this, FHIRVersion._4_3_0SNAPSHOT1);
|
return new Enumeration<FHIRVersion>(this, FHIRVersion._4_3_0SNAPSHOT1);
|
||||||
if ("4.3.0-cibuild".equals(codeString))
|
if ("4.3.0-cibuild".equalsIgnoreCase(codeString))
|
||||||
return new Enumeration<FHIRVersion>(this, FHIRVersion._4_3_0CIBUILD);
|
return new Enumeration<FHIRVersion>(this, FHIRVersion._4_3_0CIBUILD);
|
||||||
throw new FHIRException("Unknown FHIRVersion code '"+codeString+"'");
|
throw new FHIRException("Unknown FHIRVersion code '"+codeString+"'");
|
||||||
}
|
}
|
||||||
|
|
|
@ -198,6 +198,9 @@ public class ToolingExtensions {
|
||||||
public static final String EXT_TARGET_ID = "http://hl7.org/fhir/StructureDefinition/targetElement";
|
public static final String EXT_TARGET_ID = "http://hl7.org/fhir/StructureDefinition/targetElement";
|
||||||
public static final String EXT_TARGET_PATH = "http://hl7.org/fhir/StructureDefinition/targetPath";
|
public static final String EXT_TARGET_PATH = "http://hl7.org/fhir/StructureDefinition/targetPath";
|
||||||
public static final String EXT_VALUESET_SYSTEM = "http://hl7.org/fhir/StructureDefinition/valueset-system";
|
public static final String EXT_VALUESET_SYSTEM = "http://hl7.org/fhir/StructureDefinition/valueset-system";
|
||||||
|
public static final String EXT_EXPAND_RULES = "http://hl7.org/fhir/StructureDefinition/valueset-expand-rules";
|
||||||
|
public static final String EXT_EXPAND_GROUP = "http://hl7.org/fhir/StructureDefinition/valueset-expand-group";
|
||||||
|
public static final String EXT_BINDING_ADDITIONAL = "http://hl7.org/fhir/tools/StructureDefinition/additional-binding";
|
||||||
|
|
||||||
// specific extension helpers
|
// specific extension helpers
|
||||||
|
|
||||||
|
@ -511,7 +514,7 @@ public class ToolingExtensions {
|
||||||
* @return The extension, if on this element, else null
|
* @return The extension, if on this element, else null
|
||||||
*/
|
*/
|
||||||
public static Extension getExtension(DomainResource resource, String name) {
|
public static Extension getExtension(DomainResource resource, String name) {
|
||||||
if (name == null)
|
if (resource == null || name == null)
|
||||||
return null;
|
return null;
|
||||||
if (!resource.hasExtension())
|
if (!resource.hasExtension())
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -50,9 +50,6 @@ public class XVerExtensionManager {
|
||||||
return XVerExtensionStatus.Invalid;
|
return XVerExtensionStatus.Invalid;
|
||||||
}
|
}
|
||||||
String v = url.substring(20, 23);
|
String v = url.substring(20, 23);
|
||||||
if ("5.0".equals(v)) {
|
|
||||||
v = "4.6"; // for now
|
|
||||||
}
|
|
||||||
String e = url.substring(54);
|
String e = url.substring(54);
|
||||||
if (!lists.containsKey(v)) {
|
if (!lists.containsKey(v)) {
|
||||||
if (context.getBinaries().containsKey("xver-paths-"+v+".json")) {
|
if (context.getBinaries().containsKey("xver-paths-"+v+".json")) {
|
||||||
|
@ -67,6 +64,9 @@ public class XVerExtensionManager {
|
||||||
}
|
}
|
||||||
JsonObject root = lists.get(v);
|
JsonObject root = lists.get(v);
|
||||||
JsonObject path = root.getAsJsonObject(e);
|
JsonObject path = root.getAsJsonObject(e);
|
||||||
|
if (path == null) {
|
||||||
|
path = root.getAsJsonObject(e+"[x]");
|
||||||
|
}
|
||||||
if (path == null) {
|
if (path == null) {
|
||||||
return XVerExtensionStatus.Unknown;
|
return XVerExtensionStatus.Unknown;
|
||||||
}
|
}
|
||||||
|
@ -83,13 +83,13 @@ public class XVerExtensionManager {
|
||||||
|
|
||||||
public StructureDefinition makeDefinition(String url) {
|
public StructureDefinition makeDefinition(String url) {
|
||||||
String verSource = url.substring(20, 23);
|
String verSource = url.substring(20, 23);
|
||||||
if ("5.0".equals(verSource)) {
|
|
||||||
verSource = "4.6"; // for now
|
|
||||||
}
|
|
||||||
String verTarget = VersionUtilities.getMajMin(context.getVersion());
|
String verTarget = VersionUtilities.getMajMin(context.getVersion());
|
||||||
String e = url.substring(54);
|
String e = url.substring(54);
|
||||||
JsonObject root = lists.get(verSource);
|
JsonObject root = lists.get(verSource);
|
||||||
JsonObject path = root.getAsJsonObject(e);
|
JsonObject path = root.getAsJsonObject(e);
|
||||||
|
if (path == null) {
|
||||||
|
path = root.getAsJsonObject(e+"[x]");
|
||||||
|
}
|
||||||
|
|
||||||
StructureDefinition sd = new StructureDefinition();
|
StructureDefinition sd = new StructureDefinition();
|
||||||
sd.setUserData(XVER_EXT_MARKER, "true");
|
sd.setUserData(XVER_EXT_MARKER, "true");
|
||||||
|
@ -117,16 +117,18 @@ public class XVerExtensionManager {
|
||||||
populateTypes(path, val, verSource, verTarget);
|
populateTypes(path, val, verSource, verTarget);
|
||||||
} else if (path.has("elements")) {
|
} else if (path.has("elements")) {
|
||||||
for (JsonElement i : path.getAsJsonArray("elements")) {
|
for (JsonElement i : path.getAsJsonArray("elements")) {
|
||||||
String s = i.getAsString();
|
JsonObject elt = root.getAsJsonObject(e+"."+i.getAsString());
|
||||||
|
if (elt != null) {
|
||||||
|
String s = i.getAsString().replace("[x]", "");
|
||||||
sd.getDifferential().addElement().setPath("Extension.extension").setSliceName(s);
|
sd.getDifferential().addElement().setPath("Extension.extension").setSliceName(s);
|
||||||
sd.getDifferential().addElement().setPath("Extension.extension.extension").setMax("0");
|
sd.getDifferential().addElement().setPath("Extension.extension.extension").setMax("0");
|
||||||
sd.getDifferential().addElement().setPath("Extension.extension.url").setFixed(new UriType(s));
|
sd.getDifferential().addElement().setPath("Extension.extension.url").setFixed(new UriType(s));
|
||||||
ElementDefinition val = sd.getDifferential().addElement().setPath("Extension.extension.value[x]").setMin(1);
|
ElementDefinition val = sd.getDifferential().addElement().setPath("Extension.extension.value[x]").setMin(1);
|
||||||
JsonObject elt = root.getAsJsonObject(e+"."+s);
|
|
||||||
if (!elt.has("types")) {
|
if (!elt.has("types")) {
|
||||||
throw new FHIRException("Internal error - nested elements not supported yet");
|
throw new FHIRException("Internal error - nested elements not supported yet");
|
||||||
}
|
}
|
||||||
populateTypes(elt, val, verSource, verTarget);
|
populateTypes(elt, val, verSource, verTarget);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
sd.getDifferential().addElement().setPath("Extension.url").setFixed(new UriType(url));
|
sd.getDifferential().addElement().setPath("Extension.url").setFixed(new UriType(url));
|
||||||
sd.getDifferential().addElement().setPath("Extension.value[x]").setMax("0");
|
sd.getDifferential().addElement().setPath("Extension.value[x]").setMax("0");
|
||||||
|
|
|
@ -4,6 +4,7 @@ import org.hl7.fhir.exceptions.FHIRException;
|
||||||
import org.hl7.fhir.r4b.conformance.ProfileUtilities;
|
import org.hl7.fhir.r4b.conformance.ProfileUtilities;
|
||||||
import org.hl7.fhir.r4b.model.Base;
|
import org.hl7.fhir.r4b.model.Base;
|
||||||
import org.hl7.fhir.r4b.model.ElementDefinition;
|
import org.hl7.fhir.r4b.model.ElementDefinition;
|
||||||
|
import org.hl7.fhir.r4b.model.ElementDefinition.ElementDefinitionConstraintComponent;
|
||||||
import org.hl7.fhir.r4b.model.IntegerType;
|
import org.hl7.fhir.r4b.model.IntegerType;
|
||||||
import org.hl7.fhir.r4b.model.StructureDefinition;
|
import org.hl7.fhir.r4b.model.StructureDefinition;
|
||||||
import org.hl7.fhir.r4b.model.StructureDefinition.TypeDerivationRule;
|
import org.hl7.fhir.r4b.model.StructureDefinition.TypeDerivationRule;
|
||||||
|
@ -51,6 +52,12 @@ public class ProfileUtilitiesTests {
|
||||||
f.setBase(null);
|
f.setBase(null);
|
||||||
b.setRequirements(null);
|
b.setRequirements(null);
|
||||||
f.setRequirements(null);
|
f.setRequirements(null);
|
||||||
|
for (ElementDefinitionConstraintComponent c : b.getConstraint()) {
|
||||||
|
c.setSource(null);
|
||||||
|
}
|
||||||
|
for (ElementDefinitionConstraintComponent c : f.getConstraint()) {
|
||||||
|
c.setSource(null);
|
||||||
|
}
|
||||||
ok = Base.compareDeep(b, f, true);
|
ok = Base.compareDeep(b, f, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -83,6 +90,12 @@ public class ProfileUtilitiesTests {
|
||||||
if (ok) {
|
if (ok) {
|
||||||
ElementDefinition b = base.getSnapshot().getElement().get(i);
|
ElementDefinition b = base.getSnapshot().getElement().get(i);
|
||||||
ElementDefinition f = focus.getSnapshot().getElement().get(i);
|
ElementDefinition f = focus.getSnapshot().getElement().get(i);
|
||||||
|
for (ElementDefinitionConstraintComponent c : b.getConstraint()) {
|
||||||
|
c.setSource(null);
|
||||||
|
}
|
||||||
|
for (ElementDefinitionConstraintComponent c : f.getConstraint()) {
|
||||||
|
c.setSource(null);
|
||||||
|
}
|
||||||
if (!f.hasBase() || !b.getPath().equals(f.getPath()))
|
if (!f.hasBase() || !b.getPath().equals(f.getPath()))
|
||||||
ok = false;
|
ok = false;
|
||||||
else {
|
else {
|
||||||
|
@ -128,6 +141,12 @@ public class ProfileUtilitiesTests {
|
||||||
ElementDefinition f = focus.getSnapshot().getElement().get(i);
|
ElementDefinition f = focus.getSnapshot().getElement().get(i);
|
||||||
b.setRequirements(null);
|
b.setRequirements(null);
|
||||||
f.setRequirements(null);
|
f.setRequirements(null);
|
||||||
|
for (ElementDefinitionConstraintComponent c : b.getConstraint()) {
|
||||||
|
c.setSource(null);
|
||||||
|
}
|
||||||
|
for (ElementDefinitionConstraintComponent c : f.getConstraint()) {
|
||||||
|
c.setSource(null);
|
||||||
|
}
|
||||||
if (!f.hasBase() || !b.getPath().equals(f.getPath())) {
|
if (!f.hasBase() || !b.getPath().equals(f.getPath())) {
|
||||||
ok = false;
|
ok = false;
|
||||||
}
|
}
|
||||||
|
@ -174,6 +193,12 @@ public class ProfileUtilitiesTests {
|
||||||
ElementDefinition f = focus.getSnapshot().getElement().get(i);
|
ElementDefinition f = focus.getSnapshot().getElement().get(i);
|
||||||
b.setRequirements(null);
|
b.setRequirements(null);
|
||||||
f.setRequirements(null);
|
f.setRequirements(null);
|
||||||
|
for (ElementDefinitionConstraintComponent c : b.getConstraint()) {
|
||||||
|
c.setSource(null);
|
||||||
|
}
|
||||||
|
for (ElementDefinitionConstraintComponent c : f.getConstraint()) {
|
||||||
|
c.setSource(null);
|
||||||
|
}
|
||||||
if (!f.hasBase() || !b.getPath().equals(f.getPath())) {
|
if (!f.hasBase() || !b.getPath().equals(f.getPath())) {
|
||||||
ok = false;
|
ok = false;
|
||||||
}
|
}
|
||||||
|
@ -221,6 +246,12 @@ public class ProfileUtilitiesTests {
|
||||||
ElementDefinition f = focus.getSnapshot().getElement().get(i);
|
ElementDefinition f = focus.getSnapshot().getElement().get(i);
|
||||||
b.setRequirements(null);
|
b.setRequirements(null);
|
||||||
f.setRequirements(null);
|
f.setRequirements(null);
|
||||||
|
for (ElementDefinitionConstraintComponent c : b.getConstraint()) {
|
||||||
|
c.setSource(null);
|
||||||
|
}
|
||||||
|
for (ElementDefinitionConstraintComponent c : f.getConstraint()) {
|
||||||
|
c.setSource(null);
|
||||||
|
}
|
||||||
if (!f.hasBase() || !b.getPath().equals(f.getPath())) {
|
if (!f.hasBase() || !b.getPath().equals(f.getPath())) {
|
||||||
ok = false;
|
ok = false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,6 +49,7 @@ import org.hl7.fhir.utilities.npm.ToolsVersion;
|
||||||
import org.hl7.fhir.utilities.validation.ValidationMessage;
|
import org.hl7.fhir.utilities.validation.ValidationMessage;
|
||||||
import org.hl7.fhir.utilities.validation.ValidationMessage.IssueSeverity;
|
import org.hl7.fhir.utilities.validation.ValidationMessage.IssueSeverity;
|
||||||
import org.hl7.fhir.utilities.xml.XMLUtil;
|
import org.hl7.fhir.utilities.xml.XMLUtil;
|
||||||
|
import org.junit.Assert;
|
||||||
import org.junit.jupiter.api.Assertions;
|
import org.junit.jupiter.api.Assertions;
|
||||||
import org.junit.jupiter.api.BeforeAll;
|
import org.junit.jupiter.api.BeforeAll;
|
||||||
import org.junit.jupiter.params.ParameterizedTest;
|
import org.junit.jupiter.params.ParameterizedTest;
|
||||||
|
@ -137,6 +138,7 @@ public class SnapShotGenerationTests {
|
||||||
private boolean fail;
|
private boolean fail;
|
||||||
private boolean newSliceProcessing;
|
private boolean newSliceProcessing;
|
||||||
private boolean debug;
|
private boolean debug;
|
||||||
|
private boolean noR4b;
|
||||||
|
|
||||||
private List<Rule> rules = new ArrayList<>();
|
private List<Rule> rules = new ArrayList<>();
|
||||||
private StructureDefinition source;
|
private StructureDefinition source;
|
||||||
|
@ -161,6 +163,7 @@ public class SnapShotGenerationTests {
|
||||||
rules.add(new Rule(rule));
|
rules.add(new Rule(rule));
|
||||||
rule = XMLUtil.getNextSibling(rule);
|
rule = XMLUtil.getNextSibling(rule);
|
||||||
}
|
}
|
||||||
|
noR4b = test.hasAttribute("r4b") && "false".equals(test.getAttribute("r4b"));
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getId() {
|
public String getId() {
|
||||||
|
@ -466,33 +469,37 @@ public class SnapShotGenerationTests {
|
||||||
fp.setHostServices(context);
|
fp.setHostServices(context);
|
||||||
messages = new ArrayList<ValidationMessage>();
|
messages = new ArrayList<ValidationMessage>();
|
||||||
|
|
||||||
System.out.println("---- "+id+" -----------------------------------------");
|
if (test.noR4b) {
|
||||||
if (test.isFail()) {
|
Assert.assertTrue(true);
|
||||||
boolean failed = true;
|
} else {
|
||||||
try {
|
System.out.println("---- "+id+" -----------------------------------------");
|
||||||
if (test.isGen())
|
if (test.isFail()) {
|
||||||
testGen(true, test, context);
|
boolean failed = true;
|
||||||
else
|
try {
|
||||||
testSort(test, context);
|
if (test.isGen())
|
||||||
failed = false;
|
testGen(true, test, context);
|
||||||
} catch (Throwable e) {
|
else
|
||||||
System.out.println("Error running test: " + e.getMessage());
|
testSort(test, context);
|
||||||
if (!Utilities.noString(test.regex)) {
|
failed = false;
|
||||||
Assertions.assertTrue(e.getMessage().matches(test.regex), "correct error message");
|
} catch (Throwable e) {
|
||||||
} else if ("Should have failed".equals(e.getMessage())) {
|
System.out.println("Error running test: " + e.getMessage());
|
||||||
throw e;
|
if (!Utilities.noString(test.regex)) {
|
||||||
} else {
|
Assertions.assertTrue(e.getMessage().matches(test.regex), "correct error message");
|
||||||
|
} else if ("Should have failed".equals(e.getMessage())) {
|
||||||
|
throw e;
|
||||||
|
} else {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Assertions.assertTrue(failed, "Should have failed");
|
||||||
|
} else if (test.isGen())
|
||||||
|
testGen(false, test, context);
|
||||||
|
else
|
||||||
|
testSort(test, context);
|
||||||
|
for (Rule r : test.getRules()) {
|
||||||
|
StructureDefinition sdn = new StructureDefinition();
|
||||||
|
boolean ok = fp.evaluateToBoolean(sdn, sdn, sdn, r.expression);
|
||||||
|
Assertions.assertTrue(ok, r.description);
|
||||||
}
|
}
|
||||||
Assertions.assertTrue(failed, "Should have failed");
|
|
||||||
} else if (test.isGen())
|
|
||||||
testGen(false, test, context);
|
|
||||||
else
|
|
||||||
testSort(test, context);
|
|
||||||
for (Rule r : test.getRules()) {
|
|
||||||
StructureDefinition sdn = new StructureDefinition();
|
|
||||||
boolean ok = fp.evaluateToBoolean(sdn, sdn, sdn, r.expression);
|
|
||||||
Assertions.assertTrue(ok, r.description);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>org.hl7.fhir.core</artifactId>
|
<artifactId>org.hl7.fhir.core</artifactId>
|
||||||
<version>5.6.35</version>
|
<version>5.6.38-SNAPSHOT</version>
|
||||||
<relativePath>../pom.xml</relativePath>
|
<relativePath>../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -627,174 +627,178 @@ public class ProfileUtilities extends TranslatingUtilities {
|
||||||
}
|
}
|
||||||
derived.setUserData("profileutils.snapshot.generating", true);
|
derived.setUserData("profileutils.snapshot.generating", true);
|
||||||
snapshotStack.add(derived.getUrl());
|
snapshotStack.add(derived.getUrl());
|
||||||
|
|
||||||
if (!Utilities.noString(webUrl) && !webUrl.endsWith("/"))
|
|
||||||
webUrl = webUrl + '/';
|
|
||||||
|
|
||||||
if (defWebRoot == null)
|
|
||||||
defWebRoot = webUrl;
|
|
||||||
derived.setSnapshot(new StructureDefinitionSnapshotComponent());
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
checkDifferential(derived.getDifferential().getElement(), typeName(derived.getType()), derived.getUrl());
|
|
||||||
checkDifferentialBaseType(derived);
|
|
||||||
|
|
||||||
// so we have two lists - the base list, and the differential list
|
if (!Utilities.noString(webUrl) && !webUrl.endsWith("/"))
|
||||||
// the differential list is only allowed to include things that are in the base list, but
|
webUrl = webUrl + '/';
|
||||||
// is allowed to include them multiple times - thereby slicing them
|
|
||||||
|
|
||||||
// our approach is to walk through the base list, and see whether the differential
|
if (defWebRoot == null)
|
||||||
// says anything about them.
|
defWebRoot = webUrl;
|
||||||
int baseCursor = 0;
|
derived.setSnapshot(new StructureDefinitionSnapshotComponent());
|
||||||
int diffCursor = 0; // we need a diff cursor because we can only look ahead, in the bound scoped by longer paths
|
|
||||||
|
try {
|
||||||
|
checkDifferential(derived.getDifferential().getElement(), typeName(derived.getType()), derived.getUrl());
|
||||||
|
checkDifferentialBaseType(derived);
|
||||||
|
|
||||||
|
// so we have two lists - the base list, and the differential list
|
||||||
|
// the differential list is only allowed to include things that are in the base list, but
|
||||||
|
// is allowed to include them multiple times - thereby slicing them
|
||||||
|
|
||||||
|
// our approach is to walk through the base list, and see whether the differential
|
||||||
|
// says anything about them.
|
||||||
|
int baseCursor = 0;
|
||||||
|
int diffCursor = 0; // we need a diff cursor because we can only look ahead, in the bound scoped by longer paths
|
||||||
|
|
||||||
|
|
||||||
for (ElementDefinition e : derived.getDifferential().getElement())
|
for (ElementDefinition e : derived.getDifferential().getElement())
|
||||||
e.clearUserData(GENERATED_IN_SNAPSHOT);
|
e.clearUserData(GENERATED_IN_SNAPSHOT);
|
||||||
|
|
||||||
// we actually delegate the work to a subroutine so we can re-enter it with a different cursors
|
// we actually delegate the work to a subroutine so we can re-enter it with a different cursors
|
||||||
StructureDefinitionDifferentialComponent diff = cloneDiff(derived.getDifferential()); // we make a copy here because we're sometimes going to hack the differential while processing it. Have to migrate user data back afterwards
|
StructureDefinitionDifferentialComponent diff = cloneDiff(derived.getDifferential()); // we make a copy here because we're sometimes going to hack the differential while processing it. Have to migrate user data back afterwards
|
||||||
StructureDefinitionSnapshotComponent baseSnapshot = base.getSnapshot();
|
StructureDefinitionSnapshotComponent baseSnapshot = base.getSnapshot();
|
||||||
if (derived.getDerivation() == TypeDerivationRule.SPECIALIZATION) {
|
if (derived.getDerivation() == TypeDerivationRule.SPECIALIZATION) {
|
||||||
String derivedType = derived.getType();
|
String derivedType = derived.getType();
|
||||||
if (StructureDefinitionKind.LOGICAL.equals(derived.getKind()) && derived.getType().contains("/")) {
|
if (StructureDefinitionKind.LOGICAL.equals(derived.getKind()) && derived.getType().contains("/")) {
|
||||||
derivedType = derivedType.substring(derivedType.lastIndexOf("/")+1);
|
derivedType = derivedType.substring(derivedType.lastIndexOf("/")+1);
|
||||||
|
}
|
||||||
|
baseSnapshot = cloneSnapshot(baseSnapshot, base.getType(), derivedType);
|
||||||
}
|
}
|
||||||
baseSnapshot = cloneSnapshot(baseSnapshot, base.getType(), derivedType);
|
// if (derived.getId().equals("2.16.840.1.113883.10.20.22.2.1.1")) {
|
||||||
}
|
// debug = true;
|
||||||
// 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);
|
||||||
processPaths("", derived.getSnapshot(), baseSnapshot, diff, baseCursor, diffCursor, baseSnapshot.getElement().size()-1,
|
checkGroupConstraints(derived);
|
||||||
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);
|
if (derived.getDerivation() == TypeDerivationRule.SPECIALIZATION) {
|
||||||
checkGroupConstraints(derived);
|
for (ElementDefinition e : diff.getElement()) {
|
||||||
if (derived.getDerivation() == TypeDerivationRule.SPECIALIZATION) {
|
if (!e.hasUserData(GENERATED_IN_SNAPSHOT)) {
|
||||||
for (ElementDefinition e : diff.getElement()) {
|
ElementDefinition outcome = updateURLs(url, webUrl, e.copy());
|
||||||
if (!e.hasUserData(GENERATED_IN_SNAPSHOT)) {
|
e.setUserData(GENERATED_IN_SNAPSHOT, outcome);
|
||||||
ElementDefinition outcome = updateURLs(url, webUrl, e.copy());
|
derived.getSnapshot().addElement(outcome);
|
||||||
e.setUserData(GENERATED_IN_SNAPSHOT, outcome);
|
}
|
||||||
derived.getSnapshot().addElement(outcome);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (derived.getKind() != StructureDefinitionKind.LOGICAL && !derived.getSnapshot().getElementFirstRep().getType().isEmpty())
|
if (derived.getKind() != StructureDefinitionKind.LOGICAL && !derived.getSnapshot().getElementFirstRep().getType().isEmpty())
|
||||||
throw new Error(context.formatMessage(I18nConstants.TYPE_ON_FIRST_SNAPSHOT_ELEMENT_FOR__IN__FROM_, derived.getSnapshot().getElementFirstRep().getPath(), derived.getUrl(), base.getUrl()));
|
throw new Error(context.formatMessage(I18nConstants.TYPE_ON_FIRST_SNAPSHOT_ELEMENT_FOR__IN__FROM_, derived.getSnapshot().getElementFirstRep().getPath(), derived.getUrl(), base.getUrl()));
|
||||||
updateMaps(base, derived);
|
updateMaps(base, derived);
|
||||||
|
|
||||||
setIds(derived, false);
|
setIds(derived, false);
|
||||||
if (debug) {
|
if (debug) {
|
||||||
System.out.println("Differential: ");
|
|
||||||
for (ElementDefinition ed : derived.getDifferential().getElement())
|
|
||||||
System.out.println(" "+ed.getId()+" : "+typeSummaryWithProfile(ed)+"["+ed.getMin()+".."+ed.getMax()+"]"+sliceSummary(ed)+" "+constraintSummary(ed));
|
|
||||||
System.out.println("Snapshot: ");
|
|
||||||
for (ElementDefinition ed : derived.getSnapshot().getElement())
|
|
||||||
System.out.println(" "+ed.getId()+" : "+typeSummaryWithProfile(ed)+"["+ed.getMin()+".."+ed.getMax()+"]"+sliceSummary(ed)+" "+constraintSummary(ed));
|
|
||||||
}
|
|
||||||
CommaSeparatedStringBuilder b = new CommaSeparatedStringBuilder();
|
|
||||||
//Check that all differential elements have a corresponding snapshot element
|
|
||||||
int ce = 0;
|
|
||||||
for (ElementDefinition e : diff.getElement()) {
|
|
||||||
if (!e.hasUserData("diff-source"))
|
|
||||||
throw new Error(context.formatMessage(I18nConstants.UNXPECTED_INTERNAL_CONDITION__NO_SOURCE_ON_DIFF_ELEMENT));
|
|
||||||
else {
|
|
||||||
if (e.hasUserData(DERIVATION_EQUALS))
|
|
||||||
((Base) e.getUserData("diff-source")).setUserData(DERIVATION_EQUALS, e.getUserData(DERIVATION_EQUALS));
|
|
||||||
if (e.hasUserData(DERIVATION_POINTER))
|
|
||||||
((Base) e.getUserData("diff-source")).setUserData(DERIVATION_POINTER, e.getUserData(DERIVATION_POINTER));
|
|
||||||
}
|
|
||||||
if (!e.hasUserData(GENERATED_IN_SNAPSHOT)) {
|
|
||||||
b.append(e.hasId() ? "id: "+e.getId() : "path: "+e.getPath());
|
|
||||||
ce++;
|
|
||||||
if (e.hasId()) {
|
|
||||||
String msg = "No match found in the generated snapshot: check that the path and definitions are legal in the differential (including order)";
|
|
||||||
messages.add(new ValidationMessage(Source.ProfileValidator, ValidationMessage.IssueType.VALUE, url+"#"+e.getId(), msg, ValidationMessage.IssueSeverity.ERROR));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!Utilities.noString(b.toString())) {
|
|
||||||
String msg = "The profile "+derived.getUrl()+" has "+ce+" "+Utilities.pluralize("element", ce)+" in the differential ("+b.toString()+") that don't have a matching element in the snapshot: check that the path and definitions are legal in the differential (including order)";
|
|
||||||
System.out.println("Error in snapshot generation: "+msg);
|
|
||||||
if (!debug) {
|
|
||||||
System.out.println("Differential: ");
|
System.out.println("Differential: ");
|
||||||
for (ElementDefinition ed : derived.getDifferential().getElement())
|
for (ElementDefinition ed : derived.getDifferential().getElement())
|
||||||
System.out.println(" "+ed.getId()+" = "+ed.getPath()+" : "+typeSummaryWithProfile(ed)+"["+ed.getMin()+".."+ed.getMax()+"]"+sliceSummary(ed)+" "+constraintSummary(ed));
|
System.out.println(" "+ed.getId()+" : "+typeSummaryWithProfile(ed)+"["+ed.getMin()+".."+ed.getMax()+"]"+sliceSummary(ed)+" "+constraintSummary(ed));
|
||||||
System.out.println("Snapshot: ");
|
System.out.println("Snapshot: ");
|
||||||
for (ElementDefinition ed : derived.getSnapshot().getElement())
|
for (ElementDefinition ed : derived.getSnapshot().getElement())
|
||||||
System.out.println(" "+ed.getId()+" = "+ed.getPath()+" : "+typeSummaryWithProfile(ed)+"["+ed.getMin()+".."+ed.getMax()+"]"+sliceSummary(ed)+" "+constraintSummary(ed));
|
System.out.println(" "+ed.getId()+" : "+typeSummaryWithProfile(ed)+"["+ed.getMin()+".."+ed.getMax()+"]"+sliceSummary(ed)+" "+constraintSummary(ed));
|
||||||
}
|
}
|
||||||
if (exception)
|
CommaSeparatedStringBuilder b = new CommaSeparatedStringBuilder();
|
||||||
throw new DefinitionException(msg);
|
//Check that all differential elements have a corresponding snapshot element
|
||||||
else
|
int ce = 0;
|
||||||
messages.add(new ValidationMessage(Source.ProfileValidator, ValidationMessage.IssueType.VALUE, url, msg, ValidationMessage.IssueSeverity.ERROR));
|
for (ElementDefinition e : diff.getElement()) {
|
||||||
}
|
if (!e.hasUserData("diff-source"))
|
||||||
// hack around a problem in R4 definitions (somewhere?)
|
throw new Error(context.formatMessage(I18nConstants.UNXPECTED_INTERNAL_CONDITION__NO_SOURCE_ON_DIFF_ELEMENT));
|
||||||
for (ElementDefinition ed : derived.getSnapshot().getElement()) {
|
else {
|
||||||
for (ElementDefinitionMappingComponent mm : ed.getMapping()) {
|
if (e.hasUserData(DERIVATION_EQUALS))
|
||||||
if (mm.hasMap()) {
|
((Base) e.getUserData("diff-source")).setUserData(DERIVATION_EQUALS, e.getUserData(DERIVATION_EQUALS));
|
||||||
mm.setMap(mm.getMap().trim());
|
if (e.hasUserData(DERIVATION_POINTER))
|
||||||
|
((Base) e.getUserData("diff-source")).setUserData(DERIVATION_POINTER, e.getUserData(DERIVATION_POINTER));
|
||||||
}
|
}
|
||||||
}
|
if (!e.hasUserData(GENERATED_IN_SNAPSHOT)) {
|
||||||
for (ElementDefinitionConstraintComponent s : ed.getConstraint()) {
|
b.append(e.hasId() ? "id: "+e.getId() : "path: "+e.getPath());
|
||||||
if (s.hasSource()) {
|
ce++;
|
||||||
String ref = s.getSource();
|
if (e.hasId()) {
|
||||||
if (!Utilities.isAbsoluteUrl(ref)) {
|
String msg = "No match found in the generated snapshot: check that the path and definitions are legal in the differential (including order)";
|
||||||
if (ref.contains(".")) {
|
messages.add(new ValidationMessage(Source.ProfileValidator, ValidationMessage.IssueType.VALUE, url+"#"+e.getId(), msg, ValidationMessage.IssueSeverity.ERROR));
|
||||||
s.setSource("http://hl7.org/fhir/StructureDefinition/"+ref.substring(0, ref.indexOf("."))+"#"+ref);
|
|
||||||
} else {
|
|
||||||
s.setSource("http://hl7.org/fhir/StructureDefinition/"+ref);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
if (!Utilities.noString(b.toString())) {
|
||||||
if (derived.getDerivation() == TypeDerivationRule.SPECIALIZATION) {
|
String msg = "The profile "+derived.getUrl()+" has "+ce+" "+Utilities.pluralize("element", ce)+" in the differential ("+b.toString()+") that don't have a matching element in the snapshot: check that the path and definitions are legal in the differential (including order)";
|
||||||
|
System.out.println("Error in snapshot generation: "+msg);
|
||||||
|
if (!debug) {
|
||||||
|
System.out.println("Differential: ");
|
||||||
|
for (ElementDefinition ed : derived.getDifferential().getElement())
|
||||||
|
System.out.println(" "+ed.getId()+" = "+ed.getPath()+" : "+typeSummaryWithProfile(ed)+"["+ed.getMin()+".."+ed.getMax()+"]"+sliceSummary(ed)+" "+constraintSummary(ed));
|
||||||
|
System.out.println("Snapshot: ");
|
||||||
|
for (ElementDefinition ed : derived.getSnapshot().getElement())
|
||||||
|
System.out.println(" "+ed.getId()+" = "+ed.getPath()+" : "+typeSummaryWithProfile(ed)+"["+ed.getMin()+".."+ed.getMax()+"]"+sliceSummary(ed)+" "+constraintSummary(ed));
|
||||||
|
}
|
||||||
|
if (exception)
|
||||||
|
throw new DefinitionException(msg);
|
||||||
|
else
|
||||||
|
messages.add(new ValidationMessage(Source.ProfileValidator, ValidationMessage.IssueType.VALUE, url, msg, ValidationMessage.IssueSeverity.ERROR));
|
||||||
|
}
|
||||||
|
// hack around a problem in R4 definitions (somewhere?)
|
||||||
for (ElementDefinition ed : derived.getSnapshot().getElement()) {
|
for (ElementDefinition ed : derived.getSnapshot().getElement()) {
|
||||||
if (!ed.hasBase()) {
|
for (ElementDefinitionMappingComponent mm : ed.getMapping()) {
|
||||||
ed.getBase().setPath(ed.getPath()).setMin(ed.getMin()).setMax(ed.getMax());
|
if (mm.hasMap()) {
|
||||||
}
|
mm.setMap(mm.getMap().trim());
|
||||||
}
|
|
||||||
}
|
|
||||||
// last, check for wrong profiles or target profiles
|
|
||||||
for (ElementDefinition ed : derived.getSnapshot().getElement()) {
|
|
||||||
for (TypeRefComponent t : ed.getType()) {
|
|
||||||
for (UriType u : t.getProfile()) {
|
|
||||||
StructureDefinition sd = context.fetchResource(StructureDefinition.class, u.getValue());
|
|
||||||
if (sd == null) {
|
|
||||||
if (xver != null && xver.matchingUrl(u.getValue()) && xver.status(u.getValue()) == XVerExtensionStatus.Valid) {
|
|
||||||
sd = xver.makeDefinition(u.getValue());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (sd == null) {
|
}
|
||||||
if (messages != null) {
|
for (ElementDefinitionConstraintComponent s : ed.getConstraint()) {
|
||||||
messages.add(new ValidationMessage(Source.ProfileValidator, ValidationMessage.IssueType.VALUE, url+"#"+ed.getId(), "The type of profile "+u.getValue()+" cannot be checked as the profile is not known", IssueSeverity.WARNING));
|
if (s.hasSource()) {
|
||||||
}
|
String ref = s.getSource();
|
||||||
} else {
|
if (!Utilities.isAbsoluteUrl(ref)) {
|
||||||
String wt = t.getWorkingCode();
|
if (ref.contains(".")) {
|
||||||
if (ed.getPath().equals("Bundle.entry.response.outcome")) {
|
s.setSource("http://hl7.org/fhir/StructureDefinition/"+ref.substring(0, ref.indexOf("."))+"#"+ref);
|
||||||
wt = "OperationOutcome";
|
} else {
|
||||||
}
|
s.setSource("http://hl7.org/fhir/StructureDefinition/"+ref);
|
||||||
if (!sd.getType().equals(wt)) {
|
|
||||||
boolean ok = isCompatibleType(wt, sd);
|
|
||||||
if (!ok) {
|
|
||||||
String smsg = "The profile "+u.getValue()+" has type "+sd.getType()+" which is not consistent with the stated type "+wt;
|
|
||||||
if (exception)
|
|
||||||
throw new DefinitionException(smsg);
|
|
||||||
else
|
|
||||||
messages.add(new ValidationMessage(Source.ProfileValidator, ValidationMessage.IssueType.VALUE, url+"#"+ed.getId(), smsg, IssueSeverity.ERROR));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (derived.getDerivation() == TypeDerivationRule.SPECIALIZATION) {
|
||||||
|
for (ElementDefinition ed : derived.getSnapshot().getElement()) {
|
||||||
|
if (!ed.hasBase()) {
|
||||||
|
ed.getBase().setPath(ed.getPath()).setMin(ed.getMin()).setMax(ed.getMax());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// last, check for wrong profiles or target profiles
|
||||||
|
for (ElementDefinition ed : derived.getSnapshot().getElement()) {
|
||||||
|
for (TypeRefComponent t : ed.getType()) {
|
||||||
|
for (UriType u : t.getProfile()) {
|
||||||
|
StructureDefinition sd = context.fetchResource(StructureDefinition.class, u.getValue());
|
||||||
|
if (sd == null) {
|
||||||
|
if (xver != null && xver.matchingUrl(u.getValue()) && xver.status(u.getValue()) == XVerExtensionStatus.Valid) {
|
||||||
|
sd = xver.makeDefinition(u.getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (sd == null) {
|
||||||
|
if (messages != null) {
|
||||||
|
messages.add(new ValidationMessage(Source.ProfileValidator, ValidationMessage.IssueType.VALUE, url+"#"+ed.getId(), "The type of profile "+u.getValue()+" cannot be checked as the profile is not known", IssueSeverity.WARNING));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
String wt = t.getWorkingCode();
|
||||||
|
if (ed.getPath().equals("Bundle.entry.response.outcome")) {
|
||||||
|
wt = "OperationOutcome";
|
||||||
|
}
|
||||||
|
if (!sd.getType().equals(wt)) {
|
||||||
|
boolean ok = isCompatibleType(wt, sd);
|
||||||
|
if (!ok) {
|
||||||
|
String smsg = "The profile "+u.getValue()+" has type "+sd.getType()+" which is not consistent with the stated type "+wt;
|
||||||
|
if (exception)
|
||||||
|
throw new DefinitionException(smsg);
|
||||||
|
else
|
||||||
|
messages.add(new ValidationMessage(Source.ProfileValidator, ValidationMessage.IssueType.VALUE, url+"#"+ed.getId(), smsg, IssueSeverity.ERROR));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
// if we had an exception generating the snapshot, make sure we don't leave any half generated snapshot behind
|
||||||
|
derived.setSnapshot(null);
|
||||||
|
derived.clearUserData("profileutils.snapshot.generating");
|
||||||
|
throw e;
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} finally {
|
||||||
// if we had an exception generating the snapshot, make sure we don't leave any half generated snapshot behind
|
|
||||||
derived.setSnapshot(null);
|
|
||||||
derived.clearUserData("profileutils.snapshot.generating");
|
derived.clearUserData("profileutils.snapshot.generating");
|
||||||
throw e;
|
snapshotStack.remove(derived.getUrl());
|
||||||
}
|
}
|
||||||
derived.clearUserData("profileutils.snapshot.generating");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void checkDifferentialBaseType(StructureDefinition derived) throws Error {
|
public void checkDifferentialBaseType(StructureDefinition derived) throws Error {
|
||||||
|
@ -1091,6 +1095,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
||||||
ElementDefinition outcome = updateURLs(url, webUrl, currentBase.copy());
|
ElementDefinition outcome = updateURLs(url, webUrl, currentBase.copy());
|
||||||
outcome.setPath(fixedPathDest(contextPathDst, outcome.getPath(), redirector, contextPathSrc));
|
outcome.setPath(fixedPathDest(contextPathDst, outcome.getPath(), redirector, contextPathSrc));
|
||||||
updateFromBase(outcome, currentBase);
|
updateFromBase(outcome, currentBase);
|
||||||
|
updateConstraintSources(outcome, srcSD.getUrl());
|
||||||
markDerived(outcome);
|
markDerived(outcome);
|
||||||
if (resultPathBase == null)
|
if (resultPathBase == null)
|
||||||
resultPathBase = outcome.getPath();
|
resultPathBase = outcome.getPath();
|
||||||
|
@ -1146,7 +1151,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
||||||
processPaths(indent+" ", result, base, differential, nbc, start, nbl-1, diffCursor-1, url, webUrl, profileName, tgt.getElement().getPath(), outcome.getPath(), trimDifferential, contextName, resultPathBase, false, null, null, redirectorStack(redirector, outcome, cpath), srcSD);
|
processPaths(indent+" ", result, base, differential, nbc, start, nbl-1, diffCursor-1, url, webUrl, profileName, tgt.getElement().getPath(), outcome.getPath(), trimDifferential, contextName, resultPathBase, false, null, null, redirectorStack(redirector, outcome, cpath), srcSD);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
StructureDefinition dt = outcome.getType().size() > 1 ? context.fetchTypeDefinition("Element") : getProfileForDataType(outcome.getType().get(0));
|
StructureDefinition dt = outcome.getType().size() > 1 ? context.fetchTypeDefinition("Element") : getProfileForDataType(outcome.getType().get(0), webUrl);
|
||||||
if (dt == null) {
|
if (dt == null) {
|
||||||
throw new DefinitionException(context.formatMessage(I18nConstants.UNKNOWN_TYPE__AT_, outcome.getType().get(0), cpath));
|
throw new DefinitionException(context.formatMessage(I18nConstants.UNKNOWN_TYPE__AT_, outcome.getType().get(0), cpath));
|
||||||
}
|
}
|
||||||
|
@ -1299,7 +1304,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
||||||
processPaths(indent+" ", result, base, differential, nbc, start - 1, nbl-1, diffCursor - 1, url, webUrl, profileName, tgt.getElement().getPath(), diffMatches.get(0).getPath(), trimDifferential, contextName, resultPathBase, false, null, null, redirectorStack(redirector, outcome, cpath), srcSD);
|
processPaths(indent+" ", result, base, differential, nbc, start - 1, nbl-1, diffCursor - 1, url, webUrl, profileName, tgt.getElement().getPath(), diffMatches.get(0).getPath(), trimDifferential, contextName, resultPathBase, false, null, null, redirectorStack(redirector, outcome, cpath), srcSD);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
StructureDefinition dt = outcome.getType().size() == 1 ? getProfileForDataType(outcome.getType().get(0)) : getProfileForDataType("Element");
|
StructureDefinition dt = outcome.getType().size() == 1 ? getProfileForDataType(outcome.getType().get(0), webUrl) : getProfileForDataType("Element");
|
||||||
if (dt == null)
|
if (dt == null)
|
||||||
throw new DefinitionException(context.formatMessage(I18nConstants._HAS_CHILDREN__FOR_TYPE__IN_PROFILE__BUT_CANT_FIND_TYPE, diffMatches.get(0).getPath(), differential.getElement().get(diffCursor).getPath(), typeCode(outcome.getType()), profileName));
|
throw new DefinitionException(context.formatMessage(I18nConstants._HAS_CHILDREN__FOR_TYPE__IN_PROFILE__BUT_CANT_FIND_TYPE, diffMatches.get(0).getPath(), differential.getElement().get(diffCursor).getPath(), typeCode(outcome.getType()), profileName));
|
||||||
contextName = dt.getUrl();
|
contextName = dt.getUrl();
|
||||||
|
@ -1510,7 +1515,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
||||||
if (baseHasChildren(base, currentBase)) { // not a new type here
|
if (baseHasChildren(base, currentBase)) { // not a new type here
|
||||||
throw new Error("This situation is not yet handled (constrain slicing to 1..1 and fix base slice for inline structure - please report issue to grahame@fhir.org along with a test case that reproduces this error (@ "+cpath+" | "+currentBase.getPath()+")");
|
throw new Error("This situation is not yet handled (constrain slicing to 1..1 and fix base slice for inline structure - please report issue to grahame@fhir.org along with a test case that reproduces this error (@ "+cpath+" | "+currentBase.getPath()+")");
|
||||||
} else {
|
} else {
|
||||||
StructureDefinition dt = getTypeForElement(differential, diffCursor, profileName, diffMatches, outcome);
|
StructureDefinition dt = getTypeForElement(differential, diffCursor, profileName, diffMatches, outcome, webUrl);
|
||||||
contextName = dt.getUrl();
|
contextName = dt.getUrl();
|
||||||
diffCursor++;
|
diffCursor++;
|
||||||
start = diffCursor;
|
start = diffCursor;
|
||||||
|
@ -1576,7 +1581,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
||||||
processPaths(indent+" ", result, base, differential, baseCursor+1, diffCursor, baseLimit, diffLimit, url, webUrl, profileName, contextPathSrc, contextPathDst, trimDifferential, contextName, resultPathBase, false, null, null, redirector, srcSD);
|
processPaths(indent+" ", result, base, differential, baseCursor+1, diffCursor, baseLimit, diffLimit, url, webUrl, profileName, contextPathSrc, contextPathDst, trimDifferential, contextName, resultPathBase, false, null, null, redirector, srcSD);
|
||||||
baseCursor = indexOfFirstNonChild(base, currentBase, baseCursor, baseLimit);
|
baseCursor = indexOfFirstNonChild(base, currentBase, baseCursor, baseLimit);
|
||||||
} else {
|
} else {
|
||||||
StructureDefinition dt = getTypeForElement(differential, diffCursor, profileName, diffMatches, outcome);
|
StructureDefinition dt = getTypeForElement(differential, diffCursor, profileName, diffMatches, outcome, webUrl);
|
||||||
contextName = dt.getUrl();
|
contextName = dt.getUrl();
|
||||||
int start = diffCursor;
|
int start = diffCursor;
|
||||||
while (differential.getElement().size() > diffCursor && pathStartsWith(differential.getElement().get(diffCursor).getPath(), cpath+"."))
|
while (differential.getElement().size() > diffCursor && pathStartsWith(differential.getElement().get(diffCursor).getPath(), cpath+"."))
|
||||||
|
@ -1777,7 +1782,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
||||||
if (base.getElement().get(baseCursor).getType().size() != 1) {
|
if (base.getElement().get(baseCursor).getType().size() != 1) {
|
||||||
throw new Error(context.formatMessage(I18nConstants.DIFFERENTIAL_WALKS_INTO____BUT_THE_BASE_DOES_NOT_AND_THERE_IS_NOT_A_SINGLE_FIXED_TYPE_THE_TYPE_IS__THIS_IS_NOT_HANDLED_YET, cpath, diffMatches.get(0).toString(), base.getElement().get(baseCursor).typeSummary()));
|
throw new Error(context.formatMessage(I18nConstants.DIFFERENTIAL_WALKS_INTO____BUT_THE_BASE_DOES_NOT_AND_THERE_IS_NOT_A_SINGLE_FIXED_TYPE_THE_TYPE_IS__THIS_IS_NOT_HANDLED_YET, cpath, diffMatches.get(0).toString(), base.getElement().get(baseCursor).typeSummary()));
|
||||||
}
|
}
|
||||||
StructureDefinition dt = getProfileForDataType(base.getElement().get(baseCursor).getType().get(0));
|
StructureDefinition dt = getProfileForDataType(base.getElement().get(baseCursor).getType().get(0), webUrl);
|
||||||
if (dt == null) {
|
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), diffMatches.get(0).getPath()));
|
||||||
}
|
}
|
||||||
|
@ -1893,7 +1898,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
||||||
diffCursor - 1, url, webUrl, profileName+pathTail(diffMatches, 0), base.getElement().get(0).getPath(), base.getElement().get(0).getPath(), trimDifferential, contextName, resultPathBase, false, null, null, redirector, srcSD);
|
diffCursor - 1, url, webUrl, profileName+pathTail(diffMatches, 0), base.getElement().get(0).getPath(), base.getElement().get(0).getPath(), trimDifferential, contextName, resultPathBase, false, null, null, redirector, srcSD);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
StructureDefinition dt = getProfileForDataType(outcome.getType().get(0));
|
StructureDefinition dt = getProfileForDataType(outcome.getType().get(0), webUrl);
|
||||||
// if (t.getCode().equals("Extension") && t.hasProfile() && !t.getProfile().contains(":")) {
|
// if (t.getCode().equals("Extension") && t.hasProfile() && !t.getProfile().contains(":")) {
|
||||||
// lloydfix dt =
|
// lloydfix dt =
|
||||||
// }
|
// }
|
||||||
|
@ -1927,6 +1932,15 @@ public class ProfileUtilities extends TranslatingUtilities {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void updateConstraintSources(ElementDefinition ed, String url) {
|
||||||
|
for (ElementDefinitionConstraintComponent c : ed.getConstraint()) {
|
||||||
|
if (!c.hasSource()) {
|
||||||
|
c.setSource(url);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
private Set<String> getListOfTypes(ElementDefinition e) {
|
private Set<String> getListOfTypes(ElementDefinition e) {
|
||||||
Set<String> result = new HashSet<>();
|
Set<String> result = new HashSet<>();
|
||||||
for (TypeRefComponent t : e.getType()) {
|
for (TypeRefComponent t : e.getType()) {
|
||||||
|
@ -1936,7 +1950,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
||||||
}
|
}
|
||||||
|
|
||||||
public StructureDefinition getTypeForElement(StructureDefinitionDifferentialComponent differential, int diffCursor, String profileName,
|
public StructureDefinition getTypeForElement(StructureDefinitionDifferentialComponent differential, int diffCursor, String profileName,
|
||||||
List<ElementDefinition> diffMatches, ElementDefinition outcome) {
|
List<ElementDefinition> diffMatches, ElementDefinition outcome, String webUrl) {
|
||||||
if (outcome.getType().size() == 0) {
|
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_, diffMatches.get(0).getPath(), differential.getElement().get(diffCursor).getPath(), profileName));
|
||||||
}
|
}
|
||||||
|
@ -1946,7 +1960,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
||||||
throw new DefinitionException(context.formatMessage(I18nConstants._HAS_CHILDREN__AND_MULTIPLE_TYPES__IN_PROFILE_, diffMatches.get(0).getPath(), differential.getElement().get(diffCursor).getPath(), typeCode(outcome.getType()), profileName));
|
throw new DefinitionException(context.formatMessage(I18nConstants._HAS_CHILDREN__AND_MULTIPLE_TYPES__IN_PROFILE_, diffMatches.get(0).getPath(), differential.getElement().get(diffCursor).getPath(), typeCode(outcome.getType()), profileName));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
StructureDefinition dt = getProfileForDataType(outcome.getType().get(0));
|
StructureDefinition dt = getProfileForDataType(outcome.getType().get(0), webUrl);
|
||||||
if (dt == null)
|
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), diffMatches.get(0).getPath()));
|
||||||
return dt;
|
return dt;
|
||||||
|
@ -2418,10 +2432,16 @@ public class ProfileUtilities extends TranslatingUtilities {
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
private StructureDefinition getProfileForDataType(TypeRefComponent type) {
|
private StructureDefinition getProfileForDataType(TypeRefComponent type, String webUrl) {
|
||||||
StructureDefinition sd = null;
|
StructureDefinition sd = null;
|
||||||
if (type.hasProfile()) {
|
if (type.hasProfile()) {
|
||||||
sd = context.fetchResource(StructureDefinition.class, type.getProfile().get(0).getValue());
|
sd = context.fetchResource(StructureDefinition.class, type.getProfile().get(0).getValue());
|
||||||
|
if (sd == null) {
|
||||||
|
if (xver != null && xver.matchingUrl(type.getProfile().get(0).getValue()) && xver.status(type.getProfile().get(0).getValue()) == XVerExtensionStatus.Valid) {
|
||||||
|
sd = xver.makeDefinition(type.getProfile().get(0).getValue());
|
||||||
|
generateSnapshot(context.fetchTypeDefinition("Extension"), sd, sd.getUrl(), webUrl, sd.getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
if (sd == null)
|
if (sd == null)
|
||||||
System.out.println("Failed to find referenced profile: " + type.getProfile());
|
System.out.println("Failed to find referenced profile: " + type.getProfile());
|
||||||
}
|
}
|
||||||
|
@ -4314,12 +4334,12 @@ public class ProfileUtilities extends TranslatingUtilities {
|
||||||
|
|
||||||
private boolean isBaseCondition(IdType c) {
|
private boolean isBaseCondition(IdType c) {
|
||||||
String key = c.asStringValue();
|
String key = c.asStringValue();
|
||||||
return key.startsWith("ele-") || key.startsWith("res-") || key.startsWith("ext-") || key.startsWith("dom-") || key.startsWith("dr-");
|
return key != null && key.startsWith("ele-") || key.startsWith("res-") || key.startsWith("ext-") || key.startsWith("dom-") || key.startsWith("dr-");
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isBaseConstraint(ElementDefinitionConstraintComponent con) {
|
private boolean isBaseConstraint(ElementDefinitionConstraintComponent con) {
|
||||||
String key = con.getKey();
|
String key = con.getKey();
|
||||||
return key.startsWith("ele-") || key.startsWith("res-") || key.startsWith("ext-") || key.startsWith("dom-") || key.startsWith("dr-");
|
return key != null && key.startsWith("ele-") || key.startsWith("res-") || key.startsWith("ext-") || key.startsWith("dom-") || key.startsWith("dr-");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void makeChoiceRows(List<Row> subRows, ElementDefinition element, HierarchicalTableGenerator gen, String corePath, String profileBaseFileName, boolean mustSupportMode) {
|
private void makeChoiceRows(List<Row> subRows, ElementDefinition element, HierarchicalTableGenerator gen, String corePath, String profileBaseFileName, boolean mustSupportMode) {
|
||||||
|
|
|
@ -666,10 +666,11 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ValueSetExpansionOutcome expandVS(ConceptSetComponent inc, boolean hierarchical) throws TerminologyServiceException {
|
public ValueSetExpansionOutcome expandVS(ConceptSetComponent inc, boolean hierarchical, boolean noInactive) throws TerminologyServiceException {
|
||||||
ValueSet vs = new ValueSet();
|
ValueSet vs = new ValueSet();
|
||||||
vs.setStatus(PublicationStatus.ACTIVE);
|
vs.setStatus(PublicationStatus.ACTIVE);
|
||||||
vs.setCompose(new ValueSetComposeComponent());
|
vs.setCompose(new ValueSetComposeComponent());
|
||||||
|
vs.getCompose().setInactive(!noInactive);
|
||||||
vs.getCompose().getInclude().add(inc);
|
vs.getCompose().getInclude().add(inc);
|
||||||
CacheToken cacheToken = txCache.generateExpandToken(vs, hierarchical);
|
CacheToken cacheToken = txCache.generateExpandToken(vs, hierarchical);
|
||||||
ValueSetExpansionOutcome res;
|
ValueSetExpansionOutcome res;
|
||||||
|
|
|
@ -124,6 +124,9 @@ public class CanonicalResourceManager<T extends CanonicalResource> {
|
||||||
if (resource == null) {
|
if (resource == null) {
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
T1 res = (T1) proxy.getResource();
|
T1 res = (T1) proxy.getResource();
|
||||||
|
if (res == null) {
|
||||||
|
throw new Error("Proxy loading a resource from "+packageInfo+" failed and returned null");
|
||||||
|
}
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
resource = res;
|
resource = res;
|
||||||
}
|
}
|
||||||
|
|
|
@ -547,7 +547,7 @@ public interface IWorkerContext {
|
||||||
* @return
|
* @return
|
||||||
* @throws FHIRException
|
* @throws FHIRException
|
||||||
*/
|
*/
|
||||||
ValueSetExpansionOutcome expandVS(ConceptSetComponent inc, boolean hierarchical) throws TerminologyServiceException;
|
ValueSetExpansionOutcome expandVS(ConceptSetComponent inc, boolean hierarchical, boolean noInactive) throws TerminologyServiceException;
|
||||||
|
|
||||||
Locale getLocale();
|
Locale getLocale();
|
||||||
|
|
||||||
|
|
|
@ -239,7 +239,7 @@ public class SimpleWorkerContext extends BaseWorkerContext implements IWorkerCon
|
||||||
|
|
||||||
public SimpleWorkerContext fromPackage(NpmPackage pi, IContextResourceLoader loader) throws IOException, FHIRException {
|
public SimpleWorkerContext fromPackage(NpmPackage pi, IContextResourceLoader loader) throws IOException, FHIRException {
|
||||||
SimpleWorkerContext context = getSimpleWorkerContextInstance();
|
SimpleWorkerContext context = getSimpleWorkerContextInstance();
|
||||||
context.setAllowLoadingDuplicates(true);
|
context.setAllowLoadingDuplicates(allowLoadingDuplicates);
|
||||||
context.version = pi.getNpm().get("version").getAsString();
|
context.version = pi.getNpm().get("version").getAsString();
|
||||||
context.loadFromPackage(pi, loader);
|
context.loadFromPackage(pi, loader);
|
||||||
context.finishLoading();
|
context.finishLoading();
|
||||||
|
|
|
@ -11570,6 +11570,10 @@ When pattern[x] is used to constrain a complex object, it means that each proper
|
||||||
return getType().size() == 1 && Utilities.existsInList(getType().get(0).getCode(), "Element", "BackboneElement");
|
return getType().size() == 1 && Utilities.existsInList(getType().get(0).getCode(), "Element", "BackboneElement");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean prohibited() {
|
||||||
|
return "0".equals(getMax());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// end addition
|
// end addition
|
||||||
|
|
||||||
|
|
|
@ -6924,9 +6924,9 @@ The primary difference between a medicationusage and a medicationadministration
|
||||||
return _4_1_0;
|
return _4_1_0;
|
||||||
if ("4.2.0".equals(codeString))
|
if ("4.2.0".equals(codeString))
|
||||||
return _4_2_0;
|
return _4_2_0;
|
||||||
if ("4.3.0-snapshot1".equals(codeString))
|
if ("4.3.0-snapshot1".equalsIgnoreCase(codeString))
|
||||||
return _4_3_0SNAPSHOT1;
|
return _4_3_0SNAPSHOT1;
|
||||||
if ("4.3.0-cibuild".equals(codeString))
|
if ("4.3.0-cibuild".equalsIgnoreCase(codeString))
|
||||||
return _4_3_0CIBUILD;
|
return _4_3_0CIBUILD;
|
||||||
if ("4.4.0".equals(codeString))
|
if ("4.4.0".equals(codeString))
|
||||||
return _4_4_0;
|
return _4_4_0;
|
||||||
|
@ -6934,9 +6934,9 @@ The primary difference between a medicationusage and a medicationadministration
|
||||||
return _4_5_0;
|
return _4_5_0;
|
||||||
if ("4.6.0".equals(codeString))
|
if ("4.6.0".equals(codeString))
|
||||||
return _4_6_0;
|
return _4_6_0;
|
||||||
if ("5.0.0-snapshot1".equals(codeString))
|
if ("5.0.0-snapshot1".equalsIgnoreCase(codeString))
|
||||||
return _5_0_0SNAPSHOT1;
|
return _5_0_0SNAPSHOT1;
|
||||||
if ("5.0.0-cibuild".equals(codeString))
|
if ("5.0.0-cibuild".equalsIgnoreCase(codeString))
|
||||||
return _5_0_0CIBUILD;
|
return _5_0_0CIBUILD;
|
||||||
throw new FHIRException("Unknown FHIRVersion code '"+codeString+"'");
|
throw new FHIRException("Unknown FHIRVersion code '"+codeString+"'");
|
||||||
}
|
}
|
||||||
|
@ -7158,7 +7158,7 @@ public String toCode(int len) {
|
||||||
|
|
||||||
|
|
||||||
public boolean isR4B() {
|
public boolean isR4B() {
|
||||||
return toCode().startsWith("4.3");
|
return toCode().startsWith("4.1") || toCode().startsWith("4.3");
|
||||||
}
|
}
|
||||||
|
|
||||||
// end addition
|
// end addition
|
||||||
|
@ -7219,9 +7219,9 @@ public String toCode(int len) {
|
||||||
return FHIRVersion._4_1_0;
|
return FHIRVersion._4_1_0;
|
||||||
if ("4.2.0".equals(codeString))
|
if ("4.2.0".equals(codeString))
|
||||||
return FHIRVersion._4_2_0;
|
return FHIRVersion._4_2_0;
|
||||||
if ("4.3.0-snapshot1".equals(codeString))
|
if ("4.3.0-snapshot1".equalsIgnoreCase(codeString))
|
||||||
return FHIRVersion._4_3_0SNAPSHOT1;
|
return FHIRVersion._4_3_0SNAPSHOT1;
|
||||||
if ("4.3.0-cibuild".equals(codeString))
|
if ("4.3.0-cibuild".equalsIgnoreCase(codeString))
|
||||||
return FHIRVersion._4_3_0CIBUILD;
|
return FHIRVersion._4_3_0CIBUILD;
|
||||||
if ("4.4.0".equals(codeString))
|
if ("4.4.0".equals(codeString))
|
||||||
return FHIRVersion._4_4_0;
|
return FHIRVersion._4_4_0;
|
||||||
|
@ -7229,9 +7229,9 @@ public String toCode(int len) {
|
||||||
return FHIRVersion._4_5_0;
|
return FHIRVersion._4_5_0;
|
||||||
if ("4.6.0".equals(codeString))
|
if ("4.6.0".equals(codeString))
|
||||||
return FHIRVersion._4_6_0;
|
return FHIRVersion._4_6_0;
|
||||||
if ("5.0.0-snapshot1".equals(codeString))
|
if ("5.0.0-snapshot1".equalsIgnoreCase(codeString))
|
||||||
return FHIRVersion._5_0_0SNAPSHOT1;
|
return FHIRVersion._5_0_0SNAPSHOT1;
|
||||||
if ("5.0.0-cibuild".equals(codeString))
|
if ("5.0.0-cibuild".equalsIgnoreCase(codeString))
|
||||||
return FHIRVersion._5_0_0CIBUILD;
|
return FHIRVersion._5_0_0CIBUILD;
|
||||||
throw new IllegalArgumentException("Unknown FHIRVersion code '"+codeString+"'");
|
throw new IllegalArgumentException("Unknown FHIRVersion code '"+codeString+"'");
|
||||||
}
|
}
|
||||||
|
@ -7293,9 +7293,9 @@ public String toCode(int len) {
|
||||||
return new Enumeration<FHIRVersion>(this, FHIRVersion._4_1_0);
|
return new Enumeration<FHIRVersion>(this, FHIRVersion._4_1_0);
|
||||||
if ("4.2.0".equals(codeString))
|
if ("4.2.0".equals(codeString))
|
||||||
return new Enumeration<FHIRVersion>(this, FHIRVersion._4_2_0);
|
return new Enumeration<FHIRVersion>(this, FHIRVersion._4_2_0);
|
||||||
if ("4.3.0-snapshot1".equals(codeString))
|
if ("4.3.0-snapshot1".equalsIgnoreCase(codeString))
|
||||||
return new Enumeration<FHIRVersion>(this, FHIRVersion._4_3_0SNAPSHOT1);
|
return new Enumeration<FHIRVersion>(this, FHIRVersion._4_3_0SNAPSHOT1);
|
||||||
if ("4.3.0-cibuild".equals(codeString))
|
if ("4.3.0-cibuild".equalsIgnoreCase(codeString))
|
||||||
return new Enumeration<FHIRVersion>(this, FHIRVersion._4_3_0CIBUILD);
|
return new Enumeration<FHIRVersion>(this, FHIRVersion._4_3_0CIBUILD);
|
||||||
if ("4.4.0".equals(codeString))
|
if ("4.4.0".equals(codeString))
|
||||||
return new Enumeration<FHIRVersion>(this, FHIRVersion._4_4_0);
|
return new Enumeration<FHIRVersion>(this, FHIRVersion._4_4_0);
|
||||||
|
@ -7303,9 +7303,9 @@ public String toCode(int len) {
|
||||||
return new Enumeration<FHIRVersion>(this, FHIRVersion._4_5_0);
|
return new Enumeration<FHIRVersion>(this, FHIRVersion._4_5_0);
|
||||||
if ("4.6.0".equals(codeString))
|
if ("4.6.0".equals(codeString))
|
||||||
return new Enumeration<FHIRVersion>(this, FHIRVersion._4_6_0);
|
return new Enumeration<FHIRVersion>(this, FHIRVersion._4_6_0);
|
||||||
if ("5.0.0-snapshot1".equals(codeString))
|
if ("5.0.0-snapshot1".equalsIgnoreCase(codeString))
|
||||||
return new Enumeration<FHIRVersion>(this, FHIRVersion._5_0_0SNAPSHOT1);
|
return new Enumeration<FHIRVersion>(this, FHIRVersion._5_0_0SNAPSHOT1);
|
||||||
if ("5.0.0-cibuild".equals(codeString))
|
if ("5.0.0-cibuild".equalsIgnoreCase(codeString))
|
||||||
return new Enumeration<FHIRVersion>(this, FHIRVersion._5_0_0CIBUILD);
|
return new Enumeration<FHIRVersion>(this, FHIRVersion._5_0_0CIBUILD);
|
||||||
throw new FHIRException("Unknown FHIRVersion code '"+codeString+"'");
|
throw new FHIRException("Unknown FHIRVersion code '"+codeString+"'");
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,6 +30,7 @@ import org.hl7.fhir.r5.context.IWorkerContext;
|
||||||
import org.hl7.fhir.r5.context.IWorkerContext.ValidationResult;
|
import org.hl7.fhir.r5.context.IWorkerContext.ValidationResult;
|
||||||
import org.hl7.fhir.r5.model.Address;
|
import org.hl7.fhir.r5.model.Address;
|
||||||
import org.hl7.fhir.r5.model.Annotation;
|
import org.hl7.fhir.r5.model.Annotation;
|
||||||
|
import org.hl7.fhir.r5.model.BackboneType;
|
||||||
import org.hl7.fhir.r5.model.Base;
|
import org.hl7.fhir.r5.model.Base;
|
||||||
import org.hl7.fhir.r5.model.BaseDateTimeType;
|
import org.hl7.fhir.r5.model.BaseDateTimeType;
|
||||||
import org.hl7.fhir.r5.model.CanonicalResource;
|
import org.hl7.fhir.r5.model.CanonicalResource;
|
||||||
|
@ -48,6 +49,7 @@ import org.hl7.fhir.r5.model.ContactPoint.ContactPointSystem;
|
||||||
import org.hl7.fhir.r5.model.DataType;
|
import org.hl7.fhir.r5.model.DataType;
|
||||||
import org.hl7.fhir.r5.model.DateTimeType;
|
import org.hl7.fhir.r5.model.DateTimeType;
|
||||||
import org.hl7.fhir.r5.model.DateType;
|
import org.hl7.fhir.r5.model.DateType;
|
||||||
|
import org.hl7.fhir.r5.model.ElementDefinition;
|
||||||
import org.hl7.fhir.r5.model.Enumeration;
|
import org.hl7.fhir.r5.model.Enumeration;
|
||||||
import org.hl7.fhir.r5.model.Expression;
|
import org.hl7.fhir.r5.model.Expression;
|
||||||
import org.hl7.fhir.r5.model.Extension;
|
import org.hl7.fhir.r5.model.Extension;
|
||||||
|
@ -357,8 +359,138 @@ public class DataRenderer extends Renderer {
|
||||||
return value.primitiveValue();
|
return value.primitiveValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// -- 6. General purpose extension rendering ----------------------------------------------
|
||||||
|
|
||||||
// -- 5. Data type Rendering ----------------------------------------------
|
public boolean hasRenderableExtensions(DataType element) {
|
||||||
|
for (Extension ext : element.getExtension()) {
|
||||||
|
if (canRender(ext)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasRenderableExtensions(BackboneType element) {
|
||||||
|
for (Extension ext : element.getExtension()) {
|
||||||
|
if (canRender(ext)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return element.hasModifierExtension();
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getExtensionLabel(Extension ext) {
|
||||||
|
StructureDefinition sd = context.getWorker().fetchResource(StructureDefinition.class, ext.getUrl());
|
||||||
|
if (sd != null && ext.getValue().isPrimitive() && sd.hasSnapshot()) {
|
||||||
|
for (ElementDefinition ed : sd.getSnapshot().getElement()) {
|
||||||
|
if (Utilities.existsInList(ed.getPath(), "Extension", "Extension.value[x]") && ed.hasLabel()) {
|
||||||
|
return ed.getLabel();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean canRender(Extension ext) {
|
||||||
|
return getExtensionLabel(ext) != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void renderExtensionsInList(XhtmlNode ul, DataType element) throws FHIRFormatError, DefinitionException, IOException {
|
||||||
|
for (Extension ext : element.getExtension()) {
|
||||||
|
if (canRender(ext)) {
|
||||||
|
String lbl = getExtensionLabel(ext);
|
||||||
|
XhtmlNode li = ul.li();
|
||||||
|
li.tx(lbl);
|
||||||
|
li.tx(": ");
|
||||||
|
render(li, ext.getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void renderExtensionsInList(XhtmlNode ul, BackboneType element) throws FHIRFormatError, DefinitionException, IOException {
|
||||||
|
for (Extension ext : element.getModifierExtension()) {
|
||||||
|
if (canRender(ext)) {
|
||||||
|
String lbl = getExtensionLabel(ext);
|
||||||
|
XhtmlNode li = ul.li();
|
||||||
|
li = li.b();
|
||||||
|
li.tx(lbl);
|
||||||
|
li.tx(": ");
|
||||||
|
render(li, ext.getValue());
|
||||||
|
} else {
|
||||||
|
// somehow have to do better than this
|
||||||
|
XhtmlNode li = ul.li();
|
||||||
|
li.b().tx("WARNING: Unrenderable Modifier Extension!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (Extension ext : element.getExtension()) {
|
||||||
|
if (canRender(ext)) {
|
||||||
|
String lbl = getExtensionLabel(ext);
|
||||||
|
XhtmlNode li = ul.li();
|
||||||
|
li.tx(lbl);
|
||||||
|
li.tx(": ");
|
||||||
|
render(li, ext.getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void renderExtensionsInText(XhtmlNode div, DataType element, String sep) throws FHIRFormatError, DefinitionException, IOException {
|
||||||
|
boolean first = true;
|
||||||
|
for (Extension ext : element.getExtension()) {
|
||||||
|
if (canRender(ext)) {
|
||||||
|
if (first) {
|
||||||
|
first = false;
|
||||||
|
} else {
|
||||||
|
div.tx(sep);
|
||||||
|
div.tx(" ");
|
||||||
|
}
|
||||||
|
|
||||||
|
String lbl = getExtensionLabel(ext);
|
||||||
|
div.tx(lbl);
|
||||||
|
div.tx(": ");
|
||||||
|
render(div, ext.getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void renderExtensionsInList(XhtmlNode div, BackboneType element, String sep) throws FHIRFormatError, DefinitionException, IOException {
|
||||||
|
boolean first = true;
|
||||||
|
for (Extension ext : element.getModifierExtension()) {
|
||||||
|
if (first) {
|
||||||
|
first = false;
|
||||||
|
} else {
|
||||||
|
div.tx(sep);
|
||||||
|
div.tx(" ");
|
||||||
|
}
|
||||||
|
if (canRender(ext)) {
|
||||||
|
String lbl = getExtensionLabel(ext);
|
||||||
|
XhtmlNode b = div.b();
|
||||||
|
b.tx(lbl);
|
||||||
|
b.tx(": ");
|
||||||
|
render(div, ext.getValue());
|
||||||
|
} else {
|
||||||
|
// somehow have to do better than this
|
||||||
|
div.b().tx("WARNING: Unrenderable Modifier Extension!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (Extension ext : element.getExtension()) {
|
||||||
|
if (canRender(ext)) {
|
||||||
|
if (first) {
|
||||||
|
first = false;
|
||||||
|
} else {
|
||||||
|
div.tx(sep);
|
||||||
|
div.tx(" ");
|
||||||
|
}
|
||||||
|
|
||||||
|
String lbl = getExtensionLabel(ext);
|
||||||
|
div.tx(lbl);
|
||||||
|
div.tx(": ");
|
||||||
|
render(div, ext.getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// -- 6. Data type Rendering ----------------------------------------------
|
||||||
|
|
||||||
public static String display(IWorkerContext context, DataType type) {
|
public static String display(IWorkerContext context, DataType type) {
|
||||||
return new DataRenderer(new RenderingContext(context, null, null, "http://hl7.org/fhir/R4", "", null, ResourceRendererMode.END_USER)).display(type);
|
return new DataRenderer(new RenderingContext(context, null, null, "http://hl7.org/fhir/R4", "", null, ResourceRendererMode.END_USER)).display(type);
|
||||||
|
@ -866,11 +998,11 @@ public class DataRenderer extends Renderer {
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void renderCodeableConcept(XhtmlNode x, CodeableConcept cc) {
|
protected void renderCodeableConcept(XhtmlNode x, CodeableConcept cc) throws FHIRFormatError, DefinitionException, IOException {
|
||||||
renderCodeableConcept(x, cc, false);
|
renderCodeableConcept(x, cc, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void renderCodeableReference(XhtmlNode x, CodeableReference e, boolean showCodeDetails) {
|
protected void renderCodeableReference(XhtmlNode x, CodeableReference e, boolean showCodeDetails) throws FHIRFormatError, DefinitionException, IOException {
|
||||||
if (e.hasConcept()) {
|
if (e.hasConcept()) {
|
||||||
renderCodeableConcept(x, e.getConcept(), showCodeDetails);
|
renderCodeableConcept(x, e.getConcept(), showCodeDetails);
|
||||||
}
|
}
|
||||||
|
@ -879,7 +1011,7 @@ public class DataRenderer extends Renderer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void renderCodeableConcept(XhtmlNode x, CodeableConcept cc, boolean showCodeDetails) {
|
protected void renderCodeableConcept(XhtmlNode x, CodeableConcept cc, boolean showCodeDetails) throws FHIRFormatError, DefinitionException, IOException {
|
||||||
if (cc.isEmpty()) {
|
if (cc.isEmpty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -935,6 +1067,12 @@ public class DataRenderer extends Renderer {
|
||||||
sp.tx(" \""+c.getDisplay()+"\"");
|
sp.tx(" \""+c.getDisplay()+"\"");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (hasRenderableExtensions(cc)) {
|
||||||
|
if (!first) {
|
||||||
|
sp.tx("; ");
|
||||||
|
}
|
||||||
|
renderExtensionsInText(sp, cc, ";");
|
||||||
|
}
|
||||||
sp.tx(")");
|
sp.tx(")");
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
|
|
@ -33,11 +33,29 @@ public class LiquidRenderer extends ResourceRenderer {
|
||||||
this.liquidTemplate = liquidTemplate;
|
this.liquidTemplate = liquidTemplate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class provides an implementation of the ILiquidEngineIncludeResolver that makes use of the
|
||||||
|
* template provider available in the rendering context to support resolving includes.
|
||||||
|
*/
|
||||||
|
private class LiquidRendererIncludeResolver implements LiquidEngine.ILiquidEngineIncludeResolver {
|
||||||
|
public LiquidRendererIncludeResolver(RenderingContext context) {
|
||||||
|
this.context = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
private RenderingContext context;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String fetchInclude(LiquidEngine engine, String name) {
|
||||||
|
return context.getTemplateProvider().findTemplate(context, name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean render(XhtmlNode x, Resource r) throws FHIRFormatError, DefinitionException, IOException, FHIRException, EOperationOutcome {
|
public boolean render(XhtmlNode x, Resource r) throws FHIRFormatError, DefinitionException, IOException, FHIRException, EOperationOutcome {
|
||||||
LiquidEngine engine = new LiquidEngine(context.getWorker(), context.getServices());
|
LiquidEngine engine = new LiquidEngine(context.getWorker(), context.getServices());
|
||||||
XhtmlNode xn;
|
XhtmlNode xn;
|
||||||
try {
|
try {
|
||||||
|
engine.setIncludeResolver(new LiquidRendererIncludeResolver(context));
|
||||||
LiquidDocument doc = engine.parse(liquidTemplate, "template");
|
LiquidDocument doc = engine.parse(liquidTemplate, "template");
|
||||||
String html = engine.evaluate(doc, r, rcontext);
|
String html = engine.evaluate(doc, r, rcontext);
|
||||||
xn = new XhtmlParser().parseFragment(html);
|
xn = new XhtmlParser().parseFragment(html);
|
||||||
|
|
|
@ -213,7 +213,7 @@ public class ValueSetRenderer extends TerminologyRenderer {
|
||||||
XhtmlNode t = x.table( "codes");
|
XhtmlNode t = x.table( "codes");
|
||||||
XhtmlNode tr = t.tr();
|
XhtmlNode tr = t.tr();
|
||||||
if (doLevel)
|
if (doLevel)
|
||||||
tr.td().b().tx("Lvl");
|
tr.td().b().tx("Level");
|
||||||
tr.td().attribute("style", "white-space:nowrap").b().tx("Code");
|
tr.td().attribute("style", "white-space:nowrap").b().tx("Code");
|
||||||
if (doSystem)
|
if (doSystem)
|
||||||
tr.td().b().tx("System");
|
tr.td().b().tx("System");
|
||||||
|
@ -242,7 +242,7 @@ public class ValueSetRenderer extends TerminologyRenderer {
|
||||||
|
|
||||||
addMapHeaders(tr, maps);
|
addMapHeaders(tr, maps);
|
||||||
for (ValueSetExpansionContainsComponent c : vs.getExpansion().getContains()) {
|
for (ValueSetExpansionContainsComponent c : vs.getExpansion().getContains()) {
|
||||||
addExpansionRowToTable(t, c, 0, doLevel, doSystem, doDefinition, maps, allCS, langs, doLangs);
|
addExpansionRowToTable(t, c, 1, doLevel, doSystem, doDefinition, maps, allCS, langs, doLangs);
|
||||||
}
|
}
|
||||||
|
|
||||||
// now, build observed languages
|
// now, build observed languages
|
||||||
|
@ -1165,7 +1165,7 @@ public class ValueSetRenderer extends TerminologyRenderer {
|
||||||
ValueSetExpansionComponent vse = null;
|
ValueSetExpansionComponent vse = null;
|
||||||
if (!context.isNoSlowLookup() && !getContext().getWorker().hasCache()) {
|
if (!context.isNoSlowLookup() && !getContext().getWorker().hasCache()) {
|
||||||
try {
|
try {
|
||||||
ValueSetExpansionOutcome vso = getContext().getWorker().expandVS(inc, false);
|
ValueSetExpansionOutcome vso = getContext().getWorker().expandVS(inc, false, false);
|
||||||
ValueSet valueset = vso.getValueset();
|
ValueSet valueset = vso.getValueset();
|
||||||
if (valueset == null)
|
if (valueset == null)
|
||||||
throw new TerminologyServiceException("Error Expanding ValueSet: "+vso.getError());
|
throw new TerminologyServiceException("Error Expanding ValueSet: "+vso.getError());
|
||||||
|
|
|
@ -249,7 +249,7 @@ public class CodeSystemUtilities {
|
||||||
public static boolean isInactive(CodeSystem cs, ConceptDefinitionComponent def) throws FHIRException {
|
public static boolean isInactive(CodeSystem cs, ConceptDefinitionComponent def) throws FHIRException {
|
||||||
for (ConceptPropertyComponent p : def.getProperty()) {
|
for (ConceptPropertyComponent p : def.getProperty()) {
|
||||||
if ("status".equals(p.getCode()) && p.hasValueStringType())
|
if ("status".equals(p.getCode()) && p.hasValueStringType())
|
||||||
return "inactive".equals(p.getValueStringType());
|
return "inactive".equals(p.getValueStringType().primitiveValue()) || "retired".equals(p.getValueStringType().primitiveValue());
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,8 +33,10 @@ package org.hl7.fhir.r5.terminologies;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import org.hl7.fhir.exceptions.FHIRException;
|
import org.hl7.fhir.exceptions.FHIRException;
|
||||||
import org.hl7.fhir.exceptions.NoTerminologyServiceException;
|
import org.hl7.fhir.exceptions.NoTerminologyServiceException;
|
||||||
|
@ -544,71 +546,92 @@ public class ValueSetCheckerSimple extends ValueSetWorker implements ValueSetChe
|
||||||
|
|
||||||
|
|
||||||
private String systemForCodeInValueSet(String code) {
|
private String systemForCodeInValueSet(String code) {
|
||||||
String sys = null;
|
Set<String> sys = new HashSet<>();
|
||||||
|
if (!scanForCodeInValueSet(code, sys)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (sys.size() != 1) {
|
||||||
|
return null;
|
||||||
|
} else {
|
||||||
|
return sys.iterator().next();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean scanForCodeInValueSet(String code, Set<String> sys) {
|
||||||
if (valueset.hasCompose()) {
|
if (valueset.hasCompose()) {
|
||||||
if (valueset.getCompose().hasExclude()) {
|
// not sure what to do with the
|
||||||
return null;
|
// if (valueset.getCompose().hasExclude()) {
|
||||||
}
|
// return false;
|
||||||
|
// }
|
||||||
for (ConceptSetComponent vsi : valueset.getCompose().getInclude()) {
|
for (ConceptSetComponent vsi : valueset.getCompose().getInclude()) {
|
||||||
if (vsi.hasValueSet()) {
|
if (vsi.hasValueSet()) {
|
||||||
return null;
|
for (CanonicalType u : vsi.getValueSet()) {
|
||||||
}
|
if (!checkForCodeInValueSet(code, u.getValue(), sys)) {
|
||||||
if (!vsi.hasSystem()) {
|
return false;
|
||||||
return null;
|
|
||||||
}
|
|
||||||
if (vsi.hasFilter()) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
CodeSystem cs = resolveCodeSystem(vsi.getSystem());
|
|
||||||
if (cs == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
if (vsi.hasConcept()) {
|
|
||||||
for (ConceptReferenceComponent cc : vsi.getConcept()) {
|
|
||||||
boolean match = cs.getCaseSensitive() ? cc.getCode().equals(code) : cc.getCode().equalsIgnoreCase(code);
|
|
||||||
if (match) {
|
|
||||||
if (sys == null) {
|
|
||||||
sys = vsi.getSystem();
|
|
||||||
} else if (!sys.equals(vsi.getSystem())) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else if (!vsi.hasSystem()) {
|
||||||
ConceptDefinitionComponent cc = findCodeInConcept(cs.getConcept(), code);
|
return false;
|
||||||
if (cc != null) {
|
}
|
||||||
if (sys == null) {
|
if (vsi.hasSystem()) {
|
||||||
sys = vsi.getSystem();
|
if (vsi.hasFilter()) {
|
||||||
} else if (!sys.equals(vsi.getSystem())) {
|
return false;
|
||||||
return null;
|
}
|
||||||
|
CodeSystem cs = resolveCodeSystem(vsi.getSystem());
|
||||||
|
if (cs != null) {
|
||||||
|
|
||||||
|
if (vsi.hasConcept()) {
|
||||||
|
for (ConceptReferenceComponent cc : vsi.getConcept()) {
|
||||||
|
boolean match = cs.getCaseSensitive() ? cc.getCode().equals(code) : cc.getCode().equalsIgnoreCase(code);
|
||||||
|
if (match) {
|
||||||
|
sys.add(vsi.getSystem());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ConceptDefinitionComponent cc = findCodeInConcept(cs.getConcept(), code);
|
||||||
|
if (cc != null) {
|
||||||
|
sys.add(vsi.getSystem());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (vsi.hasConcept()) {
|
||||||
|
for (ConceptReferenceComponent cc : vsi.getConcept()) {
|
||||||
|
boolean match = cc.getCode().equals(code);
|
||||||
|
if (match) {
|
||||||
|
sys.add(vsi.getSystem());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (valueset.hasExpansion()) {
|
} else if (valueset.hasExpansion()) {
|
||||||
// Retrieve a list of all systems associated with this code in the expansion
|
// Retrieve a list of all systems associated with this code in the expansion
|
||||||
List<String> systems = new ArrayList<String>();
|
if (!checkSystems(valueset.getExpansion().getContains(), code, sys)) {
|
||||||
checkSystems(valueset.getExpansion().getContains(), code, systems);
|
return false;
|
||||||
if (systems.size()==1)
|
}
|
||||||
sys = systems.get(0);
|
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
return sys;
|
private boolean checkForCodeInValueSet(String code, String uri, Set<String> sys) {
|
||||||
|
ValueSetCheckerSimple vs = getVs(uri);
|
||||||
|
return vs.scanForCodeInValueSet(code, sys);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Recursively go through all codes in the expansion and for any coding that matches the specified code, add the system for that coding
|
* Recursively go through all codes in the expansion and for any coding that matches the specified code, add the system for that coding
|
||||||
* to the passed list.
|
* to the passed list.
|
||||||
*/
|
*/
|
||||||
private void checkSystems(List<ValueSetExpansionContainsComponent> contains, String code, List<String> systems) {
|
private boolean checkSystems(List<ValueSetExpansionContainsComponent> contains, String code, Set<String> systems) {
|
||||||
for (ValueSetExpansionContainsComponent c: contains) {
|
for (ValueSetExpansionContainsComponent c: contains) {
|
||||||
if (c.getCode().equals(code)) {
|
if (c.getCode().equals(code)) {
|
||||||
if (!systems.contains(c.getSystem()))
|
systems.add(c.getSystem());
|
||||||
systems.add(c.getSystem());
|
|
||||||
}
|
}
|
||||||
if (c.hasContains())
|
if (c.hasContains())
|
||||||
checkSystems(c.getContains(), code, systems);
|
checkSystems(c.getContains(), code, systems);
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -108,6 +108,8 @@ import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionParameterComponent;
|
||||||
import org.hl7.fhir.r5.utils.ToolingExtensions;
|
import org.hl7.fhir.r5.utils.ToolingExtensions;
|
||||||
import org.hl7.fhir.utilities.Utilities;
|
import org.hl7.fhir.utilities.Utilities;
|
||||||
|
|
||||||
|
import com.google.errorprone.annotations.NoAllocation;
|
||||||
|
|
||||||
public class ValueSetExpanderSimple extends ValueSetWorker implements ValueSetExpander {
|
public class ValueSetExpanderSimple extends ValueSetWorker implements ValueSetExpander {
|
||||||
|
|
||||||
public class PropertyFilter implements IConceptFilter {
|
public class PropertyFilter implements IConceptFilter {
|
||||||
|
@ -201,10 +203,15 @@ public class ValueSetExpanderSimple extends ValueSetWorker implements ValueSetEx
|
||||||
maxExpansionSize = theMaxExpansionSize;
|
maxExpansionSize = theMaxExpansionSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ValueSetExpansionContainsComponent addCode(String system, String code, String display, ValueSetExpansionContainsComponent parent, List<ConceptDefinitionDesignationComponent> designations, Parameters expParams, boolean isAbstract, boolean inactive, List<ValueSet> filters) {
|
private ValueSetExpansionContainsComponent addCode(String system, String code, String display, ValueSetExpansionContainsComponent parent, List<ConceptDefinitionDesignationComponent> designations, Parameters expParams,
|
||||||
|
boolean isAbstract, boolean inactive, List<ValueSet> filters, boolean noInactive) {
|
||||||
|
|
||||||
if (filters != null && !filters.isEmpty() && !filterContainsCode(filters, system, code))
|
if (filters != null && !filters.isEmpty() && !filterContainsCode(filters, system, code))
|
||||||
return null;
|
return null;
|
||||||
|
if (noInactive && inactive) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
ValueSetExpansionContainsComponent n = new ValueSet.ValueSetExpansionContainsComponent();
|
ValueSetExpansionContainsComponent n = new ValueSet.ValueSetExpansionContainsComponent();
|
||||||
n.setSystem(system);
|
n.setSystem(system);
|
||||||
n.setCode(code);
|
n.setCode(code);
|
||||||
|
@ -267,12 +274,12 @@ public class ValueSetExpanderSimple extends ValueSetWorker implements ValueSetEx
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addCodeAndDescendents(ValueSetExpansionContainsComponent focus, ValueSetExpansionContainsComponent parent, Parameters expParams, List<ValueSet> filters) throws FHIRException {
|
private void addCodeAndDescendents(ValueSetExpansionContainsComponent focus, ValueSetExpansionContainsComponent parent, Parameters expParams, List<ValueSet> filters, boolean noInactive) throws FHIRException {
|
||||||
focus.checkNoModifiers("Expansion.contains", "expanding");
|
focus.checkNoModifiers("Expansion.contains", "expanding");
|
||||||
ValueSetExpansionContainsComponent np = addCode(focus.getSystem(), focus.getCode(), focus.getDisplay(), parent,
|
ValueSetExpansionContainsComponent np = addCode(focus.getSystem(), focus.getCode(), focus.getDisplay(), parent,
|
||||||
convert(focus.getDesignation()), expParams, focus.getAbstract(), focus.getInactive(), filters);
|
convert(focus.getDesignation()), expParams, focus.getAbstract(), focus.getInactive(), filters, noInactive);
|
||||||
for (ValueSetExpansionContainsComponent c : focus.getContains())
|
for (ValueSetExpansionContainsComponent c : focus.getContains())
|
||||||
addCodeAndDescendents(focus, np, expParams, filters);
|
addCodeAndDescendents(focus, np, expParams, filters, noInactive);
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<ConceptDefinitionDesignationComponent> convert(List<ConceptReferenceDesignationComponent> designations) {
|
private List<ConceptDefinitionDesignationComponent> convert(List<ConceptReferenceDesignationComponent> designations) {
|
||||||
|
@ -287,7 +294,7 @@ public class ValueSetExpanderSimple extends ValueSetWorker implements ValueSetEx
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addCodeAndDescendents(CodeSystem cs, String system, ConceptDefinitionComponent def, ValueSetExpansionContainsComponent parent, Parameters expParams, List<ValueSet> filters, ConceptDefinitionComponent exclusion, IConceptFilter filterFunc) throws FHIRException {
|
private void addCodeAndDescendents(CodeSystem cs, String system, ConceptDefinitionComponent def, ValueSetExpansionContainsComponent parent, Parameters expParams, List<ValueSet> filters, ConceptDefinitionComponent exclusion, IConceptFilter filterFunc, boolean noInactive) throws FHIRException {
|
||||||
def.checkNoModifiers("Code in Code System", "expanding");
|
def.checkNoModifiers("Code in Code System", "expanding");
|
||||||
if (exclusion != null) {
|
if (exclusion != null) {
|
||||||
if (exclusion.getCode().equals(def.getCode()))
|
if (exclusion.getCode().equals(def.getCode()))
|
||||||
|
@ -298,30 +305,30 @@ public class ValueSetExpanderSimple extends ValueSetWorker implements ValueSetEx
|
||||||
boolean abs = CodeSystemUtilities.isNotSelectable(cs, def);
|
boolean abs = CodeSystemUtilities.isNotSelectable(cs, def);
|
||||||
boolean inc = CodeSystemUtilities.isInactive(cs, def);
|
boolean inc = CodeSystemUtilities.isInactive(cs, def);
|
||||||
if ((includeAbstract || !abs) && filterFunc.includeConcept(cs, def)) {
|
if ((includeAbstract || !abs) && filterFunc.includeConcept(cs, def)) {
|
||||||
np = addCode(system, def.getCode(), def.getDisplay(), parent, def.getDesignation(), expParams, abs, inc, filters);
|
np = addCode(system, def.getCode(), def.getDisplay(), parent, def.getDesignation(), expParams, abs, inc, filters, noInactive);
|
||||||
}
|
}
|
||||||
for (ConceptDefinitionComponent c : def.getConcept()) {
|
for (ConceptDefinitionComponent c : def.getConcept()) {
|
||||||
addCodeAndDescendents(cs, system, c, np, expParams, filters, exclusion, filterFunc);
|
addCodeAndDescendents(cs, system, c, np, expParams, filters, exclusion, filterFunc, noInactive);
|
||||||
}
|
}
|
||||||
if (def.hasUserData(CodeSystemUtilities.USER_DATA_CROSS_LINK)) {
|
if (def.hasUserData(CodeSystemUtilities.USER_DATA_CROSS_LINK)) {
|
||||||
List<ConceptDefinitionComponent> children = (List<ConceptDefinitionComponent>) def.getUserData(CodeSystemUtilities.USER_DATA_CROSS_LINK);
|
List<ConceptDefinitionComponent> children = (List<ConceptDefinitionComponent>) def.getUserData(CodeSystemUtilities.USER_DATA_CROSS_LINK);
|
||||||
for (ConceptDefinitionComponent c : children)
|
for (ConceptDefinitionComponent c : children)
|
||||||
addCodeAndDescendents(cs, system, c, np, expParams, filters, exclusion, filterFunc);
|
addCodeAndDescendents(cs, system, c, np, expParams, filters, exclusion, filterFunc, noInactive);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (ConceptDefinitionComponent c : def.getConcept()) {
|
for (ConceptDefinitionComponent c : def.getConcept()) {
|
||||||
addCodeAndDescendents(cs, system, c, null, expParams, filters, exclusion, filterFunc);
|
addCodeAndDescendents(cs, system, c, null, expParams, filters, exclusion, filterFunc, noInactive);
|
||||||
}
|
}
|
||||||
if (def.hasUserData(CodeSystemUtilities.USER_DATA_CROSS_LINK)) {
|
if (def.hasUserData(CodeSystemUtilities.USER_DATA_CROSS_LINK)) {
|
||||||
List<ConceptDefinitionComponent> children = (List<ConceptDefinitionComponent>) def.getUserData(CodeSystemUtilities.USER_DATA_CROSS_LINK);
|
List<ConceptDefinitionComponent> children = (List<ConceptDefinitionComponent>) def.getUserData(CodeSystemUtilities.USER_DATA_CROSS_LINK);
|
||||||
for (ConceptDefinitionComponent c : children)
|
for (ConceptDefinitionComponent c : children)
|
||||||
addCodeAndDescendents(cs, system, c, null, expParams, filters, exclusion, filterFunc);
|
addCodeAndDescendents(cs, system, c, null, expParams, filters, exclusion, filterFunc, noInactive);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addCodes(ValueSetExpansionComponent expand, List<ValueSetExpansionParameterComponent> params, Parameters expParams, List<ValueSet> filters) throws ETooCostly, FHIRException {
|
private void addCodes(ValueSetExpansionComponent expand, List<ValueSetExpansionParameterComponent> params, Parameters expParams, List<ValueSet> filters, boolean noInactive) throws ETooCostly, FHIRException {
|
||||||
if (expand != null) {
|
if (expand != null) {
|
||||||
if (expand.getContains().size() > maxExpansionSize)
|
if (expand.getContains().size() > maxExpansionSize)
|
||||||
throw failCostly("Too many codes to display (>" + Integer.toString(expand.getContains().size()) + ")");
|
throw failCostly("Too many codes to display (>" + Integer.toString(expand.getContains().size()) + ")");
|
||||||
|
@ -330,7 +337,7 @@ public class ValueSetExpanderSimple extends ValueSetWorker implements ValueSetEx
|
||||||
params.add(p);
|
params.add(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
copyImportContains(expand.getContains(), null, expParams, filters);
|
copyImportContains(expand.getContains(), null, expParams, filters, noInactive);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -354,7 +361,7 @@ public class ValueSetExpanderSimple extends ValueSetWorker implements ValueSetEx
|
||||||
|
|
||||||
CodeSystem cs = context.fetchCodeSystem(exc.getSystem());
|
CodeSystem cs = context.fetchCodeSystem(exc.getSystem());
|
||||||
if ((cs == null || cs.getContent() != CodeSystemContentMode.COMPLETE) && context.supportsSystem(exc.getSystem())) {
|
if ((cs == null || cs.getContent() != CodeSystemContentMode.COMPLETE) && context.supportsSystem(exc.getSystem())) {
|
||||||
ValueSetExpansionOutcome vse = context.expandVS(exc, false);
|
ValueSetExpansionOutcome vse = context.expandVS(exc, false, false);
|
||||||
ValueSet valueset = vse.getValueset();
|
ValueSet valueset = vse.getValueset();
|
||||||
if (valueset == null)
|
if (valueset == null)
|
||||||
throw failTSE("Error Expanding ValueSet: "+vse.getError());
|
throw failTSE("Error Expanding ValueSet: "+vse.getError());
|
||||||
|
@ -474,11 +481,11 @@ public class ValueSetExpanderSimple extends ValueSetWorker implements ValueSetEx
|
||||||
first = false;
|
first = false;
|
||||||
else
|
else
|
||||||
canBeHeirarchy = false;
|
canBeHeirarchy = false;
|
||||||
includeCodes(inc, exp, expParams, canBeHeirarchy, extensions);
|
includeCodes(inc, exp, expParams, canBeHeirarchy, compose.hasInactive() && !compose.getInactive(), extensions);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private ValueSet importValueSet(String value, ValueSetExpansionComponent exp, Parameters expParams) throws ETooCostly, TerminologyServiceException, FileNotFoundException, IOException, FHIRFormatError {
|
private ValueSet importValueSet(String value, ValueSetExpansionComponent exp, Parameters expParams, boolean noInactive) throws ETooCostly, TerminologyServiceException, FileNotFoundException, IOException, FHIRFormatError {
|
||||||
if (value == null)
|
if (value == null)
|
||||||
throw fail("unable to find value set with no identity");
|
throw fail("unable to find value set with no identity");
|
||||||
ValueSet vs = context.fetchResource(ValueSet.class, value);
|
ValueSet vs = context.fetchResource(ValueSet.class, value);
|
||||||
|
@ -489,6 +496,10 @@ public class ValueSetExpanderSimple extends ValueSetWorker implements ValueSetEx
|
||||||
throw fail("Unable to find imported value set " + value);
|
throw fail("Unable to find imported value set " + value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (noInactive) {
|
||||||
|
expParams = expParams.copy();
|
||||||
|
expParams.addParameter("activeOnly", true);
|
||||||
|
}
|
||||||
ValueSetExpansionOutcome vso = new ValueSetExpanderSimple(context, allErrors).expand(vs, expParams);
|
ValueSetExpansionOutcome vso = new ValueSetExpanderSimple(context, allErrors).expand(vs, expParams);
|
||||||
if (vso.getError() != null) {
|
if (vso.getError() != null) {
|
||||||
addErrors(vso.getAllErrors());
|
addErrors(vso.getAllErrors());
|
||||||
|
@ -543,19 +554,19 @@ public class ValueSetExpanderSimple extends ValueSetWorker implements ValueSetEx
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void copyImportContains(List<ValueSetExpansionContainsComponent> list, ValueSetExpansionContainsComponent parent, Parameters expParams, List<ValueSet> filter) throws FHIRException {
|
private void copyImportContains(List<ValueSetExpansionContainsComponent> list, ValueSetExpansionContainsComponent parent, Parameters expParams, List<ValueSet> filter, boolean noInactive) throws FHIRException {
|
||||||
for (ValueSetExpansionContainsComponent c : list) {
|
for (ValueSetExpansionContainsComponent c : list) {
|
||||||
c.checkNoModifiers("Imported Expansion in Code System", "expanding");
|
c.checkNoModifiers("Imported Expansion in Code System", "expanding");
|
||||||
ValueSetExpansionContainsComponent np = addCode(c.getSystem(), c.getCode(), c.getDisplay(), parent, null, expParams, c.getAbstract(), c.getInactive(), filter);
|
ValueSetExpansionContainsComponent np = addCode(c.getSystem(), c.getCode(), c.getDisplay(), parent, null, expParams, c.getAbstract(), c.getInactive(), filter, noInactive);
|
||||||
copyImportContains(c.getContains(), np, expParams, filter);
|
copyImportContains(c.getContains(), np, expParams, filter, noInactive);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void includeCodes(ConceptSetComponent inc, ValueSetExpansionComponent exp, Parameters expParams, boolean heirarchical, List<Extension> extensions) throws ETooCostly, FileNotFoundException, IOException, FHIRException {
|
private void includeCodes(ConceptSetComponent inc, ValueSetExpansionComponent exp, Parameters expParams, boolean heirarchical, boolean noInactive, List<Extension> extensions) throws ETooCostly, FileNotFoundException, IOException, FHIRException {
|
||||||
inc.checkNoModifiers("Compose.include", "expanding");
|
inc.checkNoModifiers("Compose.include", "expanding");
|
||||||
List<ValueSet> imports = new ArrayList<ValueSet>();
|
List<ValueSet> imports = new ArrayList<ValueSet>();
|
||||||
for (UriType imp : inc.getValueSet()) {
|
for (UriType imp : inc.getValueSet()) {
|
||||||
imports.add(importValueSet(imp.getValue(), exp, expParams));
|
imports.add(importValueSet(imp.getValue(), exp, expParams, noInactive));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!inc.hasSystem()) {
|
if (!inc.hasSystem()) {
|
||||||
|
@ -564,19 +575,19 @@ public class ValueSetExpanderSimple extends ValueSetWorker implements ValueSetEx
|
||||||
ValueSet base = imports.get(0);
|
ValueSet base = imports.get(0);
|
||||||
imports.remove(0);
|
imports.remove(0);
|
||||||
base.checkNoModifiers("Imported ValueSet", "expanding");
|
base.checkNoModifiers("Imported ValueSet", "expanding");
|
||||||
copyImportContains(base.getExpansion().getContains(), null, expParams, imports);
|
copyImportContains(base.getExpansion().getContains(), null, expParams, imports, noInactive);
|
||||||
} else {
|
} else {
|
||||||
CodeSystem cs = context.fetchCodeSystem(inc.getSystem());
|
CodeSystem cs = context.fetchCodeSystem(inc.getSystem());
|
||||||
if (isServerSide(inc.getSystem()) || (cs == null || (cs.getContent() != CodeSystemContentMode.COMPLETE && cs.getContent() != CodeSystemContentMode.FRAGMENT))) {
|
if (isServerSide(inc.getSystem()) || (cs == null || (cs.getContent() != CodeSystemContentMode.COMPLETE && cs.getContent() != CodeSystemContentMode.FRAGMENT))) {
|
||||||
doServerIncludeCodes(inc, heirarchical, exp, imports, expParams, extensions);
|
doServerIncludeCodes(inc, heirarchical, exp, imports, expParams, extensions, noInactive);
|
||||||
} else {
|
} else {
|
||||||
doInternalIncludeCodes(inc, exp, expParams, imports, cs);
|
doInternalIncludeCodes(inc, exp, expParams, imports, cs, noInactive);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void doServerIncludeCodes(ConceptSetComponent inc, boolean heirarchical, ValueSetExpansionComponent exp, List<ValueSet> imports, Parameters expParams, List<Extension> extensions) throws FHIRException {
|
private void doServerIncludeCodes(ConceptSetComponent inc, boolean heirarchical, ValueSetExpansionComponent exp, List<ValueSet> imports, Parameters expParams, List<Extension> extensions, boolean noInactive) throws FHIRException {
|
||||||
ValueSetExpansionOutcome vso = context.expandVS(inc, heirarchical);
|
ValueSetExpansionOutcome vso = context.expandVS(inc, heirarchical, noInactive);
|
||||||
if (vso.getError() != null) {
|
if (vso.getError() != null) {
|
||||||
throw failTSE("Unable to expand imported value set: " + vso.getError());
|
throw failTSE("Unable to expand imported value set: " + vso.getError());
|
||||||
}
|
}
|
||||||
|
@ -599,7 +610,7 @@ public class ValueSetExpanderSimple extends ValueSetWorker implements ValueSetEx
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (ValueSetExpansionContainsComponent cc : vs.getExpansion().getContains()) {
|
for (ValueSetExpansionContainsComponent cc : vs.getExpansion().getContains()) {
|
||||||
addCodeAndDescendents(cc, null, expParams, imports);
|
addCodeAndDescendents(cc, null, expParams, imports, noInactive);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -612,7 +623,7 @@ public class ValueSetExpanderSimple extends ValueSetWorker implements ValueSetEx
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void doInternalIncludeCodes(ConceptSetComponent inc, ValueSetExpansionComponent exp, Parameters expParams, List<ValueSet> imports, CodeSystem cs) throws NoTerminologyServiceException, TerminologyServiceException, FHIRException {
|
public void doInternalIncludeCodes(ConceptSetComponent inc, ValueSetExpansionComponent exp, Parameters expParams, List<ValueSet> imports, CodeSystem cs, boolean noInactive) throws NoTerminologyServiceException, TerminologyServiceException, FHIRException {
|
||||||
if (cs == null) {
|
if (cs == null) {
|
||||||
if (context.isNoTerminologyServer())
|
if (context.isNoTerminologyServer())
|
||||||
throw failTSE("Unable to find code system " + inc.getSystem().toString());
|
throw failTSE("Unable to find code system " + inc.getSystem().toString());
|
||||||
|
@ -629,7 +640,7 @@ public class ValueSetExpanderSimple extends ValueSetWorker implements ValueSetEx
|
||||||
if (inc.getConcept().size() == 0 && inc.getFilter().size() == 0) {
|
if (inc.getConcept().size() == 0 && inc.getFilter().size() == 0) {
|
||||||
// special case - add all the code system
|
// special case - add all the code system
|
||||||
for (ConceptDefinitionComponent def : cs.getConcept()) {
|
for (ConceptDefinitionComponent def : cs.getConcept()) {
|
||||||
addCodeAndDescendents(cs, inc.getSystem(), def, null, expParams, imports, null, new AllConceptsFilter());
|
addCodeAndDescendents(cs, inc.getSystem(), def, null, expParams, imports, null, new AllConceptsFilter(), noInactive);
|
||||||
}
|
}
|
||||||
if (cs.getContent() == CodeSystemContentMode.FRAGMENT) {
|
if (cs.getContent() == CodeSystemContentMode.FRAGMENT) {
|
||||||
addFragmentWarning(exp, cs);
|
addFragmentWarning(exp, cs);
|
||||||
|
@ -658,7 +669,7 @@ public class ValueSetExpanderSimple extends ValueSetWorker implements ValueSetEx
|
||||||
} else {
|
} else {
|
||||||
inactive = CodeSystemUtilities.isInactive(cs, def);
|
inactive = CodeSystemUtilities.isInactive(cs, def);
|
||||||
}
|
}
|
||||||
addCode(inc.getSystem(), c.getCode(), !Utilities.noString(c.getDisplay()) ? c.getDisplay() : def == null ? null : def.getDisplay(), null, convertDesignations(c.getDesignation()), expParams, false, inactive, imports);
|
addCode(inc.getSystem(), c.getCode(), !Utilities.noString(c.getDisplay()) ? c.getDisplay() : def == null ? null : def.getDisplay(), null, convertDesignations(c.getDesignation()), expParams, false, inactive, imports, noInactive);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (inc.getFilter().size() > 1) {
|
if (inc.getFilter().size() > 1) {
|
||||||
|
@ -675,14 +686,14 @@ public class ValueSetExpanderSimple extends ValueSetWorker implements ValueSetEx
|
||||||
ConceptDefinitionComponent def = getConceptForCode(cs.getConcept(), fc.getValue());
|
ConceptDefinitionComponent def = getConceptForCode(cs.getConcept(), fc.getValue());
|
||||||
if (def == null)
|
if (def == null)
|
||||||
throw failTSE("Code '" + fc.getValue() + "' not found in system '" + inc.getSystem() + "'");
|
throw failTSE("Code '" + fc.getValue() + "' not found in system '" + inc.getSystem() + "'");
|
||||||
addCodeAndDescendents(cs, inc.getSystem(), def, null, expParams, imports, null, new AllConceptsFilter());
|
addCodeAndDescendents(cs, inc.getSystem(), def, null, expParams, imports, null, new AllConceptsFilter(), noInactive);
|
||||||
} else if ("concept".equals(fc.getProperty()) && fc.getOp() == FilterOperator.ISNOTA) {
|
} else if ("concept".equals(fc.getProperty()) && fc.getOp() == FilterOperator.ISNOTA) {
|
||||||
// special: all codes in the target code system that are not under the value
|
// special: all codes in the target code system that are not under the value
|
||||||
ConceptDefinitionComponent defEx = getConceptForCode(cs.getConcept(), fc.getValue());
|
ConceptDefinitionComponent defEx = getConceptForCode(cs.getConcept(), fc.getValue());
|
||||||
if (defEx == null)
|
if (defEx == null)
|
||||||
throw failTSE("Code '" + fc.getValue() + "' not found in system '" + inc.getSystem() + "'");
|
throw failTSE("Code '" + fc.getValue() + "' not found in system '" + inc.getSystem() + "'");
|
||||||
for (ConceptDefinitionComponent def : cs.getConcept()) {
|
for (ConceptDefinitionComponent def : cs.getConcept()) {
|
||||||
addCodeAndDescendents(cs, inc.getSystem(), def, null, expParams, imports, defEx, new AllConceptsFilter());
|
addCodeAndDescendents(cs, inc.getSystem(), def, null, expParams, imports, defEx, new AllConceptsFilter(), noInactive);
|
||||||
}
|
}
|
||||||
} else if ("concept".equals(fc.getProperty()) && fc.getOp() == FilterOperator.DESCENDENTOF) {
|
} else if ("concept".equals(fc.getProperty()) && fc.getOp() == FilterOperator.DESCENDENTOF) {
|
||||||
// special: all codes in the target code system under the value
|
// special: all codes in the target code system under the value
|
||||||
|
@ -690,11 +701,11 @@ public class ValueSetExpanderSimple extends ValueSetWorker implements ValueSetEx
|
||||||
if (def == null)
|
if (def == null)
|
||||||
throw failTSE("Code '" + fc.getValue() + "' not found in system '" + inc.getSystem() + "'");
|
throw failTSE("Code '" + fc.getValue() + "' not found in system '" + inc.getSystem() + "'");
|
||||||
for (ConceptDefinitionComponent c : def.getConcept())
|
for (ConceptDefinitionComponent c : def.getConcept())
|
||||||
addCodeAndDescendents(cs, inc.getSystem(), c, null, expParams, imports, null, new AllConceptsFilter());
|
addCodeAndDescendents(cs, inc.getSystem(), c, null, expParams, imports, null, new AllConceptsFilter(), noInactive);
|
||||||
if (def.hasUserData(CodeSystemUtilities.USER_DATA_CROSS_LINK)) {
|
if (def.hasUserData(CodeSystemUtilities.USER_DATA_CROSS_LINK)) {
|
||||||
List<ConceptDefinitionComponent> children = (List<ConceptDefinitionComponent>) def.getUserData(CodeSystemUtilities.USER_DATA_CROSS_LINK);
|
List<ConceptDefinitionComponent> children = (List<ConceptDefinitionComponent>) def.getUserData(CodeSystemUtilities.USER_DATA_CROSS_LINK);
|
||||||
for (ConceptDefinitionComponent c : children)
|
for (ConceptDefinitionComponent c : children)
|
||||||
addCodeAndDescendents(cs, inc.getSystem(), c, null, expParams, imports, null, new AllConceptsFilter());
|
addCodeAndDescendents(cs, inc.getSystem(), c, null, expParams, imports, null, new AllConceptsFilter(), noInactive);
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if ("display".equals(fc.getProperty()) && fc.getOp() == FilterOperator.EQUAL) {
|
} else if ("display".equals(fc.getProperty()) && fc.getOp() == FilterOperator.EQUAL) {
|
||||||
|
@ -705,13 +716,13 @@ public class ValueSetExpanderSimple extends ValueSetWorker implements ValueSetEx
|
||||||
if (isNotBlank(def.getDisplay()) && isNotBlank(fc.getValue())) {
|
if (isNotBlank(def.getDisplay()) && isNotBlank(fc.getValue())) {
|
||||||
if (def.getDisplay().contains(fc.getValue())) {
|
if (def.getDisplay().contains(fc.getValue())) {
|
||||||
addCode(inc.getSystem(), def.getCode(), def.getDisplay(), null, def.getDesignation(), expParams, CodeSystemUtilities.isNotSelectable(cs, def), CodeSystemUtilities.isInactive(cs, def),
|
addCode(inc.getSystem(), def.getCode(), def.getDisplay(), null, def.getDesignation(), expParams, CodeSystemUtilities.isNotSelectable(cs, def), CodeSystemUtilities.isInactive(cs, def),
|
||||||
imports);
|
imports, noInactive);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (isDefinedProperty(cs, fc.getProperty())) {
|
} else if (isDefinedProperty(cs, fc.getProperty())) {
|
||||||
for (ConceptDefinitionComponent def : cs.getConcept()) {
|
for (ConceptDefinitionComponent def : cs.getConcept()) {
|
||||||
addCodeAndDescendents(cs, inc.getSystem(), def, null, expParams, imports, null, new PropertyFilter(fc, getPropertyDefinition(cs, fc.getProperty())));
|
addCodeAndDescendents(cs, inc.getSystem(), def, null, expParams, imports, null, new PropertyFilter(fc, getPropertyDefinition(cs, fc.getProperty())), noInactive);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
throw fail("Search by property[" + fc.getProperty() + "] and op[" + fc.getOp() + "] is not supported yet");
|
throw fail("Search by property[" + fc.getProperty() + "] and op[" + fc.getOp() + "] is not supported yet");
|
||||||
|
|
|
@ -75,11 +75,23 @@ public class TestingUtilities extends BaseTestingUtilities {
|
||||||
|
|
||||||
static public Map<String, IWorkerContext> fcontexts;
|
static public Map<String, IWorkerContext> fcontexts;
|
||||||
|
|
||||||
public static IWorkerContext context() {
|
final static public String DEFAULT_CONTEXT_VERSION = "4.0.1";
|
||||||
return context("4.0.1");
|
|
||||||
|
/** Get an existing instantiation of a WorkerContext if available
|
||||||
|
*
|
||||||
|
* This uses the DEFAULT_CONTEXT_VERSION
|
||||||
|
* */
|
||||||
|
public static IWorkerContext getSharedWorkerContext() {
|
||||||
|
return getSharedWorkerContext(DEFAULT_CONTEXT_VERSION);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IWorkerContext context(String version) {
|
/**
|
||||||
|
* Get an existing instantiation of a WorkerContext if available
|
||||||
|
*
|
||||||
|
* @param version FHIR Version to get context for
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static IWorkerContext getSharedWorkerContext(String version) {
|
||||||
if ("4.5.0".equals(version)) {
|
if ("4.5.0".equals(version)) {
|
||||||
version = "4.4.0"; // temporary work around
|
version = "4.4.0"; // temporary work around
|
||||||
}
|
}
|
||||||
|
@ -89,30 +101,34 @@ public class TestingUtilities extends BaseTestingUtilities {
|
||||||
fcontexts = new HashMap<>();
|
fcontexts = new HashMap<>();
|
||||||
}
|
}
|
||||||
if (!fcontexts.containsKey(v)) {
|
if (!fcontexts.containsKey(v)) {
|
||||||
FilesystemPackageCacheManager pcm;
|
IWorkerContext fcontext = getWorkerContext(version);
|
||||||
try {
|
|
||||||
pcm = new FilesystemPackageCacheManager(true, ToolsVersion.TOOLS_VERSION);
|
|
||||||
IWorkerContext fcontext = getWorkerContext(pcm.loadPackage(VersionUtilities.packageForVersion(version), version));
|
|
||||||
fcontext.setUcumService(new UcumEssenceService(TestingUtilities.loadTestResourceStream("ucum", "ucum-essence.xml")));
|
|
||||||
fcontext.setExpansionProfile(new Parameters());
|
|
||||||
// ((SimpleWorkerContext) fcontext).connectToTSServer(new TerminologyClientR5("http://tx.fhir.org/r4"), null);
|
|
||||||
fcontexts.put(v, fcontext);
|
fcontexts.put(v, fcontext);
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
throw new Error(e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return fcontexts.get(v);
|
return fcontexts.get(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static IWorkerContext getWorkerContext(String version) {
|
||||||
|
FilesystemPackageCacheManager pcm;
|
||||||
|
try {
|
||||||
|
pcm = new FilesystemPackageCacheManager(true, ToolsVersion.TOOLS_VERSION);
|
||||||
|
IWorkerContext fcontext = getWorkerContext(pcm.loadPackage(VersionUtilities.packageForVersion(version), version));
|
||||||
|
fcontext.setUcumService(new UcumEssenceService(TestingUtilities.loadTestResourceStream("ucum", "ucum-essence.xml")));
|
||||||
|
fcontext.setExpansionProfile(new Parameters());
|
||||||
|
return fcontext;
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
throw new Error(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static SimpleWorkerContext getWorkerContext(NpmPackage npmPackage) throws Exception {
|
public static SimpleWorkerContext getWorkerContext(NpmPackage npmPackage) throws Exception {
|
||||||
SimpleWorkerContext swc = new SimpleWorkerContext.SimpleWorkerContextBuilder().withUserAgent(TestConstants.USER_AGENT).withTerminologyCachePath(TestConstants.TX_CACHE).fromPackage(npmPackage);
|
SimpleWorkerContext swc = new SimpleWorkerContext.SimpleWorkerContextBuilder().withAllowLoadingDuplicates(true).withUserAgent(TestConstants.USER_AGENT).withTerminologyCachePath(TestConstants.TX_CACHE).fromPackage(npmPackage);
|
||||||
TerminologyCache.setCacheErrors(true);
|
TerminologyCache.setCacheErrors(true);
|
||||||
return swc;
|
return swc;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static SimpleWorkerContext getWorkerContext(NpmPackage npmPackage, IWorkerContext.IContextResourceLoader loader) throws Exception {
|
public static SimpleWorkerContext getWorkerContext(NpmPackage npmPackage, IWorkerContext.IContextResourceLoader loader) throws Exception {
|
||||||
SimpleWorkerContext swc = new SimpleWorkerContext.SimpleWorkerContextBuilder().withUserAgent(TestConstants.USER_AGENT).withTerminologyCachePath(TestConstants.TX_CACHE).fromPackage(npmPackage, loader);
|
SimpleWorkerContext swc = new SimpleWorkerContext.SimpleWorkerContextBuilder().withAllowLoadingDuplicates(true).withUserAgent(TestConstants.USER_AGENT).withTerminologyCachePath(TestConstants.TX_CACHE).fromPackage(npmPackage, loader);
|
||||||
TerminologyCache.setCacheErrors(true);
|
TerminologyCache.setCacheErrors(true);
|
||||||
return swc;
|
return swc;
|
||||||
}
|
}
|
||||||
|
|
|
@ -235,6 +235,18 @@ public class FHIRPathEngine {
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
public boolean hasType(String tn) {
|
||||||
|
if (type != null) {
|
||||||
|
return tn.equals(type);
|
||||||
|
} else {
|
||||||
|
for (TypeRefComponent t : element.getType()) {
|
||||||
|
if (tn.equals(t.getCode())) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
private IWorkerContext worker;
|
private IWorkerContext worker;
|
||||||
private IEvaluationContext hostServices;
|
private IEvaluationContext hostServices;
|
||||||
|
@ -5472,7 +5484,7 @@ public class FHIRPathEngine {
|
||||||
* @throws PathEngineException
|
* @throws PathEngineException
|
||||||
* @throws DefinitionException
|
* @throws DefinitionException
|
||||||
*/
|
*/
|
||||||
public TypedElementDefinition evaluateDefinition(ExpressionNode expr, StructureDefinition profile, TypedElementDefinition element, StructureDefinition source) throws DefinitionException {
|
public TypedElementDefinition evaluateDefinition(ExpressionNode expr, StructureDefinition profile, TypedElementDefinition element, StructureDefinition source, boolean dontWalkIntoReferences) throws DefinitionException {
|
||||||
StructureDefinition sd = profile;
|
StructureDefinition sd = profile;
|
||||||
TypedElementDefinition focus = null;
|
TypedElementDefinition focus = null;
|
||||||
boolean okToNotResolve = false;
|
boolean okToNotResolve = false;
|
||||||
|
@ -5584,10 +5596,19 @@ public class FHIRPathEngine {
|
||||||
} else {
|
} else {
|
||||||
throw makeException(expr, I18nConstants.FHIRPATH_DISCRIMINATOR_CANT_FIND, expr.toString(), source.getUrl(), element.getElement().getId(), profile.getUrl());
|
throw makeException(expr, I18nConstants.FHIRPATH_DISCRIMINATOR_CANT_FIND, expr.toString(), source.getUrl(), element.getElement().getId(), profile.getUrl());
|
||||||
}
|
}
|
||||||
} else if (expr.getInner() == null) {
|
|
||||||
return focus;
|
|
||||||
} else {
|
} else {
|
||||||
return evaluateDefinition(expr.getInner(), sd, focus, profile);
|
// gdg 26-02-2022. If we're walking towards a resolve() and we're on a reference, and we try to walk into the reference
|
||||||
|
// then we don't do that. .resolve() is allowed on the Reference.reference, but the target of the reference will be defined
|
||||||
|
// on the Reference, not the reference.reference.
|
||||||
|
ExpressionNode next = expr.getInner();
|
||||||
|
if (dontWalkIntoReferences && focus.hasType("Reference") && next != null && next.getKind() == Kind.Name && next.getName().equals("reference")) {
|
||||||
|
next = next.getInner();
|
||||||
|
}
|
||||||
|
if (next == null) {
|
||||||
|
return focus;
|
||||||
|
} else {
|
||||||
|
return evaluateDefinition(next, sd, focus, profile, dontWalkIntoReferences);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -132,7 +132,9 @@ public class TypesUtilities {
|
||||||
res.add(new WildcardInformation("Annotation", TypeClassification.DATATYPE));
|
res.add(new WildcardInformation("Annotation", TypeClassification.DATATYPE));
|
||||||
res.add(new WildcardInformation("Attachment", TypeClassification.DATATYPE));
|
res.add(new WildcardInformation("Attachment", TypeClassification.DATATYPE));
|
||||||
res.add(new WildcardInformation("CodeableConcept", TypeClassification.DATATYPE));
|
res.add(new WildcardInformation("CodeableConcept", TypeClassification.DATATYPE));
|
||||||
res.add(new WildcardInformation("CodeableReference", TypeClassification.DATATYPE));
|
if (!VersionUtilities.isR4BVer(version)) {
|
||||||
|
res.add(new WildcardInformation("CodeableReference", TypeClassification.DATATYPE));
|
||||||
|
}
|
||||||
res.add(new WildcardInformation("Coding", TypeClassification.DATATYPE));
|
res.add(new WildcardInformation("Coding", TypeClassification.DATATYPE));
|
||||||
res.add(new WildcardInformation("ContactPoint", TypeClassification.DATATYPE));
|
res.add(new WildcardInformation("ContactPoint", TypeClassification.DATATYPE));
|
||||||
res.add(new WildcardInformation("Count", TypeClassification.DATATYPE));
|
res.add(new WildcardInformation("Count", TypeClassification.DATATYPE));
|
||||||
|
@ -145,7 +147,9 @@ public class TypesUtilities {
|
||||||
res.add(new WildcardInformation("Quantity", TypeClassification.DATATYPE));
|
res.add(new WildcardInformation("Quantity", TypeClassification.DATATYPE));
|
||||||
res.add(new WildcardInformation("Range", TypeClassification.DATATYPE));
|
res.add(new WildcardInformation("Range", TypeClassification.DATATYPE));
|
||||||
res.add(new WildcardInformation("Ratio", TypeClassification.DATATYPE));
|
res.add(new WildcardInformation("Ratio", TypeClassification.DATATYPE));
|
||||||
res.add(new WildcardInformation("RatioRange", TypeClassification.DATATYPE));
|
if (!VersionUtilities.isR4BVer(version)) {
|
||||||
|
res.add(new WildcardInformation("RatioRange", TypeClassification.DATATYPE));
|
||||||
|
}
|
||||||
res.add(new WildcardInformation("Reference", " - a reference to another resource", TypeClassification.DATATYPE));
|
res.add(new WildcardInformation("Reference", " - a reference to another resource", TypeClassification.DATATYPE));
|
||||||
res.add(new WildcardInformation("SampledData", TypeClassification.DATATYPE));
|
res.add(new WildcardInformation("SampledData", TypeClassification.DATATYPE));
|
||||||
res.add(new WildcardInformation("Signature", TypeClassification.DATATYPE));
|
res.add(new WildcardInformation("Signature", TypeClassification.DATATYPE));
|
||||||
|
|
|
@ -50,9 +50,6 @@ public class XVerExtensionManager {
|
||||||
return XVerExtensionStatus.Invalid;
|
return XVerExtensionStatus.Invalid;
|
||||||
}
|
}
|
||||||
String v = url.substring(20, 23);
|
String v = url.substring(20, 23);
|
||||||
if ("5.0".equals(v)) {
|
|
||||||
v = "4.6"; // for now
|
|
||||||
}
|
|
||||||
String e = url.substring(54);
|
String e = url.substring(54);
|
||||||
if (!lists.containsKey(v)) {
|
if (!lists.containsKey(v)) {
|
||||||
if (context.getBinaries().containsKey("xver-paths-"+v+".json")) {
|
if (context.getBinaries().containsKey("xver-paths-"+v+".json")) {
|
||||||
|
@ -86,9 +83,6 @@ public class XVerExtensionManager {
|
||||||
|
|
||||||
public StructureDefinition makeDefinition(String url) {
|
public StructureDefinition makeDefinition(String url) {
|
||||||
String verSource = url.substring(20, 23);
|
String verSource = url.substring(20, 23);
|
||||||
if ("5.0".equals(verSource)) {
|
|
||||||
verSource = "4.6"; // for now
|
|
||||||
}
|
|
||||||
String verTarget = VersionUtilities.getMajMin(context.getVersion());
|
String verTarget = VersionUtilities.getMajMin(context.getVersion());
|
||||||
String e = url.substring(54);
|
String e = url.substring(54);
|
||||||
JsonObject root = lists.get(verSource);
|
JsonObject root = lists.get(verSource);
|
||||||
|
@ -123,16 +117,18 @@ public class XVerExtensionManager {
|
||||||
populateTypes(path, val, verSource, verTarget);
|
populateTypes(path, val, verSource, verTarget);
|
||||||
} else if (path.has("elements")) {
|
} else if (path.has("elements")) {
|
||||||
for (JsonElement i : path.getAsJsonArray("elements")) {
|
for (JsonElement i : path.getAsJsonArray("elements")) {
|
||||||
String s = i.getAsString();
|
JsonObject elt = root.getAsJsonObject(e+"."+i.getAsString());
|
||||||
|
if (elt != null) {
|
||||||
|
String s = i.getAsString().replace("[x]", "");
|
||||||
sd.getDifferential().addElement().setPath("Extension.extension").setSliceName(s);
|
sd.getDifferential().addElement().setPath("Extension.extension").setSliceName(s);
|
||||||
sd.getDifferential().addElement().setPath("Extension.extension.extension").setMax("0");
|
sd.getDifferential().addElement().setPath("Extension.extension.extension").setMax("0");
|
||||||
sd.getDifferential().addElement().setPath("Extension.extension.url").setFixed(new UriType(s));
|
sd.getDifferential().addElement().setPath("Extension.extension.url").setFixed(new UriType(s));
|
||||||
ElementDefinition val = sd.getDifferential().addElement().setPath("Extension.extension.value[x]").setMin(1);
|
ElementDefinition val = sd.getDifferential().addElement().setPath("Extension.extension.value[x]").setMin(1);
|
||||||
JsonObject elt = root.getAsJsonObject(e+"."+s);
|
|
||||||
if (!elt.has("types")) {
|
if (!elt.has("types")) {
|
||||||
throw new FHIRException("Internal error - nested elements not supported yet");
|
throw new FHIRException("Internal error - nested elements not supported yet");
|
||||||
}
|
}
|
||||||
populateTypes(elt, val, verSource, verTarget);
|
populateTypes(elt, val, verSource, verTarget);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
sd.getDifferential().addElement().setPath("Extension.url").setFixed(new UriType(url));
|
sd.getDifferential().addElement().setPath("Extension.url").setFixed(new UriType(url));
|
||||||
sd.getDifferential().addElement().setPath("Extension.value[x]").setMax("0");
|
sd.getDifferential().addElement().setPath("Extension.value[x]").setMax("0");
|
||||||
|
|
|
@ -1,13 +1,31 @@
|
||||||
package org.hl7.fhir.r5.context;
|
package org.hl7.fhir.r5.context;
|
||||||
|
|
||||||
import org.hl7.fhir.r5.model.*;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
|
import static org.mockito.ArgumentMatchers.anyBoolean;
|
||||||
|
import static org.mockito.ArgumentMatchers.argThat;
|
||||||
|
import static org.mockito.ArgumentMatchers.eq;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.times;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.hl7.fhir.r5.model.CapabilityStatement;
|
||||||
|
import org.hl7.fhir.r5.model.CodeableConcept;
|
||||||
|
import org.hl7.fhir.r5.model.Coding;
|
||||||
|
import org.hl7.fhir.r5.model.Enumerations;
|
||||||
|
import org.hl7.fhir.r5.model.Parameters;
|
||||||
|
import org.hl7.fhir.r5.model.TerminologyCapabilities;
|
||||||
|
import org.hl7.fhir.r5.model.ValueSet;
|
||||||
import org.hl7.fhir.r5.terminologies.TerminologyClient;
|
import org.hl7.fhir.r5.terminologies.TerminologyClient;
|
||||||
import org.hl7.fhir.r5.terminologies.ValueSetCheckerSimple;
|
import org.hl7.fhir.r5.terminologies.ValueSetCheckerSimple;
|
||||||
import org.hl7.fhir.r5.terminologies.ValueSetExpander;
|
import org.hl7.fhir.r5.terminologies.ValueSetExpander;
|
||||||
import org.hl7.fhir.r5.terminologies.ValueSetExpanderSimple;
|
import org.hl7.fhir.r5.terminologies.ValueSetExpanderSimple;
|
||||||
import org.hl7.fhir.r5.utils.validation.ValidationContextCarrier;
|
import org.hl7.fhir.r5.utils.validation.ValidationContextCarrier;
|
||||||
import org.hl7.fhir.utilities.ToolingClientLogger;
|
import org.hl7.fhir.utilities.ToolingClientLogger;
|
||||||
import org.hl7.fhir.utilities.graphql.Value;
|
|
||||||
import org.hl7.fhir.utilities.validation.ValidationOptions;
|
import org.hl7.fhir.utilities.validation.ValidationOptions;
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
@ -18,15 +36,6 @@ import org.mockito.Mockito;
|
||||||
import org.mockito.Spy;
|
import org.mockito.Spy;
|
||||||
import org.mockito.junit.jupiter.MockitoExtension;
|
import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
|
||||||
import static org.mockito.ArgumentMatchers.*;
|
|
||||||
import static org.mockito.Mockito.*;
|
|
||||||
|
|
||||||
@ExtendWith(MockitoExtension.class)
|
@ExtendWith(MockitoExtension.class)
|
||||||
public class SimpleWorkerContextTests {
|
public class SimpleWorkerContextTests {
|
||||||
|
|
||||||
|
@ -251,12 +260,13 @@ public class SimpleWorkerContextTests {
|
||||||
ValueSet vs = new ValueSet();
|
ValueSet vs = new ValueSet();
|
||||||
vs.setStatus(Enumerations.PublicationStatus.ACTIVE);
|
vs.setStatus(Enumerations.PublicationStatus.ACTIVE);
|
||||||
vs.setCompose(new ValueSet.ValueSetComposeComponent());
|
vs.setCompose(new ValueSet.ValueSetComposeComponent());
|
||||||
|
vs.getCompose().setInactive(true);
|
||||||
vs.getCompose().getInclude().add(inc);
|
vs.getCompose().getInclude().add(inc);
|
||||||
|
|
||||||
Mockito.doReturn(cacheToken).when(terminologyCache).generateExpandToken(argThat(new ValueSetMatcher(vs)),eq(true));
|
Mockito.doReturn(cacheToken).when(terminologyCache).generateExpandToken(argThat(new ValueSetMatcher(vs)),eq(true));
|
||||||
Mockito.doReturn(expectedExpansionResult).when(terminologyCache).getExpansion(cacheToken);
|
Mockito.doReturn(expectedExpansionResult).when(terminologyCache).getExpansion(cacheToken);
|
||||||
|
|
||||||
ValueSetExpander.ValueSetExpansionOutcome actualExpansionResult = context.expandVS(inc, true);
|
ValueSetExpander.ValueSetExpansionOutcome actualExpansionResult = context.expandVS(inc, true, false);
|
||||||
|
|
||||||
assertEquals(expectedExpansionResult, actualExpansionResult);
|
assertEquals(expectedExpansionResult, actualExpansionResult);
|
||||||
|
|
||||||
|
@ -273,6 +283,7 @@ public class SimpleWorkerContextTests {
|
||||||
ValueSet vs = new ValueSet();
|
ValueSet vs = new ValueSet();
|
||||||
vs.setStatus(Enumerations.PublicationStatus.ACTIVE);
|
vs.setStatus(Enumerations.PublicationStatus.ACTIVE);
|
||||||
vs.setCompose(new ValueSet.ValueSetComposeComponent());
|
vs.setCompose(new ValueSet.ValueSetComposeComponent());
|
||||||
|
vs.getCompose().setInactive(true);
|
||||||
vs.getCompose().getInclude().add(inc);
|
vs.getCompose().getInclude().add(inc);
|
||||||
|
|
||||||
Mockito.doReturn(cacheToken).when(terminologyCache).generateExpandToken(argThat(new ValueSetMatcher(vs)),eq(true));
|
Mockito.doReturn(cacheToken).when(terminologyCache).generateExpandToken(argThat(new ValueSetMatcher(vs)),eq(true));
|
||||||
|
@ -285,7 +296,7 @@ public class SimpleWorkerContextTests {
|
||||||
Mockito.doReturn(expectedValueSet).when(terminologyClient).expandValueset(argThat(new ValueSetMatcher(vs)),
|
Mockito.doReturn(expectedValueSet).when(terminologyClient).expandValueset(argThat(new ValueSetMatcher(vs)),
|
||||||
argThat(new ParametersMatcher(pInWithDependentResources)), eq(params));
|
argThat(new ParametersMatcher(pInWithDependentResources)), eq(params));
|
||||||
|
|
||||||
ValueSetExpander.ValueSetExpansionOutcome actualExpansionResult = context.expandVS(inc, true);
|
ValueSetExpander.ValueSetExpansionOutcome actualExpansionResult = context.expandVS(inc, true, false);
|
||||||
|
|
||||||
assertEquals(expectedValueSet, actualExpansionResult.getValueset());
|
assertEquals(expectedValueSet, actualExpansionResult.getValueset());
|
||||||
|
|
||||||
|
|
|
@ -1,15 +1,9 @@
|
||||||
package org.hl7.fhir.r5.context;
|
package org.hl7.fhir.r5.context;
|
||||||
|
|
||||||
import com.google.gson.JsonElement;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
import com.google.gson.JsonParser;
|
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||||
import org.hl7.fhir.r5.formats.IParser;
|
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||||
import org.hl7.fhir.r5.model.*;
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
import org.hl7.fhir.r5.terminologies.ValueSetExpander;
|
|
||||||
import org.hl7.fhir.utilities.validation.ValidationMessage;
|
|
||||||
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.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -25,8 +19,22 @@ import java.util.stream.Collectors;
|
||||||
import java.util.stream.IntStream;
|
import java.util.stream.IntStream;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.*;
|
import org.hl7.fhir.r5.formats.IParser;
|
||||||
import static org.mockito.Mockito.mock;
|
import org.hl7.fhir.r5.model.CanonicalResource;
|
||||||
|
import org.hl7.fhir.r5.model.CapabilityStatement;
|
||||||
|
import org.hl7.fhir.r5.model.CodeableConcept;
|
||||||
|
import org.hl7.fhir.r5.model.Coding;
|
||||||
|
import org.hl7.fhir.r5.model.TerminologyCapabilities;
|
||||||
|
import org.hl7.fhir.r5.model.ValueSet;
|
||||||
|
import org.hl7.fhir.r5.terminologies.ValueSetExpander;
|
||||||
|
import org.hl7.fhir.utilities.validation.ValidationMessage;
|
||||||
|
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 com.google.gson.JsonElement;
|
||||||
|
import com.google.gson.JsonParser;
|
||||||
|
|
||||||
public class TerminologyCacheTests {
|
public class TerminologyCacheTests {
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,46 @@
|
||||||
|
package org.hl7.fhir.r5.context;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
|
||||||
|
import org.hl7.fhir.exceptions.FHIRException;
|
||||||
|
import org.hl7.fhir.r5.context.IWorkerContext.IContextResourceLoader;
|
||||||
|
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.Resource;
|
||||||
|
import org.hl7.fhir.utilities.npm.NpmPackage;
|
||||||
|
|
||||||
|
public class TestPackageLoader implements IContextResourceLoader {
|
||||||
|
|
||||||
|
private String[] types;
|
||||||
|
|
||||||
|
public TestPackageLoader(String[] types) {
|
||||||
|
this.types = types;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Bundle loadBundle(InputStream stream, boolean isJson) throws FHIRException, IOException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Resource loadResource(InputStream stream, boolean isJson) throws FHIRException, IOException {
|
||||||
|
return isJson ? new JsonParser().parse(stream) : new XmlParser().parse(stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String[] getTypes() {
|
||||||
|
return types;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getResourcePath(Resource resource) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IContextResourceLoader getNewLoader(NpmPackage npm) {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,14 +1,11 @@
|
||||||
package org.hl7.fhir.r5.formats;
|
package org.hl7.fhir.r5.formats;
|
||||||
|
|
||||||
import org.junit.jupiter.api.Assertions;
|
|
||||||
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.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.*;
|
import org.junit.jupiter.api.Assertions;
|
||||||
|
import org.junit.jupiter.params.ParameterizedTest;
|
||||||
|
import org.junit.jupiter.params.provider.Arguments;
|
||||||
|
import org.junit.jupiter.params.provider.MethodSource;
|
||||||
|
|
||||||
class FormatUtilitiesTest {
|
class FormatUtilitiesTest {
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
package org.hl7.fhir.r5.model;
|
package org.hl7.fhir.r5.model;
|
||||||
|
|
||||||
import org.hl7.fhir.r5.model.Base64BinaryType;
|
|
||||||
import org.junit.jupiter.api.Assertions;
|
import org.junit.jupiter.api.Assertions;
|
||||||
import org.junit.jupiter.api.DisplayName;
|
import org.junit.jupiter.api.DisplayName;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
package org.hl7.fhir.r5.model;
|
package org.hl7.fhir.r5.model;
|
||||||
|
|
||||||
import org.hl7.fhir.r5.model.BooleanType;
|
|
||||||
import org.junit.jupiter.api.Assertions;
|
import org.junit.jupiter.api.Assertions;
|
||||||
import org.junit.jupiter.api.DisplayName;
|
import org.junit.jupiter.api.DisplayName;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
package org.hl7.fhir.r5.model;
|
package org.hl7.fhir.r5.model;
|
||||||
|
|
||||||
import org.hl7.fhir.r5.model.CanonicalType;
|
|
||||||
import org.junit.jupiter.api.Assertions;
|
import org.junit.jupiter.api.Assertions;
|
||||||
import org.junit.jupiter.api.DisplayName;
|
import org.junit.jupiter.api.DisplayName;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
package org.hl7.fhir.r5.model;
|
package org.hl7.fhir.r5.model;
|
||||||
|
|
||||||
import org.hl7.fhir.r5.model.CodeType;
|
|
||||||
import org.junit.jupiter.api.Assertions;
|
import org.junit.jupiter.api.Assertions;
|
||||||
import org.junit.jupiter.api.DisplayName;
|
import org.junit.jupiter.api.DisplayName;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
package org.hl7.fhir.r5.model;
|
package org.hl7.fhir.r5.model;
|
||||||
|
|
||||||
import org.hl7.fhir.r5.model.DateTimeType;
|
|
||||||
import org.junit.jupiter.api.Assertions;
|
import org.junit.jupiter.api.Assertions;
|
||||||
import org.junit.jupiter.api.DisplayName;
|
import org.junit.jupiter.api.DisplayName;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
package org.hl7.fhir.r5.model;
|
package org.hl7.fhir.r5.model;
|
||||||
|
|
||||||
import org.hl7.fhir.r5.model.DateType;
|
|
||||||
import org.junit.jupiter.api.Assertions;
|
import org.junit.jupiter.api.Assertions;
|
||||||
import org.junit.jupiter.api.DisplayName;
|
import org.junit.jupiter.api.DisplayName;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
package org.hl7.fhir.r5.model;
|
package org.hl7.fhir.r5.model;
|
||||||
|
|
||||||
import org.hl7.fhir.r5.model.DecimalType;
|
|
||||||
import org.junit.jupiter.api.Assertions;
|
import org.junit.jupiter.api.Assertions;
|
||||||
import org.junit.jupiter.api.DisplayName;
|
import org.junit.jupiter.api.DisplayName;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
package org.hl7.fhir.r5.model;
|
package org.hl7.fhir.r5.model;
|
||||||
|
|
||||||
import org.hl7.fhir.r5.model.IdType;
|
|
||||||
import org.junit.jupiter.api.Assertions;
|
import org.junit.jupiter.api.Assertions;
|
||||||
import org.junit.jupiter.api.DisplayName;
|
import org.junit.jupiter.api.DisplayName;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
package org.hl7.fhir.r5.model;
|
package org.hl7.fhir.r5.model;
|
||||||
|
|
||||||
import org.hl7.fhir.r5.model.InstantType;
|
|
||||||
import org.junit.jupiter.api.Assertions;
|
import org.junit.jupiter.api.Assertions;
|
||||||
import org.junit.jupiter.api.DisplayName;
|
import org.junit.jupiter.api.DisplayName;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
package org.hl7.fhir.r5.model;
|
package org.hl7.fhir.r5.model;
|
||||||
|
|
||||||
import org.hl7.fhir.r5.model.IntegerType;
|
|
||||||
import org.junit.jupiter.api.Assertions;
|
import org.junit.jupiter.api.Assertions;
|
||||||
import org.junit.jupiter.api.DisplayName;
|
import org.junit.jupiter.api.DisplayName;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
package org.hl7.fhir.r5.model;
|
package org.hl7.fhir.r5.model;
|
||||||
|
|
||||||
import org.hl7.fhir.r5.model.MarkdownType;
|
|
||||||
import org.junit.jupiter.api.Assertions;
|
import org.junit.jupiter.api.Assertions;
|
||||||
import org.junit.jupiter.api.DisplayName;
|
import org.junit.jupiter.api.DisplayName;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
package org.hl7.fhir.r5.model;
|
package org.hl7.fhir.r5.model;
|
||||||
|
|
||||||
import org.hl7.fhir.r5.model.OidType;
|
|
||||||
import org.junit.jupiter.api.Assertions;
|
import org.junit.jupiter.api.Assertions;
|
||||||
import org.junit.jupiter.api.DisplayName;
|
import org.junit.jupiter.api.DisplayName;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
package org.hl7.fhir.r5.model;
|
package org.hl7.fhir.r5.model;
|
||||||
|
|
||||||
import org.hl7.fhir.r5.model.PositiveIntType;
|
|
||||||
import org.junit.jupiter.api.Assertions;
|
import org.junit.jupiter.api.Assertions;
|
||||||
import org.junit.jupiter.api.DisplayName;
|
import org.junit.jupiter.api.DisplayName;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
package org.hl7.fhir.r5.model;
|
package org.hl7.fhir.r5.model;
|
||||||
|
|
||||||
import org.hl7.fhir.r5.model.StringType;
|
|
||||||
import org.junit.jupiter.api.Assertions;
|
import org.junit.jupiter.api.Assertions;
|
||||||
import org.junit.jupiter.api.DisplayName;
|
import org.junit.jupiter.api.DisplayName;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
package org.hl7.fhir.r5.model;
|
package org.hl7.fhir.r5.model;
|
||||||
|
|
||||||
import org.hl7.fhir.r5.model.TimeType;
|
|
||||||
import org.junit.jupiter.api.Assertions;
|
import org.junit.jupiter.api.Assertions;
|
||||||
import org.junit.jupiter.api.DisplayName;
|
import org.junit.jupiter.api.DisplayName;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
package org.hl7.fhir.r5.model;
|
package org.hl7.fhir.r5.model;
|
||||||
|
|
||||||
import org.hl7.fhir.r5.model.UnsignedIntType;
|
|
||||||
import org.junit.jupiter.api.Assertions;
|
import org.junit.jupiter.api.Assertions;
|
||||||
import org.junit.jupiter.api.DisplayName;
|
import org.junit.jupiter.api.DisplayName;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
package org.hl7.fhir.r5.model;
|
package org.hl7.fhir.r5.model;
|
||||||
|
|
||||||
import org.hl7.fhir.r5.model.UriType;
|
|
||||||
import org.junit.jupiter.api.Assertions;
|
import org.junit.jupiter.api.Assertions;
|
||||||
import org.junit.jupiter.api.DisplayName;
|
import org.junit.jupiter.api.DisplayName;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
package org.hl7.fhir.r5.model;
|
package org.hl7.fhir.r5.model;
|
||||||
|
|
||||||
import org.hl7.fhir.r5.model.UrlType;
|
|
||||||
import org.junit.jupiter.api.Assertions;
|
import org.junit.jupiter.api.Assertions;
|
||||||
import org.junit.jupiter.api.DisplayName;
|
import org.junit.jupiter.api.DisplayName;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
package org.hl7.fhir.r5.model;
|
package org.hl7.fhir.r5.model;
|
||||||
|
|
||||||
import org.hl7.fhir.r5.model.UuidType;
|
|
||||||
import org.junit.jupiter.api.Assertions;
|
import org.junit.jupiter.api.Assertions;
|
||||||
import org.junit.jupiter.api.DisplayName;
|
import org.junit.jupiter.api.DisplayName;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
|
@ -257,7 +257,7 @@ public class CDARoundTripTests {
|
||||||
value.setValue("öé");
|
value.setValue("öé");
|
||||||
|
|
||||||
ByteArrayOutputStream baosXml = new ByteArrayOutputStream();
|
ByteArrayOutputStream baosXml = new ByteArrayOutputStream();
|
||||||
Manager.compose(TestingUtilities.context(), xml, baosXml, FhirFormat.XML, OutputStyle.PRETTY, null);
|
Manager.compose(TestingUtilities.getSharedWorkerContext(), xml, baosXml, FhirFormat.XML, OutputStyle.PRETTY, null);
|
||||||
String cdaSerialised = baosXml.toString("UTF-8");
|
String cdaSerialised = baosXml.toString("UTF-8");
|
||||||
Assertions.assertTrue(cdaSerialised.indexOf("öé") > 0);
|
Assertions.assertTrue(cdaSerialised.indexOf("öé") > 0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,6 @@ import org.hl7.fhir.r5.model.Quantity;
|
||||||
import org.hl7.fhir.r5.model.Resource;
|
import org.hl7.fhir.r5.model.Resource;
|
||||||
import org.hl7.fhir.r5.model.TypeDetails;
|
import org.hl7.fhir.r5.model.TypeDetails;
|
||||||
import org.hl7.fhir.r5.model.ValueSet;
|
import org.hl7.fhir.r5.model.ValueSet;
|
||||||
import org.hl7.fhir.r5.test.FHIRPathTests.TestResultType;
|
|
||||||
import org.hl7.fhir.r5.test.utils.TestingUtilities;
|
import org.hl7.fhir.r5.test.utils.TestingUtilities;
|
||||||
import org.hl7.fhir.r5.utils.FHIRPathEngine;
|
import org.hl7.fhir.r5.utils.FHIRPathEngine;
|
||||||
import org.hl7.fhir.r5.utils.FHIRPathEngine.IEvaluationContext;
|
import org.hl7.fhir.r5.utils.FHIRPathEngine.IEvaluationContext;
|
||||||
|
@ -94,7 +93,7 @@ public class FHIRPathTests {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ValueSet resolveValueSet(Object appContext, String url) {
|
public ValueSet resolveValueSet(Object appContext, String url) {
|
||||||
return TestingUtilities.context().fetchResource(ValueSet.class, url);
|
return TestingUtilities.getSharedWorkerContext().fetchResource(ValueSet.class, url);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -104,7 +103,7 @@ public class FHIRPathTests {
|
||||||
|
|
||||||
@BeforeAll
|
@BeforeAll
|
||||||
public static void setUp() {
|
public static void setUp() {
|
||||||
fp = new FHIRPathEngine(TestingUtilities.context());
|
fp = new FHIRPathEngine(TestingUtilities.getSharedWorkerContext());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Stream<Arguments> data() throws ParserConfigurationException, SAXException, IOException {
|
public static Stream<Arguments> data() throws ParserConfigurationException, SAXException, IOException {
|
||||||
|
|
|
@ -65,7 +65,7 @@ public class GraphQLEngineTests implements IGraphQLStorageServices {
|
||||||
stream = TestingUtilities.loadTestResourceStream("r5", parts[0].toLowerCase()+"-"+parts[1].toLowerCase()+".xml");
|
stream = TestingUtilities.loadTestResourceStream("r5", parts[0].toLowerCase()+"-"+parts[1].toLowerCase()+".xml");
|
||||||
}
|
}
|
||||||
|
|
||||||
GraphQLEngine gql = new GraphQLEngine(TestingUtilities.context());
|
GraphQLEngine gql = new GraphQLEngine(TestingUtilities.getSharedWorkerContext());
|
||||||
gql.setServices(this);
|
gql.setServices(this);
|
||||||
if (stream != null)
|
if (stream != null)
|
||||||
gql.setFocus(new XmlParser().parse(stream));
|
gql.setFocus(new XmlParser().parse(stream));
|
||||||
|
|
|
@ -37,7 +37,7 @@ public class LiquidEngineTests implements ILiquidEngineIncludeResolver {
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
public void setUp() throws Exception {
|
public void setUp() throws Exception {
|
||||||
engine = new LiquidEngine(TestingUtilities.context(), null);
|
engine = new LiquidEngine(TestingUtilities.getSharedWorkerContext(), null);
|
||||||
engine.setIncludeResolver(this);
|
engine.setIncludeResolver(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,51 +1,35 @@
|
||||||
package org.hl7.fhir.r5.test;
|
package org.hl7.fhir.r5.test;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
|
||||||
import java.io.FileInputStream;
|
|
||||||
import java.io.FileNotFoundException;
|
|
||||||
import java.io.FileOutputStream;
|
|
||||||
import java.io.FileReader;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.time.ZoneId;
|
import java.time.ZoneId;
|
||||||
import java.time.format.DateTimeFormatter;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import javax.xml.parsers.ParserConfigurationException;
|
import javax.xml.parsers.ParserConfigurationException;
|
||||||
|
|
||||||
import org.apache.commons.io.IOUtils;
|
|
||||||
import org.apache.commons.lang3.SystemUtils;
|
|
||||||
import org.hl7.fhir.exceptions.FHIRException;
|
import org.hl7.fhir.exceptions.FHIRException;
|
||||||
import org.hl7.fhir.exceptions.FHIRFormatError;
|
import org.hl7.fhir.exceptions.FHIRFormatError;
|
||||||
import org.hl7.fhir.r5.context.IWorkerContext;
|
import org.hl7.fhir.r5.context.IWorkerContext;
|
||||||
import org.hl7.fhir.r5.elementmodel.Manager;
|
import org.hl7.fhir.r5.elementmodel.Manager;
|
||||||
import org.hl7.fhir.r5.elementmodel.Manager.FhirFormat;
|
import org.hl7.fhir.r5.elementmodel.Manager.FhirFormat;
|
||||||
import org.hl7.fhir.r5.formats.IParser.OutputStyle;
|
|
||||||
import org.hl7.fhir.r5.formats.JsonParser;
|
import org.hl7.fhir.r5.formats.JsonParser;
|
||||||
import org.hl7.fhir.r5.formats.XmlParser;
|
import org.hl7.fhir.r5.formats.XmlParser;
|
||||||
import org.hl7.fhir.r5.model.Base;
|
import org.hl7.fhir.r5.model.Base;
|
||||||
import org.hl7.fhir.r5.model.DomainResource;
|
|
||||||
import org.hl7.fhir.r5.model.Questionnaire;
|
|
||||||
import org.hl7.fhir.r5.model.Resource;
|
import org.hl7.fhir.r5.model.Resource;
|
||||||
import org.hl7.fhir.r5.renderers.RendererFactory;
|
import org.hl7.fhir.r5.renderers.RendererFactory;
|
||||||
import org.hl7.fhir.r5.renderers.ResourceRenderer;
|
|
||||||
import org.hl7.fhir.r5.renderers.utils.ElementWrappers;
|
import org.hl7.fhir.r5.renderers.utils.ElementWrappers;
|
||||||
import org.hl7.fhir.r5.renderers.utils.RenderingContext;
|
import org.hl7.fhir.r5.renderers.utils.RenderingContext;
|
||||||
import org.hl7.fhir.r5.renderers.utils.RenderingContext.ITypeParser;
|
import org.hl7.fhir.r5.renderers.utils.RenderingContext.ITypeParser;
|
||||||
import org.hl7.fhir.r5.renderers.utils.RenderingContext.QuestionnaireRendererMode;
|
|
||||||
import org.hl7.fhir.r5.renderers.utils.RenderingContext.ResourceRendererMode;
|
import org.hl7.fhir.r5.renderers.utils.RenderingContext.ResourceRendererMode;
|
||||||
import org.hl7.fhir.r5.test.NarrativeGenerationTests.TestTypeParser;
|
|
||||||
import org.hl7.fhir.r5.test.utils.TestingUtilities;
|
import org.hl7.fhir.r5.test.utils.TestingUtilities;
|
||||||
import org.hl7.fhir.utilities.TerminologyServiceOptions;
|
import org.hl7.fhir.utilities.TerminologyServiceOptions;
|
||||||
import org.hl7.fhir.utilities.TextFile;
|
import org.hl7.fhir.utilities.TextFile;
|
||||||
import org.hl7.fhir.utilities.xhtml.XhtmlComposer;
|
import org.hl7.fhir.utilities.xhtml.XhtmlComposer;
|
||||||
import org.hl7.fhir.utilities.xhtml.XhtmlNode;
|
import org.hl7.fhir.utilities.xhtml.XhtmlNode;
|
||||||
import org.hl7.fhir.utilities.xhtml.XhtmlParser;
|
|
||||||
import org.hl7.fhir.utilities.xml.XMLUtil;
|
import org.hl7.fhir.utilities.xml.XMLUtil;
|
||||||
import org.junit.jupiter.api.Assertions;
|
import org.junit.jupiter.api.Assertions;
|
||||||
import org.junit.jupiter.api.BeforeAll;
|
import org.junit.jupiter.api.BeforeAll;
|
||||||
import org.junit.jupiter.api.Disabled;
|
|
||||||
import org.junit.jupiter.params.ParameterizedTest;
|
import org.junit.jupiter.params.ParameterizedTest;
|
||||||
import org.junit.jupiter.params.provider.Arguments;
|
import org.junit.jupiter.params.provider.Arguments;
|
||||||
import org.junit.jupiter.params.provider.MethodSource;
|
import org.junit.jupiter.params.provider.MethodSource;
|
||||||
|
@ -119,7 +103,7 @@ public class NarrativeGenerationTests {
|
||||||
|
|
||||||
@BeforeAll
|
@BeforeAll
|
||||||
public static void setUp() {
|
public static void setUp() {
|
||||||
context = TestingUtilities.context();
|
context = TestingUtilities.getSharedWorkerContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ParameterizedTest(name = "{index}: file {0}")
|
@ParameterizedTest(name = "{index}: file {0}")
|
||||||
|
|
|
@ -5,11 +5,7 @@ import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.time.ZoneId;
|
import java.time.ZoneId;
|
||||||
import java.time.ZonedDateTime;
|
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.time.format.FormatStyle;
|
|
||||||
import java.util.Locale;
|
|
||||||
import java.util.TimeZone;
|
|
||||||
|
|
||||||
import org.hl7.fhir.exceptions.DefinitionException;
|
import org.hl7.fhir.exceptions.DefinitionException;
|
||||||
import org.hl7.fhir.exceptions.FHIRException;
|
import org.hl7.fhir.exceptions.FHIRException;
|
||||||
|
@ -38,7 +34,7 @@ public class NarrativeGeneratorTests {
|
||||||
|
|
||||||
@BeforeAll
|
@BeforeAll
|
||||||
public static void setUp() throws FHIRException {
|
public static void setUp() throws FHIRException {
|
||||||
rc = new RenderingContext(TestingUtilities.context(), null, null, "http://hl7.org/fhir", "", null, ResourceRendererMode.END_USER);
|
rc = new RenderingContext(TestingUtilities.getSharedWorkerContext(), null, null, "http://hl7.org/fhir", "", null, ResourceRendererMode.END_USER);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
@ -32,7 +32,7 @@ public class OpenApiGeneratorTest {
|
||||||
public void run(InputStream sfn, String dfn) throws IOException, FHIRFormatError, FileNotFoundException {
|
public void run(InputStream sfn, String dfn) throws IOException, FHIRFormatError, FileNotFoundException {
|
||||||
CapabilityStatement cs = (CapabilityStatement) new JsonParser().parse(sfn);
|
CapabilityStatement cs = (CapabilityStatement) new JsonParser().parse(sfn);
|
||||||
Writer oa = new Writer(new FileOutputStream(dfn));
|
Writer oa = new Writer(new FileOutputStream(dfn));
|
||||||
OpenApiGenerator gen = new OpenApiGenerator(TestingUtilities.context(), cs, oa);
|
OpenApiGenerator gen = new OpenApiGenerator(TestingUtilities.getSharedWorkerContext(), cs, oa);
|
||||||
gen.generate("test-lic", "http://spdx.org/licenses/test-lic.html");
|
gen.generate("test-lic", "http://spdx.org/licenses/test-lic.html");
|
||||||
oa.commit();
|
oa.commit();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,13 @@
|
||||||
package org.hl7.fhir.r5.test;
|
package org.hl7.fhir.r5.test;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import org.hl7.fhir.exceptions.FHIRException;
|
import org.hl7.fhir.exceptions.FHIRException;
|
||||||
import org.hl7.fhir.r5.conformance.ProfileUtilities;
|
import org.hl7.fhir.r5.conformance.ProfileUtilities;
|
||||||
import org.hl7.fhir.r5.model.Base;
|
import org.hl7.fhir.r5.model.Base;
|
||||||
import org.hl7.fhir.r5.model.ElementDefinition;
|
import org.hl7.fhir.r5.model.ElementDefinition;
|
||||||
|
import org.hl7.fhir.r5.model.ElementDefinition.ElementDefinitionConstraintComponent;
|
||||||
import org.hl7.fhir.r5.model.IntegerType;
|
import org.hl7.fhir.r5.model.IntegerType;
|
||||||
import org.hl7.fhir.r5.model.StructureDefinition;
|
import org.hl7.fhir.r5.model.StructureDefinition;
|
||||||
import org.hl7.fhir.r5.model.StructureDefinition.TypeDerivationRule;
|
import org.hl7.fhir.r5.model.StructureDefinition.TypeDerivationRule;
|
||||||
|
@ -13,9 +17,6 @@ import org.hl7.fhir.utilities.validation.ValidationMessage;
|
||||||
import org.junit.jupiter.api.Assertions;
|
import org.junit.jupiter.api.Assertions;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class ProfileUtilitiesTests {
|
public class ProfileUtilitiesTests {
|
||||||
|
|
||||||
// /**
|
// /**
|
||||||
|
@ -29,13 +30,13 @@ public class ProfileUtilitiesTests {
|
||||||
public void testSimple() throws FHIRException {
|
public void testSimple() throws FHIRException {
|
||||||
|
|
||||||
StructureDefinition focus = new StructureDefinition();
|
StructureDefinition focus = new StructureDefinition();
|
||||||
StructureDefinition base = TestingUtilities.context().fetchResource(StructureDefinition.class, "http://hl7.org/fhir/StructureDefinition/Patient").copy();
|
StructureDefinition base = TestingUtilities.getSharedWorkerContext().fetchResource(StructureDefinition.class, "http://hl7.org/fhir/StructureDefinition/Patient").copy();
|
||||||
focus.setUrl(Utilities.makeUuidUrn());
|
focus.setUrl(Utilities.makeUuidUrn());
|
||||||
focus.setBaseDefinition(base.getUrl());
|
focus.setBaseDefinition(base.getUrl());
|
||||||
focus.setType("Patient");
|
focus.setType("Patient");
|
||||||
focus.setDerivation(TypeDerivationRule.CONSTRAINT);
|
focus.setDerivation(TypeDerivationRule.CONSTRAINT);
|
||||||
List<ValidationMessage> messages = new ArrayList<>();
|
List<ValidationMessage> messages = new ArrayList<>();
|
||||||
new ProfileUtilities(TestingUtilities.context(), messages, null).generateSnapshot(base, focus, focus.getUrl(), "http://test.org/test", "Simple Test");
|
new ProfileUtilities(TestingUtilities.getSharedWorkerContext(), messages, null).generateSnapshot(base, focus, focus.getUrl(), "http://test.org/test", "Simple Test");
|
||||||
|
|
||||||
boolean ok = base.getSnapshot().getElement().size() == focus.getSnapshot().getElement().size();
|
boolean ok = base.getSnapshot().getElement().size() == focus.getSnapshot().getElement().size();
|
||||||
for (int i = 0; i < base.getSnapshot().getElement().size(); i++) {
|
for (int i = 0; i < base.getSnapshot().getElement().size(); i++) {
|
||||||
|
@ -51,6 +52,12 @@ public class ProfileUtilitiesTests {
|
||||||
f.setBase(null);
|
f.setBase(null);
|
||||||
b.setRequirements(null);
|
b.setRequirements(null);
|
||||||
f.setRequirements(null);
|
f.setRequirements(null);
|
||||||
|
for (ElementDefinitionConstraintComponent c : b.getConstraint()) {
|
||||||
|
c.setSource(null);
|
||||||
|
}
|
||||||
|
for (ElementDefinitionConstraintComponent c : f.getConstraint()) {
|
||||||
|
c.setSource(null);
|
||||||
|
}
|
||||||
ok = Base.compareDeep(b, f, true);
|
ok = Base.compareDeep(b, f, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -70,19 +77,25 @@ public class ProfileUtilitiesTests {
|
||||||
// */
|
// */
|
||||||
@Test
|
@Test
|
||||||
public void testSimple2() {
|
public void testSimple2() {
|
||||||
StructureDefinition base = TestingUtilities.context().fetchResource(StructureDefinition.class, "http://hl7.org/fhir/StructureDefinition/ValueSet").copy();
|
StructureDefinition base = TestingUtilities.getSharedWorkerContext().fetchResource(StructureDefinition.class, "http://hl7.org/fhir/StructureDefinition/ValueSet").copy();
|
||||||
StructureDefinition focus = base.copy();
|
StructureDefinition focus = base.copy();
|
||||||
focus.setUrl(Utilities.makeUuidUrn());
|
focus.setUrl(Utilities.makeUuidUrn());
|
||||||
focus.setSnapshot(null);
|
focus.setSnapshot(null);
|
||||||
focus.setDifferential(null);
|
focus.setDifferential(null);
|
||||||
List<ValidationMessage> messages = new ArrayList<>();
|
List<ValidationMessage> messages = new ArrayList<>();
|
||||||
new ProfileUtilities(TestingUtilities.context(), messages, null).generateSnapshot(base, focus, focus.getUrl(), "http://test.org", "Simple Test");
|
new ProfileUtilities(TestingUtilities.getSharedWorkerContext(), messages, null).generateSnapshot(base, focus, focus.getUrl(), "http://test.org", "Simple Test");
|
||||||
|
|
||||||
boolean ok = base.getSnapshot().getElement().size() == focus.getSnapshot().getElement().size();
|
boolean ok = base.getSnapshot().getElement().size() == focus.getSnapshot().getElement().size();
|
||||||
for (int i = 0; i < base.getSnapshot().getElement().size(); i++) {
|
for (int i = 0; i < base.getSnapshot().getElement().size(); i++) {
|
||||||
if (ok) {
|
if (ok) {
|
||||||
ElementDefinition b = base.getSnapshot().getElement().get(i);
|
ElementDefinition b = base.getSnapshot().getElement().get(i);
|
||||||
ElementDefinition f = focus.getSnapshot().getElement().get(i);
|
ElementDefinition f = focus.getSnapshot().getElement().get(i);
|
||||||
|
for (ElementDefinitionConstraintComponent c : b.getConstraint()) {
|
||||||
|
c.setSource(null);
|
||||||
|
}
|
||||||
|
for (ElementDefinitionConstraintComponent c : f.getConstraint()) {
|
||||||
|
c.setSource(null);
|
||||||
|
}
|
||||||
if (!f.hasBase() || !b.getPath().equals(f.getPath()))
|
if (!f.hasBase() || !b.getPath().equals(f.getPath()))
|
||||||
ok = false;
|
ok = false;
|
||||||
else {
|
else {
|
||||||
|
@ -110,7 +123,7 @@ public class ProfileUtilitiesTests {
|
||||||
@Test
|
@Test
|
||||||
void testCardinalityChange() {
|
void testCardinalityChange() {
|
||||||
StructureDefinition focus = new StructureDefinition();
|
StructureDefinition focus = new StructureDefinition();
|
||||||
StructureDefinition base = TestingUtilities.context().fetchResource(StructureDefinition.class, "http://hl7.org/fhir/StructureDefinition/Patient").copy();
|
StructureDefinition base = TestingUtilities.getSharedWorkerContext().fetchResource(StructureDefinition.class, "http://hl7.org/fhir/StructureDefinition/Patient").copy();
|
||||||
focus.setUrl(Utilities.makeUuidUrn());
|
focus.setUrl(Utilities.makeUuidUrn());
|
||||||
focus.setBaseDefinition(base.getUrl());
|
focus.setBaseDefinition(base.getUrl());
|
||||||
focus.setType(base.getType());
|
focus.setType(base.getType());
|
||||||
|
@ -119,7 +132,7 @@ public class ProfileUtilitiesTests {
|
||||||
id.setPath("Patient.identifier");
|
id.setPath("Patient.identifier");
|
||||||
id.setMin(1);
|
id.setMin(1);
|
||||||
List<ValidationMessage> messages = new ArrayList<>();
|
List<ValidationMessage> messages = new ArrayList<>();
|
||||||
new ProfileUtilities(TestingUtilities.context(), messages, null).generateSnapshot(base, focus, focus.getUrl(), "http://test.org", "Simple Test");
|
new ProfileUtilities(TestingUtilities.getSharedWorkerContext(), messages, null).generateSnapshot(base, focus, focus.getUrl(), "http://test.org", "Simple Test");
|
||||||
|
|
||||||
boolean ok = base.getSnapshot().getElement().size() == focus.getSnapshot().getElement().size();
|
boolean ok = base.getSnapshot().getElement().size() == focus.getSnapshot().getElement().size();
|
||||||
for (int i = 0; i < base.getSnapshot().getElement().size(); i++) {
|
for (int i = 0; i < base.getSnapshot().getElement().size(); i++) {
|
||||||
|
@ -128,6 +141,12 @@ public class ProfileUtilitiesTests {
|
||||||
ElementDefinition f = focus.getSnapshot().getElement().get(i);
|
ElementDefinition f = focus.getSnapshot().getElement().get(i);
|
||||||
b.setRequirements(null);
|
b.setRequirements(null);
|
||||||
f.setRequirements(null);
|
f.setRequirements(null);
|
||||||
|
for (ElementDefinitionConstraintComponent c : b.getConstraint()) {
|
||||||
|
c.setSource(null);
|
||||||
|
}
|
||||||
|
for (ElementDefinitionConstraintComponent c : f.getConstraint()) {
|
||||||
|
c.setSource(null);
|
||||||
|
}
|
||||||
if (!f.hasBase() || !b.getPath().equals(f.getPath())) {
|
if (!f.hasBase() || !b.getPath().equals(f.getPath())) {
|
||||||
ok = false;
|
ok = false;
|
||||||
}
|
}
|
||||||
|
@ -155,7 +174,7 @@ public class ProfileUtilitiesTests {
|
||||||
void testMinValueChange() {
|
void testMinValueChange() {
|
||||||
// Given
|
// Given
|
||||||
StructureDefinition focus = new StructureDefinition();
|
StructureDefinition focus = new StructureDefinition();
|
||||||
StructureDefinition base = TestingUtilities.context().fetchResource(StructureDefinition.class, "http://hl7.org/fhir/StructureDefinition/Appointment").copy();
|
StructureDefinition base = TestingUtilities.getSharedWorkerContext().fetchResource(StructureDefinition.class, "http://hl7.org/fhir/StructureDefinition/Appointment").copy();
|
||||||
focus.setUrl(Utilities.makeUuidUrn());
|
focus.setUrl(Utilities.makeUuidUrn());
|
||||||
focus.setBaseDefinition(base.getUrl());
|
focus.setBaseDefinition(base.getUrl());
|
||||||
focus.setType(base.getType());
|
focus.setType(base.getType());
|
||||||
|
@ -165,7 +184,7 @@ public class ProfileUtilitiesTests {
|
||||||
id.setMinValue(new IntegerType(1));
|
id.setMinValue(new IntegerType(1));
|
||||||
List<ValidationMessage> messages = new ArrayList<>();
|
List<ValidationMessage> messages = new ArrayList<>();
|
||||||
// When
|
// When
|
||||||
new ProfileUtilities(TestingUtilities.context(), messages, null).generateSnapshot(base, focus, focus.getUrl(), "http://test.org", "Simple Test");
|
new ProfileUtilities(TestingUtilities.getSharedWorkerContext(), messages, null).generateSnapshot(base, focus, focus.getUrl(), "http://test.org", "Simple Test");
|
||||||
// Then
|
// Then
|
||||||
boolean ok = base.getSnapshot().getElement().size() == focus.getSnapshot().getElement().size();
|
boolean ok = base.getSnapshot().getElement().size() == focus.getSnapshot().getElement().size();
|
||||||
for (int i = 0; i < base.getSnapshot().getElement().size(); i++) {
|
for (int i = 0; i < base.getSnapshot().getElement().size(); i++) {
|
||||||
|
@ -174,6 +193,12 @@ public class ProfileUtilitiesTests {
|
||||||
ElementDefinition f = focus.getSnapshot().getElement().get(i);
|
ElementDefinition f = focus.getSnapshot().getElement().get(i);
|
||||||
b.setRequirements(null);
|
b.setRequirements(null);
|
||||||
f.setRequirements(null);
|
f.setRequirements(null);
|
||||||
|
for (ElementDefinitionConstraintComponent c : b.getConstraint()) {
|
||||||
|
c.setSource(null);
|
||||||
|
}
|
||||||
|
for (ElementDefinitionConstraintComponent c : f.getConstraint()) {
|
||||||
|
c.setSource(null);
|
||||||
|
}
|
||||||
if (!f.hasBase() || !b.getPath().equals(f.getPath())) {
|
if (!f.hasBase() || !b.getPath().equals(f.getPath())) {
|
||||||
ok = false;
|
ok = false;
|
||||||
}
|
}
|
||||||
|
@ -202,7 +227,7 @@ public class ProfileUtilitiesTests {
|
||||||
void testMaxValueChange() {
|
void testMaxValueChange() {
|
||||||
// Given
|
// Given
|
||||||
StructureDefinition focus = new StructureDefinition();
|
StructureDefinition focus = new StructureDefinition();
|
||||||
StructureDefinition base = TestingUtilities.context().fetchResource(StructureDefinition.class, "http://hl7.org/fhir/StructureDefinition/Appointment").copy();
|
StructureDefinition base = TestingUtilities.getSharedWorkerContext().fetchResource(StructureDefinition.class, "http://hl7.org/fhir/StructureDefinition/Appointment").copy();
|
||||||
focus.setUrl(Utilities.makeUuidUrn());
|
focus.setUrl(Utilities.makeUuidUrn());
|
||||||
focus.setBaseDefinition(base.getUrl());
|
focus.setBaseDefinition(base.getUrl());
|
||||||
focus.setType(base.getType());
|
focus.setType(base.getType());
|
||||||
|
@ -212,7 +237,7 @@ public class ProfileUtilitiesTests {
|
||||||
id.setMaxValue(new IntegerType(1));
|
id.setMaxValue(new IntegerType(1));
|
||||||
List<ValidationMessage> messages = new ArrayList<>();
|
List<ValidationMessage> messages = new ArrayList<>();
|
||||||
// When
|
// When
|
||||||
new ProfileUtilities(TestingUtilities.context(), messages, null).generateSnapshot(base, focus, focus.getUrl(), "http://test.org", "Simple Test");
|
new ProfileUtilities(TestingUtilities.getSharedWorkerContext(), messages, null).generateSnapshot(base, focus, focus.getUrl(), "http://test.org", "Simple Test");
|
||||||
// Then
|
// Then
|
||||||
boolean ok = base.getSnapshot().getElement().size() == focus.getSnapshot().getElement().size();
|
boolean ok = base.getSnapshot().getElement().size() == focus.getSnapshot().getElement().size();
|
||||||
for (int i = 0; i < base.getSnapshot().getElement().size(); i++) {
|
for (int i = 0; i < base.getSnapshot().getElement().size(); i++) {
|
||||||
|
@ -221,6 +246,12 @@ public class ProfileUtilitiesTests {
|
||||||
ElementDefinition f = focus.getSnapshot().getElement().get(i);
|
ElementDefinition f = focus.getSnapshot().getElement().get(i);
|
||||||
b.setRequirements(null);
|
b.setRequirements(null);
|
||||||
f.setRequirements(null);
|
f.setRequirements(null);
|
||||||
|
for (ElementDefinitionConstraintComponent c : b.getConstraint()) {
|
||||||
|
c.setSource(null);
|
||||||
|
}
|
||||||
|
for (ElementDefinitionConstraintComponent c : f.getConstraint()) {
|
||||||
|
c.setSource(null);
|
||||||
|
}
|
||||||
if (!f.hasBase() || !b.getPath().equals(f.getPath())) {
|
if (!f.hasBase() || !b.getPath().equals(f.getPath())) {
|
||||||
ok = false;
|
ok = false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package org.hl7.fhir.r5.test;
|
package org.hl7.fhir.r5.test;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
import org.hl7.fhir.exceptions.FHIRException;
|
import org.hl7.fhir.exceptions.FHIRException;
|
||||||
import org.hl7.fhir.r5.model.Enumerations;
|
import org.hl7.fhir.r5.model.Enumerations;
|
||||||
import org.hl7.fhir.r5.model.Extension;
|
import org.hl7.fhir.r5.model.Extension;
|
||||||
|
@ -7,8 +9,6 @@ import org.hl7.fhir.r5.model.Observation;
|
||||||
import org.junit.jupiter.api.Assertions;
|
import org.junit.jupiter.api.Assertions;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
public class ResourceCopyTests {
|
public class ResourceCopyTests {
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,6 @@ import org.hl7.fhir.r5.formats.IParser.OutputStyle;
|
||||||
import org.hl7.fhir.r5.formats.JsonParser;
|
import org.hl7.fhir.r5.formats.JsonParser;
|
||||||
import org.hl7.fhir.r5.formats.XmlParser;
|
import org.hl7.fhir.r5.formats.XmlParser;
|
||||||
import org.hl7.fhir.r5.model.Bundle;
|
import org.hl7.fhir.r5.model.Bundle;
|
||||||
import org.hl7.fhir.r5.model.DateTimeType;
|
|
||||||
import org.hl7.fhir.r5.model.DomainResource;
|
import org.hl7.fhir.r5.model.DomainResource;
|
||||||
import org.hl7.fhir.r5.model.Resource;
|
import org.hl7.fhir.r5.model.Resource;
|
||||||
import org.hl7.fhir.r5.renderers.RendererFactory;
|
import org.hl7.fhir.r5.renderers.RendererFactory;
|
||||||
|
@ -27,7 +26,6 @@ import org.hl7.fhir.r5.renderers.utils.RenderingContext;
|
||||||
import org.hl7.fhir.r5.renderers.utils.RenderingContext.ResourceRendererMode;
|
import org.hl7.fhir.r5.renderers.utils.RenderingContext.ResourceRendererMode;
|
||||||
import org.hl7.fhir.r5.test.utils.TestingUtilities;
|
import org.hl7.fhir.r5.test.utils.TestingUtilities;
|
||||||
import org.hl7.fhir.r5.utils.EOperationOutcome;
|
import org.hl7.fhir.r5.utils.EOperationOutcome;
|
||||||
import org.junit.jupiter.api.Assertions;
|
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
public class ResourceRoundTripTests {
|
public class ResourceRoundTripTests {
|
||||||
|
@ -35,7 +33,7 @@ public class ResourceRoundTripTests {
|
||||||
@Test
|
@Test
|
||||||
public void test() throws IOException, FHIRException, EOperationOutcome {
|
public void test() throws IOException, FHIRException, EOperationOutcome {
|
||||||
DomainResource res = (DomainResource) new XmlParser().parse(TestingUtilities.loadTestResourceStream("r5", "unicode.xml"));
|
DomainResource res = (DomainResource) new XmlParser().parse(TestingUtilities.loadTestResourceStream("r5", "unicode.xml"));
|
||||||
RenderingContext rc = new RenderingContext(TestingUtilities.context(), null, null, "http://hl7.org/fhir", "", null, ResourceRendererMode.END_USER);
|
RenderingContext rc = new RenderingContext(TestingUtilities.getSharedWorkerContext(), null, null, "http://hl7.org/fhir", "", null, ResourceRendererMode.END_USER);
|
||||||
RendererFactory.factory(res, rc).render(res);
|
RendererFactory.factory(res, rc).render(res);
|
||||||
IOUtils.copy(TestingUtilities.loadTestResourceStream("r5", "unicode.xml"), new FileOutputStream(TestingUtilities.tempFile("gen", "unicode.xml")));
|
IOUtils.copy(TestingUtilities.loadTestResourceStream("r5", "unicode.xml"), new FileOutputStream(TestingUtilities.tempFile("gen", "unicode.xml")));
|
||||||
new XmlParser().setOutputStyle(OutputStyle.PRETTY).compose(new FileOutputStream(TestingUtilities.tempFile("gen", "unicode.out.xml")), res);
|
new XmlParser().setOutputStyle(OutputStyle.PRETTY).compose(new FileOutputStream(TestingUtilities.tempFile("gen", "unicode.out.xml")), res);
|
||||||
|
@ -66,7 +64,7 @@ public class ResourceRoundTripTests {
|
||||||
* verify that umlaut like äö etc are not encoded in UTF-8 in attributes
|
* verify that umlaut like äö etc are not encoded in UTF-8 in attributes
|
||||||
*/
|
*/
|
||||||
public void testSerializeUmlaut() throws IOException {
|
public void testSerializeUmlaut() throws IOException {
|
||||||
Element xml = Manager.parseSingle(TestingUtilities.context(), TestingUtilities.loadTestResourceStream("r5", "unicode.xml"),
|
Element xml = Manager.parseSingle(TestingUtilities.getSharedWorkerContext(), TestingUtilities.loadTestResourceStream("r5", "unicode.xml"),
|
||||||
FhirFormat.XML);
|
FhirFormat.XML);
|
||||||
List<Element> concept = xml.getChildrenByName("concept");
|
List<Element> concept = xml.getChildrenByName("concept");
|
||||||
assertTrue(concept!=null && concept.size()==1);
|
assertTrue(concept!=null && concept.size()==1);
|
||||||
|
@ -74,7 +72,7 @@ public class ResourceRoundTripTests {
|
||||||
assertTrue(code!=null && code.size()==1);
|
assertTrue(code!=null && code.size()==1);
|
||||||
code.get(0).setValue("ö");
|
code.get(0).setValue("ö");
|
||||||
ByteArrayOutputStream baosXml = new ByteArrayOutputStream();
|
ByteArrayOutputStream baosXml = new ByteArrayOutputStream();
|
||||||
Manager.compose(TestingUtilities.context(), xml, baosXml, FhirFormat.XML, OutputStyle.PRETTY, null);
|
Manager.compose(TestingUtilities.getSharedWorkerContext(), xml, baosXml, FhirFormat.XML, OutputStyle.PRETTY, null);
|
||||||
String cdaSerialised = baosXml.toString("UTF-8");
|
String cdaSerialised = baosXml.toString("UTF-8");
|
||||||
assertTrue(cdaSerialised.indexOf("ö")>0);
|
assertTrue(cdaSerialised.indexOf("ö")>0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
package org.hl7.fhir.r5.test;
|
package org.hl7.fhir.r5.test;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.*;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
|
|
|
@ -18,12 +18,12 @@ import org.junit.jupiter.api.Test;
|
||||||
public class ShexGeneratorTests {
|
public class ShexGeneratorTests {
|
||||||
|
|
||||||
private void doTest(String name) throws FileNotFoundException, IOException, FHIRException, UcumException {
|
private void doTest(String name) throws FileNotFoundException, IOException, FHIRException, UcumException {
|
||||||
StructureDefinition sd = TestingUtilities.context().fetchResource(StructureDefinition.class, ProfileUtilities.sdNs(name, null));
|
StructureDefinition sd = TestingUtilities.getSharedWorkerContext().fetchResource(StructureDefinition.class, ProfileUtilities.sdNs(name, null));
|
||||||
if (sd == null) {
|
if (sd == null) {
|
||||||
throw new FHIRException("StructuredDefinition for " + name + "was null");
|
throw new FHIRException("StructuredDefinition for " + name + "was null");
|
||||||
}
|
}
|
||||||
Path outPath = FileSystems.getDefault().getPath(System.getProperty("java.io.tmpdir"), name.toLowerCase() + ".shex");
|
Path outPath = FileSystems.getDefault().getPath(System.getProperty("java.io.tmpdir"), name.toLowerCase() + ".shex");
|
||||||
TextFile.stringToFile(new ShExGenerator(TestingUtilities.context()).generate(HTMLLinkPolicy.NONE, sd), outPath.toString());
|
TextFile.stringToFile(new ShExGenerator(TestingUtilities.getSharedWorkerContext()).generate(HTMLLinkPolicy.NONE, sd), outPath.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
@ -4,7 +4,6 @@ import java.io.File;
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
@ -19,28 +18,27 @@ import org.hl7.fhir.exceptions.FHIRFormatError;
|
||||||
import org.hl7.fhir.exceptions.PathEngineException;
|
import org.hl7.fhir.exceptions.PathEngineException;
|
||||||
import org.hl7.fhir.r5.conformance.ProfileUtilities;
|
import org.hl7.fhir.r5.conformance.ProfileUtilities;
|
||||||
import org.hl7.fhir.r5.conformance.ProfileUtilities.ProfileKnowledgeProvider;
|
import org.hl7.fhir.r5.conformance.ProfileUtilities.ProfileKnowledgeProvider;
|
||||||
import org.hl7.fhir.r5.context.IWorkerContext.IContextResourceLoader;
|
import org.hl7.fhir.r5.context.TestPackageLoader;
|
||||||
import org.hl7.fhir.r5.formats.IParser.OutputStyle;
|
import org.hl7.fhir.r5.formats.IParser.OutputStyle;
|
||||||
import org.hl7.fhir.r5.formats.JsonParser;
|
import org.hl7.fhir.r5.formats.JsonParser;
|
||||||
import org.hl7.fhir.r5.formats.XmlParser;
|
import org.hl7.fhir.r5.formats.XmlParser;
|
||||||
import org.hl7.fhir.r5.model.Base;
|
import org.hl7.fhir.r5.model.Base;
|
||||||
import org.hl7.fhir.r5.model.Bundle;
|
|
||||||
import org.hl7.fhir.r5.model.ElementDefinition.ElementDefinitionBindingComponent;
|
import org.hl7.fhir.r5.model.ElementDefinition.ElementDefinitionBindingComponent;
|
||||||
import org.hl7.fhir.r5.model.ExpressionNode.CollectionStatus;
|
import org.hl7.fhir.r5.model.ExpressionNode.CollectionStatus;
|
||||||
import org.hl7.fhir.r5.model.Resource;
|
import org.hl7.fhir.r5.model.Resource;
|
||||||
import org.hl7.fhir.r5.model.StructureDefinition;
|
import org.hl7.fhir.r5.model.StructureDefinition;
|
||||||
import org.hl7.fhir.r5.model.StructureDefinition.StructureDefinitionKind;
|
import org.hl7.fhir.r5.model.StructureDefinition.StructureDefinitionKind;
|
||||||
import org.hl7.fhir.r5.model.StructureDefinition.TypeDerivationRule;
|
import org.hl7.fhir.r5.model.StructureDefinition.TypeDerivationRule;
|
||||||
|
import org.hl7.fhir.r5.model.TypeDetails;
|
||||||
|
import org.hl7.fhir.r5.model.ValueSet;
|
||||||
import org.hl7.fhir.r5.renderers.RendererFactory;
|
import org.hl7.fhir.r5.renderers.RendererFactory;
|
||||||
import org.hl7.fhir.r5.renderers.utils.RenderingContext;
|
import org.hl7.fhir.r5.renderers.utils.RenderingContext;
|
||||||
import org.hl7.fhir.r5.renderers.utils.RenderingContext.ResourceRendererMode;
|
import org.hl7.fhir.r5.renderers.utils.RenderingContext.ResourceRendererMode;
|
||||||
import org.hl7.fhir.r5.model.TypeDetails;
|
|
||||||
import org.hl7.fhir.r5.model.ValueSet;
|
|
||||||
import org.hl7.fhir.r5.test.utils.TestingUtilities;
|
import org.hl7.fhir.r5.test.utils.TestingUtilities;
|
||||||
import org.hl7.fhir.r5.utils.FHIRPathEngine;
|
import org.hl7.fhir.r5.utils.FHIRPathEngine;
|
||||||
import org.hl7.fhir.r5.utils.FHIRPathEngine.IEvaluationContext;
|
import org.hl7.fhir.r5.utils.FHIRPathEngine.IEvaluationContext;
|
||||||
import org.hl7.fhir.r5.utils.validation.IResourceValidator;
|
|
||||||
import org.hl7.fhir.r5.utils.XVerExtensionManager;
|
import org.hl7.fhir.r5.utils.XVerExtensionManager;
|
||||||
|
import org.hl7.fhir.r5.utils.validation.IResourceValidator;
|
||||||
import org.hl7.fhir.utilities.Utilities;
|
import org.hl7.fhir.utilities.Utilities;
|
||||||
import org.hl7.fhir.utilities.npm.CommonPackages;
|
import org.hl7.fhir.utilities.npm.CommonPackages;
|
||||||
import org.hl7.fhir.utilities.npm.FilesystemPackageCacheManager;
|
import org.hl7.fhir.utilities.npm.FilesystemPackageCacheManager;
|
||||||
|
@ -60,41 +58,6 @@ import org.xml.sax.SAXException;
|
||||||
|
|
||||||
public class SnapShotGenerationTests {
|
public class SnapShotGenerationTests {
|
||||||
|
|
||||||
public class TestLoader implements IContextResourceLoader {
|
|
||||||
|
|
||||||
private String[] types;
|
|
||||||
|
|
||||||
public TestLoader(String[] types) {
|
|
||||||
this.types = types;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Bundle loadBundle(InputStream stream, boolean isJson) throws FHIRException, IOException {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Resource loadResource(InputStream stream, boolean isJson) throws FHIRException, IOException {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String[] getTypes() {
|
|
||||||
return types;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getResourcePath(Resource resource) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public IContextResourceLoader getNewLoader(NpmPackage npm) {
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public enum TestFetchMode {
|
public enum TestFetchMode {
|
||||||
INPUT,
|
INPUT,
|
||||||
OUTPUT,
|
OUTPUT,
|
||||||
|
@ -248,13 +211,13 @@ public class SnapShotGenerationTests {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isDatatype(String name) {
|
public boolean isDatatype(String name) {
|
||||||
StructureDefinition sd = TestingUtilities.context().fetchTypeDefinition(name);
|
StructureDefinition sd = TestingUtilities.getSharedWorkerContext().fetchTypeDefinition(name);
|
||||||
return (sd != null) && (sd.getDerivation() == TypeDerivationRule.SPECIALIZATION) && (sd.getKind() == StructureDefinitionKind.PRIMITIVETYPE || sd.getKind() == StructureDefinitionKind.COMPLEXTYPE);
|
return (sd != null) && (sd.getDerivation() == TypeDerivationRule.SPECIALIZATION) && (sd.getKind() == StructureDefinitionKind.PRIMITIVETYPE || sd.getKind() == StructureDefinitionKind.COMPLEXTYPE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isResource(String typeSimple) {
|
public boolean isResource(String typeSimple) {
|
||||||
StructureDefinition sd = TestingUtilities.context().fetchTypeDefinition(typeSimple);
|
StructureDefinition sd = TestingUtilities.getSharedWorkerContext().fetchTypeDefinition(typeSimple);
|
||||||
return (sd != null) && (sd.getDerivation() == TypeDerivationRule.SPECIALIZATION) && (sd.getKind() == StructureDefinitionKind.RESOURCE);
|
return (sd != null) && (sd.getDerivation() == TypeDerivationRule.SPECIALIZATION) && (sd.getKind() == StructureDefinitionKind.RESOURCE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -286,7 +249,7 @@ public class SnapShotGenerationTests {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getLinkForProfile(StructureDefinition profile, String url) {
|
public String getLinkForProfile(StructureDefinition profile, String url) {
|
||||||
StructureDefinition sd = TestingUtilities.context().fetchResource(StructureDefinition.class, url);
|
StructureDefinition sd = TestingUtilities.getSharedWorkerContext().fetchResource(StructureDefinition.class, url);
|
||||||
if (sd == null)
|
if (sd == null)
|
||||||
return url + "|" + url;
|
return url + "|" + url;
|
||||||
else
|
else
|
||||||
|
@ -312,15 +275,15 @@ public class SnapShotGenerationTests {
|
||||||
public Resource fetchFixture(String id) {
|
public Resource fetchFixture(String id) {
|
||||||
TestFetchMode mode = TestFetchMode.INPUT;
|
TestFetchMode mode = TestFetchMode.INPUT;
|
||||||
if (id.equals("patient"))
|
if (id.equals("patient"))
|
||||||
return TestingUtilities.context().fetchResource(StructureDefinition.class, "http://hl7.org/fhir/StructureDefinition/Patient");
|
return TestingUtilities.getSharedWorkerContext().fetchResource(StructureDefinition.class, "http://hl7.org/fhir/StructureDefinition/Patient");
|
||||||
if (id.equals("valueset"))
|
if (id.equals("valueset"))
|
||||||
return TestingUtilities.context().fetchResource(StructureDefinition.class, "http://hl7.org/fhir/StructureDefinition/ValueSet");
|
return TestingUtilities.getSharedWorkerContext().fetchResource(StructureDefinition.class, "http://hl7.org/fhir/StructureDefinition/ValueSet");
|
||||||
if (id.equals("organization"))
|
if (id.equals("organization"))
|
||||||
return TestingUtilities.context().fetchResource(StructureDefinition.class, "http://hl7.org/fhir/StructureDefinition/Organization");
|
return TestingUtilities.getSharedWorkerContext().fetchResource(StructureDefinition.class, "http://hl7.org/fhir/StructureDefinition/Organization");
|
||||||
if (id.equals("operationoutcome"))
|
if (id.equals("operationoutcome"))
|
||||||
return TestingUtilities.context().fetchResource(StructureDefinition.class, "http://hl7.org/fhir/StructureDefinition/OperationOutcome");
|
return TestingUtilities.getSharedWorkerContext().fetchResource(StructureDefinition.class, "http://hl7.org/fhir/StructureDefinition/OperationOutcome");
|
||||||
if (id.equals("parameters"))
|
if (id.equals("parameters"))
|
||||||
return TestingUtilities.context().fetchResource(StructureDefinition.class, "http://hl7.org/fhir/StructureDefinition/Parameters");
|
return TestingUtilities.getSharedWorkerContext().fetchResource(StructureDefinition.class, "http://hl7.org/fhir/StructureDefinition/Parameters");
|
||||||
|
|
||||||
if (id.contains("-")) {
|
if (id.contains("-")) {
|
||||||
String[] p = id.split("\\-");
|
String[] p = id.split("\\-");
|
||||||
|
@ -376,7 +339,7 @@ public class SnapShotGenerationTests {
|
||||||
@Override
|
@Override
|
||||||
public TypeDetails checkFunction(Object appContext, String functionName, List<TypeDetails> parameters) throws PathEngineException {
|
public TypeDetails checkFunction(Object appContext, String functionName, List<TypeDetails> parameters) throws PathEngineException {
|
||||||
if ("fixture".equals(functionName))
|
if ("fixture".equals(functionName))
|
||||||
return new TypeDetails(CollectionStatus.SINGLETON, TestingUtilities.context().getResourceNamesAsSet());
|
return new TypeDetails(CollectionStatus.SINGLETON, TestingUtilities.getSharedWorkerContext().getResourceNamesAsSet());
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -403,7 +366,7 @@ public class SnapShotGenerationTests {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean conformsToProfile(Object appContext, Base item, String url) throws FHIRException {
|
public boolean conformsToProfile(Object appContext, Base item, String url) throws FHIRException {
|
||||||
IResourceValidator val = TestingUtilities.context().newValidator();
|
IResourceValidator val = TestingUtilities.getSharedWorkerContext().newValidator();
|
||||||
List<ValidationMessage> valerrors = new ArrayList<ValidationMessage>();
|
List<ValidationMessage> valerrors = new ArrayList<ValidationMessage>();
|
||||||
if (item instanceof Resource) {
|
if (item instanceof Resource) {
|
||||||
val.validate(appContext, valerrors, (Resource) item, url);
|
val.validate(appContext, valerrors, (Resource) item, url);
|
||||||
|
@ -441,7 +404,7 @@ public class SnapShotGenerationTests {
|
||||||
|
|
||||||
@BeforeAll
|
@BeforeAll
|
||||||
public static void setUp() {
|
public static void setUp() {
|
||||||
fp = new FHIRPathEngine(TestingUtilities.context());
|
fp = new FHIRPathEngine(TestingUtilities.getSharedWorkerContext());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Stream<Arguments> data() throws ParserConfigurationException, IOException, FHIRFormatError, SAXException {
|
public static Stream<Arguments> data() throws ParserConfigurationException, IOException, FHIRFormatError, SAXException {
|
||||||
|
@ -499,7 +462,7 @@ public class SnapShotGenerationTests {
|
||||||
private void testSort(TestDetails test, SnapShotGenerationTestsContext context) throws DefinitionException, FHIRException, IOException {
|
private void testSort(TestDetails test, SnapShotGenerationTestsContext context) throws DefinitionException, FHIRException, IOException {
|
||||||
StructureDefinition base = getSD(test.getSource().getBaseDefinition(), context);
|
StructureDefinition base = getSD(test.getSource().getBaseDefinition(), context);
|
||||||
test.setOutput(test.getSource().copy());
|
test.setOutput(test.getSource().copy());
|
||||||
ProfileUtilities pu = new ProfileUtilities(TestingUtilities.context(), null, null);
|
ProfileUtilities pu = new ProfileUtilities(TestingUtilities.getSharedWorkerContext(), null, null);
|
||||||
pu.setIds(test.getSource(), false);
|
pu.setIds(test.getSource(), false);
|
||||||
List<String> errors = new ArrayList<String>();
|
List<String> errors = new ArrayList<String>();
|
||||||
pu.sortDifferential(base, test.getOutput(), test.getOutput().getUrl(), errors, false);
|
pu.sortDifferential(base, test.getOutput(), test.getOutput().getUrl(), errors, false);
|
||||||
|
@ -513,17 +476,17 @@ public class SnapShotGenerationTests {
|
||||||
private void testGen(boolean fail, TestDetails test, SnapShotGenerationTestsContext context) throws Exception {
|
private void testGen(boolean fail, TestDetails test, SnapShotGenerationTestsContext context) throws Exception {
|
||||||
if (!Utilities.noString(test.register)) {
|
if (!Utilities.noString(test.register)) {
|
||||||
List<ValidationMessage> messages = new ArrayList<ValidationMessage>();
|
List<ValidationMessage> messages = new ArrayList<ValidationMessage>();
|
||||||
ProfileUtilities pu = new ProfileUtilities(TestingUtilities.context(), messages, null);
|
ProfileUtilities pu = new ProfileUtilities(TestingUtilities.getSharedWorkerContext(), messages, null);
|
||||||
pu.setNewSlicingProcessing(true);
|
pu.setNewSlicingProcessing(true);
|
||||||
for (StructureDefinition sd : test.included) {
|
for (StructureDefinition sd : test.included) {
|
||||||
pu.setIds(sd, false);
|
pu.setIds(sd, false);
|
||||||
}
|
}
|
||||||
for (StructureDefinition sd : test.included) {
|
for (StructureDefinition sd : test.included) {
|
||||||
if (!TestingUtilities.context().hasResource(StructureDefinition.class, sd.getUrl())) {
|
if (!TestingUtilities.getSharedWorkerContext().hasResource(StructureDefinition.class, sd.getUrl())) {
|
||||||
TestingUtilities.context().cacheResource(sd);
|
TestingUtilities.getSharedWorkerContext().cacheResource(sd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
StructureDefinition base = TestingUtilities.context().fetchResource(StructureDefinition.class, test.included.get(0).getBaseDefinition());
|
StructureDefinition base = TestingUtilities.getSharedWorkerContext().fetchResource(StructureDefinition.class, test.included.get(0).getBaseDefinition());
|
||||||
if (base != null) {
|
if (base != null) {
|
||||||
pu.generateSnapshot(base, test.included.get(0), test.included.get(0).getUrl(), "http://test.org/profile", test.included.get(0).getName());
|
pu.generateSnapshot(base, test.included.get(0), test.included.get(0).getUrl(), "http://test.org/profile", test.included.get(0).getName());
|
||||||
}
|
}
|
||||||
|
@ -542,16 +505,16 @@ public class SnapShotGenerationTests {
|
||||||
throw new Exception("URL mismatch on base: " + base.getUrl() + " wanting " + test.getSource().getBaseDefinition());
|
throw new Exception("URL mismatch on base: " + base.getUrl() + " wanting " + test.getSource().getBaseDefinition());
|
||||||
|
|
||||||
StructureDefinition output = test.getSource().copy();
|
StructureDefinition output = test.getSource().copy();
|
||||||
ProfileUtilities pu = new ProfileUtilities(TestingUtilities.context(), messages, new TestPKP());
|
ProfileUtilities pu = new ProfileUtilities(TestingUtilities.getSharedWorkerContext(), messages, new TestPKP());
|
||||||
pu.setNewSlicingProcessing(test.isNewSliceProcessing());
|
pu.setNewSlicingProcessing(test.isNewSliceProcessing());
|
||||||
pu.setThrowException(false);
|
pu.setThrowException(false);
|
||||||
pu.setDebug(test.isDebug());
|
pu.setDebug(test.isDebug());
|
||||||
pu.setIds(test.getSource(), false);
|
pu.setIds(test.getSource(), false);
|
||||||
if (!TestingUtilities.context().hasPackage(CommonPackages.ID_XVER, CommonPackages.VER_XVER)) {
|
if (!TestingUtilities.getSharedWorkerContext().hasPackage(CommonPackages.ID_XVER, CommonPackages.VER_XVER)) {
|
||||||
NpmPackage npm = new FilesystemPackageCacheManager(true, ToolsVersion.TOOLS_VERSION).loadPackage(CommonPackages.ID_XVER, CommonPackages.VER_XVER);
|
NpmPackage npm = new FilesystemPackageCacheManager(true, ToolsVersion.TOOLS_VERSION).loadPackage(CommonPackages.ID_XVER, CommonPackages.VER_XVER);
|
||||||
TestingUtilities.context().loadFromPackage(npm, new TestLoader(new String[]{"StructureDefinition"}), new String[]{"StructureDefinition"});
|
TestingUtilities.getSharedWorkerContext().loadFromPackage(npm, new TestPackageLoader(new String[]{"StructureDefinition"}), new String[]{"StructureDefinition"});
|
||||||
}
|
}
|
||||||
pu.setXver(new XVerExtensionManager(TestingUtilities.context()));
|
pu.setXver(new XVerExtensionManager(TestingUtilities.getSharedWorkerContext()));
|
||||||
if (test.isSort()) {
|
if (test.isSort()) {
|
||||||
List<String> errors = new ArrayList<String>();
|
List<String> errors = new ArrayList<String>();
|
||||||
int lastCount = output.getDifferential().getElement().size();
|
int lastCount = output.getDifferential().getElement().size();
|
||||||
|
@ -576,14 +539,14 @@ public class SnapShotGenerationTests {
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
if (output.getDifferential().hasElement()) {
|
if (output.getDifferential().hasElement()) {
|
||||||
RenderingContext rc = new RenderingContext(TestingUtilities.context(), null, null, "http://hl7.org/fhir", "", null, ResourceRendererMode.END_USER);
|
RenderingContext rc = new RenderingContext(TestingUtilities.getSharedWorkerContext(), null, null, "http://hl7.org/fhir", "", null, ResourceRendererMode.END_USER);
|
||||||
rc.setDestDir(Utilities.path("[tmp]", "snapshot"));
|
rc.setDestDir(Utilities.path("[tmp]", "snapshot"));
|
||||||
rc.setProfileUtilities(new ProfileUtilities(TestingUtilities.context(), null, new TestPKP()));
|
rc.setProfileUtilities(new ProfileUtilities(TestingUtilities.getSharedWorkerContext(), null, new TestPKP()));
|
||||||
RendererFactory.factory(output, rc).render(output);
|
RendererFactory.factory(output, rc).render(output);
|
||||||
}
|
}
|
||||||
if (!fail) {
|
if (!fail) {
|
||||||
test.output = output;
|
test.output = output;
|
||||||
TestingUtilities.context().cacheResource(output);
|
TestingUtilities.getSharedWorkerContext().cacheResource(output);
|
||||||
File dst = new File(TestingUtilities.tempFile("snapshot", test.getId() + "-expected.xml"));
|
File dst = new File(TestingUtilities.tempFile("snapshot", test.getId() + "-expected.xml"));
|
||||||
if (dst.exists())
|
if (dst.exists())
|
||||||
dst.delete();
|
dst.delete();
|
||||||
|
@ -600,14 +563,14 @@ public class SnapShotGenerationTests {
|
||||||
private StructureDefinition getSD(String url, SnapShotGenerationTestsContext context) throws DefinitionException, FHIRException, IOException {
|
private StructureDefinition getSD(String url, SnapShotGenerationTestsContext context) throws DefinitionException, FHIRException, IOException {
|
||||||
StructureDefinition sd = context.getByUrl(url);
|
StructureDefinition sd = context.getByUrl(url);
|
||||||
if (sd == null) {
|
if (sd == null) {
|
||||||
sd = TestingUtilities.context().fetchResource(StructureDefinition.class, url);
|
sd = TestingUtilities.getSharedWorkerContext().fetchResource(StructureDefinition.class, url);
|
||||||
}
|
}
|
||||||
if (sd == null) {
|
if (sd == null) {
|
||||||
throw new DefinitionException("Unable to find profile "+url);
|
throw new DefinitionException("Unable to find profile "+url);
|
||||||
}
|
}
|
||||||
if (!sd.hasSnapshot()) {
|
if (!sd.hasSnapshot()) {
|
||||||
StructureDefinition base = getSD(sd.getBaseDefinition(), context);
|
StructureDefinition base = getSD(sd.getBaseDefinition(), context);
|
||||||
ProfileUtilities pu = new ProfileUtilities(TestingUtilities.context(), messages, new TestPKP());
|
ProfileUtilities pu = new ProfileUtilities(TestingUtilities.getSharedWorkerContext(), messages, new TestPKP());
|
||||||
pu.setNewSlicingProcessing(true);
|
pu.setNewSlicingProcessing(true);
|
||||||
List<String> errors = new ArrayList<String>();
|
List<String> errors = new ArrayList<String>();
|
||||||
pu.sortDifferential(base, sd, url, errors, false);
|
pu.sortDifferential(base, sd, url, errors, false);
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
package org.hl7.fhir.r5.test;
|
package org.hl7.fhir.r5.test;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import org.hl7.fhir.exceptions.FHIRException;
|
import org.hl7.fhir.exceptions.FHIRException;
|
||||||
import org.hl7.fhir.r5.context.SimpleWorkerContext;
|
import org.hl7.fhir.r5.context.SimpleWorkerContext;
|
||||||
import org.hl7.fhir.r5.model.Base;
|
import org.hl7.fhir.r5.model.Base;
|
||||||
|
@ -7,17 +10,14 @@ import org.hl7.fhir.r5.model.Coding;
|
||||||
import org.hl7.fhir.r5.model.StructureMap;
|
import org.hl7.fhir.r5.model.StructureMap;
|
||||||
import org.hl7.fhir.r5.model.StructureMap.StructureMapGroupRuleTargetComponent;
|
import org.hl7.fhir.r5.model.StructureMap.StructureMapGroupRuleTargetComponent;
|
||||||
import org.hl7.fhir.r5.test.utils.TestingUtilities;
|
import org.hl7.fhir.r5.test.utils.TestingUtilities;
|
||||||
import org.hl7.fhir.r5.utils.structuremap.StructureMapUtilities;
|
|
||||||
import org.hl7.fhir.r5.utils.structuremap.ITransformerServices;
|
import org.hl7.fhir.r5.utils.structuremap.ITransformerServices;
|
||||||
|
import org.hl7.fhir.r5.utils.structuremap.StructureMapUtilities;
|
||||||
import org.hl7.fhir.utilities.npm.FilesystemPackageCacheManager;
|
import org.hl7.fhir.utilities.npm.FilesystemPackageCacheManager;
|
||||||
import org.hl7.fhir.utilities.npm.ToolsVersion;
|
import org.hl7.fhir.utilities.npm.ToolsVersion;
|
||||||
import org.junit.jupiter.api.Assertions;
|
import org.junit.jupiter.api.Assertions;
|
||||||
import org.junit.jupiter.api.BeforeAll;
|
import org.junit.jupiter.api.BeforeAll;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class StructureMapUtilitiesTest implements ITransformerServices {
|
public class StructureMapUtilitiesTest implements ITransformerServices {
|
||||||
|
|
||||||
static private SimpleWorkerContext context;
|
static private SimpleWorkerContext context;
|
||||||
|
|
|
@ -0,0 +1,166 @@
|
||||||
|
package org.hl7.fhir.r5.test;
|
||||||
|
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import javax.xml.parsers.ParserConfigurationException;
|
||||||
|
|
||||||
|
import org.hl7.fhir.exceptions.FHIRException;
|
||||||
|
import org.hl7.fhir.exceptions.FHIRFormatError;
|
||||||
|
import org.hl7.fhir.r5.context.IWorkerContext;
|
||||||
|
import org.hl7.fhir.r5.context.TestPackageLoader;
|
||||||
|
import org.hl7.fhir.r5.formats.IParser.OutputStyle;
|
||||||
|
import org.hl7.fhir.r5.formats.JsonParser;
|
||||||
|
import org.hl7.fhir.r5.formats.XmlParser;
|
||||||
|
import org.hl7.fhir.r5.model.Base;
|
||||||
|
import org.hl7.fhir.r5.model.Resource;
|
||||||
|
import org.hl7.fhir.r5.model.ValueSet;
|
||||||
|
import org.hl7.fhir.r5.renderers.utils.RenderingContext.ITypeParser;
|
||||||
|
import org.hl7.fhir.r5.terminologies.ValueSetExpander.ValueSetExpansionOutcome;
|
||||||
|
import org.hl7.fhir.r5.test.utils.TestingUtilities;
|
||||||
|
import org.hl7.fhir.utilities.TextFile;
|
||||||
|
import org.hl7.fhir.utilities.VersionUtilities;
|
||||||
|
import org.hl7.fhir.utilities.npm.FilesystemPackageCacheManager;
|
||||||
|
import org.hl7.fhir.utilities.npm.NpmPackage;
|
||||||
|
import org.hl7.fhir.utilities.npm.ToolsVersion;
|
||||||
|
import org.hl7.fhir.utilities.xml.XMLUtil;
|
||||||
|
import org.junit.jupiter.api.Assertions;
|
||||||
|
import org.junit.jupiter.api.BeforeAll;
|
||||||
|
import org.junit.jupiter.params.ParameterizedTest;
|
||||||
|
import org.junit.jupiter.params.provider.Arguments;
|
||||||
|
import org.junit.jupiter.params.provider.MethodSource;
|
||||||
|
import org.w3c.dom.Document;
|
||||||
|
import org.w3c.dom.Element;
|
||||||
|
import org.xml.sax.SAXException;
|
||||||
|
|
||||||
|
public class VocabTests {
|
||||||
|
|
||||||
|
public enum TestType {
|
||||||
|
Expansion;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class TestTypeParser implements ITypeParser {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Base parseType(String xml, String type) throws FHIRFormatError, IOException, FHIRException {
|
||||||
|
return new org.hl7.fhir.r5.formats.XmlParser().parseType(xml, type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static IWorkerContext context;
|
||||||
|
|
||||||
|
public static class TestDetails {
|
||||||
|
private String id;
|
||||||
|
private Map<String, String> parameters = new HashMap<>();
|
||||||
|
private String source;
|
||||||
|
private String target;
|
||||||
|
private TestType type;
|
||||||
|
|
||||||
|
|
||||||
|
public TestDetails(Element test) {
|
||||||
|
super();
|
||||||
|
id = test.getAttribute("id");
|
||||||
|
source = XMLUtil.getNamedChildValue(test, "source");
|
||||||
|
target = XMLUtil.getNamedChildValue(test, "target");
|
||||||
|
type = TestType.Expansion;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, String> getParameters() {
|
||||||
|
return parameters;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSource() {
|
||||||
|
return source;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTarget() {
|
||||||
|
return target;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TestType getType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Stream<Arguments> data() throws ParserConfigurationException, IOException, FHIRFormatError, SAXException {
|
||||||
|
Document tests = XMLUtil.parseToDom(TestingUtilities.loadTestResource("r5", "vocab", "manifest.xml"));
|
||||||
|
Element test = XMLUtil.getFirstChild(tests.getDocumentElement());
|
||||||
|
List<Arguments> objects = new ArrayList<>();
|
||||||
|
while (test != null && test.getNodeName().equals("test")) {
|
||||||
|
TestDetails t = new TestDetails(test);
|
||||||
|
objects.add(Arguments.of(t.getId(), t));
|
||||||
|
test = XMLUtil.getNextSibling(test);
|
||||||
|
}
|
||||||
|
return objects.stream();
|
||||||
|
}
|
||||||
|
|
||||||
|
@BeforeAll
|
||||||
|
public static void setUp() throws FHIRException, IOException {
|
||||||
|
/* Do NOT get a shared worker context from Testing Utilities or else the terminology package loaded below
|
||||||
|
will appear in tests where it causes failures.
|
||||||
|
*/
|
||||||
|
context = TestingUtilities.getWorkerContext(VersionUtilities.getMajMin(TestingUtilities.DEFAULT_CONTEXT_VERSION));
|
||||||
|
if (!context.hasPackage("hl7.terminology", null)) {
|
||||||
|
|
||||||
|
NpmPackage utg = new FilesystemPackageCacheManager(true, ToolsVersion.TOOLS_VERSION).loadPackage("hl7.terminology");
|
||||||
|
System.out.println("Loading THO: "+utg.name()+"#"+utg.version());
|
||||||
|
context.loadFromPackage(utg, new TestPackageLoader(new String[]{"CodeSystem", "ValueSet"}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ParameterizedTest(name = "{index}: file {0}")
|
||||||
|
@MethodSource("data")
|
||||||
|
public void test(String id, TestDetails test) throws Exception {
|
||||||
|
|
||||||
|
Resource source;
|
||||||
|
if (test.getSource().endsWith(".json")) {
|
||||||
|
source = (Resource) new JsonParser().parse(TestingUtilities.loadTestResourceStream("r5", "vocab", test.getSource()));
|
||||||
|
} else {
|
||||||
|
source = (Resource) new XmlParser().parse(TestingUtilities.loadTestResourceStream("r5", "vocab", test.getSource()));
|
||||||
|
}
|
||||||
|
|
||||||
|
Resource target;
|
||||||
|
if (test.getTarget().endsWith(".json")) {
|
||||||
|
target = (Resource) new JsonParser().parse(TestingUtilities.loadTestResourceStream("r5", "vocab", test.getTarget()));
|
||||||
|
} else {
|
||||||
|
target = (Resource) new XmlParser().parse(TestingUtilities.loadTestResourceStream("r5", "vocab", test.getTarget()));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (test.getType() == TestType.Expansion) {
|
||||||
|
testExpansion(test, (ValueSet) source, (ValueSet) target);
|
||||||
|
} else {
|
||||||
|
Assertions.fail("not done yet");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void testExpansion(TestDetails test, ValueSet sourceVS, ValueSet targetVS) throws Exception {
|
||||||
|
ValueSetExpansionOutcome outcome = context.expandVS(sourceVS, false, test.getParameters().containsKey("hierarchical"));
|
||||||
|
if (outcome.isOk()) {
|
||||||
|
outcome.getValueset().getExpansion().setIdentifier(null);
|
||||||
|
outcome.getValueset().getExpansion().setTimestamp(null);
|
||||||
|
String target = new XmlParser().setOutputStyle(OutputStyle.PRETTY).composeString(targetVS);
|
||||||
|
String output = new XmlParser().setOutputStyle(OutputStyle.PRETTY).composeString(outcome.getValueset());
|
||||||
|
String tfn = TestingUtilities.tempFile("vocab", test.getId() + ".target.html");
|
||||||
|
String ofn = TestingUtilities.tempFile("vocab", test.getId() + ".output.html");
|
||||||
|
TextFile.stringToFile(target, tfn);
|
||||||
|
TextFile.stringToFile(output, ofn);
|
||||||
|
String msg = TestingUtilities.checkXMLIsSame(ofn, tfn);
|
||||||
|
Assertions.assertTrue(msg == null, "Output does not match expected: "+msg);
|
||||||
|
} else {
|
||||||
|
Assertions.fail("Expansion Failed: "+outcome.getError());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -86,9 +86,9 @@ public class ResourceTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Element testEM() throws Exception {
|
public Element testEM() throws Exception {
|
||||||
Element resource = Manager.parseSingle(TestingUtilities.context(), new FileInputStream(source), isJson() ? FhirFormat.JSON : FhirFormat.XML);
|
Element resource = Manager.parseSingle(TestingUtilities.getSharedWorkerContext(), new FileInputStream(source), isJson() ? FhirFormat.JSON : FhirFormat.XML);
|
||||||
Manager.compose(TestingUtilities.context(), resource, new FileOutputStream(source.getAbsoluteFile()+".out.json"), FhirFormat.JSON, OutputStyle.PRETTY, null);
|
Manager.compose(TestingUtilities.getSharedWorkerContext(), resource, new FileOutputStream(source.getAbsoluteFile()+".out.json"), FhirFormat.JSON, OutputStyle.PRETTY, null);
|
||||||
Manager.compose(TestingUtilities.context(), resource, new FileOutputStream(source.getAbsoluteFile()+".out.json"), FhirFormat.XML, OutputStyle.PRETTY, null);
|
Manager.compose(TestingUtilities.getSharedWorkerContext(), resource, new FileOutputStream(source.getAbsoluteFile()+".out.json"), FhirFormat.XML, OutputStyle.PRETTY, null);
|
||||||
return resource;
|
return resource;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,8 +4,6 @@ import org.junit.jupiter.api.Assertions;
|
||||||
import org.junit.jupiter.api.DisplayName;
|
import org.junit.jupiter.api.DisplayName;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.*;
|
|
||||||
|
|
||||||
class FHIRLexerTest {
|
class FHIRLexerTest {
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("Test that a 'null' current value returns 'false' when FHIRLexer.isConstant() is called, and not NPE.")
|
@DisplayName("Test that a 'null' current value returns 'false' when FHIRLexer.isConstant() is called, and not NPE.")
|
||||||
|
|
|
@ -1,9 +1,22 @@
|
||||||
package org.hl7.fhir.r5.utils.client;
|
package org.hl7.fhir.r5.utils.client;
|
||||||
|
|
||||||
import okhttp3.Headers;
|
import java.io.IOException;
|
||||||
import okhttp3.Request;
|
import java.net.URI;
|
||||||
import okhttp3.internal.http2.Header;
|
import java.net.URISyntaxException;
|
||||||
import org.hl7.fhir.r5.model.*;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
import org.hl7.fhir.r5.model.Bundle;
|
||||||
|
import org.hl7.fhir.r5.model.CapabilityStatement;
|
||||||
|
import org.hl7.fhir.r5.model.Enumerations;
|
||||||
|
import org.hl7.fhir.r5.model.IdType;
|
||||||
|
import org.hl7.fhir.r5.model.Observation;
|
||||||
|
import org.hl7.fhir.r5.model.OperationOutcome;
|
||||||
|
import org.hl7.fhir.r5.model.Patient;
|
||||||
|
import org.hl7.fhir.r5.model.Quantity;
|
||||||
|
import org.hl7.fhir.r5.model.Reference;
|
||||||
|
import org.hl7.fhir.r5.model.Resource;
|
||||||
|
import org.hl7.fhir.r5.model.TerminologyCapabilities;
|
||||||
import org.hl7.fhir.r5.utils.client.network.Client;
|
import org.hl7.fhir.r5.utils.client.network.Client;
|
||||||
import org.hl7.fhir.r5.utils.client.network.ResourceRequest;
|
import org.hl7.fhir.r5.utils.client.network.ResourceRequest;
|
||||||
import org.junit.jupiter.api.Assertions;
|
import org.junit.jupiter.api.Assertions;
|
||||||
|
@ -13,11 +26,9 @@ import org.mockito.ArgumentCaptor;
|
||||||
import org.mockito.ArgumentMatchers;
|
import org.mockito.ArgumentMatchers;
|
||||||
import org.mockito.Mockito;
|
import org.mockito.Mockito;
|
||||||
|
|
||||||
import java.io.IOException;
|
import okhttp3.Headers;
|
||||||
import java.net.URI;
|
import okhttp3.Request;
|
||||||
import java.net.URISyntaxException;
|
import okhttp3.internal.http2.Header;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
|
|
||||||
class FHIRToolingClientTest {
|
class FHIRToolingClientTest {
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1,15 @@
|
||||||
package org.hl7.fhir.r5.utils.client.network;
|
package org.hl7.fhir.r5.utils.client.network;
|
||||||
|
|
||||||
import okhttp3.internal.http2.Header;
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import org.hl7.fhir.exceptions.FHIRException;
|
import org.hl7.fhir.exceptions.FHIRException;
|
||||||
import org.junit.jupiter.api.Assertions;
|
import org.junit.jupiter.api.Assertions;
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.DisplayName;
|
import org.junit.jupiter.api.DisplayName;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import okhttp3.internal.http2.Header;
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
class ClientHeadersTest {
|
class ClientHeadersTest {
|
||||||
|
|
||||||
|
|
|
@ -1,21 +1,30 @@
|
||||||
package org.hl7.fhir.r5.utils.client.network;
|
package org.hl7.fhir.r5.utils.client.network;
|
||||||
|
|
||||||
import okhttp3.HttpUrl;
|
|
||||||
import okhttp3.mockwebserver.MockResponse;
|
|
||||||
import okhttp3.mockwebserver.MockWebServer;
|
|
||||||
import okhttp3.mockwebserver.RecordedRequest;
|
|
||||||
import org.hl7.fhir.r5.context.HTMLClientLogger;
|
|
||||||
import org.hl7.fhir.r5.formats.JsonParser;
|
|
||||||
import org.hl7.fhir.r5.model.*;
|
|
||||||
import org.junit.jupiter.api.*;
|
|
||||||
import org.mockito.Mockito;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.net.URISyntaxException;
|
import java.net.URISyntaxException;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import org.hl7.fhir.r5.context.HTMLClientLogger;
|
||||||
|
import org.hl7.fhir.r5.formats.JsonParser;
|
||||||
|
import org.hl7.fhir.r5.model.Address;
|
||||||
|
import org.hl7.fhir.r5.model.Enumerations;
|
||||||
|
import org.hl7.fhir.r5.model.HumanName;
|
||||||
|
import org.hl7.fhir.r5.model.Patient;
|
||||||
|
import org.hl7.fhir.r5.model.Resource;
|
||||||
|
import org.junit.jupiter.api.Assertions;
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
import org.junit.jupiter.api.DisplayName;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.TestInstance;
|
||||||
|
import org.mockito.Mockito;
|
||||||
|
|
||||||
|
import okhttp3.HttpUrl;
|
||||||
|
import okhttp3.mockwebserver.MockResponse;
|
||||||
|
import okhttp3.mockwebserver.MockWebServer;
|
||||||
|
import okhttp3.mockwebserver.RecordedRequest;
|
||||||
|
|
||||||
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
||||||
class ClientTest {
|
class ClientTest {
|
||||||
|
|
||||||
|
|
|
@ -1,17 +1,15 @@
|
||||||
package org.hl7.fhir.r5.utils.client.network;
|
package org.hl7.fhir.r5.utils.client.network;
|
||||||
|
|
||||||
import okhttp3.Headers;
|
import java.util.List;
|
||||||
import okhttp3.OkHttpClient;
|
import java.util.Map;
|
||||||
import okhttp3.Request;
|
|
||||||
import org.hl7.fhir.r5.model.OperationOutcome;
|
import org.hl7.fhir.r5.model.OperationOutcome;
|
||||||
import org.junit.jupiter.api.Assertions;
|
import org.junit.jupiter.api.Assertions;
|
||||||
import org.junit.jupiter.api.DisplayName;
|
import org.junit.jupiter.api.DisplayName;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import okhttp3.Headers;
|
||||||
import java.util.HashMap;
|
import okhttp3.Request;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
class FhirRequestBuilderTest {
|
class FhirRequestBuilderTest {
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>org.hl7.fhir.core</artifactId>
|
<artifactId>org.hl7.fhir.core</artifactId>
|
||||||
<version>5.6.35</version>
|
<version>5.6.38-SNAPSHOT</version>
|
||||||
<relativePath>../pom.xml</relativePath>
|
<relativePath>../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>org.hl7.fhir.core</artifactId>
|
<artifactId>org.hl7.fhir.core</artifactId>
|
||||||
<version>5.6.35</version>
|
<version>5.6.38-SNAPSHOT</version>
|
||||||
<relativePath>../pom.xml</relativePath>
|
<relativePath>../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -366,6 +366,8 @@ public class I18nConstants {
|
||||||
public static final String SD_ED_TYPE_PROFILE_UNKNOWN = "SD_ED_TYPE_PROFILE_UNKNOWN";
|
public static final String SD_ED_TYPE_PROFILE_UNKNOWN = "SD_ED_TYPE_PROFILE_UNKNOWN";
|
||||||
public static final String SD_ED_TYPE_PROFILE_NOTYPE = "SD_ED_TYPE_PROFILE_NOTYPE";
|
public static final String SD_ED_TYPE_PROFILE_NOTYPE = "SD_ED_TYPE_PROFILE_NOTYPE";
|
||||||
public static final String SD_ED_TYPE_PROFILE_WRONG = "SD_ED_TYPE_PROFILE_WRONG";
|
public static final String SD_ED_TYPE_PROFILE_WRONG = "SD_ED_TYPE_PROFILE_WRONG";
|
||||||
|
public static final String SD_ED_TYPE_PROFILE_IS_MODIFIER = "SD_ED_TYPE_PROFILE_IS_MODIFIER";
|
||||||
|
public static final String SD_ED_TYPE_PROFILE_NOT_MODIFIER = "SD_ED_TYPE_PROFILE_NOT_MODIFIER";
|
||||||
public static final String SD_ED_TYPE_PROFILE_WRONG_TARGET = "SD_ED_TYPE_PROFILE_WRONG_TARGET";
|
public static final String SD_ED_TYPE_PROFILE_WRONG_TARGET = "SD_ED_TYPE_PROFILE_WRONG_TARGET";
|
||||||
public static final String SD_ED_TYPE_NO_TARGET_PROFILE = "SD_ED_TYPE_NO_TARGET_PROFILE";
|
public static final String SD_ED_TYPE_NO_TARGET_PROFILE = "SD_ED_TYPE_NO_TARGET_PROFILE";
|
||||||
public static final String SD_ED_SHOULD_BIND = "SD_ED_SHOULD_BIND";
|
public static final String SD_ED_SHOULD_BIND = "SD_ED_SHOULD_BIND";
|
||||||
|
|
|
@ -3,7 +3,7 @@ package org.hl7.fhir.utilities.npm;
|
||||||
public class CommonPackages {
|
public class CommonPackages {
|
||||||
|
|
||||||
public static final String ID_XVER = "hl7.fhir.xver-extensions";
|
public static final String ID_XVER = "hl7.fhir.xver-extensions";
|
||||||
public static final String VER_XVER = "0.0.8";
|
public static final String VER_XVER = "0.0.11";
|
||||||
|
|
||||||
public static final String ID_PUBPACK = "hl7.fhir.pubpack";
|
public static final String ID_PUBPACK = "hl7.fhir.pubpack";
|
||||||
public static final String VER_PUBPACK = "0.0.9";
|
public static final String VER_PUBPACK = "0.0.9";
|
||||||
|
|
|
@ -16,7 +16,6 @@ import java.io.ByteArrayInputStream;
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.net.URL;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
@ -82,10 +81,10 @@ public class PackageClient {
|
||||||
if (versions != null) {
|
if (versions != null) {
|
||||||
for (String v : sorted(versions.keySet())) {
|
for (String v : sorted(versions.keySet())) {
|
||||||
JsonObject obj = versions.getAsJsonObject(v);
|
JsonObject obj = versions.getAsJsonObject(v);
|
||||||
res.add(new PackageInfo(JSONUtil.str(obj, "name"),
|
res.add(new PackageInfo(JSONUtil.str(obj, "Name", "name"),
|
||||||
JSONUtil.str(obj, "version"),
|
JSONUtil.str(obj, "Version", "version"),
|
||||||
JSONUtil.str(obj, "FhirVersion"),
|
JSONUtil.str(obj, "FhirVersion", "fhirVersion"),
|
||||||
JSONUtil.str(obj, "description"),
|
JSONUtil.str(obj, "Description", "description"),
|
||||||
JSONUtil.str(obj, "url"),
|
JSONUtil.str(obj, "url"),
|
||||||
JSONUtil.str(obj, "canonical"),
|
JSONUtil.str(obj, "canonical"),
|
||||||
address));
|
address));
|
||||||
|
@ -192,42 +191,51 @@ public class PackageClient {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected PackageInfo getPackageInfoFromJSON(JsonObject o, String name, String canonical, String fhirVersion) {
|
||||||
|
String id = JSONUtil.str(o, "npm-name");
|
||||||
|
String pname = JSONUtil.str(o, "name");
|
||||||
|
String pcanonical = JSONUtil.str(o, "canonical");
|
||||||
|
String description = JSONUtil.str(o, "description");
|
||||||
|
boolean ok = true;
|
||||||
|
if (ok && !Utilities.noString(name)) {
|
||||||
|
ok = (pname != null && pname.contains(name)) || (description != null && description.contains(name)) || (id != null && id.contains(name));
|
||||||
|
}
|
||||||
|
if (ok && !Utilities.noString(canonical)) {
|
||||||
|
ok = pcanonical.contains(canonical);
|
||||||
|
}
|
||||||
|
String version = null;
|
||||||
|
String fVersion = null;
|
||||||
|
String url = null;
|
||||||
|
|
||||||
|
if (ok) {
|
||||||
|
// if we can find something...
|
||||||
|
for (JsonObject e : JSONUtil.objects(o, "editions")) {
|
||||||
|
if (fhirVersion == null || fhirVersion.equals(JSONUtil.str(e, "fhir-version"))) {
|
||||||
|
String v = JSONUtil.str(e, "ig-version");
|
||||||
|
if (version == null || VersionUtilities.isThisOrLater(version, v)) {
|
||||||
|
version = v;
|
||||||
|
fVersion = e.getAsJsonArray("fhir-version").get(0).getAsString();
|
||||||
|
url = JSONUtil.str(e, "url");
|
||||||
|
|
||||||
|
String npmPackage = JSONUtil.str(e, "package");
|
||||||
|
if (npmPackage != null && id == null) {
|
||||||
|
id = npmPackage.substring(0, npmPackage.indexOf("#"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new PackageInfo(id, version, fVersion, description, url, pcanonical, address);
|
||||||
|
}
|
||||||
|
|
||||||
public List<PackageInfo> listFromRegistry(String name, String canonical, String fhirVersion) throws IOException {
|
public List<PackageInfo> listFromRegistry(String name, String canonical, String fhirVersion) throws IOException {
|
||||||
List<PackageInfo> result = new ArrayList<>();
|
List<PackageInfo> result = new ArrayList<>();
|
||||||
JsonObject packages = JsonTrackingParser.fetchJson("https://raw.githubusercontent.com/FHIR/ig-registry/master/fhir-ig-list.json?nocache=" + System.currentTimeMillis());
|
JsonObject packages = JsonTrackingParser.fetchJson("https://raw.githubusercontent.com/FHIR/ig-registry/master/fhir-ig-list.json?nocache=" + System.currentTimeMillis());
|
||||||
for (JsonObject o : JSONUtil.objects(packages, "guides")) {
|
for (JsonObject o : JSONUtil.objects(packages, "guides")) {
|
||||||
if (o.has("canonical")) {
|
if (o.has("canonical")) {
|
||||||
String id = JSONUtil.str(o, "npm-name");
|
final PackageInfo packageInfo = getPackageInfoFromJSON(o, name, canonical, fhirVersion);
|
||||||
String pname = JSONUtil.str(o, "name");
|
if (packageInfo.getVersion() != null) {
|
||||||
String pcanonical = JSONUtil.str(o, "canonical");
|
result.add(packageInfo);
|
||||||
String description = JSONUtil.str(o, "description");
|
|
||||||
boolean ok = true;
|
|
||||||
if (ok && !Utilities.noString(name)) {
|
|
||||||
ok = (pname != null && pname.contains(name)) || (description != null && description.contains(name)) || (id != null && id.contains(name));
|
|
||||||
}
|
|
||||||
if (ok && !Utilities.noString(canonical)) {
|
|
||||||
ok = pcanonical.contains(canonical);
|
|
||||||
}
|
|
||||||
String version = null;
|
|
||||||
String fVersion = null;
|
|
||||||
String url = null;
|
|
||||||
|
|
||||||
if (ok) {
|
|
||||||
// if we can find something...
|
|
||||||
for (JsonObject e : JSONUtil.objects(o, "editions")) {
|
|
||||||
if (fhirVersion == null || fhirVersion.equals(JSONUtil.str(e, "fhir-version"))) {
|
|
||||||
String v = JSONUtil.str(e, "ig-version");
|
|
||||||
if (version == null || VersionUtilities.isThisOrLater(version, v)) {
|
|
||||||
version = v;
|
|
||||||
fVersion = e.getAsJsonArray("fhir-version").get(0).getAsString();
|
|
||||||
url = JSONUtil.str(e, "url");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (version != null) {
|
|
||||||
result.add(new PackageInfo(id, version, fVersion, description, url, pcanonical, address));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -403,6 +403,11 @@ public class HierarchicalTableGenerator extends TranslatingUtilities {
|
||||||
pieces.add(p);
|
pieces.add(p);
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
public Piece addText(String text) {
|
||||||
|
Piece p = new Piece(null, text, null);
|
||||||
|
pieces.add(p);
|
||||||
|
return p;
|
||||||
|
}
|
||||||
public String text() {
|
public String text() {
|
||||||
StringBuilder b = new StringBuilder();
|
StringBuilder b = new StringBuilder();
|
||||||
for (Piece p : pieces)
|
for (Piece p : pieces)
|
||||||
|
|
|
@ -273,9 +273,9 @@ public class XMLUtil {
|
||||||
|
|
||||||
for (int i = 0; i < rawContent.length(); i++) {
|
for (int i = 0; i < rawContent.length(); i++) {
|
||||||
char ch = rawContent.charAt(i);
|
char ch = rawContent.charAt(i);
|
||||||
if (ch == '\'')
|
// We don't escape ' because our code always spits out attributes surrounded by "", which means
|
||||||
sb.append("'");
|
// it's not necessary to escape ' - and it's *much* less ugly and more bandwidth-efficient when we don't.
|
||||||
else if (ch == '&')
|
if (ch == '&')
|
||||||
sb.append("&");
|
sb.append("&");
|
||||||
else if (ch == '"')
|
else if (ch == '"')
|
||||||
sb.append(""");
|
sb.append(""");
|
||||||
|
|
|
@ -629,6 +629,8 @@ Unable_to_connect_to_terminology_server = Unable to connect to terminology serve
|
||||||
SD_ED_TYPE_PROFILE_UNKNOWN = Unable to resolve profile {0}
|
SD_ED_TYPE_PROFILE_UNKNOWN = Unable to resolve profile {0}
|
||||||
SD_ED_TYPE_PROFILE_NOTYPE = Found profile {0}, but unable to determine the type it applies to
|
SD_ED_TYPE_PROFILE_NOTYPE = Found profile {0}, but unable to determine the type it applies to
|
||||||
SD_ED_TYPE_PROFILE_WRONG = Profile {0} is for type {1}, but the {3} element has type {2}
|
SD_ED_TYPE_PROFILE_WRONG = Profile {0} is for type {1}, but the {3} element has type {2}
|
||||||
|
SD_ED_TYPE_PROFILE_IS_MODIFIER = Profile {0} is for not for a modifier extension, but the {3} element is a modifier
|
||||||
|
SD_ED_TYPE_PROFILE_NOT_MODIFIER = Profile {0} is for a modifier extension, but the {3} element is not a modifier
|
||||||
SD_ED_TYPE_PROFILE_WRONG_TARGET = Profile {0} is for type {1}, which is not a {4} (which is required because the {3} element has type {2})
|
SD_ED_TYPE_PROFILE_WRONG_TARGET = Profile {0} is for type {1}, which is not a {4} (which is required because the {3} element has type {2})
|
||||||
SD_ED_TYPE_NO_TARGET_PROFILE = Type {0} does not allow for target Profiles
|
SD_ED_TYPE_NO_TARGET_PROFILE = Type {0} does not allow for target Profiles
|
||||||
TERMINOLOGY_TX_NOSVC_BOUND_REQ = Could not confirm that the codes provided are from the required value set {0} because there is no terminology service
|
TERMINOLOGY_TX_NOSVC_BOUND_REQ = Could not confirm that the codes provided are from the required value set {0} because there is no terminology service
|
||||||
|
|
|
@ -39,7 +39,11 @@ class UtilitiesTest {
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("Test Utilities.path maps temp directory correctly")
|
@DisplayName("Test Utilities.path maps temp directory correctly")
|
||||||
public void testTempDirPath() throws IOException {
|
public void testTempDirPath() throws IOException {
|
||||||
Assertions.assertEquals(Utilities.path("[tmp]", TEST_TXT), getTempDirectory() + TEST_TXT);
|
if (ToolGlobalSettings.hasTempPath()) {
|
||||||
|
Assertions.assertEquals(Utilities.path("[tmp]", TEST_TXT), ToolGlobalSettings.getTempPath() +File.separator+ TEST_TXT);
|
||||||
|
} else {
|
||||||
|
Assertions.assertEquals(Utilities.path("[tmp]", TEST_TXT), getTempDirectory() + TEST_TXT);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
@ -0,0 +1,44 @@
|
||||||
|
package org.hl7.fhir.utilities.npm;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
|
import org.junit.jupiter.api.DisplayName;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
|
public class PackageClientTest {
|
||||||
|
|
||||||
|
PackageClient packageClient = new PackageClient(PackageClient.PRIMARY_SERVER);
|
||||||
|
|
||||||
|
private void assertExpectedFields(final PackageInfo packageInfo) {
|
||||||
|
assertEquals("dummy.package", packageInfo.getId());
|
||||||
|
assertEquals("1.2.3", packageInfo.getVersion());
|
||||||
|
assertEquals("4.5.6", packageInfo.getFhirVersion());
|
||||||
|
assertEquals("Dummy description",
|
||||||
|
packageInfo.getDescription());
|
||||||
|
assertEquals("https://d.e.f", packageInfo.getUrl());
|
||||||
|
assertEquals("https://a.b.c", packageInfo.getCanonical());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("test getting package from JSON works")
|
||||||
|
public void getPackageInfoFromJSONTest() throws java.io.IOException{
|
||||||
|
final JsonObject jsonObject = new Gson().fromJson(Files.newBufferedReader(Paths.get("src", "test", "resources", "npm", "PackageClient-baseTestCase.json")), JsonObject.class);
|
||||||
|
final PackageInfo packageInfo = packageClient.getPackageInfoFromJSON(jsonObject, null, null, null);
|
||||||
|
|
||||||
|
assertExpectedFields(packageInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("test getting package from JSON works")
|
||||||
|
public void getPackageInfoWithIdFromJSONTest() throws java.io.IOException {
|
||||||
|
final JsonObject jsonObject = new Gson().fromJson(Files.newBufferedReader(Paths.get("src", "test", "resources", "npm", "PackageClient-testCaseWithId.json")), JsonObject.class);
|
||||||
|
final PackageInfo packageInfo = packageClient.getPackageInfoFromJSON(jsonObject, null, null, null);
|
||||||
|
|
||||||
|
assertExpectedFields(packageInfo);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
package org.hl7.fhir.utilities.tests;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Assertions;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
public class RegexTests {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testPath1() throws IOException {
|
||||||
|
Assertions.assertFalse("http://fhir.org/guides/cqf/common/Library/FHIR-ModelInfo|4.0.1".matches("Library"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testPath2() throws IOException {
|
||||||
|
Assertions.assertTrue("http://fhir.org/guides/cqf/common/Library/FHIR-ModelInfo|4.0.1".matches(".*Library.*"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testPath3() throws IOException {
|
||||||
|
Assertions.assertTrue("http://fhir.org/guides/cqf/common/Library/FHIR-ModelInfo|4.0.1".matches("(?s).*Library.*"));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
{
|
||||||
|
"name": "Pan-Canadian Patient Summary",
|
||||||
|
"description": "Dummy description",
|
||||||
|
"canonical": "https://a.b.c",
|
||||||
|
"editions": [
|
||||||
|
{
|
||||||
|
"name": "Dummy name",
|
||||||
|
"ig-version": "1.2.3",
|
||||||
|
"package": "dummy.package#1.2.3",
|
||||||
|
"fhir-version": [
|
||||||
|
"4.5.6"
|
||||||
|
],
|
||||||
|
"url": "https://d.e.f"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
{
|
||||||
|
"name": "Pan-Canadian Patient Summary",
|
||||||
|
"description": "Dummy description",
|
||||||
|
"canonical": "https://a.b.c",
|
||||||
|
"npm-name": "dummy.package",
|
||||||
|
"editions": [
|
||||||
|
{
|
||||||
|
"name": "Dummy name",
|
||||||
|
"ig-version": "1.2.3",
|
||||||
|
"package": "not.a.dummy.package#1.2.3",
|
||||||
|
"fhir-version": [
|
||||||
|
"4.5.6"
|
||||||
|
],
|
||||||
|
"url": "https://d.e.f"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>org.hl7.fhir.core</artifactId>
|
<artifactId>org.hl7.fhir.core</artifactId>
|
||||||
<version>5.6.35</version>
|
<version>5.6.38-SNAPSHOT</version>
|
||||||
<relativePath>../pom.xml</relativePath>
|
<relativePath>../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
@ -76,7 +76,7 @@
|
||||||
<goal>unpack-dependencies</goal>
|
<goal>unpack-dependencies</goal>
|
||||||
</goals>
|
</goals>
|
||||||
<configuration>
|
<configuration>
|
||||||
<excludes>**/module-info.class,META-INF/*.SF,META-INF/*.DSA,META-INF/*.RSA</excludes>
|
<excludes>**/module-info.class,META-INF/*</excludes>
|
||||||
<outputDirectory>${project.build.directory}/classes</outputDirectory>
|
<outputDirectory>${project.build.directory}/classes</outputDirectory>
|
||||||
<overWriteReleases>false</overWriteReleases>
|
<overWriteReleases>false</overWriteReleases>
|
||||||
<overWriteSnapshots>true</overWriteSnapshots>
|
<overWriteSnapshots>true</overWriteSnapshots>
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>org.hl7.fhir.core</artifactId>
|
<artifactId>org.hl7.fhir.core</artifactId>
|
||||||
<version>5.6.35</version>
|
<version>5.6.38-SNAPSHOT</version>
|
||||||
<relativePath>../pom.xml</relativePath>
|
<relativePath>../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -3405,13 +3405,17 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
||||||
return elements;
|
return elements;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boolean dontFollowReference = false;
|
||||||
|
|
||||||
if (removeResolve) { // if we're doing profile slicing, we don't want to walk into the last resolve.. we need the profile on the source not the target
|
if (removeResolve) { // if we're doing profile slicing, we don't want to walk into the last resolve.. we need the profile on the source not the target
|
||||||
if (discriminator.equals("resolve()")) {
|
if (discriminator.equals("resolve()")) {
|
||||||
elements.add(element);
|
elements.add(element);
|
||||||
return elements;
|
return elements;
|
||||||
}
|
}
|
||||||
if (discriminator.endsWith(".resolve()"))
|
if (discriminator.endsWith(".resolve()")) {
|
||||||
discriminator = discriminator.substring(0, discriminator.length() - 10);
|
discriminator = discriminator.substring(0, discriminator.length() - 10);
|
||||||
|
dontFollowReference = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TypedElementDefinition ted = null;
|
TypedElementDefinition ted = null;
|
||||||
|
@ -3424,7 +3428,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
||||||
throw new FHIRException(context.formatMessage(I18nConstants.DISCRIMINATOR_BAD_PATH, e.getMessage(), fp), e);
|
throw new FHIRException(context.formatMessage(I18nConstants.DISCRIMINATOR_BAD_PATH, e.getMessage(), fp), e);
|
||||||
}
|
}
|
||||||
long t2 = System.nanoTime();
|
long t2 = System.nanoTime();
|
||||||
ted = fpe.evaluateDefinition(expr, profile, new TypedElementDefinition(element), srcProfile);
|
ted = fpe.evaluateDefinition(expr, profile, new TypedElementDefinition(element), srcProfile, dontFollowReference);
|
||||||
timeTracker.sd(t2);
|
timeTracker.sd(t2);
|
||||||
if (ted != null)
|
if (ted != null)
|
||||||
elements.add(ted.getElement());
|
elements.add(ted.getElement());
|
||||||
|
@ -3449,7 +3453,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
||||||
}
|
}
|
||||||
expr = fpe.parse(fp);
|
expr = fpe.parse(fp);
|
||||||
t2 = System.nanoTime();
|
t2 = System.nanoTime();
|
||||||
ted = fpe.evaluateDefinition(expr, profile, new TypedElementDefinition(element), srcProfile);
|
ted = fpe.evaluateDefinition(expr, profile, new TypedElementDefinition(element), srcProfile, dontFollowReference);
|
||||||
timeTracker.sd(t2);
|
timeTracker.sd(t2);
|
||||||
if (ted != null)
|
if (ted != null)
|
||||||
elements.add(ted.getElement());
|
elements.add(ted.getElement());
|
||||||
|
|
|
@ -27,7 +27,7 @@ import org.hl7.fhir.validation.instance.utils.IndexedElement;
|
||||||
import org.hl7.fhir.validation.instance.utils.NodeStack;
|
import org.hl7.fhir.validation.instance.utils.NodeStack;
|
||||||
import org.hl7.fhir.validation.instance.utils.ValidatorHostContext;
|
import org.hl7.fhir.validation.instance.utils.ValidatorHostContext;
|
||||||
|
|
||||||
public class BundleValidator extends BaseValidator{
|
public class BundleValidator extends BaseValidator {
|
||||||
public final static String URI_REGEX3 = "((http|https)://([A-Za-z0-9\\\\\\.\\:\\%\\$]*\\/)*)?(Account|ActivityDefinition|AllergyIntolerance|AdverseEvent|Appointment|AppointmentResponse|AuditEvent|Basic|Binary|BodySite|Bundle|CapabilityStatement|CarePlan|CareTeam|ChargeItem|Claim|ClaimResponse|ClinicalImpression|CodeSystem|Communication|CommunicationRequest|CompartmentDefinition|Composition|ConceptMap|Condition (aka Problem)|Consent|Contract|Coverage|DataElement|DetectedIssue|Device|DeviceComponent|DeviceMetric|DeviceRequest|DeviceUseStatement|DiagnosticReport|DocumentManifest|DocumentReference|EligibilityRequest|EligibilityResponse|Encounter|Endpoint|EnrollmentRequest|EnrollmentResponse|EpisodeOfCare|ExpansionProfile|ExplanationOfBenefit|FamilyMemberHistory|Flag|Goal|GraphDefinition|Group|GuidanceResponse|HealthcareService|ImagingManifest|ImagingStudy|Immunization|ImmunizationRecommendation|ImplementationGuide|Library|Linkage|List|Location|Measure|MeasureReport|Media|Medication|MedicationAdministration|MedicationDispense|MedicationRequest|MedicationStatement|MessageDefinition|MessageHeader|NamingSystem|NutritionOrder|Observation|OperationDefinition|OperationOutcome|Organization|Parameters|Patient|PaymentNotice|PaymentReconciliation|Person|PlanDefinition|Practitioner|PractitionerRole|Procedure|ProcedureRequest|ProcessRequest|ProcessResponse|Provenance|Questionnaire|QuestionnaireResponse|ReferralRequest|RelatedPerson|RequestGroup|ResearchStudy|ResearchSubject|RiskAssessment|Schedule|SearchParameter|Sequence|ServiceDefinition|Slot|Specimen|StructureDefinition|StructureMap|Subscription|Substance|SupplyDelivery|SupplyRequest|Task|TestScript|TestReport|ValueSet|VisionPrescription)\\/[A-Za-z0-9\\-\\.]{1,64}(\\/_history\\/[A-Za-z0-9\\-\\.]{1,64})?";
|
public final static String URI_REGEX3 = "((http|https)://([A-Za-z0-9\\\\\\.\\:\\%\\$]*\\/)*)?(Account|ActivityDefinition|AllergyIntolerance|AdverseEvent|Appointment|AppointmentResponse|AuditEvent|Basic|Binary|BodySite|Bundle|CapabilityStatement|CarePlan|CareTeam|ChargeItem|Claim|ClaimResponse|ClinicalImpression|CodeSystem|Communication|CommunicationRequest|CompartmentDefinition|Composition|ConceptMap|Condition (aka Problem)|Consent|Contract|Coverage|DataElement|DetectedIssue|Device|DeviceComponent|DeviceMetric|DeviceRequest|DeviceUseStatement|DiagnosticReport|DocumentManifest|DocumentReference|EligibilityRequest|EligibilityResponse|Encounter|Endpoint|EnrollmentRequest|EnrollmentResponse|EpisodeOfCare|ExpansionProfile|ExplanationOfBenefit|FamilyMemberHistory|Flag|Goal|GraphDefinition|Group|GuidanceResponse|HealthcareService|ImagingManifest|ImagingStudy|Immunization|ImmunizationRecommendation|ImplementationGuide|Library|Linkage|List|Location|Measure|MeasureReport|Media|Medication|MedicationAdministration|MedicationDispense|MedicationRequest|MedicationStatement|MessageDefinition|MessageHeader|NamingSystem|NutritionOrder|Observation|OperationDefinition|OperationOutcome|Organization|Parameters|Patient|PaymentNotice|PaymentReconciliation|Person|PlanDefinition|Practitioner|PractitionerRole|Procedure|ProcedureRequest|ProcessRequest|ProcessResponse|Provenance|Questionnaire|QuestionnaireResponse|ReferralRequest|RelatedPerson|RequestGroup|ResearchStudy|ResearchSubject|RiskAssessment|Schedule|SearchParameter|Sequence|ServiceDefinition|Slot|Specimen|StructureDefinition|StructureMap|Subscription|Substance|SupplyDelivery|SupplyRequest|Task|TestScript|TestReport|ValueSet|VisionPrescription)\\/[A-Za-z0-9\\-\\.]{1,64}(\\/_history\\/[A-Za-z0-9\\-\\.]{1,64})?";
|
||||||
private String serverBase;
|
private String serverBase;
|
||||||
private InstanceValidator validator;
|
private InstanceValidator validator;
|
||||||
|
|
|
@ -294,6 +294,15 @@ public class StructureDefinitionValidator extends BaseValidator {
|
||||||
rule(errors, IssueType.EXCEPTION, stack.getLiteralPath(), false, I18nConstants.SD_ED_TYPE_PROFILE_NOTYPE, p);
|
rule(errors, IssueType.EXCEPTION, stack.getLiteralPath(), false, I18nConstants.SD_ED_TYPE_PROFILE_NOTYPE, p);
|
||||||
} else {
|
} else {
|
||||||
rule(errors, IssueType.EXCEPTION, stack.getLiteralPath(), isInstanceOf(t, code), I18nConstants.SD_ED_TYPE_PROFILE_WRONG, p, t, code, path);
|
rule(errors, IssueType.EXCEPTION, stack.getLiteralPath(), isInstanceOf(t, code), I18nConstants.SD_ED_TYPE_PROFILE_WRONG, p, t, code, path);
|
||||||
|
if (t.getType().equals("Extension")) {
|
||||||
|
boolean isModifierDefinition = checkIsModifierExtension(sd);
|
||||||
|
boolean isModifierContext = path.endsWith(".modifierExtension");
|
||||||
|
if (isModifierDefinition) {
|
||||||
|
rule(errors, IssueType.EXCEPTION, stack.getLiteralPath(), isModifierContext, I18nConstants.SD_ED_TYPE_PROFILE_NOT_MODIFIER, p, t, code, path);
|
||||||
|
} else {
|
||||||
|
rule(errors, IssueType.EXCEPTION, stack.getLiteralPath(), !isModifierContext, I18nConstants.SD_ED_TYPE_PROFILE_IS_MODIFIER, p, t, code, path);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -325,10 +334,24 @@ public class StructureDefinitionValidator extends BaseValidator {
|
||||||
rule(errors, IssueType.EXCEPTION, stack.getLiteralPath(), false, I18nConstants.SD_ED_TYPE_PROFILE_NOTYPE, p);
|
rule(errors, IssueType.EXCEPTION, stack.getLiteralPath(), false, I18nConstants.SD_ED_TYPE_PROFILE_NOTYPE, p);
|
||||||
} else if (!isInstanceOf(t, code)) {
|
} else if (!isInstanceOf(t, code)) {
|
||||||
rule(errors, IssueType.EXCEPTION, stack.getLiteralPath(), false, I18nConstants.SD_ED_TYPE_PROFILE_WRONG, p, t, code, path);
|
rule(errors, IssueType.EXCEPTION, stack.getLiteralPath(), false, I18nConstants.SD_ED_TYPE_PROFILE_WRONG, p, t, code, path);
|
||||||
|
} else {
|
||||||
|
if (t.getType().equals("Extension")) {
|
||||||
|
boolean isModifierDefinition = checkIsModifierExtension(sd);
|
||||||
|
boolean isModifierContext = path.endsWith(".modifierExtension");
|
||||||
|
if (isModifierDefinition) {
|
||||||
|
rule(errors, IssueType.EXCEPTION, stack.getLiteralPath(), isModifierContext, I18nConstants.SD_ED_TYPE_PROFILE_NOT_MODIFIER, p, t, code, path);
|
||||||
|
} else {
|
||||||
|
rule(errors, IssueType.EXCEPTION, stack.getLiteralPath(), !isModifierContext, I18nConstants.SD_ED_TYPE_PROFILE_IS_MODIFIER, p, t, code, path);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean checkIsModifierExtension(StructureDefinition t) {
|
||||||
|
return t.getSnapshot().getElementFirstRep().getIsModifier();
|
||||||
|
}
|
||||||
|
|
||||||
private void validateTargetProfile(List<ValidationMessage> errors, Element profile, String code, NodeStack stack, String path) {
|
private void validateTargetProfile(List<ValidationMessage> errors, Element profile, String code, NodeStack stack, String path) {
|
||||||
String p = profile.primitiveValue();
|
String p = profile.primitiveValue();
|
||||||
StructureDefinition sd = context.fetchResource(StructureDefinition.class, p);
|
StructureDefinition sd = context.fetchResource(StructureDefinition.class, p);
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue