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

Java tutorial

Introduction

Here is the source code for gov.nih.nci.nbia.servlet.DownloadServletV3.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.dao.GeneralSeriesDAO;
import gov.nih.nci.nbia.dto.AnnotationDTO;
import gov.nih.nci.nbia.dto.ImageDTO2;
import gov.nih.nci.nbia.dto.SeriesDTO;
import gov.nih.nci.nbia.security.AuthorizationManager;
import gov.nih.nci.nbia.security.NCIASecurityManager;
import gov.nih.nci.nbia.util.NCIAConfig;
import gov.nih.nci.nbia.util.SiteData;
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.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.log4j.Logger;

/**
 * @author Q. Pan
 *
 */
public class DownloadServletV3 extends HttpServlet {
    private static Logger logger = Logger.getLogger(DownloadServlet.class);
    private final static int CLIENT_LOGIN_NEEDED = 460;
    private final static int CLIENT_LOGIN_FAILED = 461;
    private final static int CLIENT_NOT_AUTHORIZED = 462;

    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 numOfS = request.getParameter("numberOfSeries");

        if (numOfS != null) {
            int numberOfSeries = Integer.parseInt(numOfS);
            List<String> seriesList = new ArrayList<String>();

            for (int i = 1; i <= numberOfSeries; ++i) {
                String s = request.getParameter("series" + Integer.toString(i));
                if (s != null)
                    seriesList.add(s);
            }

            //authenticate user
            if (numberOfSeries > 0) {
                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(CLIENT_LOGIN_FAILED,
                            "Incorrect username and/or password. Please try it again.");
                    return;
                }

                downloadManifestFile(seriesList, response, userId);
            } else {
                response.sendError(HttpURLConnection.HTTP_BAD_REQUEST,
                        "The manifest file should include at least one series instance UID.");
                return;
            }
        } else { // individual download request
            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, "v3");
            } 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(List<String> seriesList, HttpServletResponse response, String userId) {
        logger.info("constructing manifest file from the serieList");

        response.setContentType("text/plain");
        response.setHeader("Content-Disposition", "attachment;filename=downloadname.txt");
        try {
            List<String> readLines = null;
            readLines = getManifestRec(seriesList, userId);
            if (readLines == null) {
                if (userId.equals(NCIAConfig.getGuestUsername()) || (userId == null)) {
                    response.sendError(CLIENT_LOGIN_NEEDED, "Login needed.");
                    return;
                } else if ((userId != null) && !(userId.equals(NCIAConfig.getGuestUsername()))) {
                    response.sendError(CLIENT_NOT_AUTHORIZED, "Insufficient privilege.");
                    return;
                }
            } else {
                OutputStream os = response.getOutputStream();
                IOUtils.writeLines(readLines, System.getProperty("line.separator"), os);
                os.close();
            }
        } catch (

        IOException e) {
            e.printStackTrace();
        }
    }

    private static String cleanStr(String in) {
        if ((in != null) && (in.length() > 0)) {
            String out = in.replaceAll("[^a-zA-Z0-9 .-]", "");
            return out;
        } else
            return null;
    }

    private static List<String> getManifestRec(List<String> seriesUids, String loginName) {
        AuthorizationManager am;
        try {
            am = new AuthorizationManager(loginName);
            NCIASecurityManager mgr = (NCIASecurityManager) SpringApplicationContext.getBean("nciaSecurityManager");

            List<SiteData> authorizedSiteData = am.getAuthorizedSites();
            GeneralSeriesDAO generalSeriesDAO = (GeneralSeriesDAO) SpringApplicationContext
                    .getBean("generalSeriesDAO");
            List<SeriesDTO> seriesDTOsFound = null;
            if (mgr.hasQaRole(loginName)) {
                seriesDTOsFound = generalSeriesDAO.findSeriesBySeriesInstanceUIDAllVisibilities(seriesUids,
                        authorizedSiteData, null);
            } else
                seriesDTOsFound = generalSeriesDAO.findSeriesBySeriesInstanceUID112(seriesUids, authorizedSiteData,
                        null);

            if ((seriesDTOsFound != null) && (seriesDTOsFound.size() < seriesUids.size())) {
                //Has some unauthorized data
                return null;
            } else if (seriesDTOsFound == null)
                return null;
            List<String> seriesDownloadData = new ArrayList<String>();
            for (SeriesDTO series : seriesDTOsFound) {
                String collection = series.getProject();
                String patientId = series.getPatientId();
                String studyInstanceUid = series.getStudyId();
                // String seriesInstanceUid = series.getSeriesUID();
                String seriesInstanceUid = series.getSeriesId();
                String annotation = "No";
                if (series.isAnnotationsFlag()) {
                    annotation = "Yes";
                } else {
                    annotation = "No";
                }

                Integer numberImages = series.getNumberImages();
                Long imagesSize = series.getTotalSizeForAllImagesInSeries();
                Long annoSize = series.getAnnotationsSize();
                String url = "url";
                String displayName = "displayName";
                String studyDate = series.getStudyDateString();
                String studyDesc = cleanStr(series.getStudyDesc());
                String seriesDesc = cleanStr(series.getDescription());
                String study_id = cleanStr(series.getStudy_id());
                String seriesNumber = series.getSeriesNumber();
                String argument = "" + collection + "|" + patientId + "|" + studyInstanceUid + "|"
                        + seriesInstanceUid + "|" + annotation + "|" + numberImages + "|" + imagesSize + "|"
                        + annoSize + "|" + url + "|" + displayName + "|" + true + "|" + studyDate + "|" + study_id
                        + "|" + studyDesc + "|" + seriesNumber + "|" + seriesDesc;
                seriesDownloadData.add(argument);
            }

            return seriesDownloadData;
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null;
    }
}