KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > infohazard > maverick > flow > MasterFactory


1 /*
2  * $Id: MasterFactory.java,v 1.3 2004/06/27 17:41:31 eelco12 Exp $
3  * $Source: /cvsroot/mav/maverick/src/java/org/infohazard/maverick/flow/MasterFactory.java,v $
4  */

5
6 package org.infohazard.maverick.flow;
7
8 import java.util.HashMap JavaDoc;
9 import java.util.Iterator JavaDoc;
10 import java.util.List JavaDoc;
11 import java.util.Map JavaDoc;
12
13 import javax.servlet.ServletConfig JavaDoc;
14
15 import org.apache.commons.logging.Log;
16 import org.apache.commons.logging.LogFactory;
17 import org.infohazard.maverick.util.XML;
18 import org.jdom.Element;
19
20 /**
21  * Factory for creating View and Transform objects. This calls out to specific instances
22  * of ViewFactory and TransformFactory to actually create the objects.
23  */

24 class MasterFactory
25 {
26     /** Logger. */
27     private static Log log = LogFactory.getLog(MasterFactory.class);
28
29     /** xml attribute for type, value = 'type'. */
30     protected static final String JavaDoc ATTR_FACTORY_TYPE_NAME = "type";
31     /** xml attribute for the factory provider, value = 'provider'. */
32     protected static final String JavaDoc ATTR_FACTORY_PROVIDER = "provider";
33     /** xml attribute for the type name, value = 'type' */
34     protected static final String JavaDoc ATTR_TYPE_NAME = "type";
35     /** xml attribute for the transform type name (for a view node), value = 'transform-type' */
36     protected static final String JavaDoc ATTR_TRANSFORM_TYPE_NAME = "transform-type";
37
38
39     /** xml tag name for a transform, value = 'transform'. */
40     public static final String JavaDoc TAG_TRANSFORM = "transform";
41
42     /**
43      * Holds mapping of typeName to ViewFactory.
44      */

45     protected Map JavaDoc viewFactories = new HashMap JavaDoc();
46
47     /**
48      * Holds mapping of typeName to TransformFactory.
49      */

50     protected Map JavaDoc transformFactories = new HashMap JavaDoc();
51
52     /**
53      * The default type of factory to use if no explicit type is set.
54      */

55     protected String JavaDoc defaultViewType;
56
57     /**
58      * The default type of factory to use if no explicit type is set.
59      */

60     protected String JavaDoc defaultTransformType;
61
62     /**
63      * Reference to servlet config of Dispatcher servlet;
64      * needed to initialize View and Transform factories.
65      */

66     protected ServletConfig JavaDoc servletCfg;
67
68     /**
69      * Create the master factory with the dispatcher servlet config.
70      * @param servletCfg dispatcher servlet config
71      */

72     public MasterFactory(ServletConfig JavaDoc servletCfg)
73     {
74         this.servletCfg = servletCfg;
75     }
76
77     // --------- VIEWS ------------------------------------------------------
78

79     /**
80      * Sets the default type to use if one is not explicitly defined in the view node.
81      * @param type the default view type
82      */

83     public void setDefaultViewType(String JavaDoc type)
84     {
85         this.defaultViewType = type;
86     }
87
88     /**
89      * @param viewNode xml element for the view
90      * @throws ConfigException
91      * @return a View from the specified view node.
92      */

93     protected View createView(Element viewNode) throws ConfigException
94     {
95         View v = this.createPlainView(viewNode);
96
97         final List JavaDoc transformsList = viewNode.getChildren(TAG_TRANSFORM);
98
99         // Look for a "view transform", specified by the presence of a "path" attribute
100
final String JavaDoc transformPath = viewNode.getAttributeValue("path");
101         if (transformPath != null)
102         {
103             String JavaDoc typeName = viewNode.getAttributeValue(ATTR_TRANSFORM_TYPE_NAME);
104             if (typeName == null)
105             {
106                 // No transform type was set explicitly so we look for a transform type
107
// with the same name as that used for the view
108
typeName = viewNode.getAttributeValue(ATTR_TYPE_NAME);
109                 if (typeName == null)
110                     typeName = this.defaultViewType;
111             }
112
113             final TransformFactory tf = (TransformFactory)transformFactories.get(typeName);
114             if (tf != null)
115                 v = new ViewWithTransforms(v, new Transform[] {tf.createTransform(viewNode)});
116         }
117
118         if (!transformsList.isEmpty())
119         {
120             final Transform[] t = this.createTransforms(transformsList);
121             v = new ViewWithTransforms(v, t);
122         }
123
124         final Map JavaDoc params = XML.getParams(viewNode);
125         if (params != null)
126             v = new ViewWithParams(v, params);
127
128         return v;
129     }
130
131     /**
132      * Create a plain (undecorated) view object.
133      * @param viewNode xml node of the view
134      * @return View the plain (undecorated) view object
135      * @throws ConfigException
136      */

137     protected View createPlainView(Element viewNode) throws ConfigException
138     {
139         String JavaDoc typeName = viewNode.getAttributeValue(ATTR_TYPE_NAME);
140         if (typeName == null)
141             typeName = this.defaultViewType;
142
143         log.debug("Creating view of type " + typeName);
144
145         ViewFactory fact = (ViewFactory)this.viewFactories.get(typeName);
146
147         if (fact == null)
148             throw new ConfigException("No view factory can be found for " + XML.toString(viewNode));
149
150         return fact.createView(viewNode);
151     }
152
153     /**
154      * Defines a view factory for the specified type; Can be used to
155      * override a previously set factory.
156      * @param typeName name of the view type
157      * @param fact view factory
158      */

159     public void defineViewFactory(String JavaDoc typeName, ViewFactory fact)
160     {
161         log.info("View factory for \"" + typeName + "\" is " + fact.getClass().getName());
162
163         this.viewFactories.put(typeName, fact);
164
165         if (this.defaultViewType == null)
166             this.defaultViewType = typeName;
167     }
168
169     /**
170      * Define the view factories from the factory nodes.
171      * @param viewFactoryNodes the factory nodes
172      * @throws ConfigException
173      */

174     public void defineViewFactories(List JavaDoc viewFactoryNodes) throws ConfigException
175     {
176         // Define view factories specified in the config file.
177
Iterator JavaDoc it = viewFactoryNodes.iterator();
178         while (it.hasNext())
179         {
180             Element viewFactoryNode = (Element)it.next();
181
182             String JavaDoc typeName = viewFactoryNode.getAttributeValue(ATTR_FACTORY_TYPE_NAME);
183             String JavaDoc providerName = viewFactoryNode.getAttributeValue(ATTR_FACTORY_PROVIDER);
184
185             if (typeName == null || providerName == null)
186                 throw new ConfigException("Not a valid view factory node: " + XML.toString(viewFactoryNode));
187
188             Class JavaDoc providerClass;
189             ViewFactory instance;
190             try
191             {
192                 providerClass = loadClass(providerName);
193                 instance = (ViewFactory)providerClass.newInstance();
194             }
195             catch (Exception JavaDoc ex)
196             {
197                 throw new ConfigException("Unable to define view factory for " + typeName, ex);
198             }
199
200             // Give the factory an opportunity to initialize itself from any subnodes
201
instance.init(viewFactoryNode, this.servletCfg);
202
203             this.defineViewFactory(typeName, instance);
204         }
205     }
206
207     // --------- TRANSFORM DEFINES ------------------------------------------------------
208

209     /**
210      * Sets the default type to use if one is not explicitly defined in the transform node.
211      * @param type the default transform type
212      */

213     public void setDefaultTransformType(String JavaDoc type)
214     {
215         this.defaultTransformType = type;
216     }
217
218     /**
219      * Create transforms.
220      * @param transformNodes transform nodes
221      * @return array of transforms, possibly with length zero
222      * @throws ConfigException
223      */

224     protected Transform[] createTransforms(List JavaDoc transformNodes) throws ConfigException
225     {
226         Transform[] retVal = new Transform[transformNodes.size()];
227
228         int index = 0;
229         Iterator JavaDoc it = transformNodes.iterator();
230         while (it.hasNext())
231         {
232             Element transNode = (Element)it.next();
233
234             retVal[index] = this.createTransform(transNode);
235
236             index++;
237         }
238
239         return retVal;
240     }
241
242     /**
243      * Creates a possibly decorated transform.
244      * @param transformNode transform node
245      * @return a transform object
246      * @throws ConfigException
247      */

248     protected Transform createTransform(Element transformNode) throws ConfigException
249     {
250         Transform t = this.createPlainTransform(transformNode);
251
252         Map JavaDoc params = XML.getParams(transformNode);
253         if (params != null)
254             t = new TransformWithParams(t, params);
255
256         return t;
257     }
258
259     /**
260      * Create a plain (undecorated) transform object.
261      * @param transformNode transform node
262      * @return transform object
263      * @throws ConfigException
264      */

265     protected Transform createPlainTransform(Element transformNode) throws ConfigException
266     {
267         String JavaDoc typeName = transformNode.getAttributeValue(ATTR_TYPE_NAME);
268         if (typeName == null)
269             typeName = this.defaultTransformType;
270
271         log.debug("Creating transform of type " + typeName);
272
273         TransformFactory fact = (TransformFactory)this.transformFactories.get(typeName);
274
275         if (fact == null)
276             throw new ConfigException("No transform factory can be found for " + XML.toString(transformNode));
277
278         return fact.createTransform(transformNode);
279     }
280
281     /**
282      * Defines a transform factory for the specified type. Can be used to
283      * override a previously set factory.
284      * @param typeName name of type
285      * @param fact the transform factory
286      */

287     public void defineTransformFactory(String JavaDoc typeName, TransformFactory fact)
288     {
289         log.info("Transform factory for \"" + typeName + "\" is " + fact.getClass().getName());
290
291         this.transformFactories.put(typeName, fact);
292
293         if (this.defaultTransformType == null)
294             this.defaultTransformType = typeName;
295     }
296
297     /**
298      * Processes a collection of transform factory nodes.
299      * @param transFactoryNodes a list factory nodes
300      * @throws ConfigException
301      */

302     public void defineTransformFactories(List JavaDoc transFactoryNodes) throws ConfigException
303     {
304         // Define transform factories specified in the config file.
305
Iterator JavaDoc it = transFactoryNodes.iterator();
306         while (it.hasNext())
307         {
308             Element transFactoryNode = (Element)it.next();
309
310             String JavaDoc typeName = transFactoryNode.getAttributeValue(ATTR_FACTORY_TYPE_NAME);
311             String JavaDoc providerName = transFactoryNode.getAttributeValue(ATTR_FACTORY_PROVIDER);
312
313             if (typeName == null || providerName == null)
314                 throw new ConfigException("Not a valid transform factory node: " + XML.toString(transFactoryNode));
315
316             Class JavaDoc providerClass;
317             TransformFactory instance;
318             try
319             {
320                 providerClass = loadClass(providerName);
321                 instance = (TransformFactory)providerClass.newInstance();
322             }
323             catch (Exception JavaDoc ex)
324             {
325                 throw new ConfigException("Unable to define transform factory for " + typeName, ex);
326             }
327
328             // Give the factory an opportunity to initialize itself from any subnodes
329
instance.init(transFactoryNode, this.servletCfg);
330
331             this.defineTransformFactory(typeName, instance);
332         }
333     }
334
335     // --------- UTILITY METHODS ------------------------------------------------------
336

337     /**
338      * Load class.
339      * @param className full class name
340      * @return Class the class
341      * @throws ClassNotFoundException
342      */

343     protected Class JavaDoc loadClass(String JavaDoc className) throws ClassNotFoundException JavaDoc
344     {
345         ClassLoader JavaDoc classLoader = Thread.currentThread().getContextClassLoader();
346         if (classLoader == null)
347         {
348             classLoader = DefaultControllerFactory.class.getClassLoader();
349         }
350         Class JavaDoc cls = classLoader.loadClass(className);
351         return cls;
352     }
353 }
Popular Tags