Search in sources :

Example 66 with ProfileComparison

use of org.hl7.fhir.r5.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);
}
Also used : StructureDefinition(org.hl7.fhir.dstu2016may.model.StructureDefinition) TypeRefComponent(org.hl7.fhir.dstu2016may.model.ElementDefinition.TypeRefComponent) DefinitionException(org.hl7.fhir.exceptions.DefinitionException)

Example 67 with ProfileComparison

use of org.hl7.fhir.r5.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;
}
Also used : ValidationMessage(org.hl7.fhir.utilities.validation.ValidationMessage) ArrayList(java.util.ArrayList) ElementDefinitionConstraintComponent(org.hl7.fhir.dstu2016may.model.ElementDefinition.ElementDefinitionConstraintComponent)

Example 68 with ProfileComparison

use of org.hl7.fhir.r5.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;
}
Also used : ConceptSetComponent(org.hl7.fhir.dstu2016may.model.ValueSet.ConceptSetComponent) ValidationMessage(org.hl7.fhir.utilities.validation.ValidationMessage) ValueSet(org.hl7.fhir.dstu2016may.model.ValueSet) UriType(org.hl7.fhir.dstu2016may.model.UriType)

Example 69 with ProfileComparison

use of org.hl7.fhir.r5.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;
}
Also used : StructureDefinition(org.hl7.fhir.dstu2016may.model.StructureDefinition) DefinitionException(org.hl7.fhir.exceptions.DefinitionException)

Example 70 with ProfileComparison

use of org.hl7.fhir.r5.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;
    }
}
Also used : ProfileComparison(org.hl7.fhir.r5.comparison.ProfileComparer.ProfileComparison) ValueSetComparison(org.hl7.fhir.r5.comparison.ValueSetComparer.ValueSetComparison) CodeSystem(org.hl7.fhir.r5.model.CodeSystem) FHIRException(org.hl7.fhir.exceptions.FHIRException) StructureDefinition(org.hl7.fhir.r5.model.StructureDefinition) CodeSystemComparison(org.hl7.fhir.r5.comparison.CodeSystemComparer.CodeSystemComparison) ProfileUtilities(org.hl7.fhir.r5.conformance.ProfileUtilities) ValueSet(org.hl7.fhir.r5.model.ValueSet)

Aggregations

ValidationMessage (org.hl7.fhir.utilities.validation.ValidationMessage)26 DefinitionException (org.hl7.fhir.exceptions.DefinitionException)24 ArrayList (java.util.ArrayList)14 FileOutputStream (java.io.FileOutputStream)5 StructureDefinition (org.hl7.fhir.r5.model.StructureDefinition)5 IOException (java.io.IOException)4 StructureDefinition (org.hl7.fhir.dstu2.model.StructureDefinition)4 StructureDefinition (org.hl7.fhir.dstu2016may.model.StructureDefinition)4 StructureDefinition (org.hl7.fhir.dstu3.model.StructureDefinition)4 StructureDefinition (org.hl7.fhir.r4.model.StructureDefinition)4 ValueSet (org.hl7.fhir.dstu2.model.ValueSet)3 ValueSet (org.hl7.fhir.dstu3.model.ValueSet)3 FHIRException (org.hl7.fhir.exceptions.FHIRException)3 ValueSet (org.hl7.fhir.r4.model.ValueSet)3 StructureDefinition (org.hl7.fhir.r4b.model.StructureDefinition)3 ValueSetComparison (org.hl7.fhir.r5.comparison.ValueSetComparer.ValueSetComparison)3 ValueSet (org.hl7.fhir.r5.model.ValueSet)3 Date (java.util.Date)2 HashMap (java.util.HashMap)2 ElementDefinitionBindingComponent (org.hl7.fhir.dstu2.model.ElementDefinition.ElementDefinitionBindingComponent)2