Java tutorial
/******************************************************************************* * Copyright (c) 2015 The Board of Trustees of the Leland Stanford Junior University * BY CLICKING ON "ACCEPT," DOWNLOADING, OR OTHERWISE USING EPAD, YOU AGREE TO THE FOLLOWING TERMS AND CONDITIONS: * STANFORD ACADEMIC SOFTWARE SOURCE CODE LICENSE FOR * "ePAD Annotation Platform for Radiology Images" * * This Agreement covers contributions to and downloads from the ePAD project ("ePAD") maintained by The Board of Trustees * of the Leland Stanford Junior University ("Stanford"). * * * Part A applies to downloads of ePAD source code and/or data from ePAD. * * * Part B applies to contributions of software and/or data to ePAD (including making revisions of or additions to code * and/or data already in ePAD), which may include source or object code. * * Your download, copying, modifying, displaying, distributing or use of any ePAD software and/or data from ePAD * (collectively, the "Software") is subject to Part A. Your contribution of software and/or data to ePAD (including any * that occurred prior to the first publication of this Agreement) is a "Contribution" subject to Part B. Both Parts A and * B shall be governed by and construed in accordance with the laws of the State of California without regard to principles * of conflicts of law. Any legal action involving this Agreement or the Research Program will be adjudicated in the State * of California. This Agreement shall supersede and replace any license terms that you may have agreed to previously with * respect to ePAD. * * PART A. DOWNLOADING AGREEMENT - LICENSE FROM STANFORD WITH RIGHT TO SUBLICENSE ("SOFTWARE LICENSE"). * 1. As used in this Software License, "you" means the individual downloading and/or using, reproducing, modifying, * displaying and/or distributing Software and the institution or entity which employs or is otherwise affiliated with you. * Stanford hereby grants you, with right to sublicense, with respect to Stanford's rights in the Software, a * royalty-free, non-exclusive license to use, reproduce, make derivative works of, display and distribute the Software, * provided that: (a) you adhere to all of the terms and conditions of this Software License; (b) in connection with any * copy, distribution of, or sublicense of all or any portion of the Software, the terms and conditions in this Software * License shall appear in and shall apply to such copy and such sublicense, including without limitation all source and * executable forms and on any user documentation, prefaced with the following words: "All or portions of this licensed * product have been obtained under license from The Board of Trustees of the Leland Stanford Junior University. and are * subject to the following terms and conditions" AND any user interface to the Software or the "About" information display * in the Software will display the following: "Powered by ePAD http://epad.stanford.edu;" (c) you preserve and maintain * all applicable attributions, copyright notices and licenses included in or applicable to the Software; (d) modified * versions of the Software must be clearly identified and marked as such, and must not be misrepresented as being the * original Software; and (e) you consider making, but are under no obligation to make, the source code of any of your * modifications to the Software freely available to others on an open source basis. * * 2. The license granted in this Software License includes without limitation the right to (i) incorporate the Software * into your proprietary programs (subject to any restrictions applicable to such programs), (ii) add your own copyright * statement to your modifications of the Software, and (iii) provide additional or different license terms and conditions * in your sublicenses of modifications of the Software; provided that in each case your use, reproduction or distribution * of such modifications otherwise complies with the conditions stated in this Software License. * 3. This Software License does not grant any rights with respect to third party software, except those rights that * Stanford has been authorized by a third party to grant to you, and accordingly you are solely responsible for (i) * obtaining any permissions from third parties that you need to use, reproduce, make derivative works of, display and * distribute the Software, and (ii) informing your sublicensees, including without limitation your end-users, of their * obligations to secure any such required permissions. * 4. You agree that you will use the Software in compliance with all applicable laws, policies and regulations including, * but not limited to, those applicable to Personal Health Information ("PHI") and subject to the Institutional Review * Board requirements of the your institution, if applicable. Licensee acknowledges and agrees that the Software is not * FDA-approved, is intended only for research, and may not be used for clinical treatment purposes. Any commercialization * of the Software is at the sole risk of you and the party or parties engaged in such commercialization. You further agree * to use, reproduce, make derivative works of, display and distribute the Software in compliance with all applicable * governmental laws, regulations and orders, including without limitation those relating to export and import control. * 5. You or your institution, as applicable, will indemnify, hold harmless, and defend Stanford against any third party * claim of any kind made against Stanford arising out of or related to the exercise of any rights granted under this * Agreement, the provision of Software, or the breach of this Agreement. Stanford provides the Software AS IS and WITH ALL * FAULTS. Stanford makes no representations and extends no warranties of any kind, either express or implied. Among * other things, Stanford disclaims any express or implied warranty in the Software: * (a) of merchantability, of fitness for a particular purpose, * (b) of non-infringement or * (c) arising out of any course of dealing. * * Title and copyright to the Program and any associated documentation shall at all times remain with Stanford, and * Licensee agrees to preserve same. Stanford reserves the right to license the Program at any time for a fee. * 6. None of the names, logos or trademarks of Stanford or any of Stanford's affiliates or any of the Contributors, or any * funding agency, may be used to endorse or promote products produced in whole or in part by operation of the Software or * derived from or based on the Software without specific prior written permission from the applicable party. * 7. Any use, reproduction or distribution of the Software which is not in accordance with this Software License shall * automatically revoke all rights granted to you under this Software License and render Paragraphs 1 and 2 of this * Software License null and void. * 8. This Software License does not grant any rights in or to any intellectual property owned by Stanford or any * Contributor except those rights expressly granted hereunder. * * PART B. CONTRIBUTION AGREEMENT - LICENSE TO STANFORD WITH RIGHT TO SUBLICENSE ("CONTRIBUTION AGREEMENT"). * 1. As used in this Contribution Agreement, "you" means an individual providing a Contribution to ePAD and the * institution or entity which employs or is otherwise affiliated with you. * 2. This Contribution Agreement applies to all Contributions made to ePAD at any time. By making a Contribution you * represent that: (i) you are legally authorized and entitled by ownership or license to make such Contribution and to * grant all licenses granted in this Contribution Agreement with respect to such Contribution; (ii) if your Contribution * includes any patient data, all such data is de-identified in accordance with U.S. confidentiality and security laws and * requirements, including but not limited to the Health Insurance Portability and Accountability Act (HIPAA) and its * regulations, and your disclosure of such data for the purposes contemplated by this Agreement is properly authorized and * in compliance with all applicable laws and regulations; and (iii) you have preserved in the Contribution all applicable * attributions, copyright notices and licenses for any third party software or data included in the Contribution. * 3. Except for the licenses you grant in this Agreement, you reserve all right, title and interest in your Contribution. * 4. You hereby grant to Stanford, with the right to sublicense, a perpetual, worldwide, non-exclusive, no charge, * royalty-free, irrevocable license to use, reproduce, make derivative works of, display and distribute the Contribution. * If your Contribution is protected by patent, you hereby grant to Stanford, with the right to sublicense, a perpetual, * worldwide, non-exclusive, no-charge, royalty-free, irrevocable license under your interest in patent rights embodied in * the Contribution, to make, have made, use, sell and otherwise transfer your Contribution, alone or in combination with * ePAD or otherwise. * 5. You acknowledge and agree that Stanford ham may incorporate your Contribution into ePAD and may make your * Contribution as incorporated available to members of the public on an open source basis under terms substantially in * accordance with the Software License set forth in Part A of this Agreement. You further acknowledge and agree that * Stanford shall have no liability arising in connection with claims resulting from your breach of any of the terms of * this Agreement. * 6. YOU WARRANT THAT TO THE BEST OF YOUR KNOWLEDGE YOUR CONTRIBUTION DOES NOT CONTAIN ANY CODE OBTAINED BY YOU UNDER AN * OPEN SOURCE LICENSE THAT REQUIRES OR PRESCRIBES DISTRBUTION OF DERIVATIVE WORKS UNDER SUCH OPEN SOURCE LICENSE. (By way * of non-limiting example, you will not contribute any code obtained by you under the GNU General Public License or other * so-called "reciprocal" license.) *******************************************************************************/ package edu.stanford.epad.epadws.handlers.dicom; import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.FileWriter; import java.io.IOException; import java.io.OutputStream; import java.io.PrintWriter; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Collection; import java.util.Date; import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletResponse; import org.apache.commons.httpclient.HttpException; import edu.stanford.epad.common.util.EPADConfig; import edu.stanford.epad.common.util.EPADFileUtils; import edu.stanford.epad.common.util.EPADLogger; import edu.stanford.epad.dtos.EPADAIM; import edu.stanford.epad.dtos.EPADAIMList; import edu.stanford.epad.dtos.EPADFile; import edu.stanford.epad.dtos.EPADImage; import edu.stanford.epad.dtos.EPADImageList; import edu.stanford.epad.dtos.EPADSeries; import edu.stanford.epad.dtos.EPADSeriesList; import edu.stanford.epad.dtos.EPADStudy; import edu.stanford.epad.dtos.EPADStudyList; import edu.stanford.epad.dtos.EPADSubject; import edu.stanford.epad.dtos.EPADSubjectList; import edu.stanford.epad.epadws.aim.AIMQueries; import edu.stanford.epad.epadws.aim.AIMSearchType; import edu.stanford.epad.epadws.aim.AIMUtil; import edu.stanford.epad.epadws.dcm4chee.Dcm4CheeDatabase; import edu.stanford.epad.epadws.dcm4chee.Dcm4CheeDatabaseOperations; import edu.stanford.epad.epadws.epaddb.EpadDatabase; import edu.stanford.epad.epadws.epaddb.EpadDatabaseOperations; import edu.stanford.epad.epadws.handlers.HandlerUtil; import edu.stanford.epad.epadws.handlers.core.EPADSearchFilter; import edu.stanford.epad.epadws.handlers.core.ImageReference; import edu.stanford.epad.epadws.handlers.core.ProjectReference; import edu.stanford.epad.epadws.handlers.core.SeriesReference; import edu.stanford.epad.epadws.handlers.core.StudyReference; import edu.stanford.epad.epadws.handlers.core.SubjectReference; import edu.stanford.epad.epadws.models.EpadFile; import edu.stanford.epad.epadws.queries.DefaultEpadOperations; import edu.stanford.epad.epadws.queries.EpadOperations; import edu.stanford.epad.epadws.security.EPADSessionOperations; import edu.stanford.epad.epadws.service.DefaultEpadProjectOperations; import edu.stanford.epad.epadws.service.EpadProjectOperations; import edu.stanford.hakan.aim4api.base.AimException; import edu.stanford.hakan.aim4api.base.ImageAnnotationCollection; import edu.stanford.hakan.aim4api.project.epad.Aim; import edu.stanford.hakan.aim4api.usage.AnnotationGetter; import edu.stanford.hakan.aim4api.compability.aimv3.ImageAnnotation; /** * @author Dev Gude * * Utility class with functions to create a zip file for subject/study/series/image dicoms and * either stream them to client * or just return a json with a pointer to the zip file (client needs to delete after use) */ public class DownloadUtil { private static final EPADLogger log = EPADLogger.getInstance(); private static final String INTERNAL_EXCEPTION_MESSAGE = "Internal error from WADO"; private static final String downloadDirName = "downloadWS/"; public static void downloadSubjects(boolean stream, HttpServletResponse httpResponse, String subjectUIDs, String username, String sessionID, EPADSearchFilter searchFilter, boolean includeAIMs) throws Exception { downloadSubjects(stream, httpResponse, subjectUIDs, username, sessionID, searchFilter, includeAIMs, null); } /** * Method to download multiple Subject dicoms * * @author Emel Alkim * @param stream - true if file should stream, otherwise placed on disk to be picked (should be deleted after use) * @param httpResponse * @param subjectReference * @param username * @param sessionID * @param searchFilter * @param subjectUIDs - download only these selected subjects * @throws Exception */ public static void downloadSubjects(boolean stream, HttpServletResponse httpResponse, String subjectUIDs, String username, String sessionID, EPADSearchFilter searchFilter, boolean includeAIMs, String projectID) throws Exception { log.info("Downloading subjects:" + subjectUIDs + " stream:" + stream); Set<String> subjects = new HashSet<String>(); if (subjectUIDs != null) { String[] ids = subjectUIDs.split(","); for (String id : ids) subjects.add(id.trim()); } String downloadDirPath = EPADConfig.getEPADWebServerResourcesDir() + downloadDirName + "temp" + Long.toString(System.currentTimeMillis()); File downloadDir = new File(downloadDirPath); downloadDir.mkdirs(); EpadOperations epadOperations = DefaultEpadOperations.getInstance(); List<String> fileNames = new ArrayList<String>(); //TODO ml change the static numbers //subjects for (String subjectID : subjects) { SubjectReference subjectReference = new SubjectReference(projectID, subjectID); EPADSubject subject = epadOperations.getSubjectDescription(subjectReference, username, sessionID); if (!subjects.isEmpty() && !subjects.contains(subject.subjectID)) continue; File subjectDir = new File(downloadDir, "Subject-" + subject.subjectID); subjectDir.mkdirs(); //studies EPADStudyList studyList = epadOperations.getStudyDescriptions(subjectReference, username, sessionID, searchFilter); for (EPADStudy study : studyList.ResultSet.Result) { File studyDir = new File(subjectDir, "Study-" + study.studyUID); studyDir.mkdirs(); StudyReference studyReference = new StudyReference(subjectReference.projectID, subjectReference.subjectID, study.studyUID); //series EPADSeriesList seriesList = epadOperations.getSeriesDescriptions(studyReference, username, sessionID, searchFilter, false); for (EPADSeries series : seriesList.ResultSet.Result) { File seriesDir = new File(studyDir, "Series-" + series.seriesUID); seriesDir.mkdirs(); SeriesReference seriesReference = new SeriesReference(studyReference.projectID, studyReference.subjectID, studyReference.studyUID, series.seriesUID); EPADImageList imageList = new EPADImageList(); try { imageList = epadOperations.getImageDescriptions(seriesReference, sessionID, null); } catch (Exception x) { } for (EPADImage image : imageList.ResultSet.Result) { String name = image.imageUID + ".dcm"; File imageFile = new File(seriesDir, name); fileNames.add("Subject-" + subjectReference.subjectID + "/Study-" + studyReference.studyUID + "/Series-" + series.seriesUID + "/" + name); FileOutputStream fos = null; try { fos = new FileOutputStream(imageFile); String queryString = "requestType=WADO&studyUID=" + seriesReference.studyUID + "&seriesUID=" + seriesReference.seriesUID + "&objectUID=" + image.imageUID + "&contentType=application/dicom"; performWADOQuery(queryString, fos, username, sessionID); } catch (Exception x) { log.warning("Error downloading image using wado", x); } finally { if (fos != null) fos.close(); } } //ml include aims copied from series if (includeAIMs) { EPADAIMList aimList = epadOperations.getSeriesAIMDescriptions(seriesReference, username, sessionID); aimList = AIMUtil.filterPermittedImageAnnotations(aimList, username, sessionID); for (EPADAIM aim : aimList.ResultSet.Result) { String name = "Aim_" + format4Filename(subject.subjectName) + "_" + aim.aimID + ".xml"; File aimFile = new File(seriesDir, name); fileNames.add("Subject-" + subjectReference.subjectID + "/Study-" + studyReference.studyUID + "/Series-" + series.seriesUID + "/" + name); FileWriter fw = null; try { fw = new FileWriter(aimFile); // fw.write(aim.xml); fw.write(formatXMLtoLatest(aim.xml)); } catch (Exception x) { log.warning("Error writing aim file"); } finally { if (fw != null) fw.close(); } } } } } } String zipName = "Subjects-" + subjectUIDs + ".zip"; if (stream) { httpResponse.setContentType("application/zip"); httpResponse.setHeader("Content-Disposition", "attachment;filename=\"" + zipName + "\""); } File zipFile = null; OutputStream out = null; try { if (stream) { out = httpResponse.getOutputStream(); } else { zipFile = new File(downloadDir, zipName); out = new FileOutputStream(zipFile); } } catch (Exception e) { log.warning("Error getting output stream", e); throw e; } ZipAndStreamFiles(out, fileNames, downloadDirPath + "/"); if (!stream) { File newZip = new File(EPADConfig.getEPADWebServerResourcesDir() + downloadDirName, zipName); zipFile.renameTo(newZip); EPADFile epadFile = new EPADFile("", "", "", "", "", zipName, zipFile.length(), "Subjects", formatDate(new Date()), downloadDirName + zipFile.getName(), true, subjectUIDs); PrintWriter responseStream = httpResponse.getWriter(); responseStream.append(epadFile.toJSON()); } EPADFileUtils.deleteDirectoryAndContents(downloadDir); } /** * Method to download Project dicoms * * @author Emel Alkim * @param stream - true if file should stream, otherwise placed on disk to be picked (should be deleted after use) * @param httpResponse * @param subjectReference * @param username * @param sessionID * @param searchFilter * @param subjectUIDs - download only these selected subjects * @throws Exception */ public static void downloadProject(boolean stream, HttpServletResponse httpResponse, ProjectReference projectReference, String username, String sessionID, EPADSearchFilter searchFilter, String subjectUIDs, boolean includeAIMs) throws Exception { log.info("Downloading project:" + projectReference.projectID + " stream:" + stream); Set<String> subjects = new HashSet<String>(); if (subjectUIDs != null) { String[] ids = subjectUIDs.split(","); for (String id : ids) subjects.add(id.trim()); } String downloadDirPath = EPADConfig.getEPADWebServerResourcesDir() + downloadDirName + "temp" + Long.toString(System.currentTimeMillis()); File downloadDir = new File(downloadDirPath); downloadDir.mkdirs(); EpadOperations epadOperations = DefaultEpadOperations.getInstance(); List<String> fileNames = new ArrayList<String>(); //TODO ml change the static numbers //subjects EPADSubjectList subjectList = epadOperations.getSubjectDescriptions(projectReference.projectID, username, sessionID, searchFilter, 1, 5000, "", false); for (EPADSubject subject : subjectList.ResultSet.Result) { if (!subjects.isEmpty() && !subjects.contains(subject.subjectID)) continue; File subjectDir = new File(downloadDir, "Subject-" + subject.subjectID); subjectDir.mkdirs(); SubjectReference subjectReference = new SubjectReference(projectReference.projectID, subject.subjectID); //studies EPADStudyList studyList = epadOperations.getStudyDescriptions(subjectReference, username, sessionID, searchFilter); for (EPADStudy study : studyList.ResultSet.Result) { File studyDir = new File(subjectDir, "Study-" + study.studyUID); studyDir.mkdirs(); StudyReference studyReference = new StudyReference(subjectReference.projectID, subjectReference.subjectID, study.studyUID); //series EPADSeriesList seriesList = epadOperations.getSeriesDescriptions(studyReference, username, sessionID, searchFilter, false); for (EPADSeries series : seriesList.ResultSet.Result) { File seriesDir = new File(studyDir, "Series-" + series.seriesUID); seriesDir.mkdirs(); SeriesReference seriesReference = new SeriesReference(studyReference.projectID, studyReference.subjectID, studyReference.studyUID, series.seriesUID); EPADImageList imageList = new EPADImageList(); try { imageList = epadOperations.getImageDescriptions(seriesReference, sessionID, null); } catch (Exception x) { } for (EPADImage image : imageList.ResultSet.Result) { String name = image.imageUID + ".dcm"; File imageFile = new File(seriesDir, name); fileNames.add("Subject-" + subjectReference.subjectID + "/Study-" + studyReference.studyUID + "/Series-" + series.seriesUID + "/" + name); FileOutputStream fos = null; try { fos = new FileOutputStream(imageFile); String queryString = "requestType=WADO&studyUID=" + seriesReference.studyUID + "&seriesUID=" + seriesReference.seriesUID + "&objectUID=" + image.imageUID + "&contentType=application/dicom"; performWADOQuery(queryString, fos, username, sessionID); } catch (Exception x) { log.warning("Error downloading image using wado"); } finally { if (fos != null) fos.close(); } } //ml include aims copied from series if (includeAIMs) { EPADAIMList aimList = epadOperations.getSeriesAIMDescriptions(seriesReference, username, sessionID); aimList = AIMUtil.filterPermittedImageAnnotations(aimList, username, sessionID); for (EPADAIM aim : aimList.ResultSet.Result) { String name = "Aim_" + format4Filename(subject.subjectName) + "_" + aim.aimID + ".xml"; File aimFile = new File(seriesDir, name); fileNames.add("Subject-" + subjectReference.subjectID + "/Study-" + studyReference.studyUID + "/Series-" + series.seriesUID + "/" + name); FileWriter fw = null; try { fw = new FileWriter(aimFile); fw.write(formatXMLtoLatest(aim.xml)); } catch (Exception x) { log.warning("Error writing aim file"); } finally { if (fw != null) fw.close(); } } } } } } String zipName = "Project-" + projectReference.projectID + ".zip"; if (stream) { httpResponse.setContentType("application/zip"); httpResponse.setHeader("Content-Disposition", "attachment;filename=\"" + zipName + "\""); } File zipFile = null; OutputStream out = null; try { if (stream) { out = httpResponse.getOutputStream(); } else { zipFile = new File(downloadDir, zipName); out = new FileOutputStream(zipFile); } } catch (Exception e) { log.warning("Error getting output stream", e); throw e; } ZipAndStreamFiles(out, fileNames, downloadDirPath + "/"); if (!stream) { File newZip = new File(EPADConfig.getEPADWebServerResourcesDir() + downloadDirName, zipName); zipFile.renameTo(newZip); EPADFile epadFile = new EPADFile("", "", "", "", "", zipName, zipFile.length(), "Project", formatDate(new Date()), downloadDirName + zipFile.getName(), true, projectReference.projectID); PrintWriter responseStream = httpResponse.getWriter(); responseStream.append(epadFile.toJSON()); } EPADFileUtils.deleteDirectoryAndContents(downloadDir); } /** * Method to download Subject dicoms * * @param stream - true if file should stream, otherwise placed on disk to be picked (should be deleted after use) * @param httpResponse * @param subjectReference * @param username * @param sessionID * @param searchFilter * @param studyUIDs - download only these selected studies * @throws Exception */ public static void downloadSubject(boolean stream, HttpServletResponse httpResponse, SubjectReference subjectReference, String username, String sessionID, EPADSearchFilter searchFilter, String studyUIDs, boolean includeAIMs) throws Exception { log.info("Downloading subject:" + subjectReference.subjectID + " stream:" + stream); Set<String> studies = new HashSet<String>(); if (studyUIDs != null) { String[] ids = studyUIDs.split(","); for (String id : ids) studies.add(id.trim()); } String downloadDirPath = EPADConfig.getEPADWebServerResourcesDir() + downloadDirName + "temp" + Long.toString(System.currentTimeMillis()); log.info("download path:" + downloadDirPath); File downloadDir = new File(downloadDirPath); downloadDir.mkdirs(); EpadOperations epadOperations = DefaultEpadOperations.getInstance(); List<String> fileNames = new ArrayList<String>(); EPADStudyList studyList = epadOperations.getStudyDescriptions(subjectReference, username, sessionID, searchFilter); for (EPADStudy study : studyList.ResultSet.Result) { if (!studies.isEmpty() && !studies.contains(study.studyUID)) continue; File studyDir = new File(downloadDir, "Study-" + study.studyUID); studyDir.mkdirs(); StudyReference studyReference = new StudyReference(subjectReference.projectID, subjectReference.subjectID, study.studyUID); EPADSeriesList seriesList = epadOperations.getSeriesDescriptions(studyReference, username, sessionID, searchFilter, false); for (EPADSeries series : seriesList.ResultSet.Result) { log.info("series proj=" + series.projectID + " study proj=" + studyReference.projectID); if (series.projectID != studyReference.projectID) //if the series is not in this project, skip continue; File seriesDir = new File(studyDir, "Series-" + series.seriesUID); seriesDir.mkdirs(); SeriesReference seriesReference = new SeriesReference(studyReference.projectID, studyReference.subjectID, studyReference.studyUID, series.seriesUID); EPADImageList imageList = new EPADImageList(); try { imageList = epadOperations.getImageDescriptions(seriesReference, sessionID, null); } catch (Exception x) { } for (EPADImage image : imageList.ResultSet.Result) { String name = image.imageUID + ".dcm"; File imageFile = new File(seriesDir, name); fileNames.add("Study-" + studyReference.studyUID + "/Series-" + series.seriesUID + "/" + name); FileOutputStream fos = null; try { fos = new FileOutputStream(imageFile); String queryString = "requestType=WADO&studyUID=" + seriesReference.studyUID + "&seriesUID=" + seriesReference.seriesUID + "&objectUID=" + image.imageUID + "&contentType=application/dicom"; performWADOQuery(queryString, fos, username, sessionID); } catch (Exception x) { log.warning("Error downloading image using wado"); } finally { if (fos != null) fos.close(); } } //ml include aims copied from series if (includeAIMs) { EPADAIMList aimList = epadOperations.getSeriesAIMDescriptions(seriesReference, username, sessionID); aimList = AIMUtil.filterPermittedImageAnnotations(aimList, username, sessionID); for (EPADAIM aim : aimList.ResultSet.Result) { String name = "Aim_" + format4Filename(study.patientName) + "_" + aim.aimID + ".xml"; File aimFile = new File(seriesDir, name); fileNames.add( "Study-" + studyReference.studyUID + "/Series-" + series.seriesUID + "/" + name); FileWriter fw = null; try { fw = new FileWriter(aimFile); fw.write(formatXMLtoLatest(aim.xml)); } catch (Exception x) { log.warning("Error writing aim file"); } finally { if (fw != null) fw.close(); } } } } } String zipName = "Patient-" + subjectReference.subjectID + ".zip"; if (stream) { httpResponse.setContentType("application/zip"); httpResponse.setHeader("Content-Disposition", "attachment;filename=\"" + zipName + "\""); } File zipFile = null; OutputStream out = null; try { if (stream) { out = httpResponse.getOutputStream(); } else { zipFile = new File(downloadDir, zipName); out = new FileOutputStream(zipFile); } } catch (Exception e) { log.warning("Error getting output stream", e); throw e; } ZipAndStreamFiles(out, fileNames, downloadDirPath + "/"); if (!stream) { File newZip = new File(EPADConfig.getEPADWebServerResourcesDir() + downloadDirName, zipName); zipFile.renameTo(newZip); EPADFile epadFile = new EPADFile("", "", "", "", "", zipName, zipFile.length(), "Patient", formatDate(new Date()), downloadDirName + zipFile.getName(), true, subjectReference.subjectID); PrintWriter responseStream = httpResponse.getWriter(); responseStream.append(epadFile.toJSON()); } EPADFileUtils.deleteDirectoryAndContents(downloadDir); } /** * keep the old version * @param stream * @param httpResponse * @param studyUIDs * @param username * @param sessionID * @param includeAIMs * @throws Exception */ public static void downloadStudies(boolean stream, HttpServletResponse httpResponse, String studyUIDs, String username, String sessionID, boolean includeAIMs) throws Exception { downloadStudies(stream, httpResponse, studyUIDs, username, sessionID, includeAIMs, null); } /** * Method to download list of Study dicoms * * @param stream - true if file should stream, otherwise placed on disk to be picked (should be deleted after use) * @param httpResponse * @param subjectReference * @param username * @param sessionID * @param searchFilter * @param studyUIDs - download only these selected studies * @param projectID * @throws Exception */ public static void downloadStudies(boolean stream, HttpServletResponse httpResponse, String studyUIDs, String username, String sessionID, boolean includeAIMs, String projectID) throws Exception { log.info("Downloading studies:" + studyUIDs + " stream:" + stream); Set<String> studies = new HashSet<String>(); if (studyUIDs != null) { String[] ids = studyUIDs.split(","); for (String id : ids) studies.add(id.trim()); } String downloadDirPath = EPADConfig.getEPADWebServerResourcesDir() + downloadDirName + "temp" + Long.toString(System.currentTimeMillis()); File downloadDir = new File(downloadDirPath); downloadDir.mkdirs(); EpadOperations epadOperations = DefaultEpadOperations.getInstance(); EpadProjectOperations projectOperations = DefaultEpadProjectOperations.getInstance(); EpadDatabaseOperations databaseOperations = EpadDatabase.getInstance().getEPADDatabaseOperations(); List<String> fileNames = new ArrayList<String>(); for (String studyUID : studies) { if (studyUID.length() == 0) continue; File studyDir = new File(downloadDir, "Study-" + studyUID); studyDir.mkdirs(); StudyReference studyReference = new StudyReference(projectID, null, studyUID); EPADStudy study = epadOperations.getStudyDescription(studyReference, username, sessionID); if (study == null) throw new Exception("Study not found:" + studyReference.studyUID); studyReference = new StudyReference(projectID, study.patientID, studyUID); EPADSeriesList seriesList = epadOperations.getSeriesDescriptions(studyReference, username, sessionID, new EPADSearchFilter(), false); for (EPADSeries series : seriesList.ResultSet.Result) { if (series.isNonDicomSeries) { File seriesDir = new File(studyDir, "Series-" + series.seriesUID); seriesDir.mkdirs(); List<EpadFile> files = projectOperations.getSeriesFiles(projectID, null, studyUID, series.seriesUID); for (EpadFile file : files) { String name = file.getName(); File epadFile = new File(seriesDir, name); EPADFileUtils.copyFile( new File(EPADConfig.getEPADWebServerResourcesDir() + getEpadFilePath(file)), epadFile); } continue; } if (series.isDSO) { try { List<EPADAIM> aims = databaseOperations.getAIMsByDSOSeries(series.seriesUID); boolean skip = true; for (EPADAIM aim : aims) { if (aim.userName.equalsIgnoreCase(username)) skip = false; } if (skip) continue; } catch (Exception x) { } ; } File seriesDir = new File(studyDir, "Series-" + series.seriesUID); seriesDir.mkdirs(); SeriesReference seriesReference = new SeriesReference(studyReference.projectID, studyReference.subjectID, studyReference.studyUID, series.seriesUID); EPADImageList imageList = new EPADImageList(); try { imageList = epadOperations.getImageDescriptions(seriesReference, sessionID, null); } catch (Exception x) { } for (EPADImage image : imageList.ResultSet.Result) { String name = image.imageUID + ".dcm"; File imageFile = new File(seriesDir, name); fileNames.add("Study-" + studyReference.studyUID + "/Series-" + series.seriesUID + "/" + name); FileOutputStream fos = null; try { fos = new FileOutputStream(imageFile); String queryString = "requestType=WADO&studyUID=" + seriesReference.studyUID + "&seriesUID=" + seriesReference.seriesUID + "&objectUID=" + image.imageUID + "&contentType=application/dicom"; performWADOQuery(queryString, fos, username, sessionID); } catch (Exception x) { log.warning("Error downloading image using wado"); } finally { if (fos != null) fos.close(); } } if (includeAIMs) { EPADAIMList aimList = epadOperations.getSeriesAIMDescriptions(seriesReference, username, sessionID); aimList = AIMUtil.filterPermittedImageAnnotations(aimList, username, sessionID); for (EPADAIM aim : aimList.ResultSet.Result) { //String name = "Aim_" + aim.aimID + ".xml"; String name = "Aim_" + format4Filename(study.patientName) + "_" + aim.aimID + ".xml"; File aimFile = new File(seriesDir, name); fileNames.add( "Study-" + studyReference.studyUID + "/Series-" + series.seriesUID + "/" + name); FileWriter fw = null; try { fw = new FileWriter(aimFile); fw.write(formatXMLtoLatest(aim.xml)); } catch (Exception x) { log.warning("Error writing aim file"); } finally { if (fw != null) fw.close(); } } } } } String ids = studyUIDs.replace(",", "-"); if (ids.length() > 128) ids = ids.substring(0, 128); String zipName = "Studies-" + ids + ".zip"; if (stream) { httpResponse.setContentType("application/zip"); httpResponse.setHeader("Content-Disposition", "attachment;filename=\"" + zipName + "\""); } File zipFile = null; OutputStream out = null; try { if (stream) { out = httpResponse.getOutputStream(); } else { zipFile = new File(downloadDir, zipName); out = new FileOutputStream(zipFile); } } catch (Exception e) { log.warning("Error getting output stream", e); throw e; } ZipAndStreamFiles(out, fileNames, downloadDirPath + "/"); if (!stream) { File newZip = new File(EPADConfig.getEPADWebServerResourcesDir() + downloadDirName, zipName); zipFile.renameTo(newZip); EPADFile epadFile = new EPADFile("", "", "", "", "", zipName, zipFile.length(), "Studies", formatDate(new Date()), downloadDirName + zipFile.getName(), true, studyUIDs); PrintWriter responseStream = httpResponse.getWriter(); responseStream.append(epadFile.toJSON()); } EPADFileUtils.deleteDirectoryAndContents(downloadDir); } public static void downloadDicomSrFile(HttpServletResponse httpResponse, String filePath, String username, String srName) throws Exception { srName = srName.replace(" ", "_"); //replace spaces log.info("Downloading DicomSR file"); String downloadDirPath = EPADConfig.getEPADWebServerResourcesDir() + downloadDirName + "temp" + Long.toString(System.currentTimeMillis()); File downloadDir = new File(downloadDirPath); downloadDir.mkdirs(); List<String> fileNames = new ArrayList<String>(); File dicomSr = new File(filePath); String name = dicomSr.getName(); File dicomSrFile = new File(downloadDir, srName); EPADFileUtils.copyFile(dicomSr, dicomSrFile); fileNames.add(srName); File rwvmDir = new File(filePath.substring(0, filePath.lastIndexOf("/")), "RWVM-" + filePath.substring(filePath.lastIndexOf("/") + 1)); log.info("rwvm dir " + rwvmDir.getAbsolutePath()); if (rwvmDir.exists()) { Collection<File> rwvmFiles = EPADFileUtils.getAllFilesWithExtension(rwvmDir, "dcm", true); log.info("rwvm files count " + rwvmFiles.size()); for (File f : rwvmFiles) { log.info("rwvm file " + f.getName()); File rwvmFile = new File(downloadDir, f.getName()); EPADFileUtils.copyFile(f, rwvmFile); fileNames.add(f.getName()); } } String zipName = "DicomSR-" + timestamp.format(new Date()) + ".zip"; httpResponse.setContentType("application/zip"); httpResponse.setHeader("Content-Disposition", "attachment;filename=\"" + zipName + "\""); File zipFile = null; OutputStream out = null; try { out = httpResponse.getOutputStream(); } catch (Exception e) { log.warning("Error getting output stream", e); throw e; } ZipAndStreamFiles(out, fileNames, downloadDirPath + "/"); EPADFileUtils.deleteDirectoryAndContents(downloadDir); } /** * Method to download list of Files * * @param stream - true if file should stream, otherwise placed on disk to be picked (should be deleted after use) * @param httpResponse * @param subjectReference * @param username * @param sessionID * @param searchFilter * @param studyUIDs - download only these selected studies * @throws Exception */ public static void downloadFiles(HttpServletResponse httpResponse, String[] filePaths, String username) throws Exception { log.info("Downloading files:" + filePaths.length); String downloadDirPath = EPADConfig.getEPADWebServerResourcesDir() + downloadDirName + "temp" + Long.toString(System.currentTimeMillis()); File downloadDir = new File(downloadDirPath); downloadDir.mkdirs(); EpadOperations epadOperations = DefaultEpadOperations.getInstance(); EpadProjectOperations projectOperations = DefaultEpadProjectOperations.getInstance(); EpadDatabaseOperations databaseOperations = EpadDatabase.getInstance().getEPADDatabaseOperations(); List<String> fileNames = new ArrayList<String>(); for (String filePath : filePaths) { if (filePath.startsWith("/")) filePath = filePath.substring(1); String[] parts = filePath.split("/"); String projectID = null; String subjectID = null; String studyUID = null; String seriesUID = null; String fileName = null; if (parts.length < 4) { log.warning("Invalid filePath:" + filePath); continue; } projectID = parts[1]; if (parts.length == 4) { fileName = parts[3]; } else if (parts.length == 6) { subjectID = parts[3]; fileName = parts[5]; } else if (parts.length == 8) { subjectID = parts[3]; studyUID = parts[5]; fileName = parts[7]; } else if (parts.length == 10) { subjectID = parts[3]; studyUID = parts[5]; seriesUID = parts[7]; fileName = parts[9]; } else { log.warning("Invalid filePath:" + filePath); } File projectDir = new File(downloadDir, "Project-" + projectID); projectDir.mkdirs(); EpadFile file = projectOperations.getEpadFile(projectID, subjectID, studyUID, seriesUID, fileName); String name = file.getName(); File epadFile = new File(projectDir, name); EPADFileUtils.copyFile(new File(EPADConfig.getEPADWebServerResourcesDir() + getEpadFilePath(file)), epadFile); fileNames.add("Project-" + projectID + "/" + name); } String zipName = "EpadFiles-" + timestamp.format(new Date()) + ".zip"; httpResponse.setContentType("application/zip"); httpResponse.setHeader("Content-Disposition", "attachment;filename=\"" + zipName + "\""); File zipFile = null; OutputStream out = null; try { out = httpResponse.getOutputStream(); } catch (Exception e) { log.warning("Error getting output stream", e); throw e; } ZipAndStreamFiles(out, fileNames, downloadDirPath + "/"); EPADFileUtils.deleteDirectoryAndContents(downloadDir); } private static String getEpadFilePath(EpadFile file) { String path = "files/" + file.getRelativePath(); String fileName = file.getId() + file.getExtension(); if (path.endsWith("/")) return path + fileName; else return path + "/" + fileName; } /** * Method to download Study dicoms * * @param stream - true if file should stream, otherwise placed on disk to be picked (should be deleted after use) * @param httpResponse * @param studyReference * @param username * @param sessionID * @param searchFilter * @param seriesUIDs - download only these selected series * @throws Exception */ public static void downloadStudy(boolean stream, HttpServletResponse httpResponse, StudyReference studyReference, String username, String sessionID, EPADSearchFilter searchFilter, String seriesUIDs, boolean includeAIMs) throws Exception { log.info("Downloading study:" + studyReference.studyUID + " stream:" + stream); Set<String> seriesSet = new HashSet<String>(); if (seriesUIDs != null) { String[] ids = seriesUIDs.split(","); for (String id : ids) seriesSet.add(id.trim()); } String downloadDirPath = EPADConfig.getEPADWebServerResourcesDir() + downloadDirName + "temp" + Long.toString(System.currentTimeMillis()); File downloadDir = new File(downloadDirPath); downloadDir.mkdirs(); EpadOperations epadOperations = DefaultEpadOperations.getInstance(); List<String> fileNames = new ArrayList<String>(); EPADSeriesList seriesList = epadOperations.getSeriesDescriptions(studyReference, username, sessionID, searchFilter, false); int imageCount = 0; log.info("Number series in study:" + seriesList.ResultSet.totalRecords); for (EPADSeries series : seriesList.ResultSet.Result) { if (!seriesSet.isEmpty() && !seriesSet.contains(series.seriesUID)) continue; File seriesDir = new File(downloadDir, "Series-" + series.seriesUID); seriesDir.mkdirs(); SeriesReference seriesReference = new SeriesReference(studyReference.projectID, studyReference.subjectID, studyReference.studyUID, series.seriesUID); if (series.isNonDicomSeries) { log.debug("Downloading files:" + series.seriesUID); EpadProjectOperations projectOperations = DefaultEpadProjectOperations.getInstance(); List<EpadFile> files = projectOperations.getSeriesFiles(studyReference.projectID, studyReference.subjectID, studyReference.studyUID, series.seriesUID); for (EpadFile file : files) { String name = file.getName(); File epadFile = new File(seriesDir, name); EPADFileUtils.copyFile( new File(EPADConfig.getEPADWebServerResourcesDir() + getEpadFilePath(file)), epadFile); fileNames.add("Series-" + series.seriesUID + "/" + name); } continue; } EPADImageList imageList = new EPADImageList(); try { imageList = epadOperations.getImageDescriptions(seriesReference, sessionID, null); } catch (Exception x) { } int i = 0; for (EPADImage image : imageList.ResultSet.Result) { imageCount++; String name = image.imageUID + ".dcm"; File imageFile = new File(seriesDir, name); fileNames.add("Series-" + series.seriesUID + "/" + name); FileOutputStream fos = null; try { fos = new FileOutputStream(imageFile); String queryString = "requestType=WADO&studyUID=" + seriesReference.studyUID + "&seriesUID=" + seriesReference.seriesUID + "&objectUID=" + image.imageUID + "&contentType=application/dicom"; performWADOQuery(queryString, fos, username, sessionID); } catch (Exception x) { log.warning("Error downloading image using wado"); } finally { if (fos != null) fos.close(); } } if (includeAIMs) { EPADAIMList aimList = epadOperations.getSeriesAIMDescriptions(seriesReference, username, sessionID); aimList = AIMUtil.filterPermittedImageAnnotations(aimList, username, sessionID); for (EPADAIM aim : aimList.ResultSet.Result) { String name = "Aim_" + format4Filename(series.patientName) + "_" + aim.aimID + ".xml"; File aimFile = new File(seriesDir, name); fileNames.add("Series-" + series.seriesUID + "/" + name); FileWriter fw = null; try { fw = new FileWriter(aimFile); fw.write(formatXMLtoLatest(aim.xml)); } catch (Exception x) { log.warning("Error writing aim file"); } finally { if (fw != null) fw.close(); } } } } String zipName = "Patient-" + studyReference.subjectID + "-Study-" + studyReference.studyUID + ".zip"; if (stream) { httpResponse.setContentType("application/zip"); httpResponse.setHeader("Content-Disposition", "attachment;filename=\"" + zipName + "\""); } File zipFile = null; OutputStream out = null; try { if (stream) { out = httpResponse.getOutputStream(); } else { zipFile = new File(downloadDir, zipName); out = new FileOutputStream(zipFile); } } catch (Exception e) { log.warning("Error getting output stream", e); throw e; } ZipAndStreamFiles(out, fileNames, downloadDirPath + "/"); if (!stream) { File newZip = new File(EPADConfig.getEPADWebServerResourcesDir() + downloadDirName, zipName); zipFile.renameTo(newZip); EPADFile epadFile = new EPADFile("", "", "", "", "", zipName, zipFile.length(), "Study", formatDate(new Date()), downloadDirName + zipFile.getName(), true, studyReference.studyUID); PrintWriter responseStream = httpResponse.getWriter(); responseStream.append(epadFile.toJSON()); } EPADFileUtils.deleteDirectoryAndContents(downloadDir); } private static String formatXMLtoLatest(String xml) throws AimException { log.info("formatting aim"); List<ImageAnnotationCollection> iacs = AnnotationGetter.getImageAnnotationCollectionsFromString(xml, EPADConfig.xsdFilePathV4); if (iacs.size() > 1) { StringBuilder aimXml = new StringBuilder("<imageAnnotations>\n"); for (ImageAnnotationCollection iac : iacs) { ImageAnnotation ia = new ImageAnnotation(iac); log.info("new aim is:" + ia.toAimV4().getXMLString()); aimXml.append(ia.toAimV4().getXMLString()); } aimXml.append("</imageAnnotations>\n"); log.info("(multiple iac) new aim is:" + aimXml.toString()); return aimXml.toString(); } ImageAnnotation ia = new ImageAnnotation(iacs.get(0)); log.info("new aim is:" + ia.toAimV4().getXMLString()); return ia.toAimV4().getXMLString(); } /** * Method to download dicoms from a list of series * * @param stream - true if file should stream, otherwise placed on disk to be picked (should be deleted after use) * @param httpResponse * @param studyReference * @param username * @param sessionID * @param searchFilter * @param seriesUIDs * @throws Exception */ public static void downloadSeries(boolean stream, HttpServletResponse httpResponse, String seriesUIDs, String username, String sessionID, boolean includeAIMs) throws Exception { log.info("Downloading seriesUIDs:" + seriesUIDs + " stream:" + stream); String downloadDirPath = EPADConfig.getEPADWebServerResourcesDir() + downloadDirName + "temp" + Long.toString(System.currentTimeMillis()); File downloadDir = new File(downloadDirPath); downloadDir.mkdirs(); EpadOperations epadOperations = DefaultEpadOperations.getInstance(); List<String> fileNames = new ArrayList<String>(); String[] seriesIDs = seriesUIDs.split(","); for (String seriesUID : seriesIDs) { if (seriesUID.trim().length() == 0) continue; File seriesDir = new File(downloadDir, "Series-" + seriesUID); seriesDir.mkdirs(); SeriesReference seriesReference = new SeriesReference(null, null, null, seriesUID); EPADSeries series = epadOperations.getSeriesDescription(seriesReference, username, sessionID); if (series.isNonDicomSeries) { EpadProjectOperations projectOperations = DefaultEpadProjectOperations.getInstance(); List<EpadFile> files = projectOperations.getSeriesFiles(null, null, null, series.seriesUID); for (EpadFile file : files) { String name = file.getName(); File epadFile = new File(seriesDir, name); EPADFileUtils.copyFile( new File(EPADConfig.getEPADWebServerResourcesDir() + getEpadFilePath(file)), epadFile); fileNames.add("Series-" + series.seriesUID + "/" + name); } continue; } seriesReference = new SeriesReference(null, series.patientID, series.studyUID, seriesUID); EPADImageList imageList = new EPADImageList(); try { imageList = epadOperations.getImageDescriptions(seriesReference, sessionID, null); } catch (Exception x) { } int i = 0; for (EPADImage image : imageList.ResultSet.Result) { String name = image.imageUID + ".dcm"; File imageFile = new File(seriesDir, name); fileNames.add("Series-" + series.seriesUID + "/" + name); FileOutputStream fos = null; try { fos = new FileOutputStream(imageFile); String queryString = "requestType=WADO&studyUID=" + seriesReference.studyUID + "&seriesUID=" + seriesReference.seriesUID + "&objectUID=" + image.imageUID + "&contentType=application/dicom"; performWADOQuery(queryString, fos, username, sessionID); } catch (Exception x) { log.warning("Error downloading image using wado"); } finally { if (fos != null) fos.close(); } } if (includeAIMs) { EPADAIMList aimList = epadOperations.getSeriesAIMDescriptions(seriesReference, username, sessionID); log.info("go filter"); aimList = AIMUtil.filterPermittedImageAnnotations(aimList, username, sessionID); for (EPADAIM aim : aimList.ResultSet.Result) { String name = "Aim_" + format4Filename(series.patientName) + "_" + aim.aimID + ".xml"; File aimFile = new File(seriesDir, name); fileNames.add("Series-" + series.seriesUID + "/" + name); FileWriter fw = null; try { fw = new FileWriter(aimFile); fw.write(formatXMLtoLatest(aim.xml)); } catch (Exception x) { log.warning("Error writing aim file"); } finally { if (fw != null) fw.close(); } } } } String ids = seriesUIDs.replace(",", "-"); if (ids.length() > 128) ids = ids.substring(0, 128); String zipName = "Series-" + ids + ".zip"; if (stream) { httpResponse.setContentType("application/zip"); httpResponse.setHeader("Content-Disposition", "attachment;filename=\"" + zipName + "\""); } File zipFile = null; OutputStream out = null; try { if (stream) { out = httpResponse.getOutputStream(); } else { zipFile = new File(downloadDir, zipName); out = new FileOutputStream(zipFile); } } catch (Exception e) { log.warning("Error getting output stream", e); throw e; } ZipAndStreamFiles(out, fileNames, downloadDirPath + "/"); if (!stream) { File newZip = new File(EPADConfig.getEPADWebServerResourcesDir() + downloadDirName, zipName); zipFile.renameTo(newZip); EPADFile epadFile = new EPADFile("", "", "", "", "", zipName, zipFile.length(), "Series", formatDate(new Date()), downloadDirName + zipFile.getName(), true, seriesUIDs); PrintWriter responseStream = httpResponse.getWriter(); responseStream.append(epadFile.toJSON()); } EPADFileUtils.deleteDirectoryAndContents(downloadDir); } /** * Method to download Series dicoms * * @param stream - true if file should stream, otherwise placed on disk to be picked (should be deleted after use) * @param httpResponse * @param seriesReference * @param username * @param sessionID * @throws Exception */ public static void downloadSeries(boolean stream, HttpServletResponse httpResponse, SeriesReference seriesReference, String username, String sessionID, boolean includeAIMs) throws Exception { log.info("Downloading series:" + seriesReference.seriesUID + " stream:" + stream); EpadOperations epadOperations = DefaultEpadOperations.getInstance(); EPADSeries series = epadOperations.getSeriesDescription(seriesReference, username, sessionID); String downloadDirPath = EPADConfig.getEPADWebServerResourcesDir() + downloadDirName + "temp" + Long.toString(System.currentTimeMillis()); File downloadDir = new File(downloadDirPath); downloadDir.mkdirs(); List<String> fileNames = new ArrayList<String>(); if (series.isNonDicomSeries) { EpadProjectOperations projectOperations = DefaultEpadProjectOperations.getInstance(); List<EpadFile> files = projectOperations.getSeriesFiles(null, null, null, series.seriesUID); for (EpadFile file : files) { String name = file.getName(); File epadFile = new File(downloadDir, name); EPADFileUtils.copyFile(new File(EPADConfig.getEPADWebServerResourcesDir() + getEpadFilePath(file)), epadFile); fileNames.add(name); } } else { EPADImageList imageList = new EPADImageList(); try { imageList = epadOperations.getImageDescriptions(seriesReference, sessionID, null); } catch (Exception x) { } for (EPADImage image : imageList.ResultSet.Result) { String name = image.imageUID + ".dcm"; File imageFile = new File(downloadDir, name); fileNames.add(name); FileOutputStream fos = null; try { fos = new FileOutputStream(imageFile); String queryString = "requestType=WADO&studyUID=" + seriesReference.studyUID + "&seriesUID=" + seriesReference.seriesUID + "&objectUID=" + image.imageUID + "&contentType=application/dicom"; performWADOQuery(queryString, fos, username, sessionID); } catch (Exception x) { log.warning("Error downloading image using wado"); } finally { if (fos != null) fos.close(); } } } if (includeAIMs) { EPADAIMList aimList = epadOperations.getSeriesAIMDescriptions(seriesReference, username, sessionID); log.info("go filter"); aimList = AIMUtil.filterPermittedImageAnnotations(aimList, username, sessionID); for (EPADAIM aim : aimList.ResultSet.Result) { String name = "Aim_" + format4Filename(series.patientName) + "_" + aim.aimID + ".xml"; File aimFile = new File(downloadDir, name); fileNames.add(name); FileWriter fw = null; try { fw = new FileWriter(aimFile); fw.write(formatXMLtoLatest(aim.xml)); } catch (Exception x) { log.warning("Error writing aim file"); } finally { if (fw != null) fw.close(); } } } String zipName = "Patient-" + seriesReference.subjectID + "-Study-" + seriesReference.studyUID + "-Serie-" + seriesReference.seriesUID + ".zip"; if (stream) { httpResponse.setContentType("application/zip"); httpResponse.setHeader("Content-Disposition", "attachment;filename=\"" + zipName + "\""); } File zipFile = null; OutputStream out = null; try { if (stream) { out = httpResponse.getOutputStream(); } else { zipFile = new File(downloadDir, zipName); out = new FileOutputStream(zipFile); } } catch (Exception e) { log.warning("Error getting output stream", e); throw e; } ZipAndStreamFiles(out, fileNames, downloadDirPath + "/"); if (!stream) { File newZip = new File(EPADConfig.getEPADWebServerResourcesDir() + downloadDirName, zipName); zipFile.renameTo(newZip); EPADFile epadFile = new EPADFile("", "", "", "", "", zipName, zipFile.length(), "Series", formatDate(new Date()), downloadDirName + zipFile.getName(), true, seriesReference.seriesUID); PrintWriter responseStream = httpResponse.getWriter(); responseStream.append(epadFile.toJSON()); } EPADFileUtils.deleteDirectoryAndContents(downloadDir); } /** * Method to download file in resources folder * * @param httpResponse * @param seriesReference * @param username * @param sessionID * @throws Exception */ public static void downloadResource(String relativePath, HttpServletResponse httpResponse, String username, String sessionID) throws Exception { String resourcesPath = EPADConfig.getEPADWebServerResourcesDir(); File file = new File(resourcesPath + "/" + relativePath); if (!file.exists()) throw new Exception("Requested resource " + relativePath + " does not exist"); if (file.isDirectory()) throw new Exception("Requested resource " + relativePath + " is a folder"); httpResponse.setContentType("application/zip"); httpResponse.setHeader("Content-Disposition", "attachment;filename=\"" + file.getName() + "\""); OutputStream out = null; BufferedInputStream fr = null; try { out = httpResponse.getOutputStream(); fr = new BufferedInputStream(new FileInputStream(file)); byte buffer[] = new byte[0xffff]; int b; while ((b = fr.read(buffer)) != -1) out.write(buffer, 0, b); } catch (Exception e) { log.warning("Error streaming file", e); throw e; } finally { if (fr != null) fr.close(); } } /** * Method to download a dicom * * @param stream - true if file should stream, otherwise placed on disk to be picked (should be deleted after use) * @param httpResponse * @param imageReference * @param username * @param sessionID * @throws Exception */ public static void downloadImage(boolean stream, HttpServletResponse httpResponse, ImageReference imageReference, String username, String sessionID, boolean dicom) throws Exception { if (imageReference.seriesUID.equals("*")) { //ml no series uid. probably dso. fill it! final Dcm4CheeDatabaseOperations dcm4CheeDatabaseOperations = Dcm4CheeDatabase.getInstance() .getDcm4CheeDatabaseOperations(); imageReference.seriesUID = dcm4CheeDatabaseOperations.getSeriesUIDForImage(imageReference.imageUID); if (imageReference.studyUID.equals("*")) imageReference.studyUID = dcm4CheeDatabaseOperations.getStudyUIDForSeries(imageReference.seriesUID); log.info("image reference of image " + imageReference.imageUID + " series uid filled with " + imageReference.seriesUID); } String queryString = "requestType=WADO&studyUID=" + imageReference.studyUID + "&seriesUID=" + imageReference.seriesUID + "&objectUID=" + imageReference.imageUID; if (dicom) queryString = queryString + "&contentType=application/dicom"; if (stream) { httpResponse.setContentType("application/octet-stream"); ServletOutputStream responseStream = httpResponse.getOutputStream(); performWADOQuery(queryString, responseStream, username, sessionID); } else { String downloadDirPath = EPADConfig.getEPADWebServerResourcesDir() + downloadDirName; File downloadDir = new File(downloadDirPath); downloadDir.mkdirs(); String imageName = imageReference.imageUID + ".dcm"; File imageFile = new File(downloadDir, imageName); FileOutputStream fos = null; try { fos = new FileOutputStream(imageFile); performWADOQuery(queryString, fos, username, sessionID); } catch (Exception x) { log.warning("Error downloading image using wado"); } finally { if (fos != null) fos.close(); } EPADFile epadFile = new EPADFile("", "", "", "", "", imageName, imageFile.length(), "Image", formatDate(new Date()), downloadDirName + imageFile.getName(), true, imageReference.imageUID); PrintWriter responseStream = httpResponse.getWriter(); responseStream.append(epadFile.toJSON()); } } /** * Method to download a png * * @param httpResponse * @param imageReference * @param username * @param sessionID * @throws Exception */ public static void downloadPNG(HttpServletResponse httpResponse, ImageReference imageReference, String username, String sessionID) throws Exception { String pngPath = EpadDatabase.getInstance().getEPADDatabaseOperations() .getPNGLocation(imageReference.studyUID, imageReference.seriesUID, imageReference.imageUID); File file = new File(EPADConfig.getEPADWebServerResourcesDir() + pngPath); if (!file.exists()) { throw new Exception("Image " + file.getAbsolutePath() + " does not exist"); } EPADFileUtils.downloadFile(null, httpResponse, file, imageReference.imageUID + ".png"); } public static int performWADOQuery(String queryString, OutputStream outputStream, String username, String sessionID) { String wadoHost = EPADConfig.dcm4CheeServer; int wadoPort = EPADConfig.dcm4cheeServerWadoPort; String wadoBase = EPADConfig.wadoURLExtension; if (queryString.toLowerCase().indexOf("dicom") != -1) { log.info("User:" + username + " host:" + EPADSessionOperations.getSessionHost(sessionID) + " Wado Request to download dicom:" + queryString); } String wadoURL = buildWADOURL(wadoHost, wadoPort, wadoBase, queryString); int statusCode; try { statusCode = HandlerUtil.streamGetResponse(wadoURL, outputStream, log); if (statusCode != HttpServletResponse.SC_OK) log.warning("Unexpected response " + statusCode + " to WADO request " + wadoURL); } catch (HttpException e) { statusCode = HandlerUtil.internalErrorResponse(INTERNAL_EXCEPTION_MESSAGE, log); } catch (IOException e) { statusCode = HandlerUtil.internalErrorResponse(INTERNAL_EXCEPTION_MESSAGE, log); } return statusCode; } private static String buildWADOURL(String host, int port, String base, String queryString) { StringBuilder sb = new StringBuilder(); sb.append("http://").append(host); sb.append(":").append(port); sb.append(base); sb.append(queryString); return sb.toString(); } public static boolean ZipAndStreamFiles(OutputStream out, List<String> fileNames, String dirPath) { File dir_file = new File(dirPath); int dir_l = dir_file.getAbsolutePath().length(); ZipOutputStream zipout = new ZipOutputStream(out); zipout.setLevel(1); for (int i = 0; i < fileNames.size(); i++) { File f = (File) new File(dirPath + fileNames.get(i)); if (f.canRead()) { log.debug("Adding file: " + f.getAbsolutePath()); try { zipout.putNextEntry(new ZipEntry(f.getAbsolutePath().substring(dir_l + 1))); } catch (Exception e) { log.warning("Error adding to zip file", e); return false; } BufferedInputStream fr; try { fr = new BufferedInputStream(new FileInputStream(f)); byte buffer[] = new byte[0xffff]; int b; while ((b = fr.read(buffer)) != -1) zipout.write(buffer, 0, b); fr.close(); zipout.closeEntry(); } catch (Exception e) { log.warning("Error closing zip file", e); return false; } } } try { zipout.finish(); out.flush(); } catch (IOException e) { e.printStackTrace(); return false; } return true; } private static String format4Filename(String name) { return name.replaceAll("[^A-Za-z0-9 _\\.\\-:]", ""); } static SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd"); private static String formatDate(Date date) { if (date == null) return ""; else return dateFormat.format(date); } static SimpleDateFormat timestamp = new SimpleDateFormat("yyyyMMddHHmm"); }