package org.drools.base.evaluators;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import org.drools.base.BaseEvaluator;
import org.drools.base.ValueType;
import org.drools.base.evaluators.EvaluatorDefinition;
import org.drools.base.evaluators.Operator;
import org.drools.common.InternalWorkingMemory;
import org.drools.rule.VariableRestriction.ObjectVariableContextEntry;
import org.drools.rule.VariableRestriction.VariableContextEntry;
import org.drools.spi.Evaluator;
import org.drools.spi.FieldValue;
import org.drools.spi.InternalReadAccessor;
/**
* <p>The implementation of the 'str' evaluator definition.</p>
*
* <p>The <b><code>str</code></b> compares two string values.</p>
*
* <p>Lets look at some examples:</p>
*
* <pre>$m : Message( routingValue str[startsWith] "R1" )</pre>
* <pre>$m : Message( routingValue str[endsWith] "R2" )</pre>
* <pre>$m : Message( routingValue str[length] 17 )</pre>
*
*
* @author tsurdilo
*/
public class StrEvaluatorDefinition implements EvaluatorDefinition {
public static final Operator STR_COMPARE = Operator.addOperatorToRegistry(
"str", false);
public static final Operator NOT_STR_COMPARE = Operator
.addOperatorToRegistry("str", true);
private static final String[] SUPPORTED_IDS = { STR_COMPARE
.getOperatorString() };
public enum Operations {
startsWith, endsWith, length;
}
private Evaluator[] evaluator;
/**
* @inheridDoc
*/
public Evaluator getEvaluator(ValueType type, Operator operator) {
return this.getEvaluator(type, operator.getOperatorString(), operator
.isNegated(), null);
}
/**
* @inheridDoc
*/
public Evaluator getEvaluator(ValueType type, Operator operator,
String parameterText) {
return this.getEvaluator(type, operator.getOperatorString(), operator
.isNegated(), parameterText);
}
/**
* @inheridDoc
*/
public Evaluator getEvaluator(ValueType type, String operatorId,
boolean isNegated, String parameterText) {
return getEvaluator(type, operatorId, isNegated, parameterText,
Target.FACT, Target.FACT);
}
/**
* @inheridDoc
*/
public Evaluator getEvaluator(ValueType type, String operatorId,
boolean isNegated, String parameterText, Target leftTarget,
Target rightTarget) {
StrEvaluator evaluator = new StrEvaluator(type, isNegated);
evaluator.setParameterText(parameterText);
return evaluator;
}
/**
* @inheridDoc
*/
public String[] getEvaluatorIds() {
return SUPPORTED_IDS;
}
/**
* @inheridDoc
*/
public Target getTarget() {
return Target.FACT;
}
/**
* @inheridDoc
*/
public boolean isNegatable() {
return true;
}
/**
* @inheridDoc
*/
public boolean supportsType(ValueType type) {
return true;
}
/**
* @inheridDoc
*/
public void readExternal(ObjectInput in) throws IOException,
ClassNotFoundException {
evaluator = (Evaluator[]) in.readObject();
}
/**
* @inheridDoc
*/
public void writeExternal(ObjectOutput out) throws IOException {
out.writeObject(evaluator);
}
public static class StrEvaluator extends BaseEvaluator {
private Operations parameter;
public void setParameterText(String parameterText) {
this.parameter = Operations.valueOf(parameterText);
}
public Operations getParameter() {
return parameter;
}
public StrEvaluator(final ValueType type, final boolean isNegated) {
super(type, isNegated ? NOT_STR_COMPARE : STR_COMPARE);
}
/**
* @inheridDoc
*/
public boolean evaluate(InternalWorkingMemory workingMemory,
InternalReadAccessor extractor, Object object, FieldValue value) {
final Object objectValue = extractor
.getValue(workingMemory, object);
switch (parameter) {
case startsWith:
return this.getOperator().isNegated() ^ (((String)objectValue).startsWith( (String)value.getValue() ));
case endsWith:
return this.getOperator().isNegated() ^ (((String)objectValue).endsWith( (String)value.getValue() ));
case length:
return this.getOperator().isNegated() ^ (((String)objectValue).length() == ((Long) value.getValue()).longValue() );
default:
throw new IllegalAccessError("Illegal str comparison parameter");
}
}
public boolean evaluate(InternalWorkingMemory workingMemory,
InternalReadAccessor leftExtractor, Object left,
InternalReadAccessor rightExtractor, Object right) {
final Object value1 = leftExtractor.getValue(workingMemory, left);
final Object value2 = rightExtractor.getValue(workingMemory, right);
switch (parameter) {
case startsWith:
return this.getOperator().isNegated() ^ (((String)value1).startsWith( (String) value2 ));
case endsWith:
return this.getOperator().isNegated() ^ (((String)value1).endsWith( (String) value2 ));
case length:
return this.getOperator().isNegated() ^ (((String)value1).length() == ((Long) value2).longValue() );
default:
throw new IllegalAccessError("Illegal str comparison parameter");
}
}
public boolean evaluateCachedLeft(InternalWorkingMemory workingMemory,
VariableContextEntry context, Object right) {
switch (parameter) {
case startsWith:
return this.getOperator().isNegated() ^ (((String)right).startsWith( (String)((ObjectVariableContextEntry)
context).left) );
case endsWith:
return this.getOperator().isNegated() ^ (((String)right).endsWith( (String)((ObjectVariableContextEntry)
context).left));
case length:
return this.getOperator().isNegated() ^ (((String)right).length() == ((Long)((ObjectVariableContextEntry)
context).left).longValue());
default:
throw new IllegalAccessError("Illegal str comparison parameter");
}
}
public boolean evaluateCachedRight(InternalWorkingMemory workingMemory,
VariableContextEntry context, Object left) {
switch (parameter) {
case startsWith:
return this.getOperator().isNegated() ^ (((String)left).startsWith((String)((ObjectVariableContextEntry)
context).right));
case endsWith:
return this.getOperator().isNegated() ^ (((String)left).endsWith((String)((ObjectVariableContextEntry)
context).right));
case length:
return this.getOperator().isNegated() ^ (((String)left).length() == ((Long)((ObjectVariableContextEntry)
context).right).longValue());
default:
throw new IllegalAccessError("Illegal str comparison parameter");
}
}
@Override
public String toString() {
return "StrEvaluatorDefinition str";
}
}
}