Skip to content

Commit 017158d

Browse files
committed
new implementation (Issue #916)
1 parent ebbcf45 commit 017158d

File tree

7 files changed

+668
-98
lines changed

7 files changed

+668
-98
lines changed

imixs-workflow-faces/pom.xml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
1+
<project xmlns="http://maven.apache.org/POM/4.0.0"
2+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
24
<parent>
35
<artifactId>imixs-workflow</artifactId>
46
<groupId>org.imixs.workflow</groupId>
Lines changed: 316 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,316 @@
1+
/*
2+
* Imixs-Workflow
3+
*
4+
* Copyright (C) 2001-2020 Imixs Software Solutions GmbH,
5+
* http://www.imixs.com
6+
*
7+
* This program is free software; you can redistribute it and/or
8+
* modify it under the terms of the GNU General Public License
9+
* as published by the Free Software Foundation; either version 2
10+
* of the License, or (at your option) any later version.
11+
*
12+
* This program is distributed in the hope that it will be useful,
13+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15+
* General Public License for more details.
16+
*
17+
* You can receive a copy of the GNU General Public
18+
* License at http://www.gnu.org/licenses/gpl.html
19+
*
20+
* Project:
21+
* https://www.imixs.org
22+
* https://github.com/imixs/imixs-workflow
23+
*
24+
* Contributors:
25+
* Imixs Software Solutions GmbH - Project Management
26+
* Ralph Soika - Software Developer
27+
*/
28+
29+
package org.imixs.workflow.faces.fileupload;
30+
31+
import java.io.IOException;
32+
import java.io.PrintWriter;
33+
import java.net.URLDecoder;
34+
import java.util.ArrayList;
35+
import java.util.List;
36+
import java.util.logging.Level;
37+
import java.util.logging.Logger;
38+
39+
import org.imixs.workflow.FileData;
40+
41+
import jakarta.inject.Inject;
42+
import jakarta.servlet.ServletException;
43+
import jakarta.servlet.ServletOutputStream;
44+
import jakarta.servlet.ServletResponse;
45+
import jakarta.servlet.annotation.MultipartConfig;
46+
import jakarta.servlet.annotation.WebServlet;
47+
import jakarta.servlet.http.HttpServlet;
48+
import jakarta.servlet.http.HttpServletRequest;
49+
import jakarta.servlet.http.HttpServletResponse;
50+
import jakarta.servlet.http.Part;
51+
52+
/**
53+
* The AjaxFileUploadServlet is a Multipart-Servlet 3.0. It is used by the
54+
* imixsFileUploadAjax widget. The widget handles the upload of multiple files
55+
* and supports drag & drop functionality. The servlet is configured with a max
56+
* file size to 10MB, and a max request size of 50MB.
57+
*
58+
* @author rsoika
59+
*/
60+
@WebServlet(urlPatterns = { "/fileupload/*" })
61+
@MultipartConfig(fileSizeThreshold = 1024 * 1024, maxFileSize = 1024 * 1024 * 10, maxRequestSize = 1024 * 1024 * 50)
62+
public class AjaxFileUploadServlet extends HttpServlet {
63+
64+
private static final long serialVersionUID = 1L;
65+
private static final String REQUEST_METHOD_POST = "POST";
66+
private static final String REQUEST_METHOD_GET = "GET";
67+
private static final String CONTENT_TYPE_MULTIPART = "multipart/";
68+
private static final String CONTENT_DISPOSITION = "content-disposition";
69+
private static final String CONTENT_DISPOSITION_FILENAME = "filename";
70+
71+
private static final Logger logger = Logger.getLogger(AjaxFileUploadServlet.class.getName());
72+
73+
@Inject
74+
FileUploadController fileUploadController;
75+
76+
/**
77+
* Upload files to stored in the current user session
78+
*/
79+
@Override
80+
protected void doPost(HttpServletRequest httpRequest, HttpServletResponse response)
81+
throws ServletException, IOException {
82+
if (isPostFileUploadRequest(httpRequest)) {
83+
logger.fine("......add files...");
84+
List<FileData> fileDataList = getFilesFromRequest(httpRequest);
85+
// now update the workitem....
86+
if (fileUploadController != null) {
87+
// check workitem... issue
88+
if (fileUploadController.getWorkitem() != null) {
89+
logger.fine("......prüfe file data Liste...");
90+
for (FileData filedata : fileDataList) {
91+
logger.fine("......add new fileData object..." + filedata.getName());
92+
fileUploadController.addFileUpload(filedata);
93+
}
94+
}
95+
}
96+
writeJsonMetadata(response, httpRequest.getRequestURI());
97+
}
98+
}
99+
100+
/**
101+
* Getter method to return the file content from the fileData list stored in the
102+
* current user
103+
*/
104+
@Override
105+
protected void doGet(HttpServletRequest httpRequest, HttpServletResponse httpResponse)
106+
throws ServletException, IOException {
107+
108+
// check cancel upload...
109+
if (isGetFileUploadRequest(httpRequest)) {
110+
int iCancel = httpRequest.getRequestURI().indexOf("/fileupload/file/");
111+
String filename = httpRequest.getRequestURI().substring(iCancel + 17);
112+
// urldecoding...
113+
filename = URLDecoder.decode(filename, "UTF-8");
114+
if (fileUploadController != null) {
115+
// check workitem... issue
116+
if (fileUploadController.getWorkitem() != null) {
117+
FileData fileData = fileUploadController.getFileUpload(filename);
118+
// write contenremoveFile(filename);
119+
if (fileData != null) {
120+
writeFileContent(httpResponse, fileData);
121+
} else {
122+
httpResponse.sendError(HttpServletResponse.SC_NOT_FOUND);
123+
}
124+
}
125+
}
126+
}
127+
}
128+
129+
/**
130+
* checks if the httpRequest is a fileupload get request...
131+
*
132+
* @param httpRequest
133+
* @return
134+
*/
135+
private boolean isGetFileUploadRequest(HttpServletRequest httpRequest) {
136+
String uri = httpRequest.getRequestURI();
137+
138+
return (REQUEST_METHOD_GET.equalsIgnoreCase(httpRequest.getMethod())
139+
&& !(uri.endsWith("/fileupload") || uri.endsWith("/fileupload/")));
140+
141+
}
142+
143+
/**
144+
* Returns a file attachment located in the property $file of the specified
145+
* workitem
146+
*
147+
* The file name will be encoded. With a URLDecode the filename is decoded in
148+
* different formats and searched in the file list. This is not a nice solution.
149+
*
150+
* @param uniqueid
151+
* @return
152+
* @throws IOException
153+
*/
154+
private void writeFileContent(ServletResponse response, FileData fileData) throws IOException {
155+
logger.finest("......write file content...");
156+
ServletOutputStream output = response.getOutputStream();
157+
output.write(fileData.getContent());
158+
// now return json string of uploaded files....
159+
response.setContentType(fileData.getContentType());
160+
output.close();
161+
}
162+
163+
/**
164+
* checks if the httpRequest is a fileupload
165+
*
166+
* @param httpRequest
167+
* @return
168+
*/
169+
private boolean isPostFileUploadRequest(HttpServletRequest httpRequest) {
170+
String sContentType = httpRequest.getContentType();
171+
logger.log(Level.FINE, "......contentType={0}", sContentType);
172+
173+
return (REQUEST_METHOD_POST.equalsIgnoreCase(httpRequest.getMethod()) && httpRequest.getContentType() != null
174+
&& sContentType.toLowerCase().startsWith(CONTENT_TYPE_MULTIPART));
175+
}
176+
177+
/**
178+
* test and extracts the filename of a http request part. The method returns
179+
* null if the part dose not contain a file
180+
*
181+
* @param part
182+
* @return - filename or null if not a file content
183+
*/
184+
private String getFilename(Part part) {
185+
for (String cd : part.getHeader(CONTENT_DISPOSITION).split(";")) {
186+
if (cd.trim().startsWith(CONTENT_DISPOSITION_FILENAME)) {
187+
return cd.substring(cd.indexOf('=') + 1).trim().replace("\"", "");
188+
}
189+
}
190+
return null;
191+
}
192+
193+
/**
194+
* This method converts mulitple files from the httpRequest into a list of
195+
* FileData objects.
196+
*
197+
* @param httpRequest
198+
* @return list of FileData objects
199+
*/
200+
private List<FileData> getFilesFromRequest(HttpServletRequest httpRequest) {
201+
logger.finest("......Looping parts");
202+
203+
List<FileData> fileDataList = new ArrayList<FileData>();
204+
try {
205+
for (Part p : httpRequest.getParts()) {
206+
byte[] b = new byte[(int) p.getSize()];
207+
p.getInputStream().read(b);
208+
p.getInputStream().close();
209+
// params.put(p.getName(), new String[] { new String(b) });
210+
211+
// test if part contains a file
212+
String fileName = getFilename(p);
213+
if (fileName != null) {
214+
215+
/*
216+
* issue #106
217+
*
218+
* https://developer.jboss.org/message/941661#941661
219+
*
220+
* Here we test of the encoding and try to convert to utf-8.
221+
*/
222+
byte fileNameISOBytes[] = fileName.getBytes("iso-8859-1");
223+
String fileNameUTF8 = new String(fileNameISOBytes, "UTF-8");
224+
if (fileName.length() != fileNameUTF8.length()) {
225+
// convert to utf-8
226+
logger.finest("......filename seems to be ISO-8859-1 encoded");
227+
fileName = new String(fileName.getBytes("iso-8859-1"), "utf-8");
228+
}
229+
230+
// extract the file content...
231+
FileData fileData = null;
232+
logger.log(Level.FINEST, "......filename : {0}, contentType {1}",
233+
new Object[] { fileName, p.getContentType() });
234+
fileData = new FileData(fileName, b, p.getContentType(), null);
235+
fileDataList.add(fileData);
236+
237+
}
238+
}
239+
240+
} catch (IOException ex) {
241+
logger.log(Level.SEVERE, null, ex);
242+
} catch (ServletException ex) {
243+
logger.log(Level.SEVERE, null, ex);
244+
}
245+
246+
return fileDataList;
247+
}
248+
249+
/**
250+
* This method write a JSON meta data structure for uploaded files into the
251+
* httpResponse. This structure is used by a ajax call to extract the result
252+
*
253+
* <code>
254+
{
255+
"files": [
256+
{
257+
"url": "0:0:0:0:0:0:0:1",
258+
"thumbnail_url": "",
259+
"name": "start.gif",
260+
"type": "image/gif",
261+
"size": 128,
262+
"delete_url": "",
263+
"delete_type": "DELETE"
264+
}
265+
]
266+
}
267+
* </code>
268+
*
269+
*
270+
* * @see https://github.com/blueimp/jQuery-File-Upload/wiki/JSON-Response
271+
*
272+
* @throws IOException
273+
*
274+
*/
275+
private void writeJsonMetadata(ServletResponse response, String context_url) throws IOException {
276+
277+
response.setContentType("application/json;charset=UTF-8");
278+
PrintWriter out = response.getWriter();
279+
280+
// look if we have a worktiem with filedata....
281+
if (fileUploadController != null) {
282+
// check workitem... issue
283+
if (fileUploadController.getWorkitem() != null) {
284+
285+
List<FileData> fileDataList = fileUploadController.getFileUploads();
286+
logger.finest("......write JSON meta data...");
287+
288+
String result = "{ \"files\":[";
289+
for (int i = 0; i < fileDataList.size(); i++) {
290+
291+
FileData fileData = fileDataList.get(i);
292+
// we construct a temp file url with the current converstion id....
293+
result += "{ \"url\": \"" + context_url + fileData.getName() + "?cid="
294+
+ fileUploadController.getCID() + "\",";
295+
result += "\"thumbnail_url\": \"\",";
296+
result += "\"name\": \"" + fileData.getName() + "\",";
297+
result += "\"type\": \"" + fileData.getContentType() + "\",";
298+
result += "\"size\": " + fileData.getContent().length + ",";
299+
result += "\"delete_url\": \"\",";
300+
result += "\"delete_type\": \"DELETE\"";
301+
302+
// last element?
303+
if (i < fileDataList.size() - 1)
304+
result += "},";
305+
else
306+
result += "}";
307+
}
308+
result += "]}";
309+
out.write(result);
310+
}
311+
}
312+
313+
out.close();
314+
315+
}
316+
}

0 commit comments

Comments
 (0)