/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.kie.dmn.feel.lang.ast;
import org.antlr.v4.runtime.ParserRuleContext;
import org.kie.dmn.api.feel.runtime.events.FEELEvent.Severity;
import org.kie.dmn.feel.lang.EvaluationContext;
import org.kie.dmn.feel.runtime.Range;
import org.kie.dmn.feel.runtime.UnaryTest;
import org.kie.dmn.feel.util.Msg;
public class InNode
extends BaseNode {
private BaseNode value;
private BaseNode exprs;
public InNode(ParserRuleContext ctx, BaseNode value, BaseNode exprs) {
super( ctx );
this.value = value;
this.exprs = exprs;
}
public BaseNode getValue() {
return value;
}
public void setValue(BaseNode value) {
this.value = value;
}
public BaseNode getExprs() {
return exprs;
}
public void setExprs(BaseNode exprs) {
this.exprs = exprs;
}
@Override
public Boolean evaluate(EvaluationContext ctx) {
Object value = this.value.evaluate( ctx );
Object expr = this.exprs.evaluate( ctx );
if ( expr != null ) {
if ( expr instanceof Iterable ) {
// evaluate in the collection
for ( Object e : ((Iterable) expr) ) {
// have to compare to Boolean.TRUE because in() might return null
if ( in( ctx, value, e ) == Boolean.TRUE ) {
return true;
}
}
return false;
} else {
// evaluate single entity
return in( ctx, value, expr );
}
}
ctx.notifyEvt( astEvent(Severity.ERROR, Msg.createMessage(Msg.IS_NULL, "Expression")) );
return null;
}
private Boolean in(EvaluationContext ctx, Object value, Object expr) {
// need to improve this to work with unary tests
if ( expr == null ) {
return value == expr;
} else if ( expr instanceof UnaryTest ) {
return ((UnaryTest) expr).apply( ctx, value );
} else if ( expr instanceof Range ) {
if( !( value instanceof Comparable ) ) {
ctx.notifyEvt( astEvent(Severity.ERROR, Msg.createMessage(Msg.EXPRESSION_IS_RANGE_BUT_VALUE_IS_NOT_COMPARABLE)));
return null;
}
return ((Range) expr).includes( (Comparable) value );
} else if ( value != null ) {
return value.equals( expr );
} else {
// value == null, expr != null and not Unary test
ctx.notifyEvt( astEvent(Severity.WARN, Msg.createMessage(Msg.VALUE_NULL_EXPR_NOT_NULL_AND_NOT_UNARY_TEST_EVALUATING_THIS_NODE_AS_FALSE)));
return Boolean.FALSE;
}
}
}