Index: FilesystemQueue.java
===================================================================
RCS file: /home/cvspublic/xml-cocoon2/src/org/apache/cocoon/components/store/FilesystemQueue.java,v
retrieving revision 1.1
diff -u -r1.1 FilesystemQueue.java
--- FilesystemQueue.java	2001/10/23 11:55:19	1.1
+++ FilesystemQueue.java	2001/11/20 16:13:20
@@ -9,6 +9,8 @@
 
 import org.apache.avalon.excalibur.collections.PriorityQueue;
 
+import org.apache.avalon.framework.activity.Startable;
+
 import org.apache.avalon.framework.component.Component;
 
 /**
@@ -16,6 +18,6 @@
  *
  * @author <a href="mailto:g-froehlich@gmx.de">Gerhard Froehlich</a>
  */
-public interface FilesystemQueue extends Component, PriorityQueue {
+public interface FilesystemQueue extends Component, PriorityQueue, Startable {
   String ROLE = "org.apache.cocoon.components.store.FilesystemQueue";
 }
Index: FilesystemQueueImpl.java
===================================================================
RCS file: /home/cvspublic/xml-cocoon2/src/org/apache/cocoon/components/store/FilesystemQueueImpl.java,v
retrieving revision 1.1
diff -u -r1.1 FilesystemQueueImpl.java
--- FilesystemQueueImpl.java	2001/10/23 11:55:19	1.1
+++ FilesystemQueueImpl.java	2001/11/20 16:13:21
@@ -70,6 +70,7 @@
   private String cachedirstr;
   private Store fsstore;
   private Thread fsQueueHandler;
+  private static boolean doRun = true;
 
  /**
    * Get the context
@@ -126,16 +127,22 @@
     this.getLogger().debug("threadpriority=" + threadpriority);
 
     this.linkedList = new LinkedList();
+  }
 
+  public void start() {
     this.fsQueueHandler = new Thread(this);
     this.fsQueueHandler.setDaemon(true);
     this.fsQueueHandler.setPriority(this.threadpriority);
     this.fsQueueHandler.setName("fsQueueHandler");
-    this.fsQueueHandler.start();
+    this.fsQueueHandler.start();  
+  }
+
+  public void stop() {
+    this.doRun = false;
   }
 
   public void run() {
-    while(true) {
+    while(doRun) {
       while(!this.isEmpty()) {
         FilesystemQueueObject filesystemQueueObject = (FilesystemQueueObject)this.pop();
         try {
@@ -149,7 +156,7 @@
         Thread.currentThread().sleep(this.handlerinterval * 1000);
       } catch (InterruptedException ignore) {}
     }
-	}
+  }
   
   /**
    * Clear all elements from queue.
Index: FilesystemStore.java
===================================================================
RCS file: /home/cvspublic/xml-cocoon2/src/org/apache/cocoon/components/store/FilesystemStore.java,v
retrieving revision 1.8
diff -u -r1.8 FilesystemStore.java
--- FilesystemStore.java	2001/11/19 13:39:44	1.8
+++ FilesystemStore.java	2001/11/20 16:13:22
@@ -164,6 +164,10 @@
     return new EnumerationFromFileArray(this.directoryFile.listFiles());
   }
 
+  public Enumeration keys(String name) {
+    return new EnumerationFromFileArray(IOUtils.createFile(this.directoryFile, name).listFiles());
+  }
+
   final class EnumerationFromFileArray implements Enumeration {
       private File[] array;
       private int    index;
Index: MRUMemoryStore.java
===================================================================
RCS file: /home/cvspublic/xml-cocoon2/src/org/apache/cocoon/components/store/MRUMemoryStore.java,v
retrieving revision 1.22
diff -u -r1.22 MRUMemoryStore.java
--- MRUMemoryStore.java	2001/10/23 11:55:19	1.22
+++ MRUMemoryStore.java	2001/11/20 16:13:25
@@ -9,6 +9,8 @@
 
 import org.apache.avalon.excalibur.collections.SynchronizedPriorityQueue;
 
+import org.apache.avalon.framework.activity.Disposable;
+
 import org.apache.avalon.framework.component.ComponentException;
 
 import org.apache.avalon.framework.component.ComponentManager;
@@ -47,7 +49,7 @@
 
 import java.util.Enumeration;
 
-import java.util.HashMap;
+import java.util.Hashtable;
 
 import java.util.LinkedList;
 
@@ -62,17 +64,17 @@
  * @author <a href="mailto:g-froehlich@gmx.de">Gerhard Froehlich</a>
  * @author <a href="mailto:dims@yahoo.com">Davanum Srinivas</a>
  */
-
 public class MRUMemoryStore extends AbstractLoggable implements Store, 
                                                                 Configurable,
                                                                 ThreadSafe,
                                                                 Composable,
+                                                                Disposable,
                                                                 Contextualizable { 
 
 
   private int maxobjects;
   private boolean filesystem;
-  private HashMap cache;
+  private Hashtable cache;
   private LinkedList mrulist;
   private File cachefile;
   private Store fsstore;
@@ -148,13 +150,46 @@
       throw new ConfigurationException("MRUMemoryStore maxobjects must be at least 1 milli second!");
     }
 
-    this.cache = new HashMap((int)(this.maxobjects * 1.2));
+    this.cache = new Hashtable((int)(this.maxobjects * 1.2));
     this.mrulist     = new LinkedList();
-  
     this.storejanitor.register(this);
   }
 
   /**
+   * Intialize the component
+   */
+  public void intialize() {
+    try {
+      this.getLogger().debug("Intialize StoreJanitor");
+      this.storejanitor.start();
+      if(filesystem) {
+        this.getLogger().debug("Intialize FilesytemQueue");
+        filesystemQueue.start();  
+      }
+    } catch (Exception e) {
+      this.getLogger().error("intialize(): Exception",e);
+    }
+  }
+
+  /**
+   * Dispose the component
+   */
+  public void dispose() {
+    try {
+        this.getLogger().debug("Dispose StoreJanitor");
+        this.storejanitor.stop();
+        this.storejanitor = null;
+        if(filesystem) {
+          this.getLogger().debug("Dispose FilesytemQueue");
+          filesystemQueue.stop();  
+          filesystemQueue.stop();
+        }
+    } catch(Exception e) {
+      this.getLogger().error("intialize(): Exception",e);
+    }
+  }
+
+  /**
    * Store the given object in a persistent state. It is up to the
    * caller to ensure that the key has a persistent state across
    * different JVM executions.
@@ -211,7 +246,7 @@
    */
   public Object get(Object key) {
     this.getLogger().debug("Getting object from memory. Key: " + key);
-
+    
     Object tmpobject = this.cache.get(key);
     if ( tmpobject != null ) {
       /** put the accessed key on top of the linked list */
@@ -269,7 +304,9 @@
    * @return true if the key exists
    */
   public boolean containsKey(Object key) {
-    synchronized(this.cache) {
+    if(filesystem) {
+      return (this.cache.containsKey(key) || this.fsstore.containsKey(key));
+    } else {
       return this.cache.containsKey(key);
     }
   }
@@ -280,11 +317,20 @@
    * @return the enumeration of the cache
    */
   public Enumeration keys() {
-    /* Not yet implemented */
-    return null;
+    return new StoreEnumeration(cache.keys(),fsstore.keys(this.cachedirstr));
   }
 
   /**
+   * Returns the list of used keys as an Enumeration.
+   *
+   * @param Name of cache directory as String
+   * @return the enumeration of the cache
+   */
+  public Enumeration keys(String name) {
+    return this.keys();
+  }
+
+  /**
    * Frees some of the fast memory used by this store.
    * It removes the last element in the store.
    */
@@ -340,5 +386,29 @@
           .append(File.separator)
           .append(URLEncoder.encode(key.toString()))
           .toString();
+  }
+
+  final class StoreEnumeration implements Enumeration {
+    private int index;
+    private Enumeration mCache;
+    private Enumeration mFs;
+
+    StoreEnumeration(Enumeration cache, Enumeration fs) {
+      this.mCache = cache;
+      this.mFs = fs;
+      this.index = 0;
+    }
+
+    public boolean hasMoreElements() {
+      return (mCache.hasMoreElements() || mFs.hasMoreElements());
+    }
+
+    public Object nextElement() {
+      if (mCache.hasMoreElements()) {
+        return mCache.nextElement();
+      } else {
+        return mFs.nextElement();
+      }
+    }
   }
 }
Index: MemoryStore.java
===================================================================
RCS file: /home/cvspublic/xml-cocoon2/src/org/apache/cocoon/components/store/MemoryStore.java,v
retrieving revision 1.5
diff -u -r1.5 MemoryStore.java
--- MemoryStore.java	2001/10/11 07:28:19	1.5
+++ MemoryStore.java	2001/11/20 16:13:27
@@ -83,4 +83,8 @@
     public Enumeration keys() {
         return(table.keys());
     }
+
+    public Enumeration keys(String name) {
+        return this.keys();
+    }
 }
Index: Store.java
===================================================================
RCS file: /home/cvspublic/xml-cocoon2/src/org/apache/cocoon/components/store/Store.java,v
retrieving revision 1.6
diff -u -r1.6 Store.java
--- Store.java	2001/10/11 07:28:19	1.6
+++ Store.java	2001/11/20 16:13:27
@@ -62,4 +62,11 @@
      */
     Enumeration keys();
 
+    /**
+     * Returns the list of used keys as an Enumeration of Objects.
+     * 
+     * @param The name of the current cachdir as String
+     */
+    Enumeration keys(String cachedir);
+
 }
Index: StoreJanitor.java
===================================================================
RCS file: /home/cvspublic/xml-cocoon2/src/org/apache/cocoon/components/store/StoreJanitor.java,v
retrieving revision 1.3
diff -u -r1.3 StoreJanitor.java
--- StoreJanitor.java	2001/10/11 07:28:19	1.3
+++ StoreJanitor.java	2001/11/20 16:13:27
@@ -9,12 +9,14 @@
 
 import org.apache.avalon.framework.component.Component;
 
+import org.apache.avalon.framework.activity.Startable;
+
 /**
  * Interface for the StoreJanitors
  *
  * @author <a href="mailto:g-froehlich@gmx.de">Gerhard Froehlich</a>
  */
-public interface StoreJanitor extends Component {
+public interface StoreJanitor extends Component,Startable {
 
   String ROLE = "org.apache.cocoon.components.store.StoreJanitor";
 
Index: StoreJanitorImpl.java
===================================================================
RCS file: /home/cvspublic/xml-cocoon2/src/org/apache/cocoon/components/store/StoreJanitorImpl.java,v
retrieving revision 1.5
diff -u -r1.5 StoreJanitorImpl.java
--- StoreJanitorImpl.java	2001/10/11 07:28:19	1.5
+++ StoreJanitorImpl.java	2001/11/20 16:13:28
@@ -8,10 +8,15 @@
 package org.apache.cocoon.components.store;
 
 import org.apache.avalon.framework.configuration.Configurable;
+
 import org.apache.avalon.framework.configuration.Configuration;
+
 import org.apache.avalon.framework.configuration.ConfigurationException;
+
 import org.apache.avalon.framework.logger.AbstractLoggable;
+
 import org.apache.avalon.framework.parameters.Parameters;
+
 import org.apache.avalon.framework.thread.ThreadSafe;
 
 import java.util.ArrayList;
@@ -27,7 +32,7 @@
  */
 public class StoreJanitorImpl extends AbstractLoggable implements StoreJanitor,
                                                                   Configurable, 
-                                                                  ThreadSafe, 
+                                                                  ThreadSafe,
                                                                   Runnable {
 
   private int freememory = -1;
@@ -37,8 +42,8 @@
   private Runtime jvm;
   private ArrayList storelist;
   private int index = -1;
+  private static boolean doRun = true;
 
-
   /** 
    * Initialize the StoreJanitorImpl.
    * A few options can be used :
@@ -76,7 +81,9 @@
     }
 
     this.setStoreList(new ArrayList());
+  }
 
+  public void start() {
     Thread checker = new Thread(this);
     this.getLogger().debug("Intializing checker thread");
     checker.setPriority(this.getPriority());
@@ -85,11 +92,15 @@
     checker.start();
   }
 
+  public void stop() {
+    doRun = false;
+  }
+
   /**
    * The "checker" thread checks if memory is running low in the jvm.
    */
   public void run() {
-    while (true) {
+    while (doRun) {
       // amount of memory used is greater then heapsize
       if (this.memoryLow()) {
         this.getLogger().debug("Invoking garbage collection, total memory = "


