source: other-projects/the-macronizer/trunk/src/java/web/servlets/FileUpload.java@ 35719

Last change on this file since 35719 was 35719, checked in by cstephen, 2 years ago

Add support for JSON response to direct input queries. Cleanup other components.

File size: 10.5 KB
Line 
1package web.servlets;
2
3import java.io.File;
4import java.io.IOException;
5import java.util.ArrayList;
6import java.util.List;
7
8import javax.servlet.RequestDispatcher;
9import javax.servlet.ServletConfig;
10import javax.servlet.ServletException;
11import javax.servlet.http.HttpServlet;
12import javax.servlet.http.HttpServletRequest;
13import javax.servlet.http.HttpServletResponse;
14
15import monogram.plugin.PluginConfiguration;
16import monogram.plugin.PluginManager;
17
18import org.apache.commons.fileupload.FileItem;
19import org.apache.commons.fileupload.FileUploadException;
20import org.apache.commons.fileupload.disk.DiskFileItemFactory;
21import org.apache.commons.fileupload.servlet.ServletFileUpload;
22import org.apache.log4j.*;
23
24import util.FileUtil;
25
26/**
27 * @author University of Waikato - Te Whare Wānanga o Waikato
28 * @version 1.0
29 * @since 2014-11-20
30 */
31public class FileUpload extends HttpServlet {
32
33 // Create an instance of the logger object defined for the DirectInput servlet in log4j.properties.
34 private static final Logger logger = Logger.getLogger(web.servlets.DirectInput.class.getName());
35
36 private File tmpdir;
37 private PluginManager pluginManager;
38
39 @Override
40 public void init(ServletConfig config)
41 throws ServletException
42 {
43 super.init(config);
44
45 tmpdir = new File((String) config.getServletContext().getAttribute("tmpdir"));
46 pluginManager = new PluginManager(tmpdir);
47 }
48
49 /**
50 * Handles the HTTP <code>GET</code> method.
51 * @param request The servlet request.
52 * @param response The servlet response.
53 * @throws IllegalStateException if a reponse has already been committed.
54 * @throws IOException if an I/O error occurs.
55 */
56 @Override
57 protected void doGet(HttpServletRequest request, HttpServletResponse response)
58 throws IllegalStateException, IOException
59 {
60 response.sendError(405); // 405 Method Not Allowed
61 }
62
63 /**
64 * Handles the HTTP <code>POST</code> method.
65 * @param request servlet request
66 * @param response servlet response
67 * @throws ServletException if a servlet-specific error occurs
68 * @throws IOException if an I/O error occurs
69 */
70 @Override
71 protected void doPost(HttpServletRequest request, HttpServletResponse response)
72 throws IllegalStateException, IOException, ServletException
73 {
74 final OutputType outputType = OutputType.parse(request.getParameter("o")); // TODO: This probably won't work with the multipart request
75
76 File restoredFile = null;
77 PluginConfiguration configuration = null;
78 Properties properties = null;
79 String forwardPath = "/jsp/mi";
80
81 try
82 {
83 properties = handleRequest(request);
84 forwardPath = properties.getLanguage() != null ? "/jsp/" + properties.getLanguage() : forwardPath;
85 }
86 catch (Exception ex)
87 {
88 setError(outputType, forwardPath, "INVALID_REQUEST", request, response);
89 }
90
91 try
92 {
93 configuration = configure(properties);
94
95 if (configuration.getFile().length() == 0)
96 {
97 configuration.getFile().delete();
98 setError(outputType, forwardPath, "FILE_NOT_FOUND_ERROR", request, response);
99 return;
100 }
101
102 restoredFile = pluginManager.run(configuration);
103 request.setAttribute("file", restoredFile);
104 request.setAttribute("fileType", configuration.getFileType());
105 request.setAttribute("charsetEncoding", "utf-8");
106 request.setAttribute("filename", properties.getFilename());
107 request.setAttribute("preserveMacrons", properties.getPreserveExistingMacrons());
108 request.setAttribute("options", properties.getOptions());
109 forward(forwardPath + "/main.jsp", request, response);
110 }
111 catch (UnsupportedOperationException uoex)
112 {
113 FileUtil.deleteFile(restoredFile);
114 logger.error("Failed to restore macrons on a file", uoex);
115 setError(outputType, forwardPath, "FILE_TYPE_NOT_SUPPORTED_ERROR", request, response);
116 }
117 catch (Exception ex)
118 {
119 FileUtil.deleteFile(restoredFile);
120 ex.printStackTrace();
121 logger.error("Failed to restore macrons on a file", ex);
122 setError(outputType, forwardPath, "UNEXPECTED_ERROR", request, response);
123 }
124 finally
125 {
126 if (configuration != null)
127 {
128 FileUtil.deleteFile(configuration.getFile());
129 }
130 }
131 }
132
133 private void setError(OutputType outputType, String forwardPath, String errorCode, HttpServletRequest request, HttpServletResponse response)
134 throws IOException, ServletException
135 {
136 switch (outputType) {
137 case Json:
138 // 500 Internal Server Error
139 response.sendError(500, errorCode);
140 break;
141 default:
142 request.setAttribute("errorMessage", errorCode);
143 forward(forwardPath + "/error.jsp", request, response);
144 break;
145 }
146 }
147
148 /**
149 * Forwards a request from a servlet to another resource on the server.
150 * @param path The path to forward to.
151 * @param request The servlet request.
152 * @param response The servlet response.
153 * @throws ServletException
154 * @throws IOException
155 */
156 private void forward(String path, HttpServletRequest request, HttpServletResponse response)
157 throws ServletException, IOException
158 {
159 final RequestDispatcher dispatcher = getServletContext().getRequestDispatcher(path);
160 dispatcher.forward(request, response);
161 }
162
163 private Properties handleRequest(HttpServletRequest request)
164 throws Exception, FileUploadException, IOException
165 {
166 Properties requestData = new Properties();
167 DiskFileItemFactory factory = new DiskFileItemFactory();
168 factory.setSizeThreshold(10 * 1024 * 1024);
169 ServletFileUpload upload = new ServletFileUpload(factory);
170
171 List<FileItem> items = new ArrayList<>();
172 for (Object element : upload.parseRequest(request)) {
173 items.add(FileItem.class.cast(element));
174 }
175
176 for (FileItem item : items)
177 {
178 if (item.isFormField())
179 {
180 String fieldName = item.getFieldName();
181 String fieldValue = item.getString();
182 if (fieldName.equals("charsetEncoding")) {
183 requestData.setCharsetEncoding(fieldValue);
184 } else if (fieldName.equals("fileType")) {
185 requestData.setFileType(fieldValue);
186 } else if (fieldName.equals("preserveExistingMacrons")) {
187 requestData.setPreserveExistingMacrons(fieldValue);
188 } else if (fieldName.equals("lang")) {
189 requestData.setLanguage(fieldValue);
190 } else if (fieldName.equals("options")) {
191 requestData.setOptions(fieldValue);
192 }
193 }
194 else
195 {
196 String fileType = FileUtil.guessFileType(new File(item.getName()));
197 File file = File.createTempFile(FileUtil.TMP_FILE_PREFIX, fileType, tmpdir);
198 item.write(file);
199 requestData.setFile(file);
200 requestData.setFilename(item.getName());
201 }
202 }
203
204 return requestData;
205 }
206
207 /* Useful for debugging file operations */
208 // private String readStringFromFile(File file)
209 // throws FileNotFoundException, IOException
210 // {
211 // BufferedReader reader = new BufferedReader(new FileReader(file));
212 // String line = null;
213 // StringBuilder sb = new StringBuilder();
214
215 // try
216 // {
217 // while ((line=reader.readLine()) != null)
218 // {
219 // sb.append(line);
220 // }
221 // }
222 // finally
223 // {
224 // reader.close();
225 // }
226
227 // return sb.toString();
228 // }
229
230 private PluginConfiguration configure(Properties properties)
231 {
232 final File file = properties.getFile();
233 final String fileType = properties.getFileType().equals("(detect automatically)") ? FileUtil.guessFileType(file) : properties.getFileType();
234 final String charsetEncoding = properties.getCharsetEncoding().equals("(detect automatically)") ? "utf8" : properties.getCharsetEncoding();
235 final String preserveExistingMacrons = properties.getPreserveExistingMacrons();
236
237 final PluginConfiguration configuration = new PluginConfiguration();
238 configuration.setFile(file);
239 configuration.setFileType(fileType);
240 configuration.setCharsetEncoding(charsetEncoding);
241 configuration.setPreserveExistingMacrons(Boolean.getBoolean(preserveExistingMacrons));
242
243 return configuration;
244 }
245
246 private class Properties
247 {
248 private File file;
249 private String filename;
250 private String fileType;
251 private String charsetEncoding;
252 private String preserveExistingMacrons;
253 private String language;
254 private String options;
255
256 public File getFile() {
257 return file;
258 }
259
260 public String getFilename() {
261 return filename;
262 }
263
264 public String getFileType() {
265 return fileType;
266 }
267
268 public String getCharsetEncoding() {
269 return charsetEncoding;
270 }
271
272 public String getPreserveExistingMacrons() {
273 return preserveExistingMacrons;
274 }
275
276 @SuppressWarnings("unused")
277 public String getLanguage() {
278 return language;
279 }
280
281 public String getOptions() {
282 return options;
283 }
284
285 public void setFile(File file) {
286 this.file = file;
287 }
288
289 public void setFilename(String filename) {
290 this.filename = filename;
291 }
292
293 public void setFileType(String fileType) {
294 this.fileType = fileType;
295 }
296
297 public void setCharsetEncoding(String charsetEncoding) {
298 this.charsetEncoding = charsetEncoding;
299 }
300
301 public void setPreserveExistingMacrons(String preserveExistingMacrons) {
302 this.preserveExistingMacrons = preserveExistingMacrons;
303 }
304
305 public void setLanguage(String language) {
306 this.language = language;
307 }
308
309 public void setOptions(String options) {
310 this.options = options;
311 }
312 }
313}
Note: See TracBrowser for help on using the repository browser.