Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
   /*
    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
    *
    * Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
    *
    * The contents of this file are subject to the terms of either the GNU
    * General Public License Version 2 only ("GPL") or the Common Development
    * and Distribution License("CDDL") (collectively, the "License").  You
    * may not use this file except in compliance with the License.  You can
   * obtain a copy of the License at
   * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
   * or packager/legal/LICENSE.txt.  See the License for the specific
   * language governing permissions and limitations under the License.
   *
   * When distributing the software, include this License Header Notice in each
   * file and include the License file at packager/legal/LICENSE.txt.
   *
   * GPL Classpath Exception:
   * Oracle designates this particular file as subject to the "Classpath"
   * exception as provided by Oracle in the GPL Version 2 section of the License
   * file that accompanied this code.
   *
   * Modifications:
   * If applicable, add the following below the License Header, with the fields
   * enclosed by brackets [] replaced by your own identifying information:
   * "Portions Copyright [year] [name of copyright owner]"
   *
   * Contributor(s):
   * If you wish your version of this file to be governed by only the CDDL or
   * only the GPL Version 2, indicate your decision by adding "[Contributor]
   * elects to include this software in this distribution under the [CDDL or GPL
   * Version 2] license."  If you don't indicate a single choice of license, a
   * recipient has the option to distribute your version of this file under
   * either the CDDL, the GPL Version 2 or to extend the choice of license to
   * its licensees as provided above.  However, if you add GPL Version 2 code
   * and therefore, elected the GPL Version 2 license, then the option applies
   * only if the new code is made subject to such option by the copyright
   * holder.
   */
  
  package javax.faces;
  
  
  import java.util.HashMap;
  import java.util.List;
  import java.util.Map;
  import java.util.Arrays;
  import java.net.URL;
  import java.util.Set;

FactoryFinder implements the standard discovery algorithm for all factory objects specified in the JavaServer 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 JavaServer 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 JavaServer Faces configuration files named by the javax.faces.CONFIG_FILES ServletContext init parameter contain any factory entries of the given factory class name, those result are used, with the last one taking precedence.

  • If there are any JavaServer 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 result 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 JavaServer Faces implementation specific class is used.

If any of the result 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 javax.faces.context.FacesContextFactory, and identified it in META-INF/services/javax.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 JavaServer 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 JavaServer 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 javax.faces.application.ApplicationFactory class name.

 
     public final static String APPLICATION_FACTORY =
          "javax.faces.application.ApplicationFactory";

    

The property name for the javax.faces.context.ExceptionHandlerFactory class name.

 
     public final static String EXCEPTION_HANDLER_FACTORY =
          "javax.faces.context.ExceptionHandlerFactory";

    

The property name for the javax.faces.context.ExternalContextFactory class name.

 
     public final static String EXTERNAL_CONTEXT_FACTORY =
          "javax.faces.context.ExternalContextFactory";

    

The property name for the javax.faces.context.FacesContextFactory class name.

 
     public final static String FACES_CONTEXT_FACTORY =
          "javax.faces.context.FacesContextFactory";

    

The property name for the javax.faces.view.facelets.FaceletCacheFactory class name.

Since:
2.1
 
     public final static String FACELET_CACHE_FACTORY =
          "javax.faces.view.facelets.FaceletCacheFactory";

    

The property name for the javax.faces.context.PartialViewContextFactory class name.

 
     public final static String PARTIAL_VIEW_CONTEXT_FACTORY =
           "javax.faces.context.PartialViewContextFactory";

    

The property name for the javax.faces.component.visit.VisitContextFactory class name.

 
     public final static String VISIT_CONTEXT_FACTORY =
          "javax.faces.component.visit.VisitContextFactory";

    

The property name for the javax.faces.lifecycle.LifecycleFactory class name.

 
     public final static String LIFECYCLE_FACTORY =
          "javax.faces.lifecycle.LifecycleFactory";

    

The property name for the javax.faces.render.RenderKitFactory class name.

 
     public final static String RENDER_KIT_FACTORY =
          "javax.faces.render.RenderKitFactory";

    

The property name for the javax.faces.view.ViewDeclarationLanguage class name.

 
     public final static String VIEW_DECLARATION_LANGUAGE_FACTORY =
          "javax.faces.view.ViewDeclarationLanguageFactory";

    

The property name for the javax.faces.view.facelets.TagHandlerDelegate class name.

 
     public final static String TAG_HANDLER_DELEGATE_FACTORY =
          "javax.faces.view.facelets.TagHandlerDelegateFactory";
 
     // ------------------------------------------------------- Static Variables
 
     private static final FactoryManagerCache FACTORIES_CACHE;


    

The set of JavaServer Faces factory classes for which the factory discovery mechanism is supported. The entries in this list must be alphabetically ordered according to the entire string of the *value* of each of the literals, not just the last part of the literal!

 
     private static final String[] FACTORY_NAMES;

    

Map of Class instances for the our factory names.

 
     private static Map<StringClassfactoryClasses;
 
     private static final Logger LOGGER;
 
     static {
 
          = new FactoryManagerCache();
 
          = new String [] {
             ,
             ,
             ,
             ,
             ,
             ,
             ,
             ,
             ,
             ,
             
         };
 
         // Ensure the factory names are sorted.
         //
         Arrays.sort();
         
          = new HashMap<StringClass>(.);
                            javax.faces.application.ApplicationFactory.class);
                            javax.faces.context.ExceptionHandlerFactory.class);
                            javax.faces.context.ExternalContextFactory.class);
                            javax.faces.context.FacesContextFactory.class);
                            javax.faces.view.facelets.FaceletCacheFactory.class);
                            javax.faces.component.visit.VisitContextFactory.class);
                            javax.faces.lifecycle.LifecycleFactory.class);
                            javax.faces.context.PartialViewContextFactory.class);
                            javax.faces.render.RenderKitFactory.class);
                            javax.faces.view.ViewDeclarationLanguageFactory.class);
                            javax.faces.view.facelets.TagHandlerDelegateFactory.class);
         
          = Logger.getLogger("javax.faces""javax.faces.LogStrings");
     }
 
 
     // --------------------------------------------------------- Public Methods
 

    

Create (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.

The standard result and wrappers in JSF all implement the interface FacesWrapper. If the returned Object is an implementation of one of the standard result, it must be legal to cast it to an instance of FacesWrapper and call FacesWrapper.getWrapped() on the instance.

Parameters:
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
FacesException if an instance of the configured factory implementation class cannot be loaded
FacesException if an instance of the configured factory implementation class cannot be instantiated
java.lang.IllegalArgumentException if factoryName does not identify a standard JavaServer Faces factory name
java.lang.IllegalStateException if there is no configured factory implementation class for the specified factory name
java.lang.NullPointerException if factoryname is null
 
     public static Object getFactory(String factoryName)
          throws FacesException {
 
         validateFactoryName(factoryName);
 
         // Identify the web application class loader
         ClassLoader classLoader = getClassLoader();
 
         FactoryManager manager =
               .getApplicationFactoryManager(classLoader);
         return manager.getFactory(classLoaderfactoryName);
 
     }

    

This method will store the argument factoryName/implName mapping in such a way that getFactory(java.lang.String) 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:
java.lang.IllegalArgumentException if factoryName does not identify a standard JavaServer Faces factory name
java.lang.NullPointerException if factoryname is null
 
     public static void setFactory(String factoryName,
                                   String implName) {
 
         validateFactoryName(factoryName);
 
         // Identify the web application class loader
         ClassLoader classLoader = getClassLoader();
 
         FactoryManager manager =
               .getApplicationFactoryManager(classLoader);
         manager.addFactory(factoryNameimplName);
 
     }


    

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 {
 
         // Identify the web application class loader
         ClassLoader cl = getClassLoader();
 
 
     }
 
 
     // -------------------------------------------------------- Private Methods
 

    

Identify and return the class loader that is associated with the calling web application.

Throws:
FacesException if the web application class loader cannot be identified
 
     private static ClassLoader getClassLoader() throws FacesException {
 
         // J2EE 1.3 (and later) containers are required to make the
         // web application class loader visible through the context
         // class loader of the current thread.
         ClassLoader cl = Thread.currentThread().getContextClassLoader();
         if (cl == null) {
             throw new FacesException("getContextClassLoader");
         }
         return (cl);
 
     }


    

Load and return an instance of the specified implementation class using the following algorithm.

  1. If the argument implementations list has more than one element, or exactly one element, interpret the last element in the list to be the fully qualified class name of a class implementing factoryName. Instantiate that class and save it for return. If the implementations list has only one element, skip this step.

  2. Look for a resource called /META-INF/services/<factoryName>. If found, interpret it as a properties file, and read out the first entry. Interpret the first entry as a fully qualify class name of a class that implements factoryName. If we have an instantiated factory from the previous step and the implementing class has a one arg constructor of the type for factoryName, instantiate it, passing the instantiated factory from the previous step. If there is no one arg constructor, just instantiate the zero arg constructor. Save the newly instantiated factory for return, replacing the instantiated factory from the previous step.

  3. Treat each remaining element in the implementations list as a fully qualified class name of a class implementing factoryName. If the current element has a one arg constructor of the type for factoryName, instantiate it, passing the instantiated factory from the previous or step iteration. If there is no one arg constructor, just instantiate the zero arg constructor, replacing the instantiated factory from the previous step or iteration.

  4. Return the saved factory

Parameters:
classLoader Class loader for the web application that will be loading the implementation class
implementations A List of implementations for a given factory class.
Throws:
FacesException if the specified implementation class cannot be loaded
FacesException if an instance of the specified implementation class cannot be instantiated
 
     private static Object getImplementationInstance(ClassLoader classLoader,
                                                     String factoryName,
                                                     List implementations)
     throws FacesException {
 
         Object result = null;
         String curImplClass;
         int len;
 
         // step 1.
         if (null != implementations &&
              (1 < (len = implementations.size()) || 1 == len)) {
             curImplClass = (Stringimplementations.remove(len - 1);
             // since this is the hard coded implementation default,
             // there is no preceding implementation, so don't bother
             // with a non-zero-arg ctor.
             result = getImplGivenPreviousImpl(classLoaderfactoryName,
                  curImplClassnull);
         }
 
         // step 2.
         List<StringfromServices = getImplNameFromServices(classLoaderfactoryName);
         if (fromServices != null) {
             for (String name : fromServices) {
                 result = getImplGivenPreviousImpl(classLoader,
                                                   factoryName,
                                                   name,
                                                   result);
             }
         }        
 
         // step 3.
         if (null != implementations) {
             for (len = (implementations.size() - 1); 0 <= lenlen--) {
                 curImplClass = (Stringimplementations.remove(len);
                 result = getImplGivenPreviousImpl(classLoaderfactoryName,
                      curImplClassresult);
             }
         }
 
         return result;
 
     }


    

Perform the logic to get the implementation class for the second step of getImplementationInstance(java.lang.ClassLoader,java.lang.String,java.util.List).

 
     private static List<StringgetImplNameFromServices(ClassLoader classLoader,
                                                         String factoryName) {
 
         // Check for a services definition
         List<Stringresult = null;
         String resourceName = "META-INF/services/" + factoryName;
         InputStream stream;
         BufferedReader reader = null;
         try {
             Enumeration<URLe = classLoader.getResources(resourceName);
             while (e.hasMoreElements()) {
                 URL url = e.nextElement();
                 URLConnection conn = url.openConnection();
                 conn.setUseCaches(false);
                 stream = conn.getInputStream();
                 if (stream != null) {
                     // Deal with systems whose native encoding is possibly
                     // different from the way that the services entry was created
                     try {
                         reader =
                               new BufferedReader(new InputStreamReader(stream,
                                                                        "UTF-8"));
                         if (result == null) {
                             result = new ArrayList<String>(3);
                         }
                         result.add(reader.readLine());
                     } catch (UnsupportedEncodingException uee) {
                         // 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(stream));
                     } finally {
                         if (reader != null) {
                             reader.close();
                             reader = null;
                         }
                         if (stream != null) {
                             stream.close();
                             //noinspection UnusedAssignment
                             stream = null;
                         }
                     }
 
                 }
             }
         } catch (IOException e) {
             if (.isLoggable(.)) {
                 .log(.,
                            e.toString(),
                            e);
             }
         } catch (SecurityException e) {
             if (.isLoggable(.)) {
                 .log(.,
                            e.toString(),
                            e);
             }
         }
         return result;
 
     }


    

Implement the decorator pattern for the factory implementation.

If previousImpl is non-null and the class named by the argument implName has a one arg contstructor of type factoryName, instantiate it, passing previousImpl to the constructor.

Otherwise, we just instantiate and return implName.

Parameters:
classLoader the ClassLoader from which to load the class
factoryName the fully qualified class name of the factory.
implName the fully qualified class name of a class that implements the factory.
previousImpl if non-null, 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;
 
         // if we have a previousImpl and the appropriate one arg ctor.
         if ((null != previousImpl) &&
              (null != (factoryClass = getFactoryClass(factoryName)))) {
             try {
                 clazz = Class.forName(implNamefalseclassLoader);
                 getCtorArg = new Class[1];
                 getCtorArg[0] = factoryClass;
                 ctor = clazz.getConstructor(getCtorArg);
                 newInstanceArgs[0] = previousImpl;
                 result = ctor.newInstance(newInstanceArgs);
             }
             catch (NoSuchMethodException nsme) {
                 // fall through to "zero-arg-ctor" case
                 factoryClass = null;
             }
             catch (Exception e) {
                 throw new FacesException(implNamee);
             }
         }
         if (null == previousImpl || null == factoryClass) {
             // we have either no previousImpl or no appropriate one arg
             // ctor.
             try {
                 clazz = Class.forName(implNamefalseclassLoader);
                 // 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(implNamee);
             }
         }
         return result;
 
     }


    

Returns:
the java.lang.Class for the argument factory.
 
     private static Class getFactoryClass(String factoryClassName) {
 
         return .get(factoryClassName);
 
     }


    
Ensure the provided factory name is valid.
 
     private static void validateFactoryName(String factoryName) {
 
         if (factoryName == null) {
             throw new NullPointerException();
         }
         if (Arrays.binarySearch(factoryName) < 0) {
             throw new IllegalArgumentException(factoryName);
         }
 
     }
     
     private static void reInitializeFactoryManager() {
     }
 
 
     // ----------------------------------------------------------- Inner Classes
 

    
Managed the mappings between a web application and its configured result.
 
     private static final class FactoryManagerCache {
 
               new ConcurrentHashMap<FactoryManagerCacheKeyFactoryManager>();
         private AtomicBoolean logNullFacesContext = new AtomicBoolean(false);
         private AtomicBoolean logNonNullFacesContext = new AtomicBoolean(false);
 
 
         // ------------------------------------------------------ Public Methods
         
         private Object getFallbackFactory(ClassLoader clFactoryManager brokenFactoryManager,
                 String factoryName) {
             Object result = null;
             for (Map.Entry<FactoryManagerCacheKey,FactoryManagercur : .entrySet()) {
                 if (cur.getKey().getClassLoader().equals(cl) && !cur.getValue().equals(brokenFactoryManager)) {
                     result = cur.getValue().getFactory(clfactoryName);
                     if (null != result) {
                         break;
                     }
                 }
             }
             return result;
         }
 
         private FactoryManager getApplicationFactoryManager(ClassLoader cl) {
             FacesContext facesContext = FacesContext.getCurrentInstance();
             boolean isSpecialInitializationCase = detectSpecialInitializationCase(facesContext);
 
             FactoryManagerCacheKey key = new FactoryManagerCacheKey(facesContext,
                     cl);
 
             FactoryManager result = .get(key);
             FactoryManager toCopy = null;
             if (result == null) {
                 boolean createNewFactoryManagerInstance = false;
                 
                 if (isSpecialInitializationCase) {
                     // We need to obtain a reference to the correct
                     // FactoryManager.  Iterate through the data structure 
                     // containing all FactoryManager instances for this VM.
                     FactoryManagerCacheKey curKey;
                     boolean classLoadersMatchButContextsDoNotMatch = false;
                     boolean foundNoMatchInApplicationMap = true;
                     for (Map.Entry<FactoryManagerCacheKeyFactoryManagercur : .entrySet()) {
                         curKey = cur.getKey();
                         // If the current FactoryManager is for a
                         // the same ClassLoader as the current ClassLoader...
                         if (curKey.getClassLoader().equals(cl)) {
                             foundNoMatchInApplicationMap = false;
                             // Check the other descriminator for the
                             // key: the context.  
 
                             // If the context objects of the keys are
                             // both non-null and non-equal, then *do*
                             // create a new FactoryManager instance.
 
                             if ((null != key.getContext() && null != curKey.getContext()) &&
                                 (!key.getContext().equals(curKey.getContext()))) {
                                 classLoadersMatchButContextsDoNotMatch = true;
                                 toCopy = cur.getValue();
                             }
                             else {
                                 // Otherwise, use this FactoryManager
                                 // instance.
                                 result = cur.getValue();
                             }
                             break;
                         }
                     }
                     // We must create a new FactoryManager if there was no match
                     // at all found in the applicationMap, or a match was found
                     // and the match is safe to use in this web app
                     createNewFactoryManagerInstance = foundNoMatchInApplicationMap ||
                             (null == result && classLoadersMatchButContextsDoNotMatch);
                 } else {
                     createNewFactoryManagerInstance = true;
                 }
                 
                 if (createNewFactoryManagerInstance) {
                     FactoryManager newResult;
                     if (null != toCopy) {
                         newResult = new FactoryManager(toCopy);
                     } else {
                         newResult = new FactoryManager();
                     }
                     result = .putIfAbsent(keynewResult);
                     result = (null != result) ? result : newResult;
                 }
                 
             }
             return result;
         }
        
        
This method is used to detect the following special initialization case. IF no FactoryManager can be found for key, AND this call to getApplicationFactoryManager() *does* have a current FacesContext BUT a previous call to getApplicationFactoryManager *did not* have a current FacesContext

Parameters:
facesContext the current FacesContext for this request
Returns:
true if the current execution falls into the special initialization case.
 
         private boolean detectSpecialInitializationCase(FacesContext facesContext) {
             boolean result = false;
             if (null == facesContext) {
                 .compareAndSet(falsetrue);
             } else {
                 .compareAndSet(falsetrue);
             }
             result = .get() && .get();
             
             return result;
         }
 
 
         public void removeApplicationFactoryManager(ClassLoader cl) {
             FacesContext facesContext = FacesContext.getCurrentInstance();
             boolean isSpecialInitializationCase = detectSpecialInitializationCase(facesContext);
 
             FactoryManagerCacheKey key = new FactoryManagerCacheKey(facesContext,
                     cl);
             
             .remove(key);
             if (isSpecialInitializationCase) {
                 .set(false);
                 .set(false);
             }
 
         }
         
         public void resetSpecialInitializationCaseFlags() {
             .set(false);
             .set(false);
         }
 
     } // END FactoryCache
 
     private static final class FactoryManagerCacheKey {
         private ClassLoader cl;
         private Long marker;
         private Object context;
 
         private static final String KEY = FactoryFinder.class.getName() + "." +
                 FactoryManagerCacheKey.class.getSimpleName();
 
         public FactoryManagerCacheKey(FacesContext facesContextClassLoader cl,
                 Map<FactoryManagerCacheKey,FactoryManagerfactoryMap) {
             this. = cl;
             boolean resolveValueFromFactoryMap = false;
             
             
             if (null == facesContext) {
                 resolveValueFromFactoryMap = true;
             } else {
                 ExternalContext extContext = facesContext.getExternalContext();
                  = extContext.getContext();
                 if (null == ) {
                     resolveValueFromFactoryMap = true;
                 } else {
                     Map<StringObjectappMap = extContext.getApplicationMap();
                 
                     Long val = (LongappMap.get();
                     if (null == val) {
                          = new Long(System.currentTimeMillis());
                         appMap.put();
                     } else {
                          = val;
                     }
                 }
             } 
             if (resolveValueFromFactoryMap) {
                 // We don't have a FacesContext.
                 // Our only recourse is to inspect the keys of the
                 // factoryMap and see if any of them has a classloader
                 // equal to our argument cl.
                 Set<FactoryManagerCacheKeykeys = factoryMap.keySet();
                 FactoryManagerCacheKey match = null;
                 for (FactoryManagerCacheKey cur : keys) {
                     if (this..equals(cur.cl)) {
                         if (null != cur && null != match) {
                             .log(."Multiple JSF Applications found on same ClassLoader.  Unable to safely determine which FactoryManager instance to use. Defaulting to first match.");
                             break;
                         }
                         match = cur;
                     }
                 }
                 if (null != match) {
                     this. = match.marker;
                 }
             }
         }
         
         public ClassLoader getClassLoader() {
             return ;
         }
         
         public Object getContext() {
             return ;
         }
         
         private FactoryManagerCacheKey() {}
 
         @Override
         public boolean equals(Object obj) {
             if (obj == null) {
                 return false;
             }
             if (getClass() != obj.getClass()) {
                 return false;
             }
             final FactoryManagerCacheKey other = (FactoryManagerCacheKeyobj;
             if (this. != other.cl && (this. == null || !this..equals(other.cl))) {
                 return false;
             }
             if (this. != other.marker && (this. == null || !this..equals(other.marker))) {
                 return false;
             }
             return true;
         }
 
         @Override
         public int hashCode() {
             int hash = 7;
             hash = 97 * hash + (this. != null ? this..hashCode() : 0);
             hash = 97 * hash + (this. != null ? this..hashCode() : 0);
             return hash;
         }
 
 
         
 
     }


    
Maintains the result for a single web application.
 
     private static final class FactoryManager {
 
         private final Map<String,Objectfactories;
         private final Map<StringList<String>> savedFactoryNames;
         private final ReentrantReadWriteLock lock;
 
 
         // -------------------------------------------------------- Consturctors
 
 
         public FactoryManager() {
              = new ReentrantReadWriteLock(true);
              = new HashMap<String,Object>();
              = new HashMap<StringList<String>>();
             for (String name : ) {
                 .put(namenew ArrayList(4));
             }
         }
 
         public FactoryManager(FactoryManager toCopy) {
              = new ReentrantReadWriteLock(true);
              = new HashMap<String,Object>();
              = new HashMap<StringList<String>>();
             .putAll(toCopy.savedFactoryNames);
                 
         }
 
         // ------------------------------------------------------ Public Methods
 
 
         public void addFactory(String factoryNameString implementation) {
 
             Object result = .get(factoryName);
             .writeLock().lock();
             try {
                 if (result instanceof List) {
                     TypedCollections.dynamicallyCastList((ListresultString.class).add(0, implementation);
                 }
             } finally {
                 .writeLock().unlock();
             }
         }
 
 
         public Object getFactory(ClassLoader clString factoryName) {
 
             Object factoryOrList;
             .readLock().lock();
             try {
                 factoryOrList = .get(factoryName);
                 if (!(factoryOrList instanceof List)) {
                     return factoryOrList;
                 }
             } finally {
                 .readLock().unlock();
             }
 
             // factory hasn't been constructed
             .writeLock().lock();
             try {
                 // double check the current value.  Another thread
                 // may have completed the initialization by the time
                 // this thread entered this block
                 factoryOrList = .get(factoryName);
                 if (!(factoryOrList instanceof List)) {
                     return factoryOrList;
                 }
                 .put(factoryNamenew ArrayList((List)factoryOrList));
                 Object factory = getImplementationInstance(cl,
                                                            factoryName,
                                                            (ListfactoryOrList);
                if (factory == null) {
                    ResourceBundle rb = .getResourceBundle();
                    String message = rb.getString("severe.no_factory");
                    message = MessageFormat.format(messagefactoryName);
                    if (.isLoggable(.)) {
                        .log(.message);
                    }
                    factory = .getFallbackFactory(clthisfactoryName);
                    if (null == factory) {
                        message = rb.getString("severe.no_factory_backup_failed");
                        message = MessageFormat.format(messagefactoryName);
                        throw new IllegalStateException(message);
                    }
                }
                // Record and return the new instance
                .put(factoryNamefactory);
                return (factory);
            } finally {
                .writeLock().unlock();
            }
        }
        
    } // END FactoryManager
New to GrepCode? Check out our FAQ X