[jboss-svn-commits] JBL Code SVN: r12720 - in labs/jbossrules/trunk: drools-compiler/src/test/java/org/drools/integrationtests and 2 other directories.

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Wed Jun 20 15:01:06 EDT 2007


Author: tirelli
Date: 2007-06-20 15:01:06 -0400 (Wed, 20 Jun 2007)
New Revision: 12720

Added:
   labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/rule/builder/dialect/mvel/MVELAccumulateBuilder.java
   labs/jbossrules/trunk/drools-compiler/src/test/resources/org/drools/integrationtests/test_AccumulateMVEL.drl
   labs/jbossrules/trunk/drools-compiler/src/test/resources/org/drools/integrationtests/test_AccumulateModifyMVEL.drl
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/mvel/MVELAccumulator.java
Modified:
   labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/rule/builder/dialect/mvel/MVELDialect.java
   labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/FirstOrderLogicTest.java
Log:
JBRULES-925: adding support to MVEL in accumulate CE

Added: labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/rule/builder/dialect/mvel/MVELAccumulateBuilder.java
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/rule/builder/dialect/mvel/MVELAccumulateBuilder.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/rule/builder/dialect/mvel/MVELAccumulateBuilder.java	2007-06-20 19:01:06 UTC (rev 12720)
@@ -0,0 +1,116 @@
+/*
+ * Copyright 2007 JBoss Inc
+ * 
+ * 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.drools.rule.builder.dialect.mvel;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.drools.base.mvel.DroolsMVELFactory;
+import org.drools.base.mvel.MVELAccumulator;
+import org.drools.lang.descr.AccumulateDescr;
+import org.drools.lang.descr.BaseDescr;
+import org.drools.lang.descr.PatternDescr;
+import org.drools.rule.Accumulate;
+import org.drools.rule.ConditionalElement;
+import org.drools.rule.Declaration;
+import org.drools.rule.Pattern;
+import org.drools.rule.builder.AccumulateBuilder;
+import org.drools.rule.builder.ConditionalElementBuilder;
+import org.drools.rule.builder.Dialect;
+import org.drools.rule.builder.PatternBuilder;
+import org.drools.rule.builder.RuleBuildContext;
+import org.mvel.MVEL;
+
+/**
+ * A builder for the java dialect accumulate version
+ * 
+ * @author etirelli
+ */
+public class MVELAccumulateBuilder
+    implements
+    ConditionalElementBuilder,
+    AccumulateBuilder {
+
+    public ConditionalElement build(final RuleBuildContext context,
+                                    final BaseDescr descr) {
+        return build( context,
+                      descr,
+                      null );
+    }
+
+    public ConditionalElement build(final RuleBuildContext context,
+                                    final BaseDescr descr,
+                                    final Pattern prefixPattern) {
+
+        final AccumulateDescr accumDescr = (AccumulateDescr) descr;
+
+        final PatternBuilder patternBuilder = (PatternBuilder) context.getDialect().getBuilder( PatternDescr.class );
+
+        final Pattern sourcePattern = patternBuilder.build( context,
+                                                            accumDescr.getSourcePattern() );
+
+        if ( sourcePattern == null ) {
+            return null;
+        }
+
+        final Pattern resultPattern = patternBuilder.build( context,
+                                                            accumDescr.getResultPattern() );
+
+        final Dialect.AnalysisResult analysis1 = context.getDialect().analyzeBlock( context,
+                                                                                    accumDescr,
+                                                                                    accumDescr.getInitCode() );
+        final Dialect.AnalysisResult analysis2 = context.getDialect().analyzeBlock( context,
+                                                                                    accumDescr,
+                                                                                    accumDescr.getActionCode() );
+        final Dialect.AnalysisResult analysis3 = context.getDialect().analyzeExpression( context,
+                                                                                         accumDescr,
+                                                                                         accumDescr.getResultCode() );
+
+        final List requiredDeclarations = new ArrayList( analysis1.getBoundIdentifiers()[0] );
+        requiredDeclarations.addAll( analysis2.getBoundIdentifiers()[0] );
+        requiredDeclarations.addAll( analysis3.getBoundIdentifiers()[0] );
+
+        final Declaration[] declarations = new Declaration[requiredDeclarations.size()];
+        for ( int i = 0, size = requiredDeclarations.size(); i < size; i++ ) {
+            declarations[i] = context.getDeclarationResolver().getDeclaration( (String) requiredDeclarations.get( i ) );
+        }
+        final Declaration[] sourceDeclArr = (Declaration[]) sourcePattern.getOuterDeclarations().values().toArray( new Declaration[0] );
+
+        final DroolsMVELFactory factory = new DroolsMVELFactory( context.getDeclarationResolver().getDeclarations(),
+                                                                 sourcePattern.getOuterDeclarations(),
+                                                                 context.getPkg().getGlobals() );
+        factory.setNextFactory( ((MVELDialect) context.getDialect()).getClassImportResolverFactory() );
+
+        final Serializable init = MVEL.compileExpression( (String) accumDescr.getInitCode(),
+                                                          ((MVELDialect) context.getDialect()).getClassImportResolverFactory().getImportedClasses() );
+        final Serializable action = MVEL.compileExpression( (String) accumDescr.getActionCode(),
+                                                          ((MVELDialect) context.getDialect()).getClassImportResolverFactory().getImportedClasses() );
+        final Serializable result = MVEL.compileExpression( (String) accumDescr.getResultCode(),
+                                                          ((MVELDialect) context.getDialect()).getClassImportResolverFactory().getImportedClasses() );
+
+        final MVELAccumulator accumulator = new MVELAccumulator( factory, init, action, result );
+
+        final Accumulate accumulate = new Accumulate( sourcePattern,
+                                                      resultPattern,
+                                                      declarations,
+                                                      sourceDeclArr,
+                                                      accumulator );
+        return accumulate;
+    }
+
+}


Property changes on: labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/rule/builder/dialect/mvel/MVELAccumulateBuilder.java
___________________________________________________________________
Name: svn:executable
   + *

Modified: labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/rule/builder/dialect/mvel/MVELDialect.java
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/rule/builder/dialect/mvel/MVELDialect.java	2007-06-20 18:44:06 UTC (rev 12719)
+++ labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/rule/builder/dialect/mvel/MVELDialect.java	2007-06-20 19:01:06 UTC (rev 12720)
@@ -13,6 +13,7 @@
 import org.drools.compiler.PackageBuilder;
 import org.drools.compiler.PackageBuilderConfiguration;
 import org.drools.compiler.RuleError;
+import org.drools.lang.descr.AccumulateDescr;
 import org.drools.lang.descr.AndDescr;
 import org.drools.lang.descr.BaseDescr;
 import org.drools.lang.descr.EvalDescr;
@@ -49,7 +50,7 @@
 
     private final PatternBuilder                    pattern                 = new PatternBuilder();
     private final QueryBuilder                      query                   = new QueryBuilder();
-    //private final JavaAccumulateBuilder           accumulate  = new JavaAccumulateBuilder();
+    private final MVELAccumulateBuilder             accumulate              = new MVELAccumulateBuilder();
     private final SalienceBuilder                   salience                = new MVELSalienceBuilder();
     private final MVELEvalBuilder                   eval                    = new MVELEvalBuilder();
     private final MVELPredicateBuilder              predicate               = new MVELPredicateBuilder();
@@ -129,8 +130,8 @@
         this.builders.put( QueryDescr.class,
                            getQueryBuilder() );
 
-        //        this.builders.put( AccumulateDescr.class,
-        //                           getAccumulateBuilder() );
+        this.builders.put( AccumulateDescr.class,
+                           getAccumulateBuilder() );
 
         this.builders.put( EvalDescr.class,
                            getEvalBuilder() );
@@ -203,12 +204,12 @@
     }
 
     public Dialect.AnalysisResult analyzeExpression(RuleBuildContext context,
-                                           BaseDescr descr,
-                                           Object content) {
+                                                    BaseDescr descr,
+                                                    Object content) {
         Dialect.AnalysisResult result = null;
         try {
             result = this.analyzer.analyzeExpression( (String) content,
-                                                               new Set[]{context.getDeclarationResolver().getDeclarations().keySet(), context.getPkg().getGlobals().keySet()} );
+                                                      new Set[]{context.getDeclarationResolver().getDeclarations().keySet(), context.getPkg().getGlobals().keySet()} );
         } catch ( final Exception e ) {
             context.getErrors().add( new RuleError( context.getRule(),
                                                     descr,
@@ -219,12 +220,12 @@
     }
 
     public Dialect.AnalysisResult analyzeBlock(RuleBuildContext context,
-                                      BaseDescr descr,
-                                      String text) {
+                                               BaseDescr descr,
+                                               String text) {
         Dialect.AnalysisResult result = null;
         try {
             result = this.analyzer.analyzeExpression( text,
-                                                               new Set[]{context.getDeclarationResolver().getDeclarations().keySet(), context.getPkg().getGlobals().keySet()} );
+                                                      new Set[]{context.getDeclarationResolver().getDeclarations().keySet(), context.getPkg().getGlobals().keySet()} );
         } catch ( final Exception e ) {
             context.getErrors().add( new RuleError( context.getRule(),
                                                     descr,
@@ -255,7 +256,7 @@
     }
 
     public AccumulateBuilder getAccumulateBuilder() {
-        throw new UnsupportedOperationException( "MVEL does not yet support accumuate" );
+        return this.accumulate;
     }
 
     public ConsequenceBuilder getConsequenceBuilder() {

Modified: labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/FirstOrderLogicTest.java
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/FirstOrderLogicTest.java	2007-06-20 18:44:06 UTC (rev 12719)
+++ labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/FirstOrderLogicTest.java	2007-06-20 19:01:06 UTC (rev 12720)
@@ -541,4 +541,111 @@
         // load up the rulebase
         return ruleBase;
     }
+    
+    public void testMVELAccumulate() throws Exception {
+
+        // read in the source
+        final Reader reader = new InputStreamReader( getClass().getResourceAsStream( "test_AccumulateMVEL.drl" ) );
+        final RuleBase ruleBase = loadRuleBase( reader );
+
+        final WorkingMemory wm = ruleBase.newStatefulSession();
+        final List results = new ArrayList();
+
+        wm.setGlobal( "results",
+                      results );
+
+        wm.insert( new Cheese( "stilton",
+                                     10 ) );
+        wm.insert( new Cheese( "brie",
+                                     5 ) );
+        wm.insert( new Cheese( "provolone",
+                                     150 ) );
+        wm.insert( new Person( "Bob",
+                                     "stilton",
+                                     20 ) );
+        wm.insert( new Person( "Mark",
+                                     "provolone" ) );
+
+        wm.fireAllRules();
+
+        Assert.assertEquals( new Integer( 165 ),
+                             results.get( 0 ) );
+        Assert.assertEquals( new Integer( 10 ),
+                             results.get( 1 ) );
+        Assert.assertEquals( new Integer( 150 ),
+                             results.get( 2 ) );
+        Assert.assertEquals( new Integer( 10 ),
+                             results.get( 3 ) );
+        Assert.assertEquals( new Integer( 210 ),
+                             results.get( 4 ) );
+    }
+    
+    public void testAccumulateModifyMVEL() throws Exception {
+        // read in the source
+        final Reader reader = new InputStreamReader( getClass().getResourceAsStream( "test_AccumulateModifyMVEL.drl" ) );
+        final RuleBase ruleBase = loadRuleBase( reader );
+
+        final WorkingMemory wm = ruleBase.newStatefulSession();
+        final List results = new ArrayList();
+
+        wm.setGlobal( "results",
+                      results );
+
+        final Cheese[] cheese = new Cheese[]{new Cheese( "stilton",
+                                                         10 ), new Cheese( "stilton",
+                                                                           2 ), new Cheese( "stilton",
+                                                                                            5 ), new Cheese( "brie",
+                                                                                                             15 ), new Cheese( "brie",
+                                                                                                                               16 ), new Cheese( "provolone",
+                                                                                                                                                 8 )};
+        final Person bob = new Person( "Bob",
+                                       "stilton" );
+
+        final FactHandle[] cheeseHandles = new FactHandle[cheese.length];
+        for ( int i = 0; i < cheese.length; i++ ) {
+            cheeseHandles[i] = wm.insert( cheese[i] );
+        }
+        final FactHandle bobHandle = wm.insert( bob );
+
+        // ---------------- 1st scenario
+        wm.fireAllRules();
+        // no fire, as per rule constraints
+        Assert.assertEquals( 0,
+                             results.size() );
+
+        // ---------------- 2nd scenario
+        final int index = 1;
+        cheese[index].setPrice( 9 );
+        wm.update( cheeseHandles[index],
+                         cheese[index] );
+        wm.fireAllRules();
+
+        // 1 fire
+        Assert.assertEquals( 1,
+                             results.size() );
+        Assert.assertEquals( 24,
+                             ((Cheesery) results.get( results.size() - 1 )).getTotalAmount() );
+
+        // ---------------- 3rd scenario
+        bob.setLikes( "brie" );
+        wm.update( bobHandle,
+                         bob );
+        wm.fireAllRules();
+
+        // 2 fires
+        Assert.assertEquals( 2,
+                             results.size() );
+        Assert.assertEquals( 31,
+                             ((Cheesery) results.get( results.size() - 1 )).getTotalAmount() );
+
+        // ---------------- 4th scenario
+        wm.retract( cheeseHandles[3] );
+        wm.fireAllRules();
+
+        // should not have fired as per constraint
+        Assert.assertEquals( 2,
+                             results.size() );
+
+    }
+
 }

Added: labs/jbossrules/trunk/drools-compiler/src/test/resources/org/drools/integrationtests/test_AccumulateMVEL.drl
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/test/resources/org/drools/integrationtests/test_AccumulateMVEL.drl	                        (rev 0)
+++ labs/jbossrules/trunk/drools-compiler/src/test/resources/org/drools/integrationtests/test_AccumulateMVEL.drl	2007-06-20 19:01:06 UTC (rev 12720)
@@ -0,0 +1,68 @@
+package org.drools.test;
+
+import org.drools.Cheese;
+import org.drools.Person;
+import org.drools.Cheesery;
+
+global java.util.List results;
+
+rule "AccumulateTest" salience 100
+	dialect "mvel"
+    when
+    	$totalAmount : Integer() from accumulate( $cheese : Cheese( ),
+                                                  init( total = 0; ),
+    	                                          action( total = total + $cheese.price ),
+                                                  result( total ) )
+    then
+        results.add($totalAmount);
+end  
+
+rule "Accumulate with Bindings" salience 90
+	dialect "mvel"
+    when
+        $person      : Person( name == "Bob", $likes : likes )
+    	$totalAmount : Integer() from accumulate( $cheese : Cheese( type == $likes ),
+                                                  init( total = 0; ),
+    	                                          action( total = total +  $cheese.price ),
+                                                  result( total ) )
+    then
+        results.add($totalAmount);
+end  
+
+rule "Constraints everywhere" salience 80
+	dialect "mvel"
+    when
+        $person      : Person( $likes : likes )
+    	$cheesery    : Cheesery( totalAmount > 100 ) 
+    	                       from accumulate( $cheese : Cheese( type == $likes ),
+                                                init( cheesery = new Cheesery(); ),
+    	                                        action( cheesery.addCheese( $cheese ); ),
+                                                result( cheesery ) );
+    then
+        results.add(new Integer($cheesery.getTotalAmount()));
+end  
+
+rule "Source pattern binds" salience 70
+	dialect "mvel"
+    when
+        $person      : Person( name == "Bob", $likes : likes )
+    	$totalAmount : Integer() from accumulate( $cheese : Cheese( type == $likes, $price: price ),
+                                                  init( total = 0; ),
+    	                                          action( total = total + $cheese.price ),
+                                                  result( total ) );
+    then
+        results.add($totalAmount);
+end
+
+rule "Accumulate with previous Bindings" salience 60
+	dialect "mvel"
+    when
+        $person      : Person( name == "Bob", $likes : likes, $age : age )
+    	$totalAmount : Integer() from accumulate( $cheese : Cheese( type == $likes, $price : price ),
+                                                  init( total = $age * 10; ),
+   	                                              action( total = total + $price; ),
+                                                  result( total ) );
+    then
+        results.add($totalAmount);
+end  
+


Property changes on: labs/jbossrules/trunk/drools-compiler/src/test/resources/org/drools/integrationtests/test_AccumulateMVEL.drl
___________________________________________________________________
Name: svn:executable
   + *

Added: labs/jbossrules/trunk/drools-compiler/src/test/resources/org/drools/integrationtests/test_AccumulateModifyMVEL.drl
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/test/resources/org/drools/integrationtests/test_AccumulateModifyMVEL.drl	                        (rev 0)
+++ labs/jbossrules/trunk/drools-compiler/src/test/resources/org/drools/integrationtests/test_AccumulateModifyMVEL.drl	2007-06-20 19:01:06 UTC (rev 12720)
@@ -0,0 +1,20 @@
+package org.drools.test;
+
+import org.drools.Cheese;
+import org.drools.Cheesery;
+import org.drools.Person;
+
+global java.util.List results;
+
+rule "Constraints everywhere" salience 80
+    dialect "mvel"
+    when
+        $person      : Person( $likes : likes )
+    	$cheesery    : Cheesery( totalAmount > 20 ) 
+    	                       from accumulate( $cheese : Cheese( type == $likes ),
+                                                init( cheesery = new Cheesery(); ),
+    	                                        action( cheesery.addCheese( $cheese ); ),
+                                                result( cheesery ) );
+    then
+        results.add( $cheesery );
+end  


Property changes on: labs/jbossrules/trunk/drools-compiler/src/test/resources/org/drools/integrationtests/test_AccumulateModifyMVEL.drl
___________________________________________________________________
Name: svn:executable
   + *

Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/mvel/MVELAccumulator.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/mvel/MVELAccumulator.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/mvel/MVELAccumulator.java	2007-06-20 19:01:06 UTC (rev 12720)
@@ -0,0 +1,115 @@
+/*
+ * Copyright 2007 JBoss Inc
+ * 
+ * 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.
+ *
+ * Created on Jun 20, 2007
+ */
+package org.drools.base.mvel;
+
+import java.io.Serializable;
+import java.util.HashMap;
+
+import org.drools.WorkingMemory;
+import org.drools.common.InternalFactHandle;
+import org.drools.rule.Declaration;
+import org.drools.spi.Accumulator;
+import org.drools.spi.Tuple;
+import org.mvel.MVEL;
+
+/**
+ * An MVEL accumulator implementation
+ * 
+ * @author etirelli
+ */
+public class MVELAccumulator
+    implements
+    Accumulator {
+
+    private static final long       serialVersionUID = 1081306132058101176L;
+
+    private final DroolsMVELFactory factory;
+    private final Serializable      init;
+    private final Serializable      action;
+    private final Serializable      result;
+
+    public MVELAccumulator(final DroolsMVELFactory factory,
+                           final Serializable init,
+                           final Serializable action,
+                           final Serializable result) {
+        super();
+        this.factory = factory;
+        this.init = init;
+        this.action = action;
+        this.result = result;
+    }
+
+    /* (non-Javadoc)
+     * @see org.drools.spi.Accumulator#createContext()
+     */
+    public Object createContext() {
+        return new HashMap();
+    }
+
+    /* (non-Javadoc)
+     * @see org.drools.spi.Accumulator#init(java.lang.Object, org.drools.spi.Tuple, org.drools.rule.Declaration[], org.drools.WorkingMemory)
+     */
+    public void init(Object context,
+                     Tuple leftTuple,
+                     Declaration[] declarations,
+                     WorkingMemory workingMemory) throws Exception {
+        this.factory.setContext( leftTuple,
+                                 null,
+                                 null,
+                                 workingMemory );
+        MVEL.executeExpression( this.init,
+                                context,
+                                this.factory );
+    }
+
+    /* (non-Javadoc)
+     * @see org.drools.spi.Accumulator#accumulate(java.lang.Object, org.drools.spi.Tuple, org.drools.common.InternalFactHandle, org.drools.rule.Declaration[], org.drools.rule.Declaration[], org.drools.WorkingMemory)
+     */
+    public void accumulate(Object context,
+                           Tuple leftTuple,
+                           InternalFactHandle handle,
+                           Declaration[] declarations,
+                           Declaration[] innerDeclarations,
+                           WorkingMemory workingMemory) throws Exception {
+        this.factory.setContext( leftTuple,
+                                 null,
+                                 handle.getObject(),
+                                 workingMemory );
+        MVEL.executeExpression( this.action,
+                                context,
+                                this.factory );
+    }
+
+    /* (non-Javadoc)
+     * @see org.drools.spi.Accumulator#getResult(java.lang.Object, org.drools.spi.Tuple, org.drools.rule.Declaration[], org.drools.WorkingMemory)
+     */
+    public Object getResult(Object context,
+                            Tuple leftTuple,
+                            Declaration[] declarations,
+                            WorkingMemory workingMemory) throws Exception {
+        this.factory.setContext( leftTuple,
+                                 null,
+                                 null,
+                                 workingMemory );
+        final Object result = MVEL.executeExpression( this.result,
+                                                      context,
+                                                      this.factory );
+        return result;
+    }
+
+}




More information about the jboss-svn-commits mailing list