* AbstractPdfStamperView.java
* Created to make the process of merging field data on an AcroForm easy to do in Spring.
*
* @author K. Bryant Larsen
*/
package edu.utah.oit.osl.controller.web.view;
import com.lowagie.text.pdf.PdfReader;
import com.lowagie.text.pdf.PdfStamper;
import java.io.ByteArrayOutputStream;
import java.net.URL;
import java.util.Map;
import javax.servlet.ServletContext;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.view.AbstractView;
/**
* This abstract class is intended to be used for the merging of
* existing PDF forms with data and will write the PDF to the response.
* Similar to Springs AbstractPdfView except there is no document in this version.
* Created on March 26, 2008, 12:09 PM
* @author Bryant Larsen Media Solutions The University of Utah
*/
public abstract class AbstractPdfStamperView extends AbstractView {
private String url;
private static final int OUTPUT_BYTE_ARRAY_INITIAL_SIZE = 1024;
public AbstractPdfStamperView(){
super();
setContentType("application/pdf");
}
/**This is the method that will put all of the peices together and send the final output down to the response.
* @param model A Map that contains the model data for this instance
* @param request The request that will be handed to this view.
* @param response Contains the byte array outpu stream to output to the actuall browser.
*/
protected final void renderMergedOutputModel(Map model, HttpServletRequest request, HttpServletResponse response) throws Exception{
//Hold our output in a temporary output stream.
ByteArrayOutputStream tempOutputStream = new ByteArrayOutputStream(AbstractPdfStamperView.OUTPUT_BYTE_ARRAY_INITIAL_SIZE);
//Get the file from the filesystem.
PdfReader reader = new PdfReader(this.getServletContext().getResourceAsStream(this.getUrl()));
//Get a PdfStamper instance that will give us access to the AcroField
PdfStamper stamper = new PdfStamper(reader, tempOutputStream);
//Give the user the chance to merge the form fields.
mergePdfDocument(model, stamper, request, response);
//Set various settings on the stamper object.
//Example, stamper.setFormFlattening(true);
prepareStamper(stamper);
//Close the stamper
stamper.close();
// Write content type and also length(determined via byte array).
response.setContentType(getContentType());
response.setContentLength(tempOutputStream.size());
// Flush byte array to servlet output stream.
ServletOutputStream out = response.getOutputStream();
tempOutputStream.writeTo(out);
out.flush();
}
/**
* Abstract method that subclasses must implement.
* This is where you are able to set values on the AcroForm.
* An example of what can be done at this level is:
* //get the form from the document:
* AcroFields form = stamper.getAcroFields();
*
* //Set some values on the form.
* form.setField("field1", "Value1");
* form.setField("field2", "Value2");
* //Set the disposition and filename
* response.setHeader("Content-disposition", "attachment; FILENAME=someName.pdf" );
*@param model The model
*@param stamper The PdfStamper instance that will containt he AcroFields.
*@param request Provided in case you want to get parameters directly from the request
*@param response Provided for setting cookies or other things. Do not attempt to write the stamper to the outputstream. That is done in a different method.
*
*/
protected abstract void mergePdfDocument(Map model, com.lowagie.text.pdf.PdfStamper stamper, HttpServletRequest request, HttpServletResponse response) throws Exception ;
/** This method is run After the MergePdfDocument and Before the stamper is closed.
* This gives you an oportunity set your own settings on the stamper.
* This is where we suggest that you set things like setFormFlattening and many other interesting things.
* @param stamper. The stamper object that has already been merged.
*/
protected abstract void prepareStamper(PdfStamper stamper);
/** The url in this case is a string value that represents the existing PDF file that will be used to generate the stamper.
* You can use the view setup to specify the url.
mergePdf.(class)=.PdfStamperClass mergePdf.url=/WEB-INF/views/resources/template.pdf * will set the url as /WEB-INF/views/resources/template.pdf.
* @param url The file location to the PDF document.
*/
public void setUrl(String url) {
this.url = url;
}
/** JavaBean method to retreive the document url from the instance.
* @return url.
*/
public String getUrl() {
return this.url;
}
}