View Javadoc

1   /*
2   
3   This software is OSI Certified Open Source Software.
4   OSI Certified is a certification mark of the Open Source Initiative.
5   
6   The license (Mozilla version 1.0) can be read at the MMBase site.
7   See http://www.MMBase.org/license
8   
9   */
10  package net.sf.mmapps.commons.util;
11  
12  import java.io.ByteArrayInputStream;
13  import java.io.InputStream;
14  import java.util.ArrayList;
15  import java.util.Iterator;
16  import java.util.List;
17  
18  import javax.servlet.http.HttpServletRequest;
19  
20  import org.apache.commons.fileupload.*;
21  import org.mmbase.util.logging.Logger;
22  import org.mmbase.util.logging.Logging;
23  
24  
25  public class UploadUtil {
26  
27      /*** MMbase logging system */
28      private static Logger log = Logging.getLoggerInstance(UploadUtil.class.getName());
29      
30      /***
31       * Process files which are uploaded through http
32       * 
33       * @param request - http request
34       * @param maxsize - maximum allowed size of a file
35       * @return List of UploadUtil.BinaryData objects
36       */
37      public static List uploadFiles(HttpServletRequest request, int maxsize) {
38          // Initialization
39          DiskFileUpload fu = new DiskFileUpload();
40          // maximum size before a FileUploadException will be thrown
41          fu.setSizeMax(maxsize);
42  
43          // maximum size that will be stored in memory --- what should this be?
44          // fu.setSizeThreshold(maxsize);
45  
46          // the location for saving data that is larger than getSizeThreshold()
47          // where to store?
48          // fu.setRepositoryPath("/tmp");
49  
50          // Upload
51          try {
52              List<BinaryData> binaries = new ArrayList<BinaryData>();
53              List fileItems = fu.parseRequest(request);
54  
55              for (Iterator i = fileItems.iterator(); i.hasNext();) {
56                  FileItem fi = (FileItem) i.next();
57                  if (!fi.isFormField()) {
58                      String fullFileName = fi.getName();
59                      if (fi.get().length > 0) { // no need uploading nothing
60                          BinaryData binaryData = new BinaryData();
61                          binaryData.setData(fi.get());
62                          binaryData.setOriginalFilePath(fullFileName);
63                          binaryData.setContentType(fi.getContentType());
64                          if (log.isDebugEnabled()) {
65                              log.debug("Setting binary " + binaryData.getLength()
66                                      + " bytes in type " + binaryData.getContentType() + " with "
67                                      + binaryData.getOriginalFilePath() + " name");
68                          }
69                          binaries.add(binaryData);
70                      }
71                  }
72              }
73              return binaries;
74          }
75          catch (FileUploadBase.SizeLimitExceededException e) {
76              String errorMessage = "Uploaded file exceeds maximum file size of " + maxsize + " bytes.";
77              log.warn(errorMessage, e);
78              throw new RuntimeException(errorMessage, e);
79          }
80          catch (FileUploadException e) {
81              String errorMessage = "An error ocurred while uploading this file " + e.toString();
82              log.warn(errorMessage, e);
83              throw new RuntimeException(errorMessage, e);
84          }
85      }
86      
87      
88      public static class BinaryData {
89          
90          private String originalFilePath = null;
91          private int length = 0;
92          private byte[] data = null;
93          private String contentType = null;
94          
95          /***
96           * set the binary data into this class to cache.
97           * @param data
98           */
99          public void setData(byte[] data) {
100             if (data == null) {
101                 this.length=0;
102             }
103             else {
104                 this.data = data;
105                 this.length = this.data.length;
106             }
107         }
108         
109         /***
110          * get the binary data cached by this class
111          * @return binary data
112          */
113         public byte[] getData() {
114             if (this.length==0) {
115                 return new byte[0];
116             }
117             return data;
118         }
119         
120         /***
121          * get original file name, it is the path in the client in which upload the file.
122          * @return Returns the originalFilePath.
123          */
124         public String getOriginalFilePath() {
125             return originalFilePath;
126         }
127 
128         /***
129          * set original file name, it is the path in the client in which upload the file.
130          * @param originalFilePath The originalFilePath to set.
131          */
132         public void setOriginalFilePath(String originalFilePath) {
133             this.originalFilePath = originalFilePath;
134         }
135         
136         /***
137          * get original file name. the return value only contains the file name, 
138          * the directory path is not include in return value.
139          * @return original file name
140          */
141         public String getOriginalFileName() {
142             if (originalFilePath==null) {
143                 return null;
144             }
145             // the path passed is in the client system's format,
146             // so test all known path separator chars ('/', '\' and "::" )
147             // and pick the one which would create the smallest filename
148             // Using Math is rather ugly but at least it is shorter and performs better
149             // than Stringtokenizer, regexp, or sorting collections
150             int last = Math.max(Math.max(
151                     originalFilePath.lastIndexOf(':'), // old mac path (::)
152                     originalFilePath.lastIndexOf('/')),  // unix path
153                     originalFilePath.lastIndexOf('//')); // windows path
154             if (last > -1) {
155                 return originalFilePath.substring(last+1);
156             }
157             return originalFilePath;
158         }
159 
160         public int getLength() {
161             return length;
162         }
163         
164         public String getContentType() {
165             return contentType;
166         }
167         
168         public void setContentType(String contentType) {
169             this.contentType = contentType;
170         }
171         
172         public InputStream getInputStream() {
173             return new ByteArrayInputStream(getData());
174         }
175     }
176 
177 }