All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.sun.faces.config.InitFacesContext Maven / Gradle / Ivy

Go to download

This is the master POM file for Oracle's Implementation of the JSF 2.2 Specification.

There is a newer version: 2.4.0
Show newest version
/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
 *
 * The contents of this file are subject to the terms of either the GNU
 * General Public License Version 2 only ("GPL") or the Common Development
 * and Distribution License("CDDL") (collectively, the "License").  You
 * may not use this file except in compliance with the License.  You can
 * obtain a copy of the License at
 * https://glassfish.java.net/public/CDDL+GPL_1_1.html
 * or packager/legal/LICENSE.txt.  See the License for the specific
 * language governing permissions and limitations under the License.
 *
 * When distributing the software, include this License Header Notice in each
 * file and include the License file at packager/legal/LICENSE.txt.
 *
 * GPL Classpath Exception:
 * Oracle designates this particular file as subject to the "Classpath"
 * exception as provided by Oracle in the GPL Version 2 section of the License
 * file that accompanied this code.
 *
 * Modifications:
 * If applicable, add the following below the License Header, with the fields
 * enclosed by brackets [] replaced by your own identifying information:
 * "Portions Copyright [year] [name of copyright owner]"
 *
 * Contributor(s):
 * If you wish your version of this file to be governed by only the CDDL or
 * only the GPL Version 2, indicate your decision by adding "[Contributor]
 * elects to include this software in this distribution under the [CDDL or GPL
 * Version 2] license."  If you don't indicate a single choice of license, a
 * recipient has the option to distribute your version of this file under
 * either the CDDL, the GPL Version 2 or to extend the choice of license to
 * its licensees as provided above.  However, if you add GPL Version 2 code
 * and therefore, elected the GPL Version 2 license, then the option applies
 * only if the new code is made subject to such option by the copyright
 * holder.
 */

package com.sun.faces.config;

import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Field;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.el.ELContext;
import javax.el.ELResolver;
import javax.el.FunctionMapper;
import javax.el.VariableMapper;
import javax.faces.FactoryFinder;
import javax.faces.application.Application;
import javax.faces.application.ApplicationFactory;
import javax.faces.application.FacesMessage;
import javax.faces.application.ProjectStage;
import javax.faces.component.UIViewRoot;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.faces.context.Flash;
import javax.faces.context.ResponseStream;
import javax.faces.context.ResponseWriter;
import javax.faces.render.RenderKit;
import javax.servlet.ServletContext;

import com.sun.faces.RIConstants;
import com.sun.faces.context.ApplicationMap;
import com.sun.faces.context.InitParameterMap;
import com.sun.faces.util.FacesLogger;
import com.sun.faces.util.Util;

/**
 * A special, minimal implementation of FacesContext used at application initialization time.
 * The ExternalContext returned by this FacesContext only exposes the ApplicationMap.
 */
public class InitFacesContext extends FacesContext {
    
    private static Logger LOGGER = FacesLogger.CONFIG.getLogger();
    
    private ServletContextAdapter ec;
    private UIViewRoot viewRoot;
    private Map attributes;
    private ELContext elContext = new ELContext() {
        @Override
        public ELResolver getELResolver() {
            return null;
        }

        @Override
        public FunctionMapper getFunctionMapper() {
            return null;
        }

        @Override
        public VariableMapper getVariableMapper() {
            return null;
        }
    };

    public InitFacesContext(ServletContext sc) {
        ec = new ServletContextAdapter(sc);
        sc.setAttribute(INIT_FACES_CONTEXT_ATTR_NAME, this);
        InitFacesContext.cleanupInitMaps(sc);
        getThreadInitContextMap().put(Thread.currentThread(), this);
        getInitContextServletContextMap().put(this, sc);
    }
    
    public void reInitializeExternalContext(ServletContext sc) {
        assert(Util.isUnitTestModeEnabled());
        ec = new ServletContextAdapter(sc);
    }
    
    private static final String INIT_FACES_CONTEXT_ATTR_NAME = RIConstants.FACES_PREFIX + "InitFacesContext";
    
    static InitFacesContext getInstance(ServletContext sc) {
        InitFacesContext result = (InitFacesContext) sc.getAttribute(INIT_FACES_CONTEXT_ATTR_NAME);
        if (null != result) {
            result.callSetCurrentInstance();
        }
        
        return result;
    }

    void callSetCurrentInstance() {
        getThreadInitContextMap().put(Thread.currentThread(), this);
    }

    @Override
    public Map getAttributes() {
        if (attributes == null) {
            attributes = new HashMap<>();
        }
        return attributes;
    }

    @Override
    public Application getApplication() {
        ApplicationFactory factory = (ApplicationFactory)
                FactoryFinder.getFactory(FactoryFinder.APPLICATION_FACTORY);
        return factory.getApplication();
    }

    @Override
    public Iterator getClientIdsWithMessages() {
        List list = Collections.emptyList();
        return list.iterator();
    }

    @Override
    public ExternalContext getExternalContext() {
        return ec;
    }

    @Override
    public FacesMessage.Severity getMaximumSeverity() {
        return FacesMessage.SEVERITY_INFO;
    }

    @Override
    public Iterator getMessages() {
        List list = Collections.emptyList();
        return list.iterator();
    }

    @Override
    public Iterator getMessages(String clientId) {
        return getMessages();
    }

    @Override
    public List getMessageList() {
	return Collections.EMPTY_LIST;
    }


    @Override
    public List getMessageList(String clientId) {
	return Collections.EMPTY_LIST;
    }


    @Override
    public boolean isProjectStage(ProjectStage stage) {
        if (stage == null) {
            throw new NullPointerException();
        }
        return stage.equals(getApplication().getProjectStage());
    }

    @Override
    public RenderKit getRenderKit() {
        return null;
    }

    @Override
    public boolean getRenderResponse() {
        return true;
    }

    @Override
    public boolean getResponseComplete() {
        return true;
    }

    @Override
    public boolean isValidationFailed() {
        return false;
    }

    @Override
    public ResponseStream getResponseStream() {
        return null;
    }

    @Override
    public void setResponseStream(ResponseStream responseStream) { }

    @Override
    public ResponseWriter getResponseWriter() {
        return null;
    }

    @Override
    public void setResponseWriter(ResponseWriter responseWriter) { }

    @Override
    public UIViewRoot getViewRoot() {
        if (viewRoot == null) {
            viewRoot = new UIViewRoot();
            viewRoot.setLocale(Locale.getDefault());
            viewRoot.setViewId(RIConstants.FACES_PREFIX + "xhtml");
        }
        return viewRoot;
    }

    @Override
    public void setViewRoot(UIViewRoot root) { }

    @Override
    public void addMessage(String clientId, FacesMessage message) { }

    @Override
    public void release() {
        setCurrentInstance(null);
        if (null != ec) {
            Map appMap = ec.getApplicationMap();
            if (null != appMap && appMap instanceof ApplicationMap) {
                if (null != ((ApplicationMap)appMap).getContext()) {
                    appMap.remove(INIT_FACES_CONTEXT_ATTR_NAME);
                }
            }
            ec.release();
        }
        
        if (null != attributes) {
            attributes.clear();
            attributes = null;
        }
        elContext = null;
        if (null != viewRoot) {
            Map viewMap = viewRoot.getViewMap(false);
            if (null != viewMap) {
                viewMap.clear();
            }
        }
        viewRoot = null;

    }

    @Override
    public void renderResponse() { }

    @Override
    public void responseComplete() { }

    @Override
    public void validationFailed() { }

    @Override
    public ELContext getELContext() {
       return elContext;
    }

    public void setELContext(ELContext elContext) {
        this.elContext = elContext;        
    }

    /**
     * Clean up entries from the threadInitContext and initContextServletContext maps 
     * using a ServletContext.  First remove entry(s) with matching ServletContext from
     * initContextSerlvetContext map.  Then remove entries from threadInitContext map
     * where the entry value(s) match the initFacesContext (associated with the ServletContext).
     * @param context
     */
    public static void cleanupInitMaps(ServletContext context) {
        Map threadInitContext = InitFacesContext.getThreadInitContextMap();
        Map initContextServletContext =
            InitFacesContext.getInitContextServletContextMap();
        Set> entries = initContextServletContext.entrySet();
        for (Iterator> iterator1 =
            entries.iterator(); iterator1.hasNext();) {
            Map.Entry entry1 = (Map.Entry)iterator1.next();
            Object initContextKey = entry1.getKey();
            Object value1 = entry1.getValue();
            if (context == value1) {
                initContextServletContext.remove(initContextKey);
                Set> threadEntries = threadInitContext.entrySet();
                for (Iterator> iterator2 =
                    threadEntries.iterator(); iterator2.hasNext();) {
                    Map.Entry  entry2 = (Map.Entry)iterator2.next();
                    Object thread = entry2.getKey();
                    Object initContextValue = entry2.getValue();
                    if (initContextKey == initContextValue) {
                        threadInitContext.remove(thread);
                    }
                }
            }
        }
    }

    // Bug 20458755: I'm not sure why this wasn't done when this concept was added
    // during the fix for JAVASERVERFACES-2436
    void removeInitContextEntryForCurrentThread() {
        Map threadInitContext = InitFacesContext.getThreadInitContextMap();
        Thread currentThread = Thread.currentThread();
        if (threadInitContext.containsKey(currentThread)) {
            threadInitContext.remove(currentThread);
        }
    }
    
    // Bug 20458755: I'm not sure why this wasn't done when this concept was added
    // during the fix for JAVASERVERFACES-2436
    public void removeServletContextEntryForInitContext() {
        Map servletContextMap = InitFacesContext.getInitContextServletContextMap();
        if (null != servletContextMap && !servletContextMap.isEmpty()) {
            servletContextMap.remove(this);
        }
    }

    public void releaseCurrentInstance() {
        Map threadInitContext = InitFacesContext.getThreadInitContextMap();
        threadInitContext.remove(Thread.currentThread());
        setCurrentInstance(null);
    }

    private static class ServletContextAdapter extends ExternalContext {

        private ServletContext servletContext = null;
        private ApplicationMap applicationMap = null;
        private InitParameterMap initMap = null;
        private boolean isEnableTransitionTimeNoOpFlash = WebConfiguration.BooleanWebContextInitParameter.EnableTransitionTimeNoOpFlash.getDefaultValue();
    
        public ServletContextAdapter(ServletContext sc) {
            this.servletContext = sc;
            
            Object paramValue = sc.getInitParameter(WebConfiguration.BooleanWebContextInitParameter.EnableTransitionTimeNoOpFlash.getQualifiedName());
            if (null != paramValue) {
                isEnableTransitionTimeNoOpFlash = Boolean.parseBoolean(paramValue.toString());
            }
            
        }

        @Override
        public void dispatch(String path) throws IOException {
        }
        
        private void release() {
            servletContext = null;
            applicationMap = null;
            initMap = null;
        }

        @Override
        public String encodeActionURL(String url) {
            return null;
        }

        @Override
        public String encodeNamespace(String name) {
            return null;
        }

        @Override
        public String encodeResourceURL(String url) {
            return null;
        }

        @Override
        public String encodeWebsocketURL(String url) {
            return null;
        }

        @Override
        public Map getApplicationMap() {
            if (applicationMap == null) {
                applicationMap =
                        new ApplicationMap(servletContext);
            }
            return applicationMap;
        }

        @Override
        public Flash getFlash() {
            if (isEnableTransitionTimeNoOpFlash) {
                return new Flash() {
                    
                    @Override
                    public void doPostPhaseActions(FacesContext ctx) {
                        
                    }
                    
                    @Override
                    public void doPrePhaseActions(FacesContext ctx) {
                        
                    }
                    
                    @Override
                    public boolean isKeepMessages() {
                        return false;
                    }
                    
                    @Override
                    public boolean isRedirect() {
                        return false;
                    }
                    
                    @Override
                    public void keep(String key) {
                        
                    }
                    
                    @Override
                    public void putNow(String key, Object value) {
                        
                    }
                    
                    @Override
                    public void setKeepMessages(boolean newValue) {
                        
                    }
                    
                    @Override
                    public void setRedirect(boolean newValue) {
                        
                    }
                    
                    @Override
                    public void clear() {
                        
                    }
                    
                    @Override
                    public boolean containsKey(Object key) {
                        return false;
                    }
                    
                    @Override
                    public boolean containsValue(Object value) {
                        return false;
                    }
                    
                    @Override
                    public Set> entrySet() {
                        return Collections.emptySet();
                    }
                    
                    @Override
                    public Object get(Object key) {
                        return null;
                    }
                    
                    @Override
                    public boolean isEmpty() {
                        return true;
                    }
                    
                    @Override
                    public Set keySet() {
                        return Collections.emptySet();
                    }
                    
                    @Override
                    public Object put(String key, Object value) {
                        return null;
                    }
                    
                    @Override
                    public void putAll(Map m) {
                        
                    }
                    
                    @Override
                    public Object remove(Object key) {
                        return null;
                    }
                    
                    @Override
                    public int size() {
                        return 0;
                    }
                    
                    @Override
                    public Collection values() {
                        return Collections.emptyList();
                    }
                    
                    
                };
            } else {
                return super.getFlash();
            }
        
    }
            
            
            
        @Override
        public String getApplicationContextPath() {
            return servletContext.getContextPath();
        }
        
        @Override
        public String getAuthType() {
            return null;
        }

        @Override
        public String getMimeType(String file) {
            return servletContext.getMimeType(file);
        }

        @Override
        public Object getContext() {
            return servletContext;
        }

        @Override
	public String getContextName() { 
	    return servletContext.getServletContextName();
	}

	

        @Override
        public String getInitParameter(String name) {
            return servletContext.getInitParameter(name);
        }

        @Override
        public Map getInitParameterMap() {
            if (initMap == null) {
                initMap = new InitParameterMap(servletContext);
            }
            return initMap;
        }

        @Override
        public String getRemoteUser() {
            return null;
        }


        @Override
        public Object getRequest() {
            return null;
        }

        @Override
        public void setRequest(Object request) {
        }

        @Override
        public String getRequestContextPath() {
            return null;
        }

        @Override
        public Map getRequestCookieMap() {
            return Collections.unmodifiableMap(Collections.emptyMap());
        }

        @Override
        public Map getRequestHeaderMap() {
            return Collections.unmodifiableMap(Collections.emptyMap());
        }


        @Override
        public Map getRequestHeaderValuesMap() {
            return Collections.unmodifiableMap(Collections.emptyMap());
        }


        @Override
        public Locale getRequestLocale() {
            return null;
        }

        @Override
        public Iterator getRequestLocales() {
            return null;
        }


        @Override
        public Map getRequestMap() {
            return Collections.emptyMap();
        }


        @Override
        public Map getRequestParameterMap() {
            return Collections.unmodifiableMap(Collections.emptyMap());
        }


        @Override
        public Iterator getRequestParameterNames() {
            return Collections.emptyList().iterator();
        }


        @Override
        public Map getRequestParameterValuesMap() {
            return Collections.unmodifiableMap(Collections.emptyMap());
        }


        @Override
        public String getRequestPathInfo() {
            return null;
        }


        @Override
        public String getRequestServletPath() {
            return null;
        }

        @Override
        public String getRequestContentType() {
            return null;
        }

        @Override
        public String getResponseContentType() {
            return null;
        }

        @Override
	public int getRequestContentLength() {
	    return -1;
	}

        @Override
        public URL getResource(String path) throws MalformedURLException {
            return servletContext.getResource(path);
        }


        @Override
        public InputStream getResourceAsStream(String path) {
            return servletContext.getResourceAsStream(path);
        }

        @Override
        public Set getResourcePaths(String path) {
            //noinspection unchecked
            return servletContext.getResourcePaths(path);
        }

        @Override
        public Object getResponse() {
            return null;
        }

        @Override
        public void setResponse(Object response) {
        }

        @Override
        public Object getSession(boolean create) {
            return null;
        }

        @Override
        public Map getSessionMap() {
            return Collections.emptyMap();
        }

        @Override
        public java.security.Principal getUserPrincipal() {
            return null;
        }

        @Override
        public boolean isUserInRole(String role) {
            return false;
        }

        @Override
        public void log(String message) {
            servletContext.log(message);
        }

        @Override
        public void log(String message, Throwable exception) {
            servletContext.log(message, exception);
        }

        @Override
        public void redirect(String url) throws IOException {
        }

        @Override
        public String getRequestCharacterEncoding() {
            return null;
        }

        @Override
        public void setRequestCharacterEncoding(String requestCharacterEncoding) throws UnsupportedEncodingException {

        }

        @Override
        public String getResponseCharacterEncoding() {
            return null;
        }

        @Override
        public void setResponseCharacterEncoding(String responseCharacterEncoding) {
        }

        @Override
        public void setResponseHeader(String name, String value) {
        }

        @Override
        public void addResponseHeader(String name, String value) {
        }

        @Override
        public String encodePartialActionURL(String url) {
            return null; 
        }

        @Override
        public String getRealPath(String path) {
            return servletContext.getRealPath(path);
        }
        
    } // END ServletContextAdapter

    static Map getThreadInitContextMap() {
        ConcurrentHashMap threadInitContext = null;
        try {
            Field threadMap = FacesContext.class.getDeclaredField("threadInitContext");
            threadMap.setAccessible(true);
            threadInitContext = (ConcurrentHashMap)threadMap.get(null);
        } catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) {
            if (LOGGER.isLoggable(Level.FINEST)) {
                LOGGER.log(Level.FINEST, "Unable to get (thread, init context) map", e);
            }
        }
        return threadInitContext;
    }

    static Map getInitContextServletContextMap() {
        ConcurrentHashMap initContextServletContext = null;
        try {
            Field initContextMap = FacesContext.class.getDeclaredField("initContextServletContext");
            initContextMap.setAccessible(true);
            initContextServletContext = (ConcurrentHashMap)initContextMap.get(null);
        } catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) {
            if (LOGGER.isLoggable(Level.FINEST)) {
                LOGGER.log(Level.FINEST, "Unable to get (init context, servlet context) map", e);
            }
        }
        return initContextServletContext;
    }

}