blob: 4623541cfe7585a7b86c2a587739f057a53599c4 [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 2004-2007 Sun Microsystems, Inc. All Rights Reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
20 * CA 95054 USA or visit www.sun.com if you need additional information or
21 * have any questions.
22 */
23
24/*
25 * @test
26 * @bug 4679556
27 * @summary Tests for duplication of some kind instances
28 * @author Sergey Malenkov, Mark Davidson, Philip Milne
29 */
30
31import java.beans.DefaultPersistenceDelegate;
32import java.beans.Encoder;
33import java.beans.Expression;
34import java.beans.XMLEncoder;
35
36/**
37 * Demonstrates the archiver bug, where the XMLEncoder duplicates
38 * the instance of class A because it is required as the target of
39 * a factory method (to produce an instance of class C).
40 * See the output in the file Test.xml for the results and note
41 * the (invalid) forward reference to the instance of class C.
42 *
43 * TO FIX
44 *
45 * Move the first line of the XMLEncoder::mark(Statement method)
46 * to the end of the method.
47 * I.e. replace the mark() method in XMLEncoder with this:
48 * <pre>private void mark(Statement stm) {
49 * Object[] args = stm.getArguments();
50 * for (int i = 0; i < args.length; i++) {
51 * Object arg = args[i];
52 * mark(arg, true);
53 * }
54 * mark(stm.getTarget(), false);
55 * }</pre>
56 *
57 * VALID ARCHIVE (WITH FIX):
58 * <pre>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
59 * &lt;java version="1.4.0" class="java.beans.XMLDecoder"&gt;
60 * &lt;object class="TestDuplicates$A"&gt;
61 * &lt;void id="TestDuplicates$C0" method="createC"/&gt;
62 * &lt;void property="x"&gt;
63 * &lt;void property="x"&gt;
64 * &lt;object idref="TestDuplicates$C0"/&gt;
65 * &lt;/void&gt;
66 * &lt;/void&gt;
67 * &lt;/object&gt;
68 * &lt;/java&gt;</pre>
69 *
70 * INVALID ARCHIVE (WITHOUT FIX):
71 * &lt;object class="TestDuplicates$A"&gt;
72 * &lt;void property="x"&gt;
73 * &lt;void property="x"&gt;
74 * &lt;void class="TestDuplicates$A"&gt;
75 * &lt;void property="x"&gt;
76 * &lt;void property="x"&gt;
77 * &lt;object idref="TestDuplicates$C0"/&gt;
78 * &lt;/void&gt;
79 * &lt;/void&gt;
80 * &lt;void id="TestDuplicates$C0" method="createC"/&gt;
81 * &lt;/void&gt;
82 * &lt;object idref="TestDuplicates$C0"/&gt;
83 * &lt;/void&gt;
84 * &lt;/void&gt;
85 * &lt;void id="TestDuplicates$C0" method="createC"/&gt;
86 * &lt;/object&gt;
87 * &lt;/java&gt;</pre>
88 */
89public class Test4679556 extends AbstractTest {
90 public static void main(String[] args) {
91 new Test4679556().test(true);
92 }
93
94 protected Object getObject() {
95 A a = new A();
96 B b = (B) a.getX();
97 b.setX(a.createC());
98 return a;
99 }
100
101 protected Object getAnotherObject() {
102 return new A();
103 }
104
105 protected void initialize(XMLEncoder encoder) {
106 encoder.setExceptionListener(this);
107 encoder.setPersistenceDelegate(C.class, new DefaultPersistenceDelegate() {
108 protected Expression instantiate(Object oldInstance, Encoder out) {
109 C c = (C) oldInstance;
110 return new Expression(c, c.getX(), "createC", new Object[] {});
111 }
112 });
113 }
114
115 public static class Base {
116 private Object x;
117
118 public Object getX() {
119 return this.x;
120 }
121
122 public void setX(Object x) {
123 this.x = x;
124 }
125 }
126
127 public static class A extends Base {
128 public A() {
129 setX(new B());
130 }
131
132 public C createC() {
133 return new C(this);
134 }
135 }
136
137 public static class B extends Base {
138 }
139
140 public static class C extends Base {
141 private C(Object x) {
142 setX(x);
143 }
144 }
145}