Home » displaytag-1.1.1-src » org » displaytag » decorator » [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.decorator;
   13   
   14   import java.lang.reflect.InvocationTargetException;
   15   import java.util.HashMap;
   16   import java.util.Map;
   17   
   18   import javax.servlet.jsp.PageContext;
   19   
   20   import org.apache.commons.beanutils.PropertyUtils;
   21   import org.apache.commons.lang.BooleanUtils;
   22   import org.displaytag.model.TableModel;
   23   
   24   
   25   /**
   26    * <p>
   27    * This class provides some basic functionality for all objects which serve as decorators for the objects in the List
   28    * being displayed.
   29    * <p>
   30    * <p>
   31    * Decorator should never be subclassed directly. Use TableDecorator instead
   32    * </p>
   33    * @author mraible
   34    * @author Fabrizio Giustina
   35    * @version $Revision: 1084 $ ($Author: fgiust $)
   36    */
   37   abstract class Decorator
   38   {
   39   
   40       /**
   41        * Char used to separate class name and property in the cache key.
   42        */
   43       private static final char CLASS_PROPERTY_SEPARATOR = '#';
   44   
   45       /**
   46        * property info cache contains classname#propertyname Strings as keys and Booleans as values.
   47        */
   48       private static Map propertyMap = new HashMap();
   49   
   50       /**
   51        * page context.
   52        */
   53       private PageContext pageContext;
   54   
   55       /**
   56        * decorated object. Usually a List
   57        */
   58       private Object decoratedObject;
   59   
   60       /**
   61        * The table model.
   62        * @since 1.1
   63        */
   64       protected TableModel tableModel;
   65   
   66       /**
   67        * Initialize the TableTecorator instance.
   68        * @param pageContext PageContext
   69        * @param decorated decorated object (usually a list)
   70        * @deprecated use #init(PageContext, Object, TableModel)
   71        * @see #init(PageContext, Object, TableModel)
   72        */
   73       public void init(PageContext pageContext, Object decorated)
   74       {
   75           this.pageContext = pageContext;
   76           this.decoratedObject = decorated;
   77       }
   78   
   79       /**
   80        * Initialize the TableTecorator instance.
   81        * @param pageContext PageContext
   82        * @param decorated decorated object (usually a list)
   83        * @param tableModel table model
   84        */
   85       public void init(PageContext pageContext, Object decorated, TableModel tableModel)
   86       {
   87           // temporary used for backward (source) compatibility
   88           init(pageContext, decorated);
   89           this.tableModel = tableModel;
   90       }
   91   
   92       /**
   93        * returns the page context.
   94        * @return PageContext
   95        */
   96       public PageContext getPageContext()
   97       {
   98           return this.pageContext;
   99       }
  100   
  101       /**
  102        * returns the decorated object.
  103        * @return Object
  104        */
  105       public Object getDecoratedObject()
  106       {
  107           return this.decoratedObject;
  108       }
  109   
  110       /**
  111        * Called at the end of evaluation to clean up instance variable. A subclass of Decorator can override this method
  112        * but should always call super.finish() before return
  113        */
  114       public void finish()
  115       {
  116           this.pageContext = null;
  117           this.decoratedObject = null;
  118       }
  119   
  120       /**
  121        * Check if a getter exists for a given property. Uses cached info if property has already been requested. This
  122        * method only check for a simple property, if pPropertyName contains multiple tokens only the first part is
  123        * evaluated
  124        * @param propertyName name of the property to check
  125        * @return boolean true if the decorator has a getter for the given property
  126        */
  127       public boolean hasGetterFor(String propertyName)
  128       {
  129           String simpleProperty = propertyName;
  130   
  131           // get the simple (not nested) bean property
  132           int indexOfDot = simpleProperty.indexOf('.');
  133           if (indexOfDot > 0)
  134           {
  135               simpleProperty = simpleProperty.substring(0, indexOfDot);
  136           }
  137   
  138           Boolean cachedResult = (Boolean) propertyMap.get(getClass().getName()
  139               + CLASS_PROPERTY_SEPARATOR
  140               + simpleProperty);
  141   
  142           if (cachedResult != null)
  143           {
  144               return cachedResult.booleanValue();
  145           }
  146   
  147           // not already cached... check
  148           boolean hasGetter = searchGetterFor(propertyName);
  149   
  150           // save in cache
  151           propertyMap.put(getClass().getName() + CLASS_PROPERTY_SEPARATOR + simpleProperty, BooleanUtils
  152               .toBooleanObject(hasGetter));
  153   
  154           // and return
  155           return hasGetter;
  156   
  157       }
  158   
  159       /**
  160        * Looks for a getter for the given property using introspection.
  161        * @param propertyName name of the property to check
  162        * @return boolean true if the decorator has a getter for the given property
  163        */
  164       public boolean searchGetterFor(String propertyName)
  165       {
  166   
  167           Class type = null;
  168   
  169           try
  170           {
  171               // using getPropertyType instead of isReadable since isReadable doesn't support mapped properties.
  172               // Note that this method usually returns null if a property is not found and doesn't throw any exception
  173               // also for non existent properties
  174               type = PropertyUtils.getPropertyType(this, propertyName);
  175           }
  176           catch (IllegalAccessException e)
  177           {
  178               // ignore
  179           }
  180           catch (InvocationTargetException e)
  181           {
  182               // ignore
  183           }
  184           catch (NoSuchMethodException e)
  185           {
  186               // ignore
  187           }
  188   
  189           return type != null;
  190   
  191       }
  192   
  193   }

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