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

jakarta.faces.FactoryFinder Maven / Gradle / Ivy

/*
 * Copyright (c) 1997, 2021 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0, which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 *
 * This Source Code may also be made available under the following Secondary
 * Licenses when the conditions for such availability set forth in the
 * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
 * version 2 with the GNU Classpath Exception, which is available at
 * https://www.gnu.org/software/classpath/license.html.
 *
 * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
 */

package jakarta.faces;

import static jakarta.faces.ServletContextFacesContextFactory.SERVLET_CONTEXT_FINDER_NAME;

/**
 * 

* FactoryFinder implements the standard discovery algorithm for all factory objects * specified in the Jakarta Faces APIs. For a given factory class name, a corresponding implementation class is * searched for based on the following algorithm. Items are listed in order of decreasing search precedence: *

* *
    * *
  • *

    * If the Jakarta Faces configuration file bundled into the WEB-INF directory of the webapp contains * a factory entry of the given factory class name, that factory is used. *

    *
  • * *
  • *

    * If the Jakarta Faces configuration files named by the jakarta.faces.CONFIG_FILES * ServletContext init parameter contain any factory entries of the given factory class name, * those injectionProvider are used, with the last one taking precedence. *

    *
  • * *
  • *

    * If there are any Jakarta Faces configuration files bundled into the META-INF directory of any * jars on the ServletContext's resource paths, the factory entries of the given factory class * name in those files are used, with the last one taking precedence. *

    *
  • * *
  • *

    * If a META-INF/services/{factory-class-name} resource is visible to the web application class loader for * the calling application (typically as a injectionProvider of being present in the manifest of a JAR file), its first * line is read and assumed to be the name of the factory implementation class to use. *

    *
  • * *
  • *

    * If none of the above steps yield a match, the Jakarta Faces implementation specific class is used. *

    *
  • * *
* *

* If any of the injectionProvider found on any of the steps above happen to have a one-argument constructor, with * argument the type being the abstract factory class, that constructor is invoked, and the previous match is passed to * the constructor. For example, say the container vendor provided an implementation of * {@link jakarta.faces.context.FacesContextFactory}, and identified it in * META-INF/services/jakarta.faces.context.FacesContextFactory in a jar on the webapp ClassLoader. Also say * this implementation provided by the container vendor had a one argument constructor that took a * FacesContextFactory instance. The FactoryFinder system would call that one-argument * constructor, passing the implementation of FacesContextFactory provided by the Jakarta Faces * implementation. *

* *

* If a Factory implementation does not provide a proper one-argument constructor, it must provide a zero-arguments * constructor in order to be successfully instantiated. *

* *

* Once the name of the factory implementation class is located, the web application class loader for the calling * application is requested to load this class, and a corresponding instance of the class will be created. A side effect * of this rule is that each web application will receive its own instance of each factory class, whether the Jakarta * Server Faces implementation is included within the web application or is made visible through the container's * facilities for shared libraries. *

*/ public final class FactoryFinder { // ----------------------------------------------------------- Constructors /** * Package-private constructor to disable instantiation of this class. */ FactoryFinder() { } // ----------------------------------------------------- Manifest Constants /** *

* The property name for the {@link jakarta.faces.application.ApplicationFactory} class name. *

*/ public final static String APPLICATION_FACTORY = "jakarta.faces.application.ApplicationFactory"; /** *

* The property name for the {@link jakarta.faces.lifecycle.ClientWindowFactory} class name. *

* * @since 2.2 */ public final static String CLIENT_WINDOW_FACTORY = "jakarta.faces.lifecycle.ClientWindowFactory"; /** *

* The property name for the {@link jakarta.faces.context.ExceptionHandlerFactory} class name. *

*/ public final static String EXCEPTION_HANDLER_FACTORY = "jakarta.faces.context.ExceptionHandlerFactory"; /** *

* The property name for the {@link jakarta.faces.context.ExternalContextFactory} class name. *

*/ public final static String EXTERNAL_CONTEXT_FACTORY = "jakarta.faces.context.ExternalContextFactory"; /** *

* The property name for the {@link jakarta.faces.context.FacesContextFactory} class name. *

*/ public final static String FACES_CONTEXT_FACTORY = "jakarta.faces.context.FacesContextFactory"; /** *

* The property name for the {@link jakarta.faces.view.facelets.FaceletCacheFactory} class name. *

* * @since 2.1 */ public final static String FACELET_CACHE_FACTORY = "jakarta.faces.view.facelets.FaceletCacheFactory"; /** *

* The property name for the {@link jakarta.faces.context.FlashFactory} class name. *

* * @since 2.2 */ public final static String FLASH_FACTORY = "jakarta.faces.context.FlashFactory"; /** *

* The property name for the {@link jakarta.faces.flow.FlowHandlerFactory} class name. *

* * @since 2.2 */ public final static String FLOW_HANDLER_FACTORY = "jakarta.faces.flow.FlowHandlerFactory"; /** *

* The property name for the {@link jakarta.faces.context.PartialViewContextFactory} class name. *

*/ public final static String PARTIAL_VIEW_CONTEXT_FACTORY = "jakarta.faces.context.PartialViewContextFactory"; /** *

* The property name for the {@link jakarta.faces.component.visit.VisitContextFactory} class name. *

*/ public final static String VISIT_CONTEXT_FACTORY = "jakarta.faces.component.visit.VisitContextFactory"; /** *

* The property name for the {@link jakarta.faces.lifecycle.LifecycleFactory} class name. *

*/ public final static String LIFECYCLE_FACTORY = "jakarta.faces.lifecycle.LifecycleFactory"; /** *

* The property name for the {@link jakarta.faces.render.RenderKitFactory} class name. *

*/ public final static String RENDER_KIT_FACTORY = "jakarta.faces.render.RenderKitFactory"; /** *

* The property name for the {@link jakarta.faces.view.ViewDeclarationLanguage} class name. *

*/ public final static String VIEW_DECLARATION_LANGUAGE_FACTORY = "jakarta.faces.view.ViewDeclarationLanguageFactory"; /** *

* The property name for the {@link jakarta.faces.view.facelets.TagHandlerDelegate} class name. *

*/ public final static String TAG_HANDLER_DELEGATE_FACTORY = "jakarta.faces.view.facelets.TagHandlerDelegateFactory"; /** *

* The property name for the {@link jakarta.faces.component.search.SearchExpressionContext} class name. *

*/ public static final String SEARCH_EXPRESSION_CONTEXT_FACTORY = "jakarta.faces.component.search.SearchExpressionContextFactory"; // ------------------------------------------------------- Static Variables static final CurrentThreadToServletContext FACTORIES_CACHE = new CurrentThreadToServletContext(); // --------------------------------------------------------- Public Methods /** *

* Create (if necessary) and return a per-web-application instance of the * appropriate implementation class for the specified Jakarta Faces factory class, based on the discovery * algorithm described in the class description. *

* *

* The standard injectionProvider and wrappers in Jakarta Faces all implement the interface {@link FacesWrapper}. * If the returned Object is an implementation of one of the standard injectionProvider, it must be legal * to cast it to an instance of FacesWrapper and call {@link FacesWrapper#getWrapped} on the instance. *

* * @param factoryName Fully qualified name of the Jakarta Faces factory for which an implementation instance is * requested * @throws FacesException if the web application class loader cannot be identified * @throws FacesException if an instance of the configured factory implementation class cannot be loaded * @throws FacesException if an instance of the configured factory implementation class cannot be instantiated * @throws IllegalArgumentException if factoryName does not identify a standard Jakarta Faces * factory name * @throws IllegalStateException if there is no configured factory implementation class for the specified factory name * @throws NullPointerException if factoryname is null * * @return the found factory instance */ public static Object getFactory(String factoryName) throws FacesException { FactoryFinderInstance factoryFinder; // Bug 20458755: If the factory being requested is the special // SERVLET_CONTEXT_FINDER, do not lazily create the FactoryFinderInstance. if (SERVLET_CONTEXT_FINDER_NAME.equals(factoryName)) { factoryFinder = FACTORIES_CACHE.getFactoryFinder(false); } else { factoryFinder = FACTORIES_CACHE.getFactoryFinder(); } if (factoryFinder != null) { return factoryFinder.getFactory(factoryName); } return null; } /** *

* This method will store the argument factoryName/implName mapping in such a way that {@link #getFactory} * will find this mapping when searching for a match. *

* *

* This method has no effect if getFactory() has already been called looking for a factory for this * factoryName. *

* *

* This method can be used by implementations to store a factory mapping while parsing the Faces configuration file *

* * @throws IllegalArgumentException if factoryName does not identify a standard Jakarta Faces * factory name * @throws NullPointerException if factoryname is null * * @param factoryName the name to be used in a subsequent call to {@link #getFactory}. * * @param implName the fully qualified class name of the factory corresponding to {@code factoryName}. */ public static void setFactory(String factoryName, String implName) { FACTORIES_CACHE.getFactoryFinder().addFactory(factoryName, implName); } /** *

* Release any references to factory instances associated with the class * loader for the calling web application. This method must be called during of web * application shutdown. *

* * @throws FacesException if the web application class loader cannot be identified */ public static void releaseFactories() throws FacesException { synchronized (FACTORIES_CACHE) { if (!FACTORIES_CACHE.factoryFinderMap.isEmpty()) { FACTORIES_CACHE.getFactoryFinder().releaseFactories(); } FACTORIES_CACHE.removeFactoryFinder(); } } // -------------------------------------------------------- Private Methods // Called via reflection from automated tests. @SuppressWarnings("unused") private static void reInitializeFactoryManager() { FACTORIES_CACHE.resetSpecialInitializationCaseFlags(); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy