Seam SVN: r10635 - modules/trunk/international/src/main/java/org/jboss/seam/international.
by seam-commits@lists.jboss.org
Author: shane.bryzak(a)jboss.com
Date: 2009-04-24 19:27:12 -0400 (Fri, 24 Apr 2009)
New Revision: 10635
Removed:
modules/trunk/international/src/main/java/org/jboss/seam/international/Locale.java
Modified:
modules/trunk/international/src/main/java/org/jboss/seam/international/LocaleSelector.java
modules/trunk/international/src/main/java/org/jboss/seam/international/StatusMessages.java
modules/trunk/international/src/main/java/org/jboss/seam/international/TimeZoneSelector.java
Log:
…
[View More]more porting of international module
Deleted: modules/trunk/international/src/main/java/org/jboss/seam/international/Locale.java
===================================================================
--- modules/trunk/international/src/main/java/org/jboss/seam/international/Locale.java 2009-04-24 23:26:14 UTC (rev 10634)
+++ modules/trunk/international/src/main/java/org/jboss/seam/international/Locale.java 2009-04-24 23:27:12 UTC (rev 10635)
@@ -1,21 +0,0 @@
-package org.jboss.seam.international;
-
-import javax.annotation.Named;
-import javax.inject.Produces;
-
-/**
- * Manager component for the current locale that is
- * aware of the selected locale
- *
- * @author Gavin King
- */
-public class Locale
-{
- @Produces public java.util.Locale getLocale()
- {
- return Contexts.isSessionContextActive() ?
- LocaleSelector.instance().getLocale() :
- super.getLocale();
- }
-
-}
\ No newline at end of file
Modified: modules/trunk/international/src/main/java/org/jboss/seam/international/LocaleSelector.java
===================================================================
--- modules/trunk/international/src/main/java/org/jboss/seam/international/LocaleSelector.java 2009-04-24 23:26:14 UTC (rev 10634)
+++ modules/trunk/international/src/main/java/org/jboss/seam/international/LocaleSelector.java 2009-04-24 23:27:12 UTC (rev 10635)
@@ -13,6 +13,7 @@
import javax.faces.model.SelectItem;
import javax.inject.Current;
import javax.inject.Initializer;
+import javax.inject.Produces;
import javax.inject.manager.Manager;
import javax.servlet.ServletRequest;
@@ -140,7 +141,7 @@
/**
* Get the selected locale
*/
- public Locale getLocale()
+ @Produces public Locale getLocale()
{
FacesContext facesContext = FacesContext.getCurrentInstance();
if (facesContext!=null)
Modified: modules/trunk/international/src/main/java/org/jboss/seam/international/StatusMessages.java
===================================================================
--- modules/trunk/international/src/main/java/org/jboss/seam/international/StatusMessages.java 2009-04-24 23:26:14 UTC (rev 10634)
+++ modules/trunk/international/src/main/java/org/jboss/seam/international/StatusMessages.java 2009-04-24 23:27:12 UTC (rev 10635)
@@ -10,9 +10,6 @@
import java.util.Map;
import org.hibernate.validator.InvalidValue;
-import org.jboss.seam.Component;
-import org.jboss.seam.ScopeType;
-import org.jboss.seam.contexts.Contexts;
import org.jboss.seam.international.StatusMessage.Severity;
/**
@@ -369,18 +366,6 @@
return tasks;
}
- protected static void runTasks()
- {
- if ( Contexts.isConversationContextActive() )
- {
- StatusMessages statusMessages = instance();
- if (statusMessages != null)
- {
- statusMessages.doRunTasks();
- }
- }
- }
-
protected void doRunTasks()
{
if (tasks!=null)
@@ -389,14 +374,5 @@
tasks.clear();
}
}
-
- public static StatusMessages instance()
- {
- if ( !Contexts.isConversationContextActive() )
- {
- throw new IllegalStateException("No active conversation context");
- }
- return (StatusMessages) Component.getInstance(COMPONENT_NAME, ScopeType.CONVERSATION);
- }
}
Modified: modules/trunk/international/src/main/java/org/jboss/seam/international/TimeZoneSelector.java
===================================================================
--- modules/trunk/international/src/main/java/org/jboss/seam/international/TimeZoneSelector.java 2009-04-24 23:26:14 UTC (rev 10634)
+++ modules/trunk/international/src/main/java/org/jboss/seam/international/TimeZoneSelector.java 2009-04-24 23:27:12 UTC (rev 10635)
@@ -89,14 +89,5 @@
return java.util.TimeZone.getTimeZone( getTimeZoneId() );
}
}
-
- public static TimeZoneSelector instance()
- {
- if ( !Contexts.isSessionContextActive() )
- {
- throw new IllegalStateException("No active session context");
- }
- return (TimeZoneSelector) Component.getInstance(TimeZoneSelector.class, ScopeType.SESSION);
- }
}
[View Less]
15 years, 10 months
Seam SVN: r10634 - modules/trunk/drools/src/main/java/org/jboss/seam/drools.
by seam-commits@lists.jboss.org
Author: shane.bryzak(a)jboss.com
Date: 2009-04-24 19:26:14 -0400 (Fri, 24 Apr 2009)
New Revision: 10634
Removed:
modules/trunk/drools/src/main/java/org/jboss/seam/drools/package-info.java
Log:
removed package-info
Deleted: modules/trunk/drools/src/main/java/org/jboss/seam/drools/package-info.java
===================================================================
--- modules/trunk/drools/src/main/java/org/jboss/seam/drools/package-info.java 2009-04-24 23:25:43 UTC (rev 10633)
+++ modules/…
[View More]trunk/drools/src/main/java/org/jboss/seam/drools/package-info.java 2009-04-24 23:26:14 UTC (rev 10634)
@@ -1,7 +0,0 @@
-/**
- * Seam components for integrating Drools.
- */
-@Namespace(value="http://jboss.com/products/seam/drools", prefix="org.jboss.seam.drools")
-package org.jboss.seam.drools;
-
-import org.jboss.seam.annotations.Namespace;
[View Less]
15 years, 10 months
Seam SVN: r10633 - in modules/trunk/drools: src/main/java and 4 other directories.
by seam-commits@lists.jboss.org
Author: shane.bryzak(a)jboss.com
Date: 2009-04-24 19:25:43 -0400 (Fri, 24 Apr 2009)
New Revision: 10633
Added:
modules/trunk/drools/pom.xml
modules/trunk/drools/src/main/java/org/
modules/trunk/drools/src/main/java/org/jboss/
modules/trunk/drools/src/main/java/org/jboss/seam/
modules/trunk/drools/src/main/java/org/jboss/seam/drools/
modules/trunk/drools/src/main/java/org/jboss/seam/drools/Decision.java
modules/trunk/drools/src/main/java/org/jboss/seam/drools/…
[View More]DroolsActionHandler.java
modules/trunk/drools/src/main/java/org/jboss/seam/drools/DroolsAssignmentHandler.java
modules/trunk/drools/src/main/java/org/jboss/seam/drools/DroolsDecisionHandler.java
modules/trunk/drools/src/main/java/org/jboss/seam/drools/DroolsHandler.java
modules/trunk/drools/src/main/java/org/jboss/seam/drools/ManagedWorkingMemory.java
modules/trunk/drools/src/main/java/org/jboss/seam/drools/RuleAgent.java
modules/trunk/drools/src/main/java/org/jboss/seam/drools/RuleBase.java
modules/trunk/drools/src/main/java/org/jboss/seam/drools/SeamGlobalResolver.java
modules/trunk/drools/src/main/java/org/jboss/seam/drools/package-info.java
Modified:
modules/trunk/drools/
Log:
initial import of drools module
Property changes on: modules/trunk/drools
___________________________________________________________________
Name: svn:ignore
+ target
.classpath
.project
.settings
Added: modules/trunk/drools/pom.xml
===================================================================
--- modules/trunk/drools/pom.xml (rev 0)
+++ modules/trunk/drools/pom.xml 2009-04-24 23:25:43 UTC (rev 10633)
@@ -0,0 +1,33 @@
+<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">
+ <parent>
+ <artifactId>seam-parent</artifactId>
+ <groupId>org.jboss.seam</groupId>
+ <version>3.0.0-SNAPSHOT</version>
+ </parent>
+
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.jboss.seam</groupId>
+ <artifactId>seam-drools</artifactId>
+ <packaging>jar</packaging>
+ <version>3.0.0-SNAPSHOT</version>
+ <name>Seam Drools</name>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.jboss.webbeans</groupId>
+ <artifactId>jsr299-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.jboss.webbeans</groupId>
+ <artifactId>webbeans-logging</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.drools</groupId>
+ <artifactId>drools-core</artifactId>
+ </dependency>
+
+ </dependencies>
+
+</project>
Added: modules/trunk/drools/src/main/java/org/jboss/seam/drools/Decision.java
===================================================================
--- modules/trunk/drools/src/main/java/org/jboss/seam/drools/Decision.java (rev 0)
+++ modules/trunk/drools/src/main/java/org/jboss/seam/drools/Decision.java 2009-04-24 23:25:43 UTC (rev 10633)
@@ -0,0 +1,21 @@
+package org.jboss.seam.drools;
+
+/**
+ * API for setting the result of a decision from rules in
+ * a Drools decision handler.
+ *
+ */
+public class Decision
+{
+ private String outcome;
+
+ public String getOutcome()
+ {
+ return outcome;
+ }
+
+ public void setOutcome(String outcome)
+ {
+ this.outcome = outcome;
+ }
+}
Added: modules/trunk/drools/src/main/java/org/jboss/seam/drools/DroolsActionHandler.java
===================================================================
--- modules/trunk/drools/src/main/java/org/jboss/seam/drools/DroolsActionHandler.java (rev 0)
+++ modules/trunk/drools/src/main/java/org/jboss/seam/drools/DroolsActionHandler.java 2009-04-24 23:25:43 UTC (rev 10633)
@@ -0,0 +1,28 @@
+package org.jboss.seam.drools;
+
+import java.util.List;
+
+import org.jbpm.graph.def.ActionHandler;
+import org.jbpm.graph.exe.ExecutionContext;
+
+/**
+ * A jBPM ActionHandler that delegates to a Drools WorkingMemory
+ * held in a Seam context variable.
+ *
+ * @author Jeff Delong
+ * @author Gavin King
+ *
+ */
+public class DroolsActionHandler extends DroolsHandler implements ActionHandler
+{
+ private static final long serialVersionUID = 7752070876220597913L;
+
+ public List<String> assertObjects;
+ public String workingMemoryName;
+
+ public void execute(ExecutionContext executionContext) throws Exception
+ {
+ getWorkingMemory(workingMemoryName, assertObjects, executionContext).fireAllRules();
+ }
+
+}
\ No newline at end of file
Added: modules/trunk/drools/src/main/java/org/jboss/seam/drools/DroolsAssignmentHandler.java
===================================================================
--- modules/trunk/drools/src/main/java/org/jboss/seam/drools/DroolsAssignmentHandler.java (rev 0)
+++ modules/trunk/drools/src/main/java/org/jboss/seam/drools/DroolsAssignmentHandler.java 2009-04-24 23:25:43 UTC (rev 10633)
@@ -0,0 +1,32 @@
+package org.jboss.seam.drools;
+
+import java.util.List;
+
+import org.drools.WorkingMemory;
+import org.jbpm.graph.exe.ExecutionContext;
+import org.jbpm.taskmgmt.def.AssignmentHandler;
+import org.jbpm.taskmgmt.exe.Assignable;
+
+/**
+ * A jBPM AssignmentHandler that delegates to a Drools WorkingMemory
+ * held in a Seam context variable.
+ *
+ * @author Jeff Delong
+ * @author Gavin King
+ *
+ */
+public class DroolsAssignmentHandler extends DroolsHandler implements AssignmentHandler
+{
+ private static final long serialVersionUID = -7114640047036854546L;
+
+ public String workingMemoryName;
+ public List<String> assertObjects;
+
+ public void assign(Assignable assignable, ExecutionContext executionContext) throws Exception
+ {
+ WorkingMemory workingMemory = getWorkingMemory(workingMemoryName, assertObjects, executionContext);
+ workingMemory.setGlobal( "assignable", assignable );
+ workingMemory.fireAllRules();
+ }
+
+}
\ No newline at end of file
Added: modules/trunk/drools/src/main/java/org/jboss/seam/drools/DroolsDecisionHandler.java
===================================================================
--- modules/trunk/drools/src/main/java/org/jboss/seam/drools/DroolsDecisionHandler.java (rev 0)
+++ modules/trunk/drools/src/main/java/org/jboss/seam/drools/DroolsDecisionHandler.java 2009-04-24 23:25:43 UTC (rev 10633)
@@ -0,0 +1,32 @@
+package org.jboss.seam.drools;
+
+import java.util.List;
+
+import org.drools.WorkingMemory;
+import org.jbpm.graph.exe.ExecutionContext;
+import org.jbpm.graph.node.DecisionHandler;
+
+/**
+ * A jBPM DecisionHandler that delegates to a Drools WorkingMemory
+ * held in a Seam context variable. The decision outcome is returned
+ * by setting the outcome attribute of the global named "decision".
+ *
+ * @author Gavin King
+ *
+ */
+public class DroolsDecisionHandler extends DroolsHandler implements DecisionHandler
+{
+ private static final long serialVersionUID = -8900810376838166513L;
+
+ public List<String> assertObjects;
+ public String workingMemoryName;
+
+ public String decide(ExecutionContext executionContext) throws Exception
+ {
+ WorkingMemory workingMemory = getWorkingMemory(workingMemoryName, assertObjects, executionContext);
+ workingMemory.setGlobal( "decision", new Decision() );
+ workingMemory.fireAllRules();
+ return ( (Decision) workingMemory.getGlobal("decision") ).getOutcome();
+ }
+
+}
\ No newline at end of file
Added: modules/trunk/drools/src/main/java/org/jboss/seam/drools/DroolsHandler.java
===================================================================
--- modules/trunk/drools/src/main/java/org/jboss/seam/drools/DroolsHandler.java (rev 0)
+++ modules/trunk/drools/src/main/java/org/jboss/seam/drools/DroolsHandler.java 2009-04-24 23:25:43 UTC (rev 10633)
@@ -0,0 +1,63 @@
+package org.jboss.seam.drools;
+
+import java.util.List;
+
+import org.drools.FactHandle;
+import org.drools.WorkingMemory;
+import org.jboss.seam.Component;
+import org.jboss.seam.bpm.Actor;
+import org.jboss.seam.core.Expressions;
+import org.jbpm.graph.exe.ExecutionContext;
+import org.jbpm.jpdl.el.ELException;
+
+/**
+ * Common functionality for jBPM handlers for Drools.
+ *
+ * @author Jeff Delong
+ * @author Gavin King
+ *
+ */
+public class DroolsHandler
+{
+ protected WorkingMemory getWorkingMemory(String workingMemoryName, List<String> expressions, ExecutionContext executionContext)
+ throws ELException
+ {
+ WorkingMemory workingMemory = (WorkingMemory) Component.getInstance(workingMemoryName, true);
+
+ for (String objectName: expressions)
+ {
+ Object object = Expressions.instance().createValueExpression(objectName).getValue();
+ //Object object = new SeamVariableResolver().resolveVariable(objectName);
+ // assert the object into the rules engine
+ if (object instanceof Iterable)
+ {
+ for (Object element: (Iterable) object)
+ {
+ assertObject(workingMemory, element);
+ }
+ }
+ else
+ {
+ assertObject(workingMemory, object);
+ }
+ }
+
+ //workingMemory.setGlobal( "contextInstance", executionContext.getContextInstance() );
+ workingMemory.insert(Actor.instance());
+
+ return workingMemory;
+ }
+
+ private void assertObject(WorkingMemory workingMemory, Object element)
+ {
+ FactHandle fact = workingMemory.getFactHandle(element);
+ if (fact==null)
+ {
+ workingMemory.insert(element);
+ }
+ else
+ {
+ workingMemory.update(fact, element);
+ }
+ }
+}
Added: modules/trunk/drools/src/main/java/org/jboss/seam/drools/ManagedWorkingMemory.java
===================================================================
--- modules/trunk/drools/src/main/java/org/jboss/seam/drools/ManagedWorkingMemory.java (rev 0)
+++ modules/trunk/drools/src/main/java/org/jboss/seam/drools/ManagedWorkingMemory.java 2009-04-24 23:25:43 UTC (rev 10633)
@@ -0,0 +1,118 @@
+package org.jboss.seam.drools;
+
+import java.io.Serializable;
+
+import org.drools.RuleBase;
+import org.drools.StatefulSession;
+import org.drools.spi.GlobalResolver;
+import org.jboss.seam.Component;
+import org.jboss.seam.ScopeType;
+import org.jboss.seam.annotations.Destroy;
+import org.jboss.seam.annotations.Scope;
+import org.jboss.seam.annotations.Unwrap;
+import org.jboss.seam.annotations.intercept.BypassInterceptors;
+import org.jboss.seam.core.Mutable;
+import org.jboss.seam.core.Expressions.ValueExpression;
+
+/**
+ * A conversation-scoped Drools WorkingMemory for a named RuleBase
+ *
+ * @author Gavin King
+ *
+ */
+(a)Scope(ScopeType.CONVERSATION)
+@BypassInterceptors
+public class ManagedWorkingMemory implements Mutable, Serializable
+{
+ private static final long serialVersionUID = -1746942080571374743L;
+
+ private String ruleBaseName;
+ private StatefulSession statefulSession;
+ private ValueExpression<RuleBase> ruleBase;
+
+ public boolean clearDirty()
+ {
+ return true;
+ }
+
+ /**
+ * The name of a Seam context variable holding an
+ * instance of org.drools.RuleBase
+ *
+ * @return a context variable name
+ * @deprecated
+ */
+ public String getRuleBaseName()
+ {
+ return ruleBaseName;
+ }
+
+ /**
+ * The name of a Seam context variable holding an
+ * instance of org.drools.RuleBase
+ *
+ * @param ruleBaseName a context variable name
+ * @deprecated
+ */
+ public void setRuleBaseName(String ruleBaseName)
+ {
+ this.ruleBaseName = ruleBaseName;
+ }
+
+ @Unwrap
+ public StatefulSession getStatefulSession()
+ {
+ if (statefulSession==null)
+ {
+ statefulSession = getRuleBaseFromValueBinding().newStatefulSession();
+ statefulSession.setGlobalResolver( createGlobalResolver( statefulSession.getGlobalResolver() ) );
+ }
+ return statefulSession;
+ }
+
+ protected RuleBase getRuleBaseFromValueBinding()
+ {
+ RuleBase ruleBase;
+ if (this.ruleBase!=null)
+ {
+ ruleBase = this.ruleBase.getValue();
+ }
+ else if (ruleBaseName!=null)
+ {
+ //deprecated stuff
+ ruleBase = (RuleBase) Component.getInstance(ruleBaseName, true);
+ }
+ else
+ {
+ throw new IllegalStateException("No RuleBase");
+ }
+
+ if (ruleBase==null)
+ {
+ throw new IllegalStateException("RuleBase not found: " + ruleBaseName);
+ }
+ return ruleBase;
+ }
+
+ protected GlobalResolver createGlobalResolver(GlobalResolver delegate)
+ {
+ return new SeamGlobalResolver(delegate);
+ }
+
+ @Destroy
+ public void destroy()
+ {
+ statefulSession.dispose();
+ }
+
+ public ValueExpression<RuleBase> getRuleBase()
+ {
+ return ruleBase;
+ }
+
+ public void setRuleBase(ValueExpression<RuleBase> ruleBase)
+ {
+ this.ruleBase = ruleBase;
+ }
+
+}
Added: modules/trunk/drools/src/main/java/org/jboss/seam/drools/RuleAgent.java
===================================================================
--- modules/trunk/drools/src/main/java/org/jboss/seam/drools/RuleAgent.java (rev 0)
+++ modules/trunk/drools/src/main/java/org/jboss/seam/drools/RuleAgent.java 2009-04-24 23:25:43 UTC (rev 10633)
@@ -0,0 +1,161 @@
+package org.jboss.seam.drools;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Properties;
+
+import org.jboss.seam.ScopeType;
+import org.jboss.seam.annotations.Create;
+import org.jboss.seam.annotations.Scope;
+import org.jboss.seam.annotations.Unwrap;
+import org.jboss.seam.annotations.intercept.BypassInterceptors;
+import org.jboss.seam.log.LogProvider;
+import org.jboss.seam.log.Logging;
+import org.jboss.seam.util.Resources;
+
+/**
+ * Manager component for a rule base loaded from a drools RulesAgent
+ */
+(a)Scope(ScopeType.APPLICATION)
+@BypassInterceptors
+public class RuleAgent
+{
+ private static final LogProvider log = Logging.getLogProvider(RuleAgent.class);
+
+ private org.drools.agent.RuleAgent agent;
+ private String configurationFile;
+
+ private String newInstance;
+ private String files;
+ private String url;
+ private String localCacheDir;
+ private String poll;
+ private String configName;
+
+ @Create
+ public void createAgent() throws Exception
+ {
+ Properties properties = new Properties();
+
+ loadFromPath(properties, configurationFile);
+ setLocalProperties(properties);
+
+ agent = org.drools.agent.RuleAgent.newRuleAgent(properties);
+ log.debug("Creating new rules agent");
+ }
+
+ protected void setLocalProperties(Properties properties)
+ {
+ if (newInstance != null) {
+ properties.setProperty(org.drools.agent.RuleAgent.NEW_INSTANCE, newInstance);
+ }
+ if (files != null) {
+ properties.setProperty(org.drools.agent.RuleAgent.FILES, files);
+ }
+ if (url != null) {
+ properties.setProperty(org.drools.agent.RuleAgent.URLS, url);
+ }
+ if (localCacheDir != null) {
+ properties.setProperty(org.drools.agent.RuleAgent.LOCAL_URL_CACHE, localCacheDir);
+ }
+ if (poll != null) {
+ properties.setProperty(org.drools.agent.RuleAgent.POLL_INTERVAL, poll);
+ }
+ if (configName != null) {
+ properties.setProperty(org.drools.agent.RuleAgent.CONFIG_NAME, configName);
+ }
+
+ }
+
+ protected void loadFromPath(Properties properties, String configurationFile)
+ throws IOException
+ {
+ if (configurationFile != null) {
+ InputStream inputStream = Resources.getResourceAsStream(configurationFile, null);
+ if (inputStream != null) {
+ try {
+ properties.load(inputStream);
+ } finally {
+ inputStream.close();
+ }
+ }
+ }
+ }
+
+ @Unwrap
+ public org.drools.RuleBase getRuleBase()
+ {
+ return agent.getRuleBase();
+ }
+
+ public String getNewInstance()
+ {
+ return newInstance;
+ }
+
+ public void setNewInstance(String newInstance)
+ {
+ this.newInstance = newInstance;
+ }
+
+ public String getFiles()
+ {
+ return files;
+ }
+
+ public void setFiles(String files)
+ {
+ this.files = files;
+ }
+
+ public String getUrl()
+ {
+ return url;
+ }
+
+ public void setUrl(String url)
+ {
+ this.url = url;
+ }
+
+ public String getLocalCacheDir()
+ {
+ return localCacheDir;
+ }
+
+ public void setLocalCacheDir(String localCacheDir)
+ {
+ this.localCacheDir = localCacheDir;
+ }
+
+ public String getPoll()
+ {
+ return poll;
+ }
+
+ public void setPoll(String poll)
+ {
+ this.poll = poll;
+ }
+
+ public String getConfigName()
+ {
+ return configName;
+ }
+
+ public void setConfigName(String name)
+ {
+ this.configName = name;
+ }
+
+ public String getConfigurationFile()
+ {
+ return configurationFile;
+ }
+
+ public void setConfigurationFile(String brmsConfig)
+ {
+ this.configurationFile = brmsConfig;
+ }
+
+}
Added: modules/trunk/drools/src/main/java/org/jboss/seam/drools/RuleBase.java
===================================================================
--- modules/trunk/drools/src/main/java/org/jboss/seam/drools/RuleBase.java (rev 0)
+++ modules/trunk/drools/src/main/java/org/jboss/seam/drools/RuleBase.java 2009-04-24 23:25:43 UTC (rev 10633)
@@ -0,0 +1,116 @@
+package org.jboss.seam.drools;
+
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+
+import org.drools.RuleBaseFactory;
+import org.drools.compiler.DroolsError;
+import org.drools.compiler.PackageBuilder;
+import org.drools.compiler.PackageBuilderConfiguration;
+import org.drools.compiler.RuleError;
+import org.jboss.seam.ScopeType;
+import org.jboss.seam.annotations.Create;
+import org.jboss.seam.annotations.Scope;
+import org.jboss.seam.annotations.Unwrap;
+import org.jboss.seam.annotations.intercept.BypassInterceptors;
+import org.jboss.seam.core.ResourceLoader;
+import org.jboss.seam.log.LogProvider;
+import org.jboss.seam.log.Logging;
+
+/**
+ * Manager component for a Drools RuleBase
+ *
+ * @author Gavin King
+ *
+ */
+(a)Scope(ScopeType.APPLICATION)
+@BypassInterceptors
+public class RuleBase
+{
+ private static final LogProvider log = Logging.getLogProvider(RuleBase.class);
+
+ private String[] ruleFiles;
+ private String dslFile;
+ private org.drools.RuleBase ruleBase;
+
+ @Create
+ public void compileRuleBase() throws Exception
+ {
+ PackageBuilderConfiguration conf = new PackageBuilderConfiguration();
+ PackageBuilder builder = new PackageBuilder(conf);
+
+ if (ruleFiles!=null)
+ {
+ for (String ruleFile: ruleFiles)
+ {
+ log.info("parsing rules: " + ruleFile);
+ InputStream stream = ResourceLoader.instance().getResourceAsStream(ruleFile);
+ if (stream==null)
+ {
+ throw new IllegalStateException("could not locate rule file: " + ruleFile);
+ }
+ // read in the source
+ Reader drlReader = new InputStreamReader(stream);
+
+ if (dslFile==null)
+ {
+ builder.addPackageFromDrl(drlReader);
+ }
+ else
+ {
+ Reader dslReader = new InputStreamReader( ResourceLoader.instance().getResourceAsStream(dslFile) );
+ builder.addPackageFromDrl(drlReader, dslReader);
+ }
+
+ if ( builder.hasErrors() )
+ {
+ log.error("errors parsing rules in: " + ruleFile);
+ for ( DroolsError error: builder.getErrors().getErrors() )
+ {
+ if (error instanceof RuleError)
+ {
+ RuleError ruleError = (RuleError) error;
+ log.error( ruleError.getMessage() + " (" + ruleFile + ':' + ruleError.getLine() + ')' );
+ }
+ else
+ {
+ log.error( error.getMessage() + " (" + ruleFile + ')' );
+ }
+ }
+ }
+ }
+ }
+
+ // add the package to a rulebase
+ ruleBase = RuleBaseFactory.newRuleBase();
+ ruleBase.addPackage( builder.getPackage() );
+ }
+
+ @Unwrap
+ public org.drools.RuleBase getRuleBase()
+ {
+ return ruleBase;
+ }
+
+ public String[] getRuleFiles()
+ {
+ return ruleFiles;
+ }
+
+ public void setRuleFiles(String[] ruleFiles)
+ {
+ this.ruleFiles = ruleFiles;
+ }
+
+ public String getDslFile()
+ {
+ return dslFile;
+ }
+
+ public void setDslFile(String dslFile)
+ {
+ this.dslFile = dslFile;
+ }
+
+}
Added: modules/trunk/drools/src/main/java/org/jboss/seam/drools/SeamGlobalResolver.java
===================================================================
--- modules/trunk/drools/src/main/java/org/jboss/seam/drools/SeamGlobalResolver.java (rev 0)
+++ modules/trunk/drools/src/main/java/org/jboss/seam/drools/SeamGlobalResolver.java 2009-04-24 23:25:43 UTC (rev 10633)
@@ -0,0 +1,52 @@
+package org.jboss.seam.drools;
+
+import org.drools.spi.GlobalResolver;
+import org.jboss.seam.Component;
+import org.jboss.seam.contexts.Contexts;
+import org.jboss.seam.core.Init;
+
+/**
+ * Resolves Seam context variables as Drools globals
+ *
+ * @author Gavin King
+ *
+ */
+public class SeamGlobalResolver implements GlobalResolver
+{
+ private GlobalResolver delegate;
+
+ public SeamGlobalResolver(GlobalResolver delegate)
+ {
+ this.delegate = delegate;
+ }
+
+ public void setGlobal(String name, Object value)
+ {
+ //TODO: is this the right thing to do??
+ //or: Contexts.getConversationContext().set(name, value);
+ delegate.setGlobal(name, value);
+ }
+
+ public Object resolveGlobal(String name)
+ {
+ if ( !Contexts.isApplicationContextActive() )
+ {
+ return delegate.resolveGlobal(name);
+ }
+ else
+ {
+ Object instance = Component.getInstance(name);
+ if (instance==null)
+ {
+ instance = delegate.resolveGlobal(name);
+ return instance==null ?
+ Init.instance().getRootNamespace().getChild(name) :
+ instance;
+ }
+ else
+ {
+ return instance;
+ }
+ }
+ }
+}
\ No newline at end of file
Added: modules/trunk/drools/src/main/java/org/jboss/seam/drools/package-info.java
===================================================================
--- modules/trunk/drools/src/main/java/org/jboss/seam/drools/package-info.java (rev 0)
+++ modules/trunk/drools/src/main/java/org/jboss/seam/drools/package-info.java 2009-04-24 23:25:43 UTC (rev 10633)
@@ -0,0 +1,7 @@
+/**
+ * Seam components for integrating Drools.
+ */
+@Namespace(value="http://jboss.com/products/seam/drools", prefix="org.jboss.seam.drools")
+package org.jboss.seam.drools;
+
+import org.jboss.seam.annotations.Namespace;
[View Less]
15 years, 10 months
Seam SVN: r10632 - modules/trunk/bpm.
by seam-commits@lists.jboss.org
Author: shane.bryzak(a)jboss.com
Date: 2009-04-24 19:24:42 -0400 (Fri, 24 Apr 2009)
New Revision: 10632
Modified:
modules/trunk/bpm/
Log:
ignores
Property changes on: modules/trunk/bpm
___________________________________________________________________
Name: svn:ignore
+ .classpath
.project
.settings
target
15 years, 10 months
Seam SVN: r10631 - in modules/trunk: bpm and 7 other directories.
by seam-commits@lists.jboss.org
Author: shane.bryzak(a)jboss.com
Date: 2009-04-24 19:24:14 -0400 (Fri, 24 Apr 2009)
New Revision: 10631
Added:
modules/trunk/bpm/
modules/trunk/bpm/pom.xml
modules/trunk/bpm/src/
modules/trunk/bpm/src/main/
modules/trunk/bpm/src/main/java/
modules/trunk/bpm/src/main/java/org/
modules/trunk/bpm/src/main/java/org/jboss/
modules/trunk/bpm/src/main/java/org/jboss/seam/
modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/
modules/trunk/bpm/src/main/java/org/jboss/seam/…
[View More]bpm/Actor.java
modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/BusinessProcess.java
modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/BusinessProcessInterceptor.java
modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/Jbpm.java
modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/JbpmELResolver.java
modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/ManagedJbpmContext.java
modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/PageflowDeploymentHandler.java
modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/PageflowParser.java
modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/PooledTask.java
modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/PooledTaskInstanceList.java
modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/ProcessInstance.java
modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/ProcessInstanceFinder.java
modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/SeamExpressionEvaluator.java
modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/SeamUserCodeInterceptor.java
modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/TaskInstance.java
modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/TaskInstanceList.java
modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/TaskInstanceListForType.java
modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/TaskInstancePriorityList.java
modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/Transition.java
modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/jbpm.pageflow.cfg.xml
modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/package-info.java
Log:
initial import of bpm module
Added: modules/trunk/bpm/pom.xml
===================================================================
--- modules/trunk/bpm/pom.xml (rev 0)
+++ modules/trunk/bpm/pom.xml 2009-04-24 23:24:14 UTC (rev 10631)
@@ -0,0 +1,32 @@
+<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">
+ <parent>
+ <artifactId>seam-parent</artifactId>
+ <groupId>org.jboss.seam</groupId>
+ <version>3.0.0-SNAPSHOT</version>
+ </parent>
+
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.jboss.seam</groupId>
+ <artifactId>seam-bpm</artifactId>
+ <packaging>jar</packaging>
+ <version>3.0.0-SNAPSHOT</version>
+ <name>Seam BPM</name>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.jboss.webbeans</groupId>
+ <artifactId>jsr299-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.jboss.webbeans</groupId>
+ <artifactId>webbeans-logging</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.jbpm</groupId>
+ <artifactId>jbpm-jpdl</artifactId>
+ </dependency>
+ </dependencies>
+
+</project>
Added: modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/Actor.java
===================================================================
--- modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/Actor.java (rev 0)
+++ modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/Actor.java 2009-04-24 23:24:14 UTC (rev 10631)
@@ -0,0 +1,105 @@
+package org.jboss.seam.bpm;
+
+import java.io.Serializable;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+
+import javax.annotation.Named;
+import javax.context.SessionScoped;
+
+/**
+ * Allows the application to specify the jBPM actorId
+ * during the login cycle.
+ *
+ * @author Gavin King
+ */
+@Named
+@SessionScoped
+public class Actor extends AbstractMutable implements Serializable
+{
+ private static final long serialVersionUID = -6515302276074415520L;
+ private String id;
+ private Set<String> groupActorIds = new HashSet<String>()
+ {
+ @Override
+ public boolean add(String o)
+ {
+ boolean dirty = super.add(o);
+ if (dirty) setDirty();
+ return dirty;
+ }
+
+ @Override
+ public void clear()
+ {
+ if (size() > 0) setDirty();
+ super.clear();
+ }
+
+ @Override
+ public boolean remove(Object o)
+ {
+ boolean dirty = super.remove(o);
+ if (dirty) setDirty();
+ return dirty;
+ }
+
+ @Override
+ public Iterator<String> iterator()
+ {
+ final Iterator<String> it = super.iterator();
+ return new Iterator<String>()
+ {
+
+ public boolean hasNext()
+ {
+ return it.hasNext();
+ }
+
+ public String next()
+ {
+ return it.next();
+ }
+
+ public void remove()
+ {
+ setDirty();
+ it.remove();
+ }
+
+ };
+ }
+ };
+
+ public String getId()
+ {
+ return id;
+ }
+ public void setId(String id)
+ {
+ setDirty(this.id, id);
+ this.id = id;
+ }
+
+ public Set<String> getGroupActorIds()
+ {
+ return groupActorIds;
+ }
+ public static Actor instance()
+ {
+ if ( !Contexts.isSessionContextActive() )
+ {
+ throw new IllegalStateException("No active session context");
+ }
+ return (Actor) Component.getInstance(Actor.class);
+ }
+
+ @Override
+ public String toString()
+ {
+ return "Actor(" + id + ")";
+ }
+}
+
+
\ No newline at end of file
Added: modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/BusinessProcess.java
===================================================================
--- modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/BusinessProcess.java (rev 0)
+++ modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/BusinessProcess.java 2009-04-24 23:24:14 UTC (rev 10631)
@@ -0,0 +1,421 @@
+package org.jboss.seam.bpm;
+
+import java.io.Serializable;
+
+import javax.annotation.Named;
+import javax.context.ConversationScoped;
+
+import org.jboss.seam.international.StatusMessage;
+import org.jboss.seam.international.StatusMessages;
+import org.jbpm.graph.def.ProcessDefinition;
+import org.jbpm.graph.exe.ProcessInstance;
+import org.jbpm.taskmgmt.exe.TaskInstance;
+
+/**
+ * Holds the task and process ids for the current conversation,
+ * and provides programmatic control over the business process.
+ *
+ * @author Gavin King
+ *
+ */
+@Named
+@ConversationScoped
+public class BusinessProcess extends AbstractMutable implements Serializable
+{
+ private static final long serialVersionUID = 4722350870845851070L;
+
+ private Long processId;
+ private Long taskId;
+
+ public static BusinessProcess instance()
+ {
+ if ( !Contexts.isConversationContextActive() )
+ {
+ throw new IllegalStateException("No active conversation context");
+ }
+ return (BusinessProcess) Component.getInstance(BusinessProcess.class, ScopeType.CONVERSATION);
+ }
+
+ /**
+ * Is there a process instance associated with
+ * the current conversation?
+ */
+ public boolean hasCurrentProcess()
+ {
+ return processId!=null;
+ }
+
+ /**
+ * Is there a process instance that has not ended
+ * associated with the current conversation?
+ */
+ public boolean hasActiveProcess()
+ {
+ return hasCurrentProcess() &&
+ !org.jboss.seam.bpm.ProcessInstance.instance().hasEnded();
+ }
+
+ /**
+ * Is there a task instance associated with
+ * the current conversation?
+ */
+ public boolean hasCurrentTask()
+ {
+ return taskId!=null;
+ }
+
+ /**
+ * The jBPM process instance id associated with
+ * the current conversation.
+ */
+ public Long getProcessId()
+ {
+ return processId;
+ }
+
+ /**
+ * Set the process instance id, without validating
+ * that the process instance actually exists.
+ */
+ public void setProcessId(Long processId)
+ {
+ setDirty(this.processId, processId);
+ this.processId = processId;
+ }
+
+ /**
+ * The jBPM task instance id associated with
+ * the current conversation.
+ */
+ public Long getTaskId()
+ {
+ return taskId;
+ }
+
+ /**
+ * Set the task instance id, without validating
+ * that the task instance actually exists.
+ */
+ public void setTaskId(Long taskId)
+ {
+ setDirty(this.taskId, taskId);
+ this.taskId = taskId;
+ }
+
+ /**
+ * Create a process instance and associate it with the
+ * current conversation.
+ *
+ * @param processDefinitionName the jBPM process definition name
+ */
+ public void createProcess(String processDefinitionName)
+ {
+ createProcess(processDefinitionName, true);
+ }
+
+ /**
+ * Create a process instance and associate it with the
+ * current conversation.
+ *
+ * @param processDefinitionName the jBPM process definition name
+ */
+ public void createProcess(String processDefinitionName, boolean shouldSignalProcess)
+ {
+ ProcessInstance process = ManagedJbpmContext.instance().newProcessInstanceForUpdate(processDefinitionName);
+ afterCreateProcess(processDefinitionName, process, shouldSignalProcess);
+ }
+
+ /**
+ * Create a process instance and associate it with the
+ * current conversation.
+ *
+ * @param processDefinitionName the jBPM process definition name
+ * @param businessKey the business key of the new process definition
+ */
+ public void createProcess(String processDefinitionName, String businessKey)
+ {
+ /*ProcessInstance process = ManagedJbpmContext.instance().getGraphSession()
+ .findLatestProcessDefinition(processDefinitionName)
+ .createProcessInstance(Collections.EMPTY_MAP, businessKey);*/
+ ProcessInstance process = ManagedJbpmContext.instance().newProcessInstanceForUpdate(processDefinitionName);
+ process.setKey(businessKey);
+ afterCreateProcess(processDefinitionName, process, true);
+ }
+
+ private void afterCreateProcess(String processDefinitionName, ProcessInstance process, boolean shouldSignalProcess)
+ {
+ setProcessId( process.getId() );
+ // need to set process variables before the signal
+ Contexts.getBusinessProcessContext().flush();
+ if (shouldSignalProcess) {
+ process.signal();
+ }
+
+ Events.instance().raiseEvent("org.jboss.seam.createProcess." + processDefinitionName);
+ }
+
+ /**
+ * Start the current task, using the current actor id
+ *
+ * @see Actor
+ */
+ public void startTask()
+ {
+ String actorId = Actor.instance().getId();
+ TaskInstance task = org.jboss.seam.bpm.TaskInstance.instance();
+ if ( actorId != null )
+ {
+ task.start(actorId);
+ }
+ else
+ {
+ task.start();
+ }
+
+ Events.instance().raiseEvent("org.jboss.seam.startTask." + task.getTask().getName());
+ }
+
+ /**
+ * End the current task, via the given transition. If no transition name
+ * is given, check the Transition component for a transition, or use the
+ * default transition.
+ *
+ * @param transitionName the jBPM transition name, or null
+ */
+ public void endTask(String transitionName)
+ {
+ TaskInstance task = org.jboss.seam.bpm.TaskInstance.instance();
+ if (task==null)
+ {
+ throw new IllegalStateException( "no task instance associated with context" );
+ }
+
+ if ( transitionName==null || "".equals(transitionName) )
+ {
+ transitionName = Transition.instance().getName();
+ }
+
+ if (transitionName==null)
+ {
+ task.end();
+ }
+ else
+ {
+ task.end(transitionName);
+ }
+
+ setTaskId(null); //TODO: do I really need this???!
+
+ Events.instance().raiseEvent("org.jboss.seam.endTask." + task.getTask().getName());
+ ProcessInstance process = org.jboss.seam.bpm.ProcessInstance.instance();
+ if ( process.hasEnded() )
+ {
+ Events.instance().raiseEvent("org.jboss.seam.endProcess." + process.getProcessDefinition().getName());
+ }
+ }
+
+ /**
+ * Signal the given transition for the current process instance.
+ *
+ * @param transitionName the jBPM transition name
+ */
+ public void transition(String transitionName)
+ {
+ ProcessInstance process = org.jboss.seam.bpm.ProcessInstance.instance();
+ process.signal(transitionName);
+ if ( process.hasEnded() )
+ {
+ Events.instance().raiseEvent("org.jboss.seam.endProcess." + process.getProcessDefinition().getName());
+ }
+ }
+
+ /**
+ * Associate the task instance with the given id with the current
+ * conversation.
+ *
+ * @param taskId the jBPM task instance id
+ * @return true if the task was found and was not ended
+ */
+ public boolean resumeTask(Long taskId)
+ {
+ setTaskId(taskId);
+ TaskInstance task = org.jboss.seam.bpm.TaskInstance.instance();
+ if (task==null)
+ {
+ taskNotFound(taskId);
+ return false;
+ }
+ else if ( task.hasEnded() )
+ {
+ taskEnded(taskId);
+ return false;
+ }
+ else
+ {
+ setProcessId( task.getTaskMgmtInstance().getProcessInstance().getId() );
+ Events.instance().raiseEvent("org.jboss.seam.initTask." + task.getTask().getName());
+ return true;
+ }
+ }
+
+ /**
+ * Associate the process instance with the given id with the
+ * current conversation.
+ *
+ * @param processId the jBPM process instance id
+ * @return true if the process was found and was not ended
+ */
+ public boolean resumeProcess(Long processId)
+ {
+ setProcessId(processId);
+ ProcessInstance process = org.jboss.seam.bpm.ProcessInstance.instance();
+ return afterResumeProcess(processId, process);
+ }
+
+ /**
+ * Associate the process instance with the given business key
+ * with the current conversation.
+ *
+ * @param processDefinition the jBPM process definition name
+ * @param key the jBPM process instance key
+ * @return true if the process was found and was not ended
+ */
+ public boolean resumeProcess(String processDefinition, String key)
+ {
+ ProcessDefinition definition = ManagedJbpmContext.instance().getGraphSession().findLatestProcessDefinition(processDefinition);
+ ProcessInstance process = definition==null ?
+ null : ManagedJbpmContext.instance().getProcessInstanceForUpdate(definition, key);
+ if (process!=null) setProcessId( process.getId() );
+ return afterResumeProcess(key, process);
+ }
+
+ private boolean afterResumeProcess(long processId, ProcessInstance process)
+ {
+ if ( process==null )
+ {
+ processNotFound(processId);
+ return false;
+ }
+ else if ( process.hasEnded() )
+ {
+ processEnded(processId);
+ return false;
+ }
+ else
+ {
+ Events.instance().raiseEvent("org.jboss.seam.initProcess." + process.getProcessDefinition().getName());
+ return true;
+ }
+ }
+
+ private boolean afterResumeProcess(String processKey, ProcessInstance process)
+ {
+ if ( process==null )
+ {
+ processNotFound(processKey);
+ return false;
+ }
+ else if ( process.hasEnded() )
+ {
+ processEnded(processKey);
+ return false;
+ }
+ else
+ {
+ Events.instance().raiseEvent("org.jboss.seam.initProcess." + process.getProcessDefinition().getName());
+ return true;
+ }
+ }
+
+ /**
+ * Check that the task currently associated with the conversation
+ * exists and has not ended.
+ *
+ * @return true if the task exists and was not ended
+ */
+ public boolean validateTask()
+ {
+ if ( !hasCurrentTask() )
+ {
+ taskNotFound(taskId);
+ return false;
+ }
+ else if ( org.jboss.seam.bpm.TaskInstance.instance().hasEnded() )
+ {
+ taskEnded(taskId);
+ return false;
+ }
+ else
+ {
+ return true;
+ }
+ }
+
+ protected void taskNotFound(Long taskId)
+ {
+ StatusMessages.instance().addFromResourceBundleOrDefault(
+ StatusMessage.Severity.WARN,
+ "org.jboss.seam.TaskNotFound",
+ "Task #0 not found",
+ taskId
+ );
+ }
+
+ protected void taskEnded(Long taskId)
+ {
+ StatusMessages.instance().addFromResourceBundleOrDefault(
+ StatusMessage.Severity.WARN,
+ "org.jboss.seam.TaskEnded",
+ "Task #0 already ended",
+ taskId
+ );
+ }
+
+ protected void processEnded(Long processId)
+ {
+ StatusMessages.instance().addFromResourceBundleOrDefault(
+ StatusMessage.Severity.WARN,
+ "org.jboss.seam.ProcessEnded",
+ "Process #0 already ended",
+ processId
+ );
+ }
+
+ protected void processNotFound(Long processId)
+ {
+ StatusMessages.instance().addFromResourceBundleOrDefault(
+ StatusMessage.Severity.WARN,
+ "org.jboss.seam.ProcessNotFound",
+ "Process #0 not found",
+ processId
+ );
+ }
+
+ protected void processEnded(String key)
+ {
+ StatusMessages.instance().addFromResourceBundleOrDefault(
+ StatusMessage.Severity.WARN,
+ "org.jboss.seam.ProcessEnded",
+ "Process #0 already ended",
+ key
+ );
+ }
+
+ protected void processNotFound(String key)
+ {
+ StatusMessages.instance().addFromResourceBundleOrDefault(
+ StatusMessage.Severity.WARN,
+ "org.jboss.seam.ProcessNotFound",
+ "Process #0 not found",
+ key
+ );
+ }
+
+
+ @Override
+ public String toString()
+ {
+ return "BusinessProcess(processId=" + processId + ",taskId=" + taskId + ")";
+ }
+
+}
Added: modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/BusinessProcessInterceptor.java
===================================================================
--- modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/BusinessProcessInterceptor.java (rev 0)
+++ modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/BusinessProcessInterceptor.java 2009-04-24 23:24:14 UTC (rev 10631)
@@ -0,0 +1,182 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Distributable under LGPL license.
+ * See terms of license at gnu.org.
+ */
+package org.jboss.seam.bpm;
+
+import java.lang.reflect.Method;
+
+import org.jboss.seam.annotations.bpm.BeginTask;
+import org.jboss.seam.annotations.bpm.CreateProcess;
+import org.jboss.seam.annotations.bpm.EndTask;
+import org.jboss.seam.annotations.bpm.ResumeProcess;
+import org.jboss.seam.annotations.bpm.StartTask;
+import org.jboss.seam.annotations.intercept.AroundInvoke;
+import org.jboss.seam.annotations.intercept.Interceptor;
+import org.jboss.seam.contexts.Contexts;
+import org.jboss.seam.core.BijectionInterceptor;
+import org.jboss.seam.core.Expressions;
+import org.jboss.seam.core.Init;
+import org.jboss.seam.intercept.AbstractInterceptor;
+import org.jboss.seam.intercept.InvocationContext;
+import org.jboss.seam.log.LogProvider;
+import org.jboss.seam.log.Logging;
+import org.jboss.seam.util.Strings;
+import org.jboss.seam.web.Parameters;
+
+/**
+ * Implements annotation-based business-process demarcation.
+ *
+ * @author <a href="mailto:steve@hibernate.org">Steve Ebersole</a>
+ * @author Gavin King
+ */
+@Interceptor(stateless=true, around=BijectionInterceptor.class)
+public class BusinessProcessInterceptor extends AbstractInterceptor
+{
+ private static final long serialVersionUID = 758197867958840918L;
+
+ private static final LogProvider log = Logging.getLogProvider( BusinessProcessInterceptor.class );
+
+ @AroundInvoke
+ public Object aroundInvoke(InvocationContext invocation) throws Exception
+ {
+ if ( !beforeInvocation(invocation) )
+ {
+ return null;
+ }
+ else
+ {
+ return afterInvocation( invocation, invocation.proceed() );
+ }
+ }
+
+ private boolean beforeInvocation(InvocationContext invocationContext)
+ {
+ Method method = invocationContext.getMethod();
+ if ( method.isAnnotationPresent(StartTask.class) )
+ {
+ log.trace( "encountered @StartTask" );
+ StartTask tag = method.getAnnotation(StartTask.class);
+ Long taskId = getProcessOrTaskId( tag.taskIdParameter(), tag.taskId() );
+ return BusinessProcess.instance().resumeTask(taskId);
+ }
+ else if ( method.isAnnotationPresent(BeginTask.class) )
+ {
+ log.trace( "encountered @BeginTask" );
+ BeginTask tag = method.getAnnotation(BeginTask.class);
+ Long taskId = getProcessOrTaskId( tag.taskIdParameter(), tag.taskId() );
+ return BusinessProcess.instance().resumeTask(taskId);
+ }
+ else if ( method.isAnnotationPresent(ResumeProcess.class) )
+ {
+ log.trace( "encountered @ResumeProcess" );
+ ResumeProcess tag = method.getAnnotation(ResumeProcess.class);
+ if ( tag.processKey().equals("") )
+ {
+ Long processId = getProcessOrTaskId( tag.processIdParameter(), tag.processId() );
+ return BusinessProcess.instance().resumeProcess(processId);
+ }
+ else
+ {
+ return BusinessProcess.instance().resumeProcess( tag.definition(), getProcessKey( tag.processKey() ) );
+ }
+ }
+ if ( method.isAnnotationPresent(EndTask.class) )
+ {
+ log.trace( "encountered @EndTask" );
+ return BusinessProcess.instance().validateTask();
+ }
+ else
+ {
+ return true;
+ }
+ }
+
+ private Object afterInvocation(InvocationContext invocation, Object result)
+ {
+ Method method = invocation.getMethod();
+ if ( result!=null || method.getReturnType().equals(void.class) ) //interpreted as "redisplay"
+ {
+ if ( method.isAnnotationPresent(CreateProcess.class) )
+ {
+ log.trace( "encountered @CreateProcess" );
+ CreateProcess tag = method.getAnnotation(CreateProcess.class);
+ if ( tag.processKey().equals("") )
+ {
+ BusinessProcess.instance().createProcess( tag.definition() );
+ }
+ else
+ {
+ BusinessProcess.instance().createProcess( tag.definition(), getProcessKey( tag.processKey() ) );
+ }
+ }
+ if ( method.isAnnotationPresent(StartTask.class) )
+ {
+ log.trace( "encountered @StartTask" );
+ BusinessProcess.instance().startTask();
+ }
+ if ( method.isAnnotationPresent(EndTask.class) )
+ {
+ log.trace( "encountered @EndTask" );
+ BusinessProcess.instance().endTask( method.getAnnotation(EndTask.class).transition() );
+ }
+ if ( method.isAnnotationPresent(org.jboss.seam.annotations.bpm.Transition.class) )
+ {
+ log.trace( "encountered @Transition" );
+ String transitionName = method.getAnnotation(org.jboss.seam.annotations.bpm.Transition.class).value();
+ if ( "".equals(transitionName) ) transitionName = method.getName();
+ BusinessProcess.instance().transition(transitionName);
+ }
+ }
+ return result;
+ }
+
+ private String getProcessKey(String el)
+ {
+ Object key = Expressions.instance().createValueExpression(el).getValue();
+ if (key==null)
+ {
+ throw new IllegalStateException("process business key may not be null");
+ }
+ return key.toString();
+ }
+
+ private Long getProcessOrTaskId(String paramName, String el)
+ {
+ Object id;
+ if ( Strings.isEmpty(paramName) )
+ {
+ id = Expressions.instance().createValueExpression(el).getValue();
+ }
+ else
+ {
+ String[] values = Parameters.instance().getRequestParameters().get(paramName);
+ id = values!=null && values.length==1 ? values[0] : null;
+ }
+
+ if (id==null)
+ {
+ throw new IllegalStateException("task/process id may not be null");
+ }
+ else if (id instanceof Long)
+ {
+ return (Long) id;
+ }
+ else if (id instanceof String)
+ {
+ return new Long( (String) id );
+ }
+ else
+ {
+ throw new IllegalArgumentException("task/process id must be a string or long");
+ }
+ }
+
+ public boolean isInterceptorEnabled()
+ {
+ return Contexts.isApplicationContextActive() && Init.instance().isJbpmInstalled();
+ }
+
+}
Added: modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/Jbpm.java
===================================================================
--- modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/Jbpm.java (rev 0)
+++ modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/Jbpm.java 2009-04-24 23:24:14 UTC (rev 10631)
@@ -0,0 +1,367 @@
+package org.jboss.seam.bpm;
+
+import java.io.InputStream;
+import java.io.StringReader;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.LinkedHashSet;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+
+import javax.annotation.Named;
+import javax.context.ApplicationScoped;
+import javax.inject.Initializer;
+import javax.naming.NamingException;
+
+import org.dom4j.Element;
+import org.hibernate.HibernateException;
+import org.hibernate.cfg.Environment;
+import org.hibernate.lob.ReaderInputStream;
+import org.jboss.seam.contexts.Contexts;
+import org.jboss.seam.core.Init;
+import org.jboss.seam.core.ResourceLoader;
+import org.jboss.seam.deployment.DeploymentStrategy;
+import org.jboss.seam.deployment.FileDescriptor;
+import org.jboss.seam.deployment.StandardDeploymentStrategy;
+import org.jboss.webbeans.log.LogProvider;
+import org.jboss.webbeans.log.Logging;
+import org.jboss.seam.util.Naming;
+import org.jboss.seam.util.Resources;
+import org.jbpm.JbpmConfiguration;
+import org.jbpm.JbpmContext;
+import org.jbpm.graph.def.ProcessDefinition;
+import org.jbpm.graph.node.DbSubProcessResolver;
+import org.jbpm.graph.node.ProcessState;
+import org.jbpm.graph.node.SubProcessResolver;
+import org.jbpm.instantiation.UserCodeInterceptorConfig;
+import org.jbpm.jpdl.JpdlException;
+import org.jbpm.jpdl.el.impl.JbpmExpressionEvaluator;
+import org.jbpm.persistence.db.DbPersistenceServiceFactory;
+import org.xml.sax.InputSource;
+
+/**
+ * A seam component that boostraps a JBPM SessionFactory
+ *
+ * @author Gavin King
+ * @author <a href="mailto:steve@hibernate.org">Steve Ebersole</a>
+ * @author Norman Richards
+ * @author <a href="mailto:theute@jboss.org">Thomas Heute</a>
+ */
+@Named
+@ApplicationScoped
+public class Jbpm
+{
+ private static final LogProvider log = Logging.getLogProvider(Jbpm.class);
+
+ private JbpmConfiguration jbpmConfiguration;
+ private String jbpmConfigurationJndiName;
+ private String[] processDefinitions;
+ private String[] pageflowDefinitions;
+ private Map<String, ProcessDefinition> pageflowProcessDefinitions = new HashMap<String, ProcessDefinition>();
+
+ @Initializer
+ public void startup() throws Exception
+ {
+ log.trace( "Starting jBPM" );
+ ProcessState.setDefaultSubProcessResolver( new SeamSubProcessResolver() );
+ installProcessDefinitions();
+ installPageflowDefinitions();
+ //JbpmExpressionEvaluator.setVariableResolver( new SeamVariableResolver() );
+ //JbpmExpressionEvaluator.setFunctionMapper( new SeamFunctionMapper() );
+ JbpmExpressionEvaluator.setExpressionEvaluator( new SeamExpressionEvaluator() );
+ UserCodeInterceptorConfig.setUserCodeInterceptor( new SeamUserCodeInterceptor() );
+ }
+
+ @Destroy
+ public void shutdown()
+ {
+ if (jbpmConfiguration!=null)
+ {
+ jbpmConfiguration.close();
+ }
+ }
+
+ public JbpmConfiguration getJbpmConfiguration()
+ {
+ if (jbpmConfiguration==null)
+ {
+ initJbpmConfiguration();
+ }
+ return jbpmConfiguration;
+ }
+
+ private void initJbpmConfiguration()
+ {
+ if (jbpmConfigurationJndiName==null)
+ {
+ jbpmConfiguration = JbpmConfiguration.getInstance();
+ }
+ else
+ {
+ try
+ {
+ jbpmConfiguration = (JbpmConfiguration) Naming.getInitialContext().lookup(jbpmConfigurationJndiName);
+ }
+ catch (NamingException ne)
+ {
+ throw new IllegalArgumentException("JbpmConfiguration not found in JNDI", ne);
+ }
+ }
+
+ DbPersistenceServiceFactory dbpsf = (DbPersistenceServiceFactory) jbpmConfiguration.getServiceFactory("persistence");
+ if (Naming.getInitialContextProperties()!=null)
+ {
+ // Prefix regular JNDI properties for Hibernate
+ Hashtable<String, String> hash = Naming.getInitialContextProperties();
+ Properties prefixed = new Properties();
+ for (Map.Entry<String, String> entry: hash.entrySet() )
+ {
+ prefixed.setProperty( Environment.JNDI_PREFIX + "." + entry.getKey(), entry.getValue() );
+ }
+
+ try
+ {
+ dbpsf.getConfiguration().getProperties().putAll(prefixed);
+ }
+ catch (HibernateException he)
+ {
+ log.info("could not set JNDI properties for jBPM persistence: " + he.getMessage());
+ }
+ }
+ }
+
+ public ProcessDefinition getPageflowProcessDefinition(String pageflowName)
+ {
+ return pageflowProcessDefinitions.get(pageflowName);
+ }
+
+ public boolean isPageflowProcessDefinition(String pageflowName)
+ {
+ return pageflowProcessDefinitions.containsKey(pageflowName);
+ }
+
+ public static ProcessDefinition getPageflowDefinitionFromResource(String resourceName)
+ {
+ InputStream resource = ResourceLoader.instance().getResourceAsStream(resourceName);
+ if (resource==null)
+ {
+ throw new IllegalArgumentException("pageflow resource not found: " + resourceName);
+ }
+ try
+ {
+ return Jbpm.parseInputSource( new InputSource(resource) );
+ }
+ catch (JpdlException e)
+ {
+ throw new JpdlException("Unable to parse process definition " + resourceName, e);
+ } finally {
+ Resources.closeStream(resource);
+ }
+ }
+
+ public ProcessDefinition getProcessDefinitionFromResource(String resourceName)
+ {
+ InputStream resource = ResourceLoader.instance().getResourceAsStream(resourceName);
+ if (resource==null)
+ {
+ throw new IllegalArgumentException("process definition resource not found: " + resourceName);
+ }
+
+ try {
+ return ProcessDefinition.parseXmlInputStream(resource);
+ } finally {
+ Resources.closeStream(resource);
+ }
+ }
+
+ public String[] getPageflowDefinitions()
+ {
+ return pageflowDefinitions;
+ }
+
+ public void setPageflowDefinitions(String[] pageflowDefinitions)
+ {
+ this.pageflowDefinitions = pageflowDefinitions;
+ }
+
+ public String[] getProcessDefinitions()
+ {
+ return processDefinitions;
+ }
+
+ public void setProcessDefinitions(String[] processDefinitions)
+ {
+ this.processDefinitions = processDefinitions;
+ }
+
+ /**
+ * Dynamically deploy a page flow definition, if a pageflow with an
+ * identical name already exists, the pageflow is updated.
+ *
+ * @return true if the pageflow definition has been updated
+ */
+ public boolean deployPageflowDefinition(ProcessDefinition pageflowDefinition)
+ {
+ return pageflowProcessDefinitions.put( pageflowDefinition.getName(), pageflowDefinition )!=null;
+ }
+
+ /**
+ * Read a pageflow definition
+ *
+ * @param pageflowDefinition the pageflow as an XML string
+ */
+ public ProcessDefinition getPageflowDefinitionFromXml(String pageflowDefinition)
+ {
+ InputStream stream = null;
+ try {
+ stream = new ReaderInputStream(new StringReader(pageflowDefinition));
+ return Jbpm.parseInputSource(new InputSource(stream));
+ } finally {
+ Resources.closeStream(stream);
+ }
+ }
+
+ /**
+ * Read a process definition
+ *
+ * @param processDefinition the process as an XML string
+ */
+ public ProcessDefinition getProcessDefinitionFromXml(String processDefinition)
+ {
+ InputStream stream = null;
+ try {
+ stream = new ReaderInputStream(new StringReader(processDefinition));
+ return ProcessDefinition.parseXmlInputStream(stream);
+ } finally {
+ Resources.closeStream(stream);
+ }
+ }
+
+ /**
+ * Remove a pageflow definition
+ *
+ * @param pageflowName Name of the pageflow to remove
+ * @return true if the pageflow definition has been removed
+ */
+ public boolean undeployPageflowDefinition(String pageflowName)
+ {
+ return pageflowProcessDefinitions.remove(pageflowName)!=null;
+ }
+
+ private void installPageflowDefinitions() {
+ Set<String> mergedPageflowDefinitions = new LinkedHashSet<String>();
+ if ( pageflowDefinitions!=null )
+ {
+ mergedPageflowDefinitions.addAll(Arrays.asList(pageflowDefinitions));
+ }
+
+ for (FileDescriptor fileDescriptor : ((PageflowDeploymentHandler) ((DeploymentStrategy) Contexts.getEventContext().get(StandardDeploymentStrategy.NAME)).getDeploymentHandlers().get(PageflowDeploymentHandler.NAME)).getResources())
+ {
+ mergedPageflowDefinitions.add(fileDescriptor.getName());
+ }
+
+ for (String pageflow: mergedPageflowDefinitions)
+ {
+ ProcessDefinition pd = getPageflowDefinitionFromResource(pageflow);
+ pageflowProcessDefinitions.put( pd.getName(), pd );
+ }
+ }
+
+ private void installProcessDefinitions()
+ {
+ if ( isProcessDeploymentEnabled() )
+ {
+ JbpmContext jbpmContext = getJbpmConfiguration().createJbpmContext();
+ try
+ {
+ if (processDefinitions!=null)
+ {
+ for ( String definitionResource : processDefinitions )
+ {
+ deployProcess(jbpmContext, definitionResource);
+ }
+ }
+ }
+ catch (RuntimeException e)
+ {
+ throw new RuntimeException("could not deploy a process definition", e);
+ }
+ finally
+ {
+ jbpmContext.close();
+ }
+ }
+ }
+
+ private void deployProcess(JbpmContext jbpmContext, String definitionResource)
+ {
+ ProcessDefinition processDefinition = ProcessDefinition.parseXmlResource(definitionResource);
+ if (log.isDebugEnabled())
+ {
+ log.debug( "deploying process definition : " + processDefinition.getName() );
+ }
+ jbpmContext.deployProcessDefinition(processDefinition);
+ }
+
+ protected boolean isProcessDeploymentEnabled()
+ {
+ return processDefinitions!=null && processDefinitions.length>0;
+ }
+
+ public static Jbpm instance()
+ {
+ if ( !Contexts.isApplicationContextActive() )
+ {
+ throw new IllegalStateException("No application context active");
+ }
+ if ( !Init.instance().isJbpmInstalled() )
+ {
+ throw new IllegalStateException("jBPM support is not installed (use components.xml to install it)");
+ }
+ return (Jbpm) Component.getInstance(Jbpm.class, ScopeType.APPLICATION);
+ }
+
+ protected String getJbpmConfigurationJndiName()
+ {
+ return jbpmConfigurationJndiName;
+ }
+
+ protected void setJbpmConfigurationJndiName(String jbpmConfigurationJndiName)
+ {
+ this.jbpmConfigurationJndiName = jbpmConfigurationJndiName;
+ }
+
+ public static JbpmConfiguration pageflowConfiguration = JbpmConfiguration.parseResource("org/jboss/seam/bpm/jbpm.pageflow.cfg.xml");
+
+ public static JbpmContext createPageflowContext()
+ {
+ return pageflowConfiguration.createJbpmContext();
+ }
+
+ public static ProcessDefinition parseInputSource(InputSource inputSource)
+ {
+ JbpmContext jbpmContext = createPageflowContext();
+ try
+ {
+ return new PageflowParser(inputSource).readProcessDefinition();
+ }
+ finally
+ {
+ jbpmContext.close();
+ }
+ }
+
+ private static final DbSubProcessResolver DB_SUB_PROCESS_RESOLVER = new DbSubProcessResolver();
+ class SeamSubProcessResolver implements SubProcessResolver
+ {
+ public ProcessDefinition findSubProcess(Element element)
+ {
+ String subProcessName = element.attributeValue("name");
+ ProcessDefinition pageflow = pageflowProcessDefinitions.get(subProcessName);
+ return pageflow==null ? DB_SUB_PROCESS_RESOLVER.findSubProcess(element) : pageflow;
+ }
+ }
+
+}
Added: modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/JbpmELResolver.java
===================================================================
--- modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/JbpmELResolver.java (rev 0)
+++ modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/JbpmELResolver.java 2009-04-24 23:24:14 UTC (rev 10631)
@@ -0,0 +1,69 @@
+package org.jboss.seam.bpm;
+
+import java.beans.FeatureDescriptor;
+import java.util.Iterator;
+
+import javax.el.ELContext;
+import javax.el.ELResolver;
+
+import org.jbpm.jpdl.el.VariableResolver;
+
+/**
+ * Resolves jBPM variables for Unified EL
+ *
+ * @author Gavin King
+ *
+ */
+final class JbpmELResolver extends ELResolver
+{
+ private final VariableResolver resolver;
+
+ JbpmELResolver(VariableResolver resolver)
+ {
+ this.resolver = resolver;
+ }
+
+ @Override
+ public Object getValue(ELContext context, Object base, Object property)
+ {
+ if ( base==null && property!=null )
+ {
+ return resolver.resolveVariable( (String) base );
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ @Override
+ public boolean isReadOnly(ELContext context, Object base, Object property)
+ {
+ return true;
+ }
+
+ @Override
+ public Class<?> getCommonPropertyType(ELContext context, Object base)
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Iterator<FeatureDescriptor> getFeatureDescriptors(ELContext context, Object base)
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Class<?> getType(ELContext context, Object base, Object property)
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void setValue(ELContext context, Object base, Object property, Object value)
+ {
+ throw new UnsupportedOperationException();
+ }
+
+}
\ No newline at end of file
Added: modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/ManagedJbpmContext.java
===================================================================
--- modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/ManagedJbpmContext.java (rev 0)
+++ modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/ManagedJbpmContext.java 2009-04-24 23:24:14 UTC (rev 10631)
@@ -0,0 +1,168 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Distributable under LGPL license.
+ * See terms of license at gnu.org.
+ */
+package org.jboss.seam.bpm;
+
+import static org.jboss.seam.annotations.Install.BUILT_IN;
+
+import javax.naming.NamingException;
+import javax.transaction.RollbackException;
+import javax.transaction.Synchronization;
+import javax.transaction.SystemException;
+
+import org.jboss.seam.Component;
+import org.jboss.seam.ScopeType;
+import org.jboss.seam.annotations.Create;
+import org.jboss.seam.annotations.Destroy;
+import org.jboss.seam.annotations.Install;
+import org.jboss.seam.annotations.Name;
+import org.jboss.seam.annotations.Scope;
+import org.jboss.seam.annotations.Unwrap;
+import org.jboss.seam.annotations.intercept.BypassInterceptors;
+import org.jboss.seam.contexts.Contexts;
+import org.jboss.seam.contexts.Lifecycle;
+import org.jboss.seam.log.LogProvider;
+import org.jboss.seam.log.Logging;
+import org.jboss.seam.transaction.Transaction;
+import org.jboss.seam.transaction.UserTransaction;
+import org.jbpm.JbpmContext;
+import org.jbpm.persistence.db.DbPersistenceServiceFactory;
+import org.jbpm.svc.Services;
+
+/**
+ * Manages a reference to a JbpmContext.
+ *
+ * @author <a href="mailto:steve@hibernate.org">Steve Ebersole</a>
+ * @author Gavin King
+ */
+(a)Scope(ScopeType.EVENT)
+@Name("org.jboss.seam.bpm.jbpmContext")
+@BypassInterceptors
+@Install(precedence=BUILT_IN, dependencies="org.jboss.seam.bpm.jbpm")
+public class ManagedJbpmContext implements Synchronization
+{
+ private static final LogProvider log = Logging.getLogProvider(ManagedJbpmContext.class);
+
+ private JbpmContext jbpmContext;
+ private boolean synchronizationRegistered;
+
+ @Create
+ public void create() throws NamingException, RollbackException, SystemException
+ {
+ jbpmContext = Jbpm.instance().getJbpmConfiguration().createJbpmContext();
+ assertNoTransactionManagement();
+ log.debug( "created seam managed jBPM context");
+ }
+
+ private void assertNoTransactionManagement()
+ {
+ DbPersistenceServiceFactory dpsf = (DbPersistenceServiceFactory) jbpmContext.getJbpmConfiguration()
+ .getServiceFactory(Services.SERVICENAME_PERSISTENCE);
+ if ( dpsf.isTransactionEnabled() )
+ {
+ throw new IllegalStateException("jBPM transaction management is enabled, disable in jbpm.cfg.xml");
+ }
+ }
+
+ @Unwrap
+ public JbpmContext getJbpmContext() throws NamingException, RollbackException, SystemException
+ {
+ joinTransaction();
+ return jbpmContext;
+ }
+
+ private void joinTransaction() throws SystemException
+ {
+ UserTransaction transaction = Transaction.instance();
+
+ if ( !transaction.isActiveOrMarkedRollback() )
+ {
+ throw new IllegalStateException("JbpmContext may only be used inside a transaction");
+ }
+
+ if ( !synchronizationRegistered && !Lifecycle.isDestroying() && transaction.isActive() )
+ {
+ jbpmContext.getSession().isOpen();
+ try //TODO: what we really want here is if (!cmt)
+ {
+ transaction.registerSynchronization(this);
+ }
+ catch (UnsupportedOperationException uoe)
+ {
+ jbpmContext.getSession().getTransaction().registerSynchronization(this);
+ }
+ synchronizationRegistered = true;
+ }
+ }
+
+ public void beforeCompletion()
+ {
+ log.debug( "flushing seam managed jBPM context" );
+ /*org.jbpm.graph.exe.ProcessInstance processInstance = ProcessInstance.instance();
+ if (processInstance!=null)
+ {
+ jbpmContext.save(processInstance);
+ }*/
+ if ( Contexts.isBusinessProcessContextActive() )
+ {
+ //in requests that come through SeamPhaseListener,
+ //transactions are committed before the contexts are
+ //destroyed, flush here:
+ Contexts.getBusinessProcessContext().flush();
+ }
+ jbpmContext.getSession().flush();
+ log.debug( "done flushing seam managed jBPM context" );
+ }
+
+ public void afterCompletion(int status)
+ {
+ synchronizationRegistered = false;
+ if ( !Contexts.isEventContextActive() )
+ {
+ //in calls to MDBs and remote calls to SBs, the
+ //transaction doesn't commit until after contexts
+ //are destroyed, so wait until the transaction
+ //completes before closing the session
+ //on the other hand, if we still have an active
+ //event context, leave it open
+ closeContext();
+ }
+ }
+
+ @Destroy
+ public void destroy()
+ {
+ if ( !synchronizationRegistered )
+ {
+ //in requests that come through SeamPhaseListener,
+ //there can be multiple transactions per request,
+ //but they are all completed by the time contexts
+ //are dstroyed
+ //so wait until the end of the request to close
+ //the session
+ //on the other hand, if we are still waiting for
+ //the transaction to commit, leave it open
+ closeContext();
+ }
+ }
+
+ private void closeContext()
+ {
+ log.debug( "destroying seam managed jBPM context" );
+ jbpmContext.close();
+ log.debug( "done destroying seam managed jBPM context" );
+ }
+
+ public static JbpmContext instance()
+ {
+ if ( !Contexts.isEventContextActive() )
+ {
+ throw new IllegalStateException("no active event context");
+ }
+ return (JbpmContext) Component.getInstance(ManagedJbpmContext.class, ScopeType.EVENT);
+ }
+
+}
Added: modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/PageflowDeploymentHandler.java
===================================================================
--- modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/PageflowDeploymentHandler.java (rev 0)
+++ modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/PageflowDeploymentHandler.java 2009-04-24 23:24:14 UTC (rev 10631)
@@ -0,0 +1,81 @@
+package org.jboss.seam.bpm;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.dom4j.DocumentException;
+import org.dom4j.Element;
+import org.jboss.seam.deployment.AbstractDeploymentHandler;
+import org.jboss.seam.deployment.DeploymentMetadata;
+import org.jboss.seam.deployment.FileDescriptor;
+import org.jboss.seam.log.LogProvider;
+import org.jboss.seam.log.Logging;
+import org.jboss.seam.util.Resources;
+import org.jboss.seam.util.XML;
+
+
+public class PageflowDeploymentHandler extends AbstractDeploymentHandler
+{
+
+ private static DeploymentMetadata NAMESPACE_METADATA = new DeploymentMetadata()
+ {
+
+ public String getFileNameSuffix()
+ {
+ return ".jpdl.xml";
+ }
+
+ };
+
+ private static LogProvider log = Logging.getLogProvider(PageflowDeploymentHandler.class);
+
+ public static final String NAME = "org.jboss.seam.bpm.PageflowDeploymentHandler";
+
+ public String getName()
+ {
+ return NAME;
+ }
+
+ @Override
+ public void postProcess(ClassLoader classLoader)
+ {
+ Set<FileDescriptor> files = new HashSet<FileDescriptor>();
+ for (FileDescriptor fileDescriptor : getResources())
+ {
+ try
+ {
+ InputStream inputStream = fileDescriptor.getUrl().openStream();
+ try
+ {
+
+ Element root = XML.getRootElementSafely(inputStream);
+ if ("pageflow-definition".equals(root.getName()))
+ {
+ files.add(fileDescriptor);
+ }
+ }
+ catch (DocumentException e)
+ {
+ log.debug("Unable to parse " + fileDescriptor.getName(), e);
+ }
+ finally
+ {
+ Resources.closeStream(inputStream);
+ }
+ } catch (IOException e)
+ {
+ log.trace("Error loading " + fileDescriptor.getName());
+ }
+
+ }
+ setResources(files);
+ }
+
+ public DeploymentMetadata getMetadata()
+ {
+ return NAMESPACE_METADATA;
+ }
+
+}
Added: modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/PageflowParser.java
===================================================================
--- modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/PageflowParser.java (rev 0)
+++ modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/PageflowParser.java 2009-04-24 23:24:14 UTC (rev 10631)
@@ -0,0 +1,65 @@
+package org.jboss.seam.bpm;
+
+import java.io.Reader;
+
+import org.dom4j.Element;
+import org.jbpm.graph.def.Node;
+import org.jbpm.graph.def.NodeCollection;
+import org.jbpm.jpdl.xml.JpdlXmlReader;
+import org.jbpm.jpdl.xml.ProblemListener;
+import org.xml.sax.InputSource;
+
+/**
+ * A jPDL parser for Seam pageflow definitions
+ *
+ * @author Tom Baeyens
+ *
+ */
+public class PageflowParser extends JpdlXmlReader
+{
+
+ private static final long serialVersionUID = 1L;
+
+ public PageflowParser(InputSource inputSource, ProblemListener problemListener)
+ {
+ super(inputSource, problemListener);
+ }
+
+ public PageflowParser(InputSource inputSource)
+ {
+ super(inputSource);
+ }
+
+ public PageflowParser(Reader reader)
+ {
+ super(reader);
+ }
+
+ @Override
+ public void readNodes(Element nodeCollectionElement, NodeCollection nodeCollection)
+ {
+ super.readNodes(nodeCollectionElement, nodeCollection);
+
+ if ( "pageflow-definition".equals( nodeCollectionElement.getName() ) )
+ {
+ String startPageName = nodeCollectionElement.attributeValue("start-page");
+ if (startPageName==null)
+ {
+ Element startPageElement = nodeCollectionElement.element("start-page");
+ if (startPageElement!=null)
+ {
+ startPageName = startPageElement.attributeValue("name");
+ }
+ }
+ if (startPageName!=null)
+ {
+ Node startPage = getProcessDefinition().getNode(startPageName);
+ if (startPage!=null)
+ {
+ getProcessDefinition().setStartState(startPage);
+ }
+ }
+ }
+ }
+
+}
Added: modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/PooledTask.java
===================================================================
--- modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/PooledTask.java (rev 0)
+++ modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/PooledTask.java 2009-04-24 23:24:14 UTC (rev 10631)
@@ -0,0 +1,120 @@
+package org.jboss.seam.bpm;
+
+import static org.jboss.seam.annotations.Install.BUILT_IN;
+
+import org.jboss.seam.ScopeType;
+import org.jboss.seam.annotations.Install;
+import org.jboss.seam.annotations.Name;
+import org.jboss.seam.annotations.Scope;
+import org.jboss.seam.annotations.Transactional;
+import org.jboss.seam.web.Parameters;
+import org.jbpm.taskmgmt.exe.TaskInstance;
+
+/**
+ * Support for assigning tasks in the pooled task list.
+ *
+ * @see TaskInstanceList
+ * @author Gavin King
+ */
+@Name("org.jboss.seam.bpm.pooledTask")
+(a)Scope(ScopeType.APPLICATION)
+@Install(precedence=BUILT_IN, dependencies="org.jboss.seam.bpm.jbpm")
+public class PooledTask
+{
+
+ /**
+ * Assign the TaskInstance with the id passed
+ * in the request parameter named "taskId" to
+ * the current actor.
+ *
+ * @see Actor
+ * @return a null outcome only if the task was not found
+ */
+ @Transactional
+ public String assignToCurrentActor()
+ {
+ Actor actor = Actor.instance();
+ if ( actor.getId()==null )
+ {
+ throw new IllegalStateException("no current actor id defined");
+ }
+ TaskInstance taskInstance = getTaskInstance();
+ if (taskInstance!=null)
+ {
+ taskInstance.setActorId( actor.getId() );
+ return "taskAssignedToActor";
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ /**
+ * Assign the TaskInstance with the id passed
+ * in the request parameter named "taskId" to
+ * the given actor id.
+ *
+ * @param actorId the jBPM actor id
+ * @return a null outcome only if the task was not found
+ */
+ @Transactional
+ public String assign(String actorId)
+ {
+ TaskInstance taskInstance = getTaskInstance();
+ if (taskInstance!=null)
+ {
+ taskInstance.setActorId(actorId);
+ return "taskAssigned";
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ /**
+ * Unassign the TaskInstance with the id passed
+ * in the request parameter named "taskId" from
+ * the actor to which it is assigned, and return
+ * it to the pool it came from.
+ *
+ * @return a null outcome only if the task was not found
+ */
+ @Transactional
+ public String unassign()
+ {
+ TaskInstance taskInstance = getTaskInstance();
+ if (taskInstance!=null)
+ {
+ taskInstance.setActorId(null);
+ return "taskUnassigned";
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ /**
+ * @return the TaskInstance with the id passed
+ * in the request parameter named "taskId".
+ */
+ @Transactional
+ public TaskInstance getTaskInstance()
+ {
+ String[] values = Parameters.instance().getRequestParameters().get("taskId");
+ if ( values==null || values.length!=1 )
+ {
+ return null;
+ }
+ else
+ {
+ String taskId = values[0];
+ return taskId==null ?
+ null :
+ ManagedJbpmContext.instance().getTaskInstanceForUpdate( Long.parseLong(taskId) );
+ }
+ }
+
+}
Added: modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/PooledTaskInstanceList.java
===================================================================
--- modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/PooledTaskInstanceList.java (rev 0)
+++ modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/PooledTaskInstanceList.java 2009-04-24 23:24:14 UTC (rev 10631)
@@ -0,0 +1,40 @@
+package org.jboss.seam.bpm;
+
+import static org.jboss.seam.annotations.Install.BUILT_IN;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.jboss.seam.ScopeType;
+import org.jboss.seam.annotations.Install;
+import org.jboss.seam.annotations.Name;
+import org.jboss.seam.annotations.Scope;
+import org.jboss.seam.annotations.Transactional;
+import org.jboss.seam.annotations.Unwrap;
+import org.jbpm.taskmgmt.exe.TaskInstance;
+
+/**
+ * Support for the pooled task list.
+ *
+ * @see TaskInstanceList
+ * @author Gavin King
+ */
+@Name("org.jboss.seam.bpm.pooledTaskInstanceList")
+(a)Scope(ScopeType.APPLICATION)
+@Install(precedence=BUILT_IN, dependencies="org.jboss.seam.bpm.jbpm")
+public class PooledTaskInstanceList
+{
+
+ @Unwrap
+ @Transactional
+ public List<TaskInstance> getPooledTaskInstanceList()
+ {
+ Actor actor = Actor.instance();
+ String actorId = actor.getId();
+ if ( actorId == null ) return null;
+ ArrayList groupIds = new ArrayList( actor.getGroupActorIds() );
+ groupIds.add(actorId);
+ return ManagedJbpmContext.instance().getGroupTaskList(groupIds);
+ }
+
+}
Added: modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/ProcessInstance.java
===================================================================
--- modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/ProcessInstance.java (rev 0)
+++ modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/ProcessInstance.java 2009-04-24 23:24:14 UTC (rev 10631)
@@ -0,0 +1,67 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Distributable under LGPL license.
+ * See terms of license at gnu.org.
+ */
+package org.jboss.seam.bpm;
+
+import static org.jboss.seam.annotations.Install.BUILT_IN;
+
+import org.jboss.seam.Component;
+import org.jboss.seam.ScopeType;
+import org.jboss.seam.annotations.Install;
+import org.jboss.seam.annotations.Name;
+import org.jboss.seam.annotations.Scope;
+import org.jboss.seam.annotations.Unwrap;
+import org.jboss.seam.annotations.intercept.BypassInterceptors;
+import org.jboss.seam.contexts.Contexts;
+import org.jboss.seam.util.Work;
+
+/**
+ * A Seam component that allows injection of the current
+ * jBPM ProcessInstance.
+ *
+ * @author Gavin King
+ */
+(a)Scope(ScopeType.STATELESS)
+@Name("org.jboss.seam.bpm.processInstance")
+@BypassInterceptors
+@Install(precedence=BUILT_IN, dependencies="org.jboss.seam.bpm.jbpm")
+public class ProcessInstance
+{
+
+ @Unwrap
+ public org.jbpm.graph.exe.ProcessInstance getProcessInstance() throws Exception
+ {
+ if ( !Contexts.isConversationContextActive() ) return null;
+
+ return new Work<org.jbpm.graph.exe.ProcessInstance>()
+ {
+
+ @Override
+ protected org.jbpm.graph.exe.ProcessInstance work() throws Exception
+ {
+ Long processId = BusinessProcess.instance().getProcessId();
+ if (processId!=null)
+ {
+ //TODO: do we need to cache this??
+ return ManagedJbpmContext.instance().getProcessInstanceForUpdate(processId);
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ }.workInTransaction();
+
+ }
+
+ public static org.jbpm.graph.exe.ProcessInstance instance()
+ {
+ if ( !Contexts.isConversationContextActive() || !BusinessProcess.instance().hasCurrentProcess() ) return null; //so we don't start a txn
+
+ return (org.jbpm.graph.exe.ProcessInstance) Component.getInstance(ProcessInstance.class, ScopeType.STATELESS);
+ }
+}
Added: modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/ProcessInstanceFinder.java
===================================================================
--- modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/ProcessInstanceFinder.java (rev 0)
+++ modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/ProcessInstanceFinder.java 2009-04-24 23:24:14 UTC (rev 10631)
@@ -0,0 +1,105 @@
+package org.jboss.seam.bpm;
+
+import static org.hibernate.criterion.Order.asc;
+import static org.hibernate.criterion.Order.desc;
+import static org.hibernate.criterion.Restrictions.isNotNull;
+import static org.hibernate.criterion.Restrictions.isNull;
+import static org.jboss.seam.annotations.Install.BUILT_IN;
+
+import java.util.List;
+
+import org.hibernate.Criteria;
+import org.hibernate.criterion.Restrictions;
+import org.jboss.seam.annotations.Factory;
+import org.jboss.seam.annotations.Install;
+import org.jboss.seam.annotations.Name;
+import org.jboss.seam.annotations.Transactional;
+import org.jbpm.graph.exe.ProcessInstance;
+
+/**
+ * Support for the process list.
+ *
+ * @author Gavin King
+ */
+@Name("org.jboss.seam.bpm.processInstanceFinder")
+@Install(precedence=BUILT_IN, dependencies="org.jboss.seam.bpm.jbpm")
+public class ProcessInstanceFinder
+{
+
+ private String processDefinitionName;
+ private String nodeName;
+ private Boolean processInstanceEnded = false;
+ private Boolean sortDescending = false;
+
+ @Factory(value="org.jboss.seam.bpm.processInstanceList", autoCreate=true)
+ @Transactional
+ public List<ProcessInstance> getProcessInstanceList()
+ {
+ Criteria query = ManagedJbpmContext.instance().getSession()
+ .createCriteria(ProcessInstance.class);
+ if ( processInstanceEnded!=null )
+ {
+ query.add( processInstanceEnded ? isNotNull("end") : isNull("end") );
+ }
+
+ if (processDefinitionName!=null)
+ {
+ query.createCriteria("processDefinition")
+ .add( Restrictions.eq("name", processDefinitionName) );
+ }
+
+ query = query.createCriteria("rootToken");
+ if (sortDescending!=null)
+ {
+ query.addOrder( sortDescending ? desc("nodeEnter") : asc("nodeEnter") );
+ }
+ if (nodeName!=null)
+ {
+ query.createCriteria("node")
+ .add( Restrictions.eq("name", nodeName) );
+ }
+
+ return query.list();
+ }
+
+ protected String getNodeName()
+ {
+ return nodeName;
+ }
+
+ protected void setNodeName(String nodeName)
+ {
+ this.nodeName = nodeName;
+ }
+
+ protected String getProcessDefinitionName()
+ {
+ return processDefinitionName;
+ }
+
+ protected void setProcessDefinitionName(String processDefinitionName)
+ {
+ this.processDefinitionName = processDefinitionName;
+ }
+
+ protected Boolean isSortDescending()
+ {
+ return sortDescending;
+ }
+
+ protected void setSortDescending(Boolean sortDescending)
+ {
+ this.sortDescending = sortDescending;
+ }
+
+ protected Boolean getProcessInstanceEnded()
+ {
+ return processInstanceEnded;
+ }
+
+ protected void setProcessInstanceEnded(Boolean ended)
+ {
+ this.processInstanceEnded = ended;
+ }
+
+}
Added: modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/SeamExpressionEvaluator.java
===================================================================
--- modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/SeamExpressionEvaluator.java (rev 0)
+++ modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/SeamExpressionEvaluator.java 2009-04-24 23:24:14 UTC (rev 10631)
@@ -0,0 +1,167 @@
+package org.jboss.seam.bpm;
+
+
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.el.CompositeELResolver;
+import javax.el.ELContext;
+import javax.el.MethodExpression;
+import javax.el.MethodNotFoundException;
+import javax.el.PropertyNotFoundException;
+import javax.el.ValueExpression;
+
+import org.jboss.seam.el.EL;
+import org.jboss.seam.el.SeamFunctionMapper;
+import org.jboss.seam.log.LogProvider;
+import org.jboss.seam.log.Logging;
+import org.jbpm.jpdl.el.ELException;
+import org.jbpm.jpdl.el.Expression;
+import org.jbpm.jpdl.el.ExpressionEvaluator;
+import org.jbpm.jpdl.el.FunctionMapper;
+import org.jbpm.jpdl.el.VariableResolver;
+
+/**
+ * Plugs the JBoss EL expression language and Seam
+ * EL resolvers into jBPM. Note that this current
+ * implementation does not allow jBPM to see stuff
+ * defined only by the JSF ELResolvers.
+ *
+ * @author Gavin King
+ * @author Pete Muir
+ *
+ */
+public class SeamExpressionEvaluator
+ extends ExpressionEvaluator
+{
+
+ private static LogProvider log = Logging.getLogProvider(SeamExpressionEvaluator.class);
+
+ @Override
+ public Object evaluate(String expression, Class returnType, final VariableResolver resolver, FunctionMapper mapper)
+ throws ELException
+ {
+ return createExpression(expression, returnType, mapper).evaluate(resolver);
+ }
+
+ @Override
+ public Expression parseExpression(final String expression, final Class returnType, FunctionMapper mapper)
+ throws ELException
+ {
+ return createExpression(expression, returnType, mapper);
+ }
+
+ private static Expression createExpression(final String expression, final Class returnType, final FunctionMapper mapper)
+ {
+
+ return new Expression()
+ {
+ private ELContext elContext = EL.createELContext();
+
+ private MethodExpression me;
+ private ValueExpression ve;
+
+ private void initMethodExpression()
+ {
+ if (me == null || ve == null)
+ {
+ me = EL.EXPRESSION_FACTORY.createMethodExpression(elContext, expression, returnType, new Class[0]);
+ }
+ }
+
+ private void initValueExpression()
+ {
+ if (me == null || ve == null)
+ {
+ ve = EL.EXPRESSION_FACTORY.createValueExpression(elContext, expression, returnType);
+ }
+ }
+
+ @Override
+ public Object evaluate(VariableResolver resolver) throws ELException
+ {
+ List<javax.el.ELException> exceptions = new ArrayList<javax.el.ELException>();
+ try
+ {
+ initMethodExpression();
+ if (me != null)
+ {
+ try
+ {
+ return me.invoke(createELContext(resolver, mapper), new Object[0]);
+ }
+ catch (MethodNotFoundException e)
+ {
+ exceptions.add(e);
+ }
+ }
+ }
+ catch (javax.el.ELException e)
+ {
+ exceptions.add(e);
+ }
+
+ try
+ {
+ initValueExpression();
+ if (ve != null)
+ {
+ try
+ {
+ return ve.getValue(createELContext(resolver, mapper));
+ }
+ catch (PropertyNotFoundException e)
+ {
+ exceptions.add(e);
+ }
+ }
+ }
+ catch (javax.el.ELException e)
+ {
+ exceptions.add(e);
+ }
+
+ if (exceptions.size() == 1)
+ {
+ throw new ELException("Error evaluating " + expression, exceptions.get(0));
+ }
+ else if (exceptions.size() > 1)
+ {
+ log.error("Exceptions occurred when parsing " + expression);
+ for (javax.el.ELException e : exceptions)
+ {
+ log.error("Possible cause", e);
+ }
+ }
+ if (me == null && ve == null)
+ {
+ log.error("Error parsing " + expression);
+ throw new ELException("Error parsing " + expression + "; not a valid EL expression");
+ }
+ throw new ELException("Error evaluating " + expression + "; possible causes are logged at debug level");
+ }
+ };
+ }
+
+ private static javax.el.FunctionMapper decorateFunctionMapper(final FunctionMapper functionMapper)
+ {
+ return new SeamFunctionMapper( new javax.el.FunctionMapper()
+ {
+ @Override
+ public Method resolveFunction(String prefix, String localName)
+ {
+ return functionMapper.resolveFunction(prefix, localName);
+ }
+ });
+ }
+
+ private static ELContext createELContext(VariableResolver resolver, FunctionMapper functionMapper)
+ {
+ CompositeELResolver composite = new CompositeELResolver();
+ composite.add(EL.EL_RESOLVER);
+ composite.add( new JbpmELResolver(resolver) );
+ return EL.createELContext(composite, decorateFunctionMapper(functionMapper));
+ }
+
+}
Added: modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/SeamUserCodeInterceptor.java
===================================================================
--- modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/SeamUserCodeInterceptor.java (rev 0)
+++ modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/SeamUserCodeInterceptor.java 2009-04-24 23:24:14 UTC (rev 10631)
@@ -0,0 +1,153 @@
+package org.jboss.seam.bpm;
+
+import org.jboss.seam.contexts.Contexts;
+import org.jboss.seam.contexts.Lifecycle;
+import org.jbpm.context.exe.ContextInstance;
+import org.jbpm.graph.def.Action;
+import org.jbpm.graph.exe.ExecutionContext;
+import org.jbpm.graph.exe.Token;
+import org.jbpm.instantiation.UserCodeInterceptor;
+import org.jbpm.taskmgmt.def.AssignmentHandler;
+import org.jbpm.taskmgmt.def.TaskControllerHandler;
+import org.jbpm.taskmgmt.exe.Assignable;
+import org.jbpm.taskmgmt.exe.TaskInstance;
+
+/**
+ * Intercepts calls to user code coming from jBPM, sets up
+ * Seam contexts and associates the process and task instances
+ * with the contexts.
+ *
+ * @author Gavin King
+ *
+ */
+class SeamUserCodeInterceptor implements UserCodeInterceptor
+{
+ abstract static class ContextualCall
+ {
+ abstract void process() throws Exception;
+
+ void run() throws Exception
+ {
+ if ( Contexts.isEventContextActive() || Contexts.isApplicationContextActive() ) //not sure about the second bit (only needed at init time!)
+ {
+ process();
+ }
+ else
+ {
+ Lifecycle.beginCall();
+ try
+ {
+ process();
+ }
+ finally
+ {
+ Lifecycle.endCall();
+ }
+ }
+ }
+
+ void runAndWrap()
+ {
+ try
+ {
+ run();
+ }
+ catch (RuntimeException re)
+ {
+ throw re;
+ }
+ catch (Exception e)
+ {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
+ public void executeAction(final Action action, final ExecutionContext context) throws Exception
+ {
+ if ( isPageflow(context) )
+ {
+ action.execute(context);
+ }
+ else
+ {
+ new ContextualCall()
+ {
+ @Override
+ void process() throws Exception
+ {
+ initProcessAndTask(context);
+ action.execute(context);
+ }
+ }.run();
+ }
+ }
+
+ private boolean isPageflow(final ExecutionContext context)
+ {
+ return Contexts.isConversationContextActive() &&
+ Jbpm.instance().isPageflowProcessDefinition( context.getProcessDefinition().getName() );
+ }
+
+ public void executeAssignment(final AssignmentHandler handler, final Assignable assignable,
+ final ExecutionContext context)
+ throws Exception
+ {
+ new ContextualCall()
+ {
+ @Override
+ void process() throws Exception
+ {
+ initProcessAndTask(context);
+ handler.assign(assignable, context);
+ }
+ }.run();
+ }
+
+ public void executeTaskControllerInitialization(final TaskControllerHandler handler, final TaskInstance task,
+ final ContextInstance context, final Token token)
+ {
+ new ContextualCall()
+ {
+ @Override
+ void process() throws Exception
+ {
+ initProcessAndTask(task);
+ handler.initializeTaskVariables(task, context, token);
+ }
+ }.runAndWrap();
+ }
+
+ public void executeTaskControllerSubmission(final TaskControllerHandler handler, final TaskInstance task,
+ final ContextInstance context, final Token token)
+ {
+ new ContextualCall()
+ {
+ @Override
+ void process() throws Exception
+ {
+ initProcessAndTask(task);
+ handler.submitTaskVariables(task, context, token);
+ }
+ }.runAndWrap();
+ }
+
+ private static void initProcessAndTask(ExecutionContext context)
+ {
+ BusinessProcess businessProcess = BusinessProcess.instance();
+ businessProcess.setProcessId( context.getProcessInstance().getId() );
+ TaskInstance taskInstance = context.getTaskInstance();
+ if (taskInstance!=null)
+ {
+ businessProcess.setTaskId( taskInstance.getId() );
+ }
+ }
+
+ private static void initProcessAndTask(TaskInstance task)
+ {
+ BusinessProcess businessProcess = BusinessProcess.instance();
+ businessProcess.setProcessId( task.getProcessInstance().getId() );
+ businessProcess.setTaskId( task.getId() );
+ }
+
+}
Added: modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/TaskInstance.java
===================================================================
--- modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/TaskInstance.java (rev 0)
+++ modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/TaskInstance.java 2009-04-24 23:24:14 UTC (rev 10631)
@@ -0,0 +1,53 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Distributable under LGPL license.
+ * See terms of license at gnu.org.
+ */
+package org.jboss.seam.bpm;
+
+import javax.annotation.Named;
+import javax.inject.Produces;
+
+/**
+ * A Seam component that allows injection of the current
+ * jBPM TaskInstance.
+ *
+ * @author Gavin King
+ */
+public class TaskInstance
+{
+ @Produces
+ public org.jbpm.taskmgmt.exe.TaskInstance getTaskInstance() throws Exception
+ {
+ if ( !Contexts.isConversationContextActive() ) return null;
+
+ return new Work<org.jbpm.taskmgmt.exe.TaskInstance>()
+ {
+
+ @Override
+ protected org.jbpm.taskmgmt.exe.TaskInstance work() throws Exception
+ {
+ Long taskId = BusinessProcess.instance().getTaskId();
+ if (taskId!=null)
+ {
+ //TODO: do we need to cache this??
+ return ManagedJbpmContext.instance().getTaskInstanceForUpdate(taskId);
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ }.workInTransaction();
+ }
+
+ public static org.jbpm.taskmgmt.exe.TaskInstance instance()
+ {
+ if ( !Contexts.isConversationContextActive() || !BusinessProcess.instance().hasCurrentTask() ) return null; //so we don't start a txn
+
+ return (org.jbpm.taskmgmt.exe.TaskInstance) Component.getInstance(TaskInstance.class, ScopeType.STATELESS);
+ }
+
+}
Added: modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/TaskInstanceList.java
===================================================================
--- modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/TaskInstanceList.java (rev 0)
+++ modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/TaskInstanceList.java 2009-04-24 23:24:14 UTC (rev 10631)
@@ -0,0 +1,33 @@
+package org.jboss.seam.bpm;
+
+import java.util.List;
+
+import javax.context.ApplicationScoped;
+import javax.inject.Produces;
+
+import org.jbpm.taskmgmt.exe.TaskInstance;
+
+/**
+ * Support for the task list.
+ *
+ * @see TaskInstanceListForType
+ * @see PooledTask
+ * @author <a href="mailto:steve@hibernate.org">Steve Ebersole</a>
+ * @author Gavin King
+ */
+public class TaskInstanceList
+{
+ @Produces
+ public List<TaskInstance> getTaskInstanceList()
+ {
+ return getTaskInstanceList( Actor.instance().getId() );
+ }
+
+ private List<TaskInstance> getTaskInstanceList(String actorId)
+ {
+ if ( actorId == null ) return null;
+
+ return ManagedJbpmContext.instance().getTaskList(actorId);
+ }
+
+}
Added: modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/TaskInstanceListForType.java
===================================================================
--- modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/TaskInstanceListForType.java (rev 0)
+++ modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/TaskInstanceListForType.java 2009-04-24 23:24:14 UTC (rev 10631)
@@ -0,0 +1,49 @@
+package org.jboss.seam.bpm;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.context.ApplicationScoped;
+
+import org.jbpm.taskmgmt.exe.TaskInstance;
+
+/**
+ * Support for a list of tasks of a particular type.
+ *
+ * @see TaskInstanceList
+ * @author Gavin King
+ * @author <a href="mailto:steve@hibernate.org">Steve Ebersole </a>
+ */
+@ApplicationScoped
+public class TaskInstanceListForType
+{
+ @Unwrap
+ @Transactional
+ public Map<String,List<TaskInstance>> getTaskInstanceList()
+ {
+ return getTaskInstanceList( Actor.instance().getId() );
+ }
+
+ private Map<String,List<TaskInstance>> getTaskInstanceList(String actorId)
+ {
+ if ( actorId == null ) return null;
+
+ Map<String, List<TaskInstance>> map = new HashMap<String, List<TaskInstance>>();
+ List<TaskInstance> taskInstances = ManagedJbpmContext.instance().getTaskList(actorId);
+ for ( TaskInstance task: taskInstances )
+ {
+ String name = task.getName();
+ List<TaskInstance> list = map.get(name);
+ if (list==null)
+ {
+ list = new ArrayList<TaskInstance>();
+ map.put(name, list);
+ }
+ list.add(task);
+ }
+ return map;
+ }
+
+}
Added: modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/TaskInstancePriorityList.java
===================================================================
--- modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/TaskInstancePriorityList.java (rev 0)
+++ modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/TaskInstancePriorityList.java 2009-04-24 23:24:14 UTC (rev 10631)
@@ -0,0 +1,45 @@
+package org.jboss.seam.bpm;
+
+import java.util.List;
+
+import javax.context.ApplicationScoped;
+import javax.inject.Produces;
+
+import org.hibernate.criterion.Order;
+import org.hibernate.criterion.Restrictions;
+import org.jbpm.taskmgmt.exe.TaskInstance;
+
+/**
+ * Support for a task list ordered by priority.
+ *
+ * @see TaskInstanceList
+ * @see PooledTask
+ * @author Gavin King
+ */
+public class TaskInstancePriorityList
+{
+
+ //TODO: we really need to cache the list in the event context,
+ // but then we would need some events to refresh it
+ // when tasks end, which is non-trivial to do....
+ @Produces @Transactional
+ public List<TaskInstance> getTaskInstanceList()
+ {
+ return getTaskInstanceList( Actor.instance().getId() );
+ }
+
+ private List<TaskInstance> getTaskInstanceList(String actorId)
+ {
+ if ( actorId == null ) return null;
+
+ return ManagedJbpmContext.instance().getSession()
+ .createCriteria(TaskInstance.class)
+ .add( Restrictions.eq("actorId", actorId) )
+ .add( Restrictions.eq("isOpen", true) )
+ .add( Restrictions.ne("isSuspended", true) )
+ .addOrder( Order.asc("priority") )
+ .setCacheable(true)
+ .list();
+ }
+
+}
Added: modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/Transition.java
===================================================================
--- modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/Transition.java (rev 0)
+++ modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/Transition.java 2009-04-24 23:24:14 UTC (rev 10631)
@@ -0,0 +1,63 @@
+package org.jboss.seam.bpm;
+
+import static org.jboss.seam.annotations.Install.BUILT_IN;
+
+import java.io.Serializable;
+
+import org.jboss.seam.Component;
+import org.jboss.seam.ScopeType;
+import org.jboss.seam.annotations.Install;
+import org.jboss.seam.annotations.Name;
+import org.jboss.seam.annotations.Scope;
+import org.jboss.seam.annotations.intercept.BypassInterceptors;
+import org.jboss.seam.contexts.Contexts;
+import org.jboss.seam.core.AbstractMutable;
+
+/**
+ * Allows the application to set the jBPM transition to be used when
+ * an <tt>@EndTask</tt> method is encountered.
+ *
+ * @see org.jboss.seam.annotations.bpm.EndTask
+ *
+ * @author Gavin King
+ */
+@Name("org.jboss.seam.bpm.transition")
+(a)Scope(ScopeType.CONVERSATION)
+@BypassInterceptors
+@Install(precedence=BUILT_IN, dependencies="org.jboss.seam.bpm.jbpm")
+public class Transition extends AbstractMutable implements Serializable
+{
+ private static final long serialVersionUID = -3054558654376670239L;
+
+ private String name;
+
+ public String getName()
+ {
+ return name;
+ }
+
+ /**
+ * Set the jBPM transition name
+ */
+ public void setName(String name)
+ {
+ setDirty(this.name, name);
+ this.name = name;
+ }
+
+ public static Transition instance()
+ {
+ if ( !Contexts.isApplicationContextActive() )
+ {
+ throw new IllegalStateException("No active application context");
+ }
+ return (Transition) Component.getInstance(Transition.class, ScopeType.CONVERSATION);
+ }
+
+ @Override
+ public String toString()
+ {
+ return "Transition(" + name + ")";
+ }
+
+}
Added: modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/jbpm.pageflow.cfg.xml
===================================================================
--- modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/jbpm.pageflow.cfg.xml (rev 0)
+++ modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/jbpm.pageflow.cfg.xml 2009-04-24 23:24:14 UTC (rev 10631)
@@ -0,0 +1,3 @@
+<pageflow-configuration>
+ <jbpm-context />
+</pageflow-configuration>
Added: modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/package-info.java
===================================================================
--- modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/package-info.java (rev 0)
+++ modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/package-info.java 2009-04-24 23:24:14 UTC (rev 10631)
@@ -0,0 +1,17 @@
+/**
+ * A set of Seam components for business process management
+ * via jBPM, including control of process and task instances,
+ * rendering of task lists, and integration with jBPM.
+ *
+ * The application may call components in this package
+ * directly, or via EL, or may use them indirectly via
+ * the annotations in org.jboss.seam.annotations.
+ *
+ * @see org.jboss.seam.annotations.bpm
+ */
+@Namespace(value="http://jboss.com/products/seam/bpm", prefix="org.jboss.seam.bpm")
+@AutoCreate
+package org.jboss.seam.bpm;
+
+import org.jboss.seam.annotations.AutoCreate;
+import org.jboss.seam.annotations.Namespace;
[View Less]
15 years, 10 months
Seam SVN: r10630 - modules/trunk/version-matrix.
by seam-commits@lists.jboss.org
Author: shane.bryzak(a)jboss.com
Date: 2009-04-24 19:23:22 -0400 (Fri, 24 Apr 2009)
New Revision: 10630
Modified:
modules/trunk/version-matrix/pom.xml
Log:
added bpm, drools dependencies
Modified: modules/trunk/version-matrix/pom.xml
===================================================================
--- modules/trunk/version-matrix/pom.xml 2009-04-24 14:09:04 UTC (rev 10629)
+++ modules/trunk/version-matrix/pom.xml 2009-04-24 23:23:22 UTC (rev 10630)
@@ -171,6 +171,18 @@
<…
[View More]version>1.0.0-SNAPSHOT</version>
</dependency>
+ <dependency>
+ <groupId>org.drools</groupId>
+ <artifactId>drools-core</artifactId>
+ <version>4.0.4</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.jbpm</groupId>
+ <artifactId>jbpm-jpdl</artifactId>
+ <version>3.2.2</version>
+ </dependency>
+
</dependencies>
</dependencyManagement>
[View Less]
15 years, 10 months
Seam SVN: r10629 - branches/community/Seam_2_1/examples/restbay/src/org/jboss/seam/example/restbay/resteasy.
by seam-commits@lists.jboss.org
Author: christian.bauer(a)jboss.com
Date: 2009-04-24 10:09:04 -0400 (Fri, 24 Apr 2009)
New Revision: 10629
Removed:
branches/community/Seam_2_1/examples/restbay/src/org/jboss/seam/example/restbay/resteasy/CalendarResource.java
Log:
Cleanup
Deleted: branches/community/Seam_2_1/examples/restbay/src/org/jboss/seam/example/restbay/resteasy/CalendarResource.java
===================================================================
--- branches/community/Seam_2_1/examples/restbay/src/org/jboss/…
[View More]seam/example/restbay/resteasy/CalendarResource.java 2009-04-24 13:29:32 UTC (rev 10628)
+++ branches/community/Seam_2_1/examples/restbay/src/org/jboss/seam/example/restbay/resteasy/CalendarResource.java 2009-04-24 14:09:04 UTC (rev 10629)
@@ -1,25 +0,0 @@
-package org.jboss.seam.example.restbay.resteasy;
-
-import javax.ws.rs.GET;
-import java.util.GregorianCalendar;
-
-/**
- * @author Christian Bauer
- */
-public class CalendarResource
-{
- private GregorianCalendar cal;
-
- public CalendarResource(GregorianCalendar cal)
- {
- this.cal = cal;
- }
-
- @GET
- public long get()
- {
- System.out.println("#### GET");
- return cal.getTime().getTime();
- }
-
-}
[View Less]
15 years, 10 months
Seam SVN: r10628 - in branches/community/Seam_2_1: doc/Seam_Reference_Guide/en-US and 5 other directories.
by seam-commits@lists.jboss.org
Author: christian.bauer(a)jboss.com
Date: 2009-04-24 09:29:32 -0400 (Fri, 24 Apr 2009)
New Revision: 10628
Added:
branches/community/Seam_2_1/examples/restbay/src/org/jboss/seam/example/restbay/resteasy/EventComponentTestResource.java
branches/community/Seam_2_1/examples/restbay/src/org/jboss/seam/example/restbay/resteasy/PlainTestResource.java
branches/community/Seam_2_1/examples/restbay/src/org/jboss/seam/example/restbay/resteasy/StatelessEjbTestResource.java
branches/community/…
[View More]Seam_2_1/examples/restbay/src/org/jboss/seam/example/restbay/resteasy/StatelessEjbTestResourceBean.java
branches/community/Seam_2_1/examples/restbay/src/org/jboss/seam/example/restbay/resteasy/TestComponent.java
branches/community/Seam_2_1/src/resteasy/org/jboss/seam/resteasy/SeamResteasyProviderFactory.java
branches/community/Seam_2_1/src/resteasy/org/jboss/seam/resteasy/SeamResteasyResourceFactory.java
Modified:
branches/community/Seam_2_1/build/root.pom.xml
branches/community/Seam_2_1/doc/Seam_Reference_Guide/en-US/Webservices.xml
branches/community/Seam_2_1/examples/restbay/resources/WEB-INF/components.xml
branches/community/Seam_2_1/examples/restbay/resources/jboss-rest-bay-ds.xml
branches/community/Seam_2_1/examples/restbay/src/org/jboss/seam/example/restbay/resteasy/TestResource.java
branches/community/Seam_2_1/examples/restbay/src/org/jboss/seam/example/restbay/test/BasicServiceTest.java
branches/community/Seam_2_1/src/resteasy/org/jboss/seam/resteasy/Application.java
branches/community/Seam_2_1/src/resteasy/org/jboss/seam/resteasy/ResourceHome.java
branches/community/Seam_2_1/src/resteasy/org/jboss/seam/resteasy/ResourceQuery.java
branches/community/Seam_2_1/src/resteasy/org/jboss/seam/resteasy/ResteasyBootstrap.java
branches/community/Seam_2_1/src/resteasy/org/jboss/seam/resteasy/ResteasyDispatcher.java
branches/community/Seam_2_1/src/resteasy/org/jboss/seam/resteasy/ResteasyResourceAdapter.java
Log:
JBSEAM-3449, JBSEAM-4150, upgrade to RESTEasy 1.1RC2, support for plain EJB resources, bootstrap improvements, more tests in example
Modified: branches/community/Seam_2_1/build/root.pom.xml
===================================================================
--- branches/community/Seam_2_1/build/root.pom.xml 2009-04-24 13:13:27 UTC (rev 10627)
+++ branches/community/Seam_2_1/build/root.pom.xml 2009-04-24 13:29:32 UTC (rev 10628)
@@ -300,7 +300,7 @@
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jaxrs</artifactId>
- <version>1.1-RC1</version>
+ <version>1.1-RC2</version>
<exclusions>
<exclusion>
<groupId>commons-codec</groupId>
Modified: branches/community/Seam_2_1/doc/Seam_Reference_Guide/en-US/Webservices.xml
===================================================================
--- branches/community/Seam_2_1/doc/Seam_Reference_Guide/en-US/Webservices.xml 2009-04-24 13:13:27 UTC (rev 10627)
+++ branches/community/Seam_2_1/doc/Seam_Reference_Guide/en-US/Webservices.xml 2009-04-24 13:29:32 UTC (rev 10628)
@@ -340,6 +340,7 @@
<resteasy:resource-class-names>
<value>org.foo.MyCustomerResource</value>
<value>org.foo.MyOrderResource</value>
+ <value>org.foo.MyStatelessEJBImplementation</value>
</resteasy:resource-class-names>
<resteasy:provider-class-names>
@@ -349,6 +350,18 @@
</resteasy:application>]]></programlisting>
<para>
+ RESTEasy supports plain EJBs (EJBs that are not Seam components) as resources. Instead of configuring the
+ JNDI names in a non-portable fashion in <literal>web.xml</literal> (see RESTEasy documentation), you can
+ simply list the EJB implementation classes, not the business interfaces, in <literal>components.xml</literal>
+ as shown above. Note that you have to annotate the <literal>@Local</literal> interface of the EJB with
+ <literal>@Path</literal>, <literal>@GET</literal>, and so on - not the bean implementation class. This allows
+ you to keep your application deployment-portable with the global Seam <literal>jndi-pattern</literal> switch
+ on <literal><core:init/></literal>. Note that EJB resources will not be found even if scanning of
+ resources is enabled, you always have to list them manually. Again, this is only relevant for EJB resources
+ that are not also Seam components and that do not have a <literal>@Name</literal> annotation.
+ </para>
+
+ <para>
The <literal>use-built-in-providers</literal> switch enables (default) or disables the RESTEasy built-in
providers. We recommend you leave them enabled, as they provide plaintext, JSON, and JAXB marshalling
out of the box.
Modified: branches/community/Seam_2_1/examples/restbay/resources/WEB-INF/components.xml
===================================================================
--- branches/community/Seam_2_1/examples/restbay/resources/WEB-INF/components.xml 2009-04-24 13:13:27 UTC (rev 10627)
+++ branches/community/Seam_2_1/examples/restbay/resources/WEB-INF/components.xml 2009-04-24 13:29:32 UTC (rev 10628)
@@ -35,7 +35,11 @@
entity-class="org.jboss.seam.example.restbay.Category"
auto-create="true"/>
- <resteasy:application resource-path-prefix="/restv1"/>
+ <resteasy:application resource-path-prefix="/restv1">
+ <resteasy:resource-class-names>
+ <value>org.jboss.seam.example.restbay.resteasy.StatelessEjbTestResourceBean</value>
+ </resteasy:resource-class-names>
+ </resteasy:application>
<resteasy:resource-home path="/configuredCategory" name="configuredCategoryResourceHome"
entity-home="#{categoryHome}" entity-id-class="java.lang.Integer"
Modified: branches/community/Seam_2_1/examples/restbay/resources/jboss-rest-bay-ds.xml
===================================================================
--- branches/community/Seam_2_1/examples/restbay/resources/jboss-rest-bay-ds.xml 2009-04-24 13:13:27 UTC (rev 10627)
+++ branches/community/Seam_2_1/examples/restbay/resources/jboss-rest-bay-ds.xml 2009-04-24 13:29:32 UTC (rev 10628)
@@ -1,9 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE datasources
- PUBLIC "-//JBoss//DTD JBOSS JCA Config 1.5//EN"
- "http://www.jboss.org/j2ee/dtd/jboss-ds_1_5.dtd">
-
<datasources>
<local-tx-datasource>
<jndi-name>restbayDatasource</jndi-name>
Added: branches/community/Seam_2_1/examples/restbay/src/org/jboss/seam/example/restbay/resteasy/EventComponentTestResource.java
===================================================================
--- branches/community/Seam_2_1/examples/restbay/src/org/jboss/seam/example/restbay/resteasy/EventComponentTestResource.java (rev 0)
+++ branches/community/Seam_2_1/examples/restbay/src/org/jboss/seam/example/restbay/resteasy/EventComponentTestResource.java 2009-04-24 13:29:32 UTC (rev 10628)
@@ -0,0 +1,138 @@
+package org.jboss.seam.example.restbay.resteasy;
+
+import org.jboss.resteasy.annotations.Form;
+import org.jboss.seam.annotations.Name;
+import org.jboss.seam.annotations.In;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.CookieParam;
+import javax.ws.rs.Encoded;
+import javax.ws.rs.FormParam;
+import javax.ws.rs.GET;
+import javax.ws.rs.HeaderParam;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.MultivaluedMap;
+import java.util.GregorianCalendar;
+import java.util.List;
+
+/**
+ * @author Christian Bauer
+ */
+@Name("eventComponentTestResource")
+@Path("/eventComponentTest")
+public class EventComponentTestResource extends TestResource
+{
+
+ @In
+ TestComponent testComponent;
+
+ @GET
+ @Path("/echouri")
+ @Override
+ public String echoUri()
+ {
+ return super.echoUri();
+ }
+
+ @GET
+ @Path("/echoquery")
+ @Override
+ public String echoQueryParam(@QueryParam("bar") String bar)
+ {
+ return super.echoQueryParam(bar);
+ }
+
+ @GET
+ @Path("/echoheader")
+ @Override
+ public String echoHeaderParam(@HeaderParam("bar") String bar)
+ {
+ return super.echoHeaderParam(bar);
+ }
+
+ @GET
+ @Path("/echocookie")
+ @Override
+ public String echoCookieParam(@CookieParam("bar") String bar)
+ {
+ return super.echoCookieParam(bar);
+ }
+
+ @GET
+ @Path("/echotwoparams/{1}/{2}")
+ @Override
+ public String echoTwoParams(@PathParam("1") String one, @PathParam("2") String two)
+ {
+ return super.echoTwoParams(one, two);
+ }
+
+ @GET
+ @Path("/echoencoded/{val}")
+ @Override
+ public String echoEncoded(@PathParam("val") @Encoded String val)
+ {
+ return super.echoEncoded(val);
+ }
+
+ @POST
+ @Path("/echoformparams")
+ @Consumes("application/x-www-form-urlencoded")
+ @Override
+ public String echoFormParams(MultivaluedMap<String, String> formMap)
+ {
+ return super.echoFormParams(formMap);
+ }
+
+ @POST
+ @Path("/echoformparams2")
+ @Override
+ public String echoFormParams2(@FormParam("foo") String[] foo)
+ {
+ return super.echoFormParams2(foo);
+ }
+
+ @POST
+ @Path("/echoformparams3")
+ @Override
+ public String echoFormParams3(@Form TestForm form)
+ {
+ return super.echoFormParams3(form);
+ }
+
+ @Path("/foo/bar/{baz}")
+ @Override
+ public SubResource getBar(@PathParam("baz") String baz)
+ {
+ return super.getBar(baz);
+ }
+
+ @GET
+ @Path("/convertDate/{isoDate}")
+ @Override
+ public long convertPathParam(@PathParam("isoDate") GregorianCalendar isoDate)
+ {
+ return super.convertPathParam(isoDate);
+ }
+
+ @GET
+ @Path("/trigger/unsupported")
+ @Override
+ public String throwException()
+ {
+ return super.throwException();
+ }
+
+ @GET
+ @Path("/commaSeparated")
+ @Produces("text/csv")
+ @Override
+ public List<String[]> getCommaSeparated()
+ {
+ return testComponent.getCommaSeparated();
+ }
+
+}
Added: branches/community/Seam_2_1/examples/restbay/src/org/jboss/seam/example/restbay/resteasy/PlainTestResource.java
===================================================================
--- branches/community/Seam_2_1/examples/restbay/src/org/jboss/seam/example/restbay/resteasy/PlainTestResource.java (rev 0)
+++ branches/community/Seam_2_1/examples/restbay/src/org/jboss/seam/example/restbay/resteasy/PlainTestResource.java 2009-04-24 13:29:32 UTC (rev 10628)
@@ -0,0 +1,121 @@
+package org.jboss.seam.example.restbay.resteasy;
+
+import org.jboss.resteasy.annotations.Form;
+
+import javax.ws.rs.*;
+import javax.ws.rs.core.MultivaluedMap;
+import java.util.GregorianCalendar;
+import java.util.List;
+
+/**
+ * @author Christian Bauer
+ */
+@Path("/plainTest")
+public class PlainTestResource extends TestResource
+{
+
+ @GET
+ @Path("/echouri")
+ @Override
+ public String echoUri()
+ {
+ return super.echoUri();
+ }
+
+ @GET
+ @Path("/echoquery")
+ @Override
+ public String echoQueryParam(@QueryParam("bar") String bar)
+ {
+ return super.echoQueryParam(bar);
+ }
+
+ @GET
+ @Path("/echoheader")
+ @Override
+ public String echoHeaderParam(@HeaderParam("bar") String bar)
+ {
+ return super.echoHeaderParam(bar);
+ }
+
+ @GET
+ @Path("/echocookie")
+ @Override
+ public String echoCookieParam(@CookieParam("bar") String bar)
+ {
+ return super.echoCookieParam(bar);
+ }
+
+ @GET
+ @Path("/echotwoparams/{1}/{2}")
+ @Override
+ public String echoTwoParams(@PathParam("1") String one, @PathParam("2") String two)
+ {
+ return super.echoTwoParams(one, two);
+ }
+
+ @GET
+ @Path("/echoencoded/{val}")
+ @Override
+ public String echoEncoded(@PathParam("val") @Encoded String val)
+ {
+ return super.echoEncoded(val);
+ }
+
+ @POST
+ @Path("/echoformparams")
+ @Consumes("application/x-www-form-urlencoded")
+ @Override
+ public String echoFormParams(MultivaluedMap<String, String> formMap)
+ {
+ return super.echoFormParams(formMap);
+ }
+
+ @POST
+ @Path("/echoformparams2")
+ @Override
+ public String echoFormParams2(@FormParam("foo") String[] foo)
+ {
+ return super.echoFormParams2(foo);
+ }
+
+ @POST
+ @Path("/echoformparams3")
+ @Override
+ public String echoFormParams3(@Form TestForm form)
+ {
+ return super.echoFormParams3(form);
+ }
+
+ @Path("/foo/bar/{baz}")
+ @Override
+ public SubResource getBar(@PathParam("baz") String baz)
+ {
+ return super.getBar(baz);
+ }
+
+ @GET
+ @Path("/convertDate/{isoDate}")
+ @Override
+ public long convertPathParam(@PathParam("isoDate") GregorianCalendar isoDate)
+ {
+ return super.convertPathParam(isoDate);
+ }
+
+ @GET
+ @Path("/trigger/unsupported")
+ @Override
+ public String throwException()
+ {
+ return super.throwException();
+ }
+
+ @GET
+ @Path("/commaSeparated")
+ @Produces("text/csv")
+ @Override
+ public List<String[]> getCommaSeparated()
+ {
+ return super.getCommaSeparated();
+ }
+}
Added: branches/community/Seam_2_1/examples/restbay/src/org/jboss/seam/example/restbay/resteasy/StatelessEjbTestResource.java
===================================================================
--- branches/community/Seam_2_1/examples/restbay/src/org/jboss/seam/example/restbay/resteasy/StatelessEjbTestResource.java (rev 0)
+++ branches/community/Seam_2_1/examples/restbay/src/org/jboss/seam/example/restbay/resteasy/StatelessEjbTestResource.java 2009-04-24 13:29:32 UTC (rev 10628)
@@ -0,0 +1,93 @@
+package org.jboss.seam.example.restbay.resteasy;
+
+import org.jboss.resteasy.annotations.Form;
+
+import javax.ejb.Local;
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.UriInfo;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.Path;
+import javax.ws.rs.GET;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.HeaderParam;
+import javax.ws.rs.CookieParam;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Encoded;
+import javax.ws.rs.POST;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.FormParam;
+import javax.ws.rs.Produces;
+import java.util.GregorianCalendar;
+import java.util.List;
+
+/**
+ * @author Christian Bauer
+ */
+@Local
+@Path("/statelessEjbTest")
+public interface StatelessEjbTestResource
+{
+
+ // TODO: RESTEasy can not inject setter/fields on plain EJBs, see https://jira.jboss.org/jira/browse/RESTEASY-151
+ // That's why we have to do it through parameter injection below
+ @Context
+ public void setUriInfo(UriInfo uriInfo);
+
+ @Context
+ public void setHeaders(HttpHeaders headers);
+
+
+ @GET
+ @Path("/echouri")
+ String echoUri(@Context UriInfo uriInfo); // TODO
+
+ @GET
+ @Path("/echoquery")
+ String echoQueryParam(@QueryParam("bar") String bar);
+
+ @GET
+ @Path("/echoheader")
+ String echoHeaderParam(@HeaderParam("bar") String bar);
+
+ @GET
+ @Path("/echocookie")
+ String echoCookieParam(@CookieParam("bar") String bar);
+
+ @GET
+ @Path("/echotwoparams/{1}/{2}")
+ String echoTwoParams(@PathParam("1") String one, @PathParam("2") String two);
+
+ @GET
+ @Path("/echoencoded/{val}")
+ String echoEncoded(@PathParam("val") @Encoded String val);
+
+ @POST
+ @Path("/echoformparams")
+ @Consumes("application/x-www-form-urlencoded")
+ String echoFormParams(MultivaluedMap<String, String> formMap);
+
+ @POST
+ @Path("/echoformparams2")
+ String echoFormParams2(@FormParam("foo") String[] foo);
+
+ @POST
+ @Path("/echoformparams3")
+ String echoFormParams3(@Form TestForm form);
+
+ @Path("/foo/bar/{baz}")
+ SubResource getBar(@PathParam("baz") String baz);
+
+ @GET
+ @Path("/convertDate/{isoDate}")
+ long convertPathParam(@PathParam("isoDate") GregorianCalendar isoDate);
+
+ @GET
+ @Path("/trigger/unsupported")
+ String throwException();
+
+ @GET
+ @Path("/commaSeparated")
+ @Produces("text/csv")
+ List<String[]> getCommaSeparated(@Context HttpHeaders headers); // TODO
+}
Added: branches/community/Seam_2_1/examples/restbay/src/org/jboss/seam/example/restbay/resteasy/StatelessEjbTestResourceBean.java
===================================================================
--- branches/community/Seam_2_1/examples/restbay/src/org/jboss/seam/example/restbay/resteasy/StatelessEjbTestResourceBean.java (rev 0)
+++ branches/community/Seam_2_1/examples/restbay/src/org/jboss/seam/example/restbay/resteasy/StatelessEjbTestResourceBean.java 2009-04-24 13:29:32 UTC (rev 10628)
@@ -0,0 +1,101 @@
+package org.jboss.seam.example.restbay.resteasy;
+
+import javax.ejb.Stateless;
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.UriInfo;
+import java.util.GregorianCalendar;
+import java.util.List;
+
+/**
+ * @author Christian Bauer
+ */
+@Stateless
+public class StatelessEjbTestResourceBean extends TestResource implements StatelessEjbTestResource
+{
+
+ @javax.annotation.Resource // EJB injection!
+ javax.ejb.SessionContext ejbSessionContext;
+
+
+ public String echoUri(@Context UriInfo uriInfo)
+ {
+ assert ejbSessionContext != null; // Ensure this is executed in the EJB container
+ setUriInfo(uriInfo);
+ return super.echoUri();
+ }
+
+ @Override
+ public String echoQueryParam(String bar)
+ {
+ return super.echoQueryParam(bar);
+ }
+
+ @Override
+ public String echoHeaderParam(String bar)
+ {
+ return super.echoHeaderParam(bar);
+ }
+
+ @Override
+ public String echoCookieParam(String bar)
+ {
+ return super.echoCookieParam(bar);
+ }
+
+ @Override
+ public String echoTwoParams(String one, String two)
+ {
+ return super.echoTwoParams(one, two);
+ }
+
+ @Override
+ public String echoEncoded(String val)
+ {
+ return super.echoEncoded(val);
+ }
+
+ @Override
+ public String echoFormParams(MultivaluedMap<String, String> formMap)
+ {
+ return super.echoFormParams(formMap);
+ }
+
+ @Override
+ public String echoFormParams2(String[] foo)
+ {
+ return super.echoFormParams2(foo);
+ }
+
+ @Override
+ public String echoFormParams3(TestForm form)
+ {
+ return super.echoFormParams3(form);
+ }
+
+ @Override
+ public SubResource getBar(String baz)
+ {
+ return super.getBar(baz);
+ }
+
+ @Override
+ public long convertPathParam(GregorianCalendar isoDate)
+ {
+ return super.convertPathParam(isoDate);
+ }
+
+ @Override
+ public String throwException()
+ {
+ return super.throwException();
+ }
+
+ public List<String[]> getCommaSeparated(@Context HttpHeaders headers)
+ {
+ setHeaders(headers);
+ return super.getCommaSeparated();
+ }
+
+}
\ No newline at end of file
Added: branches/community/Seam_2_1/examples/restbay/src/org/jboss/seam/example/restbay/resteasy/TestComponent.java
===================================================================
--- branches/community/Seam_2_1/examples/restbay/src/org/jboss/seam/example/restbay/resteasy/TestComponent.java (rev 0)
+++ branches/community/Seam_2_1/examples/restbay/src/org/jboss/seam/example/restbay/resteasy/TestComponent.java 2009-04-24 13:29:32 UTC (rev 10628)
@@ -0,0 +1,23 @@
+package org.jboss.seam.example.restbay.resteasy;
+
+import org.jboss.seam.annotations.Name;
+import org.jboss.seam.annotations.AutoCreate;
+
+import java.util.List;
+import java.util.ArrayList;
+
+/**
+ * @author Christian Bauer
+ */
+@Name("testComponent")
+@AutoCreate
+public class TestComponent
+{
+
+ public List<String[]> getCommaSeparated() {
+ List<String[]> csv = new ArrayList();
+ csv.add(new String[]{"foo", "bar"});
+ csv.add(new String[]{"asdf", "123"});
+ return csv;
+ }
+}
Modified: branches/community/Seam_2_1/examples/restbay/src/org/jboss/seam/example/restbay/resteasy/TestResource.java
===================================================================
--- branches/community/Seam_2_1/examples/restbay/src/org/jboss/seam/example/restbay/resteasy/TestResource.java 2009-04-24 13:13:27 UTC (rev 10627)
+++ branches/community/Seam_2_1/examples/restbay/src/org/jboss/seam/example/restbay/resteasy/TestResource.java 2009-04-24 13:29:32 UTC (rev 10628)
@@ -1,66 +1,67 @@
package org.jboss.seam.example.restbay.resteasy;
-import org.jboss.resteasy.annotations.Form;
-
-import javax.ws.rs.*;
-import javax.ws.rs.core.*;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.core.UriInfo;
+import java.util.ArrayList;
import java.util.GregorianCalendar;
import java.util.List;
-import java.util.ArrayList;
/**
* Plain JAX RS root resource, no Seam components/lifecycle.
*
* @author Christian Bauer
*/
-@Path("/test")
public class TestResource
{
@Context
- UriInfo uriInfo;
+ protected UriInfo uriInfo;
@Context
- HttpHeaders headers;
+ protected HttpHeaders headers;
- @GET
- @Path("/echouri")
+ public void setUriInfo(UriInfo uriInfo)
+ {
+ this.uriInfo = uriInfo;
+ }
+
+ public void setHeaders(HttpHeaders headers)
+ {
+ this.headers = headers;
+ }
+
public String echoUri()
{
return uriInfo.getPath();
}
- @GET
- @Path("/echoquery")
- public String echoQueryParam(@QueryParam("bar") String bar)
+ public String echoQueryParam(String bar)
{
return bar;
}
- @GET
- @Path("/echoheader")
- public String echoHeaderParam(@HeaderParam("bar") String bar)
+ public String echoHeaderParam(String bar)
{
return bar;
}
- @GET
- @Path("/echocookie")
- public String echoCookieParam(@CookieParam("bar") String bar)
+ public String echoCookieParam(String bar)
{
return bar;
}
- @GET
- @Path("/echoencoded/{val}")
- public String echoEncoded(@PathParam("val") @Encoded String val)
+ public String echoTwoParams(String one, String two)
{
+ return one+two;
+ }
+
+ public String echoEncoded(String val)
+ {
return val;
}
- @POST
- @Path("/echoformparams")
- @Consumes("application/x-www-form-urlencoded")
public String echoFormParams(MultivaluedMap<String, String> formMap)
{
String result = "";
@@ -71,9 +72,7 @@
return result;
}
- @POST
- @Path("/echoformparams2")
- public String echoFormParams2(@FormParam("foo") String[] foo)
+ public String echoFormParams2(String[] foo)
{
String result = "";
for (String s : foo)
@@ -83,44 +82,31 @@
return result;
}
- @POST
- @Path("/echoformparams3")
- public String echoFormParams3(@Form TestForm form)
+ public String echoFormParams3(TestForm form)
{
return form.toString();
}
- @Path("/foo/bar/{baz}")
- public SubResource getBar(@PathParam("baz") String baz)
+ public SubResource getBar(String baz)
{
return new SubResource(baz);
}
- @GET
- @Path("/foo/{isoDate}")
- public long convertPathParam(@PathParam("isoDate") GregorianCalendar isoDate)
+ public long convertPathParam(GregorianCalendar isoDate)
{
return isoDate.getTime().getTime();
}
- @GET
- @Path("/foo/unsupported")
public String throwException()
{
throw new UnsupportedOperationException("foo");
}
- @GET
- @Path("/foo/commaseparated")
- @Produces("text/csv")
public List<String[]> getCommaSeparated() {
assert headers.getAcceptableMediaTypes().size() == 2;
assert headers.getAcceptableMediaTypes().get(0).toString().equals("text/plain");
assert headers.getAcceptableMediaTypes().get(1).toString().equals("text/csv");
- List<String[]> csv = new ArrayList();
- csv.add(new String[]{"foo", "bar"});
- csv.add(new String[]{"asdf", "123"});
- return csv;
+ return new TestComponent().getCommaSeparated();
}
Modified: branches/community/Seam_2_1/examples/restbay/src/org/jboss/seam/example/restbay/test/BasicServiceTest.java
===================================================================
--- branches/community/Seam_2_1/examples/restbay/src/org/jboss/seam/example/restbay/test/BasicServiceTest.java 2009-04-24 13:13:27 UTC (rev 10627)
+++ branches/community/Seam_2_1/examples/restbay/src/org/jboss/seam/example/restbay/test/BasicServiceTest.java 2009-04-24 13:29:32 UTC (rev 10628)
@@ -4,6 +4,7 @@
import org.jboss.seam.example.restbay.test.fwk.MockHttpServletResponse;
import org.jboss.seam.example.restbay.test.fwk.MockHttpServletRequest;
import org.testng.annotations.Test;
+import org.testng.annotations.DataProvider;
import static org.testng.Assert.assertEquals;
import javax.servlet.http.Cookie;
@@ -23,10 +24,20 @@
}};
}
- @Test
- public void testExeptionMapping() throws Exception
+ @DataProvider(name = "queryPaths")
+ public Object[][] getData()
{
- new ResourceRequest(Method.GET, "/restv1/test/foo/unsupported")
+ return new String[][] {
+ { "/restv1/plainTest" },
+ { "/restv1/eventComponentTest" },
+ { "/restv1/statelessEjbTest" }
+ };
+ }
+
+ @Test(dataProvider = "queryPaths")
+ public void testExeptionMapping(final String resourcePath) throws Exception
+ {
+ new ResourceRequest(Method.GET, resourcePath + "/trigger/unsupported")
{
@Override
@@ -40,22 +51,22 @@
}
- @Test
- public void testPlainResources() throws Exception
+ @Test(dataProvider = "queryPaths")
+ public void testEchos(final String resourcePath) throws Exception
{
- new ResourceRequest(Method.GET, "/restv1/test/echouri")
+ new ResourceRequest(Method.GET, resourcePath + "/echouri")
{
@Override
protected void onResponse(MockHttpServletResponse response)
{
assert response.getStatus() == 200;
- assert response.getContentAsString().equals("/test/echouri");
+ assert response.getContentAsString().endsWith("/echouri");
}
}.run();
- new ResourceRequest(Method.GET, "/restv1/test/echoquery")
+ new ResourceRequest(Method.GET, resourcePath + "/echoquery")
{
@Override
@@ -75,7 +86,7 @@
}.run();
- new ResourceRequest(Method.GET, "/restv1/test/echoheader")
+ new ResourceRequest(Method.GET, resourcePath + "/echoheader")
{
@Override
@@ -93,7 +104,7 @@
}.run();
- new ResourceRequest(Method.GET, "/restv1/test/echocookie")
+ new ResourceRequest(Method.GET, resourcePath + "/echocookie")
{
@Override
@@ -111,7 +122,7 @@
}.run();
- new ResourceRequest(Method.GET, "/restv1/test/foo/bar/asdf")
+ new ResourceRequest(Method.GET, resourcePath + "/foo/bar/asdf")
{
@Override
@@ -124,12 +135,24 @@
}.run();
+ new ResourceRequest(Method.GET, resourcePath + "/echotwoparams/foo/bar")
+ {
+
+ @Override
+ protected void onResponse(MockHttpServletResponse response)
+ {
+ assert response.getStatus() == 200;
+ assert response.getContentAsString().equals("foobar");
+ }
+
+ }.run();
+
}
- @Test
- public void testEncoding() throws Exception
+ @Test(dataProvider = "queryPaths")
+ public void testEncoding(final String resourcePath) throws Exception
{
- new ResourceRequest(Method.GET, "/restv1/test/echoencoded/foo bar")
+ new ResourceRequest(Method.GET, resourcePath + "/echoencoded/foo bar")
{
@Override
@@ -142,10 +165,10 @@
}.run();
}
- @Test
- public void testFormHandling() throws Exception
+ @Test(dataProvider = "queryPaths")
+ public void testFormHandling(final String resourcePath) throws Exception
{
- new ResourceRequest(Method.POST, "/restv1/test/echoformparams")
+ new ResourceRequest(Method.POST, resourcePath + "/echoformparams")
{
@Override
@@ -164,7 +187,7 @@
}.run();
- new ResourceRequest(Method.POST, "/restv1/test/echoformparams2")
+ new ResourceRequest(Method.POST, resourcePath + "/echoformparams2")
{
@Override
@@ -183,7 +206,7 @@
}.run();
- new ResourceRequest(Method.POST, "/restv1/test/echoformparams3")
+ new ResourceRequest(Method.POST, resourcePath + "/echoformparams3")
{
@Override
@@ -205,13 +228,13 @@
}
- @Test
- public void testStringConverter() throws Exception
+ @Test(dataProvider = "queryPaths")
+ public void testStringConverter(final String resourcePath) throws Exception
{
final String ISO_DATE = "2007-07-10T14:54:56-0500";
final String ISO_DATE_MILLIS = "1184097296000";
- new ResourceRequest(Method.GET, "/restv1/test/foo/" + ISO_DATE)
+ new ResourceRequest(Method.GET, resourcePath + "/convertDate/" + ISO_DATE)
{
@Override
@@ -225,11 +248,11 @@
}
- @Test
- public void testProvider() throws Exception
+ @Test(dataProvider = "queryPaths")
+ public void testProvider(final String resourcePath) throws Exception
{
- new ResourceRequest(Method.GET, "/restv1/test/foo/commaseparated")
+ new ResourceRequest(Method.GET, resourcePath + "/commaSeparated")
{
@Override
Modified: branches/community/Seam_2_1/src/resteasy/org/jboss/seam/resteasy/Application.java
===================================================================
--- branches/community/Seam_2_1/src/resteasy/org/jboss/seam/resteasy/Application.java 2009-04-24 13:13:27 UTC (rev 10627)
+++ branches/community/Seam_2_1/src/resteasy/org/jboss/seam/resteasy/Application.java 2009-04-24 13:29:32 UTC (rev 10628)
@@ -23,8 +23,8 @@
public class Application extends javax.ws.rs.core.Application
{
- private Map<Class<?>, Set<Component>> providerClasses = new HashMap<Class<?>, Set<Component>>();
- private Map<Class<?>, Set<Component>> resourceClasses = new HashMap<Class<?>, Set<Component>>();
+ final private Map<Class<?>, Set<Component>> providerClasses = new HashMap<Class<?>, Set<Component>>();
+ final private Map<Class<?>, Set<Component>> resourceClasses = new HashMap<Class<?>, Set<Component>>();
private List<String> providerClassNames = new ArrayList<String>();
private List<String> resourceClassNames = new ArrayList<String>();
Modified: branches/community/Seam_2_1/src/resteasy/org/jboss/seam/resteasy/ResourceHome.java
===================================================================
--- branches/community/Seam_2_1/src/resteasy/org/jboss/seam/resteasy/ResourceHome.java 2009-04-24 13:13:27 UTC (rev 10627)
+++ branches/community/Seam_2_1/src/resteasy/org/jboss/seam/resteasy/ResourceHome.java 2009-04-24 13:29:32 UTC (rev 10628)
@@ -42,7 +42,6 @@
import org.jboss.resteasy.core.Headers;
import org.jboss.resteasy.core.StringParameterInjector;
-import org.jboss.resteasy.spi.ResteasyProviderFactory;
import org.jboss.seam.Entity;
import org.jboss.seam.annotations.Create;
import org.jboss.seam.framework.Home;
@@ -59,7 +58,9 @@
* @param <T> Entity class
* @param <T2> Entity id class
*/
-@Path("")
+// Empty @Path because it's ignored by second-stage bootstrap if not subclassed or in components.xml
+// but we need it as a marker so we'll find components.xml declarations during first stage of bootstrap.
+@Path("")
public class ResourceHome<T, T2> extends AbstractResource<T>
{
private EntityHomeWrapper<T> entityHome = null;
@@ -263,7 +264,7 @@
private T unmarshallEntity(InputStream is)
{
Class<T> entityClass = getEntityClass();
- MessageBodyReader<T> reader = ResteasyProviderFactory.getInstance().getMessageBodyReader(entityClass, entityClass, entityClass.getAnnotations(), requestContentType);
+ MessageBodyReader<T> reader = SeamResteasyProviderFactory.getInstance().getMessageBodyReader(entityClass, entityClass, entityClass.getAnnotations(), requestContentType);
if (reader == null)
{
throw new RuntimeException("Unable to find MessageBodyReader for content type " + requestContentType);
@@ -288,7 +289,7 @@
*/
private T2 unmarshallId(String id)
{
- StringParameterInjector injector = new StringParameterInjector(getEntityIdClass(), getEntityIdClass(), "id", PathParam.class, null, null, ResteasyProviderFactory.getInstance());
+ StringParameterInjector injector = new StringParameterInjector(getEntityIdClass(), getEntityIdClass(), "id", PathParam.class, null, null, SeamResteasyProviderFactory.getInstance());
return (T2) injector.extractValue(id);
}
Modified: branches/community/Seam_2_1/src/resteasy/org/jboss/seam/resteasy/ResourceQuery.java
===================================================================
--- branches/community/Seam_2_1/src/resteasy/org/jboss/seam/resteasy/ResourceQuery.java 2009-04-24 13:13:27 UTC (rev 10627)
+++ branches/community/Seam_2_1/src/resteasy/org/jboss/seam/resteasy/ResourceQuery.java 2009-04-24 13:29:32 UTC (rev 10628)
@@ -48,6 +48,8 @@
*
* @param <T> entity type
*/
+// Empty @Path because it's ignored by second-stage bootstrap if not subclassed or in components.xml
+// but we need it as a marker so we'll find components.xml declarations during first stage of bootstrap.
@Path("")
public class ResourceQuery<T> extends AbstractResource<T>
{
@@ -109,8 +111,7 @@
public Type[] getActualTypeArguments()
{
- Type[] types = { getEntityClass() };
- return types;
+ return new Type[] { getEntityClass() };
}
};
return Response.ok(new GenericEntity(result, responseType)
Modified: branches/community/Seam_2_1/src/resteasy/org/jboss/seam/resteasy/ResteasyBootstrap.java
===================================================================
--- branches/community/Seam_2_1/src/resteasy/org/jboss/seam/resteasy/ResteasyBootstrap.java 2009-04-24 13:13:27 UTC (rev 10627)
+++ branches/community/Seam_2_1/src/resteasy/org/jboss/seam/resteasy/ResteasyBootstrap.java 2009-04-24 13:29:32 UTC (rev 10628)
@@ -2,12 +2,21 @@
import org.jboss.seam.Component;
import org.jboss.seam.ScopeType;
+import org.jboss.seam.annotations.Name;
+import org.jboss.seam.annotations.Scope;
+import org.jboss.seam.annotations.Startup;
+import org.jboss.seam.annotations.AutoCreate;
+import org.jboss.seam.annotations.Install;
+import org.jboss.seam.annotations.Logger;
+import org.jboss.seam.annotations.In;
+import org.jboss.seam.annotations.Create;
import org.jboss.seam.deployment.AnnotationDeploymentHandler;
import org.jboss.seam.deployment.DeploymentStrategy;
-import org.jboss.seam.annotations.*;
import org.jboss.seam.contexts.Contexts;
import org.jboss.seam.log.Log;
import org.jboss.seam.util.Reflections;
+import org.jboss.seam.util.EJB;
+import org.jboss.resteasy.core.ThreadLocalResteasyProviderFactory;
import java.util.Collection;
import java.util.HashSet;
@@ -17,6 +26,8 @@
/**
* Scans annoated JAX-RS resources and providers, optionally registers them as Seam components.
+ * It does so by populating the <tt>Application</tt> instance, which is then processed further
+ * by the <tt>ResteasyDispatcher</tt> during startup.
*
* @author Christian Bauer
*/
@@ -24,7 +35,7 @@
@Scope(ScopeType.APPLICATION)
@Startup
@AutoCreate
-@Install(classDependencies = "org.jboss.resteasy.core.Dispatcher")
+@Install(classDependencies = "org.jboss.resteasy.spi.ResteasyProviderFactory")
public class ResteasyBootstrap
{
@@ -34,11 +45,23 @@
@In
protected Application application;
+ private SeamResteasyProviderFactory providerFactory;
+ public SeamResteasyProviderFactory getProviderFactory()
+ {
+ return providerFactory;
+ }
+
@Create
- public void onStartup()
+ public void init()
{
- log.info("deploying RESTEasy providers and resources");
+ log.info("starting RESTEasy with custom SeamResteasyProviderFactory");
+ providerFactory = new SeamResteasyProviderFactory();
+ // Always use the "deployment sensitive" factory - that means it is handled through ThreadLocal, not static
+ SeamResteasyProviderFactory.setInstance(new ThreadLocalResteasyProviderFactory(getProviderFactory()));
+
+ log.info("deploying JAX-RS application");
+
Collection<Class<?>> annotatedProviderClasses = null;
Collection<Class<?>> annotatedResourceClasses = null;
if (application.isScanProviders() || application.isScanResources())
@@ -162,9 +185,16 @@
log.debug("adding resource Seam components {0} for class {1}", components, resourceClass);
application.addResourceClass(resourceClass, components);
}
+ // Check if it is a @Path annotated EJB interface
+ else if (resourceClass.isAnnotationPresent(EJB.LOCAL) ||
+ resourceClass.isAnnotationPresent(EJB.REMOTE))
+ {
+ log.debug("ignoring @Path annotated EJB interface, add the bean " +
+ "implementation to <resteasy:resource-class-names/>: " + resourceClass.getName());
+ }
else
{
- log.debug("adding resource class with JAX-RS default lifecycle: " + resourceClass.getName());
+ log.debug("adding resource class: " + resourceClass.getName());
application.addResourceClass(resourceClass);
}
}
Modified: branches/community/Seam_2_1/src/resteasy/org/jboss/seam/resteasy/ResteasyDispatcher.java
===================================================================
--- branches/community/Seam_2_1/src/resteasy/org/jboss/seam/resteasy/ResteasyDispatcher.java 2009-04-24 13:13:27 UTC (rev 10627)
+++ branches/community/Seam_2_1/src/resteasy/org/jboss/seam/resteasy/ResteasyDispatcher.java 2009-04-24 13:29:32 UTC (rev 10628)
@@ -1,30 +1,35 @@
package org.jboss.seam.resteasy;
-import java.util.Set;
-
+import org.jboss.resteasy.core.SynchronousDispatcher;
+import org.jboss.resteasy.plugins.providers.RegisterBuiltin;
+import org.jboss.resteasy.plugins.server.resourcefactory.POJOResourceFactory;
+import org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher;
+import org.jboss.resteasy.spi.ResourceFactory;
+import org.jboss.resteasy.spi.StringConverter;
import org.jboss.seam.Component;
import org.jboss.seam.ScopeType;
-import org.jboss.seam.contexts.Contexts;
+import org.jboss.seam.Seam;
+import org.jboss.seam.core.Init;
+import org.jboss.seam.util.EJB;
import org.jboss.seam.annotations.AutoCreate;
import org.jboss.seam.annotations.Create;
import org.jboss.seam.annotations.In;
-import org.jboss.seam.annotations.Install;
import org.jboss.seam.annotations.Logger;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Scope;
import org.jboss.seam.annotations.Startup;
+import org.jboss.seam.annotations.JndiName;
import org.jboss.seam.log.Log;
-import org.jboss.resteasy.core.AsynchronousDispatcher;
-import org.jboss.resteasy.core.PropertyInjectorImpl;
-import org.jboss.resteasy.plugins.providers.RegisterBuiltin;
-import org.jboss.resteasy.plugins.server.resourcefactory.POJOResourceFactory;
-import org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher;
-import org.jboss.resteasy.spi.*;
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import java.util.Set;
+
/**
* An extended version of the RESTEasy dispatcher, configured on Seam application
* startup with a custom JAX RS <tt>Application</tt> instance. Registers custom resource
- * and provider lifecycle handlers.
+ * and provider lifecycle handlers with RESTEasy, depending on configured/detected resources
+ * from <tt>ResteasyBootstrap</tt>.
*
* @author Christian Bauer
*/
@@ -32,25 +37,41 @@
@Scope(ScopeType.APPLICATION)
@Startup(depends = "org.jboss.seam.resteasy.bootstrap")
@AutoCreate
-@Install(classDependencies = "org.jboss.resteasy.core.Dispatcher")
public class ResteasyDispatcher extends HttpServletDispatcher
{
@In
- Application application;
+ protected Application application;
+ @In
+ protected ResteasyBootstrap bootstrap;
+
@Logger
- Log log;
+ private Log log;
@Create
- public void onStartup()
+ public void init()
{
+ try
+ {
+ init(null);
+ }
+ catch (ServletException ex)
+ {
+ // Can never happen
+ }
+ }
+
+ @Override
+ public void init(ServletConfig servletConfig) throws ServletException
+ {
+ // We can skip the init, it only sets up the provider factory (did that already in bootstrap) and
+ // the other stuff we do in onStartup(). We also do NOT put the ResteasyProviderFactory, the Dispatcher,
+ // nor the Registry into the servlet context. Let's hope RESTEasy code is sane enough not to access the
+ // servlet context at runtime...
log.debug("registering RESTEasy and JAX RS resources and providers");
+ setDispatcher(new SynchronousDispatcher(bootstrap.getProviderFactory()));
- ResteasyProviderFactory providerFactory = new ResteasyProviderFactory();
- ResteasyProviderFactory.setInstance(providerFactory); // This is really necessary
- setDispatcher(new AsynchronousDispatcher(providerFactory));
-
getDispatcher().setLanguageMappings(application.getLanguageMappings());
getDispatcher().setMediaTypeMappings(application.getMediaTypeMappings());
@@ -58,145 +79,160 @@
if (application.isUseBuiltinProviders())
{
log.info("registering built-in RESTEasy providers");
- RegisterBuiltin.register(providerFactory);
+ RegisterBuiltin.register(getDispatcher().getProviderFactory());
}
+
for (Class providerClass : application.getProviderClasses())
{
- Set<Component> seamComponents = application.getProviderClassComponent(providerClass);
- if (seamComponents != null)
+ Set<Component> components = application.getProviderClassComponent(providerClass);
+ if (components != null)
{
- for (Component seamComponent : seamComponents)
- {
- if (ScopeType.STATELESS.equals(seamComponent.getScope()))
- {
- throw new RuntimeException(
- "Registration of STATELESS Seam components as RESTEasy providers not implemented!"
- );
- }
- else if (ScopeType.APPLICATION.equals(seamComponent.getScope()))
- {
- Object providerInstance = Component.getInstance(seamComponent.getName());
- boolean isStringConverter = false;
- for (Class componentIface : seamComponent.getBusinessInterfaces())
- {
- if (StringConverter.class.isAssignableFrom(componentIface))
- {
- isStringConverter = true;
- break;
- }
- }
- if (isStringConverter)
- {
- log.error("can't register Seam component as RESTEasy StringConverter, see: https://jira.jboss.org/jira/browse/JBSEAM-4020");
- //log.debug("registering Seam component as custom RESTEasy string converter provider: " + seamComponent.getName());
- //providerFactory.addStringConverter((StringConverter)providerInstance);
- }
- else
- {
- providerFactory.registerProviderInstance(providerInstance);
- }
- }
- }
+ registerSeamComponentProviders(components, providerClass);
}
else
{
- // Just plain RESTEasy, no Seam component lookup or lifecycle
- if (StringConverter.class.isAssignableFrom(providerClass))
- {
- log.debug("registering as custom RESTEasy string converter provider class: " + providerClass);
- providerFactory.addStringConverter(providerClass);
- }
- else
- {
- providerFactory.registerProvider(providerClass);
- }
+ registerProvider(providerClass);
}
}
// Resource registration
- Registry registry = getDispatcher().getRegistry();
for (final Class resourceClass : application.getClasses())
{
- log.debug("registering JAX RS resource class: " + resourceClass);
+ // First check if it's a class that is a Seam component
Set<Component> components = application.getResourceClassComponent(resourceClass);
if (components != null)
{
- log.debug("registering all {0} components of {1}", components.size(), resourceClass);
- // Register every component
- for (final Component seamComponent : components)
- {
- // Seam component lookup when call is dispatched to resource
- ResourceFactory factory = new ResourceFactory()
- {
+ registerSeamComponentResources(components, resourceClass);
+ }
+ else
+ {
+ registerResource(resourceClass);
+ }
+ }
- public Class<?> getScannableClass()
- {
- return resourceClass;
- }
+ }
- public void registered(InjectorFactory factory)
- {
- // Wrap the Resteasy PropertyInjectorImpl in a Seam interceptor (for @Context injection)
- seamComponent.addInterceptor(
- new ResteasyContextInjectionInterceptor(
- new PropertyInjectorImpl(getScannableClass(), dispatcher.getProviderFactory())
- )
- );
- // NOTE: Adding an interceptor to Component at this stage means that the interceptor is
- // always executed last in the chain. The sorting of interceptors of a Component occurs
- // only when the Component metadata is instantiated. This is OK in this case, as the
- // JAX RS @Context injection can occur last after all other interceptors executed.
+ protected void registerSeamComponentProviders(Set<Component> components, Class providerClass) {
+ for (Component seamComponent : components)
+ {
+ if (ScopeType.STATELESS.equals(seamComponent.getScope()))
+ {
+ throw new RuntimeException(
+ "Registration of STATELESS Seam components as RESTEasy providers not implemented!"
+ );
+ }
+ else if (ScopeType.APPLICATION.equals(seamComponent.getScope()))
+ {
+ Object providerInstance = Component.getInstance(seamComponent.getName());
+ boolean isStringConverter = false;
+ for (Class componentIface : seamComponent.getBusinessInterfaces())
+ {
+ if (StringConverter.class.isAssignableFrom(componentIface))
+ {
+ isStringConverter = true;
+ break;
+ }
+ }
+ if (isStringConverter)
+ {
+ log.error("can't register Seam component as RESTEasy StringConverter, see: https://jira.jboss.org/jira/browse/JBSEAM-4020");
+ //log.debug("registering Seam component as custom RESTEasy string converter provider: " + seamComponent.getName());
+ //getDispatcher().getProviderFactory().addStringConverter((StringConverter)providerInstance);
+ }
+ else
+ {
+ getDispatcher().getProviderFactory().registerProviderInstance(providerInstance);
+ }
+ }
+ }
+ }
- }
+ protected void registerSeamComponentResources(Set<Component> components, Class resourceClass) {
+ for (final Component seamComponent : components)
+ {
+ // Seam component lookup when call is dispatched to resource
+ ResourceFactory factory =
+ new SeamResteasyResourceFactory(resourceClass, seamComponent, getDispatcher().getProviderFactory());
- public Object createResource(HttpRequest request, HttpResponse response, InjectorFactory factory)
- {
- // Push this onto event context so we have it available in ResteasyContextInjectionInterceptor
- Contexts.getEventContext().set(ResteasyContextInjectionInterceptor.RE_HTTP_REQUEST_VAR, request);
- Contexts.getEventContext().set(ResteasyContextInjectionInterceptor.RE_HTTP_RESPONSE_VAR, response);
- return Component.getInstance(seamComponent.getName());
- }
+ // Register component on specific path if the component is a ResourceHome or ResourceQuery component configured in components.xml
+ if (seamComponent.getBeanClass().equals(ResourceHome.class) || seamComponent.getBeanClass().equals(ResourceQuery.class))
+ {
- public void requestFinished(HttpRequest request, HttpResponse response, Object resource)
- {
- }
-
- public void unregistered()
- {
- }
- };
- // Register component on specific path if the component is a ResourceHome or ResourceQuery component configured in components.xml
- if (seamComponent.getBeanClass().equals(ResourceHome.class) || seamComponent.getBeanClass().equals(ResourceQuery.class))
- {
- AbstractResource instance = (AbstractResource) seamComponent.newInstance();
- String path = instance.getPath();
- if (instance.getPath() != null)
- {
- log.debug("registering resource {0} on path {1}", seamComponent.getName(), path);
- registry.addResourceFactory(factory, path);
- } else {
- log.warn("Unable to register {0} resource on null path.", seamComponent.getName());
- }
- }
- else
- {
- log.debug("registering resource {0}", seamComponent.getName());
- registry.addResourceFactory(factory);
- }
+ // We can always instantiate this safely here because it can't have dependencies!
+ AbstractResource instance = (AbstractResource) seamComponent.newInstance();
+ String path = instance.getPath();
+ if (instance.getPath() != null)
+ {
+ log.debug("registering resource {0} on path {1} with Seam component lifecycle", seamComponent.getName(), path);
+ getDispatcher().getRegistry().addResourceFactory(factory, path);
}
+ else
+ {
+ log.warn("Unable to register {0} resource on null path, check components.xml", seamComponent.getName());
+ }
}
else
{
- // ResourceHome and ResourceQuery won't be registered if not declared as a component
- if (ResourceHome.class.equals(resourceClass) || ResourceQuery.class.equals(resourceClass))
- continue;
-
- // JAX-RS default lifecycle
- log.info("registering resource {0} with default JAX-RS lifecycle", resourceClass);
- registry.addResourceFactory(new POJOResourceFactory(resourceClass));
+ log.debug("registering resource {0} with Seam component lifecycle", seamComponent.getName());
+ getDispatcher().getRegistry().addResourceFactory(factory);
}
}
}
+
+ protected void registerProvider(Class providerClass) {
+ // Just plain RESTEasy, no Seam component lookup or lifecycle
+ if (StringConverter.class.isAssignableFrom(providerClass))
+ {
+ log.debug("registering as custom RESTEasy string converter provider class: " + providerClass);
+ getDispatcher().getProviderFactory().addStringConverter(providerClass);
+ }
+ else
+ {
+ getDispatcher().getProviderFactory().registerProvider(providerClass);
+ }
+ }
+
+ protected void registerResource(Class resourceClass) {
+ // ResourceHome and ResourceQuery have an empty @Path("") and are supposed to be subclassed before use
+ // (or through components.xml) - they should be ignored if they are not proper Seam components
+ if (ResourceHome.class.equals(resourceClass) || ResourceQuery.class.equals(resourceClass))
+ return;
+
+ // Plain EJBs (not a Seam component) can be registered in RESTEasy by JNDI name
+ if (resourceClass.isAnnotationPresent(EJB.STATELESS) || resourceClass.isAnnotationPresent(EJB.STATEFUL))
+ {
+ String jndiName = getJndiName(resourceClass);
+ log.debug("registering plain EJB resource as RESTEasy JNDI resource name: " + jndiName);
+ getDispatcher().getRegistry().addJndiResource(jndiName);
+
+ }
+ else
+ {
+ // JAX-RS default lifecycle
+ log.debug("registering resource {0} with default JAX-RS lifecycle", resourceClass.getName());
+ getDispatcher().getRegistry().addResourceFactory(new POJOResourceFactory(resourceClass));
+ }
+ }
+
+ protected String getJndiName(Class<?> beanClass)
+ {
+ if (beanClass.isAnnotationPresent(JndiName.class))
+ {
+ return beanClass.getAnnotation(JndiName.class).value();
+ }
+ else
+ {
+ String jndiPattern = Init.instance().getJndiPattern();
+ if (jndiPattern == null)
+ {
+ throw new IllegalArgumentException(
+ "You must specify org.jboss.seam.core.init.jndiPattern or use @JndiName: " + beanClass.getName()
+ );
+ }
+ return jndiPattern.replace("#{ejbName}", Seam.getEjbName(beanClass));
+ }
+ }
+
}
Modified: branches/community/Seam_2_1/src/resteasy/org/jboss/seam/resteasy/ResteasyResourceAdapter.java
===================================================================
--- branches/community/Seam_2_1/src/resteasy/org/jboss/seam/resteasy/ResteasyResourceAdapter.java 2009-04-24 13:13:27 UTC (rev 10627)
+++ branches/community/Seam_2_1/src/resteasy/org/jboss/seam/resteasy/ResteasyResourceAdapter.java 2009-04-24 13:29:32 UTC (rev 10628)
@@ -5,11 +5,13 @@
import org.jboss.seam.annotations.Logger;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Scope;
+import org.jboss.seam.annotations.Create;
import org.jboss.seam.annotations.intercept.BypassInterceptors;
import org.jboss.seam.log.Log;
import org.jboss.seam.servlet.ContextualHttpServletRequest;
import org.jboss.seam.web.AbstractResource;
import org.jboss.resteasy.core.SynchronousDispatcher;
+import org.jboss.resteasy.core.ThreadLocalResteasyProviderFactory;
import org.jboss.resteasy.plugins.server.servlet.HttpServletInputMessage;
import org.jboss.resteasy.plugins.server.servlet.HttpServletResponseWrapper;
import org.jboss.resteasy.plugins.server.servlet.ServletSecurityContext;
@@ -19,7 +21,6 @@
import org.jboss.resteasy.specimpl.UriInfoImpl;
import org.jboss.resteasy.spi.HttpRequest;
import org.jboss.resteasy.spi.HttpResponse;
-import org.jboss.resteasy.spi.ResteasyProviderFactory;
import org.jboss.resteasy.util.PathHelper;
import javax.servlet.ServletException;
@@ -28,6 +29,7 @@
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.PathSegment;
import javax.ws.rs.core.SecurityContext;
+import javax.ws.rs.core.UriBuilder;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URI;
@@ -49,10 +51,21 @@
@Logger
Log log;
+ protected ResteasyDispatcher dispatcher;
+ protected Application application;
+
+ @Create
+ public void init()
+ {
+ // No injection, so lookup on first request
+ dispatcher = (ResteasyDispatcher) Component.getInstance(ResteasyDispatcher.class);
+ application = (Application) Component.getInstance(Application.class);
+ }
+
@Override
public String getResourcePath()
{
- Application appConfig = (Application)Component.getInstance(Application.class);
+ Application appConfig = (Application) Component.getInstance(Application.class);
return appConfig.getResourcePathPrefix();
}
@@ -61,13 +74,18 @@
throws ServletException, IOException
{
- // Wrap in RESTEasy contexts
- try {
+ try
+ {
log.debug("processing REST request");
- ResteasyProviderFactory.pushContext(HttpServletRequest.class, request);
- ResteasyProviderFactory.pushContext(HttpServletResponse.class, response);
- ResteasyProviderFactory.pushContext(SecurityContext.class, new ServletSecurityContext(request));
+ // Wrap in RESTEasy thread-local factory handling
+ ThreadLocalResteasyProviderFactory.push(dispatcher.getDispatcher().getProviderFactory());
+
+ // Wrap in RESTEasy contexts (this also puts stuff in a thread-local)
+ SeamResteasyProviderFactory.pushContext(HttpServletRequest.class, request);
+ SeamResteasyProviderFactory.pushContext(HttpServletResponse.class, response);
+ SeamResteasyProviderFactory.pushContext(SecurityContext.class, new ServletSecurityContext(request));
+
// Wrap in Seam contexts
new ContextualHttpServletRequest(request)
{
@@ -76,51 +94,80 @@
{
HttpHeaders headers = ServletUtil.extractHttpHeaders(request);
- URI absolutePath;
- try
- {
- URL absolute = new URL(request.getRequestURL().toString());
+ UriInfoImpl uriInfo = extractUriInfo(request);
- UriBuilderImpl builder = new UriBuilderImpl();
- builder.scheme(absolute.getProtocol());
- builder.host(absolute.getHost());
- builder.port(absolute.getPort());
- builder.path(absolute.getPath());
- builder.replaceQuery(absolute.getQuery());
- absolutePath = builder.build();
- }
- catch (MalformedURLException e)
- {
- throw new RuntimeException(e);
- }
+ HttpResponse theResponse = new HttpServletResponseWrapper(
+ response,
+ dispatcher.getDispatcher().getProviderFactory()
+ );
- String path = PathHelper.getEncodedPathInfo(absolutePath.getRawPath(), request.getContextPath());
+ HttpRequest in = new HttpServletInputMessage(
+ request,
+ theResponse,
+ headers,
+ uriInfo,
+ request.getMethod().toUpperCase(),
+ (SynchronousDispatcher) dispatcher.getDispatcher()
+ );
- Application appConfig = (Application)Component.getInstance(Application.class);
- if (appConfig.isStripSeamResourcePath()) {
- log.trace("removing SeamResourceServlet url-pattern and dispatcher prefix from request path");
- path = path.substring(path.indexOf(getResourcePath())+getResourcePath().length());
- }
-
- log.debug("final request path: " + path);
- List<PathSegment> pathSegments = PathSegmentImpl.parseSegments(path);
- UriInfoImpl uriInfo = new UriInfoImpl(absolutePath, path, request.getQueryString(), pathSegments);
-
- HttpRequest in;
- ResteasyDispatcher dispatcher =
- (ResteasyDispatcher) Component.getInstance(ResteasyDispatcher.class);
- HttpResponse theResponse =
- new HttpServletResponseWrapper(response, dispatcher.getDispatcher().getProviderFactory());
- in = new HttpServletInputMessage(
- request, theResponse, headers, uriInfo, request.getMethod().toUpperCase(), (SynchronousDispatcher)dispatcher.getDispatcher());
-
dispatcher.getDispatcher().invoke(in, theResponse);
}
}.run();
- } finally {
- ResteasyProviderFactory.clearContextData();
+ }
+ finally
+ {
+ // Clean up the thread-locals
+ SeamResteasyProviderFactory.clearContextData();
+ ThreadLocalResteasyProviderFactory.pop();
log.debug("completed processing of REST request");
}
}
+
+ // Replaces the static ServletUtil.extractUriInfo(), removes the Seam-related sub-path
+ protected UriInfoImpl extractUriInfo(HttpServletRequest request)
+ {
+ String contextPath = request.getContextPath();
+ URI absolutePath;
+ try
+ {
+ URL absolute = new URL(request.getRequestURL().toString());
+
+ UriBuilderImpl builder = new UriBuilderImpl();
+ builder.scheme(absolute.getProtocol());
+ builder.host(absolute.getHost());
+ builder.port(absolute.getPort());
+ builder.path(absolute.getPath());
+ builder.replaceQuery(absolute.getQuery());
+ absolutePath = builder.build();
+ }
+ catch (MalformedURLException e)
+ {
+ throw new RuntimeException(e);
+ }
+
+ String path = PathHelper.getEncodedPathInfo(absolutePath.getRawPath(), contextPath);
+
+ if (application.isStripSeamResourcePath())
+ {
+ log.debug("removing SeamResourceServlet url-pattern and dispatcher prefix from request path");
+ path = path.substring(path.indexOf(getResourcePath()) + getResourcePath().length());
+ }
+
+ List<PathSegment> pathSegments = PathSegmentImpl.parseSegments(path);
+ URI baseURI = absolutePath;
+ if (!path.trim().equals(""))
+ {
+ String tmpContextPath = contextPath;
+ if (!tmpContextPath.endsWith("/")) tmpContextPath += "/";
+ baseURI = UriBuilder.fromUri(absolutePath).replacePath(tmpContextPath).build();
+ }
+
+ log.debug("UriInfo, absolute URI : " + absolutePath);
+ log.debug("UriInfo, base URI : " + baseURI);
+ log.debug("UriInfo, relative path/@Path: " + path);
+ log.debug("UriInfo, query string : " + request.getQueryString());
+
+ return new UriInfoImpl(absolutePath, baseURI, path, request.getQueryString(), pathSegments);
+ }
}
Added: branches/community/Seam_2_1/src/resteasy/org/jboss/seam/resteasy/SeamResteasyProviderFactory.java
===================================================================
--- branches/community/Seam_2_1/src/resteasy/org/jboss/seam/resteasy/SeamResteasyProviderFactory.java (rev 0)
+++ branches/community/Seam_2_1/src/resteasy/org/jboss/seam/resteasy/SeamResteasyProviderFactory.java 2009-04-24 13:29:32 UTC (rev 10628)
@@ -0,0 +1,25 @@
+package org.jboss.seam.resteasy;
+
+import org.jboss.resteasy.spi.ResteasyProviderFactory;
+
+/**
+ * TODO: We need to significantly extend and change that class so we can lookup provider instances
+ * through Seam at runtime. The original class has only been designed for registration of "singleton"
+ * providers during startup.
+ *
+ * @author Christian Bauer
+ */
+public class SeamResteasyProviderFactory extends ResteasyProviderFactory
+{
+
+ public static void setInstance(ResteasyProviderFactory factory)
+ {
+ ResteasyProviderFactory.setInstance(factory);
+ }
+
+ public static ResteasyProviderFactory getInstance()
+ {
+ return ResteasyProviderFactory.getInstance();
+ }
+
+}
Added: branches/community/Seam_2_1/src/resteasy/org/jboss/seam/resteasy/SeamResteasyResourceFactory.java
===================================================================
--- branches/community/Seam_2_1/src/resteasy/org/jboss/seam/resteasy/SeamResteasyResourceFactory.java (rev 0)
+++ branches/community/Seam_2_1/src/resteasy/org/jboss/seam/resteasy/SeamResteasyResourceFactory.java 2009-04-24 13:29:32 UTC (rev 10628)
@@ -0,0 +1,73 @@
+package org.jboss.seam.resteasy;
+
+import org.jboss.resteasy.spi.ResourceFactory;
+import org.jboss.resteasy.spi.InjectorFactory;
+import org.jboss.resteasy.spi.HttpRequest;
+import org.jboss.resteasy.spi.HttpResponse;
+import org.jboss.resteasy.spi.ResteasyProviderFactory;
+import org.jboss.resteasy.core.PropertyInjectorImpl;
+
+import org.jboss.seam.contexts.Contexts;
+import org.jboss.seam.Component;
+import org.jboss.seam.log.Log;
+import org.jboss.seam.log.Logging;
+
+/**
+ * Looks up Seam component in Seam contexts when a JAX RS resource is requested.
+ *
+ * @author Christian Bauer
+ */
+public class SeamResteasyResourceFactory implements ResourceFactory
+{
+ Log log = Logging.getLog(SeamResteasyResourceFactory.class);
+
+ private final Class<?> resourceClass;
+ private final Component seamComponent;
+ private final ResteasyProviderFactory providerFactory;
+
+ public SeamResteasyResourceFactory(Class<?> resourceClass, Component seamComponent, ResteasyProviderFactory providerFactory)
+ {
+ this.resourceClass = resourceClass;
+ this.seamComponent = seamComponent;
+ this.providerFactory = providerFactory;
+ }
+
+ public Class<?> getScannableClass()
+ {
+ return resourceClass;
+ }
+
+ public void registered(InjectorFactory factory)
+ {
+ // Wrap the Resteasy PropertyInjectorImpl in a Seam interceptor (for @Context injection)
+ seamComponent.addInterceptor(
+ new ResteasyContextInjectionInterceptor(
+ new PropertyInjectorImpl(getScannableClass(), providerFactory)
+ )
+ );
+
+ // NOTE: Adding an interceptor to Component at this stage means that the interceptor is
+ // always executed last in the chain. The sorting of interceptors of a Component occurs
+ // only when the Component metadata is instantiated. This is OK in this case, as the
+ // JAX RS @Context injection can occur last after all other interceptors executed.
+
+ }
+
+ public Object createResource(HttpRequest request, HttpResponse response, InjectorFactory factory)
+ {
+ // Push this onto event context so we have it available in ResteasyContextInjectionInterceptor
+ Contexts.getEventContext().set(ResteasyContextInjectionInterceptor.RE_HTTP_REQUEST_VAR, request);
+ Contexts.getEventContext().set(ResteasyContextInjectionInterceptor.RE_HTTP_RESPONSE_VAR, response);
+ log.debug("creating RESTEasy resource instance by looking up Seam component: " + seamComponent.getName());
+ return Component.getInstance(seamComponent.getName());
+ }
+
+ public void requestFinished(HttpRequest request, HttpResponse response, Object resource)
+ {
+ }
+
+ public void unregistered()
+ {
+ }
+
+}
[View Less]
15 years, 10 months
Seam SVN: r10627 - in modules/trunk/security/src/main/java/org/jboss/seam/security: management and 3 other directories.
by seam-commits@lists.jboss.org
Author: shane.bryzak(a)jboss.com
Date: 2009-04-24 09:13:27 -0400 (Fri, 24 Apr 2009)
New Revision: 10627
Added:
modules/trunk/security/src/main/java/org/jboss/seam/security/events/PrePersistUserEvent.java
modules/trunk/security/src/main/java/org/jboss/seam/security/events/PrePersistUserRoleEvent.java
modules/trunk/security/src/main/java/org/jboss/seam/security/events/UserAuthenticatedEvent.java
modules/trunk/security/src/main/java/org/jboss/seam/security/events/UserCreatedEvent.java
…
[View More] modules/trunk/security/src/main/java/org/jboss/seam/security/util/AnnotatedBeanProperty.java
modules/trunk/security/src/main/java/org/jboss/seam/security/util/Reflections.java
modules/trunk/security/src/main/java/org/jboss/seam/security/util/TypedBeanProperty.java
Removed:
modules/trunk/security/src/main/java/org/jboss/seam/security/management/package-info.java
modules/trunk/security/src/main/java/org/jboss/seam/security/permission/package-info.java
Modified:
modules/trunk/security/src/main/java/org/jboss/seam/security/management/IdentityManager.java
modules/trunk/security/src/main/java/org/jboss/seam/security/management/JpaIdentityStore.java
modules/trunk/security/src/main/java/org/jboss/seam/security/management/LdapIdentityStore.java
modules/trunk/security/src/main/java/org/jboss/seam/security/management/action/RoleAction.java
modules/trunk/security/src/main/java/org/jboss/seam/security/management/action/RoleSearch.java
modules/trunk/security/src/main/java/org/jboss/seam/security/management/action/UserAction.java
modules/trunk/security/src/main/java/org/jboss/seam/security/management/action/UserSearch.java
modules/trunk/security/src/main/java/org/jboss/seam/security/util/Strings.java
Log:
more porting
Added: modules/trunk/security/src/main/java/org/jboss/seam/security/events/PrePersistUserEvent.java
===================================================================
--- modules/trunk/security/src/main/java/org/jboss/seam/security/events/PrePersistUserEvent.java (rev 0)
+++ modules/trunk/security/src/main/java/org/jboss/seam/security/events/PrePersistUserEvent.java 2009-04-24 13:13:27 UTC (rev 10627)
@@ -0,0 +1,21 @@
+package org.jboss.seam.security.events;
+
+/**
+ * This event is raised just before a new user is persisted
+ *
+ * @author Shane Bryzak
+ */
+public class PrePersistUserEvent
+{
+ private Object user;
+
+ public PrePersistUserEvent(Object user)
+ {
+ this.user = user;
+ }
+
+ public Object getUser()
+ {
+ return user;
+ }
+}
Added: modules/trunk/security/src/main/java/org/jboss/seam/security/events/PrePersistUserRoleEvent.java
===================================================================
--- modules/trunk/security/src/main/java/org/jboss/seam/security/events/PrePersistUserRoleEvent.java (rev 0)
+++ modules/trunk/security/src/main/java/org/jboss/seam/security/events/PrePersistUserRoleEvent.java 2009-04-24 13:13:27 UTC (rev 10627)
@@ -0,0 +1,21 @@
+package org.jboss.seam.security.events;
+
+/**
+ * This event is raised just before a user role is persisted
+ *
+ * @author Shane Bryzak
+ */
+public class PrePersistUserRoleEvent
+{
+ private Object xref;
+
+ public PrePersistUserRoleEvent(Object xref)
+ {
+ this.xref = xref;
+ }
+
+ public Object getXref()
+ {
+ return xref;
+ }
+}
Added: modules/trunk/security/src/main/java/org/jboss/seam/security/events/UserAuthenticatedEvent.java
===================================================================
--- modules/trunk/security/src/main/java/org/jboss/seam/security/events/UserAuthenticatedEvent.java (rev 0)
+++ modules/trunk/security/src/main/java/org/jboss/seam/security/events/UserAuthenticatedEvent.java 2009-04-24 13:13:27 UTC (rev 10627)
@@ -0,0 +1,21 @@
+package org.jboss.seam.security.events;
+
+/**
+ * This event is raised when a user is authenticated
+ *
+ * @author Shane Bryzak
+ */
+public class UserAuthenticatedEvent
+{
+ private Object user;
+
+ public UserAuthenticatedEvent(Object user)
+ {
+ this.user = user;
+ }
+
+ public Object getUser()
+ {
+ return user;
+ }
+}
Added: modules/trunk/security/src/main/java/org/jboss/seam/security/events/UserCreatedEvent.java
===================================================================
--- modules/trunk/security/src/main/java/org/jboss/seam/security/events/UserCreatedEvent.java (rev 0)
+++ modules/trunk/security/src/main/java/org/jboss/seam/security/events/UserCreatedEvent.java 2009-04-24 13:13:27 UTC (rev 10627)
@@ -0,0 +1,21 @@
+package org.jboss.seam.security.events;
+
+/**
+ * This event is raised immediately after a user is created
+ *
+ * @author Shane Bryzak
+ */
+public class UserCreatedEvent
+{
+ private Object user;
+
+ public UserCreatedEvent(Object user)
+ {
+ this.user = user;
+ }
+
+ public Object getUser()
+ {
+ return user;
+ }
+}
Modified: modules/trunk/security/src/main/java/org/jboss/seam/security/management/IdentityManager.java
===================================================================
--- modules/trunk/security/src/main/java/org/jboss/seam/security/management/IdentityManager.java 2009-04-24 12:36:43 UTC (rev 10626)
+++ modules/trunk/security/src/main/java/org/jboss/seam/security/management/IdentityManager.java 2009-04-24 13:13:27 UTC (rev 10627)
@@ -10,6 +10,7 @@
import javax.context.RequestScoped;
import javax.inject.Current;
import javax.inject.Initializer;
+import javax.inject.manager.Bean;
import javax.inject.manager.Manager;
import org.jboss.webbeans.log.LogProvider;
@@ -55,7 +56,8 @@
// Default to JpaIdentityStore
if (identityStore == null)
{
- identityStore = (IdentityStore) Component.getInstance(JpaIdentityStore.class, true);
+ Bean<JpaIdentityStore> jpaIdentityStoreBean = manager.resolveByType(JpaIdentityStore.class).iterator().next();
+ identityStore = (IdentityStore) manager.getInstance(jpaIdentityStoreBean);
}
if (roleIdentityStore == null && identityStore != null)
Modified: modules/trunk/security/src/main/java/org/jboss/seam/security/management/JpaIdentityStore.java
===================================================================
--- modules/trunk/security/src/main/java/org/jboss/seam/security/management/JpaIdentityStore.java 2009-04-24 12:36:43 UTC (rev 10626)
+++ modules/trunk/security/src/main/java/org/jboss/seam/security/management/JpaIdentityStore.java 2009-04-24 13:13:27 UTC (rev 10627)
@@ -1,8 +1,5 @@
package org.jboss.seam.security.management;
-import static org.jboss.seam.ScopeType.APPLICATION;
-import static org.jboss.seam.annotations.Install.BUILT_IN;
-
import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
@@ -14,66 +11,63 @@
import java.util.List;
import java.util.Set;
+import javax.annotation.Named;
+import javax.context.ApplicationScoped;
+import javax.event.Observes;
+import javax.inject.Current;
+import javax.inject.Initializer;
+import javax.inject.manager.Bean;
+import javax.inject.manager.Manager;
import javax.persistence.EntityManager;
import javax.persistence.NoResultException;
-import org.jboss.seam.annotations.Create;
-import org.jboss.seam.annotations.Install;
-import org.jboss.seam.annotations.Name;
-import org.jboss.seam.annotations.Observer;
-import org.jboss.seam.annotations.Scope;
-import org.jboss.seam.annotations.intercept.BypassInterceptors;
-import org.jboss.seam.annotations.security.management.PasswordSalt;
-import org.jboss.seam.annotations.security.management.RoleConditional;
-import org.jboss.seam.annotations.security.management.RoleGroups;
-import org.jboss.seam.annotations.security.management.RoleName;
-import org.jboss.seam.annotations.security.management.UserEnabled;
-import org.jboss.seam.annotations.security.management.UserFirstName;
-import org.jboss.seam.annotations.security.management.UserLastName;
-import org.jboss.seam.annotations.security.management.UserPassword;
-import org.jboss.seam.annotations.security.management.UserPrincipal;
-import org.jboss.seam.annotations.security.management.UserRoles;
+import org.jboss.seam.security.annotations.management.PasswordSalt;
+import org.jboss.seam.security.annotations.management.RoleConditional;
+import org.jboss.seam.security.annotations.management.RoleGroups;
+import org.jboss.seam.security.annotations.management.RoleName;
+import org.jboss.seam.security.annotations.management.UserEnabled;
+import org.jboss.seam.security.annotations.management.UserFirstName;
+import org.jboss.seam.security.annotations.management.UserLastName;
+import org.jboss.seam.security.annotations.management.UserPassword;
+import org.jboss.seam.security.annotations.management.UserPrincipal;
+import org.jboss.seam.security.annotations.management.UserRoles;
import org.jboss.seam.contexts.Contexts;
-import org.jboss.seam.core.Events;
import org.jboss.seam.core.Expressions;
import org.jboss.seam.core.Expressions.ValueExpression;
-import org.jboss.seam.log.LogProvider;
-import org.jboss.seam.log.Logging;
+import org.jboss.webbeans.log.LogProvider;
+import org.jboss.webbeans.log.Logging;
import org.jboss.seam.security.Identity;
import org.jboss.seam.security.Role;
import org.jboss.seam.security.SimplePrincipal;
import org.jboss.seam.security.crypto.BinTools;
-import org.jboss.seam.util.AnnotatedBeanProperty;
-import org.jboss.seam.util.TypedBeanProperty;
+import org.jboss.seam.security.events.PostAuthenticateEvent;
+import org.jboss.seam.security.events.PrePersistUserEvent;
+import org.jboss.seam.security.events.PrePersistUserRoleEvent;
+import org.jboss.seam.security.events.UserAuthenticatedEvent;
+import org.jboss.seam.security.events.UserCreatedEvent;
+import org.jboss.seam.security.util.AnnotatedBeanProperty;
+import org.jboss.seam.security.util.TypedBeanProperty;
/**
* The default identity store implementation, uses JPA as its persistence mechanism.
*
* @author Shane Bryzak
*/
-@Name("org.jboss.seam.security.identityStore")
-@Install(precedence = BUILT_IN, value=false)
-@Scope(APPLICATION)
-@BypassInterceptors
+@Named("identityStore")
+@ApplicationScoped
public class JpaIdentityStore implements IdentityStore, Serializable
-{
- public static final String AUTHENTICATED_USER = "org.jboss.seam.security.management.authenticatedUser";
-
- public static final String EVENT_USER_CREATED = "org.jboss.seam.security.management.userCreated";
- public static final String EVENT_PRE_PERSIST_USER = "org.jboss.seam.security.management.prePersistUser";
- public static final String EVENT_USER_AUTHENTICATED = "org.jboss.seam.security.management.userAuthenticated";
-
- public static final String EVENT_PRE_PERSIST_USER_ROLE = "org.jboss.seam.security.management.prePersistUserRole";
-
+{
private static final LogProvider log = Logging.getLogProvider(JpaIdentityStore.class);
protected FeatureSet featureSet;
private ValueExpression<EntityManager> entityManager;
+ private Bean<EntityManager> entityManagerBean;
+ @Current Manager manager;
- private Class userClass;
- private Class roleClass;
- private Class xrefClass;
+ private Class<?> userClass;
+ private Class<?> roleClass;
+ private Class<?> xrefClass;
private TypedBeanProperty xrefUserProperty;
private TypedBeanProperty xrefRoleProperty;
@@ -103,7 +97,7 @@
return featureSet.supports(feature);
}
- @Create
+ @Initializer
public void init()
{
if (featureSet == null)
@@ -128,13 +122,13 @@
private void initProperties()
{
- userPrincipalProperty = new AnnotatedBeanProperty(userClass, UserPrincipal.class);
- userPasswordProperty = new AnnotatedBeanProperty(userClass, UserPassword.class);
- passwordSaltProperty = new AnnotatedBeanProperty(userClass, PasswordSalt.class);
- userRolesProperty = new AnnotatedBeanProperty(userClass, UserRoles.class);
- userEnabledProperty = new AnnotatedBeanProperty(userClass, UserEnabled.class);
- userFirstNameProperty = new AnnotatedBeanProperty(userClass, UserFirstName.class);
- userLastNameProperty = new AnnotatedBeanProperty(userClass, UserLastName.class);
+ userPrincipalProperty = new AnnotatedBeanProperty<UserPrincipal>(userClass, UserPrincipal.class);
+ userPasswordProperty = new AnnotatedBeanProperty<UserPassword>(userClass, UserPassword.class);
+ passwordSaltProperty = new AnnotatedBeanProperty<PasswordSalt>(userClass, PasswordSalt.class);
+ userRolesProperty = new AnnotatedBeanProperty<UserRoles>(userClass, UserRoles.class);
+ userEnabledProperty = new AnnotatedBeanProperty<UserEnabled>(userClass, UserEnabled.class);
+ userFirstNameProperty = new AnnotatedBeanProperty<UserFirstName>(userClass, UserFirstName.class);
+ userLastNameProperty = new AnnotatedBeanProperty<UserLastName>(userClass, UserLastName.class);
if (!userPrincipalProperty.isSet())
{
@@ -150,9 +144,9 @@
if (roleClass != null)
{
- roleNameProperty = new AnnotatedBeanProperty(roleClass, RoleName.class);
- roleGroupsProperty = new AnnotatedBeanProperty(roleClass, RoleGroups.class);
- roleConditionalProperty = new AnnotatedBeanProperty(roleClass, RoleConditional.class);
+ roleNameProperty = new AnnotatedBeanProperty<RoleName>(roleClass, RoleName.class);
+ roleGroupsProperty = new AnnotatedBeanProperty<RoleGroups>(roleClass, RoleGroups.class);
+ roleConditionalProperty = new AnnotatedBeanProperty<RoleConditional>(roleClass, RoleConditional.class);
if (!roleNameProperty.isSet())
{
@@ -162,7 +156,7 @@
Type type = userRolesProperty.getPropertyType();
if (type instanceof ParameterizedType &&
- Collection.class.isAssignableFrom((Class) ((ParameterizedType) type).getRawType()))
+ Collection.class.isAssignableFrom((Class<?>) ((ParameterizedType) type).getRawType()))
{
Type genType = Object.class;
@@ -176,7 +170,7 @@
// is going through a cross-reference table
if (!genType.equals(roleClass))
{
- xrefClass = (Class) genType;
+ xrefClass = (Class<?>) genType;
xrefUserProperty = new TypedBeanProperty(xrefClass, userClass);
xrefRoleProperty = new TypedBeanProperty(xrefClass, roleClass);
@@ -227,12 +221,12 @@
if (userEnabledProperty.isSet()) userEnabledProperty.setValue(user, true);
}
- if (Events.exists()) Events.instance().raiseEvent(EVENT_PRE_PERSIST_USER, user);
+ manager.fireEvent(new PrePersistUserEvent(user));
persistEntity(user);
+
+ manager.fireEvent(new UserCreatedEvent(user));
- if (Events.exists()) Events.instance().raiseEvent(EVENT_USER_CREATED, user);
-
return true;
}
catch (Exception ex)
@@ -331,7 +325,7 @@
throw new NoSuchRoleException("Could not grant role, role '" + role + "' does not exist");
}
- Collection userRoles = (Collection) userRolesProperty.getValue(user);
+ Collection<?> userRoles = (Collection<?>) userRolesProperty.getValue(user);
if (userRoles == null)
{
Type propType = userRolesProperty.getPropertyType();
@@ -382,7 +376,7 @@
xrefUserProperty.setValue(xref, user);
xrefRoleProperty.setValue(xref, roleToGrant);
- Events.instance().raiseEvent(EVENT_PRE_PERSIST_USER_ROLE, xref);
+ manager.fireEvent(new PrePersistUserRoleEvent(xref));
((Collection) userRolesProperty.getValue(user)).add(mergeEntity(xref));
}
@@ -830,21 +824,19 @@
boolean success = passwordHash.equals(userPasswordProperty.getValue(user));
- if (success && Events.exists())
+ if (success)
{
if (Contexts.isEventContextActive())
{
Contexts.getEventContext().set(AUTHENTICATED_USER, user);
}
- Events.instance().raiseEvent(EVENT_USER_AUTHENTICATED, user);
- }
+ manager.fireEvent(new UserAuthenticatedEvent(user));
return success;
}
- @Observer(Identity.EVENT_POST_AUTHENTICATE)
- public void setUserAccountForSession()
+ public void setUserAccountForSession(@Observes PostAuthenticateEvent event)
{
if (Contexts.isEventContextActive() && Contexts.isSessionContextActive())
{
@@ -1049,15 +1041,5 @@
private EntityManager lookupEntityManager()
{
return entityManager.getValue();
- }
-
- public ValueExpression getEntityManager()
- {
- return entityManager;
- }
-
- public void setEntityManager(ValueExpression expression)
- {
- this.entityManager = expression;
- }
+ }
}
Modified: modules/trunk/security/src/main/java/org/jboss/seam/security/management/LdapIdentityStore.java
===================================================================
--- modules/trunk/security/src/main/java/org/jboss/seam/security/management/LdapIdentityStore.java 2009-04-24 12:36:43 UTC (rev 10626)
+++ modules/trunk/security/src/main/java/org/jboss/seam/security/management/LdapIdentityStore.java 2009-04-24 13:13:27 UTC (rev 10627)
@@ -1,8 +1,5 @@
package org.jboss.seam.security.management;
-import static org.jboss.seam.ScopeType.APPLICATION;
-import static org.jboss.seam.annotations.Install.BUILT_IN;
-
import java.io.Serializable;
import java.security.Principal;
import java.util.ArrayList;
@@ -11,6 +8,8 @@
import java.util.Properties;
import java.util.Set;
+import javax.annotation.Named;
+import javax.context.ApplicationScoped;
import javax.naming.Context;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
@@ -24,24 +23,20 @@
import javax.naming.directory.SearchResult;
import javax.naming.ldap.InitialLdapContext;
-import org.jboss.seam.annotations.Install;
-import org.jboss.seam.annotations.Name;
-import org.jboss.seam.annotations.Scope;
-import org.jboss.seam.annotations.intercept.BypassInterceptors;
-import org.jboss.seam.log.LogProvider;
-import org.jboss.seam.log.Logging;
+import org.jboss.webbeans.log.LogProvider;
+import org.jboss.webbeans.log.Logging;
/**
* An IdentityStore implementation that integrates with a directory service.
*
* @author Shane Bryzak
*/
-@Name("org.jboss.seam.security.identityStore")
-@Install(precedence = BUILT_IN, value=false)
-@Scope(APPLICATION)
-@BypassInterceptors
+@Named("identityStore")
+@ApplicationScoped
public class LdapIdentityStore implements IdentityStore, Serializable
{
+ private static final long serialVersionUID = 1854090869689846220L;
+
// constants for LDAP syntax 1.3.6.1.4.1.1466.115.121.1.7 (boolean)
private static final String LDAP_BOOLEAN_TRUE = "TRUE";
private static final String LDAP_BOOLEAN_FALSE = "FALSE";
Modified: modules/trunk/security/src/main/java/org/jboss/seam/security/management/action/RoleAction.java
===================================================================
--- modules/trunk/security/src/main/java/org/jboss/seam/security/management/action/RoleAction.java 2009-04-24 12:36:43 UTC (rev 10626)
+++ modules/trunk/security/src/main/java/org/jboss/seam/security/management/action/RoleAction.java 2009-04-24 13:13:27 UTC (rev 10627)
@@ -1,40 +1,39 @@
package org.jboss.seam.security.management.action;
-import static org.jboss.seam.ScopeType.CONVERSATION;
-import static org.jboss.seam.annotations.Install.BUILT_IN;
-
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
-import org.jboss.seam.annotations.Begin;
-import org.jboss.seam.annotations.In;
-import org.jboss.seam.annotations.Install;
-import org.jboss.seam.annotations.Name;
-import org.jboss.seam.annotations.Scope;
-import org.jboss.seam.core.Conversation;
+import javax.annotation.Named;
+import javax.context.Conversation;
+import javax.context.ConversationScoped;
+import javax.inject.Current;
+
import org.jboss.seam.security.management.IdentityManager;
-@Name("org.jboss.seam.security.management.roleAction")
-@Scope(CONVERSATION)
-@Install(precedence = BUILT_IN)
+@Named
+@ConversationScoped
public class RoleAction implements Serializable
{
+ private static final long serialVersionUID = -4215849488301658353L;
+
private String originalRole;
private String role;
private List<String> groups;
- @In IdentityManager identityManager;
+ @Current IdentityManager identityManager;
+ @Current Conversation conversation;
- @Begin
public void createRole()
{
+ conversation.begin();
groups = new ArrayList<String>();
}
- @Begin
public void editRole(String role)
{
+ conversation.begin();
+
this.originalRole = role;
this.role = role;
groups = identityManager.getRoleGroups(role);
@@ -68,7 +67,7 @@
identityManager.addRoleToGroup(role, r);
}
- Conversation.instance().end();
+ conversation.end();
}
return "success";
@@ -91,7 +90,7 @@
if (grantedRoles == null || !grantedRoles.contains(r)) identityManager.addRoleToGroup(role, r);
}
- Conversation.instance().end();
+ conversation.end();
return "success";
}
Modified: modules/trunk/security/src/main/java/org/jboss/seam/security/management/action/RoleSearch.java
===================================================================
--- modules/trunk/security/src/main/java/org/jboss/seam/security/management/action/RoleSearch.java 2009-04-24 12:36:43 UTC (rev 10626)
+++ modules/trunk/security/src/main/java/org/jboss/seam/security/management/action/RoleSearch.java 2009-04-24 13:13:27 UTC (rev 10627)
@@ -1,31 +1,27 @@
package org.jboss.seam.security.management.action;
-import static org.jboss.seam.ScopeType.SESSION;
-import static org.jboss.seam.annotations.Install.BUILT_IN;
-
import java.io.Serializable;
import java.util.List;
-import org.jboss.seam.annotations.In;
-import org.jboss.seam.annotations.Install;
-import org.jboss.seam.annotations.Name;
-import org.jboss.seam.annotations.Scope;
-import org.jboss.seam.annotations.datamodel.DataModel;
-import org.jboss.seam.annotations.datamodel.DataModelSelection;
+import javax.annotation.Named;
+import javax.context.SessionScoped;
+import javax.inject.Current;
+
import org.jboss.seam.security.management.IdentityManager;
-@Name("org.jboss.seam.security.management.roleSearch")
-@Scope(SESSION)
-@Install(precedence = BUILT_IN)
+@Named
+@SessionScoped
public class RoleSearch implements Serializable
{
+ private static final long serialVersionUID = -1014495134519417515L;
+
@DataModel
List<String> roles;
@DataModelSelection
String selectedRole;
- @In IdentityManager identityManager;
+ @Current IdentityManager identityManager;
public void loadRoles()
{
Modified: modules/trunk/security/src/main/java/org/jboss/seam/security/management/action/UserAction.java
===================================================================
--- modules/trunk/security/src/main/java/org/jboss/seam/security/management/action/UserAction.java 2009-04-24 12:36:43 UTC (rev 10626)
+++ modules/trunk/security/src/main/java/org/jboss/seam/security/management/action/UserAction.java 2009-04-24 13:13:27 UTC (rev 10627)
@@ -1,19 +1,15 @@
package org.jboss.seam.security.management.action;
-import static org.jboss.seam.ScopeType.CONVERSATION;
-import static org.jboss.seam.annotations.Install.BUILT_IN;
-
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
-import org.jboss.seam.annotations.Begin;
-import org.jboss.seam.annotations.In;
-import org.jboss.seam.annotations.Install;
-import org.jboss.seam.annotations.Name;
-import org.jboss.seam.annotations.Scope;
-import org.jboss.seam.core.Conversation;
-import org.jboss.seam.international.StatusMessages;
+import javax.annotation.Named;
+import javax.context.Conversation;
+import javax.context.ConversationScoped;
+import javax.inject.Current;
+
+//import org.jboss.seam.international.StatusMessages;
import org.jboss.seam.security.management.IdentityManager;
/**
@@ -21,9 +17,8 @@
*
* @author Shane Bryzak
*/
-@Name("org.jboss.seam.security.management.userAction")
-@Scope(CONVERSATION)
-@Install(precedence = BUILT_IN)
+@Named
+@ConversationScoped
public class UserAction implements Serializable
{
private String firstname;
@@ -36,18 +31,19 @@
private boolean newUserFlag;
- @In IdentityManager identityManager;
+ @Current IdentityManager identityManager;
+ @Current Conversation conversation;
- @Begin
public void createUser()
{
+ conversation.begin();
roles = new ArrayList<String>();
newUserFlag = true;
}
- @Begin
public void editUser(String username)
- {
+ {
+ conversation.begin();
this.username = username;
roles = identityManager.getGrantedRoles(username);
enabled = identityManager.isUserEnabled(username);
@@ -70,7 +66,8 @@
{
if (password == null || !password.equals(confirm))
{
- StatusMessages.instance().addToControl("password", "Passwords do not match");
+ // TODO - add control message
+ //StatusMessages.instance().addToControl("password", "Passwords do not match");
return "failure";
}
@@ -88,7 +85,7 @@
identityManager.disableUser(username);
}
- Conversation.instance().end();
+ conversation.end();
return "success";
}
@@ -103,7 +100,8 @@
{
if (!password.equals(confirm))
{
- StatusMessages.instance().addToControl("password", "Passwords do not match");
+ // TODO - add control message
+ // StatusMessages.instance().addToControl("password", "Passwords do not match");
return "failure";
}
else
@@ -139,7 +137,7 @@
identityManager.disableUser(username);
}
- Conversation.instance().end();
+ conversation.end();
return "success";
}
Modified: modules/trunk/security/src/main/java/org/jboss/seam/security/management/action/UserSearch.java
===================================================================
--- modules/trunk/security/src/main/java/org/jboss/seam/security/management/action/UserSearch.java 2009-04-24 12:36:43 UTC (rev 10626)
+++ modules/trunk/security/src/main/java/org/jboss/seam/security/management/action/UserSearch.java 2009-04-24 13:13:27 UTC (rev 10627)
@@ -1,22 +1,18 @@
package org.jboss.seam.security.management.action;
-import static org.jboss.seam.ScopeType.SESSION;
-import static org.jboss.seam.annotations.Install.BUILT_IN;
-
import java.io.Serializable;
import java.util.List;
-import org.jboss.seam.annotations.In;
-import org.jboss.seam.annotations.Install;
-import org.jboss.seam.annotations.Name;
-import org.jboss.seam.annotations.Scope;
+import javax.annotation.Named;
+import javax.context.SessionScoped;
+import javax.inject.Current;
+
import org.jboss.seam.annotations.datamodel.DataModel;
import org.jboss.seam.annotations.datamodel.DataModelSelection;
import org.jboss.seam.security.management.IdentityManager;
-@Name("org.jboss.seam.security.management.userSearch")
-@Scope(SESSION)
-@Install(precedence = BUILT_IN)
+@Named
+@SessionScoped
public class UserSearch implements Serializable
{
private static final long serialVersionUID = 8592034786339372510L;
@@ -27,7 +23,7 @@
@DataModelSelection
String selectedUser;
- @In IdentityManager identityManager;
+ @Current IdentityManager identityManager;
public void loadUsers()
{
Deleted: modules/trunk/security/src/main/java/org/jboss/seam/security/management/package-info.java
===================================================================
--- modules/trunk/security/src/main/java/org/jboss/seam/security/management/package-info.java 2009-04-24 12:36:43 UTC (rev 10626)
+++ modules/trunk/security/src/main/java/org/jboss/seam/security/management/package-info.java 2009-04-24 13:13:27 UTC (rev 10627)
@@ -1,11 +0,0 @@
-/**
- * Seam Identity Management
- *
- * @see org.jboss.seam.security.management.IdentityManager
- */
-@Namespace(value="http://jboss.com/products/seam/security", prefix="org.jboss.seam.security")
-@AutoCreate
-package org.jboss.seam.security.management;
-
-import org.jboss.seam.annotations.AutoCreate;
-import org.jboss.seam.annotations.Namespace;
Deleted: modules/trunk/security/src/main/java/org/jboss/seam/security/permission/package-info.java
===================================================================
--- modules/trunk/security/src/main/java/org/jboss/seam/security/permission/package-info.java 2009-04-24 12:36:43 UTC (rev 10626)
+++ modules/trunk/security/src/main/java/org/jboss/seam/security/permission/package-info.java 2009-04-24 13:13:27 UTC (rev 10627)
@@ -1,11 +0,0 @@
-/**
- * Seam Security Permissions
- *
- * @see org.jboss.seam.security.permission.PermissionManager
- */
-@Namespace(value="http://jboss.com/products/seam/security", prefix="org.jboss.seam.security")
-@AutoCreate
-package org.jboss.seam.security.permission;
-
-import org.jboss.seam.annotations.AutoCreate;
-import org.jboss.seam.annotations.Namespace;
Added: modules/trunk/security/src/main/java/org/jboss/seam/security/util/AnnotatedBeanProperty.java
===================================================================
--- modules/trunk/security/src/main/java/org/jboss/seam/security/util/AnnotatedBeanProperty.java (rev 0)
+++ modules/trunk/security/src/main/java/org/jboss/seam/security/util/AnnotatedBeanProperty.java 2009-04-24 13:13:27 UTC (rev 10627)
@@ -0,0 +1,138 @@
+package org.jboss.seam.security.util;
+
+import java.beans.Introspector;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.lang.reflect.Type;
+
+/**
+ * A convenience class for working with an annotated property (either a field or method) of
+ * a JavaBean class.
+ *
+ * @author Shane Bryzak
+ */
+public class AnnotatedBeanProperty<T extends Annotation>
+{
+ private Field propertyField;
+ private Method propertyGetter;
+ private Method propertySetter;
+ private String name;
+ private Type propertyType;
+ private T annotation;
+
+ private boolean isFieldProperty;
+ private boolean set = false;
+
+ public AnnotatedBeanProperty(Class<?> cls, Class<T> annotationClass)
+ {
+ // First check declared fields
+ for (Field f : cls.getDeclaredFields())
+ {
+ if (f.isAnnotationPresent(annotationClass))
+ {
+ setupFieldProperty(f);
+ this.annotation = f.getAnnotation(annotationClass);
+ set = true;
+ return;
+ }
+ }
+
+ // Then check public fields, in case it's inherited
+ for (Field f : cls.getFields())
+ {
+ if (f.isAnnotationPresent(annotationClass))
+ {
+ this.annotation = f.getAnnotation(annotationClass);
+ setupFieldProperty(f);
+ set = true;
+ return;
+ }
+ }
+
+ // Then check public methods (we ignore private methods)
+ for (Method m : cls.getMethods())
+ {
+ if (m.isAnnotationPresent(annotationClass))
+ {
+ this.annotation = m.getAnnotation(annotationClass);
+ String methodName = m.getName();
+
+ if ( m.getName().startsWith("get") )
+ {
+ this.name = Introspector.decapitalize( m.getName().substring(3) );
+ }
+ else if ( methodName.startsWith("is") )
+ {
+ this.name = Introspector.decapitalize( m.getName().substring(2) );
+ }
+
+ if (this.name != null)
+ {
+ this.propertyGetter = Reflections.getGetterMethod(cls, this.name);
+ this.propertySetter = Reflections.getSetterMethod(cls, this.name);
+ this.propertyType = this.propertyGetter.getGenericReturnType();
+ isFieldProperty = false;
+ set = true;
+ }
+ else
+ {
+ throw new IllegalStateException("Invalid accessor method, must start with 'get' or 'is'. " +
+ "Method: " + m + " in class: " + cls);
+ }
+ }
+ }
+ }
+
+ private void setupFieldProperty(Field propertyField)
+ {
+ this.propertyField = propertyField;
+ isFieldProperty = true;
+ this.name = propertyField.getName();
+ this.propertyType = propertyField.getGenericType();
+ }
+
+ public void setValue(Object bean, Object value)
+ {
+ if (isFieldProperty)
+ {
+ Reflections.setAndWrap(propertyField, bean, value);
+ }
+ else
+ {
+ Reflections.invokeAndWrap(propertySetter, bean, value);
+ }
+ }
+
+ public Object getValue(Object bean)
+ {
+ if (isFieldProperty)
+ {
+ return Reflections.getAndWrap(propertyField, bean);
+ }
+ else
+ {
+ return Reflections.invokeAndWrap(propertyGetter, bean);
+ }
+ }
+
+ public String getName()
+ {
+ return name;
+ }
+
+ public T getAnnotation()
+ {
+ return annotation;
+ }
+
+ public Type getPropertyType()
+ {
+ return propertyType;
+ }
+
+ public boolean isSet()
+ {
+ return set;
+ }
+}
\ No newline at end of file
Added: modules/trunk/security/src/main/java/org/jboss/seam/security/util/Reflections.java
===================================================================
--- modules/trunk/security/src/main/java/org/jboss/seam/security/util/Reflections.java (rev 0)
+++ modules/trunk/security/src/main/java/org/jboss/seam/security/util/Reflections.java 2009-04-24 13:13:27 UTC (rev 10627)
@@ -0,0 +1,401 @@
+package org.jboss.seam.security.util;
+
+import java.beans.Introspector;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Member;
+import java.lang.reflect.Method;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.List;
+
+public class Reflections
+{
+
+ public static Object invoke(Method method, Object target, Object... args) throws Exception
+ {
+ try
+ {
+ return method.invoke( target, args );
+ }
+ catch (IllegalArgumentException iae)
+ {
+ String message = "Could not invoke method by reflection: " + toString(method);
+ if (args!=null && args.length>0)
+ {
+ message += " with parameters: (" + Strings.toClassNameString(", ", args) + ')';
+ }
+ message += " on: " + target.getClass().getName();
+ throw new IllegalArgumentException(message, iae);
+ }
+ catch (InvocationTargetException ite)
+ {
+ if ( ite.getCause() instanceof Exception )
+ {
+ throw (Exception) ite.getCause();
+ }
+ else
+ {
+ throw ite;
+ }
+ }
+ }
+
+ public static Object get(Field field, Object target) throws Exception
+ {
+ boolean accessible = field.isAccessible();
+ try
+ {
+ field.setAccessible(true);
+ return field.get(target);
+ }
+ catch (IllegalArgumentException iae)
+ {
+ String message = "Could not get field value by reflection: " + toString(field) +
+ " on: " + target.getClass().getName();
+ throw new IllegalArgumentException(message, iae);
+ }
+ finally
+ {
+ field.setAccessible(accessible);
+ }
+ }
+
+ public static void set(Field field, Object target, Object value) throws Exception
+ {
+ try
+ {
+ field.set(target, value);
+ }
+ catch (IllegalArgumentException iae)
+ {
+ // target may be null if field is static so use field.getDeclaringClass() instead
+ String message = "Could not set field value by reflection: " + toString(field) +
+ " on: " + field.getDeclaringClass().getName();
+ if (value==null)
+ {
+ message += " with null value";
+ }
+ else
+ {
+ message += " with value: " + value.getClass();
+ }
+ throw new IllegalArgumentException(message, iae);
+ }
+ }
+
+ public static Object getAndWrap(Field field, Object target)
+ {
+ boolean accessible = field.isAccessible();
+ try
+ {
+ field.setAccessible(true);
+ return get(field, target);
+ }
+ catch (Exception e)
+ {
+ if (e instanceof RuntimeException)
+ {
+ throw (RuntimeException) e;
+ }
+ else
+ {
+ throw new IllegalArgumentException("exception setting: " + field.getName(), e);
+ }
+ }
+ finally
+ {
+ field.setAccessible(accessible);
+ }
+ }
+
+ public static void setAndWrap(Field field, Object target, Object value)
+ {
+ boolean accessible = field.isAccessible();
+ try
+ {
+ field.setAccessible(true);
+ set(field, target, value);
+ }
+ catch (Exception e)
+ {
+ if (e instanceof RuntimeException)
+ {
+ throw (RuntimeException) e;
+ }
+ else
+ {
+ throw new IllegalArgumentException("exception setting: " + field.getName(), e);
+ }
+ }
+ finally
+ {
+ field.setAccessible(accessible);
+ }
+ }
+
+ public static Object invokeAndWrap(Method method, Object target, Object... args)
+ {
+ try
+ {
+ return invoke(method, target, args);
+ }
+ catch (Exception e)
+ {
+ if (e instanceof RuntimeException)
+ {
+ throw (RuntimeException) e;
+ }
+ else
+ {
+ throw new RuntimeException("exception invoking: " + method.getName(), e);
+ }
+ }
+ }
+
+ public static String toString(Method method)
+ {
+ return Strings.unqualify( method.getDeclaringClass().getName() ) +
+ '.' +
+ method.getName() +
+ '(' +
+ Strings.toString( ", ", method.getParameterTypes() ) +
+ ')';
+ }
+
+ public static String toString(Member member)
+ {
+ return Strings.unqualify( member.getDeclaringClass().getName() ) +
+ '.' +
+ member.getName();
+ }
+
+ public static Class classForName(String name) throws ClassNotFoundException
+ {
+ try
+ {
+ return Thread.currentThread().getContextClassLoader().loadClass(name);
+ }
+ catch (Exception e)
+ {
+ return Class.forName(name);
+ }
+ }
+
+ /**
+ * Return's true if the class can be loaded using Reflections.classForName()
+ */
+ public static boolean isClassAvailable(String name)
+ {
+ try
+ {
+ classForName(name);
+ }
+ catch (ClassNotFoundException e) {
+ return false;
+ }
+ return true;
+ }
+
+ public static Class getCollectionElementType(Type collectionType)
+ {
+ if ( !(collectionType instanceof ParameterizedType) )
+ {
+ throw new IllegalArgumentException("collection type not parameterized");
+ }
+ Type[] typeArguments = ( (ParameterizedType) collectionType ).getActualTypeArguments();
+ if (typeArguments.length==0)
+ {
+ throw new IllegalArgumentException("no type arguments for collection type");
+ }
+ Type typeArgument = typeArguments.length==1 ? typeArguments[0] : typeArguments[1]; //handle Maps
+ if (typeArgument instanceof ParameterizedType)
+ {
+ typeArgument = ((ParameterizedType) typeArgument).getRawType();
+ }
+ if ( !(typeArgument instanceof Class) )
+ {
+ throw new IllegalArgumentException("type argument not a class");
+ }
+ return (Class) typeArgument;
+ }
+
+ public static Class getMapKeyType(Type collectionType)
+ {
+ if ( !(collectionType instanceof ParameterizedType) )
+ {
+ throw new IllegalArgumentException("collection type not parameterized");
+ }
+ Type[] typeArguments = ( (ParameterizedType) collectionType ).getActualTypeArguments();
+ if (typeArguments.length==0)
+ {
+ throw new IllegalArgumentException("no type arguments for collection type");
+ }
+ Type typeArgument = typeArguments[0];
+ if ( !(typeArgument instanceof Class) )
+ {
+ throw new IllegalArgumentException("type argument not a class");
+ }
+ return (Class) typeArgument;
+ }
+
+ public static Method getSetterMethod(Class clazz, String name)
+ {
+ Method[] methods = clazz.getMethods();
+ for (Method method: methods)
+ {
+ String methodName = method.getName();
+ if ( methodName.startsWith("set") && method.getParameterTypes().length==1 )
+ {
+ if ( Introspector.decapitalize( methodName.substring(3) ).equals(name) )
+ {
+ return method;
+ }
+ }
+ }
+ throw new IllegalArgumentException("no such setter method: " + clazz.getName() + '.' + name);
+ }
+
+ public static Method getGetterMethod(Class clazz, String name)
+ {
+ Method[] methods = clazz.getMethods();
+ for (Method method: methods)
+ {
+ String methodName = method.getName();
+ if ( method.getParameterTypes().length==0 )
+ {
+ if ( methodName.startsWith("get") )
+ {
+ if ( Introspector.decapitalize( methodName.substring(3) ).equals(name) )
+ {
+ return method;
+ }
+ }
+ else if ( methodName.startsWith("is") )
+ {
+ if ( Introspector.decapitalize( methodName.substring(2) ).equals(name) )
+ {
+ return method;
+ }
+ }
+ }
+ }
+ throw new IllegalArgumentException("no such getter method: " + clazz.getName() + '.' + name);
+ }
+
+ /**
+ * Get all the getter methods annotated with the given annotation. Returns an empty list if
+ * none are found
+ */
+ public static List<Method> getGetterMethods(Class clazz, Class annotation)
+ {
+ List<Method> methods = new ArrayList<Method>();
+ for (Method method : clazz.getMethods())
+ {
+ if (method.isAnnotationPresent(annotation))
+ {
+ methods.add(method);
+ }
+ }
+ return methods;
+ }
+
+ public static Field getField(Class clazz, String name)
+ {
+ for ( Class superClass = clazz; superClass!=Object.class; superClass=superClass.getSuperclass() )
+ {
+ try
+ {
+ return superClass.getDeclaredField(name);
+ }
+ catch (NoSuchFieldException nsfe) {}
+ }
+ throw new IllegalArgumentException("no such field: " + clazz.getName() + '.' + name);
+ }
+
+ /**
+ * Get all the fields which are annotated with the given annotation. Returns an empty list
+ * if none are found
+ */
+ public static List<Field> getFields(Class clazz, Class annotation)
+ {
+ List<Field> fields = new ArrayList<Field>();
+ for (Class superClass = clazz; superClass!=Object.class; superClass=superClass.getSuperclass())
+ {
+ for (Field field : superClass.getDeclaredFields())
+ {
+ if (field.isAnnotationPresent(annotation))
+ {
+ fields.add(field);
+ }
+ }
+ }
+ return fields;
+ }
+
+ public static Method getMethod(Annotation annotation, String name)
+ {
+ try
+ {
+ return annotation.annotationType().getMethod(name);
+ }
+ catch (NoSuchMethodException nsme)
+ {
+ return null;
+ }
+ }
+
+ public static Method getMethod(Class clazz, String name)
+ {
+ for ( Class superClass = clazz; superClass!=Object.class; superClass=superClass.getSuperclass() )
+ {
+ try
+ {
+ return superClass.getDeclaredMethod(name);
+ }
+ catch (NoSuchMethodException nsme) {}
+ }
+ throw new IllegalArgumentException("no such method: " + clazz.getName() + '.' + name);
+ }
+
+ /**
+ * Check to see if clazz is an instance of name
+ */
+ public static boolean isInstanceOf(Class clazz, String name)
+ {
+ if (name == null)
+ {
+ throw new IllegalArgumentException("name cannot be null");
+ }
+ for (Class c = clazz; c != Object.class; c = c.getSuperclass())
+ {
+ if (instanceOf(c, name))
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private static boolean instanceOf(Class clazz, String name)
+ {
+ if (name.equals(clazz.getName()))
+ {
+ return true;
+ }
+ else
+ {
+ boolean found = false;
+ Class[] interfaces = clazz.getInterfaces();
+ for (int i = 0; i < interfaces.length && !found; i++)
+ {
+ found = instanceOf(interfaces[i], name);
+ }
+ return found;
+ }
+
+ }
+
+}
Modified: modules/trunk/security/src/main/java/org/jboss/seam/security/util/Strings.java
===================================================================
--- modules/trunk/security/src/main/java/org/jboss/seam/security/util/Strings.java 2009-04-24 12:36:43 UTC (rev 10626)
+++ modules/trunk/security/src/main/java/org/jboss/seam/security/util/Strings.java 2009-04-24 13:13:27 UTC (rev 10627)
@@ -2,6 +2,16 @@
public class Strings
{
+ public static String unqualify(String name)
+ {
+ return unqualify(name, '.');
+ }
+
+ public static String unqualify(String name, char sep)
+ {
+ return name.substring( name.lastIndexOf(sep)+1, name.length() );
+ }
+
public static boolean isEmpty(String string)
{
int len;
@@ -19,4 +29,39 @@
}
return true;
}
+
+ public static String toClassNameString(String sep, Object... objects)
+ {
+ if (objects.length==0) return "";
+ StringBuilder builder = new StringBuilder();
+ for (Object object: objects)
+ {
+ builder.append(sep);
+ if (object==null)
+ {
+ builder.append("null");
+ }
+ else
+ {
+ builder.append( object.getClass().getName() );
+ }
+ }
+ return builder.substring(sep.length());
+ }
+
+ public static String toString(Object... objects)
+ {
+ return toString(" ", objects);
+ }
+
+ public static String toString(String sep, Object... objects)
+ {
+ if (objects.length==0) return "";
+ StringBuilder builder = new StringBuilder();
+ for (Object object: objects)
+ {
+ builder.append(sep).append(object);
+ }
+ return builder.substring(sep.length());
+ }
}
Added: modules/trunk/security/src/main/java/org/jboss/seam/security/util/TypedBeanProperty.java
===================================================================
--- modules/trunk/security/src/main/java/org/jboss/seam/security/util/TypedBeanProperty.java (rev 0)
+++ modules/trunk/security/src/main/java/org/jboss/seam/security/util/TypedBeanProperty.java 2009-04-24 13:13:27 UTC (rev 10627)
@@ -0,0 +1,114 @@
+package org.jboss.seam.security.util;
+
+import java.beans.Introspector;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+
+public class TypedBeanProperty
+{
+ private Field propertyField;
+ private Method propertyGetter;
+ private Method propertySetter;
+
+ private String name;
+
+ private boolean isFieldProperty;
+ private boolean set = false;
+
+ public TypedBeanProperty(Class<?> cls, Class type)
+ {
+ // First check declared fields
+ for (Field f : cls.getDeclaredFields())
+ {
+ if (f.getGenericType().equals(type))
+ {
+ setupFieldProperty(f);
+ set = true;
+ return;
+ }
+ }
+
+ // Then check public fields, in case it's inherited
+ for (Field f : cls.getFields())
+ {
+ if (f.getGenericType().equals(type))
+ {
+ setupFieldProperty(f);
+ set = true;
+ return;
+ }
+ }
+
+ // Then check public methods (we ignore private methods)
+ for (Method m : cls.getMethods())
+ {
+ if (m.getGenericReturnType().equals(type))
+ {
+ String methodName = m.getName();
+
+ if ( m.getName().startsWith("get") )
+ {
+ this.name = Introspector.decapitalize( m.getName().substring(3) );
+ }
+ else if ( methodName.startsWith("is") )
+ {
+ this.name = Introspector.decapitalize( m.getName().substring(2) );
+ }
+
+ if (this.name != null)
+ {
+ this.propertyGetter = Reflections.getGetterMethod(cls, this.name);
+ this.propertySetter = Reflections.getSetterMethod(cls, this.name);
+ isFieldProperty = false;
+ set = true;
+ }
+ else
+ {
+ throw new IllegalStateException("Invalid accessor method, must start with 'get' or 'is'. " +
+ "Method: " + m + " in class: " + cls);
+ }
+ }
+ }
+ }
+
+ private void setupFieldProperty(Field propertyField)
+ {
+ this.propertyField = propertyField;
+ isFieldProperty = true;
+ this.name = propertyField.getName();
+ }
+
+ public void setValue(Object bean, Object value)
+ {
+ if (isFieldProperty)
+ {
+ Reflections.setAndWrap(propertyField, bean, value);
+ }
+ else
+ {
+ Reflections.invokeAndWrap(propertySetter, bean, value);
+ }
+ }
+
+ public Object getValue(Object bean)
+ {
+ if (isFieldProperty)
+ {
+ return Reflections.getAndWrap(propertyField, bean);
+ }
+ else
+ {
+ return Reflections.invokeAndWrap(propertyGetter, bean);
+ }
+ }
+
+ public String getName()
+ {
+ return name;
+ }
+
+ public boolean isSet()
+ {
+ return set;
+ }
+}
\ No newline at end of file
[View Less]
15 years, 10 months
Seam SVN: r10626 - branches/enterprise/JBPAPP_4_3_FP01/seam-gen/view/img.
by seam-commits@lists.jboss.org
Author: manaRH
Date: 2009-04-24 08:36:43 -0400 (Fri, 24 Apr 2009)
New Revision: 10626
Added:
branches/enterprise/JBPAPP_4_3_FP01/seam-gen/view/img/manytoone.gif
branches/enterprise/JBPAPP_4_3_FP01/seam-gen/view/img/msgerror.png
branches/enterprise/JBPAPP_4_3_FP01/seam-gen/view/img/msginfo.png
branches/enterprise/JBPAPP_4_3_FP01/seam-gen/view/img/msgwarn.png
branches/enterprise/JBPAPP_4_3_FP01/seam-gen/view/img/onetomany.gif
branches/enterprise/JBPAPP_4_3_FP01/seam-gen/view/…
[View More]img/seamlogo.png
Log:
added missing images for seam-gen
Added: branches/enterprise/JBPAPP_4_3_FP01/seam-gen/view/img/manytoone.gif
===================================================================
(Binary files differ)
Property changes on: branches/enterprise/JBPAPP_4_3_FP01/seam-gen/view/img/manytoone.gif
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: branches/enterprise/JBPAPP_4_3_FP01/seam-gen/view/img/msgerror.png
===================================================================
(Binary files differ)
Property changes on: branches/enterprise/JBPAPP_4_3_FP01/seam-gen/view/img/msgerror.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: branches/enterprise/JBPAPP_4_3_FP01/seam-gen/view/img/msginfo.png
===================================================================
(Binary files differ)
Property changes on: branches/enterprise/JBPAPP_4_3_FP01/seam-gen/view/img/msginfo.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: branches/enterprise/JBPAPP_4_3_FP01/seam-gen/view/img/msgwarn.png
===================================================================
(Binary files differ)
Property changes on: branches/enterprise/JBPAPP_4_3_FP01/seam-gen/view/img/msgwarn.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: branches/enterprise/JBPAPP_4_3_FP01/seam-gen/view/img/onetomany.gif
===================================================================
(Binary files differ)
Property changes on: branches/enterprise/JBPAPP_4_3_FP01/seam-gen/view/img/onetomany.gif
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: branches/enterprise/JBPAPP_4_3_FP01/seam-gen/view/img/seamlogo.png
===================================================================
(Binary files differ)
Property changes on: branches/enterprise/JBPAPP_4_3_FP01/seam-gen/view/img/seamlogo.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
[View Less]
15 years, 10 months