1/*
2 * Copyright (c) 2007, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24/*
25 * @test
26 * @bug 6187118
27 * @summary Tests encoding of immutable list that creates itself
28 * @author Sergey Malenkov
29 */
30
31import java.beans.Encoder;
32import java.beans.Expression;
33import java.beans.PersistenceDelegate;
34import java.beans.XMLEncoder;
35
36import java.util.ArrayList;
37import java.util.Collections;
38import java.util.Iterator;
39import java.util.List;
40
41public final class Test6187118 extends AbstractTest {
42    public static void main(String[] args) {
43        new Test6187118().test(true);
44    }
45
46    protected ImmutableList<String> getObject() {
47        return new ImmutableList<String>();
48    }
49
50    protected ImmutableList<String> getAnotherObject() {
51        return new ImmutableList<String>().add("1").add("2").add("3").add("4");
52    }
53
54    protected void initialize(XMLEncoder encoder) {
55        encoder.setPersistenceDelegate(
56                ImmutableList.class,
57                new PersistenceDelegate() {
58                    protected boolean mutatesTo(Object oldInstance, Object newInstance) {
59                        return oldInstance.equals(newInstance);
60                    }
61
62                    protected Expression instantiate(Object oldInstance, Encoder out) {
63                        ImmutableList list = (ImmutableList) oldInstance;
64                        if (!list.hasEntries()) {
65                            return getExpression(oldInstance, ImmutableList.class, "new");
66                        }
67                        Object object = list.getLast();
68                        ImmutableList shortenedList = list.removeLast();
69                        return getExpression(oldInstance, shortenedList, "add", object);
70                    }
71
72                    private Expression getExpression(Object value, Object target, String method, Object... args) {
73                        return new Expression(value, target, method, args);
74                    }
75                }
76        );
77    }
78
79    public static final class ImmutableList<T> implements Iterable {
80        private final List<T> list = new ArrayList<T>();
81
82        public ImmutableList() {
83        }
84
85        private ImmutableList(Iterable<T> iterable) {
86            for (T object : iterable) {
87                this.list.add(object);
88            }
89        }
90
91        public Iterator<T> iterator() {
92            return Collections.unmodifiableList(this.list).iterator();
93        }
94
95        public ImmutableList<T> add(T object) {
96            ImmutableList<T> list = new ImmutableList<T>(this.list);
97            list.list.add(object);
98            return list;
99        }
100
101        public ImmutableList<T> removeLast() {
102            ImmutableList<T> list = new ImmutableList<T>(this.list);
103            int size = list.list.size();
104            if (0 < size) {
105                list.list.remove(size - 1);
106            }
107            return list;
108        }
109
110        public T getLast() {
111            int size = this.list.size();
112            return (0 < size)
113                    ? this.list.get(size - 1)
114                    : null;
115        }
116
117        public boolean hasEntries() {
118            return 0 < this.list.size();
119        }
120
121        public boolean equals(Object object) {
122            if (object instanceof ImmutableList) {
123                ImmutableList list = (ImmutableList) object;
124                return this.list.equals(list.list);
125            }
126            return false;
127        }
128
129        public int hashCode() {
130            return this.list.hashCode();
131        }
132
133        public String toString() {
134            return this.list.toString();
135        }
136    }
137}
138