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

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Tue Dec 9 12:18:38 EST 2008


Author: mark.proctor at jboss.com
Date: 2008-12-09 12:18:37 -0500 (Tue, 09 Dec 2008)
New Revision: 24321

Added:
   labs/jbossrules/trunk/drools-api/src/main/java/org/drools/SystemEventListener.java
   labs/jbossrules/trunk/drools-api/src/main/java/org/drools/SystemEventListenerFactory.java
   labs/jbossrules/trunk/drools-api/src/main/java/org/drools/SystemEventListenerProvider.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/agent/impl/PrintStreamSystemEventListener.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/impl/SystemEventListenerProviderImpl.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/util/DelegatingSystemEventListener.java
Removed:
   labs/jbossrules/trunk/drools-api/src/main/java/org/drools/agent/KnowledgeAgentEventListener.java
Modified:
   labs/jbossrules/trunk/drools-api/src/main/java/org/drools/ChangeSet.java
   labs/jbossrules/trunk/drools-api/src/main/java/org/drools/KnowledgeBase.java
   labs/jbossrules/trunk/drools-api/src/main/java/org/drools/KnowledgeBaseFactory.java
   labs/jbossrules/trunk/drools-api/src/main/java/org/drools/KnowledgeBaseProvider.java
   labs/jbossrules/trunk/drools-api/src/main/java/org/drools/agent/KnowledgeAgent.java
   labs/jbossrules/trunk/drools-api/src/main/java/org/drools/agent/KnowledgeAgentFactory.java
   labs/jbossrules/trunk/drools-api/src/main/java/org/drools/agent/KnowledgeAgentProvider.java
   labs/jbossrules/trunk/drools-api/src/main/java/org/drools/builder/KnowledgeBuilder.java
   labs/jbossrules/trunk/drools-api/src/main/java/org/drools/io/ResourceChangeMonitor.java
   labs/jbossrules/trunk/drools-api/src/main/java/org/drools/io/ResourceChangeNotifier.java
   labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/agent/KnowledgeAgentTest.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/agent/AgentEventListener.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/agent/RuleAgent.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/agent/impl/KnowledgeAgentProviderImpl.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/io/impl/ResourceChangeNotifierImpl.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/io/impl/ResourceChangeScannerImpl.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/io/impl/ResourceProviderImpl.java
   labs/jbossrules/trunk/drools-core/src/test/java/org/drools/agent/MockListener.java
   labs/jbossrules/trunk/drools-core/src/test/java/org/drools/agent/RuleAgentTest.java
Log:
JBRULES-1885 Update KnowledgeAgent to use new Resource api
-Migrating the RuleAgent, there is now a central factory for event logging.

-more javadocs

Modified: labs/jbossrules/trunk/drools-api/src/main/java/org/drools/ChangeSet.java
===================================================================
--- labs/jbossrules/trunk/drools-api/src/main/java/org/drools/ChangeSet.java	2008-12-09 17:06:47 UTC (rev 24320)
+++ labs/jbossrules/trunk/drools-api/src/main/java/org/drools/ChangeSet.java	2008-12-09 17:18:37 UTC (rev 24321)
@@ -14,12 +14,41 @@
  * part of the ResourceType api when adding to KnowledgeBuilder, which is considered stable. KnowledgeBuilder currently ignored Added/Modified xml elements,
  * the KnowledgeAgent will use them, when rebuilding the KnowledgeBase.
  * 
+ * the xml format has a root level <change-set> element and then it can contain <add>, <modified>, <removed> elements - each one can only be used once.
+ * add, modified, removed then contain a list of <resource> elements. Resources may take a configuration, currently only decision table resources use that.
+ * <pre>
+ * &lt;change-set xmlns='http://drools.org/drools-5.0/change-set'
+ *             xmlns:xs='http://www.w3.org/2001/XMLSchema-instance'
+ *             xs:schemaLocation='http://drools.org/drools-5.0/change-set drools-change-set-5.0.xsd' &gt;
+ *  &lt;add&gt;
+ *       &lt;resource source='http:org/domain/myrules.drl' type='DRL' /&gt;
+ *       &lt;resource source='classpath:data/IntegrationExampleTest.xls' type="DTABLE"&gt;
+ *           &lt;decisiontable-conf input-type="XLS" worksheet-name="Tables_2" /&gt;
+ *       &lt;/resource&gt;
+ *       &lt;resource source='file:org/drools/decisiontable/myflow.drf' type='DRF' /&gt;
+ *   &lt;/add&gt;
+ * &lt;/change-set&gt;
+ * </pre>
+ * 
+ * 
  */
 public interface ChangeSet {
+    /**
+     * Returns an immutable Collection of removed Resources for this ChangeSet
+     * @return
+     */
     public Collection<Resource> getResourcesRemoved();
 
+    /**
+     * Returns an immutable Collection of added Resources for this ChangeSet
+     * @return
+     */    
     public Collection<Resource> getResourcesAdded();
     
+    /**
+     * Returns an immutable Collection of modified Resources for this ChangeSet
+     * @return
+     */    
     public Collection<Resource> getResourcesModified();
 
 }

Modified: labs/jbossrules/trunk/drools-api/src/main/java/org/drools/KnowledgeBase.java
===================================================================
--- labs/jbossrules/trunk/drools-api/src/main/java/org/drools/KnowledgeBase.java	2008-12-09 17:06:47 UTC (rev 24320)
+++ labs/jbossrules/trunk/drools-api/src/main/java/org/drools/KnowledgeBase.java	2008-12-09 17:18:37 UTC (rev 24321)
@@ -15,13 +15,24 @@
  * does not contain data, instead sessions are created from the KnowledgeBase in which
  * data can be inserted and process instances started. Creating the KnowlegeBase can be 
  * heavy, where as session creation is very light, so it is recommended that KnowleBase's
- * be cached where possible to allow for repeated session creation. The KnowledgeBase
- * is created from the KnowledgeBaseFactory:
+ * be cached where possible to allow for repeated session creation. The KnowledgeAgent
+ * can be used for this purpose. The KnowledgeBase is created from the KnowledgeBaseFactory,
+ * and a KnowledgeBaseConfiguration can be used.
  * </p>
  * <pre>
  * KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
  * </pre>
  * 
+ * <p>
+ * Create sequential KnowledgeBase using the given ClassLoader.
+ * </p>
+ * <pre>
+ * Properties properties = new Properties();
+ * properties.setProperty( "org.drools.sequential", "true");
+ * KnowledgeBaseConfiguration kbConf = KnowledgeBaseFactory.newKnowledgeBaseConfiguration(properties, myClassLoader);
+ * KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase(kbConf);
+ * </pre>
+ * 
  * @see org.drools.KnowledgeBaseFactory
  * 
  */

Modified: labs/jbossrules/trunk/drools-api/src/main/java/org/drools/KnowledgeBaseFactory.java
===================================================================
--- labs/jbossrules/trunk/drools-api/src/main/java/org/drools/KnowledgeBaseFactory.java	2008-12-09 17:06:47 UTC (rev 24320)
+++ labs/jbossrules/trunk/drools-api/src/main/java/org/drools/KnowledgeBaseFactory.java	2008-12-09 17:18:37 UTC (rev 24321)
@@ -10,6 +10,16 @@
  * <pre>
  * KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
  * </pre>
+ * 
+ * <p>
+ * Create sequential KnowledgeBase using the given ClassLoader.
+ * </p>
+ * <pre>
+ * Properties properties = new Properties();
+ * properties.setProperty( "org.drools.sequential", "true");
+ * KnowledgeBaseConfiguration kbConf = KnowledgeBaseFactory.newKnowledgeBaseConfiguration(properties, myClassLoader);
+ * KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase(kbConf);
+ * </pre>
  *
  * @see org.drools.KnowledgeBase
  */

Modified: labs/jbossrules/trunk/drools-api/src/main/java/org/drools/KnowledgeBaseProvider.java
===================================================================
--- labs/jbossrules/trunk/drools-api/src/main/java/org/drools/KnowledgeBaseProvider.java	2008-12-09 17:06:47 UTC (rev 24320)
+++ labs/jbossrules/trunk/drools-api/src/main/java/org/drools/KnowledgeBaseProvider.java	2008-12-09 17:18:37 UTC (rev 24321)
@@ -6,7 +6,7 @@
  * KnowledgeBaseProvider is used by the KnowledgeBaseFacotry to "provide" it's concrete implementation.
  * 
  * This class is not considered stable and may change, the user is protected from this change by using 
- * the Factory api, which is consiered stable.
+ * the KnowledgeBaseFactory api, which is considered stable.
  *
  */
 public interface KnowledgeBaseProvider {

Copied: labs/jbossrules/trunk/drools-api/src/main/java/org/drools/SystemEventListener.java (from rev 24315, labs/jbossrules/trunk/drools-api/src/main/java/org/drools/agent/KnowledgeAgentEventListener.java)
===================================================================
--- labs/jbossrules/trunk/drools-api/src/main/java/org/drools/SystemEventListener.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-api/src/main/java/org/drools/SystemEventListener.java	2008-12-09 17:18:37 UTC (rev 24321)
@@ -0,0 +1,43 @@
+package org.drools;
+
+/**
+ * <p>
+ * This interface is used to provide callback style logging for the system events.
+ * </p>
+ * 
+ * <p>
+ * The SystemEventListenerFactory is used to provide the default SystemEventListener to various Drools components
+ * such as the KnowledgeAgent, ResourceChangeNotifier and ResourceChangeListener. Although many of these components
+ * allow the used listener to be overriden with a setSystemEventListener(SystemEventListener) method.
+ * </p>
+ * 
+ * Componens 
+ * 
+ */
+public interface SystemEventListener {
+    /**
+     * For general info messages
+     */
+    public void info(String message);
+    
+    public void info(String message, Object object);
+
+    /**
+     * For a warning (useful when tracking down problems).
+     */
+    public void warning(String message);
+    
+    public void warning(String message, Object object);
+
+    /**
+     * An exception occurred.
+     */
+    public void exception(Exception e);
+
+    /**
+     * These should not be logged, just shown if needed.
+     */
+    public void debug(String message);
+    
+    public void debug(String message, Object object);
+}

Added: labs/jbossrules/trunk/drools-api/src/main/java/org/drools/SystemEventListenerFactory.java
===================================================================
--- labs/jbossrules/trunk/drools-api/src/main/java/org/drools/SystemEventListenerFactory.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-api/src/main/java/org/drools/SystemEventListenerFactory.java	2008-12-09 17:18:37 UTC (rev 24321)
@@ -0,0 +1,50 @@
+package org.drools;
+
+/**
+ * This factory allows you to set the SystemEventListener that will be used by various components of Drools, such
+ * as the KnowledgeAgent, ResourceChangeNotifier and ResourceChangeListener.
+ * 
+ * The default SystemEventListener
+ *
+ */
+public class SystemEventListenerFactory {
+    private static SystemEventListenerProvider provider;
+    
+    /**
+     * Set the SystemEventListener
+     * 
+     * @param listener
+     */
+    public static void setSystemEventListener(SystemEventListener listener) {
+        getSystemEventListenerProvider().setSystemEventListener( listener );
+    }
+    
+    /**
+     * Get the SystemEventListener
+     * @return
+     */
+    public static SystemEventListener getSystemEventListener() {
+        return getSystemEventListenerProvider().getSystemEventListener();
+    }
+    
+    private static synchronized void setSystemEventListenerProvider(SystemEventListenerProvider provider) {
+        SystemEventListenerFactory.provider = provider;
+    }
+
+    private static synchronized SystemEventListenerProvider getSystemEventListenerProvider() {
+        if ( provider == null ) {
+            loadProvider();
+        }
+        return provider;
+    }
+
+    private static void loadProvider() {
+        try {
+            // we didn't find anything in properties so lets try and us reflection
+            Class<SystemEventListenerProvider> cls = (Class<SystemEventListenerProvider>) Class.forName( "org.drools.impl.SystemEventListenerProviderImpl" );
+            setSystemEventListenerProvider( cls.newInstance() );
+        } catch ( Exception e ) {
+            throw new ProviderInitializationException( "Provider org.drools.impl.SystemEventListenerProviderImpl could not be set.", e );
+        }
+    }    
+}

Added: labs/jbossrules/trunk/drools-api/src/main/java/org/drools/SystemEventListenerProvider.java
===================================================================
--- labs/jbossrules/trunk/drools-api/src/main/java/org/drools/SystemEventListenerProvider.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-api/src/main/java/org/drools/SystemEventListenerProvider.java	2008-12-09 17:18:37 UTC (rev 24321)
@@ -0,0 +1,25 @@
+package org.drools;
+
+/**
+ * KnowledgeBaseProvider is used by the KnowledgeBaseFacotry to "provide" it's concrete implementation.
+ * 
+ * This class is not considered stable and may change, the user is protected from this change by using 
+ * the KnowledgeBaseFactory api, which is considered stable.
+ *
+ */
+public interface SystemEventListenerProvider {
+    
+    /**
+     * Set the SystemEventListener
+     * 
+     * @param listener
+     */    
+    void setSystemEventListener(SystemEventListener listener);
+    
+    /**
+     * Get the SystemEventListener
+     * @return
+     */    
+    SystemEventListener getSystemEventListener();
+    
+}

Modified: labs/jbossrules/trunk/drools-api/src/main/java/org/drools/agent/KnowledgeAgent.java
===================================================================
--- labs/jbossrules/trunk/drools-api/src/main/java/org/drools/agent/KnowledgeAgent.java	2008-12-09 17:06:47 UTC (rev 24320)
+++ labs/jbossrules/trunk/drools-api/src/main/java/org/drools/agent/KnowledgeAgent.java	2008-12-09 17:18:37 UTC (rev 24321)
@@ -2,6 +2,7 @@
 
 import org.drools.KnowledgeBase;
 import org.drools.KnowledgeBaseFactory;
+import org.drools.SystemEventListener;
 import org.drools.io.Resource;
 import org.drools.io.ResourceChangeScannerConfiguration;
 import org.drools.io.ResourceFactory;
@@ -20,26 +21,32 @@
  * KnowledgeBase, instead of upating the existing one, due to the "newInstance" set to "true":
  * <p/>
  * <pre>
- * KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
- *
+ * // Set the interval on the ResourceChangeScannerService if you are to use it and default of 60s is not desirable.
  * ResourceChangeScannerConfiguration sconf = ResourceFactory.getResourceChangeScannerService().newResourceChangeScannerConfiguration();
  * sconf.setProperty( "drools.resource.scanner.interval",
  *                    "30" ); // set the disk scanning interval to 30s, default is 60s
  * ResourceFactory.getResourceChangeScannerService().configure( sconf );
+ * 
+ * KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
  *
  * KnowledgeAgentConfiguration aconf = KnowledgeAgentFactory.newKnowledgeAgentConfiguration();
-        aconf.setProperty( "drools.agent.scanDirectories",
-                           "true" ); // we want to scan directories, not just files, turning this on turns on file scanning
-        aconf.setProperty( "drools.agent.newInstance",
-                           "true" ); // resource changes results in a new instance of the KnowledgeBase being built, 
-                                     // this cannot currently be set to false for incremental building
-        
-        KnowledgeAgent kagent = KnowledgeAgentFactory.newKnowledgeAgent( "test agent", // the name of the agent
-                                                                         kbase, // the rulebase to use, the Agent will also monitor any exist knowledge definitions
-                                                                         aconf );
-        kagent.applyChangeSet( ResourceFactory.newUrlResource( url ) ); // resource to the change-set xml for the resources to add
+ *       aconf.setProperty( "drools.agent.scanDirectories",
+ *                          "true" ); // we want to scan directories, not just files, turning this on turns on file scanning
+ *       aconf.setProperty( "drools.agent.newInstance",
+ *                          "true" ); // resource changes results in a new instance of the KnowledgeBase being built, 
+ *                                    // this cannot currently be set to false for incremental building
+ *       
+ *       KnowledgeAgent kagent = KnowledgeAgentFactory.newKnowledgeAgent( "test agent", // the name of the agent
+ *                                                                        kbase, // the rulebase to use, the Agent will also monitor any exist knowledge definitions
+ *                                                                        aconf );
+ *       kagent.applyChangeSet( ResourceFactory.newUrlResource( url ) ); // resource to the change-set xml for the resources to add
  * </pre>
  * 
+ * KnowledgeAgents can take a empty KnowledgeBase or a populated one. If a populated KnowledgeBase is provided, the KnowledgeAgent
+ * will iterate KnowledgeBase and subscribe to the Resource that it finds. While it is possible for the KnowledgeBuilder to build
+ * all resources found in a directory, that information is lost by the KnowledgeBuilder so those directories will not be continously scanned.
+ * Only directories specified as part of the applyChangeSet(Resource) method are monitored.
+ * 
  * @see org.drools.agent.KnowledgeAgentFactory
  * 
  */
@@ -61,4 +68,6 @@
     void monitorResourceChangeEvents(boolean monitor);
     
     void applyChangeSet(Resource resource);
+    
+    void setSystemEventListener(SystemEventListener listener);    
 }

Deleted: labs/jbossrules/trunk/drools-api/src/main/java/org/drools/agent/KnowledgeAgentEventListener.java
===================================================================
--- labs/jbossrules/trunk/drools-api/src/main/java/org/drools/agent/KnowledgeAgentEventListener.java	2008-12-09 17:06:47 UTC (rev 24320)
+++ labs/jbossrules/trunk/drools-api/src/main/java/org/drools/agent/KnowledgeAgentEventListener.java	2008-12-09 17:18:37 UTC (rev 24321)
@@ -1,27 +0,0 @@
-package org.drools.agent;
-
-/**
- * This interface is used to provide callback style logging for the agents events.
- * 
- */
-public interface KnowledgeAgentEventListener {
-    /**
-     * For general info messages
-     */
-    public void info(String message);
-
-    /**
-     * For a warning (useful when tracking down problems).
-     */
-    public void warning(String message);
-
-    /**
-     * An exception occurred.
-     */
-    public void exception(Exception e);
-
-    /**
-     * These should not be logged, just shown if needed.
-     */
-    public void debug(String message);
-}

Modified: labs/jbossrules/trunk/drools-api/src/main/java/org/drools/agent/KnowledgeAgentFactory.java
===================================================================
--- labs/jbossrules/trunk/drools-api/src/main/java/org/drools/agent/KnowledgeAgentFactory.java	2008-12-09 17:06:47 UTC (rev 24320)
+++ labs/jbossrules/trunk/drools-api/src/main/java/org/drools/agent/KnowledgeAgentFactory.java	2008-12-09 17:18:37 UTC (rev 24321)
@@ -4,6 +4,7 @@
 
 import org.drools.KnowledgeBase;
 import org.drools.KnowledgeBaseConfiguration;
+import org.drools.SystemEventListener;
 import org.drools.ProviderInitializationException;
 
 
@@ -29,14 +30,6 @@
         return getKnowledgeAgentProvider().newKnowledgeAgent( name, kbase, configuration );
     }
 
-    public static KnowledgeAgent newKnowledgeAgent(String name,
-                                                   KnowledgeBase kbase,
-                                                   KnowledgeAgentConfiguration configuration,
-                                                   KnowledgeAgentEventListener listener) {
-
-        return getKnowledgeAgentProvider().newKnowledgeAgent( name, kbase, configuration, listener );
-    }
-
     private static synchronized void setKnowledgeAgentProvider(KnowledgeAgentProvider provider) {
         KnowledgeAgentFactory.provider = provider;
     }

Modified: labs/jbossrules/trunk/drools-api/src/main/java/org/drools/agent/KnowledgeAgentProvider.java
===================================================================
--- labs/jbossrules/trunk/drools-api/src/main/java/org/drools/agent/KnowledgeAgentProvider.java	2008-12-09 17:06:47 UTC (rev 24320)
+++ labs/jbossrules/trunk/drools-api/src/main/java/org/drools/agent/KnowledgeAgentProvider.java	2008-12-09 17:18:37 UTC (rev 24321)
@@ -15,9 +15,4 @@
     KnowledgeAgent newKnowledgeAgent(String name,
                                      KnowledgeBase kbase,
                                      KnowledgeAgentConfiguration configuration);
-
-    KnowledgeAgent newKnowledgeAgent(String name,
-                                     KnowledgeBase kbase,
-                                     KnowledgeAgentConfiguration configuration,
-                                     KnowledgeAgentEventListener listener);
 }

Modified: labs/jbossrules/trunk/drools-api/src/main/java/org/drools/builder/KnowledgeBuilder.java
===================================================================
--- labs/jbossrules/trunk/drools-api/src/main/java/org/drools/builder/KnowledgeBuilder.java	2008-12-09 17:06:47 UTC (rev 24320)
+++ labs/jbossrules/trunk/drools-api/src/main/java/org/drools/builder/KnowledgeBuilder.java	2008-12-09 17:18:37 UTC (rev 24321)
@@ -12,6 +12,7 @@
  * The KnowledgeBuilder is responsible for taking source files, such as a .drl file or an xls file,
  * and turning them into a KnowledgePackage of rule and process definitions which a KnowledgeBase
  * can consume. It uses the ResourceType enum to tell it the type of the resource it is being asked to build.
+ * 
  * </p>
  * 
  * <p>

Modified: labs/jbossrules/trunk/drools-api/src/main/java/org/drools/io/ResourceChangeMonitor.java
===================================================================
--- labs/jbossrules/trunk/drools-api/src/main/java/org/drools/io/ResourceChangeMonitor.java	2008-12-09 17:06:47 UTC (rev 24320)
+++ labs/jbossrules/trunk/drools-api/src/main/java/org/drools/io/ResourceChangeMonitor.java	2008-12-09 17:18:37 UTC (rev 24321)
@@ -1,5 +1,7 @@
 package org.drools.io;
 
+import org.drools.SystemEventListener;
+
 /**
  * <p>
  * Subscribes and unsubscribes the given notifier to the requested resource. The Monitor will inform the notifier when when results it susbcribes to are changed
@@ -29,4 +31,6 @@
      * @param resource
      */
     void unsubscribeNotifier(ResourceChangeNotifier notifier, Resource resource);
+    
+    public void setSystemEventListener(SystemEventListener listener);
 }

Modified: labs/jbossrules/trunk/drools-api/src/main/java/org/drools/io/ResourceChangeNotifier.java
===================================================================
--- labs/jbossrules/trunk/drools-api/src/main/java/org/drools/io/ResourceChangeNotifier.java	2008-12-09 17:06:47 UTC (rev 24320)
+++ labs/jbossrules/trunk/drools-api/src/main/java/org/drools/io/ResourceChangeNotifier.java	2008-12-09 17:18:37 UTC (rev 24321)
@@ -3,6 +3,7 @@
 import java.util.Collection;
 
 import org.drools.ChangeSet;
+import org.drools.SystemEventListener;
 import org.drools.event.io.ResourceChangeListener;
 
 /**
@@ -63,8 +64,10 @@
      * 
      * @param changeSet
      */
-    void publishKnowledgeBaseChangeSet(ChangeSet changeSet);
+    void publishChangeSet(ChangeSet changeSet);
     
+    public void setSystemEventListener(SystemEventListener listener);
+    
     /**
      * Start the service, this will create a new Thread.
      */

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	2008-12-09 17:06:47 UTC (rev 24320)
+++ labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/agent/KnowledgeAgentTest.java	2008-12-09 17:18:37 UTC (rev 24321)
@@ -70,7 +70,7 @@
         String xml = "";
         xml += "<change-set xmlns='http://drools.org/drools-5.0/change-set'";
         xml += "    xmlns:xs='http://www.w3.org/2001/XMLSchema-instance'";
-        xml += "    xs:schemaLocation='http://drools.org/drools-5.0/change-set drools-change-set-4.0.xsd' >";
+        xml += "    xs:schemaLocation='http://drools.org/drools-5.0/change-set drools-change-set-5.0.xsd' >";
         xml += "    <add> ";
         xml += "        <resource source='" + f1.toURI().toURL() + "' type='DRL' />";
         xml += "        <resource source='" + f2.toURI().toURL() + "' type='DRL' />";

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/agent/AgentEventListener.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/agent/AgentEventListener.java	2008-12-09 17:06:47 UTC (rev 24320)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/agent/AgentEventListener.java	2008-12-09 17:18:37 UTC (rev 24321)
@@ -1,12 +1,14 @@
 package org.drools.agent;
 
+import org.drools.SystemEventListener;
+
 /**
  * This interface is used to provide callback style logging for the agents
  * async events.
  * 
  * @author Michael Neale
  */
-public interface AgentEventListener extends KnowledgeAgentEventListener {
+public interface AgentEventListener extends SystemEventListener {
 
     /**
      * This sets the name for logging.

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/agent/RuleAgent.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/agent/RuleAgent.java	2008-12-09 17:06:47 UTC (rev 24320)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/agent/RuleAgent.java	2008-12-09 17:18:37 UTC (rev 24321)
@@ -561,6 +561,18 @@
 
             }
 
+            public void debug(String message,
+                              Object object) {
+            }
+
+            public void info(String message,
+                             Object object) {
+            }
+
+            public void warning(String message,
+                                Object object) { 
+            }
+
         };
     }
 

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	2008-12-09 17:06:47 UTC (rev 24320)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/agent/impl/KnowledgeAgentImpl.java	2008-12-09 17:18:37 UTC (rev 24321)
@@ -12,10 +12,11 @@
 import org.drools.ChangeSet;
 import org.drools.KnowledgeBase;
 import org.drools.KnowledgeBaseFactory;
+import org.drools.SystemEventListener;
 import org.drools.RuleBase;
+import org.drools.SystemEventListenerFactory;
 import org.drools.agent.KnowledgeAgent;
 import org.drools.agent.KnowledgeAgentConfiguration;
-import org.drools.agent.KnowledgeAgentEventListener;
 import org.drools.builder.KnowledgeBuilder;
 import org.drools.builder.KnowledgeBuilderFactory;
 import org.drools.builder.ResourceType;
@@ -41,62 +42,67 @@
 public class KnowledgeAgentImpl
     implements
     KnowledgeAgent,
-    ResourceChangeListener,
-    Runnable {
+    ResourceChangeListener {
     private String                         name;
     private Map<Resource, ResourceMapping> resources;
     private Set<Resource>                  resourceDirectories;
     private KnowledgeBase                  kbase;
     private ResourceChangeNotifierImpl     notifier;
     private boolean                        newInstance;
-    private KnowledgeAgentEventListener    listener;
+    private SystemEventListener            listener;
     private boolean                        scanDirectories;
     private LinkedBlockingQueue<ChangeSet> queue;
     private Thread                         thread;
-    private volatile boolean               monitor;
+    private ChangeSetNotificationDetector  changeSetNotificationDetector;
+    private SemanticModules                semanticModules;
 
     public KnowledgeAgentImpl(String name,
                               KnowledgeBase kbase,
-                              KnowledgeAgentConfiguration configuration,
-                              KnowledgeAgentEventListener listener) {
+                              KnowledgeAgentConfiguration configuration) {
         this.kbase = kbase;
         this.resources = new HashMap<Resource, ResourceMapping>();
         this.resourceDirectories = new HashSet<Resource>();
-        this.listener = listener;
+        //this.listener = listener;
+        this.listener = SystemEventListenerFactory.getSystemEventListener();
         this.newInstance = true; // we hard code this for now as incremental kbase changes don't work.
+        this.queue = new LinkedBlockingQueue<ChangeSet>();
+        boolean scanResources = false;
+        boolean monitor = false;
         if ( configuration != null ) {
             //this.newInstance = ((KnowledgeAgentConfigurationImpl) configuration).isNewInstance();
             this.notifier = (ResourceChangeNotifierImpl) ResourceFactory.getResourceChangeNotifierService();
             if ( ((KnowledgeAgentConfigurationImpl) configuration).isMonitorChangeSetEvents() ) {
-                this.monitor = true;
+                monitor = true;
             }
 
             if ( ((KnowledgeAgentConfigurationImpl) configuration).isScanDirectories() ) {
                 this.scanDirectories = true;
             }
 
-            if ( ((KnowledgeAgentConfigurationImpl) configuration).isScanResources() ) {
+            scanResources = ((KnowledgeAgentConfigurationImpl) configuration).isScanResources();
+            if ( scanResources ) {
                 this.notifier.addResourceChangeMonitor( ResourceFactory.getResourceChangeScannerService() );
-                this.monitor = true; // if scanning, monitor must be true;
+                monitor = true; // if scanning, monitor must be true;
             }
         }
 
-        if ( this.monitor ) {
-            this.queue = new LinkedBlockingQueue<ChangeSet>();
-            thread = new Thread( this );
-            thread.start();
-        }
+        monitorResourceChangeEvents( monitor );
 
         buildResourceMapping( kbase );
+
+        this.listener.info( "KnowledgAgent created, with configuration:\nmonitorChangeSetEvents=" + monitor + " scanResources=" + scanResources + " scanDirectories=" + this.scanDirectories );
     }
 
-    SemanticModules semanticModules;
+    public void setSystemEventListener(SystemEventListener listener) {
+        this.listener = listener;
+    }
 
     public void applyChangeSet(Resource resource) {
         applyChangeSet( getChangeSet( resource ) );
     }
 
     public void applyChangeSet(ChangeSet changeSet) {
+        this.listener.info( "KnowledgAgent applying ChangeSet" );
         ChangeSetState changeSetState = new ChangeSetState();
         changeSetState.scanDirectories = this.scanDirectories;
         processChangeSet( changeSet,
@@ -114,42 +120,45 @@
 
     public void processChangeSet(ChangeSet changeSet,
                                  ChangeSetState changeSetState) {
-        for ( Resource resource : changeSet.getResourcesAdded() ) {           
-            if ( ((InternalResource)resource).isDirectory() ) {
+        for ( Resource resource : changeSet.getResourcesAdded() ) {
+            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() ) {
-                    if ( ((InternalResource)child).isDirectory() ) {
-                        continue;  // ignore sub directories
+                for ( Resource child : ((InternalResource) resource).listResources() ) {
+                    if ( ((InternalResource) child).isDirectory() ) {
+                        continue; // ignore sub directories
                     }
-                    ((InternalResource)child).setResourceType( ((InternalResource)resource).getResourceType() );
+                    ((InternalResource) child).setResourceType( ((InternalResource) resource).getResourceType() );
                     ResourceMapping mapping = this.resources.get( child );
                     if ( mapping == null ) {
+                        this.listener.debug( "KnowledgeAgent subscribing to directory content resource=" + child );
                         this.notifier.subscribeResourceChangeListener( this,
                                                                        child );
                         mapping = new ResourceMapping( child );
                         this.resources.put( child,
                                             mapping );
-                    }                     
+                    }
                 }
-            } else {   
-                if ( ((InternalResource) resource).getResourceType() == ResourceType.PKG ) {                               
+            } else {
+                if ( ((InternalResource) resource).getResourceType() == ResourceType.PKG ) {
                     changeSetState.pkgs.add( resource );
                 } else if ( ((InternalResource) resource).getResourceType() == ResourceType.ChangeSet ) {
                     // @TODO
                     continue;
                 }
-                
+
                 ResourceMapping mapping = this.resources.get( resource );
                 if ( mapping == null ) {
+                    this.listener.debug( "KnowledgeAgent subscribing to resource=" + resource );
                     this.notifier.subscribeResourceChangeListener( this,
                                                                    resource );
                     mapping = new ResourceMapping( resource );
                     this.resources.put( resource,
                                         mapping );
-                }       
+                }
             }
         }
 
@@ -158,10 +167,12 @@
                 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 {
+                this.listener.debug( "KnowledgeAgent unsubscribing from resource=" + resource );
                 this.resources.remove( resource );
                 this.notifier.unsubscribeResourceChangeListener( this,
                                                                  resource );
@@ -170,7 +181,8 @@
 
         // are we going to need kbuilder to build these resources?
         for ( Resource resource : this.resources.keySet() ) {
-            if ( ((InternalResource) resource).getResourceType() != ResourceType.ChangeSet && ((InternalResource) resource).getResourceType() != ResourceType.PKG  ) {
+            this.listener.debug( "KnowledgeAgent ChangeSet requires KnowledgeBuilder" );
+            if ( ((InternalResource) resource).getResourceType() != ResourceType.ChangeSet && ((InternalResource) resource).getResourceType() != ResourceType.PKG ) {
                 changeSetState.needsKnowledgeBuilder = true;
                 break;
             }
@@ -190,14 +202,16 @@
         } else {
             reader.setClassLoader( ((AbstractRuleBase) (((KnowledgeBaseImpl) this.kbase).ruleBase)).getConfiguration().getClassLoader() );
         }
+
         ChangeSet changeSet = null;
         try {
             changeSet = reader.read( resource.getReader() );
         } catch ( Exception e ) {
-            // @TODO add proper error handling
+            this.listener.exception( new RuntimeException( "Unable to parse ChangeSet",
+                                                           e ) );
         }
         if ( changeSet == null ) {
-            // @TODO should log an error
+            this.listener.exception( new RuntimeException( "Unable to parse ChangeSet" ) );
         }
         return changeSet;
     }
@@ -210,7 +224,7 @@
 
     public void buildResourceMapping(KnowledgeBase kbase) {
         RuleBase rbase = ((KnowledgeBaseImpl) kbase).ruleBase;
-
+        this.listener.debug( "KnowledgeAgent building resource map" );
         synchronized ( this.resources ) {
 
             for ( Package pkg : rbase.getPackages() ) {
@@ -227,8 +241,8 @@
                         this.resources.put( resource,
                                             mapping );
                     }
+                    this.listener.debug( "KnowledgeAgent mapping resource=" + resource + " to rule=" + rule );
                     mapping.getKnowledgeDefinitions().add( rule );
-                    System.out.println( "agent : " + resource );
                 }
 
                 for ( Process process : pkg.getRuleFlows().values() ) {
@@ -244,8 +258,8 @@
                         this.resources.put( resource,
                                             mapping );
                     }
+                    this.listener.debug( "KnowledgeAgent mapping resource=" + resource + " to process=" + process );
                     mapping.getKnowledgeDefinitions().add( process );
-                    System.out.println( "agent : " + resource );
                 }
 
                 for ( TypeDeclaration typeDeclaration : pkg.getTypeDeclarations().values() ) {
@@ -261,8 +275,8 @@
                         this.resources.put( resource,
                                             mapping );
                     }
+                    this.listener.debug( "KnowledgeAgent mapping resource=" + resource + " to TypeDeclaration=" + typeDeclaration );
                     mapping.getKnowledgeDefinitions().add( typeDeclaration );
-                    System.out.println( "agent : " + resource );
                 }
 
                 for ( Function function : pkg.getFunctions().values() ) {
@@ -278,8 +292,8 @@
                         this.resources.put( resource,
                                             mapping );
                     }
+                    this.listener.debug( "KnowledgeAgent mapping resource=" + resource + " to function=" + function );
                     mapping.getKnowledgeDefinitions().add( function );
-                    System.out.println( "agent : " + resource );
                 }
             }
         }
@@ -309,44 +323,27 @@
 
     public void resourcesChanged(ChangeSet changeSet) {
         try {
-            System.out.println( "agent resource changed" );
+            this.listener.debug( "KnowledgeAgent received ChangeSet changed notification" );
             this.queue.put( changeSet );
         } catch ( InterruptedException e ) {
-            // @TODO add proper error message
-            e.printStackTrace();
+            this.listener.exception( new RuntimeException( "KnowledgeAgent error while adding ChangeSet notification to queue",
+                                                           e ) );
         }
     }
 
-    public static class ResourceMapping {
-        private Resource                 resource;
-        private Set<KnowledgeDefinition> knowledgeDefinitions;
-
-        public ResourceMapping(Resource resource) {
-            this.knowledgeDefinitions = new HashSet<KnowledgeDefinition>();
-        }
-
-        public Resource getResource() {
-            return resource;
-        }
-
-        public Set<KnowledgeDefinition> getKnowledgeDefinitions() {
-            return knowledgeDefinitions;
-        }
-
-    }
-
     private void rebuildResources(ChangeSetState changeSetState) {
-        // for now we assume newIntance only, so just blow away the mappings and knowledgedefinition sets.
+        this.listener.debug( "KnowledgeAgent rebuilding KnowledgeBase using ChangeSet" );
         synchronized ( this.resources ) {
             for ( Resource child : changeSetState.pkgs ) {
+
                 try {
                     InputStream is = child.getInputStream();
                     Package pkg = (Package) DroolsStreamUtils.streamIn( is );
+                    this.listener.debug( "KnowledgeAgent adding KnowledgeDefinitionsPackage " + pkg.getName() );
                     ((KnowledgeBaseImpl) this.kbase).ruleBase.addPackage( pkg );
                     is.close();
                 } catch ( Exception e ) {
-                    // @TODO add proper error
-                    e.printStackTrace();
+                    this.listener.exception( new RuntimeException( "KnowledgeAgent exception while trying to serialize and KnowledgeDefinitionsPackage  " ) );
                 }
             }
 
@@ -363,18 +360,22 @@
                 KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
 
                 for ( Resource resource : resourcesClone ) {
-                    System.out.println( "building : " + resource );
+                    this.listener.debug( "KnowledgeAgent building resource=" + resource );
                     if ( ((InternalResource) resource).getResourceType() != ResourceType.PKG ) {
                         // .pks are handled as a special case.
                         kbuilder.add( resource,
                                       ((InternalResource) resource).getResourceType() );
                     }
                 }
-                
-                System.err.println( kbuilder.getErrors() );
 
+                if ( kbuilder.hasErrors() ) {
+                    this.listener.warning( "KnowledgeAgent has KnowledgeBuilder errors ",
+                                           kbuilder.getErrors() );
+                }
+
                 this.kbase = KnowledgeBaseFactory.newKnowledgeBase();
                 this.kbase.addKnowledgePackages( kbuilder.getKnowledgePackages() );
+                this.listener.info( "KnowledgeAgent new KnowledgeBase now built and in use" );
             }
         }
 
@@ -413,30 +414,86 @@
     }
 
     public void monitorResourceChangeEvents(boolean monitor) {
-        if ( !this.monitor && monitor ) {
+        if ( this.changeSetNotificationDetector == null ) {
+            if ( monitor ) {
+                // we are going to start the monitor, so initialise it
+                this.changeSetNotificationDetector = new ChangeSetNotificationDetector( this,
+                                                                                        this.queue,
+                                                                                        this.listener );
+            } else if ( this.changeSetNotificationDetector == null ) {
+                // do nothing, we aren't starting the monitor and the monitorResourceChangeEvents field is null
+                return;
+            }
+        }
+
+        if ( !this.changeSetNotificationDetector.monitor && monitor ) {
             // If the thread is not running and we are trying to start it, we must create a new Thread
-            this.monitor = monitor;
-            this.thread = new Thread( this );
+            this.thread = new Thread( this.changeSetNotificationDetector );
+            this.changeSetNotificationDetector.monitor = true;
             this.thread.start();
+        } else {
+            // this will stop the thread
+            this.changeSetNotificationDetector.monitor = false;
         }
-        this.monitor = monitor;
     }
 
-    public void run() {
-        while ( this.monitor ) {
-            try {
-                applyChangeSet( this.queue.take() );
-            } catch ( InterruptedException e ) {
-                // @TODO print proper error message
-                e.printStackTrace();
+    public static class ChangeSetNotificationDetector
+        implements
+        Runnable {
+        private LinkedBlockingQueue<ChangeSet> queue;
+        public volatile boolean                monitor;
+        private KnowledgeAgentImpl             kagent;
+        private SystemEventListener            listener;
+
+        public ChangeSetNotificationDetector(KnowledgeAgentImpl kagent,
+                                             LinkedBlockingQueue<ChangeSet> queue,
+                                             SystemEventListener listener) {
+            this.queue = queue;
+            this.kagent = kagent;
+            this.listener = listener;
+        }
+
+        public void run() {
+            if ( this.monitor ) {
+                this.listener.info( "KnowledegAgent has started listening for ChangeSet notifications" );
             }
-            Thread.yield();
+            while ( this.monitor ) {
+                try {
+                    kagent.applyChangeSet( this.queue.take() );
+                } catch ( InterruptedException e ) {
+                    this.listener.exception( new RuntimeException( "KnowledgeAgent ChangeSet notification thread has been interrupted",
+                                                                   e ) );
+                }
+                Thread.yield();
+            }
+
+            this.listener.info( "KnowledegAgent has stopped listening for ChangeSet notifications" );
         }
     }
 
+    public static class ResourceMapping {
+        private Resource                 resource;
+        private Set<KnowledgeDefinition> knowledgeDefinitions;
+
+        public ResourceMapping(Resource resource) {
+            this.knowledgeDefinitions = new HashSet<KnowledgeDefinition>();
+        }
+
+        public Resource getResource() {
+            return resource;
+        }
+
+        public Set<KnowledgeDefinition> getKnowledgeDefinitions() {
+            return knowledgeDefinitions;
+        }
+
+    }
+
     @Override
     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
-        this.monitor = false;
+        if ( this.changeSetNotificationDetector != null ) {
+            this.changeSetNotificationDetector.monitor = false;
+        }
     }
 }

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/agent/impl/KnowledgeAgentProviderImpl.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/agent/impl/KnowledgeAgentProviderImpl.java	2008-12-09 17:06:47 UTC (rev 24320)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/agent/impl/KnowledgeAgentProviderImpl.java	2008-12-09 17:18:37 UTC (rev 24321)
@@ -3,10 +3,10 @@
 import java.util.Properties;
 
 import org.drools.KnowledgeBase;
+import org.drools.SystemEventListener;
 import org.drools.agent.KnowledgeAgent;
 import org.drools.agent.KnowledgeAgentConfiguration;
 import org.drools.agent.KnowledgeAgentProvider;
-import org.drools.agent.KnowledgeAgentEventListener;
 
 public class KnowledgeAgentProviderImpl implements KnowledgeAgentProvider {
     
@@ -20,20 +20,13 @@
 
     public KnowledgeAgent newKnowledgeAgent(String name,
                                             KnowledgeBase kbase) {
-        return new KnowledgeAgentImpl(name, kbase, null, null);
+        return new KnowledgeAgentImpl(name, kbase, null);
     }
 
     public KnowledgeAgent newKnowledgeAgent(String name,
                                             KnowledgeBase kbase,
                                             KnowledgeAgentConfiguration configuration) {
-        return new KnowledgeAgentImpl(name, kbase, configuration, null);
+        return new KnowledgeAgentImpl(name, kbase, configuration);
     }
 
-    public KnowledgeAgent newKnowledgeAgent(String name,
-                                            KnowledgeBase kbase,
-                                            KnowledgeAgentConfiguration configuration,
-                                            KnowledgeAgentEventListener listener) {
-        return new KnowledgeAgentImpl(name, kbase, configuration, listener);
-    }
-
 }

Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/agent/impl/PrintStreamSystemEventListener.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/agent/impl/PrintStreamSystemEventListener.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/agent/impl/PrintStreamSystemEventListener.java	2008-12-09 17:18:37 UTC (rev 24321)
@@ -0,0 +1,61 @@
+package org.drools.agent.impl;
+
+import java.io.PrintStream;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import org.drools.SystemEventListener;
+
+public class PrintStreamSystemEventListener
+    implements
+    SystemEventListener {
+    
+    private static SimpleDateFormat dateFormat = new SimpleDateFormat( "yyyy:MM:DD HH:MM:SS");
+    
+    private PrintStream print = System.out;
+    
+    public PrintStreamSystemEventListener() {
+        
+    }
+    
+    public PrintStreamSystemEventListener(PrintStream print) {
+        this.print = print;
+    }
+    
+    private String time() {
+        return dateFormat.format( new Date() );
+    }
+
+    public void debug(String message) {
+        print.println( "[" +  time() + ":debug] " + message );
+    }
+    
+    public void debug(String message,
+                      Object object) {
+        print.println( "[" +  time() + ":debug] " + message + " object=" + object );
+    }    
+
+    public void exception(Exception e) {
+        print.println( "[" +  time() + ":exception " );
+        e.printStackTrace( print );
+    }
+
+    public void info(String message) {
+        print.println( "[" +  time() + ":info] " + message );
+    }
+    
+    public void info(String message,
+                     Object object) {
+        print.println( "[" +  time() + ":info] " + message + " object=" + object);        
+    }    
+
+    public void warning(String message) {
+        print.println( "[" +  time() + ":warning] " + message );
+    }
+
+    public void warning(String message,
+                        Object object) {
+        print.println( "[" +  time() + ":debug] " + message + " object=" + object );
+    }
+
+}

Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/impl/SystemEventListenerProviderImpl.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/impl/SystemEventListenerProviderImpl.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/impl/SystemEventListenerProviderImpl.java	2008-12-09 17:18:37 UTC (rev 24321)
@@ -0,0 +1,20 @@
+package org.drools.impl;
+
+import org.drools.SystemEventListener;
+import org.drools.SystemEventListenerProvider;
+import org.drools.agent.impl.PrintStreamSystemEventListener;
+import org.drools.util.DelegatingSystemEventListener;
+
+public class SystemEventListenerProviderImpl implements SystemEventListenerProvider{
+    
+    private DelegatingSystemEventListener    listener = new DelegatingSystemEventListener( new PrintStreamSystemEventListener() );
+    
+    public SystemEventListener getSystemEventListener() {
+        return this.listener;
+    }
+
+    public void setSystemEventListener(SystemEventListener listener) {
+        this.listener.setSystemEventListener( listener );
+    }
+
+}

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/io/impl/ResourceChangeNotifierImpl.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/io/impl/ResourceChangeNotifierImpl.java	2008-12-09 17:06:47 UTC (rev 24320)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/io/impl/ResourceChangeNotifierImpl.java	2008-12-09 17:18:37 UTC (rev 24321)
@@ -13,6 +13,8 @@
 import java.util.concurrent.LinkedBlockingQueue;
 
 import org.drools.ChangeSet;
+import org.drools.SystemEventListener;
+import org.drools.SystemEventListenerFactory;
 import org.drools.event.io.ResourceChangeListener;
 import org.drools.io.Resource;
 import org.drools.io.ResourceChangeMonitor;
@@ -23,23 +25,31 @@
     ResourceChangeNotifier {
     private Map<Resource, Set<ResourceChangeListener>> subscriptions;
     private List<ResourceChangeMonitor>                monitors;
+    private SystemEventListener                        listener;
 
-    
-    private LinkedBlockingQueue<ChangeSet> queue;
+    private LinkedBlockingQueue<ChangeSet>             queue;
 
     public ResourceChangeNotifierImpl() {
+        this.listener = SystemEventListenerFactory.getSystemEventListener();
         this.subscriptions = new HashMap<Resource, Set<ResourceChangeListener>>();
         this.monitors = new CopyOnWriteArrayList<ResourceChangeMonitor>();
         this.queue = new LinkedBlockingQueue<ChangeSet>();
+        this.listener.info( "ResourceChangeNotification created" );
     }
+    
+    public void setSystemEventListener(SystemEventListener listener) {
+        this.listener = listener;
+    }
 
     public void addResourceChangeMonitor(ResourceChangeMonitor monitor) {
         if ( !this.monitors.contains( monitor ) ) {
+            this.listener.debug( "ResourceChangeNotification monitor added monitor=" + monitor );
             this.monitors.add( monitor );
         }
     }
 
     public void removeResourceChangeMonitor(ResourceChangeMonitor monitor) {
+        this.listener.debug( "ResourceChangeNotification monitor removed monitor=" + monitor );
         this.monitors.remove( monitor );
     }
 
@@ -49,8 +59,8 @@
 
     public void subscribeResourceChangeListener(ResourceChangeListener listener,
                                                 Resource resource) {
-        System.out.println( "notifier : " + resource );
-        synchronized ( this.subscriptions ) {            
+        this.listener.debug( "ResourceChangeNotification subscribing listener=" + listener + " to resource=" + resource );
+        synchronized ( this.subscriptions ) {
             Set<ResourceChangeListener> listeners = this.subscriptions.get( resource );
             if ( listeners == null ) {
                 listeners = new HashSet<ResourceChangeListener>();
@@ -67,14 +77,15 @@
 
     public void unsubscribeResourceChangeListener(ResourceChangeListener listener,
                                                   Resource resource) {
+        this.listener.debug( "ResourceChangeNotification unsubscribing listener=" + listener + " to resource=" + resource );
         synchronized ( this.subscriptions ) {
             Set<ResourceChangeListener> listeners = this.subscriptions.get( resource );
             if ( listeners == null ) {
                 return;
             }
-            
+
             listeners.remove( listeners );
-    
+
             if ( listeners.isEmpty() ) {
                 this.subscriptions.remove( resource );
                 for ( ResourceChangeMonitor monitor : this.monitors ) {
@@ -87,30 +98,32 @@
 
     public void subscribeChildResource(Resource directory,
                                        Resource child) {
+        this.listener.debug( "ResourceChangeNotification subscribing directory=" + directory + " content resource=" + child );
         for ( ResourceChangeListener listener : this.subscriptions.get( directory ) ) {
             subscribeResourceChangeListener( listener,
                                              child );
         }
     }
 
-    public void publishKnowledgeBaseChangeSet(ChangeSet changeSet) {
+    public void publishChangeSet(ChangeSet changeSet) {
         try {
+            this.listener.debug( "ResourceChangeNotification received ChangeSet notification" );
             this.queue.put( changeSet );
         } catch ( InterruptedException e ) {
-            // @TODO print proper error message
-            e.printStackTrace();
+            this.listener.exception( new RuntimeException( "ResourceChangeNotification Exception while adding to notification queue",
+                                                           e ) );
         }
-        
+
     }
-    
+
     public void processChangeSet(ChangeSet changeSet) {
         // this provides the complete published change set for this notifier.
         // however different listeners might be listening to different resources, so provide
         // listener change specified change sets.
 
-
         Map<ResourceChangeListener, ChangeSetImpl> localChangeSets = new HashMap<ResourceChangeListener, ChangeSetImpl>();
 
+        this.listener.debug( "ResourceChangeNotification processing ChangeSet" );
         for ( Resource resource : changeSet.getResourcesAdded() ) {
             Set<ResourceChangeListener> listeners = this.subscriptions.get( resource );
             for ( ResourceChangeListener listener : listeners ) {
@@ -126,6 +139,7 @@
                     localChangeSet.setResourcesAdded( new ArrayList<Resource>() );
                 }
                 localChangeSet.getResourcesAdded().add( resource );
+                this.listener.debug( "ResourceChangeNotification ChangeSet added resource=" + resource + " for listener=" + listener );
 
             }
         }
@@ -144,6 +158,7 @@
                     localChangeSet.setResourcesRemoved( new ArrayList<Resource>() );
                 }
                 localChangeSet.getResourcesRemoved().add( resource );
+                this.listener.debug( "ResourceChangeNotification ChangeSet removed resource=" + resource + " for listener=" + listener );
             }
         }
 
@@ -161,6 +176,7 @@
                     localChangeSet.setResourcesModified( new ArrayList<Resource>() );
                 }
                 localChangeSet.getResourcesModified().add( resource );
+                this.listener.debug( "ResourceChangeNotification ChangeSet modified resource=" + resource + " for listener=" + listener );
             }
         }
 
@@ -180,13 +196,15 @@
         //            }
         //        }        
     }
-    
+
     public void start() {
         if ( this.processChangeSet == null ) {
-            this.processChangeSet = new ProcessChangeSet( this.queue, this );
+            this.processChangeSet = new ProcessChangeSet( this.queue,
+                                                          this,
+                                                          this.listener );
         }
-        
-        if ( ! this.processChangeSet.isRunning() ) {
+
+        if ( !this.processChangeSet.isRunning() ) {
             this.processChangeSet.setNotify( true );
             thread = new Thread( this.processChangeSet );
             thread.start();
@@ -194,42 +212,51 @@
     }
 
     public void stop() {
-//        this.processChangeSet.stop();
-//        this.queue.
-    }    
-    
-    private Thread thread;
+
+    }
+
+    private Thread           thread;
     private ProcessChangeSet processChangeSet;
-    
-    public static class ProcessChangeSet implements Runnable {
-        private volatile boolean notify;
+
+    public static class ProcessChangeSet
+        implements
+        Runnable {
+        private volatile boolean               notify;
         private LinkedBlockingQueue<ChangeSet> queue;
-        private ResourceChangeNotifierImpl notifier;
-        
-        ProcessChangeSet(LinkedBlockingQueue<ChangeSet> queue, ResourceChangeNotifierImpl notifier) {
+        private ResourceChangeNotifierImpl     notifier;
+        private SystemEventListener            listener;
+
+        ProcessChangeSet(LinkedBlockingQueue<ChangeSet> queue,
+                         ResourceChangeNotifierImpl notifier,
+                         SystemEventListener listener) {
             this.queue = queue;
-            this.notifier = notifier;            
+            this.notifier = notifier;
+            this.listener = listener;
         }
-        
-        public void setNotify( boolean notify ) {
+
+        public void setNotify(boolean notify) {
             this.notify = notify;
         }
-        
+
         public boolean isRunning() {
             return this.notify;
         }
-        
+
         public void run() {
-            while ( this.notify ) {           
+            if ( this.notify ) {
+                this.listener.info( "ResourceChangeNotification has started listening for ChangeSet publications" );
+            }
+            while ( this.notify ) {
                 try {
-                    System.out.println( "notifier queueing" );
+                    this.listener.debug( "ResourceChangeNotification notifier thread is waiting for queue update" );
                     this.notifier.processChangeSet( this.queue.take() );
                 } catch ( InterruptedException e ) {
-                    // @TODO print proper error message
-                    e.printStackTrace();
+                    this.listener.exception( new RuntimeException( "ResourceChangeNotification ChangeSet publication thread was interrupted",
+                                                                   e ) );
                 }
                 Thread.yield();
             }
+            this.listener.info( "ResourceChangeNotification has stopped listening for ChangeSet publications" );
         }
     }
 

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/io/impl/ResourceChangeScannerImpl.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/io/impl/ResourceChangeScannerImpl.java	2008-12-09 17:06:47 UTC (rev 24320)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/io/impl/ResourceChangeScannerImpl.java	2008-12-09 17:18:37 UTC (rev 24321)
@@ -10,6 +10,8 @@
 import java.util.Map.Entry;
 
 import org.drools.ChangeSet;
+import org.drools.SystemEventListener;
+import org.drools.SystemEventListenerFactory;
 import org.drools.io.InternalResource;
 import org.drools.io.Resource;
 import org.drools.io.ResourceChangeNotifier;
@@ -22,19 +24,26 @@
 
     private Map<Resource, Set<ResourceChangeNotifier>> resources;
     private Set<Resource>                              directories;
+    private SystemEventListener                        listener;
 
     public ResourceChangeScannerImpl() {
+        this.listener = SystemEventListenerFactory.getSystemEventListener();
         this.resources = new HashMap<Resource, Set<ResourceChangeNotifier>>();
         this.directories = new HashSet<Resource>();
         this.scannerScheduler = new ProcessChangeSet( this.resources,
-                                                      this );
+                                                      this,
+                                                      this.listener );
         setInterval( 60 );
+        this.listener.info( "ResourceChangeScanner created with default interval=60" );
     }
+    
+    public void setSystemEventListener(SystemEventListener listener) {
+        this.listener = listener;
+    }    
 
     public void configure(ResourceChangeScannerConfiguration configuration) {
         this.scannerScheduler.setInterval( ((ResourceChangeScannerConfigurationImpl) configuration).getInterval() );
-        System.out.println( getInterval() );
-        
+        this.listener.info( "ResourceChangeScanner reconfigured with interval=" + getInterval() );
         synchronized ( this.resources ) {
             this.resources.notify(); // notify wait, so that it will wait again
         }
@@ -50,7 +59,6 @@
 
     public void subscribeNotifier(ResourceChangeNotifier notifier,
                                   Resource resource) {
-        System.out.println( "scanner : " + resource );
         synchronized ( this.resources ) {
             if ( ((InternalResource) resource).isDirectory() ) {
                 this.directories.add( resource );
@@ -61,6 +69,7 @@
                 this.resources.put( resource,
                                     notifiers );
             }
+            this.listener.debug( "ResourceChangeScanner subcribing notifier=" + notifier + " to resource=" + resource );
             notifiers.add( notifier );
         }
     }
@@ -72,8 +81,10 @@
             if ( notifiers == null ) {
                 return;
             }
+            this.listener.debug( "ResourceChangeScanner unsubcribing notifier=" + notifier + " to resource=" + resource );
             notifiers.remove( notifier );
             if ( notifiers.isEmpty() ) {
+                this.listener.debug( "ResourceChangeScanner resource=" + resource + " now has no subscribers" );
                 this.resources.remove( resource );
                 this.directories.remove( resource ); // don't bother with isDirectory check, as doing a remove is harmless if it doesn't exist
             }
@@ -81,7 +92,7 @@
     }
 
     public void scan() {
-        System.out.println( "attempt scan : " + this.resources.size() );
+        this.listener.debug( "ResourceChangeScanner attempt to scan " + this.resources.size() + " resources" );
 
         synchronized ( this.resources ) {
             Map<ResourceChangeNotifier, ChangeSet> notifications = new HashMap<ResourceChangeNotifier, ChangeSet>();
@@ -90,12 +101,14 @@
 
             // detect modified and added
             for ( Resource resource : this.directories ) {
+                this.listener.debug( "ResourceChangeScanner scanning directory=" + resource );
                 for ( Resource child : ((InternalResource) resource).listResources() ) {
                     if ( ((InternalResource) child).isDirectory() ) {
                         continue; // ignore sub directories
                     }
                     if ( !this.resources.containsKey( child ) ) {
-                        System.out.println( "found new file : " + child );
+
+                        this.listener.debug( "ResourceChangeScanner new resource=" + child );
                         // child is new
                         ((InternalResource) child).setResourceType( ((InternalResource) resource).getResourceType() );
                         Set<ResourceChangeNotifier> notifiers = this.resources.get( resource ); // get notifiers for this directory
@@ -123,10 +136,10 @@
                 Set<ResourceChangeNotifier> notifiers = entry.getValue();
 
                 if ( !((InternalResource) resource).isDirectory() ) {
-                    // detect if Resource has been modified
-                    System.out.println( "scan " + resource + ": " + ((InternalResource) resource).getLastModified() + " : " + ((InternalResource) resource).getLastRead() );
+                    // detect if Resource has been removed
                     long lastModified = ((InternalResource) resource).getLastModified();
                     if ( lastModified == 0 ) {
+                        this.listener.debug( "ResourceChangeScanner removed resource=" + resource );
                         removed.add( resource );
                         // resource is no longer present
                         // iterate notifiers for this resource and add to each removed
@@ -144,6 +157,7 @@
                             changeSet.getResourcesRemoved().add( resource );
                         }
                     } else if ( ((InternalResource) resource).getLastRead() < lastModified ) {
+                        this.listener.debug( "ResourceChangeScanner modified resource=" + resource );
                         // it's modified
                         // iterate notifiers for this resource and add to each modified
                         for ( ResourceChangeNotifier notifier : notifiers ) {
@@ -171,13 +185,12 @@
             for ( Entry<ResourceChangeNotifier, ChangeSet> entry : notifications.entrySet() ) {
                 ResourceChangeNotifier notifier = entry.getKey();
                 ChangeSet changeSet = entry.getValue();
-                notifier.publishKnowledgeBaseChangeSet( changeSet );
+                notifier.publishChangeSet( changeSet );
             }
         }
     }
 
     public void setInterval(int interval) {
-
         this.scannerScheduler.setInterval( interval * 1000 );
     }
 
@@ -199,7 +212,7 @@
             this.resources.notify(); // notify wait, so that it will wait again
         }
     }
-    
+
     public void reset() {
         this.resources.clear();
         this.directories.clear();
@@ -215,11 +228,14 @@
         private ResourceChangeScannerImpl                  scanner;
         private long                                       interval;
         private Map<Resource, Set<ResourceChangeNotifier>> resources;
+        private SystemEventListener                        listener;
 
         ProcessChangeSet(Map<Resource, Set<ResourceChangeNotifier>> resources,
-                         ResourceChangeScannerImpl scanner) {
+                         ResourceChangeScannerImpl scanner,
+                         SystemEventListener listener) {
             this.resources = resources;
             this.scanner = scanner;
+            this.listener = listener;
         }
 
         public void setInterval(long interval) {
@@ -240,16 +256,20 @@
 
         public void run() {
             synchronized ( this.resources ) {
+                if ( this.scan ) {
+                    this.listener.info( "ResourceChangeNotification scanner has started" );
+                }
                 while ( this.scan ) {
                     this.scanner.scan();
                     try {
-                        System.out.println( "scanner waiting" );
+                        this.listener.debug( "ResourceChangeNotification scanner thread is waiting for " + ( this.interval / 1000 ) );
                         this.resources.wait( this.interval );
                     } catch ( InterruptedException e ) {
-                        System.out.println( "wait interrupted, new interval is " + this.interval + "s" );
-                        // swallow, this will happen when we are waiting and the interval changes
+                        this.listener.exception( new RuntimeException( "ResourceChangeNotification ChangeSet scanning thread was interrupted",
+                                                                       e ) );
                     }
                 }
+                this.listener.info( "ResourceChangeNotification scanner has stopped" );
             }
         }
     }

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/io/impl/ResourceProviderImpl.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/io/impl/ResourceProviderImpl.java	2008-12-09 17:06:47 UTC (rev 24320)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/io/impl/ResourceProviderImpl.java	2008-12-09 17:18:37 UTC (rev 24321)
@@ -5,10 +5,13 @@
 import java.io.Reader;
 import java.net.URL;
 
+import org.drools.SystemEventListener;
+import org.drools.agent.impl.PrintStreamSystemEventListener;
 import org.drools.io.Resource;
 import org.drools.io.ResourceChangeNotifier;
 import org.drools.io.ResourceChangeScanner;
 import org.drools.io.ResourceProvider;
+import org.drools.util.DelegatingSystemEventListener;
 
 public class ResourceProviderImpl
     implements
@@ -16,12 +19,12 @@
 
     private ResourceChangeNotifier notifier;
     private ResourceChangeScanner  scanner;
-    private Object                 lock = new Object();
+    private Object                 lock     = new Object();    
 
     public ResourceChangeNotifier getResourceChangeNotifierService() {
         synchronized ( this.lock ) {
             if ( this.notifier == null ) {
-                this.notifier = new ResourceChangeNotifierImpl();               
+                this.notifier = new ResourceChangeNotifierImpl( );
             }
             return this.notifier;
         }
@@ -30,7 +33,7 @@
     public ResourceChangeScanner getResourceChangeScannerService() {
         synchronized ( this.lock ) {
             if ( scanner == null ) {
-                this.scanner = new ResourceChangeScannerImpl();
+                this.scanner = new ResourceChangeScannerImpl( );
             }
             return this.scanner;
         }

Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/util/DelegatingSystemEventListener.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/util/DelegatingSystemEventListener.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/util/DelegatingSystemEventListener.java	2008-12-09 17:18:37 UTC (rev 24321)
@@ -0,0 +1,50 @@
+package org.drools.util;
+
+import org.drools.SystemEventListener;
+
+public class DelegatingSystemEventListener
+    implements
+    SystemEventListener {
+    
+    private SystemEventListener listener;
+    
+    public DelegatingSystemEventListener(SystemEventListener listener) {
+        this.listener = listener;
+    }
+    
+    public void setSystemEventListener( SystemEventListener listener ) {
+        this.listener = listener;
+    }
+
+    public void debug(String message) {
+        this.listener.debug( message );
+    }
+
+    public void debug(String message,
+                      Object object) {
+        this.listener.debug( message, object );
+    }
+
+    public void exception(Exception e) {
+        this.listener.exception( e );
+    }
+
+    public void info(String message) {
+        this.listener.info( message );
+    }
+
+    public void info(String message,
+                     Object object) {
+        this.listener.info( message, object );
+    }
+
+    public void warning(String message) {
+        this.listener.warning( message );
+    }
+
+    public void warning(String message,
+                        Object object) {
+        this.listener.warning( message, object );
+    }
+
+}

Modified: labs/jbossrules/trunk/drools-core/src/test/java/org/drools/agent/MockListener.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/test/java/org/drools/agent/MockListener.java	2008-12-09 17:06:47 UTC (rev 24320)
+++ labs/jbossrules/trunk/drools-core/src/test/java/org/drools/agent/MockListener.java	2008-12-09 17:18:37 UTC (rev 24321)
@@ -34,4 +34,22 @@
 
     }
 
+    public void debug(String message,
+                      Object object) {
+        // TODO Auto-generated method stub
+        
+    }
+
+    public void info(String message,
+                     Object object) {
+        // TODO Auto-generated method stub
+        
+    }
+
+    public void warning(String message,
+                        Object object) {
+        // TODO Auto-generated method stub
+        
+    }
+
 }

Modified: labs/jbossrules/trunk/drools-core/src/test/java/org/drools/agent/RuleAgentTest.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/test/java/org/drools/agent/RuleAgentTest.java	2008-12-09 17:06:47 UTC (rev 24320)
+++ labs/jbossrules/trunk/drools-core/src/test/java/org/drools/agent/RuleAgentTest.java	2008-12-09 17:18:37 UTC (rev 24321)
@@ -566,6 +566,24 @@
             public void setAgentName(String n) {
                 name[0] = n;
             }
+
+            public void debug(String message,
+                              Object object) {
+                // TODO Auto-generated method stub
+                
+            }
+
+            public void info(String message,
+                             Object object) {
+                // TODO Auto-generated method stub
+                
+            }
+
+            public void warning(String message,
+                                Object object) {
+                // TODO Auto-generated method stub
+                
+            }
         };
 
         File dir = RuleBaseAssemblerTest.getTempDirectory();
@@ -757,6 +775,24 @@
 
         }
 
+        public void debug(String message,
+                          Object object) {
+            // TODO Auto-generated method stub
+            
+        }
+
+        public void info(String message,
+                         Object object) {
+            // TODO Auto-generated method stub
+            
+        }
+
+        public void warning(String message,
+                            Object object) {
+            // TODO Auto-generated method stub
+            
+        }
+
     }
 
 }




More information about the jboss-svn-commits mailing list