KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > ivata > groupware > web > tag > container > ContainerBeanTag


1 /*
2  * Copyright (c) 2001 - 2005 ivata limited.
3  * All rights reserved.
4  * -----------------------------------------------------------------------------
5  * ivata groupware may be redistributed under the GNU General Public
6  * License as published by the Free Software Foundation;
7  * version 2 of the License.
8  *
9  * These programs are free software; you can redistribute them and/or
10  * modify them under the terms of the GNU General Public License
11  * as published by the Free Software Foundation; version 2 of the License.
12  *
13  * These programs are distributed in the hope that they will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16  *
17  * See the GNU General Public License in the file LICENSE.txt for more
18  * details.
19  *
20  * If you would like a copy of the GNU General Public License write to
21  *
22  * Free Software Foundation, Inc.
23  * 59 Temple Place - Suite 330
24  * Boston, MA 02111-1307, USA.
25  *
26  *
27  * To arrange commercial support and licensing, contact ivata at
28  * http://www.ivata.com/contact.jsp
29  * -----------------------------------------------------------------------------
30  * $Log: ContainerBeanTag.java,v $
31  * Revision 1.4 2005/04/30 13:06:28 colinmacleod
32  * Added default values for primitive wrappers.
33  *
34  * Revision 1.3 2005/04/10 20:10:06 colinmacleod
35  * Added new themes.
36  * Changed id type to String.
37  * Changed i tag to em and b tag to strong.
38  * Improved PicoContainerFactory with NanoContainer scripts.
39  *
40  * Revision 1.2 2005/04/09 17:19:59 colinmacleod
41  * Changed copyright text to GPL v2 explicitly.
42  *
43  * Revision 1.1.1.1 2005/03/10 17:51:35 colinmacleod
44  * Restructured ivata op around Hibernate/PicoContainer.
45  * Renamed ivata groupware.
46  *
47  * Revision 1.3 2004/12/23 21:01:30 colinmacleod
48  * Updated Struts to v1.2.4.
49  * Changed base classes to use ivata masks.
50  *
51  * Revision 1.2 2004/11/03 16:08:49 colinmacleod
52  * Fixed handling of 'automatic' string beans.
53  *
54  * Revision 1.1 2004/09/30 15:16:02 colinmacleod
55  * Split off addressbook elements into security subproject.
56  *
57  * Revision 1.7 2004/07/19 19:18:23 colinmacleod
58  * Made container override itself to create fresh instances.
59  *
60  * Revision 1.6 2004/07/18 22:03:47 colinmacleod
61  * Major bugfixes and extra scope handling.
62  *
63  * Revision 1.5 2004/07/17 16:09:13 colinmacleod
64  * Added checking to see if the security session is null.
65  *
66  * Revision 1.4 2004/07/14 22:38:37 colinmacleod
67  * Fixed bug in beanName.
68  *
69  * Revision 1.3 2004/07/14 22:30:13 colinmacleod
70  * Defaulted type to String.
71  *
72  * Revision 1.2 2004/07/14 22:13:44 colinmacleod
73  * Expanded to make a suitable replacement for bean:define.
74  *
75  * Revision 1.1 2004/07/13 19:41:15 colinmacleod
76  * Moved project to POJOs from EJBs.
77  * Applied PicoContainer to services layer (replacing session EJBs).
78  * Applied Hibernate to persistence layer (replacing entity EJBs).
79  * -----------------------------------------------------------------------------
80  */

81 package com.ivata.groupware.web.tag.container;
82
83 import org.apache.log4j.Logger;
84
85 import javax.servlet.http.HttpServletRequest JavaDoc;
86 import javax.servlet.http.HttpSession JavaDoc;
87 import javax.servlet.jsp.JspException JavaDoc;
88 import javax.servlet.jsp.PageContext JavaDoc;
89 import javax.servlet.jsp.tagext.BodyTagSupport JavaDoc;
90
91 import org.apache.struts.taglib.TagUtils;
92 import org.picocontainer.PicoContainer;
93
94 import com.ivata.groupware.admin.security.server.SecuritySession;
95 import com.ivata.groupware.container.PicoContainerFactory;
96 import com.ivata.mask.util.StringHandling;
97 import com.ivata.mask.util.SystemException;
98
99
100 /**
101  * <p>This tag retrieves an instance of the provided class from the current
102  * session contianer.</p>
103  *
104  * <p><strong>Tag attributes:</strong><br/>
105  * <table cellpadding='2' cellspacing='5' border='0' align='center'
106  * width='85%'>
107  * <tr class='TableHeadingColor'>
108  * <th>attribute</th>
109  * <th>reqd.</th>
110  * <th>param. class</th>
111  * <th width='100%'>description</th>
112  * </tr>
113  * <tr class='TableRowColor'>
114  * <td>id</td>
115  * <td>true</td>
116  * <td><code>String</code></td>
117  * <td>Id of the bean to be created.</td>
118  * </tr>
119  * <tr class='TableRowColor'>
120  * <td>type</td>
121  * <td>true</td>
122  * <td><code>String</code></td>
123  * <td>Class for which to retrieve an instance.</td>
124  * </tr>
125  * <tr class='TableRowColor'>
126  * <td>scope</td>
127  * <td>false</td>
128  * <td><code>String</code></td>
129  * <td>
130  * Scope into which to write the bean. Must be one of:
131  * <ul>
132  * <li>page (default)</li>
133  * <li>request</li>
134  * <li>session</li>
135  * <li>application</li>
136  * </ul>
137  * </td>
138  * </tr>
139  * </table>
140  * </p>
141  *
142  * @since 2004-06-12
143  * @author Colin MacLeod
144  * <a HREF='mailto:colin.macleod@ivata.com'>colin.macleod@ivata.com</a>
145  * @version $Revision: 1.4 $
146  */

147 public class ContainerBeanTag extends BodyTagSupport JavaDoc {
148     /**
149      * Logger for this class.
150      */

151     private static final Logger logger = Logger
152             .getLogger(ContainerBeanTag.class);
153
154     private final static String JavaDoc [] SCOPES = new String JavaDoc[] {
155             "application",
156             "session",
157             "request",
158             "page"
159     };
160
161     /**
162      * <p>
163      * Contains the contents of the tag body, or <code>null</code> if the body
164      * is empty.
165      * </p>
166      */

167     private String JavaDoc body;
168     /**
169      * <p>
170      * Identifier for page attribute.
171      * </p>
172      */

173     private String JavaDoc id = null;
174
175     /**
176      * <p>
177      * Name of a bean to use from the scope specified. This defaults to the
178      * value of <code>id</code>.
179      * </p>
180      */

181     private String JavaDoc name;
182
183     /**
184      * <p>
185      * Name of a property in the bean called <code>name</code>. This will act
186      * like <code>name.getProperty()</code>.
187      * </p>
188      */

189     private String JavaDoc property;
190     /**
191      * <p>
192      * Scope from which the page attribute is read.
193      * </p>
194      */

195     private String JavaDoc scope;
196
197     /**
198      * <p>
199      * Scope to which the page attribute is set. Defaults to the value for
200      * <code>scope</code>.
201      * </p>
202      */

203     private String JavaDoc toScope;
204
205     /**
206      * <p>Class of the setting to be retrieved - this must match the setting
207      * type. Defaults to &quot;String&quot;</p>
208      */

209     private String JavaDoc type = null;
210
211     /**
212      * <p>
213      * The value to set the object to, if set as an attribute. If the value is
214      * a string, you can also use the tag body.
215      * </p>
216      */

217     private Object JavaDoc value;
218
219     /**
220      * <p>
221      * Wrapper for <code>RequestUtils.lookup</p>. This method does not throw
222      * an exception if the bean property does not exist - it merely returns
223      * <code>null</code>.
224      * </p>
225      *
226      * @param pageContext Page context being processed.
227      * @param beanName Name of a bean to locate in the page context.
228      * @param property Optional property name within the bean. Set to
229      * <code>null</code> to return the bean itself.
230      * @param beanScope one of <ul><li>application</li><li>session</li>
231      * <li>request</li> or <li>page</li></ul>
232      * @return value of the bean or bean property, or <code>null</code> if no
233      * such bean exists in any scope.
234      * @throws JspException Thrown by <code>RequestUtils.lookup</code>.
235      */

236     private Object JavaDoc beanLookup(final PageContext JavaDoc pageContext,
237             final String JavaDoc beanName,
238             final String JavaDoc property,
239             final String JavaDoc beanScope)
240             throws JspException JavaDoc {
241         TagUtils tagUtils = TagUtils.getInstance();
242         Object JavaDoc thisValue = tagUtils.lookup(pageContext, beanName, beanScope);
243         // if there is a property, only find the value for that if there
244
// is a bean in the scope requested (otherwise an exception is
245
// thrown)
246
if ((thisValue != null)
247                 && (property != null)) {
248             thisValue = tagUtils.lookup(pageContext, beanName, property, beanScope);
249         }
250         return thisValue;
251     }
252
253     /**
254      * TODO
255      *
256      * @see javax.servlet.jsp.tagext.IterationTag#doAfterBody()
257      */

258     public int doAfterBody() throws JspException JavaDoc {
259         String JavaDoc thisBody;
260         if ((bodyContent != null)
261                 && ((thisBody = bodyContent.getString()) != null)
262                 && ((thisBody = thisBody.trim()).length() > 0)) {
263             body = thisBody;
264         }
265         return SKIP_BODY;
266
267     }
268
269     public int doEndTag() throws JspException JavaDoc {
270         // before we do anything else, get the request and session
271
HttpSession JavaDoc session = pageContext.getSession();
272         HttpServletRequest JavaDoc request = (HttpServletRequest JavaDoc)
273             pageContext.getRequest();
274
275         Object JavaDoc thisValue = null;
276         String JavaDoc actualType = this.type;
277         if (actualType == null) {
278             // if there is no name specified, assume that the tag contents are
279
// used
280
if ((name == null) || (value != null)) {
281                 actualType = "java.lang.String";
282             } else {
283                 actualType = "java.lang.Object";
284             }
285         }
286
287         if (body != null) {
288             // check both attribute and body were not supplied!
289
if (value != null) {
290                 throw new JspException JavaDoc("ERROR in ContainerBeanTag(id "
291                         + id
292                         + "): you cannot specify both tag body ('"
293                         + body
294                         + "') and value attribute ('"
295                         + value
296                         + "'");
297             }
298             thisValue = body;
299             actualType = "java.lang.String";
300         } else {
301             thisValue = value;
302         }
303
304         // finally look to see if there is a default in the chosen scope
305
if (thisValue == null) {
306             // if no name specified, use the id as name
307
String JavaDoc beanName = name == null ? id : name;
308             String JavaDoc beanScope = scope;
309
310             if (scope == null) {
311                 Class JavaDoc searchClass;
312                 try {
313                     searchClass = Class.forName(actualType);
314                 } catch (ClassNotFoundException JavaDoc e) {
315                     throw new JspException JavaDoc(e);
316                 }
317
318
319                 // if there was no appropriate bean at application scope, go
320
// thro' the others too
321
for (int i = 0; i < SCOPES.length; i++) {
322                     thisValue = beanLookup(pageContext, beanName,
323                             property, beanScope = SCOPES[i]);
324                     // if we found a valid bean, get out here...
325
if ((thisValue != null)
326                             && searchClass.isAssignableFrom(
327                                     thisValue.getClass())) {
328                         break;
329                     }
330                 }
331             } else {
332                 thisValue = beanLookup(pageContext, beanName,
333                         property, beanScope);
334             }
335         }
336
337         // if we have a string, default it to a request parameter, if one is
338
// available; request parameters always override the value for igw beans
339
// :-)
340
if ((thisValue == null)
341                 && "java.lang.String".equals(actualType)
342                 && !StringHandling.isNullOrEmpty(request.getParameter(id))) {
343             thisValue = request.getParameter(id);
344         }
345
346         // if the value is _still_ null, try to create a new bean from the
347
// container
348
if (thisValue == null) {
349             // initialize primitive type wrappers
350
if ("java.lang.Boolean".equals(actualType)) {
351                 thisValue = Boolean.FALSE;
352             } else if ("java.lang.Byte".equals(actualType)) {
353                 thisValue = new Byte JavaDoc((byte)0);
354             } else if ("java.lang.Character".equals(actualType)) {
355                 thisValue = new Character JavaDoc((char)0);
356             } else if ("java.lang.double".equals(actualType)) {
357                 thisValue = new Double JavaDoc(0L);
358             } else if ("java.lang.Float".equals(actualType)) {
359                 thisValue = new Float JavaDoc(0L);
360             } else if ("java.lang.Integer".equals(actualType)) {
361                 thisValue = new Integer JavaDoc(0);
362             } else if ("java.lang.Long".equals(actualType)) {
363                 thisValue = new Long JavaDoc(0L);
364             } else if ("java.lang.Short".equals(actualType)) {
365                 thisValue = new Short JavaDoc((short)0);
366             } else {
367                 // really use the container
368
SecuritySession securitySession = (SecuritySession)
369                 session.getAttribute("securitySession");
370                 PicoContainer container;
371
372                 // if there is no security session yet, use the default
373
// container
374
// this should only really happen in /login.jsp or /index.jsp
375
PicoContainerFactory factory;
376                 try {
377                     factory = PicoContainerFactory.getInstance();
378                 } catch (SystemException e) {
379                     throw new JspException JavaDoc(e);
380                 }
381                 if (securitySession == null) {
382                     container = factory.getGlobalContainer();
383                 } else {
384                     container = securitySession.getContainer();
385                 }
386                 // override - we want fresh instances
387
try {
388                     container = factory.override(container);
389                     thisValue =
390                         factory.instantiateOrOverride(container,
391                                 actualType);
392                 } catch (SystemException e) {
393                     throw new JspException JavaDoc(e);
394                 }
395             }
396         }
397
398         if (thisValue == null) {
399             throw new JspException JavaDoc("ERROR: could not instantiate id '"
400                     + id
401                     + "' for class '"
402                     + actualType
403                     + "'");
404         }
405
406         // set the value to the page
407
int writeScope;
408         TagUtils tagUtils = TagUtils.getInstance();
409         if (toScope != null) {
410             writeScope = tagUtils.getScope(toScope);
411         } else if (scope != null) {
412             writeScope = tagUtils.getScope(scope);
413         } else {
414             writeScope = PageContext.PAGE_SCOPE;
415         }
416         pageContext.setAttribute(id, thisValue, writeScope);
417
418         return EVAL_PAGE;
419     }
420
421     /**
422      * <p>This method is called when the JSP engine encounters the start
423      * tag, after the attributes are processed.<p>
424      *
425      * @return <code>EVAL_BODY_BUFFERED</code> since this tag may have a body
426      * @exception JspException if there is a <code>NamingExcpetion</code>
427      * getting the <code>InitialContext</code>
428      * @exception JspException if the session applicationServer is not
429      * set
430      * @throws JspException if there is a problem creating the
431      * SettingsRemote EJB
432      * @throws JspException if there is a
433      * <code>java.rmi.RemoteException</code retrieving the setting
434      * @throws JspException if there is an error wrting to
435      * <code>out.print()</code>
436      */

437     public int doStartTag() throws JspException JavaDoc {
438         return EVAL_BODY_BUFFERED;
439     }
440
441
442     /**
443      * <p>
444      * Identifier for page attribute.
445      * </p>
446      *
447      * @return current identifier for page attribute.
448      */

449     public final String JavaDoc getId() {
450         return id;
451     }
452
453     /**
454      * <p>
455      * Name of a bean to use from the scope specified. This defaults to the
456      * value of <code>id</code>.
457      * </p>
458      *
459      * @return current value of name.
460      */

461     public final String JavaDoc getName() {
462         return name;
463     }
464     /**
465      * <p>
466      * Name of a property in the bean called <code>name</code>. This will act
467      * like <code>name.getProperty()</code>.
468      * </p>
469      *
470      * @return current value of property.
471      */

472     public final String JavaDoc getProperty() {
473         return property;
474     }
475
476     /**
477      * <p>
478      * Scope to which the page attribute is set.
479      * </p>
480      *
481      * @return scope to which the page attribute is set.
482      */

483     public final String JavaDoc getScope() {
484         return scope;
485     }
486     /**
487      * <p>
488      * Scope to which the page attribute is set. Defaults to the value for
489      * <code>scope</code>.
490      * </p>
491      *
492      * @return current value of toScope.
493      */

494     public final String JavaDoc getToScope() {
495         return toScope;
496     }
497
498     /**
499      * <p>Class of the setting to be retrieved - this must match the setting
500      * type.</p>
501      *
502      * @return class of the setting to be retrieved.
503      */

504     public final String JavaDoc getType() {
505         return type;
506     }
507     /**
508      * <p>
509      * The value to set the object to, if set as an attribute. If the value is
510      * a string, you can also use the tag body.
511      * </p>
512      *
513      * @return current value of value.
514      */

515     public final Object JavaDoc getValue() {
516         return value;
517     }
518
519     /**
520      * <p>
521      * Identifier for page attribute.
522      * </p>
523      *
524      * @param string new identifier for page attribute.
525      */

526     public final void setId(final String JavaDoc string) {
527         id = string;
528     }
529     /**
530      * <p>
531      * Name of a bean to use from the scope specified. This defaults to the
532      * value of <code>id</code>.
533      * </p>
534      *
535      * @param name new value of name.
536      */

537     public final void setName(final String JavaDoc name) {
538         this.name = name;
539     }
540     /**
541      * <p>
542      * Name of a property in the bean called <code>name</code>. This will act
543      * like <code>name.getProperty()</code>.
544      * </p>
545      *
546      * @param property new value of property.
547      */

548     public final void setProperty(final String JavaDoc property) {
549         this.property = property;
550     }
551
552     /**
553      * <p>
554      * Scope to which the page attribute is set.
555      * </p>
556      *
557      * @param string scope to which the page attribute is set.
558      */

559     public final void setScope(final String JavaDoc string) {
560         scope = string;
561     }
562     /**
563      * <p>
564      * Scope to which the page attribute is set. Defaults to the value for
565      * <code>scope</code>.
566      * </p>
567      *
568      * @param toScope new value of toScope.
569      */

570     public final void setToScope(final String JavaDoc toScope) {
571         this.toScope = toScope;
572     }
573
574     /**
575      * <p>Class of the setting to be retrieved.</p>
576      *
577      * @param string class of the setting to be retrieved.
578      */

579     public final void setType(final String JavaDoc string) {
580         type = string;
581     }
582     /**
583      * <p>
584      * The value to set the object to, if set as an attribute. If the value is
585      * a string, you can also use the tag body.
586      * </p>
587      *
588      * @param value new value of value.
589      */

590     public final void setValue(final Object JavaDoc value) {
591         this.value = value;
592     }
593 }
594
Popular Tags