All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
io.github.linuxforhealth.hl7.util.ExpressionUtility Maven / Gradle / Ivy
/*
* (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) existing).addAll(obj.getValue());
} else {
((List) existing).add(obj.getValue());
}
}
}
if (obj.getAdditionalResources() != null && !obj.getAdditionalResources().isEmpty()
&& additionalResolveValues != null) {
additionalResolveValues.addAll(obj.getAdditionalResources());
}
}
}
private static String getKeyName(String key, String suffix) {
String[] keyComponents = StringUtils.split(key, "_", 2);
if (keyComponents.length == 2 && KEY_NAME_SUFFIX.equalsIgnoreCase(keyComponents[1])) {
return keyComponents[0] + suffix;
} else {
return keyComponents[0];
}
}
private static String getKeyNameSuffix(Map localContext) {
EvaluationResult res = localContext.get(KEY_NAME_SUFFIX);
if (res == null || res.isEmpty()) {
return null;
}
return res.getValue();
}
public static EvaluationResult extractComponent(ImmutablePair fetch,
EvaluationResult resource) {
if (resource != null && resource.getValue() instanceof ResourceValue) {
ResourceValue rv = resource.getValue();
Map resourceMap = rv.getResource();
return EvaluationResultFactory.getEvaluationResult(resourceMap.get(fetch.getValue()));
} else if (resource != null && resource.getValue() instanceof Map) {
Map resourceMap = (Map) resource.getValue();
return EvaluationResultFactory.getEvaluationResult(resourceMap.get(fetch.getValue()));
} else if (resource != null && !resource.isEmpty()) {
Map resourceMap = ObjectMapperUtil.getJSONInstance().convertValue(resource.getValue(),
Map.class);
return EvaluationResultFactory.getEvaluationResult(resourceMap.get(fetch.getValue()));
} else {
return new EmptyEvaluationResult();
}
}
public static ResourceEvaluationResult evaluate(HL7MessageData dataSource,
Map context, Map expressionMap) {
try {
Map localContext = new HashMap<>(context);
Map resolveValues = new HashMap<>();
List additionalResolveValues = new ArrayList<>();
for (Entry entry : expressionMap.entrySet()) {
processExpression(dataSource, new EmptyEvaluationResult(), localContext,
additionalResolveValues,
resolveValues, entry);
}
resolveValues.values().removeIf(Objects::isNull);
return new ResourceEvaluationResult(resolveValues, additionalResolveValues);
} 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;
}
}
}