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 tests.util;
19
20import java.io.ByteArrayInputStream;
21import java.io.ByteArrayOutputStream;
22import java.io.File;
23import java.io.FileOutputStream;
24import java.io.IOException;
25import java.io.InputStream;
26import java.io.ObjectInputStream;
27import java.io.ObjectOutputStream;
28import java.io.OutputStream;
29import java.net.URL;
30
31/**
32 * This class simplifies the serialization test.
33 */
34public class SerializationTester {
35
36    /*
37      * --------------------------------------------------------------------
38      * Class variables
39      * --------------------------------------------------------------------
40      */
41
42    // the last deserialized object
43    private static Object lastOutput = null;
44
45    /*
46      * -------------------------------------------------------------------
47      * Constructors
48      * -------------------------------------------------------------------
49      */
50
51    private SerializationTester() {
52
53    }
54
55    /*
56      * -------------------------------------------------------------------
57      * Methods
58      * -------------------------------------------------------------------
59      */
60
61    /**
62     * Serialize an object and then deserialize it.
63     *
64     * @param inputObject the input object
65     * @return the deserialized object
66     */
67    public static Object getDeserilizedObject(Object inputObject)
68            throws IOException, ClassNotFoundException {
69        ByteArrayOutputStream bos = new ByteArrayOutputStream();
70        ObjectOutputStream oos = new ObjectOutputStream(bos);
71        oos.writeObject(inputObject);
72        oos.close();
73
74        ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
75        ObjectInputStream ois = new ObjectInputStream(bis);
76        Object outputObject = ois.readObject();
77        lastOutput = outputObject;
78        ois.close();
79        return outputObject;
80    }
81
82    /**
83     * Tests the serialization and deserialization of const objects.
84     *
85     * @param inputObject A const object
86     * @return true if the deserialized object is the same as the input object,
87     *         otherwise false
88     * @throws Exception If any occurs.
89     */
90    public static boolean assertSame(Object inputObject) throws Exception {
91        return inputObject == getDeserilizedObject(inputObject);
92    }
93
94    /**
95     * Tests the serialization and deserialization of instance objects.
96     *
97     * @param inputObject An object
98     * @return true if the deserialized object is equal to the input object,
99     *         otherwise false
100     * @throws Exception If any occurs.
101     */
102    public static boolean assertEquals(Object inputObject) throws Exception {
103        return inputObject.equals(getDeserilizedObject(inputObject));
104    }
105
106    /**
107     * Tests the serialization compatibility with reference const objects.
108     *
109     * @param obj      the object to be checked
110     * @param fileName the serialization output file generated by reference
111     * @return true if compatible, otherwise false
112     * @throws Exception If any occurs.
113     */
114    public static boolean assertCompabilitySame(Object obj, String fileName)
115            throws Exception {
116        return obj == readObject(obj, fileName);
117    }
118
119    /**
120     * Tests the serialization compatibility with reference for instance
121     * objects.
122     *
123     * @param obj      the object to be checked
124     * @param fileName the serialization output file generated by reference
125     * @return true if compatible, otherwise false
126     * @throws Exception If any occurs.
127     */
128    public static boolean assertCompabilityEquals(Object obj, String fileName)
129            throws Exception {
130        return obj.equals(readObject(obj, fileName));
131    }
132
133    /**
134     * Deserialize an object from a file.
135     *
136     * @param obj      the object to be serialized if no serialization file is found
137     * @param fileName the serialization file
138     * @return the deserialized object
139     * @throws Exception If any occurs.
140     */
141    public static Object readObject(Object obj, String fileName)
142            throws Exception {
143        InputStream input = null;
144        ObjectInputStream oinput = null;
145        URL url = SerializationTester.class.getClassLoader().getResource(
146                fileName);
147        if (null == url) {
148            // serialization file does not exist, create one in the current dir
149            writeObject(obj, new File(fileName).getName());
150            throw new Error(
151                    "Serialization file does not exist, created in the current dir.");
152        }
153        input = url.openStream();
154        try {
155            oinput = new ObjectInputStream(input);
156            Object newObj = oinput.readObject();
157            return newObj;
158        } finally {
159            try {
160                if (null != oinput) {
161                    oinput.close();
162                }
163            } catch (Exception e) {
164                // ignore
165            }
166            try {
167                if (null != input) {
168                    input.close();
169                }
170            } catch (Exception e) {
171                // ignore
172            }
173        }
174    }
175
176    /*
177      * Creates a serialization output.
178      *
179      * @param obj the object to be serialized @param fileName the output file
180      * @throws Exception If any occurs.
181      */
182    public static void writeObject(Object obj, String fileName)
183            throws Exception {
184        // String path = SerializationTester.class.getResource(".").getPath();
185        // if (path.endsWith(".")) {
186        // path = path.substring(0, path.length() - 1);
187        // }
188        // if (!path.endsWith("/")) {
189        // path += "/";
190        // }
191        // path += fileName;
192        // System.out.println(path);
193        OutputStream output = null;
194        ObjectOutputStream ooutput = null;
195        try {
196            output = new FileOutputStream(fileName);
197            ooutput = new ObjectOutputStream(output);
198            ooutput.writeObject(obj);
199        } finally {
200            try {
201                if (null != ooutput) {
202                    ooutput.close();
203                }
204            } catch (Exception e) {
205                // ignore
206            }
207            try {
208                if (null != output) {
209                    output.close();
210                }
211            } catch (Exception e) {
212                // ignore
213            }
214        }
215    }
216
217    /**
218     * Gets the last deserialized object.
219     *
220     * @return the last deserialized object
221     */
222    public static Object getLastOutput() {
223        return lastOutput;
224    }
225
226    /*
227      * For test purpose.
228      */
229    public static void main(String[] args) {
230    }
231}
232