View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package javax.faces;
20  
21  import java.lang.reflect.Method;
22  import java.security.AccessController;
23  import java.security.PrivilegedActionException;
24  import java.security.PrivilegedExceptionAction;
25  import java.util.logging.Level;
26  import java.util.logging.Logger;
27  
28  /**
29   * Provide utility methods used by FactoryFinder class to lookup for SPI interface FactoryFinderProvider.
30   *
31   * @author Leonardo Uribe
32   * @since 2.0.5
33   */
34  class _FactoryFinderProviderFactory
35  {
36  
37      public static final String FACTORY_FINDER_PROVIDER_FACTORY_CLASS_NAME = "org.apache.myfaces.spi" +
38              ".FactoryFinderProviderFactory";
39  
40      public static final String FACTORY_FINDER_PROVIDER_CLASS_NAME = "org.apache.myfaces.spi.FactoryFinderProvider";
41  
42      public static final Class<?> FACTORY_FINDER_PROVIDER_FACTORY_CLASS;
43  
44      public static final Method FACTORY_FINDER_PROVIDER_GET_INSTANCE_METHOD;
45  
46      public static final Method FACTORY_FINDER_PROVIDER_FACTORY_GET_FACTORY_FINDER_METHOD;
47      public static final Class<?> FACTORY_FINDER_PROVIDER_CLASS;
48      public static final Method FACTORY_FINDER_PROVIDER_GET_FACTORY_METHOD;
49      public static final Method FACTORY_FINDER_PROVIDER_SET_FACTORY_METHOD;
50      public static final Method FACTORY_FINDER_PROVIDER_RELEASE_FACTORIES_METHOD;
51  
52      static
53      {
54          Class factoryFinderFactoryClass = null;
55          Method factoryFinderproviderFactoryGetMethod = null;
56          Method factoryFinderproviderFactoryGetFactoryFinderMethod = null;
57          Class<?> factoryFinderProviderClass = null;
58  
59          Method factoryFinderProviderGetFactoryMethod = null;
60          Method factoryFinderProviderSetFactoryMethod = null;
61          Method factoryFinderProviderReleaseFactoriesMethod = null;
62  
63          try
64          {
65              factoryFinderFactoryClass = classForName(FACTORY_FINDER_PROVIDER_FACTORY_CLASS_NAME);
66  
67  
68              if (factoryFinderFactoryClass != null)
69              {
70                  factoryFinderproviderFactoryGetMethod = factoryFinderFactoryClass.getMethod
71                          ("getInstance", null);
72                  factoryFinderproviderFactoryGetFactoryFinderMethod = factoryFinderFactoryClass
73                          .getMethod("getFactoryFinderProvider", null);
74              }
75  
76              factoryFinderProviderClass = classForName(FACTORY_FINDER_PROVIDER_CLASS_NAME);
77              if (factoryFinderProviderClass != null)
78              {
79                  factoryFinderProviderGetFactoryMethod = factoryFinderProviderClass.getMethod("getFactory",
80                          new Class[]{String.class});
81                  factoryFinderProviderSetFactoryMethod = factoryFinderProviderClass.getMethod("setFactory",
82                          new Class[]{String.class, String.class});
83                  factoryFinderProviderReleaseFactoriesMethod = factoryFinderProviderClass.getMethod
84                          ("releaseFactories", null);
85              }
86          }
87          catch (Exception e)
88          {
89              // no op
90          }
91  
92          FACTORY_FINDER_PROVIDER_FACTORY_CLASS = factoryFinderFactoryClass;
93          FACTORY_FINDER_PROVIDER_GET_INSTANCE_METHOD = factoryFinderproviderFactoryGetMethod;
94          FACTORY_FINDER_PROVIDER_FACTORY_GET_FACTORY_FINDER_METHOD = factoryFinderproviderFactoryGetFactoryFinderMethod;
95          FACTORY_FINDER_PROVIDER_CLASS = factoryFinderProviderClass;
96  
97          FACTORY_FINDER_PROVIDER_GET_FACTORY_METHOD = factoryFinderProviderGetFactoryMethod;
98          FACTORY_FINDER_PROVIDER_SET_FACTORY_METHOD = factoryFinderProviderSetFactoryMethod;
99          FACTORY_FINDER_PROVIDER_RELEASE_FACTORIES_METHOD = factoryFinderProviderReleaseFactoriesMethod;
100     }
101 
102     public static Object getInstance()
103     {
104         if (FACTORY_FINDER_PROVIDER_GET_INSTANCE_METHOD != null)
105         {
106             try
107             {
108                 return FACTORY_FINDER_PROVIDER_GET_INSTANCE_METHOD.invoke(FACTORY_FINDER_PROVIDER_FACTORY_CLASS, null);
109             }
110             catch (Exception e)
111             {
112                 //No op
113                 Logger log = Logger.getLogger(_FactoryFinderProviderFactory.class.getName());
114                 if (log.isLoggable(Level.WARNING))
115                 {
116                     log.log(Level.WARNING, "Cannot retrieve current FactoryFinder instance from " +
117                             "FactoryFinderProviderFactory." +
118                             " Default strategy using thread context class loader will be used.", e);
119                 }
120             }
121         }
122         return null;
123     }
124 
125     // ~ Methods Copied from _ClassUtils
126     // ------------------------------------------------------------------------------------
127 
128     /**
129      * Tries a Class.loadClass with the context class loader of the current thread first and automatically falls back
130      * to
131      * the ClassUtils class loader (i.e. the loader of the myfaces.jar lib) if necessary.
132      *
133      * @param type fully qualified name of a non-primitive non-array class
134      * @return the corresponding Class
135      * @throws NullPointerException   if type is null
136      * @throws ClassNotFoundException
137      */
138     public static Class<?> classForName(String type) throws ClassNotFoundException
139     {
140         if (type == null)
141         {
142             throw new NullPointerException("type");
143         }
144         try
145         {
146             // Try WebApp ClassLoader first
147             return Class.forName(type, false, // do not initialize for faster startup
148                     getContextClassLoader());
149         }
150         catch (ClassNotFoundException ignore)
151         {
152             // fallback: Try ClassLoader for ClassUtils (i.e. the myfaces.jar lib)
153             return Class.forName(type, false, // do not initialize for faster startup
154                     _FactoryFinderProviderFactory.class.getClassLoader());
155         }
156     }
157 
158     /**
159      * Gets the ClassLoader associated with the current thread. Returns the class loader associated with the specified
160      * default object if no context loader is associated with the current thread.
161      *
162      * @return ClassLoader
163      */
164     protected static ClassLoader getContextClassLoader()
165     {
166         if (System.getSecurityManager() != null)
167         {
168             try
169             {
170                 Object cl = AccessController.doPrivileged(new PrivilegedExceptionAction()
171                 {
172                     public Object run() throws PrivilegedActionException
173                     {
174                         return Thread.currentThread().getContextClassLoader();
175                     }
176                 });
177                 return (ClassLoader) cl;
178             }
179             catch (PrivilegedActionException pae)
180             {
181                 throw new FacesException(pae);
182             }
183         }
184         else
185         {
186             return Thread.currentThread().getContextClassLoader();
187         }
188     }
189 }