[seam-commits] Seam SVN: r12877 - in modules/faces/trunk/impl/src/main: java/org/jboss/seam/faces/event and 3 other directories.

seam-commits at lists.jboss.org seam-commits at lists.jboss.org
Thu May 27 21:34:15 EDT 2010


Author: lincolnthree
Date: 2010-05-27 21:34:14 -0400 (Thu, 27 May 2010)
New Revision: 12877

Added:
   modules/faces/trunk/impl/src/main/java/org/jboss/seam/faces/context/FlashScopedContext.java
Removed:
   modules/faces/trunk/impl/src/main/java/org/jboss/seam/faces/context/FlashScopedContext.java
Modified:
   modules/faces/trunk/impl/src/main/java/org/jboss/seam/faces/event/DelegatingPhaseListener.java
   modules/faces/trunk/impl/src/main/java/org/jboss/seam/faces/status/MessagesAdapter.java
   modules/faces/trunk/impl/src/main/java/org/jboss/seam/faces/util/BeanManagerUtils.java
   modules/faces/trunk/impl/src/main/resources/META-INF/faces-config.xml
Log:
First stab at real FlashScope implementation.

Deleted: modules/faces/trunk/impl/src/main/java/org/jboss/seam/faces/context/FlashScopedContext.java
===================================================================
--- modules/faces/trunk/impl/src/main/java/org/jboss/seam/faces/context/FlashScopedContext.java	2010-05-28 01:33:48 UTC (rev 12876)
+++ modules/faces/trunk/impl/src/main/java/org/jboss/seam/faces/context/FlashScopedContext.java	2010-05-28 01:34:14 UTC (rev 12877)
@@ -1,232 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2010, Red Hat, Inc., and individual contributors
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.jboss.seam.faces.context;
-
-import java.io.IOException;
-import java.lang.annotation.Annotation;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.concurrent.ConcurrentHashMap;
-
-import javax.enterprise.context.ContextNotActiveException;
-import javax.enterprise.context.spi.Context;
-import javax.enterprise.context.spi.Contextual;
-import javax.enterprise.context.spi.CreationalContext;
-import javax.enterprise.event.Observes;
-import javax.faces.bean.FlashScoped;
-import javax.faces.context.ExternalContext;
-import javax.faces.context.FacesContext;
-import javax.faces.context.Flash;
-import javax.faces.event.PhaseEvent;
-import javax.faces.event.PhaseId;
-import javax.faces.event.PhaseListener;
-import javax.faces.event.PreRenderViewEvent;
-import javax.inject.Inject;
-import javax.servlet.ServletRequest;
-
-/**
- * This class provides the lifecycle for the new JSF 2 Flash Context
- * 
- * @author <a href="mailto:lincolnbaxter at gmail.com">Lincoln Baxter, III</a>
- */
-public class FlashScopedContext implements Context, PhaseListener
-{
-   private static final long serialVersionUID = -1580689204988513798L;
-
-   final static String COMPONENT_MAP_NAME = "org.jboss.seam.faces.flash.componentInstanceMap";
-   final static String CREATIONAL_MAP_NAME = "org.jboss.seam.faces.flash.creationalInstanceMap";
-
-   @SuppressWarnings("unchecked")
-   public <T> T get(final Contextual<T> component)
-   {
-      assertActive();
-      return (T) getComponentInstanceMap().get(component);
-   }
-
-   @SuppressWarnings("unchecked")
-   public <T> T get(final Contextual<T> component, final CreationalContext<T> creationalContext)
-   {
-      assertActive();
-
-      T instance = get(component);
-
-      if (instance == null)
-      {
-         Map<Contextual<?>, CreationalContext<?>> creationalContextMap = getCreationalContextMap();
-         Map<Contextual<?>, Object> componentInstanceMap = getComponentInstanceMap();
-
-         synchronized (componentInstanceMap)
-         {
-            instance = (T) componentInstanceMap.get(component);
-            if (instance == null)
-            {
-               instance = component.create(creationalContext);
-
-               if (instance != null)
-               {
-                  componentInstanceMap.put(component, instance);
-                  creationalContextMap.put(component, creationalContext);
-               }
-            }
-         }
-      }
-
-      return instance;
-   }
-
-   public Class<? extends Annotation> getScope()
-   {
-      return FlashScoped.class;
-   }
-
-   public boolean isActive()
-   {
-      return getFlash() != null;
-   }
-
-   @Inject
-   FacesContext context;
-
-   /**
-    * This method ensures that the contextual maps are populated before
-    * rendering occurs (thus, before any contextual objects are created during
-    * the Render Response phase.)
-    * <p>
-    * This method also ensures that the maps are available after Flash.clear()
-    * is called immediately before Render Response is complete.
-    * 
-    * @param event
-    * @throws IOException
-    */
-   public void retrieveContextualMaps(@Observes final PreRenderViewEvent event) throws IOException
-   {
-      ExternalContext externalContext = context.getExternalContext();
-      Object temp = externalContext.getRequest();
-      if (temp instanceof ServletRequest)
-      {
-         Object componentMap = getComponentInstanceMap();
-         Object creationalMap = getCreationalContextMap();
-
-         ServletRequest request = (ServletRequest) temp;
-         request.setAttribute(FlashScopedContext.COMPONENT_MAP_NAME, componentMap);
-         request.setAttribute(FlashScopedContext.CREATIONAL_MAP_NAME, creationalMap);
-      }
-   }
-
-   public void beforePhase(final PhaseEvent event)
-   {
-   }
-
-   /**
-    * This method saves the current scope metadata into the Flash after Restore
-    * View, then destroys the metadata after Render Response. Since the current
-    * request's execution Flash is swapped with the last requests execution
-    * flash for the Render Response phase, the last request's execution flash is
-    * actually the one that gets cleaned up.
-    * <p>
-    * Preserve this request's new metadata. Do the object cleanup using our
-    * saved references from last request.
-    */
-   @SuppressWarnings("unchecked")
-   public void afterPhase(final PhaseEvent event)
-   {
-      if (PhaseId.RENDER_RESPONSE.equals(event.getPhaseId()))
-      {
-         ExternalContext externalContext = event.getFacesContext().getExternalContext();
-         Object temp = externalContext.getRequest();
-         if (temp instanceof ServletRequest)
-         {
-            ServletRequest request = (ServletRequest) temp;
-
-            Map<Contextual<?>, Object> componentInstanceMap = (Map<Contextual<?>, Object>) request.getAttribute(FlashScopedContext.COMPONENT_MAP_NAME);
-            Map<Contextual<?>, CreationalContext<?>> creationalContextMap = (Map<Contextual<?>, CreationalContext<?>>) request.getAttribute(FlashScopedContext.CREATIONAL_MAP_NAME);
-
-            if ((componentInstanceMap != null) && (creationalContextMap != null))
-            {
-               for (Entry<Contextual<?>, Object> componentEntry : componentInstanceMap.entrySet())
-               {
-                  Contextual contextual = componentEntry.getKey();
-                  Object instance = componentEntry.getValue();
-                  CreationalContext creational = creationalContextMap.get(contextual);
-
-                  contextual.destroy(instance, creational);
-               }
-            }
-         }
-      }
-   }
-
-   public PhaseId getPhaseId()
-   {
-      return PhaseId.ANY_PHASE;
-   }
-
-   private Flash getFlash()
-   {
-      FacesContext currentInstance = FacesContext.getCurrentInstance();
-      if (currentInstance != null)
-      {
-         ExternalContext externalContext = currentInstance.getExternalContext();
-         return externalContext.getFlash();
-      }
-      return null;
-   }
-
-   private void assertActive()
-   {
-      if (!isActive())
-      {
-         throw new ContextNotActiveException("Seam context with scope annotation @FlashScoped is not active with respect to the current thread");
-      }
-   }
-
-   @SuppressWarnings("unchecked")
-   private Map<Contextual<?>, Object> getComponentInstanceMap()
-   {
-      Flash flash = getFlash();
-      ConcurrentHashMap<Contextual<?>, Object> map = (ConcurrentHashMap<Contextual<?>, Object>) flash.get(COMPONENT_MAP_NAME);
-
-      if (map == null)
-      {
-         map = new ConcurrentHashMap<Contextual<?>, Object>();
-         flash.put(COMPONENT_MAP_NAME, map);
-      }
-
-      return map;
-   }
-
-   @SuppressWarnings("unchecked")
-   private Map<Contextual<?>, CreationalContext<?>> getCreationalContextMap()
-   {
-      Flash flash = getFlash();
-      Map<Contextual<?>, CreationalContext<?>> map = (ConcurrentHashMap<Contextual<?>, CreationalContext<?>>) flash.get(CREATIONAL_MAP_NAME);
-
-      if (map == null)
-      {
-         map = new ConcurrentHashMap<Contextual<?>, CreationalContext<?>>();
-         flash.put(CREATIONAL_MAP_NAME, map);
-      }
-
-      return map;
-   }
-
-}

Added: modules/faces/trunk/impl/src/main/java/org/jboss/seam/faces/context/FlashScopedContext.java
===================================================================
--- modules/faces/trunk/impl/src/main/java/org/jboss/seam/faces/context/FlashScopedContext.java	                        (rev 0)
+++ modules/faces/trunk/impl/src/main/java/org/jboss/seam/faces/context/FlashScopedContext.java	2010-05-28 01:34:14 UTC (rev 12877)
@@ -0,0 +1,275 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc., and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.seam.faces.context;
+
+import java.io.Serializable;
+import java.lang.annotation.Annotation;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.concurrent.ConcurrentHashMap;
+
+import javax.enterprise.context.ContextNotActiveException;
+import javax.enterprise.context.RequestScoped;
+import javax.enterprise.context.spi.Context;
+import javax.enterprise.context.spi.Contextual;
+import javax.enterprise.context.spi.CreationalContext;
+import javax.enterprise.inject.Produces;
+import javax.enterprise.inject.spi.BeanManager;
+import javax.faces.bean.FlashScoped;
+import javax.faces.context.ExternalContext;
+import javax.faces.context.FacesContext;
+import javax.faces.event.PhaseEvent;
+import javax.faces.event.PhaseId;
+import javax.faces.event.PhaseListener;
+import javax.inject.Named;
+
+import org.jboss.seam.faces.util.BeanManagerUtils;
+import org.jboss.weld.extensions.beanManager.BeanManagerAccessor;
+
+/**
+ * This class provides the lifecycle for the new JSF 2 Flash Context
+ * 
+ * @author <a href="mailto:lincolnbaxter at gmail.com">Lincoln Baxter, III</a>
+ */
+ at RequestScoped
+public class FlashScopedContext implements Context, PhaseListener, Serializable
+{
+   private static final long serialVersionUID = -1580689204988513798L;
+
+   private static final String SESSION_KEY_PREFIX = FlashScopedContext.class.getName() + ".context";
+   private final static String COMPONENT_MAP_NAME = FlashScopedContext.class.getName() + ".componentInstanceMap";
+   private final static String CREATIONAL_MAP_NAME = FlashScopedContext.class.getName() + ".creationalInstanceMap";
+
+   String requestParameterName = "fid";
+
+   FlashContext currentContext = null;
+
+   @Produces
+   @Named
+   @RequestScoped
+   public FlashContext getFlashContext()
+   {
+      return currentContext;
+   }
+
+   private FlashContext getCurrentFlashContext()
+   {
+      BeanManager manager = BeanManagerAccessor.getManager();
+      return BeanManagerUtils.getContextualInstance(manager, FlashContext.class);
+   }
+
+   private void assertActive()
+   {
+      if (!isActive())
+      {
+         throw new ContextNotActiveException("Seam context with scope annotation @FlashScoped is not active with respect to the current thread");
+      }
+   }
+
+   /*
+    * PhaseListener Methods
+    */
+   public void beforePhase(final PhaseEvent event)
+   {
+      if (PhaseId.RESTORE_VIEW.equals(event.getPhaseId()))
+      {
+         String currentId = getCurrentId();
+         if (savedContextExists(currentId))
+         {
+            FlashContext context = (FlashContext) getSessionMap().remove(getSessionKey(currentId));
+            currentContext = context;
+         }
+         else
+         {
+            FlashContextImpl context = new FlashContextImpl();
+            context.setId(getNextFlashId());
+            currentContext = context;
+         }
+      }
+   }
+
+   private String getNextFlashId()
+   {
+      String result = null;
+
+      Map<String, Object> sessionMap = getSessionMap();
+      int i = 0;
+      while (result == null)
+      {
+         if (!sessionMap.containsKey(getSessionKey(result)))
+         {
+            result = String.valueOf(i);
+         }
+      }
+
+      return result;
+   }
+
+   private boolean savedContextExists(final String id)
+   {
+      return getSessionMap().get(getSessionKey(id)) instanceof FlashContext;
+   }
+
+   private String getCurrentId()
+   {
+      Map<String, String> requestParameterMap = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap();
+      String currentId = requestParameterMap.get(requestParameterName);
+      return currentId;
+   }
+
+   /**
+    * Destroy the current context since Render Response has completed.
+    */
+   @SuppressWarnings("unchecked")
+   public void afterPhase(final PhaseEvent event)
+   {
+      if (PhaseId.RENDER_RESPONSE.equals(event.getPhaseId()))
+      {
+         Map<Contextual<?>, Object> componentInstanceMap = getComponentInstanceMap();
+         Map<Contextual<?>, CreationalContext<?>> creationalContextMap = getCreationalContextMap();
+
+         if ((componentInstanceMap != null) && (creationalContextMap != null))
+         {
+            for (Entry<Contextual<?>, Object> componentEntry : componentInstanceMap.entrySet())
+            {
+               Contextual contextual = componentEntry.getKey();
+               Object instance = componentEntry.getValue();
+               CreationalContext creational = creationalContextMap.get(contextual);
+
+               contextual.destroy(instance, creational);
+            }
+         }
+      }
+   }
+
+   public PhaseId getPhaseId()
+   {
+      return PhaseId.ANY_PHASE;
+   }
+
+   /*
+    * Context Methods
+    */
+   @SuppressWarnings("unchecked")
+   public <T> T get(final Contextual<T> component)
+   {
+      assertActive();
+      return (T) getComponentInstanceMap().get(component);
+   }
+
+   @SuppressWarnings("unchecked")
+   public <T> T get(final Contextual<T> component, final CreationalContext<T> creationalContext)
+   {
+      assertActive();
+
+      T instance = get(component);
+
+      if (instance == null)
+      {
+         Map<Contextual<?>, CreationalContext<?>> creationalContextMap = getCreationalContextMap();
+         Map<Contextual<?>, Object> componentInstanceMap = getComponentInstanceMap();
+
+         synchronized (componentInstanceMap)
+         {
+            instance = (T) componentInstanceMap.get(component);
+            if (instance == null)
+            {
+               instance = component.create(creationalContext);
+
+               if (instance != null)
+               {
+                  componentInstanceMap.put(component, instance);
+                  creationalContextMap.put(component, creationalContext);
+               }
+            }
+         }
+      }
+
+      return instance;
+   }
+
+   public boolean isActive()
+   {
+      return FacesContext.getCurrentInstance() != null;
+   }
+
+   public Class<? extends Annotation> getScope()
+   {
+      return FlashScoped.class;
+   }
+
+   /*
+    * Helpers for manipulating the Component/Context maps.
+    */
+   @SuppressWarnings("unchecked")
+   private Map<Contextual<?>, Object> getComponentInstanceMap()
+   {
+      ConcurrentHashMap<Contextual<?>, Object> map = (ConcurrentHashMap<Contextual<?>, Object>) getCurrentFlashContext().get(COMPONENT_MAP_NAME);
+
+      if (map == null)
+      {
+         map = new ConcurrentHashMap<Contextual<?>, Object>();
+         getCurrentFlashContext().put(COMPONENT_MAP_NAME, map);
+      }
+
+      return map;
+   }
+
+   @SuppressWarnings("unchecked")
+   private Map<Contextual<?>, CreationalContext<?>> getCreationalContextMap()
+   {
+      Map<Contextual<?>, CreationalContext<?>> map = (ConcurrentHashMap<Contextual<?>, CreationalContext<?>>) getCurrentFlashContext().get(CREATIONAL_MAP_NAME);
+
+      if (map == null)
+      {
+         map = new ConcurrentHashMap<Contextual<?>, CreationalContext<?>>();
+         getCurrentFlashContext().put(CREATIONAL_MAP_NAME, map);
+      }
+
+      return map;
+   }
+
+   private Map<String, Object> getSessionMap()
+   {
+      ExternalContext externalContext = FacesContext.getCurrentInstance().getExternalContext();
+      return externalContext.getSessionMap();
+   }
+
+   private String getSessionKey(final String id)
+   {
+      String result = SESSION_KEY_PREFIX;
+      if (id != null)
+      {
+         result += "_" + id;
+      }
+      return result;
+   }
+
+   /**
+    * Get the name of the request parameter to contain the current
+    * {@link FlashContext} id.
+    */
+   public String getRequestParameterName()
+   {
+      return requestParameterName;
+   }
+}

Modified: modules/faces/trunk/impl/src/main/java/org/jboss/seam/faces/event/DelegatingPhaseListener.java
===================================================================
--- modules/faces/trunk/impl/src/main/java/org/jboss/seam/faces/event/DelegatingPhaseListener.java	2010-05-28 01:33:48 UTC (rev 12876)
+++ modules/faces/trunk/impl/src/main/java/org/jboss/seam/faces/event/DelegatingPhaseListener.java	2010-05-28 01:34:14 UTC (rev 12877)
@@ -27,6 +27,8 @@
 import javax.faces.event.PhaseId;
 import javax.faces.event.PhaseListener;
 
+import org.jboss.seam.faces.context.FlashScopedContext;
+
 /**
  * Provide CDI injection to PhaseListener artifacts by delegating through this
  * class.
@@ -77,7 +79,7 @@
    @SuppressWarnings("unchecked")
    private List<PhaseListener> getPhaseListeners()
    {
-      return getListeners(PhaseEventBridge.class);
+      return getListeners(FlashScopedContext.class, PhaseEventBridge.class);
    }
 
 }

Modified: modules/faces/trunk/impl/src/main/java/org/jboss/seam/faces/status/MessagesAdapter.java
===================================================================
--- modules/faces/trunk/impl/src/main/java/org/jboss/seam/faces/status/MessagesAdapter.java	2010-05-28 01:33:48 UTC (rev 12876)
+++ modules/faces/trunk/impl/src/main/java/org/jboss/seam/faces/status/MessagesAdapter.java	2010-05-28 01:34:14 UTC (rev 12877)
@@ -50,7 +50,8 @@
    @Inject
    private Messages messages;
 
-   @SuppressWarnings("unused")
+   // void flushBeforeNavigate(@Observes BeforeNavigateEvent event);
+
    void convert(@Observes @Before @RenderResponse final PhaseEvent event)
    {
       for (Message m : messages.getAll())

Modified: modules/faces/trunk/impl/src/main/java/org/jboss/seam/faces/util/BeanManagerUtils.java
===================================================================
--- modules/faces/trunk/impl/src/main/java/org/jboss/seam/faces/util/BeanManagerUtils.java	2010-05-28 01:33:48 UTC (rev 12876)
+++ modules/faces/trunk/impl/src/main/java/org/jboss/seam/faces/util/BeanManagerUtils.java	2010-05-28 01:34:14 UTC (rev 12877)
@@ -100,9 +100,24 @@
     * @param type The class for which to return an instance.
     * @return The managed instance, or null if none could be provided.
     */
-   @SuppressWarnings("unchecked")
    public <T> T getContextualInstance(final Class<T> type)
    {
+      return getContextualInstance(manager, type);
+   }
+
+   /**
+    * Get a single CDI managed instance of a specific class. Return only the
+    * first result if multiple beans are available.
+    * <p>
+    * <b>NOTE:</b> Using this method should be avoided at all costs.
+    * 
+    * @param manager The bean manager with which to perform the lookup.
+    * @param type The class for which to return an instance.
+    * @return The managed instance, or null if none could be provided.
+    */
+   @SuppressWarnings("unchecked")
+   public static <T> T getContextualInstance(final BeanManager manager, final Class<T> type)
+   {
       T result = null;
       Bean<T> bean = (Bean<T>) manager.resolve(manager.getBeans(type));
       if (bean != null)

Modified: modules/faces/trunk/impl/src/main/resources/META-INF/faces-config.xml
===================================================================
--- modules/faces/trunk/impl/src/main/resources/META-INF/faces-config.xml	2010-05-28 01:33:48 UTC (rev 12876)
+++ modules/faces/trunk/impl/src/main/resources/META-INF/faces-config.xml	2010-05-28 01:34:14 UTC (rev 12877)
@@ -13,10 +13,13 @@
 	</ordering>
 
 	<lifecycle>
-		<phase-listener>org.jboss.seam.faces.context.FlashScopedContext</phase-listener>
 		<phase-listener>org.jboss.seam.faces.event.DelegatingPhaseListener</phase-listener>
 	</lifecycle>
 	
+	<factory>
+		<external-context-factory>org.jboss.seam.faces.environment.SeamExternalContextFactory</external-context-factory>
+	</factory>
+
 	<application>
 		<system-event-listener>
 			<system-event-listener-class>org.jboss.seam.faces.event.DelegatingSystemEventListener</system-event-listener-class>



More information about the seam-commits mailing list