Search in sources :

Example 76 with TypeRefComponent

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

the class FHIRPathEngine method evaluateDefinition.

/**
 * given an element definition in a profile, what element contains the differentiating fixed
 * for the element, given the differentiating expresssion. The expression is only allowed to
 * use a subset of FHIRPath
 *
 * @param profile
 * @param element
 * @return
 * @throws PathEngineException
 * @throws DefinitionException
 */
public TypedElementDefinition evaluateDefinition(ExpressionNode expr, StructureDefinition profile, TypedElementDefinition element, StructureDefinition source, boolean dontWalkIntoReferences) throws DefinitionException {
    StructureDefinition sd = profile;
    TypedElementDefinition focus = null;
    boolean okToNotResolve = false;
    if (expr.getKind() == Kind.Name) {
        if (element.getElement().hasSlicing()) {
            ElementDefinition slice = pickMandatorySlice(sd, element.getElement());
            if (slice == null) {
                throw makeException(expr, I18nConstants.FHIRPATH_DISCRIMINATOR_NAME_ALREADY_SLICED, element.getElement().getId());
            }
            element = new TypedElementDefinition(slice);
        }
        if (expr.getName().equals("$this")) {
            focus = element;
        } else {
            List<ElementDefinition> childDefinitions;
            childDefinitions = profileUtilities.getChildMap(sd, element.getElement());
            // if that's empty, get the children of the type
            if (childDefinitions.isEmpty()) {
                sd = fetchStructureByType(element, expr);
                if (sd == null) {
                    throw makeException(expr, I18nConstants.FHIRPATH_DISCRIMINATOR_THIS_CANNOT_FIND, element.getElement().getType().get(0).getProfile(), element.getElement().getId());
                }
                childDefinitions = profileUtilities.getChildMap(sd, sd.getSnapshot().getElementFirstRep());
            }
            for (ElementDefinition t : childDefinitions) {
                if (tailMatches(t, expr.getName()) && !t.hasSlicing()) {
                    // GG: slicing is a problem here. This is for an exetnsion with a fixed value (type slicing)
                    focus = new TypedElementDefinition(t);
                    break;
                }
            }
        }
    } else if (expr.getKind() == Kind.Function) {
        if ("resolve".equals(expr.getName())) {
            if (element.getTypes().size() == 0) {
                throw makeException(expr, I18nConstants.FHIRPATH_DISCRIMINATOR_RESOLVE_NO_TYPE, element.getElement().getId());
            }
            if (element.getTypes().size() > 1) {
                throw makeException(expr, I18nConstants.FHIRPATH_DISCRIMINATOR_RESOLVE_MULTIPLE_TYPES, element.getElement().getId());
            }
            if (!element.getTypes().get(0).hasTarget()) {
                throw makeException(expr, I18nConstants.FHIRPATH_DISCRIMINATOR_RESOLVE_NOT_REFERENCE, element.getElement().getId(), element.getElement().getType().get(0).getCode() + ")");
            }
            if (element.getTypes().get(0).getTargetProfile().size() > 1) {
                throw makeException(expr, I18nConstants.FHIRPATH_RESOLVE_DISCRIMINATOR_NO_TARGET, element.getElement().getId());
            }
            sd = worker.fetchResource(StructureDefinition.class, element.getTypes().get(0).getTargetProfile().get(0).getValue());
            if (sd == null) {
                throw makeException(expr, I18nConstants.FHIRPATH_RESOLVE_DISCRIMINATOR_CANT_FIND, element.getTypes().get(0).getTargetProfile(), element.getElement().getId());
            }
            focus = new TypedElementDefinition(sd.getSnapshot().getElementFirstRep());
        } else if ("extension".equals(expr.getName())) {
            String targetUrl = expr.getParameters().get(0).getConstant().primitiveValue();
            List<ElementDefinition> childDefinitions = profileUtilities.getChildMap(sd, element.getElement());
            for (ElementDefinition t : childDefinitions) {
                if (t.getPath().endsWith(".extension") && t.hasSliceName()) {
                    System.out.println("t: " + t.getId());
                    StructureDefinition exsd = (t.getType() == null || t.getType().isEmpty() || t.getType().get(0).getProfile().isEmpty()) ? null : worker.fetchResource(StructureDefinition.class, t.getType().get(0).getProfile().get(0).getValue());
                    while (exsd != null && !exsd.getBaseDefinition().equals("http://hl7.org/fhir/StructureDefinition/Extension")) {
                        exsd = worker.fetchResource(StructureDefinition.class, exsd.getBaseDefinition());
                    }
                    if (exsd != null && exsd.getUrl().equals(targetUrl)) {
                        if (profileUtilities.getChildMap(sd, t).isEmpty()) {
                            sd = exsd;
                        }
                        focus = new TypedElementDefinition(t);
                        break;
                    }
                }
            }
            if (focus == null) {
                throw makeException(expr, I18nConstants.FHIRPATH_DISCRIMINATOR_CANT_FIND_EXTENSION, expr.toString(), targetUrl, element.getElement().getId(), sd.getUrl());
            }
        } else if ("ofType".equals(expr.getName())) {
            if (!element.getElement().hasType()) {
                throw makeException(expr, I18nConstants.FHIRPATH_DISCRIMINATOR_TYPE_NONE, element.getElement().getId());
            }
            List<String> atn = new ArrayList<>();
            for (TypeRefComponent tr : element.getTypes()) {
                if (!tr.hasCode()) {
                    throw makeException(expr, I18nConstants.FHIRPATH_DISCRIMINATOR_NO_CODE, element.getElement().getId());
                }
                atn.add(tr.getCode());
            }
            String stn = expr.getParameters().get(0).getName();
            okToNotResolve = true;
            if ((atn.contains(stn))) {
                if (element.getTypes().size() > 1) {
                    focus = new TypedElementDefinition(element.getElement(), stn);
                } else {
                    focus = element;
                }
            }
        } else {
            throw makeException(expr, I18nConstants.FHIRPATH_DISCRIMINATOR_BAD_NAME, expr.getName());
        }
    } else if (expr.getKind() == Kind.Group) {
        throw makeException(expr, I18nConstants.FHIRPATH_DISCRIMINATOR_BAD_SYNTAX_GROUP, expr.toString());
    } else if (expr.getKind() == Kind.Constant) {
        throw makeException(expr, I18nConstants.FHIRPATH_DISCRIMINATOR_BAD_SYNTAX_CONST);
    }
    if (focus == null) {
        if (okToNotResolve) {
            return null;
        } else {
            throw makeException(expr, I18nConstants.FHIRPATH_DISCRIMINATOR_CANT_FIND, expr.toString(), source.getUrl(), element.getElement().getId(), profile.getUrl());
        }
    } else {
        // gdg 26-02-2022. If we're walking towards a resolve() and we're on a reference, and  we try to walk into the reference
        // then we don't do that. .resolve() is allowed on the Reference.reference, but the target of the reference will be defined
        // on the Reference, not the reference.reference.
        ExpressionNode next = expr.getInner();
        if (dontWalkIntoReferences && focus.hasType("Reference") && next != null && next.getKind() == Kind.Name && next.getName().equals("reference")) {
            next = next.getInner();
        }
        if (next == null) {
            return focus;
        } else {
            return evaluateDefinition(next, sd, focus, profile, dontWalkIntoReferences);
        }
    }
}
Also used : StructureDefinition(org.hl7.fhir.r5.model.StructureDefinition) TypeRefComponent(org.hl7.fhir.r5.model.ElementDefinition.TypeRefComponent) ExpressionNode(org.hl7.fhir.r5.model.ExpressionNode) MergedList(org.hl7.fhir.utilities.MergedList) List(java.util.List) ArrayList(java.util.ArrayList) ElementDefinition(org.hl7.fhir.r5.model.ElementDefinition)

Example 77 with TypeRefComponent

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

the class QuestionnaireBuilder method makeTypeList.

private ValueSet makeTypeList(StructureDefinition profile, List<TypeRefComponent> types, String path) {
    ValueSet vs = new ValueSet();
    vs.setName("Type options for " + path);
    vs.setDescription(vs.present());
    vs.setStatus(PublicationStatus.ACTIVE);
    vs.setExpansion(new ValueSetExpansionComponent());
    vs.getExpansion().setIdentifier(Factory.createUUID());
    vs.getExpansion().setTimestampElement(DateTimeType.now());
    for (TypeRefComponent t : types) {
        if (t.hasTarget()) {
            for (UriType u : t.getTargetProfile()) {
                if (u.getValue().startsWith("http://hl7.org/fhir/StructureDefinition/")) {
                    ValueSetExpansionContainsComponent cc = vs.getExpansion().addContains();
                    cc.setCode(u.getValue().substring(40));
                    cc.setSystem("http://hl7.org/fhir/resource-types");
                    cc.setDisplay(cc.getCode());
                }
            }
        } else if (!t.hasProfile()) {
            ValueSetExpansionContainsComponent cc = vs.getExpansion().addContains();
            cc.setCode(t.getWorkingCode());
            cc.setDisplay(t.getWorkingCode());
            cc.setSystem("http://hl7.org/fhir/data-types");
        } else
            for (UriType u : t.getProfile()) {
                ProfileUtilities pu = new ProfileUtilities(context, null, null);
                StructureDefinition ps = pu.getProfile(profile, u.getValue());
                if (ps != null) {
                    ValueSetExpansionContainsComponent cc = vs.getExpansion().addContains();
                    cc.setCode(u.getValue());
                    cc.setDisplay(ps.getType());
                    cc.setSystem("http://hl7.org/fhir/resource-types");
                }
            }
    }
    return vs;
}
Also used : ValueSetExpansionComponent(org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionComponent) ValueSetExpansionContainsComponent(org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionContainsComponent) StructureDefinition(org.hl7.fhir.r5.model.StructureDefinition) TypeRefComponent(org.hl7.fhir.r5.model.ElementDefinition.TypeRefComponent) ProfileUtilities(org.hl7.fhir.r5.conformance.ProfileUtilities) ValueSet(org.hl7.fhir.r5.model.ValueSet) UriType(org.hl7.fhir.r5.model.UriType)

Example 78 with TypeRefComponent

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

the class QuestionnaireBuilder method buildQuestion.

private void buildQuestion(QuestionnaireItemComponent group, StructureDefinition profile, ElementDefinition element, String path, List<QuestionnaireResponse.QuestionnaireResponseItemComponent> answerGroups, List<ElementDefinition> parents) throws FHIRException {
    group.setLinkId(path);
    // in this context, we don't have any concepts to mark...
    // prefix with name?
    group.setText(element.getShort());
    group.setRequired(element.getMin() > 0);
    if (element.getMin() > 0)
        ToolingExtensions.addMin(group, element.getMin());
    group.setRepeats(!element.getMax().equals('1'));
    if (!element.getMax().equals("*"))
        ToolingExtensions.addMax(group, Integer.parseInt(element.getMax()));
    for (QuestionnaireResponse.QuestionnaireResponseItemComponent ag : answerGroups) {
        ag.setLinkId(group.getLinkId());
        ag.setText(group.getText());
    }
    if (!Utilities.noString(element.getComment()))
        ToolingExtensions.addFlyOver(group, element.getDefinition() + " " + element.getComment(), group.getLinkId() + "-flyover");
    else
        ToolingExtensions.addFlyOver(group, element.getDefinition(), group.getLinkId() + "-flyover");
    if (element.getType().size() > 1 || element.getType().get(0).getWorkingCode().equals("*")) {
        List<TypeRefComponent> types = expandTypeList(element.getType());
        Questionnaire.QuestionnaireItemComponent q = addQuestion(group, QuestionnaireItemType.CODING, QuestionnaireAnswerConstraint.OPTIONSONLY, element.getPath(), "_type", "type", null, makeTypeList(profile, types, element.getPath()));
        for (TypeRefComponent t : types) {
            Questionnaire.QuestionnaireItemComponent sub = q.addItem();
            sub.setType(QuestionnaireItemType.GROUP);
            sub.setLinkId(element.getPath() + "._" + t.getUserData("text"));
            sub.setText((String) t.getUserData("text"));
            // always optional, never repeats
            List<QuestionnaireResponse.QuestionnaireResponseItemComponent> selected = new ArrayList<QuestionnaireResponse.QuestionnaireResponseItemComponent>();
            selectTypes(profile, sub, t, answerGroups, selected);
            processDataType(profile, sub, element, element.getPath() + "._" + t.getUserData("text"), t, selected, parents);
        }
    } else
        // now we have to build the question panel for each different data type
        processDataType(profile, group, element, element.getPath(), element.getType().get(0), answerGroups, parents);
}
Also used : Questionnaire(org.hl7.fhir.r5.model.Questionnaire) TypeRefComponent(org.hl7.fhir.r5.model.ElementDefinition.TypeRefComponent) ArrayList(java.util.ArrayList) QuestionnaireResponse(org.hl7.fhir.r5.model.QuestionnaireResponse) QuestionnaireItemComponent(org.hl7.fhir.r5.model.Questionnaire.QuestionnaireItemComponent)

Example 79 with TypeRefComponent

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

the class GraphQLSchemaGenerator method isPrimitive.

private boolean isPrimitive(TypeRefComponent type) {
    String typeName = type.getWorkingCode();
    StructureDefinition sd = context.fetchTypeDefinition(typeName);
    if (sd == null)
        return false;
    return sd.getKind() == StructureDefinitionKind.PRIMITIVETYPE;
}
Also used : StructureDefinition(org.hl7.fhir.r5.model.StructureDefinition)

Example 80 with TypeRefComponent

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

the class InstanceValidator method resolveType.

private ElementDefinition resolveType(String type, List<TypeRefComponent> list) {
    for (TypeRefComponent tr : list) {
        String url = tr.getWorkingCode();
        if (!Utilities.isAbsoluteUrl(url))
            url = "http://hl7.org/fhir/StructureDefinition/" + url;
        long t = System.nanoTime();
        StructureDefinition sd = context.fetchResource(StructureDefinition.class, url);
        timeTracker.sd(t);
        if (sd != null && (sd.getType().equals(type) || sd.getUrl().equals(type)) && sd.hasSnapshot())
            return sd.getSnapshot().getElement().get(0);
    }
    return null;
}
Also used : StructureDefinition(org.hl7.fhir.r5.model.StructureDefinition) TypeRefComponent(org.hl7.fhir.r5.model.ElementDefinition.TypeRefComponent)

Aggregations

TypeRefComponent (org.hl7.fhir.r5.model.ElementDefinition.TypeRefComponent)71 ArrayList (java.util.ArrayList)57 DefinitionException (org.hl7.fhir.exceptions.DefinitionException)47 StructureDefinition (org.hl7.fhir.r5.model.StructureDefinition)43 CommaSeparatedStringBuilder (org.hl7.fhir.utilities.CommaSeparatedStringBuilder)37 ElementDefinition (org.hl7.fhir.r5.model.ElementDefinition)31 TypeRefComponent (org.hl7.fhir.r4b.model.ElementDefinition.TypeRefComponent)30 FHIRException (org.hl7.fhir.exceptions.FHIRException)28 TypeRefComponent (org.hl7.fhir.r4.model.ElementDefinition.TypeRefComponent)24 StructureDefinition (org.hl7.fhir.r4b.model.StructureDefinition)24 FHIRFormatError (org.hl7.fhir.exceptions.FHIRFormatError)19 HashSet (java.util.HashSet)18 TypeRefComponent (org.hl7.fhir.dstu3.model.ElementDefinition.TypeRefComponent)18 ValidationMessage (org.hl7.fhir.utilities.validation.ValidationMessage)18 StructureDefinition (org.hl7.fhir.r4.model.StructureDefinition)17 UriType (org.hl7.fhir.r5.model.UriType)15 CanonicalType (org.hl7.fhir.r5.model.CanonicalType)14 List (java.util.List)13 StructureDefinition (org.hl7.fhir.dstu3.model.StructureDefinition)12 Piece (org.hl7.fhir.utilities.xhtml.HierarchicalTableGenerator.Piece)12