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

com.sun.faces.spi.InjectionProviderFactory Maven / Gradle / Ivy

Go to download

Jakarta Faces defines an MVC framework for building user interfaces for web applications, including UI components, state management, event handing, input validation, page navigation, and support for internationalization and accessibility.

There is a newer version: 4.1.2
Show newest version
/*
 * Copyright (c) 1997, 2020 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 com.sun.faces.spi;

import static java.util.logging.Level.WARNING;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;

import com.sun.faces.RIConstants;
import com.sun.faces.config.WebConfiguration;
import com.sun.faces.config.WebConfiguration.WebContextInitParameter;
import com.sun.faces.util.FacesLogger;
import com.sun.faces.util.Util;
import com.sun.faces.vendor.WebContainerInjectionProvider;

import jakarta.faces.context.ExternalContext;
import jakarta.servlet.ServletContext;

/**
 * 

* A factory for creating InjectionProvider instances. *

*/ public class InjectionProviderFactory { /** *

* Our no-op InjectionProvider. *

*/ private static final InjectionProvider NOOP_PROVIDER = new NoopInjectionProvider(); private static final InjectionProvider GENERIC_WEB_PROVIDER = new WebContainerInjectionProvider(); private static final String INJECTION_SERVICE = "META-INF/services/com.sun.faces.spi.injectionprovider"; /** *

* The system property that will be checked for alternate InjectionProvider implementations. *

*/ private static final String INJECTION_PROVIDER_PROPERTY = RIConstants.FACES_PREFIX + "InjectionProvider"; private static final Logger LOGGER = FacesLogger.APPLICATION.getLogger(); private static final String[] EMPTY_ARRAY = new String[] {}; /** *

* Creates a new instance of the class specified by the com.sun.faces.InjectionProvider system property. If * this propery is not defined, then a default, no-op, InjectionProvider will be returned. * * @param extContext ExteranlContext for the current request * * @return an implementation of the InjectionProvider interfaces */ public static InjectionProvider createInstance(ExternalContext extContext) { String providerClass = findProviderClass(extContext); InjectionProvider provider = getProviderInstance(providerClass, extContext); if (!NoopInjectionProvider.class.equals(provider.getClass()) && !WebContainerInjectionProvider.class.equals(provider.getClass())) { if (LOGGER.isLoggable(Level.FINE)) { LOGGER.log(Level.FINE, "faces.spi.injection.provider_configured", new Object[] { provider.getClass().getName() }); } return provider; } else if (WebContainerInjectionProvider.class.equals(provider.getClass())) { LOGGER.info("faces.core.injection.provider_generic_web_configured"); return provider; } else { LOGGER.log(WARNING, "faces.spi.injection.no_injection"); return provider; } } private static InjectionProvider getProviderInstance(String className, ExternalContext extContext) { InjectionProvider provider = NOOP_PROVIDER; if (className != null) { try { Class clazz = Util.loadClass(className, InjectionProviderFactory.class); if (implementsInjectionProvider(clazz)) { try { Constructor ctor = clazz.getConstructor(ServletContext.class); return (InjectionProvider) ctor.newInstance((ServletContext) extContext.getContext()); } catch (NoSuchMethodException nsme) { return (InjectionProvider) clazz.getDeclaredConstructor().newInstance(); } catch (InvocationTargetException ite) { if (LOGGER.isLoggable(Level.SEVERE)) { LOGGER.log(Level.SEVERE, "faces.spi.injection.provider_cannot_instantiate", new Object[] { className }); LOGGER.log(Level.SEVERE, "", ite); } } } else { if (LOGGER.isLoggable(Level.SEVERE)) { LOGGER.log(Level.SEVERE, "faces.spi.injection.provider_not_implemented", new Object[] { className }); } } } catch (ClassNotFoundException cnfe) { if (LOGGER.isLoggable(Level.SEVERE)) { LOGGER.log(Level.SEVERE, "faces.spi.injection.provider_not_found", new Object[] { className }); } } catch (IllegalArgumentException | ReflectiveOperationException | SecurityException ie) { if (LOGGER.isLoggable(Level.SEVERE)) { LOGGER.log(Level.SEVERE, "faces.spi.injection.provider_cannot_instantiate", new Object[] { className }); LOGGER.log(Level.SEVERE, "", ie); } } } // We weren't able to find a configured provider - check // to see if the PostConstruct and PreDestroy annotations // are available. If they are, then default to the // WebContainerInjectionProvider, otherwise, use // NoopInjectionProvider if (NOOP_PROVIDER.equals(provider)) { try { if (Util.loadClass("jakarta.annotation.PostConstruct", null) != null && Util.loadClass("jakarta.annotation.PreDestroy", null) != null) { provider = GENERIC_WEB_PROVIDER; } } catch (Exception e) { provider = NOOP_PROVIDER; } } return provider; } /** *

* Determine if the specified class implements the InjectionProvider interfaces. *

* * @param clazz the class in question * @return true if clazz implements the InjectionProvider interface */ private static boolean implementsInjectionProvider(Class clazz) { return InjectionProvider.class.isAssignableFrom(clazz); } /** *

* Determine if the specified class extends the DiscoverableInjectionProvider interfaces. *

* * @param clazz the class in question * @return true if clazz implements the InjectionProvider interface */ private static boolean extendsDiscoverableInjectionProvider(Class clazz) { return DiscoverableInjectionProvider.class.isAssignableFrom(clazz); } /** *

* Attempt to find an InjectionProvider based on the following algorithm: *

*
    *
  • Check for an explicit configuration within the web.xml using the key * com.sun.faces.injectionProvider. If found, return the value.
  • *
  • Check for a system property keyed by com.sun.faces.InjectionProvider. If found, return the * value.
  • *
  • Check for entries within META-INF/services/com.sun.faces.injectionprovider. If entries are found and * the entries extend DiscoverableInjectionProvider, invoke * isInjectionFeatureAvailable(String) passing in the configured delegate. If * isInjectionFeatureAvailable(String) returns true return the service entry.
  • *
  • If no InjectionProviders are found, return null
  • Tries to find a provider class in a web * context parameter. If not present it tries to find it as a System property. If still not found returns null. *
      * * @param extContext The ExternalContext for this request * @return The provider class name specified in the container configuration, or null if not found. */ private static String findProviderClass(ExternalContext extContext) { WebConfiguration webConfig = WebConfiguration.getInstance(extContext); String provider = webConfig.getOptionValue(WebContextInitParameter.InjectionProviderClass); if (provider != null) { return provider; } else { provider = System.getProperty(INJECTION_PROVIDER_PROPERTY); } if (provider != null) { return provider; } else { String[] serviceEntries = getServiceEntries(); if (serviceEntries.length > 0) { for (int i = 0; i < serviceEntries.length; i++) { provider = getProviderFromEntry(extContext.getApplicationMap(), serviceEntries[i]); if (provider != null) { break; } } } else { return provider; } } return provider; } private static String getProviderFromEntry(Map appMap, String entry) { if (entry == null) { return null; } String[] parts = Util.split(appMap, entry, ":"); if (parts.length != 2) { if (LOGGER.isLoggable(Level.SEVERE)) { LOGGER.log(Level.SEVERE, "faces.spi.injection.invalid_service_entry", new Object[] { entry }); } return null; } try { Class clazz = Util.loadClass(parts[0], null); if (extendsDiscoverableInjectionProvider(clazz)) { if (DiscoverableInjectionProvider.isInjectionFeatureAvailable(parts[1])) { return parts[0]; } } else { if (LOGGER.isLoggable(Level.SEVERE)) { LOGGER.log(Level.SEVERE, "faces.spi.injection.provider.entry_not_discoverable", new Object[] { parts[0] }); } return null; } } catch (ClassNotFoundException cnfe) { if (LOGGER.isLoggable(Level.SEVERE)) { LOGGER.log(Level.SEVERE, "faces.spi.injection.provider_not_found", new Object[] { parts[0] }); } return null; } return null; } private static String[] getServiceEntries() { List results = null; ClassLoader loader = Thread.currentThread().getContextClassLoader(); if (loader == null) { return EMPTY_ARRAY; } Enumeration urls = null; try { urls = loader.getResources(INJECTION_SERVICE); } catch (IOException ioe) { if (LOGGER.isLoggable(Level.SEVERE)) { LOGGER.log(Level.SEVERE, ioe.toString(), ioe); } } if (urls != null) { InputStream input = null; BufferedReader reader = null; while (urls.hasMoreElements()) { try { if (results == null) { results = new ArrayList<>(); } URL url = urls.nextElement(); URLConnection conn = url.openConnection(); conn.setUseCaches(false); input = conn.getInputStream(); if (input != null) { try { reader = new BufferedReader(new InputStreamReader(input, "UTF-8")); } catch (Exception e) { // The DM_DEFAULT_ENCODING warning is acceptable here // because we explicitly *want* to use the Java runtime's // default encoding. reader = new BufferedReader(new InputStreamReader(input)); } for (String line = reader.readLine(); line != null; line = reader.readLine()) { results.add(line.trim()); } } } catch (Exception e) { if (LOGGER.isLoggable(Level.SEVERE)) { LOGGER.log(Level.SEVERE, "faces.spi.provider.cannot_read_service", new Object[] { INJECTION_SERVICE }); LOGGER.log(Level.SEVERE, e.toString(), e); } } finally { if (input != null) { try { input.close(); } catch (Exception e) { if (LOGGER.isLoggable(Level.FINEST)) { LOGGER.log(Level.FINEST, "Closing stream", e); } } } if (reader != null) { try { reader.close(); } catch (Exception e) { if (LOGGER.isLoggable(Level.FINEST)) { LOGGER.log(Level.FINEST, "Closing stream", e); } } } } } } return results != null && !results.isEmpty() ? results.toArray(new String[results.size()]) : EMPTY_ARRAY; } /** *

      * A no-op implementation of InjectionProvider which will be used when the #INJECTION_PROVIDER_PROPERTY is * not specified or is invalid. *

      */ private static final class NoopInjectionProvider implements InjectionProvider, AnnotationScanner { /** *

      * This is a no-op. *

      * * @param managedBean target ManagedBean */ @Override public void inject(Object managedBean) { } @Override public Map> getAnnotatedClassesInCurrentModule(ServletContext extContext) throws InjectionProviderException { return Collections.emptyMap(); } /** *

      * This is a no-op. *

      * * @param managedBean target ManagedBean */ @Override public void invokePreDestroy(Object managedBean) { } /** *

      * This is a no-op. *

      * * @param managedBean target ManagedBean */ @Override public void invokePostConstruct(Object managedBean) throws InjectionProviderException { } } } // END InjectionProviderFactory




© 2015 - 2025 Weber Informatics LLC | Privacy Policy