1   /*
2    * Copyright 2005 The Apache Software Foundation
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 org.apache.commons.fileupload;
17  
18  import java.io.File;
19  import java.io.IOException;
20  import java.io.OutputStream;
21  import java.io.ByteArrayInputStream;
22  import java.io.ByteArrayOutputStream;
23  import java.io.ObjectInputStream;
24  import java.io.ObjectOutputStream;
25  import java.util.Arrays;
26  
27  import junit.framework.TestCase;
28  import org.apache.commons.fileupload.disk.DiskFileItem;
29  import org.apache.commons.fileupload.disk.DiskFileItemFactory;
30  
31  
32  /***
33   * Serialization Unit tests for 
34   *  {@link org.apache.commons.fileupload.disk.DiskFileItemTest}.
35   */
36  public class DiskFileItemSerializeTest extends TestCase
37   {
38  
39      /***
40       * Content type for regular form items.
41       */
42      private static final String textContentType = "text/plain";
43  
44      /***
45       * Content type for file uploads.
46       */
47      private static final String fileContentType = "application/octet-stream";
48  
49      /***
50       * Very low threshold for testing memory versus disk options.
51       */
52      private static final int threshold = 16;
53  
54      /***
55       * Standard JUnit test case constructor.
56       *
57       * @param name The name of the test case.
58       */
59      public DiskFileItemSerializeTest(String name)
60      {
61          super(name);
62      }
63  
64      /***
65       * Test creation of a field for which the amount of data falls below the
66       * configured threshold.
67       */
68      public void testBelowThreshold()
69      {
70  
71          // Create the FileItem
72          byte[] testFieldValueBytes = createContentBytes(threshold - 1);
73          FileItem item = createFileItem(testFieldValueBytes);
74  
75          // Check state is as expected
76          assertTrue("Initial: in memory", item.isInMemory());
77          assertEquals("Initial: size", item.getSize(), testFieldValueBytes.length);
78          compareBytes("Initial", item.get(), testFieldValueBytes);
79  
80          // Serialize & Deserialize
81          try
82          {
83              FileItem newItem = (FileItem)serializeDeserialize(item);
84  
85              // Test deserialized content is as expected
86              assertTrue("Check in memory", newItem.isInMemory());
87              compareBytes("Check", testFieldValueBytes, newItem.get());
88  
89              // Compare FileItem's (except byte[])
90              compareFileItems(item, newItem);
91  
92          }
93          catch(Exception e)
94          {
95              fail("Error Serializing/Deserializing: " + e);
96          }
97  
98  
99      }
100 
101     /***
102      * Test creation of a field for which the amount of data equals the
103      * configured threshold.
104      */
105     public void testThreshold() {
106         // Create the FileItem
107         byte[] testFieldValueBytes = createContentBytes(threshold);
108         FileItem item = createFileItem(testFieldValueBytes);
109 
110         // Check state is as expected
111         assertTrue("Initial: in memory", item.isInMemory());
112         assertEquals("Initial: size", item.getSize(), testFieldValueBytes.length);
113         compareBytes("Initial", item.get(), testFieldValueBytes);
114 
115 
116         // Serialize & Deserialize
117         try
118         {
119             FileItem newItem = (FileItem)serializeDeserialize(item);
120 
121             // Test deserialized content is as expected
122             assertTrue("Check in memory", newItem.isInMemory());
123             compareBytes("Check", testFieldValueBytes, newItem.get());
124 
125             // Compare FileItem's (except byte[])
126             compareFileItems(item, newItem);
127 
128         }
129         catch(Exception e)
130         {
131             fail("Error Serializing/Deserializing: " + e);
132         }
133     }
134 
135     /***
136      * Test creation of a field for which the amount of data falls above the
137      * configured threshold.
138      */
139     public void testAboveThreshold() {
140 
141         // Create the FileItem
142         byte[] testFieldValueBytes = createContentBytes(threshold + 1);
143         FileItem item = createFileItem(testFieldValueBytes);
144 
145         // Check state is as expected
146         assertFalse("Initial: in memory", item.isInMemory());
147         assertEquals("Initial: size", item.getSize(), testFieldValueBytes.length);
148         compareBytes("Initial", item.get(), testFieldValueBytes);
149 
150         // Serialize & Deserialize
151         try
152         {
153             FileItem newItem = (FileItem)serializeDeserialize(item);
154 
155             // Test deserialized content is as expected
156             assertFalse("Check in memory", newItem.isInMemory());
157             compareBytes("Check", testFieldValueBytes, newItem.get());
158 
159             // Compare FileItem's (except byte[])
160             compareFileItems(item, newItem);
161 
162         }
163         catch(Exception e)
164         {
165             fail("Error Serializing/Deserializing: " + e);
166         }
167     }
168 
169     /***
170      * Compare FileItem's (except the byte[] content)
171      */
172     private void compareFileItems(FileItem origItem, FileItem newItem) {
173         assertTrue("Compare: is in Memory",   origItem.isInMemory()   == newItem.isInMemory());
174         assertTrue("Compare: is Form Field",  origItem.isFormField()  == newItem.isFormField());
175         assertEquals("Compare: Field Name",   origItem.getFieldName(),   newItem.getFieldName());
176         assertEquals("Compare: Content Type", origItem.getContentType(), newItem.getContentType());
177         assertEquals("Compare: File Name",    origItem.getName(),        newItem.getName());
178     }
179 
180     /***
181      * Compare content bytes.
182      */
183     private void compareBytes(String text, byte[] origBytes, byte[] newBytes) {
184         if (origBytes == null) {
185             fail(text + " origBytes are null");
186         }
187         if (newBytes == null) {
188             fail(text + " newBytes are null");
189         }
190         assertEquals(text + " byte[] length", origBytes.length, newBytes.length);
191         for (int i = 0; i < origBytes.length; i++) {
192             assertEquals(text + " byte[" + i + "]", origBytes[i], newBytes[i]);
193         }
194     }
195 
196     /***
197      * Create content bytes of a specified size.
198      */
199     private byte[] createContentBytes(int size) {
200         StringBuffer buffer = new StringBuffer(size);
201         byte count = 0;
202         for (int i = 0; i < size; i++) {
203             buffer.append(count+"");
204             count++;
205             if (count > 9) {
206                 count = 0;
207             }
208         }
209         return buffer.toString().getBytes();
210     }
211 
212     /***
213      * Create a FileItem with the specfied content bytes.
214      */
215     private FileItem createFileItem(byte[] contentBytes) {
216         FileItemFactory factory = new DiskFileItemFactory(threshold, null);
217         String textFieldName = "textField";
218 
219         FileItem item = factory.createItem(
220                 textFieldName,
221                 textContentType,
222                 true,
223                 "My File Name"
224         );
225         try
226         {
227             OutputStream os = item.getOutputStream();
228             os.write(contentBytes);
229             os.close();
230         }
231         catch(IOException e)
232         {
233             fail("Unexpected IOException" + e);
234         }
235 
236         return item;
237 
238     }
239 
240     /***
241      * Do serialization and deserialization.
242      */
243     private Object serializeDeserialize(Object target) {
244 
245         // Serialize the test object
246         ByteArrayOutputStream baos = new ByteArrayOutputStream();
247         try {
248             ObjectOutputStream oos = new ObjectOutputStream(baos);
249             oos.writeObject(target);
250             oos.flush();
251             oos.close();
252         } catch (Exception e) {
253             fail("Exception during serialization: " + e);
254         }
255 
256         // Deserialize the test object
257         Object result = null;
258         try {
259             ByteArrayInputStream bais =
260                 new ByteArrayInputStream(baos.toByteArray());
261             ObjectInputStream ois = new ObjectInputStream(bais);
262             result = ois.readObject();
263             bais.close();
264         } catch (Exception e) {
265             fail("Exception during deserialization: " + e);
266         }
267         return result;
268 
269     }
270 
271 }