KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > inversoft > verge > mvc > controller > WebBeanHandle


1 /*
2  * Copyright (c) 2003, Inversoft
3  *
4  * This software is distribuable under the GNU Lesser General Public License.
5  * For more information visit gnu.org.
6  */

7 package com.inversoft.verge.mvc.controller;
8
9
10 import java.util.Collections JavaDoc;
11 import java.util.HashMap JavaDoc;
12 import java.util.Map JavaDoc;
13
14 import javax.servlet.http.HttpServletRequest JavaDoc;
15
16 import com.inversoft.beans.BeanException;
17 import com.inversoft.verge.util.WebBean;
18
19
20 /**
21  * <p>
22  * This class is used to reference a handle method of a
23  * bean stored in a scope. Handle methods mimic JavaBean
24  * getter and setters but use the String 'handle' instead
25  * of get or set.
26  * </p>
27  *
28  * <p>
29  * Since handle methods can take different parameters,
30  * including sub-classes of a type, this class contains
31  * a method named {@link #findBeanHandle(String, Class)
32  * findBeanHandle} which does the work of locating the
33  * {@link BeanHandle BeanHandle} instance of the handle
34  * method to invoke. This method can be overridden to
35  * provide different BeanHandle instances that take
36  * different parameter types. See that class for more
37  * information about parameter types.
38  * </p>
39  *
40  * @author Brian Pontarelli
41  * @since 1.0
42  * @version 2.0
43  */

44 public class WebBeanHandle {
45
46     /**
47      * This are the standard parameters to the handle methods for the Inversoft
48      * system
49      */

50     private static final Class JavaDoc[] HANDLE_PARAMS = new Class JavaDoc[] {Action.class};
51
52     /**
53      * Global switch for caching. This does not work yet so it is turned off. The
54      * problem is that the class can have two methods that take two different
55      * parameters, but both are valid handle methods.
56      */

57     static final boolean CACHING = true;
58
59     /**
60      * The cache Map for the BeanProperty objects (unsynchronized)
61      */

62     static Map JavaDoc cache = new HashMap JavaDoc();
63
64     private WebBean webBean;
65     private String JavaDoc handle;
66     private String JavaDoc nesting;
67
68
69     //--------------------------------------------------------------------------
70
// Cache Methods
71
//--------------------------------------------------------------------------
72

73
74     /**
75      * Returns an instance of the BeanHandle for the given handleName and
76      * bean Class. This object might be cached, depending on the implementation
77      * of this method. Therefore, you must take into account a cached or non-
78      * cached object.
79      *
80      * @param handleName The handle name of the BeanHandle
81      * @param beanClass The bean Class
82      * @return The BeanHandle and never null
83      * @throws BeanException If the creation of the obejct fails
84      */

85     private static BeanHandle getBeanHandle(String JavaDoc handleName, Class JavaDoc beanClass)
86     throws BeanException {
87
88         // If not caching, just create the objects
89
if (!CACHING) {
90             return new BeanHandle(handleName, beanClass, HANDLE_PARAMS);
91         }
92
93         // Otherwise look for the property Map or create and store
94
Map JavaDoc propMap = null;
95         synchronized (cache) {
96             propMap = (Map JavaDoc) cache.get(beanClass);
97             if (propMap == null) {
98                 propMap = Collections.synchronizedMap(new HashMap JavaDoc());
99                 cache.put(beanClass, propMap);
100             }
101         }
102
103         // Look for the property itself, or create and store
104
BeanHandle bh = null;
105         synchronized (propMap) {
106             bh = (BeanHandle) propMap.get(handleName);
107             if (bh == null) {
108                 bh = new BeanHandle(handleName, beanClass, HANDLE_PARAMS);
109                 propMap.put(handleName, bh);
110             }
111         }
112
113         return bh;
114     }
115
116
117     /**
118      * Constructs a new reference to the bean's handle method given by the
119      * id and handle parameters.
120      *
121      * @param id The id of the bean inside the scope that the bean will be
122      * placed in.
123      * @param handle The String that defines the nested properties of the
124      * bean and finally the handle method on the bean
125      * @param scope The scope that this bean is stored in
126      * @param className The Class of the bean so that it can be created if it does
127      * not exist in the scope
128      * @throws BeanException If the definition or scope are invalid or the Class
129      * is null
130      * @asserts If any parameters are null or the scope int is invalid
131      */

132     public WebBeanHandle(String JavaDoc id, String JavaDoc handle, int scope, String JavaDoc className)
133     throws BeanException {
134         // Does not call initialize, we do that here
135
super();
136
137         try {
138             initialize(id, handle, scope, Class.forName(className));
139         } catch (ClassNotFoundException JavaDoc cnfe) {
140             throw new BeanException(cnfe);
141         }
142     }
143
144     /**
145      * Constructs a new reference to the bean's handle method given by the
146      * definition parameter.
147      *
148      * @param definition The String that defines not only the name of the bean
149      * inside the scope, but also nested properties of the bean and
150      * finally the handle method on the bean
151      * @param scope The scope that this bean is stored in
152      * @param className The name of the Class of the bean so that it can be
153      * created if it does not exist in the scope
154      * @throws BeanException If the definition or scope are invalid or the Class
155      * is null
156      * @asserts If any parameters are null or the scope int is invalid
157      */

158     public WebBeanHandle(String JavaDoc definition, int scope, String JavaDoc className)
159     throws BeanException {
160         int index = definition.indexOf(".");
161         if (index == -1 || index == definition.length() - 1) {
162             throw new BeanException("Invalid handle definition: " + definition);
163         }
164
165         try {
166             initialize(definition.substring(0, index), definition.substring(index + 1),
167                 scope, Class.forName(className));
168         } catch (ClassNotFoundException JavaDoc cnfe) {
169             throw new BeanException(cnfe);
170         }
171     }
172
173     /**
174      * Constructs a new reference to the bean's handle method given by the
175      * definition parameter.
176      *
177      * @param definition The String that defines not only the name of the bean
178      * inside the scope, but also nested properties of the bean and
179      * finally the handle method on the bean
180      * @param scope The scope that this bean is stored in
181      * @param klass The Class of the bean so that it can be created if it does
182      * not exist in the scope
183      * @throws BeanException If the definition or scope are invalid or the Class
184      * is null
185      * @asserts If any parameters are null or the scope int is invalid
186      */

187     public WebBeanHandle(String JavaDoc definition, int scope, Class JavaDoc klass)
188     throws BeanException {
189         int index = definition.indexOf(".");
190         if (index == -1 || index == definition.length() - 1) {
191             throw new BeanException("Invalid handle definition: " + definition);
192         }
193
194         initialize(definition.substring(0, index), definition.substring(index + 1),
195             scope, klass);
196     }
197
198     /**
199      * Constructs a new reference to the bean's handle method given by the
200      * definition parameter.
201      *
202      * @param webBean The WebBean that the handle is defined for
203      * @param handle The String that defines the nested properties of the
204      * bean and finally the handle method on the bean
205      * @throws BeanException If the definition or scope are invalid or the Class
206      * is null
207      * @asserts If any parameters are null or the scope int is invalid
208      */

209     public WebBeanHandle(WebBean webBean, String JavaDoc handle)
210     throws BeanException {
211         this.webBean = webBean;
212         initialize(webBean.getID(), handle, webBean.getScope(), webBean.getBeanClass());
213     }
214
215
216     /**
217      * Initializes the WebBeanHandle
218      *
219      * @param id The id of the bean in the correct scope
220      * @param handle The String that defines the nested properties of the bean
221      * and finally the handle method on the bean
222      * @param scope The scope that this bean is stored in
223      * @param klass The Class of the bean so that it can be created if it does
224      * not exist in the scope
225      * @throws BeanException If the definition or scope are invalid or the Class
226      * is null
227      * @asserts If any parameters are null or the scope int is invalid
228      */

229     protected void initialize(String JavaDoc id, String JavaDoc handle, int scope, Class JavaDoc klass)
230     throws BeanException {
231
232         assert (id != null) : "id == null";
233         assert (handle != null) : "handle == null";
234
235         if (webBean == null) {
236             webBean = new WebBean(id, scope, klass);
237         }
238
239         // Pull out the nested property, the handle method and pass the id to
240
// the initialize method
241
int lastIndex = handle.lastIndexOf(".");
242         if (lastIndex != -1) {
243             nesting = handle.substring(0, lastIndex);
244             this.handle = handle.substring(lastIndex + 1);
245         } else {
246             this.handle = handle;
247         }
248     }
249
250     /**
251      * Returns the name of the handle method of the bean
252      *
253      * @return The name of the handle method (JavaBean property style)
254      */

255     public String JavaDoc getHandleName() {
256         return handle;
257     }
258
259     /**
260      * Returns the WebBean which is used internally to reference the bean which
261      * contains the handle method
262      *
263      * @return The WebBean for this handle
264      */

265     public WebBean getWebBean() {
266         return webBean;
267     }
268
269     /**
270      * Returns the parameters passed to the handle method.
271      *
272      * @return An array of Class objects which are the parameters to the handle
273      * method
274      */

275     public Class JavaDoc[] getHandleParams() {
276         return HANDLE_PARAMS;
277     }
278
279     /**
280      * Invokes the handle method for this handle reference with the given
281      * Action
282      *
283      * @param action The action to pass to the handle method
284      * @param request The request that is used to look up the bean from the
285      * scope it is (or will be) stored in
286      * @return The return value from the handle method if there was any. This
287      * could be any Object include primitive wrappers and arrays
288      * @throws BeanException If the handle method threw any other exception or
289      * if there was a problem invoking the method
290      */

291     public Object JavaDoc invokeHandle(Action action, HttpServletRequest JavaDoc request)
292     throws BeanException {
293
294         Object JavaDoc bean = null;
295         if (nesting == null) {
296             bean = webBean.getInstance(request);
297         } else {
298             bean = webBean.getPropertyValue(nesting, webBean.getInstance(request));
299         }
300
301         BeanHandle bh = findBeanHandle(handle, bean.getClass());
302         return bh.invokeHandle(bean, new Object JavaDoc[]{action});
303     }
304
305     /**
306      * Invokes the handle method for this handle reference with the given
307      * parameters
308      *
309      * @param params The parameters to the handle method
310      * @param request The request that is used to look up the bean from the
311      * scope it is (or will be) stored in
312      * @return The return value from the handle method if there was any. This
313      * could be any Object include primitive wrappers and arrays
314      * @throws BeanException If the handle method threw any other exception or
315      * if there was a problem invoking the method
316      */

317     public Object JavaDoc invokeHandle(Object JavaDoc[] params, HttpServletRequest JavaDoc request)
318     throws BeanException {
319
320         Object JavaDoc bean = null;
321         if (nesting == null) {
322             bean = webBean.getInstance(request);
323         } else {
324             bean = webBean.getPropertyValue(nesting, webBean.getInstance(request));
325         }
326
327         BeanHandle bh = findBeanHandle(handle, bean.getClass());
328         return bh.invokeHandle(bean, params);
329     }
330
331     /**
332      * Finds the BeanHandl object for the given handle name and bean class. Sub-
333      * classes can override this method to change the parameters to the handle
334      * method because the construct of the BeanHandle object takes a list of
335      * parameter Class objects.
336      *
337      * @param handleName The name of the handle method
338      * @param beanClass The bean class
339      * @return The BeanHandle object found (if any)
340      * @throws BeanException If there was a problem locating the BeanHandle
341      */

342     protected BeanHandle findBeanHandle(String JavaDoc handleName, Class JavaDoc beanClass)
343     throws BeanException {
344         return WebBeanHandle.getBeanHandle(handle, beanClass);
345     }
346 }
Popular Tags