[jboss-svn-commits] JBL Code SVN: r14445 - in labs/jbossrules/trunk: drools-compiler/src/main/java/org/drools/rule/builder and 5 other directories.
jboss-svn-commits at lists.jboss.org
jboss-svn-commits at lists.jboss.org
Wed Aug 22 08:35:47 EDT 2007
Author: tirelli
Date: 2007-08-22 08:35:46 -0400 (Wed, 22 Aug 2007)
New Revision: 14445
Added:
labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/lang/MVELDumper.java
labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/lang/MVELDumperTest.java
labs/jbossrules/trunk/drools-compiler/src/test/resources/org/drools/integrationtests/test_EvalRewriteWithSpecialOperators.drl
Modified:
labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/rule/builder/PatternBuilder.java
labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/Order.java
labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/MiscTest.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/evaluators/Operator.java
Log:
JBRULES-1089: fixing eval rewrite for special operators
Added: labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/lang/MVELDumper.java
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/lang/MVELDumper.java (rev 0)
+++ labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/lang/MVELDumper.java 2007-08-22 12:35:46 UTC (rev 14445)
@@ -0,0 +1,176 @@
+package org.drools.lang;
+
+/*
+ * Author Jayaram C S
+ *
+ * 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.
+ */
+
+import java.util.Iterator;
+
+import org.drools.base.evaluators.Operator;
+import org.drools.lang.descr.FieldBindingDescr;
+import org.drools.lang.descr.FieldConstraintDescr;
+import org.drools.lang.descr.LiteralRestrictionDescr;
+import org.drools.lang.descr.PredicateDescr;
+import org.drools.lang.descr.QualifiedIdentifierRestrictionDescr;
+import org.drools.lang.descr.RestrictionConnectiveDescr;
+import org.drools.lang.descr.ReturnValueRestrictionDescr;
+import org.drools.lang.descr.VariableRestrictionDescr;
+import org.drools.spi.Evaluator;
+import org.drools.util.ReflectiveVisitor;
+
+/**
+ *
+ * @author <a href="mailto:jayaramcs at gmail.com">Author Jayaram C S</a>
+ *
+ */
+public class MVELDumper extends ReflectiveVisitor {
+
+ private StringBuffer mvelDump;
+ private static final String eol = System.getProperty( "line.separator" );
+ private String template;
+ private String fieldName;
+
+ public String dump(FieldConstraintDescr fieldConstr) {
+ mvelDump = new StringBuffer();
+ this.visit( fieldConstr );
+ return mvelDump.toString();
+ }
+
+ public void visitFieldConstraintDescr(final FieldConstraintDescr descr) {
+ if ( !descr.getRestrictions().isEmpty() ) {
+ this.fieldName = descr.getFieldName();
+ mvelDump.append( processFieldConstraint( descr.getRestriction() ) );
+ }
+ }
+
+ public void visitVariableRestrictionDescr(final VariableRestrictionDescr descr) {
+ this.template = processRestriction( descr.getEvaluator(), descr.getIdentifier() );
+ }
+
+ public void visitFieldBindingDescr(final FieldBindingDescr descr) {
+ // do nothing
+ }
+
+ public void visitLiteralRestrictionDescr(final LiteralRestrictionDescr descr) {
+ String text = descr.getText();
+ if ( text == null ) {
+ text = "null";
+ } else {
+ try {
+ Integer.parseInt( text );
+ } catch ( final NumberFormatException e ) {
+ text = "\"" + text + "\"";
+ }
+ }
+ this.template = processRestriction( descr.getEvaluator(), text );
+ }
+
+ public void visitQualifiedIdentifierRestrictionDescr(final QualifiedIdentifierRestrictionDescr descr) {
+ this.template = processRestriction( descr.getEvaluator(), descr.getText() );
+ }
+
+ public void visitRestrictionConnectiveDescr(final RestrictionConnectiveDescr descr) {
+ this.template = "( " + this.processFieldConstraint( descr ) + " )";
+ }
+
+ public void visitPredicateDescr(final PredicateDescr descr) {
+ this.template = "eval( " + descr.getContent() + " )";
+ }
+
+ public void visitReturnValueRestrictionDescr(final ReturnValueRestrictionDescr descr) {
+ this.template = processRestriction( descr.getEvaluator(), "( "+descr.getContent().toString()+" )" );
+ }
+
+ private String processFieldConstraint(final RestrictionConnectiveDescr restriction) {
+ String descrString = "";
+ String connective = null;
+
+ if ( restriction.getConnective() == RestrictionConnectiveDescr.OR ) {
+ connective = " || ";
+ } else {
+ connective = " && ";
+ }
+ for ( final Iterator it = restriction.getRestrictions().iterator(); it.hasNext(); ) {
+ final Object temp = it.next();
+ visit( temp );
+ descrString += this.template;
+ if ( it.hasNext() ) {
+ descrString += connective;
+ }
+ }
+ return descrString;
+ }
+
+ private String processRestriction(String evaluator,
+ String value) {
+ Operator op = Operator.determineOperator( evaluator );
+ if( op == Operator.MEMBEROF ) {
+ evaluator = "contains";
+ return evaluatorPrefix( evaluator ) +
+ value + " " +
+ evaluator( evaluator ) + " " +
+ this.fieldName + evaluatorSufix( evaluator );
+ } else if(op == Operator.NOTMEMBEROF) {
+ evaluator = "not contains";
+ return evaluatorPrefix( evaluator ) +
+ value + " " +
+ evaluator( evaluator ) + " " +
+ this.fieldName + evaluatorSufix( evaluator );
+ } else if(op == Operator.EXCLUDES) {
+ evaluator = "not contains";
+ return evaluatorPrefix( evaluator ) +
+ this.fieldName + " " +
+ evaluator( evaluator ) + " " +
+ value + evaluatorSufix( evaluator );
+ } else if(op == Operator.MATCHES) {
+ evaluator = "~=";
+ return evaluatorPrefix( evaluator ) +
+ this.fieldName + " " +
+ evaluator( evaluator ) + " " +
+ value + evaluatorSufix( evaluator );
+ } else if(op == Operator.NOT_MATCHES) {
+ evaluator = "not ~=";
+ return evaluatorPrefix( evaluator ) +
+ this.fieldName + " " +
+ evaluator( evaluator ) + " " +
+ value + evaluatorSufix( evaluator );
+ }
+ return evaluatorPrefix( evaluator ) +
+ this.fieldName + " " +
+ evaluator( evaluator ) + " " +
+ value + evaluatorSufix( evaluator );
+ }
+
+ private String evaluatorPrefix(String evaluator) {
+ if ( evaluator.startsWith( "not" ) ) {
+ return "!( ";
+ }
+ return "";
+ }
+
+ private String evaluator(String evaluator) {
+ if ( evaluator.startsWith( "not" ) ) {
+ return evaluator.substring( 4 );
+ }
+ return evaluator;
+ }
+
+ private String evaluatorSufix(String evaluator) {
+ if ( evaluator.startsWith( "not" ) ) {
+ return " )";
+ }
+ return "";
+ }
+}
\ No newline at end of file
Modified: labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/rule/builder/PatternBuilder.java
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/rule/builder/PatternBuilder.java 2007-08-22 11:33:27 UTC (rev 14444)
+++ labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/rule/builder/PatternBuilder.java 2007-08-22 12:35:46 UTC (rev 14445)
@@ -30,7 +30,7 @@
import org.drools.facttemplates.FactTemplate;
import org.drools.facttemplates.FactTemplateFieldExtractor;
import org.drools.facttemplates.FactTemplateObjectType;
-import org.drools.lang.DrlDumper;
+import org.drools.lang.MVELDumper;
import org.drools.lang.descr.AndDescr;
import org.drools.lang.descr.BaseDescr;
import org.drools.lang.descr.FieldBindingDescr;
@@ -78,7 +78,7 @@
public class PatternBuilder
implements
RuleConditionBuilder {
-
+
public PatternBuilder() {
}
@@ -322,9 +322,8 @@
context.setDialect( mvelDialect );
PredicateDescr predicateDescr = new PredicateDescr();
- DrlDumper dumper = new DrlDumper();
- dumper.visitFieldConstraintDescr( fieldConstraintDescr );
- predicateDescr.setContent( dumper.getTemplate() );
+ MVELDumper dumper = new MVELDumper();
+ predicateDescr.setContent( dumper.dump( fieldConstraintDescr ) );
build( context,
pattern,
@@ -804,5 +803,5 @@
return evaluator;
}
-
+
}
Modified: labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/Order.java
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/Order.java 2007-08-22 11:33:27 UTC (rev 14444)
+++ labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/Order.java 2007-08-22 12:35:46 UTC (rev 14445)
@@ -16,6 +16,7 @@
package org.drools;
+import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
@@ -27,15 +28,18 @@
private int number;
+ private String customer;
+
private Map items;
public Order() {
- this( 0 );
+ this( 0, "Bob" );
}
- public Order(final int number) {
+ public Order(final int number, String customer) {
this.number = number;
this.items = new HashMap();
+ this.customer = customer;
}
/**
@@ -56,6 +60,14 @@
return this.items;
}
+ public Collection getItemsValues() {
+ return this.items.values();
+ }
+
+ public Collection getItemsKeys() {
+ return this.items.keySet();
+ }
+
public void addItem( OrderItem item ) {
this.items.put( new Integer( item.getSeq() ), item );
}
@@ -90,4 +102,12 @@
return true;
}
+ public String getCustomer() {
+ return customer;
+ }
+
+ public void setCustomer(String customer) {
+ this.customer = customer;
+ }
+
}
Modified: labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/MiscTest.java
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/MiscTest.java 2007-08-22 11:33:27 UTC (rev 14444)
+++ labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/MiscTest.java 2007-08-22 12:35:46 UTC (rev 14445)
@@ -654,7 +654,7 @@
list.get( 0 ) );
}
- public void testJaninoEval() throws Exception {
+ public void testJaninoEval() throws Exception {
final PackageBuilderConfiguration config = new PackageBuilderConfiguration();
JavaDialectConfiguration javaConf = (JavaDialectConfiguration) config.getDialectConfiguration( "java" );
javaConf.setCompiler( JavaDialectConfiguration.JANINO );
@@ -2344,7 +2344,7 @@
workingMemory.setGlobal( "results",
results );
- final Order order = new Order( 10 );
+ final Order order = new Order( 10, "Bob" );
final OrderItem item1 = new OrderItem( order,
1 );
final OrderItem item2 = new OrderItem( order,
@@ -2949,28 +2949,28 @@
workingMemory.setGlobal( "results",
list );
- final Order order1 = new Order( 10 );
+ final Order order1 = new Order( 10, "Bob" );
final OrderItem item11 = new OrderItem( order1,
1 );
final OrderItem item12 = new OrderItem( order1,
2 );
order1.addItem( item11 );
order1.addItem( item12 );
- final Order order2 = new Order( 11 );
+ final Order order2 = new Order( 11, "Bob" );
final OrderItem item21 = new OrderItem( order2,
1 );
final OrderItem item22 = new OrderItem( order2,
2 );
order2.addItem( item21 );
order2.addItem( item22 );
- final Order order3 = new Order( 12 );
+ final Order order3 = new Order( 12, "Bob" );
final OrderItem item31 = new OrderItem( order3,
1 );
final OrderItem item32 = new OrderItem( order3,
2 );
order3.addItem( item31 );
order3.addItem( item32 );
- final Order order4 = new Order( 13 );
+ final Order order4 = new Order( 13, "Bob" );
final OrderItem item41 = new OrderItem( order4,
1 );
final OrderItem item42 = new OrderItem( order4,
@@ -3734,6 +3734,85 @@
events.next() );
}
+ // The following test is waiting for MVEL bugfixes reported in:
+ //
+ // http://jira.codehaus.org/browse/MVEL-29
+ // http://jira.codehaus.org/browse/MVEL-30
+ public void FIXME_testEvalRewriteWithSpecialOperators() throws Exception {
+ final PackageBuilder builder = new PackageBuilder();
+ builder.addPackageFromDrl( new InputStreamReader( getClass().getResourceAsStream( "test_EvalRewriteWithSpecialOperators.drl" ) ) );
+ final Package pkg = builder.getPackage();
+
+ final RuleBase ruleBase = getRuleBase();
+ ruleBase.addPackage( pkg );
+ final WorkingMemory workingMemory = ruleBase.newStatefulSession();
+
+ final List list = new ArrayList();
+ workingMemory.setGlobal( "results",
+ list );
+
+ final Order order1 = new Order( 10, "Bob" );
+ final OrderItem item11 = new OrderItem( order1, 1 );
+ final OrderItem item12 = new OrderItem( order1, 2 );
+ order1.addItem( item11 );
+ order1.addItem( item12 );
+ final Order order2 = new Order( 11, "Bob" );
+ final OrderItem item21 = new OrderItem( order2, 1 );
+ final OrderItem item22 = new OrderItem( order2, 2 );
+ order2.addItem( item21 );
+ order2.addItem( item22 );
+ final Order order3 = new Order( 12, "Bob" );
+ final OrderItem item31 = new OrderItem( order3, 1 );
+ final OrderItem item32 = new OrderItem( order3, 2 );
+ final OrderItem item33 = new OrderItem( order3, 3 );
+ order3.addItem( item31 );
+ order3.addItem( item32 );
+ order3.addItem( item33 );
+ final Order order4 = new Order( 13, "Bob" );
+ final OrderItem item41 = new OrderItem( order4, 1 );
+ final OrderItem item42 = new OrderItem( order4, 2 );
+ order4.addItem( item41 );
+ order4.addItem( item42 );
+ final Order order5 = new Order( 14, "Mark" );
+ final OrderItem item51 = new OrderItem( order5, 1 );
+ final OrderItem item52 = new OrderItem( order5, 2 );
+ order5.addItem( item51 );
+ order5.addItem( item52 );
+ workingMemory.insert( order1 );
+ workingMemory.insert( item11 );
+ workingMemory.insert( item12 );
+ workingMemory.insert( order2 );
+ workingMemory.insert( item21 );
+ workingMemory.insert( item22 );
+ workingMemory.insert( order3 );
+ workingMemory.insert( item31 );
+ workingMemory.insert( item32 );
+ workingMemory.insert( item33 );
+ workingMemory.insert( order4 );
+ workingMemory.insert( item41 );
+ workingMemory.insert( item42 );
+ workingMemory.insert( order5 );
+ workingMemory.insert( item51 );
+ workingMemory.insert( item52 );
+
+ workingMemory.fireAllRules();
+
+ assertEquals( 9,
+ list.size() );
+ int index=0;
+ assertEquals( item11, list.get( index++ ) );
+ assertEquals( item12, list.get( index++ ) );
+ assertEquals( item21, list.get( index++ ) );
+ assertEquals( item22, list.get( index++ ) );
+ assertEquals( item31, list.get( index++ ) );
+ assertEquals( item33, list.get( index++ ) );
+ assertEquals( item41, list.get( index++ ) );
+ assertEquals( order5, list.get( index++ ) );
+ assertEquals( order5, list.get( index++ ) );
+
+
+ }
+
public void testImportColision() throws Exception {
final PackageBuilder builder = new PackageBuilder();
Added: labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/lang/MVELDumperTest.java
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/lang/MVELDumperTest.java (rev 0)
+++ labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/lang/MVELDumperTest.java 2007-08-22 12:35:46 UTC (rev 14445)
@@ -0,0 +1,62 @@
+package org.drools.lang;
+
+import junit.framework.TestCase;
+
+import org.antlr.runtime.ANTLRStringStream;
+import org.antlr.runtime.CharStream;
+import org.antlr.runtime.CommonTokenStream;
+import org.antlr.runtime.Lexer;
+import org.antlr.runtime.TokenStream;
+import org.drools.lang.descr.AndDescr;
+import org.drools.lang.descr.FieldConstraintDescr;
+import org.drools.lang.descr.PatternDescr;
+
+public class MVELDumperTest extends TestCase {
+
+ private MVELDumper dumper;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ dumper = new MVELDumper();
+ }
+
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+ public void testDump() throws Exception {
+ String input = "Cheese( price > 10 && < 20 || == $val || == 30 )";
+ String expected = "( ( price > 10 && price < 20 ) || price == $val || price == 30 )" ;
+ DRLParser parser = parse( input );
+ PatternDescr pattern = (PatternDescr) parser.fact( null );
+
+ FieldConstraintDescr fieldDescr = (FieldConstraintDescr) pattern.getConstraint().getDescrs().get( 0 );
+ String result = dumper.dump( fieldDescr );
+
+ assertEquals( expected, result );
+ }
+
+
+ private DRLParser parse(final String text) throws Exception {
+ return newParser( newTokenStream( newLexer( newCharStream( text ) ) ) );
+ }
+
+ private CharStream newCharStream(final String text) {
+ return new ANTLRStringStream( text );
+ }
+
+ private DRLLexer newLexer(final CharStream charStream) {
+ return new DRLLexer( charStream );
+ }
+
+ private TokenStream newTokenStream(final Lexer lexer) {
+ return new CommonTokenStream( lexer );
+ }
+
+ private DRLParser newParser(final TokenStream tokenStream) {
+ final DRLParser p = new DRLParser( tokenStream );
+ //p.setParserDebug( true );
+ return p;
+ }
+
+}
Added: labs/jbossrules/trunk/drools-compiler/src/test/resources/org/drools/integrationtests/test_EvalRewriteWithSpecialOperators.drl
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/test/resources/org/drools/integrationtests/test_EvalRewriteWithSpecialOperators.drl (rev 0)
+++ labs/jbossrules/trunk/drools-compiler/src/test/resources/org/drools/integrationtests/test_EvalRewriteWithSpecialOperators.drl 2007-08-22 12:35:46 UTC (rev 14445)
@@ -0,0 +1,88 @@
+package org.drools;
+
+global java.util.List results;
+
+// [not] in
+// [not] contains
+// [not] memberOf
+// excludes
+// [not] matches
+
+rule "eval rewrite with 'in'"
+ salience 100
+ when
+ Order( $id : number == 10 )
+ $o : OrderItem( order.number in ( 1, (1+1), $id ), seq == 1 )
+ then
+ results.add( $o );
+end
+
+rule "eval rewrite with 'not in'"
+ salience 90
+ when
+ Order( $id : number == 10 )
+ $o : OrderItem( order.number not in ( 1, (1+1), ( $id + 1 ) ), order.number == $id, seq == 2 )
+ then
+ results.add( $o );
+end
+
+rule "eval rewrite with 'contains'"
+ salience 80
+ when
+ $o : OrderItem( order.number == 11, seq == 1 )
+ Order( this.itemsValues contains $o )
+ then
+ results.add( $o );
+end
+
+rule "eval rewrite with 'not contains'"
+ salience 70
+ when
+ $o : OrderItem( order.number == 11, seq == 2 )
+ Order( number == 12, this.itemsValues not contains $o )
+ then
+ results.add( $o );
+end
+
+rule "eval rewrite with 'memberOf'"
+ salience 60
+ when
+ $order : Order( number == 12 )
+ $o : OrderItem( seq == 1, order.number==12, this.seq memberOf $order.itemsKeys )
+ then
+ results.add( $o );
+end
+
+rule "eval rewrite with 'not memberOf'"
+ salience 50
+ when
+ $order : Order( number == 11 )
+ $o : OrderItem( seq == 3, order.number==12, this.seq not memberOf $order.itemsKeys )
+ then
+ results.add( $o );
+end
+
+rule "eval rewrite with 'excludes'"
+ salience 30
+ when
+ $o : OrderItem( order.number == 13, seq == 1 )
+ Order( number == 12, this.itemsValues excludes $o )
+ then
+ results.add( $o );
+end
+
+rule "eval rewrite with 'matches'"
+ salience 20
+ when
+ $o : Order( number == 14, this.customer matches "Mark" )
+ then
+ results.add( $o );
+end
+
+rule "eval rewrite with 'not matches'"
+ salience 10
+ when
+ $o : Order( number == 14, this.customer not matches "Bob" )
+ then
+ results.add( $o );
+end
Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/evaluators/Operator.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/evaluators/Operator.java 2007-08-22 11:33:27 UTC (rev 14444)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/evaluators/Operator.java 2007-08-22 12:35:46 UTC (rev 14445)
@@ -68,6 +68,10 @@
public String toString() {
return "Operator = '" + this.operator + "'";
}
+
+ public String getOperatorString() {
+ return this.operator;
+ }
public int hashCode() {
return this.operator.hashCode();
More information about the jboss-svn-commits
mailing list