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   */
35  class _FactoryFinderProviderFactory
36  {
37      
38      public static final String FACTORY_FINDER_PROVIDER_FACTORY_CLASS_NAME = "org.apache.myfaces.spi.FactoryFinderProviderFactory";
39      
40      public static final String FACTORY_FINDER_PROVIDER_CLASS_NAME = "org.apache.myfaces.spi.FactoryFinderProvider";
41      
42      public static Class<?> FACTORY_FINDER_PROVIDER_FACTORY_CLASS;
43      
44      public static Method FACTORY_FINDER_PROVIDER_GET_INSTANCE_METHOD; 
45      
46      public static Method FACTORY_FINDER_PROVIDER_FACTORY_GET_FACTORY_FINDER_METHOD;
47      public static Class<?> FACTORY_FINDER_PROVIDER_CLASS;
48      public static Method FACTORY_FINDER_PROVIDER_GET_FACTORY_METHOD;
49      public static Method FACTORY_FINDER_PROVIDER_RELEASE_FACTORIES_METHOD;
50      public static Method FACTORY_FINDER_PROVIDER_SET_FACTORY_METHOD;
51      
52      static
53      {
54          try 
55          {
56              FACTORY_FINDER_PROVIDER_FACTORY_CLASS = classForName(FACTORY_FINDER_PROVIDER_FACTORY_CLASS_NAME);
57              
58              if (FACTORY_FINDER_PROVIDER_FACTORY_CLASS != null)
59              {
60                  FACTORY_FINDER_PROVIDER_GET_INSTANCE_METHOD = FACTORY_FINDER_PROVIDER_FACTORY_CLASS.getMethod("getInstance", null);
61                  FACTORY_FINDER_PROVIDER_FACTORY_GET_FACTORY_FINDER_METHOD = FACTORY_FINDER_PROVIDER_FACTORY_CLASS.getMethod("getFactoryFinderProvider", null);
62              }
63              
64              FACTORY_FINDER_PROVIDER_CLASS = classForName(FACTORY_FINDER_PROVIDER_CLASS_NAME);
65              if (FACTORY_FINDER_PROVIDER_CLASS != null)
66              {
67                  FACTORY_FINDER_PROVIDER_GET_FACTORY_METHOD = FACTORY_FINDER_PROVIDER_CLASS.getMethod("getFactory", new Class[]{String.class});
68                  FACTORY_FINDER_PROVIDER_SET_FACTORY_METHOD = FACTORY_FINDER_PROVIDER_CLASS.getMethod("setFactory", new Class[]{String.class, String.class});
69                  FACTORY_FINDER_PROVIDER_RELEASE_FACTORIES_METHOD = FACTORY_FINDER_PROVIDER_CLASS.getMethod("releaseFactories", null);
70              }
71          }
72          catch (Exception e)
73          {
74              //No op
75          }
76      }
77      
78      public static Object getInstance()
79      {
80          if (FACTORY_FINDER_PROVIDER_GET_INSTANCE_METHOD != null)
81          {
82              try
83              {
84                  return FACTORY_FINDER_PROVIDER_GET_INSTANCE_METHOD.invoke(FACTORY_FINDER_PROVIDER_FACTORY_CLASS, null);
85              }
86              catch (Exception e)
87              {
88                  //No op
89                  Logger log = Logger.getLogger(_FactoryFinderProviderFactory.class.getName());
90                  if (log.isLoggable(Level.WARNING))
91                  {
92                      log.log(Level.WARNING, "Cannot retrieve current FactoryFinder instance from FactoryFinderProviderFactory." +
93                              " Default strategy using thread context class loader will be used.", e);
94                  }
95              }
96          }
97          return null;
98      }
99     
100    // ~ Methods Copied from _ClassUtils ------------------------------------------------------------------------------------
101     
102     /**
103      * Tries a Class.loadClass with the context class loader of the current thread first and automatically falls back to
104      * the ClassUtils class loader (i.e. the loader of the myfaces.jar lib) if necessary.
105      * 
106      * @param type
107      *            fully qualified name of a non-primitive non-array class
108      * @return the corresponding Class
109      * @throws NullPointerException
110      *             if type is null
111      * @throws ClassNotFoundException
112      */
113     public static Class<?> classForName(String type) throws ClassNotFoundException
114     {
115         if (type == null)
116             throw new NullPointerException("type");
117         try
118         {
119             // Try WebApp ClassLoader first
120             return Class.forName(type, false, // do not initialize for faster startup
121                 getContextClassLoader());
122         }
123         catch (ClassNotFoundException ignore)
124         {
125             // fallback: Try ClassLoader for ClassUtils (i.e. the myfaces.jar lib)
126             return Class.forName(type, false, // do not initialize for faster startup
127                 _FactoryFinderProviderFactory.class.getClassLoader());
128         }
129     }
130     
131     /**
132      * Gets the ClassLoader associated with the current thread. Returns the class loader associated with the specified
133      * default object if no context loader is associated with the current thread.
134      * 
135      * @return ClassLoader
136      */
137     protected static ClassLoader getContextClassLoader(){
138         if (System.getSecurityManager() != null) {
139             try {
140                 Object cl = AccessController.doPrivileged(new PrivilegedExceptionAction() {
141                             public Object run() throws PrivilegedActionException {
142                                 return Thread.currentThread().getContextClassLoader();
143                             }
144                         });
145                 return (ClassLoader) cl;
146             } catch (PrivilegedActionException pae) {
147                 throw new FacesException(pae);
148             }
149         }else{
150             return Thread.currentThread().getContextClassLoader();
151         }
152     }
153 }