KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*
2  * $Id: AbstractControllerFactory.java,v 1.1 2004/06/27 17:42:14 eelco12 Exp $
3  * $Source: /cvsroot/mav/maverick/src/java/org/infohazard/maverick/flow/AbstractControllerFactory.java,v $
4  */

5
6 package org.infohazard.maverick.flow;
7
8 import java.util.Map JavaDoc;
9
10 import javax.servlet.ServletConfig JavaDoc;
11 import javax.servlet.ServletException JavaDoc;
12
13 import org.infohazard.maverick.util.XML;
14 import org.jdom.Element;
15
16 /**
17  * Base class for controller factories.
18  * Creates (what appears to be) a singleton controller object appropriate
19  * for the type of controller specified in the XML, including single-use
20  * controllers. If no controller is specified, a special do-nothing
21  * controller is returned. If you want to use a custom controller factory,
22  * it is advisable to extend from this class and override either the
23  * interface method (createController) or override one or more of the
24  * template methods (getControllerClass, getControllerInstance and
25  * initializeController).
26  *
27  * @author Jeff Schnitzer
28  * @author Eelco Hillenius
29  */

30 public abstract class AbstractControllerFactory implements ControllerFactory
31 {
32     /**
33      * xml attribute of controller class.
34      */

35     protected static final String JavaDoc ATTR_CONTROLLER_CLASS = "class";
36
37     /**
38      * Dummy controller class.
39      */

40     static class NullController implements ControllerSingleton
41     {
42         /** initialize. */
43         public void init(Element controllerNode) {}
44
45         /** cmd method impl. */
46         public String JavaDoc go(ControllerContext cctx) throws ServletException JavaDoc
47             { return "NO CONTROLLER DEFINED"; }
48     }
49
50     /**
51      * dummy controller.
52      */

53     protected static final Controller nullController = new NullController();
54
55     /**
56      * Initialize: this method does nothing; override to customize.
57      * @see org.infohazard.maverick.flow.ControllerFactory#init(org.jdom.Element, javax.servlet.ServletConfig)
58      */

59     public void init(Element factoryNode, ServletConfig JavaDoc servletCfg) throws ConfigException
60     {
61         // no nada
62
}
63
64     /**
65      * Creates (what appears to be) a singleton controller object appropriate
66      * for the type of controller specified in the XML, including single-use
67      * controllers. If no controller is specified, a special do-nothing
68      * controller is returned.
69      * @see org.infohazard.maverick.flow.ControllerFactory#createController(org.jdom.Element)
70      */

71     public Controller createController(Element controllerNode) throws ConfigException
72     {
73         if (controllerNode == null) // if no controller is defined, return the dummy impl
74
{
75             return nullController;
76         }
77
78         // get the class of the controller node
79
Class JavaDoc controllerClass = getControllerClass(controllerNode);
80         // create the proper instance based on the class
81
Controller controller = getControllerInstance(controllerNode, controllerClass);
82         // initialize the controller based on the implementation
83
initializeController(controllerNode, controller);
84
85         return controller;
86     }
87
88     /**
89      * Get the controller class from the configuration.
90      * @param controllerNode the xml node of the controller
91      * @return Class the class from the configuration or null if the controller node was null
92      * @throws ConfigException
93      */

94     protected Class JavaDoc getControllerClass(Element controllerNode) throws ConfigException
95     {
96         if(controllerNode == null) return null;
97
98         String JavaDoc className = controllerNode.getAttributeValue(ATTR_CONTROLLER_CLASS);
99         if (className == null || className.trim().equals(""))
100         {
101             throw new ConfigException(
102                 "Controller element must have " + ATTR_CONTROLLER_CLASS
103                 + " attribute: " + XML.toString(controllerNode));
104         }
105
106         Class JavaDoc controllerClass;
107         try
108         {
109             ClassLoader JavaDoc classLoader = Thread.currentThread().getContextClassLoader();
110             if (classLoader == null)
111             {
112                 classLoader = AbstractControllerFactory.class.getClassLoader();
113             }
114             controllerClass = classLoader.loadClass(className);
115         }
116         catch (ClassNotFoundException JavaDoc ex) { throw new ConfigException(ex); }
117         return controllerClass;
118     }
119
120     /**
121      * Create a controller instance (or a decorator) based on the controller class
122      * and the controller node.
123      * @param controllerNode xml node of the controller
124      * @param controllerClass the class of the controller
125      * @return Controller a controller or a controller decorator
126      * @throws ConfigException
127      */

128     protected Controller getControllerInstance(
129             Element controllerNode,
130             Class JavaDoc controllerClass)
131             throws ConfigException
132     {
133         Controller controller = null;
134         try
135         {
136             if (ControllerSingleton.class.isAssignableFrom(controllerClass))
137             {
138                 controller = createSingletonController(controllerNode, controllerClass);
139             }
140             else
141             {
142                 controller = createThrowawayController(controllerNode, controllerClass);
143             }
144         }
145         catch (InstantiationException JavaDoc ex) { throw new ConfigException(ex); }
146         catch (IllegalAccessException JavaDoc ex) { throw new ConfigException(ex); }
147
148         // decorate the controller if needed
149
controller = decorateController(controllerNode, controller);
150         
151         return controller;
152     }
153
154     /**
155      * If needed, decorate the controller.
156      * @param controllerNode xml node of controller
157      * @param controller the controller instance.
158      * @return Controller the original controller or a decorator
159      * @throws ConfigException
160      */

161     protected Controller decorateController(
162             Element controllerNode,
163             Controller controller)
164             throws ConfigException
165     {
166         Controller decorated = controller;
167         Map JavaDoc params = XML.getParams(controllerNode);
168         if (params != null) // if we have params, create a decorator for the controller
169
{
170             decorated = new ControllerWithParams(controller, params);
171         }
172         return decorated;
173     }
174
175     /**
176      * Create a singleton controller instance.
177      * @param controllerNode controller node
178      * @param controllerClass controller class
179      * @return Controller instance
180      * @throws ConfigException
181      * @throws InstantiationException
182      * @throws IllegalAccessException
183      */

184     protected Controller createSingletonController(
185             Element controllerNode,
186             Class JavaDoc controllerClass)
187             throws ConfigException,
188             InstantiationException JavaDoc,
189             IllegalAccessException JavaDoc
190     {
191         return (ControllerSingleton)controllerClass.newInstance();
192     }
193
194     /**
195      * Create a throwaway controller; this implementation creates
196      * an instance of ThrowawayControllerAdapter.
197      * @param controllerNode controller node
198      * @param controllerClass controller class
199      * @return Controller instance
200      * @throws ConfigException
201      * @throws InstantiationException
202      * @throws IllegalAccessException
203      */

204     protected Controller createThrowawayController(
205             Element controllerNode,
206             Class JavaDoc controllerClass)
207             throws ConfigException,
208             InstantiationException JavaDoc,
209             IllegalAccessException JavaDoc
210     {
211         return new ThrowawayControllerAdapter(controllerClass);
212     }
213
214     /**
215      * initialize the controller if it needs to be done. This implementation
216      * just looks if the given controller (or embedded controller in case
217      * the given controller is a decorator) is of type ControllerSingleton and,
218      * if it is, it's init method is called.
219      * @param controllerNode the xml node of the controller
220      * @param controller the controller instance
221      * @throws ConfigException
222      */

223     protected void initializeController(
224             Element controllerNode,
225             Controller controller)
226             throws ConfigException
227     {
228         controller = getControllerUndecorated(controller);
229         if(controller instanceof ControllerSingleton)
230         {
231             ((ControllerSingleton)controller).init(controllerNode);
232         }
233         // else do nothing
234
}
235
236     /**
237      * Get the 'real' controller instance unwrapped.
238      * @param controller the controller or wrapper.
239      * @return Controller the 'real' controller instance unwrapped.
240      */

241     protected Controller getControllerUndecorated(Controller controller)
242     {
243         Controller concreteController = controller;
244         if(controller instanceof ControllerWithParams)
245         {
246             concreteController = ((ControllerWithParams)controller).getDecorated();
247         }
248         return concreteController;
249     }
250 }
251
Popular Tags