package org.jvnet.jaxb2_commons.lang.tests; import java.util.IdentityHashMap; import java.util.Map; import junit.framework.TestCase; import org.jvnet.jaxb2_commons.lang.CopyStrategy; import org.jvnet.jaxb2_commons.lang.CopyTo; import org.jvnet.jaxb2_commons.lang.JAXBCopyStrategy; import org.jvnet.jaxb2_commons.locator.DefaultRootObjectLocator; import org.jvnet.jaxb2_commons.locator.ObjectLocator; import org.jvnet.jaxb2_commons.locator.util.LocatorUtils; public class CyclicTests extends TestCase { public interface CopyToInstance extends CopyTo { } public static class A implements CopyToInstance { public B b; public Object createNewInstance() { return new A(); } public Object copyTo(Object target) { return copyTo(null, target, JAXBCopyStrategy.INSTANCE); } public Object copyTo(ObjectLocator locator, Object target, CopyStrategy copyStrategy) { final A that = (A) target; that.b = (B) copyStrategy.copy(LocatorUtils.property(locator, "b", this.b), this.b); return that; } } public static class B implements CopyToInstance { public A a; public Object createNewInstance() { return new B(); } public Object copyTo(Object target) { return copyTo(null, target, JAXBCopyStrategy.INSTANCE); } public Object copyTo(ObjectLocator locator, Object target, CopyStrategy copyStrategy) { final B that = (B) target; that.a = (A) copyStrategy.copy(LocatorUtils.property(locator, "a", this.a), this.a); return that; } } public void testCycle() throws Exception { final A a = new A(); final B b = new B(); a.b = b; b.a = a; final A a1 = (A) new JAXBCopyStrategy() { private Map<Object, Object> copies = new IdentityHashMap<Object, Object>(); @Override public Object copy(ObjectLocator locator, Object object) { final Object existingCopy = copies.get(object); if (existingCopy != null) { return existingCopy; } else { if (object instanceof CopyToInstance) { final CopyToInstance source = (CopyToInstance) object; final Object newCopy = source.createNewInstance(); copies.put(object, newCopy); source.copyTo(locator, newCopy, this); return newCopy; } else { final Object newCopy = super.copy(locator, object); copies.put(object, newCopy); return newCopy; } } } }.copy(new DefaultRootObjectLocator(a), a); assertSame(a1.b.a, a1); } }