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; } }
Decorator.diff
Description: Binary data