Mercurial > hg > digilib-old
changeset 512:aa39692dd0f8
cleaned pdf-related stuff (now in branch only)
author | robcast |
---|---|
date | Thu, 03 Sep 2009 11:32:18 +0200 |
parents | 87d2ed21bdec |
children | a53693fd7a17 |
files | servlet/src/digilib/servlet/DigilibPDFWorker.java servlet/src/digilib/servlet/MakePDF.java servlet/src/digilib/servlet/PDFCache.java |
diffstat | 3 files changed, 0 insertions(+), 1379 deletions(-) [+] |
line wrap: on
line diff
--- a/servlet/src/digilib/servlet/DigilibPDFWorker.java Fri Feb 13 11:08:19 2009 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,228 +0,0 @@ -/* DigilibImageWorker.java -- worker for image operations - * - * Digital Image Library servlet components - * - * Copyright (C) 2004 Robert Casties (robcast@mail.berlios.de) - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or (at your option) - * any later version. - * - * Please read license.txt for the full details. A copy of the GPL may be found - * at http://www.gnu.org/copyleft/lgpl.html - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 59 Temple - * Place, Suite 330, Boston, MA 02111-1307 USA - * - * Created on 19.10.2004 - */ - -package digilib.servlet; - -import java.awt.Rectangle; -import java.awt.geom.Rectangle2D; -import java.io.IOException; - -import javax.servlet.http.HttpServletResponse; - -import com.lowagie.text.BadElementException; -import com.lowagie.text.Document; -import com.lowagie.text.DocumentException; -import com.lowagie.text.Image; -import com.lowagie.text.PageSize; - -import digilib.image.DocuImage; -import digilib.image.DocuImageImpl; -import digilib.image.ImageLoaderDocuImage; -import digilib.image.ImageOpException; -import digilib.image.ImageOps; -import digilib.servlet.DigilibImageWorker; -import digilib.io.FileOpException; -import digilib.io.ImageFile; - -/** - * worker for image operations. - * - * @author casties - * - */ -public class DigilibPDFWorker extends DigilibImageWorker { - - private DigilibConfiguration dlConfig; - - HttpServletResponse response; - - long startTime; - - String mimeType; - - int scaleQual; - - DigilibRequest dlRequest; - - float paramROT; - - float paramCONT; - - float paramBRGT; - - float[] paramRGBM; - - float[] paramRGBA; - - ImageFile fileToLoad; - - float areaXoff; - - float areaYoff; - - float areaWidth; - - float areaHeight; - - float scaleXY; - - Rectangle2D outerUserImgArea; - - Rectangle2D innerUserImgArea; - - float minSubsample; - - boolean wholeRotArea; - - int forceType; - - Document doc; - - - //public ImageLoaderDocuImage render();// throws Exception; - - - /** - * @param dlConfig - * @param response - * @param mimeType - * @param scaleQual - * @param dlRequest - * @param paramROT - * @param paramCONT - * @param paramBRGT - * @param paramRGBM - * @param paramRGBA - * @param fileToLoad - * @param areaXoff - * @param outerUserImgArea - * @param innerUserImgArea - * @param minSubsample - * @param wholeRotArea - * @param forceType - */ - public DigilibPDFWorker(DigilibConfiguration dlConfig, - HttpServletResponse response, String mimeType, int scaleQual, - DigilibRequest dlRequest, float paramCONT, - float paramBRGT, float[] paramRGBM, float[] paramRGBA, - ImageFile fileToLoad, float scaleXY, Rectangle2D outerUserImgArea, - Rectangle2D innerUserImgArea, float minSubsample, - boolean wholeRotArea, int forceType, Document doc) { - super(dlConfig, - response, mimeType, scaleQual, - dlRequest, 0.0f , paramCONT, - paramBRGT, paramRGBM,paramRGBA, - fileToLoad, scaleXY, outerUserImgArea, - innerUserImgArea,minSubsample, - wholeRotArea, forceType); - - this.dlConfig = dlConfig; - this.response = response; - this.mimeType = mimeType; - this.scaleQual = scaleQual; - this.dlRequest = dlRequest; - //this.paramROT = paramROT; - this.paramCONT = paramCONT; - this.paramBRGT = paramBRGT; - this.paramRGBM = paramRGBM; - this.paramRGBA = paramRGBA; - this.fileToLoad = fileToLoad; - this.scaleXY = scaleXY; - this.outerUserImgArea = outerUserImgArea; - this.innerUserImgArea = innerUserImgArea; - this.minSubsample = minSubsample; - this.wholeRotArea = wholeRotArea; - this.forceType = forceType; - this.doc = doc; - } - - public void run() { - //logger.debug((++waitingThreads) + " waiting threads"); - ImageLoaderDocuImage img = null; - try { - sem.acquire(); - //waitingThreads--; - } catch (InterruptedException e) { - error = e; - //waitingThreads--; - // should we reinterrupt? - return; - } - //logger.debug((++runningThreads) + " running threads"); - try { - /* - * do rendering under the semaphore - */ - img = (ImageLoaderDocuImage) super.render(); - } catch (Throwable e) { - error = e; - logger.error(e); - } finally { - // runningThreads--; - sem.release(); - } - /* - * write the result without semaphore - */ - if (!hasError()) { - try{ - write(img); - } catch (Throwable e) { - error = e; - logger.error(e); - } - } - } - - public void write(ImageLoaderDocuImage img) throws FileOpException, IOException { - /* write the resulting image */ - - - try { - long timing = System.currentTimeMillis(); - Image theimg = Image.getInstance(img.getImage(),null); - - theimg.scaleToFit(PageSize.A4.getWidth(),PageSize.A4.getHeight()); - - logger.debug(" --- loading and scaling took "+(-timing+System.currentTimeMillis())+"ms"); - - timing = System.currentTimeMillis(); - - this.doc.add(theimg); - logger.debug(" --- adding took "+(-timing+System.currentTimeMillis())+"ms"); - - } catch (BadElementException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - logger.debug("------DigilibPDFWorker write BadElementException"); - - } catch (DocumentException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - logger.debug("------DigilibPDFWorker write DocumentException"); - - } - - logger.info("pdf worker " + this.getName() + " done in " - + (System.currentTimeMillis() - startTime)); - - } -} \ No newline at end of file
--- a/servlet/src/digilib/servlet/MakePDF.java Fri Feb 13 11:08:19 2009 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,931 +0,0 @@ -/* - * MakePDF - * - * Digital Image Library servlet components - * - * Copyright (C) 200-2004 Robert Casties (robcast@mail.berlios.de) - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or (at your option) - * any later version. - * - * Please read license.txt for the full details. A copy of the GPL may be found - * at http://www.gnu.org/copyleft/lgpl.html - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 59 Temple - * Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -package digilib.servlet; - -import java.awt.geom.AffineTransform; -import java.awt.geom.NoninvertibleTransformException; -import java.awt.geom.Rectangle2D; -import java.io.BufferedOutputStream; -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.io.PrintWriter; -import java.util.ArrayList; -import java.util.Hashtable; -import java.util.List; - -import javax.servlet.ServletConfig; -import javax.servlet.ServletContext; -import javax.servlet.ServletException; -import javax.servlet.ServletOutputStream; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.apache.log4j.Logger; - -import com.lowagie.text.*; -import com.lowagie.text.pdf.PdfWriter; - -import digilib.auth.AuthOpException; -import digilib.auth.AuthOps; -import digilib.image.ImageOpException; -import digilib.image.ImageOps; -import digilib.image.ImageSize; -import digilib.io.DocuDirCache; -import digilib.io.DocuDirectory; -import digilib.io.DocuDirent; -import digilib.io.FileOpException; -import digilib.io.FileOps; -import digilib.io.ImageFile; -import digilib.io.ImageFileset; - -/** - * generates pdf-files from a digilib images. - * This is a very quick and dirty but functional version and will - * (hopefully soon) be replaced by a parallelized and more sophisticated one. - * - * @author cmielack - */ - -public class MakePDF extends HttpServlet implements Runnable{ - - private static final long serialVersionUID = -325080527268912852L; - - /** digilib servlet version (for all components) */ - public static final String dlVersion = "1.7.0b"; - - /** logger for accounting requests */ - private static Logger accountlog = Logger.getLogger("account.request"); - - /** gengeral logger for this class */ - private static Logger logger = Logger.getLogger("digilib.servlet"); - - /** logger for authentication related */ - private static Logger authlog = Logger.getLogger("digilib.auth"); - - /** general error code */ - public static final int ERROR_UNKNOWN = 0; - - /** error code for authentication error */ - public static final int ERROR_AUTH = 1; - - /** error code for file operation error */ - public static final int ERROR_FILE = 2; - - /** error code for image operation error */ - public static final int ERROR_IMAGE = 3; - - /** DocuDirCache instance */ - DocuDirCache dirCache; - - /** authentication error image file */ - File denyImgFile; - - /** image error image file */ - File errorImgFile; - - /** not found error image file */ - File notfoundImgFile; - - /** subsampling before scaling */ - float minSubsample = 2f; - - /** send files as is? */ - boolean sendFileAllowed = true; - - /** default scaling quality */ - int defaultQuality = 1; - - /** DigilibConfiguration instance */ - DigilibConfiguration dlConfig; - - /** use authorization database */ - boolean useAuthorization = true; - - /** AuthOps instance */ - AuthOps authOp; - - HttpServletRequest mpdf_request = null; - HttpServletResponse mpdf_response = null; - String mpdf_filename = ""; - - String default_filename = "digilib_pages.pdf"; - - - // EXPRIMENTAL - /** try to enlarge cropping area for "oblique" angles */ - boolean wholeRotArea = false; - - /** - * Initialisation on first run. - * - * @see javax.servlet.Servlet#init(javax.servlet.ServletConfig) - */ - public void init(ServletConfig config) throws ServletException { - super.init(config); - - System.out - .println("***** Digital Image Library Image MakePDF Servlet (version " - + dlVersion + ") *****"); - // say hello in the log file - logger - .info("***** Digital Image Library Image MakePDF Servlet (version " - + dlVersion + ") *****"); - - // get our ServletContext - ServletContext context = config.getServletContext(); - // see if there is a Configuration instance - dlConfig = (DigilibConfiguration) context - .getAttribute("digilib.servlet.configuration"); - if (dlConfig == null) { - // no Configuration - throw new ServletException("No Configuration!"); - } - // set our AuthOps - useAuthorization = dlConfig.getAsBoolean("use-authorization"); - authOp = (AuthOps) dlConfig.getValue("servlet.auth.op"); - - // DocuDirCache instance - dirCache = (DocuDirCache) dlConfig.getValue("servlet.dir.cache"); - denyImgFile = ServletOps.getFile((File) dlConfig.getValue("denied-image"), config); - errorImgFile = ServletOps.getFile((File) dlConfig.getValue("error-image"), config); - notfoundImgFile = ServletOps.getFile((File) dlConfig.getValue("notfound-image"), config); - sendFileAllowed = dlConfig.getAsBoolean("sendfile-allowed"); - minSubsample = dlConfig.getAsFloat("subsample-minimum"); - defaultQuality = dlConfig.getAsInt("default-quality"); - - - context.setAttribute("digilib.servlet.MakePDF", this); // register this instance globally, so PDFCache can access it - } - - - public void doCreate(HttpServletRequest request, HttpServletResponse response, String filename) - throws ServletException, IOException { - - accountlog.info("GET from " + request.getRemoteAddr()); - // create new request with defaults - DigilibRequest dlReq = new DigilibRequest(); - // set with request parameters - dlReq.setWithRequest(request); - // add DigilibRequest to ServletRequest - request.setAttribute("digilib.servlet.request", dlReq); - - - mpdf_request = request; - mpdf_response = response; - mpdf_filename = filename; - - } - -/* public void doGet(HttpServletRequest request, HttpServletResponse response) - throws ServletException, IOException { - - accountlog.info("GET from " + request.getRemoteAddr()); - // create new request with defaults - DigilibRequest dlReq = new DigilibRequest(); - // set with request parameters - dlReq.setWithRequest(request); - // add DigilibRequest to ServletRequest - request.setAttribute("digilib.servlet.request", dlReq); - // do the processing - processRequest(request, response,default_filename); - }*/ - -/* public void doPost(HttpServletRequest request, HttpServletResponse response) - throws ServletException, IOException { - - accountlog.info("POST from " + request.getRemoteAddr()); - // create new request with defaults - DigilibRequest dlReq = new DigilibRequest(); - // set with request parameters - dlReq.setWithRequest(request); - // add DigilibRequest to ServletRequest - request.setAttribute("digilib.servlet.request", dlReq); - // do the processing - processRequest(request, response,default_filename); - }*/ - - /* - * (non-Javadoc) - * - * @see javax.servlet.http.HttpServlet#getLastModified(javax.servlet.http.HttpServletRequest) - */ - - protected long getLastModified(HttpServletRequest request) { - accountlog.debug("GetLastModified from " + request.getRemoteAddr() - + " for " + request.getQueryString()); - long mtime = -1; - // create new request with defaults - DigilibRequest dlReq = new DigilibRequest(); - // set with request parameters - dlReq.setWithRequest(request); - // find the requested file - DocuDirent f = findFile(dlReq); - if (f != null) { - DocuDirectory dd = (DocuDirectory) f.getParent(); - mtime = dd.getDirMTime() / 1000 * 1000; - } - return mtime; - } - - void createPDFfile(HttpServletRequest request, HttpServletResponse response, String filename) - throws javax.servlet.ServletException, java.io.IOException { - - Hashtable<String,Integer> cache_hash = (Hashtable<String,Integer>) this.getServletContext().getAttribute("digilib.servlet.PDFCache"); - BufferedOutputStream pdfOutStream = null; - FileOutputStream fos = null; - - String file_only = filename.split("/")[filename.split("/").length-1]; - - try { - - cache_hash.put(file_only, 2); // register the file as 'pending' - - // TODO check, if file can be created without overwriting another file etc. - - fos = new FileOutputStream(filename); - - pdfOutStream = generatePDFcontent(request, response, this.getServletContext(), fos); - - fos.flush(); - - cache_hash.put(file_only, 1); // register the file as 'done' - - } - catch (DocumentException de){ - // inform the user about what went wrong - response.setContentType("text/html"); - PrintWriter writer = response.getWriter(); - writer.println(this.getClass().getName() + " caught an exception: " - + de.getClass().getName() + "<br/> <pre>"); - de.printStackTrace(writer); - writer.println("</pre>"); - } - - finally { - if (pdfOutStream != null){ - pdfOutStream.close(); - } - if (fos!=null){ - fos.close(); - } - } - } - - - - - void addImageToPDF(HttpServletRequest request, HttpServletResponse response, int pn, Document doc) - throws ServletException { - /** until now, this is taken from the Scaler-method processRequest and modified ...*/ - - - if (dlConfig == null) { - throw new ServletException("ERROR: No Configuration!"); - } - - accountlog.debug("request: " + request.getQueryString()); - logger.debug("request: " + request.getQueryString()); - - // output mime-type - String mimeType = "image/png"; - - /* preset request parameters */ - - // scale the image file to fit window size i.e. respect dw,dh - boolean scaleToFit = true; - // scale the image by a fixed factor only - boolean absoluteScale = false; - // use low resolution images only - boolean loresOnly = false; - // use hires images only - boolean hiresOnly = false; - // send the image always as a specific type (e.g. JPEG or PNG) - int forceType = ImageOps.TYPE_AUTO; - // interpolation to use for scaling - int scaleQual = defaultQuality; - // send html error message (or image file) - boolean errorMsgHtml = false; - // original (hires) image resolution - float origResX = 0; - float origResY = 0; - - /* request parameters */ - - DigilibRequest dlRequest = (DigilibRequest) request - .getAttribute("digilib.servlet.request"); - - dlRequest.setValue("pn", pn); - //dlRequest.setValue("mo", "osize"); - //dlRequest.setValue("ddpix",72); - //dlRequest.setValue("ddpix",72); - - // destination image width - int paramDW = dlRequest.getAsInt("dw"); - // destination image height - int paramDH = dlRequest.getAsInt("dh"); - // relative area x_offset (0..1) - float paramWX = dlRequest.getAsFloat("wx"); - // relative area y_offset - float paramWY = dlRequest.getAsFloat("wy"); - // relative area width (0..1) - float paramWW = dlRequest.getAsFloat("ww"); - // relative area height - float paramWH = dlRequest.getAsFloat("wh"); - // scale factor (additional to dw/width, dh/height) - float paramWS = dlRequest.getAsFloat("ws"); - // rotation angle - float paramROT = dlRequest.getAsFloat("rot"); - // contrast enhancement - float paramCONT = dlRequest.getAsFloat("cont"); - // brightness enhancement - float paramBRGT = dlRequest.getAsFloat("brgt"); - // color modification - float[] paramRGBM = null; - Parameter p = dlRequest.get("rgbm"); - if (p.hasValue() && (!p.getAsString().equals("0/0/0"))) { - paramRGBM = p.parseAsFloatArray("/"); - } - float[] paramRGBA = null; - p = dlRequest.get("rgba"); - if (p.hasValue() && (!p.getAsString().equals("0/0/0"))) { - paramRGBA = p.parseAsFloatArray("/"); - } - // destination resolution (DPI) - float paramDDPIX = dlRequest.getAsFloat("ddpix"); - float paramDDPIY = dlRequest.getAsFloat("ddpiy"); - if ((paramDDPIX == 0) || (paramDDPIY == 0)) { - // if X or Y resolution isn't set, use DDPI - paramDDPIX = dlRequest.getAsFloat("ddpi"); - paramDDPIY = paramDDPIX; - } - // absolute scale factor for mo=ascale (and mo=osize) - float paramSCALE = dlRequest.getAsFloat("scale"); - - /* - * operation mode: "fit": always fit to page, "clip": send original - * resolution cropped, "file": send whole file (if allowed) - */ - if (dlRequest.hasOption("mo", "clip")) { - scaleToFit = false; - absoluteScale = false; - hiresOnly = true; - } else if (dlRequest.hasOption("mo", "fit")) { - scaleToFit = true; - absoluteScale = false; - hiresOnly = false; - } else if (dlRequest.hasOption("mo", "osize")) { - scaleToFit = false; - absoluteScale = true; - hiresOnly = true; - } else if (dlRequest.hasOption("mo", "ascale")) { - scaleToFit = false; - absoluteScale = true; - hiresOnly = false; - } - - // operation mode: "lores": try to use scaled image, "hires": use - // unscaled image - // "autores": try best fitting resolution - if (dlRequest.hasOption("mo", "lores")) { - loresOnly = true; - hiresOnly = false; - } else if (dlRequest.hasOption("mo", "hires")) { - loresOnly = false; - hiresOnly = true; - } else if (dlRequest.hasOption("mo", "autores")) { - loresOnly = false; - hiresOnly = false; - } - // operation mode: "errtxt": error message in html, "errimg": error - // image - if (dlRequest.hasOption("mo", "errtxt")) { - errorMsgHtml = true; - } else if (dlRequest.hasOption("mo", "errimg")) { - errorMsgHtml = false; - } - // operation mode: "q0" - "q2": interpolation quality - if (dlRequest.hasOption("mo", "q0")) { - scaleQual = 0; - } else if (dlRequest.hasOption("mo", "q1")) { - scaleQual = 1; - } else if (dlRequest.hasOption("mo", "q2")) { - scaleQual = 2; - } - // operation mode: "jpg": always use JPEG - if (dlRequest.hasOption("mo", "jpg")) { - forceType = ImageOps.TYPE_JPEG; - } - // operation mode: "png": always use PNG - if (dlRequest.hasOption("mo", "png")) { - forceType = ImageOps.TYPE_PNG; - } - - // check with the maximum allowed size (if set) - int maxImgSize = dlConfig.getAsInt("max-image-size"); - if (maxImgSize > 0) { - paramDW = (paramDW * paramWS > maxImgSize) ? (int) (maxImgSize / paramWS) - : paramDW; - paramDH = (paramDH * paramWS > maxImgSize) ? (int) (maxImgSize / paramWS) - : paramDH; - } - - // "big" try for all file/image actions - try { - - // ImageFileset of the image to load - ImageFileset fileset = null; - - /* find the file to load/send */ - - // get PathInfo - String loadPathName = dlRequest.getFilePath(); - - /* check permissions */ - if (useAuthorization) { - // get a list of required roles (empty if no restrictions) - List rolesRequired = authOp.rolesForPath(loadPathName, request); - if (rolesRequired != null) { - authlog.debug("Role required: " + rolesRequired); - authlog.debug("User: " + request.getRemoteUser()); - // is the current request/user authorized? - if (!authOp.isRoleAuthorized(rolesRequired, request)) { - // send deny answer and abort - throw new AuthOpException(); - } - } - } - - // find the file - fileset = (ImageFileset) findFile(dlRequest); - if (fileset == null) { - throw new FileOpException("File " + loadPathName + "(" - + dlRequest.getAsInt("pn") + ") not found."); - } - - /* for absolute scale and original size we need the hires size */ - ImageSize hiresSize = null; - if (absoluteScale) { - ImageFile hiresFile = fileset.getBiggest(); - if (!hiresFile.isChecked()) { - ImageOps.checkFile(hiresFile); - } - hiresSize = hiresFile.getSize(); - - /* prepare resolution and scale factor for original size */ - if (dlRequest.hasOption("mo", "osize")) { - // get original resolution from metadata - fileset.checkMeta(); - origResX = fileset.getResX(); - origResY = fileset.getResY(); - if ((origResX == 0) || (origResY == 0)) { - throw new ImageOpException("Missing image DPI information!"); - } - - if ((paramDDPIX == 0) || (paramDDPIY == 0)) { - throw new ImageOpException( - "Missing display DPI information!"); - } - // calculate absolute scale factor - float sx = paramDDPIX / origResX; - float sy = paramDDPIY / origResY; - // currently only same scale :-( - paramSCALE = (sx + sy)/2f; - } - - } - - - /* calculate expected source image size */ - ImageSize expectedSourceSize = new ImageSize(); - if (scaleToFit) { - // scale to fit -- calculate minimum source size - float scale = (1 / Math.min(paramWW, paramWH)) * paramWS; - expectedSourceSize.setSize((int) (paramDW * scale), - (int) (paramDH * scale)); - } else if (absoluteScale && dlRequest.hasOption("mo", "ascale")) { - // absolute scale -- apply scale to hires size - expectedSourceSize = hiresSize.getScaled(paramSCALE); - } else { - // clip to fit -- source = destination size - expectedSourceSize.setSize((int) (paramDW * paramWS), - (int) (paramDH * paramWS)); - } - - ImageFile fileToLoad; - /* select a resolution */ - if (hiresOnly) { - // get first element (= highest resolution) - fileToLoad = fileset.getBiggest(); - } else if (loresOnly) { - // enforced lores uses next smaller resolution - fileToLoad = fileset.getNextSmaller(expectedSourceSize); - if (fileToLoad == null) { - // this is the smallest we have - fileToLoad = fileset.getSmallest(); - } - } else { - // autores: use next higher resolution - fileToLoad = fileset.getNextBigger(expectedSourceSize); - if (fileToLoad == null) { - // this is the highest we have - fileToLoad = fileset.getBiggest(); - } - } - logger.info("Planning to load: " + fileToLoad.getFile()); - - /* - * send the image if its mo=(raw)file - */ - if (dlRequest.hasOption("mo", "file") - || dlRequest.hasOption("mo", "rawfile")) { - if (sendFileAllowed) { - String mt = null; - if (dlRequest.hasOption("mo", "rawfile")) { - mt = "application/octet-stream"; - } - logger.debug("Sending RAW File as is."); - ServletOps.sendFile(fileToLoad.getFile(), mt, response); - return; - } - } - - // check the source image - if (!fileToLoad.isChecked()) { - ImageOps.checkFile(fileToLoad); - } - // get the source image type - mimeType = fileToLoad.getMimetype(); - // get the source image size - ImageSize imgSize = fileToLoad.getSize(); - - // decide if the image can be sent as is - boolean mimetypeSendable = mimeType.equals("image/jpeg") - || mimeType.equals("image/png") - || mimeType.equals("image/gif"); - boolean imagoOptions = dlRequest.hasOption("mo", "hmir") - || dlRequest.hasOption("mo", "vmir") || (paramROT != 0) - || (paramRGBM != null) || (paramRGBA != null) - || (paramCONT != 0) || (paramBRGT != 0); - boolean imageSendable = mimetypeSendable && !imagoOptions; - - /* - * if not autoRes and image smaller than requested size then send as - * is. if autoRes and image has requested size then send as is. if - * not autoScale and not scaleToFit nor cropToFit then send as is - * (mo=file) - */ -/* if (imageSendable - && ((loresOnly && fileToLoad.getSize().isSmallerThan( - expectedSourceSize)) || (!(loresOnly || hiresOnly) && fileToLoad - .getSize().fitsIn(expectedSourceSize)))) { - - logger.debug("Sending File as is."); - - ServletOps.sendFile(fileToLoad.getFile(), null, response); - - logger.info("Done in " - + (System.currentTimeMillis() - startTime) + "ms"); - return; - } -*/ - - - /* - * stop here if we're overloaded... - * - * 503 Service Unavailable - * The server is currently unable to - * handle the request due to a temporary overloading or maintenance - * of the server. The implication is that this is a temporary - * condition which will be alleviated after some delay. If known, - * the length of the delay MAY be indicated in a Retry-After header. - * If no Retry-After is given, the client SHOULD handle the response - * as it would for a 500 response. Note: The existence of the 503 - * status code does not imply that a server must use it when - * becoming overloaded. Some servers may wish to simply refuse the - * connection. - * (RFC2616 HTTP1.1) - */ - if (! DigilibWorker.canRun()) { - logger.error("Servlet overloaded!"); - response.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE); - return; - } - - // set missing dw or dh from aspect ratio - float imgAspect = fileToLoad.getAspect(); - if (paramDW == 0) { - paramDW = (int) Math.round(paramDH * imgAspect); - } else if (paramDH == 0) { - paramDH = (int) Math.round(paramDW / imgAspect); - } - - /* crop and scale the image */ - - logger.debug("IMG: " + imgSize.getWidth() + "x" - + imgSize.getHeight()); - - // coordinates and scaling - float areaWidth; - float areaHeight; - float scaleX; - float scaleY; - float scaleXY; - - // coordinates using Java2D - // image size in pixels - Rectangle2D imgBounds = new Rectangle2D.Float(0, 0, imgSize - .getWidth(), imgSize.getHeight()); - // user window area in [0,1] coordinates - Rectangle2D relUserArea = new Rectangle2D.Float(paramWX, paramWY, - paramWW, paramWH); - // transform from relative [0,1] to image coordinates. - AffineTransform imgTrafo = AffineTransform.getScaleInstance(imgSize - .getWidth(), imgSize.getHeight()); - // transform user coordinate area to image coordinate area - Rectangle2D userImgArea = imgTrafo.createTransformedShape( - relUserArea).getBounds2D(); - - // calculate scaling factors based on inner user area - if (scaleToFit) { - areaWidth = (float) userImgArea.getWidth(); - areaHeight = (float) userImgArea.getHeight(); - scaleX = paramDW / areaWidth * paramWS; - scaleY = paramDH / areaHeight * paramWS; - scaleXY = (scaleX > scaleY) ? scaleY : scaleX; - } else if (absoluteScale) { - scaleXY = paramSCALE; - // we need to correct the factor if we use a pre-scaled image - if (imgSize.getWidth() != hiresSize.getWidth()) { - scaleXY *= (float)hiresSize.getWidth() / (float)imgSize.getWidth(); - } - scaleX = scaleXY; - scaleY = scaleXY; - areaWidth = paramDW / scaleXY * paramWS; - areaHeight = paramDH / scaleXY * paramWS; - // reset user area size - userImgArea.setRect(userImgArea.getX(), userImgArea.getY(), - areaWidth, areaHeight); - } else { - // crop to fit - areaWidth = paramDW * paramWS; - areaHeight = paramDH * paramWS; - // reset user area size - userImgArea.setRect(userImgArea.getX(), userImgArea.getY(), - areaWidth, areaHeight); - scaleX = 1f; - scaleY = 1f; - scaleXY = 1f; - } - - // enlarge image area for rotations to cover additional pixels - Rectangle2D outerUserImgArea = userImgArea; - Rectangle2D innerUserImgArea = userImgArea; - if (wholeRotArea) { - if (paramROT != 0) { - try { - // rotate user area coordinates around center of user - // area - AffineTransform rotTrafo = AffineTransform - .getRotateInstance(Math.toRadians(paramROT), - userImgArea.getCenterX(), userImgArea - .getCenterY()); - // get bounds from rotated end position - innerUserImgArea = rotTrafo.createTransformedShape( - userImgArea).getBounds2D(); - // get bounds from back-rotated bounds - outerUserImgArea = rotTrafo.createInverse() - .createTransformedShape(innerUserImgArea) - .getBounds2D(); - } catch (NoninvertibleTransformException e1) { - // this shouldn't happen anyway - logger.error(e1); - } - } - } - - logger.debug("Scale " + scaleXY + "(" + scaleX + "," + scaleY - + ") on " + outerUserImgArea); - - // clip area at the image border - outerUserImgArea = outerUserImgArea.createIntersection(imgBounds); - - // check image parameters sanity - if ((outerUserImgArea.getWidth() < 1) - || (outerUserImgArea.getHeight() < 1) - || (scaleXY * outerUserImgArea.getWidth() < 2) - || (scaleXY * outerUserImgArea.getHeight() < 2)) { - logger.error("ERROR: invalid scale parameter set!"); - throw new ImageOpException("Invalid scale parameter set!"); - } - - /* - * submit the image worker job - */ - - DigilibPDFWorker job = new DigilibPDFWorker(dlConfig, response, - mimeType, scaleQual, dlRequest, paramCONT, - paramBRGT, paramRGBM, paramRGBA, fileToLoad, scaleXY, - outerUserImgArea, innerUserImgArea, minSubsample, - wholeRotArea, forceType, doc); - - job.run(); - if (job.hasError()) { - throw new ImageOpException(job.getError().toString()); - } - - /* error handling */ - - } // end of "big" try - catch (IOException e) { - logger.error("ERROR: File IO Error: " + e); - digilibError(errorMsgHtml, ERROR_FILE, - "ERROR: File IO Error: " + e, response); - } catch (AuthOpException e) { - logger.error("ERROR: Authorization error: " + e); - digilibError(errorMsgHtml, ERROR_AUTH, - "ERROR: Authorization error: " + e, response); - } catch (ImageOpException e) { - logger.error("ERROR: Image Error: " + e); - digilibError(errorMsgHtml, ERROR_IMAGE, - "ERROR: Image Operation Error: " + e, response); - } catch (RuntimeException e) { - // JAI likes to throw RuntimeExceptions ;-( - logger.error("ERROR: Other Image Error: " + e); - digilibError(errorMsgHtml, ERROR_IMAGE, - "ERROR: Other Image Operation Error: " + e, response); - } - } - - /** - * Returns the DocuDirent corresponding to the DigilibRequest. - * - * @param dlRequest - * @return - */ - public DocuDirent findFile(DigilibRequest dlRequest) { - // find the file(set) - DocuDirent f = dirCache.getFile(dlRequest.getFilePath(), dlRequest - .getAsInt("pn"), FileOps.CLASS_IMAGE); - return f; - } - - /** - * Sends an error to the client as text or image. - * - * @param asHTML - * @param type - * @param msg - * @param response - */ - public void digilibError(boolean asHTML, int type, String msg, - HttpServletResponse response) { - try { - File img = null; - if (type == ERROR_AUTH) { - if (msg == null) { - msg = "ERROR: Unauthorized access!"; - } - img = denyImgFile; - } else if (type == ERROR_FILE) { - if (msg == null) { - msg = "ERROR: Image file not found!"; - } - img = notfoundImgFile; - } else { - if (msg == null) { - msg = "ERROR: Other image error!"; - } - img = this.errorImgFile; - } - if (asHTML && (img != null)) { - ServletOps.htmlMessage(msg, response); - } else { - ServletOps.sendFile(img, null, response); - } - } catch (IOException e) { - logger.error("Error sending error!", e); - } - - } - - /** - * @return the dlVersion - */ - public static String getVersion() { - return dlVersion; - } - - - protected BufferedOutputStream generatePDFcontent(HttpServletRequest request, HttpServletResponse response, - ServletContext servletcontext, OutputStream out) - throws DocumentException { - - /** This method sets up a document and calls the addImage method to add all the images */ - Document doc = new Document(PageSize.A4,0,0,0,0); - BufferedOutputStream outstream = new BufferedOutputStream(out); - - PdfWriter docwriter = null; - - - try{ - - docwriter = PdfWriter.getInstance(doc, outstream); - - - doc.addAuthor(this.getClass().getName()); - doc.addCreationDate(); - doc.addKeywords("digilib"); - doc.addTitle("digilib PDF"); - doc.addCreator(this.getClass().getName()); - - doc.open(); - - - // get width and height from the request -/* float docW = PageSize.A4.getWidth() - 2*PageSize.A4.getBorder(); - float docH= PageSize.A4.getHeight()- 2*PageSize.A4.getBorder(); -*/ - - // evaluate the pgs parameter (which pages go into the pdf) - String pages = request.getParameter("pgs"); - ArrayList<Integer> pgs=new ArrayList<Integer>(); // a list of the requested page numbers - String intervals[] = pages.split(","); - - // convert the page-interval-strings into a list containing every single page - for(String interval: intervals){ - if(interval.indexOf("-") > -1){ - String nums[] = interval.split("-"); - - for(int i=Integer.valueOf(nums[0]); i <= Integer.valueOf(nums[1]); i++){ - pgs.add(i); - } - } - else{ - pgs.add(Integer.valueOf(interval)); - } - } - - - - - // add all the images/pages to the pdf - for(int i=0; i<pgs.size(); i++){ - int pn=pgs.get(i); - this.addImageToPDF(request, response, pn, doc); - } - - - - } - catch (Exception de) { - logger.debug(de.getMessage()); - } - finally{ - if (doc!=null){ - doc.close(); - } - if (docwriter!=null){ - docwriter.close(); - } - } - return outstream; - } - - - public void run() { - if(mpdf_request!=null && mpdf_response!=null && mpdf_filename!=""){ - try { - createPDFfile(mpdf_request, mpdf_response, mpdf_filename); - } catch (ServletException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } - } -} \ No newline at end of file
--- a/servlet/src/digilib/servlet/PDFCache.java Fri Feb 13 11:08:19 2009 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,220 +0,0 @@ -package digilib.servlet; - -import java.io.BufferedInputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.util.Hashtable; - -import javax.servlet.ServletConfig; -import javax.servlet.ServletContext; -import javax.servlet.ServletException; -import javax.servlet.ServletOutputStream; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.apache.log4j.Logger; - - -/** - * PDF request manager with caching capabilities. - * This is a very early and dirty but functional version and will - * (hopefully soon) be replaced by a parallelized and more sophisticated one. - * - * @author cmielack - * - */ - -public class PDFCache extends HttpServlet { - - private static final long serialVersionUID = 1L; - - - private static int STATUS_NONEXISTENT = 0; // the document does not exist and is not under construction - private static int STATUS_DONE = 1; // the document exists and can be downloaded - private static int STATUS_PENDING = 2; // the document is "under construction" - private static int STATUS_ERROR = 3; // an error occurred while processing the request - - private static String cache_directory = "cache/"; // the path (relative to the tomcat base-directory) where cached - // files are stored - - private static String cache_hash_id = "digilib.servlet.PDFCache"; - - - private static Logger logger = Logger.getLogger("digilib.servlet"); - - - public void init(ServletConfig config){ - // initialize the PDFCache - - logger.debug("Initializing PDFCache"); - - try { - super.init(config); - } catch (ServletException e) { - e.printStackTrace(); - } - - ServletContext context = this.getServletContext(); - - context.setAttribute(cache_hash_id, new Hashtable<String,Integer>()); - - Hashtable<String,Integer> cache_hash = (Hashtable<String,Integer>) context.getAttribute(cache_hash_id); - - if (cache_hash==null){ - cache_hash = new Hashtable<String,Integer>(); - context.setAttribute(cache_hash_id, cache_hash); - } - - // search the cache-directory for existing files and fill them into the Hashtable as STATUS_DONE - File cache_dir = new File(cache_directory); - String[] cached_files = cache_dir.list(); - - - for (String file: cached_files){ - if (file.endsWith(".pdf")){ - logger.debug("cache found "+file); - cache_hash.put(file, 1); - } - } - - } - - - public String getDocumentId(HttpServletRequest request){ - // generate an unambiguous ID from the request (this is used for filenames etc) - String id; - - String fn = request.getParameter("fn"); - String dh = request.getParameter("dh"); - String pgs = request.getParameter("pgs"); - - id = "fn=" + fn + "&dh=" + dh + "&pgs=" + pgs + ".pdf"; - - return id; - } - - - public void doGet(HttpServletRequest request, HttpServletResponse response){ - - // get the status of the Document specified by the request ... - int status = this.getStatus(request); - - - if (status == STATUS_DONE) { - // ... and if the file already exists, send it ... - try { - sendFile(request,response); - - } catch (IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } - - else if (status == STATUS_PENDING){ - // ... if it is in the works, notify the user about it ... - } - else if (status == STATUS_NONEXISTENT){ - // ... or else, generate the file and inform the user about the estimated generation-time - try { - createFile(request, response); - response.sendRedirect(request.getRequestURI()+'?'+request.getQueryString()+"&done=true"); // refresh the browser after finishing the file - } catch (ServletException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (InterruptedException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } - else { - // if an error occurred ... - } - } - - public int getStatus(HttpServletRequest request){ - - String documentId = getDocumentId(request); - - ServletContext context = this.getServletContext(); - Hashtable<String,Integer> documentStatus = (Hashtable<String,Integer>) context.getAttribute(cache_hash_id); - - int status = STATUS_NONEXISTENT; - - if (documentStatus.containsKey(documentId)){ - status = documentStatus.get(documentId); - } - - return status; - } - - public void sendFile(HttpServletRequest request, HttpServletResponse response) throws IOException{ - // send the file specified by the request to the response - - String filename = getDocumentId(request); - File cached_file = null; - FileInputStream fis = null; - ServletOutputStream sos = null; - BufferedInputStream bis = null; - - try { - cached_file = new File(this.cache_directory + filename); - fis = new FileInputStream(cached_file); - sos = response.getOutputStream(); - bis = new BufferedInputStream(fis); - int bytes = 0; - - String fn = request.getParameter("fn"); - String pgs = request.getParameter("pgs"); - - response.setContentType("application/pdf"); - response.addHeader("Content-Disposition", "attachment; filename="+fn+"_"+pgs+".pdf"); - response.setContentLength( (int) cached_file.length()); - - logger.debug("Sending document "+filename+" to the user."); - - while ((bytes = bis.read()) != -1){ - sos.write(bytes); - } - } - catch(Exception e){ - logger.error(e.getMessage()); - } - finally{ - // close all streams - if (fis != null) - fis.close(); - if (bis != null) - bis.close(); - if (sos != null) - sos.close(); - } - } - - public void createFile(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException, InterruptedException{ - // use MakePDF to generate a new Document and put it into the cache-directory - - // get global instance of MakePDF - MakePDF mpdf = (MakePDF) this.getServletContext().getAttribute("digilib.servlet.MakePDF"); - - - if (mpdf==null){ - mpdf = new MakePDF(); - logger.debug("didn't find MakePDF-Object"); - } - - String filename = this.cache_directory + this.getDocumentId(request); - - logger.debug("createFile is going to create file "+filename); - - mpdf.doCreate(request,response,filename); // set the parameters and ... - mpdf.run(); // ... start generating the pdf - - //new Thread(mpdf,"MakePDF").start(); - } -} \ No newline at end of file