changeset 546:e7c29b587829 digilibPDF

more work on util.concurrent compliant structure
author casties
date Fri, 22 Oct 2010 19:04:49 +0200
parents 88ec23c2b2fb
children e1094c5ec032
files servlet/src/digilib/servlet/DigilibConfiguration.java servlet/src/digilib/servlet/DigilibJobCenter.java servlet/src/digilib/servlet/Initialiser.java servlet/src/digilib/servlet/PDFCache.java servlet/src/digilib/servlet/PDFFileWorker.java servlet/src/digilib/servlet/PDFStreamWorker.java
diffstat 6 files changed, 201 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/servlet/src/digilib/servlet/DigilibConfiguration.java	Fri Oct 15 10:42:57 2010 +0200
+++ b/servlet/src/digilib/servlet/DigilibConfiguration.java	Fri Oct 22 19:04:49 2010 +0200
@@ -149,6 +149,14 @@
 		newParameter("worker-threads", new Integer(1), null, 'f');
 		// max number of waiting threads
 		newParameter("max-waiting-threads", new Integer(20), null, 'f');
+		// number of pdf-generation threads
+		newParameter("pdf-worker-threads", new Integer(1), null, 'f');
+		// max number of waiting pdf-generation threads
+		newParameter("pdf-max-waiting-threads", new Integer(20), null, 'f');
+		// number of pdf-image generation threads
+		newParameter("pdf-image-worker-threads", new Integer(1), null, 'f');
+		// max number of waiting pdf-image generation threads
+		newParameter("pdf-image-max-waiting-threads", new Integer(10), null, 'f');
         // PDF generation temp directory
         newParameter("pdf-temp-dir", "pdf_temp", null, 'f');
         // PDF generation cache directory
--- a/servlet/src/digilib/servlet/DigilibJobCenter.java	Fri Oct 15 10:42:57 2010 +0200
+++ b/servlet/src/digilib/servlet/DigilibJobCenter.java	Fri Oct 22 19:04:49 2010 +0200
@@ -20,7 +20,7 @@
  * @author casties
  *
  */
-public class DigilibJobCenter {
+public class DigilibJobCenter<V> {
     /** general logger for this class */
     private static Logger logger = Logger.getLogger("digilib.jobcenter");
     /** ExecutorService */
@@ -51,7 +51,7 @@
      * @param job
      * @return Future to control the job
      */
-    public Future<DocuImage> submit(Callable<DocuImage> job) {
+    public Future<V> submit(Callable<V> job) {
         return executor.submit(job);
     }
 
--- a/servlet/src/digilib/servlet/Initialiser.java	Fri Oct 15 10:42:57 2010 +0200
+++ b/servlet/src/digilib/servlet/Initialiser.java	Fri Oct 22 19:04:49 2010 +0200
@@ -21,6 +21,7 @@
 package digilib.servlet;
 
 import java.io.File;
+import java.io.OutputStream;
 import java.util.List;
 
 import javax.servlet.ServletConfig;
@@ -59,9 +60,15 @@
 	/** DigilibConfiguration instance */
 	DigilibConfiguration dlConfig;
 
-	/** Executor for image jobs */
+	/** Executor for digilib image jobs */
 	DigilibJobCenter imageEx;
 	
+	/** Executor for PDF jobs */
+	DigilibJobCenter pdfEx;
+	
+	/** Executor for PDF image jobs */
+	DigilibJobCenter pdfImageEx;
+	
 	/**
 	 * Initialisation on first run.
 	 * 
@@ -127,11 +134,21 @@
 				DocuImage di = dlConfig.getDocuImageInstance();
 				dlConfig.setValue("servlet.docuimage.class", di.getClass().getName());
                 ImageOps.setDocuImage(di);
-				// worker threads
+				// digilib worker threads
 				int nt = dlConfig.getAsInt("worker-threads");
                 int mt = dlConfig.getAsInt("max-waiting-threads");
-				imageEx = new DigilibJobCenter(nt, mt, true);
+				imageEx = new DigilibJobCenter<DocuImage>(nt, mt, true);
                 dlConfig.setValue("servlet.worker.imageexecutor", imageEx);				
+				// PDF worker threads
+				int pnt = dlConfig.getAsInt("pdf-worker-threads");
+                int pmt = dlConfig.getAsInt("pdf-max-waiting-threads");
+				pdfEx = new DigilibJobCenter<OutputStream>(pnt, pmt, true);
+                dlConfig.setValue("servlet.worker.pdfexecutor", pdfEx);				
+				// digilib worker threads
+				int pint = dlConfig.getAsInt("pdf-image-worker-threads");
+                int pimt = dlConfig.getAsInt("pdf-image-max-waiting-threads");
+				pdfImageEx = new DigilibJobCenter<DocuImage>(pint, pimt, true);
+                dlConfig.setValue("servlet.worker.pdfimageexecutor", pdfImageEx);				
 				// set as the servlets main config
 				context.setAttribute("digilib.servlet.configuration", dlConfig);
 
--- a/servlet/src/digilib/servlet/PDFCache.java	Fri Oct 15 10:42:57 2010 +0200
+++ b/servlet/src/digilib/servlet/PDFCache.java	Fri Oct 22 19:04:49 2010 +0200
@@ -4,6 +4,7 @@
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.IOException;
+import java.io.OutputStream;
 
 import javax.servlet.RequestDispatcher;
 import javax.servlet.ServletConfig;
@@ -30,6 +31,8 @@
 	
 	public static String instanceKey = "digilib.servlet.PDFCache";
 	
+	private DigilibJobCenter<OutputStream> pdfJobCenter = null;
+	
 	private File cache_directory = new File("cache");  
 	
 	private File temp_directory = new File("pdf_temp");
@@ -59,7 +62,7 @@
 		
         System.out.println("***** Digital Image Library Image PDF-Cache Servlet (version "
                 + version + ") *****");
-// say hello in the log file
+        // say hello in the log file
         logger.info("***** Digital Image Library Image PDF-Cache Servlet (version "
                 + version + ") *****");
 
@@ -84,6 +87,8 @@
             throw new ServletException("Configuration error: problem with pdf-cache-dir="+cache_fn);
         }
 
+        pdfJobCenter = (DigilibJobCenter<OutputStream>) dlConfig.getValue("servlet.worker.pdfexecutor");
+        
 		// register this instance globally
 		context.setAttribute(instanceKey, this);
 		
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/servlet/src/digilib/servlet/PDFFileWorker.java	Fri Oct 22 19:04:49 2010 +0200
@@ -0,0 +1,7 @@
+package digilib.servlet;
+
+import java.util.concurrent.Callable;
+
+public class PDFFileWorker extends PDFStreamWorker implements Callable<V> {
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/servlet/src/digilib/servlet/PDFStreamWorker.java	Fri Oct 22 19:04:49 2010 +0200
@@ -0,0 +1,158 @@
+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;
+	}
+
+}