nu.kelvin.jfileshare.ajax.FileReceiverServlet.java Source code

Java tutorial

Introduction

Here is the source code for nu.kelvin.jfileshare.ajax.FileReceiverServlet.java

Source

/**
 *  Copyright 2011 SECTRA Imtec AB
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 * @author      Markus Berg <markus.berg @ sectra.se>
 * @version     1.6
 * @since       2011-09-21
 */
package nu.kelvin.jfileshare.ajax;

import nu.kelvin.jfileshare.objects.Conf;
import nu.kelvin.jfileshare.objects.FileItem;
import nu.kelvin.jfileshare.objects.UserItem;
import nu.kelvin.jfileshare.utils.Helpers;

import java.io.File;

import java.io.InputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;

import java.security.MessageDigest;
import java.security.DigestOutputStream;
// import java.text.DecimalFormat;
// import java.text.NumberFormat;
import java.util.logging.Level;

import java.util.logging.Logger;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;

import javax.sql.DataSource;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;

import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.FileItemIterator;
import org.apache.commons.fileupload.FileItemStream;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.FileUploadBase.SizeLimitExceededException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.fileupload.util.Streams;
import org.apache.commons.io.IOUtils;

/**
 * Send an xml response to how the upload is progressing
 *
 * @author markus
 */
public class FileReceiverServlet extends HttpServlet {
    static final long serialVersionUID = 1L;

    private DataSource ds;
    private static final Logger logger = Logger.getLogger(FileReceiverServlet.class.getName());

    @Override
    public void init(ServletConfig config) throws ServletException {
        super.init(config);

        try {
            Context env = (Context) new InitialContext().lookup("java:comp/env");
            ds = (DataSource) env.lookup("jdbc/jfileshare");
        } catch (NamingException e) {
            throw new ServletException(e);
        }
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        PrintWriter out = resp.getWriter();
        HttpSession session = req.getSession();

        resp.setContentType("text/xml;charset=UTF-8");

        FileUploadListener listener = (FileUploadListener) session.getAttribute("uploadListener");
        if (listener == null) {
            listener = new FileUploadListener();
        }

        try {
            JAXBContext context = JAXBContext.newInstance(FileUploadListener.class);
            Marshaller marshaller = context.createMarshaller();
            marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
            marshaller.marshal(listener, out);
        } catch (Exception ignore) {
        }
        out.flush();
        out.close();
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        HttpSession session = req.getSession();
        UserItem currentUser = (UserItem) session.getAttribute("user");
        if (currentUser != null && ServletFileUpload.isMultipartContent(req)) {
            Conf conf = (Conf) getServletContext().getAttribute("conf");
            // keep files of up to 10 MiB in memory 10485760
            FileItemFactory factory = new DiskFileItemFactory(10485760, new File(conf.getPathTemp()));
            ServletFileUpload upload = new ServletFileUpload(factory);
            upload.setSizeMax(conf.getFileSizeMax());

            // set file upload progress listener
            FileUploadListener listener = new FileUploadListener();
            session.setAttribute("uploadListener", listener);
            upload.setProgressListener(listener);

            File tempFile = File.createTempFile(String.format("%05d-", currentUser.getUid()), null,
                    new File(conf.getPathTemp()));
            tempFile.deleteOnExit();
            try {
                FileItem file = new FileItem();

                /* iterate over all uploaded items */
                FileItemIterator it = upload.getItemIterator(req);
                FileOutputStream filestream = null;

                while (it.hasNext()) {
                    FileItemStream item = it.next();
                    String name = item.getFieldName();
                    InputStream instream = item.openStream();
                    DigestOutputStream outstream = null;

                    if (item.isFormField()) {
                        String value = Streams.asString(instream);
                        // logger.info(name + " : " + value);
                        /* not the file upload. Maybe the password field? */
                        if (name.equals("password") && !value.equals("")) {
                            logger.info("Uploaded file has password set");
                            file.setPwPlainText(value);
                        }
                        instream.close();
                    } else {
                        // This is the file you're looking for
                        file.setName(item.getName());
                        file.setType(
                                item.getContentType() == null ? "application/octet-stream" : item.getContentType());
                        file.setUid(currentUser.getUid());

                        try {
                            filestream = new FileOutputStream(tempFile);
                            MessageDigest md = MessageDigest.getInstance("MD5");
                            outstream = new DigestOutputStream(filestream, md);
                            long filesize = IOUtils.copyLarge(instream, outstream);

                            if (filesize == 0) {
                                throw new Exception("File is empty.");
                            }
                            md = outstream.getMessageDigest();
                            file.setMd5sum(toHex(md.digest()));
                            file.setSize(filesize);

                        } finally {
                            if (outstream != null) {
                                try {
                                    outstream.close();
                                } catch (IOException ignored) {
                                }
                            }
                            if (filestream != null) {
                                try {
                                    filestream.close();
                                } catch (IOException ignored) {
                                }
                            }
                            if (instream != null) {
                                try {
                                    instream.close();
                                } catch (IOException ignored) {
                                }
                            }
                        }
                    }
                }
                /* All done. Save the new file */
                if (conf.getDaysFileExpiration() != 0) {
                    file.setDaysToKeep(conf.getDaysFileExpiration());
                }
                if (file.create(ds, req.getRemoteAddr())) {
                    File finalFile = new File(conf.getPathStore(), Integer.toString(file.getFid()));
                    tempFile.renameTo(finalFile);
                    logger.log(Level.INFO, "User {0} storing file \"{1}\" in the filestore",
                            new Object[] { currentUser.getUid(), file.getName() });
                    req.setAttribute("msg",
                            "File <strong>\"" + Helpers.htmlSafe(file.getName())
                                    + "\"</strong> uploaded successfully. <a href='" + req.getContextPath()
                                    + "/file/edit/" + file.getFid() + "'>Click here to edit file</a>");
                    req.setAttribute("javascript", "parent.uploadComplete('info');");
                } else {
                    req.setAttribute("msg", "Unable to contact the database");
                    req.setAttribute("javascript", "parent.uploadComplete('critical');");
                }
            } catch (SizeLimitExceededException e) {
                tempFile.delete();
                req.setAttribute("msg", "File is too large. The maximum size of file uploads is "
                        + FileItem.humanReadable(conf.getFileSizeMax()));
                req.setAttribute("javascript", "parent.uploadComplete('warning');");
            } catch (FileUploadException e) {
                tempFile.delete();
                req.setAttribute("msg", "Unable to upload file");
                req.setAttribute("javascript", "parent.uploadComplete('warning');");
            } catch (Exception e) {
                tempFile.delete();
                req.setAttribute("msg",
                        "Unable to upload file. ".concat(e.getMessage() == null ? "" : e.getMessage()));
                req.setAttribute("javascript", "parent.uploadComplete('warning');");
            } finally {
                session.setAttribute("uploadListener", null);
            }
            ServletContext app = getServletContext();
            RequestDispatcher disp = app.getRequestDispatcher("/templates/AjaxDummy.jsp");
            disp.forward(req, resp);
        }
    }

    /**
     * Convert a byte array to a hex-string. For md5 strings for example
     *
     * @param hashValue Input bytearray
     * @return ascii hexcode representation of input
     */
    private static String toHex(byte[] hashValue) {
        StringBuilder hexString = new StringBuilder();
        for (int i = 0; i < hashValue.length; i++) {
            String hex = Integer.toHexString(0xFF & hashValue[i]);
            if (hex.length() == 1) {
                hexString.append('0');
            }
            hexString.append(hex);
        }
        return hexString.toString();
    }
}