You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by lu...@apache.org on 2009/08/01 00:55:50 UTC

svn commit: r799765 - in /myfaces/core/trunk: api/src/main/java/javax/faces/context/ impl/src/main/java/org/apache/myfaces/config/ impl/src/main/java/org/apache/myfaces/context/ impl/src/main/java/org/apache/myfaces/context/servlet/

Author: lu4242
Date: Fri Jul 31 22:55:49 2009
New Revision: 799765

URL: http://svn.apache.org/viewvc?rev=799765&view=rev
Log:
MYFACES-2285 Add ExternalContextFactory Implementation

Added:
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/context/ExternalContextFactoryImpl.java   (with props)
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/context/ReleaseableFacesContextFactory.java   (with props)
Modified:
    myfaces/core/trunk/api/src/main/java/javax/faces/context/ExternalContext.java
    myfaces/core/trunk/api/src/main/java/javax/faces/context/FacesContext.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/FacesConfigurator.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/context/FacesContextFactoryImpl.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/context/servlet/FacesContextImpl.java

Modified: myfaces/core/trunk/api/src/main/java/javax/faces/context/ExternalContext.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/api/src/main/java/javax/faces/context/ExternalContext.java?rev=799765&r1=799764&r2=799765&view=diff
==============================================================================
--- myfaces/core/trunk/api/src/main/java/javax/faces/context/ExternalContext.java (original)
+++ myfaces/core/trunk/api/src/main/java/javax/faces/context/ExternalContext.java Fri Jul 31 22:55:49 2009
@@ -39,6 +39,22 @@
     public static final String CLIENT_CERT_AUTH = "CLIENT_CERT";
     public static final String DIGEST_AUTH = "DIGEST";
     public static final String FORM_AUTH = "FORM";
+    
+    /**
+     * This variable holds the firstInstance where all ExternalContext
+     * objects should call when new jsf 2.0 methods are called.
+     * 
+     * This variable is an implementation detail and should be 
+     * initialized and released on FacesContextFactoryImpl (because
+     * this is the place where ExternalContextFactory.getExternalContext()
+     * is called).
+     * 
+     * The objective of this is keep compatibility of libraries that wrap 
+     * ExternalContext objects before 2.0. It is similar as FacesContext._firstInstace,
+     * but since we don't have any place to init and release this variable properly
+     * we should do it using reflection.
+     */
+    private static ThreadLocal<ExternalContext> _firstInstance = new ThreadLocal<ExternalContext>();
 
     /**
      *
@@ -50,7 +66,14 @@
      */
     public void addResponseCookie(String name, String value, Map<String, Object> properties)
     {
-        throw new UnsupportedOperationException();
+        ExternalContext ctx = _firstInstance.get();
+        
+        if (ctx == null)
+        {
+            throw new UnsupportedOperationException();
+        }
+        
+        ctx.addResponseCookie(name, value, properties);
     }
 
     /**
@@ -62,7 +85,14 @@
      */
     public void addResponseHeader(String name, String value)
     {
-        throw new UnsupportedOperationException();
+        ExternalContext ctx = _firstInstance.get();
+        
+        if (ctx == null)
+        {
+            throw new UnsupportedOperationException();
+        }
+        
+        ctx.addResponseHeader(name, value);
     }
 
     public abstract void dispatch(String path) throws IOException;
@@ -78,7 +108,14 @@
      */
     public String encodeBookmarkableURL(String baseUrl, Map<String,List<String>> parameters)
     {
-        throw new UnsupportedOperationException();
+        ExternalContext ctx = _firstInstance.get();
+        
+        if (ctx == null)
+        {
+            throw new UnsupportedOperationException();
+        }
+        
+        return ctx.encodeBookmarkableURL(baseUrl, parameters);
     }
 
     public abstract String encodeNamespace(String name);
@@ -90,7 +127,14 @@
     public String encodePartialActionURL(String url)
     {
         // TODO: IMPLEMENT IMPL
-        throw new UnsupportedOperationException();
+        ExternalContext ctx = _firstInstance.get();
+        
+        if (ctx == null)
+        {
+            throw new UnsupportedOperationException();
+        }
+        
+        return ctx.encodePartialActionURL(url);
     }
 
     /**
@@ -102,7 +146,14 @@
      */
     public String encodeRedirectURL(String baseUrl, Map<String,List<String>> parameters)
     {
-        throw new UnsupportedOperationException();
+        ExternalContext ctx = _firstInstance.get();
+        
+        if (ctx == null)
+        {
+            throw new UnsupportedOperationException();
+        }
+        
+        return ctx.encodeRedirectURL(baseUrl, parameters);
     }
 
     public abstract String encodeResourceURL(String url);
@@ -122,7 +173,14 @@
      */
     public String getContextName()
     {
-        throw new UnsupportedOperationException();
+        ExternalContext ctx = _firstInstance.get();
+        
+        if (ctx == null)
+        {
+            throw new UnsupportedOperationException();
+        }
+        
+        return ctx.getContextName();
     }
 
     /**
@@ -130,7 +188,14 @@
      */
     public Flash getFlash()
     {
-        throw new UnsupportedOperationException();
+        ExternalContext ctx = _firstInstance.get();
+        
+        if (ctx == null)
+        {
+            throw new UnsupportedOperationException();
+        }
+        
+        return ctx.getFlash();
     }
 
     public abstract String getInitParameter(String name);
@@ -143,7 +208,14 @@
      */
     public String getMimeType(String file)
     {
-        throw new UnsupportedOperationException();
+        ExternalContext ctx = _firstInstance.get();
+        
+        if (ctx == null)
+        {
+            throw new UnsupportedOperationException();
+        }
+        
+        return ctx.getMimeType(file);
     }
 
     /**
@@ -151,7 +223,14 @@
      */
     public String getRealPath(String path)
     {
-        throw new UnsupportedOperationException();
+        ExternalContext ctx = _firstInstance.get();
+        
+        if (ctx == null)
+        {
+            throw new UnsupportedOperationException();
+        }
+        
+        return ctx.getRealPath(path);
     }
 
     public abstract String getRemoteUser();
@@ -160,7 +239,14 @@
 
     public String getRequestCharacterEncoding()
     {
-        throw new UnsupportedOperationException();
+        ExternalContext ctx = _firstInstance.get();
+        
+        if (ctx == null)
+        {
+            throw new UnsupportedOperationException();
+        }
+        
+        return ctx.getRequestCharacterEncoding();
     }
 
     /**
@@ -171,12 +257,26 @@
      */
     public int getRequestContentLength()
     {
-        throw new UnsupportedOperationException();
+        ExternalContext ctx = _firstInstance.get();
+        
+        if (ctx == null)
+        {
+            throw new UnsupportedOperationException();
+        }
+        
+        return ctx.getRequestContentLength();
     }
 
     public String getRequestContentType()
     {
-        throw new UnsupportedOperationException();
+        ExternalContext ctx = _firstInstance.get();
+        
+        if (ctx == null)
+        {
+            throw new UnsupportedOperationException();
+        }
+        
+        return ctx.getRequestContentType();
     }
 
     public abstract String getRequestContextPath();
@@ -206,7 +306,14 @@
      */
     public String getRequestScheme()
     {
-        throw new UnsupportedOperationException();
+        ExternalContext ctx = _firstInstance.get();
+        
+        if (ctx == null)
+        {
+            throw new UnsupportedOperationException();
+        }
+        
+        return ctx.getRequestScheme();
     }
 
     /**
@@ -214,7 +321,14 @@
      */
     public String getRequestServerName()
     {
-        throw new UnsupportedOperationException();
+        ExternalContext ctx = _firstInstance.get();
+        
+        if (ctx == null)
+        {
+            throw new UnsupportedOperationException();
+        }
+        
+        return ctx.getRequestServerName();
     }
 
     /**
@@ -222,7 +336,14 @@
      */
     public int getRequestServerPort()
     {
-        throw new UnsupportedOperationException();
+        ExternalContext ctx = _firstInstance.get();
+        
+        if (ctx == null)
+        {
+            throw new UnsupportedOperationException();
+        }
+        
+        return ctx.getRequestServerPort();
     }
 
     public abstract String getRequestServletPath();
@@ -243,12 +364,26 @@
      */
     public int getResponseBufferSize()
     {
-        throw new UnsupportedOperationException();
+        ExternalContext ctx = _firstInstance.get();
+        
+        if (ctx == null)
+        {
+            throw new UnsupportedOperationException();
+        }
+        
+        return ctx.getResponseBufferSize();
     }
 
     public String getResponseCharacterEncoding()
     {
-        throw new UnsupportedOperationException("JSF 1.2 : figure out how to tell if this is a Portlet request");
+        ExternalContext ctx = _firstInstance.get();
+        
+        if (ctx == null)
+        {
+            throw new UnsupportedOperationException("JSF 1.2 : figure out how to tell if this is a Portlet request");
+        }
+        
+        return ctx.getResponseCharacterEncoding();
     }
 
     /**
@@ -258,7 +393,14 @@
      */
     public String getResponseContentType()
     {
-        throw new UnsupportedOperationException();
+        ExternalContext ctx = _firstInstance.get();
+        
+        if (ctx == null)
+        {
+            throw new UnsupportedOperationException();
+        }
+        
+        return ctx.getResponseContentType();
     }
 
     /**
@@ -266,7 +408,14 @@
      */
     public OutputStream getResponseOutputStream() throws IOException
     {
-        throw new UnsupportedOperationException();
+        ExternalContext ctx = _firstInstance.get();
+        
+        if (ctx == null)
+        {
+            throw new UnsupportedOperationException();
+        }
+        
+        return ctx.getResponseOutputStream();
     }
 
     /**
@@ -274,7 +423,14 @@
      */
     public Writer getResponseOutputWriter() throws IOException
     {
-        throw new UnsupportedOperationException();
+        ExternalContext ctx = _firstInstance.get();
+        
+        if (ctx == null)
+        {
+            throw new UnsupportedOperationException();
+        }
+        
+        return ctx.getResponseOutputWriter();
     }
 
     public abstract Object getSession(boolean create);
@@ -288,7 +444,14 @@
      */
     public void invalidateSession()
     {
-        throw new UnsupportedOperationException();
+        ExternalContext ctx = _firstInstance.get();
+        
+        if (ctx == null)
+        {
+            throw new UnsupportedOperationException();
+        }
+        
+        ctx.invalidateSession();
     }
 
     /**
@@ -296,7 +459,14 @@
      */
     public boolean isResponseCommitted()
     {
-        throw new UnsupportedOperationException();
+        ExternalContext ctx = _firstInstance.get();
+        
+        if (ctx == null)
+        {
+            throw new UnsupportedOperationException();
+        }
+        
+        return ctx.isResponseCommitted();
     }
 
     public abstract boolean isUserInRole(String role);
@@ -321,7 +491,14 @@
      */
     public void responseFlushBuffer() throws IOException
     {
-        throw new UnsupportedOperationException();
+        ExternalContext ctx = _firstInstance.get();
+        
+        if (ctx == null)
+        {
+            throw new UnsupportedOperationException();
+        }
+        
+        ctx.responseFlushBuffer();
     }
 
     /**
@@ -330,7 +507,14 @@
      */
     public void responseReset()
     {
-        throw new UnsupportedOperationException();
+        ExternalContext ctx = _firstInstance.get();
+        
+        if (ctx == null)
+        {
+            throw new UnsupportedOperationException();
+        }
+        
+        ctx.responseReset();
     }
 
     /**
@@ -343,7 +527,14 @@
      */
     public void responseSendError(int statusCode, String message) throws IOException
     {
-        throw new UnsupportedOperationException();
+        ExternalContext ctx = _firstInstance.get();
+        
+        if (ctx == null)
+        {
+            throw new UnsupportedOperationException();
+        }
+        
+        ctx.responseSendError(statusCode, message);
     }
 
     /**
@@ -354,7 +545,14 @@
      */
     public void setRequest(Object request)
     {
-        throw new UnsupportedOperationException();
+        ExternalContext ctx = _firstInstance.get();
+        
+        if (ctx == null)
+        {
+            throw new UnsupportedOperationException();
+        }
+        
+        ctx.setRequest(request);
     }
 
     /**
@@ -366,7 +564,14 @@
      */
     public void setRequestCharacterEncoding(String encoding) throws java.io.UnsupportedEncodingException
     {
-        throw new UnsupportedOperationException();
+        ExternalContext ctx = _firstInstance.get();
+        
+        if (ctx == null)
+        {
+            throw new UnsupportedOperationException();
+        }
+        
+        ctx.setRequestCharacterEncoding(encoding);
     }
 
     /**
@@ -377,7 +582,14 @@
      */
     public void setResponse(Object response)
     {
-        throw new UnsupportedOperationException();
+        ExternalContext ctx = _firstInstance.get();
+        
+        if (ctx == null)
+        {
+            throw new UnsupportedOperationException();
+        }
+        
+        ctx.setResponse(response);
     }
 
     /**
@@ -388,7 +600,14 @@
      */
     public void setResponseBufferSize(int size)
     {
-        throw new UnsupportedOperationException();
+        ExternalContext ctx = _firstInstance.get();
+        
+        if (ctx == null)
+        {
+            throw new UnsupportedOperationException();
+        }
+        
+        ctx.setResponseBufferSize(size);
     }
 
     /**
@@ -399,7 +618,14 @@
      */
     public void setResponseCharacterEncoding(String encoding)
     {
-        throw new UnsupportedOperationException();
+        ExternalContext ctx = _firstInstance.get();
+        
+        if (ctx == null)
+        {
+            throw new UnsupportedOperationException();
+        }
+        
+        ctx.setResponseCharacterEncoding(encoding);
     }
 
     /**
@@ -410,7 +636,14 @@
      */
     public void setResponseContentLength(int length)
     {
-        throw new UnsupportedOperationException();
+        ExternalContext ctx = _firstInstance.get();
+        
+        if (ctx == null)
+        {
+            throw new UnsupportedOperationException();
+        }
+        
+        ctx.setResponseContentLength(length);
     }
 
     /**
@@ -421,7 +654,14 @@
      */
     public void setResponseContentType(String contentType)
     {
-        throw new UnsupportedOperationException();
+        ExternalContext ctx = _firstInstance.get();
+        
+        if (ctx == null)
+        {
+            throw new UnsupportedOperationException();
+        }
+        
+        ctx.setResponseContentType(contentType);
     }
 
     /**
@@ -433,7 +673,14 @@
      */
     public void setResponseHeader(String name, String value)
     {
-        throw new UnsupportedOperationException();
+        ExternalContext ctx = _firstInstance.get();
+        
+        if (ctx == null)
+        {
+            throw new UnsupportedOperationException();
+        }
+        
+        ctx.setResponseHeader(name, value);
     }
 
     /**
@@ -444,6 +691,13 @@
      */
     public void setResponseStatus(int statusCode)
     {
-        throw new UnsupportedOperationException();
+        ExternalContext ctx = _firstInstance.get();
+        
+        if (ctx == null)
+        {
+            throw new UnsupportedOperationException();
+        }
+        
+        ctx.setResponseStatus(statusCode);
     }
 }

Modified: myfaces/core/trunk/api/src/main/java/javax/faces/context/FacesContext.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/api/src/main/java/javax/faces/context/FacesContext.java?rev=799765&r1=799764&r2=799765&view=diff
==============================================================================
--- myfaces/core/trunk/api/src/main/java/javax/faces/context/FacesContext.java (original)
+++ myfaces/core/trunk/api/src/main/java/javax/faces/context/FacesContext.java Fri Jul 31 22:55:49 2009
@@ -54,7 +54,14 @@
      */
     public Map<Object, Object> getAttributes()
     {
-        throw new UnsupportedOperationException();
+        FacesContext ctx = _firstInstance.get();
+        
+        if (ctx == null)
+        {
+            throw new UnsupportedOperationException();
+        }
+        
+        return ctx.getAttributes();
     }
 
     public abstract Iterator<String> getClientIdsWithMessages();
@@ -72,7 +79,14 @@
      */
     public PhaseId getCurrentPhaseId()
     {
-        throw new UnsupportedOperationException();
+        FacesContext ctx = _firstInstance.get();
+        
+        if (ctx == null)
+        {
+            throw new UnsupportedOperationException();
+        }
+        
+        return ctx.getCurrentPhaseId();
     }
     
     /**
@@ -139,7 +153,14 @@
      */
     public ExceptionHandler getExceptionHandler()
     {
-        throw new UnsupportedOperationException();
+        FacesContext ctx = _firstInstance.get();
+        
+        if (ctx == null)
+        {
+            throw new UnsupportedOperationException();
+        }
+        
+        return ctx.getExceptionHandler();
     }
 
     public abstract ExternalContext getExternalContext();
@@ -154,7 +175,14 @@
      */
     public List<FacesMessage> getMessageList()
     {
-        throw new UnsupportedOperationException();
+        FacesContext ctx = _firstInstance.get();
+        
+        if (ctx == null)
+        {
+            throw new UnsupportedOperationException();
+        }
+        
+        return ctx.getMessageList();
     }
     
     /**
@@ -166,7 +194,14 @@
      */
     public List<FacesMessage> getMessageList(String clientId)
     {
-        throw new UnsupportedOperationException();
+        FacesContext ctx = _firstInstance.get();
+        
+        if (ctx == null)
+        {
+            throw new UnsupportedOperationException();
+        }
+        
+        return ctx.getMessageList(clientId);
     }
 
     public abstract Iterator<FacesMessage> getMessages();
@@ -189,7 +224,14 @@
      */
     public PartialViewContext getPartialViewContext()
     {
-        throw new UnsupportedOperationException();
+        FacesContext ctx = _firstInstance.get();
+        
+        if (ctx == null)
+        {
+            throw new UnsupportedOperationException();
+        }
+        
+        return ctx.getPartialViewContext();
     }
 
     public abstract RenderKit getRenderKit();
@@ -210,7 +252,14 @@
      */
     public boolean isValidationFailed()
     {
-        throw new UnsupportedOperationException();
+        FacesContext ctx = _firstInstance.get();
+        
+        if (ctx == null)
+        {
+            throw new UnsupportedOperationException();
+        }
+        
+        return ctx.isValidationFailed();
     }
 
     public abstract UIViewRoot getViewRoot();
@@ -223,7 +272,14 @@
      */
     public boolean isPostback()
     {
-        throw new UnsupportedOperationException();
+        FacesContext ctx = _firstInstance.get();
+        
+        if (ctx == null)
+        {
+            throw new UnsupportedOperationException();
+        }
+        
+        return ctx.isPostback();
     }
     
     /**
@@ -234,7 +290,14 @@
      */
     public boolean isProcessingEvents()
     {
-        throw new UnsupportedOperationException();
+        FacesContext ctx = _firstInstance.get();
+        
+        if (ctx == null)
+        {
+            throw new UnsupportedOperationException();
+        }
+        
+        return ctx.isProcessingEvents();
     }
 
     public abstract void release();
@@ -269,7 +332,14 @@
      */
     public void setCurrentPhaseId(PhaseId currentPhaseId)
     {
-        throw new UnsupportedOperationException();
+        FacesContext ctx = _firstInstance.get();
+        
+        if (ctx == null)
+        {
+            throw new UnsupportedOperationException();
+        }
+        
+        ctx.setCurrentPhaseId(currentPhaseId);
     }
 
     /**
@@ -280,7 +350,14 @@
      */
     public void setExceptionHandler(ExceptionHandler exceptionHandler)
     {
-        throw new UnsupportedOperationException();
+        FacesContext ctx = _firstInstance.get();
+        
+        if (ctx == null)
+        {
+            throw new UnsupportedOperationException();
+        }
+        
+        ctx.setExceptionHandler(exceptionHandler);
     }
     
     /**
@@ -291,7 +368,14 @@
      */
     public void setProcessingEvents(boolean processingEvents)
     {
-        throw new UnsupportedOperationException();
+        FacesContext ctx = _firstInstance.get();
+        
+        if (ctx == null)
+        {
+            throw new UnsupportedOperationException();
+        }
+        
+        ctx.setProcessingEvents(processingEvents);
     }
 
     public abstract void setResponseStream(ResponseStream responseStream);
@@ -307,7 +391,14 @@
      */
     public void validationFailed()
     {
-        throw new UnsupportedOperationException();
+        FacesContext ctx = _firstInstance.get();
+        
+        if (ctx == null)
+        {
+            throw new UnsupportedOperationException();
+        }
+        
+        ctx.validationFailed();
     }
     
     public boolean isProjectStage(ProjectStage stage)

Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/FacesConfigurator.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/FacesConfigurator.java?rev=799765&r1=799764&r2=799765&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/FacesConfigurator.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/FacesConfigurator.java Fri Jul 31 22:55:49 2009
@@ -87,6 +87,7 @@
 import org.apache.myfaces.config.impl.digester.elements.ResourceBundle;
 import org.apache.myfaces.config.impl.digester.elements.SystemEventListener;
 import org.apache.myfaces.context.ExceptionHandlerFactoryImpl;
+import org.apache.myfaces.context.ExternalContextFactoryImpl;
 import org.apache.myfaces.context.FacesContextFactoryImpl;
 import org.apache.myfaces.context.PartialViewContextFactoryImpl;
 import org.apache.myfaces.el.DefaultPropertyResolver;
@@ -125,6 +126,7 @@
 
     private static final String DEFAULT_RENDER_KIT_CLASS = HtmlRenderKitImpl.class.getName();
     private static final String DEFAULT_APPLICATION_FACTORY = ApplicationFactoryImpl.class.getName();
+    private static final String DEFAULT_EXTERNAL_CONTEXT_FACTORY = ExternalContextFactoryImpl.class.getName();
     private static final String DEFAULT_FACES_CONTEXT_FACTORY = FacesContextFactoryImpl.class.getName();
     private static final String DEFAULT_LIFECYCLE_FACTORY = LifecycleFactoryImpl.class.getName();
     private static final String DEFAULT_RENDER_KIT_FACTORY = RenderKitFactoryImpl.class.getName();
@@ -137,13 +139,14 @@
     private static final Set<String> FACTORY_NAMES = new HashSet<String>();
     {
         FACTORY_NAMES.add(FactoryFinder.APPLICATION_FACTORY);
+        FACTORY_NAMES.add(FactoryFinder.EXCEPTION_HANDLER_FACTORY);
+        FACTORY_NAMES.add(FactoryFinder.EXTERNAL_CONTEXT_FACTORY);
         FACTORY_NAMES.add(FactoryFinder.FACES_CONTEXT_FACTORY);
         FACTORY_NAMES.add(FactoryFinder.LIFECYCLE_FACTORY);
         FACTORY_NAMES.add(FactoryFinder.RENDER_KIT_FACTORY);
         FACTORY_NAMES.add(FactoryFinder.PARTIAL_VIEW_CONTEXT_FACTORY);
         FACTORY_NAMES.add(FactoryFinder.VISIT_CONTEXT_FACTORY);
         FACTORY_NAMES.add(FactoryFinder.VIEW_DECLARATION_LANGUAGE_FACTORY);
-        FACTORY_NAMES.add(FactoryFinder.EXCEPTION_HANDLER_FACTORY);
     }
 
     private final ExternalContext _externalContext;
@@ -639,6 +642,9 @@
                     if (factoryName.equals(FactoryFinder.APPLICATION_FACTORY))
                     {
                         getDispenser().feedApplicationFactory(className);
+                    } else if (factoryName.equals(FactoryFinder.EXTERNAL_CONTEXT_FACTORY))
+                    {
+                        getDispenser().feedExternalContextFactory(className);
                     } else if (factoryName.equals(FactoryFinder.FACES_CONTEXT_FACTORY))
                     {
                         getDispenser().feedFacesContextFactory(className);
@@ -1516,6 +1522,10 @@
         FacesConfigDispenser<FacesConfig> dispenser = getDispenser();
         setFactories(FactoryFinder.APPLICATION_FACTORY, dispenser.getApplicationFactoryIterator(),
                      DEFAULT_APPLICATION_FACTORY);
+        setFactories(FactoryFinder.EXCEPTION_HANDLER_FACTORY, dispenser.getExceptionHandlerFactoryIterator(),
+                     DEFAULT_EXCEPTION_HANDLER_FACTORY);        
+        setFactories(FactoryFinder.EXTERNAL_CONTEXT_FACTORY, dispenser.getExternalContextFactoryIterator(),
+                     DEFAULT_EXTERNAL_CONTEXT_FACTORY);
         setFactories(FactoryFinder.FACES_CONTEXT_FACTORY, dispenser.getFacesContextFactoryIterator(),
                      DEFAULT_FACES_CONTEXT_FACTORY);
         setFactories(FactoryFinder.LIFECYCLE_FACTORY, dispenser.getLifecycleFactoryIterator(),
@@ -1527,9 +1537,7 @@
         setFactories(FactoryFinder.VISIT_CONTEXT_FACTORY, dispenser.getVisitContextFactoryIterator(),
                      DEFAULT_VISIT_CONTEXT_FACTORY);
         setFactories(FactoryFinder.VIEW_DECLARATION_LANGUAGE_FACTORY, dispenser.getViewDeclarationLanguageFactoryIterator(),
-                DEFAULT_VIEW_DECLARATION_LANGUAGE_FACTORY);
-        setFactories(FactoryFinder.EXCEPTION_HANDLER_FACTORY, dispenser.getExceptionHandlerFactoryIterator(),
-                DEFAULT_EXCEPTION_HANDLER_FACTORY);
+                     DEFAULT_VIEW_DECLARATION_LANGUAGE_FACTORY);
     }
 
     private void setFactories(String factoryName, Collection<String> factories, String defaultFactory)

Added: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/context/ExternalContextFactoryImpl.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/context/ExternalContextFactoryImpl.java?rev=799765&view=auto
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/context/ExternalContextFactoryImpl.java (added)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/context/ExternalContextFactoryImpl.java Fri Jul 31 22:55:49 2009
@@ -0,0 +1,71 @@
+/*
+ * 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.context;
+
+import javax.faces.FacesException;
+import javax.faces.context.ExternalContext;
+import javax.faces.context.ExternalContextFactory;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+
+import org.apache.myfaces.context.servlet.ServletExternalContextImpl;
+
+/**
+ * @author Leonardo Uribe (latest modification by $Author$)
+ * @version $Revision$ $Date$
+ * 
+ * @since 2.0
+ */
+public class ExternalContextFactoryImpl extends ExternalContextFactory
+{
+
+    public static final String EXTERNAL_CONTEXT_KEY = 
+        "org.apache.myfaces.context.servlet.ServletExternalContextImpl";
+    
+    @Override
+    public ExternalContext getExternalContext(Object context, Object request,
+            Object response) throws FacesException
+    {
+        if (context == null)
+        {
+            throw new NullPointerException("context");
+        }
+        if (request == null)
+        {
+            throw new NullPointerException("request");
+        }
+        if (response == null)
+        {
+            throw new NullPointerException("response");
+        }
+
+        if (context instanceof ServletContext)
+        {
+            ExternalContext externalContext = new ServletExternalContextImpl(
+                    (ServletContext) context, (ServletRequest) request, (ServletResponse) response);
+            
+            externalContext.getRequestMap().put(EXTERNAL_CONTEXT_KEY, externalContext);
+            
+            return externalContext;
+        }
+        
+        throw new FacesException("Unsupported context type " + context.getClass().getName());
+    }
+}

Propchange: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/context/ExternalContextFactoryImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/context/ExternalContextFactoryImpl.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/context/FacesContextFactoryImpl.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/context/FacesContextFactoryImpl.java?rev=799765&r1=799764&r2=799765&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/context/FacesContextFactoryImpl.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/context/FacesContextFactoryImpl.java Fri Jul 31 22:55:49 2009
@@ -18,14 +18,20 @@
  */
 package org.apache.myfaces.context;
 
+import java.lang.reflect.Field;
+
 import javax.faces.FacesException;
+import javax.faces.FactoryFinder;
+import javax.faces.context.ExceptionHandlerFactory;
+import javax.faces.context.ExternalContext;
+import javax.faces.context.ExternalContextFactory;
 import javax.faces.context.FacesContext;
 import javax.faces.context.FacesContextFactory;
 import javax.faces.lifecycle.Lifecycle;
 import javax.servlet.ServletContext;
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
 
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
 import org.apache.myfaces.context.servlet.FacesContextImpl;
 
 /**
@@ -35,7 +41,70 @@
  * @version $Revision$ $Date$
  */
 public class FacesContextFactoryImpl extends FacesContextFactory
+    implements ReleaseableFacesContextFactory
 {
+    private static final Log log = LogFactory.getLog(FacesContextFactoryImpl.class);
+    
+    /**
+     * Reference to factory to prevent unnecessary lookups
+     */
+    private final ExternalContextFactory _externalContextFactory;
+    
+    /**
+     * Reference to factory to prevent unnecessary lookups
+     */
+    private final ExceptionHandlerFactory _exceptionHandlerFactory;
+        
+    /**
+     * This var is assigned as the same as javax.faces.context.ExternalContext._firstInstance,
+     * and since it is a static reference and does not change, we can cache it here safely.
+     * 
+     * We need
+     */
+    private final ThreadLocal<ExternalContext> _firstExternalContextInstance;
+    
+    @SuppressWarnings("unchecked")
+    public FacesContextFactoryImpl()
+    {
+        super();
+        ThreadLocal<ExternalContext> firstExternalContextInstance = null;
+        try
+        {
+            Field externalContextFirstInstance = ExternalContext.class.getDeclaredField("_firstInstance");
+            externalContextFirstInstance.setAccessible(true);
+            
+            if (externalContextFirstInstance != null)
+            {
+                if (firstExternalContextInstance == null)
+                {
+                    firstExternalContextInstance = 
+                        (ThreadLocal<ExternalContext>) externalContextFirstInstance.get(null);
+                }
+            }
+        }
+        catch (SecurityException e)
+        {
+            // It could happen, but we can ignore it.
+            if (log.isDebugEnabled())
+                log.debug("Cannot access private field _firstInstance from ExternalContext ",e);
+        }
+        catch (Exception e)
+        {
+            //It should not happen if we have only myfaces on classpath
+            if (log.isErrorEnabled())
+                log.error("Cannot found private field _firstInstance from ExternalContext ",e);
+        }
+        
+        _firstExternalContextInstance = firstExternalContextInstance;
+        
+        _externalContextFactory = (ExternalContextFactory)
+            FactoryFinder.getFactory(FactoryFinder.EXTERNAL_CONTEXT_FACTORY);
+
+        _exceptionHandlerFactory = (ExceptionHandlerFactory)
+            FactoryFinder.getFactory(FactoryFinder.EXCEPTION_HANDLER_FACTORY);
+        
+    }
+
     @Override
     public FacesContext getFacesContext(Object context, Object request, Object response, Lifecycle lifecycle)
         throws FacesException
@@ -56,12 +125,48 @@
         {
             throw new NullPointerException("lifecycle");
         }
+        
+        ExternalContext externalContext = _externalContextFactory.getExternalContext(context, request, response);
 
+        ExternalContext defaultExternalContext = null;
+        
+        if (_firstExternalContextInstance != null)
+        {
+            if (_firstExternalContextInstance.get() == null)
+            {
+                defaultExternalContext = (ExternalContext)
+                    externalContext.getRequestMap().remove(
+                            ExternalContextFactoryImpl.EXTERNAL_CONTEXT_KEY);
+                
+                if (defaultExternalContext != null)
+                {
+                    // Initialize the firstExternalContext that old jsf 1.2 or lower
+                    // implementations of ExternalContext should fall when call jsf 2.0
+                    // methods.
+                    _firstExternalContextInstance.set(defaultExternalContext);
+                }
+            }
+        }
+        
         if (context instanceof ServletContext)
         {
-            return new FacesContextImpl((ServletContext)context, (ServletRequest)request, (ServletResponse)response);
+            FacesContext facesContext = new FacesContextImpl(externalContext, null, this);
+            
+            facesContext.setExceptionHandler(_exceptionHandlerFactory.getExceptionHandler());
+            
+            return facesContext;
+            //return new FacesContextImpl((ServletContext)context, (ServletRequest)request, (ServletResponse)response);
         }
 
         throw new FacesException("Unsupported context type " + context.getClass().getName());
     }
+
+    @Override
+    public void release()
+    {
+        if (_firstExternalContextInstance != null)
+        {
+            _firstExternalContextInstance.remove();
+        }
+    }
 }

Added: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/context/ReleaseableFacesContextFactory.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/context/ReleaseableFacesContextFactory.java?rev=799765&view=auto
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/context/ReleaseableFacesContextFactory.java (added)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/context/ReleaseableFacesContextFactory.java Fri Jul 31 22:55:49 2009
@@ -0,0 +1,32 @@
+/*
+ * 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.context;
+
+/**
+ *
+ * @author  Leonardo Uribe (latest modification by $Author$)
+ * @version $Revision$ $Date$
+ */
+public interface ReleaseableFacesContextFactory
+{
+    /**
+     * Release resources that the ExternalContext is holding onto.
+     */
+    public void release();
+}

Propchange: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/context/ReleaseableFacesContextFactory.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/context/ReleaseableFacesContextFactory.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/context/servlet/FacesContextImpl.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/context/servlet/FacesContextImpl.java?rev=799765&r1=799764&r2=799765&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/context/servlet/FacesContextImpl.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/context/servlet/FacesContextImpl.java Fri Jul 31 22:55:49 2009
@@ -50,6 +50,7 @@
 import javax.servlet.ServletResponse;
 
 import org.apache.myfaces.context.ReleaseableExternalContext;
+import org.apache.myfaces.context.ReleaseableFacesContextFactory;
 import org.apache.myfaces.el.unified.FacesELContext;
 import org.apache.myfaces.shared_impl.util.NullIterator;
 
@@ -68,7 +69,8 @@
     private Map<String, List<FacesMessage>> _messages = null;
     private Application _application;
     private PhaseId _currentPhaseId;
-    private ReleaseableExternalContext _externalContext;
+    private ExternalContext _externalContext;
+    private ReleaseableExternalContext _defaultExternalContext;
     private ResponseStream _responseStream = null;
     private ResponseWriter _responseWriter = null;
     private FacesMessage.Severity _maximumSeverity = null;
@@ -84,6 +86,7 @@
     private boolean _processingEvents = true;
     private ExceptionHandler _exceptionHandler = null;
     private PartialViewContext _partialViewContext = null;
+    private ReleaseableFacesContextFactory _facesContextFactory = null;
 
     // ~ Constructors -------------------------------------------------------------------------------
     public FacesContextImpl(final ServletContext servletContext, final ServletRequest servletRequest,
@@ -103,18 +106,27 @@
             log.fatal("Could not obtain the response writers! Detail:" + ex.toString());
         }*/
     }
+    
+    public FacesContextImpl(final ExternalContext externalContext,
+            final ReleaseableExternalContext defaultExternalContext , 
+            final ReleaseableFacesContextFactory facesContextFactory)
+    {
+        _facesContextFactory = facesContextFactory;
+        init(externalContext, defaultExternalContext);
+    }
 
     private void init(final ReleaseableExternalContext externalContext)
     {
-        ExceptionHandlerFactory exceptionHandlerFactory = (ExceptionHandlerFactory)
-            FactoryFinder.getFactory (FactoryFinder.EXCEPTION_HANDLER_FACTORY);
-        
+        init((ExternalContext) externalContext, externalContext);
+    }
+
+    private void init(final ExternalContext externalContext, final ReleaseableExternalContext defaultExternalContext)
+    {       
         _externalContext = externalContext;
         FacesContext.setCurrentInstance(this);  //protected method, therefore must be called from here
         _application = ((ApplicationFactory)FactoryFinder.getFactory(FactoryFinder.APPLICATION_FACTORY))
                 .getApplication();
         _renderKitFactory = (RenderKitFactory) FactoryFinder.getFactory(FactoryFinder.RENDER_KIT_FACTORY);
-        _exceptionHandler = exceptionHandlerFactory.getExceptionHandler();
     }
 
     // ~ Methods ------------------------------------------------------------------------------------
@@ -394,11 +406,17 @@
     {
         assertNotReleased();
 
-        if (_externalContext != null)
+        if (_facesContextFactory != null)
+        {
+            _facesContextFactory.release();
+            _facesContextFactory = null;
+        }
+        if (_defaultExternalContext != null)
         {
-            _externalContext.release();
-            _externalContext = null;
+            _defaultExternalContext.release();
+            _defaultExternalContext = null;
         }
+        _externalContext = null;
 
         /*
          * Spec JSF 2 section getAttributes when release is called the attributes map must!!! be cleared!
@@ -486,13 +504,14 @@
 
     // Portlet need to do this to change from ActionRequest/Response to
     // RenderRequest/Response
+    /* This code comes from jsf 1.1 and is not valid anymore
     public final void setExternalContext(ReleaseableExternalContext extContext)
     {
         assertNotReleased();
 
         _externalContext = extContext;
         FacesContext.setCurrentInstance(this); // TODO: figure out if I really need to do this
-    }
+    }*/
 
     @Override
     public final ELContext getELContext()