Skip to content

Commit

Permalink
Extend Event report mechanism to FEEL AST Nodes (apache#23)
Browse files Browse the repository at this point in the history
* reboot

* BaseNode

* BetweenNode

* FilterExpressionNode

* FunctionDefNode

* FunctionInvocationNode

* IfExpressionNode

* InNode

* NumberNode

* PathExpressionNode

* QuantifiedExpressionNode

* RangeNode

* SignedUnaryNode

* UnaryTestNode

* toString

* Fix RangeNode checks

* Improve BetweenNode checks

* Improve FilterExpression event

* Improve FunctionDefNode event

* Fix UnaryTestNode actual check

* Fix string formatting
  • Loading branch information
tarilabs authored and etirelli committed Dec 20, 2016
1 parent d4a2749 commit beb5f3b
Show file tree
Hide file tree
Showing 15 changed files with 164 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,10 @@
package org.kie.dmn.feel.lang;

import org.kie.dmn.feel.lang.impl.FEELEventListenersManager;
import org.kie.dmn.feel.runtime.events.FEELEvent;

import java.util.Map;
import java.util.function.Supplier;

public interface EvaluationContext {

Expand All @@ -39,4 +41,8 @@ public interface EvaluationContext {
Map<String, Object> getAllValues();

FEELEventListenersManager getEventsManager();

default void notifyEvt(Supplier<FEELEvent> event) {
FEELEventListenersManager.notifyListeners(getEventsManager(), event);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,17 @@

package org.kie.dmn.feel.lang.ast;

import java.util.function.Supplier;

import org.antlr.v4.runtime.ParserRuleContext;
import org.antlr.v4.runtime.misc.Interval;
import org.kie.dmn.feel.lang.EvaluationContext;
import org.kie.dmn.feel.lang.Type;
import org.kie.dmn.feel.lang.impl.EvaluationContextImpl;
import org.kie.dmn.feel.lang.types.BuiltInType;
import org.kie.dmn.feel.runtime.events.ASTEventBase;
import org.kie.dmn.feel.runtime.events.FEELEvent;
import org.kie.dmn.feel.runtime.events.FEELEvent.Severity;

public class BaseNode
implements ASTNode {
Expand Down Expand Up @@ -119,9 +124,17 @@ public String toString() {
public Type getResultType() {
return BuiltInType.UNKNOWN;
}

protected Supplier<FEELEvent> astEvent(Severity severity, String message) {
return () -> new ASTEventBase(severity, message, this) ;
}
protected Supplier<FEELEvent> astEvent(Severity severity, String message, Throwable throwable) {
return () -> new ASTEventBase(severity, message, this, throwable) ;
}

@Override
public Object evaluate(EvaluationContext ctx) {
ctx.notifyEvt( astEvent(Severity.ERROR, "BaseNode evaluate called") );
return null;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

import org.antlr.v4.runtime.ParserRuleContext;
import org.kie.dmn.feel.lang.EvaluationContext;
import org.kie.dmn.feel.runtime.events.FEELEvent.Severity;

public class BetweenNode
extends BaseNode {
Expand Down Expand Up @@ -59,15 +60,31 @@ public void setEnd(BaseNode end) {

@Override
public Object evaluate(EvaluationContext ctx) {
if ( value != null && start != null && end != null ) {
Comparable val = (Comparable) value.evaluate( ctx );
Comparable s = (Comparable) start.evaluate( ctx );
Comparable e = (Comparable) end.evaluate( ctx );
if ( val != null && s != null && e != null &&
val.getClass().isAssignableFrom( s.getClass() ) && val.getClass().isAssignableFrom( e.getClass() ) ) {
return val.compareTo( s ) >= 0 && val.compareTo( e ) <= 0;
}
boolean problem = false;
if ( value == null ) { ctx.notifyEvt( astEvent(Severity.ERROR, "value is null") ); problem = true; }
if ( start == null ) { ctx.notifyEvt( astEvent(Severity.ERROR, "start is null") ); problem = true; }
if ( end == null ) { ctx.notifyEvt( astEvent(Severity.ERROR, "end is null") ); problem = true; }
if (problem) return null;

Comparable val = (Comparable) value.evaluate( ctx );
Comparable s = (Comparable) start.evaluate( ctx );
Comparable e = (Comparable) end.evaluate( ctx );

if ( val == null ) { ctx.notifyEvt( astEvent(Severity.ERROR, "value evaluated to null") ); problem = true; }
if ( s == null ) { ctx.notifyEvt( astEvent(Severity.ERROR, "start evaluated to null") ); problem = true; }
if ( e == null ) { ctx.notifyEvt( astEvent(Severity.ERROR, "end evaluated to null") ); problem = true; }
if (problem) return null;

if ( !val.getClass().isAssignableFrom( s.getClass() ) ) {
ctx.notifyEvt( astEvent(Severity.ERROR, "value type incompatible with start type") );
return null;
}

if ( !val.getClass().isAssignableFrom( e.getClass() ) ) {
ctx.notifyEvt( astEvent(Severity.ERROR, "value type incompatible with end types") );
return null;
}
return null;

return val.compareTo( s ) >= 0 && val.compareTo( e ) <= 0;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

import org.antlr.v4.runtime.ParserRuleContext;
import org.kie.dmn.feel.lang.EvaluationContext;
import org.kie.dmn.feel.runtime.events.FEELEvent.Severity;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand Down Expand Up @@ -70,6 +71,7 @@ public Object evaluate(EvaluationContext ctx) {
} else if ( i < 0 && Math.abs( i ) <= list.size() ) {
return list.get( list.size() + i );
} else {
ctx.notifyEvt( astEvent(Severity.ERROR, "Index out of bound") );
return null;
}
} else {
Expand All @@ -80,7 +82,9 @@ public Object evaluate(EvaluationContext ctx) {
return results;
}
} catch ( Exception e ) {
logger.error( "Error executing list filter: " + getText(), e );
ctx.notifyEvt( astEvent(Severity.ERROR,
String.format("Error executing list filter: %s", getText()),
e) );
}

return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

import org.antlr.v4.runtime.ParserRuleContext;
import org.kie.dmn.feel.lang.EvaluationContext;
import org.kie.dmn.feel.runtime.events.FEELEvent.Severity;
import org.kie.dmn.feel.runtime.functions.CustomFEELFunction;
import org.kie.dmn.feel.runtime.functions.JavaFunction;
import org.slf4j.Logger;
Expand Down Expand Up @@ -110,16 +111,20 @@ public Object evaluate(EvaluationContext ctx) {
Method method = clazz.getMethod( methodName, paramTypes );
return new JavaFunction( ANONYMOUS, params, clazz, method );
} else {
logger.error( "Parameter count mismatch on function definition: "+getText() );
ctx.notifyEvt( astEvent(Severity.ERROR,
String.format("Parameter count mismatch on function definition: %s", getText())) );
return null;
}
}
}
}
}
logger.error("Unable to find external function as defined by "+getText() );
ctx.notifyEvt( astEvent(Severity.ERROR,
String.format("Unable to find external function as defined by: %s", getText()) ) );
} catch( Exception e ) {
logger.error("Error resolving external function as defined by "+getText(), e );
ctx.notifyEvt( astEvent(Severity.ERROR,
String.format("Error resolving external function as defined by: %s", getText()),
e) );
}
return null;
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,14 @@

package org.kie.dmn.feel.lang.ast;

import java.util.function.Supplier;

import org.antlr.v4.runtime.ParserRuleContext;
import org.kie.dmn.feel.lang.EvaluationContext;
import org.kie.dmn.feel.runtime.FEELFunction;
import org.kie.dmn.feel.runtime.UnaryTest;
import org.kie.dmn.feel.runtime.events.FEELEvent;
import org.kie.dmn.feel.runtime.events.FEELEvent.Severity;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand Down Expand Up @@ -72,16 +76,19 @@ public Object evaluate(EvaluationContext ctx) {
Object result = function.invokeReflectively( ctx, p );
return result;
} else {
logger.error( "Function not found: '" + name.getText() + "'" );
ctx.notifyEvt( astEvent(Severity.ERROR,
String.format("Function not found: '%s'", name.getText())) );
}
} else if( value instanceof UnaryTest ) {
if( params.getElements().size() == 1 ) {
Object p = params.getElements().get( 0 ).evaluate( ctx );
return ((UnaryTest) value).apply( ctx, p );
} else {
logger.error( "Can't invoke an unary test with "+params.getElements().size()+ " parameters. Unary tests require 1 single parameter." );
ctx.notifyEvt( astEvent(Severity.ERROR,
String.format("Can't invoke an unary test with %s parameters. Unary tests require 1 single parameter.", params.getElements().size()) ) );
}
}
return null;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

import org.antlr.v4.runtime.ParserRuleContext;
import org.kie.dmn.feel.lang.EvaluationContext;
import org.kie.dmn.feel.runtime.events.FEELEvent.Severity;

public class IfExpressionNode
extends BaseNode {
Expand Down Expand Up @@ -67,6 +68,7 @@ public Object evaluate(EvaluationContext ctx) {
return this.elseExpression.evaluate( ctx );
}
}
ctx.notifyEvt( astEvent(Severity.ERROR, "Condition was not a Boolean") );
return null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
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.runtime.events.FEELEvent.Severity;

public class InNode
extends BaseNode {
Expand Down Expand Up @@ -68,6 +69,7 @@ public Boolean evaluate(EvaluationContext ctx) {
return in( ctx, value, expr );
}
}
ctx.notifyEvt( astEvent(Severity.ERROR, "Expression is null") );
return null;
}

Expand All @@ -79,13 +81,15 @@ private Boolean in(EvaluationContext ctx, Object value, Object expr) {
return ((UnaryTest) expr).apply( ctx, value );
} else if ( expr instanceof Range ) {
if( !( value instanceof Comparable ) ) {
ctx.notifyEvt( astEvent(Severity.ERROR, "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, "value == null, expr != null and not Unary test, Evaluating this node as FALSE."));
return Boolean.FALSE;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

import org.antlr.v4.runtime.ParserRuleContext;
import org.kie.dmn.feel.lang.EvaluationContext;
import org.kie.dmn.feel.util.EvalHelper;

import java.math.BigDecimal;

Expand All @@ -28,7 +29,7 @@ public class NumberNode

public NumberNode(ParserRuleContext ctx) {
super( ctx );
value = new BigDecimal( ctx.getText() );
value = EvalHelper.getBigDecimalOrNull( ctx.getText() );
}

public BigDecimal getValue() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

import org.antlr.v4.runtime.ParserRuleContext;
import org.kie.dmn.feel.lang.EvaluationContext;
import org.kie.dmn.feel.runtime.events.FEELEvent.Severity;
import org.kie.dmn.feel.util.EvalHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand Down Expand Up @@ -76,7 +77,9 @@ public Object evaluate(EvaluationContext ctx) {
return fetchValue( o );
}
} catch ( Exception e ) {
logger.error( "Error evaluating path expression: " + expression.getText() + "." + name.getText(), e );
ctx.notifyEvt( astEvent(Severity.ERROR,
String.format("Error evaluating path expression: %s. %s", expression.getText(), name.getText()),
e) );
}
return null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

import org.antlr.v4.runtime.ParserRuleContext;
import org.kie.dmn.feel.lang.EvaluationContext;
import org.kie.dmn.feel.runtime.events.FEELEvent.Severity;

import java.util.*;

Expand Down Expand Up @@ -87,6 +88,7 @@ public Boolean evaluate(EvaluationContext ctx) {
if( quantifier == Quantifier.SOME || quantifier == Quantifier.EVERY ) {
return iterateContexts( ctx, iterationContexts, expression, quantifier );
}
ctx.notifyEvt( astEvent(Severity.ERROR, "Quantifier is null") );
return null;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import org.kie.dmn.feel.lang.types.BuiltInType;
import org.kie.dmn.feel.runtime.Range;
import org.kie.dmn.feel.runtime.UnaryTest;
import org.kie.dmn.feel.runtime.events.FEELEvent.Severity;
import org.kie.dmn.feel.runtime.impl.RangeImpl;

public class RangeNode
Expand Down Expand Up @@ -79,10 +80,15 @@ public void setEnd(BaseNode end) {
public Range evaluate(EvaluationContext ctx) {
Comparable s = (Comparable) start.evaluate( ctx );
Comparable e = (Comparable) end.evaluate( ctx );

if( s == null || e == null ||
( BuiltInType.determineTypeFromInstance( s ) != BuiltInType.determineTypeFromInstance( e ) &&
! s.getClass().isAssignableFrom( e.getClass() ) ) ) {

boolean problem = false;
if ( s == null ) { ctx.notifyEvt( astEvent(Severity.ERROR, "Start is null")); problem = true; }
if ( e == null ) { ctx.notifyEvt( astEvent(Severity.ERROR, "End is null")); problem = true; }
if (problem) { return null; }

if ( BuiltInType.determineTypeFromInstance( s ) != BuiltInType.determineTypeFromInstance( e )
&& !s.getClass().isAssignableFrom( e.getClass() ) ) {
ctx.notifyEvt( astEvent(Severity.ERROR, "Start and End are not of compatible types"));
return null;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

import org.antlr.v4.runtime.ParserRuleContext;
import org.kie.dmn.feel.lang.EvaluationContext;
import org.kie.dmn.feel.runtime.events.FEELEvent.Severity;
import org.kie.dmn.feel.util.EvalHelper;

import java.math.BigDecimal;
Expand Down Expand Up @@ -59,6 +60,7 @@ public BaseNode getExpression() {
public Object evaluate(EvaluationContext ctx) {
BigDecimal result = EvalHelper.getBigDecimalOrNull( expression.evaluate( ctx ) );
if ( result == null ) {
ctx.notifyEvt( astEvent(Severity.WARN, "Negating a null"));
return null;
} else if ( Sign.NEGATIVE == sign ) {
return BigDecimal.valueOf( -1 ).multiply( result );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
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.runtime.events.FEELEvent.Severity;

import java.util.List;

Expand Down Expand Up @@ -135,6 +136,7 @@ public UnaryTest evaluate(EvaluationContext ctx) {
return true;
};
}
ctx.notifyEvt( astEvent(Severity.ERROR, "Null or unknown operator"));
return null;
}
}
Loading

0 comments on commit beb5f3b

Please sign in to comment.