[jboss-svn-commits] JBL Code SVN: r17494 - in labs/jbossrules/trunk/drools-compiler/src: main/java/org/drools/process/builder and 1 other directories.
jboss-svn-commits at lists.jboss.org
jboss-svn-commits at lists.jboss.org
Wed Jan 2 09:37:31 EST 2008
Author: mark.proctor at jboss.com
Date: 2008-01-02 09:37:31 -0500 (Wed, 02 Jan 2008)
New Revision: 17494
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/ProcessBuilder.java
labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/process/builder/ProcessNodeBuilderRegistry.java
labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/MiscTest.java
Log:
JBRULES-1394 RuleFlow Nodes should be pluggable
-PackageBuilder node builders are now pluggable and discoverable
-tweaks to node instance factory tests.
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 2008-01-02 14:33:16 UTC (rev 17493)
+++ labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/compiler/PackageBuilderConfiguration.java 2008-01-02 14:37:31 UTC (rev 17494)
@@ -24,10 +24,16 @@
import java.util.Properties;
import java.util.Map.Entry;
+import org.drools.RuleBaseConfiguration;
import org.drools.RuntimeDroolsException;
import org.drools.base.accumulators.AccumulateFunction;
import org.drools.base.evaluators.EvaluatorDefinition;
import org.drools.base.evaluators.EvaluatorRegistry;
+import org.drools.process.builder.ProcessNodeBuilder;
+import org.drools.process.builder.ProcessNodeBuilderRegistry;
+import org.drools.ruleflow.core.Node;
+import org.drools.ruleflow.instance.impl.ProcessNodeInstanceFactory;
+import org.drools.ruleflow.instance.impl.ProcessNodeInstanceFactoryRegistry;
import org.drools.util.ChainedProperties;
import org.drools.util.ClassUtils;
import org.drools.util.ConfFileUtils;
@@ -37,6 +43,7 @@
import org.drools.xml.RulesSemanticModule;
import org.drools.xml.SemanticModule;
import org.drools.xml.SemanticModules;
+import org.mvel.MVEL;
/**
* This class configures the package compiler.
@@ -61,24 +68,26 @@
*/
public class PackageBuilderConfiguration {
- private static final String ACCUMULATE_FUNCTION_PREFIX = "drools.accumulate.function.";
+ private static final String ACCUMULATE_FUNCTION_PREFIX = "drools.accumulate.function.";
- private static final String EVALUATOR_DEFINITION_PREFIX = "drools.evaluator.";
-
- private Map dialectConfigurations;
+ private static final String EVALUATOR_DEFINITION_PREFIX = "drools.evaluator.";
- private String defaultDialect;
+ private Map dialectConfigurations;
- private ClassLoader classLoader;
+ private String defaultDialect;
- private ChainedProperties chainedProperties;
+ private ClassLoader classLoader;
- private Map<String, String> accumulateFunctions;
-
- private EvaluatorRegistry evaluatorRegistry;
-
- private SemanticModules semanticModules;
+ private ChainedProperties chainedProperties;
+ private Map<String, String> accumulateFunctions;
+
+ private EvaluatorRegistry evaluatorRegistry;
+
+ private SemanticModules semanticModules;
+
+ private ProcessNodeBuilderRegistry nodeBuilderRegistry = new ProcessNodeBuilderRegistry();
+
/**
* Constructor that sets the parent class loader for the package being built/compiled
* @param classLoader
@@ -135,7 +144,7 @@
buildDialectConfigurationMap();
buildAccumulateFunctionsMap();
-
+
buildEvaluatorRegistry();
}
@@ -238,10 +247,10 @@
public void initSemanticModules() {
this.semanticModules = new SemanticModules();
-
+
this.semanticModules.addSemanticModule( new ProcessSemanticModule() );
this.semanticModules.addSemanticModule( new RulesSemanticModule() );
-
+
// split on each space
String locations[] = this.chainedProperties.getProperty( "semanticModules",
"" ).split( "\\s" );
@@ -259,25 +268,27 @@
moduleLocation.length() - 1 );
}
if ( !moduleLocation.equals( "" ) ) {
- loadSemanticModule( moduleLocation );
+ loadSemanticModule( moduleLocation );
}
}
}
public void loadSemanticModule(String moduleLocation) {
- URL url = ConfFileUtils.getURL( moduleLocation, this.classLoader , getClass() );
+ URL url = ConfFileUtils.getURL( moduleLocation,
+ this.classLoader,
+ getClass() );
if ( url == null ) {
throw new IllegalArgumentException( moduleLocation + " is specified but cannot be found.'" );
- }
-
- Properties properties = ConfFileUtils.getProperties( url );
+ }
+
+ Properties properties = ConfFileUtils.getProperties( url );
if ( properties == null ) {
throw new IllegalArgumentException( moduleLocation + " is specified but cannot be found.'" );
}
loadSemanticModule( properties );
}
-
+
public void loadSemanticModule(Properties properties) {
String uri = properties.getProperty( "uri",
null );
@@ -289,12 +300,12 @@
for ( Entry<Object, Object> entry : properties.entrySet() ) {
String elementName = (String) entry.getKey();
-
+
//uri is processed above, so skip
if ( "uri".equals( elementName ) ) {
continue;
}
-
+
if ( elementName == null || elementName.trim().equals( "" ) ) {
throw new RuntimeException( "Element name must be specified for Semantic Module handler" );
}
@@ -303,7 +314,8 @@
throw new RuntimeException( "Handler name must be specified for Semantic Module" );
}
- Handler handler = ( Handler ) ClassUtils.instantiateObject( handlerName, this.classLoader );
+ Handler handler = (Handler) ClassUtils.instantiateObject( handlerName,
+ this.classLoader );
if ( handler == null ) {
throw new RuntimeException( "Unable to load Semantic Module handler '" + elementName + ":" + handlerName + "'" );
@@ -315,6 +327,55 @@
this.semanticModules.addSemanticModule( module );
}
+ public ProcessNodeBuilderRegistry getProcessNodeBuilderRegistry() {
+ if ( this.nodeBuilderRegistry == null ) {
+ initProcessNodeBuilderRegistry();
+ }
+ return this.nodeBuilderRegistry;
+
+ }
+
+ private void initProcessNodeBuilderRegistry() {
+ this.nodeBuilderRegistry = new ProcessNodeBuilderRegistry();
+
+ // split on each space
+ String locations[] = this.chainedProperties.getProperty( "processNodeBuilderRegistry",
+ "" ).split( "\\s" );
+
+ int i = 0;
+ // load each SemanticModule
+ for ( String builderLocation : locations ) {
+ // trim leading/trailing spaces and quotes
+ builderLocation = builderLocation.trim();
+ if ( builderLocation.startsWith( "\"" ) ) {
+ builderLocation = builderLocation.substring( 1 );
+ }
+ if ( builderLocation.endsWith( "\"" ) ) {
+ builderLocation = builderLocation.substring( 0,
+ builderLocation.length() - 1 );
+ }
+ if ( !builderLocation.equals( "" ) ) {
+ loadProcessNodeBuilderRegistry( builderLocation );
+ }
+ }
+ }
+
+ private void loadProcessNodeBuilderRegistry(String factoryLocation) {
+ String content = ConfFileUtils.URLContentsToString( ConfFileUtils.getURL( factoryLocation,
+ null,
+ RuleBaseConfiguration.class ) );
+
+ Map<Class< ? extends Node>, ProcessNodeBuilder> map = (Map<Class< ? extends Node>, ProcessNodeBuilder>) MVEL.eval( content,
+ new HashMap() );
+
+ if ( map != null ) {
+ for ( Entry<Class< ? extends Node>, ProcessNodeBuilder> entry : map.entrySet() ) {
+ this.nodeBuilderRegistry.register( entry.getKey(),
+ entry.getValue() );
+ }
+ }
+ }
+
private void buildAccumulateFunctionsMap() {
this.accumulateFunctions = new HashMap<String, String>();
Map temp = new HashMap();
@@ -396,7 +457,7 @@
* The class must implement the EvaluatorDefinition interface.
*
*/
- public void addEvaluatorDefinition( String className ) {
+ public void addEvaluatorDefinition(String className) {
this.evaluatorRegistry.addEvaluatorDefinition( className );
}
@@ -408,7 +469,7 @@
* @param def the evaluator definition to be added.
*
*/
- public void addEvaluatorDefinition( EvaluatorDefinition def ) {
+ public void addEvaluatorDefinition(EvaluatorDefinition def) {
this.evaluatorRegistry.addEvaluatorDefinition( def );
}
Modified: labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/compiler/ProcessBuilder.java
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/compiler/ProcessBuilder.java 2008-01-02 14:33:16 UTC (rev 17493)
+++ labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/compiler/ProcessBuilder.java 2008-01-02 14:37:31 UTC (rev 17494)
@@ -116,16 +116,11 @@
}
}
- private static ProcessNodeBuilderRegistry nodeBuilderRegistry = new ProcessNodeBuilderRegistry();
+
- static {
- nodeBuilderRegistry.register( ActionNodeImpl.class,
- new ActionNodeBuilder() );
- nodeBuilderRegistry.register( SplitImpl.class,
- new SplitNodeBuilder() );
- }
-
public void buildNodes(Process process) {
+ ProcessNodeBuilderRegistry nodeBuilderRegistry = packageBuilder.getPackageBuilderConfiguration().getProcessNodeBuilderRegistry();
+
RuleFlowProcess rfp = (RuleFlowProcess) process;
ProcessDescr processDescr = new ProcessDescr();
@@ -163,21 +158,6 @@
}
- public void buildAction(Process process,
- ProcessDescr processDescr,
- ProcessBuildContext context,
- ActionNodeImpl actionNode) {
- DroolsConsequenceAction action = (DroolsConsequenceAction) actionNode.getAction();
- ActionDescr actionDescr = new ActionDescr();
- actionDescr.setText( action.getConsequence() );
-
- Dialect dialect = this.packageBuilder.getDialectRegistry().getDialect( action.getDialect() );
-
- dialect.getActionBuilder().build( context,
- actionNode,
- actionDescr );
- }
-
public void addProcessFromFile(final Reader reader) throws Exception {
final XStream stream = new XStream();
stream.setMode( XStream.ID_REFERENCES );
Modified: labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/process/builder/ProcessNodeBuilderRegistry.java
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/process/builder/ProcessNodeBuilderRegistry.java 2008-01-02 14:33:16 UTC (rev 17493)
+++ labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/process/builder/ProcessNodeBuilderRegistry.java 2008-01-02 14:37:31 UTC (rev 17494)
@@ -4,19 +4,28 @@
import java.util.Map;
import org.drools.ruleflow.core.Node;
+import org.drools.ruleflow.core.impl.ActionNodeImpl;
+import org.drools.ruleflow.core.impl.SplitImpl;
public class ProcessNodeBuilderRegistry {
- private Map<Class<? extends Node>, ProcessNodeBuilder> registry;
-
- public ProcessNodeBuilderRegistry() {
- this.registry = new HashMap<Class<? extends Node>, ProcessNodeBuilder>();
- }
-
- public void register(Class<? extends Node> cls, ProcessNodeBuilder builder) {
- this.registry.put(cls, builder);
- }
-
- public ProcessNodeBuilder getNodeBuilder(Node node) {
- return this.registry.get( node.getClass() );
- }
+ private Map<Class< ? extends Node>, ProcessNodeBuilder> registry;
+
+ public ProcessNodeBuilderRegistry() {
+ this.registry = new HashMap<Class< ? extends Node>, ProcessNodeBuilder>();
+
+ register( ActionNodeImpl.class,
+ new ActionNodeBuilder() );
+ register( SplitImpl.class,
+ new SplitNodeBuilder() );
+ }
+
+ public void register(Class< ? extends Node> cls,
+ ProcessNodeBuilder builder) {
+ this.registry.put( cls,
+ builder );
+ }
+
+ public ProcessNodeBuilder getNodeBuilder(Node node) {
+ return this.registry.get( node.getClass() );
+ }
}
Modified: labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/MiscTest.java
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/MiscTest.java 2008-01-02 14:33:16 UTC (rev 17493)
+++ labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/MiscTest.java 2008-01-02 14:37:31 UTC (rev 17494)
@@ -1909,6 +1909,7 @@
RuleBase ruleBase = getRuleBase();// RuleBaseFactory.newRuleBase();
+ // serialise a hashmap with the RuleBase as a key
Map map = new HashMap();
map.put( "x", ruleBase );
final byte[] ast = serializeOut( map );
@@ -1917,23 +1918,92 @@
WorkingMemory workingMemory = ruleBase.newStatefulSession();
- final byte[] wm = serializeOut( workingMemory );
-
+ // serialise the working memory before population
+ final byte[] wm = serializeOut( workingMemory );
workingMemory = ruleBase.newStatefulSession( new ByteArrayInputStream( wm ) );
ruleBase.addPackage( pkg );
workingMemory.setGlobal( "list",
- new ArrayList() );
+ new ArrayList() );
-
final Person bob = new Person( "bob" );
workingMemory.insert( bob );
+
+ final Rule[] rules = ruleBase.getPackages()[0].getRules();
+
+ assertEquals( 4,
+ rules.length );
+ assertEquals( "match Person 1",
+ rules[0].getName() );
+ assertEquals( "match Person 2",
+ rules[1].getName() );
+ assertEquals( "match Person 3",
+ rules[2].getName() );
+ assertEquals( "match Integer",
+ rules[3].getName() );
+ assertEquals( 1,
+ IteratorToList.convert( workingMemory.iterateObjects() ).size() );
+ assertEquals( bob,
+ IteratorToList.convert( workingMemory.iterateObjects() ).get( 0 ) );
+
+ assertEquals( 2,
+ workingMemory.getAgenda().agendaSize() );
+
+ workingMemory.fireAllRules();
+
+ final List list = (List) workingMemory.getGlobal( "list" );
+
+ assertEquals( 3,
+ list.size() );
+ // because of agenda-groups
+ assertEquals( new Integer( 4 ),
+ list.get( 0 ) );
+
+ assertEquals( 2,
+ IteratorToList.convert( workingMemory.iterateObjects() ).size() );
+ assertTrue( IteratorToList.convert( workingMemory.iterateObjects() ).contains( bob ) );
+ assertTrue( IteratorToList.convert( workingMemory.iterateObjects() ).contains( new Person( "help" ) ) );
+ }
+
+
+ public void testSerializeWorkingMemoryAndRuleBase3() throws Exception {
+ // has the first newStatefulSession after the ruleBase is serialised
+ final Reader reader = new InputStreamReader( getClass().getResourceAsStream( "test_Serializable.drl" ) );
+
+ final PackageBuilder builder = new PackageBuilder();
+ builder.addPackageFromDrl( reader );
+ final Package pkg = builder.getPackage();
+
+ assertEquals( 0,
+ builder.getErrors().getErrors().length );
+
+ RuleBase ruleBase = getRuleBase();
+ WorkingMemory workingMemory = ruleBase.newStatefulSession();
+
+ ruleBase.addPackage( pkg );
+
+ workingMemory.setGlobal( "list",
+ new ArrayList() );
+
+ final Person bob = new Person( "bob" );
+ workingMemory.insert( bob );
+
+ // serialise a hashmap with the RuleBase as a key, after WM population
+ Map map = new HashMap();
+ map.put( "x", ruleBase );
+ final byte[] ast = serializeOut( map );
+ map = (Map) serializeIn( ast );
+ ruleBase = (RuleBase) map.get( "x" );
+
+ // now try serialising with a fully populated wm from a serialised rulebase
+ final byte[] wm = serializeOut( workingMemory );
+ workingMemory = ruleBase.newStatefulSession( new ByteArrayInputStream( wm ) );
+
final Rule[] rules = ruleBase.getPackages()[0].getRules();
-
assertEquals( 4,
rules.length );
@@ -1945,10 +2015,8 @@
assertEquals( "match Person 3",
rules[2].getName() );
assertEquals( "match Integer",
- rules[3].getName() );
+ rules[3].getName() );
-
-
assertEquals( 1,
IteratorToList.convert( workingMemory.iterateObjects() ).size() );
assertEquals( bob,
@@ -1970,8 +2038,7 @@
assertEquals( 2,
IteratorToList.convert( workingMemory.iterateObjects() ).size() );
assertTrue( IteratorToList.convert( workingMemory.iterateObjects() ).contains( bob ) );
- assertTrue( IteratorToList.convert( workingMemory.iterateObjects() ).contains( new Person( "help" ) ) );
-
+ assertTrue( IteratorToList.convert( workingMemory.iterateObjects() ).contains( new Person( "help" ) ) );
}
More information about the jboss-svn-commits
mailing list