changeset 1592:7031524fc6e9

new DigilibOptions Enum for typesafe Scaler "mo" options/flags.
author robcast
date Wed, 08 Feb 2017 19:22:57 +0100
parents 8dff61ffdbc3
children 4ef25f916df8
files common/src/main/java/digilib/conf/DigilibOption.java common/src/main/java/digilib/conf/DigilibRequest.java common/src/main/java/digilib/image/ImageJobDescription.java common/src/main/java/digilib/image/ImageWorker.java common/src/main/java/digilib/util/OptionsSet.java common/src/main/java/digilib/util/ParameterMap.java webapp/src/main/webapp/api/dirInfo-json.jsp webapp/src/main/webapp/api/dirInfo-xml.jsp
diffstat 8 files changed, 153 insertions(+), 74 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/common/src/main/java/digilib/conf/DigilibOption.java	Wed Feb 08 19:22:57 2017 +0100
@@ -0,0 +1,63 @@
+package digilib.conf;
+
+/**
+ * Enum of options for the digilib "mo" parameter.
+ * 
+ * @author casties
+ *
+ */
+public enum DigilibOption {
+	/** scale the (selected area of the) image proportionally to fit inside [dw x dh], preserving its aspect ratio (default). */
+    fit,
+    /** scale the (selected area of the) image to fill [dw x dh], changing its aspect ratio. */
+    squeeze,
+    /** scale the (selected area of the) image proportionally to fill [dw x dh] with the shorter side, cropping the longer side. */
+    crop,
+    /** scale the (selected area of the) image proportionally to fill [dw x dh] with the longer side, filling out the image on the shorter side if possible. */
+    fill,
+    /** send the file in the highest resolution, cropped to fit [dw x dh]. */
+    clip,
+    /** scale to original size based on image resolution (from the image metadata) and display resolution (from parameter ddpi). Fails if either resolution is unknown. */
+    osize,
+    /** scale the highest resolution image by an absolute factor given by the scale parameter. */
+    ascale,
+    /** send the file as-is (may be very large and all sorts of image types!). If the configuration doesn’t allow sending files (sendfile-allowed=false) revert to clip. */
+    file,
+    /** send the file as-is with a mime-type of “application/octet-stream” so the browser presents a download dialog. */
+    rawfile,
+    /** send error response as plain text. */
+    errtxt,
+    /** send error response as image (default). */
+    errimg,
+    /** send error response as HTTP status code. */
+    errcode,
+    /** quality of interpolation in scaling (q0: worst, q2 best).*/
+    q0,
+    /** quality of interpolation in scaling (q0: worst, q2 best).*/
+    q1,
+    /** quality of interpolation in scaling (q0: worst, q2 best).*/
+    q2,
+    /** only use the highest resolution image. */
+    hires,
+    /** use the pre-scaled image that is bigger than the requested size (default). */
+    autores,
+    /** prefer the next-smaller pre-scaled image. */
+    lores,
+    /** mirror image vertically. */
+    vmir,
+    /** mirror image horizontally. */
+    hmir,
+    /** the resulting image is always sent as JPEG (otherwise TIFF and PNG images are sent as PNG). */
+    jpg,
+    /** the resulting image is always sent as PNG (otherwise JPEG and J2K images are sent as JPEG). */
+    png,
+    /** interpret wx, wy, ww, wh as pixel coordinates on the highest resolution image. */
+    pxarea,
+    /** send IIIF image info (instead of image). */
+    info, 
+    /** send redirect to IIIF image info URI */ 
+    redirect_info,
+    /** dirInfo returns directory contents */
+    dir
+     
+}
--- a/common/src/main/java/digilib/conf/DigilibRequest.java	Wed Feb 08 19:21:46 2017 +0100
+++ b/common/src/main/java/digilib/conf/DigilibRequest.java	Wed Feb 08 19:22:57 2017 +0100
@@ -420,7 +420,7 @@
 	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");
+        options.setOption(DigilibOption.errcode);
         
         /*
          * parameter identifier (encoded)
@@ -453,7 +453,7 @@
         if (region != null) {
             if (region.equals("info.json")) {
                 // info request
-                options.setOption("info");
+                options.setOption(DigilibOption.info);
                 return true;
             } else if (region.equals("full")) {
                 // full image -- default
@@ -482,7 +482,7 @@
                     logger.error(errorMessage);
                     return false;
                 } else {
-                    options.setOption("pxarea");
+                    options.setOption(DigilibOption.pxarea);
                     setValueFromString("wx", parms[0]);
                     setValueFromString("wy", parms[1]);
                     setValueFromString("ww", parms[2]);
@@ -491,7 +491,7 @@
             }
         } else {
             // region omitted -- redirect to info request
-            options.setOption("redirect-info");
+            options.setOption(DigilibOption.redirect_info);
             return true;
         }
         
@@ -503,7 +503,7 @@
                 /*
                  * full -- size of original
                  */
-                options.setOption("ascale");
+                options.setOption(DigilibOption.ascale);
                 setValue("scale", 1f);
                 
             } else if (size.startsWith("pct:")) {
@@ -512,7 +512,7 @@
                  */
                 try {
                     float pct = Float.parseFloat(size.substring(4));
-                    options.setOption("ascale");
+                    options.setOption(DigilibOption.ascale);
                     setValue("scale", pct / 100);
                 } catch (NumberFormatException e) {
                     errorMessage = "Error parsing size parameter in IIIF path! ";
@@ -536,7 +536,7 @@
                             setValueFromString("dw", parms[0]);
                         } else {
                             // w,h -- according to spec, we should distort the image to match ;-(
-                        	options.setOption("squeeze");
+                        	options.setOption(DigilibOption.squeeze);
                             setValueFromString("dw", parms[0]);
                         }
                     }
@@ -552,7 +552,7 @@
             }
         } else {
             // size omitted -- assume "full"
-            options.setOption("ascale");
+            options.setOption(DigilibOption.ascale);
             setValue("scale", 1f);
             return true;
         }
@@ -563,7 +563,7 @@
         if (rotation != null) {
             if (rotation.startsWith("!")) {
                 // !n -- mirror and rotate
-                options.setOption("hmir");
+                options.setOption(DigilibOption.hmir);
                 rotation = rotation.substring(1);
             }
             try {
@@ -601,10 +601,10 @@
             // format param (we only support jpg and png)
             if (format.equals("jpg")) {
                 // force jpg
-                options.setOption("jpg");
+                options.setOption(DigilibOption.jpg);
             } else if (format.equals("png")) {
                 // force png
-                options.setOption("png");
+                options.setOption(DigilibOption.png);
             } else {
                 errorMessage = "Invalid format parameter in IIIF path!";
                 logger.error(errorMessage);
--- a/common/src/main/java/digilib/image/ImageJobDescription.java	Wed Feb 08 19:21:46 2017 +0100
+++ b/common/src/main/java/digilib/image/ImageJobDescription.java	Wed Feb 08 19:22:57 2017 +0100
@@ -33,6 +33,7 @@
 import org.apache.log4j.Logger;
 
 import digilib.conf.DigilibConfiguration;
+import digilib.conf.DigilibOption;
 import digilib.conf.DigilibRequest;
 import digilib.image.DocuImage.ColorOp;
 import digilib.io.DocuDirCache;
@@ -323,7 +324,7 @@
         } else if (scaleY == 0) {
             // dh undefined
             scaleY = scaleX;
-        } else if (hasOption("crop")) {
+        } else if (hasOption(DigilibOption.crop)) {
             // use the bigger factor to get fill-the-box
             if (scaleX > scaleY) {
                 scaleY = scaleX;
@@ -352,7 +353,7 @@
             // use the smaller factor to get fit-in-box
             if (scaleX > scaleY) {
                 scaleX = scaleY;
-                if (hasOption("fill")) {
+                if (hasOption(DigilibOption.fill)) {
                     // fill mode uses whole destination rect
                     long filledAreaWidth = Math.round(getDw() / scaleX);
                     if (filledAreaWidth > areaWidth) {
@@ -365,7 +366,7 @@
                 }
             } else {
                 scaleY = scaleX;
-                if (hasOption("fill")) {
+                if (hasOption(DigilibOption.fill)) {
                     // fill mode uses whole destination rect
                     long filledAreaHeight = Math.round(getDh() / scaleY);
                     if (filledAreaHeight > areaHeight) {
@@ -459,7 +460,7 @@
         /*
          * absolute scale factor -- either original size, based on dpi, or absolute 
          */
-        if (hasOption("osize")) {
+        if (hasOption(DigilibOption.osize)) {
             /*
              * get original resolution from metadata
              */
@@ -570,9 +571,9 @@
      */
     public String getOutputMimeType() {
         // forced destination image type
-        if (hasOption("jpg")) {
+        if (hasOption(DigilibOption.jpg)) {
             return "image/jpeg";
-        } else if (hasOption("png")) {
+        } else if (hasOption(DigilibOption.png)) {
             return "image/png";
         }
         // use input image type
@@ -709,7 +710,7 @@
      * @return
      */
     public boolean isHiresOnly() {
-        return hasOption("clip") || hasOption("hires");
+        return hasOption(DigilibOption.clip) || hasOption(DigilibOption.hires);
     }
 
     /**
@@ -718,7 +719,7 @@
      * @return
      */
     public boolean isLoresOnly() {
-        return hasOption("lores");
+        return hasOption(DigilibOption.lores);
     }
 
     /**
@@ -727,8 +728,9 @@
      * @return
      */
     public boolean isScaleToFit() {
-        return hasOption("fit") || 
-        		!(hasOption("clip") || hasOption("osize") || hasOption("ascale") || hasOption("squeeze"));
+        return hasOption(DigilibOption.fit) || 
+        		!(hasOption(DigilibOption.clip) || hasOption(DigilibOption.osize) 
+        				|| hasOption(DigilibOption.ascale) || hasOption(DigilibOption.squeeze));
     }
 
     /**
@@ -737,7 +739,7 @@
      * @return
      */
     public boolean isCropToFit() {
-        return hasOption("clip");
+        return hasOption(DigilibOption.clip);
     }
 
     /**
@@ -746,7 +748,7 @@
      * @return
      */
     public boolean isSqueezeToFit() {
-        return hasOption("squeeze");
+        return hasOption(DigilibOption.squeeze);
     }
 
     /**
@@ -755,7 +757,7 @@
      * @return
      */
     public boolean isAbsoluteScale() {
-        return hasOption("osize") || hasOption("ascale");
+        return hasOption(DigilibOption.osize) || hasOption(DigilibOption.ascale);
     }
 
     /**
@@ -891,7 +893,7 @@
         //logger.debug("get_paramWW()");
         if (paramWW == null) {
         	paramWW = getAsFloat("ww");
-        	if (hasOption("pxarea")) {
+        	if (hasOption(DigilibOption.pxarea)) {
         		// area in absolute pixels - convert to relative
         		hiresSize = getHiresSize();
         		paramWW = paramWW / hiresSize.getWidth(); 
@@ -912,7 +914,7 @@
         //logger.debug("get_paramWH()");
         if (paramWH == null) {
         	paramWH = getAsFloat("wh");
-        	if (hasOption("pxarea")) {
+        	if (hasOption(DigilibOption.pxarea)) {
         		// area in absolute pixels - convert to relative
         		hiresSize = getHiresSize();
         		paramWH = paramWH / hiresSize.getHeight(); 
@@ -933,7 +935,7 @@
         //logger.debug("get_paramWX()");
         if (paramWX == null) {
         	paramWX = getAsFloat("wx");
-        	if (hasOption("pxarea")) {
+        	if (hasOption(DigilibOption.pxarea)) {
         		// area in absolute pixels - convert to relative
         		ImageSize imgSize = getHiresSize();
         		paramWX = paramWX / imgSize.getWidth(); 
@@ -954,7 +956,7 @@
         //logger.debug("get_paramWY()");
         if (paramWY == null) {
         	paramWY = getAsFloat("wy");
-        	if (hasOption("pxarea")) {
+        	if (hasOption(DigilibOption.pxarea)) {
         		// area in absolute pixels - convert to relative
         		ImageSize imgSize = getHiresSize();
         		paramWY = paramWY / imgSize.getHeight(); 
@@ -971,11 +973,11 @@
     public int getScaleQual() {
         //logger.debug("get_scaleQual()");
         int qual = dlConfig.getAsInt("default-quality");
-        if (hasOption("q0"))
+        if (hasOption(DigilibOption.q0))
             qual = 0;
-        else if (hasOption("q1"))
+        else if (hasOption(DigilibOption.q1))
             qual = 1;
-        else if (hasOption("q2")) 
+        else if (hasOption(DigilibOption.q2)) 
             qual = 2;
         return qual;
     }
@@ -1072,7 +1074,7 @@
      * @return
      */
     public boolean getSendAsFile() {
-        return hasOption("file") || hasOption("rawfile");
+        return hasOption(DigilibOption.file) || hasOption(DigilibOption.rawfile);
     }
 
     /**
@@ -1090,11 +1092,11 @@
             		// input image is browser compatible
                     && (mimeType.equals("image/jpeg") || mimeType.equals("image/png") || mimeType.equals("image/gif"))
                     // no forced type conversion
-                    && !(hasOption("jpg") || hasOption("png"))
+                    && !(hasOption(DigilibOption.jpg) || hasOption(DigilibOption.png))
                     // no zooming
                     && !(getWx() > 0f || getWy() > 0f || getWw() < 1f || getWh() < 1f
                     // no other image operations
-                    || hasOption("vmir") || hasOption("hmir")
+                    || hasOption(DigilibOption.vmir) || hasOption(DigilibOption.hmir)
                     || (getAsFloat("rot") != 0.0)
                     || (getRGBM() != null)
                     || (getRGBA() != null)
--- a/common/src/main/java/digilib/image/ImageWorker.java	Wed Feb 08 19:21:46 2017 +0100
+++ b/common/src/main/java/digilib/image/ImageWorker.java	Wed Feb 08 19:22:57 2017 +0100
@@ -30,6 +30,7 @@
 import org.apache.log4j.Logger;
 
 import digilib.conf.DigilibConfiguration;
+import digilib.conf.DigilibOption;
 import digilib.io.FileOpException;
 
 /**
@@ -147,10 +148,10 @@
          * mirror image
          * operation mode: "hmir": mirror horizontally, "vmir": mirror vertically
          */
-        if (jobinfo.hasOption("hmir")) {
+        if (jobinfo.hasOption(DigilibOption.hmir)) {
             docuImage.mirror(0);
         }
-        if (jobinfo.hasOption("vmir")) {
+        if (jobinfo.hasOption(DigilibOption.vmir)) {
             docuImage.mirror(90);
         }
         if (stopNow) {
--- a/common/src/main/java/digilib/util/OptionsSet.java	Wed Feb 08 19:21:46 2017 +0100
+++ b/common/src/main/java/digilib/util/OptionsSet.java	Wed Feb 08 19:22:57 2017 +0100
@@ -1,49 +1,36 @@
 package digilib.util;
 
-/*
- * #%L
- * Set for option flags.
- * %%
- * Copyright (C) 2010 - 2013 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@berlios.de)
- */
+import java.util.EnumSet;
+import java.util.StringTokenizer;
 
-import java.util.HashSet;
-import java.util.StringTokenizer;
+import org.apache.log4j.Logger;
+
+import digilib.conf.DigilibOption;
 
 /**
  * @author casties
  *
  */
-@SuppressWarnings("serial")
-public class OptionsSet extends HashSet<String> {
+public class OptionsSet {
 
+	/** content EnumSet */
+	private EnumSet<DigilibOption> options;
+	
+    /** logger */
+    protected static final Logger logger = Logger.getLogger(OptionsSet.class);
+
+	/** String separating options in a String. */
 	protected String optionSep = ",";
 	
 	public OptionsSet() {
-		super();
+		options = EnumSet.noneOf(DigilibOption.class);
 	}
 
 	/** Constructor with String of options.
 	 * @param s
 	 */
 	public OptionsSet(String s) {
-		super();
+		options = EnumSet.noneOf(DigilibOption.class);
 		parseString(s);
 	}
 
@@ -55,7 +42,12 @@
 			StringTokenizer i = new StringTokenizer(s, optionSep);
 			while (i.hasMoreTokens()) {
 				String opt = i.nextToken();
-				this.add(opt);
+				try {
+					DigilibOption dlOpt = DigilibOption.valueOf(opt);
+					options.add(dlOpt);
+				} catch (IllegalArgumentException e) {
+					logger.warn("Ignored unknown digilib option: "+opt); 
+				}
 			}
 		}
 	}
@@ -66,8 +58,8 @@
 	 * @param opt
 	 * @return
 	 */
-	public boolean setOption(String opt) {
-	    return this.add(opt);
+	public boolean setOption(DigilibOption opt) {
+	    return options.add(opt);
 	}
 	
 	/**
@@ -76,13 +68,16 @@
 	 * @param opt
 	 * @return
 	 */
-	public boolean hasOption(String opt) {
-		return this.contains(opt);
+	public boolean hasOption(DigilibOption opt) {
+		return options.contains(opt);
 	}
 
+	/* (non-Javadoc)
+	 * @see java.util.AbstractCollection#toString()
+	 */
 	public String toString() {
 		StringBuffer b = new StringBuffer();
-		for (String s: this) {
+		for (DigilibOption s: options) {
 			if (b.length() > 0) {
 				b.append(optionSep);
 			}
@@ -92,6 +87,20 @@
 	}
 	
 	
+	/**
+	 * @return the options
+	 */
+	public EnumSet<DigilibOption> getOptions() {
+		return options;
+	}
+
+	/**
+	 * @param options the options to set
+	 */
+	public void setOptions(EnumSet<DigilibOption> options) {
+		this.options = options;
+	}
+
 	public String getOptionSep() {
 		return optionSep;
 	}
--- a/common/src/main/java/digilib/util/ParameterMap.java	Wed Feb 08 19:21:46 2017 +0100
+++ b/common/src/main/java/digilib/util/ParameterMap.java	Wed Feb 08 19:22:57 2017 +0100
@@ -30,6 +30,8 @@
 import java.io.File;
 import java.util.HashMap;
 
+import digilib.conf.DigilibOption;
+
 
 /** HashMap of digilib.servlet.Parameter's.
  * 
@@ -71,7 +73,7 @@
         // TODO: initParams?
 		// clone params to this map
 		newPm.params = (HashMap<String, Parameter>) pm.params.clone();
-		newPm.options = (OptionsSet) pm.options.clone();
+		newPm.options.setOptions(pm.options.getOptions().clone());
 		return newPm;
 	}
 
@@ -321,7 +323,7 @@
 	 * @param opt
 	 * @return
 	 */
-	public boolean hasOption(String opt) {
+	public boolean hasOption(DigilibOption opt) {
 		return options.hasOption(opt);
 	}
 
--- a/webapp/src/main/webapp/api/dirInfo-json.jsp	Wed Feb 08 19:21:46 2017 +0100
+++ b/webapp/src/main/webapp/api/dirInfo-json.jsp	Wed Feb 08 19:22:57 2017 +0100
@@ -23,6 +23,7 @@
     import="digilib.servlet.DigilibBean,
           digilib.conf.DigilibServletConfiguration,
           digilib.conf.DigilibServletRequest,
+          digilib.conf.DigilibOption,
           digilib.io.DocuDirectory,
           digilib.io.DocuDirent,
           digilib.io.FileOps,
@@ -58,7 +59,7 @@
 %>  "count" : "<%= dirSize %>",
   "files" : [
 <%
-    if (!docBean.getRequest().hasOption("dir")) {
+    if (!docBean.getRequest().hasOption(DigilibOption.dir)) {
         // list all files
         for (int i = 0; i < dirSize; i++) {
             DocuDirent f = dir.get(i);
--- a/webapp/src/main/webapp/api/dirInfo-xml.jsp	Wed Feb 08 19:21:46 2017 +0100
+++ b/webapp/src/main/webapp/api/dirInfo-xml.jsp	Wed Feb 08 19:22:57 2017 +0100
@@ -23,6 +23,7 @@
     import="digilib.servlet.DigilibBean,
           digilib.conf.DigilibServletConfiguration,
           digilib.conf.DigilibServletRequest,
+          digilib.conf.DigilibOption,
           digilib.io.DocuDirectory,
           digilib.io.DocuDirent,
           digilib.io.FileOps,
@@ -57,7 +58,7 @@
 %>  <auth-required><%= ! docBean.isAuthorized() %></auth-required>
 <%
     }
-    if (!docBean.getRequest().hasOption("dir")) {
+    if (!docBean.getRequest().hasOption(DigilibOption.dir)) {
       for (int i = 0; i < dirSize; i++) {
         DocuDirent f = dir.get(i);
         String fn = (f != null) ? f.getName() : "null";