Seam SVN: r12295 - modules/drools/trunk/docs.
by seam-commits@lists.jboss.org
Author: tsurdilovic
Date: 2010-03-26 00:58:26 -0400 (Fri, 26 Mar 2010)
New Revision: 12295
Removed:
modules/drools/trunk/docs/.settings/
Log:
deleted
14 years, 9 months
Seam SVN: r12294 - modules/drools/trunk.
by seam-commits@lists.jboss.org
Author: tsurdilovic
Date: 2010-03-26 00:57:39 -0400 (Fri, 26 Mar 2010)
New Revision: 12294
Removed:
modules/drools/trunk/.project
Log:
Deleted: modules/drools/trunk/.project
===================================================================
--- modules/drools/trunk/.project 2010-03-26 04:57:27 UTC (rev 12293)
+++ modules/drools/trunk/.project 2010-03-26 04:57:39 UTC (rev 12294)
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
- <name>drools</name>
- <comment></comment>
- <projects>
- </projects>
- <buildSpec>
- <buildCommand>
- <name>org.eclipse.wst.common.project.facet.core.builder</name>
- <arguments>
- </arguments>
- </buildCommand>
- <buildCommand>
- <name>org.maven.ide.eclipse.maven2Builder</name>
- <arguments>
- </arguments>
- </buildCommand>
- </buildSpec>
- <natures>
- <nature>org.maven.ide.eclipse.maven2Nature</nature>
- <nature>org.eclipse.wst.common.project.facet.core.nature</nature>
- </natures>
-</projectDescription>
14 years, 9 months
Seam SVN: r12293 - modules/drools/trunk/core.
by seam-commits@lists.jboss.org
Author: tsurdilovic
Date: 2010-03-26 00:57:27 -0400 (Fri, 26 Mar 2010)
New Revision: 12293
Removed:
modules/drools/trunk/core/.classpath
Log:
Deleted: modules/drools/trunk/core/.classpath
===================================================================
--- modules/drools/trunk/core/.classpath 2010-03-26 04:57:07 UTC (rev 12292)
+++ modules/drools/trunk/core/.classpath 2010-03-26 04:57:27 UTC (rev 12293)
@@ -1,9 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<classpath>
- <classpathentry kind="src" output="target/classes" path="src/main/java"/>
- <classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources"/>
- <classpathentry kind="src" output="target/test-classes" path="src/test/java"/>
- <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
- <classpathentry kind="con" path="org.maven.ide.eclipse.MAVEN2_CLASSPATH_CONTAINER"/>
- <classpathentry kind="output" path="target/classes"/>
-</classpath>
14 years, 9 months
Seam SVN: r12291 - in modules/drools: trunk and 17 other directories.
by seam-commits@lists.jboss.org
Author: tsurdilovic
Date: 2010-03-26 00:56:04 -0400 (Fri, 26 Mar 2010)
New Revision: 12291
Added:
modules/drools/branches/
modules/drools/tags/
modules/drools/trunk/
modules/drools/trunk/.project
modules/drools/trunk/.settings/
modules/drools/trunk/.settings/org.maven.ide.eclipse.prefs
modules/drools/trunk/assembly.xml
modules/drools/trunk/core/
modules/drools/trunk/core/.classpath
modules/drools/trunk/core/.project
modules/drools/trunk/core/.settings/
modules/drools/trunk/core/.settings/org.eclipse.jdt.core.prefs
modules/drools/trunk/core/.settings/org.maven.ide.eclipse.prefs
modules/drools/trunk/core/pom.xml
modules/drools/trunk/core/src/
modules/drools/trunk/core/src/main/
modules/drools/trunk/core/src/main/java/
modules/drools/trunk/core/src/main/java/META-INF/
modules/drools/trunk/core/src/main/java/META-INF/MANIFEST.MF
modules/drools/trunk/core/src/main/java/org/
modules/drools/trunk/core/src/main/java/org/jboss/
modules/drools/trunk/core/src/main/java/org/jboss/seam/
modules/drools/trunk/core/src/main/java/org/jboss/seam/drools/
modules/drools/trunk/core/src/main/java/org/jboss/seam/drools/FactProvider.java
modules/drools/trunk/core/src/main/java/org/jboss/seam/drools/KnowledgeBaseManager.java
modules/drools/trunk/core/src/main/java/org/jboss/seam/drools/KnowledgeBaseManagerConfig.java
modules/drools/trunk/core/src/main/java/org/jboss/seam/drools/KnowledgeSessionManager.java
modules/drools/trunk/core/src/main/java/org/jboss/seam/drools/KnowledgeSessionManagerConfig.java
modules/drools/trunk/core/src/main/java/org/jboss/seam/drools/TemplateDataProvider.java
modules/drools/trunk/core/src/main/java/org/jboss/seam/drools/events/
modules/drools/trunk/core/src/main/java/org/jboss/seam/drools/events/KnowledgeBuilderErrorsEvent.java
modules/drools/trunk/core/src/main/java/org/jboss/seam/drools/events/KnowledgeSessionCreatedEvent.java
modules/drools/trunk/core/src/main/java/org/jboss/seam/drools/events/RuleResourceAddedEvent.java
modules/drools/trunk/core/src/main/resources/
modules/drools/trunk/core/src/main/resources/META-INF/
modules/drools/trunk/core/src/test/
modules/drools/trunk/core/src/test/java/
modules/drools/trunk/distribution.txt
modules/drools/trunk/docs/
modules/drools/trunk/docs/.classpath
modules/drools/trunk/docs/.project
modules/drools/trunk/docs/.settings/
modules/drools/trunk/docs/.settings/org.eclipse.jdt.core.prefs
modules/drools/trunk/docs/.settings/org.maven.ide.eclipse.prefs
modules/drools/trunk/docs/README.TXT
modules/drools/trunk/docs/drools-reference.pdf
modules/drools/trunk/docs/en-US/
modules/drools/trunk/docs/en-US/drools-general.xml
modules/drools/trunk/docs/en-US/drools-model.xml
modules/drools/trunk/docs/en-US/images/
modules/drools/trunk/docs/en-US/master.xml
modules/drools/trunk/docs/pom.xml
modules/drools/trunk/examples/
modules/drools/trunk/lgpl.txt
modules/drools/trunk/pom.xml
modules/drools/trunk/readme.txt
Log:
Drools module structure
Added: modules/drools/trunk/.project
===================================================================
--- modules/drools/trunk/.project (rev 0)
+++ modules/drools/trunk/.project 2010-03-26 04:56:04 UTC (rev 12291)
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>drools</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.wst.common.project.facet.core.builder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.maven.ide.eclipse.maven2Builder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.maven.ide.eclipse.maven2Nature</nature>
+ <nature>org.eclipse.wst.common.project.facet.core.nature</nature>
+ </natures>
+</projectDescription>
Added: modules/drools/trunk/.settings/org.maven.ide.eclipse.prefs
===================================================================
--- modules/drools/trunk/.settings/org.maven.ide.eclipse.prefs (rev 0)
+++ modules/drools/trunk/.settings/org.maven.ide.eclipse.prefs 2010-03-26 04:56:04 UTC (rev 12291)
@@ -0,0 +1,9 @@
+#Fri Mar 26 00:04:15 EDT 2010
+activeProfiles=
+eclipse.preferences.version=1
+fullBuildGoals=process-test-resources
+includeModules=false
+resolveWorkspaceProjects=true
+resourceFilterGoals=process-resources resources\:testResources
+skipCompilerPlugin=true
+version=1
Added: modules/drools/trunk/assembly.xml
===================================================================
--- modules/drools/trunk/assembly.xml (rev 0)
+++ modules/drools/trunk/assembly.xml 2010-03-26 04:56:04 UTC (rev 12291)
@@ -0,0 +1,69 @@
+<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
+ <id>bin</id>
+ <formats>
+ <format>zip</format>
+ </formats>
+ <includeBaseDirectory>false</includeBaseDirectory>
+
+ <fileSets>
+ <fileSet>
+ <directory>core/target/site/apidocs</directory>
+ <outputDirectory>seam-drools/doc/api</outputDirectory>
+ <includes>
+ <include>**</include>
+ </includes>
+ </fileSet>
+
+ <fileSet>
+ <directory>examples</directory>
+ <outputDirectory>seam-drools/examples</outputDirectory>
+ <useDefaultExcludes>true</useDefaultExcludes>
+ <includes>
+ <!-- <include>seamspace/pom.xml</include>
+ <include>seamspace/src/**</include> -->
+ </includes>
+ </fileSet>
+
+ <fileSet>
+ <directory>.</directory>
+ <outputDirectory>seam-drools</outputDirectory>
+ <includes>
+ <include>readme.txt</include>
+ <include>lgpl.txt</include>
+ </includes>
+ </fileSet>
+
+ <fileSet>
+ <directory>core/src/main/java</directory>
+ <outputDirectory>seam-drools/source</outputDirectory>
+ <includes>
+ <include>**</include>
+ </includes>
+ </fileSet>
+ </fileSets>
+
+ <moduleSets>
+ <moduleSet>
+ <includes>
+ <include>org.jboss.seam.drools:seam-drools-core:jar</include>
+ </includes>
+ <binaries>
+ <outputDirectory>seam-drools/lib</outputDirectory>
+ <unpack>false</unpack>
+ </binaries>
+ </moduleSet>
+
+ <moduleSet>
+ <includes>
+ <include>org.jboss.seam.drools:seam-drools-reference-guide</include>
+ </includes>
+ <binaries>
+ <outputDirectory>seam-drools/doc/reference</outputDirectory>
+ <unpack>true</unpack>
+ </binaries>
+ </moduleSet>
+
+ </moduleSets>
+</assembly>
Added: modules/drools/trunk/core/.classpath
===================================================================
--- modules/drools/trunk/core/.classpath (rev 0)
+++ modules/drools/trunk/core/.classpath 2010-03-26 04:56:04 UTC (rev 12291)
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="src" output="target/classes" path="src/main/java"/>
+ <classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources"/>
+ <classpathentry kind="src" output="target/test-classes" path="src/test/java"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+ <classpathentry kind="con" path="org.maven.ide.eclipse.MAVEN2_CLASSPATH_CONTAINER"/>
+ <classpathentry kind="output" path="target/classes"/>
+</classpath>
Added: modules/drools/trunk/core/.project
===================================================================
--- modules/drools/trunk/core/.project (rev 0)
+++ modules/drools/trunk/core/.project 2010-03-26 04:56:04 UTC (rev 12291)
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>seam-drools-core</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.wst.common.project.facet.core.builder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.maven.ide.eclipse.maven2Builder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ <nature>org.maven.ide.eclipse.maven2Nature</nature>
+ <nature>org.eclipse.wst.common.project.facet.core.nature</nature>
+ </natures>
+</projectDescription>
Added: modules/drools/trunk/core/.settings/org.eclipse.jdt.core.prefs
===================================================================
--- modules/drools/trunk/core/.settings/org.eclipse.jdt.core.prefs (rev 0)
+++ modules/drools/trunk/core/.settings/org.eclipse.jdt.core.prefs 2010-03-26 04:56:04 UTC (rev 12291)
@@ -0,0 +1,6 @@
+#Fri Mar 26 00:27:07 EDT 2010
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
+org.eclipse.jdt.core.compiler.source=1.5
Added: modules/drools/trunk/core/.settings/org.maven.ide.eclipse.prefs
===================================================================
--- modules/drools/trunk/core/.settings/org.maven.ide.eclipse.prefs (rev 0)
+++ modules/drools/trunk/core/.settings/org.maven.ide.eclipse.prefs 2010-03-26 04:56:04 UTC (rev 12291)
@@ -0,0 +1,9 @@
+#Thu Mar 25 23:57:23 EDT 2010
+activeProfiles=
+eclipse.preferences.version=1
+fullBuildGoals=process-test-resources
+includeModules=false
+resolveWorkspaceProjects=true
+resourceFilterGoals=process-resources resources\:testResources
+skipCompilerPlugin=true
+version=1
Added: modules/drools/trunk/core/pom.xml
===================================================================
--- modules/drools/trunk/core/pom.xml (rev 0)
+++ modules/drools/trunk/core/pom.xml 2010-03-26 04:56:04 UTC (rev 12291)
@@ -0,0 +1,68 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.jboss.seam.drools</groupId>
+ <artifactId>seam-drools-parent</artifactId>
+ <version>3.0.0-SNAPSHOT</version>
+ </parent>
+
+ <groupId>org.jboss.seam.drools</groupId>
+ <artifactId>seam-drools-core</artifactId>
+ <version>3.0.0-SNAPSHOT</version>
+ <packaging>jar</packaging>
+ <name>Seam Drools Core</name>
+
+ <dependencies>
+ <dependency>
+ <groupId>javax.el</groupId>
+ <artifactId>el-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>javax.validation</groupId>
+ <artifactId>validation-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>javax.enterprise</groupId>
+ <artifactId>cdi-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.drools</groupId>
+ <artifactId>drools-core</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.drools</groupId>
+ <artifactId>drools-compiler</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.drools</groupId>
+ <artifactId>drools-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.drools</groupId>
+ <artifactId>drools-templates</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.drools</groupId>
+ <artifactId>drools-decisiontables</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.drools</groupId>
+ <artifactId>drools-workitems</artifactId>
+ </dependency>
+ </dependencies>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-javadoc-plugin</artifactId>
+ <version>2.6.1</version>
+ </plugin>
+ </plugins>
+ </build>
+
+</project>
Added: modules/drools/trunk/core/src/main/java/META-INF/MANIFEST.MF
===================================================================
--- modules/drools/trunk/core/src/main/java/META-INF/MANIFEST.MF (rev 0)
+++ modules/drools/trunk/core/src/main/java/META-INF/MANIFEST.MF 2010-03-26 04:56:04 UTC (rev 12291)
@@ -0,0 +1,2 @@
+Manifest-Version: 1.0
+Class-Path:
Added: modules/drools/trunk/core/src/main/java/org/jboss/seam/drools/FactProvider.java
===================================================================
--- modules/drools/trunk/core/src/main/java/org/jboss/seam/drools/FactProvider.java (rev 0)
+++ modules/drools/trunk/core/src/main/java/org/jboss/seam/drools/FactProvider.java 2010-03-26 04:56:04 UTC (rev 12291)
@@ -0,0 +1,20 @@
+package org.jboss.seam.drools;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Interface for fact providers.
+ *
+ * @author Tihomir Surdilovic
+ *
+ */
+public interface FactProvider
+{
+ public List<Object> getFacts();
+ public void setFacts(List<Object> facts);
+
+ public Map<String, Object> getGlobals();
+ public void setGlobals(Map<String, Object> globals);
+
+}
\ No newline at end of file
Added: modules/drools/trunk/core/src/main/java/org/jboss/seam/drools/KnowledgeBaseManager.java
===================================================================
--- modules/drools/trunk/core/src/main/java/org/jboss/seam/drools/KnowledgeBaseManager.java (rev 0)
+++ modules/drools/trunk/core/src/main/java/org/jboss/seam/drools/KnowledgeBaseManager.java 2010-03-26 04:56:04 UTC (rev 12291)
@@ -0,0 +1,207 @@
+package org.jboss.seam.drools;
+
+import java.io.InputStream;
+import java.io.Reader;
+import java.io.StringReader;
+import java.util.Properties;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.enterprise.inject.Disposes;
+import javax.enterprise.inject.Produces;
+import javax.enterprise.inject.spi.Bean;
+import javax.enterprise.inject.spi.BeanManager;
+import javax.inject.Inject;
+import javax.security.auth.login.Configuration;
+
+import org.drools.KnowledgeBase;
+import org.drools.KnowledgeBaseConfiguration;
+import org.drools.KnowledgeBaseFactory;
+import org.drools.builder.KnowledgeBuilder;
+import org.drools.builder.KnowledgeBuilderConfiguration;
+import org.drools.builder.KnowledgeBuilderError;
+import org.drools.builder.KnowledgeBuilderErrors;
+import org.drools.builder.KnowledgeBuilderFactory;
+import org.drools.builder.ResourceType;
+import org.drools.event.knowledgebase.KnowledgeBaseEventListener;
+import org.drools.io.ResourceFactory;
+import org.drools.template.ObjectDataCompiler;
+import org.jboss.seam.drools.events.KnowledgeBuilderErrorsEvent;
+import org.jboss.seam.drools.events.RuleResourceAddedEvent;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Manager component for a Drools KnowledgeBase.
+ *
+ * @author Tihomir Surdilovic
+ */
+public class KnowledgeBaseManager
+{
+ private static final Logger log = LoggerFactory.getLogger(KnowledgeBaseManager.class);
+
+ private KnowledgeBaseManagerConfig kbaseManagerConfig;
+
+ @Inject
+ BeanManager manager;
+
+ @Inject
+ public KnowledgeBaseManager(KnowledgeBaseManagerConfig kbaseManagerConfig) {
+ this.kbaseManagerConfig = kbaseManagerConfig;
+ }
+
+ @Produces
+ @ApplicationScoped
+ public KnowledgeBase createKBase() throws Exception
+ {
+ KnowledgeBase kbase;
+ KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder(getKnowledgeBuilderConfiguration());
+
+ for (String nextResource : kbaseManagerConfig.getRuleResources())
+ {
+ addResource(kbuilder, nextResource);
+ }
+
+ KnowledgeBuilderErrors kbuildererrors = kbuilder.getErrors();
+ if (kbuildererrors.size() > 0)
+ {
+ for (KnowledgeBuilderError kbuildererror : kbuildererrors)
+ {
+ log.error(kbuildererror.getMessage());
+ }
+ manager.fireEvent(new KnowledgeBuilderErrorsEvent(kbuildererrors));
+ }
+
+ kbase = KnowledgeBaseFactory.newKnowledgeBase(getKnowledgeBaseConfiguration());
+ kbase.addKnowledgePackages(kbuilder.getKnowledgePackages());
+
+ if (kbaseManagerConfig.getEventListeners() != null)
+ {
+ for (String eventListener : kbaseManagerConfig.getEventListeners())
+ {
+ addEventListener(kbase, eventListener);
+ }
+ }
+ return kbase;
+ }
+
+ public void disposeKBase(@Disposes KnowledgeBase kbase)
+ {
+ kbase = null;
+ }
+
+ private void addEventListener(org.drools.KnowledgeBase kbase, String eventListener) {
+ try {
+ @SuppressWarnings("unchecked")
+ Class eventListenerClass = Class.forName(eventListener);
+ Object eventListenerObject = eventListenerClass.newInstance();
+
+ if(eventListenerObject instanceof KnowledgeBaseEventListener) {
+ kbase.addEventListener((KnowledgeBaseEventListener) eventListenerObject);
+ } else {
+ log.debug("Event Listener " + eventListener + " is not of type KnowledgeBaseEventListener");
+ }
+ } catch(Exception e) {
+ log.error("Error adding event listener " + e.getMessage());
+ }
+ }
+
+ protected void addResource(KnowledgeBuilder kbuilder, String resource) throws Exception
+ {
+ if(KnowledgeBaseManagerConfig.isValidResource(resource)) {
+ ResourceType resourceType = ResourceType.getResourceType(KnowledgeBaseManagerConfig.getResourceType(resource));
+ if(KnowledgeBaseManagerConfig.isRuleTemplate(resource)) {
+ @SuppressWarnings("unchecked")
+ Bean<TemplateDataProvider> templateDataProviderBean = (Bean<TemplateDataProvider>) manager.getBeans(KnowledgeBaseManagerConfig.getTemplateData(resource)).iterator().next();
+
+ TemplateDataProvider templateDataProvider = (TemplateDataProvider) manager.getReference(templateDataProviderBean, Configuration.class, manager.createCreationalContext(templateDataProviderBean));
+
+ InputStream templateStream = this.getClass().getClassLoader().getResourceAsStream(KnowledgeBaseManagerConfig.getRuleResource(resource));
+ if (templateStream == null)
+ {
+ throw new IllegalStateException("Could not locate rule resource: " + KnowledgeBaseManagerConfig.getRuleResource(resource));
+ }
+
+ ObjectDataCompiler converter = new ObjectDataCompiler();
+ String drl = converter.compile(templateDataProvider.getTemplateData(), templateStream);
+ templateStream.close();
+ log.debug("Generated following DRL from template: " + drl);
+ Reader rdr = new StringReader(drl);
+
+ kbuilder.add(ResourceFactory.newReaderResource(rdr), resourceType);
+ } else {
+ if (KnowledgeBaseManagerConfig.getResourcePath(resource).equals(KnowledgeBaseManagerConfig.RESOURCE_TYPE_URL))
+ {
+ kbuilder.add(ResourceFactory.newUrlResource(KnowledgeBaseManagerConfig.getRuleResource(resource)), resourceType);
+ manager.fireEvent(new RuleResourceAddedEvent(KnowledgeBaseManagerConfig.getRuleResource(resource)));
+ }
+ else if (KnowledgeBaseManagerConfig.getResourcePath(resource).equals(KnowledgeBaseManagerConfig.RESOURCE_TYPE_FILE))
+ {
+ kbuilder.add(ResourceFactory.newFileResource(KnowledgeBaseManagerConfig.getRuleResource(resource)), resourceType);
+ manager.fireEvent(new RuleResourceAddedEvent(KnowledgeBaseManagerConfig.getRuleResource(resource)));
+ }
+ else if (KnowledgeBaseManagerConfig.getResourcePath(resource).equals(KnowledgeBaseManagerConfig.RESOURCE_TYPE_CLASSPATH))
+ {
+ kbuilder.add(ResourceFactory.newClassPathResource(KnowledgeBaseManagerConfig.getRuleResource(resource)), resourceType);
+ manager.fireEvent(new RuleResourceAddedEvent(KnowledgeBaseManagerConfig.getRuleResource(resource)));
+ }
+ else
+ {
+ log.error("Invalid resource path: " + KnowledgeBaseManagerConfig.getResourcePath(resource));
+ }
+ }
+ } else {
+ log.error("Invalid resource definition: " + resource);
+ }
+ }
+
+ public KnowledgeBuilderConfiguration getKnowledgeBuilderConfiguration() throws Exception
+ {
+ KnowledgeBuilderConfiguration kbuilderconfig = KnowledgeBuilderFactory.newKnowledgeBuilderConfiguration();
+ if(kbaseManagerConfig.getKnowledgeBuilderConfigProp() != null) {
+ kbuilderconfig = KnowledgeBuilderFactory.newKnowledgeBuilderConfiguration(kbaseManagerConfig.getKnowledgeBuilderConfigProp(), null);
+ log.debug("KnowledgeBuilderConfiguration loaded: " + kbaseManagerConfig.getKnowledgeBuilderConfigProp());
+ } else {
+ // Only allow resource for .properties files
+ if (kbaseManagerConfig.getKnowledgeBuilderConfig() != null && kbaseManagerConfig.getKnowledgeBuilderConfig().endsWith(".properties"))
+ {
+ Properties kbuilderProp = new Properties();
+ InputStream in = this.getClass().getClassLoader().getResourceAsStream(kbaseManagerConfig.getKnowledgeBuilderConfig());
+ if (in == null)
+ {
+ throw new IllegalStateException("Could not locate knowledgeBuilderConfig: " + kbaseManagerConfig.getKnowledgeBuilderConfig());
+ }
+ kbuilderProp.load(in);
+ in.close();
+ kbuilderconfig = KnowledgeBuilderFactory.newKnowledgeBuilderConfiguration(kbuilderProp, null);
+ log.debug("KnowledgeBuilderConfiguration loaded: " + kbaseManagerConfig.getKnowledgeBuilderConfig());
+ }
+ }
+ return kbuilderconfig;
+ }
+
+ public KnowledgeBaseConfiguration getKnowledgeBaseConfiguration() throws Exception
+ {
+ KnowledgeBaseConfiguration kbaseconfig = KnowledgeBaseFactory.newKnowledgeBaseConfiguration();
+
+ if(kbaseManagerConfig.getKnowledgeBaseConfigProp() != null) {
+ kbaseconfig = KnowledgeBaseFactory.newKnowledgeBaseConfiguration(kbaseManagerConfig.getKnowledgeBaseConfigProp(), null);
+ log.debug("KnowledgeBaseConfiguration loaded: " + kbaseManagerConfig.getKnowledgeBaseConfigProp());
+ } else {
+ // Only allow resource for .properties files
+ if (kbaseManagerConfig.getKnowledgeBaseConfig() != null && kbaseManagerConfig.getKnowledgeBaseConfig().endsWith(".properties"))
+ {
+ Properties kbaseProp = new Properties();
+ InputStream in = this.getClass().getClassLoader().getResourceAsStream(kbaseManagerConfig.getKnowledgeBaseConfig());
+ if (in == null)
+ {
+ throw new IllegalStateException("Could not locate knowledgeBaseConfig: " + kbaseManagerConfig.getKnowledgeBaseConfig());
+ }
+ kbaseProp.load(in);
+ in.close();
+ kbaseconfig = KnowledgeBaseFactory.newKnowledgeBaseConfiguration(kbaseProp, null);
+ log.debug("KnowledgeBaseConfiguration loaded: " + kbaseManagerConfig.getKnowledgeBaseConfig());
+ }
+ }
+ return kbaseconfig;
+ }
+}
\ No newline at end of file
Added: modules/drools/trunk/core/src/main/java/org/jboss/seam/drools/KnowledgeBaseManagerConfig.java
===================================================================
--- modules/drools/trunk/core/src/main/java/org/jboss/seam/drools/KnowledgeBaseManagerConfig.java (rev 0)
+++ modules/drools/trunk/core/src/main/java/org/jboss/seam/drools/KnowledgeBaseManagerConfig.java 2010-03-26 04:56:04 UTC (rev 12291)
@@ -0,0 +1,116 @@
+package org.jboss.seam.drools;
+
+import java.util.Properties;
+import java.util.regex.Pattern;
+
+/**
+ * KnowledgeBaseManager Configuration.
+ *
+ * @author Tihomir Surdilovic
+ */
+public class KnowledgeBaseManagerConfig
+{
+ private static final Pattern DIVIDER = Pattern.compile(";");
+ private static final int RESOURCE_PATH = 0;
+ private static final int RESOURCE = 1;
+ private static final int RESOURCE_TYPE = 2;
+ private static final int RESOURCE_TEMPLATE_DATA = 3;
+
+ public static final String RESOURCE_TYPE_URL = "url";
+ public static final String RESOURCE_TYPE_FILE = "file";
+ public static final String RESOURCE_TYPE_CLASSPATH = "classpath";
+
+ private String knowledgeBuilderConfig;
+ private String knowledgeBaseConfig;
+ private Properties knowledgeBuilderConfigProp;
+ private Properties knowledgeBaseConfigProp;
+ private String[] ruleResources;
+ private String[] eventListeners;
+
+ public static boolean isValidResource(String resource) {
+ return DIVIDER.split(resource.trim()).length >= 3;
+ }
+
+ public static boolean isRuleTemplate(String resource) {
+ return DIVIDER.split(resource.trim()).length == 4;
+ }
+
+ public static String getResourceType(String resource) {
+ return DIVIDER.split(resource.trim())[RESOURCE_TYPE];
+ }
+
+ public static String getRuleResource(String resource) {
+ return DIVIDER.split(resource.trim())[RESOURCE];
+ }
+
+ public static String getTemplateData(String resource) {
+ return DIVIDER.split(resource.trim())[RESOURCE_TEMPLATE_DATA];
+ }
+
+ public static String getResourcePath(String resource) {
+ return DIVIDER.split(resource.trim())[RESOURCE_PATH];
+ }
+
+ public String getKnowledgeBuilderConfig()
+ {
+ return knowledgeBuilderConfig;
+ }
+
+ public void setKnowledgeBuilderConfig(String knowledgeBuilderConfig)
+ {
+ this.knowledgeBuilderConfig = knowledgeBuilderConfig;
+ }
+
+ public String getKnowledgeBaseConfig()
+ {
+ return knowledgeBaseConfig;
+ }
+
+ public void setKnowledgeBaseConfig(String knowledgeBaseConfig)
+ {
+ this.knowledgeBaseConfig = knowledgeBaseConfig;
+ }
+
+ public String[] getRuleResources()
+ {
+ return ruleResources;
+ }
+
+ public void setRuleResources(String[] ruleResources)
+ {
+ this.ruleResources = ruleResources;
+ }
+
+ public String[] getEventListeners()
+ {
+ return eventListeners;
+ }
+
+ public void setEventListeners(String[] eventListeners)
+ {
+ this.eventListeners = eventListeners;
+ }
+
+ public Properties getKnowledgeBuilderConfigProp()
+ {
+ return knowledgeBuilderConfigProp;
+ }
+
+ public void setKnowledgeBuilderConfigProp(Properties knowledgeBuilderConfigProp)
+ {
+ this.knowledgeBuilderConfigProp = knowledgeBuilderConfigProp;
+ }
+
+ public Properties getKnowledgeBaseConfigProp()
+ {
+ return knowledgeBaseConfigProp;
+ }
+
+ public void setKnowledgeBaseConfigProp(Properties knowledgeBaseConfigProp)
+ {
+ this.knowledgeBaseConfigProp = knowledgeBaseConfigProp;
+ }
+
+
+
+}
Added: modules/drools/trunk/core/src/main/java/org/jboss/seam/drools/KnowledgeSessionManager.java
===================================================================
--- modules/drools/trunk/core/src/main/java/org/jboss/seam/drools/KnowledgeSessionManager.java (rev 0)
+++ modules/drools/trunk/core/src/main/java/org/jboss/seam/drools/KnowledgeSessionManager.java 2010-03-26 04:56:04 UTC (rev 12291)
@@ -0,0 +1,186 @@
+package org.jboss.seam.drools;
+
+import java.io.InputStream;
+import java.util.Hashtable;
+import java.util.Map;
+import java.util.Properties;
+
+import java.lang.annotation.Annotation;
+import javax.enterprise.inject.Any;
+import javax.enterprise.inject.Disposes;
+import javax.enterprise.inject.Instance;
+import javax.enterprise.inject.Produces;
+import javax.enterprise.inject.spi.Bean;
+import javax.enterprise.inject.spi.BeanManager;
+import javax.enterprise.inject.spi.InjectionPoint;
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.security.auth.login.Configuration;
+
+import org.drools.KnowledgeBase;
+import org.drools.KnowledgeBaseFactory;
+import org.drools.event.process.ProcessEventListener;
+import org.drools.event.rule.AgendaEventListener;
+import org.drools.event.rule.WorkingMemoryEventListener;
+import org.drools.logger.KnowledgeRuntimeLogger;
+import org.drools.logger.KnowledgeRuntimeLoggerFactory;
+import org.drools.runtime.KnowledgeSessionConfiguration;
+import org.drools.runtime.StatefulKnowledgeSession;
+import org.drools.runtime.StatelessKnowledgeSession;
+import org.drools.runtime.process.WorkItemHandler;
+import org.jboss.seam.drools.events.KnowledgeSessionCreatedEvent;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Manager component for a Drools Knowledge Sessions.
+ *
+ * @author Tihomir Surdilovic
+ */
+public class KnowledgeSessionManager
+{
+ private static final Logger log = LoggerFactory.getLogger(KnowledgeSessionManager.class);
+
+ private KnowledgeSessionManagerConfig ksessionManagerConfig;
+ private Map<Integer, KnowledgeRuntimeLogger> statefulKnowledgeLoggers = new Hashtable<Integer, KnowledgeRuntimeLogger>();
+
+ @Inject
+ BeanManager manager;
+
+ @Inject
+ public KnowledgeSessionManager(KnowledgeSessionManagerConfig ksessionManagerConfig)
+ {
+ this.ksessionManagerConfig = ksessionManagerConfig;
+ }
+
+ @Produces
+ @Any
+ public StatefulKnowledgeSession getStatefulSession(InjectionPoint ip, Instance<KnowledgeBase> kbase) throws Exception
+ {
+ StatefulKnowledgeSession ksession = kbase.select(ip.getQualifiers().toArray(new Annotation[0])).get().newStatefulKnowledgeSession(getKSessionConfig(), null);
+ addEventListeners(ksession);
+ addWorkItemHandlers(ksession);
+ addAuditLog(ksession);
+ manager.fireEvent(new KnowledgeSessionCreatedEvent(ksession.getId()));
+ return ksession;
+ }
+
+ public void disposeStatefulSession(@Disposes StatefulKnowledgeSession statefulSession)
+ {
+ if (statefulKnowledgeLoggers.get(statefulSession.getId()) != null)
+ {
+ statefulKnowledgeLoggers.get(statefulSession.getId()).close();
+ }
+ statefulSession.dispose();
+ }
+
+ @Produces
+ @Any
+ public StatelessKnowledgeSession getStatelessSession(InjectionPoint ip, Instance<KnowledgeBase> kbase) throws Exception
+ {
+ StatelessKnowledgeSession ksession = kbase.select(ip.getQualifiers().toArray(new Annotation[0])).get().newStatelessKnowledgeSession(getKSessionConfig());
+ addEventListeners(ksession);
+ manager.fireEvent(new KnowledgeSessionCreatedEvent(-1));
+ return ksession;
+ }
+
+ private KnowledgeSessionConfiguration getKSessionConfig() throws Exception
+ {
+ KnowledgeSessionConfiguration ksessionConfig = KnowledgeBaseFactory.newKnowledgeSessionConfiguration();
+ if(ksessionManagerConfig.getKnowledgeSessionConfigProp() != null) {
+ ksessionConfig = KnowledgeBaseFactory.newKnowledgeSessionConfiguration(ksessionManagerConfig.getKnowledgeSessionConfigProp());
+ } else {
+ // Only allow resource for .properties files
+ if (ksessionManagerConfig.getKnowledgeSessionConfig() != null && ksessionManagerConfig.getKnowledgeSessionConfig().endsWith(".properties"))
+ {
+ Properties ksessionProp = new Properties();
+ InputStream in = this.getClass().getClassLoader().getResourceAsStream(ksessionManagerConfig.getKnowledgeSessionConfig());
+ if (in == null)
+ {
+ throw new IllegalStateException("Could not locate knowledgeSessionrConfig: " + ksessionManagerConfig.getKnowledgeSessionConfig());
+ }
+ ksessionProp.load(in);
+ in.close();
+ ksessionConfig = KnowledgeBaseFactory.newKnowledgeSessionConfiguration(ksessionProp);
+ log.debug("KnowledgeSessionConfiguration loaded: " + ksessionManagerConfig.getKnowledgeSessionConfig());
+ }
+ }
+ return ksessionConfig;
+ }
+
+
+ private void addAuditLog(StatefulKnowledgeSession ksession) throws Exception {
+ if(ksessionManagerConfig.getAuditLog() != null) {
+ if(KnowledgeSessionManagerConfig.isFileLogger(ksessionManagerConfig.getAuditLog())) {
+ String logName = KnowledgeSessionManagerConfig.getFileLoggerPath(ksessionManagerConfig.getAuditLog()) + System.currentTimeMillis();
+ KnowledgeRuntimeLogger krLogger = KnowledgeRuntimeLoggerFactory.newFileLogger(ksession, logName);
+ statefulKnowledgeLoggers.put(ksession.getId(), krLogger);
+ } else if(KnowledgeSessionManagerConfig.isConsoleLogger(ksessionManagerConfig.getAuditLog())) {
+ KnowledgeRuntimeLogger krLogger = KnowledgeRuntimeLoggerFactory.newConsoleLogger(ksession);
+ statefulKnowledgeLoggers.put(ksession.getId(), krLogger);
+ } else if(KnowledgeSessionManagerConfig.isThreadedLogger(ksessionManagerConfig.getAuditLog())) {
+ String logName = KnowledgeSessionManagerConfig.getThreadedLoggerPath(ksessionManagerConfig.getAuditLog()) + System.currentTimeMillis();
+ int interval = KnowledgeSessionManagerConfig.getThreadedLoggerInterval(ksessionManagerConfig.getAuditLog());
+ KnowledgeRuntimeLogger krLogger = KnowledgeRuntimeLoggerFactory.newThreadedFileLogger(ksession, logName, interval);
+ statefulKnowledgeLoggers.put(ksession.getId(), krLogger);
+ } else {
+ log.warn("Invalid logger specified: " + ksessionManagerConfig.getAuditLog());
+ }
+ }
+ }
+
+ public void addEventListeners(StatefulKnowledgeSession ksession) throws Exception {
+ if(ksessionManagerConfig.getEventListeners() != null) {
+ for(String eventListener : ksessionManagerConfig.getEventListeners()) {
+ Class eventListenerClass = Class.forName(eventListener);
+ Object eventListenerObject = eventListenerClass.newInstance();
+
+ if(eventListenerObject instanceof WorkingMemoryEventListener) {
+ ksession.addEventListener((WorkingMemoryEventListener) eventListenerObject);
+ } else if(eventListenerObject instanceof AgendaEventListener) {
+ ksession.addEventListener((AgendaEventListener) eventListenerObject);
+ } else if(eventListenerObject instanceof ProcessEventListener) {
+ ksession.addEventListener((ProcessEventListener) eventListenerObject);
+ } else {
+ log.debug("Invalid Event Listener: " + eventListener);
+ }
+ }
+ }
+ }
+
+ public void addEventListeners(StatelessKnowledgeSession ksession) throws Exception{
+ if(ksessionManagerConfig.getEventListeners() != null) {
+ for(String eventListener : ksessionManagerConfig.getEventListeners()) {
+ @SuppressWarnings("unchecked")
+ Class eventListenerClass = Class.forName(eventListener);
+ Object eventListenerObject = eventListenerClass.newInstance();
+
+ if(eventListenerObject instanceof WorkingMemoryEventListener) {
+ ksession.addEventListener((WorkingMemoryEventListener) eventListenerObject);
+ } else if(eventListenerObject instanceof AgendaEventListener) {
+ ksession.addEventListener((AgendaEventListener) eventListenerObject);
+ } else if(eventListenerObject instanceof ProcessEventListener) {
+ ksession.addEventListener((ProcessEventListener) eventListenerObject);
+ } else {
+ log.debug("Invalid Event Listener: " + eventListener);
+ }
+ }
+ }
+ }
+
+ public void addWorkItemHandlers(StatefulKnowledgeSession ksession) {
+ if(ksessionManagerConfig.getWorkItemHandlers() != null) {
+ for(String workItemHandlerStr : ksessionManagerConfig.getWorkItemHandlers()) {
+ if(KnowledgeSessionManagerConfig.isValidWorkItemHandler(workItemHandlerStr)) {
+ @SuppressWarnings("unchecked")
+ Bean<WorkItemHandler> workItemHandlerBean = (Bean<WorkItemHandler>) manager.getBeans(KnowledgeSessionManagerConfig.getWorkItemHandlerType(workItemHandlerStr)).iterator().next();
+ WorkItemHandler handler = (WorkItemHandler) manager.getReference(workItemHandlerBean, Configuration.class, manager.createCreationalContext(workItemHandlerBean));
+ log.debug("Registering new WorkItemHandler: " + KnowledgeSessionManagerConfig.getWorkItemHandlerName(workItemHandlerStr));
+ ksession.getWorkItemManager().registerWorkItemHandler(KnowledgeSessionManagerConfig.getWorkItemHandlerName(workItemHandlerStr), handler);
+ }
+ }
+ }
+ }
+
+
+}
Added: modules/drools/trunk/core/src/main/java/org/jboss/seam/drools/KnowledgeSessionManagerConfig.java
===================================================================
--- modules/drools/trunk/core/src/main/java/org/jboss/seam/drools/KnowledgeSessionManagerConfig.java (rev 0)
+++ modules/drools/trunk/core/src/main/java/org/jboss/seam/drools/KnowledgeSessionManagerConfig.java 2010-03-26 04:56:04 UTC (rev 12291)
@@ -0,0 +1,106 @@
+package org.jboss.seam.drools;
+
+import java.util.Properties;
+import java.util.regex.Pattern;
+
+/**
+ * KnowledgeSessionManager Configuration.
+ *
+ * @author Tihomir Surdilovic
+ */
+public class KnowledgeSessionManagerConfig
+{
+ private static final Pattern DIVIDER = Pattern.compile(";");
+ private static final int WORKITEMHANDLER_NAME = 0;
+ private static final int WORKITEMHANDLER_TYPE = 1;
+ private static final int AUDIT_LOG_TYPE = 0;
+ private static final int AUDIT_LOG_INFO = 1;
+ private static final int AUDIT_LOG_INTERVAL = 2;
+ private static final String AUDIT_LOG_TYPE_FILE = "file";
+ private static final String AUDIT_LOG_TYPE_CONSOLE = "console";
+ private static final String AUDIT_LOG_TYPE_THREADED = "threaded";
+
+ private String[] eventListeners;
+ private String[] workItemHandlers;
+ private String knowledgeSessionConfig;
+ private Properties knowledgeSessionConfigProp;
+ private String auditLog;
+
+ public static String getWorkItemHandlerName(String workItemHandlerStr) {
+ return DIVIDER.split(workItemHandlerStr.trim())[WORKITEMHANDLER_NAME];
+ }
+
+ public static String getWorkItemHandlerType(String workItemHandlerStr) {
+ return DIVIDER.split(workItemHandlerStr.trim())[WORKITEMHANDLER_TYPE];
+ }
+
+ public static boolean isValidWorkItemHandler(String workItemHandlerStr) {
+ return DIVIDER.split(workItemHandlerStr.trim()).length == 2;
+ }
+
+ public static boolean isFileLogger(String auditLog) {
+ return DIVIDER.split(auditLog.trim())[AUDIT_LOG_TYPE] == AUDIT_LOG_TYPE_FILE;
+ }
+
+ public static boolean isConsoleLogger(String auditLog) {
+ return DIVIDER.split(auditLog.trim())[AUDIT_LOG_TYPE] == AUDIT_LOG_TYPE_CONSOLE;
+ }
+
+ public static boolean isThreadedLogger(String auditLog) {
+ return DIVIDER.split(auditLog.trim())[AUDIT_LOG_TYPE] == AUDIT_LOG_TYPE_THREADED;
+ }
+
+ public static String getFileLoggerPath(String auditLog) {
+ return DIVIDER.split(auditLog.trim())[AUDIT_LOG_INFO];
+ }
+
+ public static String getThreadedLoggerPath(String auditLog) {
+ return DIVIDER.split(auditLog.trim())[AUDIT_LOG_INFO];
+ }
+
+ public static int getThreadedLoggerInterval(String auditLog) {
+ return Integer.parseInt(DIVIDER.split(auditLog.trim())[AUDIT_LOG_INTERVAL]);
+ }
+
+ public String[] getEventListeners()
+ {
+ return eventListeners;
+ }
+ public void setEventListeners(String[] eventListeners)
+ {
+ this.eventListeners = eventListeners;
+ }
+ public String[] getWorkItemHandlers()
+ {
+ return workItemHandlers;
+ }
+ public void setWorkItemHandlers(String[] workItemHandlers)
+ {
+ this.workItemHandlers = workItemHandlers;
+ }
+ public String getKnowledgeSessionConfig()
+ {
+ return knowledgeSessionConfig;
+ }
+ public void setKnowledgeSessionConfig(String knowledgeSessionConfig)
+ {
+ this.knowledgeSessionConfig = knowledgeSessionConfig;
+ }
+ public String getAuditLog()
+ {
+ return auditLog;
+ }
+ public void setAuditLog(String auditLog)
+ {
+ this.auditLog = auditLog;
+ }
+ public Properties getKnowledgeSessionConfigProp()
+ {
+ return knowledgeSessionConfigProp;
+ }
+ public void setKnowledgeSessionConfigProp(Properties knowledgeSessionConfigProp)
+ {
+ this.knowledgeSessionConfigProp = knowledgeSessionConfigProp;
+ }
+
+}
Added: modules/drools/trunk/core/src/main/java/org/jboss/seam/drools/TemplateDataProvider.java
===================================================================
--- modules/drools/trunk/core/src/main/java/org/jboss/seam/drools/TemplateDataProvider.java (rev 0)
+++ modules/drools/trunk/core/src/main/java/org/jboss/seam/drools/TemplateDataProvider.java 2010-03-26 04:56:04 UTC (rev 12291)
@@ -0,0 +1,14 @@
+package org.jboss.seam.drools;
+
+import java.util.Collection;
+import java.util.Map;
+
+/**
+ * Interface for template data providers.
+ *
+ * @author Tihomir Surdilovic
+ */
+public interface TemplateDataProvider
+{
+ public Collection<Map<String, Object>> getTemplateData();
+}
Added: modules/drools/trunk/core/src/main/java/org/jboss/seam/drools/events/KnowledgeBuilderErrorsEvent.java
===================================================================
--- modules/drools/trunk/core/src/main/java/org/jboss/seam/drools/events/KnowledgeBuilderErrorsEvent.java (rev 0)
+++ modules/drools/trunk/core/src/main/java/org/jboss/seam/drools/events/KnowledgeBuilderErrorsEvent.java 2010-03-26 04:56:04 UTC (rev 12291)
@@ -0,0 +1,29 @@
+package org.jboss.seam.drools.events;
+
+import org.drools.builder.KnowledgeBuilderErrors;
+
+/**
+ * This event is fires in case of KnowledgeBuilder errors.
+ *
+ * @author Tihomir Surdilovic
+ */
+public class KnowledgeBuilderErrorsEvent
+{
+ private KnowledgeBuilderErrors errors;
+
+ public KnowledgeBuilderErrorsEvent(KnowledgeBuilderErrors errors)
+ {
+ this.errors = errors;
+ }
+
+ public KnowledgeBuilderErrors getErrors()
+ {
+ return errors;
+ }
+
+ public void setErrors(KnowledgeBuilderErrors errors)
+ {
+ this.errors = errors;
+ }
+
+}
Added: modules/drools/trunk/core/src/main/java/org/jboss/seam/drools/events/KnowledgeSessionCreatedEvent.java
===================================================================
--- modules/drools/trunk/core/src/main/java/org/jboss/seam/drools/events/KnowledgeSessionCreatedEvent.java (rev 0)
+++ modules/drools/trunk/core/src/main/java/org/jboss/seam/drools/events/KnowledgeSessionCreatedEvent.java 2010-03-26 04:56:04 UTC (rev 12291)
@@ -0,0 +1,26 @@
+package org.jboss.seam.drools.events;
+
+/**
+ * This event is fires when Stateful or Stateless KnowledgeSession is created.
+ *
+ * @author Tihomir Surdilovic
+ */
+public class KnowledgeSessionCreatedEvent
+{
+ private int sessionId;
+
+ public KnowledgeSessionCreatedEvent(int sessionId) {
+ this.sessionId = sessionId;
+ }
+
+ public int getSessionId()
+ {
+ return sessionId;
+ }
+
+ public void setSessionId(int sessionId)
+ {
+ this.sessionId = sessionId;
+ }
+
+}
Added: modules/drools/trunk/core/src/main/java/org/jboss/seam/drools/events/RuleResourceAddedEvent.java
===================================================================
--- modules/drools/trunk/core/src/main/java/org/jboss/seam/drools/events/RuleResourceAddedEvent.java (rev 0)
+++ modules/drools/trunk/core/src/main/java/org/jboss/seam/drools/events/RuleResourceAddedEvent.java 2010-03-26 04:56:04 UTC (rev 12291)
@@ -0,0 +1,26 @@
+package org.jboss.seam.drools.events;
+
+/**
+ * This event is fires when a rule resource is added.
+ *
+ * @author Tihomir Surdilovic
+ */
+public class RuleResourceAddedEvent
+{
+ String resource;
+
+ public RuleResourceAddedEvent(String resource)
+ {
+ this.resource = resource;
+ }
+
+ public String getResource()
+ {
+ return resource;
+ }
+
+ public void setResource(String resource)
+ {
+ this.resource = resource;
+ }
+}
Added: modules/drools/trunk/distribution.txt
===================================================================
--- modules/drools/trunk/distribution.txt (rev 0)
+++ modules/drools/trunk/distribution.txt 2010-03-26 04:56:04 UTC (rev 12291)
@@ -0,0 +1,4 @@
+To create the Seam Drools distribution, run the following Maven command:
+
+mvn clean package javadoc:javadoc assembly:assembly
+
Added: modules/drools/trunk/docs/.classpath
===================================================================
--- modules/drools/trunk/docs/.classpath (rev 0)
+++ modules/drools/trunk/docs/.classpath 2010-03-26 04:56:04 UTC (rev 12291)
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.4"/>
+ <classpathentry kind="con" path="org.maven.ide.eclipse.MAVEN2_CLASSPATH_CONTAINER"/>
+ <classpathentry kind="output" path="target/classes"/>
+</classpath>
Added: modules/drools/trunk/docs/.project
===================================================================
--- modules/drools/trunk/docs/.project (rev 0)
+++ modules/drools/trunk/docs/.project 2010-03-26 04:56:04 UTC (rev 12291)
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>seam-drools-reference-guide</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.wst.common.project.facet.core.builder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.maven.ide.eclipse.maven2Builder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ <nature>org.maven.ide.eclipse.maven2Nature</nature>
+ <nature>org.eclipse.wst.common.project.facet.core.nature</nature>
+ </natures>
+</projectDescription>
Added: modules/drools/trunk/docs/.settings/org.eclipse.jdt.core.prefs
===================================================================
--- modules/drools/trunk/docs/.settings/org.eclipse.jdt.core.prefs (rev 0)
+++ modules/drools/trunk/docs/.settings/org.eclipse.jdt.core.prefs 2010-03-26 04:56:04 UTC (rev 12291)
@@ -0,0 +1,6 @@
+#Fri Mar 26 00:27:07 EDT 2010
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.4
+org.eclipse.jdt.core.compiler.compliance=1.4
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
+org.eclipse.jdt.core.compiler.source=1.4
Added: modules/drools/trunk/docs/.settings/org.maven.ide.eclipse.prefs
===================================================================
--- modules/drools/trunk/docs/.settings/org.maven.ide.eclipse.prefs (rev 0)
+++ modules/drools/trunk/docs/.settings/org.maven.ide.eclipse.prefs 2010-03-26 04:56:04 UTC (rev 12291)
@@ -0,0 +1,9 @@
+#Fri Mar 26 00:04:15 EDT 2010
+activeProfiles=
+eclipse.preferences.version=1
+fullBuildGoals=process-test-resources
+includeModules=false
+resolveWorkspaceProjects=true
+resourceFilterGoals=process-resources resources\:testResources
+skipCompilerPlugin=true
+version=1
Added: modules/drools/trunk/docs/README.TXT
===================================================================
--- modules/drools/trunk/docs/README.TXT (rev 0)
+++ modules/drools/trunk/docs/README.TXT 2010-03-26 04:56:04 UTC (rev 12291)
@@ -0,0 +1,4 @@
+To build the Seam Drools docs run the following command:
+
+mvn clean install
+
Added: modules/drools/trunk/docs/drools-reference.pdf
===================================================================
(Binary files differ)
Property changes on: modules/drools/trunk/docs/drools-reference.pdf
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: modules/drools/trunk/docs/en-US/drools-general.xml
===================================================================
--- modules/drools/trunk/docs/en-US/drools-general.xml (rev 0)
+++ modules/drools/trunk/docs/en-US/drools-general.xml 2010-03-26 04:56:04 UTC (rev 12291)
@@ -0,0 +1,510 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN" "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd">
+
+<chapter id="remoting-general">
+ <title>Seam Remoting</title>
+
+ <para>Seam provides a convenient method of remotely accessing CDI beans from a web page, using AJAX (Asynchronous
+ Javascript and XML). The framework for this functionality is provided with almost no up-front development effort -
+ your beans only require simple annotating to become accessible via AJAX. This chapter describes the steps
+ required to build an AJAX-enabled web page, then goes on to explain the features of the Seam Remoting framework in
+ more detail. </para>
+
+ <section>
+ <title>Configuration</title>
+ <para>To use remoting, the Seam Remoting servlet must first be configured in your <literal>web.xml</literal> file: </para>
+
+ <programlisting role="XML"><![CDATA[<servlet>
+ <servlet-name>Remoting Servlet</servlet-name>
+ <servlet-class>org.jboss.seam.remoting.Remoting</servlet-class>
+ <load-on-startup>1</load-on-startup>
+</servlet>
+
+<servlet-mapping>
+ <servlet-name>Remoting Servlet</servlet-name>
+ <url-pattern>/seam/resource/remoting/*</url-pattern>
+</servlet-mapping>]]></programlisting>
+
+ <para>The next step is to import the necessary Javascript into your web page. There are a minimum of two scripts
+ that must be imported. The first one contains all the client-side framework code that enables remoting
+ functionality:</para>
+
+ <programlisting role="XHTML"><![CDATA[<script type="text/javascript" src="seam/resource/remoting/resource/remote.js"></script>]]></programlisting>
+
+ <para>For a production environment, you may wish to use a compressed version of <literal>remote.js</literal>.
+ To do this, simply add the <literal>compress=true</literal> parameter to the end of the url:</para>
+
+ <programlisting role="XHTML"><![CDATA[<script type="text/javascript" src="seam/resource/remoting/resource/remote.js?compress=true"></script>]]></programlisting>
+
+ <para>The compressed version has its white space compacted and JavaScript comments removed. For development and
+ debugging purposes it is recommended that you use the non-compacted version.</para>
+
+ <para>The second script that you need contains the stubs and type definitions for the beans you wish to call. It is
+ generated dynamically based on the method signatures of your beans, and includes type definitions for all of
+ the classes that can be used to call its remotable methods. The name of the script reflects the
+ name of your bean. For example, if you have a named bean annotated with <literal>@Named</literal>, then your script
+ tag should look like this (for a bean class called <literal>CustomerAction</literal>): </para>
+
+ <programlisting role="XHTML"><![CDATA[<script type="text/javascript"
+ src="seam/resource/remoting/interface.js?customerAction"></script>]]></programlisting>
+
+ <para>Otherwise, you can simply specify the fully qualified class name of the bean:</para>
+
+ <programlisting role="XHTML"><![CDATA[<script type="text/javascript"
+ src="seam/resource/remoting/interface.js?com.acme.myapp.CustomerAction"></script>]]></programlisting>
+
+ <para>If you wish to access more than one bean from the same page, then include them all as parameters of your
+ script tag: </para>
+
+ <programlisting role="XHTML"><![CDATA[<script type="text/javascript"
+ src="seam/resource/remoting/interface.js?customerAction&accountAction"></script>]]></programlisting>
+
+ <section>
+ <title>Dynamic type loading</title>
+
+ <para>If you forget to import a bean or other class that is required by your bean, don't worry. Seam Remoting has
+ a dynamic type loading feature that automatically loads any JavaScript stubs for bean types that it doesn't
+ recognize.</para>
+ </section>
+
+ </section>
+
+ <section>
+ <title>The "Seam" object</title>
+
+ <para>Client-side interaction with your beans is all performed via the <literal>Seam</literal> Javascript
+ object. This object is defined in <literal>remote.js</literal>, and you'll be using it to make asynchronous calls
+ against your bean. It contains methods for creating client-side bean objects and also methods for executing remote
+ requests. The easiest way to become familiar with this object is to start with a simple example.</para>
+
+ <section>
+ <title>A Hello World example</title>
+
+ <para>Let's step through a simple example to see how the <literal>Seam</literal> object works. First of all,
+ let's create a new bean called <literal>helloAction</literal>:</para>
+
+ <programlisting role="JAVA"><![CDATA[@Named
+public class HelloAction implements HelloLocal {
+ @WebRemote public String sayHello(String name) {
+ return "Hello, " + name;
+ }
+}]]></programlisting>
+
+ <para>Take note of the <literal>@WebRemote</literal> annotation on the <literal>sayHello()</literal> method in the
+ above listing. This annotation makes the method accessible via the Remoting API. Besides this annotation, there's
+ nothing else required on your bean to enable it for remoting.</para>
+
+ <!--note>
+ <para>If you are performing a persistence operation in the method marked <literal>@WebRemote</literal> you will
+ also need to add a <literal>@Transactional</literal> annotation to the method. Otherwise, your method would
+ execute outside of a transaction without this extra hint.That's because unlike a JSF request, Seam does not
+ wrap the remoting request in a transaction automatically.</para>
+ </note-->
+
+ <para>Now for our web page - create a new JSF page and import the <literal>helloAction</literal> bean:</para>
+
+ <programlisting role="XHTML"><![CDATA[<script type="text/javascript"
+ src="seam/resource/remoting/interface.js?helloAction]]></programlisting>
+
+ <para>To make this a fully interactive user experience, let's add a button to our page:</para>
+
+ <programlisting role="XHTML"><![CDATA[<button onclick="javascript:sayHello()">Say Hello</button>]]></programlisting>
+
+ <para>We'll also need to add some more script to make our button actually do something when it's clicked: </para>
+
+ <programlisting role="XHTML"><![CDATA[<script type="text/javascript">
+ //<![CDATA[
+
+ function sayHello() {
+ var name = prompt("What is your name?");
+ Seam.createBean("helloAction").sayHello(name, sayHelloCallback);
+ }
+
+ function sayHelloCallback(result) {
+ alert(result);
+ }
+
+ // ]]>]]><![CDATA[
+</script>]]></programlisting>
+
+ <para>We're done! Deploy your application and open the page in a web browser. Click the button, and enter a name when
+ prompted. A message box will display the hello message confirming that the call was successful. If you want to
+ save some time, you'll find the full source code for this Hello World example in the
+ <literal>/examples/helloworld</literal> directory.</para>
+
+ <para>So what does the code of our script actually do? Let's break it down into smaller pieces. To start with,
+ you can see from the Javascript code listing that we have implemented two methods - the first method is
+ responsible for prompting the user for their name and then making a remote request. Take a look at the following
+ line:</para>
+
+ <programlisting role="XHTML">Seam.createBean("helloAction").sayHello(name, sayHelloCallback);</programlisting>
+
+ <para>The first section of this line, <literal>Seam.createBean("helloAction")</literal> returns a
+ proxy, or "stub" for our <literal>helloAction</literal> bean. We can invoke the methods of our bean
+ against this stub, which is exactly what happens with the remainder of the line:
+ <literal>sayHello(name, sayHelloCallback);</literal>. </para>
+
+ <para>What this line of code in its completeness does, is invoke the <literal>sayHello</literal> method of our
+ bean, passing in <literal>name</literal> as a parameter. The second parameter,
+ <literal>sayHelloCallback</literal> isn't a parameter of our bean's <literal>sayHello</literal> method,
+ instead it tells the Seam Remoting framework that once it receives the response to our request, it should pass
+ it to the <literal>sayHelloCallback</literal> Javascript method. This callback parameter is entirely optional,
+ so feel free to leave it out if you're calling a method with a <literal>void</literal> return type or if you
+ don't care about the result. </para>
+
+ <para>The <literal>sayHelloCallback</literal> method, once receiving the response to our remote request then pops
+ up an alert message displaying the result of our method call. </para>
+ </section>
+
+ <section>
+ <title>Seam.createBean</title>
+
+ <para> The <literal>Seam.createBean</literal> JavaScript method is used to create client-side instances of both
+ action and "state" beans. For action beans (which are those that contain one or more methods annotated with
+ <literal>@WebRemote</literal>), the stub object provides all of the remotable methods exposed by the bean.
+ For "state" beans (i.e. beans that simply carry state, for example Entity beans) the stub object provides all
+ the same accessible properties as its server-side equivalent. Each property also has a corresponding
+ getter/setter method so you can work with the object in JavaScript in much the same way as you would in Java.</para>
+ </section>
+
+ </section>
+
+ <section>
+ <title>The Context</title>
+
+ <para>The Seam Remoting Context contains additional information which is sent and received as part of a remoting
+ request/response cycle. It currently contains the conversation ID and Call ID, and may be expanded to include other
+ properties in the future. </para>
+
+ <section>
+ <title>Setting and reading the Conversation ID</title>
+
+ <para> If you intend on using remote calls within the scope of a conversation then you need to be able to read or
+ set the conversation ID in the Seam Remoting Context. To read the conversation ID after making a remote request
+ call <literal>Seam.context.getConversationId()</literal>. To set the conversation ID before making a
+ request, call <literal>Seam.context.setConversationId()</literal>. </para>
+
+ <para>If the conversation ID hasn't been explicitly set with
+ <literal>Seam.context.setConversationId()</literal>, then it will be automatically assigned the
+ first valid conversation ID that is returned by any remoting call. If you are working with multiple conversations
+ within your page, then you may need to explicitly set the conversation ID before each call. If you are working
+ with just a single conversation, then you don't need to do anything special. </para>
+ </section>
+
+ <section>
+ <title>Remote calls within the current conversation scope</title>
+
+ <para>In some circumstances it may be required to make a remote call within the scope of the
+ current view's conversation. To do this, you must explicitly set the conversation ID to that
+ of the view before making the remote call. This small snippet of JavaScript will set the
+ conversation ID that is used for remoting calls to the current view's conversation ID: </para>
+
+ <programlisting role="XHTML"><![CDATA[Seam.context.setConversationId( #{conversation.id} );]]></programlisting>
+ </section>
+ </section>
+
+ <section>
+ <title>Working with Data types</title>
+
+ <section>
+ <title>Primitives / Basic Types</title>
+
+ <para>This section describes the support for basic data types. On the server side these values as a rule are
+ compatible with either their primitive type or their corresponding wrapper class. </para>
+
+ <section>
+ <title>String</title>
+
+ <para>Simply use Javascript String objects when setting String parameter values. </para>
+ </section>
+
+ <section>
+ <title>Number</title>
+
+ <para>There is support for all number types supported by Java. On the client side, number values are always
+ serialized as their String representation and then on the server side they are converted to the correct
+ destination type. Conversion into either a primitive or wrapper type is supported for <literal>Byte</literal>,
+ <literal>Double</literal>, <literal>Float</literal>, <literal>Integer</literal>, <literal>Long</literal> and
+ <literal>Short</literal> types. </para>
+ </section>
+
+ <section>
+ <title>Boolean</title>
+
+ <para>Booleans are represented client side by Javascript Boolean values, and server side by a Java boolean.
+ </para>
+ </section>
+ </section>
+
+ <section>
+ <title>JavaBeans</title>
+
+ <para> In general these will be either entity beans or JavaBean classes, or some other non-bean class. Use
+ <literal>Seam.createBean()</literal> to create a new instance of the object. </para>
+ </section>
+
+ <section>
+ <title>Dates and Times</title>
+
+ <para>Date values are serialized into a String representation that is accurate to the millisecond. On the client
+ side, use a JavaScript <literal>Date</literal> object to work with date values. On the server side, use any
+ <literal>java.util.Date</literal> (or descendent, such as <literal>java.sql.Date</literal> or
+ <literal>java.sql.Timestamp</literal> class. </para>
+ </section>
+
+ <section>
+ <title>Enums</title>
+
+ <para> On the client side, enums are treated the same as <literal>String</literal>s. When setting the value for an enum parameter,
+ simply use the <literal>String</literal> representation of the enum. Take the following bean as an example: </para>
+
+ <programlisting role="JAVA">@Named
+public class paintAction {
+ public enum Color {red, green, blue, yellow, orange, purple};
+
+ public void paint(Color color) {
+ // code
+ }
+} </programlisting>
+
+ <para> To call the <literal>paint()</literal> method with the color <literal>red</literal>, pass the parameter
+ value as a <literal>String</literal> literal: </para>
+
+ <programlisting role="XHTML">Seam.createBean("paintAction").paint("red");</programlisting>
+
+ <para> The inverse is also true - that is, if a bean method returns an enum parameter (or contains an enum
+ field anywhere in the returned object graph) then on the client-side it will be converted to a <literal>String</literal>. </para>
+ </section>
+
+ <section>
+ <title>Collections</title>
+
+ <section>
+ <title>Bags</title>
+
+ <para>Bags cover all collection types including arrays, collections, lists, sets, (but excluding Maps - see the
+ next section for those), and are implemented client-side as a JavaScript array. When calling a bean
+ method that accepts one of these types as a parameter, your parameter should be a JavaScript array. If a
+ bean method returns one of these types, then the return value will also be a JavaScript array. The
+ remoting framework is clever enough on the server side to convert the bag to an appropriate type (including
+ sophisticated support for generics) for the bean method call.</para>
+ </section>
+
+ <section>
+ <title>Maps</title>
+
+ <para> As there is no native support for Maps within JavaScript, a simple Map implementation is provided with
+ the Seam Remoting framework. To create a Map which can be used as a parameter to a remote call, create a new
+ <literal>Seam.Map</literal> object: </para>
+
+ <programlisting role="XHTML">var map = new Seam.Map();</programlisting>
+
+ <para> This JavaScript implementation provides basic methods for working with Maps: <literal>size()</literal>,
+ <literal>isEmpty()</literal>, <literal>keySet()</literal>, <literal>values()</literal>,
+ <literal>get(key)</literal>, <literal>put(key, value)</literal>, <literal>remove(key)</literal> and
+ <literal>contains(key)</literal>. Each of these methods are equivalent to their Java counterpart. Where the
+ method returns a collection, such as <literal>keySet()</literal> and <literal>values()</literal>, a JavaScript
+ Array object will be returned that contains the key or value objects (respectively). </para>
+ </section>
+ </section>
+ </section>
+
+ <section>
+ <title>Debugging</title>
+
+ <para> To aid in tracking down bugs, it is possible to enable a debug mode which will display the contents of all
+ the packets send back and forth between the client and server in a popup window. To enable debug mode, set the
+ <literal>Seam.debug</literal> property to <literal>true</literal> in Javascript: </para>
+
+ <programlisting role="XHTML">Seam.debug = true;</programlisting>
+
+ <para>If you want to write your own messages to the debug log, call
+ <literal>Seam.log(message)</literal>. </para>
+ </section>
+
+ <section>
+ <title>Handling Exceptions</title>
+
+ <para>
+ When invoking a remote bean method, it is possible to specify an exception handler which will process
+ the response in the event of an exception during bean invocation. To specify an exception handler function,
+ include a reference to it after the callback parameter in your JavaScript:
+ </para>
+
+ <programlisting><![CDATA[var callback = function(result) { alert(result); };
+var exceptionHandler = function(ex) { alert("An exception occurred: " + ex.getMessage()); };
+Seam.createBean("helloAction").sayHello(name, callback, exceptionHandler);]]></programlisting>
+
+ <para>
+ If you do not have a callback handler defined, you must specify <literal>null</literal> in its place:
+ </para>
+
+ <programlisting><![CDATA[var exceptionHandler = function(ex) { alert("An exception occurred: " + ex.getMessage()); };
+Seam.createBean("helloAction").sayHello(name, null, exceptionHandler);]]></programlisting>
+
+ <para>
+ The exception object that is passed to the exception handler exposes one method, <literal>getMessage()</literal>
+ that returns the exception message which is produced by the exception thrown by the <literal>@WebRemote</literal>
+ method.
+ </para>
+
+ </section>
+
+ <section>
+ <title>The Loading Message</title>
+
+ <para> The default loading message that appears in the top right corner of the screen can be modified, its rendering
+ customised or even turned off completely. </para>
+
+ <section>
+ <title>Changing the message</title>
+
+ <para> To change the message from the default "Please Wait..." to something different, set the value of
+ <literal>Seam.loadingMessage</literal>: </para>
+
+ <programlisting role="XHTML">Seam.loadingMessage = "Loading..."; </programlisting>
+ </section>
+
+ <section>
+ <title>Hiding the loading message</title>
+
+ <para> To completely suppress the display of the loading message, override the implementation of
+ <literal>displayLoadingMessage()</literal> and <literal>hideLoadingMessage()</literal> with functions that
+ instead do nothing: </para>
+
+ <programlisting role="XHTML">// don't display the loading indicator
+Seam.displayLoadingMessage = function() {};
+Seam.hideLoadingMessage = function() {};</programlisting>
+ </section>
+
+ <section>
+ <title>A Custom Loading Indicator</title>
+
+ <para> It is also possible to override the loading indicator to display an animated icon, or anything else that
+ you want. To do this override the <literal>displayLoadingMessage()</literal> and
+ <literal>hideLoadingMessage()</literal> messages with your own implementation: </para>
+
+ <programlisting role="XHTML"> Seam.displayLoadingMessage = function() {
+ // Write code here to display the indicator
+ };
+
+ Seam.hideLoadingMessage = function() {
+ // Write code here to hide the indicator
+ };</programlisting>
+ </section>
+ </section>
+
+ <section>
+ <title>Controlling what data is returned</title>
+
+ <para> When a remote method is executed, the result is serialized into an XML response that is returned to the
+ client. This response is then unmarshaled by the client into a JavaScript object. For complex types (i.e.
+ Javabeans) that include references to other objects, all of these referenced objects are also serialized as part
+ of the response. These objects may reference other objects, which may reference other objects, and so forth. If
+ left unchecked, this object "graph" could potentially be enormous, depending on what relationships exist between
+ your objects. And as a side issue (besides the potential verbosity of the response), you might also wish to
+ prevent sensitive information from being exposed to the client. </para>
+
+ <para> Seam Remoting provides a simple means to "constrain" the object graph, by specifying the
+ <literal>exclude</literal> field of the remote method's <literal>@WebRemote</literal> annotation. This field
+ accepts a String array containing one or more paths specified using dot notation. When invoking a remote method,
+ the objects in the result's object graph that match these paths are excluded from the serialized result packet. </para>
+
+ <para> For all our examples, we'll use the following <literal>Widget</literal> class: </para>
+
+ <programlisting role="JAVA">public class Widget
+{
+ private String value;
+ private String secret;
+ private Widget child;
+ private Map<String,Widget> widgetMap;
+ private List<Widget> widgetList;
+
+ // getters and setters for all fields
+}</programlisting>
+
+ <section>
+ <title>Constraining normal fields</title>
+
+ <para> If your remote method returns an instance of <literal>Widget</literal>, but you don't want to expose the
+ <literal>secret</literal> field because it contains sensitive information, you would constrain it like this: </para>
+
+ <programlisting role="JAVA">@WebRemote(exclude = {"secret"})
+public Widget getWidget(); </programlisting>
+
+ <para> The value "secret" refers to the <literal>secret</literal> field of the returned object. Now, suppose that
+ we don't care about exposing this particular field to the client. Instead, notice that the
+ <literal>Widget</literal> value that is returned has a field <literal>child</literal> that is also a
+ <literal>Widget</literal>. What if we want to hide the <literal>child</literal>'s <literal>secret</literal>
+ value instead? We can do this by using dot notation to specify this field's path within the result's object
+ graph: </para>
+
+ <programlisting role="JAVA">@WebRemote(exclude = {"child.secret"})
+public Widget getWidget();</programlisting>
+
+ </section>
+
+ <section>
+ <title>Constraining Maps and Collections</title>
+
+ <para> The other place that objects can exist within an object graph are within a <literal>Map</literal> or some
+ kind of collection (<literal>List</literal>, <literal>Set</literal>, <literal>Array</literal>, etc). Collections
+ are easy, and are treated like any other field. For example, if our <literal>Widget</literal> contained a list
+ of other <literal>Widget</literal>s in its <literal>widgetList</literal> field, to constrain the
+ <literal>secret</literal> field of the <literal>Widget</literal>s in this list the annotation would look like
+ this: </para>
+
+ <programlisting role="JAVA">@WebRemote(exclude = {"widgetList.secret"})
+public Widget getWidget();</programlisting>
+
+ <para> To constrain a <literal>Map</literal>'s key or value, the notation is slightly different. Appending
+ <literal>[key]</literal> after the <literal>Map</literal>'s field name will constrain the
+ <literal>Map</literal>'s key object values, while <literal>[value]</literal> will constrain the value object
+ values. The following example demonstrates how the values of the <literal>widgetMap</literal> field have their
+ <literal>secret</literal> field constrained: </para>
+
+ <programlisting role="JAVA">@WebRemote(exclude = {"widgetMap[value].secret"})
+public Widget getWidget(); </programlisting>
+ </section>
+
+ <section>
+ <title>Constraining objects of a specific type</title>
+
+ <para> There is one last notation that can be used to constrain the fields of a type of object no matter where in
+ the result's object graph it appears. This notation uses either the name of the bean (if the object is a
+ named bean) or the fully qualified class name (only if the object is not a named bean) and is expressed
+ using square brackets: </para>
+
+ <programlisting role="JAVA">@WebRemote(exclude = {"[widget].secret"})
+public Widget getWidget(); </programlisting>
+
+ </section>
+
+ <section>
+ <title>Combining Constraints</title>
+
+ <para> Constraints can also be combined, to filter objects from multiple paths within the object graph: </para>
+
+ <programlisting role="JAVA">@WebRemote(exclude = {"widgetList.secret", "widgetMap[value].secret"})
+public Widget getWidget();</programlisting>
+ </section>
+
+ </section>
+
+ <!--section>
+ <title>Transactional Requests</title>
+
+ <para>
+ By default there is no active transaction during a remoting request, so if you wish to perform database updates
+ during a remoting request, you need to annotate the <literal>@WebRemote</literal> method with
+ <literal>@Transactional</literal>, like so:
+ </para>
+
+ <programlisting><![CDATA[ @WebRemote @Transactional(TransactionPropagationType.REQUIRED)
+ public void updateOrder(Order order) {
+ entityManager.merge(order);
+ }]]></programlisting>
+ </section-->
+
+</chapter>
+
Added: modules/drools/trunk/docs/en-US/drools-model.xml
===================================================================
--- modules/drools/trunk/docs/en-US/drools-model.xml (rev 0)
+++ modules/drools/trunk/docs/en-US/drools-model.xml 2010-03-26 04:56:04 UTC (rev 12291)
@@ -0,0 +1,652 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN" "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd">
+
+<chapter id="remoting-model">
+ <title>Seam Remoting - Model API</title>
+
+ <section>
+ <title>Introduction</title>
+ <para>
+ The Model API builds on top of Seam Remoting's object serialization features to provide a
+ <emphasis>component-based</emphasis> approach to working with a server-side object model, as
+ opposed to the <emphasis>RPC-based</emphasis> approach provided by the standard Remoting API.
+ This allows a client-side representation of a server-side object graph to be modified ad hoc
+ by the client, after which the changes made to the objects in the graph can be
+ <emphasis>applied</emphasis> to the corresponding server-side objects. When applying the
+ changes the client determines exactly which objects have been modified by recursively walking
+ the client-side object tree and generating a delta by comparing the original property values
+ of the objects with their new property values.
+ </para>
+
+ <para>
+ This approach, when used in conjunction with the extended persistence context provided by Seam
+ elegantly solves a number of problems faced by AJAX developers when working remotely with
+ persistent objects. A persistent, managed object graph can be loaded at the start of
+ a new conversation, and then across multiple requests (and within the same transaction) the client
+ can fetch the objects, make changes to them and apply those changes to the same managed objects after
+ which the long-running transaction can be committed when the conversation ends.
+ </para>
+
+ <para>
+ One other useful feature of the Model API is its ability to <emphasis>expand</emphasis> a model.
+ For example, if you are working with entities with lazy-loaded associations it is usually not a good idea
+ to blindly fetch the associated objects (which may in turn themselves contain associations
+ to other entities, ad nauseum), as you may inadvertently end up fetching the bulk of your database.
+ Seam Remoting already knows how to deal with lazy-loaded associations by automatically excluding
+ them when marshalling instances of entity beans, and assigning them a client-side value of
+ <literal>undefined</literal> (which is a special JavaScript value, distinct from <literal>null</literal>).
+ The Model API goes one step further by giving the client the option of manipulating the associated objects
+ also. By providing an <emphasis>expand</emphasis> operation, it allows for the initialization of a
+ previously-uninitialized object property (such as a lazy-loaded collection), by dynamically "grafting"
+ the initialized value onto the object graph. By <emphasis>expanding</emphasis> the model in this way,
+ we have at our disposal a powerful tool for building dynamic client interfaces.
+ </para>
+ </section>
+
+ <section>
+ <title>Model Operations</title>
+
+ <para>
+ For the methods of the Model API that accept action parameters, an instance of
+ <literal>Seam.Action</literal> should be used. The constructor for
+ <literal>Seam.Action</literal> takes no parameters:
+ </para>
+
+ <programlisting role="XHTML"><![CDATA[ var action = new Seam.Action();]]></programlisting>
+
+ <para>
+ The following table lists the methods used to define the action. Each of the following methods
+ return a reference to the <literal>Seam.Action</literal> object, so methods can be chained.
+ </para>
+
+ <table>
+ <title>Seam.Action method reference</title>
+
+ <tgroup cols="2">
+ <colspec colnum="1" colwidth="2*" />
+ <colspec colnum="2" colwidth="3*" />
+
+ <thead>
+ <row>
+ <entry align="center">
+ <para>Method</para>
+ </entry>
+ <entry align="center">
+ <para>Description</para>
+ </entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry>
+ <para>
+ <literal>setBeanType(beanType)</literal>
+ </para>
+ </entry>
+ <entry>
+ <para>
+ Sets the class name of the bean to be invoked.
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <literal>beanType</literal> - the fully qualified class name of the bean type to be invoked.
+ </listitem>
+ </itemizedlist>
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <para>
+ <literal>setQualifiers(qualifiers)</literal>
+ </para>
+ </entry>
+ <entry>
+ <para>
+ Sets the qualifiers for the bean to be invoked.
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <literal>qualifiers</literal> - a comma-separated list of bean qualifier names.
+ The names may either be the simple or fully qualified names of the qualifier classes.
+ </listitem>
+ </itemizedlist>
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <para>
+ <literal>setMethod(method)</literal>
+ </para>
+ </entry>
+ <entry>
+ <para>
+ Sets the name of the bean method.
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <literal>method</literal> - the name of the bean method to invoke.
+ </listitem>
+ </itemizedlist>
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <para>
+ <literal>addParam(param)</literal>
+ </para>
+ </entry>
+ <entry>
+ <para>
+ Adds a parameter value for the action method. This method should be called once for
+ each parameter value to be added, in the correct parameter order.
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <literal>param</literal> - the parameter value to add.
+ </listitem>
+ </itemizedlist>
+ </entry>
+ </row>
+
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ The following table describes the methods provided by the <literal>Seam.Model</literal> object. To work with
+ the Model API in JavaScript you must first create a new Model object:
+ </para>
+
+ <programlisting role="XHTML"><![CDATA[ var model = new Seam.Model();]]></programlisting>
+
+ <table>
+ <title>Seam.Model method reference</title>
+
+ <tgroup cols="2">
+ <colspec colnum="1" colwidth="2*" />
+ <colspec colnum="2" colwidth="3*" />
+
+ <thead>
+ <row>
+ <entry align="center">
+ <para>Method</para>
+ </entry>
+ <entry align="center">
+ <para>Description</para>
+ </entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry>
+ <para>
+ <literal>addBean(alias, bean, qualifiers)</literal>
+ </para>
+ </entry>
+ <entry>
+ <para>
+ Adds a bean value to the model. When the model is fetched, the value of the specified bean
+ will be read and placed into the model, where it may be accessed by using the
+ <literal>getValue()</literal> method with the specified alias.
+ </para>
+
+ <para>
+ Can only be used before the model is fetched.
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <literal>alias</literal> - the local alias for the bean value.
+ </listitem>
+ <listitem>
+ <literal>bean</literal> - the name of the bean, either specified by the <literal>@Named</literal>
+ annotation or the fully qualified class name.
+ </listitem>
+ <listitem>
+ <literal>qualifiers</literal> (optional) - a list of bean qualifiers.
+ </listitem>
+ </itemizedlist>
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <para>
+ <literal>addBeanProperty(alias, bean, property, qualifiers)</literal>
+ </para>
+ </entry>
+ <entry>
+ <para>
+ Adds a bean property value to the model. When the model is fetched, the value of the specified
+ property on the specified bean will be read and placed into the model, where it may be accessed
+ by using the <literal>getValue()</literal> method with the specified alias.
+ </para>
+
+ <para>
+ Can only be used before the model is fetched.
+ </para>
+
+ <para>
+ Example:
+ </para>
+
+ <programlisting role="XHTML"><![CDATA[ addBeanProperty("account", "AccountAction", "account", "@Qualifier1", "@Qualifier2");]]></programlisting>
+
+ <itemizedlist>
+ <listitem>
+ <literal>alias</literal> - the local alias for the bean value.
+ </listitem>
+ <listitem>
+ <literal>bean</literal> - the name of the bean, either specified by the <literal>@Named</literal>
+ annotation or the fully qualified class name.
+ </listitem>
+ <listitem>
+ <literal>property</literal> - the name of the bean property.
+ </listitem>
+ <listitem>
+ <literal>qualifiers</literal> (optional) - a list of bean qualifiers. This parameter (and any
+ after it) are treated as bean qualifiers.
+ </listitem>
+ </itemizedlist>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <para>
+ <literal>fetch(action, callback)</literal>
+ </para>
+ </entry>
+ <entry>
+ <para>
+ Fetches the model - this operation causes an asynchronous request to be sent to the server.
+ The request contains a list of the beans and bean properties (set by calling the
+ <literal>addBean()</literal> and <literal>addBeanProperty()</literal> methods) for which values
+ will be returned. Once the response is received, the callback method (if specified) will be
+ invoked, passing in a reference to the model as a parameter.
+ </para>
+
+ <para>
+ A model should only be fetched once.
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <literal>action</literal> (optional) - a <literal>Seam.Action</literal> instance representing
+ the bean action to invoke before the model values are read and stored in the model.
+ </listitem>
+ <listitem>
+ <literal>callback</literal> (optional) - a reference to a JavaScript function that will be
+ invoked after the model has been fetched. A reference to the model instance is passed to
+ the callback method as a parameter.
+ </listitem>
+ </itemizedlist>
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <para>
+ <literal>getValue(alias)</literal>
+ </para>
+ </entry>
+ <entry>
+ <para>
+ This method returns the value of the object with the specified alias.
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <literal>alias</literal> - the alias of the value to return.
+ </listitem>
+ </itemizedlist>
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <para>
+ <literal>expand(value, property, callback)</literal>
+ </para>
+ </entry>
+ <entry>
+ <para>
+ Expands the model by initializing a property value that was previously uninitialized. This
+ operation causes an asynchronous request to be sent to the server, where the uninitialized
+ property value (such as a lazy-loaded collection within an entity bean association) is
+ initialized and the resulting value is returned to the client. Once the response is received,
+ the callback method (if specified) will be invoked, passing in a reference to the model as a
+ parameter.
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <literal>value</literal> - a reference to the value containing the uninitialized property
+ to fetch. This can be any value within the model, and does not need to be a "root" value
+ (i.e. it doesn't need to be a value specified by <literal>addBean()</literal> or
+ <literal>addBeanProperty()</literal>, it can exist anywhere within the object graph.
+ </listitem>
+ <listitem>
+ <literal>property</literal> - the name of the uninitialized property to be initialized.
+ </listitem>
+ <listitem>
+ <literal>callback</literal> (optional) - a reference to a JavaScript function that will be
+ invoked after the model has been expanded. A reference to the model instance is passed to
+ the callback method as a parameter.
+ </listitem>
+ </itemizedlist>
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <para>
+ <literal>applyUpdates(action, callback)</literal>
+ </para>
+ </entry>
+ <entry>
+ <para>
+ Applies the changes made to the objects contained in the model. This method causes an
+ asynchronous request to be sent to the server containing a delta consisting of
+ a list of the changes made to the client-side objects.
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <literal>action</literal> (optional) - a <literal>Seam.Action</literal> instance representing
+ a bean method to be invoked after the client-side model changes have been applied to their
+ corresponding server-side objects.
+ </listitem>
+ <listitem>
+ <literal>callback</literal> (optional) - a reference to a JavaScript function that will be
+ invoked after the updates have been applied. A reference to the model instance is passed to
+ the callback method as a parameter.
+ </listitem>
+ </itemizedlist>
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+
+ </table>
+
+ <para>
+
+ </para>
+ </section>
+
+ <section>
+ <title>Fetching a model</title>
+
+ <para>
+ To fetch a model, one or more values must first be specified using <literal>addBean()</literal> or
+ <literal>addBeanProperty()</literal> before invoking the <literal>fetch()</literal> operation.
+ Let's work through an example - here we have an entity bean called <literal>Customer</literal>:
+ </para>
+
+ <programlisting role="JAVA"><![CDATA[@Entity Customer implements Serializable {
+ private Integer customerId;
+ private String firstName;
+ private String lastName;
+
+ @Id @GeneratedValue public Integer getCustomerId() { return customerId; }
+ public void setCustomerId(Integer customerId) { this.customerId = customerId; }
+
+ public String getFirstName() { return firstName; }
+ public void setFirstName(String firstName) { this.firstName = firstName; }
+
+ public String getLastName() { return lastName; }
+ public void setLastName(String lastName) { this.lastName = lastName; }
+}]]></programlisting>
+
+ <para>
+ We also have a bean called <literal>CustomerAction</literal>, which is responsible for creating and editing
+ <literal>Customer</literal> instances. Since we're only interested in editing a customer right now, the
+ following code only shows the <literal>editCustomer()</literal> method:
+ </para>
+
+
+ <programlisting role="JAVA"><![CDATA[@ConversationScoped @Named
+public class CustomerAction {
+ @Inject Conversation conversation;
+ @PersistenceContext EntityManager entityManager;
+ public Customer customer;
+
+ public void editCustomer(Integer customerId) {
+ conversation.begin();
+ customer = entityManager.find(Customer.class, customerId);
+ }
+
+ public void saveCustomer() {
+ entityManager.merge(customer);
+ conversation.end();
+ }
+}]]></programlisting>
+
+ <para>
+ In the client section of this example, we wish to make changes to an existing <literal>Customer</literal>
+ instance, so we need to use the <literal>editCustomer()</literal> method of <literal>CustomerAction</literal>
+ to first load the customer entity, after which we can access it via the public <literal>customer</literal>
+ field. Our model object must therefore be configured to fetch the <literal>CustomerAction.customer</literal>
+ property, and to invoke the <literal>editCustomer()</literal> method when the model is fetched. We start
+ by using the <literal>addBeanProperty()</literal> method to add a bean property to the model:
+ </para>
+
+ <programlisting role="XHTML"><![CDATA[ var model = new Seam.Model();
+ model.addBeanProperty("customer", "CustomerAction", "customer");]]></programlisting>
+
+ <para>
+ The first parameter of <literal>addBeanProperty()</literal> is the <emphasis>alias</emphasis> (in this case
+ <literal>customer</literal>), which is used to access the value via the <literal>getValue()</literal> method.
+ The <literal>addBeanProperty()</literal> and <literal>addBean()</literal> methods can be called multiple times
+ to bind multiple values to the model. An important thing to note is that the values may come from multiple
+ server-side beans, they aren't all required to come from the same bean.
+ </para>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="images/remoting-model-customer-uml-1.png" format="PNG"/>
+ </imageobject>
+ </mediaobject>
+
+ <para>
+ We also specify the action that we wish to invoke (i.e. the <literal>editCustomer()</literal> method).
+ In this example we know the value of the <literal>customerId</literal> that we wish to edit, so we can
+ specify this value as an action method parameter:
+ </para>
+
+ <programlisting role="XHTML"><![CDATA[ var action = new Seam.Action()
+ .setBeanType("CustomerAction")
+ .setMethod("editCustomer")
+ .addParam(123);]]></programlisting>
+
+ <para>
+ Once we've specified the bean properties we wish to fetch and the action to invoke, we can then fetch the
+ model. We pass in a reference to the action object as the first parameter of the <literal>fetch()</literal>
+ method. Also, since this is an asynchronous request we need to provide a callback method to deal with the
+ response. The callback method is passed a reference to the model object as a parameter.
+ </para>
+
+ <programlisting role="XHTML"><![CDATA[ var callback = function(model) { alert("Fetched customer: " model.getValue("customer").firstName +
+ " " + model.getValue("customer").lastName); };
+ model.fetch(action, callback);]]></programlisting>
+
+ <para>
+ When the server receives a model fetch request, it first invokes the action (if one is specified) before
+ reading the requested property values and returning them to the client.
+ </para>
+
+ <section>
+ <title>Fetching a bean value</title>
+
+ <para>
+ Alternatively, if you don't wish to fetch a bean <emphasis>property</emphasis> but rather a bean itself
+ (such as a value created by a producer method) then the <literal>addBean()</literal> method is used instead.
+ Let's say we have a producer method that returns a qualified <literal>UserSettings</literal> value:
+ </para>
+
+ <programlisting role="JAVA"><![CDATA[ @Produces @ConversationScoped @Settings UserSettings getUserSettings() {
+ /* snip code */
+ }]]></programlisting>
+
+ <para>
+ We would add this value to our model with the following code:
+ </para>
+
+ <programlisting role="XHTML"><![CDATA[ model.addBean("settings", "UserSettings", "@Settings");]]></programlisting>
+
+ <para>
+ The first parameter is the local alias for the value, the second parameter is the fully qualified
+ class of the bean, and the third (and subsequent) parameter/s are optional bean qualifiers.
+ </para>
+
+ </section>
+ </section>
+
+ <section>
+ <title>Modifying model values</title>
+
+ <para>
+ Once a model has been fetched its values may be read using the <literal>getValue()</literal> method.
+ Continuing on with the previous example, we would retrieve the <literal>Customer</literal> object via
+ it's local alias (<literal>customer</literal>) like this:
+ </para>
+
+ <programlisting role="XHTML"><![CDATA[ var customer = model.getValue("customer");]]></programlisting>
+
+ <para>
+ We are then free to read or modify the properties of the value (or any of the other values within its
+ object graph).
+ </para>
+
+ <programlisting role="XHTML"><![CDATA[ alert("Customer name is: " + customer.firstName + " " + customer.lastName);
+ customer.setLastName("Jones"); // was Smith, but Peggy got married on the weekend]]></programlisting>
+
+ </section>
+
+ <section>
+ <title>Expanding a model</title>
+
+ <para>
+ We can use the Model API's ability to expand a model to load uninitialized branches of the objects in
+ the model's object graph. To understand how this works exactly, let's flesh out our example a little
+ more by adding an <literal>Address</literal> entity class, and creating a one-to-many relationship
+ between <literal>Customer</literal> and <literal>Address</literal>.
+ </para>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="images/remoting-model-customer-address-uml.png" format="PNG"/>
+ </imageobject>
+ </mediaobject>
+
+ <programlisting role="JAVA"><![CDATA[@Entity Address implements Serializable {
+ private Integer addressId;
+ private Customer customer;
+ private String unitNumber;
+ private String streetNumber;
+ private String streetName;
+ private String suburb;
+ private String zip;
+ private String state;
+ private String country;
+
+ @Id @GeneratedValue public Integer getAddressId() { return addressId; }
+ public void setAddressId(Integer addressId) { this.addressId = addressId; }
+
+ @ManyToOne public Customer getCustomer() { return customer; }
+ public void setCustomer(Customer customer) { this.customer = customer; }
+
+ /* Snipped other getter/setter methods */
+
+}]]></programlisting>
+
+ <para>
+ Here's the new field and methods that we also need to add to the <literal>Customer</literal> class:
+ </para>
+
+ <programlisting role="JAVA"><![CDATA[ private Collection<Address> addresses;
+
+ @OneToMany(fetch = FetchType.LAZY, mappedBy = "customer", cascade = CascadeType.ALL)
+ public Collection<Address> getAddresses() { return addresses; }
+ public void setAddresses(Collection<Address> addresses) { this.addresses = addresses; }]]></programlisting>
+
+ <para>
+ As we can see, the <literal>@OneToMany</literal> annotation on the <literal>getAddresses()</literal>
+ method specifies a <literal>fetch</literal> attribute of <literal>LAZY</literal>, meaning that by
+ default the customer's addresses won't be loaded automatically when the customer is. When reading the
+ <emphasis>uninitialized</emphasis> <literal>addresses</literal> property value from a newly-fetched
+ <literal>Customer</literal> object in JavaScript, a value of <literal>undefined</literal> will be returned.
+ </para>
+
+ <programlisting role="XHTML"><![CDATA[ getValue("customer").addresses == undefined; // returns true]]></programlisting>
+
+ <para>
+ We can <emphasis>expand</emphasis> the model by making a special request to initialize this uninitialized
+ property value. The <literal>expand()</literal> operation takes three parameters - the value containing
+ the property to be initialized, the name of the property and an optional callback method. The following
+ example shows us how the customer's <literal>addresses</literal> property can be initialized:
+ </para>
+
+ <programlisting role="XHTML"><![CDATA[ model.expand(model.getValue("customer"), "addresses");]]></programlisting>
+
+ <para>
+ The <literal>expand()</literal> operation makes an asynchronous request to the server, where the
+ property value is initialized and the value returned to the client. When the client receives the
+ response, it reads the initialized value and appends it to the model.
+ </para>
+
+ <programlisting role="XHTML"><![CDATA[ // The addresses property now contains an array of address objects
+ alert(model.getValue("customer").addresses.length + " addresses loaded");]]></programlisting>
+
+ </section>
+
+ <section>
+ <title>Applying Changes</title>
+
+ <para>
+ Once you have finished making changes to the values in the model, you can apply them with the
+ <literal>applyUpdates()</literal> method. This method scans all of the objects in the model, compares
+ them with their original values and generates a delta which may contain one or more changesets to
+ send to the server. A changeset is simply a list of property value changes for a single object.
+ </para>
+
+ <para>
+ Like the <literal>fetch()</literal> command you can also specify an action to invoke when applying updates,
+ although the action is invoked <emphasis>after</emphasis> the model updates have been applied. In a
+ typical situation the invoked action would do things like commit a database transaction, end the current
+ conversation, etc.
+ </para>
+
+ <para>
+ Since the <literal>applyUpdates()</literal> method sends an asynchronous request like the
+ <literal>fetch()</literal> and <literal>expand()</literal> methods, we also need to specify a callback
+ function if we wish to do something when the operation completes.
+ </para>
+
+ <programlisting role="XHTML"><![CDATA[ var action = new Seam.Action();
+ .setBeanType("CustomerAction")
+ .setMethod("saveCustomer");
+
+ var callback = function() { alert("Customer saved."); };
+
+ model.applyUpdates(action, callback);]]></programlisting>
+
+ <para>
+ The <literal>applyUpdates()</literal> method performs a refresh of the model, retrieving the latest
+ state of the objects contained in the model after all updates have been applied and the action method
+ (if specified) invoked.
+ </para>
+ </section>
+
+
+</chapter>
+
Added: modules/drools/trunk/docs/en-US/master.xml
===================================================================
--- modules/drools/trunk/docs/en-US/master.xml (rev 0)
+++ modules/drools/trunk/docs/en-US/master.xml 2010-03-26 04:56:04 UTC (rev 12291)
@@ -0,0 +1,12 @@
+<?xml version='1.0' encoding="utf-8"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [ ]>
+<book lang="en">
+
+ <toc/>
+
+ <title>Seam Drools</title>
+ <xi:include href="drools-general.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <xi:include href="drools-model.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+</book>
Added: modules/drools/trunk/docs/pom.xml
===================================================================
--- modules/drools/trunk/docs/pom.xml (rev 0)
+++ modules/drools/trunk/docs/pom.xml 2010-03-26 04:56:04 UTC (rev 12291)
@@ -0,0 +1,136 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.jboss.weld</groupId>
+ <artifactId>weld-parent</artifactId>
+ <version>8</version>
+ </parent>
+
+ <groupId>org.jboss.seam.drools</groupId>
+ <artifactId>seam-drools-reference-guide</artifactId>
+ <version>3.0.0-SNAPSHOT</version>
+ <packaging>jdocbook</packaging>
+ <name>Seam Drools Reference Guide</name>
+
+ <pluginRepositories>
+ <pluginRepository>
+ <id>repository.jboss.org</id>
+ <name>JBoss Repository</name>
+ <url>http://repository.jboss.org/maven2</url>
+ </pluginRepository>
+ </pluginRepositories>
+ <repositories>
+ <repository>
+ <id>repository.jboss.org</id>
+ <name>JBoss Repository</name>
+ <url>http://repository.jboss.org/maven2</url>
+ </repository>
+ </repositories>
+
+ <properties>
+ <pdf.name>drools-reference.pdf</pdf.name>
+ <weld.docbook.version>1.1.1-Beta5</weld.docbook.version>
+ </properties>
+
+ <build>
+ <defaultGoal>process-classes</defaultGoal>
+ <plugins>
+ <plugin>
+ <artifactId>maven-deploy-plugin</artifactId>
+ <configuration>
+ <skip>true</skip>
+ </configuration>
+ </plugin>
+
+ <plugin>
+ <groupId>org.jboss.maven.plugins</groupId>
+ <artifactId>maven-jdocbook-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <artifactId>maven-antrun-plugin</artifactId>
+ <executions>
+ <execution>
+ <phase>process-classes</phase>
+ <configuration>
+ <tasks>
+ <copy file="${basedir}/target/docbook/publish/en-US/pdf/${pdf.name}" todir="${basedir}" />
+ </tasks>
+ </configuration>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>build-helper-maven-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>attach-zip</id>
+ <phase>package</phase>
+ <goals>
+ <goal>attach-artifact</goal>
+ </goals>
+ <configuration>
+ <artifacts>
+ <artifact>
+ <file>${project.build.outputDirectory}/${project.artifactId}-${project.version}.war</file>
+ <type>war</type>
+ </artifact>
+ </artifacts>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+
+ <profiles>
+
+ <profile>
+ <id>translations</id>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.jboss.maven.plugins</groupId>
+ <artifactId>maven-jdocbook-plugin</artifactId>
+
+ <executions>
+ <execution>
+ <phase>process-resources</phase>
+ <goals>
+ <goal>translate</goal>
+ </goals>
+ </execution>
+ </executions>
+
+ <configuration>
+ <translations>
+ <!--translation>it-IT</translation>
+ <translation>zh-CN</translation>
+ <translation>zh-TW</translation>
+ <translation>es-ES</translation>
+ <translation>ko-KR</translation>
+
+ <translation>de-DE</translation>
+ <translation>pt-BR</translation-->
+ </translations>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+
+ </profiles>
+
+
+ <scm>
+ <connection>scm:svn:http://anonsvn.jboss.org/repos/seam/modules/drools/trunk/docs</connection>
+ <developerConnection>scm:svn:https://svn.jboss.org/repos/seam/modules/drools/trunk/docs</developerConnection>
+ <url>http://fisheye.jboss.org/browse/seam/modules/drools/docs</url>
+ </scm>
+
+</project>
+
Added: modules/drools/trunk/lgpl.txt
===================================================================
--- modules/drools/trunk/lgpl.txt (rev 0)
+++ modules/drools/trunk/lgpl.txt 2010-03-26 04:56:04 UTC (rev 12291)
@@ -0,0 +1,504 @@
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL. It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+ This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it. You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+ When we speak of free software, we are referring to freedom of use,
+not price. Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+ To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights. These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+
+ We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ To protect each distributor, we want to make it very clear that
+there is no warranty for the free library. Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+ Finally, software patents pose a constant threat to the existence of
+any free program. We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder. Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+ Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License. This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License. We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+ When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library. The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom. The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+ We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License. It also provides other free software developers Less
+of an advantage over competing non-free programs. These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries. However, the Lesser license provides advantages in certain
+special circumstances.
+
+ For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard. To achieve this, non-free programs must be
+allowed to use the library. A more frequent case is that a free
+library does the same job as widely used non-free libraries. In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+ In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software. For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+ Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+ The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+ GNU LESSER GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+ A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+ The "Library", below, refers to any such software library or work
+which has been distributed under these terms. A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+ "Source code" for a work means the preferred form of the work for
+making modifications to it. For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+ Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+ 1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+ You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+ 2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) The modified work must itself be a software library.
+
+ b) You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ c) You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ d) If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility
+ is invoked, then you must make a good faith effort to ensure that,
+ in the event an application does not supply such function or
+ table, the facility still operates, and performs whatever part of
+ its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots has
+ a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square
+ root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+
+ Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+ 4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+ If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library". Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+ However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library". The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+ When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+
+ If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+ 6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+
+ a) Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood
+ that the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+
+ b) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (1) uses at run time a
+ copy of the library already present on the user's computer system,
+ rather than copying library functions into the executable, and (2)
+ will operate properly with a modified version of the library, if
+ the user installs one, as long as the modified version is
+ interface-compatible with the version that the work was made with.
+
+ c) Accompany the work with a written offer, valid for at
+ least three years, to give the same user the materials
+ specified in Subsection 6a, above, for a charge no more
+ than the cost of performing this distribution.
+
+ d) If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+
+ e) Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+ For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it. However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+ It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+ 7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+ a) Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the
+ Sections above.
+
+ b) Give prominent notice with the combined library of the fact
+ that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same work.
+
+ 8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License. However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+ 9. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Library or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+ 10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+
+ 11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded. In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+ 13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation. If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+ 14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission. For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this. Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+ NO WARRANTY
+
+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Libraries
+
+ If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change. You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+ To apply these terms, attach the following notices to the library. It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the library's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the
+ library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+ <signature of Ty Coon>, 1 April 1990
+ Ty Coon, President of Vice
+
+That's all there is to it!
+
+
Added: modules/drools/trunk/pom.xml
===================================================================
--- modules/drools/trunk/pom.xml (rev 0)
+++ modules/drools/trunk/pom.xml 2010-03-26 04:56:04 UTC (rev 12291)
@@ -0,0 +1,99 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <artifactId>weld-parent</artifactId>
+ <groupId>org.jboss.weld</groupId>
+ <version>8</version>
+ </parent>
+
+ <groupId>org.jboss.seam.drools</groupId>
+ <artifactId>seam-drools-parent</artifactId>
+ <packaging>pom</packaging>
+ <version>3.0.0-SNAPSHOT</version>
+ <name>Seam Drools Parent</name>
+
+ <modules>
+ <module>core</module>
+ <module>docs</module>
+ <!-- <module>examples</module> -->
+ </modules>
+
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-assembly-plugin</artifactId>
+ <version>2.2-beta-5</version>
+ <configuration>
+ <descriptors>
+ <descriptor>assembly.xml</descriptor>
+ </descriptors>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+ <dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>javax.el</groupId>
+ <artifactId>el-api</artifactId>
+ <version>2.2</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>javax.validation</groupId>
+ <artifactId>validation-api</artifactId>
+ <version>1.0.0.GA</version>
+ </dependency>
+ <dependency>
+ <groupId>javax.enterprise</groupId>
+ <artifactId>cdi-api</artifactId>
+ <version>1.0-SP1</version>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ <version>1.5.10</version>
+ </dependency>
+ <dependency>
+ <groupId>org.drools</groupId>
+ <artifactId>drools-core</artifactId>
+ <version>5.1.0.M1</version>
+ </dependency>
+ <dependency>
+ <groupId>org.drools</groupId>
+ <artifactId>drools-compiler</artifactId>
+ <version>5.1.0.M1</version>
+ </dependency>
+ <dependency>
+ <groupId>org.drools</groupId>
+ <artifactId>drools-api</artifactId>
+ <version>5.1.0.M1</version>
+ </dependency>
+ <dependency>
+ <groupId>org.drools</groupId>
+ <artifactId>drools-templates</artifactId>
+ <version>5.1.0.M1</version>
+ </dependency>
+ <dependency>
+ <groupId>org.drools</groupId>
+ <artifactId>drools-decisiontables</artifactId>
+ <version>5.1.0.M1</version>
+ </dependency>
+ <dependency>
+ <groupId>org.drools</groupId>
+ <artifactId>drools-workitems</artifactId>
+ <version>5.1.0.M1</version>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+
+ <scm>
+ <connection>scm:svn:http://anonsvn.jboss.org/repos/seam/modules/drools/trunk</connection>
+ <developerConnection>scm:svn:https://svn.jboss.org/repos/seam/modules/drools/trunk</developerConnection>
+ <url>http://fisheye.jboss.org/browse/Seam/modules/drools/trunk</url>
+ </scm>
+
+</project>
Added: modules/drools/trunk/readme.txt
===================================================================
--- modules/drools/trunk/readme.txt (rev 0)
+++ modules/drools/trunk/readme.txt 2010-03-26 04:56:04 UTC (rev 12291)
@@ -0,0 +1,64 @@
+Seam Drools 3.0.0 Beta 1
+==========================
+
+Seam Drools provides integration with the Drools 5 API.
+
+
+Contents of distribution
+========================
+
+doc/
+
+ API Docs and reference guide.
+
+examples/
+
+ Seam Drools Examples
+
+lib/
+
+ Seam Drools jar files
+
+Licensing
+=========
+
+This distribution, as a whole, is licensed under the terms of the GNU Lesser General Public License
+(LGPL) Version 2.1, the text of which is contained in the file lgpl.txt.
+
+Seam Remoting URLs
+==================
+
+Seam Framework Home Page: http://www.seamframework.org
+Downloads: http://www.seamframework.org/Download/SeamDownloads
+Forums: http://www.seamframework.org/Community/SeamUsers
+Source Code: http://anonsvn.jboss.org/repos/seam/modules/drools/
+Issue Tracking: http://jira.jboss.org/jira/browse/SEAMDROOLS
+
+Release Notes
+=============
+
+Version 3.0.0 Beta 1
+--------------------
+First beta release of Seam Drools 3.x, ported from Seam 2.x to CDI.
+
+
+* If using Maven, some artifacts may only be available in the JBoss Repository. To allow Seam Remoting to correctly function, add the JBoss Repository to Maven. Edit your ~/.m2/settings.xml, and add the following entry:
+
+ <profile>
+ <id>jboss.repository</id>
+ <activation>
+ <activeByDefault>true</activeByDefault>
+ </activation>
+ <repositories>
+ <repository>
+ <id>repository.jboss.org</id>
+ <url>http://repository.jboss.org/maven2</url>
+ <releases>
+ <enabled>true</enabled>
+ </releases>
+ <snapshots>
+ <enabled>false</enabled>
+ </snapshots>
+ </repository>
+ </repositories>
+ </profile>
14 years, 9 months
Seam SVN: r12290 - modules.
by seam-commits@lists.jboss.org
Author: tsurdilovic
Date: 2010-03-26 00:54:53 -0400 (Fri, 26 Mar 2010)
New Revision: 12290
Added:
modules/drools/
Log:
14 years, 9 months
Seam SVN: r12289 - modules.
by seam-commits@lists.jboss.org
Author: tsurdilovic
Date: 2010-03-26 00:54:30 -0400 (Fri, 26 Mar 2010)
New Revision: 12289
Removed:
modules/trunk/
Log:
14 years, 9 months
Seam SVN: r12288 - modules.
by seam-commits@lists.jboss.org
Author: tsurdilovic
Date: 2010-03-26 00:54:08 -0400 (Fri, 26 Mar 2010)
New Revision: 12288
Removed:
modules/tags/
Log:
14 years, 9 months
Seam SVN: r12287 - modules.
by seam-commits@lists.jboss.org
Author: tsurdilovic
Date: 2010-03-26 00:53:52 -0400 (Fri, 26 Mar 2010)
New Revision: 12287
Removed:
modules/branches/
Log:
14 years, 9 months
Seam SVN: r12286 - in modules: trunk and 17 other directories.
by seam-commits@lists.jboss.org
Author: tsurdilovic
Date: 2010-03-26 00:53:15 -0400 (Fri, 26 Mar 2010)
New Revision: 12286
Added:
modules/branches/
modules/tags/
modules/trunk/
modules/trunk/.project
modules/trunk/.settings/
modules/trunk/.settings/org.maven.ide.eclipse.prefs
modules/trunk/assembly.xml
modules/trunk/core/
modules/trunk/core/.classpath
modules/trunk/core/.project
modules/trunk/core/.settings/
modules/trunk/core/.settings/org.eclipse.jdt.core.prefs
modules/trunk/core/.settings/org.maven.ide.eclipse.prefs
modules/trunk/core/pom.xml
modules/trunk/core/src/
modules/trunk/core/src/main/
modules/trunk/core/src/main/java/
modules/trunk/core/src/main/java/META-INF/
modules/trunk/core/src/main/java/META-INF/MANIFEST.MF
modules/trunk/core/src/main/java/org/
modules/trunk/core/src/main/java/org/jboss/
modules/trunk/core/src/main/java/org/jboss/seam/
modules/trunk/core/src/main/java/org/jboss/seam/drools/
modules/trunk/core/src/main/java/org/jboss/seam/drools/FactProvider.java
modules/trunk/core/src/main/java/org/jboss/seam/drools/KnowledgeBaseManager.java
modules/trunk/core/src/main/java/org/jboss/seam/drools/KnowledgeBaseManagerConfig.java
modules/trunk/core/src/main/java/org/jboss/seam/drools/KnowledgeSessionManager.java
modules/trunk/core/src/main/java/org/jboss/seam/drools/KnowledgeSessionManagerConfig.java
modules/trunk/core/src/main/java/org/jboss/seam/drools/TemplateDataProvider.java
modules/trunk/core/src/main/java/org/jboss/seam/drools/events/
modules/trunk/core/src/main/java/org/jboss/seam/drools/events/KnowledgeBuilderErrorsEvent.java
modules/trunk/core/src/main/java/org/jboss/seam/drools/events/KnowledgeSessionCreatedEvent.java
modules/trunk/core/src/main/java/org/jboss/seam/drools/events/RuleResourceAddedEvent.java
modules/trunk/core/src/main/resources/
modules/trunk/core/src/main/resources/META-INF/
modules/trunk/core/src/test/
modules/trunk/core/src/test/java/
modules/trunk/distribution.txt
modules/trunk/docs/
modules/trunk/docs/.classpath
modules/trunk/docs/.project
modules/trunk/docs/.settings/
modules/trunk/docs/.settings/org.eclipse.jdt.core.prefs
modules/trunk/docs/.settings/org.maven.ide.eclipse.prefs
modules/trunk/docs/README.TXT
modules/trunk/docs/drools-reference.pdf
modules/trunk/docs/en-US/
modules/trunk/docs/en-US/drools-general.xml
modules/trunk/docs/en-US/drools-model.xml
modules/trunk/docs/en-US/images/
modules/trunk/docs/en-US/master.xml
modules/trunk/docs/pom.xml
modules/trunk/examples/
modules/trunk/lgpl.txt
modules/trunk/pom.xml
modules/trunk/readme.txt
Log:
new drools module structure
Added: modules/trunk/.project
===================================================================
--- modules/trunk/.project (rev 0)
+++ modules/trunk/.project 2010-03-26 04:53:15 UTC (rev 12286)
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>drools</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.wst.common.project.facet.core.builder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.maven.ide.eclipse.maven2Builder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.maven.ide.eclipse.maven2Nature</nature>
+ <nature>org.eclipse.wst.common.project.facet.core.nature</nature>
+ </natures>
+</projectDescription>
Added: modules/trunk/.settings/org.maven.ide.eclipse.prefs
===================================================================
--- modules/trunk/.settings/org.maven.ide.eclipse.prefs (rev 0)
+++ modules/trunk/.settings/org.maven.ide.eclipse.prefs 2010-03-26 04:53:15 UTC (rev 12286)
@@ -0,0 +1,9 @@
+#Fri Mar 26 00:04:15 EDT 2010
+activeProfiles=
+eclipse.preferences.version=1
+fullBuildGoals=process-test-resources
+includeModules=false
+resolveWorkspaceProjects=true
+resourceFilterGoals=process-resources resources\:testResources
+skipCompilerPlugin=true
+version=1
Added: modules/trunk/assembly.xml
===================================================================
--- modules/trunk/assembly.xml (rev 0)
+++ modules/trunk/assembly.xml 2010-03-26 04:53:15 UTC (rev 12286)
@@ -0,0 +1,69 @@
+<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
+ <id>bin</id>
+ <formats>
+ <format>zip</format>
+ </formats>
+ <includeBaseDirectory>false</includeBaseDirectory>
+
+ <fileSets>
+ <fileSet>
+ <directory>core/target/site/apidocs</directory>
+ <outputDirectory>seam-drools/doc/api</outputDirectory>
+ <includes>
+ <include>**</include>
+ </includes>
+ </fileSet>
+
+ <fileSet>
+ <directory>examples</directory>
+ <outputDirectory>seam-drools/examples</outputDirectory>
+ <useDefaultExcludes>true</useDefaultExcludes>
+ <includes>
+ <!-- <include>seamspace/pom.xml</include>
+ <include>seamspace/src/**</include> -->
+ </includes>
+ </fileSet>
+
+ <fileSet>
+ <directory>.</directory>
+ <outputDirectory>seam-drools</outputDirectory>
+ <includes>
+ <include>readme.txt</include>
+ <include>lgpl.txt</include>
+ </includes>
+ </fileSet>
+
+ <fileSet>
+ <directory>core/src/main/java</directory>
+ <outputDirectory>seam-drools/source</outputDirectory>
+ <includes>
+ <include>**</include>
+ </includes>
+ </fileSet>
+ </fileSets>
+
+ <moduleSets>
+ <moduleSet>
+ <includes>
+ <include>org.jboss.seam.drools:seam-drools-core:jar</include>
+ </includes>
+ <binaries>
+ <outputDirectory>seam-drools/lib</outputDirectory>
+ <unpack>false</unpack>
+ </binaries>
+ </moduleSet>
+
+ <moduleSet>
+ <includes>
+ <include>org.jboss.seam.drools:seam-drools-reference-guide</include>
+ </includes>
+ <binaries>
+ <outputDirectory>seam-drools/doc/reference</outputDirectory>
+ <unpack>true</unpack>
+ </binaries>
+ </moduleSet>
+
+ </moduleSets>
+</assembly>
Added: modules/trunk/core/.classpath
===================================================================
--- modules/trunk/core/.classpath (rev 0)
+++ modules/trunk/core/.classpath 2010-03-26 04:53:15 UTC (rev 12286)
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="src" output="target/classes" path="src/main/java"/>
+ <classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources"/>
+ <classpathentry kind="src" output="target/test-classes" path="src/test/java"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+ <classpathentry kind="con" path="org.maven.ide.eclipse.MAVEN2_CLASSPATH_CONTAINER"/>
+ <classpathentry kind="output" path="target/classes"/>
+</classpath>
Added: modules/trunk/core/.project
===================================================================
--- modules/trunk/core/.project (rev 0)
+++ modules/trunk/core/.project 2010-03-26 04:53:15 UTC (rev 12286)
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>seam-drools-core</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.wst.common.project.facet.core.builder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.maven.ide.eclipse.maven2Builder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ <nature>org.maven.ide.eclipse.maven2Nature</nature>
+ <nature>org.eclipse.wst.common.project.facet.core.nature</nature>
+ </natures>
+</projectDescription>
Added: modules/trunk/core/.settings/org.eclipse.jdt.core.prefs
===================================================================
--- modules/trunk/core/.settings/org.eclipse.jdt.core.prefs (rev 0)
+++ modules/trunk/core/.settings/org.eclipse.jdt.core.prefs 2010-03-26 04:53:15 UTC (rev 12286)
@@ -0,0 +1,6 @@
+#Fri Mar 26 00:27:07 EDT 2010
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
+org.eclipse.jdt.core.compiler.source=1.5
Added: modules/trunk/core/.settings/org.maven.ide.eclipse.prefs
===================================================================
--- modules/trunk/core/.settings/org.maven.ide.eclipse.prefs (rev 0)
+++ modules/trunk/core/.settings/org.maven.ide.eclipse.prefs 2010-03-26 04:53:15 UTC (rev 12286)
@@ -0,0 +1,9 @@
+#Thu Mar 25 23:57:23 EDT 2010
+activeProfiles=
+eclipse.preferences.version=1
+fullBuildGoals=process-test-resources
+includeModules=false
+resolveWorkspaceProjects=true
+resourceFilterGoals=process-resources resources\:testResources
+skipCompilerPlugin=true
+version=1
Added: modules/trunk/core/pom.xml
===================================================================
--- modules/trunk/core/pom.xml (rev 0)
+++ modules/trunk/core/pom.xml 2010-03-26 04:53:15 UTC (rev 12286)
@@ -0,0 +1,68 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.jboss.seam.drools</groupId>
+ <artifactId>seam-drools-parent</artifactId>
+ <version>3.0.0-SNAPSHOT</version>
+ </parent>
+
+ <groupId>org.jboss.seam.drools</groupId>
+ <artifactId>seam-drools-core</artifactId>
+ <version>3.0.0-SNAPSHOT</version>
+ <packaging>jar</packaging>
+ <name>Seam Drools Core</name>
+
+ <dependencies>
+ <dependency>
+ <groupId>javax.el</groupId>
+ <artifactId>el-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>javax.validation</groupId>
+ <artifactId>validation-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>javax.enterprise</groupId>
+ <artifactId>cdi-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.drools</groupId>
+ <artifactId>drools-core</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.drools</groupId>
+ <artifactId>drools-compiler</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.drools</groupId>
+ <artifactId>drools-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.drools</groupId>
+ <artifactId>drools-templates</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.drools</groupId>
+ <artifactId>drools-decisiontables</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.drools</groupId>
+ <artifactId>drools-workitems</artifactId>
+ </dependency>
+ </dependencies>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-javadoc-plugin</artifactId>
+ <version>2.6.1</version>
+ </plugin>
+ </plugins>
+ </build>
+
+</project>
Added: modules/trunk/core/src/main/java/META-INF/MANIFEST.MF
===================================================================
--- modules/trunk/core/src/main/java/META-INF/MANIFEST.MF (rev 0)
+++ modules/trunk/core/src/main/java/META-INF/MANIFEST.MF 2010-03-26 04:53:15 UTC (rev 12286)
@@ -0,0 +1,2 @@
+Manifest-Version: 1.0
+Class-Path:
Added: modules/trunk/core/src/main/java/org/jboss/seam/drools/FactProvider.java
===================================================================
--- modules/trunk/core/src/main/java/org/jboss/seam/drools/FactProvider.java (rev 0)
+++ modules/trunk/core/src/main/java/org/jboss/seam/drools/FactProvider.java 2010-03-26 04:53:15 UTC (rev 12286)
@@ -0,0 +1,20 @@
+package org.jboss.seam.drools;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Interface for fact providers.
+ *
+ * @author Tihomir Surdilovic
+ *
+ */
+public interface FactProvider
+{
+ public List<Object> getFacts();
+ public void setFacts(List<Object> facts);
+
+ public Map<String, Object> getGlobals();
+ public void setGlobals(Map<String, Object> globals);
+
+}
\ No newline at end of file
Added: modules/trunk/core/src/main/java/org/jboss/seam/drools/KnowledgeBaseManager.java
===================================================================
--- modules/trunk/core/src/main/java/org/jboss/seam/drools/KnowledgeBaseManager.java (rev 0)
+++ modules/trunk/core/src/main/java/org/jboss/seam/drools/KnowledgeBaseManager.java 2010-03-26 04:53:15 UTC (rev 12286)
@@ -0,0 +1,207 @@
+package org.jboss.seam.drools;
+
+import java.io.InputStream;
+import java.io.Reader;
+import java.io.StringReader;
+import java.util.Properties;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.enterprise.inject.Disposes;
+import javax.enterprise.inject.Produces;
+import javax.enterprise.inject.spi.Bean;
+import javax.enterprise.inject.spi.BeanManager;
+import javax.inject.Inject;
+import javax.security.auth.login.Configuration;
+
+import org.drools.KnowledgeBase;
+import org.drools.KnowledgeBaseConfiguration;
+import org.drools.KnowledgeBaseFactory;
+import org.drools.builder.KnowledgeBuilder;
+import org.drools.builder.KnowledgeBuilderConfiguration;
+import org.drools.builder.KnowledgeBuilderError;
+import org.drools.builder.KnowledgeBuilderErrors;
+import org.drools.builder.KnowledgeBuilderFactory;
+import org.drools.builder.ResourceType;
+import org.drools.event.knowledgebase.KnowledgeBaseEventListener;
+import org.drools.io.ResourceFactory;
+import org.drools.template.ObjectDataCompiler;
+import org.jboss.seam.drools.events.KnowledgeBuilderErrorsEvent;
+import org.jboss.seam.drools.events.RuleResourceAddedEvent;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Manager component for a Drools KnowledgeBase.
+ *
+ * @author Tihomir Surdilovic
+ */
+public class KnowledgeBaseManager
+{
+ private static final Logger log = LoggerFactory.getLogger(KnowledgeBaseManager.class);
+
+ private KnowledgeBaseManagerConfig kbaseManagerConfig;
+
+ @Inject
+ BeanManager manager;
+
+ @Inject
+ public KnowledgeBaseManager(KnowledgeBaseManagerConfig kbaseManagerConfig) {
+ this.kbaseManagerConfig = kbaseManagerConfig;
+ }
+
+ @Produces
+ @ApplicationScoped
+ public KnowledgeBase createKBase() throws Exception
+ {
+ KnowledgeBase kbase;
+ KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder(getKnowledgeBuilderConfiguration());
+
+ for (String nextResource : kbaseManagerConfig.getRuleResources())
+ {
+ addResource(kbuilder, nextResource);
+ }
+
+ KnowledgeBuilderErrors kbuildererrors = kbuilder.getErrors();
+ if (kbuildererrors.size() > 0)
+ {
+ for (KnowledgeBuilderError kbuildererror : kbuildererrors)
+ {
+ log.error(kbuildererror.getMessage());
+ }
+ manager.fireEvent(new KnowledgeBuilderErrorsEvent(kbuildererrors));
+ }
+
+ kbase = KnowledgeBaseFactory.newKnowledgeBase(getKnowledgeBaseConfiguration());
+ kbase.addKnowledgePackages(kbuilder.getKnowledgePackages());
+
+ if (kbaseManagerConfig.getEventListeners() != null)
+ {
+ for (String eventListener : kbaseManagerConfig.getEventListeners())
+ {
+ addEventListener(kbase, eventListener);
+ }
+ }
+ return kbase;
+ }
+
+ public void disposeKBase(@Disposes KnowledgeBase kbase)
+ {
+ kbase = null;
+ }
+
+ private void addEventListener(org.drools.KnowledgeBase kbase, String eventListener) {
+ try {
+ @SuppressWarnings("unchecked")
+ Class eventListenerClass = Class.forName(eventListener);
+ Object eventListenerObject = eventListenerClass.newInstance();
+
+ if(eventListenerObject instanceof KnowledgeBaseEventListener) {
+ kbase.addEventListener((KnowledgeBaseEventListener) eventListenerObject);
+ } else {
+ log.debug("Event Listener " + eventListener + " is not of type KnowledgeBaseEventListener");
+ }
+ } catch(Exception e) {
+ log.error("Error adding event listener " + e.getMessage());
+ }
+ }
+
+ protected void addResource(KnowledgeBuilder kbuilder, String resource) throws Exception
+ {
+ if(KnowledgeBaseManagerConfig.isValidResource(resource)) {
+ ResourceType resourceType = ResourceType.getResourceType(KnowledgeBaseManagerConfig.getResourceType(resource));
+ if(KnowledgeBaseManagerConfig.isRuleTemplate(resource)) {
+ @SuppressWarnings("unchecked")
+ Bean<TemplateDataProvider> templateDataProviderBean = (Bean<TemplateDataProvider>) manager.getBeans(KnowledgeBaseManagerConfig.getTemplateData(resource)).iterator().next();
+
+ TemplateDataProvider templateDataProvider = (TemplateDataProvider) manager.getReference(templateDataProviderBean, Configuration.class, manager.createCreationalContext(templateDataProviderBean));
+
+ InputStream templateStream = this.getClass().getClassLoader().getResourceAsStream(KnowledgeBaseManagerConfig.getRuleResource(resource));
+ if (templateStream == null)
+ {
+ throw new IllegalStateException("Could not locate rule resource: " + KnowledgeBaseManagerConfig.getRuleResource(resource));
+ }
+
+ ObjectDataCompiler converter = new ObjectDataCompiler();
+ String drl = converter.compile(templateDataProvider.getTemplateData(), templateStream);
+ templateStream.close();
+ log.debug("Generated following DRL from template: " + drl);
+ Reader rdr = new StringReader(drl);
+
+ kbuilder.add(ResourceFactory.newReaderResource(rdr), resourceType);
+ } else {
+ if (KnowledgeBaseManagerConfig.getResourcePath(resource).equals(KnowledgeBaseManagerConfig.RESOURCE_TYPE_URL))
+ {
+ kbuilder.add(ResourceFactory.newUrlResource(KnowledgeBaseManagerConfig.getRuleResource(resource)), resourceType);
+ manager.fireEvent(new RuleResourceAddedEvent(KnowledgeBaseManagerConfig.getRuleResource(resource)));
+ }
+ else if (KnowledgeBaseManagerConfig.getResourcePath(resource).equals(KnowledgeBaseManagerConfig.RESOURCE_TYPE_FILE))
+ {
+ kbuilder.add(ResourceFactory.newFileResource(KnowledgeBaseManagerConfig.getRuleResource(resource)), resourceType);
+ manager.fireEvent(new RuleResourceAddedEvent(KnowledgeBaseManagerConfig.getRuleResource(resource)));
+ }
+ else if (KnowledgeBaseManagerConfig.getResourcePath(resource).equals(KnowledgeBaseManagerConfig.RESOURCE_TYPE_CLASSPATH))
+ {
+ kbuilder.add(ResourceFactory.newClassPathResource(KnowledgeBaseManagerConfig.getRuleResource(resource)), resourceType);
+ manager.fireEvent(new RuleResourceAddedEvent(KnowledgeBaseManagerConfig.getRuleResource(resource)));
+ }
+ else
+ {
+ log.error("Invalid resource path: " + KnowledgeBaseManagerConfig.getResourcePath(resource));
+ }
+ }
+ } else {
+ log.error("Invalid resource definition: " + resource);
+ }
+ }
+
+ public KnowledgeBuilderConfiguration getKnowledgeBuilderConfiguration() throws Exception
+ {
+ KnowledgeBuilderConfiguration kbuilderconfig = KnowledgeBuilderFactory.newKnowledgeBuilderConfiguration();
+ if(kbaseManagerConfig.getKnowledgeBuilderConfigProp() != null) {
+ kbuilderconfig = KnowledgeBuilderFactory.newKnowledgeBuilderConfiguration(kbaseManagerConfig.getKnowledgeBuilderConfigProp(), null);
+ log.debug("KnowledgeBuilderConfiguration loaded: " + kbaseManagerConfig.getKnowledgeBuilderConfigProp());
+ } else {
+ // Only allow resource for .properties files
+ if (kbaseManagerConfig.getKnowledgeBuilderConfig() != null && kbaseManagerConfig.getKnowledgeBuilderConfig().endsWith(".properties"))
+ {
+ Properties kbuilderProp = new Properties();
+ InputStream in = this.getClass().getClassLoader().getResourceAsStream(kbaseManagerConfig.getKnowledgeBuilderConfig());
+ if (in == null)
+ {
+ throw new IllegalStateException("Could not locate knowledgeBuilderConfig: " + kbaseManagerConfig.getKnowledgeBuilderConfig());
+ }
+ kbuilderProp.load(in);
+ in.close();
+ kbuilderconfig = KnowledgeBuilderFactory.newKnowledgeBuilderConfiguration(kbuilderProp, null);
+ log.debug("KnowledgeBuilderConfiguration loaded: " + kbaseManagerConfig.getKnowledgeBuilderConfig());
+ }
+ }
+ return kbuilderconfig;
+ }
+
+ public KnowledgeBaseConfiguration getKnowledgeBaseConfiguration() throws Exception
+ {
+ KnowledgeBaseConfiguration kbaseconfig = KnowledgeBaseFactory.newKnowledgeBaseConfiguration();
+
+ if(kbaseManagerConfig.getKnowledgeBaseConfigProp() != null) {
+ kbaseconfig = KnowledgeBaseFactory.newKnowledgeBaseConfiguration(kbaseManagerConfig.getKnowledgeBaseConfigProp(), null);
+ log.debug("KnowledgeBaseConfiguration loaded: " + kbaseManagerConfig.getKnowledgeBaseConfigProp());
+ } else {
+ // Only allow resource for .properties files
+ if (kbaseManagerConfig.getKnowledgeBaseConfig() != null && kbaseManagerConfig.getKnowledgeBaseConfig().endsWith(".properties"))
+ {
+ Properties kbaseProp = new Properties();
+ InputStream in = this.getClass().getClassLoader().getResourceAsStream(kbaseManagerConfig.getKnowledgeBaseConfig());
+ if (in == null)
+ {
+ throw new IllegalStateException("Could not locate knowledgeBaseConfig: " + kbaseManagerConfig.getKnowledgeBaseConfig());
+ }
+ kbaseProp.load(in);
+ in.close();
+ kbaseconfig = KnowledgeBaseFactory.newKnowledgeBaseConfiguration(kbaseProp, null);
+ log.debug("KnowledgeBaseConfiguration loaded: " + kbaseManagerConfig.getKnowledgeBaseConfig());
+ }
+ }
+ return kbaseconfig;
+ }
+}
\ No newline at end of file
Added: modules/trunk/core/src/main/java/org/jboss/seam/drools/KnowledgeBaseManagerConfig.java
===================================================================
--- modules/trunk/core/src/main/java/org/jboss/seam/drools/KnowledgeBaseManagerConfig.java (rev 0)
+++ modules/trunk/core/src/main/java/org/jboss/seam/drools/KnowledgeBaseManagerConfig.java 2010-03-26 04:53:15 UTC (rev 12286)
@@ -0,0 +1,116 @@
+package org.jboss.seam.drools;
+
+import java.util.Properties;
+import java.util.regex.Pattern;
+
+/**
+ * KnowledgeBaseManager Configuration.
+ *
+ * @author Tihomir Surdilovic
+ */
+public class KnowledgeBaseManagerConfig
+{
+ private static final Pattern DIVIDER = Pattern.compile(";");
+ private static final int RESOURCE_PATH = 0;
+ private static final int RESOURCE = 1;
+ private static final int RESOURCE_TYPE = 2;
+ private static final int RESOURCE_TEMPLATE_DATA = 3;
+
+ public static final String RESOURCE_TYPE_URL = "url";
+ public static final String RESOURCE_TYPE_FILE = "file";
+ public static final String RESOURCE_TYPE_CLASSPATH = "classpath";
+
+ private String knowledgeBuilderConfig;
+ private String knowledgeBaseConfig;
+ private Properties knowledgeBuilderConfigProp;
+ private Properties knowledgeBaseConfigProp;
+ private String[] ruleResources;
+ private String[] eventListeners;
+
+ public static boolean isValidResource(String resource) {
+ return DIVIDER.split(resource.trim()).length >= 3;
+ }
+
+ public static boolean isRuleTemplate(String resource) {
+ return DIVIDER.split(resource.trim()).length == 4;
+ }
+
+ public static String getResourceType(String resource) {
+ return DIVIDER.split(resource.trim())[RESOURCE_TYPE];
+ }
+
+ public static String getRuleResource(String resource) {
+ return DIVIDER.split(resource.trim())[RESOURCE];
+ }
+
+ public static String getTemplateData(String resource) {
+ return DIVIDER.split(resource.trim())[RESOURCE_TEMPLATE_DATA];
+ }
+
+ public static String getResourcePath(String resource) {
+ return DIVIDER.split(resource.trim())[RESOURCE_PATH];
+ }
+
+ public String getKnowledgeBuilderConfig()
+ {
+ return knowledgeBuilderConfig;
+ }
+
+ public void setKnowledgeBuilderConfig(String knowledgeBuilderConfig)
+ {
+ this.knowledgeBuilderConfig = knowledgeBuilderConfig;
+ }
+
+ public String getKnowledgeBaseConfig()
+ {
+ return knowledgeBaseConfig;
+ }
+
+ public void setKnowledgeBaseConfig(String knowledgeBaseConfig)
+ {
+ this.knowledgeBaseConfig = knowledgeBaseConfig;
+ }
+
+ public String[] getRuleResources()
+ {
+ return ruleResources;
+ }
+
+ public void setRuleResources(String[] ruleResources)
+ {
+ this.ruleResources = ruleResources;
+ }
+
+ public String[] getEventListeners()
+ {
+ return eventListeners;
+ }
+
+ public void setEventListeners(String[] eventListeners)
+ {
+ this.eventListeners = eventListeners;
+ }
+
+ public Properties getKnowledgeBuilderConfigProp()
+ {
+ return knowledgeBuilderConfigProp;
+ }
+
+ public void setKnowledgeBuilderConfigProp(Properties knowledgeBuilderConfigProp)
+ {
+ this.knowledgeBuilderConfigProp = knowledgeBuilderConfigProp;
+ }
+
+ public Properties getKnowledgeBaseConfigProp()
+ {
+ return knowledgeBaseConfigProp;
+ }
+
+ public void setKnowledgeBaseConfigProp(Properties knowledgeBaseConfigProp)
+ {
+ this.knowledgeBaseConfigProp = knowledgeBaseConfigProp;
+ }
+
+
+
+}
Added: modules/trunk/core/src/main/java/org/jboss/seam/drools/KnowledgeSessionManager.java
===================================================================
--- modules/trunk/core/src/main/java/org/jboss/seam/drools/KnowledgeSessionManager.java (rev 0)
+++ modules/trunk/core/src/main/java/org/jboss/seam/drools/KnowledgeSessionManager.java 2010-03-26 04:53:15 UTC (rev 12286)
@@ -0,0 +1,186 @@
+package org.jboss.seam.drools;
+
+import java.io.InputStream;
+import java.util.Hashtable;
+import java.util.Map;
+import java.util.Properties;
+
+import java.lang.annotation.Annotation;
+import javax.enterprise.inject.Any;
+import javax.enterprise.inject.Disposes;
+import javax.enterprise.inject.Instance;
+import javax.enterprise.inject.Produces;
+import javax.enterprise.inject.spi.Bean;
+import javax.enterprise.inject.spi.BeanManager;
+import javax.enterprise.inject.spi.InjectionPoint;
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.security.auth.login.Configuration;
+
+import org.drools.KnowledgeBase;
+import org.drools.KnowledgeBaseFactory;
+import org.drools.event.process.ProcessEventListener;
+import org.drools.event.rule.AgendaEventListener;
+import org.drools.event.rule.WorkingMemoryEventListener;
+import org.drools.logger.KnowledgeRuntimeLogger;
+import org.drools.logger.KnowledgeRuntimeLoggerFactory;
+import org.drools.runtime.KnowledgeSessionConfiguration;
+import org.drools.runtime.StatefulKnowledgeSession;
+import org.drools.runtime.StatelessKnowledgeSession;
+import org.drools.runtime.process.WorkItemHandler;
+import org.jboss.seam.drools.events.KnowledgeSessionCreatedEvent;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Manager component for a Drools Knowledge Sessions.
+ *
+ * @author Tihomir Surdilovic
+ */
+public class KnowledgeSessionManager
+{
+ private static final Logger log = LoggerFactory.getLogger(KnowledgeSessionManager.class);
+
+ private KnowledgeSessionManagerConfig ksessionManagerConfig;
+ private Map<Integer, KnowledgeRuntimeLogger> statefulKnowledgeLoggers = new Hashtable<Integer, KnowledgeRuntimeLogger>();
+
+ @Inject
+ BeanManager manager;
+
+ @Inject
+ public KnowledgeSessionManager(KnowledgeSessionManagerConfig ksessionManagerConfig)
+ {
+ this.ksessionManagerConfig = ksessionManagerConfig;
+ }
+
+ @Produces
+ @Any
+ public StatefulKnowledgeSession getStatefulSession(InjectionPoint ip, Instance<KnowledgeBase> kbase) throws Exception
+ {
+ StatefulKnowledgeSession ksession = kbase.select(ip.getQualifiers().toArray(new Annotation[0])).get().newStatefulKnowledgeSession(getKSessionConfig(), null);
+ addEventListeners(ksession);
+ addWorkItemHandlers(ksession);
+ addAuditLog(ksession);
+ manager.fireEvent(new KnowledgeSessionCreatedEvent(ksession.getId()));
+ return ksession;
+ }
+
+ public void disposeStatefulSession(@Disposes StatefulKnowledgeSession statefulSession)
+ {
+ if (statefulKnowledgeLoggers.get(statefulSession.getId()) != null)
+ {
+ statefulKnowledgeLoggers.get(statefulSession.getId()).close();
+ }
+ statefulSession.dispose();
+ }
+
+ @Produces
+ @Any
+ public StatelessKnowledgeSession getStatelessSession(InjectionPoint ip, Instance<KnowledgeBase> kbase) throws Exception
+ {
+ StatelessKnowledgeSession ksession = kbase.select(ip.getQualifiers().toArray(new Annotation[0])).get().newStatelessKnowledgeSession(getKSessionConfig());
+ addEventListeners(ksession);
+ manager.fireEvent(new KnowledgeSessionCreatedEvent(-1));
+ return ksession;
+ }
+
+ private KnowledgeSessionConfiguration getKSessionConfig() throws Exception
+ {
+ KnowledgeSessionConfiguration ksessionConfig = KnowledgeBaseFactory.newKnowledgeSessionConfiguration();
+ if(ksessionManagerConfig.getKnowledgeSessionConfigProp() != null) {
+ ksessionConfig = KnowledgeBaseFactory.newKnowledgeSessionConfiguration(ksessionManagerConfig.getKnowledgeSessionConfigProp());
+ } else {
+ // Only allow resource for .properties files
+ if (ksessionManagerConfig.getKnowledgeSessionConfig() != null && ksessionManagerConfig.getKnowledgeSessionConfig().endsWith(".properties"))
+ {
+ Properties ksessionProp = new Properties();
+ InputStream in = this.getClass().getClassLoader().getResourceAsStream(ksessionManagerConfig.getKnowledgeSessionConfig());
+ if (in == null)
+ {
+ throw new IllegalStateException("Could not locate knowledgeSessionrConfig: " + ksessionManagerConfig.getKnowledgeSessionConfig());
+ }
+ ksessionProp.load(in);
+ in.close();
+ ksessionConfig = KnowledgeBaseFactory.newKnowledgeSessionConfiguration(ksessionProp);
+ log.debug("KnowledgeSessionConfiguration loaded: " + ksessionManagerConfig.getKnowledgeSessionConfig());
+ }
+ }
+ return ksessionConfig;
+ }
+
+
+ private void addAuditLog(StatefulKnowledgeSession ksession) throws Exception {
+ if(ksessionManagerConfig.getAuditLog() != null) {
+ if(KnowledgeSessionManagerConfig.isFileLogger(ksessionManagerConfig.getAuditLog())) {
+ String logName = KnowledgeSessionManagerConfig.getFileLoggerPath(ksessionManagerConfig.getAuditLog()) + System.currentTimeMillis();
+ KnowledgeRuntimeLogger krLogger = KnowledgeRuntimeLoggerFactory.newFileLogger(ksession, logName);
+ statefulKnowledgeLoggers.put(ksession.getId(), krLogger);
+ } else if(KnowledgeSessionManagerConfig.isConsoleLogger(ksessionManagerConfig.getAuditLog())) {
+ KnowledgeRuntimeLogger krLogger = KnowledgeRuntimeLoggerFactory.newConsoleLogger(ksession);
+ statefulKnowledgeLoggers.put(ksession.getId(), krLogger);
+ } else if(KnowledgeSessionManagerConfig.isThreadedLogger(ksessionManagerConfig.getAuditLog())) {
+ String logName = KnowledgeSessionManagerConfig.getThreadedLoggerPath(ksessionManagerConfig.getAuditLog()) + System.currentTimeMillis();
+ int interval = KnowledgeSessionManagerConfig.getThreadedLoggerInterval(ksessionManagerConfig.getAuditLog());
+ KnowledgeRuntimeLogger krLogger = KnowledgeRuntimeLoggerFactory.newThreadedFileLogger(ksession, logName, interval);
+ statefulKnowledgeLoggers.put(ksession.getId(), krLogger);
+ } else {
+ log.warn("Invalid logger specified: " + ksessionManagerConfig.getAuditLog());
+ }
+ }
+ }
+
+ public void addEventListeners(StatefulKnowledgeSession ksession) throws Exception {
+ if(ksessionManagerConfig.getEventListeners() != null) {
+ for(String eventListener : ksessionManagerConfig.getEventListeners()) {
+ Class eventListenerClass = Class.forName(eventListener);
+ Object eventListenerObject = eventListenerClass.newInstance();
+
+ if(eventListenerObject instanceof WorkingMemoryEventListener) {
+ ksession.addEventListener((WorkingMemoryEventListener) eventListenerObject);
+ } else if(eventListenerObject instanceof AgendaEventListener) {
+ ksession.addEventListener((AgendaEventListener) eventListenerObject);
+ } else if(eventListenerObject instanceof ProcessEventListener) {
+ ksession.addEventListener((ProcessEventListener) eventListenerObject);
+ } else {
+ log.debug("Invalid Event Listener: " + eventListener);
+ }
+ }
+ }
+ }
+
+ public void addEventListeners(StatelessKnowledgeSession ksession) throws Exception{
+ if(ksessionManagerConfig.getEventListeners() != null) {
+ for(String eventListener : ksessionManagerConfig.getEventListeners()) {
+ @SuppressWarnings("unchecked")
+ Class eventListenerClass = Class.forName(eventListener);
+ Object eventListenerObject = eventListenerClass.newInstance();
+
+ if(eventListenerObject instanceof WorkingMemoryEventListener) {
+ ksession.addEventListener((WorkingMemoryEventListener) eventListenerObject);
+ } else if(eventListenerObject instanceof AgendaEventListener) {
+ ksession.addEventListener((AgendaEventListener) eventListenerObject);
+ } else if(eventListenerObject instanceof ProcessEventListener) {
+ ksession.addEventListener((ProcessEventListener) eventListenerObject);
+ } else {
+ log.debug("Invalid Event Listener: " + eventListener);
+ }
+ }
+ }
+ }
+
+ public void addWorkItemHandlers(StatefulKnowledgeSession ksession) {
+ if(ksessionManagerConfig.getWorkItemHandlers() != null) {
+ for(String workItemHandlerStr : ksessionManagerConfig.getWorkItemHandlers()) {
+ if(KnowledgeSessionManagerConfig.isValidWorkItemHandler(workItemHandlerStr)) {
+ @SuppressWarnings("unchecked")
+ Bean<WorkItemHandler> workItemHandlerBean = (Bean<WorkItemHandler>) manager.getBeans(KnowledgeSessionManagerConfig.getWorkItemHandlerType(workItemHandlerStr)).iterator().next();
+ WorkItemHandler handler = (WorkItemHandler) manager.getReference(workItemHandlerBean, Configuration.class, manager.createCreationalContext(workItemHandlerBean));
+ log.debug("Registering new WorkItemHandler: " + KnowledgeSessionManagerConfig.getWorkItemHandlerName(workItemHandlerStr));
+ ksession.getWorkItemManager().registerWorkItemHandler(KnowledgeSessionManagerConfig.getWorkItemHandlerName(workItemHandlerStr), handler);
+ }
+ }
+ }
+ }
+
+
+}
Added: modules/trunk/core/src/main/java/org/jboss/seam/drools/KnowledgeSessionManagerConfig.java
===================================================================
--- modules/trunk/core/src/main/java/org/jboss/seam/drools/KnowledgeSessionManagerConfig.java (rev 0)
+++ modules/trunk/core/src/main/java/org/jboss/seam/drools/KnowledgeSessionManagerConfig.java 2010-03-26 04:53:15 UTC (rev 12286)
@@ -0,0 +1,106 @@
+package org.jboss.seam.drools;
+
+import java.util.Properties;
+import java.util.regex.Pattern;
+
+/**
+ * KnowledgeSessionManager Configuration.
+ *
+ * @author Tihomir Surdilovic
+ */
+public class KnowledgeSessionManagerConfig
+{
+ private static final Pattern DIVIDER = Pattern.compile(";");
+ private static final int WORKITEMHANDLER_NAME = 0;
+ private static final int WORKITEMHANDLER_TYPE = 1;
+ private static final int AUDIT_LOG_TYPE = 0;
+ private static final int AUDIT_LOG_INFO = 1;
+ private static final int AUDIT_LOG_INTERVAL = 2;
+ private static final String AUDIT_LOG_TYPE_FILE = "file";
+ private static final String AUDIT_LOG_TYPE_CONSOLE = "console";
+ private static final String AUDIT_LOG_TYPE_THREADED = "threaded";
+
+ private String[] eventListeners;
+ private String[] workItemHandlers;
+ private String knowledgeSessionConfig;
+ private Properties knowledgeSessionConfigProp;
+ private String auditLog;
+
+ public static String getWorkItemHandlerName(String workItemHandlerStr) {
+ return DIVIDER.split(workItemHandlerStr.trim())[WORKITEMHANDLER_NAME];
+ }
+
+ public static String getWorkItemHandlerType(String workItemHandlerStr) {
+ return DIVIDER.split(workItemHandlerStr.trim())[WORKITEMHANDLER_TYPE];
+ }
+
+ public static boolean isValidWorkItemHandler(String workItemHandlerStr) {
+ return DIVIDER.split(workItemHandlerStr.trim()).length == 2;
+ }
+
+ public static boolean isFileLogger(String auditLog) {
+ return DIVIDER.split(auditLog.trim())[AUDIT_LOG_TYPE] == AUDIT_LOG_TYPE_FILE;
+ }
+
+ public static boolean isConsoleLogger(String auditLog) {
+ return DIVIDER.split(auditLog.trim())[AUDIT_LOG_TYPE] == AUDIT_LOG_TYPE_CONSOLE;
+ }
+
+ public static boolean isThreadedLogger(String auditLog) {
+ return DIVIDER.split(auditLog.trim())[AUDIT_LOG_TYPE] == AUDIT_LOG_TYPE_THREADED;
+ }
+
+ public static String getFileLoggerPath(String auditLog) {
+ return DIVIDER.split(auditLog.trim())[AUDIT_LOG_INFO];
+ }
+
+ public static String getThreadedLoggerPath(String auditLog) {
+ return DIVIDER.split(auditLog.trim())[AUDIT_LOG_INFO];
+ }
+
+ public static int getThreadedLoggerInterval(String auditLog) {
+ return Integer.parseInt(DIVIDER.split(auditLog.trim())[AUDIT_LOG_INTERVAL]);
+ }
+
+ public String[] getEventListeners()
+ {
+ return eventListeners;
+ }
+ public void setEventListeners(String[] eventListeners)
+ {
+ this.eventListeners = eventListeners;
+ }
+ public String[] getWorkItemHandlers()
+ {
+ return workItemHandlers;
+ }
+ public void setWorkItemHandlers(String[] workItemHandlers)
+ {
+ this.workItemHandlers = workItemHandlers;
+ }
+ public String getKnowledgeSessionConfig()
+ {
+ return knowledgeSessionConfig;
+ }
+ public void setKnowledgeSessionConfig(String knowledgeSessionConfig)
+ {
+ this.knowledgeSessionConfig = knowledgeSessionConfig;
+ }
+ public String getAuditLog()
+ {
+ return auditLog;
+ }
+ public void setAuditLog(String auditLog)
+ {
+ this.auditLog = auditLog;
+ }
+ public Properties getKnowledgeSessionConfigProp()
+ {
+ return knowledgeSessionConfigProp;
+ }
+ public void setKnowledgeSessionConfigProp(Properties knowledgeSessionConfigProp)
+ {
+ this.knowledgeSessionConfigProp = knowledgeSessionConfigProp;
+ }
+
+}
Added: modules/trunk/core/src/main/java/org/jboss/seam/drools/TemplateDataProvider.java
===================================================================
--- modules/trunk/core/src/main/java/org/jboss/seam/drools/TemplateDataProvider.java (rev 0)
+++ modules/trunk/core/src/main/java/org/jboss/seam/drools/TemplateDataProvider.java 2010-03-26 04:53:15 UTC (rev 12286)
@@ -0,0 +1,14 @@
+package org.jboss.seam.drools;
+
+import java.util.Collection;
+import java.util.Map;
+
+/**
+ * Interface for template data providers.
+ *
+ * @author Tihomir Surdilovic
+ */
+public interface TemplateDataProvider
+{
+ public Collection<Map<String, Object>> getTemplateData();
+}
Added: modules/trunk/core/src/main/java/org/jboss/seam/drools/events/KnowledgeBuilderErrorsEvent.java
===================================================================
--- modules/trunk/core/src/main/java/org/jboss/seam/drools/events/KnowledgeBuilderErrorsEvent.java (rev 0)
+++ modules/trunk/core/src/main/java/org/jboss/seam/drools/events/KnowledgeBuilderErrorsEvent.java 2010-03-26 04:53:15 UTC (rev 12286)
@@ -0,0 +1,29 @@
+package org.jboss.seam.drools.events;
+
+import org.drools.builder.KnowledgeBuilderErrors;
+
+/**
+ * This event is fires in case of KnowledgeBuilder errors.
+ *
+ * @author Tihomir Surdilovic
+ */
+public class KnowledgeBuilderErrorsEvent
+{
+ private KnowledgeBuilderErrors errors;
+
+ public KnowledgeBuilderErrorsEvent(KnowledgeBuilderErrors errors)
+ {
+ this.errors = errors;
+ }
+
+ public KnowledgeBuilderErrors getErrors()
+ {
+ return errors;
+ }
+
+ public void setErrors(KnowledgeBuilderErrors errors)
+ {
+ this.errors = errors;
+ }
+
+}
Added: modules/trunk/core/src/main/java/org/jboss/seam/drools/events/KnowledgeSessionCreatedEvent.java
===================================================================
--- modules/trunk/core/src/main/java/org/jboss/seam/drools/events/KnowledgeSessionCreatedEvent.java (rev 0)
+++ modules/trunk/core/src/main/java/org/jboss/seam/drools/events/KnowledgeSessionCreatedEvent.java 2010-03-26 04:53:15 UTC (rev 12286)
@@ -0,0 +1,26 @@
+package org.jboss.seam.drools.events;
+
+/**
+ * This event is fires when Stateful or Stateless KnowledgeSession is created.
+ *
+ * @author Tihomir Surdilovic
+ */
+public class KnowledgeSessionCreatedEvent
+{
+ private int sessionId;
+
+ public KnowledgeSessionCreatedEvent(int sessionId) {
+ this.sessionId = sessionId;
+ }
+
+ public int getSessionId()
+ {
+ return sessionId;
+ }
+
+ public void setSessionId(int sessionId)
+ {
+ this.sessionId = sessionId;
+ }
+
+}
Added: modules/trunk/core/src/main/java/org/jboss/seam/drools/events/RuleResourceAddedEvent.java
===================================================================
--- modules/trunk/core/src/main/java/org/jboss/seam/drools/events/RuleResourceAddedEvent.java (rev 0)
+++ modules/trunk/core/src/main/java/org/jboss/seam/drools/events/RuleResourceAddedEvent.java 2010-03-26 04:53:15 UTC (rev 12286)
@@ -0,0 +1,26 @@
+package org.jboss.seam.drools.events;
+
+/**
+ * This event is fires when a rule resource is added.
+ *
+ * @author Tihomir Surdilovic
+ */
+public class RuleResourceAddedEvent
+{
+ String resource;
+
+ public RuleResourceAddedEvent(String resource)
+ {
+ this.resource = resource;
+ }
+
+ public String getResource()
+ {
+ return resource;
+ }
+
+ public void setResource(String resource)
+ {
+ this.resource = resource;
+ }
+}
Added: modules/trunk/distribution.txt
===================================================================
--- modules/trunk/distribution.txt (rev 0)
+++ modules/trunk/distribution.txt 2010-03-26 04:53:15 UTC (rev 12286)
@@ -0,0 +1,4 @@
+To create the Seam Drools distribution, run the following Maven command:
+
+mvn clean package javadoc:javadoc assembly:assembly
+
Added: modules/trunk/docs/.classpath
===================================================================
--- modules/trunk/docs/.classpath (rev 0)
+++ modules/trunk/docs/.classpath 2010-03-26 04:53:15 UTC (rev 12286)
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.4"/>
+ <classpathentry kind="con" path="org.maven.ide.eclipse.MAVEN2_CLASSPATH_CONTAINER"/>
+ <classpathentry kind="output" path="target/classes"/>
+</classpath>
Added: modules/trunk/docs/.project
===================================================================
--- modules/trunk/docs/.project (rev 0)
+++ modules/trunk/docs/.project 2010-03-26 04:53:15 UTC (rev 12286)
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>seam-drools-reference-guide</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.wst.common.project.facet.core.builder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.maven.ide.eclipse.maven2Builder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ <nature>org.maven.ide.eclipse.maven2Nature</nature>
+ <nature>org.eclipse.wst.common.project.facet.core.nature</nature>
+ </natures>
+</projectDescription>
Added: modules/trunk/docs/.settings/org.eclipse.jdt.core.prefs
===================================================================
--- modules/trunk/docs/.settings/org.eclipse.jdt.core.prefs (rev 0)
+++ modules/trunk/docs/.settings/org.eclipse.jdt.core.prefs 2010-03-26 04:53:15 UTC (rev 12286)
@@ -0,0 +1,6 @@
+#Fri Mar 26 00:27:07 EDT 2010
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.4
+org.eclipse.jdt.core.compiler.compliance=1.4
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
+org.eclipse.jdt.core.compiler.source=1.4
Added: modules/trunk/docs/.settings/org.maven.ide.eclipse.prefs
===================================================================
--- modules/trunk/docs/.settings/org.maven.ide.eclipse.prefs (rev 0)
+++ modules/trunk/docs/.settings/org.maven.ide.eclipse.prefs 2010-03-26 04:53:15 UTC (rev 12286)
@@ -0,0 +1,9 @@
+#Fri Mar 26 00:04:15 EDT 2010
+activeProfiles=
+eclipse.preferences.version=1
+fullBuildGoals=process-test-resources
+includeModules=false
+resolveWorkspaceProjects=true
+resourceFilterGoals=process-resources resources\:testResources
+skipCompilerPlugin=true
+version=1
Added: modules/trunk/docs/README.TXT
===================================================================
--- modules/trunk/docs/README.TXT (rev 0)
+++ modules/trunk/docs/README.TXT 2010-03-26 04:53:15 UTC (rev 12286)
@@ -0,0 +1,4 @@
+To build the Seam Drools docs run the following command:
+
+mvn clean install
+
Added: modules/trunk/docs/drools-reference.pdf
===================================================================
(Binary files differ)
Property changes on: modules/trunk/docs/drools-reference.pdf
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: modules/trunk/docs/en-US/drools-general.xml
===================================================================
--- modules/trunk/docs/en-US/drools-general.xml (rev 0)
+++ modules/trunk/docs/en-US/drools-general.xml 2010-03-26 04:53:15 UTC (rev 12286)
@@ -0,0 +1,510 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN" "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd">
+
+<chapter id="remoting-general">
+ <title>Seam Remoting</title>
+
+ <para>Seam provides a convenient method of remotely accessing CDI beans from a web page, using AJAX (Asynchronous
+ Javascript and XML). The framework for this functionality is provided with almost no up-front development effort -
+ your beans only require simple annotating to become accessible via AJAX. This chapter describes the steps
+ required to build an AJAX-enabled web page, then goes on to explain the features of the Seam Remoting framework in
+ more detail. </para>
+
+ <section>
+ <title>Configuration</title>
+ <para>To use remoting, the Seam Remoting servlet must first be configured in your <literal>web.xml</literal> file: </para>
+
+ <programlisting role="XML"><![CDATA[<servlet>
+ <servlet-name>Remoting Servlet</servlet-name>
+ <servlet-class>org.jboss.seam.remoting.Remoting</servlet-class>
+ <load-on-startup>1</load-on-startup>
+</servlet>
+
+<servlet-mapping>
+ <servlet-name>Remoting Servlet</servlet-name>
+ <url-pattern>/seam/resource/remoting/*</url-pattern>
+</servlet-mapping>]]></programlisting>
+
+ <para>The next step is to import the necessary Javascript into your web page. There are a minimum of two scripts
+ that must be imported. The first one contains all the client-side framework code that enables remoting
+ functionality:</para>
+
+ <programlisting role="XHTML"><![CDATA[<script type="text/javascript" src="seam/resource/remoting/resource/remote.js"></script>]]></programlisting>
+
+ <para>For a production environment, you may wish to use a compressed version of <literal>remote.js</literal>.
+ To do this, simply add the <literal>compress=true</literal> parameter to the end of the url:</para>
+
+ <programlisting role="XHTML"><![CDATA[<script type="text/javascript" src="seam/resource/remoting/resource/remote.js?compress=true"></script>]]></programlisting>
+
+ <para>The compressed version has its white space compacted and JavaScript comments removed. For development and
+ debugging purposes it is recommended that you use the non-compacted version.</para>
+
+ <para>The second script that you need contains the stubs and type definitions for the beans you wish to call. It is
+ generated dynamically based on the method signatures of your beans, and includes type definitions for all of
+ the classes that can be used to call its remotable methods. The name of the script reflects the
+ name of your bean. For example, if you have a named bean annotated with <literal>@Named</literal>, then your script
+ tag should look like this (for a bean class called <literal>CustomerAction</literal>): </para>
+
+ <programlisting role="XHTML"><![CDATA[<script type="text/javascript"
+ src="seam/resource/remoting/interface.js?customerAction"></script>]]></programlisting>
+
+ <para>Otherwise, you can simply specify the fully qualified class name of the bean:</para>
+
+ <programlisting role="XHTML"><![CDATA[<script type="text/javascript"
+ src="seam/resource/remoting/interface.js?com.acme.myapp.CustomerAction"></script>]]></programlisting>
+
+ <para>If you wish to access more than one bean from the same page, then include them all as parameters of your
+ script tag: </para>
+
+ <programlisting role="XHTML"><![CDATA[<script type="text/javascript"
+ src="seam/resource/remoting/interface.js?customerAction&accountAction"></script>]]></programlisting>
+
+ <section>
+ <title>Dynamic type loading</title>
+
+ <para>If you forget to import a bean or other class that is required by your bean, don't worry. Seam Remoting has
+ a dynamic type loading feature that automatically loads any JavaScript stubs for bean types that it doesn't
+ recognize.</para>
+ </section>
+
+ </section>
+
+ <section>
+ <title>The "Seam" object</title>
+
+ <para>Client-side interaction with your beans is all performed via the <literal>Seam</literal> Javascript
+ object. This object is defined in <literal>remote.js</literal>, and you'll be using it to make asynchronous calls
+ against your bean. It contains methods for creating client-side bean objects and also methods for executing remote
+ requests. The easiest way to become familiar with this object is to start with a simple example.</para>
+
+ <section>
+ <title>A Hello World example</title>
+
+ <para>Let's step through a simple example to see how the <literal>Seam</literal> object works. First of all,
+ let's create a new bean called <literal>helloAction</literal>:</para>
+
+ <programlisting role="JAVA"><![CDATA[@Named
+public class HelloAction implements HelloLocal {
+ @WebRemote public String sayHello(String name) {
+ return "Hello, " + name;
+ }
+}]]></programlisting>
+
+ <para>Take note of the <literal>@WebRemote</literal> annotation on the <literal>sayHello()</literal> method in the
+ above listing. This annotation makes the method accessible via the Remoting API. Besides this annotation, there's
+ nothing else required on your bean to enable it for remoting.</para>
+
+ <!--note>
+ <para>If you are performing a persistence operation in the method marked <literal>@WebRemote</literal> you will
+ also need to add a <literal>@Transactional</literal> annotation to the method. Otherwise, your method would
+ execute outside of a transaction without this extra hint.That's because unlike a JSF request, Seam does not
+ wrap the remoting request in a transaction automatically.</para>
+ </note-->
+
+ <para>Now for our web page - create a new JSF page and import the <literal>helloAction</literal> bean:</para>
+
+ <programlisting role="XHTML"><![CDATA[<script type="text/javascript"
+ src="seam/resource/remoting/interface.js?helloAction]]></programlisting>
+
+ <para>To make this a fully interactive user experience, let's add a button to our page:</para>
+
+ <programlisting role="XHTML"><![CDATA[<button onclick="javascript:sayHello()">Say Hello</button>]]></programlisting>
+
+ <para>We'll also need to add some more script to make our button actually do something when it's clicked: </para>
+
+ <programlisting role="XHTML"><![CDATA[<script type="text/javascript">
+ //<![CDATA[
+
+ function sayHello() {
+ var name = prompt("What is your name?");
+ Seam.createBean("helloAction").sayHello(name, sayHelloCallback);
+ }
+
+ function sayHelloCallback(result) {
+ alert(result);
+ }
+
+ // ]]>]]><![CDATA[
+</script>]]></programlisting>
+
+ <para>We're done! Deploy your application and open the page in a web browser. Click the button, and enter a name when
+ prompted. A message box will display the hello message confirming that the call was successful. If you want to
+ save some time, you'll find the full source code for this Hello World example in the
+ <literal>/examples/helloworld</literal> directory.</para>
+
+ <para>So what does the code of our script actually do? Let's break it down into smaller pieces. To start with,
+ you can see from the Javascript code listing that we have implemented two methods - the first method is
+ responsible for prompting the user for their name and then making a remote request. Take a look at the following
+ line:</para>
+
+ <programlisting role="XHTML">Seam.createBean("helloAction").sayHello(name, sayHelloCallback);</programlisting>
+
+ <para>The first section of this line, <literal>Seam.createBean("helloAction")</literal> returns a
+ proxy, or "stub" for our <literal>helloAction</literal> bean. We can invoke the methods of our bean
+ against this stub, which is exactly what happens with the remainder of the line:
+ <literal>sayHello(name, sayHelloCallback);</literal>. </para>
+
+ <para>What this line of code in its completeness does, is invoke the <literal>sayHello</literal> method of our
+ bean, passing in <literal>name</literal> as a parameter. The second parameter,
+ <literal>sayHelloCallback</literal> isn't a parameter of our bean's <literal>sayHello</literal> method,
+ instead it tells the Seam Remoting framework that once it receives the response to our request, it should pass
+ it to the <literal>sayHelloCallback</literal> Javascript method. This callback parameter is entirely optional,
+ so feel free to leave it out if you're calling a method with a <literal>void</literal> return type or if you
+ don't care about the result. </para>
+
+ <para>The <literal>sayHelloCallback</literal> method, once receiving the response to our remote request then pops
+ up an alert message displaying the result of our method call. </para>
+ </section>
+
+ <section>
+ <title>Seam.createBean</title>
+
+ <para> The <literal>Seam.createBean</literal> JavaScript method is used to create client-side instances of both
+ action and "state" beans. For action beans (which are those that contain one or more methods annotated with
+ <literal>@WebRemote</literal>), the stub object provides all of the remotable methods exposed by the bean.
+ For "state" beans (i.e. beans that simply carry state, for example Entity beans) the stub object provides all
+ the same accessible properties as its server-side equivalent. Each property also has a corresponding
+ getter/setter method so you can work with the object in JavaScript in much the same way as you would in Java.</para>
+ </section>
+
+ </section>
+
+ <section>
+ <title>The Context</title>
+
+ <para>The Seam Remoting Context contains additional information which is sent and received as part of a remoting
+ request/response cycle. It currently contains the conversation ID and Call ID, and may be expanded to include other
+ properties in the future. </para>
+
+ <section>
+ <title>Setting and reading the Conversation ID</title>
+
+ <para> If you intend on using remote calls within the scope of a conversation then you need to be able to read or
+ set the conversation ID in the Seam Remoting Context. To read the conversation ID after making a remote request
+ call <literal>Seam.context.getConversationId()</literal>. To set the conversation ID before making a
+ request, call <literal>Seam.context.setConversationId()</literal>. </para>
+
+ <para>If the conversation ID hasn't been explicitly set with
+ <literal>Seam.context.setConversationId()</literal>, then it will be automatically assigned the
+ first valid conversation ID that is returned by any remoting call. If you are working with multiple conversations
+ within your page, then you may need to explicitly set the conversation ID before each call. If you are working
+ with just a single conversation, then you don't need to do anything special. </para>
+ </section>
+
+ <section>
+ <title>Remote calls within the current conversation scope</title>
+
+ <para>In some circumstances it may be required to make a remote call within the scope of the
+ current view's conversation. To do this, you must explicitly set the conversation ID to that
+ of the view before making the remote call. This small snippet of JavaScript will set the
+ conversation ID that is used for remoting calls to the current view's conversation ID: </para>
+
+ <programlisting role="XHTML"><![CDATA[Seam.context.setConversationId( #{conversation.id} );]]></programlisting>
+ </section>
+ </section>
+
+ <section>
+ <title>Working with Data types</title>
+
+ <section>
+ <title>Primitives / Basic Types</title>
+
+ <para>This section describes the support for basic data types. On the server side these values as a rule are
+ compatible with either their primitive type or their corresponding wrapper class. </para>
+
+ <section>
+ <title>String</title>
+
+ <para>Simply use Javascript String objects when setting String parameter values. </para>
+ </section>
+
+ <section>
+ <title>Number</title>
+
+ <para>There is support for all number types supported by Java. On the client side, number values are always
+ serialized as their String representation and then on the server side they are converted to the correct
+ destination type. Conversion into either a primitive or wrapper type is supported for <literal>Byte</literal>,
+ <literal>Double</literal>, <literal>Float</literal>, <literal>Integer</literal>, <literal>Long</literal> and
+ <literal>Short</literal> types. </para>
+ </section>
+
+ <section>
+ <title>Boolean</title>
+
+ <para>Booleans are represented client side by Javascript Boolean values, and server side by a Java boolean.
+ </para>
+ </section>
+ </section>
+
+ <section>
+ <title>JavaBeans</title>
+
+ <para> In general these will be either entity beans or JavaBean classes, or some other non-bean class. Use
+ <literal>Seam.createBean()</literal> to create a new instance of the object. </para>
+ </section>
+
+ <section>
+ <title>Dates and Times</title>
+
+ <para>Date values are serialized into a String representation that is accurate to the millisecond. On the client
+ side, use a JavaScript <literal>Date</literal> object to work with date values. On the server side, use any
+ <literal>java.util.Date</literal> (or descendent, such as <literal>java.sql.Date</literal> or
+ <literal>java.sql.Timestamp</literal> class. </para>
+ </section>
+
+ <section>
+ <title>Enums</title>
+
+ <para> On the client side, enums are treated the same as <literal>String</literal>s. When setting the value for an enum parameter,
+ simply use the <literal>String</literal> representation of the enum. Take the following bean as an example: </para>
+
+ <programlisting role="JAVA">@Named
+public class paintAction {
+ public enum Color {red, green, blue, yellow, orange, purple};
+
+ public void paint(Color color) {
+ // code
+ }
+} </programlisting>
+
+ <para> To call the <literal>paint()</literal> method with the color <literal>red</literal>, pass the parameter
+ value as a <literal>String</literal> literal: </para>
+
+ <programlisting role="XHTML">Seam.createBean("paintAction").paint("red");</programlisting>
+
+ <para> The inverse is also true - that is, if a bean method returns an enum parameter (or contains an enum
+ field anywhere in the returned object graph) then on the client-side it will be converted to a <literal>String</literal>. </para>
+ </section>
+
+ <section>
+ <title>Collections</title>
+
+ <section>
+ <title>Bags</title>
+
+ <para>Bags cover all collection types including arrays, collections, lists, sets, (but excluding Maps - see the
+ next section for those), and are implemented client-side as a JavaScript array. When calling a bean
+ method that accepts one of these types as a parameter, your parameter should be a JavaScript array. If a
+ bean method returns one of these types, then the return value will also be a JavaScript array. The
+ remoting framework is clever enough on the server side to convert the bag to an appropriate type (including
+ sophisticated support for generics) for the bean method call.</para>
+ </section>
+
+ <section>
+ <title>Maps</title>
+
+ <para> As there is no native support for Maps within JavaScript, a simple Map implementation is provided with
+ the Seam Remoting framework. To create a Map which can be used as a parameter to a remote call, create a new
+ <literal>Seam.Map</literal> object: </para>
+
+ <programlisting role="XHTML">var map = new Seam.Map();</programlisting>
+
+ <para> This JavaScript implementation provides basic methods for working with Maps: <literal>size()</literal>,
+ <literal>isEmpty()</literal>, <literal>keySet()</literal>, <literal>values()</literal>,
+ <literal>get(key)</literal>, <literal>put(key, value)</literal>, <literal>remove(key)</literal> and
+ <literal>contains(key)</literal>. Each of these methods are equivalent to their Java counterpart. Where the
+ method returns a collection, such as <literal>keySet()</literal> and <literal>values()</literal>, a JavaScript
+ Array object will be returned that contains the key or value objects (respectively). </para>
+ </section>
+ </section>
+ </section>
+
+ <section>
+ <title>Debugging</title>
+
+ <para> To aid in tracking down bugs, it is possible to enable a debug mode which will display the contents of all
+ the packets send back and forth between the client and server in a popup window. To enable debug mode, set the
+ <literal>Seam.debug</literal> property to <literal>true</literal> in Javascript: </para>
+
+ <programlisting role="XHTML">Seam.debug = true;</programlisting>
+
+ <para>If you want to write your own messages to the debug log, call
+ <literal>Seam.log(message)</literal>. </para>
+ </section>
+
+ <section>
+ <title>Handling Exceptions</title>
+
+ <para>
+ When invoking a remote bean method, it is possible to specify an exception handler which will process
+ the response in the event of an exception during bean invocation. To specify an exception handler function,
+ include a reference to it after the callback parameter in your JavaScript:
+ </para>
+
+ <programlisting><![CDATA[var callback = function(result) { alert(result); };
+var exceptionHandler = function(ex) { alert("An exception occurred: " + ex.getMessage()); };
+Seam.createBean("helloAction").sayHello(name, callback, exceptionHandler);]]></programlisting>
+
+ <para>
+ If you do not have a callback handler defined, you must specify <literal>null</literal> in its place:
+ </para>
+
+ <programlisting><![CDATA[var exceptionHandler = function(ex) { alert("An exception occurred: " + ex.getMessage()); };
+Seam.createBean("helloAction").sayHello(name, null, exceptionHandler);]]></programlisting>
+
+ <para>
+ The exception object that is passed to the exception handler exposes one method, <literal>getMessage()</literal>
+ that returns the exception message which is produced by the exception thrown by the <literal>@WebRemote</literal>
+ method.
+ </para>
+
+ </section>
+
+ <section>
+ <title>The Loading Message</title>
+
+ <para> The default loading message that appears in the top right corner of the screen can be modified, its rendering
+ customised or even turned off completely. </para>
+
+ <section>
+ <title>Changing the message</title>
+
+ <para> To change the message from the default "Please Wait..." to something different, set the value of
+ <literal>Seam.loadingMessage</literal>: </para>
+
+ <programlisting role="XHTML">Seam.loadingMessage = "Loading..."; </programlisting>
+ </section>
+
+ <section>
+ <title>Hiding the loading message</title>
+
+ <para> To completely suppress the display of the loading message, override the implementation of
+ <literal>displayLoadingMessage()</literal> and <literal>hideLoadingMessage()</literal> with functions that
+ instead do nothing: </para>
+
+ <programlisting role="XHTML">// don't display the loading indicator
+Seam.displayLoadingMessage = function() {};
+Seam.hideLoadingMessage = function() {};</programlisting>
+ </section>
+
+ <section>
+ <title>A Custom Loading Indicator</title>
+
+ <para> It is also possible to override the loading indicator to display an animated icon, or anything else that
+ you want. To do this override the <literal>displayLoadingMessage()</literal> and
+ <literal>hideLoadingMessage()</literal> messages with your own implementation: </para>
+
+ <programlisting role="XHTML"> Seam.displayLoadingMessage = function() {
+ // Write code here to display the indicator
+ };
+
+ Seam.hideLoadingMessage = function() {
+ // Write code here to hide the indicator
+ };</programlisting>
+ </section>
+ </section>
+
+ <section>
+ <title>Controlling what data is returned</title>
+
+ <para> When a remote method is executed, the result is serialized into an XML response that is returned to the
+ client. This response is then unmarshaled by the client into a JavaScript object. For complex types (i.e.
+ Javabeans) that include references to other objects, all of these referenced objects are also serialized as part
+ of the response. These objects may reference other objects, which may reference other objects, and so forth. If
+ left unchecked, this object "graph" could potentially be enormous, depending on what relationships exist between
+ your objects. And as a side issue (besides the potential verbosity of the response), you might also wish to
+ prevent sensitive information from being exposed to the client. </para>
+
+ <para> Seam Remoting provides a simple means to "constrain" the object graph, by specifying the
+ <literal>exclude</literal> field of the remote method's <literal>@WebRemote</literal> annotation. This field
+ accepts a String array containing one or more paths specified using dot notation. When invoking a remote method,
+ the objects in the result's object graph that match these paths are excluded from the serialized result packet. </para>
+
+ <para> For all our examples, we'll use the following <literal>Widget</literal> class: </para>
+
+ <programlisting role="JAVA">public class Widget
+{
+ private String value;
+ private String secret;
+ private Widget child;
+ private Map<String,Widget> widgetMap;
+ private List<Widget> widgetList;
+
+ // getters and setters for all fields
+}</programlisting>
+
+ <section>
+ <title>Constraining normal fields</title>
+
+ <para> If your remote method returns an instance of <literal>Widget</literal>, but you don't want to expose the
+ <literal>secret</literal> field because it contains sensitive information, you would constrain it like this: </para>
+
+ <programlisting role="JAVA">@WebRemote(exclude = {"secret"})
+public Widget getWidget(); </programlisting>
+
+ <para> The value "secret" refers to the <literal>secret</literal> field of the returned object. Now, suppose that
+ we don't care about exposing this particular field to the client. Instead, notice that the
+ <literal>Widget</literal> value that is returned has a field <literal>child</literal> that is also a
+ <literal>Widget</literal>. What if we want to hide the <literal>child</literal>'s <literal>secret</literal>
+ value instead? We can do this by using dot notation to specify this field's path within the result's object
+ graph: </para>
+
+ <programlisting role="JAVA">@WebRemote(exclude = {"child.secret"})
+public Widget getWidget();</programlisting>
+
+ </section>
+
+ <section>
+ <title>Constraining Maps and Collections</title>
+
+ <para> The other place that objects can exist within an object graph are within a <literal>Map</literal> or some
+ kind of collection (<literal>List</literal>, <literal>Set</literal>, <literal>Array</literal>, etc). Collections
+ are easy, and are treated like any other field. For example, if our <literal>Widget</literal> contained a list
+ of other <literal>Widget</literal>s in its <literal>widgetList</literal> field, to constrain the
+ <literal>secret</literal> field of the <literal>Widget</literal>s in this list the annotation would look like
+ this: </para>
+
+ <programlisting role="JAVA">@WebRemote(exclude = {"widgetList.secret"})
+public Widget getWidget();</programlisting>
+
+ <para> To constrain a <literal>Map</literal>'s key or value, the notation is slightly different. Appending
+ <literal>[key]</literal> after the <literal>Map</literal>'s field name will constrain the
+ <literal>Map</literal>'s key object values, while <literal>[value]</literal> will constrain the value object
+ values. The following example demonstrates how the values of the <literal>widgetMap</literal> field have their
+ <literal>secret</literal> field constrained: </para>
+
+ <programlisting role="JAVA">@WebRemote(exclude = {"widgetMap[value].secret"})
+public Widget getWidget(); </programlisting>
+ </section>
+
+ <section>
+ <title>Constraining objects of a specific type</title>
+
+ <para> There is one last notation that can be used to constrain the fields of a type of object no matter where in
+ the result's object graph it appears. This notation uses either the name of the bean (if the object is a
+ named bean) or the fully qualified class name (only if the object is not a named bean) and is expressed
+ using square brackets: </para>
+
+ <programlisting role="JAVA">@WebRemote(exclude = {"[widget].secret"})
+public Widget getWidget(); </programlisting>
+
+ </section>
+
+ <section>
+ <title>Combining Constraints</title>
+
+ <para> Constraints can also be combined, to filter objects from multiple paths within the object graph: </para>
+
+ <programlisting role="JAVA">@WebRemote(exclude = {"widgetList.secret", "widgetMap[value].secret"})
+public Widget getWidget();</programlisting>
+ </section>
+
+ </section>
+
+ <!--section>
+ <title>Transactional Requests</title>
+
+ <para>
+ By default there is no active transaction during a remoting request, so if you wish to perform database updates
+ during a remoting request, you need to annotate the <literal>@WebRemote</literal> method with
+ <literal>@Transactional</literal>, like so:
+ </para>
+
+ <programlisting><![CDATA[ @WebRemote @Transactional(TransactionPropagationType.REQUIRED)
+ public void updateOrder(Order order) {
+ entityManager.merge(order);
+ }]]></programlisting>
+ </section-->
+
+</chapter>
+
Added: modules/trunk/docs/en-US/drools-model.xml
===================================================================
--- modules/trunk/docs/en-US/drools-model.xml (rev 0)
+++ modules/trunk/docs/en-US/drools-model.xml 2010-03-26 04:53:15 UTC (rev 12286)
@@ -0,0 +1,652 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN" "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd">
+
+<chapter id="remoting-model">
+ <title>Seam Remoting - Model API</title>
+
+ <section>
+ <title>Introduction</title>
+ <para>
+ The Model API builds on top of Seam Remoting's object serialization features to provide a
+ <emphasis>component-based</emphasis> approach to working with a server-side object model, as
+ opposed to the <emphasis>RPC-based</emphasis> approach provided by the standard Remoting API.
+ This allows a client-side representation of a server-side object graph to be modified ad hoc
+ by the client, after which the changes made to the objects in the graph can be
+ <emphasis>applied</emphasis> to the corresponding server-side objects. When applying the
+ changes the client determines exactly which objects have been modified by recursively walking
+ the client-side object tree and generating a delta by comparing the original property values
+ of the objects with their new property values.
+ </para>
+
+ <para>
+ This approach, when used in conjunction with the extended persistence context provided by Seam
+ elegantly solves a number of problems faced by AJAX developers when working remotely with
+ persistent objects. A persistent, managed object graph can be loaded at the start of
+ a new conversation, and then across multiple requests (and within the same transaction) the client
+ can fetch the objects, make changes to them and apply those changes to the same managed objects after
+ which the long-running transaction can be committed when the conversation ends.
+ </para>
+
+ <para>
+ One other useful feature of the Model API is its ability to <emphasis>expand</emphasis> a model.
+ For example, if you are working with entities with lazy-loaded associations it is usually not a good idea
+ to blindly fetch the associated objects (which may in turn themselves contain associations
+ to other entities, ad nauseum), as you may inadvertently end up fetching the bulk of your database.
+ Seam Remoting already knows how to deal with lazy-loaded associations by automatically excluding
+ them when marshalling instances of entity beans, and assigning them a client-side value of
+ <literal>undefined</literal> (which is a special JavaScript value, distinct from <literal>null</literal>).
+ The Model API goes one step further by giving the client the option of manipulating the associated objects
+ also. By providing an <emphasis>expand</emphasis> operation, it allows for the initialization of a
+ previously-uninitialized object property (such as a lazy-loaded collection), by dynamically "grafting"
+ the initialized value onto the object graph. By <emphasis>expanding</emphasis> the model in this way,
+ we have at our disposal a powerful tool for building dynamic client interfaces.
+ </para>
+ </section>
+
+ <section>
+ <title>Model Operations</title>
+
+ <para>
+ For the methods of the Model API that accept action parameters, an instance of
+ <literal>Seam.Action</literal> should be used. The constructor for
+ <literal>Seam.Action</literal> takes no parameters:
+ </para>
+
+ <programlisting role="XHTML"><![CDATA[ var action = new Seam.Action();]]></programlisting>
+
+ <para>
+ The following table lists the methods used to define the action. Each of the following methods
+ return a reference to the <literal>Seam.Action</literal> object, so methods can be chained.
+ </para>
+
+ <table>
+ <title>Seam.Action method reference</title>
+
+ <tgroup cols="2">
+ <colspec colnum="1" colwidth="2*" />
+ <colspec colnum="2" colwidth="3*" />
+
+ <thead>
+ <row>
+ <entry align="center">
+ <para>Method</para>
+ </entry>
+ <entry align="center">
+ <para>Description</para>
+ </entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry>
+ <para>
+ <literal>setBeanType(beanType)</literal>
+ </para>
+ </entry>
+ <entry>
+ <para>
+ Sets the class name of the bean to be invoked.
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <literal>beanType</literal> - the fully qualified class name of the bean type to be invoked.
+ </listitem>
+ </itemizedlist>
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <para>
+ <literal>setQualifiers(qualifiers)</literal>
+ </para>
+ </entry>
+ <entry>
+ <para>
+ Sets the qualifiers for the bean to be invoked.
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <literal>qualifiers</literal> - a comma-separated list of bean qualifier names.
+ The names may either be the simple or fully qualified names of the qualifier classes.
+ </listitem>
+ </itemizedlist>
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <para>
+ <literal>setMethod(method)</literal>
+ </para>
+ </entry>
+ <entry>
+ <para>
+ Sets the name of the bean method.
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <literal>method</literal> - the name of the bean method to invoke.
+ </listitem>
+ </itemizedlist>
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <para>
+ <literal>addParam(param)</literal>
+ </para>
+ </entry>
+ <entry>
+ <para>
+ Adds a parameter value for the action method. This method should be called once for
+ each parameter value to be added, in the correct parameter order.
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <literal>param</literal> - the parameter value to add.
+ </listitem>
+ </itemizedlist>
+ </entry>
+ </row>
+
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ The following table describes the methods provided by the <literal>Seam.Model</literal> object. To work with
+ the Model API in JavaScript you must first create a new Model object:
+ </para>
+
+ <programlisting role="XHTML"><![CDATA[ var model = new Seam.Model();]]></programlisting>
+
+ <table>
+ <title>Seam.Model method reference</title>
+
+ <tgroup cols="2">
+ <colspec colnum="1" colwidth="2*" />
+ <colspec colnum="2" colwidth="3*" />
+
+ <thead>
+ <row>
+ <entry align="center">
+ <para>Method</para>
+ </entry>
+ <entry align="center">
+ <para>Description</para>
+ </entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry>
+ <para>
+ <literal>addBean(alias, bean, qualifiers)</literal>
+ </para>
+ </entry>
+ <entry>
+ <para>
+ Adds a bean value to the model. When the model is fetched, the value of the specified bean
+ will be read and placed into the model, where it may be accessed by using the
+ <literal>getValue()</literal> method with the specified alias.
+ </para>
+
+ <para>
+ Can only be used before the model is fetched.
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <literal>alias</literal> - the local alias for the bean value.
+ </listitem>
+ <listitem>
+ <literal>bean</literal> - the name of the bean, either specified by the <literal>@Named</literal>
+ annotation or the fully qualified class name.
+ </listitem>
+ <listitem>
+ <literal>qualifiers</literal> (optional) - a list of bean qualifiers.
+ </listitem>
+ </itemizedlist>
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <para>
+ <literal>addBeanProperty(alias, bean, property, qualifiers)</literal>
+ </para>
+ </entry>
+ <entry>
+ <para>
+ Adds a bean property value to the model. When the model is fetched, the value of the specified
+ property on the specified bean will be read and placed into the model, where it may be accessed
+ by using the <literal>getValue()</literal> method with the specified alias.
+ </para>
+
+ <para>
+ Can only be used before the model is fetched.
+ </para>
+
+ <para>
+ Example:
+ </para>
+
+ <programlisting role="XHTML"><![CDATA[ addBeanProperty("account", "AccountAction", "account", "@Qualifier1", "@Qualifier2");]]></programlisting>
+
+ <itemizedlist>
+ <listitem>
+ <literal>alias</literal> - the local alias for the bean value.
+ </listitem>
+ <listitem>
+ <literal>bean</literal> - the name of the bean, either specified by the <literal>@Named</literal>
+ annotation or the fully qualified class name.
+ </listitem>
+ <listitem>
+ <literal>property</literal> - the name of the bean property.
+ </listitem>
+ <listitem>
+ <literal>qualifiers</literal> (optional) - a list of bean qualifiers. This parameter (and any
+ after it) are treated as bean qualifiers.
+ </listitem>
+ </itemizedlist>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <para>
+ <literal>fetch(action, callback)</literal>
+ </para>
+ </entry>
+ <entry>
+ <para>
+ Fetches the model - this operation causes an asynchronous request to be sent to the server.
+ The request contains a list of the beans and bean properties (set by calling the
+ <literal>addBean()</literal> and <literal>addBeanProperty()</literal> methods) for which values
+ will be returned. Once the response is received, the callback method (if specified) will be
+ invoked, passing in a reference to the model as a parameter.
+ </para>
+
+ <para>
+ A model should only be fetched once.
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <literal>action</literal> (optional) - a <literal>Seam.Action</literal> instance representing
+ the bean action to invoke before the model values are read and stored in the model.
+ </listitem>
+ <listitem>
+ <literal>callback</literal> (optional) - a reference to a JavaScript function that will be
+ invoked after the model has been fetched. A reference to the model instance is passed to
+ the callback method as a parameter.
+ </listitem>
+ </itemizedlist>
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <para>
+ <literal>getValue(alias)</literal>
+ </para>
+ </entry>
+ <entry>
+ <para>
+ This method returns the value of the object with the specified alias.
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <literal>alias</literal> - the alias of the value to return.
+ </listitem>
+ </itemizedlist>
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <para>
+ <literal>expand(value, property, callback)</literal>
+ </para>
+ </entry>
+ <entry>
+ <para>
+ Expands the model by initializing a property value that was previously uninitialized. This
+ operation causes an asynchronous request to be sent to the server, where the uninitialized
+ property value (such as a lazy-loaded collection within an entity bean association) is
+ initialized and the resulting value is returned to the client. Once the response is received,
+ the callback method (if specified) will be invoked, passing in a reference to the model as a
+ parameter.
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <literal>value</literal> - a reference to the value containing the uninitialized property
+ to fetch. This can be any value within the model, and does not need to be a "root" value
+ (i.e. it doesn't need to be a value specified by <literal>addBean()</literal> or
+ <literal>addBeanProperty()</literal>, it can exist anywhere within the object graph.
+ </listitem>
+ <listitem>
+ <literal>property</literal> - the name of the uninitialized property to be initialized.
+ </listitem>
+ <listitem>
+ <literal>callback</literal> (optional) - a reference to a JavaScript function that will be
+ invoked after the model has been expanded. A reference to the model instance is passed to
+ the callback method as a parameter.
+ </listitem>
+ </itemizedlist>
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <para>
+ <literal>applyUpdates(action, callback)</literal>
+ </para>
+ </entry>
+ <entry>
+ <para>
+ Applies the changes made to the objects contained in the model. This method causes an
+ asynchronous request to be sent to the server containing a delta consisting of
+ a list of the changes made to the client-side objects.
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <literal>action</literal> (optional) - a <literal>Seam.Action</literal> instance representing
+ a bean method to be invoked after the client-side model changes have been applied to their
+ corresponding server-side objects.
+ </listitem>
+ <listitem>
+ <literal>callback</literal> (optional) - a reference to a JavaScript function that will be
+ invoked after the updates have been applied. A reference to the model instance is passed to
+ the callback method as a parameter.
+ </listitem>
+ </itemizedlist>
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+
+ </table>
+
+ <para>
+
+ </para>
+ </section>
+
+ <section>
+ <title>Fetching a model</title>
+
+ <para>
+ To fetch a model, one or more values must first be specified using <literal>addBean()</literal> or
+ <literal>addBeanProperty()</literal> before invoking the <literal>fetch()</literal> operation.
+ Let's work through an example - here we have an entity bean called <literal>Customer</literal>:
+ </para>
+
+ <programlisting role="JAVA"><![CDATA[@Entity Customer implements Serializable {
+ private Integer customerId;
+ private String firstName;
+ private String lastName;
+
+ @Id @GeneratedValue public Integer getCustomerId() { return customerId; }
+ public void setCustomerId(Integer customerId) { this.customerId = customerId; }
+
+ public String getFirstName() { return firstName; }
+ public void setFirstName(String firstName) { this.firstName = firstName; }
+
+ public String getLastName() { return lastName; }
+ public void setLastName(String lastName) { this.lastName = lastName; }
+}]]></programlisting>
+
+ <para>
+ We also have a bean called <literal>CustomerAction</literal>, which is responsible for creating and editing
+ <literal>Customer</literal> instances. Since we're only interested in editing a customer right now, the
+ following code only shows the <literal>editCustomer()</literal> method:
+ </para>
+
+
+ <programlisting role="JAVA"><![CDATA[@ConversationScoped @Named
+public class CustomerAction {
+ @Inject Conversation conversation;
+ @PersistenceContext EntityManager entityManager;
+ public Customer customer;
+
+ public void editCustomer(Integer customerId) {
+ conversation.begin();
+ customer = entityManager.find(Customer.class, customerId);
+ }
+
+ public void saveCustomer() {
+ entityManager.merge(customer);
+ conversation.end();
+ }
+}]]></programlisting>
+
+ <para>
+ In the client section of this example, we wish to make changes to an existing <literal>Customer</literal>
+ instance, so we need to use the <literal>editCustomer()</literal> method of <literal>CustomerAction</literal>
+ to first load the customer entity, after which we can access it via the public <literal>customer</literal>
+ field. Our model object must therefore be configured to fetch the <literal>CustomerAction.customer</literal>
+ property, and to invoke the <literal>editCustomer()</literal> method when the model is fetched. We start
+ by using the <literal>addBeanProperty()</literal> method to add a bean property to the model:
+ </para>
+
+ <programlisting role="XHTML"><![CDATA[ var model = new Seam.Model();
+ model.addBeanProperty("customer", "CustomerAction", "customer");]]></programlisting>
+
+ <para>
+ The first parameter of <literal>addBeanProperty()</literal> is the <emphasis>alias</emphasis> (in this case
+ <literal>customer</literal>), which is used to access the value via the <literal>getValue()</literal> method.
+ The <literal>addBeanProperty()</literal> and <literal>addBean()</literal> methods can be called multiple times
+ to bind multiple values to the model. An important thing to note is that the values may come from multiple
+ server-side beans, they aren't all required to come from the same bean.
+ </para>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="images/remoting-model-customer-uml-1.png" format="PNG"/>
+ </imageobject>
+ </mediaobject>
+
+ <para>
+ We also specify the action that we wish to invoke (i.e. the <literal>editCustomer()</literal> method).
+ In this example we know the value of the <literal>customerId</literal> that we wish to edit, so we can
+ specify this value as an action method parameter:
+ </para>
+
+ <programlisting role="XHTML"><![CDATA[ var action = new Seam.Action()
+ .setBeanType("CustomerAction")
+ .setMethod("editCustomer")
+ .addParam(123);]]></programlisting>
+
+ <para>
+ Once we've specified the bean properties we wish to fetch and the action to invoke, we can then fetch the
+ model. We pass in a reference to the action object as the first parameter of the <literal>fetch()</literal>
+ method. Also, since this is an asynchronous request we need to provide a callback method to deal with the
+ response. The callback method is passed a reference to the model object as a parameter.
+ </para>
+
+ <programlisting role="XHTML"><![CDATA[ var callback = function(model) { alert("Fetched customer: " model.getValue("customer").firstName +
+ " " + model.getValue("customer").lastName); };
+ model.fetch(action, callback);]]></programlisting>
+
+ <para>
+ When the server receives a model fetch request, it first invokes the action (if one is specified) before
+ reading the requested property values and returning them to the client.
+ </para>
+
+ <section>
+ <title>Fetching a bean value</title>
+
+ <para>
+ Alternatively, if you don't wish to fetch a bean <emphasis>property</emphasis> but rather a bean itself
+ (such as a value created by a producer method) then the <literal>addBean()</literal> method is used instead.
+ Let's say we have a producer method that returns a qualified <literal>UserSettings</literal> value:
+ </para>
+
+ <programlisting role="JAVA"><![CDATA[ @Produces @ConversationScoped @Settings UserSettings getUserSettings() {
+ /* snip code */
+ }]]></programlisting>
+
+ <para>
+ We would add this value to our model with the following code:
+ </para>
+
+ <programlisting role="XHTML"><![CDATA[ model.addBean("settings", "UserSettings", "@Settings");]]></programlisting>
+
+ <para>
+ The first parameter is the local alias for the value, the second parameter is the fully qualified
+ class of the bean, and the third (and subsequent) parameter/s are optional bean qualifiers.
+ </para>
+
+ </section>
+ </section>
+
+ <section>
+ <title>Modifying model values</title>
+
+ <para>
+ Once a model has been fetched its values may be read using the <literal>getValue()</literal> method.
+ Continuing on with the previous example, we would retrieve the <literal>Customer</literal> object via
+ it's local alias (<literal>customer</literal>) like this:
+ </para>
+
+ <programlisting role="XHTML"><![CDATA[ var customer = model.getValue("customer");]]></programlisting>
+
+ <para>
+ We are then free to read or modify the properties of the value (or any of the other values within its
+ object graph).
+ </para>
+
+ <programlisting role="XHTML"><![CDATA[ alert("Customer name is: " + customer.firstName + " " + customer.lastName);
+ customer.setLastName("Jones"); // was Smith, but Peggy got married on the weekend]]></programlisting>
+
+ </section>
+
+ <section>
+ <title>Expanding a model</title>
+
+ <para>
+ We can use the Model API's ability to expand a model to load uninitialized branches of the objects in
+ the model's object graph. To understand how this works exactly, let's flesh out our example a little
+ more by adding an <literal>Address</literal> entity class, and creating a one-to-many relationship
+ between <literal>Customer</literal> and <literal>Address</literal>.
+ </para>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="images/remoting-model-customer-address-uml.png" format="PNG"/>
+ </imageobject>
+ </mediaobject>
+
+ <programlisting role="JAVA"><![CDATA[@Entity Address implements Serializable {
+ private Integer addressId;
+ private Customer customer;
+ private String unitNumber;
+ private String streetNumber;
+ private String streetName;
+ private String suburb;
+ private String zip;
+ private String state;
+ private String country;
+
+ @Id @GeneratedValue public Integer getAddressId() { return addressId; }
+ public void setAddressId(Integer addressId) { this.addressId = addressId; }
+
+ @ManyToOne public Customer getCustomer() { return customer; }
+ public void setCustomer(Customer customer) { this.customer = customer; }
+
+ /* Snipped other getter/setter methods */
+
+}]]></programlisting>
+
+ <para>
+ Here's the new field and methods that we also need to add to the <literal>Customer</literal> class:
+ </para>
+
+ <programlisting role="JAVA"><![CDATA[ private Collection<Address> addresses;
+
+ @OneToMany(fetch = FetchType.LAZY, mappedBy = "customer", cascade = CascadeType.ALL)
+ public Collection<Address> getAddresses() { return addresses; }
+ public void setAddresses(Collection<Address> addresses) { this.addresses = addresses; }]]></programlisting>
+
+ <para>
+ As we can see, the <literal>@OneToMany</literal> annotation on the <literal>getAddresses()</literal>
+ method specifies a <literal>fetch</literal> attribute of <literal>LAZY</literal>, meaning that by
+ default the customer's addresses won't be loaded automatically when the customer is. When reading the
+ <emphasis>uninitialized</emphasis> <literal>addresses</literal> property value from a newly-fetched
+ <literal>Customer</literal> object in JavaScript, a value of <literal>undefined</literal> will be returned.
+ </para>
+
+ <programlisting role="XHTML"><![CDATA[ getValue("customer").addresses == undefined; // returns true]]></programlisting>
+
+ <para>
+ We can <emphasis>expand</emphasis> the model by making a special request to initialize this uninitialized
+ property value. The <literal>expand()</literal> operation takes three parameters - the value containing
+ the property to be initialized, the name of the property and an optional callback method. The following
+ example shows us how the customer's <literal>addresses</literal> property can be initialized:
+ </para>
+
+ <programlisting role="XHTML"><![CDATA[ model.expand(model.getValue("customer"), "addresses");]]></programlisting>
+
+ <para>
+ The <literal>expand()</literal> operation makes an asynchronous request to the server, where the
+ property value is initialized and the value returned to the client. When the client receives the
+ response, it reads the initialized value and appends it to the model.
+ </para>
+
+ <programlisting role="XHTML"><![CDATA[ // The addresses property now contains an array of address objects
+ alert(model.getValue("customer").addresses.length + " addresses loaded");]]></programlisting>
+
+ </section>
+
+ <section>
+ <title>Applying Changes</title>
+
+ <para>
+ Once you have finished making changes to the values in the model, you can apply them with the
+ <literal>applyUpdates()</literal> method. This method scans all of the objects in the model, compares
+ them with their original values and generates a delta which may contain one or more changesets to
+ send to the server. A changeset is simply a list of property value changes for a single object.
+ </para>
+
+ <para>
+ Like the <literal>fetch()</literal> command you can also specify an action to invoke when applying updates,
+ although the action is invoked <emphasis>after</emphasis> the model updates have been applied. In a
+ typical situation the invoked action would do things like commit a database transaction, end the current
+ conversation, etc.
+ </para>
+
+ <para>
+ Since the <literal>applyUpdates()</literal> method sends an asynchronous request like the
+ <literal>fetch()</literal> and <literal>expand()</literal> methods, we also need to specify a callback
+ function if we wish to do something when the operation completes.
+ </para>
+
+ <programlisting role="XHTML"><![CDATA[ var action = new Seam.Action();
+ .setBeanType("CustomerAction")
+ .setMethod("saveCustomer");
+
+ var callback = function() { alert("Customer saved."); };
+
+ model.applyUpdates(action, callback);]]></programlisting>
+
+ <para>
+ The <literal>applyUpdates()</literal> method performs a refresh of the model, retrieving the latest
+ state of the objects contained in the model after all updates have been applied and the action method
+ (if specified) invoked.
+ </para>
+ </section>
+
+
+</chapter>
+
Added: modules/trunk/docs/en-US/master.xml
===================================================================
--- modules/trunk/docs/en-US/master.xml (rev 0)
+++ modules/trunk/docs/en-US/master.xml 2010-03-26 04:53:15 UTC (rev 12286)
@@ -0,0 +1,12 @@
+<?xml version='1.0' encoding="utf-8"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [ ]>
+<book lang="en">
+
+ <toc/>
+
+ <title>Seam Drools</title>
+ <xi:include href="drools-general.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <xi:include href="drools-model.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+</book>
Added: modules/trunk/docs/pom.xml
===================================================================
--- modules/trunk/docs/pom.xml (rev 0)
+++ modules/trunk/docs/pom.xml 2010-03-26 04:53:15 UTC (rev 12286)
@@ -0,0 +1,136 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.jboss.weld</groupId>
+ <artifactId>weld-parent</artifactId>
+ <version>8</version>
+ </parent>
+
+ <groupId>org.jboss.seam.drools</groupId>
+ <artifactId>seam-drools-reference-guide</artifactId>
+ <version>3.0.0-SNAPSHOT</version>
+ <packaging>jdocbook</packaging>
+ <name>Seam Drools Reference Guide</name>
+
+ <pluginRepositories>
+ <pluginRepository>
+ <id>repository.jboss.org</id>
+ <name>JBoss Repository</name>
+ <url>http://repository.jboss.org/maven2</url>
+ </pluginRepository>
+ </pluginRepositories>
+ <repositories>
+ <repository>
+ <id>repository.jboss.org</id>
+ <name>JBoss Repository</name>
+ <url>http://repository.jboss.org/maven2</url>
+ </repository>
+ </repositories>
+
+ <properties>
+ <pdf.name>drools-reference.pdf</pdf.name>
+ <weld.docbook.version>1.1.1-Beta5</weld.docbook.version>
+ </properties>
+
+ <build>
+ <defaultGoal>process-classes</defaultGoal>
+ <plugins>
+ <plugin>
+ <artifactId>maven-deploy-plugin</artifactId>
+ <configuration>
+ <skip>true</skip>
+ </configuration>
+ </plugin>
+
+ <plugin>
+ <groupId>org.jboss.maven.plugins</groupId>
+ <artifactId>maven-jdocbook-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <artifactId>maven-antrun-plugin</artifactId>
+ <executions>
+ <execution>
+ <phase>process-classes</phase>
+ <configuration>
+ <tasks>
+ <copy file="${basedir}/target/docbook/publish/en-US/pdf/${pdf.name}" todir="${basedir}" />
+ </tasks>
+ </configuration>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>build-helper-maven-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>attach-zip</id>
+ <phase>package</phase>
+ <goals>
+ <goal>attach-artifact</goal>
+ </goals>
+ <configuration>
+ <artifacts>
+ <artifact>
+ <file>${project.build.outputDirectory}/${project.artifactId}-${project.version}.war</file>
+ <type>war</type>
+ </artifact>
+ </artifacts>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+
+ <profiles>
+
+ <profile>
+ <id>translations</id>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.jboss.maven.plugins</groupId>
+ <artifactId>maven-jdocbook-plugin</artifactId>
+
+ <executions>
+ <execution>
+ <phase>process-resources</phase>
+ <goals>
+ <goal>translate</goal>
+ </goals>
+ </execution>
+ </executions>
+
+ <configuration>
+ <translations>
+ <!--translation>it-IT</translation>
+ <translation>zh-CN</translation>
+ <translation>zh-TW</translation>
+ <translation>es-ES</translation>
+ <translation>ko-KR</translation>
+
+ <translation>de-DE</translation>
+ <translation>pt-BR</translation-->
+ </translations>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+
+ </profiles>
+
+
+ <scm>
+ <connection>scm:svn:http://anonsvn.jboss.org/repos/seam/modules/drools/trunk/docs</connection>
+ <developerConnection>scm:svn:https://svn.jboss.org/repos/seam/modules/drools/trunk/docs</developerConnection>
+ <url>http://fisheye.jboss.org/browse/seam/modules/drools/docs</url>
+ </scm>
+
+</project>
+
Added: modules/trunk/lgpl.txt
===================================================================
--- modules/trunk/lgpl.txt (rev 0)
+++ modules/trunk/lgpl.txt 2010-03-26 04:53:15 UTC (rev 12286)
@@ -0,0 +1,504 @@
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL. It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+ This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it. You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+ When we speak of free software, we are referring to freedom of use,
+not price. Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+ To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights. These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+
+ We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ To protect each distributor, we want to make it very clear that
+there is no warranty for the free library. Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+ Finally, software patents pose a constant threat to the existence of
+any free program. We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder. Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+ Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License. This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License. We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+ When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library. The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom. The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+ We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License. It also provides other free software developers Less
+of an advantage over competing non-free programs. These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries. However, the Lesser license provides advantages in certain
+special circumstances.
+
+ For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard. To achieve this, non-free programs must be
+allowed to use the library. A more frequent case is that a free
+library does the same job as widely used non-free libraries. In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+ In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software. For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+ Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+ The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+ GNU LESSER GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+ A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+ The "Library", below, refers to any such software library or work
+which has been distributed under these terms. A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+ "Source code" for a work means the preferred form of the work for
+making modifications to it. For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+ Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+ 1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+ You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+ 2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) The modified work must itself be a software library.
+
+ b) You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ c) You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ d) If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility
+ is invoked, then you must make a good faith effort to ensure that,
+ in the event an application does not supply such function or
+ table, the facility still operates, and performs whatever part of
+ its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots has
+ a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square
+ root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+
+ Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+ 4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+ If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library". Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+ However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library". The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+ When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+
+ If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+ 6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+
+ a) Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood
+ that the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+
+ b) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (1) uses at run time a
+ copy of the library already present on the user's computer system,
+ rather than copying library functions into the executable, and (2)
+ will operate properly with a modified version of the library, if
+ the user installs one, as long as the modified version is
+ interface-compatible with the version that the work was made with.
+
+ c) Accompany the work with a written offer, valid for at
+ least three years, to give the same user the materials
+ specified in Subsection 6a, above, for a charge no more
+ than the cost of performing this distribution.
+
+ d) If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+
+ e) Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+ For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it. However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+ It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+ 7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+ a) Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the
+ Sections above.
+
+ b) Give prominent notice with the combined library of the fact
+ that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same work.
+
+ 8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License. However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+ 9. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Library or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+ 10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+
+ 11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded. In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+ 13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation. If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+ 14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission. For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this. Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+ NO WARRANTY
+
+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Libraries
+
+ If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change. You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+ To apply these terms, attach the following notices to the library. It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the library's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the
+ library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+ <signature of Ty Coon>, 1 April 1990
+ Ty Coon, President of Vice
+
+That's all there is to it!
+
+
Added: modules/trunk/pom.xml
===================================================================
--- modules/trunk/pom.xml (rev 0)
+++ modules/trunk/pom.xml 2010-03-26 04:53:15 UTC (rev 12286)
@@ -0,0 +1,99 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <artifactId>weld-parent</artifactId>
+ <groupId>org.jboss.weld</groupId>
+ <version>8</version>
+ </parent>
+
+ <groupId>org.jboss.seam.drools</groupId>
+ <artifactId>seam-drools-parent</artifactId>
+ <packaging>pom</packaging>
+ <version>3.0.0-SNAPSHOT</version>
+ <name>Seam Drools Parent</name>
+
+ <modules>
+ <module>core</module>
+ <module>docs</module>
+ <!-- <module>examples</module> -->
+ </modules>
+
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-assembly-plugin</artifactId>
+ <version>2.2-beta-5</version>
+ <configuration>
+ <descriptors>
+ <descriptor>assembly.xml</descriptor>
+ </descriptors>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+ <dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>javax.el</groupId>
+ <artifactId>el-api</artifactId>
+ <version>2.2</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>javax.validation</groupId>
+ <artifactId>validation-api</artifactId>
+ <version>1.0.0.GA</version>
+ </dependency>
+ <dependency>
+ <groupId>javax.enterprise</groupId>
+ <artifactId>cdi-api</artifactId>
+ <version>1.0-SP1</version>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ <version>1.5.10</version>
+ </dependency>
+ <dependency>
+ <groupId>org.drools</groupId>
+ <artifactId>drools-core</artifactId>
+ <version>5.1.0.M1</version>
+ </dependency>
+ <dependency>
+ <groupId>org.drools</groupId>
+ <artifactId>drools-compiler</artifactId>
+ <version>5.1.0.M1</version>
+ </dependency>
+ <dependency>
+ <groupId>org.drools</groupId>
+ <artifactId>drools-api</artifactId>
+ <version>5.1.0.M1</version>
+ </dependency>
+ <dependency>
+ <groupId>org.drools</groupId>
+ <artifactId>drools-templates</artifactId>
+ <version>5.1.0.M1</version>
+ </dependency>
+ <dependency>
+ <groupId>org.drools</groupId>
+ <artifactId>drools-decisiontables</artifactId>
+ <version>5.1.0.M1</version>
+ </dependency>
+ <dependency>
+ <groupId>org.drools</groupId>
+ <artifactId>drools-workitems</artifactId>
+ <version>5.1.0.M1</version>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+
+ <scm>
+ <connection>scm:svn:http://anonsvn.jboss.org/repos/seam/modules/drools/trunk</connection>
+ <developerConnection>scm:svn:https://svn.jboss.org/repos/seam/modules/drools/trunk</developerConnection>
+ <url>http://fisheye.jboss.org/browse/Seam/modules/drools/trunk</url>
+ </scm>
+
+</project>
Added: modules/trunk/readme.txt
===================================================================
--- modules/trunk/readme.txt (rev 0)
+++ modules/trunk/readme.txt 2010-03-26 04:53:15 UTC (rev 12286)
@@ -0,0 +1,64 @@
+Seam Drools 3.0.0 Beta 1
+==========================
+
+Seam Drools provides integration with the Drools 5 API.
+
+
+Contents of distribution
+========================
+
+doc/
+
+ API Docs and reference guide.
+
+examples/
+
+ Seam Drools Examples
+
+lib/
+
+ Seam Drools jar files
+
+Licensing
+=========
+
+This distribution, as a whole, is licensed under the terms of the GNU Lesser General Public License
+(LGPL) Version 2.1, the text of which is contained in the file lgpl.txt.
+
+Seam Remoting URLs
+==================
+
+Seam Framework Home Page: http://www.seamframework.org
+Downloads: http://www.seamframework.org/Download/SeamDownloads
+Forums: http://www.seamframework.org/Community/SeamUsers
+Source Code: http://anonsvn.jboss.org/repos/seam/modules/drools/
+Issue Tracking: http://jira.jboss.org/jira/browse/SEAMDROOLS
+
+Release Notes
+=============
+
+Version 3.0.0 Beta 1
+--------------------
+First beta release of Seam Drools 3.x, ported from Seam 2.x to CDI.
+
+
+* If using Maven, some artifacts may only be available in the JBoss Repository. To allow Seam Remoting to correctly function, add the JBoss Repository to Maven. Edit your ~/.m2/settings.xml, and add the following entry:
+
+ <profile>
+ <id>jboss.repository</id>
+ <activation>
+ <activeByDefault>true</activeByDefault>
+ </activation>
+ <repositories>
+ <repository>
+ <id>repository.jboss.org</id>
+ <url>http://repository.jboss.org/maven2</url>
+ <releases>
+ <enabled>true</enabled>
+ </releases>
+ <snapshots>
+ <enabled>false</enabled>
+ </snapshots>
+ </repository>
+ </repositories>
+ </profile>
14 years, 9 months