io.github.linuxforhealth.hl7.expression.AbstractExpression Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of hl7v2-fhir-converter Show documentation
Show all versions of hl7v2-fhir-converter Show documentation
FHIR converter is a Java based library that enables converting Hl7v2 messages to FHIR resources
/*
* (C) Copyright IBM Corp. 2020
*
* SPDX-License-Identifier: Apache-2.0
*/
package io.github.linuxforhealth.hl7.expression;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableMap;
import io.github.linuxforhealth.api.EvaluationResult;
import io.github.linuxforhealth.api.Expression;
import io.github.linuxforhealth.api.InputDataExtractor;
import io.github.linuxforhealth.api.ResourceValue;
import io.github.linuxforhealth.api.Specification;
import io.github.linuxforhealth.api.Variable;
import io.github.linuxforhealth.core.Constants;
import io.github.linuxforhealth.core.data.DataTypeUtil;
import io.github.linuxforhealth.core.exception.DataExtractionException;
import io.github.linuxforhealth.core.exception.RequiredConstraintFailureException;
import io.github.linuxforhealth.core.expression.EmptyEvaluationResult;
import io.github.linuxforhealth.core.expression.EvaluationResultFactory;
import io.github.linuxforhealth.core.expression.VariableUtils;
import io.github.linuxforhealth.hl7.expression.specification.SpecificationUtil;
public abstract class AbstractExpression implements Expression {
private static final String RESOURCE = "Resource";
private static final Logger LOGGER = LoggerFactory.getLogger(AbstractExpression.class);
private ExpressionAttributes attr;
private String originalContext;
private boolean conditionSatisfiedState;
public AbstractExpression(ExpressionAttributes attr) {
this.attr = attr;
}
@Override
public String getType() {
return this.attr.getType();
}
public ExpressionAttributes getExpressionAttr() {
return this.attr;
}
@Override
public boolean isEvaluateLater() {
return this.attr.isEvaluateLater();
}
@Override
public EvaluationResult getDefaultValue() {
return EvaluationResultFactory.getEvaluationResult(this.attr.getDefaultValue());
}
public boolean isRequired() {
return this.attr.isRequired();
}
@Override
public List getspecs() {
return this.attr.getSpecs();
}
@Override
public List getVariables() {
return this.attr.getVariables();
}
/**
* Evaluates the expression and generated single or multiple resources based on the expression
* values. If expression (reference and resource) ends with * then for that expression the Generic
* result includes list of values.
*
* @see io.github.linuxforhealth.api.Expression#evaluate(io.github.linuxforhealth.api.InputDataExtractor,
* java.util.Map, EvaluationResult)
*/
@Override
public EvaluationResult evaluate(InputDataExtractor dataSource,
Map contextValues, EvaluationResult baseValue) {
Preconditions.checkArgument(dataSource != null, "dataSource cannot be null");
Preconditions.checkArgument(contextValues != null, "contextValues cannot be null");
Preconditions.checkArgument(baseValue != null, "baseValue cannot be null");
EvaluationResult result;
try {
setLoggingContext();
Map localContextValues = new HashMap<>(contextValues);
if (!baseValue.isEmpty()) {
localContextValues.put(baseValue.getIdentifier(), baseValue);
localContextValues.put(Constants.BASE_VALUE_NAME, baseValue);
}
result = evaluateValueOfExpression(dataSource, localContextValues, baseValue);
if (this.conditionSatisfiedState && this.isRequired()
&& (result == null || result.isEmpty())) {
String stringRep = this.toString();
throw new RequiredConstraintFailureException(
"Resource Constraint condition not satisfied for expression :" + stringRep);
} else {
return result;
}
} catch (DataExtractionException | IllegalArgumentException e) {
LOGGER.warn("Failure encountered during evaluation of expression {}",
this.attr.getName());
return null;
} finally {
resetLoggingContext();
}
}
private void setLoggingContext() {
originalContext = MDC.get(RESOURCE);
MDC.put(RESOURCE, originalContext + "-> Field:" + this.getExpressionAttr().getName());
}
private void resetLoggingContext() {
MDC.put(RESOURCE, originalContext);
}
private EvaluationResult evaluateValueOfExpression(InputDataExtractor dataSource,
Map localContextValues, EvaluationResult baseinputValue) {
/**
* Steps:
*
* - Add all constants to the context map
* - Evaluate the specs
* - Evaluate the variables
* - Apply the condition
* - If condition is satisfies then evaluate the valueOf/value attribute.
*
* Note: If generateMultiple is set that all the spec values are used for generating list value
* from the expression.
*
*/
// Add constants to the context map
this.attr.getConstants().entrySet().forEach(e -> localContextValues.put(e.getKey(),
EvaluationResultFactory.getEvaluationResult(e.getValue())));
List