[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