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);
}
}
}
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;
}
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);
}
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;
}
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;
}
Aggregations