[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