[jboss-svn-commits] JBL Code SVN: r30813 - in labs/jbossrules/trunk: drools-api/src/main/java/org/drools/agent and 11 other directories.
jboss-svn-commits at lists.jboss.org
jboss-svn-commits at lists.jboss.org
Thu Dec 24 12:54:15 EST 2009
Author: eaa
Date: 2009-12-24 12:54:14 -0500 (Thu, 24 Dec 2009)
New Revision: 30813
Added:
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/agent/ResourceDiffProducer.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/agent/impl/BinaryResourceDiffProducerImpl.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/agent/impl/DefaultResourceDiffProducerImpl.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/agent/impl/ResourceDiffResult.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/xml/changeset/DefinitionHandler.java
Removed:
labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/agent/KnowledgeAgentRemoveRuleChangeSetTest.java
Modified:
labs/jbossrules/trunk/drools-api/src/main/java/org/drools/ChangeSet.java
labs/jbossrules/trunk/drools-api/src/main/java/org/drools/KnowledgeBase.java
labs/jbossrules/trunk/drools-api/src/main/java/org/drools/agent/KnowledgeAgentFactory.java
labs/jbossrules/trunk/drools-api/src/main/java/org/drools/definition/KnowledgePackage.java
labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/rule/builder/dialect/java/JavaDialect.java
labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/agent/KnowledgeAgentIncrementalChangeSetTest.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/definitions/impl/KnowledgePackageImp.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/impl/KnowledgeBaseImpl.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/io/impl/ChangeSetImpl.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/Function.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/Package.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/xml/ChangeSetSemanticModule.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/xml/changeset/RemoveHandler.java
Log:
JBRULES-2082: support for delete/modify in changesets
- The agent now support adding/modifying/removing entire resources. For modified resources (when newInstance=false), a silly diff is made: all the definitions are marked as changed. A better implementation of this diff will allow to modify in the kbase just the rules that have changed.
Modified: labs/jbossrules/trunk/drools-api/src/main/java/org/drools/ChangeSet.java
===================================================================
--- labs/jbossrules/trunk/drools-api/src/main/java/org/drools/ChangeSet.java 2009-12-24 16:09:54 UTC (rev 30812)
+++ labs/jbossrules/trunk/drools-api/src/main/java/org/drools/ChangeSet.java 2009-12-24 17:54:14 UTC (rev 30813)
@@ -82,8 +82,11 @@
*/
public Collection<Resource> getResourcesModified();
- Map<Resource, String> getKnowledgeDefinitionsRemoved();
+ /**
+ * Returns a collection containing the full names (package+name) of the kdefinitions to be removed.
+ * @return
+ */
+ Collection<String> getKnowledgeDefinitionsRemoved();
- void setKnowledgeDefinitionsRemoved(Map<Resource, String> knowledgeDefinitionsRemoved);
}
Modified: labs/jbossrules/trunk/drools-api/src/main/java/org/drools/KnowledgeBase.java
===================================================================
--- labs/jbossrules/trunk/drools-api/src/main/java/org/drools/KnowledgeBase.java 2009-12-24 16:09:54 UTC (rev 30812)
+++ labs/jbossrules/trunk/drools-api/src/main/java/org/drools/KnowledgeBase.java 2009-12-24 17:54:14 UTC (rev 30813)
@@ -91,6 +91,14 @@
String ruleName);
/**
+ * Remove a function from the specified package.
+ * @param packageName
+ * @param ruleName
+ */
+ void removeFunction(String packageName,
+ String ruleName);
+
+ /**
* Returns the FactType identified by the given package and type names.
*
* @param packageName the name of the package the fact belongs to.
Modified: labs/jbossrules/trunk/drools-api/src/main/java/org/drools/agent/KnowledgeAgentFactory.java
===================================================================
--- labs/jbossrules/trunk/drools-api/src/main/java/org/drools/agent/KnowledgeAgentFactory.java 2009-12-24 16:09:54 UTC (rev 30812)
+++ labs/jbossrules/trunk/drools-api/src/main/java/org/drools/agent/KnowledgeAgentFactory.java 2009-12-24 17:54:14 UTC (rev 30813)
@@ -27,7 +27,7 @@
* KnowledgeBase kbase = kagent.getKnowledgeBase();
* </pre>
*
- * <p>If you wish to change to change the polling time of the scanner, this can be done with the ResourceChangeScannerService on the ResourceFactory</p>
+ * <p>If you wish to change the polling time of the scanner, this can be done with the ResourceChangeScannerService on the ResourceFactory</p>
* <pre>
* // Set the interval on the ResourceChangeScannerService if the default of 60s is not desirable.
* ResourceChangeScannerConfiguration sconf = ResourceFactory.getResourceChangeScannerService().newResourceChangeScannerConfiguration();
@@ -53,10 +53,9 @@
* </pre>
*
* <p>
- * You'll notice the property "drools.agent.newInstance", which defaults to true, currently this cannot be set to false. This property when
+ * You'll notice the property "drools.agent.newInstance", which defaults to true. This property when
* true means the KnowledgeBase will be rebuilt as a new instance when changes are detected and that new instance will be available when
- * kagent.getKnowledgeBase() is next called. We hope to add incremental KnowledgeBase support in the future, when a "false" value will be supported
- * for this property.
+ * kagent.getKnowledgeBase() is next called.
* </p>
*
* <p>
@@ -85,14 +84,32 @@
* For example -Ddrools.resource.urlcache=/home/rulecaches
*
* </p>
+ *
+ * <p>
+ * The default implementation of KnowledgeAgent returned by this factory is
+ * "org.drools.agent.impl.KnowledgeAgentProviderImpl". You can change it using
+ * the system property {@link #PROVIDER_CLASS_NAME_PROPERTY_NAME} to point to a diverse
+ * implementation of "org.drools.agent.KnowledgeAgentProvider".
+ * </p>
*
* @see org.drools.agent.KnowledgeAgent
- * @see org.drools.agent.KnowledgeAgentConfiguration
+ * @see org.drools.agent.KnowledgeAgent
*
*/
public class KnowledgeAgentFactory {
+
+ public static final String PROVIDER_CLASS_NAME_PROPERTY_NAME = "drools.agent.factory.provider";
+ /**
+ * The provider class name. The default provider is org.drools.agent.impl.KnowledgeAgentProviderImpl.
+ * If you need a different provider you can use the system property
+ * {@link #PROVIDER_CLASS_NAME_PROPERTY_NAME} to point to a diverse implementation of
+ * "org.drools.agent.KnowledgeAgentProvider"
+ */
+ private static String providerClassName = "org.drools.agent.impl.KnowledgeAgentProviderImpl";
+
private static KnowledgeAgentProvider provider;
+
public static KnowledgeAgentConfiguration newKnowledgeAgentConfiguration() {
return getKnowledgeAgentProvider().newKnowledgeAgentConfiguration();
}
@@ -140,11 +157,13 @@
private static void loadProvider() {
try {
- // we didn't find anything in properties so lets try and us reflection
- Class<KnowledgeAgentProvider> cls = (Class<KnowledgeAgentProvider>) Class.forName( "org.drools.agent.impl.KnowledgeAgentProviderImpl" );
+ //loads the provider class
+ providerClassName = System.getProperty(KnowledgeAgentFactory.PROVIDER_CLASS_NAME_PROPERTY_NAME, providerClassName);
+
+ Class<KnowledgeAgentProvider> cls = (Class<KnowledgeAgentProvider>) Class.forName(providerClassName);
setKnowledgeAgentProvider( cls.newInstance() );
} catch ( Exception e ) {
- throw new ProviderInitializationException( "Provider org.drools.agent.KnowledgeAgentProvider could not be set." );
+ throw new ProviderInitializationException( "Provider "+providerClassName+" could not be set." );
}
}
}
Modified: labs/jbossrules/trunk/drools-api/src/main/java/org/drools/definition/KnowledgePackage.java
===================================================================
--- labs/jbossrules/trunk/drools-api/src/main/java/org/drools/definition/KnowledgePackage.java 2009-12-24 16:09:54 UTC (rev 30812)
+++ labs/jbossrules/trunk/drools-api/src/main/java/org/drools/definition/KnowledgePackage.java 2009-12-24 17:54:14 UTC (rev 30813)
@@ -34,4 +34,5 @@
*/
Collection<Process> getProcesses();
+
}
Modified: labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/rule/builder/dialect/java/JavaDialect.java
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/rule/builder/dialect/java/JavaDialect.java 2009-12-24 16:09:54 UTC (rev 30812)
+++ labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/rule/builder/dialect/java/JavaDialect.java 2009-12-24 17:54:14 UTC (rev 30813)
@@ -582,7 +582,7 @@
this.pkg.addStaticImport( functionClassName + "." + functionDescr.getName() );
- Function function = new Function( functionDescr.getName(),
+ Function function = new Function( functionDescr.getNamespace(), functionDescr.getName(),
this.ID );
if ( resource != null && ((InternalResource) resource).hasURL() ) {
function.setResource( resource );
Modified: 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 2009-12-24 16:09:54 UTC (rev 30812)
+++ labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/agent/KnowledgeAgentIncrementalChangeSetTest.java 2009-12-24 17:54:14 UTC (rev 30813)
@@ -1005,6 +1005,216 @@
kagent.monitorResourceChangeEvents(false);
}
+
+ public void completeTest() throws Exception {
+ String header = "";
+ header += "package org.drools.test\n";
+ header += "global java.util.List list\n\n";
+
+ String rule1 = this.createCommonRule("rule1");
+ String rule1V2 = this.createCommonRule("rule1", "2");
+ String rule1V3 = this.createCommonRule("rule1", "3");
+ String rule2 = this.createCommonRule("rule2");
+ String rule3 = this.createCommonRule("rule3");
+ String rule3V2 = this.createCommonRule("rule3","2");
+ String rule4 = this.createCommonRule("rule4");
+
+
+ File f1 = fileManager.newFile("rule1.drl");
+ Writer output = new BufferedWriter(new FileWriter(f1));
+ output.write(header);
+ output.write(rule1);
+ output.write(rule2);
+ output.close();
+
+ File f2 = fileManager.newFile("rule2.drl");
+ output = new BufferedWriter(new FileWriter(f2));
+ output.write(header);
+ output.write(rule3);
+ output.close();
+
+ File f3 = fileManager.newFile("rule3.drl");
+ output = new BufferedWriter(new FileWriter(f3));
+ output.write(header);
+ output.write(rule1V2);
+ 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();
+ KnowledgeAgent kagent = this.createKAgent(kbase);
+
+ 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();
+
+ 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/rule3.drl' type='DRL' />";
+ xml += " </add> ";
+ xml += "</change-set>";
+
+ fxml = fileManager.newFile("changeset.xml");
+ output = new BufferedWriter(new FileWriter(fxml));
+ output.write(xml);
+ output.close();
+
+ kagent.applyChangeSet(ResourceFactory.newUrlResource(fxml.toURI().toURL()));
+
+ ksession = kbase.newStatefulKnowledgeSession();
+ list = new ArrayList<String>();
+ ksession.setGlobal("list", list);
+ ksession.fireAllRules();
+ ksession.dispose();
+
+ assertEquals(3, list.size());
+ assertTrue(list.contains("rule1-V2"));
+ assertTrue(list.contains("rule2"));
+ assertTrue(list.contains("rule3"));
+
+
+ // have to sleep here as linux lastModified does not do milliseconds
+ // http://saloon.javaranch.com/cgi-bin/ubb/ultimatebb.cgi?ubb=get_topic&f=1&t=019789
+ Thread.sleep(2000);
+
+ output = new BufferedWriter(new FileWriter(f2));
+ output.write(header);
+ output.write(rule3);
+ output.write(rule4);
+ output.close();
+ Thread.sleep(3000);
+
+ ksession = kbase.newStatefulKnowledgeSession();
+ list = new ArrayList<String>();
+ ksession.setGlobal("list", list);
+ ksession.fireAllRules();
+ ksession.dispose();
+
+ assertEquals(4, list.size());
+ assertTrue(list.contains("rule1-V2"));
+ assertTrue(list.contains("rule2"));
+ assertTrue(list.contains("rule3"));
+ assertTrue(list.contains("rule4"));
+
+
+ // 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);
+
+ //removes rule1 from rules3.drl and add a new definition for rule3 in that file
+ output = new BufferedWriter(new FileWriter(f3));
+ output.write(header);
+ output.write(rule3V2);
+ output.close();
+ Thread.sleep(3000);
+
+ ksession = kbase.newStatefulKnowledgeSession();
+ list = new ArrayList<String>();
+ ksession.setGlobal("list", list);
+ ksession.fireAllRules();
+ ksession.dispose();
+
+ assertEquals(3, list.size());
+ assertTrue(list.contains("rule2"));
+ assertTrue(list.contains("rule3-V2"));
+ assertTrue(list.contains("rule4"));
+
+ // 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);
+
+ //removes rule3 from rules3.drl
+ output = new BufferedWriter(new FileWriter(f3));
+ output.write(header);
+ output.close();
+ 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("rule4"));
+
+ // 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);
+
+ //removes rule3 from rules3.drl
+ f3.delete();
+ 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("rule4"));
+
+
+ // 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);
+
+ //adds rules1-V3 definition to rules2.drl
+ output = new BufferedWriter(new FileWriter(f2));
+ output.write(header);
+ output.write(rule1V3);
+ output.write(rule3);
+ output.write(rule4);
+ output.close();
+ Thread.sleep(3000);
+
+ ksession = kbase.newStatefulKnowledgeSession();
+ list = new ArrayList<String>();
+ ksession.setGlobal("list", list);
+ ksession.fireAllRules();
+ ksession.dispose();
+
+ assertEquals(4, list.size());
+ assertTrue(list.contains("rule1-V3"));
+ assertTrue(list.contains("rule2"));
+ //rule3 reapears because rules2.drl was reporcessed
+ assertTrue(list.contains("rule3"));
+ assertTrue(list.contains("rule4"));
+
+ kagent.monitorResourceChangeEvents(false);
+
+ }
+
private static void writePackage(Object pkg, File p1file)
@@ -1017,6 +1227,101 @@
}
}
+
+ private KnowledgeAgent createKAgent(KnowledgeBase kbase) {
+ ResourceChangeScannerConfiguration sconf = ResourceFactory.getResourceChangeScannerService().newResourceChangeScannerConfiguration();
+ sconf.setProperty("drools.resource.scanner.interval", "2");
+ ResourceFactory.getResourceChangeScannerService().configure(sconf);
+
+ //System.setProperty(KnowledgeAgentFactory.PROVIDER_CLASS_NAME_PROPERTY_NAME, "org.drools.agent.impl.KnowledgeAgentProviderImpl");
+
+ KnowledgeAgentConfiguration aconf = KnowledgeAgentFactory.newKnowledgeAgentConfiguration();
+ aconf.setProperty("drools.agent.scanDirectories", "true");
+ aconf.setProperty("drools.agent.scanResources", "true");
+ // Testing incremental build here
+ aconf.setProperty("drools.agent.newInstance", "false");
+
+
+
+ KnowledgeAgent kagent = KnowledgeAgentFactory.newKnowledgeAgent(
+ "test agent", kbase, aconf);
+
+ assertEquals("test agent", kagent.getName());
+
+ return kagent;
+ }
+
+ private String createCommonRule(String ruleName) {
+ StringBuilder sb = new StringBuilder();
+ sb.append("rule ");
+ sb.append(ruleName);
+ sb.append("\n");
+ sb.append("when\n");
+ sb.append("then\n");
+ sb.append("list.add( drools.getRule().getName() );\n");
+ sb.append("end\n");
+
+ return sb.toString();
+ }
+
+ private String createCommonDSLRRule(String ruleName) {
+ StringBuilder sb = new StringBuilder();
+ sb.append("rule ");
+ sb.append(ruleName);
+ sb.append("\n");
+ sb.append("when\n");
+ sb.append("There is a String\n");
+ sb.append("then\n");
+ sb.append("add rule's name to list;\n");
+ sb.append("end\n");
+
+ return sb.toString();
+ }
+
+ private String createCommonRule(String ruleName, String version) {
+ StringBuilder sb = new StringBuilder();
+ sb.append("rule ");
+ sb.append(ruleName);
+ sb.append("\n");
+ sb.append("when\n");
+ sb.append("then\n");
+ sb.append("list.add( drools.getRule().getName()+\"-V" + version + "\");\n");
+ sb.append("end\n");
+
+ return sb.toString();
+ }
+
+ private String createCommonDSL() {
+ StringBuilder sb = new StringBuilder();
+ sb.append("[condition][]There is a String = String()\n");
+ sb.append("[consequence][]add rule's name to list = list.add( drools.getRule().getName() );\n");
+ return sb.toString();
+ }
+
+ private String createDummyFunction(String functionName) {
+ StringBuilder sb = new StringBuilder();
+ sb.append("function void ");
+ sb.append(functionName);
+ sb.append("(){\n");
+ sb.append(" System.out.println(\"Function executed\");\n");
+ sb.append("}\n");
+
+ return sb.toString();
+ }
+
+ private String createCommonFunction(String functionName, String valueToAdd) {
+ StringBuilder sb = new StringBuilder();
+ sb.append("function void ");
+ sb.append(functionName);
+ sb.append("(java.util.List myList,String source){\n");
+ sb.append(" myList.add(\"");
+ sb.append(valueToAdd);
+ sb.append(" from \"+source);\n");
+ sb.append("}\n");
+
+ return sb.toString();
+ }
+
public static class ResultHandlerImpl implements ResultHandler {
Object object;
Deleted: labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/agent/KnowledgeAgentRemoveRuleChangeSetTest.java
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/agent/KnowledgeAgentRemoveRuleChangeSetTest.java 2009-12-24 16:09:54 UTC (rev 30812)
+++ labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/agent/KnowledgeAgentRemoveRuleChangeSetTest.java 2009-12-24 17:54:14 UTC (rev 30813)
@@ -1,365 +0,0 @@
-package org.drools.agent;
-
-import java.io.BufferedWriter;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.io.Writer;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-
-import junit.framework.TestCase;
-
-import org.drools.KnowledgeBase;
-import org.drools.KnowledgeBaseFactory;
-import org.drools.io.Resource;
-import org.drools.io.ResourceChangeScannerConfiguration;
-import org.drools.io.ResourceFactory;
-import org.drools.io.impl.ChangeSetImpl;
-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 KnowledgeAgentRemoveRuleChangeSetTest 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 header = "";
- header += "package org.drools.test\n";
- header += "global java.util.List list\n\n";
-
- String rule1 = this.createCommonRule("rule1");
- String rule2 = this.createCommonRule("rule2");
- String rule3 = this.createCommonRule("rule3");
- String rule4 = this.createCommonRule("rule4");
-
- String function1 = this.createDummyFunction("function1");
-
- String query1 = "";
- query1 += "query \"all the Strings\"\n";
- //query1 += "query \"rule1\"\n";
- query1 += " str : String()\n";
- query1 += "end\n";
-
- String type1 = "";
- type1 += "declare Address\n";
- type1 += " number : int\n";
- type1 += " streetName : String\n";
- type1 += " city : String\n";
- type1 += "end\n";
-
-
- File f1 = fileManager.newFile("rule1.drl");
- Writer output = new BufferedWriter(new FileWriter(f1));
- output.write(header);
- output.write(type1);
- output.write(query1);
- output.write(function1);
- output.write(rule1);
- output.write(rule2);
- output.close();
-
- File f2 = fileManager.newFile("rule2.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/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();
- KnowledgeAgent kagent = this.createKAgent(kbase);
- 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(f1));
- output.write(header);
- output.write(rule2);
- output.write(rule4);
- 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(3, list.size());
-
- assertTrue(list.contains("rule3"));
- assertTrue(list.contains("rule2"));
- assertTrue(list.contains("rule4"));
- kagent.monitorResourceChangeEvents(false);
- }
-
- public void testRemoveRuleChangeSet() throws Exception {
-
- String header = "";
- header += "package org.drools.test\n";
- header += "global java.util.List list\n\n";
-
- String rule1 = this.createCommonRule("rule1");
- String rule2 = this.createCommonRule("rule2");
- String rule3 = this.createCommonRule("rule3");
-
- String function1 = this.createDummyFunction("function1");
-
- File f1 = fileManager.newFile("rule1.drl");
- Writer output = new BufferedWriter(new FileWriter(f1));
- output.write(header);
- output.write(function1);
- output.write(rule1);
- output.write(rule2);
- output.close();
-
- File f2 = fileManager.newFile("rule2.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/rule1.drl' type='DRL' />";
- xml += " <resource source='http://localhost:9000/rule2.drl' type='DRL' />";
- xml += " </add> ";
- xml += "</change-set>";
- final File fxml = fileManager.newFile("changeset.xml");
- output = new BufferedWriter(new FileWriter(fxml));
- output.write(xml);
- output.close();
-
- KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
- KnowledgeAgent kagent = this.createKAgent(kbase);
- 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();
-
- //Creates a new changeSet that will delete Rule1 from kbase
- ChangeSetImpl cs = new ChangeSetImpl();
- cs.setKnowledgeDefinitionsRemoved(new HashMap<Resource, String>() {
-
- {
- Resource r = ResourceFactory.newUrlResource("http://localhost:9000/rule1.drl");
- this.put(r, "rule1");
- }
- });
-
- kagent.applyChangeSet(cs);
-
-
- 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"));
-
-
-
- //Creates a new changeSet that will try to delete Rule3 from rule1.drl.
- //Because Rule3 is defined in rule2.drl, this shouldn't remove any rule.
- cs = new ChangeSetImpl();
- cs.setKnowledgeDefinitionsRemoved(new HashMap<Resource, String>() {
-
- {
- Resource r = ResourceFactory.newUrlResource("http://localhost:9000/rule1.drl");
- this.put(r, "rule3");
- }
- });
-
- kagent.applyChangeSet(cs);
-
-
- 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"));
-
-
- //Finally, remove Rule3
- cs = new ChangeSetImpl();
- cs.setKnowledgeDefinitionsRemoved(new HashMap<Resource, String>() {
-
- {
- Resource r = ResourceFactory.newUrlResource("http://localhost:9000/rule2.drl");
- this.put(r, "rule3");
- }
- });
-
- kagent.applyChangeSet(cs);
-
-
- ksession = kbase.newStatefulKnowledgeSession();
- list = new ArrayList<String>();
- ksession.setGlobal("list", list);
- ksession.fireAllRules();
- ksession.dispose();
-
- assertEquals(1, list.size());
-
- assertTrue(list.contains("rule2"));
-
- }
-
-
- private KnowledgeAgent createKAgent(KnowledgeBase kbase){
- ResourceChangeScannerConfiguration sconf = ResourceFactory.getResourceChangeScannerService().newResourceChangeScannerConfiguration();
- sconf.setProperty("drools.resource.scanner.interval", "2");
- ResourceFactory.getResourceChangeScannerService().configure(sconf);
-
- KnowledgeAgentConfiguration aconf = KnowledgeAgentFactory.newKnowledgeAgentConfiguration();
- aconf.setProperty("drools.agent.scanDirectories", "true");
- aconf.setProperty("drools.agent.scanResources", "true");
- // Testing incremental build here
- aconf.setProperty("drools.agent.newInstance", "false");
- KnowledgeAgent kagent = KnowledgeAgentFactory.newKnowledgeAgent(
- "test agent", kbase, aconf);
-
- assertEquals("test agent", kagent.getName());
-
- return kagent;
- }
-
- private String createCommonRule(String ruleName) {
- StringBuilder sb = new StringBuilder();
- sb.append("rule ");
- sb.append(ruleName);
- sb.append("\n");
- sb.append("when\n");
- sb.append("then\n");
- sb.append("list.add( drools.getRule().getName() );\n");
- sb.append("end\n");
-
- return sb.toString();
- }
-
- private String createDummyFunction(String functionName) {
- StringBuilder sb = new StringBuilder();
- sb.append("function void ");
- sb.append(functionName);
- sb.append("(){\n");
- sb.append(" System.out.println(\"Function executed\");\n");
- sb.append("}\n");
-
- return sb.toString();
- }
-
- 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;
- }
- }
-}
Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/agent/ResourceDiffProducer.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/agent/ResourceDiffProducer.java (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/agent/ResourceDiffProducer.java 2009-12-24 17:54:14 UTC (rev 30813)
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2009 esteban.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * under the License.
+ */
+
+package org.drools.agent;
+
+import java.util.Set;
+import org.drools.definition.KnowledgeDefinition;
+import org.drools.definitions.impl.KnowledgePackageImp;
+import org.drools.agent.impl.ResourceDiffResult;
+
+/**
+ *
+ * @author esteban
+ */
+public interface ResourceDiffProducer {
+ ResourceDiffResult diff(Set<KnowledgeDefinition> originalDefinitions, KnowledgePackageImp pkg);
+}
Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/agent/impl/BinaryResourceDiffProducerImpl.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/agent/impl/BinaryResourceDiffProducerImpl.java (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/agent/impl/BinaryResourceDiffProducerImpl.java 2009-12-24 17:54:14 UTC (rev 30813)
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2009 JBoss Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.drools.agent.impl;
+
+import java.util.HashSet;
+import java.util.Set;
+import org.drools.definition.KnowledgeDefinition;
+import org.drools.definitions.impl.KnowledgePackageImp;
+import org.drools.agent.ResourceDiffProducer;
+import org.drools.rule.Rule;
+import org.drools.util.ReflectiveVisitor;
+
+/**
+ *
+ * @author esteban.aliverti at gmail.com
+ */
+public class BinaryResourceDiffProducerImpl extends ReflectiveVisitor implements ResourceDiffProducer {
+
+ private KnowledgePackageImp newPkg;
+
+ public ResourceDiffResult diff(Set<KnowledgeDefinition> originalDefinitions, KnowledgePackageImp pkg) {
+
+ this.newPkg = pkg;
+
+ Set<KnowledgeDefinition> removed = new HashSet<KnowledgeDefinition>();
+
+
+ for (KnowledgeDefinition knowledgeDefinition : originalDefinitions) {
+ this.visit(knowledgeDefinition);
+ }
+
+
+ //return the whole new package as new
+ return new ResourceDiffResult(pkg, originalDefinitions);
+ }
+
+
+ public void visitRule(final Rule rule){
+ //ok, so I got an old rule: is it modified in the new pkg? is it even present on it?
+ //newPkg.
+
+ }
+
+
+
+}
Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/agent/impl/DefaultResourceDiffProducerImpl.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/agent/impl/DefaultResourceDiffProducerImpl.java (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/agent/impl/DefaultResourceDiffProducerImpl.java 2009-12-24 17:54:14 UTC (rev 30813)
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2009 esteban.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * under the License.
+ */
+
+package org.drools.agent.impl;
+
+import java.util.HashSet;
+import java.util.Set;
+import org.drools.RuntimeDroolsException;
+import org.drools.builder.KnowledgeBuilder;
+import org.drools.builder.KnowledgeBuilderFactory;
+import org.drools.definition.KnowledgeDefinition;
+import org.drools.definitions.impl.KnowledgePackageImp;
+import org.drools.agent.ResourceDiffProducer;
+
+/**
+ *
+ * @author esteban.aliverti at gmail.com
+ */
+public class DefaultResourceDiffProducerImpl implements ResourceDiffProducer {
+
+ public ResourceDiffResult diff(Set<KnowledgeDefinition> originalDefinitions, KnowledgePackageImp pkg) {
+
+ Set<KnowledgeDefinition> removed = new HashSet<KnowledgeDefinition>();
+
+ //put all the original definitions as removed
+ for (KnowledgeDefinition knowledgeDefinition : originalDefinitions) {
+ removed.add(knowledgeDefinition);
+ }
+
+ //return the whole new package as new
+ return new ResourceDiffResult(pkg, removed);
+
+
+ }
+
+
+}
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-24 16:09:54 UTC (rev 30812)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/agent/impl/KnowledgeAgentImpl.java 2009-12-24 17:54:14 UTC (rev 30813)
@@ -3,9 +3,9 @@
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.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -36,9 +36,9 @@
import org.drools.io.ResourceFactory;
import org.drools.io.impl.ClassPathResource;
import org.drools.io.impl.ResourceChangeNotifierImpl;
+import org.drools.agent.ResourceDiffProducer;
import org.drools.rule.Function;
import org.drools.rule.Package;
-import org.drools.rule.Query;
import org.drools.rule.Rule;
import org.drools.rule.TypeDeclaration;
import org.drools.runtime.KnowledgeSessionConfiguration;
@@ -60,7 +60,6 @@
ResourceChangeListener {
private String name;
- private ResourceMap resourcesMap;
private Set<Resource> resourceDirectories;
private KnowledgeBase kbase;
private ResourceChangeNotifierImpl notifier;
@@ -71,6 +70,7 @@
private Thread thread;
private ChangeSetNotificationDetector changeSetNotificationDetector;
private SemanticModules semanticModules;
+ private final RegisteredResourceMap registeredResources = new RegisteredResourceMap();
/**
* Default constructor for KnowledgeAgentImpl
@@ -83,7 +83,6 @@
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();
@@ -111,8 +110,9 @@
monitorResourceChangeEvents(monitor);
- buildResourceMapping();
+ autoBuildResourceMapping();
+
this.listener.info("KnowledgeAgent created, with configuration:\nmonitorChangeSetEvents="
+ monitor
+ " scanResources="
@@ -131,7 +131,7 @@
}
public void applyChangeSet(ChangeSet changeSet) {
- synchronized (this.resourcesMap) {
+ synchronized (this.registeredResources) {
this.listener.info("KnowledgeAgent applying ChangeSet");
ChangeSetState changeSetState = new ChangeSetState();
@@ -144,7 +144,7 @@
// Rebuild or do an update to the KnowledgeBase
buildKnowledgeBase(changeSetState);
// Rebuild the resource mapping
- buildResourceMapping();
+ //buildResourceMapping();
}
}
@@ -155,7 +155,7 @@
public void processChangeSet(ChangeSet changeSet,
ChangeSetState changeSetState) {
- synchronized (this.resourcesMap) {
+ synchronized (this.registeredResources) {
/*
* Process the added resources from a ChangeSet by subscribing to
* the notifier and inserting a new ResourceMapping.
@@ -181,18 +181,18 @@
}
((InternalResource) child).setResourceType(((InternalResource) resource).getResourceType());
- if (this.resourcesMap.addResourceMapping(child, true)
+
+ this.addDefinitionMapping(child, null, true);
+ if (this.addResourceMapping(child, true)
&& changeSetState.incrementalBuild) {
changeSetState.addedResources.add(child);
}
}
} else {
- if (this.resourcesMap.addResourceMapping(resource, true)
+ if (this.addResourceMapping(resource, true)
&& changeSetState.incrementalBuild) {
- // parse the reource using DlrParser. save the packageDescr into a Map<Resource,PackageDescr
changeSetState.addedResources.add(resource);
-
}
}
}
@@ -215,10 +215,11 @@
this.notifier.unsubscribeResourceChangeListener(this,
resource);
} else {
- ResourceMapEntry removedEntry = this.resourcesMap.removeResourceMapping(resource, true);
- if (removedEntry != null && changeSetState.incrementalBuild) {
- changeSetState.removedResourceMappings.add(removedEntry);
+ Set<KnowledgeDefinition> definitions = this.removeResourceMapping(resource, true);
+
+ if (definitions != null && changeSetState.incrementalBuild) {
+ changeSetState.removedResourceMappings.put(resource, definitions);
}
}
}
@@ -249,7 +250,7 @@
continue;
}
- if (this.resourcesMap.addResourceMapping(child, true)) {
+ if (this.addResourceMapping(child, true)) {
((InternalResource) child).setResourceType(((InternalResource) resource).getResourceType());
if (changeSetState.incrementalBuild) {
changeSetState.addedResources.add(child);
@@ -257,45 +258,28 @@
}
}
} else {
- ResourceMapEntry modifiedMapping = this.resourcesMap.removeResourceMapping(resource, false);
- if (modifiedMapping == null) {
+
+ boolean isResourceMapped = this.registeredResources.isResourceMapped(resource);
+
+ if (!isResourceMapped) {
this.listener.warning("KnowledgeAgent subscribing to new resource="
+ resource
+ ", though it was marked as modified.");
- this.resourcesMap.addResourceMapping(resource, true);
+ this.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);
- }
- }
- }
- }
+ Set<KnowledgeDefinition> definitions = this.removeResourceMapping(resource, true);
- //Removes each knowledgeDefinition marked as deleted from resourceMap.
- //The deletion from kbase will be performed after by buildKnowledgeBase()
- for (Resource resource : changeSet.getKnowledgeDefinitionsRemoved().keySet()) {
+ changeSetState.modifiedResourceMappings.put(resource, definitions);
- KnowledgeDefinition removedDefinition = this.resourcesMap.removeResourceMappingEntry(resource, changeSet.getKnowledgeDefinitionsRemoved().get(resource));
-
- if (removedDefinition == null) {
- this.listener.warning("Knowledge definition "
- + changeSet.getKnowledgeDefinitionsRemoved().get(resource)
- + " couldn't be removed from "
- + resource);
- } else{
- //set the removedDefinition into the changeSetState so it
- //can be removed from kbase by buildKnowledgeBase().
- changeSetState.removedKnowledgeDefinitions.put(resource, removedDefinition);
+ //adds a new empty mapping that will be filled in buildResourceMapping()
+ this.addResourceMapping(resource, false);
+ }
+ }
}
}
@@ -346,78 +330,112 @@
public static class ChangeSetState {
List<Resource> addedResources = new ArrayList<Resource>();
- List<ResourceMapEntry> removedResourceMappings = new ArrayList<ResourceMapEntry>();
- List<ResourceMapEntry> modifiedResourceMappings = new ArrayList<ResourceMapEntry>();
- Map<Resource, KnowledgeDefinition> removedKnowledgeDefinitions = new HashMap<Resource, KnowledgeDefinition>();
+ /**
+ * Map of removed definitions. The Set of kdefinitions is the original
+ * definitions of the resource (before the deletion).
+ */
+ Map<Resource, Set<KnowledgeDefinition>> removedResourceMappings = new HashMap<Resource, Set<KnowledgeDefinition>>();
+ /**
+ * Map of modified definitions. The Set of kdefinitions is the original
+ * definitions of the resource (before the modification).
+ */
+ Map<Resource, Set<KnowledgeDefinition>> modifiedResourceMappings = new HashMap<Resource, Set<KnowledgeDefinition>>();
+ /**
+ *Map of created Packages. The agent will create this packages when
+ * processing added and modified resources
+ */
+ Map<Resource, KnowledgePackage> createdPackages = new LinkedHashMap<Resource, KnowledgePackage>();
boolean scanDirectories;
boolean incrementalBuild;
}
+ private void buildResourceMapping(Package pkg, Resource resource) {
+ if (resource == null) {
+ this.listener.warning("KnowledgeAgent: trying to build a resource map for a null resource!");
+ return;
+ }
+ this.buildResourceMapping(pkg, resource, false);
+ }
+
+ private void buildResourceMapping(Package pkg, Resource resource, boolean autoDiscoverResource) {
+
+ synchronized (this.registeredResources) {
+ if (!autoDiscoverResource && resource == null) {
+ this.listener.warning("KnowledgeAgent: Impossible to map to a null resource! Use autoDiscoverResource = true ");
+ return;
+ }
+
+ if (autoDiscoverResource && resource != null) {
+ this.listener.warning("KnowledgeAgent: building resource map with resource set and autoDiscoverResource=true. Resource value wil be overwritten!");
+ }
+
+ for (Rule rule : pkg.getRules()) {
+ if (resource != null && !((InternalResource) resource).hasURL()) {
+ this.listener.debug("KnowledgeAgent no resource mapped for rule="
+ + rule);
+ }
+ if (autoDiscoverResource) {
+ resource = rule.getResource();
+ }
+
+ this.addDefinitionMapping(resource, rule, true);
+ }
+
+ for (Process process : pkg.getRuleFlows().values()) {
+ if (resource != null && !((InternalResource) resource).hasURL()) {
+ this.listener.debug("KnowledgeAgent no resource mapped for rule="
+ + process);
+ }
+ if (autoDiscoverResource) {
+ resource = ((org.drools.process.core.Process) process).getResource();
+ }
+
+ this.addDefinitionMapping(resource, process, true);
+ }
+
+ for (TypeDeclaration typeDeclaration : pkg.getTypeDeclarations().values()) {
+ if (resource != null && !((InternalResource) resource).hasURL()) {
+ this.listener.debug("KnowledgeAgent no resource mapped for rule="
+ + typeDeclaration);
+ }
+ if (autoDiscoverResource) {
+ resource = typeDeclaration.getResource();
+ }
+
+ this.addDefinitionMapping(resource, typeDeclaration, true);
+ }
+
+ for (Function function : pkg.getFunctions().values()) {
+ if (resource != null && !((InternalResource) resource).hasURL()) {
+ this.listener.debug("KnowledgeAgent no resource mapped for rule="
+ + function);
+ }
+ if (autoDiscoverResource) {
+ resource = function.getResource();
+ }
+ this.addDefinitionMapping(resource, function, true);
+ }
+ }
+ }
+
/**
* 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() {
+ public void autoBuildResourceMapping() {
this.listener.debug("KnowledgeAgent building resource map");
- synchronized (this.resourcesMap) {
+ synchronized (this.registeredResources) {
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);
- }
- 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);
- }
-
- 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);
- }
-
- 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);
- }
+ for (Package pkg : rbase.getPackages()) {
+ this.buildResourceMapping(pkg, null, true);
}
}
}
public KnowledgeBase getKnowledgeBase() {
- synchronized (this.resourcesMap) {
+ synchronized (this.registeredResources) {
return this.kbase;
}
}
@@ -453,7 +471,7 @@
*/
public void buildKnowledgeBase(ChangeSetState changeSetState) {
this.listener.debug("KnowledgeAgent rebuilding KnowledgeBase using ChangeSet");
- synchronized (this.resourcesMap) {
+ synchronized (this.registeredResources) {
/*
* Do the following only if we are building a new instance,
@@ -479,6 +497,57 @@
this.listener.debug("KnowledgeAgent finished rebuilding KnowledgeBase using ChangeSet");
}
+ private KnowledgePackageImp createPackageFromResource(Resource resource) {
+ return this.createPackageFromResource(resource, null);
+ }
+
+ private KnowledgePackageImp createPackageFromResource(Resource resource,KnowledgeBuilder kbuilder) {
+
+ if (kbuilder == null){
+ kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
+ }
+
+ if (((InternalResource) resource).getResourceType() != ResourceType.PKG) {
+ kbuilder.add(resource, ((InternalResource) resource).getResourceType());
+ if (kbuilder.hasErrors()) {
+ this.listener.warning(
+ "KnowledgeAgent has KnowledgeBuilder errors ", kbuilder.getErrors());
+ }
+ if (kbuilder.getKnowledgePackages().iterator().hasNext()){
+ return (KnowledgePackageImp) kbuilder.getKnowledgePackages().iterator().next();
+ }
+ return null;
+ } else {
+ // .pks are handled as a special case.
+ InputStream is = null;
+ KnowledgePackageImp kpkg = null;
+ try {
+ is = resource.getInputStream();
+ Object object = DroolsStreamUtils.streamIn(is);
+ if (object instanceof KnowledgePackageImp) {
+ kpkg = ((KnowledgePackageImp) object);
+ } else {
+ kpkg = new KnowledgePackageImp((Package) object);
+ }
+ for (Rule rule : kpkg.pkg.getRules()) {
+ rule.setResource(resource);
+ }
+
+ } catch (Exception ex) {
+ this.listener.exception(new RuntimeException("KnowledgeAgent exception while trying to deserialize KnowledgeDefinitionsPackage ", ex));
+ } finally {
+ try {
+ if (is != null) {
+ is.close();
+ }
+ } catch (IOException e) {
+ this.listener.exception(new RuntimeException("KnowledgeAgent exception while trying to close KnowledgeDefinitionsPackage ", e));
+ }
+ }
+ return kpkg;
+ }
+ }
+
/**
* This method is meant to rebuild the entire KnowledgeBase. Cached
* references outside of this Agent will no longer be valid to the current
@@ -503,7 +572,10 @@
this.kbase = KnowledgeBaseFactory.newKnowledgeBase();
}
- addResourcesToKnowledgeBase(resourcesMap.getAllResources());
+ changeSetState.addedResources.clear();
+ changeSetState.addedResources.addAll(this.registeredResources.getAllResources());
+ addResourcesToKnowledgeBase(changeSetState);
+ //autoBuildResourceMapping();
this.listener.info("KnowledgeAgent new KnowledgeBase now built and in use");
}
@@ -520,7 +592,7 @@
this.listener.warning("KnowledgeAgent incremental build of KnowledgeBase when newInstance is true");
}
// Incrementally rebuild the resources
- synchronized (this.resourcesMap) {
+ synchronized (this.registeredResources) {
this.listener.info("KnowledgeAgent performing an incremental build of the ChangeSet");
// Create the knowledge base if one does not exist
@@ -530,30 +602,53 @@
// Remove all rules from the resources removed and also those
// modified
- for (ResourceMapEntry resourceMapEntry : changeSetState.removedResourceMappings) {
- for (KnowledgeDefinition kd : resourceMapEntry.getKnowledgeDefinitions()) {
+ for (Map.Entry<Resource, Set<KnowledgeDefinition>> entry : changeSetState.removedResourceMappings.entrySet()) {
+ for (KnowledgeDefinition kd : entry.getValue()) {
removeKnowledgeDefinitionFromBase(kd);
}
}
- for (ResourceMapEntry resourceMapEntry : changeSetState.modifiedResourceMappings) {
- for (KnowledgeDefinition kd : resourceMapEntry.getKnowledgeDefinitions()) {
+
+
+
+ for (Map.Entry<Resource, Set<KnowledgeDefinition>> entry : changeSetState.modifiedResourceMappings.entrySet()) {
+
+ KnowledgePackageImp kpkg = createPackageFromResource(entry.getKey());
+
+ if (kpkg == null){
+ continue;
+ }
+
+
+ ResourceDiffProducer rdp = new DefaultResourceDiffProducerImpl();
+ //ResourceDiffProducer rdp = new BinaryResourceDiffProducerImpl();
+
+ ResourceDiffResult diff = rdp.diff(entry.getValue(), kpkg);
+
+ for (KnowledgeDefinition kd : diff.getRemovedDefinitions()) {
removeKnowledgeDefinitionFromBase(kd);
}
- changeSetState.addedResources.add(resourceMapEntry.getResource());
+
+ changeSetState.createdPackages.put(entry.getKey(), diff.getPkg());
+
}
/*
- * Adds both the newly added resources and the modified resources
+ * Compile the newly added resources
*/
- addResourcesToKnowledgeBase(changeSetState.addedResources);
+ for (Resource resource : changeSetState.addedResources) {
+ ///compile the new resource
+ KnowledgePackageImp kpkg = createPackageFromResource(resource);
+ if (kpkg == null){
+ continue;
+ }
+ changeSetState.createdPackages.put(resource, kpkg);
+ }
+ //the added resources were already processed and converted to createdPackages.
+ changeSetState.addedResources.clear();
+ addResourcesToKnowledgeBase(changeSetState);
- //Remove the individual knowledgeDefinitions marked as deleted by the
- //changeset
- for (Resource resource : changeSetState.removedKnowledgeDefinitions.keySet()) {
- removeKnowledgeDefinitionFromBase(changeSetState.removedKnowledgeDefinitions.get(resource));
- }
}
this.listener.info("KnowledgeAgent incremental build of KnowledgeBase finished and in use");
}
@@ -563,22 +658,26 @@
* @param kd
*/
private void removeKnowledgeDefinitionFromBase(KnowledgeDefinition kd) {
- if (kd instanceof Query) {
- // @TODO Queries. The way JavaDialectRuntimeData removes rules
- // doesn't apply to Queries (Even when Query is a subclass of Rule).
- } else if (kd instanceof Rule) {
- Rule rule = (Rule) kd;
- this.listener.debug("KnowledgeAgent removing Rule=" + rule
- + " from package=" + rule.getPackageName());
- this.kbase.removeRule(rule.getPackageName(), rule.getName());
- } else if (kd instanceof Process) {
- 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
+ try {
+ 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) {
+ Function function = (Function) kd;
+ this.kbase.removeFunction(function.getNamespace(), function.getName());
+ }
+ } catch (IllegalArgumentException e) {
+ //it could be possible that a definition does not longer exists
+ //in the kbase.
+ this.listener.warning(e.getMessage());
}
}
@@ -588,63 +687,42 @@
*
* @param resources
*/
- private void addResourcesToKnowledgeBase(Collection<Resource> resources) {
+ private void addResourcesToKnowledgeBase(ChangeSetState changeSetState) {
- KnowledgeBuilder kbuilder = null;
+ KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();;
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);
- 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;
+ for (Resource resource : changeSetState.addedResources) {
+ KnowledgePackageImp createdPackage = this.createPackageFromResource(resource, kbuilder);
+ changeSetState.createdPackages.put(resource, createdPackage);
- } else {
- pkg = (Package) object;
- }
- for (Rule rule : pkg.getRules()) {
- rule.setResource(resource);
- }
+ }
- 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));
- }
+
+ for (Map.Entry<Resource, KnowledgePackage> entry : changeSetState.createdPackages.entrySet()) {
+ // For PKG (.pks) just add them
+ Resource resource = entry.getKey();
+ this.listener.debug("KnowledgeAgent obtaining pkg resource="
+ + resource);
+
+ try {
+ // .pks are handled as a special case.
+ Package pkg = ((KnowledgePackageImp) entry.getValue()).pkg;
+ for (Rule rule : pkg.getRules()) {
+ rule.setResource(resource);
}
+ packages.add(pkg);
+
+ this.buildResourceMapping(pkg, resource);
+ } catch (Exception e) {
+ this.listener.exception(new RuntimeException(
+ "KnowledgeAgent exception while trying to deserialize KnowledgeDefinitionsPackage ",
+ e));
}
}
- if (kbuilder != null) {
+ if (kbuilder
+ != null) {
// Log any errors we come across
if (kbuilder.hasErrors()) {
this.listener.warning(
@@ -671,6 +749,10 @@
*/
public String getName() {
return this.name;
+
+
+
+
}
/**
@@ -695,6 +777,84 @@
}
/**
+ *
+ * @param resource
+ * @param notify
+ * @return
+ */
+ public boolean addResourceMapping(Resource resource, boolean notify) {
+ boolean newMapping = this.registeredResources.createNewResourceEntry(resource);
+
+ if (notify && newMapping) {
+ this.listener.debug("KnowledgeAgent notifier subscribing to resource="
+ + resource);
+ this.notifier.subscribeResourceChangeListener(this,
+ resource);
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Add an resource/definition entry to registeredResources. Optionaly it
+ * adds a listener to the resource added.
+ * @param resource
+ * @param definition
+ * @param notify
+ * @return if the resource/definition didn't exist in registeredResources.
+ */
+ public boolean addDefinitionMapping(Resource resource, KnowledgeDefinition definition, boolean notify) {
+
+ if (resource == null) {
+ listener.warning("KnowledgeAgent: impossible to add a map for a null resource! skiping.");
+ return false;
+ }
+
+ this.listener.debug("KnowledgeAgent mapping resource="
+ + resource + " to KnowledgeDefinition=" + definition);
+
+ boolean isNewResource = this.registeredResources.isResourceMapped(resource);
+
+ boolean isNewDefinition = true;
+
+ if (definition != null) {
+ isNewDefinition = this.registeredResources.putDefinition(resource, definition);
+ }
+
+ if (notify && isNewResource) {
+ this.listener.debug("KnowledgeAgent notifier subscribing to resource="
+ + resource);
+
+ this.notifier.subscribeResourceChangeListener(this,
+ resource);
+ }
+
+ return isNewDefinition;
+ }
+
+ public Set<KnowledgeDefinition> removeResourceMapping(Resource resource,
+ boolean unsubscribe) {
+ this.listener.debug("KnowledgeAgent removing mappings for resource="
+ + resource + " with unsubscribe=" + unsubscribe);
+ Set<KnowledgeDefinition> definitions = this.registeredResources.removeDefinitions(resource);
+
+
+
+
+ if (definitions != null) {
+ if (unsubscribe) {
+ this.listener.debug("KnowledgeAgent notifier unsubscribing to resource="
+ + resource);
+
+ this.notifier.unsubscribeResourceChangeListener(
+ this, resource);
+ }
+ }
+ return definitions;
+
+ }
+
+ /**
* A class to monitor and handle ChangeSets fired by the
* ResourceChangeNotifier on a separate service (or process).
*
@@ -743,252 +903,63 @@
}
}
- /**
- * 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 static class RegisteredResourceMap {
- private final Resource resource;
- private Set<KnowledgeDefinition> knowledgeDefinitions;
+ private Map<Resource, Set<KnowledgeDefinition>> map = new HashMap<Resource, Set<KnowledgeDefinition>>();
- 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>();
- }
-
/**
+ * Creates a new entry for resource with an empty Set<KnowledgeDefinition>.
+ * If the map already contains an entry for the resource, then nothing
+ * is changed.
* @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.
+ * @return true if the resource was not previously mapped.
*/
- 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);
- }
+ public boolean createNewResourceEntry(Resource resource) {
+ if (!this.isResourceMapped(resource)) {
+ this.map.put(resource, new HashSet<KnowledgeDefinition>());
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);
- }
+ public boolean putDefinition(Resource resource, KnowledgeDefinition definition) {
+ Set<KnowledgeDefinition> defList = map.get(resource);
+ if (defList == null) {
+ defList = new HashSet<KnowledgeDefinition>();
+ this.map.put(resource, defList);
+ }
- for (KnowledgeDefinition kd : rsrcMapping.knowledgeDefinitions) {
- this.knowledgeDefinitionMappings.remove(kd);
- }
+ //support for lazy loading
+ if (definition != null) {
+ boolean isNew = defList.add(definition);
+ return isNew;
}
- return rsrcMapping;
+
+ return false;
}
- public Set<Resource> getAllResources() {
- return this.resourceMappings.keySet();
+ public Set<KnowledgeDefinition> removeDefinitions(Resource resource) {
+ return this.map.remove(resource);
}
- /**
- * 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 Set<KnowledgeDefinition> getDefinitions(Resource resource) {
+ return this.getDefinitions(resource, false);
}
- 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;
- }
+ public Set<KnowledgeDefinition> getDefinitions(Resource resource, boolean returnEmptyIfNull) {
+ Set<KnowledgeDefinition> definitions = this.map.get(resource);
+ if (returnEmptyIfNull && definitions == null) {
+ definitions = new HashSet<KnowledgeDefinition>();
}
- return false;
+ return definitions;
}
- /**
- * Removes a resource's knowledge definition from the maps given its name.
- * To find the right knowledge definition, this method uses
- * {@link #getKnowledgeDefinitionByName(org.drools.io.Resource, java.lang.String).
- *
- * <b>Author:<b> Esteban Aliverti.
- *
- * @param resource the resource where the kdefinition will be seached.
- * @param knowledgeDefinitionName the name of the kdefinition.
- * @return The removed kdefinition if it was found and succesfully
- * removed. Oterwise, null.
- */
- public KnowledgeDefinition removeResourceMappingEntry(Resource resource,
- String knowledgeDefinitionName) {
-
- ResourceMapEntry rsrcMapping = this.resourceMappings.get(resource);
-
-
- if (rsrcMapping != null) {
- KnowledgeDefinition foundDefinition = this.getKnowledgeDefinitionByName(resource, knowledgeDefinitionName);
- if (rsrcMapping.getKnowledgeDefinitions().remove(foundDefinition)) {
- this.knowledgeDefinitionMappings.remove(foundDefinition);
- return foundDefinition;
- }
- }
-
-
- return null;
+ public boolean isResourceMapped(Resource resource) {
+ return this.map.containsKey(resource);
}
- /**
- * Return a knowledgeDeinition of a resource fiven its name. If
- * the resource doesn't have a kdefinition with he specified name, null
- * is returned.
- * If the resouce has more than one kdefinition with the given name
- * (according to some tests I made, functions and queries could have
- * the same name), the first kdefinition found is returned. The search
- * order is Rule/Query, Function, TypeDeclaration.
- *
- * <b>Author:<b> Esteban Aliverti.
- *
- * @param resource the resource where the kdefinition will be seached.
- * @param knowledgeDefinitionName the name of the kdefinition.
- * @return the kdefinition with the given name, or null if it doesn't exist.
- *
- */
- private KnowledgeDefinition getKnowledgeDefinitionByName(Resource resource, String knowledgeDefinitionName) {
-
- KnowledgeDefinition foundDefinition = null;
-
- ResourceMapEntry rsrcMapping = this.resourceMappings.get(resource);
- if (rsrcMapping != null) {
-
-
- for (KnowledgeDefinition kd : rsrcMapping.knowledgeDefinitions) {
-
- String currentKDefinitionName = "";
-
- if (kd instanceof Rule) {
- //rules and queries
- currentKDefinitionName = ((Rule) kd).getName();
- } else if (kd instanceof Function) {
- currentKDefinitionName = ((Function) kd).getName();
- } else if (kd instanceof TypeDeclaration) {
- currentKDefinitionName = ((TypeDeclaration) kd).getTypeName();
- }
-
- if (currentKDefinitionName.equals(knowledgeDefinitionName)) {
- foundDefinition = kd;
- break;
- }
-
- }
-
- }
-
- return foundDefinition;
+ public Set<Resource> getAllResources() {
+ return this.map.keySet();
}
}
@@ -1004,6 +975,8 @@
if (this.changeSetNotificationDetector != null) {
this.changeSetNotificationDetector.monitor = false;
+
+
}
}
}
Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/agent/impl/ResourceDiffResult.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/agent/impl/ResourceDiffResult.java (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/agent/impl/ResourceDiffResult.java 2009-12-24 17:54:14 UTC (rev 30813)
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2009 esteban.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * under the License.
+ */
+
+package org.drools.agent.impl;
+
+import java.util.Set;
+import org.drools.definition.KnowledgeDefinition;
+import org.drools.definition.KnowledgePackage;
+
+/**
+ *
+ * @author esteban.aliverti at gmail.com
+ */
+public class ResourceDiffResult {
+ private KnowledgePackage pkg;
+ private Set<KnowledgeDefinition> removedDefinitions;
+
+ public ResourceDiffResult(KnowledgePackage pkg, Set<KnowledgeDefinition> removedDefinitions) {
+ this.pkg = pkg;
+ this.removedDefinitions = removedDefinitions;
+ }
+
+ public KnowledgePackage getPkg() {
+ return pkg;
+ }
+
+ public Set<KnowledgeDefinition> getRemovedDefinitions() {
+ return removedDefinitions;
+ }
+
+}
Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/definitions/impl/KnowledgePackageImp.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/definitions/impl/KnowledgePackageImp.java 2009-12-24 16:09:54 UTC (rev 30812)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/definitions/impl/KnowledgePackageImp.java 2009-12-24 17:54:14 UTC (rev 30813)
@@ -59,4 +59,6 @@
public void writeExternal(ObjectOutput out) throws IOException {
this.pkg.writeExternal( out );
}
+
+
}
Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/impl/KnowledgeBaseImpl.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/impl/KnowledgeBaseImpl.java 2009-12-24 16:09:54 UTC (rev 30812)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/impl/KnowledgeBaseImpl.java 2009-12-24 17:54:14 UTC (rev 30813)
@@ -172,6 +172,12 @@
ruleName );
}
+ public void removeFunction(String packageName,
+ String ruleName) {
+ this.ruleBase.removeFunction( packageName,
+ ruleName );
+ }
+
public void removeProcess(String processId) {
this.ruleBase.removeProcess( processId );
}
Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/io/impl/ChangeSetImpl.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/io/impl/ChangeSetImpl.java 2009-12-24 16:09:54 UTC (rev 30812)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/io/impl/ChangeSetImpl.java 2009-12-24 17:54:14 UTC (rev 30813)
@@ -2,11 +2,8 @@
import java.util.Collection;
import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
import org.drools.ChangeSet;
-import org.drools.definition.KnowledgeDefinition;
import org.drools.io.Resource;
public class ChangeSetImpl implements ChangeSet {
@@ -16,7 +13,7 @@
//Map of removed kdefinitions. The key is the resource and the string is
//the knowledgeDefinition's name.
- private Map<Resource,String> knowledgeDefinitionsRemoved = new HashMap<Resource, String>();
+ private Collection<String> knowledgeDefinitionsRemoved = Collections.<String>emptyList();
public ChangeSetImpl() {
@@ -46,11 +43,11 @@
this.resourcesModified = resourcesModified;
}
- public Map<Resource, String> getKnowledgeDefinitionsRemoved() {
+ public Collection<String> getKnowledgeDefinitionsRemoved() {
return knowledgeDefinitionsRemoved;
}
- public void setKnowledgeDefinitionsRemoved(Map<Resource, String> knowledgeDefinitionsRemoved) {
+ public void setKnowledgeDefinitionsRemoved(Collection<String> knowledgeDefinitionsRemoved) {
this.knowledgeDefinitionsRemoved = knowledgeDefinitionsRemoved;
}
Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/Function.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/Function.java 2009-12-24 16:09:54 UTC (rev 30812)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/Function.java 2009-12-24 17:54:14 UTC (rev 30813)
@@ -10,6 +10,7 @@
public class Function implements KnowledgeDefinition, Dialectable, Externalizable {
private String name;
+ private String namespace;
private String dialect;
private Resource resource;
@@ -17,8 +18,9 @@
}
- public Function(String name,
+ public Function(String namespace, String name,
String dialect) {
+ this.namespace = namespace;
this.name = name;
this.dialect = dialect;
}
@@ -39,6 +41,16 @@
this.resource = resource;
}
+ public String getNamespace() {
+ return namespace;
+ }
+
+ public void setNamespace(String namespace) {
+ this.namespace = namespace;
+ }
+
+
+
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
name = (String)in.readObject();
dialect = (String)in.readObject();
Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/Package.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/Package.java 2009-12-24 16:09:54 UTC (rev 30812)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/Package.java 2009-12-24 17:54:14 UTC (rev 30813)
@@ -33,6 +33,7 @@
import org.drools.base.ClassFieldAccessorStore;
import org.drools.common.DroolsObjectInputStream;
import org.drools.common.DroolsObjectOutputStream;
+import org.drools.definition.KnowledgeDefinition;
import org.drools.definition.process.Process;
import org.drools.definition.type.FactType;
import org.drools.facttemplates.FactTemplate;
@@ -555,4 +556,5 @@
this.classFieldAccessorStore.setClassFieldAccessorCache( classFieldAccessorCache );
}
+
}
\ No newline at end of file
Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/xml/ChangeSetSemanticModule.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/xml/ChangeSetSemanticModule.java 2009-12-24 16:09:54 UTC (rev 30812)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/xml/ChangeSetSemanticModule.java 2009-12-24 17:54:14 UTC (rev 30813)
@@ -6,6 +6,7 @@
import org.drools.xml.changeset.AddHandler;
import org.drools.xml.changeset.ChangeSetHandler;
import org.drools.xml.changeset.DecisionTableConfigurationHandler;
+import org.drools.xml.changeset.DefinitionHandler;
import org.drools.xml.changeset.ModifyHandler;
import org.drools.xml.changeset.RemoveHandler;
import org.drools.xml.changeset.ResourceHandler;
@@ -29,6 +30,9 @@
addHandler( "resource",
new ResourceHandler() );
+
+ addHandler( "definition",
+ new DefinitionHandler() );
addHandler( "decisiontable-conf",
new DecisionTableConfigurationHandler() );
Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/xml/changeset/DefinitionHandler.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/xml/changeset/DefinitionHandler.java (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/xml/changeset/DefinitionHandler.java 2009-12-24 17:54:14 UTC (rev 30813)
@@ -0,0 +1,92 @@
+package org.drools.xml.changeset;
+
+import java.util.Collection;
+import java.util.HashSet;
+
+import org.drools.xml.BaseAbstractHandler;
+import org.drools.xml.ExtensibleXmlParser;
+import org.drools.xml.Handler;
+import org.w3c.dom.Element;
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+
+public class DefinitionHandler extends BaseAbstractHandler
+ implements
+ Handler {
+
+
+ public class DefinitionHandlerData {
+ private String packageName;
+ private String name;
+
+ public DefinitionHandlerData(String packageName, String name) {
+ this.packageName = packageName;
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public String getPackageName() {
+ return packageName;
+ }
+
+
+ }
+
+ public DefinitionHandler() {
+ if ( (this.validParents == null) && (this.validPeers == null) ) {
+ this.validParents = new HashSet(1);
+ this.validParents.add( Collection.class );
+
+ this.validPeers = new HashSet(2);
+ this.validPeers.add( null );
+ this.validPeers.add( DefinitionHandler.DefinitionHandlerData.class );
+
+ this.allowNesting = true;
+ }
+ }
+
+ public Object start(String uri,
+ String localName,
+ Attributes attrs,
+ ExtensibleXmlParser parser) throws SAXException {
+ parser.startElementBuilder( localName,
+ attrs );
+
+
+ String packageName = attrs.getValue( "package" );
+ String name = attrs.getValue( "name" );
+
+ emptyAttributeCheck( localName,
+ "package",
+ packageName,
+ parser );
+
+ emptyAttributeCheck( localName,
+ "name",
+ name,
+ parser );
+ DefinitionHandler.DefinitionHandlerData data = new DefinitionHandlerData(packageName, name);
+
+ return data;
+ }
+
+ public Object end(String uri,
+ String localName,
+ ExtensibleXmlParser parser) throws SAXException {
+ final Element element = parser.endElementBuilder();
+
+ final Collection collection = (Collection) parser.getParent();
+ final DefinitionHandlerData data = ( DefinitionHandlerData ) parser.getCurrent();
+ collection.add( data );
+ return data;
+ }
+
+
+ public Class< ? > generateNodeFor() {
+ return DefinitionHandler.DefinitionHandlerData.class;
+ }
+
+}
Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/xml/changeset/RemoveHandler.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/xml/changeset/RemoveHandler.java 2009-12-24 16:09:54 UTC (rev 30812)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/xml/changeset/RemoveHandler.java 2009-12-24 17:54:14 UTC (rev 30813)
@@ -1,18 +1,12 @@
package org.drools.xml.changeset;
-import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import org.drools.ChangeSet;
-import org.drools.builder.ResourceType;
import org.drools.io.Resource;
import org.drools.io.impl.ChangeSetImpl;
-import org.drools.io.impl.ClassPathResource;
-import org.drools.io.impl.KnowledgeResource;
-import org.drools.io.impl.UrlResource;
-import org.drools.util.StringUtils;
import org.drools.xml.BaseAbstractHandler;
import org.drools.xml.ExtensibleXmlParser;
import org.drools.xml.Handler;
@@ -55,9 +49,32 @@
final Element element = parser.endElementBuilder();
final ChangeSetImpl changeSet = (ChangeSetImpl) parser.getParent();
- final Collection removed = ( Collection ) parser.getCurrent();
- changeSet.setResourcesRemoved( removed );
- return removed;
+
+ Collection<Resource> removedResources = new ArrayList<Resource>();
+ Collection<String> removedDefinitions = new ArrayList<String>();
+
+ for (Object object : ( Collection ) parser.getCurrent()) {
+ if (object instanceof DefinitionHandler.DefinitionHandlerData){
+ DefinitionHandler.DefinitionHandlerData data = (DefinitionHandler.DefinitionHandlerData)object;
+
+ String fullName = data.getPackageName();
+
+ if (fullName == null || fullName.equals("")){
+ fullName = data.getName();
+ }else{
+ fullName += "."+data.getName();
+ }
+
+ removedDefinitions.add(fullName);
+
+ }else if (object instanceof Resource){
+ removedResources.add((Resource)object);
+ }
+ }
+
+ changeSet.setResourcesRemoved( removedResources );
+ changeSet.setKnowledgeDefinitionsRemoved( removedDefinitions );
+ return ( Collection ) parser.getCurrent();
}
More information about the jboss-svn-commits
mailing list