Skip to content

Instantly share code, notes, and snippets.

@lovelock
Last active July 12, 2020 13:56
Show Gist options
  • Save lovelock/baeb5d97f4c18f31c2cd14ecc112856d to your computer and use it in GitHub Desktop.
Save lovelock/baeb5d97f4c18f31c2cd14ecc112856d to your computer and use it in GitHub Desktop.
This is compatible with drools 7.x, InEvaluator is not necessary because it is memberOfEvaluator. drools extension for collection operator, including `in`, `not in`, `intersectWith` and `not intersectWith`
import lombok.extern.slf4j.Slf4j;
import org.kie.api.KieServices;
import org.kie.internal.utils.KieHelper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
@Configuration
@Slf4j
@Profile("console")
public class DroolsConfig {
@Bean(name = "kieHelper")
public KieHelper getKieHelper() {
return new KieHelper()
.setKieModuleModel(KieServices.Factory
.get()
.newKieModuleModel()
.setConfigurationProperty("drools.evaluator.intersectWith", IntersectWithEvaluatorDefinition.class.getName())
.setConfigurationProperty("drools.evaluator.in", InEvaluatorDefinition.class.getName())
);
}
}
import org.drools.core.base.BaseEvaluator;
import org.drools.core.base.ValueType;
import org.drools.core.common.InternalFactHandle;
import org.drools.core.common.InternalWorkingMemory;
import org.drools.core.rule.VariableRestriction;
import org.drools.core.spi.FieldValue;
import org.drools.core.spi.InternalReadAccessor;
import java.util.List;
public class InEvaluator<E> extends BaseEvaluator {
private final boolean isNegated;
public InEvaluator(final ValueType type, final boolean isNegated) {
super(type, isNegated ? InEvaluatorDefinition.IN : InEvaluatorDefinition.NOT_IN);
this.isNegated = isNegated;
}
@Override
@SuppressWarnings("unchecked")
public boolean evaluate(InternalWorkingMemory internalWorkingMemory, InternalReadAccessor internalReadAccessor, InternalFactHandle internalFactHandle, FieldValue fieldValue) {
final Object objectValue = internalReadAccessor.getValue(internalWorkingMemory, internalFactHandle);
return isNegated ^ evaluateAll((E) fieldValue.getValue(), (List<E>) objectValue);
}
@Override
@SuppressWarnings("unchecked")
public boolean evaluate(InternalWorkingMemory internalWorkingMemory, InternalReadAccessor internalReadAccessor, InternalFactHandle internalFactHandle, InternalReadAccessor internalReadAccessor1, InternalFactHandle internalFactHandle1) {
return isNegated ^ evaluateAll((E) internalFactHandle.getObject(), (List<E>) internalFactHandle1.getObject());
}
@Override
@SuppressWarnings("unchecked")
public boolean evaluateCachedLeft(InternalWorkingMemory internalWorkingMemory, VariableRestriction.VariableContextEntry variableContextEntry, InternalFactHandle internalFactHandle) {
final Object valRight = variableContextEntry.extractor.getValue(internalWorkingMemory, internalFactHandle.getObject());
return isNegated ^ evaluateAll((E) ((VariableRestriction.ObjectVariableContextEntry) variableContextEntry).left, (List<E>) valRight);
}
@Override
@SuppressWarnings("unchecked")
public boolean evaluateCachedRight(InternalWorkingMemory internalWorkingMemory, VariableRestriction.VariableContextEntry variableContextEntry, InternalFactHandle internalFactHandle) {
final Object valLeft = variableContextEntry.declaration.getExtractor().getValue(internalWorkingMemory, internalFactHandle);
return isNegated ^ evaluateAll((E) valLeft, (List<E>) ((VariableRestriction.ObjectVariableContextEntry) variableContextEntry).right);
}
public boolean evaluateAll(E element, List<E> container) {
return container.contains(element);
}
}
import org.drools.core.base.ValueType;
import org.drools.core.base.evaluators.EvaluatorDefinition;
import org.drools.core.base.evaluators.Operator;
import org.drools.core.spi.Evaluator;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
public class InEvaluatorDefinition implements EvaluatorDefinition {
protected static final String inOp = "in";
private static final Long serialVersionUID = 1L;
public static Operator IN;
public static Operator NOT_IN;
private static String[] SUPPORTED_IDS;
static {
IN = Operator.addOperatorToRegistry(inOp, false);
NOT_IN = Operator.addOperatorToRegistry(inOp, true);
SUPPORTED_IDS = new String[]{inOp};
}
private InEvaluator<?> evaluator;
private Evaluator[] evaluators;
private InEvaluator<?> negatedEvaluator;
@Override
public boolean isNegatable() {
return true;
}
@Override
public String[] getEvaluatorIds() {
return SUPPORTED_IDS;
}
@Override
public Evaluator getEvaluator(ValueType valueType, String s, boolean b, String s1, Target target, Target target1) {
return b ? (negatedEvaluator == null ? new InEvaluator<>(valueType, true) : negatedEvaluator) :
(evaluator == null ? new InEvaluator<>(valueType, false) : evaluator);
}
@Override
public Evaluator getEvaluator(ValueType valueType, Operator operator, String s) {
return getEvaluator(valueType, operator.getOperatorString(), operator.isNegated(), s);
}
@Override
public Evaluator getEvaluator(ValueType valueType, Operator operator) {
return getEvaluator(valueType, operator.getOperatorString(), operator.isNegated(), null);
}
@Override
public boolean supportsType(ValueType valueType) {
return true;
}
@Override
public Evaluator getEvaluator(ValueType valueType, String s, boolean b, String s1) {
return getEvaluator(valueType, s, b, s1, Target.BOTH, Target.BOTH);
}
@Override
public void writeExternal(ObjectOutput out) throws IOException {
out.writeObject(evaluators);
}
@Override
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
evaluators = (Evaluator[]) in.readObject();
}
@Override
public Target getTarget() {
return Target.BOTH;
}
}
import org.drools.core.base.BaseEvaluator;
import org.drools.core.base.ValueType;
import org.drools.core.common.InternalFactHandle;
import org.drools.core.common.InternalWorkingMemory;
import org.drools.core.rule.VariableRestriction;
import org.drools.core.spi.FieldValue;
import org.drools.core.spi.InternalReadAccessor;
import java.util.List;
public class IntersectWithEvaluator<E> extends BaseEvaluator {
private final boolean isNegated;
public IntersectWithEvaluator(final ValueType type, final boolean isNegated) {
super(type, isNegated ? IntersectWithEvaluatorDefinition.INTERSECT_WITH : IntersectWithEvaluatorDefinition.NOT_INTERSECT_WITH);
this.isNegated = isNegated;
}
@Override
@SuppressWarnings("unchecked")
public boolean evaluate(InternalWorkingMemory internalWorkingMemory, InternalReadAccessor internalReadAccessor, InternalFactHandle internalFactHandle, FieldValue fieldValue) {
final Object objectValue = internalReadAccessor.getValue(internalWorkingMemory, internalFactHandle);
return isNegated ^ evaluateAll((List<E>) fieldValue.getValue(), (List<E>) objectValue);
}
@Override
@SuppressWarnings("unchecked")
public boolean evaluate(InternalWorkingMemory internalWorkingMemory, InternalReadAccessor internalReadAccessor, InternalFactHandle internalFactHandle, InternalReadAccessor internalReadAccessor1, InternalFactHandle internalFactHandle1) {
return isNegated ^ evaluateAll((List<E>) internalFactHandle.getObject(), (List<E>) internalFactHandle1.getObject());
}
@Override
@SuppressWarnings("unchecked")
public boolean evaluateCachedLeft(InternalWorkingMemory internalWorkingMemory, VariableRestriction.VariableContextEntry variableContextEntry, InternalFactHandle internalFactHandle) {
final Object valRight = variableContextEntry.extractor.getValue(internalWorkingMemory, internalFactHandle.getObject());
return isNegated ^ evaluateAll((List<E>) ((VariableRestriction.ObjectVariableContextEntry) variableContextEntry).left, (List<E>) valRight);
}
@Override
@SuppressWarnings("unchecked")
public boolean evaluateCachedRight(InternalWorkingMemory internalWorkingMemory, VariableRestriction.VariableContextEntry variableContextEntry, InternalFactHandle internalFactHandle) {
final Object valLeft = variableContextEntry.declaration.getExtractor().getValue(internalWorkingMemory, internalFactHandle);
return isNegated ^ evaluateAll((List<E>) valLeft, (List<E>) ((VariableRestriction.ObjectVariableContextEntry) variableContextEntry).right);
}
public boolean evaluateAll(List<E> leftList, List<E> rightList) {
return leftList.stream().anyMatch(rightList::contains);
}
}
import org.drools.core.base.ValueType;
import org.drools.core.base.evaluators.EvaluatorDefinition;
import org.drools.core.base.evaluators.Operator;
import org.drools.core.spi.Evaluator;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
public class IntersectWithEvaluatorDefinition implements EvaluatorDefinition {
protected static final String intersectWithOp = "intersectWith";
private static final Long serialVersionUID = 1L;
public static Operator INTERSECT_WITH;
public static Operator NOT_INTERSECT_WITH;
private static String[] SUPPORTED_IDS;
static {
INTERSECT_WITH = Operator.addOperatorToRegistry(intersectWithOp, false);
NOT_INTERSECT_WITH = Operator.addOperatorToRegistry(intersectWithOp, true);
SUPPORTED_IDS = new String[]{intersectWithOp};
}
private IntersectWithEvaluator<?> evaluator;
private IntersectWithEvaluator<?> negatedEvaluator;
private Evaluator[] evaluators;
@Override
public String[] getEvaluatorIds() {
return SUPPORTED_IDS;
}
@Override
public boolean isNegatable() {
return true;
}
@Override
public Evaluator getEvaluator(ValueType valueType, String s, boolean b, String s1, Target target, Target target1) {
return b ? (negatedEvaluator == null ? new IntersectWithEvaluator<>(valueType, true) : negatedEvaluator) :
(evaluator == null ? new IntersectWithEvaluator<>(valueType, false) : evaluator);
}
@Override
public Evaluator getEvaluator(ValueType valueType, String s, boolean b, String s1) {
return getEvaluator(valueType, s, b, s1, Target.BOTH, Target.BOTH);
}
@Override
public Evaluator getEvaluator(ValueType valueType, Operator operator, String s) {
return getEvaluator(valueType, operator.getOperatorString(), operator.isNegated(), s);
}
@Override
public Evaluator getEvaluator(ValueType valueType, Operator operator) {
return getEvaluator(valueType, operator.getOperatorString(), operator.isNegated(), null);
}
@Override
public boolean supportsType(ValueType valueType) {
return true;
}
@Override
public Target getTarget() {
return Target.BOTH;
}
@Override
public void writeExternal(ObjectOutput out) throws IOException {
out.writeObject(evaluators);
}
@Override
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
evaluators = (Evaluator[]) in.readObject();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment