[jboss-svn-commits] JBL Code SVN: r12605 - in labs/jbossrules/trunk/drools-core/src: main/java/org/drools/common and 3 other directories.

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Fri Jun 15 00:04:57 EDT 2007


Author: mark.proctor at jboss.com
Date: 2007-06-15 00:04:57 -0400 (Fri, 15 Jun 2007)
New Revision: 12605

Modified:
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/RuleBaseConfiguration.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/InternalRuleBase.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/Rete.java
   labs/jbossrules/trunk/drools-core/src/test/java/org/drools/RuleBaseConfigurationTest.java
   labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/ReteTest.java
Log:
JBRULES-930 Optional Shadow Facts

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/RuleBaseConfiguration.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/RuleBaseConfiguration.java	2007-06-15 03:58:05 UTC (rev 12604)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/RuleBaseConfiguration.java	2007-06-15 04:04:57 UTC (rev 12605)
@@ -17,6 +17,10 @@
 package org.drools;
 
 import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
 import java.util.Properties;
 
 import org.drools.concurrent.ExecutorService;
@@ -54,44 +58,51 @@
  * drools.indexRightBetaMemory = <true/false>
  * drools.assertBehaviour = <IDENTITY|EQUALITY>
  * drools.logicalOverride = <DISCARD|PRESERVE>
+ * drools.executorService = <qualified class name>
+ * drools.conflictResolver = <qualified class name>
+ * 
+ * drools.shadowproxy.exclude = org.domainy.* org.domainx.ClassZ
  */
 public class RuleBaseConfiguration
     implements
     Serializable {
-    private static final long serialVersionUID = 320L;
+    private static final long   serialVersionUID = 320L;
 
-    private ChainedProperties chainedProperties;
+    private ChainedProperties   chainedProperties;
 
-    private boolean           immutable;
+    private boolean             immutable;
 
-    private boolean           maintainTms;
-    private boolean           removeIdentities;
-    private boolean           shareAlphaNodes;
-    private boolean           shareBetaNodes;
-    private boolean           alphaMemory;
-    private int               alphaNodeHashingThreshold;
-    private int               compositeKeyDepth;
-    private boolean           indexLeftBetaMemory;
-    private boolean           indexRightBetaMemory;
-    private AssertBehaviour   assertBehaviour;
-    private LogicalOverride   logicalOverride;
-    private ExecutorService   executorService;
+    private boolean             maintainTms;
+    private boolean             removeIdentities;
+    private boolean             shareAlphaNodes;
+    private boolean             shareBetaNodes;
+    private boolean             alphaMemory;
+    private int                 alphaNodeHashingThreshold;
+    private int                 compositeKeyDepth;
+    private boolean             indexLeftBetaMemory;
+    private boolean             indexRightBetaMemory;
+    private AssertBehaviour     assertBehaviour;
+    private LogicalOverride     logicalOverride;
+    private ExecutorService     executorService;
 
-    private ConflictResolver conflictResolver;
+    private ConflictResolver    conflictResolver;
 
+    private Map                 shadowProxyExcludes;
+    private static final String STAR             = "*";
+
     public RuleBaseConfiguration(Properties properties) {
-        init(properties);
+        init( properties );
     }
-    
+
     public RuleBaseConfiguration() {
-        init(null);
+        init( null );
     }
-    
+
     private void init(Properties properties) {
         this.immutable = false;
 
         this.chainedProperties = new ChainedProperties( "rulebase.conf" );
-        
+
         if ( properties != null ) {
             this.chainedProperties.addProperties( properties );
         }
@@ -129,9 +140,12 @@
 
         setExecutorService( RuleBaseConfiguration.determineExecutorService( this.chainedProperties.getProperty( "drools.executorService",
                                                                                                                 "org.drools.concurrent.DefaultExecutorService" ) ) );
-        
+
         setConflictResolver( RuleBaseConfiguration.determineConflictResolver( this.chainedProperties.getProperty( "drools.conflictResolver",
-                                                                                                                 "org.drools.conflict.DepthConflictResolver" ) ) );
+                                                                                                                  "org.drools.conflict.DepthConflictResolver" ) ) );
+
+        setShadowProxyExcludes( this.chainedProperties.getProperty( "drools.shadowProxyExcludes",
+                                                                    "" ) );
     }
 
     /**
@@ -271,7 +285,7 @@
         this.executorService = executorService;
     }
 
-    public static ExecutorService determineExecutorService(String className) {
+    private static ExecutorService determineExecutorService(String className) {
         Class clazz = null;
         try {
             clazz = Thread.currentThread().getContextClassLoader().loadClass( className );
@@ -330,9 +344,9 @@
                     throw new IllegalArgumentException( "Illegal enum value '" + this.value + "' for AssertBehaviour" );
             }
         }
-        
+
         public String toString() {
-            return "AssertBehaviour : " + ( ( this.value == 0) ? "identity" : "equality" );
+            return "AssertBehaviour : " + ((this.value == 0) ? "identity" : "equality");
         }
     }
 
@@ -370,13 +384,13 @@
                     throw new IllegalArgumentException( "Illegal enum value '" + this.value + "' for LogicalOverride" );
             }
         }
-        
+
         public String toString() {
-            return "LogicalOverride : " + ( ( this.value == 0) ? "preserve" : "discard" );
-        }        
+            return "LogicalOverride : " + ((this.value == 0) ? "preserve" : "discard");
+        }
     }
-    
-    public static ConflictResolver determineConflictResolver(String className) {
+
+    private static ConflictResolver determineConflictResolver(String className) {
         Class clazz = null;
         try {
             clazz = Thread.currentThread().getContextClassLoader().loadClass( className );
@@ -392,15 +406,17 @@
 
         if ( clazz != null ) {
             try {
-                return (ConflictResolver) clazz.getMethod( "getInstance", null ).invoke( null, null );
+                return (ConflictResolver) clazz.getMethod( "getInstance",
+                                                           null ).invoke( null,
+                                                                          null );
             } catch ( Exception e ) {
                 throw new IllegalArgumentException( "Unable to Conflict Resolver '" + className + "'" );
             }
         } else {
             throw new IllegalArgumentException( "conflict Resolver '" + className + "' not found" );
         }
-    }    
-    
+    }
+
     public void setConflictResolver(ConflictResolver conflictResolver) {
         this.conflictResolver = conflictResolver;
     }
@@ -409,4 +425,66 @@
         return this.conflictResolver;
     }
 
+    private void setShadowProxyExcludes(String excludes) {
+        if ( excludes == null || "".equals( excludes.trim() ) ) {
+            return;
+        }
+        
+        if ( this.shadowProxyExcludes == null ) {
+            this.shadowProxyExcludes = new HashMap();
+        }
+        
+        String[] items = excludes.split( " " );
+        for ( int i = 0; i < items.length; i++ ) {
+            String qualifiedNamespace = items[i].substring( 0,
+                                                            items[i].lastIndexOf( '.' ) ).trim();
+            String name = items[i].substring( items[i].lastIndexOf( '.' ) + 1 ).trim();
+            Object object = this.shadowProxyExcludes.get( qualifiedNamespace );
+            if ( object == null ) {
+                if ( STAR.equals( name ) ) {
+                    this.shadowProxyExcludes.put( qualifiedNamespace,
+                                                  STAR );
+                } else {
+                    // create a new list and add it
+                    List list = new ArrayList();
+                    list.add( name );
+                    this.shadowProxyExcludes.put( qualifiedNamespace,
+                                                  list );                    
+                }
+            } else if ( name.equals( STAR ) ) {
+                // if its a STAR now add it anyway, we don't care if it was a STAR or a List before
+                this.shadowProxyExcludes.put( qualifiedNamespace,
+                                              STAR );
+            } else {
+                // its a list so add it if it doesn't already exist
+                List list = (List) object;
+                if ( !list.contains( object ) ) {
+                    list.add( name );
+                }
+            }
+        }
+    }
+    
+    public boolean isShadowed(String className) {
+        if ( this.shadowProxyExcludes == null ) {
+            return true;
+        }
+        
+        String qualifiedNamespace = className.substring( 0,
+                                                         className.lastIndexOf( '.' ) ).trim();
+        String name = className.substring( className.lastIndexOf( '.' ) + 1 ).trim();
+        Object object = this.shadowProxyExcludes.get( qualifiedNamespace );
+        if ( object == null ) {
+            return true;
+        } else if ( STAR.equals( object ) ) {
+            return false;
+        } else {
+            List list = ( List ) object;
+            return !list.contains( name );
+        }
+        
+        
+        
+    }
+
 }

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/InternalRuleBase.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/InternalRuleBase.java	2007-06-15 03:58:05 UTC (rev 12604)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/InternalRuleBase.java	2007-06-15 04:04:57 UTC (rev 12605)
@@ -23,6 +23,7 @@
 import org.drools.RuleBase;
 import org.drools.RuleBaseConfiguration;
 import org.drools.StatefulSession;
+import org.drools.reteoo.Rete;
 import org.drools.reteoo.ReteooWorkingMemory;
 import org.drools.rule.CompositePackageClassLoader;
 import org.drools.rule.MapBackedClassLoader;
@@ -87,4 +88,6 @@
     public CompositePackageClassLoader getCompositePackageClassLoader();
     
     public MapBackedClassLoader getMapBackedClassLoader();
+    
+    public Rete getRete();
 }

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/Rete.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/Rete.java	2007-06-15 03:58:05 UTC (rev 12604)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/Rete.java	2007-06-15 04:04:57 UTC (rev 12605)
@@ -123,7 +123,7 @@
             String key = ((Fact) object).getFactTemplate().getName();
             ojectTypeConf = (ObjectTypeConf) memory.get( key );
             if ( ojectTypeConf == null ) {
-                ojectTypeConf = new ObjectTypeConf( null, this);            
+                ojectTypeConf = new ObjectTypeConf( null, this.ruleBase);            
                 memory.put( key,
                             ojectTypeConf,
                             false );
@@ -136,7 +136,7 @@
             
             ojectTypeConf = (ObjectTypeConf) memory.get( cls );
             if ( ojectTypeConf == null ) {
-                ojectTypeConf = new ObjectTypeConf( cls, this);            
+                ojectTypeConf = new ObjectTypeConf( cls, this.ruleBase);            
                 memory.put( cls,
                             ojectTypeConf,
                             false );
@@ -308,7 +308,7 @@
         private static final Objenesis         OBJENESIS        = new ObjenesisStd( false );
         
         private final Class cls;
-        private final Rete rete;        
+        private final InternalRuleBase ruleBase;        
         private ObjectTypeNode[] objectTypeNodes;
         
         protected boolean                      shadowEnabled;
@@ -317,11 +317,12 @@
         protected transient Field              delegate;        
         //private final InternalRuleBase ruleBase;
         
-        public ObjectTypeConf(Class cls, Rete rete) {
+        public ObjectTypeConf(Class cls, InternalRuleBase ruleBase) {
             this.cls = cls;
-            this.rete = rete;      
+            this.ruleBase = ruleBase;
+            Rete rete = ruleBase.getRete(); 
             
-            if ( cls == null ) {
+            if ( cls == null || !ruleBase.getConfiguration().isShadowed( cls.getName() ) ) {
                 return;
             }
             
@@ -336,15 +337,15 @@
             final String shadowProxyName = ShadowProxyFactory.getProxyClassNameForClass( this.cls );
             try {
                 // if already loaded
-                shadowClass =  this.rete.getRuleBase().getMapBackedClassLoader().loadClass( shadowProxyName );
+                shadowClass =  rete.getRuleBase().getMapBackedClassLoader().loadClass( shadowProxyName );
             } catch ( final ClassNotFoundException cnfe ) {
                 // otherwise, create and load
                 final byte[] proxyBytes = ShadowProxyFactory.getProxyBytes( cls );
                 if ( proxyBytes != null ) {
-                    this.rete.getRuleBase().getMapBackedClassLoader().addClass( shadowProxyName,
+                    rete.getRuleBase().getMapBackedClassLoader().addClass( shadowProxyName,
                                                                               proxyBytes );
                     try {
-                        shadowClass =  this.rete.getRuleBase().getMapBackedClassLoader().loadClass( shadowProxyName );
+                        shadowClass =  rete.getRuleBase().getMapBackedClassLoader().loadClass( shadowProxyName );
                     } catch ( ClassNotFoundException e ) {
                         throw new RuntimeException( "Unable to find or generate the ShadowProxy implementation for '" + this.cls.getName() + "'" );
                     }
@@ -419,7 +420,7 @@
         private void buildCache(final Object object) throws FactException {
             final List cache = new ArrayList();
 
-            final Iterator it = this.rete.getObjectTypeNodes().iterator();
+            final Iterator it = ruleBase.getRete().getObjectTypeNodes().iterator();
             for ( ObjectEntry entry = (ObjectEntry) it.next(); entry != null; entry = (ObjectEntry) it.next() ) {
                 final ObjectTypeNode node = (ObjectTypeNode) entry.getValue();
                 if ( node.matches( object ) ) {

Modified: labs/jbossrules/trunk/drools-core/src/test/java/org/drools/RuleBaseConfigurationTest.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/test/java/org/drools/RuleBaseConfigurationTest.java	2007-06-15 03:58:05 UTC (rev 12604)
+++ labs/jbossrules/trunk/drools-core/src/test/java/org/drools/RuleBaseConfigurationTest.java	2007-06-15 04:04:57 UTC (rev 12605)
@@ -37,5 +37,22 @@
         
         System.getProperties().remove( "drools.indexLeftBetaMemory" );        
     }
+    
+    public void testShadowProxyExcludes() {
+        RuleBaseConfiguration cfg = new RuleBaseConfiguration();
+        
+        Properties properties = new Properties();
+        properties.setProperty( "drools.shadowProxyExcludes", "java.util.List java.util.Map java.lang.reflect.*" );
+        
+        cfg = new RuleBaseConfiguration( properties );
+        
+        assertFalse( cfg.isShadowed( "java.util.List" ) );
+        assertFalse( cfg.isShadowed( "java.util.Map" ) );
+        assertTrue( cfg.isShadowed( "java.util.HashMap" ) );
+        
+        assertFalse( cfg.isShadowed( "java.lang.reflect.Method" ) );
+        
+        assertTrue( cfg.isShadowed( "java.lang.String" ) );
+    }
 
 }

Modified: labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/ReteTest.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/ReteTest.java	2007-06-15 03:58:05 UTC (rev 12604)
+++ labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/ReteTest.java	2007-06-15 04:04:57 UTC (rev 12605)
@@ -21,9 +21,12 @@
 import java.util.Collection;
 import java.util.LinkedList;
 import java.util.List;
+import java.util.Properties;
 
+import org.drools.Cheese;
 import org.drools.DroolsTestCase;
 import org.drools.FactException;
+import org.drools.RuleBaseConfiguration;
 import org.drools.RuleBaseFactory;
 import org.drools.base.ClassObjectType;
 import org.drools.base.ShadowProxy;
@@ -221,6 +224,8 @@
                            null,
                            workingMemory );
         assertLength( 0,
+                      sink1.getAsserted() );        
+        assertLength( 0,
                       sink1.getRetracted() );
 
         // There is a List ObjectTypeNode, make sure it was propagated
@@ -251,7 +256,78 @@
         assertSame( list,
                     unwrapShadow( ((DefaultFactHandle) results[0]).getObject() ) );
     }
+    
+    public void testIsShadowed() {
+        final ReteooRuleBase ruleBase = (ReteooRuleBase) RuleBaseFactory.newRuleBase();
+        final ReteooWorkingMemory workingMemory = new ReteooWorkingMemory( 1,
+                                                                           ruleBase );
 
+        // Create a Rete network with ObjectTypeNodes for List, Collection and ArrayList
+        final Rete rete = ruleBase.getRete();
+        final ObjectTypeNode objectTypeNode = new ObjectTypeNode( 1,
+                                                                  new ClassObjectType( Cheese.class ),
+                                                                  rete,
+                                                                  3 );
+        objectTypeNode.attach();
+        final MockObjectSink sink1 = new MockObjectSink();
+        objectTypeNode.addObjectSink( sink1 );
+
+        // There are no String ObjectTypeNodes, make sure its not propagated
+
+        final Cheese cheese = new Cheese("brie", 15);
+        final DefaultFactHandle h1 = new DefaultFactHandle( 1,
+                                                            cheese );
+
+        rete.assertObject( h1,
+                           new PropagationContextImpl( 0,
+                                                       PropagationContext.ASSERTION,
+                                                       null,
+                                                       null ),
+                           workingMemory );
+
+        assertTrue( h1.isShadowFact() );   
+        
+        final Object[] results = (Object[]) sink1.getAsserted().get( 0 );
+        assertTrue( ((DefaultFactHandle) results[0]).getObject()  instanceof ShadowProxy );        
+    }
+    
+    public void testNotShadowed() {
+        
+        Properties properties = new Properties();
+        properties.setProperty( "drools.shadowProxyExcludes", "org.drools.Cheese" );
+        RuleBaseConfiguration conf = new RuleBaseConfiguration(properties);
+        final ReteooRuleBase ruleBase = (ReteooRuleBase) RuleBaseFactory.newRuleBase( conf);
+        final ReteooWorkingMemory workingMemory = new ReteooWorkingMemory( 1,
+                                                                           ruleBase );
+
+        // Create a Rete network with ObjectTypeNodes for List, Collection and ArrayList
+        final Rete rete = ruleBase.getRete();
+        final ObjectTypeNode objectTypeNode = new ObjectTypeNode( 1,
+                                                                  new ClassObjectType( Cheese.class ),
+                                                                  rete,
+                                                                  3 );
+        objectTypeNode.attach();
+        final MockObjectSink sink1 = new MockObjectSink();
+        objectTypeNode.addObjectSink( sink1 );
+
+        // There are no String ObjectTypeNodes, make sure its not propagated
+
+        final Cheese cheese = new Cheese("brie", 15);
+        final DefaultFactHandle h1 = new DefaultFactHandle( 1,
+                                                            cheese );
+
+        rete.assertObject( h1,
+                           new PropagationContextImpl( 0,
+                                                       PropagationContext.ASSERTION,
+                                                       null,
+                                                       null ),
+                           workingMemory );
+
+        assertFalse( h1.isShadowFact() );   
+        final Object[] results = (Object[]) sink1.getAsserted().get( 0 );
+        assertFalse( ((DefaultFactHandle) results[0]).getObject()  instanceof ShadowProxy );         
+    }    
+
     private Object unwrapShadow(Object object) {
         if ( object instanceof ShadowProxy ) {
             return ((ShadowProxy) object).getShadowedObject();




More information about the jboss-svn-commits mailing list