commons-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Rodrigo di Lorenzo Lopes <rdllo...@gmail.com>
Subject Hi alll and a suggestion
Date Fri, 01 Feb 2008 15:22:10 GMT
Hi all!

I'm Rodrigo di Lorenzo Lopes and I'd like to do some contributions to 
commons apache project (despite my poor English Knowledge).

So, I have one problem with BeanUtils.copyProperties:  From a source, I 
have a bean partialy populated. From another source, I have the same 
bean with others informations. How can I merge these beans?
My solutions is:  verify an mustOverwrite method before each 
copyProperty call.  See the patch in attachment.

;)

Best Regards,

Rodrigo

------------------------------------------------------------------------

Index: C:/desenvolvimento/workspace_3.3/Commons-BeanUtils/src/test/org/apache/commons/beanutils/BeanUtilsTestCase.java
===================================================================
--- C:/desenvolvimento/workspace_3.3/Commons-BeanUtils/src/test/org/apache/commons/beanutils/BeanUtilsTestCase.java
(revision 617468)
+++ C:/desenvolvimento/workspace_3.3/Commons-BeanUtils/src/test/org/apache/commons/beanutils/BeanUtilsTestCase.java
(working copy)
@@ -20,6 +20,7 @@
 
 import java.lang.reflect.InvocationTargetException;
 import java.util.Calendar;
+import java.util.Date;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.Locale;
@@ -1637,4 +1638,28 @@
         }
         return false;
     }
+    
+    public void testMergeProperty() throws Exception {
+    	TestBean testBean = new TestBean();
+    	testBean.setStringProperty("string");
+    	HashMap hashmapTest = new HashMap();
+    	testBean.setMapProperty(null);
+    	Date date = new Date();    	
+    	testBean.setDateProperty(date);
+    	TestBean testBean2 = new TestBean();
+    	testBean2.setStringProperty("string2");
+    	testBean2.setMapProperty(hashmapTest);
+    	testBean2.setDateProperty(null);
+    	BeanUtilsBean.getInstance().mergeProperties(testBean, testBean2, new Overwritable()
{
+
+			public boolean mustOverwrite(String propertyName, Object originValue) {
+				if (originValue != null) return true; 
+				return false;
+			}
+    		
+    	});
+    	assertEquals(testBean.getStringProperty(), "string2");
+    	assertEquals(testBean.getMapProperty(), hashmapTest);
+    	assertEquals(testBean.getDateProperty(), date);
+	}
 }
Index: C:/desenvolvimento/workspace_3.3/Commons-BeanUtils/src/java/org/apache/commons/beanutils/Overwritable.java
===================================================================
--- C:/desenvolvimento/workspace_3.3/Commons-BeanUtils/src/java/org/apache/commons/beanutils/Overwritable.java
(revision 0)
+++ C:/desenvolvimento/workspace_3.3/Commons-BeanUtils/src/java/org/apache/commons/beanutils/Overwritable.java
(revision 0)
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.beanutils;
+/**
+ * <p>Interface to know when a property must be overwrite.</p>
+ * <p>See mergeProperties {@link BeanUtils}.</p>
+ * @author Rodrigo di Lorenzo Lopes
+ * @version 1.0
+ * @since 3.3
+ *
+ */
+public interface Overwritable {
+ 
+	/**
+	 * Determine if property must be overwrite.
+	 * @param propertyName Property name
+	 * @param value Value from origin bean 
+	 * @return true, if method must be overwrite.
+	 */
+	public boolean mustOverwrite(String propertyName, Object originValue);
+
+}
Index: C:/desenvolvimento/workspace_3.3/Commons-BeanUtils/src/java/org/apache/commons/beanutils/BeanUtilsBean.java
===================================================================
--- C:/desenvolvimento/workspace_3.3/Commons-BeanUtils/src/java/org/apache/commons/beanutils/BeanUtilsBean.java
(revision 617468)
+++ C:/desenvolvimento/workspace_3.3/Commons-BeanUtils/src/java/org/apache/commons/beanutils/BeanUtilsBean.java
(working copy)
@@ -190,8 +190,9 @@
 
 
     /**
-     * <p>Copy property values from the origin bean to the destination bean
-     * for all cases where the property names are the same.  For each
+     * <p>Merge property values from the origin bean to the destination bean
+     * for all cases where the property names are the same, and always where
+     * method mustOverwrite of overwritable return true.  For each
      * property, a conversion is attempted as necessary.  All combinations of
      * standard JavaBeans and DynaBeans as origin and destination are
      * supported.  Properties that exist in the origin bean, but do not exist
@@ -205,22 +206,17 @@
      * is intended to perform a "shallow copy" of the properties and so complex
      * properties (for example, nested ones) will not be copied.</p>
      *
-     * <p>This method differs from <code>populate()</code>, which
-     * was primarily designed for populating JavaBeans from the map of request
-     * parameters retrieved on an HTTP request, is that no scalar->indexed
-     * or indexed->scalar manipulations are performed.  If the origin property
-     * is indexed, the destination property must be also.</p>
+     * <p>This method differs from <code>copyProperties()</code>, which
+     * always overwrite destination bean with origin bean values. </p>
      *
-     * <p>If you know that no type conversions are required, the
-     * <code>copyProperties()</code> method in {@link PropertyUtils} will
-     * execute faster than this method.</p>
-     *
      * <p><strong>FIXME</strong> - Indexed and mapped properties that do
not
      * have getter and setter methods for the underlying array or Map are not
      * copied by this method.</p>
      *
      * @param dest Destination bean whose properties are modified
      * @param orig Origin bean whose properties are retrieved
+     * @param overwritable Overwritable whose determines when origin bean value must overwrite
+     * destination bean
      *
      * @exception IllegalAccessException if the caller does not have
      *  access to the property accessor method
@@ -231,7 +227,7 @@
      * @exception InvocationTargetException if the property accessor method
      *  throws an exception
      */
-    public void copyProperties(Object dest, Object orig)
+    public void mergeProperties(Object dest, Object orig, Overwritable overwritable)
         throws IllegalAccessException, InvocationTargetException {
 
         // Validate existence of the specified beans
@@ -258,6 +254,7 @@
                 if (getPropertyUtils().isReadable(orig, name) &&
                     getPropertyUtils().isWriteable(dest, name)) {
                     Object value = ((DynaBean) orig).get(name);
+                    if (overwritable.mustOverwrite(name, value))
                     copyProperty(dest, name, value);
                 }
             }
@@ -267,6 +264,7 @@
                 String name = (String) names.next();
                 if (getPropertyUtils().isWriteable(dest, name)) {
                     Object value = ((Map) orig).get(name);
+                    if (overwritable.mustOverwrite(name, value))
                     copyProperty(dest, name, value);
                 }
             }
@@ -283,9 +281,10 @@
                     try {
                         Object value =
                             getPropertyUtils().getSimpleProperty(orig, name);
+                        if (overwritable.mustOverwrite(name, value))
                         copyProperty(dest, name, value);
                     } catch (NoSuchMethodException e) {
-                        // Should not happen
+                        ; // Should not happen
                     }
                 }
             }
@@ -293,7 +292,56 @@
 
     }
 
+    /**
+     * <p>Copy property values from the origin bean to the destination bean
+     * for all cases where the property names are the same.  For each
+     * property, a conversion is attempted as necessary.  All combinations of
+     * standard JavaBeans and DynaBeans as origin and destination are
+     * supported.  Properties that exist in the origin bean, but do not exist
+     * in the destination bean (or are read-only in the destination bean) are
+     * silently ignored.</p>
+     *
+     * <p>If the origin "bean" is actually a <code>Map</code>, it is assumed
+     * to contain String-valued <strong>simple</strong> property names as the
keys, pointing at
+     * the corresponding property values that will be converted (if necessary)
+     * and set in the destination bean. <strong>Note</strong> that this method
+     * is intended to perform a "shallow copy" of the properties and so complex
+     * properties (for example, nested ones) will not be copied.</p>
+     *
+     * <p>This method differs from <code>populate()</code>, which
+     * was primarily designed for populating JavaBeans from the map of request
+     * parameters retrieved on an HTTP request, is that no scalar->indexed
+     * or indexed->scalar manipulations are performed.  If the origin property
+     * is indexed, the destination property must be also.</p>
+     *
+     * <p>If you know that no type conversions are required, the
+     * <code>copyProperties()</code> method in {@link PropertyUtils} will
+     * execute faster than this method.</p>
+     *
+     * <p><strong>FIXME</strong> - Indexed and mapped properties that do
not
+     * have getter and setter methods for the underlying array or Map are not
+     * copied by this method.</p>
+     *
+     * @param dest Destination bean whose properties are modified
+     * @param orig Origin bean whose properties are retrieved
+     *
+     * @exception IllegalAccessException if the caller does not have
+     *  access to the property accessor method
+     * @exception IllegalArgumentException if the <code>dest</code> or
+     *  <code>orig</code> argument is null
+     * @exception InvocationTargetException if the property accessor method
+     *  throws an exception
+     */
+    public void copyProperties(Object dest, Object orig)
+        throws IllegalAccessException, InvocationTargetException {
+    	mergeProperties(dest, orig, new Overwritable() {
 
+			public boolean mustOverwrite(String property, Object value) {
+				return true;
+			}});
+    }
+
+
     /**
      * <p>Copy the specified property value to the specified destination bean,
      * performing any type conversion that is required.  If the specified


Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message