1/*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements.  See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License.  You may obtain a copy of the License at
8 *
9 *     http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18package org.apache.harmony.luni.tests.java.io;
19
20import java.io.ByteArrayInputStream;
21import java.io.ByteArrayOutputStream;
22import java.io.IOException;
23import java.io.InputStream;
24import java.io.InvalidClassException;
25import java.io.ObjectInputStream;
26import java.io.ObjectOutputStream;
27import java.io.ObjectStreamClass;
28import java.io.ObjectStreamException;
29import java.io.Serializable;
30import java.util.ArrayList;
31
32import junit.framework.TestCase;
33
34import org.apache.harmony.testframework.serialization.SerializationTest;
35
36public class ObjectInputStream2Test extends TestCase {
37
38    public void test_readUnshared() throws IOException, ClassNotFoundException {
39        // Regression test for HARMONY-819
40        ByteArrayOutputStream baos = new ByteArrayOutputStream();
41        try {
42            ObjectOutputStream oos = new ObjectOutputStream(baos);
43            oos.writeObject("abc");
44            oos.writeObject("abc");
45            oos.close();
46
47            ObjectInputStream ois = new ObjectInputStream(
48                    new ByteArrayInputStream(baos.toByteArray()));
49            ois.readUnshared();
50            ois.readObject();
51            ois.close();
52            fail("Expected ObjectStreamException");
53        } catch (ObjectStreamException e) {
54            // expected
55        }
56    }
57
58    /**
59     * Micro-scenario of de/serialization of an object with non-serializable
60     * superclass. The super-constructor only should be invoked on the
61     * deserialized instance.
62     */
63    public void test_readObject_Hierarchy() throws IOException,
64            ClassNotFoundException {
65        ByteArrayOutputStream baos = new ByteArrayOutputStream();
66
67        ObjectOutputStream oos = new ObjectOutputStream(baos);
68        oos.writeObject(new B());
69        oos.close();
70
71        ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(
72                baos.toByteArray()));
73        B b = (B) ois.readObject();
74        ois.close();
75
76        assertTrue("should construct super", A.list.contains(b));
77        assertFalse("should not construct self", B.list.contains(b));
78        assertEquals("super field A.s", A.DEFAULT, ((A) b).s);
79        assertNull("transient field B.s", b.s);
80    }
81
82    /**
83     * @tests {@link java.io.ObjectInputStream#readNewLongString()}
84     */
85    public void test_readNewLongString() throws Exception {
86        LongString longString = new LongString();
87        SerializationTest.verifySelf(longString);
88    }
89
90    @SuppressWarnings("serial")
91    private static class LongString implements Serializable {
92        String lString;
93
94        public LongString() {
95            StringBuilder builder = new StringBuilder();
96            // construct a string whose length > 64K
97            for (int i = 0; i < 65636; i++) {
98                builder.append('1');
99            }
100            lString = builder.toString();
101        }
102
103        @Override
104        public boolean equals(Object o) {
105            if (o == this) {
106                return true;
107            }
108            if (o instanceof LongString) {
109                LongString l = (LongString) o;
110                return l.lString.equals(l.lString);
111            }
112            return true;
113        }
114
115        @Override
116        public int hashCode() {
117            return lString.hashCode();
118        }
119    }
120
121    static class A {
122        static final ArrayList<A> list = new ArrayList<A>();
123        String s;
124        public static final String DEFAULT = "aaa";
125
126        public A() {
127            s = DEFAULT;
128            list.add(this);
129        }
130    }
131
132    static class B extends A implements Serializable {
133        private static final long serialVersionUID = 1L;
134        static final ArrayList<A> list = new ArrayList<A>();
135        transient String s;
136
137        public B() {
138            s = "bbb";
139            list.add(this);
140        }
141    }
142
143    class OIS extends ObjectInputStream {
144
145        OIS() throws IOException {
146            super();
147        }
148
149        void test() throws ClassNotFoundException, IOException {
150            readClassDescriptor();
151        }
152
153    }
154
155    public void test_readClassDescriptor() throws ClassNotFoundException,
156            IOException {
157        try {
158            new OIS().test();
159            fail("Should throw NullPointerException");
160        } catch (NullPointerException e) {
161            // expected
162        }
163    }
164
165    static class TestObjectInputStream extends ObjectInputStream {
166        public TestObjectInputStream(InputStream in) throws IOException {
167            super(in);
168        }
169
170        @Override
171        @SuppressWarnings("unchecked")
172        protected Class resolveClass(ObjectStreamClass desc)
173                throws IOException, ClassNotFoundException {
174            if (desc.getName().endsWith("ObjectInputStream2Test$TestClass1")) {
175                return TestClass2.class;
176            }
177            return super.resolveClass(desc);
178        }
179    }
180
181    static class TestClass1 implements Serializable {
182        private static final long serialVersionUID = 11111L;
183        int i = 0;
184    }
185
186    static class TestClass2 implements Serializable {
187        private static final long serialVersionUID = 11111L;
188        int i = 0;
189    }
190
191    public void test_resolveClass_invalidClassName() throws Exception {
192        // Regression test for HARMONY-1920
193        TestClass1 to1 = new TestClass1();
194        ByteArrayOutputStream baos = new ByteArrayOutputStream();
195        ObjectOutputStream oos = new ObjectOutputStream(baos);
196        ByteArrayInputStream bais;
197        ObjectInputStream ois;
198
199        to1.i = 555;
200        oos.writeObject(to1);
201        oos.flush();
202        byte[] bytes = baos.toByteArray();
203        bais = new ByteArrayInputStream(bytes);
204        ois = new TestObjectInputStream(bais);
205
206        try {
207            ois.readObject();
208            fail("Should throw InvalidClassException");
209        } catch (InvalidClassException ice) {
210            // Excpected
211        }
212    }
213}
214