View Javadoc

1   /*
2    * $Id: TagUtils.java 421151 2006-07-12 06:07:14Z wsmoak $
3    *
4    * Copyright 1999-2004 The Apache Software Foundation.
5    *
6    * Licensed under the Apache License, Version 2.0 (the "License");
7    * you may not use this file except in compliance with the License.
8    * You may obtain a copy of the License at
9    *
10   *      http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
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             //throw new JspException(messages.getMessage("lookup.scope", scope));
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         // Default value doesn't matter because we have already check it
132         int scope = getScope(scopeName, PageContext.PAGE_SCOPE);
133 
134         //return pageContext.getAttribute( beanName, scope );
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         // Search in pageContext scopes
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; // value can be null
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) { // factory not found.
323             throw new JspException(ex);
324 
325         } catch (DefinitionsFactoryException ex) {
326             if (debug)
327                 ex.printStackTrace();
328             // Save exception to be able to show it later
329             saveException(pageContext, ex);
330             throw new JspException(ex);
331         }
332     }
333 
334 }