Package com.sun.faces.application

Source Code of com.sun.faces.application.ApplicationAssociate

/*
* $Id: ApplicationAssociate.java,v 1.40.2.1 2007/04/26 16:51:52 rlubke Exp $
*/

/*
* The contents of this file are subject to the terms
* of the Common Development and Distribution License
* (the License). You may not use this file except in
* compliance with the License.
*
* You can obtain a copy of the License at
* https://javaserverfaces.dev.java.net/CDDL.html or
* legal/CDDLv1.0.txt.
* See the License for the specific language governing
* permission and limitations under the License.
*
* When distributing Covered Code, include this CDDL
* Header Notice in each file and include the License file
* at legal/CDDLv1.0.txt.
* If applicable, add the following below the CDDL Header,
* with the fields enclosed by brackets [] replaced by
* your own identifying information:
* "Portions Copyrighted [year] [name of copyright owner]"
*
* [Name of File] [ver.__] [Date]
*
* Copyright 2005 Sun Microsystems Inc. All Rights Reserved
*/

package com.sun.faces.application;

import javax.el.CompositeELResolver;
import javax.el.ExpressionFactory;
import javax.el.ELResolver;
import javax.faces.FacesException;
import javax.faces.component.UIViewRoot;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.faces.el.PropertyResolver;
import javax.faces.el.VariableResolver;
import javax.servlet.ServletContext;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.ResourceBundle;
import java.util.TreeSet;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.text.MessageFormat;

import com.sun.faces.RIConstants;
import com.sun.faces.config.ConfigureListener;
import com.sun.faces.config.beans.ResourceBundleBean;
import com.sun.faces.spi.ManagedBeanFactory;
import com.sun.faces.spi.InjectionProviderFactory;
import com.sun.faces.spi.InjectionProvider;
import com.sun.faces.spi.InjectionProviderException;
import com.sun.faces.spi.ManagedBeanFactory.Scope;
import com.sun.faces.util.MessageUtils;
import com.sun.faces.util.Util;

/**
* <p>Break out the things that are associated with the Application, but
* need to be present even when the user has replaced the Application
* instance.</p>
*
* <p>For example: the user replaces ApplicationFactory, and wants to
* intercept calls to createValueExpression() and createMethodExpression() for
* certain kinds of expressions, but allow the existing application to
* handle the rest.</p>
*/

public class ApplicationAssociate {

    // Log instance for this class
    private static final Logger LOGGER = Util.getLogger(Util.FACES_LOGGER
                                                        + Util.APPLICATION_LOGGER);

    private static final String APPLICATION_IMPL_ATTR_NAME = RIConstants.FACES_PREFIX +
                                                             "ApplicationImpl";

    private ApplicationImpl app = null;

    //
    // This map stores "managed bean name" | "managed bean factory"
    // mappings.
    //
    private Map<String, ManagedBeanFactory> managedBeanFactoriesMap = null;


    /**
     * Overall Map containing <code>from-view-id</code> key and
     * <code>ArrayList</code> of <code>ConfigNavigationCase</code>
     * objects for that key; The <code>from-view-id</code> strings in
     * this map will be stored as specified in the configuration file -
     * some of them will have a trailing asterisk "*" signifying wild
     * card, and some may be specified as an asterisk "*".
     */
    private Map<String,List<ConfigNavigationCase>> caseListMap = null;

    /**
     * The List that contains all view identifier strings ending in an
     * asterisk "*".  The entries are stored without the trailing
     * asterisk.
     */
    private TreeSet<String> wildcardMatchList = null;

    // Flag indicating that a response has been rendered.
    private boolean responseRendered = false;

    private static final String ASSOCIATE_KEY = RIConstants.FACES_PREFIX +
                                                "ApplicationAssociate";

    private List<ELResolver> elResolversFromFacesConfig = null;

    @SuppressWarnings("deprecation")
    private VariableResolver legacyVRChainHead = null;

    @SuppressWarnings("deprecation")
    private PropertyResolver legacyPRChainHead = null;
    private ExpressionFactory expressionFactory = null;

    @SuppressWarnings("deprecation")
    private PropertyResolver legacyPropertyResolver = null;

    @SuppressWarnings("deprecation")
    private VariableResolver legacyVariableResolver = null;
    private CompositeELResolver facesELResolverForJsp = null;

    private InjectionProvider injectionProvider;

    private String contextName;
    private boolean requestServiced;

    public ApplicationAssociate(ApplicationImpl appImpl) {
    app = appImpl;

        ExternalContext externalContext = FacesContext.getCurrentInstance().getExternalContext();
        if (externalContext == null) {
            throw new IllegalStateException(
                MessageUtils.getExceptionMessageString(
                    MessageUtils.APPLICATION_ASSOCIATE_CTOR_WRONG_CALLSTACK_ID));
        }

        if (null != externalContext.getApplicationMap().get(ASSOCIATE_KEY)) {
            throw new IllegalStateException(
                MessageUtils.getExceptionMessageString(
                    MessageUtils.APPLICATION_ASSOCIATE_EXISTS_ID));
        }
        externalContext.getApplicationMap().put(APPLICATION_IMPL_ATTR_NAME,
                                                appImpl);
        externalContext.getApplicationMap().put(ASSOCIATE_KEY, this);
        //noinspection CollectionWithoutInitialCapacity
        managedBeanFactoriesMap = new HashMap<String, ManagedBeanFactory>();
        //noinspection CollectionWithoutInitialCapacity
        caseListMap = new HashMap<String,List<ConfigNavigationCase>>();
        wildcardMatchList = new TreeSet<String>(new SortIt());
        injectionProvider = InjectionProviderFactory.createInstance(externalContext);
    }

    public static ApplicationAssociate getInstance(ExternalContext
        externalContext) {
      if(externalContext == null) {
        return null;
      }
        Map applicationMap = externalContext.getApplicationMap();
    return ((ApplicationAssociate)
        applicationMap.get(ASSOCIATE_KEY));
    }

    public static ApplicationAssociate getInstance(ServletContext context) {
      if(context == null) {
        return null;
      }
        return (ApplicationAssociate) context.getAttribute(ASSOCIATE_KEY);
    }

    public static void clearInstance(ExternalContext
        externalContext) {
        Map applicationMap = externalContext.getApplicationMap();
        ApplicationAssociate me = (ApplicationAssociate) applicationMap.get(ASSOCIATE_KEY);
        if (null != me) {
            if (null != me.resourceBundles) {
                me.resourceBundles.clear();
            }
        }
    applicationMap.remove(ASSOCIATE_KEY);
    }

    /**
     * This method is called by <code>ConfigureListener</code> and will
     * contain any <code>VariableResolvers</code> defined within
     * faces-config configuration files.
     * @param resolver
     */
    @SuppressWarnings("deprecation")
    public void setLegacyVRChainHead(VariableResolver resolver) {
        this.legacyVRChainHead = resolver;
    }

    @SuppressWarnings("deprecation")
    public VariableResolver getLegacyVRChainHead() {
        return legacyVRChainHead;
    }

    /**
     * This method is called by <code>ConfigureListener</code> and will
     * contain any <code>PropertyResolvers</code> defined within
     * faces-config configuration files.
     * @param resolver
     */
    @SuppressWarnings("deprecation")
    public void setLegacyPRChainHead(PropertyResolver resolver) {
        this.legacyPRChainHead = resolver;
    }

    @SuppressWarnings("deprecation")
    public PropertyResolver getLegacyPRChainHead() {
        return legacyPRChainHead;
    }

    public CompositeELResolver getFacesELResolverForJsp() {
        return facesELResolverForJsp;
    }

    public void setFacesELResolverForJsp(CompositeELResolver celr) {
        facesELResolverForJsp = celr;
    }

    public void setELResolversFromFacesConfig(List<ELResolver> resolvers) {
        this.elResolversFromFacesConfig = resolvers;
    }

    public List<ELResolver> getELResolversFromFacesConfig() {
         return elResolversFromFacesConfig;
    }

    public void setExpressionFactory(ExpressionFactory expressionFactory) {
        this.expressionFactory = expressionFactory;
    }

    public ExpressionFactory getExpressionFactory() {
        return this.expressionFactory;
    }

    public List<ELResolver> getApplicationELResolvers() {
        return app.getApplicationELResolvers();
    }

    public InjectionProvider getInjectionProvider() {
        return injectionProvider;
    }

    public void setContextName(String contextName) {
        this.contextName = contextName;
    }

    public String getContextName() {
        return contextName;
    }

    /**
     * Maintains the PropertyResolver called through
     * Application.setPropertyResolver()
     */
    @SuppressWarnings("deprecation")
    public void setLegacyPropertyResolver(PropertyResolver resolver){
        this.legacyPropertyResolver = resolver;
    }

     /**
     * Returns the PropertyResolver called through
     * Application.getPropertyResolver()
     */
     @SuppressWarnings("deprecation")
    public PropertyResolver getLegacyPropertyResolver(){
        return legacyPropertyResolver;
    }

    /**
     * Maintains the PropertyResolver called through
     * Application.setVariableResolver()
     */
    @SuppressWarnings("deprecation")
    public void setLegacyVariableResolver(VariableResolver resolver){
        this.legacyVariableResolver = resolver;
    }

    /**
     * Returns the VariableResolver called through
     * Application.getVariableResolver()
     */
    @SuppressWarnings("deprecation")
    public VariableResolver getLegacyVariableResolver(){
        return legacyVariableResolver;
    }


    /**
     * Called by application code to indicate we've processed the
     * first request to the application.
     */
    public void setRequestServiced() {
        this.requestServiced = true;
    }

    /**
     * @return <code>true</code> if we've processed a request, otherwise
     *  <code>false</code>
     */
    public boolean hasRequestBeenServiced() {
        return requestServiced;
    }


    /**
     * Add a navigation case to the internal case list.  If a case list
     * does not already exist in the case list map containing this case
     * (identified by <code>from-view-id</code>), start a new list,
     * add the case to it, and store the list in the case list map.
     * If a case list already exists, see if a case entry exists in the list
     * with a matching <code>from-view-id</code><code>from-action</code>
     * <code>from-outcome</code> combination.  If there is suach an entry,
     * overwrite it with this new case.  Otherwise, add the case to the list.
     *
     * @param navigationCase the navigation case containing navigation
     *                       mapping information from the configuration file.
     */
    public void addNavigationCase(ConfigNavigationCase navigationCase) {

        String fromViewId = navigationCase.getFromViewId();
        List<ConfigNavigationCase> caseList = caseListMap.get(fromViewId);
        if (caseList == null) {
            //noinspection CollectionWithoutInitialCapacity
            caseList = new ArrayList<ConfigNavigationCase>();
            caseList.add(navigationCase);
            caseListMap.put(fromViewId, caseList);
        } else {
            String key = navigationCase.getKey();
            boolean foundIt = false;
            for (int i = 0; i < caseList.size(); i++) {
                ConfigNavigationCase navCase = caseList.get(i);
                // if there already is a case existing for the
                // fromviewid/fromaction.fromoutcome combination,
                // replace it ...  (last one wins).
                //
                if (key.equals(navCase.getKey())) {
                    caseList.set(i, navigationCase);
                    foundIt = true;
                    break;
                }
            }
            if (!foundIt) {
                caseList.add(navigationCase);
            }
        }
        if (fromViewId.endsWith("*")) {
            fromViewId =
                 fromViewId.substring(0, fromViewId.lastIndexOf('*'));
            wildcardMatchList.add(fromViewId);
        }

    }


    /**
     * Return a <code>Map</code> of navigation mappings loaded from
     * the configuration system.  The key for the returned <code>Map</code>
     * is <code>from-view-id</code>, and the value is a <code>List</code>
     * of navigation cases.
     *
     * @return Map the map of navigation mappings.
     */
    public Map<String,List<ConfigNavigationCase>> getNavigationCaseListMappings() {
        if (caseListMap == null) {
            return Collections.emptyMap();
        }
        return caseListMap;
    }


    /**
     * Return all navigation mappings whose <code>from-view-id</code>
     * contained a trailing "*".
     *
     * @return <code>TreeSet</code> The navigation mappings sorted in
     *         descending order.
     */
    public TreeSet<String> getNavigationWildCardList() {
        return wildcardMatchList;
    }

    public ResourceBundle getResourceBundle(FacesContext context,
                                            String var) {
        if (!resourceBundles.containsKey(var)) {
            return null;
        }
        UIViewRoot root;
        // Start out with the default locale
        Locale locale;
        Locale defaultLocale = Locale.getDefault();
        locale = defaultLocale;
        // See if this FacesContext has a ViewRoot
        if (null != (root = context.getViewRoot())) {
            // If so, ask it for its Locale
            if (null == (locale = root.getLocale())) {
                // If the ViewRoot has no Locale, fall back to the default.
                locale = defaultLocale;
            }
        }
        assert(null != locale);
        ResourceBundleBean bean = resourceBundles.get(var);
        ResourceBundle result = null;

        if (null != bean) {
            String baseName = bean.getBasename();
            if (null != baseName) {
                result =
                    ResourceBundle.getBundle(baseName,
                                             locale,
                                             Thread.currentThread().
                                                 getContextClassLoader());
            }
        }
        // PENDING(edburns): should cache these based on var/Locale pair for performance
        return result;
    }

    /**
     * keys: <var> element from faces-config<p>
     *
     * values: ResourceBundleBean instances.
     */

    @SuppressWarnings({"CollectionWithoutInitialCapacity"})
    Map<String,ResourceBundleBean> resourceBundles = new HashMap<String, ResourceBundleBean>();

    public void addResourceBundleBean(String var, ResourceBundleBean bean) {
        resourceBundles.put(var, bean);
    }

    public Map<String,ResourceBundleBean> getResourceBundleBeanMap() {
        return resourceBundles;
    }

    /**
     * <p>Adds a new mapping of managed bean name to a managed bean
     * factory instance.</p>
     *
     * @param managedBeanName the name of the managed bean that will
     *                        be created by the managed bean factory instance.
     * @param factory         the managed bean factory instance.
     */
    synchronized public void addManagedBeanFactory(String managedBeanName,
                                                   ManagedBeanFactory factory) {
        managedBeanFactoriesMap.put(managedBeanName, factory);
    factory.setManagedBeanFactoryMap(managedBeanFactoriesMap);
        if (LOGGER.isLoggable(Level.FINE)) {
            LOGGER.log(Level.FINE, MessageFormat.format("Added managedBeanFactory {0} for {1}",
                                                        factory,
                                                        managedBeanName));
        }
    }

    public Map<String,ManagedBeanFactory> getManagedBeanFactoryMap() {
        return managedBeanFactoriesMap;
    }



    /**
     * <p>The managedBeanFactories HashMap has been populated
     * with ManagedBeanFactoryImpl object keyed by the bean name.
     * Find the ManagedBeanFactoryImpl object and if it exists instantiate
     * the bean and store it in the appropriate scope, if any.</p>
     *
     * @param context         The Faces context.
     * @param managedBeanName The name identifying the managed bean.
     * @return The managed bean.
     * @throws FacesException if the managed bean
     *                                   could not be created.
     */
    public Object createAndMaybeStoreManagedBeans(FacesContext context,
                                                  String managedBeanName) throws FacesException {
        ManagedBeanFactory managedBean = managedBeanFactoriesMap.get(managedBeanName);
        if (managedBean == null) {
            if (LOGGER.isLoggable(Level.FINE)) {
                LOGGER.fine("Couldn't find a factory for " + managedBeanName);
            }
            return null;
        }

        Object bean;
        Scope scope = managedBean.getScope();

        boolean scopeIsApplication;
        boolean scopeIsRequest;
        ExternalContext extContext = context.getExternalContext();
        if ((scopeIsApplication = (scope == Scope.APPLICATION)) ||
            ((scope == Scope.SESSION))) {
            if (scopeIsApplication) {
                synchronized (extContext.getContext()) {
                    try {
                        bean = managedBean.newInstance(context);
                        if (LOGGER.isLoggable(Level.FINE)) {
                            LOGGER.fine(MessageFormat.format("Created application scoped bean {0} successfully ", managedBeanName));
                        }
                    } catch (Exception ex) {
                        Object[] params = {managedBeanName};
                        if (LOGGER.isLoggable(Level.SEVERE)) {
                            LOGGER.log(Level.SEVERE,
                                       "jsf.managed_bean_creation_error", params);
                        }
                        throw new FacesException(ex);
                    }
                    //add bean to appropriate scope
                    extContext.getApplicationMap().put(managedBeanName, bean);
                }
            } else {
                synchronized (extContext.getSession(true)) {
                    try {
                        bean = managedBean.newInstance(context);
                        if (LOGGER.isLoggable(Level.FINE)) {
                            LOGGER.fine(MessageFormat.format("Created session scoped bean {0} successfully ", managedBeanName));
                        }
                    } catch (Exception ex) {
                        Object[] params = {managedBeanName};
                        if (LOGGER.isLoggable(Level.SEVERE)) {
                            LOGGER.log(Level.SEVERE,
                                       "jsf.managed_bean_creation_error", params);
                        }
                        throw new FacesException(ex);
                    }
                    //add bean to appropriate scope
                    extContext.getSessionMap().put(managedBeanName, bean);
                }
            }
        } else {
            scopeIsRequest = (scope == Scope.REQUEST);
            try {
                bean = managedBean.newInstance(context);
                if (LOGGER.isLoggable(Level.FINE)) {
                    LOGGER.log(Level.FINE, MessageFormat.format("Created bean {0} successfully ", managedBeanName));
                }
            } catch (Exception ex) {
                Object[] params = {managedBeanName};
                if (LOGGER.isLoggable(Level.SEVERE)) {
                    LOGGER.log(Level.SEVERE,
                               "jsf.managed_bean_creation_error", params);
                }
                throw new FacesException(ex);
            }

            if (scopeIsRequest) {
                extContext.getRequestMap().put(managedBeanName, bean);
            }
        }
        return bean;
    }

    // This is called by ViewHandlerImpl.renderView().
    void responseRendered() {
        responseRendered = true;
    }

    boolean isResponseRendered() {
    return responseRendered;
    }


    /**
     * <p>Attempts to look up a ManagedBeanFactory from the
     * managedBeanFactoriesMap.  If not </code>null</code> and
     * <code>ManagedBeanFactory.isInjectable()</code> returns true,
     * pass <code>bean</code> to <code>InjectionProvider.invokePreDestr
     *
     * @param beanName the name of the bean for which to call PreDestroy
     * annotated methods.  If <code>null</code>, all beans in argument
     * <code>scope</code> have their PreDestroy annotated methods
     * called.
     *
     * @param bean the target bean associated with <code>beanName</code>
     *
     * @param scope the managed bean scope in which to look for the bean
     * or beans.
     */

    public void handlePreDestroy(String beanName, Object bean, Scope scope) {
        ManagedBeanFactory factory = managedBeanFactoriesMap.get(beanName);
        if (factory != null && factory.isInjectable()) {
            try {
                injectionProvider.invokePreDestroy(bean);
            } catch (InjectionProviderException ipe) {
                if (LOGGER.isLoggable(Level.SEVERE)) {
                    LOGGER.log(Level.SEVERE, ipe.getMessage(), ipe);
                }
            }
        }
    }

    /**
     * This Comparator class will help sort the <code>ConfigNavigationCase</code> objects
     * based on their <code>fromViewId</code> properties in descending order -
     * largest string to smallest string.
     */
    static class SortIt implements Comparator<String> {

        public int compare(String fromViewId1, String fromViewId2) {
            return -(fromViewId1.compareTo(fromViewId2));
        }
    }

    /**
     * Holds value of property JSFVersionTracker.
     */
    private com.sun.faces.config.JSFVersionTracker JSFVersionTracker;

    /**
     * Getter for property JSFVersionTracker.
     * @return Value of property JSFVersionTracker.
     */
    public com.sun.faces.config.JSFVersionTracker getJSFVersionTracker() {
        return this.JSFVersionTracker;
    }

    /**
     * Setter for property JSFVersionTracker.
     * @param JSFVersionTracker New value of property JSFVersionTracker.
     */
    public void setJSFVersionTracker(com.sun.faces.config.JSFVersionTracker JSFVersionTracker) {
        this.JSFVersionTracker = JSFVersionTracker;
    }

}
TOP

Related Classes of com.sun.faces.application.ApplicationAssociate

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.