changeset 586:41a8d293b798 stream

Merge with HEAD 3af19d51dd7e579c3384d27b24053c2660915d9d
author robcast
date Wed, 05 Jan 2011 14:46:19 +0100
parents 95417c4615b8 (diff) 3af19d51dd7e (current diff)
children 720d061a1b30
files
diffstat 25 files changed, 1106 insertions(+), 852 deletions(-) [+]
line wrap: on
line diff
--- a/servlet/src/digilib/image/DocuImage.java	Wed Jan 05 14:44:19 2011 +0100
+++ b/servlet/src/digilib/image/DocuImage.java	Wed Jan 05 14:46:19 2011 +0100
@@ -29,6 +29,7 @@
 
 import digilib.io.ImageFile;
 import digilib.io.FileOpException;
+import digilib.io.ImageInput;
 
 /** The basic class for the representation of a digilib image.
  *
@@ -46,7 +47,7 @@
 	 */
 	public void loadImage(ImageFile f) throws FileOpException;
 
-	/** This DocuImage support the loadSubImage operation.
+	/** This DocuImage supports the loadSubImage operation.
 	 * 
 	 * @return boolean
 	 */
@@ -223,7 +224,7 @@
     /**
      * Check image size and type and store in ImageFile f
      */
-    public ImageFile identify(ImageFile imgf) throws IOException;
+    public ImageInput identify(ImageFile imgf) throws IOException;
 
     /**
      * Returns a list of supported image formats
--- a/servlet/src/digilib/image/DocuImageImpl.java	Wed Jan 05 14:44:19 2011 +0100
+++ b/servlet/src/digilib/image/DocuImageImpl.java	Wed Jan 05 14:46:19 2011 +0100
@@ -34,6 +34,7 @@
 
 import digilib.io.FileOpException;
 import digilib.io.ImageFile;
+import digilib.io.ImageInput;
 
 /** Simple abstract implementation of the <code>DocuImage</code> interface.
  *
@@ -106,7 +107,7 @@
     /* (non-Javadoc)
      * @see digilib.image.DocuImage#identify(digilib.io.ImageFile)
      */
-    public ImageFile identify(ImageFile imgf) throws IOException {
+    public ImageInput identify(ImageFile imgf) throws IOException {
         // just a do-nothing implementation
         return null;
     }
--- a/servlet/src/digilib/image/ImageInfoDocuImage.java	Wed Jan 05 14:44:19 2011 +0100
+++ b/servlet/src/digilib/image/ImageInfoDocuImage.java	Wed Jan 05 14:46:19 2011 +0100
@@ -10,6 +10,7 @@
 import org.marcoschmidt.image.ImageInfo;
 
 import digilib.io.ImageFile;
+import digilib.io.ImageInput;
 
 /** Simple abstract implementation of the <code>DocuImage</code> interface.
  * Implements only the identify method using the ImageInfo class.
@@ -19,7 +20,7 @@
 public abstract class ImageInfoDocuImage extends DocuImageImpl {
 
     /** Check image size and type and store in ImageFile f */
-    public ImageFile identify(ImageFile imgf) throws IOException {
+    public ImageInput identify(ImageFile imgf) throws IOException {
         // fileset to store the information
         File f = imgf.getFile();
         if (f == null) {
--- a/servlet/src/digilib/image/ImageJobDescription.java	Wed Jan 05 14:44:19 2011 +0100
+++ b/servlet/src/digilib/image/ImageJobDescription.java	Wed Jan 05 14:46:19 2011 +0100
@@ -12,7 +12,8 @@
 import digilib.io.FileOps;
 import digilib.io.FileOps.FileClass;
 import digilib.io.ImageFile;
-import digilib.io.ImageFileset;
+import digilib.io.ImageInput;
+import digilib.io.ImageSet;
 import digilib.servlet.DigilibConfiguration;
 import digilib.util.OptionsSet;
 import digilib.util.Parameter;
@@ -36,8 +37,8 @@
 	DigilibConfiguration dlConfig = null;
 	protected static Logger logger = Logger.getLogger("digilib.servlet");
 
-	ImageFile fileToLoad = null;
-	ImageFileset fileset = null;
+	ImageInput fileToLoad = null;
+	ImageSet fileset = null;
 	DocuDirectory fileDir = null;
 	String filePath = null;
 	ImageSize expectedSourceSize = null;
@@ -131,15 +132,12 @@
 	public String getMimeType() throws IOException {
 		if (mimeType == null) {
 			fileToLoad = getFileToLoad();
-			if(! fileToLoad.isChecked()){
-				DigilibConfiguration.docuImageIdentify(fileToLoad);
-			}
 			mimeType = fileToLoad.getMimetype();
 		}
 		return mimeType;
 	}
 	
-	public ImageFile getFileToLoad() throws IOException {
+	public ImageInput getFileToLoad() throws IOException {
 		
 		if(fileToLoad == null){
 			fileset = getFileset();
@@ -163,7 +161,7 @@
 					fileToLoad = fileset.getBiggest();
 				}
 			}
-			logger.info("Planning to load: " + fileToLoad.getFile());
+			logger.info("Planning to load: " + fileToLoad);
 		}
 		
 		return fileToLoad;
@@ -182,11 +180,11 @@
 		return fileDir;
 	}
 	
-    public ImageFileset getFileset() throws FileOpException {
+    public ImageSet getFileset() throws FileOpException {
         if(fileset==null){
             DocuDirCache dirCache = (DocuDirCache) dlConfig.getValue("servlet.dir.cache");
     
-            fileset = (ImageFileset) dirCache.getFile(getFilePath(), getAsInt("pn"), FileClass.IMAGE);
+            fileset = (ImageSet) dirCache.getFile(getFilePath(), getAsInt("pn"), FileClass.IMAGE);
             if (fileset == null) {
                 throw new FileOpException("File " + getFilePath() + "("
                         + getAsInt("pn") + ") not found.");
@@ -245,12 +243,9 @@
 		logger.debug("get_hiresSize()");
 
 		ImageSize hiresSize = null;
-		ImageFileset fileset = getFileset();
+		ImageSet fileset = getFileset();
 		if (getAbsoluteScale()) {
-			ImageFile hiresFile = fileset.getBiggest();
-			if (!hiresFile.isChecked()) {
-				DigilibConfiguration.docuImageIdentify(hiresFile);
-			}
+			ImageInput hiresFile = fileset.getBiggest();
 			hiresSize = hiresFile.getSize();
 		}
 		return hiresSize;
--- a/servlet/src/digilib/image/ImageLoaderDocuImage.java	Wed Jan 05 14:44:19 2011 +0100
+++ b/servlet/src/digilib/image/ImageLoaderDocuImage.java	Wed Jan 05 14:46:19 2011 +0100
@@ -50,7 +50,8 @@
 import digilib.io.FileOpException;
 import digilib.io.FileOps;
 import digilib.io.ImageFile;
-import digilib.io.ImageFileset;
+import digilib.io.ImageSet;
+import digilib.io.ImageInput;
 
 /** Implementation of DocuImage using the ImageLoader API of Java 1.4 and Java2D. */
 public class ImageLoaderDocuImage extends ImageInfoDocuImage {
@@ -119,14 +120,14 @@
 	}
 
     /** Check image size and type and store in ImageFile f */
-    public ImageFile identify(ImageFile imageFile) throws IOException {
+    public ImageInput identify(ImageFile imageFile) throws IOException {
         // try parent method first
-        ImageFile imf = super.identify(imageFile);
+        ImageInput imf = super.identify(imageFile);
         if (imf != null) {
             return imf;
         }
         // fileset to store the information
-        ImageFileset imgfs = imageFile.getParent();
+        ImageSet imgfs = imageFile.getParent();
         File f = imageFile.getFile();
         if (f == null) {
             throw new IOException("File not found!");
--- a/servlet/src/digilib/image/ImageWorker.java	Wed Jan 05 14:44:19 2011 +0100
+++ b/servlet/src/digilib/image/ImageWorker.java	Wed Jan 05 14:46:19 2011 +0100
@@ -10,6 +10,7 @@
 import org.apache.log4j.Logger;
 
 import digilib.io.FileOpException;
+import digilib.io.ImageFile;
 import digilib.servlet.DigilibConfiguration;
 
 /** Worker that renders an image.
@@ -70,7 +71,7 @@
                         + scaleXY);
             }
 
-            docuImage.loadSubimage(jobinfo.getFileToLoad(), loadRect, (int) subsamp);
+            docuImage.loadSubimage((ImageFile) jobinfo.getFileToLoad(), loadRect, (int) subsamp); //FIXME: cast to file
 
             logger.debug("SUBSAMP: " + subsamp + " -> " + docuImage.getSize());
 
@@ -78,7 +79,7 @@
 
         } else {
             // else load and crop the whole file
-            docuImage.loadImage(jobinfo.getFileToLoad());
+            docuImage.loadImage((ImageFile) jobinfo.getFileToLoad()); //FIXME: cast to file
             docuImage.crop((int) loadRect.getX(), (int) loadRect.getY(),
                     (int) loadRect.getWidth(), (int) loadRect.getHeight());
 
--- a/servlet/src/digilib/image/JAIDocuImage.java	Wed Jan 05 14:44:19 2011 +0100
+++ b/servlet/src/digilib/image/JAIDocuImage.java	Wed Jan 05 14:46:19 2011 +0100
@@ -47,7 +47,8 @@
 import digilib.io.FileOpException;
 import digilib.io.FileOps;
 import digilib.io.ImageFile;
-import digilib.io.ImageFileset;
+import digilib.io.ImageSet;
+import digilib.io.ImageInput;
 
 /** A DocuImage implementation using Java Advanced Imaging Library. */
 /**
@@ -104,14 +105,14 @@
     }
 
 	/* Check image size and type and store in ImageFile f */
-	public ImageFile identify(ImageFile imageFile) throws IOException {
+	public ImageInput identify(ImageFile imageFile) throws IOException {
         // try parent method first
-	    ImageFile imf = super.identify(imageFile);
+	    ImageInput imf = super.identify(imageFile);
 		if (imf != null) {
 			return imf;
 		}
 		// fileset to store the information
-		ImageFileset imgfs = imageFile.getParent();
+		ImageSet imgfs = imageFile.getParent();
 		File f = imageFile.getFile();
 		if (f == null) {
 			throw new IOException("File not found!");
--- a/servlet/src/digilib/io/DigilibInfoReader.java	Wed Jan 05 14:44:19 2011 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,76 +0,0 @@
-package digilib.io;
-
-/** DigilibInfoReader 
- * A class for reading the information from info.xml files used in digilib image directories.
- *
- */
-
-import java.io.File;
-import java.util.List;
-
-import org.apache.log4j.Logger;
-import org.jdom.Document;
-import org.jdom.Element;
-import org.jdom.input.SAXBuilder;
-
-
-
-public class DigilibInfoReader {
-
-	/** gengeral logger for this class */
-	protected static Logger logger = Logger.getLogger("digilib.servlet");
-	
-	private String filename = null;
-	//private static String base_element = "info";
-	
-	public DigilibInfoReader(String fn){
-		filename = fn;
-	}
-
-	/**
-	 * Returns the attribute defined by 'attr' as a String.
-	 * 
-	 * @param attr
-	 * @return
-	 */
-	@SuppressWarnings("unchecked") // Element.getChildren() returns naked List
-    public String getAsString(String attr){
-		try{
-			SAXBuilder builder = new SAXBuilder();
-			Document doc = builder.build(new File(filename));
-			Element root = doc.getRootElement();
-			List<Element> mainElements = root.getChildren();
-			// logger.debug("XML mainElements:"+mainElements.toString());
-
-			for(int i=0; i<mainElements.size(); i++){
-				Element elem = mainElements.get(i);
-				if(elem.getName()==attr){
-					// logger.debug(attr+" == "+(String)elem.getTextTrim());
-					return (String)elem.getTextTrim();
-				}
-			}
-
-		}
-		catch(Exception e){
-			logger.error(e.getMessage());
-		}
-		return null;
-	}
-	
-	
-	/**
-	 * Find out if the info.xml exists
-	 * @return
-	 */
-	public boolean hasInfo(){
-		try {
-			SAXBuilder builder = new SAXBuilder();
-			builder.build(new File(filename));
-			return true;
-		}
-		catch(Exception e){
-			return false;
-		}
-	}
-	
-}
--- a/servlet/src/digilib/io/DocuDirectory.java	Wed Jan 05 14:44:19 2011 +0100
+++ b/servlet/src/digilib/io/DocuDirectory.java	Wed Jan 05 14:46:19 2011 +0100
@@ -40,9 +40,6 @@
 	/** list of files (DocuDirent) */
 	private List<List<DocuDirent>> list = null;
 
-	/** default FileClass for unspecified calls */
-	public static FileClass defaultFileClass = FileClass.IMAGE;
-	
 	/** directory object is valid (exists on disk) */
 	private boolean isValid = false;
 
@@ -52,6 +49,9 @@
 	/** directory name (digilib canonical form) */
 	private String dirName = null;
 
+	/** array of parallel dirs for scaled images */
+	private Directory[] dirs = null;
+
 	/** directory metadata */
 	private MetadataMap dirMeta = null;
 
@@ -111,7 +111,7 @@
 	 *  
 	 */
 	public int size() {
-	    return size(defaultFileClass);
+		return ((list != null) && (list.get(0) != null)) ? list.get(0).size() : 0;
 	}
 
 	/**
@@ -121,13 +121,7 @@
 	 *            fileClass
 	 */
 	public int size(FileClass fc) {
-        if (list != null) {
-            List<DocuDirent> l = list.get(fc.ordinal());
-            if (l != null) {
-                return l.size();
-            }
-        }
-        return 0;
+		return ((list != null) && (list.get(fc.ordinal()) != null)) ? list.get(fc.ordinal()).size() : 0;
 	}
 
 	/**
@@ -136,8 +130,11 @@
 	 * @param index
 	 * @return
 	 */
-	public ImageFileset get(int index) {
-		return (ImageFileset) get(index, defaultFileClass);
+	public DocuDirent get(int index) {
+		if ((list == null) || (list.get(0) == null) || (index >= list.get(0).size())) {
+			return null;
+		}
+		return list.get(0).get(index);
 	}
 
 	/**
@@ -177,81 +174,75 @@
 	 * 
 	 * @return boolean the directory exists
 	 */
-	public synchronized boolean readDir() {
+	public boolean readDir() {
 		// check directory first
 		checkDir();
 		if (!isValid) {
 			return false;
 		}
-		// first file extension to try for scaled directories
-		String scalext = null;
 		// read all filenames
 		logger.debug("reading directory " + dir.getPath());
+		File[] allFiles = null;
 		/*
 		 * using ReadableFileFilter is safer (we won't get directories with file
 		 * extensions) but slower.
 		 */
-		File[] allFiles = null;
-		//	allFiles = dir.listFiles(new FileOps.ReadableFileFilter());
+		// allFiles = dir.listFiles(new FileOps.ReadableFileFilter());
 		allFiles = dir.listFiles();
-		//logger.debug("  done");
 		if (allFiles == null) {
 			// not a directory
 			return false;
 		}
-		// list of base dirs from the parent cache
-		String[] baseDirNames = cache.getBaseDirNames();
-		// number of base dirs
-		int nb = baseDirNames.length;
-		// array of base dirs
-		Directory[] dirs = new Directory[nb];
-		// first entry is this directory
-		dirs[0] = this;
-		// fill array with the remaining directories
-		for (int j = 1; j < nb; j++) {
-			File d = new File(baseDirNames[j], dirName);
-			if (d.isDirectory()) {
-				dirs[j] = new Directory(d);
-				logger.debug("  reading scaled directory " + d.getPath());
-				dirs[j].readDir();
-				//logger.debug("    done");
+		// init parallel directories
+		if (dirs == null) {
+			// list of base dirs from the parent cache
+			String[] baseDirNames = cache.getBaseDirNames();
+			// number of base dirs
+			int nb = baseDirNames.length;
+			// array of parallel dirs
+			dirs = new Directory[nb];
+			// first entry is this directory
+			dirs[0] = this;
+			// fill array with the remaining directories
+			for (int j = 1; j < nb; j++) {
+				// add dirName to baseDirName
+				File d = new File(baseDirNames[j], dirName);
+				if (d.isDirectory()) {
+					dirs[j] = new Directory(d);
+					logger.debug("  reading scaled directory " + d.getPath());
+					dirs[j].readDir();
+				}
 			}
 		}
 
 		// go through all file classes
-        //for (int classIdx = 0; classIdx < FileOps.NUM_CLASSES; classIdx++) {
-		for (FileClass fileClass: cache.getFileClasses()) {
-			//fileClass = cache.getFileClasses()[classIdx];
-			File[] fileList = FileOps.listFiles(allFiles, FileOps
-					.filterForClass(fileClass));
-			//logger.debug(" done");
+		for (FileClass fileClass : cache.getFileClasses()) {
+			File[] fileList = FileOps.listFiles(allFiles,
+					FileOps.filterForClass(fileClass));
 			// number of files in the directory
 			int numFiles = fileList.length;
 			if (numFiles > 0) {
 				// create new list
-				list.set(fileClass.ordinal(), new ArrayList<DocuDirent>(numFiles));
-				// sort the file names alphabetically and iterate the list
-				// Arrays.sort(fileList); // not needed <hertzhaft>
-				Map<Integer, Object> hints = FileOps.newHints(FileOps.HINT_BASEDIRS, dirs);
-				hints.put(FileOps.HINT_FILEEXT, scalext);
-				for (int i = 0; i < numFiles; i++) {
-					DocuDirent f = FileOps.fileForClass(fileClass, fileList[i],
-							hints);
+				ArrayList<DocuDirent> dl = new ArrayList<DocuDirent>(numFiles);
+				list.set(fileClass.ordinal(), dl);
+				for (File f : fileList) {
+					DocuDirent df = FileOps.fileForClass(fileClass, f, dirs);
+					df.setParent(this);
 					// add the file to our list
-                    // logger.debug(f.getName());
-
-					list.get(fileClass.ordinal()).add(f);
-					f.setParent(this);
+					dl.add(df);
 				}
-                // we sort the inner ArrayList (the list of files not the list of file types)
-				// for binarySearch to work (DocuDirent's natural sort order is by filename)
-                Collections.sort(list.get(fileClass.ordinal()));
+				/*
+				 * we sort the inner ArrayList (the list of files not the list
+				 * of file types) for binarySearch to work (DocuDirent's natural
+				 * sort order is by filename)
+				 */
+				Collections.sort(dl);
 			}
 		}
 		// clear the scaled directories
-		for (int j = 1; j < nb; j++) {
-			if (dirs[j] != null) {
-				dirs[j].clearFilenames();
+		for (Directory d: dirs) {
+			if (d != null) {
+				d.clearFilenames();
 			}
 		}
 		// update number of cached files if this was the first time
@@ -456,9 +447,8 @@
 		return -1;
 	}
 
-	private boolean isBasenameInList(List<DocuDirent> fl, int idx, String fn) {
-		String dfn = FileOps.basename((fl.get(idx))
-				.getName());
+	private boolean isBasenameInList(List<DocuDirent> fileList, int idx, String fn) {
+		String dfn = FileOps.basename((fileList.get(idx)).getName());
 		return (dfn.equals(fn)||dfn.equals(FileOps.basename(fn))); 
 	}
 	
@@ -474,7 +464,12 @@
 	 * @return DocuDirent
 	 */
 	public DocuDirent find(String fn) {
-		return find(fn, defaultFileClass);
+		FileClass fc = FileOps.classForFilename(fn);
+		int i = indexOf(fn, fc);
+		if (i >= 0) {
+			return list.get(0).get(i);
+		}
+		return null;
 	}
 
 	/**
@@ -491,7 +486,7 @@
 	public DocuDirent find(String fn, FileClass fc) {
 		int i = indexOf(fn, fc);
 		if (i >= 0) {
-			return (DocuDirent) list.get(fc.ordinal()).get(i);
+			return list.get(fc.ordinal()).get(i);
 		}
 		return null;
 	}
--- a/servlet/src/digilib/io/DocuDirent.java	Wed Jan 05 14:44:19 2011 +0100
+++ b/servlet/src/digilib/io/DocuDirent.java	Wed Jan 05 14:46:19 2011 +0100
@@ -1,169 +1,79 @@
-/*
- * DocuDirent.java -- Abstract directory entry in a DocuDirectory
- * 
- * Digital Image Library servlet components
- * 
- * Copyright (C) 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 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
- * 
- * Created on 15.09.2003 by casties
- *  
- */
 package digilib.io;
 
 import java.io.File;
-import java.util.Map;
 
-import org.apache.log4j.Logger;
-
-import digilib.io.FileOps.FileClass;
-
-/**
- * Abstract directory entry in a DocuDirectory.
- * 
- * @author casties
- *  
- */
-public abstract class DocuDirent implements Comparable<Object> {
+public interface DocuDirent extends Comparable<Object> {
 
-	/** the file class of this file */
-	protected static FileClass fileClass = FileClass.NONE;
-	/** HashMap with metadata */
-	protected MetadataMap fileMeta = null;
-	/** Is the Metadata valid */
-	protected boolean metaChecked = false;
-	/** the parent directory */
-	protected Directory parent = null;
+    /**
+     * Checks metadata and does something with it.
+     *  
+     */
+    public abstract void checkMeta();
 
-	/**
-	 * Checks metadata and does something with it.
-	 *  
-	 */
-	public abstract void checkMeta();
+    /**
+     * gets the (default) File
+     * 
+     * @return
+     */
+    public abstract File getFile();
 
-	/**
-	 * gets the (default) File
-	 * 
-	 * @return
-	 */
-	public abstract File getFile();
+    /**
+     * Reads meta-data for this Fileset if there is any.
+     *  
+     */
+    public abstract void readMeta();
 
-	/**
-	 * Reads meta-data for this Fileset if there is any.
-	 *  
-	 */
-	public void readMeta() {
-		if ((fileMeta != null) || (getFile() == null)) {
-			// there is already metadata or there is no file
-			return;
-		}
-		// metadata is in the file {filename}.meta
-		String fn = getFile().getAbsolutePath();
-		File mf = new File(fn + ".meta");
-		if (mf.canRead()) {
-			XMLMetaLoader ml = new XMLMetaLoader();
-			try {
-				// read meta file
-				Map<String, MetadataMap> meta = ml.loadURL(mf.getAbsolutePath());
-				if (meta == null) {
-					return;
-				}
-				fileMeta = meta.get(getName());
-			} catch (Exception e) {
-				Logger.getLogger(this.getClass()).warn("error reading file .meta", e);
-			}
-		}
-	}
+    /**
+     * The name of the file.
+     * 
+     * If this is a Fileset, the method returns the name of the default file
+     * (for image filesets the highest resolution file).
+     * 
+     * @return
+     */
+    public abstract String getName();
 
-	/**
-	 * The name of the file.
-	 * 
-	 * If this is a Fileset, the method returns the name of the default file
-	 * (for image filesets the highest resolution file).
-	 * 
-	 * @return
-	 */
-	public String getName() {
-		File f = getFile();
-		return (f != null) ? f.getName() : null;
-	} 
-	
-	/**
-	 * Returns the parent Directory.
-	 * 
-	 * @return DocuDirectory
-	 */
-	public Directory getParent() {
-		return parent;
-	}
-	
-	/**
-	 * Sets the parent Directory.
-	 * 
-	 * @param parent
-	 *            The parent to set
-	 */
-	public void setParent(Directory parent) {
-		this.parent = parent;
-	} 
-	
-	/**
-	 * Returns the meta-data for this file(set).
-	 * 
-	 * @return HashMap
-	 */
-	public MetadataMap getFileMeta() {
-		return fileMeta;
-	} 
-	
-	/**
-	 * Sets the meta-data for this file(set) .
-	 * 
-	 * @param fileMeta
-	 *            The fileMeta to set
-	 */
-	public void setFileMeta(MetadataMap fileMeta) {
-		this.fileMeta = fileMeta;
-	} 
-	
-	/**
-	 * @return
-	 */
-	public boolean isMetaChecked() {
-		return metaChecked;
-	} 
-	
-	/**
-	 * @return
-	 */
-	public static FileClass getFileClass() {
-		return fileClass;
-	}
+    /**
+     * Returns the parent Directory.
+     * 
+     * @return DocuDirectory
+     */
+    public abstract Directory getParent();
+
+    /**
+     * Sets the parent Directory.
+     * 
+     * @param parent
+     *            The parent to set
+     */
+    public abstract void setParent(Directory parent);
+
+    /**
+     * Returns the meta-data for this file(set).
+     * 
+     * @return HashMap
+     */
+    public abstract MetadataMap getFileMeta();
 
-	/** Comparator using the file name.
-	 * Compares to a String (for binarySearch)
+    /**
+     * Sets the meta-data for this file(set) .
+     * 
+     * @param fileMeta
+     *            The fileMeta to set
+     */
+    public abstract void setFileMeta(MetadataMap fileMeta);
+
+    /**
+     * @return
+     */
+    public abstract boolean isMetaChecked();
+
+    /** Comparator using the file name.
+     * Compares to a String (for binarySearch)
      * or to another DocuDirent (for sort)
-	 * 
-	 * @see java.lang.Comparable#compareTo(java.lang.Object)
-	 */
-	public int compareTo(Object arg0) {
-		if (arg0 instanceof DocuDirent) {
-		    return getName().compareTo(((DocuDirent) arg0).getName());
-		} else {
-		    return getName().compareTo((String) arg0);
-		}
-	}
+     * 
+     * @see java.lang.Comparable#compareTo(java.lang.Object)
+     */
+    public abstract int compareTo(Object arg0);
 
-	
-}
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/servlet/src/digilib/io/DocuDirentImpl.java	Wed Jan 05 14:46:19 2011 +0100
@@ -0,0 +1,147 @@
+/*
+ * DocuDirent.java -- Abstract directory entry in a DocuDirectory
+ * 
+ * Digital Image Library servlet components
+ * 
+ * Copyright (C) 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 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
+ * 
+ * Created on 15.09.2003 by casties
+ *  
+ */
+package digilib.io;
+
+import java.io.File;
+import java.util.Map;
+
+import org.apache.log4j.Logger;
+
+import digilib.io.FileOps.FileClass;
+
+/**
+ * Abstract directory entry in a DocuDirectory.
+ * 
+ * @author casties
+ *  
+ */
+public abstract class DocuDirentImpl implements DocuDirent {
+
+	/** the file class of this file */
+	protected static FileClass fileClass = FileClass.NONE;
+	/** HashMap with metadata */
+	protected MetadataMap fileMeta = null;
+	/** Is the Metadata valid */
+	protected boolean metaChecked = false;
+	/** the parent directory */
+	protected Directory parent = null;
+
+	/* (non-Javadoc)
+     * @see digilib.io.DocuDirent#checkMeta()
+     */
+	public abstract void checkMeta();
+
+	/* (non-Javadoc)
+     * @see digilib.io.DocuDirent#getInput()
+     */
+	public abstract File getFile();
+
+	/* (non-Javadoc)
+     * @see digilib.io.DocuDirent#readMeta()
+     */
+	public void readMeta() {
+		if ((fileMeta != null) || (getFile() == null)) {
+			// there is already metadata or there is no file
+			return;
+		}
+		// metadata is in the file {filename}.meta
+		String fn = getFile().getAbsolutePath();
+		File mf = new File(fn + ".meta");
+		if (mf.canRead()) {
+			XMLMetaLoader ml = new XMLMetaLoader();
+			try {
+				// read meta file
+				Map<String, MetadataMap> meta = ml.loadURL(mf.getAbsolutePath());
+				if (meta == null) {
+					return;
+				}
+				fileMeta = meta.get(getName());
+			} catch (Exception e) {
+				Logger.getLogger(this.getClass()).warn("error reading file .meta", e);
+			}
+		}
+	}
+
+	/* (non-Javadoc)
+     * @see digilib.io.DocuDirent#getName()
+     */
+	public String getName() {
+		File f = getFile();
+		return (f != null) ? f.getName() : null;
+	} 
+	
+	/* (non-Javadoc)
+     * @see digilib.io.DocuDirent#getParent()
+     */
+	public Directory getParent() {
+		return parent;
+	}
+	
+	/* (non-Javadoc)
+     * @see digilib.io.DocuDirent#setParent(digilib.io.Directory)
+     */
+	public void setParent(Directory parent) {
+		this.parent = parent;
+	} 
+	
+	/* (non-Javadoc)
+     * @see digilib.io.DocuDirent#getFileMeta()
+     */
+	public MetadataMap getFileMeta() {
+		return fileMeta;
+	} 
+	
+	/* (non-Javadoc)
+     * @see digilib.io.DocuDirent#setFileMeta(digilib.io.MetadataMap)
+     */
+	public void setFileMeta(MetadataMap fileMeta) {
+		this.fileMeta = fileMeta;
+	} 
+	
+	/* (non-Javadoc)
+     * @see digilib.io.DocuDirent#isMetaChecked()
+     */
+	public boolean isMetaChecked() {
+		return metaChecked;
+	} 
+	
+	/**
+	 * @return
+	 */
+	public static FileClass getFileClass() {
+		return fileClass;
+	}
+
+	/* (non-Javadoc)
+     * @see digilib.io.DocuDirent#compareTo(java.lang.Object)
+     */
+	public int compareTo(Object arg0) {
+		if (arg0 instanceof DocuDirentImpl) {
+		    return getName().compareTo(((DocuDirent) arg0).getName());
+		} else {
+		    return getName().compareTo((String) arg0);
+		}
+	}
+
+	
+}
--- a/servlet/src/digilib/io/FileOps.java	Wed Jan 05 14:44:19 2011 +0100
+++ b/servlet/src/digilib/io/FileOps.java	Wed Jan 05 14:46:19 2011 +0100
@@ -329,20 +329,20 @@
 	/**
 	 * Factory for DocuDirents based on file class.
 	 * 
-	 * Returns an ImageFileset, TextFile or SVGFile. baseDirs and scalext are
+	 * Returns an ImageSet, TextFile or SVGFile. scaleDirs are
 	 * only for ImageFilesets.
 	 * 
 	 * @param fileClass
 	 * @param file
-	 * @param hints
+	 * @param scaleDirs
 	 *            optional additional parameters
 	 * @return
 	 */
-	public static DocuDirent fileForClass(FileClass fileClass, File file, Map<Integer,Object> hints) {
+	public static DocuDirent fileForClass(FileClass fileClass, File file, Directory[] scaleDirs) {
 		// what class of file do we have?
 		if (fileClass == FileClass.IMAGE) {
 			// image file
-			return new ImageFileset(file, hints);
+			return new ImageFileSet(file, scaleDirs);
 		} else if (fileClass == FileClass.TEXT) {
 			// text file
 			return new TextFile(file);
--- a/servlet/src/digilib/io/ImageFile.java	Wed Jan 05 14:44:19 2011 +0100
+++ b/servlet/src/digilib/io/ImageFile.java	Wed Jan 05 14:46:19 2011 +0100
@@ -22,74 +22,124 @@
 package digilib.io;
 
 import java.io.File;
+import java.io.IOException;
 
 import digilib.image.ImageSize;
+import digilib.servlet.DigilibConfiguration;
 
 /**
  * @author casties
  */
-public class ImageFile {
+public class ImageFile extends ImageInput {
 	
+	// file
+	private File file = null;
 	// file name
-	private String filename = null;
-	// parent ImageFileset
-	private ImageFileset parent = null;
+	private String name = null;
+	// parent ImageSet
+	private ImageSet parent = null;
 	// parent directory
 	private Directory dir = null;
-	// mime file type
-	private String mimetype = null;
-	// image size in pixels
-	private ImageSize pixelSize = null;
 
-	public ImageFile(String fn, ImageFileset parent, Directory dir) {
-		this.filename = fn;
+	/** Constructor with File.
+	 * 
+	 * @param f
+	 * @param parent
+	 * @param dir
+	 */
+	public ImageFile(File f, ImageSet parent, Directory dir) {
+		this.file = f;
+		this.name = f.getName();
 		this.parent = parent;
 		this.dir = dir;
 	}
 	
-	public ImageFile(String fn) {
-		File f = new File(fn);
-		this.dir = new Directory(f.getParentFile());
-		this.filename = f.getName();
+	/** Constructor with filename (without path).
+	 * @param fn
+	 * @param parent
+	 * @param dir
+	 */
+	public ImageFile(String fn, ImageSet parent, Directory dir) {
+		this.name = fn;
+		this.dir = dir;
+		this.file = new File(this.dir.getDir(), fn);
+		this.parent = parent;
+	}
+	
+	
+	/** Checks the image and sets size and type.
+	 * 
+	 */
+	public void check() {
+	    if (pixelSize == null) {
+	        try {
+	            // use the configured toolkit to identify the image
+                DigilibConfiguration.identifyDocuImage(this);
+            } catch (IOException e) {
+                // nothing much to do...
+            }
+	    }
 	}
 	
-	/** Returns the file name (without path).
+	/* (non-Javadoc)
+     * @see digilib.io.ImageInput#getSize()
+     */
+    @Override
+    public ImageSize getSize() {
+        check();
+        return pixelSize;
+    }
+
+    /* (non-Javadoc)
+     * @see digilib.io.ImageInput#getMimetype()
+     */
+    @Override
+    public String getMimetype() {
+        check();
+        return mimetype;
+    }
+
+    /* (non-Javadoc)
+     * @see digilib.io.ImageInput#getAspect()
+     */
+    @Override
+    public float getAspect() {
+        check();
+        return (pixelSize != null) ? pixelSize.getAspect() : 0f;
+    }
+
+    /** Returns the file name (without path).
 	 * 
 	 * @return
 	 */
 	public String getName() {
-		return filename;
+		return name;
 	}
 
-
 	/**
 	 * @return File
 	 */
 	public File getFile() {
-		if (dir == null) {
-			return null;
-		}
-		File f = new File(dir.getDir(), filename);
-		return f;
+		return file;
 	}
 
 	/**
-	 * @return ImageSize
+	 * @return ImageSet
 	 */
-	public ImageSize getSize() {
-		return pixelSize;
+	public ImageSet getParent() {
+		return parent;
 	}
 
 	/**
-	 * @return String
+	 * Sets the parent.
+	 * @param parent The parent to set
 	 */
-	public String getMimetype() {
-		return mimetype;
+	public void setParent(ImageSet parent) {
+		this.parent = parent;
 	}
 
-	/**
-	 * Sets the imageSize.
-	 * @param imageSize The imageSize to set
+	/* (non-Javadoc)
+	 * @see digilib.io.ImageInput#setSize(digilib.image.ImageSize)
 	 */
 	public void setSize(ImageSize imageSize) {
 		this.pixelSize = imageSize;
@@ -99,42 +149,17 @@
 		}
 	}
 
-	/**
-	 * Sets the mimetype.
-	 * @param mimetype The mimetype to set
-	 */
-	public void setMimetype(String filetype) {
-		this.mimetype = filetype;
-	}
-
-	/**
-	 * @return ImageFileset
-	 */
-	public ImageFileset getParent() {
-		return parent;
-	}
+    /* (non-Javadoc)
+     * @see java.lang.Object#toString()
+     */
+    @Override
+    public String toString() {
+        // try to use File.toString
+        if (file != null) {
+            return file.toString();
+        }
+        return super.toString();
+    }
 
-	/**
-	 * Sets the parent.
-	 * @param parent The parent to set
-	 */
-	public void setParent(ImageFileset parent) {
-		this.parent = parent;
-	}
-
-	/**
-	 * @return boolean
-	 */
-	public boolean isChecked() {
-		return (pixelSize != null);
-	}
 	
-	/** Returns the aspect ratio of the image (width/height).
-	 * 
-	 * @return
-	 */
-	public float getAspect() {
-		return (pixelSize != null) ? pixelSize.getAspect() : 0;
-	}
-
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/servlet/src/digilib/io/ImageFileSet.java	Wed Jan 05 14:46:19 2011 +0100
@@ -0,0 +1,305 @@
+/**
+ * 
+ */
+package digilib.io;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Map;
+
+import org.apache.log4j.Logger;
+
+import digilib.io.FileOps.FileClass;
+
+/**
+ * @author casties
+ *
+ */
+public class ImageFileSet extends ImageSet implements DocuDirent {
+
+    /** this is an image file */
+    protected static FileClass fileClass = FileClass.IMAGE;
+    /** the (main) file */
+    protected File file = null;
+    /** the file name */
+    protected String name = null;
+	/** HashMap with metadata */
+	protected MetadataMap fileMeta = null;
+	/** Is the Metadata valid */
+	protected boolean metaChecked = false;
+	/** the parent directory */
+	protected Directory parentDir = null;
+    
+    /**
+     * Constructor with a File and Directories.
+     * 
+     * @param file
+     * @param scaleDirs
+     */
+    public ImageFileSet(File file, Directory[] scaleDirs) {
+        int nb = scaleDirs.length;
+        list = new ArrayList<ImageInput>(nb);
+        // first dir is our parent
+        parentDir = scaleDirs[0];
+        this.file = file;
+        this.name = file.getName();
+        fill(scaleDirs, file);
+    }
+
+    /* (non-Javadoc)
+     * @see digilib.io.DocuDirent#getName()
+     */
+    public String getName() {
+    	return this.name;
+    }
+
+    /* (non-Javadoc)
+     * @see digilib.io.DocuDirent#getParent()
+     */
+    public Directory getParent() {
+    	return this.parentDir;
+    }
+
+    /* (non-Javadoc)
+     * @see digilib.io.DocuDirent#setParent(digilib.io.Directory)
+     */
+    public void setParent(Directory parent) {
+    	this.parentDir = parent;
+    }
+
+    /* (non-Javadoc)
+     * @see digilib.io.DocuDirent#getFileMeta()
+     */
+    public MetadataMap getFileMeta() {
+    	return this.fileMeta;
+    }
+
+    /* (non-Javadoc)
+     * @see digilib.io.DocuDirent#setFileMeta(digilib.io.MetadataMap)
+     */
+    public void setFileMeta(MetadataMap fileMeta) {
+    	this.fileMeta = fileMeta;
+    }
+
+    /* (non-Javadoc)
+     * @see digilib.io.DocuDirent#isMetaChecked()
+     */
+    public boolean isMetaChecked() {
+    	return this.metaChecked;
+    }
+
+    /* (non-Javadoc)
+     * @see digilib.io.DocuDirent#compareTo(java.lang.Object)
+     */
+    public int compareTo(Object arg0) {
+		if (arg0 instanceof DocuDirent) {
+		    return name.compareTo(((DocuDirent) arg0).getName());
+		} else {
+		    return getName().compareTo((String) arg0);
+		}
+    }
+
+    /* (non-Javadoc)
+     * @see digilib.io.DocuDirent#getFile()
+     */
+    public File getFile() {
+        return file;
+    }
+
+    /**
+     * Adds an ImageFile to this Fileset.
+     * 
+     * The files should be added in the order of higher to lower resolutions.
+     * The first file is considered the hires "original".
+     * 
+     * 
+     * @param f
+     *            file to add
+     * @return true (always)
+     */
+    public boolean add(ImageFile f) {
+    	f.setParent(this);
+    	return list.add(f);
+    }
+
+    /**
+     * Fill the ImageSet with files from different base directories.
+     * 
+     * 
+     * @param dirs
+     *            list of base directories
+     * @param fl
+     *            file (from first base dir)
+     * @param hints
+     *  
+     */
+    void fill(Directory[] dirs, File fl) {
+    	String fn = fl.getName();
+    	String baseFn = FileOps.basename(fn);
+    	// add the first ImageFile to the ImageSet
+    	add(new ImageFile(fl, this, parentDir));
+    	// iterate the remaining base directories
+    	for (int i = 1; i < dirs.length; ++i) {
+    	    Directory dir = dirs[i];
+    		if (dir == null) {
+    			continue;
+    		}
+    		// read the directory
+    		if (dir.getFilenames() == null) {
+    			dir.readDir();
+    		}
+    		String[] dirFiles = dir.getFilenames();
+    		// try the same filename as the original
+    		int fileIdx = Arrays.binarySearch(dirFiles, fn);
+    		if (fileIdx < 0) {
+    			// try closest matches without extension
+    			fileIdx = -fileIdx - 1;
+    			// try idx
+    			if ((fileIdx < dirFiles.length)
+    					&& (FileOps.basename(dirFiles[fileIdx]).equals(baseFn))) {
+    				// idx ok
+    			} else if ((fileIdx > 0)
+    					&& (FileOps.basename(dirFiles[fileIdx - 1])
+    							.equals(baseFn))) {
+    				// idx-1 ok
+    				fileIdx = fileIdx - 1;
+    			} else if ((fileIdx+1 < dirFiles.length)
+    					&& (FileOps.basename(dirFiles[fileIdx + 1])
+    							.equals(baseFn))) {
+    				// idx+1 ok
+    				fileIdx = fileIdx + 1;
+    			} else {
+    				// basename doesn't match
+    				continue;
+    			}
+    		}
+    		if (FileOps.classForFilename(dirFiles[fileIdx]) == fileClass) {
+    			/* logger.debug("adding file " + dirFiles[fileIdx]
+    					+ " to Fileset " + this.getName()); */
+    			add(new ImageFile(dirFiles[fileIdx], this, dir));
+    		}
+    	}
+    }
+
+    /**
+     * Checks metadata and sets resolution in resX and resY.
+     *  
+     */
+    public void checkMeta() {
+        if (metaChecked) {
+            return;
+        }
+        if (fileMeta == null) {
+            // try to read metadata file
+            readMeta();
+            if (fileMeta == null) {
+                // try directory metadata
+                ((DocuDirectory) parentDir).checkMeta();
+                if (((DocuDirectory) parentDir).getDirMeta() != null) {
+                    fileMeta = ((DocuDirectory) parentDir).getDirMeta();
+                } else {
+                    // try parent directory metadata
+                    DocuDirectory gp = (DocuDirectory) parentDir.getParent();
+                    if (gp != null) {
+                        gp.checkMeta();
+                        if (gp.getDirMeta() != null) {
+                            fileMeta = gp.getDirMeta();
+                        }
+                    }
+                }
+            }
+        }
+        if (fileMeta == null) {
+            // no metadata available
+            metaChecked = true;
+            return;
+        }
+        metaChecked = true;
+        float dpi = 0;
+        float dpix = 0;
+        float dpiy = 0;
+        float sizex = 0;
+        float sizey = 0;
+        float pixx = 0;
+        float pixy = 0;
+        // DPI is valid for X and Y
+        if (fileMeta.containsKey("original-dpi")) {
+            try {
+                dpi = Float.parseFloat((String) fileMeta.get("original-dpi"));
+            } catch (NumberFormatException e) {
+            }
+            if (dpi != 0) {
+                resX = dpi;
+                resY = dpi;
+                return;
+            }
+        }
+        // DPI-X and DPI-Y
+        if (fileMeta.containsKey("original-dpi-x")
+                && fileMeta.containsKey("original-dpi-y")) {
+            try {
+                dpix = Float.parseFloat((String) fileMeta
+                        .get("original-dpi-x"));
+                dpiy = Float.parseFloat((String) fileMeta
+                        .get("original-dpi-y"));
+            } catch (NumberFormatException e) {
+            }
+            if ((dpix != 0) && (dpiy != 0)) {
+                resX = dpix;
+                resY = dpiy;
+                return;
+            }
+        }
+        // SIZE-X and SIZE-Y and PIXEL-X and PIXEL-Y
+        if (fileMeta.containsKey("original-size-x")
+                && fileMeta.containsKey("original-size-y")
+                && fileMeta.containsKey("original-pixel-x")
+                && fileMeta.containsKey("original-pixel-y")) {
+            try {
+                sizex = Float.parseFloat((String) fileMeta
+                        .get("original-size-x"));
+                sizey = Float.parseFloat((String) fileMeta
+                        .get("original-size-y"));
+                pixx = Float.parseFloat((String) fileMeta
+                        .get("original-pixel-x"));
+                pixy = Float.parseFloat((String) fileMeta
+                        .get("original-pixel-y"));
+            } catch (NumberFormatException e) {
+            }
+            if ((sizex != 0) && (sizey != 0) && (pixx != 0) && (pixy != 0)) {
+                resX = pixx / (sizex * 100 / 2.54f);
+                resY = pixy / (sizey * 100 / 2.54f);
+                return;
+            }
+        }
+    }
+
+	/* (non-Javadoc)
+     * @see digilib.io.DocuDirent#readMeta()
+     */
+	public void readMeta() {
+		if ((fileMeta != null) || (file == null)) {
+			// there is already metadata or there is no file
+			return;
+		}
+		// metadata is in the file {filename}.meta
+		String fn = file.getAbsolutePath();
+		File mf = new File(fn + ".meta");
+		if (mf.canRead()) {
+			XMLMetaLoader ml = new XMLMetaLoader();
+			try {
+				// read meta file
+				Map<String, MetadataMap> meta = ml.loadURL(mf.getAbsolutePath());
+				if (meta == null) {
+					return;
+				}
+				fileMeta = meta.get(name);
+			} catch (Exception e) {
+				Logger.getLogger(this.getClass()).warn("error reading file .meta", e);
+			}
+		}
+	}
+
+
+}
--- a/servlet/src/digilib/io/ImageFileset.java	Wed Jan 05 14:44:19 2011 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,414 +0,0 @@
-/* ImageFileset -- digilib image file info class.  
- * Digital Image Library servlet components  
- * Copyright (C) 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 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.io;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Iterator;
-import java.util.List;
-import java.util.ListIterator;
-import java.util.Map;
-
-import digilib.image.ImageSize;
-import digilib.io.FileOps.FileClass;
-import digilib.servlet.DigilibConfiguration;
-
-/**
- * @author casties
- */
-public class ImageFileset extends DocuDirent {
-
-	/** this is an image file */
-	protected static FileClass fileClass = FileClass.IMAGE;
-	
-	/** list of files (ImageFile) */
-	private List<ImageFile> list = null;
-
-	/** aspect ratio (width/height) */
-	private float aspect = 0;
-
-	/** resolution of the biggest image (DPI) */
-	private float resX = 0;
-
-	/** resolution of the biggest image (DPI) */
-	private float resY = 0;
-
-	/**
-	 * Creator for empty fileset.
-	 * 
-	 * 
-	 * @param initialCapacity
-	 */
-	public ImageFileset() {
-		list = new ArrayList<ImageFile>();
-	}
-
-	/**
-	 * Constructor with a file and hints.
-	 * 
-	 * The hints are expected to contain 'basedirs' and 'scaledfilext' keys.
-	 * 
-	 * @param file
-	 * @param hints
-	 */
-	public ImageFileset(File file, Map<Integer,Object> hints) {
-		Directory[] dirs = (Directory[]) hints.get(FileOps.HINT_BASEDIRS);
-		int nb = dirs.length;
-		list = new ArrayList<ImageFile>(nb);
-		parent = dirs[0];
-		fill(dirs, file, hints);
-	}
-
-	/**
-	 * Adds an ImageFile to this Fileset.
-	 * 
-	 * The files should be added in the order of higher to lower resolutions.
-	 * The first file is considered the hires "original".
-	 * 
-	 * 
-	 * @param f
-	 *            file to add
-	 * @return true (always)
-	 */
-	public boolean add(ImageFile f) {
-		f.setParent(this);
-		return list.add(f);
-	}
-
-	/**
-	 * The number of image files in this Fileset.
-	 * 
-	 * 
-	 * @return number of image files
-	 */
-	public int size() {
-		return (list != null) ? list.size() : 0;
-	}
-
-	/**
-	 * Gets the default File.
-	 *  
-	 */
-	public File getFile() {
-		return (list != null) ? list.get(0).getFile() : null;
-	}
-
-	/**
-	 * Get the ImageFile at the index.
-	 * 
-	 * 
-	 * @param index
-	 * @return
-	 */
-	public ImageFile get(int index) {
-		return list.get(index);
-	}
-
-	/**
-	 * Get the next smaller ImageFile than the given size.
-	 * 
-	 * Returns the ImageFile from the set that has a width and height smaller or
-	 * equal the given size. Returns null if there isn't any smaller image.
-	 * Needs DocuInfo instance to checkFile().
-	 * 
-	 * 
-	 * @param size
-	 * @param info
-	 * @return
-	 */
-	public ImageFile getNextSmaller(ImageSize size) {
-		for (Iterator<ImageFile> i = getHiresIterator(); i.hasNext();) {
-			ImageFile f = i.next();
-			try {
-				if (!f.isChecked()) {
-					DigilibConfiguration.docuImageIdentify(f);
-				}
-				if (f.getSize().isTotallySmallerThan(size)) {
-					return f;
-				}
-			} catch (IOException e) {
-			}
-		}
-		return null;
-	}
-
-	/**
-	 * Get the next bigger ImageFile than the given size.
-	 * 
-	 * Returns the ImageFile from the set that has a width or height bigger or
-	 * equal the given size. Returns null if there isn't any bigger image. Needs
-	 * DocuInfo instance to checkFile().
-	 * 
-	 * 
-	 * @param size
-	 * @param info
-	 * @return
-	 */
-	public ImageFile getNextBigger(ImageSize size) {
-		for (ListIterator<ImageFile> i = getLoresIterator(); i.hasPrevious();) {
-			ImageFile f = i.previous();
-			try {
-				if (!f.isChecked()) {
-					DigilibConfiguration.docuImageIdentify(f);
-				}
-				if (f.getSize().isBiggerThan(size)) {
-					return f;
-				}
-			} catch (IOException e) {
-			}
-		}
-		return null;
-	}
-
-	/**
-	 * Returns the biggest ImageFile in the set.
-	 * 
-	 * 
-	 * @return
-	 */
-	public ImageFile getBiggest() {
-		return this.get(0);
-	}
-
-	/**
-	 * Returns the biggest ImageFile in the set.
-	 * 
-	 * 
-	 * @return
-	 */
-	public ImageFile getSmallest() {
-		return this.get(this.size() - 1);
-	}
-
-	/**
-	 * Get an Iterator for this Fileset starting at the highest resolution
-	 * images.
-	 * 
-	 * 
-	 * @return
-	 */
-	public ListIterator<ImageFile> getHiresIterator() {
-		return list.listIterator();
-	}
-
-	/**
-	 * Get an Iterator for this Fileset starting at the lowest resolution
-	 * images.
-	 * 
-	 * The Iterator starts at the last element, so you have to use it backwards
-	 * with hasPrevious() and previous().
-	 * 
-	 * 
-	 * @return
-	 */
-	public ListIterator<ImageFile> getLoresIterator() {
-		return list.listIterator(list.size());
-	}
-
-	/**
-	 * Fill the ImageFileset with files from different base directories.
-	 * 
-	 * 
-	 * @param dirs
-	 *            list of base directories
-	 * @param fl
-	 *            file (from first base dir)
-	 * @param hints
-	 *  
-	 */
-	void fill(Directory[] dirs, File fl, Map<Integer,Object> hints) {
-		int nb = dirs.length;
-		String fn = fl.getName();
-		String baseFn = FileOps.basename(fn);
-		// add the first ImageFile to the ImageFileset
-		add(new ImageFile(fn, this, parent));
-		// iterate the remaining base directories
-		for (int dirIdx = 1; dirIdx < nb; dirIdx++) {
-			if (dirs[dirIdx] == null) {
-				continue;
-			}
-			// read the directory
-			if (dirs[dirIdx].getFilenames() == null) {
-				dirs[dirIdx].readDir();
-			}
-			String[] dirFiles = dirs[dirIdx].getFilenames();
-			// try the same filename as the original
-			int fileIdx = Arrays.binarySearch(dirFiles, fn);
-			if (fileIdx < 0) {
-				// try closest matches without extension
-				fileIdx = -fileIdx - 1;
-				// try idx
-				if ((fileIdx < dirFiles.length)
-						&& (FileOps.basename(dirFiles[fileIdx]).equals(baseFn))) {
-					// idx ok
-				} else if ((fileIdx > 0)
-						&& (FileOps.basename(dirFiles[fileIdx - 1])
-								.equals(baseFn))) {
-					// idx-1 ok
-					fileIdx = fileIdx - 1;
-				} else if ((fileIdx+1 < dirFiles.length)
-						&& (FileOps.basename(dirFiles[fileIdx + 1])
-								.equals(baseFn))) {
-					// idx+1 ok
-					fileIdx = fileIdx + 1;
-				} else {
-					// basename doesn't match
-					continue;
-				}
-			}
-			if (FileOps.classForFilename(dirFiles[fileIdx]) == fileClass) {
-				/* logger.debug("adding file " + dirFiles[fileIdx]
-						+ " to Fileset " + this.getName()); */
-				add(new ImageFile(dirFiles[fileIdx], this, dirs[dirIdx]));
-			}
-		}
-	}
-
-	/**
-	 * Checks metadata and sets resolution in resX and resY.
-	 *  
-	 */
-	public void checkMeta() {
-		if (metaChecked) {
-			return;
-		}
-		if (fileMeta == null) {
-			// try to read metadata file
-			readMeta();
-			if (fileMeta == null) {
-				// try directory metadata
-				((DocuDirectory) parent).checkMeta();
-				if (((DocuDirectory) parent).getDirMeta() != null) {
-					fileMeta = ((DocuDirectory) parent).getDirMeta();
-				} else {
-					// try parent directory metadata
-					DocuDirectory gp = (DocuDirectory) parent.getParent();
-					if (gp != null) {
-						gp.checkMeta();
-						if (gp.getDirMeta() != null) {
-							fileMeta = gp.getDirMeta();
-						}
-					}
-				}
-			}
-		}
-		if (fileMeta == null) {
-			// no metadata available
-			metaChecked = true;
-			return;
-		}
-		metaChecked = true;
-		float dpi = 0;
-		float dpix = 0;
-		float dpiy = 0;
-		float sizex = 0;
-		float sizey = 0;
-		float pixx = 0;
-		float pixy = 0;
-		// DPI is valid for X and Y
-		if (fileMeta.containsKey("original-dpi")) {
-			try {
-				dpi = Float.parseFloat((String) fileMeta.get("original-dpi"));
-			} catch (NumberFormatException e) {
-			}
-			if (dpi != 0) {
-				resX = dpi;
-				resY = dpi;
-				return;
-			}
-		}
-		// DPI-X and DPI-Y
-		if (fileMeta.containsKey("original-dpi-x")
-				&& fileMeta.containsKey("original-dpi-y")) {
-			try {
-				dpix = Float.parseFloat((String) fileMeta
-						.get("original-dpi-x"));
-				dpiy = Float.parseFloat((String) fileMeta
-						.get("original-dpi-y"));
-			} catch (NumberFormatException e) {
-			}
-			if ((dpix != 0) && (dpiy != 0)) {
-				resX = dpix;
-				resY = dpiy;
-				return;
-			}
-		}
-		// SIZE-X and SIZE-Y and PIXEL-X and PIXEL-Y
-		if (fileMeta.containsKey("original-size-x")
-				&& fileMeta.containsKey("original-size-y")
-				&& fileMeta.containsKey("original-pixel-x")
-				&& fileMeta.containsKey("original-pixel-y")) {
-			try {
-				sizex = Float.parseFloat((String) fileMeta
-						.get("original-size-x"));
-				sizey = Float.parseFloat((String) fileMeta
-						.get("original-size-y"));
-				pixx = Float.parseFloat((String) fileMeta
-						.get("original-pixel-x"));
-				pixy = Float.parseFloat((String) fileMeta
-						.get("original-pixel-y"));
-			} catch (NumberFormatException e) {
-			}
-			if ((sizex != 0) && (sizey != 0) && (pixx != 0) && (pixy != 0)) {
-				resX = pixx / (sizex * 100 / 2.54f);
-				resY = pixy / (sizey * 100 / 2.54f);
-				return;
-			}
-		}
-	}
-
-	/**
-	 * @return
-	 */
-	public float getResX() {
-		return resX;
-	}
-
-	/**
-	 * @return
-	 */
-	public float getResY() {
-		return resY;
-	}
-
-	/**
-	 * Sets the aspect ratio from an ImageSize.
-	 * 
-	 * 
-	 * @param f
-	 */
-	public void setAspect(ImageSize s) {
-		aspect = s.getAspect();
-	}
-
-	/**
-	 * Returns the aspect ratio.
-	 * 
-	 * Aspect ratio is (width/height). So it's <1 for portrait and >1 for
-	 * landscape.
-	 * 
-	 * 
-	 * @return
-	 */
-	public float getAspect() {
-		return aspect;
-	}
-
-}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/servlet/src/digilib/io/ImageInput.java	Wed Jan 05 14:46:19 2011 +0100
@@ -0,0 +1,80 @@
+/* ImageInput-- digilib image input interface.
+
+  Digital Image Library servlet components
+
+  Copyright (C) 2010 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
+
+ * Created on 20.12.2010
+ */
+
+package digilib.io;
+
+import digilib.image.ImageSize;
+
+public abstract class ImageInput {
+
+	// mime file type
+	protected String mimetype = null;
+	// image size in pixels
+	protected ImageSize pixelSize = null;
+
+	/**
+	 * @return ImageSize
+	 */
+	public ImageSize getSize() {
+		return pixelSize;
+	}
+
+	/**
+	 * Sets the imageSize.
+	 * @param imageSize The imageSize to set
+	 */
+	public void setSize(ImageSize imageSize) {
+		this.pixelSize = imageSize;
+	}
+
+	/**
+	 * @return String
+	 */
+	public String getMimetype() {
+		return mimetype;
+	}
+
+	/**
+	 * Sets the mimetype.
+	 * @param mimetype The mimetype to set
+	 */
+	public void setMimetype(String filetype) {
+		this.mimetype = filetype;
+	}
+
+	/** returns if this image has been checked 
+	 * (i.e. has size and mimetype)
+	 * TODO: deprecated
+	 * @return boolean
+	 */
+	public boolean isChecked() {
+		return (pixelSize != null);
+	}
+	
+	/** Returns the aspect ratio of the image (width/height).
+	 * 
+	 * @return
+	 */
+	public float getAspect() {
+		return (pixelSize != null) ? pixelSize.getAspect() : 0f;
+	}
+	
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/servlet/src/digilib/io/ImageSet.java	Wed Jan 05 14:46:19 2011 +0100
@@ -0,0 +1,209 @@
+/* ImageSet -- digilib image file info class.  
+ * Digital Image Library servlet components  
+ * Copyright (C) 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 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.io;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.ListIterator;
+
+import digilib.image.ImageSize;
+
+/**
+ * @author casties
+ */
+public class ImageSet {
+
+	/** list of files (ImageFile) */
+	protected List<ImageInput> list = null;
+
+	/** aspect ratio (width/height) */
+	protected float aspect = 0f;
+
+	/** resolution of the biggest image (DPI) */
+	protected float resX = 0f;
+
+	/** resolution of the biggest image (DPI) */
+	protected float resY = 0f;
+
+	/**
+	 * Creator for empty fileset.
+	 * 
+	 * 
+	 * @param initialCapacity
+	 */
+	public ImageSet() {
+		list = new ArrayList<ImageInput>();
+	}
+
+	/**
+	 * The number of image files in this Fileset.
+	 * 
+	 * 
+	 * @return number of image files
+	 */
+	public int size() {
+		return (list != null) ? list.size() : 0;
+	}
+
+	/**
+	 * Gets the default Input.
+	 *  
+	 */
+	public ImageInput get() {
+		return (list != null) ? list.get(0) : null;
+	}
+
+	/**
+	 * Get the ImageFile at the index.
+	 * 
+	 * 
+	 * @param index
+	 * @return
+	 */
+	public ImageInput get(int index) {
+		return list.get(index);
+	}
+
+	/**
+	 * Get the next smaller ImageFile than the given size.
+	 * 
+	 * Returns the ImageFile from the set that has a width and height smaller or
+	 * equal the given size. Returns null if there isn't any smaller image.
+	 * 
+	 * @param size
+	 * @param info
+	 * @return
+	 */
+	public ImageInput getNextSmaller(ImageSize size) {
+		for (ListIterator<ImageInput> i = getHiresIterator(); i.hasNext();) {
+			ImageInput f = i.next();
+			if (f.getSize().isTotallySmallerThan(size)) {
+				return f;
+			}
+		}
+		return null;
+	}
+
+	/**
+	 * Get the next bigger ImageFile than the given size.
+	 * 
+	 * Returns the ImageFile from the set that has a width or height bigger or
+	 * equal the given size. Returns null if there isn't any bigger image.
+	 * 
+	 * @param size
+	 * @param info
+	 * @return
+	 */
+	public ImageInput getNextBigger(ImageSize size) {
+		for (ListIterator<ImageInput> i = getLoresIterator(); i.hasPrevious();) {
+			ImageInput f = i.previous();
+			if (f.getSize().isBiggerThan(size)) {
+				return f;
+			}
+		}
+		return null;
+	}
+
+	/**
+	 * Returns the biggest ImageFile in the set.
+	 * 
+	 * 
+	 * @return
+	 */
+	public ImageInput getBiggest() {
+		return this.get(0);
+	}
+
+	/**
+	 * Returns the biggest ImageFile in the set.
+	 * 
+	 * 
+	 * @return
+	 */
+	public ImageInput getSmallest() {
+		return this.get(this.size() - 1);
+	}
+
+	/**
+	 * Get an Iterator for this Fileset starting at the highest resolution
+	 * images.
+	 * 
+	 * 
+	 * @return
+	 */
+	public ListIterator<ImageInput> getHiresIterator() {
+		return list.listIterator();
+	}
+
+	/**
+	 * Get an Iterator for this Fileset starting at the lowest resolution
+	 * images.
+	 * 
+	 * The Iterator starts at the last element, so you have to use it backwards
+	 * with hasPrevious() and previous().
+	 * 
+	 * 
+	 * @return
+	 */
+	public ListIterator<ImageInput> getLoresIterator() {
+		return list.listIterator(list.size());
+	}
+
+	/**
+	 * @return
+	 */
+	public float getResX() {
+		return resX;
+	}
+
+	/**
+	 * @return
+	 */
+	public float getResY() {
+		return resY;
+	}
+
+	/**
+	 * Sets the aspect ratio from an ImageSize.
+	 * 
+	 * 
+	 * @param f
+	 */
+	public void setAspect(ImageSize s) {
+		aspect = s.getAspect();
+	}
+
+	/**
+	 * Returns the aspect ratio.
+	 * 
+	 * Aspect ratio is (width/height). So it's <1 for portrait and >1 for
+	 * landscape.
+	 * 
+	 * 
+	 * @return
+	 */
+	public float getAspect() {
+		return aspect;
+	}
+
+    public void checkMeta() {
+        // TODO Auto-generated method stub
+        
+    }
+
+}
\ No newline at end of file
--- a/servlet/src/digilib/io/SVGFile.java	Wed Jan 05 14:44:19 2011 +0100
+++ b/servlet/src/digilib/io/SVGFile.java	Wed Jan 05 14:46:19 2011 +0100
@@ -30,7 +30,7 @@
  * @author casties
  *
  */
-public class SVGFile extends DocuDirent {
+public class SVGFile extends DocuDirentImpl {
 	/** this is a text file */
 	protected static FileClass fileClass = FileClass.SVG;
 	/** our File instance */
--- a/servlet/src/digilib/io/TextFile.java	Wed Jan 05 14:44:19 2011 +0100
+++ b/servlet/src/digilib/io/TextFile.java	Wed Jan 05 14:46:19 2011 +0100
@@ -30,7 +30,7 @@
  * @author casties
  *
  */
-public class TextFile extends DocuDirent {
+public class TextFile extends DocuDirentImpl {
 	/** this is a text file */
 	protected static FileClass fileClass = FileClass.TEXT;
 	/** our File instance */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/servlet/src/digilib/pdf/DigilibInfoReader.java	Wed Jan 05 14:46:19 2011 +0100
@@ -0,0 +1,76 @@
+package digilib.pdf;
+
+/** DigilibInfoReader 
+ * A class for reading the information from info.xml files used in digilib image directories.
+ *
+ */
+
+import java.io.File;
+import java.util.List;
+
+import org.apache.log4j.Logger;
+import org.jdom.Document;
+import org.jdom.Element;
+import org.jdom.input.SAXBuilder;
+
+
+
+public class DigilibInfoReader {
+
+	/** gengeral logger for this class */
+	protected static Logger logger = Logger.getLogger("digilib.servlet");
+	
+	private String filename = null;
+	//private static String base_element = "info";
+	
+	public DigilibInfoReader(String fn){
+		filename = fn;
+	}
+
+	/**
+	 * Returns the attribute defined by 'attr' as a String.
+	 * 
+	 * @param attr
+	 * @return
+	 */
+	@SuppressWarnings("unchecked") // Element.getChildren() returns naked List
+    public String getAsString(String attr){
+		try{
+			SAXBuilder builder = new SAXBuilder();
+			Document doc = builder.build(new File(filename));
+			Element root = doc.getRootElement();
+			List<Element> mainElements = root.getChildren();
+			// logger.debug("XML mainElements:"+mainElements.toString());
+
+			for(int i=0; i<mainElements.size(); i++){
+				Element elem = mainElements.get(i);
+				if(elem.getName()==attr){
+					// logger.debug(attr+" == "+(String)elem.getTextTrim());
+					return (String)elem.getTextTrim();
+				}
+			}
+
+		}
+		catch(Exception e){
+			logger.error(e.getMessage());
+		}
+		return null;
+	}
+	
+	
+	/**
+	 * Find out if the info.xml exists
+	 * @return
+	 */
+	public boolean hasInfo(){
+		try {
+			SAXBuilder builder = new SAXBuilder();
+			builder.build(new File(filename));
+			return true;
+		}
+		catch(Exception e){
+			return false;
+		}
+	}
+	
+}
--- a/servlet/src/digilib/pdf/PDFTitlePage.java	Wed Jan 05 14:44:19 2011 +0100
+++ b/servlet/src/digilib/pdf/PDFTitlePage.java	Wed Jan 05 14:46:19 2011 +0100
@@ -15,7 +15,6 @@
 import com.itextpdf.text.Paragraph;
 
 
-import digilib.io.DigilibInfoReader;
 import digilib.io.DocuDirCache;
 import digilib.servlet.PDFCache;
 import digilib.servlet.PDFRequest;
--- a/servlet/src/digilib/servlet/DigilibConfiguration.java	Wed Jan 05 14:44:19 2011 +0100
+++ b/servlet/src/digilib/servlet/DigilibConfiguration.java	Wed Jan 05 14:46:19 2011 +0100
@@ -36,6 +36,7 @@
 import digilib.image.DocuImageImpl;
 import digilib.io.FileOps;
 import digilib.io.ImageFile;
+import digilib.io.ImageInput;
 import digilib.io.XMLListLoader;
 import digilib.util.Parameter;
 import digilib.util.ParameterMap;
@@ -277,7 +278,7 @@
 	 * @return
 	 * @throws IOException
 	 */
-	public static ImageFile docuImageIdentify(ImageFile imgf) throws IOException {
+	public static ImageInput identifyDocuImage(ImageFile imgf) throws IOException {
 	    // use fresh DocuImage instance
 	    DocuImage di = getDocuImageInstance();
 		return di.identify(imgf);
--- a/servlet/src/digilib/servlet/DocumentBean.java	Wed Jan 05 14:44:19 2011 +0100
+++ b/servlet/src/digilib/servlet/DocumentBean.java	Wed Jan 05 14:46:19 2011 +0100
@@ -38,7 +38,8 @@
 import digilib.io.DocuDirectory;
 import digilib.io.FileOps.FileClass;
 import digilib.io.ImageFile;
-import digilib.io.ImageFileset;
+import digilib.io.ImageInput;
+import digilib.io.ImageSet;
 
 public class DocumentBean {
 
@@ -191,13 +192,13 @@
 		}
 		String fn = dlRequest.getFilePath();
 		// get information about the file
-		ImageFileset fileset = (ImageFileset) dirCache.getFile(fn, dlRequest
+		ImageSet fileset = (ImageSet) dirCache.getFile(fn, dlRequest
 				.getAsInt("pn"), FileClass.IMAGE);
 		if (fileset == null) {
 			return;
 		}
 		// add file name
-		dlRequest.setValue("img.fn", fileset.getName());
+		dlRequest.setValue("img.fn", fileset);
 		// add dpi
 		dlRequest.setValue("img.dpix", new Double(fileset.getResX()));
 		dlRequest.setValue("img.dpiy", new Double(fileset.getResY()));
@@ -208,12 +209,8 @@
 			dlRequest.setValue("pt", dd.size());
 		}
 		// get original pixel size
-		ImageFile origfile = fileset.getBiggest();
-		// check image for size if mo=hires
-		if ((! origfile.isChecked())&&dlRequest.hasOption("hires")) {
-			logger.debug("pre-checking image!");
-			DigilibConfiguration.docuImageIdentify(origfile);
-		}
+		ImageInput origfile = fileset.getBiggest();
+		// check image for size (TODO: just if mo=hires?)
 		ImageSize pixsize = origfile.getSize();
 		if (pixsize != null) {
 			// add pixel size
--- a/servlet/src/digilib/servlet/Scaler.java	Wed Jan 05 14:44:19 2011 +0100
+++ b/servlet/src/digilib/servlet/Scaler.java	Wed Jan 05 14:46:19 2011 +0100
@@ -32,7 +32,7 @@
 public class Scaler extends HttpServlet {
 
     /** digilib servlet version (for all components) */
-    public static final String version = "1.8.2b";
+    public static final String version = "1.9.0a";
 
     /** servlet error codes */
     public static enum Error {UNKNOWN, AUTH, FILE, IMAGE};
@@ -195,7 +195,7 @@
         	/*
         	 *  check if we can fast-track without scaling
         	 */
-            ImageFile fileToLoad = jobTicket.getFileToLoad();
+            ImageFile fileToLoad = (ImageFile) jobTicket.getFileToLoad();
 
             // check permissions
             if (useAuthorization) {
--- a/servlet/src/digilib/servlet/Texter.java	Wed Jan 05 14:44:19 2011 +0100
+++ b/servlet/src/digilib/servlet/Texter.java	Wed Jan 05 14:46:19 2011 +0100
@@ -30,7 +30,6 @@
 import digilib.auth.AuthOps;
 import digilib.image.ImageOpException;
 import digilib.io.DocuDirCache;
-import digilib.io.FileOpException;
 import digilib.io.FileOps;
 import digilib.io.FileOps.FileClass;
 import digilib.io.TextFile;
@@ -128,33 +127,33 @@
 		processRequest(request, response);
 	}
 
-    protected void processRequest(HttpServletRequest request,
-            HttpServletResponse response) throws ServletException, IOException {
-
-        /*
-         * request parameters
-         */
+	protected void processRequest(HttpServletRequest request,
+			HttpServletResponse response) throws ServletException, IOException {
+		
+		/*
+		 * request parameters
+		 */
         // create new request with defaults
         DigilibRequest dlRequest = new DigilibRequest(request);
-        try {
-            /*
-             * find the file to load/send
-             */
-            TextFile f = getTextFile(dlRequest, "/txt");
-            if (f != null) {
-                ServletOps.sendFile(f.getFile(), null, null, response, logger);
-            } else {
-                f = getTextFile(dlRequest, "");
-                if (f != null) {
-                    ServletOps.sendFile(f.getFile(), null, null, response, logger);
-                } else {
-                    response.sendError(HttpServletResponse.SC_NOT_FOUND,
-                            "Text-File not found!");
-                    // ServletOps.htmlMessage("No Text-File!", response);
-                }
-            }
-
-        } catch (ImageOpException e) {
+		try {
+			
+			/*
+			 * find the file to load/send
+			 */
+			TextFile f = getTextFile(dlRequest, "/txt");
+			if (f != null) {
+				ServletOps.sendFile(f.getFile(), null, null, response, logger);
+			} else {
+				f = getTextFile(dlRequest, "");
+				if (f != null) {
+					ServletOps.sendFile(f.getFile(),	null, null, response, logger);
+				} else {
+					response.sendError(HttpServletResponse.SC_NOT_FOUND, "Text-File not found!");
+					//ServletOps.htmlMessage("No Text-File!", response);
+				}
+			}
+			
+		} catch (ImageOpException e) {
             // most likely wrong file format...
             logger.error("ERROR sending text file: ", e);
             response.sendError(HttpServletResponse.SC_BAD_REQUEST);