View Javadoc

1   /*
2    * Copyright 2008-2013 smartics, Kronseder & Reiner GmbH
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package de.smartics.util.test.io;
17  
18  import java.io.ByteArrayInputStream;
19  import java.io.ByteArrayOutputStream;
20  import java.io.IOException;
21  import java.io.ObjectInputStream;
22  import java.io.ObjectOutputStream;
23  
24  import org.apache.commons.io.IOUtils;
25  import static org.junit.Assert.fail;
26  
27  /**
28   * Provides utility functions to help on tests dealing with serialization.
29   * <p>
30   * The example shows the typical usage of {@link #runSerialization(Object)}:
31   * </p> {@example "Example Usage Error" final MyClass uut = new MyClass(); ...
32   * SerialTestUtils.runSerialization(uut);
33   * assertTrue("Serialization successful.", true);}
34   * <p>
35   * If the serialization is not successful, an exception is thrown. If you do not
36   * want an error to be reported by JUnit you have catch the exception and fail.
37   * </p> {@example "Example Usage Failure" final MyClass uut = new MyClass(); ...
38   * SerialTestUtils.runSerializationQuietly(uut);
39   * assertTrue("Serialization successful.", true);}
40   *
41   * @author <a href="mailto:robert.reiner@smartics.de">Robert Reiner</a>
42   * @version $Revision:591 $
43   */
44  public final class SerialTestUtils
45  {
46    // ********************************* Fields *********************************
47  
48    // --- constants ------------------------------------------------------------
49  
50    // --- members --------------------------------------------------------------
51  
52    // ****************************** Initializer *******************************
53  
54    // ****************************** Constructors ******************************
55  
56    /**
57     * Utility class.
58     */
59    private SerialTestUtils()
60    {
61    }
62  
63    // ****************************** Inner Classes *****************************
64  
65    // ********************************* Methods ********************************
66  
67    // --- init -----------------------------------------------------------------
68  
69    // --- get&set --------------------------------------------------------------
70  
71    // --- business -------------------------------------------------------------
72  
73    /**
74     * Runs the serialization test and signals a fail to the JUnit runtime.
75     *
76     * @param <T> the type of the instance to read and write.
77     * @param uut the unit under test to serialize and deserialized.
78     * @return the serialized and deserialized object. Allows the client to check
79     *         the internals if required.
80     */
81    public static <T> T runSerializationQuietly(final T uut)
82    {
83      try
84      {
85        return runSerialization(uut);
86      }
87      catch (final IOException e)
88      {
89        fail("Serialization failed.");
90      }
91      catch (final ClassNotFoundException e)
92      {
93        fail("Serialization failed since class cannot be found: "
94             + e.getMessage());
95      }
96      return null; // never happens.
97    }
98  
99    /**
100    * Test the serialization and deserialization of the unit under test.
101    *
102    * @param <T> the type of the instance to read and write.
103    * @param uut the unit under test to serialize and deserialized.
104    * @return the serialized and deserialized object. Allows the client to check
105    *         the internals if required.
106    * @throws IOException if the object cannot be serialized or deserialized.
107    * @throws ClassNotFoundException if the class for the deserialized object
108    *           cannot be found.
109    */
110   public static <T> T runSerialization(final T uut) throws IOException,
111     ClassNotFoundException
112   {
113     final byte[] data = writeObject(uut);
114 
115     // The following specifies the type T because of a bug in the javac
116     // (including version 1.6.0_12) that prevents proper type inference.
117     // * http://forums.sun.com/thread.jspa?messageID=4196171
118     // * http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6302954
119     return SerialTestUtils.<T> readObject(data);
120   }
121 
122   /**
123    * Reads the object from the given byte array.
124    *
125    * @param <T> the type of the instance to read.
126    * @param data the serialized object to deserialize.
127    * @return the deserialized object.
128    * @throws IOException if the object cannot be deserialized.
129    * @throws ClassNotFoundException if the class for the deserialized object
130    *           cannot be found.
131    */
132   @SuppressWarnings("unchecked")
133   public static <T> T readObject(final byte[] data) throws IOException,
134     ClassNotFoundException
135   {
136     final ByteArrayInputStream in = new ByteArrayInputStream(data);
137     ObjectInputStream ois = null; // NOPMD resource release pattern
138     try
139     {
140       ois = new ObjectInputStream(in);
141       final T result = (T) ois.readObject();
142       return result;
143     }
144     finally
145     {
146       IOUtils.closeQuietly(ois);
147     }
148   }
149 
150   /**
151    * Writes the given object to an byte array.
152    *
153    * @param <T> the type of the instance to write.
154    * @param uut the unit under test to serialize.
155    * @param bufferSize the size of the in-memory buffer to write to.
156    * @return the serialized object in a byte array.
157    * @throws IOException if the object cannot be serialized.
158    */
159   public static <T> byte[] writeObject(final T uut, final int bufferSize)
160     throws IOException
161   {
162     final ByteArrayOutputStream out = new ByteArrayOutputStream(bufferSize);
163     ObjectOutputStream oos = null; // NOPMD resource release pattern
164     try
165     {
166       oos = new ObjectOutputStream(out);
167       oos.writeObject(uut);
168     }
169     finally
170     {
171       IOUtils.closeQuietly(oos);
172     }
173     return out.toByteArray();
174   }
175 
176   /**
177    * Writes the given object to an byte array. The size of the in-memory buffer
178    * is set to 1024 bytes.
179    *
180    * @param <T> the type of the instance to write.
181    * @param uut the unit under test to serialize.
182    * @return the serialized object in a byte array.
183    * @throws IOException if the object cannot be serialized.
184    */
185   public static <T> byte[] writeObject(final T uut) throws IOException
186   {
187     // The following specifies the type T because of a bug in the javac
188     // (including version 1.6.0_12) that prevents proper type inference.
189     // * http://forums.sun.com/thread.jspa?messageID=4196171
190     // * http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6302954
191     return SerialTestUtils.<T> writeObject(uut, 1024);
192   }
193 
194   // --- object basics --------------------------------------------------------
195 
196 }