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