KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > javax > faces > FactoryFinder


1 /*
2  * Copyright 2004 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

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 JavaDoc;
24 import java.lang.reflect.InvocationTargetException JavaDoc;
25 import java.util.*;
26
27 /**
28  * @author Manfred Geiler (latest modification by $Author: matze $)
29  * @version $Revision: 1.19 $ $Date: 2004/10/13 11:50:59 $
30  * $Log: FactoryFinder.java,v $
31  * Revision 1.19 2004/10/13 11:50:59 matze
32  * renamed packages to org.apache
33  *
34  * Revision 1.18 2004/07/20 14:57:27 manolito
35  * cosmetic change
36  *
37  * Revision 1.17 2004/07/20 14:56:41 manolito
38  * removed public FactoryFinder method getValidFactoryNames - there is no such method in JSF 1.1 !
39  *
40  * Revision 1.16 2004/07/07 08:37:06 mwessendorf
41  * final class
42  *
43  * Revision 1.15 2004/07/06 23:21:19 o_rossmueller
44  * fix #985217: decoration support for factories
45  *
46  * Revision 1.14 2004/07/01 22:00:47 mwessendorf
47  * ASF switch
48  *
49  * Revision 1.13 2004/06/16 23:02:20 o_rossmueller
50  * merged confignew_branch
51  *
52  * Revision 1.12.2.1 2004/06/16 01:25:50 o_rossmueller
53  * refactorings: FactoryFinder, decorator creation, dispenser (removed reverse order)
54  * bug fixes
55  * additional tests
56  *
57  * Revision 1.12 2004/04/29 07:24:51 manolito
58  * fixed NPE in releaseFactories
59  *
60  * Revision 1.11 2004/04/13 08:25:59 manolito
61  * Log
62  *
63  */

64 public final class FactoryFinder
65 {
66     public static final String JavaDoc APPLICATION_FACTORY = "javax.faces.application.ApplicationFactory";
67     public static final String JavaDoc FACES_CONTEXT_FACTORY = "javax.faces.context.FacesContextFactory";
68     public static final String JavaDoc LIFECYCLE_FACTORY = "javax.faces.lifecycle.LifecycleFactory";
69     public static final String JavaDoc 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 JavaDoc getFactory(String JavaDoc factoryName)
89             throws FacesException
90     {
91         ClassLoader JavaDoc classLoader = getClassLoader();
92         Map factoryClassNames = (Map) _registeredFactoryNames.get(classLoader);
93
94         if (factoryClassNames == null)
95         {
96             String JavaDoc 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 JavaDoc(message);
102         }
103
104         if (! factoryClassNames.containsKey(factoryName)) {
105             throw new IllegalStateException JavaDoc("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 JavaDoc factory = factoryMap.get(factoryName);
115
116         if (factory == null) {
117             List classNames = (List) factoryClassNames.get(factoryName);
118             factory = newFactoryInstance((Class JavaDoc)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 JavaDoc newFactoryInstance(Class JavaDoc interfaceClass, Iterator classNamesIterator, ClassLoader JavaDoc classLoader)
130     {
131         try
132         {
133             Object JavaDoc current = null;
134
135             while (classNamesIterator.hasNext())
136             {
137                 String JavaDoc implClassName = (String JavaDoc) classNamesIterator.next();
138                 Class JavaDoc implClass = classLoader.loadClass(implClassName);
139
140                 // check, if class is of expected interface type
141
if (!interfaceClass.isAssignableFrom(implClass))
142                 {
143                     throw new IllegalArgumentException JavaDoc("Class " + implClassName + " is no " + interfaceClass.getName());
144                 }
145
146                 if (current == null)
147                 {
148                     // nothing to decorate
149
current = implClass.newInstance();
150                 } else
151                 {
152                     // let's check if class supports the decorator pattern
153
try
154                     {
155                         Constructor JavaDoc delegationConstructor = implClass.getConstructor(new Class JavaDoc[]{interfaceClass});
156                         // impl class supports decorator pattern,
157
try
158                         {
159                             // create new decorator wrapping current
160
current = delegationConstructor.newInstance(new Object JavaDoc[]{current});
161                         } catch (InstantiationException JavaDoc e)
162                         {
163                             throw new FacesException(e);
164                         } catch (IllegalAccessException JavaDoc e)
165                         {
166                             throw new FacesException(e);
167                         } catch (InvocationTargetException JavaDoc e)
168                         {
169                             throw new FacesException(e);
170                         }
171                     } catch (NoSuchMethodException JavaDoc e)
172                     {
173                         // no decorator pattern support
174
current = implClass.newInstance();
175                     }
176                 }
177             }
178
179             return current;
180         } catch (ClassNotFoundException JavaDoc e)
181         {
182             throw new FacesException(e);
183         } catch (InstantiationException JavaDoc e)
184         {
185             throw new FacesException(e);
186         } catch (IllegalAccessException JavaDoc e)
187         {
188             throw new FacesException(e);
189         }
190     }
191
192
193     public static void setFactory(String JavaDoc factoryName,
194                                   String JavaDoc implName)
195     {
196         checkFactoryName(factoryName);
197
198         ClassLoader JavaDoc classLoader = getClassLoader();
199         synchronized(_registeredFactoryNames)
200         {
201             Map factories = (Map) _factories.get(classLoader);
202
203             if (factories != null && factories.containsKey(factoryName)) {
204                 // Javadoc says ... This method has no effect if getFactory() has already been
205
// called looking for a factory for this factoryName.
206
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 JavaDoc classLoader = getClassLoader();
232         _factories.remove(classLoader);
233     }
234
235
236     private static void checkFactoryName(String JavaDoc factoryName)
237     {
238         if (! VALID_FACTORY_NAMES.contains(factoryName)) {
239             throw new IllegalArgumentException JavaDoc("factoryName '" + factoryName + "'");
240         }
241     }
242
243
244     private static ClassLoader JavaDoc getClassLoader()
245     {
246         try
247         {
248             ClassLoader JavaDoc 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 JavaDoc e)
256         {
257             throw new FacesException("web application class loader cannot be identified", e);
258         }
259     }
260 }
261
Popular Tags