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