1 /*
2 * PROJECT : DAR Runtime and Tools
3 * COPYRIGHT : Copyright (C) 1999-2004 tim.stephenson@enableit.org
4 * LICENSE : GNU LESSER GENERAL PUBLIC LICENSE
5 * Version 2.1, February 1999
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (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
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21 package org.enableit.db.darrt.web;
22
23 import java.io.ByteArrayOutputStream;
24 import java.io.File;
25 import java.io.FileOutputStream;
26 import java.io.InputStream;
27 import java.io.OutputStream;
28 import java.util.Enumeration;
29
30 import javax.naming.Context;
31 import javax.naming.InitialContext;
32 import javax.servlet.ServletContext;
33 import javax.servlet.http.HttpServletRequest;
34 import javax.servlet.http.HttpServletResponse;
35 import javax.servlet.http.HttpSession;
36
37 import org.apache.commons.beanutils.MethodUtils;
38 import org.apache.commons.beanutils.PropertyUtils;
39 import org.apache.log4j.Category;
40 import org.apache.struts.action.ActionError;
41 import org.apache.struts.action.ActionErrors;
42 import org.apache.struts.action.ActionForm;
43 import org.apache.struts.action.ActionForward;
44 import org.apache.struts.action.ActionMapping;
45 import org.apache.struts.actions.DispatchAction;
46 import org.apache.struts.upload.FormFile;
47 import org.enableit.db.beans.Provider;
48 import org.enableit.db.beans.Table;
49 import org.enableit.db.darrt.FileProcessor;
50
51
52 /***
53 * General action to support uploading.
54 * <p>
55 * Note that the JSP page may specify a sub-directory of the
56 * web-application into which the file is to be saved. By default the
57 * file will be saved into the web-app root.
58 * </p>
59 *
60 * @author Tim Stephenson (based on struts upload example)
61 *
62 * @struts:action path="/upload" scope="request"
63 * name="UploadForm" parameter="action"
64 * input="/ssUpload.jsp" validate="true"
65 */
66 public class UploadAction extends DispatchAction {
67 /***
68 * The Log4J <code>Category</code> doing the logging.
69 */
70 private static Category logger = Category.getInstance(UploadAction.class);
71
72 /***
73 * Default constructor.
74 */
75 public UploadAction() {
76 super();
77 }
78
79 /***
80 * Present the default file upload page.
81 */
82 public ActionForward preUpload(ActionMapping mapping, ActionForm form,
83 HttpServletRequest request, HttpServletResponse response)
84 throws Exception {
85 logger.info("METHOD_ENTRY: preUpload");
86
87 ActionForward forwardTo = new ActionForward(mapping.getInput());
88
89 logger.info("METHOD_EXIT: preUpload, forwarding to: "
90 + forwardTo.getPath());
91
92 return forwardTo;
93 }
94
95 /***
96 * Handle the file upload and forward to the confirmation page.
97 */
98 public ActionForward upload(ActionMapping mapping, ActionForm form,
99 HttpServletRequest request, HttpServletResponse response)
100 throws java.io.IOException, javax.servlet.ServletException {
101 logger.info("METHOD_ENTRY: upload");
102
103 try {
104 //this line is here for when the input page is upload-utf8.jsp,
105 //it sets the correct character encoding for the response
106 String encoding = request.getCharacterEncoding();
107
108 if ((encoding != null) && (encoding.equalsIgnoreCase("utf-8"))) {
109 response.setContentType("text/html; charset=utf-8");
110 }
111
112 UploadForm theForm = (UploadForm) form;
113
114 //retrieve the file representation
115 FormFile formFile = theForm.getTheFile();
116
117 String data = null;
118 File file = null;
119 String tableName = request.getParameter("tableName");
120
121 //retrieve the file data
122 ByteArrayOutputStream baos = new ByteArrayOutputStream();
123 InputStream stream = formFile.getInputStream();
124
125 if (!theForm.getWriteFile()) {
126 //only write files out that are less than 4MB
127 if (formFile.getFileSize() < (4 * 1024000)) {
128 byte[] buffer = new byte[8192];
129 int bytesRead = 0;
130
131 while ((bytesRead = stream.read(buffer, 0, 8192)) != -1) {
132 baos.write(buffer, 0, bytesRead);
133 }
134
135 data = new String(baos.toByteArray());
136 } else {
137 data = new String("The file is greater than 4MB, "
138 + " and has not been written to stream."
139 + " File Size: " + formFile.getFileSize()
140 + " bytes. This is a"
141 + " limitation of this particular web application, hard-coded"
142 + " in org.apache.struts.webapp.upload.UploadAction");
143 }
144 } else {
145 // Write the file to the file specified within the webapp dir
146 File dir = getIncomingDir();
147 String filePath = theForm.getFilePath();
148
149 if ((filePath == null) || (filePath.length() <= 0)) {
150 logger.debug("Uploading file: " + formFile.getFileName());
151 filePath = formFile.getFileName();
152 }
153
154 file = new File(dir, filePath);
155 request.setAttribute("File", file.toString());
156
157 OutputStream bos = new FileOutputStream(file);
158 int bytesRead = 0;
159 byte[] buffer = new byte[8192];
160
161 while ((bytesRead = stream.read(buffer, 0, 8192)) != -1) {
162 bos.write(buffer, 0, bytesRead);
163 }
164
165 bos.close();
166 data = "The file has been written to \"" + filePath + "\"";
167 }
168
169 // Close the stream
170 stream.close();
171
172 String fileName = formFile.getFileName();
173 String fileType = fileName.substring(fileName.lastIndexOf(".") + 1)
174 .toUpperCase();
175
176 request.setAttribute("fileType", fileType);
177 request.setAttribute("fileName", fileName);
178 request.setAttribute("contentType", formFile.getContentType());
179 request.setAttribute("size", formFile.getFileSize() + " bytes");
180 request.setAttribute("data", data);
181 request.setAttribute("tableName", tableName);
182
183 postProcess(mapping, form, request, response);
184 } catch (Exception e) {
185 logger.error(e.getMessage(), e);
186
187 ActionErrors errors = new ActionErrors();
188 ActionError error = new ActionError("errors.unknown", e.getMessage());
189
190 errors.add(ActionErrors.GLOBAL_ERROR, error);
191 saveErrors(request, errors);
192
193 HttpSession session = request.getSession();
194 Table table = (Table) session.getAttribute("table");
195
196 request.setAttribute("table", table);
197 session.removeAttribute("table");
198 }
199
200 // ALWAYS returns to input page (msg varies: success or failure)
201 logger.info("METHOD_EXIT: upload, forwarding to: " + mapping.getInput());
202
203 return new ActionForward(mapping.getInput());
204 }
205
206 /***
207 * Handle the file upload and forward to the confirmation page.
208 */
209 private ActionForward postProcess(ActionMapping mapping, ActionForm form,
210 HttpServletRequest request, HttpServletResponse response)
211 throws java.io.IOException, javax.servlet.ServletException {
212 logger.info("METHOD_ENTRY: postProcess");
213
214 String tableName = request.getParameter("tableName");
215
216 // This is where to find it if invoked as part of upload
217 File file = new File((String) request.getAttribute("File"));
218
219 if (file == null) {
220 // This happens when invoked independently of file upload
221 file = new File(request.getParameter("File"));
222 }
223
224 try {
225 // check for a post-processor for this file in request
226 String ppName = null;
227 Context context = null;
228
229 if (request.getParameter("postProcessor") != null) {
230 ppName = request.getParameter("postProcessor");
231 } else {
232 // check for a post-processor for this file in JNDI
233 context = new InitialContext();
234
235 String fileExtension = file.getName()
236 .substring(file.getName()
237 .lastIndexOf(".") + 1)
238 .toUpperCase();
239
240 ppName = (String) context.lookup("java:/comp/env/"
241 + fileExtension + "PostProcessor");
242 }
243
244 logger.warn("Found file processor: " + ppName);
245
246 FileProcessor pp = null;
247
248 // NB if ppName is null will have thrown NamingException already
249 if (ppName.indexOf(".") > -1) {
250 // Assume class
251 Class ppType = UploadAction.class.getClassLoader().loadClass(ppName);
252
253 pp = (FileProcessor) ppType.newInstance();
254 pp.setProvider((Provider) getServlet().getServletContext()
255 .getAttribute("Provider"));
256 } else {
257 // Assume EJB
258 Object ejbHome = context.lookup(ppName);
259
260 pp = (FileProcessor) MethodUtils.invokeMethod(ejbHome,
261 "create", null);
262 }
263
264 // TODO: It may be possible to replace this with a forward to the SimpleDelegatingAction
265 // Inform the delegate of the request parameters using bean utils.
266 for (Enumeration enum = request.getParameterNames();
267 enum.hasMoreElements();) {
268 String propName = (String) enum.nextElement();
269
270 try {
271 String[] propValues = request.getParameterValues(propName);
272
273 switch (propValues.length) {
274 case 0:
275 ; // nothing
276
277 break;
278 case 1:
279 PropertyUtils.setProperty(pp, propName, propValues[0]);
280
281 break;
282 default:
283 PropertyUtils.setProperty(pp, propName, propValues);
284 }
285 } catch (Exception e) {
286 logger.warn("Unable to set property named: " + propName, e);
287 }
288 }
289
290 // Process file
291 pp.process(file, tableName);
292
293 // report success as 'error'
294 ActionErrors errors = new ActionErrors();
295 ActionError error = new ActionError("shapeShifter.upload.success");
296
297 errors.add(ActionErrors.GLOBAL_ERROR, error);
298 saveErrors(request, errors);
299
300 // Free the file to be garbage collected
301 file = null;
302 } catch (javax.naming.NamingException e) {
303 logger.warn("No post processor found for file, message is: "
304 + e.getMessage());
305 } catch (Exception e) {
306 logger.error(e.getMessage(), e);
307
308 ActionErrors errors = new ActionErrors();
309 ActionError error = new ActionError("errors.unknown", e.getMessage());
310
311 errors.add(ActionErrors.GLOBAL_ERROR, error);
312 saveErrors(request, errors);
313
314 HttpSession session = request.getSession();
315 Table table = (Table) session.getAttribute("table");
316
317 request.setAttribute("table", table);
318 session.removeAttribute("table");
319 }
320
321 // ALWAYS returns to input page (msg varies: success or failure)
322 logger.info("METHOD_EXIT: postProcess");
323
324 return new ActionForward(mapping.getInput());
325 }
326
327 /***
328 * @return A file representing a directory where
329 * may write uploaded files.
330 */
331 private File getIncomingDir() {
332 logger.info("METHOD_ENTRY: getIncomingDir");
333
334 // Look first for the root of the web-application
335 String sDir = getServlet().getServletContext().getRealPath("/");
336 File dir = null;
337
338 if (sDir == null) {
339 logger.debug("Real root is null, probably an unexploded war.");
340
341 ServletContext appContext = getServlet().getServletContext();
342 Object temp = appContext.getAttribute(
343 "javax.servlet.context.tempdir");
344
345 if (temp instanceof File) {
346 // Weblogic for one does it this way
347 dir = (File) temp;
348 } else {
349 sDir = temp.toString();
350 dir = new File(sDir);
351 }
352 } else {
353 dir = new File(sDir);
354 }
355
356 /* is this possible?
357 if (!dir.exists()) {
358 realRoot.mkdirs() ;
359 }
360 */
361 logger.info("METHOD_EXIT: getIncomingDir, dir=" + dir);
362
363 return dir;
364 }
365 }
This page was automatically generated by Maven