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

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Sat Dec 4 13:09:28 EST 2010


Author: mark.proctor at jboss.com
Date: 2010-12-04 13:09:28 -0500 (Sat, 04 Dec 2010)
New Revision: 36212

Added:
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/core/util/IoUtils.java
Modified:
   labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/agent/KnowledgeAgentTest.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/core/util/FileManager.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/core/util/StringUtils.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/io/impl/UrlResource.java
Log:
JBRULES-2817 Make the KnowledgeAgent Tests more robust and faster

Modified: labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/agent/KnowledgeAgentTest.java
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/agent/KnowledgeAgentTest.java	2010-12-04 04:44:13 UTC (rev 36211)
+++ labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/agent/KnowledgeAgentTest.java	2010-12-04 18:09:28 UTC (rev 36212)
@@ -1,16 +1,15 @@
 package org.drools.agent;
 
-import java.io.BufferedWriter;
 import java.io.File;
 import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
-import java.io.FileWriter;
 import java.io.IOException;
-import java.io.Writer;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
 
 import junit.framework.TestCase;
 
@@ -23,6 +22,7 @@
 import org.drools.command.runtime.rule.InsertObjectCommand;
 import org.drools.core.util.DroolsStreamUtils;
 import org.drools.core.util.FileManager;
+import org.drools.core.util.IoUtils;
 import org.drools.definition.KnowledgePackage;
 import org.drools.event.knowledgeagent.AfterChangeSetAppliedEvent;
 import org.drools.event.knowledgeagent.AfterChangeSetProcessedEvent;
@@ -33,7 +33,7 @@
 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.Resource;
 import org.drools.io.ResourceFactory;
 import org.drools.io.impl.ResourceChangeNotifierImpl;
 import org.drools.io.impl.ResourceChangeScannerImpl;
@@ -44,62 +44,200 @@
 
 public class KnowledgeAgentTest extends TestCase {
 
-    FileManager fileManager;
-    private Server server;
-    private final Object lock = new Object();
-    private volatile boolean kbaseUpdated;
+    FileManager              fileManager;
+    private Server           server;
+    
+    private ResourceChangeScannerImpl scanner;
 
     @Override
     protected void setUp() throws Exception {
-        fileManager = new FileManager();
-        fileManager.setUp();
+        this.fileManager = new FileManager();
+        this.fileManager.setUp();
         ((ResourceChangeScannerImpl) ResourceFactory.getResourceChangeScannerService()).reset();
 
         ResourceFactory.getResourceChangeNotifierService().start();
-        ResourceFactory.getResourceChangeScannerService().start();
+        
+        // we don't start the scanner, as we call it manually;
+        this.scanner = (ResourceChangeScannerImpl) ResourceFactory.getResourceChangeScannerService();
 
-        this.server = new Server(0);
+        this.server = new Server( IoUtils.findPort() );
         ResourceHandler resourceHandler = new ResourceHandler();
-        resourceHandler.setResourceBase(fileManager.getRootDirectory().getPath());
+        resourceHandler.setResourceBase( fileManager.getRootDirectory().getPath() );
 
-        server.setHandler(resourceHandler);
+        this.server.setHandler( resourceHandler );
 
-        server.start();
-
-        this.kbaseUpdated = false;
-        System.gc();
-        Thread.sleep( 300 );
+        this.server.start();
     }
-
-    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();
+    }    
+
+    private int getPort() {
+        return this.server.getConnectors()[0].getLocalPort();
     }
+    
+    private void scan(KnowledgeAgent kagent) {
+        // Calls the Resource Scanner and sets up a listener and a latch so we can wait until it's finished processing, instead of using timers
+        final CountDownLatch latch = new CountDownLatch( 1 );
+        
+        KnowledgeAgentEventListener l = new KnowledgeAgentEventListener() {
+            
+            public void resourceCompilationFailed(ResourceCompilationFailedEvent event) {
+            }
+            
+            public void knowledgeBaseUpdated(KnowledgeBaseUpdatedEvent event) {
+            }
+            
+            public void beforeResourceProcessed(BeforeResourceProcessedEvent event) {
+            }
+            
+            public void beforeChangeSetProcessed(BeforeChangeSetProcessedEvent event) {                              
+            }
+            
+            public void beforeChangeSetApplied(BeforeChangeSetAppliedEvent event) {
+            }
+            
+            public void afterResourceProcessed(AfterResourceProcessedEvent event) {
+            }
+            
+            public void afterChangeSetProcessed(AfterChangeSetProcessedEvent event) {
+            }
+            
+            public void afterChangeSetApplied(AfterChangeSetAppliedEvent event) {
+                latch.countDown();
+            }
+        };        
+        
+        kagent.addEventListener( l );
+        
+        this.scanner.scan();
+        
+        try {
+            latch.await( 10, TimeUnit.SECONDS );
+        } catch ( InterruptedException e ) {
+            throw new RuntimeException( "Unable to wait for latch countdown", e);
+        }
+        
+        if ( latch.getCount() > 0 ) {            
+            throw new RuntimeException( "Event for KnowlegeBase update, due to scan, was never received" );
+        }
+        
+        kagent.removeEventListener( l );
+    }
+    
+    void applyChangeSet(KnowledgeAgent kagent, String xml) {
+        // Calls the Resource Scanner and sets up a listener and a latch so we can wait until it's finished processing, instead of using timers
+        final CountDownLatch latch = new CountDownLatch( 1 );
+        
+        KnowledgeAgentEventListener l = new KnowledgeAgentEventListener() {
+            
+            public void resourceCompilationFailed(ResourceCompilationFailedEvent event) {
+            }
+            
+            public void knowledgeBaseUpdated(KnowledgeBaseUpdatedEvent event) {
+            }
+            
+            public void beforeResourceProcessed(BeforeResourceProcessedEvent event) {
+            }
+            
+            public void beforeChangeSetProcessed(BeforeChangeSetProcessedEvent event) {                              
+            }
+            
+            public void beforeChangeSetApplied(BeforeChangeSetAppliedEvent event) {
+            }
+            
+            public void afterResourceProcessed(AfterResourceProcessedEvent event) {
+            }
+            
+            public void afterChangeSetProcessed(AfterChangeSetProcessedEvent event) {
+            }
+            
+            public void afterChangeSetApplied(AfterChangeSetAppliedEvent event) {
+                latch.countDown();
+            }
+        };        
+        
+        kagent.addEventListener( l );
+        
+        kagent.applyChangeSet( ResourceFactory.newByteArrayResource( xml.getBytes() ) );
+        
+        try {
+            latch.await( 10, TimeUnit.SECONDS );
+        } catch ( InterruptedException e ) {
+            throw new RuntimeException( "Unable to wait for latch countdown", e);
+        }
+        
+        if ( latch.getCount() > 0 ) {            
+            throw new RuntimeException( "Event for KnowlegeBase update, due to scan, was never received" );
+        }
+        
+        kagent.removeEventListener( l );        
+    }
+    
+    void applyChangeSet(KnowledgeAgent kagent, Resource r) {
+        // Calls the Resource Scanner and sets up a listener and a latch so we can wait until it's finished processing, instead of using timers
+        final CountDownLatch latch = new CountDownLatch( 1 );
+        
+        KnowledgeAgentEventListener l = new KnowledgeAgentEventListener() {
+            
+            public void resourceCompilationFailed(ResourceCompilationFailedEvent event) {
+            }
+            
+            public void knowledgeBaseUpdated(KnowledgeBaseUpdatedEvent event) {
+            }
+            
+            public void beforeResourceProcessed(BeforeResourceProcessedEvent event) {
+            }
+            
+            public void beforeChangeSetProcessed(BeforeChangeSetProcessedEvent event) {                              
+            }
+            
+            public void beforeChangeSetApplied(BeforeChangeSetAppliedEvent event) {
+            }
+            
+            public void afterResourceProcessed(AfterResourceProcessedEvent event) {
+            }
+            
+            public void afterChangeSetProcessed(AfterChangeSetProcessedEvent event) {
+            }
+            
+            public void afterChangeSetApplied(AfterChangeSetAppliedEvent event) {
+                latch.countDown();
+            }
+        };        
+        
+        kagent.addEventListener( l );
+        
+        kagent.applyChangeSet( r );
+        
+        try {
+            latch.await( 10, TimeUnit.SECONDS );
+        } catch ( InterruptedException e ) {
+            throw new RuntimeException( "Unable to wait for latch countdown", e);
+        }
+        
+        if ( latch.getCount() > 0 ) {            
+            throw new RuntimeException( "Event for KnowlegeBase update, due to scan, was never received" );
+        }
+        
+        kagent.removeEventListener( l );        
+    }    
 
+
     public void testModifyFileUrl() throws Exception {
-        String rule1 = this.createDefaultRule("rule1");
-        File f1 = fileManager.newFile("rule1.drl");
-        Writer output = new BufferedWriter(new FileWriter(f1));
-        output.write(rule1);
-        output.close();
-
-        String rule2 = this.createDefaultRule("rule2");
-
-        File f2 = fileManager.newFile("rule2.drl");
-        output = new BufferedWriter(new FileWriter(f2));
-        output.write(rule2);
-        output.close();
-
+        fileManager.write( "rule1.drl",
+                           createDefaultRule( "rule1" ) );        
+        
+        fileManager.write( "rule2.drl",
+                           createDefaultRule( "rule2" ) );
+        
         String xml = "";
         xml += "<change-set xmlns='http://drools.org/drools-5.0/change-set'";
         xml += "    xmlns:xs='http://www.w3.org/2001/XMLSchema-instance'";
@@ -109,65 +247,47 @@
         xml += "        <resource source='http://localhost:" + this.getPort() + "/rule2.drl' type='DRL' />";
         xml += "    </add> ";
         xml += "</change-set>";
-        File fxml = fileManager.newFile("changeset.xml");
-        output = new BufferedWriter(new FileWriter(fxml));
-        output.write(xml);
-        output.close();
 
+        File fxml = fileManager.write( "changeset.xml",
+                                       xml );
+
         KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
+        KnowledgeAgent kagent = createKAgent( kbase );
 
-        ResourceChangeScannerConfiguration sconf = ResourceFactory.getResourceChangeScannerService().newResourceChangeScannerConfiguration();
-        sconf.setProperty("drools.resource.scanner.interval", "2");
-        ResourceFactory.getResourceChangeScannerService().configure(sconf);
+        kagent.applyChangeSet( ResourceFactory.newUrlResource( fxml.toURI().toURL() ) );
 
-        KnowledgeAgentConfiguration aconf = KnowledgeAgentFactory.newKnowledgeAgentConfiguration();
-        aconf.setProperty("drools.agent.scanDirectories", "true");
-        aconf.setProperty("drools.agent.scanResources", "true");
-        aconf.setProperty("drools.agent.newInstance", "true");
-        KnowledgeAgent kagent = KnowledgeAgentFactory.newKnowledgeAgent(
-                "test agent", kbase, aconf);
-
-        assertEquals("test agent", kagent.getName());
-
-        kagent.applyChangeSet(ResourceFactory.newUrlResource(fxml.toURI().toURL()));
-        kbaseUpdated = false;
-
         StatefulKnowledgeSession ksession = kagent.getKnowledgeBase().newStatefulKnowledgeSession();
         List<String> list = new ArrayList<String>();
-        ksession.setGlobal("list", list);
+        ksession.setGlobal( "list",
+                            list );
         ksession.fireAllRules();
         ksession.dispose();
 
-        assertEquals(2, list.size());
-        assertTrue(list.contains("rule1"));
-        assertTrue(list.contains("rule2"));
+        assertEquals( 2,
+                      list.size() );
+        assertTrue( list.contains( "rule1" ) );
+        assertTrue( list.contains( "rule2" ) );
 
         list.clear();
 
-        // have to sleep here as linux lastModified does not do milliseconds
-        // http://saloon.javaranch.com/cgi-bin/ubb/ultimatebb.cgi?ubb=get_topic&f=1&t=019789
-        System.gc();
-        Thread.sleep(2000);
-
-        rule1 = this.createDefaultRule("rule3");
-
-        output = new BufferedWriter(new FileWriter(f1));
-        output.write(rule1);
-        output.close();
-        System.gc();
-        Thread.sleep(3000);
-
+        this.fileManager.write( "rule1.drl", createDefaultRule( "rule3" ) );
+        
+        scan(kagent);
+        
         ksession = kagent.getKnowledgeBase().newStatefulKnowledgeSession();
         list = new ArrayList<String>();
-        ksession.setGlobal("list", list);
+        ksession.setGlobal( "list",
+                            list );
         ksession.fireAllRules();
         ksession.dispose();
 
-        assertEquals(2, list.size());
-
-        assertTrue(list.contains("rule3"));
-        assertTrue(list.contains("rule2"));
-        kagent.monitorResourceChangeEvents(false);
+        assertEquals( 2,
+                      list.size() );
+        
+        assertTrue( list.contains( "rule3" ) );
+        assertTrue( list.contains( "rule2" ) );
+        
+        kagent.dispose();
     }
 
     /**
@@ -178,18 +298,12 @@
      *             If an unexpected exception occurs.
      */
     public void testChangeSetInChangeSet() throws Exception {
-        String rule1 = this.createDefaultRule("rule1");
-        File f1 = fileManager.newFile("rule1.drl");
-        Writer output = new BufferedWriter(new FileWriter(f1));
-        output.write(rule1);
-        output.close();
+        fileManager.write( "rule1.drl",
+                           createDefaultRule( "rule1" ) );        
+        
+        fileManager.write( "rule2.drl",
+                           createDefaultRule( "rule2" ) );
 
-        String rule2 = this.createDefaultRule("rule2");
-        File f2 = fileManager.newFile("rule2.drl");
-        output = new BufferedWriter(new FileWriter(f2));
-        output.write(rule2);
-        output.close();
-
         String xml1 = "";
         xml1 += "<change-set xmlns='http://drools.org/drools-5.0/change-set'";
         xml1 += "    xmlns:xs='http://www.w3.org/2001/XMLSchema-instance'";
@@ -199,11 +313,8 @@
         xml1 += "        <resource source='http://localhost:" + this.getPort() + "/rule2.drl' type='DRL' />";
         xml1 += "    </add> ";
         xml1 += "</change-set>";
-        File fxml1 = fileManager.newFile("changeset2.xml");
-        output = new BufferedWriter(new FileWriter(fxml1));
-        output.write(xml1);
-        output.close();
-
+        File fxml = fileManager.write( "changeset2.xml",
+                                       xml1 );
         String xml2 = "";
         xml2 += "<change-set xmlns='http://drools.org/drools-5.0/change-set'";
         xml2 += "    xmlns:xs='http://www.w3.org/2001/XMLSchema-instance'";
@@ -212,69 +323,56 @@
         xml2 += "        <resource source='http://localhost:" + this.getPort() + "/changeset2.xml' type='CHANGE_SET' />";
         xml2 += "    </add> ";
         xml2 += "</change-set>";
-        File fxml2 = fileManager.newFile("changeset.xml");
-        output = new BufferedWriter(new FileWriter(fxml2));
-        output.write(xml2);
-        output.close();
+        File fxm2 = fileManager.write( "changeset.xml",
+                                       xml1 );
 
         KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
+        KnowledgeAgent kagent = this.createKAgent( kbase );
 
-        KnowledgeAgent kagent = this.createKAgent(kbase);
+        kagent.applyChangeSet( ResourceFactory.newUrlResource( fxm2.toURI().toURL() ) );
 
-        kagent.applyChangeSet(ResourceFactory.newUrlResource(fxml2.toURI().toURL()));
-        kbaseUpdated = false;
-
         StatefulKnowledgeSession ksession = kagent.getKnowledgeBase().newStatefulKnowledgeSession();
         List<String> list = new ArrayList<String>();
-        ksession.setGlobal("list", list);
+        ksession.setGlobal( "list",
+                            list );
         ksession.fireAllRules();
         ksession.dispose();
 
-        assertEquals(2, list.size());
-        assertTrue(list.contains("rule1"));
-        assertTrue(list.contains("rule2"));
+        assertEquals( 2,
+                      list.size() );
+        assertTrue( list.contains( "rule1" ) );
+        assertTrue( list.contains( "rule2" ) );
 
         list.clear();
+        
+        fileManager.write( "rule1.drl",
+                           createDefaultRule( "rule3" ) );        
 
-        // have to sleep here as linux lastModified does not do milliseconds
-        // http://saloon.javaranch.com/cgi-bin/ubb/ultimatebb.cgi?ubb=get_topic&f=1&t=019789
-        System.gc();
-        Thread.sleep(2000);
+        scan(kagent);
 
-        rule1 = this.createDefaultRule("rule3");
-        output = new BufferedWriter(new FileWriter(f1));
-        output.write(rule1);
-        output.close();
-
-        this.waitUntilKBaseUpdate();
-
         ksession = kagent.getKnowledgeBase().newStatefulKnowledgeSession();
         list = new ArrayList<String>();
-        ksession.setGlobal("list", list);
+        ksession.setGlobal( "list",
+                            list );
         ksession.fireAllRules();
         ksession.dispose();
 
-        assertEquals(2, list.size());
+        assertEquals( 2,
+                      list.size() );
 
-        assertTrue(list.contains("rule3"));
-        assertTrue(list.contains("rule2"));
+        assertTrue( list.contains( "rule3" ) );
+        assertTrue( list.contains( "rule2" ) );
 
-        kagent.monitorResourceChangeEvents(false);
+        kagent.dispose();
     }
 
     public void testModifyFileUrlWithStateless() throws Exception {
-        String rule1 = this.createDefaultRule("rule1");
-        File f1 = fileManager.newFile("rule1.drl");
-        Writer output = new BufferedWriter(new FileWriter(f1));
-        output.write(rule1);
-        output.close();
+        fileManager.write( "rule1.drl",
+                           createDefaultRule( "rule1" ) );        
+        
+        fileManager.write( "rule2.drl",
+                           createDefaultRule( "rule2" ) );
 
-        String rule2 = this.createDefaultRule("rule2");
-        File f2 = fileManager.newFile("rule2.drl");
-        output = new BufferedWriter(new FileWriter(f2));
-        output.write(rule2);
-        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'";
@@ -284,66 +382,58 @@
         xml += "        <resource source='http://localhost:" + this.getPort() + "/rule2.drl' type='DRL' />";
         xml += "    </add> ";
         xml += "</change-set>";
-        File fxml = fileManager.newFile("changeset.xml");
-        output = new BufferedWriter(new FileWriter(fxml));
-        output.write(xml);
-        output.close();
+        File fxml = fileManager.write( "changeset.xml",
+                                       xml );
 
         KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
+        KnowledgeAgent kagent = this.createKAgent( kbase );
 
-        KnowledgeAgent kagent = this.createKAgent(kbase);
+        kagent.applyChangeSet( ResourceFactory.newUrlResource( fxml.toURI().toURL() ) );
 
-        kagent.applyChangeSet(ResourceFactory.newUrlResource(fxml.toURI().toURL()));
-        kbaseUpdated = false;
-
         StatelessKnowledgeSession ksession = kagent.newStatelessKnowledgeSession();
         List<String> list = new ArrayList<String>();
-        ksession.setGlobal("list", list);
-        ksession.execute("hello");
+        ksession.setGlobal( "list",
+                            list );
+        ksession.execute( "hello" );
 
-        assertEquals(2, list.size());
-        assertTrue(list.contains("rule1"));
-        assertTrue(list.contains("rule2"));
+        assertEquals( 2,
+                      list.size() );
+        assertTrue( list.contains( "rule1" ) );
+        assertTrue( list.contains( "rule2" ) );
 
         list.clear();
 
-        // have to sleep here as linux lastModified does not do milliseconds
-        // http://saloon.javaranch.com/cgi-bin/ubb/ultimatebb.cgi?ubb=get_topic&f=1&t=019789
-        System.gc();
-        Thread.sleep(2000);
+        fileManager.write( "rule1.drl",
+                           createDefaultRule( "rule3" ) );          
+        
+        scan(kagent);
 
-        rule1 = this.createDefaultRule("rule3");
-        System.out.println("root : " + f1.getPath());
-        output = new BufferedWriter(new FileWriter(f1));
-        output.write(rule1);
-        output.close();
+        ksession.execute( "hello" );
 
-        this.waitUntilKBaseUpdate();
+        assertEquals( 2,
+                      list.size() );
 
-        ksession.execute("hello");
-
-        assertEquals(2, list.size());
-
-        assertTrue(list.contains("rule3"));
-        assertTrue(list.contains("rule2"));
-        kagent.monitorResourceChangeEvents(false);
+        assertTrue( list.contains( "rule3" ) );
+        assertTrue( list.contains( "rule2" ) );
+        kagent.dispose();
     }
 
     public void testModifyPackageUrl() throws Exception {
-        String rule1 = this.createDefaultRule("rule1");
+        String rule1 = this.createDefaultRule( "rule1" );
 
-        String rule2 = this.createDefaultRule("rule2");
+        String rule2 = this.createDefaultRule( "rule2" );
 
         KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
-        kbuilder.add(ResourceFactory.newByteArrayResource(rule1.getBytes()),
-                ResourceType.DRL);
-        kbuilder.add(ResourceFactory.newByteArrayResource(rule2.getBytes()),
-                ResourceType.DRL);
-        if (kbuilder.hasErrors()) {
-            fail(kbuilder.getErrors().toString());
+        kbuilder.add( ResourceFactory.newByteArrayResource( rule1.getBytes() ),
+                      ResourceType.DRL );
+        kbuilder.add( ResourceFactory.newByteArrayResource( rule2.getBytes() ),
+                      ResourceType.DRL );
+        if ( kbuilder.hasErrors() ) {
+            fail( kbuilder.getErrors().toString() );
         }
         KnowledgePackage pkg = (KnowledgePackage) kbuilder.getKnowledgePackages().iterator().next();
-        writePackage(pkg, fileManager.newFile("pkg1.pkg"));
+        writePackage( pkg,
+                      fileManager.newFile( "pkg1.pkg" ) );
 
         String xml = "";
         xml += "<change-set xmlns='http://drools.org/drools-5.0/change-set'";
@@ -353,85 +443,85 @@
         xml += "        <resource source='http://localhost:" + this.getPort() + "/pkg1.pkg' type='PKG' />";
         xml += "    </add> ";
         xml += "</change-set>";
-        File fxml = fileManager.newFile("changeset.xml");
-        Writer output = new BufferedWriter(new FileWriter(fxml));
-        output.write(xml);
-        output.close();
+        File fxml = fileManager.write( "changeset.xml",
+                                       xml );
 
         KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
 
-        KnowledgeAgent kagent = this.createKAgent(kbase);
+        KnowledgeAgent kagent = this.createKAgent( kbase );
 
-        kagent.applyChangeSet(ResourceFactory.newUrlResource(fxml.toURI().toURL()));
-        kbaseUpdated = false;
+        kagent.applyChangeSet( ResourceFactory.newUrlResource( fxml.toURI().toURL() ) );
 
         StatefulKnowledgeSession ksession = kagent.getKnowledgeBase().newStatefulKnowledgeSession();
         List<String> list = new ArrayList<String>();
-        ksession.setGlobal("list", list);
+        ksession.setGlobal( "list",
+                            list );
         ksession.fireAllRules();
         ksession.dispose();
 
-        assertEquals(2, list.size());
-        assertTrue(list.contains("rule1"));
-        assertTrue(list.contains("rule2"));
+        assertEquals( 2,
+                      list.size() );
+        assertTrue( list.contains( "rule1" ) );
+        assertTrue( list.contains( "rule2" ) );
 
         list.clear();
 
-        // have to sleep here as linux lastModified does not do milliseconds
-        // http://saloon.javaranch.com/cgi-bin/ubb/ultimatebb.cgi?ubb=get_topic&f=1&t=019789
-        System.gc();
-        Thread.sleep(2000);
+        rule1 = this.createDefaultRule( "rule3" );
 
-        rule1 = this.createDefaultRule("rule3");
-
         kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
-        kbuilder.add(ResourceFactory.newByteArrayResource(rule1.getBytes()),
-                ResourceType.DRL);
-        kbuilder.add(ResourceFactory.newByteArrayResource(rule2.getBytes()),
-                ResourceType.DRL);
-        if (kbuilder.hasErrors()) {
-            fail(kbuilder.getErrors().toString());
+        kbuilder.add( ResourceFactory.newByteArrayResource( rule1.getBytes() ),
+                      ResourceType.DRL );
+        kbuilder.add( ResourceFactory.newByteArrayResource( rule2.getBytes() ),
+                      ResourceType.DRL );
+        if ( kbuilder.hasErrors() ) {
+            fail( kbuilder.getErrors().toString() );
         }
         pkg = (KnowledgePackage) kbuilder.getKnowledgePackages().iterator().next();
-        writePackage(pkg, fileManager.newFile("pkg1.pkg"));
+        writePackage( pkg,
+                      fileManager.newFile( "pkg1.pkg" ) );
 
-        this.waitUntilKBaseUpdate();
+        scan( kagent );
 
         ksession = kagent.getKnowledgeBase().newStatefulKnowledgeSession();
         list = new ArrayList<String>();
-        ksession.setGlobal("list", list);
+        ksession.setGlobal( "list",
+                            list );
         ksession.fireAllRules();
         ksession.dispose();
 
-        assertEquals(2, list.size());
+        assertEquals( 2,
+                      list.size() );
 
-        assertTrue(list.contains("rule3"));
-        assertTrue(list.contains("rule2"));
-        kagent.monitorResourceChangeEvents(false);
+        assertTrue( list.contains( "rule3" ) );
+        assertTrue( list.contains( "rule2" ) );
+        kagent.dispose();
     }
 
     public void testDeletePackageUrl() throws Exception {
-        String rule1 = this.createDefaultRule("rule1","org.drools.test1");
+        String rule1 = this.createDefaultRule( "rule1",
+                                               "org.drools.test1" );
 
-        String rule2 = this.createDefaultRule("rule2","org.drools.test2");
+        String rule2 = this.createDefaultRule( "rule2",
+                                               "org.drools.test2" );
 
         KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
-        kbuilder.add(ResourceFactory.newByteArrayResource(rule1.getBytes()),
-                ResourceType.DRL);
-        kbuilder.add(ResourceFactory.newByteArrayResource(rule2.getBytes()),
-                ResourceType.DRL);
-        if (kbuilder.hasErrors()) {
-            fail(kbuilder.getErrors().toString());
+        kbuilder.add( ResourceFactory.newByteArrayResource( rule1.getBytes() ),
+                      ResourceType.DRL );
+        kbuilder.add( ResourceFactory.newByteArrayResource( rule2.getBytes() ),
+                      ResourceType.DRL );
+        if ( kbuilder.hasErrors() ) {
+            fail( kbuilder.getErrors().toString() );
         }
 
         Map<String, KnowledgePackage> map = new HashMap<String, KnowledgePackage>();
-        for (KnowledgePackage pkg : kbuilder.getKnowledgePackages()) {
-            map.put(pkg.getName(), pkg);
+        for ( KnowledgePackage pkg : kbuilder.getKnowledgePackages() ) {
+            map.put( pkg.getName(),
+                     pkg );
         }
-        writePackage((KnowledgePackage) map.get("org.drools.test1"),
-                fileManager.newFile("pkg1.pkg"));
-        writePackage((KnowledgePackage) map.get("org.drools.test2"),
-                fileManager.newFile("pkg2.pkg"));
+        writePackage( (KnowledgePackage) map.get( "org.drools.test1" ),
+                      fileManager.newFile( "pkg1.pkg" ) );
+        writePackage( (KnowledgePackage) map.get( "org.drools.test2" ),
+                      fileManager.newFile( "pkg2.pkg" ) );
 
         String xml = "";
         xml += "<change-set xmlns='http://drools.org/drools-5.0/change-set'";
@@ -445,20 +535,21 @@
 
         KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
 
-        KnowledgeAgent kagent = this.createKAgent(kbase);
+        KnowledgeAgent kagent = this.createKAgent( kbase );
 
-        kagent.applyChangeSet(ResourceFactory.newByteArrayResource(xml.getBytes()));
-        kbaseUpdated = false;
+        kagent.applyChangeSet( ResourceFactory.newByteArrayResource( xml.getBytes() ) );
 
         StatefulKnowledgeSession ksession = kagent.getKnowledgeBase().newStatefulKnowledgeSession();
         List<String> list = new ArrayList<String>();
-        ksession.setGlobal("list", list);
+        ksession.setGlobal( "list",
+                            list );
         ksession.fireAllRules();
         ksession.dispose();
 
-        assertEquals(2, list.size());
-        assertTrue(list.contains("rule1"));
-        assertTrue(list.contains("rule2"));
+        assertEquals( 2,
+                      list.size() );
+        assertTrue( list.contains( "rule1" ) );
+        assertTrue( list.contains( "rule2" ) );
 
         list.clear();
 
@@ -470,41 +561,41 @@
         xml += "        <resource source='http://localhost:" + this.getPort() + "/pkg2.pkg' type='PKG' />";
         xml += "    </remove> ";
         xml += "</change-set>";
-
-        kagent.applyChangeSet(ResourceFactory.newByteArrayResource(xml.getBytes()));
-        kbaseUpdated = false;
-
+        
+        applyChangeSet( kagent, xml );
+        
         ksession = kagent.getKnowledgeBase().newStatefulKnowledgeSession();
         list = new ArrayList<String>();
-        ksession.setGlobal("list", list);
+        ksession.setGlobal( "list",
+                            list );
         ksession.fireAllRules();
         ksession.dispose();
 
-        assertEquals(1, list.size());
+        assertEquals( 1,
+                      list.size() );
 
-        assertTrue(list.contains("rule1"));
-        kagent.monitorResourceChangeEvents(false);
+        assertTrue( list.contains( "rule1" ) );
+        kagent.dispose();
     }
 
     public void testOldSchoolPackageUrl() throws Exception {
-        String rule1 = this.createDefaultRule("rule1");
+        String rule1 = this.createDefaultRule( "rule1" );
 
-        String rule2 = this.createDefaultRule("rule2");
+        String rule2 = this.createDefaultRule( "rule2" );
 
         KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
-        kbuilder.add(ResourceFactory.newByteArrayResource(rule1.getBytes()),
-                ResourceType.DRL);
-        kbuilder.add(ResourceFactory.newByteArrayResource(rule2.getBytes()),
-                ResourceType.DRL);
-        if (kbuilder.hasErrors()) {
-            fail(kbuilder.getErrors().toString());
+        kbuilder.add( ResourceFactory.newByteArrayResource( rule1.getBytes() ),
+                      ResourceType.DRL );
+        kbuilder.add( ResourceFactory.newByteArrayResource( rule2.getBytes() ),
+                      ResourceType.DRL );
+        if ( kbuilder.hasErrors() ) {
+            fail( kbuilder.getErrors().toString() );
         }
 
         KnowledgeBuilderImpl kbi = (KnowledgeBuilderImpl) kbuilder;
 
-        // KnowledgePackage pkg = ( KnowledgePackage )
-        // kbuilder.getKnowledgePackages().iterator().next();
-        writePackage(kbi.getPackageBuilder().getPackage(), fileManager.newFile("pkgold.pkg"));
+        writePackage( kbi.getPackageBuilder().getPackage(),
+                      fileManager.newFile( "pkgold.pkg" ) );
 
         String xml = "";
         xml += "<change-set xmlns='http://drools.org/drools-5.0/change-set'";
@@ -514,121 +605,101 @@
         xml += "        <resource source='http://localhost:" + this.getPort() + "/pkgold.pkg' type='PKG' />";
         xml += "    </add> ";
         xml += "</change-set>";
-        File fxml = fileManager.newFile("changeset.xml");
-        Writer output = new BufferedWriter(new FileWriter(fxml));
-        output.write(xml);
-        output.close();
+        File fxml = fileManager.write( "changeset.xml",
+                                       xml );
 
         KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
 
-        KnowledgeAgent kagent = this.createKAgent(kbase);
+        KnowledgeAgent kagent = this.createKAgent( kbase );
 
-        kagent.applyChangeSet(ResourceFactory.newUrlResource(fxml.toURI().toURL()));
-        kbaseUpdated = false;
+        applyChangeSet( kagent, ResourceFactory.newUrlResource( fxml.toURI().toURL() )  );
 
-
         StatefulKnowledgeSession ksession = kagent.getKnowledgeBase().newStatefulKnowledgeSession();
         List<String> list = new ArrayList<String>();
-        ksession.setGlobal("list", list);
+        ksession.setGlobal( "list",
+                            list );
         ksession.fireAllRules();
         ksession.dispose();
 
-        assertEquals(2, list.size());
-        assertTrue(list.contains("rule1"));
-        assertTrue(list.contains("rule2"));
+        assertEquals( 2,
+                      list.size() );
+        assertTrue( list.contains( "rule1" ) );
+        assertTrue( list.contains( "rule2" ) );
+        
+        kagent.dispose();
 
     }
 
-    public void testModifyFile() throws IOException, InterruptedException {
-        String rule1 = this.createDefaultRule("rule1");
-        File f1 = fileManager.newFile("rule1.drl");
-        Writer output = new BufferedWriter(new FileWriter(f1));
-        output.write(rule1);
-        output.close();
+    public void testModifyFile() throws IOException,
+                                InterruptedException {
+        File f1 = fileManager.write( "rule1.drl",
+                                     createDefaultRule( "rule1" ) );        
+        
+        File f2 = fileManager.write( "rule2.drl",
+                                     createDefaultRule( "rule2" ) );
 
-        String rule2 = this.createDefaultRule("rule2");
-        File f2 = fileManager.newFile("rule2.drl");
-        output = new BufferedWriter(new FileWriter(f2));
-        output.write(rule2);
-        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 http://anonsvn.jboss.org/repos/labs/labs/jbossrules/trunk/drools-api/src/main/resources/change-set-1.0.0.xsd' >";
         xml += "    <add> ";
-        xml += "        <resource source='" + f1.toURI().toURL()
-                + "' type='DRL' />";
-        xml += "        <resource source='" + f2.toURI().toURL()
-                + "' type='DRL' />";
+        xml += "        <resource source='" + f1.toURI().toURL() + "' type='DRL' />";
+        xml += "        <resource source='" + f2.toURI().toURL() + "' type='DRL' />";
         xml += "    </add> ";
         xml += "</change-set>";
-        File fxml = fileManager.newFile("changeset.xml");
-        output = new BufferedWriter(new FileWriter(fxml));
-        output.write(xml);
-        output.close();
+        File fxml = fileManager.write( "changeset.xml",
+                                       xml );
 
         KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
 
-        KnowledgeAgent kagent = this.createKAgent(kbase);
+        KnowledgeAgent kagent = this.createKAgent( kbase );
+        
+        applyChangeSet( kagent,ResourceFactory.newUrlResource( fxml.toURI().toURL() ) );
 
-        kagent.applyChangeSet(ResourceFactory.newUrlResource(fxml.toURI().toURL()));
-        kbaseUpdated = false;
-
-
         StatefulKnowledgeSession ksession = kagent.getKnowledgeBase().newStatefulKnowledgeSession();
         List<String> list = new ArrayList<String>();
-        ksession.setGlobal("list", list);
+        ksession.setGlobal( "list",
+                            list );
         ksession.fireAllRules();
         ksession.dispose();
 
-        assertEquals(2, list.size());
-        assertTrue(list.contains("rule1"));
-        assertTrue(list.contains("rule2"));
+        assertEquals( 2,
+                      list.size() );
+        assertTrue( list.contains( "rule1" ) );
+        assertTrue( list.contains( "rule2" ) );
 
         list.clear();
 
-        // have to sleep here as linux lastModified does not do milliseconds
-        // http://saloon.javaranch.com/cgi-bin/ubb/ultimatebb.cgi?ubb=get_topic&f=1&t=019789
-        System.gc();
-        Thread.sleep(2000);
+        fileManager.write( "rule1.drl",
+                           createDefaultRule( "rule3" ) ); 
 
-        rule1 = this.createDefaultRule("rule3");
-        output = new BufferedWriter(new FileWriter(f1));
-        output.write(rule1);
-        output.close();
+        scan( kagent );
 
-        this.waitUntilKBaseUpdate();
-
         ksession = kagent.getKnowledgeBase().newStatefulKnowledgeSession();
         list = new ArrayList<String>();
-        ksession.setGlobal("list", list);
+        ksession.setGlobal( "list",
+                            list );
         ksession.fireAllRules();
         ksession.dispose();
 
-        assertEquals(2, list.size());
+        assertEquals( 2,
+                      list.size() );
 
-        assertTrue(list.contains("rule3"));
-        assertTrue(list.contains("rule2"));
-        kagent.monitorResourceChangeEvents(false);
+        assertTrue( list.contains( "rule3" ) );
+        assertTrue( list.contains( "rule2" ) );
+        kagent.monitorResourceChangeEvents( false );
     }
 
-    public void testModifyDirectory() throws IOException, InterruptedException {
+    public void testModifyDirectory() throws IOException,
+                                     InterruptedException {
         // adds 2 files to a dir and executes then adds one and removes one and
         // detects changes
-        String rule1 = this.createDefaultRule("rule1");
-        File f1 = fileManager.newFile("rule1.drl");
+        File f1 = fileManager.write( "rule1.drl",
+                                     createDefaultRule( "rule1" ) );        
+        
+        File f2 = fileManager.write( "rule2.drl",
+                                     createDefaultRule( "rule2" ) );
 
-        Writer output = new BufferedWriter(new FileWriter(f1));
-        output.write(rule1);
-        output.close();
-
-        String rule2 = this.createDefaultRule("rule2");
-        File f2 = fileManager.newFile("rule2.drl");
-        output = new BufferedWriter(new FileWriter(f2));
-        output.write(rule2);
-        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'";
@@ -638,81 +709,64 @@
                 + f1.getParentFile().toURI().toURL() + "' type='DRL' />";
         xml += "    </add> ";
         xml += "</change-set>";
-        File newDir = fileManager.newFile("changeset");
-        newDir.mkdir();
-        File fxml = fileManager.newFile(newDir, "changeset.xml");
-        output = new BufferedWriter(new FileWriter(fxml));
-        output.write(xml);
-        output.close();
+        File fxml = fileManager.write( "changeset",
+                                       "changeset.xml",
+                                       xml );
 
-        // KnowledgeBuilder kbuilder =
-        // KnowledgeBuilderFactory.newKnowledgeBuilder();
-        // kbuilder.add( ResourceFactory.newUrlResource( fxml.toURI().toURL() ),
-        // ResourceType.ChangeSet );
-        // assertFalse( kbuilder.hasErrors() );
-
         KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
-        // kbase.addKnowledgePackages( kbuilder.getKnowledgePackages() );
 
-        KnowledgeAgent kagent = this.createKAgent(kbase);
+        KnowledgeAgent kagent = this.createKAgent( kbase );
 
-        kagent.applyChangeSet(ResourceFactory.newUrlResource(fxml.toURI().toURL()));
-        kbaseUpdated = false;
+        applyChangeSet( kagent, ResourceFactory.newUrlResource( fxml.toURI().toURL() ) );
 
         StatefulKnowledgeSession ksession = kagent.getKnowledgeBase().newStatefulKnowledgeSession();
         List<String> list = new ArrayList<String>();
-        ksession.setGlobal("list", list);
+        ksession.setGlobal( "list",
+                            list );
         ksession.fireAllRules();
         ksession.dispose();
 
-        assertEquals(2, list.size());
-        assertTrue(list.contains("rule1"));
-        assertTrue(list.contains("rule2"));
+        assertEquals( 2,
+                      list.size() );
+        assertTrue( list.contains( "rule1" ) );
+        assertTrue( list.contains( "rule2" ) );
 
         list.clear();
 
-        System.gc();
-        Thread.sleep(2000); // give it 2 seconds to detect and build the changes
-        String rule3 = this.createDefaultRule("rule3");
-        File f3 = fileManager.newFile("rule3.drl");
-        output = new BufferedWriter(new FileWriter(f3));
-        output.write(rule3);
-        output.close();
+        fileManager.write( "rule3.drl",
+                           createDefaultRule( "rule3" ) );
+        fileManager.deleteFile( f1 );
 
-        assertTrue(f1.delete());
+        scan( kagent );
 
-        this.waitUntilKBaseUpdate();
-
         ksession = kagent.getKnowledgeBase().newStatefulKnowledgeSession();
         list = new ArrayList<String>();
-        ksession.setGlobal("list", list);
+        ksession.setGlobal( "list",
+                            list );
         ksession.fireAllRules();
         ksession.dispose();
 
-        assertEquals(2, list.size());
-        assertTrue(list.contains("rule2"));
-        assertTrue(list.contains("rule3"));
+        assertEquals( 2,
+                      list.size() );
+        assertTrue( list.contains( "rule2" ) );
+        assertTrue( list.contains( "rule3" ) );
 
-        kagent.monitorResourceChangeEvents(false);
+        kagent.dispose();
     }
 
     public void testModifyFileInDirectory() throws Exception {
         // Create the test directory
-        File testDirectory = fileManager.newFile("test");
+        File testDirectory = fileManager.newFile( "test" );
         testDirectory.mkdir();
 
-        String rule1 = this.createDefaultRule("rule1");
-        File f1 = fileManager.newFile(testDirectory, "rule1.drl");
-        Writer output = new BufferedWriter(new FileWriter(f1));
-        output.write(rule1);
-        output.close();
+        File f1 = fileManager.write( "test",
+                                     "rule1.drl",
+                                     createDefaultRule( "rule1" ) );        
+        
+        File f2 = fileManager.write( "test",
+                                     "rule2.drl",
+                                     createDefaultRule( "rule2" ) );
 
-        String rule2 = this.createDefaultRule("rule2");
-        File f2 = fileManager.newFile(testDirectory, "rule2.drl");
-        output = new BufferedWriter(new FileWriter(f2));
-        output.write(rule2);
-        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'";
@@ -723,70 +777,57 @@
                 + "/test' type='DRL' />";
         xml += "    </add> ";
         xml += "</change-set>";
-        File fxml = fileManager.newFile("changeset.xml");
-        output = new BufferedWriter(new FileWriter(fxml));
-        output.write(xml);
-        output.close();
-
+        File fxml = fileManager.write( "changeset",
+                                       "changeset.xml",
+                                       xml );
         KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
 
-        KnowledgeAgent kagent = this.createKAgent(kbase);
+        KnowledgeAgent kagent = this.createKAgent( kbase );
 
-        kagent.applyChangeSet(ResourceFactory.newUrlResource(fxml.toURI().toURL()));
-        kbaseUpdated = false;
-
-
+        applyChangeSet( kagent, ResourceFactory.newUrlResource( fxml.toURI().toURL() ) );
+        
         StatefulKnowledgeSession ksession = kagent.getKnowledgeBase().newStatefulKnowledgeSession();
         List<String> list = new ArrayList<String>();
-        ksession.setGlobal("list", list);
+        ksession.setGlobal( "list",
+                            list );
         ksession.fireAllRules();
         ksession.dispose();
 
-        assertEquals(2, list.size());
-        assertTrue(list.contains("rule1"));
-        assertTrue(list.contains("rule2"));
+        assertEquals( 2,
+                      list.size() );
+        assertTrue( list.contains( "rule1" ) );
+        assertTrue( list.contains( "rule2" ) );
 
         list.clear();
+        
+        fileManager.write( "test",
+                           "rule1.drl",
+                           createDefaultRule( "rule3" ) );          
 
-        // have to sleep here as linux lastModified does not do milliseconds
-        // http://saloon.javaranch.com/cgi-bin/ubb/ultimatebb.cgi?ubb=get_topic&f=1&t=019789
-        System.gc();
-        Thread.sleep(2000);
+        scan(kagent);
 
-        rule1 = this.createDefaultRule("rule3");
-        output = new BufferedWriter(new FileWriter(f1));
-        output.write(rule1);
-        output.close();
-
-        this.waitUntilKBaseUpdate();
-
         ksession = kagent.getKnowledgeBase().newStatefulKnowledgeSession();
         list = new ArrayList<String>();
-        ksession.setGlobal("list", list);
+        ksession.setGlobal( "list",
+                            list );
         ksession.fireAllRules();
         ksession.dispose();
 
-        assertEquals(2, list.size());
+        assertEquals( 2,
+                      list.size() );
 
-        assertTrue(list.contains("rule3"));
-        assertTrue(list.contains("rule2"));
-        kagent.monitorResourceChangeEvents(false);
+        assertTrue( list.contains( "rule3" ) );
+        assertTrue( list.contains( "rule2" ) );
+        kagent.dispose();
     }
 
     public void testStatelessWithCommands() throws Exception {
-        String rule1 = this.createDefaultRule("rule1");
-        File f1 = fileManager.newFile("rule1.drl");
+        File f1 = fileManager.write( "rule1.drl",
+                                     createDefaultRule( "rule1" ) );        
+        
+        File f2 = fileManager.write( "rule2.drl",
+                                     createDefaultRule( "rule2" ) );
 
-        Writer output = new BufferedWriter(new FileWriter(f1));
-        output.write(rule1);
-        output.close();
-
-        String rule2 = this.createDefaultRule("rule2");
-        File f2 = fileManager.newFile("rule2.drl");
-        output = new BufferedWriter(new FileWriter(f2));
-        output.write(rule2);
-        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'";
@@ -796,129 +837,94 @@
                 + f1.getParentFile().toURI().toURL() + "' type='DRL' />";
         xml += "    </add> ";
         xml += "</change-set>";
-        File newDir = fileManager.newFile("changeset");
-        newDir.mkdir();
-        File fxml = fileManager.newFile(newDir, "changeset.xml");
-        output = new BufferedWriter(new FileWriter(fxml));
-        output.write(xml);
-        output.close();
+        File fxml = fileManager.write( "changeset",
+                                       "changeset.xml",
+                                       xml );
 
         KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
 
-        KnowledgeAgent kagent = this.createKAgent(kbase);
+        KnowledgeAgent kagent = this.createKAgent( kbase );
+        
+        applyChangeSet(kagent, ResourceFactory.newUrlResource( fxml.toURI().toURL() ) );
 
-        kagent.applyChangeSet(ResourceFactory.newUrlResource(fxml.toURI().toURL()));
-        kbaseUpdated = false;
-
-
         StatelessKnowledgeSession ksession = kagent.newStatelessKnowledgeSession();
 
         List<String> list = new ArrayList<String>();
-        ksession.setGlobal("list", list);
+        ksession.setGlobal( "list",
+                            list );
 
-        ksession.execute( new InsertObjectCommand("hello") );
+        ksession.execute( new InsertObjectCommand( "hello" ) );
 
-        assertEquals(2, list.size());
-        assertTrue(list.contains("rule1"));
-        assertTrue(list.contains("rule2"));
+        assertEquals( 2,
+                      list.size() );
+        assertTrue( list.contains( "rule1" ) );
+        assertTrue( list.contains( "rule2" ) );
     }
 
-    private static void writePackage(Object pkg, File p1file)
-            throws IOException, FileNotFoundException {
-        FileOutputStream out = new FileOutputStream(p1file);
+    private static void writePackage(Object pkg,
+                                     File p1file )throws IOException, FileNotFoundException {
+        if ( p1file.exists() ) {
+            // we want to make sure there is a time difference for lastModified and lastRead checks as Linux and http often round to seconds
+            // http://saloon.javaranch.com/cgi-bin/ubb/ultimatebb.cgi?ubb=get_topic&f=1&t=019789
+            try {
+                Thread.sleep( 1000 );
+            } catch (Exception e) {
+                throw new RuntimeException( "Unable to sleep" );
+            }            
+        }
+        FileOutputStream out = new FileOutputStream( p1file );
         try {
-            DroolsStreamUtils.streamOut(out, pkg);
+            DroolsStreamUtils.streamOut( out,
+                                         pkg );
         } finally {
             out.close();
         }
     }
 
     private KnowledgeAgent createKAgent(KnowledgeBase kbase) {
-        ResourceChangeScannerConfiguration sconf = ResourceFactory.getResourceChangeScannerService().newResourceChangeScannerConfiguration();
-        sconf.setProperty("drools.resource.scanner.interval", "2");
-        ResourceFactory.getResourceChangeScannerService().configure(sconf);
-
         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", "true");
+        aconf.setProperty( "drools.agent.scanDirectories",
+                           "true" );
+        aconf.setProperty( "drools.agent.scanResources",
+                           "true" );
+        aconf.setProperty( "drools.agent.newInstance",
+                           "true" );
 
-        KnowledgeAgent kagent = KnowledgeAgentFactory.newKnowledgeAgent(
-                "test agent", kbase, aconf);
+        KnowledgeAgent kagent = KnowledgeAgentFactory.newKnowledgeAgent("test agent",
+                                                                         kbase,
+                                                                         aconf );
 
-        kagent.addEventListener(new KnowledgeAgentEventListener() {
+        assertEquals( "test agent",
+                      kagent.getName() );
 
-            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) {
-            }
-        });
-
-        assertEquals("test agent", kagent.getName());
-
         return kagent;
     }
 
-    private String createDefaultRule(String name){
-        return this.createDefaultRule(name, null);
+    private String createDefaultRule(String name) {
+        return this.createDefaultRule( name,
+                                       null );
     }
 
-    private String createDefaultRule(String name, String packageName){
+    private String createDefaultRule(String name,
+                                     String packageName) {
         StringBuilder rule = new StringBuilder();
-        if (packageName == null){
-            rule.append("package org.drools.test\n");
-        }else{
-            rule.append("package ");
-            rule.append(packageName);
-            rule.append("\n");
+        if ( packageName == null ) {
+            rule.append( "package org.drools.test\n" );
+        } else {
+            rule.append( "package " );
+            rule.append( packageName );
+            rule.append( "\n" );
         }
-        rule.append("global java.util.List list\n");
-        rule.append("rule ");
-        rule.append(name);
-        rule.append("\n");
-        rule.append("when\n");
-        rule.append("then\n");
-        rule.append("list.add( drools.getRule().getName() );\n");
-        rule.append("end\n");
+        rule.append( "global java.util.List list\n" );
+        rule.append( "rule " );
+        rule.append( name );
+        rule.append( "\n" );
+        rule.append( "when\n" );
+        rule.append( "then\n" );
+        rule.append( "list.add( drools.getRule().getName() );\n" );
+        rule.append( "end\n" );
 
         return rule.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-12-04 04:44:13 UTC (rev 36211)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/agent/impl/KnowledgeAgentImpl.java	2010-12-04 18:09:28 UTC (rev 36212)
@@ -81,25 +81,27 @@
  *
  * @author Mark Proctor, Sam Romano
  */
-public class KnowledgeAgentImpl implements KnowledgeAgent,
+public class KnowledgeAgentImpl
+    implements
+    KnowledgeAgent,
         ResourceChangeListener {
 
-    private String name;
-    private Set<Resource> resourceDirectories;
-    private KnowledgeBase kbase;
-    private ResourceChangeNotifierImpl notifier;
-    private boolean newInstance;
-    private SystemEventListener listener;
-    private boolean scanDirectories;
-    private boolean useKBaseClassLoaderForCompiling;
+    private String                         name;
+    private Set<Resource>                  resourceDirectories;
+    private KnowledgeBase                  kbase;
+    private ResourceChangeNotifierImpl     notifier;
+    private boolean                        newInstance;
+    private SystemEventListener            listener;
+    private boolean                        scanDirectories;
+    private boolean                        useKBaseClassLoaderForCompiling;
     private LinkedBlockingQueue<ChangeSet> queue;
-    private Thread thread;
-    private ChangeSetNotificationDetector changeSetNotificationDetector;
-    private SemanticModules semanticModules;
-    private final RegisteredResourceMap registeredResources = new RegisteredResourceMap();
-    private Map<Resource, String> dslResources = new HashMap<Resource, String>();
-    private KnowledgeAgentEventSupport eventSupport = new KnowledgeAgentEventSupport();
-    private KnowledgeBuilderConfiguration builderConfiguration;
+    private Thread                         thread;
+    private ChangeSetNotificationDetector  changeSetNotificationDetector;
+    private SemanticModules                semanticModules;
+    private final RegisteredResourceMap    registeredResources = new RegisteredResourceMap();
+    private Map<Resource, String>          dslResources        = new HashMap<Resource, String>();
+    private KnowledgeAgentEventSupport     eventSupport        = new KnowledgeAgentEventSupport();
+    private KnowledgeBuilderConfiguration  builderConfiguration;
 
     /**
      * Default constructor for KnowledgeAgentImpl
@@ -108,8 +110,10 @@
      * @param kbase
      * @param configuration
      */
-    public KnowledgeAgentImpl(String name, KnowledgeBase kbase,
-            KnowledgeAgentConfiguration configuration, KnowledgeBuilderConfiguration builderConfiguration) {
+    public KnowledgeAgentImpl(String name,
+                              KnowledgeBase kbase,
+                              KnowledgeAgentConfiguration configuration,
+                              KnowledgeBuilderConfiguration builderConfiguration) {
         this.name = name;
         this.kbase = kbase;
         this.builderConfiguration = builderConfiguration;
@@ -119,38 +123,37 @@
         this.queue = new LinkedBlockingQueue<ChangeSet>();
         boolean scanResources = false;
         boolean monitor = false;
-        if (configuration != null) {
+        if ( configuration != null ) {
             // New Instance describes if we do incremental builds or not
             this.newInstance = ((KnowledgeAgentConfigurationImpl) configuration).isNewInstance();
             this.useKBaseClassLoaderForCompiling = ((KnowledgeAgentConfigurationImpl) configuration).isUseKBaseClassLoaderForCompiling();
             this.notifier = (ResourceChangeNotifierImpl) ResourceFactory.getResourceChangeNotifierService();
-            if (((KnowledgeAgentConfigurationImpl) configuration).isMonitorChangeSetEvents()) {
+            if ( ((KnowledgeAgentConfigurationImpl) configuration).isMonitorChangeSetEvents() ) {
                 monitor = true;
             }
 
-            if (((KnowledgeAgentConfigurationImpl) configuration).isScanDirectories()) {
+            if ( ((KnowledgeAgentConfigurationImpl) configuration).isScanDirectories() ) {
                 this.scanDirectories = true;
             }
 
             scanResources = ((KnowledgeAgentConfigurationImpl) configuration).isScanResources();
-            if (scanResources) {
-                this.notifier.addResourceChangeMonitor(ResourceFactory.getResourceChangeScannerService());
+            if ( scanResources ) {
+                this.notifier.addResourceChangeMonitor( ResourceFactory.getResourceChangeScannerService() );
                 monitor = true; // if scanning, monitor must be true;
             }
         }
 
-        monitorResourceChangeEvents(monitor);
+        monitorResourceChangeEvents( monitor );
 
-
         autoBuildResourceMapping();
 
-        this.listener.info("KnowledgeAgent created, with configuration:\nmonitorChangeSetEvents="
-                + monitor
-                + " scanResources="
-                + scanResources
-                + " scanDirectories="
-                + this.scanDirectories
-                + " newInstance=" + this.newInstance);
+        this.listener.info( "KnowledgeAgent created, with configuration:\nmonitorChangeSetEvents="
+                            + monitor
+                            + " scanResources="
+                            + scanResources
+                            + " scanDirectories="
+                            + this.scanDirectories
+                            + " newInstance=" + this.newInstance );
     }
 
     public void setSystemEventListener(SystemEventListener listener) {
@@ -166,14 +169,14 @@
     }
 
     public void applyChangeSet(Resource resource) {
-        applyChangeSet(getChangeSet(resource));
+        applyChangeSet( getChangeSet( resource ) );
     }
 
     public void applyChangeSet(ChangeSet changeSet) {
-        synchronized (this.registeredResources) {
-            this.eventSupport.fireBeforeChangeSetApplied(changeSet);
+        synchronized ( this.registeredResources ) {
+            this.eventSupport.fireBeforeChangeSetApplied( changeSet );
 
-            this.listener.info("KnowledgeAgent applying ChangeSet");
+            this.listener.info( "KnowledgeAgent applying ChangeSet" );
 
             ChangeSetState changeSetState = new ChangeSetState();
             changeSetState.scanDirectories = this.scanDirectories;
@@ -181,19 +184,21 @@
             changeSetState.incrementalBuild = !(this.newInstance);
 
             // Process the new ChangeSet
-            processChangeSet(changeSet, changeSetState);
+            processChangeSet( changeSet,
+                              changeSetState );
             // Rebuild or do an update to the KnowledgeBase
-            buildKnowledgeBase(changeSetState);
+            buildKnowledgeBase( changeSetState );
             // Rebuild the resource mapping
             //buildResourceMapping();
 
-            this.eventSupport.fireAfterChangeSetApplied(changeSet);
+            this.eventSupport.fireAfterChangeSetApplied( changeSet );
         }
     }
 
     public void processChangeSet(Resource resource,
-            ChangeSetState changeSetState) {
-        processChangeSet(getChangeSet(resource), changeSetState);
+                                 ChangeSetState changeSetState) {
+        processChangeSet( getChangeSet( resource ),
+                          changeSetState );
     }
 
     /**
@@ -205,60 +210,72 @@
      * @param changeSetState
      */
     public void processChangeSet(ChangeSet changeSet,
-            ChangeSetState changeSetState) {
-        synchronized (this.registeredResources) {
-            this.eventSupport.fireBeforeChangeSetProcessed(changeSet);
+                                 ChangeSetState changeSetState) {
+        synchronized ( this.registeredResources ) {
+            this.eventSupport.fireBeforeChangeSetProcessed( changeSet );
 
             /*
              * Process the added resources from a ChangeSet by subscribing to
              * the notifier and inserting a new ResourceMapping.
              */
-            for (Resource resource : changeSet.getResourcesAdded()) {
-                this.eventSupport.fireBeforeResourceProcessed(changeSet, resource, ((InternalResource) resource).getResourceType(), ResourceStatus.RESOURCE_ADDED);
-                if (((InternalResource) resource).getResourceType() == ResourceType.DSL) {
-                    this.notifier.subscribeResourceChangeListener(this,
-                            resource);
+            for ( Resource resource : changeSet.getResourcesAdded() ) {
+                this.eventSupport.fireBeforeResourceProcessed( changeSet,
+                                                               resource,
+                                                               ((InternalResource) resource).getResourceType(),
+                                                               ResourceStatus.RESOURCE_ADDED );
+                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);
+                        this.retrieveDSLResource( resource );
+                    } catch ( IOException ex ) {
+                        this.listener.exception( "KnowledgeAgent Fails trying to read DSL Resource: "
+                                                         + resource,
+                                                 ex );
                     }
-                } else if (((InternalResource) resource).getResourceType() == ResourceType.CHANGE_SET) {
+                } else if ( ((InternalResource) resource).getResourceType() == ResourceType.CHANGE_SET ) {
                     // @TODO We should not ignore an added change set
-                    this.listener.debug("KnowledgeAgent processing sub ChangeSet="
-                            + resource);
-                    processChangeSet(resource, changeSetState);
-                } else if (((InternalResource) resource).isDirectory()) {
-                    this.resourceDirectories.add(resource);
-                    this.listener.debug("KnowledgeAgent subscribing to directory="
-                            + resource);
-                    this.notifier.subscribeResourceChangeListener(this,
-                            resource);
+                    this.listener.debug( "KnowledgeAgent processing sub ChangeSet="
+                                         + resource );
+                    processChangeSet( resource,
+                                      changeSetState );
+                } else if ( ((InternalResource) resource).isDirectory() ) {
+                    this.resourceDirectories.add( resource );
+                    this.listener.debug( "KnowledgeAgent subscribing to directory="
+                                         + resource );
+                    this.notifier.subscribeResourceChangeListener( this,
+                                                                   resource );
                     // if it's a dir, subscribe it's children first
-                    for (Resource child : ((InternalResource) resource).listResources()) {
+                    for ( Resource child : ((InternalResource) resource).listResources() ) {
 
                         // ignore sub directories
-                        if (((InternalResource) child).isDirectory()) {
+                        if ( ((InternalResource) child).isDirectory() ) {
                             continue;
                         }
 
-                        ((InternalResource) child).setResourceType(((InternalResource) resource).getResourceType());
+                        ((InternalResource) child).setResourceType( ((InternalResource) resource).getResourceType() );
 
-                        this.addDefinitionMapping(child, null, true);
-                        if (this.addResourceMapping(child, true)
-                                && changeSetState.incrementalBuild) {
-                            changeSetState.addedResources.add(child);
+                        this.addDefinitionMapping( child,
+                                                   null,
+                                                   true );
+                        if ( this.addResourceMapping( child,
+                                                      true )
+                                && changeSetState.incrementalBuild ) {
+                            changeSetState.addedResources.add( child );
                         }
                     }
                 } else {
-                    if (this.addResourceMapping(resource, true)
-                            && changeSetState.incrementalBuild) {
-                        changeSetState.addedResources.add(resource);
+                    if ( this.addResourceMapping( resource,
+                                                  true )
+                            && changeSetState.incrementalBuild ) {
+                        changeSetState.addedResources.add( resource );
 
                     }
                 }
-                this.eventSupport.fireAfterResourceProcessed(changeSet, resource, ((InternalResource) resource).getResourceType(), ResourceStatus.RESOURCE_ADDED);
+                this.eventSupport.fireAfterResourceProcessed( changeSet,
+                                                              resource,
+                                                              ((InternalResource) resource).getResourceType(),
+                                                              ResourceStatus.RESOURCE_ADDED );
             }
 
             /*
@@ -266,32 +283,41 @@
              * mappings, index them if we are doing incremental builds so the
              * incremental building process knows what to remove.
              */
-            for (Resource resource : changeSet.getResourcesRemoved()) {
-                this.eventSupport.fireBeforeResourceProcessed(changeSet, resource, ((InternalResource) resource).getResourceType(), ResourceStatus.RESOURCE_MODIFIED);
-                if (((InternalResource) resource).getResourceType() == ResourceType.DSL) {
-                    this.notifier.unsubscribeResourceChangeListener(this,
-                            resource);
-                    this.dslResources.remove(resource);
-                } else if (((InternalResource) resource).getResourceType() == ResourceType.CHANGE_SET) {
+            for ( Resource resource : changeSet.getResourcesRemoved() ) {
+                this.eventSupport.fireBeforeResourceProcessed( changeSet,
+                                                               resource,
+                                                               ((InternalResource) resource).getResourceType(),
+                                                               ResourceStatus.RESOURCE_MODIFIED );
+                if ( ((InternalResource) resource).getResourceType() == ResourceType.DSL ) {
+                    this.notifier.unsubscribeResourceChangeListener( this,
+                                                                     resource );
+                    this.dslResources.remove( resource );
+                } else if ( ((InternalResource) resource).getResourceType() == ResourceType.CHANGE_SET ) {
                     // @TODO Is this true? Shouldn't we just ignore it in
                     // removed?
-                    processChangeSet(resource, changeSetState);
-                } else if (changeSetState.scanDirectories
-                        && ((InternalResource) resource).isDirectory()) {
-                    this.listener.debug("KnowledgeAgent unsubscribing from directory resource="
-                            + resource);
-                    this.resourceDirectories.remove(resource);
-                    this.notifier.unsubscribeResourceChangeListener(this,
-                            resource);
+                    processChangeSet( resource,
+                                      changeSetState );
+                } else if ( changeSetState.scanDirectories
+                            && ((InternalResource) resource).isDirectory() ) {
+                    this.listener.debug( "KnowledgeAgent unsubscribing from directory resource="
+                                         + resource );
+                    this.resourceDirectories.remove( resource );
+                    this.notifier.unsubscribeResourceChangeListener( this,
+                                                                     resource );
                 } else {
 
-                    Set<KnowledgeDefinition> definitions = this.removeResourceMapping(resource, true);
+                    Set<KnowledgeDefinition> definitions = this.removeResourceMapping( resource,
+                                                                                       true );
 
-                    if (definitions != null && changeSetState.incrementalBuild) {
-                        changeSetState.removedResourceMappings.put(resource, definitions);
+                    if ( definitions != null && changeSetState.incrementalBuild ) {
+                        changeSetState.removedResourceMappings.put( resource,
+                                                                    definitions );
                     }
                 }
-                this.eventSupport.fireAfterResourceProcessed(changeSet, resource, ((InternalResource) resource).getResourceType(), ResourceStatus.RESOURCE_MODIFIED);
+                this.eventSupport.fireAfterResourceProcessed( changeSet,
+                                                              resource,
+                                                              ((InternalResource) resource).getResourceType(),
+                                                              ResourceStatus.RESOURCE_MODIFIED );
             }
 
             /*
@@ -300,69 +326,82 @@
              * repopulated with the KnowledgeDefinitions later after rebuilding.
              * Process any modified ChangeSets - treat them as if they were new.
              */
-            for (Resource resource : changeSet.getResourcesModified()) {
-                this.eventSupport.fireBeforeResourceProcessed(changeSet, resource, ((InternalResource) resource).getResourceType(), ResourceStatus.RESOURCE_REMOVED);
-                if (((InternalResource) resource).getResourceType() == ResourceType.DSL) {
+            for ( Resource resource : changeSet.getResourcesModified() ) {
+                this.eventSupport.fireBeforeResourceProcessed( changeSet,
+                                                               resource,
+                                                               ((InternalResource) resource).getResourceType(),
+                                                               ResourceStatus.RESOURCE_REMOVED );
+                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);
+                        this.retrieveDSLResource( resource );
+                    } catch ( IOException ex ) {
+                        this.listener.exception( "KnowledgeAgent Fails trying to read DSL Resource: " + resource,
+                                                 ex );
                     }
-                } else if (((InternalResource) resource).getResourceType() == ResourceType.CHANGE_SET) {
+                } else if ( ((InternalResource) resource).getResourceType() == ResourceType.CHANGE_SET ) {
                     // processChangeSet(resource, changeSetState);
                     continue;
-                } else if (((InternalResource) resource).isDirectory()) {
-                    if (this.resourceDirectories.add(resource)) {
-                        this.listener.warning("KnowledgeAgent is subscribing to a modified directory="
-                                + resource
-                                + " when it should have already been subscribed");
-                        this.notifier.subscribeResourceChangeListener(this,
-                                resource);
+                } else if ( ((InternalResource) resource).isDirectory() ) {
+                    if ( this.resourceDirectories.add( resource ) ) {
+                        this.listener.warning( "KnowledgeAgent is subscribing to a modified directory=" + resource+ 
+                                               " when it should have already been subscribed" );
+                        this.notifier.subscribeResourceChangeListener( this,
+                                                                       resource );
                     }
                     // if it's a dir, subscribe it's children first
-                    for (Resource child : ((InternalResource) resource).listResources()) {
+                    for ( Resource child : ((InternalResource) resource).listResources() ) {
 
                         // ignore sub directories
-                        if (((InternalResource) child).isDirectory()) {
+                        if ( ((InternalResource) child).isDirectory() ) {
                             continue;
                         }
 
-                        if (this.addResourceMapping(child, true)) {
-                            ((InternalResource) child).setResourceType(((InternalResource) resource).getResourceType());
-                            if (changeSetState.incrementalBuild) {
-                                changeSetState.addedResources.add(child);
+                        if ( this.addResourceMapping( child,
+                                                      true ) ) {
+                            ((InternalResource) child).setResourceType( ((InternalResource) resource).getResourceType() );
+                            if ( changeSetState.incrementalBuild ) {
+                                changeSetState.addedResources.add( child );
                             }
                         }
                     }
                 } else {
 
-                    boolean isResourceMapped = this.registeredResources.isResourceMapped(resource);
+                    boolean isResourceMapped = this.registeredResources.isResourceMapped( resource );
 
-                    if (!isResourceMapped) {
-                        this.listener.warning("KnowledgeAgent subscribing to new resource="
-                                + resource
-                                + ", though it was marked as modified.");
-                        this.addResourceMapping(resource, true);
-                        if (changeSetState.incrementalBuild) {
-                            changeSetState.addedResources.add(resource);
+                    if ( !isResourceMapped ) {
+                        this.listener.warning( "KnowledgeAgent subscribing to new resource="
+                                               + resource
+                                               + ", though it was marked as modified." );
+                        this.addResourceMapping( resource,
+                                                 true );
+                        if ( changeSetState.incrementalBuild ) {
+                            changeSetState.addedResources.add( resource );
                         }
                     } else {
-                        if (changeSetState.incrementalBuild) {
+                        if ( changeSetState.incrementalBuild ) {
 
-                            Set<KnowledgeDefinition> definitions = this.removeResourceMapping(resource, true);
+                            Set<KnowledgeDefinition> definitions = this.removeResourceMapping( resource,
+                                                                                               true );
 
-                            changeSetState.modifiedResourceMappings.put(resource, definitions);
+                            changeSetState.modifiedResourceMappings.put( resource,
+                                                                         definitions );
 
                             //adds a new empty mapping that will be filled in buildKnowledgeBase()
-                            this.addResourceMapping(resource, false);
+                            this.addResourceMapping( resource,
+                                                     false );
                         }
                     }
                 }
-                this.eventSupport.fireAfterResourceProcessed(changeSet, resource, ((InternalResource) resource).getResourceType(), ResourceStatus.RESOURCE_REMOVED);
+                this.eventSupport.fireAfterResourceProcessed( changeSet,
+                                                              resource,
+                                                              ((InternalResource) resource).getResourceType(),
+                                                              ResourceStatus.RESOURCE_REMOVED );
             }
 
-            this.eventSupport.fireAfterChangeSetProcessed(changeSet, changeSetState.addedResources, changeSetState.modifiedResourceMappings, changeSetState.removedResourceMappings);
+            this.eventSupport.fireAfterChangeSetProcessed( changeSet,
+                                                           changeSetState.addedResources,
+                                                           changeSetState.modifiedResourceMappings,
+                                                           changeSetState.removedResourceMappings );
         }
     }
 
@@ -375,28 +414,31 @@
      * @return A ChangeSet that can be processed by this Agent.
      */
     public ChangeSet getChangeSet(Resource resource) {
-        if (this.semanticModules == null) {
+        if ( this.semanticModules == null ) {
             this.semanticModules = new SemanticModules();
-            this.semanticModules.addSemanticModule(new ChangeSetSemanticModule());
+            this.semanticModules.addSemanticModule( new ChangeSetSemanticModule() );
         }
 
-        XmlChangeSetReader reader = new XmlChangeSetReader(this.semanticModules);
-        if (resource instanceof ClassPathResource) {
-            reader.setClassLoader(((ClassPathResource) resource).getClassLoader(), null);
+        XmlChangeSetReader reader = new XmlChangeSetReader( this.semanticModules );
+        if ( resource instanceof ClassPathResource ) {
+            reader.setClassLoader( ((ClassPathResource) resource).getClassLoader(),
+                                   null );
         } else {
-            reader.setClassLoader(((AbstractRuleBase) (((KnowledgeBaseImpl) this.kbase).ruleBase)).getConfiguration().getClassLoader(), null);
+            reader.setClassLoader( ((AbstractRuleBase) (((KnowledgeBaseImpl) this.kbase).ruleBase)).getConfiguration().getClassLoader(),
+                                   null );
         }
 
         ChangeSet changeSet = null;
         try {
-            changeSet = reader.read(resource.getReader());
-        } catch (Exception e) {
-            this.listener.exception(new RuntimeException(
-                    "Unable to parse ChangeSet", e));
+            changeSet = reader.read( resource.getReader() );
+        } catch ( Exception e ) {
+            this.listener.exception( new RuntimeException(
+                                                           "Unable to parse ChangeSet",
+                                                           e ) );
         }
-        if (changeSet == null) {
-            this.listener.exception(new RuntimeException(
-                    "Unable to parse ChangeSet"));
+        if ( changeSet == null ) {
+            this.listener.exception( new RuntimeException(
+                                                           "Unable to parse ChangeSet" ) );
         }
         return changeSet;
     }
@@ -409,12 +451,12 @@
      */
     public static class ChangeSetState {
 
-        List<Resource> addedResources = new ArrayList<Resource>();
+        List<Resource>                          addedResources           = new ArrayList<Resource>();
         /**
          * Map of removed definitions. The Set of kdefinitions is the original
          * definitions of the resource (before the deletion).
          */
-        Map<Resource, Set<KnowledgeDefinition>> removedResourceMappings = new HashMap<Resource, Set<KnowledgeDefinition>>();
+        Map<Resource, Set<KnowledgeDefinition>> removedResourceMappings  = new HashMap<Resource, Set<KnowledgeDefinition>>();
         /**
          * Map of modified definitions. The Set of kdefinitions is the original
          * definitions of the resource (before the modification).
@@ -424,9 +466,9 @@
          *Map of created Packages. The agent will create this packages when
          * processing added and modified resources
          */
-        Map<Resource, KnowledgePackage> createdPackages = new LinkedHashMap<Resource, KnowledgePackage>();
-        boolean scanDirectories;
-        boolean incrementalBuild;
+        Map<Resource, KnowledgePackage>         createdPackages          = new LinkedHashMap<Resource, KnowledgePackage>();
+        boolean                                 scanDirectories;
+        boolean                                 incrementalBuild;
     }
 
     /**
@@ -436,12 +478,15 @@
      * @param pkg
      * @param resource
      */
-    private void buildResourceMapping(Package pkg, Resource resource) {
-        if (resource == null) {
-            this.listener.warning("KnowledgeAgent: trying to build a resource map for a null resource!");
+    private void buildResourceMapping(Package pkg,
+                                      Resource resource) {
+        if ( resource == null ) {
+            this.listener.warning( "KnowledgeAgent: trying to build a resource map for a null resource!" );
             return;
         }
-        this.buildResourceMapping(pkg, resource, false);
+        this.buildResourceMapping( pkg,
+                                   resource,
+                                   false );
     }
 
     /**
@@ -461,63 +506,73 @@
      * will be taken from each definition. If that is the case, the parameter
      * <code>resource</code> is not used.
      */
-    private void buildResourceMapping(Package pkg, Resource resource, boolean autoDiscoverResource) {
+    private void buildResourceMapping(Package pkg,
+                                      Resource resource,
+                                      boolean autoDiscoverResource) {
 
-        synchronized (this.registeredResources) {
-            if (!autoDiscoverResource && resource == null) {
-                this.listener.warning("KnowledgeAgent: Impossible to map to a null resource! Use autoDiscoverResource = true ");
+        synchronized ( this.registeredResources ) {
+            if ( !autoDiscoverResource && resource == null ) {
+                this.listener.warning( "KnowledgeAgent: Impossible to map to a null resource! Use autoDiscoverResource = true " );
                 return;
             }
 
-            if (autoDiscoverResource && resource != null) {
-                this.listener.warning("KnowledgeAgent: building resource map with resource set and autoDiscoverResource=true. Resource value wil be overwritten!");
+            if ( autoDiscoverResource && resource != null ) {
+                this.listener.warning( "KnowledgeAgent: building resource map with resource set and autoDiscoverResource=true. Resource value wil be overwritten!" );
             }
 
-            for (Rule rule : pkg.getRules()) {
-                if (resource != null && !((InternalResource) resource).hasURL()) {
-                    this.listener.debug("KnowledgeAgent no resource mapped for rule="
-                            + rule);
+            for ( Rule rule : pkg.getRules() ) {
+                if ( resource != null && !((InternalResource) resource).hasURL() ) {
+                    this.listener.debug( "KnowledgeAgent no resource mapped for rule="
+                                         + rule );
                 }
-                if (autoDiscoverResource) {
+                if ( autoDiscoverResource ) {
                     resource = rule.getResource();
                 }
 
-                this.addDefinitionMapping(resource, rule, true);
+                this.addDefinitionMapping( resource,
+                                           rule,
+                                           true );
             }
 
-            for (Process process : pkg.getRuleFlows().values()) {
-                if (resource != null && !((InternalResource) resource).hasURL()) {
-                    this.listener.debug("KnowledgeAgent no resource mapped for process="
-                            + process);
+            for ( Process process : pkg.getRuleFlows().values() ) {
+                if ( resource != null && !((InternalResource) resource).hasURL() ) {
+                    this.listener.debug( "KnowledgeAgent no resource mapped for process="
+                                         + process );
                 }
-                if (autoDiscoverResource) {
+                if ( autoDiscoverResource ) {
                     resource = ((ResourcedObject) process).getResource();
                 }
 
-                this.addDefinitionMapping(resource, process, true);
+                this.addDefinitionMapping( resource,
+                                           process,
+                                           true );
             }
 
-            for (TypeDeclaration typeDeclaration : pkg.getTypeDeclarations().values()) {
-                if (resource != null && !((InternalResource) resource).hasURL()) {
-                    this.listener.debug("KnowledgeAgent no resource mapped for type="
-                            + typeDeclaration);
+            for ( TypeDeclaration typeDeclaration : pkg.getTypeDeclarations().values() ) {
+                if ( resource != null && !((InternalResource) resource).hasURL() ) {
+                    this.listener.debug( "KnowledgeAgent no resource mapped for type="
+                                         + typeDeclaration );
                 }
-                if (autoDiscoverResource) {
+                if ( autoDiscoverResource ) {
                     resource = typeDeclaration.getResource();
                 }
 
-                this.addDefinitionMapping(resource, typeDeclaration, true);
+                this.addDefinitionMapping( resource,
+                                           typeDeclaration,
+                                           true );
             }
 
-            for (Function function : pkg.getFunctions().values()) {
-                if (resource != null && !((InternalResource) resource).hasURL()) {
-                    this.listener.debug("KnowledgeAgent no resource mapped for function="
-                            + function);
+            for ( Function function : pkg.getFunctions().values() ) {
+                if ( resource != null && !((InternalResource) resource).hasURL() ) {
+                    this.listener.debug( "KnowledgeAgent no resource mapped for function="
+                                         + function );
                 }
-                if (autoDiscoverResource) {
+                if ( autoDiscoverResource ) {
                     resource = function.getResource();
                 }
-                this.addDefinitionMapping(resource, function, true);
+                this.addDefinitionMapping( resource,
+                                           function,
+                                           true );
             }
         }
     }
@@ -528,39 +583,45 @@
      * not just removing of an entire package
      */
     public void autoBuildResourceMapping() {
-        this.listener.debug("KnowledgeAgent building resource map");
-        synchronized (this.registeredResources) {
+        this.listener.debug( "KnowledgeAgent building resource map" );
+        synchronized ( this.registeredResources ) {
             RuleBase rbase = ((KnowledgeBaseImpl) this.kbase).ruleBase;
 
-            for (Package pkg : rbase.getPackages()) {
-                this.buildResourceMapping(pkg, null, true);
+            for ( Package pkg : rbase.getPackages() ) {
+                this.buildResourceMapping( pkg,
+                                           null,
+                                           true );
             }
         }
     }
 
     public KnowledgeBase getKnowledgeBase() {
-        synchronized (this.registeredResources) {
+        synchronized ( this.registeredResources ) {
             return this.kbase;
         }
     }
 
     public StatelessKnowledgeSession newStatelessKnowledgeSession() {
-        return new StatelessKnowledgeSessionImpl(null, this, null);
+        return new StatelessKnowledgeSessionImpl( null,
+                                                  this,
+                                                  null );
     }
 
     public StatelessKnowledgeSession newStatelessKnowledgeSession(
-            KnowledgeSessionConfiguration conf) {
-        return new StatelessKnowledgeSessionImpl(null, this, conf);
+                                                                  KnowledgeSessionConfiguration conf) {
+        return new StatelessKnowledgeSessionImpl( null,
+                                                  this,
+                                                  conf );
     }
 
     public void resourcesChanged(ChangeSet changeSet) {
         try {
-            this.listener.debug("KnowledgeAgent received ChangeSet changed notification");
-            this.queue.put(changeSet);
-        } catch (InterruptedException e) {
-            this.listener.exception(new RuntimeException(
-                    "KnowledgeAgent error while adding ChangeSet notification to queue",
-                    e));
+            this.listener.debug( "KnowledgeAgent received ChangeSet changed notification" );
+            this.queue.put( changeSet );
+        } catch ( InterruptedException e ) {
+            this.listener.exception( new RuntimeException(
+                                                           "KnowledgeAgent error while adding ChangeSet notification to queue",
+                                                           e ) );
         }
     }
 
@@ -574,17 +635,17 @@
      *            The state that the ChangeSet performed
      */
     public void buildKnowledgeBase(ChangeSetState changeSetState) {
-        this.listener.debug("KnowledgeAgent rebuilding KnowledgeBase using ChangeSet");
-        synchronized (this.registeredResources) {
+        this.listener.debug( "KnowledgeAgent rebuilding KnowledgeBase using ChangeSet" );
+        synchronized ( this.registeredResources ) {
 
             /*
              * Do the following only if we are building a new instance,
              * otherwise, do an incremental build/update
              */
-            if (this.newInstance) {
-                rebuildResources(changeSetState);
+            if ( this.newInstance ) {
+                rebuildResources( changeSetState );
             } else {
-                incrementalBuildResources(changeSetState);
+                incrementalBuildResources( changeSetState );
             }
 
             /*
@@ -600,10 +661,10 @@
                 }
             } finally {
                 ruleBase.unlock();
-            }            
+            }
         }
-        this.eventSupport.fireKnowledgeBaseUpdated(this.kbase);
-        this.listener.debug("KnowledgeAgent finished rebuilding KnowledgeBase using ChangeSet");
+        this.eventSupport.fireKnowledgeBaseUpdated( this.kbase );
+        this.listener.debug( "KnowledgeAgent finished rebuilding KnowledgeBase using ChangeSet" );
     }
 
     /**
@@ -615,7 +676,8 @@
      * @see #createPackageFromResource(org.drools.io.Resource, org.drools.builder.KnowledgeBuilder) 
      */
     private KnowledgePackageImp createPackageFromResource(Resource resource) {
-        return this.createPackageFromResource(resource, null);
+        return this.createPackageFromResource( resource,
+                                               null );
     }
 
     /**
@@ -627,21 +689,26 @@
      * 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 (((InternalResource) resource).getResourceType() != ResourceType.PKG) {
+        if ( ((InternalResource) resource).getResourceType() != ResourceType.PKG ) {
 
-            if (kbuilder == null) {
+            if ( kbuilder == null ) {
                 kbuilder = this.createKBuilder();
             }
 
-            kbuilder.add(resource, ((InternalResource) resource).getResourceType());
-            if (kbuilder.hasErrors()) {
-                this.eventSupport.fireResourceCompilationFailed(kbuilder, resource, ((InternalResource) resource).getResourceType());
+            kbuilder.add( resource,
+                          ((InternalResource) resource).getResourceType() );
+            if ( kbuilder.hasErrors() ) {
+                this.eventSupport.fireResourceCompilationFailed( kbuilder,
+                                                                 resource,
+                                                                 ((InternalResource) resource).getResourceType() );
                 this.listener.warning(
-                        "KnowledgeAgent has KnowledgeBuilder errors ", kbuilder.getErrors());
+                                       "KnowledgeAgent has KnowledgeBuilder errors ",
+                                       kbuilder.getErrors() );
             }
-            if (kbuilder.getKnowledgePackages().iterator().hasNext()) {
+            if ( kbuilder.getKnowledgePackages().iterator().hasNext() ) {
                 return (KnowledgePackageImp) kbuilder.getKnowledgePackages().iterator().next();
             }
             return null;
@@ -651,25 +718,27 @@
             KnowledgePackageImp kpkg = null;
             try {
                 is = resource.getInputStream();
-                Object object = DroolsStreamUtils.streamIn(is);
-                if (object instanceof KnowledgePackageImp) {
+                Object object = DroolsStreamUtils.streamIn( is );
+                if ( object instanceof KnowledgePackageImp ) {
                     kpkg = ((KnowledgePackageImp) object);
                 } else {
-                    kpkg = new KnowledgePackageImp((Package) object);
+                    kpkg = new KnowledgePackageImp( (Package) object );
                 }
-                for (Rule rule : kpkg.pkg.getRules()) {
-                    rule.setResource(resource);
+                for ( Rule rule : kpkg.pkg.getRules() ) {
+                    rule.setResource( resource );
                 }
 
-            } catch (Exception ex) {
-                this.listener.exception(new RuntimeException("KnowledgeAgent exception while trying to deserialize KnowledgeDefinitionsPackage  ", ex));
+            } catch ( Exception ex ) {
+                this.listener.exception( new RuntimeException( "KnowledgeAgent exception while trying to deserialize KnowledgeDefinitionsPackage  ",
+                                                               ex ) );
             } finally {
                 try {
-                    if (is != null) {
+                    if ( is != null ) {
                         is.close();
                     }
-                } catch (IOException e) {
-                    this.listener.exception(new RuntimeException("KnowledgeAgent exception while trying to close KnowledgeDefinitionsPackage  ", e));
+                } catch ( IOException e ) {
+                    this.listener.exception( new RuntimeException( "KnowledgeAgent exception while trying to close KnowledgeDefinitionsPackage  ",
+                                                                   e ) );
                 }
             }
             return kpkg;
@@ -685,26 +754,26 @@
      *            The ChangeSetState
      */
     private void rebuildResources(ChangeSetState changeSetState) {
-        if (!this.newInstance) {
-            listener.warning("KnowledgeAgent rebuilding KnowledgeBase when newInstance is false");
+        if ( !this.newInstance ) {
+            listener.warning( "KnowledgeAgent rebuilding KnowledgeBase when newInstance is false" );
         }
 
         /*
          * Rebuild a new knowledge base. Try to use the old configuration if
          * possible
          */
-        if (this.kbase != null) {
-            this.kbase = KnowledgeBaseFactory.newKnowledgeBase(((InternalRuleBase) ((KnowledgeBaseImpl) this.kbase).ruleBase).getConfiguration());
+        if ( this.kbase != null ) {
+            this.kbase = KnowledgeBaseFactory.newKnowledgeBase( ((InternalRuleBase) ((KnowledgeBaseImpl) this.kbase).ruleBase).getConfiguration() );
         } else {
             this.kbase = KnowledgeBaseFactory.newKnowledgeBase();
         }
 
         //puts all the resources as added in the changeSet.
         changeSetState.addedResources.clear();
-        changeSetState.addedResources.addAll(this.registeredResources.getAllResources());
-        addResourcesToKnowledgeBase(changeSetState);
+        changeSetState.addedResources.addAll( this.registeredResources.getAllResources() );
+        addResourcesToKnowledgeBase( changeSetState );
 
-        this.listener.info("KnowledgeAgent new KnowledgeBase now built and in use");
+        this.listener.info( "KnowledgeAgent new KnowledgeBase now built and in use" );
     }
 
     /**
@@ -745,73 +814,77 @@
      * @param changeSetState the ChangeSetState
      */
     private void incrementalBuildResources(ChangeSetState changeSetState) {
-        if (this.newInstance) {
-            this.listener.warning("KnowledgeAgent incremental build of KnowledgeBase when newInstance is true");
+        if ( this.newInstance ) {
+            this.listener.warning( "KnowledgeAgent incremental build of KnowledgeBase when newInstance is true" );
         }
         // Incrementally rebuild the resources
-        synchronized (this.registeredResources) {
-            this.listener.info("KnowledgeAgent performing an incremental build of the ChangeSet");
+        synchronized ( this.registeredResources ) {
+            this.listener.info( "KnowledgeAgent performing an incremental build of the ChangeSet" );
 
             // Create the knowledge base if one does not exist
-            if (this.kbase == null) {
+            if ( this.kbase == null ) {
                 this.kbase = KnowledgeBaseFactory.newKnowledgeBase();
             }
 
             // Remove all rules from the resources removed and also those
             // modified
-            for (Map.Entry<Resource, Set<KnowledgeDefinition>> entry : changeSetState.removedResourceMappings.entrySet()) {
-                for (KnowledgeDefinition kd : entry.getValue()) {
-                    removeKnowledgeDefinitionFromBase(kd);
+            for ( Map.Entry<Resource, Set<KnowledgeDefinition>> entry : changeSetState.removedResourceMappings.entrySet() ) {
+                for ( KnowledgeDefinition kd : entry.getValue() ) {
+                    removeKnowledgeDefinitionFromBase( kd );
                 }
             }
 
-            for (Map.Entry<Resource, Set<KnowledgeDefinition>> entry : changeSetState.modifiedResourceMappings.entrySet()) {
+            for ( Map.Entry<Resource, Set<KnowledgeDefinition>> entry : changeSetState.modifiedResourceMappings.entrySet() ) {
 
-                KnowledgePackageImp kpkg = createPackageFromResource(entry.getKey());
+                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();
 
                 //we suppose that the package definition didn't change in the resource.
                 //That's why we are serching the current package as
                 //this.kbase.getKnowledgePackage(kpkg.getName())
-                ResourceDiffResult diff = rdp.diff(entry.getValue(), kpkg, (KnowledgePackageImp) this.kbase.getKnowledgePackage(kpkg.getName()));
+                ResourceDiffResult diff = rdp.diff( entry.getValue(),
+                                                    kpkg,
+                                                    (KnowledgePackageImp) this.kbase.getKnowledgePackage( kpkg.getName() ) );
 
-                for (KnowledgeDefinition kd : diff.getRemovedDefinitions()) {
-                    this.listener.debug("KnowledgeAgent: Removing: " + kd);
-                    removeKnowledgeDefinitionFromBase(kd);
+                for ( KnowledgeDefinition kd : diff.getRemovedDefinitions() ) {
+                    this.listener.debug( "KnowledgeAgent: Removing: " + kd );
+                    removeKnowledgeDefinitionFromBase( kd );
                 }
 
                 //because all the mappings for "resource" were removed, we
                 //need to map again the definitions that didn't change.
                 //Those modified or added will be mapped in addResourcesToKnowledgeBase()
-                for (KnowledgeDefinition knowledgeDefinition : diff.getUnmodifiedDefinitions()) {
-                    this.addDefinitionMapping(entry.getKey(), knowledgeDefinition, false);
+                for ( KnowledgeDefinition knowledgeDefinition : diff.getUnmodifiedDefinitions() ) {
+                    this.addDefinitionMapping( entry.getKey(),
+                                               knowledgeDefinition,
+                                               false );
                 }
 
-                changeSetState.createdPackages.put(entry.getKey(), diff.getPkg());
+                changeSetState.createdPackages.put( entry.getKey(),
+                                                    diff.getPkg() );
 
             }
 
             /*
              * Compile the newly added resources
              */
-            for (Resource resource : changeSetState.addedResources) {
+            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);
+                KnowledgePackageImp kpkg = createPackageFromResource( resource );
+                if ( kpkg == null ) {
+                    this.listener.warning( "KnowledgeAgent: The resource didn't create any package: " + resource );
                     continue;
                 }
-                changeSetState.createdPackages.put(resource, kpkg);
+                changeSetState.createdPackages.put( resource,
+                                                    kpkg );
             }
 
             //the added and modified resources were already processed and 
@@ -819,10 +892,10 @@
             changeSetState.addedResources.clear();
             changeSetState.modifiedResourceMappings.clear();
 
-            addResourcesToKnowledgeBase(changeSetState);
+            addResourcesToKnowledgeBase( changeSetState );
 
         }
-        this.listener.info("KnowledgeAgent incremental build of KnowledgeBase finished and in use");
+        this.listener.info( "KnowledgeAgent incremental build of KnowledgeBase finished and in use" );
     }
 
     /**
@@ -831,30 +904,33 @@
      */
     private void removeKnowledgeDefinitionFromBase(KnowledgeDefinition kd) {
         try {
-            if (kd instanceof Query) {
+            if ( kd instanceof Query ) {
                 Query query = (Query) kd;
-                this.listener.debug("KnowledgeAgent removing Query=" + query
-                        + " from package=" + query.getPackageName());
-                this.kbase.removeQuery(query.getPackageName(), query.getName());
-            }else if (kd instanceof Rule) {
+                this.listener.debug( "KnowledgeAgent removing Query=" + query
+                                     + " from package=" + query.getPackageName() );
+                this.kbase.removeQuery( query.getPackageName(),
+                                        query.getName() );
+            } else if ( kd instanceof Rule ) {
                 Rule rule = (Rule) kd;
-                this.listener.debug("KnowledgeAgent removing Rule=" + rule
-                        + " from package=" + rule.getPackageName());
-                this.kbase.removeRule(rule.getPackageName(), rule.getName());
-            } else if (kd instanceof Process) {
+                this.listener.debug( "KnowledgeAgent removing Rule=" + rule
+                                     + " from package=" + rule.getPackageName() );
+                this.kbase.removeRule( rule.getPackageName(),
+                                       rule.getName() );
+            } else if ( kd instanceof Process ) {
                 Process process = (Process) kd;
-                this.listener.debug("KnowledgeAgent removing Process=" + process);
-                this.kbase.removeProcess(process.getId());
-            } else if (kd instanceof TypeDeclaration) {
+                this.listener.debug( "KnowledgeAgent removing Process=" + process );
+                this.kbase.removeProcess( process.getId() );
+            } else if ( kd instanceof TypeDeclaration ) {
                 // @TODO Handle Type Declarations... is there a way to remove this?
-            } else if (kd instanceof Function) {
+            } else if ( kd instanceof Function ) {
                 Function function = (Function) kd;
-                this.kbase.removeFunction(function.getNamespace(), function.getName());
+                this.kbase.removeFunction( function.getNamespace(),
+                                           function.getName() );
             }
-        } catch (IllegalArgumentException e) {
+        } catch ( IllegalArgumentException e ) {
             //it could be possible that a definition does not longer exists
             //in the kbase.
-            this.listener.warning(e.getMessage());
+            this.listener.warning( e.getMessage() );
         }
     }
 
@@ -885,57 +961,59 @@
         KnowledgeBuilder kbuilder = this.createKBuilder();
         List<Package> packages = new ArrayList<Package>();
 
-
-        for (Resource resource : changeSetState.addedResources) {
-            KnowledgePackageImp createdPackage = this.createPackageFromResource(resource, kbuilder);
-            changeSetState.createdPackages.put(resource, createdPackage);
+        for ( Resource resource : changeSetState.addedResources ) {
+            KnowledgePackageImp createdPackage = this.createPackageFromResource( resource,
+                                                                                 kbuilder );
+            changeSetState.createdPackages.put( resource,
+                                                createdPackage );
         }
 
         //createPackageFromResource already log this
-//        if (kbuilder.hasErrors()) {
-//            this.listener.warning(
-//                    "KnowledgeAgent has KnowledgeBuilder errors ", kbuilder.getErrors());
-//        }
+        //        if (kbuilder.hasErrors()) {
+        //            this.listener.warning(
+        //                    "KnowledgeAgent has KnowledgeBuilder errors ", kbuilder.getErrors());
+        //        }
 
-        for (Map.Entry<Resource, KnowledgePackage> entry : changeSetState.createdPackages.entrySet()) {
+        for ( Map.Entry<Resource, KnowledgePackage> entry : changeSetState.createdPackages.entrySet() ) {
             // For PKG (.pks) just add them
             Resource resource = entry.getKey();
-            this.listener.debug("KnowledgeAgent obtaining pkg resource="
-                    + resource);
+            this.listener.debug( "KnowledgeAgent obtaining pkg resource="
+                                 + resource );
 
             try {
                 Package pkg = ((KnowledgePackageImp) entry.getValue()).pkg;
-                for (Rule rule : pkg.getRules()) {
-                    rule.setResource(resource);
+                for ( Rule rule : pkg.getRules() ) {
+                    rule.setResource( resource );
                 }
-                packages.add(pkg);
+                packages.add( pkg );
 
-                this.buildResourceMapping(pkg, resource);
-            } catch (Exception e) {
-                this.listener.exception(new RuntimeException(
-                        "KnowledgeAgent exception while trying to deserialize KnowledgeDefinitionsPackage  ",
-                        e));
+                this.buildResourceMapping( pkg,
+                                           resource );
+            } catch ( Exception e ) {
+                this.listener.exception( new RuntimeException(
+                                                               "KnowledgeAgent exception while trying to deserialize KnowledgeDefinitionsPackage  ",
+                                                               e ) );
             }
         }
 
-//        if (kbuilder
-//                != null) {
-//            // Log any errors we come across
-//            if (kbuilder.hasErrors()) {
-//                this.listener.warning(
-//                        "KnowledgeAgent has KnowledgeBuilder errors ", kbuilder.getErrors());
-//            }
-//            this.listener.debug("KnowledgeAgent adding KnowledgePackages from KnowledgeBuilder");
-//            this.kbase.addKnowledgePackages(kbuilder.getKnowledgePackages());
-//        }
+        //        if (kbuilder
+        //                != null) {
+        //            // Log any errors we come across
+        //            if (kbuilder.hasErrors()) {
+        //                this.listener.warning(
+        //                        "KnowledgeAgent has KnowledgeBuilder errors ", kbuilder.getErrors());
+        //            }
+        //            this.listener.debug("KnowledgeAgent adding KnowledgePackages from KnowledgeBuilder");
+        //            this.kbase.addKnowledgePackages(kbuilder.getKnowledgePackages());
+        //        }
         /*
          * Add all the packages we found, but did not build, from the resources
          * now
          */
-        for (Package pkg : packages) {
-            this.listener.debug("KnowledgeAgent adding KnowledgeDefinitionsPackage "
-                    + pkg.getName());
-            ((KnowledgeBaseImpl) this.kbase).ruleBase.addPackage(pkg);
+        for ( Package pkg : packages ) {
+            this.listener.debug( "KnowledgeAgent adding KnowledgeDefinitionsPackage "
+                                 + pkg.getName() );
+            ((KnowledgeBaseImpl) this.kbase).ruleBase.addPackage( pkg );
         }
     }
 
@@ -947,9 +1025,6 @@
     public String getName() {
         return this.name;
 
-
-
-
     }
 
     /**
@@ -961,34 +1036,37 @@
     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());
+        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);
+        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);
+                this.listener.debug( "KnowledgeAgent unsubscribing from resource="
+                                     + resource );
+                this.notifier.unsubscribeResourceChangeListener( this,
+                                                                 resource );
             }
         }
 
-        if (!monitor && this.changeSetNotificationDetector != null) {
+        if ( !monitor && this.changeSetNotificationDetector != null ) {
             // we are running, but it wants to stop
             // this will stop the thread
             this.changeSetNotificationDetector.stop();
             this.thread.interrupt();
             this.changeSetNotificationDetector = null;
-        } else if (monitor && this.changeSetNotificationDetector == null) {
+        } else if ( monitor && this.changeSetNotificationDetector == null ) {
             this.changeSetNotificationDetector = new ChangeSetNotificationDetector(
-                    this, this.queue, this.listener);
-            this.thread = new Thread(this.changeSetNotificationDetector);
+                                                                                    this,
+                                                                                    this.queue,
+                                                                                    this.listener );
+            this.thread = new Thread( this.changeSetNotificationDetector );
             this.thread.start();
         }
     }
@@ -999,14 +1077,15 @@
      * @param notify
      * @return
      */
-    public boolean addResourceMapping(Resource resource, boolean notify) {
-        boolean newMapping = this.registeredResources.createNewResourceEntry(resource);
+    public boolean addResourceMapping(Resource resource,
+                                      boolean notify) {
+        boolean newMapping = this.registeredResources.createNewResourceEntry( resource );
 
-        if (notify && newMapping) {
-            this.listener.debug("KnowledgeAgent notifier subscribing to resource="
-                    + resource);
-            this.notifier.subscribeResourceChangeListener(this,
-                    resource);
+        if ( notify && newMapping ) {
+            this.listener.debug( "KnowledgeAgent notifier subscribing to resource="
+                                 + resource );
+            this.notifier.subscribeResourceChangeListener( this,
+                                                           resource );
             return true;
         }
         return false;
@@ -1020,51 +1099,52 @@
      * @param notify
      * @return if the resource/definition didn't exist in registeredResources.
      */
-    public boolean addDefinitionMapping(Resource resource, KnowledgeDefinition definition, boolean notify) {
+    public boolean addDefinitionMapping(Resource resource,
+                                        KnowledgeDefinition definition,
+                                        boolean notify) {
 
-        if (resource == null) {
-            listener.warning("KnowledgeAgent: impossible to add a map for a null resource! skiping.");
+        if ( resource == null ) {
+            listener.warning( "KnowledgeAgent: impossible to add a map for a null resource! skiping." );
             return false;
         }
 
-        this.listener.debug("KnowledgeAgent mapping resource="
-                + resource + " to KnowledgeDefinition=" + definition);
+        this.listener.debug( "KnowledgeAgent mapping resource="
+                             + resource + " to KnowledgeDefinition=" + definition );
 
-        boolean isNewResource = this.registeredResources.isResourceMapped(resource);
+        boolean isNewResource = this.registeredResources.isResourceMapped( resource );
 
         boolean isNewDefinition = true;
 
-        if (definition != null) {
-            isNewDefinition = this.registeredResources.putDefinition(resource, definition);
+        if ( definition != null ) {
+            isNewDefinition = this.registeredResources.putDefinition( resource,
+                                                                      definition );
         }
 
-        if (notify && isNewResource) {
-            this.listener.debug("KnowledgeAgent notifier subscribing to resource="
-                    + resource);
+        if ( notify && isNewResource ) {
+            this.listener.debug( "KnowledgeAgent notifier subscribing to resource="
+                                 + resource );
 
-            this.notifier.subscribeResourceChangeListener(this,
-                    resource);
+            this.notifier.subscribeResourceChangeListener( this,
+                                                           resource );
         }
 
         return isNewDefinition;
     }
 
     public Set<KnowledgeDefinition> removeResourceMapping(Resource resource,
-            boolean unsubscribe) {
-        this.listener.debug("KnowledgeAgent removing mappings for resource="
-                + resource + " with unsubscribe=" + unsubscribe);
-        Set<KnowledgeDefinition> definitions = this.registeredResources.removeDefinitions(resource);
+                                                          boolean unsubscribe) {
+        this.listener.debug( "KnowledgeAgent removing mappings for resource="
+                             + resource + " with unsubscribe=" + unsubscribe );
+        Set<KnowledgeDefinition> definitions = this.registeredResources.removeDefinitions( resource );
 
+        if ( definitions != null ) {
+            if ( unsubscribe ) {
+                this.listener.debug( "KnowledgeAgent notifier unsubscribing to resource="
+                                     + resource );
 
-
-
-        if (definitions != null) {
-            if (unsubscribe) {
-                this.listener.debug("KnowledgeAgent notifier unsubscribing to resource="
-                        + resource);
-
                 this.notifier.unsubscribeResourceChangeListener(
-                        this, resource);
+                                                                 this,
+                                                                 resource );
             }
         }
         return definitions;
@@ -1077,16 +1157,18 @@
      *
      * @author Mark Proctor
      */
-    public static class ChangeSetNotificationDetector implements Runnable {
+    public static class ChangeSetNotificationDetector
+        implements
+        Runnable {
 
         private LinkedBlockingQueue<ChangeSet> queue;
-        private volatile boolean monitor;
-        private KnowledgeAgentImpl kagent;
-        private SystemEventListener listener;
+        private volatile boolean               monitor;
+        private KnowledgeAgentImpl             kagent;
+        private SystemEventListener            listener;
 
         public ChangeSetNotificationDetector(KnowledgeAgentImpl kagent,
-                LinkedBlockingQueue<ChangeSet> queue,
-                SystemEventListener listener) {
+                                             LinkedBlockingQueue<ChangeSet> queue,
+                                             SystemEventListener listener) {
             this.queue = queue;
             this.kagent = kagent;
             this.listener = listener;
@@ -1098,25 +1180,25 @@
         }
 
         public void run() {
-            if (this.monitor) {
-                this.listener.info("KnowledegAgent has started listening for ChangeSet notifications");
+            if ( this.monitor ) {
+                this.listener.info( "KnowledegAgent has started listening for ChangeSet notifications" );
             }
-            while (this.monitor) {
+            while ( this.monitor ) {
                 Exception exception = null;
                 try {
-                    kagent.applyChangeSet(this.queue.take());
-                } catch (InterruptedException e) {
+                    kagent.applyChangeSet( this.queue.take() );
+                } catch ( InterruptedException e ) {
                     exception = e;
                 }
                 Thread.yield();
-                if (this.monitor && exception != null) {
-                    this.listener.exception(new RuntimeException(
-                            "KnowledgeAgent ChangeSet notification thread has been interrupted, but shutdown was not scheduled",
-                            exception));
+                if ( this.monitor && exception != null ) {
+                    this.listener.exception( new RuntimeException(
+                                                                   "KnowledgeAgent ChangeSet notification thread has been interrupted, but shutdown was not scheduled",
+                                                                   exception ) );
                 }
             }
 
-            this.listener.info("KnowledegAgent has stopped listening for ChangeSet notifications");
+            this.listener.info( "KnowledegAgent has stopped listening for ChangeSet notifications" );
         }
     }
 
@@ -1132,23 +1214,26 @@
          * @return true if the resource was not previously mapped.
          */
         public boolean createNewResourceEntry(Resource resource) {
-            if (!this.isResourceMapped(resource)) {
-                this.map.put(resource, new HashSet<KnowledgeDefinition>());
+            if ( !this.isResourceMapped( resource ) ) {
+                this.map.put( resource,
+                              new HashSet<KnowledgeDefinition>() );
                 return true;
             }
             return false;
         }
 
-        public boolean putDefinition(Resource resource, KnowledgeDefinition definition) {
-            Set<KnowledgeDefinition> defList = map.get(resource);
-            if (defList == null) {
+        public boolean putDefinition(Resource resource,
+                                     KnowledgeDefinition definition) {
+            Set<KnowledgeDefinition> defList = map.get( resource );
+            if ( defList == null ) {
                 defList = new HashSet<KnowledgeDefinition>();
-                this.map.put(resource, defList);
+                this.map.put( resource,
+                              defList );
             }
 
             //support for lazy loading
-            if (definition != null) {
-                boolean isNew = defList.add(definition);
+            if ( definition != null ) {
+                boolean isNew = defList.add( definition );
                 return isNew;
             }
 
@@ -1156,23 +1241,25 @@
         }
 
         public Set<KnowledgeDefinition> removeDefinitions(Resource resource) {
-            return this.map.remove(resource);
+            return this.map.remove( resource );
         }
 
         public Set<KnowledgeDefinition> getDefinitions(Resource resource) {
-            return this.getDefinitions(resource, false);
+            return this.getDefinitions( resource,
+                                        false );
         }
 
-        public Set<KnowledgeDefinition> getDefinitions(Resource resource, boolean returnEmptyIfNull) {
-            Set<KnowledgeDefinition> definitions = this.map.get(resource);
-            if (returnEmptyIfNull && definitions == null) {
+        public Set<KnowledgeDefinition> getDefinitions(Resource resource,
+                                                       boolean returnEmptyIfNull) {
+            Set<KnowledgeDefinition> definitions = this.map.get( resource );
+            if ( returnEmptyIfNull && definitions == null ) {
                 definitions = new HashSet<KnowledgeDefinition>();
             }
             return definitions;
         }
 
         public boolean isResourceMapped(Resource resource) {
-            return this.map.containsKey(resource);
+            return this.map.containsKey( resource );
         }
 
         public Set<Resource> getAllResources() {
@@ -1180,8 +1267,8 @@
         }
 
         public boolean onlyHasPKGResources() {
-            for (Resource resource : map.keySet()) {
-                if (((InternalResource) resource).getResourceType() != ResourceType.PKG) {
+            for ( Resource resource : map.keySet() ) {
+                if ( ((InternalResource) resource).getResourceType() != ResourceType.PKG ) {
                     return false;
                 }
             }
@@ -1202,22 +1289,24 @@
      */
     private KnowledgeBuilder createKBuilder() {
 
-        if (this.registeredResources.onlyHasPKGResources()){
+        if ( this.registeredResources.onlyHasPKGResources() ) {
             return null;
         }
 
         KnowledgeBuilder kbuilder = 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()));
+        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 {
             kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
         }
 
-        if (this.dslResources != null) {
-            for (Map.Entry<Resource, String> entry : this.dslResources.entrySet()) {
-                kbuilder.add(ResourceFactory.newByteArrayResource(entry.getValue().getBytes()), ResourceType.DSL);
+        if ( this.dslResources != null ) {
+            for ( Map.Entry<Resource, String> entry : this.dslResources.entrySet() ) {
+                kbuilder.add( ResourceFactory.newByteArrayResource( entry.getValue().getBytes() ),
+                              ResourceType.DSL );
             }
         }
 
@@ -1225,35 +1314,40 @@
     }
 
     private void retrieveDSLResource(Resource resource) throws IOException {
-        BufferedReader bufferedReader = new BufferedReader(resource.getReader());
+        BufferedReader bufferedReader = new BufferedReader( resource.getReader() );
         String line = null;
         StringBuilder content = new StringBuilder();
-        while ((line = bufferedReader.readLine()) != null) {
-            content.append(line);
-            content.append("\n");
+        while ( (line = bufferedReader.readLine()) != null ) {
+            content.append( line );
+            content.append( "\n" );
         }
 
-        this.dslResources.put(resource, content.toString());
+        this.dslResources.put( resource,
+                               content.toString() );
     }
 
     public void addEventListener(KnowledgeAgentEventListener listener) {
-        this.eventSupport.addEventListener(listener);
+        this.eventSupport.addEventListener( listener );
     }
+    
+    public void removeEventListener(KnowledgeAgentEventListener listener) {
+        this.eventSupport.removeEventListener( listener );
+    }    
 
     public void dispose() {
-        synchronized (this.registeredResources) {
+        synchronized ( this.registeredResources ) {
             //all kbase's ksessions must be disposed
-            if (this.kbase != null) {
+            if ( this.kbase != null ) {
                 Collection<StatefulKnowledgeSession> statefulSessions = this.kbase.getStatefulKnowledgeSessions();
-                if (statefulSessions != null && statefulSessions.size() > 0) {
+                if ( statefulSessions != null && statefulSessions.size() > 0 ) {
                     String message = "The kbase still contains " + statefulSessions.size() + " stateful sessions. You must dispose them first.";
-                    this.listener.warning(message);
-                    throw new IllegalStateException(message);
+                    this.listener.warning( message );
+                    throw new IllegalStateException( message );
                 }
             }
 
             //stop changeSet Notification Detector
-            this.monitorResourceChangeEvents(false);
+            this.monitorResourceChangeEvents( false );
         }
     }
 
@@ -1266,11 +1360,9 @@
     protected void finalize() throws Throwable {
         // users should turn off monitoring, but just in case when this class is
         // GC'd we turn off the thread
-        if (this.changeSetNotificationDetector != null) {
+        if ( this.changeSetNotificationDetector != null ) {
             this.changeSetNotificationDetector.monitor = false;
 
-
-
         }
     }
 }

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/core/util/FileManager.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/core/util/FileManager.java	2010-12-04 04:44:13 UTC (rev 36211)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/core/util/FileManager.java	2010-12-04 18:09:28 UTC (rev 36212)
@@ -19,54 +19,66 @@
  */
 package org.drools.core.util;
 
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
 import java.io.File;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.StringReader;
 import java.util.UUID;
 
+import org.drools.io.impl.ResourceChangeScannerImpl;
+
 public class FileManager {
     //private Set<File> files;
     private File root;
-    
+
     public void setUp() {
         this.root = getRootDirectory();
     }
-    
-    public void tearDown() {            
-        // GC and Sleep, to give OS maximum chance of allowing stuff to be deleted. Attempt 5 times
-        boolean result = false;
-        for ( int i = 0; i < 5 && !result; i++ ) {
-            System.gc();
-            try {
-                Thread.sleep( 250 );
-            } catch ( InterruptedException e ) {
-                throw new RuntimeException( "This should never happen" );
-            }
-            
-            result = deleteDir( root );
-        }
+
+    public void tearDown() {
+        deleteDir( root );
     }
-    
+
     public File newFile(String name) {
-        File file = new File( getRootDirectory(), name);
+        File file = new File( getRootDirectory(),
+                              name );
         //files.add( file );
         return file;
     }
-    
-    public File newFile(File dir, String name) {
-        File file = new File( dir, name);
+
+    private File newFile(String path,
+                         String fileName) {
+        File file = new File( getRootDirectory(),
+                              path );
+        
+        file.mkdir();
         //files.add( file );
-        return file;        
+        return new File( file,
+                         fileName );
     }
-    
+
+    public File newFile(File dir,
+                        String name) {
+        File file = new File( dir,
+                              name );
+        //files.add( file );
+        return file;
+    }
+
     public File getRootDirectory() {
         if ( this.root != null ) {
             return this.root;
         }
-        File tmp = new File(System.getProperty( "java.io.tmpdir" ));
-        File f = new File(tmp, "__drools__" + UUID.randomUUID().toString() );
+        File tmp = new File( System.getProperty( "java.io.tmpdir" ) );
+        File f = new File( tmp,
+                           "__drools__" + UUID.randomUUID().toString() );
         //files.add( f );
-        if (f.exists()) {
-            if (f.isFile()) {
-                throw new IllegalStateException("The temp directory exists as a file. Nuke it now !");
+        if ( f.exists() ) {
+            if ( f.isFile() ) {
+                throw new IllegalStateException( "The temp directory exists as a file. Nuke it now !" );
             }
             deleteDir( f );
             f.mkdir();
@@ -77,34 +89,111 @@
         return this.root;
     }
 
+    public void deleteDir(File dir) {
+        // Will throw RuntimeException is anything fails to delete
+        String[] children = dir.list();
+        for ( String child : children ) {
+            File file = new File( dir,
+                                  child );
+            if ( file.isFile() ) {
+                deleteFile( file );
+            } else {
+                deleteDir( file );
+            }
+        }
+        
+        deleteFile( dir );
+    }
 
-    public boolean deleteDir(File dir) {
-
-        if (dir.isDirectory()) {
-            String[] children = dir.list();
-            for (String child : children) {
-                File file = new File(dir, child);
-                boolean success = deleteDir( file );
-                if (!success) {                    
-                    // this is a hack, but some time you need to wait for a file release to release
-                    // Windows was having intermittent issues with DirectoryScannerTest with the dir not being empty
-                    System.gc();
-                    try {
-                        Thread.sleep( 250 );
-                    } catch ( InterruptedException e ) {
-                        throw new RuntimeException( "This should never happen" );
-                    }
-                    success = deleteDir( file );
-                    if ( !success) {
-                        //ok now give up 
-                        //throw new RuntimeException("Unable to delete !");
-                        return false;
-                    }
+    public void deleteFile(File file) {
+        // This will attempt to delete a file 5 times, calling GC and Sleep between each iteration
+        // Sometimes windows takes a while to release a lock on a file.
+        // Throws an exception if it fails to delete
+        if ( !file.delete() ) {
+            int count = 0;
+            while ( !file.delete() && count++ < 5 ) {
+                System.gc();
+                try {
+                    Thread.sleep( 250 );
+                } catch ( InterruptedException e ) {
+                    throw new RuntimeException( "This should never happen" );
                 }
             }
         }
+        
+        if ( file.exists() ) {
+            try {
+                throw new RuntimeException( "Unable to delete file:" + file.getCanonicalPath() );
+            } catch ( IOException e ) {
+                throw new RuntimeException( "Unable to delete file", e);
+            }
+        }
 
-        // The directory is now empty so delete it
-        return dir.delete();
-    }      
+    }
+
+    public void write(File f,
+                      String text) throws IOException {
+        if ( f.exists() ) {
+            // we want to make sure there is a time difference for lastModified and lastRead checks as Linux and http often round to seconds
+            // http://saloon.javaranch.com/cgi-bin/ubb/ultimatebb.cgi?ubb=get_topic&f=1&t=019789
+            try {
+                Thread.sleep( 1000 );
+            } catch ( Exception e ) {
+                throw new RuntimeException( "Unable to sleep" );
+            }
+        }
+
+        // Attempt to write the file
+        BufferedWriter output = new BufferedWriter( new FileWriter( f ) );
+        output.write( text );
+        output.close();
+
+        // Now check the file was written and re-attempt if it was not        
+        // Need to do this for testing, to ensure the texts are read the same way, otherwise sometimes you get tail \n sometimes you don't
+        String t1 = StringUtils.toString( new StringReader( text ) );
+
+        int count = 0;
+        while ( !t1.equals( StringUtils.toString( new BufferedReader( new FileReader( f ) ) ) ) && count < 5 ) {
+            // The file failed to write, try 5 times, calling GC and sleep between each iteration
+            // Sometimes windows takes a while to release a lock on a file            
+            System.gc();
+            try {
+                Thread.sleep( 250 );
+            } catch ( InterruptedException e ) {
+                throw new RuntimeException( "This should never happen" );
+            }
+            output = new BufferedWriter( new FileWriter( f ) );
+            output.write( text );
+            output.close();
+            count++;
+        }
+
+        if ( count == 5 ) {
+            throw new IOException( "Unable to write to file:" + f.getCanonicalPath() );
+        }
+    }
+
+    public File write(String fileName,
+                      String text) throws IOException {
+        File f = newFile( fileName );
+
+        write( f,
+               text );
+
+        return f;
+
+    }
+
+    public File write(String path,
+                      String fileName,
+                      String text) throws IOException {
+        File f = newFile( path,
+                          fileName );
+
+        write( f,
+               text );
+
+        return f;
+    }
+
 }
\ No newline at end of file

Copied: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/core/util/IoUtils.java (from rev 36210, labs/jbossrules/trunk/drools-grid/drools-grid-impl/src/test/java/org/drools/grid/util/IoUtils.java)
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/core/util/IoUtils.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/core/util/IoUtils.java	2010-12-04 18:09:28 UTC (rev 36212)
@@ -0,0 +1,46 @@
+package org.drools.core.util;
+
+import java.io.IOException;
+import java.net.DatagramSocket;
+import java.net.ServerSocket;
+
+public class IoUtils {
+
+    public static int findPort() {
+        for( int i = 1024; i < 65535; i++) {
+            if ( validPort( i ) ) {
+                return i;
+            }
+        }
+        throw new RuntimeException( "No valid port could be found" );
+    }
+    
+    public static boolean validPort(int port) {
+
+        ServerSocket ss = null;
+        DatagramSocket ds = null;
+        try {
+            ss = new ServerSocket(port);
+            ss.setReuseAddress(true);
+            ds = new DatagramSocket(port);
+            ds.setReuseAddress(true);
+            return true;
+        } catch (IOException e) {
+        } finally {
+            if (ds != null) {
+                ds.close();
+            }
+
+            if (ss != null) {
+                try {
+                    ss.close();
+                } catch (IOException e) {
+                    /* should not be thrown */
+                }
+            }
+        }
+
+        return false;
+    }
+
+}

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/core/util/StringUtils.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/core/util/StringUtils.java	2010-12-04 04:44:13 UTC (rev 36211)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/core/util/StringUtils.java	2010-12-04 18:09:28 UTC (rev 36212)
@@ -1220,8 +1220,13 @@
         StringBuilder sb = new StringBuilder();
         try {
             String line;
+            boolean previousLine = false;
             while ((line = reader.readLine()) != null) {
-                sb.append(line).append("\n");
+                if ( previousLine ) {
+                    sb.append("\n");                    
+                }
+                sb.append(line);
+                previousLine = true;
             }
         } finally {
             reader.close();

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/io/impl/UrlResource.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/io/impl/UrlResource.java	2010-12-04 04:44:13 UTC (rev 36211)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/io/impl/UrlResource.java	2010-12-04 18:09:28 UTC (rev 36212)
@@ -269,7 +269,7 @@
     }
 
     private long grabLastMod() throws IOException {
-        // use File, as http rounds milliseconds on some machines, this fine level of granularity is only really an issue for testing
+        // use File if possible, as http rounds milliseconds on some machines, this fine level of granularity is only really an issue for testing
         // http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4504473
         if ( "file".equals( url.getProtocol() ) ) {
             File file = getFile();



More information about the jboss-svn-commits mailing list