# HG changeset patch # User robcast # Date 1292530751 -3600 # Node ID 0885f5ca5b24fe04ab5afe6d9ec54ccfcdb70bb2 # Parent 5cc180bb0a5c2d87360d1c571cd024947f198589 more refactoring and rearranging pdf and image generation works now diff -r 5cc180bb0a5c -r 0885f5ca5b24 client/digitallibrary/dlInfo-xml.jsp --- a/client/digitallibrary/dlInfo-xml.jsp Thu Dec 16 17:02:34 2010 +0100 +++ b/client/digitallibrary/dlInfo-xml.jsp Thu Dec 16 21:19:11 2010 +0100 @@ -23,7 +23,7 @@ %> <% - Object[] keys = dlRequest.getParams.keySet().toArray(); + Object[] keys = dlRequest.getParams().keySet().toArray(); java.util.Arrays.sort(keys); int l = keys.length; for (int i = 0; i < l; i++) { diff -r 5cc180bb0a5c -r 0885f5ca5b24 client/digitallibrary/greyskin/digimage-neu.jsp --- a/client/digitallibrary/greyskin/digimage-neu.jsp Thu Dec 16 17:02:34 2010 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,443 +0,0 @@ -<%@ page language="java" %><%! -// -- JSP init ------------- - -// create DocumentBean instance for all JSP requests -digilib.servlet.DocumentBean docBean = new digilib.servlet.DocumentBean(); - -// initialize DocumentBean instance in JSP init -public void jspInit() { - try { - // set servlet init-parameter - docBean.setConfig(getServletConfig()); - } catch (javax.servlet.ServletException e) { - System.out.println(e); - } -} -// -- end of JSP init ------------- -%><% -// -- JSP request ------------- - -// parsing the query -// ----------------- -digilib.servlet.DigilibRequest dlRequest = new digilib.servlet.DigilibRequest(request); -docBean.setRequest(dlRequest); -// check if authentication is needed and redirect if necessary -docBean.doAuthentication(response); -// add number of pages -dlRequest.setValue("pt", docBean.getNumPages()); -// store objects for jsp:include -pageContext.setAttribute("docBean", docBean, pageContext.REQUEST_SCOPE); -%> - - Digital Document Library NG - - - - - - - - - - - - - - -
- <% if (dlRequest.hasOption("clop", "noarrows")) { - %><% - } else { - %><% - } - %> -
- - - - - - - - - - - - - - - -
- - - - -
- -
- - - - -
- -
- - - - -
- -
- - - - -
- -
- - - - -
- -
- - - - -
- -
- - - - -
- -
- - - - -
- -
- - - - -
- -
- - - - -
- -
- - - - -
- -
- - - - -
- -
- - - - -
- -
- - - - -
- -
- - - - -
- -
- - - - -
- -
- - - - -
- -
- - - - -
- -
- - - - -
- - - - - - - diff -r 5cc180bb0a5c -r 0885f5ca5b24 client/digitallibrary/greyskin/digimage.jsp --- a/client/digitallibrary/greyskin/digimage.jsp Thu Dec 16 17:02:34 2010 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,459 +0,0 @@ -<%@ page language="java" %><%! - // -- JSP init ------------- - - // create DocumentBean instance for all JSP requests - digilib.servlet.DocumentBean docBean = new digilib.servlet.DocumentBean(); - - // initialize DocumentBean instance in JSP init - public void jspInit() { - try { - // set servlet init-parameter - docBean.setConfig(getServletConfig()); - } catch (javax.servlet.ServletException e) { - System.out.println(e); - } - } - // -- end of JSP init ------------- -%> - -<% - // -- JSP request ------------- - - // parsing the query - // ----------------- - digilib.servlet.DigilibRequest dlRequest = new digilib.servlet.DigilibRequest(request); - docBean.setRequest(dlRequest); - // check if authentication is needed and redirect if necessary - docBean.doAuthentication(response); - // add number of pages - dlRequest.setValue("pt", docBean.getNumPages()); - // store objects for jsp:include - pageContext.setAttribute("docBean", docBean, pageContext.REQUEST_SCOPE); -%> - - - - - Digital Document Library NG - - - - - - - - - - - - -
-
- -
-
- - -
-
-
-
-
-
-
-
- - -
-
-
-
- - -
- - - - -
- -
- - - - -
- -
- - - - -
- -
- - - - -
- -
- - - - -
- -
- - - - -
- -
- - - - -
- -
- - - - -
- -
- - - - -
- -
- - - - -
- -
- - - - -
- -
- - - - -
- -
- - - - -
- -
- - - - -
- -
- - - - -
- -
- - - - -
- -
- - - - -
- -
- - - - -
- -
- - - - -
- - - - - - - diff -r 5cc180bb0a5c -r 0885f5ca5b24 client/digitallibrary/greyskin/digimage_img_inc.jsp --- a/client/digitallibrary/greyskin/digimage_img_inc.jsp Thu Dec 16 17:02:34 2010 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,25 +0,0 @@ -<%@ page language="java" %><% -// retrieve objects from context -digilib.servlet.DocumentBean docBean = (digilib.servlet.DocumentBean) pageContext.getAttribute("docBean", pageContext.REQUEST_SCOPE); -digilib.servlet.DigilibRequest dlRequest = docBean.getRequest(); -String ua = request.getHeader("User-Agent"); -boolean isN4 = ((ua.indexOf("Mozilla/4.") > -1)&&(ua.indexOf("MSIE") == -1)); -%> -<% - if (isN4) { -%><% - } else { -%>
<% - } -%> - -<% - if (isN4) { -%><% - } else { -%>
<% - } -%> diff -r 5cc180bb0a5c -r 0885f5ca5b24 client/digitallibrary/greyskin/digimage_tbl_inc.jsp --- a/client/digitallibrary/greyskin/digimage_tbl_inc.jsp Thu Dec 16 17:02:34 2010 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,61 +0,0 @@ -<%@ page language="java" %><% -// retrieve objects from context -digilib.servlet.DocumentBean docBean = (digilib.servlet.DocumentBean) pageContext.getAttribute("docBean", pageContext.REQUEST_SCOPE); -digilib.servlet.DigilibRequest dlRequest = docBean.getRequest(); -String ua = request.getHeader("User-Agent"); -boolean isN4 = ((ua.indexOf("Mozilla/4.") > -1)&&(ua.indexOf("MSIE") == -1)); -%> - - - - - - - - - - - - - - - - -
<% - if (docBean.canMoveUp()) { - %><% - } - %>
<% - if (docBean.canMoveLeft()) { - %><% - } - %> -<% - if(isN4) { - %><% - } else { - %>
<% - } -%> - -<% - if(isN4) { - %><% - } else { - %>
<% - } -%> -
<% - if (docBean.canMoveRight()) { - %><% - } - %>
<% - if (docBean.canMoveDown()) { - %><% - } - %>
diff -r 5cc180bb0a5c -r 0885f5ca5b24 client/digitallibrary/greyskin/diginew.jsp --- a/client/digitallibrary/greyskin/diginew.jsp Thu Dec 16 17:02:34 2010 +0100 +++ b/client/digitallibrary/greyskin/diginew.jsp Thu Dec 16 21:19:11 2010 +0100 @@ -28,7 +28,7 @@ // add number of pages dlRequest.setValue("pt", docBean.getNumPages()); // store objects for jsp:include - pageContext.setAttribute("docBean", docBean, pageContext.REQUEST_SCOPE); + pageContext.setAttribute("docBean", docBean, PageContext.REQUEST_SCOPE); %> diff -r 5cc180bb0a5c -r 0885f5ca5b24 client/digitallibrary/pdf/error.jsp --- a/client/digitallibrary/pdf/error.jsp Thu Dec 16 17:02:34 2010 +0100 +++ b/client/digitallibrary/pdf/error.jsp Thu Dec 16 21:19:11 2010 +0100 @@ -1,13 +1,13 @@ -<%@ page language="java" contentType="text/html; charset=ISO-8859-1" +<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="ISO-8859-1"%> - + Error

Error

-Während der Verarbeitung ihrer Anfrage trat ein Fehler auf. Möglicherweise sind die übergebenen Parameter fehlerhaft. +There was an error while processing your request. Please check the parameters and try again. diff -r 5cc180bb0a5c -r 0885f5ca5b24 client/digitallibrary/pdf/wip.jsp --- a/client/digitallibrary/pdf/wip.jsp Thu Dec 16 17:02:34 2010 +0100 +++ b/client/digitallibrary/pdf/wip.jsp Thu Dec 16 21:19:11 2010 +0100 @@ -1,14 +1,14 @@ -<%@ page language="java" contentType="text/html; charset=ISO-8859-1" +<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="ISO-8859-1"%> - + Work in progress ... -

Bitte warten ...

-ihre Anfrage wird bearbeitet. Der Download beginnt automatisch, sobald das Dokument fertig generiert ist. +

Please wait ...

+your request is being processed. The download starts automatically when the document is finished. diff -r 5cc180bb0a5c -r 0885f5ca5b24 client/digitallibrary/server/dlConfig.jsp --- a/client/digitallibrary/server/dlConfig.jsp Thu Dec 16 17:02:34 2010 +0100 +++ b/client/digitallibrary/server/dlConfig.jsp Thu Dec 16 21:19:11 2010 +0100 @@ -1,4 +1,4 @@ -<%@page import="digilib.servlet.DigilibJobCenter"%> +<%@page import="digilib.util.DigilibJobCenter"%> <%@ page language="java" %> <%! diff -r 5cc180bb0a5c -r 0885f5ca5b24 servlet/src/digilib/image/ImageJobDescription.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/servlet/src/digilib/image/ImageJobDescription.java Thu Dec 16 21:19:11 2010 +0100 @@ -0,0 +1,503 @@ +package digilib.image; + +import java.awt.geom.AffineTransform; +import java.awt.geom.Rectangle2D; +import java.io.IOException; + +import org.apache.log4j.Logger; + +import digilib.io.DocuDirCache; +import digilib.io.DocuDirectory; +import digilib.io.FileOpException; +import digilib.io.FileOps; +import digilib.io.ImageFile; +import digilib.io.ImageFileset; +import digilib.servlet.DigilibConfiguration; +import digilib.util.OptionsSet; +import digilib.util.Parameter; +import digilib.util.ParameterMap; + + +/** + * A container class for storing a set of instructional parameters + * used for content generating classes like MakePDF. + * + * This contains the functionality formerly found in Scaler, processRequest, only factorized. + * + * TODO clean up... + * + * @author cmielack, casties + * + */ + +public class ImageJobDescription extends ParameterMap { + + DigilibConfiguration dlConfig = null; + protected static Logger logger = Logger.getLogger("digilib.servlet"); + + ImageFile fileToLoad = null; + ImageFileset fileset = null; + DocuDirectory fileDir = null; + String filePath = null; + ImageSize expectedSourceSize = null; + Float scaleXY = null; + Rectangle2D userImgArea = null; + Rectangle2D outerUserImgArea= null; + Boolean imageSendable = null; + String mimeType; + Integer paramDW; + Integer paramDH; + + /** create empty ImageJobDescription. + * @param dlcfg + */ + public ImageJobDescription(DigilibConfiguration dlcfg) { + super(30); + dlConfig = dlcfg; + } + + + /** set up Parameters + * @see digilib.util.ParameterMap#initParams() + */ + @Override + protected void initParams() { + // url of the page/document (second part) + newParameter("fn", "", null, 's'); + // page number + newParameter("pn", new Integer(1), null, 's'); + // width of client in pixels + newParameter("dw", new Integer(0), null, 's'); + // height of client in pixels + newParameter("dh", new Integer(0), null, 's'); + // left edge of image (float from 0 to 1) + newParameter("wx", new Float(0), null, 's'); + // top edge in image (float from 0 to 1) + newParameter("wy", new Float(0), null, 's'); + // width of image (float from 0 to 1) + newParameter("ww", new Float(1), null, 's'); + // height of image (float from 0 to 1) + newParameter("wh", new Float(1), null, 's'); + // scale factor + newParameter("ws", new Float(1), null, 's'); + // special options like 'fit' for gifs + newParameter("mo", this.options, null, 's'); + // rotation angle (degree) + newParameter("rot", new Float(0), null, 's'); + // contrast enhancement factor + newParameter("cont", new Float(0), null, 's'); + // brightness enhancement factor + newParameter("brgt", new Float(0), null, 's'); + // color multiplicative factors + newParameter("rgbm", "0/0/0", null, 's'); + // color additive factors + newParameter("rgba", "0/0/0", null, 's'); + // display dpi resolution (total) + newParameter("ddpi", new Float(0), null, 's'); + // display dpi X resolution + newParameter("ddpix", new Float(0), null, 's'); + // display dpi Y resolution + newParameter("ddpiy", new Float(0), null, 's'); + // scale factor for mo=ascale + newParameter("scale", new Float(1), null, 's'); + } + + + /* (non-Javadoc) + * @see digilib.servlet.ParameterMap#initOptions() + */ + @Override + protected void initOptions() { + if (options == null) { + String s = this.getAsString("mo"); + options = new OptionsSet(s); + } + } + + + /** Creates new ImageJobDescription by merging Parameters from another ParameterMap. + * @param pm + * @param dlcfg + * @return + */ + public static ImageJobDescription getInstance(ParameterMap pm, DigilibConfiguration dlcfg) { + ImageJobDescription newMap = new ImageJobDescription(dlcfg); + // add all params to this map + newMap.params.putAll(pm.getParams()); + newMap.initOptions(); + return newMap; + } + + + public String getMimeType() throws IOException { + if (mimeType == null) { + fileToLoad = getFileToLoad(); + if(! fileToLoad.isChecked()){ + ImageOps.checkFile(fileToLoad); + } + mimeType = fileToLoad.getMimetype(); + } + return mimeType; + } + + public ImageFile getFileToLoad() throws IOException { + + if(fileToLoad == null){ + fileset = getFileset(); + + /* select a resolution */ + if (getHiresOnly()) { + // get first element (= highest resolution) + fileToLoad = fileset.getBiggest(); + } else if (getLoresOnly()) { + // enforced lores uses next smaller resolution + fileToLoad = fileset.getNextSmaller(getExpectedSourceSize()); + if (fileToLoad == null) { + // this is the smallest we have + fileToLoad = fileset.getSmallest(); + } + } else { + // autores: use next higher resolution + fileToLoad = fileset.getNextBigger(getExpectedSourceSize()); + if (fileToLoad == null) { + // this is the highest we have + fileToLoad = fileset.getBiggest(); + } + } + logger.info("Planning to load: " + fileToLoad.getFile()); + } + + return fileToLoad; + + } + + public DocuDirectory getFileDirectory() throws FileOpException { + if(fileDir == null){ + DocuDirCache dirCache = (DocuDirCache) dlConfig.getValue("servlet.dir.cache"); + String fp = getFilePath(); + fileDir = dirCache.getDirectory(fp); + if (fileDir == null) { + throw new FileOpException("Directory " + getFilePath() + " not found."); + } + } + return fileDir; + } + + public ImageFileset getFileset() throws FileOpException { + if(fileset==null){ + DocuDirCache dirCache = (DocuDirCache) dlConfig.getValue("servlet.dir.cache"); + + fileset = (ImageFileset) dirCache.getFile(getFilePath(), getAsInt("pn"), FileOps.CLASS_IMAGE); + if (fileset == null) { + throw new FileOpException("File " + getFilePath() + "(" + + getAsInt("pn") + ") not found."); + } + } + return fileset; + } + + public String getFilePath() { + if(filePath == null){ + String s = this.getAsString("request.path"); + s += this.getAsString("fn"); + filePath = FileOps.normalName(s); + } + return filePath; + } + + public boolean getHiresOnly(){ + return hasOption("clip") || hasOption("hires"); + } + + public boolean getLoresOnly(){ + return hasOption("lores"); + } + + public boolean getScaleToFit() { + return !(hasOption("clip") || hasOption("osize") || hasOption("ascale")); + } + + public boolean getAbsoluteScale(){ + return hasOption("osize") || hasOption("ascale"); + } + + + public ImageSize getExpectedSourceSize() throws IOException { + if (expectedSourceSize == null){ + expectedSourceSize = new ImageSize(); + if (getScaleToFit()) { + // scale to fit -- calculate minimum source size + float scale = (1 / Math.min(getAsFloat("ww"), getAsFloat("wh"))) * getAsFloat("ws"); + expectedSourceSize.setSize((int) (getDw() * scale), + (int) (getDh() * scale)); + } else if (getAbsoluteScale() && hasOption("ascale")) { + // absolute scale -- apply scale to hires size + expectedSourceSize = getHiresSize().getScaled(getAsFloat("scale")); + } else { + // clip to fit -- source = destination size + expectedSourceSize.setSize((int) (getDw() * getAsFloat("ws")), + (int) (getDh() * getAsFloat("ws"))); + } + } + return expectedSourceSize; + } + + public ImageSize getHiresSize() throws IOException { + logger.debug("get_hiresSize()"); + + ImageSize hiresSize = null; + ImageFileset fileset = getFileset(); + if (getAbsoluteScale()) { + ImageFile hiresFile = fileset.getBiggest(); + if (!hiresFile.isChecked()) { + ImageOps.checkFile(hiresFile); + } + hiresSize = hiresFile.getSize(); + } + return hiresSize; + + } + + /** Returns image scaling factor. + * Uses image size and user parameters. + * Modifies scaleXY, userImgArea. + * @return + * @throws IOException + * @throws ImageOpException + */ + public float getScaleXY() throws IOException, ImageOpException { + //logger.debug("get_scaleXY()"); + if(scaleXY == null){ + // coordinates and scaling + float areaWidth; + float areaHeight; + float ws = getAsFloat("ws"); + ImageSize imgSize = getFileToLoad().getSize(); + // user window area in [0,1] coordinates + Rectangle2D relUserArea = new Rectangle2D.Float(getAsFloat("wx"), getAsFloat("wy"), + getAsFloat("ww"), getAsFloat("wh")); + // transform from relative [0,1] to image coordinates. + AffineTransform imgTrafo = AffineTransform.getScaleInstance(imgSize + .getWidth(), imgSize.getHeight()); + // transform user coordinate area to image coordinate area + userImgArea = imgTrafo.createTransformedShape( + relUserArea).getBounds2D(); + + if (getScaleToFit()) { + // calculate scaling factors based on inner user area + areaWidth = (float) userImgArea.getWidth(); + areaHeight = (float) userImgArea.getHeight(); + float scaleX = getDw() / areaWidth * ws; + float scaleY = getDh() / areaHeight * ws; + scaleXY = (scaleX > scaleY) ? scaleY : scaleX; + } else if (getAbsoluteScale()) { + // absolute scaling factor + if (hasOption("osize")) { + // get original resolution from metadata + fileset.checkMeta(); + float origResX = fileset.getResX(); + float origResY = fileset.getResY(); + if ((origResX == 0) || (origResY == 0)) { + throw new ImageOpException("Missing image DPI information!"); + } + if ((getAsFloat("ddpix") == 0) || (getAsFloat("ddpiy") == 0)) { + throw new ImageOpException("Missing display DPI information!"); + } + // calculate absolute scale factor + float sx = getAsFloat("ddpix") / origResX; + float sy = getAsFloat("ddpiy") / origResY; + // currently only same scale -- mean value + scaleXY = (sx + sy) / 2f; + } else { + scaleXY = getAsFloat("scale"); + } + // we need to correct the factor if we use a pre-scaled image + ImageSize hiresSize = getHiresSize(); + if (imgSize.getWidth() != hiresSize.getWidth()) { + scaleXY *= (float)hiresSize.getWidth() / (float)imgSize.getWidth(); + } + areaWidth = getDw() / scaleXY * ws; + areaHeight = getDh() / scaleXY * ws; + // reset user area size + userImgArea.setRect(userImgArea.getX(), userImgArea.getY(), + areaWidth, areaHeight); + } else { + // crop to fit -- don't scale + areaWidth = getDw() * ws; + areaHeight = getDh() * ws; + // reset user area size + userImgArea.setRect(userImgArea.getX(), userImgArea.getY(), + areaWidth, areaHeight); + scaleXY = 1f; + } + } + return (float) scaleXY; + } + + public int getDw() throws IOException { + logger.debug("get_paramDW()"); + if (paramDW == null) { + + paramDW = getAsInt("dw"); + paramDH = getAsInt("dh"); + + float imgAspect = getFileToLoad().getAspect(); + if (paramDW == 0) { + // calculate dw + paramDW = Math.round(paramDH * imgAspect); + setValue("dw", paramDW); + } else if (paramDH == 0) { + // calculate dh + paramDH = Math.round(paramDW / imgAspect); + setValue("dh", paramDH); + } + } + return paramDW; + } + + public int getDh() throws IOException { + logger.debug("get_paramDH()"); + if (paramDH == null) { + + paramDW = getAsInt("dw"); + paramDH = getAsInt("dh"); + + float imgAspect = getFileToLoad().getAspect(); + if (paramDW == 0) { + // calculate dw + paramDW = Math.round(paramDH * imgAspect); + setValue("dw", paramDW); + } else if (paramDH == 0) { + // calculate dh + paramDH = Math.round(paramDW / imgAspect); + setValue("dh", paramDH); + } + } + return paramDH; + } + + public Integer get_scaleQual(){ + logger.debug("get_scaleQual()"); + Integer qual = dlConfig.getAsInt("default-quality"); + if(hasOption("q0")) + qual = 0; + else if(hasOption("q1")) + qual = 1; + else if(hasOption("q2")) + qual = 2; + return qual; + } + + + public Rectangle2D getUserImgArea() throws IOException, ImageOpException{ + if(userImgArea == null) { + // getScaleXY sets userImgArea + getScaleXY(); + } + return userImgArea; + + } + + public Rectangle2D getOuterUserImgArea() throws IOException, ImageOpException { + if(outerUserImgArea == null){ + outerUserImgArea = getUserImgArea(); + + // image size in pixels + ImageSize imgSize = getFileToLoad().getSize(); + Rectangle2D imgBounds = new Rectangle2D.Float(0, 0, imgSize.getWidth(), + imgSize.getHeight()); + + // clip area at the image border + outerUserImgArea = outerUserImgArea.createIntersection(imgBounds); + + // check image parameters sanity + scaleXY = getScaleXY(); + logger.debug("outerUserImgArea.getWidth()=" + outerUserImgArea.getWidth()); + logger.debug("get_scaleXY() * outerUserImgArea.getWidth() = " + (scaleXY * outerUserImgArea.getWidth())); + + 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!"); + } + } + return outerUserImgArea; + } + + + public int getForceType(){ + if(hasOption("jpg")) + return ImageOps.TYPE_JPEG; + if(hasOption("png")) + return ImageOps.TYPE_PNG; + + return ImageOps.TYPE_AUTO; + } + + public float[] getRGBM(){ + float[] paramRGBM = null;//{0f,0f,0f}; + Parameter p = params.get("rgbm"); + if (p.hasValue() && (!p.getAsString().equals("0/0/0"))) { + return p.parseAsFloatArray("/"); + } + return paramRGBM; + } + + public float[] getRGBA(){ + float[] paramRGBA = null;//{0f,0f,0f}; + Parameter p = params.get("rgba"); + if (p.hasValue() && (!p.getAsString().equals("0/0/0"))) { + paramRGBA = p.parseAsFloatArray("/"); + } + return paramRGBA; + } + + /** Has send-as-file been requested? + * @return + */ + public boolean getSendAsFile(){ + return hasOption("file") + || hasOption("rawfile"); + } + + /** Could the image be sent without processing? + * Takes image type and additional image operations into account. + * Does not check requested size transformation. + * @return + * @throws IOException + */ + public boolean isImageSendable() throws IOException { + // cached result? + if (imageSendable == null) { + String mimeType = getMimeType(); + imageSendable = ( (mimeType.equals("image/jpeg") + || mimeType.equals("image/png") + || mimeType.equals("image/gif") ) + && + !(hasOption("hmir") + || hasOption("vmir") + || (getAsFloat("rot") != 0.0) + || (getRGBM() != null) + || (getRGBA() != null) + || (getAsFloat("cont") != 0.0) + || (getAsFloat("brgt") != 0.0))); + } + + return imageSendable; + } + + + public boolean isTransformRequired() throws IOException { + ImageSize is = getFileToLoad().getSize(); + ImageSize ess = getExpectedSourceSize(); + // nt = no transform required + boolean nt = isImageSendable() && ( + // lores: send if smaller + (getLoresOnly() && is.isSmallerThan(ess)) + // else send if it fits + || (!(getLoresOnly() || getHiresOnly()) && is.fitsIn(ess))); + return ! nt; + } +} \ No newline at end of file diff -r 5cc180bb0a5c -r 0885f5ca5b24 servlet/src/digilib/image/ImageWorker.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/servlet/src/digilib/image/ImageWorker.java Thu Dec 16 21:19:11 2010 +0100 @@ -0,0 +1,154 @@ +/** Worker (Callable) that renders an image. + * + */ +package digilib.image; + +import java.awt.Rectangle; +import java.io.IOException; +import java.util.concurrent.Callable; + +import org.apache.log4j.Logger; + +import digilib.io.FileOpException; +import digilib.servlet.DigilibConfiguration; + +/** Worker that renders an image. + * + * @author casties + * + */ +public class ImageWorker implements Callable { + + + protected static Logger logger = Logger.getLogger(ImageWorker.class); + private DigilibConfiguration dlConfig; + private ImageJobDescription jobinfo; + + public ImageWorker(DigilibConfiguration dlConfig, ImageJobDescription jobinfo) { + super(); + this.dlConfig = dlConfig; + this.jobinfo = jobinfo; + } + + /** + * render and return the image + */ + @Override + public DocuImage call() throws FileOpException, IOException, ImageOpException { + + logger.debug("image worker starting"); + long startTime = System.currentTimeMillis(); + + /* crop and scale image */ + + // new DocuImage instance + DocuImage docuImage = dlConfig.getDocuImageInstance(); + if (docuImage == null) { + throw new ImageOpException("Unable to load DocuImage class!"); + } + + // set interpolation quality + docuImage.setQuality(jobinfo.get_scaleQual()); + + Rectangle loadRect = jobinfo.getOuterUserImgArea().getBounds(); + float scaleXY = jobinfo.getScaleXY(); + + // use subimage loading if possible + if (docuImage.isSubimageSupported()) { + logger.debug("Subimage: scale " + scaleXY + " = " + (1 / scaleXY)); + float subf = 1f; + float subsamp = 1f; + if (scaleXY < 1) { + subf = 1 / scaleXY; + // for higher quality reduce subsample factor by minSubsample + if (jobinfo.get_scaleQual() > 0) { + subsamp = (float) Math.max(Math.floor(subf / dlConfig.getAsFloat("subsample-minimum")), 1d); + } else { + subsamp = (float) Math.floor(subf); + } + scaleXY = subsamp / subf; + logger.debug("Using subsampling: " + subsamp + " rest " + + scaleXY); + } + + docuImage.loadSubimage(jobinfo.getFileToLoad(), loadRect, (int) subsamp); + + logger.debug("SUBSAMP: " + subsamp + " -> " + docuImage.getWidth() + + "x" + docuImage.getHeight()); + + docuImage.scale(scaleXY, scaleXY); + + } else { + // else load and crop the whole file + docuImage.loadImage(jobinfo.getFileToLoad()); + docuImage.crop((int) loadRect.getX(), (int) loadRect.getY(), + (int) loadRect.getWidth(), (int) loadRect.getHeight()); + + docuImage.scale(scaleXY, scaleXY); + } + + // mirror image + // operation mode: "hmir": mirror horizontally, "vmir": mirror + // vertically + if (jobinfo.hasOption("hmir")) { + docuImage.mirror(0); + } + if (jobinfo.hasOption("vmir")) { + docuImage.mirror(90); + } + + // rotate image + if (jobinfo.getAsFloat("rot") != 0d) { + docuImage.rotate(jobinfo.getAsFloat("rot")); + /* if (jobinfo.get_wholeRotArea()) { + // crop to the inner bounding box + float xcrop = (float) (docuImage.getWidth() - jobinfo.get_innerUserImgArea().getWidth() + * scaleXY); + float ycrop = (float) (docuImage.getHeight() - jobinfo.get_innerUserImgArea().getHeight() + * scaleXY); + if ((xcrop > 0) || (ycrop > 0)) { + // only crop smaller + xcrop = (xcrop > 0) ? xcrop : 0; + ycrop = (ycrop > 0) ? ycrop : 0; + // crop image + docuImage.crop((int) (xcrop / 2), (int) (ycrop / 2), + (int) (docuImage.getWidth() - xcrop), + (int) (docuImage.getHeight() - ycrop)); + } + } */ + + } + + // color modification + float[] paramRGBM = jobinfo.getRGBM(); + float[] paramRGBA = jobinfo.getRGBA(); + if ((paramRGBM != null) || (paramRGBA != null)) { + // make sure we actually have two arrays + if (paramRGBM == null) { + paramRGBM = new float[3]; + } + if (paramRGBA == null) { + paramRGBA = new float[3]; + } + // calculate "contrast" values (c=2^x) + float[] mult = new float[3]; + for (int i = 0; i < 3; i++) { + mult[i] = (float) Math.pow(2, (float) paramRGBM[i]); + } + docuImage.enhanceRGB(mult, paramRGBA); + } + + // contrast and brightness enhancement + float paramCONT = jobinfo.getAsFloat("cont"); + float paramBRGT = jobinfo.getAsFloat("brgt"); + if ((paramCONT != 0f) || (paramBRGT != 0f)) { + float mult = (float) Math.pow(2, paramCONT); + docuImage.enhance(mult, paramBRGT); + } + + logger.debug("rendered in " + (System.currentTimeMillis() - startTime) + "ms"); + + return docuImage; + } + +} diff -r 5cc180bb0a5c -r 0885f5ca5b24 servlet/src/digilib/io/DigilibInfoReader.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/servlet/src/digilib/io/DigilibInfoReader.java Thu Dec 16 21:19:11 2010 +0100 @@ -0,0 +1,76 @@ +package digilib.io; + +/** DigilibInfoReader + * A class for reading the information from info.xml files used in digilib image directories. + * + */ + +import java.io.File; +import java.util.List; + +import org.apache.log4j.Logger; +import org.jdom.Document; +import org.jdom.Element; +import org.jdom.input.SAXBuilder; + + + +public class DigilibInfoReader { + + /** gengeral logger for this class */ + protected static Logger logger = Logger.getLogger("digilib.servlet"); + + private String filename = null; + //private static String base_element = "info"; + + public DigilibInfoReader(String fn){ + filename = fn; + } + + /** + * Returns the attribute defined by 'attr' as a String. + * + * @param attr + * @return + */ + @SuppressWarnings("unchecked") // Element.getChildren() returns naked List + public String getAsString(String attr){ + try{ + SAXBuilder builder = new SAXBuilder(); + Document doc = builder.build(new File(filename)); + Element root = doc.getRootElement(); + List mainElements = root.getChildren(); + // logger.debug("XML mainElements:"+mainElements.toString()); + + for(int i=0; i { + /** the wrapped PDFStreamWorker */ + protected PDFStreamWorker streamWorker; + + /** the temporary output file */ + protected File tempFile; + + /** the final output file */ + protected File finalFile; + + /** Create new PDFFileWorker. + * @param dlConfig + * @param tempFile + * @param job_info + * @param imageJobCenter + * @throws FileNotFoundException + */ + public PDFFileWorker(DigilibConfiguration dlConfig, + File tempFile, File finalFile, + PDFRequest job_info, + DigilibJobCenter imageJobCenter) throws FileNotFoundException { + this.tempFile = tempFile; + OutputStream outstream = new FileOutputStream(tempFile); + this.finalFile = finalFile; + this.streamWorker = new PDFStreamWorker(dlConfig, outstream, job_info, imageJobCenter); + } + + @Override + public File call() throws Exception { + OutputStream outstream = streamWorker.call(); + outstream.flush(); + // move temporary to final file + tempFile.renameTo(finalFile); + return finalFile; + } + + +} diff -r 5cc180bb0a5c -r 0885f5ca5b24 servlet/src/digilib/pdf/PDFStreamWorker.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/servlet/src/digilib/pdf/PDFStreamWorker.java Thu Dec 16 21:19:11 2010 +0100 @@ -0,0 +1,162 @@ +package digilib.pdf; + +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; +import digilib.image.ImageJobDescription; +import digilib.image.ImageWorker; +import digilib.servlet.DigilibConfiguration; +import digilib.servlet.PDFRequest; +import digilib.util.DigilibJobCenter; +import digilib.util.NumRange; + +public class PDFStreamWorker implements Callable { + + protected static Logger logger = Logger.getLogger(PDFStreamWorker.class); + + protected DigilibConfiguration dlConfig = null; + + protected Document doc = null; + + protected OutputStream outstream = null; + + protected PDFRequest job_info = null; + + protected DigilibJobCenter imageJobCenter = null; + + /** + * @param dlConfig + * @param outputfile + * @param job_info + */ + public PDFStreamWorker(DigilibConfiguration dlConfig, OutputStream outputfile, + PDFRequest job_info, + DigilibJobCenter imageJobCenter) { + super(); + this.dlConfig = dlConfig; + this.outstream = outputfile; + this.job_info = job_info; + this.imageJobCenter = imageJobCenter; + } + + 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(); + + NumRange pgs = job_info.getPages(); + + for (int p : pgs) { + logger.debug(" - adding Image " + p + " to " + outstream); + // create ImageJobInformation + ImageJobDescription iji = ImageJobDescription.getInstance(job_info, job_info.getDlConfig()); + 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, ImageJobDescription iji) + throws InterruptedException, ExecutionException, IOException, + DocumentException { + // create image worker + ImageWorker job = new ImageWorker(dlConfig, iji); + // submit + Future jobTicket = imageJobCenter.submit(job); + // 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 scale this again? + pdfimg.scaleToFit(docW, docH); + // add to PDF + doc.add(pdfimg); + return doc; + } + +} diff -r 5cc180bb0a5c -r 0885f5ca5b24 servlet/src/digilib/pdf/PDFTitlePage.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/servlet/src/digilib/pdf/PDFTitlePage.java Thu Dec 16 21:19:11 2010 +0100 @@ -0,0 +1,184 @@ +package digilib.pdf; + +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URL; + +import org.apache.log4j.Logger; + +import com.itextpdf.text.Anchor; +import com.itextpdf.text.BadElementException; +import com.itextpdf.text.Chunk; +import com.itextpdf.text.Element; +import com.itextpdf.text.FontFactory; +import com.itextpdf.text.Image; +import com.itextpdf.text.Paragraph; + + +import digilib.io.DigilibInfoReader; +import digilib.io.DocuDirCache; +import digilib.servlet.PDFCache; +import digilib.servlet.PDFRequest; + +/** A class for the generation of title pages for the generated pdf documents. + * + * + */ +public class PDFTitlePage { + + private PDFRequest job_info = null; + private DigilibInfoReader info_reader= null; + private DocuDirCache dirCache = null; + protected static Logger logger = Logger.getLogger("digilib.servlet"); + + + /** + * Initialize a TitlePage + * @param pdfji + */ + public PDFTitlePage(PDFRequest pdfji){ + job_info = pdfji; + dirCache = (DocuDirCache) job_info.getDlConfig().getValue("servlet.dir.cache"); + + String fn = getBase(dirCache.getDirectory(pdfji.getImageJobInformation().getAsString("fn")).getDir().getPath()) + "presentation/info.xml"; + + info_reader = new DigilibInfoReader(fn); + } + + /** + * generate iText-PDF-Contents for the title page + * + * @return + */ + public Element getPageContents(){ + Paragraph content = new Paragraph(); + content.setAlignment(Element.ALIGN_CENTER); + + // add vertical whitespace + for(int i=0; i<8; i++){ + content.add(Chunk.NEWLINE); + } + + + // add logo + content.add(getLogo()); + content.add(Chunk.NEWLINE); + content.add(Chunk.NEWLINE); + + // add title + Anchor title = new Anchor(new Paragraph(getTitle(),FontFactory.getFont(FontFactory.HELVETICA,16))); + String burl = job_info.getImageJobInformation().getAsString("base.url"); + + title.setReference(burl+"digilib.jsp?fn="+job_info.getImageJobInformation().getAsString("fn")); + content.add(title); + content.add(Chunk.NEWLINE); + + // add author + if(getDate()!=" ") + content.add(new Paragraph(getAuthor()+" ("+getDate()+")",FontFactory.getFont(FontFactory.HELVETICA,14))); + else + content.add(new Paragraph(getAuthor(),FontFactory.getFont(FontFactory.HELVETICA,14))); + + content.add(Chunk.NEWLINE); + + // add page numbers + content.add(new Paragraph(getPages(), FontFactory.getFont(FontFactory.HELVETICA, 12))); + + + content.add(Chunk.NEWLINE); + content.add(Chunk.NEWLINE); + content.add(Chunk.NEWLINE); + + // add credits + content.add(new Paragraph("MPIWG Berlin 2009", FontFactory.getFont(FontFactory.HELVETICA,10))); + + // add digilib version + content.add(new Paragraph(getDigilibVersion(),FontFactory.getFont(FontFactory.HELVETICA,10))); + + for(int i=0; i<8; i++){ + content.add(Chunk.NEWLINE); + } + Anchor address = new Anchor( + new Paragraph(burl+"digilib.jsp?fn="+job_info.getImageJobInformation().getAsString("fn"), FontFactory.getFont(FontFactory.COURIER, 9)) + ); + address.setReference(burl+"digilib.jsp?fn="+job_info.getImageJobInformation().getAsString("fn")); + + content.add(address); + + + return content; + } + + /** + * return base directory of an image directory + * + * @param path + * @return + */ + private String getBase(String path){ + if(path.contains("/")){ + String[] x = path.split("/"); + String newpath = ""; + for(int i=0; i mainElements = root.getChildren(); - // logger.debug("XML mainElements:"+mainElements.toString()); - - for(int i=0; i { - /** general logger for this class */ - private static Logger logger = Logger.getLogger("digilib.jobcenter"); - /** ExecutorService */ - private ExecutorService executor; - /** max number of running threads */ - private int maxThreads = 1; - /** max number of waiting threads */ - private int maxQueueLen = 50; - - /** - * @param maxThreads - * @param maxQueueLength - */ - public DigilibJobCenter(int maxThreads, int maxQueueLen, boolean prestart) { - super(); - this.maxThreads = maxThreads; - this.maxQueueLen = maxQueueLen; - executor = Executors.newFixedThreadPool(maxThreads); - if (prestart) { - // prestart threads so Tomcat's leak protection doesn't complain - int st = ((ThreadPoolExecutor)executor).prestartAllCoreThreads(); - logger.debug("prestarting threads: "+st); - } - } - - /** Submit job to execute - * - * @param job - * @return Future to control the job - */ - public Future submit(Callable job) { - return executor.submit(job); - } - - /** Returns if the service is not overloaded. - * - * @return - */ - public boolean canRun() { - int jql = getWaitingJobs(); - int jrl = getRunningJobs(); - logger.debug("canRun: waiting jobs="+jql+" running jobs="+jrl); - return (jql <= maxQueueLen); - } - - /** Returns if the service is overloaded. - * - * @return - */ - public boolean isBusy() { - int jql = getWaitingJobs(); - int jrl = getRunningJobs(); - logger.debug("isBusy: waiting jobs="+jql+" running jobs="+jrl); - return (jql > maxQueueLen); - } - - public int getRunningJobs() { - return ((ThreadPoolExecutor)executor).getActiveCount(); - } - - public int getWaitingJobs() { - BlockingQueue jq = ((ThreadPoolExecutor)executor).getQueue(); - int jql = jq.size(); - return jql; - } - - public void setMaxThreads(int maxThreads) { - this.maxThreads = maxThreads; - } - - public int getMaxThreads() { - return maxThreads; - } - - public void setMaxQueueLen(int maxQueueLen) { - this.maxQueueLen = maxQueueLen; - } - - public int getMaxQueueLen() { - return maxQueueLen; - } - - public List shutdownNow() { - return executor.shutdownNow(); - } - -} diff -r 5cc180bb0a5c -r 0885f5ca5b24 servlet/src/digilib/servlet/DigilibPDFWorker.java --- a/servlet/src/digilib/servlet/DigilibPDFWorker.java Thu Dec 16 17:02:34 2010 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,214 +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.io.File; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; - -import com.itextpdf.text.BadElementException; -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; -import digilib.image.ImageOpException; -import digilib.io.FileOpException; - -/** - * Worker for pdf generation. - * - * @author cmielack - * - */ -public class DigilibPDFWorker extends DigilibWorker1 { - - private DigilibConfiguration dlConfig = null; - - private Document doc = null; - - private File outputfile = null; - - private PDFJobDescription job_info = null; - - public DigilibPDFWorker(DigilibConfiguration dlConfig, PDFJobDescription pdfji, File outputfile) { - super(); - // TODO dlConfig - this.dlConfig = dlConfig; - this.job_info = pdfji; - this.outputfile = outputfile; - } - - public void run() { - // create document object - doc = new Document(PageSize.A4, 0,0,0,0); - PdfWriter docwriter = null; - FileOutputStream fos; - - try { - fos = new FileOutputStream(outputfile); - } catch (FileNotFoundException e1) { - // TODO Auto-generated catch block - logger.error(e1.getMessage()); - e1.printStackTrace(); - return; - } - - long start_time = System.currentTimeMillis(); - - try { - docwriter = PdfWriter.getInstance(doc, fos); - - setPDFProperties(); - - doc.open(); - - addTitlePage(); - - logger.debug("- "+outputfile+" 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(Integer p: pgs){ - logger.debug(" - adding Image "+p+" to " + outputfile); - addImage(p); - logger.debug(" - done adding Image "+p+" to " + outputfile); - } - - logger.debug(" - done adding all Images to " + outputfile); - - } catch(Exception e) { - logger.error(e.getMessage()); - error = e; - return; - } finally { - if (doc!=null){ - doc.close(); - logger.debug("- "+outputfile+" doc.close() ("+(System.currentTimeMillis()-start_time) + "ms)"); - } - if (docwriter!=null){ - docwriter.close(); - } - } - - try { - fos.flush(); - } catch (IOException e) { - logger.error(e.getMessage()); - e.printStackTrace(); - error = e; - } finally{ - if(fos!=null){ - try { - fos.close(); - } catch (IOException e) { - logger.error(e.getMessage()); - e.printStackTrace(); - } - } - } - } - - /** - * Set PDF-Meta-Attributes. - */ - public void setPDFProperties(){ - // 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()); - } - - /** - * Create a title page and append it to the document (should, of course, be called first) - * @throws DocumentException - */ - public void addTitlePage() throws DocumentException{ - PDFTitlePage titlepage = new PDFTitlePage(job_info); - doc.add(titlepage.getPageContents()); - doc.newPage(); - } - - /** - * add the image with page number 'pn' to the document. - * - * @param pn - */ - public void addImage(int pn) { - // create ImageJobInformation - ImageJobDescription iji = job_info.getImageJobInformation(); - iji.setValue("pn", pn); - // create image worker - /* FIXME: DigilibImageWorker1 image_worker = new DigilibImageWorker1(dlConfig, null, iji); - try { - DocuImage img = image_worker.render(); - - 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(); - - pdfimg.scaleToFit(docW,docH); - - doc.add(pdfimg); - - } catch (FileOpException e) { - logger.error(e.getMessage()); - e.printStackTrace(); - } catch (IOException e) { - logger.error(e.getMessage()); - e.printStackTrace(); - } catch (ImageOpException e) { - logger.error(e.getMessage()); - e.printStackTrace(); - } catch (BadElementException e) { - logger.error(e.getMessage()); - e.printStackTrace(); - } catch (DocumentException e) { - logger.error(e.getMessage()); - e.printStackTrace(); - } - */ - } - - - - - - @Override - public DocuImage render() throws Exception { - return null; - } - - @Override - public void write(DocuImage img) throws Exception { - - } - -} \ No newline at end of file diff -r 5cc180bb0a5c -r 0885f5ca5b24 servlet/src/digilib/servlet/DigilibRequest.java --- a/servlet/src/digilib/servlet/DigilibRequest.java Thu Dec 16 17:02:34 2010 +0100 +++ b/servlet/src/digilib/servlet/DigilibRequest.java Thu Dec 16 21:19:11 2010 +0100 @@ -36,6 +36,9 @@ import digilib.image.DocuImage; import digilib.io.FileOps; +import digilib.util.OptionsSet; +import digilib.util.Parameter; +import digilib.util.ParameterMap; /** * Class holding the parameters of a digilib user request. The parameters are @@ -69,6 +72,18 @@ super(30); } + /** + * Creates a new instance of DigilibRequest with parameters from a + * ServletRequest. All undefined parameters are set to default values. + * + * @param request + */ + public DigilibRequest(ServletRequest request) { + super(30); + setWithRequest(request); + initOptions(); + } + /** set up parameters. * */ @@ -157,16 +172,13 @@ newParameter("mk", "", null, 'c'); } - /** - * Creates a new instance of DigilibRequest with parameters from a - * ServletRequest. All undefined parameters are set to default values. - * - * @param request - */ - public DigilibRequest(ServletRequest request) { - super(30); - setWithRequest(request); - } + /* (non-Javadoc) + * @see digilib.servlet.ParameterMap#initOptions() + */ + @Override + protected void initOptions() { + options = (OptionsSet) getValue("mo"); + } /** * Populate the request object with data from a ServletRequest. diff -r 5cc180bb0a5c -r 0885f5ca5b24 servlet/src/digilib/servlet/DigilibWorker1.java --- a/servlet/src/digilib/servlet/DigilibWorker1.java Thu Dec 16 17:02:34 2010 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,195 +0,0 @@ -/* DigilibWorker.java -- image operation worker - * - * 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 18.10.2004 - */ -package digilib.servlet; - -import java.util.concurrent.Semaphore; - -import org.apache.log4j.Logger; - -import digilib.image.DocuImage; - -/** - * image operation worker. - * - * @author casties - */ -public abstract class DigilibWorker1 { - - protected static Logger logger = Logger.getLogger(DigilibWorker1.class); - - private static int maxRunningThreads = 0; - - private static int runningThreads = 0; - - private static int waitingThreads = 0; - - private static int maxWaitingThreads = 0; - - public static Semaphore sem = new Semaphore(2, true); - - protected Throwable error; - - /** - * @param job - */ - public DigilibWorker1() { - super(); - error = null; - } - - public abstract DocuImage render() throws Exception; - - public abstract void write(DocuImage img) throws Exception; - - /** - * Do the work. - */ - public void run() { - logger.debug((++waitingThreads) + " waiting threads"); - DocuImage 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 = 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); - } - } - } - - /** - * Returns the name of this thread. - * - * @return - */ - public String getName() { - return Thread.currentThread().getName(); - } - - /** Returns if the worker could run (i.e. is not overloaded). - * - * @return - */ - public static boolean canRun() { - return ((DigilibWorker1.maxWaitingThreads == 0) || (DigilibWorker1.getNumWaiting() <= DigilibWorker1.maxWaitingThreads)); - } - - /** - * returns if an error occurred. - * - * @return - */ - public boolean hasError() { - return (error != null); - } - - /** - * @return Returns the error. - */ - public Throwable getError() { - return error; - } - - /** - * @return Returns the semaphore. - */ - public static Semaphore getSemaphore() { - return sem; - } - - /** - * @param sem - * The semaphore to set. - */ - public static void setSemaphore(Semaphore sem) { - DigilibWorker1.sem = sem; - } - - public static void setSemaphore(int maxrun, boolean fair) { - sem = new Semaphore(maxrun, fair); - maxRunningThreads = maxrun; - } - - /** - * The number of currently running threads (approximate). - * - * @return - */ - public static int getNumRunning() { - return (maxRunningThreads - sem.availablePermits()); - } - - /** - * The number of currently waiting threads (approximate). - * - * @return - */ - public static int getNumWaiting() { - return sem.getQueueLength(); - } - - /** - * @return Returns the maxWaitingThreads. - */ - public static int getMaxWaitingThreads() { - return maxWaitingThreads; - } - - /** - * @param maxWaitingThreads The maxWaitingThreads to set. - */ - public static void setMaxWaitingThreads(int maxWaitingThreads) { - DigilibWorker1.maxWaitingThreads = maxWaitingThreads; - } - - public static int getMaxRunningThreads() { - return maxRunningThreads; - } - - public static void setMaxRunningThreads(int maxRunningThreads) { - DigilibWorker1.maxRunningThreads = maxRunningThreads; - } -} diff -r 5cc180bb0a5c -r 0885f5ca5b24 servlet/src/digilib/servlet/ImageJobDescription.java --- a/servlet/src/digilib/servlet/ImageJobDescription.java Thu Dec 16 17:02:34 2010 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,502 +0,0 @@ -package digilib.servlet; - -import java.awt.geom.AffineTransform; -import java.awt.geom.Rectangle2D; -import java.io.IOException; - -import org.apache.log4j.Logger; - -import digilib.image.ImageOpException; -import digilib.image.ImageOps; -import digilib.image.ImageSize; -import digilib.io.DocuDirCache; -import digilib.io.DocuDirectory; -import digilib.io.FileOpException; -import digilib.io.FileOps; -import digilib.io.ImageFile; -import digilib.io.ImageFileset; - - -/** - * A container class for storing a set of instructional parameters - * used for content generating classes like MakePDF. - * - * This contains the functionality formerly found in Scaler, processRequest, only factorized. - * - * TODO clean up... - * - * @author cmielack, casties - * - */ - -public class ImageJobDescription extends ParameterMap { - - DigilibConfiguration dlConfig = null; - protected static Logger logger = Logger.getLogger("digilib.servlet"); - - ImageFile fileToLoad = null; - ImageFileset fileset = null; - DocuDirectory fileDir = null; - String filePath = null; - ImageSize expectedSourceSize = null; - Float scaleXY = null; - Rectangle2D userImgArea = null; - Rectangle2D outerUserImgArea= null; - Boolean imageSendable = null; - String mimeType; - Integer paramDW; - Integer paramDH; - - /** create empty ImageJobDescription. - * @param dlcfg - */ - public ImageJobDescription(DigilibConfiguration dlcfg) { - super(30); - dlConfig = dlcfg; - } - - - /** set up Parameters - * @see digilib.servlet.ParameterMap#initParams() - */ - @Override - protected void initParams() { - // url of the page/document (second part) - newParameter("fn", "", null, 's'); - // page number - newParameter("pn", new Integer(1), null, 's'); - // width of client in pixels - newParameter("dw", new Integer(0), null, 's'); - // height of client in pixels - newParameter("dh", new Integer(0), null, 's'); - // left edge of image (float from 0 to 1) - newParameter("wx", new Float(0), null, 's'); - // top edge in image (float from 0 to 1) - newParameter("wy", new Float(0), null, 's'); - // width of image (float from 0 to 1) - newParameter("ww", new Float(1), null, 's'); - // height of image (float from 0 to 1) - newParameter("wh", new Float(1), null, 's'); - // scale factor - newParameter("ws", new Float(1), null, 's'); - // special options like 'fit' for gifs - newParameter("mo", this.options, null, 's'); - // rotation angle (degree) - newParameter("rot", new Float(0), null, 's'); - // contrast enhancement factor - newParameter("cont", new Float(0), null, 's'); - // brightness enhancement factor - newParameter("brgt", new Float(0), null, 's'); - // color multiplicative factors - newParameter("rgbm", "0/0/0", null, 's'); - // color additive factors - newParameter("rgba", "0/0/0", null, 's'); - // display dpi resolution (total) - newParameter("ddpi", new Float(0), null, 's'); - // display dpi X resolution - newParameter("ddpix", new Float(0), null, 's'); - // display dpi Y resolution - newParameter("ddpiy", new Float(0), null, 's'); - // scale factor for mo=ascale - newParameter("scale", new Float(1), null, 's'); - } - - - /* (non-Javadoc) - * @see digilib.servlet.ParameterMap#initOptions() - */ - @Override - protected void initOptions() { - if (options == null) { - String s = this.getAsString("mo"); - options = new OptionsSet(s); - } - } - - - /** Creates new ImageJobDescription by merging Parameters from another ParameterMap. - * @param pm - * @param dlcfg - * @return - */ - public static ImageJobDescription setFrom(ParameterMap pm, DigilibConfiguration dlcfg) { - ImageJobDescription newMap = new ImageJobDescription(dlcfg); - // add all params to this map - newMap.params.putAll(pm.params); - newMap.initOptions(); - return newMap; - } - - - public String getMimeType() throws IOException { - if (mimeType == null) { - fileToLoad = getFileToLoad(); - if(! fileToLoad.isChecked()){ - ImageOps.checkFile(fileToLoad); - } - mimeType = fileToLoad.getMimetype(); - } - return mimeType; - } - - public ImageFile getFileToLoad() throws IOException { - - if(fileToLoad == null){ - fileset = getFileset(); - - /* select a resolution */ - if (getHiresOnly()) { - // get first element (= highest resolution) - fileToLoad = fileset.getBiggest(); - } else if (getLoresOnly()) { - // enforced lores uses next smaller resolution - fileToLoad = fileset.getNextSmaller(getExpectedSourceSize()); - if (fileToLoad == null) { - // this is the smallest we have - fileToLoad = fileset.getSmallest(); - } - } else { - // autores: use next higher resolution - fileToLoad = fileset.getNextBigger(getExpectedSourceSize()); - if (fileToLoad == null) { - // this is the highest we have - fileToLoad = fileset.getBiggest(); - } - } - logger.info("Planning to load: " + fileToLoad.getFile()); - } - - return fileToLoad; - - } - - public DocuDirectory getFileDirectory() throws FileOpException{ - if(fileDir == null){ - DocuDirCache dirCache = (DocuDirCache) dlConfig.getValue("servlet.dir.cache"); - String fp = getFilePath(); - fileDir = dirCache.getDirectory(fp); - if (fileDir == null) { - throw new FileOpException("Directory " + getFilePath() + " not found."); - } - } - return fileDir; - } - - public ImageFileset getFileset() throws FileOpException{ - if(fileset==null){ - DocuDirCache dirCache = (DocuDirCache) dlConfig.getValue("servlet.dir.cache"); - - fileset = (ImageFileset) dirCache.getFile(getFilePath(), getAsInt("pn"), FileOps.CLASS_IMAGE); - if (fileset == null) { - throw new FileOpException("File " + getFilePath() + "(" - + getAsInt("pn") + ") not found."); - } - } - return fileset; - } - - public String getFilePath() { - if(filePath == null){ - String s = this.getAsString("request.path"); - s += this.getAsString("fn"); - filePath = FileOps.normalName(s); - } - return filePath; - } - - public boolean getHiresOnly(){ - return hasOption("clip") || hasOption("hires"); - } - - public boolean getLoresOnly(){ - return hasOption("lores"); - } - - public boolean getScaleToFit() { - return !(hasOption("clip") || hasOption("osize") || hasOption("ascale")); - } - - public boolean getAbsoluteScale(){ - return hasOption("osize") || hasOption("ascale"); - } - - - public ImageSize getExpectedSourceSize() throws IOException { - if (expectedSourceSize == null){ - expectedSourceSize = new ImageSize(); - if (getScaleToFit()) { - // scale to fit -- calculate minimum source size - float scale = (1 / Math.min(getAsFloat("ww"), getAsFloat("wh"))) * getAsFloat("ws"); - expectedSourceSize.setSize((int) (getDw() * scale), - (int) (getDh() * scale)); - } else if (getAbsoluteScale() && hasOption("ascale")) { - // absolute scale -- apply scale to hires size - expectedSourceSize = getHiresSize().getScaled(getAsFloat("scale")); - } else { - // clip to fit -- source = destination size - expectedSourceSize.setSize((int) (getDw() * getAsFloat("ws")), - (int) (getDh() * getAsFloat("ws"))); - } - } - return expectedSourceSize; - } - - public ImageSize getHiresSize() throws IOException { - logger.debug("get_hiresSize()"); - - ImageSize hiresSize = null; - ImageFileset fileset = getFileset(); - if (getAbsoluteScale()) { - ImageFile hiresFile = fileset.getBiggest(); - if (!hiresFile.isChecked()) { - ImageOps.checkFile(hiresFile); - } - hiresSize = hiresFile.getSize(); - } - return hiresSize; - - } - - /** Returns image scaling factor. - * Uses image size and user parameters. - * Modifies scaleXY, userImgArea. - * @return - * @throws IOException - * @throws ImageOpException - */ - public float getScaleXY() throws IOException, ImageOpException { - //logger.debug("get_scaleXY()"); - if(scaleXY == null){ - // coordinates and scaling - float areaWidth; - float areaHeight; - float ws = getAsFloat("ws"); - ImageSize imgSize = getFileToLoad().getSize(); - // user window area in [0,1] coordinates - Rectangle2D relUserArea = new Rectangle2D.Float(getAsFloat("wx"), getAsFloat("wy"), - getAsFloat("ww"), getAsFloat("wh")); - // transform from relative [0,1] to image coordinates. - AffineTransform imgTrafo = AffineTransform.getScaleInstance(imgSize - .getWidth(), imgSize.getHeight()); - // transform user coordinate area to image coordinate area - userImgArea = imgTrafo.createTransformedShape( - relUserArea).getBounds2D(); - - if (getScaleToFit()) { - // calculate scaling factors based on inner user area - areaWidth = (float) userImgArea.getWidth(); - areaHeight = (float) userImgArea.getHeight(); - float scaleX = getDw() / areaWidth * ws; - float scaleY = getDh() / areaHeight * ws; - scaleXY = (scaleX > scaleY) ? scaleY : scaleX; - } else if (getAbsoluteScale()) { - // absolute scaling factor - if (hasOption("osize")) { - // get original resolution from metadata - fileset.checkMeta(); - float origResX = fileset.getResX(); - float origResY = fileset.getResY(); - if ((origResX == 0) || (origResY == 0)) { - throw new ImageOpException("Missing image DPI information!"); - } - if ((getAsFloat("ddpix") == 0) || (getAsFloat("ddpiy") == 0)) { - throw new ImageOpException("Missing display DPI information!"); - } - // calculate absolute scale factor - float sx = getAsFloat("ddpix") / origResX; - float sy = getAsFloat("ddpiy") / origResY; - // currently only same scale -- mean value - scaleXY = (sx + sy) / 2f; - } else { - scaleXY = getAsFloat("scale"); - } - // we need to correct the factor if we use a pre-scaled image - ImageSize hiresSize = getHiresSize(); - if (imgSize.getWidth() != hiresSize.getWidth()) { - scaleXY *= (float)hiresSize.getWidth() / (float)imgSize.getWidth(); - } - areaWidth = getDw() / scaleXY * ws; - areaHeight = getDh() / scaleXY * ws; - // reset user area size - userImgArea.setRect(userImgArea.getX(), userImgArea.getY(), - areaWidth, areaHeight); - } else { - // crop to fit -- don't scale - areaWidth = getDw() * ws; - areaHeight = getDh() * ws; - // reset user area size - userImgArea.setRect(userImgArea.getX(), userImgArea.getY(), - areaWidth, areaHeight); - scaleXY = 1f; - } - } - return (float) scaleXY; - } - - public int getDw() throws IOException { - logger.debug("get_paramDW()"); - if (paramDW == null) { - - paramDW = getAsInt("dw"); - paramDH = getAsInt("dh"); - - float imgAspect = getFileToLoad().getAspect(); - if (paramDW == 0) { - // calculate dw - paramDW = Math.round(paramDH * imgAspect); - setValue("dw", paramDW); - } else if (paramDH == 0) { - // calculate dh - paramDH = Math.round(paramDW / imgAspect); - setValue("dh", paramDH); - } - } - return paramDW; - } - - public int getDh() throws IOException { - logger.debug("get_paramDH()"); - if (paramDH == null) { - - paramDW = getAsInt("dw"); - paramDH = getAsInt("dh"); - - float imgAspect = getFileToLoad().getAspect(); - if (paramDW == 0) { - // calculate dw - paramDW = Math.round(paramDH * imgAspect); - setValue("dw", paramDW); - } else if (paramDH == 0) { - // calculate dh - paramDH = Math.round(paramDW / imgAspect); - setValue("dh", paramDH); - } - } - return paramDH; - } - - public Integer get_scaleQual(){ - logger.debug("get_scaleQual()"); - Integer qual = dlConfig.getAsInt("default-quality"); - if(hasOption("q0")) - qual = 0; - else if(hasOption("q1")) - qual = 1; - else if(hasOption("q2")) - qual = 2; - return qual; - } - - - public Rectangle2D getUserImgArea() throws IOException, ImageOpException{ - if(userImgArea == null) { - // getScaleXY sets userImgArea - getScaleXY(); - } - return userImgArea; - - } - - public Rectangle2D getOuterUserImgArea() throws IOException, ImageOpException { - if(outerUserImgArea == null){ - outerUserImgArea = getUserImgArea(); - - // image size in pixels - ImageSize imgSize = getFileToLoad().getSize(); - Rectangle2D imgBounds = new Rectangle2D.Float(0, 0, imgSize.getWidth(), - imgSize.getHeight()); - - // clip area at the image border - outerUserImgArea = outerUserImgArea.createIntersection(imgBounds); - - // check image parameters sanity - scaleXY = getScaleXY(); - logger.debug("outerUserImgArea.getWidth()=" + outerUserImgArea.getWidth()); - logger.debug("get_scaleXY() * outerUserImgArea.getWidth() = " + (scaleXY * outerUserImgArea.getWidth())); - - 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!"); - } - } - return outerUserImgArea; - } - - - public int getForceType(){ - if(hasOption("jpg")) - return ImageOps.TYPE_JPEG; - if(hasOption("png")) - return ImageOps.TYPE_PNG; - - return ImageOps.TYPE_AUTO; - } - - public float[] getRGBM(){ - float[] paramRGBM = null;//{0f,0f,0f}; - Parameter p = params.get("rgbm"); - if (p.hasValue() && (!p.getAsString().equals("0/0/0"))) { - return p.parseAsFloatArray("/"); - } - return paramRGBM; - } - - public float[] getRGBA(){ - float[] paramRGBA = null;//{0f,0f,0f}; - Parameter p = params.get("rgba"); - if (p.hasValue() && (!p.getAsString().equals("0/0/0"))) { - paramRGBA = p.parseAsFloatArray("/"); - } - return paramRGBA; - } - - /** Has send-as-file been requested? - * @return - */ - public boolean getSendAsFile(){ - return hasOption("file") - || hasOption("rawfile"); - } - - /** Could the image be sent without processing? - * Takes image type and additional image operations into account. - * Does not check requested size transformation. - * @return - * @throws IOException - */ - public boolean isImageSendable() throws IOException { - // cached result? - if (imageSendable == null) { - String mimeType = getMimeType(); - imageSendable = ( (mimeType.equals("image/jpeg") - || mimeType.equals("image/png") - || mimeType.equals("image/gif") ) - && - !(hasOption("hmir") - || hasOption("vmir") - || (getAsFloat("rot") != 0.0) - || (getRGBM() != null) - || (getRGBA() != null) - || (getAsFloat("cont") != 0.0) - || (getAsFloat("brgt") != 0.0))); - } - - return imageSendable; - } - - - public boolean isTransformRequired() throws IOException { - ImageSize is = getFileToLoad().getSize(); - ImageSize ess = getExpectedSourceSize(); - // nt = no transform required - boolean nt = isImageSendable() && ( - // lores: send if smaller - (getLoresOnly() && is.isSmallerThan(ess)) - // else send if it fits - || (!(getLoresOnly() || getHiresOnly()) && is.fitsIn(ess))); - return ! nt; - } -} \ No newline at end of file diff -r 5cc180bb0a5c -r 0885f5ca5b24 servlet/src/digilib/servlet/ImageWorker.java --- a/servlet/src/digilib/servlet/ImageWorker.java Thu Dec 16 17:02:34 2010 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,155 +0,0 @@ -/** Worker (Callable) that renders an image. - * - */ -package digilib.servlet; - -import java.awt.Rectangle; -import java.io.IOException; -import java.util.concurrent.Callable; - -import org.apache.log4j.Logger; - -import digilib.image.DocuImage; -import digilib.image.ImageOpException; -import digilib.io.FileOpException; - -/** Worker that renders an image. - * - * @author casties - * - */ -public class ImageWorker implements Callable { - - - protected static Logger logger = Logger.getLogger(ImageWorker.class); - private DigilibConfiguration dlConfig; - private ImageJobDescription jobinfo; - - public ImageWorker(DigilibConfiguration dlConfig, ImageJobDescription jobinfo) { - super(); - this.dlConfig = dlConfig; - this.jobinfo = jobinfo; - } - - /** - * render and return the image - */ - @Override - public DocuImage call() throws FileOpException, IOException, ImageOpException { - - logger.debug("image worker starting"); - long startTime = System.currentTimeMillis(); - - /* crop and scale image */ - - // new DocuImage instance - DocuImage docuImage = dlConfig.getDocuImageInstance(); - if (docuImage == null) { - throw new ImageOpException("Unable to load DocuImage class!"); - } - - // set interpolation quality - docuImage.setQuality(jobinfo.get_scaleQual()); - - Rectangle loadRect = jobinfo.getOuterUserImgArea().getBounds(); - float scaleXY = jobinfo.getScaleXY(); - - // use subimage loading if possible - if (docuImage.isSubimageSupported()) { - logger.debug("Subimage: scale " + scaleXY + " = " + (1 / scaleXY)); - float subf = 1f; - float subsamp = 1f; - if (scaleXY < 1) { - subf = 1 / scaleXY; - // for higher quality reduce subsample factor by minSubsample - if (jobinfo.get_scaleQual() > 0) { - subsamp = (float) Math.max(Math.floor(subf / dlConfig.getAsFloat("subsample-minimum")), 1d); - } else { - subsamp = (float) Math.floor(subf); - } - scaleXY = subsamp / subf; - logger.debug("Using subsampling: " + subsamp + " rest " - + scaleXY); - } - - docuImage.loadSubimage(jobinfo.getFileToLoad(), loadRect, (int) subsamp); - - logger.debug("SUBSAMP: " + subsamp + " -> " + docuImage.getWidth() - + "x" + docuImage.getHeight()); - - docuImage.scale(scaleXY, scaleXY); - - } else { - // else load and crop the whole file - docuImage.loadImage(jobinfo.getFileToLoad()); - docuImage.crop((int) loadRect.getX(), (int) loadRect.getY(), - (int) loadRect.getWidth(), (int) loadRect.getHeight()); - - docuImage.scale(scaleXY, scaleXY); - } - - // mirror image - // operation mode: "hmir": mirror horizontally, "vmir": mirror - // vertically - if (jobinfo.hasOption("hmir")) { - docuImage.mirror(0); - } - if (jobinfo.hasOption("vmir")) { - docuImage.mirror(90); - } - - // rotate image - if (jobinfo.getAsFloat("rot") != 0d) { - docuImage.rotate(jobinfo.getAsFloat("rot")); - /* if (jobinfo.get_wholeRotArea()) { - // crop to the inner bounding box - float xcrop = (float) (docuImage.getWidth() - jobinfo.get_innerUserImgArea().getWidth() - * scaleXY); - float ycrop = (float) (docuImage.getHeight() - jobinfo.get_innerUserImgArea().getHeight() - * scaleXY); - if ((xcrop > 0) || (ycrop > 0)) { - // only crop smaller - xcrop = (xcrop > 0) ? xcrop : 0; - ycrop = (ycrop > 0) ? ycrop : 0; - // crop image - docuImage.crop((int) (xcrop / 2), (int) (ycrop / 2), - (int) (docuImage.getWidth() - xcrop), - (int) (docuImage.getHeight() - ycrop)); - } - } */ - - } - - // color modification - float[] paramRGBM = jobinfo.getRGBM(); - float[] paramRGBA = jobinfo.getRGBA(); - if ((paramRGBM != null) || (paramRGBA != null)) { - // make sure we actually have two arrays - if (paramRGBM == null) { - paramRGBM = new float[3]; - } - if (paramRGBA == null) { - paramRGBA = new float[3]; - } - // calculate "contrast" values (c=2^x) - float[] mult = new float[3]; - for (int i = 0; i < 3; i++) { - mult[i] = (float) Math.pow(2, (float) paramRGBM[i]); - } - docuImage.enhanceRGB(mult, paramRGBA); - } - - // contrast and brightness enhancement - float paramCONT = jobinfo.getAsFloat("cont"); - float paramBRGT = jobinfo.getAsFloat("brgt"); - if ((paramCONT != 0f) || (paramBRGT != 0f)) { - float mult = (float) Math.pow(2, paramCONT); - docuImage.enhance(mult, paramBRGT); - } - - logger.debug("rendered in " + (System.currentTimeMillis() - startTime) + "ms"); - - return docuImage; - } - -} diff -r 5cc180bb0a5c -r 0885f5ca5b24 servlet/src/digilib/servlet/Initialiser.java --- a/servlet/src/digilib/servlet/Initialiser.java Thu Dec 16 17:02:34 2010 +0100 +++ b/servlet/src/digilib/servlet/Initialiser.java Thu Dec 16 21:19:11 2010 +0100 @@ -39,6 +39,7 @@ import digilib.io.AliasingDocuDirCache; import digilib.io.DocuDirCache; import digilib.io.FileOps; +import digilib.util.DigilibJobCenter; /** * Singleton initalisation servlet for setup tasks and resources. diff -r 5cc180bb0a5c -r 0885f5ca5b24 servlet/src/digilib/servlet/NumRange.java --- a/servlet/src/digilib/servlet/NumRange.java Thu Dec 16 17:02:34 2010 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,175 +0,0 @@ -/** - * - */ -package digilib.servlet; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; - -/** - * @author casties - * - */ -public class NumRange implements Iterable { - - private Integer start = 1; - private Integer end = Integer.MAX_VALUE; - private List list = null; - private Integer maxnum = null; - - /** - * @param start - * @param end - */ - public NumRange(Integer start, Integer end) { - this.start = start; - this.end = end; - } - - /** - * @param range - */ - public NumRange(String range) { - parseString(range); - } - - /** - * @param range - */ - public NumRange(String range, Integer max) { - this.maxnum = max; - parseString(range); - } - - - public void parseString(String pages) { - - ArrayList pgs = new ArrayList(); - - String intervals[] = pages.split(","); - - // convert the page-interval-strings into a list containing every single - // page - for (String interval : intervals) { - if (interval.contains("-")) { - String nums[] = interval.split("-"); - int start = Integer.valueOf(nums[0]); - if (nums.length > 1) { - // second number is end of range - int end = Integer.valueOf(nums[1]); - if (intervals.length == 1) { - // optimized case of just one interval - this.start = start; - this.end = end; - this.list = null; - return; - } - for (int i = start; i <= end; i++) { - // add all numbers to list - pgs.add(i); - } - } else { - // second number missing: range to infinity - pgs.add(start); - pgs.add(Integer.MAX_VALUE); - } - } else { - // single number - pgs.add(Integer.valueOf(interval)); - } - } - if (intervals.length > 1) { - Collections.sort(pgs); - } - list = pgs; - } - - public int getStart() { - if (list == null) { - return start; - } else { - return list.get(0); - } - } - - public int getEnd() { - Integer last; - if (list == null) { - last = end; - } else { - last = list.get(list.size() - 1); - } - if (maxnum == null) { - return last; - } else { - return Math.min(last, maxnum); - } - } - - public Iterator iterator() { - if (list == null) { - // return count-based iterator - return new Iterator() { - // anonymous inner Iterator class - private int num = getStart(); - private int end = getEnd(); - - public boolean hasNext() { - return (num <= end); - } - - public Integer next() { - return num++; - } - - public void remove() { - // don't do this - } - }; - } else { - // return list-based iterator - return new Iterator() { - // anonymous inner Iterator class - private int listidx = 0; - private int listend = list.size(); - private int num = getStart(); - private int end = getEnd(); - - public boolean hasNext() { - return (num <= end); - } - - public Integer next() { - if (listidx < listend - 1) { - num = list.get(listidx++); - return num; - } else if (listidx == listend - 1) { - // last element in list - int n = list.get(listidx++); - if (n == Integer.MAX_VALUE) { - // open end -- continue - num++; - return num++; - } else { - num = n; - return num++; - } - } else { - return num++; - } - } - - public void remove() { - // don't do this - } - }; - } - } - - public void setMaxnum(Integer maxnum) { - this.maxnum = maxnum; - } - -} diff -r 5cc180bb0a5c -r 0885f5ca5b24 servlet/src/digilib/servlet/OptionsSet.java --- a/servlet/src/digilib/servlet/OptionsSet.java Thu Dec 16 17:02:34 2010 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,67 +0,0 @@ -/** - * - */ -package digilib.servlet; - -import java.util.HashSet; -import java.util.StringTokenizer; - -/** - * @author casties - * - */ -@SuppressWarnings("serial") -public class OptionsSet extends HashSet { - - protected String optionSep = ","; - - public OptionsSet() { - super(); - } - - /** Constructor with String of options. - * @param s - */ - public OptionsSet(String s) { - super(); - parseString(s); - } - - /** Adds all options from String to Set. - * @param s - */ - public void parseString(String s) { - if (s != null) { - StringTokenizer i = new StringTokenizer(s, optionSep); - while (i.hasMoreTokens()) { - String opt = i.nextToken(); - this.add(opt); - } - } - } - - public boolean hasOption(String opt) { - return this.contains(opt); - } - - public String toString() { - StringBuffer b = new StringBuffer(); - for (String s: this) { - if (b.length() > 0) { - b.append(optionSep); - } - b.append(s); - } - return b.toString(); - } - - - public String getOptionSep() { - return optionSep; - } - - public void setOptionSep(String optionSep) { - this.optionSep = optionSep; - } - -} diff -r 5cc180bb0a5c -r 0885f5ca5b24 servlet/src/digilib/servlet/PDFCache.java --- a/servlet/src/digilib/servlet/PDFCache.java Thu Dec 16 17:02:34 2010 +0100 +++ b/servlet/src/digilib/servlet/PDFCache.java Thu Dec 16 21:19:11 2010 +0100 @@ -4,9 +4,7 @@ import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; -import java.io.FileOutputStream; import java.io.IOException; -import java.io.OutputStream; import java.util.concurrent.Future; import javax.servlet.RequestDispatcher; @@ -14,10 +12,15 @@ 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 digilib.image.DocuImage; +import digilib.pdf.PDFFileWorker; +import digilib.util.DigilibJobCenter; /** * A class for handling user requests for pdf documents from digilib images. @@ -30,7 +33,18 @@ */ @SuppressWarnings("serial") -public class PDFCache extends RequestHandler { +public class PDFCache extends HttpServlet { + + public static String version = "0.3a"; + + /** logger for accounting requests */ + protected static Logger accountlog = Logger.getLogger("account.pdf.request"); + + /** gengeral logger for this class */ + protected static Logger logger = Logger.getLogger("digilib.pdfcache"); + + /** logger for authentication related */ + protected static Logger authlog = Logger.getLogger("digilib.pdf.auth"); private DigilibConfiguration dlConfig = null; @@ -56,7 +70,6 @@ public static Integer STATUS_ERROR = 3; // an error occurred while processing the request - public static String version = "0.3a"; // TODO ? functionality for the pre-generation of complete books/chapters using default values @@ -82,12 +95,13 @@ if (!temp_directory.exists()) { // try to create temp_directory.mkdirs(); + } else { + // rid the temporary directory of possible incomplete document files + emptyDirectory(temp_directory); } if (!temp_directory.isDirectory()) { throw new ServletException("Configuration error: problem with pdf-temp-dir="+temp_fn); } - // rid the temporary directory of possible incomplete document files - emptyDirectory(temp_directory); String cache_fn = dlConfig.getAsString("pdf-cache-dir"); cache_directory = new File(cache_fn); @@ -107,12 +121,28 @@ } + /* (non-Javadoc) + * @see javax.servlet.http.HttpServlet#doGet(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) + */ + public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException { + accountlog.info("GET from " + request.getRemoteAddr()); + this.processRequest(request, response); + } + + + /* (non-Javadoc) + * @see javax.servlet.http.HttpServlet#doPost(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) + */ + public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException { + accountlog.info("POST from " + request.getRemoteAddr()); + this.processRequest(request, response); + } + /** * clean up any broken and unfinished files from the temporary directory. */ - public void emptyDirectory(File temp_dir){ - File[] temp_files = temp_dir.listFiles(); - + public void emptyDirectory(File dir){ + File[] temp_files = dir.listFiles(); for (File f: temp_files){ f.delete(); } @@ -120,12 +150,17 @@ public void processRequest(HttpServletRequest request, - HttpServletResponse response) { + HttpServletResponse response) throws ServletException { - String docid = ""; + if (dlConfig == null) { + logger.error("ERROR: No Configuration!"); + throw new ServletException("NO VALID digilib CONFIGURATION!"); + } + + String docid = ""; try { // evaluate request ( make a PDFJobDeclaration , get the DocumentId) - PDFJobDescription pdfji = new PDFJobDescription(request, dlConfig); + PDFRequest pdfji = new PDFRequest(request, dlConfig); docid = pdfji.getDocumentId(); @@ -150,7 +185,8 @@ } else if (status == STATUS_DONE) { // pdf created -- send it try { - sendFile(docid, getDownloadFilename(pdfji), response); + ServletOps.sendFile(getCacheFile(docid), "application/pdf", getDownloadFilename(pdfji), response); + //sendFile(docid, getDownloadFilename(pdfji), response); } catch (IOException e) { // sending didn't work logger.error(e.getMessage()); @@ -233,7 +269,7 @@ * @return * @throws FileNotFoundException */ - public Future createNewPdfDocument(PDFJobDescription pdfji, String filename) throws FileNotFoundException{ + public Future createNewPdfDocument(PDFRequest pdfji, String filename) throws FileNotFoundException{ // start new worker File tempf = this.getTempFile(filename); File finalf = this.getCacheFile(filename); @@ -250,7 +286,7 @@ * @param pdfji * @return */ - public String getDownloadFilename(PDFJobDescription pdfji){ + public String getDownloadFilename(PDFRequest pdfji){ // filename example: digilib_example_pgs1-3.pdf String filename; filename = "digilib_"; diff -r 5cc180bb0a5c -r 0885f5ca5b24 servlet/src/digilib/servlet/PDFFileWorker.java --- a/servlet/src/digilib/servlet/PDFFileWorker.java Thu Dec 16 17:02:34 2010 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,54 +0,0 @@ -/** - * - */ -package digilib.servlet; - -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.OutputStream; -import java.util.concurrent.Callable; - -import digilib.image.DocuImage; - -/** - * @author casties - * - */ -public class PDFFileWorker implements Callable { - /** the wrapped PDFStreamWorker */ - protected PDFStreamWorker streamWorker; - - /** the temporary output file */ - protected File tempFile; - - /** the final output file */ - protected File finalFile; - - /** Create new PDFFileWorker. - * @param dlConfig - * @param tempFile - * @param job_info - * @param imageJobCenter - * @throws FileNotFoundException - */ - public PDFFileWorker(DigilibConfiguration dlConfig, - File tempFile, File finalFile, - PDFJobDescription job_info, - DigilibJobCenter imageJobCenter) throws FileNotFoundException { - OutputStream outstream = new FileOutputStream(tempFile); - this.finalFile = finalFile; - this.streamWorker = new PDFStreamWorker(dlConfig, outstream, job_info, imageJobCenter); - } - - @Override - public File call() throws Exception { - OutputStream outstream = streamWorker.call(); - outstream.flush(); - // move temporary to final file - tempFile.renameTo(finalFile); - return finalFile; - } - - -} diff -r 5cc180bb0a5c -r 0885f5ca5b24 servlet/src/digilib/servlet/PDFJobDescription.java --- a/servlet/src/digilib/servlet/PDFJobDescription.java Thu Dec 16 17:02:34 2010 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,142 +0,0 @@ -package digilib.servlet; - -import java.io.UnsupportedEncodingException; -import java.net.URLEncoder; - -import javax.servlet.http.HttpServletRequest; - -import org.apache.log4j.Logger; - -import digilib.io.DocuDirectory; -import digilib.io.FileOpException; -import digilib.io.FileOps; - - -/** - * A container class for storing a set of instruction parameters - * used for content generator classes like MakePDF. - * - * - * @author cmielack, casties - * - */ -public class PDFJobDescription extends ParameterMap { - - DigilibConfiguration dlConfig = null; - NumRange pages = null; - /** general logger for this class */ - protected static Logger logger = Logger.getLogger("digilib.servlet"); - - - /** - * Initialize the PDFJobInformation - * - * @param dlcfg - * The DigilibConfiguration. - */ - public PDFJobDescription(DigilibConfiguration dlcfg) { - super(30); - dlConfig = dlcfg; - } - - /** - * Initialize the PDFJobInformation with a request. - * - * @param dlcfg The DigilibConfiguration. - * @param request - * @throws FileOpException - */ - public PDFJobDescription(HttpServletRequest request, DigilibConfiguration dlcfg) throws FileOpException { - super(30); - dlConfig = dlcfg; - this.setWithRequest(request); - } - - - protected void initParams() { - // page numbers - newParameter("pgs", "", null, 's'); - // url of the page/document (second part) - newParameter("fn", "", null, 's'); - // width of client in pixels - newParameter("dw", new Integer(0), null, 's'); - // height of client in pixels - newParameter("dh", new Integer(500), null, 's'); - } - - /** - * Read the request object. - * - * @param request - * @throws FileOpException - */ - public void setWithRequest(HttpServletRequest request) throws FileOpException { - // read matching request parameters for the parameters in this map - for (String k : params.keySet()) { - if (request.getParameterMap().containsKey(k)) { - setValueFromString(k, request.getParameter(k)); - } - } - // process parameters - pages = new NumRange(getAsString("pgs")); - ImageJobDescription ij = ImageJobDescription.setFrom(this, dlConfig); - DocuDirectory dir = ij.getFileDirectory(); - int dirsize = dir.size(FileOps.CLASS_IMAGE); - pages.setMaxnum(dirsize); - } - - - /** - * Generate a filename for the pdf to be created. - * - * @return - */ - public String getDocumentId(){ - String id; - - // TODO use complete request information for id generation - - String fn = getAsString("fn"); - String dh = getAsString("dh"); - String dw = getAsString("dw"); - String pgs = getAsString("pgs"); - - id = "fn=" + fn + "&dw=" + dw + "&dh=" + dh + "&pgs=" + pgs + ".pdf"; - // make safe to use as filename by urlencoding - try { - id = URLEncoder.encode(id, "UTF-8"); - } catch (UnsupportedEncodingException e) { - // this shouldn't happen - } - return id; - } - - - public ImageJobDescription getImageJobInformation(){ - return ImageJobDescription.setFrom(this, dlConfig); - } - - - public NumRange getPages() { - return pages; - } - - - /** - * Check parameters for validity. - * Returns true if no errors are found. - * - * @return - */ - public boolean checkValidity(){ - if (pages != null) { - return true; - } - return false; - } - - public DigilibConfiguration getDlConfig(){ - return dlConfig; - } - -} \ No newline at end of file diff -r 5cc180bb0a5c -r 0885f5ca5b24 servlet/src/digilib/servlet/PDFMaker.java --- a/servlet/src/digilib/servlet/PDFMaker.java Thu Dec 16 17:02:34 2010 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,74 +0,0 @@ -package digilib.servlet; - -import java.io.File; - -import javax.servlet.ServletContext; -import javax.servlet.http.HttpServlet; - -import org.apache.log4j.Logger; - - - - -/** - * A Runnable that creates the PDFWorker and moves completed files from a temporary location - * (defined in PDFCache) to the cache directory. - * - * @author cmielack - * - */ -@SuppressWarnings("serial") -public class PDFMaker extends HttpServlet implements Runnable { - - public static String version = "0.1"; - - private PDFJobDescription job_info = null; - private String filename = null; - private DigilibConfiguration dlConfig = null; - private ServletContext context = null; - - /** gengeral logger for this class */ - protected static Logger logger = Logger.getLogger("digilib.PDFMaker"); - - - - public PDFMaker(ServletContext context, PDFJobDescription pdfji, String filename){ - this.job_info = pdfji; - this.filename = filename; - this.dlConfig = pdfji.getDlConfig(); - this.context = context; - } - - public void run() { - - if (! DigilibWorker1.canRun()) { - // TODO include the logger - logger.error("Servlet overloaded!"); - return; - } - - PDFCache pdfcache = (PDFCache) context.getAttribute(PDFCache.instanceKey); - - File tempfile = pdfcache.getTempFile(filename); - // create PDFWorker - DigilibPDFWorker pdf_worker = new DigilibPDFWorker(dlConfig, job_info, tempfile); - - // run PDFWorker - pdf_worker.run(); - - if(pdf_worker.hasError()){ - // raise error, write to logger - logger.error(pdf_worker.getError().getMessage()); - tempfile.delete(); - return; - } - else{ // move the completed file to the cache directory - boolean success = tempfile.renameTo(pdfcache.getCacheFile(filename)); - if(!success){ - // TODO raise error - } - } - - } - -} diff -r 5cc180bb0a5c -r 0885f5ca5b24 servlet/src/digilib/servlet/PDFRequest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/servlet/src/digilib/servlet/PDFRequest.java Thu Dec 16 21:19:11 2010 +0100 @@ -0,0 +1,150 @@ +package digilib.servlet; + +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; + +import javax.servlet.http.HttpServletRequest; + +import org.apache.log4j.Logger; + +import digilib.image.ImageJobDescription; +import digilib.io.DocuDirectory; +import digilib.io.FileOpException; +import digilib.io.FileOps; +import digilib.util.NumRange; +import digilib.util.OptionsSet; +import digilib.util.ParameterMap; + + +/** + * A container class for storing a set of instruction parameters + * used for content generator classes like MakePDF. + * + * + * @author cmielack, casties + * + */ +public class PDFRequest extends ParameterMap { + + DigilibConfiguration dlConfig = null; + NumRange pages = null; + /** general logger for this class */ + protected static Logger logger = Logger.getLogger("digilib.servlet"); + + + /** + * Initialize the PDFJobInformation + * + * @param dlcfg + * The DigilibConfiguration. + */ + public PDFRequest(DigilibConfiguration dlcfg) { + super(30); + dlConfig = dlcfg; + } + + /** + * Initialize the PDFJobInformation with a request. + * + * @param dlcfg The DigilibConfiguration. + * @param request + * @throws FileOpException + */ + public PDFRequest(HttpServletRequest request, DigilibConfiguration dlcfg) throws FileOpException { + super(30); + dlConfig = dlcfg; + this.setWithRequest(request); + } + + + protected void initParams() { + // page numbers + newParameter("pgs", "", null, 's'); + // url of the page/document (second part) + newParameter("fn", "", null, 's'); + // width of client in pixels + newParameter("dw", new Integer(0), null, 's'); + // height of client in pixels + newParameter("dh", new Integer(500), null, 's'); + } + + /* (non-Javadoc) + * @see digilib.servlet.ParameterMap#initOptions() + */ + @Override + protected void initOptions() { + options = (OptionsSet) getValue("mo"); + } + + /** + * Read the request object. + * + * @param request + * @throws FileOpException + */ + public void setWithRequest(HttpServletRequest request) throws FileOpException { + // read matching request parameters for the parameters in this map + for (String k : params.keySet()) { + if (request.getParameterMap().containsKey(k)) { + setValueFromString(k, request.getParameter(k)); + } + } + // process parameters + pages = new NumRange(getAsString("pgs")); + ImageJobDescription ij = ImageJobDescription.getInstance(this, dlConfig); + DocuDirectory dir = ij.getFileDirectory(); + int dirsize = dir.size(FileOps.CLASS_IMAGE); + pages.setMaxnum(dirsize); + } + + + /** + * Generate a filename for the pdf to be created. + * + * @return + */ + public String getDocumentId(){ + String fn = getAsString("fn"); + String dh = getAsString("dh"); + String dw = getAsString("dw"); + String pgs = getAsString("pgs"); + + String id = "fn=" + fn + "&dw=" + dw + "&dh=" + dh + "&pgs=" + pgs + ".pdf"; + // make safe to use as filename by urlencoding + try { + id = URLEncoder.encode(id, "UTF-8"); + } catch (UnsupportedEncodingException e) { + // this shouldn't happen + } + return id; + } + + + public ImageJobDescription getImageJobInformation(){ + return ImageJobDescription.getInstance(this, dlConfig); + } + + + public NumRange getPages() { + return pages; + } + + + /** + * Check parameters for validity. + * Returns true if no errors are found. + * + * @return + */ + public boolean checkValidity(){ + if (pages != null) { + return true; + } + return false; + } + + public DigilibConfiguration getDlConfig(){ + return dlConfig; + } + +} \ No newline at end of file diff -r 5cc180bb0a5c -r 0885f5ca5b24 servlet/src/digilib/servlet/PDFStreamWorker.java --- a/servlet/src/digilib/servlet/PDFStreamWorker.java Thu Dec 16 17:02:34 2010 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,156 +0,0 @@ -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 { - - protected static Logger logger = Logger.getLogger(PDFStreamWorker.class); - - protected DigilibConfiguration dlConfig = null; - - protected Document doc = null; - - protected OutputStream outstream = null; - - protected PDFJobDescription job_info = null; - - protected DigilibJobCenter imageJobCenter = null; - - /** - * @param dlConfig - * @param outputfile - * @param job_info - */ - public PDFStreamWorker(DigilibConfiguration dlConfig, OutputStream outputfile, - PDFJobDescription job_info, - DigilibJobCenter imageJobCenter) { - super(); - this.dlConfig = dlConfig; - this.outstream = outputfile; - this.job_info = job_info; - this.imageJobCenter = imageJobCenter; - } - - 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(); - - NumRange pgs = job_info.getPages(); - - for (int p : pgs) { - logger.debug(" - adding Image " + p + " to " + outstream); - // create ImageJobInformation - ImageJobDescription iji = ImageJobDescription.setFrom(job_info, job_info.dlConfig); - 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, ImageJobDescription iji) - throws InterruptedException, ExecutionException, IOException, - DocumentException { - // create image worker - ImageWorker job = new ImageWorker(dlConfig, iji); - // submit - Future jobTicket = imageJobCenter.submit(job); - // 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 scale this again? - pdfimg.scaleToFit(docW, docH); - // add to PDF - doc.add(pdfimg); - return doc; - } - -} diff -r 5cc180bb0a5c -r 0885f5ca5b24 servlet/src/digilib/servlet/PDFTitlePage.java --- a/servlet/src/digilib/servlet/PDFTitlePage.java Thu Dec 16 17:02:34 2010 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,181 +0,0 @@ -package digilib.servlet; - -import java.io.IOException; -import java.net.MalformedURLException; -import java.net.URL; - -import org.apache.log4j.Logger; - -import com.itextpdf.text.Anchor; -import com.itextpdf.text.BadElementException; -import com.itextpdf.text.Chunk; -import com.itextpdf.text.Element; -import com.itextpdf.text.FontFactory; -import com.itextpdf.text.Image; -import com.itextpdf.text.Paragraph; - - -import digilib.io.DocuDirCache; - -/** A class for the generation of title pages for the generated pdf documents. - * - * - */ -public class PDFTitlePage { - - private PDFJobDescription job_info = null; - private DigilibInfoReader info_reader= null; - private DocuDirCache dirCache = null; - protected static Logger logger = Logger.getLogger("digilib.servlet"); - - - /** - * Initialize a TitlePage - * @param pdfji - */ - public PDFTitlePage(PDFJobDescription pdfji){ - job_info = pdfji; - dirCache = (DocuDirCache) job_info.getDlConfig().getValue("servlet.dir.cache"); - - String fn = getBase(dirCache.getDirectory(pdfji.getImageJobInformation().getAsString("fn")).getDir().getPath()) + "presentation/info.xml"; - - info_reader = new DigilibInfoReader(fn); - } - - /** - * generate iText-PDF-Contents for the title page - * - * @return - */ - public Element getPageContents(){ - Paragraph content = new Paragraph(); - content.setAlignment(Element.ALIGN_CENTER); - - // add vertical whitespace - for(int i=0; i<8; i++){ - content.add(Chunk.NEWLINE); - } - - - // add logo - content.add(getLogo()); - content.add(Chunk.NEWLINE); - content.add(Chunk.NEWLINE); - - // add title - Anchor title = new Anchor(new Paragraph(getTitle(),FontFactory.getFont(FontFactory.HELVETICA,16))); - String burl = job_info.getImageJobInformation().getAsString("base.url"); - - title.setReference(burl+"digilib.jsp?fn="+job_info.getImageJobInformation().getAsString("fn")); - content.add(title); - content.add(Chunk.NEWLINE); - - // add author - if(getDate()!=" ") - content.add(new Paragraph(getAuthor()+" ("+getDate()+")",FontFactory.getFont(FontFactory.HELVETICA,14))); - else - content.add(new Paragraph(getAuthor(),FontFactory.getFont(FontFactory.HELVETICA,14))); - - content.add(Chunk.NEWLINE); - - // add page numbers - content.add(new Paragraph(getPages(), FontFactory.getFont(FontFactory.HELVETICA, 12))); - - - content.add(Chunk.NEWLINE); - content.add(Chunk.NEWLINE); - content.add(Chunk.NEWLINE); - - // add credits - content.add(new Paragraph("MPIWG Berlin 2009", FontFactory.getFont(FontFactory.HELVETICA,10))); - - // add digilib version - content.add(new Paragraph(getDigilibVersion(),FontFactory.getFont(FontFactory.HELVETICA,10))); - - for(int i=0; i<8; i++){ - content.add(Chunk.NEWLINE); - } - Anchor address = new Anchor( - new Paragraph(burl+"digilib.jsp?fn="+job_info.getImageJobInformation().getAsString("fn"), FontFactory.getFont(FontFactory.COURIER, 9)) - ); - address.setReference(burl+"digilib.jsp?fn="+job_info.getImageJobInformation().getAsString("fn")); - - content.add(address); - - - return content; - } - - /** - * return base directory of an image directory - * - * @param path - * @return - */ - private String getBase(String path){ - if(path.contains("/")){ - String[] x = path.split("/"); - String newpath = ""; - for(int i=0; i c = defval.getClass(); - // take String as is - if (c == String.class) { - this.value = val; - return true; - } - // set File - if (c == File.class) { - this.value = new File(val); - return true; - } - // set Options - if (c == OptionsSet.class) { - this.value = new OptionsSet(val); - return true; - } - // set Boolean if string == "true" - if (c == Boolean.class) { - this.value = new Boolean(val.compareToIgnoreCase("true") == 0); - return true; - } - try { - // set Integer - if (c == Integer.class) { - this.value = new Integer(Integer.parseInt(val)); - return true; - } - // set Float - if (c == Float.class) { - this.value = new Float(Float.parseFloat(val)); - return true; - } - } catch (NumberFormatException e) { - } - // then it's unknown - return false; - } - - /** - * Get the default as Object. - * - * @return - */ - public Object getDefault() { - return defval; - } - - /** - * Set the default. - * - * @param defval - */ - public void setDefault(Object defval) { - this.defval = defval; - } - - /** - * Get the value as Object. - * - * Returns the default if the value is not set. - * - * @return - */ - public Object getValue() { - return (value != null) ? value : defval; - } - - public int getAsInt() { - Integer i = (Integer) getValue(); - return (i != null) ? i.intValue() : 0; - } - - public float getAsFloat() { - Float f = (Float) getValue(); - return (f != null) ? f.floatValue() : 0f; - } - - public String getAsString() { - Object s = getValue(); - if (s == null) { - return ""; - } - if (s.getClass() == File.class) { - try { - return ((File) s).getCanonicalPath(); - } catch (IOException e) { - return "ERR: " + s.toString(); - } - } - return s.toString(); - } - - public boolean getAsBoolean() { - Boolean b = (Boolean) getValue(); - return (b != null) ? b.booleanValue() : false; - } - - public String[] parseAsArray(String separator) { - String s = getAsString(); - String[] sa = s.split(separator); - return sa; - } - - public float[] parseAsFloatArray(String separator) { - String s = getAsString(); - String[] sa = s.split(separator); - float[] fa = null; - try { - int n = sa.length; - fa = new float[n]; - for (int i = 0; i < n; i++) { - float f = Float.parseFloat(sa[i]); - fa[i] = f; - } - } catch (Exception e) { - } - - return fa; - } - - /** - * Set the value. - * - * @param value - */ - public void setValue(Object value) { - this.value = value; - } - - /** - * Set the value. - * - * @param value - */ - public void setValue(int value) { - this.value = new Integer(value); - } - - /** - * Set the value. - * - * @param value - */ - public void setValue(float value) { - this.value = new Float(value); - } - - /** - * @return - */ - public String getName() { - return name; - } - - /** - * @param name - */ - public void setName(String name) { - this.name = name; - } - - /** - * @return - */ - public int getType() { - return type; - } - - /** - * @param type - */ - public void setType(int type) { - this.type = type; - } - -} diff -r 5cc180bb0a5c -r 0885f5ca5b24 servlet/src/digilib/servlet/ParameterMap.java --- a/servlet/src/digilib/servlet/ParameterMap.java Thu Dec 16 17:02:34 2010 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,323 +0,0 @@ -/* ParameterMap.java -- HashMap of Parameters. - - Digital Image Library servlet components - - Copyright (C) 2003 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 02.09.2003 by casties - * - */ -package digilib.servlet; - -import java.util.HashMap; -import java.util.Map.Entry; - -/** HashMap of digilib.servlet.Parameter's. - * - * Keys are Strings. Values are Parameters. - * - * @author casties - * - */ -public class ParameterMap { - - protected HashMap params; - - protected OptionsSet options; - - /** Default constructor. - * - */ - public ParameterMap() { - params = new HashMap(); - options = new OptionsSet(); - initParams(); - } - - /** Constructor with initial size. - * @param size - */ - public ParameterMap(int size) { - params = new HashMap(size); - options = new OptionsSet(); - initParams(); - } - - /** Shallow copy constructor. - * Be warned that the maps are only cloned i.e. keys and values are shared! - * @param pm - */ - @SuppressWarnings("unchecked") - public static ParameterMap cloneFrom(ParameterMap pm) { - ParameterMap newPm = new ParameterMap(); - // clone params to this map - newPm.params = (HashMap) pm.params.clone(); - newPm.options = (OptionsSet) pm.options.clone(); - return newPm; - } - - - /** Creates new ParameterMap by merging Parameters from another ParameterMap. - * @param pm - * @return - */ - public static ParameterMap setFrom(ParameterMap pm) { - ParameterMap newPm = new ParameterMap(); - // add all params to this map - newPm.params.putAll(pm.params); - newPm.initOptions(); - return newPm; - - } - - /** set up parameters - * - */ - protected void initParams() { - // no default parameters - } - - /** set up options - * - */ - protected void initOptions() { - // no default options - } - - /** Get the Parameter with the corresponding key. - * - * Returns null if no element is associated with key. - * - * @param key - * @return - */ - public Parameter get(String key) { - return params.get(key); - } - - /** Get the Parameter with the corresponding key. - * - * Returns null if no element is associated with key. - * - * @param key - * @return - */ - public Object getValue(String key) { - Parameter p = params.get(key); - return (p != null) ? p.getValue() : null; - } - - /** Get the Parameter with the corresponding key. - * - * Returns null if no element is associated with key. - * - * @param key - * @return - */ - public String getAsString(String key) { - Parameter p = params.get(key); - return (p != null) ? p.getAsString() : ""; - } - - /** Get the Parameter with the corresponding key. - * - * Returns null if no element is associated with key. - * - * @param key - * @return - */ - public int getAsInt(String key) { - Parameter p = params.get(key); - return (p != null) ? p.getAsInt() : 0; - } - - /** Get the Parameter with the corresponding key. - * - * Returns null if no element is associated with key. - * - * @param key - * @return - */ - public float getAsFloat(String key) { - Parameter p = params.get(key); - return (p != null) ? p.getAsFloat() : 0f; - } - - /** Get the Parameter with the corresponding key. - * - * Returns null if no element is associated with key. - * - * @param key - * @return - */ - public boolean getAsBoolean(String key) { - Parameter p = params.get(key); - return (p != null) ? p.getAsBoolean() : false; - } - - /** Returns if the Parameter's value has been set. - * - * @param key - * @return - */ - public boolean hasValue(String key) { - Parameter p = params.get(key); - return (p != null) ? p.hasValue() : false; - } - - /** Add the Parameter to the map with a certain key. - * - * Returns the value that was previously associated with key. - * - * @param key - * @param val - * @return - */ - public Parameter put(String key, Parameter val) { - return params.put(key, val); - } - - /** Add the Parameter val to the map, using val's name. - * - * Returns the value that was previously associated with val's name. - * - * @param val - * @return - */ - public Parameter put(Parameter val) { - return params.put(val.getName(), val); - } - - /** Add a new Parameter with name, default and value. - * - * Returns the key that was previously associated with name. - * - * @param name - * @param def - * @param val - * @return - */ - public Parameter newParameter(String name, Object def, Object val) { - Parameter p = new Parameter(name, def, val); - return params.put(name, p); - } - - /** Add a new Parameter with name, default, value and type. - * - * Returns the key that was previously associated with name. - * - * @param name - * @param def - * @param val - * @param type - * @return - */ - public Parameter newParameter(String name, Object def, Object val, int type) { - Parameter p = new Parameter(name, def, val, type); - return params.put(name, p); - } - - /** Set the value of an existing parameter. - * - * Sets the value and returns true if the parameter exists. - * - * @param key - * @param val - * @return - */ - public boolean setValue(String key, Object val) { - Parameter p = params.get(key); - if (p != null) { - p.setValue(val); - return true; - } - return false; - } - - /** Set the value of an existing parameter. - * - * Sets the value and returns true if the parameter exists. - * - * @param key - * @param val - * @return - */ - public boolean setValue(String key, int val) { - Parameter p = params.get(key); - if (p != null) { - p.setValue(val); - return true; - } - return false; - } - - /** Set the value of an existing parameter. - * - * Sets the value and returns true if the parameter exists. - * - * @param key - * @param val - * @return - */ - public boolean setValue(String key, float val) { - Parameter p = params.get(key); - if (p != null) { - p.setValue(val); - return true; - } - return false; - } - - /** Set the value of an existing parameter. - * - * Sets the value and returns true if the parameter exists. - * - * @param key - * @param val - * @return - */ - public boolean setValueFromString(String key, String val) { - Parameter p = params.get(key); - if (p != null) { - p.setValueFromString(val); - return true; - } - return false; - } - - /** Returns of the option has been set. - * @param opt - * @return - */ - public boolean hasOption(String opt) { - return options.hasOption(opt); - } - - public HashMap getParams() { - return params; - } - - public void setParams(HashMap params) { - this.params = params; - } - - public OptionsSet getOptions() { - return options; - } - - public void setOptions(OptionsSet options) { - this.options = options; - } -} diff -r 5cc180bb0a5c -r 0885f5ca5b24 servlet/src/digilib/servlet/RequestHandler.java --- a/servlet/src/digilib/servlet/RequestHandler.java Thu Dec 16 17:02:34 2010 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,82 +0,0 @@ -package digilib.servlet; - -import javax.servlet.ServletConfig; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.apache.log4j.Logger; - -import digilib.image.ImageOpException; - -public abstract class RequestHandler extends HttpServlet { - - /** logger for accounting requests */ - protected static Logger accountlog = Logger.getLogger("account.request"); - - /** gengeral logger for this class */ - protected static Logger logger = Logger.getLogger("digilib.servlet"); - - /** logger for authentication related */ - protected static Logger authlog = Logger.getLogger("digilib.auth"); - - - public void init(ServletConfig config) throws ServletException{ - try { - super.init(config); - } catch (ServletException e) { - e.printStackTrace(); - logger.error(e.getMessage()); - } - - - - } - - - public void doGet(HttpServletRequest request, HttpServletResponse response){ - accountlog.info("GET from " + request.getRemoteAddr()); - - try { - this.processRequest(request, response); - } catch (ServletException e) { - e.printStackTrace(); - logger.error(e.getMessage()); - } catch (ImageOpException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } - - - public void doPost(HttpServletRequest request, HttpServletResponse response){ - accountlog.info("POST from " + request.getRemoteAddr()); - - try { - this.processRequest(request, response); - } catch (ServletException e) { - e.printStackTrace(); - logger.error(e.getMessage()); - } catch (ImageOpException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } - - /** - * processRequest - * - * evaluate request (,generate content), send content to user - * @throws ServletException - * @throws ImageOpException - * - * */ - abstract public void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, ImageOpException; - - - /** send the requested content to the response */ - // abstract public void sendFile(File f, HttpServletResponse response, String filename); - - -} diff -r 5cc180bb0a5c -r 0885f5ca5b24 servlet/src/digilib/servlet/Scaler.java --- a/servlet/src/digilib/servlet/Scaler.java Thu Dec 16 17:02:34 2010 +0100 +++ b/servlet/src/digilib/servlet/Scaler.java Thu Dec 16 21:19:11 2010 +0100 @@ -9,23 +9,26 @@ import javax.servlet.ServletConfig; import javax.servlet.ServletContext; import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import org.apache.log4j.Logger; + import digilib.auth.AuthOpException; import digilib.auth.AuthOps; import digilib.image.DocuImage; -import digilib.image.ImageOpException; +import digilib.image.ImageJobDescription; +import digilib.image.ImageWorker; import digilib.io.DocuDirCache; import digilib.io.DocuDirectory; import digilib.io.DocuDirent; import digilib.io.FileOps; import digilib.io.ImageFile; - -// TODO digilibError is not used anymore and may need to get reintegrated +import digilib.util.DigilibJobCenter; @SuppressWarnings("serial") -public class Scaler extends RequestHandler { +public class Scaler extends HttpServlet { /** digilib servlet version (for all components) */ public static final String dlVersion = "1.9.0a"; @@ -42,6 +45,15 @@ /** error code for image operation error */ public static final int ERROR_IMAGE = 3; + /** logger for accounting requests */ + protected static Logger accountlog = Logger.getLogger("account.request"); + + /** gengeral logger for this class */ + protected static Logger logger = Logger.getLogger("digilib.servlet"); + + /** logger for authentication related */ + protected static Logger authlog = Logger.getLogger("digilib.auth"); + /** DocuDirCache instance */ DocuDirCache dirCache; @@ -115,7 +127,7 @@ sendFileAllowed = dlConfig.getAsBoolean("sendfile-allowed"); } - /** Returns modification time relevant to the request. + /** Returns modification time relevant to the request for caching. * * @see javax.servlet.http.HttpServlet#getLastModified(javax.servlet.http.HttpServletRequest) */ @@ -136,13 +148,35 @@ return mtime; } + /* (non-Javadoc) + * @see javax.servlet.http.HttpServlet#doGet(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) + */ + public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException { + accountlog.info("GET from " + request.getRemoteAddr()); + this.processRequest(request, response); + } + + /* (non-Javadoc) + * @see javax.servlet.http.HttpServlet#doPost(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) + */ + public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException { + accountlog.info("POST from " + request.getRemoteAddr()); + this.processRequest(request, response); + } + + + /** Service this request using the response. + * @param request + * @param response + * @throws ServletException + */ public void processRequest(HttpServletRequest request, - HttpServletResponse response) throws ServletException, - ImageOpException { + HttpServletResponse response) throws ServletException { if (dlConfig == null) { - throw new ServletException("ERROR: No Configuration!"); + logger.error("ERROR: No Configuration!"); + throw new ServletException("NO VALID digilib CONFIGURATION!"); } accountlog.debug("request: " + request.getQueryString()); @@ -152,9 +186,8 @@ // parse request DigilibRequest dlRequest = new DigilibRequest(request); // extract the job information - ImageJobDescription jobTicket = ImageJobDescription.setFrom(dlRequest, dlConfig); + ImageJobDescription jobTicket = ImageJobDescription.getInstance(dlRequest, dlConfig); - ImageWorker job = null; try { /* * check if we can fast-track without scaling @@ -184,7 +217,7 @@ mt = "application/octet-stream"; } logger.debug("Sending RAW File as is."); - ServletOps.sendFile(fileToLoad.getFile(), mt, response); + ServletOps.sendFile(fileToLoad.getFile(), mt, null, response); logger.info("Done in " + (System.currentTimeMillis() - startTime) + "ms"); return; } @@ -192,7 +225,7 @@ // if possible, send the image without actually having to transform it if (! jobTicket.isTransformRequired()) { logger.debug("Sending File as is."); - ServletOps.sendFile(fileToLoad.getFile(), null, response); + ServletOps.sendFile(fileToLoad.getFile(), null, null, response); logger.info("Done in " + (System.currentTimeMillis() - startTime) + "ms"); return; } @@ -204,7 +237,7 @@ return; } // create job - job = new ImageWorker(dlConfig, jobTicket); + ImageWorker job = new ImageWorker(dlConfig, jobTicket); // submit job Future jobResult = imageJobCenter.submit(job); // wait for result @@ -216,15 +249,17 @@ } catch (IOException e) { logger.error(e.getClass() + ": " + e.getMessage()); - // response.sendError(1); + digilibError(dlRequest.hasOption("errtxt"), dlRequest.hasOption("errimg"), dlRequest.hasOption("errcode"), ERROR_FILE, null, response); } catch (AuthOpException e) { logger.error(e.getClass() + ": " + e.getMessage()); - // response.sendError(1); + digilibError(dlRequest.hasOption("errtxt"), dlRequest.hasOption("errimg"), dlRequest.hasOption("errcode"), ERROR_AUTH, null, response); } catch (InterruptedException e) { logger.error(e.getClass() + ": " + e.getMessage()); } catch (ExecutionException e) { logger.error(e.getClass() + ": " + e.getMessage()); - logger.error("caused by: " + e.getCause().getMessage()); + String causeMsg = e.getCause().getMessage(); + logger.error("caused by: " + causeMsg); + digilibError(dlRequest.hasOption("errtxt"), dlRequest.hasOption("errimg"), dlRequest.hasOption("errcode"), ERROR_IMAGE, causeMsg, response); } } @@ -232,35 +267,42 @@ /** * Sends an error to the client as text or image. * - * @param asHTML + * @param asText * @param type * @param msg * @param response */ - public void digilibError(boolean asHTML, int type, String msg, + public void digilibError(boolean asText, boolean asImage, boolean asCode, int type, String msg, HttpServletResponse response) { try { File img = null; + int status = 0; if (type == ERROR_AUTH) { if (msg == null) { msg = "ERROR: Unauthorized access!"; } img = denyImgFile; + status = HttpServletResponse.SC_FORBIDDEN; } else if (type == ERROR_FILE) { if (msg == null) { msg = "ERROR: Image file not found!"; } img = notfoundImgFile; + status = HttpServletResponse.SC_NOT_FOUND; } else { if (msg == null) { msg = "ERROR: Other image error!"; } img = this.errorImgFile; + status = HttpServletResponse.SC_BAD_REQUEST; } - if (asHTML && (img != null)) { + if (asText) { ServletOps.htmlMessage(msg, response); - } else { - ServletOps.sendFile(img, null, response); + } else if (asCode) { + response.sendError(status, msg); + } else if (img != null) { + // default: image + ServletOps.sendFile(img, null, null, response); } } catch (IOException e) { logger.error("Error sending error!", e); diff -r 5cc180bb0a5c -r 0885f5ca5b24 servlet/src/digilib/servlet/ServletOps.java --- a/servlet/src/digilib/servlet/ServletOps.java Thu Dec 16 17:02:34 2010 +0100 +++ b/servlet/src/digilib/servlet/ServletOps.java Thu Dec 16 21:19:11 2010 +0100 @@ -179,18 +179,20 @@ * The local file is copied to the OutputStream of the * ServletResponse. If mt is null then the mime-type is * auto-detected with mimeForFile. - * + * @param f + * Image file to be sent. * @param mt * mime-type of the file. - * @param f - * Image file to be sent. + * @param name + * name of the download file (for application/x) * @param res * ServletResponse where the image file will be sent. + * * @throws FileOpException * Exception is thrown for a IOException. * @throws IOException */ - public static void sendFile(File f, String mt, HttpServletResponse response) + public static void sendFile(File f, String mt, String name, HttpServletResponse response) throws FileOpException, IOException { logger.debug("sendRawFile(" + mt + ", " + f + ")"); if (mt == null) { @@ -202,12 +204,16 @@ } response.setContentType(mt); // open file - if (mt.equals("application/octet-stream")) { - response.addHeader("Content-Disposition", "attachment; filename=\"" - + f.getName() + "\""); + if (mt.startsWith("application")) { + if (name == null) { + // no download name -- use filename + name = f.getName(); + } + response.addHeader("Content-Disposition", "attachment; filename=\""+name+"\""); } FileInputStream inFile = new FileInputStream(f); OutputStream outStream = response.getOutputStream(); + response.setContentLength( (int) f.length()); byte dataBuffer[] = new byte[4096]; int len; while ((len = inFile.read(dataBuffer)) != -1) { @@ -215,8 +221,8 @@ outStream.write(dataBuffer, 0, len); outStream.flush(); } + response.flushBuffer(); inFile.close(); - response.flushBuffer(); } /** diff -r 5cc180bb0a5c -r 0885f5ca5b24 servlet/src/digilib/servlet/Texter.java --- a/servlet/src/digilib/servlet/Texter.java Thu Dec 16 17:02:34 2010 +0100 +++ b/servlet/src/digilib/servlet/Texter.java Thu Dec 16 21:19:11 2010 +0100 @@ -107,10 +107,6 @@ */ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { - // create new request with defaults - DigilibRequest dlReq = new DigilibRequest(request); - // add DigilibRequest to ServletRequest - request.setAttribute("digilib.servlet.request", dlReq); // do the processing processRequest(request, response); } @@ -123,10 +119,6 @@ */ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { - // create new request with defaults - DigilibRequest dlReq = new DigilibRequest(request); - // add DigilibRequest to ServletRequest - request.setAttribute("digilib.servlet.request", dlReq); // do the processing processRequest(request, response); } @@ -137,7 +129,8 @@ /* * request parameters */ - DigilibRequest dlRequest = (DigilibRequest) request.getAttribute("digilib.servlet.request"); + // create new request with defaults + DigilibRequest dlRequest = new DigilibRequest(request); try { /* @@ -145,11 +138,11 @@ */ TextFile f = getTextFile(dlRequest, "/txt"); if (f != null) { - ServletOps.sendFile(f.getFile(), null, response); + ServletOps.sendFile(f.getFile(), null, null, response); } else { f = getTextFile(dlRequest, ""); if (f != null) { - ServletOps.sendFile(f.getFile(), null, response); + ServletOps.sendFile(f.getFile(), null, null, response); } else { response.sendError(HttpServletResponse.SC_NOT_FOUND, "Text-File not found!"); //ServletOps.htmlMessage("No Text-File!", response); diff -r 5cc180bb0a5c -r 0885f5ca5b24 servlet/src/digilib/util/DigilibJobCenter.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/servlet/src/digilib/util/DigilibJobCenter.java Thu Dec 16 21:19:11 2010 +0100 @@ -0,0 +1,110 @@ +/** Wrapper around ExecutionService. + * + */ +package digilib.util; + +import java.util.List; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.concurrent.ThreadPoolExecutor; + +import org.apache.log4j.Logger; + +import digilib.image.DocuImage; + +/** Wrapper around ExecutionService. + * + * @author casties + * + */ +public class DigilibJobCenter { + /** general logger for this class */ + private static Logger logger = Logger.getLogger("digilib.jobcenter"); + /** ExecutorService */ + private ExecutorService executor; + /** max number of running threads */ + private int maxThreads = 1; + /** max number of waiting threads */ + private int maxQueueLen = 50; + + /** + * @param maxThreads + * @param maxQueueLength + */ + public DigilibJobCenter(int maxThreads, int maxQueueLen, boolean prestart) { + super(); + this.maxThreads = maxThreads; + this.maxQueueLen = maxQueueLen; + executor = Executors.newFixedThreadPool(maxThreads); + if (prestart) { + // prestart threads so Tomcat's leak protection doesn't complain + int st = ((ThreadPoolExecutor)executor).prestartAllCoreThreads(); + logger.debug("prestarting threads: "+st); + } + } + + /** Submit job to execute + * + * @param job + * @return Future to control the job + */ + public Future submit(Callable job) { + return executor.submit(job); + } + + /** Returns if the service is not overloaded. + * + * @return + */ + public boolean canRun() { + int jql = getWaitingJobs(); + int jrl = getRunningJobs(); + logger.debug("canRun: waiting jobs="+jql+" running jobs="+jrl); + return (jql <= maxQueueLen); + } + + /** Returns if the service is overloaded. + * + * @return + */ + public boolean isBusy() { + int jql = getWaitingJobs(); + int jrl = getRunningJobs(); + logger.debug("isBusy: waiting jobs="+jql+" running jobs="+jrl); + return (jql > maxQueueLen); + } + + public int getRunningJobs() { + return ((ThreadPoolExecutor)executor).getActiveCount(); + } + + public int getWaitingJobs() { + BlockingQueue jq = ((ThreadPoolExecutor)executor).getQueue(); + int jql = jq.size(); + return jql; + } + + public void setMaxThreads(int maxThreads) { + this.maxThreads = maxThreads; + } + + public int getMaxThreads() { + return maxThreads; + } + + public void setMaxQueueLen(int maxQueueLen) { + this.maxQueueLen = maxQueueLen; + } + + public int getMaxQueueLen() { + return maxQueueLen; + } + + public List shutdownNow() { + return executor.shutdownNow(); + } + +} diff -r 5cc180bb0a5c -r 0885f5ca5b24 servlet/src/digilib/util/NumRange.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/servlet/src/digilib/util/NumRange.java Thu Dec 16 21:19:11 2010 +0100 @@ -0,0 +1,175 @@ +/** + * + */ +package digilib.util; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; + +/** + * @author casties + * + */ +public class NumRange implements Iterable { + + private Integer start = 1; + private Integer end = Integer.MAX_VALUE; + private List list = null; + private Integer maxnum = null; + + /** + * @param start + * @param end + */ + public NumRange(Integer start, Integer end) { + this.start = start; + this.end = end; + } + + /** + * @param range + */ + public NumRange(String range) { + parseString(range); + } + + /** + * @param range + */ + public NumRange(String range, Integer max) { + this.maxnum = max; + parseString(range); + } + + + public void parseString(String pages) { + + ArrayList pgs = new ArrayList(); + + String intervals[] = pages.split(","); + + // convert the page-interval-strings into a list containing every single + // page + for (String interval : intervals) { + if (interval.contains("-")) { + String nums[] = interval.split("-"); + int start = Integer.valueOf(nums[0]); + if (nums.length > 1) { + // second number is end of range + int end = Integer.valueOf(nums[1]); + if (intervals.length == 1) { + // optimized case of just one interval + this.start = start; + this.end = end; + this.list = null; + return; + } + for (int i = start; i <= end; i++) { + // add all numbers to list + pgs.add(i); + } + } else { + // second number missing: range to infinity + pgs.add(start); + pgs.add(Integer.MAX_VALUE); + } + } else { + // single number + pgs.add(Integer.valueOf(interval)); + } + } + if (intervals.length > 1) { + Collections.sort(pgs); + } + list = pgs; + } + + public int getStart() { + if (list == null) { + return start; + } else { + return list.get(0); + } + } + + public int getEnd() { + Integer last; + if (list == null) { + last = end; + } else { + last = list.get(list.size() - 1); + } + if (maxnum == null) { + return last; + } else { + return Math.min(last, maxnum); + } + } + + public Iterator iterator() { + if (list == null) { + // return count-based iterator + return new Iterator() { + // anonymous inner Iterator class + private int num = getStart(); + private int end = getEnd(); + + public boolean hasNext() { + return (num <= end); + } + + public Integer next() { + return num++; + } + + public void remove() { + // don't do this + } + }; + } else { + // return list-based iterator + return new Iterator() { + // anonymous inner Iterator class + private int listidx = 0; + private int listend = list.size(); + private int num = getStart(); + private int end = getEnd(); + + public boolean hasNext() { + return (num <= end); + } + + public Integer next() { + if (listidx < listend - 1) { + num = list.get(listidx++); + return num; + } else if (listidx == listend - 1) { + // last element in list + int n = list.get(listidx++); + if (n == Integer.MAX_VALUE) { + // open end -- continue + num++; + return num++; + } else { + num = n; + return num++; + } + } else { + return num++; + } + } + + public void remove() { + // don't do this + } + }; + } + } + + public void setMaxnum(Integer maxnum) { + this.maxnum = maxnum; + } + +} diff -r 5cc180bb0a5c -r 0885f5ca5b24 servlet/src/digilib/util/OptionsSet.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/servlet/src/digilib/util/OptionsSet.java Thu Dec 16 21:19:11 2010 +0100 @@ -0,0 +1,67 @@ +/** + * + */ +package digilib.util; + +import java.util.HashSet; +import java.util.StringTokenizer; + +/** + * @author casties + * + */ +@SuppressWarnings("serial") +public class OptionsSet extends HashSet { + + protected String optionSep = ","; + + public OptionsSet() { + super(); + } + + /** Constructor with String of options. + * @param s + */ + public OptionsSet(String s) { + super(); + parseString(s); + } + + /** Adds all options from String to Set. + * @param s + */ + public void parseString(String s) { + if (s != null) { + StringTokenizer i = new StringTokenizer(s, optionSep); + while (i.hasMoreTokens()) { + String opt = i.nextToken(); + this.add(opt); + } + } + } + + public boolean hasOption(String opt) { + return this.contains(opt); + } + + public String toString() { + StringBuffer b = new StringBuffer(); + for (String s: this) { + if (b.length() > 0) { + b.append(optionSep); + } + b.append(s); + } + return b.toString(); + } + + + public String getOptionSep() { + return optionSep; + } + + public void setOptionSep(String optionSep) { + this.optionSep = optionSep; + } + +} diff -r 5cc180bb0a5c -r 0885f5ca5b24 servlet/src/digilib/util/Parameter.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/servlet/src/digilib/util/Parameter.java Thu Dec 16 21:19:11 2010 +0100 @@ -0,0 +1,284 @@ +/* Parameter -- General digilib parameter class. + + Digital Image Library servlet components + + Copyright (C) 2003 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 02.09.2003 by casties + * + */ +package digilib.util; + +import java.io.File; +import java.io.IOException; + + +/** + * General digilib parameter class. + * + * @author casties + * + */ +public class Parameter { + /** real value */ + protected Object value = null; + + /** default value */ + protected Object defval = null; + + /** parameter name (e.g. in config file) */ + protected String name = null; + + /** parameter type */ + protected int type = 0; + + /** + * Default constructor. + * + */ + public Parameter() { + super(); + } + + /** + * Constructor with name, default, and value. + * + * @param value + * @param defval + */ + public Parameter(String name, Object defval, Object value) { + this.name = name; + this.value = value; + this.defval = defval; + } + + /** + * Constructor with name, default, value, and type. + * + * @param value + * @param defval + */ + public Parameter(String name, Object defval, Object value, int type) { + this.name = name; + this.value = value; + this.defval = defval; + this.type = type; + } + + /** + * Is the value valid. + * + * @return + */ + public boolean hasValue() { + return (value != null); + } + + /** + * Try to set the value from a String. + * + * Tries to convert the String to the same type as the default value. Sets + * the value anyway if the default is null. Returns if the value could be + * set. + * + * @param val + * @return + */ + public boolean setValueFromString(String val) { + if (val == null) { + val = ""; + } + // no default matches all + if (defval == null) { + this.value = val; + return true; + } + Class c = defval.getClass(); + // take String as is + if (c == String.class) { + this.value = val; + return true; + } + // set File + if (c == File.class) { + this.value = new File(val); + return true; + } + // set Options + if (c == OptionsSet.class) { + this.value = new OptionsSet(val); + return true; + } + // set Boolean if string == "true" + if (c == Boolean.class) { + this.value = new Boolean(val.compareToIgnoreCase("true") == 0); + return true; + } + try { + // set Integer + if (c == Integer.class) { + this.value = new Integer(Integer.parseInt(val)); + return true; + } + // set Float + if (c == Float.class) { + this.value = new Float(Float.parseFloat(val)); + return true; + } + } catch (NumberFormatException e) { + } + // then it's unknown + return false; + } + + /** + * Get the default as Object. + * + * @return + */ + public Object getDefault() { + return defval; + } + + /** + * Set the default. + * + * @param defval + */ + public void setDefault(Object defval) { + this.defval = defval; + } + + /** + * Get the value as Object. + * + * Returns the default if the value is not set. + * + * @return + */ + public Object getValue() { + return (value != null) ? value : defval; + } + + public int getAsInt() { + Integer i = (Integer) getValue(); + return (i != null) ? i.intValue() : 0; + } + + public float getAsFloat() { + Float f = (Float) getValue(); + return (f != null) ? f.floatValue() : 0f; + } + + public String getAsString() { + Object s = getValue(); + if (s == null) { + return ""; + } + if (s.getClass() == File.class) { + try { + return ((File) s).getCanonicalPath(); + } catch (IOException e) { + return "ERR: " + s.toString(); + } + } + return s.toString(); + } + + public boolean getAsBoolean() { + Boolean b = (Boolean) getValue(); + return (b != null) ? b.booleanValue() : false; + } + + public String[] parseAsArray(String separator) { + String s = getAsString(); + String[] sa = s.split(separator); + return sa; + } + + public float[] parseAsFloatArray(String separator) { + String s = getAsString(); + String[] sa = s.split(separator); + float[] fa = null; + try { + int n = sa.length; + fa = new float[n]; + for (int i = 0; i < n; i++) { + float f = Float.parseFloat(sa[i]); + fa[i] = f; + } + } catch (Exception e) { + } + + return fa; + } + + /** + * Set the value. + * + * @param value + */ + public void setValue(Object value) { + this.value = value; + } + + /** + * Set the value. + * + * @param value + */ + public void setValue(int value) { + this.value = new Integer(value); + } + + /** + * Set the value. + * + * @param value + */ + public void setValue(float value) { + this.value = new Float(value); + } + + /** + * @return + */ + public String getName() { + return name; + } + + /** + * @param name + */ + public void setName(String name) { + this.name = name; + } + + /** + * @return + */ + public int getType() { + return type; + } + + /** + * @param type + */ + public void setType(int type) { + this.type = type; + } + +} diff -r 5cc180bb0a5c -r 0885f5ca5b24 servlet/src/digilib/util/ParameterMap.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/servlet/src/digilib/util/ParameterMap.java Thu Dec 16 21:19:11 2010 +0100 @@ -0,0 +1,322 @@ +/* ParameterMap.java -- HashMap of Parameters. + + Digital Image Library servlet components + + Copyright (C) 2003 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 02.09.2003 by casties + * + */ +package digilib.util; + +import java.util.HashMap; + + +/** HashMap of digilib.servlet.Parameter's. + * + * Keys are Strings. Values are Parameters. + * + * @author casties + * + */ +public class ParameterMap { + + protected HashMap params; + + protected OptionsSet options; + + /** Default constructor. + * + */ + public ParameterMap() { + params = new HashMap(); + options = new OptionsSet(); + initParams(); + } + + /** Constructor with initial size. + * @param size + */ + public ParameterMap(int size) { + params = new HashMap(size); + options = new OptionsSet(); + initParams(); + } + + /** Shallow copy constructor. + * Be warned that the maps are only cloned i.e. keys and values are shared! + * @param pm + */ + @SuppressWarnings("unchecked") + public static ParameterMap cloneInstance(ParameterMap pm) { + ParameterMap newPm = new ParameterMap(); + // clone params to this map + newPm.params = (HashMap) pm.params.clone(); + newPm.options = (OptionsSet) pm.options.clone(); + return newPm; + } + + + /** Creates new ParameterMap by merging Parameters from another ParameterMap. + * @param pm + * @return + */ + public static ParameterMap getInstance(ParameterMap pm) { + ParameterMap newPm = new ParameterMap(); + // add all params to this map + newPm.params.putAll(pm.params); + newPm.initOptions(); + return newPm; + } + + /** set up parameters + * + */ + protected void initParams() { + // no default parameters + } + + /** set up options + * + */ + protected void initOptions() { + // no default options + } + + /** Get the Parameter with the corresponding key. + * + * Returns null if no element is associated with key. + * + * @param key + * @return + */ + public Parameter get(String key) { + return params.get(key); + } + + /** Get the Parameter with the corresponding key. + * + * Returns null if no element is associated with key. + * + * @param key + * @return + */ + public Object getValue(String key) { + Parameter p = params.get(key); + return (p != null) ? p.getValue() : null; + } + + /** Get the Parameter with the corresponding key. + * + * Returns null if no element is associated with key. + * + * @param key + * @return + */ + public String getAsString(String key) { + Parameter p = params.get(key); + return (p != null) ? p.getAsString() : ""; + } + + /** Get the Parameter with the corresponding key. + * + * Returns null if no element is associated with key. + * + * @param key + * @return + */ + public int getAsInt(String key) { + Parameter p = params.get(key); + return (p != null) ? p.getAsInt() : 0; + } + + /** Get the Parameter with the corresponding key. + * + * Returns null if no element is associated with key. + * + * @param key + * @return + */ + public float getAsFloat(String key) { + Parameter p = params.get(key); + return (p != null) ? p.getAsFloat() : 0f; + } + + /** Get the Parameter with the corresponding key. + * + * Returns null if no element is associated with key. + * + * @param key + * @return + */ + public boolean getAsBoolean(String key) { + Parameter p = params.get(key); + return (p != null) ? p.getAsBoolean() : false; + } + + /** Returns if the Parameter's value has been set. + * + * @param key + * @return + */ + public boolean hasValue(String key) { + Parameter p = params.get(key); + return (p != null) ? p.hasValue() : false; + } + + /** Add the Parameter to the map with a certain key. + * + * Returns the value that was previously associated with key. + * + * @param key + * @param val + * @return + */ + public Parameter put(String key, Parameter val) { + return params.put(key, val); + } + + /** Add the Parameter val to the map, using val's name. + * + * Returns the value that was previously associated with val's name. + * + * @param val + * @return + */ + public Parameter put(Parameter val) { + return params.put(val.getName(), val); + } + + /** Add a new Parameter with name, default and value. + * + * Returns the key that was previously associated with name. + * + * @param name + * @param def + * @param val + * @return + */ + public Parameter newParameter(String name, Object def, Object val) { + Parameter p = new Parameter(name, def, val); + return params.put(name, p); + } + + /** Add a new Parameter with name, default, value and type. + * + * Returns the key that was previously associated with name. + * + * @param name + * @param def + * @param val + * @param type + * @return + */ + public Parameter newParameter(String name, Object def, Object val, int type) { + Parameter p = new Parameter(name, def, val, type); + return params.put(name, p); + } + + /** Set the value of an existing parameter. + * + * Sets the value and returns true if the parameter exists. + * + * @param key + * @param val + * @return + */ + public boolean setValue(String key, Object val) { + Parameter p = params.get(key); + if (p != null) { + p.setValue(val); + return true; + } + return false; + } + + /** Set the value of an existing parameter. + * + * Sets the value and returns true if the parameter exists. + * + * @param key + * @param val + * @return + */ + public boolean setValue(String key, int val) { + Parameter p = params.get(key); + if (p != null) { + p.setValue(val); + return true; + } + return false; + } + + /** Set the value of an existing parameter. + * + * Sets the value and returns true if the parameter exists. + * + * @param key + * @param val + * @return + */ + public boolean setValue(String key, float val) { + Parameter p = params.get(key); + if (p != null) { + p.setValue(val); + return true; + } + return false; + } + + /** Set the value of an existing parameter. + * + * Sets the value and returns true if the parameter exists. + * + * @param key + * @param val + * @return + */ + public boolean setValueFromString(String key, String val) { + Parameter p = params.get(key); + if (p != null) { + p.setValueFromString(val); + return true; + } + return false; + } + + /** Returns of the option has been set. + * @param opt + * @return + */ + public boolean hasOption(String opt) { + return options.hasOption(opt); + } + + public HashMap getParams() { + return params; + } + + public void setParams(HashMap params) { + this.params = params; + } + + public OptionsSet getOptions() { + return options; + } + + public void setOptions(OptionsSet options) { + this.options = options; + } +}