You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by sk...@apache.org on 2008/02/07 17:31:21 UTC

svn commit: r619486 - in /myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra: frameworkAdapter/jsf/ lib/jsf/

Author: skitching
Date: Thu Feb  7 08:31:20 2008
New Revision: 619486

URL: http://svn.apache.org/viewvc?rev=619486&view=rev
Log:
Move orchestra initialisation process for JSF down into a FacesContextFactory.

Added:
    myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/lib/jsf/ContextLockRequestHandler.java
    myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/lib/jsf/ConversationManagerRequestHandler.java
    myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/lib/jsf/DataSourceLeakRequestHandler.java
    myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/lib/jsf/FrameworkAdapterRequestHandler.java
    myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/lib/jsf/RequestHandler.java
Removed:
    myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/lib/jsf/OrchestraInitializationPhaseListener.java
Modified:
    myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/frameworkAdapter/jsf/JsfFrameworkAdapter.java
    myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/frameworkAdapter/jsf/JsfFrameworkAdapterFilter.java
    myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/lib/jsf/OrchestraFacesContextFactory.java

Modified: myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/frameworkAdapter/jsf/JsfFrameworkAdapter.java
URL: http://svn.apache.org/viewvc/myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/frameworkAdapter/jsf/JsfFrameworkAdapter.java?rev=619486&r1=619485&r2=619486&view=diff
==============================================================================
--- myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/frameworkAdapter/jsf/JsfFrameworkAdapter.java (original)
+++ myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/frameworkAdapter/jsf/JsfFrameworkAdapter.java Thu Feb  7 08:31:20 2008
@@ -18,26 +18,44 @@
  */
 package org.apache.myfaces.orchestra.frameworkAdapter.jsf;
 
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
 import org.apache.myfaces.orchestra.conversation.ConversationMessager;
 import org.apache.myfaces.orchestra.conversation.jsf.JsfConversationMessager;
-import org.apache.myfaces.orchestra.frameworkAdapter.basic.BasicFrameworkAdapter;
+import org.apache.myfaces.orchestra.frameworkAdapter.FrameworkAdapter;
+import org.apache.myfaces.orchestra.frameworkAdapter._FrameworkAdapterUtils;
+import org.apache.myfaces.orchestra.lib.OrchestraException;
 
 import javax.faces.context.FacesContext;
+
 import java.io.IOException;
 
 /**
  * An implementation of the FrameworkAdapter for JSF environments.
  * <p>
- * This class requires the JsfFrameworkAdapterFilter to be configured to run
- * or every JSF request.
- * <p>
  * This class defaults to using a JsfConversationMessager instance. 
  */
-public class JsfFrameworkAdapter extends BasicFrameworkAdapter
+public class JsfFrameworkAdapter extends FrameworkAdapter
 {
-	public JsfFrameworkAdapter(String conversationMessager)
+	private final Log log = LogFactory.getLog(JsfFrameworkAdapter.class);
+
+	public JsfFrameworkAdapter(String conversationMessagerClass)
+	{
+		ConversationMessager cm = _FrameworkAdapterUtils.createConversationMessager(conversationMessagerClass,
+				JsfConversationMessager.class);
+		setConversationMessager(cm);
+	}
+
+	public void beginRequest()
 	{
-		super(null, conversationMessager);
+		log.debug("Beginning request");
+		FrameworkAdapter.setCurrentInstance(this);
+	}
+
+	public void endRequest()
+	{
+		log.debug("Ending request");
+		FrameworkAdapter.setCurrentInstance(null);
 	}
 
 	protected ConversationMessager createDefaultConversationMessager()
@@ -47,7 +65,12 @@
 
 	protected FacesContext getFacesContext()
 	{
-		return FacesContext.getCurrentInstance();
+		FacesContext fc = FacesContext.getCurrentInstance();
+		if (fc == null)
+		{
+			throw new OrchestraException("Missing FacesContext");
+		}
+		return fc;
 	}
 
 	public String getInitParameter(String key)
@@ -60,105 +83,55 @@
 	public Object getRequestParameterAttribute(String key)
 	{
 		FacesContext context = getFacesContext();
-		if (context != null)
-		{
-			return context.getExternalContext().getRequestParameterMap().get(key);
-		}
-
-		// Fall back to standard request stuff. Note that this is necessary as this
-		// method might be called before the FacesServletFilter has been run, ie
-		// the FacesContext might not yet exist.
-		return super.getRequestParameterAttribute(key);
+		return context.getExternalContext().getRequestParameterMap().get(key);
 	}
 
 	public boolean containsRequestParameterAttribute(String key)
 	{
 		FacesContext context = getFacesContext();
-		if (context != null)
-		{
-			return context.getExternalContext().getRequestParameterMap().containsKey(key);
-		}
-
-		return super.containsRequestParameterAttribute(key);
+		return context.getExternalContext().getRequestParameterMap().containsKey(key);
 	}
 
 	public Object getRequestAttribute(String key)
 	{
 		FacesContext context = getFacesContext();
-		if (context != null)
-		{
-			return context.getExternalContext().getRequestMap().get(key);
-		}
-
-		return super.getRequestAttribute(key);
+		return context.getExternalContext().getRequestMap().get(key);
 	}
 
 	public void setRequestAttribute(String key, Object value)
 	{
 		FacesContext context = getFacesContext();
-		if (context != null)
-		{
-			context.getExternalContext().getRequestMap().put(key, value);
-			return;
-		}
-
-		super.setRequestAttribute(key, value);
+		context.getExternalContext().getRequestMap().put(key, value);
 	}
 
 	public boolean containsRequestAttribute(String key)
 	{
 		FacesContext context = getFacesContext();
-		if (context != null)
-		{
-			return context.getExternalContext().getRequestMap().containsKey(key);
-		}
-
-		return super.containsRequestAttribute(key);
+		return context.getExternalContext().getRequestMap().containsKey(key);
 	}
 
 	public Object getSessionAttribute(String key)
 	{
 		FacesContext context = getFacesContext();
-		if (context != null)
-		{
-			return context.getExternalContext().getSessionMap().get(key);
-		}
-
-		return super.getSessionAttribute(key);
+		return context.getExternalContext().getSessionMap().get(key);
 	}
 
 	public void setSessionAttribute(String key, Object value)
 	{
 		FacesContext context = getFacesContext();
-		if (context != null)
-		{
-			context.getExternalContext().getSessionMap().put(key, value);
-			return;
-		}
-
-		super.setSessionAttribute(key, value);
+		context.getExternalContext().getSessionMap().put(key, value);
 	}
 
 	public boolean containsSessionAttribute(String key)
 	{
 		FacesContext context = getFacesContext();
-		if (context != null)
-		{
-			return context.getExternalContext().getSessionMap().containsKey(key);
-		}
-
-		return super.containsSessionAttribute(key);
+		return context.getExternalContext().getSessionMap().containsKey(key);
 	}
 
 	protected String getRequestContextPath()
 	{
 		FacesContext context = getFacesContext();
-		if (context != null)
-		{
-			return context.getExternalContext().getRequestContextPath();
-		}
-
-		return super.getRequestContextPath();
+		return context.getExternalContext().getRequestContextPath();
 	}
 
 	public void redirect(String url) throws IOException

Modified: myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/frameworkAdapter/jsf/JsfFrameworkAdapterFilter.java
URL: http://svn.apache.org/viewvc/myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/frameworkAdapter/jsf/JsfFrameworkAdapterFilter.java?rev=619486&r1=619485&r2=619486&view=diff
==============================================================================
--- myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/frameworkAdapter/jsf/JsfFrameworkAdapterFilter.java (original)
+++ myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/frameworkAdapter/jsf/JsfFrameworkAdapterFilter.java Thu Feb  7 08:31:20 2008
@@ -45,6 +45,11 @@
  * passed to the BasicFrameworkAdapter, meaning that this can be either a 
  * beanname defined in the dependency-injection framework, or an absolute
  * classname of a type implementing ConversationMessager.
+ * <p>
+ * Note that this class is generally only needed in Orchestra 1.0. In later 
+ * releases the OrchestraFacesContextFactory configures the JsfFrameworkAdapter
+ * instead, requiring less configuration. However this class can be used if the
+ * OrchestraFacesContextFactory approach cannot be used for some reason.
  */
 public class JsfFrameworkAdapterFilter implements Filter
 {
@@ -65,7 +70,7 @@
 		log.debug("doFilter");
 		try
 		{
-			adapter.beginRequest(req, rsp);
+			adapter.beginRequest();
 			filterChain.doFilter(req, rsp);
 		}
 		finally

Added: myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/lib/jsf/ContextLockRequestHandler.java
URL: http://svn.apache.org/viewvc/myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/lib/jsf/ContextLockRequestHandler.java?rev=619486&view=auto
==============================================================================
--- myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/lib/jsf/ContextLockRequestHandler.java (added)
+++ myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/lib/jsf/ContextLockRequestHandler.java Thu Feb  7 08:31:20 2008
@@ -0,0 +1,72 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.orchestra.lib.jsf;
+
+import javax.faces.FacesException;
+
+import org.apache.myfaces.orchestra.conversation.ConversationContext;
+import org.apache.myfaces.orchestra.conversation.ConversationManager;
+
+/**
+ * RequestHandler that ensures that only one thread is processing
+ * each ConversationContext at a time.
+ */
+class ContextLockRequestHandler implements RequestHandler
+{
+	boolean serializeRequests;
+	ConversationContext context;
+
+	public ContextLockRequestHandler(boolean serializeRequests)
+	{
+		this.serializeRequests = serializeRequests;
+	}
+
+	public void init() throws FacesException
+	{
+		if (serializeRequests)
+		{
+			// Note that ConversationManager.getInstance requires the FrameworkAdapter
+			// to be initialised...
+			//
+			// ?? Why is false passed here ??
+			ConversationManager manager = ConversationManager.getInstance(false);
+			if (manager != null)
+			{
+				context = manager.getCurrentConversationContext();
+				try
+				{
+					context.lockInterruptablyForCurrentThread();
+				}
+				catch(InterruptedException e)
+				{
+					throw new FacesException(e);
+				}
+			}
+		}
+	}
+
+	public void deinit() throws FacesException
+	{
+		if (context != null)
+		{
+			context.unlockForCurrentThread();
+		}
+	}
+}
+

Added: myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/lib/jsf/ConversationManagerRequestHandler.java
URL: http://svn.apache.org/viewvc/myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/lib/jsf/ConversationManagerRequestHandler.java?rev=619486&view=auto
==============================================================================
--- myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/lib/jsf/ConversationManagerRequestHandler.java (added)
+++ myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/lib/jsf/ConversationManagerRequestHandler.java Thu Feb  7 08:31:20 2008
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.orchestra.lib.jsf;
+
+import javax.faces.FacesException;
+
+import org.apache.myfaces.orchestra.conversation.ConversationManager;
+
+/**
+ * RequestHandler that simply ensures that a ConversationManager exists
+ * for the current user at the start of a request.
+ */
+class ConversationManagerRequestHandler implements RequestHandler
+{
+	public void init() throws FacesException
+	{
+		ConversationManager.getInstance();
+	}
+
+	public void deinit() throws FacesException
+	{
+	}
+}
+

Added: myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/lib/jsf/DataSourceLeakRequestHandler.java
URL: http://svn.apache.org/viewvc/myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/lib/jsf/DataSourceLeakRequestHandler.java?rev=619486&view=auto
==============================================================================
--- myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/lib/jsf/DataSourceLeakRequestHandler.java (added)
+++ myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/lib/jsf/DataSourceLeakRequestHandler.java Thu Feb  7 08:31:20 2008
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.orchestra.lib.jsf;
+
+import javax.faces.FacesException;
+
+import org.apache.myfaces.orchestra.connectionManager.ConnectionManagerDataSource;
+
+/**
+ * RequestHandler that ensures that any jdbc connections allocated during
+ * the course of this request are freed at the end.
+ */
+class DataSourceLeakRequestHandler implements RequestHandler
+{
+	public void init() throws FacesException
+	{
+	}
+
+	public void deinit() throws FacesException
+	{
+		ConnectionManagerDataSource.releaseAllBorrowedConnections();
+	}
+}
+

Added: myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/lib/jsf/FrameworkAdapterRequestHandler.java
URL: http://svn.apache.org/viewvc/myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/lib/jsf/FrameworkAdapterRequestHandler.java?rev=619486&view=auto
==============================================================================
--- myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/lib/jsf/FrameworkAdapterRequestHandler.java (added)
+++ myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/lib/jsf/FrameworkAdapterRequestHandler.java Thu Feb  7 08:31:20 2008
@@ -0,0 +1,67 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.orchestra.lib.jsf;
+
+import javax.faces.FacesException;
+import javax.faces.context.FacesContext;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.myfaces.orchestra.frameworkAdapter.FrameworkAdapter;
+import org.apache.myfaces.orchestra.frameworkAdapter.jsf.JsfFrameworkAdapter;
+
+/**
+ * RequestHandler that ensures that the FrameworkAdapter is initialised as a JsfFrameworkAdapter.
+ */
+class FrameworkAdapterRequestHandler implements RequestHandler
+{
+	private final static String CONVERSATION_MESSAGER_CLASS = "org.apache.myfaces.orchestra.CONVERSATION_MESSAGER"; // NON-NLS
+
+	private final Log log = LogFactory.getLog(FrameworkAdapterRequestHandler.class);
+
+	private FacesContext facesContext;
+	private JsfFrameworkAdapter adapter;
+
+	public FrameworkAdapterRequestHandler(FacesContext facesContext)
+	{
+		this.facesContext = facesContext;
+	}
+
+	public void init() throws FacesException
+	{
+		log.debug("init");
+		if (FrameworkAdapter.getCurrentInstance() == null)
+		{
+			log.debug("creating jsfFrameworkAdapter");
+			// No filter has yet initialised the adapter, so do it here.
+			String conversationMessagerClass = facesContext.getExternalContext().getInitParameter(
+					CONVERSATION_MESSAGER_CLASS);
+			adapter = new JsfFrameworkAdapter(conversationMessagerClass);
+			adapter.beginRequest();
+		}
+	}
+
+	public void deinit() throws FacesException
+	{
+		if (adapter != null)
+		{
+			adapter.endRequest();
+		}
+	}
+}
\ No newline at end of file

Modified: myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/lib/jsf/OrchestraFacesContextFactory.java
URL: http://svn.apache.org/viewvc/myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/lib/jsf/OrchestraFacesContextFactory.java?rev=619486&r1=619485&r2=619486&view=diff
==============================================================================
--- myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/lib/jsf/OrchestraFacesContextFactory.java (original)
+++ myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/lib/jsf/OrchestraFacesContextFactory.java Thu Feb  7 08:31:20 2008
@@ -18,14 +18,17 @@
  */
 package org.apache.myfaces.orchestra.lib.jsf;
 
-import org.apache.myfaces.orchestra.frameworkAdapter.FrameworkAdapter;
-import org.apache.myfaces.orchestra.frameworkAdapter.jsf.JsfFrameworkAdapter;
+import java.util.LinkedList;
+import java.util.ListIterator;
 
 import javax.faces.FacesException;
 import javax.faces.context.FacesContext;
 import javax.faces.context.FacesContextFactory;
 import javax.faces.lifecycle.Lifecycle;
 
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
 /**
  * Setup some aspects of the Orchestra framework whenever a JSF request is being processed.
  * <p>
@@ -47,37 +50,90 @@
  */
 public class OrchestraFacesContextFactory extends FacesContextFactory
 {
-	private final static String INIT_CONVERSATION_MESSAGER = "org.apache.myfaces.orchestra.CONVERSATION_MESSAGER"; // NON-NLS
-
+	private final Log log = LogFactory.getLog(OrchestraFacesContextFactory.class);
 	private final FacesContextFactory original;
 
 	public OrchestraFacesContextFactory(FacesContextFactory original)
 	{
 		this.original = original;
 	}
-
-	public FacesContext getFacesContext(Object context, Object request, Object response, Lifecycle lifecycle) throws FacesException
+	
+	public FacesContext getFacesContext(
+			final Object context, 
+			final Object request, 
+			final Object response, 
+			final Lifecycle lifecycle) throws FacesException
 	{
-		FacesContext facesContext = original.getFacesContext(context, request, response, lifecycle);
-
-		if (facesContext != null && FrameworkAdapter.getCurrentInstance() == null)
+		log.debug("getFacesContext: entry");
+		final FacesContext facesContext = original.getFacesContext(context, request, response, lifecycle);
+		if (facesContext == null)
 		{
-			String conversationMessager = facesContext.getExternalContext().getInitParameter(INIT_CONVERSATION_MESSAGER);
-			FrameworkAdapter.setCurrentInstance(new JsfFrameworkAdapter(conversationMessager));
+			// should not happen
+			return null;
+		}
+
+		// TODO: make this handlers list configurable
+		final LinkedList handlers = new LinkedList();
+		handlers.add(new ContextLockRequestHandler(true));
+		handlers.add(new FrameworkAdapterRequestHandler(facesContext));
+		handlers.add(new ConversationManagerRequestHandler());
+		handlers.add(new DataSourceLeakRequestHandler());
 
-			FacesContext wrappedFacesContext = new FacesContextWrapper(facesContext)
+		log.debug("getFacesContext: creating custom instance");
+		return new FacesContextWrapper(facesContext)
+		{
+			// Constructor...
 			{
-				public void release()
+				log.debug("getFacesContext: running inner constructor");
+				ListIterator i = handlers.listIterator();
+				try
 				{
-					super.release();
+					while(i.hasNext())
+					{
+						RequestHandler h = (RequestHandler) i.next();
+						
+						if (log.isDebugEnabled())
+						{
+							log.debug("Running inithandler of type " + i.getClass().getName());
+						}
 
-					FrameworkAdapter.setCurrentInstance(null);
+						h.init();
+					}
 				}
-			};
-
-			facesContext = wrappedFacesContext;
-		}
+				catch(RuntimeException e)
+				{
+					_release(i);
+					throw e;
+				}
+			}
 
-		return facesContext;
+			public void release()
+			{
+				log.debug("Running release");
+				super.release();
+				ListIterator i = handlers.listIterator();
+				// ecch, wind forward to end of list.
+				while (i.hasNext()) i.next();
+				_release(i);
+			}
+			
+			private void _release(ListIterator i)
+			{
+				while (i.hasPrevious())
+				{
+					try
+					{
+						RequestHandler h = (RequestHandler) i.previous();
+						h.deinit();
+					}
+					catch(Exception e)
+					{
+						// ignore errors, so we always deinitialise anything
+						// that we initialised.
+						log.error("Problem deinitialising RequestHandler", e);
+					}
+				}
+			}
+		};
 	}
 }

Added: myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/lib/jsf/RequestHandler.java
URL: http://svn.apache.org/viewvc/myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/lib/jsf/RequestHandler.java?rev=619486&view=auto
==============================================================================
--- myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/lib/jsf/RequestHandler.java (added)
+++ myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/lib/jsf/RequestHandler.java Thu Feb  7 08:31:20 2008
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.orchestra.lib.jsf;
+
+import javax.faces.FacesException;
+
+/**
+ * An interface for classes that want to be run at the start and end
+ * of each jsf request.
+ */
+interface RequestHandler
+{
+	void init() throws FacesException;
+	void deinit() throws FacesException;
+}