/* * Copyright 2009 The Apache Software Foundation. * * Licensed 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 net.sf.beanlib.spi; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.not; import static org.hamcrest.CoreMatchers.nullValue; import static org.hamcrest.CoreMatchers.sameInstance; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; import java.util.Arrays; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; import junit.framework.JUnit4TestAdapter; import net.sf.beanlib.BeanlibException; import net.sf.beanlib.PropertyInfo; import net.sf.beanlib.provider.BeanTransformer; import net.sf.beanlib.provider.replicator.BeanReplicator; import org.apache.commons.lang.builder.EqualsBuilder; import org.apache.commons.lang.builder.ToStringBuilder; import org.apache.commons.lang.builder.ToStringStyle; import org.junit.Test; /** * @author Hanson Char */ public class CustomBeanTransformerTest { public static class Point { private final int x, y; public Point(int x, int y) { this.x = x; this.y = y; } public int getX() { return x; } public int getY() { return y; } @Override public String toString() { return ToStringBuilder.reflectionToString(this, ToStringStyle.MULTI_LINE_STYLE); } @Override public boolean equals(Object obj) { return EqualsBuilder.reflectionEquals(this, obj); } } public static class Bean { private Point point; private Collection<Point> collection; private Point[] array; private Map<String, Point> map; public Map<String, Point> getMap() { return map; } public void setMap(Map<String, Point> map) { this.map = map; } public Point[] getArray() { return array; } public void setArray(Point[] array) { this.array = array; } public Collection<Point> getCollection() { return collection; } public void setCollection(Collection<Point> collection) { this.collection = collection; } public Point getPoint() { return point; } public void setPoint(Point point) { this.point = point; } @Override public String toString() { return ToStringBuilder.reflectionToString(this, ToStringStyle.MULTI_LINE_STYLE); } } public static class MyBeanTransformer implements CustomBeanTransformerSpi { @Override public boolean isTransformable(Object from, Class<?> toClass, PropertyInfo propertyInfo) { return toClass == Point.class && from != null; } @Override public <T> T transform(Object in, Class<T> toClass, PropertyInfo propertyInfo) { Point from = (Point) in; // Note the framework takes care of the issue of object identity, // so we don't need to here. @SuppressWarnings("unchecked") T ret = (T) new Point(from.getX(), from.getY()); return ret; } } public static class MyBeanTransformerFactory implements CustomBeanTransformerSpi.Factory { @Override public CustomBeanTransformerSpi newCustomBeanTransformer(BeanTransformerSpi beanTransformer) { return new MyBeanTransformer(); } } @Test(expected = BeanlibException.class) public void testReplicationFailure() { // Initialize a bean Bean from = new Bean(); from.setPoint(new Point(1, 2)); // Tries to replicate the bean via the default replicator BeanReplicator replicator = new BeanReplicator(); // Will cause exception, as Point has no default constructor replicator.replicateBean(from); } @Test public void testCustomReplicationSuccess() { // Initialize a bean Bean from = new Bean(); from.setPoint(new Point(1, 2)); // Partially overrides the default transformer behavior BeanTransformerSpi transformer = new BeanTransformer(); transformer.initCustomTransformerFactory(new MyBeanTransformerFactory()); BeanReplicator replicator = new BeanReplicator(transformer); Bean to = replicator.replicateBean(from); // now works! System.out.println(to); assertThat(to.getPoint(), is(from.getPoint())); assertThat(to.getCollection(), is(nullValue())); assertThat(to, not(sameInstance(from))); assertThat(to.getPoint(), not(sameInstance(from.getPoint()))); assertThat(from.getCollection(), is(nullValue())); } @Test public void testCustomCollectionReplication() { Bean from = new Bean(); final Point p0 = new Point(3, 4); final Point p3 = p0; Collection<Point> col = Arrays.asList(p0, null, new Point(5, 6), p3); from.setCollection(col); BeanTransformerSpi transformer = new BeanTransformer(); transformer.initCustomTransformerFactory(new MyBeanTransformerFactory()); BeanReplicator replicator = new BeanReplicator(transformer); Bean to = replicator.replicateBean(from); // now works! System.out.println(to); assertThat(to.getPoint(), is(nullValue())); assertThat(from.getPoint(), is(nullValue())); assertThat(to, not(sameInstance(from))); assertThat(from.getCollection(), is(to.getCollection())); assertThat(from.getCollection(), not(sameInstance(to.getCollection()))); List<Point> toList = (List<Point>) to.getCollection(); assertThat(toList.get(0), sameInstance(toList.get(3))); assertThat(toList.get(0), not(sameInstance(p0))); } @Test public void testCustomArrayReplication() { final Bean from = new Bean(); final Point p0 = new Point(3, 4); final Point p3 = p0; Point[] a = { p0, null, new Point(5, 6), p3 }; from.setArray(a); BeanTransformerSpi transformer = new BeanTransformer(); transformer.initCustomTransformerFactory(new MyBeanTransformerFactory()); BeanReplicator replicator = new BeanReplicator(transformer); Bean to = replicator.replicateBean(from); // now works! System.out.println(to); assertThat(to.getPoint(), is(nullValue())); assertThat(from.getPoint(), is(nullValue())); assertThat(to.getCollection(), is(nullValue())); assertThat(from.getCollection(), is(nullValue())); assertThat(to, not(sameInstance(from))); assertTrue(Arrays.equals(from.getArray(), to.getArray())); assertThat(from.getArray(), not(sameInstance(to.getArray()))); assertThat(to.getArray()[0], sameInstance(to.getArray()[3])); assertThat(to.getArray()[0], not(sameInstance(p0))); } @Test public void testCustomMapReplication() { Bean from = new Bean(); final Point p0 = new Point(3, 4); final Point p56 = new Point(5, 6); final Point p3 = p0; Map<String, Point> map = new HashMap<String, Point>(); map.put("p0", p0); map.put("pnull", null); map.put("p5-6", p56); map.put("p3", p3); from.setMap(map); BeanTransformerSpi transformer = new BeanTransformer(); transformer.initCustomTransformerFactory(new MyBeanTransformerFactory()); BeanReplicator replicator = new BeanReplicator(transformer); Bean to = replicator.replicateBean(from); // now works! System.out.println(to); assertThat(to.getPoint(), is(nullValue())); assertThat(from.getPoint(), is(nullValue())); assertThat(to.getCollection(), is(nullValue())); assertThat(from.getCollection(), is(nullValue())); assertThat(to.getArray(), is(nullValue())); assertThat(from.getArray(), is(nullValue())); assertThat(to, not(sameInstance(from))); assertThat(from.getMap(), is(to.getMap())); assertThat(from.getMap(), not(sameInstance(to.getMap()))); assertThat(to.getMap().get("pnull"), is(nullValue())); assertTrue(to.getMap().containsKey("pnull")); assertThat(to.getMap().get("p0"), sameInstance(to.getMap().get("p3"))); assertThat(to.getMap().get("p0"), is(p0)); assertThat(to.getMap().get("p0"), not(sameInstance(p0))); assertThat(to.getMap().get("p5-6"), is(p56)); assertThat(to.getMap().get("p5-6"), not(sameInstance(p56))); } public static junit.framework.Test suite() { return new JUnit4TestAdapter(new Object() {}.getClass().getEnclosingClass()); } }