View Javadoc

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