Seam SVN: r10655 - modules/trunk/international.
by seam-commits@lists.jboss.org
Author: dan.j.allen
Date: 2009-04-27 11:34:36 -0400 (Mon, 27 Apr 2009)
New Revision: 10655
Modified:
modules/trunk/international/pom.xml
Log:
use American/UK spelling ;)
reorder dependency list
Modified: modules/trunk/international/pom.xml
===================================================================
--- modules/trunk/international/pom.xml 2009-04-27 12:52:32 UTC (rev 10654)
+++ modules/trunk/international/pom.xml 2009-04-27 15:34:36 UTC (rev 10655)
@@ -1,21 +1,29 @@
<project …
[View More]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">
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
<parent>
<artifactId>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-international</artifactId>
<packaging>jar</packaging>
<version>3.0.0-SNAPSHOT</version>
- <name>Seam Internationalisation</name>
-
+ <name>Seam Internationalization</name>
+
<dependencies>
<dependency>
+ <groupId>javax.faces</groupId>
+ <artifactId>jsf-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>javax.servlet</groupId>
+ <artifactId>servlet-api</artifactId>
+ </dependency>
+ <dependency>
<groupId>org.jboss.webbeans</groupId>
<artifactId>jsr299-api</artifactId>
</dependency>
@@ -23,14 +31,6 @@
<groupId>org.jboss.webbeans</groupId>
<artifactId>webbeans-logging</artifactId>
</dependency>
- <dependency>
- <groupId>javax.faces</groupId>
- <artifactId>jsf-api</artifactId>
- </dependency>
- <dependency>
- <groupId>javax.servlet</groupId>
- <artifactId>servlet-api</artifactId>
- </dependency>
</dependencies>
-
+
</project>
[View Less]
15 years, 10 months
Seam SVN: r10654 - in modules/trunk: bpm/src/main/java/org/jboss/seam/bpm and 2 other directories.
by seam-commits@lists.jboss.org
Author: shane.bryzak(a)jboss.com
Date: 2009-04-27 08:52:32 -0400 (Mon, 27 Apr 2009)
New Revision: 10654
Added:
modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/annotations/
modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/annotations/BeginTask.java
modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/annotations/CreateProcess.java
modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/annotations/EndTask.java
modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/annotations/…
[View More]ResumeProcess.java
modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/annotations/StartTask.java
modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/annotations/Transition.java
modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/annotations/package-info.java
Modified:
modules/trunk/bpm/pom.xml
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/ManagedJbpmContext.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/TaskInstance.java
modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/TaskInstanceList.java
modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/Transition.java
modules/trunk/version-matrix/pom.xml
Log:
add bpm annotations, more component conversion
Modified: modules/trunk/bpm/pom.xml
===================================================================
--- modules/trunk/bpm/pom.xml 2009-04-27 12:51:10 UTC (rev 10653)
+++ modules/trunk/bpm/pom.xml 2009-04-27 12:52:32 UTC (rev 10654)
@@ -35,6 +35,18 @@
<groupId>org.hibernate</groupId>
<artifactId>hibernate</artifactId>
</dependency>
+ <dependency>
+ <groupId>javax.el</groupId>
+ <artifactId>el-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.jboss.seam</groupId>
+ <artifactId>seam-el</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.jboss.seam</groupId>
+ <artifactId>seam-international</artifactId>
+ </dependency>
</dependencies>
</project>
Modified: modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/BusinessProcess.java
===================================================================
--- modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/BusinessProcess.java 2009-04-27 12:51:10 UTC (rev 10653)
+++ modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/BusinessProcess.java 2009-04-27 12:52:32 UTC (rev 10654)
@@ -162,7 +162,8 @@
*/
public void startTask()
{
- String actorId = Actor.instance().getId();
+ Actor actor = manager.getInstanceByType(Actor.class);
+ String actorId = actor.getId();
TaskInstance task = org.jboss.seam.bpm.TaskInstance.instance();
if ( actorId != null )
{
Modified: modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/BusinessProcessInterceptor.java
===================================================================
--- modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/BusinessProcessInterceptor.java 2009-04-27 12:51:10 UTC (rev 10653)
+++ modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/BusinessProcessInterceptor.java 2009-04-27 12:52:32 UTC (rev 10654)
@@ -8,16 +8,16 @@
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.bpm.annotations.BeginTask;
+import org.jboss.seam.bpm.annotations.CreateProcess;
+import org.jboss.seam.bpm.annotations.EndTask;
+import org.jboss.seam.bpm.annotations.ResumeProcess;
+import org.jboss.seam.bpm.annotations.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.el.Expressions;
import org.jboss.seam.core.Init;
import org.jboss.seam.intercept.AbstractInterceptor;
import org.jboss.seam.intercept.InvocationContext;
Modified: modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/Jbpm.java
===================================================================
--- modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/Jbpm.java 2009-04-27 12:51:10 UTC (rev 10653)
+++ modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/Jbpm.java 2009-04-27 12:52:32 UTC (rev 10654)
@@ -342,6 +342,7 @@
}
private static final DbSubProcessResolver DB_SUB_PROCESS_RESOLVER = new DbSubProcessResolver();
+
class SeamSubProcessResolver implements SubProcessResolver
{
public ProcessDefinition findSubProcess(Element element)
Modified: modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/ManagedJbpmContext.java
===================================================================
--- modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/ManagedJbpmContext.java 2009-04-27 12:51:10 UTC (rev 10653)
+++ modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/ManagedJbpmContext.java 2009-04-27 12:52:32 UTC (rev 10654)
@@ -8,8 +8,10 @@
import javax.annotation.PreDestroy;
import javax.context.RequestScoped;
+import javax.inject.Current;
import javax.inject.Initializer;
import javax.inject.Produces;
+import javax.inject.manager.Manager;
import javax.naming.NamingException;
import javax.transaction.RollbackException;
import javax.transaction.Synchronization;
@@ -38,11 +40,13 @@
private JbpmContext jbpmContext;
private boolean synchronizationRegistered;
+
+ @Current Jbpm jbpm;
@Initializer
public void create() throws NamingException, RollbackException, SystemException
{
- jbpmContext = Jbpm.instance().getJbpmConfiguration().createJbpmContext();
+ jbpmContext = jbpm.getJbpmConfiguration().createJbpmContext();
assertNoTransactionManagement();
log.debug( "created seam managed jBPM context");
}
@@ -145,14 +149,5 @@
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);
- }
}
Modified: modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/PooledTask.java
===================================================================
--- modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/PooledTask.java 2009-04-27 12:51:10 UTC (rev 10653)
+++ modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/PooledTask.java 2009-04-27 12:52:32 UTC (rev 10654)
@@ -1,13 +1,9 @@
package org.jboss.seam.bpm;
-import static org.jboss.seam.annotations.Install.BUILT_IN;
+import javax.context.ApplicationScoped;
+import javax.inject.Current;
+import javax.inject.manager.Manager;
-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;
/**
@@ -16,12 +12,10 @@
* @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")
+@ApplicationScoped
public class PooledTask
{
-
+ @Current Manager manager;
/**
* Assign the TaskInstance with the id passed
* in the request parameter named "taskId" to
@@ -33,7 +27,7 @@
@Transactional
public String assignToCurrentActor()
{
- Actor actor = Actor.instance();
+ Actor actor = manager.getInstanceByType(Actor.class);
if ( actor.getId()==null )
{
throw new IllegalStateException("no current actor id defined");
Modified: modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/PooledTaskInstanceList.java
===================================================================
--- modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/PooledTaskInstanceList.java 2009-04-27 12:51:10 UTC (rev 10653)
+++ modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/PooledTaskInstanceList.java 2009-04-27 12:52:32 UTC (rev 10654)
@@ -1,16 +1,12 @@
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 javax.inject.Current;
+import javax.inject.Produces;
+import javax.inject.manager.Manager;
+
import org.jbpm.taskmgmt.exe.TaskInstance;
/**
@@ -19,17 +15,14 @@
* @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
{
+ @Current Manager manager;
- @Unwrap
- @Transactional
+ @Produces @Transactional
public List<TaskInstance> getPooledTaskInstanceList()
{
- Actor actor = Actor.instance();
+ Actor actor = manager.getInstanceByType(Actor.class);
String actorId = actor.getId();
if ( actorId == null ) return null;
ArrayList groupIds = new ArrayList( actor.getGroupActorIds() );
Modified: modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/ProcessInstance.java
===================================================================
--- modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/ProcessInstance.java 2009-04-27 12:51:10 UTC (rev 10653)
+++ modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/ProcessInstance.java 2009-04-27 12:52:32 UTC (rev 10654)
@@ -6,16 +6,9 @@
*/
package org.jboss.seam.bpm;
-import static org.jboss.seam.annotations.Install.BUILT_IN;
+import javax.annotation.Named;
+import javax.inject.Produces;
-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;
/**
@@ -24,14 +17,9 @@
*
* @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
+{
+ @Produces @Named
public org.jbpm.graph.exe.ProcessInstance getProcessInstance() throws Exception
{
if ( !Contexts.isConversationContextActive() ) return null;
@@ -57,11 +45,4 @@
}.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);
- }
}
Modified: modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/ProcessInstanceFinder.java
===================================================================
--- modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/ProcessInstanceFinder.java 2009-04-27 12:51:10 UTC (rev 10653)
+++ modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/ProcessInstanceFinder.java 2009-04-27 12:52:32 UTC (rev 10654)
@@ -4,15 +4,14 @@
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 javax.annotation.Named;
+import javax.inject.Produces;
+
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;
@@ -21,8 +20,6 @@
*
* @author Gavin King
*/
-@Name("org.jboss.seam.bpm.processInstanceFinder")
-@Install(precedence=BUILT_IN, dependencies="org.jboss.seam.bpm.jbpm")
public class ProcessInstanceFinder
{
@@ -31,8 +28,7 @@
private Boolean processInstanceEnded = false;
private Boolean sortDescending = false;
- @Factory(value="org.jboss.seam.bpm.processInstanceList", autoCreate=true)
- @Transactional
+ @Produces @Named @Transactional
public List<ProcessInstance> getProcessInstanceList()
{
Criteria query = ManagedJbpmContext.instance().getSession()
Modified: modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/SeamExpressionEvaluator.java
===================================================================
--- modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/SeamExpressionEvaluator.java 2009-04-27 12:51:10 UTC (rev 10653)
+++ modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/SeamExpressionEvaluator.java 2009-04-27 12:52:32 UTC (rev 10654)
@@ -14,8 +14,8 @@
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.jboss.webbeans.log.LogProvider;
+import org.jboss.webbeans.log.Logging;
import org.jbpm.jpdl.el.ELException;
import org.jbpm.jpdl.el.Expression;
import org.jbpm.jpdl.el.ExpressionEvaluator;
Modified: modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/TaskInstance.java
===================================================================
--- modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/TaskInstance.java 2009-04-27 12:51:10 UTC (rev 10653)
+++ modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/TaskInstance.java 2009-04-27 12:52:32 UTC (rev 10654)
@@ -43,11 +43,4 @@
}.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);
- }
-
}
Modified: modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/TaskInstanceList.java
===================================================================
--- modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/TaskInstanceList.java 2009-04-27 12:51:10 UTC (rev 10653)
+++ modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/TaskInstanceList.java 2009-04-27 12:52:32 UTC (rev 10654)
@@ -2,7 +2,6 @@
import java.util.List;
-import javax.context.ApplicationScoped;
import javax.inject.Produces;
import org.jbpm.taskmgmt.exe.TaskInstance;
Modified: modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/Transition.java
===================================================================
--- modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/Transition.java 2009-04-27 12:51:10 UTC (rev 10653)
+++ modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/Transition.java 2009-04-27 12:52:32 UTC (rev 10654)
@@ -1,16 +1,9 @@
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 javax.context.ConversationScoped;
+
import org.jboss.seam.core.AbstractMutable;
/**
@@ -21,10 +14,7 @@
*
* @author Gavin King
*/
-@Name("org.jboss.seam.bpm.transition")
-(a)Scope(ScopeType.CONVERSATION)
-@BypassInterceptors
-@Install(precedence=BUILT_IN, dependencies="org.jboss.seam.bpm.jbpm")
+@ConversationScoped
public class Transition extends AbstractMutable implements Serializable
{
private static final long serialVersionUID = -3054558654376670239L;
@@ -45,15 +35,6 @@
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()
{
Added: modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/annotations/BeginTask.java
===================================================================
--- modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/annotations/BeginTask.java (rev 0)
+++ modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/annotations/BeginTask.java 2009-04-27 12:52:32 UTC (rev 10654)
@@ -0,0 +1,65 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Distributable under LGPL license.
+ * See terms of license at gnu.org.
+ */
+package org.jboss.seam.annotations.bpm;
+
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import org.jboss.seam.annotations.FlushModeType;
+
+/**
+ * Marks a method as causing a jBPM {@link org.jbpm.taskmgmt.exe.TaskInstance task}
+ * to be resumed. The jBPM {@link org.jbpm.context.exe.ContextInstance}
+ * is associated with the BUSINESS_PROCESS scope and the
+ * {@link org.jbpm.taskmgmt.exe.TaskInstance} is associated with a new
+ * conversation, unless the annotated method returns a null outcome.
+ * <p/>
+ * Note that both {@link BeginTask} and {@link StartTask} have effect
+ * before invocation of the intercepted method in that they are both
+ * about setting up appropriate {@link org.jbpm.context.exe.ContextInstance}
+ * for the current {@link org.jboss.seam.contexts.BusinessProcessContext}.
+ * <p/>
+ *
+ * @author Steve Ebersole
+ */
+@Target(METHOD)
+@Retention(RUNTIME)
+@Documented
+public @interface BeginTask
+{
+ /**
+ * The name of the request parameter under which we should locate the
+ * the id of task to be resumed.
+ */
+ String taskIdParameter() default "";
+ /**
+ * An EL expression that evaluates to the task id.
+ * @return an EL expression
+ */
+ String taskId() default "#{param.taskId}";
+ /**
+ * The name of the jBPM process definition defining the page flow for
+ * this conversation.
+ */
+ String pageflow() default "";
+ /**
+ * An EL expression for the conversation id. If a conversation with
+ * the same id aready exists, Seam will redirect to that conversation.
+ *
+ * @deprecated use <conversation/> in pages.xml
+ */
+ String id() default "";
+ /**
+ * Set the FlushMode for any EntityManager used in
+ * this conversation.
+ */
+ FlushModeType flushMode() default FlushModeType.AUTO;
+}
Added: modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/annotations/CreateProcess.java
===================================================================
--- modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/annotations/CreateProcess.java (rev 0)
+++ modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/annotations/CreateProcess.java 2009-04-27 12:52:32 UTC (rev 10654)
@@ -0,0 +1,40 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Distributable under LGPL license.
+ * See terms of license at gnu.org.
+ */
+package org.jboss.seam.annotations.bpm;
+
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+/**
+ * Marks a method creating a jBPM
+ * {@link org.jbpm.graph.exe.ProcessInstance process instance}
+ * unless the method throws an exception or returns a null outcome.
+ *
+ * @author Steve Ebersole
+ */
+@Target(METHOD)
+@Retention(RUNTIME)
+@Documented
+public @interface CreateProcess
+{
+ /**
+ * The name of the {@link org.jbpm.graph.def.ProcessDefinition} from which
+ * to create the {@link org.jbpm.graph.exe.ProcessInstance}
+ */
+ String definition();
+ /**
+ * An EL expression that evaluates to the process
+ * business key.
+ *
+ * @return an EL expression or an empty string to indicate a null key
+ */
+ String processKey() default "";
+}
Added: modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/annotations/EndTask.java
===================================================================
--- modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/annotations/EndTask.java (rev 0)
+++ modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/annotations/EndTask.java 2009-04-27 12:52:32 UTC (rev 10654)
@@ -0,0 +1,61 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Distributable under LGPL license.
+ * See terms of license at gnu.org.
+ */
+package org.jboss.seam.annotations.bpm;
+
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+/**
+ * Marks a method as causing a jBPM
+ * {@link org.jbpm.taskmgmt.exe.TaskInstance task instance}
+ * to be ended. The current conversation also ends. If a list of outcomes
+ * is specified, the task ends only if the outcome is in the list. A null
+ * outcome never ends the task.
+ *
+ * @see org.jbpm.taskmgmt.exe.TaskInstance#end(String)
+ * @author Gavin King
+ */
+@Target(METHOD)
+@Retention(RUNTIME)
+@Documented
+public @interface EndTask
+{
+
+ /**
+ * An empty outcome list is interpreted to mean any
+ * outcome except for the null (redisplay) outcome.
+ *
+ * @deprecated use BusinessProcess.instance().end("...") and
+ * Conversation.instance().end()
+ */
+ String[] ifOutcome() default {};
+
+ /**
+ * Specifies the transition that should be triggered by
+ * completing the task. If the transition needs to be
+ * specified dynamically, use the Seam <tt>transition</tt>
+ * component, calling <tt>Transition.setName()<tt>.
+ *
+ * @return a transition name
+ */
+ String transition() default "";
+
+ /**
+ * Should the conversation be destroyed before any
+ * redirect? (The default behavior is to propagate
+ * the conversation across the redirect and then
+ * destroy it at the end of the redirected request.)
+ *
+ * @return false by default
+ */
+ boolean beforeRedirect() default false;
+
+}
Added: modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/annotations/ResumeProcess.java
===================================================================
--- modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/annotations/ResumeProcess.java (rev 0)
+++ modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/annotations/ResumeProcess.java 2009-04-27 12:52:32 UTC (rev 10654)
@@ -0,0 +1,57 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Distributable under LGPL license.
+ * See terms of license at gnu.org.
+ */
+package org.jboss.seam.annotations.bpm;
+
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+/**
+ * Marks a method as causing an existing jBPM
+ * {@link org.jbpm.graph.exe.ProcessInstance process instance}
+ * to be associated with the current conversation, unless the
+ * annotated method returns a null outcome.
+ *
+ * @author Steve Ebersole
+ */
+@Target(METHOD)
+@Retention(RUNTIME)
+@Documented
+public @interface ResumeProcess
+{
+ /**
+ * The name of the request parameter under which we should locate the
+ * the id of process to be resumed.
+ * (not required for lookup by business key)
+ *
+ * @return a request parameter name
+ */
+ String processIdParameter() default "";
+ /**
+ * An EL expression that evaluates to the process id.
+ * (not required for lookup by business key)
+ *
+ * @return an EL expression
+ */
+ String processId() default "#{param.processId}";
+ /**
+ * An EL expression that evaluates to the process
+ * business key.
+ * (optional, only required for lookup by business key)
+ *
+ * @return an EL expression
+ */
+ String processKey() default "";
+ /**
+ * The name of the {@link org.jbpm.graph.def.ProcessDefinition}
+ * (optional, only required for lookup by business key)
+ */
+ String definition() default "";
+}
Added: modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/annotations/StartTask.java
===================================================================
--- modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/annotations/StartTask.java (rev 0)
+++ modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/annotations/StartTask.java 2009-04-27 12:52:32 UTC (rev 10654)
@@ -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.annotations.bpm;
+
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import org.jboss.seam.annotations.FlushModeType;
+
+/**
+ * Marks a method as causing jBPM {@link org.jbpm.taskmgmt.exe.TaskInstance task}
+ * to be started. The jBPM {@link org.jbpm.context.exe.ContextInstance}
+ * is associated with the BUSINESS_PROCESS scope and the
+ * {@link org.jbpm.taskmgmt.exe.TaskInstance} is associated with a new
+ * conversation, unless the annotated method returns a null outcome.
+ * <p/>
+ * Note that both {@link BeginTask} and {@link StartTask} have effect
+ * before invocation of the intercepted method in that they are both
+ * about setting up appropriate {@link org.jbpm.context.exe.ContextInstance}
+ * for the current {@link org.jboss.seam.contexts.BusinessProcessContext};
+ * {@link StartTask} however, also has effect after method invocation
+ * as that is the time it actually marks the task as started.
+ *
+ * @see org.jbpm.taskmgmt.exe.TaskInstance#start()
+ * @author Steve Ebersole
+ */
+@Target( METHOD )
+@Retention( RUNTIME )
+@Documented
+public @interface StartTask
+{
+ /**
+ * The name of the request parameter under which we should locate the
+ * the id of task to be started.
+ */
+ String taskIdParameter() default "";
+ /**
+ * An EL expression that evaluates to the task id.
+ * @return an EL expression
+ */
+ String taskId() default "#{param.taskId}";
+ /**
+ * The name of the jBPM process definition defining
+ * the page flow for this conversation.
+ */
+ String pageflow() default "";
+ /**
+ * An EL expression for the conversation id. If a conversation with
+ * the same id aready exists, Seam will redirect to that conversation.
+ *
+ * @deprecated use <conversation/> in pages.xml
+ */
+ String id() default "";
+ /**
+ * Set the FlushMode for any EntityManager used in
+ * this conversation.
+ */
+ FlushModeType flushMode() default FlushModeType.AUTO;
+}
Added: modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/annotations/Transition.java
===================================================================
--- modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/annotations/Transition.java (rev 0)
+++ modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/annotations/Transition.java 2009-04-27 12:52:32 UTC (rev 10654)
@@ -0,0 +1,36 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Distributable under LGPL license.
+ * See terms of license at gnu.org.
+ */
+package org.jboss.seam.annotations.bpm;
+
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+/**
+ * Marks a method as causing a jBPM transition after
+ * the method returns a non-null result without exception.
+ *
+ * @author Gavin King
+ */
+@Target(METHOD)
+@Retention(RUNTIME)
+@Documented
+public @interface Transition
+{
+
+ /**
+ * The transition name, defaults to the name
+ * of the method.
+ *
+ * @return the transition name
+ */
+ String value() default "";
+
+}
Added: modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/annotations/package-info.java
===================================================================
--- modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/annotations/package-info.java (rev 0)
+++ modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/annotations/package-info.java 2009-04-27 12:52:32 UTC (rev 10654)
@@ -0,0 +1,9 @@
+/**
+ * Annotations for controlling the business process
+ * and business process context.
+ *
+ * @see org.jboss.seam.bpm
+ * @see org.jboss.seam.bpm.BusinessProcess
+ */
+package org.jboss.seam.annotations.bpm;
+
Modified: modules/trunk/version-matrix/pom.xml
===================================================================
--- modules/trunk/version-matrix/pom.xml 2009-04-27 12:51:10 UTC (rev 10653)
+++ modules/trunk/version-matrix/pom.xml 2009-04-27 12:52:32 UTC (rev 10654)
@@ -207,6 +207,12 @@
<version>${seam.version}</version>
</dependency>
+ <dependency>
+ <groupId>org.jboss.seam</groupId>
+ <artifactId>seam-international</artifactId>
+ <version>${seam.version}</version>
+ </dependency>
+
</dependencies>
</dependencyManagement>
[View Less]
15 years, 10 months
Seam SVN: r10653 - in modules/trunk/transaction: src/main/java/org/jboss/seam/transaction and 1 other directory.
by seam-commits@lists.jboss.org
Author: shane.bryzak(a)jboss.com
Date: 2009-04-27 08:51:10 -0400 (Mon, 27 Apr 2009)
New Revision: 10653
Removed:
modules/trunk/transaction/src/main/java/org/jboss/seam/transaction/package-info.java
Modified:
modules/trunk/transaction/
Log:
ignores
Property changes on: modules/trunk/transaction
___________________________________________________________________
Name: svn:ignore
+ .classpath
.project
.settings
target
Deleted: modules/trunk/transaction/src/main/java/org/jboss/seam/…
[View More]transaction/package-info.java
===================================================================
--- modules/trunk/transaction/src/main/java/org/jboss/seam/transaction/package-info.java 2009-04-27 12:50:30 UTC (rev 10652)
+++ modules/trunk/transaction/src/main/java/org/jboss/seam/transaction/package-info.java 2009-04-27 12:51:10 UTC (rev 10653)
@@ -1,20 +0,0 @@
-/**
- * Abstracts all possible transaction management APIs behind a
- * JTA-compatible interface. Unfortunately, many
- * otherwise-perfectly-intelligent-looking Java developers like
- * to invent their own transaction management APIs when they get
- * bored, even though JTA is well-known to be more than good
- * enough. For example, one of the co-authors of this class was
- * present at the creation of not one but two "alternative"
- * transaction APIs (org.hibernate.Transaction and
- * javax.persistence.EntityTransaction), and is more
- * embarrassed by this than by any other of his many professional
- * blunders.
- *
- * @see org.jboss.seam.transaction.Transaction
- * @see org.jboss.seam.transaction.UserTransaction
- */
-@Namespace(value="http://jboss.com/products/seam/transaction", prefix="org.jboss.seam.transaction")
-package org.jboss.seam.transaction;
-
-import org.jboss.seam.annotations.Namespace;
[View Less]
15 years, 10 months
Seam SVN: r10652 - in modules/trunk: transaction and 7 other directories.
by seam-commits@lists.jboss.org
Author: shane.bryzak(a)jboss.com
Date: 2009-04-27 08:50:30 -0400 (Mon, 27 Apr 2009)
New Revision: 10652
Added:
modules/trunk/transaction/
modules/trunk/transaction/pom.xml
modules/trunk/transaction/src/
modules/trunk/transaction/src/main/
modules/trunk/transaction/src/main/java/
modules/trunk/transaction/src/main/java/org/
modules/trunk/transaction/src/main/java/org/jboss/
modules/trunk/transaction/src/main/java/org/jboss/seam/
modules/trunk/transaction/src/main/java/…
[View More]org/jboss/seam/transaction/
modules/trunk/transaction/src/main/java/org/jboss/seam/transaction/AbstractUserTransaction.java
modules/trunk/transaction/src/main/java/org/jboss/seam/transaction/CMTTransaction.java
modules/trunk/transaction/src/main/java/org/jboss/seam/transaction/EjbSynchronizations.java
modules/trunk/transaction/src/main/java/org/jboss/seam/transaction/EjbTransaction.java
modules/trunk/transaction/src/main/java/org/jboss/seam/transaction/EntityTransaction.java
modules/trunk/transaction/src/main/java/org/jboss/seam/transaction/FacesTransactionEvents.java
modules/trunk/transaction/src/main/java/org/jboss/seam/transaction/HibernateTransaction.java
modules/trunk/transaction/src/main/java/org/jboss/seam/transaction/LocalEjbSynchronizations.java
modules/trunk/transaction/src/main/java/org/jboss/seam/transaction/NoTransaction.java
modules/trunk/transaction/src/main/java/org/jboss/seam/transaction/RollbackInterceptor.java
modules/trunk/transaction/src/main/java/org/jboss/seam/transaction/SeSynchronizations.java
modules/trunk/transaction/src/main/java/org/jboss/seam/transaction/SynchronizationRegistry.java
modules/trunk/transaction/src/main/java/org/jboss/seam/transaction/Synchronizations.java
modules/trunk/transaction/src/main/java/org/jboss/seam/transaction/Transaction.java
modules/trunk/transaction/src/main/java/org/jboss/seam/transaction/TransactionInterceptor.java
modules/trunk/transaction/src/main/java/org/jboss/seam/transaction/UTTransaction.java
modules/trunk/transaction/src/main/java/org/jboss/seam/transaction/UserTransaction.java
modules/trunk/transaction/src/main/java/org/jboss/seam/transaction/package-info.java
Log:
initial import of transaction module
Added: modules/trunk/transaction/pom.xml
===================================================================
--- modules/trunk/transaction/pom.xml (rev 0)
+++ modules/trunk/transaction/pom.xml 2009-04-27 12:50:30 UTC (rev 10652)
@@ -0,0 +1,44 @@
+<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-transaction</artifactId>
+ <packaging>jar</packaging>
+ <version>3.0.0-SNAPSHOT</version>
+ <name>Seam Transaction</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>javax.persistence</groupId>
+ <artifactId>persistence-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>javax.transaction</groupId>
+ <artifactId>jta</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>javax.ejb</groupId>
+ <artifactId>ejb-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.jboss.seam</groupId>
+ <artifactId>seam-el</artifactId>
+ </dependency>
+ </dependencies>
+
+</project>
Added: modules/trunk/transaction/src/main/java/org/jboss/seam/transaction/AbstractUserTransaction.java
===================================================================
--- modules/trunk/transaction/src/main/java/org/jboss/seam/transaction/AbstractUserTransaction.java (rev 0)
+++ modules/trunk/transaction/src/main/java/org/jboss/seam/transaction/AbstractUserTransaction.java 2009-04-27 12:50:30 UTC (rev 10652)
@@ -0,0 +1,82 @@
+package org.jboss.seam.transaction;
+
+import static javax.transaction.Status.STATUS_ACTIVE;
+import static javax.transaction.Status.STATUS_MARKED_ROLLBACK;
+import static javax.transaction.Status.STATUS_ROLLEDBACK;
+import static javax.transaction.Status.STATUS_COMMITTED;
+import static javax.transaction.Status.STATUS_NO_TRANSACTION;
+
+import javax.persistence.EntityManager;
+import javax.transaction.Synchronization;
+import javax.transaction.SystemException;
+
+import org.jboss.seam.Component;
+import org.jboss.seam.ScopeType;
+
+/**
+ * Base implementation of UserTransaction
+ *
+ * @author Gavin King
+ *
+ */
+public abstract class AbstractUserTransaction implements UserTransaction
+{
+
+ public boolean isActive() throws SystemException
+ {
+ return getStatus() == STATUS_ACTIVE;
+ }
+
+ public boolean isActiveOrMarkedRollback() throws SystemException
+ {
+ int status = getStatus();
+ return status == STATUS_ACTIVE || status == STATUS_MARKED_ROLLBACK;
+ }
+
+ public boolean isRolledBackOrMarkedRollback() throws SystemException
+ {
+ int status = getStatus();
+ return status == STATUS_ROLLEDBACK || status == STATUS_MARKED_ROLLBACK;
+ }
+
+ public boolean isMarkedRollback() throws SystemException
+ {
+ return getStatus() == STATUS_MARKED_ROLLBACK;
+ }
+
+ public boolean isNoTransaction() throws SystemException
+ {
+ return getStatus() == STATUS_NO_TRANSACTION;
+ }
+
+ public boolean isRolledBack() throws SystemException
+ {
+ return getStatus() == STATUS_ROLLEDBACK;
+ }
+
+ public boolean isCommitted() throws SystemException
+ {
+ return getStatus() == STATUS_COMMITTED;
+ }
+
+ public boolean isConversationContextRequired()
+ {
+ return false;
+ }
+
+ public abstract void registerSynchronization(Synchronization sync);
+
+ public void enlist(EntityManager entityManager) throws SystemException
+ {
+ if ( isActiveOrMarkedRollback() )
+ {
+ entityManager.joinTransaction();
+ }
+ }
+
+ public static Synchronizations getSynchronizations()
+ {
+ return (Synchronizations) Component.getInstance("org.jboss.seam.transaction.synchronizations", ScopeType.EVENT);
+ }
+
+}
Added: modules/trunk/transaction/src/main/java/org/jboss/seam/transaction/CMTTransaction.java
===================================================================
--- modules/trunk/transaction/src/main/java/org/jboss/seam/transaction/CMTTransaction.java (rev 0)
+++ modules/trunk/transaction/src/main/java/org/jboss/seam/transaction/CMTTransaction.java 2009-04-27 12:50:30 UTC (rev 10652)
@@ -0,0 +1,126 @@
+package org.jboss.seam.transaction;
+
+import javax.ejb.EJBContext;
+import javax.transaction.HeuristicMixedException;
+import javax.transaction.HeuristicRollbackException;
+import javax.transaction.NotSupportedException;
+import javax.transaction.RollbackException;
+import javax.transaction.Status;
+import javax.transaction.Synchronization;
+import javax.transaction.SystemException;
+import javax.transaction.UserTransaction;
+
+/**
+ * Wraps EJBContext transaction management in a
+ * UserTransaction interface. Note that container managed
+ * transactions cannot be controlled by the application,
+ * so begin(), commit() and rollback() are disallowed in
+ * a CMT.
+ *
+ * @author Mike Youngstrom
+ * @author Gavin King
+ *
+ */
+public class CMTTransaction extends AbstractUserTransaction
+{
+
+ private final EJBContext ejbContext;
+
+ public CMTTransaction(EJBContext ejbContext)
+ {
+ this.ejbContext = ejbContext;
+ if (ejbContext==null)
+ {
+ throw new IllegalArgumentException("null EJBContext");
+ }
+ }
+
+ public void begin() throws NotSupportedException, SystemException
+ {
+ ejbContext.getUserTransaction().begin();
+ getSynchronizations().afterTransactionBegin();
+ }
+
+ public void commit() throws RollbackException, HeuristicMixedException,
+ HeuristicRollbackException, SecurityException, IllegalStateException, SystemException
+ {
+ UserTransaction userTransaction = ejbContext.getUserTransaction();
+ boolean success = false;
+ Synchronizations synchronizations = getSynchronizations();
+ synchronizations.beforeTransactionCommit();
+ try
+ {
+ userTransaction.commit();
+ success = true;
+ }
+ finally
+ {
+ synchronizations.afterTransactionCommit(success);
+ }
+ }
+
+ public void rollback() throws IllegalStateException, SecurityException, SystemException
+ {
+ UserTransaction userTransaction = ejbContext.getUserTransaction();
+ try
+ {
+ userTransaction.rollback();
+ }
+ finally
+ {
+ getSynchronizations().afterTransactionRollback();
+ }
+ }
+
+ public int getStatus() throws SystemException
+ {
+ try
+ {
+ //TODO: not correct for SUPPORTS or NEVER!
+ if ( !ejbContext.getRollbackOnly() )
+ {
+ return Status.STATUS_ACTIVE;
+ }
+ else
+ {
+ return Status.STATUS_MARKED_ROLLBACK;
+ }
+ }
+ catch (IllegalStateException ise)
+ {
+ try
+ {
+ return ejbContext.getUserTransaction().getStatus();
+ }
+ catch (IllegalStateException is)
+ {
+ return Status.STATUS_NO_TRANSACTION;
+ }
+ }
+ }
+
+ public void setRollbackOnly() throws IllegalStateException, SystemException
+ {
+ ejbContext.setRollbackOnly();
+ }
+
+ public void setTransactionTimeout(int timeout) throws SystemException
+ {
+ ejbContext.getUserTransaction().setTransactionTimeout(timeout);
+ }
+
+ @Override
+ public void registerSynchronization(Synchronization sync)
+ {
+ Synchronizations synchronizations = getSynchronizations();
+ if ( synchronizations.isAwareOfContainerTransactions() )
+ {
+ synchronizations.registerSynchronization(sync);
+ }
+ else
+ {
+ throw new UnsupportedOperationException("cannot register synchronization with container transaction, use <transaction:ejb-transaction/>");
+ }
+ }
+
+}
Added: modules/trunk/transaction/src/main/java/org/jboss/seam/transaction/EjbSynchronizations.java
===================================================================
--- modules/trunk/transaction/src/main/java/org/jboss/seam/transaction/EjbSynchronizations.java (rev 0)
+++ modules/trunk/transaction/src/main/java/org/jboss/seam/transaction/EjbSynchronizations.java 2009-04-27 12:50:30 UTC (rev 10652)
@@ -0,0 +1,108 @@
+package org.jboss.seam.transaction;
+
+import java.rmi.RemoteException;
+import java.util.LinkedList;
+
+import javax.context.RequestScoped;
+import javax.ejb.EJBException;
+import javax.ejb.Remove;
+import javax.ejb.SessionSynchronization;
+import javax.ejb.Stateful;
+import javax.ejb.TransactionAttribute;
+import javax.ejb.TransactionAttributeType;
+import javax.transaction.Synchronization;
+
+import org.jboss.webbeans.log.LogProvider;
+import org.jboss.webbeans.log.Logging;
+
+/**
+ * Receives JTA transaction completion notifications from
+ * the EJB container, and passes them on to the registered
+ * Synchronizations. This implementation
+ * is fully aware of container managed transactions and is
+ * able to register Synchronizations for the container
+ * transaction.
+ *
+ * @author Gavin King
+ *
+ */
+@Stateful
+@RequestScoped
+(a)TransactionAttribute(TransactionAttributeType.SUPPORTS)
+public class EjbSynchronizations implements LocalEjbSynchronizations, SessionSynchronization
+{
+ private static final LogProvider log = Logging.getLogProvider(EjbSynchronizations.class);
+
+ //maintain two lists to work around a bug in JBoss EJB3 where a new SessionSynchronization
+ //gets registered each time the bean is called
+ protected LinkedList<SynchronizationRegistry> synchronizations = new LinkedList<SynchronizationRegistry>();
+ protected LinkedList<SynchronizationRegistry> committing = new LinkedList<SynchronizationRegistry>();
+
+ public void afterBegin()
+ {
+ log.debug("afterBegin");
+ synchronizations.addLast( new SynchronizationRegistry() );
+ }
+
+ public void beforeCompletion() throws EJBException, RemoteException
+ {
+ log.debug("beforeCompletion");
+ SynchronizationRegistry sync = synchronizations.removeLast();
+ sync.beforeTransactionCompletion();
+ committing.addLast(sync);
+ }
+
+ public void afterCompletion(boolean success) throws EJBException, RemoteException
+ {
+ log.debug("afterCompletion");
+ if ( committing.isEmpty() )
+ {
+ if (success)
+ {
+ throw new IllegalStateException("beforeCompletion was never called");
+ }
+ else
+ {
+ synchronizations.removeLast().afterTransactionCompletion(false);
+ }
+ }
+ else
+ {
+ committing.removeFirst().afterTransactionCompletion(success);
+ }
+ }
+
+ public boolean isAwareOfContainerTransactions()
+ {
+ return true;
+ }
+
+ public void afterTransactionBegin()
+ {
+ //noop, let JTA notify us
+ }
+
+ public void afterTransactionCommit(boolean success)
+ {
+ //noop, let JTA notify us
+ }
+
+ public void afterTransactionRollback()
+ {
+ //noop, let JTA notify us
+ }
+
+ public void beforeTransactionCommit()
+ {
+ //noop, let JTA notify us
+ }
+
+ public void registerSynchronization(Synchronization sync)
+ {
+ synchronizations.getLast().registerSynchronization(sync);
+ }
+
+ @Remove
+ public void destroy() {}
+
+}
Added: modules/trunk/transaction/src/main/java/org/jboss/seam/transaction/EjbTransaction.java
===================================================================
--- modules/trunk/transaction/src/main/java/org/jboss/seam/transaction/EjbTransaction.java (rev 0)
+++ modules/trunk/transaction/src/main/java/org/jboss/seam/transaction/EjbTransaction.java 2009-04-27 12:50:30 UTC (rev 10652)
@@ -0,0 +1,15 @@
+package org.jboss.seam.transaction;
+
+import javax.annotation.Named;
+
+/**
+ * Dummy component that lets us install the
+ * EjbSynchronizations via the tag
+ * transaction:ejb-transaction
+ *
+ * @see EjbSynchronizations
+ * @author Gavin King
+ *
+ */
+@Named
+public class EjbTransaction {}
Added: modules/trunk/transaction/src/main/java/org/jboss/seam/transaction/EntityTransaction.java
===================================================================
--- modules/trunk/transaction/src/main/java/org/jboss/seam/transaction/EntityTransaction.java (rev 0)
+++ modules/trunk/transaction/src/main/java/org/jboss/seam/transaction/EntityTransaction.java 2009-04-27 12:50:30 UTC (rev 10652)
@@ -0,0 +1,226 @@
+package org.jboss.seam.transaction;
+
+import javax.annotation.Named;
+import javax.context.RequestScoped;
+import javax.inject.Current;
+import javax.inject.Initializer;
+import javax.persistence.EntityManager;
+import javax.transaction.HeuristicMixedException;
+import javax.transaction.HeuristicRollbackException;
+import javax.transaction.NotSupportedException;
+import javax.transaction.RollbackException;
+import javax.transaction.Status;
+import javax.transaction.Synchronization;
+import javax.transaction.SystemException;
+
+import org.jboss.seam.el.Expressions;
+import org.jboss.seam.el.Expressions.ValueExpression;
+import org.jboss.webbeans.log.LogProvider;
+import org.jboss.webbeans.log.Logging;
+import org.jboss.seam.persistence.PersistenceProvider;
+
+/**
+ * Support for the JPA EntityTransaction API.
+ *
+ * Adapts JPA transaction management to a Seam UserTransaction
+ * interface.For use in non-JTA-capable environments.
+ *
+ * @author Gavin King
+ *
+ */
+@Named
+@RequestScoped
+public class EntityTransaction extends AbstractUserTransaction
+{
+ private static final LogProvider log = Logging.getLogProvider(EntityTransaction.class);
+
+ private ValueExpression<EntityManager> entityManager;
+ private EntityManager currentEntityManager;
+
+ @Current Expressions expressions;
+
+ @Initializer
+ public void validate()
+ {
+ if (entityManager==null)
+ {
+ entityManager = expressions.createValueExpression("#{entityManager}", EntityManager.class);
+ }
+ }
+
+ private javax.persistence.EntityTransaction getDelegate()
+ {
+ if (currentEntityManager==null)
+ {
+ //should never occur
+ throw new IllegalStateException("entity manager is null");
+ }
+ return currentEntityManager.getTransaction();
+ }
+
+ private void initEntityManager()
+ {
+ currentEntityManager = entityManager.getValue();
+ if (currentEntityManager==null)
+ {
+ throw new IllegalStateException("entity manager was null: " + entityManager.getExpressionString());
+ }
+ }
+
+ public void begin() throws NotSupportedException, SystemException
+ {
+ log.debug("beginning JPA resource-local transaction");
+ //TODO: translate exceptions that occur into the correct JTA exception
+ assertNotActive();
+ initEntityManager();
+ try
+ {
+ getDelegate().begin();
+ getSynchronizations().afterTransactionBegin();
+ }
+ catch (RuntimeException re)
+ {
+ clearEntityManager();
+ throw re;
+ }
+ }
+
+ public void commit() throws RollbackException, HeuristicMixedException,
+ HeuristicRollbackException, SecurityException, IllegalStateException, SystemException
+ {
+ log.debug("committing JPA resource-local transaction");
+ assertActive();
+ javax.persistence.EntityTransaction delegate = getDelegate();
+ clearEntityManager();
+ boolean success = false;
+ try
+ {
+ if ( delegate.getRollbackOnly() )
+ {
+ delegate.rollback();
+ throw new RollbackException();
+ }
+ else
+ {
+ getSynchronizations().beforeTransactionCommit();
+ delegate.commit();
+ success = true;
+ }
+ }
+ finally
+ {
+ getSynchronizations().afterTransactionCommit(success);
+ }
+ }
+
+ public void rollback() throws IllegalStateException, SecurityException, SystemException
+ {
+ log.debug("rolling back JPA resource-local transaction");
+ //TODO: translate exceptions that occur into the correct JTA exception
+ assertActive();
+ javax.persistence.EntityTransaction delegate = getDelegate();
+ clearEntityManager();
+ try
+ {
+ delegate.rollback();
+ }
+ finally
+ {
+ getSynchronizations().afterTransactionRollback();
+ }
+ }
+
+ public void setRollbackOnly() throws IllegalStateException, SystemException
+ {
+ log.debug("marking JPA resource-local transaction for rollback");
+ assertActive();
+ getDelegate().setRollbackOnly();
+ }
+
+ public int getStatus() throws SystemException
+ {
+ if ( isEntityManagerSet() && getDelegate().getRollbackOnly() )
+ {
+ return Status.STATUS_MARKED_ROLLBACK;
+ }
+ else if ( isEntityManagerSet() && getDelegate().isActive() )
+ {
+ return Status.STATUS_ACTIVE;
+ }
+ else
+ {
+ return Status.STATUS_NO_TRANSACTION;
+ }
+ }
+
+ public void setTransactionTimeout(int timeout) throws SystemException
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ private boolean isEntityManagerSet()
+ {
+ return currentEntityManager!=null;
+ }
+
+ private void clearEntityManager()
+ {
+ currentEntityManager = null;
+ }
+
+ private void assertActive()
+ {
+ if ( !isEntityManagerSet() )
+ {
+ throw new IllegalStateException("transaction is not active");
+ }
+ }
+
+ private void assertNotActive() throws NotSupportedException
+ {
+ if ( isEntityManagerSet() )
+ {
+ throw new NotSupportedException("transaction is already active");
+ }
+ }
+
+ @Override
+ public void registerSynchronization(Synchronization sync)
+ {
+ if ( log.isDebugEnabled() )
+ {
+ log.debug("registering synchronization: " + sync);
+ }
+ assertActive();
+ //try to register the synchronization directly with the
+ //persistence provider, but if this fails, just hold
+ //on to it myself
+ if ( !PersistenceProvider.instance().registerSynchronization(sync, currentEntityManager) )
+ {
+ getSynchronizations().registerSynchronization(sync);
+ }
+ }
+
+ @Override
+ public boolean isConversationContextRequired()
+ {
+ return true;
+ }
+
+ public ValueExpression<EntityManager> getEntityManager()
+ {
+ return entityManager;
+ }
+
+ public void setEntityManager(ValueExpression<EntityManager> entityManager)
+ {
+ this.entityManager = entityManager;
+ }
+
+ @Override
+ public void enlist(EntityManager entityManager)
+ {
+ //no-op
+ }
+
+}
Added: modules/trunk/transaction/src/main/java/org/jboss/seam/transaction/FacesTransactionEvents.java
===================================================================
--- modules/trunk/transaction/src/main/java/org/jboss/seam/transaction/FacesTransactionEvents.java (rev 0)
+++ modules/trunk/transaction/src/main/java/org/jboss/seam/transaction/FacesTransactionEvents.java 2009-04-27 12:50:30 UTC (rev 10652)
@@ -0,0 +1,66 @@
+package org.jboss.seam.transaction;
+
+import static org.jboss.seam.ScopeType.APPLICATION;
+import static org.jboss.seam.annotations.Install.BUILT_IN;
+
+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.Startup;
+import org.jboss.seam.annotations.intercept.BypassInterceptors;
+import org.jboss.seam.international.StatusMessages;
+import org.jboss.seam.international.StatusMessage.Severity;
+
+/**
+ * Produces StatusMessages for JSF in response of certain transaction events.
+ * These events can be observed by support classes for other UI frameworks
+ * to produce similar messages.
+ *
+ * @author Dan Allen
+ */
+@Name("org.jboss.seam.transaction.facesTransactionEvents")
+@Scope(APPLICATION)
+@Install(precedence = BUILT_IN, classDependencies = "javax.faces.context.FacesContext")
+@BypassInterceptors
+@Startup
+public class FacesTransactionEvents
+{
+ private boolean transactionFailedMessageEnabled = true;
+
+ @Observer(Transaction.TRANSACTION_FAILED)
+ public void addTransactionFailedMessage(int status)
+ {
+ if (transactionFailedMessageEnabled) {
+ StatusMessages.instance().addFromResourceBundleOrDefault(
+ getTransactionFailedMessageSeverity(),
+ getTransactionFailedMessageKey(),
+ getTransactionFailedMessage());
+ }
+ }
+
+ public String getTransactionFailedMessage()
+ {
+ return "Transaction failed";
+ }
+
+ public Severity getTransactionFailedMessageSeverity()
+ {
+ return Severity.WARN;
+ }
+
+ public String getTransactionFailedMessageKey()
+ {
+ return "org.jboss.seam.TransactionFailed";
+ }
+
+ public boolean isTransactionFailedMessageEnabled()
+ {
+ return transactionFailedMessageEnabled;
+ }
+
+ public void setTransactionFailedMessageEnabled(boolean enabled)
+ {
+ this.transactionFailedMessageEnabled = enabled;
+ }
+}
Added: modules/trunk/transaction/src/main/java/org/jboss/seam/transaction/HibernateTransaction.java
===================================================================
--- modules/trunk/transaction/src/main/java/org/jboss/seam/transaction/HibernateTransaction.java (rev 0)
+++ modules/trunk/transaction/src/main/java/org/jboss/seam/transaction/HibernateTransaction.java 2009-04-27 12:50:30 UTC (rev 10652)
@@ -0,0 +1,212 @@
+package org.jboss.seam.transaction;
+
+import static org.jboss.seam.annotations.Install.FRAMEWORK;
+
+import javax.persistence.EntityManager;
+import javax.transaction.HeuristicMixedException;
+import javax.transaction.HeuristicRollbackException;
+import javax.transaction.NotSupportedException;
+import javax.transaction.RollbackException;
+import javax.transaction.Status;
+import javax.transaction.Synchronization;
+import javax.transaction.SystemException;
+
+import org.hibernate.Session;
+import org.hibernate.Transaction;
+import org.jboss.seam.ScopeType;
+import org.jboss.seam.annotations.Create;
+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.core.Expressions;
+import org.jboss.seam.core.Expressions.ValueExpression;
+import org.jboss.seam.log.LogProvider;
+import org.jboss.seam.log.Logging;
+
+/**
+ * Support for the Hibernate Transaction API.
+ *
+ * Adapts Hibernate transaction management to a Seam UserTransaction
+ * interface. For use in non-JTA-capable environments.
+ *
+ * @author Gavin King
+ *
+ */
+@Name("org.jboss.seam.transaction.transaction")
+(a)Scope(ScopeType.EVENT)
+@Install(value=false, precedence=FRAMEWORK)
+@BypassInterceptors
+public class HibernateTransaction extends AbstractUserTransaction
+{
+ private static final LogProvider log = Logging.getLogProvider(HibernateTransaction.class);
+
+ private ValueExpression<Session> session;
+ private Session currentSession;
+ private boolean rollbackOnly; //Hibernate Transaction doesn't have a "rollback only" state
+
+ @Create
+ public void validate()
+ {
+ if (session==null)
+ {
+ session = Expressions.instance().createValueExpression("#{session}", Session.class);
+ }
+ }
+
+ private org.hibernate.Transaction getDelegate()
+ {
+ if (currentSession==null)
+ {
+ //should never occur
+ throw new IllegalStateException("session is null");
+ }
+ return currentSession.getTransaction();
+ }
+
+ private void initSession()
+ {
+ currentSession = session.getValue();
+ if (currentSession==null)
+ {
+ throw new IllegalStateException("session was null: " + session.getExpressionString());
+ }
+ }
+
+ public void begin() throws NotSupportedException, SystemException
+ {
+ log.debug("beginning Hibernate transaction");
+ assertNotActive();
+ initSession();
+ try
+ {
+ getDelegate().begin();
+ }
+ catch (RuntimeException re)
+ {
+ clearSession();
+ throw re;
+ }
+ }
+
+ public void commit() throws RollbackException, HeuristicMixedException,
+ HeuristicRollbackException, SecurityException, IllegalStateException, SystemException
+ {
+ log.debug("committing Hibernate transaction");
+ //TODO: translate exceptions that occur into the correct JTA exception
+ assertActive();
+ Transaction delegate = getDelegate();
+ clearSession();
+ if (rollbackOnly)
+ {
+ rollbackOnly = false;
+ delegate.rollback();
+ throw new RollbackException();
+ }
+ else
+ {
+ delegate.commit();
+ }
+ }
+
+ public void rollback() throws IllegalStateException, SecurityException, SystemException
+ {
+ log.debug("rolling back Hibernate transaction");
+ //TODO: translate exceptions that occur into the correct JTA exception
+ assertActive();
+ Transaction delegate = getDelegate();
+ clearSession();
+ rollbackOnly = false;
+ delegate.rollback();
+ }
+
+ public void setRollbackOnly() throws IllegalStateException, SystemException
+ {
+ log.debug("marking Hibernate transaction for rollback");
+ assertActive();
+ rollbackOnly = true;
+ }
+
+ public int getStatus() throws SystemException
+ {
+ if (rollbackOnly)
+ {
+ return Status.STATUS_MARKED_ROLLBACK;
+ }
+ else if ( isSessionSet() && getDelegate().isActive() )
+ {
+ return Status.STATUS_ACTIVE;
+ }
+ else
+ {
+ return Status.STATUS_NO_TRANSACTION;
+ }
+ }
+
+ public void setTransactionTimeout(int timeout) throws SystemException
+ {
+ assertActive();
+ getDelegate().setTimeout(timeout);
+ }
+
+ private boolean isSessionSet()
+ {
+ return currentSession!=null;
+ }
+
+ private void clearSession()
+ {
+ currentSession = null;
+ }
+
+ private void assertActive()
+ {
+ if ( !isSessionSet() )
+ {
+ throw new IllegalStateException("transaction is not active");
+ }
+ }
+
+ private void assertNotActive() throws NotSupportedException
+ {
+ //TODO: translate exceptions that occur into the correct JTA exception
+ if ( isSessionSet() )
+ {
+ throw new NotSupportedException("transaction is already active");
+ }
+ }
+
+ @Override
+ public void registerSynchronization(Synchronization sync)
+ {
+ if ( log.isDebugEnabled() )
+ {
+ log.debug("registering synchronization: " + sync);
+ }
+ assertActive();
+ getDelegate().registerSynchronization(sync);
+ }
+
+ @Override
+ public void enlist(EntityManager entityManager) throws SystemException
+ {
+ throw new UnsupportedOperationException("JPA EntityManager should not be used with Hibernate Transaction API");
+ }
+
+ @Override
+ public boolean isConversationContextRequired()
+ {
+ return true;
+ }
+
+ public ValueExpression<Session> getSession()
+ {
+ return session;
+ }
+
+ public void setSession(ValueExpression<Session> entityManager)
+ {
+ this.session = entityManager;
+ }
+
+}
Added: modules/trunk/transaction/src/main/java/org/jboss/seam/transaction/LocalEjbSynchronizations.java
===================================================================
--- modules/trunk/transaction/src/main/java/org/jboss/seam/transaction/LocalEjbSynchronizations.java (rev 0)
+++ modules/trunk/transaction/src/main/java/org/jboss/seam/transaction/LocalEjbSynchronizations.java 2009-04-27 12:50:30 UTC (rev 10652)
@@ -0,0 +1,15 @@
+package org.jboss.seam.transaction;
+
+import javax.ejb.Local;
+
+/**
+ * Local interface for EjbTransaction
+ *
+ * @author Gavin King
+ *
+ */
+@Local
+public interface LocalEjbSynchronizations extends Synchronizations
+{
+ public void destroy();
+}
Added: modules/trunk/transaction/src/main/java/org/jboss/seam/transaction/NoTransaction.java
===================================================================
--- modules/trunk/transaction/src/main/java/org/jboss/seam/transaction/NoTransaction.java (rev 0)
+++ modules/trunk/transaction/src/main/java/org/jboss/seam/transaction/NoTransaction.java 2009-04-27 12:50:30 UTC (rev 10652)
@@ -0,0 +1,77 @@
+package org.jboss.seam.transaction;
+
+import static org.jboss.seam.annotations.Install.FRAMEWORK;
+
+import javax.persistence.EntityManager;
+import javax.transaction.HeuristicMixedException;
+import javax.transaction.HeuristicRollbackException;
+import javax.transaction.NotSupportedException;
+import javax.transaction.RollbackException;
+import javax.transaction.Status;
+import javax.transaction.Synchronization;
+import javax.transaction.SystemException;
+
+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;
+
+/**
+ * When no kind of transaction management exists.
+ *
+ * @author Mike Youngstrom
+ * @author Gavin King
+ *
+ */
+@Name("org.jboss.seam.transaction.transaction")
+(a)Scope(ScopeType.EVENT)
+@Install(value = false, precedence = FRAMEWORK)
+@BypassInterceptors
+public class NoTransaction extends AbstractUserTransaction
+{
+
+ public void begin() throws NotSupportedException, SystemException
+ {
+ throw new UnsupportedOperationException("no transaction");
+ }
+
+ public void commit() throws RollbackException, HeuristicMixedException,
+ HeuristicRollbackException, SecurityException, IllegalStateException, SystemException
+ {
+ throw new UnsupportedOperationException("no transaction");
+ }
+
+ public int getStatus() throws SystemException
+ {
+ return Status.STATUS_NO_TRANSACTION;
+ }
+
+ public void rollback() throws IllegalStateException, SecurityException, SystemException
+ {
+ throw new UnsupportedOperationException("no transaction");
+ }
+
+ public void setRollbackOnly() throws IllegalStateException, SystemException
+ {
+ throw new UnsupportedOperationException("no transaction");
+ }
+
+ public void setTransactionTimeout(int timeout) throws SystemException
+ {
+ throw new UnsupportedOperationException("no transaction");
+ }
+
+ @Override
+ public void registerSynchronization(Synchronization sync)
+ {
+ throw new UnsupportedOperationException("no transaction");
+ }
+
+ @Override
+ public void enlist(EntityManager entityManager) throws SystemException
+ {
+ //no-op
+ }
+
+}
Added: modules/trunk/transaction/src/main/java/org/jboss/seam/transaction/RollbackInterceptor.java
===================================================================
--- modules/trunk/transaction/src/main/java/org/jboss/seam/transaction/RollbackInterceptor.java (rev 0)
+++ modules/trunk/transaction/src/main/java/org/jboss/seam/transaction/RollbackInterceptor.java 2009-04-27 12:50:30 UTC (rev 10652)
@@ -0,0 +1,50 @@
+//$Id: RollbackInterceptor.java 8626 2008-08-07 19:50:09Z pete.muir(a)jboss.org $
+package org.jboss.seam.transaction;
+
+import static org.jboss.seam.ComponentType.JAVA_BEAN;
+import static org.jboss.seam.util.Work.isRollbackRequired;
+
+import org.jboss.seam.annotations.intercept.AroundInvoke;
+import org.jboss.seam.annotations.intercept.Interceptor;
+import org.jboss.seam.intercept.AbstractInterceptor;
+import org.jboss.seam.intercept.InvocationContext;
+
+/**
+ * Automatically sets the current transaction to rollback
+ * only when an exception is thrown.
+ *
+ * @author Gavin King
+ */
+@Interceptor(stateless=true)
+public class RollbackInterceptor extends AbstractInterceptor
+{
+ private static final long serialVersionUID = 5551801508325093417L;
+
+ @AroundInvoke
+ public Object aroundInvoke(InvocationContext invocation) throws Exception
+ {
+ try
+ {
+ return invocation.proceed();
+ }
+ catch (Exception e)
+ {
+ if ( isRollbackRequired(e, getComponent().getType() == JAVA_BEAN) )
+ {
+ try
+ {
+ Transaction.instance().setRollbackOnly();
+ }
+ catch (Exception te) {} //swallow
+ }
+ throw e;
+ }
+ }
+
+ public boolean isInterceptorEnabled()
+ {
+ // Just here for consistency
+ return true;
+ }
+
+}
Added: modules/trunk/transaction/src/main/java/org/jboss/seam/transaction/SeSynchronizations.java
===================================================================
--- modules/trunk/transaction/src/main/java/org/jboss/seam/transaction/SeSynchronizations.java (rev 0)
+++ modules/trunk/transaction/src/main/java/org/jboss/seam/transaction/SeSynchronizations.java 2009-04-27 12:50:30 UTC (rev 10652)
@@ -0,0 +1,71 @@
+package org.jboss.seam.transaction;
+
+import static org.jboss.seam.annotations.Install.BUILT_IN;
+
+import java.util.Stack;
+
+import javax.transaction.Synchronization;
+
+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;
+
+/**
+ * This implementation does not have access
+ * to the JTA TransactionManager, so it is not fully aware
+ * of container managed transaction lifecycle, and is not
+ * able to register Synchronizations with a container managed
+ * transaction.
+ *
+ * @author Gavin King
+ *
+ */
+@Name("org.jboss.seam.transaction.synchronizations")
+(a)Scope(ScopeType.EVENT)
+@Install(precedence=BUILT_IN)
+@BypassInterceptors
+public class SeSynchronizations implements Synchronizations
+{
+ protected Stack<SynchronizationRegistry> synchronizations = new Stack<SynchronizationRegistry>();
+
+ public void afterTransactionBegin()
+ {
+ synchronizations.push( new SynchronizationRegistry() );
+ }
+
+ public void afterTransactionCommit(boolean success)
+ {
+ synchronizations.pop().afterTransactionCompletion(success);
+ }
+
+ public void afterTransactionRollback()
+ {
+ synchronizations.pop().afterTransactionCompletion(false);
+ }
+
+ public void beforeTransactionCommit()
+ {
+ synchronizations.peek().beforeTransactionCompletion();
+ }
+
+ public void registerSynchronization(Synchronization sync)
+ {
+ if (synchronizations.isEmpty())
+ {
+ throw new IllegalStateException("Transaction begin not detected, " +
+ "try installing transaction:ejb-transaction in components.xml");
+ }
+ else
+ {
+ synchronizations.peek().registerSynchronization(sync);
+ }
+ }
+
+ public boolean isAwareOfContainerTransactions()
+ {
+ return false;
+ }
+
+}
Added: modules/trunk/transaction/src/main/java/org/jboss/seam/transaction/SynchronizationRegistry.java
===================================================================
--- modules/trunk/transaction/src/main/java/org/jboss/seam/transaction/SynchronizationRegistry.java (rev 0)
+++ modules/trunk/transaction/src/main/java/org/jboss/seam/transaction/SynchronizationRegistry.java 2009-04-27 12:50:30 UTC (rev 10652)
@@ -0,0 +1,71 @@
+package org.jboss.seam.transaction;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.transaction.Status;
+import javax.transaction.Synchronization;
+
+import org.jboss.seam.core.Events;
+import org.jboss.seam.log.LogProvider;
+import org.jboss.seam.log.Logging;
+
+/**
+ * A list of Synchronizations to be invoked before and after transaction
+ * completion. This class is used when we can't register a synchronization
+ * directly with JTA.
+ *
+ * @author Gavin King
+ *
+ */
+class SynchronizationRegistry
+{
+ private static final LogProvider log = Logging.getLogProvider(SynchronizationRegistry.class);
+
+ private List<Synchronization> synchronizations = new ArrayList<Synchronization>();
+
+ void registerSynchronization(Synchronization sync)
+ {
+ synchronizations.add(sync);
+ }
+
+ void afterTransactionCompletion(boolean success)
+ {
+ if ( Events.exists() )
+ {
+ Events.instance().raiseEvent("org.jboss.seam.afterTransactionCompletion", success);
+ }
+ for (Synchronization sync: synchronizations)
+ {
+ try
+ {
+ sync.afterCompletion(success ? Status.STATUS_COMMITTED : Status.STATUS_ROLLEDBACK);
+ }
+ catch (Exception e)
+ {
+ log.error("Exception processing transaction Synchronization after completion", e);
+ }
+ }
+ synchronizations.clear();
+ }
+
+ void beforeTransactionCompletion()
+ {
+ if ( Events.exists() )
+ {
+ Events.instance().raiseEvent("org.jboss.seam.beforeTransactionCompletion");
+ }
+ for (Synchronization sync: synchronizations)
+ {
+ try
+ {
+ sync.beforeCompletion();
+ }
+ catch (Exception e)
+ {
+ log.error("Exception processing transaction Synchronization before completion", e);
+ }
+ }
+ }
+
+}
Added: modules/trunk/transaction/src/main/java/org/jboss/seam/transaction/Synchronizations.java
===================================================================
--- modules/trunk/transaction/src/main/java/org/jboss/seam/transaction/Synchronizations.java (rev 0)
+++ modules/trunk/transaction/src/main/java/org/jboss/seam/transaction/Synchronizations.java 2009-04-27 12:50:30 UTC (rev 10652)
@@ -0,0 +1,19 @@
+package org.jboss.seam.transaction;
+
+import javax.transaction.Synchronization;
+
+/**
+ * Interface for registering transaction synchronizations
+ *
+ * @author Gavin King
+ *
+ */
+public interface Synchronizations
+{
+ public void afterTransactionBegin();
+ public void afterTransactionCommit(boolean success);
+ public void afterTransactionRollback();
+ public void beforeTransactionCommit();
+ public void registerSynchronization(Synchronization sync);
+ public boolean isAwareOfContainerTransactions();
+}
\ No newline at end of file
Added: modules/trunk/transaction/src/main/java/org/jboss/seam/transaction/Transaction.java
===================================================================
--- modules/trunk/transaction/src/main/java/org/jboss/seam/transaction/Transaction.java (rev 0)
+++ modules/trunk/transaction/src/main/java/org/jboss/seam/transaction/Transaction.java 2009-04-27 12:50:30 UTC (rev 10652)
@@ -0,0 +1,100 @@
+package org.jboss.seam.transaction;
+
+import static org.jboss.seam.annotations.Install.BUILT_IN;
+
+import javax.naming.InitialContext;
+import javax.naming.NameNotFoundException;
+import javax.naming.NamingException;
+
+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.util.EJB;
+import org.jboss.seam.util.Naming;
+
+/**
+ * Supports injection of a Seam UserTransaction object that
+ * wraps the current JTA transaction or EJB container managed
+ * transaction.
+ *
+ * @author Mike Youngstrom
+ * @author Gavin King
+ *
+ */
+@Name("org.jboss.seam.transaction.transaction")
+(a)Scope(ScopeType.EVENT)
+@Install(precedence=BUILT_IN)
+@BypassInterceptors
+public class Transaction
+{
+ // Event keys
+ public static final String TRANSACTION_FAILED = "org.jboss.seam.transaction.transactionFailed";
+
+ public static UserTransaction instance()
+ {
+ return (UserTransaction) Component.getInstance(Transaction.class, ScopeType.EVENT);
+ }
+
+ @Unwrap
+ public UserTransaction getTransaction() throws NamingException
+ {
+ try
+ {
+ return createUTTransaction();
+ }
+ catch (NameNotFoundException nnfe)
+ {
+ try
+ {
+ return createCMTTransaction();
+ }
+ catch (NameNotFoundException nnfe2)
+ {
+ return createNoTransaction();
+ }
+ }
+ }
+
+ protected UserTransaction createNoTransaction()
+ {
+ return new NoTransaction();
+ }
+
+ protected UserTransaction createCMTTransaction() throws NamingException
+ {
+ return new CMTTransaction( EJB.getEJBContext() );
+ }
+
+ protected UserTransaction createUTTransaction() throws NamingException
+ {
+ return new UTTransaction( getUserTransaction() );
+ }
+
+ protected javax.transaction.UserTransaction getUserTransaction() throws NamingException
+ {
+ InitialContext context = Naming.getInitialContext();
+ try
+ {
+ return (javax.transaction.UserTransaction) context.lookup("java:comp/UserTransaction");
+ }
+ catch (NameNotFoundException nnfe)
+ {
+ try
+ {
+ //Embedded JBoss has no java:comp/UserTransaction
+ javax.transaction.UserTransaction ut = (javax.transaction.UserTransaction) context.lookup("UserTransaction");
+ ut.getStatus(); //for glassfish, which can return an unusable UT
+ return ut;
+ }
+ catch (Exception e)
+ {
+ throw nnfe;
+ }
+ }
+ }
+
+}
Added: modules/trunk/transaction/src/main/java/org/jboss/seam/transaction/TransactionInterceptor.java
===================================================================
--- modules/trunk/transaction/src/main/java/org/jboss/seam/transaction/TransactionInterceptor.java (rev 0)
+++ modules/trunk/transaction/src/main/java/org/jboss/seam/transaction/TransactionInterceptor.java 2009-04-27 12:50:30 UTC (rev 10652)
@@ -0,0 +1,128 @@
+package org.jboss.seam.transaction;
+
+import static org.jboss.seam.ComponentType.JAVA_BEAN;
+
+import java.lang.reflect.AnnotatedElement;
+import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.jboss.seam.annotations.TransactionPropagationType;
+import org.jboss.seam.annotations.Transactional;
+import org.jboss.seam.annotations.intercept.AroundInvoke;
+import org.jboss.seam.annotations.intercept.Interceptor;
+import org.jboss.seam.bpm.BusinessProcessInterceptor;
+import org.jboss.seam.core.BijectionInterceptor;
+import org.jboss.seam.core.ConversationInterceptor;
+import org.jboss.seam.intercept.AbstractInterceptor;
+import org.jboss.seam.intercept.InvocationContext;
+import org.jboss.seam.util.Work;
+
+/**
+ * Implements transaction propagation rules for Seam JavaBean components.
+ *
+ * @author Gavin King
+ * @author Shane Bryzak
+ */
+@Interceptor(stateless=false,
+ around={RollbackInterceptor.class, BusinessProcessInterceptor.class,
+ ConversationInterceptor.class, BijectionInterceptor.class})
+public class TransactionInterceptor extends AbstractInterceptor
+{
+ private static final long serialVersionUID = -4364203056333738988L;
+
+ transient
+ private Map<AnnotatedElement,TransactionMetadata> transactionMetadata = new HashMap<AnnotatedElement, TransactionMetadata>();
+
+ private class TransactionMetadata
+ {
+ private boolean annotationPresent;
+ TransactionPropagationType propType;
+
+ public TransactionMetadata(AnnotatedElement element)
+ {
+ annotationPresent = element.isAnnotationPresent(Transactional.class);
+
+ if (annotationPresent)
+ {
+ propType = element.getAnnotation(Transactional.class).value();
+ }
+ }
+
+ public boolean isAnnotationPresent()
+ {
+ return annotationPresent;
+ }
+
+ public boolean isNewTransactionRequired(boolean transactionActive)
+ {
+ return propType != null && propType.isNewTransactionRequired(transactionActive);
+ }
+ }
+
+ private TransactionMetadata lookupTransactionMetadata(AnnotatedElement element) {
+ if (transactionMetadata == null) {
+ transactionMetadata = new HashMap<AnnotatedElement, TransactionMetadata>();
+ }
+
+ TransactionMetadata metadata = transactionMetadata.get(element);
+
+ if (metadata == null) {
+ metadata = loadMetadata(element);
+ }
+
+ return metadata;
+ }
+
+ private synchronized TransactionMetadata loadMetadata(AnnotatedElement element) {
+ if (!transactionMetadata.containsKey(element)) {
+ TransactionMetadata metadata = new TransactionMetadata(element);
+ transactionMetadata.put(element, metadata);
+ return metadata;
+ }
+
+ return transactionMetadata.get(element);
+ }
+
+
+ @AroundInvoke
+ public Object aroundInvoke(final InvocationContext invocation) throws Exception
+ {
+ return new Work()
+ {
+
+ @Override
+ protected Object work() throws Exception
+ {
+ return invocation.proceed();
+ }
+
+ @Override
+ protected boolean isNewTransactionRequired(boolean transactionActive)
+ {
+ return isNewTransactionRequired( invocation.getMethod(), getComponent().getBeanClass(), transactionActive );
+ }
+
+ private boolean isNewTransactionRequired(Method method, Class beanClass, boolean transactionActive)
+ {
+ TransactionMetadata metadata = lookupTransactionMetadata(method);
+ if (metadata.isAnnotationPresent())
+ {
+ return metadata.isNewTransactionRequired(transactionActive);
+ }
+ else
+ {
+ metadata = lookupTransactionMetadata(beanClass);
+ return metadata.isNewTransactionRequired(transactionActive);
+ }
+ }
+
+ }.workInTransaction();
+ }
+
+ public boolean isInterceptorEnabled()
+ {
+ return getComponent().getType()==JAVA_BEAN && getComponent().beanClassHasAnnotation(Transactional.class);
+ }
+
+}
Added: modules/trunk/transaction/src/main/java/org/jboss/seam/transaction/UTTransaction.java
===================================================================
--- modules/trunk/transaction/src/main/java/org/jboss/seam/transaction/UTTransaction.java (rev 0)
+++ modules/trunk/transaction/src/main/java/org/jboss/seam/transaction/UTTransaction.java 2009-04-27 12:50:30 UTC (rev 10652)
@@ -0,0 +1,95 @@
+package org.jboss.seam.transaction;
+
+import javax.transaction.HeuristicMixedException;
+import javax.transaction.HeuristicRollbackException;
+import javax.transaction.NotSupportedException;
+import javax.transaction.RollbackException;
+import javax.transaction.Synchronization;
+import javax.transaction.SystemException;
+
+import org.jboss.seam.log.LogProvider;
+import org.jboss.seam.log.Logging;
+
+/**
+ * Wraps JTA transaction management in a Seam UserTransaction
+ * interface.
+ *
+ * @author Mike Youngstrom
+ * @author Gavin King
+ *
+ */
+public class UTTransaction extends AbstractUserTransaction
+{
+ private static final LogProvider log = Logging.getLogProvider(UTTransaction.class);
+
+ private final javax.transaction.UserTransaction delegate;
+
+ UTTransaction(javax.transaction.UserTransaction delegate)
+ {
+ this.delegate = delegate;
+ if (delegate==null)
+ {
+ throw new IllegalArgumentException("null UserTransaction");
+ }
+ }
+
+ public void begin() throws NotSupportedException, SystemException
+ {
+ log.debug("beginning JTA transaction");
+ delegate.begin();
+ getSynchronizations().afterTransactionBegin();
+ }
+
+ public void commit() throws RollbackException, HeuristicMixedException,
+ HeuristicRollbackException, SecurityException, IllegalStateException, SystemException
+ {
+ log.debug("committing JTA transaction");
+ boolean success = false;
+ Synchronizations synchronizations = getSynchronizations();
+ synchronizations.beforeTransactionCommit();
+ try
+ {
+ delegate.commit();
+ success = true;
+ }
+ finally
+ {
+ synchronizations.afterTransactionCommit(success);
+ }
+ }
+
+ public void rollback() throws IllegalStateException, SecurityException, SystemException
+ {
+ log.debug("rolling back JTA transaction");
+ try
+ {
+ delegate.rollback();
+ }
+ finally
+ {
+ getSynchronizations().afterTransactionRollback();
+ }
+ }
+
+ public int getStatus() throws SystemException
+ {
+ return delegate.getStatus();
+ }
+
+ public void setRollbackOnly() throws IllegalStateException, SystemException
+ {
+ delegate.setRollbackOnly();
+ }
+
+ public void setTransactionTimeout(int timeout) throws SystemException
+ {
+ delegate.setTransactionTimeout(timeout);
+ }
+
+ @Override
+ public void registerSynchronization(Synchronization sync)
+ {
+ getSynchronizations().registerSynchronization(sync);
+ }
+
+}
Added: modules/trunk/transaction/src/main/java/org/jboss/seam/transaction/UserTransaction.java
===================================================================
--- modules/trunk/transaction/src/main/java/org/jboss/seam/transaction/UserTransaction.java (rev 0)
+++ modules/trunk/transaction/src/main/java/org/jboss/seam/transaction/UserTransaction.java 2009-04-27 12:50:30 UTC (rev 10652)
@@ -0,0 +1,29 @@
+package org.jboss.seam.transaction;
+
+import javax.persistence.EntityManager;
+import javax.transaction.Synchronization;
+import javax.transaction.SystemException;
+
+/**
+ * Extends the standard UserTransaction interface with a couple
+ * of helpful methods.
+ *
+ * @author Gavin King
+ *
+ */
+public interface UserTransaction extends javax.transaction.UserTransaction
+{
+
+ public boolean isActive() throws SystemException;
+ public boolean isActiveOrMarkedRollback() throws SystemException;
+ public boolean isRolledBackOrMarkedRollback() throws SystemException;
+ public boolean isMarkedRollback() throws SystemException;
+ public boolean isNoTransaction() throws SystemException;
+ public boolean isRolledBack() throws SystemException;
+ public boolean isCommitted() throws SystemException;
+
+ public boolean isConversationContextRequired();
+ public abstract void registerSynchronization(Synchronization sync);
+
+ public void enlist(EntityManager entityManager) throws SystemException;
+}
Added: modules/trunk/transaction/src/main/java/org/jboss/seam/transaction/package-info.java
===================================================================
--- modules/trunk/transaction/src/main/java/org/jboss/seam/transaction/package-info.java (rev 0)
+++ modules/trunk/transaction/src/main/java/org/jboss/seam/transaction/package-info.java 2009-04-27 12:50:30 UTC (rev 10652)
@@ -0,0 +1,20 @@
+/**
+ * Abstracts all possible transaction management APIs behind a
+ * JTA-compatible interface. Unfortunately, many
+ * otherwise-perfectly-intelligent-looking Java developers like
+ * to invent their own transaction management APIs when they get
+ * bored, even though JTA is well-known to be more than good
+ * enough. For example, one of the co-authors of this class was
+ * present at the creation of not one but two "alternative"
+ * transaction APIs (org.hibernate.Transaction and
+ * javax.persistence.EntityTransaction), and is more
+ * embarrassed by this than by any other of his many professional
+ * blunders.
+ *
+ * @see org.jboss.seam.transaction.Transaction
+ * @see org.jboss.seam.transaction.UserTransaction
+ */
+@Namespace(value="http://jboss.com/products/seam/transaction", prefix="org.jboss.seam.transaction")
+package org.jboss.seam.transaction;
+
+import org.jboss.seam.annotations.Namespace;
[View Less]
15 years, 10 months
Seam SVN: r10651 - modules/trunk/persistence.
by seam-commits@lists.jboss.org
Author: shane.bryzak(a)jboss.com
Date: 2009-04-27 08:49:44 -0400 (Mon, 27 Apr 2009)
New Revision: 10651
Modified:
modules/trunk/persistence/
Log:
ignores
Property changes on: modules/trunk/persistence
___________________________________________________________________
Name: svn:ignore
+ .classpath
.project
.settings
target
15 years, 10 months
Seam SVN: r10650 - in modules/trunk: persistence and 9 other directories.
by seam-commits@lists.jboss.org
Author: shane.bryzak(a)jboss.com
Date: 2009-04-27 08:48:53 -0400 (Mon, 27 Apr 2009)
New Revision: 10650
Added:
modules/trunk/persistence/
modules/trunk/persistence/pom.xml
modules/trunk/persistence/src/
modules/trunk/persistence/src/main/
modules/trunk/persistence/src/main/java/
modules/trunk/persistence/src/main/java/org/
modules/trunk/persistence/src/main/java/org/jboss/
modules/trunk/persistence/src/main/java/org/jboss/seam/
modules/trunk/persistence/src/main/java/…
[View More]org/jboss/seam/persistence/
modules/trunk/persistence/src/main/java/org/jboss/seam/persistence/AbstractPersistenceProvider.java
modules/trunk/persistence/src/main/java/org/jboss/seam/persistence/Entity.java
modules/trunk/persistence/src/main/java/org/jboss/seam/persistence/EntityManagerFactory.java
modules/trunk/persistence/src/main/java/org/jboss/seam/persistence/EntityManagerProxy.java
modules/trunk/persistence/src/main/java/org/jboss/seam/persistence/EntityManagerProxyInterceptor.java
modules/trunk/persistence/src/main/java/org/jboss/seam/persistence/Filter.java
modules/trunk/persistence/src/main/java/org/jboss/seam/persistence/FullTextEntityManagerProxy.java
modules/trunk/persistence/src/main/java/org/jboss/seam/persistence/FullTextHibernateSessionProxy.java
modules/trunk/persistence/src/main/java/org/jboss/seam/persistence/HibernatePersistenceProvider.java
modules/trunk/persistence/src/main/java/org/jboss/seam/persistence/HibernateSessionFactory.java
modules/trunk/persistence/src/main/java/org/jboss/seam/persistence/HibernateSessionProxy.java
modules/trunk/persistence/src/main/java/org/jboss/seam/persistence/HibernateSessionProxyInterceptor.java
modules/trunk/persistence/src/main/java/org/jboss/seam/persistence/ManagedEntityInterceptor.java
modules/trunk/persistence/src/main/java/org/jboss/seam/persistence/ManagedEntityWrapper.java
modules/trunk/persistence/src/main/java/org/jboss/seam/persistence/ManagedHibernateSession.java
modules/trunk/persistence/src/main/java/org/jboss/seam/persistence/ManagedPersistenceContext.java
modules/trunk/persistence/src/main/java/org/jboss/seam/persistence/Model.java
modules/trunk/persistence/src/main/java/org/jboss/seam/persistence/PersistenceContextManager.java
modules/trunk/persistence/src/main/java/org/jboss/seam/persistence/PersistenceContexts.java
modules/trunk/persistence/src/main/java/org/jboss/seam/persistence/PersistenceProvider.java
modules/trunk/persistence/src/main/java/org/jboss/seam/persistence/QueryParser.java
modules/trunk/persistence/src/main/java/org/jboss/seam/persistence/annotations/
modules/trunk/persistence/src/main/java/org/jboss/seam/persistence/annotations/FlushModeType.java
modules/trunk/persistence/src/main/java/org/jboss/seam/persistence/util/
modules/trunk/persistence/src/main/java/org/jboss/seam/persistence/util/Naming.java
modules/trunk/persistence/src/main/java/org/jboss/seam/persistence/util/Reflections.java
modules/trunk/persistence/src/main/java/org/jboss/seam/persistence/util/Strings.java
Log:
initial import of persistence module
Added: modules/trunk/persistence/pom.xml
===================================================================
--- modules/trunk/persistence/pom.xml (rev 0)
+++ modules/trunk/persistence/pom.xml 2009-04-27 12:48:53 UTC (rev 10650)
@@ -0,0 +1,44 @@
+<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-persistence</artifactId>
+ <packaging>jar</packaging>
+ <version>3.0.0-SNAPSHOT</version>
+ <name>Seam Persistence</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>javax.persistence</groupId>
+ <artifactId>persistence-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>javax.transaction</groupId>
+ <artifactId>jta</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.hibernate</groupId>
+ <artifactId>hibernate</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.jboss.seam</groupId>
+ <artifactId>seam-el</artifactId>
+ </dependency>
+ </dependencies>
+
+</project>
Added: modules/trunk/persistence/src/main/java/org/jboss/seam/persistence/AbstractPersistenceProvider.java
===================================================================
--- modules/trunk/persistence/src/main/java/org/jboss/seam/persistence/AbstractPersistenceProvider.java (rev 0)
+++ modules/trunk/persistence/src/main/java/org/jboss/seam/persistence/AbstractPersistenceProvider.java 2009-04-27 12:48:53 UTC (rev 10650)
@@ -0,0 +1,145 @@
+package org.jboss.seam.persistence;
+
+import java.lang.reflect.Method;
+import java.util.Date;
+
+import javax.persistence.EntityManager;
+import javax.persistence.OptimisticLockException;
+import javax.transaction.Synchronization;
+
+/**
+ * Provides a default implementation of PersistenceProvider methods where possible
+ *
+ * Other methods must be implemented
+ *
+ * @author Pete Muir
+ *
+ */
+public abstract class AbstractPersistenceProvider
+{
+
+ /**
+ * Set the flush mode to manual-only flushing. Called when
+ * an atomic persistence context is required.
+ */
+ public abstract void setFlushModeManual(EntityManager entityManager);
+
+ /**
+ * Does the persistence context have unflushed changes? If
+ * it does not, persistence context replication can be
+ * optimized.
+ *
+ * @return true to indicate that there are unflushed changes
+ */
+ public abstract boolean isDirty(EntityManager entityManager);
+
+ /**
+ * Get the value of the entity identifier attribute.
+ *
+ * @param bean a managed entity instance
+ */
+ public Object getId(Object bean, EntityManager entityManager)
+ {
+ return Entity.forClass( bean.getClass() ).getIdentifier(bean);
+ }
+
+ /**
+ * Get the name of the entity
+ *
+ * @param bean
+ * @param entityManager
+ *
+ * @throws IllegalArgumentException if the passed object is not an entity
+ */
+ public String getName(Object bean, EntityManager entityManager) throws IllegalArgumentException
+ {
+ return Entity.forClass(bean.getClass()).getName();
+ }
+
+ /**
+ * Get the value of the entity version attribute.
+ *
+ * @param bean a managed entity instance
+ */
+ public Object getVersion(Object bean, EntityManager entityManager)
+ {
+ return Entity.forClass( bean.getClass() ).getVersion(bean);
+ }
+
+ public void checkVersion(Object bean, EntityManager entityManager, Object oldVersion, Object version)
+ {
+ boolean equal;
+ if (oldVersion instanceof Date)
+ {
+ equal = ( (Date) oldVersion ).getTime() == ( (Date) version ).getTime();
+ }
+ else
+ {
+ equal = oldVersion.equals(version);
+ }
+ if ( !equal )
+ {
+ throw new OptimisticLockException("current database version number does not match passivated version number");
+ }
+ }
+
+ /**
+ * Enable a Filter. This is here just especially for Hibernate,
+ * since we well know that other products don't have such cool
+ * features.
+ */
+ public abstract void enableFilter(Filter filter, EntityManager entityManager);
+
+ /**
+ * Register a Synchronization with the current transaction.
+ */
+ public abstract boolean registerSynchronization(Synchronization sync, EntityManager entityManager);
+
+ /**
+ * Wrap the delegate before returning it to the application
+ */
+ public Object proxyDelegate(Object delegate)
+ {
+ return delegate;
+ }
+
+ /**
+ * Wrap the entityManager before returning it to the application
+ */
+ public EntityManager proxyEntityManager(EntityManager entityManager)
+ {
+ return new EntityManagerProxy(entityManager);
+ }
+
+ /**
+ * Returns the class of an entity bean instance
+ *
+ * @param bean The entity bean instance
+ * @return The class of the entity bean
+ */
+ public Class getBeanClass(Object bean)
+ {
+ return Entity.forClass(bean.getClass()).getBeanClass();
+ }
+
+ public Method getPostLoadMethod(Class beanClass, EntityManager entityManager)
+ {
+ return Entity.forClass(beanClass).getPostLoadMethod();
+ }
+
+ public Method getPrePersistMethod(Class beanClass, EntityManager entityManager)
+ {
+ return Entity.forClass(beanClass).getPrePersistMethod();
+ }
+
+ public Method getPreUpdateMethod(Class beanClass, EntityManager entityManager)
+ {
+ return Entity.forClass(beanClass).getPreUpdateMethod();
+ }
+
+ public Method getPreRemoveMethod(Class beanClass, EntityManager entityManager)
+ {
+ return Entity.forClass(beanClass).getPreRemoveMethod();
+ }
+
+}
\ No newline at end of file
Added: modules/trunk/persistence/src/main/java/org/jboss/seam/persistence/Entity.java
===================================================================
--- modules/trunk/persistence/src/main/java/org/jboss/seam/persistence/Entity.java (rev 0)
+++ modules/trunk/persistence/src/main/java/org/jboss/seam/persistence/Entity.java 2009-04-27 12:48:53 UTC (rev 10650)
@@ -0,0 +1,281 @@
+package org.jboss.seam.persistence;
+
+import java.lang.reflect.AccessibleObject;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.context.ApplicationScoped;
+import javax.persistence.EmbeddedId;
+import javax.persistence.Id;
+import javax.persistence.PostLoad;
+import javax.persistence.PrePersist;
+import javax.persistence.PreRemove;
+import javax.persistence.PreUpdate;
+import javax.persistence.Version;
+
+import org.jboss.seam.init.EjbDescriptor;
+import org.jboss.seam.init.EjbEntityDescriptor;
+import org.jboss.seam.persistence.util.Reflections;
+
+/**
+ * Metamodel class for entity classes.
+ *
+ * A class will be identified as an entity class if it has an @Entity annotation.
+ *
+ * @author Gavin King
+ *
+ */
+@ApplicationScoped
+public class Entity extends Model
+{
+ public Entity(Class<?> beanClass)
+ {
+ super(beanClass);
+ }
+
+ private Method preRemoveMethod;
+ private Method prePersistMethod;
+ private Method preUpdateMethod;
+ private Method postLoadMethod;
+ private Method identifierGetter;
+ private Field identifierField;
+ private Method versionGetter;
+ private Field versionField;
+ private String name;
+
+ public Method getPostLoadMethod()
+ {
+ return postLoadMethod;
+ }
+
+ public Method getPrePersistMethod()
+ {
+ return prePersistMethod;
+ }
+
+ public Method getPreRemoveMethod()
+ {
+ return preRemoveMethod;
+ }
+
+ public Method getPreUpdateMethod()
+ {
+ return preUpdateMethod;
+ }
+
+ public Object getIdentifier(Object entity)
+ {
+ if (identifierGetter != null)
+ {
+ return Reflections.invokeAndWrap(identifierGetter, entity);
+ }
+ else if (identifierField != null)
+ {
+ return Reflections.getAndWrap(identifierField, entity);
+ }
+ else
+ {
+ throw new IllegalStateException("@Id attribute not found for entity class: " + getBeanClass().getName());
+ }
+ }
+
+ public Object getVersion(Object entity)
+ {
+ if (versionGetter != null)
+ {
+ return Reflections.invokeAndWrap(versionGetter, entity);
+ }
+ else if (versionField != null)
+ {
+ return Reflections.getAndWrap(versionField, entity);
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ public String getName()
+ {
+ return name;
+ }
+
+ public static Entity forBean(Object bean)
+ {
+ return forClass(bean.getClass());
+ }
+
+ public static Entity forClass(Class clazz)
+ {
+ Class entityClass = Seam.getEntityClass(clazz);
+
+ if (entityClass == null)
+ {
+ throw new NotEntityException("Not an entity class: " + clazz.getName());
+ }
+ String name = getModelName(entityClass);
+ Model model = modelCache.get(name);
+ if (model == null || !(model instanceof Entity))
+ {
+ Entity entity = new Entity(entityClass);
+ modelCache.put(name, entity);
+ return entity;
+ }
+ else
+ {
+ return (Entity) model;
+ }
+ }
+
+ private void mergeAnnotationAndOrmXml(EjbEntityDescriptor descriptor)
+ {
+ // Lookup the name of the Entity from XML, annotation or default
+ this.name = lookupName(getBeanClass(), descriptor);
+ if (this.name == null)
+ {
+ throw new NotEntityException("Unable to establish name of entity " + getBeanClass());
+ }
+
+ if (descriptor != null)
+ {
+ // Set any methods and fields we need metadata for from the XML
+ // descriptor. These take priority over annotations
+
+ this.preRemoveMethod = getEntityCallbackMethod(getBeanClass(), descriptor.getPreRemoveMethodName());
+ this.prePersistMethod = getEntityCallbackMethod(getBeanClass(), descriptor.getPrePersistMethodName());
+ this.preUpdateMethod = getEntityCallbackMethod(getBeanClass(), descriptor.getPreUpdateMethodName());
+ this.postLoadMethod = getEntityCallbackMethod(getBeanClass(), descriptor.getPostLoadMethodName());
+
+ this.identifierField = descriptor.getIdentifierFieldName() != null ? Reflections.getField(getBeanClass(), descriptor.getIdentifierFieldName()) : null;
+ this.identifierGetter = descriptor.getIdentifierPropertyName() != null ? Reflections.getGetterMethod(getBeanClass(), descriptor.getIdentifierPropertyName()) : null;
+
+ this.versionField = descriptor.getVersionFieldName() != null ? Reflections.getField(getBeanClass(), descriptor.getVersionFieldName()) : null;
+ this.versionGetter = descriptor.getVersionPropertyName() != null ? Reflections.getGetterMethod(getBeanClass(), descriptor.getVersionPropertyName()) : null;
+ }
+
+ if (descriptor == null || !descriptor.isMetaDataComplete())
+ {
+ for ( Class<?> clazz=getBeanClass(); clazz!=Object.class; clazz = clazz.getSuperclass() )
+ {
+
+ for ( Method method: clazz.getDeclaredMethods() )
+ {
+ //TODO: does the spec allow multiple lifecycle method
+ // in the entity class heirarchy?
+ if (this.preRemoveMethod == null && method.isAnnotationPresent(PreRemove.class))
+ {
+ this.preRemoveMethod = method;
+ }
+ if (this.prePersistMethod == null && method.isAnnotationPresent(PrePersist.class) )
+ {
+ this.prePersistMethod = method;
+ }
+ if (preUpdateMethod == null && method.isAnnotationPresent(PreUpdate.class) )
+ {
+ preUpdateMethod = method;
+ }
+ if (postLoadMethod == null && method.isAnnotationPresent(PostLoad.class) )
+ {
+ postLoadMethod = method;
+ }
+ if (identifierField == null && identifierGetter == null && method.isAnnotationPresent(Id.class) || method.isAnnotationPresent(EmbeddedId.class))
+ {
+ identifierGetter = method;
+ }
+ if (versionField == null && versionGetter == null && method.isAnnotationPresent(Version.class) )
+ {
+ versionGetter = method;
+ }
+ }
+
+ if ( ( identifierGetter == null && identifierField == null ) || ( versionField == null && versionGetter == null ) )
+ {
+ for ( Field field: clazz.getDeclaredFields() )
+ {
+ if ( identifierGetter == null && identifierField == null && (field.isAnnotationPresent(Id.class) || field.isAnnotationPresent(EmbeddedId.class)))
+ {
+ identifierField = field;
+ }
+ if ( versionGetter == null && versionField == null && field.isAnnotationPresent(Version.class) )
+ {
+ versionField = field;
+ }
+ }
+ }
+ }
+ }
+
+ setAccessible(this.preRemoveMethod);
+ setAccessible(this.prePersistMethod);
+ setAccessible(this.preUpdateMethod);
+ setAccessible(this.postLoadMethod);
+ setAccessible(this.identifierField);
+ setAccessible(this.identifierGetter);
+ setAccessible(this.versionField);
+ setAccessible(this.versionGetter);
+ }
+
+ private void setAccessible(AccessibleObject accessibleObject)
+ {
+ if (accessibleObject != null)
+ {
+ accessibleObject.setAccessible(true);
+ }
+ }
+
+ private static String lookupName(Class<?> beanClass, EjbEntityDescriptor descriptor)
+ {
+ if (descriptor != null && descriptor.getEjbName() != null)
+ {
+ // XML overrides annotations
+ return descriptor.getEjbName();
+ }
+ else if ( (descriptor == null || !descriptor.isMetaDataComplete()) && beanClass.isAnnotationPresent(javax.persistence.Entity.class) && !"".equals(beanClass.getAnnotation(javax.persistence.Entity.class).name()))
+ {
+ // Is a name specified?
+ return beanClass.getAnnotation(javax.persistence.Entity.class).name();
+ }
+ else if (descriptor != null || beanClass.isAnnotationPresent(javax.persistence.Entity.class))
+ {
+ // Use the default name if either a descriptor is specified or the
+ // annotation is present
+ return beanClass.getName();
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ private static Method getEntityCallbackMethod(Class beanClass, String callbackMethodName)
+ {
+ try
+ {
+ if (callbackMethodName != null)
+ {
+ return Reflections.getMethod(beanClass, callbackMethodName);
+ }
+ else
+ {
+ return null;
+ }
+ }
+ catch (IllegalArgumentException e)
+ {
+ throw new IllegalArgumentException("Unable to find Entity callback method specified in orm.xml", e);
+ }
+ }
+
+ public static class NotEntityException extends IllegalArgumentException
+ {
+
+ public NotEntityException(String string)
+ {
+ super(string);
+ }
+
+ }
+
+}
Added: modules/trunk/persistence/src/main/java/org/jboss/seam/persistence/EntityManagerFactory.java
===================================================================
--- modules/trunk/persistence/src/main/java/org/jboss/seam/persistence/EntityManagerFactory.java (rev 0)
+++ modules/trunk/persistence/src/main/java/org/jboss/seam/persistence/EntityManagerFactory.java 2009-04-27 12:48:53 UTC (rev 10650)
@@ -0,0 +1,109 @@
+//$Id: EntityManagerFactory.java 6280 2007-09-27 15:29:56Z pmuir $
+package org.jboss.seam.persistence;
+
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.Map;
+
+import javax.annotation.PreDestroy;
+import javax.context.ApplicationScoped;
+import javax.inject.Initializer;
+import javax.inject.Produces;
+import javax.persistence.Persistence;
+
+import org.hibernate.cfg.Environment;
+import org.jboss.seam.persistence.util.Naming;
+
+/**
+ * A Seam component that bootstraps an EntityManagerFactory,
+ * for use of JPA outside of Java EE 5 / Embedded JBoss.
+ *
+ * @author Gavin King
+ */
+@ApplicationScoped
+public class EntityManagerFactory
+{
+ private javax.persistence.EntityManagerFactory entityManagerFactory;
+
+ private String persistenceUnitName;
+ private Map<String, String> persistenceUnitProperties;
+
+ @Produces
+ public javax.persistence.EntityManagerFactory getEntityManagerFactory()
+ {
+ return entityManagerFactory;
+ }
+
+ @Initializer
+ public void startup(Component component) throws Exception
+ {
+ if (persistenceUnitName==null)
+ {
+ persistenceUnitName = component.getName();
+ }
+ entityManagerFactory = createEntityManagerFactory();
+ }
+
+ @PreDestroy
+ public void shutdown()
+ {
+ if (entityManagerFactory!=null)
+ {
+ entityManagerFactory.close();
+ }
+ }
+
+ protected javax.persistence.EntityManagerFactory createEntityManagerFactory()
+ {
+ Map properties = new HashMap();
+ Hashtable<String, String> jndiProperties = Naming.getInitialContextProperties();
+ if ( jndiProperties!=null )
+ {
+ // Prefix regular JNDI properties for Hibernate
+ for (Map.Entry<String, String> entry : jndiProperties.entrySet())
+ {
+ properties.put( Environment.JNDI_PREFIX + "." + entry.getKey(), entry.getValue() );
+ }
+ }
+ if (persistenceUnitProperties!=null)
+ {
+ properties.putAll(persistenceUnitProperties);
+ }
+
+ if ( properties.isEmpty() )
+ {
+ return Persistence.createEntityManagerFactory(persistenceUnitName);
+ }
+ else
+ {
+ return Persistence.createEntityManagerFactory(persistenceUnitName, properties);
+ }
+ }
+
+ /**
+ * The persistence unit name
+ */
+ public String getPersistenceUnitName()
+ {
+ return persistenceUnitName;
+ }
+
+ public void setPersistenceUnitName(String persistenceUnitName)
+ {
+ this.persistenceUnitName = persistenceUnitName;
+ }
+
+ /**
+ * Properties to pass to Persistence.createEntityManagerFactory()
+ */
+ public Map<String, String> getPersistenceUnitProperties()
+ {
+ return persistenceUnitProperties;
+ }
+
+ public void setPersistenceUnitProperties(Map<String, String> persistenceUnitProperties)
+ {
+ this.persistenceUnitProperties = persistenceUnitProperties;
+ }
+
+}
Added: modules/trunk/persistence/src/main/java/org/jboss/seam/persistence/EntityManagerProxy.java
===================================================================
--- modules/trunk/persistence/src/main/java/org/jboss/seam/persistence/EntityManagerProxy.java (rev 0)
+++ modules/trunk/persistence/src/main/java/org/jboss/seam/persistence/EntityManagerProxy.java 2009-04-27 12:48:53 UTC (rev 10650)
@@ -0,0 +1,155 @@
+package org.jboss.seam.persistence;
+
+import java.io.Serializable;
+
+import javax.persistence.EntityManager;
+import javax.persistence.EntityTransaction;
+import javax.persistence.FlushModeType;
+import javax.persistence.LockModeType;
+import javax.persistence.Query;
+
+import org.jboss.seam.security.permission.PermissionManager;
+
+/**
+ * Proxies the EntityManager, and implements EL interpolation
+ * in JPA-QL
+ *
+ * @author Gavin King
+ *
+ */
+public class EntityManagerProxy implements EntityManager, Serializable
+{
+ private EntityManager delegate;
+
+ public EntityManagerProxy(EntityManager entityManager)
+ {
+ delegate = entityManager;
+ }
+
+ public void clear()
+ {
+ delegate.clear();
+ }
+
+ public void close()
+ {
+ delegate.close();
+ }
+
+ public boolean contains(Object entity)
+ {
+ return delegate.contains(entity);
+ }
+
+ public Query createNamedQuery(String name)
+ {
+ return delegate.createNamedQuery(name);
+ }
+
+ public Query createNativeQuery(String sql, Class clazz)
+ {
+ return delegate.createNativeQuery(sql, clazz);
+ }
+
+ public Query createNativeQuery(String sql, String lang)
+ {
+ return delegate.createNativeQuery(sql, lang);
+ }
+
+ public Query createNativeQuery(String sql)
+ {
+ return delegate.createNativeQuery(sql);
+ }
+
+ public Query createQuery(String ejbql)
+ {
+ if ( ejbql.indexOf('#')>0 )
+ {
+ QueryParser qp = new QueryParser(ejbql);
+ Query query = delegate.createQuery( qp.getEjbql() );
+ for (int i=0; i<qp.getParameterValueBindings().size(); i++)
+ {
+ query.setParameter(
+ QueryParser.getParameterName(i),
+ qp.getParameterValueBindings().get(i).getValue()
+ );
+ }
+ return query;
+ }
+ else
+ {
+ return delegate.createQuery(ejbql);
+ }
+ }
+
+ public <T> T find(Class<T> clazz, Object id)
+ {
+ return delegate.find(clazz, id);
+ }
+
+ public void flush()
+ {
+ delegate.flush();
+ }
+
+ public Object getDelegate()
+ {
+ return PersistenceProvider.instance().proxyDelegate( delegate.getDelegate() );
+ }
+
+ public FlushModeType getFlushMode()
+ {
+ return delegate.getFlushMode();
+ }
+
+ public <T> T getReference(Class<T> clazz, Object id)
+ {
+ return delegate.getReference(clazz, id);
+ }
+
+ public EntityTransaction getTransaction()
+ {
+ return delegate.getTransaction();
+ }
+
+ public boolean isOpen()
+ {
+ return delegate.isOpen();
+ }
+
+ public void joinTransaction()
+ {
+ delegate.joinTransaction();
+ }
+
+ public void lock(Object entity, LockModeType lm)
+ {
+ delegate.lock(entity, lm);
+ }
+
+ public <T> T merge(T entity)
+ {
+ return delegate.merge(entity);
+ }
+
+ public void persist(Object entity)
+ {
+ delegate.persist(entity);
+ }
+
+ public void refresh(Object entity)
+ {
+ delegate.refresh(entity);
+ }
+
+ public void remove(Object entity)
+ {
+ delegate.remove(entity);
+ PermissionManager.instance().clearPermissions(entity);
+ }
+
+ public void setFlushMode(FlushModeType fm)
+ {
+ delegate.setFlushMode(fm);
+ }
+}
Added: modules/trunk/persistence/src/main/java/org/jboss/seam/persistence/EntityManagerProxyInterceptor.java
===================================================================
--- modules/trunk/persistence/src/main/java/org/jboss/seam/persistence/EntityManagerProxyInterceptor.java (rev 0)
+++ modules/trunk/persistence/src/main/java/org/jboss/seam/persistence/EntityManagerProxyInterceptor.java 2009-04-27 12:48:53 UTC (rev 10650)
@@ -0,0 +1,67 @@
+package org.jboss.seam.persistence;
+
+import static org.jboss.seam.ComponentType.STATEFUL_SESSION_BEAN;
+import static org.jboss.seam.ComponentType.STATELESS_SESSION_BEAN;
+
+import javax.persistence.EntityManager;
+
+import org.jboss.seam.Component.BijectedAttribute;
+import org.jboss.seam.annotations.intercept.AroundInvoke;
+import org.jboss.seam.annotations.intercept.Interceptor;
+import org.jboss.seam.annotations.intercept.PostActivate;
+import org.jboss.seam.annotations.intercept.PostConstruct;
+import org.jboss.seam.intercept.AbstractInterceptor;
+import org.jboss.seam.intercept.InvocationContext;
+
+/**
+ * Proxy the EntityManager if injected using @PersistenceContext
+ *
+ * @author Pete Muir
+ */
+
+@Interceptor(stateless=true)
+public class EntityManagerProxyInterceptor extends AbstractInterceptor
+{
+
+ @AroundInvoke
+ public Object aroundInvoke(InvocationContext ic) throws Exception
+ {
+ return ic.proceed();
+ }
+
+ @PostActivate
+ public void postActivate(InvocationContext invocation) throws Exception
+ {
+ //just in case the container does some special handling of PC serialization
+ proxyPersistenceContexts(invocation.getTarget());
+ invocation.proceed();
+ }
+
+ @PostConstruct
+ public void postConstruct(InvocationContext invocation) throws Exception
+ {
+ proxyPersistenceContexts(invocation.getTarget());
+ invocation.proceed();
+ }
+
+
+ private void proxyPersistenceContexts(Object bean)
+ {
+ //wrap any @PersistenceContext attributes in our proxy
+ for ( BijectedAttribute ba: getComponent().getPersistenceContextAttributes() )
+ {
+ Object object = ba.get(bean);
+ if ( ! ( object instanceof EntityManagerProxy ) && object instanceof EntityManager )
+ {
+ PersistenceProvider provider = PersistenceProvider.instance();
+ ba.set( bean, provider.proxyEntityManager( (EntityManager) object ) );
+ }
+ }
+ }
+
+ public boolean isInterceptorEnabled()
+ {
+ return getComponent().getType()==STATEFUL_SESSION_BEAN || getComponent().getType()==STATELESS_SESSION_BEAN;
+ }
+
+}
Added: modules/trunk/persistence/src/main/java/org/jboss/seam/persistence/Filter.java
===================================================================
--- modules/trunk/persistence/src/main/java/org/jboss/seam/persistence/Filter.java (rev 0)
+++ modules/trunk/persistence/src/main/java/org/jboss/seam/persistence/Filter.java 2009-04-27 12:48:53 UTC (rev 10650)
@@ -0,0 +1,100 @@
+package org.jboss.seam.persistence;
+
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.jboss.seam.Component;
+import org.jboss.seam.ScopeType;
+import org.jboss.seam.annotations.Create;
+import org.jboss.seam.annotations.Scope;
+import org.jboss.seam.annotations.intercept.BypassInterceptors;
+import org.jboss.seam.core.Expressions.ValueExpression;
+
+/**
+ * Support for declarative application of
+ * Hibernate filters to persistence contexts.
+ *
+ * @see org.hibernate.Filter
+ * @see ManagedHibernateSession
+ * @see ManagedPersistenceContext
+ * @author Gavin King
+ */
+@BypassInterceptors
+(a)Scope(ScopeType.APPLICATION)
+public class Filter implements Serializable
+{
+ private String name;
+ // default to no parameters
+ private Map<String, ValueExpression> parameters = new HashMap<String, ValueExpression>();
+ private ValueExpression enabled;
+
+ @Create
+ public void create(Component component)
+ {
+ //default the filter name to the component name
+ if (name==null)
+ {
+ name = component.getName();
+ }
+ }
+
+ /**
+ * The filter parameters.
+ *
+ * @see org.hibernate.Filter#setParameter(String, Object)
+ */
+ public Map<String, ValueExpression> getParameters()
+ {
+ return parameters;
+ }
+ public void setParameters(Map<String, ValueExpression> parameters)
+ {
+ this.parameters = parameters;
+ }
+
+ /**
+ * The Hibernate filter name.
+ *
+ * @see org.hibernate.Session#enableFilter(String)
+ */
+ public String getName()
+ {
+ return name;
+ }
+
+ public void setName(String name)
+ {
+ this.name = name;
+ }
+
+ public boolean isFilterEnabled()
+ {
+ ValueExpression enabledValueBinding = getEnabled();
+ if (enabledValueBinding==null)
+ {
+ return true;
+ }
+ else
+ {
+ Boolean enabled = (Boolean) enabledValueBinding.getValue();
+ return enabled!=null && enabled;
+ }
+ }
+
+ @Override
+ public String toString()
+ {
+ return "Filter(" + name + ")";
+ }
+
+ public ValueExpression getEnabled()
+ {
+ return enabled;
+ }
+
+ public void setEnabled(ValueExpression enabled)
+ {
+ this.enabled = enabled;
+ }
+}
\ No newline at end of file
Added: modules/trunk/persistence/src/main/java/org/jboss/seam/persistence/FullTextEntityManagerProxy.java
===================================================================
--- modules/trunk/persistence/src/main/java/org/jboss/seam/persistence/FullTextEntityManagerProxy.java (rev 0)
+++ modules/trunk/persistence/src/main/java/org/jboss/seam/persistence/FullTextEntityManagerProxy.java 2009-04-27 12:48:53 UTC (rev 10650)
@@ -0,0 +1,50 @@
+//$Id: FullTextEntityManagerProxy.java 9696 2008-12-02 12:05:50Z shane.bryzak(a)jboss.com $
+package org.jboss.seam.persistence;
+
+import java.io.Serializable;
+
+import org.apache.lucene.search.Query;
+import org.hibernate.search.SearchFactory;
+import org.hibernate.search.jpa.FullTextEntityManager;
+import org.hibernate.search.jpa.FullTextQuery;
+
+/**
+ * Wrap a FullTextEntityManager
+ *
+ * @author Emmanuel Bernard
+ */
+public class FullTextEntityManagerProxy extends EntityManagerProxy implements FullTextEntityManager
+{
+ private FullTextEntityManager fullTextEntityManager;
+
+ public FullTextEntityManagerProxy(FullTextEntityManager entityManager)
+ {
+ super(entityManager);
+ this.fullTextEntityManager = entityManager;
+ }
+
+ public FullTextQuery createFullTextQuery(Query query, Class... classes)
+ {
+ return fullTextEntityManager.createFullTextQuery(query, classes);
+ }
+
+ public void index(Object object)
+ {
+ fullTextEntityManager.index(object);
+ }
+
+ public SearchFactory getSearchFactory()
+ {
+ return fullTextEntityManager.getSearchFactory();
+ }
+
+ public void purge(Class aClass, Serializable serializable)
+ {
+ fullTextEntityManager.purge(aClass, serializable);
+ }
+
+ public void purgeAll(Class aClass)
+ {
+ fullTextEntityManager.purgeAll(aClass);
+ }
+}
Added: modules/trunk/persistence/src/main/java/org/jboss/seam/persistence/FullTextHibernateSessionProxy.java
===================================================================
--- modules/trunk/persistence/src/main/java/org/jboss/seam/persistence/FullTextHibernateSessionProxy.java (rev 0)
+++ modules/trunk/persistence/src/main/java/org/jboss/seam/persistence/FullTextHibernateSessionProxy.java 2009-04-27 12:48:53 UTC (rev 10650)
@@ -0,0 +1,168 @@
+package org.jboss.seam.persistence;
+
+import java.io.Serializable;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+
+import org.hibernate.HibernateException;
+import org.hibernate.Query;
+import org.hibernate.search.FullTextQuery;
+import org.hibernate.search.FullTextSession;
+import org.hibernate.search.SearchFactory;
+import org.hibernate.type.Type;
+
+/**
+ * Wraps a Hibernate Search session
+ *
+ * @author Gavin King
+ *
+ */
+@SuppressWarnings("deprecation")
+public class FullTextHibernateSessionProxy extends HibernateSessionProxy implements FullTextSession
+{
+ private FullTextSession fullTextSession;
+
+ public FullTextHibernateSessionProxy(FullTextSession fullTextSession)
+ {
+ super(fullTextSession);
+ this.fullTextSession = fullTextSession;
+ }
+
+ public void index(Object arg0)
+ {
+ fullTextSession.index(arg0);
+ }
+
+ public FullTextQuery createFullTextQuery(org.apache.lucene.search.Query arg0, Class... arg1)
+ {
+ return fullTextSession.createFullTextQuery(arg0, arg1);
+ }
+
+ public Query createSQLQuery(String arg0, String arg1, Class arg2)
+ {
+ return fullTextSession.createSQLQuery(arg0, arg1, arg2);
+ }
+
+ public Query createSQLQuery(String arg0, String[] arg1, Class[] arg2)
+ {
+ return fullTextSession.createSQLQuery(arg0, arg1, arg2);
+ }
+
+ public int delete(String arg0, Object arg1, Type arg2) throws HibernateException
+ {
+ return fullTextSession.delete(arg0, arg1, arg2);
+ }
+
+ public int delete(String arg0, Object[] arg1, Type[] arg2) throws HibernateException
+ {
+ return fullTextSession.delete(arg0, arg1, arg2);
+ }
+
+ public int delete(String arg0) throws HibernateException
+ {
+ return fullTextSession.delete(arg0);
+ }
+
+ public Collection filter(Object arg0, String arg1, Object arg2, Type arg3) throws HibernateException
+ {
+ return fullTextSession.filter(arg0, arg1, arg2, arg3);
+ }
+
+ public Collection filter(Object arg0, String arg1, Object[] arg2, Type[] arg3) throws HibernateException
+ {
+ return fullTextSession.filter(arg0, arg1, arg2, arg3);
+ }
+
+ public Collection filter(Object arg0, String arg1) throws HibernateException
+ {
+ return fullTextSession.filter(arg0, arg1);
+ }
+
+ public List find(String arg0, Object arg1, Type arg2) throws HibernateException
+ {
+ return fullTextSession.find(arg0, arg1, arg2);
+ }
+
+ public List find(String arg0, Object[] arg1, Type[] arg2) throws HibernateException
+ {
+ return fullTextSession.find(arg0, arg1, arg2);
+ }
+
+ public List find(String arg0) throws HibernateException
+ {
+ return fullTextSession.find(arg0);
+ }
+
+
+ public SearchFactory getSearchFactory()
+ {
+ return fullTextSession.getSearchFactory();
+ }
+
+ public void purge(Class aClass, Serializable serializable)
+ {
+ fullTextSession.purge(aClass, serializable);
+ }
+
+ public void purgeAll(Class aClass)
+ {
+ fullTextSession.purgeAll(aClass);
+ }
+
+ public Iterator iterate(String arg0, Object arg1, Type arg2) throws HibernateException
+ {
+ return fullTextSession.iterate(arg0, arg1, arg2);
+ }
+
+ public Iterator iterate(String arg0, Object[] arg1, Type[] arg2) throws HibernateException
+ {
+ return fullTextSession.iterate(arg0, arg1, arg2);
+ }
+
+ public Iterator iterate(String arg0) throws HibernateException
+ {
+ return fullTextSession.iterate(arg0);
+ }
+
+ public void save(Object arg0, Serializable arg1) throws HibernateException
+ {
+ fullTextSession.save(arg0, arg1);
+ }
+
+ public void save(String arg0, Object arg1, Serializable arg2) throws HibernateException
+ {
+ fullTextSession.save(arg0, arg1, arg2);
+ }
+
+ public Object saveOrUpdateCopy(Object arg0, Serializable arg1) throws HibernateException
+ {
+ return fullTextSession.saveOrUpdateCopy(arg0, arg1);
+ }
+
+ public Object saveOrUpdateCopy(Object arg0) throws HibernateException
+ {
+ return fullTextSession.saveOrUpdateCopy(arg0);
+ }
+
+ public Object saveOrUpdateCopy(String arg0, Object arg1, Serializable arg2) throws HibernateException
+ {
+ return fullTextSession.saveOrUpdateCopy(arg0, arg1, arg2);
+ }
+
+ public Object saveOrUpdateCopy(String arg0, Object arg1) throws HibernateException
+ {
+ return fullTextSession.saveOrUpdateCopy(arg0, arg1);
+ }
+
+ public void update(Object arg0, Serializable arg1) throws HibernateException
+ {
+ fullTextSession.update(arg0, arg1);
+ }
+
+ public void update(String arg0, Object arg1, Serializable arg2) throws HibernateException
+ {
+ fullTextSession.update(arg0, arg1, arg2);
+ }
+
+}
Added: modules/trunk/persistence/src/main/java/org/jboss/seam/persistence/HibernatePersistenceProvider.java
===================================================================
--- modules/trunk/persistence/src/main/java/org/jboss/seam/persistence/HibernatePersistenceProvider.java (rev 0)
+++ modules/trunk/persistence/src/main/java/org/jboss/seam/persistence/HibernatePersistenceProvider.java 2009-04-27 12:48:53 UTC (rev 10650)
@@ -0,0 +1,393 @@
+package org.jboss.seam.persistence;
+import static org.jboss.seam.annotations.Install.FRAMEWORK;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.Collection;
+import java.util.Map;
+
+import javax.persistence.EntityManager;
+import javax.transaction.Synchronization;
+
+import org.hibernate.EntityMode;
+import org.hibernate.FlushMode;
+import org.hibernate.Hibernate;
+import org.hibernate.Session;
+import org.hibernate.StaleStateException;
+import org.hibernate.TransientObjectException;
+import org.hibernate.metadata.ClassMetadata;
+import org.hibernate.proxy.HibernateProxy;
+import org.hibernate.type.VersionType;
+import org.jboss.seam.Component;
+import org.jboss.seam.Entity;
+import org.jboss.seam.ScopeType;
+import org.jboss.seam.Entity.NotEntityException;
+import org.jboss.seam.annotations.FlushModeType;
+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.core.Expressions.ValueExpression;
+import org.jboss.seam.log.Log;
+import org.jboss.seam.log.Logging;
+/**
+ * Support for non-standardized features of Hibernate, when
+ * used as the JPA persistence provider.
+ *
+ * @author Gavin King
+ * @author Pete Muir
+ *
+ */
+@Name("org.jboss.seam.persistence.persistenceProvider")
+(a)Scope(ScopeType.STATELESS)
+@BypassInterceptors
+@Install(precedence=FRAMEWORK, classDependencies={"org.hibernate.Session", "javax.persistence.EntityManager"})
+public class HibernatePersistenceProvider extends PersistenceProvider
+{
+
+ private static Log log = Logging.getLog(HibernatePersistenceProvider.class);
+ private static Constructor FULL_TEXT_SESSION_PROXY_CONSTRUCTOR;
+ private static Method FULL_TEXT_SESSION_CONSTRUCTOR;
+ private static Constructor FULL_TEXT_ENTITYMANAGER_PROXY_CONSTRUCTOR;
+ private static Method FULL_TEXT_ENTITYMANAGER_CONSTRUCTOR;
+ static
+ {
+ try
+ {
+ String version = null;
+ try {
+ Class searchVersionClass = Class.forName("org.hibernate.search.Version");
+ Field versionField = searchVersionClass.getDeclaredField("VERSION");
+ version = (String) versionField.get(null);
+ }
+ catch (Exception e)
+ {
+ log.debug("no Hibernate Search, sorry :-(", e);
+ }
+ if (version != null) {
+ Class searchClass = Class.forName("org.hibernate.search.Search");
+ FULL_TEXT_SESSION_CONSTRUCTOR = searchClass.getDeclaredMethod("createFullTextSession", Session.class);
+ Class fullTextSessionProxyClass = Class.forName("org.jboss.seam.persistence.FullTextHibernateSessionProxy");
+ Class fullTextSessionClass = Class.forName("org.hibernate.search.FullTextSession");
+ FULL_TEXT_SESSION_PROXY_CONSTRUCTOR = fullTextSessionProxyClass.getDeclaredConstructor(fullTextSessionClass);
+ Class jpaSearchClass = Class.forName("org.hibernate.search.jpa.Search");
+ FULL_TEXT_ENTITYMANAGER_CONSTRUCTOR = jpaSearchClass.getDeclaredMethod("createFullTextEntityManager", EntityManager.class);
+ Class fullTextEntityManagerProxyClass = Class.forName("org.jboss.seam.persistence.FullTextEntityManagerProxy");
+ Class fullTextEntityManagerClass = Class.forName("org.hibernate.search.jpa.FullTextEntityManager");
+ FULL_TEXT_ENTITYMANAGER_PROXY_CONSTRUCTOR = fullTextEntityManagerProxyClass.getDeclaredConstructor(fullTextEntityManagerClass);
+ log.debug("Hibernate Search is available :-)");
+ }
+ }
+ catch (Exception e)
+ {
+ log.debug("no Hibernate Search, sorry :-(", e);
+ }
+ }
+
+ @Override
+ public void init()
+ {
+ super.init();
+ featureSet.add(Feature.WILDCARD_AS_COUNT_QUERY_SUBJECT);
+ }
+
+ /**
+ * Wrap the Hibernate Session in a proxy that supports HQL
+ * EL interpolation and implements FullTextSession if Hibernate
+ * Search is available in the classpath.
+ */
+ static Session proxySession(Session session)
+ {
+ if (FULL_TEXT_SESSION_PROXY_CONSTRUCTOR==null)
+ {
+ return new HibernateSessionProxy(session);
+ }
+ else
+ {
+ try {
+ return (Session) FULL_TEXT_SESSION_PROXY_CONSTRUCTOR.newInstance( FULL_TEXT_SESSION_CONSTRUCTOR.invoke(null, session) );
+ }
+ catch(Exception e) {
+ log.warn("Unable to wrap into a FullTextSessionProxy, regular SessionProxy returned", e);
+ return new HibernateSessionProxy(session);
+ }
+ }
+ }
+
+ /**
+ * Wrap the delegate Hibernate Session in a proxy that supports HQL
+ * EL interpolation and implements FullTextSession if Hibernate
+ * Search is available in the classpath.
+ */
+ @Override
+ public Object proxyDelegate(Object delegate)
+ {
+ try
+ {
+ return proxySession( (Session) delegate );
+ }
+ catch (NotHibernateException nhe)
+ {
+ return super.proxyDelegate(delegate);
+ }
+ catch (Exception e)
+ {
+ throw new RuntimeException("could not proxy delegate", e);
+ }
+ }
+
+ @Override
+ public void setFlushModeManual(EntityManager entityManager)
+ {
+ try
+ {
+ getSession(entityManager).setFlushMode(FlushMode.MANUAL);
+ }
+ catch (NotHibernateException nhe)
+ {
+ super.setFlushModeManual(entityManager);
+ }
+ }
+
+ @Override
+ public void setRenderFlushMode()
+ {
+ PersistenceContexts.instance().changeFlushMode(FlushModeType.MANUAL, true);
+ }
+
+ @Override
+ public boolean isDirty(EntityManager entityManager)
+ {
+ try
+ {
+ return getSession(entityManager).isDirty();
+ }
+ catch (NotHibernateException nhe)
+ {
+ return super.isDirty(entityManager);
+ }
+ }
+
+ @Override
+ public Object getId(Object bean, EntityManager entityManager)
+ {
+ try
+ {
+ return getSession(entityManager).getIdentifier(bean);
+ }
+ catch (NotHibernateException nhe)
+ {
+ return super.getId(bean, entityManager);
+ }
+ catch (TransientObjectException e)
+ {
+ if (bean instanceof HibernateProxy)
+ {
+ return super.getId(((HibernateProxy) bean).getHibernateLazyInitializer().getImplementation(), entityManager);
+ }
+ else
+ {
+ return super.getId(bean, entityManager);
+ }
+ }
+ }
+
+ @Override
+ public Object getVersion(Object bean, EntityManager entityManager)
+ {
+ try
+ {
+ return getVersion( bean, getSession(entityManager) );
+ }
+ catch (NotHibernateException nhe)
+ {
+ return super.getVersion(bean, entityManager);
+ }
+ }
+
+ @Override
+ public void checkVersion(Object bean, EntityManager entityManager, Object oldVersion, Object version)
+ {
+ try
+ {
+ checkVersion(bean, getSession(entityManager), oldVersion, version);
+ }
+ catch (NotHibernateException nhe)
+ {
+ super.checkVersion(bean, entityManager, oldVersion, version);
+ }
+ }
+
+ @Override
+ public void enableFilter(Filter f, EntityManager entityManager)
+ {
+ try
+ {
+ org.hibernate.Filter filter = getSession(entityManager).enableFilter( f.getName() );
+ for ( Map.Entry<String, ValueExpression> me: f.getParameters().entrySet() )
+ {
+ Object filterValue = me.getValue().getValue();
+ if ( filterValue instanceof Collection ) {
+ filter.setParameterList(me.getKey(), (Collection) filterValue);
+ } else {
+ filter.setParameter(me.getKey(), filterValue);
+ }
+ }
+ filter.validate();
+ }
+ catch (NotHibernateException nhe)
+ {
+ super.enableFilter(f, entityManager);
+ }
+
+ }
+
+ @Override
+ public boolean registerSynchronization(Synchronization sync, EntityManager entityManager)
+ {
+ try
+ {
+ //TODO: just make sure that a Hibernate JPA EntityTransaction
+ // delegates to the Hibernate Session transaction
+ getSession(entityManager).getTransaction().registerSynchronization(sync);
+ return true;
+ }
+ catch (NotHibernateException nhe)
+ {
+ return super.registerSynchronization(sync, entityManager);
+ }
+
+ }
+
+ @Override
+ public String getName(Object bean, EntityManager entityManager) throws IllegalArgumentException
+ {
+ try
+ {
+ return getSession(entityManager).getEntityName(bean);
+ }
+ catch (NotHibernateException nhe)
+ {
+ return super.getName(bean, entityManager);
+ }
+ catch (TransientObjectException e)
+ {
+ return super.getName(bean, entityManager);
+ }
+ }
+
+ @Override
+ public EntityManager proxyEntityManager(EntityManager entityManager)
+ {
+ if (FULL_TEXT_ENTITYMANAGER_PROXY_CONSTRUCTOR==null)
+ {
+ return super.proxyEntityManager(entityManager);
+ }
+ else
+ {
+ try
+ {
+ return (EntityManager) FULL_TEXT_ENTITYMANAGER_PROXY_CONSTRUCTOR.newInstance(
+ FULL_TEXT_ENTITYMANAGER_CONSTRUCTOR.invoke(null, super.proxyEntityManager( entityManager) )
+ //TODO is double wrapping the right choice? ie to wrap the session?
+ );
+ }
+ catch (Exception e)
+ {
+ //throw new RuntimeException("could not proxy FullTextEntityManager", e);
+ return super.proxyEntityManager(entityManager);
+ }
+ }
+ }
+
+ public static void checkVersion(Object value, Session session, Object oldVersion, Object version)
+ {
+ ClassMetadata classMetadata = getClassMetadata(value, session);
+ VersionType versionType = (VersionType) classMetadata.getPropertyTypes()[ classMetadata.getVersionProperty() ];
+ if ( !versionType.isEqual(oldVersion, version) )
+ {
+ throw new StaleStateException("current database version number does not match passivated version number");
+ }
+ }
+
+ public static Object getVersion(Object value, Session session)
+ {
+ ClassMetadata classMetadata = getClassMetadata(value, session);
+ return classMetadata!=null && classMetadata.isVersioned() ?
+ classMetadata.getVersion(value, EntityMode.POJO) : null;
+ }
+
+ private static ClassMetadata getClassMetadata(Object value, Session session)
+ {
+ Class entityClass = getEntityClass(value);
+ ClassMetadata classMetadata = null;
+ if (entityClass!=null)
+ {
+ classMetadata = session.getSessionFactory().getClassMetadata(entityClass);
+ if (classMetadata==null)
+ {
+ throw new IllegalArgumentException(
+ "Could not find ClassMetadata object for entity class: " +
+ entityClass.getName()
+ );
+ }
+ }
+ return classMetadata;
+ }
+
+ /**
+ * Returns the class of the specified Hibernate entity
+ */
+ @Override
+ public Class getBeanClass(Object bean)
+ {
+ return getEntityClass(bean);
+ }
+
+ public static Class getEntityClass(Object bean)
+ {
+ Class clazz = null;
+ try
+ {
+ clazz = Entity.forBean(bean).getBeanClass();
+ }
+ catch (NotEntityException e) {
+ // It's ok, try some other methods
+ }
+
+ if (clazz == null)
+ {
+ clazz = Hibernate.getClass(bean);
+ }
+
+ return clazz;
+ }
+
+ private Session getSession(EntityManager entityManager)
+ {
+ Object delegate = entityManager.getDelegate();
+ if ( delegate instanceof Session )
+ {
+ return (Session) delegate;
+ }
+ else
+ {
+ throw new NotHibernateException();
+ }
+ }
+
+ /**
+ * Occurs when Hibernate is in the classpath, but this particular
+ * EntityManager is not from Hibernate
+ *
+ * @author Gavin King
+ *
+ */
+ static class NotHibernateException extends IllegalArgumentException {}
+
+ public static HibernatePersistenceProvider instance()
+ {
+ return (HibernatePersistenceProvider) Component.getInstance(HibernatePersistenceProvider.class, ScopeType.STATELESS);
+ }
+}
Added: modules/trunk/persistence/src/main/java/org/jboss/seam/persistence/HibernateSessionFactory.java
===================================================================
--- modules/trunk/persistence/src/main/java/org/jboss/seam/persistence/HibernateSessionFactory.java (rev 0)
+++ modules/trunk/persistence/src/main/java/org/jboss/seam/persistence/HibernateSessionFactory.java 2009-04-27 12:48:53 UTC (rev 10650)
@@ -0,0 +1,248 @@
+//$Id: HibernateSessionFactory.java 6143 2007-09-07 00:59:34Z gavin $
+package org.jboss.seam.persistence;
+
+import java.io.File;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+import org.hibernate.SessionFactory;
+import org.hibernate.cfg.AnnotationConfiguration;
+import org.hibernate.cfg.Environment;
+import org.hibernate.cfg.NamingStrategy;
+import org.hibernate.util.ReflectHelper;
+import org.jboss.seam.ScopeType;
+import org.jboss.seam.annotations.Create;
+import org.jboss.seam.annotations.Destroy;
+import org.jboss.seam.annotations.Scope;
+import org.jboss.seam.annotations.Startup;
+import org.jboss.seam.annotations.Unwrap;
+import org.jboss.seam.annotations.intercept.BypassInterceptors;
+import org.jboss.seam.security.HibernateSecurityInterceptor;
+import org.jboss.seam.util.Naming;
+
+/**
+ * A Seam component that bootstraps a Hibernate SessionFactory
+ *
+ * <p>
+ * Loads Hibernate configuration options by checking:
+ * <li>hibernate.properties in root of the classpath
+ * <li>hibernate.cfg.xml in root of the classpath
+ * <li>cfgResourceName as location of a cfg.xml file
+ * <li>factory-supplied cfgProperties options
+ * <p>
+ * Note that this factory only supports cfg.xml files <b>or</b> programmatic
+ * <tt>cfgProperties</tt> supplied to the factory. Any
+ * <tt>hibernate.properties</tt> are always loaded from the classpath.
+ * <p>
+ * Mapping metadata can be supplied via
+ * <li>mappingClasses: equivalent to <mapping class="..."/>
+ * <li>mappingFiles: equivalent to <mapping file="..."/>
+ * <li>mappingJars: equivalent to <mapping jar="..."/>
+ * <li>mappingPackages: equivalent to <mapping package="..."/>
+ * <li>mappingResources: equivalent to <mapping resource="..."/>
+ * <p>
+ * or via cfg.xml files.
+ * <p>
+ * The <tt>jndiProperties</tt> are convenience, the factory will automatically
+ * prefix regular JNDI properties for use as Hibernate configuration properties.
+ *
+ * @author Gavin King
+ * @author Christian Bauer
+ */
+(a)Scope(ScopeType.APPLICATION)
+@BypassInterceptors
+@Startup
+public class HibernateSessionFactory
+{
+ private SessionFactory sessionFactory;
+
+ private String cfgResourceName;
+ private Map<String, String> cfgProperties;
+ private List<String> mappingClasses;
+ private List<String> mappingFiles;
+ private List<String> mappingJars;
+ private List<String> mappingPackages;
+ private List<String> mappingResources;
+ private NamingStrategy namingStrategy;
+
+ @Unwrap
+ public SessionFactory getSessionFactory() throws Exception
+ {
+ return sessionFactory;
+ }
+
+ @Create
+ public void startup() throws Exception
+ {
+ sessionFactory = createSessionFactory();
+ }
+
+ @Destroy
+ public void shutdown()
+ {
+ if (sessionFactory!=null)
+ {
+ sessionFactory.close();
+ }
+ }
+
+ protected SessionFactory createSessionFactory() throws ClassNotFoundException
+ {
+ AnnotationConfiguration configuration = new AnnotationConfiguration();
+
+ // setup non-default naming strategy
+ if (namingStrategy != null)
+ {
+ configuration.setNamingStrategy(namingStrategy);
+ }
+
+ // Programmatic configuration
+ if (cfgProperties != null)
+ {
+ Properties props = new Properties();
+ props.putAll(cfgProperties);
+ configuration.setProperties(props);
+ }
+ Hashtable<String, String> jndiProperties = Naming.getInitialContextProperties();
+ if ( jndiProperties!=null )
+ {
+ // Prefix regular JNDI properties for Hibernate
+ for (Map.Entry<String, String> entry : jndiProperties.entrySet())
+ {
+ configuration.setProperty( Environment.JNDI_PREFIX + "." + entry.getKey(), entry.getValue() );
+ }
+ }
+ // hibernate.cfg.xml configuration
+ if (cfgProperties==null && cfgResourceName==null)
+ {
+ configuration.configure();
+ }
+ else if (cfgProperties==null && cfgResourceName!=null)
+ {
+ configuration.configure(cfgResourceName);
+ }
+ // Mapping metadata
+ if (mappingClasses!=null)
+ {
+ for (String className: mappingClasses)
+ {
+ configuration.addAnnotatedClass(ReflectHelper.classForName(className));
+ }
+ }
+ if (mappingFiles!=null)
+ {
+ for (String fileName: mappingFiles)
+ {
+ configuration.addFile(fileName);
+ }
+ }
+ if (mappingJars!=null)
+ {
+ for (String jarName: mappingJars)
+ {
+ configuration.addJar(new File(jarName));
+ }
+ }
+ if (mappingPackages!= null)
+ {
+ for (String packageName: mappingPackages)
+ {
+ configuration.addPackage(packageName);
+ }
+ }
+ if (mappingResources!= null)
+ {
+ for (String resourceName : mappingResources)
+ {
+ configuration.addResource(resourceName);
+ }
+ }
+
+ configuration.setInterceptor(new HibernateSecurityInterceptor(configuration.getInterceptor()));
+
+ return configuration.buildSessionFactory();
+ }
+
+ public String getCfgResourceName()
+ {
+ return cfgResourceName;
+ }
+
+ public void setCfgResourceName(String cfgFileName)
+ {
+ this.cfgResourceName = cfgFileName;
+ }
+
+ public NamingStrategy getNamingStrategy()
+ {
+ return namingStrategy;
+ }
+
+ public void setNamingStrategy(NamingStrategy namingStrategy)
+ {
+ this.namingStrategy = namingStrategy;
+ }
+
+ public Map<String, String> getCfgProperties()
+ {
+ return cfgProperties;
+ }
+
+ public void setCfgProperties(Map<String, String> cfgProperties)
+ {
+ this.cfgProperties = cfgProperties;
+ }
+
+ public List<String> getMappingClasses()
+ {
+ return mappingClasses;
+ }
+
+ public void setMappingClasses(List<String> mappingClasses)
+ {
+ this.mappingClasses = mappingClasses;
+ }
+
+ public List<String> getMappingFiles()
+ {
+ return mappingFiles;
+ }
+
+ public void setMappingFiles(List<String> mappingFiles)
+ {
+ this.mappingFiles = mappingFiles;
+ }
+
+ public List<String> getMappingJars()
+ {
+ return mappingJars;
+ }
+
+ public void setMappingJars(List<String> mappingJars)
+ {
+ this.mappingJars = mappingJars;
+ }
+
+ public List<String> getMappingPackages()
+ {
+ return mappingPackages;
+ }
+
+ public void setMappingPackages(List<String> mappingPackages)
+ {
+ this.mappingPackages = mappingPackages;
+ }
+
+ public List<String> getMappingResources()
+ {
+ return mappingResources;
+ }
+
+ public void setMappingResources(List<String> mappingResources)
+ {
+ this.mappingResources = mappingResources;
+ }
+
+}
Added: modules/trunk/persistence/src/main/java/org/jboss/seam/persistence/HibernateSessionProxy.java
===================================================================
--- modules/trunk/persistence/src/main/java/org/jboss/seam/persistence/HibernateSessionProxy.java (rev 0)
+++ modules/trunk/persistence/src/main/java/org/jboss/seam/persistence/HibernateSessionProxy.java 2009-04-27 12:48:53 UTC (rev 10650)
@@ -0,0 +1,669 @@
+package org.jboss.seam.persistence;
+
+import java.io.Serializable;
+import java.sql.Connection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.hibernate.CacheMode;
+import org.hibernate.Criteria;
+import org.hibernate.EntityMode;
+import org.hibernate.Filter;
+import org.hibernate.FlushMode;
+import org.hibernate.HibernateException;
+import org.hibernate.Interceptor;
+import org.hibernate.LockMode;
+import org.hibernate.Query;
+import org.hibernate.ReplicationMode;
+import org.hibernate.SQLQuery;
+import org.hibernate.ScrollMode;
+import org.hibernate.ScrollableResults;
+import org.hibernate.Session;
+import org.hibernate.SessionFactory;
+import org.hibernate.Transaction;
+import org.hibernate.collection.PersistentCollection;
+import org.hibernate.engine.EntityKey;
+import org.hibernate.engine.PersistenceContext;
+import org.hibernate.engine.QueryParameters;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.engine.ActionQueue;
+import org.hibernate.engine.EntityEntry;
+import org.hibernate.engine.query.sql.NativeSQLQuerySpecification;
+import org.hibernate.event.EventListeners;
+import org.hibernate.event.EventSource;
+import org.hibernate.impl.CriteriaImpl;
+import org.hibernate.jdbc.Batcher;
+import org.hibernate.jdbc.JDBCContext;
+import org.hibernate.loader.custom.CustomQuery;
+import org.hibernate.persister.entity.EntityPersister;
+import org.hibernate.stat.SessionStatistics;
+import org.hibernate.type.Type;
+
+/**
+ * Proxies the Session, and implements EL interpolation
+ * in HQL. Needs to implement SessionImplementor because
+ * DetachedCriteria casts the Session to SessionImplementor.
+ *
+ * @author Gavin King
+ * @author Emmanuel Bernard
+ * FIXME: EventSource should not really be there, remove once HSearch is fixed
+ *
+ */
+public class HibernateSessionProxy implements Session, SessionImplementor, EventSource
+{
+ private Session delegate;
+
+ /**
+ * Don't use that constructor directly, use HibernatePersistenceProvider.proxySession()
+ */
+ public HibernateSessionProxy(Session session)
+ {
+ delegate = session;
+ }
+
+ public Transaction beginTransaction() throws HibernateException
+ {
+ return delegate.beginTransaction();
+ }
+
+ public void cancelQuery() throws HibernateException
+ {
+ delegate.cancelQuery();
+ }
+
+ public void clear()
+ {
+ delegate.clear();
+ }
+
+ public Connection close() throws HibernateException
+ {
+ return delegate.close();
+ }
+
+ @SuppressWarnings("deprecation")
+ public Connection connection() throws HibernateException
+ {
+ return delegate.connection();
+ }
+
+ public boolean contains(Object arg0)
+ {
+ return delegate.contains(arg0);
+ }
+
+ public Criteria createCriteria(Class arg0, String arg1)
+ {
+ return delegate.createCriteria(arg0, arg1);
+ }
+
+ public Criteria createCriteria(Class arg0)
+ {
+ return delegate.createCriteria(arg0);
+ }
+
+ public Criteria createCriteria(String arg0, String arg1)
+ {
+ return delegate.createCriteria(arg0, arg1);
+ }
+
+ public Criteria createCriteria(String arg0)
+ {
+ return delegate.createCriteria(arg0);
+ }
+
+ public Query createFilter(Object arg0, String arg1) throws HibernateException
+ {
+ return delegate.createFilter(arg0, arg1);
+ }
+
+ public Query createQuery(String hql) throws HibernateException
+ {
+ if ( hql.indexOf('#')>0 )
+ {
+ QueryParser qp = new QueryParser(hql);
+ Query query = delegate.createQuery( qp.getEjbql() );
+ for (int i=0; i<qp.getParameterValueBindings().size(); i++)
+ {
+ query.setParameter(
+ QueryParser.getParameterName(i),
+ qp.getParameterValueBindings().get(i).getValue()
+ );
+ }
+ return query;
+ }
+ else
+ {
+ return delegate.createQuery(hql);
+ }
+ }
+
+ public SQLQuery createSQLQuery(String arg0) throws HibernateException
+ {
+ return delegate.createSQLQuery(arg0);
+ }
+
+ public void delete(Object arg0) throws HibernateException
+ {
+ delegate.delete(arg0);
+ }
+
+ public void delete(String arg0, Object arg1) throws HibernateException
+ {
+ delegate.delete(arg0, arg1);
+ }
+
+ public void disableFilter(String arg0)
+ {
+ delegate.disableFilter(arg0);
+ }
+
+ public Connection disconnect() throws HibernateException
+ {
+ return delegate.disconnect();
+ }
+
+ public Filter enableFilter(String arg0)
+ {
+ return delegate.enableFilter(arg0);
+ }
+
+ public void evict(Object arg0) throws HibernateException
+ {
+ delegate.evict(arg0);
+ }
+
+ public void flush() throws HibernateException
+ {
+ delegate.flush();
+ }
+
+ public Object get(Class arg0, Serializable arg1, LockMode arg2) throws HibernateException
+ {
+ return delegate.get(arg0, arg1, arg2);
+ }
+
+ public Object get(Class arg0, Serializable arg1) throws HibernateException
+ {
+ return delegate.get(arg0, arg1);
+ }
+
+ public Object get(String arg0, Serializable arg1, LockMode arg2) throws HibernateException
+ {
+ return delegate.get(arg0, arg1, arg2);
+ }
+
+ public Object get(String arg0, Serializable arg1) throws HibernateException
+ {
+ return delegate.get(arg0, arg1);
+ }
+
+ public CacheMode getCacheMode()
+ {
+ return delegate.getCacheMode();
+ }
+
+ public LockMode getCurrentLockMode(Object arg0) throws HibernateException
+ {
+ return delegate.getCurrentLockMode(arg0);
+ }
+
+ public Filter getEnabledFilter(String arg0)
+ {
+ return delegate.getEnabledFilter(arg0);
+ }
+
+ public EntityMode getEntityMode()
+ {
+ return delegate.getEntityMode();
+ }
+
+ public String getEntityName(Object arg0) throws HibernateException
+ {
+ return delegate.getEntityName(arg0);
+ }
+
+ public FlushMode getFlushMode()
+ {
+ return delegate.getFlushMode();
+ }
+
+ public Serializable getIdentifier(Object arg0) throws HibernateException
+ {
+ return delegate.getIdentifier(arg0);
+ }
+
+ public Query getNamedQuery(String arg0) throws HibernateException
+ {
+ return delegate.getNamedQuery(arg0);
+ }
+
+ public Session getSession(EntityMode arg0)
+ {
+ return delegate.getSession(arg0);
+ }
+
+ public SessionFactory getSessionFactory()
+ {
+ return delegate.getSessionFactory();
+ }
+
+ public SessionStatistics getStatistics()
+ {
+ return delegate.getStatistics();
+ }
+
+ public Transaction getTransaction()
+ {
+ return delegate.getTransaction();
+ }
+
+ public boolean isConnected()
+ {
+ return delegate.isConnected();
+ }
+
+ public boolean isDirty() throws HibernateException
+ {
+ return delegate.isDirty();
+ }
+
+ public boolean isOpen()
+ {
+ return delegate.isOpen();
+ }
+
+ public Object load(Class arg0, Serializable arg1, LockMode arg2) throws HibernateException
+ {
+ return delegate.load(arg0, arg1, arg2);
+ }
+
+ public Object load(Class arg0, Serializable arg1) throws HibernateException
+ {
+ return delegate.load(arg0, arg1);
+ }
+
+ public void load(Object arg0, Serializable arg1) throws HibernateException
+ {
+ delegate.load(arg0, arg1);
+ }
+
+ public Object load(String arg0, Serializable arg1, LockMode arg2) throws HibernateException
+ {
+ return delegate.load(arg0, arg1, arg2);
+ }
+
+ public Object load(String arg0, Serializable arg1) throws HibernateException
+ {
+ return delegate.load(arg0, arg1);
+ }
+
+ public void lock(Object arg0, LockMode arg1) throws HibernateException
+ {
+ delegate.lock(arg0, arg1);
+ }
+
+ public void lock(String arg0, Object arg1, LockMode arg2) throws HibernateException
+ {
+ delegate.lock(arg0, arg1, arg2);
+ }
+
+ public Object merge(Object arg0) throws HibernateException
+ {
+ return delegate.merge(arg0);
+ }
+
+ public Object merge(String arg0, Object arg1) throws HibernateException
+ {
+ return delegate.merge(arg0, arg1);
+ }
+
+ public void persist(Object arg0) throws HibernateException
+ {
+ delegate.persist(arg0);
+ }
+
+ public void persist(String arg0, Object arg1) throws HibernateException
+ {
+ delegate.persist(arg0, arg1);
+ }
+
+ public void reconnect() throws HibernateException
+ {
+ throw new UnsupportedOperationException("deprecated");
+ }
+
+ public void reconnect(Connection arg0) throws HibernateException
+ {
+ delegate.reconnect(arg0);
+ }
+
+ public void refresh(Object arg0, LockMode arg1) throws HibernateException
+ {
+ delegate.refresh(arg0, arg1);
+ }
+
+ public void refresh(Object arg0) throws HibernateException
+ {
+ delegate.refresh(arg0);
+ }
+
+ public void replicate(Object arg0, ReplicationMode arg1) throws HibernateException
+ {
+ delegate.replicate(arg0, arg1);
+ }
+
+ public void replicate(String arg0, Object arg1, ReplicationMode arg2) throws HibernateException
+ {
+ delegate.replicate(arg0, arg1, arg2);
+ }
+
+ public Serializable save(Object arg0) throws HibernateException
+ {
+ return delegate.save(arg0);
+ }
+
+ public Serializable save(String arg0, Object arg1) throws HibernateException
+ {
+ return delegate.save(arg0, arg1);
+ }
+
+ public void saveOrUpdate(Object arg0) throws HibernateException
+ {
+ delegate.saveOrUpdate(arg0);
+ }
+
+ public void saveOrUpdate(String arg0, Object arg1) throws HibernateException
+ {
+ delegate.saveOrUpdate(arg0, arg1);
+ }
+
+ public void setCacheMode(CacheMode arg0)
+ {
+ delegate.setCacheMode(arg0);
+ }
+
+ public void setFlushMode(FlushMode arg0)
+ {
+ delegate.setFlushMode(arg0);
+ }
+
+ public void setReadOnly(Object arg0, boolean arg1)
+ {
+ delegate.setReadOnly(arg0, arg1);
+ }
+
+ public void update(Object arg0) throws HibernateException
+ {
+ delegate.update(arg0);
+ }
+
+ public void update(String arg0, Object arg1) throws HibernateException
+ {
+ delegate.update(arg0, arg1);
+ }
+
+ private SessionImplementor getDelegateSessionImplementor()
+ {
+ return (SessionImplementor) delegate;
+ }
+
+ private EventSource getDelegateEventSource()
+ {
+ return (EventSource) delegate;
+ }
+
+ public void afterScrollOperation()
+ {
+ getDelegateSessionImplementor().afterScrollOperation();
+ }
+
+ public void afterTransactionCompletion(boolean arg0, Transaction arg1)
+ {
+ getDelegateSessionImplementor().afterTransactionCompletion(arg0, arg1);
+ }
+
+ public void beforeTransactionCompletion(Transaction arg0)
+ {
+ getDelegateSessionImplementor().beforeTransactionCompletion(arg0);
+ }
+
+ public String bestGuessEntityName(Object arg0)
+ {
+ return getDelegateSessionImplementor().bestGuessEntityName(arg0);
+ }
+
+ public int executeNativeUpdate(NativeSQLQuerySpecification arg0, QueryParameters arg1) throws HibernateException
+ {
+ return getDelegateSessionImplementor().executeNativeUpdate(arg0, arg1);
+ }
+
+ public int executeUpdate(String arg0, QueryParameters arg1) throws HibernateException
+ {
+ return getDelegateSessionImplementor().executeUpdate(arg0, arg1);
+ }
+
+ public Batcher getBatcher()
+ {
+ return getDelegateSessionImplementor().getBatcher();
+ }
+
+ public Serializable getContextEntityIdentifier(Object arg0)
+ {
+ return getDelegateSessionImplementor().getContextEntityIdentifier(arg0);
+ }
+
+ public int getDontFlushFromFind()
+ {
+ return getDelegateSessionImplementor().getDontFlushFromFind();
+ }
+
+ public Map getEnabledFilters()
+ {
+ return getDelegateSessionImplementor().getEnabledFilters();
+ }
+
+ public EntityPersister getEntityPersister(String arg0, Object arg1) throws HibernateException
+ {
+ return getDelegateSessionImplementor().getEntityPersister(arg0, arg1);
+ }
+
+ public Object getEntityUsingInterceptor(EntityKey arg0) throws HibernateException
+ {
+ return getDelegateSessionImplementor().getEntityUsingInterceptor(arg0);
+ }
+
+ public SessionFactoryImplementor getFactory()
+ {
+ return getDelegateSessionImplementor().getFactory();
+ }
+
+ public String getFetchProfile()
+ {
+ return getDelegateSessionImplementor().getFetchProfile();
+ }
+
+ public Type getFilterParameterType(String arg0)
+ {
+ return getDelegateSessionImplementor().getFilterParameterType(arg0);
+ }
+
+ public Object getFilterParameterValue(String arg0)
+ {
+ return getDelegateSessionImplementor().getFilterParameterValue(arg0);
+ }
+
+ public Interceptor getInterceptor()
+ {
+ return getDelegateSessionImplementor().getInterceptor();
+ }
+
+ public JDBCContext getJDBCContext()
+ {
+ return getDelegateSessionImplementor().getJDBCContext();
+ }
+
+ public EventListeners getListeners()
+ {
+ return getDelegateSessionImplementor().getListeners();
+ }
+
+ public Query getNamedSQLQuery(String arg0)
+ {
+ return getDelegateSessionImplementor().getNamedSQLQuery(arg0);
+ }
+
+ public PersistenceContext getPersistenceContext()
+ {
+ return getDelegateSessionImplementor().getPersistenceContext();
+ }
+
+ public long getTimestamp()
+ {
+ return getDelegateSessionImplementor().getTimestamp();
+ }
+
+ public String guessEntityName(Object arg0) throws HibernateException
+ {
+ return getDelegateSessionImplementor().guessEntityName(arg0);
+ }
+
+ public Object immediateLoad(String arg0, Serializable arg1) throws HibernateException
+ {
+ return getDelegateSessionImplementor().immediateLoad(arg0, arg1);
+ }
+
+ public void initializeCollection(PersistentCollection arg0, boolean arg1) throws HibernateException
+ {
+ getDelegateSessionImplementor().initializeCollection(arg0, arg1);
+ }
+
+ public Object instantiate(String arg0, Serializable arg1) throws HibernateException
+ {
+ return getDelegateSessionImplementor().instantiate(arg0, arg1);
+ }
+
+ public Object internalLoad(String arg0, Serializable arg1, boolean arg2, boolean arg3) throws HibernateException
+ {
+ return getDelegateSessionImplementor().internalLoad(arg0, arg1, arg2, arg3);
+ }
+
+ public boolean isClosed()
+ {
+ return getDelegateSessionImplementor().isClosed();
+ }
+
+ public boolean isEventSource()
+ {
+ return getDelegateSessionImplementor().isEventSource();
+ }
+
+ public boolean isTransactionInProgress()
+ {
+ return getDelegateSessionImplementor().isTransactionInProgress();
+ }
+
+ public Iterator iterate(String arg0, QueryParameters arg1) throws HibernateException
+ {
+ return getDelegateSessionImplementor().iterate(arg0, arg1);
+ }
+
+ public Iterator iterateFilter(Object arg0, String arg1, QueryParameters arg2) throws HibernateException
+ {
+ return getDelegateSessionImplementor().iterateFilter(arg0, arg1, arg2);
+ }
+
+ public List list(CriteriaImpl arg0)
+ {
+ return getDelegateSessionImplementor().list(arg0);
+ }
+
+ public List list(NativeSQLQuerySpecification arg0, QueryParameters arg1) throws HibernateException
+ {
+ return getDelegateSessionImplementor().list(arg0, arg1);
+ }
+
+ public List list(String arg0, QueryParameters arg1) throws HibernateException
+ {
+ return getDelegateSessionImplementor().list(arg0, arg1);
+ }
+
+ public List listCustomQuery(CustomQuery arg0, QueryParameters arg1) throws HibernateException
+ {
+ return getDelegateSessionImplementor().listCustomQuery(arg0, arg1);
+ }
+
+ public List listFilter(Object arg0, String arg1, QueryParameters arg2) throws HibernateException
+ {
+ return getDelegateSessionImplementor().listFilter(arg0, arg1, arg2);
+ }
+
+ public ScrollableResults scroll(CriteriaImpl arg0, ScrollMode arg1)
+ {
+ return getDelegateSessionImplementor().scroll(arg0, arg1);
+ }
+
+ public ScrollableResults scroll(NativeSQLQuerySpecification arg0, QueryParameters arg1) throws HibernateException
+ {
+ return getDelegateSessionImplementor().scroll(arg0, arg1);
+ }
+
+ public ScrollableResults scroll(String arg0, QueryParameters arg1) throws HibernateException
+ {
+ return getDelegateSessionImplementor().scroll(arg0, arg1);
+ }
+
+ public ScrollableResults scrollCustomQuery(CustomQuery arg0, QueryParameters arg1) throws HibernateException
+ {
+ return getDelegateSessionImplementor().scrollCustomQuery(arg0, arg1);
+ }
+
+ public void setAutoClear(boolean arg0)
+ {
+ getDelegateSessionImplementor().setAutoClear(arg0);
+ }
+
+ public void setFetchProfile(String arg0)
+ {
+ getDelegateSessionImplementor().setFetchProfile(arg0);
+ }
+
+ public ActionQueue getActionQueue() {
+ return getDelegateEventSource().getActionQueue();
+ }
+
+ public Object instantiate(EntityPersister entityPersister, Serializable serializable) throws HibernateException {
+ return getDelegateEventSource().instantiate( entityPersister, serializable );
+ }
+
+ public void forceFlush(EntityEntry entityEntry) throws HibernateException {
+ getDelegateEventSource().forceFlush( entityEntry );
+ }
+
+ public void merge(String s, Object o, Map map) throws HibernateException {
+ getDelegateEventSource().merge( s, o, map );
+ }
+
+ public void persist(String s, Object o, Map map) throws HibernateException {
+ getDelegateEventSource().persist( s, o, map );
+ }
+
+ public void persistOnFlush(String s, Object o, Map map) {
+ getDelegateEventSource().persistOnFlush( s, o, map );
+ }
+
+ public void refresh(Object o, Map map) throws HibernateException {
+ getDelegateEventSource().refresh( o, map );
+ }
+
+ public void saveOrUpdateCopy(String s, Object o, Map map) throws HibernateException {
+ getDelegateEventSource().saveOrUpdateCopy( s, o , map );
+ }
+
+ public void delete(String s, Object o, boolean b, Set set) {
+ getDelegateEventSource().delete( s, o, b, set );
+ }
+}
Added: modules/trunk/persistence/src/main/java/org/jboss/seam/persistence/HibernateSessionProxyInterceptor.java
===================================================================
--- modules/trunk/persistence/src/main/java/org/jboss/seam/persistence/HibernateSessionProxyInterceptor.java (rev 0)
+++ modules/trunk/persistence/src/main/java/org/jboss/seam/persistence/HibernateSessionProxyInterceptor.java 2009-04-27 12:48:53 UTC (rev 10650)
@@ -0,0 +1,67 @@
+package org.jboss.seam.persistence;
+
+import static org.jboss.seam.ComponentType.STATEFUL_SESSION_BEAN;
+import static org.jboss.seam.ComponentType.STATELESS_SESSION_BEAN;
+
+import org.hibernate.Session;
+import org.jboss.seam.Component.BijectedAttribute;
+import org.jboss.seam.annotations.intercept.AroundInvoke;
+import org.jboss.seam.annotations.intercept.Interceptor;
+import org.jboss.seam.annotations.intercept.PostActivate;
+import org.jboss.seam.annotations.intercept.PostConstruct;
+import org.jboss.seam.intercept.AbstractInterceptor;
+import org.jboss.seam.intercept.InvocationContext;
+import org.jboss.seam.util.Reflections;
+
+/**
+ * Proxy the Hibernate Session if injected using @PersistenceContext
+ *
+ * @author Pete Muir
+ *
+ */
+
+@Interceptor(stateless=true)
+public class HibernateSessionProxyInterceptor extends AbstractInterceptor
+{
+
+ @AroundInvoke
+ public Object aroundInvoke(InvocationContext ic) throws Exception
+ {
+ return ic.proceed();
+ }
+
+ @PostActivate
+ public void postActivate(InvocationContext invocation) throws Exception
+ {
+ //just in case the container does some special handling of PC serialization
+ proxyPersistenceContexts(invocation.getTarget());
+ invocation.proceed();
+ }
+
+ @PostConstruct
+ public void postConstruct(InvocationContext invocation) throws Exception
+ {
+ proxyPersistenceContexts(invocation.getTarget());
+ invocation.proceed();
+ }
+
+
+ private void proxyPersistenceContexts(Object bean)
+ {
+ //wrap any @PersistenceContext attributes in our proxy
+ for ( BijectedAttribute ba: getComponent().getPersistenceContextAttributes() )
+ {
+ Object object = ba.get(bean);
+ if ( ! ( object instanceof HibernateSessionProxy) && object instanceof Session)
+ {
+ ba.set( bean, HibernatePersistenceProvider.proxySession( (Session) object ) );
+ }
+ }
+ }
+
+ public boolean isInterceptorEnabled()
+ {
+ return (getComponent().getType()==STATEFUL_SESSION_BEAN || getComponent().getType()==STATELESS_SESSION_BEAN) && Reflections.isClassAvailable("org.hibernate.Session");
+ }
+
+}
Added: modules/trunk/persistence/src/main/java/org/jboss/seam/persistence/ManagedEntityInterceptor.java
===================================================================
--- modules/trunk/persistence/src/main/java/org/jboss/seam/persistence/ManagedEntityInterceptor.java (rev 0)
+++ modules/trunk/persistence/src/main/java/org/jboss/seam/persistence/ManagedEntityInterceptor.java 2009-04-27 12:48:53 UTC (rev 10650)
@@ -0,0 +1,80 @@
+package org.jboss.seam.persistence;
+
+import static org.jboss.seam.ScopeType.CONVERSATION;
+
+import org.jboss.seam.annotations.intercept.AroundInvoke;
+import org.jboss.seam.annotations.intercept.Interceptor;
+import org.jboss.seam.core.BijectionInterceptor;
+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.transaction.Transaction;
+
+/**
+ * Swizzles entity references around each invocation, maintaining referential
+ * integrity even across passivation of the stateful bean or Seam-managed
+ * extended persistence context, and allowing for more efficient replication.
+ *
+ * @author Gavin King
+ * @author Pete Muir
+ *
+ */
+@Interceptor(around = BijectionInterceptor.class)
+public class ManagedEntityInterceptor extends AbstractInterceptor
+{
+
+ private static LogProvider log = Logging.getLogProvider(ManagedEntityInterceptor.class);
+
+ private static ManagedEntityWrapper managedEntityWrapper = new ManagedEntityWrapper();
+
+ private boolean reentrant;
+
+ @AroundInvoke
+ public Object aroundInvoke(InvocationContext ctx) throws Exception
+ {
+ if (reentrant)
+ {
+ return ctx.proceed();
+ }
+ else
+ {
+ reentrant = true;
+ log.trace("Attempting to activate " + getComponent().getName() + " component");
+ managedEntityWrapper.deserialize(ctx.getTarget(), getComponent());
+ log.debug("Activated " + getComponent().getName() + " component");
+ try
+ {
+ return ctx.proceed();
+ }
+ finally
+ {
+ if (!isTransactionRolledBackOrMarkedRollback())
+ {
+ log.trace("Attempting to passivate " + getComponent().getName() + " component");
+ managedEntityWrapper.wrap(ctx.getTarget(), getComponent());
+ reentrant = false;
+ log.debug("Passivated " + getComponent().getName() + " component");
+ }
+ }
+ }
+ }
+
+ public boolean isInterceptorEnabled()
+ {
+ return getComponent().getScope() == CONVERSATION;
+ }
+
+ private static boolean isTransactionRolledBackOrMarkedRollback()
+ {
+ try
+ {
+ return Transaction.instance().isRolledBackOrMarkedRollback();
+ }
+ catch (Exception e)
+ {
+ return false;
+ }
+ }
+
+}
Added: modules/trunk/persistence/src/main/java/org/jboss/seam/persistence/ManagedEntityWrapper.java
===================================================================
--- modules/trunk/persistence/src/main/java/org/jboss/seam/persistence/ManagedEntityWrapper.java (rev 0)
+++ modules/trunk/persistence/src/main/java/org/jboss/seam/persistence/ManagedEntityWrapper.java 2009-04-27 12:48:53 UTC (rev 10650)
@@ -0,0 +1,253 @@
+package org.jboss.seam.persistence;
+
+import static org.jboss.seam.util.JSF.DATA_MODEL;
+import static org.jboss.seam.util.JSF.getWrappedData;
+import static org.jboss.seam.util.JSF.setWrappedData;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.jboss.seam.Component;
+import org.jboss.seam.Seam;
+import org.jboss.seam.annotations.In;
+import org.jboss.seam.contexts.Contexts;
+import org.jboss.seam.core.Manager;
+import org.jboss.webbeans.log.LogProvider;
+import org.jboss.webbeans.log.Logging;
+import org.jboss.seam.util.Reflections;
+
+/**
+ * @author Gavin King
+ * @author Pete Muir
+ * @author Norman Richards
+ * @author Dan Allen
+ */
+public class ManagedEntityWrapper
+{
+
+ private static LogProvider log = Logging.getLogProvider(ManagedEntityWrapper.class);
+
+ public void wrap(Object target, Component component) throws Exception
+ {
+ if ( !touchedContextsExist() )
+ {
+ log.trace("No touched persistence contexts. Therefore, there are no entities in this conversation whose identities need to be preserved.");
+ return;
+ }
+
+ String oldCid = switchToConversationContextOfComponent(component);
+ Class beanClass = target.getClass();
+ for (; beanClass!=Object.class; beanClass=beanClass.getSuperclass())
+ {
+ log.trace("Examining fields on " + beanClass);
+ for ( Field field: beanClass.getDeclaredFields() )
+ {
+ if ( !ignore(field) )
+ {
+ Object value = getFieldValue(target, field);
+ if (value!=null)
+ {
+ Object dataModel = null;
+ if ( DATA_MODEL.isInstance(value) )
+ {
+ dataModel = value;
+ value = getWrappedData(dataModel);
+ }
+ if ( containsReferenceToEntityInstance(value) )
+ {
+ log.trace("Attempting to save wrapper for " + field + " (" + value + ")");
+ saveWrapper(target, component, field, dataModel, value);
+ }
+ else
+ {
+ log.trace("Clearing wrapper for " + field + " (" + value + ") as it isn't a entity reference");
+ clearWrapper(component, field);
+ }
+ }
+ else
+ {
+ log.trace("Clearing wrapper for " + field + " as it is null");
+ clearWrapper(component, field);
+ }
+ }
+ else
+ {
+ log.trace("Ignoring field " + field + " as it is static, transient or annotated with @In");
+ }
+ }
+ }
+ restorePreviousConversationContextIfNecessary(oldCid);
+ }
+
+ public void deserialize(Object controllerBean, Component component) throws Exception
+ {
+ if ( !touchedContextsExist() )
+ {
+ log.trace("No touched persistence contexts. Therefore, there are no entities in this conversation whose identities need to be restored.");
+ return;
+ }
+
+ Class beanClass = controllerBean.getClass();
+ for (; beanClass!=Object.class; beanClass=beanClass.getSuperclass())
+ {
+ log.trace("Examining fields on " + beanClass);
+ for ( Field field: beanClass.getDeclaredFields() )
+ {
+ if ( !ignore(field) )
+ {
+ Object value = getFieldValue(controllerBean, field);
+ Object dataModel = null;
+ if (value!=null && DATA_MODEL.isInstance(value) )
+ {
+ dataModel = value;
+ }
+ log.trace("Attempting to restore wrapper for " + field + " (" + value + ")");
+ //TODO: be more selective
+ getFromWrapper(controllerBean, component, field, dataModel);
+ }
+ else
+ {
+ log.trace("Ignoring field " + field + " as it is static, transient or annotated with @In");
+ }
+ }
+ }
+ }
+
+ private boolean containsReferenceToEntityInstance(Object value)
+ {
+ if (value == null)
+ {
+ return false;
+ }
+ else if (value instanceof Collection)
+ {
+ // Do a lazy man's generic check by scanning the collection until an entity is found (nested objects not considered).
+ for (Iterator iter = ((Collection) value).iterator(); iter.hasNext();)
+ {
+ Object v = iter.next();
+ if (v != null && Seam.getEntityClass(v.getClass()) != null)
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+ else if (value instanceof Map)
+ {
+ // Do a lazy man's generic check by scanning the collection until an entity is found (nested objects not considered).
+ for (Iterator iter = ((Map) value).entrySet().iterator(); iter.hasNext();)
+ {
+ Entry e = (Entry) iter.next();
+ if ((e.getKey() != null && Seam.getEntityClass(e.getKey().getClass()) != null) ||
+ (e.getValue() != null && Seam.getEntityClass(e.getValue().getClass()) != null))
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+ else if (Seam.getEntityClass(value.getClass()) != null)
+ {
+ return true;
+ }
+
+ return false;
+ }
+
+ private Object getFieldValue(Object bean, Field field) throws Exception
+ {
+ if ( !field.isAccessible() ) field.setAccessible(true);
+ Object value = Reflections.get(field, bean);
+ return value;
+ }
+
+ private boolean ignore(Field field)
+ {
+ return Modifier.isTransient( field.getModifiers() ) ||
+ Modifier.isStatic( field.getModifiers() )
+ || field.isAnnotationPresent(In.class);
+ }
+
+ private boolean touchedContextsExist()
+ {
+ PersistenceContexts touchedContexts = PersistenceContexts.instance();
+ return touchedContexts!=null && touchedContexts.getTouchedContexts().size()>0;
+ }
+
+ private String getFieldId(Component component, Field field)
+ {
+ return component.getName() + '.' + field.getName();
+ }
+
+ private void saveWrapper(Object bean, Component component, Field field, Object dataModel, Object value) throws Exception
+ {
+ Contexts.getConversationContext().set( getFieldId(component, field), value );
+ if (dataModel==null)
+ {
+ Reflections.set(field, bean, null);
+ }
+ else
+ {
+ // JBSEAM-1814, JBPAPP-1616 Clearing the wrapped data is simply unnecessary. Either we leave it alone, or we set the field to null.
+ //setWrappedData(dataModel, null);
+ }
+ }
+
+ private void clearWrapper(Component component, Field field) throws Exception
+ {
+ Contexts.getConversationContext().remove( getFieldId(component, field) );
+ }
+
+ private void getFromWrapper(Object bean, Component component, Field field, Object dataModel) throws Exception
+ {
+ Object value =Contexts.getConversationContext().get( getFieldId(component, field) );
+ if (value!=null)
+ {
+ if (dataModel==null)
+ {
+ Reflections.set(field, bean, value);
+ }
+ else
+ {
+ setWrappedData(dataModel, value);
+ }
+ }
+ }
+
+ /**
+ * Changes the thread's current conversation context to the one that holds a reference to this
+ * component. This is necessary if a nested conversation is making a call to a component in
+ * a parent conversation.
+ */
+ private String switchToConversationContextOfComponent(Component component)
+ {
+ Manager manager = Manager.instance();
+ if (manager.isNestedConversation())
+ {
+ String currentCid = manager.getCurrentConversationId();
+ String residentCid = manager.getCurrentConversationEntry().findPositionInConversationStack(component);
+ if (!currentCid.equals(residentCid))
+ {
+ Contexts.getConversationContext().flush();
+ Manager.instance().switchConversation(residentCid, false);
+ return currentCid;
+ }
+ }
+
+ return null;
+ }
+
+ private void restorePreviousConversationContextIfNecessary(String oldCid)
+ {
+ if (oldCid != null)
+ {
+ Contexts.getConversationContext().flush();
+ Manager.instance().switchConversation(oldCid, false);
+ }
+ }
+
+}
Added: modules/trunk/persistence/src/main/java/org/jboss/seam/persistence/ManagedHibernateSession.java
===================================================================
--- modules/trunk/persistence/src/main/java/org/jboss/seam/persistence/ManagedHibernateSession.java (rev 0)
+++ modules/trunk/persistence/src/main/java/org/jboss/seam/persistence/ManagedHibernateSession.java 2009-04-27 12:48:53 UTC (rev 10650)
@@ -0,0 +1,322 @@
+//$Id: ManagedHibernateSession.java 9081 2008-09-22 03:02:30Z dan.j.allen $
+package org.jboss.seam.persistence;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+import javax.annotation.PreDestroy;
+import javax.context.ConversationScoped;
+import javax.inject.Current;
+import javax.inject.Initializer;
+import javax.inject.Produces;
+import javax.naming.NamingException;
+import javax.servlet.http.HttpSessionActivationListener;
+import javax.servlet.http.HttpSessionEvent;
+import javax.transaction.Synchronization;
+import javax.transaction.SystemException;
+
+import org.hibernate.FlushMode;
+import org.hibernate.Session;
+import org.hibernate.SessionFactory;
+import org.jboss.seam.core.Mutable;
+import org.jboss.seam.core.Expressions.ValueExpression;
+import org.jboss.webbeans.log.LogProvider;
+import org.jboss.webbeans.log.Logging;
+import org.jboss.seam.persistence.annotations.FlushModeType;
+import org.jboss.seam.transaction.Transaction;
+import org.jboss.seam.transaction.UserTransaction;
+import org.jboss.seam.util.Naming;
+
+/**
+ * A Seam component that manages a conversation-scoped extended
+ * persistence context that can be shared by arbitrary other
+ * components.
+ *
+ * @author Gavin King
+ */
+@ConversationScoped
+public class ManagedHibernateSession
+ implements Serializable, HttpSessionActivationListener, Mutable, PersistenceContextManager, Synchronization
+{
+
+ /** The serialVersionUID */
+ private static final long serialVersionUID = 3130309555079841107L;
+
+ private static final LogProvider log = Logging.getLogProvider(ManagedHibernateSession.class);
+
+ private Session session;
+ private String sessionFactoryJndiName;
+ private String componentName;
+ private ValueExpression<SessionFactory> sessionFactory;
+ private List<Filter> filters = new ArrayList<Filter>(0);
+
+ private transient boolean synchronizationRegistered;
+ private transient boolean destroyed;
+
+ @Current PersistenceContexts persistenceContexts;
+
+ public boolean clearDirty()
+ {
+ return true;
+ }
+
+ @Initializer
+ public void create(Component component)
+ {
+ this.componentName = component.getName();
+ if (sessionFactoryJndiName==null)
+ {
+ sessionFactoryJndiName = "java:/" + componentName;
+ }
+
+ persistenceContexts.touch(componentName);
+ }
+
+ private void initSession() throws Exception
+ {
+ session = getSessionFactoryFromJndiOrValueBinding().openSession();
+ setSessionFlushMode( persistenceContexts.getFlushMode() );
+ session = HibernatePersistenceProvider.proxySession(session);
+
+ for (Filter f: filters)
+ {
+ if ( f.isFilterEnabled() )
+ {
+ enableFilter(f);
+ }
+ }
+
+ if ( log.isDebugEnabled() )
+ {
+ log.debug("created seam managed session for session factory: "+ sessionFactoryJndiName);
+ }
+ }
+
+ private void enableFilter(Filter f)
+ {
+ org.hibernate.Filter filter = session.enableFilter( f.getName() );
+ for ( Map.Entry<String, ValueExpression> me: f.getParameters().entrySet() )
+ {
+ Object filterValue = me.getValue().getValue();
+ if ( filterValue instanceof Collection ) {
+ filter.setParameterList(me.getKey(), (Collection) filterValue);
+ } else {
+ filter.setParameter(me.getKey(), filterValue);
+ }
+ }
+ filter.validate();
+ }
+
+ @Produces public Session getSession() throws Exception
+ {
+ if (session==null) initSession();
+
+ if ( !synchronizationRegistered && !Lifecycle.isDestroying() )
+ {
+ joinTransaction();
+ }
+
+ return session;
+ }
+
+ private void joinTransaction() throws SystemException
+ {
+ UserTransaction transaction = Transaction.instance();
+ if ( transaction.isActive() )
+ {
+ session.isOpen();
+ try
+ {
+ transaction.registerSynchronization(this);
+ }
+ catch (Exception e)
+ {
+ session.getTransaction().registerSynchronization(this);
+ }
+ synchronizationRegistered = true;
+ }
+ }
+
+ //we can't use @PrePassivate because it is intercept NEVER
+ public void sessionWillPassivate(HttpSessionEvent event)
+ {
+ if (synchronizationRegistered)
+ {
+ throw new IllegalStateException("cannot passivate persistence context with active transaction");
+ }
+ if ( session!=null && session.isOpen() && !session.isDirty() )
+ {
+ session.close();
+ session = null;
+ }
+ }
+
+ //we can't use @PostActivate because it is intercept NEVER
+ public void sessionDidActivate(HttpSessionEvent event) {}
+
+ @PreDestroy
+ public void destroy()
+ {
+ destroyed = true;
+ 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 destroyed
+ //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
+ close();
+ }
+ persistenceContexts.untouch(componentName);
+ }
+
+ public void afterCompletion(int status)
+ {
+ synchronizationRegistered = false;
+ //if ( !Contexts.isConversationContextActive() )
+ if (destroyed)
+ {
+ //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
+ //conversation context, leave it open
+ close();
+ }
+ }
+
+ public void beforeCompletion() {}
+
+ private void close()
+ {
+ boolean transactionActive = false;
+ try
+ {
+ transactionActive = Transaction.instance().isActive();
+ }
+ catch (SystemException se)
+ {
+ log.debug("could not get transaction status while destroying persistence context");
+ }
+
+ if ( transactionActive )
+ {
+ throw new IllegalStateException("attempting to destroy the persistence context while an active transaction exists (try installing <transaction:ejb-transaction/>)");
+ }
+
+ if ( log.isDebugEnabled() )
+ {
+ log.debug("destroying seam managed session for session factory: " + sessionFactoryJndiName);
+ }
+ if (session!=null && session.isOpen())
+ {
+ session.close();
+ }
+ }
+
+ private SessionFactory getSessionFactoryFromJndiOrValueBinding()
+ {
+ SessionFactory result = null;
+ //first try to find it via the value binding
+ if (sessionFactory!=null)
+ {
+ result = sessionFactory.getValue();
+ }
+ //if its not there, try JNDI
+ if (result==null)
+ {
+ try
+ {
+ result = (SessionFactory) Naming.getInitialContext().lookup(sessionFactoryJndiName);
+ }
+ catch (NamingException ne)
+ {
+ throw new IllegalArgumentException("SessionFactory not found in JNDI: " + sessionFactoryJndiName, ne);
+ }
+ }
+ return result;
+ }
+
+ public String getComponentName() {
+ return componentName;
+ }
+
+ public void changeFlushMode(FlushModeType flushMode)
+ {
+ if (session!=null && session.isOpen())
+ {
+ setSessionFlushMode(flushMode);
+ }
+ }
+
+ protected void setSessionFlushMode(FlushModeType flushMode)
+ {
+ switch (flushMode)
+ {
+ case AUTO:
+ session.setFlushMode(FlushMode.AUTO);
+ break;
+ case MANUAL:
+ session.setFlushMode(FlushMode.MANUAL);
+ break;
+ case COMMIT:
+ session.setFlushMode(FlushMode.COMMIT);
+ break;
+ }
+ }
+
+ /**
+ * The JNDI name of the Hibernate SessionFactory, if it is
+ * to be obtained from JNDI
+ */
+ public String getSessionFactoryJndiName()
+ {
+ return sessionFactoryJndiName;
+ }
+
+ public void setSessionFactoryJndiName(String sessionFactoryName)
+ {
+ this.sessionFactoryJndiName = sessionFactoryName;
+ }
+
+ /**
+ * A value binding expression that returns a SessionFactory,
+ * if it is to be obtained as a Seam component reference
+ */
+ public void setSessionFactory(ValueExpression<SessionFactory> sessionFactory)
+ {
+ this.sessionFactory = sessionFactory;
+ }
+
+ public ValueExpression<SessionFactory> getSessionFactory()
+ {
+ return sessionFactory;
+ }
+
+ /**
+ * Hibernate filters to enable automatically
+ */
+ public List<Filter> getFilters()
+ {
+ return filters;
+ }
+
+ public void setFilters(List<Filter> filters)
+ {
+ this.filters = filters;
+ }
+
+ @Override
+ public String toString()
+ {
+ return "ManagedHibernateSession(" + sessionFactoryJndiName + ")";
+ }
+
+}
Added: modules/trunk/persistence/src/main/java/org/jboss/seam/persistence/ManagedPersistenceContext.java
===================================================================
--- modules/trunk/persistence/src/main/java/org/jboss/seam/persistence/ManagedPersistenceContext.java (rev 0)
+++ modules/trunk/persistence/src/main/java/org/jboss/seam/persistence/ManagedPersistenceContext.java 2009-04-27 12:48:53 UTC (rev 10650)
@@ -0,0 +1,323 @@
+//$Id: ManagedPersistenceContext.java 9721 2008-12-04 08:29:25Z dan.j.allen $
+package org.jboss.seam.persistence;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.annotation.PreDestroy;
+import javax.context.ConversationScoped;
+import javax.inject.Current;
+import javax.inject.Initializer;
+import javax.inject.Produces;
+import javax.naming.NamingException;
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import javax.servlet.http.HttpSessionActivationListener;
+import javax.servlet.http.HttpSessionEvent;
+import javax.transaction.Synchronization;
+import javax.transaction.SystemException;
+
+import org.jboss.seam.contexts.Lifecycle;
+import org.jboss.seam.core.Mutable;
+import org.jboss.seam.core.Expressions.ValueExpression;
+import org.jboss.webbeans.log.LogProvider;
+import org.jboss.webbeans.log.Logging;
+import org.jboss.seam.persistence.annotations.FlushModeType;
+import org.jboss.seam.transaction.Transaction;
+import org.jboss.seam.transaction.UserTransaction;
+import org.jboss.seam.util.Naming;
+
+/**
+ * A Seam component that manages a conversation-scoped extended
+ * persistence context that can be shared by arbitrary other
+ * components.
+ *
+ * @author Gavin King
+ */
+@ConversationScoped
+public class ManagedPersistenceContext
+ implements Serializable, HttpSessionActivationListener, Mutable, PersistenceContextManager, Synchronization
+{
+ private static final long serialVersionUID = -4972387440275848126L;
+ private static final LogProvider log = Logging.getLogProvider(ManagedPersistenceContext.class);
+
+ private transient EntityManager entityManager;
+ private String persistenceUnitJndiName;
+ private String componentName;
+ private ValueExpression<EntityManagerFactory> entityManagerFactory;
+ private List<Filter> filters = new ArrayList<Filter>(0);
+
+ private transient boolean synchronizationRegistered;
+ private transient boolean destroyed;
+
+ @Current PersistenceContexts persistenceContexts;
+ @Current PersistenceProvider persistenceProvider;
+
+ public boolean clearDirty()
+ {
+ return true;
+ }
+
+ @Initializer
+ public void create(Component component)
+ {
+ this.componentName = component.getName();
+ if (persistenceUnitJndiName==null)
+ {
+ persistenceUnitJndiName = "java:/" + componentName;
+ }
+
+ persistenceContexts.touch(componentName);
+ }
+
+ private void initEntityManager()
+ {
+ entityManager = getEntityManagerFactoryFromJndiOrValueBinding().createEntityManager();
+ entityManager = persistenceProvider.proxyEntityManager(entityManager);
+ setEntityManagerFlushMode( persistenceContexts.getFlushMode() );
+
+ for (Filter f: filters)
+ {
+ if ( f.isFilterEnabled() )
+ {
+ persistenceProvider.enableFilter(f, entityManager);
+ }
+ }
+
+ if ( log.isDebugEnabled() )
+ {
+ if (entityManagerFactory==null)
+ {
+ log.debug("created seam managed persistence context for persistence unit: "+ persistenceUnitJndiName);
+ }
+ else
+ {
+ log.debug("created seam managed persistence context from EntityManagerFactory");
+ }
+ }
+ }
+
+ @Produces
+ public EntityManager getEntityManager() throws NamingException, SystemException
+ {
+ if (entityManager==null) initEntityManager();
+
+ if ( !synchronizationRegistered && !Lifecycle.isDestroying() )
+ {
+ joinTransaction();
+ }
+
+ return entityManager;
+ }
+
+ private void joinTransaction() throws SystemException
+ {
+ UserTransaction transaction = Transaction.instance();
+ if ( transaction.isActive() )
+ {
+ transaction.enlist(entityManager);
+ try
+ {
+ transaction.registerSynchronization(this);
+ synchronizationRegistered = true;
+ }
+ catch (Exception e)
+ {
+ synchronizationRegistered = persistenceProvider.registerSynchronization(this, entityManager);
+ }
+ }
+ }
+
+ /**
+ * If a transaction is active, fail the passivation. The field holding the
+ * managed EntityManager is marked as transient so that it is not serialized
+ * (it can't be). The transient keyword was choosen because we don't want to
+ * forcefully close and nullify the EntityManager on every request because
+ * then we have to keep hitting the database to load the entities back into
+ * the persistence context. The only downside is that we cannot clean up
+ * on the old node before the session hops, but it turns out not to matter.
+ *
+ * Note that we must use the method on the
+ * {@link HttpSessionActivationListener} interface rather than
+ * <code>@PrePassivate</code> since interceptors are disabled on this component.
+ */
+ public void sessionWillPassivate(HttpSessionEvent event)
+ {
+ if (synchronizationRegistered)
+ {
+ throw new IllegalStateException("cannot passivate persistence context with active transaction");
+ }
+ }
+
+ /**
+ * Note that we must use the method on the {@link HttpSessionActivationListener}
+ * interface rather than @PostActivate since interceptors are disabled
+ * on this component.
+ */
+ public void sessionDidActivate(HttpSessionEvent event) {}
+
+ @PreDestroy
+ public void destroy()
+ {
+ destroyed = true;
+ 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 destroyed
+ //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
+ close();
+ }
+ persistenceContexts.untouch(componentName);
+ }
+
+ public void afterCompletion(int status)
+ {
+ synchronizationRegistered = false;
+ //if ( !Contexts.isConversationContextActive() )
+ if (destroyed)
+ {
+ //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
+ //conversation context, leave it open
+ close();
+ }
+ }
+
+ public void beforeCompletion() {}
+
+ private void close()
+ {
+ boolean transactionActive = false;
+ try
+ {
+ transactionActive = Transaction.instance().isActive();
+ }
+ catch (SystemException se)
+ {
+ log.debug("could not get transaction status while destroying persistence context");
+ }
+
+ if ( transactionActive )
+ {
+ throw new IllegalStateException("attempting to destroy the persistence context while an active transaction exists (try installing <transaction:ejb-transaction/>)");
+ }
+
+ if ( log.isDebugEnabled() )
+ {
+ log.debug("destroying seam managed persistence context for persistence unit: " + persistenceUnitJndiName);
+ }
+
+ if (entityManager!=null && entityManager.isOpen())
+ {
+ entityManager.close();
+ }
+ }
+
+ public EntityManagerFactory getEntityManagerFactoryFromJndiOrValueBinding()
+ {
+ EntityManagerFactory result = null;
+ //first try to find it via the value binding
+ if (entityManagerFactory!=null)
+ {
+ result = entityManagerFactory.getValue();
+ }
+ //if its not there, try JNDI
+ if (result==null)
+ {
+ try
+ {
+ result = (EntityManagerFactory) Naming.getInitialContext().lookup(persistenceUnitJndiName);
+ }
+ catch (NamingException ne)
+ {
+ throw new IllegalArgumentException("EntityManagerFactory not found in JNDI : " + persistenceUnitJndiName, ne);
+ }
+ }
+ return result;
+ }
+
+ /**
+ * A value binding expression that returns an EntityManagerFactory,
+ * for use of JPA outside of Java EE 5 / Embeddable EJB3.
+ */
+ public ValueExpression<EntityManagerFactory> getEntityManagerFactory()
+ {
+ return entityManagerFactory;
+ }
+
+ public void setEntityManagerFactory(ValueExpression<EntityManagerFactory> entityManagerFactory)
+ {
+ this.entityManagerFactory = entityManagerFactory;
+ }
+
+ /**
+ * The JNDI name of the EntityManagerFactory, for
+ * use of JPA in Java EE 5 / Embeddable EJB3.
+ */
+ public String getPersistenceUnitJndiName()
+ {
+ return persistenceUnitJndiName;
+ }
+
+ public void setPersistenceUnitJndiName(String persistenceUnitName)
+ {
+ this.persistenceUnitJndiName = persistenceUnitName;
+ }
+
+ public String getComponentName()
+ {
+ return componentName;
+ }
+
+ /**
+ * Hibernate filters to enable automatically
+ */
+ public List<Filter> getFilters()
+ {
+ return filters;
+ }
+
+ public void setFilters(List<Filter> filters)
+ {
+ this.filters = filters;
+ }
+
+ public void changeFlushMode(FlushModeType flushMode)
+ {
+ if (entityManager!=null && entityManager.isOpen())
+ {
+ setEntityManagerFlushMode(flushMode);
+ }
+ }
+
+ protected void setEntityManagerFlushMode(FlushModeType flushMode)
+ {
+ switch (flushMode)
+ {
+ case AUTO:
+ entityManager.setFlushMode(javax.persistence.FlushModeType.AUTO);
+ break;
+ case COMMIT:
+ entityManager.setFlushMode(javax.persistence.FlushModeType.COMMIT);
+ break;
+ case MANUAL:
+ persistenceProvider.setFlushModeManual(entityManager);
+ break;
+ }
+ }
+
+ @Override
+ public String toString()
+ {
+ return "ManagedPersistenceContext(" + persistenceUnitJndiName + ")";
+ }
+}
Added: modules/trunk/persistence/src/main/java/org/jboss/seam/persistence/Model.java
===================================================================
--- modules/trunk/persistence/src/main/java/org/jboss/seam/persistence/Model.java (rev 0)
+++ modules/trunk/persistence/src/main/java/org/jboss/seam/persistence/Model.java 2009-04-27 12:48:53 UTC (rev 10650)
@@ -0,0 +1,50 @@
+package org.jboss.seam.persistence;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Base class of metamodels. For a class which
+ * is neither an entity nor a Seam component,
+ * the concrete type of the metamodel object
+ * will be Model. For components or entities
+ * it is a subclass of Model.
+ *
+ * @author Gavin King
+ *
+ */
+public class Model
+{
+ protected static Map<String,Model> modelCache = new HashMap<String,Model>();
+
+ private Class<?> beanClass;
+
+ public Model(Class<?> beanClass)
+ {
+ this.beanClass = beanClass;
+ }
+
+ public final Class<?> getBeanClass()
+ {
+ return beanClass;
+ }
+
+ public static Model forClass(Class clazz)
+ {
+ String name = getModelName(clazz);
+ Model model = modelCache.get(name);
+ if ( model==null )
+ {
+ model = clazz.isAnnotationPresent(javax.persistence.Entity.class) ?
+ new Entity(clazz) : new Model(clazz);
+ modelCache.put(name, model);
+ }
+ return model;
+ }
+
+ static String getModelName(Class clazz)
+ {
+ return clazz.getName() + ".model";
+ }
+
+}
Added: modules/trunk/persistence/src/main/java/org/jboss/seam/persistence/PersistenceContextManager.java
===================================================================
--- modules/trunk/persistence/src/main/java/org/jboss/seam/persistence/PersistenceContextManager.java (rev 0)
+++ modules/trunk/persistence/src/main/java/org/jboss/seam/persistence/PersistenceContextManager.java 2009-04-27 12:48:53 UTC (rev 10650)
@@ -0,0 +1,15 @@
+package org.jboss.seam.persistence;
+
+import org.jboss.seam.persistence.annotations.FlushModeType;
+
+/**
+ * Support for changing flushmodes for an existing
+ * persistence context.
+ *
+ * @author Gavin King
+ *
+ */
+public interface PersistenceContextManager
+{
+ public void changeFlushMode(FlushModeType flushMode);
+}
Added: modules/trunk/persistence/src/main/java/org/jboss/seam/persistence/PersistenceContexts.java
===================================================================
--- modules/trunk/persistence/src/main/java/org/jboss/seam/persistence/PersistenceContexts.java (rev 0)
+++ modules/trunk/persistence/src/main/java/org/jboss/seam/persistence/PersistenceContexts.java 2009-04-27 12:48:53 UTC (rev 10650)
@@ -0,0 +1,128 @@
+package org.jboss.seam.persistence;
+
+import java.io.Serializable;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.context.Conversation;
+import javax.context.ConversationScoped;
+import javax.inject.Current;
+import javax.inject.Initializer;
+
+import org.jboss.seam.persistence.annotations.FlushModeType;
+import org.jboss.webbeans.log.LogProvider;
+import org.jboss.webbeans.log.Logging;
+
+/**
+ * Maintains the set of persistence contexts that have been touched in a
+ * conversation. Also controls the flush mode used by the persistence contexts
+ * during the render phase.
+ *
+ * @author Gavin King
+ */
+@ConversationScoped
+public class PersistenceContexts extends AbstractMutable implements Serializable
+{
+ private static final long serialVersionUID = -4897350516435283182L;
+ private static final LogProvider log = Logging.getLogProvider(PersistenceContexts.class);
+ private Set<String> set = new HashSet<String>();
+ private FlushModeType flushMode;
+ // the real flush mode is a backup of the flush mode when doing a temporary switch (such as during render)
+ private FlushModeType realFlushMode;
+
+ @Current PersistenceProvider persistenceProvider;
+
+ @Initializer
+ public void create()
+ {
+ FlushModeType defaultFlushMode = Manager.instance().getDefaultFlushMode();
+ if (defaultFlushMode != null)
+ {
+ flushMode = defaultFlushMode;
+ }
+ else
+ {
+ flushMode = FlushModeType.AUTO;
+ }
+ }
+
+ public FlushModeType getFlushMode()
+ {
+ return flushMode;
+ }
+
+ public Set<String> getTouchedContexts()
+ {
+ return Collections.unmodifiableSet(set);
+ }
+
+ public void touch(String context)
+ {
+ if ( set.add(context) ) setDirty();
+ }
+
+ public void untouch(String context)
+ {
+ if ( set.remove(context) ) setDirty();
+ }
+
+ public void changeFlushMode(FlushModeType flushMode)
+ {
+ changeFlushMode(flushMode, false);
+ }
+
+ public void changeFlushMode(FlushModeType flushMode, boolean temporary)
+ {
+ if (temporary) {
+ realFlushMode = this.flushMode;
+ }
+ this.flushMode = flushMode;
+ changeFlushModes();
+ }
+
+ /**
+ * Restore the previous flush mode if the current flush mode is marked
+ * as temporary.
+ */
+ public void restoreFlushMode() {
+ if (realFlushMode != null && realFlushMode != flushMode) {
+ flushMode = realFlushMode;
+ realFlushMode = null;
+ changeFlushModes();
+ }
+ }
+
+ private void changeFlushModes()
+ {
+ for (String name: set)
+ {
+ PersistenceContextManager pcm = (PersistenceContextManager) Contexts.getConversationContext().get(name);
+ if (pcm!=null)
+ {
+ try
+ {
+ pcm.changeFlushMode(flushMode);
+ }
+ catch (UnsupportedOperationException uoe)
+ {
+ // we won't be nasty and throw and exception, but we'll log a warning to the developer
+ log.warn(uoe.getMessage());
+ }
+ }
+ }
+ }
+
+ public void beforeRender()
+ {
+ // some JPA providers may not support MANUAL flushing
+ // defer the decision to the provider manager component
+ persistenceProvider.setRenderFlushMode();
+ }
+
+ public void afterRender()
+ {
+ restoreFlushMode();
+ }
+
+}
Added: modules/trunk/persistence/src/main/java/org/jboss/seam/persistence/PersistenceProvider.java
===================================================================
--- modules/trunk/persistence/src/main/java/org/jboss/seam/persistence/PersistenceProvider.java (rev 0)
+++ modules/trunk/persistence/src/main/java/org/jboss/seam/persistence/PersistenceProvider.java 2009-04-27 12:48:53 UTC (rev 10650)
@@ -0,0 +1,210 @@
+package org.jboss.seam.persistence;
+
+import java.lang.reflect.Method;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.annotation.Named;
+import javax.annotation.PostConstruct;
+import javax.persistence.EntityManager;
+import javax.persistence.OptimisticLockException;
+import javax.transaction.Synchronization;
+
+/**
+ * Abstraction layer for persistence providers (JPA implementations).
+ * This class provides a working base implementation that can be
+ * optimized for performance and non-standardized features by extending
+ * and overriding the methods.
+ *
+ * The methods on this class are a great todo list for the next rev
+ * of the JPA spec ;-)
+ *
+ * @author Gavin King
+ * @author Pete Muir
+ *
+ */
+@Named
+public class PersistenceProvider
+{
+ public enum Feature {
+ /**
+ * Identifies whether this JPA provider supports using a wildcard as the subject of a count query.
+ *
+ * <p>Here's a count query that uses a wildcard as the subject.</p>
+ * <pre>select count(*) from Vehicle v</pre>
+ * <p>Per the JPA 1.0 spec, using a wildcard as a subject of a count query is not permitted. Instead,
+ * the subject must be the entity or the alias, as in this count query:</p>
+ * <pre>select count(v) from Vehicle v</pre>
+ * <p>Hibernate supports the wildcard syntax as an vendor extension. Furthermore, Hibernate produces
+ * an invalid SQL query when using the compliant subject if the entity has a composite primary key.
+ * Therefore, we prefer to use the wildcard syntax if it is supported.</p>
+ */
+ WILDCARD_AS_COUNT_QUERY_SUBJECT
+ }
+
+ protected Set<Feature> featureSet = new HashSet<Feature>();
+
+ @PostConstruct // @Create method not called on stateless components
+ public void init() {}
+
+ /**
+ * Indicate whether this JPA provider supports the feature defined by the provided Feature enum value.
+ */
+ public boolean supportsFeature(Feature feature) {
+ return featureSet.contains(feature);
+ }
+
+ /**
+ * Set the flush mode to manual-only flushing. Called when
+ * an atomic persistence context is required.
+ */
+ public void setFlushModeManual(EntityManager entityManager)
+ {
+ throw new UnsupportedOperationException("Use of FlushMode.MANUAL requires Hibernate as the persistence provider. Please use Hibernate, a custom persistenceProvider, or remove the MANUAL flush mode setting.");
+ }
+
+ /**
+ * <p>
+ * Set the FlushMode the persistence contexts should use during rendering by
+ * calling {@link PersistenceContexts#changeFlushMode(FlushModeType, true)}. The
+ * actual changing of the flush mode is handled by the
+ * {@link PersistenceContexts} instance. The boolean argument should be true
+ * to indicate that this is a temporary change and that the old flush mode
+ * should be restored after render.
+ * </p>
+ * <p>
+ * Ideally, this should be MANUAL since changes should never flush to the
+ * database while in render response and the cost of a dirty check can be
+ * avoided. However, since the MANUAL mode is not officially part of the JPA
+ * specification, the default implementation will perform no operation.
+ * </p>
+ */
+ public void setRenderFlushMode() {
+ // no-op in default implementation
+ }
+
+ /**
+ * Does the persistence context have unflushed changes? If
+ * it does not, persistence context replication can be
+ * optimized.
+ *
+ * @return true to indicate that there are unflushed changes
+ */
+ public boolean isDirty(EntityManager entityManager)
+ {
+ return true; //best we can do!
+ }
+
+ /**
+ * Get the value of the entity identifier attribute.
+ *
+ * @param bean a managed entity instance
+ */
+ public Object getId(Object bean, EntityManager entityManager)
+ {
+ return Entity.forBean( bean ).getIdentifier(bean);
+ }
+
+ /**
+ * Get the name of the entity
+ *
+ * @param bean
+ * @param entityManager
+ *
+ * @throws IllegalArgumentException if the passed object is not an entity
+ */
+ public String getName(Object bean, EntityManager entityManager) throws IllegalArgumentException
+ {
+ return Entity.forBean( bean ).getName();
+ }
+
+ /**
+ * Get the value of the entity version attribute.
+ *
+ * @param bean a managed entity instance
+ */
+ public Object getVersion(Object bean, EntityManager entityManager)
+ {
+ return Entity.forBean( bean ).getVersion(bean);
+ }
+
+ public void checkVersion(Object bean, EntityManager entityManager, Object oldVersion, Object version)
+ {
+ boolean equal;
+ if (oldVersion instanceof Date)
+ {
+ equal = ( (Date) oldVersion ).getTime() == ( (Date) version ).getTime();
+ }
+ else
+ {
+ equal = oldVersion.equals(version);
+ }
+ if ( !equal )
+ {
+ throw new OptimisticLockException("Current database version number does not match passivated version number");
+ }
+ }
+ /**
+ * Enable a Filter. This is here just especially for Hibernate,
+ * since we well know that other products don't have such cool
+ * features.
+ */
+ public void enableFilter(Filter filter, EntityManager entityManager)
+ {
+ throw new UnsupportedOperationException("Use of filters requires Hibernate as the persistence provider. Please use Hibernate or remove the filters configuration.");
+ }
+
+ /**
+ * Register a Synchronization with the current transaction.
+ */
+ public boolean registerSynchronization(Synchronization sync, EntityManager entityManager)
+ {
+ return false; //best we can do!
+ }
+
+ /**
+ * Wrap the delegate before returning it to the application
+ */
+ public Object proxyDelegate(Object delegate)
+ {
+ return delegate;
+ }
+ /**
+ * Wrap the entityManager before returning it to the application
+ */
+ public EntityManager proxyEntityManager(EntityManager entityManager) {
+ return new EntityManagerProxy(entityManager);
+ }
+
+ /**
+ * Returns the class of an entity bean instance
+ *
+ * @param bean The entity bean instance
+ * @return The class of the entity bean
+ */
+ public Class getBeanClass(Object bean)
+ {
+ return Entity.forBean(bean).getBeanClass();
+ }
+
+ public Method getPostLoadMethod(Object bean, EntityManager entityManager)
+ {
+ return Entity.forBean(bean).getPostLoadMethod();
+ }
+
+ public Method getPrePersistMethod(Object bean, EntityManager entityManager)
+ {
+ return Entity.forBean(bean).getPrePersistMethod();
+ }
+
+ public Method getPreUpdateMethod(Object bean, EntityManager entityManager)
+ {
+ return Entity.forBean(bean).getPreUpdateMethod();
+ }
+
+ public Method getPreRemoveMethod(Object bean, EntityManager entityManager)
+ {
+ return Entity.forBean(bean).getPreRemoveMethod();
+ }
+}
Added: modules/trunk/persistence/src/main/java/org/jboss/seam/persistence/QueryParser.java
===================================================================
--- modules/trunk/persistence/src/main/java/org/jboss/seam/persistence/QueryParser.java (rev 0)
+++ modules/trunk/persistence/src/main/java/org/jboss/seam/persistence/QueryParser.java 2009-04-27 12:48:53 UTC (rev 10650)
@@ -0,0 +1,58 @@
+package org.jboss.seam.persistence;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.StringTokenizer;
+
+import org.jboss.seam.el.Expressions.ValueExpression;
+
+import org.jboss.seam.el.Expressions;
+
+public class QueryParser
+{
+ private List<ValueExpression> parameterValueBindings = new ArrayList<ValueExpression>();
+ private StringBuilder ejbqlBuilder;
+
+ public static String getParameterName(int loc)
+ {
+ return "el" + (loc+1);
+ }
+
+ public String getEjbql()
+ {
+ return ejbqlBuilder.toString();
+ }
+
+ public List<ValueExpression> getParameterValueBindings()
+ {
+ return parameterValueBindings;
+ }
+
+ public QueryParser(String ejbql)
+ {
+ this(ejbql, 0);
+ }
+
+ public QueryParser(String ejbql, int startingParameterNumber)
+ {
+ StringTokenizer tokens = new StringTokenizer(ejbql, "#}", true);
+ ejbqlBuilder = new StringBuilder(ejbql.length());
+ while (tokens.hasMoreTokens()) {
+ String token = tokens.nextToken();
+ if ("#".equals(token) && tokens.hasMoreTokens()) {
+ String expressionToken = tokens.nextToken();
+
+ if (!expressionToken.startsWith("{") || !tokens.hasMoreTokens()) {
+ ejbqlBuilder.append(token).append(expressionToken);
+ } else {
+ String expression = token + expressionToken + tokens.nextToken();
+ ejbqlBuilder.append(':').append( getParameterName( startingParameterNumber + parameterValueBindings.size() ) );
+ parameterValueBindings.add( Expressions.instance().createValueExpression(expression) );
+ }
+ } else {
+ ejbqlBuilder.append(token);
+ }
+ }
+ }
+
+}
Added: modules/trunk/persistence/src/main/java/org/jboss/seam/persistence/annotations/FlushModeType.java
===================================================================
--- modules/trunk/persistence/src/main/java/org/jboss/seam/persistence/annotations/FlushModeType.java (rev 0)
+++ modules/trunk/persistence/src/main/java/org/jboss/seam/persistence/annotations/FlushModeType.java 2009-04-27 12:48:53 UTC (rev 10650)
@@ -0,0 +1,42 @@
+package org.jboss.seam.persistence.annotations;
+
+/**
+ * A full set of flush modes, including MANUAL,
+ * which is a glaring missing feature of the JPA
+ * spec.
+ *
+ * @author Gavin King
+ *
+ */
+public enum FlushModeType
+{
+
+ /**
+ * Flushing never occurs automatically, all changes are queued
+ * until the application calls flush() explicitly.
+ */
+ MANUAL,
+
+ /**
+ * Flushing occurs automatically at commit time and when necessary
+ * before query executions.
+ */
+ AUTO,
+
+ /**
+ * Flushing occurs automatically at transaction commit time.
+ */
+ COMMIT;
+
+ /**
+ * Does this flush mode keep unflushed changes past a
+ * transaction commit?
+ *
+ * @return false for all flush modes except for MANUAL
+ */
+ public boolean dirtyBetweenTransactions()
+ {
+ return this==MANUAL;
+ }
+
+}
Added: modules/trunk/persistence/src/main/java/org/jboss/seam/persistence/util/Naming.java
===================================================================
--- modules/trunk/persistence/src/main/java/org/jboss/seam/persistence/util/Naming.java (rev 0)
+++ modules/trunk/persistence/src/main/java/org/jboss/seam/persistence/util/Naming.java 2009-04-27 12:48:53 UTC (rev 10650)
@@ -0,0 +1,75 @@
+package org.jboss.seam.persistence.util;
+
+import java.util.Hashtable;
+
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+
+import org.jboss.webbeans.log.LogProvider;
+import org.jboss.webbeans.log.Logging;
+
+public final class Naming
+{
+ private static final LogProvider log = Logging.getLogProvider(Naming.class);
+
+ private static Hashtable initialContextProperties;
+
+ private static InitialContext initialContext;
+
+ public static InitialContext getInitialContext(
+ Hashtable<String, String> props) throws NamingException
+ {
+ if (props == null)
+ {
+ throw new IllegalStateException(
+ "JNDI properties not initialized, Seam was not started correctly");
+ }
+
+ if (log.isDebugEnabled())
+ {
+ log.debug("JNDI InitialContext properties:" + props);
+ }
+
+ try
+ {
+ return props.size() == 0 ? new InitialContext() : new InitialContext(
+ props);
+ } catch (NamingException e)
+ {
+ log.debug("Could not obtain initial context", e);
+ throw e;
+ }
+
+ }
+
+ public static InitialContext getInitialContext() throws NamingException
+ {
+ if (initialContext == null)
+ initInitialContext();
+
+ return initialContext;
+ }
+
+ private static synchronized void initInitialContext() throws NamingException
+ {
+ if (initialContext == null)
+ {
+ initialContext = getInitialContext(initialContextProperties);
+ }
+ }
+
+ private Naming() {
+ }
+
+ public static void setInitialContextProperties(
+ Hashtable initialContextProperties)
+ {
+ Naming.initialContextProperties = initialContextProperties;
+ initialContext = null;
+ }
+
+ public static Hashtable getInitialContextProperties()
+ {
+ return initialContextProperties;
+ }
+}
Added: modules/trunk/persistence/src/main/java/org/jboss/seam/persistence/util/Reflections.java
===================================================================
--- modules/trunk/persistence/src/main/java/org/jboss/seam/persistence/util/Reflections.java (rev 0)
+++ modules/trunk/persistence/src/main/java/org/jboss/seam/persistence/util/Reflections.java 2009-04-27 12:48:53 UTC (rev 10650)
@@ -0,0 +1,401 @@
+package org.jboss.seam.persistence.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;
+ }
+
+ }
+
+}
Added: modules/trunk/persistence/src/main/java/org/jboss/seam/persistence/util/Strings.java
===================================================================
--- modules/trunk/persistence/src/main/java/org/jboss/seam/persistence/util/Strings.java (rev 0)
+++ modules/trunk/persistence/src/main/java/org/jboss/seam/persistence/util/Strings.java 2009-04-27 12:48:53 UTC (rev 10650)
@@ -0,0 +1,147 @@
+package org.jboss.seam.persistence.util;
+
+import java.beans.Introspector;
+import java.beans.PropertyDescriptor;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.StringTokenizer;
+
+/**
+ * @author <a href="mailto:theute@jboss.org">Thomas Heute</a>
+ */
+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;
+ if (string == null || (len = string.length()) == 0)
+ {
+ return true;
+ }
+
+ for (int i = 0; i < len; i++)
+ {
+ if ((Character.isWhitespace(string.charAt(i)) == false))
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public static String nullIfEmpty(String string)
+ {
+ return isEmpty(string) ? null : string;
+ }
+
+ public static String emptyIfNull(String string)
+ {
+ return string == null ? "" : string;
+ }
+
+ public static String toString(Object component)
+ {
+ try {
+ PropertyDescriptor[] props = Introspector.getBeanInfo( component.getClass() )
+ .getPropertyDescriptors();
+ StringBuilder builder = new StringBuilder();
+ for (PropertyDescriptor descriptor : props)
+ {
+ builder.append( descriptor.getName() )
+ .append('=')
+ .append( descriptor.getReadMethod().invoke(component) )
+ .append("; ");
+ }
+ return builder.toString();
+ }
+ catch (Exception e) {
+ return "";
+ }
+ }
+
+ public static String[] split(String strings, String delims)
+ {
+ if (strings==null)
+ {
+ return new String[0];
+ }
+ else
+ {
+ StringTokenizer tokens = new StringTokenizer(strings, delims);
+ String[] result = new String[ tokens.countTokens() ];
+ int i=0;
+ while ( tokens.hasMoreTokens() )
+ {
+ result[i++] = tokens.nextToken();
+ }
+ return result;
+ }
+ }
+
+ 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());
+ }
+
+ 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(String sep, Class... classes)
+ {
+ if (classes.length==0) return "";
+ StringBuilder builder = new StringBuilder();
+ for (Class clazz: classes)
+ {
+ builder.append(sep).append( clazz.getName() );
+ }
+ return builder.substring(sep.length());
+ }
+
+ public static String toString(InputStream in) throws IOException {
+ final StringBuilder out = new StringBuilder();
+ final byte[] b = new byte[4096];
+ for ( int n; (n = in.read(b)) != -1; )
+ {
+ out.append(new String(b, 0, n));
+ }
+ return out.toString();
+ }
+}
[View Less]
15 years, 10 months
Seam SVN: r10649 - modules/trunk/version-matrix.
by seam-commits@lists.jboss.org
Author: shane.bryzak(a)jboss.com
Date: 2009-04-27 05:02:36 -0400 (Mon, 27 Apr 2009)
New Revision: 10649
Modified:
modules/trunk/version-matrix/pom.xml
Log:
dependencies
Modified: modules/trunk/version-matrix/pom.xml
===================================================================
--- modules/trunk/version-matrix/pom.xml 2009-04-27 09:02:16 UTC (rev 10648)
+++ modules/trunk/version-matrix/pom.xml 2009-04-27 09:02:36 UTC (rev 10649)
@@ -184,11 +184,29 @@
</dependency>
…
[View More]
<dependency>
+ <groupId>org.drools</groupId>
+ <artifactId>drools-compiler</artifactId>
+ <version>4.0.4</version>
+ </dependency>
+
+ <dependency>
<groupId>org.jbpm</groupId>
<artifactId>jbpm-jpdl</artifactId>
<version>3.2.2</version>
</dependency>
+ <dependency>
+ <groupId>org.jboss.seam</groupId>
+ <artifactId>seam-el</artifactId>
+ <version>${seam.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.jboss.seam</groupId>
+ <artifactId>seam-bpm</artifactId>
+ <version>${seam.version}</version>
+ </dependency>
+
</dependencies>
</dependencyManagement>
[View Less]
15 years, 10 months
Seam SVN: r10648 - 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-27 05:02:16 -0400 (Mon, 27 Apr 2009)
New Revision: 10648
Modified:
modules/trunk/international/src/main/java/org/jboss/seam/international/LocaleConfig.java
Log:
remove static instance() method
Modified: modules/trunk/international/src/main/java/org/jboss/seam/international/LocaleConfig.java
===================================================================
--- modules/trunk/international/src/main/java/org/jboss/seam/international/LocaleConfig.…
[View More]java 2009-04-27 09:01:39 UTC (rev 10647)
+++ modules/trunk/international/src/main/java/org/jboss/seam/international/LocaleConfig.java 2009-04-27 09:02:16 UTC (rev 10648)
@@ -83,11 +83,6 @@
this.supportedLocales = supportedLocales;
}
- public static LocaleConfig instance()
- {
- return (LocaleConfig) Component.getInstance(LocaleConfig.class, ScopeType.APPLICATION);
- }
-
private java.util.Locale getLocaleFromString(String localeString)
{
if (localeString == null || localeString.length() < 2)
[View Less]
15 years, 10 months
Seam SVN: r10647 - in modules/trunk/drools: src/main/java/org/jboss/seam/drools and 1 other directories.
by seam-commits@lists.jboss.org
Author: shane.bryzak(a)jboss.com
Date: 2009-04-27 05:01:39 -0400 (Mon, 27 Apr 2009)
New Revision: 10647
Added:
modules/trunk/drools/src/main/java/org/jboss/seam/drools/util/
modules/trunk/drools/src/main/java/org/jboss/seam/drools/util/Resources.java
Modified:
modules/trunk/drools/pom.xml
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/…
[View More]java/org/jboss/seam/drools/RuleAgent.java
modules/trunk/drools/src/main/java/org/jboss/seam/drools/RuleBase.java
Log:
added util classes, add dependencies, component conversion
Modified: modules/trunk/drools/pom.xml
===================================================================
--- modules/trunk/drools/pom.xml 2009-04-27 09:00:42 UTC (rev 10646)
+++ modules/trunk/drools/pom.xml 2009-04-27 09:01:39 UTC (rev 10647)
@@ -24,10 +24,27 @@
<artifactId>webbeans-logging</artifactId>
</dependency>
<dependency>
+ <groupId>org.jboss.seam</groupId>
+ <artifactId>seam-bpm</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.jboss.seam</groupId>
+ <artifactId>seam-el</artifactId>
+ </dependency>
+ <dependency>
<groupId>org.drools</groupId>
<artifactId>drools-core</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.drools</groupId>
+ <artifactId>drools-compiler</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.jbpm</groupId>
+ <artifactId>jbpm-jpdl</artifactId>
+ </dependency>
+
</dependencies>
</project>
Modified: modules/trunk/drools/src/main/java/org/jboss/seam/drools/DroolsHandler.java
===================================================================
--- modules/trunk/drools/src/main/java/org/jboss/seam/drools/DroolsHandler.java 2009-04-27 09:00:42 UTC (rev 10646)
+++ modules/trunk/drools/src/main/java/org/jboss/seam/drools/DroolsHandler.java 2009-04-27 09:01:39 UTC (rev 10647)
@@ -27,7 +27,7 @@
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)
{
@@ -42,7 +42,6 @@
}
}
- //workingMemory.setGlobal( "contextInstance", executionContext.getContextInstance() );
workingMemory.insert(Actor.instance());
return workingMemory;
Modified: modules/trunk/drools/src/main/java/org/jboss/seam/drools/ManagedWorkingMemory.java
===================================================================
--- modules/trunk/drools/src/main/java/org/jboss/seam/drools/ManagedWorkingMemory.java 2009-04-27 09:00:42 UTC (rev 10646)
+++ modules/trunk/drools/src/main/java/org/jboss/seam/drools/ManagedWorkingMemory.java 2009-04-27 09:01:39 UTC (rev 10647)
@@ -2,17 +2,17 @@
import java.io.Serializable;
+import javax.annotation.PreDestroy;
+import javax.context.ConversationScoped;
+import javax.inject.Current;
+import javax.inject.Produces;
+import javax.inject.manager.Manager;
+
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;
+import org.jboss.seam.el.Expressions.ValueExpression;
/**
* A conversation-scoped Drools WorkingMemory for a named RuleBase
@@ -20,8 +20,7 @@
* @author Gavin King
*
*/
-(a)Scope(ScopeType.CONVERSATION)
-@BypassInterceptors
+@ConversationScoped
public class ManagedWorkingMemory implements Mutable, Serializable
{
private static final long serialVersionUID = -1746942080571374743L;
@@ -30,6 +29,8 @@
private StatefulSession statefulSession;
private ValueExpression<RuleBase> ruleBase;
+ @Current Manager manager;
+
public boolean clearDirty()
{
return true;
@@ -59,7 +60,7 @@
this.ruleBaseName = ruleBaseName;
}
- @Unwrap
+ @Produces
public StatefulSession getStatefulSession()
{
if (statefulSession==null)
@@ -79,8 +80,8 @@
}
else if (ruleBaseName!=null)
{
- //deprecated stuff
- ruleBase = (RuleBase) Component.getInstance(ruleBaseName, true);
+ //deprecated stuff
+ ruleBase = (RuleBase) manager.getInstanceByName(ruleBaseName);
}
else
{
@@ -99,7 +100,7 @@
return new SeamGlobalResolver(delegate);
}
- @Destroy
+ @PreDestroy
public void destroy()
{
statefulSession.dispose();
Modified: modules/trunk/drools/src/main/java/org/jboss/seam/drools/RuleAgent.java
===================================================================
--- modules/trunk/drools/src/main/java/org/jboss/seam/drools/RuleAgent.java 2009-04-27 09:00:42 UTC (rev 10646)
+++ modules/trunk/drools/src/main/java/org/jboss/seam/drools/RuleAgent.java 2009-04-27 09:01:39 UTC (rev 10647)
@@ -4,20 +4,18 @@
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;
+import javax.context.ApplicationScoped;
+import javax.inject.Initializer;
+import javax.inject.Produces;
+import org.jboss.seam.drools.util.Resources;
+import org.jboss.webbeans.log.LogProvider;
+import org.jboss.webbeans.log.Logging;
+
/**
* Manager component for a rule base loaded from a drools RulesAgent
*/
-(a)Scope(ScopeType.APPLICATION)
-@BypassInterceptors
+@ApplicationScoped
public class RuleAgent
{
private static final LogProvider log = Logging.getLogProvider(RuleAgent.class);
@@ -32,7 +30,7 @@
private String poll;
private String configName;
- @Create
+ @Initializer
public void createAgent() throws Exception
{
Properties properties = new Properties();
@@ -71,7 +69,7 @@
throws IOException
{
if (configurationFile != null) {
- InputStream inputStream = Resources.getResourceAsStream(configurationFile, null);
+ InputStream inputStream = Resources.getResourceAsStream(configurationFile);
if (inputStream != null) {
try {
properties.load(inputStream);
@@ -82,7 +80,7 @@
}
}
- @Unwrap
+ @Produces
public org.drools.RuleBase getRuleBase()
{
return agent.getRuleBase();
Modified: modules/trunk/drools/src/main/java/org/jboss/seam/drools/RuleBase.java
===================================================================
--- modules/trunk/drools/src/main/java/org/jboss/seam/drools/RuleBase.java 2009-04-27 09:00:42 UTC (rev 10646)
+++ modules/trunk/drools/src/main/java/org/jboss/seam/drools/RuleBase.java 2009-04-27 09:01:39 UTC (rev 10647)
@@ -4,19 +4,18 @@
import java.io.InputStreamReader;
import java.io.Reader;
+import javax.context.ApplicationScoped;
+import javax.inject.Initializer;
+import javax.inject.Produces;
+
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;
+import org.jboss.webbeans.log.LogProvider;
+import org.jboss.webbeans.log.Logging;
/**
* Manager component for a Drools RuleBase
@@ -24,8 +23,7 @@
* @author Gavin King
*
*/
-(a)Scope(ScopeType.APPLICATION)
-@BypassInterceptors
+@ApplicationScoped
public class RuleBase
{
private static final LogProvider log = Logging.getLogProvider(RuleBase.class);
@@ -34,7 +32,7 @@
private String dslFile;
private org.drools.RuleBase ruleBase;
- @Create
+ @Initializer
public void compileRuleBase() throws Exception
{
PackageBuilderConfiguration conf = new PackageBuilderConfiguration();
@@ -87,7 +85,7 @@
ruleBase.addPackage( builder.getPackage() );
}
- @Unwrap
+ @Produces
public org.drools.RuleBase getRuleBase()
{
return ruleBase;
Added: modules/trunk/drools/src/main/java/org/jboss/seam/drools/util/Resources.java
===================================================================
--- modules/trunk/drools/src/main/java/org/jboss/seam/drools/util/Resources.java (rev 0)
+++ modules/trunk/drools/src/main/java/org/jboss/seam/drools/util/Resources.java 2009-04-27 09:01:39 UTC (rev 10647)
@@ -0,0 +1,123 @@
+package org.jboss.seam.drools.util;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+
+import org.jboss.webbeans.log.LogProvider;
+import org.jboss.webbeans.log.Logging;
+
+public class Resources
+{
+ private static final LogProvider log = Logging.getLogProvider(Resources.class);
+
+ public static InputStream getResourceAsStream(String resource)
+ {
+ String stripped = resource.startsWith("/") ? resource.substring(1) : resource;
+
+ InputStream stream = getResourceAsStream(resource, stripped);
+ return stream;
+ }
+
+ public static URL getResource(String resource)
+ {
+ if (!resource.startsWith("/"))
+ {
+ resource = "/" + resource;
+ }
+
+ String stripped = resource.startsWith("/") ? resource.substring(1)
+ : resource;
+
+ URL url = getResource(resource, stripped);
+
+ return url;
+ }
+
+ static InputStream getResourceAsStream(String resource, String stripped)
+ {
+ ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
+ InputStream stream = null;
+ if (classLoader != null)
+ {
+ stream = classLoader.getResourceAsStream(stripped);
+ if (stream != null)
+ {
+ log.debug("Loaded resource from context classloader: " + stripped);
+ }
+ }
+
+ if (stream == null)
+ {
+ stream = Resources.class.getResourceAsStream(resource);
+ if (stream != null)
+ {
+ log.debug("Loaded resource from Seam classloader: " + resource);
+ }
+ }
+
+ if (stream == null)
+ {
+ stream = Resources.class.getClassLoader()
+ .getResourceAsStream(stripped);
+ if (stream != null)
+ {
+ log.debug("Loaded resource from Seam classloader: " + stripped);
+ }
+ }
+
+ return stream;
+ }
+
+ static URL getResource(String resource, String stripped)
+ {
+ ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
+ URL url = null;
+ if (classLoader != null)
+ {
+ url = classLoader.getResource(stripped);
+ if (url != null)
+ {
+ log.debug("Loaded resource from context classloader: " + url);
+ }
+ }
+
+ if (url == null)
+ {
+ url = Resources.class.getResource(resource);
+ if (url != null)
+ {
+ log.debug("Loaded resource from Seam classloader: " + url);
+ }
+ }
+
+ if (url == null)
+ {
+ url = Resources.class.getClassLoader().getResource(stripped);
+ if (url != null)
+ {
+ log.debug("Loaded resource from Seam classloader: " + url);
+ }
+ }
+
+ return url;
+ }
+
+ public static void closeStream(InputStream inputStream)
+ {
+ if (inputStream == null)
+ {
+ return;
+ }
+
+ try
+ {
+ inputStream.close();
+ }
+ catch (IOException e)
+ {
+ //
+ }
+ }
+
+}
\ No newline at end of file
[View Less]
15 years, 10 months
Seam SVN: r10646 - in modules/trunk/bpm/src/main/java/org/jboss/seam/bpm: util and 1 other directory.
by seam-commits@lists.jboss.org
Author: shane.bryzak(a)jboss.com
Date: 2009-04-27 05:00:42 -0400 (Mon, 27 Apr 2009)
New Revision: 10646
Added:
modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/util/
modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/util/FileDescriptor.java
modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/util/Resources.java
Removed:
modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/package-info.java
Modified:
modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/Actor.java
modules/trunk/…
[View More]bpm/src/main/java/org/jboss/seam/bpm/BusinessProcessInterceptor.java
modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/Jbpm.java
Log:
added util classes, some cleanup
Modified: modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/Actor.java
===================================================================
--- modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/Actor.java 2009-04-27 04:15:21 UTC (rev 10645)
+++ modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/Actor.java 2009-04-27 09:00:42 UTC (rev 10646)
@@ -86,14 +86,6 @@
{
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()
Modified: modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/BusinessProcessInterceptor.java
===================================================================
--- modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/BusinessProcessInterceptor.java 2009-04-27 04:15:21 UTC (rev 10645)
+++ modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/BusinessProcessInterceptor.java 2009-04-27 09:00:42 UTC (rev 10646)
@@ -21,8 +21,8 @@
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.webbeans.log.LogProvider;
+import org.jboss.webbeans.log.Logging;
import org.jboss.seam.util.Strings;
import org.jboss.seam.web.Parameters;
Modified: modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/Jbpm.java
===================================================================
--- modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/Jbpm.java 2009-04-27 04:15:21 UTC (rev 10645)
+++ modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/Jbpm.java 2009-04-27 09:00:42 UTC (rev 10646)
@@ -11,6 +11,7 @@
import java.util.Set;
import javax.annotation.Named;
+import javax.annotation.PreDestroy;
import javax.context.ApplicationScoped;
import javax.inject.Initializer;
import javax.naming.NamingException;
@@ -74,7 +75,7 @@
UserCodeInterceptorConfig.setUserCodeInterceptor( new SeamUserCodeInterceptor() );
}
- @Destroy
+ @PreDestroy
public void shutdown()
{
if (jbpmConfiguration!=null)
@@ -310,19 +311,6 @@
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;
Deleted: 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 2009-04-27 04:15:21 UTC (rev 10645)
+++ modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/package-info.java 2009-04-27 09:00:42 UTC (rev 10646)
@@ -1,17 +0,0 @@
-/**
- * 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;
Added: modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/util/FileDescriptor.java
===================================================================
--- modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/util/FileDescriptor.java (rev 0)
+++ modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/util/FileDescriptor.java 2009-04-27 09:00:42 UTC (rev 10646)
@@ -0,0 +1,74 @@
+package org.jboss.seam.bpm.util;
+
+import java.net.URL;
+
+import org.jboss.seam.contexts.ServletLifecycle;
+import org.jboss.seam.util.Resources;
+
+public class FileDescriptor
+{
+
+ private String name;
+ private URL url;
+
+ public FileDescriptor(String name, URL url)
+ {
+ this.name = name;
+ this.url = url;
+ }
+
+ public FileDescriptor(String name, ClassLoader classLoader)
+ {
+ this.name = name;
+ if (name == null)
+ {
+ throw new NullPointerException("Name cannot be null, loading from " + classLoader);
+ }
+ this.url = classLoader.getResource(name);
+ if (url == null)
+ {
+ this.url = Resources.getResource(name, ServletLifecycle.getServletContext());
+ }
+ if (this.url == null)
+ {
+ throw new NullPointerException("Cannot find URL from classLoader for " + name + ", loading from " + classLoader);
+ }
+ }
+
+ public String getName()
+ {
+ return name;
+ }
+
+ public URL getUrl()
+ {
+ return url;
+ }
+
+ @Override
+ public String toString()
+ {
+ return url.getPath();
+ }
+
+ @Override
+ public boolean equals(Object other)
+ {
+ if (other instanceof FileDescriptor)
+ {
+ FileDescriptor that = (FileDescriptor) other;
+ return this.getUrl().equals(that.getUrl());
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ @Override
+ public int hashCode()
+ {
+ return getUrl().hashCode();
+ }
+
+}
\ No newline at end of file
Added: modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/util/Resources.java
===================================================================
--- modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/util/Resources.java (rev 0)
+++ modules/trunk/bpm/src/main/java/org/jboss/seam/bpm/util/Resources.java 2009-04-27 09:00:42 UTC (rev 10646)
@@ -0,0 +1,177 @@
+package org.jboss.seam.bpm.util;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+
+import javax.servlet.ServletContext;
+
+import org.jboss.webbeans.log.LogProvider;
+import org.jboss.webbeans.log.Logging;
+
+public class Resources
+{
+ private static final LogProvider log = Logging.getLogProvider(Resources.class);
+
+ public static InputStream getResourceAsStream(String resource, ServletContext servletContext)
+ {
+ String stripped = resource.startsWith("/") ?
+ resource.substring(1) : resource;
+
+ InputStream stream = null;
+
+ if (servletContext!=null) {
+ try {
+ stream = servletContext.getResourceAsStream(resource);
+ if (stream!=null) {
+ log.debug("Loaded resource from servlet context: " + resource);
+ }
+ } catch (Exception e) {
+ //
+ }
+ }
+
+ if (stream==null) {
+ stream = getResourceAsStream(resource, stripped);
+ }
+
+ return stream;
+ }
+
+ public static URL getResource(String resource, ServletContext servletContext)
+ {
+ if (!resource.startsWith("/"))
+ {
+ resource = "/" + resource;
+ }
+
+ String stripped = resource.startsWith("/") ?
+ resource.substring(1) : resource;
+
+ URL url = null;
+
+ if (servletContext!=null)
+ {
+ try {
+ url = servletContext.getResource(resource);
+ log.debug("Loaded resource from servlet context: " + url);
+ } catch (Exception e) {
+ //
+ }
+ }
+
+ if (url==null)
+ {
+ url = getResource(resource, stripped);
+ }
+
+ return url;
+ }
+
+ static InputStream getResourceAsStream(String resource, String stripped)
+ {
+ ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
+ InputStream stream = null;
+ if (classLoader!=null) {
+ stream = classLoader.getResourceAsStream(stripped);
+ if (stream !=null) {
+ log.debug("Loaded resource from context classloader: " + stripped);
+ }
+ }
+
+ if (stream == null) {
+ stream = Seam.class.getResourceAsStream(resource);
+ if (stream !=null) {
+ log.debug("Loaded resource from Seam classloader: " + resource);
+ }
+ }
+
+ if (stream == null) {
+ stream = Seam.class.getClassLoader().getResourceAsStream(stripped);
+ if (stream!=null) {
+ log.debug("Loaded resource from Seam classloader: " + stripped);
+ }
+ }
+
+ return stream;
+ }
+
+ static URL getResource(String resource, String stripped)
+ {
+ ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
+ URL url = null;
+ if (classLoader!=null) {
+ url = classLoader.getResource(stripped);
+ if (url!=null) {
+ log.debug("Loaded resource from context classloader: " + url);
+ }
+ }
+
+ if (url == null) {
+ url = Seam.class.getResource(resource);
+ if (url!=null) {
+ log.debug("Loaded resource from Seam classloader: " + url);
+ }
+ }
+
+ if (url == null) {
+ url = Seam.class.getClassLoader().getResource(stripped);
+ if (url!=null) {
+ log.debug("Loaded resource from Seam classloader: " + url);
+ }
+ }
+
+ return url;
+ }
+
+ public static void closeStream(InputStream inputStream) {
+ if (inputStream == null) {
+ return;
+ }
+
+ try {
+ inputStream.close();
+ } catch (IOException e) {
+ //
+ }
+ }
+
+ public static File getRealFile(ServletContext servletContext, String path)
+ {
+ String realPath = servletContext.getRealPath(path);
+ if (realPath==null) //WebLogic!
+ {
+ try
+ {
+ URL resourcePath = servletContext.getResource(path);
+ if ((resourcePath != null) && (resourcePath.getProtocol().equals("file")))
+ {
+ realPath = resourcePath.getPath();
+ }
+ else
+ {
+ log.warn("Unable to determine real path from servlet context for \"" + path + "\" path does not exist.");
+ }
+ }
+ catch (MalformedURLException e)
+ {
+ log.warn("Unable to determine real path from servlet context for : " + path);
+ log.debug("Caused by MalformedURLException", e);
+ }
+
+ }
+
+ if (realPath != null)
+ {
+ File file = new File(realPath);
+ if (file.exists())
+ {
+ return file;
+ }
+ }
+ return null;
+ }
+
+}
\ No newline at end of file
[View Less]
15 years, 10 months