/*
* Copyright (C) 2004, 2005 Joe Walnes.
* Copyright (C) 2006, 2007 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.StandardObject;
import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
public class ExternalizableTest extends AbstractAcceptanceTest {
public static class SomethingExternalizable extends StandardObject implements Externalizable {
private String first;
private String last;
public SomethingExternalizable() {
}
public SomethingExternalizable(String first, String last) {
this.first = first;
this.last = last;
}
public void writeExternal(ObjectOutput out) throws IOException {
out.writeInt(first.length());
out.writeObject(first + last);
}
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
int offset = in.readInt();
String full = (String) in.readObject();
first = full.substring(0, offset);
last = full.substring(offset);
}
}
public void testExternalizable() {
xstream.alias("something", SomethingExternalizable.class);
SomethingExternalizable in = new SomethingExternalizable("Joe", "Walnes");
String expected = ""
+ "<something>\n"
+ " <int>3</int>\n"
+ " <string>JoeWalnes</string>\n"
+ "</something>";
assertBothWays(in, expected);
}
static class Owner extends StandardObject {
SomethingExternalizable target;
}
public void testExternalizableAsFieldOfAnotherObject() {
xstream.alias("something", SomethingExternalizable.class);
xstream.alias("owner", Owner.class);
Owner in = new Owner();
in.target = new SomethingExternalizable("Joe", "Walnes");
String expected = ""
+ "<owner>\n"
+ " <target>\n"
+ " <int>3</int>\n"
+ " <string>JoeWalnes</string>\n"
+ " </target>\n"
+ "</owner>";
assertBothWays(in, expected);
}
public static class CircularExternalizable implements Externalizable {
private String name;
private CircularExternalizable parent;
private CircularExternalizable child;
public CircularExternalizable() {
}
public CircularExternalizable(String name) {
this.name = name;
}
public void setParent(CircularExternalizable parent) {
this.parent = parent;
if (parent != null) {
parent.child = this;
}
}
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
name = (String)in.readObject();
parent = (CircularExternalizable)in.readObject();
child = (CircularExternalizable)in.readObject();
}
public void writeExternal(ObjectOutput out) throws IOException {
out.writeObject(name);
out.writeObject(parent);
out.writeObject(child);
}
// StandardObject uses EqualsBuilder.reflectionEquals of commons-lang,
// that does not handle circular dependencies
public boolean equals(Object obj) {
return obj instanceof CircularExternalizable && name.equals(obj.toString());
}
public int hashCode() {
return name.hashCode()+1;
}
public String toString() {
return name;
}
}
public void testCircularExternalizable() {
xstream.alias("elem", CircularExternalizable.class);
CircularExternalizable parent = new CircularExternalizable("parent");
CircularExternalizable child = new CircularExternalizable("child");
child.setParent(parent);
String expected = ""
+ "<elem>\n"
+ " <string>parent</string>\n"
+ " <null/>\n"
+ " <elem>\n"
+ " <string>child</string>\n"
+ " <elem reference=\"../..\"/>\n"
+ " <null/>\n"
+ " </elem>\n"
+ "</elem>";
assertBothWays(parent, expected);
}
}