[seam-commits] Seam SVN: r10859 - in modules/trunk/faces/src: main/java/org/jboss/seam/faces/lifecycle and 2 other directories.

seam-commits at lists.jboss.org seam-commits at lists.jboss.org
Mon May 11 16:14:35 EDT 2009


Author: dan.j.allen
Date: 2009-05-11 16:14:34 -0400 (Mon, 11 May 2009)
New Revision: 10859

Added:
   modules/trunk/faces/src/main/java/org/jboss/seam/faces/lifecycle/AfterPhase.java
   modules/trunk/faces/src/main/java/org/jboss/seam/faces/lifecycle/BeforePhase.java
   modules/trunk/faces/src/main/java/org/jboss/seam/faces/lifecycle/ManagedSeamPhaseListener.java
   modules/trunk/faces/src/main/java/org/jboss/seam/faces/lifecycle/SeamPhaseListener.java
   modules/trunk/faces/src/main/java/org/jboss/seam/faces/lifecycle/Transaction.java
Removed:
   modules/trunk/faces/src/main/java/org/jboss/seam/faces/application/JcdiManager.java
Modified:
   modules/trunk/faces/src/main/java/org/jboss/seam/faces/application/SeamViewHandler.java
   modules/trunk/faces/src/main/java/org/jboss/seam/faces/lifecycle/TransferStatusMessagesListener.java
   modules/trunk/faces/src/main/resources/META-INF/faces-config.xml
   modules/trunk/faces/src/test/java/org/jboss/seam/faces/FacesStatusMessagesTest.java
Log:
use Manager bridge to get JCDI Manager
add SeamPhaseListener to raise before/after phase events and wrap transaction around request (not complete)
temporary Transaction bean until transaction module is ready
update faces descriptor


Deleted: modules/trunk/faces/src/main/java/org/jboss/seam/faces/application/JcdiManager.java
===================================================================
--- modules/trunk/faces/src/main/java/org/jboss/seam/faces/application/JcdiManager.java	2009-05-11 20:12:16 UTC (rev 10858)
+++ modules/trunk/faces/src/main/java/org/jboss/seam/faces/application/JcdiManager.java	2009-05-11 20:14:34 UTC (rev 10859)
@@ -1,60 +0,0 @@
-package org.jboss.seam.faces.application;
-
-import javax.faces.context.ExternalContext;
-import javax.faces.context.FacesContext;
-import javax.inject.manager.Manager;
-import javax.naming.InitialContext;
-import javax.naming.NamingException;
-
-/**
- * <strong>JcdiManager</strong> retrieves the JCDI Manager from JNDI and caches the
- * result in an application-scoped attribute.
- *
- * @author Dan Allen
- */
-public class JcdiManager
-{
-   public static final String JCDI_MANAGER_JNDI_NAME = "java:app/Manager";
-
-   public static final String JCDI_MANAGER_ALT_JNDI_NAME = "java:comp/env/app/Manager";
-
-   private static final String JCDI_MANAGER_CACHE_KEY = JcdiManager.class.getName() + ".CACHE_KEY";
-
-   public static Manager getCurrentManager()
-   {
-      Manager currentManager = null;
-      ExternalContext externalContext = FacesContext.getCurrentInstance().getExternalContext();
-      if (externalContext != null)
-      {
-         currentManager = (Manager) externalContext.getApplicationMap().get(JCDI_MANAGER_CACHE_KEY);
-      }
-
-      if (currentManager != null)
-      {
-         return currentManager;
-      }
-
-      try
-      {
-         InitialContext initialContext = new InitialContext();
-         try
-         {
-            currentManager = (Manager) initialContext.lookup(JCDI_MANAGER_JNDI_NAME);
-         }
-         catch (NamingException e)
-         {
-            currentManager = (Manager) initialContext.lookup(JCDI_MANAGER_ALT_JNDI_NAME);
-         }
-      }
-      catch (NamingException e)
-      {
-      }
-
-      if (currentManager != null && externalContext != null)
-      {
-         externalContext.getApplicationMap().put(JCDI_MANAGER_CACHE_KEY, currentManager);
-      }
-
-      return currentManager;
-   }
-}

Modified: modules/trunk/faces/src/main/java/org/jboss/seam/faces/application/SeamViewHandler.java
===================================================================
--- modules/trunk/faces/src/main/java/org/jboss/seam/faces/application/SeamViewHandler.java	2009-05-11 20:12:16 UTC (rev 10858)
+++ modules/trunk/faces/src/main/java/org/jboss/seam/faces/application/SeamViewHandler.java	2009-05-11 20:14:34 UTC (rev 10859)
@@ -39,12 +39,16 @@
    @Override
    public String getRedirectURL(FacesContext context, String viewId, Map<String, List<String>> parameters, boolean includeViewParams)
    {
-      // QUESTION hmmm, we have to convert to faces messages now to leverage JSF's flash feature...I suppose that is okay
-      new TransferStatusMessagesListener().execute();
-      // should I move this next step into TransferStatusMessagesListener?
-      if (context.getMessages().hasNext())
+      // TODO temporary check if session has been killed be Web Beans throws an exception trying to access a session-scoped bean
+      if (context.getExternalContext().getSession(false) != null)
       {
-         context.getExternalContext().getFlash().setKeepMessages(true);
+         // QUESTION hmmm, we have to convert to faces messages now to leverage JSF's flash feature...I suppose that is okay
+         new TransferStatusMessagesListener().execute();
+         // should I move this next step into TransferStatusMessagesListener?
+         if (context.getMessages().hasNext())
+         {
+            context.getExternalContext().getFlash().setKeepMessages(true);
+         }
       }
       
       return super.getRedirectURL(context, viewId, parameters, includeViewParams);

Added: modules/trunk/faces/src/main/java/org/jboss/seam/faces/lifecycle/AfterPhase.java
===================================================================
--- modules/trunk/faces/src/main/java/org/jboss/seam/faces/lifecycle/AfterPhase.java	                        (rev 0)
+++ modules/trunk/faces/src/main/java/org/jboss/seam/faces/lifecycle/AfterPhase.java	2009-05-11 20:14:34 UTC (rev 10859)
@@ -0,0 +1,27 @@
+package org.jboss.seam.faces.lifecycle;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.PARAMETER;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import javax.inject.BindingType;
+
+/**
+ * Binding type that identifies a PhaseEvent which is raised
+ * after a JSF life-cycle phase.
+ * 
+ * @author Dan Allen
+ */
+ at Target( { PARAMETER, FIELD })
+ at Retention(RUNTIME)
+ at Documented
+ at BindingType
+ at Inherited
+public @interface AfterPhase
+{
+}

Added: modules/trunk/faces/src/main/java/org/jboss/seam/faces/lifecycle/BeforePhase.java
===================================================================
--- modules/trunk/faces/src/main/java/org/jboss/seam/faces/lifecycle/BeforePhase.java	                        (rev 0)
+++ modules/trunk/faces/src/main/java/org/jboss/seam/faces/lifecycle/BeforePhase.java	2009-05-11 20:14:34 UTC (rev 10859)
@@ -0,0 +1,27 @@
+package org.jboss.seam.faces.lifecycle;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.PARAMETER;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import javax.inject.BindingType;
+
+/**
+ * Binding type that identifies a PhaseEvent which is
+ * raised before a JSF life-cycle phase.
+ * 
+ * @author Dan Allen
+ */
+ at Target( { PARAMETER, FIELD })
+ at Retention(RUNTIME)
+ at Documented
+ at BindingType
+ at Inherited
+public @interface BeforePhase
+{
+}

Added: modules/trunk/faces/src/main/java/org/jboss/seam/faces/lifecycle/ManagedSeamPhaseListener.java
===================================================================
--- modules/trunk/faces/src/main/java/org/jboss/seam/faces/lifecycle/ManagedSeamPhaseListener.java	                        (rev 0)
+++ modules/trunk/faces/src/main/java/org/jboss/seam/faces/lifecycle/ManagedSeamPhaseListener.java	2009-05-11 20:14:34 UTC (rev 10859)
@@ -0,0 +1,110 @@
+package org.jboss.seam.faces.lifecycle;
+
+import javax.context.ApplicationScoped;
+import javax.faces.event.PhaseEvent;
+import javax.faces.event.PhaseId;
+import javax.inject.AnnotationLiteral;
+import javax.inject.Initializer;
+import javax.inject.manager.Manager;
+import javax.transaction.Status;
+import javax.transaction.UserTransaction;
+
+/**
+ * A class that is invoked by the JCDI Manager handles setup and cleanup tasks
+ * which are specific to Seam's JSF support. This listener does not tasks which
+ * are relevant for any servlet request. Specifically, it raises events so that
+ * other beans managed by JCDI can tie into the JSF phases and it handles
+ * transaction management a key points in the JSF life cycle.
+ * 
+ * @author Dan Allen
+ */
+public
+ at ApplicationScoped
+class ManagedSeamPhaseListener
+{
+   private Manager manager;
+   
+   private UserTransaction transaction;
+   
+   public ManagedSeamPhaseListener() {}
+   
+   public @Initializer ManagedSeamPhaseListener(Manager manager, UserTransaction transaction)
+   {
+      this.manager = manager;
+      this.transaction = transaction;
+   }
+   
+   public void beforePhase(PhaseEvent event)
+   {
+      handleTransactionBeforePhase(event);
+      raiseEventBeforePhase(event);
+   }
+   
+   public void afterPhase(PhaseEvent event)
+   {
+      handleTransactionAfterPhase(event);
+      raiseEventAfterPhase(event);
+   }
+   
+   protected void handleTransactionBeforePhase(PhaseEvent event)
+   {
+      if (event.getPhaseId() == PhaseId.RENDER_RESPONSE)
+      {
+         beginTransaction(event.getPhaseId());
+      }
+   }
+   
+   protected void handleTransactionAfterPhase(PhaseEvent event)
+   {
+      if (event.getPhaseId() == PhaseId.RENDER_RESPONSE)
+      {
+         commitOrRollbackTransaction(event.getPhaseId());
+      }
+   }
+   
+   protected void beginTransaction(PhaseId phase)
+   {
+      try
+      {
+         int status = transaction.getStatus();
+         if (status != Status.STATUS_ACTIVE && status != Status.STATUS_MARKED_ROLLBACK)
+         {
+            transaction.begin();
+         }
+      }
+      catch (Exception e)
+      {
+         throw new RuntimeException("Could not begin transaction", e);
+      }
+   }
+   
+   protected void commitOrRollbackTransaction(PhaseId phase)
+   {
+      try
+      {
+         int status = transaction.getStatus();
+         if (status == Status.STATUS_ACTIVE)
+         {
+            transaction.commit();
+         }
+         else if (status == Status.STATUS_MARKED_ROLLBACK)
+         {
+            transaction.rollback();
+         }
+      }
+      catch (Exception e)
+      {
+         throw new RuntimeException("Could not commit or rollback transaction", e);
+      }
+   }
+   
+   protected void raiseEventBeforePhase(PhaseEvent event)
+   {
+      manager.fireEvent(event, new AnnotationLiteral<BeforePhase>() {});
+   }
+   
+   protected void raiseEventAfterPhase(PhaseEvent event)
+   {
+      manager.fireEvent(event, new AnnotationLiteral<AfterPhase>() {});
+   }
+}

Added: modules/trunk/faces/src/main/java/org/jboss/seam/faces/lifecycle/SeamPhaseListener.java
===================================================================
--- modules/trunk/faces/src/main/java/org/jboss/seam/faces/lifecycle/SeamPhaseListener.java	                        (rev 0)
+++ modules/trunk/faces/src/main/java/org/jboss/seam/faces/lifecycle/SeamPhaseListener.java	2009-05-11 20:14:34 UTC (rev 10859)
@@ -0,0 +1,38 @@
+package org.jboss.seam.faces.lifecycle;
+
+import javax.faces.event.PhaseEvent;
+import javax.faces.event.PhaseId;
+import javax.faces.event.PhaseListener;
+
+import org.jboss.seam.bridge.ManagerBridge;
+
+/**
+ * A JSF <strong>PhaseListener</strong> implementation that hooks Seam into the
+ * JSF life cycle. This class observes all JSF phases and merely delegates to
+ * an application-scope bean managed by JCDI.
+ * 
+ * @author Dan Allen
+ */
+public class SeamPhaseListener implements PhaseListener
+{
+   public void beforePhase(PhaseEvent event)
+   {
+      getDelegate().beforePhase(event);
+   }
+   
+   public void afterPhase(PhaseEvent event)
+   {
+      getDelegate().afterPhase(event);
+   }
+   
+   public PhaseId getPhaseId()
+   {
+      return PhaseId.ANY_PHASE;
+   }
+
+   protected ManagedSeamPhaseListener getDelegate()
+   {
+      return ManagerBridge.getProvider().getCurrentManager().getInstanceByType(ManagedSeamPhaseListener.class);
+   }
+
+}

Added: modules/trunk/faces/src/main/java/org/jboss/seam/faces/lifecycle/Transaction.java
===================================================================
--- modules/trunk/faces/src/main/java/org/jboss/seam/faces/lifecycle/Transaction.java	                        (rev 0)
+++ modules/trunk/faces/src/main/java/org/jboss/seam/faces/lifecycle/Transaction.java	2009-05-11 20:14:34 UTC (rev 10859)
@@ -0,0 +1,47 @@
+package org.jboss.seam.faces.lifecycle;
+
+import javax.context.RequestScoped;
+import javax.inject.Produces;
+import javax.naming.InitialContext;
+import javax.naming.NameNotFoundException;
+import javax.naming.NamingException;
+import javax.transaction.UserTransaction;
+
+// TEMPORARY!!
+public class Transaction
+{
+   private static final String USER_TRANSACTION_JNDI_NAME = "java:comp/UserTransaction";
+   
+   // Embedded JBoss has no java:comp/UserTransaction
+   private static final String ALTERNATE_USER_TRANSACTION_JNDI_NAME = "UserTransaction";
+   
+   public
+   @Produces
+   @RequestScoped
+   UserTransaction getUserTransaction() throws NamingException
+   {
+      InitialContext context = new InitialContext();
+      try
+      {
+         try
+         {
+            return (UserTransaction) context.lookup(USER_TRANSACTION_JNDI_NAME);
+         }
+         catch (NameNotFoundException nnfe)
+         {
+            try
+            {
+               return (UserTransaction) context.lookup(ALTERNATE_USER_TRANSACTION_JNDI_NAME);
+            }
+            catch (NamingException e)
+            {
+               throw nnfe;
+            }
+         }
+      }
+      catch (NamingException e)
+      {
+         throw e;
+      }
+   }
+}

Modified: modules/trunk/faces/src/main/java/org/jboss/seam/faces/lifecycle/TransferStatusMessagesListener.java
===================================================================
--- modules/trunk/faces/src/main/java/org/jboss/seam/faces/lifecycle/TransferStatusMessagesListener.java	2009-05-11 20:12:16 UTC (rev 10858)
+++ modules/trunk/faces/src/main/java/org/jboss/seam/faces/lifecycle/TransferStatusMessagesListener.java	2009-05-11 20:14:34 UTC (rev 10859)
@@ -2,7 +2,10 @@
 
 import javax.faces.event.SystemEvent;
 import javax.faces.event.SystemEventListener;
-import org.jboss.seam.faces.application.JcdiManager;
+import javax.inject.UnsatisfiedDependencyException;
+import javax.inject.manager.Manager;
+
+import org.jboss.seam.bridge.ManagerBridge;
 import org.jboss.seam.international.StatusMessages;
 import org.jboss.webbeans.log.LogProvider;
 import org.jboss.webbeans.log.Logging;
@@ -31,15 +34,19 @@
 
    public void execute()
    {
-      StatusMessages statusMessages = JcdiManager.getCurrentManager().getInstanceByType(StatusMessages.class);
-
-      if (statusMessages != null)
+      try
       {
-         statusMessages.onBeforeRender();
+         Manager manager = ManagerBridge.getProvider().getRootManager();
+         // tests
+         if (manager != null)
+         {
+            manager.getInstanceByType(StatusMessages.class).onBeforeRender();
+         }
       }
-      else
+      catch (UnsatisfiedDependencyException e)
       {
-         log.warn("Could not locate StatusMessages bean. Status messages will not be transfered to FacesContext.");
+         log.warn("Could not locate the StatusMessages bean. Status messages will not be transfered to the FacesContext.");
       }
+
    }
 }

Modified: modules/trunk/faces/src/main/resources/META-INF/faces-config.xml
===================================================================
--- modules/trunk/faces/src/main/resources/META-INF/faces-config.xml	2009-05-11 20:12:16 UTC (rev 10858)
+++ modules/trunk/faces/src/main/resources/META-INF/faces-config.xml	2009-05-11 20:14:34 UTC (rev 10859)
@@ -3,10 +3,10 @@
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd"
    version="2.0"
-   id="seam-faces">
+   id="seam3">
 
    <ordering>
-      <after>web-beans</after>
+      <after>webbeans</after>
    </ordering>
 
    <factory>
@@ -23,4 +23,10 @@
       </system-event-listener>
    </application>
 
+   <lifecycle>
+      <!-- Not ready for this yet, it is just testing
+      <phase-listener>org.jboss.seam.faces.lifecycle.SeamPhaseListener</phase-listener>
+      -->
+   </lifecycle>
+
 </faces-config>

Modified: modules/trunk/faces/src/test/java/org/jboss/seam/faces/FacesStatusMessagesTest.java
===================================================================
--- modules/trunk/faces/src/test/java/org/jboss/seam/faces/FacesStatusMessagesTest.java	2009-05-11 20:12:16 UTC (rev 10858)
+++ modules/trunk/faces/src/test/java/org/jboss/seam/faces/FacesStatusMessagesTest.java	2009-05-11 20:14:34 UTC (rev 10859)
@@ -15,6 +15,7 @@
 import org.jboss.seam.international.LocaleProducer;
 import org.jboss.seam.international.StatusMessage;
 import org.jboss.seam.international.StatusMessages;
+import org.jboss.seam.mock.faces.MockApplication;
 import org.jboss.seam.mock.faces.MockFacesContext;
 import org.jboss.testharness.impl.packaging.Artifact;
 import org.jboss.testharness.impl.packaging.Classes;
@@ -127,7 +128,7 @@
 
    private void installMockFacesContext()
    {
-      new MockFacesContext(true).setCurrent();
+      new MockFacesContext(new MockApplication(), true).setCurrent();
    }
 
    private void activateConversationContext()




More information about the seam-commits mailing list