changeset 176:67ff8c7fecb9

Servlet version 1.17b2 - new mapping file for "virtual directories" - direct file URLs now work without extension (even with wrong ones)
author robcast
date Mon, 10 Nov 2003 20:59:00 +0100
parents 633947100c86
children 830b0111a0c9
files servlet/src/digilib/io/AliasingDocuDirCache.java servlet/src/digilib/io/DocuDirCache.java servlet/src/digilib/io/DocuDirectory.java servlet/src/digilib/io/DocuDirent.java servlet/src/digilib/io/FileOps.java servlet/src/digilib/io/ImageFileset.java servlet/src/digilib/io/XMLListLoader.java
diffstat 7 files changed, 278 insertions(+), 89 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/servlet/src/digilib/io/AliasingDocuDirCache.java	Mon Nov 10 20:59:00 2003 +0100
@@ -0,0 +1,94 @@
+/*
+ * AliasingDocuDirCache -- DocuDirCache using alias entries from config file
+ * 
+ * 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 04.11.2003
+ */
+
+package digilib.io;
+
+import java.io.File;
+import java.util.HashMap;
+import java.util.Iterator;
+
+/**
+ * @author casties
+ *  
+ */
+public class AliasingDocuDirCache extends DocuDirCache {
+
+	/**
+	 * @param baseDirs
+	 * @param fileClasses
+	 * @param confFileName
+	 * @throws FileOpException
+	 */
+	public AliasingDocuDirCache(
+		String[] baseDirs,
+		int[] fileClasses,
+		String confFileName)
+		throws FileOpException {
+		// create standard DocuDirCache
+		super(baseDirs, fileClasses);
+		HashMap pathMap = null;
+		// read alias config file
+		try {
+			// create data loader for mapping-file
+			File confFile = new File(confFileName);
+			// load into pathMap
+			XMLListLoader mapLoader =
+				new XMLListLoader("digilib-aliases", "mapping", "link", "dir");
+			pathMap = mapLoader.loadURL(confFile.toURL().toString());
+		} catch (Exception e) {
+			throw new FileOpException("ERROR loading mapping file: " + e);
+		}
+		if (pathMap == null) {
+			throw new FileOpException("ERROR unable to load mapping file!");
+		}
+
+		/*
+		 * load map entries into cache
+		 */
+		
+		for (Iterator i = pathMap.keySet().iterator(); i.hasNext();) {
+			String link = (String)i.next();
+			String dir = (String) pathMap.get(link);
+			DocuDirectory destDir = new DocuDirectory(dir, this);
+			if (destDir.isValid()) {
+				// add the alias name
+				putName(link, destDir);
+				// add the real dir
+				putDir(destDir);
+			}
+		}
+	}
+
+	/** Adds a DocuDirectory under another name to the cache.
+	 * 
+	 * @param name 
+	 * @param newdir
+	 */
+	public void putName(String name, DocuDirectory newdir) {
+		if (map.containsKey(name)) {
+			System.out.println("Baah, duplicate key in AliasingDocuDirCache.put!");
+		} else {
+			map.put(name, newdir);
+		}
+	}
+	
+}
--- a/servlet/src/digilib/io/DocuDirCache.java	Mon Nov 10 20:50:32 2003 +0100
+++ b/servlet/src/digilib/io/DocuDirCache.java	Mon Nov 10 20:59:00 2003 +0100
@@ -1,21 +1,22 @@
-/* DocuDirCache.java
-
-  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
-
+/*
+ * DocuDirCache.java
+ * 
+ * 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 03.03.2003
  */
 
@@ -33,7 +34,7 @@
 public class DocuDirCache {
 
 	/** HashMap of directories */
-	private HashMap map = null;
+	protected HashMap map = null;
 	/** names of base directories */
 	private String[] baseDirNames = null;
 	/** array of allowed file classes (image/text) */
@@ -45,18 +46,22 @@
 	/** number of cache misses */
 	private long misses = 0;
 
-	/** Constructor with array of base directory names and file classes.
-	 *  
-	 * @param bd base directory names
+	/**
+	 * Constructor with array of base directory names and file classes.
+	 * 
+	 * @param bd
+	 *            base directory names
 	 */
 	public DocuDirCache(String[] bd, int[] fileClasses) {
 		baseDirNames = bd;
 		map = new HashMap();
 		this.fileClasses = fileClasses;
 	}
-	/** Constructor with array of base directory names.
-	 *  
-	 * @param bd base directory names
+	/**
+	 * Constructor with array of base directory names.
+	 * 
+	 * @param bd
+	 *            base directory names
 	 */
 	public DocuDirCache(String[] bd) {
 		baseDirNames = bd;
@@ -66,14 +71,17 @@
 		fileClasses[0] = FileOps.CLASS_IMAGE;
 	}
 
-	/** The number of directories in the cache.
+	/**
+	 * The number of directories in the cache.
+	 * 
 	 * @return
 	 */
 	public int size() {
 		return (map != null) ? map.size() : 0;
 	}
 
-	/** Add a DocuDirectory to the cache.
+	/**
+	 * Add a DocuDirectory to the cache.
 	 * 
 	 * @param newdir
 	 */
@@ -87,7 +95,8 @@
 		}
 	}
 
-	/** Add a directory to the cache and check its parents.
+	/**
+	 * Add a directory to the cache and check its parents.
 	 * 
 	 * @param newDir
 	 */
@@ -96,7 +105,7 @@
 		String parent = newDir.getParentDirName();
 		if (parent != null) {
 			// check the parent in the cache
-			DocuDirectory pd = (DocuDirectory)map.get(parent);
+			DocuDirectory pd = (DocuDirectory) map.get(parent);
 			if (pd == null) {
 				// the parent is unknown
 				pd = new DocuDirectory(parent, this);
@@ -106,20 +115,22 @@
 		}
 	}
 
-	/** Get a list with all children of a directory.
+	/**
+	 * Get a list with all children of a directory.
 	 * 
-	 * Returns a List of DocuDirectory's.
-	 * Returns an empty List if the directory has no children.
-	 * If recurse is false then only direct children are returned.
+	 * Returns a List of DocuDirectory's. Returns an empty List if the
+	 * directory has no children. If recurse is false then only direct children
+	 * are returned.
 	 * 
 	 * @param dirname
-	 * @param recurse find all children and their children.
+	 * @param recurse
+	 *            find all children and their children.
 	 * @return
 	 */
 	public List getChildren(String dirname, boolean recurse) {
 		List l = new LinkedList();
-		for (Iterator i = map.keySet().iterator(); i.hasNext(); ) {
-			DocuDirectory dd = (DocuDirectory)i.next();
+		for (Iterator i = map.keySet().iterator(); i.hasNext();) {
+			DocuDirectory dd = (DocuDirectory) i.next();
 			if (recurse) {
 				if (dd.getDirName().startsWith(dirname)) {
 					l.add(dd);
@@ -133,15 +144,18 @@
 		return l;
 	}
 
-	/** Returns the ImageFileset with the pathname <code>fn</code> and the 
+	/**
+	 * Returns the ImageFileset with the pathname <code>fn</code> and the
 	 * index <code>in</code> and the class <code>fc</code>.
 	 * 
-	 * If <code>fn</code> is a file then the corresponding Fileset is 
+	 * If <code>fn</code> is a file then the corresponding Fileset is
 	 * returned and the index is ignored.
 	 * 
-	 * @param fn digilib pathname
-	 * @param in file index
-	 * @return 
+	 * @param fn
+	 *            digilib pathname
+	 * @param in
+	 *            file index
+	 * @return
 	 */
 	public DocuDirent getFile(String fn, int in, int fc) {
 		DocuDirectory dd;
@@ -152,7 +166,9 @@
 		if (dd == null) {
 			// cache miss
 			misses++;
-			// see if it's a directory
+			/*
+			 * see if it's a directory
+			 */
 			File f = new File(baseDirNames[0], fn);
 			if (f.isDirectory()) {
 				dd = new DocuDirectory(fn, this);
@@ -161,32 +177,30 @@
 					putDir(dd);
 				}
 			} else {
-				// maybe it's a file
-				if (f.canRead()) {
-					// get the parent directory string (like we store it in the cache)
-					String d = fn.substring(0, fn.lastIndexOf("/"));
-					// try it in the cache
-					dd = (DocuDirectory) map.get(d);
-					if (dd == null) {
-						// try to read from disk
-						dd = new DocuDirectory(d, this);
-						if (dd.isValid()) {
-							// add to the cache
-							putDir(dd);
-						} else {
-							// invalid path
-							return null;
-						}
+				/*
+				 * maybe it's a file
+				 */
+				// get the parent directory string (like we store it in the
+				// cache)
+				String d = fn.substring(0, fn.lastIndexOf("/"));
+				// try it in the cache
+				dd = (DocuDirectory) map.get(d);
+				if (dd == null) {
+					// try to read from disk
+					dd = new DocuDirectory(d, this);
+					if (dd.isValid()) {
+						// add to the cache
+						putDir(dd);
 					} else {
-						// then it was not a real cache miss
-						misses--;
+						// invalid path
+						return null;
 					}
-					// get the file's index
-					n = dd.indexOf(f.getName(), fc);
 				} else {
-					// it's not even a file :-(
-					return null;
+					// it was not a real cache miss
+					misses--;
 				}
+				// get the file's index
+				n = dd.indexOf(f.getName(), fc);
 			}
 		} else {
 			// cache hit
@@ -202,11 +216,13 @@
 		return null;
 	}
 
-	/** Returns the DocuDirectory indicated by the pathname <code>fn</code>.
+	/**
+	 * Returns the DocuDirectory indicated by the pathname <code>fn</code>.
 	 * 
 	 * If <code>fn</code> is a file then its parent directory is returned.
 	 * 
-	 * @param fn digilib pathname
+	 * @param fn
+	 *            digilib pathname
 	 * @return
 	 */
 	public DocuDirectory getDirectory(String fn) {
@@ -275,7 +291,9 @@
 
 	/**
 	 * Sets the baseDirNames.
-	 * @param baseDirNames The baseDirNames to set
+	 * 
+	 * @param baseDirNames
+	 *            The baseDirNames to set
 	 */
 	public void setBaseDirNames(String[] baseDirNames) {
 		this.baseDirNames = baseDirNames;
@@ -308,5 +326,5 @@
 	public void setFileClasses(int[] fileClasses) {
 		this.fileClasses = fileClasses;
 	}
-	
+
 }
--- a/servlet/src/digilib/io/DocuDirectory.java	Mon Nov 10 20:50:32 2003 +0100
+++ b/servlet/src/digilib/io/DocuDirectory.java	Mon Nov 10 20:59:00 2003 +0100
@@ -57,13 +57,11 @@
 	 * 
 	 * Directory names at the given path are appended to the base directories 
 	 * from the cache. The directory is checked on disk and isValid is set. 
-	 * If read is true the directory is read and filled.
 	 * 
 	 * @see readDir
 	 *  
 	 * @param path digilib directory path name
-	 * @param bd array of base directory names
-	 * @param read the directory is read and filled
+	 * @param cache parent DocuDirCache
 	 */
 	public DocuDirectory(String path, DocuDirCache cache) {
 		this.dirName = path;
@@ -364,11 +362,26 @@
 	 * @return int index of file <code>fn</code>
 	 */
 	public int indexOf(String fn, int fc) {
+		if (!isRead()) {
+			// read directory now
+			if (!readDir()) {
+				return -1;
+			}
+		}
 		// linear search -> worst performance
 		int n = list[fc].size();
 		for (int i = 0; i < n; i++) {
 			ImageFileset fs = (ImageFileset) list[fc].get(i);
 			if (fs.getName().equals(fn)) {
+				// filename matches
+				return i;
+			}
+		}
+		// try again without extension
+		for (int i = 0; i < n; i++) {
+			ImageFileset fs = (ImageFileset) list[fc].get(i);
+			if (fs.getBasename().equals(FileOps.basename(fn))) {
+				// basename matches
 				return i;
 			}
 		}
--- a/servlet/src/digilib/io/DocuDirent.java	Mon Nov 10 20:50:32 2003 +0100
+++ b/servlet/src/digilib/io/DocuDirent.java	Mon Nov 10 20:59:00 2003 +0100
@@ -78,7 +78,10 @@
 		}
 	}
 
-	/** The name of the (hires) image file.
+	/** 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
 	 */
@@ -87,7 +90,19 @@
 		return (f != null) ? f.getName() : null;
 	}
 
-	/** Returns the parent DocuDirectory.
+	/** The filename sans extension.
+	 * 
+	 * @return
+	 */
+	public String getBasename() {
+		File f = getFile();
+		if (f == null) {
+			return null;
+		}
+		return FileOps.basename(f.getName());
+	}
+
+	/** Returns the parent Directory.
 	 * 
 	 * @return DocuDirectory
 	 */
@@ -95,15 +110,15 @@
 		return parent;
 	}
 
-	/**
-	 * Sets the 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 fileset.
+	/** Returns the meta-data for this file(set).
 	 * 
 	 * @return HashMap
 	 */
@@ -111,8 +126,8 @@
 		return fileMeta;
 	}
 
-	/**
-	 * Sets the fileMeta.
+	/** Sets the meta-data for this file(set)
+	 * .
 	 * @param fileMeta The fileMeta to set
 	 */
 	public void setFileMeta(HashMap fileMeta) {
--- a/servlet/src/digilib/io/FileOps.java	Mon Nov 10 20:50:32 2003 +0100
+++ b/servlet/src/digilib/io/FileOps.java	Mon Nov 10 20:59:00 2003 +0100
@@ -148,6 +148,40 @@
 		}
 		return pathArray;
 	}
+	
+	/** Extract the base of a file name (sans extension).
+	 * 
+	 * Returns the filename without the extension. The extension is the part behind
+	 * the last dot in the filename. If the filename has no dot the full file name 
+	 * is returned.
+	 *  
+	 * @param fn
+	 * @return
+	 */
+	public static String basename(String fn) {
+		int i = fn.lastIndexOf('.');
+		if (i > 0) {
+			return fn.substring(0, i);
+		}
+		return fn;
+	}
+
+	/** Extract the extension of a file name.
+	 * 
+	 * Returns the extension of a file name. The extension is the part behind
+	 * the last dot in the filename. If the filename has no dot the empty string 
+	 * is returned.
+	 *  
+	 * @param fn
+	 * @return
+	 */
+	public static String extname(String fn) {
+		int i = fn.lastIndexOf('.');
+		if (i > 0) {
+			return fn.substring(i+1);
+		}
+		return "";
+	}
 
 	/**
 	 *  FileFilter for image types (helper class for getFile)
--- a/servlet/src/digilib/io/ImageFileset.java	Mon Nov 10 20:50:32 2003 +0100
+++ b/servlet/src/digilib/io/ImageFileset.java	Mon Nov 10 20:59:00 2003 +0100
@@ -1,16 +1,20 @@
-/*
- * 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
+/* 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  
+ * 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;
@@ -74,7 +78,7 @@
 	}
 
 	/**
-	 * Adds a ImageFile to this Fileset.
+	 * 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".
--- a/servlet/src/digilib/io/XMLListLoader.java	Mon Nov 10 20:50:32 2003 +0100
+++ b/servlet/src/digilib/io/XMLListLoader.java	Mon Nov 10 20:59:00 2003 +0100
@@ -34,6 +34,17 @@
 import org.xml.sax.SAXParseException;
 import org.xml.sax.helpers.DefaultHandler;
 
+/** Loads a simple XML list into a HashMap.
+ * 
+ * The XML file has an outer <code>list_tag</code>. Every entry is an 
+ * <code>entry_tag</code> with two attributes: the <code>key_att</code>
+ * key and the <code>value_att</code> value.
+ * 
+ * The file is read by the <code>loadURL</code> method, that returns a
+ * HashMap with the key-value pairs.
+ * 
+ * @author casties
+ */
 public class XMLListLoader {
 
 	private String listTag = "list";