changeset 1209:59d615f4e5f3

refactored setWithIiifPath(String) into string splitter and setWithIiifParams().
author robcast
date Thu, 22 Aug 2013 17:14:33 +0200
parents ee5d2ce6b11a
children 247eab96bf04
files common/src/main/java/digilib/conf/DigilibConfiguration.java common/src/main/java/digilib/conf/DigilibRequest.java servlet/src/main/java/digilib/servlet/ServletOps.java
diffstat 3 files changed, 237 insertions(+), 149 deletions(-) [+]
line wrap: on
line diff
--- a/common/src/main/java/digilib/conf/DigilibConfiguration.java	Mon Jul 22 21:18:50 2013 +0200
+++ b/common/src/main/java/digilib/conf/DigilibConfiguration.java	Thu Aug 22 17:14:33 2013 +0200
@@ -44,8 +44,9 @@
     /** Log4J logger */
     protected static Logger logger = Logger.getLogger(DigilibConfiguration.class);
 
+    /** digilib version */
     public static String getVersion() {
-        return "2.2.1";
+        return "2.2.2";
     }
     
     /**
--- a/common/src/main/java/digilib/conf/DigilibRequest.java	Mon Jul 22 21:18:50 2013 +0200
+++ b/common/src/main/java/digilib/conf/DigilibRequest.java	Thu Aug 22 17:14:33 2013 +0200
@@ -282,8 +282,14 @@
         if (path == null) {
             return false;
         }
-        // alway set HTTP status code error reporting
-        options.setOption("errcode");
+        
+        String identifier = null;
+        String region = null;
+        String size = null;
+        String rotation = null;
+        String quality = null;
+        String format = null;
+
         // enable passing of delimiter to get empty parameters
         StringTokenizer query = new StringTokenizer(path, "/", true);
         String token;
@@ -308,17 +314,7 @@
         if (query.hasMoreTokens()) {
             token = getNextDecodedToken(query);
             if (!token.equals("/")) {
-                try {
-                    if (token.contains("%")) {
-                        // still escape chars -- decode again
-                        token = URLDecoder.decode(token, "UTF-8");
-                    }
-                    setValueFromString("fn", token);
-                } catch (UnsupportedEncodingException e) {
-                    errorMessage = "Error decoding identifier in IIIF path!";
-                    logger.error(errorMessage);
-                    return false;
-                }
+                identifier = token;
                 // skip /
                 if (query.hasMoreTokens()) {
                     query.nextToken();
@@ -331,53 +327,12 @@
         if (query.hasMoreTokens()) {
             token = getNextDecodedToken(query);
             if (!token.equals("/")) {
-                if (token.equals("info.json")) {
-                    // info request
-                    options.setOption("info");
-                    return true;
-                } else if (token.equals("full")) {
-                    // full region -- default
-                } else if (token.startsWith("pct:")) {
-                    // pct:x,y,w,h -- region in % of original image
-                    String[] parms = token.substring(4).split(",");
-                    try {
-                        float x = Float.parseFloat(parms[0]);
-                        setValue("wx", x / 100f);
-                        float y = Float.parseFloat(parms[1]);
-                        setValue("wy", y / 100f);
-                        float w = Float.parseFloat(parms[2]);
-                        setValue("ww", w / 100f);
-                        float h = Float.parseFloat(parms[3]);
-                        setValue("wh", h / 100f);
-                    } catch (Exception e) {
-                        errorMessage = "Error parsing range parameter in IIIF path!";
-                        logger.error(errorMessage, e);
-                        return false;
-                    }
-                } else {
-                    // x,y,w,h -- region in pixel of original image :-(
-                    String[] parms = token.split(",");
-                    if (parms.length != 4) {
-                        errorMessage = "Error parsing range parameter in IIIF path!";
-                        logger.error(errorMessage);
-                        return false;
-                    } else {
-                        options.setOption("pxarea");
-                        setValueFromString("wx", parms[0]);
-                        setValueFromString("wy", parms[1]);
-                        setValueFromString("ww", parms[2]);
-                        setValueFromString("wh", parms[3]);
-                    }
-                }
+                region = token;
                 // skip /
                 if (query.hasMoreTokens()) {
                     query.nextToken();
                 }
             }
-        } else {
-            // region omitted -- assume info request
-            options.setOption("info");
-            return true;
         }
         /*
          * fourth parameter size
@@ -385,60 +340,12 @@
         if (query.hasMoreTokens()) {
             token = getNextDecodedToken(query);
             if (!token.equals("/")) {
-                if (token.equals("full")) {
-                    // full -- size of original
-                    options.setOption("ascale");
-                    setValue("scale", 1f);
-                } else if (token.startsWith("pct:")) {
-                    // pct:n -- n% size of original
-                    try {
-                        float pct = Float.parseFloat(token.substring(4));
-                        options.setOption("ascale");
-                        setValue("scale", pct / 100);
-                    } catch (NumberFormatException e) {
-                        errorMessage = "Error parsing size parameter in IIIF path!";
-                        logger.error(errorMessage, e);
-                        return false;
-                    }
-                } else {
-                    // w,h -- pixel size
-                    try {
-                        String[] parms = token.split(",", 2);
-                        if (parms[0].length() > 0) {
-                            // width param
-                            if (parms[0].startsWith("!")) {
-                                // width (in digilib-like bounding box)
-                                setValueFromString("dw", parms[0].substring(1));
-                            } else if (parms[1].length() == 0) {
-                                // width only
-                                setValueFromString("dw", parms[0]);
-                            } else {
-                                // w,h -- according to spec, we should distort the image to match ;-(
-                                errorMessage = "Non-uniform-scale size parameter in IIIF path not supported!";
-                                logger.error(errorMessage);
-                                return false;
-                            }
-                        }
-                        if (parms[1].length() > 0) {
-                            // height param
-                            setValueFromString("dh", parms[1]);
-                        }
-                    } catch (Exception e) {
-                        errorMessage = "Error parsing size parameter in IIIF path!";
-                        logger.error(errorMessage, e);
-                        return false;
-                    }
-                }
+                size = token;
                 // skip /
                 if (query.hasMoreTokens()) {
                     query.nextToken();
                 }
             }
-        } else {
-            // size omitted -- assume "full"
-            options.setOption("ascale");
-            setValue("scale", 1f);
-            return true;
         }
         /*
          * fifth parameter rotation
@@ -446,14 +353,7 @@
         if (query.hasMoreTokens()) {
             token = getNextDecodedToken(query);
             if (!token.equals("/")) {
-                try {
-                    float rot = Float.parseFloat(token);
-                    setValue("rot", rot);
-                } catch (NumberFormatException e) {
-                    errorMessage = "Error parsing rotation parameter in IIIF path!";
-                    logger.error(errorMessage, e);
-                    return false;
-                }
+                rotation = token;
                 // skip /
                 if (query.hasMoreTokens()) {
                     query.nextToken();
@@ -469,26 +369,10 @@
             try {
                 String[] parms = token.split("\\.");
                 // quality param
-                if (parms[0].equals("native")||parms[0].equals("color")) {
-                    // native is default anyway
-                } else if (parms[0].equals("grey")) {
-                    setValueFromString("colop", "grayscale");
-                } else {
-                    errorMessage = "Invalid quality parameter in IIIF path!";
-                    logger.error(errorMessage);
-                    return false;
-                }
-                // format param (we only support jpg and png)
-                if (parms.length > 1 && parms[1].equals("jpg")) {
-                    // force jpg
-                    options.setOption("jpg");
-                } else if (parms.length > 1 && parms[1].equals("png")) {
-                    // force png
-                    options.setOption("png");
-                } else if (parms.length > 1) {
-                    errorMessage = "Invalid format parameter in IIIF path!";
-                    logger.error(errorMessage);
-                    return false;
+                quality = parms[0];
+                // format param
+                if (parms.length > 1) {
+                    format = parms[1];
                 }
             } catch (Exception e) {
                 errorMessage = "Error parsing quality and format parameters in IIIF path!";
@@ -496,7 +380,9 @@
                 return false;
             }
         }
-        return true;
+
+        // set request with these parameters
+        return setWithIiifParams(identifier, region, size, rotation, quality, format);        
     }
 
     private String getNextDecodedToken(StringTokenizer tokens) {
@@ -510,6 +396,195 @@
         return null;
     }
 
+	/**
+	 * Populate a request from IIIF image API parameters.
+	 * 
+	 * {scheme}://{server}{/prefix}/{identifier}/{region}/{size}/{rotation}/{quality}{.format}
+	 * 
+	 * @see <a href="http://www-sul.stanford.edu/iiif/image-api/1.1/">IIIF Image
+	 *      API</a>
+	 */
+	public boolean setWithIiifParams(String identifier, String region, String size, 
+			String rotation, String quality, String format) {
+        // alway set HTTP status code error reporting
+        options.setOption("errcode");
+        
+        /*
+         * parameter identifier (encoded)
+         */
+        if (identifier != null) {
+            try {
+                if (identifier.contains("%")) {
+                    // still escape chars -- decode again
+                    identifier = URLDecoder.decode(identifier, "UTF-8");
+                }
+                setValueFromString("fn", identifier);
+            } catch (UnsupportedEncodingException e) {
+                errorMessage = "Error decoding identifier in IIIF path!";
+                logger.error(errorMessage);
+                return false;
+            }
+        } else {
+            errorMessage = "Missing identifier in IIIF path!";
+            logger.error(errorMessage);
+            return false;
+        }
+
+        /*
+         * parameter region
+         */
+        if (region != null) {
+            if (region.equals("info.json")) {
+                // info request
+                options.setOption("info");
+                return true;
+            } else if (region.equals("full")) {
+                // full region -- default
+            } else if (region.startsWith("pct:")) {
+                // pct:x,y,w,h -- region in % of original image
+                String[] parms = region.substring(4).split(",");
+                try {
+                    float x = Float.parseFloat(parms[0]);
+                    setValue("wx", x / 100f);
+                    float y = Float.parseFloat(parms[1]);
+                    setValue("wy", y / 100f);
+                    float w = Float.parseFloat(parms[2]);
+                    setValue("ww", w / 100f);
+                    float h = Float.parseFloat(parms[3]);
+                    setValue("wh", h / 100f);
+                } catch (Exception e) {
+                    errorMessage = "Error parsing range parameter in IIIF path!";
+                    logger.error(errorMessage, e);
+                    return false;
+                }
+            } else {
+                // x,y,w,h -- region in pixel of original image :-(
+                String[] parms = region.split(",");
+                if (parms.length != 4) {
+                    errorMessage = "Error parsing range parameter in IIIF path!";
+                    logger.error(errorMessage);
+                    return false;
+                } else {
+                    options.setOption("pxarea");
+                    setValueFromString("wx", parms[0]);
+                    setValueFromString("wy", parms[1]);
+                    setValueFromString("ww", parms[2]);
+                    setValueFromString("wh", parms[3]);
+                }
+            }
+        } else {
+            // region omitted -- assume info request
+            options.setOption("info");
+            return true;
+        }
+        
+        /*
+         * parameter size
+         */
+        if (size != null) {
+            if (size.equals("full")) {
+                // full -- size of original
+                options.setOption("ascale");
+                setValue("scale", 1f);
+            } else if (size.startsWith("pct:")) {
+                // pct:n -- n% size of original
+                try {
+                    float pct = Float.parseFloat(size.substring(4));
+                    options.setOption("ascale");
+                    setValue("scale", pct / 100);
+                } catch (NumberFormatException e) {
+                    errorMessage = "Error parsing size parameter in IIIF path!";
+                    logger.error(errorMessage, e);
+                    return false;
+                }
+            } else {
+                // w,h -- pixel size
+                try {
+                    String[] parms = size.split(",", 2);
+                    if (parms[0].length() > 0) {
+                        // width param
+                        if (parms[0].startsWith("!")) {
+                            // width (in digilib-like bounding box)
+                            setValueFromString("dw", parms[0].substring(1));
+                        } else if (parms[1].length() == 0) {
+                            // width only
+                            setValueFromString("dw", parms[0]);
+                        } else {
+                            // w,h -- according to spec, we should distort the
+                            // image to match ;-(
+                            errorMessage = "Non-uniform-scale size parameter in IIIF path not supported!";
+                            logger.error(errorMessage);
+                            return false;
+                        }
+                    }
+                    if (parms[1].length() > 0) {
+                        // height param
+                        setValueFromString("dh", parms[1]);
+                    }
+                } catch (Exception e) {
+                    errorMessage = "Error parsing size parameter in IIIF path!";
+                    logger.error(errorMessage, e);
+                    return false;
+                }
+            }
+        } else {
+            // size omitted -- assume "full"
+            options.setOption("ascale");
+            setValue("scale", 1f);
+            return true;
+        }
+        
+        /*
+         * parameter rotation
+         */
+        if (rotation != null) {
+            try {
+                float rot = Float.parseFloat(rotation);
+                setValue("rot", rot);
+            } catch (NumberFormatException e) {
+                errorMessage = "Error parsing rotation parameter in IIIF path!";
+                logger.error(errorMessage, e);
+                return false;
+            }
+        }
+        
+        /*
+         * parameter quality
+         */
+        if (quality != null) {
+            // quality param
+            if (quality.equals("native") || quality.equals("color")) {
+                // native is default anyway
+            } else if (quality.equals("grey")) {
+                setValueFromString("colop", "grayscale");
+            } else {
+                errorMessage = "Invalid quality parameter in IIIF path!";
+                logger.error(errorMessage);
+                return false;
+            }
+        }
+        
+        /*
+         * parameter format
+         */
+        if (format != null) {
+            // format param (we only support jpg and png)
+            if (format.equals("jpg")) {
+                // force jpg
+                options.setOption("jpg");
+            } else if (format.equals("png")) {
+                // force png
+                options.setOption("png");
+            } else {
+                errorMessage = "Invalid format parameter in IIIF path!";
+                logger.error(errorMessage);
+                return false;
+            }
+        }
+        return true;
+	}
+
+	
     /**
      * Test if option string <code>opt</code> is set. Checks if the substring
      * <code>opt</code> is contained in the options string <code>param</code>.
--- a/servlet/src/main/java/digilib/servlet/ServletOps.java	Mon Jul 22 21:18:50 2013 +0200
+++ b/servlet/src/main/java/digilib/servlet/ServletOps.java	Thu Aug 22 17:14:33 2013 +0200
@@ -44,6 +44,7 @@
 import digilib.conf.DigilibServletRequest;
 import digilib.image.DocuImage;
 import digilib.image.ImageOpException;
+import digilib.io.FileOpException;
 import digilib.io.FileOps;
 import digilib.io.ImageInput;
 import digilib.util.ImageSize;
@@ -353,6 +354,7 @@
      * @param dlReq
      * @param response
      * @param logger
+     * @throws FileOpException 
      * @throws ServletException
      * @see <a href="http://www-sul.stanford.edu/iiif/image-api/1.1/#info">IIIF Image Information Request</a>
      */
@@ -361,34 +363,44 @@
             logger.error("No response!");
             return;
         }
+        ImageSize size = null;
         try {
             // get original image size
-            ImageInput img = dlReq.getJobDescription().getImageSet().getBiggest();
-            ImageSize size = img.getSize();
-            String url = dlReq.getServletRequest().getRequestURL().toString();
-            if (url.endsWith("/info.json")) {
-                url = url.substring(0, url.lastIndexOf("/info.json"));
-            } else if (url.endsWith("/")) {
-                url = url.substring(0, url.lastIndexOf("/"));
+            ImageInput img;
+            img = dlReq.getJobDescription().getImageSet().getBiggest();
+            size = img.getSize();
+        } catch (FileOpException e) {
+            try {
+                response.sendError(HttpServletResponse.SC_NOT_FOUND);
+                return;
+            } catch (IOException e1) {
+                throw new ServletException("Unable to write error response!", e);
             }
-            response.setContentType("application/json;charset=UTF-8");
-            PrintWriter writer = response.getWriter();
+        }
+        String url = dlReq.getServletRequest().getRequestURL().toString();
+        if (url.endsWith("/info.json")) {
+            url = url.substring(0, url.lastIndexOf("/info.json"));
+        } else if (url.endsWith("/")) {
+            url = url.substring(0, url.lastIndexOf("/"));
+        }
+        response.setContentType("application/json;charset=UTF-8");
+        PrintWriter writer;
+        try {
+            writer = response.getWriter();
             writer.println("{");
             writer.println("\"@context\" : \"http://library.stanford.edu/iiif/image-api/1.1/context.json\",");
-            writer.println("\"@id\" : \""+url+"\",");
-            writer.println("\"width\" : "+size.width+",");
-            writer.println("\"height\" : "+size.height+",");
+            writer.println("\"@id\" : \"" + url + "\",");
+            writer.println("\"width\" : " + size.width + ",");
+            writer.println("\"height\" : " + size.height + ",");
             writer.println("\"formats\" : [\"jpg\", \"png\"],");
             writer.println("\"qualities\" : [\"native\", \"color\", \"grey\"],");
             writer.println("\"profile\" : \"http://library.stanford.edu/iiif/image-api/1.1/compliance.html#level2\"");
             writer.println("}");
         } catch (IOException e) {
-            throw new ServletException("Error sending info:", e);
+            throw new ServletException("Unable to write response!", e);
         }
-        // TODO: should we: finally { img.dispose(); }
     }
 
-
     /** Returns text representation of headers for debuggging purposes.
      * @param req
      * @return