org.iplantc.phyloviewer.viewer.server.ParseTreeService.java Source code

Java tutorial

Introduction

Here is the source code for org.iplantc.phyloviewer.viewer.server.ParseTreeService.java

Source

/**
 * Copyright (c) 2009, iPlant Collaborative, Texas Advanced Computing Center
 * This software is licensed under the CC-GNU GPL version 2.0 or later.
 * License: http://creativecommons.org/licenses/GPL/2.0/
 */

package org.iplantc.phyloviewer.viewer.server;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

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 org.iplantc.phyloparser.exception.ParserException;
import org.iplantc.phyloviewer.viewer.server.persistence.Constants;
import org.iplantc.phyloviewer.viewer.server.persistence.ImportTreeLayout;
import org.xml.sax.SAXException;

/**
 * A servlet that accepts tree uploads and returns a URL to view the tree.
 */
public class ParseTreeService extends HttpServlet {
    private static final long serialVersionUID = -2532260393364629170L;
    private ServletFileUpload upload = new ServletFileUpload(new DiskFileItemFactory());
    private ParseTree parseTree;

    /**
     * Accepts a tree for parsing and storage, and returns a URL to view the tree.  
     * May return before the tree has finished importing.
     * 
     * @param request has the following parameters:
     * <pre>
     * newickData or nexml: a string representing the tree data
     * name (optional): the label that is given to the newick tree. 
     *    Nexml documents already have an attribute for tree label, so they don't use this parameter.
     * </pre>
     * 
     * @param response contains the URL to view the tree
     */
    protected void doPost(HttpServletRequest request, HttpServletResponse response) {
        Logger.getLogger("org.iplantc.phyloviewer").log(Level.FINE, "Received tree post request");

        PrintWriter writer = getWriter(response);

        Map<String, String[]> parameters = null;
        try {
            Logger.getLogger("org.iplantc.phyloviewer").log(Level.FINE, "Reading request parameters");
            parameters = getParameters(request);
        } catch (FileUploadException e) {
            response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
            writer.println(e.getMessage());
            writer.flush();
            writer.close();
            return;
        }

        try {
            String id = parseTree.saveTree(parameters);

            if (id != null) {
                Logger.getLogger("org.iplantc.phyloviewer").log(Level.FINE, "Returning response");
                response.setStatus(HttpServletResponse.SC_ACCEPTED);

                String viewURL = getViewURL(id, request);
                response.setHeader("Location", viewURL);
                writer.println(viewURL);
            } else {
                Logger.getLogger("org.iplantc.phyloviewer").log(Level.FINE, "No trees found. Returning response");
                response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
                writer.println("Bad request: No tree data found.");
            }
        } catch (ParserException e) {
            response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
            writer.println(e.getMessage());
            e.printStackTrace(writer);
        } catch (SAXException e) {
            response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
            writer.println(e.getMessage());
            e.printStackTrace(writer);
        } catch (Exception e) {
            response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
            writer.println(e.getMessage());
            e.printStackTrace(writer);
        }

        writer.flush();
        writer.close();
    }

    @Override
    public void init() throws ServletException {
        ServletContext servletContext = this.getServletContext();

        IImportTreeData treeImporter = (IImportTreeData) servletContext
                .getAttribute(Constants.IMPORT_TREE_DATA_KEY);
        ImportTreeLayout layoutImporter = (ImportTreeLayout) servletContext
                .getAttribute(Constants.IMPORT_TREE_LAYOUT_KEY);

        String path = servletContext.getInitParameter("treefile.path");
        path = servletContext.getRealPath(path);

        parseTree = new ParseTree(treeImporter, layoutImporter);
        parseTree.setTreeBackupDir(path);

        Logger.getLogger("org.iplantc.phyloviewer").log(Level.INFO,
                "Setting parseTree file backup path to " + parseTree.getTreeBackupDir().getAbsolutePath());
    }

    private PrintWriter getWriter(HttpServletResponse response) {
        PrintWriter writer = null;

        try {
            writer = response.getWriter();
        } catch (IOException e1) {
            Logger.getLogger("org.iplantc.phyloviewer").log(Level.SEVERE, "Unable to write response");
            response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
        }

        return writer;
    }

    private Map<String, String[]> getMultipartParameters(HttpServletRequest request) throws FileUploadException {
        HashMap<String, List<String>> parameters = new HashMap<String, List<String>>();

        List<?> items = null;
        try {
            items = upload.parseRequest(request);
        } catch (FileUploadException e) {
            Logger.getLogger("org.iplantc.phyloviewer").log(Level.SEVERE, "Unable to parse request", e);
            throw e;
        }

        for (Object obj : items) {
            if (obj instanceof FileItem) {
                FileItem item = (FileItem) obj;

                String name = item.getFieldName();
                if (!parameters.containsKey(name)) {
                    parameters.put(name, new ArrayList<String>());
                }
                parameters.get(name).add(item.getString());
            }
        }

        //convert to match return type of HttpServletRequest.getParameterMap()
        Map<String, String[]> copy = new HashMap<String, String[]>();
        for (String key : parameters.keySet()) {
            List<String> value = parameters.get(key);
            copy.put(key, value.toArray(new String[value.size()]));
        }

        return copy;
    }

    @SuppressWarnings("unchecked")
    private Map<String, String[]> getParameters(HttpServletRequest request) throws FileUploadException {
        if (ServletFileUpload.isMultipartContent(request)) {
            return getMultipartParameters(request);
        } else {
            return request.getParameterMap();
        }
    }

    private String getViewURL(String id, HttpServletRequest request) {
        String viewURL = request.getScheme() + "://" + request.getServerName();

        if (request.getServerPort() != 80) {
            viewURL += ":" + request.getServerPort();
        }

        if (request.getContextPath().length() > 0) {
            viewURL += request.getContextPath();
        }

        viewURL += "/view/tree/" + id;

        return viewURL;
    }
}