view servlet/src/digilib/servlet/PDFStreamWorker.java @ 546:e7c29b587829 digilibPDF

more work on util.concurrent compliant structure
author casties
date Fri, 22 Oct 2010 19:04:49 +0200
parents
children e1094c5ec032
line wrap: on
line source

package digilib.servlet;

import java.io.IOException;
import java.io.OutputStream;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;

import org.apache.log4j.Logger;

import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Image;
import com.itextpdf.text.PageSize;
import com.itextpdf.text.pdf.PdfWriter;

import digilib.image.DocuImage;

public class PDFStreamWorker implements Callable<OutputStream> {

	private static Logger logger = Logger.getLogger(PDFStreamWorker.class);

	private DigilibConfiguration dlConfig = null;

	private Document doc = null;

	private OutputStream outstream = null;

	private PDFJobInformation job_info = null;

	private DigilibJobCenter<DocuImage> imageJobCenter = null;

	/**
	 * @param dlConfig
	 * @param outputfile
	 * @param job_info
	 */
	public PDFStreamWorker(DigilibConfiguration dlConfig, OutputStream outputfile,
			PDFJobInformation job_info,
			DigilibJobCenter<DocuImage> imageJobCenter) {
		super();
		this.dlConfig = dlConfig;
		this.outstream = outputfile;
		this.job_info = job_info;
		this.imageJobCenter = imageJobCenter;
	}

	@Override
	public OutputStream call() throws Exception {
		outstream = renderPDF();
		return outstream;
	}

	/**
	 * @throws DocumentException
	 * @throws InterruptedException
	 * @throws ExecutionException
	 * @throws IOException
	 */
	protected OutputStream renderPDF() throws DocumentException, InterruptedException,
			ExecutionException, IOException {
		// create document object
		doc = new Document(PageSize.A4, 0, 0, 0, 0);
		PdfWriter docwriter = null;

		long start_time = System.currentTimeMillis();

		docwriter = PdfWriter.getInstance(doc, outstream);

		setPDFProperties(doc);

		doc.open();

		addTitlePage(doc);

		logger.debug("- " + outstream + " doc.open()ed ("
				+ (System.currentTimeMillis() - start_time) + "ms)");
		start_time = System.currentTimeMillis();

		// Integer[] pgs = job_info.getPageNrs();//get_pgs();
		NumRange pgs = job_info.getPages();

		for (int p : pgs) {
			logger.debug(" - adding Image " + p + " to " + outstream);
			// create ImageJobInformation
			ImageJobInformation iji = job_info.getImageJobInformation();
			iji.setValue("pn", p);
			addImage(doc, iji);
			logger.debug(" - done adding Image " + p + " to " + outstream);
		}

		logger.debug(" - done adding all Images to " + outstream);

		doc.close();
		logger.debug("- " + outstream + " doc.close() ("
				+ (System.currentTimeMillis() - start_time) + "ms)");
		docwriter.close();
		return outstream;
	}

	/**
	 * Set PDF-Meta-Attributes.
	 */
	public Document setPDFProperties(Document doc) {
		// TODO get proper Information from dlConfig
		doc.addAuthor(this.getClass().getName());
		doc.addCreationDate();
		doc.addKeywords("digilib");
		doc.addTitle("digilib PDF");
		doc.addCreator(this.getClass().getName());
		return doc;
	}

	/**
	 * Create a title page and append it to the document (should, of course, be
	 * called first)
	 * 
	 * @throws DocumentException
	 */
	public Document addTitlePage(Document doc) throws DocumentException {
		PDFTitlePage titlepage = new PDFTitlePage(job_info);
		doc.add(titlepage.getPageContents());
		doc.newPage();
		return doc;
	}

	/**
	 * adds an image to the document.
	 * 
	 * @param doc
	 * @param iji
	 * @return
	 * @throws InterruptedException
	 * @throws ExecutionException
	 * @throws IOException
	 * @throws DocumentException
	 */
	public Document addImage(Document doc, ImageJobInformation iji)
			throws InterruptedException, ExecutionException, IOException,
			DocumentException {
		// create image worker
		ImageWorker image_worker = new ImageWorker(dlConfig, iji);
		// submit
		Future<DocuImage> jobTicket = imageJobCenter.submit(image_worker);
		// wait for result
		DocuImage img = jobTicket.get();
		// scale the image
		Image pdfimg = Image.getInstance(img.getAwtImage(), null);
		float docW = PageSize.A4.getWidth() - 2 * PageSize.A4.getBorder();
		float docH = PageSize.A4.getHeight() - 2 * PageSize.A4.getBorder();
		// TODO: do we really want to scale this again?
		pdfimg.scaleToFit(docW, docH);
		// add to PDF
		doc.add(pdfimg);
		return doc;
	}

}