// Copyright (c) 2003-present, Jodd Team (http://jodd.org) // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // // 1. Redistributions of source code must retain the above copyright notice, // this list of conditions and the following disclaimer. // // 2. Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE // POSSIBILITY OF SUCH DAMAGE. package jodd.bean; import jodd.bean.fixtures.FooBean; import jodd.bean.fixtures.FooBeanString; import jodd.util.Wildcard; import org.junit.Test; import java.util.HashMap; import java.util.Map; import java.util.Properties; import static org.hamcrest.CoreMatchers.is; import static org.junit.Assert.*; public class BeanCopyTest { @Test public void testCopy() { FooBean fb = createFooBean(); FooBean dest = new FooBean(); BeanCopy.beans(fb, dest).copy(); Integer v = BeanUtil.pojo.getProperty(dest, "fooInteger"); assertEquals(201, v.intValue()); v = BeanUtil.pojo.getProperty(dest, "fooint"); assertEquals(202, v.intValue()); Long vl = BeanUtil.pojo.getProperty(dest, "fooLong"); assertEquals(203, vl.longValue()); vl = BeanUtil.pojo.getProperty(dest, "foolong"); assertEquals(204, vl.longValue()); Byte vb = BeanUtil.pojo.getProperty(dest, "fooByte"); assertEquals(95, vb.intValue()); vb = BeanUtil.pojo.getProperty(dest, "foobyte"); assertEquals(96, vb.intValue()); Character c = BeanUtil.pojo.getProperty(dest, "fooCharacter"); assertEquals('7', c.charValue()); c = BeanUtil.pojo.getProperty(dest, "foochar"); assertEquals('8', c.charValue()); Boolean b = BeanUtil.pojo.getProperty(dest, "fooBoolean"); assertTrue(b.booleanValue()); b = BeanUtil.pojo.getProperty(dest, "fooboolean"); assertFalse(b.booleanValue()); Float f = BeanUtil.pojo.getProperty(dest, "fooFloat"); assertEquals(209.0, f.floatValue(), 0.005); f = BeanUtil.pojo.getProperty(dest, "foofloat"); assertEquals(210.0, f.floatValue(), 0.005); Double d = BeanUtil.pojo.getProperty(dest, "fooDouble"); assertEquals(211.0, d.doubleValue(), 0.005); d = BeanUtil.pojo.getProperty(dest, "foodouble"); assertEquals(212.0, d.doubleValue(), 0.005); String s = BeanUtil.pojo.getProperty(dest, "fooString"); assertEquals("213", s); String[] sa = BeanUtil.pojo.getProperty(dest, "fooStringA"); assertEquals(2, sa.length); assertEquals("214", sa[0]); assertEquals("215", sa[1]); assertSame(dest.getFooStringA(), sa); FooBean empty = new FooBean(); BeanCopy.beans(empty, dest).copy(); v = BeanUtil.pojo.getProperty(dest, "fooInteger"); assertNull(v); v = BeanUtil.pojo.getProperty(dest, "fooint"); assertEquals(0, v.intValue()); vl = BeanUtil.pojo.getProperty(dest, "fooLong"); assertNull(vl); vl = BeanUtil.pojo.getProperty(dest, "foolong"); assertEquals(0, vl.longValue()); vb = BeanUtil.pojo.getProperty(dest, "fooByte"); assertNull(vb); vb = BeanUtil.pojo.getProperty(dest, "foobyte"); assertEquals(0, vb.byteValue()); c = BeanUtil.pojo.getProperty(dest, "fooCharacter"); assertNull(c); c = BeanUtil.pojo.getProperty(dest, "foochar"); assertEquals(0, c.charValue()); b = BeanUtil.pojo.getProperty(dest, "fooBoolean"); assertNull(b); b = BeanUtil.pojo.getProperty(dest, "fooboolean"); assertFalse(b); f = BeanUtil.pojo.getProperty(dest, "fooFloat"); assertNull(f); f = BeanUtil.pojo.getProperty(dest, "foofloat"); assertEquals(0, f, 0.005); d = BeanUtil.pojo.getProperty(dest, "fooDouble"); assertNull(d); d = BeanUtil.pojo.getProperty(dest, "foodouble"); assertEquals(0, d, 0.005); s = BeanUtil.pojo.getProperty(dest, "fooString"); assertNull(s); sa = BeanUtil.pojo.getProperty(dest, "fooStringA"); assertNull(sa); } @Test public void testCopyIncludes() { FooBean fb = createFooBean(); FooBean dest = new FooBean(); BeanCopy.beans(fb, dest).excludeAll().include("fooInteger", "fooLong").copy(); Integer v = BeanUtil.pojo.getProperty(dest, "fooInteger"); assertEquals(201, v.intValue()); Long vl = BeanUtil.pojo.getProperty(dest, "fooLong"); assertEquals(203, vl.longValue()); v = BeanUtil.pojo.getProperty(dest, "fooint"); assertEquals(0, v.intValue()); vl = BeanUtil.pojo.getProperty(dest, "foolong"); assertEquals(0, vl.longValue()); Byte vb = BeanUtil.pojo.getProperty(dest, "fooByte"); assertNull(vb); vb = BeanUtil.pojo.getProperty(dest, "foobyte"); assertEquals(0, vb.byteValue()); Character c = BeanUtil.pojo.getProperty(dest, "fooCharacter"); assertNull(c); c = BeanUtil.pojo.getProperty(dest, "foochar"); assertEquals(0, c.charValue()); Boolean b = BeanUtil.pojo.getProperty(dest, "fooBoolean"); assertNull(b); b = BeanUtil.pojo.getProperty(dest, "fooboolean"); assertFalse(b); Float f = BeanUtil.pojo.getProperty(dest, "fooFloat"); assertNull(f); f = BeanUtil.pojo.getProperty(dest, "foofloat"); assertEquals(0, f, 0.005); Double d = BeanUtil.pojo.getProperty(dest, "fooDouble"); assertNull(d); d = BeanUtil.pojo.getProperty(dest, "foodouble"); assertEquals(0, d, 0.005); String s = BeanUtil.pojo.getProperty(dest, "fooString"); assertNull(s); String[] sa = BeanUtil.pojo.getProperty(dest, "fooStringA"); assertNull(sa); } @Test public void testCopyExcludes() { FooBean fb = createFooBean(); FooBean dest = new FooBean(); BeanCopy.beans(fb, dest).exclude("fooInteger", "fooLong").copy(); Integer v = BeanUtil.pojo.getProperty(dest, "fooInteger"); assertNull(v); v = BeanUtil.pojo.getProperty(dest, "fooint"); assertEquals(202, v.intValue()); Long vl = BeanUtil.pojo.getProperty(dest, "fooLong"); assertNull(vl); vl = BeanUtil.pojo.getProperty(dest, "foolong"); assertEquals(204, vl.longValue()); Byte vb = BeanUtil.pojo.getProperty(dest, "fooByte"); assertEquals(95, vb.intValue()); vb = BeanUtil.pojo.getProperty(dest, "foobyte"); assertEquals(96, vb.intValue()); Character c = BeanUtil.pojo.getProperty(dest, "fooCharacter"); assertEquals('7', c.charValue()); c = BeanUtil.pojo.getProperty(dest, "foochar"); assertEquals('8', c.charValue()); Boolean b = BeanUtil.pojo.getProperty(dest, "fooBoolean"); assertTrue(b.booleanValue()); b = BeanUtil.pojo.getProperty(dest, "fooboolean"); assertFalse(b.booleanValue()); Float f = BeanUtil.pojo.getProperty(dest, "fooFloat"); assertEquals(209.0, f.floatValue(), 0.005); f = BeanUtil.pojo.getProperty(dest, "foofloat"); assertEquals(210.0, f.floatValue(), 0.005); Double d = BeanUtil.pojo.getProperty(dest, "fooDouble"); assertEquals(211.0, d.doubleValue(), 0.005); d = BeanUtil.pojo.getProperty(dest, "foodouble"); assertEquals(212.0, d.doubleValue(), 0.005); String s = BeanUtil.pojo.getProperty(dest, "fooString"); assertEquals("213", s); String[] sa = BeanUtil.pojo.getProperty(dest, "fooStringA"); assertEquals(2, sa.length); assertEquals("214", sa[0]); assertEquals("215", sa[1]); assertSame(dest.getFooStringA(), sa); } @Test public void testCopyTemplate() { FooBean fooBean = createFooBean(); FooBean dest = new FooBean(); BeanCopy.beans(fooBean, dest).includeAs(FooBeanString.class).copy(); Integer v = BeanUtil.pojo.getProperty(dest, "fooInteger"); assertNull(v); v = BeanUtil.pojo.getProperty(dest, "fooint"); assertEquals(0, v.intValue()); Long vl = BeanUtil.pojo.getProperty(dest, "fooLong"); assertNull(vl); vl = BeanUtil.pojo.getProperty(dest, "foolong"); assertEquals(0, vl.longValue()); Byte vb = BeanUtil.pojo.getProperty(dest, "fooByte"); assertNull(vb); vb = BeanUtil.pojo.getProperty(dest, "foobyte"); assertEquals(0, vb.byteValue()); Character c = BeanUtil.pojo.getProperty(dest, "fooCharacter"); assertNull(c); c = BeanUtil.pojo.getProperty(dest, "foochar"); assertEquals(0, c.charValue()); Boolean b = BeanUtil.pojo.getProperty(dest, "fooBoolean"); assertNull(b); b = BeanUtil.pojo.getProperty(dest, "fooboolean"); assertFalse(b.booleanValue()); Float f = BeanUtil.pojo.getProperty(dest, "fooFloat"); assertNull(f); f = BeanUtil.pojo.getProperty(dest, "foofloat"); assertEquals(0, f.floatValue(), 0.005); Double d = BeanUtil.pojo.getProperty(dest, "fooDouble"); assertNull(d); d = BeanUtil.pojo.getProperty(dest, "foodouble"); assertEquals(0, d.doubleValue(), 0.005); String s = BeanUtil.pojo.getProperty(dest, "fooString"); assertEquals("213", s); String[] sa = BeanUtil.pojo.getProperty(dest, "fooStringA"); assertNull(sa); } @Test public void testCopyProperties() { Properties properties = new Properties(); properties.put("fooInteger", Integer.valueOf(1)); properties.put("fooint", Integer.valueOf(2)); FooBean fooBean = new FooBean(); assertEquals(0, fooBean.getFooint()); // copy to BeanCopy.fromMap(properties).toBean(fooBean).copy(); assertEquals(1, fooBean.getFooInteger().intValue()); assertEquals(2, fooBean.getFooint()); // copy back properties.clear(); BeanCopy.fromBean(fooBean).toMap(properties).copy(); assertEquals(1, properties.get("fooInteger")); assertEquals(2, properties.get("fooint")); } static class Less { String data; Integer number; public String getData() { return data; } public void setData(String data) { this.data = data; } public Integer getNumber() { return number; } public void setNumber(Integer number) { this.number = number; } } static class More { String data; String number; String boo; public String getData() { return data; } public void setData(String data) { this.data = data; } public String getNumber() { return number; } public void setNumber(String number) { this.number = number; } public String getBoo() { return boo; } public void setBoo(String boo) { this.boo = boo; } } @Test public void testLessToMore() { Less less = new Less(); less.data = "data"; less.number = new Integer(2); More more = new More(); BeanCopy.beans(less, more).declared(true).copy(); assertEquals("data", more.data); assertEquals("2", more.number); more.data = "tij"; more.number = "17"; BeanCopy.beans(more, less).declared(true).copy(); assertEquals("tij", less.data); assertEquals(17, less.number.intValue()); } @Test public void testCopyMap() { Map map = new HashMap(); map.put("fooint", Integer.valueOf(102)); map.put("fooString", "mao"); FooBean dest = new FooBean(); BeanCopy.beans(map, dest).copy(); assertEquals(102, dest.getFooint()); assertEquals("mao", dest.getFooString()); Map destMap = new HashMap(); BeanCopy.beans(map, destMap).copy(); assertEquals(2, destMap.size()); assertEquals(Integer.valueOf(102), destMap.get("fooint")); assertEquals("mao", destMap.get("fooString")); } @Test public void testCopyIgnoreNulls() { FooBean fb = createFooBean(); FooBean dest = new FooBean(); dest.setFooInteger(Integer.valueOf(999)); fb.setFooInteger(null); BeanCopy.beans(fb, dest).ignoreNulls(true).copy(); Integer v = BeanUtil.pojo.getProperty(dest, "fooInteger"); assertEquals(999, v.intValue()); v = BeanUtil.pojo.getProperty(dest, "fooint"); assertEquals(202, v.intValue()); Long vl = BeanUtil.pojo.getProperty(dest, "fooLong"); assertEquals(203, vl.longValue()); vl = BeanUtil.pojo.getProperty(dest, "foolong"); assertEquals(204, vl.longValue()); Byte vb = BeanUtil.pojo.getProperty(dest, "fooByte"); assertEquals(95, vb.intValue()); vb = BeanUtil.pojo.getProperty(dest, "foobyte"); assertEquals(96, vb.intValue()); Character c = BeanUtil.pojo.getProperty(dest, "fooCharacter"); assertEquals('7', c.charValue()); c = BeanUtil.pojo.getProperty(dest, "foochar"); assertEquals('8', c.charValue()); Boolean b = BeanUtil.pojo.getProperty(dest, "fooBoolean"); assertTrue(b.booleanValue()); b = BeanUtil.pojo.getProperty(dest, "fooboolean"); assertFalse(b.booleanValue()); Float f = BeanUtil.pojo.getProperty(dest, "fooFloat"); assertEquals(209.0, f.floatValue(), 0.005); f = BeanUtil.pojo.getProperty(dest, "foofloat"); assertEquals(210.0, f.floatValue(), 0.005); Double d = BeanUtil.pojo.getProperty(dest, "fooDouble"); assertEquals(211.0, d.doubleValue(), 0.005); d = BeanUtil.pojo.getProperty(dest, "foodouble"); assertEquals(212.0, d.doubleValue(), 0.005); String s = BeanUtil.pojo.getProperty(dest, "fooString"); assertEquals("213", s); String[] sa = BeanUtil.pojo.getProperty(dest, "fooStringA"); assertEquals(2, sa.length); assertEquals("214", sa[0]); assertEquals("215", sa[1]); assertSame(dest.getFooStringA(), sa); } private FooBean createFooBean() { FooBean fb = new FooBean(); fb.setFooInteger(new Integer(201)); fb.setFooint(202); fb.setFooLong(new Long(203)); fb.setFoolong(204); fb.setFooByte(new Byte((byte) 95)); fb.setFoobyte((byte) 96); fb.setFooCharacter(new Character('7')); fb.setFoochar('8'); fb.setFooBoolean(Boolean.TRUE); fb.setFooboolean(false); fb.setFooFloat(new Float(209.0)); fb.setFoofloat((float) 210.0); fb.setFooDouble(new Double(211.0)); fb.setFoodouble(212.0); fb.setFooString("213"); fb.setFooStringA(new String[]{"214", "215"}); return fb; } public static class Source { public String pub = "a1"; private int priv = 2; public long getGetter() { return 5; } private int _prop = 8; public int getProp() { return _prop; } protected String getMoo() { return moo; } protected String moo = "wof"; } @Test public void testCopyWithFields() { Source source = new Source(); HashMap dest = new HashMap(); BeanCopy.beans(source, dest).copy(); assertEquals(2, dest.size()); assertEquals("8", dest.get("prop").toString()); assertEquals("5", dest.get("getter").toString()); dest.clear(); BeanCopy.beans(source, dest).declared(true).copy(); assertEquals(3, dest.size()); assertEquals("8", dest.get("prop").toString()); assertEquals("5", dest.get("getter").toString()); assertEquals("wof", dest.get("moo").toString()); dest.clear(); BeanCopy.beans(source, dest).declared(false).includeFields(true).copy(); assertEquals(3, dest.size()); assertEquals("8", dest.get("prop").toString()); assertEquals("5", dest.get("getter").toString()); assertEquals("a1", dest.get("pub").toString()); dest.clear(); BeanCopy.beans(source, dest).declared(true).includeFields(true).copy(); assertEquals(6, dest.size()); assertEquals("8", dest.get("prop").toString()); assertEquals("5", dest.get("getter").toString()); assertEquals("a1", dest.get("pub").toString()); assertEquals("2", dest.get("priv").toString()); assertEquals("8", dest.get("_prop").toString()); assertEquals("wof", dest.get("moo").toString()); } public static class Moo { private String name = "cow"; private Integer value = Integer.valueOf(7); private long nick = 100; public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getValue() { return value; } public void setValue(Integer value) { this.value = value; } public long getNick() { return nick; } public void setNick(long nick) { this.nick = nick; } } @Test public void testIncludeExclude() { Moo moo = new Moo(); HashMap map = new HashMap(); BeanCopy beanCopy = new BeanCopy(moo, map) { @Override public boolean accept(String propertyName, String pattern, boolean included) { return Wildcard.match(propertyName, pattern); } }; // + exclude all beanCopy.rules.reset(); map.clear(); beanCopy.exclude("*"); beanCopy.copy(); assertEquals(0, map.size()); // + exclude all but one beanCopy.rules.reset(); map.clear(); beanCopy.exclude("*"); beanCopy.include("name"); beanCopy.copy(); assertEquals(1, map.size()); assertEquals("cow", map.get("name")); // + include all but one beanCopy.rules.reset(); map.clear(); beanCopy.exclude("nick"); beanCopy.copy(); assertEquals(2, map.size()); assertEquals("cow", map.get("name")); assertEquals("7", map.get("value").toString()); // + include all beanCopy.rules.reset(); map.clear(); beanCopy.copy(); assertEquals(3, map.size()); assertEquals("cow", map.get("name")); assertEquals("7", map.get("value").toString()); assertEquals("100", map.get("nick").toString()); } // ---------------------------------------------------------------- special test public static class PropertyBean { public int number; public PropertyBean child; } @Test public void testFromMapToBean() throws Exception { Properties propsSource = new Properties(); propsSource.put("number", 42); propsSource.put("child.number", 43); propsSource.put("nonExistantNumber", 142); propsSource.put("nonExistantChild.number", 143); PropertyBean beanDest = new PropertyBean(); BeanCopy.fromMap(propsSource).toBean(beanDest).forced(true).copy(); assertThat(beanDest.number, is(42)); assertThat(beanDest.child.number, is(43)); } @Test public void testFromMapToMap() throws Exception { Properties propsSource = new Properties(); propsSource.put("number", 42); propsSource.put("child.number", 43); propsSource.put("nonExistantNumber", 142); propsSource.put("nonExistantChild.number", 143); Properties propsDest = new Properties(); BeanCopy.fromMap(propsSource).toMap(propsDest).copy(); assertEquals(propsSource, propsDest); } @Test public void testFromBeanToMap() throws Exception { PropertyBean beanSource = new PropertyBean(); beanSource.number = 42; beanSource.child = new PropertyBean(); beanSource.child.number = 43; Properties propsDest = new Properties(); BeanCopy .fromBean(beanSource) .toMap(propsDest) .includeFields(true) .copy(); assertThat(propsDest.size(), is(2)); assertThat((Integer) propsDest.get("number"), is(42)); assertThat((Integer) BeanUtil.pojo.getProperty(propsDest, "child.number"), is(43)); } @Test public void testFromBeanToBean() throws Exception { PropertyBean beanSource = new PropertyBean(); beanSource.number = 42; beanSource.child = new PropertyBean(); beanSource.child.number = 43; PropertyBean beanDest = new PropertyBean(); BeanCopy.fromBean(beanSource).toBean(beanDest).includeFields(true).copy(); assertThat(beanDest.number, is(42)); assertThat(beanDest.child.number, is(43)); } }