On Feb 1, 2008 3:22 PM, Rodrigo di Lorenzo Lopes <[EMAIL PROTECTED]> wrote:
> 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.

I don't have time at the moment to look at what you're proposing -
could you file a JIRA enhancement request with your patch attached
please - otherwise its likely to be forgotten / lost on the list.

http://commons.apache.org/beanutils/issue-tracking.html

thanks

Niall

> ;)
>
> 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 [EMAIL PROTECTED] 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 [EMAIL PROTECTED] 
> 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 [EMAIL PROTECTED] 
> 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
>
>

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to