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 2010/06/21 23:46:05 UTC

svn commit: r956711 - in /myfaces/core/trunk/impl/src/main/java/org/apache/myfaces: application/ config/ context/servlet/ webapp/

Author: lu4242
Date: Mon Jun 21 21:46:05 2010
New Revision: 956711

URL: http://svn.apache.org/viewvc?rev=956711&view=rev
Log:
revert of MYFACES-2759 and MYFACES-2760 (cannot allow include this code on a release without test it)

Added:
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/_SystemEventServletRequest.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/_SystemEventServletResponse.java
Modified:
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/FacesConfigurator.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/context/servlet/ServletExternalContextImpl.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/webapp/AbstractFacesInitializer.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/webapp/StartupServletContextListener.java

Added: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/_SystemEventServletRequest.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/_SystemEventServletRequest.java?rev=956711&view=auto
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/_SystemEventServletRequest.java (added)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/_SystemEventServletRequest.java Mon Jun 21 21:46:05 2010
@@ -0,0 +1,397 @@
+/*
+ * 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.application;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.security.Principal;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+
+import javax.servlet.RequestDispatcher;
+import javax.servlet.ServletInputStream;
+import javax.servlet.ServletRequest;
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletRequestWrapper;
+import javax.servlet.http.HttpSession;
+
+/**
+ * @author Werner Punz (latest modification by $Author$)
+ * @version $Revision$ $Date$
+ *
+ * Dummy request for various system event listeners
+ *
+ * the problem with the system event listeners is that they
+ * are triggered often outside of an existing request
+ * hence we have to provide dummy objects
+ */
+
+
+public class _SystemEventServletRequest extends HttpServletRequestWrapper{
+
+    Map<String, Object> _attributesMap = new HashMap<String, Object>();
+    public _SystemEventServletRequest()
+    {
+        super( (HttpServletRequest) Proxy.newProxyInstance(
+                HttpServletRequest.class.getClassLoader(),
+                new Class[] { HttpServletRequest.class },
+                new InvocationHandler()
+                {
+                    public Object invoke(Object proxy, Method m, Object[] args) 
+                    {
+                        throw new UnsupportedOperationException("This request class is an empty placeholder");
+                    }
+                }));
+    }
+
+    public Object getAttribute(String s) {
+       return  _attributesMap.get(s);
+    }
+
+    public void setAttribute(String s, Object o) {
+        _attributesMap.put(s, o);
+    }
+
+    public void removeAttribute(String s) {
+        _attributesMap.remove(s);
+    }
+
+    public String getServletPath()
+    {
+        return null;
+    }
+
+    public String getPathInfo()
+    {
+        return null;
+    }
+
+    @Override
+    public HttpSession getSession()
+    {
+        return null;
+    }
+
+    @Override
+    public HttpSession getSession(boolean create)
+    {
+        return null;
+    }
+
+    @Override
+    public int getContentLength()
+    {
+        return -1;
+    }
+
+    @Override
+    public String getContentType()
+    {
+        return null;
+    }
+
+    @Override
+    public String getCharacterEncoding()
+    {
+        return null;
+    }
+
+    @Override
+    public String getHeader(String name)
+    {
+        return null;
+    }
+
+    @Override
+    public Enumeration getHeaderNames()
+    {
+        return Collections.enumeration(Collections.emptyList());
+    }
+
+    @Override
+    public Enumeration getHeaders(String name)
+    {
+        return Collections.enumeration(Collections.EMPTY_LIST);
+    }
+
+    @Override
+    public Cookie[] getCookies()
+    {
+        return new Cookie[0];
+    }
+
+    @Override
+    public String getAuthType()
+    {
+        return null;
+    }
+
+    @Override
+    public String getContextPath()
+    {
+        return null;
+    }
+
+    @Override
+    public long getDateHeader(String name)
+    {
+        return -1;
+    }
+
+    @Override
+    public int getIntHeader(String name)
+    {
+        return -1;
+    }
+
+    @Override
+    public String getMethod()
+    {
+        return null;
+    }
+
+    @Override
+    public String getPathTranslated()
+    {
+        return null;
+    }
+
+    @Override
+    public String getQueryString()
+    {
+        return null;
+    }
+
+    @Override
+    public String getRemoteUser()
+    {
+        return null;
+    }
+
+    @Override
+    public String getRequestedSessionId()
+    {
+        return null;
+    }
+
+    @Override
+    public String getRequestURI()
+    {
+        return null;
+    }
+
+    @Override
+    public StringBuffer getRequestURL()
+    {
+        return null;
+    }
+
+    @Override
+    public Principal getUserPrincipal()
+    {
+        return null;
+    }
+
+    @Override
+    public boolean isRequestedSessionIdFromCookie()
+    {
+        return false;
+    }
+
+    @Override
+    public boolean isRequestedSessionIdFromUrl()
+    {
+        return false;
+    }
+
+    @Override
+    public boolean isRequestedSessionIdFromURL()
+    {
+        return false;
+    }
+
+    @Override
+    public boolean isRequestedSessionIdValid()
+    {
+        return false;
+    }
+
+    @Override
+    public boolean isUserInRole(String role)
+    {
+        return false;
+    }
+
+    @Override
+    public Enumeration getAttributeNames()
+    {
+        return Collections.enumeration(Collections.EMPTY_LIST);
+    }
+
+    @Override
+    public ServletInputStream getInputStream() throws IOException
+    {
+        return null;
+    }
+
+    @Override
+    public String getLocalAddr()
+    {
+        return null;
+    }
+
+    @Override
+    public Locale getLocale()
+    {
+        return null;
+    }
+
+    @Override
+    public Enumeration getLocales()
+    {
+        return Collections.enumeration(Collections.emptyList());
+    }
+
+    @Override
+    public String getLocalName()
+    {
+        return null;
+    }
+
+    @Override
+    public int getLocalPort()
+    {
+        return -1;
+    }
+
+    @Override
+    public String getParameter(String name)
+    {
+        return null;
+    }
+
+    @Override
+    public Map getParameterMap()
+    {
+        return Collections.emptyMap();
+    }
+
+    @Override
+    public Enumeration getParameterNames()
+    {
+        return Collections.enumeration(Collections.emptyList());
+    }
+
+    @Override
+    public String[] getParameterValues(String name)
+    {
+        return new String[0];
+    }
+
+    @Override
+    public String getProtocol()
+    {
+        return null;
+    }
+
+    @Override
+    public BufferedReader getReader() throws IOException
+    {
+        return null;
+    }
+
+    @Override
+    public String getRealPath(String path)
+    {
+        return null;
+    }
+
+    @Override
+    public String getRemoteAddr()
+    {
+        return null;
+    }
+
+    @Override
+    public String getRemoteHost()
+    {
+        return null;
+    }
+
+    @Override
+    public int getRemotePort()
+    {
+        return -1;
+    }
+
+    @Override
+    public ServletRequest getRequest()
+    {
+        return null;
+    }
+
+    @Override
+    public RequestDispatcher getRequestDispatcher(String path)
+    {
+        return null;
+    }
+
+    @Override
+    public String getScheme()
+    {
+        return null;
+    }
+
+    @Override
+    public String getServerName()
+    {
+        return null;
+    }
+
+    @Override
+    public int getServerPort()
+    {
+        return -1;
+    }
+
+    @Override
+    public boolean isSecure()
+    {
+        return false;
+    }
+
+    @Override
+    public void setCharacterEncoding(String enc)
+            throws UnsupportedEncodingException
+    {
+    }
+
+    @Override
+    public void setRequest(ServletRequest request)
+    {
+    }
+}

Added: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/_SystemEventServletResponse.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/_SystemEventServletResponse.java?rev=956711&view=auto
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/_SystemEventServletResponse.java (added)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/_SystemEventServletResponse.java Mon Jun 21 21:46:05 2010
@@ -0,0 +1,80 @@
+/*
+ * 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.application;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpServletResponseWrapper;
+
+/**
+ * @author Werner Punz (latest modification by $Author$)
+ * @version $Revision$ $Date$
+ *
+ * the problem with the system event listeners is that they
+ * are triggered often outside of an existing request
+ * hence we have to provide dummy objects
+ */
+
+public class _SystemEventServletResponse extends HttpServletResponseWrapper {
+
+    public _SystemEventServletResponse()
+    {
+        super( (HttpServletResponse) Proxy.newProxyInstance(
+                HttpServletResponse.class.getClassLoader(),
+                new Class[] { HttpServletResponse.class },
+                new InvocationHandler()
+                {
+                    public Object invoke(Object proxy, Method m, Object[] args) 
+                    {
+                        throw new UnsupportedOperationException("This response class is an empty placeholder");
+                    }
+                }));
+    }
+
+    @Override
+    public String getCharacterEncoding()
+    {
+        return null;
+    }
+
+    @Override
+    public String getContentType()
+    {
+        return null;
+    }
+
+    @Override
+    public void setCharacterEncoding(String charset)
+    {
+    }
+
+    @Override
+    public void setContentLength(int len)
+    {
+    }
+
+    @Override
+    public void setContentType(String type)
+    {
+    }
+
+}

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=956711&r1=956710&r2=956711&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 Mon Jun 21 21:46:05 2010
@@ -2384,8 +2384,10 @@ public class FacesConfigurator
         }
         
         // if ProjectStage is Development, install the DebugPhaseListener
+        // Note that FacesContext.getCurrentInstance() will be null for the very first
+        // initialisation here. In that case the PhaseListener is installed in AbstractFacesInitializer.
         FacesContext facesContext = FacesContext.getCurrentInstance();
-        if (facesContext.isProjectStage(ProjectStage.Development))
+        if (facesContext != null && facesContext.isProjectStage(ProjectStage.Development))
         {
             lifecycle.addPhaseListener(new DebugPhaseListener());
         }

Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/context/servlet/ServletExternalContextImpl.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/context/servlet/ServletExternalContextImpl.java?rev=956711&r1=956710&r2=956711&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/context/servlet/ServletExternalContextImpl.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/context/servlet/ServletExternalContextImpl.java Mon Jun 21 21:46:05 2010
@@ -19,9 +19,12 @@
 package org.apache.myfaces.context.servlet;
 
 import java.io.IOException;
+import java.io.InputStream;
 import java.io.OutputStream;
 import java.io.UnsupportedEncodingException;
 import java.io.Writer;
+import java.net.MalformedURLException;
+import java.net.URL;
 import java.net.URLEncoder;
 import java.security.Principal;
 import java.util.ArrayList;
@@ -30,9 +33,11 @@ import java.util.Iterator;
 import java.util.List;
 import java.util.Locale;
 import java.util.Map;
+import java.util.Set;
 import java.util.logging.Logger;
 
 import javax.faces.FacesException;
+import javax.faces.context.ExternalContext;
 import javax.faces.context.FacesContext;
 import javax.faces.context.Flash;
 import javax.faces.context.PartialResponseWriter;
@@ -47,6 +52,7 @@ import javax.servlet.http.HttpServletReq
 import javax.servlet.http.HttpServletResponse;
 import javax.servlet.http.HttpSession;
 
+import org.apache.myfaces.context.ReleaseableExternalContext;
 import org.apache.myfaces.shared_impl.context.flash.FlashImpl;
 import org.apache.myfaces.util.EnumerationIterator;
 
@@ -57,18 +63,21 @@ import org.apache.myfaces.util.Enumerati
  * @author Anton Koinov
  * @version $Revision$ $Date$
  */
-public final class ServletExternalContextImpl extends ServletExternalContextImplBase
+public final class ServletExternalContextImpl extends ExternalContext implements ReleaseableExternalContext
 {
     //private static final Log log = LogFactory.getLog(ServletExternalContextImpl.class);
     private static final Logger log = Logger.getLogger(ServletExternalContextImpl.class.getName());
 
+    private static final String INIT_PARAMETER_MAP_ATTRIBUTE = InitParameterMap.class.getName();
     private static final String URL_PARAM_SEPERATOR="&";
     private static final String URL_QUERY_SEPERATOR="?";
     private static final String URL_FRAGMENT_SEPERATOR="#";
     private static final String URL_NAME_VALUE_PAIR_SEPERATOR="=";
 
+    private ServletContext _servletContext;
     private ServletRequest _servletRequest;
     private ServletResponse _servletResponse;
+    private Map<String, Object> _applicationMap;
     private Map<String, Object> _sessionMap;
     private Map<String, Object> _requestMap;
     private Map<String, String> _requestParameterMap;
@@ -76,19 +85,19 @@ public final class ServletExternalContex
     private Map<String, String> _requestHeaderMap;
     private Map<String, String[]> _requestHeaderValuesMap;
     private Map<String, Object> _requestCookieMap;
+    private Map<String, String> _initParameterMap;
     private HttpServletRequest _httpServletRequest;
     private HttpServletResponse _httpServletResponse;
     private String _requestServletPath;
     private String _requestPathInfo;
 
-    public ServletExternalContextImpl(final ServletContext servletContext, 
-            final ServletRequest servletRequest,
+    public ServletExternalContextImpl(final ServletContext servletContext, final ServletRequest servletRequest,
             final ServletResponse servletResponse)
     {
-        super(servletContext); // initialize ServletExternalContextImplBase
-        
+        _servletContext = servletContext;
         _servletRequest = servletRequest;
         _servletResponse = servletResponse;
+        _applicationMap = null;
         _sessionMap = null;
         _requestMap = null;
         _requestParameterMap = null;
@@ -96,6 +105,7 @@ public final class ServletExternalContex
         _requestHeaderMap = null;
         _requestHeaderValuesMap = null;
         _requestCookieMap = null;
+        _initParameterMap = null;
         _httpServletRequest = isHttpServletRequest(servletRequest) ? (HttpServletRequest) servletRequest : null;
         _httpServletResponse = isHttpServletResponse(servletResponse) ? (HttpServletResponse) servletResponse : null;
 
@@ -111,10 +121,10 @@ public final class ServletExternalContex
 
     public void release()
     {
-        super.release(); // releases fields on ServletExternalContextImplBase
-        
+        _servletContext = null;
         _servletRequest = null;
         _servletResponse = null;
+        _applicationMap = null;
         _sessionMap = null;
         _requestMap = null;
         _requestParameterMap = null;
@@ -122,6 +132,7 @@ public final class ServletExternalContex
         _requestHeaderMap = null;
         _requestHeaderValuesMap = null;
         _requestCookieMap = null;
+        _initParameterMap = null;
         _httpServletRequest = null;
         _httpServletResponse = null;
     }
@@ -134,6 +145,12 @@ public final class ServletExternalContex
     }
 
     @Override
+    public Object getContext()
+    {
+        return _servletContext;
+    }
+
+    @Override
     public Object getRequest()
     {
         return _servletRequest;
@@ -185,6 +202,16 @@ public final class ServletExternalContex
     }
 
     @Override
+    public Map<String, Object> getApplicationMap()
+    {
+        if (_applicationMap == null)
+        {
+            _applicationMap = new ApplicationMap(_servletContext);
+        }
+        return _applicationMap;
+    }
+
+    @Override
     public Map<String, Object> getSessionMap()
     {
         if (_sessionMap == null)
@@ -303,12 +330,56 @@ public final class ServletExternalContex
     }
 
     @Override
+    public String getInitParameter(final String s)
+    {
+        return _servletContext.getInitParameter(s);
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public Map<String, String> getInitParameterMap()
+    {
+        if (_initParameterMap == null)
+        {
+            // We cache it as an attribute in ServletContext itself (is this circular reference a problem?)
+            if ((_initParameterMap = (Map<String, String>) _servletContext.getAttribute(INIT_PARAMETER_MAP_ATTRIBUTE)) == null)
+            {
+                _initParameterMap = new InitParameterMap(_servletContext);
+                _servletContext.setAttribute(INIT_PARAMETER_MAP_ATTRIBUTE, _initParameterMap);
+            }
+        }
+        return _initParameterMap;
+    }
+
+    @Override
+    public String getMimeType(String file)
+    {
+        checkNull(file, "file");
+        return _servletContext.getMimeType(file);
+    }
+
+    @Override
     public String getRequestScheme()
     {
         return _servletRequest.getScheme();
     }
 
     @Override
+    @SuppressWarnings("unchecked")
+    public Set<String> getResourcePaths(final String path)
+    {
+        checkNull(path, "path");
+        return _servletContext.getResourcePaths(path);
+    }
+
+    @Override
+    public InputStream getResourceAsStream(final String path)
+    {
+        checkNull(path, "path");
+        return _servletContext.getResourceAsStream(path);
+    }
+
+    @Override
     public String encodeActionURL(final String url)
     {
         checkNull(url, "url");
@@ -402,6 +473,13 @@ public final class ServletExternalContex
     }
 
     @Override
+    public String getRealPath(String path)
+    {
+        checkNull(path, "path");
+        return _servletContext.getRealPath(path);
+    }
+
+    @Override
     public String getRemoteUser()
     {
         checkHttpServletRequest();
@@ -444,6 +522,21 @@ public final class ServletExternalContex
     }
 
     @Override
+    public void log(final String message)
+    {
+        checkNull(message, "message");
+        _servletContext.log(message);
+    }
+
+    @Override
+    public void log(final String message, final Throwable exception)
+    {
+        checkNull(message, "message");
+        checkNull(exception, "exception");
+        _servletContext.log(message, exception);
+    }
+
+    @Override
     public void redirect(final String url) throws IOException
     {
         FacesContext facesContext = FacesContext.getCurrentInstance();
@@ -515,6 +608,13 @@ public final class ServletExternalContex
         return new EnumerationIterator(_httpServletRequest.getLocales());
     }
 
+    @Override
+    public URL getResource(final String path) throws MalformedURLException
+    {
+        checkNull(path, "path");
+        return _servletContext.getResource(path);
+    }
+
     /**
      * @since JSF 1.2
      * @param request
@@ -631,6 +731,14 @@ public final class ServletExternalContex
         _httpServletResponse.setStatus(statusCode);
     }
 
+    private void checkNull(final Object o, final String param)
+    {
+        if (o == null)
+        {
+            throw new NullPointerException(param + " can not be null.");
+        }
+    }
+
     private void checkHttpServletRequest()
     {
         if (_httpServletRequest == null)
@@ -708,6 +816,11 @@ public final class ServletExternalContex
         _httpServletResponse.addHeader(name, value);
     }
 
+    @Override
+    public String getContextName() {
+        return _servletContext.getServletContextName();
+    }
+
     private String encodeURL(String baseUrl, Map<String, List<String>> parameters)
     {
         checkNull(baseUrl, "url");

Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/webapp/AbstractFacesInitializer.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/webapp/AbstractFacesInitializer.java?rev=956711&r1=956710&r2=956711&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/webapp/AbstractFacesInitializer.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/webapp/AbstractFacesInitializer.java Mon Jun 21 21:46:05 2010
@@ -19,27 +19,38 @@
 package org.apache.myfaces.webapp;
 
 import java.util.List;
+import java.util.Locale;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
 import javax.el.ExpressionFactory;
+import javax.faces.FactoryFinder;
 import javax.faces.application.Application;
+import javax.faces.application.ApplicationFactory;
 import javax.faces.application.ProjectStage;
+import javax.faces.component.UIViewRoot;
 import javax.faces.context.ExternalContext;
 import javax.faces.context.FacesContext;
+import javax.faces.context.FacesContextFactory;
 import javax.faces.event.PostConstructApplicationEvent;
 import javax.faces.event.PreDestroyApplicationEvent;
-import javax.faces.event.SystemEvent;
+import javax.faces.lifecycle.Lifecycle;
+import javax.faces.lifecycle.LifecycleFactory;
+import javax.faces.webapp.FacesServlet;
 import javax.servlet.ServletContext;
 
 import org.apache.myfaces.application.ApplicationImpl;
+import org.apache.myfaces.application._SystemEventServletRequest;
+import org.apache.myfaces.application._SystemEventServletResponse;
 import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFWebConfigParam;
 import org.apache.myfaces.config.FacesConfigValidator;
 import org.apache.myfaces.config.FacesConfigurator;
 import org.apache.myfaces.config.RuntimeConfig;
 import org.apache.myfaces.config.annotation.DefaultLifecycleProviderFactory;
+import org.apache.myfaces.context.servlet.ServletExternalContextImpl;
 import org.apache.myfaces.shared_impl.util.StateUtils;
 import org.apache.myfaces.shared_impl.webapp.webxml.WebXml;
+import org.apache.myfaces.view.facelets.tag.ui.DebugPhaseListener;
 
 /**
  * Performs common initialization tasks.
@@ -68,34 +79,29 @@ public abstract class AbstractFacesIniti
      * Performs all necessary initialization tasks like configuring this JSF
      * application.
      */
-    public void initFaces(ServletContext servletContext) 
-    {
-        try 
-        {
-            if (log.isLoggable(Level.FINEST)) 
-            {
+    public void initFaces(ServletContext servletContext) {
+        try {
+            if (log.isLoggable(Level.FINEST)) {
                 log.finest("Initializing MyFaces");
             }
-            
-            // since we have the StartupFacesContextImpl, we can use FacesContext
-            // and ExternalContext here directly.
-            FacesContext facesContext = FacesContext.getCurrentInstance();
-            ExternalContext externalContext = facesContext.getExternalContext();
+
+            // Some parts of the following configuration tasks have been implemented 
+            // by using an ExternalContext. However, that's no problem as long as no 
+            // one tries to call methods depending on either the ServletRequest or 
+            // the ServletResponse.
+            ExternalContext externalContext = new ServletExternalContextImpl(
+                    servletContext, null, null);
 
             // Parse and validate the web.xml configuration file
             WebXml webXml = WebXml.getWebXml(externalContext);
-            if (webXml == null) 
-            {
-                if (log.isLoggable(Level.WARNING)) 
-                {
+            if (webXml == null) {
+                if (log.isLoggable(Level.WARNING)) {
                     log.warning("Couldn't find the web.xml configuration file. "
                              + "Abort initializing MyFaces.");
                 }
 
                 return;
-            }
-            else if (webXml.getFacesServletMappings().isEmpty())
-            {
+            } else if (webXml.getFacesServletMappings().isEmpty()) {
                 // check if the FacesServlet has been added dynamically
                 // in a Servlet 3.0 environment by MyFacesContainerInitializer
                 Boolean mappingAdded = (Boolean) servletContext.getAttribute(FACES_SERVLET_ADDED_ATTRIBUTE);
@@ -112,13 +118,11 @@ public abstract class AbstractFacesIniti
             initContainerIntegration(servletContext, externalContext);
 
             String useEncryption = servletContext.getInitParameter(StateUtils.USE_ENCRYPTION);
-            if (!"false".equals(useEncryption)) // the default value is true
-            { 
+            if (!"false".equals(useEncryption)) { // the default value is true
                 StateUtils.initSecret(servletContext);
             }
 
-            if (log.isLoggable(Level.INFO))
-            {
+            if (log.isLoggable(Level.INFO)) {
                 log.info("ServletContext '" + servletContext.getRealPath("/") + "' initialized.");
             }
 
@@ -131,9 +135,9 @@ public abstract class AbstractFacesIniti
             DefaultLifecycleProviderFactory.getLifecycleProviderFactory().getLifecycleProvider(externalContext);
             
             // print out a very prominent log message if the project stage is != Production
-            if (!facesContext.isProjectStage(ProjectStage.Production))
+            if (!FacesContext.getCurrentInstance().isProjectStage(ProjectStage.Production))
             {
-                ProjectStage projectStage = facesContext.getApplication().getProjectStage();
+                ProjectStage projectStage = FacesContext.getCurrentInstance().getApplication().getProjectStage();
                 StringBuilder message = new StringBuilder("\n\n");
                 message.append("*******************************************************************\n");
                 message.append("*** WARNING: Apache MyFaces-2 is running in ");
@@ -159,16 +163,26 @@ public abstract class AbstractFacesIniti
                 message.append("*** See Application#getProjectStage() for more information.     ***\n");
                 message.append("*******************************************************************\n");
                 log.log(Level.WARNING, message.toString());
+                
+                // if ProjectStage is Development, install the DebugPhaseListener
+                if (FacesContext.getCurrentInstance().isProjectStage(ProjectStage.Development))
+                {
+                    LifecycleFactory lifeFac = (LifecycleFactory) FactoryFinder
+                            .getFactory(FactoryFinder.LIFECYCLE_FACTORY);
+                    Lifecycle lifecycle = lifeFac.getLifecycle(getLifecycleId(servletContext));
+                    lifecycle.addPhaseListener(new DebugPhaseListener());
+                }
             }
             
-        } 
-        catch (Exception ex) 
-        {
+            releaseFacesContext();
+
+        } catch (Exception ex) {
             log.log(Level.SEVERE, "An error occured while initializing MyFaces: "
                       + ex.getMessage(), ex);
         }
     }
 
+
     /**
      * Eventually we can use our plugin infrastructure for this as well
      * it would be a cleaner interception point than the base class
@@ -184,27 +198,72 @@ public abstract class AbstractFacesIniti
      * @param eventClass     the class to be passed down into the dispatching
      *                       code
      */
-    private void dispatchInitDestroyEvent(ServletContext servletContext, Class<? extends SystemEvent> eventClass) 
-    {
-        // since we have the StartupFacesContextImpl, we can use the FacesContext
-        // and the Application object directly here
-        FacesContext facesContext = FacesContext.getCurrentInstance();
-        Application application = facesContext.getApplication();
+    private void dispatchInitDestroyEvent(ServletContext servletContext, Class eventClass) {
+        ApplicationFactory appFac = (ApplicationFactory) FactoryFinder.getFactory(FactoryFinder.APPLICATION_FACTORY);
+        FacesContext fc = null;
+
+        fc = FacesContext.getCurrentInstance();
+        if (fc == null) {
+            LifecycleFactory lifeFac = (LifecycleFactory) FactoryFinder.getFactory(FactoryFinder.LIFECYCLE_FACTORY);
+            FacesContextFactory facFac = (FacesContextFactory) FactoryFinder.getFactory(FactoryFinder.FACES_CONTEXT_FACTORY);
+            fc = facFac.getFacesContext(servletContext, 
+                    new _SystemEventServletRequest(), 
+                    new _SystemEventServletResponse(), 
+                    lifeFac.getLifecycle(getLifecycleId(servletContext)));
+        }
         
-        application.publishEvent(facesContext, eventClass, Application.class, application);
+        // in order to allow FacesContext.getViewRoot calls during startup/shutdown listeners, 
+        // we need to initialize a new ViewRoot with locale set to Locale.getDefault().
+        UIViewRoot root = new UIViewRoot();
+        root.setLocale(Locale.getDefault());
+        fc.setViewRoot(root);
+        
+        appFac.getApplication().publishEvent(fc, eventClass, Application.class, appFac.getApplication());
+    }
+    
+    /**
+     * Gets the LifecycleId from the ServletContext init param.
+     * If this is null, it returns LifecycleFactory.DEFAULT_LIFECYCLE.
+     * @param servletContext
+     * @return
+     */
+    private String getLifecycleId(ServletContext servletContext)
+    {
+        String id = servletContext.getInitParameter(FacesServlet.LIFECYCLE_ID_ATTR);
+
+        if (id != null)
+        {
+            return id;
+        }
+        return LifecycleFactory.DEFAULT_LIFECYCLE;
     }
 
     /**
      * Cleans up all remaining resources (well, theoretically).
      */
-    public void destroyFaces(ServletContext servletContext) 
-    {
+    public void destroyFaces(ServletContext servletContext) {
         dispatchInitDestroyEvent(servletContext, PreDestroyApplicationEvent.class);
+        releaseFacesContext();
 
         // TODO is it possible to make a real cleanup?
     }
     
     /**
+     * ensures faces context with dummy request/response objects is released so it doesn't get reused
+     */
+    
+    private void releaseFacesContext()
+    {        
+        //make sure that the facesContext gets released.  This is important in an OSGi environment 
+        FacesContext fc = null;
+        fc = FacesContext.getCurrentInstance();        
+        if(fc != null)
+        {
+            fc.release();
+        }        
+    }
+
+    /**
      * Configures this JSF application. It's required that every
      * FacesInitializer (i.e. every subclass) calls this method during
      * initialization.
@@ -215,8 +274,7 @@ public abstract class AbstractFacesIniti
      * @return the current runtime configuration
      */
     protected RuntimeConfig buildConfiguration(ServletContext servletContext,
-        ExternalContext externalContext, ExpressionFactory expressionFactory) 
-    {
+                                               ExternalContext externalContext, ExpressionFactory expressionFactory) {
         RuntimeConfig runtimeConfig = RuntimeConfig.getCurrentInstance(externalContext);
         runtimeConfig.setExpressionFactory(expressionFactory);
 
@@ -230,16 +288,13 @@ public abstract class AbstractFacesIniti
         return runtimeConfig;
     }
 
-    protected void validateFacesConfig(ServletContext servletContext, ExternalContext externalContext) 
-    {
+    protected void validateFacesConfig(ServletContext servletContext, ExternalContext externalContext) {
         String validate = servletContext.getInitParameter(FacesConfigValidator.VALIDATE_CONTEXT_PARAM);
-        if ("true".equals(validate) && log.isLoggable(Level.WARNING)) // the default value is false 
-        { 
+        if ("true".equals(validate) && log.isLoggable(Level.WARNING)) { // the default value is false
             List<String> warnings = FacesConfigValidator.validate(
                     externalContext, servletContext.getRealPath("/"));
 
-            for (String warning : warnings) 
-            {
+            for (String warning : warnings) {
                 log.warning(warning);
             }
         }
@@ -253,14 +308,11 @@ public abstract class AbstractFacesIniti
      * @return User-specified ExpressionFactory, or
      *         <code>null</code>, if no no custom implementation was specified
      */
-    protected static ExpressionFactory getUserDefinedExpressionFactory(ExternalContext externalContext) 
-    {
+    protected static ExpressionFactory getUserDefinedExpressionFactory(ExternalContext externalContext) {
         String expressionFactoryClassName = externalContext.getInitParameter(EXPRESSION_FACTORY);
         if (expressionFactoryClassName != null
-            && expressionFactoryClassName.trim().length() > 0) 
-        {
-            if (log.isLoggable(Level.FINE)) 
-            {
+            && expressionFactoryClassName.trim().length() > 0) {
+            if (log.isLoggable(Level.FINE)) {
                 log.fine("Attempting to load the ExpressionFactory implementation "
                           + "you've specified: '" + expressionFactoryClassName + "'.");
             }
@@ -278,17 +330,12 @@ public abstract class AbstractFacesIniti
      * @return the newly created ExpressionFactory implementation, or
      *         <code>null</code>, if an error occurred
      */
-    protected static ExpressionFactory loadExpressionFactory(String expressionFactoryClassName) 
-    {
-        try 
-        {
+    protected static ExpressionFactory loadExpressionFactory(String expressionFactoryClassName) {
+        try {
             Class<?> expressionFactoryClass = Class.forName(expressionFactoryClassName);
             return (ExpressionFactory) expressionFactoryClass.newInstance();
-        }
-        catch (Exception ex) 
-        {
-            if (log.isLoggable(Level.FINE)) 
-            {
+        } catch (Exception ex) {
+            if (log.isLoggable(Level.FINE)) {
                 log.log(Level.FINE, "An error occured while instantiating a new ExpressionFactory. "
                           + "Attempted to load class '" + expressionFactoryClassName + "'.", ex);
             }

Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/webapp/StartupServletContextListener.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/webapp/StartupServletContextListener.java?rev=956711&r1=956710&r2=956711&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/webapp/StartupServletContextListener.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/webapp/StartupServletContextListener.java Mon Jun 21 21:46:05 2010
@@ -22,7 +22,6 @@ import java.util.logging.Level;
 import java.util.logging.Logger;
 
 import javax.faces.FactoryFinder;
-import javax.faces.context.FacesContext;
 import javax.servlet.ServletContext;
 import javax.servlet.ServletContextAttributeEvent;
 import javax.servlet.ServletContextAttributeListener;
@@ -38,7 +37,6 @@ import javax.servlet.http.HttpSessionEve
 import javax.servlet.http.HttpSessionListener;
 
 import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFWebConfigParam;
-import org.apache.myfaces.context.servlet.StartupFacesContextImpl;
 import org.apache.myfaces.shared_impl.util.ClassUtils;
 import org.apache.myfaces.util.ContainerUtils;
 
@@ -153,12 +151,8 @@ public class StartupServletContextListen
             throw new IllegalStateException("context is already initialized");
         }
         _servletContext = event.getServletContext();
-        
-        // provide a FacesContext for application startup.
-        // Note that setCurrentInstance() is called in the constructor.
-        FacesContext facesContext = new StartupFacesContextImpl(true, _servletContext);
-        
         Boolean b = (Boolean) _servletContext.getAttribute(FACES_INIT_DONE);
+
         if (b == null || b.booleanValue() == false)
         {
             dispatchInitializationEvent(event, FACES_INIT_PHASE_PREINIT);
@@ -173,9 +167,6 @@ public class StartupServletContextListen
         
         // call contextInitialized on ManagedBeanDestroyerListener
         _detroyerListener.contextInitialized(event);
-        
-        // release the FacesContext for application startup
-        facesContext.release();
     }
 
     protected void initFaces(ServletContext context)
@@ -215,10 +206,6 @@ public class StartupServletContextListen
 
     public void contextDestroyed(ServletContextEvent event)
     {
-        // provide a FacesContext for application shutdown.
-        // Note that setCurrentInstance() is called in the constructor.
-        FacesContext facesContext = new StartupFacesContextImpl(false, event.getServletContext());
-        
         dispatchInitializationEvent(event, FACES_INIT_PHASE_PREDESTROY);
         // call contextDestroyed on ManagedBeanDestroyerListener to destroy the attributes
         _detroyerListener.contextDestroyed(event);
@@ -230,9 +217,6 @@ public class StartupServletContextListen
         FactoryFinder.releaseFactories();
         dispatchInitializationEvent(event, FACES_INIT_PHASE_POSTDESTROY);
 
-        // release the FacesContext for application shutdown
-        facesContext.release();
-        
         _servletContext = null;
     }