Author: fdesbois Date: 2010-05-12 22:16:51 +0200 (Wed, 12 May 2010) New Revision: 1861 Url: http://nuiton.org/repositories/revision/nuiton-utils/1861 Log: Evo #605 : add copyExcluding method in Binder Modified: trunk/src/main/java/org/nuiton/util/beans/Binder.java trunk/src/test/java/org/nuiton/util/beans/BinderTest.java Modified: trunk/src/main/java/org/nuiton/util/beans/Binder.java =================================================================== --- trunk/src/main/java/org/nuiton/util/beans/Binder.java 2010-05-11 14:42:58 UTC (rev 1860) +++ trunk/src/main/java/org/nuiton/util/beans/Binder.java 2010-05-12 20:16:51 UTC (rev 1861) @@ -33,9 +33,11 @@ import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.HashSet; +import java.util.List; import java.util.Map; import java.util.Set; import java.util.TreeMap; @@ -192,7 +194,8 @@ /** * Copy properties from a source bean to a destination one according to - * the model of the binder. + * the model of the binder. If {@code propertyNames} is defined, only + * those properties will be copied. * <p/> * <b>Note:</b> If {@code from} object is null, then {@code null} values * will be set to mapped properties into {@code dst} @@ -204,13 +207,53 @@ * binder) * @throws NullPointerException if target parameter is {@code null} */ - public void copy(I source, O target, String... propertyNames) + public void copy(I source, O target, String... propertyNames) { + copy(source, target, false, propertyNames); + } + + /** + * Copy properties from a source bean to a destination one according to + * the model of the binder excluding {@code propertyNames}. + * <p/> + * <b>Note:</b> If {@code from} object is null, then {@code null} values + * will be set to mapped properties into {@code dst}. + * + * @param source the bean to read + * @param target the bean to write + * @param propertyNames optional subset of properties to copy (if none is + * specifed, will use all the properties defined in + * binder) + * @throws NullPointerException if target parameter is {@code null} + */ + public void copyExcluding(I source, O target, String... propertyNames) { + copy(source, target, true, propertyNames); + } + + /** + * Copy properties from a source bean to a destination one according to + * the model of the binder. + * <p/> + * <b>Note:</b> If {@code from} object is null, then {@code null} values + * will be set to mapped properties into {@code dst}. + * + * @param source the bean to read + * @param target the bean to write + * @param excludeProperties true to exclude following {@code propertyNames} + * @param propertyNames optional subset of properties to copy (if none is + * specifed, will use all the properties defined in + * binder) + * @throws NullPointerException if target parameter is {@code null} + */ + protected void copy(I source, O target, boolean excludeProperties, + String... propertyNames) throws NullPointerException { if (target == null) { throw new NullPointerException("parameter 'target' can no be null"); } - propertyNames = getProperties(propertyNames); + propertyNames = excludeProperties ? + getAllPropertiesExclude(propertyNames) : + getProperties(propertyNames); for (String sourceProperty : propertyNames) { @@ -306,6 +349,24 @@ return propertyNames; } + /** + * Obtains all properties from binder's model except those {@code + * propertyNameExcludes}. Unknown properties will be ignored. + * + * @param propertyNameExcludes name of properties to exclude + * @return the array of property names without those in argument + */ + protected String[] getAllPropertiesExclude(String... propertyNameExcludes) { + List<String> excludes = Arrays.asList(propertyNameExcludes); + List<String> results = new ArrayList<String>(); + for (String propertyName : model.getSourceDescriptors()) { + if (!excludes.contains(propertyName)) { + results.add(propertyName); + } + } + return results.toArray(new String[results.size()]); + } + protected Object getCollectionValue(String sourceProperty, Object readValue) { CollectionStrategy strategy = model.getCollectionStrategy(sourceProperty); Modified: trunk/src/test/java/org/nuiton/util/beans/BinderTest.java =================================================================== --- trunk/src/test/java/org/nuiton/util/beans/BinderTest.java 2010-05-11 14:42:58 UTC (rev 1860) +++ trunk/src/test/java/org/nuiton/util/beans/BinderTest.java 2010-05-12 20:16:51 UTC (rev 1861) @@ -148,4 +148,41 @@ Assert.assertEquals(0,b.getE2()); } + + @Test + public void testCopyExcluding() throws Exception { + + a.setA(VALUE_A); + a.setB(VALUE_B); + a.setC(VALUE_C); + a.setE(VALUE_E); + + // #1 : Copy all properties defined by binderB instead of PROPERTY_A + binderB.copyExcluding(a, b, BeanA.PROPERTY_A); + Assert.assertNull(b.getA()); + // same result as copy + Assert.assertEquals(VALUE_B, b.getB()); + Assert.assertNull(b.getC()); + Assert.assertEquals(VALUE_C, b.getC2()); + Assert.assertEquals(VALUE_E, b.getE2()); + + // #2 : Copy all properties : same as binderB.copy(a, b); + binderB.copyExcluding(a, b); + // same result as copy + Assert.assertEquals(VALUE_A, b.getA()); + Assert.assertEquals(VALUE_B, b.getB()); + Assert.assertNull(b.getC()); + Assert.assertEquals(VALUE_C, b.getC2()); + Assert.assertEquals(VALUE_E, b.getE2()); + + // #3 : Copy all properties, excluding one is not considered from source + binderB.copyExcluding(a, b, BeanB.PROPERTY_C2); + // same result as copy + Assert.assertEquals(VALUE_A, b.getA()); + Assert.assertEquals(VALUE_B, b.getB()); + Assert.assertNull(b.getC()); + Assert.assertEquals(VALUE_C, b.getC2()); + Assert.assertEquals(VALUE_E, b.getE2()); + + } }