changeset 1235:c8e7f5552849

more work on directories.
author casties
date Mon, 13 Jan 2014 12:45:56 +0100
parents 6c1f198b292b
children e8862382a8f2
files common/src/main/java/digilib/io/AliasingDocuDirCache.java common/src/main/java/digilib/io/BaseDirDocuDirectory.java common/src/main/java/digilib/io/DocuDirCache.java common/src/main/java/digilib/io/DocuDirectory.java common/src/main/java/digilib/io/DocuDirectoryFactory.java common/src/main/java/digilib/io/FileOps.java servlet/src/main/java/digilib/conf/DigilibServletConfiguration.java
diffstat 7 files changed, 128 insertions(+), 108 deletions(-) [+]
line wrap: on
line diff
--- a/common/src/main/java/digilib/io/AliasingDocuDirCache.java	Thu Jan 09 18:07:32 2014 +0100
+++ b/common/src/main/java/digilib/io/AliasingDocuDirCache.java	Mon Jan 13 12:45:56 2014 +0100
@@ -43,16 +43,15 @@
 public class AliasingDocuDirCache extends DocuDirCache {
 
 	/**
-	 * @param baseDirs
 	 * @param fc
 	 * @param confFileName
 	 * @throws FileOpException
 	 */
-	public AliasingDocuDirCache(String[] baseDirs, FileClass fc,
+	public AliasingDocuDirCache(FileClass fc,
 			File confFile, DigilibConfiguration dlConfig)
 			throws FileOpException {
 		// create standard DocuDirCache
-		super(baseDirs, fc, dlConfig);
+		super(fc, dlConfig);
 		Map<String,String> pathMap = null;
 		// read alias config file
 		try {
--- a/common/src/main/java/digilib/io/BaseDirDocuDirectory.java	Thu Jan 09 18:07:32 2014 +0100
+++ b/common/src/main/java/digilib/io/BaseDirDocuDirectory.java	Mon Jan 13 12:45:56 2014 +0100
@@ -29,6 +29,7 @@
 import java.util.ArrayList;
 import java.util.Collections;
 
+import digilib.conf.DigilibConfiguration;
 import digilib.io.FileOps.FileClass;
 import digilib.meta.MetaFactory;
 
@@ -43,8 +44,8 @@
 
     /** array of parallel dirs for scaled images */
     protected Directory[] dirs = null;
-    /** reference of the parent DocuDirCache */
-    protected DocuDirCache cache = null;
+    /** list of base directories */
+    protected String[] baseDirNames = null;
 
     /**
      * Configure object with digilib directory path and a parent DocuDirCache.
@@ -61,12 +62,13 @@
      * @return 
      */
     @Override
-    public void configure(String path, DocuDirCache cache) {
+    public void configure(String path, FileClass fileClass, DigilibConfiguration dlConfig) {
         this.dirName = path;
-        this.cache = cache;
-        String baseDirName = cache.getBaseDirNames()[0];
+        this.fileClass = fileClass;
+        this.baseDirNames = (String[]) dlConfig.getValue("basedir-list");
+        String baseDirName = baseDirNames[0];
         // clear directory list
-        list = new ArrayList<DocuDirent>();
+        files = new ArrayList<DocuDirent>();
         dirMTime = 0;
         // the first directory has to exist
         dir = new File(baseDirName, path);
@@ -99,8 +101,6 @@
     	}
     	// 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
@@ -119,14 +119,13 @@
     		}
     	}
     
-    	FileClass fileClass = cache.getFileClass();
     	File[] fileList = FileOps.listFiles(allFiles, FileOps.filterForClass(fileClass));
     	// number of files in the directory
     	int numFiles = fileList.length;
     	if (numFiles > 0) {
     		// create new list
     		ArrayList<DocuDirent> dl = new ArrayList<DocuDirent>(numFiles);
-    		list = dl;
+    		files = dl;
     		for (File f : fileList) {
     			DocuDirent df = FileOps.fileForClass(fileClass, f, dirs);
     			df.setParent(this);
@@ -145,26 +144,10 @@
     			d.clearFilenames();
     		}
     	}
-    	// update number of cached files if this was the first time
-    	if (dirMTime == 0) {
-    		cache.numFiles.addAndGet(size());
-    	}
     	dirMTime = dir.lastModified();
     	// read metadata as well
     	readMeta();
     	return isValid;
     }
 
-    @Override
-    public boolean refresh() {
-    	if (isValid) {
-    		if (dir.lastModified() > dirMTime) {
-    			// on-disk modification time is more recent
-    			readDir();
-    		}
-    		touch();
-    	}
-    	return isValid;
-    }
-
 }
--- a/common/src/main/java/digilib/io/DocuDirCache.java	Thu Jan 09 18:07:32 2014 +0100
+++ b/common/src/main/java/digilib/io/DocuDirCache.java	Mon Jan 13 12:45:56 2014 +0100
@@ -7,7 +7,7 @@
  * Digital Image Library servlet components
  * 
  * %%
- * Copyright (C) 2003 - 2013 MPIWG Berlin
+ * Copyright (C) 2003 - 2014 MPIWG Berlin
  * %%
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Lesser General Public License as 
@@ -27,7 +27,6 @@
  * Created on 03.03.2003
  */
 
-import java.io.File;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
 import java.util.concurrent.atomic.AtomicInteger;
@@ -48,9 +47,6 @@
 	/** HashMap of directories */
 	protected ConcurrentMap<String, DocuDirectory> map = new ConcurrentHashMap<String, DocuDirectory>();
 
-	/** names of base directories */
-	protected String[] baseDirNames = null;
-
 	/** allowed file class (image/text) */
 	protected FileClass fileClass = null;
 
@@ -71,9 +67,8 @@
      * @param fc
      * @param dlConfig
 	 */
-	public DocuDirCache(String[] bd, FileClass fc,
+	public DocuDirCache(FileClass fc,
 			DigilibConfiguration dlConfig) {
-		baseDirNames = bd;
 		this.fileClass = fc;
 	}
 
@@ -83,8 +78,7 @@
 	 * @param bd
 	 *            base directory names
 	 */
-	public DocuDirCache(String[] bd) {
-		baseDirNames = bd;
+	public DocuDirCache() {
 		// default file class is CLASS_IMAGE
 		fileClass = FileClass.IMAGE;
 	}
@@ -136,7 +130,7 @@
 				DocuDirectory pd = map.get(parent);
 				if (pd == null) {
 					// the parent is unknown
-					pd = DocuDirectoryFactory.getDocuDirectoryInstance(parent, this);
+					pd = DocuDirectoryFactory.getDocuDirectoryInstance(parent, fileClass);
 					pd = putDir(pd);
 				}
 				newDir.setParent(pd);
@@ -190,16 +184,12 @@
 			// cache miss
 			misses.incrementAndGet();
 			/*
-			 * see if fn is a directory
+			 * try fn as a directory
 			 */
-			File f = new File(baseDirNames[0], fn);
-			if (f.isDirectory()) {
-                // logger.debug(fn + " is a dir");
-				dd = DocuDirectoryFactory.getDocuDirectoryInstance(fn, this);
-				if (dd.isValid()) {
-					// add to the cache
-					dd = putDir(dd);
-				}
+			dd = DocuDirectoryFactory.getDocuDirectoryInstance(fn, fileClass);
+			if (dd.isValid()) {
+			    // add to the cache
+			    dd = putDir(dd);
 			} else {
 				/*
 				 * maybe it's a file
@@ -211,7 +201,7 @@
 				dd = map.get(d);
 				if (dd == null) {
 					// try to read from disk
-					dd = DocuDirectoryFactory.getDocuDirectoryInstance(d, this);
+					dd = DocuDirectoryFactory.getDocuDirectoryInstance(d, fileClass);
 					if (dd.isValid()) {
 						// add to the cache
                         // logger.debug(dd + " is valid");
@@ -225,7 +215,7 @@
 					misses.decrementAndGet();
 				}
 				// get the file's index
-				n = dd.indexOf(f.getName());
+				n = dd.indexOf(FileOps.filename(fn));
 			}
 		} else {
 			// cache hit
@@ -259,35 +249,27 @@
 			// cache miss
 			misses.incrementAndGet();
 			// see if it's a directory
-			File f = new File(baseDirNames[0], fn);
-			if (f.isDirectory()) {
-				dd = DocuDirectoryFactory.getDocuDirectoryInstance(fn, this);
-				if (dd.isValid()) {
-					// add to the cache
-					dd = putDir(dd);
-				}
+			dd = DocuDirectoryFactory.getDocuDirectoryInstance(fn, fileClass);
+			if (dd.isValid()) {
+			    // add to the cache
+			    dd = putDir(dd);
 			} else {
-				// maybe it's a file
-				if (f.canRead()) {
-					// try the parent directory in the cache
-					dd = map.get(f.getParent());
-					if (dd == null) {
-						// try to read from disk
-						dd = DocuDirectoryFactory.getDocuDirectoryInstance(f.getParent(), this);
-						if (dd.isValid()) {
-							// add to the cache
-							dd = putDir(dd);
-						} else {
-							// invalid path
-							return null;
-						}
+				// try the parent directory in the cache
+				String pn = FileOps.parent(fn);
+                dd = map.get(pn);
+				if (dd == null) {
+					// try to read from disk
+					dd = DocuDirectoryFactory.getDocuDirectoryInstance(pn, fileClass);
+					if (dd.isValid()) {
+						// add to the cache
+						dd = putDir(dd);
 					} else {
-						// not a real cache miss then
-						misses.decrementAndGet();
+						// invalid path
+						return null;
 					}
 				} else {
-					// it's not even a file :-(
-					return null;
+					// not a real cache miss then
+					misses.decrementAndGet();
 				}
 			}
 		} else {
@@ -301,23 +283,6 @@
 		return null;
 	}
 
-	/**
-	 * @return String[]
-	 */
-	public String[] getBaseDirNames() {
-		return baseDirNames;
-	}
-
-	/**
-	 * Sets the baseDirNames.
-	 * 
-	 * @param baseDirNames
-	 *            The baseDirNames to set
-	 */
-	public void setBaseDirNames(String[] baseDirNames) {
-		this.baseDirNames = baseDirNames;
-	}
-
     /**
      * @return long
      */
--- a/common/src/main/java/digilib/io/DocuDirectory.java	Thu Jan 09 18:07:32 2014 +0100
+++ b/common/src/main/java/digilib/io/DocuDirectory.java	Mon Jan 13 12:45:56 2014 +0100
@@ -7,7 +7,7 @@
  * Digital Image Library servlet components
  * 
  * %%
- * Copyright (C) 2003 - 2013 MPIWG Berlin
+ * Copyright (C) 2003 - 2014 MPIWG Berlin
  * %%
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Lesser General Public License as 
@@ -32,17 +32,28 @@
 import java.util.Collections;
 import java.util.List;
 
+import digilib.conf.DigilibConfiguration;
 import digilib.io.FileOps.FileClass;
 import digilib.meta.DirMeta;
 import digilib.meta.MetaFactory;
 
 /**
+ * Class representing a directory containing (image) files.
+ * 
+ * Files can be access by index or name. All files are of the same FileClass.
+ * The DocuDirectory holds DirMeta. 
+ * 
+ * Subclasses of DocuDirectory can also hold multiple scaled versions of an image file. 
+ * 
  * @author casties
  */
 public abstract class DocuDirectory extends Directory {
 
+    /** type of files in this DocuDirectory */
+    protected FileClass fileClass = FileClass.IMAGE;
+    
 	/** list of files (DocuDirent) */
-	protected List<DocuDirent> list = null;
+	protected List<DocuDirent> files = null;
 
 	/** directory object is valid (exists on disk) */
 	protected boolean isValid = false;
@@ -69,14 +80,17 @@
 	 * 
 	 * @param path
 	 *            digilib directory path name
-	 * @param cache
-	 *            parent DocuDirCache
+	 * @param fileClass 
+	 *            type of files in this DocuDirectory
+	 * @param dlConfig
+	 *            digilib config
 	 * @return 
 	 */
-	public void configure(String path, DocuDirCache cache) {
+	public void configure(String path, FileClass fileClass, DigilibConfiguration dlConfig) {
 		this.dirName = path;
+		this.fileClass = fileClass;
 		// clear directory list
-		list = new ArrayList<DocuDirent>();
+		files = new ArrayList<DocuDirent>();
 		dirMTime = 0;
 		// the first directory has to exist
 		dir = new File(path);
@@ -88,7 +102,7 @@
 	 * number of DocuFiles in this directory. 
 	 */
 	public int size() {
-		return (list != null) ? list.size() : 0;
+		return (files != null) ? files.size() : 0;
 	}
 
 	/**
@@ -109,10 +123,10 @@
 	 * @return
 	 */
 	public DocuDirent get(int index) {
-		if ((list == null) || (index >= list.size())) {
+		if ((files == null) || (index >= files.size())) {
 			return null;
 		}
-		return list.get(index);
+		return files.get(index);
 	}
 
 	/**
@@ -128,6 +142,7 @@
 	    return get(index);
 	}
 
+
 	/**
 	 * Read the filesystem directory and fill this object.
 	 * 
@@ -137,12 +152,23 @@
 	 */
 	public abstract boolean readDir();
 
+
 	/**
 	 * Check to see if the directory has been modified and reread if necessary.
 	 * 
 	 * @return boolean the directory is valid
 	 */
-	public abstract boolean refresh();
+    public boolean refresh() {
+        if (isValid) {
+            if (dir.lastModified() > dirMTime) {
+                // on-disk modification time is more recent
+                readDir();
+            }
+            touch();
+        }
+        return isValid;
+    }
+
 
 	/**
 	 * Read directory metadata.
@@ -207,7 +233,7 @@
 				return -1;
 			}
 		}
-		List<DocuDirent> fileList = list;
+		List<DocuDirent> fileList = files;
 		// empty directory?
 		if (fileList == null) {
 			return -1;
@@ -253,7 +279,7 @@
 	public DocuDirent find(String fn) {
 		int i = indexOf(fn);
 		if (i >= 0) {
-			return list.get(i);
+			return files.get(i);
 		}
 		return null;
 	}
--- a/common/src/main/java/digilib/io/DocuDirectoryFactory.java	Thu Jan 09 18:07:32 2014 +0100
+++ b/common/src/main/java/digilib/io/DocuDirectoryFactory.java	Mon Jan 13 12:45:56 2014 +0100
@@ -25,6 +25,9 @@
 
 import org.apache.log4j.Logger;
 
+import digilib.conf.DigilibConfiguration;
+import digilib.io.FileOps.FileClass;
+
 /**
  * Static factory for DocuDirectory implementations.
  * 
@@ -35,6 +38,9 @@
 
     /** Log4J logger */
     protected static Logger logger = Logger.getLogger(DocuDirectoryFactory.class);
+    
+    /** digilib config instance */
+    protected static DigilibConfiguration dlConfig;
 
     /** DocuDirectory implementation class */
     protected static Class<DocuDirectory> docuDirClass;
@@ -54,6 +60,19 @@
     }
 
     /**
+     * Returns a DocuDirectory instance with the given path and FileClass.
+     *  
+     * @param path
+     * @param fileClass
+     * @return
+     */
+    public static DocuDirectory getDocuDirectoryInstance(String path, FileClass fileClass) {
+        DocuDirectory dd = getInstance();
+        dd.configure(path, fileClass, dlConfig);
+        return dd;        
+    }
+    
+    /**
      * Returns a DocuDirectory instance with the given path and DocuDirCache.
      *  
      * @param path
@@ -62,7 +81,7 @@
      */
     public static DocuDirectory getDocuDirectoryInstance(String path, DocuDirCache cache) {
         DocuDirectory dd = getInstance();
-        dd.configure(path, cache);
+        dd.configure(path, null, dlConfig);
         return dd;        
     }
     
@@ -73,5 +92,12 @@
         DocuDirectoryFactory.docuDirClass = dirMetaClass;
     }
 
+    /**
+     * @param dlConfig
+     */
+    public static void setDigilibConfig(DigilibConfiguration dlConfig) {
+        DocuDirectoryFactory.dlConfig = dlConfig;
+    }
+
 
 }
--- a/common/src/main/java/digilib/io/FileOps.java	Thu Jan 09 18:07:32 2014 +0100
+++ b/common/src/main/java/digilib/io/FileOps.java	Mon Jan 13 12:45:56 2014 +0100
@@ -242,6 +242,27 @@
 		return "";
 	}
 
+    /**
+     * Extract the file name of a (digilib) path name.
+     * 
+     * Returns the file name of a path name. The file name is the part
+     * after the last slash in the path name. If the path name has no slash the
+     * original string is returned.
+     * 
+     * @param fn
+     * @return
+     */
+    public static String filename(String fn) {
+        if (fn == null) {
+            return null;
+        }
+        int i = fn.lastIndexOf('/');
+        if (i >= 0 && i < fn.length()) {
+            return fn.substring(i+1);
+        }
+        return fn;
+    }
+
 	/**
 	 * Normalize a path name.
 	 * 
--- a/servlet/src/main/java/digilib/conf/DigilibServletConfiguration.java	Thu Jan 09 18:07:32 2014 +0100
+++ b/servlet/src/main/java/digilib/conf/DigilibServletConfiguration.java	Mon Jan 13 12:45:56 2014 +0100
@@ -267,6 +267,7 @@
             Class<DocuDirectory> docuDirectoryClass = (Class<DocuDirectory>) Class.forName(config.getAsString("docudirectory-class"));
             config.setValue("servlet.docudirectory.class", docuDirectoryClass);
             DocuDirectoryFactory.setDocuDirectoryClass(docuDirectoryClass);
+            DocuDirectoryFactory.setDigilibConfig(this);
         } catch (ClassNotFoundException e) {
             logger.error("Error setting DocuDirectory class!");
         }
@@ -283,16 +284,15 @@
         logger.info("***** Digital Image Library Configuration (version " + getVersion() + ") *****");
         try {
             // directory cache
-            String[] bd = (String[]) config.getValue("basedir-list");
             DocuDirCache dirCache;
             if (config.getAsBoolean("use-mapping")) {
                 // with mapping file
                 File mapConf = ServletOps.getConfigFile((File) config.getValue("mapping-file"), context);
-                dirCache = new AliasingDocuDirCache(bd, FileClass.IMAGE, mapConf, config);
+                dirCache = new AliasingDocuDirCache(FileClass.IMAGE, mapConf, config);
                 config.setValue("mapping-file", mapConf);
             } else {
                 // without mapping
-                dirCache = new DocuDirCache(bd, FileClass.IMAGE, this);
+                dirCache = new DocuDirCache(FileClass.IMAGE, this);
             }
             config.setValue(DIR_CACHE_KEY, dirCache);
             // useAuthentication