Mercurial > hg > digilib
changeset 1623:5418b39dd49f
Merge from iiif-presentation branch
62246fdad98050c4c371e0e6c2d8e5c56a73c092
author | Robert Casties <casties@mpiwg-berlin.mpg.de> |
---|---|
date | Thu, 01 Jun 2017 15:06:02 +0200 |
parents | 3f3a4f4eecb1 (current diff) 62246fdad980 (diff) |
children | 373b05148ab2 |
files | servlet3/pom.xml.orig text/pom.xml.orig webapp/pom.xml.orig webapp/src/main/webapp/jquery/digilib-auth.html.orig webapp/src/main/webapp/jquery/digilib.html.orig webapp/src/main/webapp/jquery/jquery.digilib-ann.css webapp/src/main/webapp/jquery/jquery.digilib-ann.js webapp/src/main/webapp/jquery/jquery.digilib-ann.min.css webapp/src/main/webapp/jquery/jquery.digilib-ann.min.js webapp/src/main/webapp/jquery/jquery.digilib-ann.min.js.map webapp/src/main/webapp/jquery/jquery.digilib-auth.css webapp/src/main/webapp/jquery/jquery.digilib-auth.js webapp/src/main/webapp/jquery/jquery.digilib-auth.min.css webapp/src/main/webapp/jquery/jquery.digilib-auth.min.js |
diffstat | 33 files changed, 1475 insertions(+), 188 deletions(-) [+] |
line wrap: on
line diff
--- a/.hgignore Wed Mar 08 13:12:01 2017 +0100 +++ b/.hgignore Thu Jun 01 15:06:02 2017 +0200 @@ -129,4 +129,12 @@ syntax: regexp ^webapp/src/main/webapp/jquery/jquery\.digilib-basic\.js$ syntax: regexp -^webapp/src/main/webapp/jquery/jquery\.digilib-basic\.min\.css$ \ No newline at end of file +^webapp/src/main/webapp/jquery/jquery\.digilib-basic\.min\.css$ +syntax: regexp +^iiif-presentation/target$ +syntax: regexp +^iiif-presentation/\.settings$ +syntax: regexp +^iiif-presentation/\.classpath$ +syntax: regexp +^iiif-presentation/\.project$ \ No newline at end of file
--- a/common/src/main/java/digilib/conf/DigilibConfiguration.java Wed Mar 08 13:12:01 2017 +0100 +++ b/common/src/main/java/digilib/conf/DigilibConfiguration.java Thu Jun 01 15:06:02 2017 +0200 @@ -57,7 +57,7 @@ /** digilib version */ public static String getClassVersion() { - return "2.5.2a"; + return "2.5.3a"; } /* non-static getVersion for Java inheritance */ @@ -98,8 +98,6 @@ newParameter("iiif-prefix", "IIIF", null, 'f'); // IIIF Image API version to support (mostly relevant for info.json) newParameter("iiif-api-version", "2.0", null, 'f'); - // set CORS header on IIIF Image API info request - newParameter("iiif-info-cors", Boolean.TRUE, null, 'f'); // character to use as slash-replacement in IIIF identifier part newParameter("iiif-slash-replacement", "!", null, 'f'); }
--- a/common/src/main/java/digilib/conf/DigilibRequest.java Wed Mar 08 13:12:01 2017 +0100 +++ b/common/src/main/java/digilib/conf/DigilibRequest.java Thu Jun 01 15:06:02 2017 +0200 @@ -31,6 +31,9 @@ import java.io.UnsupportedEncodingException; import java.net.URLDecoder; +import java.util.ArrayList; +import java.util.EnumSet; +import java.util.List; import java.util.StringTokenizer; import org.apache.log4j.Logger; @@ -63,13 +66,26 @@ public class DigilibRequest extends ParameterMap { private static Logger logger = Logger.getLogger("digilib.request"); + + /** + * special options for parsing the request. + */ + public static enum ParsingOption { + omitIiifImageApi + } + /** active pasing options */ + public EnumSet<ParsingOption> parsingOptions = EnumSet.noneOf(ParsingOption.class); + /** IIIF path prefix (taken from config) */ protected String iiifPrefix = "IIIF"; /** IIIF slash replacement (taken from config) */ protected String iiifSlashReplacement = null; + /** parse IIIF path as IIIF image API */ + public boolean parseIiifImageApi = true; + /** error message while configuring */ public String errorMessage = null; @@ -154,6 +170,9 @@ newParameter("request.path", "", null, 'i'); // base URL (from http:// to below /servlet) newParameter("base.url", null, null, 'i'); + // elements of IIIF API path + newParameter("request.iiif.elements", null, null, 'i'); + /* * Parameters of type 'c' are for the clients use */ @@ -291,13 +310,9 @@ return false; } - String identifier = null; - String region = null; - String size = null; - String rotation = null; - String quality = null; - String format = null; - + List<String> params = new ArrayList<String>(5); + setValue("request.iiif.elements", params); + // enable passing of delimiter to get empty parameters StringTokenizer query = new StringTokenizer(path, "/", true); String token; @@ -317,80 +332,89 @@ } } /* - * second parameter identifier (encoded) + * following parameters */ - if (query.hasMoreTokens()) { + while (query.hasMoreTokens()) { token = getNextDecodedToken(query); if (!token.equals("/")) { - identifier = token; - // skip / - if (query.hasMoreTokens()) { - query.nextToken(); - } - } - } - /* - * third parameter region - */ - if (query.hasMoreTokens()) { - token = getNextDecodedToken(query); - if (!token.equals("/")) { - region = token; - // skip / - if (query.hasMoreTokens()) { - query.nextToken(); - } - } - } - /* - * fourth parameter size - */ - if (query.hasMoreTokens()) { - token = getNextDecodedToken(query); - if (!token.equals("/")) { - size = token; + params.add(token); // skip / if (query.hasMoreTokens()) { query.nextToken(); } - } - } - /* - * fifth parameter rotation - */ - if (query.hasMoreTokens()) { - token = getNextDecodedToken(query); - if (!token.equals("/")) { - rotation = token; - // skip / - if (query.hasMoreTokens()) { - query.nextToken(); - } - } - } - /* - * sixth parameter quality.format - */ - if (query.hasMoreTokens()) { - token = getNextDecodedToken(query); - // quality.format -- color depth and output format - try { - String[] parms = token.split("\\."); - // quality param - 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!"; - logger.error(errorMessage, e); - return false; + } else { + // empty parameter + params.add(null); } } + if (parsingOptions.contains(ParsingOption.omitIiifImageApi)) { + return true; + } + + /* + * parse sequence of parameters as IIIF image API + */ + String identifier = null; + String region = null; + String size = null; + String rotation = null; + String quality = null; + String format = null; + + if (params.size() > 0) { + /* + * first parameter identifier (encoded) + */ + identifier = params.get(0); + + if (params.size() > 1) { + /* + * second parameter region + */ + region = params.get(1); + + if (params.size() > 2) { + /* + * third parameter size + */ + size = params.get(2); + + if (params.size() > 3) { + /* + * fourth parameter rotation + */ + rotation = params.get(3); + + if (params.size() > 4) { + /* + * fifth parameter quality.format + */ + String qf = params.get(4); + if (qf != null) { + // quality.format -- color depth and output + // format + try { + String[] parms = qf.split("\\."); + // quality param + 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!"; + logger.error(errorMessage, e); + return false; + } + } + } + } + } + } + } // set request with these parameters - return setWithIiifParams(identifier, region, size, rotation, quality, format); + return setWithIiifImageParams(identifier, region, size, rotation, quality, format); } private String getNextDecodedToken(StringTokenizer tokens) { @@ -417,7 +441,7 @@ * @param format * @return */ - public boolean setWithIiifParams(String identifier, String region, String size, + public boolean setWithIiifImageParams(String identifier, String region, String size, String rotation, String quality, String format) { // alway set HTTP status code error reporting options.setOption(DigilibOption.errcode); @@ -427,14 +451,7 @@ */ if (identifier != null) { try { - if (identifier.contains("%")) { - // still escape chars -- decode again - identifier = URLDecoder.decode(identifier, "UTF-8"); - } - if (iiifSlashReplacement != null && identifier.contains(iiifSlashReplacement)) { - // change replacement back to slash - identifier = identifier.replace(iiifSlashReplacement, "/"); - } + identifier = decodeIiifIdentifier(identifier); setValueFromString("fn", identifier); } catch (UnsupportedEncodingException e) { errorMessage = "Error decoding identifier in IIIF path!"; @@ -614,6 +631,23 @@ return true; } + /** + * @param identifier + * @return + * @throws UnsupportedEncodingException + */ + public String decodeIiifIdentifier(String identifier) throws UnsupportedEncodingException { + if (identifier.contains("%")) { + // still escape chars -- decode again + identifier = URLDecoder.decode(identifier, "UTF-8"); + } + if (iiifSlashReplacement != null && identifier.contains(iiifSlashReplacement)) { + // change replacement back to slash + identifier = identifier.replace(iiifSlashReplacement, "/"); + } + return identifier; + } + /** * Test if option string <code>opt</code> is set. Checks if the substring
--- a/common/src/main/java/digilib/io/DocuDirectory.java Wed Mar 08 13:12:01 2017 +0100 +++ b/common/src/main/java/digilib/io/DocuDirectory.java Thu Jun 01 15:06:02 2017 +0200 @@ -30,6 +30,7 @@ import java.io.File; import java.util.ArrayList; import java.util.Collections; +import java.util.Iterator; import java.util.List; import digilib.conf.DigilibConfiguration; @@ -47,7 +48,7 @@ * * @author casties */ -public abstract class DocuDirectory extends Directory { +public abstract class DocuDirectory extends Directory implements Iterable<DocuDirent> { /** type of files in this DocuDirectory */ protected FileClass fileClass = FileClass.IMAGE; @@ -347,6 +348,15 @@ public DirMeta getMeta() { return meta; } + + /** + * Returns an Iterator over all DocuDirents in this DocuDirectory in default order. + * + * @return + */ + public Iterator<DocuDirent> iterator() { + return files.iterator(); + } private boolean isBasenameInList(List<DocuDirent> fileList, int idx, String fn) { String dfn = FileOps.basename((fileList.get(idx)).getName());
--- a/common/src/main/java/digilib/util/ParameterMap.java Wed Mar 08 13:12:01 2017 +0100 +++ b/common/src/main/java/digilib/util/ParameterMap.java Thu Jun 01 15:06:02 2017 +0200 @@ -130,7 +130,7 @@ /** Get the Parameter with the corresponding key. * - * Returns null if no element is associated with key. + * Returns empty string if no element is associated with key. * * @param key * @return @@ -142,7 +142,7 @@ /** Get the Parameter with the corresponding key. * - * Returns null if no element is associated with key. + * Returns 0 if no element is associated with key. * * @param key * @return @@ -154,7 +154,7 @@ /** Get the Parameter with the corresponding key. * - * Returns null if no element is associated with key. + * Returns 0 if no element is associated with key. * * @param key * @return @@ -166,7 +166,7 @@ /** Get the Parameter with the corresponding key. * - * Returns null if no element is associated with key. + * Returns false if no element is associated with key. * * @param key * @return
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/iiif-presentation/pom.xml Thu Jun 01 15:06:02 2017 +0200 @@ -0,0 +1,41 @@ +<?xml version="1.0"?> +<project + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" + xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>digilib</groupId> + <artifactId>digilib</artifactId> + <version>2.5-SNAPSHOT</version> + </parent> + <artifactId>digilib-iiif-presentation</artifactId> + <name>digilib-iiif-presentation</name> + <description>The Digital Image Library - IIIF presentation API manifest serving servlet</description> + <url>http://digilib.sourceforge.net</url> + <properties> + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + </properties> + <dependencies> + <dependency> + <groupId>digilib</groupId> + <artifactId>digilib-servlet</artifactId> + </dependency> + <dependency> + <groupId>org.mortbay.jetty</groupId> + <artifactId>servlet-api</artifactId> + <version>3.0.20100224</version> + <type>jar</type> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>javax.json</groupId> + <artifactId>javax.json-api</artifactId> + <version>1.1</version> + </dependency> + <dependency> + <groupId>org.glassfish</groupId> + <artifactId>javax.json</artifactId> + <version>1.1</version> + </dependency> + </dependencies> +</project>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/iiif-presentation/src/main/java/digilib/conf/ManifestServletConfiguration.java Thu Jun 01 15:06:02 2017 +0200 @@ -0,0 +1,114 @@ +package digilib.conf; + +/* + * #%L + * + * ManifesteServletConfiguration.java + * + * Digital Image Library servlet components + * %% + * Copyright (C) 2003 - 2017 MPIWG Berlin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + * Author: Robert Casties (robcast@sourceforge.net) + * Created on 24.5.2017 + */ + +import javax.servlet.ServletContext; +import javax.servlet.annotation.WebListener; + +/** + * Class to hold the digilib servlet configuration parameters. The parameters + * can be read from the digilib-config file and be passed to other servlets or + * beans. + * + * @author casties + */ +@WebListener +public class ManifestServletConfiguration extends DigilibServletConfiguration { + + public static final String MANIFEST_SERVLET_CONFIG_KEY = "digilib.manifest.servlet.configuration"; + + public static String getClassVersion() { + return DigilibConfiguration.getClassVersion() + " manif"; + } + + /** non-static getVersion for Java inheritance */ + @Override + public String getVersion() { + return getClassVersion(); + } + + /** + * Constructs DigilibServletConfiguration and defines all parameters and + * their default values. + */ + public ManifestServletConfiguration() { + super(); + + // Scaler servlet name used in constructing IIIF image API paths + newParameter("scaler-servlet-path", "Scaler", null, 'f'); + } + + /* + * (non-Javadoc) + * + * @see digilib.conf.DigilibServletConfiguration#configure(javax.servlet. + * ServletContext) + */ + @Override + public void configure(ServletContext context) { + super.configure(context); + + // set version + setValue("servlet.version", getVersion()); + + } + + /** + * Sets the current DigilibConfiguration in the context. + * @param context + */ + @Override + public void setContextConfig(ServletContext context) { + context.setAttribute(ManifestServletConfiguration.MANIFEST_SERVLET_CONFIG_KEY, this); + } + + /** + * Returns the current TextServletConfiguration from the context. + * + * @param context + * @return + */ + public static DigilibServletConfiguration getCurrentConfig(ServletContext context) { + DigilibServletConfiguration config = (DigilibServletConfiguration) context + .getAttribute(ManifestServletConfiguration.MANIFEST_SERVLET_CONFIG_KEY); + return config; + } + + /** + * Returns the current DigilibConfiguration from the context. + * (non-static method, for Java inheritance) + * + * @param context + * @return + */ + @Override + protected DigilibServletConfiguration getContextConfig(ServletContext context) { + return getCurrentConfig(context); + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/iiif-presentation/src/main/java/digilib/servlet/Manifester.java Thu Jun 01 15:06:02 2017 +0200 @@ -0,0 +1,523 @@ +package digilib.servlet; + +/* + * #%L + * + * Manifester.java -- Servlet for creating IIIF Presentation API manifests. + * + * Digital Image Library servlet components + * %% + * Copyright (C) 2003 - 2017 MPIWG Berlin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + * Author: Robert Casties (robcast@sourceforge.net) + * Created on 24.5.2017 + */ + +import java.io.IOException; +import java.util.EnumSet; +import java.util.List; + +import javax.json.Json; +import javax.json.stream.JsonGenerator; +import javax.servlet.ServletConfig; +import javax.servlet.ServletContext; +import javax.servlet.ServletException; +import javax.servlet.ServletOutputStream; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.log4j.Logger; + +import digilib.auth.AuthOpException; +import digilib.auth.AuthzOps; +import digilib.conf.DigilibRequest.ParsingOption; +import digilib.conf.DigilibServletConfiguration; +import digilib.conf.DigilibServletRequest; +import digilib.conf.ManifestServletConfiguration; +import digilib.io.DocuDirCache; +import digilib.io.DocuDirectory; +import digilib.io.DocuDirent; +import digilib.io.FileOps; +import digilib.io.ImageFileSet; +import digilib.io.ImageInput; +import digilib.util.ImageSize; + +/** + * Servlet for creating IIIF Presentation API manifests. + * + * + * @author casties + * + */ +public class Manifester extends HttpServlet { + + private static final long serialVersionUID = 6678666342141409868L; + + /** Servlet version */ + public static String mfVersion = ManifestServletConfiguration.getClassVersion(); + + /** DigilibConfiguration instance */ + protected DigilibServletConfiguration dlConfig = null; + + /** general logger */ + protected Logger logger = Logger.getLogger("digilib.manifester"); + + /** logger for accounting requests */ + protected static Logger accountlog = Logger.getLogger("account.manifester.request"); + + /** AuthOps instance */ + protected AuthzOps authzOp; + + /** DocuDirCache instance */ + protected DocuDirCache dirCache; + + /** use authentication */ + protected boolean useAuthorization = false; + + /** scaler servlet path */ + protected String scalerServletPath; + + /** character for IIIF path separation */ + protected String iiifPathSep; + + /** set CORS header ACAO* for info requests */ + protected boolean corsForInfoRequests = true; + + /* + * (non-Javadoc) + * + * @see javax.servlet.Servlet#init(javax.servlet.ServletConfig) + */ + public void init(ServletConfig config) throws ServletException { + super.init(config); + + System.out.println("***** Digital Image Library IIF Manifest Servlet (version " + mfVersion + ") *****"); + + // get our ServletContext + ServletContext context = config.getServletContext(); + // see if there is a Configuration instance + dlConfig = ManifestServletConfiguration.getCurrentConfig(context); + if (dlConfig == null) { + // no Configuration + throw new ServletException("No Configuration!"); + } + // say hello in the log file + logger.info("***** Digital Image Library IIIF Manifest Servlet (version " + mfVersion + ") *****"); + + // set our AuthOps + useAuthorization = dlConfig.getAsBoolean("use-authorization"); + authzOp = (AuthzOps) dlConfig.getValue(DigilibServletConfiguration.AUTHZ_OP_KEY); + // DocuDirCache instance + dirCache = (DocuDirCache) dlConfig.getValue(DigilibServletConfiguration.DIR_CACHE_KEY); + // Scaler path + scalerServletPath = dlConfig.getAsString("scaler-servlet-path"); + // IIIF path separator + iiifPathSep = dlConfig.getAsString("iiif-slash-replacement"); + // CORS for info requests + corsForInfoRequests = dlConfig.getAsBoolean("iiif-info-cors"); + } + + /** + * Returns modification time relevant to the request for caching. + * + * @see javax.servlet.http.HttpServlet#getLastModified(javax.servlet.http.HttpServletRequest) + */ + public long getLastModified(HttpServletRequest request) { + accountlog.debug("GetLastModified from " + request.getRemoteAddr() + " for " + request.getQueryString()); + long mtime = -1; + try { + // create new digilib request + DigilibServletRequest dlRequest = new DigilibServletRequest(request, dlConfig, + EnumSet.of(ParsingOption.omitIiifImageApi)); + // get list of IIIF parameters + @SuppressWarnings("unchecked") + List<String> iiifParams = (List<String>) dlRequest.getValue("request.iiif.elements"); + // get identifier (first parameter) + String identifier = iiifParams.get(0); + // decode identifier to file path + dlRequest.setValueFromString("fn", dlRequest.decodeIiifIdentifier(identifier)); + DocuDirectory dd = dirCache.getDirectory(dlRequest.getFilePath()); + if (dd != null) { + mtime = dd.getDirMTime() / 1000 * 1000; + } + } catch (Exception e) { + logger.error("error in getLastModified: " + e.getMessage()); + } + logger.debug(" returns " + mtime); + return mtime; + } + + /* + * (non-Javadoc) + * + * @see javax.servlet.http.HttpServlet#doGet(javax.servlet.http. + * HttpServletRequest, javax.servlet.http.HttpServletResponse) + */ + protected void doGet(HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException { + accountlog.info("GET from " + request.getRemoteAddr()); + // do the processing + processRequest(request, response); + } + + /* + * (non-Javadoc) + * + * @see javax.servlet.http.HttpServlet#doPost(javax.servlet.http. + * HttpServletRequest, javax.servlet.http.HttpServletResponse) + */ + protected void doPost(HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException { + accountlog.info("POST from " + request.getRemoteAddr()); + // do the processing + processRequest(request, response); + } + + protected void processRequest(HttpServletRequest request, HttpServletResponse response) { + try { + // create DigilibRequest from ServletRequest, omit IIIF Image API parsing + DigilibServletRequest dlRequest = new DigilibServletRequest(request, dlConfig, + EnumSet.of(ParsingOption.omitIiifImageApi)); + // get list of IIIF parameters + @SuppressWarnings("unchecked") + List<String> iiifParams = (List<String>) dlRequest.getValue("request.iiif.elements"); + if (iiifParams == null) { + logger.error("Invalid IIIF request."); + response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Invalid IIIF request."); + return; + } + // get identifier (first parameter) + String identifier = iiifParams.get(0); + if (identifier == null) { + logger.error("IIIF identifier missing"); + response.sendError(HttpServletResponse.SC_BAD_REQUEST, "IIIF identifier missing."); + return; + } + // decode identifier to file path + dlRequest.setValueFromString("fn", dlRequest.decodeIiifIdentifier(identifier)); + // get directory path + String dlFn = dlRequest.getFilePath(); + // get information about the directory + DocuDirectory dlDir = dirCache.getDirectory(dlFn); + if (dlDir == null) { + logger.error("Directory for manifest not found: " + dlFn); + response.sendError(HttpServletResponse.SC_NOT_FOUND); + return; + } + if (dlDir.size() == 0) { + logger.debug("Directory has no files: " + dlFn); + response.sendError(HttpServletResponse.SC_NOT_FOUND); + return; + } + + ManifestParams params = new ManifestParams(); + + /* + * set CORS header ACAO "*" for info response as per IIIF spec + */ + if (corsForInfoRequests) { + String origin = request.getHeader("Origin"); + if (origin != null) { + response.setHeader("Access-Control-Allow-Origin", "*"); + } + } + + /* + * check permissions + */ + if (useAuthorization) { + // is the current request/user authorized? + if (!authzOp.isAuthorized(dlRequest)) { + // TODO: does this work for directories? + // send deny answer and abort + throw new AuthOpException("Access denied!"); + } + } + + // use JSON-LD content type only when asked + String accept = request.getHeader("Accept"); + if (accept != null && accept.contains("application/ld+json")) { + response.setContentType("application/ld+json"); + } else { + response.setContentType("application/json"); + } + + /* + * get manifest base URL + */ + String url = request.getRequestURL().toString(); + // get base URL for Servlets + int srvPathLen = request.getServletPath().length() + request.getPathInfo().length(); + String servletBaseUrl = url.substring(0, url.length() - srvPathLen); + // manifest base URL + String baseurl = servletBaseUrl + request.getServletPath() + "/" + dlConfig.getAsString("iiif-prefix") + "/" + identifier; + + params.manifestUrl = baseurl; + params.imgApiUrl = servletBaseUrl +"/" + this.scalerServletPath + "/" + dlConfig.getAsString("iiif-prefix"); + params.identifier = identifier; + params.docuDir = dlDir; + + /* + * start json representation + */ + ServletOutputStream out = response.getOutputStream(); + JsonGenerator manifest = Json.createGenerator(out).writeStartObject(); + /* + * manifest metadata + */ + writeManifestMeta(manifest, dlFn, params); + + /* + * sequences + */ + writeSequences(manifest, params); + + manifest.writeEnd(); // manifest + manifest.close(); + + } catch (IOException e) { + logger.error("ERROR sending manifest: ", e); + } catch (AuthOpException e) { + logger.debug("Permission denied."); + try { + response.sendError(HttpServletResponse.SC_FORBIDDEN); + } catch (IOException e1) { + logger.error("Error sending error: ", e); + } + } + } + + /** + * @param manifest + * @param dlFn + * @param params + */ + protected void writeManifestMeta(JsonGenerator manifest, String dlFn, ManifestParams params) { + manifest.write("@context", "http://iiif.io/api/presentation/2/context.json") + .write("@type", "sc:Manifest") + .write("@id", params.manifestUrl + "/manifest") + .write("label", "[Scanned work " + dlFn + "]") + .write("description", "[Automatically generated manifest for scanned work " + dlFn + "]"); + } + + /** + * @param dlDir + * @param url + * @param manifest + * @param servletBaseUrl + */ + protected void writeSequences(JsonGenerator manifest, ManifestParams params) { + manifest.writeStartArray("sequences"); + /* + * first sequence + */ + writeSequence(manifest, params); + + manifest.writeEnd(); // sequences + } + + /** + * @param dlDir + * @param url + * @param manifest + * @param servletUrl + */ + protected void writeSequence(JsonGenerator manifest, ManifestParams params) { + manifest.writeStartObject() + .write("@id", params.manifestUrl + "/sequence/default") + .write("@type", "sc:Sequence") + .write("label", "Scan image order"); + /* + * canvases + */ + writeCanvases(manifest, params); + + manifest.writeEnd(); // sequence + } + + /** + * @param dlDir + * @param url + * @param manifest + * @param servletUrl + */ + protected void writeCanvases(JsonGenerator manifest, ManifestParams params) { + /* + * list of canvases + */ + manifest.writeStartArray("canvases"); + + int idx = 0; + for (DocuDirent imgFile : params.docuDir) { + idx += 1; + ImageFileSet imgFs = (ImageFileSet) imgFile; + ImageInput img = imgFs.getBiggest(); + ImageSize imgSize = img.getSize(); + /* + * canvas + */ + writeCanvas(manifest, idx, imgFile, imgSize, params); + } + + manifest.writeEnd(); // canvases + } + + /** + * @param url + * @param manifest + * @param idx + * @param imgFile + * @param imgSize + * @param servletUrl + */ + protected void writeCanvas(JsonGenerator manifest, int idx, DocuDirent imgFile, ImageSize imgSize, + ManifestParams params) { + manifest.writeStartObject() + .write("@type", "sc:Canvas") + .write("@id", params.manifestUrl + "/canvas/p" + idx) + .write("label", "image " + FileOps.basename(imgFile.getName())) + .write("height", imgSize.getHeight()) + .write("width", imgSize.getWidth()); + /* + * images + */ + writeImages(manifest, idx, imgFile, imgSize, params); + + manifest.writeEnd(); // canvas + } + + /** + * @param url + * @param manifest + * @param idx + * @param imgFile + * @param imgSize + * @param servletUrl + */ + protected void writeImages(JsonGenerator manifest, int idx, DocuDirent imgFile, ImageSize imgSize, + ManifestParams params) { + /* + * list of images (just one) + */ + manifest.writeStartArray("images"); + /* + * image + */ + writeImage(manifest, idx, imgFile, imgSize, params); + + manifest.writeEnd(); // images + } + + /** + * @param url + * @param manifest + * @param idx + * @param imgFile + * @param imgSize + * @param servletUrl + */ + protected void writeImage(JsonGenerator manifest, int idx, DocuDirent imgFile, ImageSize imgSize, + ManifestParams params) { + /* + * image + */ + manifest.writeStartObject() + .write("@type", "oa:Annotation") + .write("@id", params.manifestUrl + "/annotation/p" + idx + "-image") + .write("motivation", "sc:painting"); + /* + * resource + */ + writeResource(manifest, imgFile, imgSize, params); + + manifest.write("on", params.manifestUrl + "/canvas/p" + idx) + .writeEnd(); // image + } + + /** + * @param url + * @param manifest + * @param imgFile + * @param imgSize + * @param servletUrl + */ + protected void writeResource(JsonGenerator manifest, DocuDirent imgFile, ImageSize imgSize, + ManifestParams params) { + // base URL for image using IIIF image API + String iiifImgBaseUrl = params.imgApiUrl + "/" + params.identifier + this.iiifPathSep + FileOps.basename(imgFile.getName()); + // IIIF image parameters + String imgUrl = iiifImgBaseUrl + "/full/full/0/default.jpg"; + /* + * resource + */ + manifest.writeStartObject("resource") + .write("@id", imgUrl) + .write("@type", "dctypes:Image") + .write("format", "image/jpeg") + .write("height", imgSize.getHeight()) + .write("width", imgSize.getWidth()); + /* + * (iiif) service + */ + writeService(manifest, iiifImgBaseUrl, imgSize, params); + + manifest.writeEnd(); // resource + } + + /** + * @param manifest + * @param iiifImgBaseUrl + * @param imgSize + * @param servletUrl + */ + protected void writeService(JsonGenerator manifest, String iiifImgBaseUrl, ImageSize imgSize, + ManifestParams params) { + /* + * service + */ + manifest.writeStartObject("service") + .write("@context", "http://iiif.io/api/image/2/context.json") + .write("@id", iiifImgBaseUrl) + .write("profile", "http://iiif.io/api/image/2/profiles/level2.json") + // maximum size + .write("height", imgSize.getHeight()) + .write("width", imgSize.getWidth()) + /* other sizes + .writeStartArray("sizes") + .writeStartObject() + .write("width", 100) + .write("height", 100) + .writeEnd() // size + .writeEnd() // sizes + */ + + .writeEnd(); // service + } + + /** + * Class holding parameters to construct manifest. + * @author casties + * + */ + protected class ManifestParams { + public DocuDirectory docuDir; + String manifestUrl; + String imgApiUrl; + String identifier; + } +} \ No newline at end of file
--- a/pom.xml Wed Mar 08 13:12:01 2017 +0100 +++ b/pom.xml Thu Jun 01 15:06:02 2017 +0200 @@ -1,6 +1,5 @@ <?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"> +<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> <properties> @@ -158,6 +157,12 @@ </modules> </profile> <profile> + <id>iiif-presentation</id> + <modules> + <module>iiif-presentation</module> + </modules> + </profile> + <profile> <id>pdf</id> <modules> <module>pdf</module> @@ -230,6 +235,11 @@ </dependency> <dependency> <groupId>digilib</groupId> + <artifactId>digilib-iiif-presentation</artifactId> + <version>2.5-SNAPSHOT</version> + </dependency> + <dependency> + <groupId>digilib</groupId> <artifactId>digilib-servlet</artifactId> <version>2.5-SNAPSHOT</version> </dependency>
--- a/servlet/src/main/java/digilib/conf/DigilibServletConfiguration.java Wed Mar 08 13:12:01 2017 +0100 +++ b/servlet/src/main/java/digilib/conf/DigilibServletConfiguration.java Thu Jun 01 15:06:02 2017 +0200 @@ -171,6 +171,10 @@ newParameter("docudirectory-class", "digilib.io.BaseDirDocuDirectory", null, 'f'); // name of cookie with authentication token newParameter("authn-token-cookie", "id_token", null, 'f'); + // set CORS header on IIIF Image API info request + newParameter("iiif-info-cors", Boolean.TRUE, null, 'f'); + // set CORS header on IIIF Image API image request + newParameter("iiif-image-cors", Boolean.TRUE, null, 'f'); } /**
--- a/servlet/src/main/java/digilib/conf/DigilibServletRequest.java Wed Mar 08 13:12:01 2017 +0100 +++ b/servlet/src/main/java/digilib/conf/DigilibServletRequest.java Thu Jun 01 15:06:02 2017 +0200 @@ -1,5 +1,7 @@ package digilib.conf; +import java.util.EnumSet; + /* * #%L * DigilibRequest.java @@ -73,7 +75,6 @@ * ServletRequest. All undefined parameters are set to default values. * * @param request - * @throws ImageOpException */ public DigilibServletRequest(HttpServletRequest request) { super(); @@ -86,7 +87,7 @@ * ServletRequest. All undefined parameters are set to default values. * * @param request - * @throws ImageOpException + * @param config */ public DigilibServletRequest(HttpServletRequest request, DigilibConfiguration config) { super(config); @@ -94,58 +95,34 @@ initOptions(); } + /** + * Creates a new instance of DigilibRequest with parameters from a + * ServletRequest. All undefined parameters are set to default values. + * + * @param request + * @param config + * @param parsingOptions + */ + public DigilibServletRequest(HttpServletRequest request, DigilibConfiguration config, + EnumSet<ParsingOption> parsingOptions) { + super(config); + this.parsingOptions = parsingOptions; + setWithRequest(request); + initOptions(); + } + /* (non-Javadoc) * @see digilib.conf.DigilibRequest#initParams() * Define and set up parameters with default values. */ @Override protected void initParams() { - // TODO: check if we can call super.initParams() + super.initParams(); /* - * Definition of parameters and default values. Parameter of type 's' + * Definition of additional parameters and default values. Parameter of type 's' * are for the servlet. */ - // url of the page/document (second part) - newParameter("fn", "", null, 's'); - // page number - newParameter("pn", new Integer(1), null, 's'); - // width of client in pixels - newParameter("dw", new Integer(0), null, 's'); - // height of client in pixels - newParameter("dh", new Integer(0), null, 's'); - // left edge of image (float from 0 to 1) - newParameter("wx", new Float(0), null, 's'); - // top edge in image (float from 0 to 1) - newParameter("wy", new Float(0), null, 's'); - // width of image (float from 0 to 1) - newParameter("ww", new Float(1), null, 's'); - // height of image (float from 0 to 1) - newParameter("wh", new Float(1), null, 's'); - // scale factor - newParameter("ws", new Float(1), null, 's'); - // special options like 'fit' for gifs - newParameter("mo", this.options, null, 's'); - // rotation angle (degree) - newParameter("rot", new Float(0), null, 's'); - // contrast enhancement factor - newParameter("cont", new Float(0), null, 's'); - // brightness enhancement factor - newParameter("brgt", new Float(0), null, 's'); - // color multiplicative factors - newParameter("rgbm", "0/0/0", null, 's'); - // color additive factors - newParameter("rgba", "0/0/0", null, 's'); - // display dpi resolution (total) - newParameter("ddpi", new Float(0), null, 's'); - // display dpi X resolution - newParameter("ddpix", new Float(0), null, 's'); - // display dpi Y resolution - newParameter("ddpiy", new Float(0), null, 's'); - // scale factor for mo=ascale - newParameter("scale", new Float(1), null, 's'); - // color conversion operation - newParameter("colop", "", null, 's'); // OpenID Connect ID token newParameter("id_token", "", null, 's'); @@ -154,39 +131,12 @@ * 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, null, 'i'); // DocuImage instance for this request newParameter("docu.image", image, null, 'i'); image = null; // HttpServletRequest for this request newParameter("servlet.request", servletRequest, null, 'i'); servletRequest = null; - - /* - * 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'); - - /* - * set local variables from config - */ - if (config != null) { - iiifPrefix = config.getAsString("iiif-prefix"); - iiifSlashReplacement = config.getAsString("iiif-slash-replacement"); - } } /* @@ -212,7 +162,9 @@ setValue("servlet.request", request); // request path (after servlet, before "?") String path = request.getPathInfo(); - // decide if its IIIF API + /* + * is it IIIF API? + */ if (path != null && path.startsWith(iiifPrefix, 1)) { // for IIIF we need the undecoded path :-( String uri = request.getRequestURI(); @@ -228,7 +180,9 @@ setValue("dw", -1); } } else { - // decide if it's old-style or new-style digilib + /* + * is it old-style or new-style digilib? + */ String qs = ((HttpServletRequest) request).getQueryString(); if (qs != null) { if (qs.indexOf("&") > -1) {
--- a/servlet/src/main/java/digilib/servlet/ServletOps.java Wed Mar 08 13:12:01 2017 +0100 +++ b/servlet/src/main/java/digilib/servlet/ServletOps.java Thu Jun 01 15:06:02 2017 +0200 @@ -41,6 +41,7 @@ import org.apache.log4j.Logger; +import digilib.conf.DigilibServletConfiguration; import digilib.conf.DigilibServletRequest; import digilib.image.DocuImage; import digilib.image.ImageOpException; @@ -52,16 +53,39 @@ public class ServletOps { - private static Logger logger = Logger.getLogger("servlet.op"); + protected static Logger logger = Logger.getLogger("servlet.op"); + + protected static DigilibServletConfiguration dlConfig; + + /** set CORS header ACAO* for info requests */ + protected static boolean corsForInfoRequests = true; + + /** set CORS header ACAO* for image requests */ + protected static boolean corsForImageRequests = true; /** + * @return the dlConfig + */ + public static DigilibServletConfiguration getDlConfig() { + return dlConfig; + } + + /** + * @param dlConfig the dlConfig to set + */ + public static void setDlConfig(DigilibServletConfiguration dlConfig) { + ServletOps.dlConfig = dlConfig; + corsForInfoRequests = dlConfig.getAsBoolean("iiif-info-cors"); + corsForImageRequests = dlConfig.getAsBoolean("iiif-image-cors"); + } + + /** * convert a string with a list of pathnames into an array of strings using * the system's path separator string */ public static String[] getPathArray(String paths) { // split list into directories - StringTokenizer dirs = new StringTokenizer(paths, - java.io.File.pathSeparator); + StringTokenizer dirs = new StringTokenizer(paths, java.io.File.pathSeparator); int n = dirs.countTokens(); if (n < 1) { return null; @@ -225,6 +249,7 @@ * The local file is copied to the <code>OutputStream</code> of the * <code>ServletResponse</code>. If mt is null then the mime-type is * auto-detected with mimeForFile. + * * @param f * Image file to be sent. * @param mt @@ -246,6 +271,9 @@ logger.error("No response!"); return; } + /* + * set content-type + */ if (mt == null) { // auto-detect mime-type mt = FileOps.mimeForFile(f); @@ -254,7 +282,6 @@ } } response.setContentType(mt); - // open file if (mt.startsWith("application")) { if (name == null) { // no download name -- use filename @@ -262,7 +289,19 @@ } response.addHeader("Content-Disposition", "attachment; filename=\""+name+"\""); } - FileInputStream inFile = null; + + /* + * set CORS header ACAO "*" for image response + */ + if (corsForImageRequests) { + // TODO: would be nice to check request for Origin header + response.setHeader("Access-Control-Allow-Origin", "*"); + } + + /* + * open file + */ + FileInputStream inFile = null; try { inFile = new FileInputStream(f); OutputStream outStream = response.getOutputStream(); @@ -313,9 +352,8 @@ * @throws ImageOpException * @throws ServletException Exception on sending data. */ - public static void sendImage(DocuImage img, String mimeType, - HttpServletResponse response, Logger logger) throws ImageOpException, - ServletException { + public static void sendImage(DocuImage img, String mimeType, HttpServletResponse response, Logger logger) + throws ImageOpException, ServletException { if (response == null) { logger.error("No response!"); return; @@ -342,6 +380,7 @@ } // set the content type response.setContentType(mimeType); + // check content type String respType = response.getContentType(); if (! mimeType.equals(respType)) { // this shouldn't happen @@ -351,6 +390,15 @@ return; } + + /* + * set CORS header ACAO "*" for image response + */ + if (corsForImageRequests) { + // TODO: would be nice to check request for Origin header + response.setHeader("Access-Control-Allow-Origin", "*"); + } + /* * write the image */ @@ -375,7 +423,8 @@ * @throws ServletException * @see <a href="http://www-sul.stanford.edu/iiif/image-api/1.1/#info">IIIF Image Information Request</a> */ - public static void sendIiifInfo(DigilibServletRequest dlReq, HttpServletResponse response, Logger logger) throws ServletException { + public static void sendIiifInfo(DigilibServletRequest dlReq, HttpServletResponse response, Logger logger) + throws ServletException { if (response == null) { logger.error("No response!"); return; @@ -419,7 +468,7 @@ /* * set CORS header ACAO "*" for info response as per IIIF spec */ - if (dlReq.getDigilibConfig().getAsBoolean("iiif-info-cors")) { + if (corsForInfoRequests) { String origin = dlReq.getServletRequest().getHeader("Origin"); if (origin != null) { response.setHeader("Access-Control-Allow-Origin", "*"); @@ -427,7 +476,7 @@ } PrintWriter writer; - if (dlReq.getDigilibConfig().getAsString("iiif-api-version").startsWith("2.")) { + if (dlConfig.getAsString("iiif-api-version").startsWith("2.")) { /* * IIIF Image API version 2 image information */
--- a/servlet2/src/main/java/digilib/servlet/Scaler.java Wed Mar 08 13:12:01 2017 +0100 +++ b/servlet2/src/main/java/digilib/servlet/Scaler.java Thu Jun 01 15:06:02 2017 +0200 @@ -147,6 +147,9 @@ // Executor imageJobCenter = (DigilibJobCenter<DocuImage>) dlConfig.getValue("servlet.worker.imageexecutor"); + // configure ServletOps + ServletOps.setDlConfig(dlConfig); + denyImgFile = ServletOps.getFile(dlConfig.getAsFile("denied-image"), context); errorImgFile = ServletOps.getFile(dlConfig.getAsFile("error-image"), context); notfoundImgFile = ServletOps.getFile(dlConfig.getAsFile("notfound-image"), context);
--- a/servlet2/src/main/java/digilib/servlet/ScalerNoThread.java Wed Mar 08 13:12:01 2017 +0100 +++ b/servlet2/src/main/java/digilib/servlet/ScalerNoThread.java Thu Jun 01 15:06:02 2017 +0200 @@ -130,6 +130,9 @@ // DocuDirCache instance dirCache = (DocuDirCache) dlConfig.getValue("servlet.dir.cache"); + // configure ServletOps + ServletOps.setDlConfig(dlConfig); + denyImgFile = ServletOps.getFile((File) dlConfig.getValue("denied-image"), context); errorImgFile = ServletOps.getFile((File) dlConfig.getValue("error-image"), context); notfoundImgFile = ServletOps.getFile((File) dlConfig.getValue("notfound-image"), context);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/servlet3/pom.xml.orig Thu Jun 01 15:06:02 2017 +0200 @@ -0,0 +1,39 @@ +<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> + <artifactId>digilib</artifactId> + <groupId>digilib</groupId> + <version>2.3.1</version> + </parent> + <artifactId>digilib-servlet3</artifactId> + <name>digilib-servlet3</name> + <build> + <pluginManagement> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-compiler-plugin</artifactId> + <version>3.3</version> + <configuration> + <source>1.7</source> + <target>1.7</target> + </configuration> + </plugin> + </plugins> + </pluginManagement> + </build> + <dependencies> + <dependency> + <groupId>org.mortbay.jetty</groupId> + <artifactId>servlet-api</artifactId> + <version>3.0.20100224</version> + <type>jar</type> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>digilib</groupId> + <artifactId>digilib-servlet</artifactId> + </dependency> + </dependencies> + <description>digilib servlet components using asynchronous servlet API.</description> +</project> \ No newline at end of file
--- a/servlet3/src/main/java/digilib/servlet/Scaler.java Wed Mar 08 13:12:01 2017 +0100 +++ b/servlet3/src/main/java/digilib/servlet/Scaler.java Thu Jun 01 15:06:02 2017 +0200 @@ -42,7 +42,6 @@ import digilib.auth.AuthOpException; import digilib.auth.AuthzOps; -import digilib.conf.DigilibConfiguration; import digilib.conf.DigilibOption; import digilib.conf.DigilibServlet3Configuration; import digilib.conf.DigilibServletConfiguration; @@ -104,7 +103,7 @@ protected boolean sendFileAllowed = true; /** DigilibConfiguration instance */ - protected DigilibConfiguration dlConfig; + protected DigilibServletConfiguration dlConfig; /** use authorization database */ protected boolean useAuthorization = false; @@ -142,11 +141,14 @@ authzOp = (AuthzOps) dlConfig.getValue(DigilibServletConfiguration.AUTHZ_OP_KEY); // DocuDirCache instance - dirCache = (DocuDirCache) dlConfig.getValue("servlet.dir.cache"); + dirCache = (DocuDirCache) dlConfig.getValue(DigilibServletConfiguration.DIR_CACHE_KEY); // Executor imageJobCenter = (DigilibJobCenter<DocuImage>) dlConfig.getValue("servlet.worker.imageexecutor"); + // configure ServletOps + ServletOps.setDlConfig(dlConfig); + denyImgFile = ServletOps.getFile(dlConfig.getAsFile("denied-image"), context); errorImgFile = ServletOps.getFile(dlConfig.getAsFile("error-image"), context); notfoundImgFile = ServletOps.getFile(dlConfig.getAsFile("notfound-image"), context); @@ -260,8 +262,14 @@ return; } if (dlRequest.hasOption(DigilibOption.redirect_info)) { + StringBuffer url = request.getRequestURL(); + if (url.toString().endsWith("/")) { + url.append("info.json"); + } else { + url.append("/info.json"); + } // TODO: the redirect should have code 303 - response.sendRedirect("info.json"); + response.sendRedirect(url.toString()); return; }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/text/pom.xml.orig Thu Jun 01 15:06:02 2017 +0200 @@ -0,0 +1,72 @@ +<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> + <artifactId>digilib</artifactId> + <groupId>digilib</groupId> + <version>2.3.1</version> + </parent> + <artifactId>digilib-text</artifactId> + <name>digilib-text</name> + <dependencies> + <dependency> + <groupId>digilib</groupId> + <artifactId>digilib-common</artifactId> + <type>jar</type> + <scope>compile</scope> + </dependency> + </dependencies> + <description>The Digital Image Library - text (plain or XML) serving servlet</description> + <url>http://digilib.sourceforge.net</url> + <profiles> + <profile> + <id>servlet2</id> + <activation> + <activeByDefault>true</activeByDefault> + <property> + <name>servletapi</name> + <value>2</value> + </property> + </activation> + <dependencies> + <dependency> + <groupId>digilib</groupId> + <artifactId>digilib-servlet2</artifactId> + <type>jar</type> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>javax.servlet</groupId> + <artifactId>servlet-api</artifactId> + <version>2.3</version> + <type>jar</type> + <scope>provided</scope> + </dependency> + </dependencies> + </profile> + <profile> + <id>servlet3</id> + <activation> + <property> + <name>servletapi</name> + <value>3</value> + </property> + </activation> + <dependencies> + <dependency> + <groupId>digilib</groupId> + <artifactId>digilib-servlet3</artifactId> + <type>jar</type> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.mortbay.jetty</groupId> + <artifactId>servlet-api</artifactId> + <version>3.0.20100224</version> + <type>jar</type> + <scope>provided</scope> + </dependency> + </dependencies> + </profile> + </profiles> +</project> \ No newline at end of file
--- a/text/src/main/java/digilib/servlet/Texter.java Wed Mar 08 13:12:01 2017 +0100 +++ b/text/src/main/java/digilib/servlet/Texter.java Thu Jun 01 15:06:02 2017 +0200 @@ -62,28 +62,25 @@ public static String tlVersion = TextServletConfiguration.getClassVersion(); /** DigilibConfiguration instance */ - DigilibServletConfiguration dlConfig = null; + protected DigilibServletConfiguration dlConfig = null; /** general logger */ - Logger logger = Logger.getLogger("digilib.texter"); + protected Logger logger = Logger.getLogger("digilib.texter"); /** logger for accounting requests */ protected static Logger accountlog = Logger.getLogger("account.texter.request"); /** FileOps instance */ - FileOps fileOp; + protected FileOps fileOp; /** AuthOps instance */ - AuthzOps authzOp; - - /** ServletOps instance */ - ServletOps servletOp; + protected AuthzOps authzOp; /** DocuDirCache instance */ - DocuDirCache dirCache; + protected DocuDirCache dirCache; /** use authentication */ - boolean useAuthorization = false; + protected boolean useAuthorization = false; /* * (non-Javadoc) @@ -113,6 +110,8 @@ authzOp = (AuthzOps) dlConfig.getValue(DigilibServletConfiguration.AUTHZ_OP_KEY); // DocuDirCache instance dirCache = (DocuDirCache) dlConfig.getValue(TextServletConfiguration.TEXT_DIR_CACHE_KEY); + // configure ServletOps + ServletOps.setDlConfig(dlConfig); } /* @@ -192,7 +191,7 @@ * @return The wanted Textfile or null if there wasn't a file. */ - private TextFile getTextFile(DigilibServletRequest dlRequest, String subDirectory) { + protected TextFile getTextFile(DigilibServletRequest dlRequest, String subDirectory) { String loadPathName = dlRequest.getFilePath() + subDirectory; // find the file(set) return (TextFile) dirCache.getFile(loadPathName, dlRequest.getAsInt("pn"));
--- a/webapp/pom.xml Wed Mar 08 13:12:01 2017 +0100 +++ b/webapp/pom.xml Thu Jun 01 15:06:02 2017 +0200 @@ -276,6 +276,36 @@ </dependency> </dependencies> </profile> + <profile> + <id>iiif-presentation</id> + <!-- IIIF presentation servlet uses servlet3 and has a web.xml --> + <dependencies> + <dependency> + <groupId>digilib</groupId> + <artifactId>digilib-iiif-presentation</artifactId> + <type>jar</type> + <scope>compile</scope> + </dependency> + <dependency> + <groupId>digilib</groupId> + <artifactId>digilib-servlet3</artifactId> + <type>jar</type> + <scope>compile</scope> + </dependency> + </dependencies> + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-war-plugin</artifactId> + <configuration> + <webXml>${basedir}/src/main/webapp/WEB-INF/web-iiif-pres.xml</webXml> + <classifier>srv3p</classifier> + </configuration> + </plugin> + </plugins> + </build> + </profile> <profile> <id>codec-jai</id> <dependencies>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/webapp/pom.xml.orig Thu Jun 01 15:06:02 2017 +0200 @@ -0,0 +1,204 @@ +<?xml version="1.0"?> +<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> + <artifactId>digilib</artifactId> + <groupId>digilib</groupId> + <version>2.3.7</version> + </parent> + <artifactId>digilib-webapp</artifactId> + <name>digilib-webapp</name> + <description>The Digital Image Library - web application server and HTML and JS clients.</description> + <url>http://digilib.sourceforge.net</url> + <packaging>war</packaging> + + <properties> + <skipTests>true</skipTests> + </properties> + + <build> + <pluginManagement> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-war-plugin</artifactId> + <version>2.6</version> + </plugin> + <plugin> + <groupId>org.codehaus.mojo</groupId> + <artifactId>license-maven-plugin</artifactId> + <version>1.4</version> + <configuration> + <includes> + <include>**/*digilib*.js</include> + <include>**/*.jsp</include> + </includes> + </configuration> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-surefire-plugin</artifactId> + <version>2.19</version> + <configuration> + <skip>${skipTests}</skip> + </configuration> + </plugin> + </plugins> + </pluginManagement> + </build> + <profiles> + <profile> + <id>servlet2</id> + <activation> + <property> + <name>servletapi</name> + <value>2</value> + </property> + </activation> + <dependencies> + <dependency> + <groupId>digilib</groupId> + <artifactId>digilib-servlet2</artifactId> + <type>jar</type> + <scope>compile</scope> + </dependency> + </dependencies> + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-war-plugin</artifactId> + <configuration> + <webXml>${basedir}/src/main/webapp/WEB-INF/web-2.4.xml</webXml> + <classifier>srv2</classifier> + </configuration> + </plugin> + </plugins> + </build> + </profile> + <profile> + <id>servlet3</id> + <activation> + <activeByDefault>true</activeByDefault> + <property> + <name>servletapi</name> + <value>3</value> + </property> + </activation> + <dependencies> + <dependency> + <groupId>digilib</groupId> + <artifactId>digilib-servlet3</artifactId> + <type>jar</type> + <scope>compile</scope> + </dependency> + </dependencies> + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-war-plugin</artifactId> + <configuration> + <webXml>${basedir}/src/main/webapp/WEB-INF/web-3.0.xml</webXml> + <classifier>srv3</classifier> + </configuration> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-compiler-plugin</artifactId> + <configuration> + <source>1.7</source> + <target>1.7</target> + </configuration> + </plugin> + </plugins> + </build> + </profile> + <profile> + <id>pdf</id> + <dependencies> + <dependency> + <groupId>digilib</groupId> + <artifactId>digilib-pdf</artifactId> + <type>jar</type> + <scope>compile</scope> + </dependency> + </dependencies> + </profile> + <profile> + <id>text</id> + <dependencies> + <dependency> + <groupId>digilib</groupId> + <artifactId>digilib-text</artifactId> + <type>jar</type> + <scope>compile</scope> + </dependency> + </dependencies> + </profile> + <profile> + <id>codec-jai</id> + <dependencies> + <dependency> + <groupId>digilib</groupId> + <artifactId>digilib-common-jai</artifactId> + <type>jar</type> + <scope>compile</scope> + </dependency> + </dependencies> + </profile> + <profile> + <id>codec-imagej</id> + <dependencies> + <dependency> + <groupId>digilib</groupId> + <artifactId>digilib-common-imagej</artifactId> + <type>jar</type> + <scope>compile</scope> + </dependency> + </dependencies> + </profile> + <profile> + <id>codec-bioformats</id> + <dependencies> + <dependency> + <groupId>digilib</groupId> + <artifactId>digilib-common-bioformats</artifactId> + <type>jar</type> + <scope>compile</scope> + </dependency> + </dependencies> + </profile> + <profile> + <id>cors-filter</id> + <!-- external servlet filter to add CORS headers. enable in web.xml --> + <dependencies> + <dependency> + <groupId>org.eclipse.jetty</groupId> + <artifactId>jetty-servlets</artifactId> + <version>9.2.13.v20150730</version> + </dependency> + </dependencies> + </profile> + </profiles> + <dependencies> + <dependency> + <groupId>org.eclipse.jetty</groupId> + <artifactId>jetty-servlet</artifactId> + <version>9.2.13.v20150730</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.eclipse.jetty</groupId> + <artifactId>jetty-http</artifactId> + <version>9.2.13.v20150730</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <version>4.12</version> + <scope>test</scope> + </dependency> + </dependencies> +</project>
--- a/webapp/src/main/webapp/WEB-INF/web-3.0.xml Wed Mar 08 13:12:01 2017 +0100 +++ b/webapp/src/main/webapp/WEB-INF/web-3.0.xml Thu Jun 01 15:06:02 2017 +0200 @@ -50,4 +50,6 @@ /Scaler/* </url-pattern> </servlet-mapping> + + </web-app>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/webapp/src/main/webapp/WEB-INF/web-iiif-pres.xml Thu Jun 01 15:06:02 2017 +0200 @@ -0,0 +1,73 @@ +<?xml version="1.0" encoding="UTF-8"?> +<web-app + xmlns="http://java.sun.com/xml/ns/javaee" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" + version="3.0"> + + <!-- General description of your web application --> + <display-name> + digilib + </display-name> + <description> + This is the web frontend of the Digital Document Library. + </description> + <!-- The Intialisation Listener (also configured by annotation) --> + <listener> + <listener-class> + digilib.conf.DigilibServlet3Configuration + </listener-class> + </listener> + <!-- The Scaler servlet (also configured by annotation) --> + <servlet> + <servlet-name> + Scaler + </servlet-name> + <servlet-class> + digilib.servlet.Scaler + </servlet-class> + <!-- Load this servlet at server startup time --> + <load-on-startup> + 5 + </load-on-startup> + <!-- yes we do use async, Jetty! --> + <async-supported>true</async-supported> + </servlet> + <!-- The mapping for the Scaler servlet --> + <servlet-mapping> + <servlet-name> + Scaler + </servlet-name> + <url-pattern> + /servlet/Scaler/* + </url-pattern> + </servlet-mapping> + <servlet-mapping> + <servlet-name> + Scaler + </servlet-name> + <url-pattern> + /Scaler/* + </url-pattern> + </servlet-mapping> + + <!-- The Manifest servlet --> + <servlet> + <servlet-name>Manifester</servlet-name> + <servlet-class>digilib.servlet.Manifester</servlet-class> + </servlet> + <!-- The Intialisation Listener --> + <listener> + <listener-class> + digilib.conf.ManifestServletConfiguration + </listener-class> + </listener> + <!-- The mapping for the Manifest servlet --> + <servlet-mapping> + <servlet-name>Manifester</servlet-name> + <url-pattern>/servlet/Manifester/*</url-pattern> + </servlet-mapping> + + + +</web-app>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/webapp/src/main/webapp/jquery/digilib-auth.html.orig Thu Jun 01 15:06:02 2017 +0200 @@ -0,0 +1,61 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> + <head> + <meta http-equiv="content-type" content="text/html; charset=utf-8" /> + <meta name="viewport" content="initial-scale=1.0"/> + <title>Digilib jQuery: fullscreen</title> + + <style type="text/css"> + body { + background: silver; + } + </style> + + <script type="text/javascript" src="jquery.js"></script> + <script type="text/javascript" src="jquery.cookie.js"></script> + + <!-- + <script type="text/javascript" src="jquery.digilib-auth.min.js"></script> + <link rel="stylesheet" type="text/css" href="jquery.digilib-auth.min.css" /> + --> + + <script type="text/javascript" src="jquery.digilib.js"></script> + <script type="text/javascript" src="jquery.digilib.geometry.js"></script> + <script type="text/javascript" src="jquery.digilib.arrows.js"></script> + <script type="text/javascript" src="jquery.range.js"></script> + <link rel="stylesheet" type="text/css" href="jquery.range.css" /> + <script type="text/javascript" src="jquery.digilib.buttons.js"></script> + <script type="text/javascript" src="jquery.digilib.dialogs.js"></script> + <script type="text/javascript" src="jquery.digilib.sliders.js"></script> + <script type="text/javascript" src="jquery.digilib.birdseye.js"></script> + <script type="text/javascript" src="jquery.digilib.marks.js"></script> + <script type="text/javascript" src="jquery.digilib.regions.js"></script> + <script type="text/javascript" src="jquery.digilib.oauth.js"></script> + <link rel="stylesheet" type="text/css" href="jquery.digilib.css" /> + <link rel="stylesheet" type="text/css" href="jquery.digilib.buttons-full-32-sprite.css" /> + + + <script type="text/javascript"> + $(document).ready(function(){ + var opts = { + //authServerUrl : 'http://localhost:18080/ldap-openid-connect-server/authorize', + //authClientId : 'client', + authServerUrl : 'https://id.mpiwg-berlin.mpg.de/openid/authorize', + authClientId : 'digilib-rc-local', + authOnErrorMode : true + }; + var $div = $('div#digilib'); + $div.digilib(opts); + }); + + </script> + </head> + + <body> + <div id="digilib"> + <p>digilib doesn't work! Please switch on Javascript or notify the server administrator!</p> + <img src="http://digilib.sourceforge.net/images/digilib-logo-big.png" /> + </div> + </body> +</html> +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/webapp/src/main/webapp/jquery/digilib.html.orig Thu Jun 01 15:06:02 2017 +0200 @@ -0,0 +1,39 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> + <head> + <meta http-equiv="content-type" content="text/html; charset=utf-8" /> + <meta name="viewport" content="initial-scale=1.0"/> + <title>Digilib jQuery: fullscreen</title> + + <style type="text/css"> + body { + background: silver; + } + </style> + + <script type="text/javascript" src="jquery.min.js"></script> + <script type="text/javascript" src="jquery.cookie-range.min.js"></script> + <script type="text/javascript" src="jquery.digilib-basic.min.js"></script> + <link rel="stylesheet" type="text/css" href="jquery.digilib-basic.css" /> + + <script type="text/javascript"> + $(document).ready(function(){ + var opts = { + interactionMode : 'fullscreen', + showRegionNumbers : true + }; + var $div = $('div#digilib'); + $div.digilib(opts); + }); + + </script> + </head> + + <body> + <div id="digilib"> + <p>digilib doesn't work! Please switch on Javascript or notify the server administrator!</p> + <img src="http://digilib.sourceforge.net/images/digilib-logo-big.png" /> + </div> + </body> +</html> +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/webapp/src/main/webapp/jquery/jquery.digilib-ann.css Thu Jun 01 15:06:02 2017 +0200 @@ -0,0 +1,1 @@ +../../../../target/digilib-webapp-2.5-SNAPSHOT/jquery/jquery.digilib-ann.css \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/webapp/src/main/webapp/jquery/jquery.digilib-ann.js Thu Jun 01 15:06:02 2017 +0200 @@ -0,0 +1,1 @@ +../../../../target/digilib-webapp-2.5-SNAPSHOT/jquery/jquery.digilib-ann.js \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/webapp/src/main/webapp/jquery/jquery.digilib-ann.min.css Thu Jun 01 15:06:02 2017 +0200 @@ -0,0 +1,1 @@ +../../../../target/digilib-webapp-2.5-SNAPSHOT/jquery/jquery.digilib-ann.min.css \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/webapp/src/main/webapp/jquery/jquery.digilib-ann.min.js Thu Jun 01 15:06:02 2017 +0200 @@ -0,0 +1,1 @@ +../../../../target/digilib-webapp-2.5-SNAPSHOT/jquery/jquery.digilib-ann.min.js \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/webapp/src/main/webapp/jquery/jquery.digilib-ann.min.js.map Thu Jun 01 15:06:02 2017 +0200 @@ -0,0 +1,1 @@ +../../../../target/digilib-webapp-2.5-SNAPSHOT/jquery/jquery.digilib-ann.min.js.map \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/webapp/src/main/webapp/jquery/jquery.digilib-auth.css Thu Jun 01 15:06:02 2017 +0200 @@ -0,0 +1,1 @@ +../../../../target/digilib-webapp-2.5-SNAPSHOT/jquery/jquery.digilib-auth.css \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/webapp/src/main/webapp/jquery/jquery.digilib-auth.js Thu Jun 01 15:06:02 2017 +0200 @@ -0,0 +1,1 @@ +../../../../target/digilib-webapp-2.5-SNAPSHOT/jquery/jquery.digilib-auth.js \ No newline at end of file