io.github.linuxforhealth.hl7.expression.SimpleExpression Maven / Gradle / Ivy
/*
* (C) Copyright IBM Corp. 2020
*
* SPDX-License-Identifier: Apache-2.0
*/
package io.github.linuxforhealth.hl7.expression;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableMap;
import io.github.linuxforhealth.api.EvaluationResult;
import io.github.linuxforhealth.api.InputDataExtractor;
import io.github.linuxforhealth.core.Constants;
import io.github.linuxforhealth.core.expression.ContextValueUtils;
import io.github.linuxforhealth.core.expression.EvaluationResultFactory;
import io.github.linuxforhealth.core.expression.VariableUtils;
import io.github.linuxforhealth.hl7.data.SimpleDataTypeMapper;
import io.github.linuxforhealth.hl7.data.ValueExtractor;
import io.github.linuxforhealth.hl7.util.ExpressionUtility;
@JsonIgnoreProperties(ignoreUnknown = true)
public class SimpleExpression extends AbstractExpression {
private static final Logger LOGGER = LoggerFactory.getLogger(SimpleExpression.class);
private String value;
private ImmutablePair fetch;
@JsonCreator
public SimpleExpression(ExpressionAttributes expAttr) {
super(expAttr);
this.value = expAttr.getValue();
if (StringUtils.isBlank(value)) {
this.value = expAttr.getValueOf();
}
if (this.value != null && this.value.startsWith("$") && this.value.contains(":")) {
String[] tokens = StringUtils.split(this.value, ":", 2);
this.fetch = ImmutablePair.of(tokens[0], tokens[1]);
}
}
@Override
public EvaluationResult evaluateExpression(InputDataExtractor dataSource,
Map contextValues, EvaluationResult baseValue) {
Preconditions.checkArgument(contextValues != null, "contextValues cannot be null");
Map localContextValues = new HashMap<>(contextValues);
if (baseValue != null && !baseValue.isEmpty()) {
localContextValues.put(baseValue.getIdentifier(), baseValue);
localContextValues.put(Constants.BASE_VALUE_NAME, baseValue);
}
/**
* If the expression has fetch pair populated then use that for evaluation.
*/
if(this.fetch!=null) {
return evaluateExpressionForFetch(localContextValues, baseValue);
}
Object resolvedValue = null;
if (VariableUtils.isVar(value)) {
boolean fuzzyMatch = VariableUtils.isFuzzyMatch(value);
EvaluationResult obj =
ContextValueUtils.getVariableValuesFromVariableContextMap(value,
ImmutableMap.copyOf(localContextValues),
this.getExpressionAttr().isUseGroup(), fuzzyMatch);
if (obj != null && !obj.isEmpty()) {
resolvedValue = obj.getValue();
}
} else {
resolvedValue = this.value;
}
if (resolvedValue != null) {
return getValueOfSpecifiedType(resolvedValue);
} else {
return null;
}
}
/**
* Any expression that needs to extract value from another object will use fetch field.
* example:'$ref-type:id' The expression will try and extract the value of the variable $ref-type
* from the context.
*
*
*/
private EvaluationResult evaluateExpressionForFetch(Map contextValues,
EvaluationResult basevalue) {
EvaluationResult resource;
if (Constants.BASE_VALUE_NAME.equals(fetch.getKey())) {
resource = basevalue;
} else {
boolean fuzzyMatch = VariableUtils.isFuzzyMatch(fetch.getKey());
resource = ContextValueUtils.getVariableValuesFromVariableContextMap(fetch.getKey(),
contextValues, this.getExpressionAttr().isUseGroup(), fuzzyMatch);
}
return ExpressionUtility.extractComponent(fetch, resource);
}
private EvaluationResult getValueOfSpecifiedType(Object obj) {
if (obj != null) {
ValueExtractor