[jboss-svn-commits] JBL Code SVN: r30563 - in labs/jbossrules/trunk: drools-core/src/main/java/org/drools/agent/impl and 1 other directories.
jboss-svn-commits at lists.jboss.org
jboss-svn-commits at lists.jboss.org
Wed Dec 9 08:29:17 EST 2009
Author: eaa
Date: 2009-12-09 08:29:15 -0500 (Wed, 09 Dec 2009)
New Revision: 30563
Added:
labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/agent/KnowledgeAgentIncrementalChangeSetTest.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/io/impl/ResourceChangeScannerImpl.java
Log:
JBRULES-2152: KnowledgeAgentConfiguration - allow for property "drools.agent.newInstance" to be set to false
-KnowledgeAgentImpl: Added support for drools.agent.newInstance=false. This will apply the change sets in an incremental way.
-Moved Incremental change sets unit tests to a new class KnowledgeAgentIncrementalChangeSetTest.
-Created new unit test for incremental change sets.
Added: labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/agent/KnowledgeAgentIncrementalChangeSetTest.java
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/agent/KnowledgeAgentIncrementalChangeSetTest.java (rev 0)
+++ labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/agent/KnowledgeAgentIncrementalChangeSetTest.java 2009-12-09 13:29:15 UTC (rev 30563)
@@ -0,0 +1,889 @@
+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.List;
+
+import junit.framework.TestCase;
+
+import org.drools.KnowledgeBase;
+import org.drools.KnowledgeBaseFactory;
+import org.drools.builder.KnowledgeBuilder;
+import org.drools.builder.KnowledgeBuilderFactory;
+import org.drools.builder.ResourceType;
+import org.drools.definition.KnowledgePackage;
+import org.drools.io.ResourceChangeScannerConfiguration;
+import org.drools.io.ResourceFactory;
+import org.drools.io.impl.ResourceChangeNotifierImpl;
+import org.drools.io.impl.ResourceChangeScannerImpl;
+import org.drools.runtime.StatefulKnowledgeSession;
+import org.drools.runtime.pipeline.ResultHandler;
+import org.drools.util.DroolsStreamUtils;
+import org.drools.util.FileManager;
+import org.mortbay.jetty.Server;
+import org.mortbay.jetty.handler.ResourceHandler;
+
+public class KnowledgeAgentIncrementalChangeSetTest extends TestCase {
+
+ FileManager fileManager;
+ private Server server;
+
+ @Override
+ protected void setUp() throws Exception {
+ fileManager = new FileManager();
+ fileManager.setUp();
+ ((ResourceChangeScannerImpl) ResourceFactory.getResourceChangeScannerService()).reset();
+ ResourceFactory.getResourceChangeNotifierService().start();
+ ResourceFactory.getResourceChangeScannerService().start();
+
+ this.server = new Server(9000);
+ ResourceHandler resourceHandler = new ResourceHandler();
+ resourceHandler.setResourceBase(fileManager.getRootDirectory().getPath());
+ System.out.println("root : " + fileManager.getRootDirectory().getPath());
+
+ server.setHandler(resourceHandler);
+
+ server.start();
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ fileManager.tearDown();
+ ResourceFactory.getResourceChangeNotifierService().stop();
+ ResourceFactory.getResourceChangeScannerService().stop();
+ ((ResourceChangeNotifierImpl) ResourceFactory.getResourceChangeNotifierService()).reset();
+ ((ResourceChangeScannerImpl) ResourceFactory.getResourceChangeScannerService()).reset();
+
+ server.stop();
+ }
+
+
+ public void testModifyFileUrlIncremental() throws Exception {
+ String rule1 = "";
+ rule1 += "package org.drools.test\n";
+ rule1 += "global java.util.List list\n";
+ rule1 += "rule rule1\n";
+ rule1 += "when\n";
+ rule1 += "then\n";
+ rule1 += "list.add( drools.getRule().getName() );\n";
+ rule1 += "end\n";
+ File f1 = fileManager.newFile("rule1.drl");
+ Writer output = new BufferedWriter(new FileWriter(f1));
+ output.write(rule1);
+ output.close();
+
+ String rule2 = "";
+ rule2 += "package org.drools.test\n";
+ rule2 += "global java.util.List list\n";
+ rule2 += "rule rule2\n";
+ rule2 += "when\n";
+ rule2 += "then\n";
+ rule2 += "list.add( drools.getRule().getName() );\n";
+ rule2 += "end\n";
+ 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 drools-change-set-5.0.xsd' >";
+ xml += " <add> ";
+ xml += " <resource source='http://localhost:9000/rule1.drl' type='DRL' />";
+ xml += " <resource source='http://localhost:9000/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();
+
+ KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
+
+ 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", "false");
+ KnowledgeAgent kagent = KnowledgeAgentFactory.newKnowledgeAgent(
+ "test agent", kbase, aconf);
+
+ assertEquals("test agent", kagent.getName());
+
+ kagent.applyChangeSet(ResourceFactory.newUrlResource(fxml.toURI().toURL()));
+
+ StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession();
+ List<String> list = new ArrayList<String>();
+ ksession.setGlobal("list", list);
+ ksession.fireAllRules();
+ ksession.dispose();
+
+ 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
+ Thread.sleep(2000);
+
+ rule1 = "";
+ rule1 += "package org.drools.test\n";
+ rule1 += "global java.util.List list\n";
+ rule1 += "rule rule3\n";
+ rule1 += "when\n";
+ rule1 += "then\n";
+ rule1 += "list.add( drools.getRule().getName() );\n";
+ rule1 += "end\n";
+ output = new BufferedWriter(new FileWriter(f1));
+ output.write(rule1);
+ output.close();
+ Thread.sleep(3000);
+
+ // Use the same session for incremental build test
+ ksession = kbase.newStatefulKnowledgeSession();
+ list = new ArrayList<String>();
+ ksession.setGlobal("list", list);
+ ksession.fireAllRules();
+ ksession.dispose();
+
+ assertEquals(2, list.size());
+
+ assertTrue(list.contains("rule3"));
+ assertTrue(list.contains("rule2"));
+ kagent.monitorResourceChangeEvents(false);
+ }
+
+ public void testRemoveFileUrlIncremental() throws Exception {
+ String rule1 = "";
+ rule1 += "package org.drools.test\n";
+ rule1 += "global java.util.List list\n";
+ rule1 += "rule rule1\n";
+ rule1 += "when\n";
+ rule1 += "then\n";
+ rule1 += "list.add( drools.getRule().getName() );\n";
+ rule1 += "end\n";
+ File f1 = fileManager.newFile("rule1.drl");
+ Writer output = new BufferedWriter(new FileWriter(f1));
+ output.write(rule1);
+ output.close();
+
+ String rule2 = "";
+ rule2 += "package org.drools.test\n";
+ rule2 += "global java.util.List list\n";
+ rule2 += "rule rule2\n";
+ rule2 += "when\n";
+ rule2 += "then\n";
+ rule2 += "list.add( drools.getRule().getName() );\n";
+ rule2 += "end\n";
+ 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 drools-change-set-5.0.xsd' >";
+ xml += " <add> ";
+ xml += " <resource source='http://localhost:9000/rule1.drl' type='DRL' />";
+ xml += " <resource source='http://localhost:9000/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();
+
+ KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
+
+ 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", "false");
+ KnowledgeAgent kagent = KnowledgeAgentFactory.newKnowledgeAgent(
+ "test agent", kbase, aconf);
+
+ assertEquals("test agent", kagent.getName());
+
+ kagent.applyChangeSet(ResourceFactory.newUrlResource(fxml.toURI().toURL()));
+
+ StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession();
+ List<String> list = new ArrayList<String>();
+ ksession.setGlobal("list", list);
+ ksession.fireAllRules();
+ ksession.dispose();
+
+ assertEquals(2, list.size());
+ assertTrue(list.contains("rule1"));
+ assertTrue(list.contains("rule2"));
+
+ list.clear();
+
+ // Delete the file so only rule 2 fires
+ f1.delete();
+ Thread.sleep(3000);
+
+ // Use the same session for incremental build test
+ ksession = kbase.newStatefulKnowledgeSession();
+ ksession.setGlobal("list", list);
+ ksession.fireAllRules();
+ ksession.dispose();
+
+ assertEquals(1, list.size());
+ assertTrue(list.contains("rule2"));
+
+ //Delete f2 now, no rules should fire
+ list.clear();
+ f2.delete();
+ Thread.sleep(3000);
+
+ ksession = kbase.newStatefulKnowledgeSession();
+ ksession.setGlobal("list", list);
+ ksession.fireAllRules();
+ ksession.dispose();
+
+ assertEquals(0, list.size());
+
+ kagent.monitorResourceChangeEvents(false);
+ }
+
+
+
+ /**
+ * Tests that if we have two DRL files, where one file overwrites a rule in
+ * a prior file, that if we modify the first file that was overwritten, that
+ * it will gain precedence and overwrite the other.
+ *
+ * @throws Exception
+ */
+ public void testModifyFileUrlOverwriteIncremental() throws Exception {
+ String rule1 = "";
+ rule1 += "package org.drools.test\n";
+ rule1 += "global java.util.List list\n";
+ rule1 += "rule rule1\n";
+ rule1 += "when\n";
+ rule1 += "then\n";
+ rule1 += "list.add( drools.getRule().getName() );\n";
+ rule1 += "end\n";
+ File f1 = fileManager.newFile("rule1.drl");
+ Writer output = new BufferedWriter(new FileWriter(f1));
+ output.write(rule1);
+ output.close();
+
+ String rule2 = "";
+ rule2 += "package org.drools.test\n";
+ rule2 += "global java.util.List list\n";
+ rule2 += "rule rule1\n";
+ rule2 += "when\n";
+ rule2 += "then\n";
+ rule2 += "list.add( drools.getRule().getName() + \"_v2\");\n";
+ rule2 += "end\n";
+ 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 drools-change-set-5.0.xsd' >";
+ xml += " <add> ";
+ xml += " <resource source='http://localhost:9000/rule1.drl' type='DRL' />";
+ xml += " <resource source='http://localhost:9000/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();
+
+ KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
+
+ 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", "false");
+ KnowledgeAgent kagent = KnowledgeAgentFactory.newKnowledgeAgent(
+ "test agent", kbase, aconf);
+
+ assertEquals("test agent", kagent.getName());
+
+ kagent.applyChangeSet(ResourceFactory.newUrlResource(fxml.toURI().toURL()));
+
+ StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession();
+ List<String> list = new ArrayList<String>();
+ ksession.setGlobal("list", list);
+ ksession.fireAllRules();
+ ksession.dispose();
+
+ assertEquals(1, list.size());
+ assertTrue(list.contains("rule1_v2"));
+
+ 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
+ Thread.sleep(2000);
+
+ rule1 = "";
+ rule1 += "package org.drools.test\n";
+ rule1 += "global java.util.List list\n";
+ rule1 += "rule rule1\n";
+ rule1 += "when\n";
+ rule1 += "then\n";
+ rule1 += "list.add( drools.getRule().getName() + \"_v3\" );\n";
+ rule1 += "end\n";
+ output = new BufferedWriter(new FileWriter(f1));
+ output.write(rule1);
+ output.close();
+ Thread.sleep(3000);
+
+ // Use the same session for incremental build test
+ ksession = kbase.newStatefulKnowledgeSession();
+ ksession.setGlobal("list", list);
+ ksession.fireAllRules();
+ ksession.dispose();
+
+ assertEquals(1, list.size());
+ assertTrue(list.contains("rule1_v3"));
+
+ //Delete f2 now, rule1 should still fire if the indexing worked properly
+ list.clear();
+ f2.delete();
+ Thread.sleep(3000);
+
+ ksession = kbase.newStatefulKnowledgeSession();
+ ksession.setGlobal("list", list);
+ ksession.fireAllRules();
+ ksession.dispose();
+
+ assertEquals(1, list.size());
+ assertTrue(list.contains("rule1_v3"));
+
+ kagent.monitorResourceChangeEvents(false);
+ }
+
+
+
+ /**
+ * Creates two rules (rule1 and rule2) in a drl file. Then it modifies the
+ * drl file to change rule2 with rule3.
+ * @throws Exception
+ */
+ public void testMultipleRulesOnFileUrlIncremental() throws Exception {
+ String rule1 = "";
+ rule1 += "package org.drools.test\n";
+ rule1 += "global java.util.List list\n";
+ rule1 += "rule rule1\n";
+ rule1 += "when\n";
+ rule1 += "then\n";
+ rule1 += "list.add( drools.getRule().getName() );\n";
+ rule1 += "end\n\n";
+
+
+ String rule2 = "";
+ rule2 += "rule rule2\n";
+ rule2 += "when\n";
+ rule2 += "then\n";
+ rule2 += "list.add( drools.getRule().getName());\n";
+ rule2 += "end\n";
+
+ File f1 = fileManager.newFile("rules.drl");
+ Writer output = new BufferedWriter(new FileWriter(f1));
+ output.write(rule1);
+ 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 drools-change-set-5.0.xsd' >";
+ xml += " <add> ";
+ xml += " <resource source='http://localhost:9000/rules.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();
+
+ KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
+
+ 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", "false");
+ KnowledgeAgent kagent = KnowledgeAgentFactory.newKnowledgeAgent(
+ "test agent", kbase, aconf);
+
+ assertEquals("test agent", kagent.getName());
+
+ kagent.applyChangeSet(ResourceFactory.newUrlResource(fxml.toURI().toURL()));
+
+ StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession();
+ List<String> list = new ArrayList<String>();
+ ksession.setGlobal("list", list);
+ ksession.fireAllRules();
+ ksession.dispose();
+
+ 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
+ Thread.sleep(2000);
+
+ String rule3 = "";
+ rule3 += "rule rule3\n";
+ rule3 += "when\n";
+ rule3 += "then\n";
+ rule3 += "list.add( drools.getRule().getName());\n";
+ rule3 += "end\n";
+ output = new BufferedWriter(new FileWriter(f1));
+ output.write(rule1);
+ output.write(rule3);
+ output.close();
+ Thread.sleep(3000);
+
+ // Use the same session for incremental build test
+ ksession = kbase.newStatefulKnowledgeSession();
+ ksession.setGlobal("list", list);
+ ksession.fireAllRules();
+ ksession.dispose();
+
+ assertEquals(2, list.size());
+ assertTrue(list.contains("rule1"));
+ assertTrue(list.contains("rule3"));
+
+ kagent.monitorResourceChangeEvents(false);
+ }
+
+
+ public void testMultipleRulesOnFilesUrlIncremental() throws Exception {
+ String header = "";
+ header += "package org.drools.test\n";
+ header += "global java.util.List list\n\n";
+
+ String rule1 = "";
+ rule1 += "rule rule1\n";
+ rule1 += "when\n";
+ rule1 += "then\n";
+ rule1 += "list.add( drools.getRule().getName() );\n";
+ rule1 += "end\n\n";
+
+
+ String rule2 = "";
+ rule2 += "rule rule2\n";
+ rule2 += "when\n";
+ rule2 += "then\n";
+ rule2 += "list.add( drools.getRule().getName());\n";
+ rule2 += "end\n";
+
+ String rule3 = "";
+ rule3 += "rule rule3\n";
+ rule3 += "when\n";
+ rule3 += "then\n";
+ rule3 += "list.add( drools.getRule().getName());\n";
+ rule3 += "end\n";
+
+ String rule4 = "";
+ rule4 += "rule rule4\n";
+ rule4 += "when\n";
+ rule4 += "then\n";
+ rule4 += "list.add( drools.getRule().getName());\n";
+ rule4 += "end\n";
+
+ String rule5 = "";
+ rule5 += "rule rule5\n";
+ rule5 += "when\n";
+ rule5 += "then\n";
+ rule5 += "list.add( drools.getRule().getName());\n";
+ rule5 += "end\n";
+
+ File f1 = fileManager.newFile("rules1.drl");
+ Writer output = new BufferedWriter(new FileWriter(f1));
+ output.write(header);
+ output.write(rule1);
+ output.write(rule2);
+ output.close();
+
+ File f2 = fileManager.newFile("rules2.drl");
+ output = new BufferedWriter(new FileWriter(f2));
+ output.write(header);
+ output.write(rule3);
+ output.close();
+
+ String xml = "";
+ xml += "<change-set xmlns='http://drools.org/drools-5.0/change-set'";
+ xml += " xmlns:xs='http://www.w3.org/2001/XMLSchema-instance'";
+ xml += " xs:schemaLocation='http://drools.org/drools-5.0/change-set drools-change-set-5.0.xsd' >";
+ xml += " <add> ";
+ xml += " <resource source='http://localhost:9000/rules1.drl' type='DRL' />";
+ xml += " <resource source='http://localhost:9000/rules2.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();
+
+ KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
+
+ 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", "false");
+ KnowledgeAgent kagent = KnowledgeAgentFactory.newKnowledgeAgent(
+ "test agent", kbase, aconf);
+
+ assertEquals("test agent", kagent.getName());
+
+ kagent.applyChangeSet(ResourceFactory.newUrlResource(fxml.toURI().toURL()));
+
+ StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession();
+ List<String> list = new ArrayList<String>();
+ ksession.setGlobal("list", list);
+ ksession.fireAllRules();
+ ksession.dispose();
+
+ assertEquals(3, list.size());
+ assertTrue(list.contains("rule1"));
+ assertTrue(list.contains("rule2"));
+ assertTrue(list.contains("rule3"));
+
+ 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
+ Thread.sleep(2000);
+
+
+ output = new BufferedWriter(new FileWriter(f2));
+ output.write(header);
+ output.write(rule4);
+ output.close();
+ Thread.sleep(3000);
+
+ // Use the same session for incremental build test
+ ksession = kbase.newStatefulKnowledgeSession();
+ ksession.setGlobal("list", list);
+ ksession.fireAllRules();
+ ksession.dispose();
+
+ assertEquals(3, list.size());
+ assertTrue(list.contains("rule1"));
+ assertTrue(list.contains("rule2"));
+ assertTrue(list.contains("rule4"));
+
+ 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
+ Thread.sleep(2000);
+
+
+ output = new BufferedWriter(new FileWriter(f1));
+ output.write(header);
+ output.write(rule1);
+ output.write(rule5);
+ output.close();
+ Thread.sleep(3000);
+
+
+ // Use the same session for incremental build test
+ ksession = kbase.newStatefulKnowledgeSession();
+ ksession.setGlobal("list", list);
+ ksession.fireAllRules();
+ ksession.dispose();
+
+ assertEquals(3, list.size());
+ assertTrue(list.contains("rule1"));
+ assertTrue(list.contains("rule5"));
+ assertTrue(list.contains("rule4"));
+
+ list.clear();
+
+ kagent.monitorResourceChangeEvents(false);
+ }
+
+
+ public void testModifyPackageUrlIncremental() throws Exception {
+ String rule1 = "";
+ rule1 += "package org.drools.test\n";
+ rule1 += "global java.util.List list\n";
+ rule1 += "rule rule1\n";
+ rule1 += "when\n";
+ rule1 += "then\n";
+ rule1 += "list.add( drools.getRule().getName() );\n";
+ rule1 += "end\n";
+
+ String rule2 = "";
+ rule2 += "package org.drools.test\n";
+ rule2 += "global java.util.List list\n";
+ rule2 += "rule rule2\n";
+ rule2 += "when\n";
+ rule2 += "then\n";
+ rule2 += "list.add( drools.getRule().getName() );\n";
+ rule2 += "end\n";
+
+ // Do only Rule1 in the first package
+ File pkg1 = fileManager.newFile("pkg1.pkg");
+ KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
+ kbuilder.add(ResourceFactory.newByteArrayResource(rule1.getBytes()),
+ ResourceType.DRL);
+ if (kbuilder.hasErrors()) {
+ fail(kbuilder.getErrors().toString());
+ }
+ KnowledgePackage pkg = (KnowledgePackage) kbuilder.getKnowledgePackages().iterator().next();
+ writePackage(pkg, pkg1);
+
+ String xml = "";
+ xml += "<change-set xmlns='http://drools.org/drools-5.0/change-set'";
+ xml += " xmlns:xs='http://www.w3.org/2001/XMLSchema-instance'";
+ xml += " xs:schemaLocation='http://drools.org/drools-5.0/change-set drools-change-set-5.0.xsd' >";
+ xml += " <add> ";
+ xml += " <resource source='http://localhost:9000/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();
+
+ KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
+
+ 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");
+ aconf.setProperty("drools.agent.newInstance", "false");
+ KnowledgeAgent kagent = KnowledgeAgentFactory.newKnowledgeAgent(
+ "test agent", kbase, aconf);
+
+ kagent.applyChangeSet(ResourceFactory.newUrlResource(fxml.toURI().toURL()));
+
+ StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession();
+ List<String> list = new ArrayList<String>();
+ ksession.setGlobal("list", list);
+ ksession.fireAllRules();
+ ksession.dispose();
+
+ assertEquals(1, list.size());
+ assertTrue(list.contains("rule1"));
+
+ 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
+ Thread.sleep(2000);
+
+ rule1 = "";
+ rule1 += "package org.drools.test\n";
+ rule1 += "global java.util.List list\n";
+ rule1 += "rule rule3\n";
+ rule1 += "when\n";
+ rule1 += "then\n";
+ rule1 += "list.add( drools.getRule().getName() );\n";
+ rule1 += "end\n";
+
+ 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());
+ }
+ pkg = (KnowledgePackage) kbuilder.getKnowledgePackages().iterator().next();
+ writePackage(pkg, pkg1);
+
+ Thread.sleep(3000);
+
+ ksession = kbase.newStatefulKnowledgeSession();
+ list = new ArrayList<String>();
+ ksession.setGlobal("list", list);
+ ksession.fireAllRules();
+ ksession.dispose();
+
+ assertEquals(2, list.size());
+
+ assertTrue(list.contains("rule3"));
+ assertTrue(list.contains("rule2"));
+ kagent.monitorResourceChangeEvents(false);
+ }
+
+ public void testUpdatePackageUrlIncremental() throws Exception {
+ String rule1 = "";
+ rule1 += "package org.drools.test\n";
+ rule1 += "global java.util.List list\n";
+ rule1 += "rule rule1\n";
+ rule1 += "when\n";
+ rule1 += "then\n";
+ rule1 += "list.add( drools.getRule().getName() );\n";
+ rule1 += "end\n";
+
+ String rule2 = "";
+ rule2 += "package org.drools.test\n";
+ rule2 += "global java.util.List list\n";
+ rule2 += "rule rule2\n";
+ rule2 += "when\n";
+ rule2 += "then\n";
+ rule2 += "list.add( drools.getRule().getName() );\n";
+ rule2 += "end\n";
+
+ // Add Rule1 and Rule2 in the first package
+ File pkg1 = fileManager.newFile("pkg1.pkg");
+ 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());
+ }
+ KnowledgePackage pkg = (KnowledgePackage) kbuilder.getKnowledgePackages().iterator().next();
+ writePackage(pkg, pkg1);
+
+ String xml = "";
+ xml += "<change-set xmlns='http://drools.org/drools-5.0/change-set'";
+ xml += " xmlns:xs='http://www.w3.org/2001/XMLSchema-instance'";
+ xml += " xs:schemaLocation='http://drools.org/drools-5.0/change-set drools-change-set-5.0.xsd' >";
+ xml += " <add> ";
+ xml += " <resource source='http://localhost:9000/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();
+
+ KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
+
+ 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");
+ aconf.setProperty("drools.agent.newInstance", "false");
+ KnowledgeAgent kagent = KnowledgeAgentFactory.newKnowledgeAgent(
+ "test agent", kbase, aconf);
+
+ kagent.applyChangeSet(ResourceFactory.newUrlResource(fxml.toURI().toURL()));
+
+ StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession();
+ List<String> list = new ArrayList<String>();
+ ksession.setGlobal("list", list);
+ ksession.fireAllRules();
+ ksession.dispose();
+
+ 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
+ Thread.sleep(2000);
+
+ String rule3 = "";
+ rule3 += "package org.drools.test\n";
+ rule3 += "global java.util.List list\n";
+ rule3 += "rule rule3\n";
+ rule3 += "when\n";
+ rule3 += "then\n";
+ rule3 += "list.add( drools.getRule().getName() );\n";
+ rule3 += "end\n";
+
+ kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
+ kbuilder.add(ResourceFactory.newByteArrayResource(rule2.getBytes()),
+ ResourceType.DRL);
+ kbuilder.add(ResourceFactory.newByteArrayResource(rule3.getBytes()),
+ ResourceType.DRL);
+ if (kbuilder.hasErrors()) {
+ fail(kbuilder.getErrors().toString());
+ }
+ pkg = (KnowledgePackage) kbuilder.getKnowledgePackages().iterator().next();
+ writePackage(pkg, pkg1);
+
+ Thread.sleep(3000);
+
+ ksession = kbase.newStatefulKnowledgeSession();
+ list = new ArrayList<String>();
+ ksession.setGlobal("list", list);
+ ksession.fireAllRules();
+ ksession.dispose();
+
+ assertEquals(2, list.size());
+
+ assertTrue(list.contains("rule2"));
+ assertTrue(list.contains("rule3"));
+ kagent.monitorResourceChangeEvents(false);
+ }
+
+
+
+ private static void writePackage(Object pkg, File p1file)
+ throws IOException, FileNotFoundException {
+ FileOutputStream out = new FileOutputStream(p1file);
+ try {
+ DroolsStreamUtils.streamOut(out, pkg);
+ } finally {
+ out.close();
+ }
+ }
+
+ public static class ResultHandlerImpl implements ResultHandler {
+
+ Object object;
+
+ public void handleResult(Object object) {
+ this.object = object;
+ }
+
+ public Object getObject() {
+ return this.object;
+ }
+ }
+}
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 2009-12-09 06:02:19 UTC (rev 30562)
+++ labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/agent/KnowledgeAgentTest.java 2009-12-09 13:29:15 UTC (rev 30563)
@@ -7,22 +7,15 @@
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
-import java.net.HttpURLConnection;
-import java.net.URL;
-import java.net.URLConnection;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import java.util.UUID;
import junit.framework.TestCase;
import org.drools.KnowledgeBase;
import org.drools.KnowledgeBaseFactory;
-import org.drools.agent.KnowledgeAgent;
-import org.drools.agent.KnowledgeAgentConfiguration;
-import org.drools.agent.KnowledgeAgentFactory;
import org.drools.agent.KnowledgeAgentTest.ResultHandlerImpl;
import org.drools.builder.KnowledgeBuilder;
import org.drools.builder.KnowledgeBuilderFactory;
@@ -33,7 +26,6 @@
import org.drools.io.ResourceFactory;
import org.drools.io.impl.ResourceChangeNotifierImpl;
import org.drools.io.impl.ResourceChangeScannerImpl;
-import org.drools.io.impl.UrlResource;
import org.drools.runtime.StatefulKnowledgeSession;
import org.drools.runtime.StatelessKnowledgeSession;
import org.drools.runtime.pipeline.Action;
@@ -47,911 +39,1117 @@
import org.mortbay.jetty.handler.ResourceHandler;
public class KnowledgeAgentTest extends TestCase {
- FileManager fileManager;
+ FileManager fileManager;
- private Server server;
- private String returnUrl;
+ private Server server;
- protected void setUp() throws Exception {
- fileManager = new FileManager();
- fileManager.setUp();
- ((ResourceChangeScannerImpl) ResourceFactory.getResourceChangeScannerService()).reset();
- ResourceFactory.getResourceChangeNotifierService().start();
- ResourceFactory.getResourceChangeScannerService().start();
+ protected void setUp() throws Exception {
+ fileManager = new FileManager();
+ fileManager.setUp();
+ ((ResourceChangeScannerImpl) ResourceFactory
+ .getResourceChangeScannerService()).reset();
+ ResourceFactory.getResourceChangeNotifierService().start();
+ ResourceFactory.getResourceChangeScannerService().start();
- this.server = new Server( 9000 );
- ResourceHandler resourceHandler = new ResourceHandler();
- resourceHandler.setResourceBase( fileManager.getRootDirectory().getPath() );
- System.out.println("root : " + fileManager.getRootDirectory().getPath() );
+ this.server = new Server(9000);
+ ResourceHandler resourceHandler = new ResourceHandler();
+ resourceHandler.setResourceBase(fileManager.getRootDirectory()
+ .getPath());
+ System.out
+ .println("root : " + fileManager.getRootDirectory().getPath());
- server.setHandler( resourceHandler );
+ server.setHandler(resourceHandler);
- server.start();
- }
-
+ server.start();
+ }
- protected void tearDown() throws Exception {
- fileManager.tearDown();
- ResourceFactory.getResourceChangeNotifierService().stop();
- ResourceFactory.getResourceChangeScannerService().stop();
- ((ResourceChangeNotifierImpl) ResourceFactory.getResourceChangeNotifierService()).reset();
- ((ResourceChangeScannerImpl) ResourceFactory.getResourceChangeScannerService()).reset();
-
- server.stop();
- }
-
- public void testModifyFileUrl() throws Exception {
+ protected void tearDown() throws Exception {
+ fileManager.tearDown();
+ ResourceFactory.getResourceChangeNotifierService().stop();
+ ResourceFactory.getResourceChangeScannerService().stop();
+ ((ResourceChangeNotifierImpl) ResourceFactory
+ .getResourceChangeNotifierService()).reset();
+ ((ResourceChangeScannerImpl) ResourceFactory
+ .getResourceChangeScannerService()).reset();
+ server.stop();
+ }
- UrlResource.CACHE_DIR = new File(".");
+ public void testModifyFileUrl() throws Exception {
+ String rule1 = "";
+ rule1 += "package org.drools.test\n";
+ rule1 += "global java.util.List list\n";
+ rule1 += "rule rule1\n";
+ rule1 += "when\n";
+ rule1 += "then\n";
+ rule1 += "list.add( drools.getRule().getName() );\n";
+ rule1 += "end\n";
+ File f1 = fileManager.newFile("rule1.drl");
+ Writer output = new BufferedWriter(new FileWriter(f1));
+ output.write(rule1);
+ output.close();
- String rule1 = "";
- rule1 += "package org.drools.test\n";
- rule1 += "global java.util.List list\n";
- rule1 += "rule rule1\n";
- rule1 += "when\n";
- rule1 += "then\n";
- rule1 += "list.add( drools.getRule().getName() );\n";
- rule1 += "end\n";
- File f1 = fileManager.newFile( "rule1.drl" );
- Writer output = new BufferedWriter( new FileWriter( f1 ) );
- output.write( rule1 );
- output.close();
+ String rule2 = "";
+ rule2 += "package org.drools.test\n";
+ rule2 += "global java.util.List list\n";
+ rule2 += "rule rule2\n";
+ rule2 += "when\n";
+ rule2 += "then\n";
+ rule2 += "list.add( drools.getRule().getName() );\n";
+ rule2 += "end\n";
+ File f2 = fileManager.newFile("rule2.drl");
+ output = new BufferedWriter(new FileWriter(f2));
+ output.write(rule2);
+ output.close();
- String rule2 = "";
- rule2 += "package org.drools.test\n";
- rule2 += "global java.util.List list\n";
- rule2 += "rule rule2\n";
- rule2 += "when\n";
- rule2 += "then\n";
- rule2 += "list.add( drools.getRule().getName() );\n";
- rule2 += "end\n";
- 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 drools-change-set-5.0.xsd' >";
+ xml += " <add> ";
+ xml += " <resource source='http://localhost:9000/rule1.drl' type='DRL' />";
+ xml += " <resource source='http://localhost:9000/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();
- String xml = "";
- xml += "<change-set xmlns='http://drools.org/drools-5.0/change-set'";
- xml += " xmlns:xs='http://www.w3.org/2001/XMLSchema-instance'";
- xml += " xs:schemaLocation='http://drools.org/drools-5.0/change-set drools-change-set-5.0.xsd' >";
- xml += " <add> ";
- xml += " <resource source='http://localhost:9000/rule1.drl' type='DRL' />";
- xml += " <resource source='http://localhost:9000/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();
+ KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
- KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
+ ResourceChangeScannerConfiguration sconf = ResourceFactory
+ .getResourceChangeScannerService()
+ .newResourceChangeScannerConfiguration();
+ sconf.setProperty("drools.resource.scanner.interval", "2");
+ ResourceFactory.getResourceChangeScannerService().configure(sconf);
- 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");
+ aconf.setProperty("drools.agent.newInstance", "true");
+ KnowledgeAgent kagent = KnowledgeAgentFactory.newKnowledgeAgent(
+ "test agent", kbase, aconf);
- 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());
- assertEquals("test agent", kagent.getName());
+ kagent.applyChangeSet(ResourceFactory.newUrlResource(fxml.toURI()
+ .toURL()));
- kagent.applyChangeSet( ResourceFactory.newUrlResource( fxml.toURI().toURL() ) );
+ StatefulKnowledgeSession ksession = kagent.getKnowledgeBase()
+ .newStatefulKnowledgeSession();
+ List<String> list = new ArrayList<String>();
+ ksession.setGlobal("list", list);
+ ksession.fireAllRules();
+ ksession.dispose();
- StatefulKnowledgeSession ksession = kagent.getKnowledgeBase().newStatefulKnowledgeSession();
- List list = new ArrayList();
- 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();
- 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
+ Thread.sleep(2000);
- // 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
- Thread.sleep( 2000 );
+ rule1 = "";
+ rule1 += "package org.drools.test\n";
+ rule1 += "global java.util.List list\n";
+ rule1 += "rule rule3\n";
+ rule1 += "when\n";
+ rule1 += "then\n";
+ rule1 += "list.add( drools.getRule().getName() );\n";
+ rule1 += "end\n";
+ output = new BufferedWriter(new FileWriter(f1));
+ output.write(rule1);
+ output.close();
+ Thread.sleep(3000);
- rule1 = "";
- rule1 += "package org.drools.test\n";
- rule1 += "global java.util.List list\n";
- rule1 += "rule rule3\n";
- rule1 += "when\n";
- rule1 += "then\n";
- rule1 += "list.add( drools.getRule().getName() );\n";
- rule1 += "end\n";
- output = new BufferedWriter( new FileWriter( f1 ) );
- output.write( rule1 );
- output.close();
- Thread.sleep( 3000 );
+ ksession = kagent.getKnowledgeBase().newStatefulKnowledgeSession();
+ list = new ArrayList<String>();
+ ksession.setGlobal("list", list);
+ ksession.fireAllRules();
+ ksession.dispose();
- ksession = kagent.getKnowledgeBase().newStatefulKnowledgeSession();
- list = new ArrayList();
- 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 );
+ /**
+ * Tests that if we change a ChangeSet that is referenced by another change
+ * set or added by another ChangeSet, that the changes are picked up.
+ *
+ * @throws Exception
+ * If an unexpected exception occurs.
+ */
+ public void testChangeSetInChangeSet() throws Exception {
+ String rule1 = "";
+ rule1 += "package org.drools.test\n";
+ rule1 += "global java.util.List list\n";
+ rule1 += "rule rule1\n";
+ rule1 += "when\n";
+ rule1 += "then\n";
+ rule1 += "list.add( drools.getRule().getName() );\n";
+ rule1 += "end\n";
+ File f1 = fileManager.newFile("rule1.drl");
+ Writer output = new BufferedWriter(new FileWriter(f1));
+ output.write(rule1);
+ output.close();
- server.stop();
+ String rule2 = "";
+ rule2 += "package org.drools.test\n";
+ rule2 += "global java.util.List list\n";
+ rule2 += "rule rule2\n";
+ rule2 += "when\n";
+ rule2 += "then\n";
+ rule2 += "list.add( drools.getRule().getName() );\n";
+ rule2 += "end\n";
+ 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'";
+ xml1 += " xs:schemaLocation='http://drools.org/drools-5.0/change-set drools-change-set-5.0.xsd' >";
+ xml1 += " <add> ";
+ xml1 += " <resource source='http://localhost:9000/rule1.drl' type='DRL' />";
+ xml1 += " <resource source='http://localhost:9000/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();
- //now try it with the server stopped, so cache has to be used...
- kagent = KnowledgeAgentFactory.newKnowledgeAgent( "test agent",
- kbase,
- aconf );
- kagent.monitorResourceChangeEvents(true);
- assertEquals("test agent", kagent.getName());
+ String xml2 = "";
+ xml2 += "<change-set xmlns='http://drools.org/drools-5.0/change-set'";
+ xml2 += " xmlns:xs='http://www.w3.org/2001/XMLSchema-instance'";
+ xml2 += " xs:schemaLocation='http://drools.org/drools-5.0/change-set drools-change-set-5.0.xsd' >";
+ xml2 += " <add> ";
+ xml2 += " <resource source='http://localhost:9000/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();
+ KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
- //hmmm...
- kagent.applyChangeSet( ResourceFactory.newFileResource(fxml) );
+ ResourceChangeScannerConfiguration sconf = ResourceFactory
+ .getResourceChangeScannerService()
+ .newResourceChangeScannerConfiguration();
+ sconf.setProperty("drools.resource.scanner.interval", "2");
+ ResourceFactory.getResourceChangeScannerService().configure(sconf);
- ksession = kagent.getKnowledgeBase().newStatefulKnowledgeSession();
- assertNotNull(ksession);
- }
-
- public void testModifyFileUrlWithStateless() throws Exception {
- String rule1 = "";
- rule1 += "package org.drools.test\n";
- rule1 += "global java.util.List list\n";
- rule1 += "rule rule1\n";
- rule1 += "when\n";
- rule1 += "then\n";
- rule1 += "list.add( drools.getRule().getName() );\n";
- rule1 += "end\n";
- File f1 = fileManager.newFile( "rule1.drl" );
- Writer output = new BufferedWriter( new FileWriter( f1 ) );
- output.write( rule1 );
- output.close();
+ 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);
- String rule2 = "";
- rule2 += "package org.drools.test\n";
- rule2 += "global java.util.List list\n";
- rule2 += "rule rule2\n";
- rule2 += "when\n";
- rule2 += "then\n";
- rule2 += "list.add( drools.getRule().getName() );\n";
- rule2 += "end\n";
- File f2 = fileManager.newFile( "rule2.drl" );
- output = new BufferedWriter( new FileWriter( f2 ) );
- output.write( rule2 );
- output.close();
+ assertEquals("test agent", kagent.getName());
- String xml = "";
- xml += "<change-set xmlns='http://drools.org/drools-5.0/change-set'";
- xml += " xmlns:xs='http://www.w3.org/2001/XMLSchema-instance'";
- xml += " xs:schemaLocation='http://drools.org/drools-5.0/change-set drools-change-set-5.0.xsd' >";
- xml += " <add> ";
- xml += " <resource source='http://localhost:9000/rule1.drl' type='DRL' />";
- xml += " <resource source='http://localhost:9000/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();
+ kagent.applyChangeSet(ResourceFactory.newUrlResource(fxml2.toURI()
+ .toURL()));
- KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
+ StatefulKnowledgeSession ksession = kagent.getKnowledgeBase()
+ .newStatefulKnowledgeSession();
+ List<String> list = new ArrayList<String>();
+ ksession.setGlobal("list", list);
+ ksession.fireAllRules();
+ ksession.dispose();
- ResourceChangeScannerConfiguration sconf = ResourceFactory.getResourceChangeScannerService().newResourceChangeScannerConfiguration();
- sconf.setProperty( "drools.resource.scanner.interval",
- "2" );
- ResourceFactory.getResourceChangeScannerService().configure( sconf );
+ assertEquals(2, list.size());
+ assertTrue(list.contains("rule1"));
+ assertTrue(list.contains("rule2"));
- 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 );
+ list.clear();
- kagent.applyChangeSet( ResourceFactory.newUrlResource( fxml.toURI().toURL() ) );
+ // 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
+ Thread.sleep(2000);
- StatelessKnowledgeSession ksession = kagent.newStatelessKnowledgeSession();
- List list = new ArrayList();
- ksession.setGlobal( "list",
- list );
- ksession.execute( "hello" );
+ rule1 = "";
+ rule1 += "package org.drools.test\n";
+ rule1 += "global java.util.List list\n";
+ rule1 += "rule rule3\n";
+ rule1 += "when\n";
+ rule1 += "then\n";
+ rule1 += "list.add( drools.getRule().getName() );\n";
+ rule1 += "end\n";
+ output = new BufferedWriter(new FileWriter(f1));
+ output.write(rule1);
+ output.close();
+ Thread.sleep(3000);
- assertEquals( 2,
- list.size() );
- assertTrue( list.contains( "rule1" ) );
- assertTrue( list.contains( "rule2" ) );
+ ksession = kagent.getKnowledgeBase().newStatefulKnowledgeSession();
+ list = new ArrayList<String>();
+ ksession.setGlobal("list", list);
+ ksession.fireAllRules();
+ ksession.dispose();
- list.clear();
+ assertEquals(2, list.size());
- // 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
- Thread.sleep( 2000 );
+ assertTrue(list.contains("rule3"));
+ assertTrue(list.contains("rule2"));
+ kagent.monitorResourceChangeEvents(false);
+ }
- rule1 = "";
- rule1 += "package org.drools.test\n";
- rule1 += "global java.util.List list\n";
- rule1 += "rule rule3\n";
- rule1 += "when\n";
- rule1 += "then\n";
- rule1 += "list.add( drools.getRule().getName() );\n";
- rule1 += "end\n";
- System.out.println("root : " + f1.getPath() );
- output = new BufferedWriter( new FileWriter( f1 ) );
- output.write( rule1 );
- output.close();
- Thread.sleep( 3000 );
+ public void testModifyFileUrlWithStateless() throws Exception {
+ String rule1 = "";
+ rule1 += "package org.drools.test\n";
+ rule1 += "global java.util.List list\n";
+ rule1 += "rule rule1\n";
+ rule1 += "when\n";
+ rule1 += "then\n";
+ rule1 += "list.add( drools.getRule().getName() );\n";
+ rule1 += "end\n";
+ File f1 = fileManager.newFile("rule1.drl");
+ Writer output = new BufferedWriter(new FileWriter(f1));
+ output.write(rule1);
+ output.close();
+ String rule2 = "";
+ rule2 += "package org.drools.test\n";
+ rule2 += "global java.util.List list\n";
+ rule2 += "rule rule2\n";
+ rule2 += "when\n";
+ rule2 += "then\n";
+ rule2 += "list.add( drools.getRule().getName() );\n";
+ rule2 += "end\n";
+ File f2 = fileManager.newFile("rule2.drl");
+ output = new BufferedWriter(new FileWriter(f2));
+ output.write(rule2);
+ output.close();
- ksession.execute( "hello" );
+ String xml = "";
+ xml += "<change-set xmlns='http://drools.org/drools-5.0/change-set'";
+ xml += " xmlns:xs='http://www.w3.org/2001/XMLSchema-instance'";
+ xml += " xs:schemaLocation='http://drools.org/drools-5.0/change-set drools-change-set-5.0.xsd' >";
+ xml += " <add> ";
+ xml += " <resource source='http://localhost:9000/rule1.drl' type='DRL' />";
+ xml += " <resource source='http://localhost:9000/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();
- assertEquals( 2,
- list.size() );
-
- assertTrue( list.contains( "rule3" ) );
- assertTrue( list.contains( "rule2" ) );
+ KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
+ ResourceChangeScannerConfiguration sconf = ResourceFactory
+ .getResourceChangeScannerService()
+ .newResourceChangeScannerConfiguration();
+ sconf.setProperty("drools.resource.scanner.interval", "2");
+ ResourceFactory.getResourceChangeScannerService().configure(sconf);
- kagent.monitorResourceChangeEvents( false );
+ 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);
+ kagent.applyChangeSet(ResourceFactory.newUrlResource(fxml.toURI()
+ .toURL()));
+ StatelessKnowledgeSession ksession = kagent
+ .newStatelessKnowledgeSession();
+ List<String> list = new ArrayList<String>();
+ ksession.setGlobal("list", list);
+ ksession.execute("hello");
- }
+ assertEquals(2, list.size());
+ assertTrue(list.contains("rule1"));
+ assertTrue(list.contains("rule2"));
- public void testModifyPackageUrl() throws Exception {
- String rule1 = "";
- rule1 += "package org.drools.test\n";
- rule1 += "global java.util.List list\n";
- rule1 += "rule rule1\n";
- rule1 += "when\n";
- rule1 += "then\n";
- rule1 += "list.add( drools.getRule().getName() );\n";
- rule1 += "end\n";
-
- String rule2 = "";
- rule2 += "package org.drools.test\n";
- rule2 += "global java.util.List list\n";
- rule2 += "rule rule2\n";
- rule2 += "when\n";
- rule2 += "then\n";
- rule2 += "list.add( drools.getRule().getName() );\n";
- rule2 += "end\n";
-
- 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() );
- }
- KnowledgePackage pkg = ( KnowledgePackage ) kbuilder.getKnowledgePackages().iterator().next();
- writePackage( pkg, fileManager.newFile( "pkg1.pkg" ) );
-
-
- String xml = "";
- xml += "<change-set xmlns='http://drools.org/drools-5.0/change-set'";
- xml += " xmlns:xs='http://www.w3.org/2001/XMLSchema-instance'";
- xml += " xs:schemaLocation='http://drools.org/drools-5.0/change-set drools-change-set-5.0.xsd' >";
- xml += " <add> ";
- xml += " <resource source='http://localhost:9000/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();
-
- KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
-
- 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" );
- aconf.setProperty( "drools.agent.newInstance",
- "true" );
- KnowledgeAgent kagent = KnowledgeAgentFactory.newKnowledgeAgent( "test agent",
- kbase,
- aconf );
-
- kagent.applyChangeSet( ResourceFactory.newUrlResource( fxml.toURI().toURL() ) );
-
- StatefulKnowledgeSession ksession = kagent.getKnowledgeBase().newStatefulKnowledgeSession();
- List list = new ArrayList();
- ksession.setGlobal( "list",
- list );
- ksession.fireAllRules();
- ksession.dispose();
-
- 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
- Thread.sleep( 2000 );
-
- rule1 = "";
- rule1 += "package org.drools.test\n";
- rule1 += "global java.util.List list\n";
- rule1 += "rule rule3\n";
- rule1 += "when\n";
- rule1 += "then\n";
- rule1 += "list.add( drools.getRule().getName() );\n";
- rule1 += "end\n";
-
- 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() );
- }
- pkg = ( KnowledgePackage ) kbuilder.getKnowledgePackages().iterator().next();
- writePackage( pkg, fileManager.newFile( "pkg1.pkg" ) );
-
- //KnowledgePackage pkg2 = ( KnowledgePackage ) DroolsStreamUtils.streamIn( new FileInputStream( fileManager.newFile( "pkg1.pkg" ) ) );
-
-
- Thread.sleep( 3000 );
-
- ksession = kagent.getKnowledgeBase().newStatefulKnowledgeSession();
- list = new ArrayList();
- ksession.setGlobal( "list",
- list );
- ksession.fireAllRules();
- ksession.dispose();
-
- assertEquals( 2,
- list.size() );
-
- assertTrue( list.contains( "rule3" ) );
- assertTrue( list.contains( "rule2" ) );
- kagent.monitorResourceChangeEvents( false );
- }
+ 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
+ Thread.sleep(2000);
- public void testDeletePackageUrl() throws Exception {
- String rule1 = "";
- rule1 += "package org.drools.test1\n";
- rule1 += "global java.util.List list\n";
- rule1 += "rule rule1\n";
- rule1 += "when\n";
- rule1 += "then\n";
- rule1 += "list.add( drools.getRule().getName() );\n";
- rule1 += "end\n";
+ rule1 = "";
+ rule1 += "package org.drools.test\n";
+ rule1 += "global java.util.List list\n";
+ rule1 += "rule rule3\n";
+ rule1 += "when\n";
+ rule1 += "then\n";
+ rule1 += "list.add( drools.getRule().getName() );\n";
+ rule1 += "end\n";
+ System.out.println("root : " + f1.getPath());
+ output = new BufferedWriter(new FileWriter(f1));
+ output.write(rule1);
+ output.close();
+ Thread.sleep(3000);
- String rule2 = "";
- rule2 += "package org.drools.test2\n";
- rule2 += "global java.util.List list\n";
- rule2 += "rule rule2\n";
- rule2 += "when\n";
- rule2 += "then\n";
- rule2 += "list.add( drools.getRule().getName() );\n";
- rule2 += "end\n";
+ ksession.execute("hello");
- 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() );
- }
+ assertEquals(2, list.size());
- Map map = new HashMap();
- 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" ) );
+ assertTrue(list.contains("rule3"));
+ assertTrue(list.contains("rule2"));
+ kagent.monitorResourceChangeEvents(false);
+ }
+ public void testModifyPackageUrl() throws Exception {
+ String rule1 = "";
+ rule1 += "package org.drools.test\n";
+ rule1 += "global java.util.List list\n";
+ rule1 += "rule rule1\n";
+ rule1 += "when\n";
+ rule1 += "then\n";
+ rule1 += "list.add( drools.getRule().getName() );\n";
+ rule1 += "end\n";
- String xml = "";
- xml += "<change-set xmlns='http://drools.org/drools-5.0/change-set'";
- xml += " xmlns:xs='http://www.w3.org/2001/XMLSchema-instance'";
- xml += " xs:schemaLocation='http://drools.org/drools-5.0/change-set drools-change-set-5.0.xsd' >";
- xml += " <add> ";
- xml += " <resource source='http://localhost:9000/pkg1.pkg' type='PKG' />";
- xml += " <resource source='http://localhost:9000/pkg2.pkg' type='PKG' />";
- xml += " </add> ";
- xml += "</change-set>";
+ String rule2 = "";
+ rule2 += "package org.drools.test\n";
+ rule2 += "global java.util.List list\n";
+ rule2 += "rule rule2\n";
+ rule2 += "when\n";
+ rule2 += "then\n";
+ rule2 += "list.add( drools.getRule().getName() );\n";
+ rule2 += "end\n";
- KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
+ 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());
+ }
+ KnowledgePackage pkg = (KnowledgePackage) kbuilder
+ .getKnowledgePackages().iterator().next();
+ writePackage(pkg, fileManager.newFile("pkg1.pkg"));
- ResourceChangeScannerConfiguration sconf = ResourceFactory.getResourceChangeScannerService().newResourceChangeScannerConfiguration();
- sconf.setProperty( "drools.resource.scanner.interval",
- "2" );
- ResourceFactory.getResourceChangeScannerService().configure( sconf );
+ String xml = "";
+ xml += "<change-set xmlns='http://drools.org/drools-5.0/change-set'";
+ xml += " xmlns:xs='http://www.w3.org/2001/XMLSchema-instance'";
+ xml += " xs:schemaLocation='http://drools.org/drools-5.0/change-set drools-change-set-5.0.xsd' >";
+ xml += " <add> ";
+ xml += " <resource source='http://localhost:9000/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();
- 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 );
+ KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
- kagent.applyChangeSet( ResourceFactory.newByteArrayResource( xml.getBytes() ) );
+ ResourceChangeScannerConfiguration sconf = ResourceFactory
+ .getResourceChangeScannerService()
+ .newResourceChangeScannerConfiguration();
+ sconf.setProperty("drools.resource.scanner.interval", "2");
+ ResourceFactory.getResourceChangeScannerService().configure(sconf);
- StatefulKnowledgeSession ksession = kagent.getKnowledgeBase().newStatefulKnowledgeSession();
- List list = new ArrayList();
- ksession.setGlobal( "list",
- list );
- ksession.fireAllRules();
- ksession.dispose();
+ 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( 2,
- list.size() );
- assertTrue( list.contains( "rule1" ) );
- assertTrue( list.contains( "rule2" ) );
+ kagent.applyChangeSet(ResourceFactory.newUrlResource(fxml.toURI()
+ .toURL()));
- list.clear();
+ StatefulKnowledgeSession ksession = kagent.getKnowledgeBase()
+ .newStatefulKnowledgeSession();
+ List<String> list = new ArrayList<String>();
+ ksession.setGlobal("list", list);
+ ksession.fireAllRules();
+ ksession.dispose();
- // 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
- Thread.sleep( 2000 );
+ assertEquals(2, list.size());
+ assertTrue(list.contains("rule1"));
+ assertTrue(list.contains("rule2"));
- xml = "";
- xml += "<change-set xmlns='http://drools.org/drools-5.0/change-set'";
- xml += " xmlns:xs='http://www.w3.org/2001/XMLSchema-instance'";
- xml += " xs:schemaLocation='http://drools.org/drools-5.0/change-set drools-change-set-5.0.xsd' >";
- xml += " <remove> ";
- xml += " <resource source='http://localhost:9000/pkg2.pkg' type='PKG' />";
- xml += " </remove> ";
- xml += "</change-set>";
+ list.clear();
- kagent.applyChangeSet( ResourceFactory.newByteArrayResource( xml.getBytes() ) );
+ // 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
+ Thread.sleep(2000);
- Thread.sleep( 3000 );
+ rule1 = "";
+ rule1 += "package org.drools.test\n";
+ rule1 += "global java.util.List list\n";
+ rule1 += "rule rule3\n";
+ rule1 += "when\n";
+ rule1 += "then\n";
+ rule1 += "list.add( drools.getRule().getName() );\n";
+ rule1 += "end\n";
- ksession = kagent.getKnowledgeBase().newStatefulKnowledgeSession();
- list = new ArrayList();
- ksession.setGlobal( "list",
- list );
- ksession.fireAllRules();
- ksession.dispose();
+ 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());
+ }
+ pkg = (KnowledgePackage) kbuilder.getKnowledgePackages().iterator()
+ .next();
+ writePackage(pkg, fileManager.newFile("pkg1.pkg"));
- assertEquals( 1,
- list.size() );
+ // KnowledgePackage pkg2 = ( KnowledgePackage )
+ // DroolsStreamUtils.streamIn( new FileInputStream( fileManager.newFile(
+ // "pkg1.pkg" ) ) );
- assertTrue( list.contains( "rule1" ) );
- kagent.monitorResourceChangeEvents( false );
- }
+ Thread.sleep(3000);
- public void testOldSchoolPackageUrl() throws Exception {
- String rule1 = "";
- rule1 += "package org.drools.test\n";
- rule1 += "global java.util.List list\n";
- rule1 += "rule rule1\n";
- rule1 += "when\n";
- rule1 += "then\n";
- rule1 += "list.add( drools.getRule().getName() );\n";
- rule1 += "end\n";
+ ksession = kagent.getKnowledgeBase().newStatefulKnowledgeSession();
+ list = new ArrayList<String>();
+ ksession.setGlobal("list", list);
+ ksession.fireAllRules();
+ ksession.dispose();
- String rule2 = "";
- rule2 += "package org.drools.test\n";
- rule2 += "global java.util.List list\n";
- rule2 += "rule rule2\n";
- rule2 += "when\n";
- rule2 += "then\n";
- rule2 += "list.add( drools.getRule().getName() );\n";
- rule2 += "end\n";
+ assertEquals(2, list.size());
+ assertTrue(list.contains("rule3"));
+ assertTrue(list.contains("rule2"));
+ kagent.monitorResourceChangeEvents(false);
+ }
+ public void testDeletePackageUrl() throws Exception {
+ String rule1 = "";
+ rule1 += "package org.drools.test1\n";
+ rule1 += "global java.util.List list\n";
+ rule1 += "rule rule1\n";
+ rule1 += "when\n";
+ rule1 += "then\n";
+ rule1 += "list.add( drools.getRule().getName() );\n";
+ rule1 += "end\n";
+ String rule2 = "";
+ rule2 += "package org.drools.test2\n";
+ rule2 += "global java.util.List list\n";
+ rule2 += "rule rule2\n";
+ rule2 += "when\n";
+ rule2 += "then\n";
+ rule2 += "list.add( drools.getRule().getName() );\n";
+ rule2 += "end\n";
- 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() );
- }
+ 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());
+ }
- KnowledgeBuilderImpl kbi = (KnowledgeBuilderImpl) kbuilder;
+ Map<String, KnowledgePackage> map = new HashMap<String, KnowledgePackage>();
+ 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"));
- //KnowledgePackage pkg = ( KnowledgePackage ) kbuilder.getKnowledgePackages().iterator().next();
- writePackage( kbi.getPackageBuilder().getPackage(), fileManager.newFile( "pkgold.pkg" ) );
+ String xml = "";
+ xml += "<change-set xmlns='http://drools.org/drools-5.0/change-set'";
+ xml += " xmlns:xs='http://www.w3.org/2001/XMLSchema-instance'";
+ xml += " xs:schemaLocation='http://drools.org/drools-5.0/change-set drools-change-set-5.0.xsd' >";
+ xml += " <add> ";
+ xml += " <resource source='http://localhost:9000/pkg1.pkg' type='PKG' />";
+ xml += " <resource source='http://localhost:9000/pkg2.pkg' type='PKG' />";
+ xml += " </add> ";
+ xml += "</change-set>";
+ KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
- String xml = "";
- xml += "<change-set xmlns='http://drools.org/drools-5.0/change-set'";
- xml += " xmlns:xs='http://www.w3.org/2001/XMLSchema-instance'";
- xml += " xs:schemaLocation='http://drools.org/drools-5.0/change-set drools-change-set-5.0.xsd' >";
- xml += " <add> ";
- xml += " <resource source='http://localhost:9000/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();
+ ResourceChangeScannerConfiguration sconf = ResourceFactory
+ .getResourceChangeScannerService()
+ .newResourceChangeScannerConfiguration();
+ sconf.setProperty("drools.resource.scanner.interval", "2");
+ ResourceFactory.getResourceChangeScannerService().configure(sconf);
- KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
+ 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);
- ResourceChangeScannerConfiguration sconf = ResourceFactory.getResourceChangeScannerService().newResourceChangeScannerConfiguration();
- sconf.setProperty( "drools.resource.scanner.interval",
- "2" );
- ResourceFactory.getResourceChangeScannerService().configure( sconf );
+ kagent.applyChangeSet(ResourceFactory.newByteArrayResource(xml
+ .getBytes()));
- 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 );
+ StatefulKnowledgeSession ksession = kagent.getKnowledgeBase()
+ .newStatefulKnowledgeSession();
+ List<String> list = new ArrayList<String>();
+ ksession.setGlobal("list", list);
+ ksession.fireAllRules();
+ ksession.dispose();
- kagent.applyChangeSet( ResourceFactory.newUrlResource( fxml.toURI().toURL() ) );
+ assertEquals(2, list.size());
+ assertTrue(list.contains("rule1"));
+ assertTrue(list.contains("rule2"));
- StatefulKnowledgeSession ksession = kagent.getKnowledgeBase().newStatefulKnowledgeSession();
- List list = new ArrayList();
- ksession.setGlobal( "list",
- list );
- ksession.fireAllRules();
- ksession.dispose();
+ list.clear();
- assertEquals( 2,
- list.size() );
- assertTrue( list.contains( "rule1" ) );
- assertTrue( list.contains( "rule2" ) );
+ // 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
+ Thread.sleep(2000);
+ xml = "";
+ xml += "<change-set xmlns='http://drools.org/drools-5.0/change-set'";
+ xml += " xmlns:xs='http://www.w3.org/2001/XMLSchema-instance'";
+ xml += " xs:schemaLocation='http://drools.org/drools-5.0/change-set drools-change-set-5.0.xsd' >";
+ xml += " <remove> ";
+ xml += " <resource source='http://localhost:9000/pkg2.pkg' type='PKG' />";
+ xml += " </remove> ";
+ xml += "</change-set>";
- }
+ kagent.applyChangeSet(ResourceFactory.newByteArrayResource(xml
+ .getBytes()));
- public void testModifyFile() throws IOException,
- InterruptedException {
- String rule1 = "";
- rule1 += "package org.drools.test\n";
- rule1 += "global java.util.List list\n";
- rule1 += "rule rule1\n";
- rule1 += "when\n";
- rule1 += "then\n";
- rule1 += "list.add( drools.getRule().getName() );\n";
- rule1 += "end\n";
- File f1 = fileManager.newFile( "rule1.drl" );
- Writer output = new BufferedWriter( new FileWriter( f1 ) );
- output.write( rule1 );
- output.close();
+ Thread.sleep(3000);
- String rule2 = "";
- rule2 += "package org.drools.test\n";
- rule2 += "global java.util.List list\n";
- rule2 += "rule rule2\n";
- rule2 += "when\n";
- rule2 += "then\n";
- rule2 += "list.add( drools.getRule().getName() );\n";
- rule2 += "end\n";
- File f2 = fileManager.newFile( "rule2.drl" );
- output = new BufferedWriter( new FileWriter( f2 ) );
- output.write( rule2 );
- output.close();
+ ksession = kagent.getKnowledgeBase().newStatefulKnowledgeSession();
+ list = new ArrayList<String>();
+ ksession.setGlobal("list", list);
+ ksession.fireAllRules();
+ ksession.dispose();
- String xml = "";
- xml += "<change-set xmlns='http://drools.org/drools-5.0/change-set'";
- xml += " xmlns:xs='http://www.w3.org/2001/XMLSchema-instance'";
- xml += " xs:schemaLocation='http://drools.org/drools-5.0/change-set drools-change-set-5.0.xsd' >";
- xml += " <add> ";
- xml += " <resource source='" + 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();
+ assertEquals(1, list.size());
- KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
+ assertTrue(list.contains("rule1"));
+ kagent.monitorResourceChangeEvents(false);
+ }
- ResourceChangeScannerConfiguration sconf = ResourceFactory.getResourceChangeScannerService().newResourceChangeScannerConfiguration();
- sconf.setProperty( "drools.resource.scanner.interval",
- "2" );
- ResourceFactory.getResourceChangeScannerService().configure( sconf );
+ public void testOldSchoolPackageUrl() throws Exception {
+ String rule1 = "";
+ rule1 += "package org.drools.test\n";
+ rule1 += "global java.util.List list\n";
+ rule1 += "rule rule1\n";
+ rule1 += "when\n";
+ rule1 += "then\n";
+ rule1 += "list.add( drools.getRule().getName() );\n";
+ rule1 += "end\n";
- 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 );
+ String rule2 = "";
+ rule2 += "package org.drools.test\n";
+ rule2 += "global java.util.List list\n";
+ rule2 += "rule rule2\n";
+ rule2 += "when\n";
+ rule2 += "then\n";
+ rule2 += "list.add( drools.getRule().getName() );\n";
+ rule2 += "end\n";
- kagent.applyChangeSet( ResourceFactory.newUrlResource( fxml.toURI().toURL() ) );
+ 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());
+ }
- StatefulKnowledgeSession ksession = kagent.getKnowledgeBase().newStatefulKnowledgeSession();
- List list = new ArrayList();
- ksession.setGlobal( "list",
- list );
- ksession.fireAllRules();
- ksession.dispose();
+ KnowledgeBuilderImpl kbi = (KnowledgeBuilderImpl) kbuilder;
- assertEquals( 2,
- list.size() );
- assertTrue( list.contains( "rule1" ) );
- assertTrue( list.contains( "rule2" ) );
+ // KnowledgePackage pkg = ( KnowledgePackage )
+ // kbuilder.getKnowledgePackages().iterator().next();
+ writePackage(kbi.getPackageBuilder().getPackage(), fileManager
+ .newFile("pkgold.pkg"));
- list.clear();
+ String xml = "";
+ xml += "<change-set xmlns='http://drools.org/drools-5.0/change-set'";
+ xml += " xmlns:xs='http://www.w3.org/2001/XMLSchema-instance'";
+ xml += " xs:schemaLocation='http://drools.org/drools-5.0/change-set drools-change-set-5.0.xsd' >";
+ xml += " <add> ";
+ xml += " <resource source='http://localhost:9000/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();
- // 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
- Thread.sleep( 2000 );
+ KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
- rule1 = "";
- rule1 += "package org.drools.test\n";
- rule1 += "global java.util.List list\n";
- rule1 += "rule rule3\n";
- rule1 += "when\n";
- rule1 += "then\n";
- rule1 += "list.add( drools.getRule().getName() );\n";
- rule1 += "end\n";
- output = new BufferedWriter( new FileWriter( f1 ) );
- output.write( rule1 );
- output.close();
- Thread.sleep( 3000 );
+ ResourceChangeScannerConfiguration sconf = ResourceFactory
+ .getResourceChangeScannerService()
+ .newResourceChangeScannerConfiguration();
+ sconf.setProperty("drools.resource.scanner.interval", "2");
+ ResourceFactory.getResourceChangeScannerService().configure(sconf);
- ksession = kagent.getKnowledgeBase().newStatefulKnowledgeSession();
- list = new ArrayList();
- ksession.setGlobal( "list",
- list );
- ksession.fireAllRules();
- ksession.dispose();
+ 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( 2,
- list.size() );
+ kagent.applyChangeSet(ResourceFactory.newUrlResource(fxml.toURI()
+ .toURL()));
- assertTrue( list.contains( "rule3" ) );
- assertTrue( list.contains( "rule2" ) );
- kagent.monitorResourceChangeEvents( false );
- }
-
- 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 = "";
- rule1 += "package org.drools.test\n";
- rule1 += "global java.util.List list\n";
- rule1 += "rule rule1\n";
- rule1 += "when\n";
- rule1 += "then\n";
- rule1 += "list.add( drools.getRule().getName() );\n";
- rule1 += "end\n";
- File f1 = fileManager.newFile( "rule1.drl" );
+ StatefulKnowledgeSession ksession = kagent.getKnowledgeBase()
+ .newStatefulKnowledgeSession();
+ List<String> list = new ArrayList<String>();
+ ksession.setGlobal("list", list);
+ ksession.fireAllRules();
+ ksession.dispose();
- Writer output = new BufferedWriter( new FileWriter( f1 ) );
- output.write( rule1 );
- output.close();
+ assertEquals(2, list.size());
+ assertTrue(list.contains("rule1"));
+ assertTrue(list.contains("rule2"));
- String rule2 = "";
- rule2 += "package org.drools.test\n";
- rule2 += "global java.util.List list\n";
- rule2 += "rule rule2\n";
- rule2 += "when\n";
- rule2 += "then\n";
- rule2 += "list.add( drools.getRule().getName() );\n";
- rule2 += "end\n";
- 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 drools-change-set-5.0.xsd' >";
- xml += " <add> ";
- xml += " <resource source='" + 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();
+ public void testModifyFile() throws IOException, InterruptedException {
+ String rule1 = "";
+ rule1 += "package org.drools.test\n";
+ rule1 += "global java.util.List list\n";
+ rule1 += "rule rule1\n";
+ rule1 += "when\n";
+ rule1 += "then\n";
+ rule1 += "list.add( drools.getRule().getName() );\n";
+ rule1 += "end\n";
+ File f1 = fileManager.newFile("rule1.drl");
+ Writer output = new BufferedWriter(new FileWriter(f1));
+ output.write(rule1);
+ output.close();
- // KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
- // kbuilder.add( ResourceFactory.newUrlResource( fxml.toURI().toURL() ),
- // ResourceType.ChangeSet );
- // assertFalse( kbuilder.hasErrors() );
+ String rule2 = "";
+ rule2 += "package org.drools.test\n";
+ rule2 += "global java.util.List list\n";
+ rule2 += "rule rule2\n";
+ rule2 += "when\n";
+ rule2 += "then\n";
+ rule2 += "list.add( drools.getRule().getName() );\n";
+ rule2 += "end\n";
+ File f2 = fileManager.newFile("rule2.drl");
+ output = new BufferedWriter(new FileWriter(f2));
+ output.write(rule2);
+ output.close();
- KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
- //kbase.addKnowledgePackages( kbuilder.getKnowledgePackages() );
+ String xml = "";
+ xml += "<change-set xmlns='http://drools.org/drools-5.0/change-set'";
+ xml += " xmlns:xs='http://www.w3.org/2001/XMLSchema-instance'";
+ xml += " xs:schemaLocation='http://drools.org/drools-5.0/change-set drools-change-set-5.0.xsd' >";
+ xml += " <add> ";
+ xml += " <resource source='" + 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();
- ResourceChangeScannerConfiguration sconf = ResourceFactory.getResourceChangeScannerService().newResourceChangeScannerConfiguration();
- sconf.setProperty( "drools.resource.scanner.interval",
- "2" );
- ResourceFactory.getResourceChangeScannerService().configure( sconf );
+ KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
- KnowledgeAgentConfiguration aconf = KnowledgeAgentFactory.newKnowledgeAgentConfiguration();
- aconf.setProperty( "drools.agent.scanDirectories",
- "true" );
- aconf.setProperty( "drools.agent.newInstance",
- "true" );
+ ResourceChangeScannerConfiguration sconf = ResourceFactory
+ .getResourceChangeScannerService()
+ .newResourceChangeScannerConfiguration();
+ sconf.setProperty("drools.resource.scanner.interval", "2");
+ ResourceFactory.getResourceChangeScannerService().configure(sconf);
- KnowledgeAgent kagent = KnowledgeAgentFactory.newKnowledgeAgent( "test agent",
- kbase,
- aconf );
- 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);
- Thread.sleep( 3000 ); // give it 2 seconds to detect and build the changes
- StatefulKnowledgeSession ksession = kagent.getKnowledgeBase().newStatefulKnowledgeSession();
- List list = new ArrayList();
- ksession.setGlobal( "list",
- list );
- ksession.fireAllRules();
- ksession.dispose();
+ kagent.applyChangeSet(ResourceFactory.newUrlResource(fxml.toURI()
+ .toURL()));
- assertEquals( 2,
- list.size() );
- assertTrue( list.contains( "rule1" ) );
- assertTrue( list.contains( "rule2" ) );
+ StatefulKnowledgeSession ksession = kagent.getKnowledgeBase()
+ .newStatefulKnowledgeSession();
+ List<String> list = new ArrayList<String>();
+ ksession.setGlobal("list", list);
+ ksession.fireAllRules();
+ ksession.dispose();
- list.clear();
- String rule3 = "";
- rule3 += "package org.drools.test\n";
- rule3 += "global java.util.List list\n";
- rule3 += "rule rule3\n";
- rule3 += "when\n";
- rule3 += "then\n";
- rule3 += "list.add( drools.getRule().getName() );\n";
- rule3 += "end\n";
- File f3 = fileManager.newFile( "rule3.drl" );
- output = new BufferedWriter( new FileWriter( f3 ) );
- output.write( rule3 );
- output.close();
+ assertEquals(2, list.size());
+ assertTrue(list.contains("rule1"));
+ assertTrue(list.contains("rule2"));
- assertTrue( f1.delete() );
+ list.clear();
- Thread.sleep( 3000 );
+ // 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
+ Thread.sleep(2000);
- ksession = kagent.getKnowledgeBase().newStatefulKnowledgeSession();
- list = new ArrayList();
- ksession.setGlobal( "list",
- list );
- ksession.fireAllRules();
- ksession.dispose();
+ rule1 = "";
+ rule1 += "package org.drools.test\n";
+ rule1 += "global java.util.List list\n";
+ rule1 += "rule rule3\n";
+ rule1 += "when\n";
+ rule1 += "then\n";
+ rule1 += "list.add( drools.getRule().getName() );\n";
+ rule1 += "end\n";
+ output = new BufferedWriter(new FileWriter(f1));
+ output.write(rule1);
+ output.close();
+ Thread.sleep(3000);
- assertEquals( 2,
- list.size() );
- assertTrue( list.contains( "rule2" ) );
- assertTrue( list.contains( "rule3" ) );
+ ksession = kagent.getKnowledgeBase().newStatefulKnowledgeSession();
+ list = new ArrayList<String>();
+ ksession.setGlobal("list", list);
+ ksession.fireAllRules();
+ ksession.dispose();
- kagent.monitorResourceChangeEvents( false );
- }
+ assertEquals(2, list.size());
- public void testStatelessWithPipeline() throws Exception {
- String rule1 = "";
- rule1 += "package org.drools.test\n";
- rule1 += "global java.util.List list\n";
- rule1 += "rule rule1\n";
- rule1 += "when\n";
- rule1 += "then\n";
- rule1 += "list.add( drools.getRule().getName() );\n";
- rule1 += "end\n";
- File f1 = fileManager.newFile( "rule1.drl" );
+ assertTrue(list.contains("rule3"));
+ assertTrue(list.contains("rule2"));
+ kagent.monitorResourceChangeEvents(false);
+ }
- Writer output = new BufferedWriter( new FileWriter( f1 ) );
- output.write( rule1 );
- output.close();
+ 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 = "";
+ rule1 += "package org.drools.test\n";
+ rule1 += "global java.util.List list\n";
+ rule1 += "rule rule1\n";
+ rule1 += "when\n";
+ rule1 += "then\n";
+ rule1 += "list.add( drools.getRule().getName() );\n";
+ rule1 += "end\n";
+ File f1 = fileManager.newFile("rule1.drl");
- String rule2 = "";
- rule2 += "package org.drools.test\n";
- rule2 += "global java.util.List list\n";
- rule2 += "rule rule2\n";
- rule2 += "when\n";
- rule2 += "then\n";
- rule2 += "list.add( drools.getRule().getName() );\n";
- rule2 += "end\n";
- File f2 = fileManager.newFile( "rule2.drl" );
- output = new BufferedWriter( new FileWriter( f2 ) );
- output.write( rule2 );
- output.close();
+ Writer output = new BufferedWriter(new FileWriter(f1));
+ output.write(rule1);
+ output.close();
- String xml = "";
- xml += "<change-set xmlns='http://drools.org/drools-5.0/change-set'";
- xml += " xmlns:xs='http://www.w3.org/2001/XMLSchema-instance'";
- xml += " xs:schemaLocation='http://drools.org/drools-5.0/change-set drools-change-set-5.0.xsd' >";
- xml += " <add> ";
- xml += " <resource source='" + 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();
-
- KnowledgeAgentConfiguration aconf = KnowledgeAgentFactory.newKnowledgeAgentConfiguration();
- aconf.setProperty( "drools.agent.scanDirectories",
- "true" );
- aconf.setProperty( "drools.agent.newInstance",
- "true" );
+ String rule2 = "";
+ rule2 += "package org.drools.test\n";
+ rule2 += "global java.util.List list\n";
+ rule2 += "rule rule2\n";
+ rule2 += "when\n";
+ rule2 += "then\n";
+ rule2 += "list.add( drools.getRule().getName() );\n";
+ rule2 += "end\n";
+ File f2 = fileManager.newFile("rule2.drl");
+ output = new BufferedWriter(new FileWriter(f2));
+ output.write(rule2);
+ output.close();
- KnowledgeAgent kagent = KnowledgeAgentFactory.newKnowledgeAgent( "test agent",
- aconf );
- kagent.applyChangeSet( ResourceFactory.newUrlResource( fxml.toURI().toURL() ) );
+ String xml = "";
+ xml += "<change-set xmlns='http://drools.org/drools-5.0/change-set'";
+ xml += " xmlns:xs='http://www.w3.org/2001/XMLSchema-instance'";
+ xml += " xs:schemaLocation='http://drools.org/drools-5.0/change-set drools-change-set-5.0.xsd' >";
+ xml += " <add> ";
+ xml += " <resource source='"
+ + 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();
- Thread.sleep( 3000 ); // give it 2 seconds to detect and build the changes
- StatelessKnowledgeSession ksession = kagent.newStatelessKnowledgeSession();
-
- List list = new ArrayList();
- ksession.setGlobal( "list",
- list );
+ // KnowledgeBuilder kbuilder =
+ // KnowledgeBuilderFactory.newKnowledgeBuilder();
+ // kbuilder.add( ResourceFactory.newUrlResource( fxml.toURI().toURL() ),
+ // ResourceType.ChangeSet );
+ // assertFalse( kbuilder.hasErrors() );
- Action executeResultHandler = PipelineFactory.newExecuteResultHandler();
+ KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
+ // kbase.addKnowledgePackages( kbuilder.getKnowledgePackages() );
- Action assignResult = PipelineFactory.newAssignObjectAsResult();
- assignResult.setReceiver( executeResultHandler );
+ ResourceChangeScannerConfiguration sconf = ResourceFactory
+ .getResourceChangeScannerService()
+ .newResourceChangeScannerConfiguration();
+ sconf.setProperty("drools.resource.scanner.interval", "2");
+ ResourceFactory.getResourceChangeScannerService().configure(sconf);
- KnowledgeRuntimeCommand batchExecution = PipelineFactory.newCommandExecutor();
- batchExecution.setReceiver( assignResult );
+ KnowledgeAgentConfiguration aconf = KnowledgeAgentFactory
+ .newKnowledgeAgentConfiguration();
+ aconf.setProperty("drools.agent.scanDirectories", "true");
+ aconf.setProperty("drools.agent.newInstance", "true");
- KnowledgeRuntimeCommand insertStage = PipelineFactory.newInsertObjectCommand();
- insertStage.setReceiver( batchExecution );
+ KnowledgeAgent kagent = KnowledgeAgentFactory.newKnowledgeAgent(
+ "test agent", kbase, aconf);
+ kagent.applyChangeSet(ResourceFactory.newUrlResource(fxml.toURI()
+ .toURL()));
- Pipeline pipeline = PipelineFactory.newStatelessKnowledgeSessionPipeline( ksession );
- pipeline.setReceiver( insertStage );
+ Thread.sleep(3000); // give it 2 seconds to detect and build the changes
+ StatefulKnowledgeSession ksession = kagent.getKnowledgeBase()
+ .newStatefulKnowledgeSession();
+ List<String> list = new ArrayList<String>();
+ ksession.setGlobal("list", list);
+ ksession.fireAllRules();
+ ksession.dispose();
- ResultHandlerImpl resultHandler = new ResultHandlerImpl();
- pipeline.insert( "hello", resultHandler );
+ 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 );
- try {
- DroolsStreamUtils.streamOut( out,
- pkg );
- } finally {
- out.close();
- }
- }
-
- public static class ResultHandlerImpl implements ResultHandler {
- Object object;
-
- public void handleResult(Object object) {
- this.object = object;
- }
-
- public Object getObject() {
- return this.object;
- }
- }
-}
+ list.clear();
+ String rule3 = "";
+ rule3 += "package org.drools.test\n";
+ rule3 += "global java.util.List list\n";
+ rule3 += "rule rule3\n";
+ rule3 += "when\n";
+ rule3 += "then\n";
+ rule3 += "list.add( drools.getRule().getName() );\n";
+ rule3 += "end\n";
+ File f3 = fileManager.newFile("rule3.drl");
+ output = new BufferedWriter(new FileWriter(f3));
+ output.write(rule3);
+ output.close();
+
+ assertTrue(f1.delete());
+
+ Thread.sleep(3000);
+
+ ksession = kagent.getKnowledgeBase().newStatefulKnowledgeSession();
+ list = new ArrayList<String>();
+ ksession.setGlobal("list", list);
+ ksession.fireAllRules();
+ ksession.dispose();
+
+ assertEquals(2, list.size());
+ assertTrue(list.contains("rule2"));
+ assertTrue(list.contains("rule3"));
+
+ kagent.monitorResourceChangeEvents(false);
+ }
+
+ public void testModifyFileInDirectory() throws Exception {
+ // Create the test directory
+ File testDirectory = fileManager.newFile("test");
+ testDirectory.mkdir();
+
+ String rule1 = "";
+ rule1 += "package org.drools.test\n";
+ rule1 += "global java.util.List list\n";
+ rule1 += "rule rule1\n";
+ rule1 += "when\n";
+ rule1 += "then\n";
+ rule1 += "list.add( drools.getRule().getName() );\n";
+ rule1 += "end\n";
+ File f1 = fileManager.newFile(testDirectory, "rule1.drl");
+ Writer output = new BufferedWriter(new FileWriter(f1));
+ output.write(rule1);
+ output.close();
+
+ String rule2 = "";
+ rule2 += "package org.drools.test\n";
+ rule2 += "global java.util.List list\n";
+ rule2 += "rule rule2\n";
+ rule2 += "when\n";
+ rule2 += "then\n";
+ rule2 += "list.add( drools.getRule().getName() );\n";
+ rule2 += "end\n";
+ 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'";
+ xml += " xs:schemaLocation='http://drools.org/drools-5.0/change-set drools-change-set-5.0.xsd' >";
+ xml += " <add> ";
+ xml += " <resource source='file:"
+ + fileManager.getRootDirectory().getAbsolutePath()
+ + "/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();
+
+ KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
+
+ 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");
+ 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()));
+
+ StatefulKnowledgeSession ksession = kagent.getKnowledgeBase()
+ .newStatefulKnowledgeSession();
+ List<String> list = new ArrayList<String>();
+ ksession.setGlobal("list", list);
+ ksession.fireAllRules();
+ ksession.dispose();
+
+ 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
+ Thread.sleep(2000);
+
+ rule1 = "";
+ rule1 += "package org.drools.test\n";
+ rule1 += "global java.util.List list\n";
+ rule1 += "rule rule3\n";
+ rule1 += "when\n";
+ rule1 += "then\n";
+ rule1 += "list.add( drools.getRule().getName() );\n";
+ rule1 += "end\n";
+ output = new BufferedWriter(new FileWriter(f1));
+ output.write(rule1);
+ output.close();
+ Thread.sleep(3000);
+
+ ksession = kagent.getKnowledgeBase().newStatefulKnowledgeSession();
+ list = new ArrayList<String>();
+ ksession.setGlobal("list", list);
+ ksession.fireAllRules();
+ ksession.dispose();
+
+ assertEquals(2, list.size());
+
+ assertTrue(list.contains("rule3"));
+ assertTrue(list.contains("rule2"));
+ kagent.monitorResourceChangeEvents(false);
+ }
+
+ public void testStatelessWithPipeline() throws Exception {
+ String rule1 = "";
+ rule1 += "package org.drools.test\n";
+ rule1 += "global java.util.List list\n";
+ rule1 += "rule rule1\n";
+ rule1 += "when\n";
+ rule1 += "then\n";
+ rule1 += "list.add( drools.getRule().getName() );\n";
+ rule1 += "end\n";
+ File f1 = fileManager.newFile("rule1.drl");
+
+ Writer output = new BufferedWriter(new FileWriter(f1));
+ output.write(rule1);
+ output.close();
+
+ String rule2 = "";
+ rule2 += "package org.drools.test\n";
+ rule2 += "global java.util.List list\n";
+ rule2 += "rule rule2\n";
+ rule2 += "when\n";
+ rule2 += "then\n";
+ rule2 += "list.add( drools.getRule().getName() );\n";
+ rule2 += "end\n";
+ 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 drools-change-set-5.0.xsd' >";
+ xml += " <add> ";
+ xml += " <resource source='"
+ + 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();
+
+ KnowledgeAgentConfiguration aconf = KnowledgeAgentFactory
+ .newKnowledgeAgentConfiguration();
+ aconf.setProperty("drools.agent.scanDirectories", "true");
+ aconf.setProperty("drools.agent.newInstance", "true");
+
+ KnowledgeAgent kagent = KnowledgeAgentFactory.newKnowledgeAgent(
+ "test agent", aconf);
+ kagent.applyChangeSet(ResourceFactory.newUrlResource(fxml.toURI()
+ .toURL()));
+
+ Thread.sleep(3000); // give it 2 seconds to detect and build the changes
+ StatelessKnowledgeSession ksession = kagent
+ .newStatelessKnowledgeSession();
+
+ List<String> list = new ArrayList<String>();
+ ksession.setGlobal("list", list);
+
+ Action executeResultHandler = PipelineFactory.newExecuteResultHandler();
+
+ Action assignResult = PipelineFactory.newAssignObjectAsResult();
+ assignResult.setReceiver(executeResultHandler);
+
+ KnowledgeRuntimeCommand batchExecution = PipelineFactory
+ .newCommandExecutor();
+ batchExecution.setReceiver(assignResult);
+
+ KnowledgeRuntimeCommand insertStage = PipelineFactory
+ .newInsertObjectCommand();
+ insertStage.setReceiver(batchExecution);
+
+ Pipeline pipeline = PipelineFactory
+ .newStatelessKnowledgeSessionPipeline(ksession);
+ pipeline.setReceiver(insertStage);
+
+ ResultHandlerImpl resultHandler = new ResultHandlerImpl();
+ pipeline.insert("hello", resultHandler);
+
+ 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);
+ try {
+ DroolsStreamUtils.streamOut(out, pkg);
+ } finally {
+ out.close();
+ }
+ }
+
+ public static class ResultHandlerImpl implements ResultHandler {
+ Object object;
+
+ public void handleResult(Object object) {
+ this.object = object;
+ }
+
+ public Object getObject() {
+ return this.object;
+ }
+ }
+}
\ No newline at end of file
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 2009-12-09 06:02:19 UTC (rev 30562)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/agent/impl/KnowledgeAgentImpl.java 2009-12-09 13:29:15 UTC (rev 30563)
@@ -3,6 +3,7 @@
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
@@ -13,8 +14,8 @@
import org.drools.ChangeSet;
import org.drools.KnowledgeBase;
import org.drools.KnowledgeBaseFactory;
+import org.drools.RuleBase;
import org.drools.SystemEventListener;
-import org.drools.RuleBase;
import org.drools.SystemEventListenerFactory;
import org.drools.agent.KnowledgeAgent;
import org.drools.agent.KnowledgeAgentConfiguration;
@@ -46,541 +47,907 @@
import org.drools.xml.SemanticModules;
import org.drools.xml.XmlChangeSetReader;
-public class KnowledgeAgentImpl
- implements
- KnowledgeAgent,
- ResourceChangeListener {
- private String name;
- private Map<Resource, ResourceMapping> resources;
- private Set<Resource> resourceDirectories;
- private KnowledgeBase kbase;
- private ResourceChangeNotifierImpl notifier;
- private boolean newInstance;
- private SystemEventListener listener;
- private boolean scanDirectories;
- private LinkedBlockingQueue<ChangeSet> queue;
- private Thread thread;
- private ChangeSetNotificationDetector changeSetNotificationDetector;
- private SemanticModules semanticModules;
+/**
+ * Drools Implementation of the KnowledgeAgent interface. Implements itself as a
+ * ResourceChangeListener as well so it can act as an agent service to provide
+ * incremental of the KnowledgeBase which connects to this or entirely new
+ * rebuilds for new KnowledgeBases.
+ *
+ * @author Mark Proctor, Sam Romano
+ */
+public class KnowledgeAgentImpl implements KnowledgeAgent,
+ ResourceChangeListener {
- public KnowledgeAgentImpl(String name,
- KnowledgeBase kbase,
- KnowledgeAgentConfiguration configuration) {
- this.name = name;
- this.kbase = kbase;
- this.resources = new HashMap<Resource, ResourceMapping>();
- this.resourceDirectories = new HashSet<Resource>();
- //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() ) {
- monitor = true;
- }
+ private String name;
+ private ResourceMap resourcesMap;
+ private Set<Resource> resourceDirectories;
+ private KnowledgeBase kbase;
+ private ResourceChangeNotifierImpl notifier;
+ private boolean newInstance;
+ private SystemEventListener listener;
+ private boolean scanDirectories;
+ private LinkedBlockingQueue<ChangeSet> queue;
+ private Thread thread;
+ private ChangeSetNotificationDetector changeSetNotificationDetector;
+ private SemanticModules semanticModules;
- if ( ((KnowledgeAgentConfigurationImpl) configuration).isScanDirectories() ) {
- this.scanDirectories = true;
- }
+ /**
+ * Default constructor for KnowledgeAgentImpl
+ *
+ * @param name
+ * @param kbase
+ * @param configuration
+ */
+ public KnowledgeAgentImpl(String name, KnowledgeBase kbase,
+ KnowledgeAgentConfiguration configuration) {
+ this.name = name;
+ this.kbase = kbase;
+ this.resourcesMap = new ResourceMap(this);
+ this.resourceDirectories = new HashSet<Resource>();
+ // this.listener = listener;
+ this.listener = SystemEventListenerFactory.getSystemEventListener();
+ this.queue = new LinkedBlockingQueue<ChangeSet>();
+ boolean scanResources = false;
+ boolean monitor = false;
+ if (configuration != null) {
+ // New Instance describes if we do incremental builds or not
+ this.newInstance = ((KnowledgeAgentConfigurationImpl) configuration)
+ .isNewInstance();
+ this.notifier = (ResourceChangeNotifierImpl) ResourceFactory
+ .getResourceChangeNotifierService();
+ if (((KnowledgeAgentConfigurationImpl) configuration)
+ .isMonitorChangeSetEvents()) {
+ monitor = true;
+ }
- scanResources = ((KnowledgeAgentConfigurationImpl) configuration).isScanResources();
- if ( scanResources ) {
- this.notifier.addResourceChangeMonitor( ResourceFactory.getResourceChangeScannerService() );
- monitor = true; // if scanning, monitor must be true;
- }
- }
+ if (((KnowledgeAgentConfigurationImpl) configuration)
+ .isScanDirectories()) {
+ this.scanDirectories = true;
+ }
- monitorResourceChangeEvents( monitor );
+ scanResources = ((KnowledgeAgentConfigurationImpl) configuration)
+ .isScanResources();
+ if (scanResources) {
+ this.notifier.addResourceChangeMonitor(ResourceFactory
+ .getResourceChangeScannerService());
+ monitor = true; // if scanning, monitor must be true;
+ }
+ }
- //buildResourceMapping( kbase );
+ monitorResourceChangeEvents(monitor);
- this.listener.info( "KnowledgAgent created, with configuration:\nmonitorChangeSetEvents=" + monitor + " scanResources=" + scanResources + " scanDirectories=" + this.scanDirectories );
- }
+ buildResourceMapping();
- public void setSystemEventListener(SystemEventListener listener) {
- this.listener = listener;
- }
+ this.listener
+ .info("KnowledgeAgent created, with configuration:\nmonitorChangeSetEvents="
+ + monitor
+ + " scanResources="
+ + scanResources
+ + " scanDirectories="
+ + this.scanDirectories
+ + " newInstance=" + this.newInstance);
+ }
- public void applyChangeSet(Resource resource) {
- applyChangeSet( getChangeSet( resource ) );
- }
+ public void setSystemEventListener(SystemEventListener listener) {
+ this.listener = listener;
+ }
- public void applyChangeSet(ChangeSet changeSet) {
- synchronized ( this.resources ) {
- this.listener.info( "KnowledgAgent applying ChangeSet" );
- ChangeSetState changeSetState = new ChangeSetState();
- changeSetState.scanDirectories = this.scanDirectories;
- processChangeSet( changeSet,
- changeSetState );
-
- rebuildResources( changeSetState );
- }
- //buildResourceMapping( this.kbase );
- }
+ public void applyChangeSet(Resource resource) {
+ applyChangeSet(getChangeSet(resource));
+ }
- public void processChangeSet(Resource resource,
- ChangeSetState changeSetState) {
- processChangeSet( getChangeSet( resource ),
- changeSetState );
- }
+ public void applyChangeSet(ChangeSet changeSet) {
+ synchronized (this.resourcesMap) {
+ this.listener.info("KnowledgeAgent applying ChangeSet");
- public void processChangeSet(ChangeSet changeSet,
- ChangeSetState changeSetState) {
- synchronized ( this.resources ) {
-
- 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
- }
- ((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 ) {
- changeSetState.pkgs.add( resource );
- } else if ( ((InternalResource) resource).getResourceType() == ResourceType.CHANGE_SET ) {
- // @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 );
- }
- }
- }
-
- for ( Resource resource : changeSet.getResourcesRemoved() ) {
- if ( ((InternalResource) resource).getResourceType() == ResourceType.CHANGE_SET ) {
- 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 );
- }
- }
-
- // are we going to need kbuilder to build these resources?
- for ( Resource resource : this.resources.keySet() ) {
- this.listener.debug( "KnowledgeAgent ChangeSet requires KnowledgeBuilder" );
- if ( ((InternalResource) resource).getResourceType() != ResourceType.CHANGE_SET && ((InternalResource) resource).getResourceType() != ResourceType.PKG ) {
- changeSetState.needsKnowledgeBuilder = true;
- break;
- }
- }
- }
+ ChangeSetState changeSetState = new ChangeSetState();
+ changeSetState.scanDirectories = this.scanDirectories;
+ // incremental build is inverse of newInstance
+ changeSetState.incrementalBuild = !(this.newInstance);
- }
+ // Process the new ChangeSet
+ processChangeSet(changeSet, changeSetState);
+ // Rebuild or do an update to the KnowledgeBase
+ buildKnowledgeBase(changeSetState);
+ // Rebuild the resource mapping
+ buildResourceMapping();
+ }
+ }
- public ChangeSet getChangeSet(Resource resource) {
- if ( this.semanticModules == null ) {
- this.semanticModules = new SemanticModules();
- this.semanticModules.addSemanticModule( new ChangeSetSemanticModule() );
- }
+ public void processChangeSet(Resource resource,
+ ChangeSetState changeSetState) {
+ processChangeSet(getChangeSet(resource), changeSetState);
+ }
- XmlChangeSetReader reader = new XmlChangeSetReader( this.semanticModules );
- if ( resource instanceof ClassPathResource ) {
- reader.setClassLoader( ((ClassPathResource) resource).getClassLoader() );
- } else {
- reader.setClassLoader( ((AbstractRuleBase) (((KnowledgeBaseImpl) this.kbase).ruleBase)).getConfiguration().getClassLoader() );
- }
+ public void processChangeSet(ChangeSet changeSet,
+ ChangeSetState changeSetState) {
+ synchronized (this.resourcesMap) {
+ /*
+ * Process the added resources from a ChangeSet by subscribing to
+ * the notifier and inserting a new ResourceMapping.
+ */
+ for (Resource resource : changeSet.getResourcesAdded()) {
+ 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);
+ // if it's a dir, subscribe it's children first
+ for (Resource child : ((InternalResource) resource)
+ .listResources()) {
- ChangeSet changeSet = null;
- try {
- 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" ) );
- }
- return changeSet;
- }
+ // ignore sub directories
+ if (((InternalResource) child).isDirectory()) {
+ continue;
+ }
- public static class ChangeSetState {
- List<Resource> pkgs = new ArrayList<Resource>();
- boolean scanDirectories;
- boolean needsKnowledgeBuilder;
- }
+ ((InternalResource) child)
+ .setResourceType(((InternalResource) resource)
+ .getResourceType());
+ if (this.resourcesMap.addResourceMapping(child, true)
+ && changeSetState.incrementalBuild) {
+ changeSetState.addedResources.add(child);
+ }
+ }
+ } else {
+ if (this.resourcesMap.addResourceMapping(resource, true)
+ && changeSetState.incrementalBuild) {
+ changeSetState.addedResources.add(resource);
+ }
+ }
+ }
- /**
- * This indexes the rules and flows against their respective urls, to allow more fine grained removal and not just removing of an entire package
- * @param kbase
- */
- public void buildResourceMapping(KnowledgeBase kbase) {
- RuleBase rbase = ((KnowledgeBaseImpl) kbase).ruleBase;
- this.listener.debug( "KnowledgeAgent building resource map" );
- synchronized ( this.resources ) {
+ /*
+ * For those marked as removed by the ChangeSet, remove their
+ * mappings, index them if we are doing incremental builds so the
+ * incremental building process knows what to remove.
+ */
+ for (Resource resource : changeSet.getResourcesRemoved()) {
+ 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);
+ } else {
+ ResourceMapEntry removedEntry = this.resourcesMap
+ .removeResourceMapping(resource, true);
- for ( Package pkg : rbase.getPackages() ) {
- for ( Rule rule : pkg.getRules() ) {
- Resource resource = rule.getResource();
- if ( resource == null || !((InternalResource) resource).hasURL() ) {
- continue;
- }
- ResourceMapping mapping = this.resources.get( resource );
- if ( mapping == null ) {
- this.notifier.subscribeResourceChangeListener( this,
- resource );
- mapping = new ResourceMapping( resource );
- this.resources.put( resource,
- mapping );
- }
- this.listener.debug( "KnowledgeAgent mapping resource=" + resource + " to rule=" + rule );
- mapping.getKnowledgeDefinitions().add( rule );
- }
+ if (removedEntry != null && changeSetState.incrementalBuild) {
+ changeSetState.removedResourceMappings
+ .add(removedEntry);
+ }
+ }
+ }
- for ( Process process : pkg.getRuleFlows().values() ) {
- Resource resource = ((org.drools.process.core.Process) process).getResource();
- if ( resource == null || !((InternalResource) resource).hasURL() ) {
- continue;
- }
- ResourceMapping mapping = this.resources.get( resource );
- if ( mapping == null ) {
- this.notifier.subscribeResourceChangeListener( this,
- resource );
- mapping = new ResourceMapping( resource );
- this.resources.put( resource,
- mapping );
- }
- this.listener.debug( "KnowledgeAgent mapping resource=" + resource + " to process=" + process );
- mapping.getKnowledgeDefinitions().add( process );
- }
+ /*
+ * For those marked as modified, remove their ResourceMapping,
+ * attach it to the ChangeSetState, and add a new one - it will be
+ * repopulated with the KnowledgeDefinitions later after rebuilding.
+ * Process any modified ChangeSets - treat them as if they were new.
+ */
+ for (Resource resource : changeSet.getResourcesModified()) {
+ 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);
+ }
+ // if it's a dir, subscribe it's children first
+ for (Resource child : ((InternalResource) resource)
+ .listResources()) {
- for ( TypeDeclaration typeDeclaration : pkg.getTypeDeclarations().values() ) {
- Resource resource = typeDeclaration.getResource();
- if ( resource == null || !((InternalResource) resource).hasURL() ) {
- continue;
- }
- ResourceMapping mapping = this.resources.get( resource );
- if ( mapping == null ) {
- this.notifier.subscribeResourceChangeListener( this,
- resource );
- mapping = new ResourceMapping( resource );
- this.resources.put( resource,
- mapping );
- }
- this.listener.debug( "KnowledgeAgent mapping resource=" + resource + " to TypeDeclaration=" + typeDeclaration );
- mapping.getKnowledgeDefinitions().add( typeDeclaration );
- }
+ // ignore sub directories
+ if (((InternalResource) child).isDirectory()) {
+ continue;
+ }
- for ( Function function : pkg.getFunctions().values() ) {
- Resource resource = function.getResource();
- if ( resource == null || !((InternalResource) resource).hasURL() ) {
- continue;
- }
- ResourceMapping mapping = this.resources.get( resource );
- if ( mapping == null ) {
- this.notifier.subscribeResourceChangeListener( this,
- resource );
- mapping = new ResourceMapping( resource );
- this.resources.put( resource,
- mapping );
- }
- this.listener.debug( "KnowledgeAgent mapping resource=" + resource + " to function=" + function );
- mapping.getKnowledgeDefinitions().add( function );
- }
- }
- }
- }
+ if (this.resourcesMap.addResourceMapping(child, true)) {
+ ((InternalResource) child)
+ .setResourceType(((InternalResource) resource)
+ .getResourceType());
+ if (changeSetState.incrementalBuild) {
+ changeSetState.addedResources.add(child);
+ }
+ }
+ }
+ } else {
+ ResourceMapEntry modifiedMapping = this.resourcesMap
+ .removeResourceMapping(resource, false);
+ if (modifiedMapping == null) {
+ this.listener
+ .warning("KnowledgeAgent subscribing to new resource="
+ + resource
+ + ", though it was marked as modified.");
+ this.resourcesMap.addResourceMapping(resource, true);
+ if (changeSetState.incrementalBuild) {
+ changeSetState.addedResources.add(resource);
+ }
+ } else {
+ /*
+ * Put a new one, but no need to subscribe or update
+ * since this will be done in the buildResourceMapping
+ * later
+ */
+ this.resourcesMap.addResourceMapping(resource, false);
+ if (changeSetState.incrementalBuild) {
+ changeSetState.modifiedResourceMappings
+ .add(modifiedMapping);
+ }
+ }
+ }
+ }
+ }
+ }
- public KnowledgeBase getKnowledgeBase() {
- synchronized ( this.resources ) {
- return this.kbase;
- }
- }
+ /**
+ * Returns a ChangeSet based on a resource with a resource type of
+ * ChangeSet.
+ *
+ * @param resource
+ * A resource with the type set to ChangeSet
+ * @return A ChangeSet that can be processed by this Agent.
+ */
+ public ChangeSet getChangeSet(Resource resource) {
+ if (this.semanticModules == null) {
+ this.semanticModules = new SemanticModules();
+ this.semanticModules
+ .addSemanticModule(new ChangeSetSemanticModule());
+ }
- public StatelessKnowledgeSession newStatelessKnowledgeSession() {
- return new StatelessKnowledgeSessionImpl( null, this, null );
- }
+ XmlChangeSetReader reader = new XmlChangeSetReader(this.semanticModules);
+ if (resource instanceof ClassPathResource) {
+ reader.setClassLoader(((ClassPathResource) resource)
+ .getClassLoader());
+ } else {
+ reader
+ .setClassLoader(((AbstractRuleBase) (((KnowledgeBaseImpl) this.kbase).ruleBase))
+ .getConfiguration().getClassLoader());
+ }
- public StatelessKnowledgeSession newStatelessKnowledgeSession(KnowledgeSessionConfiguration conf) {
- return new StatelessKnowledgeSessionImpl( null, this, conf );
- }
-
- // public void resourceModified(ResourceModifiedEvent event) {
- // ResourceMapping mapping = this.resources.get( event.getResource() );
- // System.out.println( "modified : " + event.getResource() );
- // KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
- // synchronized ( this.resources ) {
- // for ( Resource resource : this.resources.keySet() ) {
- // System.out.println( "building : " + resource );
- // kbuilder.add( resource,
- // KnowledgeType.DRL );
- // }
- //
- // this.kbase = KnowledgeBaseFactory.newKnowledgeBase();
- // this.kbase.addKnowledgePackages( kbuilder.getKnowledgePackages() );
- // }
- // }
+ ChangeSet changeSet = null;
+ try {
+ 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"));
+ }
+ return changeSet;
+ }
- 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 ) );
- }
- }
+ /**
+ * Keeps state information during the 'state' of a ChangeSet alteration so
+ * past information can be kept along the way.
+ *
+ * @author Mark Proctor
+ */
+ public static class ChangeSetState {
+ List<Resource> addedResources = new ArrayList<Resource>();
+ List<ResourceMapEntry> removedResourceMappings = new ArrayList<ResourceMapEntry>();
+ List<ResourceMapEntry> modifiedResourceMappings = new ArrayList<ResourceMapEntry>();
+ boolean scanDirectories;
+ boolean incrementalBuild;
+ }
- private void rebuildResources(ChangeSetState changeSetState) {
- this.listener.debug( "KnowledgeAgent rebuilding KnowledgeBase using ChangeSet" );
- synchronized ( this.resources ) {
- // modified we already know is in the map, so no need to process those
+ /**
+ * This indexes the rules, flows, type declarations, etc against their
+ * respective URLs if they have any, to allow more fine grained removal and
+ * not just removing of an entire package
+ */
+ public void buildResourceMapping() {
+ this.listener.debug("KnowledgeAgent building resource map");
+ synchronized (this.resourcesMap) {
+ RuleBase rbase = ((KnowledgeBaseImpl) this.kbase).ruleBase;
+ /*
+ * Iterate each package for the different types of
+ * KnowledgeDefinitions we want to track
+ */
+ for (Package pkg : rbase.getPackages()) {
+ for (Rule rule : pkg.getRules()) {
+ Resource resource = rule.getResource();
+ if (resource == null
+ || !((InternalResource) resource).hasURL()) {
+ this.listener
+ .debug("KnowledgeAgent no resource mapped for rule="
+ + rule);
+ continue;
+ }
+ this.resourcesMap.putResourceMappingEntry(resource, rule);
+ }
- // // now make a copy of the resource keys, as we are about to reset it, but need the keys to rebuild the kbase
- // Resource[] resourcesClone = this.resources.keySet().toArray( new Resource[this.resources.size()] );
- //
- // // reset the resources map, so it can now be rebuilt
- // this.resources.clear();
+ for (Process process : pkg.getRuleFlows().values()) {
+ Resource resource = ((org.drools.process.core.Process) process)
+ .getResource();
+ if (resource == null
+ || !((InternalResource) resource).hasURL()) {
+ this.listener
+ .debug("KnowledgeAgent no resource mapped for process="
+ + process);
+ continue;
+ }
+ this.resourcesMap
+ .putResourceMappingEntry(resource, process);
+ }
- if ( this.kbase != null ) {
- // re-use the KnowledgeBaseConfiguration if possible
- this.kbase = KnowledgeBaseFactory.newKnowledgeBase( ((InternalRuleBase) ((KnowledgeBaseImpl) this.kbase).ruleBase).getConfiguration() );
- } else {
- this.kbase = KnowledgeBaseFactory.newKnowledgeBase();
- }
+ for (TypeDeclaration typeDeclaration : pkg
+ .getTypeDeclarations().values()) {
+ Resource resource = typeDeclaration.getResource();
+ if (resource == null
+ || !((InternalResource) resource).hasURL()) {
+ this.listener
+ .debug("KnowledgeAgent no resource mapped for typeDeclaration="
+ + typeDeclaration);
+ continue;
+ }
+ this.resourcesMap.putResourceMappingEntry(resource,
+ typeDeclaration);
+ }
- if ( changeSetState.needsKnowledgeBuilder ) {
+ for (Function function : pkg.getFunctions().values()) {
+ Resource resource = function.getResource();
+ if (resource == null
+ || !((InternalResource) resource).hasURL()) {
+ this.listener
+ .debug("KnowledgeAgent no resource mapped for function="
+ + function);
+ continue;
+ }
+ this.resourcesMap.putResourceMappingEntry(resource,
+ function);
+ }
+ }
+ }
+ }
- // rebuild the kbase
- KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
+ public KnowledgeBase getKnowledgeBase() {
+ synchronized (this.resourcesMap) {
+ return this.kbase;
+ }
+ }
- for ( Resource resource : this.resources.keySet() ) {
- if ( ((InternalResource) resource).getResourceType() != ResourceType.PKG ) {
- // .pks are handled as a special case.
- if ( ((InternalResource) resource).getConfiguration() == null ) {
- kbuilder.add( resource,
- ((InternalResource) resource).getResourceType() );
- } else {
- kbuilder.add( resource,
- ((InternalResource) resource).getResourceType(),
- ((InternalResource) resource).getConfiguration() );
- }
- this.listener.debug( "KnowledgeAgent building resource=" + resource );
- }
- }
+ public StatelessKnowledgeSession newStatelessKnowledgeSession() {
+ return new StatelessKnowledgeSessionImpl(null, this, null);
+ }
- if ( kbuilder.hasErrors() ) {
- this.listener.warning( "KnowledgeAgent has KnowledgeBuilder errors ",
- kbuilder.getErrors() );
- }
+ public StatelessKnowledgeSession newStatelessKnowledgeSession(
+ KnowledgeSessionConfiguration conf) {
+ return new StatelessKnowledgeSessionImpl(null, this, conf);
+ }
- this.kbase.addKnowledgePackages( kbuilder.getKnowledgePackages() );
- }
+ 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));
+ }
+ }
- for ( Resource resource : this.resources.keySet() ) {
+ /**
+ * Rebuilds and creates a new KnowledgeBase for this KnowledgeAgent when
+ * called based on the ChangeSet that comes in and if newInstance is set to
+ * true. If incremental building or KnowledgeBase updates is on, then this
+ * will attempt to update the KnowledgeBase instead.
+ *
+ * @param changeSetState
+ * The state that the ChangeSet performed
+ */
+ public void buildKnowledgeBase(ChangeSetState changeSetState) {
+ this.listener
+ .debug("KnowledgeAgent rebuilding KnowledgeBase using ChangeSet");
+ synchronized (this.resourcesMap) {
- if ( ((InternalResource) resource).getResourceType() == ResourceType.PKG ) {
- this.listener.debug( "KnowledgeAgent building resource=" + resource );
+ /*
+ * Do the following only if we are building a new instance,
+ * otherwise, do an incremental build/update
+ */
+ if (this.newInstance) {
+ rebuildResources(changeSetState);
+ } else {
+ incrementalBuildResources(changeSetState);
+ }
- InputStream is = null;
- try {
- // .pks are handled as a special case.
- is = resource.getInputStream();
- Object object = DroolsStreamUtils.streamIn( is );
- Package pkg = null;
- if ( object instanceof KnowledgePackage ) {
- pkg = ((KnowledgePackageImp) object).pkg;
- } else {
- pkg = (Package) object;
- }
- this.listener.debug( "KnowledgeAgent adding KnowledgeDefinitionsPackage " + pkg.getName() );
- ((KnowledgeBaseImpl) this.kbase).ruleBase.addPackage( pkg );
- } catch ( Exception e ) {
- this.listener.exception( new RuntimeException( "KnowledgeAgent exception while trying to deserialize KnowledgeDefinitionsPackage ", e ) );
- } finally {
- try {
- is.close();
- } catch ( IOException e ) {
- this.listener.exception( new RuntimeException( "KnowledgeAgent exception while trying to close KnowledgeDefinitionsPackage ", e ) );
- }
- }
- }
- }
-
- InternalRuleBase ruleBase = ( InternalRuleBase ) ((KnowledgeBaseImpl)this.kbase).ruleBase;
- synchronized ( ruleBase.getPackagesMap() ) {
- if ( ruleBase.getConfiguration().isSequential() ) {
- ruleBase.getReteooBuilder().order();
- }
- }
+ /*
+ * If the ruleBase is sequential, after rebuilding or incremental
+ * update, do an ordering of the ReteooBuilder
+ */
+ InternalRuleBase ruleBase = (InternalRuleBase) ((KnowledgeBaseImpl) this.kbase).ruleBase;
+ synchronized (ruleBase.getPackagesMap()) {
+ if (ruleBase.getConfiguration().isSequential()) {
+ ruleBase.getReteooBuilder().order();
+ }
+ }
+ }
+ this.listener
+ .debug("KnowledgeAgent finished rebuilding KnowledgeBase using ChangeSet");
+ }
- // for ( Resource child : changeSetState.pkgs ) {
- // try {
- // this.listener.debug( "child : " + ((InternalResource) child).getLastRead() + " : " + ((InternalResource) child).getLastModified() );
- // InputStream is = child.getInputStream();
- // Object object = DroolsStreamUtils.streamIn( is );
- // Package pkg = null;
- // if ( object instanceof KnowledgePackage ) {
- // pkg = ((KnowledgePackageImp)object).pkg;
- // } else {
- // pkg = ( Package ) pkg;
- // }
- // this.listener.debug( "KnowledgeAgent adding KnowledgeDefinitionsPackage " + pkg.getName() );
- // ((KnowledgeBaseImpl) this.kbase).ruleBase.addPackage( pkg );
- // is.close();
- // } catch ( Exception e ) {
- // this.listener.exception( new RuntimeException( "KnowledgeAgent exception while trying to serialize and KnowledgeDefinitionsPackage " ) );
- // }
- // }
+ /**
+ * This method is meant to rebuild the entire KnowledgeBase. Cached
+ * references outside of this Agent will no longer be valid to the current
+ * KnowledgeBase
+ *
+ * @param changeSetState
+ * The ChangeSetState
+ */
+ private void rebuildResources(ChangeSetState changeSetState) {
- this.listener.info( "KnowledgeAgent new KnowledgeBase now built and in use" );
- }
+ if (!this.newInstance) {
+ listener
+ .warning("KnowledgeAgent rebuilding KnowledgeBase when newInstance is false");
+ }
- // code commented out to try and do incremental kbase changes
- // @TODO get this working for incremental changes
- // synchronized ( this.resources ) {
- // // first deal with removals
- // for ( Resource resource : changeSet.getResourcesRemoved() ) {
- // ResourceMapping mapping = this.resources.remove(resource );
- // if ( !this.newInstance ) {
- // // we are keeping the current instance, so we need remove the individual knowledge definitions
- // for ( KnowledgeDefinition kd : mapping.getKnowledgeDefinitions() ) {
- // if ( kd instanceof Rule ) {
- // Rule rule = ( Rule ) kd;
- // this.kbase.removeRule( rule.getPackageName(), rule.getName() );
- // } else if ( kd instanceof Process ) {
- // Process process = ( Process ) kd;
- // this.kbase.removeProcess( process.getId() );
- // }
- // // @TODO functions and type declarations
- // }
- // }
- // }
- //
- // // now deal with additions
- // for ( Resource resource : changeSet.getResourcesAdded() ) {
- //
- // }
- //
- // // final deal with modifies
- // }
- }
+ /*
+ * 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());
+ } else {
+ this.kbase = KnowledgeBaseFactory.newKnowledgeBase();
+ }
- public String getName() {
- return this.name;
- }
+ addResourcesToKnowledgeBase(resourcesMap.getAllResources());
- public void monitorResourceChangeEvents(boolean monitor) {
-
- 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 ) {
- this.changeSetNotificationDetector = new ChangeSetNotificationDetector( this,
- this.queue,
- this.listener );
- this.thread = new Thread( this.changeSetNotificationDetector );
- this.thread.start();
- }
+ this.listener
+ .info("KnowledgeAgent new KnowledgeBase now built and in use");
+ }
- }
+ /**
+ * This method is meant to incrementally build or update the current
+ * KnowledgeBase.
+ *
+ * @param changeSet
+ * @param changeSetState
+ */
+ private void incrementalBuildResources(ChangeSetState changeSetState) {
+ if (this.newInstance) {
+ this.listener
+ .warning("KnowledgeAgent incremental build of KnowledgeBase when newInstance is true");
+ }
+ // Incrementally rebuild the resources
+ synchronized (this.resourcesMap) {
+ this.listener
+ .info("KnowledgeAgent performing an incremental build of the ChangeSet");
- public static class ChangeSetNotificationDetector
- implements
- Runnable {
- private LinkedBlockingQueue<ChangeSet> queue;
- private volatile boolean monitor;
- private KnowledgeAgentImpl kagent;
- private SystemEventListener listener;
+ // Create the knowledge base if one does not exist
+ if (this.kbase == null) {
+ this.kbase = KnowledgeBaseFactory.newKnowledgeBase();
+ }
- public ChangeSetNotificationDetector(KnowledgeAgentImpl kagent,
- LinkedBlockingQueue<ChangeSet> queue,
- SystemEventListener listener) {
- this.queue = queue;
- this.kagent = kagent;
- this.listener = listener;
- this.monitor = true;
- }
-
- public void stop() {
- this.monitor = false;
- }
+ // Remove all rules from the resources removed and also those
+ // modified
+ for (ResourceMapEntry resourceMapEntry : changeSetState.removedResourceMappings) {
+ for (KnowledgeDefinition kd : resourceMapEntry
+ .getKnowledgeDefinitions()) {
+ removeKnowledgeDefinitionFromBase(kd);
+ }
+ }
- public void run() {
- if ( this.monitor ) {
- this.listener.info( "KnowledegAgent has started listening for ChangeSet notifications" );
- }
- while ( this.monitor ) {
- Exception exception = null;
- try {
- 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 ) );
- }
- }
+ for (ResourceMapEntry resourceMapEntry : changeSetState.modifiedResourceMappings) {
+ for (KnowledgeDefinition kd : resourceMapEntry
+ .getKnowledgeDefinitions()) {
+ removeKnowledgeDefinitionFromBase(kd);
+ }
+ changeSetState.addedResources.add(resourceMapEntry
+ .getResource());
+ }
- this.listener.info( "KnowledegAgent has stopped listening for ChangeSet notifications" );
- }
- }
+ /*
+ * Adds both the newly added resources and the modified resources
+ */
+ addResourcesToKnowledgeBase(changeSetState.addedResources);
+ }
+ this.listener
+ .info("KnowledgeAgent incremental build of KnowledgeBase finished and in use");
+ }
- public static class ResourceMapping {
- private Resource resource;
- private Set<KnowledgeDefinition> knowledgeDefinitions;
+ /**
+ *
+ * @param kd
+ */
+ private void removeKnowledgeDefinitionFromBase(KnowledgeDefinition kd) {
+ 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) {
+ Process process = (Process) kd;
+ 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) {
+ // @TODO functions and type declarations
+ }
+ }
- public ResourceMapping(Resource resource) {
- this.knowledgeDefinitions = new HashSet<KnowledgeDefinition>();
- }
+ /**
+ * Adds the resources to the current KnowledgeBase on this KnowledgeAgent.
+ * Only uses the KnowledgeBuilder when necessary.
+ *
+ * @param resources
+ */
+ private void addResourcesToKnowledgeBase(Collection<Resource> resources) {
- public Resource getResource() {
- return resource;
- }
+ KnowledgeBuilder kbuilder = null;
+ List<Package> packages = new ArrayList<Package>();
+ for (Resource resource : resources) {
+ /*
+ * If it's not a PKG, clearly we need the knowledge builder, so
+ * build it
+ */
+ if (((InternalResource) resource).getResourceType() != ResourceType.PKG) {
+ this.listener.debug("KnowledgeAgent building resource="
+ + resource);
+ if (kbuilder == null) {
+ kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
+ }
+ kbuilder.add(resource, ((InternalResource) resource)
+ .getResourceType());
+ } else {
+ // For PKG (.pks) just add them
+ this.listener.debug("KnowledgeAgent obtaining pkg resource="
+ + resource);
- public Set<KnowledgeDefinition> getKnowledgeDefinitions() {
- return knowledgeDefinitions;
- }
+ InputStream is = null;
+ try {
+ // .pks are handled as a special case.
+ is = resource.getInputStream();
+ Object object = DroolsStreamUtils.streamIn(is);
+ Package pkg = null;
+ if (object instanceof KnowledgePackage) {
+ pkg = ((KnowledgePackageImp) object).pkg;
- }
+ } else {
+ pkg = (Package) object;
+ }
+ for (Rule rule : pkg.getRules()) {
+ rule.setResource(resource);
+ }
- @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
- if ( this.changeSetNotificationDetector != null ) {
- this.changeSetNotificationDetector.monitor = false;
- }
- }
+ packages.add(pkg);
+ } catch (Exception e) {
+ this.listener
+ .exception(new RuntimeException(
+ "KnowledgeAgent exception while trying to deserialize KnowledgeDefinitionsPackage ",
+ e));
+ } finally {
+ try {
+ if (is != null) {
+ is.close();
+ }
+ } catch (IOException e) {
+ this.listener
+ .exception(new RuntimeException(
+ "KnowledgeAgent exception while trying to close 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());
+ }
+ /*
+ * 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);
+ }
+ }
-}
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.drools.agent.KnowledgeAgent#getName()
+ */
+ public String getName() {
+ return this.name;
+ }
+
+ /**
+ * Kicks off the monitoring service for handling ResourceChangeEvents on a
+ * separate process.
+ *
+ * @boolean monitor True if monitoring should take place, false otherwise
+ */
+ public void monitorResourceChangeEvents(boolean monitor) {
+ 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) {
+ this.changeSetNotificationDetector = new ChangeSetNotificationDetector(
+ this, this.queue, this.listener);
+ this.thread = new Thread(this.changeSetNotificationDetector);
+ this.thread.start();
+ }
+ }
+
+ /**
+ * A class to monitor and handle ChangeSets fired by the
+ * ResourceChangeNotifier on a separate service (or process).
+ *
+ * @author Mark Proctor
+ */
+ public static class ChangeSetNotificationDetector implements Runnable {
+ private LinkedBlockingQueue<ChangeSet> queue;
+ private 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;
+ this.monitor = true;
+ }
+
+ public void stop() {
+ this.monitor = false;
+ }
+
+ public void run() {
+ if (this.monitor) {
+ this.listener
+ .info("KnowledegAgent has started listening for ChangeSet notifications");
+ }
+ while (this.monitor) {
+ Exception exception = null;
+ try {
+ 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));
+ }
+ }
+
+ this.listener
+ .info("KnowledegAgent has stopped listening for ChangeSet notifications");
+ }
+ }
+
+ /**
+ * Maps a set of KnowledgeDefinitions to the resource that created them so
+ * we can perform incremental building of a KnowledgeBase.
+ *
+ * @author Mark Proctor
+ */
+ public static class ResourceMapEntry {
+ private final Resource resource;
+ private Set<KnowledgeDefinition> knowledgeDefinitions;
+
+ public ResourceMapEntry(Resource resource) {
+ this.resource = resource;
+ this.knowledgeDefinitions = new HashSet<KnowledgeDefinition>();
+ }
+
+ public Resource getResource() {
+ return resource;
+ }
+
+ public Set<KnowledgeDefinition> getKnowledgeDefinitions() {
+ return knowledgeDefinitions;
+ }
+ }
+
+ /**
+ * A Bidirectional map of Resources to KnowledgeDefinitions.This allows you
+ * to go both ways due to a KnowledgeDefinition being able to be overwritten
+ * by multiple resources, and we only want to track the Resource responsible
+ * as tagged by the KnowledgeBase for creating that resource.
+ *
+ * @author Sam Romano
+ */
+ public static class ResourceMap {
+ private final KnowledgeAgentImpl agent;
+ private Map<Resource, ResourceMapEntry> resourceMappings;
+ private Map<KnowledgeDefinition, Resource> knowledgeDefinitionMappings;
+
+ public ResourceMap(KnowledgeAgentImpl agent) {
+ this.agent = agent;
+ this.resourceMappings = new HashMap<Resource, ResourceMapEntry>();
+ this.knowledgeDefinitionMappings = new HashMap<KnowledgeDefinition, Resource>();
+ }
+
+ /**
+ * @param resource
+ * The resource to add to the Map
+ * @param notify
+ * True if you want to notify the listener, false otherwise.
+ * @return True if it was added, false otherwise.
+ */
+ public boolean addResourceMapping(Resource resource, boolean notify) {
+ ResourceMapEntry rsrcMapping = this.resourceMappings.get(resource);
+ if (rsrcMapping == null) {
+ rsrcMapping = new ResourceMapEntry(resource);
+ this.resourceMappings.put(resource, rsrcMapping);
+ if (notify) {
+ this.agent.listener
+ .debug("KnowledgeAgent notifier subscribing to resource="
+ + resource);
+
+ this.agent.notifier.subscribeResourceChangeListener(agent,
+ resource);
+ }
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Returns the old ResourceMapping mapped to the Resource. If it finds a
+ * resource mapping, it will unsubscribe from the
+ * ResourceChangeListener.
+ *
+ * @param resource
+ * @param unsubscribe
+ * True if you want to unsubscribe on a successful removal,
+ * false otherwise... normally false on attempting to remove
+ * entries for Modifications
+ * @return The old resourceMapping with the KnowledgeDefinitions that it
+ * use to have
+ */
+ public ResourceMapEntry removeResourceMapping(Resource resource,
+ boolean unsubscribe) {
+ this.agent.listener
+ .debug("KnowledgeAgent removing mappings for resource="
+ + resource + " with unsubscribe=" + unsubscribe);
+ ResourceMapEntry rsrcMapping = this.resourceMappings
+ .remove(resource);
+ if (rsrcMapping != null) {
+ if (unsubscribe) {
+ this.agent.listener
+ .debug("KnowledgeAgent notifier unsubscribing to resource="
+ + resource);
+ this.agent.notifier.unsubscribeResourceChangeListener(
+ agent, resource);
+ }
+
+ for (KnowledgeDefinition kd : rsrcMapping.knowledgeDefinitions) {
+ this.knowledgeDefinitionMappings.remove(kd);
+ }
+ }
+ return rsrcMapping;
+ }
+
+ public Set<Resource> getAllResources() {
+ return this.resourceMappings.keySet();
+ }
+
+ /**
+ * Maps a resource to the knowledge Definition, and vice versa for
+ * bidirectional mapping and integrity. If the resource is not mapped at
+ * all, this will subscribe the agent specified to this ResourceMap to
+ * listen for those changes.
+ *
+ * @param resource
+ * @param kd
+ * @return The old resource the KnowledgeDefinition use to be mapped to
+ * if it was
+ */
+ public Resource putResourceMappingEntry(Resource resource,
+ KnowledgeDefinition kd) {
+ ResourceMapEntry rsrcMapping = this.resourceMappings.get(resource);
+ if (rsrcMapping == null) {
+ addResourceMapping(resource, true);
+ rsrcMapping = this.resourceMappings.get(resource);
+ }
+ /*
+ * If adding this returns true, then we need to map it the other
+ * way, otherwise don't bother with the bidirectional logic and
+ * waste time - essentially we know we mapped it before.
+ */
+ if (rsrcMapping.knowledgeDefinitions.add(kd)) {
+ this.agent.listener.debug("KnowledgeAgent mapping resource="
+ + resource + " to KnowledgeDefinition=" + kd);
+
+ Resource oldRsrc = this.knowledgeDefinitionMappings.put(kd,
+ resource);
+ /*
+ * If an oldRsrc exists, make sure we remove the kd from that
+ * mapping - but dont unsubscribe from it as the resource is
+ * still being compiled in the KnowledgeBase, we need to know of
+ * its updates
+ */
+ ResourceMapEntry oldRsrcMapping = this.resourceMappings
+ .get(oldRsrc);
+ if (oldRsrcMapping != null) {
+ this.agent.listener
+ .debug("KnowledgeAgent removing reference from resource="
+ + oldRsrc + " to KnowledgeDefinition=" + kd);
+ oldRsrcMapping.getKnowledgeDefinitions().remove(kd);
+ }
+
+ return oldRsrc;
+ }
+ return null;
+ }
+
+ public boolean removeResourceMappingEntry(Resource resource,
+ KnowledgeDefinition kd) {
+ ResourceMapEntry rsrcMapping = this.resourceMappings.get(resource);
+ if (rsrcMapping != null) {
+ /*
+ * If the above didn't remove the kd, then we don't do the
+ * bidirectional removal
+ */
+ if (rsrcMapping.getKnowledgeDefinitions().remove(kd)) {
+ this.knowledgeDefinitionMappings.remove(kd);
+ return true;
+ }
+ }
+ return false;
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.lang.Object#finalize()
+ */
+ @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
+ if (this.changeSetNotificationDetector != null) {
+ this.changeSetNotificationDetector.monitor = false;
+ }
+ }
+
+}
\ No newline at end of file
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 2009-12-09 06:02:19 UTC (rev 30562)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/io/impl/ResourceChangeScannerImpl.java 2009-12-09 13:29:15 UTC (rev 30563)
@@ -18,278 +18,314 @@
import org.drools.io.ResourceChangeScanner;
import org.drools.io.ResourceChangeScannerConfiguration;
-public class ResourceChangeScannerImpl
- implements
- ResourceChangeScanner {
+public class ResourceChangeScannerImpl implements ResourceChangeScanner {
- private Map<Resource, Set<ResourceChangeNotifier>> resources;
- private Set<Resource> directories;
- private SystemEventListener listener;
- private int interval;
+ private Map<Resource, Set<ResourceChangeNotifier>> resources;
+ private Set<Resource> directories;
+ private SystemEventListener listener;
+ private int interval;
- public ResourceChangeScannerImpl() {
- this.listener = SystemEventListenerFactory.getSystemEventListener();
- this.resources = new HashMap<Resource, Set<ResourceChangeNotifier>>();
- this.directories = new HashSet<Resource>();
- this.interval = 60;
+ public ResourceChangeScannerImpl() {
+ this.listener = SystemEventListenerFactory.getSystemEventListener();
+ this.resources = new HashMap<Resource, Set<ResourceChangeNotifier>>();
+ this.directories = new HashSet<Resource>();
+ this.interval = 60;
this.listener.info( "ResourceChangeScanner created with default interval=60" );
- }
+ }
- public void setSystemEventListener(SystemEventListener listener) {
- this.listener = listener;
- }
+ public void setSystemEventListener(SystemEventListener listener) {
+ this.listener = listener;
+ }
- public void configure(ResourceChangeScannerConfiguration configuration) {
+ public void configure(ResourceChangeScannerConfiguration configuration) {
this.interval = ((ResourceChangeScannerConfigurationImpl) configuration).getInterval();
this.listener.info( "ResourceChangeScanner reconfigured with interval=" + getInterval() );
- // restart it if it's already running.
- if ( this.scannerScheduler != null && this.scannerScheduler.isRunning() ) {
- stop();
- start();
- }
- }
+ // restart it if it's already running.
+ if (this.scannerScheduler != null && this.scannerScheduler.isRunning()) {
+ stop();
+ start();
+ }
+ }
- public ResourceChangeScannerConfiguration newResourceChangeScannerConfiguration() {
- return new ResourceChangeScannerConfigurationImpl();
- }
+ public ResourceChangeScannerConfiguration newResourceChangeScannerConfiguration() {
+ return new ResourceChangeScannerConfigurationImpl();
+ }
- public ResourceChangeScannerConfiguration newResourceChangeScannerConfiguration(Properties properties) {
- return new ResourceChangeScannerConfigurationImpl( properties );
- }
+ public ResourceChangeScannerConfiguration newResourceChangeScannerConfiguration(
+ Properties properties) {
+ return new ResourceChangeScannerConfigurationImpl(properties);
+ }
- public void subscribeNotifier(ResourceChangeNotifier notifier,
- Resource resource) {
- synchronized ( this.resources ) {
- if ( ((InternalResource) resource).isDirectory() ) {
- this.directories.add( resource );
- }
- Set<ResourceChangeNotifier> notifiers = this.resources.get( resource );
- if ( notifiers == null ) {
- notifiers = new HashSet<ResourceChangeNotifier>();
- this.resources.put( resource,
- notifiers );
- }
- this.listener.debug( "ResourceChangeScanner subcribing notifier=" + notifier + " to resource=" + resource );
- notifiers.add( notifier );
- }
- }
+ public void subscribeNotifier(ResourceChangeNotifier notifier,
+ Resource resource) {
+ synchronized (this.resources) {
+ if (((InternalResource) resource).isDirectory()) {
+ this.directories.add(resource);
+ }
+ Set<ResourceChangeNotifier> notifiers = this.resources
+ .get(resource);
+ if (notifiers == null) {
+ notifiers = new HashSet<ResourceChangeNotifier>();
+ this.resources.put(resource, notifiers);
+ }
+ this.listener.debug("ResourceChangeScanner subcribing notifier="
+ + notifier + " to resource=" + resource);
+ notifiers.add(notifier);
+ }
+ }
- public void unsubscribeNotifier(ResourceChangeNotifier notifier,
- Resource resource) {
- synchronized ( this.resources ) {
- Set<ResourceChangeNotifier> notifiers = this.resources.get( resource );
- 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
- }
- }
- }
+ public void unsubscribeNotifier(ResourceChangeNotifier notifier,
+ Resource resource) {
+ synchronized (this.resources) {
+ Set<ResourceChangeNotifier> notifiers = this.resources
+ .get(resource);
+ 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
+ }
+ }
+ }
- public void scan() {
- this.listener.debug( "ResourceChangeScanner attempt to scan " + this.resources.size() + " resources" );
+ public void scan() {
+ this.listener.debug("ResourceChangeScanner attempt to scan "
+ + this.resources.size() + " resources");
- synchronized ( this.resources ) {
- Map<ResourceChangeNotifier, ChangeSet> notifications = new HashMap<ResourceChangeNotifier, ChangeSet>();
+ synchronized (this.resources) {
+ Map<ResourceChangeNotifier, ChangeSet> notifications = new HashMap<ResourceChangeNotifier, ChangeSet>();
- List<Resource> removed = new ArrayList<Resource>();
+ List<Resource> removed = new ArrayList<Resource>();
- // 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 ) ) {
+ // 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)) {
- 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
- for ( ResourceChangeNotifier notifier : notifiers ) {
- ChangeSetImpl changeSet = (ChangeSetImpl) notifications.get( notifier );
- if ( changeSet == null ) {
- // lazy initialise changeSet
- changeSet = new ChangeSetImpl();
- notifications.put( notifier,
- changeSet );
- }
- if ( changeSet.getResourcesAdded().isEmpty() ) {
- changeSet.setResourcesAdded( new ArrayList<Resource>() );
- }
- changeSet.getResourcesAdded().add( child );
- notifier.subscribeChildResource( resource,
- 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
+ for (ResourceChangeNotifier notifier : notifiers) {
+ ChangeSetImpl changeSet = (ChangeSetImpl) notifications
+ .get(notifier);
+ if (changeSet == null) {
+ // lazy initialise changeSet
+ changeSet = new ChangeSetImpl();
+ notifications.put(notifier, changeSet);
+ }
+ if (changeSet.getResourcesAdded().isEmpty()) {
+ changeSet
+ .setResourcesAdded(new ArrayList<Resource>());
+ }
+ changeSet.getResourcesAdded().add(child);
+ notifier.subscribeChildResource(resource, child);
+ }
+ }
+ }
+ }
- for ( Entry<Resource, Set<ResourceChangeNotifier>> entry : this.resources.entrySet() ) {
- Resource resource = entry.getKey();
- Set<ResourceChangeNotifier> notifiers = entry.getValue();
+ for (Entry<Resource, Set<ResourceChangeNotifier>> entry : this.resources
+ .entrySet()) {
+ Resource resource = entry.getKey();
+ Set<ResourceChangeNotifier> notifiers = entry.getValue();
- if ( !((InternalResource) resource).isDirectory() ) {
- // 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
- for ( ResourceChangeNotifier notifier : notifiers ) {
- ChangeSetImpl changeSet = (ChangeSetImpl) notifications.get( notifier );
- if ( changeSet == null ) {
- // lazy initialise changeSet
- changeSet = new ChangeSetImpl();
- notifications.put( notifier,
- changeSet );
- }
- if ( changeSet.getResourcesRemoved().isEmpty() ) {
- changeSet.setResourcesRemoved( new ArrayList<Resource>() );
- }
- changeSet.getResourcesRemoved().add( resource );
- }
- } else if ( ((InternalResource) resource).getLastRead() < lastModified ) {
- this.listener.debug( "ResourceChangeScanner modified resource=" + resource + " : " + ((InternalResource) resource).getLastRead() + " : " + lastModified );
- // it's modified
- // iterate notifiers for this resource and add to each modified
- for ( ResourceChangeNotifier notifier : notifiers ) {
- ChangeSetImpl changeSet = (ChangeSetImpl) notifications.get( notifier );
- if ( changeSet == null ) {
- // lazy initialise changeSet
- changeSet = new ChangeSetImpl();
- notifications.put( notifier,
- changeSet );
- }
- if ( changeSet.getResourcesModified().isEmpty() ) {
- changeSet.setResourcesModified( new ArrayList<Resource>() );
- }
- changeSet.getResourcesModified().add( resource );
- }
- }
- }
- }
+ if (!((InternalResource) resource).isDirectory()) {
+ // detect if Resource has been removed
+ long lastModified = ((InternalResource) resource)
+ .getLastModified();
+ long lastRead = ((InternalResource) resource).getLastRead();
+ 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
+ for (ResourceChangeNotifier notifier : notifiers) {
+ ChangeSetImpl changeSet = (ChangeSetImpl) notifications
+ .get(notifier);
+ if (changeSet == null) {
+ // lazy initialise changeSet
+ changeSet = new ChangeSetImpl();
+ notifications.put(notifier, changeSet);
+ }
+ if (changeSet.getResourcesRemoved().isEmpty()) {
+ changeSet
+ .setResourcesRemoved(new ArrayList<Resource>());
+ }
+ changeSet.getResourcesRemoved().add(resource);
+ }
+ } else if (lastRead < lastModified && lastRead >= 0) {
+ this.listener
+ .debug("ResourceChangeScanner modified resource="
+ + resource
+ + " : "
+ + lastRead
+ + " : "
+ + lastModified);
+ // it's modified
+ // iterate notifiers for this resource and add to each
+ // modified
+ for (ResourceChangeNotifier notifier : notifiers) {
+ ChangeSetImpl changeSet = (ChangeSetImpl) notifications
+ .get(notifier);
+ if (changeSet == null) {
+ // lazy initialise changeSet
+ changeSet = new ChangeSetImpl();
+ notifications.put(notifier, changeSet);
+ }
+ if (changeSet.getResourcesModified().isEmpty()) {
+ changeSet
+ .setResourcesModified(new ArrayList<Resource>());
+ }
+ changeSet.getResourcesModified().add(resource);
+ }
+ }
+ }
+ }
- // now iterate and removed the removed resources, we do this so as not to mutate the foreach loop while iterating
- for ( Resource resource : removed ) {
- this.resources.remove( resource );
- }
+ // now iterate and removed the removed resources, we do this so as
+ // not to mutate the foreach loop while iterating
+ for (Resource resource : removed) {
+ this.resources.remove(resource);
+ }
- for ( Entry<ResourceChangeNotifier, ChangeSet> entry : notifications.entrySet() ) {
- ResourceChangeNotifier notifier = entry.getKey();
- ChangeSet changeSet = entry.getValue();
- notifier.publishChangeSet( changeSet );
- }
- }
- }
+ for (Entry<ResourceChangeNotifier, ChangeSet> entry : notifications
+ .entrySet()) {
+ ResourceChangeNotifier notifier = entry.getKey();
+ ChangeSet changeSet = entry.getValue();
+ notifier.publishChangeSet(changeSet);
+ }
+ }
+ }
- public void setInterval(int interval) {
- this.interval = interval;
- this.listener.info( "ResourceChangeScanner reconfigured with interval=" + getInterval() );
+ public void setInterval(int interval) {
+ this.interval = interval;
+ this.listener.info("ResourceChangeScanner reconfigured with interval="
+ + getInterval());
- if ( this.scannerScheduler != null && this.scannerScheduler.isRunning() ) {
- stop();
- start();
- }
- }
+ if (this.scannerScheduler != null && this.scannerScheduler.isRunning()) {
+ stop();
+ start();
+ }
+ }
- public int getInterval() {
- return this.interval;
- }
+ public int getInterval() {
+ return this.interval;
+ }
- public void start() {
- this.scannerScheduler = new ProcessChangeSet( this.resources,
- this,
- this.listener,
- this.interval );
- thread = new Thread( this.scannerScheduler );
- thread.start();
- }
+ public void start() {
+ this.scannerScheduler = new ProcessChangeSet(this.resources, this,
+ this.listener, this.interval);
+ thread = new Thread(this.scannerScheduler);
+ thread.start();
+ }
- public void stop() {
- if ( this.scannerScheduler != null && this.scannerScheduler.isRunning() ) {
- this.scannerScheduler.stop();
- this.thread.interrupt();
- this.scannerScheduler = null;
- }
- }
+ public void stop() {
+ if (this.scannerScheduler != null && this.scannerScheduler.isRunning()) {
+ this.scannerScheduler.stop();
+ this.thread.interrupt();
+ this.scannerScheduler = null;
+ }
+ }
- public void reset() {
- this.resources.clear();
- this.directories.clear();
- }
+ public void reset() {
+ this.resources.clear();
+ this.directories.clear();
+ }
- private Thread thread;
- private ProcessChangeSet scannerScheduler;
+ private Thread thread;
+ private ProcessChangeSet scannerScheduler;
- public static class ProcessChangeSet
- implements
- Runnable {
- private volatile boolean scan;
- private ResourceChangeScannerImpl scanner;
- private long interval;
- private Map<Resource, Set<ResourceChangeNotifier>> resources;
- private SystemEventListener listener;
+ public static class ProcessChangeSet implements Runnable {
+ private volatile boolean scan;
+ private ResourceChangeScannerImpl scanner;
+ private long interval;
+ private Map<Resource, Set<ResourceChangeNotifier>> resources;
+ private SystemEventListener listener;
- ProcessChangeSet(Map<Resource, Set<ResourceChangeNotifier>> resources,
- ResourceChangeScannerImpl scanner,
- SystemEventListener listener,
- int interval) {
- this.resources = resources;
- this.scanner = scanner;
- this.listener = listener;
- this.interval = interval;
- this.scan = true;
- }
+ ProcessChangeSet(Map<Resource, Set<ResourceChangeNotifier>> resources,
+ ResourceChangeScannerImpl scanner,
+ SystemEventListener listener, int interval) {
+ this.resources = resources;
+ this.scanner = scanner;
+ this.listener = listener;
+ this.interval = interval;
+ this.scan = true;
+ }
- public int getInterval() {
- return (int) this.interval;
- }
+ public int getInterval() {
+ return (int) this.interval;
+ }
- public void stop() {
- this.scan = false;
- }
+ public void stop() {
+ this.scan = false;
+ }
- public boolean isRunning() {
- return this.scan;
- }
+ public boolean isRunning() {
+ return this.scan;
+ }
- public void run() {
- synchronized ( this ) {
- if ( this.scan ) {
- this.listener.info( "ResourceChangeNotification scanner has started" );
- }
- while ( this.scan ) {
- Exception exception = null;
- //System.out.println( "BEFORE : sync this.resources" );
- synchronized ( this.resources ) {
- //System.out.println( "DURING : sync this.resources" );
- // lock the resources, as we don't want this modified while processing
- this.scanner.scan();
- }
- //System.out.println( "AFTER : SCAN" );
- try {
- this.listener.debug( "ResourceChangeScanner thread is waiting for " + this.interval );
- wait( this.interval * 1000 );
- } catch ( InterruptedException e ) {
- exception = e;
- }
+ public void run() {
+ synchronized (this) {
+ if (this.scan) {
+ this.listener
+ .info("ResourceChangeNotification scanner has started");
+ }
+ while (this.scan) {
+ Exception exception = null;
+ // System.out.println( "BEFORE : sync this.resources" );
+ synchronized (this.resources) {
+ // System.out.println( "DURING : sync this.resources" );
+ // lock the resources, as we don't want this modified
+ // while processing
+ this.scanner.scan();
+ }
+ // System.out.println( "AFTER : SCAN" );
+ try {
+ this.listener
+ .debug("ResourceChangeScanner thread is waiting for "
+ + this.interval + " seconds.");
+ wait(this.interval * 1000);
+ } catch (InterruptedException e) {
+ exception = e;
+ }
- if ( this.scan && exception != null ) {
- this.listener.exception( new RuntimeException( "ResourceChangeNotification ChangeSet scanning thread was interrupted, but shutdown was not requested",
- exception ) );
- }
- }
- this.listener.info( "ResourceChangeNotification scanner has stopped" );
- }
- }
- }
-}
+ if (this.scan && exception != null) {
+ this.listener
+ .exception(new RuntimeException(
+ "ResourceChangeNotification ChangeSet scanning thread was interrupted, but shutdown was not requested",
+ exception));
+ }
+ }
+ this.listener
+ .info("ResourceChangeNotification scanner has stopped");
+ }
+ }
+ }
+}
\ No newline at end of file
More information about the jboss-svn-commits
mailing list