Search in sources :

Example 1 with AggregationMode

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

the class ProfileUtilities method genTypes.

private Cell genTypes(HierarchicalTableGenerator gen, Row r, ElementDefinition e, String profileBaseFileName, StructureDefinition profile, String corePath, String imagePath, boolean root, boolean mustSupportMode) {
    Cell c = gen.new Cell();
    r.getCells().add(c);
    if (e.hasContentReference()) {
        ElementInStructure ed = getElementByName(profile.getSnapshot().getElement(), e.getContentReference(), profile);
        if (ed == null)
            c.getPieces().add(gen.new Piece(null, translate("sd.table", "Unknown reference to %s", e.getContentReference()), null));
        else {
            if (ed.getSource() == profile) {
                c.getPieces().add(gen.new Piece(null, translate("sd.table", "See ", ed.getElement().getPath()), null));
                c.getPieces().add(gen.new Piece("#" + ed.getElement().getPath(), tail(ed.getElement().getPath()), ed.getElement().getPath()));
            } else {
                c.getPieces().add(gen.new Piece(null, translate("sd.table", "See ", ed.getElement().getPath()), null));
                c.getPieces().add(gen.new Piece(pfx(corePath, ed.getSource().getUserString("path")) + "#" + ed.getElement().getPath(), tail(ed.getElement().getPath()) + " (" + ed.getSource().getType() + ")", ed.getElement().getPath()));
            }
        }
        return c;
    }
    List<TypeRefComponent> types = e.getType();
    if (!e.hasType()) {
        if (root) {
            // we'll use base instead of types then
            StructureDefinition bsd = profile == null ? null : context.fetchResource(StructureDefinition.class, profile.getBaseDefinition());
            if (bsd != null) {
                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));
                } else {
                    c.getPieces().add(gen.new Piece(null, bsd.getName(), null));
                }
            }
            return c;
        } else if (e.hasContentReference()) {
            return c;
        } else {
            ElementDefinition d = (ElementDefinition) e.getUserData(DERIVATION_POINTER);
            if (d != null && d.hasType()) {
                types = new ArrayList<ElementDefinition.TypeRefComponent>();
                for (TypeRefComponent tr : d.getType()) {
                    TypeRefComponent tt = tr.copy();
                    tt.setUserData(DERIVATION_EQUALS, true);
                    types.add(tt);
                }
            } else {
                return c;
            }
        }
    }
    boolean first = true;
    TypeRefComponent tl = null;
    for (TypeRefComponent t : types) {
        if (!mustSupportMode || allTypesMustSupport(e) || isMustSupport(t)) {
            if (first) {
                first = false;
            } else {
                c.addPiece(checkForNoChange(tl, gen.new Piece(null, ", ", null)));
            }
            tl = t;
            if (t.hasTarget()) {
                c.getPieces().add(gen.new Piece(corePath + "references.html", t.getWorkingCode(), null));
                if (!mustSupportMode && isMustSupportDirect(t) && e.getMustSupport()) {
                    c.addPiece(gen.new Piece(null, " ", null));
                    c.addStyledText(translate("sd.table", "This type must be supported"), "S", "white", "red", null, false);
                }
                c.getPieces().add(gen.new Piece(null, "(", null));
                boolean tfirst = true;
                for (CanonicalType u : t.getTargetProfile()) {
                    if (!mustSupportMode || allProfilesMustSupport(t.getTargetProfile()) || isMustSupport(u)) {
                        if (tfirst)
                            tfirst = false;
                        else
                            c.addPiece(gen.new Piece(null, " | ", null));
                        genTargetLink(gen, profileBaseFileName, corePath, c, t, u.getValue());
                        if (!mustSupportMode && isMustSupport(u) && e.getMustSupport()) {
                            c.addPiece(gen.new Piece(null, " ", null));
                            c.addStyledText(translate("sd.table", "This target must be supported"), "S", "white", "red", null, false);
                        }
                    }
                }
                c.getPieces().add(gen.new Piece(null, ")", null));
                if (t.getAggregation().size() > 0) {
                    c.getPieces().add(gen.new Piece(corePath + "valueset-resource-aggregation-mode.html", " {", null));
                    boolean firstA = true;
                    for (Enumeration<AggregationMode> a : t.getAggregation()) {
                        if (firstA = true)
                            firstA = false;
                        else
                            c.getPieces().add(gen.new Piece(corePath + "valueset-resource-aggregation-mode.html", ", ", null));
                        c.getPieces().add(gen.new Piece(corePath + "valueset-resource-aggregation-mode.html", codeForAggregation(a.getValue()), hintForAggregation(a.getValue())));
                    }
                    c.getPieces().add(gen.new Piece(corePath + "valueset-resource-aggregation-mode.html", "}", null));
                }
            } else if (t.hasProfile() && (!t.getWorkingCode().equals("Extension") || isProfiledType(t.getProfile()))) {
                // a profiled type
                String ref;
                boolean pfirst = true;
                for (CanonicalType p : t.getProfile()) {
                    if (!mustSupportMode || allProfilesMustSupport(t.getProfile()) || isMustSupport(p)) {
                        if (pfirst) {
                            pfirst = false;
                        } else {
                            c.addPiece(checkForNoChange(tl, gen.new Piece(null, ", ", null)));
                        }
                        ref = pkp == null ? null : pkp.getLinkForProfile(profile, p.getValue());
                        if (ref != null) {
                            String[] parts = ref.split("\\|");
                            if (parts[0].startsWith("http:") || parts[0].startsWith("https:")) {
                                // c.addPiece(checkForNoChange(t, gen.new Piece(parts[0], "<" + parts[1] + ">", t.getCode()))); Lloyd
                                c.addPiece(checkForNoChange(t, gen.new Piece(parts[0], parts[1], t.getWorkingCode())));
                            } else {
                                // c.addPiece(checkForNoChange(t, gen.new Piece((t.getProfile().startsWith(corePath)? corePath: "")+parts[0], "<" + parts[1] + ">", t.getCode())));
                                c.addPiece(checkForNoChange(t, gen.new Piece((p.getValue().startsWith(corePath + "StructureDefinition") ? corePath : "") + parts[0], parts[1], t.getWorkingCode())));
                            }
                        } else
                            c.addPiece(checkForNoChange(t, gen.new Piece((p.getValue().startsWith(corePath) ? corePath : "") + ref, t.getWorkingCode(), null)));
                        if (!mustSupportMode && isMustSupport(p) && e.getMustSupport()) {
                            c.addPiece(gen.new Piece(null, " ", null));
                            c.addStyledText(translate("sd.table", "This profile must be supported"), "S", "white", "red", null, false);
                        }
                    }
                }
            } else {
                String tc = t.getWorkingCode();
                if (Utilities.isAbsoluteUrl(tc)) {
                    StructureDefinition sd = context.fetchTypeDefinition(tc);
                    if (sd == null) {
                        c.addPiece(checkForNoChange(t, gen.new Piece(pkp.getLinkFor(corePath, tc), tc, null)));
                    } else {
                        c.addPiece(checkForNoChange(t, gen.new Piece(pkp.getLinkFor(corePath, tc), sd.getType(), null)));
                    }
                } else if (pkp != null && pkp.hasLinkFor(tc)) {
                    c.addPiece(checkForNoChange(t, gen.new Piece(pkp.getLinkFor(corePath, tc), tc, null)));
                } else {
                    c.addPiece(checkForNoChange(t, gen.new Piece(null, tc, null)));
                }
                if (!mustSupportMode && isMustSupportDirect(t) && e.getMustSupport()) {
                    c.addPiece(gen.new Piece(null, " ", null));
                    c.addStyledText(translate("sd.table", "This type must be supported"), "S", "white", "red", null, false);
                }
            }
        }
    }
    return c;
}
Also used : ArrayList(java.util.ArrayList) AggregationMode(org.hl7.fhir.r5.model.ElementDefinition.AggregationMode) CanonicalType(org.hl7.fhir.r5.model.CanonicalType) StructureDefinition(org.hl7.fhir.r5.model.StructureDefinition) TypeRefComponent(org.hl7.fhir.r5.model.ElementDefinition.TypeRefComponent) Piece(org.hl7.fhir.utilities.xhtml.HierarchicalTableGenerator.Piece) ElementDefinition(org.hl7.fhir.r5.model.ElementDefinition) Cell(org.hl7.fhir.utilities.xhtml.HierarchicalTableGenerator.Cell)

Example 2 with AggregationMode

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

the class ProfileUtilities method genTypes.

private Cell genTypes(HierarchicalTableGenerator gen, Row r, ElementDefinition e, String profileBaseFileName, StructureDefinition profile, String corePath, String imagePath) {
    Cell c = gen.new Cell();
    r.getCells().add(c);
    List<TypeRefComponent> types = e.getType();
    if (!e.hasType()) {
        if (e.hasContentReference()) {
            return c;
        } else {
            ElementDefinition d = (ElementDefinition) e.getUserData(DERIVATION_POINTER);
            if (d != null && d.hasType()) {
                types = new ArrayList<ElementDefinition.TypeRefComponent>();
                for (TypeRefComponent tr : d.getType()) {
                    TypeRefComponent tt = tr.copy();
                    tt.setUserData(DERIVATION_EQUALS, true);
                    types.add(tt);
                }
            } else
                return c;
        }
    }
    boolean first = true;
    TypeRefComponent tl = null;
    for (TypeRefComponent t : types) {
        if (first)
            first = false;
        else
            c.addPiece(checkForNoChange(tl, gen.new Piece(null, ", ", null)));
        tl = t;
        if (t.hasTarget()) {
            c.getPieces().add(gen.new Piece(corePath + "references.html", t.getWorkingCode(), null));
            c.getPieces().add(gen.new Piece(null, "(", null));
            boolean tfirst = true;
            for (UriType u : t.getTargetProfile()) {
                if (tfirst)
                    tfirst = false;
                else
                    c.addPiece(gen.new Piece(null, " | ", null));
                genTargetLink(gen, profileBaseFileName, corePath, c, t, u.getValue());
            }
            c.getPieces().add(gen.new Piece(null, ")", null));
            if (t.getAggregation().size() > 0) {
                c.getPieces().add(gen.new Piece(corePath + "valueset-resource-aggregation-mode.html", " {", null));
                boolean firstA = true;
                for (Enumeration<AggregationMode> a : t.getAggregation()) {
                    if (firstA = true)
                        firstA = false;
                    else
                        c.getPieces().add(gen.new Piece(corePath + "valueset-resource-aggregation-mode.html", ", ", null));
                    c.getPieces().add(gen.new Piece(corePath + "valueset-resource-aggregation-mode.html", codeForAggregation(a.getValue()), hintForAggregation(a.getValue())));
                }
                c.getPieces().add(gen.new Piece(corePath + "valueset-resource-aggregation-mode.html", "}", null));
            }
        } else if (t.hasProfile() && (!t.getWorkingCode().equals("Extension") || isProfiledType(t.getProfile()))) {
            // a profiled type
            String ref;
            ref = pkp.getLinkForProfile(profile, t.getProfile().get(0).getValue());
            if (ref != null) {
                String[] parts = ref.split("\\|");
                if (parts[0].startsWith("http:") || parts[0].startsWith("https:")) {
                    // c.addPiece(checkForNoChange(t, gen.new Piece(parts[0], "<" + parts[1] + ">", t.getCode()))); Lloyd
                    c.addPiece(checkForNoChange(t, gen.new Piece(parts[0], parts[1], t.getWorkingCode())));
                } else {
                    // c.addPiece(checkForNoChange(t, gen.new Piece((t.getProfile().startsWith(corePath)? corePath: "")+parts[0], "<" + parts[1] + ">", t.getCode())));
                    c.addPiece(checkForNoChange(t, gen.new Piece((t.getProfile().get(0).getValue().startsWith(corePath + "StructureDefinition") ? corePath : "") + parts[0], parts[1], t.getWorkingCode())));
                }
            } else
                c.addPiece(checkForNoChange(t, gen.new Piece((t.getProfile().get(0).getValue().startsWith(corePath) ? corePath : "") + ref, t.getWorkingCode(), null)));
        } else {
            String tc = t.getWorkingCode();
            if (pkp != null && pkp.hasLinkFor(tc)) {
                c.addPiece(checkForNoChange(t, gen.new Piece(pkp.getLinkFor(corePath, tc), tc, null)));
            } else
                c.addPiece(checkForNoChange(t, gen.new Piece(null, tc, null)));
        }
    }
    return c;
}
Also used : TypeRefComponent(org.hl7.fhir.r4.model.ElementDefinition.TypeRefComponent) Piece(org.hl7.fhir.utilities.xhtml.HierarchicalTableGenerator.Piece) AggregationMode(org.hl7.fhir.r4.model.ElementDefinition.AggregationMode) ElementDefinition(org.hl7.fhir.r4.model.ElementDefinition) Cell(org.hl7.fhir.utilities.xhtml.HierarchicalTableGenerator.Cell) UriType(org.hl7.fhir.r4.model.UriType)

Example 3 with AggregationMode

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

the class InstanceValidator method checkReference.

private void checkReference(ValidatorHostContext hostContext, List<ValidationMessage> errors, String path, Element element, StructureDefinition profile, ElementDefinition container, String parentType, NodeStack stack) throws FHIRException {
    Reference reference = ObjectConverter.readAsReference(element);
    String ref = reference.getReference();
    if (Utilities.noString(ref)) {
        if (!path.contains("element.pattern")) {
            // this business rule doesn't apply to patterns
            if (Utilities.noString(reference.getIdentifier().getSystem()) && Utilities.noString(reference.getIdentifier().getValue())) {
                warning(errors, IssueType.STRUCTURE, element.line(), element.col(), path, !Utilities.noString(element.getNamedChildValue("display")), I18nConstants.REFERENCE_REF_NODISPLAY);
            }
        }
        return;
    } else if (Utilities.existsInList(ref, "http://tools.ietf.org/html/bcp47")) {
        // special known URLs that can't be validated but are known to be valid
        return;
    }
    warning(errors, IssueType.STRUCTURE, element.line(), element.col(), path, !isSuspiciousReference(ref), I18nConstants.REFERENCE_REF_SUSPICIOUS, ref);
    ResolvedReference we = localResolve(ref, stack, errors, path, hostContext.getRootResource(), hostContext.getGroupingResource(), element);
    String refType;
    if (ref.startsWith("#")) {
        refType = "contained";
    } else {
        if (we == null) {
            refType = "remote";
        } else {
            refType = "bundled";
        }
    }
    ReferenceValidationPolicy pol;
    if (refType.equals("contained") || refType.equals("bundled")) {
        pol = ReferenceValidationPolicy.CHECK_VALID;
    } else {
        if (policyAdvisor == null)
            pol = ReferenceValidationPolicy.IGNORE;
        else
            pol = policyAdvisor.policyForReference(this, hostContext.getAppContext(), path, ref);
    }
    if (pol.checkExists()) {
        if (we == null) {
            if (!refType.equals("contained")) {
                if (fetcher == null) {
                    throw new FHIRException(context.formatMessage(I18nConstants.RESOURCE_RESOLUTION_SERVICES_NOT_PROVIDED));
                } else {
                    Element ext = null;
                    if (fetchCache.containsKey(ref)) {
                        ext = fetchCache.get(ref);
                    } else {
                        try {
                            ext = fetcher.fetch(this, hostContext.getAppContext(), ref);
                        } catch (IOException e) {
                            if (STACK_TRACE)
                                e.printStackTrace();
                            throw new FHIRException(e);
                        }
                        if (ext != null) {
                            setParents(ext);
                            fetchCache.put(ref, ext);
                        }
                    }
                    we = ext == null ? null : makeExternalRef(ext, path);
                }
            }
        }
        boolean ok = (allowExamples && (ref.contains("example.org") || ref.contains("acme.com"))) || (we != null || pol == ReferenceValidationPolicy.CHECK_TYPE_IF_EXISTS);
        rule(errors, IssueType.STRUCTURE, element.line(), element.col(), path, ok, I18nConstants.REFERENCE_REF_CANTRESOLVE, ref);
    }
    String ft;
    if (we != null) {
        ft = we.getType();
    } else {
        ft = tryParse(ref);
    }
    if (reference.hasType()) {
        // R4 onwards...
        // the type has to match the specified
        String tu = isAbsolute(reference.getType()) ? reference.getType() : "http://hl7.org/fhir/StructureDefinition/" + reference.getType();
        TypeRefComponent containerType = container.getType("Reference");
        if (!containerType.hasTargetProfile(tu) && !containerType.hasTargetProfile("http://hl7.org/fhir/StructureDefinition/Resource") && !containerType.getTargetProfile().isEmpty()) {
            boolean matchingResource = false;
            for (CanonicalType target : containerType.getTargetProfile()) {
                StructureDefinition sd = resolveProfile(profile, target.asStringValue());
                if (rule(errors, IssueType.NOTFOUND, element.line(), element.col(), path, sd != null, I18nConstants.REFERENCE_REF_CANTRESOLVEPROFILE, target.asStringValue())) {
                    if (("http://hl7.org/fhir/StructureDefinition/" + sd.getType()).equals(tu)) {
                        matchingResource = true;
                        break;
                    }
                }
            }
            rule(errors, IssueType.STRUCTURE, element.line(), element.col(), path, matchingResource, I18nConstants.REFERENCE_REF_WRONGTARGET, reference.getType(), container.getType("Reference").getTargetProfile());
        }
        // the type has to match the actual
        rule(errors, IssueType.STRUCTURE, element.line(), element.col(), path, ft == null || ft.equals(reference.getType()), I18nConstants.REFERENCE_REF_BADTARGETTYPE, reference.getType(), ft);
    }
    if (we != null && pol.checkType()) {
        if (warning(errors, IssueType.STRUCTURE, element.line(), element.col(), path, ft != null, I18nConstants.REFERENCE_REF_NOTYPE)) {
            // we validate as much as we can. First, can we infer a type from the profile?
            boolean ok = false;
            TypeRefComponent type = getReferenceTypeRef(container.getType());
            if (type.hasTargetProfile() && !type.hasTargetProfile("http://hl7.org/fhir/StructureDefinition/Resource")) {
                Set<String> types = new HashSet<>();
                List<StructureDefinition> profiles = new ArrayList<>();
                for (UriType u : type.getTargetProfile()) {
                    StructureDefinition sd = resolveProfile(profile, u.getValue());
                    if (rule(errors, IssueType.STRUCTURE, element.line(), element.col(), path, sd != null, I18nConstants.REFERENCE_REF_CANTRESOLVEPROFILE, u.getValue())) {
                        types.add(sd.getType());
                        if (ft.equals(sd.getType())) {
                            ok = true;
                            profiles.add(sd);
                        }
                    }
                }
                if (!pol.checkValid()) {
                    rule(errors, IssueType.STRUCTURE, element.line(), element.col(), path, profiles.size() > 0, I18nConstants.REFERENCE_REF_CANTMATCHTYPE, ref, StringUtils.join("; ", type.getTargetProfile()));
                } else {
                    Map<StructureDefinition, List<ValidationMessage>> badProfiles = new HashMap<>();
                    Map<StructureDefinition, List<ValidationMessage>> goodProfiles = new HashMap<>();
                    int goodCount = 0;
                    for (StructureDefinition pr : profiles) {
                        List<ValidationMessage> profileErrors = new ArrayList<ValidationMessage>();
                        validateResource(we.hostContext(hostContext, pr), profileErrors, we.getResource(), we.getFocus(), pr, IdStatus.OPTIONAL, we.getStack().resetIds());
                        if (!hasErrors(profileErrors)) {
                            goodCount++;
                            goodProfiles.put(pr, profileErrors);
                            trackUsage(pr, hostContext, element);
                        } else {
                            badProfiles.put(pr, profileErrors);
                        }
                    }
                    if (goodCount == 1) {
                        if (showMessagesFromReferences) {
                            for (ValidationMessage vm : goodProfiles.values().iterator().next()) {
                                if (!errors.contains(vm)) {
                                    errors.add(vm);
                                }
                            }
                        }
                    } else if (goodProfiles.size() == 0) {
                        if (!isShowMessagesFromReferences()) {
                            rule(errors, IssueType.STRUCTURE, element.line(), element.col(), path, areAllBaseProfiles(profiles), I18nConstants.REFERENCE_REF_CANTMATCHCHOICE, ref, asList(type.getTargetProfile()));
                            for (StructureDefinition sd : badProfiles.keySet()) {
                                slicingHint(errors, IssueType.STRUCTURE, element.line(), element.col(), path, false, false, context.formatMessage(I18nConstants.DETAILS_FOR__MATCHING_AGAINST_PROFILE_, ref, sd.getUrl()), errorSummaryForSlicingAsHtml(badProfiles.get(sd)), errorSummaryForSlicingAsText(badProfiles.get(sd)));
                            }
                        } else {
                            rule(errors, IssueType.STRUCTURE, element.line(), element.col(), path, profiles.size() == 1, I18nConstants.REFERENCE_REF_CANTMATCHCHOICE, ref, asList(type.getTargetProfile()));
                            for (List<ValidationMessage> messages : badProfiles.values()) {
                                for (ValidationMessage vm : messages) {
                                    if (!errors.contains(vm)) {
                                        errors.add(vm);
                                    }
                                }
                            }
                        }
                    } else {
                        if (!isShowMessagesFromReferences()) {
                            warning(errors, IssueType.STRUCTURE, element.line(), element.col(), path, false, I18nConstants.REFERENCE_REF_MULTIPLEMATCHES, ref, asListByUrl(goodProfiles.keySet()));
                            for (StructureDefinition sd : badProfiles.keySet()) {
                                slicingHint(errors, IssueType.STRUCTURE, element.line(), element.col(), path, false, false, context.formatMessage(I18nConstants.DETAILS_FOR__MATCHING_AGAINST_PROFILE_, ref, sd.getUrl()), errorSummaryForSlicingAsHtml(badProfiles.get(sd)), errorSummaryForSlicingAsText(badProfiles.get(sd)));
                            }
                        } else {
                            warning(errors, IssueType.STRUCTURE, element.line(), element.col(), path, false, I18nConstants.REFERENCE_REF_MULTIPLEMATCHES, ref, asListByUrl(goodProfiles.keySet()));
                            for (List<ValidationMessage> messages : goodProfiles.values()) {
                                for (ValidationMessage vm : messages) {
                                    if (!errors.contains(vm)) {
                                        errors.add(vm);
                                    }
                                }
                            }
                        }
                    }
                }
                rule(errors, IssueType.STRUCTURE, element.line(), element.col(), path, ok, I18nConstants.REFERENCE_REF_BADTARGETTYPE, ft, types.toString());
            }
            if (type.hasAggregation() && !noCheckAggregation) {
                boolean modeOk = false;
                CommaSeparatedStringBuilder b = new CommaSeparatedStringBuilder();
                for (Enumeration<AggregationMode> mode : type.getAggregation()) {
                    b.append(mode.getCode());
                    if (mode.getValue().equals(AggregationMode.CONTAINED) && refType.equals("contained"))
                        modeOk = true;
                    else if (mode.getValue().equals(AggregationMode.BUNDLED) && refType.equals("bundled"))
                        modeOk = true;
                    else if (mode.getValue().equals(AggregationMode.REFERENCED) && (refType.equals("bundled") || refType.equals("remote")))
                        modeOk = true;
                }
                rule(errors, IssueType.STRUCTURE, element.line(), element.col(), path, modeOk, I18nConstants.REFERENCE_REF_AGGREGATION, refType, b.toString());
            }
        }
    }
    if (we == null) {
        TypeRefComponent type = getReferenceTypeRef(container.getType());
        boolean okToRef = !type.hasAggregation() || type.hasAggregation(AggregationMode.REFERENCED);
        rule(errors, IssueType.REQUIRED, -1, -1, path, okToRef, I18nConstants.REFERENCE_REF_NOTFOUND_BUNDLE, ref);
    }
    if (we == null && ft != null && assumeValidRestReferences) {
        // if we == null, we inferred ft from the reference. if we are told to treat this as gospel
        TypeRefComponent type = getReferenceTypeRef(container.getType());
        Set<String> types = new HashSet<>();
        StructureDefinition sdFT = context.fetchResource(StructureDefinition.class, "http://hl7.org/fhir/StructureDefinition/" + ft);
        boolean ok = false;
        for (CanonicalType tp : type.getTargetProfile()) {
            StructureDefinition sd = context.fetchResource(StructureDefinition.class, tp.getValue());
            if (sd != null) {
                types.add(sd.getType());
            }
            StructureDefinition sdF = sdFT;
            while (sdF != null) {
                if (sdF.getType().equals(sd.getType())) {
                    ok = true;
                    break;
                }
                sdF = sdF.hasBaseDefinition() ? context.fetchResource(StructureDefinition.class, sdF.getBaseDefinition()) : null;
            }
        }
        rule(errors, IssueType.STRUCTURE, element.line(), element.col(), path, types.isEmpty() || ok, I18nConstants.REFERENCE_REF_BADTARGETTYPE2, ft, ref, types);
    }
    if (pol == ReferenceValidationPolicy.CHECK_VALID) {
    // todo....
    }
}
Also used : ResolvedReference(org.hl7.fhir.validation.instance.utils.ResolvedReference) ValidationMessage(org.hl7.fhir.utilities.validation.ValidationMessage) HashMap(java.util.HashMap) NamedElement(org.hl7.fhir.r5.elementmodel.ParserBase.NamedElement) IndexedElement(org.hl7.fhir.validation.instance.utils.IndexedElement) SpecialElement(org.hl7.fhir.r5.elementmodel.Element.SpecialElement) Element(org.hl7.fhir.r5.elementmodel.Element) ArrayList(java.util.ArrayList) AggregationMode(org.hl7.fhir.r5.model.ElementDefinition.AggregationMode) CanonicalType(org.hl7.fhir.r5.model.CanonicalType) UriType(org.hl7.fhir.r5.model.UriType) StructureDefinition(org.hl7.fhir.r5.model.StructureDefinition) TypeRefComponent(org.hl7.fhir.r5.model.ElementDefinition.TypeRefComponent) ArrayList(java.util.ArrayList) List(java.util.List) HashSet(java.util.HashSet) Reference(org.hl7.fhir.r5.model.Reference) ResolvedReference(org.hl7.fhir.validation.instance.utils.ResolvedReference) CommaSeparatedStringBuilder(org.hl7.fhir.utilities.CommaSeparatedStringBuilder) IOException(java.io.IOException) FHIRException(org.hl7.fhir.exceptions.FHIRException) ContactPoint(org.hl7.fhir.r5.model.ContactPoint)

Example 4 with AggregationMode

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

the class ProfileUtilities method genTypes.

private Cell genTypes(HierarchicalTableGenerator gen, Row r, ElementDefinition e, String profileBaseFileName, StructureDefinition profile, String corePath, String imagePath, boolean root, boolean mustSupportMode) {
    Cell c = gen.new Cell();
    r.getCells().add(c);
    if (e.hasContentReference()) {
        ElementInStructure ed = getElementByName(profile.getSnapshot().getElement(), e.getContentReference(), profile);
        if (ed == null)
            c.getPieces().add(gen.new Piece(null, translate("sd.table", "Unknown reference to %s", e.getContentReference()), null));
        else {
            if (ed.getSource() == profile) {
                c.getPieces().add(gen.new Piece(null, translate("sd.table", "See ", ed.getElement().getPath()), null));
                c.getPieces().add(gen.new Piece("#" + ed.getElement().getPath(), tail(ed.getElement().getPath()), ed.getElement().getPath()));
            } else {
                c.getPieces().add(gen.new Piece(null, translate("sd.table", "See ", ed.getElement().getPath()), null));
                c.getPieces().add(gen.new Piece(pfx(corePath, ed.getSource().getUserString("path")) + "#" + ed.getElement().getPath(), tail(ed.getElement().getPath()) + " (" + ed.getSource().getType() + ")", ed.getElement().getPath()));
            }
        }
        return c;
    }
    List<TypeRefComponent> types = e.getType();
    if (!e.hasType()) {
        if (root) {
            // we'll use base instead of types then
            StructureDefinition bsd = profile == null ? null : context.fetchResource(StructureDefinition.class, profile.getBaseDefinition());
            if (bsd != null) {
                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));
                } else {
                    c.getPieces().add(gen.new Piece(null, bsd.getName(), null));
                }
            }
            return c;
        } else if (e.hasContentReference()) {
            return c;
        } else {
            ElementDefinition d = (ElementDefinition) e.getUserData(DERIVATION_POINTER);
            if (d != null && d.hasType()) {
                types = new ArrayList<ElementDefinition.TypeRefComponent>();
                for (TypeRefComponent tr : d.getType()) {
                    TypeRefComponent tt = tr.copy();
                    tt.setUserData(DERIVATION_EQUALS, true);
                    types.add(tt);
                }
            } else {
                return c;
            }
        }
    }
    boolean first = true;
    TypeRefComponent tl = null;
    for (TypeRefComponent t : types) {
        if (!mustSupportMode || allTypesMustSupport(e) || isMustSupport(t)) {
            if (first) {
                first = false;
            } else {
                c.addPiece(checkForNoChange(tl, gen.new Piece(null, ", ", null)));
            }
            tl = t;
            if (t.hasTarget()) {
                c.getPieces().add(gen.new Piece(corePath + "references.html", t.getWorkingCode(), null));
                if (!mustSupportMode && isMustSupportDirect(t) && e.getMustSupport()) {
                    c.addPiece(gen.new Piece(null, " ", null));
                    c.addStyledText(translate("sd.table", "This type must be supported"), "S", "white", "red", null, false);
                }
                c.getPieces().add(gen.new Piece(null, "(", null));
                boolean tfirst = true;
                for (CanonicalType u : t.getTargetProfile()) {
                    if (!mustSupportMode || allProfilesMustSupport(t.getTargetProfile()) || isMustSupport(u)) {
                        if (tfirst)
                            tfirst = false;
                        else
                            c.addPiece(gen.new Piece(null, " | ", null));
                        genTargetLink(gen, profileBaseFileName, corePath, c, t, u.getValue());
                        if (!mustSupportMode && isMustSupport(u) && e.getMustSupport()) {
                            c.addPiece(gen.new Piece(null, " ", null));
                            c.addStyledText(translate("sd.table", "This target must be supported"), "S", "white", "red", null, false);
                        }
                    }
                }
                c.getPieces().add(gen.new Piece(null, ")", null));
                if (t.getAggregation().size() > 0) {
                    c.getPieces().add(gen.new Piece(corePath + "valueset-resource-aggregation-mode.html", " {", null));
                    boolean firstA = true;
                    for (Enumeration<AggregationMode> a : t.getAggregation()) {
                        if (firstA = true)
                            firstA = false;
                        else
                            c.getPieces().add(gen.new Piece(corePath + "valueset-resource-aggregation-mode.html", ", ", null));
                        c.getPieces().add(gen.new Piece(corePath + "valueset-resource-aggregation-mode.html", codeForAggregation(a.getValue()), hintForAggregation(a.getValue())));
                    }
                    c.getPieces().add(gen.new Piece(corePath + "valueset-resource-aggregation-mode.html", "}", null));
                }
            } else if (t.hasProfile() && (!t.getWorkingCode().equals("Extension") || isProfiledType(t.getProfile()))) {
                // a profiled type
                String ref;
                boolean pfirst = true;
                for (CanonicalType p : t.getProfile()) {
                    if (!mustSupportMode || allProfilesMustSupport(t.getProfile()) || isMustSupport(p)) {
                        if (pfirst) {
                            pfirst = false;
                        } else {
                            c.addPiece(checkForNoChange(tl, gen.new Piece(null, ", ", null)));
                        }
                        ref = pkp == null ? null : pkp.getLinkForProfile(profile, p.getValue());
                        if (ref != null) {
                            String[] parts = ref.split("\\|");
                            if (parts[0].startsWith("http:") || parts[0].startsWith("https:")) {
                                // c.addPiece(checkForNoChange(t, gen.new Piece(parts[0], "<" + parts[1] + ">", t.getCode()))); Lloyd
                                c.addPiece(checkForNoChange(t, gen.new Piece(parts[0], parts[1], t.getWorkingCode())));
                            } else {
                                // c.addPiece(checkForNoChange(t, gen.new Piece((t.getProfile().startsWith(corePath)? corePath: "")+parts[0], "<" + parts[1] + ">", t.getCode())));
                                c.addPiece(checkForNoChange(t, gen.new Piece((p.getValue().startsWith(corePath + "StructureDefinition") ? corePath : "") + parts[0], parts[1], t.getWorkingCode())));
                            }
                        } else
                            c.addPiece(checkForNoChange(t, gen.new Piece((p.getValue().startsWith(corePath) ? corePath : "") + ref, t.getWorkingCode(), null)));
                        if (!mustSupportMode && isMustSupport(p) && e.getMustSupport()) {
                            c.addPiece(gen.new Piece(null, " ", null));
                            c.addStyledText(translate("sd.table", "This profile must be supported"), "S", "white", "red", null, false);
                        }
                    }
                }
            } else {
                String tc = t.getWorkingCode();
                if (Utilities.isAbsoluteUrl(tc)) {
                    StructureDefinition sd = context.fetchTypeDefinition(tc);
                    if (sd == null) {
                        c.addPiece(checkForNoChange(t, gen.new Piece(pkp.getLinkFor(corePath, tc), tc, null)));
                    } else {
                        c.addPiece(checkForNoChange(t, gen.new Piece(pkp.getLinkFor(corePath, tc), sd.getType(), null)));
                    }
                } else if (pkp != null && pkp.hasLinkFor(tc)) {
                    c.addPiece(checkForNoChange(t, gen.new Piece(pkp.getLinkFor(corePath, tc), tc, null)));
                } else {
                    c.addPiece(checkForNoChange(t, gen.new Piece(null, tc, null)));
                }
                if (!mustSupportMode && isMustSupportDirect(t) && e.getMustSupport()) {
                    c.addPiece(gen.new Piece(null, " ", null));
                    c.addStyledText(translate("sd.table", "This type must be supported"), "S", "white", "red", null, false);
                }
            }
        }
    }
    return c;
}
Also used : ArrayList(java.util.ArrayList) AggregationMode(org.hl7.fhir.r4b.model.ElementDefinition.AggregationMode) CanonicalType(org.hl7.fhir.r4b.model.CanonicalType) StructureDefinition(org.hl7.fhir.r4b.model.StructureDefinition) TypeRefComponent(org.hl7.fhir.r4b.model.ElementDefinition.TypeRefComponent) Piece(org.hl7.fhir.utilities.xhtml.HierarchicalTableGenerator.Piece) ElementDefinition(org.hl7.fhir.r4b.model.ElementDefinition) Cell(org.hl7.fhir.utilities.xhtml.HierarchicalTableGenerator.Cell)

Example 5 with AggregationMode

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

the class ProfileUtilities method genTypes.

private Cell genTypes(HierarchicalTableGenerator gen, Row r, ElementDefinition e, String profileBaseFileName, StructureDefinition profile, String corePath, String imagePath) {
    Cell c = gen.new Cell();
    r.getCells().add(c);
    List<TypeRefComponent> types = e.getType();
    if (!e.hasType()) {
        if (e.hasContentReference()) {
            return c;
        } else {
            ElementDefinition d = (ElementDefinition) e.getUserData(DERIVATION_POINTER);
            if (d != null && d.hasType()) {
                types = new ArrayList<ElementDefinition.TypeRefComponent>();
                for (TypeRefComponent tr : d.getType()) {
                    TypeRefComponent tt = tr.copy();
                    tt.setUserData(DERIVATION_EQUALS, true);
                    types.add(tt);
                }
            } else
                return c;
        }
    }
    boolean first = true;
    // either all types are the same, or we don't consider any of them the same
    Element source = types.get(0);
    int aggMode = AGG_NONE;
    boolean allReference = !types.isEmpty();
    Set<AggregationMode> aggs = new HashSet<ElementDefinition.AggregationMode>();
    for (TypeRefComponent t : types) {
        if (t.getCode() != null && t.getCode().equals("Reference") && t.hasProfile()) {
            for (Enumeration<AggregationMode> en : t.getAggregation()) aggs.add(en.getValue());
        } else
            allReference = false;
    }
    if (allReference) {
        if (aggs.size() > 0) {
            boolean allSame = true;
            for (TypeRefComponent t : types) {
                for (AggregationMode agg : aggs) {
                    boolean found = false;
                    for (Enumeration<AggregationMode> en : t.getAggregation()) if (en.getValue() == agg)
                        found = true;
                    if (!found)
                        allSame = false;
                }
            }
            aggMode = allSame ? AGG_GR : AGG_IND;
            if (aggMode != AGG_GR)
                allReference = false;
        }
    } else
        aggMode = aggs.size() == 0 ? AGG_NONE : AGG_IND;
    if (allReference) {
        c.getPieces().add(gen.new Piece(corePath + "references.html", "Reference", null));
        c.getPieces().add(gen.new Piece(null, "(", null));
    }
    TypeRefComponent tl = null;
    for (TypeRefComponent t : types) {
        if (first)
            first = false;
        else if (allReference)
            c.addPiece(checkForNoChange(tl, gen.new Piece(null, " | ", null)));
        else
            c.addPiece(checkForNoChange(tl, gen.new Piece(null, ", ", null)));
        tl = t;
        if (t.getCode() != null && t.getCode().equals("Reference")) {
            if (!allReference) {
                c.getPieces().add(gen.new Piece(corePath + "references.html", "Reference", null));
                c.getPieces().add(gen.new Piece(null, "(", null));
            }
            if (t.hasTargetProfile() && t.getTargetProfile().startsWith("http://hl7.org/fhir/StructureDefinition/")) {
                StructureDefinition sd = context.fetchResource(StructureDefinition.class, t.getTargetProfile());
                if (sd != null) {
                    String disp = sd.hasTitle() ? sd.getTitle() : sd.getName();
                    c.addPiece(checkForNoChange(t, gen.new Piece(checkPrepend(corePath, sd.getUserString("path")), disp, null)));
                } else {
                    String rn = t.getTargetProfile().substring(40);
                    c.addPiece(checkForNoChange(t, gen.new Piece(pkp.getLinkFor(corePath, rn), rn, null)));
                }
            } else if (t.hasTargetProfile() && Utilities.isAbsoluteUrl(t.getTargetProfile())) {
                StructureDefinition sd = context.fetchResource(StructureDefinition.class, t.getTargetProfile());
                if (sd != null) {
                    String disp = sd.hasTitle() ? sd.getTitle() : sd.getName();
                    String ref = pkp.getLinkForProfile(null, sd.getUrl());
                    if (ref.contains("|"))
                        ref = ref.substring(0, ref.indexOf("|"));
                    c.addPiece(checkForNoChange(t, gen.new Piece(ref, disp, null)));
                } else
                    c.addPiece(checkForNoChange(t, gen.new Piece(null, t.getTargetProfile(), null)));
            } else if (t.hasTargetProfile() && t.getTargetProfile().startsWith("#"))
                c.addPiece(checkForNoChange(t, gen.new Piece(corePath + profileBaseFileName + "." + t.getTargetProfile().substring(1).toLowerCase() + ".html", t.getTargetProfile(), null)));
            else if (t.hasTargetProfile())
                c.addPiece(checkForNoChange(t, gen.new Piece(corePath + t.getTargetProfile(), t.getTargetProfile(), null)));
            if (!allReference) {
                c.getPieces().add(gen.new Piece(null, ")", null));
                if (t.getAggregation().size() > 0) {
                    c.getPieces().add(gen.new Piece(corePath + "valueset-resource-aggregation-mode.html", " {", null));
                    boolean firstA = true;
                    for (Enumeration<AggregationMode> a : t.getAggregation()) {
                        if (firstA = true)
                            firstA = false;
                        else
                            c.getPieces().add(gen.new Piece(corePath + "valueset-resource-aggregation-mode.html", ", ", null));
                        c.getPieces().add(gen.new Piece(corePath + "valueset-resource-aggregation-mode.html", codeForAggregation(a.getValue()), null));
                    }
                    c.getPieces().add(gen.new Piece(corePath + "valueset-resource-aggregation-mode.html", "}", null));
                }
            }
        } else if (t.hasProfile() && (!t.getCode().equals("Extension") || t.getProfile().contains(":"))) {
            // a profiled type
            String ref;
            ref = pkp.getLinkForProfile(profile, t.getProfile());
            if (ref != null) {
                String[] parts = ref.split("\\|");
                if (parts[0].startsWith("http:") || parts[0].startsWith("https:"))
                    c.addPiece(checkForNoChange(t, gen.new Piece(parts[0], parts[1], t.getCode())));
                else
                    c.addPiece(checkForNoChange(t, gen.new Piece((t.getProfile().startsWith(corePath) ? corePath : "") + parts[0], parts[1], t.getCode())));
            } else
                c.addPiece(checkForNoChange(t, gen.new Piece((t.getProfile().startsWith(corePath) ? corePath : "") + ref, t.getCode(), null)));
        } else if (pkp.hasLinkFor(t.getCode())) {
            c.addPiece(checkForNoChange(t, gen.new Piece(pkp.getLinkFor(corePath, t.getCode()), t.getCode(), null)));
        } else
            c.addPiece(checkForNoChange(t, gen.new Piece(null, t.getCode(), null)));
    }
    if (allReference) {
        c.getPieces().add(gen.new Piece(null, ")", null));
        if (aggs.size() > 0) {
            c.getPieces().add(gen.new Piece(corePath + "valueset-resource-aggregation-mode.html", " {", null));
            boolean firstA = true;
            for (AggregationMode a : aggs) {
                if (firstA = true)
                    firstA = false;
                else
                    c.getPieces().add(gen.new Piece(corePath + "valueset-resource-aggregation-mode.html", ", ", null));
                c.getPieces().add(gen.new Piece(corePath + "valueset-resource-aggregation-mode.html", codeForAggregation(a), null));
            }
            c.getPieces().add(gen.new Piece(corePath + "valueset-resource-aggregation-mode.html", "}", null));
        }
    }
    return c;
}
Also used : Element(org.hl7.fhir.dstu3.model.Element) AggregationMode(org.hl7.fhir.dstu3.model.ElementDefinition.AggregationMode) StructureDefinition(org.hl7.fhir.dstu3.model.StructureDefinition) TypeRefComponent(org.hl7.fhir.dstu3.model.ElementDefinition.TypeRefComponent) Piece(org.hl7.fhir.utilities.xhtml.HierarchicalTableGenerator.Piece) ElementDefinition(org.hl7.fhir.dstu3.model.ElementDefinition) Cell(org.hl7.fhir.utilities.xhtml.HierarchicalTableGenerator.Cell) HashSet(java.util.HashSet)

Aggregations

Cell (org.hl7.fhir.utilities.xhtml.HierarchicalTableGenerator.Cell)4 Piece (org.hl7.fhir.utilities.xhtml.HierarchicalTableGenerator.Piece)4 ArrayList (java.util.ArrayList)3 HashSet (java.util.HashSet)2 CanonicalType (org.hl7.fhir.r5.model.CanonicalType)2 AggregationMode (org.hl7.fhir.r5.model.ElementDefinition.AggregationMode)2 TypeRefComponent (org.hl7.fhir.r5.model.ElementDefinition.TypeRefComponent)2 StructureDefinition (org.hl7.fhir.r5.model.StructureDefinition)2 IOException (java.io.IOException)1 HashMap (java.util.HashMap)1 List (java.util.List)1 Element (org.hl7.fhir.dstu3.model.Element)1 ElementDefinition (org.hl7.fhir.dstu3.model.ElementDefinition)1 AggregationMode (org.hl7.fhir.dstu3.model.ElementDefinition.AggregationMode)1 TypeRefComponent (org.hl7.fhir.dstu3.model.ElementDefinition.TypeRefComponent)1 StructureDefinition (org.hl7.fhir.dstu3.model.StructureDefinition)1 FHIRException (org.hl7.fhir.exceptions.FHIRException)1 ElementDefinition (org.hl7.fhir.r4.model.ElementDefinition)1 AggregationMode (org.hl7.fhir.r4.model.ElementDefinition.AggregationMode)1 TypeRefComponent (org.hl7.fhir.r4.model.ElementDefinition.TypeRefComponent)1