Mercurial > hg > digilib-old
changeset 536:e758a49258e8 digilibPDF
Merge with 9936604d466e3c44d8a2609519848f33f2801629 (changes to HEAD)
line wrap: on
line diff
--- a/client/digitallibrary/WEB-INF/digilib-config.xml Wed Jul 14 16:36:42 2010 +0200 +++ b/client/digitallibrary/WEB-INF/digilib-config.xml Wed Aug 25 18:29:08 2010 +0200 @@ -58,5 +58,17 @@ <!-- location of logger config file --> <parameter name="log-config-file" value="log4j-config.xml"/> + + + + <!-- location for PDF files while still in progress --> + <parameter name="pdf-temp-dir" value="pdf_temp/" /> + + <!-- location for PDF files upon completion --> + <parameter name="pdf-cache-dir" value="cache/"/> + + <!-- location for PDFs while still in progress --> + <parameter name="pdf-logo" value="http://www.mpiwg-berlin.mpg.de/de/images/logo.png" /> + </digilib-config>
--- a/client/digitallibrary/WEB-INF/web.xml Wed Jul 14 16:36:42 2010 +0200 +++ b/client/digitallibrary/WEB-INF/web.xml Wed Aug 25 18:29:08 2010 +0200 @@ -54,40 +54,16 @@ digilib.servlet.Texter </servlet-class> </servlet> - <!-- The Raster servlet --> - <servlet> - <servlet-name> - Raster - </servlet-name> - <description> - The servlet for rastered SVG. - </description> - <servlet-class> - digilib.servlet.Raster - </servlet-class> - </servlet> - <!-- The Mapper servlet --> + <!-- The PDFCache servlet --> <servlet> <servlet-name> - Mapper + PDFCache </servlet-name> <description> - The servlet to create image maps. + The servlet for PDF. </description> <servlet-class> - digilib.servlet.Mapper - </servlet-class> - </servlet> - <!-- The Relato servlet --> - <servlet> - <servlet-name> - Relato - </servlet-name> - <description> - The relato servlet - </description> - <servlet-class> - Relato + digilib.servlet.PDFCache </servlet-class> </servlet> <!-- We want to mess around with the default JSP servlet... --> @@ -145,47 +121,21 @@ /authenticated/servlet/Texter/* </url-pattern> </servlet-mapping> - <!-- The mapping for the Raster servlet --> + <!-- The mapping for the Texter servlet --> <servlet-mapping> <servlet-name> - Raster + PDFCache </servlet-name> <url-pattern> - /servlet/Raster/* + /servlet/PDFCache/* </url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name> - Raster - </servlet-name> - <url-pattern> - /authenticated/servlet/Raster/* - </url-pattern> - </servlet-mapping> - <!-- The mapping for the Mapper servlet --> - <servlet-mapping> - <servlet-name> - Mapper + PDFCache </servlet-name> <url-pattern> - /servlet/Mapper/* - </url-pattern> - </servlet-mapping> - <servlet-mapping> - <servlet-name> - Mapper - </servlet-name> - <url-pattern> - /authenticated/servlet/Mapper/* - </url-pattern> - </servlet-mapping> - <!-- The mapping for the Relato servlet --> - <servlet-mapping> - <servlet-name> - Relato - </servlet-name> - <url-pattern> - /Relato + /authenticated/servlet/PDFCache/* </url-pattern> </servlet-mapping> <!-- The mapping for the JSP servlet -->
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/client/digitallibrary/pdf/error.jsp Wed Aug 25 18:29:08 2010 +0200 @@ -0,0 +1,13 @@ +<%@ page language="java" contentType="text/html; charset=ISO-8859-1" + pageEncoding="ISO-8859-1"%> +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> +<html> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> +<title>Error</title> +</head> +<body> +<h1>Error</h1> +Während der Verarbeitung ihrer Anfrage trat ein Fehler auf. Möglicherweise sind die übergebenen Parameter fehlerhaft. +</body> +</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/client/digitallibrary/pdf/wip.jsp Wed Aug 25 18:29:08 2010 +0200 @@ -0,0 +1,14 @@ +<%@ page language="java" contentType="text/html; charset=ISO-8859-1" + pageEncoding="ISO-8859-1"%> +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> +<html> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> +<meta http-equiv="refresh" content="10"> +<title>Work in progress ...</title> +</head> +<body> +<h1>Bitte warten ...</h1> +ihre Anfrage wird bearbeitet. Der Download beginnt automatisch, sobald das Dokument fertig generiert ist. +</body> +</html>
--- a/servlet/src/digilib/auth/AuthOps.java Wed Jul 14 16:36:42 2010 +0200 +++ b/servlet/src/digilib/auth/AuthOps.java Wed Aug 25 18:29:08 2010 +0200 @@ -81,7 +81,7 @@ * @throws AuthOpException Exception thrown on error. * @return List of Strings with role names. */ - public List rolesForPath(String filepath, HttpServletRequest request) + public List<String> rolesForPath(String filepath, HttpServletRequest request) throws AuthOpException; /** Authorization roles needed for request. @@ -95,7 +95,7 @@ * @throws AuthOpException Exception thrown on error. * @return List of Strings with role names. */ - public List rolesForPath(DigilibRequest request) + public List<String> rolesForPath(DigilibRequest request) throws AuthOpException; /** Test request authorization against a list of roles. @@ -103,13 +103,13 @@ * @param request ServletRequest with address information. * @return true if the user information in the request authorizes one of the roles. */ - public boolean isRoleAuthorized(List roles, HttpServletRequest request); + public boolean isRoleAuthorized(List<String> roles, HttpServletRequest request); /** Test request authorization against a list of roles. * @param roles List of Strings with role names. * @param request ServletRequest with address information. * @return true if the user information in the request authorizes one of the roles. */ - public boolean isRoleAuthorized(List roles, DigilibRequest request); + public boolean isRoleAuthorized(List<String> roles, DigilibRequest request); }
--- a/servlet/src/digilib/auth/AuthOpsImpl.java Wed Jul 14 16:36:42 2010 +0200 +++ b/servlet/src/digilib/auth/AuthOpsImpl.java Wed Aug 25 18:29:08 2010 +0200 @@ -21,7 +21,6 @@ package digilib.auth; import java.util.List; -import java.util.ListIterator; import javax.servlet.http.HttpServletRequest; @@ -56,7 +55,7 @@ */ public boolean isAuthRequired(String filepath, HttpServletRequest request) throws AuthOpException { // check permissions - List rolesRequired = rolesForPath(filepath, request); + List<String> rolesRequired = rolesForPath(filepath, request); return (rolesRequired != null); } @@ -66,7 +65,7 @@ public boolean isAuthRequired(DigilibRequest request) throws AuthOpException { // check permissions - List rolesRequired = rolesForPath(request); + List<String> rolesRequired = rolesForPath(request); return (rolesRequired != null); } @@ -80,7 +79,7 @@ * @return List of Strings with role names. */ public boolean isAuthorized(String filepath, HttpServletRequest request) throws AuthOpException { - List rolesAllowed = rolesForPath(filepath, request); + List<String> rolesAllowed = rolesForPath(filepath, request); return isRoleAuthorized(rolesAllowed, request); } @@ -89,7 +88,7 @@ */ public boolean isAuthorized(DigilibRequest request) throws AuthOpException { - List rolesAllowed = rolesForPath(request); + List<String> rolesAllowed = rolesForPath(request); return isRoleAuthorized(rolesAllowed, request); } @@ -98,11 +97,8 @@ * @param request ServletRequest with address information. * @return true if the user information in the request authorizes one of the roles. */ - public boolean isRoleAuthorized(List roles, HttpServletRequest request) { - ListIterator r = roles.listIterator(); - String s = ""; - while (r.hasNext()) { - s = (String)r.next(); + public boolean isRoleAuthorized(List<String> roles, HttpServletRequest request) { + for (String s: roles) { logger.debug("Testing role: "+s); if (request.isUserInRole(s)) { logger.debug("Role Authorized"); @@ -115,11 +111,8 @@ /** * @see digilib.auth.AuthOps#isRoleAuthorized(java.util.List, digilib.servlet.DigilibRequest) */ - public boolean isRoleAuthorized(List roles, DigilibRequest request) { - ListIterator r = roles.listIterator(); - String s = ""; - while (r.hasNext()) { - s = (String)r.next(); + public boolean isRoleAuthorized(List<String> roles, DigilibRequest request) { + for (String s: roles) { logger.debug("Testing role: "+s); if (((HttpServletRequest)request.getServletRequest()).isUserInRole(s)) { logger.debug("Role Authorized"); @@ -131,8 +124,8 @@ public abstract void init() throws AuthOpException; - public abstract List rolesForPath(String filepath, HttpServletRequest request) throws AuthOpException; + public abstract List<String> rolesForPath(String filepath, HttpServletRequest request) throws AuthOpException; - public abstract List rolesForPath(DigilibRequest request) throws AuthOpException; + public abstract List<String> rolesForPath(DigilibRequest request) throws AuthOpException; }
--- a/servlet/src/digilib/auth/HashTree.java Wed Jul 14 16:36:42 2010 +0200 +++ b/servlet/src/digilib/auth/HashTree.java Wed Aug 25 18:29:08 2010 +0200 @@ -20,7 +20,10 @@ package digilib.auth; -import java.util.*; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.StringTokenizer; /** * Tree representation wrapper for a HashMap. @@ -37,7 +40,7 @@ */ public class HashTree { - private Map table; + private Map<String, String> table; private String twigSep = "/"; @@ -53,7 +56,7 @@ * @param twig_separator * @param leaf_separator */ - public HashTree(Map t, String twig_separator, String leaf_separator) { + public HashTree(Map<String, String> t, String twig_separator, String leaf_separator) { table = t; twigSep = twig_separator; leafSep = leaf_separator; @@ -73,10 +76,10 @@ * @param branch * @return */ - List match(String branch) { + List<String> match(String branch) { String b = ""; String m; - LinkedList matches = new LinkedList(); + LinkedList<String> matches = new LinkedList<String>(); // split branch StringTokenizer twig = new StringTokenizer(branch, twigSep); @@ -87,7 +90,7 @@ } else { b += twigSep + twig.nextToken(); } - m = (String) table.get(b); + m = table.get(b); if (m != null) { if (m.indexOf(leafSep) < 0) { // single leaf
--- a/servlet/src/digilib/auth/XMLAuthOps.java Wed Jul 14 16:36:42 2010 +0200 +++ b/servlet/src/digilib/auth/XMLAuthOps.java Wed Aug 25 18:29:08 2010 +0200 @@ -69,8 +69,8 @@ */ public void init() throws AuthOpException { logger.debug("xmlauthops.init (" + configFile + ")"); - Map pathList = null; - Map ipList = null; + Map<String, String> pathList = null; + Map<String, String> ipList = null; try { // load authPaths XMLListLoader pathLoader = @@ -105,7 +105,7 @@ * @throws AuthOpException Exception thrown on error. * @return List of Strings with role names. */ - public List rolesForPath(String filepath, HttpServletRequest request) + public List<String> rolesForPath(String filepath, HttpServletRequest request) throws digilib.auth.AuthOpException { logger.debug("rolesForPath (" + filepath @@ -114,13 +114,13 @@ + "]"); // check if the requests address provides a role - List provided = authIPs.match(request.getRemoteAddr()); + List<String> provided = authIPs.match(request.getRemoteAddr()); if ((provided != null) && (provided.contains("ALL"))) { // ALL switches off checking; return null; } // which roles are required? - List required = authPaths.match(filepath); + List<String> required = authPaths.match(filepath); // do any provided roles match? if ((provided != null) && (required != null)) { for (int i = 0; i < provided.size(); i++) { @@ -136,7 +136,7 @@ /** * @see digilib.auth.AuthOps#rolesForPath(digilib.servlet.DigilibRequest) */ - public List rolesForPath(DigilibRequest request) throws AuthOpException { + public List<String> rolesForPath(DigilibRequest request) throws AuthOpException { logger.debug("rolesForPath (" + request.getFilePath() + ") by [" @@ -144,14 +144,14 @@ + "]"); // check if the requests address provides a role - List provided = + List<String> provided = authIPs.match(request.getServletRequest().getRemoteAddr()); if ((provided != null) && (provided.contains("ALL"))) { // ALL switches off checking; return null; } // which roles are required? - List required = authPaths.match(request.getFilePath()); + List<String> required = authPaths.match(request.getFilePath()); // do any provided roles match? if ((provided != null) && (required != null)) { for (int i = 0; i < provided.size(); i++) {
--- a/servlet/src/digilib/image/DocuImage.java Wed Jul 14 16:36:42 2010 +0200 +++ b/servlet/src/digilib/image/DocuImage.java Wed Aug 25 18:29:08 2010 +0200 @@ -219,6 +219,12 @@ /** * Returns a list of supported image formats */ - public Iterator getSupportedFormats(); + public Iterator<String> getSupportedFormats(); + + /** + * returns the underlying image as java.awt.Image (if possible, or null) + * @return + */ + public java.awt.Image getAwtImage(); }
--- a/servlet/src/digilib/image/DocuImageImpl.java Wed Jul 14 16:36:42 2010 +0200 +++ b/servlet/src/digilib/image/DocuImageImpl.java Wed Aug 25 18:29:08 2010 +0200 @@ -20,9 +20,11 @@ package digilib.image; +import java.awt.Image; import java.awt.Rectangle; import java.io.File; import java.io.IOException; +import java.io.OutputStream; import java.io.RandomAccessFile; import java.util.Iterator; import java.util.LinkedList; @@ -157,10 +159,52 @@ // emtpy implementation } - public Iterator getSupportedFormats() { - List empty = new LinkedList(); + public Iterator<String> getSupportedFormats() { + List<String> empty = new LinkedList<String>(); return empty.iterator(); } - + + @Override + public void crop(int xoff, int yoff, int width, int height) + throws ImageOpException { + // TODO Auto-generated method stub + + } + + @Override + public Image getAwtImage() { + // TODO Auto-generated method stub + return null; + } + + @Override + public int getHeight() { + // TODO Auto-generated method stub + return 0; + } + @Override + public int getWidth() { + // TODO Auto-generated method stub + return 0; + } + + @Override + public void loadImage(ImageFile f) throws FileOpException { + // TODO Auto-generated method stub + + } + + @Override + public void scale(double scaleX, double scaleY) throws ImageOpException { + // TODO Auto-generated method stub + + } + + @Override + public void writeImage(String mt, OutputStream ostream) + throws FileOpException { + // TODO Auto-generated method stub + } + }
--- a/servlet/src/digilib/image/ImageLoaderDocuImage.java Wed Jul 14 16:36:42 2010 +0200 +++ b/servlet/src/digilib/image/ImageLoaderDocuImage.java Wed Aug 25 18:29:08 2010 +0200 @@ -117,7 +117,7 @@ } /* returns a list of supported image formats */ - public Iterator getSupportedFormats() { + public Iterator<String> getSupportedFormats() { String[] formats = ImageIO.getReaderFormatNames(); return Arrays.asList(formats).iterator(); } @@ -140,9 +140,9 @@ */ RandomAccessFile raf = new RandomAccessFile(f, "r"); ImageInputStream istream = ImageIO.createImageInputStream(raf); - Iterator readers = ImageIO.getImageReaders(istream); + Iterator<ImageReader> readers = ImageIO.getImageReaders(istream); if (readers.hasNext()) { - ImageReader reader = (ImageReader) readers.next(); + ImageReader reader = readers.next(); /* are there more readers? */ logger.debug("ImageIO: this reader: " + reader.getClass()); while (readers.hasNext()) { @@ -202,11 +202,11 @@ // Iterator readers = ImageIO.getImageReaders(istream); String mt = f.getMimetype(); logger.debug("File type:" + mt); - Iterator readers = ImageIO.getImageReadersByMIMEType(mt); + Iterator<ImageReader> readers = ImageIO.getImageReadersByMIMEType(mt); if (!readers.hasNext()) { throw new FileOpException("Unable to load File!"); } - reader = (ImageReader) readers.next(); + reader = readers.next(); /* are there more readers? */ logger.debug("ImageIO: this reader: " + reader.getClass()); while (readers.hasNext()) { @@ -562,7 +562,7 @@ img = null; } - public Image getImage(){ + public Image getAwtImage(){ return (Image) img; }
--- a/servlet/src/digilib/image/JAIDocuImage.java Wed Jul 14 16:36:42 2010 +0200 +++ b/servlet/src/digilib/image/JAIDocuImage.java Wed Aug 25 18:29:08 2010 +0200 @@ -20,6 +20,7 @@ package digilib.image; +import java.awt.Image; import java.awt.Rectangle; import java.awt.RenderingHints; import java.awt.image.RenderedImage; @@ -84,20 +85,19 @@ } /* returns a list of supported image formats */ - public Iterator getSupportedFormats() { - Enumeration codecs = ImageCodec.getCodecs(); - List formats = new ArrayList(5); - for (Object codec = codecs.nextElement(); codecs.hasMoreElements(); codec = codecs - .nextElement()) { - logger - .debug("known format:" - + ((ImageCodec) codec).getFormatName()); - formats.add(((ImageCodec) codec).getFormatName()); - } - logger.debug("tilecachesize:" - + JAI.getDefaultInstance().getTileCache().getMemoryCapacity()); - return formats.iterator(); - } + @SuppressWarnings("unchecked") // ImageCodec.getCodecs() returns a naked Enumeration + public Iterator<String> getSupportedFormats() { + Enumeration<ImageCodec> codecs = ImageCodec.getCodecs(); + List<String> formats = new ArrayList<String>(); + for (ImageCodec codec = codecs.nextElement(); codecs.hasMoreElements(); codec = codecs + .nextElement()) { + logger.debug("known format:"+codec.getFormatName()); + formats.add(codec.getFormatName()); + } + logger.debug("tilecachesize:" + + JAI.getDefaultInstance().getTileCache().getMemoryCapacity()); + return formats.iterator(); + } /* Check image size and type and store in ImageFile f */ public boolean identify(ImageFile imgf) throws IOException {
--- a/servlet/src/digilib/image/JAIImageLoaderDocuImage.java Wed Jul 14 16:36:42 2010 +0200 +++ b/servlet/src/digilib/image/JAIImageLoaderDocuImage.java Wed Aug 25 18:29:08 2010 +0200 @@ -20,6 +20,7 @@ package digilib.image; +import java.awt.Image; import java.awt.Rectangle; import java.awt.image.renderable.ParameterBlock; import java.io.File; @@ -98,11 +99,11 @@ RandomAccessFile rf = new RandomAccessFile(f.getFile(), "r"); ImageInputStream istream = new FileImageInputStream(rf); //Iterator readers = ImageIO.getImageReaders(istream); - Iterator readers = ImageIO.getImageReadersByMIMEType(f.getMimetype()); + Iterator<ImageReader> readers = ImageIO.getImageReadersByMIMEType(f.getMimetype()); if (! readers.hasNext()) { throw new FileOpException("Unable to load File!"); } - reader = (ImageReader) readers.next(); + reader = readers.next(); logger.debug("JAIImageIO: this reader: " + reader.getClass()); while (readers.hasNext()) { logger.debug(" next reader: " + readers.next().getClass()); @@ -166,7 +167,13 @@ } } - /* (non-Javadoc) + @Override + public Image getAwtImage() { + // TODO Auto-generated method stub + return (Image) img; + } + + /* (non-Javadoc) * @see java.lang.Object#finalize() */ protected void finalize() throws Throwable {
--- a/servlet/src/digilib/io/AliasingDocuDirCache.java Wed Jul 14 16:36:42 2010 +0200 +++ b/servlet/src/digilib/io/AliasingDocuDirCache.java Wed Aug 25 18:29:08 2010 +0200 @@ -23,8 +23,8 @@ package digilib.io; import java.io.File; -import java.util.Iterator; import java.util.Map; +import java.util.Map.Entry; import digilib.servlet.DigilibConfiguration; @@ -45,7 +45,7 @@ throws FileOpException { // create standard DocuDirCache super(baseDirs, fileClasses, dlConfig); - Map pathMap = null; + Map<String,String> pathMap = null; // read alias config file try { // load into pathMap @@ -63,18 +63,16 @@ * load map entries into cache */ - for (Iterator i = pathMap.keySet().iterator(); i.hasNext();) { - String link = (String) i.next(); - String dir = (String) pathMap.get(link); - if (dir == null) { + for (Entry<String, String> linkdir: pathMap.entrySet()) { + if (linkdir.getValue() == null) { logger.error("Key mismatch in mapping file!"); break; } - DocuDirectory destDir = new DocuDirectory(dir, this); + DocuDirectory destDir = new DocuDirectory(linkdir.getValue(), this); if (destDir.isValid()) { - logger.debug("Aliasing dir: " + link); + logger.debug("Aliasing dir: " + linkdir.getKey()); // add the alias name - putName(FileOps.normalName(link), destDir); + putName(FileOps.normalName(linkdir.getKey()), destDir); // add the real dir putDir(destDir); } @@ -87,13 +85,12 @@ * @param name * @param newdir */ - public void putName(String name, DocuDirectory newdir) { - if (map.containsKey(name)) { - logger - .warn("Duplicate key in AliasingDocuDirCache.put -- ignored!"); - } else { - map.put(name, newdir); - } - } + public void putName(String name, DocuDirectory newdir) { + if (map.containsKey(name)) { + logger.warn("Duplicate key in AliasingDocuDirCache.put -- ignored!"); + } else { + map.put(name, newdir); + } + } }
--- a/servlet/src/digilib/io/DocuDirCache.java Wed Jul 14 16:36:42 2010 +0200 +++ b/servlet/src/digilib/io/DocuDirCache.java Wed Aug 25 18:29:08 2010 +0200 @@ -24,7 +24,6 @@ import java.io.File; import java.util.HashMap; -import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Map; @@ -42,7 +41,7 @@ Logger logger = Logger.getLogger(this.getClass()); /** HashMap of directories */ - Map map = null; + Map<String, DocuDirectory> map = null; /** names of base directories */ String[] baseDirNames = null; @@ -74,7 +73,7 @@ public DocuDirCache(String[] bd, int[] fileClasses, DigilibConfiguration dlConfig) { baseDirNames = bd; - map = new HashMap(); + map = new HashMap<String, DocuDirectory>(); this.fileClasses = fileClasses; safeDirIndex = dlConfig.getAsBoolean("safe-dir-index"); } @@ -87,7 +86,7 @@ */ public DocuDirCache(String[] bd) { baseDirNames = bd; - map = new HashMap(); + map = new HashMap<String, DocuDirectory>(); // default file class is CLASS_IMAGE fileClasses = new int[1]; fileClasses[0] = FileOps.CLASS_IMAGE; @@ -149,11 +148,9 @@ * find all children and their children. * @return */ - public List getChildren(String dirname, boolean recurse) { - List l = new LinkedList(); - for (Iterator i = map.keySet().iterator(); i.hasNext();) { - String n = (String) i.next(); - DocuDirectory dd = (DocuDirectory) map.get(n); + public List<DocuDirectory> getChildren(String dirname, boolean recurse) { + List<DocuDirectory> l = new LinkedList<DocuDirectory>(); + for (DocuDirectory dd: map.values()) { if (recurse) { if (dd.getDirName().startsWith(dirname)) { l.add(dd);
--- a/servlet/src/digilib/io/DocuDirectory.java Wed Jul 14 16:36:42 2010 +0200 +++ b/servlet/src/digilib/io/DocuDirectory.java Wed Aug 25 18:29:08 2010 +0200 @@ -25,7 +25,6 @@ import java.io.IOException; import java.util.ArrayList; import java.util.Collections; -import java.util.Iterator; import java.util.List; import java.util.Map; @@ -37,7 +36,7 @@ public class DocuDirectory extends Directory { /** list of files (DocuDirent) */ - private ArrayList[] list = null; + private List<List<DocuDirent>> list = null; /** directory object is valid (exists on disk) */ private boolean isValid = false; @@ -49,13 +48,13 @@ private String dirName = null; /** directory metadata */ - private Map dirMeta = null; + private MetadataMap dirMeta = null; /** state of metadata is valid */ private boolean metaChecked = false; /** unresolved file metadata */ - private Map unresolvedFileMeta = null; + private Map<String, MetadataMap> unresolvedFileMeta = null; /** time of last access of this object (not the filesystem) */ private long objectATime = 0; @@ -90,7 +89,13 @@ protected void initDir() { String baseDirName = cache.getBaseDirNames()[0]; // clear directory first - list = new ArrayList[FileOps.NUM_CLASSES]; + //list = new ArrayList[FileOps.NUM_CLASSES]; + + list = new ArrayList<List<DocuDirent>>(FileOps.NUM_CLASSES); + // create empty list + for (int i=0; i < FileOps.NUM_CLASSES; ++i) { + list.add(null); + } isValid = false; dirMTime = 0; // the first directory has to exist @@ -102,7 +107,7 @@ * */ public int size() { - return ((list != null) && (list[0] != null)) ? list[0].size() : 0; + return ((list != null) && (list.get(0) != null)) ? list.get(0).size() : 0; } /** @@ -112,7 +117,7 @@ * fileClass */ public int size(int fc) { - return ((list != null) && (list[fc] != null)) ? list[fc].size() : 0; + return ((list != null) && (list.get(fc) != null)) ? list.get(fc).size() : 0; } /** @@ -122,10 +127,10 @@ * @return */ public ImageFileset get(int index) { - if ((list == null) || (list[0] == null) || (index >= list[0].size())) { + if ((list == null) || (list.get(0) == null) || (index >= list.get(0).size())) { return null; } - return (ImageFileset) list[0].get(index); + return (ImageFileset) list.get(0).get(index); } /** @@ -137,10 +142,10 @@ * @return */ public DocuDirent get(int index, int fc) { - if ((list == null) || (list[fc] == null) || (index >= list[fc].size())) { + if ((list == null) || (list.get(fc) == null) || (index >= list.get(fc).size())) { return null; } - return (DocuDirent) list[fc].get(index); + return (DocuDirent) list.get(fc).get(index); } /** @@ -221,10 +226,10 @@ int numFiles = fileList.length; if (numFiles > 0) { // create new list - list[fileClass] = new ArrayList(numFiles); + list.set(fileClass, new ArrayList<DocuDirent>(numFiles)); // sort the file names alphabetically and iterate the list // Arrays.sort(fileList); // not needed <hertzhaft> - Map hints = FileOps.newHints(FileOps.HINT_BASEDIRS, dirs); + Map<Integer, Object> hints = FileOps.newHints(FileOps.HINT_BASEDIRS, dirs); hints.put(FileOps.HINT_FILEEXT, scalext); for (int i = 0; i < numFiles; i++) { DocuDirent f = FileOps.fileForClass(fileClass, fileList[i], @@ -232,11 +237,12 @@ // add the file to our list // logger.debug(f.getName()); - list[fileClass].add(f); + list.get(fileClass).add(f); f.setParent(this); } - // we sort the ArrayList, not the Array, for binarySearch to work - Collections.sort(list[fileClass]); + // we sort the inner ArrayList (the list of files not the list of file types) + // for binarySearch to work (DocuDirent's natural sort order is by filename) + Collections.sort(list.get(fileClass)); } } // clear the scaled directories @@ -282,12 +288,12 @@ XMLMetaLoader ml = new XMLMetaLoader(); try { // read directory meta file - Map fileMeta = ml.loadURL(mf.getAbsolutePath()); + Map<String, MetadataMap> fileMeta = ml.loadURL(mf.getAbsolutePath()); if (fileMeta == null) { return; } // meta for the directory itself is in the "" bin - dirMeta = (Map) fileMeta.remove(""); + dirMeta = fileMeta.remove(""); // read meta for files in this directory readFileMeta(fileMeta, null); // is there meta for other files left? @@ -334,25 +340,24 @@ * @param fc * fileClass */ - protected void readFileMeta(Map fileMeta, String relPath) { + protected void readFileMeta(Map<String,MetadataMap> fileMeta, String relPath) { if (list == null) { // there are no files return; } String path = (relPath != null) ? (relPath + "/") : ""; // go through all file classes - for (int nc = 0; nc < list.length; nc++) { + for (int nc = 0; nc < list.size(); nc++) { int fc = cache.getFileClasses()[nc]; - if (list[fc] == null) { + if (list.get(fc) == null) { continue; } // iterate through the list of files in this directory - for (Iterator i = list[fc].iterator(); i.hasNext();) { - DocuDirent f = (DocuDirent) i.next(); + for (DocuDirent f: list.get(fc)) { // prepend path to the filename String fn = path + f.getName(); // look up meta for this file and remove from dir - Map meta = (Map) fileMeta.remove(fn); + MetadataMap meta = fileMeta.remove(fn); if (meta != null) { // store meta in file f.setFileMeta(meta); @@ -361,13 +366,13 @@ } } - protected void notifyChildMeta(Map childmeta) { - List children = cache.getChildren(this.dirName, true); + protected void notifyChildMeta(MetadataMap childmeta) { + List<DocuDirectory> children = cache.getChildren(this.dirName, true); if (children.size() > 0) { - for (Iterator i = children.iterator(); i.hasNext();) { + /*for (DocuDirectory d: children) { // TODO: finish this! //((DocuDirectory) i.next()).readFileMeta() - } + }*/ } } @@ -416,13 +421,13 @@ return -1; } } - List fileList = list[fc]; + List<DocuDirent> fileList = list.get(fc); // empty directory? if (fileList == null) { return -1; } - // search for exact match + // search for exact match (DocuDirent does compareTo<String>) // OBS: fileList needs to be sorted first (see )! <hertzhaft> int idx = Collections.binarySearch(fileList, fn); if (idx >= 0) { @@ -449,8 +454,8 @@ return -1; } - private boolean isBaseInList(List fl, int idx, String fn) { - String dfn = FileOps.basename(((DocuDirent) fl.get(idx)) + private boolean isBaseInList(List<DocuDirent> fl, int idx, String fn) { + String dfn = FileOps.basename((fl.get(idx)) .getName()); return (dfn.equals(fn)||dfn.equals(FileOps.basename(fn))); } @@ -470,7 +475,7 @@ int fc = FileOps.classForFilename(fn); int i = indexOf(fn, fc); if (i >= 0) { - return (DocuDirent) list[0].get(i); + return (DocuDirent) list.get(0).get(i); } return null; } @@ -489,7 +494,7 @@ public DocuDirent find(String fn, int fc) { int i = indexOf(fn, fc); if (i >= 0) { - return (DocuDirent) list[fc].get(i); + return (DocuDirent) list.get(fc).get(i); } return null; } @@ -531,7 +536,7 @@ /** * @return Hashtable */ - public Map getDirMeta() { + public MetadataMap getDirMeta() { return dirMeta; } @@ -560,7 +565,7 @@ * @param dirMeta * The dirMeta to set */ - public void setDirMeta(Map dirMeta) { + public void setDirMeta(MetadataMap dirMeta) { this.dirMeta = dirMeta; }
--- a/servlet/src/digilib/io/DocuDirent.java Wed Jul 14 16:36:42 2010 +0200 +++ b/servlet/src/digilib/io/DocuDirent.java Wed Aug 25 18:29:08 2010 +0200 @@ -33,12 +33,12 @@ * @author casties * */ -public abstract class DocuDirent implements Comparable { +public abstract class DocuDirent implements Comparable<Object> { /** the file class of this file */ protected static int fileClass = FileOps.CLASS_NONE; /** HashMap with metadata */ - protected Map fileMeta = null; + protected MetadataMap fileMeta = null; /** Is the Metadata valid */ protected boolean metaChecked = false; /** the parent directory */ @@ -73,11 +73,11 @@ XMLMetaLoader ml = new XMLMetaLoader(); try { // read meta file - Map meta = ml.loadURL(mf.getAbsolutePath()); + Map<String, MetadataMap> meta = ml.loadURL(mf.getAbsolutePath()); if (meta == null) { return; } - fileMeta = (Map) meta.get(getName()); + fileMeta = meta.get(getName()); } catch (Exception e) { Logger.getLogger(this.getClass()).warn("error reading file .meta", e); } @@ -121,7 +121,7 @@ * * @return HashMap */ - public Map getFileMeta() { + public MetadataMap getFileMeta() { return fileMeta; } @@ -131,7 +131,7 @@ * @param fileMeta * The fileMeta to set */ - public void setFileMeta(Map fileMeta) { + public void setFileMeta(MetadataMap fileMeta) { this.fileMeta = fileMeta; } @@ -156,9 +156,11 @@ * @see java.lang.Comparable#compareTo(java.lang.Object) */ public int compareTo(Object arg0) { - return (arg0 instanceof DocuDirent) - ? getName().compareTo(((DocuDirent) arg0).getName()) - : getName().compareTo((String) arg0); + if (arg0 instanceof DocuDirent) { + return getName().compareTo(((DocuDirent) arg0).getName()); + } else { + return getName().compareTo((String) arg0); + } }
--- a/servlet/src/digilib/io/FileOps.java Wed Jul 14 16:36:42 2010 +0200 +++ b/servlet/src/digilib/io/FileOps.java Wed Aug 25 18:29:08 2010 +0200 @@ -44,13 +44,13 @@ { "htm", "text/html" }, { "xml", "text/xml" }, { "svg", "image/svg+xml" }, { "meta", "text/xml" } }; - public static Map fileTypes; + public static Map<String, String> fileTypes; - public static List imageExtensions; + public static List<String> imageExtensions; - public static List textExtensions; + public static List<String> textExtensions; - public static List svgExtensions; + public static List<String> svgExtensions; public static final int CLASS_NONE = -1; @@ -72,10 +72,10 @@ * static initializer for FileOps */ static { - fileTypes = new HashMap(); - imageExtensions = new ArrayList(); - textExtensions = new ArrayList(); - svgExtensions = new ArrayList(); + fileTypes = new HashMap<String, String>(); + imageExtensions = new ArrayList<String>(); + textExtensions = new ArrayList<String>(); + svgExtensions = new ArrayList<String>(); // iterate through file types in ft and fill the Map and Lists for (int i = 0; i < ft.length; i++) { String ext = ft[i][0]; @@ -129,18 +129,31 @@ return classForMimetype(mt); } - public static Iterator getImageExtensionIterator() { + public static Iterator<String> getImageExtensionIterator() { return imageExtensions.iterator(); } - public static Iterator getTextExtensionIterator() { + public static List<String> getImageExtensions() { + return imageExtensions; + } + + public static Iterator<String> getTextExtensionIterator() { return textExtensions.iterator(); } - public static Iterator getSVGExtensionIterator() { + public static List<String> getTextExtensions() { + return textExtensions; + } + + public static Iterator<String> getSVGExtensionIterator() { return svgExtensions.iterator(); } + public static List<String> getSvgExtensions() { + return svgExtensions; + } + + /** * convert a string with a list of pathnames into an array of strings using * the system's path separator string @@ -333,7 +346,7 @@ * optional additional parameters * @return */ - public static DocuDirent fileForClass(int fileClass, File file, Map hints) { + public static DocuDirent fileForClass(int fileClass, File file, Map<Integer,Object> hints) { // what class of file do we have? if (fileClass == CLASS_IMAGE) { // image file @@ -379,8 +392,8 @@ * @param value * @return */ - public static Map newHints(Integer type, Object value) { - Map m = new HashMap(); + public static Map<Integer, Object> newHints(Integer type, Object value) { + Map<Integer, Object> m = new HashMap<Integer, Object>(); if (type != null) { m.put(type, value); }
--- a/servlet/src/digilib/io/ImageFileset.java Wed Jul 14 16:36:42 2010 +0200 +++ b/servlet/src/digilib/io/ImageFileset.java Wed Aug 25 18:29:08 2010 +0200 @@ -22,6 +22,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Iterator; +import java.util.List; import java.util.ListIterator; import java.util.Map; @@ -37,7 +38,7 @@ protected static int fileClass = FileOps.CLASS_IMAGE; /** list of files (ImageFile) */ - private ArrayList list = null; + private List<ImageFile> list = null; /** aspect ratio (width/height) */ private float aspect = 0; @@ -55,7 +56,7 @@ * @param initialCapacity */ public ImageFileset() { - list = new ArrayList(); + list = new ArrayList<ImageFile>(); } /** @@ -66,10 +67,10 @@ * @param file * @param hints */ - public ImageFileset(File file, Map hints) { + public ImageFileset(File file, Map<Integer,Object> hints) { Directory[] dirs = (Directory[]) hints.get(FileOps.HINT_BASEDIRS); int nb = dirs.length; - list = new ArrayList(nb); + list = new ArrayList<ImageFile>(nb); parent = dirs[0]; fill(dirs, file, hints); } @@ -105,7 +106,7 @@ * */ public File getFile() { - return (list != null) ? ((ImageFile) list.get(0)).getFile() : null; + return (list != null) ? list.get(0).getFile() : null; } /** @@ -116,7 +117,7 @@ * @return */ public ImageFile get(int index) { - return (ImageFile) list.get(index); + return list.get(index); } /** @@ -132,8 +133,8 @@ * @return */ public ImageFile getNextSmaller(ImageSize size) { - for (Iterator i = getHiresIterator(); i.hasNext();) { - ImageFile f = (ImageFile) i.next(); + for (Iterator<ImageFile> i = getHiresIterator(); i.hasNext();) { + ImageFile f = i.next(); try { if (!f.isChecked()) { ImageOps.checkFile(f); @@ -160,8 +161,8 @@ * @return */ public ImageFile getNextBigger(ImageSize size) { - for (ListIterator i = getLoresIterator(); i.hasPrevious();) { - ImageFile f = (ImageFile) i.previous(); + for (ListIterator<ImageFile> i = getLoresIterator(); i.hasPrevious();) { + ImageFile f = i.previous(); try { if (!f.isChecked()) { ImageOps.checkFile(f); @@ -202,7 +203,7 @@ * * @return */ - public ListIterator getHiresIterator() { + public ListIterator<ImageFile> getHiresIterator() { return list.listIterator(); } @@ -216,7 +217,7 @@ * * @return */ - public ListIterator getLoresIterator() { + public ListIterator<ImageFile> getLoresIterator() { return list.listIterator(list.size()); } @@ -231,7 +232,7 @@ * @param hints * */ - void fill(Directory[] dirs, File fl, Map hints) { + void fill(Directory[] dirs, File fl, Map<Integer,Object> hints) { int nb = dirs.length; String fn = fl.getName(); String baseFn = FileOps.basename(fn);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/servlet/src/digilib/io/MetadataMap.java Wed Aug 25 18:29:08 2010 +0200 @@ -0,0 +1,14 @@ +/** + * + */ +package digilib.io; + +import java.util.HashMap; + +/** Map for metadata related to files. + * @author casties + * + */ +public class MetadataMap extends HashMap<String, String> { + +}
--- a/servlet/src/digilib/io/XMLListLoader.java Wed Jul 14 16:36:42 2010 +0200 +++ b/servlet/src/digilib/io/XMLListLoader.java Wed Aug 25 18:29:08 2010 +0200 @@ -75,17 +75,17 @@ */ private class XMLListParser extends DefaultHandler { - private Map listData; - private LinkedList tagSpace; + private Map<String, String> listData; + private LinkedList<String> tagSpace; - public Map getData() { + public Map<String, String> getData() { return listData; } // Parser calls this once at the beginning of a document public void startDocument() throws SAXException { - listData = new HashMap(); - tagSpace = new LinkedList(); + listData = new HashMap<String, String>(); + tagSpace = new LinkedList<String>(); } // Parser calls this for each element in a document @@ -151,7 +151,7 @@ * load and parse a file (as URL) * returns HashMap with list data */ - public Map loadURL(String path) throws SAXException, IOException { + public Map<String, String> loadURL(String path) throws SAXException, IOException { //System.out.println("loadurl ("+path+")"); // Create a JAXP SAXParserFactory and configure it SAXParserFactory spf = SAXParserFactory.newInstance();
--- a/servlet/src/digilib/io/XMLMetaLoader.java Wed Jul 14 16:36:42 2010 +0200 +++ b/servlet/src/digilib/io/XMLMetaLoader.java Wed Aug 25 18:29:08 2010 +0200 @@ -52,9 +52,9 @@ */ private class XMLMetaParser extends DefaultHandler { - private LinkedList tags; - private Map files; - private Map meta; + private LinkedList<String> tags; + private Map<String, MetadataMap> files; + private MetadataMap meta; private StringBuffer content; private boolean collecting; private StringBuffer collectedContent; @@ -96,8 +96,8 @@ // Parser calls this once at the beginning of a document public void startDocument() throws SAXException { - tags = new LinkedList(); - files = new HashMap(); + tags = new LinkedList<String>(); + files = new HashMap<String, MetadataMap>(); collecting = false; collectedContent = null; } @@ -118,13 +118,13 @@ if (name.equals(metaTag)) { // new meta tag - meta = new HashMap(); + meta = new MetadataMap(); collectedContent = new StringBuffer(); } else if (name.equals(fileTag)) { // new file tag fileName = null; filePath = null; - meta = new HashMap(); + meta = new MetadataMap(); collectedContent = new StringBuffer(); } else if (name.equals(collectTag)) { // start collecting @@ -162,7 +162,7 @@ String name = getName(localName, qName); // exit the tag tags.removeLast(); - String lastTag = (tags.isEmpty()) ? "" : (String) tags.getLast(); + String lastTag = (tags.isEmpty()) ? "" : tags.getLast(); // was it a file/name tag? if (name.equals(fileNameTag) && lastTag.equals(fileTag)) { @@ -260,7 +260,7 @@ * load and parse a file (as URL) * returns HashMap with list data */ - public Map loadURL(String path) throws SAXException, IOException { + public Map<String, MetadataMap> loadURL(String path) throws SAXException, IOException { logger.debug("loading meta: "+path); // Create a JAXP SAXParserFactory and configure it SAXParserFactory spf = SAXParserFactory.newInstance();
--- a/servlet/src/digilib/servlet/DigilibConfiguration.java Wed Jul 14 16:36:42 2010 +0200 +++ b/servlet/src/digilib/servlet/DigilibConfiguration.java Wed Aug 25 18:29:08 2010 +0200 @@ -22,8 +22,8 @@ package digilib.servlet; import java.io.File; -import java.util.Iterator; import java.util.Map; +import java.util.Map.Entry; import javax.servlet.ServletConfig; import javax.servlet.ServletException; @@ -53,7 +53,7 @@ private static final long serialVersionUID = -6630487070791637120L; /** DocuImage class instance */ - private Class docuImageClass = null; + private Class<DocuImageImpl> docuImageClass = null; /** Log4J logger */ private Logger logger = Logger.getLogger("digilib.config"); @@ -140,9 +140,9 @@ // use mapping file to translate paths newParameter("use-mapping", Boolean.FALSE, null, 'f'); // mapping file location - newParameter("mapping-file", new File("WEB-INF/digilib-map.xml"), null, 'f'); + newParameter("mapping-file", new File("digilib-map.xml"), null, 'f'); // log4j config file location - newParameter("log-config-file", new File("WEB-INF/log4j-config.xml"), null, 'f'); + newParameter("log-config-file", new File("log4j-config.xml"), null, 'f'); // maximum destination image size (0 means no limit) newParameter("max-image-size", new Integer(0), null, 'f'); // use safe (but slower) directory indexing @@ -151,6 +151,10 @@ newParameter("worker-threads", new Integer(1), null, 'f'); // max number of waiting threads newParameter("max-waiting-threads", new Integer(0), null, 'f'); + // PDF generation temp directory + newParameter("pdf-temp-dir", "pdf_temp", null, 'f'); + // PDF generation cache directory + newParameter("pdf-cache-dir", "pdf_cache", null, 'f'); } @@ -168,56 +172,54 @@ /** * read parameter list from the XML file in init parameter "config-file" */ - public void readConfig(ServletConfig config) throws Exception { + public void readConfig(ServletConfig c) throws Exception { /* * Get config file name. The file name is first looked for as an init * parameter, then in a fixed location in the webapp. */ - if (config == null) { + if (c == null) { // no config no file... return; } - String fn = config.getInitParameter("config-file"); + String fn = c.getInitParameter("config-file"); if (fn == null) { - fn = ServletOps.getFile("WEB-INF/digilib-config.xml", config); + fn = ServletOps.getConfigFile("digilib-config.xml", c); if (fn == null) { logger.fatal("readConfig: no param config-file"); throw new ServletException("ERROR: no digilib config file!"); } } - File configFile = new File(fn); + File f = new File(fn); // setup config file list reader XMLListLoader lilo = new XMLListLoader("digilib-config", "parameter", "name", "value"); // read config file into HashMap - Map confTable = lilo.loadURL(configFile.toURL().toString()); + Map<String,String> confTable = lilo.loadURL(f.toURL().toString()); // set config file path parameter - setValue("servlet.config.file", configFile.getCanonicalPath()); + setValue("servlet.config.file", f.getCanonicalPath()); /* - * process parameters from file + * read parameters */ - for (Iterator i = confTable.keySet().iterator(); i.hasNext();) { - String key = (String) i.next(); - String val = (String) confTable.get(key); - Parameter p = get(key); + for (Entry<String, String> confEntry: confTable.entrySet()) { + Parameter p = get(confEntry.getKey()); if (p != null) { if (p.getType() == 's') { // type 's' Parameters are not overwritten. continue; } - if (!p.setValueFromString(val)) { + if (!p.setValueFromString(confEntry.getValue())) { /* * automatic conversion failed -- try special cases */ // basedir-list - if (key.equals("basedir-list")) { + if (confEntry.getKey().equals("basedir-list")) { // split list into directories - String[] sa = FileOps.pathToArray(val); + String[] sa = FileOps.pathToArray(confEntry.getValue()); if (sa != null) { p.setValue(sa); } @@ -226,36 +228,9 @@ } } else { // parameter unknown -- just add - newParameter(key, null, val, 'f'); + newParameter(confEntry.getKey(), null, confEntry.getValue(), 'f'); } } - - /* - * process all parameters - */ - for (Iterator i = this.keySet().iterator(); i.hasNext();) { - String key = (String) i.next(); - Parameter para = (Parameter) this.get(key); - - // basedir-list - if (key.equals("basedir-list")) { - // split list into directories - String[] dirs = (String[]) para.getValue(); - for (int j = 0; j < dirs.length; j++) { - // make relative directory paths be inside the webapp - dirs[j] = ServletOps.getFile(dirs[j], config); - } - para.setValue(dirs); - } - - // File types - if (para.getValue() instanceof File) { - File pf = (File) para.getValue(); - // make relative paths be inside the webapp - para.setValue(ServletOps.getFile(pf, config)); - } - - } } @@ -266,13 +241,14 @@ * * @return DocuImage */ - public DocuImage getDocuImageInstance() { + @SuppressWarnings("unchecked") + public DocuImage getDocuImageInstance() { DocuImageImpl di = null; try { if (docuImageClass == null) { - docuImageClass = Class.forName(getAsString("docuimage-class")); + docuImageClass = (Class<DocuImageImpl>) Class.forName(getAsString("docuimage-class")); } - di = (DocuImageImpl) docuImageClass.newInstance(); + di = docuImageClass.newInstance(); } catch (Exception e) { } return di; @@ -281,13 +257,13 @@ /** * @return Returns the docuImageClass. */ - public Class getDocuImageClass() { + public Class<DocuImageImpl> getDocuImageClass() { return docuImageClass; } /** * @param docuImageClass The docuImageClass to set. */ - public void setDocuImageClass(Class docuImageClass) { + public void setDocuImageClass(Class<DocuImageImpl> docuImageClass) { this.docuImageClass = docuImageClass; } }
--- a/servlet/src/digilib/servlet/DigilibImageWorker.java Wed Jul 14 16:36:42 2010 +0200 +++ b/servlet/src/digilib/servlet/DigilibImageWorker.java Wed Aug 25 18:29:08 2010 +0200 @@ -24,8 +24,7 @@ import java.awt.Rectangle; import java.awt.geom.Rectangle2D; import java.io.IOException; - -import javax.servlet.http.HttpServletResponse; +import java.io.OutputStream; import digilib.image.DocuImage; import digilib.image.ImageOpException; @@ -43,16 +42,20 @@ private DigilibConfiguration dlConfig; - HttpServletResponse response; + //HttpServletResponse response; + OutputStream outstream; + long startTime; String mimeType; int scaleQual; - DigilibRequest dlRequest; + //DigilibRequest dlRequest; + //ImageJobInformation ijd; + float paramROT; float paramCONT; @@ -83,59 +86,49 @@ boolean wholeRotArea; + boolean vmir; + boolean hmir; + int forceType; - /** - * @param dlConfig - * @param response - * @param mimeType - * @param scaleQual - * @param dlRequest - * @param paramROT - * @param paramCONT - * @param paramBRGT - * @param paramRGBM - * @param paramRGBA - * @param fileToLoad - * @param areaXoff - * @param outerUserImgArea - * @param innerUserImgArea - * @param minSubsample - * @param wholeRotArea - * @param forceType - */ - public DigilibImageWorker(DigilibConfiguration dlConfig, - HttpServletResponse response, String mimeType, int scaleQual, - DigilibRequest dlRequest, float paramROT, float paramCONT, - float paramBRGT, float[] paramRGBM, float[] paramRGBA, - ImageFile fileToLoad, float scaleXY, Rectangle2D outerUserImgArea, - Rectangle2D innerUserImgArea, float minSubsample, - boolean wholeRotArea, int forceType) { + + public DigilibImageWorker(DigilibConfiguration dlConfig, OutputStream outstream, ImageJobInformation jobinfo) { super(); + this.dlConfig = dlConfig; - this.response = response; - this.mimeType = mimeType; - this.scaleQual = scaleQual; - this.dlRequest = dlRequest; - this.paramROT = paramROT; - this.paramCONT = paramCONT; - this.paramBRGT = paramBRGT; - this.paramRGBM = paramRGBM; - this.paramRGBA = paramRGBA; - this.fileToLoad = fileToLoad; - this.scaleXY = scaleXY; - this.outerUserImgArea = outerUserImgArea; - this.innerUserImgArea = innerUserImgArea; - this.minSubsample = minSubsample; - this.wholeRotArea = wholeRotArea; - this.forceType = forceType; + this.outstream = outstream; + this.mimeType = jobinfo.get_mimeType(); + this.scaleQual = jobinfo.get_scaleQual(); + this.paramROT = jobinfo.getAsFloat("rot"); + this.paramCONT = jobinfo.getAsFloat("cont"); + this.paramBRGT = jobinfo.getAsFloat("brgt"); + this.paramRGBM = jobinfo.get_paramRGBM(); + this.paramRGBA = jobinfo.get_paramRGBA(); + try { + this.fileToLoad = jobinfo.get_fileToLoad(); + this.scaleXY = jobinfo.get_scaleXY(); + this.outerUserImgArea = jobinfo.get_outerUserImgArea(); + this.innerUserImgArea = jobinfo.get_innerUserImgArea(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (ImageOpException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + this.minSubsample = dlConfig.getAsFloat("subsample-minimum"); + this.wholeRotArea = jobinfo.get_wholeRotArea(); + this.forceType = jobinfo.get_forceType(); + this.hmir = jobinfo.get_hmir(); + this.vmir = jobinfo.get_vmir(); } /* * do the work */ public DocuImage render() throws FileOpException, IOException, ImageOpException { - ; + logger.debug("image worker " + this.getName() + " working"); startTime = System.currentTimeMillis(); @@ -190,10 +183,10 @@ // mirror image // operation mode: "hmir": mirror horizontally, "vmir": mirror // vertically - if (dlRequest.hasOption("mo", "hmir")) { + if (hmir) { docuImage.mirror(0); } - if (dlRequest.hasOption("mo", "vmir")) { + if (vmir) { docuImage.mirror(90); } @@ -267,12 +260,12 @@ } else { mimeType = "image/png"; } - response.setContentType(mimeType); // write the image - img.writeImage(mimeType, response.getOutputStream()); - response.flushBuffer(); - + img.writeImage(mimeType, outstream); + outstream.flush(); + + logger.info("image worker " + this.getName() + " done in " + (System.currentTimeMillis() - startTime));
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/servlet/src/digilib/servlet/DigilibInfoReader.java Wed Aug 25 18:29:08 2010 +0200 @@ -0,0 +1,76 @@ +package digilib.servlet; + +/** 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<Element> mainElements = root.getChildren(); + // logger.debug("XML mainElements:"+mainElements.toString()); + + for(int i=0; i<mainElements.size(); i++){ + Element elem = mainElements.get(i); + if(elem.getName()==attr){ + // logger.debug(attr+" == "+(String)elem.getTextTrim()); + return (String)elem.getTextTrim(); + } + } + + } + catch(Exception e){ + logger.error(e.getMessage()); + } + return null; + } + + + /** + * Find out if the info.xml exists + * @return + */ + public boolean hasInfo(){ + try { + SAXBuilder builder = new SAXBuilder(); + builder.build(new File(filename)); + return true; + } + catch(Exception e){ + return false; + } + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/servlet/src/digilib/servlet/DigilibPDFWorker.java Wed Aug 25 18:29:08 2010 +0200 @@ -0,0 +1,212 @@ +/* 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 DigilibWorker { + + private DigilibConfiguration dlConfig = null; + + private Document doc = null; + + private File outputfile = null; + + private PDFJobInformation job_info = null; + + public DigilibPDFWorker(DigilibConfiguration dlConfig, PDFJobInformation 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(); + + 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 + ImageJobInformation iji = job_info.getImageJobInformation(); + iji.setValue("pn", pn); + // create image worker + DigilibImageWorker image_worker = new DigilibImageWorker(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
--- a/servlet/src/digilib/servlet/DigilibRequest.java Wed Jul 14 16:36:42 2010 +0200 +++ b/servlet/src/digilib/servlet/DigilibRequest.java Wed Aug 25 18:29:08 2010 +0200 @@ -26,27 +26,14 @@ package digilib.servlet; -import java.io.StringReader; import java.io.UnsupportedEncodingException; import java.net.URLDecoder; import java.util.Enumeration; -import java.util.Hashtable; -import java.util.Iterator; import java.util.StringTokenizer; import javax.servlet.ServletRequest; import javax.servlet.http.HttpServletRequest; -import org.apache.log4j.Logger; - -import com.hp.hpl.mesa.rdf.jena.mem.ModelMem; -import com.hp.hpl.mesa.rdf.jena.model.Model; -import com.hp.hpl.mesa.rdf.jena.model.Property; -import com.hp.hpl.mesa.rdf.jena.model.ResIterator; -import com.hp.hpl.mesa.rdf.jena.model.Resource; -import com.hp.hpl.mesa.rdf.jena.model.Statement; -import com.hp.hpl.mesa.rdf.jena.model.StmtIterator; - import digilib.image.DocuImage; import digilib.io.FileOps; @@ -76,11 +63,7 @@ private static final long serialVersionUID = -4707707539569977901L; - private final static String ECHO = "http://echo.unibe.ch/digilib/rdf#"; - - private final static String DIGILIB = "Digilib"; - - private Logger logger = Logger.getLogger(this.getClass()); + //private Logger logger = Logger.getLogger(this.getClass()); private boolean boolRDF = false; // use RDF Parameters @@ -199,11 +182,7 @@ servletRequest = request; // decide if it's old-style or new-style String qs = ((HttpServletRequest) request).getQueryString(); - if (request.getParameter("rdf") != null) { - // RDF stuff - boolRDF = true; - setWithRDF(request); - } else if (qs != null) { + if (qs != null) { if (qs.indexOf("&") > -1) { // & separator setWithParamString(qs, "&"); @@ -349,8 +328,7 @@ public String getAsString(int type) { StringBuffer s = new StringBuffer(50); // go through all values - for (Iterator i = this.values().iterator(); i.hasNext();) { - Parameter p = (Parameter) i.next(); + for (Parameter p: this.values()) { if ((type > 0) && (p.getType() != type)) { // skip the wrong types continue; @@ -406,10 +384,11 @@ * @param request * ServletRequest to get parameters from. */ - public void setWithParamRequest(ServletRequest request) { + @SuppressWarnings("unchecked") // ServletRequest.getParameterNames() returns naked Enumeration + public void setWithParamRequest(ServletRequest request) { setValue("servlet.request", request); // go through all request parameters - for (Enumeration i = request.getParameterNames(); i.hasMoreElements();) { + for (Enumeration<String> i = request.getParameterNames(); i.hasMoreElements();) { String name = (String) i.nextElement(); // is this a known parameter? if (this.containsKey(name)) { @@ -466,76 +445,6 @@ } /** - * - * - */ - public void setWithRDF(ServletRequest request) { - String strRDF; - strRDF = request.getParameter("rdf"); - if (strRDF != null) { - Hashtable hashRDF = rdf2hash(strRDF); - // go through all parameters - for (Iterator i = hashRDF.keySet().iterator(); i.hasNext();) { - String name = (String) i.next(); - // is this a known parameter? - if (this.containsKey(name)) { - Parameter p = (Parameter) this.get(name); - // internal parameters are not set - if (p.getType() == 'i') { - continue; - } - p.setValueFromString((String) hashRDF.get(name)); - } - } - } - // add path from request - setValue("request.path", ((HttpServletRequest) request).getPathInfo()); - } - - private Hashtable rdf2hash(String strRDF) { - Hashtable hashParams = new Hashtable(); - try { - // create an empty model - Model model = new ModelMem(); - StringReader sr = new StringReader(strRDF); - model.read(sr, ""); - // get Property type -> digilib - Property property = model.getProperty(DigilibRequest.ECHO, "type"); - if (property != null) { - ResIterator resourceIterator = model - .listSubjectsWithProperty(property); - while (resourceIterator.hasNext()) { - Resource resource = resourceIterator.next(); - StmtIterator statementIterator = resource.listProperties(); - String type = resource.getProperty(property).getResource() - .getURI(); - if (type == null) { - continue; - } - if (type.equals(DigilibRequest.ECHO - + DigilibRequest.DIGILIB)) { - while (statementIterator.hasNext()) { - Statement statement = statementIterator.next(); - Property predicate = statement.getPredicate(); - if (predicate.getNameSpace().equals( - DigilibRequest.ECHO)) { - hashParams.put(predicate.getLocalName(), - statement.getObject().toString()); - } - } - } - } - } else { - logger.warn("The type property was null! So the rdf-model" - + " sent to Digilib was probably incorrect!"); - } - } catch (Exception e) { - logger.warn("rdf2hash function caused an error: ", e); - } - return hashParams; - } - - /** * Test if option string <code>opt</code> is set. Checks if the substring * <code>opt</code> is contained in the options string <code>param</code>. *
--- a/servlet/src/digilib/servlet/DigilibWorker.java Wed Jul 14 16:36:42 2010 +0200 +++ b/servlet/src/digilib/servlet/DigilibWorker.java Wed Aug 25 18:29:08 2010 +0200 @@ -1,4 +1,4 @@ - /* DigilibWorker.java -- image operation worker +/* DigilibWorker.java -- image operation worker * * Digital Image Library servlet components *
--- a/servlet/src/digilib/servlet/DocumentBean.java Wed Jul 14 16:36:42 2010 +0200 +++ b/servlet/src/digilib/servlet/DocumentBean.java Wed Aug 25 18:29:08 2010 +0200 @@ -128,7 +128,7 @@ * return a list of authorization roles needed for request to access the * specified path */ - public List rolesForPath(DigilibRequest request) throws AuthOpException { + public List<String> rolesForPath(DigilibRequest request) throws AuthOpException { logger.debug("rolesForPath"); return useAuthentication ? authOp.rolesForPath(request) : null; } @@ -136,7 +136,7 @@ /** * check request authorization against a list of roles */ - public boolean isRoleAuthorized(List roles, DigilibRequest request) { + public boolean isRoleAuthorized(List<String> roles, DigilibRequest request) { logger.debug("isRoleAuthorized"); return useAuthentication ? authOp.isRoleAuthorized(roles, request) : true;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/servlet/src/digilib/servlet/ImageJobInformation.java Wed Aug 25 18:29:08 2010 +0200 @@ -0,0 +1,664 @@ +package digilib.servlet; + +import java.awt.geom.AffineTransform; +import java.awt.geom.NoninvertibleTransformException; +import java.awt.geom.Rectangle2D; +import java.io.IOException; +import java.util.StringTokenizer; + +import javax.servlet.http.HttpServletRequest; + +import org.apache.log4j.Logger; + +import digilib.image.ImageOpException; +import digilib.image.ImageOps; +import digilib.image.ImageSize; +import digilib.io.DocuDirCache; +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 + * + */ + +public class ImageJobInformation extends ParameterMap { + + String[] parameter_list = {"fn","pn","dw","dh", + "wx", "wy", "ww", "wh", "ws", + "mo", "rot", "cont", "brgt", "rgbm", "rbgm", + "ddpi", "ddpix", "ddpiy", "scale"}; + DigilibConfiguration dlConfig = null; + protected static Logger logger = Logger.getLogger("digilib.servlet"); + + ImageFile fileToLoad = null; + ImageFileset fileset=null; + String FilePath = null; + ImageSize expectedSourceSize = null; + Float scaleXY = null; + Rectangle2D userImgArea = null; + Rectangle2D outerUserImgArea= null; + Boolean imageSendable = null; +// Integer paramDW = null; +// Integer paramDH + public ImageJobInformation(DigilibConfiguration dlcfg) { + super(30); + + // 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", "", 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'); + + /* + * Parameters of type 'i' are not exchanged between client and server, + * but are for the servlets or JSPs internal use. + */ + + // url of the page/document (first part, may be empty) + newParameter("request.path", "", null, 'i'); + // base URL (from http:// to below /servlet) + newParameter("base.url", "", null, 'i'); + + /* + * Parameters of type 'c' are for the clients use + */ +/* + // "real" filename + newParameter("img.fn", "", null, 'c'); + // image dpi x + newParameter("img.dpix", new Integer(0), null, 'c'); + // image dpi y + newParameter("img.dpiy", new Integer(0), null, 'c'); + // hires image size x + newParameter("img.pix_x", new Integer(0), null, 'c'); + // hires image size y + newParameter("img.pix_y", new Integer(0), null, 'c'); + // total number of pages + newParameter("pt", new Integer(0), null, 'c'); + // display level of digilib (0 = just image, 1 = one HTML page + // 2 = in frameset, 3 = XUL-'frameset' + // 4 = XUL-Sidebar ) + newParameter("lv", new Integer(2), null, 'c'); + // marks + newParameter("mk", "", null, 'c'); +*/ + dlConfig = dlcfg; + } + + + + public void setWithRequest(HttpServletRequest request) { + for (String param : parameter_list){ + if (request.getParameterMap().containsKey(param)){ + this.setValueFromString(param, request.getParameter(param)); + } + } + setValueFromString("request.path", ((HttpServletRequest) request).getPathInfo()); + String[] baseurl_parts = ((HttpServletRequest) request).getRequestURL().toString().split("/"); + String baseurl = ""; + for(int i=0; i<baseurl_parts.length-2; i++){ + baseurl += baseurl_parts[i]+"/"; + } + setValueFromString("base.url", baseurl); + } + + public String[] getParameterList(){ + return parameter_list; + } + + + public boolean hasOption(String param, String opt) { + String s = getAsString(param); + if (s != null) { + StringTokenizer i = new StringTokenizer(s, ","); + while (i.hasMoreTokens()) { + if (i.nextToken().equals(opt)) { + return true; + } + } + } + return false; + } + + + public String get_mimeType() { + String mimeType = "image/png"; + + + ImageFile fileToLoad; + try { + + fileToLoad = get_fileToLoad(); + + if(!get_fileToLoad().isChecked()){ + ImageOps.checkFile(fileToLoad); + } + + + if(fileToLoad != null) + mimeType = fileToLoad.getMimetype(); + + } catch (IOException e) { + e.printStackTrace(); + } catch (ImageOpException e) { + e.printStackTrace(); + } + + + return mimeType; + } + + public ImageFile get_fileToLoad() throws IOException, ImageOpException{ + + if(fileToLoad == null){ + ImageFileset fileset = get_fileset(); + + /* select a resolution */ + if (get_hiresOnly()) { + // get first element (= highest resolution) + fileToLoad = fileset.getBiggest(); + } else if (get_loresOnly()) { + // enforced lores uses next smaller resolution + fileToLoad = fileset.getNextSmaller(get_expectedSourceSize()); + if (fileToLoad == null) { + // this is the smallest we have + fileToLoad = fileset.getSmallest(); + } + } else { + // autores: use next higher resolution + fileToLoad = fileset.getNextBigger(get_expectedSourceSize()); + if (fileToLoad == null) { + // this is the highest we have + fileToLoad = fileset.getBiggest(); + } + } + logger.info("Planning to load: " + fileToLoad.getFile()); + } + + return fileToLoad; + + } + + public ImageFileset get_fileset() 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 get_hiresOnly(){ + return hasOption("mo","clip") || hasOption("mo","osize") || hasOption("mo","hires"); + } + + public boolean get_loresOnly(){ + + return hasOption("mo","lores"); + } + + public boolean get_scaleToFit() { + + return !(hasOption("mo","clip") || hasOption("mo","osize") || hasOption("mo","ascale")); + } + + public boolean get_absoluteScale(){ + + return hasOption("mo","osize") || hasOption("mo","ascale"); + } + + + public ImageSize get_expectedSourceSize() throws IOException, ImageOpException{ + + if (expectedSourceSize == null){ + expectedSourceSize = new ImageSize(); + + if (get_scaleToFit()) { + // scale to fit -- calculate minimum source size + float scale = (1 / Math.min(getAsFloat("ww"), getAsFloat("wh"))) * getAsFloat("ws"); + expectedSourceSize.setSize((int) (getAsInt("dw") * scale), + (int) (getAsInt("dh") * scale)); + } else if (get_absoluteScale() && hasOption("mo", "ascale")) { + // absolute scale -- apply scale to hires size + expectedSourceSize = get_hiresSize().getScaled(getAsFloat("scale")); + } else { + // clip to fit -- source = destination size + expectedSourceSize.setSize((int) (getAsInt("dw") * getAsFloat("ws")), + (int) (getAsInt("dh") * getAsFloat("ws"))); + } + } + return expectedSourceSize; + } + + public ImageSize get_hiresSize() throws IOException, ImageOpException{ + logger.debug("get_hiresSize()"); + + ImageSize hiresSize = null; + ImageFileset fileset = get_fileset(); + if (get_absoluteScale()) { + ImageFile hiresFile = fileset.getBiggest(); + if (!hiresFile.isChecked()) { + ImageOps.checkFile(hiresFile); + } + hiresSize = hiresFile.getSize(); + + /* prepare resolution and scale factor for original size */ + if (hasOption("mo", "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 :-( + setValue("scale", (sx + sy)/2f); + } + + } + return hiresSize; + + } + + public float get_scaleXY() throws IOException, ImageOpException{ + //logger.debug("get_scaleXY()"); + if(scaleXY == null){ + // coordinates and scaling + float areaWidth; + float areaHeight; + float scaleX; + float scaleY; + ImageSize imgSize = get_fileToLoad().getSize(); + ImageSize hiresSize = get_hiresSize(); + // coordinates using Java2D + // image size in pixels + // Rectangle2D imgBounds = new Rectangle2D.Float(0, 0, imgSize + // .getWidth(), imgSize.getHeight()); + // user window area in [0,1] coordinates + Rectangle2D relUserArea = new Rectangle2D.Float(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 + Rectangle2D userImgArea = imgTrafo.createTransformedShape( + relUserArea).getBounds2D(); + + // calculate scaling factors based on inner user area + if (get_scaleToFit()) { + areaWidth = (float) userImgArea.getWidth(); + areaHeight = (float) userImgArea.getHeight(); + scaleX = get_paramDW() / areaWidth * getAsFloat("ws"); + scaleY = get_paramDH() / areaHeight * getAsFloat("ws"); + scaleXY = (scaleX > scaleY) ? scaleY : scaleX; + } else if (get_absoluteScale()) { + scaleXY = getAsFloat("scale"); + // we need to correct the factor if we use a pre-scaled image + if (imgSize.getWidth() != hiresSize.getWidth()) { + scaleXY *= (float)hiresSize.getWidth() / (float)imgSize.getWidth(); + } + //scaleX = scaleXY; + //scaleY = scaleXY; + areaWidth = get_paramDW() / scaleXY * getAsFloat("ws"); + areaHeight = get_paramDH() / scaleXY * getAsFloat("ws"); + // reset user area size + userImgArea.setRect(userImgArea.getX(), userImgArea.getY(), + areaWidth, areaHeight); + } else { + // crop to fit + areaWidth = get_paramDW() * getAsFloat("ws"); + areaHeight = get_paramDH() * getAsFloat("ws"); + // reset user area size + userImgArea.setRect(userImgArea.getX(), userImgArea.getY(), + areaWidth, areaHeight); + scaleX = 1f; + scaleY = 1f; + scaleXY = 1f; + } + } + + return (float) scaleXY; + } + + public int get_paramDW(){ + logger.debug("get_paramDW()"); + + int paramDW = getAsInt("dw"); + int paramDH = getAsInt("dh"); + + float imgAspect; + try { + imgAspect = get_fileToLoad().getAspect(); + if (paramDW == 0) { + paramDW = (int) Math.round(paramDH * imgAspect); + setValue("dw", paramDW); + } else if (paramDH == 0) { + setValue("dh", (int) Math.round(paramDW / imgAspect)); + } + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (ImageOpException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return paramDW; + } + + public int get_paramDH(){ + logger.debug("get_paramDH()"); + + int paramDW = getAsInt("dw"); + int paramDH = getAsInt("dh"); + + float imgAspect; + try { + imgAspect = get_fileToLoad().getAspect(); + if (paramDW == 0) { + setValue("dw", (int) Math.round(paramDH * imgAspect)); + } else if (paramDH == 0) { + paramDH = (int) Math.round(paramDW / imgAspect); + setValue("dh", paramDH ); + } + + + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (ImageOpException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return paramDH; + } + public Integer get_scaleQual(){ + logger.debug("get_scaleQual()"); + + Integer qual = dlConfig.getAsInt("default-quality"); + if(hasOption("mo","q0")) + qual = 0; + else if(hasOption("mo","q1")) + qual = 1; + else if(hasOption("mo","q2")) + qual = 2; + return qual; + } + + + public ImageSize get_imgSize() throws IOException, ImageOpException{ + + ImageSize imgSize = get_fileToLoad().getSize(); + return imgSize; + } + + public Rectangle2D get_userImgArea() throws IOException, ImageOpException{ + //logger.debug("get_userImgArea()"); + + if(userImgArea==null){ + // transform from relative [0,1] to image coordinates. + AffineTransform imgTrafo = AffineTransform.getScaleInstance(get_imgSize() + .getWidth(), get_imgSize().getHeight()); + + // user window area in [0,1] coordinates + Rectangle2D relUserArea = new Rectangle2D.Float(getAsFloat("wx"), getAsFloat("wy"), + getAsFloat("ww"), getAsFloat("wh")); + + // transform user coordinate area to image coordinate area + userImgArea = imgTrafo.createTransformedShape( + relUserArea).getBounds2D(); + + if(get_absoluteScale()){ + float areaWidth = getAsInt("dw") / get_scaleXY() * getAsFloat("ws"); + float areaHeight = getAsInt("dh") / get_scaleXY() * getAsFloat("ws"); + // reset user area size + userImgArea.setRect(userImgArea.getX(), userImgArea.getY(), + areaWidth, areaHeight); + } else if (!get_scaleToFit()){ + // crop to fit + float areaWidth = getAsInt("dw") * getAsFloat("ws"); + float areaHeight = getAsInt("dh") * getAsFloat("ws"); + // reset user area size + userImgArea.setRect(userImgArea.getX(), userImgArea.getY(), + areaWidth, areaHeight); + } + } + return userImgArea; + + } + + public Rectangle2D get_outerUserImgArea() throws IOException, ImageOpException{ + //logger.debug("get_outerUserImgArea()"); + + if(outerUserImgArea == null){ + Rectangle2D userImgArea = get_userImgArea(); + + // image size in pixels + Rectangle2D imgBounds = new Rectangle2D.Float(0, 0, get_imgSize() + .getWidth(), get_imgSize().getHeight()); + + + + + outerUserImgArea = userImgArea; + Rectangle2D innerUserImgArea = userImgArea; + if (get_wholeRotArea()) { + if (getAsFloat("rot") != 0) { + try { + // rotate user area coordinates around center of user + // area + AffineTransform rotTrafo = AffineTransform + .getRotateInstance(Math.toRadians(getAsFloat("rot")), + userImgArea.getCenterX(), userImgArea + .getCenterY()); + // get bounds from rotated end position + innerUserImgArea = rotTrafo.createTransformedShape( + userImgArea).getBounds2D(); + // get bounds from back-rotated bounds + outerUserImgArea = rotTrafo.createInverse() + .createTransformedShape(innerUserImgArea) + .getBounds2D(); + } catch (NoninvertibleTransformException e1) { + // this shouldn't happen anyway + logger.error(e1); + } + } + } + + // logger.debug("Scale " + scaleXY + "(" + scaleX + "," + scaleY + //+ ") on " + outerUserImgArea); + + // clip area at the image border + outerUserImgArea = outerUserImgArea.createIntersection(imgBounds); + + // check image parameters sanity + logger.debug("outerUserImgArea.getWidth()=" + outerUserImgArea.getWidth()); + logger.debug("get_scaleXY() * outerUserImgArea.getWidth() = " + (get_scaleXY() * outerUserImgArea.getWidth())); + + if ((outerUserImgArea.getWidth() < 1) + || (outerUserImgArea.getHeight() < 1) + || (get_scaleXY() * outerUserImgArea.getWidth() < 2) + || (get_scaleXY() * outerUserImgArea.getHeight() < 2)) { + logger.error("ERROR: invalid scale parameter set!"); + throw new ImageOpException("Invalid scale parameter set!"); + } + } + return outerUserImgArea; + } + + + public Rectangle2D get_innerUserImgArea() throws IOException, ImageOpException{ + logger.debug("get_innerUserImgArea()"); + + Rectangle2D userImgArea = get_userImgArea(); + Rectangle2D innerUserImgArea = get_userImgArea(); + if (get_wholeRotArea()) { + if (getAsFloat("rot") != 0) { + // rotate user area coordinates around center of user + // area + AffineTransform rotTrafo = AffineTransform + .getRotateInstance(Math.toRadians(getAsFloat("rot")), + userImgArea.getCenterX(), userImgArea + .getCenterY()); + // get bounds from rotated end position + innerUserImgArea = rotTrafo.createTransformedShape( + userImgArea).getBounds2D(); + } + } + return innerUserImgArea; + + } + public boolean get_wholeRotArea(){ + // TODO this is not really implemented yet + //boolean wholeRotArea = false; + return false;//wholeRotArea; + } + + public int get_forceType(){ + + if(hasOption("mo","jpg")) + return ImageOps.TYPE_JPEG; + if(hasOption("mo","png")) + return ImageOps.TYPE_PNG; + + return ImageOps.TYPE_AUTO; + } + + public float[] get_paramRGBM(){ + logger.debug("get_paramRGBM()"); + + float[] paramRGBM = null;//{0f,0f,0f}; + Parameter p = get("rgbm"); + if (p.hasValue() && (!p.getAsString().equals("0/0/0"))) { + return p.parseAsFloatArray("/"); + } + return paramRGBM; + } + + public float[] get_paramRGBA(){ + logger.debug("get_paramRGBA()"); + + float[] paramRGBA = null;//{0f,0f,0f}; + Parameter p = get("rgba"); + if (p.hasValue() && (!p.getAsString().equals("0/0/0"))) { + paramRGBA = p.parseAsFloatArray("/"); + } + return paramRGBA; + } + + public boolean get_hmir(){ + logger.debug("get_hmir()"); + + return hasOption("mo","hmir"); + } + + public boolean get_vmir(){ + logger.debug("get_vmir()"); + + return hasOption("mo","vmir"); + } + + public boolean checkSendAsFile(){ + return hasOption("mo", "file") + || hasOption("mo", "rawfile"); + } + + public boolean get_imageSendable(){ + if(imageSendable==null){ + String mimeType = get_mimeType(); + imageSendable = ( (mimeType.equals("image/jpeg") + || mimeType.equals("image/png") + || mimeType.equals("image/gif") ) + && + !(hasOption("mo", "hmir") + || hasOption("mo", "vmir") + || (getAsFloat("rot") != 0) + || (get_paramRGBM() != null) + || (get_paramRGBA() != null) + || (getAsFloat("cont") != 0) + || (getAsFloat("brgt") != 0))); + } + + return imageSendable; + } + + + public boolean noTransformRequired(){ + try { + return get_imageSendable() && ((get_loresOnly() && get_fileToLoad().getSize().isSmallerThan( + get_expectedSourceSize())) || (!(get_loresOnly() || get_hiresOnly()) && get_fileToLoad() + .getSize().fitsIn(expectedSourceSize))); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (ImageOpException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return false; + } +} \ No newline at end of file
--- a/servlet/src/digilib/servlet/Initialiser.java Wed Jul 14 16:36:42 2010 +0200 +++ b/servlet/src/digilib/servlet/Initialiser.java Wed Aug 25 18:29:08 2010 +0200 @@ -32,6 +32,7 @@ import digilib.auth.AuthOps; import digilib.auth.XMLAuthOps; +import digilib.image.DocuImage; import digilib.image.ImageOps; import digilib.io.AliasingDocuDirCache; import digilib.io.DocuDirCache; @@ -48,7 +49,7 @@ private static final long serialVersionUID = -5126621114382549343L; /** servlet version */ - public static final String iniVersion = "0.2"; + public static final String iniVersion = "0.1b2"; /** gengeral logger for this class */ private static Logger logger = Logger.getLogger("digilib.init"); @@ -128,11 +129,9 @@ dlConfig.setValue("auth-file", authConf); } // DocuImage class - Class cl = Class.forName(dlConfig - .getAsString("docuimage-class")); - dlConfig.setDocuImageClass(cl); - dlConfig.setValue("servlet.docuimage.class", cl.getName()); - ImageOps.setDocuImage(dlConfig.getDocuImageInstance()); + DocuImage di = dlConfig.getDocuImageInstance(); + dlConfig.setValue("servlet.docuimage.class", di.getClass().getName()); + ImageOps.setDocuImage(di); // worker threads int nt = dlConfig.getAsInt("worker-threads"); DigilibWorker.setSemaphore(nt, true);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/servlet/src/digilib/servlet/NumRange.java Wed Aug 25 18:29:08 2010 +0200 @@ -0,0 +1,164 @@ +/** + * + */ +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<Integer> { + + private Integer start = 1; + private Integer end = Integer.MAX_VALUE; + private List<Integer> 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<Integer> pgs = new ArrayList<Integer>(); + + 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]); + 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); + } + } + + @Override + public Iterator<Integer> iterator() { + if (list == null) { + // return count-based iterator + return new Iterator<Integer>() { + // anonymous inner Iterator class + private int num = getStart(); + private int end = getEnd(); + + @Override + public boolean hasNext() { + return (num < end); + } + + @Override + public Integer next() { + return num++; + } + + @Override + public void remove() { + // don't do this + } + }; + } else { + // return list-based iterator + return new Iterator<Integer>() { + // anonymous inner Iterator class + private int listidx = 0; + private int listend = list.size(); + private int num = getStart(); + private int end = getEnd(); + + @Override + public boolean hasNext() { + return (num < end); + } + + @Override + public Integer next() { + if (listidx < listend) { + num = list.get(listidx++); + return num; + } else { + return num++; + } + } + + @Override + public void remove() { + // don't do this + } + }; + } + } + + public void setMaxnum(Integer maxnum) { + this.maxnum = maxnum; + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/servlet/src/digilib/servlet/PDFCache.java Wed Aug 25 18:29:08 2010 +0200 @@ -0,0 +1,300 @@ +package digilib.servlet; + +import java.io.BufferedInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; + +import javax.servlet.RequestDispatcher; +import javax.servlet.ServletConfig; +import javax.servlet.ServletContext; +import javax.servlet.ServletException; +import javax.servlet.ServletOutputStream; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * A class for handling user requests for pdf documents from digilib images. + * + * If a document does not already exist, it will be enqueued for generation; if it does exist, it is sent + * to the user. + * + * @author cmielack + * + */ + +@SuppressWarnings("serial") +public class PDFCache extends RequestHandler { + + private DigilibConfiguration dlConfig = null; + + public static String instanceKey = "digilib.servlet.PDFCache"; + + private File cache_directory = new File("cache"); + + private File temp_directory = new File("pdf_temp"); + + private static String JSP_WIP = "/pdf/wip.jsp"; + + private static String JSP_ERROR = "/pdf/error.jsp"; + + public static Integer STATUS_DONE = 0; // document exists in cache + + public static Integer STATUS_WIP = 1; // document is "work in progress" + + public static Integer STATUS_NONEXISTENT = 2; // document does not exist in cache and is not in progress + + public static Integer STATUS_ERROR = 3; // an error occurred while processing the request + + public static String version = "0.2"; + + private ServletContext context = null; + + + // TODO ? functionality for the pre-generation of complete books/chapters using default values + + + public void init(ServletConfig config) throws ServletException{ + super.init(config); + + System.out.println("***** Digital Image Library Image PDF-Cache Servlet (version " + + version + ") *****"); +// say hello in the log file + logger.info("***** Digital Image Library Image PDF-Cache Servlet (version " + + version + ") *****"); + + context = config.getServletContext(); + dlConfig = (DigilibConfiguration) context.getAttribute("digilib.servlet.configuration"); + if (dlConfig == null) { + // no Configuration + throw new ServletException("No Configuration!"); + } + + String temp_fn = dlConfig.getAsString("pdf-temp-dir"); + temp_directory = new File(temp_fn); + 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); + if (!cache_directory.isDirectory()) { + throw new ServletException("Configuration error: problem with pdf-cache-dir="+cache_fn); + } + + // register this instance globally + context.setAttribute(instanceKey, this); + + } + + /** + * clean up any broken and unfinished files from the temporary directory. + */ + public void emptyDirectory(File temp_dir){ + File[] temp_files = temp_dir.listFiles(); + + for (File f: temp_files){ + f.delete(); + } + } + + + + @Override + public void processRequest(HttpServletRequest request, + HttpServletResponse response) { + + // evaluate request ( make a PDFJobDeclaration , get the DocumentId) + PDFJobInformation pdfji = new PDFJobInformation(dlConfig); + pdfji.setWithRequest(request); + + String docid = pdfji.getDocumentId(); + + // if some invalid data has been entered ... + if(!pdfji.checkValidity()) { + notifyUser(STATUS_ERROR, docid, request, response); + return; + } + + int status = getStatus(docid); + + if (status == STATUS_NONEXISTENT) { + createNewPdfDocument(pdfji, docid); + notifyUser(status, docid, request, response); + } else if (status == STATUS_DONE) { + try { + sendFile(docid, downloadFilename(pdfji), response); + } catch (IOException e) { + e.printStackTrace(); + logger.error(e.getMessage()); + } + } else { + notifyUser(status, docid, request, response); + } + } + + /** + * depending on the documents status, redirect the user to an appropriate waiting- or download-site + * + * @param status + * @param documentid + * @param request + * @param response + */ + public void notifyUser(int status, String documentid, HttpServletRequest request, HttpServletResponse response){ + + String jsp=null; + + if(status == STATUS_NONEXISTENT){ + // tell the user that the document has to be created before he/she can download it + logger.debug("PDFCache: "+documentid+" has STATUS_NONEXISTENT."); + jsp = JSP_WIP; + } else if(status == STATUS_WIP){ + logger.debug("PDFCache: "+documentid+" has STATUS_WIP."); + jsp = JSP_WIP; + + // estimate remaining work time + // tell the user he/she has to wait + } else if(status == STATUS_DONE){ + logger.debug("PDFCache: "+documentid+" has STATUS_DONE."); + } else { + logger.debug("PDFCache: "+documentid+" has STATUS_ERROR."); + jsp = JSP_ERROR; + } + + RequestDispatcher dispatch = context.getRequestDispatcher(jsp); + + try { + dispatch.forward(request, response); + } catch (ServletException e) { + logger.debug(e.getMessage()); + e.printStackTrace(); + } catch (IOException e) { + logger.debug(e.getMessage()); + e.printStackTrace(); + } + + } + + + /** check the status of the document corresponding to the documentid */ + public Integer getStatus(String documentid){ + // looks into the cache and temp directory in order to find out the status of the document + File cached = new File(cache_directory, documentid); + File wip = new File(temp_directory, documentid); + if(cached.exists()){ + return STATUS_DONE; + } else if (wip.exists()){ + return STATUS_WIP; + } else { + return STATUS_NONEXISTENT; + } + } + + /** + * create new thread for pdf generation. + * + * @param pdfji + * @param filename + */ + public void createNewPdfDocument(PDFJobInformation pdfji, String filename){ + // start new worker + PDFMaker pdf_maker = new PDFMaker(context, pdfji,filename); + new Thread(pdf_maker, "PDFMaker").start(); + } + + + /** + * generate the filename the user is going to receive the pdf as + * + * @param pdfji + * @return + */ + public String downloadFilename(PDFJobInformation pdfji){ + // filename example: digilib_example_pgs1-3.pdf + String filename; + filename = "digilib_"; + filename += pdfji.getImageJobInformation().getAsString("fn"); + filename += "_pgs" + pdfji.getAsString("pgs"); + filename += ".pdf"; + + return filename; + } + + /** + * sends a document to the user + * + * @param cachefile The filename of the document in cache. + * @param filename The filename used for downloading. + * @param response + * @throws IOException + */ + public void sendFile(String cachefile, String filename, HttpServletResponse response) throws IOException{ + File cached_file = null; + FileInputStream fis = null; + ServletOutputStream sos = null; + BufferedInputStream bis = null; + + try { + // get file handle + cached_file = new File(cache_directory, cachefile); + // create necessary streams + fis = new FileInputStream(cached_file); + sos = response.getOutputStream(); + bis = new BufferedInputStream(fis); + + int bytes = 0; + + // set http headers + response.setContentType("application/pdf"); + response.addHeader("Content-Disposition", "attachment; filename="+filename); + response.setContentLength( (int) cached_file.length()); + + // send the bytes + while ((bytes = bis.read()) != -1){ + sos.write(bytes); + } + } + catch(Exception e){ + logger.error(e.getMessage()); + } + finally{ + // close all streams + if (fis != null) + fis.close(); + if (bis != null) + bis.close(); + if (sos != null) + sos.close(); + } + + } + + public File getCacheDirectory(){ + return cache_directory; + } + + public File getTempDirectory(){ + return temp_directory; + } + + /** + * returns a File object based on filename in the temp directory. + * @param filename + * @return + */ + public File getTempFile(String filename) { + return new File(temp_directory, filename); + } + + /** + * returns a File object based on filename in the cache directory. + * @param filename + * @return + */ + public File getCacheFile(String filename) { + return new File(cache_directory, filename); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/servlet/src/digilib/servlet/PDFJobInformation.java Wed Aug 25 18:29:08 2010 +0200 @@ -0,0 +1,185 @@ +package digilib.servlet; + +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; +import java.util.ArrayList; + +import javax.servlet.http.HttpServletRequest; + +import org.apache.log4j.Logger; + + +/** + * A container class for storing a set of instruction parameters + * used for content generator classes like MakePDF. + * + * + * @author cmielack + * + */ +@SuppressWarnings("serial") +public class PDFJobInformation extends ParameterMap { + + String[] parameter_list = {"pgs"}; // all other parameters get passed into an extra ImageJobInformation + // (this should be redesigned later...) + + + ImageJobInformation image_info = null; + DigilibConfiguration dlConfig = null; + /** gengeral logger for this class */ + protected static Logger logger = Logger.getLogger("digilib.servlet"); + + + /** + * Initialize the PDFJobInformation + * + * @param dlcfg + * The DigilibConfiguration. + */ + public PDFJobInformation(DigilibConfiguration dlcfg) { + super(30); + + // page numbers + newParameter("pgs", "", null, 's'); + dlConfig = dlcfg; + + } + + + /** + * Read in the request object. + * + * @param request + */ + public void setWithRequest(HttpServletRequest request) { + image_info = new ImageJobInformation(dlConfig); + image_info.setWithRequest(request); + + for (String param : parameter_list){ + if (request.getParameterMap().containsKey(param)){ + setValueFromString(param, request.getParameter(param)); + } + } + } + + + /** + * Generate the filename of the pdf to be created. + * + * @return + */ + public String getDocumentId(){ + String id; + + // TODO use complete request information for id generation + + if(this.image_info!=null){ + String fn = image_info.getAsString("fn"); + String dh = image_info.getAsString("dh"); + String pgs = getAsString("pgs"); + + id = "fn=" + fn + "&dh=" + dh + "&pgs=" + pgs + ".pdf"; + // make safe to use as filename by urlencoding + try { + id = URLEncoder.encode(id, "UTF-8"); + } catch (UnsupportedEncodingException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + else { + id = null; + } + + return id; + } + + + public ImageJobInformation getImageJobInformation(){ + ImageJobInformation new_image_info = (ImageJobInformation) image_info.clone(); + return new_image_info; + } + + + /** + * Convert the "pgs"-Parameter to an Array of Integers. + * + * @return + * @throws Exception + */ + public Integer[] getPageNrs() throws Exception{ + + String pages = getAsString("pgs"); + ArrayList<Integer> pgs = new ArrayList<Integer>(); + Integer[] out = null; + + 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]); + int end = Integer.valueOf(nums[1]); + for(int i = start; i <= end; i++){ + // add all numbers to list + pgs.add(i); + } + } + else{ + pgs.add(Integer.valueOf(interval)); + } + } + out = new Integer[pgs.size()]; + + pgs.toArray(out); + return out; + } + + + /** + * Check parameters for validity. + * Returns true if no errors are found. + * + * @return + */ + public boolean checkValidity(){ + String pgs = getAsString("pgs"); + try{ + String[] intervals = null; + if(pgs.indexOf(",")>0){ + intervals = pgs.split(","); + } + else{ + intervals = new String[1]; + intervals[0]=pgs; + } + for(String interval:intervals){ + if(interval.indexOf("-")>=0){ + String[] intrvl = interval.split("-"); + int a = Integer.valueOf(intrvl[0]); + int b = Integer.valueOf(intrvl[1]); + if(a<=0 || b<a){ + return false; + } + } + else { + int c = Integer.valueOf(interval); + if(c<=0) + return false; + + } + } + } + catch(Exception e){ + logger.error("invalid pgs-input"); + return false; + } + return true; + } + + public DigilibConfiguration getDlConfig(){ + return dlConfig; + } + +} \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/servlet/src/digilib/servlet/PDFMaker.java Wed Aug 25 18:29:08 2010 +0200 @@ -0,0 +1,74 @@ +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 PDFJobInformation 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, PDFJobInformation pdfji, String filename){ + this.job_info = pdfji; + this.filename = filename; + this.dlConfig = pdfji.getDlConfig(); + this.context = context; + } + + public void run() { + + if (! DigilibWorker.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 + } + } + + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/servlet/src/digilib/servlet/PDFTitlePage.java Wed Aug 25 18:29:08 2010 +0200 @@ -0,0 +1,181 @@ +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 PDFJobInformation 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(PDFJobInformation 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<x.length-1; i++){ + newpath += x[i]+"/"; + } + return newpath; + } + else + return ""; + } + + + /** + * Methods for the different attributes. + * + */ + + + private Image getLogo(){ + try { + URL url = new URL(job_info.getDlConfig().getAsString("pdf-logo")); + if(url!=null && !url.equals("")){ + Image logo = Image.getInstance(url); + logo.setAlignment(Element.ALIGN_CENTER); + return logo; + } + } catch (BadElementException e) { + logger.error(e.getMessage()); + e.printStackTrace(); + } catch (MalformedURLException e) { + logger.error(e.getMessage()); + e.printStackTrace(); + } catch (IOException e) { + logger.error(e.getMessage()); + e.printStackTrace(); + } + return null; + } + private String getTitle(){ + if(info_reader.hasInfo()) + return info_reader.getAsString("title"); + else + return job_info.getImageJobInformation().getAsString("fn"); + } + private String getAuthor(){ + if(info_reader.hasInfo()) + return info_reader.getAsString("author"); + else + return " "; + } + private String getDate(){ + if(info_reader.hasInfo()) + return info_reader.getAsString("date"); + else + return " "; + } + private String getPages(){ + return "Pages "+job_info.getAsString("pgs") + " (scan page numbers)"; + } + + private String getDigilibVersion(){ + return "Digilib PDFMaker v."+PDFMaker.version; + } + +}
--- a/servlet/src/digilib/servlet/Parameter.java Wed Jul 14 16:36:42 2010 +0200 +++ b/servlet/src/digilib/servlet/Parameter.java Wed Aug 25 18:29:08 2010 +0200 @@ -102,7 +102,7 @@ this.value = val; return true; } - Class c = defval.getClass(); + Class<? extends Object> c = defval.getClass(); // take String as is if (c == String.class) { this.value = val;
--- a/servlet/src/digilib/servlet/ParameterMap.java Wed Jul 14 16:36:42 2010 +0200 +++ b/servlet/src/digilib/servlet/ParameterMap.java Wed Aug 25 18:29:08 2010 +0200 @@ -30,7 +30,7 @@ * @author casties * */ -public class ParameterMap extends HashMap { +public class ParameterMap extends HashMap<String, Parameter> { private static final long serialVersionUID = 1530820988748391313L; @@ -56,7 +56,7 @@ * @return */ public Parameter get(String key) { - return (Parameter) super.get(key); + return super.get(key); } /** Get the Parameter with the corresponding key. @@ -67,7 +67,7 @@ * @return */ public Object getValue(String key) { - Parameter p = (Parameter) super.get(key); + Parameter p = super.get(key); return (p != null) ? p.getValue() : null; } @@ -79,7 +79,7 @@ * @return */ public String getAsString(String key) { - Parameter p = (Parameter) super.get(key); + Parameter p = super.get(key); return (p != null) ? p.getAsString() : null; } @@ -91,7 +91,7 @@ * @return */ public int getAsInt(String key) { - Parameter p = (Parameter) super.get(key); + Parameter p = super.get(key); return (p != null) ? p.getAsInt() : 0; } @@ -103,7 +103,7 @@ * @return */ public float getAsFloat(String key) { - Parameter p = (Parameter) super.get(key); + Parameter p = super.get(key); return (p != null) ? p.getAsFloat() : 0f; } @@ -115,7 +115,7 @@ * @return */ public boolean getAsBoolean(String key) { - Parameter p = (Parameter) super.get(key); + Parameter p = super.get(key); return (p != null) ? p.getAsBoolean() : false; } @@ -125,7 +125,7 @@ * @return */ public boolean hasValue(String key) { - Parameter p = (Parameter) super.get(key); + Parameter p = super.get(key); return (p != null) ? p.hasValue() : false; } @@ -138,7 +138,7 @@ * @return */ public Parameter put(String key, Parameter val) { - return (Parameter) super.put(key, val); + return super.put(key, val); } /** Add the Parameter val to the map, using val's name. @@ -149,7 +149,7 @@ * @return */ public Parameter put(Parameter val) { - return (Parameter) super.put(val.getName(), val); + return super.put(val.getName(), val); } /** Add a new Parameter with name, default and value. @@ -163,7 +163,7 @@ */ public Parameter newParameter(String name, Object def, Object val) { Parameter p = new Parameter(name, def, val); - return (Parameter) super.put(name, p); + return super.put(name, p); } /** Add a new Parameter with name, default, value and type. @@ -178,7 +178,7 @@ */ public Parameter newParameter(String name, Object def, Object val, int type) { Parameter p = new Parameter(name, def, val, type); - return (Parameter) super.put(name, p); + return super.put(name, p); } /** Set the value of an existing parameter.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/servlet/src/digilib/servlet/RequestHandler.java Wed Aug 25 18:29:08 2010 +0200 @@ -0,0 +1,82 @@ +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); + + +}
--- a/servlet/src/digilib/servlet/Scaler.java Wed Jul 14 16:36:42 2010 +0200 +++ b/servlet/src/digilib/servlet/Scaler.java Wed Aug 25 18:29:08 2010 +0200 @@ -1,74 +1,33 @@ -/* - * Scaler -- Scaler servlet main class - * - * Digital Image Library servlet components - * - * Copyright (C) 200-2004 Robert Casties (robcast@mail.berlios.de) - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or (at your option) - * any later version. - * - * Please read license.txt for the full details. A copy of the GPL may be found - * at http://www.gnu.org/copyleft/lgpl.html - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 59 Temple - * Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - package digilib.servlet; -import java.awt.geom.AffineTransform; -import java.awt.geom.NoninvertibleTransformException; -import java.awt.geom.Rectangle2D; import java.io.File; import java.io.IOException; +import java.io.OutputStream; import java.util.List; 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.ImageOpException; -import digilib.image.ImageOps; -import digilib.image.ImageSize; import digilib.io.DocuDirCache; import digilib.io.DocuDirectory; import digilib.io.DocuDirent; import digilib.io.FileOpException; import digilib.io.FileOps; import digilib.io.ImageFile; -import digilib.io.ImageFileset; + -/** - * @author casties - */ -// public class Scaler extends HttpServlet implements SingleThreadModel { -public class Scaler extends HttpServlet { +// TODO digilibError is not used anymore and may need to get reintegrated - private static final long serialVersionUID = -325080527268912852L; +public class Scaler extends RequestHandler { /** digilib servlet version (for all components) */ - public static final String dlVersion = "1.7.1b"; - - /** logger for accounting requests */ - private static Logger accountlog = Logger.getLogger("account.request"); - - /** gengeral logger for this class */ - private static Logger logger = Logger.getLogger("digilib.servlet"); - - /** logger for authentication related */ - private static Logger authlog = Logger.getLogger("digilib.auth"); + public static final String dlVersion = "1.8.0a"; /** general error code */ public static final int ERROR_UNKNOWN = 0; @@ -116,8 +75,41 @@ /** try to enlarge cropping area for "oblique" angles */ boolean wholeRotArea = false; + + protected long getLastModified(HttpServletRequest request) { + accountlog.debug("GetLastModified from " + request.getRemoteAddr() + + " for " + request.getQueryString()); + long mtime = -1; + // create new request with defaults + DigilibRequest dlReq = new DigilibRequest(); + // set with request parameters + dlReq.setWithRequest(request); + // find the requested file + DocuDirent f = findFile(dlReq); + if (f != null) { + DocuDirectory dd = (DocuDirectory) f.getParent(); + mtime = dd.getDirMTime() / 1000 * 1000; + } + return mtime; + } + /** + * Returns the DocuDirent corresponding to the DigilibRequest. + * + * @param dlRequest + * @return + */ + public DocuDirent findFile(DigilibRequest dlRequest) { + // find the file(set) + DocuDirent f = dirCache.getFile(dlRequest.getFilePath(), dlRequest + .getAsInt("pn"), FileOps.CLASS_IMAGE); + return f; + } + + + /** * Initialisation on first run. + * @throws ServletException * * @see javax.servlet.Servlet#init(javax.servlet.ServletConfig) */ @@ -155,554 +147,161 @@ defaultQuality = dlConfig.getAsInt("default-quality"); } - /** Process the HTTP Get request */ - public void doGet(HttpServletRequest request, HttpServletResponse response) - throws ServletException, IOException { - accountlog.info("GET from " + request.getRemoteAddr()); - // create new request with defaults - DigilibRequest dlReq = new DigilibRequest(); - // set with request parameters - dlReq.setWithRequest(request); - // add DigilibRequest to ServletRequest - request.setAttribute("digilib.servlet.request", dlReq); - // do the processing - processRequest(request, response); - } + + + + @Override + public void processRequest(HttpServletRequest request, + HttpServletResponse response) throws ServletException, ImageOpException { - /** Process the HTTP Post request */ - public void doPost(HttpServletRequest request, HttpServletResponse response) - throws ServletException, IOException { - accountlog.info("POST from " + request.getRemoteAddr()); - // create new request with defaults - DigilibRequest dlReq = new DigilibRequest(); - // set with request parameters - dlReq.setWithRequest(request); - // add DigilibRequest to ServletRequest - request.setAttribute("digilib.servlet.request", dlReq); - // do the processing - processRequest(request, response); - } - - /* - * (non-Javadoc) - * - * @see javax.servlet.http.HttpServlet#getLastModified(javax.servlet.http.HttpServletRequest) - */ - protected long getLastModified(HttpServletRequest request) { - accountlog.debug("GetLastModified from " + request.getRemoteAddr() - + " for " + request.getQueryString()); - long mtime = -1; - // create new request with defaults - DigilibRequest dlReq = new DigilibRequest(); - // set with request parameters - dlReq.setWithRequest(request); - // find the requested file - DocuDirent f = findFile(dlReq); - if (f != null) { - DocuDirectory dd = (DocuDirectory) f.getParent(); - mtime = dd.getDirMTime() / 1000 * 1000; - } - return mtime; - } - - /** main request handler. */ -void processRequest(HttpServletRequest request, HttpServletResponse response) - throws ServletException { - + if (dlConfig == null) { throw new ServletException("ERROR: No Configuration!"); } - + accountlog.debug("request: " + request.getQueryString()); logger.debug("request: " + request.getQueryString()); - - // time for benchmarking - long startTime = System.currentTimeMillis(); - // output mime-type - String mimeType = "image/png"; - - /* preset request parameters */ - - // scale the image file to fit window size i.e. respect dw,dh - boolean scaleToFit = true; - // scale the image by a fixed factor only - boolean absoluteScale = false; - // use low resolution images only - boolean loresOnly = false; - // use hires images only - boolean hiresOnly = false; - // send the image always as a specific type (e.g. JPEG or PNG) - int forceType = ImageOps.TYPE_AUTO; - // interpolation to use for scaling - int scaleQual = defaultQuality; - // send html error message (or image file) - boolean errorMsgHtml = false; - // original (hires) image resolution - float origResX = 0; - float origResY = 0; - - /* request parameters */ - - DigilibRequest dlRequest = (DigilibRequest) request - .getAttribute("digilib.servlet.request"); + - // destination image width - int paramDW = dlRequest.getAsInt("dw"); - // destination image height - int paramDH = dlRequest.getAsInt("dh"); - // relative area x_offset (0..1) - float paramWX = dlRequest.getAsFloat("wx"); - // relative area y_offset - float paramWY = dlRequest.getAsFloat("wy"); - // relative area width (0..1) - float paramWW = dlRequest.getAsFloat("ww"); - // relative area height - float paramWH = dlRequest.getAsFloat("wh"); - // scale factor (additional to dw/width, dh/height) - float paramWS = dlRequest.getAsFloat("ws"); - // rotation angle - float paramROT = dlRequest.getAsFloat("rot"); - // contrast enhancement - float paramCONT = dlRequest.getAsFloat("cont"); - // brightness enhancement - float paramBRGT = dlRequest.getAsFloat("brgt"); - // color modification - float[] paramRGBM = null; - Parameter p = dlRequest.get("rgbm"); - if (p.hasValue() && (!p.getAsString().equals("0/0/0"))) { - paramRGBM = p.parseAsFloatArray("/"); - } - float[] paramRGBA = null; - p = dlRequest.get("rgba"); - if (p.hasValue() && (!p.getAsString().equals("0/0/0"))) { - paramRGBA = p.parseAsFloatArray("/"); + // define the job information + ImageJobInformation jobdeclaration = new ImageJobInformation(dlConfig); + jobdeclaration.setWithRequest(request); + + ImageFile fileToLoad = null; + try { + fileToLoad = jobdeclaration.get_fileToLoad(); + } catch (IOException e2) { + // TODO Auto-generated catch block + e2.printStackTrace(); + return; } - // destination resolution (DPI) - float paramDDPIX = dlRequest.getAsFloat("ddpix"); - float paramDDPIY = dlRequest.getAsFloat("ddpiy"); - if ((paramDDPIX == 0) || (paramDDPIY == 0)) { - // if X or Y resolution isn't set, use DDPI - paramDDPIX = dlRequest.getAsFloat("ddpi"); - paramDDPIY = paramDDPIX; - } - // absolute scale factor for mo=ascale (and mo=osize) - float paramSCALE = dlRequest.getAsFloat("scale"); + + + // if requested, send image as a file + if(sendFileAllowed && jobdeclaration.checkSendAsFile()){ + String mt = null; + if (jobdeclaration.hasOption("mo", "rawfile")) { + mt = "application/octet-stream"; + } + logger.debug("Sending RAW File as is."); + try { + ServletOps.sendFile(fileToLoad.getFile(), mt, response); + } catch (FileOpException e) { + e.printStackTrace(); + } - /* - * operation mode: "fit": always fit to page, "clip": send original - * resolution cropped, "file": send whole file (if allowed) - */ - if (dlRequest.hasOption("mo", "clip")) { - scaleToFit = false; - absoluteScale = false; - hiresOnly = true; - } else if (dlRequest.hasOption("mo", "fit")) { - scaleToFit = true; - absoluteScale = false; - hiresOnly = false; - } else if (dlRequest.hasOption("mo", "osize")) { - scaleToFit = false; - absoluteScale = true; - hiresOnly = true; - } else if (dlRequest.hasOption("mo", "ascale")) { - scaleToFit = false; - absoluteScale = true; - hiresOnly = false; + return; } - // operation mode: "lores": try to use scaled image, "hires": use - // unscaled image - // "autores": try best fitting resolution - if (dlRequest.hasOption("mo", "lores")) { - loresOnly = true; - hiresOnly = false; - } else if (dlRequest.hasOption("mo", "hires")) { - loresOnly = false; - hiresOnly = true; - } else if (dlRequest.hasOption("mo", "autores")) { - loresOnly = false; - hiresOnly = false; + + + // if possible, send the image without actually having to transform it + if(jobdeclaration.noTransformRequired()){ + logger.debug("Sending File as is."); + + try { + ServletOps.sendFile(fileToLoad.getFile(), null, response); + } catch (FileOpException e) { + e.printStackTrace(); + } + + //logger.info("Done in " + // + (System.currentTimeMillis() - startTime) + "ms"); + return; } - // operation mode: "errtxt": error message in html, "errimg": error - // image - if (dlRequest.hasOption("mo", "errtxt")) { - errorMsgHtml = true; - } else if (dlRequest.hasOption("mo", "errimg")) { - errorMsgHtml = false; + + + + + OutputStream outputstream = null; + try { + outputstream = response.getOutputStream(); + } catch (IOException e1) { + // TODO Auto-generated catch block + e1.printStackTrace(); + logger.error(e1.getMessage()); } - // operation mode: "q0" - "q2": interpolation quality - if (dlRequest.hasOption("mo", "q0")) { - scaleQual = 0; - } else if (dlRequest.hasOption("mo", "q1")) { - scaleQual = 1; - } else if (dlRequest.hasOption("mo", "q2")) { - scaleQual = 2; - } - // operation mode: "jpg": always use JPEG - if (dlRequest.hasOption("mo", "jpg")) { - forceType = ImageOps.TYPE_JPEG; - } - // operation mode: "png": always use PNG - if (dlRequest.hasOption("mo", "png")) { - forceType = ImageOps.TYPE_PNG; + + if (! DigilibWorker.canRun()) { + logger.error("Servlet overloaded!"); + try { + response.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE); + } catch (IOException e) { + e.printStackTrace(); + } + return; } - // check with the maximum allowed size (if set) - int maxImgSize = dlConfig.getAsInt("max-image-size"); - if (maxImgSize > 0) { - paramDW = (paramDW * paramWS > maxImgSize) ? (int) (maxImgSize / paramWS) - : paramDW; - paramDH = (paramDH * paramWS > maxImgSize) ? (int) (maxImgSize / paramWS) - : paramDH; - } - - // "big" try for all file/image actions + + DigilibWorker job=null; try { - - // ImageFileset of the image to load - ImageFileset fileset = null; - - /* find the file to load/send */ - - // get PathInfo - String loadPathName = dlRequest.getFilePath(); + + long startTime = System.currentTimeMillis(); /* check permissions */ if (useAuthorization) { // get a list of required roles (empty if no restrictions) - List rolesRequired = authOp.rolesForPath(loadPathName, request); - if (rolesRequired != null) { - authlog.debug("Role required: " + rolesRequired); - authlog.debug("User: " + request.getRemoteUser()); - // is the current request/user authorized? - if (!authOp.isRoleAuthorized(rolesRequired, request)) { - // send deny answer and abort - throw new AuthOpException(); - } - } - } - - // find the file - fileset = (ImageFileset) findFile(dlRequest); - if (fileset == null) { - throw new FileOpException("File " + loadPathName + "(" - + dlRequest.getAsInt("pn") + ") not found."); - } - - /* for absolute scale and original size we need the hires size */ - ImageSize hiresSize = null; - if (absoluteScale) { - ImageFile hiresFile = fileset.getBiggest(); - if (!hiresFile.isChecked()) { - ImageOps.checkFile(hiresFile); - } - hiresSize = hiresFile.getSize(); - - /* prepare resolution and scale factor for original size */ - if (dlRequest.hasOption("mo", "osize")) { - // get original resolution from metadata - fileset.checkMeta(); - origResX = fileset.getResX(); - origResY = fileset.getResY(); - if ((origResX == 0) || (origResY == 0)) { - throw new ImageOpException("Missing image DPI information!"); + List<String> rolesRequired; + try { + rolesRequired = authOp.rolesForPath(jobdeclaration.getFilePath(), request); + if (rolesRequired != null) { + authlog.debug("Role required: " + rolesRequired); + authlog.debug("User: " + request.getRemoteUser()); + // is the current request/user authorized? + if (!authOp.isRoleAuthorized(rolesRequired, request)) { + // send deny answer and abort + throw new AuthOpException(); + } } - if ((paramDDPIX == 0) || (paramDDPIY == 0)) { - throw new ImageOpException( - "Missing display DPI information!"); - } - // calculate absolute scale factor - float sx = paramDDPIX / origResX; - float sy = paramDDPIY / origResY; - // currently only same scale :-( - paramSCALE = (sx + sy)/2f; - } - - } - - - /* calculate expected source image size */ - ImageSize expectedSourceSize = new ImageSize(); - if (scaleToFit) { - // scale to fit -- calculate minimum source size - float scale = (1 / Math.min(paramWW, paramWH)) * paramWS; - expectedSourceSize.setSize((int) (paramDW * scale), - (int) (paramDH * scale)); - } else if (absoluteScale && dlRequest.hasOption("mo", "ascale")) { - // absolute scale -- apply scale to hires size - expectedSourceSize = hiresSize.getScaled(paramSCALE); - } else { - // clip to fit -- source = destination size - expectedSourceSize.setSize((int) (paramDW * paramWS), - (int) (paramDH * paramWS)); - } - - ImageFile fileToLoad; - /* select a resolution */ - if (hiresOnly) { - // get first element (= highest resolution) - fileToLoad = fileset.getBiggest(); - } else if (loresOnly) { - // enforced lores uses next smaller resolution - fileToLoad = fileset.getNextSmaller(expectedSourceSize); - if (fileToLoad == null) { - // this is the smallest we have - fileToLoad = fileset.getSmallest(); - } - } else { - // autores: use next higher resolution - fileToLoad = fileset.getNextBigger(expectedSourceSize); - if (fileToLoad == null) { - // this is the highest we have - fileToLoad = fileset.getBiggest(); - } - } - logger.info("Planning to load: " + fileToLoad.getFile()); - - /* - * send the image if its mo=(raw)file - */ - if (dlRequest.hasOption("mo", "file") - || dlRequest.hasOption("mo", "rawfile")) { - if (sendFileAllowed) { - String mt = null; - if (dlRequest.hasOption("mo", "rawfile")) { - mt = "application/octet-stream"; - } - logger.debug("Sending RAW File as is."); - ServletOps.sendFile(fileToLoad.getFile(), mt, response); - logger.info("Done in " - + (System.currentTimeMillis() - startTime) + "ms"); - return; + } catch (AuthOpException e) { + // TODO Auto-generated catch block + e.printStackTrace(); } } - // check the source image - if (!fileToLoad.isChecked()) { - ImageOps.checkFile(fileToLoad); - } - // get the source image type - mimeType = fileToLoad.getMimetype(); - // get the source image size - ImageSize imgSize = fileToLoad.getSize(); - - // decide if the image can be sent as is - boolean mimetypeSendable = mimeType.equals("image/jpeg") - || mimeType.equals("image/png") - || mimeType.equals("image/gif"); - boolean imagoOptions = dlRequest.hasOption("mo", "hmir") - || dlRequest.hasOption("mo", "vmir") || (paramROT != 0) - || (paramRGBM != null) || (paramRGBA != null) - || (paramCONT != 0) || (paramBRGT != 0); - boolean imageSendable = mimetypeSendable && !imagoOptions; + + job = new DigilibImageWorker(dlConfig, outputstream , jobdeclaration); - /* - * if not autoRes and image smaller than requested size then send as - * is. if autoRes and image has requested size then send as is. if - * not autoScale and not scaleToFit nor cropToFit then send as is - * (mo=file) - */ - if (imageSendable - && ((loresOnly && fileToLoad.getSize().isSmallerThan( - expectedSourceSize)) || (!(loresOnly || hiresOnly) && fileToLoad - .getSize().fitsIn(expectedSourceSize)))) { - - logger.debug("Sending File as is."); - - ServletOps.sendFile(fileToLoad.getFile(), null, response); - - logger.info("Done in " - + (System.currentTimeMillis() - startTime) + "ms"); - return; - } + job.run(); - /* - * stop here if we're overloaded... - * - * 503 Service Unavailable - * The server is currently unable to - * handle the request due to a temporary overloading or maintenance - * of the server. The implication is that this is a temporary - * condition which will be alleviated after some delay. If known, - * the length of the delay MAY be indicated in a Retry-After header. - * If no Retry-After is given, the client SHOULD handle the response - * as it would for a 500 response. Note: The existence of the 503 - * status code does not imply that a server must use it when - * becoming overloaded. Some servers may wish to simply refuse the - * connection. - * (RFC2616 HTTP1.1) - */ - if (! DigilibWorker.canRun()) { - logger.error("Servlet overloaded!"); - response.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE); - return; - } - - // set missing dw or dh from aspect ratio - float imgAspect = fileToLoad.getAspect(); - if (paramDW == 0) { - paramDW = (int) Math.round(paramDH * imgAspect); - } else if (paramDH == 0) { - paramDH = (int) Math.round(paramDW / imgAspect); - } - - /* crop and scale the image */ - - logger.debug("IMG: " + imgSize.getWidth() + "x" - + imgSize.getHeight()); - logger.debug("time " + (System.currentTimeMillis() - startTime) - + "ms"); - - // coordinates and scaling - float areaWidth; - float areaHeight; - float scaleX; - float scaleY; - float scaleXY; - - // coordinates using Java2D - // image size in pixels - Rectangle2D imgBounds = new Rectangle2D.Float(0, 0, imgSize - .getWidth(), imgSize.getHeight()); - // user window area in [0,1] coordinates - Rectangle2D relUserArea = new Rectangle2D.Float(paramWX, paramWY, - paramWW, paramWH); - // transform from relative [0,1] to image coordinates. - AffineTransform imgTrafo = AffineTransform.getScaleInstance(imgSize - .getWidth(), imgSize.getHeight()); - // transform user coordinate area to image coordinate area - Rectangle2D userImgArea = imgTrafo.createTransformedShape( - relUserArea).getBounds2D(); - - // calculate scaling factors based on inner user area - if (scaleToFit) { - areaWidth = (float) userImgArea.getWidth(); - areaHeight = (float) userImgArea.getHeight(); - scaleX = paramDW / areaWidth * paramWS; - scaleY = paramDH / areaHeight * paramWS; - scaleXY = (scaleX > scaleY) ? scaleY : scaleX; - } else if (absoluteScale) { - scaleXY = paramSCALE; - // we need to correct the factor if we use a pre-scaled image - if (imgSize.getWidth() != hiresSize.getWidth()) { - scaleXY *= (float)hiresSize.getWidth() / (float)imgSize.getWidth(); - } - scaleX = scaleXY; - scaleY = scaleXY; - areaWidth = paramDW / scaleXY * paramWS; - areaHeight = paramDH / scaleXY * paramWS; - // reset user area size - userImgArea.setRect(userImgArea.getX(), userImgArea.getY(), - areaWidth, areaHeight); - } else { - // crop to fit - areaWidth = paramDW * paramWS; - areaHeight = paramDH * paramWS; - // reset user area size - userImgArea.setRect(userImgArea.getX(), userImgArea.getY(), - areaWidth, areaHeight); - scaleX = 1f; - scaleY = 1f; - scaleXY = 1f; - } - - // enlarge image area for rotations to cover additional pixels - Rectangle2D outerUserImgArea = userImgArea; - Rectangle2D innerUserImgArea = userImgArea; - if (wholeRotArea) { - if (paramROT != 0) { - try { - // rotate user area coordinates around center of user - // area - AffineTransform rotTrafo = AffineTransform - .getRotateInstance(Math.toRadians(paramROT), - userImgArea.getCenterX(), userImgArea - .getCenterY()); - // get bounds from rotated end position - innerUserImgArea = rotTrafo.createTransformedShape( - userImgArea).getBounds2D(); - // get bounds from back-rotated bounds - outerUserImgArea = rotTrafo.createInverse() - .createTransformedShape(innerUserImgArea) - .getBounds2D(); - } catch (NoninvertibleTransformException e1) { - // this shouldn't happen anyway - logger.error(e1); - } - } - } - - logger.debug("Scale " + scaleXY + "(" + scaleX + "," + scaleY - + ") on " + outerUserImgArea); - - // clip area at the image border - outerUserImgArea = outerUserImgArea.createIntersection(imgBounds); - - // check image parameters sanity - if ((outerUserImgArea.getWidth() < 1) - || (outerUserImgArea.getHeight() < 1) - || (scaleXY * outerUserImgArea.getWidth() < 2) - || (scaleXY * outerUserImgArea.getHeight() < 2)) { - logger.error("ERROR: invalid scale parameter set!"); - throw new ImageOpException("Invalid scale parameter set!"); - } - - /* - * submit the image worker job - */ - - DigilibWorker job = new DigilibImageWorker(dlConfig, response, - mimeType, scaleQual, dlRequest, paramROT, paramCONT, - paramBRGT, paramRGBM, paramRGBA, fileToLoad, scaleXY, - outerUserImgArea, innerUserImgArea, minSubsample, - wholeRotArea, forceType); - - job.run(); if (job.hasError()) { throw new ImageOpException(job.getError().toString()); } - logger.debug("servlet done in " - + (System.currentTimeMillis() - startTime)); - - /* error handling */ + try { + outputstream.flush(); + logger.debug("Job Processing Time: "+ (System.currentTimeMillis()-startTime) + "ms"); + } catch (IOException e) { + e.printStackTrace(); + logger.error(e.getMessage()); + response.sendError(1); + } - } // end of "big" try - catch (IOException e) { - logger.error("ERROR: File IO Error: " + e); - digilibError(errorMsgHtml, ERROR_FILE, - "ERROR: File IO Error: " + e, response); - } catch (AuthOpException e) { - logger.error("ERROR: Authorization error: " + e); - digilibError(errorMsgHtml, ERROR_AUTH, - "ERROR: Authorization error: " + e, response); + + } catch (IOException e) { + e.printStackTrace(); + logger.error(e.getClass()+": "+ e.getMessage()); + //response.sendError(1); } catch (ImageOpException e) { - logger.error("ERROR: Image Error: " + e); - digilibError(errorMsgHtml, ERROR_IMAGE, - "ERROR: Image Operation Error: " + e, response); - } catch (RuntimeException e) { - // JAI likes to throw RuntimeExceptions ;-( - logger.error("ERROR: Other Image Error: " + e); - digilibError(errorMsgHtml, ERROR_IMAGE, - "ERROR: Other Image Operation Error: " + e, response); + e.printStackTrace(); + logger.error(e.getClass()+": "+ e.getMessage()); + //response.sendError(1); } - } - /** - * Returns the DocuDirent corresponding to the DigilibRequest. - * - * @param dlRequest - * @return - */ - public DocuDirent findFile(DigilibRequest dlRequest) { - // find the file(set) - DocuDirent f = dirCache.getFile(dlRequest.getFilePath(), dlRequest - .getAsInt("pn"), FileOps.CLASS_IMAGE); - return f; + + /* boolean errorMsgHtml = false; + + if(jobdeclaration.hasOption("mo","errtxt")){ + errorMsgHtml = true; + } else if (jobdeclaration.hasOption("mo","errimg")) { + errorMsgHtml = true; + } */ + } - + + /** * Sends an error to the client as text or image. * @@ -742,11 +341,9 @@ } - /** - * @return the dlVersion - */ - public static String getVersion() { + public static String getVersion(){ return dlVersion; } + -} // Scaler class +}