001: /*
002: * Copyright (C) 2004, 2005 Joe Walnes.
003: * Copyright (C) 2006, 2007 XStream Committers.
004: * All rights reserved.
005: *
006: * The software in this package is published under the terms of the BSD
007: * style license a copy of which has been included with this distribution in
008: * the LICENSE.txt file.
009: *
010: * Created on 24. August 2004 by Joe Walnes
011: */
012: package com.thoughtworks.acceptance;
013:
014: import com.thoughtworks.acceptance.objects.StandardObject;
015:
016: import java.io.Externalizable;
017: import java.io.IOException;
018: import java.io.ObjectInput;
019: import java.io.ObjectOutput;
020:
021: public class ExternalizableTest extends AbstractAcceptanceTest {
022:
023: public static class SomethingExternalizable extends StandardObject
024: implements Externalizable {
025:
026: private String first;
027: private String last;
028:
029: public SomethingExternalizable() {
030: }
031:
032: public SomethingExternalizable(String first, String last) {
033: this .first = first;
034: this .last = last;
035: }
036:
037: public void writeExternal(ObjectOutput out) throws IOException {
038: out.writeInt(first.length());
039: out.writeObject(first + last);
040: }
041:
042: public void readExternal(ObjectInput in) throws IOException,
043: ClassNotFoundException {
044: int offset = in.readInt();
045: String full = (String) in.readObject();
046: first = full.substring(0, offset);
047: last = full.substring(offset);
048: }
049: }
050:
051: public void testExternalizable() {
052: xstream.alias("something", SomethingExternalizable.class);
053:
054: SomethingExternalizable in = new SomethingExternalizable("Joe",
055: "Walnes");
056:
057: String expected = "" + "<something>\n" + " <int>3</int>\n"
058: + " <string>JoeWalnes</string>\n" + "</something>";
059:
060: assertBothWays(in, expected);
061: }
062:
063: static class Owner extends StandardObject {
064: SomethingExternalizable target;
065: }
066:
067: public void testExternalizableAsFieldOfAnotherObject() {
068: xstream.alias("something", SomethingExternalizable.class);
069: xstream.alias("owner", Owner.class);
070:
071: Owner in = new Owner();
072: in.target = new SomethingExternalizable("Joe", "Walnes");
073:
074: String expected = "" + "<owner>\n" + " <target>\n"
075: + " <int>3</int>\n"
076: + " <string>JoeWalnes</string>\n" + " </target>\n"
077: + "</owner>";
078:
079: assertBothWays(in, expected);
080: }
081:
082: public static class CircularExternalizable implements
083: Externalizable {
084: private String name;
085: private CircularExternalizable parent;
086: private CircularExternalizable child;
087:
088: public CircularExternalizable() {
089: }
090:
091: public CircularExternalizable(String name) {
092: this .name = name;
093: }
094:
095: public void setParent(CircularExternalizable parent) {
096: this .parent = parent;
097: if (parent != null) {
098: parent.child = this ;
099: }
100: }
101:
102: public void readExternal(ObjectInput in) throws IOException,
103: ClassNotFoundException {
104: name = (String) in.readObject();
105: parent = (CircularExternalizable) in.readObject();
106: child = (CircularExternalizable) in.readObject();
107: }
108:
109: public void writeExternal(ObjectOutput out) throws IOException {
110: out.writeObject(name);
111: out.writeObject(parent);
112: out.writeObject(child);
113: }
114:
115: // StandardObject uses EqualsBuilder.reflectionEquals of commons-lang,
116: // that does not handle circular dependencies
117: public boolean equals(Object obj) {
118: return obj instanceof CircularExternalizable
119: && name.equals(obj.toString());
120: }
121:
122: public int hashCode() {
123: return name.hashCode() + 1;
124: }
125:
126: public String toString() {
127: return name;
128: }
129:
130: }
131:
132: public void testCircularExternalizable() {
133: xstream.alias("elem", CircularExternalizable.class);
134:
135: CircularExternalizable parent = new CircularExternalizable(
136: "parent");
137: CircularExternalizable child = new CircularExternalizable(
138: "child");
139: child.setParent(parent);
140:
141: String expected = "" + "<elem>\n"
142: + " <string>parent</string>\n" + " <null/>\n"
143: + " <elem>\n" + " <string>child</string>\n"
144: + " <elem reference=\"../..\"/>\n" + " <null/>\n"
145: + " </elem>\n" + "</elem>";
146:
147: assertBothWays(parent, expected);
148: }
149: }
|