[jboss-svn-commits] JBL Code SVN: r33901 - in labs/jbossrules/trunk: drools-compiler/src/test/java/org/drools/agent and 2 other directories.

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Thu Jul 15 10:27:46 EDT 2010


Author: eaa
Date: 2010-07-15 10:27:46 -0400 (Thu, 15 Jul 2010)
New Revision: 33901

Added:
   labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/agent/KnowledgeAgentDisposeTest.java
Modified:
   labs/jbossrules/trunk/drools-api/src/main/java/org/drools/agent/KnowledgeAgent.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/agent/impl/KnowledgeAgentImpl.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/io/impl/ResourceChangeNotifierImpl.java
Log:
JBRULES-2570: KnowledgeAgent lacks a safe disposal method
	- Implemented dispose() method. This method will un-subscribe all the agent's resources listeners and stop the notification thread.
	- monitorResourceChangeEvents(false) now un-subscribe all the agent's resources listeners. The will be set up again when calling monitorResourceChangeEvents(true)
	- fixed a bug in ResourceChangeNotifierImpl that prevented listeners to be un subscribed properly

Modified: labs/jbossrules/trunk/drools-api/src/main/java/org/drools/agent/KnowledgeAgent.java
===================================================================
--- labs/jbossrules/trunk/drools-api/src/main/java/org/drools/agent/KnowledgeAgent.java	2010-07-15 14:03:00 UTC (rev 33900)
+++ labs/jbossrules/trunk/drools-api/src/main/java/org/drools/agent/KnowledgeAgent.java	2010-07-15 14:27:46 UTC (rev 33901)
@@ -60,4 +60,6 @@
     void applyChangeSet(ChangeSet changeSet);
 
     void setSystemEventListener(SystemEventListener listener);
+
+    void dispose();
 }

Added: labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/agent/KnowledgeAgentDisposeTest.java
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/agent/KnowledgeAgentDisposeTest.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/agent/KnowledgeAgentDisposeTest.java	2010-07-15 14:27:46 UTC (rev 33901)
@@ -0,0 +1,435 @@
+package org.drools.agent;
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.Writer;
+import java.util.ArrayList;
+
+import junit.framework.TestCase;
+
+import org.drools.KnowledgeBase;
+import org.drools.KnowledgeBaseFactory;
+import org.drools.SystemEventListener;
+import org.drools.core.util.FileManager;
+import org.drools.event.knowledgeagent.AfterChangeSetAppliedEvent;
+import org.drools.event.knowledgeagent.AfterChangeSetProcessedEvent;
+import org.drools.event.knowledgeagent.AfterResourceProcessedEvent;
+import org.drools.event.knowledgeagent.BeforeChangeSetAppliedEvent;
+import org.drools.event.knowledgeagent.BeforeChangeSetProcessedEvent;
+import org.drools.event.knowledgeagent.BeforeResourceProcessedEvent;
+import org.drools.event.knowledgeagent.KnowledgeAgentEventListener;
+import org.drools.event.knowledgeagent.KnowledgeBaseUpdatedEvent;
+import org.drools.event.knowledgeagent.ResourceCompilationFailedEvent;
+import org.drools.io.ResourceChangeScannerConfiguration;
+import org.drools.io.ResourceFactory;
+import org.drools.io.impl.ResourceChangeNotifierImpl;
+import org.drools.io.impl.ResourceChangeScannerImpl;
+import org.drools.runtime.StatefulKnowledgeSession;
+import org.mortbay.jetty.Server;
+import org.mortbay.jetty.handler.ResourceHandler;
+
+public class KnowledgeAgentDisposeTest extends TestCase {
+
+    FileManager fileManager;
+    private Server server;
+    private final Object lock = new Object();
+    private volatile boolean kbaseUpdated;
+    private boolean compilationErrors;
+
+    private int resourceChangeNotificationCount = 0;
+
+
+    @Override
+    protected void setUp() throws Exception {
+        fileManager = new FileManager();
+        fileManager.setUp();
+        ((ResourceChangeScannerImpl) ResourceFactory.getResourceChangeScannerService()).reset();
+
+        ResourceFactory.getResourceChangeNotifierService().start();
+        ResourceFactory.getResourceChangeScannerService().start();
+
+        this.server = new Server(0);
+        ResourceHandler resourceHandler = new ResourceHandler();
+        resourceHandler.setResourceBase(fileManager.getRootDirectory().getPath());
+
+        server.setHandler(resourceHandler);
+
+        server.start();
+
+        this.kbaseUpdated = false;
+        this.resourceChangeNotificationCount = 0;
+    }
+
+    private int getPort() {
+        return this.server.getConnectors()[0].getLocalPort();
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        fileManager.tearDown();
+        ResourceFactory.getResourceChangeNotifierService().stop();
+        ResourceFactory.getResourceChangeScannerService().stop();
+        ((ResourceChangeNotifierImpl) ResourceFactory.getResourceChangeNotifierService()).reset();
+        ((ResourceChangeScannerImpl) ResourceFactory.getResourceChangeScannerService()).reset();
+
+        server.stop();
+    }
+
+    public void testMonitorResourceChangeEvents() throws Exception {
+
+        String header = "";
+        header += "package org.drools.test\n";
+        header += "import org.drools.Person\n\n";
+        header += "global java.util.List list\n\n";
+
+        //create a basic dsl file
+        File f1 = fileManager.newFile("myExpander.dsl");
+        Writer output = new BufferedWriter(new FileWriter(f1));
+        output.write(this.createCommonDSL(null));
+        output.close();
+
+        //create a basic dslr file
+        f1 = fileManager.newFile("rules.drl");
+        output = new BufferedWriter(new FileWriter(f1));
+        output.write(header);
+        output.write(this.createCommonDSLRRule("Rule1"));
+        output.close();
+
+        String xml = "";
+        xml += "<change-set xmlns='http://drools.org/drools-5.0/change-set'";
+        xml += "    xmlns:xs='http://www.w3.org/2001/XMLSchema-instance'";
+        xml += "    xs:schemaLocation='http://drools.org/drools-5.0/change-set drools-change-set-5.0.xsd' >";
+        xml += "    <add> ";
+        xml += "        <resource source='http://localhost:" + this.getPort() + "/rules.drl' type='DSLR' />";
+        xml += "        <resource source='http://localhost:" + this.getPort() + "/myExpander.dsl' type='DSL' />";
+        xml += "    </add> ";
+        xml += "</change-set>";
+        File fxml = fileManager.newFile("changeset.xml");
+        output = new BufferedWriter(new FileWriter(fxml));
+        output.write(xml);
+        output.close();
+
+        //Create a new Agent with newInstace=true
+        KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
+        KnowledgeAgent kagent = this.createKAgent(kbase, false);
+
+        //Agent: take care of them!
+        kagent.applyChangeSet(ResourceFactory.newUrlResource(fxml.toURI().toURL()));
+
+        kbaseUpdated = false;
+        resourceChangeNotificationCount = 0;
+        
+        Thread.sleep(2000);
+        //the dsl is now modified.
+        f1 = fileManager.newFile("myExpander.dsl");
+        output = new BufferedWriter(new FileWriter(f1));
+        output.write(this.createCommonDSL("name == \"John\""));
+        output.close();
+
+        //the drl file is marked as modified too
+        f1 = fileManager.newFile("rules.drl");
+        output = new BufferedWriter(new FileWriter(f1));
+        output.write(header);
+        output.write(this.createCommonDSLRRule("Rule1"));
+        output.close();
+
+
+        this.waitUntilKBaseUpdate();
+
+        //two resources were modified, but only one change set is created
+        assertEquals(1, resourceChangeNotificationCount);
+        resourceChangeNotificationCount = 0;
+        Thread.sleep(2000);
+
+        //let's add a new rule
+        f1 = fileManager.newFile("rules.drl");
+        output = new BufferedWriter(new FileWriter(f1));
+        output.write(header);
+        output.write(this.createCommonDSLRRule("Rule1"));
+        output.write(this.createCommonDSLRRule("Rule2"));
+        output.close();
+
+        this.waitUntilKBaseUpdate();
+
+        assertEquals(1, resourceChangeNotificationCount);
+        resourceChangeNotificationCount = 0;
+
+        //the kagent is stopped
+        kagent.monitorResourceChangeEvents(false);
+
+        //the drl file is marked as modified
+        f1 = fileManager.newFile("rules.drl");
+        output = new BufferedWriter(new FileWriter(f1));
+        output.write(header);
+        output.write(this.createCommonDSLRRule("Rule1"));
+        output.close();
+
+        //we can't wait until kbase update, because the agent is not monitoring
+        //change sets anymore
+        Thread.sleep(5000);
+
+        assertEquals(0, resourceChangeNotificationCount);
+
+
+        //let start the agent again
+        kagent.monitorResourceChangeEvents(true);
+
+        //the drl file is marked as modified
+        f1 = fileManager.newFile("rules.drl");
+        output = new BufferedWriter(new FileWriter(f1));
+        output.write(header);
+        output.write(this.createCommonDSLRRule("Rule1"));
+        output.close();
+
+         Thread.sleep(2000);
+
+        assertEquals(1, resourceChangeNotificationCount);
+
+        kagent.monitorResourceChangeEvents(false);
+    }
+
+
+    public void testDispose() throws Exception {
+
+        String header = "";
+        header += "package org.drools.test\n";
+        header += "import org.drools.Person\n\n";
+        header += "global java.util.List list\n\n";
+
+        //create a basic dsl file
+        File f1 = fileManager.newFile("myExpander.dsl");
+        Writer output = new BufferedWriter(new FileWriter(f1));
+        output.write(this.createCommonDSL(null));
+        output.close();
+
+        //create a basic dslr file
+        f1 = fileManager.newFile("rules.drl");
+        output = new BufferedWriter(new FileWriter(f1));
+        output.write(header);
+        output.write(this.createCommonDSLRRule("Rule1"));
+        output.close();
+
+        String xml = "";
+        xml += "<change-set xmlns='http://drools.org/drools-5.0/change-set'";
+        xml += "    xmlns:xs='http://www.w3.org/2001/XMLSchema-instance'";
+        xml += "    xs:schemaLocation='http://drools.org/drools-5.0/change-set drools-change-set-5.0.xsd' >";
+        xml += "    <add> ";
+        xml += "        <resource source='http://localhost:" + this.getPort() + "/rules.drl' type='DSLR' />";
+        xml += "        <resource source='http://localhost:" + this.getPort() + "/myExpander.dsl' type='DSL' />";
+        xml += "    </add> ";
+        xml += "</change-set>";
+        File fxml = fileManager.newFile("changeset.xml");
+        output = new BufferedWriter(new FileWriter(fxml));
+        output.write(xml);
+        output.close();
+
+        //Create a new Agent with newInstace=true
+        KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
+        KnowledgeAgent kagent = this.createKAgent(kbase, false);
+
+        //Agent: take care of them!
+        kagent.applyChangeSet(ResourceFactory.newUrlResource(fxml.toURI().toURL()));
+
+        kbaseUpdated = false;
+        resourceChangeNotificationCount = 0;
+
+        Thread.sleep(2000);
+        //the dsl is now modified.
+        f1 = fileManager.newFile("myExpander.dsl");
+        output = new BufferedWriter(new FileWriter(f1));
+        output.write(this.createCommonDSL("name == \"John\""));
+        output.close();
+
+        //the drl file is marked as modified too
+        f1 = fileManager.newFile("rules.drl");
+        output = new BufferedWriter(new FileWriter(f1));
+        output.write(header);
+        output.write(this.createCommonDSLRRule("Rule1"));
+        output.close();
+
+
+        this.waitUntilKBaseUpdate();
+
+        //two resources were modified, but only one change set is created
+        assertEquals(1, resourceChangeNotificationCount);
+        resourceChangeNotificationCount = 0;
+
+        //let us create a new ksession and fire all the rules
+        StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession();
+        ksession.setGlobal("list", new ArrayList<String>());
+        ksession.fireAllRules();
+
+        Thread.sleep(2000);
+
+        //let's add a new rule
+        f1 = fileManager.newFile("rules.drl");
+        output = new BufferedWriter(new FileWriter(f1));
+        output.write(header);
+        output.write(this.createCommonDSLRRule("Rule1"));
+        output.write(this.createCommonDSLRRule("Rule2"));
+        output.close();
+
+        this.waitUntilKBaseUpdate();
+
+        assertEquals(1, resourceChangeNotificationCount);
+        resourceChangeNotificationCount = 0;
+
+        //the old ksession can be reused
+        ksession.fireAllRules();
+
+
+        //We will try to dispose the kagent: but an active stateful ksession exists.
+        try{
+            kagent.dispose();
+            fail("The agent should failed");
+        } catch (IllegalStateException ex){
+        }
+
+        //We need to dispose the ksession first
+        ksession.dispose();
+
+        //Now it is safe to dispose the kagent
+        kagent.dispose();
+
+        //the drl file is marked as modified
+        f1 = fileManager.newFile("rules.drl");
+        output = new BufferedWriter(new FileWriter(f1));
+        output.write(header);
+        output.write(this.createCommonDSLRRule("Rule1"));
+        output.close();
+
+        //we can't wait until kbase update, because the agent is not monitoring
+        //change sets anymore
+        Thread.sleep(5000);
+
+        assertEquals(0, resourceChangeNotificationCount);
+
+
+
+
+    }
+
+
+    private KnowledgeAgent createKAgent(KnowledgeBase kbase, boolean newInstance) {
+        ResourceChangeScannerConfiguration sconf = ResourceFactory.getResourceChangeScannerService().newResourceChangeScannerConfiguration();
+        sconf.setProperty("drools.resource.scanner.interval", "2");
+        ResourceFactory.getResourceChangeScannerService().configure(sconf);
+
+        //System.setProperty(KnowledgeAgentFactory.PROVIDER_CLASS_NAME_PROPERTY_NAME, "org.drools.agent.impl.KnowledgeAgentProviderImpl");
+
+        KnowledgeAgentConfiguration aconf = KnowledgeAgentFactory.newKnowledgeAgentConfiguration();
+        aconf.setProperty("drools.agent.scanDirectories", "true");
+        aconf.setProperty("drools.agent.scanResources", "true");
+        // Testing incremental build here
+        aconf.setProperty("drools.agent.newInstance", "" + newInstance);
+
+        KnowledgeAgent kagent = KnowledgeAgentFactory.newKnowledgeAgent(
+                "test agent", kbase, aconf);
+
+        kagent.setSystemEventListener(new SystemEventListener() {
+
+            public void info(String message) {
+            }
+
+            public void info(String message, Object object) {
+            }
+
+            public void warning(String message) {
+            }
+
+            public void warning(String message, Object object) {
+            }
+
+            public void exception(String message, Throwable e) {
+            }
+
+            public void exception(Throwable e) {
+            }
+
+            public void debug(String message) {
+                if ("KnowledgeAgent received ChangeSet changed notification".equals(message)){
+                    resourceChangeNotificationCount++;
+                }
+            }
+
+            public void debug(String message, Object object) {
+            }
+        });
+
+        kagent.addEventListener(new KnowledgeAgentEventListener() {
+
+            public void beforeChangeSetApplied(BeforeChangeSetAppliedEvent event) {
+            }
+
+            public void afterChangeSetApplied(AfterChangeSetAppliedEvent event) {
+            }
+
+            public void beforeChangeSetProcessed(BeforeChangeSetProcessedEvent event) {
+            }
+
+            public void afterChangeSetProcessed(AfterChangeSetProcessedEvent event) {
+            }
+
+            public void beforeResourceProcessed(BeforeResourceProcessedEvent event) {
+            }
+
+            public void afterResourceProcessed(AfterResourceProcessedEvent event) {
+            }
+
+            public void knowledgeBaseUpdated(KnowledgeBaseUpdatedEvent event) {
+                System.out.println("KBase was updated");
+                synchronized (lock) {
+                    kbaseUpdated = true;
+                    lock.notifyAll();
+                }
+            }
+
+            public void resourceCompilationFailed(ResourceCompilationFailedEvent event) {
+                compilationErrors = true;
+            }
+        });
+
+        assertEquals("test agent", kagent.getName());
+
+        return kagent;
+    }
+
+    private String createCommonDSLRRule(String ruleName) {
+        StringBuilder sb = new StringBuilder();
+        sb.append("rule ");
+        sb.append(ruleName);
+        sb.append("\n");
+        sb.append("when\n");
+        sb.append("There is a Person\n");
+        sb.append("then\n");
+        sb.append("add rule's name to list;\n");
+        sb.append("end\n");
+
+        return sb.toString();
+    }
+
+    private String createCommonDSL(String restriction) {
+        StringBuilder sb = new StringBuilder();
+        sb.append("[condition][]There is a Person = Person(");
+        if (restriction != null) {
+            sb.append(restriction);
+        }
+        sb.append(")\n");
+        sb.append("[consequence][]add rule's name to list = list.add( drools.getRule().getName() );\n");
+        return sb.toString();
+    }
+
+    private void waitUntilKBaseUpdate() {
+        synchronized (lock) {
+            while (!kbaseUpdated) {
+                try {
+                    lock.wait();
+                } catch (InterruptedException e) {
+                }
+                System.out.println("Waking up!");
+            }
+            kbaseUpdated = false;
+        }
+    }
+}

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/agent/impl/KnowledgeAgentImpl.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/agent/impl/KnowledgeAgentImpl.java	2010-07-15 14:03:00 UTC (rev 33900)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/agent/impl/KnowledgeAgentImpl.java	2010-07-15 14:27:46 UTC (rev 33901)
@@ -16,6 +16,7 @@
 import org.drools.KnowledgeBase;
 import org.drools.KnowledgeBaseFactory;
 import org.drools.RuleBase;
+import org.drools.StatefulSession;
 import org.drools.SystemEventListener;
 import org.drools.SystemEventListenerFactory;
 import org.drools.agent.KnowledgeAgent;
@@ -77,9 +78,8 @@
     private ChangeSetNotificationDetector changeSetNotificationDetector;
     private SemanticModules semanticModules;
     private final RegisteredResourceMap registeredResources = new RegisteredResourceMap();
-    private Map<Resource,String> dslResources = new HashMap<Resource, String>();
+    private Map<Resource, String> dslResources = new HashMap<Resource, String>();
     private KnowledgeAgentEventSupport eventSupport = new KnowledgeAgentEventSupport();
-
     private KnowledgeBuilderConfiguration builderConfiguration;
 
     /**
@@ -188,14 +188,14 @@
              */
             for (Resource resource : changeSet.getResourcesAdded()) {
                 this.eventSupport.fireBeforeResourceProcessed(changeSet, resource, ((InternalResource) resource).getResourceType(), ResourceStatus.RESOURCE_ADDED);
-                if (((InternalResource) resource).getResourceType() == ResourceType.DSL){
+                if (((InternalResource) resource).getResourceType() == ResourceType.DSL) {
                     this.notifier.subscribeResourceChangeListener(this,
                             resource);
                     try {
                         this.retrieveDSLResource(resource);
                     } catch (IOException ex) {
                         this.listener.exception("KnowledgeAgent Fails trying to read DSL Resource: "
-                            + resource,ex);
+                                + resource, ex);
                     }
                 } else if (((InternalResource) resource).getResourceType() == ResourceType.CHANGE_SET) {
                     // @TODO We should not ignore an added change set
@@ -241,7 +241,7 @@
              */
             for (Resource resource : changeSet.getResourcesRemoved()) {
                 this.eventSupport.fireBeforeResourceProcessed(changeSet, resource, ((InternalResource) resource).getResourceType(), ResourceStatus.RESOURCE_MODIFIED);
-                if (((InternalResource) resource).getResourceType() == ResourceType.DSL){
+                if (((InternalResource) resource).getResourceType() == ResourceType.DSL) {
                     this.notifier.unsubscribeResourceChangeListener(this,
                             resource);
                     this.dslResources.remove(resource);
@@ -275,12 +275,12 @@
              */
             for (Resource resource : changeSet.getResourcesModified()) {
                 this.eventSupport.fireBeforeResourceProcessed(changeSet, resource, ((InternalResource) resource).getResourceType(), ResourceStatus.RESOURCE_REMOVED);
-                if (((InternalResource) resource).getResourceType() == ResourceType.DSL){
+                if (((InternalResource) resource).getResourceType() == ResourceType.DSL) {
                     try {
                         this.retrieveDSLResource(resource);
                     } catch (IOException ex) {
                         this.listener.exception("KnowledgeAgent Fails trying to read DSL Resource: "
-                            + resource,ex);
+                                + resource, ex);
                     }
                 } else if (((InternalResource) resource).getResourceType() == ResourceType.CHANGE_SET) {
                     // processChangeSet(resource, changeSetState);
@@ -596,9 +596,9 @@
      * is already a package, this builder is not used.
      * @return the package resulting of the compilation of resource.
      */
-    private KnowledgePackageImp createPackageFromResource(Resource resource,KnowledgeBuilder kbuilder) {
+    private KnowledgePackageImp createPackageFromResource(Resource resource, KnowledgeBuilder kbuilder) {
 
-        if (kbuilder == null){
+        if (kbuilder == null) {
             kbuilder = this.createKBuilder();
         }
 
@@ -609,7 +609,7 @@
                 this.listener.warning(
                         "KnowledgeAgent has KnowledgeBuilder errors ", kbuilder.getErrors());
             }
-            if (kbuilder.getKnowledgePackages().iterator().hasNext()){
+            if (kbuilder.getKnowledgePackages().iterator().hasNext()) {
                 return (KnowledgePackageImp) kbuilder.getKnowledgePackages().iterator().next();
             }
             return null;
@@ -737,13 +737,13 @@
 
                 KnowledgePackageImp kpkg = createPackageFromResource(entry.getKey());
 
-                if (kpkg == null){
-                    this.listener.warning("KnowledgeAgent: The resource didn't create any package: "+entry.getKey());
+                if (kpkg == null) {
+                    this.listener.warning("KnowledgeAgent: The resource didn't create any package: " + entry.getKey());
                     continue;
                 }
 
 
-                this.listener.debug("KnowledgeAgent: Diffing: "+entry.getKey());
+                this.listener.debug("KnowledgeAgent: Diffing: " + entry.getKey());
 
 
                 ResourceDiffProducer rdp = new BinaryResourceDiffProducerImpl();
@@ -754,7 +754,7 @@
                 ResourceDiffResult diff = rdp.diff(entry.getValue(), kpkg, (KnowledgePackageImp) this.kbase.getKnowledgePackage(kpkg.getName()));
 
                 for (KnowledgeDefinition kd : diff.getRemovedDefinitions()) {
-                    this.listener.debug("KnowledgeAgent: Removing: "+kd);
+                    this.listener.debug("KnowledgeAgent: Removing: " + kd);
                     removeKnowledgeDefinitionFromBase(kd);
                 }
 
@@ -775,13 +775,13 @@
             for (Resource resource : changeSetState.addedResources) {
                 ///compile the new resource
                 KnowledgePackageImp kpkg = createPackageFromResource(resource);
-                if (kpkg == null){
-                    this.listener.warning("KnowledgeAgent: The resource didn't create any package: "+resource);
+                if (kpkg == null) {
+                    this.listener.warning("KnowledgeAgent: The resource didn't create any package: " + resource);
                     continue;
                 }
                 changeSetState.createdPackages.put(resource, kpkg);
             }
-            
+
             //the added and modified resources were already processed and 
             //converted to createdPackages. We must clear the lists.
             changeSetState.addedResources.clear();
@@ -922,6 +922,26 @@
      * @boolean monitor True if monitoring should take place, false otherwise
      */
     public void monitorResourceChangeEvents(boolean monitor) {
+
+        Set<Resource> allResources = new HashSet<Resource>();
+        allResources.addAll(this.resourceDirectories);
+        allResources.addAll(this.registeredResources.getAllResources());
+        allResources.addAll(this.dslResources.keySet());
+
+
+        //subscribe/unsubscribe from resources
+        for (Resource resource : allResources) {
+            if (monitor){
+                this.listener.debug("KnowledgeAgent subscribing from resource="
+                        + resource);
+                this.notifier.subscribeResourceChangeListener(this, resource);
+            }else{
+                this.listener.debug("KnowledgeAgent unsubscribing from resource="
+                        + resource);
+                this.notifier.unsubscribeResourceChangeListener(this, resource);
+            }
+        }
+
         if (!monitor && this.changeSetNotificationDetector != null) {
             // we are running, but it wants to stop
             // this will stop the thread
@@ -1123,17 +1143,17 @@
         }
     }
 
-    private KnowledgeBuilder createKBuilder(){
+    private KnowledgeBuilder createKBuilder() {
         KnowledgeBuilder kbuilder = null;
-        if (this.builderConfiguration != null){
+        if (this.builderConfiguration != null) {
             kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder(this.builderConfiguration);
-        }else if (this.useKBaseClassLoaderForCompiling){
-            kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder(KnowledgeBuilderFactory.newKnowledgeBuilderConfiguration(null, ((ReteooRuleBase)((KnowledgeBaseImpl)this.getKnowledgeBase()).getRuleBase()).getRootClassLoader()));
-        }else{
+        } else if (this.useKBaseClassLoaderForCompiling) {
+            kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder(KnowledgeBuilderFactory.newKnowledgeBuilderConfiguration(null, ((ReteooRuleBase) ((KnowledgeBaseImpl) this.getKnowledgeBase()).getRuleBase()).getRootClassLoader()));
+        } else {
             kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
         }
 
-        if (this.dslResources != null){
+        if (this.dslResources != null) {
             for (Map.Entry<Resource, String> entry : this.dslResources.entrySet()) {
                 kbuilder.add(ResourceFactory.newByteArrayResource(entry.getValue().getBytes()), ResourceType.DSL);
             }
@@ -1142,11 +1162,11 @@
         return kbuilder;
     }
 
-    private void retrieveDSLResource(Resource resource) throws IOException{
+    private void retrieveDSLResource(Resource resource) throws IOException {
         BufferedReader bufferedReader = new BufferedReader(resource.getReader());
         String line = null;
         StringBuilder content = new StringBuilder();
-        while((line = bufferedReader.readLine()) != null){
+        while ((line = bufferedReader.readLine()) != null) {
             content.append(line);
             content.append("\n");
         }
@@ -1158,6 +1178,23 @@
         this.eventSupport.addEventListener(listener);
     }
 
+    public void dispose() {
+        synchronized (this.registeredResources) {
+            //all kbase's ksessions must be disposed
+            if (this.kbase != null) {
+                StatefulSession[] statefulSessions = ((AbstractRuleBase) (((KnowledgeBaseImpl) this.kbase).ruleBase)).getStatefulSessions();
+                if (statefulSessions != null && statefulSessions.length > 0){
+                    String message = "The kbase still contains "+statefulSessions.length+" stateful sessions. You must dispose them first.";
+                    this.listener.warning(message);
+                    throw new IllegalStateException(message);
+                }
+            }
+
+            //stop changeSet Notification Detector
+            this.monitorResourceChangeEvents(false);
+        }
+    }
+
     /*
      * (non-Javadoc)
      *

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/io/impl/ResourceChangeNotifierImpl.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/io/impl/ResourceChangeNotifierImpl.java	2010-07-15 14:03:00 UTC (rev 33900)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/io/impl/ResourceChangeNotifierImpl.java	2010-07-15 14:27:46 UTC (rev 33901)
@@ -84,7 +84,7 @@
                 return;
             }
 
-            listeners.remove( listeners );
+            listeners.remove( listener );
 
             if ( listeners.isEmpty() ) {
                 this.subscriptions.remove( resource );



More information about the jboss-svn-commits mailing list