Home » displaytag-1.1.1-src » org » displaytag » util » [javadoc | source]

    1   /**
    2    * Licensed under the Artistic License; you may not use this file
    3    * except in compliance with the License.
    4    * You may obtain a copy of the License at
    5    *
    6    *      http://displaytag.sourceforge.net/license.html
    7    *
    8    * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
    9    * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
   10    * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
   11    */
   12   package org.displaytag.util;
   13   
   14   import java.lang.reflect.InvocationTargetException;
   15   import java.util.List;
   16   import java.util.Map;
   17   
   18   import javax.servlet.jsp.PageContext;
   19   
   20   import org.apache.commons.beanutils.NestedNullException;
   21   import org.apache.commons.beanutils.PropertyUtils;
   22   import org.apache.commons.lang.StringUtils;
   23   import org.apache.commons.lang.Validate;
   24   import org.apache.commons.logging.Log;
   25   import org.apache.commons.logging.LogFactory;
   26   import org.displaytag.exception.ObjectLookupException;
   27   
   28   
   29   /**
   30    * Utility class with methods for object and properties retrieving.
   31    * @author Fabrizio Giustina
   32    * @version $Id: LookupUtil.java 1081 2006-04-03 20:26:34Z fgiust $
   33    */
   34   public final class LookupUtil
   35   {
   36   
   37       /**
   38        * logger.
   39        */
   40       private static Log log = LogFactory.getLog(LookupUtil.class);
   41   
   42       /**
   43        * don't instantiate a LookupUtil.
   44        */
   45       private LookupUtil()
   46       {
   47           // unused
   48       }
   49   
   50       /**
   51        * Read an object from the pagecontext with the specified scope and eventually lookup a property in it.
   52        * @param pageContext PageContext
   53        * @param beanAndPropertyName String expression with bean name and attributes
   54        * @param scope One of the following values:
   55        * <ul>
   56        * <li>PageContext.PAGE_SCOPE</li>
   57        * <li>PageContext.REQUEST_SCOPE</li>
   58        * <li>PageContext.SESSION_SCOPE</li>
   59        * <li>PageContext.APPLICATION_SCOPE</li>
   60        * </ul>
   61        * @return Object
   62        * @throws ObjectLookupException for errors while retrieving a property in the bean
   63        */
   64       public static Object getBeanValue(PageContext pageContext, String beanAndPropertyName, int scope)
   65           throws ObjectLookupException
   66       {
   67   
   68           if (beanAndPropertyName.indexOf('.') != -1)
   69           {
   70               // complex: property from a bean
   71               String objectName = StringUtils.substringBefore(beanAndPropertyName, ".");
   72               String beanProperty = StringUtils.substringAfter(beanAndPropertyName, ".");
   73               Object beanObject;
   74   
   75               if (log.isDebugEnabled())
   76               {
   77                   log.debug("getBeanValue - bean: {" + objectName + "}, property: {" + beanProperty + "}");
   78               }
   79   
   80               // get the bean
   81               beanObject = pageContext.getAttribute(objectName, scope);
   82   
   83               // if null return
   84               if (beanObject == null)
   85               {
   86                   return null;
   87               }
   88   
   89               // go get the property
   90               return getBeanProperty(beanObject, beanProperty);
   91   
   92           }
   93   
   94           // simple, only the javabean
   95           if (log.isDebugEnabled())
   96           {
   97               log.debug("getBeanValue - bean: {" + beanAndPropertyName + "}");
   98           }
   99   
  100           return pageContext.getAttribute(beanAndPropertyName, scope);
  101       }
  102   
  103       /**
  104        * <p>
  105        * Returns the value of a property in the given bean.
  106        * </p>
  107        * <p>
  108        * Handle <code>NestedNullException</code> returning nulls and other exceptions returning
  109        * <code>ObjectLookupException</code>.
  110        * </p>
  111        * @param bean javabean
  112        * @param name name of the property to read from the javabean
  113        * @return Object
  114        * @throws ObjectLookupException for errors while retrieving a property in the bean
  115        */
  116       public static Object getBeanProperty(Object bean, String name) throws ObjectLookupException
  117       {
  118   
  119           Validate.notNull(bean, "No bean specified");
  120           Validate.notNull(name, "No name specified");
  121   
  122           if (log.isDebugEnabled())
  123           {
  124               log.debug("getProperty [" + name + "] on bean " + bean);
  125           }
  126   
  127           try
  128           {
  129               return getProperty(bean, name);
  130           }
  131           catch (IllegalAccessException e)
  132           {
  133               throw new ObjectLookupException(LookupUtil.class, bean, name, e);
  134           }
  135           catch (InvocationTargetException e)
  136           {
  137               throw new ObjectLookupException(LookupUtil.class, bean, name, e);
  138           }
  139           catch (NoSuchMethodException e)
  140           {
  141               throw new ObjectLookupException(LookupUtil.class, bean, name, e);
  142           }
  143           catch (NestedNullException nne)
  144           {
  145               // don't throw exceptions for nulls
  146               return null;
  147           }
  148           catch (IllegalArgumentException e)
  149           {
  150               // don't throw exceptions for nulls; the bean and name have already been checked; this is being thrown when
  151               // the bean property value is itself null.
  152               log
  153                   .debug(
  154                       "Caught IllegalArgumentException from beanutils while looking up " + name + " in bean " + bean,
  155                       e);
  156               return null;
  157           }
  158       }
  159   
  160       /**
  161        * Return the value of the (possibly nested) property of the specified name, for the specified bean, with no type
  162        * conversions.
  163        * @param bean Bean whose property is to be extracted
  164        * @param name Possibly nested name of the property to be extracted
  165        * @return Object
  166        * @throws NoSuchMethodException
  167        * @throws InvocationTargetException
  168        * @throws IllegalAccessException
  169        * @throws BeanPropertyLookupException in caso di errori nella lettura di propriet? del bean
  170        */
  171       public static Object getProperty(Object bean, String name) throws IllegalAccessException,
  172           InvocationTargetException, NoSuchMethodException
  173       {
  174           if (log.isDebugEnabled())
  175           {
  176               log.debug("getProperty [" + name + "] on bean " + bean);
  177           }
  178   
  179           Validate.notNull(bean, "No bean specified");
  180           Validate.notNull(name, "No name specified");
  181   
  182           Object evalBean = bean;
  183           String evalName = name;
  184   
  185           if (evalBean == null)
  186           {
  187               throw new IllegalArgumentException("No bean specified");
  188           }
  189           if (evalName == null)
  190           {
  191               throw new IllegalArgumentException("No name specified");
  192           }
  193   
  194           int indexOfINDEXEDDELIM = -1;
  195           int indexOfMAPPEDDELIM = -1;
  196           int indexOfMAPPEDDELIM2 = -1;
  197           int indexOfNESTEDDELIM = -1;
  198           while (true)
  199           {
  200   
  201               indexOfNESTEDDELIM = evalName.indexOf(PropertyUtils.NESTED_DELIM);
  202               indexOfMAPPEDDELIM = evalName.indexOf(PropertyUtils.MAPPED_DELIM);
  203               indexOfMAPPEDDELIM2 = evalName.indexOf(PropertyUtils.MAPPED_DELIM2);
  204               if (indexOfMAPPEDDELIM2 >= 0
  205                   && indexOfMAPPEDDELIM >= 0
  206                   && (indexOfNESTEDDELIM < 0 || indexOfNESTEDDELIM > indexOfMAPPEDDELIM))
  207               {
  208                   indexOfNESTEDDELIM = evalName.indexOf(PropertyUtils.NESTED_DELIM, indexOfMAPPEDDELIM2);
  209               }
  210               else
  211               {
  212                   indexOfNESTEDDELIM = evalName.indexOf(PropertyUtils.NESTED_DELIM);
  213               }
  214               if (indexOfNESTEDDELIM < 0)
  215               {
  216                   break;
  217               }
  218               String next = evalName.substring(0, indexOfNESTEDDELIM);
  219               indexOfINDEXEDDELIM = next.indexOf(PropertyUtils.INDEXED_DELIM);
  220               indexOfMAPPEDDELIM = next.indexOf(PropertyUtils.MAPPED_DELIM);
  221               if (evalBean instanceof Map)
  222               {
  223                   evalBean = ((Map) evalBean).get(next);
  224               }
  225               else if (indexOfMAPPEDDELIM >= 0)
  226               {
  227   
  228                   evalBean = PropertyUtils.getMappedProperty(evalBean, next);
  229   
  230               }
  231               else if (indexOfINDEXEDDELIM >= 0)
  232               {
  233                   evalBean = getIndexedProperty(evalBean, next);
  234               }
  235               else
  236               {
  237                   evalBean = PropertyUtils.getSimpleProperty(evalBean, next);
  238               }
  239   
  240               if (evalBean == null)
  241               {
  242                   log.debug("Null property value for '" + evalName.substring(0, indexOfNESTEDDELIM) + "'");
  243                   return null;
  244               }
  245               evalName = evalName.substring(indexOfNESTEDDELIM + 1);
  246   
  247           }
  248   
  249           indexOfINDEXEDDELIM = evalName.indexOf(PropertyUtils.INDEXED_DELIM);
  250           indexOfMAPPEDDELIM = evalName.indexOf(PropertyUtils.MAPPED_DELIM);
  251   
  252           if (evalBean == null)
  253           {
  254               log.debug("Null property value for '" + evalName.substring(0, indexOfNESTEDDELIM) + "'");
  255               return null;
  256           }
  257           else if (evalBean instanceof Map)
  258           {
  259               evalBean = ((Map) evalBean).get(evalName);
  260           }
  261           else if (indexOfMAPPEDDELIM >= 0)
  262           {
  263               evalBean = PropertyUtils.getMappedProperty(evalBean, evalName);
  264           }
  265           else if (indexOfINDEXEDDELIM >= 0)
  266           {
  267               evalBean = getIndexedProperty(evalBean, evalName);
  268           }
  269           else
  270           {
  271               evalBean = PropertyUtils.getSimpleProperty(evalBean, evalName);
  272           }
  273   
  274           return evalBean;
  275   
  276       }
  277   
  278       /**
  279        * Return the value of the specified indexed property of the specified bean, with no type conversions. The
  280        * zero-relative index of the required value must be included (in square brackets) as a suffix to the property name,
  281        * or <code>IllegalArgumentException</code> will be thrown. In addition to supporting the JavaBeans specification,
  282        * this method has been extended to support <code>List</code> objects as well.
  283        * @param bean Bean whose property is to be extracted
  284        * @param name <code>propertyname[index]</code> of the property value to be extracted
  285        * @return Object
  286        * @exception IllegalAccessException if the caller does not have access to the property accessor method
  287        * @exception InvocationTargetException if the property accessor method throws an exception
  288        * @exception NoSuchMethodException if an accessor method for this propety cannot be found
  289        */
  290       public static Object getIndexedProperty(Object bean, String name) throws IllegalAccessException,
  291           InvocationTargetException, NoSuchMethodException
  292       {
  293   
  294           Validate.notNull(bean, "No bean specified");
  295           Validate.notNull(name, "No name specified");
  296   
  297           String evalName = name;
  298   
  299           // Identify the index of the requested individual property
  300           int delim = evalName.indexOf(PropertyUtils.INDEXED_DELIM);
  301           int delim2 = evalName.indexOf(PropertyUtils.INDEXED_DELIM2);
  302           if ((delim < 0) || (delim2 <= delim))
  303           {
  304               throw new IllegalArgumentException("Invalid indexed property '" + evalName + "'");
  305           }
  306           int index = -1;
  307           try
  308           {
  309               String subscript = evalName.substring(delim + 1, delim2);
  310               index = Integer.parseInt(subscript);
  311           }
  312           catch (NumberFormatException e)
  313           {
  314               throw new IllegalArgumentException("Invalid indexed property '" + evalName + "'");
  315           }
  316           evalName = evalName.substring(0, delim);
  317   
  318           if (log.isDebugEnabled())
  319           {
  320               log.debug("getIndexedProperty property name={" + evalName + "} with index " + index);
  321   
  322           }
  323   
  324           // addd support for lists and arrays
  325           if (StringUtils.isEmpty(evalName))
  326           {
  327               if (bean instanceof List)
  328               {
  329                   return ((List) bean).get(index);
  330               }
  331               else if (bean.getClass().isArray())
  332               {
  333                   return ((Object[]) bean)[index];
  334               }
  335           }
  336           // Request the specified indexed property value
  337           return (PropertyUtils.getIndexedProperty(bean, evalName, index));
  338   
  339       }
  340   
  341   }

Home » displaytag-1.1.1-src » org » displaytag » util » [javadoc | source]