[jboss-svn-commits] JBoss Common SVN: r4493 - in arquillian/trunk/frameworks/jsfunit/src/main/java/org/jboss/jsfunit: context and 1 other directory.

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Fri Jun 11 08:19:19 EDT 2010


Author: aslak
Date: 2010-06-11 08:19:19 -0400 (Fri, 11 Jun 2010)
New Revision: 4493

Added:
   arquillian/trunk/frameworks/jsfunit/src/main/java/org/jboss/jsfunit/context/
   arquillian/trunk/frameworks/jsfunit/src/main/java/org/jboss/jsfunit/context/JSFUnitFacesContext.java
Log:
ARQ-172 Added patched v. of JSFUnitFacesContext in Arquillian-JSFUnit for integration testing. Temporary local fix until JSFUNIT-253 is resolved.


Added: arquillian/trunk/frameworks/jsfunit/src/main/java/org/jboss/jsfunit/context/JSFUnitFacesContext.java
===================================================================
--- arquillian/trunk/frameworks/jsfunit/src/main/java/org/jboss/jsfunit/context/JSFUnitFacesContext.java	                        (rev 0)
+++ arquillian/trunk/frameworks/jsfunit/src/main/java/org/jboss/jsfunit/context/JSFUnitFacesContext.java	2010-06-11 12:19:19 UTC (rev 4493)
@@ -0,0 +1,401 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2007, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file 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.jsfunit.context;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import javax.el.ELContext;
+import javax.faces.application.Application;
+import javax.faces.application.FacesMessage;
+import javax.faces.application.ProjectStage;
+import javax.faces.component.UIViewRoot;
+import javax.faces.context.ExceptionHandler;
+import javax.faces.context.ExternalContext;
+import javax.faces.context.FacesContext;
+import javax.faces.context.PartialViewContext;
+import javax.faces.context.ResponseStream;
+import javax.faces.context.ResponseWriter;
+import javax.faces.event.PhaseId;
+import javax.faces.render.RenderKit;
+import javax.servlet.http.HttpSessionBindingEvent;
+import javax.servlet.http.HttpSessionBindingListener;
+
+/**
+ * This class is a wrapper for the "real" FacesContext.
+ *
+ * @author Stan Silvert
+ * @since 1.0
+ */
+public class JSFUnitFacesContext extends FacesContext implements HttpSessionBindingListener, Serializable
+{
+   public static final String SESSION_KEY = JSFUnitFacesContext.class.getName() + ".sessionkey";
+   
+   // This is the wrapped FacesContext instance.
+   private FacesContext delegate;
+   
+   // initialized after the JSF lifecycle is over
+   private ExternalContext extContext = null;
+
+   // Must save FacesMessages for use when request is over: JSFUNIT-82
+   private List<FacesMessage> allMessages = new ArrayList<FacesMessage>();
+   private Map<String, List<FacesMessage>> messagesByClientId = new HashMap<String, List<FacesMessage>>();
+   
+   public JSFUnitFacesContext(FacesContext delegate)
+   {
+      if (delegate == null) throw new NullPointerException("delegate can not be null.");
+      
+      this.delegate = delegate;
+      setCurrentInstance(this);
+   }
+
+   @Override
+   public boolean isProjectStage(ProjectStage projectStage)
+   {
+      return delegate.isProjectStage(projectStage);
+   }
+   
+   @Override
+   public Iterator getMessages(String clientId)
+   {
+      if (!isJSFRequestDone()) return delegate.getMessages(clientId);
+      
+      List<FacesMessage> messages = this.messagesByClientId.get(clientId);
+      if (messages == null) return new ArrayList().iterator();
+      
+      return messages.iterator();
+   }
+   
+   @Override
+   public void addMessage(String clientId, FacesMessage facesMessage)
+   {
+      delegate.addMessage(clientId, facesMessage);
+      
+      // save FacesMessages for when the request is done
+      this.allMessages.add(facesMessage);
+      List<FacesMessage> messageList = messagesByClientId.get(clientId);
+      if (messageList == null) messageList = new ArrayList<FacesMessage>();
+      messageList.add(facesMessage);
+      messagesByClientId.put(clientId, messageList);
+   }
+   
+   @Override
+   public void setResponseWriter(ResponseWriter responseWriter)
+   {
+      delegate.setResponseWriter(responseWriter);
+   }
+   
+   @Override
+   public void setResponseStream(ResponseStream responseStream)
+   {
+      delegate.setResponseStream(responseStream);
+   }
+   
+   @Override
+   public void setViewRoot(UIViewRoot uIViewRoot)
+   {
+      delegate.setViewRoot(uIViewRoot);
+   }
+   
+   @Override
+   public void responseComplete()
+   {
+      delegate.responseComplete();
+   }
+   
+   @Override
+   public void renderResponse()
+   {
+      delegate.renderResponse();
+   }
+   
+   @Override
+   public Application getApplication()
+   {
+      return delegate.getApplication();
+   }
+   
+   @Override
+   public Iterator getClientIdsWithMessages()
+   {
+      return delegate.getClientIdsWithMessages();
+   }
+   
+   @Override
+   public ExternalContext getExternalContext()
+   {
+      if (!isJSFRequestDone())
+      {
+         return new JSFUnitDelegatingExternalContext(delegate.getExternalContext());
+      }
+      
+      return this.extContext;
+   }
+   
+   @Override
+   public FacesMessage.Severity getMaximumSeverity()
+   {
+      return delegate.getMaximumSeverity();
+   }
+   
+   @Override
+   public Iterator getMessages()
+   {
+      if (!isJSFRequestDone()) return delegate.getMessages();
+      
+      return this.allMessages.iterator();
+   }
+   
+   @Override
+   public RenderKit getRenderKit()
+   {
+      return delegate.getRenderKit();
+   }
+   
+   @Override
+   public boolean getRenderResponse()
+   {
+      return delegate.getRenderResponse();
+   }
+   
+   @Override
+   public boolean getResponseComplete()
+   {
+      return delegate.getResponseComplete();
+   }
+   
+   @Override
+   public ResponseStream getResponseStream()
+   {
+      return delegate.getResponseStream();
+   }
+   
+   @Override
+   public ResponseWriter getResponseWriter()
+   {
+      return delegate.getResponseWriter();
+   }
+   
+   @Override
+   public UIViewRoot getViewRoot()
+   {
+      return delegate.getViewRoot();
+   }
+   
+   /**
+    * This is called when the JSF lifecycle is over.  After this is called,
+    * most operations will still delegate to the wrapped FacesContext, but
+    * the ExternalContext will be replaced with a JSFUnitExternalContext.
+    *
+    * This method does not call release() on the wrapped FacesContext.  So, all
+    * of its state is retained for use by JSFUnit tests.
+    */
+   @Override
+   public void release()
+   {
+      // Make the FacesContext available to JSFUnit, if and only if a new
+      // page was rendered.
+      if (!viewHasChildren())
+      {
+         cleanUp();
+         return;
+      }
+      
+      ExternalContext extCtx = delegate.getExternalContext();
+      this.extContext = new JSFUnitExternalContext(extCtx);
+      extCtx.getSessionMap().put(SESSION_KEY, this);
+      
+      // Clean local Thread variable to prevent leak on the HTTP Threads. 
+      setCurrentInstance(null);
+   }
+   
+   //-------- JSF 2.0 -----------------------------------------
+   @Override
+   public Map<Object, Object> getAttributes() 
+   {
+      return this.delegate.getAttributes();
+   }
+
+   @Override
+   public PhaseId getCurrentPhaseId() 
+   {
+      return this.delegate.getCurrentPhaseId();
+   }
+
+   @Override
+   public boolean isPostback() 
+   {
+      return this.delegate.isPostback();
+   }
+
+   @Override
+   public void setCurrentPhaseId(PhaseId phaseId) 
+   {
+      this.delegate.setCurrentPhaseId(phaseId);
+   }
+
+   @Override
+   public ExceptionHandler getExceptionHandler()
+   {
+      return delegate.getExceptionHandler();
+   }
+
+   @Override
+   public List<FacesMessage> getMessageList()
+   {
+      return delegate.getMessageList();
+   }
+
+   @Override
+   public List<FacesMessage> getMessageList(String clientId)
+   {
+      return delegate.getMessageList(clientId);
+   }
+
+   @Override
+   public PartialViewContext getPartialViewContext()
+   {
+      return delegate.getPartialViewContext();
+   }
+
+   @Override
+   public boolean isProcessingEvents()
+   {
+      return delegate.isProcessingEvents();
+   }
+
+   @Override
+   public boolean isValidationFailed()
+   {
+      return delegate.isValidationFailed();
+   }
+
+   @Override
+   public void setExceptionHandler(ExceptionHandler exceptionHandler)
+   {
+      delegate.setExceptionHandler(exceptionHandler);
+   }
+
+   @Override
+   public void setProcessingEvents(boolean processingEvents)
+   {
+      delegate.setProcessingEvents(processingEvents);
+   }
+
+   @Override
+   public void validationFailed()
+   {
+      delegate.validationFailed();
+   }
+
+      
+   //-----End JSF 2.0 Methods-----------------------------------------------------
+   private boolean viewHasChildren()
+   {
+      UIViewRoot viewRoot = getViewRoot();
+      return (viewRoot != null) && (viewRoot.getChildCount() != 0);
+   }
+   
+   /**
+    * This allows the FacesContextBridge to associate the JSFUnitFacesContext
+    * with the thread running the tests.
+    */
+   public void setInstanceToJSFUnitThread()
+   {
+      setCurrentInstance(this);
+   }
+   
+   public boolean isJSFRequestDone()
+   {
+      return this.extContext != null;
+   }
+   
+   @Override
+   public ELContext getELContext()
+   {
+      ELContext elContext = delegate.getELContext();
+      
+      // if JSF lifecycle is over we are using the JSFUnitFacesContext
+      // instead of the delegate.  So we need to replace it in ELContext
+      if (isJSFRequestDone())
+      {
+         elContext.putContext(FacesContext.class, this);
+      }
+      
+      return elContext;
+   }
+   
+   /**
+    * This static method will attempt to clean up any FacesContext that is
+    * associated with the current thread.
+    */
+   public static void cleanUpOldFacesContext()
+   {
+      FacesContext facesContext = FacesContext.getCurrentInstance();
+      if (facesContext == null) return;
+      
+      if (facesContext instanceof JSFUnitFacesContext)
+      {
+         JSFUnitFacesContext ctx = (JSFUnitFacesContext)facesContext;
+         ctx.cleanUp();
+      } else {
+         facesContext.release();
+      }
+   }
+   
+   private synchronized void cleanUp()
+   {
+      try
+      {
+         delegate.release();
+      }
+      catch (Exception e)
+      {
+         // ignore - best effort to clean up delegate
+      }
+      finally
+      {
+         setCurrentInstance(null);
+      }
+   }
+   
+   /**
+    * Attempt to clean up the previous FacesContext.
+    */
+   //@Override
+   public void valueUnbound(HttpSessionBindingEvent httpSessionBindingEvent)
+   {
+      cleanUp();
+   }
+   
+   //@Override
+   public void valueBound(HttpSessionBindingEvent httpSessionBindingEvent)
+   {
+      // do nothing
+   }
+   
+}



More information about the jboss-svn-commits mailing list