// 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));
}
}