You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by tc...@apache.org on 2007/02/19 10:56:51 UTC

svn commit: r509144 [1/2] - in /jakarta/commons/sandbox/jci/trunk: compilers/eclipse/src/test/ compilers/eclipse/src/test/java/ compilers/eclipse/src/test/java/org/ compilers/eclipse/src/test/java/org/apache/ compilers/eclipse/src/test/java/org/apache/...

Author: tcurdt
Date: Mon Feb 19 01:56:48 2007
New Revision: 509144

URL: http://svn.apache.org/viewvc?view=rev&rev=509144
Log:
better project separation,
tests back to sub-projects,
renamed a few FAM listener methods,
added observer / monitor separation,
new monitoring algorithm supporting type changes etc,
prepared monitoring abstraction,
removed the general listener mess

a few fixes and little changes are still to come ...but already in much better shape for a release


Added:
    jakarta/commons/sandbox/jci/trunk/compilers/eclipse/src/test/
    jakarta/commons/sandbox/jci/trunk/compilers/eclipse/src/test/java/
    jakarta/commons/sandbox/jci/trunk/compilers/eclipse/src/test/java/org/
    jakarta/commons/sandbox/jci/trunk/compilers/eclipse/src/test/java/org/apache/
    jakarta/commons/sandbox/jci/trunk/compilers/eclipse/src/test/java/org/apache/commons/
    jakarta/commons/sandbox/jci/trunk/compilers/eclipse/src/test/java/org/apache/commons/jci/
    jakarta/commons/sandbox/jci/trunk/compilers/eclipse/src/test/java/org/apache/commons/jci/compilers/
    jakarta/commons/sandbox/jci/trunk/compilers/eclipse/src/test/java/org/apache/commons/jci/compilers/EclipseJavaCompilerTestCase.java   (with props)
    jakarta/commons/sandbox/jci/trunk/core/src/main/java/org/apache/commons/jci/listeners/ReloadNotificationListener.java   (with props)
    jakarta/commons/sandbox/jci/trunk/core/src/test/java/org/apache/commons/jci/AbstractTestCase.java   (with props)
    jakarta/commons/sandbox/jci/trunk/core/src/test/java/org/apache/commons/jci/CompilingClassLoaderTestCase.java   (with props)
    jakarta/commons/sandbox/jci/trunk/core/src/test/java/org/apache/commons/jci/ReloadingClassLoaderTestCase.java   (with props)
    jakarta/commons/sandbox/jci/trunk/core/src/test/java/org/apache/commons/jci/classes/
    jakarta/commons/sandbox/jci/trunk/core/src/test/java/org/apache/commons/jci/classes/ExtendedDump.java   (with props)
    jakarta/commons/sandbox/jci/trunk/core/src/test/java/org/apache/commons/jci/classes/SimpleDump.java   (with props)
    jakarta/commons/sandbox/jci/trunk/core/src/test/java/org/apache/commons/jci/readers/
    jakarta/commons/sandbox/jci/trunk/core/src/test/java/org/apache/commons/jci/readers/ResourceReaderTestCase.java   (with props)
    jakarta/commons/sandbox/jci/trunk/core/src/test/java/org/apache/commons/jci/stores/
    jakarta/commons/sandbox/jci/trunk/core/src/test/java/org/apache/commons/jci/stores/ResourceStoreTestCase.java   (with props)
    jakarta/commons/sandbox/jci/trunk/fam/src/test/java/simplelog.properties   (with props)
Removed:
    jakarta/commons/sandbox/jci/trunk/core/src/main/java/org/apache/commons/jci/ReloadingClassLoaderListener.java
    jakarta/commons/sandbox/jci/trunk/core/src/main/java/org/apache/commons/jci/listeners/ResourceStoringListener.java
    jakarta/commons/sandbox/jci/trunk/core/src/test/resources/
    jakarta/commons/sandbox/jci/trunk/fam/src/main/java/org/apache/commons/jci/listeners/NotificationListener.java
    jakarta/commons/sandbox/jci/trunk/fam/src/main/java/org/apache/commons/jci/listeners/NotifyingListener.java
    jakarta/commons/sandbox/jci/trunk/tests/src/test/java/org/apache/commons/jci/AbstractTestCase.java
    jakarta/commons/sandbox/jci/trunk/tests/src/test/java/org/apache/commons/jci/CompilerUtils.java
    jakarta/commons/sandbox/jci/trunk/tests/src/test/java/org/apache/commons/jci/CompilingClassLoaderTestCase.java
    jakarta/commons/sandbox/jci/trunk/tests/src/test/java/org/apache/commons/jci/ReloadingClassLoaderTestCase.java
    jakarta/commons/sandbox/jci/trunk/tests/src/test/java/org/apache/commons/jci/readers/FileResourceReaderTestCase.java
    jakarta/commons/sandbox/jci/trunk/tests/src/test/java/org/apache/commons/jci/stores/AbstractStoreTestCase.java
    jakarta/commons/sandbox/jci/trunk/tests/src/test/java/org/apache/commons/jci/stores/FileResourceStoreTestCase.java
    jakarta/commons/sandbox/jci/trunk/tests/src/test/java/org/apache/commons/jci/stores/MemoryResourceStoreTestCase.java
    jakarta/commons/sandbox/jci/trunk/tests/src/test/java/org/apache/commons/jci/stores/TransactinonalResourceStoreTestCase.java
Modified:
    jakarta/commons/sandbox/jci/trunk/core/pom.xml
    jakarta/commons/sandbox/jci/trunk/core/src/main/java/org/apache/commons/jci/ReloadingClassLoader.java
    jakarta/commons/sandbox/jci/trunk/core/src/main/java/org/apache/commons/jci/listeners/CompilingListener.java
    jakarta/commons/sandbox/jci/trunk/core/src/main/java/org/apache/commons/jci/listeners/FileChangeListener.java
    jakarta/commons/sandbox/jci/trunk/core/src/main/java/org/apache/commons/jci/listeners/ReloadingListener.java
    jakarta/commons/sandbox/jci/trunk/core/src/main/java/org/apache/commons/jci/stores/MemoryResourceStore.java
    jakarta/commons/sandbox/jci/trunk/core/src/main/java/org/apache/commons/jci/stores/ResourceStoreClassLoader.java
    jakarta/commons/sandbox/jci/trunk/core/src/main/java/org/apache/commons/jci/utils/ClassUtils.java
    jakarta/commons/sandbox/jci/trunk/fam/src/main/java/org/apache/commons/jci/listeners/AbstractFilesystemAlterationListener.java
    jakarta/commons/sandbox/jci/trunk/fam/src/main/java/org/apache/commons/jci/monitor/FilesystemAlterationListener.java
    jakarta/commons/sandbox/jci/trunk/fam/src/main/java/org/apache/commons/jci/monitor/FilesystemAlterationMonitor.java
    jakarta/commons/sandbox/jci/trunk/fam/src/main/java/org/apache/commons/jci/monitor/FilesystemAlterationObserver.java
    jakarta/commons/sandbox/jci/trunk/fam/src/main/java/org/apache/commons/jci/monitor/FilesystemAlterationObserverImpl.java
    jakarta/commons/sandbox/jci/trunk/fam/src/test/java/org/apache/commons/jci/monitor/FilesystemAlterationMonitorTestCase.java

Added: jakarta/commons/sandbox/jci/trunk/compilers/eclipse/src/test/java/org/apache/commons/jci/compilers/EclipseJavaCompilerTestCase.java
URL: http://svn.apache.org/viewvc/jakarta/commons/sandbox/jci/trunk/compilers/eclipse/src/test/java/org/apache/commons/jci/compilers/EclipseJavaCompilerTestCase.java?view=auto&rev=509144
==============================================================================
--- jakarta/commons/sandbox/jci/trunk/compilers/eclipse/src/test/java/org/apache/commons/jci/compilers/EclipseJavaCompilerTestCase.java (added)
+++ jakarta/commons/sandbox/jci/trunk/compilers/eclipse/src/test/java/org/apache/commons/jci/compilers/EclipseJavaCompilerTestCase.java Mon Feb 19 01:56:48 2007
@@ -0,0 +1,7 @@
+package org.apache.commons.jci.compilers;
+
+import junit.framework.TestCase;
+
+public class EclipseJavaCompilerTestCase extends TestCase {
+
+}

Propchange: jakarta/commons/sandbox/jci/trunk/compilers/eclipse/src/test/java/org/apache/commons/jci/compilers/EclipseJavaCompilerTestCase.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jakarta/commons/sandbox/jci/trunk/compilers/eclipse/src/test/java/org/apache/commons/jci/compilers/EclipseJavaCompilerTestCase.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision Author HeadURL Id

Propchange: jakarta/commons/sandbox/jci/trunk/compilers/eclipse/src/test/java/org/apache/commons/jci/compilers/EclipseJavaCompilerTestCase.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: jakarta/commons/sandbox/jci/trunk/core/pom.xml
URL: http://svn.apache.org/viewvc/jakarta/commons/sandbox/jci/trunk/core/pom.xml?view=diff&rev=509144&r1=509143&r2=509144
==============================================================================
--- jakarta/commons/sandbox/jci/trunk/core/pom.xml (original)
+++ jakarta/commons/sandbox/jci/trunk/core/pom.xml Mon Feb 19 01:56:48 2007
@@ -54,6 +54,13 @@
       <version>3.1</version>
     </dependency>
 
+    <dependency>
+      <groupId>asm</groupId>
+      <artifactId>asm</artifactId>
+      <version>2.2.1</version>
+      <scope>test</scope>
+    </dependency>
+
   </dependencies>
 
 </project>

Modified: jakarta/commons/sandbox/jci/trunk/core/src/main/java/org/apache/commons/jci/ReloadingClassLoader.java
URL: http://svn.apache.org/viewvc/jakarta/commons/sandbox/jci/trunk/core/src/main/java/org/apache/commons/jci/ReloadingClassLoader.java?view=diff&rev=509144&r1=509143&r2=509144
==============================================================================
--- jakarta/commons/sandbox/jci/trunk/core/src/main/java/org/apache/commons/jci/ReloadingClassLoader.java (original)
+++ jakarta/commons/sandbox/jci/trunk/core/src/main/java/org/apache/commons/jci/ReloadingClassLoader.java Mon Feb 19 01:56:48 2007
@@ -18,8 +18,8 @@
 
 import java.io.InputStream;
 import java.net.URL;
-import org.apache.commons.jci.listeners.NotificationListener;
-import org.apache.commons.jci.listeners.ReloadingListener;
+
+import org.apache.commons.jci.listeners.ReloadNotificationListener;
 import org.apache.commons.jci.stores.ResourceStore;
 import org.apache.commons.jci.stores.ResourceStoreClassLoader;
 import org.apache.commons.logging.Log;
@@ -28,14 +28,15 @@
 /**
  * @author tcurdt
  */
-public class ReloadingClassLoader extends ClassLoader implements NotificationListener {
+public class ReloadingClassLoader extends ClassLoader implements ReloadNotificationListener {
     
     private final Log log = LogFactory.getLog(ReloadingClassLoader.class);
     
     private final ClassLoader parent;
-    //private final Collection reloadingListeners = new HashSet();
     private ResourceStore[] stores = new ResourceStore[0];
     private ClassLoader delegate;
+
+    //private final Collection reloadingListeners = new HashSet();
     
     public ReloadingClassLoader( final ClassLoader pParent ) {        
         super(pParent);
@@ -44,32 +45,33 @@
         delegate = new ResourceStoreClassLoader(parent, stores);
     }
 
-    public void addListener(final ReloadingListener pListener) {
-        pListener.setNotificationListener(this);
-        addResourceStore(pListener.getStore());
-    }
+//    public void addListener(final ReloadingListener pListener) {
+////        pListener.setNotificationListener(this);
+//        addResourceStore(pListener.getStore());
+//    }
     
-    public void removeListener(final ReloadingListener pListener) {
-        removeResourceStore(pListener.getStore());
-        pListener.setNotificationListener(null);
-    }
+//    public void removeListener(final ReloadingListener pListener) {
+//        removeResourceStore(pListener.getStore());
+////        pListener.setNotificationListener(null);
+//    }
     
-    private boolean addResourceStore( final ResourceStore pStore ) {
+    public boolean addResourceStore( final ResourceStore pStore ) {
         try {        
             final int n = stores.length;
             final ResourceStore[] newStores = new ResourceStore[n + 1];
-            System.arraycopy(stores, 0, newStores, 0, n);
-            newStores[n] = pStore;
+            System.arraycopy(stores, 0, newStores, 1, n);
+            newStores[0] = pStore;
             stores = newStores;
-            delegate = new ResourceStoreClassLoader(parent, stores);
+            delegate = new ResourceStoreClassLoader(parent, stores);            
             return true;
         } catch ( final Exception e ) {
+        	e.printStackTrace();
             // TODO: rethrow?
         }
         return false;
     }
 
-    private boolean removeResourceStore( final ResourceStore pStore ) {
+    public boolean removeResourceStore( final ResourceStore pStore ) {
         try {
             final int n = stores.length;
             int i = 0;
@@ -78,8 +80,7 @@
             while ( ( i <= n )  && ( stores[i] != pStore ) ) {
                 i++;
             }
-            
-            
+                        
             //pStore was not found
             if ( i == n ) {
                 throw new Exception( "pStore was not found" );

Modified: jakarta/commons/sandbox/jci/trunk/core/src/main/java/org/apache/commons/jci/listeners/CompilingListener.java
URL: http://svn.apache.org/viewvc/jakarta/commons/sandbox/jci/trunk/core/src/main/java/org/apache/commons/jci/listeners/CompilingListener.java?view=diff&rev=509144&r1=509143&r2=509144
==============================================================================
--- jakarta/commons/sandbox/jci/trunk/core/src/main/java/org/apache/commons/jci/listeners/CompilingListener.java (original)
+++ jakarta/commons/sandbox/jci/trunk/core/src/main/java/org/apache/commons/jci/listeners/CompilingListener.java Mon Feb 19 01:56:48 2007
@@ -24,6 +24,7 @@
 import org.apache.commons.jci.compilers.CompilationResult;
 import org.apache.commons.jci.compilers.JavaCompiler;
 import org.apache.commons.jci.compilers.JavaCompilerFactory;
+import org.apache.commons.jci.monitor.FilesystemAlterationObserver;
 import org.apache.commons.jci.problems.CompilationProblem;
 import org.apache.commons.jci.readers.FileResourceReader;
 import org.apache.commons.jci.readers.ResourceReader;
@@ -37,30 +38,25 @@
 
 public class CompilingListener extends ReloadingListener {
 
-    private final static Log log = LogFactory.getLog(CompilingListener.class);
+    private final Log log = LogFactory.getLog(CompilingListener.class);
     
     private final JavaCompiler compiler;
-    private final ResourceReader reader;
     private final TransactionalResourceStore transactionalStore;
+    private ResourceReader reader;
     private CompilationResult lastResult;
     
-    public CompilingListener( final File pRepository ) {
-        this(pRepository,
-             new JavaCompilerFactory().createCompiler("eclipse"),
-             new TransactionalResourceStore(new MemoryResourceStore())
-             );
+    public CompilingListener() {
+        this(new JavaCompilerFactory().createCompiler("eclipse"));
+    }
+
+    public CompilingListener( final JavaCompiler pCompiler ) {
+        this(pCompiler, new TransactionalResourceStore(new MemoryResourceStore()));
     }
     
-    public CompilingListener(
-            final File pRepository,
-            final JavaCompiler pCompiler,
-            final TransactionalResourceStore pTransactionalStore
-            ) {
-        super(pRepository);
+    public CompilingListener( final JavaCompiler pCompiler, final TransactionalResourceStore pTransactionalStore ) {
+    	super(pTransactionalStore);
         compiler = pCompiler;
         transactionalStore = pTransactionalStore;
-
-        reader = new FileResourceReader(pRepository);
         lastResult = null;
     }
     
@@ -72,25 +68,38 @@
         return lastResult;
     }
     
-    public void onStart() {
-        super.onStart();
-        transactionalStore.onStart();
-    }
+    public void onStart( final FilesystemAlterationObserver pObserver ) {
+        super.onStart(pObserver);
 
-    public void onStop() {
-        boolean reload = false;
+        reader = new FileResourceReader(pObserver.getRootDirectory());
 
-        log.debug("created:" + created.size()
-                + " changed:" + changed.size()
-                + " deleted:" + deleted.size()
-                + " resources");
+        transactionalStore.onStart();
+    }
 
+    public boolean isReloadRequired( final FilesystemAlterationObserver pObserver ) {
+    	boolean reload = false;
+    	
+        final Collection created = getCreatedFiles();
+        final Collection changed = getChangedFiles();
+        final Collection deleted = getDeletedFiles();
         
+        log.debug("created:" + created.size() + " changed:" + changed.size() + " deleted:" + deleted.size() + " resources");
+
         if (deleted.size() > 0) {
             for (Iterator it = deleted.iterator(); it.hasNext();) {
-                final File file = (File) it.next();
+                final File deletedFile = (File) it.next();
+
+                if (deletedFile.getName().endsWith(".java")) {
+                    transactionalStore.remove(
+                    		ClassUtils.stripExtension(
+                    				ClassUtils.relative(pObserver.getRootDirectory(), deletedFile)) + ".class");
+                } else {
+                    transactionalStore.remove(ClassUtils.relative(pObserver.getRootDirectory(), deletedFile));                	
+                }
+
+                
                 // FIXME: does not remove nested classes
-                transactionalStore.remove(ClassUtils.clazzName(repository, file));
+                
             }
             reload = true;
         }
@@ -113,21 +122,19 @@
 
         if (compileables.size() > 0) {
 
-            log.debug(compileables.size()
-                    + " classes to compile"
-                    );
+            log.debug(compileables.size() + " classes to compile");
 
             int i = 0;
-            final String[] clazzes = new String[compileables.size()];            
+            final String[] sourceFiles = new String[compileables.size()];            
             for (Iterator it = compileables.iterator(); it.hasNext();) {
                 final File file = (File) it.next();
-                clazzes[i] = ClassUtils.clazzName(repository, file);
+                sourceFiles[i] = ClassUtils.relative(pObserver.getRootDirectory(), file);
                 i++;
             }
             
             final CompilationResult result =
                 compiler.compile(
-                    clazzes,
+                    sourceFiles,
                     reader,
                     transactionalStore
                     );
@@ -147,16 +154,14 @@
             if (errors.length > 0) {
                 // FIXME: they need to be marked for re-compilation
                 // and then added as compileables again
-                for (int j = 0; j < clazzes.length; j++) {
-                    transactionalStore.remove(clazzes[j]);
+                for (int j = 0; j < sourceFiles.length; j++) {
+                    transactionalStore.remove(sourceFiles[j]);
                 }
             }
             
             reload = true;
         }
-
-        transactionalStore.onStop();
-
-        super.onStop();
-    }
+        
+        return reload;
+    }    
 }

Modified: jakarta/commons/sandbox/jci/trunk/core/src/main/java/org/apache/commons/jci/listeners/FileChangeListener.java
URL: http://svn.apache.org/viewvc/jakarta/commons/sandbox/jci/trunk/core/src/main/java/org/apache/commons/jci/listeners/FileChangeListener.java?view=diff&rev=509144&r1=509143&r2=509144
==============================================================================
--- jakarta/commons/sandbox/jci/trunk/core/src/main/java/org/apache/commons/jci/listeners/FileChangeListener.java (original)
+++ jakarta/commons/sandbox/jci/trunk/core/src/main/java/org/apache/commons/jci/listeners/FileChangeListener.java Mon Feb 19 01:56:48 2007
@@ -2,46 +2,49 @@
 
 import java.io.File;
 
+import org.apache.commons.jci.monitor.FilesystemAlterationObserver;
 
-public class FileChangeListener extends NotifyingListener {
+
+public class FileChangeListener extends AbstractFilesystemAlterationListener {
 
     private boolean changed;
-        
-    public FileChangeListener(final File pRepository) {
-        super(pRepository);
+    
+    public boolean hasChanged() {
+    	return changed;
     }
     
-    public void onStart() {
+    public void onStart( final FilesystemAlterationObserver pObserver ) {
         changed = false;
+    	super.onStart(pObserver);
     }
 
-    public void onStop() {
-    	super.onStop();
+    public void onStop( final FilesystemAlterationObserver pObserver ) {
+    	super.onStop(pObserver);
     }
 
     
-    public void onChangeFile( File pFile ) {
+    public void onFileChange( final File pFile ) {
         changed = true;
     }
 
 
-    public void onCreateFile( File pFile ) {
+    public void onFileCreate( final File pFile ) {
         changed = true;
     }
 
 
-    public void onDeleteFile( File pFile ) {
+    public void onFileDelete( final File pFile ) {
         changed = true;
     }
 
 
-    public void onChangeDirectory( File pDir ) {
+    public void onDirectoryChange( final File pDir ) {
     }
 
-    public void onCreateDirectory( File pDir ) {
+    public void onDirectoryCreate( final File pDir ) {
     }
 
-    public void onDeleteDirectory( File pDir ) {
+    public void onDirectoryDelete( final File pDir ) {
     }
     
 }

Added: jakarta/commons/sandbox/jci/trunk/core/src/main/java/org/apache/commons/jci/listeners/ReloadNotificationListener.java
URL: http://svn.apache.org/viewvc/jakarta/commons/sandbox/jci/trunk/core/src/main/java/org/apache/commons/jci/listeners/ReloadNotificationListener.java?view=auto&rev=509144
==============================================================================
--- jakarta/commons/sandbox/jci/trunk/core/src/main/java/org/apache/commons/jci/listeners/ReloadNotificationListener.java (added)
+++ jakarta/commons/sandbox/jci/trunk/core/src/main/java/org/apache/commons/jci/listeners/ReloadNotificationListener.java Mon Feb 19 01:56:48 2007
@@ -0,0 +1,5 @@
+package org.apache.commons.jci.listeners;
+
+public interface ReloadNotificationListener {
+	void handleNotification();
+}

Propchange: jakarta/commons/sandbox/jci/trunk/core/src/main/java/org/apache/commons/jci/listeners/ReloadNotificationListener.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jakarta/commons/sandbox/jci/trunk/core/src/main/java/org/apache/commons/jci/listeners/ReloadNotificationListener.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision Author HeadURL Id

Propchange: jakarta/commons/sandbox/jci/trunk/core/src/main/java/org/apache/commons/jci/listeners/ReloadNotificationListener.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: jakarta/commons/sandbox/jci/trunk/core/src/main/java/org/apache/commons/jci/listeners/ReloadingListener.java
URL: http://svn.apache.org/viewvc/jakarta/commons/sandbox/jci/trunk/core/src/main/java/org/apache/commons/jci/listeners/ReloadingListener.java?view=diff&rev=509144&r1=509143&r2=509144
==============================================================================
--- jakarta/commons/sandbox/jci/trunk/core/src/main/java/org/apache/commons/jci/listeners/ReloadingListener.java (original)
+++ jakarta/commons/sandbox/jci/trunk/core/src/main/java/org/apache/commons/jci/listeners/ReloadingListener.java Mon Feb 19 01:56:48 2007
@@ -18,12 +18,14 @@
 
 import java.io.File;
 import java.io.FileInputStream;
-import java.util.ArrayList;
 import java.util.Collection;
+import java.util.HashSet;
 import java.util.Iterator;
+import java.util.Set;
 
 import org.apache.commons.io.IOUtils;
 import org.apache.commons.jci.ReloadingClassLoader;
+import org.apache.commons.jci.monitor.FilesystemAlterationObserver;
 import org.apache.commons.jci.stores.MemoryResourceStore;
 import org.apache.commons.jci.stores.ResourceStore;
 import org.apache.commons.jci.stores.Transactional;
@@ -32,53 +34,47 @@
 import org.apache.commons.logging.LogFactory;
 
 
-public class ReloadingListener extends ResourceStoringListener {
+public class ReloadingListener extends AbstractFilesystemAlterationListener {
 
     private final Log log = LogFactory.getLog(ReloadingListener.class);
 
-    protected final Collection created = new ArrayList();
-    protected final Collection changed = new ArrayList();
-    protected final Collection deleted = new ArrayList();
-
+    private final Set notificationListeners = new HashSet();
     private final ResourceStore store;
-
-    protected ReloadingClassLoader reloader;
     
-    public ReloadingListener( final File pRepository ) {
-        this(pRepository, new MemoryResourceStore());
+    public ReloadingListener() {
+        this(new MemoryResourceStore());
     }
 
-    public ReloadingListener( final File pRepository, final ResourceStore pStore ) {
-        super(pRepository);
+    public ReloadingListener( final ResourceStore pStore ) {
         store = pStore;
     }
     
     public ResourceStore getStore() {
         return store;
     }
-        
-    public void onStart() {
-        created.clear();
-        changed.clear();
-        deleted.clear();
-    }
 
-    public void onStop() {
-        boolean reload = false;
-        
-        log.debug("created:" + created.size()
-                + " changed:" + changed.size()
-                + " deleted:" + deleted.size()
-                + " resources");
-        
-        if (store instanceof Transactional) {
-            ((Transactional)store).onStart();
-        }
+    public void addReloadNotificationListener( final ReloadNotificationListener pNotificationListener ) {
+    	notificationListeners.add(pNotificationListener);
+    	
+    	if (pNotificationListener instanceof ReloadingClassLoader) {
+    		((ReloadingClassLoader)pNotificationListener).addResourceStore(store);
+    	}
+    	
+    }
+    
+    public boolean isReloadRequired( final FilesystemAlterationObserver pObserver ) {
+    	boolean reload = false;
+    	
+        final Collection created = getCreatedFiles();
+        final Collection changed = getChangedFiles();
+        final Collection deleted = getDeletedFiles();
         
+        log.debug("created:" + created.size() + " changed:" + changed.size() + " deleted:" + deleted.size() + " resources");
+
         if (deleted.size() > 0) {
             for (Iterator it = deleted.iterator(); it.hasNext();) {
                 final File file = (File) it.next();
-                final String resourceName = ClassUtils.clazzName(repository, file);
+                final String resourceName = ClassUtils.relative(pObserver.getRootDirectory(), file);
                 //if (resourceName.endsWith(".class")) {
                     store.remove(resourceName);
                 //}
@@ -91,7 +87,7 @@
                 final File file = (File) it.next();
                 try {
                     final byte[] bytes = IOUtils.toByteArray(new FileInputStream(file));
-                    final String resourceName = ClassUtils.clazzName(repository, file); 
+                    final String resourceName = ClassUtils.relative(pObserver.getRootDirectory(), file); 
                     //if (resourceName.endsWith(".class")) {
                         store.write(resourceName, bytes);
                     //}
@@ -108,7 +104,7 @@
                 final File file = (File) it.next();
                 try {
                     final byte[] bytes = IOUtils.toByteArray(new FileInputStream(file));
-                    final String resourceName = ClassUtils.clazzName(repository, file); 
+                    final String resourceName = ClassUtils.relative(pObserver.getRootDirectory(), file); 
                     //if (resourceName.endsWith(".class")) {
                         store.write(resourceName, bytes);
                     //}
@@ -118,36 +114,41 @@
             }
             reload = true;
         }
+    	
+        return reload;
+    }
+    
+    public void onStop( final FilesystemAlterationObserver pObserver ) {
+        
+        
+        if (store instanceof Transactional) {
+            ((Transactional)store).onStart();
+        }
+
+        final boolean reload = isReloadRequired(pObserver);
 
         if (store instanceof Transactional) {
             ((Transactional)store).onStop();
         }
-
         
-        if (reload && notificationListener != null) {
-        	notificationListener.handleNotification();
+        if (reload) {
+        	notifyReloadNotificationListeners();
         }
         
-        super.onStop();
+        super.onStop(pObserver);
     }
 
-    public void onCreateFile( final File pFile ) {
-        created.add(pFile);
-        super.onCreateFile(pFile);
-    }
-    public void onChangeFile( final File pFile ) {                
-        changed.add(pFile);
-        super.onChangeFile(pFile);
+    void notifyReloadNotificationListeners() {
+    	for (Iterator it = notificationListeners.iterator(); it.hasNext();) {
+    		final ReloadNotificationListener listener = (ReloadNotificationListener) it.next();
+			listener.handleNotification();
+		}    	
     }
-    public void onDeleteFile( final File pFile ) {
-        deleted.add(pFile);
-        super.onDeleteFile(pFile);
-    }
-
-    public void onCreateDirectory( final File file ) {                
+    
+    public void onDirectoryCreate( final File pDir ) {                
     }
-    public void onChangeDirectory( final File file ) {                
+    public void onDirectoryChange( final File pDir ) {                
     }
-    public void onDeleteDirectory( final File file ) {
+    public void onDirectoryDelete( final File pDir ) {
     }
 }

Modified: jakarta/commons/sandbox/jci/trunk/core/src/main/java/org/apache/commons/jci/stores/MemoryResourceStore.java
URL: http://svn.apache.org/viewvc/jakarta/commons/sandbox/jci/trunk/core/src/main/java/org/apache/commons/jci/stores/MemoryResourceStore.java?view=diff&rev=509144&r1=509143&r2=509144
==============================================================================
--- jakarta/commons/sandbox/jci/trunk/core/src/main/java/org/apache/commons/jci/stores/MemoryResourceStore.java (original)
+++ jakarta/commons/sandbox/jci/trunk/core/src/main/java/org/apache/commons/jci/stores/MemoryResourceStore.java Mon Feb 19 01:56:48 2007
@@ -33,13 +33,14 @@
     private final Log log = LogFactory.getLog(MemoryResourceStore.class);
 
 	private final Map store = new HashMap();
-	
+		
 	public byte[] read( final String pResourceName ) {
+		log.debug("reading resource " + pResourceName);
 		return (byte[]) store.get(pResourceName);
 	}
 
 	public void write( final String pResourceName, final byte[] pData ) {
-		log.debug("storing resource " + pResourceName + "(" + pData.length + ")");
+		log.debug("writing resource " + pResourceName + "(" + pData.length + ")");
 		store.put(pResourceName, pData);
 	}
 	

Modified: jakarta/commons/sandbox/jci/trunk/core/src/main/java/org/apache/commons/jci/stores/ResourceStoreClassLoader.java
URL: http://svn.apache.org/viewvc/jakarta/commons/sandbox/jci/trunk/core/src/main/java/org/apache/commons/jci/stores/ResourceStoreClassLoader.java?view=diff&rev=509144&r1=509143&r2=509144
==============================================================================
--- jakarta/commons/sandbox/jci/trunk/core/src/main/java/org/apache/commons/jci/stores/ResourceStoreClassLoader.java (original)
+++ jakarta/commons/sandbox/jci/trunk/core/src/main/java/org/apache/commons/jci/stores/ResourceStoreClassLoader.java Mon Feb 19 01:56:48 2007
@@ -16,6 +16,7 @@
  */
 package org.apache.commons.jci.stores;
 
+import org.apache.commons.jci.utils.ClassUtils;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
@@ -28,11 +29,9 @@
     private final Log log = LogFactory.getLog(ResourceStoreClassLoader.class);
 
     private final ResourceStore[] stores;
-    //private final ClassLoader parent;
 
     public ResourceStoreClassLoader( final ClassLoader pParent, final ResourceStore[] pStores ) {
         super(pParent);
-        //parent = pParent;
         stores = pStores;
     }
 
@@ -41,7 +40,7 @@
         if (stores != null) {
             for (int i = 0; i < stores.length; i++) {
                 final ResourceStore store = stores[i];
-                final byte[] clazzBytes = store.read(name);
+                final byte[] clazzBytes = store.read(ClassUtils.convertClassToResourcePath(name));
                 if (clazzBytes != null) {
                     log.debug("found class " + name  + " (" + clazzBytes.length + " bytes)");
                     return defineClass(name, clazzBytes, 0, clazzBytes.length);
@@ -50,12 +49,12 @@
         }
         
         log.debug("did not find class " + name);
-        
+
         return null;            
     }
     
     protected synchronized Class loadClass(String name, boolean resolve) throws ClassNotFoundException {
-        log.debug("looking for " + name);
+        //log.debug("looking for " + name);
         Class clazz = findLoadedClass(name);
 
         if (clazz == null) {
@@ -66,13 +65,13 @@
                 final ClassLoader parent = getParent();
                 if (parent != null) {
                     clazz = parent.loadClass(name);
-                    log.debug("loaded from parent: " + name);
+                    //log.debug("loaded from parent: " + name);
                 } else {
                     throw new ClassNotFoundException(name);
                 }
                 
             } else {
-                log.debug("loaded from store: " + name);
+                //log.debug("loaded from store: " + name);
             }
         }
 

Modified: jakarta/commons/sandbox/jci/trunk/core/src/main/java/org/apache/commons/jci/utils/ClassUtils.java
URL: http://svn.apache.org/viewvc/jakarta/commons/sandbox/jci/trunk/core/src/main/java/org/apache/commons/jci/utils/ClassUtils.java?view=diff&rev=509144&r1=509143&r2=509144
==============================================================================
--- jakarta/commons/sandbox/jci/trunk/core/src/main/java/org/apache/commons/jci/utils/ClassUtils.java (original)
+++ jakarta/commons/sandbox/jci/trunk/core/src/main/java/org/apache/commons/jci/utils/ClassUtils.java Mon Feb 19 01:56:48 2007
@@ -9,12 +9,20 @@
 	 * Please do not use - internal
 	 * org/my/Class.xxx -> org.my.Class
 	 */
-	public static String convertResourceNameToClassName( final String pResourceName ) {
+	public static String convertResourceToClassName( final String pResourceName ) {
 		return ClassUtils.stripExtension(pResourceName).replace('/', '.');
 	}
 
 	/**
 	 * Please do not use - internal
+	 * org.my.Class -> org/my/Class.class
+	 */
+	public static String convertClassToResourcePath( final String pName ) {
+		return pName.replace('.', '/') + ".class";
+	}
+
+	/**
+	 * Please do not use - internal
 	 * org/my/Class.xxx -> org/my/Class
 	 */
 	public static String stripExtension( final String pResourceName ) {
@@ -38,4 +46,11 @@
 	    return clazzName;
 	}
 
+	public static String relative( final File base, final File file ) {
+	    final int rootLength = base.getAbsolutePath().length();
+	    final String absFileName = file.getAbsolutePath();
+	    final String relFileName = absFileName.substring(rootLength + 1);
+		return relFileName;
+	}
+	
 }

Added: jakarta/commons/sandbox/jci/trunk/core/src/test/java/org/apache/commons/jci/AbstractTestCase.java
URL: http://svn.apache.org/viewvc/jakarta/commons/sandbox/jci/trunk/core/src/test/java/org/apache/commons/jci/AbstractTestCase.java?view=auto&rev=509144
==============================================================================
--- jakarta/commons/sandbox/jci/trunk/core/src/test/java/org/apache/commons/jci/AbstractTestCase.java (added)
+++ jakarta/commons/sandbox/jci/trunk/core/src/test/java/org/apache/commons/jci/AbstractTestCase.java Mon Feb 19 01:56:48 2007
@@ -0,0 +1,133 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.jci;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.FileWriter;
+import java.io.IOException;
+import junit.framework.TestCase;
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+
+public abstract class AbstractTestCase extends TestCase {
+
+    private final Log log = LogFactory.getLog(AbstractTestCase.class);
+    
+    protected String extension = "java";
+
+    protected File directory;
+
+    /*
+    public void runBare() throws Throwable {
+        try {
+            setUp();
+            runTest();
+        } finally {
+            tearDown();
+        }
+    }
+    */
+    
+    protected void setUp() throws Exception {
+    	
+    	System.setProperty("org.apache.commons.logging.Log", "org.apache.commons.logging.impl.SimpleLog");
+    	
+        directory = createTempDirectory();
+        assertTrue(directory.exists());
+        assertTrue(directory.isDirectory());
+    }
+    
+    
+    protected File createDirectory( final String pName ) throws Exception {
+        final File newDirectory = new File(directory, pName);
+        assertTrue(newDirectory.mkdir());
+        assertTrue(newDirectory.exists());
+        assertTrue(newDirectory.isDirectory());
+        return newDirectory;
+    }
+    
+    protected File writeFile( final String pName, final byte[] pData ) throws Exception {
+        final File file = new File(directory, pName);
+        final File parent = file.getParentFile();
+        if (!parent.exists()) {
+            if (!parent.mkdirs()) {
+                throw new IOException("could not create" + parent);
+            }
+        }
+        
+        log.debug("writing file " + pName + " (" + pData.length + " bytes)");
+        
+        final FileOutputStream os = new FileOutputStream(file);
+        os.write(pData);
+        os.close();
+        
+        assertTrue(file.exists());
+        assertTrue(file.isFile());
+        
+        return file;
+    }
+
+    protected File writeFile( final String pName, final String pText ) throws Exception {
+        final File file = new File(directory, pName);
+        final File parent = file.getParentFile();
+        if (!parent.exists()) {
+            if (!parent.mkdirs()) {
+                throw new IOException("could not create" + parent);
+            }
+        }
+        log.debug("writing " + file);
+        final FileWriter writer = new FileWriter(file);
+        writer.write(pText);
+        writer.close();
+        
+        assertTrue(file.exists());
+        assertTrue(file.isFile());
+        
+        return file;
+    }
+    
+    protected void delay() {
+    	try {
+            Thread.sleep(1500);
+        } catch (final InterruptedException e) {
+        }
+    }
+    
+    protected File createTempDirectory() throws IOException {
+        final File tempFile = File.createTempFile("jci", null);
+        
+        if (!tempFile.delete()) {
+            throw new IOException();
+        }
+        
+        if (!tempFile.mkdir()) {
+            throw new IOException();
+        }
+        
+        return tempFile;         
+    }
+
+
+    protected void tearDown() throws Exception {
+        FileUtils.deleteDirectory(directory);
+    }
+
+
+}

Propchange: jakarta/commons/sandbox/jci/trunk/core/src/test/java/org/apache/commons/jci/AbstractTestCase.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jakarta/commons/sandbox/jci/trunk/core/src/test/java/org/apache/commons/jci/AbstractTestCase.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision Author HeadURL Id

Propchange: jakarta/commons/sandbox/jci/trunk/core/src/test/java/org/apache/commons/jci/AbstractTestCase.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: jakarta/commons/sandbox/jci/trunk/core/src/test/java/org/apache/commons/jci/CompilingClassLoaderTestCase.java
URL: http://svn.apache.org/viewvc/jakarta/commons/sandbox/jci/trunk/core/src/test/java/org/apache/commons/jci/CompilingClassLoaderTestCase.java?view=auto&rev=509144
==============================================================================
--- jakarta/commons/sandbox/jci/trunk/core/src/test/java/org/apache/commons/jci/CompilingClassLoaderTestCase.java (added)
+++ jakarta/commons/sandbox/jci/trunk/core/src/test/java/org/apache/commons/jci/CompilingClassLoaderTestCase.java Mon Feb 19 01:56:48 2007
@@ -0,0 +1,335 @@
+package org.apache.commons.jci;
+
+import java.io.File;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.jci.classes.ExtendedDump;
+import org.apache.commons.jci.classes.SimpleDump;
+import org.apache.commons.jci.compilers.CompilationResult;
+import org.apache.commons.jci.compilers.JavaCompiler;
+import org.apache.commons.jci.listeners.CompilingListener;
+import org.apache.commons.jci.monitor.FilesystemAlterationMonitor;
+import org.apache.commons.jci.problems.CompilationProblem;
+import org.apache.commons.jci.problems.CompilationProblemHandler;
+import org.apache.commons.jci.readers.ResourceReader;
+import org.apache.commons.jci.stores.ResourceStore;
+import org.apache.commons.jci.utils.ClassUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+
+public final class CompilingClassLoaderTestCase extends AbstractTestCase {
+
+	private final Log log = LogFactory.getLog(CompilingClassLoaderTestCase.class);
+
+    private ReloadingClassLoader classloader;
+    private CompilingListener listener;
+    private FilesystemAlterationMonitor fam;
+    
+//    private final static class BeanUtils {
+//        
+//        public static void setProperty( Object object, String property, Object value) throws SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException {
+//            final Class clazz = object.getClass();
+//            
+//            final Method setter = clazz.getMethod("set" + property, new Class[]{ value.getClass()});
+//            setter.invoke(object, new Object[]{ value });   
+//        }
+//    }
+    
+    
+    private final static class MockJavaCompiler implements JavaCompiler {
+
+        private final Log log = LogFactory.getLog(MockJavaCompiler.class);
+
+		public CompilationResult compile(String[] pResourcePaths, ResourceReader pReader, ResourceStore pStore, ClassLoader classLoader) {
+			
+			for (int i = 0; i < pResourcePaths.length; i++) {
+				final String resourcePath = pResourcePaths[i];				
+				final byte[] resourceContent = pReader.getBytes(resourcePath);
+				
+				log.debug("resource " + resourcePath + " = " + ((resourceContent!=null)?new String(resourceContent):null) );
+				
+				final byte[] data;
+				
+				if ("jci/Simple.java".equals(resourcePath)) {
+
+					try {
+						data = SimpleDump.dump(new String(resourceContent));
+					} catch (Exception e) {
+						throw new RuntimeException("cannot handle resource " + resourcePath, e);
+					}
+					
+				} else if ("jci/Extended.java".equals(resourcePath)) {
+
+					try {
+						data = ExtendedDump.dump();
+					} catch (Exception e) {
+						throw new RuntimeException("cannot handle resource " + resourcePath, e);
+					}
+					
+				} else {
+					throw new RuntimeException("cannot handle resource " + resourcePath);
+				}
+
+				log.debug("compiling " + resourcePath + " (" + data.length + ")");
+				
+				pStore.write(ClassUtils.stripExtension(resourcePath) + ".class", data);
+
+			}
+			
+			return new CompilationResult(new CompilationProblem[0]);
+		}
+
+		public CompilationResult compile(String[] pResourcePaths, ResourceReader pReader, ResourceStore pStore) {
+			return compile(pResourcePaths, pReader, pStore, null);
+		}
+
+		public void setCompilationProblemHandler(CompilationProblemHandler pHandler) {
+		}
+    	
+    }
+    
+    protected void setUp() throws Exception {
+        super.setUp();
+        
+        classloader = new ReloadingClassLoader(this.getClass().getClassLoader());
+        listener = new CompilingListener(new MockJavaCompiler());   
+
+        listener.addReloadNotificationListener(classloader);
+        
+        fam = new FilesystemAlterationMonitor();
+        fam.addListener(directory, listener);
+        fam.start();
+    }
+
+    private void initialCompile() throws Exception {
+        log.debug("initial compile");        
+
+        listener.waitForFirstCheck();
+                
+        writeFile("jci/Simple.java", "Simple1");        
+        writeFile("jci/Extended.java", "Extended");        
+        
+        log.debug("waiting for compile changes to get applied");        
+        listener.waitForCheck();
+        
+        log.debug("*** ready to test");        
+    }
+    
+    
+//    public void testCompileProblems() throws Exception {
+//        delay();        
+//        writeFile("jci/Simple.java", "JavaSources.error");
+//        listener.waitForEvent();
+//        
+//        // FIXME
+//    }
+    
+    public void testCreate() throws Exception {
+        initialCompile();
+        
+        log.debug("loading Simple");        
+        final Object simple = classloader.loadClass("jci.Simple").newInstance();        
+        assertEquals("Simple1", simple.toString());
+        
+        log.debug("loading Extended");        
+        final Object extended = classloader.loadClass("jci.Extended").newInstance();        
+        assertEquals("Extended:Simple1", extended.toString());
+    }
+
+    public void testChange() throws Exception {        
+        initialCompile();
+
+        final Object simple = classloader.loadClass("jci.Simple").newInstance();        
+        assertEquals("Simple1", simple.toString());
+        
+        final Object extended = classloader.loadClass("jci.Extended").newInstance();        
+        assertEquals("Extended:Simple1", extended.toString());
+
+        delay();
+        writeFile("jci/Simple.java", "Simple2");
+        listener.waitForCheck();
+    
+        final Object simple2 = classloader.loadClass("jci.Simple").newInstance();        
+        assertEquals("Simple2", simple2.toString());
+        
+        final Object newExtended = classloader.loadClass("jci.Extended").newInstance();        
+        assertEquals("Extended:Simple2", newExtended.toString());
+    }
+
+    public void testDelete() throws Exception {
+        initialCompile();
+
+        final Object simple = classloader.loadClass("jci.Simple").newInstance();        
+        assertEquals("Simple1", simple.toString());
+        
+        final Object extended = classloader.loadClass("jci.Extended").newInstance();        
+        assertEquals("Extended:Simple1", extended.toString());
+                
+        listener.waitForCheck();
+        
+        log.debug("deleting source file");
+        assertTrue(new File(directory, "jci/Extended.java").delete());
+        
+        listener.waitForCheck();
+       
+        log.debug("loading Simple");
+        final Object oldSimple = classloader.loadClass("jci.Simple").newInstance();        
+        assertEquals("Simple1", oldSimple.toString());
+
+        log.debug("trying to loading Extended");
+        try {
+            classloader.loadClass("jci.Extended").newInstance();
+            fail();
+        } catch(final ClassNotFoundException e) {
+            assertEquals("jci.Extended", e.getMessage());
+        }        
+        
+        log.debug("deleting whole directory");
+        FileUtils.deleteDirectory(new File(directory, "jci"));
+
+        listener.waitForCheck();
+
+        log.debug("trying to loading Simple");
+        try {
+            classloader.loadClass("jci.Simple").newInstance();
+            fail();
+        } catch(final ClassNotFoundException e) {
+            assertEquals("jci.Simple", e.getMessage());
+        }
+
+    }
+
+    public void testDeleteDependency() throws Exception {        
+        initialCompile();
+
+        final Object simple = classloader.loadClass("jci.Simple").newInstance();        
+        assertEquals("Simple1", simple.toString());
+        
+        final Object extended = classloader.loadClass("jci.Extended").newInstance();        
+        assertEquals("Extended:Simple1", extended.toString());
+        
+        log.debug("deleting source file");
+        assertTrue(new File(directory, "jci/Simple.java").delete());
+        listener.waitForCheck();
+
+        log.debug("trying to load dependend class");
+        try {
+            classloader.loadClass("jci.Extended").newInstance();
+            fail();
+        } catch(final NoClassDefFoundError e) {
+            assertEquals("jci/Simple", e.getMessage());
+        }
+        
+    }
+
+
+//    public void testReference1() throws Exception {        
+//        delay();        
+//        writeFile("jci/Foo.java",
+//                "package jci;\n" + 
+//                "\n" + 
+//                "public class Foo {\n" + 
+//                "    public String toString() {\n" + 
+//                "        return \"foo1\";\n" + 
+//                "    }\n" + 
+//                "}"
+//                );        
+//        writeFile("jci/Bar.java",
+//                "package jci;\n" + 
+//                "\n" + 
+//                "public class Bar {\n" + 
+//                "    \n" + 
+//                "    private Foo foo;\n" + 
+//                "    \n" + 
+//                "    public void setFoo( Foo foo) {\n" + 
+//                "        this.foo = foo;\n" + 
+//                "    }\n" + 
+//                "    \n" + 
+//                "    public String toString() {\n" + 
+//                "        return \"bar1\";\n" + 
+//                "    }\n" + 
+//                "}"
+//                );        
+//        listener.waitForEvent();
+//        
+//        final Object foo1 = classloader.loadClass("jci.Foo").newInstance();        
+//        assertTrue("foo1".equals(foo1.toString()));
+//
+//        final Object bar1 = classloader.loadClass("jci.Bar").newInstance();        
+//        assertTrue("bar1".equals(bar1.toString()));
+//        
+//        BeanUtils.setProperty(bar1, "Foo", foo1);
+//        
+//        delay();
+//        writeFile("jci/Foo.java",
+//                "package jci;\n" + 
+//                "\n" + 
+//                "public class Foo {\n" + 
+//                "    public String toString() {\n" + 
+//                "        return \"foo2\";\n" + 
+//                "    }\n" + 
+//                "}"
+//                );        
+//        listener.waitForEvent();
+//
+//        final Object foo2 = classloader.loadClass("jci.Foo").newInstance();        
+//        assertTrue("foo2".equals(foo2.toString()));
+//
+//        final Object bar2 = classloader.loadClass("jci.Bar").newInstance();        
+//        // has not change -> still bar1
+//        assertTrue("bar1".equals(bar2.toString()));
+//    
+//        BeanUtils.setProperty(bar2, "Foo", foo2);
+//        BeanUtils.setProperty(bar1, "Foo", foo2);
+//
+//    }
+//
+//    public void testReference2() throws Exception {        
+//        delay();        
+//        writeFile("jci/Foo.java",
+//                "package jci;\n" + 
+//                "\n" + 
+//                "public class Foo implements org.apache.commons.jci.MyFoo {\n" + 
+//                "    public String toString() {\n" + 
+//                "        return \"foo1\";\n" + 
+//                "    }\n" + 
+//                "}"
+//                );        
+//        listener.waitForEvent();
+//        
+//        final MyFoo foo1 = (MyFoo) classloader.loadClass("jci.Foo").newInstance();        
+//        assertTrue("foo1".equals(foo1.toString()));
+//
+//
+//        final MyBar bar1 = new MyBar();
+//        bar1.setFoo(foo1);
+//        
+//        delay();
+//        writeFile("jci/Foo.java",
+//                "package jci;\n" + 
+//                "\n" + 
+//                "public class Foo implements org.apache.commons.jci.MyFoo {\n" + 
+//                "    public String toString() {\n" + 
+//                "        return \"foo2\";\n" + 
+//                "    }\n" + 
+//                "}"
+//                );        
+//        listener.waitForEvent();
+//
+//        final MyFoo foo2 = (MyFoo) classloader.loadClass("jci.Foo").newInstance();        
+//        assertTrue("foo2".equals(foo2.toString()));
+//
+//        bar1.setFoo(foo2);
+//    }
+
+
+
+
+    protected void tearDown() throws Exception {
+        fam.removeListener(listener);
+        fam.stop();
+        super.tearDown();
+    }
+    
+}

Propchange: jakarta/commons/sandbox/jci/trunk/core/src/test/java/org/apache/commons/jci/CompilingClassLoaderTestCase.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jakarta/commons/sandbox/jci/trunk/core/src/test/java/org/apache/commons/jci/CompilingClassLoaderTestCase.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision Author HeadURL Id

Propchange: jakarta/commons/sandbox/jci/trunk/core/src/test/java/org/apache/commons/jci/CompilingClassLoaderTestCase.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: jakarta/commons/sandbox/jci/trunk/core/src/test/java/org/apache/commons/jci/ReloadingClassLoaderTestCase.java
URL: http://svn.apache.org/viewvc/jakarta/commons/sandbox/jci/trunk/core/src/test/java/org/apache/commons/jci/ReloadingClassLoaderTestCase.java?view=auto&rev=509144
==============================================================================
--- jakarta/commons/sandbox/jci/trunk/core/src/test/java/org/apache/commons/jci/ReloadingClassLoaderTestCase.java (added)
+++ jakarta/commons/sandbox/jci/trunk/core/src/test/java/org/apache/commons/jci/ReloadingClassLoaderTestCase.java Mon Feb 19 01:56:48 2007
@@ -0,0 +1,163 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.jci;
+
+import java.io.File;
+
+import org.apache.commons.jci.classes.ExtendedDump;
+import org.apache.commons.jci.classes.SimpleDump;
+import org.apache.commons.jci.listeners.ReloadingListener;
+import org.apache.commons.jci.monitor.FilesystemAlterationMonitor;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+
+public final class ReloadingClassLoaderTestCase extends AbstractTestCase {
+
+    private final Log log = LogFactory.getLog(ReloadingClassLoaderTestCase.class);
+    
+    private ReloadingClassLoader classloader;
+    private ReloadingListener listener;
+    private FilesystemAlterationMonitor fam;
+
+    private final byte[] clazzSimple1;
+    private final byte[] clazzSimple2;
+    private final byte[] clazzExtended;
+    
+    public ReloadingClassLoaderTestCase() throws Exception {
+        clazzSimple1 = SimpleDump.dump("Simple1");
+        clazzSimple2 = SimpleDump.dump("Simple2");
+        clazzExtended = ExtendedDump.dump(); 
+        assertTrue(clazzSimple1.length > 0);
+        assertTrue(clazzSimple2.length > 0);
+        assertTrue(clazzExtended.length > 0);
+    }
+    
+    protected void setUp() throws Exception {
+        super.setUp();
+        
+        classloader = new ReloadingClassLoader(this.getClass().getClassLoader());
+        listener = new ReloadingListener();
+        
+        listener.addReloadNotificationListener(classloader);
+        
+        fam = new FilesystemAlterationMonitor();
+        fam.addListener(directory, listener);
+        fam.start();
+    }
+
+    public void testCreate() throws Exception {
+        listener.waitForFirstCheck();
+
+        log.debug("creating class");        
+        writeFile("jci/Simple.class", clazzSimple1);
+        listener.waitForCheck();
+        
+        final Object simple = classloader.loadClass("jci.Simple").newInstance();        
+        assertEquals("Simple1", simple.toString());        
+    }
+
+    public void testChange() throws Exception {        
+        listener.waitForFirstCheck();
+
+        log.debug("creating class");
+        writeFile("jci/Simple.class", clazzSimple1);
+        listener.waitForCheck();
+
+        final Object simple1 = classloader.loadClass("jci.Simple").newInstance();        
+        assertEquals("Simple1", simple1.toString());
+        
+        log.debug("changing class");        
+        writeFile("jci/Simple.class", clazzSimple2);
+        listener.waitForEvent();
+    
+        final Object simple2 = classloader.loadClass("jci.Simple").newInstance();        
+        assertEquals("Simple2", simple2.toString());        
+    }
+
+    public void testDelete() throws Exception {
+        listener.waitForFirstCheck();
+
+        log.debug("creating class");
+        writeFile("jci/Simple.class", clazzSimple1);
+        listener.waitForCheck();
+
+        final Object simple = classloader.loadClass("jci.Simple").newInstance();        
+        assertEquals("Simple1", simple.toString());
+
+        log.debug("deleting class");        
+        assertTrue(new File(directory, "jci/Simple.class").delete());
+        listener.waitForEvent();
+
+        try {
+            classloader.loadClass("jci.Simple").newInstance();        
+            fail();
+        } catch(final ClassNotFoundException e) {
+            assertEquals("jci.Simple", e.getMessage());
+        }        
+    }
+
+    public void testDeleteDependency() throws Exception {        
+        listener.waitForFirstCheck();
+
+        log.debug("creating classes");
+        writeFile("jci/Simple.class", clazzSimple1);
+        writeFile("jci/Extended.class", clazzExtended);
+        listener.waitForCheck();
+
+        final Object simple = classloader.loadClass("jci.Simple").newInstance();        
+        assertEquals("Simple1", simple.toString());
+        
+        final Object extended = classloader.loadClass("jci.Extended").newInstance();        
+        assertEquals("Extended:Simple1", extended.toString());
+
+        log.debug("deleting class dependency");        
+        assertTrue(new File(directory, "jci/Simple.class").delete());
+        listener.waitForEvent();
+
+        try {
+            classloader.loadClass("jci.Extended").newInstance();
+            fail();
+        } catch(final NoClassDefFoundError e) {
+            assertEquals("jci/Simple", e.getMessage());
+        }
+    }
+
+    public void testClassNotFound() {
+        try {
+            classloader.loadClass("bla");
+            fail();
+        } catch(final ClassNotFoundException e) {
+            log.info(e.getMessage());
+        }
+    }
+    
+    public void testDelegation() {
+        classloader.clearAssertionStatus();
+        classloader.setClassAssertionStatus("org.apache.commons.jci.ReloadingClassLoader", true);
+        classloader.setDefaultAssertionStatus(false);
+        classloader.setPackageAssertionStatus("org.apache.commons.jci", true);
+        // FIXME: compare with delegation
+    }
+    
+    protected void tearDown() throws Exception {
+        fam.removeListener(listener);
+        fam.stop();
+        super.tearDown();
+    }
+    
+}

Propchange: jakarta/commons/sandbox/jci/trunk/core/src/test/java/org/apache/commons/jci/ReloadingClassLoaderTestCase.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jakarta/commons/sandbox/jci/trunk/core/src/test/java/org/apache/commons/jci/ReloadingClassLoaderTestCase.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision Author HeadURL Id

Propchange: jakarta/commons/sandbox/jci/trunk/core/src/test/java/org/apache/commons/jci/ReloadingClassLoaderTestCase.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: jakarta/commons/sandbox/jci/trunk/core/src/test/java/org/apache/commons/jci/classes/ExtendedDump.java
URL: http://svn.apache.org/viewvc/jakarta/commons/sandbox/jci/trunk/core/src/test/java/org/apache/commons/jci/classes/ExtendedDump.java?view=auto&rev=509144
==============================================================================
--- jakarta/commons/sandbox/jci/trunk/core/src/test/java/org/apache/commons/jci/classes/ExtendedDump.java (added)
+++ jakarta/commons/sandbox/jci/trunk/core/src/test/java/org/apache/commons/jci/classes/ExtendedDump.java Mon Feb 19 01:56:48 2007
@@ -0,0 +1,62 @@
+package org.apache.commons.jci.classes;
+
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.Label;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+
+
+public class ExtendedDump implements Opcodes {
+
+	public static byte[] dump() throws Exception {
+
+		ClassWriter cw = new ClassWriter(true);
+//		FieldVisitor fv;
+		MethodVisitor mv;
+//		AnnotationVisitor av0;
+
+		cw.visit(V1_4, ACC_PUBLIC + ACC_SUPER, "jci/Extended", null, "jci/Simple", null);
+
+		cw.visitSource("Extended.java", null);
+
+		{
+			mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
+			mv.visitCode();
+			Label l0 = new Label();
+			mv.visitLabel(l0);
+			mv.visitLineNumber(3, l0);
+			mv.visitVarInsn(ALOAD, 0);
+			mv.visitMethodInsn(INVOKESPECIAL, "jci/Simple", "<init>", "()V");
+			mv.visitInsn(RETURN);
+			Label l1 = new Label();
+			mv.visitLabel(l1);
+			mv.visitLocalVariable("this", "Ljci/Extended;", null, l0, l1, 0);
+			mv.visitMaxs(1, 1);
+			mv.visitEnd();
+		}
+		{
+			mv = cw.visitMethod(ACC_PUBLIC, "toString", "()Ljava/lang/String;", null, null);
+			mv.visitCode();
+			Label l0 = new Label();
+			mv.visitLabel(l0);
+			mv.visitLineNumber(6, l0);
+			mv.visitTypeInsn(NEW, "java/lang/StringBuffer");
+			mv.visitInsn(DUP);
+			mv.visitLdcInsn("Extended:");
+			mv.visitMethodInsn(INVOKESPECIAL, "java/lang/StringBuffer", "<init>", "(Ljava/lang/String;)V");
+			mv.visitVarInsn(ALOAD, 0);
+			mv.visitMethodInsn(INVOKESPECIAL, "jci/Simple", "toString", "()Ljava/lang/String;");
+			mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuffer", "append", "(Ljava/lang/String;)Ljava/lang/StringBuffer;");
+			mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuffer", "toString", "()Ljava/lang/String;");
+			mv.visitInsn(ARETURN);
+			Label l1 = new Label();
+			mv.visitLabel(l1);
+			mv.visitLocalVariable("this", "Ljci/Extended;", null, l0, l1, 0);
+			mv.visitMaxs(3, 1);
+			mv.visitEnd();
+		}
+		cw.visitEnd();
+
+		return cw.toByteArray();
+	}
+}

Propchange: jakarta/commons/sandbox/jci/trunk/core/src/test/java/org/apache/commons/jci/classes/ExtendedDump.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jakarta/commons/sandbox/jci/trunk/core/src/test/java/org/apache/commons/jci/classes/ExtendedDump.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision Author HeadURL Id

Propchange: jakarta/commons/sandbox/jci/trunk/core/src/test/java/org/apache/commons/jci/classes/ExtendedDump.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: jakarta/commons/sandbox/jci/trunk/core/src/test/java/org/apache/commons/jci/classes/SimpleDump.java
URL: http://svn.apache.org/viewvc/jakarta/commons/sandbox/jci/trunk/core/src/test/java/org/apache/commons/jci/classes/SimpleDump.java?view=auto&rev=509144
==============================================================================
--- jakarta/commons/sandbox/jci/trunk/core/src/test/java/org/apache/commons/jci/classes/SimpleDump.java (added)
+++ jakarta/commons/sandbox/jci/trunk/core/src/test/java/org/apache/commons/jci/classes/SimpleDump.java Mon Feb 19 01:56:48 2007
@@ -0,0 +1,54 @@
+package org.apache.commons.jci.classes;
+
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.Label;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+
+public class SimpleDump implements Opcodes {
+
+	public static byte[] dump( final String to ) throws Exception {
+
+	ClassWriter cw = new ClassWriter(true);
+//	FieldVisitor fv;
+	MethodVisitor mv;
+//	AnnotationVisitor av0;
+
+	cw.visit(V1_4, ACC_PUBLIC + ACC_SUPER, "jci/Simple", null, "java/lang/Object", null);
+
+	cw.visitSource("Simple.java", null);
+
+	{
+	mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
+	mv.visitCode();
+	Label l0 = new Label();
+	mv.visitLabel(l0);
+	mv.visitLineNumber(3, l0);
+	mv.visitVarInsn(ALOAD, 0);
+	mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V");
+	mv.visitInsn(RETURN);
+	Label l1 = new Label();
+	mv.visitLabel(l1);
+	mv.visitLocalVariable("this", "Ljci/Simple;", null, l0, l1, 0);
+	mv.visitMaxs(1, 1);
+	mv.visitEnd();
+	}
+	{
+	mv = cw.visitMethod(ACC_PUBLIC, "toString", "()Ljava/lang/String;", null, null);
+	mv.visitCode();
+	Label l0 = new Label();
+	mv.visitLabel(l0);
+	mv.visitLineNumber(6, l0);
+	mv.visitLdcInsn(to);
+	mv.visitInsn(ARETURN);
+	Label l1 = new Label();
+	mv.visitLabel(l1);
+	mv.visitLocalVariable("this", "Ljci/Simple;", null, l0, l1, 0);
+	mv.visitMaxs(1, 1);
+	mv.visitEnd();
+	}
+	cw.visitEnd();
+
+	return cw.toByteArray();
+	}
+}

Propchange: jakarta/commons/sandbox/jci/trunk/core/src/test/java/org/apache/commons/jci/classes/SimpleDump.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jakarta/commons/sandbox/jci/trunk/core/src/test/java/org/apache/commons/jci/classes/SimpleDump.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision Author HeadURL Id

Propchange: jakarta/commons/sandbox/jci/trunk/core/src/test/java/org/apache/commons/jci/classes/SimpleDump.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: jakarta/commons/sandbox/jci/trunk/core/src/test/java/org/apache/commons/jci/readers/ResourceReaderTestCase.java
URL: http://svn.apache.org/viewvc/jakarta/commons/sandbox/jci/trunk/core/src/test/java/org/apache/commons/jci/readers/ResourceReaderTestCase.java?view=auto&rev=509144
==============================================================================
--- jakarta/commons/sandbox/jci/trunk/core/src/test/java/org/apache/commons/jci/readers/ResourceReaderTestCase.java (added)
+++ jakarta/commons/sandbox/jci/trunk/core/src/test/java/org/apache/commons/jci/readers/ResourceReaderTestCase.java Mon Feb 19 01:56:48 2007
@@ -0,0 +1,28 @@
+package org.apache.commons.jci.readers;
+
+import org.apache.commons.jci.AbstractTestCase;
+
+
+public final class ResourceReaderTestCase extends AbstractTestCase {
+
+	public void testFileResourceReader() throws Exception {
+        writeFile("test", "test");
+		checkRead(new FileResourceReader(directory));
+	}
+
+	public void testMemoryResourceReader() throws Exception {
+		final MemoryResourceReader reader = new MemoryResourceReader();
+		reader.add("test", "test".getBytes());
+		checkRead(reader);
+	}
+	
+	private void checkRead( final ResourceReader reader ) throws Exception {
+        assertTrue(reader.isAvailable("test"));
+        final byte[] content = reader.getBytes("test");
+        assertTrue(content != null);
+        assertTrue("test".equals(new String(content)));        
+
+        assertTrue(!reader.isAvailable("bla"));
+        assertTrue(reader.getBytes("bla") == null);
+    }
+}

Propchange: jakarta/commons/sandbox/jci/trunk/core/src/test/java/org/apache/commons/jci/readers/ResourceReaderTestCase.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jakarta/commons/sandbox/jci/trunk/core/src/test/java/org/apache/commons/jci/readers/ResourceReaderTestCase.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision Author HeadURL Id

Propchange: jakarta/commons/sandbox/jci/trunk/core/src/test/java/org/apache/commons/jci/readers/ResourceReaderTestCase.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: jakarta/commons/sandbox/jci/trunk/core/src/test/java/org/apache/commons/jci/stores/ResourceStoreTestCase.java
URL: http://svn.apache.org/viewvc/jakarta/commons/sandbox/jci/trunk/core/src/test/java/org/apache/commons/jci/stores/ResourceStoreTestCase.java?view=auto&rev=509144
==============================================================================
--- jakarta/commons/sandbox/jci/trunk/core/src/test/java/org/apache/commons/jci/stores/ResourceStoreTestCase.java (added)
+++ jakarta/commons/sandbox/jci/trunk/core/src/test/java/org/apache/commons/jci/stores/ResourceStoreTestCase.java Mon Feb 19 01:56:48 2007
@@ -0,0 +1,52 @@
+package org.apache.commons.jci.stores;
+
+import org.apache.commons.jci.AbstractTestCase;
+import org.apache.commons.lang.ArrayUtils;
+
+
+public final class ResourceStoreTestCase extends AbstractTestCase {
+
+	public void testMemoryResourceStore() {
+		checkReadWrite(new MemoryResourceStore());
+		checkRemove(new MemoryResourceStore());		
+	}
+	
+	public void testFileResourceStore() {
+		checkReadWrite(new FileResourceStore(directory));
+		checkRemove(new FileResourceStore(directory));		
+	}
+
+	public void testTransactionalFileResourceStore() {
+		checkReadWrite(new TransactionalResourceStore(new FileResourceStore(directory)));
+		checkRemove(new TransactionalResourceStore(new FileResourceStore(directory)));		
+	}
+	
+    private void checkReadWrite( final ResourceStore pStore ) {
+        final byte[] data = { 1, 2, 3 };
+        pStore.write("key", data);
+        
+        final byte[] read = pStore.read("key");
+        
+        assertTrue(read != null);
+        assertTrue(ArrayUtils.isEquals(data, read));
+    }
+
+    private void checkRemove( final ResourceStore pStore ) {
+        final byte[] data = { 1, 2, 3 };
+        pStore.write("key", data);
+        
+        final byte[] read = pStore.read("key");
+        
+        assertTrue(read != null);
+        assertTrue(ArrayUtils.isEquals(data, read));
+
+        pStore.remove("key");
+
+        final byte[] empty = pStore.read("key");
+        
+        assertTrue(empty == null);
+    }
+    
+    
+    
+}

Propchange: jakarta/commons/sandbox/jci/trunk/core/src/test/java/org/apache/commons/jci/stores/ResourceStoreTestCase.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jakarta/commons/sandbox/jci/trunk/core/src/test/java/org/apache/commons/jci/stores/ResourceStoreTestCase.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision Author HeadURL Id

Propchange: jakarta/commons/sandbox/jci/trunk/core/src/test/java/org/apache/commons/jci/stores/ResourceStoreTestCase.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: jakarta/commons/sandbox/jci/trunk/fam/src/main/java/org/apache/commons/jci/listeners/AbstractFilesystemAlterationListener.java
URL: http://svn.apache.org/viewvc/jakarta/commons/sandbox/jci/trunk/fam/src/main/java/org/apache/commons/jci/listeners/AbstractFilesystemAlterationListener.java?view=diff&rev=509144&r1=509143&r2=509144
==============================================================================
--- jakarta/commons/sandbox/jci/trunk/fam/src/main/java/org/apache/commons/jci/listeners/AbstractFilesystemAlterationListener.java (original)
+++ jakarta/commons/sandbox/jci/trunk/fam/src/main/java/org/apache/commons/jci/listeners/AbstractFilesystemAlterationListener.java Mon Feb 19 01:56:48 2007
@@ -1,8 +1,26 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 package org.apache.commons.jci.listeners;
 
 import java.io.File;
+import java.util.ArrayList;
+import java.util.Collection;
 
 import org.apache.commons.jci.monitor.FilesystemAlterationListener;
+import org.apache.commons.jci.monitor.FilesystemAlterationObserver;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
@@ -10,83 +28,72 @@
 
     private final Log log = LogFactory.getLog(AbstractFilesystemAlterationListener.class);
 
+    private final Collection createdFiles = new ArrayList();
+    private final Collection changedFiles = new ArrayList();
+    private final Collection deletedFiles = new ArrayList();
+    private final Collection createdDirectories = new ArrayList();
+    private final Collection changedDirectories = new ArrayList();
+    private final Collection deletedDirectories = new ArrayList();
+
+    
     private final static class Signal {
         public boolean triggered;
     }
 
     private final Signal eventSignal = new Signal();
     private final Signal checkSignal = new Signal();
-
-	private int createdFiles;
-	private int createdDirectories;
-	private int changedFiles;
-	private int changedDirectories;
-	private int deletedFiles;
-	private int deletedDirectories;
-    
-	public void onStart() {
-    	createdFiles = 0;
-    	createdDirectories = 0;
-    	changedFiles = 0;
-    	changedDirectories = 0;
-    	deletedFiles = 0;
-    	deletedDirectories = 0;
-    }
     
-	public void onChangeDirectory( final File pDir ) {
-    	changedDirectories++;
+	protected FilesystemAlterationObserver observer;
+	    
+	public void onDirectoryCreate( final File pDir ) {
+		createdDirectories.add(pDir);
 	}
-
-	public void onChangeFile( final File pFile ) {
-		changedFiles++;
+	public void onDirectoryChange( final File pDir ) {
+    	changedDirectories.add(pDir);
 	}
-
-	public void onCreateDirectory( final File pDir ) {
-		createdDirectories++;
+	public void onDirectoryDelete( final File pDir ) {
+		deletedDirectories.add(pDir);
 	}
 
-	public void onCreateFile( final File pFile) {
-		createdFiles++;
+	public void onFileCreate( final File pFile) {
+		createdFiles.add(pFile);
 	}
-
-	public void onDeleteDirectory( final File pDir ) {
-		deletedDirectories++;
+	public void onFileChange( final File pFile ) {
+		changedFiles.add(pFile);
 	}
-
-	public void onDeleteFile( final File pfile ) {
-		deletedFiles++;
+	public void onFileDelete( final File pFile ) {
+		deletedFiles.add(pFile);
 	}
 
 	
-	public int getChangedDirectories() {
+	public Collection getChangedDirectories() {
 		return changedDirectories;
 	}
 
-	public int getChangedFiles() {
+	public Collection getChangedFiles() {
 		return changedFiles;
 	}
 
-	public int getCreatedDirectories() {
+	public Collection getCreatedDirectories() {
 		return createdDirectories;
 	}
 
-	public int getCreatedFiles() {
+	public Collection getCreatedFiles() {
 		return createdFiles;
 	}
 
-	public int getDeletedDirectories() {
+	public Collection getDeletedDirectories() {
 		return deletedDirectories;
 	}
 
-	public int getDeletedFiles() {
+	public Collection getDeletedFiles() {
 		return deletedFiles;
 	}
 
-	
-    public void onStop() {
-    	if (createdFiles > 0 || createdDirectories > 0 ||
-    	    changedFiles > 0 || changedDirectories > 0 ||
-    	    deletedFiles > 0 || deletedDirectories >0) {
+	protected void signals() {
+    	if (createdFiles.size() > 0 || createdDirectories.size() > 0 ||
+        	changedFiles.size() > 0 || changedDirectories.size() > 0 ||
+        	deletedFiles.size() > 0 || deletedDirectories.size() > 0) {
 
     		log.debug("event signal");
     		
@@ -101,7 +108,23 @@
         synchronized(checkSignal) {
             checkSignal.triggered = true;
             checkSignal.notifyAll();
-        }    	
+        }		
+	}
+
+	public void onStart( final FilesystemAlterationObserver pObserver ) {
+		observer = pObserver;
+
+		createdFiles.clear();
+    	changedFiles.clear();
+    	deletedFiles.clear();
+    	createdDirectories.clear();
+    	changedDirectories.clear();
+    	deletedDirectories.clear();
+    }
+
+    public void onStop( final FilesystemAlterationObserver pObserver ) {
+        signals();
+        observer = null;
     }
         
 	public void waitForEvent() throws Exception {

Modified: jakarta/commons/sandbox/jci/trunk/fam/src/main/java/org/apache/commons/jci/monitor/FilesystemAlterationListener.java
URL: http://svn.apache.org/viewvc/jakarta/commons/sandbox/jci/trunk/fam/src/main/java/org/apache/commons/jci/monitor/FilesystemAlterationListener.java?view=diff&rev=509144&r1=509143&r2=509144
==============================================================================
--- jakarta/commons/sandbox/jci/trunk/fam/src/main/java/org/apache/commons/jci/monitor/FilesystemAlterationListener.java (original)
+++ jakarta/commons/sandbox/jci/trunk/fam/src/main/java/org/apache/commons/jci/monitor/FilesystemAlterationListener.java Mon Feb 19 01:56:48 2007
@@ -19,22 +19,20 @@
 import java.io.File;
 
 /**
+ * A listener that receives events of filesystem modifications.
+ * The observer basically represents the source of the events.
+ * The file root and its state. (see FilesystemAlterationObserver)
+ * 
  * @author tcurdt
  */
 public interface FilesystemAlterationListener {
 	
-	/**
-	 * @deprecated
-	 */
-    File getRepository();
-    
-    
-    void onStart();
-    void onCreateFile( final File file );
-    void onChangeFile( final File file );
-    void onDeleteFile( final File file );
-    void onCreateDirectory( final File dir );
-    void onChangeDirectory( final File dir );
-    void onDeleteDirectory( final File dir );
-    void onStop();
+    void onStart( final FilesystemAlterationObserver pObserver );
+    void onFileCreate( final File pFile );
+    void onFileChange( final File pFile );
+    void onFileDelete( final File pFile );
+    void onDirectoryCreate( final File pDir );
+    void onDirectoryChange( final File pDir );
+    void onDirectoryDelete( final File pDir );
+    void onStop( final FilesystemAlterationObserver pObserver );
 }

Modified: jakarta/commons/sandbox/jci/trunk/fam/src/main/java/org/apache/commons/jci/monitor/FilesystemAlterationMonitor.java
URL: http://svn.apache.org/viewvc/jakarta/commons/sandbox/jci/trunk/fam/src/main/java/org/apache/commons/jci/monitor/FilesystemAlterationMonitor.java?view=diff&rev=509144&r1=509143&r2=509144
==============================================================================
--- jakarta/commons/sandbox/jci/trunk/fam/src/main/java/org/apache/commons/jci/monitor/FilesystemAlterationMonitor.java (original)
+++ jakarta/commons/sandbox/jci/trunk/fam/src/main/java/org/apache/commons/jci/monitor/FilesystemAlterationMonitor.java Mon Feb 19 01:56:48 2007
@@ -18,25 +18,52 @@
 
 import java.io.File;
 import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
 
+import org.apache.commons.collections.MultiHashMap;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
 /**
+ * It's a runnable that spawns of a monitoring thread triggering the
+ * the observers and managing the their listeners.
+ * 
  * @author tcurdt
  */
 public final class FilesystemAlterationMonitor implements Runnable {
 
     private final Log log = LogFactory.getLog(FilesystemAlterationMonitor.class);
 
-    private final FilesystemAlterationObserver observer;
+    public static class UniqueMultiValueMap extends MultiHashMap {
 
+		private static final long serialVersionUID = 1L;
+
+		public UniqueMultiValueMap() {
+            super( );
+        }
+
+        public UniqueMultiValueMap(Map copy) {
+            super( copy );
+        }
+
+        protected Collection createCollection( Collection copy ) {
+            if (copy != null) {
+                return new HashSet(copy);
+            }
+            return new HashSet();
+        }
+        
+    }
+    
     private long delay = 3000;
     private volatile boolean running = true;
     private Thread thread;
-
+    private Map observers = new HashMap(); 
+        
     public FilesystemAlterationMonitor() {
-    	observer = new FilesystemAlterationObserverImpl();
     }
 
 
@@ -61,43 +88,103 @@
     }
 
 
-    public void addListener( final FilesystemAlterationListener pListener ) {
-    	observer.addListener( pListener );
-    }
-
-    public Collection getListeners() {
-        return observer.getListeners();
-    }
-
-    public Collection getListenersFor( final File pRepository ) {
-        return observer.getListenersFor( pRepository );
-    }
+    public void addListener( final File pRoot, final FilesystemAlterationListener pListener ) {
+    	
+    	FilesystemAlterationObserver observer;
+    	
+    	synchronized (observers) {
+        	observer = (FilesystemAlterationObserver)observers.get(pRoot);
+
+        	if (observer == null) {
+        		observer = new FilesystemAlterationObserverImpl(pRoot);
+        		observers.put(pRoot, observer);
+        	}			
+		}
+    	
+    	observer.addListener(pListener);    	
+    }
+
+//    public void removeListeners( final File pRoot ) {
+//    	FilesystemAlterationObserver observer;
+//    	
+//    	synchronized (observers) {
+//        	observer = (FilesystemAlterationObserver)observers.get(pRoot);
+//
+//        	if (observer == null) {
+//        		return;
+//        	}			
+//		}
+//    	
+//    	final FilesystemAlterationListener[] listeners = observer.getListeners();
+//    	for (int i = 0; i < listeners.length; i++) {
+//			final  FilesystemAlterationListener listener = listeners[i];
+//	    	observer.removeListener(listener);    				
+//		}
+//    }
+    
+    public void removeListener( final FilesystemAlterationListener pListener ) {
+    	synchronized (observers) {
+    		for (Iterator it = observers.values().iterator(); it.hasNext();) {
+				final FilesystemAlterationObserver observer = (FilesystemAlterationObserver) it.next();
+				observer.removeListener(pListener);
+			}
+    	}
+    }
+    
+//    public FilesystemAlterationListener[] getListeners() {
+//    	final Collection listeners = new ArrayList();
+//    	
+//    	synchronized (observers) {
+//    		for (Iterator it = observers.values().iterator(); it.hasNext();) {
+//				final FilesystemAlterationObserver observer = (FilesystemAlterationObserver) it.next();
+//			}
+//    	}
+//    	return null;
+//    }
+
+    public FilesystemAlterationListener[] getListenersFor( final File pRoot  ) {
+    	FilesystemAlterationObserver observer;
+    	
+    	synchronized (observers) {
+        	observer = (FilesystemAlterationObserver)observers.get(pRoot);
+
+        	if (observer == null) {
+        		return new FilesystemAlterationListener[0];
+        	}			
+		}
 
-    public void removeListener( final FilesystemAlterationListener listener ) {
-    	observer.removeListener( listener );
+    	return observer.getListeners();
     }
 
 
     public void run() {
         log.debug("fam running");
+        
         while (true) {
             if (!running) {
                 break;
             }
 
-            observer.check();
-
+            final FilesystemAlterationObserver[] observerArray;
+            
+        	synchronized (observers) {
+        		observerArray = (FilesystemAlterationObserver[])observers.values().toArray(
+        				new FilesystemAlterationObserver[observers.size()]); 
+
+        	}        	
+            
+            for (int i = 0; i < observerArray.length; i++) {
+				final FilesystemAlterationObserver observer = observerArray[i];
+				observer.checkAndNotify();
+			}
+            
             try {
                 Thread.sleep(delay);
             } catch (final InterruptedException e) {
             }
         }
+        
         log.debug("fam exiting");
     }
 
-
-
-    public String toString() {
-        return observer.toString();
-    }   
 }

Modified: jakarta/commons/sandbox/jci/trunk/fam/src/main/java/org/apache/commons/jci/monitor/FilesystemAlterationObserver.java
URL: http://svn.apache.org/viewvc/jakarta/commons/sandbox/jci/trunk/fam/src/main/java/org/apache/commons/jci/monitor/FilesystemAlterationObserver.java?view=diff&rev=509144&r1=509143&r2=509144
==============================================================================
--- jakarta/commons/sandbox/jci/trunk/fam/src/main/java/org/apache/commons/jci/monitor/FilesystemAlterationObserver.java (original)
+++ jakarta/commons/sandbox/jci/trunk/fam/src/main/java/org/apache/commons/jci/monitor/FilesystemAlterationObserver.java Mon Feb 19 01:56:48 2007
@@ -1,21 +1,42 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 package org.apache.commons.jci.monitor;
 
 import java.io.File;
-import java.util.Collection;
 
+/**
+ * FilesystemAlterationObserver represents the state of files
+ * below a certain root directory. It implements the code to
+ * check the filesystem and notify listeners.
+ * 
+ * @author tcurdt
+ */
 public interface FilesystemAlterationObserver {
 
-	void check();
+	// FilesystemAlterationObserver( final File pRootDirectory );
 	
+	File getRootDirectory();
 	
-	// FIXME: the listener stuff should probably not part of this interface
 	
-	void addListener( final FilesystemAlterationListener pListener );
+	void checkAndNotify();
 
-	Collection getListeners();
-
-	Collection getListenersFor( final File pRepository );
-
-	void removeListener( final FilesystemAlterationListener listener );
+	
+	void addListener( final FilesystemAlterationListener pListener );	
 
+	void removeListener( final FilesystemAlterationListener pListener );
+	
+	FilesystemAlterationListener[] getListeners();
 }



---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org