I am using displaytag with some complex beans and noticed that the
hasGetterFor() method in org.displaytag.decorator.Decorator is less than
perfect.  It checks for a complex property (using '.') but doesn't handle
indexed or mapped properties (using value[int] or 'value(key)').

Instead of using org.displaytag.util.LookupUtil, I decided to simply catch
an exception when trying to access the property with
org.apache.commons.beanutils.PropertyUtils.  If an exception is thrown,
the property isn't there, and false is returned.  Else, hasGetterFor
returns true.  The result is cached just like before, so I don't believe a
performance hit is an issue.

I didn't look at refactoring the code to take this into account. 
Decorator.hasGetterFor() may be superfluous if this approach is taken.

Patch is attached and also follows inline.

Chris Eldredge

Index: src/java/org/displaytag/decorator/Decorator.java
===================================================================
RCS file:
/cvsroot/displaytag/displaytag2/src/java/org/displaytag/decorator/Decorator.java,v
retrieving revision 1.10
diff -u -r1.10 Decorator.java
--- src/java/org/displaytag/decorator/Decorator.java    29 Feb 2004 10:00:46
-0000   1.10
+++ src/java/org/displaytag/decorator/Decorator.java    23 Mar 2004 20:41:56
-0000
@@ -1,6 +1,5 @@
 package org.displaytag.decorator;

-import java.beans.PropertyDescriptor;
 import java.util.HashMap;
 import java.util.Map;

@@ -78,27 +77,6 @@
     }

     /**
-     * Looks for a getter for the given property using introspection.
-     * @param propertyName name of the property to check
-     * @return boolean true if the decorator has a getter for the given
property
-     */
-    public boolean searchGetterFor(String propertyName)
-    {
-        PropertyDescriptor[] descriptors =
PropertyUtils.getPropertyDescriptors(getClass());
-
-        // iterate on property descriptors
-        for (int j = 0; j < descriptors.length; j++)
-        {
-            if (propertyName.equals(descriptors[j].getName()))
-            {
-                return true;
-            }
-        }
-
-        return false;
-    }
-
-    /**
      * Check if a getter exists for a given property. Uses cached info if
property has already been requested. This
      * method only check for a simple property, if pPropertyName contains
multiple tokens only the first part is
      * evaluated
@@ -107,30 +85,26 @@
      */
     public boolean hasGetterFor(String propertyName)
     {
-        String simpleProperty = propertyName;
-
-        // get the simple (not nested) bean property
-        if ((simpleProperty != null) && (simpleProperty.indexOf(".") > 0))
-        {
-            simpleProperty = simpleProperty.substring(0,
simpleProperty.indexOf("."));
-        }
-
-        Boolean cachedResult;
-
-        if ((cachedResult = (Boolean)
propertyMap.get(getClass().getName() + "#" + simpleProperty)) != null)
-        {
-            return cachedResult.booleanValue();
-        }
-
-        // not already cached... check
-        boolean hasGetter = searchGetterFor(simpleProperty);
-
-        // save in cache
-        propertyMap.put(getClass().getName() + "#" + simpleProperty, new
Boolean(hasGetter));
+               Boolean cachedResult;

-        // and return
-        return hasGetter;
+               if ((cachedResult = (Boolean) propertyMap.get(getClass().getName() +
"#" + propertyName)) != null)
+               {
+                       return cachedResult.booleanValue();
+               }
+
+               boolean hasGetter = true;
+
+               try {
+                       PropertyUtils.getProperty(this, propertyName);
+               } catch (Exception e) {
+                       hasGetter = false;
+               }
+
+               // save in cache
+               propertyMap.put(getClass().getName() + "#" + propertyName, new
Boolean(hasGetter));

+               // and return
+               return hasGetter;
     }

 }

Attachment: Decorator.diff
Description: Binary data

Reply via email to