Return-Path: Delivered-To: apmail-commons-dev-archive@www.apache.org Received: (qmail 30475 invoked from network); 1 Feb 2008 15:43:10 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.2) by minotaur.apache.org with SMTP; 1 Feb 2008 15:43:10 -0000 Received: (qmail 530 invoked by uid 500); 1 Feb 2008 15:42:10 -0000 Delivered-To: apmail-commons-dev-archive@commons.apache.org Received: (qmail 447 invoked by uid 500); 1 Feb 2008 15:42:10 -0000 Mailing-List: contact dev-help@commons.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: "Jakarta Commons Developers List" Delivered-To: mailing list dev@commons.apache.org Received: (qmail 438 invoked by uid 99); 1 Feb 2008 15:42:10 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 01 Feb 2008 07:42:10 -0800 X-ASF-Spam-Status: No, hits=-0.0 required=10.0 tests=SPF_PASS X-Spam-Check-By: apache.org Received-SPF: pass (athena.apache.org: domain of niall.pemberton@gmail.com designates 209.85.146.178 as permitted sender) Received: from [209.85.146.178] (HELO wa-out-1112.google.com) (209.85.146.178) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 01 Feb 2008 15:41:42 +0000 Received: by wa-out-1112.google.com with SMTP id k34so618180wah.10 for ; Fri, 01 Feb 2008 07:41:50 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:received:message-id:date:from:to:subject:in-reply-to:mime-version:content-type:content-transfer-encoding:content-disposition:references; bh=/qDBGg0kw/AItRihp8vBe6oeFMvkOTskLGDpd70e2j0=; b=VMhoZAFSx+YKKL/XippjitX+kQAzrWLCvwuT1rjWdAt8oh5ML8GLSuEyzN/53w/ubOtxMpem/hOMgqmEOJjU1OHP7+U6byHCyc2mn7wvDFOQC/0AdjKT7K+Ru178N8QU/t1AXt9mguz0yEWheKKubKiQ7XmYhjoaOpob9rbSGrc= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=message-id:date:from:to:subject:in-reply-to:mime-version:content-type:content-transfer-encoding:content-disposition:references; b=WTQ6Vy54O+mdlJqlFSvENqOzeB7MuKFqI2hIUS9mtFQEVBNPZSIb35O5Ob7gtFUJmnxtuLI6mmBc4lhFdPt9c72sRovk97xe/hFdf8t9Spmn28Tif+dnmV9UeLrfw1m6fcPh87xXYUwFN/w2IGg8YDi2LFn+9YziI7D3YPKuCUU= Received: by 10.114.53.1 with SMTP id b1mr4119437waa.134.1201880509798; Fri, 01 Feb 2008 07:41:49 -0800 (PST) Received: by 10.114.155.12 with HTTP; Fri, 1 Feb 2008 07:41:49 -0800 (PST) Message-ID: <55afdc850802010741qbb62373r86b0281a8ac06d8a@mail.gmail.com> Date: Fri, 1 Feb 2008 15:41:49 +0000 From: "Niall Pemberton" To: "Jakarta Commons Developers List" Subject: Re: Hi alll and a suggestion In-Reply-To: <47A33921.8080701@gmail.com> MIME-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit Content-Disposition: inline References: <47A33921.8080701@gmail.com> X-Virus-Checked: Checked by ClamAV on apache.org On Feb 1, 2008 3:22 PM, Rodrigo di Lorenzo Lopes 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; > +/** > + *

Interface to know when a property must be overwrite.

> + *

See mergeProperties {@link BeanUtils}.

> + * @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 @@ > > > /** > - *

Copy property values from the origin bean to the destination bean > - * for all cases where the property names are the same. For each > + *

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.

> * > - *

This method differs from populate(), 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.

> + *

This method differs from copyProperties(), which > + * always overwrite destination bean with origin bean values.

> * > - *

If you know that no type conversions are required, the > - * copyProperties() method in {@link PropertyUtils} will > - * execute faster than this method.

> - * > *

FIXME - Indexed and mapped properties that do not > * have getter and setter methods for the underlying array or Map are not > * copied by this method.

> * > * @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 @@ > > } > > + /** > + *

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.

> + * > + *

If the origin "bean" is actually a Map, it is assumed > + * to contain String-valued simple property names as the keys, pointing at > + * the corresponding property values that will be converted (if necessary) > + * and set in the destination bean. Note 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.

> + * > + *

This method differs from populate(), 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.

> + * > + *

If you know that no type conversions are required, the > + * copyProperties() method in {@link PropertyUtils} will > + * execute faster than this method.

> + * > + *

FIXME - Indexed and mapped properties that do not > + * have getter and setter methods for the underlying array or Map are not > + * copied by this method.

> + * > + * @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 dest or > + * orig 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; > + }}); > + } > + > + > /** > *

Copy the specified property value to the specified destination bean, > * performing any type conversion that is required. If the specified > > --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org For additional commands, e-mail: dev-help@commons.apache.org