changeset 1669:078bf3d13f5c

Merge branch 'master' into release-2.5 Conflicts: common/src/main/java/digilib/conf/DigilibConfiguration.java webapp/src/main/webapp/jquery/jquery.digilib.js
author Robert Casties <r0bcas7@gmail.com>
date Thu, 23 Nov 2017 18:41:50 +0100
parents cf9dcddf4ec6 (current diff) 0a8070be7900 (diff)
children 0268cfc402fa
files common/src/main/java/digilib/conf/DigilibConfiguration.java iiif-presentation/pom.xml servlet/pom.xml webapp/src/main/webapp/jquery/jquery.digilib.js
diffstat 7 files changed, 206 insertions(+), 89 deletions(-) [+]
line wrap: on
line diff
--- a/README.md	Tue Nov 21 15:23:38 2017 +0100
+++ b/README.md	Thu Nov 23 18:41:50 2017 +0100
@@ -36,7 +36,7 @@
 
 `digilib` documentation can be found on the 
 [digilib documentation pages](https://robcast.github.io/digilib/) on GitHub
-or on [SourceForge](http://digilib.sourceforge.net).
+or on [SourceForge](https://sourceforge.net/projects/digilib/).
 
 ## How do I run digilib?
 
--- a/doc/src/site/markdown/build-maven.md	Tue Nov 21 15:23:38 2017 +0100
+++ b/doc/src/site/markdown/build-maven.md	Thu Nov 23 18:41:50 2017 +0100
@@ -86,10 +86,66 @@
 
 ## Additional Maven build options
 
+Some build options have to be activated as Maven profiles with the `-P` command line option
+when building digilib. For example, to build digilib with the Manifester servlet ("iiif-presentation") 
+use:
+
+    mvn -Piiif-presentation package
+
+You can add multiple profiles at the same time if necessary.
+
+
 ### servlet2
 
 Digilib uses the Asynchronous Servlet API (3.0) by default. You will need Java version 6 or later 
 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.
+
+`-Pservlet2` builds a servlet with the the old non-Asynchronous Servlet API (2.3).
+
+This creates a WAR file with the postfix "-srv2".
+The build process uses the file `webapp/src/main/webapp/WEB-INF/web-2.4.xml` as `web.xml` file.
+
+### servlet3
+
+`-Pservlet3` builds digillib with the Asynchronous Servlet API (3.0). This is the default profile, it will be used
+if you do not specify any profile.
+
+This creates a WAR file with the postfix "-srv3".
+The build process uses the file `webapp/src/main/webapp/WEB-INF/web-3.0.xml` as `web.xml` file. 
+
+### iiif-presentation
+
+`-Piiif-presentation` builds digilib with the "Manifester" servlet for IIIF Presentation API support 
+(see [digilib IIIF support documentation](iiif-api.html)). 
+
+This creates a WAR file with the postfix "-srv3p".
+The build process uses the file `webapp/src/main/webapp/WEB-INF/web-iiif-pres.xml` as `web.xml` file.
+
+### text
 
+`-Ptext` builds digilib with the "Texter" servlet to download plain text or XML files 
+(see [the source](https://github.com/robcast/digilib/tree/master/text)). You have
+to add `-Pservlet3` or `-Pservlet2` as well.
+
+You also have to copy the mapping for the "Texter" servlet from `web-additional.xml` into the `web.xml` file
+used by the selected servlet API like `web-3.0.xml`.
+
+### pdf
+
+`-Ppdf` builds digilib with the "PDFCache" servlet to generate and download PDF files from images. 
+(see [the source](https://github.com/robcast/digilib/tree/master/pdf)).
+
+You also have to copy the mapping for the "PDFCache" servlet from `web-additional.xml` into the `web.xml` file
+used by the selected servlet API like `web-3.0.xml`.
+
+## create-sprites
+
+`-Pcreate-sprites` re-creates the image sprite file (`webapp/src/main/webapp/jquery/img/dl-buttons-full-32-sprite.png`) 
+from the separate icon image files. This option only needs to be used if you are a developer and you want to 
+change the icon images.
+
+## running tests
+
+`-DskipTests=false` enables some functional tests. The tests are run as part of the normal build process.
+You can also run just the tests with `mvn -DskipTests=false test`.
+
--- a/doc/src/site/markdown/digilib-config.md	Tue Nov 21 15:23:38 2017 +0100
+++ b/doc/src/site/markdown/digilib-config.md	Thu Nov 23 18:41:50 2017 +0100
@@ -35,7 +35,7 @@
 the web application's directory as base.
 
 You can inspect a summary of your running digilib configuration at the URL
-`<base_url>/server/dlConfig.jsp`.
+`<base_url>/server/dlConfig.jsp` e.g. <http://localhost:8080/digilib/server/dlConfig.jsp>.
 
 ### Image locations
 
@@ -44,7 +44,7 @@
 ```
 
 A list of directories where images are searched. See
-[this document](image-directories.html) for details.
+[this document](image-directories.html) for details (**required**).
 
 ```xml
 <parameter name="denied-image" value="img/digilib-denied.png" />
@@ -79,7 +79,7 @@
 [digilib-map.xml.template](https://github.com/robcast/digilib/blob/master/webapp/src/main/webapp/WEB-INF/digilib-map.xml.template)
 for an example. 
 
-The file contains `mapping` elements with a `link` attribute containing a 'virtual directory' name that is mapped to the 
+The file contains `mapping` elements with a `link` attribute containing a 'virtual directory' name that is redirected to the 
 directory given in the `dir` attribute.
 
 
@@ -122,6 +122,13 @@
 [documentation on authentication and authorization](auth.html).
 
 ```xml
+<parameter name="use-authorization" value="false" />
+```
+
+Enables or disables all authorization. If `use-authorization` is `true` you also have to configure
+`authnops-class`, `authzops-class` and the `auth-file` and its contents.
+
+```xml
 <parameter name="auth-file" value="digilib-auth.xml" />
 ```
 
@@ -146,13 +153,6 @@
 
 The class to handle authorization.
 
-```xml
-<parameter name="use-authorization" value="false" />
-```
-
-Enable or disable all authorization. If `use-authorization` is `true` it also needs to be configured
-using `authnops-class` and `authzops-class` and the `auth-file`.
-
 
 ### IIIF API options
 
@@ -168,13 +168,15 @@
 <parameter name="iiif-info-cors" value="true" />
 ```
 
-Enables the `Cross-Origin Resource Sharing` header in IIIF info requests.
+Enables the [Cross-Origin Resource Sharing](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS)
+header in IIIF info requests (`Access-Control-Allow-Origin: *`).
 
 ```xml
 <parameter name="iiif-image-cors" value="true" />
 ```
 
-Enables the `Cross-Origin Resource Sharing` header in IIIF image requests.
+Enables the [Cross-Origin Resource Sharing](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS)
+header in IIIF image requests (`Access-Control-Allow-Origin: *`).
 
 ```xml
 <parameter name="iiif-prefix" value="IIIF" />
@@ -195,7 +197,7 @@
 <parameter name="max-waiting-threads" value="20" />
 ```
 
-The maximum number of requests waiting in the queue before sending "service unavailable".
+The maximum number of requests waiting in the queue before new requests get "service unavailable".
 
 ```xml
 <parameter name="worker-threads" value="2" />
@@ -210,7 +212,7 @@
 Timeout for worker threads in milliseconds.
 
 
-### Assorted options
+### Other options
 
 ```xml
 <parameter name="default-errmsg-type" value="image" />
@@ -234,39 +236,45 @@
 <parameter name="log-config-file" value="log4j-config.xml" />
 ```
 
-Location of the logging configuration file. The current logger is 
+Location of the logging configuration file. The current logging library is 
 [Log4J 1.2](https://logging.apache.org/log4j/1.2/manual.html).
 
+### Options for developers
+
+Using these options you can replace default classes used by digilib with your own implementations
+to change the behaviour of digilib. 
+
+```xml
+<parameter name="docuimage-class" value="digilib.image.ImageLoaderDocuImage" />
+```
+
 
-### Unknown category
-
-**TODO** move items to appropriate sections
+Class of the `DocuImage` instance. You can replace the `digilib.image.DocuImage` implementation to use a different image
+toolkit than Java ImageIO. (There are deprecated alternative implementations in the `common-jai`,
+`common-imagej` and `common-bioformats` modules.) 
 
 ```xml
+<parameter name="docuimage-hacks" value="" />
+```
+
+Text string to selectively enable specific `Hacks` in the `DocuImage` implementation
+(see [the source](https://github.com/robcast/digilib/blob/master/common/src/main/java/digilib/image/ImageLoaderDocuImage.java))
+
+```xml
+<parameter name="filemeta-class" value="digilib.meta.IndexMetaFileMeta" />
 <parameter name="dirmeta-class" value="digilib.meta.IndexMetaDirMeta" />
 ```
 
-Class for **TODO**.
+Classes of the `digilib.meta.FileMeta` and `digilib.meta.DirMeta` implementations. You can change these implementations
+to change the way digilib finds metadata about image files.
+
+`IndexMetaFileMeta` and `IndexMetaDirMeta` read metadata from `index.meta` and `*.meta` XML files according to
+the [index meta standard](http://intern.mpiwg-berlin.mpg.de/digitalhumanities/mpiwg-metadata-documentation/formate/indexmeta-standard).
 
 ```xml
 <parameter name="docudirectory-class" value="digilib.io.BaseDirDocuDirectory" />
 ```
 
-Class for **TODO**.
-
-```xml
-<parameter name="docuimage-class" value="digilib.image.ImageLoaderDocuImage" />
-```
-
-Class for the `DocuImage` instance, **TODO** elaborate intended use
+Class of the `digilib.io.DocuDirectory` implementation. You can change this implementation to change the way
+digilib finds image files (including different resolutions).
 
-```xml
-<parameter name="docuimage-hacks" value="" />
-```
-
-**TODO** elaborate
-
-```xml
-<parameter name="filemeta-class" value="digilib.meta.IndexMetaFileMeta" />
-```
-Class for **TODO**.
--- a/doc/src/site/markdown/install-digilib.md	Tue Nov 21 15:23:38 2017 +0100
+++ b/doc/src/site/markdown/install-digilib.md	Thu Nov 23 18:41:50 2017 +0100
@@ -10,8 +10,8 @@
 ## Start the Servlet Container
 
 Install and run the Servlet Container of your choice: 
-[Tomcat](http://tomcat.apache.org/tomcat-7.0-doc/setup.html) or 
-[Jetty](http://wiki.eclipse.org/Jetty/Howto/Run_Jetty).
+[Tomcat](http://tomcat.apache.org/) or 
+[Jetty](http://wiki.eclipse.org/Jetty/).
 
 When the Servlet Container runs you should be able to access the start page on 
 <http://localhost:8080/>
@@ -35,7 +35,7 @@
 Also you get the chance to always use the latest digilib version by updating the source code. 
 
 You can also download a digilib WAR file with a default configuration from the
-[SourceForge download page](https://sourceforge.net/projects/digilib/files/)
+[GitHub release page](https://github.com/robcast/digilib/releases)
 or the latest digilib build from the 
 [daily build page](https://it-dev.mpiwg-berlin.mpg.de/downloads/digilib/daily-build/). 
 The default configuration will only show a set of sample images. If you want to show your own images
@@ -47,12 +47,12 @@
 1. Get a digilib WAR file.
 2. Rename the WAR file to `digilib.war`.
 3. Deploy the WAR file by copying it into the `webapps` directory of your 
-Servlet Container.
+  Servlet Container.
 4. Restart your Servlet Container (this may not be necessary).
 5. Access your digilib instance at <http://localhost:8080/digilib/digilib.html>.
 
 You will now be able to see the sample images provided with the digilib 
-installation in the default configuration yor your own images 
+installation in the default configuration or your own images 
 if you have updated the [configuration](digilib-config.html).
 
 In digilib you can view images by providing the directory and file 
@@ -68,14 +68,14 @@
 ## Install digilib as a web application directory
 
 1. Get a digilib web application directory.
-2. Rename the WAR file to `digilib.war`.
-3. Deploy the WAR file by copying it into the `webapps` directory of your 
-Servlet Container.
+2. Rename the directory to `digilib`.
+3. Deploy the directory by copying it into the `webapps` directory of your 
+  Servlet Container.
 4. Restart your Servlet Container (this may not be necessary).
 5. Access your digilib instance at <http://localhost:8080/digilib/digilib.html>
 
 You will now be able to see the sample images provided with the digilib 
-installation in the default configuration yor your own images 
+installation in the default configuration or your own images 
 if you have updated the [configuration](digilib-config.html).
 
 In digilib you can view images by providing the directory and file 
@@ -98,6 +98,6 @@
 application directory called `digilib`. Then:
 
 1. Make sure that your Servlet Container is not running and remove any
-`digilib.war` files from the `webapps` directory.
-2. Copy your `digilib` directory into the `webapps` directory of the
-Servlet Container.
+  `digilib.war` files from the `webapps` directory.
+2. Keep the `digilib` directory in the `webapps` directory of the
+  Servlet Container.
--- a/iiif-presentation/pom.xml	Tue Nov 21 15:23:38 2017 +0100
+++ b/iiif-presentation/pom.xml	Thu Nov 23 18:41:50 2017 +0100
@@ -35,7 +35,7 @@
 		<dependency>
 			<groupId>org.glassfish</groupId>
 			<artifactId>javax.json</artifactId>
-			<version>1.0</version>
+			<version>1.0.4</version>
 		</dependency>
 	</dependencies>
 </project>
--- a/servlet/pom.xml	Tue Nov 21 15:23:38 2017 +0100
+++ b/servlet/pom.xml	Thu Nov 23 18:41:50 2017 +0100
@@ -27,9 +27,20 @@
   		<scope>provided</scope>
   	</dependency>
   	<dependency>
+  	    <!-- implementation of JWT JOSE specification -->
   		<groupId>org.bitbucket.b_c</groupId>
   		<artifactId>jose4j</artifactId>
   		<version>0.5.0</version>
   	</dependency>
+  	<dependency>
+  		<groupId>javax.json</groupId>
+  		<artifactId>javax.json-api</artifactId>
+  		<version>1.0</version>
+  	</dependency>
+  	<dependency>
+  		<groupId>org.glassfish</groupId>
+  		<artifactId>javax.json</artifactId>
+  		<version>1.0.4</version>
+  	</dependency>
   </dependencies>
 </project>
--- a/servlet/src/main/java/digilib/servlet/ServletOps.java	Tue Nov 21 15:23:38 2017 +0100
+++ b/servlet/src/main/java/digilib/servlet/ServletOps.java	Thu Nov 23 18:41:50 2017 +0100
@@ -34,8 +34,11 @@
 import java.util.Enumeration;
 import java.util.StringTokenizer;
 
+import javax.json.Json;
+import javax.json.stream.JsonGenerator;
 import javax.servlet.ServletContext;
 import javax.servlet.ServletException;
+import javax.servlet.ServletOutputStream;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
@@ -482,7 +485,6 @@
                 }
             }
             
-            PrintWriter writer;
             if (dlConfig.getAsString("iiif-api-version").startsWith("2.")) {
                 /*
                  * IIIF Image API version 2 image information
@@ -493,59 +495,99 @@
                     response.setContentType("application/ld+json");
                 } else {
                     response.setContentType("application/json");
-                    response.setHeader("Link", "<http://iiif.io/api/image/2/context.json>"
-                            +"; rel=\"http://www.w3.org/ns/json-ld#context\""
-                            +"; type=\"application/ld+json\"");
                 }
                 // write info.json
-                writer = response.getWriter();
-                writer.println("{");
-                writer.println("\"@context\" : \"http://iiif.io/api/image/2/context.json\",");
-                writer.println("\"@id\" : \"" + url + "\",");
-                writer.println("\"protocol\" : \"http://iiif.io/api/image\",");
-                writer.println("\"width\" : " + size.width + ",");
-                writer.println("\"height\" : " + size.height + ",");
-                writer.println("\"profile\" : [");
-                writer.println("  \"http://iiif.io/api/image/2/level2.json\",");
-                writer.println("  {");
-                writer.println("    \"formats\" : [\"jpg\", \"png\"],");
-                writer.println("    \"qualities\" : [\"color\", \"gray\"],");
+                ServletOutputStream out = response.getOutputStream();
+                JsonGenerator info = Json.createGenerator(out);
+                // top level object
+                info.writeStartObject()
+                .write("@context", "http://iiif.io/api/image/2/context.json")
+                .write("@id", url)
+                .write("protocol", "http://iiif.io/api/image")
+                .write("width", size.width)
+                .write("height", size.height);
+                // profile[ array
+                info.writeStartArray("profile")
+                // profile[ level
+                .write("http://iiif.io/api/image/2/level2.json");
+                // profile[{ object
+                info.writeStartObject();
+                // profile[{formats[
+                info.writeStartArray("formats")
+                .write("jpg")
+                .write("png")
+                .writeEnd();
+                // profile[{qualities[
+                info.writeStartArray("qualities")
+                .write("color")
+                .write("gray")
+                .writeEnd();
+                // profile[{maxArea
                 if (dlConfig.getAsInt("max-image-size") > 0) {
-                	writer.println("    \"maxArea\" : " + dlConfig.getAsInt("max-image-size") + ",");
+                    info.write("maxArea", dlConfig.getAsInt("max-image-size"));
                 }
-                writer.println("    \"supports\" : ["
-                		+ "\"mirroring\", \"rotationArbitrary\", \"sizeAboveFull\", \"regionSquare\""
-                		+ "]");
-                writer.println("  }]");
+                // profile[{supports[
+                info.writeStartArray("supports")
+                .write("mirroring")
+                .write("rotationArbitrary")
+                .write("sizeAboveFull")
+                .write("regionSquare")
+                .writeEnd();
+                // profile[{}
+                info.writeEnd();
+                // profile[]
+                info.writeEnd();
                 // add size of original and prescaled images
                 int numImgs = imageSet.size();
                 if (numImgs > 0) {
-                    writer.println(", \"sizes\" : [");
+                    // sizes[
+                    info.writeStartArray("sizes");
                     for (int i = numImgs - 1; i >= 0; --i) {
                         ImageInput ii = imageSet.get(i);
                         ImageSize is = ii.getSize();
-                        writer.println("  {\"width\" : "+is.getWidth()+", \"height\" : "+is.getHeight()+"}"
-                                +((i > 1)?",":""));
+                        // sizes[{
+                        info.writeStartObject()
+                        .write("width", is.getWidth())
+                        .write("height", is.getHeight())
+                        .writeEnd();
                     }
-                    writer.println("]");
+                    // sizes[]
+                    info.writeEnd();
                 }
-                writer.println("}");
-                
+                // end info.json
+                info.writeEnd();
+                info.close();
+
             } else {
                 /*
                  * IIIF Image API version 1 image information
                  */
                 response.setContentType("application/json,application/ld+json");
-                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("\"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("}");
+                // write info.json
+                ServletOutputStream out = response.getOutputStream();
+                JsonGenerator info = Json.createGenerator(out);
+                // top level object
+                info.writeStartObject()
+                .write("@context", "http://library.stanford.edu/iiif/image-api/1.1/context.json")
+                .write("@id", url)
+                .write("width", size.width)
+                .write("height", size.height);
+                // formats[
+                info.writeStartArray("formats")
+                .write("jpg")
+                .write("png")
+                .writeEnd();
+                // qualities[
+                info.writeStartArray("qualities")
+                .write("native")
+                .write("color")
+                .write("gray")
+                .writeEnd();
+                // profile
+                info.write("profile", "http://library.stanford.edu/iiif/image-api/1.1/compliance.html#level2");
+                // end info.json
+                info.writeEnd();
+                info.close();
             }
         } catch (IOException e) {
             throw new ServletException("Unable to write response!", e);