gov.nih.nci.nbia.servlet.DownloadServletV2.java Source code

Java tutorial

Introduction

Here is the source code for gov.nih.nci.nbia.servlet.DownloadServletV2.java

Source

/*L
 *  Copyright SAIC, Ellumen and RSNA (CTP)
 *
 *
 *  Distributed under the OSI-approved BSD 3-Clause License.
 *  See http://ncip.github.com/national-biomedical-image-archive/LICENSE.txt for details.
 */

package gov.nih.nci.nbia.servlet;

import gov.nih.nci.nbia.DownloadProcessor;
import gov.nih.nci.nbia.dto.AnnotationDTO;
import gov.nih.nci.nbia.dto.ImageDTO2;
import gov.nih.nci.nbia.security.NCIASecurityManager;
import gov.nih.nci.nbia.util.NCIAConfig;
import gov.nih.nci.nbia.util.SpringApplicationContext;
import gov.nih.nci.nbia.util.StringEncrypter;
import gov.nih.nci.security.exceptions.CSException;
import gov.nih.nci.security.exceptions.internal.CSInternalLoginException;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

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

import org.apache.commons.compress.archivers.ArchiveEntry;
import org.apache.commons.compress.archivers.tar.TarArchiveOutputStream;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;

/**
 * @author Q. Pan
 *
 */
public class DownloadServletV2 extends HttpServlet {
    private static Logger logger = Logger.getLogger(DownloadServlet.class);

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request, response);
    }

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // This servlet processes Manifest download related requests only. JNLP
        // download related requests are processed at DownloadServlet
        String serverManifestLoc = request.getParameter("serverManifestLoc");

        // check file type and authenticate user
        if (StringUtils.isNotBlank(serverManifestLoc)) {

            String userId = request.getParameter("userId");
            String password = request.getHeader("password");

            if ((userId == null) || (password == null)) {
                userId = NCIAConfig.getGuestUsername();
            } else if (!loggedIn(userId, password)) {
                response.sendError(HttpURLConnection.HTTP_UNAUTHORIZED,
                        "Incorrect username and/or password. Please try it again.");
                return;
            }
            downloadManifestFile(serverManifestLoc, response, userId, password);
        } else {
            String seriesUid = request.getParameter("seriesUid");
            String userId = request.getParameter("userId");
            String password = request.getHeader("password");
            Boolean includeAnnotation = Boolean.valueOf(request.getParameter("includeAnnotation"));
            Boolean hasAnnotation = Boolean.valueOf(request.getParameter("hasAnnotation"));
            String sopUids = request.getParameter("sopUids");

            if ((userId == null) || (userId.length() < 1)) {
                userId = NCIAConfig.getGuestUsername();
            }

            logger.info("sopUids:" + sopUids);
            logger.info("seriesUid: " + seriesUid + " userId: " + userId + " includeAnnotation: "
                    + includeAnnotation + " hasAnnotation: " + hasAnnotation);

            processRequest(response, seriesUid, userId, password, includeAnnotation, hasAnnotation, sopUids);
        }
    }

    private boolean loggedIn(String userId, String password) {
        try {
            password = decrypt(password);
            NCIASecurityManager mgr = (NCIASecurityManager) SpringApplicationContext.getBean("nciaSecurityManager");

            if (mgr.login(userId, password)) {
                return true;
            } else {
                return false;
            }
        } catch (CSException cse) {
            // cse.printStackTrace();
            return false;
        } catch (CSInternalLoginException e) {
            // TODO Auto-generated catch block
            // e.printStackTrace();
            return false;
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            return false;
        }
    }

    protected void processRequest(HttpServletResponse response, String seriesUid, String userId, String password,
            Boolean includeAnnotation, Boolean hasAnnotation, String sopUids) throws IOException {

        DownloadProcessor processor = new DownloadProcessor();
        List<AnnotationDTO> annoResults = new ArrayList<AnnotationDTO>();
        boolean hasAccess = false;

        try {
            password = decrypt(password);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        List<ImageDTO2> imageResults = processor.process(seriesUid, sopUids);
        if ((imageResults == null) || imageResults.isEmpty()) {
            // no data for this series
            logger.info("no data for series: " + seriesUid);
        } else {
            hasAccess = processor.hasAccess(userId, password, imageResults.get(0).getProject(),
                    imageResults.get(0).getSite(), imageResults.get(0).getSsg());
        }

        if (hasAccess) {
            if (includeAnnotation && hasAnnotation) {
                annoResults = processor.process(seriesUid);
            }
            sendResponse(response, imageResults, annoResults);
            // compute the size for this series
            long size = computeContentLength(imageResults, annoResults);
            try {
                processor.recordAppDownload(seriesUid, userId, size, "v2");
            } catch (Exception e) {
                logger.error("Exception recording download " + e.getMessage());
            }
        } else
            sendAccessDenial(response);
    }

    private void sendAccessDenial(HttpServletResponse response) throws IOException {
        response.sendError(HttpServletResponse.SC_FORBIDDEN, "Access Denied");
    }

    private void sendResponse(HttpServletResponse response, List<ImageDTO2> imageResults,
            List<AnnotationDTO> annoResults) throws IOException {

        TarArchiveOutputStream tos = new TarArchiveOutputStream(response.getOutputStream());

        try {
            long start = System.currentTimeMillis();

            logger.info("images size: " + imageResults.size() + " anno size: " + annoResults.size());

            sendAnnotationData(annoResults, tos);
            sendImagesData(imageResults, tos);

            logger.info("total time to send  files are " + (System.currentTimeMillis() - start) / 1000 + " ms.");
        } finally {
            IOUtils.closeQuietly(tos);
        }
    }

    private void sendImagesData(List<ImageDTO2> imageResults, TarArchiveOutputStream tos) throws IOException {
        InputStream dicomIn = null;
        try {
            for (ImageDTO2 imageDto : imageResults) {
                String filePath = imageDto.getFileName();
                String sop = imageDto.getSOPInstanceUID();

                logger.info("filepath: " + filePath + " filename: " + sop);
                try {
                    File dicomFile = new File(filePath);
                    ArchiveEntry tarArchiveEntry = tos.createArchiveEntry(dicomFile, sop + ".dcm");
                    dicomIn = new FileInputStream(dicomFile);
                    tos.putArchiveEntry(tarArchiveEntry);
                    IOUtils.copy(dicomIn, tos);
                    tos.closeArchiveEntry();
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                    // just print the exception and continue the loop so rest of
                    // images will get download.
                } finally {
                    IOUtils.closeQuietly(dicomIn);
                    logger.info("DownloadServlet Image transferred at " + new Date().getTime());
                }
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    private void sendAnnotationData(List<AnnotationDTO> annoResults, TarArchiveOutputStream tos)
            throws IOException {
        InputStream annoIn = null;
        for (AnnotationDTO a : annoResults) {
            String filePath = a.getFilePath();
            String fileName = a.getFileName();

            try {
                File annotationFile = new File(filePath);
                ArchiveEntry tarArchiveEntry = tos.createArchiveEntry(annotationFile, fileName);
                annoIn = new FileInputStream(annotationFile);
                tos.putArchiveEntry(tarArchiveEntry);
                IOUtils.copy(annoIn, tos);
                tos.closeArchiveEntry();
            } catch (FileNotFoundException e) {
                e.printStackTrace();
                // just print the exception and continue the loop so rest of
                // images will get download.
            } finally {
                IOUtils.closeQuietly(annoIn);
                logger.info("DownloadServlet Annotation transferred at " + new Date().getTime());
            }
        }
    }

    private String decrypt(String password) throws Exception {
        StringEncrypter decrypter = new StringEncrypter();
        if (password.equals("")) {
            return "";
        } else {
            return decrypter.decryptString(password);
        }
    }

    private static long computeContentLength(List<ImageDTO2> imageResults, List<AnnotationDTO> annoResults) {
        long contentSize = 0;
        for (ImageDTO2 imageDto : imageResults) {
            contentSize += imageDto.getDicomSize();
        }
        for (AnnotationDTO annoDto : annoResults) {
            contentSize += annoDto.getFileSize();
        }
        return contentSize;
    }

    private void downloadManifestFile(String fileName, HttpServletResponse response, String userId,
            String password) {
        logger.info("looking for manifest file name ..." + fileName);

        response.setContentType("text/plain");
        response.setHeader("Content-Disposition", "attachment;filename=downloadname.txt");
        try {
            List<String> readLines = IOUtils.readLines(new FileReader(fileName));
            OutputStream os = response.getOutputStream();
            IOUtils.writeLines(readLines, System.getProperty("line.separator"), os);
            os.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}