1 16 package javax.faces; 17 18 19 import javax.faces.application.ApplicationFactory; 20 import javax.faces.context.FacesContextFactory; 21 import javax.faces.lifecycle.LifecycleFactory; 22 import javax.faces.render.RenderKitFactory; 23 import java.lang.reflect.Constructor ; 24 import java.lang.reflect.InvocationTargetException ; 25 import java.util.*; 26 27 64 public final class FactoryFinder 65 { 66 public static final String APPLICATION_FACTORY = "javax.faces.application.ApplicationFactory"; 67 public static final String FACES_CONTEXT_FACTORY = "javax.faces.context.FacesContextFactory"; 68 public static final String LIFECYCLE_FACTORY = "javax.faces.lifecycle.LifecycleFactory"; 69 public static final String RENDER_KIT_FACTORY = "javax.faces.render.RenderKitFactory"; 70 71 private static Map _registeredFactoryNames = new HashMap(); 72 private static Map _factories = new HashMap(); 73 74 private static final Set VALID_FACTORY_NAMES = new HashSet(); 75 private static final Map ABSTRACT_FACTORY_CLASSES = new HashMap(); 76 static { 77 VALID_FACTORY_NAMES.add(APPLICATION_FACTORY); 78 VALID_FACTORY_NAMES.add(FACES_CONTEXT_FACTORY); 79 VALID_FACTORY_NAMES.add(LIFECYCLE_FACTORY); 80 VALID_FACTORY_NAMES.add(RENDER_KIT_FACTORY); 81 82 ABSTRACT_FACTORY_CLASSES.put(APPLICATION_FACTORY, ApplicationFactory.class); 83 ABSTRACT_FACTORY_CLASSES.put(FACES_CONTEXT_FACTORY, FacesContextFactory.class); 84 ABSTRACT_FACTORY_CLASSES.put(LIFECYCLE_FACTORY, LifecycleFactory.class); 85 ABSTRACT_FACTORY_CLASSES.put(RENDER_KIT_FACTORY, RenderKitFactory.class); 86 } 87 88 public static Object getFactory(String factoryName) 89 throws FacesException 90 { 91 ClassLoader classLoader = getClassLoader(); 92 Map factoryClassNames = (Map) _registeredFactoryNames.get(classLoader); 93 94 if (factoryClassNames == null) 95 { 96 String message = "No Factories configured for this Application - typically this is because " + 97 "a context listener is not setup in your web.xml.\n" + 98 "A typical config looks like this;\n<listener>\n" + 99 " <listener-class>org.apache.myfaces.webapp.StartupServletContextListener</listener-class>\n" + 100 "</listener>\n"; 101 throw new IllegalStateException (message); 102 } 103 104 if (! factoryClassNames.containsKey(factoryName)) { 105 throw new IllegalStateException ("no factory " + factoryName + " configured for this appliction"); 106 } 107 108 Map factoryMap = (Map) _factories.get(classLoader); 109 110 if (factoryMap == null) { 111 factoryMap = new HashMap(); 112 _factories.put(classLoader, factoryMap); 113 } 114 Object factory = factoryMap.get(factoryName); 115 116 if (factory == null) { 117 List classNames = (List) factoryClassNames.get(factoryName); 118 factory = newFactoryInstance((Class )ABSTRACT_FACTORY_CLASSES.get(factoryName), classNames.iterator(), classLoader); 119 factoryMap.put(factoryName, factory); 120 return factory; 121 } 122 else 123 { 124 return factory; 125 } 126 } 127 128 129 private static Object newFactoryInstance(Class interfaceClass, Iterator classNamesIterator, ClassLoader classLoader) 130 { 131 try 132 { 133 Object current = null; 134 135 while (classNamesIterator.hasNext()) 136 { 137 String implClassName = (String ) classNamesIterator.next(); 138 Class implClass = classLoader.loadClass(implClassName); 139 140 if (!interfaceClass.isAssignableFrom(implClass)) 142 { 143 throw new IllegalArgumentException ("Class " + implClassName + " is no " + interfaceClass.getName()); 144 } 145 146 if (current == null) 147 { 148 current = implClass.newInstance(); 150 } else 151 { 152 try 154 { 155 Constructor delegationConstructor = implClass.getConstructor(new Class []{interfaceClass}); 156 try 158 { 159 current = delegationConstructor.newInstance(new Object []{current}); 161 } catch (InstantiationException e) 162 { 163 throw new FacesException(e); 164 } catch (IllegalAccessException e) 165 { 166 throw new FacesException(e); 167 } catch (InvocationTargetException e) 168 { 169 throw new FacesException(e); 170 } 171 } catch (NoSuchMethodException e) 172 { 173 current = implClass.newInstance(); 175 } 176 } 177 } 178 179 return current; 180 } catch (ClassNotFoundException e) 181 { 182 throw new FacesException(e); 183 } catch (InstantiationException e) 184 { 185 throw new FacesException(e); 186 } catch (IllegalAccessException e) 187 { 188 throw new FacesException(e); 189 } 190 } 191 192 193 public static void setFactory(String factoryName, 194 String implName) 195 { 196 checkFactoryName(factoryName); 197 198 ClassLoader classLoader = getClassLoader(); 199 synchronized(_registeredFactoryNames) 200 { 201 Map factories = (Map) _factories.get(classLoader); 202 203 if (factories != null && factories.containsKey(factoryName)) { 204 return; 207 } 208 209 Map factoryClassNames = (Map) _registeredFactoryNames.get(classLoader); 210 211 if (factoryClassNames == null) 212 { 213 factoryClassNames = new HashMap(); 214 _registeredFactoryNames.put(classLoader, factoryClassNames); 215 } 216 217 List classNameList = (List) factoryClassNames.get(factoryName); 218 219 if (classNameList == null) { 220 classNameList = new ArrayList(); 221 factoryClassNames.put(factoryName, classNameList); 222 } 223 classNameList.add(implName); 224 } 225 } 226 227 228 public static void releaseFactories() 229 throws FacesException 230 { 231 ClassLoader classLoader = getClassLoader(); 232 _factories.remove(classLoader); 233 } 234 235 236 private static void checkFactoryName(String factoryName) 237 { 238 if (! VALID_FACTORY_NAMES.contains(factoryName)) { 239 throw new IllegalArgumentException ("factoryName '" + factoryName + "'"); 240 } 241 } 242 243 244 private static ClassLoader getClassLoader() 245 { 246 try 247 { 248 ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); 249 if (classLoader == null) 250 { 251 throw new FacesException("web application class loader cannot be identified", null); 252 } 253 return classLoader; 254 } 255 catch (Exception e) 256 { 257 throw new FacesException("web application class loader cannot be identified", e); 258 } 259 } 260 } 261
| Popular Tags
|