[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