use of org.hl7.fhir.r4b.comparison.ProfileComparer.ProfileComparison in project org.hl7.fhir.core by hapifhir.
the class ProfileComparer method checkAddTypeUnion.
private void checkAddTypeUnion(String path, List<TypeRefComponent> results, TypeRefComponent nw) throws DefinitionException, IOException {
boolean found = false;
nw = nw.copy();
if (nw.getProfile().size() > 1)
throw new DefinitionException("Multiple profiles not supported: " + path);
if (nw.hasAggregation())
throw new DefinitionException("Aggregation not supported: " + path);
for (TypeRefComponent ex : results) {
if (Utilities.equals(ex.getCode(), nw.getCode())) {
if (!ex.hasProfile() && !nw.hasProfile())
found = true;
else if (!ex.hasProfile()) {
found = true;
} else if (!nw.hasProfile()) {
found = true;
ex.getProfile().clear();
} else {
// both have profiles. Is one derived from the other?
StructureDefinition sdex = context.fetchResource(StructureDefinition.class, ex.getProfile().get(0).getValueAsString());
StructureDefinition sdnw = context.fetchResource(StructureDefinition.class, nw.getProfile().get(0).getValueAsString());
if (sdex != null && sdnw != null) {
if (sdex == sdnw) {
found = true;
} else if (derivesFrom(sdex, sdnw)) {
ex.getProfile().clear();
ex.getProfile().add(nw.getProfile().get(0));
found = true;
} else if (derivesFrom(sdnw, sdex)) {
found = true;
} else if (sdnw.getSnapshot().getElement().get(0).getPath().equals(sdex.getSnapshot().getElement().get(0).getPath())) {
ProfileComparison comp = compareProfiles(sdex, sdnw);
if (comp.getSuperset() != null) {
found = true;
ex.getProfile().clear();
ex.addProfile("#" + comp.id);
}
}
}
}
}
}
if (!found)
results.add(nw);
}
use of org.hl7.fhir.r4b.comparison.ProfileComparer.ProfileComparison in project org.hl7.fhir.core by hapifhir.
the class ProfileComparer method unionConstraints.
// we can't really know about constraints. We create warnings, and collate them
private List<ElementDefinitionConstraintComponent> unionConstraints(ElementDefinition ed, ProfileComparison outcome, String path, List<ElementDefinitionConstraintComponent> left, List<ElementDefinitionConstraintComponent> right) {
List<ElementDefinitionConstraintComponent> result = new ArrayList<ElementDefinitionConstraintComponent>();
for (ElementDefinitionConstraintComponent l : left) {
boolean found = false;
for (ElementDefinitionConstraintComponent r : right) if (Utilities.equals(r.getId(), l.getId()) || (Utilities.equals(r.getXpath(), l.getXpath()) && r.getSeverity() == l.getSeverity()))
found = true;
if (!found) {
outcome.messages.add(new ValidationMessage(Source.ProfileComparer, IssueType.STRUCTURE, path, "StructureDefinition " + outcome.leftName() + " has a constraint that is not found in " + outcome.rightName() + " and it is uncertain whether they are compatible (" + l.getXpath() + ")", IssueSeverity.WARNING));
status(ed, ProfileUtilities.STATUS_WARNING);
}
result.add(l);
}
for (ElementDefinitionConstraintComponent r : right) {
boolean found = false;
for (ElementDefinitionConstraintComponent l : left) if (Utilities.equals(r.getId(), l.getId()) || (Utilities.equals(r.getXpath(), l.getXpath()) && r.getSeverity() == l.getSeverity()))
found = true;
if (!found) {
outcome.messages.add(new ValidationMessage(Source.ProfileComparer, IssueType.STRUCTURE, path, "StructureDefinition " + outcome.rightName() + " has a constraint that is not found in " + outcome.leftName() + " and it is uncertain whether they are compatible (" + r.getXpath() + ")", IssueSeverity.WARNING));
status(ed, ProfileUtilities.STATUS_WARNING);
result.add(r);
}
}
return result;
}
use of org.hl7.fhir.r4b.comparison.ProfileComparer.ProfileComparison in project org.hl7.fhir.core by hapifhir.
the class ProfileComparer method unite.
private ValueSet unite(ElementDefinition ed, ProfileComparison outcome, String path, ValueSet lvs, ValueSet rvs) {
ValueSet vs = new ValueSet();
if (lvs.hasCompose()) {
for (UriType imp : lvs.getCompose().getImport()) vs.getCompose().getImport().add(imp);
for (ConceptSetComponent inc : lvs.getCompose().getInclude()) vs.getCompose().getInclude().add(inc);
if (lvs.getCompose().hasExclude()) {
outcome.messages.add(new ValidationMessage(Source.ProfileComparer, IssueType.STRUCTURE, path, "The value sets " + lvs.getUrl() + " has exclude statements, and no union involving it can be correctly determined", IssueSeverity.ERROR));
status(ed, ProfileUtilities.STATUS_ERROR);
}
}
if (rvs.hasCompose()) {
for (UriType imp : rvs.getCompose().getImport()) if (!vs.getCompose().hasImport(imp.getValue()))
vs.getCompose().getImport().add(imp);
for (ConceptSetComponent inc : rvs.getCompose().getInclude()) if (!mergeIntoExisting(vs.getCompose().getInclude(), inc))
vs.getCompose().getInclude().add(inc);
if (rvs.getCompose().hasExclude()) {
outcome.messages.add(new ValidationMessage(Source.ProfileComparer, IssueType.STRUCTURE, path, "The value sets " + lvs.getUrl() + " has exclude statements, and no union involving it can be correctly determined", IssueSeverity.ERROR));
status(ed, ProfileUtilities.STATUS_ERROR);
}
}
return vs;
}
use of org.hl7.fhir.r4b.comparison.ProfileComparer.ProfileComparison in project org.hl7.fhir.core by hapifhir.
the class ProfileComparer method compareProfiles.
/**
* Compare left and right structure definitions to see whether they are consistent or not
*
* Note that left and right are arbitrary choices. In one respect, left
* is 'preferred' - the left's example value and data sets will be selected
* over the right ones in the common structure definition
* @throws DefinitionException
* @throws IOException
*
* @
*/
public ProfileComparison compareProfiles(StructureDefinition left, StructureDefinition right) throws DefinitionException, IOException {
ProfileComparison outcome = new ProfileComparison();
outcome.left = left;
outcome.right = right;
if (left == null)
throw new DefinitionException("No StructureDefinition provided (left)");
if (right == null)
throw new DefinitionException("No StructureDefinition provided (right)");
if (!left.hasSnapshot())
throw new DefinitionException("StructureDefinition has no snapshot (left: " + outcome.leftName() + ")");
if (!right.hasSnapshot())
throw new DefinitionException("StructureDefinition has no snapshot (right: " + outcome.rightName() + ")");
if (left.getSnapshot().getElement().isEmpty())
throw new DefinitionException("StructureDefinition snapshot is empty (left: " + outcome.leftName() + ")");
if (right.getSnapshot().getElement().isEmpty())
throw new DefinitionException("StructureDefinition snapshot is empty (right: " + outcome.rightName() + ")");
for (ProfileComparison pc : comparisons) if (pc.left.getUrl().equals(left.getUrl()) && pc.right.getUrl().equals(right.getUrl()))
return pc;
outcome.id = Integer.toString(comparisons.size() + 1);
comparisons.add(outcome);
DefinitionNavigator ln = new DefinitionNavigator(context, left);
DefinitionNavigator rn = new DefinitionNavigator(context, right);
// from here on in, any issues go in messages
outcome.superset = new StructureDefinition();
outcome.subset = new StructureDefinition();
if (outcome.ruleEqual(ln.path(), null, ln.path(), rn.path(), "Base Type is not compatible", false)) {
if (compareElements(outcome, ln.path(), ln, rn)) {
outcome.subset.setName("intersection of " + outcome.leftName() + " and " + outcome.rightName());
outcome.subset.setStatus(ConformanceResourceStatus.DRAFT);
outcome.subset.setKind(outcome.left.getKind());
outcome.subset.setBaseType(outcome.left.getBaseType());
outcome.subset.setBaseDefinition("http://hl7.org/fhir/StructureDefinition/" + outcome.subset.getBaseType());
outcome.subset.setDerivation(TypeDerivationRule.CONSTRAINT);
outcome.subset.setAbstract(false);
outcome.superset.setName("union of " + outcome.leftName() + " and " + outcome.rightName());
outcome.superset.setStatus(ConformanceResourceStatus.DRAFT);
outcome.superset.setKind(outcome.left.getKind());
outcome.superset.setBaseType(outcome.left.getBaseType());
outcome.superset.setBaseDefinition("http://hl7.org/fhir/StructureDefinition/" + outcome.subset.getBaseType());
outcome.superset.setAbstract(false);
outcome.superset.setDerivation(TypeDerivationRule.CONSTRAINT);
} else {
outcome.subset = null;
outcome.superset = null;
}
}
return outcome;
}
use of org.hl7.fhir.r4b.comparison.ProfileComparer.ProfileComparison in project org.hl7.fhir.core by hapifhir.
the class ComparisonSession method compare.
public ResourceComparison compare(CanonicalResource left, CanonicalResource right) throws DefinitionException, FHIRFormatError, IOException {
if (left != null && right != null) {
String key = key(left.getUrl(), left.getVersion(), right.getUrl(), right.getVersion());
if (compares.containsKey(key)) {
// this can happen when profiles refer to each other
return compares.get(key);
}
compares.put(key, null);
try {
if (left instanceof CodeSystem && right instanceof CodeSystem) {
CodeSystemComparer cs = new CodeSystemComparer(this);
CodeSystemComparison csc = cs.compare((CodeSystem) left, (CodeSystem) right);
compares.put(key, csc);
return csc;
} else if (left instanceof ValueSet && right instanceof ValueSet) {
ValueSetComparer cs = new ValueSetComparer(this);
ValueSetComparison csc = cs.compare((ValueSet) left, (ValueSet) right);
compares.put(key, csc);
return csc;
} else if (left instanceof StructureDefinition && right instanceof StructureDefinition) {
ProfileComparer cs = new ProfileComparer(this, new ProfileUtilities(contextLeft, null, pkp), new ProfileUtilities(contextRight, null, pkp));
ProfileComparison csc = cs.compare((StructureDefinition) left, (StructureDefinition) right);
compares.put(key, csc);
return csc;
} else {
throw new FHIRException("Unable to compare resources of type " + left.fhirType() + " and " + right.fhirType());
}
} catch (Throwable e) {
ResourceComparer.PlaceHolderComparison csc = new ResourceComparer.PlaceHolderComparison(left, right, e);
compares.put(key, csc);
return csc;
}
} else if (left != null) {
String key = key(left.getUrl(), left.getVersion(), left.getUrl(), left.getVersion());
if (compares.containsKey(key)) {
return compares.get(key);
}
ResourceComparer.PlaceHolderComparison csc = new ResourceComparer.PlaceHolderComparison(left, right);
compares.put(key, csc);
return csc;
} else {
String key = key(right.getUrl(), right.getVersion(), right.getUrl(), right.getVersion());
if (compares.containsKey(key)) {
return compares.get(key);
}
ResourceComparer.PlaceHolderComparison csc = new ResourceComparer.PlaceHolderComparison(left, right);
compares.put(key, csc);
return csc;
}
}
Aggregations