[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