[jboss-svn-commits] JBL Code SVN: r24898 - in labs/jbossrules/trunk: drools-compiler/src/main/resources/META-INF and 3 other directories.

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Fri Jan 23 13:32:55 EST 2009


Author: tirelli
Date: 2009-01-23 13:32:55 -0500 (Fri, 23 Jan 2009)
New Revision: 24898

Added:
   labs/jbossrules/trunk/drools-compiler/src/test/resources/org/drools/integrationtests/test_AccumulateCollectList.drl
   labs/jbossrules/trunk/drools-compiler/src/test/resources/org/drools/integrationtests/test_AccumulateCollectListMVEL.drl
   labs/jbossrules/trunk/drools-compiler/src/test/resources/org/drools/integrationtests/test_AccumulateCollectSet.drl
   labs/jbossrules/trunk/drools-compiler/src/test/resources/org/drools/integrationtests/test_AccumulateCollectSetMVEL.drl
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/accumulators/CollectListAccumulateFunction.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/accumulators/CollectSetAccumulateFunction.java
Modified:
   labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/compiler/PackageBuilderConfiguration.java
   labs/jbossrules/trunk/drools-compiler/src/main/resources/META-INF/drools.default.packagebuilder.conf
   labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/AccumulateTest.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/accumulators/AccumulateFunction.java
Log:
JBRULES-1933: adding collectList and collectSet accumulate functions

Modified: labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/compiler/PackageBuilderConfiguration.java
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/compiler/PackageBuilderConfiguration.java	2009-01-23 18:30:15 UTC (rev 24897)
+++ labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/compiler/PackageBuilderConfiguration.java	2009-01-23 18:32:55 UTC (rev 24898)
@@ -473,18 +473,19 @@
     }
 
     public void addAccumulateFunction(String identifier,
-                                      Class clazz) {
+                                      Class<? extends AccumulateFunction> clazz) {
         this.accumulateFunctions.put( identifier,
                                       clazz.getName() );
     }
 
+    @SuppressWarnings("unchecked")
     public AccumulateFunction getAccumulateFunction(String identifier) {
         String className = this.accumulateFunctions.get( identifier );
         if ( className == null ) {
             throw new RuntimeDroolsException( "No accumulator function found for identifier: " + identifier );
         }
         try {
-            Class clazz = this.classLoader.loadClass( className );
+            Class<? extends AccumulateFunction> clazz = (Class<? extends AccumulateFunction>)this.classLoader.loadClass( className );
             return (AccumulateFunction) clazz.newInstance();
         } catch ( ClassNotFoundException e ) {
             throw new RuntimeDroolsException( "Error loading accumulator function for identifier " + identifier + ". Class " + className + " not found",

Modified: labs/jbossrules/trunk/drools-compiler/src/main/resources/META-INF/drools.default.packagebuilder.conf
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/main/resources/META-INF/drools.default.packagebuilder.conf	2009-01-23 18:30:15 UTC (rev 24897)
+++ labs/jbossrules/trunk/drools-compiler/src/main/resources/META-INF/drools.default.packagebuilder.conf	2009-01-23 18:32:55 UTC (rev 24898)
@@ -11,6 +11,8 @@
 drools.accumulate.function.min = org.drools.base.accumulators.MinAccumulateFunction
 drools.accumulate.function.count = org.drools.base.accumulators.CountAccumulateFunction
 drools.accumulate.function.sum = org.drools.base.accumulators.SumAccumulateFunction
+drools.accumulate.function.collectList = org.drools.base.accumulators.CollectListAccumulateFunction
+drools.accumulate.function.collectSet = org.drools.base.accumulators.CollectSetAccumulateFunction
 
 drools.evaluator.coincides = org.drools.base.evaluators.CoincidesEvaluatorDefinition
 drools.evaluator.before = org.drools.base.evaluators.BeforeEvaluatorDefinition

Modified: labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/AccumulateTest.java
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/AccumulateTest.java	2009-01-23 18:30:15 UTC (rev 24897)
+++ labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/AccumulateTest.java	2009-01-23 18:32:55 UTC (rev 24898)
@@ -6,6 +6,7 @@
 import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Set;
 
 import junit.framework.Assert;
 import junit.framework.TestCase;
@@ -836,6 +837,22 @@
         execTestAccumulateReverseModifyMultiPattern( "test_AccumulateMultiPatternMVEL.drl" );
     }
 
+    public void testAccumulateCollectListJava() throws Exception {
+        execTestAccumulateCollectList( "test_AccumulateCollectList.drl" );
+    }
+
+    public void testAccumulateCollectListMVEL() throws Exception {
+        execTestAccumulateCollectList( "test_AccumulateCollectListMVEL.drl" );
+    }
+
+    public void testAccumulateCollectSetJava() throws Exception {
+        execTestAccumulateCollectSet( "test_AccumulateCollectSet.drl" );
+    }
+
+    public void testAccumulateCollectSetMVEL() throws Exception {
+        execTestAccumulateCollectSet( "test_AccumulateCollectSetMVEL.drl" );
+    }
+
     public void execTestAccumulateSum(String fileName) throws Exception {
         // read in the source
         final Reader reader = new InputStreamReader( getClass().getResourceAsStream( fileName ) );
@@ -1210,6 +1227,123 @@
 
     }
 
+    public void execTestAccumulateCollectList(String fileName) throws Exception {
+        // read in the source
+        final Reader reader = new InputStreamReader( getClass().getResourceAsStream( fileName ) );
+        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",
+                                                         4 ), new Cheese( "stilton",
+                                                                          2 ), new Cheese( "stilton",
+                                                                                           3 ), new Cheese( "brie",
+                                                                                                            15 ), new Cheese( "brie",
+                                                                                                                              17 ), new Cheese( "provolone",
+                                                                                                                                                8 )};
+        final FactHandle[] cheeseHandles = new FactHandle[cheese.length];
+        for ( int i = 0; i < cheese.length; i++ ) {
+            cheeseHandles[i] = wm.insert( cheese[i] );
+        }
+
+        // ---------------- 1st scenario
+        wm.fireAllRules();
+        Assert.assertEquals( 1,
+                             results.size() );
+        Assert.assertEquals( 6,
+                             ((List) results.get( results.size() - 1 )).size() );
+
+        // ---------------- 2nd scenario
+        final int index = 1;
+        cheese[index].setPrice( 9 );
+        wm.update( cheeseHandles[index],
+                   cheese[index] );
+        wm.fireAllRules();
+
+        // fire again
+        Assert.assertEquals( 2,
+                             results.size() );
+        Assert.assertEquals( 6,
+                             ((List) results.get( results.size() - 1 )).size() );
+
+        // ---------------- 3rd scenario
+        wm.retract( cheeseHandles[3] );
+        wm.retract( cheeseHandles[4] );
+        wm.fireAllRules();
+
+        // should not have fired as per constraint
+        Assert.assertEquals( 2,
+                             results.size() );
+
+    }
+
+    public void execTestAccumulateCollectSet(String fileName) throws Exception {
+        // read in the source
+        final Reader reader = new InputStreamReader( getClass().getResourceAsStream( fileName ) );
+        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",
+                                                         4 ), new Cheese( "stilton",
+                                                                          2 ), new Cheese( "stilton",
+                                                                                           3 ), new Cheese( "brie",
+                                                                                                            15 ), new Cheese( "brie",
+                                                                                                                              17 ), new Cheese( "provolone",
+                                                                                                                                                8 )};
+        final FactHandle[] cheeseHandles = new FactHandle[cheese.length];
+        for ( int i = 0; i < cheese.length; i++ ) {
+            cheeseHandles[i] = wm.insert( cheese[i] );
+        }
+
+        // ---------------- 1st scenario
+        wm.fireAllRules();
+        Assert.assertEquals( 1,
+                             results.size() );
+        Assert.assertEquals( 3,
+                             ((Set) results.get( results.size() - 1 )).size() );
+
+        // ---------------- 2nd scenario
+        final int index = 1;
+        cheese[index].setPrice( 9 );
+        wm.update( cheeseHandles[index],
+                   cheese[index] );
+        wm.fireAllRules();
+
+        // fire again
+        Assert.assertEquals( 2,
+                             results.size() );
+        Assert.assertEquals( 3,
+                             ((Set) results.get( results.size() - 1 )).size() );
+
+        // ---------------- 3rd scenario
+        wm.retract( cheeseHandles[3] );
+        wm.fireAllRules();
+        // fire again
+        Assert.assertEquals( 3,
+                             results.size() );
+        Assert.assertEquals( 3,
+                             ((Set) results.get( results.size() - 1 )).size() );
+
+
+        // ---------------- 4rd scenario
+        wm.retract( cheeseHandles[4] );
+        wm.fireAllRules();
+
+        // should not have fired as per constraint
+        Assert.assertEquals( 3,
+                             results.size() );
+
+    }
+
     public void execTestAccumulateReverseModifyMultiPattern(String fileName) throws Exception {
         // read in the source
         final Reader reader = new InputStreamReader( getClass().getResourceAsStream( fileName ) );

Added: labs/jbossrules/trunk/drools-compiler/src/test/resources/org/drools/integrationtests/test_AccumulateCollectList.drl
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/test/resources/org/drools/integrationtests/test_AccumulateCollectList.drl	                        (rev 0)
+++ labs/jbossrules/trunk/drools-compiler/src/test/resources/org/drools/integrationtests/test_AccumulateCollectList.drl	2009-01-23 18:32:55 UTC (rev 24898)
@@ -0,0 +1,15 @@
+package org.drools.test;
+
+import org.drools.Cheese;
+import java.util.List;
+
+global List results;
+
+rule "External Function" salience 80
+    when
+    	$list : List( size >= 5 ) 
+    	        from accumulate( Cheese( $type : type ),
+                                 collectList( $type ) );
+    then
+        results.add( $list );
+end  

Added: labs/jbossrules/trunk/drools-compiler/src/test/resources/org/drools/integrationtests/test_AccumulateCollectListMVEL.drl
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/test/resources/org/drools/integrationtests/test_AccumulateCollectListMVEL.drl	                        (rev 0)
+++ labs/jbossrules/trunk/drools-compiler/src/test/resources/org/drools/integrationtests/test_AccumulateCollectListMVEL.drl	2009-01-23 18:32:55 UTC (rev 24898)
@@ -0,0 +1,16 @@
+package org.drools.test;
+
+import org.drools.Cheese;
+import java.util.List;
+
+global List results;
+
+rule "External Function" salience 80
+    dialect "mvel"
+    when
+    	$list : List( size >= 5 ) 
+    	        from accumulate( Cheese( $type : type ),
+                                 collectList( $type ) );
+    then
+        results.add( $list );
+end  

Added: labs/jbossrules/trunk/drools-compiler/src/test/resources/org/drools/integrationtests/test_AccumulateCollectSet.drl
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/test/resources/org/drools/integrationtests/test_AccumulateCollectSet.drl	                        (rev 0)
+++ labs/jbossrules/trunk/drools-compiler/src/test/resources/org/drools/integrationtests/test_AccumulateCollectSet.drl	2009-01-23 18:32:55 UTC (rev 24898)
@@ -0,0 +1,16 @@
+package org.drools.test;
+
+import org.drools.Cheese;
+import java.util.List;
+import java.util.Set;
+
+global List results;
+
+rule "External Function" salience 80
+    when
+    	$set  : Set( size >= 3 ) 
+    	        from accumulate( Cheese( $type : type ),
+                                 collectSet( $type ) );
+    then
+        results.add( $set );
+end  

Added: labs/jbossrules/trunk/drools-compiler/src/test/resources/org/drools/integrationtests/test_AccumulateCollectSetMVEL.drl
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/test/resources/org/drools/integrationtests/test_AccumulateCollectSetMVEL.drl	                        (rev 0)
+++ labs/jbossrules/trunk/drools-compiler/src/test/resources/org/drools/integrationtests/test_AccumulateCollectSetMVEL.drl	2009-01-23 18:32:55 UTC (rev 24898)
@@ -0,0 +1,17 @@
+package org.drools.test;
+
+import org.drools.Cheese;
+import java.util.List;
+import java.util.Set;
+
+global List results;
+
+rule "External Function" salience 80
+    dialect "mvel"
+    when
+    	$set  : Set( size >= 3 ) 
+    	        from accumulate( Cheese( $type : type ),
+                                 collectSet( $type ) );
+    then
+        results.add( $set );
+end  

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/accumulators/AccumulateFunction.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/accumulators/AccumulateFunction.java	2009-01-23 18:30:15 UTC (rev 24897)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/accumulators/AccumulateFunction.java	2009-01-23 18:32:55 UTC (rev 24898)
@@ -18,7 +18,6 @@
 package org.drools.base.accumulators;
 
 import java.io.Externalizable;
-import java.io.Serializable;
 
 /**
  * An interface for accumulate external function implementations

Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/accumulators/CollectListAccumulateFunction.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/accumulators/CollectListAccumulateFunction.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/accumulators/CollectListAccumulateFunction.java	2009-01-23 18:32:55 UTC (rev 24898)
@@ -0,0 +1,133 @@
+/*
+ * 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 21, 2007
+ */
+package org.drools.base.accumulators;
+
+import java.io.Externalizable;
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * <p>An implementation of an accumulator capable of collecting lists of values.
+ * This is similar to the "collect" CE, but allows us to collect any value, not
+ * only facts.</p>
+ * 
+ * <p>Example:</p>
+ * <pre>
+ * rule "List employee names"
+ * when
+ *     $names : List() from accumulate(
+ *             Employee( $n : firstName, $l : lastName ),
+ *             collectList( $n + " " + $l ) )
+ * then
+ *     // do something
+ * end
+ * </pre>
+ * 
+ * <p>The list accepts duplications and the order of the elements in the list is not
+ * guaranteed.</p>
+ *
+ * @author etirelli
+ *
+ */
+public class CollectListAccumulateFunction
+    implements
+    AccumulateFunction {
+
+    public void readExternal(ObjectInput in) throws IOException,
+                                            ClassNotFoundException {
+        // functions are stateless, so nothing to serialize
+    }
+
+    public void writeExternal(ObjectOutput out) throws IOException {
+        // functions are stateless, so nothing to serialize
+    }
+
+    public static class CollectListData
+        implements
+        Externalizable {
+        public List< Object > list = new ArrayList<Object>();
+
+        public CollectListData() {
+        }
+
+        @SuppressWarnings("unchecked")
+        public void readExternal(ObjectInput in) throws IOException,
+                                                ClassNotFoundException {
+            list = (List< Object >) in.readObject();
+        }
+
+        public void writeExternal(ObjectOutput out) throws IOException {
+            out.writeObject( list );
+        }
+
+    }
+
+    /* (non-Javadoc)
+     * @see org.drools.base.accumulators.AccumulateFunction#createContext()
+     */
+    public Serializable createContext() {
+        return new CollectListData();
+    }
+
+    /* (non-Javadoc)
+     * @see org.drools.base.accumulators.AccumulateFunction#init(java.lang.Object)
+     */
+    public void init(Serializable context) throws Exception {
+        CollectListData data = (CollectListData) context;
+        data.list.clear();
+    }
+
+    /* (non-Javadoc)
+     * @see org.drools.base.accumulators.AccumulateFunction#accumulate(java.lang.Object, java.lang.Object)
+     */
+    public void accumulate(Serializable context,
+                           Object value) {
+        CollectListData data = (CollectListData) context;
+        data.list.add( value );
+    }
+
+    /* (non-Javadoc)
+     * @see org.drools.base.accumulators.AccumulateFunction#reverse(java.lang.Object, java.lang.Object)
+     */
+    public void reverse(Serializable context,
+                        Object value) throws Exception {
+        CollectListData data = (CollectListData) context;
+        data.list.remove( value );
+    }
+
+    /* (non-Javadoc)
+     * @see org.drools.base.accumulators.AccumulateFunction#getResult(java.lang.Object)
+     */
+    public Object getResult(Serializable context) throws Exception {
+        CollectListData data = (CollectListData) context;
+        return Collections.unmodifiableList( data.list );
+    }
+
+    /* (non-Javadoc)
+     * @see org.drools.base.accumulators.AccumulateFunction#supportsReverse()
+     */
+    public boolean supportsReverse() {
+        return true;
+    }
+
+}

Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/accumulators/CollectSetAccumulateFunction.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/accumulators/CollectSetAccumulateFunction.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/accumulators/CollectSetAccumulateFunction.java	2009-01-23 18:32:55 UTC (rev 24898)
@@ -0,0 +1,146 @@
+/*
+ * 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 21, 2007
+ */
+package org.drools.base.accumulators;
+
+import java.io.Externalizable;
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.io.Serializable;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * <p>An implementation of an accumulator capable of collecting sets of values.
+ * This is similar to the "collect" CE, but allows us to collect any value, not
+ * only facts.</p>
+ * 
+ * <p>Example:</p>
+ * <pre>
+ * rule "Set of unique employee names"
+ * when
+ *     $names : Set() from accumulate(
+ *             Employee( $n : firstName, $l : lastName ),
+ *             collectSet( $n + " " + $l ) )
+ * then
+ *     // do something
+ * end
+ * </pre>
+ * 
+ * <p>The set obviously does not computes duplications and the order of the elements in the set is not
+ * guaranteed.</p>
+ *
+ * @author etirelli
+ *
+ */
+public class CollectSetAccumulateFunction
+    implements
+    AccumulateFunction {
+
+    public void readExternal(ObjectInput in) throws IOException,
+                                            ClassNotFoundException {
+        // functions are stateless, so nothing to serialize
+    }
+
+    public void writeExternal(ObjectOutput out) throws IOException {
+        // functions are stateless, so nothing to serialize
+    }
+
+    public static class CollectListData
+        implements
+        Externalizable {
+        public Map< Object, MutableInt > map = new HashMap<Object, MutableInt>();
+
+        public CollectListData() {
+        }
+
+        @SuppressWarnings("unchecked")
+        public void readExternal(ObjectInput in) throws IOException,
+                                                ClassNotFoundException {
+            map = (Map< Object, MutableInt >) in.readObject();
+        }
+
+        public void writeExternal(ObjectOutput out) throws IOException {
+            out.writeObject( map );
+        }
+        
+        public static class MutableInt implements Serializable {
+            private static final long serialVersionUID = 6106891423456113914L;
+            public int value = 0;
+        }
+
+    }
+
+    /* (non-Javadoc)
+     * @see org.drools.base.accumulators.AccumulateFunction#createContext()
+     */
+    public Serializable createContext() {
+        return new CollectListData();
+    }
+
+    /* (non-Javadoc)
+     * @see org.drools.base.accumulators.AccumulateFunction#init(java.lang.Object)
+     */
+    public void init(Serializable context) throws Exception {
+        CollectListData data = (CollectListData) context;
+        data.map.clear();
+    }
+
+    /* (non-Javadoc)
+     * @see org.drools.base.accumulators.AccumulateFunction#accumulate(java.lang.Object, java.lang.Object)
+     */
+    public void accumulate(Serializable context,
+                           Object value) {
+        CollectListData data = (CollectListData) context;
+        CollectListData.MutableInt counter = data.map.get( value );
+        if( counter == null ) {
+            counter = new CollectListData.MutableInt();
+            data.map.put( value, counter );
+        }
+        counter.value++;
+    }
+
+    /* (non-Javadoc)
+     * @see org.drools.base.accumulators.AccumulateFunction#reverse(java.lang.Object, java.lang.Object)
+     */
+    public void reverse(Serializable context,
+                        Object value) throws Exception {
+        CollectListData data = (CollectListData) context;
+        CollectListData.MutableInt counter = data.map.get( value );
+        if( (--counter.value) == 0 ) {
+            data.map.remove( value );
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see org.drools.base.accumulators.AccumulateFunction#getResult(java.lang.Object)
+     */
+    public Object getResult(Serializable context) throws Exception {
+        CollectListData data = (CollectListData) context;
+        return Collections.unmodifiableSet( data.map.keySet() );
+    }
+
+    /* (non-Javadoc)
+     * @see org.drools.base.accumulators.AccumulateFunction#supportsReverse()
+     */
+    public boolean supportsReverse() {
+        return true;
+    }
+
+}




More information about the jboss-svn-commits mailing list