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

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Tue Oct 2 23:14:31 EDT 2007


Author: mark.proctor at jboss.com
Date: 2007-10-02 23:14:31 -0400 (Tue, 02 Oct 2007)
New Revision: 15532

Added:
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/AfterFunctionRemovedEvent.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/AfterRuleBaseLockedEvent.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/AfterRuleBaseUnlockedEvent.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/BeforeFunctionRemovedEvent.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/BeforeRuleBaseLockedEvent.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/BeforeRuleBaseUnlockedEvent.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/DefaultRuleBaseEventListener.java
Modified:
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/RuleBase.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/agent/PackageProvider.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/audit/WorkingMemoryFileLogger.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/audit/WorkingMemoryLogger.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/AbstractRuleBase.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/AfterPackageAddedEvent.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/AfterPackageRemovedEvent.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/AfterRuleAddedEvent.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/AfterRuleRemovedEvent.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/AgendaEventSupport.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/BeforePackageAddedEvent.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/BeforePackageRemovedEvent.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/BeforeRuleAddedEvent.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/BeforeRuleRemovedEvent.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/DebugRuleFlowEventListener.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/DefaultRuleFlowEventListener.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/ObjectUpdatedEvent.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/RuleBaseEvent.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/RuleBaseEventListener.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/RuleBaseEventSupport.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/RuleFlowCompletedEvent.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/RuleFlowEvent.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/RuleFlowEventListener.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/RuleFlowEventSupport.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/RuleFlowGroupActivatedEvent.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/RuleFlowGroupDeactivatedEvent.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/RuleFlowGroupEvent.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/RuleFlowStartedEvent.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/WorkingMemoryEventSupport.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ReteooRuleBase.java
   labs/jbossrules/trunk/drools-core/src/test/java/org/drools/event/RuleBaseEventListenerTest.java
Log:
JBRULES-1241 Dynamic rules should be able to lock for a series of updates and fireAllRules should be optional
-Base infrastructure is working, just need to make the event listener pluggeable.

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/RuleBase.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/RuleBase.java	2007-10-03 00:28:04 UTC (rev 15531)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/RuleBase.java	2007-10-03 03:14:31 UTC (rev 15532)
@@ -120,7 +120,15 @@
     Package getPackage(String name);
 
     void addPackage(Package pkg) throws Exception;
+    
+    void lock();
+    
+    void unlock();
+    
+    int getAdditionsSinceLock();
 
+    int getRemovalsSinceLock();
+
     void removePackage(String packageName);
 
     void removeRule(String packageName,

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/agent/PackageProvider.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/agent/PackageProvider.java	2007-10-03 00:28:04 UTC (rev 15531)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/agent/PackageProvider.java	2007-10-03 03:14:31 UTC (rev 15532)
@@ -54,6 +54,7 @@
     }
     
     static void applyChanges(RuleBase rb, boolean removeExistingPackages, Collection changes, AgentEventListener listener) {
+        rb.lock();
         if ( changes == null ) return;
         for ( Iterator iter = changes.iterator(); iter.hasNext(); ) {
             Package p = (Package) iter.next();
@@ -69,6 +70,7 @@
                 throw new RuntimeDroolsException( e );
             }
         }
+        rb.unlock();
     }
     
     public void setAgentListener(AgentEventListener listener) {

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/audit/WorkingMemoryFileLogger.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/audit/WorkingMemoryFileLogger.java	2007-10-03 00:28:04 UTC (rev 15531)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/audit/WorkingMemoryFileLogger.java	2007-10-03 03:14:31 UTC (rev 15532)
@@ -24,6 +24,12 @@
 
 import org.drools.WorkingMemoryEventManager;
 import org.drools.audit.event.LogEvent;
+import org.drools.event.AfterFunctionRemovedEvent;
+import org.drools.event.AfterRuleBaseLockedEvent;
+import org.drools.event.AfterRuleBaseUnlockedEvent;
+import org.drools.event.BeforeFunctionRemovedEvent;
+import org.drools.event.BeforeRuleBaseLockedEvent;
+import org.drools.event.BeforeRuleBaseUnlockedEvent;
 
 import com.thoughtworks.xstream.XStream;
 
@@ -124,4 +130,5 @@
     public void finalize() {
         writeToDisk();
     }
+
 }

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/audit/WorkingMemoryLogger.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/audit/WorkingMemoryLogger.java	2007-10-03 00:28:04 UTC (rev 15531)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/audit/WorkingMemoryLogger.java	2007-10-03 03:14:31 UTC (rev 15532)
@@ -36,17 +36,23 @@
 import org.drools.event.ActivationCancelledEvent;
 import org.drools.event.ActivationCreatedEvent;
 import org.drools.event.AfterActivationFiredEvent;
+import org.drools.event.AfterFunctionRemovedEvent;
 import org.drools.event.AfterPackageAddedEvent;
 import org.drools.event.AfterPackageRemovedEvent;
 import org.drools.event.AfterRuleAddedEvent;
+import org.drools.event.AfterRuleBaseLockedEvent;
+import org.drools.event.AfterRuleBaseUnlockedEvent;
 import org.drools.event.AfterRuleRemovedEvent;
 import org.drools.event.AgendaEventListener;
 import org.drools.event.AgendaGroupPoppedEvent;
 import org.drools.event.AgendaGroupPushedEvent;
 import org.drools.event.BeforeActivationFiredEvent;
+import org.drools.event.BeforeFunctionRemovedEvent;
 import org.drools.event.BeforePackageAddedEvent;
 import org.drools.event.BeforePackageRemovedEvent;
 import org.drools.event.BeforeRuleAddedEvent;
+import org.drools.event.BeforeRuleBaseLockedEvent;
+import org.drools.event.BeforeRuleBaseUnlockedEvent;
 import org.drools.event.BeforeRuleRemovedEvent;
 import org.drools.event.ObjectInsertedEvent;
 import org.drools.event.ObjectUpdatedEvent;
@@ -389,5 +395,33 @@
                                               event.getRule().getName() ) );
     }
     
+    public void afterFunctionRemoved(AfterFunctionRemovedEvent event) {
+        // TODO Auto-generated method stub
+        
+    }
 
+    public void afterRuleBaseLocked(AfterRuleBaseLockedEvent event) {
+        // TODO Auto-generated method stub
+        
+    }
+
+    public void afterRuleBaseUnlocked(AfterRuleBaseUnlockedEvent event) {
+        // TODO Auto-generated method stub
+        
+    }
+
+    public void beforeFunctionRemoved(BeforeFunctionRemovedEvent event) {
+        // TODO Auto-generated method stub
+        
+    }
+
+    public void beforeRuleBaseLocked(BeforeRuleBaseLockedEvent event) {
+        // TODO Auto-generated method stub
+        
+    }
+
+    public void beforeRuleBaseUnlocked(BeforeRuleBaseUnlockedEvent event) {
+        // TODO Auto-generated method stub
+        
+    }        
 }

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/AbstractRuleBase.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/AbstractRuleBase.java	2007-10-03 00:28:04 UTC (rev 15531)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/AbstractRuleBase.java	2007-10-03 03:14:31 UTC (rev 15532)
@@ -51,6 +51,7 @@
 import org.drools.ruleflow.common.core.Process;
 import org.drools.spi.FactHandleFactory;
 import org.drools.util.ObjectHashSet;
+import org.drools.util.concurrent.locks.ReentrantLock;
 
 /**
  * Implementation of <code>RuleBase</code>.
@@ -87,17 +88,29 @@
     protected FactHandleFactory                     factHandleFactory;
 
     protected Map                                   globals;
-    
-    private ReloadPackageCompilationData reloadPackageCompilationData = null;
-    
-    private RuleBaseEventSupport                    eventSupport = new RuleBaseEventSupport();
 
+    private ReloadPackageCompilationData            reloadPackageCompilationData = null;
+
+    private RuleBaseEventSupport                    eventSupport                 = new RuleBaseEventSupport( this );
+
     /**
      * WeakHashMap to keep references of WorkingMemories but allow them to be
      * garbage collected
      */
     protected transient ObjectHashSet               statefulSessions;
 
+    // wms used for lock list during dynamic updates
+    InternalWorkingMemory[]                         wms;
+
+    // indexed used to track invariant lock
+    int                                             lastAquiredLock;
+
+    // lock for entire rulebase, used for dynamic updates
+    protected final ReentrantLock                   lock                         = new ReentrantLock();
+    
+    private int                                  additionsSinceLock;
+    private int                                  removalsSinceLock;
+
     /**
      * Default constructor - for Externalizable. This should never be used by a user, as it 
      * will result in an invalid state for the instance.
@@ -186,7 +199,7 @@
         this.pkgs = (Map) stream.readObject();
 
         if ( stream instanceof DroolsObjectInputStream ) {
-            DroolsObjectInputStream parentStream = (DroolsObjectInputStream) stream;
+            final DroolsObjectInputStream parentStream = (DroolsObjectInputStream) stream;
             parentStream.setRuleBase( this );
             this.packageClassLoader = new CompositePackageClassLoader( parentStream.getClassLoader() );
             this.classLoader = new MapBackedClassLoader( parentStream.getClassLoader() );
@@ -210,7 +223,7 @@
         childStream.setRuleBase( this );
 
         this.id = (String) childStream.readObject();
-        this.processes = ( Map ) childStream.readObject();
+        this.processes = (Map) childStream.readObject();
         this.agendaGroupRuleTotals = (Map) childStream.readObject();
         this.factHandleFactory = (FactHandleFactory) childStream.readObject();
         this.globals = (Map) childStream.readObject();
@@ -218,6 +231,7 @@
         this.config = (RuleBaseConfiguration) childStream.readObject();
         this.config.setClassLoader( childStream.getClassLoader() );
         this.eventSupport = (RuleBaseEventSupport) childStream.readObject();
+        this.eventSupport.setRuleBase( this );
 
         this.statefulSessions = new ObjectHashSet();
 
@@ -278,8 +292,55 @@
 
     public Map getAgendaGroupRuleTotals() {
         return this.agendaGroupRuleTotals;
+    }        
+
+    public int getAdditionsSinceLock() {
+        return additionsSinceLock;
     }
 
+    public int getRemovalsSinceLock() {
+        return removalsSinceLock;
+    }
+
+    public void lock() {
+        this.additionsSinceLock = 0;
+        this.removalsSinceLock = 0;
+        
+        this.eventSupport.fireBeforeRuleBaseLocked();
+        this.lock.lock();
+
+        // INVARIANT: lastAquiredLock always contains the index of the last aquired lock +1 
+        // in the working memory array 
+        this.lastAquiredLock = 0;
+
+        this.wms = getWorkingMemories();
+
+        // Iterate each workingMemory and lock it
+        // This is so we don't update the Rete network during propagation
+        for ( this.lastAquiredLock = 0; this.lastAquiredLock < this.wms.length; this.lastAquiredLock++ ) {
+            this.wms[this.lastAquiredLock].getLock().lock();
+        }
+
+        this.eventSupport.fireAfterRuleBaseLocked();
+    }
+
+    public void unlock() {
+        this.eventSupport.fireBeforeRuleBaseUnlocked();
+
+        // Iterate each workingMemory and attempt to fire any rules, that were activated as a result 
+
+        // as per the INVARIANT defined above, we need to iterate from lastAquiredLock-1 to 0. 
+        for ( this.lastAquiredLock--; this.lastAquiredLock > -1; this.lastAquiredLock-- ) {
+            this.wms[this.lastAquiredLock].getLock().unlock();
+        }
+
+        this.lock.unlock();
+
+        this.eventSupport.fireAfterRuleBaseUnlocked();
+
+        this.wms = null;      
+    }
+
     /**
      * Add a <code>Package</code> to the network. Iterates through the
      * <code>Package</code> adding Each individual <code>Rule</code> to the
@@ -298,78 +359,68 @@
      */
     public synchronized void addPackage(final Package newPkg) throws PackageIntegrationException {
         newPkg.checkValidity();
-
         synchronized ( this.pkgs ) {
             final Package pkg = (Package) this.pkgs.get( newPkg.getName() );
-            // INVARIANT: lastAquiredLock always contains the index of the last aquired lock +1 
-            // in the working memory array 
-            int lastAquiredLock = 0;
-            // get a snapshot of current working memories for locking
-            final InternalWorkingMemory[] wms = getWorkingMemories();
 
-            try {
-                // Iterate each workingMemory and lock it
-                // This is so we don't update the Rete network during propagation
-                for ( lastAquiredLock = 0; lastAquiredLock < wms.length; lastAquiredLock++ ) {
-                    wms[lastAquiredLock].getLock().lock();
-                }
+            // only acquire the lock if it hasn't been done explicitely
+            boolean doUnlock = false;
+            if ( !this.lock.isHeldByCurrentThread() && (this.wms == null || this.wms.length == 0) ) {
+                lock();
+                doUnlock = true;
+            }
+            this.additionsSinceLock++;
 
-                this.eventSupport.fireBeforePackageAdded( newPkg );
-                
-                if ( pkg != null ) {
-                    mergePackage( pkg,
-                                  newPkg );
-                } else {
-                    this.pkgs.put( newPkg.getName(),
-                                   newPkg );
-                }
+            this.eventSupport.fireBeforePackageAdded( newPkg );
 
-                final Map newGlobals = newPkg.getGlobals();
+            if ( pkg != null ) {
+                mergePackage( pkg,
+                              newPkg );
+            } else {
+                this.pkgs.put( newPkg.getName(),
+                               newPkg );
+            }
 
-                // Check that the global data is valid, we cannot change the type
-                // of an already declared global variable
-                for ( final Iterator it = newGlobals.keySet().iterator(); it.hasNext(); ) {
-                    final String identifier = (String) it.next();
-                    final Class type = (Class) newGlobals.get( identifier );
-                    final boolean f = this.globals.containsKey( identifier );
-                    if ( f ) {
-                        final boolean y = !this.globals.get( identifier ).equals( type );
-                        if ( f && y ) {
-                            throw new PackageIntegrationException( pkg );
-                        }
+            final Map newGlobals = newPkg.getGlobals();
+
+            // Check that the global data is valid, we cannot change the type
+            // of an already declared global variable
+            for ( final Iterator it = newGlobals.keySet().iterator(); it.hasNext(); ) {
+                final String identifier = (String) it.next();
+                final Class type = (Class) newGlobals.get( identifier );
+                final boolean f = this.globals.containsKey( identifier );
+                if ( f ) {
+                    final boolean y = !this.globals.get( identifier ).equals( type );
+                    if ( f && y ) {
+                        throw new PackageIntegrationException( pkg );
                     }
                 }
-                this.globals.putAll( newGlobals );
+            }
+            this.globals.putAll( newGlobals );
 
-                final Rule[] rules = newPkg.getRules();
+            final Rule[] rules = newPkg.getRules();
 
-                for ( int i = 0; i < rules.length; ++i ) {
-                    addRule( newPkg, rules[i] );
-                }
+            for ( int i = 0; i < rules.length; ++i ) {
+                addRule( newPkg,
+                         rules[i] );
+            }
 
-                //and now the rule flows
-                if ( newPkg.getRuleFlows() != Collections.EMPTY_MAP ) {
-                    Map flows = newPkg.getRuleFlows();
-                    for ( Iterator iter = flows.entrySet().iterator(); iter.hasNext(); ) {
-                        Entry flow = (Entry) iter.next();
-                        this.processes.put( flow.getKey(),
-                                            flow.getValue() );
-                    }
+            //and now the rule flows
+            if ( newPkg.getRuleFlows() != Collections.EMPTY_MAP ) {
+                final Map flows = newPkg.getRuleFlows();
+                for ( final Iterator iter = flows.entrySet().iterator(); iter.hasNext(); ) {
+                    final Entry flow = (Entry) iter.next();
+                    this.processes.put( flow.getKey(),
+                                        flow.getValue() );
                 }
+            }
 
-                this.packageClassLoader.addClassLoader( newPkg.getPackageCompilationData().getClassLoader() );
+            this.packageClassLoader.addClassLoader( newPkg.getPackageCompilationData().getClassLoader() );
 
-                this.eventSupport.fireAfterPackageAdded( newPkg );
+            this.eventSupport.fireAfterPackageAdded( newPkg );
 
-            } finally {
-                // Iterate each workingMemory and attempt to fire any rules, that were activated as a result 
-                // of the new rule addition. Unlock after fireAllRules();
-
-                // as per the INVARIANT defined above, we need to iterate from lastAquiredLock-1 to 0. 
-                for ( lastAquiredLock--; lastAquiredLock > -1; lastAquiredLock-- ) {
-                    wms[lastAquiredLock].fireAllRules();
-                    wms[lastAquiredLock].getLock().unlock();
-                }
+            // only unlock if it had been acquired implicitely
+            if ( doUnlock ) {
+                unlock();
             }
         }
 
@@ -401,12 +452,12 @@
 
         // Add invokers
         compilationData.putAllInvokers( newCompilationData.getInvokers() );
-        
+
         if ( compilationData.isDirty() ) {
             if ( this.reloadPackageCompilationData == null ) {
                 this.reloadPackageCompilationData = new ReloadPackageCompilationData();
             }
-            this.reloadPackageCompilationData.addPackageCompilationData( compilationData );            
+            this.reloadPackageCompilationData.addPackageCompilationData( compilationData );
         }
 
         // Add globals
@@ -432,92 +483,85 @@
 
         //and now the rule flows
         if ( newPkg.getRuleFlows() != Collections.EMPTY_MAP ) {
-            Map flows = newPkg.getRuleFlows();
-            for ( Iterator iter = flows.values().iterator(); iter.hasNext(); ) {
-                Process flow = (Process) iter.next();
+            final Map flows = newPkg.getRuleFlows();
+            for ( final Iterator iter = flows.values().iterator(); iter.hasNext(); ) {
+                final Process flow = (Process) iter.next();
                 pkg.addRuleFlow( flow );
             }
         }
     }
-    
-    private synchronized void addRule( final Package pkg, final Rule rule ) throws InvalidPatternException {
-        this.eventSupport.fireBeforeRuleAdded( pkg, rule );
+
+    private synchronized void addRule(final Package pkg,
+                                      final Rule rule) throws InvalidPatternException {
+        this.eventSupport.fireBeforeRuleAdded( pkg,
+                                               rule );
         if ( !rule.isValid() ) {
             throw new IllegalArgumentException( "The rule called " + rule.getName() + " is not valid. Check for compile errors reported." );
         }
         addRule( rule );
-        this.eventSupport.fireAfterRuleAdded( pkg, rule );
+        this.eventSupport.fireAfterRuleAdded( pkg,
+                                              rule );
     }
 
     protected abstract void addRule(final Rule rule) throws InvalidPatternException;
 
-    public synchronized void removePackage(final String packageName) {
+    public void removePackage(final String packageName) {
         synchronized ( this.pkgs ) {
             final Package pkg = (Package) this.pkgs.get( packageName );
-            if ( pkg ==  null) {
-                throw new IllegalArgumentException("Package name '" + packageName + "' does not exist for this Rule Base.");
+            if ( pkg == null ) {
+                throw new IllegalArgumentException( "Package name '" + packageName + "' does not exist for this Rule Base." );
             }
 
-            // INVARIANT: lastAquiredLock always contains the index of the last aquired lock +1 
-            // in the working memory array 
-            int lastAquiredLock = 0;
-            // get a snapshot of current working memories for locking
-            final InternalWorkingMemory[] wms = getWorkingMemories();
+            // only acquire the lock if it hasn't been done explicitely
+            boolean doUnlock = false;
+            if ( !this.lock.isHeldByCurrentThread() && (this.wms == null || this.wms.length == 0) ) {
+                lock();
+                doUnlock = true;
+            }
+            this.removalsSinceLock++;
+            
+            this.eventSupport.fireBeforePackageRemoved( pkg );
 
-            try {
-                // Iterate each workingMemory and lock it
-                // This is so we don't update the Rete network during propagation
-                for ( lastAquiredLock = 0; lastAquiredLock < wms.length; lastAquiredLock++ ) {
-                    wms[lastAquiredLock].getLock().lock();
-                }
-                
-                this.eventSupport.fireBeforePackageRemoved( pkg );
+            final Rule[] rules = pkg.getRules();
 
-                final Rule[] rules = pkg.getRules();
+            for ( int i = 0; i < rules.length; ++i ) {
+                removeRule( pkg,
+                            rules[i] );
+            }
 
-                for ( int i = 0; i < rules.length; ++i ) {
-                    removeRule( pkg, rules[i] );
-                }
+            this.packageClassLoader.removeClassLoader( pkg.getPackageCompilationData().getClassLoader() );
 
-                this.packageClassLoader.removeClassLoader( pkg.getPackageCompilationData().getClassLoader() );
-
-                // getting the list of referenced globals 
-                final Set referencedGlobals = new HashSet();
-                for ( final Iterator it = this.pkgs.values().iterator(); it.hasNext(); ) {
-                    final org.drools.rule.Package pkgref = (org.drools.rule.Package) it.next();
-                    if ( pkgref != pkg ) {
-                        referencedGlobals.addAll( pkgref.getGlobals().keySet() );
-                    }
+            // getting the list of referenced globals 
+            final Set referencedGlobals = new HashSet();
+            for ( final Iterator it = this.pkgs.values().iterator(); it.hasNext(); ) {
+                final org.drools.rule.Package pkgref = (org.drools.rule.Package) it.next();
+                if ( pkgref != pkg ) {
+                    referencedGlobals.addAll( pkgref.getGlobals().keySet() );
                 }
-                // removing globals declared inside the package that are not shared
-                for ( final Iterator it = pkg.getGlobals().keySet().iterator(); it.hasNext(); ) {
-                    final String globalName = (String) it.next();
-                    if ( !referencedGlobals.contains( globalName ) ) {
-                        this.globals.remove( globalName );
-                    }
+            }
+            // removing globals declared inside the package that are not shared
+            for ( final Iterator it = pkg.getGlobals().keySet().iterator(); it.hasNext(); ) {
+                final String globalName = (String) it.next();
+                if ( !referencedGlobals.contains( globalName ) ) {
+                    this.globals.remove( globalName );
                 }
-                //and now the rule flows
-                Map flows = pkg.getRuleFlows();
-                for ( Iterator iter = flows.keySet().iterator(); iter.hasNext(); ) {
-                    removeProcess( (String) iter.next() );
-                }
-                // removing the package itself from the list
-                this.pkgs.remove( pkg.getName() );
-                
-                //clear all members of the pkg
-                pkg.clear();
-                
-                this.eventSupport.fireAfterPackageRemoved( pkg );
-                
-            } finally {
-                // Iterate each workingMemory and attempt to fire any rules, that were activated as a result 
-                // of the new rule addition. Unlock after fireAllRules();
+            }
+            //and now the rule flows
+            final Map flows = pkg.getRuleFlows();
+            for ( final Iterator iter = flows.keySet().iterator(); iter.hasNext(); ) {
+                removeProcess( (String) iter.next() );
+            }
+            // removing the package itself from the list
+            this.pkgs.remove( pkg.getName() );
 
-                // as per the INVARIANT defined above, we need to iterate from lastAquiredLock-1 to 0. 
-                for ( lastAquiredLock--; lastAquiredLock > -1; lastAquiredLock-- ) {
-                    wms[lastAquiredLock].fireAllRules();
-                    wms[lastAquiredLock].getLock().unlock();
-                }
+            //clear all members of the pkg
+            pkg.clear();
+
+            this.eventSupport.fireAfterPackageRemoved( pkg );
+
+            // only unlock if it had been acquired implicitely
+            if ( doUnlock ) {
+                unlock();
             }
         }
     }
@@ -526,73 +570,74 @@
                            final String ruleName) {
         synchronized ( this.pkgs ) {
             final Package pkg = (Package) this.pkgs.get( packageName );
-            if ( pkg ==  null) {
-                throw new IllegalArgumentException("Package name '" + packageName + "' does not exist for this Rule Base.");
+            if ( pkg == null ) {
+                throw new IllegalArgumentException( "Package name '" + packageName + "' does not exist for this Rule Base." );
             }
-            
-            final Rule rule = pkg.getRule( ruleName );            
-            if ( rule ==  null) {
-                throw new IllegalArgumentException("Rule name '"+ ruleName + "' does not exist in the Package '" + packageName + "'.");
+
+            final Rule rule = pkg.getRule( ruleName );
+            if ( rule == null ) {
+                throw new IllegalArgumentException( "Rule name '" + ruleName + "' does not exist in the Package '" + packageName + "'." );
             }
 
-            // INVARIANT: lastAquiredLock always contains the index of the last aquired lock +1 
-            // in the working memory array 
-            int lastAquiredLock = 0;
-            // get a snapshot of current working memories for locking
-            final InternalWorkingMemory[] wms = getWorkingMemories();
-            
+            // only acquire the lock if it hasn't been done explicitely
+            boolean doUnlock = false;
+            if ( !this.lock.isHeldByCurrentThread() && (this.wms == null || this.wms.length == 0) ) {
+                lock();
+                doUnlock = true;
+            }
+            this.removalsSinceLock++;
+
             PackageCompilationData compilationData = null;
 
-            try {
-                // Iterate each workingMemory and lock it
-                // This is so we don't update the Rete network during propagation
-                for ( lastAquiredLock = 0; lastAquiredLock < wms.length; lastAquiredLock++ ) {
-                    wms[lastAquiredLock].getLock().lock();
-                }
+            removeRule( pkg,
+                        rule );
+            compilationData = pkg.removeRule( rule );
+            if ( this.reloadPackageCompilationData == null ) {
+                this.reloadPackageCompilationData = new ReloadPackageCompilationData();
+            }
+            this.reloadPackageCompilationData.addPackageCompilationData( compilationData );
 
-                removeRule( pkg, rule );
-                compilationData = pkg.removeRule( rule );
-                if ( this.reloadPackageCompilationData == null ) {
-                    this.reloadPackageCompilationData = new ReloadPackageCompilationData();
-                }
-                this.reloadPackageCompilationData.addPackageCompilationData( compilationData );
-
-            } finally {
-                // Iterate each workingMemory and attempt to fire any rules, that were activated as a result 
-                // of the new rule addition. Unlock after fireAllRules();
-
-                // as per the INVARIANT defined above, we need to iterate from lastAquiredLock-1 to 0. 
-                for ( lastAquiredLock--; lastAquiredLock > -1; lastAquiredLock-- ) {
-                    wms[lastAquiredLock].getLock().unlock();
-                }
-            }                       
+            // only unlock if it had been acquired implicitely                
+            if ( doUnlock ) {
+                unlock();
+            }
         }
     }
-    
-    private void removeRule( final Package pkg, final Rule rule ) {
-        this.eventSupport.fireBeforeRuleRemoved( pkg, rule );
+
+    private void removeRule(final Package pkg,
+                            final Rule rule) {
+        this.eventSupport.fireBeforeRuleRemoved( pkg,
+                                                 rule );
         removeRule( rule );
-        this.eventSupport.fireAfterRuleRemoved( pkg, rule );
+        this.eventSupport.fireAfterRuleRemoved( pkg,
+                                                rule );
     }
 
     protected abstract void removeRule(Rule rule);
-    
-    public void removeFunction(String packageName, String functionName) {
+
+    public void removeFunction(final String packageName,
+                               final String functionName) {
         synchronized ( this.pkgs ) {
             final Package pkg = (Package) this.pkgs.get( packageName );
-            if ( pkg ==  null) {
-                throw new IllegalArgumentException("Package name '" + packageName + "' does not exist for this Rule Base.");
+            if ( pkg == null ) {
+                throw new IllegalArgumentException( "Package name '" + packageName + "' does not exist for this Rule Base." );
             }
-            
-            PackageCompilationData compilationData = pkg.removeFunction( functionName );
+
+            this.eventSupport.fireBeforeFunctionRemoved( pkg,
+                                                         functionName );
+
+            final PackageCompilationData compilationData = pkg.removeFunction( functionName );
             if ( compilationData == null ) {
-                throw new IllegalArgumentException("function name '" + packageName + "' does not exist in the Package '" + packageName + "'.");
+                throw new IllegalArgumentException( "function name '" + packageName + "' does not exist in the Package '" + packageName + "'." );
             }
-            
+
             if ( this.reloadPackageCompilationData == null ) {
                 this.reloadPackageCompilationData = new ReloadPackageCompilationData();
             }
-            this.reloadPackageCompilationData.addPackageCompilationData( compilationData );            
+            this.reloadPackageCompilationData.addPackageCompilationData( compilationData );
+
+            this.eventSupport.fireAfterFunctionRemoved( pkg,
+                                                        functionName );
         }
     }
 
@@ -601,11 +646,11 @@
             this.processes.put( process.getId(),
                                 process );
         }
-        
+
     }
 
     public synchronized void removeProcess(final String id) {
-        synchronized ( this.pkgs ) {        
+        synchronized ( this.pkgs ) {
             this.processes.remove( id );
         }
     }
@@ -613,7 +658,7 @@
     public Process getProcess(final String id) {
         Process process = null;
         synchronized ( this.pkgs ) {
-            process = ( Process ) this.processes.get( id );
+            process = (Process) this.processes.get( id );
         }
         return process;
     }
@@ -622,7 +667,7 @@
         this.statefulSessions.add( statefulSession );
     }
 
-    public Package getPackage(String name) {
+    public Package getPackage(final String name) {
         return (Package) this.pkgs.get( name );
     }
 
@@ -663,8 +708,8 @@
         }
     }
 
-    public void addClass(String className,
-                         byte[] bytes) {
+    public void addClass(final String className,
+                         final byte[] bytes) {
         this.classLoader.addClass( className,
                                    bytes );
     }
@@ -676,15 +721,15 @@
     public MapBackedClassLoader getMapBackedClassLoader() {
         return this.classLoader;
     }
-    
+
     public void executeQueuedActions() {
-       synchronized ( this.pkgs ) {
-           if ( this.reloadPackageCompilationData != null ) {
-               this.reloadPackageCompilationData.execute( this );
-           }
+        synchronized ( this.pkgs ) {
+            if ( this.reloadPackageCompilationData != null ) {
+                this.reloadPackageCompilationData.execute( this );
+            }
         }
-    }    
-    
+    }
+
     public void addEventListener(final RuleBaseEventListener listener) {
         // since the event support is thread-safe, no need for locks... right?
         this.eventSupport.addEventListener( listener );
@@ -699,28 +744,32 @@
         // since the event support is thread-safe, no need for locks... right?
         return this.eventSupport.getEventListeners();
     }
-    
-    public static class ReloadPackageCompilationData implements RuleBaseAction {
+
+    public static class ReloadPackageCompilationData
+        implements
+        RuleBaseAction {
         private static final long serialVersionUID = 1L;
-        private Set set;
-        
-        public void addPackageCompilationData(PackageCompilationData packageCompilationData) {
-            if ( set == null ) {
+        private Set               set;
+
+        public void addPackageCompilationData(final PackageCompilationData packageCompilationData) {
+            if ( this.set == null ) {
                 this.set = new HashSet();
             }
-            
+
             this.set.add( packageCompilationData );
         }
-        
-        public void execute(InternalRuleBase ruleBase) {
-            for ( Iterator it = this.set.iterator(); it.hasNext(); ) {
-                PackageCompilationData packageCompilationData = ( PackageCompilationData ) it.next();
+
+        public void execute(final InternalRuleBase ruleBase) {
+            for ( final Iterator it = this.set.iterator(); it.hasNext(); ) {
+                final PackageCompilationData packageCompilationData = (PackageCompilationData) it.next();
                 packageCompilationData.reload();
             }
         }
     }
 
-    public static interface RuleBaseAction extends Serializable  {
+    public static interface RuleBaseAction
+        extends
+        Serializable {
         public void execute(InternalRuleBase ruleBase);
     }
 }

Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/AfterFunctionRemovedEvent.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/AfterFunctionRemovedEvent.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/AfterFunctionRemovedEvent.java	2007-10-03 03:14:31 UTC (rev 15532)
@@ -0,0 +1,41 @@
+package org.drools.event;
+
+/*
+ * Copyright 2005 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.
+ */
+
+import org.drools.RuleBase;
+import org.drools.rule.Package;
+
+public class AfterFunctionRemovedEvent extends RuleBaseEvent {
+
+    private static final long serialVersionUID = 400L;
+
+    public AfterFunctionRemovedEvent(final RuleBase ruleBase,
+                                     final Package pkg,
+                                     final String function) {
+        super( ruleBase,
+               pkg,
+               function );
+    }
+
+    public Object getSource() {
+        return super.getRule();
+    }
+
+    public String toString() {
+        return "[AfterFunctionRemoved: package=" + getPackage() + " function=" + getFunction() + "]";
+    }
+}
\ No newline at end of file

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/AfterPackageAddedEvent.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/AfterPackageAddedEvent.java	2007-10-03 00:28:04 UTC (rev 15531)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/AfterPackageAddedEvent.java	2007-10-03 03:14:31 UTC (rev 15532)
@@ -16,14 +16,17 @@
  * limitations under the License.
  */
 
+import org.drools.RuleBase;
 import org.drools.rule.Package;
 
 public class AfterPackageAddedEvent extends RuleBaseEvent {
 
     private static final long serialVersionUID = 400L;
 
-    public AfterPackageAddedEvent(final Package pkg) {
-        super( pkg, null );
+    public AfterPackageAddedEvent(final RuleBase ruleBase,
+                                  final Package pkg) {
+        super( ruleBase,
+               pkg );
     }
 
     public String toString() {

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/AfterPackageRemovedEvent.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/AfterPackageRemovedEvent.java	2007-10-03 00:28:04 UTC (rev 15531)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/AfterPackageRemovedEvent.java	2007-10-03 03:14:31 UTC (rev 15532)
@@ -16,14 +16,17 @@
  * limitations under the License.
  */
 
+import org.drools.RuleBase;
 import org.drools.rule.Package;
 
 public class AfterPackageRemovedEvent extends RuleBaseEvent {
 
     private static final long serialVersionUID = 400L;
 
-    public AfterPackageRemovedEvent(final Package pkg) {
-        super( pkg, null );
+    public AfterPackageRemovedEvent(final RuleBase ruleBase,
+                                    final Package pkg) {
+        super( ruleBase,
+               pkg );
     }
 
     public String toString() {

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/AfterRuleAddedEvent.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/AfterRuleAddedEvent.java	2007-10-03 00:28:04 UTC (rev 15531)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/AfterRuleAddedEvent.java	2007-10-03 03:14:31 UTC (rev 15532)
@@ -16,6 +16,7 @@
  * limitations under the License.
  */
 
+import org.drools.RuleBase;
 import org.drools.rule.Package;
 import org.drools.rule.Rule;
 
@@ -23,14 +24,18 @@
 
     private static final long serialVersionUID = 400L;
 
-    public AfterRuleAddedEvent(final Package pkg, final Rule rule) {
-        super( pkg, rule );
+    public AfterRuleAddedEvent(final RuleBase ruleBase,
+                               final Package pkg,
+                               final Rule rule) {
+        super( ruleBase,
+               pkg,
+               rule );
     }
-    
+
     public Object getSource() {
         return super.getRule();
     }
-    
+
     public String toString() {
         return "[AfterRuleAdded: package=" + getPackage() + " rule=" + getRule() + "]";
     }

Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/AfterRuleBaseLockedEvent.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/AfterRuleBaseLockedEvent.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/AfterRuleBaseLockedEvent.java	2007-10-03 03:14:31 UTC (rev 15532)
@@ -0,0 +1,32 @@
+package org.drools.event;
+
+/*
+ * Copyright 2005 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.
+ */
+
+import org.drools.RuleBase;
+
+public class AfterRuleBaseLockedEvent extends RuleBaseEvent {
+
+    private static final long serialVersionUID = 400L;
+
+    public AfterRuleBaseLockedEvent(final RuleBase ruleBase) {
+        super( ruleBase );
+    }
+
+    public String toString() {
+        return "[AfterRuleBaseLocked: ruleBase=" + getRuleBase() + "]";
+    }
+}
\ No newline at end of file

Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/AfterRuleBaseUnlockedEvent.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/AfterRuleBaseUnlockedEvent.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/AfterRuleBaseUnlockedEvent.java	2007-10-03 03:14:31 UTC (rev 15532)
@@ -0,0 +1,32 @@
+package org.drools.event;
+
+/*
+ * Copyright 2005 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.
+ */
+
+import org.drools.RuleBase;
+
+public class AfterRuleBaseUnlockedEvent extends RuleBaseEvent {
+
+    private static final long serialVersionUID = 400L;
+
+    public AfterRuleBaseUnlockedEvent(final RuleBase ruleBase) {
+        super( ruleBase );
+    }
+
+    public String toString() {
+        return "[AfterRuleBaseUnlocked: ruleBase=" + getRuleBase() + "]";
+    }
+}
\ No newline at end of file

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/AfterRuleRemovedEvent.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/AfterRuleRemovedEvent.java	2007-10-03 00:28:04 UTC (rev 15531)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/AfterRuleRemovedEvent.java	2007-10-03 03:14:31 UTC (rev 15532)
@@ -16,6 +16,7 @@
  * limitations under the License.
  */
 
+import org.drools.RuleBase;
 import org.drools.rule.Package;
 import org.drools.rule.Rule;
 
@@ -23,14 +24,18 @@
 
     private static final long serialVersionUID = 400L;
 
-    public AfterRuleRemovedEvent(final Package pkg, final Rule rule) {
-        super( pkg, rule );
+    public AfterRuleRemovedEvent(final RuleBase ruleBase,
+                                 final Package pkg,
+                                 final Rule rule) {
+        super( ruleBase,
+               pkg,
+               rule );
     }
-    
+
     public Object getSource() {
         return super.getRule();
     }
-    
+
     public String toString() {
         return "[AfterRuleRemoved: package=" + getPackage() + " rule=" + getRule() + "]";
     }

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/AgendaEventSupport.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/AgendaEventSupport.java	2007-10-03 00:28:04 UTC (rev 15531)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/AgendaEventSupport.java	2007-10-03 03:14:31 UTC (rev 15532)
@@ -35,8 +35,8 @@
     /**
      * 
      */
-    private static final long   serialVersionUID = 400L;
-    private final List          listeners        = Collections.synchronizedList( new ArrayList() );
+    private static final long serialVersionUID = 400L;
+    private final List        listeners        = Collections.synchronizedList( new ArrayList() );
 
     public AgendaEventSupport() {
     }
@@ -105,7 +105,8 @@
         }
     }
 
-    public void fireAfterActivationFired(final Activation activation, final InternalWorkingMemory workingMemory) {
+    public void fireAfterActivationFired(final Activation activation,
+                                         final InternalWorkingMemory workingMemory) {
         if ( this.listeners.isEmpty() ) {
             return;
         }
@@ -118,7 +119,8 @@
         }
     }
 
-    public void fireAgendaGroupPopped(final AgendaGroup agendaGroup, final InternalWorkingMemory workingMemory) {
+    public void fireAgendaGroupPopped(final AgendaGroup agendaGroup,
+                                      final InternalWorkingMemory workingMemory) {
         if ( this.listeners.isEmpty() ) {
             return;
         }
@@ -131,7 +133,8 @@
         }
     }
 
-    public void fireAgendaGroupPushed(final AgendaGroup agendaGroup, final InternalWorkingMemory workingMemory) {
+    public void fireAgendaGroupPushed(final AgendaGroup agendaGroup,
+                                      final InternalWorkingMemory workingMemory) {
         if ( this.listeners.isEmpty() ) {
             return;
         }

Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/BeforeFunctionRemovedEvent.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/BeforeFunctionRemovedEvent.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/BeforeFunctionRemovedEvent.java	2007-10-03 03:14:31 UTC (rev 15532)
@@ -0,0 +1,41 @@
+package org.drools.event;
+
+/*
+ * Copyright 2005 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.
+ */
+
+import org.drools.RuleBase;
+import org.drools.rule.Package;
+
+public class BeforeFunctionRemovedEvent extends RuleBaseEvent {
+
+    private static final long serialVersionUID = 400L;
+
+    public BeforeFunctionRemovedEvent(final RuleBase ruleBase,
+                                      final Package pkg,
+                                      final String function) {
+        super( ruleBase,
+               pkg,
+               function );
+    }
+
+    public Object getSource() {
+        return super.getRule();
+    }
+
+    public String toString() {
+        return "[BeforeFunctionRemoved: package=" + getPackage() + " function=" + getFunction() + "]";
+    }
+}
\ No newline at end of file

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/BeforePackageAddedEvent.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/BeforePackageAddedEvent.java	2007-10-03 00:28:04 UTC (rev 15531)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/BeforePackageAddedEvent.java	2007-10-03 03:14:31 UTC (rev 15532)
@@ -16,14 +16,17 @@
  * limitations under the License.
  */
 
+import org.drools.RuleBase;
 import org.drools.rule.Package;
 
 public class BeforePackageAddedEvent extends RuleBaseEvent {
 
     private static final long serialVersionUID = 400L;
 
-    public BeforePackageAddedEvent(final Package pkg) {
-        super( pkg, null );
+    public BeforePackageAddedEvent(final RuleBase ruleBase,
+                                   final Package pkg) {
+        super( ruleBase,
+               pkg );
     }
 
     public String toString() {

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/BeforePackageRemovedEvent.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/BeforePackageRemovedEvent.java	2007-10-03 00:28:04 UTC (rev 15531)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/BeforePackageRemovedEvent.java	2007-10-03 03:14:31 UTC (rev 15532)
@@ -16,14 +16,17 @@
  * limitations under the License.
  */
 
+import org.drools.RuleBase;
 import org.drools.rule.Package;
 
 public class BeforePackageRemovedEvent extends RuleBaseEvent {
 
     private static final long serialVersionUID = 400L;
 
-    public BeforePackageRemovedEvent(final Package pkg) {
-        super( pkg, null );
+    public BeforePackageRemovedEvent(final RuleBase ruleBase,
+                                     final Package pkg) {
+        super( ruleBase,
+               pkg );
     }
 
     public String toString() {

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/BeforeRuleAddedEvent.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/BeforeRuleAddedEvent.java	2007-10-03 00:28:04 UTC (rev 15531)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/BeforeRuleAddedEvent.java	2007-10-03 03:14:31 UTC (rev 15532)
@@ -16,6 +16,7 @@
  * limitations under the License.
  */
 
+import org.drools.RuleBase;
 import org.drools.rule.Package;
 import org.drools.rule.Rule;
 
@@ -23,14 +24,18 @@
 
     private static final long serialVersionUID = 400L;
 
-    public BeforeRuleAddedEvent(final Package pkg, final Rule rule) {
-        super( pkg, rule );
+    public BeforeRuleAddedEvent(final RuleBase ruleBase,
+                                final Package pkg,
+                                final Rule rule) {
+        super( ruleBase,
+               pkg,
+               rule );
     }
-    
+
     public Object getSource() {
         return super.getRule();
     }
-    
+
     public String toString() {
         return "[BeforeRuleAdded: package=" + getPackage() + " rule=" + getRule() + "]";
     }

Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/BeforeRuleBaseLockedEvent.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/BeforeRuleBaseLockedEvent.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/BeforeRuleBaseLockedEvent.java	2007-10-03 03:14:31 UTC (rev 15532)
@@ -0,0 +1,32 @@
+package org.drools.event;
+
+/*
+ * Copyright 2005 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.
+ */
+
+import org.drools.RuleBase;
+
+public class BeforeRuleBaseLockedEvent extends RuleBaseEvent {
+
+    private static final long serialVersionUID = 400L;
+
+    public BeforeRuleBaseLockedEvent(final RuleBase ruleBase) {
+        super( ruleBase );
+    }
+
+    public String toString() {
+        return "[BeforeRuleBaseLocked: ruleBase=" + getRuleBase() + "]";
+    }
+}
\ No newline at end of file

Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/BeforeRuleBaseUnlockedEvent.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/BeforeRuleBaseUnlockedEvent.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/BeforeRuleBaseUnlockedEvent.java	2007-10-03 03:14:31 UTC (rev 15532)
@@ -0,0 +1,32 @@
+package org.drools.event;
+
+/*
+ * Copyright 2005 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.
+ */
+
+import org.drools.RuleBase;
+
+public class BeforeRuleBaseUnlockedEvent extends RuleBaseEvent {
+
+    private static final long serialVersionUID = 400L;
+
+    public BeforeRuleBaseUnlockedEvent(final RuleBase ruleBase) {
+        super( ruleBase );
+    }
+
+    public String toString() {
+        return "[BeforeRuleBaseUnlocked: ruleBase=" + getRuleBase() + "]";
+    }
+}
\ No newline at end of file

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/BeforeRuleRemovedEvent.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/BeforeRuleRemovedEvent.java	2007-10-03 00:28:04 UTC (rev 15531)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/BeforeRuleRemovedEvent.java	2007-10-03 03:14:31 UTC (rev 15532)
@@ -16,6 +16,7 @@
  * limitations under the License.
  */
 
+import org.drools.RuleBase;
 import org.drools.rule.Package;
 import org.drools.rule.Rule;
 
@@ -23,14 +24,18 @@
 
     private static final long serialVersionUID = 400L;
 
-    public BeforeRuleRemovedEvent(final Package pkg, final Rule rule) {
-        super( pkg, rule );
+    public BeforeRuleRemovedEvent(final RuleBase ruleBase,
+                                  final Package pkg,
+                                  final Rule rule) {
+        super( ruleBase,
+               pkg,
+               rule );
     }
-    
+
     public Object getSource() {
         return super.getRule();
     }
-    
+
     public String toString() {
         return "[BeforeRuleRemoved: package=" + getPackage() + " rule=" + getRule() + "]";
     }

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/DebugRuleFlowEventListener.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/DebugRuleFlowEventListener.java	2007-10-03 00:28:04 UTC (rev 15531)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/DebugRuleFlowEventListener.java	2007-10-03 03:14:31 UTC (rev 15532)
@@ -6,23 +6,23 @@
     implements
     RuleFlowEventListener {
 
-    public void ruleFlowCompleted(RuleFlowCompletedEvent event,
-                                  WorkingMemory workingMemory) {
+    public void ruleFlowCompleted(final RuleFlowCompletedEvent event,
+                                  final WorkingMemory workingMemory) {
         System.err.println( event );
     }
 
-    public void ruleFlowGroupActivated(RuleFlowGroupActivatedEvent event,
-                                       WorkingMemory workingMemory) {
+    public void ruleFlowGroupActivated(final RuleFlowGroupActivatedEvent event,
+                                       final WorkingMemory workingMemory) {
         System.err.println( event );
     }
 
-    public void ruleFlowGroupDeactivated(RuleFlowGroupDeactivatedEvent event,
-                                         WorkingMemory workingMemory) {
+    public void ruleFlowGroupDeactivated(final RuleFlowGroupDeactivatedEvent event,
+                                         final WorkingMemory workingMemory) {
         System.err.println( event );
     }
 
-    public void ruleFlowStarted(RuleFlowStartedEvent event,
-                                WorkingMemory workingMemory) {
+    public void ruleFlowStarted(final RuleFlowStartedEvent event,
+                                final WorkingMemory workingMemory) {
         System.err.println( event );
     }
 

Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/DefaultRuleBaseEventListener.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/DefaultRuleBaseEventListener.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/DefaultRuleBaseEventListener.java	2007-10-03 03:14:31 UTC (rev 15532)
@@ -0,0 +1,78 @@
+package org.drools.event;
+/*
+ * Copyright 2005 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.
+ */
+
+
+public class DefaultRuleBaseEventListener
+    implements
+    RuleBaseEventListener {
+
+    public void afterFunctionRemoved(AfterFunctionRemovedEvent event) {
+        // intentionally left blank
+    }
+
+    public void afterPackageAdded(AfterPackageAddedEvent event) {
+        // intentionally left blank
+    }
+
+    public void afterPackageRemoved(AfterPackageRemovedEvent event) {
+        // intentionally left blank
+    }
+
+    public void afterRuleAdded(AfterRuleAddedEvent event) {
+        // intentionally left blank
+    }
+
+    public void afterRuleBaseLocked(AfterRuleBaseLockedEvent event) {
+        // intentionally left blank
+    }
+
+    public void afterRuleBaseUnlocked(AfterRuleBaseUnlockedEvent event) {
+        // intentionally left blank
+    }
+
+    public void afterRuleRemoved(AfterRuleRemovedEvent event) {
+        // intentionally left blank
+    }
+
+    public void beforeFunctionRemoved(BeforeFunctionRemovedEvent event) {
+        // intentionally left blank
+    }
+
+    public void beforePackageAdded(BeforePackageAddedEvent event) {
+        // intentionally left blank
+    }
+
+    public void beforePackageRemoved(BeforePackageRemovedEvent event) {
+        // intentionally left blank
+    }
+
+    public void beforeRuleAdded(BeforeRuleAddedEvent event) {
+        // intentionally left blank
+    }
+
+    public void beforeRuleBaseLocked(BeforeRuleBaseLockedEvent event) {
+        // intentionally left blank
+    }
+
+    public void beforeRuleBaseUnlocked(BeforeRuleBaseUnlockedEvent event) {
+        // intentionally left blank
+    }
+
+    public void beforeRuleRemoved(BeforeRuleRemovedEvent event) {
+        // intentionally left blank
+    }
+}

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/DefaultRuleFlowEventListener.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/DefaultRuleFlowEventListener.java	2007-10-03 00:28:04 UTC (rev 15531)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/DefaultRuleFlowEventListener.java	2007-10-03 03:14:31 UTC (rev 15532)
@@ -6,23 +6,23 @@
     implements
     RuleFlowEventListener {
 
-    public void ruleFlowCompleted(RuleFlowCompletedEvent event,
-                                  WorkingMemory workingMemory) {
+    public void ruleFlowCompleted(final RuleFlowCompletedEvent event,
+                                  final WorkingMemory workingMemory) {
         // intentionally left blank
     }
 
-    public void ruleFlowGroupActivated(RuleFlowGroupActivatedEvent event,
-                                       WorkingMemory workingMemory) {
+    public void ruleFlowGroupActivated(final RuleFlowGroupActivatedEvent event,
+                                       final WorkingMemory workingMemory) {
         // intentionally left blank
     }
 
-    public void ruleFlowGroupDeactivated(RuleFlowGroupDeactivatedEvent event,
-                                         WorkingMemory workingMemory) {
+    public void ruleFlowGroupDeactivated(final RuleFlowGroupDeactivatedEvent event,
+                                         final WorkingMemory workingMemory) {
         // intentionally left blank
     }
 
-    public void ruleFlowStarted(RuleFlowStartedEvent event,
-                                WorkingMemory workingMemory) {
+    public void ruleFlowStarted(final RuleFlowStartedEvent event,
+                                final WorkingMemory workingMemory) {
         // intentionally left blank
     }
 

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/ObjectUpdatedEvent.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/ObjectUpdatedEvent.java	2007-10-03 00:28:04 UTC (rev 15531)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/ObjectUpdatedEvent.java	2007-10-03 03:14:31 UTC (rev 15532)
@@ -33,10 +33,10 @@
     private final Object      object;
 
     public ObjectUpdatedEvent(final WorkingMemory workingMemory,
-                               final PropagationContext propagationContext,
-                               final FactHandle handle,
-                               final Object oldObject,
-                               final Object object) {
+                              final PropagationContext propagationContext,
+                              final FactHandle handle,
+                              final Object oldObject,
+                              final Object object) {
         super( workingMemory,
                propagationContext );
         this.handle = handle;

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/RuleBaseEvent.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/RuleBaseEvent.java	2007-10-03 00:28:04 UTC (rev 15531)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/RuleBaseEvent.java	2007-10-03 03:14:31 UTC (rev 15532)
@@ -17,27 +17,70 @@
  */
 
 import java.util.EventObject;
+
+import org.drools.RuleBase;
 import org.drools.rule.Package;
 import org.drools.rule.Rule;
 
 public class RuleBaseEvent extends EventObject {
 
     private static final long serialVersionUID = 400L;
-    private final Package pkg;
-    private final Rule rule;
+    private final RuleBase    ruleBase;
+    private final Package     pkg;
+    private final Rule        rule;
+    private final String      function;
 
-    public RuleBaseEvent(final Package pkg, final Rule rule) {
-        super( pkg );
+    public RuleBaseEvent(final RuleBase ruleBase) {
+        super( ruleBase );
+        this.ruleBase = ruleBase;
+        this.pkg = null;
+        this.rule = null;
+        this.function = null;
+    }
+
+    public RuleBaseEvent(final RuleBase ruleBase,
+                         final Package pkg) {
+        super( ruleBase );
+        this.ruleBase = ruleBase;
         this.pkg = pkg;
+        this.rule = null;
+        this.function = null;
+    }
+
+    public RuleBaseEvent(final RuleBase ruleBase,
+                         final Package pkg,
+                         final Rule rule) {
+        super( ruleBase );
+        this.ruleBase = ruleBase;
+        this.pkg = pkg;
         this.rule = rule;
+        this.function = null;
     }
 
+    public RuleBaseEvent(final RuleBase ruleBase,
+                         final Package pkg,
+                         final String function) {
+        super( ruleBase );
+        this.ruleBase = ruleBase;
+        this.pkg = pkg;
+        this.rule = null;
+        this.function = function;
+    }
+
+    public RuleBase getRuleBase() {
+        return this.ruleBase;
+    }
+
     public Package getPackage() {
         return this.pkg;
     }
-    
+
     public Rule getRule() {
         return this.rule;
     }
 
+    public String getFunction() {
+        return this.function;
+    }
+
 }
\ No newline at end of file

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/RuleBaseEventListener.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/RuleBaseEventListener.java	2007-10-03 00:28:04 UTC (rev 15531)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/RuleBaseEventListener.java	2007-10-03 03:14:31 UTC (rev 15532)
@@ -31,6 +31,30 @@
     void afterPackageRemoved(AfterPackageRemovedEvent event);
 
     /**
+     * Method called before a rule base is locked
+     * @param event
+     */
+    void beforeRuleBaseLocked(BeforeRuleBaseLockedEvent event);
+
+    /**
+     * Method called after a rule base is locked
+     * @param event
+     */
+    void afterRuleBaseLocked(AfterRuleBaseLockedEvent event);
+
+    /**
+     * Method called before a rule base is unlocked
+     * @param event
+     */
+    void beforeRuleBaseUnlocked(BeforeRuleBaseUnlockedEvent event);
+
+    /**
+     * Method called after a rule base is unlocked
+     * @param event
+     */
+    void afterRuleBaseUnlocked(AfterRuleBaseUnlockedEvent event);
+
+    /**
      * Method called before a new rule is added to the rule base
      * @param event
      */
@@ -54,4 +78,16 @@
      */
     void afterRuleRemoved(AfterRuleRemovedEvent event);
 
+    /**
+     * Method called before a function is removed from the rule base
+     * @param event
+     */
+    void beforeFunctionRemoved(BeforeFunctionRemovedEvent event);
+
+    /**
+     * Method called after a function is removed from the rule base
+     * @param event
+     */
+    void afterFunctionRemoved(AfterFunctionRemovedEvent event);
+
 }

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/RuleBaseEventSupport.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/RuleBaseEventSupport.java	2007-10-03 00:28:04 UTC (rev 15531)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/RuleBaseEventSupport.java	2007-10-03 03:14:31 UTC (rev 15532)
@@ -20,8 +20,9 @@
 import java.util.Collections;
 import java.util.List;
 
+import org.drools.RuleBase;
+import org.drools.rule.Rule;
 import org.drools.rule.Package;
-import org.drools.rule.Rule;
 
 /**
  * 
@@ -35,8 +36,10 @@
      */
     private static final long serialVersionUID = 400L;
     private final List        listeners        = Collections.synchronizedList( new ArrayList() );
+    private transient RuleBase    ruleBase;
 
-    public RuleBaseEventSupport() {
+    public RuleBaseEventSupport(final RuleBase ruleBase) {
+        this.ruleBase = ruleBase;
     }
 
     public void addEventListener(final RuleBaseEventListener listener) {
@@ -44,6 +47,10 @@
             this.listeners.add( listener );
         }
     }
+    
+    public void setRuleBase(RuleBase ruleBase) {
+        this.ruleBase = ruleBase;
+    }
 
     public void removeEventListener(final RuleBaseEventListener listener) {
         this.listeners.remove( listener );
@@ -61,61 +68,115 @@
         return this.listeners.isEmpty();
     }
 
-    public void fireBeforePackageAdded(Package newPkg) {
+    public void fireBeforePackageAdded(final Package newPkg) {
         if ( this.listeners.isEmpty() ) {
             return;
         }
 
-        final BeforePackageAddedEvent event = new BeforePackageAddedEvent( newPkg );
+        final BeforePackageAddedEvent event = new BeforePackageAddedEvent( this.ruleBase,
+                                                                           newPkg );
 
         for ( int i = 0, size = this.listeners.size(); i < size; i++ ) {
             ((RuleBaseEventListener) this.listeners.get( i )).beforePackageAdded( event );
         }
     }
 
-    public void fireAfterPackageAdded(Package newPkg) {
+    public void fireAfterPackageAdded(final Package newPkg) {
         if ( this.listeners.isEmpty() ) {
             return;
         }
 
-        final AfterPackageAddedEvent event = new AfterPackageAddedEvent( newPkg );
+        final AfterPackageAddedEvent event = new AfterPackageAddedEvent( this.ruleBase,
+                                                                         newPkg );
 
         for ( int i = 0, size = this.listeners.size(); i < size; i++ ) {
             ((RuleBaseEventListener) this.listeners.get( i )).afterPackageAdded( event );
         }
     }
 
-    public void fireBeforePackageRemoved(Package pkg) {
+    public void fireBeforePackageRemoved(final Package pkg) {
         if ( this.listeners.isEmpty() ) {
             return;
         }
 
-        final BeforePackageRemovedEvent event = new BeforePackageRemovedEvent( pkg );
+        final BeforePackageRemovedEvent event = new BeforePackageRemovedEvent( this.ruleBase,
+                                                                               pkg );
 
         for ( int i = 0, size = this.listeners.size(); i < size; i++ ) {
             ((RuleBaseEventListener) this.listeners.get( i )).beforePackageRemoved( event );
         }
     }
 
-    public void fireAfterPackageRemoved(Package pkg) {
+    public void fireAfterPackageRemoved(final Package pkg) {
         if ( this.listeners.isEmpty() ) {
             return;
         }
 
-        final AfterPackageRemovedEvent event = new AfterPackageRemovedEvent( pkg );
+        final AfterPackageRemovedEvent event = new AfterPackageRemovedEvent( this.ruleBase,
+                                                                             pkg );
 
         for ( int i = 0, size = this.listeners.size(); i < size; i++ ) {
             ((RuleBaseEventListener) this.listeners.get( i )).afterPackageRemoved( event );
         }
     }
 
-    public void fireBeforeRuleAdded(Package newPkg,
-                                    Rule rule) {
+    //--
+    public void fireBeforeRuleBaseLocked() {
         if ( this.listeners.isEmpty() ) {
             return;
         }
 
-        final BeforeRuleAddedEvent event = new BeforeRuleAddedEvent( newPkg,
+        final BeforeRuleBaseLockedEvent event = new BeforeRuleBaseLockedEvent( this.ruleBase );
+
+        for ( int i = 0, size = this.listeners.size(); i < size; i++ ) {
+            ((RuleBaseEventListener) this.listeners.get( i )).beforeRuleBaseLocked( event );
+        }
+    }
+
+    public void fireAfterRuleBaseLocked() {
+        if ( this.listeners.isEmpty() ) {
+            return;
+        }
+
+        final AfterRuleBaseLockedEvent event = new AfterRuleBaseLockedEvent( this.ruleBase );
+
+        for ( int i = 0, size = this.listeners.size(); i < size; i++ ) {
+            ((RuleBaseEventListener) this.listeners.get( i )).afterRuleBaseLocked( event );
+        }
+    }
+
+    public void fireBeforeRuleBaseUnlocked() {
+        if ( this.listeners.isEmpty() ) {
+            return;
+        }
+
+        final BeforeRuleBaseUnlockedEvent event = new BeforeRuleBaseUnlockedEvent( this.ruleBase );
+
+        for ( int i = 0, size = this.listeners.size(); i < size; i++ ) {
+            ((RuleBaseEventListener) this.listeners.get( i )).beforeRuleBaseUnlocked( event );
+        }
+    }
+
+    public void fireAfterRuleBaseUnlocked() {
+        if ( this.listeners.isEmpty() ) {
+            return;
+        }
+
+        final AfterRuleBaseUnlockedEvent event = new AfterRuleBaseUnlockedEvent( this.ruleBase );
+
+        for ( int i = 0, size = this.listeners.size(); i < size; i++ ) {
+            ((RuleBaseEventListener) this.listeners.get( i )).afterRuleBaseUnlocked( event );
+        }
+    }
+
+    public void fireBeforeRuleAdded(final Package newPkg,
+                                    final Rule rule) {
+        if ( this.listeners.isEmpty() ) {
+            return;
+        }
+
+        final BeforeRuleAddedEvent event = new BeforeRuleAddedEvent( this.ruleBase,
+                                                                     newPkg,
                                                                      rule );
 
         for ( int i = 0, size = this.listeners.size(); i < size; i++ ) {
@@ -123,13 +184,14 @@
         }
     }
 
-    public void fireAfterRuleAdded(Package newPkg,
-                                   Rule rule) {
+    public void fireAfterRuleAdded(final Package newPkg,
+                                   final Rule rule) {
         if ( this.listeners.isEmpty() ) {
             return;
         }
 
-        final AfterRuleAddedEvent event = new AfterRuleAddedEvent( newPkg,
+        final AfterRuleAddedEvent event = new AfterRuleAddedEvent( this.ruleBase,
+                                                                   newPkg,
                                                                    rule );
 
         for ( int i = 0, size = this.listeners.size(); i < size; i++ ) {
@@ -137,13 +199,14 @@
         }
     }
 
-    public void fireBeforeRuleRemoved(Package pkg,
-                                      Rule rule) {
+    public void fireBeforeRuleRemoved(final Package pkg,
+                                      final Rule rule) {
         if ( this.listeners.isEmpty() ) {
             return;
         }
 
-        final BeforeRuleRemovedEvent event = new BeforeRuleRemovedEvent( pkg,
+        final BeforeRuleRemovedEvent event = new BeforeRuleRemovedEvent( this.ruleBase,
+                                                                         pkg,
                                                                          rule );
 
         for ( int i = 0, size = this.listeners.size(); i < size; i++ ) {
@@ -151,13 +214,14 @@
         }
     }
 
-    public void fireAfterRuleRemoved(Package pkg,
-                                     Rule rule) {
+    public void fireAfterRuleRemoved(final Package pkg,
+                                     final Rule rule) {
         if ( this.listeners.isEmpty() ) {
             return;
         }
 
-        final AfterRuleRemovedEvent event = new AfterRuleRemovedEvent( pkg,
+        final AfterRuleRemovedEvent event = new AfterRuleRemovedEvent( this.ruleBase,
+                                                                       pkg,
                                                                        rule );
 
         for ( int i = 0, size = this.listeners.size(); i < size; i++ ) {
@@ -165,4 +229,34 @@
         }
     }
 
+    public void fireBeforeFunctionRemoved(final Package pkg,
+                                          final String function) {
+        if ( this.listeners.isEmpty() ) {
+            return;
+        }
+
+        final BeforeFunctionRemovedEvent event = new BeforeFunctionRemovedEvent( this.ruleBase,
+                                                                                 pkg,
+                                                                                 function );
+
+        for ( int i = 0, size = this.listeners.size(); i < size; i++ ) {
+            ((RuleBaseEventListener) this.listeners.get( i )).beforeFunctionRemoved( event );
+        }
+    }
+
+    public void fireAfterFunctionRemoved(final Package pkg,
+                                         final String function) {
+        if ( this.listeners.isEmpty() ) {
+            return;
+        }
+
+        final AfterFunctionRemovedEvent event = new AfterFunctionRemovedEvent( this.ruleBase,
+                                                                               pkg,
+                                                                               function );
+
+        for ( int i = 0, size = this.listeners.size(); i < size; i++ ) {
+            ((RuleBaseEventListener) this.listeners.get( i )).afterFunctionRemoved( event );
+        }
+    }
+
 }
\ No newline at end of file

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/RuleFlowCompletedEvent.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/RuleFlowCompletedEvent.java	2007-10-03 00:28:04 UTC (rev 15531)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/RuleFlowCompletedEvent.java	2007-10-03 03:14:31 UTC (rev 15532)
@@ -23,9 +23,9 @@
  */
 public class RuleFlowCompletedEvent extends RuleFlowEvent {
 
-	private static final long serialVersionUID = 400L;
+    private static final long serialVersionUID = 400L;
 
-	public RuleFlowCompletedEvent(final RuleFlowProcessInstance instance) {
+    public RuleFlowCompletedEvent(final RuleFlowProcessInstance instance) {
         super( instance );
     }
 

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/RuleFlowEvent.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/RuleFlowEvent.java	2007-10-03 00:28:04 UTC (rev 15531)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/RuleFlowEvent.java	2007-10-03 03:14:31 UTC (rev 15532)
@@ -25,9 +25,9 @@
  */
 public class RuleFlowEvent extends EventObject {
 
-	private static final long serialVersionUID = 400L;
+    private static final long serialVersionUID = 400L;
 
-	public RuleFlowEvent(final RuleFlowProcessInstance instance) {
+    public RuleFlowEvent(final RuleFlowProcessInstance instance) {
         super( instance );
     }
 

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/RuleFlowEventListener.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/RuleFlowEventListener.java	2007-10-03 00:28:04 UTC (rev 15531)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/RuleFlowEventListener.java	2007-10-03 03:14:31 UTC (rev 15532)
@@ -23,8 +23,10 @@
 /**
  * @author <a href="mailto:kris_verlaenen at hotmail.com">Kris Verlaenen</a>
  */
-public interface RuleFlowEventListener extends EventListener {
-	
+public interface RuleFlowEventListener
+    extends
+    EventListener {
+
     void ruleFlowStarted(RuleFlowStartedEvent event,
                          WorkingMemory workingMemory);
 
@@ -36,5 +38,5 @@
 
     void ruleFlowGroupDeactivated(RuleFlowGroupDeactivatedEvent event,
                                   WorkingMemory workingMemory);
-    
+
 }
\ No newline at end of file

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/RuleFlowEventSupport.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/RuleFlowEventSupport.java	2007-10-03 00:28:04 UTC (rev 15531)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/RuleFlowEventSupport.java	2007-10-03 03:14:31 UTC (rev 15532)
@@ -21,7 +21,6 @@
 import java.util.Collections;
 import java.util.List;
 
-import org.drools.WorkingMemory;
 import org.drools.common.InternalWorkingMemory;
 import org.drools.ruleflow.instance.RuleFlowProcessInstance;
 import org.drools.spi.RuleFlowGroup;
@@ -29,10 +28,12 @@
 /**
  * @author <a href="mailto:kris_verlaenen at hotmail.com">Kris Verlaenen</a>
  */
-public class RuleFlowEventSupport implements Serializable {
+public class RuleFlowEventSupport
+    implements
+    Serializable {
 
-	private static final long serialVersionUID = 400L;
-	private final List listeners = Collections.synchronizedList( new ArrayList() );
+    private static final long serialVersionUID = 400L;
+    private final List        listeners        = Collections.synchronizedList( new ArrayList() );
 
     public RuleFlowEventSupport() {
     }
@@ -59,7 +60,8 @@
         return this.listeners.isEmpty();
     }
 
-    public void fireRuleFlowProcessStarted(final RuleFlowProcessInstance instance, final InternalWorkingMemory workingMemory) {
+    public void fireRuleFlowProcessStarted(final RuleFlowProcessInstance instance,
+                                           final InternalWorkingMemory workingMemory) {
         if ( this.listeners.isEmpty() ) {
             return;
         }
@@ -67,12 +69,13 @@
         final RuleFlowStartedEvent event = new RuleFlowStartedEvent( instance );
 
         for ( int i = 0, size = this.listeners.size(); i < size; i++ ) {
-            ((RuleFlowEventListener) this.listeners.get( i ))
-            	.ruleFlowStarted( event, workingMemory );
+            ((RuleFlowEventListener) this.listeners.get( i )).ruleFlowStarted( event,
+                                                                               workingMemory );
         }
     }
 
-    public void fireRuleFlowProcessCompleted(final RuleFlowProcessInstance instance, final InternalWorkingMemory workingMemory) {
+    public void fireRuleFlowProcessCompleted(final RuleFlowProcessInstance instance,
+                                             final InternalWorkingMemory workingMemory) {
         if ( this.listeners.isEmpty() ) {
             return;
         }
@@ -80,12 +83,13 @@
         final RuleFlowCompletedEvent event = new RuleFlowCompletedEvent( instance );
 
         for ( int i = 0, size = this.listeners.size(); i < size; i++ ) {
-            ((RuleFlowEventListener) this.listeners.get( i ))
-            	.ruleFlowCompleted( event, workingMemory );
+            ((RuleFlowEventListener) this.listeners.get( i )).ruleFlowCompleted( event,
+                                                                                 workingMemory );
         }
     }
 
-    public void fireRuleFlowGroupActivated(final RuleFlowGroup ruleFlowGroup, final InternalWorkingMemory workingMemory) {
+    public void fireRuleFlowGroupActivated(final RuleFlowGroup ruleFlowGroup,
+                                           final InternalWorkingMemory workingMemory) {
         if ( this.listeners.isEmpty() ) {
             return;
         }
@@ -93,12 +97,13 @@
         final RuleFlowGroupActivatedEvent event = new RuleFlowGroupActivatedEvent( ruleFlowGroup );
 
         for ( int i = 0, size = this.listeners.size(); i < size; i++ ) {
-            ((RuleFlowEventListener) this.listeners.get( i ))
-            	.ruleFlowGroupActivated( event, workingMemory );
+            ((RuleFlowEventListener) this.listeners.get( i )).ruleFlowGroupActivated( event,
+                                                                                      workingMemory );
         }
     }
 
-    public void fireRuleFlowGroupDeactivated(final RuleFlowGroup ruleFlowGroup, final InternalWorkingMemory workingMemory) {
+    public void fireRuleFlowGroupDeactivated(final RuleFlowGroup ruleFlowGroup,
+                                             final InternalWorkingMemory workingMemory) {
         if ( this.listeners.isEmpty() ) {
             return;
         }
@@ -106,8 +111,8 @@
         final RuleFlowGroupDeactivatedEvent event = new RuleFlowGroupDeactivatedEvent( ruleFlowGroup );
 
         for ( int i = 0, size = this.listeners.size(); i < size; i++ ) {
-            ((RuleFlowEventListener) this.listeners.get( i ))
-            	.ruleFlowGroupDeactivated( event, workingMemory );
+            ((RuleFlowEventListener) this.listeners.get( i )).ruleFlowGroupDeactivated( event,
+                                                                                        workingMemory );
         }
     }
 

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/RuleFlowGroupActivatedEvent.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/RuleFlowGroupActivatedEvent.java	2007-10-03 00:28:04 UTC (rev 15531)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/RuleFlowGroupActivatedEvent.java	2007-10-03 03:14:31 UTC (rev 15532)
@@ -23,9 +23,9 @@
  */
 public class RuleFlowGroupActivatedEvent extends RuleFlowGroupEvent {
 
-	private static final long serialVersionUID = 400L;
+    private static final long serialVersionUID = 400L;
 
-	public RuleFlowGroupActivatedEvent(final RuleFlowGroup ruleFlowGroup) {
+    public RuleFlowGroupActivatedEvent(final RuleFlowGroup ruleFlowGroup) {
         super( ruleFlowGroup );
     }
 

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/RuleFlowGroupDeactivatedEvent.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/RuleFlowGroupDeactivatedEvent.java	2007-10-03 00:28:04 UTC (rev 15531)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/RuleFlowGroupDeactivatedEvent.java	2007-10-03 03:14:31 UTC (rev 15532)
@@ -23,9 +23,9 @@
  */
 public class RuleFlowGroupDeactivatedEvent extends RuleFlowGroupEvent {
 
-	private static final long serialVersionUID = 400L;
+    private static final long serialVersionUID = 400L;
 
-	public RuleFlowGroupDeactivatedEvent(final RuleFlowGroup ruleFlowGroup) {
+    public RuleFlowGroupDeactivatedEvent(final RuleFlowGroup ruleFlowGroup) {
         super( ruleFlowGroup );
     }
 

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/RuleFlowGroupEvent.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/RuleFlowGroupEvent.java	2007-10-03 00:28:04 UTC (rev 15531)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/RuleFlowGroupEvent.java	2007-10-03 03:14:31 UTC (rev 15532)
@@ -25,9 +25,9 @@
  */
 public class RuleFlowGroupEvent extends EventObject {
 
-	private static final long serialVersionUID = 400L;
+    private static final long serialVersionUID = 400L;
 
-	public RuleFlowGroupEvent(final RuleFlowGroup ruleFlowGroup) {
+    public RuleFlowGroupEvent(final RuleFlowGroup ruleFlowGroup) {
         super( ruleFlowGroup );
     }
 

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/RuleFlowStartedEvent.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/RuleFlowStartedEvent.java	2007-10-03 00:28:04 UTC (rev 15531)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/RuleFlowStartedEvent.java	2007-10-03 03:14:31 UTC (rev 15532)
@@ -23,9 +23,9 @@
  */
 public class RuleFlowStartedEvent extends RuleFlowEvent {
 
-	private static final long serialVersionUID = 400L;
+    private static final long serialVersionUID = 400L;
 
-	public RuleFlowStartedEvent(final RuleFlowProcessInstance instance) {
+    public RuleFlowStartedEvent(final RuleFlowProcessInstance instance) {
         super( instance );
     }
 

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/WorkingMemoryEventSupport.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/WorkingMemoryEventSupport.java	2007-10-03 00:28:04 UTC (rev 15531)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/WorkingMemoryEventSupport.java	2007-10-03 03:14:31 UTC (rev 15532)
@@ -22,7 +22,6 @@
 import java.util.List;
 
 import org.drools.FactHandle;
-import org.drools.WorkingMemory;
 import org.drools.common.InternalWorkingMemory;
 import org.drools.spi.PropagationContext;
 
@@ -35,8 +34,8 @@
     /**
      * 
      */
-    private static final long   serialVersionUID = 400L;
-    private final List          listeners        = Collections.synchronizedList( new ArrayList() );
+    private static final long serialVersionUID = 400L;
+    private final List        listeners        = Collections.synchronizedList( new ArrayList() );
 
     public WorkingMemoryEventSupport() {
     }
@@ -82,19 +81,19 @@
     }
 
     public void fireObjectUpdated(final PropagationContext propagationContext,
-                                   final FactHandle handle,
-                                   final Object oldObject,
-                                   final Object object,
-                                   final InternalWorkingMemory workingMemory) {
+                                  final FactHandle handle,
+                                  final Object oldObject,
+                                  final Object object,
+                                  final InternalWorkingMemory workingMemory) {
         if ( this.listeners.isEmpty() ) {
             return;
         }
 
         final ObjectUpdatedEvent event = new ObjectUpdatedEvent( workingMemory,
-                                                                   propagationContext,
-                                                                   handle,
-                                                                   oldObject,
-                                                                   object );
+                                                                 propagationContext,
+                                                                 handle,
+                                                                 oldObject,
+                                                                 object );
 
         for ( int i = 0, size = this.listeners.size(); i < size; i++ ) {
             ((WorkingMemoryEventListener) this.listeners.get( i )).objectUpdated( event );
@@ -104,7 +103,7 @@
     public void fireObjectRetracted(final PropagationContext propagationContext,
                                     final FactHandle handle,
                                     final Object oldObject,
-                                    final InternalWorkingMemory workingMemory ) {
+                                    final InternalWorkingMemory workingMemory) {
         if ( this.listeners.isEmpty() ) {
             return;
         }

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ReteooRuleBase.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ReteooRuleBase.java	2007-10-03 00:28:04 UTC (rev 15531)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ReteooRuleBase.java	2007-10-03 03:14:31 UTC (rev 15532)
@@ -36,6 +36,9 @@
 import org.drools.concurrent.CommandExecutor;
 import org.drools.concurrent.DefaultExecutorService;
 import org.drools.concurrent.ExecutorService;
+import org.drools.event.BeforeRuleBaseUnlockedEvent;
+import org.drools.event.DefaultRuleBaseEventListener;
+import org.drools.event.RuleBaseEventListener;
 import org.drools.rule.CompositePackageClassLoader;
 import org.drools.rule.InvalidPatternException;
 import org.drools.rule.Rule;
@@ -246,8 +249,56 @@
                                                                                  null,
                                                                                  null ) );
         }
+        
+        // setup event listener for fireAllRules on rulebase modifications
+        FireAllRulesBeforeUnlockEventListener listener =  new DefaultFireAllRulesBeforeUnlockEventListener();
+        listener.setSession( session );
+        addEventListener( listener );
+        
         return session;
     }
+    
+    public static interface FireAllRulesBeforeUnlockEventListener extends RuleBaseEventListener {
+        public void setSession(StatefulSession session);
+    }
+    
+    public static class DefaultFireAllRulesBeforeUnlockEventListener extends DefaultRuleBaseEventListener 
+    implements FireAllRulesBeforeUnlockEventListener {
+        private StatefulSession session;
+        
+        public DefaultFireAllRulesBeforeUnlockEventListener() {
+            
+        }
+        
+        public void setSession(StatefulSession session) {
+            this.session = session;
+        }
+        
+        public void beforeRuleBaseUnlocked(BeforeRuleBaseUnlockedEvent event) {
+            if ( session.getRuleBase().getAdditionsSinceLock() > 0 ) {
+                session.fireAllRules();
+            }
+        }
+    }
+    
+    public static class AsyncFireAllRulesBeforeUnlockEventListener extends DefaultRuleBaseEventListener 
+    implements FireAllRulesBeforeUnlockEventListener {
+        private StatefulSession session;
+        
+        public AsyncFireAllRulesBeforeUnlockEventListener() {
+            
+        }
+        
+        public void setSession(StatefulSession session) {
+            this.session = session;
+        }
+        
+        public void beforeRuleBaseUnlocked(BeforeRuleBaseUnlockedEvent event) {
+            if ( session.getRuleBase().getAdditionsSinceLock() > 0 ) { 
+                session.asyncFireAllRules();
+            }
+        }
+    }    
 
     public StatelessSession newStatelessSession() {
 

Modified: labs/jbossrules/trunk/drools-core/src/test/java/org/drools/event/RuleBaseEventListenerTest.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/test/java/org/drools/event/RuleBaseEventListenerTest.java	2007-10-03 00:28:04 UTC (rev 15531)
+++ labs/jbossrules/trunk/drools-core/src/test/java/org/drools/event/RuleBaseEventListenerTest.java	2007-10-03 03:14:31 UTC (rev 15532)
@@ -296,6 +296,36 @@
             this.beforeRuleRemoved++;
         }
 
+        public void afterFunctionRemoved(AfterFunctionRemovedEvent event) {
+            // TODO Auto-generated method stub
+            
+        }
+
+        public void afterRuleBaseLocked(AfterRuleBaseLockedEvent event) {
+            // TODO Auto-generated method stub
+            
+        }
+
+        public void afterRuleBaseUnlocked(AfterRuleBaseUnlockedEvent event) {
+            // TODO Auto-generated method stub
+            
+        }
+
+        public void beforeFunctionRemoved(BeforeFunctionRemovedEvent event) {
+            // TODO Auto-generated method stub
+            
+        }
+
+        public void beforeRuleBaseLocked(BeforeRuleBaseLockedEvent event) {
+            // TODO Auto-generated method stub
+            
+        }
+
+        public void beforeRuleBaseUnlocked(BeforeRuleBaseUnlockedEvent event) {
+            // TODO Auto-generated method stub
+            
+        }
+
     }
 
 }




More information about the jboss-svn-commits mailing list