/** * Release any references to factory instances associated with the class loader for the calling * web application. This method should be called as apart of web application shutdown in a * container where the JavaServer Faces API classes are part of the container itself, rather than * being included inside the web application. * * @throws FacesException if the web application class loader cannot be identified */ public static void releaseFactories() throws FacesException { // Identify the web application class loader ClassLoader cl = getClassLoader(); FACTORIES_CACHE.removeApplicationFactoryManager(cl); }
/** * Implement the decorator pattern for the factory implementation. * * <p> * * <p>If <code>previousImpl</code> is non-<code>null</code> and the class named by the argument * <code>implName</code> has a one arg contstructor of type <code>factoryName</code>, instantiate * it, passing previousImpl to the constructor. * * <p> * * <p>Otherwise, we just instantiate and return <code>implName</code>. * * @param classLoader the ClassLoader from which to load the class * @param factoryName the fully qualified class name of the factory. * @param implName the fully qualified class name of a class that implements the factory. * @param previousImpl if non-<code>null</code>, the factory instance to be passed to the * constructor of the new factory. */ private static Object getImplGivenPreviousImpl( ClassLoader classLoader, String factoryName, String implName, Object previousImpl) { Class clazz; Class factoryClass = null; Class[] getCtorArg; Object[] newInstanceArgs = new Object[1]; Constructor ctor; Object result = null; InjectionProvider provider = null; // if we have a previousImpl and the appropriate one arg ctor. if ((null != previousImpl) && (null != (factoryClass = getFactoryClass(factoryName)))) { try { clazz = Class.forName(implName, false, classLoader); getCtorArg = new Class[1]; getCtorArg[0] = factoryClass; ctor = clazz.getConstructor(getCtorArg); newInstanceArgs[0] = previousImpl; result = ctor.newInstance(newInstanceArgs); FactoryManager fm = FACTORIES_CACHE.getApplicationFactoryManager(classLoader); provider = fm.getInjectionProvider(); if (null != provider) { provider.inject(result); provider.invokePostConstruct(result); } else { if (LOGGER.isLoggable(Level.SEVERE)) { LOGGER.log( Level.SEVERE, "Unable to inject {0} because no InjectionProvider can be found. Does this container implement the Mojarra Injection SPI?", result); } } } catch (NoSuchMethodException nsme) { // fall through to "zero-arg-ctor" case factoryClass = null; } catch (Exception e) { throw new FacesException(implName, e); } } if (null == previousImpl || null == factoryClass) { // we have either no previousImpl or no appropriate one arg // ctor. try { clazz = Class.forName(implName, false, classLoader); // since this is the hard coded implementation default, // there is no preceding implementation, so don't bother // with a non-zero-arg ctor. result = clazz.newInstance(); } catch (Exception e) { throw new FacesException(implName, e); } } return result; }
/** * This method will store the argument <code>factoryName/implName</code> mapping in such a way * that {@link #getFactory} will find this mapping when searching for a match. * * <p> * * <p>This method has no effect if <code>getFactory()</code> has already been called looking for a * factory for this <code>factoryName</code>. * * <p> * * <p>This method can be used by implementations to store a factory mapping while parsing the * Faces configuration file * * @throws IllegalArgumentException if <code>factoryName</code> does not identify a standard * JavaServer Faces factory name * @throws NullPointerException if <code>factoryname</code> is null */ public static void setFactory(String factoryName, String implName) { validateFactoryName(factoryName); // Identify the web application class loader ClassLoader classLoader = getClassLoader(); FactoryManager manager = FACTORIES_CACHE.getApplicationFactoryManager(classLoader); manager.addFactory(factoryName, implName); }
/** * <span class="changed_modified_2_0">Create</span> (if necessary) and return a * per-web-application instance of the appropriate implementation class for the specified * JavaServer Faces factory class, based on the discovery algorithm described in the class * description. * * <p class="changed_added_2_0">The standard factories and wrappers in JSF all implement the * interface {@link FacesWrapper}. If the returned <code>Object</code> is an implementation of one * of the standard factories, it must be legal to cast it to an instance of <code>FacesWrapper * </code> and call {@link FacesWrapper#getWrapped} on the instance. * * @param factoryName Fully qualified name of the JavaServer 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 <code>factoryName</code> does not identify a standard * JavaServer Faces factory name * @throws IllegalStateException if there is no configured factory implementation class for the * specified factory name * @throws NullPointerException if <code>factoryname</code> is null */ public static Object getFactory(String factoryName) throws FacesException { validateFactoryName(factoryName); // Identify the web application class loader ClassLoader classLoader = getClassLoader(); FactoryManager manager = FACTORIES_CACHE.getApplicationFactoryManager(classLoader); return manager.getFactory(classLoader, factoryName); }
/** * <span class="changed_modified_2_0">Release</span> any references to factory instances * associated with the class loader for the calling web application. <span * class="changed_modified_2_0">This method must be called during of web application * shutdown.</span> * * @throws FacesException if the web application class loader cannot be identified */ public static void releaseFactories() throws FacesException { // Identify the web application class loader ClassLoader cl = getClassLoader(); if (!FACTORIES_CACHE.applicationMap.isEmpty()) { FactoryManager fm = FACTORIES_CACHE.getApplicationFactoryManager(cl); InjectionProvider provider = fm.getInjectionProvider(); if (null != provider) { Collection factories = null; for (Map.Entry<FactoryManagerCacheKey, FactoryManager> entry : FACTORIES_CACHE.applicationMap.entrySet()) { factories = entry.getValue().getFactories(); for (Object curFactory : factories) { try { provider.invokePreDestroy(curFactory); } catch (Exception ex) { if (LOGGER.isLoggable(Level.SEVERE)) { String message = MessageFormat.format( "Unable to invoke @PreDestroy annotated methods on {0}.", curFactory); LOGGER.log(Level.SEVERE, message, ex); } } } } } else { if (LOGGER.isLoggable(Level.SEVERE)) { LOGGER.log( Level.SEVERE, "Unable to call @PreDestroy annotated methods because no InjectionProvider can be found. Does this container implement the Mojarra Injection SPI?"); } } } FACTORIES_CACHE.removeApplicationFactoryManager(cl); }
public Object getFactory(ClassLoader cl, String factoryName) { Object factoryOrList; lock.readLock().lock(); try { factoryOrList = factories.get(factoryName); if (!(factoryOrList instanceof List)) { return factoryOrList; } } finally { lock.readLock().unlock(); } // factory hasn't been constructed lock.writeLock().lock(); try { // double check the current value. Another thread // may have completed the initialization by the time // this thread entered this block factoryOrList = factories.get(factoryName); if (!(factoryOrList instanceof List)) { return factoryOrList; } savedFactoryNames.put(factoryName, new ArrayList((List) factoryOrList)); Object factory = getImplementationInstance(cl, factoryName, (List) factoryOrList); if (factory == null) { ResourceBundle rb = LOGGER.getResourceBundle(); String message = rb.getString("severe.no_factory"); message = MessageFormat.format(message, factoryName); if (LOGGER.isLoggable(Level.SEVERE)) { LOGGER.log(Level.SEVERE, message); } factory = FACTORIES_CACHE.getFallbackFactory(cl, this, factoryName); if (null == factory) { message = rb.getString("severe.no_factory_backup_failed"); message = MessageFormat.format(message, factoryName); throw new IllegalStateException(message); } } // Record and return the new instance factories.put(factoryName, factory); return (factory); } finally { lock.writeLock().unlock(); } }
private static void reInitializeFactoryManager() { FACTORIES_CACHE.resetSpecialInitializationCaseFlags(); }