You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by im...@apache.org on 2006/06/23 09:15:56 UTC

svn commit: r416590 - in /myfaces/tomahawk/trunk/sandbox/core/src/main: java/org/apache/myfaces/custom/redirectTracker/ resources-facesconfig/META-INF/

Author: imario
Date: Fri Jun 23 00:15:56 2006
New Revision: 416590

URL: http://svn.apache.org/viewvc?rev=416590&view=rev
Log:
uups, not committed all the stuff - so again.
RedirectTracker: captures request scoped data on navigation redirect, these are
* beans
* messages
* locale

Added:
    myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/custom/redirectTracker/
    myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/custom/redirectTracker/FacesContextWrapper.java   (with props)
    myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/custom/redirectTracker/RedirectTrackerExternalContextWrapper.java   (with props)
    myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/custom/redirectTracker/RedirectTrackerFacesContextFactory.java   (with props)
    myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/custom/redirectTracker/RedirectTrackerManager.java   (with props)
    myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/custom/redirectTracker/RedirectTrackerNavigationHandler.java   (with props)
    myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/custom/redirectTracker/RedirectTrackerPhaseListener.java   (with props)
    myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/custom/redirectTracker/RedirectTrackerRequestMapWrapper.java   (with props)
    myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/custom/redirectTracker/RedirectTrackerVariableResolver.java   (with props)
Modified:
    myfaces/tomahawk/trunk/sandbox/core/src/main/resources-facesconfig/META-INF/faces-config.xml

Added: myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/custom/redirectTracker/FacesContextWrapper.java
URL: http://svn.apache.org/viewvc/myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/custom/redirectTracker/FacesContextWrapper.java?rev=416590&view=auto
==============================================================================
--- myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/custom/redirectTracker/FacesContextWrapper.java (added)
+++ myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/custom/redirectTracker/FacesContextWrapper.java Fri Jun 23 00:15:56 2006
@@ -0,0 +1,149 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.apache.myfaces.custom.redirectTracker;
+
+import javax.faces.context.FacesContext;
+import javax.faces.context.ExternalContext;
+import javax.faces.context.ResponseStream;
+import javax.faces.context.ResponseWriter;
+import javax.faces.application.Application;
+import javax.faces.application.FacesMessage;
+import javax.faces.render.RenderKit;
+import javax.faces.component.UIViewRoot;
+import java.util.Iterator;
+
+/**
+ * Convenient class to wrap the current FacesContext.
+ * @author Manfred Geiler (latest modification by $Author$)
+ * @author Anton Koinov
+ * @version $Revision$ $Date$
+ */
+public class FacesContextWrapper
+	extends FacesContext
+{
+    //~ Instance fields ----------------------------------------------------------------------------
+
+    private FacesContext _facesContext;
+
+    //~ Constructors -------------------------------------------------------------------------------
+
+    public FacesContextWrapper(FacesContext facesContext)
+    {
+        _facesContext = facesContext;
+    }
+
+    //~ Methods ------------------------------------------------------------------------------------
+
+    public Application getApplication()
+    {
+        return _facesContext.getApplication();
+    }
+
+    public Iterator getClientIdsWithMessages()
+    {
+        return _facesContext.getClientIdsWithMessages();
+    }
+
+    public ExternalContext getExternalContext()
+    {
+        return _facesContext.getExternalContext();
+    }
+
+    public FacesMessage.Severity getMaximumSeverity()
+    {
+        return _facesContext.getMaximumSeverity();
+    }
+
+    public Iterator getMessages()
+    {
+        return _facesContext.getMessages();
+    }
+
+    public Iterator getMessages(String clientId)
+    {
+        return _facesContext.getMessages(clientId);
+    }
+
+    public RenderKit getRenderKit()
+    {
+        return _facesContext.getRenderKit();
+    }
+
+    public boolean getRenderResponse()
+    {
+        return _facesContext.getRenderResponse();
+    }
+
+    public boolean getResponseComplete()
+    {
+        return _facesContext.getResponseComplete();
+    }
+
+    public void setResponseStream(ResponseStream responsestream)
+    {
+        _facesContext.setResponseStream(responsestream);
+    }
+
+    public ResponseStream getResponseStream()
+    {
+        return _facesContext.getResponseStream();
+    }
+
+    public void setResponseWriter(ResponseWriter responsewriter)
+    {
+        _facesContext.setResponseWriter(responsewriter);
+    }
+
+    public ResponseWriter getResponseWriter()
+    {
+        return _facesContext.getResponseWriter();
+    }
+
+    public void setViewRoot(UIViewRoot viewRoot)
+    {
+        _facesContext.setViewRoot(viewRoot);
+    }
+
+    public UIViewRoot getViewRoot()
+    {
+        return _facesContext.getViewRoot();
+    }
+
+    public void addMessage(String clientId, FacesMessage message)
+    {
+        _facesContext.addMessage(clientId, message);
+    }
+
+    public void release()
+    {
+        _facesContext.release();
+    }
+
+    public void renderResponse()
+    {
+        _facesContext.renderResponse();
+    }
+
+    public void responseComplete()
+    {
+        _facesContext.responseComplete();
+    }
+
+	public FacesContext getWrappedFacesContext()
+	{
+		return _facesContext;
+	}
+}

Propchange: myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/custom/redirectTracker/FacesContextWrapper.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/custom/redirectTracker/FacesContextWrapper.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Propchange: myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/custom/redirectTracker/FacesContextWrapper.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/custom/redirectTracker/RedirectTrackerExternalContextWrapper.java
URL: http://svn.apache.org/viewvc/myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/custom/redirectTracker/RedirectTrackerExternalContextWrapper.java?rev=416590&view=auto
==============================================================================
--- myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/custom/redirectTracker/RedirectTrackerExternalContextWrapper.java (added)
+++ myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/custom/redirectTracker/RedirectTrackerExternalContextWrapper.java Fri Jun 23 00:15:56 2006
@@ -0,0 +1,226 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.apache.myfaces.custom.redirectTracker;
+
+import javax.faces.context.ExternalContext;
+import javax.faces.context.FacesContext;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Map;
+import java.util.Locale;
+import java.util.Iterator;
+import java.util.Set;
+import java.net.URL;
+import java.net.MalformedURLException;
+import java.security.Principal;
+
+/**
+ * wraps a external context
+ */
+public class RedirectTrackerExternalContextWrapper extends ExternalContext
+{
+	private final ExternalContext original;
+
+	public RedirectTrackerExternalContextWrapper(ExternalContext original)
+	{
+		this.original = original;
+	}
+
+	public void dispatch(String s)
+		throws IOException
+	{
+		original.dispatch(s);
+	}
+
+	public String encodeActionURL(String s)
+	{
+		return original.encodeActionURL(s);
+	}
+
+	public String encodeNamespace(String s)
+	{
+		return original.encodeNamespace(s);
+	}
+
+	public String encodeResourceURL(String s)
+	{
+		return original.encodeResourceURL(s);
+	}
+
+	public Map getApplicationMap()
+	{
+		return original.getApplicationMap();
+	}
+
+	public String getAuthType()
+	{
+		return original.getAuthType();
+	}
+
+	public Object getContext()
+	{
+		return original.getContext();
+	}
+
+	public String getInitParameter(String s)
+	{
+		return original.getInitParameter(s);
+	}
+
+	public Map getInitParameterMap()
+	{
+		return original.getInitParameterMap();
+	}
+
+	public String getRemoteUser()
+	{
+		return original.getRemoteUser();
+	}
+
+	public Object getRequest()
+	{
+		return original.getRequest();
+	}
+
+	public String getRequestContextPath()
+	{
+		return original.getRequestContextPath();
+	}
+
+	public Map getRequestCookieMap()
+	{
+		return original.getRequestCookieMap();
+	}
+
+	public Map getRequestHeaderMap()
+	{
+		return original.getRequestHeaderMap();
+	}
+
+	public Map getRequestHeaderValuesMap()
+	{
+		return original.getRequestHeaderValuesMap();
+	}
+
+	public Locale getRequestLocale()
+	{
+		return original.getRequestLocale();
+	}
+
+	public Iterator getRequestLocales()
+	{
+		return original.getRequestLocales();
+	}
+
+	public Map getRequestMap()
+	{
+		return original.getRequestMap();
+	}
+
+	public Map getRequestParameterMap()
+	{
+		return original.getRequestParameterMap();
+	}
+
+	public Iterator getRequestParameterNames()
+	{
+		return original.getRequestParameterNames();
+	}
+
+	public Map getRequestParameterValuesMap()
+	{
+		return original.getRequestParameterValuesMap();
+	}
+
+	public String getRequestPathInfo()
+	{
+		return original.getRequestPathInfo();
+	}
+
+	public String getRequestServletPath()
+	{
+		return original.getRequestServletPath();
+	}
+
+	public URL getResource(String s)
+		throws MalformedURLException
+	{
+		return original.getResource(s);
+	}
+
+	public InputStream getResourceAsStream(String s)
+	{
+		return original.getResourceAsStream(s);
+	}
+
+	public Set getResourcePaths(String s)
+	{
+		return original.getResourcePaths(s);
+	}
+
+	public Object getResponse()
+	{
+		return original.getResponse();
+	}
+
+	public Object getSession(boolean b)
+	{
+		return original.getSession(b);
+	}
+
+	public Map getSessionMap()
+	{
+		return original.getSessionMap();
+	}
+
+	public Principal getUserPrincipal()
+	{
+		return original.getUserPrincipal();
+	}
+
+	public boolean isUserInRole(String s)
+	{
+		return original.isUserInRole(s);
+	}
+
+	public void log(String s)
+	{
+		original.log(s);
+	}
+
+	public void log(String s, Throwable throwable)
+	{
+		original.log(s, throwable);
+	}
+
+	public void redirect(String url) throws IOException
+	{
+		FacesContext facesContext = FacesContext.getCurrentInstance();
+
+		RedirectTrackerManager manager = RedirectTrackerManager.getInstance(facesContext);
+		if (manager != null)
+		{
+			url = manager.trackRedirect(facesContext, url);
+		}
+
+		original.redirect(url);
+	}
+
+	public ExternalContext getWrappedExternalContext()
+	{
+		return original;
+	}
+}

Propchange: myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/custom/redirectTracker/RedirectTrackerExternalContextWrapper.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/custom/redirectTracker/RedirectTrackerExternalContextWrapper.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Propchange: myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/custom/redirectTracker/RedirectTrackerExternalContextWrapper.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/custom/redirectTracker/RedirectTrackerFacesContextFactory.java
URL: http://svn.apache.org/viewvc/myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/custom/redirectTracker/RedirectTrackerFacesContextFactory.java?rev=416590&view=auto
==============================================================================
--- myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/custom/redirectTracker/RedirectTrackerFacesContextFactory.java (added)
+++ myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/custom/redirectTracker/RedirectTrackerFacesContextFactory.java Fri Jun 23 00:15:56 2006
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.apache.myfaces.custom.redirectTracker;
+
+import javax.faces.FacesException;
+import javax.faces.context.ExternalContext;
+import javax.faces.context.FacesContext;
+import javax.faces.context.FacesContextFactory;
+import javax.faces.lifecycle.Lifecycle;
+
+/**
+ * decoreates the external context to allow to intercept its redirect method.
+ */
+public class RedirectTrackerFacesContextFactory extends FacesContextFactory
+{
+	private final FacesContextFactory original;
+
+	public RedirectTrackerFacesContextFactory(FacesContextFactory original)
+	{
+		this.original = original;
+	}
+
+	public FacesContext getFacesContext(Object context,
+										Object request,
+										Object response,
+										Lifecycle lifecycle) throws FacesException
+	{
+		final FacesContext facesContext = original.getFacesContext(context, request, response, lifecycle);
+
+		return new RedirectTrackerFacesContextWrapper(facesContext);
+	}
+
+	private static class RedirectTrackerFacesContextWrapper extends FacesContextWrapper
+	{
+		private final ExternalContext externalContextWrappper;
+
+		public RedirectTrackerFacesContextWrapper(final FacesContext facesContext)
+		{
+			super(facesContext);
+			externalContextWrappper = new RedirectTrackerExternalContextWrapper(facesContext.getExternalContext());
+
+			FacesContext.setCurrentInstance(this);
+		}
+
+		public ExternalContext getExternalContext()
+		{
+			return externalContextWrappper;
+		}
+	}
+}

Propchange: myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/custom/redirectTracker/RedirectTrackerFacesContextFactory.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/custom/redirectTracker/RedirectTrackerFacesContextFactory.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Propchange: myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/custom/redirectTracker/RedirectTrackerFacesContextFactory.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/custom/redirectTracker/RedirectTrackerManager.java
URL: http://svn.apache.org/viewvc/myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/custom/redirectTracker/RedirectTrackerManager.java?rev=416590&view=auto
==============================================================================
--- myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/custom/redirectTracker/RedirectTrackerManager.java (added)
+++ myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/custom/redirectTracker/RedirectTrackerManager.java Fri Jun 23 00:15:56 2006
@@ -0,0 +1,357 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.apache.myfaces.custom.redirectTracker;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import javax.faces.application.FacesMessage;
+import javax.faces.context.FacesContext;
+import javax.faces.el.ValueBinding;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+import java.util.Locale;
+
+/**
+ * The redirect tracker maintains a list/map of data needed to restore the myfaces
+ * system after a navigation redirect
+ */
+public class RedirectTrackerManager
+{
+	private final static Log log = LogFactory.getLog(RedirectTrackerManager.class);
+
+	public static final String SESSION_KEY = RedirectTrackerManager.class.getName();
+	public static final String REDIRECT_ARG = "_rtid";
+	public static final int TRACK_REDIRECTS = 20; // TODO: make configureable
+
+	private final int redirects;
+	private final Map redirectEntryMap;
+	private final List redirectEntryList;
+	private final Map requestBeanMap = new TreeMap();
+
+	private long requests = 0;
+
+	private static class Entry
+	{
+		private final String mapKey;
+		private List messages;
+		private Map beanMap;
+		private Locale locale;
+
+		private Entry(String mapKey)
+		{
+			this.mapKey = mapKey;
+		}
+
+		void addMessage(Object clientId, Object message)
+		{
+			if (messages == null)
+			{
+				messages = new ArrayList();
+			}
+			messages.add(new MessageEntry(clientId, message));
+		}
+
+		public Iterator getMessages()
+		{
+			if (messages == null)
+			{
+				return null;
+			}
+
+			return messages.iterator();
+		}
+
+		public boolean hasCapturedData()
+		{
+			return (messages != null && messages.size() > 0)
+				|| (beanMap != null && beanMap.size() > 0)
+				|| locale != null;
+		}
+	}
+
+	private static class MessageEntry
+	{
+		private final Object clientId;
+		private final Object message;
+
+		public MessageEntry(Object clientId, Object message)
+		{
+			this.clientId = clientId;
+			this.message = message;
+		}
+	}
+
+	/**
+	 * Instantiate the tracker
+	 *
+	 * @param redirects nuof redirects to track
+	 */
+	public RedirectTrackerManager(int redirects)
+	{
+		this.redirects = redirects;
+		redirectEntryMap = new TreeMap();
+		redirectEntryList = new ArrayList(redirects);
+	}
+
+	/**
+	 * check if this was a redirect, and if, process it
+	 */
+	public void processTrackedRequest(FacesContext facesContext)
+	{
+		Object rtid = facesContext.getExternalContext().getRequestParameterMap().get(REDIRECT_ARG);
+		if (!isRedirectedRequest(rtid))
+		{
+			return;
+		}
+
+		setupFaces(facesContext, rtid);
+	}
+
+	/**
+	 * check to see if the request parameter contains the identifier to the saved states
+	 */
+	protected boolean isRedirectedRequest(Object rtid)
+	{
+		if (rtid == null)
+		{
+			return false;
+		}
+
+		synchronized (redirectEntryMap)
+		{
+			return redirectEntryMap.containsKey(rtid);
+		}
+	}
+
+	/**
+	 * access the redirect tracker
+	 */
+	public static RedirectTrackerManager getInstance(FacesContext facesContext)
+	{
+		Map sessionMap = facesContext.getExternalContext().getSessionMap();
+		if (sessionMap == null)
+		{
+			return null;
+		}
+		RedirectTrackerManager redirectManager = (RedirectTrackerManager) sessionMap.get(SESSION_KEY);
+		if (redirectManager == null)
+		{
+			redirectManager = createRedirectTrackerManager();
+			sessionMap.put(SESSION_KEY, redirectManager);
+		}
+
+		return redirectManager;
+	}
+
+	/**
+	 * create a new redirect tracker
+	 */
+	protected static RedirectTrackerManager createRedirectTrackerManager()
+	{
+		return new RedirectTrackerManager(TRACK_REDIRECTS);
+	}
+
+	/**
+	 * add the current state to the redirect map/list
+	 * @return the new path used for redirect
+	 */
+	public String trackRedirect(FacesContext facesContext, String redirectPath)
+	{
+		long rtid = getNextRequestNo();
+		String mapKey = Long.toString(rtid, Character.MAX_RADIX);
+
+		Entry entry = new Entry(mapKey);
+
+		saveBeans(entry);
+		saveMessages(facesContext, entry);
+
+		// prepare for next redirect
+		clearSaveStateBean();
+
+		if (!entry.hasCapturedData())
+		{
+			// nothing to restore
+			return redirectPath;
+		}
+
+		synchronized (redirectEntryMap)
+		{
+			redirectEntryMap.put(mapKey, entry);
+			redirectEntryList.add(entry);
+
+			while (redirectEntryList.size() > redirects)
+			{
+				Entry prevEntry = (Entry) redirectEntryList.remove(0);
+				redirectEntryMap.remove(prevEntry.mapKey);
+			}
+		}
+
+		if (redirectPath.indexOf('?') == -1)
+		{
+			return redirectPath + "?" + REDIRECT_ARG + "=" + rtid;
+		}
+		else
+		{
+			return redirectPath + "&" + REDIRECT_ARG + "=" + rtid;
+		}
+	}
+
+	protected void saveBeans(Entry entry)
+	{
+		entry.beanMap = new TreeMap(requestBeanMap);
+	}
+
+	/**
+	 * Add the object to the current request holder
+	 */
+	public void addSaveStateBean(String expressionString, Object value)
+	{
+		if (log.isDebugEnabled())
+		{
+			log.debug("addSaveStateBean: " + expressionString + " value=" + value);
+		}
+		requestBeanMap.put(expressionString, value);
+	}
+
+	/**
+	 * request done, clear saveState beanmap
+	 */
+	public void clearSaveStateBean()
+	{
+		requestBeanMap.clear();
+	}
+
+	protected void saveMessages(FacesContext facesContext, Entry entry)
+	{
+		Iterator iterClientIds = facesContext.getClientIdsWithMessages();
+		while (iterClientIds.hasNext())
+		{
+			String clientId = (String) iterClientIds.next();
+			Iterator iterMessages = facesContext.getMessages(clientId);
+			while (iterMessages.hasNext())
+			{
+				Object message = iterMessages.next();
+
+				if (log.isDebugEnabled())
+				{
+					log.debug("saveMessage: " + message);
+				}
+
+				entry.addMessage(clientId, message);
+			}
+		}
+	}
+
+	protected void restoreMessages(FacesContext facesContext, Entry entry)
+	{
+		Iterator iterMessages = entry.getMessages();
+		if (iterMessages == null)
+		{
+			return;
+		}
+
+		while (iterMessages.hasNext())
+		{
+			MessageEntry message = (MessageEntry) iterMessages.next();
+			facesContext.addMessage((String) message.clientId, (FacesMessage) message.message);
+		}
+	}
+
+	protected void saveLocale(FacesContext facesContext, Entry entry)
+	{
+		if (facesContext.getViewRoot() != null && facesContext.getViewRoot().getLocale() != null)
+		{
+			if (log.isDebugEnabled())
+			{
+				log.debug("saveLocale: " + facesContext.getViewRoot().getLocale());
+			}
+
+			entry.locale = facesContext.getViewRoot().getLocale();
+		}
+	}
+
+	protected void restoreLocale(FacesContext facesContext, Entry entry)
+	{
+		if (entry.locale != null && facesContext.getViewRoot() != null)
+		{
+			facesContext.getViewRoot().setLocale(entry.locale);
+		}
+	}
+
+	/**
+	 * resetup faces after redirect request
+	 */
+	protected void setupFaces(FacesContext facesContext, Object rtid)
+	{
+		Entry entry;
+		synchronized (redirectEntryMap)
+		{
+			entry = (Entry) redirectEntryMap.get(rtid);
+		}
+
+		if (entry == null)
+		{
+			// entry lost?
+			return;
+		}
+
+		restoreLocale(facesContext, entry);
+		restoreMessages(facesContext, entry);
+		restoreBeans(facesContext, entry);
+	}
+
+	protected void restoreBeans(FacesContext facesContext, Entry entry)
+	{
+		Iterator iterBeanMap = entry.beanMap.entrySet().iterator();
+		while (iterBeanMap.hasNext())
+		{
+			Map.Entry bean = (Map.Entry) iterBeanMap.next();
+
+			String beanName = bean.getKey().toString();
+
+			if (log.isDebugEnabled())
+			{
+				log.debug("restore bean: " + beanName + " value=" + bean.getValue());
+			}
+
+			if (beanName.startsWith("#{") && beanName.endsWith("}"))
+			{
+				ValueBinding vb = facesContext.getApplication().createValueBinding(bean.getKey().toString());
+				vb.setValue(facesContext, bean.getValue());
+			}
+			else
+			{
+				facesContext.getExternalContext().getRequestMap().put(beanName, bean.getValue());
+
+				// if we add the bean directly to the request map, also put it again into our own list
+				addSaveStateBean(beanName, bean.getValue());
+			}
+		}
+	}
+
+	/**
+	 * get the next request number
+	 */
+	protected synchronized long getNextRequestNo()
+	{
+		requests++;
+		return requests;
+	}
+}
\ No newline at end of file

Propchange: myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/custom/redirectTracker/RedirectTrackerManager.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/custom/redirectTracker/RedirectTrackerManager.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Propchange: myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/custom/redirectTracker/RedirectTrackerManager.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/custom/redirectTracker/RedirectTrackerNavigationHandler.java
URL: http://svn.apache.org/viewvc/myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/custom/redirectTracker/RedirectTrackerNavigationHandler.java?rev=416590&view=auto
==============================================================================
--- myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/custom/redirectTracker/RedirectTrackerNavigationHandler.java (added)
+++ myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/custom/redirectTracker/RedirectTrackerNavigationHandler.java Fri Jun 23 00:15:56 2006
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.apache.myfaces.custom.redirectTracker;
+
+import javax.faces.application.NavigationHandler;
+import javax.faces.context.ExternalContext;
+import javax.faces.context.FacesContext;
+
+/**
+ * intercept the redirect navigation case
+ */
+public class RedirectTrackerNavigationHandler extends NavigationHandler
+{
+	private final NavigationHandler original;
+
+	public RedirectTrackerNavigationHandler(NavigationHandler original)
+	{
+		this.original = original;
+	}
+
+	public void handleNavigation(FacesContext facesContext, String fromAction, String outcome)
+	{
+		final RedirectTrackerExternalContextWrapper wrappedExternalContext = new RedirectTrackerExternalContextWrapper(facesContext.getExternalContext());
+		original.handleNavigation(new FacesContextWrapper(facesContext)
+		{
+			public ExternalContext getExternalContext()
+			{
+				return wrappedExternalContext;
+			}
+		},
+			fromAction,
+			outcome);
+	}
+}

Propchange: myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/custom/redirectTracker/RedirectTrackerNavigationHandler.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/custom/redirectTracker/RedirectTrackerNavigationHandler.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Propchange: myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/custom/redirectTracker/RedirectTrackerNavigationHandler.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/custom/redirectTracker/RedirectTrackerPhaseListener.java
URL: http://svn.apache.org/viewvc/myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/custom/redirectTracker/RedirectTrackerPhaseListener.java?rev=416590&view=auto
==============================================================================
--- myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/custom/redirectTracker/RedirectTrackerPhaseListener.java (added)
+++ myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/custom/redirectTracker/RedirectTrackerPhaseListener.java Fri Jun 23 00:15:56 2006
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.apache.myfaces.custom.redirectTracker;
+
+import javax.faces.event.PhaseEvent;
+import javax.faces.event.PhaseId;
+import javax.faces.event.PhaseListener;
+
+/**
+ * reinitialize the system after a tracked redirect
+ */
+public class RedirectTrackerPhaseListener implements PhaseListener
+{
+	public void afterPhase(PhaseEvent event)
+	{
+		if (event.getPhaseId().equals(PhaseId.RESTORE_VIEW))
+		{
+			RedirectTrackerManager manager = RedirectTrackerManager.getInstance(event.getFacesContext());
+			if (manager != null)
+			{
+				manager.processTrackedRequest(event.getFacesContext());
+			}
+		}
+	}
+
+	public void beforePhase(PhaseEvent event)
+	{
+	}
+
+	public PhaseId getPhaseId()
+	{
+		return PhaseId.ANY_PHASE;
+	}
+}

Propchange: myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/custom/redirectTracker/RedirectTrackerPhaseListener.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/custom/redirectTracker/RedirectTrackerPhaseListener.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Propchange: myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/custom/redirectTracker/RedirectTrackerPhaseListener.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/custom/redirectTracker/RedirectTrackerRequestMapWrapper.java
URL: http://svn.apache.org/viewvc/myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/custom/redirectTracker/RedirectTrackerRequestMapWrapper.java?rev=416590&view=auto
==============================================================================
--- myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/custom/redirectTracker/RedirectTrackerRequestMapWrapper.java (added)
+++ myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/custom/redirectTracker/RedirectTrackerRequestMapWrapper.java Fri Jun 23 00:15:56 2006
@@ -0,0 +1,124 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.apache.myfaces.custom.redirectTracker;
+
+import javax.faces.context.FacesContext;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * captures beans put into the request scope
+ */
+class RedirectTrackerRequestMapWrapper implements Map
+{
+	private final Map original;
+
+	public RedirectTrackerRequestMapWrapper(Map original)
+	{
+		this.original = original;
+	}
+
+	public int size()
+	{
+		return original.size();
+	}
+
+	public boolean isEmpty()
+	{
+		return original.isEmpty();
+	}
+
+	public boolean containsKey(Object key)
+	{
+		return original.containsKey(key);
+	}
+
+	public boolean containsValue(Object value)
+	{
+		return original.containsValue(value);
+	}
+
+	public Object get(Object key)
+	{
+		return original.get(key);
+	}
+
+	public Object put(Object key, Object value)
+	{
+		RedirectTrackerManager manager = RedirectTrackerManager.getInstance(FacesContext.getCurrentInstance());
+		if (manager != null)
+		{
+			manager.addSaveStateBean(key.toString(), value);
+		}
+
+		return original.put(key, value);
+	}
+
+	public Object remove(Object key)
+	{
+		return original.remove(key);
+	}
+
+	public void putAll(Map t)
+	{
+		if (t != null)
+		{
+			RedirectTrackerManager manager = RedirectTrackerManager.getInstance(FacesContext.getCurrentInstance());
+			if (manager != null)
+			{
+				Iterator iterEntrySet = t.entrySet().iterator();
+				while (iterEntrySet.hasNext())
+				{
+					Entry entry = (Entry) iterEntrySet.next();
+					manager.addSaveStateBean(entry.getKey().toString(), entry.getValue());
+				}
+			}
+		}
+		original.putAll(t);
+	}
+
+	public void clear()
+	{
+		original.clear();
+	}
+
+	public Set keySet()
+	{
+		return original.keySet();
+	}
+
+	public Collection values()
+	{
+		return original.values();
+	}
+
+	public Set entrySet()
+	{
+		return original.entrySet();
+	}
+
+	public boolean equals(Object o)
+	{
+		return original.equals(o);
+	}
+
+	public int hashCode()
+	{
+		return original.hashCode();
+	}
+}

Propchange: myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/custom/redirectTracker/RedirectTrackerRequestMapWrapper.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/custom/redirectTracker/RedirectTrackerRequestMapWrapper.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Propchange: myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/custom/redirectTracker/RedirectTrackerRequestMapWrapper.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/custom/redirectTracker/RedirectTrackerVariableResolver.java
URL: http://svn.apache.org/viewvc/myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/custom/redirectTracker/RedirectTrackerVariableResolver.java?rev=416590&view=auto
==============================================================================
--- myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/custom/redirectTracker/RedirectTrackerVariableResolver.java (added)
+++ myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/custom/redirectTracker/RedirectTrackerVariableResolver.java Fri Jun 23 00:15:56 2006
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.apache.myfaces.custom.redirectTracker;
+
+import javax.faces.el.VariableResolver;
+import javax.faces.el.EvaluationException;
+import javax.faces.context.FacesContext;
+
+/**
+ * try to capture all beans put into the request scope
+ */
+public class RedirectTrackerVariableResolver extends VariableResolver
+{
+	private final VariableResolver original;
+
+	public RedirectTrackerVariableResolver(VariableResolver original)
+	{
+		this.original = original;
+	}
+
+	public Object resolveVariable(FacesContext facesContext, String variable) throws EvaluationException
+	{
+		boolean exists = facesContext.getExternalContext().getRequestMap().containsKey(variable);
+
+		Object value = original.resolveVariable(facesContext, variable);
+
+		if (!exists && facesContext.getExternalContext().getRequestMap().containsKey(variable))
+		{
+			// variable created and put into the request scope
+
+			RedirectTrackerManager manager = RedirectTrackerManager.getInstance(FacesContext.getCurrentInstance());
+			if (manager != null)
+			{
+				manager.addSaveStateBean(variable, value);
+			}
+		}
+
+		return value;
+	}
+}

Propchange: myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/custom/redirectTracker/RedirectTrackerVariableResolver.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/custom/redirectTracker/RedirectTrackerVariableResolver.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Propchange: myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/custom/redirectTracker/RedirectTrackerVariableResolver.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: myfaces/tomahawk/trunk/sandbox/core/src/main/resources-facesconfig/META-INF/faces-config.xml
URL: http://svn.apache.org/viewvc/myfaces/tomahawk/trunk/sandbox/core/src/main/resources-facesconfig/META-INF/faces-config.xml?rev=416590&r1=416589&r2=416590&view=diff
==============================================================================
--- myfaces/tomahawk/trunk/sandbox/core/src/main/resources-facesconfig/META-INF/faces-config.xml (original)
+++ myfaces/tomahawk/trunk/sandbox/core/src/main/resources-facesconfig/META-INF/faces-config.xml Fri Jun 23 00:15:56 2006
@@ -401,12 +401,9 @@
 	  <phase-listener>org.apache.myfaces.custom.redirectTracker.RedirectTrackerPhaseListener</phase-listener>
   </lifecycle>
 
-  <factory>
-    <faces-context-factory>org.apache.myfaces.custom.redirectTracker.RedirectTrackerFacesContextFactory</faces-context-factory>
-  </factory>
-
   <application>
     <variable-resolver>org.apache.myfaces.custom.redirectTracker.RedirectTrackerVariableResolver</variable-resolver>
+	<navigation-handler>org.apache.myfaces.custom.redirectTracker.RedirectTrackerNavigationHandler</navigation-handler>
   </application>
 
   <!--custom validators -->