use of org.hl7.fhir.r4b.model.Expression in project org.hl7.fhir.core by hapifhir.
the class MeasureValidator method validateMeasureCriteria.
private void validateMeasureCriteria(ValidatorHostContext hostContext, List<ValidationMessage> errors, MeasureContext mctxt, Element crit, NodeStack nsc) {
String mimeType = crit.getChildValue("language");
if (!Utilities.noString(mimeType)) {
// that would be an error elsewhere
if ("text/cql".equals(mimeType) || "text/cql.identifier".equals(mimeType)) {
String cqlRef = crit.getChildValue("expression");
Library lib = null;
if (rule(errors, IssueType.INVALID, crit.line(), crit.col(), nsc.getLiteralPath(), mctxt.libraries().size() > 0, I18nConstants.MEASURE_M_CRITERIA_CQL_NO_LIB)) {
if (cqlRef.contains(".")) {
String name = cqlRef.substring(0, cqlRef.indexOf("."));
cqlRef = cqlRef.substring(cqlRef.indexOf(".") + 1);
for (Library l : mctxt.libraries()) {
if (name.equals(l.getName())) {
if (rule(errors, IssueType.INVALID, crit.line(), crit.col(), nsc.getLiteralPath(), lib == null, I18nConstants.MEASURE_M_CRITERIA_CQL_LIB_DUPL)) {
lib = l;
}
}
}
rule(errors, IssueType.INVALID, crit.line(), crit.col(), nsc.getLiteralPath(), lib != null, I18nConstants.MEASURE_M_CRITERIA_CQL_LIB_NOT_FOUND, name);
} else {
if (rule(errors, IssueType.INVALID, crit.line(), crit.col(), nsc.getLiteralPath(), mctxt.libraries().size() == 1, I18nConstants.MEASURE_M_CRITERIA_CQL_ONLY_ONE_LIB)) {
lib = mctxt.libraries().get(0);
}
}
}
if (lib != null) {
if (rule(errors, IssueType.INVALID, crit.line(), crit.col(), nsc.getLiteralPath(), lib.hasUserData(MeasureContext.USER_DATA_ELM), I18nConstants.MEASURE_M_CRITERIA_CQL_NO_ELM, lib.getUrl())) {
if (lib.getUserData(MeasureContext.USER_DATA_ELM) instanceof String) {
rule(errors, IssueType.INVALID, crit.line(), crit.col(), nsc.getLiteralPath(), false, I18nConstants.MEASURE_M_CRITERIA_CQL_ERROR, lib.getUrl(), lib.getUserString(MeasureContext.USER_DATA_ELM));
} else if (lib.getUserData(MeasureContext.USER_DATA_ELM) instanceof Document) {
org.w3c.dom.Element elm = ((Document) lib.getUserData(MeasureContext.USER_DATA_ELM)).getDocumentElement();
if (rule(errors, IssueType.INVALID, crit.line(), crit.col(), nsc.getLiteralPath(), isValidElm(elm), I18nConstants.MEASURE_M_CRITERIA_CQL_ELM_NOT_VALID, lib.getUrl(), cqlRef)) {
rule(errors, IssueType.INVALID, crit.line(), crit.col(), nsc.getLiteralPath(), hasCqlTarget(elm, cqlRef), I18nConstants.MEASURE_M_CRITERIA_CQL_NOT_FOUND, lib.getUrl(), cqlRef);
}
}
}
}
} else if ("text/fhirpath".equals(mimeType)) {
warning(errors, IssueType.REQUIRED, crit.line(), crit.col(), nsc.getLiteralPath(), false, I18nConstants.MEASURE_M_CRITERIA_UNKNOWN, mimeType);
} else if ("application/x-fhir-query".equals(mimeType)) {
warning(errors, IssueType.REQUIRED, crit.line(), crit.col(), nsc.getLiteralPath(), false, I18nConstants.MEASURE_M_CRITERIA_UNKNOWN, mimeType);
} else {
warning(errors, IssueType.REQUIRED, crit.line(), crit.col(), nsc.getLiteralPath(), false, I18nConstants.MEASURE_M_CRITERIA_UNKNOWN, mimeType);
}
}
}
use of org.hl7.fhir.r4b.model.Expression 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) 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 if (expr.getInner() == null) {
return focus;
} else {
return evaluateDefinition(expr.getInner(), sd, focus, profile);
}
}
use of org.hl7.fhir.r4b.model.Expression in project org.hl7.fhir.core by hapifhir.
the class ProfileDrivenRenderer method renderLeaf.
private void renderLeaf(ResourceWrapper res, BaseWrapper ew, ElementDefinition defn, XhtmlNode parent, XhtmlNode x, boolean title, boolean showCodeDetails, Map<String, String> displayHints, String path, int indent) throws FHIRException, UnsupportedEncodingException, IOException, EOperationOutcome {
if (ew == null)
return;
Base e = ew.getBase();
if (e instanceof StringType)
x.addText(((StringType) e).getValue());
else if (e instanceof CodeType)
x.addText(((CodeType) e).getValue());
else if (e instanceof IdType)
x.addText(((IdType) e).getValue());
else if (e instanceof Extension)
return;
else if (e instanceof InstantType)
x.addText(((InstantType) e).toHumanDisplay());
else if (e instanceof DateTimeType) {
renderDateTime(x, e);
} else if (e instanceof Base64BinaryType)
x.addText(new Base64().encodeAsString(((Base64BinaryType) e).getValue()));
else if (e instanceof org.hl7.fhir.r5.model.DateType) {
org.hl7.fhir.r5.model.DateType dt = ((org.hl7.fhir.r5.model.DateType) e);
renderDate(x, dt);
} else if (e instanceof Enumeration) {
Object ev = ((Enumeration<?>) e).getValue();
// todo: look up a display name if there is one
x.addText(ev == null ? "" : ev.toString());
} else if (e instanceof BooleanType) {
x.addText(((BooleanType) e).getValue().toString());
} else if (e instanceof CodeableConcept) {
renderCodeableConcept(x, (CodeableConcept) e, showCodeDetails);
} else if (e instanceof Coding) {
renderCoding(x, (Coding) e, showCodeDetails);
} else if (e instanceof CodeableReference) {
renderCodeableReference(x, (CodeableReference) e, showCodeDetails);
} else if (e instanceof Annotation) {
renderAnnotation(x, (Annotation) e);
} else if (e instanceof Identifier) {
renderIdentifier(x, (Identifier) e);
} else if (e instanceof org.hl7.fhir.r5.model.IntegerType) {
if (((org.hl7.fhir.r5.model.IntegerType) e).hasValue()) {
x.addText(Integer.toString(((org.hl7.fhir.r5.model.IntegerType) e).getValue()));
} else {
x.addText("??");
}
} else if (e instanceof org.hl7.fhir.r5.model.Integer64Type) {
if (((org.hl7.fhir.r5.model.Integer64Type) e).hasValue()) {
x.addText(Long.toString(((org.hl7.fhir.r5.model.Integer64Type) e).getValue()));
} else {
x.addText("??");
}
} else if (e instanceof org.hl7.fhir.r5.model.DecimalType) {
x.addText(((org.hl7.fhir.r5.model.DecimalType) e).getValue().toString());
} else if (e instanceof HumanName) {
renderHumanName(x, (HumanName) e);
} else if (e instanceof SampledData) {
renderSampledData(x, (SampledData) e);
} else if (e instanceof Address) {
renderAddress(x, (Address) e);
} else if (e instanceof ContactPoint) {
renderContactPoint(x, (ContactPoint) e);
} else if (e instanceof Expression) {
renderExpression(x, (Expression) e);
} else if (e instanceof Money) {
renderMoney(x, (Money) e);
} else if (e instanceof ContactDetail) {
ContactDetail cd = (ContactDetail) e;
if (cd.hasName()) {
x.tx(cd.getName() + ": ");
}
boolean first = true;
for (ContactPoint c : cd.getTelecom()) {
if (first)
first = false;
else
x.tx(",");
renderContactPoint(x, c);
}
} else if (e instanceof UriType) {
renderUri(x, (UriType) e, defn.getPath(), rcontext != null && rcontext.getResourceResource() != null ? rcontext.getResourceResource().getId() : null);
} else if (e instanceof Timing) {
renderTiming(x, (Timing) e);
} else if (e instanceof Range) {
renderRange(x, (Range) e);
} else if (e instanceof Quantity) {
renderQuantity(x, (Quantity) e, showCodeDetails);
} else if (e instanceof Ratio) {
renderQuantity(x, ((Ratio) e).getNumerator(), showCodeDetails);
x.tx("/");
renderQuantity(x, ((Ratio) e).getDenominator(), showCodeDetails);
} else if (e instanceof Period) {
Period p = (Period) e;
renderPeriod(x, p);
} else if (e instanceof Reference) {
Reference r = (Reference) e;
if (r.getReference() != null && r.getReference().contains("#")) {
if (containedIds.contains(r.getReference().substring(1))) {
x.ah(r.getReference()).tx("See " + r.getReference());
} else {
// in this case, we render the resource in line
ResourceWrapper rw = null;
for (ResourceWrapper t : res.getContained()) {
if (r.getReference().substring(1).equals(t.getId())) {
rw = t;
}
}
if (rw == null) {
renderReference(res, x, r);
} else {
x.an(rw.getId());
ResourceRenderer rr = RendererFactory.factory(rw, context.copy().setAddGeneratedNarrativeHeader(false));
rr.render(parent.blockquote(), rw);
}
}
} else {
renderReference(res, x, r);
}
} else if (e instanceof Resource) {
return;
} else if (e instanceof DataRequirement) {
DataRequirement p = (DataRequirement) e;
renderDataRequirement(x, p);
} else if (e instanceof PrimitiveType) {
x.tx(((PrimitiveType) e).primitiveValue());
} else if (e instanceof ElementDefinition) {
x.tx("todo-bundle");
} else if (e != null && !(e instanceof Attachment) && !(e instanceof Narrative) && !(e instanceof Meta)) {
throw new NotImplementedException("type " + e.getClass().getName() + " not handled - should not be here");
}
}
use of org.hl7.fhir.r4b.model.Expression in project org.hl7.fhir.core by hapifhir.
the class SearchParameterRenderer method render.
public boolean render(XhtmlNode x, SearchParameter spd) throws IOException, FHIRException, EOperationOutcome {
x.h2().addText(spd.getName());
XhtmlNode p = x.para();
p.tx("Parameter ");
p.code().tx(spd.getCode());
p.tx(":");
p.code().tx(spd.getType().toCode());
addMarkdown(x, spd.getDescription());
XhtmlNode tbl = x.table("grid");
XhtmlNode tr = tbl.tr();
tr.td().tx(Utilities.pluralize("Resource", spd.getBase().size()));
XhtmlNode td = tr.td();
for (CodeType t : spd.getBase()) {
StructureDefinition sd = context.getWorker().fetchTypeDefinition(t.toString());
if (sd != null && sd.hasUserData("path")) {
td.sep(", ").ah(sd.getUserString("path")).tx(t.getCode());
} else {
td.sep(", ").tx(t.getCode());
}
}
tr = tbl.tr();
tr.td().tx("Expression");
if (spd.hasExpression()) {
tr.td().code().tx(spd.getExpression());
} else {
tr.td().tx("(none)");
}
if (spd.hasXpathUsage()) {
tr = tbl.tr();
tr.td().tx("Usage");
tr.td().tx(spd.getXpathUsage().getDisplay());
}
if (spd.hasXpath()) {
tr = tbl.tr();
tr.td().tx("XPath");
tr.td().code().tx(spd.getXpath());
}
if (spd.hasTarget()) {
tr = tbl.tr();
tr.td().tx(Utilities.pluralize("Target Resources", spd.getTarget().size()));
td = tr.td();
for (CodeType t : spd.getTarget()) {
StructureDefinition sd = context.getWorker().fetchTypeDefinition(t.toString());
if (sd != null && sd.hasUserData("path")) {
td.sep(", ").ah(sd.getUserString("path")).tx(t.getCode());
} else {
td.sep(", ").tx(t.getCode());
}
}
}
tr = tbl.tr();
tr.td().tx("Multiples");
if (spd.getMultipleAnd() && spd.getMultipleOr()) {
tr.td().tx("The parameter can repeat (and) and can have repeating values (or)");
} else if (spd.getMultipleOr()) {
tr.td().tx("The parameter can repeat (and) but each repeat can only have one value");
} else if (spd.getMultipleAnd()) {
tr.td().tx("The parameter cannot repeat (and) but the single parameter can have multiple values (or)");
} else {
tr.td().tx("The parameter cannot repeat or have multiple values");
}
if (spd.hasComparator()) {
tr = tbl.tr();
tr.td().tx("Comparators");
td = tr.td().tx("Allowed: ");
for (Enumeration<SearchComparator> t : spd.getComparator()) {
td.sep(", ").tx(t.asStringValue());
}
}
if (spd.hasModifier()) {
tr = tbl.tr();
tr.td().tx("Modifiers");
td = tr.td().tx("Allowed: ");
for (Enumeration<SearchModifierCode> t : spd.getModifier()) {
td.sep(", ").tx(t.asStringValue());
}
}
if (spd.hasChain()) {
tr = tbl.tr();
tr.td().tx("Chains");
td = tr.td().tx("Allowed: ");
for (StringType t : spd.getChain()) {
td.sep(", ").tx(t.asStringValue());
}
}
if (spd.hasComponent()) {
x.para().b().tx("Components");
tbl = x.table("grid");
for (SearchParameterComponentComponent t : spd.getComponent()) {
tr = tbl.tr();
SearchParameter tsp = context.getWorker().fetchResource(SearchParameter.class, t.getDefinition());
if (tsp != null && tsp.hasUserData("path")) {
tr.td().ah(tsp.getUserString("path")).tx(tsp.present());
} else {
tr.td().tx(t.getDefinition());
}
tr.td().code().tx(t.getExpression());
}
}
return false;
}
use of org.hl7.fhir.r4b.model.Expression in project org.hl7.fhir.core by hapifhir.
the class DataRenderer method renderExpression.
private boolean renderExpression(CommaSeparatedStringBuilder c, PrimitiveType p) {
Extension exp = p.getExtensionByUrl("http://hl7.org/fhir/StructureDefinition/cqf-expression");
if (exp == null) {
return false;
}
c.append(exp.getValueExpression().getExpression());
return true;
}
Aggregations