1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.struts.tiles.taglib.util;
20
21 import java.lang.reflect.InvocationTargetException;
22 import java.util.Map;
23 import java.util.HashMap;
24
25 import javax.servlet.jsp.JspException;
26 import javax.servlet.jsp.PageContext;
27
28 import org.apache.commons.beanutils.PropertyUtils;
29 import org.apache.struts.Globals;
30 import org.apache.struts.tiles.taglib.ComponentConstants;
31 import org.apache.struts.tiles.ComponentContext;
32 import org.apache.struts.tiles.ComponentDefinition;
33 import org.apache.struts.tiles.DefinitionsFactoryException;
34 import org.apache.struts.tiles.FactoryNotFoundException;
35 import org.apache.struts.tiles.NoSuchDefinitionException;
36 import org.apache.struts.tiles.TilesUtil;
37
38 /***
39 * Collection of utilities.
40 * This class also serves as an interface between Components and Struts. If
41 * you want to rip away Struts, simply reimplement some methods in this class.
42 * You can copy them from Struts.
43 *
44 */
45 public class TagUtils {
46
47 /*** Debug flag */
48 public static final boolean debug = true;
49
50 /***
51 * Maps lowercase JSP scope names to their PageContext integer constant
52 * values.
53 */
54 private static final Map scopes = new HashMap();
55
56 /***
57 * Initialize the scope names map and the encode variable with the
58 * Java 1.4 method if available.
59 */
60 static {
61 scopes.put("page", new Integer(PageContext.PAGE_SCOPE));
62 scopes.put("request", new Integer(PageContext.REQUEST_SCOPE));
63 scopes.put("session", new Integer(PageContext.SESSION_SCOPE));
64 scopes.put("application", new Integer(PageContext.APPLICATION_SCOPE));
65 }
66
67
68 /***
69 * Get scope value from string value
70 * @param scopeName Scope as a String.
71 * @param defaultValue Returned default value, if not found.
72 * @return Scope as an <code>int</code>, or <code>defaultValue</code> if scope is <code>null</code>.
73 * @throws JspException Scope name is not recognized as a valid scope.
74 */
75 public static int getScope(String scopeName, int defaultValue) throws JspException {
76 if (scopeName == null) {
77 return defaultValue;
78 }
79
80 if (scopeName.equalsIgnoreCase("component")) {
81 return ComponentConstants.COMPONENT_SCOPE;
82
83 } else if (scopeName.equalsIgnoreCase("template")) {
84 return ComponentConstants.COMPONENT_SCOPE;
85
86 } else if (scopeName.equalsIgnoreCase("tile")) {
87 return ComponentConstants.COMPONENT_SCOPE;
88
89 } else {
90 return getScope(scopeName);
91 }
92 }
93
94 /***
95 * Converts the scope name into its corresponding PageContext constant value.
96 * @param scopeName Can be "page", "request", "session", or "application" in any
97 * case.
98 * @return The constant representing the scope (ie. PageContext.REQUEST_SCOPE).
99 * @throws JspException if the scopeName is not a valid name.
100 */
101 public static int getScope(String scopeName) throws JspException {
102 Integer scope = (Integer) scopes.get(scopeName.toLowerCase());
103
104 if (scope == null) {
105
106 throw new JspException("Unable to retrieve the scope "+scopeName);
107 }
108
109 return scope.intValue();
110 }
111
112
113 /***
114 * Retrieve bean from page context, using specified scope.
115 * If scope is not set, use <code>findAttribute()</code>.
116 *
117 * @param beanName Name of bean to retrieve.
118 * @param scopeName Scope or <code>null</code>. If <code>null</code>, bean is searched using
119 * findAttribute().
120 * @param pageContext Current pageContext.
121 * @return Requested bean or <code>null</code> if not found.
122 * @throws JspException Scope name is not recognized as a valid scope.
123 */
124 public static Object retrieveBean(String beanName, String scopeName, PageContext pageContext)
125 throws JspException {
126
127 if (scopeName == null) {
128 return findAttribute(beanName, pageContext);
129 }
130
131
132 int scope = getScope(scopeName, PageContext.PAGE_SCOPE);
133
134
135 return getAttribute(beanName, scope, pageContext);
136 }
137
138 /***
139 * Search attribute in different contexts.
140 * First, check in component context, then use pageContext.findAttribute().
141 * @param beanName Name of bean to retrieve.
142 * @param pageContext Current pageContext.
143 * @return Requested bean or <code>null</code> if not found.
144 */
145 public static Object findAttribute(String beanName, PageContext pageContext) {
146 ComponentContext compContext = ComponentContext.getContext(pageContext.getRequest());
147
148 if (compContext != null) {
149 Object attribute = compContext.findAttribute(beanName, pageContext);
150 if (attribute != null) {
151 return attribute;
152 }
153 }
154
155
156 return pageContext.findAttribute(beanName);
157 }
158
159 /***
160 * Get object from requested context. Return <code>null</code> if not found.
161 * Context can be "component" or normal JSP contexts.
162 * @param beanName Name of bean to retrieve.
163 * @param scope Scope from which bean must be retrieved.
164 * @param pageContext Current pageContext.
165 * @return Requested bean or <code>null</code> if not found.
166 */
167 public static Object getAttribute(String beanName, int scope, PageContext pageContext) {
168 if (scope == ComponentConstants.COMPONENT_SCOPE) {
169 ComponentContext compContext = ComponentContext.getContext(pageContext.getRequest());
170 return compContext.getAttribute(beanName);
171 }
172 return pageContext.getAttribute(beanName, scope);
173 }
174
175 /***
176 * Locate and return the specified property of the specified bean, from
177 * an optionally specified scope, in the specified page context.
178 *
179 * @param pageContext Page context to be searched.
180 * @param beanName Name of the bean to be retrieved.
181 * @param beanProperty Name of the property to be retrieved, or
182 * <code>null</code> to retrieve the bean itself.
183 * @param beanScope Scope to be searched (page, request, session, application)
184 * or <code>null</code> to use <code>findAttribute()</code> instead.
185 *
186 * @exception JspException Scope name is not recognized as a valid scope
187 * @exception JspException if the specified bean is not found
188 * @exception JspException if accessing this property causes an
189 * IllegalAccessException, IllegalArgumentException,
190 * InvocationTargetException, or NoSuchMethodException
191 */
192 public static Object getRealValueFromBean(
193 String beanName,
194 String beanProperty,
195 String beanScope,
196 PageContext pageContext)
197 throws JspException {
198
199 try {
200 Object realValue;
201 Object bean = retrieveBean(beanName, beanScope, pageContext);
202 if (bean != null && beanProperty != null) {
203 realValue = PropertyUtils.getProperty(bean, beanProperty);
204 } else {
205 realValue = bean;
206 }
207 return realValue;
208
209 } catch (NoSuchMethodException ex) {
210 throw new JspException(
211 "Error - component.PutAttributeTag : Error while retrieving value from bean '"
212 + beanName
213 + "' with property '"
214 + beanProperty
215 + "' in scope '"
216 + beanScope
217 + "'. (exception : "
218 + ex.getMessage(), ex);
219
220 } catch (InvocationTargetException ex) {
221 throw new JspException(
222 "Error - component.PutAttributeTag : Error while retrieving value from bean '"
223 + beanName
224 + "' with property '"
225 + beanProperty
226 + "' in scope '"
227 + beanScope
228 + "'. (exception : "
229 + ex.getMessage(), ex);
230
231 } catch (IllegalAccessException ex) {
232 throw new JspException(
233 "Error - component.PutAttributeTag : Error while retrieving value from bean '"
234 + beanName
235 + "' with property '"
236 + beanProperty
237 + "' in scope '"
238 + beanScope
239 + "'. (exception : "
240 + ex.getMessage(), ex);
241 }
242 }
243
244 /***
245 * Store bean in requested context.
246 * If scope is <code>null</code>, save it in REQUEST_SCOPE context.
247 *
248 * @param pageContext Current pageContext.
249 * @param name Name of the bean.
250 * @param scope Scope under which bean is saved (page, request, session, application)
251 * or <code>null</code> to store in <code>request()</code> instead.
252 * @param value Bean value to store.
253 *
254 * @exception JspException Scope name is not recognized as a valid scope
255 */
256 public static void setAttribute(
257 PageContext pageContext,
258 String name,
259 Object value,
260 String scope)
261 throws JspException {
262
263 if (scope == null)
264 pageContext.setAttribute(name, value, PageContext.REQUEST_SCOPE);
265 else if (scope.equalsIgnoreCase("page"))
266 pageContext.setAttribute(name, value, PageContext.PAGE_SCOPE);
267 else if (scope.equalsIgnoreCase("request"))
268 pageContext.setAttribute(name, value, PageContext.REQUEST_SCOPE);
269 else if (scope.equalsIgnoreCase("session"))
270 pageContext.setAttribute(name, value, PageContext.SESSION_SCOPE);
271 else if (scope.equalsIgnoreCase("application"))
272 pageContext.setAttribute(name, value, PageContext.APPLICATION_SCOPE);
273 else {
274 throw new JspException("Error - bad scope name '" + scope + "'");
275 }
276 }
277
278 /***
279 * Store bean in REQUEST_SCOPE context.
280 *
281 * @param pageContext Current pageContext.
282 * @param name Name of the bean.
283 * @param beanValue Bean value to store.
284 *
285 * @exception JspException Scope name is not recognized as a valid scope
286 */
287 public static void setAttribute(PageContext pageContext, String name, Object beanValue)
288 throws JspException {
289 pageContext.setAttribute(name, beanValue, PageContext.REQUEST_SCOPE);
290 }
291
292 /***
293 * Save the specified exception as a request attribute for later use.
294 *
295 * @param pageContext The PageContext for the current page.
296 * @param exception The exception to be saved.
297 */
298 public static void saveException(PageContext pageContext, Throwable exception) {
299 pageContext.setAttribute(Globals.EXCEPTION_KEY, exception, PageContext.REQUEST_SCOPE);
300 }
301
302 /***
303 * Get component definition by its name.
304 * @param name Definition name.
305 * @param pageContext The PageContext for the current page.
306 * @throws JspException -
307 */
308 public static ComponentDefinition getComponentDefinition(String name, PageContext pageContext)
309 throws JspException {
310
311 try {
312 return TilesUtil.getDefinition(
313 name,
314 pageContext.getRequest(),
315 pageContext.getServletContext());
316
317 } catch (NoSuchDefinitionException ex) {
318 throw new JspException(
319 "Error : Can't get component definition for '"
320 + name
321 + "'. Check if this name exist in component definitions.",ex);
322 } catch (FactoryNotFoundException ex) {
323 throw new JspException(ex);
324
325 } catch (DefinitionsFactoryException ex) {
326 if (debug)
327 ex.printStackTrace();
328
329 saveException(pageContext, ex);
330 throw new JspException(ex);
331 }
332 }
333
334 }