示例#1
0
  /**
   * 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);
  }
示例#2
0
  /**
   * 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;
  }
示例#3
0
  /**
   * 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);
  }
示例#4
0
  /**
   * <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);
  }
示例#5
0
  /**
   * <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);
  }
示例#6
0
    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();
      }
    }
示例#7
0
 private static void reInitializeFactoryManager() {
   FACTORIES_CACHE.resetSpecialInitializationCaseFlags();
 }