Download all attachments (Java)

/*
Save this Java class in your database and create a XPage, say xDownloadAllAttachments.xsp, with below code.

<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core" rendered="false">
	<xp:this.beforeRenderResponse>
		<![CDATA[#{javascript: org.openntf.DownloadAllAttachments.process()}]]>
	</xp:this.beforeRenderResponse>
	<xp:text escape="false" value="#{viewScope.errorString}" style="color:rgb(192,0,0)">
	</xp:text>
</xp:view>

Now call the XPage with following URL:

http://<SERVER>/<DATABASE PATH>/ xDownloadAllAttachments.xsp? documentUNID=<DOCUMENT UNID>&zipFileName=<NAME OF ZP FILE>

Parameters to query string

1. documentUNID – Universal ID of the document in which attachments are present. This is a mandatory parameter.
2. zipFileName – Name of zip file when the download box is shown to the user. This is optional and if this parameter is not specified then by default AllAttachments.zip name is taken.
*/

package org.openntf;

import java.io.BufferedInputStream;
import java.io.OutputStream;
import java.util.Map;
import java.util.Vector;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import javax.faces.component.UIViewRoot;
import javax.faces.context.FacesContext;
import javax.servlet.http.HttpServletResponse;
import lotus.domino.Document;
import lotus.domino.EmbeddedObject;
import com.ibm.xsp.designer.context.XSPContext;
import com.ibm.xsp.model.domino.DominoUtils;

public class DownloadAllAttachments {

	@SuppressWarnings("unchecked")
	public static void process() {
		
		// Initialize global XPage objects
		FacesContext facesContext = FacesContext.getCurrentInstance();
		XSPContext context = XSPContext.getXSPContext(facesContext);
		UIViewRoot view = facesContext.getViewRoot();
		Map viewScope = view.getViewMap();
		
		try {
			// Get and validate the document universal ID from URL
			String documentUNID = context.getUrlParameter("documentUNID");
			if (documentUNID == null || documentUNID.trim().equals("")) {
				viewScope.put("errorString", "URL parameter \"documentUNID\" not found.");
				view.setRendered(true);
				return;
			}
			
			// Get and validate the document from which attachments would be zipped
			Document downloadDocument = null;
			downloadDocument = DominoUtils.getCurrentDatabase().getDocumentByUNID(documentUNID);

			// Get and validate zip file name from URL
			String zipFileName = context.getUrlParameter("zipFileName");
			if (zipFileName == null || zipFileName.equals("")) {
				zipFileName = "AllAttachments.zip";
			} else if (!zipFileName.toLowerCase().endsWith(".zip")) {
				zipFileName = zipFileName + ".zip";
			}

			
			// Get and validate the attachments in document
			Vector attachments = DominoUtils.getCurrentSession().evaluate("@AttachmentNames", downloadDocument);
			if (attachments == null || (attachments.size() == 1 && attachments.get(0).toString().trim().equals(""))) {
				viewScope.put("errorString", "No attachments found in the document.");
				view.setRendered(true);
				return;
			}
			
			// Set response header values
			HttpServletResponse response = (HttpServletResponse) facesContext.getExternalContext().getResponse();
			response.setHeader("Cache-Control", "no-cache");
			response.setDateHeader("Expires", -1);
			response.setContentType("application/zip");
			response.setHeader("Content-Disposition", "attachment; filename=" + zipFileName);
			
			// Get stream related objects
			OutputStream outStream = response.getOutputStream();
			ZipOutputStream zipOutStream = new ZipOutputStream(outStream);
			EmbeddedObject embeddedObj = null;
			BufferedInputStream bufferInStream = null;

			// Get all attachment names and loop through all of them adding to zip
			for (int i = 0; i < attachments.size(); i++) {
				embeddedObj = downloadDocument.getAttachment(attachments.get(i).toString());
				if (embeddedObj != null) {
					bufferInStream = new BufferedInputStream(embeddedObj.getInputStream());
					int bufferLength = bufferInStream.available();
					byte data[] = new byte[bufferLength];
					bufferInStream.read(data, 0, bufferLength); // Read the attachment data
					ZipEntry entry = new ZipEntry(embeddedObj.getName());
					zipOutStream.putNextEntry(entry);
					zipOutStream.write(data); // Write attachment into Zip file
					bufferInStream.close();
					embeddedObj.recycle();
				}
			}
			
			// Clean up and close objects
			downloadDocument.recycle();
			zipOutStream.flush();
			zipOutStream.close();
			outStream.flush();
			outStream.close();
			facesContext.responseComplete();
			
		} catch (Exception e) {
			viewScope.put("errorString", "Error while zipping attachments.<br>" + e.toString());
			view.setRendered(true);
			e.printStackTrace();
		}
	}
}





I always loved the feature of “Download all attachments” in Gmail. So I decided we should have this option available in XPages also. This snippet is the Java version of my XSnippet - Download all attachments. You can see the SSJS version here: http://openntf.org/XSnippets.nsf/snippet.xsp?id=download-all-attachments

The implementation steps are explained in comments at the start.

Parameters to query string

1. documentUNID – Universal ID of the document in which attachments are present. This is a mandatory parameter.
2. zipFileName – Name of zip file when the download box is shown to the user. This is optional and if this parameter is not specified then by default AllAttachments.zip name is taken.

Java
Naveen Maurya
February 28, 2013 8:07 AM
Rating
238

All code submitted to OpenNTF XSnippets, whether submitted as a "Snippet" or in the body of a Comment, is provided under the Apache License Version 2.0. See Terms of Use for full details.



No comments yetLogin first to comment...