##### Coverage Report - org.apache.commons.fileupload.disk.DiskFileItem

Classes in this File | Line Coverage | Branch Coverage | Complexity
DiskFileItem |
69% | 81/116
60% | 30/50
| 2.4615384615384617;2.462

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.disk;
18 |  |
19 |  |
     import static java.lang.String.format;
20 |  |
21 |  |
     import java.io.ByteArrayInputStream;
22 |  |
     import java.io.File;
23 |  |
     import java.io.FileInputStream;
24 |  |
     import java.io.FileOutputStream;
25 |  |
     import java.io.IOException;
26 |  |
     import java.io.InputStream;
27 |  |
     import java.io.OutputStream;
28 |  |
     import java.io.UnsupportedEncodingException;
29 |  |
     import java.util.Map;
30 |  |
     import java.util.UUID;
31 |  |
     import java.util.concurrent.atomic.AtomicInteger;
32 |  |
33 |  |
     import org.apache.commons.fileupload.FileItem;
34 |  |
     import org.apache.commons.fileupload.FileItemHeaders;
35 |  |
     import org.apache.commons.fileupload.FileUploadException;
36 |  |
     import org.apache.commons.fileupload.ParameterParser;
37 |  |
     import org.apache.commons.fileupload.util.Streams;
38 |  |
     import org.apache.commons.io.FileUtils;
39 |  |
     import org.apache.commons.io.IOUtils;
40 |  |
     import org.apache.commons.io.output.DeferredFileOutputStream;
41 |  |
42 |  |
     /**
43 |  |
      * <p> The default implementation of the
44 |  |
      * {@link org.apache.commons.fileupload.FileItem FileItem} interface.
45 |  |
      *
46 |  |
      * <p> After retrieving an instance of this class from a {@link
47 |  |
      * DiskFileItemFactory} instance (see
48 |  |
      * {@link org.apache.commons.fileupload.servlet.ServletFileUpload
49 |  |
      * #parseRequest(javax.servlet.http.HttpServletRequest)}), you may
50 |  |
      * either request all contents of file at once using {@link #get()} or
51 |  |
      * request an {@link java.io.InputStream InputStream} with
52 |  |
      * {@link #getInputStream()} and process the file without attempting to load
53 |  |
      * it into memory, which may come handy with large files.
54 |  |
      *
55 |  |
      * <p>Temporary files, which are created for file items, should be
56 |  |
      * deleted later on. The best way to do this is using a
57 |  |
      * {@link org.apache.commons.io.FileCleaningTracker}, which you can set on the
58 |  |
      * {@link DiskFileItemFactory}. However, if you do use such a tracker,
59 |  |
      * then you must consider the following: Temporary files are automatically
60 |  |
      * deleted as soon as they are no longer needed. (More precisely, when the
61 |  |
      * corresponding instance of {@link java.io.File} is garbage collected.)
62 |  |
      * This is done by the so-called reaper thread, which is started and stopped
63 |  |
      * automatically by the {@link org.apache.commons.io.FileCleaningTracker} when
64 |  |
      * there are files to be tracked.
65 |  |
      * It might make sense to terminate that thread, for example, if
66 |  |
      * your web application ends. See the section on "Resource cleanup"
67 |  |
      * in the users guide of commons-fileupload.</p>
68 |  |
      *
69 |  |
      * @since FileUpload 1.1
70 |  |
      */
71 |  |
     public class DiskFileItem
72 |  |
         implements FileItem {
73 |  |
74 |  |
         // ----------------------------------------------------- Manifest constants
75 |  |
76 |  |
         /**
77 |  |
          * Default content charset to be used when no explicit charset
78 |  |
          * parameter is provided by the sender. Media subtypes of the
79 |  |
          * "text" type are defined to have a default charset value of
80 |  |
          * "ISO-8859-1" when received via HTTP.
81 |  |
          */
82 |  |
         public static final String DEFAULT_CHARSET = "ISO-8859-1";
83 |  |
84 |  |
         // ----------------------------------------------------------- Data members
85 |  |
86 |  |
         /**
87 |  |
          * UID used in unique file name generation.
88 |  |
          */
89 |  |
         private static final String UID =
90 | 1 |
                 UUID.randomUUID().toString().replace('-', '_');
91 |  |
92 |  |
         /**
93 |  |
          * Counter used in unique identifier generation.
94 |  |
          */
95 | 1 |
         private static final AtomicInteger COUNTER = new AtomicInteger(0);
96 |  |
97 |  |
         /**
98 |  |
          * The name of the form field as provided by the browser.
99 |  |
          */
100 |  |
         private String fieldName;
101 |  |
102 |  |
         /**
103 |  |
          * The content type passed by the browser, or <code>null</code> if
104 |  |
          * not defined.
105 |  |
          */
106 |  |
         private final String contentType;
107 |  |
108 |  |
         /**
109 |  |
          * Whether or not this item is a simple form field.
110 |  |
          */
111 |  |
         private boolean isFormField;
112 |  |
113 |  |
         /**
114 |  |
          * The original filename in the user's filesystem.
115 |  |
          */
116 |  |
         private final String fileName;
117 |  |
118 |  |
         /**
119 |  |
          * The size of the item, in bytes. This is used to cache the size when a
120 |  |
          * file item is moved from its original location.
121 |  |
          */
122 | 2174 |
         private long size = -1;
123 |  |
124 |  |
125 |  |
         /**
126 |  |
          * The threshold above which uploads will be stored on disk.
127 |  |
          */
128 |  |
         private final int sizeThreshold;
129 |  |
130 |  |
         /**
131 |  |
          * The directory in which uploaded files will be stored, if stored on disk.
132 |  |
          */
133 |  |
         private final File repository;
134 |  |
135 |  |
         /**
136 |  |
          * Cached contents of the file.
137 |  |
          */
138 |  |
         private byte[] cachedContent;
139 |  |
140 |  |
         /**
141 |  |
          * Output stream for this item.
142 |  |
          */
143 |  |
         private transient DeferredFileOutputStream dfos;
144 |  |
145 |  |
         /**
146 |  |
          * The temporary file to use.
147 |  |
          */
148 |  |
         private transient File tempFile;
149 |  |
150 |  |
         /**
151 |  |
          * The file items headers.
152 |  |
          */
153 |  |
         private FileItemHeaders headers;
154 |  |
155 |  |
         /**
156 |  |
          * Default content charset to be used when no explicit charset
157 |  |
          * parameter is provided by the sender.
158 |  |
          */
159 | 2174 |
         private String defaultCharset = DEFAULT_CHARSET;
160 |  |
161 |  |
         // ----------------------------------------------------------- Constructors
162 |  |
163 |  |
         /**
164 |  |
          * Constructs a new <code>DiskFileItem</code> instance.
165 |  |
          *
166 |  |
          * @param fieldName     The name of the form field.
167 |  |
          * @param contentType   The content type passed by the browser or
168 |  |
          *                      <code>null</code> if not specified.
169 |  |
          * @param isFormField   Whether or not this item is a plain form field, as
170 |  |
          *                      opposed to a file upload.
171 |  |
          * @param fileName      The original filename in the user's filesystem, or
172 |  |
          *                      <code>null</code> if not specified.
173 |  |
          * @param sizeThreshold The threshold, in bytes, below which items will be
174 |  |
          *                      retained in memory and above which they will be
175 |  |
          *                      stored as a file.
176 |  |
          * @param repository    The data repository, which is the directory in
177 |  |
          *                      which files will be created, should the item size
178 |  |
          *                      exceed the threshold.
179 |  |
          */
180 |  |
         public DiskFileItem(String fieldName,
181 |  |
                 String contentType, boolean isFormField, String fileName,
182 | 2174 |
                 int sizeThreshold, File repository) {
183 | 2174 |
             this.fieldName = fieldName;
184 | 2174 |
             this.contentType = contentType;
185 | 2174 |
             this.isFormField = isFormField;
186 | 2174 |
             this.fileName = fileName;
187 | 2174 |
             this.sizeThreshold = sizeThreshold;
188 | 2174 |
             this.repository = repository;
189 | 2174 |
         }
190 |  |
191 |  |
         // ------------------------------- Methods from javax.activation.DataSource
192 |  |
193 |  |
         /**
194 |  |
          * Returns an {@link java.io.InputStream InputStream} that can be
195 |  |
          * used to retrieve the contents of the file.
196 |  |
          *
197 |  |
          * @return An {@link java.io.InputStream InputStream} that can be
198 |  |
          *         used to retrieve the contents of the file.
199 |  |
          *
200 |  |
          * @throws IOException if an error occurs.
201 |  |
          */
202 |  |
         @Override
203 |  |
         public InputStream getInputStream()
204 |  |
             throws IOException {
205 | 0 |
             if (!isInMemory()) {
206 | 0 |
                 return new FileInputStream(dfos.getFile());
207 |  |
             }
208 |  |
209 | 0 |
             if (cachedContent == null) {
210 | 0 |
                 cachedContent = dfos.getData();
211 |  |
             }
212 | 0 |
             return new ByteArrayInputStream(cachedContent);
213 |  |
         }
214 |  |
215 |  |
         /**
216 |  |
          * Returns the content type passed by the agent or <code>null</code> if
217 |  |
          * not defined.
218 |  |
          *
219 |  |
          * @return The content type passed by the agent or <code>null</code> if
220 |  |
          *         not defined.
221 |  |
          */
222 |  |
         @Override
223 |  |
         public String getContentType() {
224 | 43 |
             return contentType;
225 |  |
         }
226 |  |
227 |  |
         /**
228 |  |
          * Returns the content charset passed by the agent or <code>null</code> if
229 |  |
          * not defined.
230 |  |
          *
231 |  |
          * @return The content charset passed by the agent or <code>null</code> if
232 |  |
          *         not defined.
233 |  |
          */
234 |  |
         public String getCharSet() {
235 | 35 |
             ParameterParser parser = new ParameterParser();
236 | 35 |
             parser.setLowerCaseNames(true);
237 |  |
             // Parameter parser can handle null input
238 | 35 |
             Map<String, String> params = parser.parse(getContentType(), ';');
239 | 35 |
             return params.get("charset");
240 |  |
         }
241 |  |
242 |  |
         /**
243 |  |
          * Returns the original filename in the client's filesystem.
244 |  |
          *
245 |  |
          * @return The original filename in the client's filesystem.
246 |  |
          * @throws org.apache.commons.fileupload.InvalidFileNameException The file name contains a NUL character,
247 |  |
          *   which might be an indicator of a security attack. If you intend to
248 |  |
          *   use the file name anyways, catch the exception and use
249 |  |
          *   {@link org.apache.commons.fileupload.InvalidFileNameException#getName()}.
250 |  |
          */
251 |  |
         @Override
252 |  |
         public String getName() {
253 | 19 |
             return Streams.checkFileName(fileName);
254 |  |
         }
255 |  |
256 |  |
         // ------------------------------------------------------- FileItem methods
257 |  |
258 |  |
         /**
259 |  |
          * Provides a hint as to whether or not the file contents will be read
260 |  |
          * from memory.
261 |  |
          *
262 |  |
          * @return <code>true</code> if the file contents will be read
263 |  |
          *         from memory; <code>false</code> otherwise.
264 |  |
          */
265 |  |
         @Override
266 |  |
         public boolean isInMemory() {
267 | 2432 |
             if (cachedContent != null) {
268 | 2 |
                 return true;
269 |  |
             }
270 | 2430 |
             return dfos.isInMemory();
271 |  |
         }
272 |  |
273 |  |
         /**
274 |  |
          * Returns the size of the file.
275 |  |
          *
276 |  |
          * @return The size of the file, in bytes.
277 |  |
          */
278 |  |
         @Override
279 |  |
         public long getSize() {
280 | 536 |
             if (size >= 0) {
281 | 0 |
                 return size;
282 | 536 |
             } else if (cachedContent != null) {
283 | 0 |
                 return cachedContent.length;
284 | 536 |
             } else if (dfos.isInMemory()) {
285 | 4 |
                 return dfos.getData().length;
286 |  |
             } else {
287 | 532 |
                 return dfos.getFile().length();
288 |  |
             }
289 |  |
         }
290 |  |
291 |  |
         /**
292 |  |
          * Returns the contents of the file as an array of bytes.  If the
293 |  |
          * contents of the file were not yet cached in memory, they will be
294 |  |
          * loaded from the disk storage and cached.
295 |  |
          *
296 |  |
          * @return The contents of the file as an array of bytes
297 |  |
          * or {@code null} if the data cannot be read
298 |  |
          */
299 |  |
         @Override
300 |  |
         public byte[] get() {
301 | 1451 |
             if (isInMemory()) {
302 | 922 |
                 if (cachedContent == null && dfos != null) {
303 | 920 |
                     cachedContent = dfos.getData();
304 |  |
                 }
305 | 922 |
                 return cachedContent;
306 |  |
             }
307 |  |
308 | 529 |
             byte[] fileData = new byte[(int) getSize()];
309 | 529 |
             InputStream fis = null;
310 |  |
311 |  |
             try {
312 | 529 |
                 fis = new FileInputStream(dfos.getFile());
313 | 529 |
                 IOUtils.readFully(fis, fileData);
314 | 0 |
             } catch (IOException e) {
315 | 0 |
                 fileData = null;
316 |  |
             } finally {
317 | 529 |
                 IOUtils.closeQuietly(fis);
318 | 529 |
             }
319 |  |
320 | 529 |
             return fileData;
321 |  |
         }
322 |  |
323 |  |
         /**
324 |  |
          * Returns the contents of the file as a String, using the specified
325 |  |
          * encoding.  This method uses {@link #get()} to retrieve the
326 |  |
          * contents of the file.
327 |  |
          *
328 |  |
          * @param charset The charset to use.
329 |  |
          *
330 |  |
          * @return The contents of the file, as a string.
331 |  |
          *
332 |  |
          * @throws UnsupportedEncodingException if the requested character
333 |  |
          *                                      encoding is not available.
334 |  |
          */
335 |  |
         @Override
336 |  |
         public String getString(final String charset)
337 |  |
             throws UnsupportedEncodingException {
338 | 0 |
             return new String(get(), charset);
339 |  |
         }
340 |  |
341 |  |
         /**
342 |  |
          * Returns the contents of the file as a String, using the default
343 |  |
          * character encoding.  This method uses {@link #get()} to retrieve the
344 |  |
          * contents of the file.
345 |  |
          *
346 |  |
          * <b>TODO</b> Consider making this method throw UnsupportedEncodingException.
347 |  |
          *
348 |  |
          * @return The contents of the file, as a string.
349 |  |
          */
350 |  |
         @Override
351 |  |
         public String getString() {
352 | 35 |
             byte[] rawdata = get();
353 | 35 |
             String charset = getCharSet();
354 | 35 |
             if (charset == null) {
355 | 35 |
                 charset = defaultCharset;
356 |  |
             }
357 |  |
             try {
358 | 35 |
                 return new String(rawdata, charset);
359 | 0 |
             } catch (UnsupportedEncodingException e) {
360 | 0 |
                 return new String(rawdata);
361 |  |
             }
362 |  |
         }
363 |  |
364 |  |
         /**
365 |  |
          * A convenience method to write an uploaded item to disk. The client code
366 |  |
          * is not concerned with whether or not the item is stored in memory, or on
367 |  |
          * disk in a temporary location. They just want to write the uploaded item
368 |  |
          * to a file.
369 |  |
          * <p>
370 |  |
          * This implementation first attempts to rename the uploaded item to the
371 |  |
          * specified destination file, if the item was originally written to disk.
372 |  |
          * Otherwise, the data will be copied to the specified file.
373 |  |
          * <p>
374 |  |
          * This method is only guaranteed to work <em>once</em>, the first time it
375 |  |
          * is invoked for a particular item. This is because, in the event that the
376 |  |
          * method renames a temporary file, that file will no longer be available
377 |  |
          * to copy or rename again at a later time.
378 |  |
          *
379 |  |
          * @param file The <code>File</code> into which the uploaded item should
380 |  |
          *             be stored.
381 |  |
          *
382 |  |
          * @throws Exception if an error occurs.
383 |  |
          */
384 |  |
         @Override
385 |  |
         public void write(File file) throws Exception {
386 | 0 |
             if (isInMemory()) {
387 | 0 |
                 FileOutputStream fout = null;
388 |  |
                 try {
389 | 0 |
                     fout = new FileOutputStream(file);
390 | 0 |
                     fout.write(get());
391 | 0 |
                     fout.close();
392 |  |
                 } finally {
393 | 0 |
                     IOUtils.closeQuietly(fout);
394 | 0 |
                 }
395 | 0 |
             } else {
396 | 0 |
                 File outputFile = getStoreLocation();
397 | 0 |
                 if (outputFile != null) {
398 |  |
                     // Save the length of the file
399 | 0 |
                     size = outputFile.length();
400 |  |
                     /*
401 |  |
                      * The uploaded file is being stored on disk
402 |  |
                      * in a temporary location so move it to the
403 |  |
                      * desired file.
404 |  |
                      */
405 | 0 |
                     FileUtils.moveFile(outputFile, file);
406 |  |
                 } else {
407 |  |
                     /*
408 |  |
                      * For whatever reason we cannot write the
409 |  |
                      * file to disk.
410 |  |
                      */
411 | 0 |
                     throw new FileUploadException(
412 |  |
                         "Cannot write uploaded file to disk!");
413 |  |
                 }
414 |  |
             }
415 | 0 |
         }
416 |  |
417 |  |
         /**
418 |  |
          * Deletes the underlying storage for a file item, including deleting any
419 |  |
          * associated temporary disk file. Although this storage will be deleted
420 |  |
          * automatically when the <code>FileItem</code> instance is garbage
421 |  |
          * collected, this method can be used to ensure that this is done at an
422 |  |
          * earlier time, thus preserving system resources.
423 |  |
          */
424 |  |
         @Override
425 |  |
         public void delete() {
426 | 707 |
             cachedContent = null;
427 | 707 |
             File outputFile = getStoreLocation();
428 | 707 |
             if (outputFile != null && !isInMemory() && outputFile.exists()) {
429 | 265 |
                 outputFile.delete();
430 |  |
             }
431 | 707 |
         }
432 |  |
433 |  |
         /**
434 |  |
          * Returns the name of the field in the multipart form corresponding to
435 |  |
          * this file item.
436 |  |
          *
437 |  |
          * @return The name of the form field.
438 |  |
          *
439 |  |
          * @see #setFieldName(java.lang.String)
440 |  |
          *
441 |  |
          */
442 |  |
         @Override
443 |  |
         public String getFieldName() {
444 | 1445 |
             return fieldName;
445 |  |
         }
446 |  |
447 |  |
         /**
448 |  |
          * Sets the field name used to reference this file item.
449 |  |
          *
450 |  |
          * @param fieldName The name of the form field.
451 |  |
          *
452 |  |
          * @see #getFieldName()
453 |  |
          *
454 |  |
          */
455 |  |
         @Override
456 |  |
         public void setFieldName(String fieldName) {
457 | 0 |
             this.fieldName = fieldName;
458 | 0 |
         }
459 |  |
460 |  |
         /**
461 |  |
          * Determines whether or not a <code>FileItem</code> instance represents
462 |  |
          * a simple form field.
463 |  |
          *
464 |  |
          * @return <code>true</code> if the instance represents a simple form
465 |  |
          *         field; <code>false</code> if it represents an uploaded file.
466 |  |
          *
467 |  |
          * @see #setFormField(boolean)
468 |  |
          *
469 |  |
          */
470 |  |
         @Override
471 |  |
         public boolean isFormField() {
472 | 32 |
             return isFormField;
473 |  |
         }
474 |  |
475 |  |
         /**
476 |  |
          * Specifies whether or not a <code>FileItem</code> instance represents
477 |  |
          * a simple form field.
478 |  |
          *
479 |  |
          * @param state <code>true</code> if the instance represents a simple form
480 |  |
          *              field; <code>false</code> if it represents an uploaded file.
481 |  |
          *
482 |  |
          * @see #isFormField()
483 |  |
          *
484 |  |
          */
485 |  |
         @Override
486 |  |
         public void setFormField(boolean state) {
487 | 0 |
             isFormField = state;
488 | 0 |
         }
489 |  |
490 |  |
         /**
491 |  |
          * Returns an {@link java.io.OutputStream OutputStream} that can
492 |  |
          * be used for storing the contents of the file.
493 |  |
          *
494 |  |
          * @return An {@link java.io.OutputStream OutputStream} that can be used
495 |  |
          *         for storing the contents of the file.
496 |  |
          *
497 |  |
          * @throws IOException if an error occurs.
498 |  |
          */
499 |  |
         @Override
500 |  |
         public OutputStream getOutputStream()
501 |  |
             throws IOException {
502 | 2172 |
             if (dfos == null) {
503 | 2172 |
                 File outputFile = getTempFile();
504 | 2172 |
                 dfos = new DeferredFileOutputStream(sizeThreshold, outputFile);
505 |  |
             }
506 | 2172 |
             return dfos;
507 |  |
         }
508 |  |
509 |  |
         // --------------------------------------------------------- Public methods
510 |  |
511 |  |
         /**
512 |  |
          * Returns the {@link java.io.File} object for the <code>FileItem</code>'s
513 |  |
          * data's temporary location on the disk. Note that for
514 |  |
          * <code>FileItem</code>s that have their data stored in memory,
515 |  |
          * this method will return <code>null</code>. When handling large
516 |  |
          * files, you can use {@link java.io.File#renameTo(java.io.File)} to
517 |  |
          * move the file to new location without copying the data, if the
518 |  |
          * source and destination locations reside within the same logical
519 |  |
          * volume.
520 |  |
          *
521 |  |
          * @return The data file, or <code>null</code> if the data is stored in
522 |  |
          *         memory.
523 |  |
          */
524 |  |
         public File getStoreLocation() {
525 | 709 |
             if (dfos == null) {
526 | 0 |
                 return null;
527 |  |
             }
528 | 709 |
             if (isInMemory()) {
529 | 442 |
                 return null;
530 |  |
             }
531 | 267 |
             return dfos.getFile();
532 |  |
         }
533 |  |
534 |  |
         // ------------------------------------------------------ Protected methods
535 |  |
536 |  |
         /**
537 |  |
          * Removes the file contents from the temporary storage.
538 |  |
          */
539 |  |
         @Override
540 |  |
         protected void finalize() {
541 | 1417 |
             if (dfos == null || dfos.isInMemory()) {
542 | 892 |
                 return;
543 |  |
             }
544 | 525 |
             File outputFile = dfos.getFile();
545 |  |
546 | 525 |
             if (outputFile != null && outputFile.exists()) {
547 | 262 |
                 outputFile.delete();
548 |  |
             }
549 | 525 |
         }
550 |  |
551 |  |
         /**
552 |  |
          * Creates and returns a {@link java.io.File File} representing a uniquely
553 |  |
          * named temporary file in the configured repository path. The lifetime of
554 |  |
          * the file is tied to the lifetime of the <code>FileItem</code> instance;
555 |  |
          * the file will be deleted when the instance is garbage collected.
556 |  |
          * <p>
557 |  |
          * <b>Note: Subclasses that override this method must ensure that they return the
558 |  |
          * same File each time.</b>
559 |  |
          *
560 |  |
          * @return The {@link java.io.File File} to be used for temporary storage.
561 |  |
          */
562 |  |
         protected File getTempFile() {
563 | 2172 |
             if (tempFile == null) {
564 | 2172 |
                 File tempDir = repository;
565 | 2172 |
                 if (tempDir == null) {
566 | 2165 |
                     tempDir = new File(System.getProperty("java.io.tmpdir"));
567 |  |
                 }
568 |  |
569 | 2172 |
                 String tempFileName = format("upload_%s_%s.tmp", UID, getUniqueId());
570 |  |
571 | 2172 |
                 tempFile = new File(tempDir, tempFileName);
572 |  |
             }
573 | 2172 |
             return tempFile;
574 |  |
         }
575 |  |
576 |  |
         // -------------------------------------------------------- Private methods
577 |  |
578 |  |
         /**
579 |  |
          * Returns an identifier that is unique within the class loader used to
580 |  |
          * load this class, but does not have random-like appearance.
581 |  |
          *
582 |  |
          * @return A String with the non-random looking instance identifier.
583 |  |
          */
584 |  |
         private static String getUniqueId() {
585 | 2172 |
             final int limit = 100000000;
586 | 2172 |
             int current = COUNTER.getAndIncrement();
587 | 2172 |
             String id = Integer.toString(current);
588 |  |
589 |  |
             // If you manage to get more than 100 million of ids, you'll
590 |  |
             // start getting ids longer than 8 characters.
591 | 2172 |
             if (current < limit) {
592 | 2172 |
                 id = ("00000000" + id).substring(id.length());
593 |  |
             }
594 | 2172 |
             return id;
595 |  |
         }
596 |  |
597 |  |
         /**
598 |  |
          * Returns a string representation of this object.
599 |  |
          *
600 |  |
          * @return a string representation of this object.
601 |  |
          */
602 |  |
         @Override
603 |  |
         public String toString() {
604 | 0 |
             return format("name=%s, StoreLocation=%s, size=%s bytes, isFormField=%s, FieldName=%s",
605 | 0 |
                           getName(), getStoreLocation(), Long.valueOf(getSize()),
606 | 0 |
                           Boolean.valueOf(isFormField()), getFieldName());
607 |  |
         }
608 |  |
609 |  |
         /**
610 |  |
          * Returns the file item headers.
611 |  |
          * @return The file items headers.
612 |  |
          */
613 |  |
         @Override
614 |  |
         public FileItemHeaders getHeaders() {
615 | 32 |
             return headers;
616 |  |
         }
617 |  |
618 |  |
         /**
619 |  |
          * Sets the file item headers.
620 |  |
          * @param pHeaders The file items headers.
621 |  |
          */
622 |  |
         @Override
623 |  |
         public void setHeaders(FileItemHeaders pHeaders) {
624 | 2160 |
             headers = pHeaders;
625 | 2160 |
         }
626 |  |
627 |  |
         /**
628 |  |
          * Returns the default charset for use when no explicit charset
629 |  |
          * parameter is provided by the sender.
630 |  |
          * @return the default charset
631 |  |
          */
632 |  |
         public String getDefaultCharset() {
633 | 0 |
             return defaultCharset;
634 |  |
         }
635 |  |
636 |  |
         /**
637 |  |
          * Sets the default charset for use when no explicit charset
638 |  |
          * parameter is provided by the sender.
639 |  |
          * @param charset the default charset
640 |  |
          */
641 |  |
         public void setDefaultCharset(String charset) {
642 | 2169 |
             defaultCharset = charset;
643 | 2169 |
         }
644 |  |
     }