changeset 73:3b8797fc3e90

New servlet version 1.5b. Mostly cleanup. Global parameters for digilib now in DigilibConfiguration, per request parameters are now all in DigilibRequest. The DocuImage implementation can be selected by the configuration docuimage-class. Pixel-by-pixel view implemented with "mo=clip".
author robcast
date Fri, 24 Jan 2003 21:40:59 +0100
parents 300d5ba8b33b
children c64e9ae9c788
files servlet/src/digilib/auth/AuthOpsImpl.java servlet/src/digilib/auth/XMLAuthOps.java servlet/src/digilib/image/DocuImage.java servlet/src/digilib/image/DocuImageImpl.java servlet/src/digilib/image/ImageLoaderDocuImage.java servlet/src/digilib/image/JAIDocuImage.java servlet/src/digilib/image/JAIImageLoaderDocuImage.java servlet/src/digilib/image/JIMIDocuImage.java servlet/src/digilib/servlet/DigilibConfiguration.java servlet/src/digilib/servlet/DigilibRequest.java servlet/src/digilib/servlet/DocumentBean.java servlet/src/digilib/servlet/Scaler.java servlet/src/digilib/servlet/ServletOps.java
diffstat 13 files changed, 2477 insertions(+), 1484 deletions(-) [+]
line wrap: on
line diff
--- a/servlet/src/digilib/auth/AuthOpsImpl.java	Fri Jan 24 21:40:59 2003 +0100
+++ b/servlet/src/digilib/auth/AuthOpsImpl.java	Fri Jan 24 21:40:59 2003 +0100
@@ -24,11 +24,19 @@
 import java.util.*;
 
 import digilib.*;
+import digilib.servlet.DigilibRequest;
 
+/** Basic implementation of AuthOps interface.
+ *
+ * Provides basic implementations. Only rolesForPath needs to be implemented
+ * by specific implementations.
+ */
 public abstract class AuthOpsImpl implements AuthOps {
 
+  /** Local utils object. */    
   protected Utils util;
 
+  /** Default constructor. */  
   public AuthOpsImpl() {
     util = new Utils();
     try {
@@ -37,6 +45,9 @@
     }
   }
 
+  /** Constructor taking an utils object.
+   * @param u utils object.
+   */  
   public AuthOpsImpl(Utils u) {
     util = u;
     try {
@@ -45,17 +56,56 @@
     }
   }
 
+  /** Test if the request is allowed to access filepath.
+   * @param filepath filepath to be acessed.
+   * @param request Request with user information.
+   * @throws AuthOpException Exception thrown on error.
+   * @return true if the request is allowed.
+   */
   public boolean isAuthRequired(String filepath, HttpServletRequest request) throws AuthOpException {
     // check permissions
     List rolesRequired = rolesForPath(filepath, request);
     return (rolesRequired != null);
   }
 
+  /**
+   * @see digilib.auth.AuthOps#isAuthRequired(digilib.servlet.DigilibRequest)
+   */
+  public boolean isAuthRequired(DigilibRequest request)
+	  throws AuthOpException {
+		// check permissions
+		List rolesRequired = rolesForPath(request);
+		return (rolesRequired != null);
+  }
+
+  /** Return authorization roles needed for request.
+   *
+   * Returns a list of authorization roles that would be allowed to access the
+   * specified path. The location information of the request is considered also.
+   * @param filepath filepath to be accessed.
+   * @param request ServletRequest with address information.
+   * @throws AuthOpException Exception thrown on error.
+   * @return List of Strings with role names.
+   */
   public boolean isAuthorized(String filepath, HttpServletRequest request) throws AuthOpException {
     List rolesAllowed = rolesForPath(filepath, request);
     return isRoleAuthorized(rolesAllowed, request);
   }
 
+  /**
+   * @see digilib.auth.AuthOps#isAuthorized(digilib.servlet.DigilibRequest)
+   */
+  public boolean isAuthorized(DigilibRequest request)
+	  throws AuthOpException {
+		List rolesAllowed = rolesForPath(request);
+		return isRoleAuthorized(rolesAllowed, request);
+  }
+
+  /** Test request authorization against a list of roles.
+   * @param roles List of Strings with role names.
+   * @param request ServletRequest with address information.
+   * @return true if the user information in the request authorizes one of the roles.
+   */
   public boolean isRoleAuthorized(List roles, HttpServletRequest request) {
     ListIterator r = roles.listIterator();
     String s = "";
@@ -70,8 +120,27 @@
     return false;
   }
 
+  /**
+   * @see digilib.auth.AuthOps#isRoleAuthorized(java.util.List, digilib.servlet.DigilibRequest)
+   */
+  public boolean isRoleAuthorized(List roles, DigilibRequest request) {
+	ListIterator r = roles.listIterator();
+	String s = "";
+	while (r.hasNext()) {
+	  s = (String)r.next();
+	  util.dprintln(5, "Testing role: "+s);
+	  if (((HttpServletRequest)request.getServletRequest()).isUserInRole(s)) {
+		util.dprintln(5, "Role Authorized");
+		return true;
+	  }
+	}
+	return false;
+  }
+
   public abstract void init() throws AuthOpException;
 
   public abstract List rolesForPath(String filepath, HttpServletRequest request) throws AuthOpException;
 
+  public abstract List rolesForPath(DigilibRequest request) throws AuthOpException;
+
 }
--- a/servlet/src/digilib/auth/XMLAuthOps.java	Fri Jan 24 21:40:59 2003 +0100
+++ b/servlet/src/digilib/auth/XMLAuthOps.java	Fri Jan 24 21:40:59 2003 +0100
@@ -26,72 +26,149 @@
 
 import digilib.*;
 import digilib.io.*;
+import digilib.servlet.DigilibRequest;
 
-
+/** Implementation of AuthOps using XML files.
+ *
+ * The configuration file is read by an XMLListLoader into HashTree objects for 
+ * authentication paths and IP numbers.
+ */
 public class XMLAuthOps extends AuthOpsImpl {
 
-  private String configFile = "/docuserver/www/digitallibrary/WEB-INF/digilib-auth.xml";
-  private HashTree authPaths;
-  private HashTree authIPs;
+	private String configFile =
+		"/docuserver/www/digitallibrary/WEB-INF/digilib-auth.xml";
+	private HashTree authPaths;
+	private HashTree authIPs;
+
+	/** Constructor taking an XML config file name and utils object.
+	 *
+	 * @param u utils object
+	 * @param confFile Configuration file name.
+	 * @throws AuthOpException Exception thrown on error.
+	 */
+	public XMLAuthOps(Utils u, String confFile) throws AuthOpException {
+		util = u;
+		configFile = confFile;
+		init();
+	}
+
+	/** Set configuration file and utils object.
+	 *
+	 * @param confFile XML config file name.
+	 * @throws AuthOpException Exception thrown on error.
+	 */
+	public void setConfig(String confFile) throws AuthOpException {
+		configFile = confFile;
+		init();
+	}
 
-  public XMLAuthOps(Utils u, String confFile) throws AuthOpException {
-    util = u;
-    configFile = confFile;
-    init();
-  }
-
-  public void setConfig(String confFile) throws AuthOpException {
-    configFile = confFile;
-    init();
-  }
+	/** Initialize.
+	 *
+	 * Read configuration files and setup authentication arrays.
+	 *
+	 * @throws AuthOpException Exception thrown on error.
+	 */
+	public void init() throws AuthOpException {
+		util.dprintln(10, "xmlauthops.init (" + configFile + ")");
+		Hashtable pathList = null;
+		Hashtable ipList = null;
+		try {
+			// create data loader for auth-path file
+			File confFile = new File(configFile);
+			// load authPaths
+			XMLListLoader pathLoader =
+				new XMLListLoader("digilib-paths", "path", "name", "role");
+			pathList = pathLoader.loadURL(confFile.toURL().toString());
+			// load authIPs
+			XMLListLoader ipLoader =
+				new XMLListLoader("digilib-addresses", "address", "ip", "role");
+			ipList = ipLoader.loadURL(confFile.toURL().toString());
+		} catch (Exception e) {
+			throw new AuthOpException(
+				"ERROR loading authorization config file: " + e);
+		}
+		if ((pathList == null) || (ipList == null)) {
+			throw new AuthOpException("ERROR unable to load authorization config file!");
+		}
+		// setup path tree
+		authPaths = new HashTree(pathList, "/", ",");
+		// setup ip tree
+		authIPs = new HashTree(ipList, ".", ",");
+	}
 
-  public void init() throws AuthOpException {
-    util.dprintln(10, "xmlauthops.init ("+configFile+")");
-    Hashtable pathList = null;
-    Hashtable ipList = null;
-    try {
-      // create data loader for auth-path file
-      File confFile = new File(configFile);
-      // load authPaths
-      XMLListLoader pathLoader = new XMLListLoader("digilib-paths", "path", "name", "role");
-      pathList = pathLoader.loadURL(confFile.toURL().toString());
-      // load authIPs
-      XMLListLoader ipLoader = new XMLListLoader("digilib-addresses", "address", "ip", "role");
-      ipList = ipLoader.loadURL(confFile.toURL().toString());
-    }
-    catch (Exception e) {
-      throw new AuthOpException("ERROR loading authorization config file: "+e);
-    }
-    if ((pathList == null)||(ipList == null)) {
-      throw new AuthOpException("ERROR unable to load authorization config file!");
-    }
-    // setup path tree
-    authPaths = new HashTree(pathList, "/", ",");
-    // setup ip tree
-    authIPs = new HashTree(ipList, ".", ",");
-  }
+	/** Return authorization roles needed for request.
+	 *
+	 * Returns the list of authorization roles that are needed to access the
+	 * specified path. No list means the path is free.
+	 *
+	 * The location information of the request is also considered.
+	 *
+	 * @param filepath filepath to be accessed.
+	 * @param request ServletRequest with address information.
+	 * @throws AuthOpException Exception thrown on error.
+	 * @return List of Strings with role names.
+	 */
+	public List rolesForPath(String filepath, HttpServletRequest request)
+		throws digilib.auth.AuthOpException {
+		util.dprintln(
+			4,
+			"rolesForPath ("
+				+ filepath
+				+ ") by ["
+				+ request.getRemoteAddr()
+				+ "]");
 
-  public List rolesForPath(String filepath, HttpServletRequest request) throws digilib.auth.AuthOpException {
-    util.dprintln(4, "rolesForPath ("+filepath+") by ["+request.getRemoteAddr()+"]");
+		// check if the requests address provides a role
+		List provided = authIPs.match(request.getRemoteAddr());
+		if ((provided != null) && (provided.contains("ALL"))) {
+			// ALL switches off checking;
+			return null;
+		}
+		// which roles are required?
+		List required = authPaths.match(filepath);
+		// do any provided roles match?
+		if ((provided != null) && (required != null)) {
+			for (int i = 0; i < provided.size(); i++) {
+				if (required.contains(provided.get(i))) {
+					// satisfied
+					return null;
+				}
+			}
+		}
+		return required;
+	}
 
-    // check if the requests address provides a role
-    List provided = authIPs.match(request.getRemoteAddr());
-    if ((provided != null)&&(provided.contains("ALL"))) {
-      // ALL switches off checking;
-      return null;
-    }
-    // which roles are required?
-    List required = authPaths.match(filepath);
-    // do any provided roles match?
-    if ((provided != null)&&(required != null)) {
-      for (int i = 0; i < provided.size(); i++) {
-        if (required.contains(provided.get(i))) {
-          // satisfied
-          return null;
-        }
-      }
-    }
-    return required;
-  }
+	/**
+	 * @see digilib.auth.AuthOps#rolesForPath(digilib.servlet.DigilibRequest)
+	 */
+	public List rolesForPath(DigilibRequest request) throws AuthOpException {
+		util.dprintln(
+			4,
+			"rolesForPath ("
+				+ request.getFilePath()
+				+ ") by ["
+				+ request.getServletRequest().getRemoteAddr()
+				+ "]");
+
+		// check if the requests address provides a role
+		List provided =
+			authIPs.match(request.getServletRequest().getRemoteAddr());
+		if ((provided != null) && (provided.contains("ALL"))) {
+			// ALL switches off checking;
+			return null;
+		}
+		// which roles are required?
+		List required = authPaths.match(request.getFilePath());
+		// do any provided roles match?
+		if ((provided != null) && (required != null)) {
+			for (int i = 0; i < provided.size(); i++) {
+				if (required.contains(provided.get(i))) {
+					// satisfied
+					return null;
+				}
+			}
+		}
+		return required;
+	}
 
 }
--- a/servlet/src/digilib/image/DocuImage.java	Fri Jan 24 21:40:59 2003 +0100
+++ b/servlet/src/digilib/image/DocuImage.java	Fri Jan 24 21:40:59 2003 +0100
@@ -20,46 +20,74 @@
 
 package digilib.image;
 
-import javax.servlet.*;
-import javax.servlet.http.*;
-import java.io.*;
-import java.util.*;
+import java.io.File;
+
+import javax.servlet.ServletResponse;
+
+import digilib.io.FileOpException;
+
 
-import java.awt.image.*;
-import java.awt.image.renderable.*;
-
-import digilib.*;
-import digilib.io.*;
-
+/** The basic class for the representation of a digilib image.
+ *
+ * The actual image object is hidden in the class, only methods for loading,
+ * manipulation, and saving are exported. This strategy enables implementations
+ * using different toolkits that rely on different image base classes (like
+ * JIMI, Java2D and JAI).
+ */
 public interface DocuImage {
 
+  /** Returns the list of image file types known to the DocuImage implementation.
+   * 
+   * @return List of image file types. Strings are standard file extensions.
+   */    
   public String[] getKnownFileTypes();
 
-  /**
-   *  send an image file as-is
-   */
-  public void sendFile(File f, ServletResponse res) throws FileOpException;
-
-  /**
-   *  load image file
+  /** Loads an image file into the Object.
+   * 
+   * @param f Image File.
+   * @throws FileOpException Exception thrown if any error occurs.
    */
   public void loadImage(File f) throws FileOpException;
 
-  /**
-   *  write image with mime type mt to Stream
+  /** Writes the current image to a ServletResponse.
+   *
+   * The image is encoded to the mime-type <code>mt</code> and sent to the output
+   * stream of the <code>ServletResponse</code> <code>res</code>.
+   *
+   * Currently only mime-types "image/jpeg" and "image/png" are supported.
+   * 
+   * @param mt mime-type of the image to be sent.
+   * @param res ServletResponse where the image is sent.
+   * @throws FileOpException Exception thrown on any error.
    */
   public void writeImage(String mt, ServletResponse res) throws FileOpException;
 
-  /**
-   *  get the image height and width
+  /** The width of the current image in pixel.
+   * 
+   * @return Image width in pixels.
    */
   public int getWidth();
+  
+  /** The height of the current image in pixel.
+   * 
+   * @return Image height in pixels.
+   */  
   public int getHeight();
 
-  /**
-   *  crop and scale image
-   *    take rectangle width,height at position x_off,y_off
-   *    and scale by scale with interpolation quality qual (0=worst)
+  /** Crops and scales the current image.
+   *
+   * The current image is cropped to a rectangle of <code>width</code>,
+   * <code>height</code> at position <code>x_off</code>, <code>y_off</code>. The
+   * resulting image is scaled by the factor <code>scale</code> using the
+   * interpolation quality <code>qual</code> (0=worst).
+   * 
+   * @param x_off x offset of the crop rectangle in pixel.
+   * @param y_off y offset of the crop rectangle in pixel.
+   * @param width width of the crop rectangle in pixel.
+   * @param height height of the crop rectangle in pixel.
+   * @param scale scaling factor.
+   * @param qual interpolation quality (0=worst).
+   * @throws ImageOpException exception thrown on any error.
    */
   public void cropAndScale(
                 int x_off, int y_off,
--- a/servlet/src/digilib/image/DocuImageImpl.java	Fri Jan 24 21:40:59 2003 +0100
+++ b/servlet/src/digilib/image/DocuImageImpl.java	Fri Jan 24 21:40:59 2003 +0100
@@ -14,7 +14,7 @@
 
   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
-  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 
 */
 
@@ -26,55 +26,51 @@
 import digilib.*;
 import digilib.io.*;
 
+/** Simple abstract implementation of the <code>DocuImage</code> interface.
+ *
+ * This implementation provides basic functionality for the utility methods like
+ * <code>SetUtils</code>, and <code>getKnownFileTypes</code>. Image methods like
+ * <code>loadImage</code>, <code>writeImage</code>, <code>getWidth</code>,
+ * <code>getHeight</code> and <code>cropAndScale</code> must be implemented by
+ * derived classes.
+ */
 public abstract class DocuImageImpl implements DocuImage {
 
+  /** Internal utils object. */    
   protected Utils util = null;
 
+  /** Default constructor. */  
   public DocuImageImpl() {
     util = new Utils();
   }
 
+  /** Contructor taking an utils object.
+   * 
+   * @param u Utils object.
+   */  
   public DocuImageImpl(Utils u) {
     util = u;
   }
 
+  /** Set local Utils object.
+   * 
+   * @param u Utils object.
+   */  
   public void setUtils(Utils u) {
     util = u;
   }
 
+  /** Internal knownFileTypes. */  
   protected String[] knownFileTypes = {"jpg", "png", "gif", "tiff"};
 
+  /** Returns the list of image file types known to the DocuImage implementation.
+   * 
+   * @return List of image file types. Strings are standard file extensions.
+   */    
   public String[] getKnownFileTypes() {
     return knownFileTypes;
   }
 
-  /**
-   *  send an image file as-is
-   */
-  public void sendFile(File f, ServletResponse response) throws FileOpException {
-    util.dprintln(4, "sendFile("+f+")");
-    String mimeType = FileOps.mimeForFile(f);
-    if (mimeType == null) {
-      util.dprintln(2, "ERROR(sendFile): unknown file Type");
-      throw new FileOpException("Unknown file type.");
-    }
-    response.setContentType(mimeType);
-    // open file
-    try {
-      FileInputStream inFile = new FileInputStream(f);
-      OutputStream outStream = response.getOutputStream();
-      byte dataBuffer[] = new byte[1024];
-      int len;
-      while ((len = inFile.read(dataBuffer)) != -1) {
-        // copy out file
-        outStream.write(dataBuffer, 0, len);
-      }
-      inFile.close();
-    } catch (IOException e) {
-      util.dprintln(2, "ERROR(sendFile): unable to send file");
-      throw new FileOpException("Unable to send file.");
-    }
-  }
 
   public abstract void loadImage(File f) throws FileOpException;
   public abstract void writeImage(String mt, ServletResponse res) throws FileOpException;
--- a/servlet/src/digilib/image/ImageLoaderDocuImage.java	Fri Jan 24 21:40:59 2003 +0100
+++ b/servlet/src/digilib/image/ImageLoaderDocuImage.java	Fri Jan 24 21:40:59 2003 +0100
@@ -20,21 +20,19 @@
 
 package digilib.image;
 
-import javax.servlet.*;
-import javax.servlet.http.*;
-import java.io.*;
-import java.util.*;
+import java.awt.geom.AffineTransform;
+import java.awt.image.AffineTransformOp;
+import java.awt.image.BufferedImage;
+import java.io.File;
+import java.io.IOException;
 
-import java.awt.*;
-import java.awt.image.*;
-import java.awt.geom.*;
-import java.awt.image.renderable.*;
+import javax.imageio.ImageIO;
+import javax.servlet.ServletResponse;
 
-import javax.imageio.*;
+import digilib.Utils;
+import digilib.io.FileOpException;
 
-import digilib.*;
-import digilib.io.*;
-
+/** Implementation of DocuImage using the ImageLoader API of Java 1.4 and Java2D. */
 public class ImageLoaderDocuImage extends DocuImageImpl {
 
   private BufferedImage img;
--- a/servlet/src/digilib/image/JAIDocuImage.java	Fri Jan 24 21:40:59 2003 +0100
+++ b/servlet/src/digilib/image/JAIDocuImage.java	Fri Jan 24 21:40:59 2003 +0100
@@ -20,149 +20,191 @@
 
 package digilib.image;
 
-import javax.servlet.*;
-import javax.servlet.http.*;
-import java.io.*;
-import java.util.*;
+import java.awt.image.RenderedImage;
+import java.awt.image.renderable.ParameterBlock;
+import java.io.File;
+import java.io.IOException;
 
-import java.awt.*;
-import java.awt.image.*;
-import java.awt.image.renderable.*;
-import javax.media.jai.*;
+import javax.media.jai.Interpolation;
+import javax.media.jai.JAI;
+import javax.servlet.ServletResponse;
 
-import digilib.*;
-import digilib.io.*;
+import digilib.Utils;
+import digilib.io.FileOpException;
 
-
+/** A DocuImage implementation using Java Advanced Imaging Library. */
 public class JAIDocuImage extends DocuImageImpl {
 
-  private RenderedImage img;
+	private RenderedImage img;
+
+	/** Default constructor. */
+	public JAIDocuImage() {
+	}
 
-  public JAIDocuImage() {
-  }
-
-  public JAIDocuImage(Utils u) {
-    util = u;
-  }
+	/** Contructor taking a utils object.
+	 * @param u utils object.
+	 */
+	public JAIDocuImage(Utils u) {
+		util = u;
+	}
 
-  /**
-   *  load image file
-   */
-  public void loadImage(File f) throws FileOpException {
-    System.gc();
-    img = JAI.create("fileload", f.getAbsolutePath());
-    if (img == null) {
-      util.dprintln(3, "ERROR(loadImage): unable to load file");
-      throw new FileOpException("Unable to load File!");
-    }
-  }
+	/** Load an image file into the Object.
+	 *
+	 * @param f Image File.
+	 * @throws FileOpException Exception thrown if any error occurs.
+	 */
+	public void loadImage(File f) throws FileOpException {
+		System.gc();
+		img = JAI.create("fileload", f.getAbsolutePath());
+		if (img == null) {
+			util.dprintln(3, "ERROR(loadImage): unable to load file");
+			throw new FileOpException("Unable to load File!");
+		}
+	}
 
-  /**
-   *  write image of type mt to Stream
-   */
-  public void writeImage(String mt, ServletResponse res)
-         throws FileOpException {
-    try {
-    // setup output
-    ParameterBlock pb3 = new ParameterBlock();
-    pb3.addSource(img);
-    pb3.add(res.getOutputStream());
-    if (mt == "image/jpeg") {
-      pb3.add("JPEG");
-    } else if (mt == "image/png") {
-      pb3.add("PNG");
-    } else {
-      // unknown mime type
-      util.dprintln(2, "ERROR(writeImage): Unknown mime type "+mt);
-      throw new FileOpException("Unknown mime type: "+mt);
-    }
-    res.setContentType(mt);
-    // render output
-    JAI.create("encode", pb3);
+	/** Write the current image to a ServletResponse.
+	 *
+	 * The image is encoded to the mime-type mt and sent to the output stream of the
+	 * ServletResponse res.
+	 *
+	 * Currently only mime-types "image/jpeg" and "image/png" are allowed.
+	 * @param mt mime-type of the image to be sent.
+	 * @param res ServletResponse where the image is sent.
+	 * @throws FileOpException Exception thrown on any error.
+	 */
+	public void writeImage(String mt, ServletResponse res)
+		throws FileOpException {
+		try {
+			// setup output
+			ParameterBlock pb3 = new ParameterBlock();
+			pb3.addSource(img);
+			pb3.add(res.getOutputStream());
+			if (mt == "image/jpeg") {
+				pb3.add("JPEG");
+			} else if (mt == "image/png") {
+				pb3.add("PNG");
+			} else {
+				// unknown mime type
+				util.dprintln(2, "ERROR(writeImage): Unknown mime type " + mt);
+				throw new FileOpException("Unknown mime type: " + mt);
+			}
+			res.setContentType(mt);
+			// render output
+			JAI.create("encode", pb3);
 
-    } catch (IOException e) {
-      throw new FileOpException("Error writing image.");
-    }
-  }
+		} catch (IOException e) {
+			throw new FileOpException("Error writing image.");
+		}
+	}
 
-  public int getWidth() {
-    if (img != null) {
-      return img.getWidth();
-    }
-    return 0;
-  }
+	/** The width of the curent image in pixel.
+	 * @return Image width in pixels.
+	 */
+	public int getWidth() {
+		if (img != null) {
+			return img.getWidth();
+		}
+		return 0;
+	}
 
-  public int getHeight() {
-    if (img != null) {
-      return img.getHeight();
-    }
-    return 0;
-  }
-
+	/** The height of the curent image in pixel.
+	 * @return Image height in pixels.
+	 */
+	public int getHeight() {
+		if (img != null) {
+			return img.getHeight();
+		}
+		return 0;
+	}
 
-  /**
-   *  crop and scale image
-   *    take rectangle width,height at position x_off,y_off
-   *    and scale by scale
-   */
-   public void cropAndScale(int x_off, int y_off, int width, int height,
-         float scale, int qual) throws ImageOpException {
+	/** Crop and scale the current image.
+	 *
+	 * The current image is cropped to a rectangle of width, height at position
+	 * x_off, y_off. The resulting image is scaled by the factor scale using the
+	 * interpolation quality qual (0=worst).
+	 * 
+	 * @param x_off X offset of the crop rectangle in pixel.
+	 * @param y_off Y offset of the crop rectangle in pixel.
+	 * @param width Width of the crop rectangle in pixel.
+	 * @param height Height of the crop rectangle in pixel.
+	 * @param scale Scaling factor.
+	 * @param qual Interpolation quality (0=worst).
+	 * @throws ImageOpException Exception thrown on any error.
+	 */
+	public void cropAndScale(
+		int x_off,
+		int y_off,
+		int width,
+		int height,
+		float scale,
+		int qual)
+		throws ImageOpException {
 
-    Interpolation scaleInt = null;
-    // setup interpolation quality
-    if (qual > 1) {
-      util.dprintln(4, "quality q2");
-      scaleInt = Interpolation.getInstance(Interpolation.INTERP_BICUBIC);
-    } else if (qual == 1) {
-      util.dprintln(4, "quality q1");
-      scaleInt = Interpolation.getInstance(Interpolation.INTERP_BILINEAR);
-    } else {
-      util.dprintln(4, "quality q0");
-      scaleInt = Interpolation.getInstance(Interpolation.INTERP_NEAREST);
-    }
-
-    // setup Crop
-    ParameterBlock pb1 = new ParameterBlock();
-    pb1.addSource(img);
-    pb1.add((float)x_off);
-    pb1.add((float)y_off);
-    pb1.add((float)width);
-    pb1.add((float)height);
-    RenderedImage croppedImg = JAI.create("crop", pb1);
-    img = null; // free img
+		Interpolation scaleInt = null;
+		// setup interpolation quality
+		if (qual > 1) {
+			util.dprintln(4, "quality q2");
+			scaleInt = Interpolation.getInstance(Interpolation.INTERP_BICUBIC);
+		} else if (qual == 1) {
+			util.dprintln(4, "quality q1");
+			scaleInt = Interpolation.getInstance(Interpolation.INTERP_BILINEAR);
+		} else {
+			util.dprintln(4, "quality q0");
+			scaleInt = Interpolation.getInstance(Interpolation.INTERP_NEAREST);
+		}
 
-    util.dprintln(3, "CROP:"+croppedImg.getWidth()+"x"+croppedImg.getHeight()); //DEBUG
+		// setup Crop
+		ParameterBlock pb1 = new ParameterBlock();
+		pb1.addSource(img);
+		pb1.add((float) x_off);
+		pb1.add((float) y_off);
+		pb1.add((float) width);
+		pb1.add((float) height);
+		RenderedImage croppedImg = JAI.create("crop", pb1);
+		img = null; // free img
 
-    if (croppedImg == null) {
-      util.dprintln(2, "ERROR(cropAndScale): error in crop");
-      throw new ImageOpException("Unable to crop");
-    }
+		util.dprintln(
+			3,
+			"CROP:" + croppedImg.getWidth() + "x" + croppedImg.getHeight());
+		//DEBUG
+
+		if (croppedImg == null) {
+			util.dprintln(2, "ERROR(cropAndScale): error in crop");
+			throw new ImageOpException("Unable to crop");
+		}
+
+		// setup scale
+		RenderedImage scaledImg;
 
-    // setup scale
-    ParameterBlock pb2 = new ParameterBlock();
-    pb2.addSource(croppedImg);
-    pb2.add(scale);
-    pb2.add(scale);
-    pb2.add(0f);
-    pb2.add(0f);
-    pb2.add(scaleInt);
-    // the following is nice but way too slow...
-    //if (opCrop.getColorModel().getPixelSize() < 8) {
-    // change color model if necessary
-    //  util.dprintln("converting color model...");
-    //  BufferedImage bi = new BufferedImage(1, 1, BufferedImage.TYPE_BYTE_GRAY);
-    //  ImageLayout lay = new ImageLayout(bi);
-    //  rh = new RenderingHints(JAI.KEY_IMAGE_LAYOUT, lay);
-    //}
-    RenderedImage scaledImg = JAI.create("scale", pb2);
-    croppedImg = null; // free opCrop
+		if (scale != 1f) {
+			ParameterBlock pb2 = new ParameterBlock();
+			pb2.addSource(croppedImg);
+			pb2.add(scale);
+			pb2.add(scale);
+			pb2.add(0f);
+			pb2.add(0f);
+			pb2.add(scaleInt);
+			// the following is nice but way too slow...
+			//if (opCrop.getColorModel().getPixelSize() < 8) {
+			// change color model if necessary
+			//  util.dprintln("converting color model...");
+			//  BufferedImage bi = new BufferedImage(1, 1, BufferedImage.TYPE_BYTE_GRAY);
+			//  ImageLayout lay = new ImageLayout(bi);
+			//  rh = new RenderingHints(JAI.KEY_IMAGE_LAYOUT, lay);
+			//}
+			scaledImg = JAI.create("scale", pb2);
+			croppedImg = null; // free opCrop
+		} else {
+			// no scaling
+			scaledImg = croppedImg;
+		}
 
-    if (scaledImg == null) {
-      util.dprintln(2, "ERROR(cropAndScale): error in scale");
-      throw new ImageOpException("Unable to scale");
-    }
+		if (scaledImg == null) {
+			util.dprintln(2, "ERROR(cropAndScale): error in scale");
+			throw new ImageOpException("Unable to scale");
+		}
 
-    img = scaledImg;
-  }
+		img = scaledImg;
+	}
 
 }
--- a/servlet/src/digilib/image/JAIImageLoaderDocuImage.java	Fri Jan 24 21:40:59 2003 +0100
+++ b/servlet/src/digilib/image/JAIImageLoaderDocuImage.java	Fri Jan 24 21:40:59 2003 +0100
@@ -20,149 +20,189 @@
 
 package digilib.image;
 
-import javax.servlet.*;
-import javax.servlet.http.*;
-import java.io.*;
-import java.util.*;
+import java.awt.image.RenderedImage;
+import java.awt.image.renderable.ParameterBlock;
+import java.io.File;
+import java.io.IOException;
 
-import java.awt.*;
-import java.awt.image.*;
-import java.awt.image.renderable.*;
-import javax.media.jai.*;
+import javax.media.jai.Interpolation;
+import javax.media.jai.JAI;
+import javax.servlet.ServletResponse;
 
-import digilib.*;
-import digilib.io.*;
+import digilib.Utils;
+import digilib.io.FileOpException;
 
-
+/** DocuImage implementation using the Java Advanced Imaging API and the ImageLoader
+ * API of Java 1.4.
+ */
 public class JAIImageLoaderDocuImage extends DocuImageImpl {
 
-  private RenderedImage img;
+	private RenderedImage img;
+
+	/** Default constructor. */
+	public JAIImageLoaderDocuImage() {
+	}
 
-  public JAIImageLoaderDocuImage() {
-  }
-
-  public JAIImageLoaderDocuImage(Utils u) {
-    util = u;
-  }
+	/** Constructor using an utils object.
+	 * @param u Utils object.
+	 */
+	public JAIImageLoaderDocuImage(Utils u) {
+		util = u;
+	}
 
-  /**
-   *  load image file
-   */
-  public void loadImage(File f) throws FileOpException {
-    System.gc();
-    img = JAI.create("ImageRead", f.getAbsolutePath());
-    if (img == null) {
-      util.dprintln(3, "ERROR(loadImage): unable to load file");
-      throw new FileOpException("Unable to load File!");
-    }
-  }
+	/** Load an image file into the Object.
+	 * @param f Image file.
+	 * @throws FileOpException Exception thrown on any error.
+	 */
+	public void loadImage(File f) throws FileOpException {
+		System.gc();
+		img = JAI.create("ImageRead", f.getAbsolutePath());
+		if (img == null) {
+			util.dprintln(3, "ERROR(loadImage): unable to load file");
+			throw new FileOpException("Unable to load File!");
+		}
+	}
 
-  /**
-   *  write image of type mt to Stream
-   */
-  public void writeImage(String mt, ServletResponse res)
-         throws FileOpException {
-    try {
-    // setup output
-    ParameterBlock pb3 = new ParameterBlock();
-    pb3.addSource(img);
-    pb3.add(res.getOutputStream());
-    if (mt == "image/jpeg") {
-      pb3.add("JPEG");
-    } else if (mt == "image/png") {
-      pb3.add("PNG");
-    } else {
-      // unknown mime type
-      util.dprintln(2, "ERROR(writeImage): Unknown mime type "+mt);
-      throw new FileOpException("Unknown mime type: "+mt);
-    }
-    res.setContentType(mt);
-    // render output
-    JAI.create("ImageWrite", pb3);
+	/** Write the current image to a ServletResponse.
+	 *
+	 * The image is encoded to the mime-type mt and sent to the output stream of the
+	 * ServletResponse res.
+	 *
+	 * Currently only mime-types "image/jpeg" and "image/png" are allowed.
+	 * @param mt mime-type of the image to be sent.
+	 * @param res ServletResponse where the image is sent.
+	 * @throws FileOpException Exception thrown on any error.
+	 */
+	public void writeImage(String mt, ServletResponse res)
+		throws FileOpException {
+		try {
+			// setup output
+			ParameterBlock pb3 = new ParameterBlock();
+			pb3.addSource(img);
+			pb3.add(res.getOutputStream());
+			if (mt == "image/jpeg") {
+				pb3.add("JPEG");
+			} else if (mt == "image/png") {
+				pb3.add("PNG");
+			} else {
+				// unknown mime type
+				util.dprintln(2, "ERROR(writeImage): Unknown mime type " + mt);
+				throw new FileOpException("Unknown mime type: " + mt);
+			}
+			res.setContentType(mt);
+			// render output
+			JAI.create("ImageWrite", pb3);
 
-    } catch (IOException e) {
-      throw new FileOpException("Error writing image.");
-    }
-  }
+		} catch (IOException e) {
+			throw new FileOpException("Error writing image.");
+		}
+	}
 
-  public int getWidth() {
-    if (img != null) {
-      return img.getWidth();
-    }
-    return 0;
-  }
+	/** The width of the curent image in pixel.
+	 * @return Image width in pixels.
+	 */
+	public int getWidth() {
+		if (img != null) {
+			return img.getWidth();
+		}
+		return 0;
+	}
 
-  public int getHeight() {
-    if (img != null) {
-      return img.getHeight();
-    }
-    return 0;
-  }
-
+	/** The height of the curent image in pixel.
+	 * @return Image height in pixels.
+	 */
+	public int getHeight() {
+		if (img != null) {
+			return img.getHeight();
+		}
+		return 0;
+	}
 
-  /**
-   *  crop and scale image
-   *    take rectangle width,height at position x_off,y_off
-   *    and scale by scale
-   */
-   public void cropAndScale(int x_off, int y_off, int width, int height,
-         float scale, int qual) throws ImageOpException {
+	/** Crop and scale the current image.
+	 *
+	 * The current image is cropped to a rectangle of width, height at position
+	 * x_off, y_off. The resulting image is scaled by the factor scale using the
+	 * interpolation quality qual (0=worst).
+	 * @param x_off X offset of the crop rectangle in pixel.
+	 * @param y_off Y offset of the crop rectangle in pixel.
+	 * @param width Width of the crop rectangle in pixel.
+	 * @param height Height of the crop rectangle in pixel.
+	 * @param scale Scaling factor.
+	 * @param qual Interpolation quality (0=worst).
+	 * @throws ImageOpException Exception thrown on any error.
+	 */
+	public void cropAndScale(
+		int x_off,
+		int y_off,
+		int width,
+		int height,
+		float scale,
+		int qual)
+		throws ImageOpException {
 
-    Interpolation scaleInt = null;
-    // setup interpolation quality
-    if (qual > 1) {
-      util.dprintln(4, "quality q2");
-      scaleInt = Interpolation.getInstance(Interpolation.INTERP_BICUBIC);
-    } else if (qual == 1) {
-      util.dprintln(4, "quality q1");
-      scaleInt = Interpolation.getInstance(Interpolation.INTERP_BILINEAR);
-    } else {
-      util.dprintln(4, "quality q0");
-      scaleInt = Interpolation.getInstance(Interpolation.INTERP_NEAREST);
-    }
-
-    // setup Crop
-    ParameterBlock pb1 = new ParameterBlock();
-    pb1.addSource(img);
-    pb1.add((float)x_off);
-    pb1.add((float)y_off);
-    pb1.add((float)width);
-    pb1.add((float)height);
-    RenderedImage croppedImg = JAI.create("crop", pb1);
-    img = null; // free img
+		Interpolation scaleInt = null;
+		// setup interpolation quality
+		if (qual > 1) {
+			util.dprintln(4, "quality q2");
+			scaleInt = Interpolation.getInstance(Interpolation.INTERP_BICUBIC);
+		} else if (qual == 1) {
+			util.dprintln(4, "quality q1");
+			scaleInt = Interpolation.getInstance(Interpolation.INTERP_BILINEAR);
+		} else {
+			util.dprintln(4, "quality q0");
+			scaleInt = Interpolation.getInstance(Interpolation.INTERP_NEAREST);
+		}
 
-    util.dprintln(3, "CROP:"+croppedImg.getWidth()+"x"+croppedImg.getHeight()); //DEBUG
+		// setup Crop
+		ParameterBlock pb1 = new ParameterBlock();
+		pb1.addSource(img);
+		pb1.add((float) x_off);
+		pb1.add((float) y_off);
+		pb1.add((float) width);
+		pb1.add((float) height);
+		RenderedImage croppedImg = JAI.create("crop", pb1);
 
-    if (croppedImg == null) {
-      util.dprintln(2, "ERROR(cropAndScale): error in crop");
-      throw new ImageOpException("Unable to crop");
-    }
+		util.dprintln(
+			3,
+			"CROP:" + croppedImg.getWidth() + "x" + croppedImg.getHeight());
+		//DEBUG
+
+		if (croppedImg == null) {
+			util.dprintln(2, "ERROR(cropAndScale): error in crop");
+			throw new ImageOpException("Unable to crop");
+		}
+
+		RenderedImage scaledImg;
 
-    // setup scale
-    ParameterBlock pb2 = new ParameterBlock();
-    pb2.addSource(croppedImg);
-    pb2.add(scale);
-    pb2.add(scale);
-    pb2.add(0f);
-    pb2.add(0f);
-    pb2.add(scaleInt);
-    // the following is nice but way too slow...
-    //if (opCrop.getColorModel().getPixelSize() < 8) {
-    // change color model if necessary
-    //  util.dprintln("converting color model...");
-    //  BufferedImage bi = new BufferedImage(1, 1, BufferedImage.TYPE_BYTE_GRAY);
-    //  ImageLayout lay = new ImageLayout(bi);
-    //  rh = new RenderingHints(JAI.KEY_IMAGE_LAYOUT, lay);
-    //}
-    RenderedImage scaledImg = JAI.create("scale", pb2);
-    croppedImg = null; // free opCrop
+		if (scale != 1f) {
+			// setup scale
+			ParameterBlock pb2 = new ParameterBlock();
+			pb2.addSource(croppedImg);
+			pb2.add(scale);
+			pb2.add(scale);
+			pb2.add(0f);
+			pb2.add(0f);
+			pb2.add(scaleInt);
+			// the following is nice but way too slow...
+			//if (opCrop.getColorModel().getPixelSize() < 8) {
+			// change color model if necessary
+			//  util.dprintln("converting color model...");
+			//  BufferedImage bi = new BufferedImage(1, 1, BufferedImage.TYPE_BYTE_GRAY);
+			//  ImageLayout lay = new ImageLayout(bi);
+			//  rh = new RenderingHints(JAI.KEY_IMAGE_LAYOUT, lay);
+			//}
+			scaledImg = JAI.create("scale", pb2);
+		} else {
+			// no scaling
+			scaledImg = croppedImg;
+		}
 
-    if (scaledImg == null) {
-      util.dprintln(2, "ERROR(cropAndScale): error in scale");
-      throw new ImageOpException("Unable to scale");
-    }
+		if (scaledImg == null) {
+			util.dprintln(2, "ERROR(cropAndScale): error in scale");
+			throw new ImageOpException("Unable to scale");
+		}
 
-    img = scaledImg;
-  }
+		img = scaledImg;
+	}
 
 }
--- a/servlet/src/digilib/image/JIMIDocuImage.java	Fri Jan 24 21:40:59 2003 +0100
+++ b/servlet/src/digilib/image/JIMIDocuImage.java	Fri Jan 24 21:40:59 2003 +0100
@@ -36,6 +36,7 @@
 import digilib.io.*;
 
 
+/** Implementation of DocuImage using the JIMI image Library. */
 public class JIMIDocuImage extends DocuImageImpl {
 
   private JimiRasterImage img;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/servlet/src/digilib/servlet/DigilibConfiguration.java	Fri Jan 24 21:40:59 2003 +0100
@@ -0,0 +1,458 @@
+/* DigilibConfiguration -- Holding all parameters for digilib servlet.
+
+  Digital Image Library servlet components
+
+  Copyright (C) 2001, 2002 Robert Casties (robcast@mail.berlios.de)
+
+  This program is free software; you can redistribute  it and/or modify it
+  under  the terms of  the GNU General  Public License as published by the
+  Free Software Foundation;  either version 2 of the  License, or (at your
+  option) any later version.
+   
+  Please read license.txt for the full details. A copy of the GPL
+  may be found at http://www.gnu.org/copyleft/lgpl.html
+
+  You should have received a copy of the GNU General Public License
+  along with this program; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+*/
+
+package digilib.servlet;
+
+import digilib.auth.*;
+import digilib.image.*;
+import digilib.io.XMLListLoader;
+import digilib.Utils;
+import javax.servlet.*;
+import java.util.*;
+import java.io.*;
+
+/** 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.<br>
+ * errorImgFileName: image file to send in case of error.<br>
+ * denyImgFileName: image file to send if access is denied.<br>
+ * baseDirs: array of base directories in order of preference (prescaled
+ * versions first).<br>
+ * useAuth: use authentication information.<br>
+ * authConfPath: authentication configuration file.<br>
+ * authOp: AuthOps instance for authentication.<br>
+ * ...<br>
+ * 
+ * @author casties
+ *
+ */
+public class DigilibConfiguration {
+	// digilib servlet version
+	private String servletVersion = digilib.servlet.Scaler.dlVersion;
+	// configuration file location
+	private String dlConfPath = "";
+	// image file to send in case of error
+	private String errorImgFileName = "/docuserver/images/icons/scalerror.gif";
+	private String errorImgParam = "error-image";
+	// image file to send if access is denied
+	private String denyImgFileName = "/docuserver/images/icons/denied.gif";
+	private String denyImgParam = "denied-image";
+	// base directories in order of preference (prescaled versions first)
+	private String[] baseDirs =
+		{
+			"/docuserver/scaled/small",
+			"/docuserver/images",
+			"/docuserver/scans/quellen" };
+	private String baseDirParam = "basedir-list";
+	// use authentication information
+	private boolean useAuthentication = true;
+	private String useAuthParam = "use-authorization";
+	// authentication configuration file
+	private String authConfPath =
+		"/docuserver/www/digitallibrary/WEB-INF/digilib-auth.xml";
+	private String authConfParam = "auth-file";
+	// sending image files as-is allowed
+	private boolean sendFileAllowed = true;
+	private String sendFileAllowedParam = "sendfile-allowed";
+	// AuthOps instance for authentication
+	private AuthOps authOp;
+	// Debug level
+	private int debugLevel = 5;
+	private String debugLevelParam = "debug-level";
+	// Utils instance
+	private Utils util = new Utils();
+	// HashTable for parameters
+	private Hashtable confTable = null;
+	// Type of DocuImage instance
+	private String docuImageType = "digilib.image.JAIDocuImage";
+	private String docuImageTypeParam = "docuimage-class";
+	// part of URL used to indicate authorized access
+	private String authURLPath = "authenticated/";
+	private String AuthURLPathParam = "auth-url-path";
+
+	/** Constructor taking a ServletConfig.
+	 * Reads the config file location from an init parameter and loads the
+	 * config file. Calls <code>init</code>.
+	 * 
+	 * @see init()
+	 */
+	public DigilibConfiguration(ServletConfig c) throws Exception {
+		init(c);
+	}
+
+	/**
+	 * read parameter list from the XML file in init parameter "config-file"
+	 */
+	public void init(ServletConfig c) throws Exception {
+		// reset parameter table
+		confTable = null;
+		if (c == null) {
+			return;
+		}
+		// get config file name
+		String fn = c.getInitParameter("config-file");
+		if (fn == null) {
+			util.dprintln(4, "setConfig: no param config-file");
+			throw new ServletException("ERROR no digilib config file!");
+		}
+		File f = new File(fn);
+		// setup config file list reader
+		XMLListLoader lilo =
+			new XMLListLoader("digilib-config", "parameter", "name", "value");
+		confTable = lilo.loadURL(f.toURL().toString());
+		dlConfPath = fn;
+
+		/* 
+		 * read parameters
+		 */
+		 
+		// debugLevel
+		debugLevel = tryToGetInitParam(debugLevelParam, debugLevel);
+		// errorImgFileName
+		errorImgFileName = tryToGetInitParam(errorImgParam, errorImgFileName);
+		// denyImgFileName
+		denyImgFileName = tryToGetInitParam(denyImgParam, denyImgFileName);
+		// docuImageType
+		docuImageType = tryToGetInitParam(docuImageTypeParam, docuImageType);
+		// sendFileAllowed
+		sendFileAllowed =
+			tryToGetInitParam(sendFileAllowedParam, sendFileAllowed);
+		// baseDirs
+		String baseDirList =
+			tryToGetInitParam(
+				baseDirParam,
+				"/docuserver/scaled/small:/docuserver/images:/docuserver/scans/quellen");
+		// split list into directories
+		String[] sa = splitPathArray(baseDirList);
+		baseDirs = (sa != null) ? sa : baseDirs;
+		// useAuthentication
+		useAuthentication = tryToGetInitParam(useAuthParam, useAuthentication);
+		if (useAuthentication) {
+			// DB version
+			//authOp = new DBAuthOpsImpl(util);
+			// XML version
+			authConfPath = tryToGetInitParam(authConfParam, authConfPath);
+			authOp = new XMLAuthOps(util, authConfPath);
+		}
+	}
+
+	/**
+	 * convert a string with a list of pathnames into an array of strings
+	 * using the system's path separator string
+	 */
+	public String[] splitPathArray(String paths) {
+		// split list into directories
+		StringTokenizer dirs =
+			new StringTokenizer(paths, java.io.File.pathSeparator);
+		int n = dirs.countTokens();
+		if (n < 1) {
+			return null;
+		}
+		// add directories into array
+		String[] pathArray = new String[n];
+		for (int i = 0; i < n; i++) {
+			pathArray[i] = dirs.nextToken();
+		}
+		return pathArray;
+	}
+
+	/**
+	 *  get an init parameter from config and return it if set, otherwise return default
+	 */
+	public int tryToGetInitParam(String s, int i) {
+		//System.out.println("trytogetInitParam("+s+", "+i+")");
+		try {
+			//System.out.println("trytogetInitParam: "+(String)confTable.get(s));
+			i = Integer.parseInt((String) confTable.get(s));
+		} catch (Exception e) {
+			util.dprintln(4, "trytogetInitParam(int) failed on param " + s);
+			//e.printStackTrace();
+		}
+		return i;
+	}
+	public float tryToGetInitParam(String s, float f) {
+		try {
+			f = Float.parseFloat((String) confTable.get(s));
+		} catch (Exception e) {
+			util.dprintln(4, "trytoGetInitParam(float) failed on param " + s);
+			//e.printStackTrace();
+		}
+		return f;
+	}
+	public String tryToGetInitParam(String s, String x) {
+		if ((confTable != null) && ((String) confTable.get(s) != null)) {
+			x = (String) confTable.get(s);
+		} else {
+			util.dprintln(4, "trytoGetInitParam(string) failed on param " + s);
+		}
+		return x;
+	}
+	public boolean tryToGetInitParam(String s, boolean b) {
+		String bs;
+		boolean bb = b;
+		if ((confTable != null) && ((String) confTable.get(s) != null)) {
+			bs = (String) confTable.get(s);
+
+			if ((bs.indexOf("false") > -1) || (bs.indexOf("FALSE") > -1)) {
+				bb = false;
+			} else if (
+				(bs.indexOf("true") > -1) || (bs.indexOf("TRUE") > -1)) {
+				bb = true;
+			} else {
+				util.dprintln(
+					4,
+					"trytoGetInitParam(string) failed on param " + s);
+			}
+		} else {
+			util.dprintln(4, "trytoGetInitParam(string) failed on param " + s);
+		}
+		return bb;
+	}
+
+	/** Creates a new DocuImage instance.
+	 * 
+	 * The type of DocuImage is specified by docuImageType.
+	 * 
+	 * @return DocuImage
+	 */
+	public DocuImage getDocuImageInstance() {
+		DocuImageImpl di = null;
+		try {
+			di = (DocuImageImpl) Class.forName(docuImageType).newInstance();
+			di.setUtils(util);
+		} catch (Exception e) {
+		}
+		return di;
+	}
+
+	/**
+	 * Returns the authConfPath.
+	 * @return String
+	 */
+	public String getAuthConfPath() {
+		return authConfPath;
+	}
+
+	/**
+	 * Returns the authOp.
+	 * @return AuthOps
+	 */
+	public AuthOps getAuthOp() {
+		return authOp;
+	}
+
+	/**
+	 * Returns the denyImgFileName.
+	 * @return String
+	 */
+	public String getDenyImgFileName() {
+		return denyImgFileName;
+	}
+
+	/**
+	 * Returns the errorImgFileName.
+	 * @return String
+	 */
+	public String getErrorImgFileName() {
+		return errorImgFileName;
+	}
+
+	/**
+	 * Returns the useAuth.
+	 * @return boolean
+	 */
+	public boolean isUseAuthentication() {
+		return useAuthentication;
+	}
+
+	/**
+	 * Sets the authConfPath.
+	 * @param authConfPath The authConfPath to set
+	 */
+	public void setAuthConfPath(String authConfPath) {
+		this.authConfPath = authConfPath;
+	}
+
+	/**
+	 * Sets the authOp.
+	 * @param authOp The authOp to set
+	 */
+	public void setAuthOp(AuthOps authOp) {
+		this.authOp = authOp;
+	}
+
+	/**
+	 * Sets the denyImgFileName.
+	 * @param denyImgFileName The denyImgFileName to set
+	 */
+	public void setDenyImgFileName(String denyImgFileName) {
+		this.denyImgFileName = denyImgFileName;
+	}
+
+	/**
+	 * Sets the errorImgFileName.
+	 * @param errorImgFileName The errorImgFileName to set
+	 */
+	public void setErrorImgFileName(String errorImgFileName) {
+		this.errorImgFileName = errorImgFileName;
+	}
+
+	/**
+	 * Returns the baseDirs.
+	 * @return String[]
+	 */
+	public String[] getBaseDirs() {
+		return baseDirs;
+	}
+
+	/**
+	 * Returns the baseDirs as String.
+	 * @return String
+	 */
+	public String getBaseDirList() {
+		String s = "";
+		java.util.Iterator i = java.util.Arrays.asList(baseDirs).iterator();
+		while (i.hasNext()) {
+			s += ( i.next() + "; ");
+		}
+		return s;
+	}
+
+	/**
+	 * Sets the baseDirs.
+	 * @param baseDirs The baseDirs to set
+	 */
+	public void setBaseDirs(String[] baseDirs) {
+		this.baseDirs = baseDirs;
+	}
+
+	/**
+	 * Returns the debugLevel.
+	 * @return int
+	 */
+	public int getDebugLevel() {
+		return debugLevel;
+	}
+
+	/**
+	 * Sets the debugLevel.
+	 * @param debugLevel The debugLevel to set
+	 */
+	public void setDebugLevel(int debugLevel) {
+		this.debugLevel = debugLevel;
+	}
+
+	/**
+	 * Returns the util.
+	 * @return Utils
+	 */
+	public Utils getUtil() {
+		return util;
+	}
+
+	/**
+	 * Sets the util.
+	 * @param util The util to set
+	 */
+	public void setUtil(Utils util) {
+		this.util = util;
+	}
+
+	/**
+	 * Returns the servletVersion.
+	 * @return String
+	 */
+	public String getServletVersion() {
+		return servletVersion;
+	}
+
+	/**
+	 * Sets the servletVersion.
+	 * @param servletVersion The servletVersion to set
+	 */
+	public void setServletVersion(String servletVersion) {
+		this.servletVersion = servletVersion;
+	}
+
+	/**
+	 * Returns the docuImageType.
+	 * @return String
+	 */
+	public String getDocuImageType() {
+		return docuImageType;
+	}
+
+	/**
+	 * Sets the docuImageType.
+	 * @param docuImageType The docuImageType to set
+	 */
+	public void setDocuImageType(String docuImageType) {
+		this.docuImageType = docuImageType;
+	}
+
+	/**
+	 * Returns the sendFileAllowed.
+	 * @return boolean
+	 */
+	public boolean isSendFileAllowed() {
+		return sendFileAllowed;
+	}
+
+	/**
+	 * Sets the sendFileAllowed.
+	 * @param sendFileAllowed The sendFileAllowed to set
+	 */
+	public void setSendFileAllowed(boolean sendFileAllowed) {
+		this.sendFileAllowed = sendFileAllowed;
+	}
+
+	/**
+	 * Returns the authURLPath.
+	 * @return String
+	 */
+	public String getAuthURLPath() {
+		return authURLPath;
+	}
+
+	/**
+	 * Sets the authURLPath.
+	 * @param authURLPath The authURLPath to set
+	 */
+	public void setAuthURLPath(String authURLPath) {
+		this.authURLPath = authURLPath;
+	}
+
+	/**
+	 * Sets the useAuthentication.
+	 * @param useAuthentication The useAuthentication to set
+	 */
+	public void setUseAuthentication(boolean useAuthentication) {
+		this.useAuthentication = useAuthentication;
+	}
+
+	/**
+	 * Returns the dlConfPath.
+	 * @return String
+	 */
+	public String getDlConfPath() {
+		return dlConfPath;
+	}
+
+}
--- a/servlet/src/digilib/servlet/DigilibRequest.java	Fri Jan 24 21:40:59 2003 +0100
+++ b/servlet/src/digilib/servlet/DigilibRequest.java	Fri Jan 24 21:40:59 2003 +0100
@@ -19,659 +19,807 @@
 
   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
-  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 
  * Created on 27. August 2002, 19:43
  */
 
 package digilib.servlet;
 
-/**
+import java.util.StringTokenizer;
+
+import javax.servlet.ServletRequest;
+import javax.servlet.http.HttpServletRequest;
+
+import digilib.image.DocuImage;
+
+/** Class holding the parameters of a digilib user request.
+ * The parameters are mostly named like the servlet parameters:<br>
+ * request_path: url of the page/document.<br> fn: url of the page/document.
+ * <br> pn: page number.<br> dw: width of result window in pixels.<br> dh:
+ * height of result window in pixels.<br> wx: left edge of image area (float
+ * from 0 to 1).<br> wy: top edge of image area (float from 0 to 1).<br> ww:
+ * width of image area(float from 0 to 1).<br> wh: height of image area(float
+ * from 0 to 1).<br> ws: scale factor.<br> mo: special options like 'fit' for
+ * gifs.<br> mk: list of marks.<br> pt: total number of pages (generated by
+ * sevlet).<br> baseURL: base URL (from http:// to below /servlet).
+ * 
+ * @author casties
  *
- * @author  casties
  */
-
-import java.util.*;
-
 public class DigilibRequest {
 
-    private String request_path;    // url of the page/document
-    private String fn;              // url of the page/document
-    private int pn;                 // page number
-    private String pn_s;
-    private int dw;                 // width of client in pixels
-    private String dw_s;
-    private int dh;                 // height of client in pixels
-    private String dh_s;
-    private float wx;               // left edge of image (float from 0 to 1)
-    private String wx_s;
-    private float wy;               // top edge in image (float from 0 to 1)
-    private String wy_s;
-    private float ww;               // width of image (float from 0 to 1)
-    private String ww_s;
-    private float wh;               // height of image (float from 0 to 1)
-    private String wh_s; 
-    private float ws;               // scale factor
-    private String ws_s;
-    private String mo;              // special options like 'fit' for gifs
-    private String mk;              // marks    
-    private int pt;                 // total number of pages (generated by sevlet)
-    private String pt_s;
-    private String baseURL;         // base URL (from http:// to below /servlet)
-    
-    /** Creates a new instance of DigilibRequest */
-    public DigilibRequest() {
-    }
+	private String request_path; // url of the page/document
+	private String fn; // url of the page/document
+	private int pn; // page number
+	private String pn_s;
+	private int dw; // width of client in pixels
+	private String dw_s;
+	private int dh; // height of client in pixels
+	private String dh_s;
+	private float wx; // left edge of image (float from 0 to 1)
+	private String wx_s;
+	private float wy; // top edge in image (float from 0 to 1)
+	private String wy_s;
+	private float ww; // width of image (float from 0 to 1)
+	private String ww_s;
+	private float wh; // height of image (float from 0 to 1)
+	private String wh_s;
+	private float ws; // scale factor
+	private String ws_s;
+	private String mo; // special options like 'fit' for gifs
+	private String mk; // marks    
+	private int pt; // total number of pages (generated by sevlet)
+	private String pt_s;
+	private String baseURL; // base URL (from http:// to below /servlet)
+	private DocuImage image; // internal DocuImage instance for this request
+	private ServletRequest servletRequest; // internal ServletRequest
 
-    /** Populate a request from a string in the old "++++" parameter form.
-     *
-     * @param queryString String with paramters in the old "+++" form.
-     */    
-    public void setWithOldString(String queryString) {
-        
-        resetRequest(); // clear all first
-        if (queryString == null) {
-            return;
-        }
-        
-	// enable the passing of delimiter to get empty parameters
-	StringTokenizer query = new StringTokenizer(queryString, "+", true);
-        String token;
-
-	if (query.hasMoreTokens()) {
-            token = query.nextToken();
-            if (! token.equals("+")) {
-		fn = token;
-                request_path = null;
-                if (query.hasMoreTokens()) {
-                    query.nextToken();
-                }
-            }
-	}
-	if (query.hasMoreTokens()) {
-            token = query.nextToken();
-            if (! token.equals("+")) {
-                try {
-                    int i = Integer.parseInt(token);
-                    pn = i;
-                    pn_s = token;
-                } catch(Exception e) {
-                //util.dprintln(4, "trytoGetParam(int) failed on param "+s);
-                }
-                if (query.hasMoreTokens()) {
-                    query.nextToken();
-                }
-            }
+	/** Creates a new instance of DigilibRequest and sets default values. */
+	public DigilibRequest() {
+		setToDefault();
 	}
-	if (query.hasMoreTokens()) {
-            token = query.nextToken();
-            if (! token.equals("+")) {
-                try {
-                    float f = Float.parseFloat(token);
-                    ws = f;
-                    ws_s = token;
-                } catch(Exception e) {
-                //util.dprintln(4, "trytoGetParam(int) failed on param "+s);
-                }
-                if (query.hasMoreTokens()) {
-                    query.nextToken();
-                }
-            }
-	}
-	if (query.hasMoreTokens()) {
-            token = query.nextToken();
-            if (! token.equals("+")) {
-                mo = token;
-            }
-	}
-	if (query.hasMoreTokens()) {
-            token = query.nextToken();
-            if (! token.equals("+")) {
-                mk = token;
-                if (query.hasMoreTokens()) {
-                    query.nextToken();
-                }
-            }
+
+	/** Creates a new instance of DigilibRequest with parameters from a
+	 * ServletRequest.
+	 * All undefined parameters are set to default values.
+	 * 
+	 * @param request
+	 */
+	public DigilibRequest(ServletRequest request) {
+		reset();
+		setWithRequest(request);
 	}
-	if (query.hasMoreTokens()) {
-            token = query.nextToken();
-            if (! token.equals("+")) {
-                try {
-                    float f = Float.parseFloat(token);
-                    wx = f;
-                    wx_s = token;
-                } catch(Exception e) {
-                //util.dprintln(4, "trytoGetParam(int) failed on param "+s);
-                }
-                if (query.hasMoreTokens()) {
-                    query.nextToken();
-                }
-            }
-	}
-	if (query.hasMoreTokens()) {
-            token = query.nextToken();
-            if (! token.equals("+")) {
-                try {
-                    float f = Float.parseFloat(token);
-                    wy = f;
-                    wy_s = token;
-                } catch(Exception e) {
-                //util.dprintln(4, "trytoGetParam(int) failed on param "+s);
-                }
-                if (query.hasMoreTokens()) {
-                    query.nextToken();
-                }
-            }
-	}
-	if (query.hasMoreTokens()) {
-            token = query.nextToken();
-            if (! token.equals("+")) {
-                try {
-                    float f = Float.parseFloat(token);
-                    ww = f;
-                    ww_s = token;
-                } catch(Exception e) {
-                //util.dprintln(4, "trytoGetParam(int) failed on param "+s);
-                }
-                if (query.hasMoreTokens()) {
-                    query.nextToken();
-                }
-            }
+
+	public void setWithRequest(ServletRequest request) {
+		servletRequest = request;
+		// decide if it's old-style or new-style
+		String qs = ((HttpServletRequest) request).getQueryString();
+		if (request.getParameter("fn") != null) {
+			setWithParamRequest(request);
+		} else if ((qs != null)&&(qs.indexOf("&") > -1)) {
+			setWithParamRequest(request);
+		} else {
+			setWithOldString(qs);
+		}
+		// set the baseURL
+		setBaseURL((HttpServletRequest) request);
 	}
-	if (query.hasMoreTokens()) {
-            token = query.nextToken();
-            if (! token.equals("+")) {
-                try {
-                    float f = Float.parseFloat(token);
-                    wh = f;
-                    wh_s = token;
-                } catch(Exception e) {
-                //util.dprintln(4, "trytoGetParam(int) failed on param "+s);
-                }
-                if (query.hasMoreTokens()) {
-                    query.nextToken();
-                }
-            }
+
+	/** Populate a request from a string in the old "++++" parameter form.
+	 *
+	 * @param queryString String with paramters in the old "+++" form.
+	 */
+	public void setWithOldString(String queryString) {
+
+		if (queryString == null) {
+			return;
+		}
+
+		// enable the passing of delimiter to get empty parameters
+		StringTokenizer query = new StringTokenizer(queryString, "+", true);
+		String token;
+
+		// first parameter FN
+		if (query.hasMoreTokens()) {
+			token = query.nextToken();
+			if (!token.equals("+")) {
+				fn = token;
+				request_path = null;
+				if (query.hasMoreTokens()) {
+					query.nextToken();
+				}
+			}
+		}
+		// second parameter PN
+		if (query.hasMoreTokens()) {
+			token = query.nextToken();
+			if (!token.equals("+")) {
+				try {
+					int i = Integer.parseInt(token);
+					pn = i;
+					pn_s = token;
+				} catch (Exception e) {
+					//util.dprintln(4, "trytoGetParam(int) failed on param "+s);
+				}
+				if (query.hasMoreTokens()) {
+					query.nextToken();
+				}
+			}
+		}
+		// third parameter WS
+		if (query.hasMoreTokens()) {
+			token = query.nextToken();
+			if (!token.equals("+")) {
+				try {
+					float f = Float.parseFloat(token);
+					ws = f;
+					ws_s = token;
+				} catch (Exception e) {
+					//util.dprintln(4, "trytoGetParam(int) failed on param "+s);
+				}
+				if (query.hasMoreTokens()) {
+					query.nextToken();
+				}
+			}
+		}
+		// fourth parameter MO
+		if (query.hasMoreTokens()) {
+			token = query.nextToken();
+			if (!token.equals("+")) {
+				mo = token;
+				if (query.hasMoreTokens()) {
+					query.nextToken();
+				}
+			}
+		}
+		// fifth parameter MK
+		if (query.hasMoreTokens()) {
+			token = query.nextToken();
+			if (!token.equals("+")) {
+				mk = token;
+				if (query.hasMoreTokens()) {
+					query.nextToken();
+				}
+			}
+		}
+		// sixth parameter WX
+		if (query.hasMoreTokens()) {
+			token = query.nextToken();
+			if (!token.equals("+")) {
+				try {
+					float f = Float.parseFloat(token);
+					wx = f;
+					wx_s = token;
+				} catch (Exception e) {
+					//util.dprintln(4, "trytoGetParam(int) failed on param "+s);
+				}
+				if (query.hasMoreTokens()) {
+					query.nextToken();
+				}
+			}
+		}
+		// seventh parameter WY
+		if (query.hasMoreTokens()) {
+			token = query.nextToken();
+			if (!token.equals("+")) {
+				try {
+					float f = Float.parseFloat(token);
+					wy = f;
+					wy_s = token;
+				} catch (Exception e) {
+					//util.dprintln(4, "trytoGetParam(int) failed on param "+s);
+				}
+				if (query.hasMoreTokens()) {
+					query.nextToken();
+				}
+			}
+		}
+		// eigth parameter WW
+		if (query.hasMoreTokens()) {
+			token = query.nextToken();
+			if (!token.equals("+")) {
+				try {
+					float f = Float.parseFloat(token);
+					ww = f;
+					ww_s = token;
+				} catch (Exception e) {
+					//util.dprintln(4, "trytoGetParam(int) failed on param "+s);
+				}
+				if (query.hasMoreTokens()) {
+					query.nextToken();
+				}
+			}
+		}
+		// ninth parameter WH
+		if (query.hasMoreTokens()) {
+			token = query.nextToken();
+			if (!token.equals("+")) {
+				try {
+					float f = Float.parseFloat(token);
+					wh = f;
+					wh_s = token;
+				} catch (Exception e) {
+					//util.dprintln(4, "trytoGetParam(int) failed on param "+s);
+				}
+				if (query.hasMoreTokens()) {
+					query.nextToken();
+				}
+			}
+		}
 	}
-    }   
-    
-    /** Returns the request parameters as a String in the parameter form
-     * 'fn=/icons&amp;pn=1'. Empty (undefined) fields are not included.
-     *
-     * @return String of request paramters in parameter form.
-     */    
-    public String getAsString() {
-        String s = "";
-        if (request_path != null) {
-            s += request_path + "?";
-        }
-        if (fn != null) {
-            s += "fn=" + fn;
-        }
-        if (pn_s != null) {
-            s += "&pn=" + pn_s;
-        }
-        if (dw_s != null) {
-            s += "&dw=" + dw_s;
-        }
-        if (dh_s != null) {
-            s += "&dh=" + dh_s;
-        }
-        if (wx_s != null) {
-            s += "&wx=" + wx_s;
-        }
-        if (wy_s != null) {
-            s += "&wy=" + wy_s;
-        }
-        if (ww_s != null) {
-            s += "&ww=" + ww_s;
-        }
-        if (wh_s != null) {
-            s += "&wh=" + wh_s;
-        }
-        if (ws_s != null) {
-            s += "&ws=" + ws_s;
-        }
-        if (mo != null) {
-            s += "&mo=" + mo;
-        }
-        if (mk != null) {
-            s += "&mk=" + mk;
-        }
-        if (pt_s != null) {
-            s += "&pt=" + pt_s;
-        }
-        return s;
-    }
-    
-    /** Returns request parameters in old '++++' form.
-     *
-     * @return String with parameters in old '++++' form.
-     */    
-    public String getAsOldString() {
-        String s = "";
-        s += (request_path != null) ? request_path : "";
-        s += (fn != null) ? fn : "";
-        s += "+" + ((pn_s != null) ? pn_s : "");
-        s += "+" + ((ws_s != null) ? ws_s : "");
-        s += "+" + ((mo != null) ? mo : "");
-        s += "+" + ((mk != null) ? mk : "");
-        s += "+" + ((wx_s != null) ? wx_s : "");
-        s += "+" + ((wy_s != null) ? wy_s : "");
-        s += "+" + ((ww_s != null) ? ww_s : "");
-        s += "+" + ((wh_s != null) ? wh_s : "");
-        return s;
-    }
-    
-    /** Set request parameters from javax.servlet.ServletRequest. Uses the Requests
-     * getParameter methods for 'fn=foo' style parameters.
-     *
-     * @param request ServletRequest to get parameters from.
-     */    
-    public void setWithRequest(javax.servlet.ServletRequest request) {
-        String s;
-        s = request.getParameter("fn");
-        if (s != null) {
-            setFn(s);
-        }
-        s = request.getParameter("pn");
-        if (s != null) {
-            setPn(s);
-        }
-        s = request.getParameter("ws");
-        if (s != null) {
-            setWs(s);
-        }
-        s = request.getParameter("mo");
-        if (s != null) {
-            setMo(s);
-        }
-        s = request.getParameter("mk");
-        if (s != null) {
-            setMk(s);
-        }
-        s = request.getParameter("wx");
-        if (s != null) {
-            setWx(s);
-        }
-        s = request.getParameter("wy");
-        if (s != null) {
-            setWy(s);
-        }
-        s = request.getParameter("ww");
-        if (s != null) {
-            setWw(s);
-        }
-        s = request.getParameter("wh");
-        if (s != null) {
-            setWh(s);
-        }
-        s = request.getParameter("dw");
-        if (s != null) {
-            setDw(s);
-        }
-        s = request.getParameter("dh");
-        if (s != null) {
-            setDh(s);
-        }
-        s = request.getParameter("pt");
-        if (s != null) {
-            setPt(s);
-        }
-        setBaseURL((javax.servlet.http.HttpServletRequest)request);
-    }
+
+	/** Return the request parameters as a String in the parameter form
+	 * 'fn=/icons&amp;pn=1'. Empty (undefined) fields are not included.
+	 *
+	 * @return String of request parameters in parameter form.
+	 */
+	public String getAsString() {
+		String s = "";
+		// request_path adds to fn 
+		if ((fn != null) || (request_path != null)) {
+			s += "fn="
+				+ ((request_path != null) ? request_path : "")
+				+ ((fn != null) ? fn : "");
+		}
+		if (pn_s != null) {
+			s += "&pn=" + pn_s;
+		}
+		if (dw_s != null) {
+			s += "&dw=" + dw_s;
+		}
+		if (dh_s != null) {
+			s += "&dh=" + dh_s;
+		}
+		if (wx_s != null) {
+			s += "&wx=" + wx_s;
+		}
+		if (wy_s != null) {
+			s += "&wy=" + wy_s;
+		}
+		if (ww_s != null) {
+			s += "&ww=" + ww_s;
+		}
+		if (wh_s != null) {
+			s += "&wh=" + wh_s;
+		}
+		if (ws_s != null) {
+			s += "&ws=" + ws_s;
+		}
+		if (mo != null) {
+			s += "&mo=" + mo;
+		}
+		if (mk != null) {
+			s += "&mk=" + mk;
+		}
+		if (pt_s != null) {
+			s += "&pt=" + pt_s;
+		}
+		return s;
+	}
+
+	/** Returns request parameters in old '++++' form.
+	 *
+	 * @return String with parameters in old '++++' form.
+	 */
+	public String getAsOldString() {
+		String s = "";
+		s += (request_path != null) ? request_path : "";
+		s += (fn != null) ? fn : "";
+		s += "+" + ((pn_s != null) ? pn_s : "");
+		s += "+" + ((ws_s != null) ? ws_s : "");
+		s += "+" + ((mo != null) ? mo : "");
+		s += "+" + ((mk != null) ? mk : "");
+		s += "+" + ((wx_s != null) ? wx_s : "");
+		s += "+" + ((wy_s != null) ? wy_s : "");
+		s += "+" + ((ww_s != null) ? ww_s : "");
+		s += "+" + ((wh_s != null) ? wh_s : "");
+		return s;
+	}
+
+	/** Set request parameters from javax.servlet.ServletRequest. Uses the Requests
+	 * getParameter methods for 'fn=foo' style parameters.
+	 *
+	 * @param request ServletRequest to get parameters from.
+	 */
+	public void setWithParamRequest(ServletRequest request) {
+		String s;
+		s = request.getParameter("fn");
+		if (s != null) {
+			setFn(s);
+		}
+		s = request.getParameter("pn");
+		if (s != null) {
+			setPn(s);
+		}
+		s = request.getParameter("ws");
+		if (s != null) {
+			setWs(s);
+		}
+		s = request.getParameter("mo");
+		if (s != null) {
+			setMo(s);
+		}
+		s = request.getParameter("mk");
+		if (s != null) {
+			setMk(s);
+		}
+		s = request.getParameter("wx");
+		if (s != null) {
+			setWx(s);
+		}
+		s = request.getParameter("wy");
+		if (s != null) {
+			setWy(s);
+		}
+		s = request.getParameter("ww");
+		if (s != null) {
+			setWw(s);
+		}
+		s = request.getParameter("wh");
+		if (s != null) {
+			setWh(s);
+		}
+		s = request.getParameter("dw");
+		if (s != null) {
+			setDw(s);
+		}
+		s = request.getParameter("dh");
+		if (s != null) {
+			setDh(s);
+		}
+		s = request.getParameter("pt");
+		if (s != null) {
+			setPt(s);
+		}
+		s = ((HttpServletRequest) request).getPathInfo();
+		if (s != null) {
+			setRequestPath(s);
+		}
+	}
+
+	/** Reset all request parameters to null. */
+	public void reset() {
+		request_path = null; // url of the page/document
+		fn = null; // url of the page/document
+		pn = 0; // page number
+		pn_s = null;
+		dw = 0; // width of client in pixels
+		dw_s = null;
+		dh = 0; // height of client in pixels
+		dh_s = null;
+		wx = 0f; // left edge of image (float from 0 to 1)
+		wx_s = null;
+		wy = 0f; // top edge in image (float from 0 to 1)
+		wy_s = null;
+		ww = 0f; // width of image (float from 0 to 1)
+		ww_s = null;
+		wh = 0f; // height of image (float from 0 to 1)
+		wh_s = null;
+		ws = 0f; // scale factor
+		ws_s = null;
+		mo = null; // special options like 'fit' for gifs
+		mk = null; // marks
+		pt = 0; // total number of pages
+		pt_s = null;
+		baseURL = null;
+		image = null;
+		servletRequest = null;
+	}
+
+	/** Reset all request parameters to default values. */
+	public void setToDefault() {
+		request_path = ""; // url of the page/document
+		fn = ""; // url of the page/document
+		pn = 1; // page number
+		pn_s = "1";
+		dw = 500; // width of client in pixels
+		dw_s = "500";
+		dh = 500; // height of client in pixels
+		dh_s = "500";
+		wx = 0f; // left edge of image (float from 0 to 1)
+		wx_s = "0";
+		wy = 0f; // top edge in image (float from 0 to 1)
+		wy_s = "0";
+		ww = 1f; // width of image (float from 0 to 1)
+		ww_s = "1";
+		wh = 1f; // height of image (float from 0 to 1)
+		wh_s = "1";
+		ws = 1f; // scale factor
+		ws_s = "1";
+		mo = ""; // special options like 'fit' for gifs
+		mk = ""; // marks
+		pt = 0; // total number of pages
+		pt_s = null;
+		baseURL = null;
+		image = null;
+		servletRequest = null;
+	}
 
-    
-    /** Reset all request parameters to null. */    
-    public void resetRequest() {
-        request_path = null;    // url of the page/document
-        fn = null;              // url of the page/document
-        pn = 0;                 // page number
-        pn_s = null;
-        dw = 0;                 // width of client in pixels
-        dw_s = null;
-        dh = 0;                 // height of client in pixels
-        dh_s = null;
-        wx = 0f;               // left edge of image (float from 0 to 1)
-        wx_s = null;
-        wy = 0f;               // top edge in image (float from 0 to 1)
-        wy_s = null;
-        ww = 0f;               // width of image (float from 0 to 1)
-        ww_s = null;
-        wh = 0f;               // height of image (float from 0 to 1)
-        wh_s = null;
-        ws = 0f;               // scale factor
-        ws_s = null;
-        mo = null;              // special options like 'fit' for gifs
-        mk = null;              // marks
-        pt = 0;                 // total number of pages
-        pt_s = null;
-        baseURL = null;
-    }
-    
-    /* Default getter and setter */
-    
-    /** Getter for property dh.
-     * @return Value of property dh.
-     *
-     */
-    public int getDh() {
-        return dh;
-    }
-    
-    /** Setter for property dh.
-     * @param dh New value of property dh.
-     *
-     */
-    public void setDh(int dh) {
-        this.dh = dh;
-        dh_s = Integer.toString(dh);
-    }
-    public void setDh(String dh) {
-        try {
-            int i = Integer.parseInt(dh);
-            this.dh = i;
-            this.dh_s = dh;
-        } catch(Exception e) {
-            //util.dprintln(4, "trytoGetParam(int) failed on param "+s);
-        }
-    }
-    
-    /** Getter for property dw.
-     * @return Value of property dw.
-     *
-     */
-    public int getDw() {
-        return dw;
-    }
-    
-    /** Setter for property dw.
-     * @param dw New value of property dw.
-     *
-     */
-    public void setDw(int dw) {
-        this.dw = dw;
-        dw_s = Integer.toString(dw);
-    }
-    public void setDw(String dw) {
-        try {
-            int i = Integer.parseInt(dw);
-            this.dw = i;
-            this.dw_s = dw;
-        } catch(Exception e) {
-            //util.dprintln(4, "trytoGetParam(int) failed on param "+s);
-        }
-    }
-    
-    /** Getter for property fn.
-     * @return Value of property fn.
-     *
-     */
-    public java.lang.String getFn() {
-        return fn;
-    }
-    
-    /** Setter for property fn.
-     * @param fn New value of property fn.
-     *
-     */
-    public void setFn(java.lang.String fn) {
-        this.fn = fn;
-    }
-    
-    /** Getter for property mo.
-     * @return Value of property mo.
-     *
-     */
-    public java.lang.String getMo() {
-        return mo;
-    }
-    
-    /** Setter for property mo.
-     * @param mo New value of property mo.
-     *
-     */
-    public void setMo(java.lang.String mo) {
-        this.mo = mo;
-    }
-    
-    /** Getter for property pn.
-     * @return Value of property pn.
-     *
-     */
-    public int getPn() {
-        return pn;
-    }
-    
-    /** Setter for property pn.
-     * @param pn New value of property pn.
-     *
-     */
-    public void setPn(int pn) {
-        this.pn = pn;
-        pn_s = Integer.toString(pn);
-    }
-    public void setPn(String pn) {
-        try {
-            int i = Integer.parseInt(pn);
-            this.pn = i;
-            this.pn_s = pn;
-        } catch(Exception e) {
-            //util.dprintln(4, "trytoGetParam(int) failed on param "+s);
-        }
-    }
-    
-    /** Getter for property request_path.
-     * @return Value of property request_path.
-     *
-     */
-    public java.lang.String getRequest_path() {
-        return request_path;
-    }
-    
-    /** Setter for property request_path.
-     * @param request_path New value of property request_path.
-     *
-     */
-    public void setRequest_path(java.lang.String request_path) {
-        this.request_path = request_path;
-    }
-    
-    /** Getter for property wh.
-     * @return Value of property wh.
-     *
-     */
-    public float getWh() {
-        return wh;
-    }
-    
-    /** Setter for property wh.
-     * @param wh New value of property wh.
-     *
-     */
-    public void setWh(float wh) {
-        this.wh = wh;
-        wh_s = Float.toString(wh);
-    }
-    public void setWh(String wh) {
-        try {
-            float f = Float.parseFloat(wh);
-            this.wh = f;
-            this.wh_s = wh;
-        } catch(Exception e) {
-            //util.dprintln(4, "trytoGetParam(int) failed on param "+s);
-        }
-    }
-    
-    /** Getter for property ws.
-     * @return Value of property ws.
-     *
-     */
-    public float getWs() {
-        return ws;
-    }
-    
-    /** Setter for property ws.
-     * @param ws New value of property ws.
-     *
-     */
-    public void setWs(float ws) {
-        this.ws = ws;
-        ws_s = Float.toString(ws);
-    }
-    public void setWs(String ws) {
-        try {
-            float f = Float.parseFloat(ws);
-            this.ws = f;
-            this.ws_s = ws;
-        } catch(Exception e) {
-            //util.dprintln(4, "trytoGetParam(int) failed on param "+s);
-        }
-    }
-    
-    /** Getter for property ww.
-     * @return Value of property ww.
-     *
-     */
-    public float getWw() {
-        return ww;
-    }
-    
-    /** Setter for property ww.
-     * @param ww New value of property ww.
-     *
-     */
-    public void setWw(float ww) {
-        this.ww = ww;
-        ww_s = Float.toString(ww);
-    }
-    public void setWw(String ww) {
-        try {
-            float f = Float.parseFloat(ww);
-            this.ww = f;
-            this.ww_s = ww;
-        } catch(Exception e) {
-            //util.dprintln(4, "trytoGetParam(int) failed on param "+s);
-        }
-    }
-    
-    /** Getter for property wx.
-     * @return Value of property wx.
-     *
-     */
-    public float getWx() {
-        return wx;
-    }
-    
-    /** Setter for property wx.
-     * @param wx New value of property wx.
-     *
-     */
-    public void setWx(float wx) {
-        this.wx = wx;
-        wx_s = Float.toString(wx);
-    }
-    public void setWx(String wx) {
-        try {
-            float f = Float.parseFloat(wx);
-            this.wx = f;
-            this.wx_s = wx;
-        } catch(Exception e) {
-            //util.dprintln(4, "trytoGetParam(int) failed on param "+s);
-        }
-    }
-    
-    /** Getter for property wy.
-     * @return Value of property wy.
-     *
-     */
-    public float getWy() {
-        return wy;
-    }
-    
-    /** Setter for property wy.
-     * @param wy New value of property wy.
-     *
-     */
-    public void setWy(float wy) {
-        this.wy = wy;
-        wy_s = Float.toString(wy);
-    }
-    public void setWy(String wy) {
-        try {
-            float f = Float.parseFloat(wy);
-            this.wy = f;
-            this.wy_s = wy;
-        } catch(Exception e) {
-            //util.dprintln(4, "trytoGetParam(int) failed on param "+s);
-        }
-    }
-    
-    /** Getter for property mk.
-     * @return Value of property mk.
-     *
-     */
-    public java.lang.String getMk() {
-        return mk;
-    }
-    
-    /** Setter for property mk.
-     * @param mk New value of property mk.
-     *
-     */
-    public void setMk(java.lang.String mk) {
-        this.mk = mk;
-    }
-    
-    /** Getter for property pt.
-     * @return Value of property pt.
-     *
-     */
-    public int getPt() {
-        return pt;
-    }
-    
-    /** Setter for property pt.
-     * @param pt New value of property pt.
-     *
-     */
-    public void setPt(int pt) {
-        this.pt = pt;
-        pt_s = Integer.toString(pt);
-    }
-    public void setPt(String pt) {
-        try {
-            int i = Integer.parseInt(pt);
-            this.pt = i;
-            this.pt_s = pt;
-        } catch(Exception e) {
-            //util.dprintln(4, "trytoGetParam(int) failed on param "+s);
-        }
-    }
-    
-    /** Returns the base URL (from http:// up to the base directory without file name or
-     * /servlet). Base URL has to be set from a request via setBaseURL or
-     * setWithRequest.
-     * @return String with the base URL.
-     */    
-    public String getBaseURL() {
-        return baseURL;
-    }
-    
-    /** Set the requests base URL parameter from a javax.sevlet.http.HttpServletRequest.
-     * @param request HttpServletRequest to set the base URL.
-     */    
-    public void setBaseURL(javax.servlet.http.HttpServletRequest request) {
-        // calculate base URL string from request (minus last part)
-        String s = request.getRequestURL().toString();
-        int eop = s.lastIndexOf("/");
-        if (eop > 0) {
-            baseURL = s.substring(0, eop);
-        } else {
-            // fall back
-            baseURL = "http://" + request.getServerName() + "/docuserver/digitallibrary";
-        }
-    }
+	/** Test if option string <code>opt</code> is set.
+	 * Checks if the substring <code>opt</code> is contained in the options
+	 * string <code>mo</code>.
+	 * 
+	 * @param opt Option string to be tested.
+	 * @return boolean
+	 */
+	public boolean isOption(String opt) {
+		if ((mo != null) && (mo.indexOf(opt) >= 0)) {
+			return true;
+		}
+		return false;
+	}
+
+	/** The image file path to be accessed.
+	 * 
+	 * The mage file path is assembled from the servlets RequestPath and
+	 * Parameter fn.
+	 * 
+	 * @return String the effektive filepath.
+	 */
+	public String getFilePath() {
+		String s = getRequestPath();
+		s += getFn();
+		return s;
+	}
+
+	/* Property getter and setter */
+
+	/** Getter for property dh.
+	 * @return Value of property dh.
+	 *
+	 */
+	public int getDh() {
+		return dh;
+	}
+
+	/** Setter for property dh.
+	 * @param dh New value of property dh.
+	 *
+	 */
+	public void setDh(int dh) {
+		this.dh = dh;
+		dh_s = Integer.toString(dh);
+	}
+	public void setDh(String dh) {
+		try {
+			int i = Integer.parseInt(dh);
+			this.dh = i;
+			this.dh_s = dh;
+		} catch (Exception e) {
+			//util.dprintln(4, "trytoGetParam(int) failed on param "+s);
+		}
+	}
+
+	/** Getter for property dw.
+	 * @return Value of property dw.
+	 *
+	 */
+	public int getDw() {
+		return dw;
+	}
+
+	/** Setter for property dw.
+	 * @param dw New value of property dw.
+	 *
+	 */
+	public void setDw(int dw) {
+		this.dw = dw;
+		dw_s = Integer.toString(dw);
+	}
+	public void setDw(String dw) {
+		try {
+			int i = Integer.parseInt(dw);
+			this.dw = i;
+			this.dw_s = dw;
+		} catch (Exception e) {
+			//util.dprintln(4, "trytoGetParam(int) failed on param "+s);
+		}
+	}
+
+	/** Getter for property fn.
+	 * @return Value of property fn.
+	 *
+	 */
+	public String getFn() {
+		return (fn != null) ? fn : "";
+	}
+
+	/** Setter for property fn.
+	 * @param fn New value of property fn.
+	 *
+	 */
+	public void setFn(String fn) {
+		this.fn = fn;
+	}
+
+	/** Getter for property mo.
+	 * @return Value of property mo.
+	 *
+	 */
+	public String getMo() {
+		return (mo != null) ? mo : "";
+	}
+
+	/** Setter for property mo.
+	 * @param mo New value of property mo.
+	 *
+	 */
+	public void setMo(String mo) {
+		this.mo = mo;
+	}
+
+	/** Getter for property pn.
+	 * @return Value of property pn.
+	 *
+	 */
+	public int getPn() {
+		return pn;
+	}
+
+	/** Setter for property pn.
+	 * @param pn New value of property pn.
+	 *
+	 */
+	public void setPn(int pn) {
+		this.pn = pn;
+		pn_s = Integer.toString(pn);
+	}
+	public void setPn(String pn) {
+		try {
+			int i = Integer.parseInt(pn);
+			this.pn = i;
+			this.pn_s = pn;
+		} catch (Exception e) {
+			//util.dprintln(4, "trytoGetParam(int) failed on param "+s);
+		}
+	}
+
+	/** Getter for property request_path.
+	 * @return Value of property request_path.
+	 *
+	 */
+	public String getRequestPath() {
+		return (request_path != null) ? request_path : "";
+	}
+
+	/** Setter for property request_path.
+	 * @param request_path New value of property request_path.
+	 *
+	 */
+	public void setRequestPath(String request_path) {
+		this.request_path = request_path;
+	}
+
+	/** Getter for property wh.
+	 * @return Value of property wh.
+	 *
+	 */
+	public float getWh() {
+		return wh;
+	}
+
+	/** Setter for property wh.
+	 * @param wh New value of property wh.
+	 *
+	 */
+	public void setWh(float wh) {
+		this.wh = wh;
+		wh_s = Float.toString(wh);
+	}
+	public void setWh(String wh) {
+		try {
+			float f = Float.parseFloat(wh);
+			this.wh = f;
+			this.wh_s = wh;
+		} catch (Exception e) {
+			//util.dprintln(4, "trytoGetParam(int) failed on param "+s);
+		}
+	}
+
+	/** Getter for property ws.
+	 * @return Value of property ws.
+	 *
+	 */
+	public float getWs() {
+		return ws;
+	}
 
-    
+	/** Setter for property ws.
+	 * @param ws New value of property ws.
+	 *
+	 */
+	public void setWs(float ws) {
+		this.ws = ws;
+		ws_s = Float.toString(ws);
+	}
+	public void setWs(String ws) {
+		try {
+			float f = Float.parseFloat(ws);
+			this.ws = f;
+			this.ws_s = ws;
+		} catch (Exception e) {
+			//util.dprintln(4, "trytoGetParam(int) failed on param "+s);
+		}
+	}
+
+	/** Getter for property ww.
+	 * @return Value of property ww.
+	 *
+	 */
+	public float getWw() {
+		return ww;
+	}
+
+	/** Setter for property ww.
+	 * @param ww New value of property ww.
+	 *
+	 */
+	public void setWw(float ww) {
+		this.ww = ww;
+		ww_s = Float.toString(ww);
+	}
+	public void setWw(String ww) {
+		try {
+			float f = Float.parseFloat(ww);
+			this.ww = f;
+			this.ww_s = ww;
+		} catch (Exception e) {
+			//util.dprintln(4, "trytoGetParam(int) failed on param "+s);
+		}
+	}
+
+	/** Getter for property wx.
+	 * @return Value of property wx.
+	 *
+	 */
+	public float getWx() {
+		return wx;
+	}
+
+	/** Setter for property wx.
+	 * @param wx New value of property wx.
+	 *
+	 */
+	public void setWx(float wx) {
+		this.wx = wx;
+		wx_s = Float.toString(wx);
+	}
+	public void setWx(String wx) {
+		try {
+			float f = Float.parseFloat(wx);
+			this.wx = f;
+			this.wx_s = wx;
+		} catch (Exception e) {
+			//util.dprintln(4, "trytoGetParam(int) failed on param "+s);
+		}
+	}
+
+	/** Getter for property wy.
+	 * @return Value of property wy.
+	 *
+	 */
+	public float getWy() {
+		return wy;
+	}
+
+	/** Setter for property wy.
+	 * @param wy New value of property wy.
+	 *
+	 */
+	public void setWy(float wy) {
+		this.wy = wy;
+		wy_s = Float.toString(wy);
+	}
+	public void setWy(String wy) {
+		try {
+			float f = Float.parseFloat(wy);
+			this.wy = f;
+			this.wy_s = wy;
+		} catch (Exception e) {
+			//util.dprintln(4, "trytoGetParam(int) failed on param "+s);
+		}
+	}
+
+	/** Getter for property mk.
+	 * @return Value of property mk.
+	 *
+	 */
+	public String getMk() {
+		return (mk != null) ? mk : "";
+	}
+
+	/** Setter for property mk.
+	 * @param mk New value of property mk.
+	 *
+	 */
+	public void setMk(String mk) {
+		this.mk = mk;
+	}
+
+	/** Getter for property pt.
+	 * @return Value of property pt.
+	 *
+	 */
+	public int getPt() {
+		return pt;
+	}
+
+	/** Setter for property pt.
+	 * @param pt New value of property pt.
+	 *
+	 */
+	public void setPt(int pt) {
+		this.pt = pt;
+		pt_s = Integer.toString(pt);
+	}
+	public void setPt(String pt) {
+		try {
+			int i = Integer.parseInt(pt);
+			this.pt = i;
+			this.pt_s = pt;
+		} catch (Exception e) {
+			//util.dprintln(4, "trytoGetParam(int) failed on param "+s);
+		}
+	}
+
+	/** Returns the base URL (from http:// up to the base directory without file name or
+	 * /servlet). Base URL has to be set from a request via setBaseURL or
+	 * setWithRequest.
+	 * @return String with the base URL.
+	 */
+	public String getBaseURL() {
+		return (baseURL != null) ? baseURL : "";
+	}
+
+	/** Set the requests base URL parameter from a javax.sevlet.http.HttpServletRequest.
+	 * @param request HttpServletRequest to set the base URL.
+	 */
+	public void setBaseURL(javax.servlet.http.HttpServletRequest request) {
+		// calculate base URL string from request (minus last part)
+		String s = request.getRequestURL().toString();
+		int eop = s.lastIndexOf("/");
+		if (eop > 0) {
+			baseURL = s.substring(0, eop);
+		} else {
+			// fall back
+			baseURL =
+				"http://"
+					+ request.getServerName()
+					+ "/docuserver/digitallibrary";
+		}
+	}
+
+	/**
+	 * Returns the image.
+	 * @return DocuImage
+	 */
+	public DocuImage getImage() {
+		return image;
+	}
+
+	/**
+	 * Sets the image.
+	 * @param image The image to set
+	 */
+	public void setImage(DocuImage image) {
+		this.image = image;
+	}
+
+	/**
+	 * Returns the servletRequest.
+	 * @return ServletRequest
+	 */
+	public ServletRequest getServletRequest() {
+		return servletRequest;
+	}
+
+	/**
+	 * Sets the servletRequest.
+	 * @param servletRequest The servletRequest to set
+	 */
+	public void setServletRequest(ServletRequest servletRequest) {
+		this.servletRequest = servletRequest;
+	}
+
 }
--- a/servlet/src/digilib/servlet/DocumentBean.java	Fri Jan 24 21:40:59 2003 +0100
+++ b/servlet/src/digilib/servlet/DocumentBean.java	Fri Jan 24 21:40:59 2003 +0100
@@ -2,7 +2,7 @@
 
   Digital Image Library servlet components
 
-  Copyright (C) 2001, 2002 Robert Casties (robcast@mail.berlios.de)
+  Copyright (C) 2001, 2002, 2003 Robert Casties (robcast@mail.berlios.de)
 
   This program is free software; you can redistribute  it and/or modify it
   under  the terms of  the GNU General  Public License as published by the
@@ -20,7 +20,6 @@
 
 package digilib.servlet;
 
-
 import java.util.*;
 import javax.servlet.*;
 import javax.servlet.http.*;
@@ -29,170 +28,154 @@
 import digilib.io.*;
 import digilib.auth.*;
 
-public class DocumentBean implements AuthOps {
+public class DocumentBean {
+
+	// Utils object for logging
+	private Utils util = new Utils(0);
+	// AuthOps object to check authorization
+	private AuthOps authOp;
+	// FileOps object
+	private FileOps fileOp = new FileOps(util);
+	// use authorization database
+	private boolean useAuthentication = true;
+
+	// DigilibConfiguration object
+	private DigilibConfiguration dlConfig;
 
-  // Utils object for logging
-  private Utils util = new Utils(5);
-  // AuthOps object to check authorization
-  private AuthOps authOp;
-  // FileOps object
-  private FileOps fileOp = new FileOps(util);
-  // use authorization database
-  boolean useAuthentication = true;
+	/**
+	 * Constructor for DocumentBean.
+	 */
+	public DocumentBean() {
+		super();
+	}
 
-  // base directories in order of preference (prescaled versions first)
-  private String[] baseDirs = {"/docuserver/scaled/small", "/docuserver/images", "/docuserver/scans/quellen"};
-  // part of URL path to prepend for authenticated access
-  private String authURLpath = "authenticated/";
-
-
-  public DocumentBean() {
-  }
+	public DocumentBean(ServletConfig conf) {
+		try {
+			setConfig(conf);
+		} catch (Exception e) {
+			util.dprintln(2, "ERROR: Unable to read config: " + e.toString());
+		}
+	}
 
-  public void setConfig(ServletConfig conf) throws ServletException {
-    util.dprintln(10, "setConfig");
-    // servletOps takes a ServletConfig to get the config file name
-    ServletOps servletOp = new ServletOps(util, conf);
-    // get debug-level first
-    int dbg = servletOp.tryToGetInitParam("debug-level", 10);
-    util.setDebugLevel(dbg);
-    // basedir-list : List of document directories
-    String bl = servletOp.tryToGetInitParam("basedir-list", null);
-    // split list into directories
-    baseDirs = servletOp.tryToGetPathArray(bl, baseDirs);
-    util.dprintln(3, "basedir-list: "+bl);
-    
-    /*
-     *  auth-url-path : part of URL to indicate authenticated access
-     */
-    String au = servletOp.tryToGetInitParam("auth-url-path", null);
-    if ((au != null)&&(au.length() > 0)) {
-      authURLpath = au;
-      util.dprintln(3, "auth-url-path: "+au);
-    }
-    /*
-     *  authentication
-     */
-    String useAuth = servletOp.tryToGetInitParam("use-authorization", "true");
-    if ((useAuth.indexOf("false") > -1)||(useAuth.indexOf("FALSE") > -1)) {
-      useAuthentication = false;
-    } else {
-      useAuthentication = true;
-      try {
-          // DB version
-          //private AuthOps authOp = new DBAuthOpsImpl(util);
-          // XML version
-          String cp = servletOp.tryToGetInitParam("auth-file", "/docuserver/www/digitallibrary/WEB-INF/digilib-auth.xml");
-          util.dprintln(3, "auth-file: "+cp);
-          authOp = new XMLAuthOps(util, cp);
-        } catch (AuthOpException e) {
-          throw new ServletException(e);
-        }
-    }
-  }
+	public void setConfig(ServletConfig conf) throws ServletException {
+		util.dprintln(10, "setConfig");
+		// get our ServletContext
+		ServletContext context = conf.getServletContext();
+		// see if there is a Configuration instance
+		dlConfig =
+			(DigilibConfiguration) context.getAttribute(
+				"digilib.servlet.configuration");
+		if (dlConfig == null) {
+			// create new Configuration
+			try {
+				dlConfig = new DigilibConfiguration(conf);
+				context.setAttribute("digilib.servlet.configuration", dlConfig);
+			} catch (Exception e) {
+				throw new ServletException(e);
+			}
+		}
+
+		// get util
+		util = dlConfig.getUtil();
 
-  public String getDocuPath(HttpServletRequest request) {
-    util.dprintln(10, "getDocuPath");
-    // fetch query string
-    String qs = request.getQueryString();
-    String fn = "";
-    if (qs != null && qs.length() > 0) {
-       // the file name is in the request before the first "+"
-       int endfn = qs.indexOf("+");
-       if (endfn > 0) {
-         fn = qs.substring(0, endfn);
-       } else {
-	 fn = qs;
-       }
-    }
-    util.dprintln(4, "docuPath: "+fn);
-    return fn;
-  }
+		/*
+		 *  authentication
+		 */
+		useAuthentication = dlConfig.isUseAuthentication();
+		authOp = dlConfig.getAuthOp();
+	}
+
+	/**
+	 *  check if the request must be authorized to access filepath
+	 */
+	public boolean isAuthRequired(DigilibRequest request)
+		throws AuthOpException {
+		util.dprintln(10, "isAuthRequired");
+		return useAuthentication ? authOp.isAuthRequired(request) : false;
+	}
+
+	/**
+	 *  check if the request is allowed to access filepath
+	 */
+	public boolean isAuthorized(DigilibRequest request)
+		throws AuthOpException {
+		util.dprintln(10, "isAuthorized");
+		return useAuthentication ? authOp.isAuthorized(request) : true;
+	}
 
-  /**
-   *  check if the request must be authorized to access filepath
-   */
-  public boolean isAuthRequired(HttpServletRequest request) throws AuthOpException {
-    util.dprintln(10, "isAuthRequired");
-    return useAuthentication ? authOp.isAuthRequired(getDocuPath(request), request) : false;
-  }
-
-  public boolean isAuthRequired(String filepath, HttpServletRequest request) throws AuthOpException {
-    util.dprintln(10, "isAuthRequired");
-    return useAuthentication ? authOp.isAuthRequired(filepath, request) : false;
-  }
-
-  /**
-   *  check if the request is allowed to access filepath
-   */
-  public boolean isAuthorized(HttpServletRequest request) throws AuthOpException {
-    util.dprintln(10, "isAuthorized");
-    return useAuthentication ? authOp.isAuthorized(getDocuPath(request), request) : true;
-  }
+	/**
+	 *  return a list of authorization roles needed for request
+	 *  to access the specified path
+	 */
+	public List rolesForPath(DigilibRequest request) throws AuthOpException {
+		util.dprintln(10, "rolesForPath");
+		return useAuthentication ? authOp.rolesForPath(request) : null;
+	}
 
-  public boolean isAuthorized(String filepath, HttpServletRequest request) throws AuthOpException {
-    util.dprintln(10, "isAuthorized");
-    return useAuthentication ? authOp.isAuthorized(filepath, request) : true;
-  }
-
-  /**
-   *  return a list of authorization roles needed for request
-   *  to access the specified path
-   */
-  public List rolesForPath(String filepath, HttpServletRequest request) throws AuthOpException {
-    util.dprintln(10, "rolesForPath");
-    return useAuthentication ? authOp.rolesForPath(filepath, request) : null;
-  }
-
-  /**
-   * check request authorization against a list of roles
-   */
-  public boolean isRoleAuthorized(List roles, HttpServletRequest request) {
-    util.dprintln(10, "isRoleAuthorized");
-    return useAuthentication ? authOp.isRoleAuthorized(roles, request) : true;
-  }
+	/**
+	 * check request authorization against a list of roles
+	 */
+	public boolean isRoleAuthorized(List roles, DigilibRequest request) {
+		util.dprintln(10, "isRoleAuthorized");
+		return useAuthentication
+			? authOp.isRoleAuthorized(roles, request)
+			: true;
+	}
 
-  /**
-   * check for authenticated access and redirect if necessary
-   */
-  public boolean doAuthentication(HttpServletRequest request, HttpServletResponse response) throws Exception {
-    util.dprintln(10, "doAuthentication");
-    // check if we are already authenticated
-    if (request.getRemoteUser() == null) {
-      util.dprintln(3, "unauthenticated so far");
-      // if not maybe we must?
-      if (isAuthRequired(request)) {
-        util.dprintln(3, "auth required, redirect");
-	// we are not yet authenticated -> redirect
-	response.sendRedirect(authURLpath+request.getServletPath()+"?"+request.getQueryString());
-      }
-    }
-    return true;
-  }
+	/**
+	 * check for authenticated access and redirect if necessary
+	 */
+	public boolean doAuthentication(
+		DigilibRequest request,
+		HttpServletResponse response)
+		throws Exception {
+		util.dprintln(10, "doAuthentication");
+		// check if we are already authenticated
+		if (((HttpServletRequest) request.getServletRequest()).getRemoteUser()
+			== null) {
+			util.dprintln(3, "unauthenticated so far");
+			// if not maybe we must?
+			if (isAuthRequired(request)) {
+				util.dprintln(3, "auth required, redirect");
+				// we are not yet authenticated -> redirect
+				response.sendRedirect(
+					dlConfig.getAuthURLPath()
+						+ ((HttpServletRequest) request.getServletRequest())
+							.getServletPath()
+						+ "?"
+						+ ((HttpServletRequest) request.getServletRequest())
+							.getQueryString());
+			}
+		}
+		return true;
+	}
 
-  /**
-   *  get the first page number in the directory
-   *  (not yet functional)
-   */
-  public int getFirstPage(HttpServletRequest request) {
-    return getFirstPage(getDocuPath(request), request);
-  }
+	/**
+	 *  get the first page number in the directory
+	 *  (not yet functional)
+	 */
+	public int getFirstPage(DigilibRequest request) {
+		util.dprintln(10, "getFirstPage");
+		return 1;
+	}
 
-  public int getFirstPage(String filepath, HttpServletRequest request) {
-    util.dprintln(10, "getFirstPage");
-    return 1;
-  }
+	/**
+	 *  get the number of pages/files in the directory
+	 */
+	public int getNumPages(DigilibRequest request) throws Exception {
+		util.dprintln(10, "getNumPages");
+		return fileOp.getNumFilesVariant(
+			dlConfig.getBaseDirs(),
+			"/" + request.getFilePath(),
+			true);
+	}
 
-  /**
-   *  get the number of pages/files in the directory
-   */
-  public int getNumPages(HttpServletRequest request) throws Exception {
-    return getNumPages(getDocuPath(request), request);
-  }
-
-  public int getNumPages(String filepath, HttpServletRequest request) throws Exception {
-    util.dprintln(10, "getNumPages");
-    return fileOp.getNumFilesVariant(baseDirs, "/"+filepath, true);
-  }
+	/**
+	 * Returns the dlConfig.
+	 * @return DigilibConfiguration
+	 */
+	public DigilibConfiguration getDlConfig() {
+		return dlConfig;
+	}
 
 }
--- a/servlet/src/digilib/servlet/Scaler.java	Fri Jan 24 21:40:59 2003 +0100
+++ b/servlet/src/digilib/servlet/Scaler.java	Fri Jan 24 21:40:59 2003 +0100
@@ -2,7 +2,7 @@
 
   Digital Image Library servlet components
 
-  Copyright (C) 2001, 2002 Robert Casties (robcast@mail.berlios.de)
+  Copyright (C) 2001, 2002, 2003 Robert Casties (robcast@mail.berlios.de)
 
   This program is free software; you can redistribute  it and/or modify it
   under  the terms of  the GNU General  Public License as published by the
@@ -32,353 +32,470 @@
 
 //import tilecachetool.*;
 
+/**
+ * @author casties
+ *
+ */
 //public class Scaler extends HttpServlet implements SingleThreadModel {
 public class Scaler extends HttpServlet {
 
-  // Utils instance with debuglevel
-  Utils util;
-  // ServletOpss instance
-  ServletOps servletOp;
-  // FileOps instance
-  FileOps fileOp;
-  // AuthOps instance
-  AuthOps authOp;
-  // global DocuImage instance (don't reuse inside a request!)
-  DocuImage globalImage;
+	// digilib servlet version (for all components)
+	public static final String dlVersion = "1.5b";
+	
+	// Utils instance with debuglevel
+	Utils util;
+	// FileOps instance
+	FileOps fileOp;
+	// AuthOps instance
+	AuthOps authOp;
+	// ServletOps instance
+	ServletOps servletOp;
 
-  // use authorization database
-  boolean useAuthentication = true;
-  // image file to send in case of error
-  File errorImgFile = new File("/docuserver/images/icons/scalerror.gif");
-  // image file to send if access is denied
-  File denyImgFile = new File("/docuserver/images/icons/denied.gif");
-  // base directories in order of preference (prescaled versions first)
-  String[] baseDirs = {"/docuserver/scaled/small", "/docuserver/images", "/docuserver/scans/quellen"};
+	// DigilibParameters instance
+	DigilibConfiguration dlConfig;
 
+	// use authorization database
+	boolean useAuthentication = true;
 
-  /*********************************************************
-   *             Initialize global variables
-   *********************************************************/
-  public void init(ServletConfig config) throws ServletException {
-    super.init(config);
+	/** Initialisation on first run.
+	 * 
+	 * @see javax.servlet.Servlet#init(javax.servlet.ServletConfig)
+	 */
+	public void init(ServletConfig config) throws ServletException {
+		super.init(config);
 
-    // Debuggin!
-    //TCTool tctool = new TCTool();
-    
-    // first we need an Utils to setup ServletOps UGLY!!
-    util = new Utils(5);
-    // servletOps takes a ServletConfig to get the config file name
-    servletOp = new ServletOps(util, config);
-    // then we can start reading parameters UGLY!!
+		// Debuggin!
+		//TCTool tctool = new TCTool();
 
-    // Utils with new debuglevel
-    int debugLevel = servletOp.tryToGetInitParam("debug-level", 10);
-    util.setDebugLevel(debugLevel);
-    // image file to send in case of error
-    String errorImgFileName = servletOp.tryToGetInitParam("error-image", "/docuserver/images/icons/scalerror.gif");
-    errorImgFile = new File(errorImgFileName);
-    // image file to send if access is denied
-    String denyImgFileName = servletOp.tryToGetInitParam("denied-image", "/docuserver/images/icons/denied.gif");
-    denyImgFile = new File(denyImgFileName);
-    // base directories in order of preference (prescaled versions first)
-    String baseDirList = servletOp.tryToGetInitParam("basedir-list", "/docuserver/scaled/small:/docuserver/images:/docuserver/scans/quellen");
-    // split list into directories
-    baseDirs = servletOp.tryToGetPathArray(baseDirList, baseDirs);
-    // use authentication information
-    String useAuth = servletOp.tryToGetInitParam("use-authorization", "true");
-    if ((useAuth.indexOf("false") > -1)||(useAuth.indexOf("FALSE") > -1)) {
-      useAuthentication = false;
-    } else {
-      useAuthentication = true;
-      try {
-        // DB version
-        //authOp = new DBAuthOpsImpl(util);
-        // XML version
-        String cnfPath = servletOp.tryToGetInitParam("auth-file", "/docuserver/www/digitallibrary/WEB-INF/digilib-auth.xml");
-        authOp = new XMLAuthOps(util, cnfPath);
-      } catch (AuthOpException e) {
-        throw new ServletException(e);
-      }
-    }
-    // FileOps instance
-    fileOp = new FileOps(util);
-    // global DocuImage instance (don't reuse inside a request!)
-    globalImage = new JAIDocuImage(util);
-    // globalImage = new JIMIDocuImage(util);
-    //globalImage = new ImageLoaderDocuImage(util);
-    //globalImage = new JAIImageLoaderDocuImage(util);
-  }
+		// get our ServletContext
+		ServletContext context = config.getServletContext();
+		// see if there is a Configuration instance
+		dlConfig =
+			(DigilibConfiguration) context.getAttribute(
+				"digilib.servlet.parameters");
+		if (dlConfig == null) {
+			// create new Configuration
+			try {
+				dlConfig = new DigilibConfiguration(config);
+			} catch (Exception e) {
+				throw new ServletException(e);
+			}
+		}
+		// set the servlet version
+		dlConfig.setServletVersion(dlVersion);
+		// first we need an Utils
+		util = dlConfig.getUtil();
+		// set our AuthOps
+		useAuthentication = dlConfig.isUseAuthentication();
+		authOp = dlConfig.getAuthOp();
+		// FileOps instance
+		fileOp = new FileOps(util);
+		// AuthOps instance
+		servletOp = new ServletOps(util);
+	}
 
-  /**Process the HTTP Get request*/
-  public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
-    util.dprintln(1, "The servlet has received a GET!");
-    processRequest(request, response);
-  }
+	/** Process the HTTP Get request*/
+	public void doGet(HttpServletRequest request, HttpServletResponse response)
+		throws ServletException, IOException {
+		util.dprintln(1, "The servlet has received a GET!");
+		// create new request with defaults
+		DigilibRequest dlReq = new DigilibRequest();
+		// set with request parameters
+		dlReq.setWithRequest(request);
+		// add DigilibRequest to ServletRequest
+		request.setAttribute(
+			"digilib.servlet.request",
+			dlReq);
+		// do the processing
+		processRequest(request, response);
+	}
 
-  /**Process the HTTP Post request*/
-  public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
-    util.dprintln(1, "The servlet has received a POST!");
-    processRequest(request, response);
-  }
+	/**Process the HTTP Post request*/
+	public void doPost(
+		HttpServletRequest request,
+		HttpServletResponse response)
+		throws ServletException, IOException {
+		util.dprintln(1, "The servlet has received a POST!");
+		// create new request with defaults
+		DigilibRequest dlReq = new DigilibRequest();
+		// set with request parameters
+		dlReq.setWithRequest(request);
+		// add DigilibRequest to ServletRequest
+		request.setAttribute(
+			"digilib.servlet.request",
+			dlReq);
+		// do the processing
+		processRequest(request, response);
+	}
+
+	/** main request handler. */
+	void processRequest(
+		HttpServletRequest request,
+		HttpServletResponse response)
+		throws ServletException, IOException {
 
-  /**Clean up resources*/
-  public void destroy() {
-  }
+		// time for benchmarking
+		long startTime = System.currentTimeMillis();
+		// output mime/type
+		String mimeType = "image/png";
 
-/**********************************************************************
- *                       main request handler
- **********************************************************************/
+		/*
+		 * parameters for a session
+		 */
 
-  void processRequest(HttpServletRequest request, HttpServletResponse response)
-    throws ServletException, IOException {
-
-    // time for benchmarking
-    long startTime = System.currentTimeMillis();
-    // output mime/type
-    String mimeType = "image/png";
+		// scale the image file to fit window size i.e. respect dw,dh
+		boolean scaleToFit = true;
+		// crop the image if needed
+		boolean cropToFit = true;
+		// use heuristics (GIF?) to scale or send as is
+		boolean autoScale = true;
+		// try prescaled images first
+		boolean preScaledFirst = true;
+		// interpolation to use for scaling
+		int scaleQual = 0;
+		// send html error message (or image file)
+		boolean errorMsgHtml = false;
 
-    /**
-     * parameters for a session
-     */
+		/*
+		 *  request parameters
+		 */
+
+		DigilibRequest dlRequest =
+			(DigilibRequest) request.getAttribute("digilib.servlet.request");
 
-    // scale the image file to fit window size
-    boolean scaleToFit = true;
-    // use heuristics (GIF?) to scale or not
-    boolean forcedScale = false;
-    // try prescaled images first
-    boolean preScaledFirst = true;
-    // interpolation to use for scaling
-    int scaleQual = 0;
-    // send html error message (or image file)
-    boolean errorMsgHtml = false;
-
-    /**
-     *  request parameter
-     */
+		// destination image width
+		int paramDW = dlRequest.getDw();
+		// destination image height
+		int paramDH = dlRequest.getDh();
+		// relative area x_offset (0..1)
+		float paramWX = dlRequest.getWx();
+		// relative area y_offset
+		float paramWY = dlRequest.getWy();
+		// relative area width (0..1)
+		float paramWW = dlRequest.getWw();
+		// relative area height
+		float paramWH = dlRequest.getWh();
+		// scale factor (additional to dw/width, dh/height)
+		float paramWS = dlRequest.getWs();
 
-    // file/dir to load
-    String param_fn = servletOp.tryToGetParam("fn", "", request);
-    // page number
-    int param_pn = servletOp.tryToGetParam("pn", 1, request);
-    // destination image width
-    int param_dw = servletOp.tryToGetParam("dw", 300, request);
-    // destination image height
-    int param_dh = servletOp.tryToGetParam("dh", 400, request);
-    // relative area x_offset (0..1)
-    float param_wx = servletOp.tryToGetParam("wx", 0f, request);
-    // relative area y_offset
-    float param_wy = servletOp.tryToGetParam("wy", 0f, request);
-    // relative area width (0..1)
-    float param_ww = servletOp.tryToGetParam("ww", 1f, request);
-    // relative area height
-    float param_wh = servletOp.tryToGetParam("wh", 1f, request);
-    // scale factor (additional to dw/width, dh/height)
-    float param_ws = servletOp.tryToGetParam("ws", 1f, request);
-    // operation mode: flags separated by "+"
-    String param_mo = servletOp.tryToGetParam("mo", "", request);
-    // operation mode: "fit": always fit to page, "file": send as-is
-    if (param_mo.indexOf("fit") >= 0) {
-      scaleToFit = true;
-      forcedScale = true;
-    } else if (param_mo.indexOf("file") >= 0) {
-      scaleToFit = false;
-      forcedScale = true;
-    }
-    // operation mode: "errtxt": error message in html, "errimg": error image
-    if (param_mo.indexOf("errtxt") >= 0) {
-      errorMsgHtml = true;
-    } else if (param_mo.indexOf("errimg") >= 0) {
-      errorMsgHtml = false;
-    }
-    // operation mode: "q0" - "q2": interpolation quality
-    if (param_mo.indexOf("q0") >= 0) {
-      scaleQual = 0;
-    } else if (param_mo.indexOf("q1") >= 0) {
-      scaleQual = 1;
-    } else if (param_mo.indexOf("q2") >= 0) {
-      scaleQual = 2;
-    }
-    // operation mode: "lores": try to use scaled image, "hires": unscaled image
-    if (param_mo.indexOf("lores") >= 0) {
-      preScaledFirst = true;
-    } else if (param_mo.indexOf("hires") >= 0) {
-      preScaledFirst = false;
-    }
+		/* operation mode: "fit": always fit to page, 
+		 * "clip": send original resolution cropped, "file": send whole file (if
+		 * allowed)
+		 */
+		if (dlRequest.isOption("clip")) {
+			scaleToFit = false;
+			cropToFit = true;
+			autoScale = false;
+		} else if (dlRequest.isOption("fit")) {
+			scaleToFit = true;
+			cropToFit = true;
+			autoScale = false;
+		} else if (dlRequest.isOption("file")) {
+			scaleToFit = false;
+			if (dlConfig.isSendFileAllowed()) {
+				cropToFit = false;
+			} else {
+				cropToFit = true;
+			}
+			autoScale = false;
+		}
+		// operation mode: "errtxt": error message in html, "errimg": error image
+		if (dlRequest.isOption("errtxt")) {
+			errorMsgHtml = true;
+		} else if (dlRequest.isOption("errimg")) {
+			errorMsgHtml = false;
+		}
+		// operation mode: "q0" - "q2": interpolation quality
+		if (dlRequest.isOption("q0")) {
+			scaleQual = 0;
+		} else if (dlRequest.isOption("q1")) {
+			scaleQual = 1;
+		} else if (dlRequest.isOption("q2")) {
+			scaleQual = 2;
+		}
+		// operation mode: "lores": try to use scaled image, "hires": use unscaled image
+		if (dlRequest.isOption("lores")) {
+			preScaledFirst = true;
+		} else if (dlRequest.isOption("hires")) {
+			preScaledFirst = false;
+		}
 
-    Utils.dprintln(1, "Parameter values: fn:"+param_fn+" pn:"+param_pn+" dw:"+param_dw+" dh:"+param_dh+" wx:"+param_wx+" wy:"+param_wy+" ww:"+param_ww+" wh:"+param_wh+" ws:"+param_ws+" mo:"+param_mo);
+		//"big" try for all file/image actions
+		try {
+
+			// DocuImage instance
+			DocuImage docuImage = dlConfig.getDocuImageInstance();
+			if (docuImage == null) {
+				throw new ImageOpException("Unable to load DocuImage class!");
+			}
+			//DocuImage docuImage = new JAIDocuImage(util);
+			//DocuImage docuImage = new JIMIDocuImage(util);
+			//DocuImage docuImage = new ImageLoaderDocuImage(util);
+			//DocuImage docuImage = new JAIImageLoaderDocuImage(util);
+
+			/*
+			 *  find the file to load/send
+			 */
 
-    //"big" try for all file/image actions
-    try {
-
-    // DocuImage instance
-    DocuImage docuImage = new JAIDocuImage(util);
-    //DocuImage docuImage = new JIMIDocuImage(util);
-    //DocuImage docuImage = new ImageLoaderDocuImage(util);
-    //DocuImage docuImage = new JAIImageLoaderDocuImage(util);
-
-    /**
-     *  find the file to load/send
-     */
+			// get PathInfo
+			String loadPathName = dlRequest.getFilePath();
+			// if it's zoomed, try hires version (to be optimized...)
+			if ((paramWW < 1f) || (paramWH < 1f)) {
+				preScaledFirst = false;
+			}
+			
+			/*
+			 * check permissions
+			 */
+			if (useAuthentication) {
+				// get a list of required roles (empty if no restrictions)
+				List rolesRequired = authOp.rolesForPath(loadPathName, request);
+				if (rolesRequired != null) {
+					util.dprintln(1, "Role required: " + rolesRequired);
+					util.dprintln(2, "User: " + request.getRemoteUser());
+					// is the current request/user authorized?
+					if (!authOp.isRoleAuthorized(rolesRequired, request)) {
+						// send deny answer and abort
+						util.dprintln(1, "ERROR: access denied!");
+						if (errorMsgHtml) {
+							ServletOps.htmlMessage(
+								"ERROR: Unauthorized access!",
+								response);
+						} else {
+							servletOp.sendFile(
+								new File(dlConfig.getDenyImgFileName()),
+								response);
+						}
+						return;
+					}
+				}
+			}
 
-    String loadPathName = "";
-    // if there's PathInfo, append
-    if (request.getPathInfo() != null) {
-      loadPathName += request.getPathInfo();
-    }
-    // append fn parameter
-    loadPathName += param_fn;
-    // if it's zoomed, try hires version (to be optimized...)
-    if ((param_ww < 1f) || (param_wh < 1f)) {
-      preScaledFirst = false;
-    }
+			// find the file
+			File fileToLoad =
+				fileOp.getFileVariant(
+					dlConfig.getBaseDirs(),
+					loadPathName,
+					dlRequest.getPn(),
+					preScaledFirst);
+
+			util.dprintln(1, "Loading: " + fileToLoad);
 
-    if (useAuthentication) {
-      // check permissions
-      List rolesRequired = authOp.rolesForPath(loadPathName, request);
-      if (rolesRequired != null) {
-        Utils.dprintln(1, "Role required: "+rolesRequired);
-        Utils.dprintln(2, "User: "+request.getRemoteUser());
-        if (! authOp.isRoleAuthorized(rolesRequired, request)) {
-          Utils.dprintln(1, "ERROR: access denied!");
-          if (errorMsgHtml) {
-            servletOp.htmlMessage("ERROR: Unauthorized access!", response);
-          } else {
-            docuImage.sendFile(denyImgFile, response);
-          }
-          return;
-        }
-      }
-    }
+			// get the source image type (if it's known)
+			mimeType = FileOps.mimeForFile(fileToLoad);
+
+			/* if autoScale and not zoomed and source is GIF/PNG 
+			 * then send as is.
+			 */
+			if ((autoScale
+				&& (mimeType == "image/gif" || mimeType == "image/png")
+				&& (paramWW == 1f)
+				&& (paramWH == 1f))
+				|| (autoScale && !(scaleToFit || cropToFit))) {
+
+				util.dprintln(1, "Sending File as is.");
 
-    // find the file
-    File fileToLoad = fileOp.getFileVariant(baseDirs, loadPathName, param_pn, preScaledFirst);
+				servletOp.sendFile(fileToLoad, response);
 
-    Utils.dprintln(1, "Loading: "+fileToLoad);
+				util.dprintln(
+					1,
+					"Done in "
+						+ (System.currentTimeMillis() - startTime)
+						+ "ms");
+				return;
+			}
 
-    // get the source image type (if it's known)
-    mimeType = fileOp.mimeForFile(fileToLoad);
+			// finally load the file
+			docuImage.loadImage(fileToLoad);
 
-    // if not forced and source is GIF/PNG then send-as-is if not zoomed
-    if((!forcedScale && (mimeType == "image/gif" || mimeType == "image/png")
-        && (param_ww == 1f) && (param_wh == 1f)) || (forcedScale && !scaleToFit)) {
-
-      Utils.dprintln(1, "Sending File as is.");
+			/*
+			 *  crop and scale the image
+			 */
 
-      docuImage.sendFile(fileToLoad, response);
+			// get size
+			int imgWidth = docuImage.getWidth();
+			int imgHeight = docuImage.getHeight();
 
-      Utils.dprintln(1, "Done in "+(System.currentTimeMillis()-startTime)+"ms");
-      return;
-    }
+			util.dprintln(2, "IMG: " + imgWidth + "x" + imgHeight);
+			util.dprintln(
+				2,
+				"time " + (System.currentTimeMillis() - startTime) + "ms");
 
-    // load file
-    docuImage.loadImage(fileToLoad);
-
-    /**
-     *  crop and scale the image
-     */
-
-    // get size
-    int imgWidth = docuImage.getWidth();
-    int imgHeight = docuImage.getHeight();
+			// coordinates and scaling
+			float areaXoff;
+			float areaYoff;
+			float areaWidth;
+			float areaHeight;
+			float scaleX;
+			float scaleY;
+			float scaleXY;
 
-    util.dprintln(2, "IMG: "+imgWidth+"x"+imgHeight);
-    util.dprintln(2, "time "+(System.currentTimeMillis()-startTime)+"ms");
-
-    // calculate absolute from relative coordinates
-    float areaXoff = param_wx * imgWidth;
-    float areaYoff = param_wy * imgHeight;
-    float areaWidth = param_ww * imgWidth;
-    float areaHeight = param_wh * imgHeight;
-    // calculate scaling factors
-    float scaleX = param_dw / areaWidth * param_ws;
-    float scaleY = param_dh / areaHeight * param_ws;
-    float scaleXY = (scaleX > scaleY) ? scaleY : scaleX;
+			if (scaleToFit) {
+				// calculate absolute from relative coordinates
+				areaXoff = paramWX * imgWidth;
+				areaYoff = paramWY * imgHeight;
+				areaWidth = paramWW * imgWidth;
+				areaHeight = paramWH * imgHeight;
+				// calculate scaling factors
+				scaleX = paramDW / areaWidth * paramWS;
+				scaleY = paramDH / areaHeight * paramWS;
+				scaleXY = (scaleX > scaleY) ? scaleY : scaleX;
+			} else {
+				// crop to fit
+				// calculate absolute from relative coordinates
+				areaXoff = paramWX * imgWidth;
+				areaYoff = paramWY * imgHeight;
+				areaWidth = paramDW;
+				areaHeight = paramDH;
+				// calculate scaling factors
+				scaleX = 1f;
+				scaleY = 1f;
+				scaleXY = 1f;
+			}
 
-    util.dprintln(1, "Scale "+scaleXY+"("+scaleX+","+scaleY+") on "+areaXoff+","+areaYoff+" "+areaWidth+"x"+areaHeight);
-
-    // fit area to image
-    areaWidth = (areaXoff + areaWidth > imgWidth) ? imgWidth - areaXoff : areaWidth;
-    areaHeight = (areaYoff + areaHeight > imgHeight) ? imgHeight - areaYoff : areaHeight;
-
-    util.dprintln(2, "cropped: "+areaXoff+","+areaYoff+" "+areaWidth+"x"+areaHeight);
+			util.dprintln(
+				1,
+				"Scale "
+					+ scaleXY
+					+ "("
+					+ scaleX
+					+ ","
+					+ scaleY
+					+ ") on "
+					+ areaXoff
+					+ ","
+					+ areaYoff
+					+ " "
+					+ areaWidth
+					+ "x"
+					+ areaHeight);
 
-    // check image parameters
-    if ((areaWidth < 1)||(areaHeight < 1)
-       ||(scaleXY * areaWidth < 2)||(scaleXY * areaHeight < 2)) {
-      Utils.dprintln(1, "ERROR: invalid scale parameter set!");
-      throw new ImageOpException("Invalid scale parameter set!");
-    }
-
-    // crop and scale image
-    docuImage.cropAndScale((int)areaXoff, (int)areaYoff, (int)areaWidth, (int)areaHeight,
-                            scaleXY, scaleQual);
+			// clip area at the image border
+			areaWidth =
+				(areaXoff + areaWidth > imgWidth)
+					? imgWidth - areaXoff
+					: areaWidth;
+			areaHeight =
+				(areaYoff + areaHeight > imgHeight)
+					? imgHeight - areaYoff
+					: areaHeight;
 
-    util.dprintln(2, "time "+(System.currentTimeMillis()-startTime)+"ms");
+			util.dprintln(
+				2,
+				"cropped: "
+					+ areaXoff
+					+ ","
+					+ areaYoff
+					+ " "
+					+ areaWidth
+					+ "x"
+					+ areaHeight);
 
-    /**
-     *  write the resulting image
-     */
+			// check image parameters sanity
+			if ((areaWidth < 1)
+				|| (areaHeight < 1)
+				|| (scaleXY * areaWidth < 2)
+				|| (scaleXY * areaHeight < 2)) {
+				util.dprintln(1, "ERROR: invalid scale parameter set!");
+				throw new ImageOpException("Invalid scale parameter set!");
+			}
 
-    // setup output -- if source is JPG then dest will be JPG else it's PNG
-    if (mimeType != "image/jpeg") {
-      mimeType="image/png";
-    }
+			// crop and scale image
+			docuImage.cropAndScale(
+				(int) areaXoff,
+				(int) areaYoff,
+				(int) areaWidth,
+				(int) areaHeight,
+				scaleXY,
+				scaleQual);
 
-    // write the image
-    docuImage.writeImage(mimeType, response);
+			util.dprintln(
+				2,
+				"time " + (System.currentTimeMillis() - startTime) + "ms");
+
+			/*
+			 *  write the resulting image
+			 */
 
-    util.dprintln(1, "Done in "+(System.currentTimeMillis()-startTime)+"ms");
+			// setup output -- if source is JPG then dest will be JPG else it's PNG
+			if (mimeType != "image/jpeg") {
+				mimeType = "image/png";
+			}
 
-    /**
-     *  error handling
-     */
+			// write the image
+			docuImage.writeImage(mimeType, response);
 
-    }//"big" try
-    catch (FileOpException e) {
-      util.dprintln(1, "ERROR: File IO Error: "+e);
-      try {
-        if (errorMsgHtml) {
-          servletOp.htmlMessage("ERROR: File IO Error: "+e, response);
-        } else {
-          globalImage.sendFile(errorImgFile, response);
-        }
-      } catch (FileOpException ex) {} // so we don't get a loop
-      return;
-    }
-    catch (AuthOpException e) {
-      Utils.dprintln(1, "ERROR: Authorization error: "+e);
-      try {
-        if (errorMsgHtml) {
-          servletOp.htmlMessage("ERROR: Authorization error: "+e, response);
-        } else {
-          globalImage.sendFile(errorImgFile, response);
-        }
-      } catch (FileOpException ex) {} // so we don't get a loop
-      return;
-    }
-    catch (ImageOpException e) {
-      Utils.dprintln(1, "ERROR: Image Error: "+e);
-      try {
-        if (errorMsgHtml) {
-          servletOp.htmlMessage("ERROR: Image Operation Error: "+e, response);
-        } else {
-          globalImage.sendFile(errorImgFile, response);
-        }
-      } catch (FileOpException ex) {} // so we don't get a loop
-      return;
-    }
-    catch (RuntimeException e) {
-      Utils.dprintln(1, "ERROR: Any other Error: "+e);
-      try {
-        if (errorMsgHtml) {
-          servletOp.htmlMessage("ERROR: Other Error: "+e, response);
-        } else {
-          globalImage.sendFile(errorImgFile, response);
-        }
-      } catch (FileOpException ex) {} // so we don't get a loop
-      return;
-    }
+			util.dprintln(
+				1,
+				"Done in " + (System.currentTimeMillis() - startTime) + "ms");
+
+			/*
+			 *  error handling
+			 */
 
-  }
+		} // end of "big" try
+		catch (FileOpException e) {
+			util.dprintln(1, "ERROR: File IO Error: " + e);
+			try {
+				if (errorMsgHtml) {
+					ServletOps.htmlMessage(
+						"ERROR: File IO Error: " + e,
+						response);
+				} else {
+					servletOp.sendFile(
+						new File(dlConfig.getErrorImgFileName()),
+						response);
+				}
+			} catch (FileOpException ex) {
+			} // so we don't get a loop
+			return;
+		} catch (AuthOpException e) {
+			util.dprintln(1, "ERROR: Authorization error: " + e);
+			try {
+				if (errorMsgHtml) {
+					ServletOps.htmlMessage(
+						"ERROR: Authorization error: " + e,
+						response);
+				} else {
+					servletOp.sendFile(
+						new File(dlConfig.getErrorImgFileName()),
+						response);
+				}
+			} catch (FileOpException ex) {
+			} // so we don't get a loop
+			return;
+		} catch (ImageOpException e) {
+			util.dprintln(1, "ERROR: Image Error: " + e);
+			try {
+				if (errorMsgHtml) {
+					ServletOps.htmlMessage(
+						"ERROR: Image Operation Error: " + e,
+						response);
+				} else {
+					servletOp.sendFile(
+						new File(dlConfig.getErrorImgFileName()),
+						response);
+				}
+			} catch (FileOpException ex) {
+			} // so we don't get a loop
+			return;
+		} catch (RuntimeException e) {
+			// JAI likes to throw RuntimeExceptions ;-(
+			util.dprintln(1, "ERROR: Other Image Error: " + e);
+			try {
+				if (errorMsgHtml) {
+					ServletOps.htmlMessage(
+						"ERROR: Other Image Operation Error: " + e,
+						response);
+				} else {
+					servletOp.sendFile(
+						new File(dlConfig.getErrorImgFileName()),
+						response);
+				}
+			} catch (FileOpException ex) {
+			} // so we don't get a loop
+			return;
+		}
+	}
 
-}//Scaler class
+} //Scaler class
--- a/servlet/src/digilib/servlet/ServletOps.java	Fri Jan 24 21:40:59 2003 +0100
+++ b/servlet/src/digilib/servlet/ServletOps.java	Fri Jan 24 21:40:59 2003 +0100
@@ -117,6 +117,42 @@
     out.println("</body></html>");
   }
 
+  /** Transfers an image file as-is.
+   *
+   * The local file is copied to the <code>OutputStream</code> of the
+   * <code>ServletResponse</code>. The mime-type for the response is detected
+   * from the file.
+   *
+   * @param f Image file to be sent.
+   * @param res ServletResponse where the image file will be sent.
+   * @throws FileOpException Exception is thrown for a IOException.
+   */
+  public void sendFile(File f, ServletResponse response) throws FileOpException {
+	util.dprintln(4, "sendFile("+f+")");
+	String mimeType = FileOps.mimeForFile(f);
+	if (mimeType == null) {
+	  util.dprintln(2, "ERROR(sendFile): unknown file Type");
+	  throw new FileOpException("Unknown file type.");
+	}
+	response.setContentType(mimeType);
+	// open file
+	try {
+	  FileInputStream inFile = new FileInputStream(f);
+	  OutputStream outStream = response.getOutputStream();
+	  byte dataBuffer[] = new byte[4096];
+	  int len;
+	  while ((len = inFile.read(dataBuffer)) != -1) {
+		// copy out file
+		outStream.write(dataBuffer, 0, len);
+	  }
+	  inFile.close();
+	} catch (IOException e) {
+	  util.dprintln(2, "ERROR(sendFile): unable to send file");
+	  throw new FileOpException("Unable to send file.");
+	}
+  }
+
+
   /**
    *  get a parameter from request and return it if set, otherwise return default
    */