001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     *
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    package org.apache.commons.fileupload;
018    
019    import java.io.IOException;
020    import java.io.OutputStream;
021    import java.io.ByteArrayInputStream;
022    import java.io.ByteArrayOutputStream;
023    import java.io.ObjectInputStream;
024    import java.io.ObjectOutputStream;
025    
026    import junit.framework.TestCase;
027    import org.apache.commons.fileupload.disk.DiskFileItemFactory;
028    
029    
030    /**
031     * Serialization Unit tests for 
032     *  {@link org.apache.commons.fileupload.disk.DiskFileItem}.
033     */
034    public class DiskFileItemSerializeTest extends TestCase
035     {
036    
037        /**
038         * Content type for regular form items.
039         */
040        private static final String textContentType = "text/plain";
041    
042        /**
043         * Content type for file uploads.
044         */
045        private static final String fileContentType = "application/octet-stream";
046    
047        /**
048         * Very low threshold for testing memory versus disk options.
049         */
050        private static final int threshold = 16;
051    
052        /**
053         * Standard JUnit test case constructor.
054         *
055         * @param name The name of the test case.
056         */
057        public DiskFileItemSerializeTest(String name)
058        {
059            super(name);
060        }
061    
062        /**
063         * Test creation of a field for which the amount of data falls below the
064         * configured threshold.
065         */
066        public void testBelowThreshold()
067        {
068    
069            // Create the FileItem
070            byte[] testFieldValueBytes = createContentBytes(threshold - 1);
071            FileItem item = createFileItem(testFieldValueBytes);
072    
073            // Check state is as expected
074            assertTrue("Initial: in memory", item.isInMemory());
075            assertEquals("Initial: size", item.getSize(), testFieldValueBytes.length);
076            compareBytes("Initial", item.get(), testFieldValueBytes);
077    
078            // Serialize & Deserialize
079            try
080            {
081                FileItem newItem = (FileItem)serializeDeserialize(item);
082    
083                // Test deserialized content is as expected
084                assertTrue("Check in memory", newItem.isInMemory());
085                compareBytes("Check", testFieldValueBytes, newItem.get());
086    
087                // Compare FileItem's (except byte[])
088                compareFileItems(item, newItem);
089    
090            }
091            catch(Exception e)
092            {
093                fail("Error Serializing/Deserializing: " + e);
094            }
095    
096    
097        }
098    
099        /**
100         * Test creation of a field for which the amount of data equals the
101         * configured threshold.
102         */
103        public void testThreshold() {
104            // Create the FileItem
105            byte[] testFieldValueBytes = createContentBytes(threshold);
106            FileItem item = createFileItem(testFieldValueBytes);
107    
108            // Check state is as expected
109            assertTrue("Initial: in memory", item.isInMemory());
110            assertEquals("Initial: size", item.getSize(), testFieldValueBytes.length);
111            compareBytes("Initial", item.get(), testFieldValueBytes);
112    
113    
114            // Serialize & Deserialize
115            try
116            {
117                FileItem newItem = (FileItem)serializeDeserialize(item);
118    
119                // Test deserialized content is as expected
120                assertTrue("Check in memory", newItem.isInMemory());
121                compareBytes("Check", testFieldValueBytes, newItem.get());
122    
123                // Compare FileItem's (except byte[])
124                compareFileItems(item, newItem);
125    
126            }
127            catch(Exception e)
128            {
129                fail("Error Serializing/Deserializing: " + e);
130            }
131        }
132    
133        /**
134         * Test creation of a field for which the amount of data falls above the
135         * configured threshold.
136         */
137        public void testAboveThreshold() {
138    
139            // Create the FileItem
140            byte[] testFieldValueBytes = createContentBytes(threshold + 1);
141            FileItem item = createFileItem(testFieldValueBytes);
142    
143            // Check state is as expected
144            assertFalse("Initial: in memory", item.isInMemory());
145            assertEquals("Initial: size", item.getSize(), testFieldValueBytes.length);
146            compareBytes("Initial", item.get(), testFieldValueBytes);
147    
148            // Serialize & Deserialize
149            try
150            {
151                FileItem newItem = (FileItem)serializeDeserialize(item);
152    
153                // Test deserialized content is as expected
154                assertFalse("Check in memory", newItem.isInMemory());
155                compareBytes("Check", testFieldValueBytes, newItem.get());
156    
157                // Compare FileItem's (except byte[])
158                compareFileItems(item, newItem);
159    
160            }
161            catch(Exception e)
162            {
163                fail("Error Serializing/Deserializing: " + e);
164            }
165        }
166    
167        /**
168         * Compare FileItem's (except the byte[] content)
169         */
170        private void compareFileItems(FileItem origItem, FileItem newItem) {
171            assertTrue("Compare: is in Memory",   origItem.isInMemory()   == newItem.isInMemory());
172            assertTrue("Compare: is Form Field",  origItem.isFormField()  == newItem.isFormField());
173            assertEquals("Compare: Field Name",   origItem.getFieldName(),   newItem.getFieldName());
174            assertEquals("Compare: Content Type", origItem.getContentType(), newItem.getContentType());
175            assertEquals("Compare: File Name",    origItem.getName(),        newItem.getName());
176        }
177    
178        /**
179         * Compare content bytes.
180         */
181        private void compareBytes(String text, byte[] origBytes, byte[] newBytes) {
182            if (origBytes == null) {
183                fail(text + " origBytes are null");
184            }
185            if (newBytes == null) {
186                fail(text + " newBytes are null");
187            }
188            assertEquals(text + " byte[] length", origBytes.length, newBytes.length);
189            for (int i = 0; i < origBytes.length; i++) {
190                assertEquals(text + " byte[" + i + "]", origBytes[i], newBytes[i]);
191            }
192        }
193    
194        /**
195         * Create content bytes of a specified size.
196         */
197        private byte[] createContentBytes(int size) {
198            StringBuffer buffer = new StringBuffer(size);
199            byte count = 0;
200            for (int i = 0; i < size; i++) {
201                buffer.append(count+"");
202                count++;
203                if (count > 9) {
204                    count = 0;
205                }
206            }
207            return buffer.toString().getBytes();
208        }
209    
210        /**
211         * Create a FileItem with the specfied content bytes.
212         */
213        private FileItem createFileItem(byte[] contentBytes) {
214            FileItemFactory factory = new DiskFileItemFactory(threshold, null);
215            String textFieldName = "textField";
216    
217            FileItem item = factory.createItem(
218                    textFieldName,
219                    textContentType,
220                    true,
221                    "My File Name"
222            );
223            try
224            {
225                OutputStream os = item.getOutputStream();
226                os.write(contentBytes);
227                os.close();
228            }
229            catch(IOException e)
230            {
231                fail("Unexpected IOException" + e);
232            }
233    
234            return item;
235    
236        }
237    
238        /**
239         * Do serialization and deserialization.
240         */
241        private Object serializeDeserialize(Object target) {
242    
243            // Serialize the test object
244            ByteArrayOutputStream baos = new ByteArrayOutputStream();
245            try {
246                ObjectOutputStream oos = new ObjectOutputStream(baos);
247                oos.writeObject(target);
248                oos.flush();
249                oos.close();
250            } catch (Exception e) {
251                fail("Exception during serialization: " + e);
252            }
253    
254            // Deserialize the test object
255            Object result = null;
256            try {
257                ByteArrayInputStream bais =
258                    new ByteArrayInputStream(baos.toByteArray());
259                ObjectInputStream ois = new ObjectInputStream(bais);
260                result = ois.readObject();
261                bais.close();
262            } catch (Exception e) {
263                fail("Exception during deserialization: " + e);
264            }
265            return result;
266    
267        }
268    
269    }