Author: simonetripodi Date: Fri Jun 8 11:58:29 2012 New Revision: 1348032 URL: http://svn.apache.org/viewvc?rev=1348032&view=rev Log: [SANDBOX-405] Implement copyPropertiesTo(T target) on DefaultBeanAccessor - patch provided by Benedikt Ritter
Added: commons/sandbox/beanutils2/trunk/src/test/java/org/apache/commons/beanutils2/CopyPropertiesTestCase.java (with props) Modified: commons/sandbox/beanutils2/trunk/src/changes/changes.xml commons/sandbox/beanutils2/trunk/src/main/java/org/apache/commons/beanutils2/BeanAccessor.java commons/sandbox/beanutils2/trunk/src/main/java/org/apache/commons/beanutils2/DefaultBeanAccessor.java Modified: commons/sandbox/beanutils2/trunk/src/changes/changes.xml URL: http://svn.apache.org/viewvc/commons/sandbox/beanutils2/trunk/src/changes/changes.xml?rev=1348032&r1=1348031&r2=1348032&view=diff ============================================================================== --- commons/sandbox/beanutils2/trunk/src/changes/changes.xml (original) +++ commons/sandbox/beanutils2/trunk/src/changes/changes.xml Fri Jun 8 11:58:29 2012 @@ -23,6 +23,9 @@ </properties> <body> <release version="0.1" date="201?-??-??" description="First release."> + <action dev="simonetripodi" type="add" issue="SANDBOX-405" due-to="Benedikt Ritter"> + Implement copyPropertiesTo(T target) on DefaultBeanAccessor + </action> <action dev="simonetripodi" type="add" issue="SANDBOX-403" due-to="Benedikt Ritter"> Refactor Unit tests for better readability </action> Modified: commons/sandbox/beanutils2/trunk/src/main/java/org/apache/commons/beanutils2/BeanAccessor.java URL: http://svn.apache.org/viewvc/commons/sandbox/beanutils2/trunk/src/main/java/org/apache/commons/beanutils2/BeanAccessor.java?rev=1348032&r1=1348031&r2=1348032&view=diff ============================================================================== --- commons/sandbox/beanutils2/trunk/src/main/java/org/apache/commons/beanutils2/BeanAccessor.java (original) +++ commons/sandbox/beanutils2/trunk/src/main/java/org/apache/commons/beanutils2/BeanAccessor.java Fri Jun 8 11:58:29 2012 @@ -97,8 +97,32 @@ public interface BeanAccessor<B> throws IllegalAccessException, InstantiationException, IntrospectionException, InvocationTargetException, NoSuchMethodException; + /** + * <p>Copies property values from the bean wrapped by this BeanAccessor + * to target for all cases where the property names are the same. For each + * property, a conversion is attempted as necessary.</p> + * + * <p><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> + * + * <strong>TODO</strong> should we implement something like the following? + * <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 target the target to copy properties to from the wrapped bean + * @throws IllegalAccessException if the caller does not have access to any of the property accessor methods + * @throws IntrospectionException TODO + * @throws InvocationTargetException if any of the property accessor methods throws an exception + * @throws NoSuchMethodException if an accessor method for a property cannot be found + */ <T extends B> void copyPropertiesTo( T target ) - throws IllegalAccessException, InvocationTargetException, NoSuchMethodException; + throws IllegalAccessException, IntrospectionException, InvocationTargetException, NoSuchMethodException; // description Modified: commons/sandbox/beanutils2/trunk/src/main/java/org/apache/commons/beanutils2/DefaultBeanAccessor.java URL: http://svn.apache.org/viewvc/commons/sandbox/beanutils2/trunk/src/main/java/org/apache/commons/beanutils2/DefaultBeanAccessor.java?rev=1348032&r1=1348031&r2=1348032&view=diff ============================================================================== --- commons/sandbox/beanutils2/trunk/src/main/java/org/apache/commons/beanutils2/DefaultBeanAccessor.java (original) +++ commons/sandbox/beanutils2/trunk/src/main/java/org/apache/commons/beanutils2/DefaultBeanAccessor.java Fri Jun 8 11:58:29 2012 @@ -228,10 +228,10 @@ final class DefaultBeanAccessor<B> * {@inheritDoc} */ public <T extends B> void copyPropertiesTo( T target ) - throws IllegalAccessException, InvocationTargetException, NoSuchMethodException + throws IllegalAccessException, IntrospectionException, InvocationTargetException, NoSuchMethodException { - // TODO - + checkNotNull( target, "Can not copy properties to null!" ); + on( target ).populate( describe() ); } /** Added: commons/sandbox/beanutils2/trunk/src/test/java/org/apache/commons/beanutils2/CopyPropertiesTestCase.java URL: http://svn.apache.org/viewvc/commons/sandbox/beanutils2/trunk/src/test/java/org/apache/commons/beanutils2/CopyPropertiesTestCase.java?rev=1348032&view=auto ============================================================================== --- commons/sandbox/beanutils2/trunk/src/test/java/org/apache/commons/beanutils2/CopyPropertiesTestCase.java (added) +++ commons/sandbox/beanutils2/trunk/src/test/java/org/apache/commons/beanutils2/CopyPropertiesTestCase.java Fri Jun 8 11:58:29 2012 @@ -0,0 +1,172 @@ +package org.apache.commons.beanutils2; + +/* + * 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. + */ + +import static org.apache.commons.beanutils2.BeanUtils.on; +import static org.apache.commons.beanutils2.TestBeanUtils.*; +import static org.junit.Assert.assertEquals; + +import java.util.Map; + +import org.junit.*; + +public class CopyPropertiesTestCase +{ + + private TestBean source; + + private ExtendedTestBean target; + + @Before + public void setUp() + { + source = new TestBean(); + target = new ExtendedTestBean(); + } + + @After + public void tearDown() + { + source = null; + target = null; + } + + @Test( expected = NullPointerException.class ) + public void copyPropertiesToNull() + throws Exception + { + on( source ).copyPropertiesTo( null ); + } + + @Test + public void copyPropertiesToTargetWithChangedScalarProperties() + throws Exception + { + changeScalarProperties( target ); + on( source ).copyPropertiesTo( target ); + // we can not simply call assertEquals because of the nested properties in TestBean + assertReadWritePropertiesEquals( source, target ); + assertExtendedPropertiesUnchanged(); + } + + private void assertExtendedPropertiesUnchanged() + { + ExtendedTestBean expected = new ExtendedTestBean(); + assertEquals( expected.extendedBooleanProperty, target.extendedBooleanProperty ); + assertEquals( expected.extendedReadOnlyProperty, target.extendedReadOnlyProperty ); + assertEquals( expected.extendedStringProperty, target.extendedStringProperty ); + } + + @Test + public void copyPropertiesToTargetWithChangedArrayProperties() + throws Exception + { + changeArrayProperties( target ); + on( source ).copyPropertiesTo( target ); + assertReadWritePropertiesEquals( source, target ); + assertExtendedPropertiesUnchanged(); + } + + /** + * Makes sure that copy properties has the same effect as populate, if source and target are of the same type + */ + @Test + public void copyPropertiesToSameAsPopulate() + throws Exception + { + changeScalarProperties( source ); + changeArrayProperties( source ); + Map<String, Object> sourceProperties = on( source ).describe(); + + TestBean targetForCopyProperties = new TestBean(); + TestBean targetForPopulate = new TestBean(); + + on( source ).copyPropertiesTo( targetForCopyProperties ); + on( targetForPopulate ).populate( sourceProperties ); + + assertReadWritePropertiesEquals( source, targetForCopyProperties ); + assertReadWritePropertiesEquals( source, targetForPopulate ); + assertReadWritePropertiesEquals( targetForCopyProperties, targetForPopulate ); + } + + /** + * Makes sure, that coping properties does not change the source + */ + @Test + public void copyPropertiesToTargetNotChangingSource() + throws Exception + { + Map<String, Object> propertiesBefore = on( source ).describe(); + on( source ).copyPropertiesTo( target ); + Map<String, Object> propertiesAfter = on( source ).describe(); + + assertEquals( propertiesBefore, propertiesAfter ); + } + + /** + * Makes sure, that properties are copied shallow. In other words, that complex properties like nested beans will + * only be referenced from target and not copied. + */ + @Test + public void copyPropertiesToTargetIsShallow() throws Exception { + on( source ).copyPropertiesTo( target ); + + assertShallow(source, target); + } + + @SuppressWarnings( "unused" ) // unused methods invoked via introspection + private static class ExtendedTestBean + extends TestBean + { + + private static final long serialVersionUID = 4854743778089894313L; + + private boolean extendedBooleanProperty = true; + + private final String extendedReadOnlyProperty = "extended read only property"; + + private String extendedStringProperty = "extended string property"; + + public boolean getExtendedBooleanProperty() + { + return extendedBooleanProperty; + } + + public void setExtendedBooleanProperty( boolean booleanProperty ) + { + extendedBooleanProperty = booleanProperty; + } + + public String getExtendedReadOnlyProperty() + { + return extendedReadOnlyProperty; + } + + public String getExtendedStringProperty() + { + return extendedStringProperty; + } + + public void setExtendedStringProperty( String stringProperty ) + { + extendedStringProperty = stringProperty; + } + + } + +} Propchange: commons/sandbox/beanutils2/trunk/src/test/java/org/apache/commons/beanutils2/CopyPropertiesTestCase.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: commons/sandbox/beanutils2/trunk/src/test/java/org/apache/commons/beanutils2/CopyPropertiesTestCase.java ------------------------------------------------------------------------------ svn:keywords = Date Author Id Revision HeadURL Propchange: commons/sandbox/beanutils2/trunk/src/test/java/org/apache/commons/beanutils2/CopyPropertiesTestCase.java ------------------------------------------------------------------------------ svn:mime-type = text/plain