Fix issue with comparer not rendering properly and add explicit checks around cardinality
This commit is contained in:
parent
73737b5b4c
commit
ecad7cc5f8
|
@ -304,3 +304,4 @@ local.properties
|
||||||
/org.hl7.fhir.r5/src/test/resources/snapshot-generation/logical2-actual.xml
|
/org.hl7.fhir.r5/src/test/resources/snapshot-generation/logical2-actual.xml
|
||||||
/org.hl7.fhir.r5.new
|
/org.hl7.fhir.r5.new
|
||||||
/org.hl7.fhir.r5.newc
|
/org.hl7.fhir.r5.newc
|
||||||
|
/org.hl7.fhir.r4b.new
|
||||||
|
|
|
@ -0,0 +1,74 @@
|
||||||
|
package org.hl7.fhir.convertors.misc;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.hl7.fhir.convertors.factory.VersionConvertorFactory_30_50;
|
||||||
|
import org.hl7.fhir.convertors.factory.VersionConvertorFactory_40_50;
|
||||||
|
import org.hl7.fhir.exceptions.FHIRFormatError;
|
||||||
|
import org.hl7.fhir.r4b.formats.JsonParser;
|
||||||
|
import org.hl7.fhir.r4b.model.Bundle;
|
||||||
|
import org.hl7.fhir.r4b.model.Bundle.BundleEntryComponent;
|
||||||
|
import org.hl7.fhir.utilities.TextFile;
|
||||||
|
import org.hl7.fhir.utilities.Utilities;
|
||||||
|
import org.hl7.fhir.utilities.json.JsonTrackingParser;
|
||||||
|
|
||||||
|
import com.google.gson.JsonArray;
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
|
|
||||||
|
import org.hl7.fhir.r4b.model.SearchParameter;
|
||||||
|
import org.hl7.fhir.r4b.utils.NPMPackageGenerator;
|
||||||
|
import org.hl7.fhir.r4b.utils.NPMPackageGenerator.Category;
|
||||||
|
|
||||||
|
public class ExamplesPackageBuilder {
|
||||||
|
|
||||||
|
public static void main(String[] args) throws FHIRFormatError, FileNotFoundException, IOException {
|
||||||
|
new ExamplesPackageBuilder().process(args[0]);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void process(String source) throws FHIRFormatError, FileNotFoundException, IOException {
|
||||||
|
Set<String> set = new HashSet<>();
|
||||||
|
for (File f : new File(source).listFiles()) {
|
||||||
|
if (f.getName().endsWith(".json")) {
|
||||||
|
JsonObject obj = JsonTrackingParser.parseJson(new FileInputStream(f));
|
||||||
|
if (obj.has("resourceType") && obj.has("id")) {
|
||||||
|
String type = obj.get("resourceType").getAsString();
|
||||||
|
String id = obj.get("id").getAsString();
|
||||||
|
byte[] content = TextFile.fileToBytes(f);
|
||||||
|
if (type.equals("ConceptMap")) {
|
||||||
|
System.out.println("convert "+f.getName());
|
||||||
|
content = r5ToR4B(content);
|
||||||
|
TextFile.bytesToFile(content, f);
|
||||||
|
}
|
||||||
|
// TextFile.bytesToFile(content, Utilities.path(dest2, type+"-"+id+".json"));
|
||||||
|
// if (!set.contains(type+"/"+id)) {
|
||||||
|
// set.add(type+"/"+id);
|
||||||
|
// pck.addFile(Category.RESOURCE, type+"-"+id+".json", content);
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// pck.finish();
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
private byte[] r5ToR4B(byte[] content) throws FHIRFormatError, IOException {
|
||||||
|
try {
|
||||||
|
org.hl7.fhir.r5.model.Resource r5 = new org.hl7.fhir.r5.formats.JsonParser().parse(content);
|
||||||
|
org.hl7.fhir.r4.model.Resource r4 = VersionConvertorFactory_40_50.convertResource(r5);
|
||||||
|
return new org.hl7.fhir.r4.formats.JsonParser().composeBytes(r4);
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.out.println(" .. failed: "+e.getMessage());
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,87 @@
|
||||||
|
package org.hl7.fhir.core.generator.engine;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import org.hl7.fhir.convertors.factory.VersionConvertorFactory_40_50;
|
||||||
|
import org.hl7.fhir.exceptions.FHIRFormatError;
|
||||||
|
import org.hl7.fhir.r4.formats.JsonParser;
|
||||||
|
import org.hl7.fhir.r4.model.Bundle;
|
||||||
|
import org.hl7.fhir.r4.model.Bundle.BundleEntryComponent;
|
||||||
|
import org.hl7.fhir.r5.model.CapabilityStatement;
|
||||||
|
import org.hl7.fhir.r5.model.CodeSystem;
|
||||||
|
import org.hl7.fhir.r5.model.CompartmentDefinition;
|
||||||
|
import org.hl7.fhir.r5.model.ConceptMap;
|
||||||
|
import org.hl7.fhir.r5.model.OperationDefinition;
|
||||||
|
import org.hl7.fhir.r5.model.Resource;
|
||||||
|
import org.hl7.fhir.r5.model.SearchParameter;
|
||||||
|
import org.hl7.fhir.r5.model.StructureDefinition;
|
||||||
|
import org.hl7.fhir.r5.model.ValueSet;
|
||||||
|
import org.hl7.fhir.utilities.Utilities;
|
||||||
|
import org.hl7.fhir.utilities.npm.NpmPackage;
|
||||||
|
import org.hl7.fhir.utilities.npm.ToolsVersion;
|
||||||
|
|
||||||
|
public class DefinitionsLoaderR4B {
|
||||||
|
|
||||||
|
public static Definitions load(NpmPackage npm) throws IOException {
|
||||||
|
Definitions res = new Definitions();
|
||||||
|
|
||||||
|
for (String t : npm.listResources("CodeSystem")) {
|
||||||
|
res.getCodeSystems().see((CodeSystem) load(npm, t), null);
|
||||||
|
}
|
||||||
|
for (String t : npm.listResources("ValueSet")) {
|
||||||
|
res.getValuesets().see((ValueSet) load(npm, t), null);
|
||||||
|
}
|
||||||
|
for (String t : npm.listResources("ConceptMap")) {
|
||||||
|
res.getConceptMaps().see((ConceptMap) load(npm, t), null);
|
||||||
|
}
|
||||||
|
for (String t : npm.listResources("CapabilityStatement")) {
|
||||||
|
res.getStatements().see((CapabilityStatement) load(npm, t), null);
|
||||||
|
}
|
||||||
|
for (String t : npm.listResources("StructureDefinition")) {
|
||||||
|
res.getStructures().see((StructureDefinition) load(npm, t), null);
|
||||||
|
}
|
||||||
|
for (String t : npm.listResources("OperationDefinition")) {
|
||||||
|
res.getOperations().see((OperationDefinition) load(npm, t), null);
|
||||||
|
}
|
||||||
|
for (String t : npm.listResources("SearchParameter")) {
|
||||||
|
res.getSearchParams().see((SearchParameter) load(npm, t), null);
|
||||||
|
}
|
||||||
|
for (String t : npm.listResources("CompartmentDefinition")) {
|
||||||
|
res.getCompartments().see((CompartmentDefinition) load(npm, t), null);
|
||||||
|
}
|
||||||
|
// Bundle bnd = (Bundle) load(npm, "Bundle-searchParams.json");
|
||||||
|
// if (bnd != null) {
|
||||||
|
// for (BundleEntryComponent be : bnd.getEntry()) {
|
||||||
|
// Resource r = be.getResource();
|
||||||
|
// if (r instanceof CodeSystem) {
|
||||||
|
// res.getCodeSystems().see((CodeSystem) r, null);
|
||||||
|
// } else if (r instanceof ValueSet) {
|
||||||
|
// res.getValuesets().see((ValueSet) r, null);
|
||||||
|
// } else if (r instanceof ConceptMap) {
|
||||||
|
// res.getConceptMaps().see((ConceptMap) r, null);
|
||||||
|
// } else if (r instanceof CapabilityStatement) {
|
||||||
|
// res.getStatements().see((CapabilityStatement) r, null);
|
||||||
|
// } else if (r instanceof StructureDefinition) {
|
||||||
|
// res.getStructures().see((StructureDefinition) r, null);
|
||||||
|
// } else if (r instanceof OperationDefinition) {
|
||||||
|
// res.getOperations().see((OperationDefinition) r, null);
|
||||||
|
// } else if (r instanceof SearchParameter) {
|
||||||
|
// res.getSearchParams().see((SearchParameter) r, null);
|
||||||
|
// } else if (r instanceof CompartmentDefinition) {
|
||||||
|
// res.getCompartments().see((CompartmentDefinition) r, null);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Resource load(NpmPackage npm, String t) {
|
||||||
|
try {
|
||||||
|
return VersionConvertorFactory_40_50.convertResource(new JsonParser().parse(npm.loadResource(t)));
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.out.println("Error reading "+t+": "+e.getMessage());
|
||||||
|
e.printStackTrace();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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:\r\n \""+left.current().getMustSupport()+"\"\r\n \""+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,11 +212,16 @@ 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()));
|
||||||
|
@ -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) {
|
||||||
|
@ -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)
|
||||||
|
@ -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:\r\n \""+leftMin+"\"\r\n vs \""+rightMin+"\"", path, comp.getMessages(), res.getMessages());
|
||||||
|
} else if (rightMin == 0) {
|
||||||
|
vm(IssueSeverity.INFORMATION, "Element minimum cardinalities differ:\r\n \""+leftMin+"\"\r\n vs \""+rightMin+"\"", path, comp.getMessages(), res.getMessages());
|
||||||
|
} else {
|
||||||
|
vm(IssueSeverity.INFORMATION, "Element minimum cardinalities differ:\r\n \""+leftMin+"\"\r\n vs \""+rightMin+"\"", path, comp.getMessages(), res.getMessages());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (leftMax != rightMax) {
|
||||||
|
if (leftMax == Integer.MAX_VALUE) {
|
||||||
|
vm(IssueSeverity.INFORMATION, "Element maximum cardinalities differ:\r\n \""+leftMax+"\"\r\n vs \""+rightMax+"\"", path, comp.getMessages(), res.getMessages());
|
||||||
|
} else if (rightMax == Integer.MAX_VALUE) {
|
||||||
|
vm(IssueSeverity.INFORMATION, "Element maximum cardinalities differ:\r\n \""+leftMax+"\"\r\n vs \""+rightMax+"\"", path, comp.getMessages(), res.getMessages());
|
||||||
|
} else {
|
||||||
|
vm(IssueSeverity.INFORMATION, "Element maximum cardinalities differ:\r\n \""+leftMax+"\"\r\n 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:\r\n \""+leftMin+".."+leftMax+"\"\r\n 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:\r\n \""+leftMin+".."+leftMax+"\"\r\n 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), 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), 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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -301,11 +301,11 @@ public class ResourceComparer {
|
||||||
private String halfColorForLevel(IssueSeverity level) {
|
private String halfColorForLevel(IssueSeverity level) {
|
||||||
switch (level) {
|
switch (level) {
|
||||||
case ERROR:
|
case ERROR:
|
||||||
return "#ffeeee";
|
return "#ffdddd";
|
||||||
case FATAL:
|
case FATAL:
|
||||||
return "#ffcccc";
|
return "#ffcccc";
|
||||||
case WARNING:
|
case WARNING:
|
||||||
return "#fff4ee";
|
return "#fff6ee";
|
||||||
default: // INFORMATION:
|
default: // INFORMATION:
|
||||||
return "#fffff2";
|
return "#fffff2";
|
||||||
}
|
}
|
||||||
|
@ -319,6 +319,9 @@ public class ResourceComparer {
|
||||||
XhtmlNode li = new XhtmlNode(NodeType.Element, "li");
|
XhtmlNode li = new XhtmlNode(NodeType.Element, "li");
|
||||||
piece.getChildren().add(li);
|
piece.getChildren().add(li);
|
||||||
li.style("background-color: "+halfColorForLevel(msg.getLevel()));
|
li.style("background-color: "+halfColorForLevel(msg.getLevel()));
|
||||||
|
if (msg.getLevel() == IssueSeverity.ERROR) {
|
||||||
|
li.style("font-weight: bold");
|
||||||
|
}
|
||||||
li.tx(msg.getMessage());
|
li.tx(msg.getMessage());
|
||||||
}
|
}
|
||||||
return cell;
|
return cell;
|
||||||
|
|
|
@ -4,6 +4,7 @@ import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.hl7.fhir.r5.comparison.ResourceComparer.MessageCounts;
|
import org.hl7.fhir.r5.comparison.ResourceComparer.MessageCounts;
|
||||||
|
import org.hl7.fhir.r5.model.StructureDefinition;
|
||||||
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;
|
||||||
|
|
||||||
|
@ -114,4 +115,5 @@ public class StructuralMatch<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -36,6 +36,9 @@ import java.io.FileReader;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
|
import java.text.DateFormat;
|
||||||
|
import java.text.ParseException;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
|
@ -3504,7 +3507,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));
|
||||||
|
@ -3586,7 +3589,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:")) {
|
||||||
|
@ -3685,7 +3688,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;
|
||||||
|
@ -4566,7 +4569,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));
|
||||||
}
|
}
|
||||||
|
@ -4661,7 +4664,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()) {
|
||||||
|
@ -4670,7 +4673,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)));
|
||||||
|
@ -4764,6 +4767,13 @@ public class ProfileUtilities extends TranslatingUtilities {
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
|
@ -614,6 +614,9 @@ public class ExpressionNode {
|
||||||
|
|
||||||
public String check() {
|
public String check() {
|
||||||
|
|
||||||
|
if (kind == null) {
|
||||||
|
return "Error in expression - node has no kind";
|
||||||
|
}
|
||||||
switch (kind) {
|
switch (kind) {
|
||||||
case Name:
|
case Name:
|
||||||
if (Utilities.noString(name))
|
if (Utilities.noString(name))
|
||||||
|
|
|
@ -511,7 +511,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;
|
||||||
|
|
Loading…
Reference in New Issue