io.github.linuxforhealth.hl7.util.ExpressionUtility 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, 2021
*
* SPDX-License-Identifier: Apache-2.0
*/
package io.github.linuxforhealth.hl7.util;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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.core.Constants;
import io.github.linuxforhealth.core.ObjectMapperUtil;
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.hl7.message.HL7MessageData;
import io.github.linuxforhealth.hl7.resource.PendingExpressionState;
import io.github.linuxforhealth.hl7.resource.ResourceEvaluationResult;
public class ExpressionUtility {
private static final String KEY_NAME_SUFFIX = "KEY_NAME_SUFFIX";
private static final String EVALUATING = "Evaluating {} {}";
private static final Logger LOGGER = LoggerFactory.getLogger(ExpressionUtility.class);
private ExpressionUtility() {
}
/**
* Evaluates map of expression and generates ResourceEvaluationResult object.
*
* @param dataSource The data extractor to be used
* @param context The context in use
* @param baseValue The value to evaluate
* @param expressionMap Map of expressions
* @return {@link ResourceEvaluationResult}
*/
public static ResourceEvaluationResult evaluate(InputDataExtractor dataSource,
Map context, EvaluationResult baseValue,
Map expressionMap) {
try {
Map expressionsToEvaluateLater = new HashMap<>();
Map localContext = new HashMap<>(context);
localContext.put(Constants.NULL_VAR_NAME, new EmptyEvaluationResult());
// initialize the map and list to collect values
List additionalResolveValues = new ArrayList<>();
Map resolveValues = new HashMap<>();
for (Entry entry : expressionMap.entrySet()) {
Expression exp = entry.getValue();
if (exp.isEvaluateLater()) {
expressionsToEvaluateLater.put(entry.getKey(), entry.getValue());
} else {
processExpression(dataSource, baseValue, localContext, additionalResolveValues,
resolveValues, entry);
}
}
resolveValues.values().removeIf(Objects::isNull);
return new ResourceEvaluationResult(resolveValues, additionalResolveValues,
new PendingExpressionState(expressionsToEvaluateLater, context));
} catch (RequiredConstraintFailureException e) {
LOGGER.warn("Resource Constraint condition not satisfied.");
return null;
} catch (IllegalArgumentException | IllegalStateException | DataExtractionException e) {
LOGGER.error("Exception during resource evaluation");
return null;
}
}
private static void processExpression(InputDataExtractor dataSource, EvaluationResult baseValue,
Map localContext, List additionalResolveValues,
Map resolveValues, Entry entry) {
EvaluationResult obj = entry.getValue().evaluate(dataSource, localContext, baseValue);
if (obj != null && !obj.isEmpty()) {
String keyNameSuffix = getKeyNameSuffix(localContext);
// Check if the key already exist in the HashMap, if found append, do not replace
if (!resolveValues.containsKey(getKeyName(entry.getKey(), keyNameSuffix))) {
resolveValues.put(getKeyName(entry.getKey(), keyNameSuffix), obj.getValue());
} else {
Object existing = resolveValues.get(getKeyName(entry.getKey(), keyNameSuffix));
if (existing instanceof List) {
if (obj.getValue() instanceof List) {
((List