com.idr.servlets.UploadServlet.java Source code

Java tutorial

Introduction

Here is the source code for com.idr.servlets.UploadServlet.java

Source

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.idr.servlets;

import com.idr.conversion.Converter;
import com.idr.misc.Flag;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.print.attribute.standard.PageRanges;
import javax.servlet.ServletException;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.io.FileUtils;
import org.jpedal.PdfDecoderServer;

/**
 * Servlet responsible for handling conversion and progression requests from
 * client.
 */
@MultipartConfig
@WebServlet(name = "UploadServlet", urlPatterns = { "/UploadServlet", "/UploadServletProgress",
        "/UploadServletCancel" })
public class UploadServlet extends HttpServlet {

    private boolean isZipLinkOutput = true;
    private boolean isEditorLinkOutput = false;
    private volatile Thread counterThread = null;
    private int conversionCount = 0;
    private int totalConversions = 1; //there will always be at least 1 conversion
    private boolean isZip = false;
    private boolean isPDF = true;
    private Converter con;
    private Thread currentThread;

    /**
     * Processes requests for both HTTP <code>GET</code> and <code>POST</code>
     * methods.
     *
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        if (request.getRequestURI().endsWith("UploadServletProgress")) {
            try {
                doStatus(request, response);
            } catch (Exception ex) {
                Logger.getLogger(UploadServlet.class.getName()).log(Level.SEVERE, null, ex);
            }
        } else if (request.getRequestURI().endsWith("UploadServletCancel")) {
            cancelUpload(request, response);
        } else {
            doFileUpload(request, response);
        }
    }

    /**
     * Cancel the thread which runs the conversion
     * @param session
     * @param response
     */
    private void cancelUpload(HttpServletRequest request, HttpServletResponse response) {
        if (currentThread != null && currentThread.isAlive()) {
            try {
                currentThread.interrupt();
                currentThread.stop();//deprecated but use it now
            } catch (Exception e) {
                //
            }
            String[] attrArray = { "href", "FILE_UPLOAD_STATS", "pageCount", "pageReached", "isUploading",
                    "isConvertAlive", "convert", "isZipping" };
            for (String attr : attrArray) {
                request.getSession().removeAttribute(attr);
            }
        }
        conversionCount = 0;
        totalConversions = 1;
    }

    /**
     * Uploading the file to the sever and complete the conversion
     * @param request
     * @param response 
     */
    private void doFileUpload(HttpServletRequest request, HttpServletResponse response) {

        //        System.out.println("Doing upload"+System.currentTimeMillis());
        HttpSession session = request.getSession();

        session.setAttribute("href", null);
        session.setAttribute("FILE_UPLOAD_STATS", null);
        session.setAttribute("pageCount", 0);
        session.setAttribute("pageReached", 0);
        session.setAttribute("isUploading", "true");
        session.setAttribute("isConverting", "false");
        session.setAttribute("convertType", "html");
        session.setAttribute("isZipping", "false");
        con = new Converter();
        byte[] fileBytes = null;

        String sessionId = session.getId();
        String userFileName = "";
        HashMap<String, String> paramMap = new HashMap<String, String>();
        int conType = Converter.getConversionType(request.getRequestURI());

        int startPageNumber = 1;
        int pageCount = 0;

        try {

            if (ServletFileUpload.isMultipartContent(request)) {
                FileItemFactory factory = new DiskFileItemFactory();
                ServletFileUpload upload = new ServletFileUpload(factory);
                UploadListener listener = new UploadListener();//listens file uploads                  
                upload.setProgressListener(listener);
                session.setAttribute("FILE_UPLOAD_STATS", listener);
                List<FileItem> fields = upload.parseRequest(request);
                Iterator<FileItem> it = fields.iterator();
                FileItem fileItem = null;
                if (!it.hasNext()) {
                    return;//("No fields found");
                }
                while (it.hasNext()) {
                    FileItem field = it.next();
                    if (field.isFormField()) {
                        String fieldName = field.getFieldName();
                        Flag.updateParameterMap(fieldName, field.getString(), paramMap);
                        field.delete();
                    } else {
                        fileItem = field;
                    }
                }
                //Flags whether the file is a .zip or a .pdf
                if (fileItem.getName().contains(".pdf")) {
                    isPDF = true;
                    isZip = false;
                } else if (fileItem.getName().contains(".zip")) {
                    isZip = true;
                    isPDF = false;
                }
                //removes the last 4 chars and replaces odd chars with underscore
                userFileName = fileItem.getName().substring(0, fileItem.getName().length() - 4)
                        .replaceAll("[^a-zA-Z0-9]", "_");
                fileBytes = fileItem.get();
                fileItem.delete();
            }

            // Delete existing editor files if any exist. 
            if (isEditorLinkOutput) {
                File editorFolder = new File(Converter.EDITORPATH + "/" + sessionId + "/");
                if (editorFolder.exists()) {
                    FileUtils.deleteDirectory(editorFolder);
                }
            }
            con.initializeConversion(sessionId, userFileName, fileBytes, isZip);
            PdfDecoderServer decoder = new PdfDecoderServer(false);
            decoder.openPdfFile(con.getUserPdfFilePath());
            pageCount = decoder.getPageCount();
            //Check whether or not the PDF contains forms
            if (decoder.isForm()) {
                session.setAttribute("isForm", "true"); //set an attrib for extraction.jps to use
                response.getWriter().println("<div id='isForm'></div>");
            } else if (!decoder.isForm()) {
                session.setAttribute("isForm", "false"); //set an attrib for extraction.jps to use
            }
            //Check whther or not the PDF is XFA
            if (decoder.getFormRenderer().isXFA()) {
                session.setAttribute("isXFA", "true");
                //                response.getWriter().println("<div id='isXFA'></div>");
            } else if (!decoder.getFormRenderer().isXFA()) {
                session.setAttribute("isXFA", "false");
            }
            decoder.closePdfFile(); //closes file

            if (paramMap.containsKey("org.jpedal.pdf2html.realPageRange")) {
                String tokensCSV = (String) paramMap.get("org.jpedal.pdf2html.realPageRange");
                PageRanges range = new PageRanges(tokensCSV);
                ArrayList<Integer> rangeList = new ArrayList<Integer>();
                for (int z = 0; z < pageCount; z++) {
                    if (range.contains(z)) {
                        rangeList.add(z);
                    }
                }
                int userPageCount = rangeList.size();
                if (rangeList.size() > 0) {
                    session.setAttribute("pageCount", userPageCount);
                } else {
                    throw new Exception("invalid Page Range");
                }
            } else {
                session.setAttribute("pageCount", pageCount);
            }

            session.setAttribute("isUploading", "false");
            session.setAttribute("isConverting", "true");

            String scales = paramMap.get("org.jpedal.pdf2html.scaling");
            String[] scaleArr = null;
            String userOutput = con.getUserFileDirName();
            if (scales != null && scales.contains(",")) {
                scaleArr = scales.split(",");
            }

            String reference = UploadServlet.getConvertedFileHref(sessionId, userFileName, conType, pageCount,
                    startPageNumber, paramMap, scaleArr, isZip) + "<br/><br/>";

            if (isZipLinkOutput) {
                reference = reference + con.getZipFileHref(userOutput, scaleArr);
            }

            if (isEditorLinkOutput && conType != Converter.PDF2ANDROID && conType != Converter.PDF2IMAGE) {
                reference = reference + "<br/><br/>" + con.getEditorHref(userOutput, scaleArr); // editor link
            }
            String typeString = Converter.getConversionTypeAsString(conType);

            converterThread(userFileName, scaleArr, fileBytes, typeString, paramMap, session, pageCount, reference);

        } catch (Exception ex) {
            session.setAttribute("href", "<end></end><div class='errorMsg'>Error: " + ex.getMessage() + "</div>");
            Logger.getLogger(UploadServlet.class.getName()).log(Level.SEVERE, null, ex);
            cancelUpload(request, response);
        }
    }

    /**
     * method responsible for calling the conversion and counting the number of
     * conversions performed
     * @param fileName
     * @param scaleArr can be null
     * @param byteData
     * @param conTypeStr
     * @param map
     * @param session
     * @param pageCount
     * @param reference
     * @throws Exception 
     */
    private void converterThread(final String fileName, final String[] scaleArr, final byte[] byteData,
            final String conTypeStr, final HashMap<String, String> map, final HttpSession session,
            final int pageCount, final String reference) throws Exception {
        final String tempFileName = fileName;
        currentThread = new Thread(new Runnable() {

            public void run() {
                try {
                    if (scaleArr != null && scaleArr.length > 0) {
                        for (int z = 0; z < scaleArr.length; z++) {
                            map.put("org.jpedal.pdf2html.scaling", scaleArr[z]);
                            con.setUserFileDirName(fileName + scaleArr[z]);
                            File userPdfFile = new File(con.getUserPdfFilePath());
                            File file = new File(
                                    userPdfFile.getParent() + File.separator + fileName + scaleArr[z] + ".pdf");
                            userPdfFile.renameTo(file);
                            con.setUserPdfFilePath(file.getPath());
                            totalConversions = scaleArr.length;
                            conversionCount++;
                            con.convert(conTypeStr, map);
                        }
                    } else {
                        conversionCount = 1;
                        con.convert(conTypeStr, map);
                    }
                    session.setAttribute("isConverting", "false");
                    session.setAttribute("isZipping", "false");
                    session.setAttribute("href", reference);
                    conversionCount = 0; //reset the conversion counter
                } catch (Exception ex) {
                    session.setAttribute("href", "<div class='errorMsg'> " + ex.getMessage() + "</div>");
                }
            }
        });

        currentThread.start();

        counterThread = new Thread() {
            @Override
            public void run() {
                while (currentThread != null && currentThread.isAlive()) {
                    try {
                        int totalConvertedFiles = 0;
                        String temp = fileName;
                        if (scaleArr != null && conversionCount != 0 && conversionCount <= scaleArr.length) {
                            temp = fileName + "" + scaleArr[conversionCount - 1];
                        }
                        File conDir = new File(con.getUserOutputDirPath() + File.separator + temp);
                        if (!conDir.exists()) {
                            conDir.mkdirs();
                        }
                        String extStr = null;
                        String str = conTypeStr.toLowerCase();
                        if (str.endsWith("svg")) {
                            extStr = ".svg";
                        } else if (str.endsWith("android")) {
                            extStr = ".html";
                            String appSafeFileName = fileName;
                            char firstLetter = fileName.charAt(0);
                            if (firstLetter >= '0' && firstLetter <= '9') {
                                appSafeFileName = "_" + appSafeFileName;
                            }
                            conDir = new File(con.getUserOutputDirPath() + File.separator + appSafeFileName
                                    + "/assets/html/" + temp);
                        } else {
                            extStr = ".html";
                        }
                        for (String s : conDir.list()) {
                            if (pageCount == 1) {
                                if (s.endsWith(extStr)) {
                                    totalConvertedFiles++;
                                }
                            } else {
                                if (s.endsWith(extStr) && !s.contains("index")) {
                                    totalConvertedFiles++;
                                }
                            }
                        }
                        if (session != null) {
                            session.setAttribute("pageReached", totalConvertedFiles);
                        }
                        counterThread.sleep(1000);
                    } catch (InterruptedException ex) {

                    }
                }
            }
        };
        counterThread.start();
    }

    /**
     * method check the current status of upload and conversion and sending response
     * to the client 
     * @param session
     * @param response
     * @throws Exception 
     */
    private void doStatus(HttpServletRequest request, HttpServletResponse response) throws Exception {
        //        System.out.println("Doing Status"+System.currentTimeMillis());
        HttpSession session = request.getSession();
        if (session == null) {
            return;
        }
        // Make sure the status response is not cached by the browser
        response.addHeader("Expires", "0");
        response.addHeader("Cache-Control", "no-store, no-cache, must-revalidate");
        response.addHeader("Cache-Control", "post-check=0, pre-check=0");
        response.addHeader("Pragma", "no-cache");

        UploadListener fileUploadStats = null;
        if (session.getAttribute("FILE_UPLOAD_STATS") != null) {
            fileUploadStats = (UploadListener) session.getAttribute("FILE_UPLOAD_STATS");
        }
        if (session.getAttribute("href") == null) {
            if (session.getAttribute("isUploading") != null && session.getAttribute("isUploading").equals("true")
                    && fileUploadStats != null) {
                response.getWriter().println("<div class=\"prog-border\"><div class=\"prog-bar\" style=\"width: "
                        + fileUploadStats.getPercent() + "%;\"></div></div>");
                response.getWriter().println("Uploading: " + fileUploadStats.getMessage() + " ("
                        + fileUploadStats.getPercent() + "%) <br/>");
                response.getWriter().println("<div id='currentSt'>uploading</div>");
            } else if (session.getAttribute("isConverting") != null && session.getAttribute("pageCount") != null
                    && session.getAttribute("isConverting").equals("true")) {
                int pageCount = (Integer) session.getAttribute("pageCount");
                int pageReached = (Integer) session.getAttribute("pageReached");
                if (pageCount > 0) {
                    int percentage = (int) Math.round(100.00 * pageReached / pageCount);
                    //                    if (session.getAttribute("fileAlreadyUploaded").equals("true")) {
                    //                        response.getWriter().println("<p>File already uploaded</p>");
                    //                    }
                    response.getWriter().println("<div class=\"convert-border\">"
                            + "<div class=\"convert-bar\" style=\"width: " + percentage + "%;\"></div></div>");
                    response.getWriter()
                            .println("Converting " + conversionCount + " of " + totalConversions
                                    + " documents.<br/> Converting " + pageReached + " of " + pageCount + " pages ("
                                    + percentage + "% complete)<br/>");
                    response.getWriter().println("<div id='currentSt'>converting</div>");
                }
            } else if (session.getAttribute("isZipping") != null
                    && session.getAttribute("isZipping").equals("true")) {
                response.getWriter().println("Zipping: " + "<img src='img/uploading.gif'/>");
                response.getWriter().println("<div id='currentSt'>zipping</div>");
            }
        } else {
            response.getWriter().println("<end></end>" + session.getAttribute("href") + "<br/>");
            response.getWriter().println("<div id='currentSt'></div>");
            cancelUpload(request, response);
        }
    }

    //    private static String getFilename(Part part) {
    //        for (String cd : part.getHeader("content-disposition").split(";")) {
    //            if (cd.trim().startsWith("filename")) {
    //                String filename = cd.substring(cd.indexOf('=') + 1).trim().replace("\"", "");
    //                return filename.substring(filename.lastIndexOf('/') + 1).substring(filename.lastIndexOf('\\') + 1); // MSIE fix.
    //            }
    //        }
    //        return null;
    //    }

    /**
     * retrieve the converted file location of Href as String
     * @param uniqueId
     * @param userFileName
     * @param conT
     * @param pageCount
     * @param startPageNumber
     * @param paramMap
     * @param scaleArr
     * @param isZip
     * @return
     * @throws Exception 
     */
    public static String getConvertedFileHref(String uniqueId, String userFileName, int conT, int pageCount,
            int startPageNumber, Map paramMap, String[] scaleArr, boolean isZip) throws Exception {

        // Currently there is no online view for the Android
        if (conT == Converter.PDF2ANDROID) {
            return "";
        }
        String firstPageName = (String) paramMap.get("org.jpedal.pdf2html.firstPageName");
        if (firstPageName == null) {
            firstPageName = "index";
            //firstPageName = calculatePageName(pageCount, startPageNumber);
        }
        String extStr = Converter.getConvertExtension(conT);
        String startFileName = firstPageName + extStr;
        if (scaleArr != null) {
            String ref = "View Online:"; //return string & title
            String spacer = ", "; //to break up href links
            String suffix = "%"; //atached to end of percentage links
            String percents = ""; //holds the percetage links
            String resolutions = "";//holds the resolution scale links
            for (int z = 0; z < scaleArr.length; z++) {
                String link = "";
                if (scaleArr[z].contains("fit")) {
                    link = scaleArr[z];
                    suffix = "";
                } else if (scaleArr[z].contains("x")) {
                    link = scaleArr[z];
                    suffix = "";
                } else {
                    link = "" + (Double.parseDouble(scaleArr[z].replaceAll("_", ".")) * 100);
                }

                //Controls position of Percentage ad Resolution links
                if (scaleArr[z].contains("x")) {
                    if (z <= scaleArr.length - 2) {
                        resolutions = resolutions + "<a href='output/" + uniqueId + "/" + userFileName + ""
                                + scaleArr[z] + "/" + startFileName + "' target='_blank'>" + link + "" + suffix
                                + "</a>" + spacer;
                    } else {
                        resolutions = resolutions + "<a href='output/" + uniqueId + "/" + userFileName + ""
                                + scaleArr[z] + "/" + startFileName + "' target='_blank'>" + link + "" + suffix
                                + "</a>";
                    }
                } else {
                    if (z <= scaleArr.length - 2) {
                        percents = percents + "<a href='output/" + uniqueId + "/" + userFileName + "" + scaleArr[z]
                                + "/" + startFileName + "' target='_blank'>" + link + "" + suffix + "</a>" + spacer;
                    } else {
                        percents = percents + "<a href='output/" + uniqueId + "/" + userFileName + "" + scaleArr[z]
                                + "/" + startFileName + "' target='_blank'>" + link + "" + suffix + "</a>";
                    }
                }
            }
            return ref = "<u>" + ref + "</u>" + "<br>" + "Percentage: " + percents + "<br>" + "Resolution: "
                    + resolutions;
        }
        if (!isZip) {
            return "<a href='output/" + uniqueId + "/" + userFileName + "/" + startFileName
                    + "' target='_blank'>View Online</a>";
        }
        return "";
    }

    // <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on the + sign on the left to edit the code.">
    /**
     * Handles the HTTP <code>GET</code> method.
     *
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    /**
     * Handles the HTTP <code>POST</code> method.
     *
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    /**
     * Returns a short description of the servlet.
     *
     * @return a String containing servlet description
     */
    @Override
    public String getServletInfo() {
        return "Short description";
    }// </editor-fold>

}