[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