Java tutorial
/* * Copyright (C) 2004, 2005 Joe Walnes. * Copyright (C) 2006, 2007, 2008, 2009, 2014, 2015 XStream Committers. * All rights reserved. * * The software in this package is published under the terms of the BSD * style license a copy of which has been included with this distribution in * the LICENSE.txt file. * * Created on 24. August 2004 by Joe Walnes */ package com.thoughtworks.acceptance; import com.thoughtworks.acceptance.objects.Original; import com.thoughtworks.acceptance.objects.Replaced; import com.thoughtworks.acceptance.objects.StandardObject; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.Externalizable; import java.io.IOException; import java.io.ObjectInput; import java.io.ObjectInputStream; import java.io.ObjectOutput; import java.io.ObjectOutputStream; import java.io.Serializable; import java.util.ArrayList; import java.util.List; import org.apache.commons.lang.StringUtils; public class WriteReplaceTest extends AbstractAcceptanceTest { public static class Thing extends StandardObject implements Serializable { int a; int b; public Thing() { } public Thing(int a, int b) { this.a = a; this.b = b; } private Object writeReplace() { return new Thing(a * 1000, b * 1000); } private Object readResolve() { return new Thing(a / 1000, b / 1000); } } public void testReplacesAndResolves() throws IOException, ClassNotFoundException { Thing thing = new Thing(3, 6); // ensure that Java serialization does not cause endless loop for a Thing ByteArrayOutputStream baos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(baos); oos.writeObject(thing); oos.close(); ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); ObjectInputStream ios = new ObjectInputStream(bais); assertEquals(thing, ios.readObject()); ios.close(); // ensure that XStream does not cause endless loop for a Thing xstream.alias("thing", Thing.class); String expectedXml = "" + "<thing>\n" + " <a>3000</a>\n" + " <b>6000</b>\n" + "</thing>"; assertBothWays(thing, expectedXml); } public void testAllowsDifferentTypeToBeSubstituted() { xstream.alias("original-class", Original.class); xstream.alias("replaced-class", Replaced.class); Original in = new Original("hello world"); String expectedXml = "" + "<original-class resolves-to=\"replaced-class\">\n" + " <replacedValue>HELLO WORLD</replacedValue>\n" + "</original-class>"; assertBothWays(in, expectedXml); } public void testAllowsDifferentTypeToBeSubstitutedInList() { xstream.alias("original-class", Original.class); xstream.alias("replaced-class", Replaced.class); List in = new ArrayList(); in.add(new Original("hello world")); String expectedXml = "" + "<list>\n" + " <original-class resolves-to=\"replaced-class\">\n" + " <replacedValue>HELLO WORLD</replacedValue>\n" + " </original-class>\n" + "</list>"; assertBothWays(in, expectedXml); } public static class Container extends StandardObject { Original original; } public void testAllowsDifferentTypeToBeSubstitutedAsMember() { xstream.alias("container", Container.class); xstream.alias("original-class", Original.class); xstream.alias("replaced-class", Replaced.class); Container in = new Container(); in.original = new Original("hello world"); String expectedXml = "" + "<container>\n" + " <original resolves-to=\"replaced-class\">\n" + " <replacedValue>HELLO WORLD</replacedValue>\n" + " </original>\n" + "</container>"; assertBothWays(in, expectedXml); } public static class ExternalizableContainer extends StandardObject implements Externalizable { Original original; public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { original = (Original) in.readObject(); } public void writeExternal(ObjectOutput out) throws IOException { out.writeObject(original); } } public void testAllowsDifferentTypeToBeSubstitutedInExternalizable() { xstream.alias("container", ExternalizableContainer.class); xstream.alias("original-class", Original.class); xstream.alias("replaced-class", Replaced.class); ExternalizableContainer in = new ExternalizableContainer(); in.original = new Original("hello world"); String expectedXml = "" + "<container>\n" + " <original-class resolves-to=\"replaced-class\">\n" + " <replacedValue>HELLO WORLD</replacedValue>\n" + " </original-class>\n" + "</container>"; assertBothWays(in, expectedXml); } public void testAllowsDifferentTypeToBeSubstitutedWithNonExistingClass() { xstream.alias("original-class", Original.class); xstream.alias("replaced-class", Replaced.class); Original in = new Original("hello world"); String xml = "" + "<original-class resolves-to=\"replaced-class\" class=\"not.Existing\">\n" + " <replacedValue>HELLO WORLD</replacedValue>\n" + "</original-class>"; assertEquals(in, xstream.fromXML(xml)); } public void testAllowsDifferentTypeToBeSubstitutedWithNonExistingClassInList() { xstream.alias("original-class", Original.class); xstream.alias("replaced-class", Replaced.class); List in = new ArrayList(); in.add(new Original("hello world")); String xml = "" + "<list>\n" + " <original-class resolves-to=\"replaced-class\" class=\"not.Existing\">\n" + " <replacedValue>HELLO WORLD</replacedValue>\n" + " </original-class>\n" + "</list>"; assertEquals(in, xstream.fromXML(xml)); } public void testAllowsDifferentTypeToBeSubstitutedWithNonExistingClassAsMember() { xstream.alias("container", Container.class); xstream.alias("original-class", Original.class); xstream.alias("replaced-class", Replaced.class); Container in = new Container(); in.original = new Original("hello world"); String xml = "" + "<container>\n" + " <original resolves-to=\"replaced-class\" class=\"not.Existing\">\n" + " <replacedValue>HELLO WORLD</replacedValue>\n" + " </original>\n" + "</container>"; assertEquals(in, xstream.fromXML(xml)); } public void testAllowsDifferentTypeToBeSubstitutedWithNonExistingClassInExternalizable() { xstream.alias("container", ExternalizableContainer.class); xstream.alias("original-class", Original.class); xstream.alias("replaced-class", Replaced.class); ExternalizableContainer in = new ExternalizableContainer(); in.original = new Original("hello world"); String xml = "" + "<container>\n" + " <original-class resolves-to=\"replaced-class\" class=\"not.Existing\">\n" + " <replacedValue>HELLO WORLD</replacedValue>\n" + " </original-class>\n" + "</container>"; assertEquals(in, xstream.fromXML(xml)); } public static class OriginalSerializable extends StandardObject { String originalValue; public OriginalSerializable() { } public OriginalSerializable(String originalValue) { this.originalValue = originalValue; } private Object writeReplace() { return new ReplacedSerializable(originalValue.toUpperCase()); } private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { in.defaultReadObject(); } } public static class ReplacedSerializable extends StandardObject { String replacedValue; public ReplacedSerializable() { } public ReplacedSerializable(String replacedValue) { this.replacedValue = replacedValue; } private Object readResolve() { return new OriginalSerializable(replacedValue.toLowerCase()); } private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { in.defaultReadObject(); } } public void testAllowsDifferentTypeToBeSubstitutedForCustomSerializableObjects() { xstream.alias("original-serializable-class", OriginalSerializable.class); xstream.alias("replaced-serializable-class", ReplacedSerializable.class); OriginalSerializable in = new OriginalSerializable("hello world"); String expectedXml = "" + "<original-serializable-class resolves-to=\"replaced-serializable-class\" serialization=\"custom\">\n" + " <replaced-serializable-class>\n" + " <default>\n" + " <replacedValue>HELLO WORLD</replacedValue>\n" + " </default>\n" + " </replaced-serializable-class>\n" + "</original-serializable-class>"; assertBothWays(in, expectedXml); } public static class OriginalExternalizable extends StandardObject implements Externalizable { String originalValue; public OriginalExternalizable() { } public OriginalExternalizable(String originalValue) { this.originalValue = originalValue; } private Object writeReplace() { return new ReplacedExternalizable(originalValue.toUpperCase()); } public void writeExternal(ObjectOutput out) throws IOException { out.writeObject(originalValue); } public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { originalValue = (String) in.readObject(); } } public static class ReplacedExternalizable extends StandardObject implements Externalizable { String replacedValue; public ReplacedExternalizable() { } public ReplacedExternalizable(String replacedValue) { this.replacedValue = replacedValue; } private Object readResolve() { return new OriginalExternalizable(replacedValue.toLowerCase()); } public void writeExternal(ObjectOutput out) throws IOException { out.writeObject(StringUtils.reverse(replacedValue)); } public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { replacedValue = StringUtils.reverse((String) in.readObject()); } } public void testAllowsDifferentTypeToBeSubstitutedForCustomExternalizableObjects() { xstream.alias("original-externalizable-class", OriginalExternalizable.class); xstream.alias("replaced-externalizable-class", ReplacedExternalizable.class); OriginalExternalizable in = new OriginalExternalizable("hello world"); String expectedXml = "" + "<original-externalizable-class resolves-to=\"replaced-externalizable-class\">\n" + " <string>DLROW OLLEH</string>\n" + "</original-externalizable-class>"; assertBothWays(in, expectedXml); } }