-
Notifications
You must be signed in to change notification settings - Fork 9
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix evaluation of is not defined expression #108
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
This file was deleted.
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,126 @@ | ||
package org.drools.ansible.rulebook.integration.api.domain.constraints; | ||
|
||
import org.drools.ansible.rulebook.integration.api.domain.RuleGenerationContext; | ||
import org.drools.ansible.rulebook.integration.api.domain.conditions.ConditionExpression; | ||
import org.drools.ansible.rulebook.integration.api.rulesmodel.ParsedCondition; | ||
import org.drools.model.functions.Function1; | ||
import org.drools.model.prototype.PrototypeExpression; | ||
import org.drools.model.prototype.PrototypeVariable; | ||
import org.kie.api.prototype.Prototype; | ||
import org.kie.api.prototype.PrototypeFactInstance; | ||
|
||
import java.util.Collection; | ||
import java.util.Map; | ||
import java.util.Optional; | ||
import java.util.function.BiPredicate; | ||
|
||
import static org.drools.ansible.rulebook.integration.api.domain.conditions.ConditionExpression.map2Expr; | ||
import static org.drools.model.prototype.PrototypeExpression.thisPrototype; | ||
|
||
public enum NegatedExistsField implements RulebookOperator, ConditionFactory { | ||
|
||
INSTANCE; | ||
|
||
public static final String EXPRESSION_NAME = "IsNotDefinedExpression"; | ||
|
||
private static final Object ADMITTED_UNDEFINED_VALUE = AdmittedUndefinedValue.INSTANCE; | ||
|
||
@Override | ||
public <T, V> BiPredicate<T, V> asPredicate() { | ||
return (t, v) -> v == ADMITTED_UNDEFINED_VALUE; | ||
} | ||
|
||
@Override | ||
public String toString() { | ||
return "NEGATED_EXISTS_FIELD"; | ||
} | ||
|
||
@Override | ||
public ParsedCondition createParsedCondition(RuleGenerationContext ruleContext, String expressionName, Map<?, ?> expression) { | ||
PrototypeExpression rightExpression = map2Expr(ruleContext, expression).getPrototypeExpression(); | ||
return new ParsedCondition(thisPrototype(), this, new PrototypeExpressionWithAdmittedUndefined(rightExpression)); | ||
} | ||
|
||
private static class PrototypeExpressionWithAdmittedUndefined implements PrototypeExpression { | ||
private final PrototypeExpression delegate; | ||
|
||
private PrototypeExpressionWithAdmittedUndefined(PrototypeExpression delegate) { | ||
this.delegate = delegate; | ||
} | ||
|
||
@Override | ||
public Function1<PrototypeFactInstance, Object> asFunction(Prototype prototype) { | ||
return delegate.asFunction(prototype).andThen( result -> result == Prototype.UNDEFINED_VALUE ? ADMITTED_UNDEFINED_VALUE : result ); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is the main fix and it is necessary to workaround the fact that on the Drools side it prevents any constraint evaluation, returning false, when it meets an |
||
} | ||
|
||
@Override | ||
public Collection<String> getImpactedFields() { | ||
return delegate.getImpactedFields(); | ||
} | ||
|
||
@Override | ||
public Optional<String> getIndexingKey() { | ||
return delegate.getIndexingKey(); | ||
} | ||
|
||
@Override | ||
public PrototypeExpression andThen(PrototypeExpression other) { | ||
return delegate.andThen(other); | ||
} | ||
|
||
@Override | ||
public boolean hasPrototypeVariable() { | ||
return delegate.hasPrototypeVariable(); | ||
} | ||
|
||
@Override | ||
public Collection<PrototypeVariable> getPrototypeVariables() { | ||
return delegate.getPrototypeVariables(); | ||
} | ||
|
||
@Override | ||
public PrototypeExpression composeWith(BinaryOperation.Operator op, PrototypeExpression right) { | ||
return delegate.composeWith(op, right); | ||
} | ||
|
||
@Override | ||
public PrototypeExpression add(PrototypeExpression right) { | ||
return delegate.add(right); | ||
} | ||
|
||
@Override | ||
public PrototypeExpression sub(PrototypeExpression right) { | ||
return delegate.sub(right); | ||
} | ||
|
||
@Override | ||
public PrototypeExpression mul(PrototypeExpression right) { | ||
return delegate.mul(right); | ||
} | ||
|
||
@Override | ||
public PrototypeExpression div(PrototypeExpression right) { | ||
return delegate.div(right); | ||
} | ||
} | ||
|
||
public static class AdmittedUndefinedValue { | ||
static final AdmittedUndefinedValue INSTANCE = new AdmittedUndefinedValue(); | ||
static final UnsupportedOperationException HASHCODE_EXCEPTION = new UnsupportedOperationException(); | ||
|
||
public AdmittedUndefinedValue() { | ||
} | ||
|
||
public int hashCode() { | ||
throw HASHCODE_EXCEPTION; | ||
} | ||
|
||
public boolean equals(Object obj) { | ||
return false; | ||
} | ||
|
||
public String toString() { | ||
return "$AdmittedUndefinedValue$"; | ||
} | ||
} | ||
} |
This file was deleted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here I'm clearly making a distinction between the case when the
IsNotDefinedExpression
is used alone, when it is evaluated as ournot
existential operator, or in conjuction with another constraint, when it is simply the negation ofIsDefinedExpression
.