Index: other-projects/the-macronizer/trunk/src/java/web/servlets/FileUpload.java
===================================================================
--- other-projects/the-macronizer/trunk/src/java/web/servlets/FileUpload.java	(revision 31964)
+++ other-projects/the-macronizer/trunk/src/java/web/servlets/FileUpload.java	(revision 35719)
@@ -1,10 +1,9 @@
 package web.servlets;
 
-import java.io.BufferedReader;
 import java.io.File;
-import java.io.FileReader;
 import java.io.IOException;
-import java.lang.StringBuilder;
+import java.util.ArrayList;
 import java.util.List;
+
 import javax.servlet.RequestDispatcher;
 import javax.servlet.ServletConfig;
@@ -13,11 +12,15 @@
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
+
+import monogram.plugin.PluginConfiguration;
+import monogram.plugin.PluginManager;
+
 import org.apache.commons.fileupload.FileItem;
+import org.apache.commons.fileupload.FileUploadException;
 import org.apache.commons.fileupload.disk.DiskFileItemFactory;
 import org.apache.commons.fileupload.servlet.ServletFileUpload;
-import monogram.plugin.PluginConfiguration;
+import org.apache.log4j.*;
+
 import util.FileUtil;
-import monogram.plugin.PluginManager;
-import org.apache.log4j.*;
 
 /**
@@ -28,26 +31,32 @@
 public class FileUpload extends HttpServlet {
 
+    // Create an instance of the logger object defined for the DirectInput servlet in log4j.properties.
+    private static final Logger logger = Logger.getLogger(web.servlets.DirectInput.class.getName());
+
     private File tmpdir;
-    private String inputFile;
-    private String outputFile;
-
-    //Create an instance of the Logger object created for this class in log4j.properties            
-    static Logger logger = Logger.getLogger(web.servlets.DirectInput.class.getName());
+    private PluginManager pluginManager;
 
     @Override
-    public void init(ServletConfig config) throws ServletException {
+    public void init(ServletConfig config)
+        throws ServletException
+    {
         super.init(config);
+
         tmpdir = new File((String) config.getServletContext().getAttribute("tmpdir"));
-    }
-
-    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
-            throws ServletException, IOException {
-        //do nothing
-    }
-
+        pluginManager = new PluginManager(tmpdir);
+    }
+
+    /** 
+     * Handles the HTTP <code>GET</code> method.
+     * @param request The servlet request.
+     * @param response The servlet response.
+     * @throws IllegalStateException if a reponse has already been committed.
+     * @throws IOException if an I/O error occurs.
+     */
     @Override
     protected void doGet(HttpServletRequest request, HttpServletResponse response)
-            throws ServletException, IOException {
-        processRequest(request, response);
+            throws IllegalStateException, IOException
+    {
+        response.sendError(405); // 405 Method Not Allowed
     }
 
@@ -61,21 +70,34 @@
     @Override
     protected void doPost(HttpServletRequest request, HttpServletResponse response)
-            throws ServletException, IOException {
-        // set DI to false as this is not Directinput.
-       DirectInput.DI = false; 
-        final Properties properties = handleRequest(request);
-        final String address = "/jsp" + (properties.getLanguage().equals("en") ? "/en" : "/mi");
-        final PluginConfiguration configuration = configure(properties);
-        final PluginManager pluginManager = new PluginManager(tmpdir);
-
-        if (configuration.getFile().length() == 0) {
-            configuration.getFile().delete();
-            request.setAttribute("errorCode", "FILE_NOT_FOUND_ERROR");
-            forward(address + "/error.jsp", request, response);
-            return;
-        }
-
+        throws IllegalStateException, IOException, ServletException
+    {
+        final OutputType outputType = OutputType.parse(request.getParameter("o")); // TODO: This probably won't work with the multipart request
+        
         File restoredFile = null;
-        try {
+        PluginConfiguration configuration = null;
+        Properties properties = null;
+        String forwardPath = "/jsp/mi";
+
+        try
+        {
+            properties = handleRequest(request);
+            forwardPath = properties.getLanguage() != null ? "/jsp/" + properties.getLanguage() : forwardPath;
+        }
+        catch (Exception ex)
+        {
+            setError(outputType, forwardPath, "INVALID_REQUEST", request, response);
+        }
+
+        try
+        {
+            configuration = configure(properties);
+
+            if (configuration.getFile().length() == 0)
+            {
+                configuration.getFile().delete();
+                setError(outputType, forwardPath, "FILE_NOT_FOUND_ERROR", request, response);
+                return;
+            }
+
             restoredFile = pluginManager.run(configuration);
             request.setAttribute("file", restoredFile);
@@ -85,85 +107,127 @@
             request.setAttribute("preserveMacrons", properties.getPreserveExistingMacrons());
             request.setAttribute("options", properties.getOptions());
-            forward(address + "/main.jsp", request, response);
-	    outputFile = stringFromFile(restoredFile);
-	    logger.error("Output:"+outputFile);
-        } catch (UnsupportedOperationException e) {
+            forward(forwardPath + "/main.jsp", request, response);
+        }
+        catch (UnsupportedOperationException uoex)
+        {
             FileUtil.deleteFile(restoredFile);
-            request.setAttribute("errorCode", "FILE_TYPE_NOT_SUPPORTED_ERROR");
-            forward(address + "/error.jsp", request, response);
-        } catch (Exception e) {
+            logger.error("Failed to restore macrons on a file", uoex);
+            setError(outputType, forwardPath, "FILE_TYPE_NOT_SUPPORTED_ERROR", request, response);
+        }
+        catch (Exception ex)
+        {
             FileUtil.deleteFile(restoredFile);
-            request.setAttribute("errorCode", "UNEXPECTED_ERROR");
-            forward(address + "/error.jsp", request, response);
-        } finally {
-            FileUtil.deleteFile(configuration.getFile());
-        }
-    }
-
+            ex.printStackTrace();
+            logger.error("Failed to restore macrons on a file", ex);
+            setError(outputType, forwardPath, "UNEXPECTED_ERROR", request, response);
+        }
+        finally
+        {
+            if (configuration != null)
+            {
+                FileUtil.deleteFile(configuration.getFile());
+            }
+        }
+    }
+
+    private void setError(OutputType outputType, String forwardPath, String errorCode, HttpServletRequest request, HttpServletResponse response)
+        throws IOException, ServletException
+    {
+        switch (outputType) {
+            case Json:
+                // 500 Internal Server Error
+                response.sendError(500, errorCode);
+                break;
+            default:
+                request.setAttribute("errorMessage", errorCode);
+                forward(forwardPath + "/error.jsp", request, response);
+                break;
+        }
+    }
+
+    /**
+     * Forwards a request from a servlet to another resource on the server.
+     * @param path The path to forward to.
+     * @param request The servlet request.
+     * @param response The servlet response.
+     * @throws ServletException
+     * @throws IOException
+     */
     private void forward(String path, HttpServletRequest request, HttpServletResponse response)
-            throws ServletException, IOException {
+            throws ServletException, IOException
+    {
         final RequestDispatcher dispatcher = getServletContext().getRequestDispatcher(path);
         dispatcher.forward(request, response);
     }
 
-    private Properties handleRequest(HttpServletRequest request) {
+    private Properties handleRequest(HttpServletRequest request)
+        throws Exception, FileUploadException, IOException
+    {
         Properties requestData = new Properties();
         DiskFileItemFactory factory = new DiskFileItemFactory();
         factory.setSizeThreshold(10 * 1024 * 1024);
         ServletFileUpload upload = new ServletFileUpload(factory);
-        try {
-            //System.out.println("looking at request parameters...");
-            List<FileItem> items = upload.parseRequest(request);
-
-            for (FileItem item : items) {
-                if (item.isFormField()) {
-                    String fieldName = item.getFieldName();
-                    String fieldValue = item.getString();
-                    if (fieldName.equals("charsetEncoding")) {
-                        requestData.setCharsetEncoding(fieldValue);
-                    } else if (fieldName.equals("fileType")) {
-                        requestData.setFileType(fieldValue);
-                    } else if (fieldName.equals("preserveExistingMacrons")) {
-                        requestData.setPreserveExistingMacrons(fieldValue);
-                    } else if (fieldName.equals("lang")) {
-                        requestData.setLanguage(fieldValue);
-                    } else if (fieldName.equals("options")) {
-                        requestData.setOptions(fieldValue);
-                    }
-                } else {
-                    String fileType = FileUtil.guessFileType(new File(item.getName()));
-                    File file = File.createTempFile("mi-tmp-", fileType, tmpdir);
-                    item.write(file);
-                    requestData.setFile(file);
-                    requestData.setFilename(item.getName());
-		    inputFile=stringFromFile(file);
-		    // logger.error("Input:"+logText);
+
+        List<FileItem> items = new ArrayList<>();
+        for (Object element : upload.parseRequest(request)) {
+            items.add(FileItem.class.cast(element));
+        }
+
+        for (FileItem item : items)
+        {
+            if (item.isFormField())
+            {
+                String fieldName = item.getFieldName();
+                String fieldValue = item.getString();
+                if (fieldName.equals("charsetEncoding")) {
+                    requestData.setCharsetEncoding(fieldValue);
+                } else if (fieldName.equals("fileType")) {
+                    requestData.setFileType(fieldValue);
+                } else if (fieldName.equals("preserveExistingMacrons")) {
+                    requestData.setPreserveExistingMacrons(fieldValue);
+                } else if (fieldName.equals("lang")) {
+                    requestData.setLanguage(fieldValue);
+                } else if (fieldName.equals("options")) {
+                    requestData.setOptions(fieldValue);
                 }
             }
-        } catch (Exception e) {
-            e.printStackTrace();
-        }
+            else
+            {
+                String fileType = FileUtil.guessFileType(new File(item.getName()));
+                File file = File.createTempFile(FileUtil.TMP_FILE_PREFIX, fileType, tmpdir);
+                item.write(file);
+                requestData.setFile(file);
+                requestData.setFilename(item.getName());
+            }
+        }
+
         return requestData;
     }
     
-    private String stringFromFile(File file)throws IOException{
-	BufferedReader reader = new BufferedReader(new FileReader(file));
-	String line = null;
-	StringBuilder sb = new StringBuilder();
-	try{
-	    while((line=reader.readLine())!=null){
-		sb.append(line);
-	    }
-	}
-	catch (Exception e){
-	    e.printStackTrace();
-	}
-	finally{
-	    reader.close();
-	}
-        return sb.toString();
-    }
+    /* Useful for debugging file operations */
+    // private String readStringFromFile(File file)
+    //     throws FileNotFoundException, IOException
+    // {
+    //     BufferedReader reader = new BufferedReader(new FileReader(file));
+    //     String line = null;
+    //     StringBuilder sb = new StringBuilder();
+
+    //     try
+    //     {
+    //         while ((line=reader.readLine()) != null)
+    //         {
+    //             sb.append(line);
+    //         }
+    //     }
+    //     finally
+    //     {
+    //         reader.close();
+    //     }
+
+    //     return sb.toString();
+    // }
     
-    private PluginConfiguration configure(Properties properties) {
+    private PluginConfiguration configure(Properties properties)
+    {
         final File file = properties.getFile();
         final String fileType = properties.getFileType().equals("(detect automatically)") ? FileUtil.guessFileType(file) : properties.getFileType();
@@ -176,9 +240,10 @@
         configuration.setCharsetEncoding(charsetEncoding);
         configuration.setPreserveExistingMacrons(Boolean.getBoolean(preserveExistingMacrons));
+
         return configuration;
     }
 
-    private class Properties {
-
+    private class Properties
+    {
         private File file;
         private String filename;
@@ -209,4 +274,5 @@
         }
 
+        @SuppressWarnings("unused")
         public String getLanguage() {
             return language;
