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  import javax.faces.context.ExternalContext;
28  
29  /**
30   * Provide utility methods used by FactoryFinder class to lookup for SPI interface FactoryFinderProvider.
31   *
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 String INJECTION_PROVIDER_FACTORY_CLASS_NAME = 
43          "org.apache.myfaces.spi.InjectionProviderFactory";
44  
45      public static final String INJECTION_PROVIDER_CLASS_NAME = "org.apache.myfaces.spi.InjectionProvider";
46      
47      public static final Class<?> FACTORY_FINDER_PROVIDER_FACTORY_CLASS;
48  
49      public static final Method FACTORY_FINDER_PROVIDER_GET_INSTANCE_METHOD;
50  
51      public static final Method FACTORY_FINDER_PROVIDER_FACTORY_GET_FACTORY_FINDER_METHOD;
52      public static final Class<?> FACTORY_FINDER_PROVIDER_CLASS;
53      public static final Method FACTORY_FINDER_PROVIDER_GET_FACTORY_METHOD;
54      public static final Method FACTORY_FINDER_PROVIDER_SET_FACTORY_METHOD;
55      public static final Method FACTORY_FINDER_PROVIDER_RELEASE_FACTORIES_METHOD;
56      
57      public static final Class<?> INJECTION_PROVIDER_FACTORY_CLASS;
58      public static final Method INJECTION_PROVIDER_FACTORY_GET_INSTANCE_METHOD;
59      public static final Method INJECTION_PROVIDER_FACTORY_GET_INJECTION_PROVIDER_METHOD;
60      public static final Class<?> INJECTION_PROVIDER_CLASS;
61      public static final Method INJECTION_PROVIDER_INJECT_METHOD;
62      public static final Method INJECTION_PROVIDER_POST_CONSTRUCT_METHOD;
63      public static final Method INJECTION_PROVIDER_PRE_DESTROY_METHOD;
64  
65      static
66      {
67          Class factoryFinderFactoryClass = null;
68          Method factoryFinderproviderFactoryGetMethod = null;
69          Method factoryFinderproviderFactoryGetFactoryFinderMethod = null;
70          Class<?> factoryFinderProviderClass = null;
71  
72          Method factoryFinderProviderGetFactoryMethod = null;
73          Method factoryFinderProviderSetFactoryMethod = null;
74          Method factoryFinderProviderReleaseFactoriesMethod = null;
75          
76          Class injectionProviderFactoryClass = null;
77          Method injectionProviderFactoryGetInstanceMethod = null;
78          Method injectionProviderFactoryGetInjectionProviderMethod = null;
79          Class injectionProviderClass = null;
80          Method injectionProviderInjectMethod = null;
81          Method injectionProviderPostConstructMethod = null;
82          Method injectionProviderPreDestroyMethod = null;
83  
84          try
85          {
86              factoryFinderFactoryClass = classForName(FACTORY_FINDER_PROVIDER_FACTORY_CLASS_NAME);
87              if (factoryFinderFactoryClass != null)
88              {
89                  factoryFinderproviderFactoryGetMethod = factoryFinderFactoryClass.getMethod
90                          ("getInstance", null);
91                  factoryFinderproviderFactoryGetFactoryFinderMethod = factoryFinderFactoryClass
92                          .getMethod("getFactoryFinderProvider", null);
93              }
94  
95              factoryFinderProviderClass = classForName(FACTORY_FINDER_PROVIDER_CLASS_NAME);
96              if (factoryFinderProviderClass != null)
97              {
98                  factoryFinderProviderGetFactoryMethod = factoryFinderProviderClass.getMethod("getFactory",
99                          new Class[]{String.class});
100                 factoryFinderProviderSetFactoryMethod = factoryFinderProviderClass.getMethod("setFactory",
101                         new Class[]{String.class, String.class});
102                 factoryFinderProviderReleaseFactoriesMethod = factoryFinderProviderClass.getMethod
103                         ("releaseFactories", null);
104             }
105             
106             injectionProviderFactoryClass = classForName(INJECTION_PROVIDER_FACTORY_CLASS_NAME);
107             
108             if (injectionProviderFactoryClass != null)
109             {
110                 injectionProviderFactoryGetInstanceMethod = injectionProviderFactoryClass.
111                     getMethod("getInjectionProviderFactory", null);
112                 injectionProviderFactoryGetInjectionProviderMethod = injectionProviderFactoryClass.
113                     getMethod("getInjectionProvider", ExternalContext.class);
114             }
115             
116             injectionProviderClass = classForName(INJECTION_PROVIDER_CLASS_NAME);
117             
118             if (injectionProviderClass != null)
119             {
120                 injectionProviderInjectMethod = injectionProviderClass.
121                     getMethod("inject", Object.class);
122                 injectionProviderPostConstructMethod = injectionProviderClass.
123                     getMethod("postConstruct", Object.class, Object.class);
124                 injectionProviderPreDestroyMethod = injectionProviderClass.
125                     getMethod("preDestroy", Object.class, Object.class);
126             }
127         }
128         catch (Exception e)
129         {
130             // no op
131         }
132 
133         FACTORY_FINDER_PROVIDER_FACTORY_CLASS = factoryFinderFactoryClass;
134         FACTORY_FINDER_PROVIDER_GET_INSTANCE_METHOD = factoryFinderproviderFactoryGetMethod;
135         FACTORY_FINDER_PROVIDER_FACTORY_GET_FACTORY_FINDER_METHOD = factoryFinderproviderFactoryGetFactoryFinderMethod;
136         FACTORY_FINDER_PROVIDER_CLASS = factoryFinderProviderClass;
137 
138         FACTORY_FINDER_PROVIDER_GET_FACTORY_METHOD = factoryFinderProviderGetFactoryMethod;
139         FACTORY_FINDER_PROVIDER_SET_FACTORY_METHOD = factoryFinderProviderSetFactoryMethod;
140         FACTORY_FINDER_PROVIDER_RELEASE_FACTORIES_METHOD = factoryFinderProviderReleaseFactoriesMethod;
141         
142         INJECTION_PROVIDER_FACTORY_CLASS = injectionProviderFactoryClass;
143         INJECTION_PROVIDER_FACTORY_GET_INSTANCE_METHOD = injectionProviderFactoryGetInstanceMethod;
144         INJECTION_PROVIDER_FACTORY_GET_INJECTION_PROVIDER_METHOD = injectionProviderFactoryGetInjectionProviderMethod;
145         INJECTION_PROVIDER_CLASS = injectionProviderClass;
146         INJECTION_PROVIDER_INJECT_METHOD = injectionProviderInjectMethod;
147         INJECTION_PROVIDER_POST_CONSTRUCT_METHOD = injectionProviderPostConstructMethod;
148         INJECTION_PROVIDER_PRE_DESTROY_METHOD = injectionProviderPreDestroyMethod;
149     }
150 
151     public static Object getInstance()
152     {
153         if (FACTORY_FINDER_PROVIDER_GET_INSTANCE_METHOD != null)
154         {
155             try
156             {
157                 return FACTORY_FINDER_PROVIDER_GET_INSTANCE_METHOD.invoke(FACTORY_FINDER_PROVIDER_FACTORY_CLASS, null);
158             }
159             catch (Exception e)
160             {
161                 //No op
162                 Logger log = Logger.getLogger(_FactoryFinderProviderFactory.class.getName());
163                 if (log.isLoggable(Level.WARNING))
164                 {
165                     log.log(Level.WARNING, "Cannot retrieve current FactoryFinder instance from " +
166                             "FactoryFinderProviderFactory." +
167                             " Default strategy using thread context class loader will be used.", e);
168                 }
169             }
170         }
171         return null;
172     }
173 
174     // ~ Methods Copied from _ClassUtils
175     // ------------------------------------------------------------------------------------
176 
177     /**
178      * Tries a Class.loadClass with the context class loader of the current thread first and automatically falls back
179      * to
180      * the ClassUtils class loader (i.e. the loader of the myfaces.jar lib) if necessary.
181      *
182      * @param type fully qualified name of a non-primitive non-array class
183      * @return the corresponding Class
184      * @throws NullPointerException   if type is null
185      * @throws ClassNotFoundException
186      */
187     public static Class<?> classForName(String type) throws ClassNotFoundException
188     {
189         if (type == null)
190         {
191             throw new NullPointerException("type");
192         }
193         try
194         {
195             // Try WebApp ClassLoader first
196             return Class.forName(type, false, // do not initialize for faster startup
197                     getContextClassLoader());
198         }
199         catch (ClassNotFoundException ignore)
200         {
201             // fallback: Try ClassLoader for ClassUtils (i.e. the myfaces.jar lib)
202             return Class.forName(type, false, // do not initialize for faster startup
203                     _FactoryFinderProviderFactory.class.getClassLoader());
204         }
205     }
206 
207     /**
208      * Gets the ClassLoader associated with the current thread. Returns the class loader associated with the specified
209      * default object if no context loader is associated with the current thread.
210      *
211      * @return ClassLoader
212      */
213     protected static ClassLoader getContextClassLoader()
214     {
215         if (System.getSecurityManager() != null)
216         {
217             try
218             {
219                 Object cl = AccessController.doPrivileged(new PrivilegedExceptionAction()
220                 {
221                     public Object run() throws PrivilegedActionException
222                     {
223                         return Thread.currentThread().getContextClassLoader();
224                     }
225                 });
226                 return (ClassLoader) cl;
227             }
228             catch (PrivilegedActionException pae)
229             {
230                 throw new FacesException(pae);
231             }
232         }
233         else
234         {
235             return Thread.currentThread().getContextClassLoader();
236         }
237     }
238 }