Search in sources :

Example 6 with ElementDefinitionConstraintComponent

use of org.hl7.fhir.r4b.model.ElementDefinition.ElementDefinitionConstraintComponent in project kindling by HL7.

the class ProfileGenerator method addElementConstraint.

/*
   *     // resource
    // domain resource
    for (ElementDefn child : definitions.getBaseResources().get("DomainResource").getRoot().getElements()) 
      defineElement(null, p, p.getSnapshot(), child, r.getRoot().getName()+"."+child.getName(), containedSlices, new ArrayList<ProfileGenerator.SliceHandle>(), SnapShotMode.Resource);

   */
/*
  private String registerMapping(ConformancePackage ap, StructureDefinition p, String m) {
    for (StructureDefinitionMappingComponent map : p.getMapping()) {
      if (map.getUri().equals(m))
        return map.getIdentity();
    }
    StructureDefinitionMappingComponent map = new StructureDefinitionMappingComponent();
    MappingSpace space = definitions.getMapTypes().get(m);
    if (space != null)
      map.setIdentity(space.getId());
    else
      map.setIdentity("m" + Integer.toString(p.getMapping().size()+1));
    map.setUri(m);
    String name = ap.metadata(m+"-name");
    if (Utilities.noString(name) && space != null)
      name = space.getTitle();
    if (!Utilities.noString(name))
      map.setName(name);
    String comments = ap.metadata(m+"-comments");
    if (Utilities.noString(comments) && space != null)
        comments = space.getPreamble();
    if (!Utilities.noString(comments))
      map.setComments(comments);
    return map.getIdentity();
  }
   */
private ElementDefinition addElementConstraint(StructureDefinition sd, ElementDefinition ed) {
    if (!ed.getPath().contains(".") && sd.getKind() == StructureDefinitionKind.RESOURCE)
        return ed;
    if (hasSystemType(ed))
        return ed;
    if (isResource(ed))
        return ed;
    if (hasConstraint(ed, "ele-1"))
        return ed;
    ElementDefinitionConstraintComponent inv = ed.addConstraint();
    inv.setKey("ele-1");
    inv.setSeverity(ConstraintSeverity.ERROR);
    inv.setHuman("All FHIR elements must have a @value or children");
    inv.setExpression("hasValue() or (children().count() > id.count())");
    inv.setXpath("@value|f:*|h:div");
    inv.setSource("http://hl7.org/fhir/StructureDefinition/Element");
    return ed;
}
Also used : ElementDefinitionConstraintComponent(org.hl7.fhir.r5.model.ElementDefinition.ElementDefinitionConstraintComponent)

Example 7 with ElementDefinitionConstraintComponent

use of org.hl7.fhir.r4b.model.ElementDefinition.ElementDefinitionConstraintComponent in project kindling by HL7.

the class DictHTMLGenerator method invariants.

// 
// 
// for (String id : ids) {
// ElementDefinitionConstraintComponent inv = getConstraint(constraints, id);
// s.append("<tr><td><b title=\"Formal Invariant Identifier\">"+inv.getId()+"</b></td><td>"+presentLevel(inv)+"</td><td>(base)</td><td>"+Utilities.escapeXml(inv.getHuman())+"</td><td><span style=\"font-family: Courier New, monospace\">"+Utilities.escapeXml(inv.getExpression())+"</span>");
// if (inv.hasExtension("http://hl7.org/fhir/StructureDefinition/elementdefinition-bestpractice"))
// s.append("<br/>This is (only) a best practice guideline because: <blockquote>"+page.processMarkdown("best practice guideline", inv.getExtensionString("http://hl7.org/fhir/StructureDefinition/elementdefinition-bestpractice-explanation"), prefix)+"</blockquote>");
// s.append("</td></tr>");
// }
// }
private String invariants(Map<String, Invariant> invariants, List<Invariant> stated) throws Exception {
    List<String> done = new ArrayList<String>();
    StringBuilder s = new StringBuilder();
    if (invariants.size() + stated.size() > 0) {
        s.append("<table class=\"dict\">\r\n");
        if (invariants.size() > 0) {
            s.append("<tr><td colspan=\"4\"><b>Defined on this element</b></td></tr>\r\n");
            List<String> ids = new ArrayList<String>();
            for (String id : invariants.keySet()) ids.add(id);
            Collections.sort(ids, new ConstraintsSorter());
            for (String i : ids) {
                Invariant inv = invariants.get(i);
                done.add(inv.getId());
                s.append("<tr><td width=\"60px\"><b title=\"Formal Invariant Identifier\">" + inv.getId() + "</b></td><td>" + presentLevel(inv) + "</td><td>" + Utilities.escapeXml(inv.getEnglish()) + "</td><td><span style=\"font-family: Courier New, monospace\">" + Utilities.escapeXml(inv.getExpression()) + "</span>");
                if (!Utilities.noString(inv.getExplanation()))
                    s.append("<br/>This is (only) a best practice guideline because: <blockquote>" + page.processMarkdown("best practice guideline", inv.getExplanation(), prefix) + "</blockquote>");
                s.append("</td></tr>");
            }
        }
        if (stated.size() > 0) {
            s.append("<tr><td colspan=\"4\"><b>Affect this element</b></td></tr>\r\n");
            boolean b = false;
            for (Invariant id : stated) {
                if (!done.contains(id.getId())) {
                    s.append("<tr><td width=\"60px\"><b title=\"Formal Invariant Identifier\">" + id.getId() + "</b></td><td>" + presentLevel(id) + "</td><td>" + Utilities.escapeXml(id.getEnglish()) + "</td><td><span style=\"font-family: Courier New, monospace\">" + Utilities.escapeXml(id.getExpression()) + "</span>");
                    if (!Utilities.noString(id.getExplanation()))
                        s.append("<br/>This is (only) a best practice guideline because: <blockquote>" + page.processMarkdown("best practice guideline", id.getExplanation(), prefix) + "</blockquote>");
                    s.append("</td></tr>");
                }
            }
        }
        s.append("</table>\r\n");
    }
    return s.toString();
}
Also used : Invariant(org.hl7.fhir.definitions.model.Invariant) CommaSeparatedStringBuilder(org.hl7.fhir.utilities.CommaSeparatedStringBuilder) ArrayList(java.util.ArrayList)

Example 8 with ElementDefinitionConstraintComponent

use of org.hl7.fhir.r4b.model.ElementDefinition.ElementDefinitionConstraintComponent in project org.hl7.fhir.core by hapifhir.

the class ProfileUtilities method updateFromDefinition.

private void updateFromDefinition(ElementDefinition dest, ElementDefinition source, String pn, boolean trimDifferential, String purl) throws DefinitionException, FHIRException {
    source.setUserData(GENERATED_IN_SNAPSHOT, true);
    // we start with a clone of the base profile ('dest') and we copy from the profile ('source')
    // over the top for anything the source has
    ElementDefinition base = dest;
    ElementDefinition derived = source;
    derived.setUserData(DERIVATION_POINTER, base);
    // Before applying changes, apply them to what's in the profile
    // TODO: follow Chris's rules
    StructureDefinition profile = source.getType().size() == 1 && source.getTypeFirstRep().hasProfile() ? context.fetchResource(StructureDefinition.class, source.getTypeFirstRep().getProfile()) : null;
    if (profile != null) {
        ElementDefinition e = profile.getSnapshot().getElement().get(0);
        base.setDefinition(e.getDefinition());
        base.setShort(e.getShort());
        if (e.hasCommentElement())
            base.setCommentElement(e.getCommentElement());
        if (e.hasRequirementsElement())
            base.setRequirementsElement(e.getRequirementsElement());
        base.getAlias().clear();
        base.getAlias().addAll(e.getAlias());
        base.getMapping().clear();
        base.getMapping().addAll(e.getMapping());
    }
    if (derived != null) {
        boolean isExtension = checkExtensionDoco(base);
        if (derived.hasSliceName()) {
            base.setSliceName(derived.getSliceName());
        }
        if (derived.hasShortElement()) {
            if (!Base.compareDeep(derived.getShortElement(), base.getShortElement(), false))
                base.setShortElement(derived.getShortElement().copy());
            else if (trimDifferential)
                derived.setShortElement(null);
            else if (derived.hasShortElement())
                derived.getShortElement().setUserData(DERIVATION_EQUALS, true);
        }
        if (derived.hasDefinitionElement()) {
            if (derived.getDefinition().startsWith("..."))
                base.setDefinition(base.getDefinition() + "\r\n" + derived.getDefinition().substring(3));
            else if (!Base.compareDeep(derived.getDefinitionElement(), base.getDefinitionElement(), false))
                base.setDefinitionElement(derived.getDefinitionElement().copy());
            else if (trimDifferential)
                derived.setDefinitionElement(null);
            else if (derived.hasDefinitionElement())
                derived.getDefinitionElement().setUserData(DERIVATION_EQUALS, true);
        }
        if (derived.hasCommentElement()) {
            if (derived.getComment().startsWith("..."))
                base.setComment(base.getComment() + "\r\n" + derived.getComment().substring(3));
            else if (derived.hasCommentElement() != base.hasCommentElement() || !Base.compareDeep(derived.getCommentElement(), base.getCommentElement(), false))
                base.setCommentElement(derived.getCommentElement().copy());
            else if (trimDifferential)
                base.setCommentElement(derived.getCommentElement().copy());
            else if (derived.hasCommentElement())
                derived.getCommentElement().setUserData(DERIVATION_EQUALS, true);
        }
        if (derived.hasLabelElement()) {
            if (derived.getLabel().startsWith("..."))
                base.setLabel(base.getLabel() + "\r\n" + derived.getLabel().substring(3));
            else if (!base.hasLabelElement() || !Base.compareDeep(derived.getLabelElement(), base.getLabelElement(), false))
                base.setLabelElement(derived.getLabelElement().copy());
            else if (trimDifferential)
                base.setLabelElement(derived.getLabelElement().copy());
            else if (derived.hasLabelElement())
                derived.getLabelElement().setUserData(DERIVATION_EQUALS, true);
        }
        if (derived.hasRequirementsElement()) {
            if (derived.getRequirements().startsWith("..."))
                base.setRequirements(base.getRequirements() + "\r\n" + derived.getRequirements().substring(3));
            else if (!base.hasRequirementsElement() || !Base.compareDeep(derived.getRequirementsElement(), base.getRequirementsElement(), false))
                base.setRequirementsElement(derived.getRequirementsElement().copy());
            else if (trimDifferential)
                base.setRequirementsElement(derived.getRequirementsElement().copy());
            else if (derived.hasRequirementsElement())
                derived.getRequirementsElement().setUserData(DERIVATION_EQUALS, true);
        }
        // sdf-9
        if (derived.hasRequirements() && !base.getPath().contains("."))
            derived.setRequirements(null);
        if (base.hasRequirements() && !base.getPath().contains("."))
            base.setRequirements(null);
        if (derived.hasAlias()) {
            if (!Base.compareDeep(derived.getAlias(), base.getAlias(), false))
                for (StringType s : derived.getAlias()) {
                    if (!base.hasAlias(s.getValue()))
                        base.getAlias().add(s.copy());
                }
            else if (trimDifferential)
                derived.getAlias().clear();
            else
                for (StringType t : derived.getAlias()) t.setUserData(DERIVATION_EQUALS, true);
        }
        if (derived.hasMinElement()) {
            if (!Base.compareDeep(derived.getMinElement(), base.getMinElement(), false)) {
                if (derived.getMin() < base.getMin())
                    messages.add(new ValidationMessage(Source.ProfileValidator, ValidationMessage.IssueType.BUSINESSRULE, pn + "." + source.getPath(), "Derived min  (" + Integer.toString(derived.getMin()) + ") cannot be less than base min (" + Integer.toString(base.getMin()) + ")", ValidationMessage.IssueSeverity.ERROR));
                base.setMinElement(derived.getMinElement().copy());
            } else if (trimDifferential)
                derived.setMinElement(null);
            else
                derived.getMinElement().setUserData(DERIVATION_EQUALS, true);
        }
        if (derived.hasMaxElement()) {
            if (!Base.compareDeep(derived.getMaxElement(), base.getMaxElement(), false)) {
                if (isLargerMax(derived.getMax(), base.getMax()))
                    messages.add(new ValidationMessage(Source.ProfileValidator, ValidationMessage.IssueType.BUSINESSRULE, pn + "." + source.getPath(), "Derived max (" + derived.getMax() + ") cannot be greater than base max (" + base.getMax() + ")", ValidationMessage.IssueSeverity.ERROR));
                base.setMaxElement(derived.getMaxElement().copy());
            } else if (trimDifferential)
                derived.setMaxElement(null);
            else
                derived.getMaxElement().setUserData(DERIVATION_EQUALS, true);
        }
        if (derived.hasFixed()) {
            if (!Base.compareDeep(derived.getFixed(), base.getFixed(), true)) {
                base.setFixed(derived.getFixed().copy());
            } else if (trimDifferential)
                derived.setFixed(null);
            else
                derived.getFixed().setUserData(DERIVATION_EQUALS, true);
        }
        if (derived.hasPattern()) {
            if (!Base.compareDeep(derived.getPattern(), base.getPattern(), false)) {
                base.setPattern(derived.getPattern().copy());
            } else if (trimDifferential)
                derived.setPattern(null);
            else
                derived.getPattern().setUserData(DERIVATION_EQUALS, true);
        }
        for (ElementDefinitionExampleComponent ex : derived.getExample()) {
            boolean found = false;
            for (ElementDefinitionExampleComponent exS : base.getExample()) if (Base.compareDeep(ex, exS, false))
                found = true;
            if (!found)
                base.addExample(ex.copy());
            else if (trimDifferential)
                derived.getExample().remove(ex);
            else
                ex.setUserData(DERIVATION_EQUALS, true);
        }
        if (derived.hasMaxLengthElement()) {
            if (!Base.compareDeep(derived.getMaxLengthElement(), base.getMaxLengthElement(), false))
                base.setMaxLengthElement(derived.getMaxLengthElement().copy());
            else if (trimDifferential)
                derived.setMaxLengthElement(null);
            else
                derived.getMaxLengthElement().setUserData(DERIVATION_EQUALS, true);
        }
        if (derived.hasMaxValue()) {
            if (!Base.compareDeep(derived.getMaxValue(), base.getMaxValue(), false))
                base.setMaxValue(derived.getMaxValue().copy());
            else if (trimDifferential)
                derived.setMaxValue(null);
            else
                derived.getMaxValue().setUserData(DERIVATION_EQUALS, true);
        }
        if (derived.hasMinValue()) {
            if (!Base.compareDeep(derived.getMinValue(), base.getMinValue(), false))
                base.setMinValue(derived.getMinValue().copy());
            else if (trimDifferential)
                derived.setMinValue(null);
            else
                derived.getMinValue().setUserData(DERIVATION_EQUALS, true);
        }
        if (derived.hasMustSupportElement()) {
            if (!(base.hasMustSupportElement() && Base.compareDeep(derived.getMustSupportElement(), base.getMustSupportElement(), false)))
                base.setMustSupportElement(derived.getMustSupportElement().copy());
            else if (trimDifferential)
                derived.setMustSupportElement(null);
            else
                derived.getMustSupportElement().setUserData(DERIVATION_EQUALS, true);
        }
        // but extensions can change isModifier
        if (isExtension) {
            if (derived.hasIsModifierElement() && !(base.hasIsModifierElement() && Base.compareDeep(derived.getIsModifierElement(), base.getIsModifierElement(), false)))
                base.setIsModifierElement(derived.getIsModifierElement().copy());
            else if (trimDifferential)
                derived.setIsModifierElement(null);
            else if (derived.hasIsModifierElement())
                derived.getIsModifierElement().setUserData(DERIVATION_EQUALS, true);
        }
        if (derived.hasBinding()) {
            if (!base.hasBinding() || !Base.compareDeep(derived.getBinding(), base.getBinding(), false)) {
                if (base.hasBinding() && base.getBinding().getStrength() == BindingStrength.REQUIRED && derived.getBinding().getStrength() != BindingStrength.REQUIRED)
                    messages.add(new ValidationMessage(Source.ProfileValidator, ValidationMessage.IssueType.BUSINESSRULE, pn + "." + derived.getPath(), "illegal attempt to change the binding on " + derived.getPath() + " from " + base.getBinding().getStrength().toCode() + " to " + derived.getBinding().getStrength().toCode(), ValidationMessage.IssueSeverity.ERROR));
                else // throw new DefinitionException("StructureDefinition "+pn+" at "+derived.getPath()+": illegal attempt to change a binding from "+base.getBinding().getStrength().toCode()+" to "+derived.getBinding().getStrength().toCode());
                if (base.hasBinding() && derived.hasBinding() && base.getBinding().getStrength() == BindingStrength.REQUIRED && base.getBinding().hasValueSetReference() && derived.getBinding().hasValueSetReference()) {
                    ValueSetExpansionOutcome expBase = context.expandVS(context.fetchResource(ValueSet.class, base.getBinding().getValueSetReference().getReference()), true, false);
                    ValueSetExpansionOutcome expDerived = context.expandVS(context.fetchResource(ValueSet.class, derived.getBinding().getValueSetReference().getReference()), true, false);
                    if (expBase.getValueset() == null)
                        messages.add(new ValidationMessage(Source.ProfileValidator, ValidationMessage.IssueType.BUSINESSRULE, pn + "." + base.getPath(), "Binding " + base.getBinding().getValueSetReference().getReference() + " could not be expanded", ValidationMessage.IssueSeverity.WARNING));
                    else if (expDerived.getValueset() == null)
                        messages.add(new ValidationMessage(Source.ProfileValidator, ValidationMessage.IssueType.BUSINESSRULE, pn + "." + derived.getPath(), "Binding " + derived.getBinding().getValueSetReference().getReference() + " could not be expanded", ValidationMessage.IssueSeverity.WARNING));
                    else if (!isSubset(expBase.getValueset(), expDerived.getValueset()))
                        messages.add(new ValidationMessage(Source.ProfileValidator, ValidationMessage.IssueType.BUSINESSRULE, pn + "." + derived.getPath(), "Binding " + derived.getBinding().getValueSetReference().getReference() + " is not a subset of binding " + base.getBinding().getValueSetReference().getReference(), ValidationMessage.IssueSeverity.ERROR));
                }
                base.setBinding(derived.getBinding().copy());
            } else if (trimDifferential)
                derived.setBinding(null);
            else
                derived.getBinding().setUserData(DERIVATION_EQUALS, true);
        }
        if (derived.hasIsSummaryElement()) {
            if (!Base.compareDeep(derived.getIsSummaryElement(), base.getIsSummaryElement(), false)) {
                if (base.hasIsSummary())
                    throw new Error("Error in profile " + pn + " at " + derived.getPath() + ": Base isSummary = " + base.getIsSummaryElement().asStringValue() + ", derived isSummary = " + derived.getIsSummaryElement().asStringValue());
                base.setIsSummaryElement(derived.getIsSummaryElement().copy());
            } else if (trimDifferential)
                derived.setIsSummaryElement(null);
            else
                derived.getIsSummaryElement().setUserData(DERIVATION_EQUALS, true);
        }
        if (derived.hasType()) {
            if (!Base.compareDeep(derived.getType(), base.getType(), false)) {
                if (base.hasType()) {
                    for (TypeRefComponent ts : derived.getType()) {
                        boolean ok = false;
                        CommaSeparatedStringBuilder b = new CommaSeparatedStringBuilder();
                        for (TypeRefComponent td : base.getType()) {
                            ;
                            b.append(td.getCode());
                            if (td.hasCode() && (td.getCode().equals(ts.getCode()) || td.getCode().equals("Extension") || td.getCode().equals("Element") || td.getCode().equals("*") || ((td.getCode().equals("Resource") || (td.getCode().equals("DomainResource")) && pkp.isResource(ts.getCode())))))
                                ok = true;
                        }
                        if (!ok)
                            throw new DefinitionException("StructureDefinition " + pn + " at " + derived.getPath() + ": illegal constrained type " + ts.getCode() + " from " + b.toString());
                    }
                }
                base.getType().clear();
                for (TypeRefComponent t : derived.getType()) {
                    TypeRefComponent tt = t.copy();
                    // tt.setUserData(DERIVATION_EQUALS, true);
                    base.getType().add(tt);
                }
            } else if (trimDifferential)
                derived.getType().clear();
            else
                for (TypeRefComponent t : derived.getType()) t.setUserData(DERIVATION_EQUALS, true);
        }
        if (derived.hasMapping()) {
            // todo: mappings are not cumulative - one replaces another
            if (!Base.compareDeep(derived.getMapping(), base.getMapping(), false)) {
                for (ElementDefinitionMappingComponent s : derived.getMapping()) {
                    boolean found = false;
                    for (ElementDefinitionMappingComponent d : base.getMapping()) {
                        found = found || (d.getIdentity().equals(s.getIdentity()) && d.getMap().equals(s.getMap()));
                    }
                    if (!found)
                        base.getMapping().add(s);
                }
            } else if (trimDifferential)
                derived.getMapping().clear();
            else
                for (ElementDefinitionMappingComponent t : derived.getMapping()) t.setUserData(DERIVATION_EQUALS, true);
        }
        // todo: constraints are cumulative. there is no replacing
        for (ElementDefinitionConstraintComponent s : base.getConstraint()) {
            s.setUserData(IS_DERIVED, true);
            if (!s.hasSource())
                s.setSource(base.getId());
        }
        if (derived.hasConstraint()) {
            for (ElementDefinitionConstraintComponent s : derived.getConstraint()) {
                ElementDefinitionConstraintComponent inv = s.copy();
                base.getConstraint().add(inv);
            }
        }
        // now, check that we still have a bindable type; if not, delete the binding - see task 8477
        if (dest.hasBinding() && !hasBindableType(dest))
            dest.setBinding(null);
        // finally, we copy any extensions from source to dest
        for (Extension ex : base.getExtension()) {
            StructureDefinition sd = context.fetchResource(StructureDefinition.class, ex.getUrl());
            if (sd == null || sd.getSnapshot() == null || sd.getSnapshot().getElementFirstRep().getMax().equals("1"))
                ToolingExtensions.removeExtension(dest, ex.getUrl());
            dest.addExtension(ex);
        }
    }
}
Also used : ElementDefinitionExampleComponent(org.hl7.fhir.dstu3.model.ElementDefinition.ElementDefinitionExampleComponent) ValidationMessage(org.hl7.fhir.utilities.validation.ValidationMessage) StringType(org.hl7.fhir.dstu3.model.StringType) FHIRFormatError(org.hl7.fhir.exceptions.FHIRFormatError) CommaSeparatedStringBuilder(org.hl7.fhir.utilities.CommaSeparatedStringBuilder) ElementDefinitionConstraintComponent(org.hl7.fhir.dstu3.model.ElementDefinition.ElementDefinitionConstraintComponent) Extension(org.hl7.fhir.dstu3.model.Extension) StructureDefinition(org.hl7.fhir.dstu3.model.StructureDefinition) TypeRefComponent(org.hl7.fhir.dstu3.model.ElementDefinition.TypeRefComponent) ValueSetExpansionOutcome(org.hl7.fhir.dstu3.terminologies.ValueSetExpander.ValueSetExpansionOutcome) ElementDefinition(org.hl7.fhir.dstu3.model.ElementDefinition) DefinitionException(org.hl7.fhir.exceptions.DefinitionException) ElementDefinitionMappingComponent(org.hl7.fhir.dstu3.model.ElementDefinition.ElementDefinitionMappingComponent)

Example 9 with ElementDefinitionConstraintComponent

use of org.hl7.fhir.r4b.model.ElementDefinition.ElementDefinitionConstraintComponent in project org.hl7.fhir.core by hapifhir.

the class ProfileUtilities method generateGridDescription.

private Cell generateGridDescription(HierarchicalTableGenerator gen, Row row, ElementDefinition definition, ElementDefinition fallback, boolean used, String baseURL, String url, StructureDefinition profile, String corePath, String imagePath, boolean root, ElementDefinition valueDefn) throws IOException {
    Cell c = gen.new Cell();
    row.getCells().add(c);
    if (used) {
        if (definition.hasContentReference()) {
            ElementDefinition ed = getElementByName(profile.getSnapshot().getElement(), definition.getContentReference());
            if (ed == null)
                c.getPieces().add(gen.new Piece(null, "Unknown reference to " + definition.getContentReference(), null));
            else
                c.getPieces().add(gen.new Piece("#" + ed.getPath(), "See " + ed.getPath(), null));
        }
        if (definition.getPath().endsWith("url") && definition.hasFixed()) {
            c.getPieces().add(checkForNoChange(definition.getFixed(), gen.new Piece(null, "\"" + buildJson(definition.getFixed()) + "\"", null).addStyle("color: darkgreen")));
        } else {
            if (url != null) {
                if (!c.getPieces().isEmpty())
                    c.addPiece(gen.new Piece("br"));
                String fullUrl = url.startsWith("#") ? baseURL + url : url;
                StructureDefinition ed = context.fetchResource(StructureDefinition.class, url);
                String ref = null;
                if (ed != null) {
                    String p = ed.getUserString("path");
                    if (p != null) {
                        ref = p.startsWith("http:") || igmode ? p : Utilities.pathURL(corePath, p);
                    }
                }
                c.getPieces().add(gen.new Piece(null, "URL: ", null).addStyle("font-weight:bold"));
                c.getPieces().add(gen.new Piece(ref, fullUrl, null));
            }
            if (definition.hasSlicing()) {
                if (!c.getPieces().isEmpty())
                    c.addPiece(gen.new Piece("br"));
                c.getPieces().add(gen.new Piece(null, "Slice: ", null).addStyle("font-weight:bold"));
                c.getPieces().add(gen.new Piece(null, describeSlice(definition.getSlicing()), null));
            }
            if (definition != null) {
                ElementDefinitionBindingComponent binding = null;
                if (valueDefn != null && valueDefn.hasBinding() && !valueDefn.getBinding().isEmpty())
                    binding = valueDefn.getBinding();
                else if (definition.hasBinding())
                    binding = definition.getBinding();
                if (binding != null && !binding.isEmpty()) {
                    if (!c.getPieces().isEmpty())
                        c.addPiece(gen.new Piece("br"));
                    BindingResolution br = pkp.resolveBinding(profile, binding, definition.getPath());
                    c.getPieces().add(checkForNoChange(binding, gen.new Piece(null, "Binding: ", null).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)));
                    if (binding.hasStrength()) {
                        c.getPieces().add(checkForNoChange(binding, gen.new Piece(null, " (", null)));
                        c.getPieces().add(checkForNoChange(binding, gen.new Piece(corePath + "terminologies.html#" + binding.getStrength().toCode(), binding.getStrength().toCode(), binding.getStrength().getDefinition())));
                        c.getPieces().add(gen.new Piece(null, ")", null));
                    }
                }
                for (ElementDefinitionConstraintComponent inv : definition.getConstraint()) {
                    if (!c.getPieces().isEmpty())
                        c.addPiece(gen.new Piece("br"));
                    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, inv.getHuman(), null)));
                }
                if (definition.hasFixed()) {
                    if (!c.getPieces().isEmpty())
                        c.addPiece(gen.new Piece("br"));
                    c.getPieces().add(checkForNoChange(definition.getFixed(), gen.new Piece(null, "Fixed Value: ", null).addStyle("font-weight:bold")));
                    c.getPieces().add(checkForNoChange(definition.getFixed(), gen.new Piece(null, buildJson(definition.getFixed()), null).addStyle("color: darkgreen")));
                } else if (definition.hasPattern()) {
                    if (!c.getPieces().isEmpty())
                        c.addPiece(gen.new Piece("br"));
                    c.getPieces().add(checkForNoChange(definition.getPattern(), gen.new Piece(null, "Required Pattern: ", null).addStyle("font-weight:bold")));
                    c.getPieces().add(checkForNoChange(definition.getPattern(), gen.new Piece(null, buildJson(definition.getPattern()), null).addStyle("color: darkgreen")));
                } else if (definition.hasExample()) {
                    for (ElementDefinitionExampleComponent ex : definition.getExample()) {
                        if (!c.getPieces().isEmpty())
                            c.addPiece(gen.new Piece("br"));
                        c.getPieces().add(checkForNoChange(ex, gen.new Piece(null, "Example'" + ("".equals("General") ? "" : " " + ex.getLabel() + "'") + ": ", null).addStyle("font-weight:bold")));
                        c.getPieces().add(checkForNoChange(ex, gen.new Piece(null, buildJson(ex.getValue()), null).addStyle("color: darkgreen")));
                    }
                }
                if (definition.hasMaxLength() && definition.getMaxLength() != 0) {
                    if (!c.getPieces().isEmpty())
                        c.addPiece(gen.new Piece("br"));
                    c.getPieces().add(checkForNoChange(definition.getMaxLengthElement(), gen.new Piece(null, "Max Length: ", null).addStyle("font-weight:bold")));
                    c.getPieces().add(checkForNoChange(definition.getMaxLengthElement(), gen.new Piece(null, Integer.toString(definition.getMaxLength()), null).addStyle("color: darkgreen")));
                }
                if (profile != null) {
                    for (StructureDefinitionMappingComponent md : profile.getMapping()) {
                        if (md.hasExtension(ToolingExtensions.EXT_TABLE_NAME)) {
                            ElementDefinitionMappingComponent map = null;
                            for (ElementDefinitionMappingComponent m : definition.getMapping()) if (m.getIdentity().equals(md.getIdentity()))
                                map = m;
                            if (map != null) {
                                for (int i = 0; i < definition.getMapping().size(); i++) {
                                    c.addPiece(gen.new Piece("br"));
                                    c.getPieces().add(gen.new Piece(null, ToolingExtensions.readStringExtension(md, ToolingExtensions.EXT_TABLE_NAME) + ": " + map.getMap(), null));
                                }
                            }
                        }
                    }
                }
                if (definition.getComment() != null) {
                    if (!c.getPieces().isEmpty())
                        c.addPiece(gen.new Piece("br"));
                    c.getPieces().add(gen.new Piece(null, "Comments: ", null).addStyle("font-weight:bold"));
                    c.addPiece(gen.new Piece("br"));
                    c.addMarkdown(definition.getComment());
                // c.getPieces().add(checkForNoChange(definition.getCommentElement(), gen.new Piece(null, definition.getComment(), null)));
                }
            }
        }
    }
    return c;
}
Also used : ElementDefinitionExampleComponent(org.hl7.fhir.dstu3.model.ElementDefinition.ElementDefinitionExampleComponent) StructureDefinition(org.hl7.fhir.dstu3.model.StructureDefinition) BindingResolution(org.hl7.fhir.dstu3.conformance.ProfileUtilities.ProfileKnowledgeProvider.BindingResolution) StructureDefinitionMappingComponent(org.hl7.fhir.dstu3.model.StructureDefinition.StructureDefinitionMappingComponent) Piece(org.hl7.fhir.utilities.xhtml.HierarchicalTableGenerator.Piece) ElementDefinition(org.hl7.fhir.dstu3.model.ElementDefinition) Cell(org.hl7.fhir.utilities.xhtml.HierarchicalTableGenerator.Cell) ElementDefinitionBindingComponent(org.hl7.fhir.dstu3.model.ElementDefinition.ElementDefinitionBindingComponent) ElementDefinitionConstraintComponent(org.hl7.fhir.dstu3.model.ElementDefinition.ElementDefinitionConstraintComponent) ElementDefinitionMappingComponent(org.hl7.fhir.dstu3.model.ElementDefinition.ElementDefinitionMappingComponent)

Example 10 with ElementDefinitionConstraintComponent

use of org.hl7.fhir.r4b.model.ElementDefinition.ElementDefinitionConstraintComponent in project org.hl7.fhir.core by hapifhir.

the class ProfileUtilities method updateFromDefinition.

private void updateFromDefinition(ElementDefinition dest, ElementDefinition source, String pn, boolean trimDifferential, String purl) throws DefinitionException, FHIRException {
    // we start with a clone of the base profile ('dest') and we copy from the profile ('source')
    // over the top for anything the source has
    ElementDefinition base = dest;
    ElementDefinition derived = source;
    derived.setUserData(DERIVATION_POINTER, base);
    if (derived != null) {
        boolean isExtension = checkExtensionDoco(base);
        if (derived.hasShortElement()) {
            if (!Base.compareDeep(derived.getShortElement(), base.getShortElement(), false))
                base.setShortElement(derived.getShortElement().copy());
            else if (trimDifferential)
                derived.setShortElement(null);
            else if (derived.hasShortElement())
                derived.getShortElement().setUserData(DERIVATION_EQUALS, true);
        }
        if (derived.hasDefinitionElement()) {
            if (derived.getDefinition().startsWith("..."))
                base.setDefinition(base.getDefinition() + "\r\n" + derived.getDefinition().substring(3));
            else if (!Base.compareDeep(derived.getDefinitionElement(), base.getDefinitionElement(), false))
                base.setDefinitionElement(derived.getDefinitionElement().copy());
            else if (trimDifferential)
                derived.setDefinitionElement(null);
            else if (derived.hasDefinitionElement())
                derived.getDefinitionElement().setUserData(DERIVATION_EQUALS, true);
        }
        if (derived.hasCommentsElement()) {
            if (derived.getComments().startsWith("..."))
                base.setComments(base.getComments() + "\r\n" + derived.getComments().substring(3));
            else if (!Base.compareDeep(derived.getCommentsElement(), base.getCommentsElement(), false))
                base.setCommentsElement(derived.getCommentsElement().copy());
            else if (trimDifferential)
                base.setCommentsElement(derived.getCommentsElement().copy());
            else if (derived.hasCommentsElement())
                derived.getCommentsElement().setUserData(DERIVATION_EQUALS, true);
        }
        if (derived.hasLabelElement()) {
            if (derived.getLabel().startsWith("..."))
                base.setLabel(base.getLabel() + "\r\n" + derived.getLabel().substring(3));
            else if (!Base.compareDeep(derived.getLabelElement(), base.getLabelElement(), false))
                base.setLabelElement(derived.getLabelElement().copy());
            else if (trimDifferential)
                base.setLabelElement(derived.getLabelElement().copy());
            else if (derived.hasLabelElement())
                derived.getLabelElement().setUserData(DERIVATION_EQUALS, true);
        }
        if (derived.hasRequirementsElement()) {
            if (derived.getRequirements().startsWith("..."))
                base.setRequirements(base.getRequirements() + "\r\n" + derived.getRequirements().substring(3));
            else if (!Base.compareDeep(derived.getRequirementsElement(), base.getRequirementsElement(), false))
                base.setRequirementsElement(derived.getRequirementsElement().copy());
            else if (trimDifferential)
                base.setRequirementsElement(derived.getRequirementsElement().copy());
            else if (derived.hasRequirementsElement())
                derived.getRequirementsElement().setUserData(DERIVATION_EQUALS, true);
        }
        // sdf-9
        if (derived.hasRequirements() && !base.getPath().contains("."))
            derived.setRequirements(null);
        if (base.hasRequirements() && !base.getPath().contains("."))
            base.setRequirements(null);
        if (derived.hasAlias()) {
            if (!Base.compareDeep(derived.getAlias(), base.getAlias(), false))
                for (StringType s : derived.getAlias()) {
                    if (!base.hasAlias(s.getValue()))
                        base.getAlias().add(s.copy());
                }
            else if (trimDifferential)
                derived.getAlias().clear();
            else
                for (StringType t : derived.getAlias()) t.setUserData(DERIVATION_EQUALS, true);
        }
        if (derived.hasMinElement()) {
            if (!Base.compareDeep(derived.getMinElement(), base.getMinElement(), false)) {
                if (derived.getMin() < base.getMin())
                    messages.add(new ValidationMessage(Source.ProfileValidator, IssueType.BUSINESSRULE, pn + "." + derived.getPath(), "Derived min  (" + Integer.toString(derived.getMin()) + ") cannot be less than base min (" + Integer.toString(base.getMin()) + ")", IssueSeverity.ERROR));
                base.setMinElement(derived.getMinElement().copy());
            } else if (trimDifferential)
                derived.setMinElement(null);
            else
                derived.getMinElement().setUserData(DERIVATION_EQUALS, true);
        }
        if (derived.hasMaxElement()) {
            if (!Base.compareDeep(derived.getMaxElement(), base.getMaxElement(), false)) {
                if (isLargerMax(derived.getMax(), base.getMax()))
                    messages.add(new ValidationMessage(Source.ProfileValidator, IssueType.BUSINESSRULE, pn + "." + derived.getPath(), "Derived max (" + derived.getMax() + ") cannot be greater than base max (" + base.getMax() + ")", IssueSeverity.ERROR));
                base.setMaxElement(derived.getMaxElement().copy());
            } else if (trimDifferential)
                derived.setMaxElement(null);
            else
                derived.getMaxElement().setUserData(DERIVATION_EQUALS, true);
        }
        if (derived.hasFixed()) {
            if (!Base.compareDeep(derived.getFixed(), base.getFixed(), true)) {
                base.setFixed(derived.getFixed().copy());
            } else if (trimDifferential)
                derived.setFixed(null);
            else
                derived.getFixed().setUserData(DERIVATION_EQUALS, true);
        }
        if (derived.hasPattern()) {
            if (!Base.compareDeep(derived.getPattern(), base.getPattern(), false)) {
                base.setPattern(derived.getPattern().copy());
            } else if (trimDifferential)
                derived.setPattern(null);
            else
                derived.getPattern().setUserData(DERIVATION_EQUALS, true);
        }
        if (derived.hasExample()) {
            if (!Base.compareDeep(derived.getExample(), base.getExample(), false))
                base.setExample(derived.getExample().copy());
            else if (trimDifferential)
                derived.setExample(null);
            else
                derived.getExample().setUserData(DERIVATION_EQUALS, true);
        }
        if (derived.hasMaxLengthElement()) {
            if (!Base.compareDeep(derived.getMaxLengthElement(), base.getMaxLengthElement(), false))
                base.setMaxLengthElement(derived.getMaxLengthElement().copy());
            else if (trimDifferential)
                derived.setMaxLengthElement(null);
            else
                derived.getMaxLengthElement().setUserData(DERIVATION_EQUALS, true);
        }
        if (derived.hasMaxValue()) {
            if (!Base.compareDeep(derived.getMaxValue(), base.getMaxValue(), false))
                base.setMaxValue(derived.getMaxValue().copy());
            else if (trimDifferential)
                derived.setMaxValue(null);
            else
                derived.getMaxValue().setUserData(DERIVATION_EQUALS, true);
        }
        if (derived.hasMinValue()) {
            if (!Base.compareDeep(derived.getMinValue(), base.getMinValue(), false))
                base.setMinValue(derived.getMinValue().copy());
            else if (trimDifferential)
                derived.setMinValue(null);
            else
                derived.getMinValue().setUserData(DERIVATION_EQUALS, true);
        }
        if (derived.hasMustSupportElement()) {
            if (!Base.compareDeep(derived.getMustSupportElement(), base.getMustSupportElement(), false))
                base.setMustSupportElement(derived.getMustSupportElement().copy());
            else if (trimDifferential)
                derived.setMustSupportElement(null);
            else
                derived.getMustSupportElement().setUserData(DERIVATION_EQUALS, true);
        }
        // but extensions can change isModifier
        if (isExtension) {
            if (!Base.compareDeep(derived.getIsModifierElement(), base.getIsModifierElement(), false))
                base.setIsModifierElement(derived.getIsModifierElement().copy());
            else if (trimDifferential)
                derived.setIsModifierElement(null);
            else
                derived.getIsModifierElement().setUserData(DERIVATION_EQUALS, true);
        }
        if (derived.hasBinding()) {
            if (!Base.compareDeep(derived.getBinding(), base.getBinding(), false)) {
                if (base.hasBinding() && base.getBinding().getStrength() == BindingStrength.REQUIRED && derived.getBinding().getStrength() != BindingStrength.REQUIRED)
                    messages.add(new ValidationMessage(Source.ProfileValidator, IssueType.BUSINESSRULE, pn + "." + derived.getPath(), "illegal attempt to change a binding from " + base.getBinding().getStrength().toCode() + " to " + derived.getBinding().getStrength().toCode(), IssueSeverity.ERROR));
                else // throw new DefinitionException("StructureDefinition "+pn+" at "+derived.getPath()+": illegal attempt to change a binding from "+base.getBinding().getStrength().toCode()+" to "+derived.getBinding().getStrength().toCode());
                if (base.hasBinding() && derived.hasBinding() && base.getBinding().getStrength() == BindingStrength.REQUIRED) {
                    ValueSetExpansionOutcome expBase = context.expandVS(context.fetchResource(ValueSet.class, base.getBinding().getValueSetReference().getReference()), true);
                    ValueSetExpansionOutcome expDerived = context.expandVS(context.fetchResource(ValueSet.class, derived.getBinding().getValueSetReference().getReference()), true);
                    if (expBase.getValueset() == null)
                        messages.add(new ValidationMessage(Source.ProfileValidator, IssueType.BUSINESSRULE, pn + "." + base.getPath(), "Binding " + base.getBinding().getValueSetReference().getReference() + " could not be expanded", IssueSeverity.WARNING));
                    else if (expDerived.getValueset() == null)
                        messages.add(new ValidationMessage(Source.ProfileValidator, IssueType.BUSINESSRULE, pn + "." + derived.getPath(), "Binding " + derived.getBinding().getValueSetReference().getReference() + " could not be expanded", IssueSeverity.WARNING));
                    else if (!isSubset(expBase.getValueset(), expDerived.getValueset()))
                        messages.add(new ValidationMessage(Source.ProfileValidator, IssueType.BUSINESSRULE, pn + "." + derived.getPath(), "Binding " + derived.getBinding().getValueSetReference().getReference() + " is not a subset of binding " + base.getBinding().getValueSetReference().getReference(), IssueSeverity.ERROR));
                }
                base.setBinding(derived.getBinding().copy());
            } else if (trimDifferential)
                derived.setBinding(null);
            else
                derived.getBinding().setUserData(DERIVATION_EQUALS, true);
        }
        if (derived.hasIsSummaryElement()) {
            if (!Base.compareDeep(derived.getIsSummaryElement(), base.getIsSummaryElement(), false))
                base.setIsSummaryElement(derived.getIsSummaryElement().copy());
            else if (trimDifferential)
                derived.setIsSummaryElement(null);
            else
                derived.getIsSummaryElement().setUserData(DERIVATION_EQUALS, true);
        }
        if (derived.hasType()) {
            if (!Base.compareDeep(derived.getType(), base.getType(), false)) {
                if (base.hasType()) {
                    for (TypeRefComponent ts : derived.getType()) {
                        boolean ok = false;
                        CommaSeparatedStringBuilder b = new CommaSeparatedStringBuilder();
                        for (TypeRefComponent td : base.getType()) {
                            b.append(td.getCode());
                            if (td.hasCode() && (td.getCode().equals(ts.getCode()) || td.getCode().equals("Extension") || td.getCode().equals("Element") || td.getCode().equals("*") || ((td.getCode().equals("Resource") || (td.getCode().equals("DomainResource")) && pkp.isResource(ts.getCode())))))
                                ok = true;
                        }
                        if (!ok)
                            throw new DefinitionException("StructureDefinition " + pn + " at " + derived.getPath() + ": illegal constrained type " + ts.getCode() + " from " + b.toString());
                    }
                }
                base.getType().clear();
                for (TypeRefComponent t : derived.getType()) {
                    TypeRefComponent tt = t.copy();
                    // tt.setUserData(DERIVATION_EQUALS, true);
                    base.getType().add(tt);
                }
            } else if (trimDifferential)
                derived.getType().clear();
            else
                for (TypeRefComponent t : derived.getType()) t.setUserData(DERIVATION_EQUALS, true);
        }
        if (derived.hasMapping()) {
            // todo: mappings are not cumulative - one replaces another
            if (!Base.compareDeep(derived.getMapping(), base.getMapping(), false)) {
                for (ElementDefinitionMappingComponent s : derived.getMapping()) {
                    boolean found = false;
                    for (ElementDefinitionMappingComponent d : base.getMapping()) {
                        found = found || (d.getIdentity().equals(s.getIdentity()) && d.getMap().equals(s.getMap()));
                    }
                    if (!found)
                        base.getMapping().add(s);
                }
            } else if (trimDifferential)
                derived.getMapping().clear();
            else
                for (ElementDefinitionMappingComponent t : derived.getMapping()) t.setUserData(DERIVATION_EQUALS, true);
        }
        // todo: constraints are cumulative. there is no replacing
        for (ElementDefinitionConstraintComponent s : base.getConstraint()) s.setUserData(IS_DERIVED, true);
        if (derived.hasConstraint()) {
            for (ElementDefinitionConstraintComponent s : derived.getConstraint()) {
                base.getConstraint().add(s.copy());
            }
        }
    }
}
Also used : ValidationMessage(org.hl7.fhir.utilities.validation.ValidationMessage) StringType(org.hl7.fhir.dstu2.model.StringType) TypeRefComponent(org.hl7.fhir.dstu2.model.ElementDefinition.TypeRefComponent) ValueSetExpansionOutcome(org.hl7.fhir.dstu2.terminologies.ValueSetExpander.ValueSetExpansionOutcome) CommaSeparatedStringBuilder(org.hl7.fhir.utilities.CommaSeparatedStringBuilder) ElementDefinition(org.hl7.fhir.dstu2.model.ElementDefinition) DefinitionException(org.hl7.fhir.exceptions.DefinitionException) ElementDefinitionMappingComponent(org.hl7.fhir.dstu2.model.ElementDefinition.ElementDefinitionMappingComponent) ElementDefinitionConstraintComponent(org.hl7.fhir.dstu2.model.ElementDefinition.ElementDefinitionConstraintComponent)

Aggregations

ElementDefinitionConstraintComponent (org.hl7.fhir.r5.model.ElementDefinition.ElementDefinitionConstraintComponent)31 ValidationMessage (org.hl7.fhir.utilities.validation.ValidationMessage)25 ArrayList (java.util.ArrayList)23 ElementDefinition (org.hl7.fhir.r5.model.ElementDefinition)16 CommaSeparatedStringBuilder (org.hl7.fhir.utilities.CommaSeparatedStringBuilder)15 ElementDefinitionConstraintComponent (org.hl7.fhir.r4b.model.ElementDefinition.ElementDefinitionConstraintComponent)14 StructureDefinition (org.hl7.fhir.r5.model.StructureDefinition)12 Cell (org.hl7.fhir.utilities.xhtml.HierarchicalTableGenerator.Cell)10 Piece (org.hl7.fhir.utilities.xhtml.HierarchicalTableGenerator.Piece)10 DefinitionException (org.hl7.fhir.exceptions.DefinitionException)9 FHIRException (org.hl7.fhir.exceptions.FHIRException)9 ElementDefinition (org.hl7.fhir.r4b.model.ElementDefinition)9 StructureDefinition (org.hl7.fhir.r4b.model.StructureDefinition)9 Test (org.junit.jupiter.api.Test)8 FHIRFormatError (org.hl7.fhir.exceptions.FHIRFormatError)7 ElementDefinitionConstraintComponent (org.hl7.fhir.r4.model.ElementDefinition.ElementDefinitionConstraintComponent)7 TypeRefComponent (org.hl7.fhir.r5.model.ElementDefinition.TypeRefComponent)7 Rule (org.hl7.fhir.utilities.xml.SchematronWriter.Rule)7 Section (org.hl7.fhir.utilities.xml.SchematronWriter.Section)7 IOException (java.io.IOException)6