Source code: com/RuntimeCollective/webapps/tag/FindBeanCollectionTag.java
1 /* $Header: /home/CVS/rjp/src/com/RuntimeCollective/webapps/tag/FindBeanCollectionTag.java,v 1.3 2003/09/30 15:13:18 joe Exp $
2 * $Revision: 1.3 $
3 * $Date: 2003/09/30 15:13:18 $
4 *
5 * ====================================================================
6 *
7 * Josephine : http://www.runtime-collective.com/josephine/index.html
8 *
9 * Copyright (C) 2003 Runtime Collective
10 *
11 * This product includes software developed by the
12 * Apache Software Foundation (http://www.apache.org/).
13 *
14 * This library is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU Lesser General Public
16 * License as published by the Free Software Foundation; either
17 * version 2.1 of the License, or (at your option) any later version.
18 *
19 * This library is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 * Lesser General Public License for more details.
23 *
24 * You should have received a copy of the GNU Lesser General Public
25 * License along with this library; if not, write to the Free Software
26 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 *
28 */
29
30 package com.RuntimeCollective.webapps.tag;
31
32 import com.RuntimeCollective.webapps.RuntimeParameters;
33 import com.RuntimeCollective.webapps.bean.EntityBean;
34
35 import java.lang.reflect.Method;
36 import java.lang.reflect.InvocationTargetException;
37 import java.sql.SQLException;
38 import java.util.Collection;
39 import javax.servlet.jsp.JspException;
40 import javax.servlet.jsp.JspWriter;
41 import javax.servlet.jsp.PageContext;
42 import javax.servlet.jsp.tagext.TagSupport;
43 import org.apache.struts.action.Action;
44 import org.apache.struts.action.ActionError;
45 import org.apache.struts.action.ActionErrors;
46 import org.apache.struts.util.MessageResources;
47
48 /** Finds a collection of EntityBean's given the bean type and a named query.
49 *
50 * <p>The tag uses reflection to call the static finder method for the query
51 * on the bean type. The naming convention for the finder method is:</p>
52 *
53 * <p><code>public static Collection findQueryName();</code></p>
54 *
55 * <p>Attributes:</p>
56 *
57 * <ul>
58 * <li>name - the name of the collection to create.</li>
59 * <li>scope - the scope in which to create the collection. [optional]</li>
60 * <li>type - the subtype of the EntityBean in which the finder is defined.</li>
61 * <li>query - the name of the query to be executed.</li>
62 * </ul>
63 *
64 * <p>For example, the tag:</p>
65 *
66 * <p><code><rs:findBeans name="giraffes"
67 * type="com.RuntimeCollective.webapps.bean.Giraffe"
68 * query="femaleGiraffes" /></code></p>
69 *
70 * <p>Would cause a collection called "giraffes" to be defined in
71 * page scope which contained the results of executing
72 * Giraffe.findFemaleGiraffes()</p>
73 *
74 * <p>If an exception is thrown while trying execute the query, the error is
75 * logged and an empty collection is returned to the calling page.</p>
76 *
77 * @author Lee Denison (lee@runtime-collective.com)
78 * @version $Id: FindBeanCollectionTag.java,v 1.3 2003/09/30 15:13:18 joe Exp $
79 */
80 public final class FindBeanCollectionTag extends TagSupport {
81
82 private String name;
83 /** get the name. */
84 public String getName() { return name; }
85 /** set the name. */
86 public void setName(String name) { this.name = name; }
87
88 private String scope;
89 /** get the scope. */
90 public String getScope() { return scope; }
91 /** set the scope. */
92 public void setScope(String scope) { this.scope = scope; }
93
94 private String type;
95 /** get the type. */
96 public String getType() { return type; }
97 /** set the type. */
98 public void setType(String type) { this.type = type; }
99
100 private String query;
101 /** get the query. */
102 public String getQuery() { return query; }
103 /** set the query. */
104 public void setQuery(String query) { this.query = query; }
105
106 public FindBeanCollectionTag() {
107 initialise();
108 }
109
110 /** Execute the query and define the collection. */
111 public int doStartTag() throws JspException {
112 ActionErrors errors = new ActionErrors();
113
114 try {
115 Method finderMethod = getFinder();
116 Collection beans = (Collection) finderMethod.invoke(null, null);
117
118 if (null == scope ||
119 scope.equals("page")) {
120 pageContext.setAttribute(name, beans);
121 } else if (scope.equals("request")) {
122 pageContext.setAttribute(name,
123 beans,
124 PageContext.REQUEST_SCOPE);
125 } else if (scope.equals("session")) {
126 pageContext.setAttribute(name,
127 beans,
128 PageContext.SESSION_SCOPE);
129 } else if (scope.equals("application")) {
130 pageContext.setAttribute(name,
131 beans,
132 PageContext.SESSION_SCOPE);
133 } else {
134 RuntimeParameters.logError(this, "unknown scope - " + scope);
135 }
136 } catch (ClassCastException e) {
137 RuntimeParameters.logError(this,
138 type + "." + mangleMethodName() +
139 " does not return a java.util.Collection",
140 e);
141 } catch (InvocationTargetException e) {
142 RuntimeParameters.logError(this,
143 "exception thrown in " +
144 type + "." + mangleMethodName(),
145 e.getTargetException());
146 // FIXME: Have to print the stack trace of the enclosed exception
147 // FIXME separately because logError doesn't do it.
148 e.getTargetException().printStackTrace();
149 } catch (NoSuchMethodException e) {
150 RuntimeParameters.logError(this, type + "." + mangleMethodName(), e);
151 } catch (Exception e) {
152 RuntimeParameters.logError(this, e.getMessage(), e);
153 }
154
155 return (SKIP_BODY);
156 }
157
158 /** Release any acquired resources. */
159 public void release() {
160 super.release();
161
162 initialise();
163 }
164
165 private Method getFinder()
166 throws ClassNotFoundException,
167 NoSuchMethodException,
168 SecurityException {
169 Class finderClass = Class.forName(type);
170
171 if (null == query) {
172 throw new NoSuchMethodException("no method specified");
173 }
174
175 return finderClass.getMethod(mangleMethodName(), null);
176 }
177
178 private String mangleMethodName() {
179 StringBuffer finderName = new StringBuffer("find");
180 finderName.append(Character.toUpperCase(query.charAt(0)));
181 finderName.append(query.substring(1));
182
183 return finderName.toString();
184 }
185
186 private void initialise() {
187 name = null;
188 scope = null;
189 type = null;
190 query = null;
191 }
192 }