Mercurial > hg > digilib
changeset 1219:74363771603f
Merge with e543b88b3cfa5e6574bfc2b66835e6895b1491f8
author | robcast |
---|---|
date | Tue, 01 Oct 2013 12:24:29 +0200 |
parents | bd7dfa8b164e (diff) e543b88b3cfa (current diff) |
children | cde51f04895c |
files | |
diffstat | 18 files changed, 1115 insertions(+), 379 deletions(-) [+] |
line wrap: on
line diff
--- a/.hgignore Mon Sep 30 16:06:13 2013 +0200 +++ b/.hgignore Tue Oct 01 12:24:29 2013 +0200 @@ -113,4 +113,10 @@ syntax: regexp ^servlet/\.project$ syntax: regexp -^servlet/bin$ \ No newline at end of file +^servlet/bin$ +syntax: regexp +^doc/\.settings$ +syntax: regexp +^doc/\.project$ +syntax: regexp +^doc/target$ \ No newline at end of file
--- a/common/src/main/java/digilib/conf/DigilibConfiguration.java Mon Sep 30 16:06:13 2013 +0200 +++ b/common/src/main/java/digilib/conf/DigilibConfiguration.java Tue Oct 01 12:24:29 2013 +0200 @@ -43,9 +43,12 @@ /** Log4J logger */ protected static Logger logger = Logger.getLogger(DigilibConfiguration.class); + + private static boolean isLoggerConfigured = false; + /** digilib version */ public static String getVersion() { - return "2.2.1"; + return "2.2.2"; } /** @@ -87,8 +90,13 @@ @SuppressWarnings("unchecked") public void configure() { DigilibConfiguration config = this; - // we start log4j with a default logger config TODO: is this the right place? - BasicConfigurator.configure(); + if (DigilibConfiguration.isLoggerConfigured) { + logger.debug("Logger already configured!"); + } else { + // we start log4j with a default logger config + BasicConfigurator.configure(); + DigilibConfiguration.isLoggerConfigured = true; + } /* * initialise static DocuImage class instance */
--- a/common/src/main/java/digilib/conf/DigilibRequest.java Mon Sep 30 16:06:13 2013 +0200 +++ b/common/src/main/java/digilib/conf/DigilibRequest.java Tue Oct 01 12:24:29 2013 +0200 @@ -282,8 +282,14 @@ if (path == null) { return false; } - // alway set HTTP status code error reporting - options.setOption("errcode"); + + String identifier = null; + String region = null; + String size = null; + String rotation = null; + String quality = null; + String format = null; + // enable passing of delimiter to get empty parameters StringTokenizer query = new StringTokenizer(path, "/", true); String token; @@ -308,17 +314,7 @@ if (query.hasMoreTokens()) { token = getNextDecodedToken(query); if (!token.equals("/")) { - try { - if (token.contains("%")) { - // still escape chars -- decode again - token = URLDecoder.decode(token, "UTF-8"); - } - setValueFromString("fn", token); - } catch (UnsupportedEncodingException e) { - errorMessage = "Error decoding identifier in IIIF path!"; - logger.error(errorMessage); - return false; - } + identifier = token; // skip / if (query.hasMoreTokens()) { query.nextToken(); @@ -331,53 +327,12 @@ if (query.hasMoreTokens()) { token = getNextDecodedToken(query); if (!token.equals("/")) { - if (token.equals("info.json")) { - // info request - options.setOption("info"); - return true; - } else if (token.equals("full")) { - // full region -- default - } else if (token.startsWith("pct:")) { - // pct:x,y,w,h -- region in % of original image - String[] parms = token.substring(4).split(","); - try { - float x = Float.parseFloat(parms[0]); - setValue("wx", x / 100f); - float y = Float.parseFloat(parms[1]); - setValue("wy", y / 100f); - float w = Float.parseFloat(parms[2]); - setValue("ww", w / 100f); - float h = Float.parseFloat(parms[3]); - setValue("wh", h / 100f); - } catch (Exception e) { - errorMessage = "Error parsing range parameter in IIIF path!"; - logger.error(errorMessage, e); - return false; - } - } else { - // x,y,w,h -- region in pixel of original image :-( - String[] parms = token.split(","); - if (parms.length != 4) { - errorMessage = "Error parsing range parameter in IIIF path!"; - logger.error(errorMessage); - return false; - } else { - options.setOption("pxarea"); - setValueFromString("wx", parms[0]); - setValueFromString("wy", parms[1]); - setValueFromString("ww", parms[2]); - setValueFromString("wh", parms[3]); - } - } + region = token; // skip / if (query.hasMoreTokens()) { query.nextToken(); } } - } else { - // region omitted -- assume info request - options.setOption("info"); - return true; } /* * fourth parameter size @@ -385,60 +340,12 @@ if (query.hasMoreTokens()) { token = getNextDecodedToken(query); if (!token.equals("/")) { - if (token.equals("full")) { - // full -- size of original - options.setOption("ascale"); - setValue("scale", 1f); - } else if (token.startsWith("pct:")) { - // pct:n -- n% size of original - try { - float pct = Float.parseFloat(token.substring(4)); - options.setOption("ascale"); - setValue("scale", pct / 100); - } catch (NumberFormatException e) { - errorMessage = "Error parsing size parameter in IIIF path!"; - logger.error(errorMessage, e); - return false; - } - } else { - // w,h -- pixel size - try { - String[] parms = token.split(",", 2); - if (parms[0].length() > 0) { - // width param - if (parms[0].startsWith("!")) { - // width (in digilib-like bounding box) - setValueFromString("dw", parms[0].substring(1)); - } else if (parms[1].length() == 0) { - // width only - setValueFromString("dw", parms[0]); - } else { - // w,h -- according to spec, we should distort the image to match ;-( - errorMessage = "Non-uniform-scale size parameter in IIIF path not supported!"; - logger.error(errorMessage); - return false; - } - } - if (parms[1].length() > 0) { - // height param - setValueFromString("dh", parms[1]); - } - } catch (Exception e) { - errorMessage = "Error parsing size parameter in IIIF path!"; - logger.error(errorMessage, e); - return false; - } - } + size = token; // skip / if (query.hasMoreTokens()) { query.nextToken(); } } - } else { - // size omitted -- assume "full" - options.setOption("ascale"); - setValue("scale", 1f); - return true; } /* * fifth parameter rotation @@ -446,14 +353,7 @@ if (query.hasMoreTokens()) { token = getNextDecodedToken(query); if (!token.equals("/")) { - try { - float rot = Float.parseFloat(token); - setValue("rot", rot); - } catch (NumberFormatException e) { - errorMessage = "Error parsing rotation parameter in IIIF path!"; - logger.error(errorMessage, e); - return false; - } + rotation = token; // skip / if (query.hasMoreTokens()) { query.nextToken(); @@ -469,26 +369,10 @@ try { String[] parms = token.split("\\."); // quality param - if (parms[0].equals("native")||parms[0].equals("color")) { - // native is default anyway - } else if (parms[0].equals("grey")) { - setValueFromString("colop", "grayscale"); - } else { - errorMessage = "Invalid quality parameter in IIIF path!"; - logger.error(errorMessage); - return false; - } - // format param (we only support jpg and png) - if (parms.length > 1 && parms[1].equals("jpg")) { - // force jpg - options.setOption("jpg"); - } else if (parms.length > 1 && parms[1].equals("png")) { - // force png - options.setOption("png"); - } else if (parms.length > 1) { - errorMessage = "Invalid format parameter in IIIF path!"; - logger.error(errorMessage); - return false; + quality = parms[0]; + // format param + if (parms.length > 1) { + format = parms[1]; } } catch (Exception e) { errorMessage = "Error parsing quality and format parameters in IIIF path!"; @@ -496,7 +380,9 @@ return false; } } - return true; + + // set request with these parameters + return setWithIiifParams(identifier, region, size, rotation, quality, format); } private String getNextDecodedToken(StringTokenizer tokens) { @@ -510,6 +396,195 @@ return null; } + /** + * Populate a request from IIIF image API parameters. + * + * {scheme}://{server}{/prefix}/{identifier}/{region}/{size}/{rotation}/{quality}{.format} + * + * @see <a href="http://www-sul.stanford.edu/iiif/image-api/1.1/">IIIF Image + * API</a> + */ + public boolean setWithIiifParams(String identifier, String region, String size, + String rotation, String quality, String format) { + // alway set HTTP status code error reporting + options.setOption("errcode"); + + /* + * parameter identifier (encoded) + */ + if (identifier != null) { + try { + if (identifier.contains("%")) { + // still escape chars -- decode again + identifier = URLDecoder.decode(identifier, "UTF-8"); + } + setValueFromString("fn", identifier); + } catch (UnsupportedEncodingException e) { + errorMessage = "Error decoding identifier in IIIF path!"; + logger.error(errorMessage); + return false; + } + } else { + errorMessage = "Missing identifier in IIIF path!"; + logger.error(errorMessage); + return false; + } + + /* + * parameter region + */ + if (region != null) { + if (region.equals("info.json")) { + // info request + options.setOption("info"); + return true; + } else if (region.equals("full")) { + // full region -- default + } else if (region.startsWith("pct:")) { + // pct:x,y,w,h -- region in % of original image + String[] parms = region.substring(4).split(","); + try { + float x = Float.parseFloat(parms[0]); + setValue("wx", x / 100f); + float y = Float.parseFloat(parms[1]); + setValue("wy", y / 100f); + float w = Float.parseFloat(parms[2]); + setValue("ww", w / 100f); + float h = Float.parseFloat(parms[3]); + setValue("wh", h / 100f); + } catch (Exception e) { + errorMessage = "Error parsing range parameter in IIIF path!"; + logger.error(errorMessage, e); + return false; + } + } else { + // x,y,w,h -- region in pixel of original image :-( + String[] parms = region.split(","); + if (parms.length != 4) { + errorMessage = "Error parsing range parameter in IIIF path!"; + logger.error(errorMessage); + return false; + } else { + options.setOption("pxarea"); + setValueFromString("wx", parms[0]); + setValueFromString("wy", parms[1]); + setValueFromString("ww", parms[2]); + setValueFromString("wh", parms[3]); + } + } + } else { + // region omitted -- assume info request + options.setOption("info"); + return true; + } + + /* + * parameter size + */ + if (size != null) { + if (size.equals("full")) { + // full -- size of original + options.setOption("ascale"); + setValue("scale", 1f); + } else if (size.startsWith("pct:")) { + // pct:n -- n% size of original + try { + float pct = Float.parseFloat(size.substring(4)); + options.setOption("ascale"); + setValue("scale", pct / 100); + } catch (NumberFormatException e) { + errorMessage = "Error parsing size parameter in IIIF path!"; + logger.error(errorMessage, e); + return false; + } + } else { + // w,h -- pixel size + try { + String[] parms = size.split(",", 2); + if (parms[0].length() > 0) { + // width param + if (parms[0].startsWith("!")) { + // width (in digilib-like bounding box) + setValueFromString("dw", parms[0].substring(1)); + } else if (parms[1].length() == 0) { + // width only + setValueFromString("dw", parms[0]); + } else { + // w,h -- according to spec, we should distort the + // image to match ;-( + errorMessage = "Non-uniform-scale size parameter in IIIF path not supported!"; + logger.error(errorMessage); + return false; + } + } + if (parms[1].length() > 0) { + // height param + setValueFromString("dh", parms[1]); + } + } catch (Exception e) { + errorMessage = "Error parsing size parameter in IIIF path!"; + logger.error(errorMessage, e); + return false; + } + } + } else { + // size omitted -- assume "full" + options.setOption("ascale"); + setValue("scale", 1f); + return true; + } + + /* + * parameter rotation + */ + if (rotation != null) { + try { + float rot = Float.parseFloat(rotation); + setValue("rot", rot); + } catch (NumberFormatException e) { + errorMessage = "Error parsing rotation parameter in IIIF path!"; + logger.error(errorMessage, e); + return false; + } + } + + /* + * parameter quality + */ + if (quality != null) { + // quality param + if (quality.equals("native") || quality.equals("color")) { + // native is default anyway + } else if (quality.equals("grey")) { + setValueFromString("colop", "grayscale"); + } else { + errorMessage = "Invalid quality parameter in IIIF path!"; + logger.error(errorMessage); + return false; + } + } + + /* + * parameter format + */ + if (format != null) { + // format param (we only support jpg and png) + if (format.equals("jpg")) { + // force jpg + options.setOption("jpg"); + } else if (format.equals("png")) { + // force png + options.setOption("png"); + } else { + errorMessage = "Invalid format parameter in IIIF path!"; + logger.error(errorMessage); + return false; + } + } + return true; + } + + /** * 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/common/src/main/java/digilib/image/ImageJobDescription.java Mon Sep 30 16:06:13 2013 +0200 +++ b/common/src/main/java/digilib/image/ImageJobDescription.java Tue Oct 01 12:24:29 2013 +0200 @@ -78,6 +78,7 @@ String mimeType = null; Integer paramDW = null; Integer paramDH = null; + DocuDirCache dirCache = null; /** * create empty ImageJobDescription. @@ -87,6 +88,7 @@ public ImageJobDescription(DigilibConfiguration dlcfg) { super(30); dlConfig = dlcfg; + dirCache = (DocuDirCache) dlConfig.getValue("servlet.dir.cache"); } /** @@ -184,7 +186,7 @@ } /** - * Returns the mime-type (of the input). + * Returns the mime-type of the input. * * @return * @throws IOException @@ -197,12 +199,46 @@ return mimeType; } + /** + * Return the mime-type of the output. + * + * @return + */ + public String getOutputMimeType() { + // forced destination image type + if (hasOption("jpg")) { + return "image/jpeg"; + } else if (hasOption("png")) { + return "image/png"; + } + // use input image type + try { + String mt = getMimeType(); + if ((mt.equals("image/jpeg") || mt.equals("image/jp2") || mt.equals("image/fpx"))) { + return "image/jpeg"; + } else { + return "image/png"; + } + } catch (IOException e) { + logger.error("No input when trying to getOutputMimeType!"); + } + return null; + } + + /** + * Set the current ImageInput. + * * @param input * the input to set */ public void setInput(ImageInput input) { this.input = input; + // create and set ImageSet if needed + if (dirCache == null && imageSet == null) { + imageSet = new ImageSet(); + imageSet.add(input); + } } /** @@ -250,7 +286,6 @@ */ public DocuDirectory getFileDirectory() throws FileOpException { if (fileDir == null) { - DocuDirCache dirCache = (DocuDirCache) dlConfig.getValue("servlet.dir.cache"); String fp = getFilePath(); fileDir = dirCache.getDirectory(fp); if (fileDir == null) { @@ -268,8 +303,9 @@ */ public ImageSet getImageSet() throws FileOpException { if (imageSet == null) { - DocuDirCache dirCache = (DocuDirCache) dlConfig.getValue("servlet.dir.cache"); - + if (dirCache == null) { + throw new FileOpException("No DirCache configured!"); + } imageSet = (ImageSet) dirCache.getFile(getFilePath(), getAsInt("pn"), FileClass.IMAGE); if (imageSet == null) { throw new FileOpException("File " + getFilePath() + "(" + getAsInt("pn") + ") not found."); @@ -279,6 +315,16 @@ } /** + * Set the current ImageSet. + * + * @param imageSet + */ + public void setImageSet(ImageSet imageSet) { + this.imageSet = imageSet; + } + + + /** * Returns the file path name from the request. * * @return @@ -667,6 +713,8 @@ } /** + * Set the current docuImage. + * * @param docuImage * the docuImage to set */
--- a/common/src/main/java/digilib/io/ImageFileSet.java Mon Sep 30 16:06:13 2013 +0200 +++ b/common/src/main/java/digilib/io/ImageFileSet.java Tue Oct 01 12:24:29 2013 +0200 @@ -115,22 +115,6 @@ } /** - * Adds an ImageFile to this Fileset. - * - * The files should be added in the order of higher to lower resolutions. - * The first file is considered the hires "original". - * - * - * @param f - * file to add - * @return true (always) - */ - public boolean add(ImageInput f) { - f.setParent(this); - return list.add(f); - } - - /** * Fill the ImageSet with files from different base directories. * *
--- a/common/src/main/java/digilib/io/ImageSet.java Mon Sep 30 16:06:13 2013 +0200 +++ b/common/src/main/java/digilib/io/ImageSet.java Tue Oct 01 12:24:29 2013 +0200 @@ -217,4 +217,20 @@ } + /** + * Adds an ImageImput to this ImageSet. + * + * The images should be added in the order of higher to lower resolutions. + * The first image is considered the hires "original". + * + * + * @param f + * ImageInput to add + * @return true (always) + */ + public boolean add(ImageInput f) { + f.setParent(this); + return list.add(f); + } + }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/doc/pom.xml Tue Oct 01 12:24:29 2013 +0200 @@ -0,0 +1,50 @@ +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>digilib</groupId> + <artifactId>digilib</artifactId> + <version>2.2-SNAPSHOT</version> + </parent> + <artifactId>digilib-doc</artifactId> + <packaging>pom</packaging> + <name>digilib-doc</name> + <description>The Digital Image Library - documentation</description> + <url>http://digilib.berlios.de</url> + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-site-plugin</artifactId> + <version>3.3</version> + <dependencies> + <dependency> + <groupId>org.apache.maven.doxia</groupId> + <artifactId>doxia-module-markdown</artifactId> + <version>1.4</version> + </dependency> + </dependencies> + </plugin> + </plugins> + </build> + <reporting> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-project-info-reports-plugin</artifactId> + <version>2.7</version> + <reportSets> + <reportSet> + <reports> + <report>project-team</report> + <report>mailing-list</report> + <report>scm</report> + <report>issue-tracking</report> + <!-- <report>cim</report> --> + <report>license</report> + </reports> + </reportSet> + </reportSets> + </plugin> + </plugins> + </reporting> +</project> \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/doc/src/site/markdown/build-maven.md Tue Oct 01 12:24:29 2013 +0200 @@ -0,0 +1,91 @@ +# Building digilib with Maven + +The easiest way to get the latest and greatest digilib is the [Maven](http://maven.apache.org/) build tool. +It will download, compile, and install the latest digilib version and all required libraries. + +## What you need + +* [Java](http://www.java.com/) (1.5 or higher) +* [Maven](http://maven.apache.org/) +* [Mercurial](http://mercurial.selenic.com/) +* A Servlet container like [Tomcat](http://tomcat.apache.org/) +or [Jetty](http://www.eclipse.org/jetty/) to run the web application. + +## Quick build + +The fastest way to build the digilib web application is to download the digilib +project file [pom.xml](http://hg.berlios.de/repos/digilib/raw-file/tip/pom.xml) +(download and save it) and run + + mvn scm:bootstrap -N + +in the same directory as the `pom.xml` file. + +This will create a web application directory `digilib-webapp-2.2-SNAPSHOT` +and a WAR file `digilib-webapp-2.2-SNAPSHOT-srv3.war` (or similar) +in the subdirectory `target/checkout/webapp/target/` + +Digilib uses the Asynchronous Servlet API (3.0) by default. You will need Java version 6 +and Tomcat version 7 or Jetty version 8 or later to use it. +If you want to use the old non-Asynchronous Servlet API (2.3) add `-Pservlet2` +to the Maven command line above. + +## Developer build + +If you are developing with digilib it is helpful to check out the source +code separately so you can keep it around, modify it or change the configuration +before you deploy. + +To check out the latest source code into the directory `digilib` run + + hg clone http://hg.berlios.de/repos/digilib + +The digilib configuration files are now in `digilib/webapp/src/main/webapp/WEB-INF/` + +If you want to update your copy of digilib to the latest version at some time in the future +just run + + hg pull + hg up + +in the `digilib` directory. + +To build the resulting source code, change into the `digilib` +directory you checked out above and run + + mvn package + +This will create a web application directory `digilib-webapp-2.2-SNAPSHOT` +and a WAR file `digilib-webapp-2.2-SNAPSHOT-srv3.war` (or similar) in +the subdirectory `webapp/target/` . + +Digilib uses the Asynchronous Servlet API (3.0) by default. You will need Java version 6 +and Tomcat version 7 or Jetty version 8 or later to use it. +If you want to use the old non-Asynchronous Servlet API (2.3) add `-Pservlet2` +to the Maven command line above. + +## Deploying the web application by hand + +To deploy digilib just copy the web application directory or the WAR file into the `webapp` +directory of the Servlet container. + +Since the URL of your digilib server starts with the name of the web application +and the name of the web application is derived from the name of the web +application directory or the WAR file **please rename the web application directory or WAR file +to `digitallibrary` before you start** + +Then you should see your digilib running at the URL +[http://localhost:8080/digitallibrary/jquery/digilib.html](http://localhost:8080/digitallibrary/jquery/digilib.html) + +If you use the unmodified default configuration you should see the digilib logo +and other sample images from the `sample-images` directory of the web application. + +## Configuring digilib + +To change the configuration of digilib just edit the file `digilib-config.xml` +in the web application directory (`digitallibrary/WEB-INF/digilib-config.xml`). +Documentation of the configuration options is [here](digilib-config.html). + +You can see a summary of your running digilib configuration at the URL +[http://localhost:8080/digitallibrary/server/dlConfig.jsp](http://localhost:8080/digitallibrary/server/dlConfig.jsp) +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/doc/src/site/markdown/digilib-config.md Tue Oct 01 12:24:29 2013 +0200 @@ -0,0 +1,154 @@ +# Configuring digilib + +## digilib-config.xml + +The main configuration for digilib is `digilib-config.xml` in the `WEB-INF` +directory in the webapp. +(If you really need a different location you can define it in the `config-file` +init-parameter to the Servlet.) + +In the XML-based configuration file you can set several paths and options. + +You have to adjust the **`basedir-list`** parameter to the directories +where your images are installed. The directory path has to be an absolute +path following the conventions of your operating system (a relative path +is taken to be relative to the web application directory). + +You need only one directory if you don't want to provide pre-scaled low resolution +versions of your images. If you have pre-scaled images the directory with the +high-resolution images must be the first entry in the list. + +Documentation on the directory layout and on using pre-scaled images is +[here](image-directories.md). + +A minimal configuration looks like this: + + <!-- Digilib servlet config file --> + <digilib-config> + <!-- List of directories where images are searched. + The authoritative directory with the high-resolution images + is first in list. --> + <parameter name="basedir-list" value="/docuserver/images" /> + </digilib-config> + +A more customized configuration may look like this (for a full list of +configuration options use the source: +[1](http://hg.berlios.de/repos/digilib/file/default/common/src/main/java/digilib/conf/DigilibConfiguration.java) +[2](http://hg.berlios.de/repos/digilib/file/default/servlet/src/main/java/digilib/conf/DigilibServletConfiguration.java) +[3](http://hg.berlios.de/repos/digilib/file/default/servlet3/src/main/java/digilib/conf/DigilibServlet3Configuration.java) +): + + <!-- Digilib servlet config file --> + <digilib-config> + <!-- Image to be sent to indicate general failure. --> + <parameter name="error-image" value="/docuserver/images/icons/broken.gif" /> + + <!-- Image to be sent to indicate authorization failure. --> + <parameter name="denied-image" value="/docuserver/images/icons/alert.red.gif" /> + + <!-- Image to be sent to indicate file-not-found. --> + <parameter name="notfound-image" value="/docuserver/images/icons/notfound.gif" /> + + <!-- List of directories where images are searched. + The authoritative directory with the high-resolution images + is first in list. --> + <parameter name="basedir-list" value="/docuserver/images:/docuserver/scaled/small" /> + + <!-- mimimum amount of scaling done with antialiasing --> + <parameter name="subsample-minimum" value="2"/> + + <!-- default interpolation quality (0=worst) --> + <parameter name="default-quality" value="2"/> + + <!-- is sending whole image files with mo=file allowed? --> + <parameter name="sendfile-allowed" value="true" /> + + <!-- the a maximum size of any sent image. (0 means no limit) --> + <parameter name="max-image-size" value="0" /> + + <!-- number of working threads --> + <parameter name="worker-threads" value="2" /> + + <!-- number of waiting requests in queue --> + <parameter name="max-waiting-threads" value="20" /> + + <!-- Restrict access to authorized users. + User authentication and roles are provided by the servlet container + (see tomcat-users.xml). + Authorization for resources (directories) is evaluated by the servlet + (see auth-file). --> + <parameter name="use-authorization" value="false"/> + + <!-- Location of XML file with authorization requirements. --> + <parameter name="auth-file" value="digilib-auth.xml"/> + + <!-- Part of URL to indicate authenticated access to Tomcat. --> + <parameter name="auth-url-path" value="authenticated/"/> + + <!-- use mapping of "virtual directories" to real directories on the server --> + <parameter name="use-mapping" value="false"/> + + <!-- location of XML mapping file --> + <parameter name="mapping-file" value="digilib-map.xml"/> + + <!-- location of logger config file --> + <parameter name="log-config-file" value="log4j-config.xml"/> + </digilib-config> + +You can supply your own icons for the "error" and "access denied" +messages by the servlet. Standard images will be used if these +parameters are not defined. + +You can specify the Java toolkit implementation with the `docuimage-class` +parameter. The `ImageLoaderDocuImage` usually gives best performance +and works with JDK 1.4 and up. + +You can see a summary of your running digilib configuration at the URL +[http://localhost:8080/digitallibrary/server/dlConfig.jsp](http://localhost:8080/digitallibrary/server/dlConfig.jsp) + + +## digilib-auth.xml + +The digilib access authorization is defined in the file defined by the `auth-file` +parameter (default: `digilib-auth.xml` in `WEB-INF` ). + +The file has two parts `diglib-paths` and `diglib-addresses`. It looks like this: + + <auth-config> + + <digilib-paths> + <!-- + A user must supply one of the roles under "role" + to access the directory "name". + Roles under "role" must be separated by comma only (no spaces). + --> + <path name="histast/eastwood-collection" role="eastwood-coll" /> + <path name="ptolemaios_geo" role="ptolemaios-geo" /> + </digilib-paths> + + <digilib-addresses> + <!-- + A computer with an ip address that matches "ip" + is automatically granted all roles under "role". + The ip address is matched from the left (in full quads). + Roles under "role" must be separated by comma only (no spaces). + --> + <address ip="127" role="local" /> + <address ip="130.92.68" role="eastwood-coll,ptolemaios-geo" /> + <address ip="130.92.151" role="ALL" /> + </digilib-addresses> + + </auth-config> + +`diglib-paths` defines restricted directories and the roles needed +for access. The roles are defined with the users in `tomcat-users.xml` +(see above). All subdirectories of the given directories have the same +restrictions. All directories not listed here (and not subdirectories of listed +directories) are freely accessible. + +`diglib-addresses` defines hosts or networks of computers that are +automatically authenticated without username and password. Hosts can be assigned +roles. The special keyword `ALL` authorizes for everything. If the +role assigned to the computer is not sufficient to access a resource the user +will be asked for username and password. + \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/doc/src/site/markdown/history.md Tue Oct 01 12:24:29 2013 +0200 @@ -0,0 +1,36 @@ +## Early history of digilib (in German) + +### docuedit (auch DocumentDatabase, später doculight) + +Imageviewer mit Dokumenten-Baum Ansicht, in Java geschrieben, komplett +Client-seitig. Entstanden vor März 1998 (müsste am MPIWG gewesen sein). +Wesentlicher Autor Michael May (glaube ich). + +Von doculight gibt es hier sogar noch eine "Web-Version" von Anfang 2000 +aus Bern, die aber nicht mehr ganz funktioniert: + +[http://pythia2.unibe.ch/docuserver/viewerlite/frame.htm](http://pythia2.unibe.ch/docuserver/viewerlite/frame.htm) + +Und hier ist der Übergang zur Client-Server Lösung "gg.jsp" (noch ohne +serverseitige Skalierung der Seiten) vom Juni 2000, das leider mangels +JSP auf dem Server nicht mehr geht: + +[http://pythia2.unibe.ch/docuserver/viewerlite/gg.jsp](http://pythia2.unibe.ch/docuserver/viewerlite/gg.jsp) + +(Die Knöpfe sind zwar noch schlicht haben aber schon die gleichen +Funktionen wie später) + +### digilib (ScaleServlet, später Scaler) + +Client-Server Lösung mit Javascript auf dem Client und Java auf dem Server. +Entstanden ca. Juli 2000. Wesentlicher Autor zunächst Robert Gordesch (Stud. +Hilfskraft MPIWG) für den Server-Teil in Java und Gerd Graßhoff (Bern) fürs +Javascript (glaube ich), seit Februar 2001 Robert Casties (Bern, ab 2002 MPIWG), +danach auch Christian Luginbühl. Seit Anfang 2002 Open Source Projekt bei +BerliOS. + +## Articles on digilib + +1. Raspe, Martin; Casties, Robert; "Digilib: Wissenschaftliches Bildmaterial +studieren und kommentierenim Internet", Jahrbuch der Max-Planck-Gesellschaft 2006, +[http://www.mpg.de/411123/pdf.pdf](http://www.mpg.de/411123/pdf.pdf) \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/doc/src/site/markdown/image-directories.md Tue Oct 01 12:24:29 2013 +0200 @@ -0,0 +1,85 @@ +# Directory layout for images + +In digilib all images are identified by the `fn` and (optional) `pn` parameters. +The value for `fn` can be a directory path or a directory path and a filename, +separated by slashes, e.g. "`fn=books/book1/page0002`". + +If `fn` is a directory path without filename `pn` is the index number of the +image files in this directory in alphabetical order, e.g. +"`fn=books/book1&pn=2`". The default for `pn` is 1 i.e. the first image. + +If `fn` ends in a filename `pn` is ignored. File extensions are also ignored, +i.e. "`books/book1/page0002`" and "`books/book1/page0002.tif`" identify the same +image. It is recommended to omit the file extension. + +The directory path in `fn` is relative to the base directory in the `basedir-list` +parameter of the `digilib-config.xml` file, e.g. if + + <parameter name="basedir-list" value="/docuserver/images" /> + +and + + fn=books/book1/page0002 + +then digilib will try to load the file + + /docuserver/images/books/book1/page0002.tif + +(automatically finding the right file extension) + + +## Prescaled images + +You can provide any number of scaled-down versions of your images that +digilib can use when a smaller version of an image is requested. Since less data +has to be read and processed this can speed up digilib's performance considerably. + +The actual process is that the client requests a certain target size, +digilib scans all available scaled-down versions of the same image, selects the +smallest image that is larger than the requested size and scales it down to the +requested size. + +There is another optimization in digilib: if the requested image is *exactly* +the same size and type as the pre-scaled image then the pre-scaled image is sent +unmodified to the client which is a lot faster. So it makes sense to produce +thumbnails of exactly 90 pixel width when they are used in an HTML page where +all images are 90 pixel wide. + +The scaled-down versions of the image have to have the same file name as +the original hi-res file. They can have a different type and extension (e.g. +`img002.jpg` for `img002.TIFF`) + +The scaled down images have to have the same directory path (the part that +shows up in digilib's "fn" parameter) as the hi-res file wile the first part of each +directory tree is configured by the `basedir-list` parameter in +`digilib-config.xml`. + +The sequence of directories in `basedir-list` is from high-res to low-res. +Images must be present in the hires directory but they need not be present in +all lower-res directories. + +e.g. if digilib-config.xml contains + + <parameter name="basedir-list" value="/images:/scaled:/thumb" /> + +and a user requests the image `books/book1/page0002` digilib looks for + +1. `/thumb/books/book1/page0002.jpg` +2. `/scaled/books/book1/page002.jpg` +3. `/images/books/book1/page002.tif` + +(automatically finding the right file extension) +and uses the first image that is bigger than or equal to the requested size. + +For batch-prescaling our images we use a script called "scale-o-mat" that uses a +lot of freely available imaging libraries (ImageMagick, libtiff, netpbm) and is +available in our public CVS [[1]](http://itgroup.mpiwg-berlin.mpg.de/cgi-bin/cvsweb.cgi/scaleomat/). +The script is given a +hi-res base directory, a destination base directory, a destination size and a +starting directory. It then processes all files in the starting directory and +all its subdirectories and creates scaled images in corresponding directories +under the destination base directory. + +We currently use prescaled thumbnails of 100 pixels and images for browser +display of 1500 pixels. Remember that the prescaled image has to be larger (or +the same size) than the requested image size!
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/doc/src/site/markdown/index.md Tue Oct 01 12:24:29 2013 +0200 @@ -0,0 +1,33 @@ + + +## What is digilib? + +* `digilib` is a web based client/server technology for images. The image + content is processed on-the-fly by a Java Servlet on the server side so that + only the visible portion of the image is sent to the web browser on the client + side. +* `digilib` supports a wide range of image formats and viewing options on + the server side while only requiring an internet browser with Javascript and a + low bandwidth internet connection on the client side. +* `digilib` enables very detailed work on an image as required by + scholars with elaborate viewing features like an option to show images on the + screen in their original size. +* `digilib` facilitates cooperation of scholars over the internet and + novel uses of source material by image annotations and stable references that + can be embedded in URLs. +* `digilib` is Open Source Software under the Lesser General Public License, + jointly developed by the + [Max-Planck-Institute for the History of Science](http://www.mpiwg-berlin.mpg.de), + the [Bibliotheca Hertziana](http://www.biblhertz.it), + the [University of Bern](http://philoscience.unibe.ch) and others. + +## Where can I get digilib? + +`digilib` source code, binaries and documentation can be found on the +[digilib project pages](http://developer.berlios.de/projects/digilib/) +on [BerliOS](http://developer.berlios.de): + +* [Source code](http://hg.berlios.de/repos/digilib) +* Daily built [WAR files](http://digilib.berlios.de/downloads/daily-build/) +* Daily built [Javadoc](http://digilib.berlios.de/downloads/daily-build/javadoc/) +* [Maven repository](http://it-dev.mpiwg-berlin.mpg.de/maven-repo/)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/doc/src/site/markdown/java-settings.md Tue Oct 01 12:24:29 2013 +0200 @@ -0,0 +1,55 @@ +# Java VM settings for digilib + +The Java virtual machine (Java-VM) only uses a fixed amount of memory for +its operations. When an operation needs more memory than available it aborts +with an error ("out of memory error"). + +digilib can need a lot of memory depending on the size and type of images. +Since digilib runs as a servlet under Tomcat its in the same VM as the Tomcat +server. + +The amount of memory Tomcat (version 5.0) uses is configured by creating a +`setenv.sh` (or `setenbv.bat`) script with a line + + CATALINA_OPTS="-Xmx512m" + +in Tomcat's `bin` directory (giving 512MB RAM in this case). + +You can check the amount of memory your digilib instance has available on the +bottom of the web page `/server/dlConfig.jsp` in your digilib instance (e.g. +<http://localhost:8080/digilib/server/dlConfig.jsp> + +# Installing JAI ImageIO + +In principle you should be able to install the +[Java Advanced Imaging](http://java.sun.com/javase/technologies/desktop/media/jai/) JAI-ImageIO +JAR file `jai_imageio.jar` (and native +library files if available) in the `/WEB-INF/lib/` directory of the +digilib web application as part of the default installation. + +You can see if the Jai-ImageIO plugin is active by checking for the +availability of the TIFF image format under "Supported image types" on the +[`/server/dlConfig.jsp`](http://localhost:8080/digilib/server/dlConfig.jsp) +status page. + +Sometimes there are memory issues. Newer versions of Tomcat refuse to load +the libraries and I found that in some cases digilib stopped reading TIFF files +after a period of running. In these cases it helped to install the JAI files in +Tomcats `lib/` directory or globally in the local Java JDK +installation (i.e. in the Java's 'jre/lib/ext/' directory on linux). + +# Sample setup + +The current digilib setup at the MPIWG (as of December 2010): + +* One frontend server running the lightweight web-multiplexer [pound](http://www.apsis.ch/pound/) + on port 80 that distributes requests to three servers runnning digilib +* the three servers run digilib under [Jetty](http://www.eclipse.org/jetty/) on port 8080 without Apache + * one server is the frontend server (Linux 32bit, Dual 2.4GHz Xeon, 2GB RAM) + * the other server is a separate, newer machine (Linux 64bit, Dual 1.8GHz Opteron, 2GB RAM) + * the third server is a separate, newer machine (Linux 32bit, Dual 2.8GHz Xeon, 4GB RAM) +* the digilib instances (digilib 2.0b1 as of 12.12.2011) run on Jetty 8.0.4 on Java + 1.6.0_26 with 1GB of Java VM memory for digilib (-Xmx1024m) with JAI (1.1.3) and JAI-ImageIO (1.1) + installed in `Jetty/lib/ext` +* both digilib servers access all image files over NFS (over GBit Ethernet) from a central file server + (Solaris 10, Sun Fire 240, multiple RAIDs on Fibrechannel) \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/doc/src/site/site.xml Tue Oct 01 12:24:29 2013 +0200 @@ -0,0 +1,40 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/DECORATION/1.3.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/DECORATION/1.3.0 http://maven.apache.org/xsd/decoration-1.3.0.xsd"> + <skin> + <groupId>org.apache.maven.skins</groupId> + <artifactId>maven-fluido-skin</artifactId> + <version>1.3.0</version> + </skin> + <bannerLeft> + <name>digilib - a versatile image viewing environment for the internet</name> + <href>http://digilib.berlios.de/</href> + </bannerLeft> + <bannerRight> + <src>images/digilib-logo-small.png</src> + <href>http://digilib.berlios.de/</href> + </bannerRight> + <body> + <menu name="Overview"> + <item name="About digilib" href="index.html"/> + <item name="How digilib works" href="digilib-short.html"/> + <item name="Ancient history" href="history.html"/> + </menu> + <menu name="Installation"> + <item name="Installing digilib" href="install-digilib.html"/> + <item name="Building digilib" href="build-maven.html"/> + </menu> + <menu name="Configuration"> + <item name="Configuring digilib" href="digilib-config.html"/> + <item name="Directory layout" href="image-directories.html"/> + <item name="Java settings" href="java-settings.html"/> + </menu> + <menu name="Development"> + <item name="The digilib Scaler API" href="scaler-api.html"/> + <!-- <item name="Integrating digilib into your page" href=""/> + <item name="Integrating digilib into your server" href=""/> --> + </menu> + <menu ref="reports"/> + </body> +</project>
--- a/pom.xml Mon Sep 30 16:06:13 2013 +0200 +++ b/pom.xml Tue Oct 01 12:24:29 2013 +0200 @@ -1,217 +1,260 @@ <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> - <modelVersion>4.0.0</modelVersion> + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> - <groupId>digilib</groupId> - <artifactId>digilib</artifactId> - <version>2.2-SNAPSHOT</version> - <packaging>pom</packaging> + <groupId>digilib</groupId> + <artifactId>digilib</artifactId> + <version>2.2-SNAPSHOT</version> + <packaging>pom</packaging> - <name>digilib</name> - <description>The Digital Image Library</description> - <url>http://digilib.berlios.de</url> - <inceptionYear>2001</inceptionYear> + <name>digilib</name> + <description>The Digital Image Library</description> + <url>http://digilib.berlios.de</url> + <inceptionYear>2001</inceptionYear> - <organization> - <name>digilib Community</name> - <url>http://digilib.berlios.de</url> - </organization> + <organization> + <name>digilib Community</name> + <url>http://digilib.berlios.de</url> + </organization> - <developers> - <developer> - <id>robcast</id> - <name>Robert Casties</name> - <email>robcast@berlios.de</email> - <organization>Max Planck Institute for the History of Science (MPIWG)</organization> - <organizationUrl>http://www.mpiwg-berlin.mpg.de</organizationUrl> - <roles> - </roles> - </developer> - <developer> - <id>hertzhaft</id> - <name>Martin Raspe</name> - <email>hertzhaft@berlios.de</email> - <organization>Bibliotheca Hertziana</organization> - <organizationUrl>http://www.biblhertz.it</organizationUrl> - </developer> - </developers> - <licenses> - <license> - <name>GNU General Lesser Public License (LGPL) version 3.0</name> - <url>http://www.gnu.org/licenses/lgpl-3.0.html</url> - <distribution>repo</distribution> - </license> - </licenses> - <scm> - <connection>scm:hg:http://hg.berlios.de/repos/digilib</connection> - <developerConnection>scm:hg:https://hg.berlios.de/repos/digilib</developerConnection> - <url>http://hg.berlios.de/repos/digilib</url> - </scm> - <issueManagement> - <system>Trac</system> - <url>https://it-dev.mpiwg-berlin.mpg.de/tracs/digilib</url> - </issueManagement> + <developers> + <developer> + <id>robcast</id> + <name>Robert Casties</name> + <email>robcast@berlios.de</email> + <organization>Max Planck Institute for the History of Science (MPIWG)</organization> + <organizationUrl>http://www.mpiwg-berlin.mpg.de</organizationUrl> + <roles> + <role>developer</role> + <role>architect</role> + </roles> + </developer> + <developer> + <id>hertzhaft</id> + <name>Martin Raspe</name> + <email>hertzhaft@berlios.de</email> + <organization>Bibliotheca Hertziana</organization> + <organizationUrl>http://www.biblhertz.it</organizationUrl> + <roles> + <role>developer</role> + </roles> + </developer> + </developers> + <contributors> + <contributor> + <name>Gerd Grasshoff</name> + <organization>Humboldt Universität Berlin</organization> + <organizationUrl>http://www.hu-berlin.de</organizationUrl> + <roles> + <role>former developer</role> + </roles> + </contributor> + <contributor> + <name>Robert Gordesch</name> + <organization>Max Planck Institute for the History of Science (MPIWG)</organization> + <roles> + <role>former developer</role> + </roles> + </contributor> + <contributor> + <name>Christian Luginbuehl</name> + <organization>Universität Bern</organization> + <roles> + <role>former developer</role> + </roles> + </contributor> + </contributors> + <licenses> + <license> + <name>GNU General Lesser Public License (LGPL) version 3.0</name> + <url>http://www.gnu.org/licenses/lgpl-3.0-standalone.html</url> + <distribution>repo</distribution> + </license> + </licenses> + <scm> + <connection>scm:hg:http://hg.berlios.de/repos/digilib</connection> + <developerConnection>scm:hg:https://hg.berlios.de/repos/digilib</developerConnection> + <url>http://hg.berlios.de/repos/digilib</url> + </scm> + <issueManagement> + <system>Trac</system> + <url>https://it-dev.mpiwg-berlin.mpg.de/tracs/digilib</url> + </issueManagement> + <mailingLists> + <mailingList> + <name>Developer List</name> + <subscribe>https://lists.berlios.de/mailman/listinfo/digilib-devel</subscribe> + <unsubscribe>https://lists.berlios.de/mailman/listinfo/digilib-devel</unsubscribe> + <archive>https://lists.berlios.de/pipermail/digilib-devel/</archive> + </mailingList> + </mailingLists> - <build> - <pluginManagement> - <plugins> - <plugin> - <groupId>org.apache.maven.plugins</groupId> - <artifactId>maven-compiler-plugin</artifactId> - <version>2.3.2</version> - </plugin> - </plugins> - </pluginManagement> - <plugins> - <plugin> - <groupId>org.apache.maven.plugins</groupId> - <artifactId>maven-scm-plugin</artifactId> - <version>1.5</version> - <configuration> - <goals>install</goals> - </configuration> - </plugin> - <plugin> - <groupId>org.codehaus.mojo</groupId> - <artifactId>license-maven-plugin</artifactId> - <version>1.4</version> - <configuration> - <!-- <verbose>false</verbose> --> - <licenseName>lgpl_v3</licenseName> - <!-- <useMissingFile>true</useMissingFile> --> - <!-- servlet-api is never included in packaging --> - <excludedArtifacts>servlet-api</excludedArtifacts> - </configuration> - </plugin> - <plugin> - <groupId>org.apache.maven.plugins</groupId> - <artifactId>maven-javadoc-plugin</artifactId> - <version>2.9.1</version> - <configuration> - <show>package</show> - <nohelp>true</nohelp> - </configuration> - </plugin> - </plugins> - </build> - <profiles> - <profile> - <id>servlet2</id> - </profile> - <profile> - <id>servlet3</id> - <activation> - <activeByDefault>true</activeByDefault> - </activation> - </profile> - <!-- optional modules with dependencies selected by profile --> - <profile> - <id>text</id> - <modules> - <module>text</module> - </modules> - </profile> - <profile> - <id>pdf</id> - <modules> - <module>pdf</module> - </modules> - </profile> - <profile> - <id>codec-jai</id> - <modules> - <module>common-jai</module> - </modules> - </profile> - <profile> - <id>codec-imagej</id> - <modules> - <module>common-imagej</module> - </modules> - </profile> - <profile> - <id>codec-bioformats</id> - <modules> - <module>common-bioformats</module> - </modules> - </profile> - </profiles> - <repositories> - </repositories> + <build> + <pluginManagement> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-compiler-plugin</artifactId> + <version>2.3.2</version> + </plugin> + </plugins> + </pluginManagement> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-scm-plugin</artifactId> + <version>1.5</version> + <configuration> + <goals>install</goals> + </configuration> + </plugin> + <plugin> + <groupId>org.codehaus.mojo</groupId> + <artifactId>license-maven-plugin</artifactId> + <version>1.4</version> + <configuration> + <!-- <verbose>false</verbose> --> + <licenseName>lgpl_v3</licenseName> + <!-- <useMissingFile>true</useMissingFile> --> + <!-- servlet-api is never included in packaging --> + <excludedArtifacts>servlet-api</excludedArtifacts> + </configuration> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-javadoc-plugin</artifactId> + <version>2.9.1</version> + <configuration> + <show>package</show> + <nohelp>true</nohelp> + </configuration> + </plugin> + </plugins> + </build> + <profiles> + <profile> + <id>servlet2</id> + </profile> + <profile> + <id>servlet3</id> + <activation> + <activeByDefault>true</activeByDefault> + </activation> + </profile> + <!-- optional modules with dependencies selected by profile --> + <profile> + <id>text</id> + <modules> + <module>text</module> + </modules> + </profile> + <profile> + <id>pdf</id> + <modules> + <module>pdf</module> + </modules> + </profile> + <profile> + <id>codec-jai</id> + <modules> + <module>common-jai</module> + </modules> + </profile> + <profile> + <id>codec-imagej</id> + <modules> + <module>common-imagej</module> + </modules> + </profile> + <profile> + <id>codec-bioformats</id> + <modules> + <module>common-bioformats</module> + </modules> + </profile> + </profiles> + <repositories> + </repositories> - <dependencyManagement> - <dependencies> - <dependency> - <groupId>log4j</groupId> - <artifactId>log4j</artifactId> - <version>1.2.14</version> - </dependency> - <!-- digilib module versions --> - <dependency> - <groupId>digilib</groupId> - <artifactId>digilib-common</artifactId> - <version>2.2-SNAPSHOT</version> - </dependency> - <dependency> - <groupId>digilib</groupId> - <artifactId>digilib-common-jai</artifactId> - <version>2.2-SNAPSHOT</version> - </dependency> - <dependency> - <groupId>digilib</groupId> - <artifactId>digilib-common-imagej</artifactId> - <version>2.2-SNAPSHOT</version> - </dependency> - <dependency> - <groupId>digilib</groupId> - <artifactId>digilib-common-bioformats</artifactId> - <version>2.2-SNAPSHOT</version> - </dependency> - <dependency> - <groupId>digilib</groupId> - <artifactId>digilib-pdf</artifactId> - <version>2.2-SNAPSHOT</version> - </dependency> - <dependency> - <groupId>digilib</groupId> - <artifactId>digilib-text</artifactId> - <version>2.2-SNAPSHOT</version> - </dependency> - <dependency> - <groupId>digilib</groupId> - <artifactId>digilib-servlet</artifactId> - <version>2.2-SNAPSHOT</version> - </dependency> - <dependency> - <groupId>digilib</groupId> - <artifactId>digilib-servlet2</artifactId> - <version>2.2-SNAPSHOT</version> - </dependency> - <dependency> - <groupId>digilib</groupId> - <artifactId>digilib-servlet3</artifactId> - <version>2.2-SNAPSHOT</version> - </dependency> - <dependency> - <groupId>digilib</groupId> - <artifactId>digilib-webapp</artifactId> - <version>2.2-SNAPSHOT</version> - </dependency> - </dependencies> - </dependencyManagement> - <properties> - <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> - </properties> + <dependencyManagement> + <dependencies> + <dependency> + <groupId>log4j</groupId> + <artifactId>log4j</artifactId> + <version>1.2.14</version> + </dependency> + <!-- digilib module versions --> + <dependency> + <groupId>digilib</groupId> + <artifactId>digilib-common</artifactId> + <version>2.2-SNAPSHOT</version> + </dependency> + <dependency> + <groupId>digilib</groupId> + <artifactId>digilib-common-jai</artifactId> + <version>2.2-SNAPSHOT</version> + </dependency> + <dependency> + <groupId>digilib</groupId> + <artifactId>digilib-common-imagej</artifactId> + <version>2.2-SNAPSHOT</version> + </dependency> + <dependency> + <groupId>digilib</groupId> + <artifactId>digilib-common-bioformats</artifactId> + <version>2.2-SNAPSHOT</version> + </dependency> + <dependency> + <groupId>digilib</groupId> + <artifactId>digilib-doc</artifactId> + <version>2.2-SNAPSHOT</version> + </dependency> + <dependency> + <groupId>digilib</groupId> + <artifactId>digilib-pdf</artifactId> + <version>2.2-SNAPSHOT</version> + </dependency> + <dependency> + <groupId>digilib</groupId> + <artifactId>digilib-text</artifactId> + <version>2.2-SNAPSHOT</version> + </dependency> + <dependency> + <groupId>digilib</groupId> + <artifactId>digilib-servlet</artifactId> + <version>2.2-SNAPSHOT</version> + </dependency> + <dependency> + <groupId>digilib</groupId> + <artifactId>digilib-servlet2</artifactId> + <version>2.2-SNAPSHOT</version> + </dependency> + <dependency> + <groupId>digilib</groupId> + <artifactId>digilib-servlet3</artifactId> + <version>2.2-SNAPSHOT</version> + </dependency> + <dependency> + <groupId>digilib</groupId> + <artifactId>digilib-webapp</artifactId> + <version>2.2-SNAPSHOT</version> + </dependency> + </dependencies> + </dependencyManagement> + <properties> + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + </properties> - <dependencies> - </dependencies> - <!-- default modules --> - <modules> - <module>common</module> - <module>servlet</module> - <module>servlet2</module> - <module>servlet3</module> - <module>webapp</module> - </modules> + <dependencies> + </dependencies> + <!-- default modules --> + <modules> + <module>common</module> + <module>servlet</module> + <module>servlet2</module> + <module>servlet3</module> + <module>webapp</module> + <module>doc</module> + </modules> </project> \ No newline at end of file
--- a/servlet/src/main/java/digilib/servlet/ServletOps.java Mon Sep 30 16:06:13 2013 +0200 +++ b/servlet/src/main/java/digilib/servlet/ServletOps.java Tue Oct 01 12:24:29 2013 +0200 @@ -44,6 +44,7 @@ import digilib.conf.DigilibServletRequest; import digilib.image.DocuImage; import digilib.image.ImageOpException; +import digilib.io.FileOpException; import digilib.io.FileOps; import digilib.io.ImageInput; import digilib.util.ImageSize; @@ -353,6 +354,7 @@ * @param dlReq * @param response * @param logger + * @throws FileOpException * @throws ServletException * @see <a href="http://www-sul.stanford.edu/iiif/image-api/1.1/#info">IIIF Image Information Request</a> */ @@ -361,34 +363,44 @@ logger.error("No response!"); return; } + ImageSize size = null; try { // get original image size - ImageInput img = dlReq.getJobDescription().getImageSet().getBiggest(); - ImageSize size = img.getSize(); - String url = dlReq.getServletRequest().getRequestURL().toString(); - if (url.endsWith("/info.json")) { - url = url.substring(0, url.lastIndexOf("/info.json")); - } else if (url.endsWith("/")) { - url = url.substring(0, url.lastIndexOf("/")); + ImageInput img; + img = dlReq.getJobDescription().getImageSet().getBiggest(); + size = img.getSize(); + } catch (FileOpException e) { + try { + response.sendError(HttpServletResponse.SC_NOT_FOUND); + return; + } catch (IOException e1) { + throw new ServletException("Unable to write error response!", e); } - response.setContentType("application/json;charset=UTF-8"); - PrintWriter writer = response.getWriter(); + } + String url = dlReq.getServletRequest().getRequestURL().toString(); + if (url.endsWith("/info.json")) { + url = url.substring(0, url.lastIndexOf("/info.json")); + } else if (url.endsWith("/")) { + url = url.substring(0, url.lastIndexOf("/")); + } + response.setContentType("application/json;charset=UTF-8"); + PrintWriter writer; + try { + writer = response.getWriter(); writer.println("{"); writer.println("\"@context\" : \"http://library.stanford.edu/iiif/image-api/1.1/context.json\","); - writer.println("\"@id\" : \""+url+"\","); - writer.println("\"width\" : "+size.width+","); - writer.println("\"height\" : "+size.height+","); + writer.println("\"@id\" : \"" + url + "\","); + writer.println("\"width\" : " + size.width + ","); + writer.println("\"height\" : " + size.height + ","); writer.println("\"formats\" : [\"jpg\", \"png\"],"); writer.println("\"qualities\" : [\"native\", \"color\", \"grey\"],"); writer.println("\"profile\" : \"http://library.stanford.edu/iiif/image-api/1.1/compliance.html#level2\""); writer.println("}"); } catch (IOException e) { - throw new ServletException("Error sending info:", e); + throw new ServletException("Unable to write response!", e); } - // TODO: should we: finally { img.dispose(); } } - /** Returns text representation of headers for debuggging purposes. * @param req * @return