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.expression.ExpressionAttributes Maven / Gradle / Ivy
/*
* (C) Copyright IBM Corp. 2021
*
* 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 java.util.Map.Entry;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.EnumUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import org.apache.commons.text.StringTokenizer;
import org.apache.commons.text.matcher.StringMatcherFactory;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import io.github.linuxforhealth.api.Condition;
import io.github.linuxforhealth.api.Specification;
import io.github.linuxforhealth.api.Variable;
import io.github.linuxforhealth.core.expression.condition.ConditionUtil;
import io.github.linuxforhealth.hl7.expression.specification.SpecificationParser;
import io.github.linuxforhealth.hl7.expression.variable.VariableGenerator;
@JsonDeserialize(builder = ExpressionAttributes.Builder.class)
public class ExpressionAttributes {
private static final String OBJECT_TYPE = Object.class.getSimpleName();
// Basic properties of an expression
private String name;
private final String type;
private final String defaultValue;
private final boolean isRequired;
private final List specs;
private final List variables;
private final Condition condition; // filter is applies to the specs, spec values that pass the
// condition
// are used for evaluating the expression.
private final Map constants;
private final String value;
private final String valueOf;
private final boolean useGroup;
private ExpressionType expressionType;
private String toString;
private final List expressions;
private final Map expressionsMap;
private final boolean isEvaluateLater;
// if valueof attribute ends with * then list of values will be generated
private boolean generateMultiple;
private ExpressionAttributes(Builder exBuilder) {
if (exBuilder.type == null) {
this.type = OBJECT_TYPE;
} else {
this.type = exBuilder.type;
}
this.defaultValue = exBuilder.defaultValue;
this.name = exBuilder.name;
this.isRequired = exBuilder.isRequired;
this.isEvaluateLater = exBuilder.isEvaluateLater;
this.generateMultiple = exBuilder.generateList;
this.specs = getSpecList(exBuilder.rawSpecs, exBuilder.useGroup, this.generateMultiple);
if (StringUtils.isNotBlank(exBuilder.rawCondition)) {
this.condition = ConditionUtil.createCondition(exBuilder.rawCondition, exBuilder.useGroup);
} else {
this.condition = null;
}
this.constants = new HashMap<>();
if (exBuilder.constants != null && !exBuilder.constants.isEmpty()) {
this.constants.putAll(exBuilder.constants);
}
this.variables = new ArrayList<>();
if (exBuilder.rawVariables != null) {
for (Entry e : exBuilder.rawVariables.entrySet()) {
this.variables.add(VariableGenerator.parse(e.getKey(), e.getValue()));
}
}
this.value = exBuilder.value;
this.valueOf = exBuilder.valueOf;
this.expressionType = exBuilder.expressionType;
this.useGroup = exBuilder.useGroup;
if (this.expressionType == null && CollectionUtils.isNotEmpty(this.specs)) {
this.expressionType = ExpressionType.HL7SPEC;
}
if (exBuilder.expressions != null) {
this.expressions = exBuilder.expressions;
} else {
this.expressions = null;
}
if (exBuilder.expressionsMap != null) {
this.expressionsMap = exBuilder.expressionsMap;
} else {
this.expressionsMap = null;
}
}
public Map getExpressionsMap() {
return expressionsMap;
}
public boolean isUseGroup() {
return useGroup;
}
public String getType() {
return type;
}
public String getDefaultValue() {
return defaultValue;
}
public boolean isRequired() {
return isRequired;
}
public List getSpecs() {
return ImmutableList.copyOf(specs);
}
public List getVariables() {
return ImmutableList.copyOf(variables);
}
public Condition getFilter() {
return condition;
}
public Map getConstants() {
return ImmutableMap.copyOf(constants);
}
public boolean isGenerateMultiple() {
return this.generateMultiple;
}
public String getValue() {
return this.value;
}
public ExpressionType getExpressionType() {
return expressionType;
}
public String getValueOf() {
return valueOf;
}
public String getName() {
return name;
}
public List getExpressions() {
return expressions;
}
/**
* Extract special chars: * indicates to extract fields from multiple entries and indicates to
* retain empty (null) fields
*
* @param inputString The input string to extract from
* @param generateMultiple Should all special characters be extracted in the same call
* @return ExpressionModifiers object with booleans indicating which modifiers were used and the
* expression after modifiers have been removed
*/
public static final ExpressionModifiers extractExpressionModifiers(String inputString,
boolean generateMultiple) {
boolean extractMultiple = generateMultiple;
boolean retainEmpty = false;
String expression = inputString;
if (StringUtils.endsWith(expression, "*") && !StringUtils.endsWith(expression, ".*")) {
expression = StringUtils.removeEnd(expression, "*");
extractMultiple = true;
}
if (StringUtils.endsWith(expression, "&")) {
expression = StringUtils.removeEnd(expression, "&");
retainEmpty = true;
}
// Repeat check for asterisk to allow for different order of special chars
if (StringUtils.endsWith(expression, "*") && !StringUtils.endsWith(expression, ".*")) {
expression = StringUtils.removeEnd(expression, "*");
extractMultiple = true;
}
expression = StringUtils.strip(expression);
return new ExpressionModifiers(extractMultiple, retainEmpty, expression);
}
public static List getSpecList(String inputString, boolean useGroup,
boolean generateMultiple) {
ExpressionModifiers exp = extractExpressionModifiers(inputString, generateMultiple);
List specs = new ArrayList<>();
if (StringUtils.isNotBlank(exp.expression)) {
StringTokenizer st = new StringTokenizer(exp.expression, "|").setIgnoreEmptyTokens(true)
.setTrimmerMatcher(StringMatcherFactory.INSTANCE.spaceMatcher());
st.getTokenList().forEach(s -> specs
.add(SpecificationParser.parse(s, exp.extractMultiple, useGroup, exp.retainEmpty)));
}
return specs;
}
@Override
public String toString() {
if (this.toString == null) {
this.toString = ReflectionToStringBuilder.toString(this, ToStringStyle.NO_CLASS_NAME_STYLE,
false, false, true, null);
}
return this.toString;
}
public boolean isEvaluateLater() {
return isEvaluateLater;
}
public static class Builder {
private String name;
private String type;
private String defaultValue;
private boolean isRequired;
private String rawSpecs;
private String rawCondition;
private Map rawVariables;
private Map constants;
private boolean useGroup;
private ExpressionType expressionType;
private String valueOf;
private String value;
private boolean generateList;
private List expressions;
private Map expressionsMap;
private boolean isEvaluateLater;
public Builder() {
}
public Builder(String singleValue) {
value = singleValue;
this.expressionType = ExpressionType.SIMPLE;
}
public boolean isUseGroup() {
return useGroup;
}
public Builder withName(String name) {
this.name = name;
return this;
}
public Builder withType(String type) {
this.type = type;
return this;
}
public Builder withDefault(String defaultValue) {
this.defaultValue = defaultValue;
return this;
}
public Builder withRequired(boolean isRequired) {
this.isRequired = isRequired;
return this;
}
public Builder withEvaluateLater(boolean isEvaluateLater) {
this.isEvaluateLater = isEvaluateLater;
return this;
}
public Builder withSpecs(String rawSpecs) {
this.rawSpecs = rawSpecs;
return this;
}
public Builder withUseGroup(boolean useGroup) {
this.useGroup = useGroup;
return this;
}
public Builder withCondition(String rawCondition) {
this.rawCondition = rawCondition;
return this;
}
public Builder withVars(Map rawVariables) {
this.rawVariables = rawVariables;
return this;
}
public Builder withConstants(Map constants) {
this.constants = constants;
return this;
}
public Builder withExpressions(List expressions) {
this.expressions = expressions;
return this;
}
public Builder withExpressionsMap(Map expressionsMap) {
this.expressionsMap = expressionsMap;
return this;
}
public Builder withValueOf(String valueOf) {
this.valueOf = StringUtils.trim(valueOf);
if (this.expressionType == null) {
this.expressionType = ExpressionType.SIMPLE;
}
return this;
}
public Builder withExpressionType(String expressionType) {
this.expressionType = EnumUtils.getEnumIgnoreCase(ExpressionType.class, expressionType);
return this;
}
public Builder withValue(String value) {
this.value = value;
this.expressionType = ExpressionType.SIMPLE;
return this;
}
public Builder withGenerateList(boolean generateList) {
this.generateList = generateList;
return this;
}
public ExpressionAttributes build() {
return new ExpressionAttributes(this);
}
}
// Class used when extracting modifiers from the expression, contains the expression after
// modifiers have been removed and
// booleans indicating which modifiers were in the expression.
public static class ExpressionModifiers {
private boolean extractMultiple = false; // true when * is used in the expression
private boolean retainEmpty = false; // true when & is used in the expression
private String expression = ""; // resulting expression after the modifiers have been removed
ExpressionModifiers(boolean theExtractMultiple, boolean theRetainEmpty, String theExpression) {
extractMultiple = theExtractMultiple;
retainEmpty = theRetainEmpty;
expression = theExpression;
}
public boolean getExtractMultiple() {
return extractMultiple;
}
public boolean getRetainEmpty() {
return retainEmpty;
}
public String getExpression() {
return expression;
}
}
public void setName(String key) {
this.name = key;
}
}