craigmcc 2002/12/15 17:31:29
Modified: beanutils/src/java/org/apache/commons/beanutils
BeanUtils.java PropertyUtils.java
Log:
Optimize the behavior of BeanUtils.copyProperties() and
PropertyUtils.copyProperties() to only get the origin property and
set the destination property if:
- Origin property is readable
- Destination property is writeable
In addition, copyProperty operations on DynaBeans will now run faster because
properties are accessed directly, rather than via getSimpleProperty() and
setSimpleProperty().
PR: Bugzilla #15004
Submitted by: Tim Chen <chengt at tvratings.com>
Revision Changes Path
1.31 +22 -23
jakarta-commons/beanutils/src/java/org/apache/commons/beanutils/BeanUtils.java
Index: BeanUtils.java
===================================================================
RCS file:
/home/cvs/jakarta-commons/beanutils/src/java/org/apache/commons/beanutils/BeanUtils.java,v
retrieving revision 1.30
retrieving revision 1.31
diff -u -r1.30 -r1.31
--- BeanUtils.java 16 Dec 2002 00:29:48 -0000 1.30
+++ BeanUtils.java 16 Dec 2002 01:31:29 -0000 1.31
@@ -234,39 +234,38 @@
((DynaBean) orig).getDynaClass().getDynaProperties();
for (int i = 0; i < origDescriptors.length; i++) {
String name = origDescriptors[i].getName();
- Object value = ((DynaBean) orig).get(name);
- copyProperty(dest, name, value);
+ if (PropertyUtils.isWriteable(dest, name)) {
+ Object value = ((DynaBean) orig).get(name);
+ copyProperty(dest, name, value);
+ }
}
} else if (orig instanceof Map) {
Iterator names = ((Map) orig).keySet().iterator();
while (names.hasNext()) {
String name = (String) names.next();
- Object value = ((Map) orig).get(name);
- copyProperty(dest, name, value);
+ if (PropertyUtils.isWriteable(dest, name)) {
+ Object value = ((Map) orig).get(name);
+ copyProperty(dest, name, value);
+ }
}
- } else /* if (not a DynaBean or a Map) */ {
+ } else /* if (orig is a standard JavaBean) */ {
PropertyDescriptor origDescriptors[] =
PropertyUtils.getPropertyDescriptors(orig);
for (int i = 0; i < origDescriptors.length; i++) {
- if (origDescriptors[i].getReadMethod() == null) {
- if (log.isTraceEnabled()) {
- log.trace("-->No getter on JavaBean for " +
- origDescriptors[i].getName() + ", skipping");
- }
- continue;
- }
String name = origDescriptors[i].getName();
if ("class".equals(name)) {
continue; // No point in trying to set an object's class
}
- Object value = null;
- try {
- value = PropertyUtils.getSimpleProperty(orig, name);
- } catch (NoSuchMethodException e) {
- log.error("-->Should not have happened", e);
- value = null; // Can not happen
+ if (PropertyUtils.isReadable(orig, name) &&
+ PropertyUtils.isWriteable(dest, name)) {
+ try {
+ Object value =
+ PropertyUtils.getSimpleProperty(orig, name);
+ copyProperty(dest, name, value);
+ } catch (NoSuchMethodException e) {
+ ; // Should not happen
+ }
}
- copyProperty(dest, name, value);
}
}
1.37 +143 -30
jakarta-commons/beanutils/src/java/org/apache/commons/beanutils/PropertyUtils.java
Index: PropertyUtils.java
===================================================================
RCS file:
/home/cvs/jakarta-commons/beanutils/src/java/org/apache/commons/beanutils/PropertyUtils.java,v
retrieving revision 1.36
retrieving revision 1.37
diff -u -r1.36 -r1.37
--- PropertyUtils.java 16 Dec 2002 00:21:02 -0000 1.36
+++ PropertyUtils.java 16 Dec 2002 01:31:29 -0000 1.37
@@ -274,44 +274,51 @@
((DynaBean) orig).getDynaClass().getDynaProperties();
for (int i = 0; i < origDescriptors.length; i++) {
String name = origDescriptors[i].getName();
- Object value = getSimpleProperty(orig, name);
- try {
- setSimpleProperty(dest, name, value);
- } catch (NoSuchMethodException e) {
- ; // Skip non-matching property
+ if (dest instanceof DynaBean) {
+ if (isWriteable(dest, name)) {
+ Object value = ((DynaBean) orig).get(name);
+ ((DynaBean) dest).set(name, value);
+ }
+ } else {
+ if (isWriteable(dest, name)) {
+ Object value = ((DynaBean) orig).get(name);
+ PropertyUtils.setSimpleProperty(dest, name, value);
+ }
}
}
} else if (orig instanceof Map) {
Iterator names = ((Map) orig).keySet().iterator();
while (names.hasNext()) {
String name = (String) names.next();
- Object value = ((Map) orig).get(name);
- try {
- setSimpleProperty(dest, name, value);
- } catch (NoSuchMethodException e) {
- ; // Skip non-matching property
+ if (dest instanceof DynaBean) {
+ if (isWriteable(dest, name)) {
+ Object value = ((Map) orig).get(name);
+ ((DynaBean) dest).set(name, value);
+ }
+ } else {
+ if (isWriteable(dest, name)) {
+ Object value = ((Map) orig).get(name);
+ PropertyUtils.setSimpleProperty(dest, name, value);
+ }
}
}
- } else /* orig is a standard JavaBean */ {
+ } else /* if (orig is a standard JavaBean) */ {
PropertyDescriptor origDescriptors[] =
getPropertyDescriptors(orig);
for (int i = 0; i < origDescriptors.length; i++) {
- Method readMethod = origDescriptors[i].getReadMethod();
- if ((readMethod == null) &&
- (origDescriptors[i] instanceof IndexedPropertyDescriptor)) {
- readMethod =
- ((IndexedPropertyDescriptor) origDescriptors[i]).
- getIndexedReadMethod();
- }
- if (readMethod == null) {
- continue; // This is a write-only property
- }
String name = origDescriptors[i].getName();
- Object value = getSimpleProperty(orig, name);
- try {
- setSimpleProperty(dest, name, value);
- } catch (NoSuchMethodException e) {
- ; // Skip non-matching property
+ if (isReadable(orig, name)) {
+ if (dest instanceof DynaBean) {
+ if (isWriteable(dest, name)) {
+ Object value = getSimpleProperty(orig, name);
+ ((DynaBean) dest).set(name, value);
+ }
+ } else {
+ if (isWriteable(dest, name)) {
+ Object value = getSimpleProperty(orig, name);
+ setSimpleProperty(dest, name, value);
+ }
+ }
}
}
}
@@ -1192,6 +1199,112 @@
public static Method getWriteMethod(PropertyDescriptor descriptor) {
return (MethodUtils.getAccessibleMethod(descriptor.getWriteMethod()));
+
+ }
+
+
+ /**
+ * <p>Return <code>true</code> if the specified property name identifies
+ * a readable property on the specified bean; otherwise, return
+ * <code>false</code>.
+ *
+ * @param bean Bean to be examined (may be a {@link DynaBean}
+ * @param name Property name to be evaluated
+ *
+ * @exception IllegalArgumentException if <code>bean</code>
+ * or <code>name</code> is <code>null</code>
+ *
+ * @since BeanUtils 1.6
+ */
+ public static boolean isReadable(Object bean, String name) {
+
+ // Validate method parameters
+ if (bean == null) {
+ throw new IllegalArgumentException("No bean specified");
+ }
+ if (name == null) {
+ throw new IllegalArgumentException("No name specified");
+ }
+
+ // Return the requested result
+ if (bean instanceof DynaBean) {
+ // All DynaBean properties are readable
+ return (((DynaBean) bean).getDynaClass().getDynaProperty(name) != null);
+ } else {
+ try {
+ PropertyDescriptor desc =
+ getPropertyDescriptor(bean, name);
+ if (desc != null) {
+ Method readMethod = desc.getReadMethod();
+ if ((readMethod == null) &&
+ (desc instanceof IndexedPropertyDescriptor)) {
+ readMethod = ((IndexedPropertyDescriptor)
desc).getIndexedReadMethod();
+ }
+ return (readMethod != null);
+ } else {
+ return (false);
+ }
+ } catch (IllegalAccessException e) {
+ return (false);
+ } catch (InvocationTargetException e) {
+ return (false);
+ } catch (NoSuchMethodException e) {
+ return (false);
+ }
+ }
+
+ }
+
+
+ /**
+ * <p>Return <code>true</code> if the specified property name identifies
+ * a writeable property on the specified bean; otherwise, return
+ * <code>false</code>.
+ *
+ * @param bean Bean to be examined (may be a {@link DynaBean}
+ * @param name Property name to be evaluated
+ *
+ * @exception IllegalPointerException if <code>bean</code>
+ * or <code>name</code> is <code>null</code>
+ *
+ * @since BeanUtils 1.6
+ */
+ public static boolean isWriteable(Object bean, String name) {
+
+ // Validate method parameters
+ if (bean == null) {
+ throw new IllegalArgumentException("No bean specified");
+ }
+ if (name == null) {
+ throw new IllegalArgumentException("No name specified");
+ }
+
+ // Return the requested result
+ if (bean instanceof DynaBean) {
+ // All DynaBean properties are writeable
+ return (((DynaBean) bean).getDynaClass().getDynaProperty(name) != null);
+ } else {
+ try {
+ PropertyDescriptor desc =
+ getPropertyDescriptor(bean, name);
+ if (desc != null) {
+ Method writeMethod = desc.getWriteMethod();
+ if ((writeMethod == null) &&
+ (desc instanceof IndexedPropertyDescriptor)) {
+ writeMethod = ((IndexedPropertyDescriptor)
desc).getIndexedWriteMethod();
+ }
+ return (writeMethod != null);
+ } else {
+ return (false);
+ }
+ } catch (IllegalAccessException e) {
+ return (false);
+ } catch (InvocationTargetException e) {
+ return (false);
+ } catch (NoSuchMethodException e) {
+ return (false);
+ }
+ }
}
--
To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>