commons-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From tcu...@apache.org
Subject svn commit: r498446 - in /jakarta/commons/sandbox/jci/trunk: core/src/main/java/org/apache/commons/jci/listeners/ fam/src/main/java/org/apache/commons/jci/listeners/ fam/src/main/java/org/apache/commons/jci/monitor/ fam/src/test/java/org/apache/commons...
Date Sun, 21 Jan 2007 20:33:38 GMT
Author: tcurdt
Date: Sun Jan 21 12:33:37 2007
New Revision: 498446

URL: http://svn.apache.org/viewvc?view=rev&rev=498446
Log:
refactoring


Added:
    jakarta/commons/sandbox/jci/trunk/fam/src/main/java/org/apache/commons/jci/listeners/AbstractFilesystemAlterationListener.java
  (with props)
Removed:
    jakarta/commons/sandbox/jci/trunk/fam/src/main/java/org/apache/commons/jci/monitor/AbstractFilesystemAlterationListener.java
Modified:
    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/fam/src/main/java/org/apache/commons/jci/listeners/NotifyingListener.java
    jakarta/commons/sandbox/jci/trunk/fam/src/test/java/org/apache/commons/jci/monitor/FilesystemAlterationMonitorTestCase.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/CompilingClassLoaderTestCase.java
    jakarta/commons/sandbox/jci/trunk/tests/src/test/java/org/apache/commons/jci/ReloadingClassLoaderTestCase.java

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=498446&r1=498445&r2=498446
==============================================================================
--- 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
Sun Jan 21 12:33:37 2007
@@ -20,6 +20,7 @@
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Iterator;
+
 import org.apache.commons.jci.compilers.CompilationResult;
 import org.apache.commons.jci.compilers.JavaCompiler;
 import org.apache.commons.jci.compilers.JavaCompilerFactory;
@@ -156,6 +157,6 @@
 
         transactionalStore.onStop();
 
-        checked(reload);
+        super.onStop();
     }
 }

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=498446&r1=498445&r2=498446
==============================================================================
--- 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
Sun Jan 21 12:33:37 2007
@@ -16,7 +16,7 @@
     }
 
     public void onStop() {
-        checked(changed);
+    	super.onStop();
     }
 
     

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=498446&r1=498445&r2=498446
==============================================================================
--- 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
Sun Jan 21 12:33:37 2007
@@ -123,17 +123,25 @@
             ((Transactional)store).onStop();
         }
 
-        checked(reload);
+        
+        if (reload && notificationListener != null) {
+        	notificationListener.handleNotification();
+        }
+        
+        super.onStop();
     }
 
-    public void onCreateFile( final File file ) {
-        created.add(file);
+    public void onCreateFile( final File pFile ) {
+        created.add(pFile);
+        super.onCreateFile(pFile);
     }
-    public void onChangeFile( final File file ) {                
-        changed.add(file);
+    public void onChangeFile( final File pFile ) {                
+        changed.add(pFile);
+        super.onChangeFile(pFile);
     }
-    public void onDeleteFile( final File file ) {
-        deleted.add(file);
+    public void onDeleteFile( final File pFile ) {
+        deleted.add(pFile);
+        super.onDeleteFile(pFile);
     }
 
     public void onCreateDirectory( final File file ) {                

Added: 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=auto&rev=498446
==============================================================================
--- jakarta/commons/sandbox/jci/trunk/fam/src/main/java/org/apache/commons/jci/listeners/AbstractFilesystemAlterationListener.java
(added)
+++ jakarta/commons/sandbox/jci/trunk/fam/src/main/java/org/apache/commons/jci/listeners/AbstractFilesystemAlterationListener.java
Sun Jan 21 12:33:37 2007
@@ -0,0 +1,165 @@
+package org.apache.commons.jci.listeners;
+
+import java.io.File;
+
+import org.apache.commons.jci.monitor.FilesystemAlterationListener;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+public abstract class AbstractFilesystemAlterationListener implements FilesystemAlterationListener
{
+
+    private final Log log = LogFactory.getLog(AbstractFilesystemAlterationListener.class);
+
+    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++;
+	}
+
+	public void onChangeFile( final File pFile ) {
+		changedFiles++;
+	}
+
+	public void onCreateDirectory( final File pDir ) {
+		createdDirectories++;
+	}
+
+	public void onCreateFile( final File pFile) {
+		createdFiles++;
+	}
+
+	public void onDeleteDirectory( final File pDir ) {
+		deletedDirectories++;
+	}
+
+	public void onDeleteFile( final File pfile ) {
+		deletedFiles++;
+	}
+
+	
+	public int getChangedDirectories() {
+		return changedDirectories;
+	}
+
+	public int getChangedFiles() {
+		return changedFiles;
+	}
+
+	public int getCreatedDirectories() {
+		return createdDirectories;
+	}
+
+	public int getCreatedFiles() {
+		return createdFiles;
+	}
+
+	public int getDeletedDirectories() {
+		return deletedDirectories;
+	}
+
+	public int getDeletedFiles() {
+		return deletedFiles;
+	}
+
+	
+    public void onStop() {
+    	if (createdFiles > 0 || createdDirectories > 0 ||
+    	    changedFiles > 0 || changedDirectories > 0 ||
+    	    deletedFiles > 0 || deletedDirectories >0) {
+
+    		log.debug("event signal");
+    		
+    		synchronized(eventSignal) {
+                eventSignal.triggered = true;
+                eventSignal.notifyAll();
+            }    	    		
+    	}
+    	
+    	log.debug("check signal");
+    	
+        synchronized(checkSignal) {
+            checkSignal.triggered = true;
+            checkSignal.notifyAll();
+        }    	
+    }
+        
+	public void waitForEvent() throws Exception {
+        synchronized(eventSignal) {
+            eventSignal.triggered = false;
+        }
+        log.debug("waiting for change");
+        if (!waitForSignal(eventSignal, 10)) {
+            throw new Exception("timeout");
+        }
+    }
+    
+    /*
+     * we don't reset the signal
+     * so if there was a check it is
+     * already true and exit immediatly
+     * otherwise it will behave just
+     * like waitForCheck()
+     */
+    public void waitForFirstCheck() throws Exception {
+        log.debug("waiting for first check");
+        if (!waitForSignal(checkSignal, 10)) {
+            throw new Exception("timeout");
+        }        
+    }
+
+    public void waitForCheck() throws Exception {
+        synchronized(checkSignal) {
+            checkSignal.triggered = false;
+        }
+        log.debug("waiting for check");
+        if (!waitForSignal(checkSignal, 10)) {
+            throw new Exception("timeout");
+        }
+    }
+    
+    private boolean waitForSignal(final Signal pSignal, final int pSecondsTimeout) {
+        int i = 0;
+        while(true) {
+            synchronized(pSignal) {
+                if (!pSignal.triggered) {
+                    try {
+                        pSignal.wait(1000);
+                    } catch (InterruptedException e) {
+                    }
+
+                    if (++i > pSecondsTimeout) {
+                        log.error("timeout after " + pSecondsTimeout + "s");
+                        return false;
+                    }
+                    
+                } else {
+                    pSignal.triggered = false;
+                    break;
+                }
+            }
+        }        
+        return true;
+    }
+
+}

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

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

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

Modified: jakarta/commons/sandbox/jci/trunk/fam/src/main/java/org/apache/commons/jci/listeners/NotifyingListener.java
URL: http://svn.apache.org/viewvc/jakarta/commons/sandbox/jci/trunk/fam/src/main/java/org/apache/commons/jci/listeners/NotifyingListener.java?view=diff&rev=498446&r1=498445&r2=498446
==============================================================================
--- jakarta/commons/sandbox/jci/trunk/fam/src/main/java/org/apache/commons/jci/listeners/NotifyingListener.java
(original)
+++ jakarta/commons/sandbox/jci/trunk/fam/src/main/java/org/apache/commons/jci/listeners/NotifyingListener.java
Sun Jan 21 12:33:37 2007
@@ -1,14 +1,9 @@
 package org.apache.commons.jci.listeners;
 
 import java.io.File;
-import org.apache.commons.jci.monitor.FilesystemAlterationListener;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
 
 
-public abstract class NotifyingListener implements FilesystemAlterationListener {
-
-    private final Log log = LogFactory.getLog(NotifyingListener.class);
+public abstract class NotifyingListener extends AbstractFilesystemAlterationListener {
 
     public final static class Signal {
         public boolean triggered;
@@ -16,8 +11,6 @@
 
     protected final File repository;
     protected NotificationListener notificationListener;
-    private final Signal notificationSignal = new Signal();
-    private final Signal checkSignal = new Signal();
 
     public NotifyingListener(final File pRepository) {
         repository = pRepository;        
@@ -31,82 +24,5 @@
         notificationListener = pNotificationListener;
     }
 
-    protected void checked( final boolean pNotify ) {
-        if (pNotify) {
-            if (notificationListener != null) {
-                notificationListener.handleNotification();
-            }
-            synchronized(notificationSignal) {
-                notificationSignal.triggered = true;
-                notificationSignal.notifyAll();
-            }
-        }
-        synchronized(checkSignal) {
-            checkSignal.triggered = true;
-            checkSignal.notifyAll();
-        }
-    }
-    
-    
-    public void waitForNotification() throws Exception {
-        synchronized(notificationSignal) {
-            notificationSignal.triggered = false;
-        }
-        log.debug("waiting for reload signal");
-        if (!waitForSignal(notificationSignal, 10)) {
-            throw new Exception("timeout");
-        }
-    }
-    
-    /*
-     * we don't reset the signal
-     * so if there was a check it is
-     * already true and exit immediatly
-     * otherwise it will behave just
-     * like waitForCheck()
-     */
-    public void waitForFirstCheck() throws Exception {
-        log.debug("waiting for first signal");
-        if (!waitForSignal(checkSignal, 10)) {
-            throw new Exception("timeout");
-        }        
-    }
-
-    public void waitForCheck() throws Exception {
-        synchronized(checkSignal) {
-            checkSignal.triggered = false;
-        }
-        log.debug("waiting for check signal");
-        if (!waitForSignal(checkSignal, 10)) {
-            throw new Exception("timeout");
-        }
-    }
-    
-    private boolean waitForSignal(final Signal pSignal, final int pSecondsTimeout) {
-        int i = 0;
-        while(true) {
-            synchronized(pSignal) {
-                //log.debug("loop");
-                if (!pSignal.triggered) {
-                    try {
-                        //log.debug("waiting");
-                        pSignal.wait(1000);
-                    } catch (InterruptedException e) {
-                        ;
-                    }
-                    if (++i > pSecondsTimeout) {
-                        log.error("timeout after " + pSecondsTimeout + "s");
-                        return false;
-                    }
-                } else {
-                    pSignal.triggered = false;
-                    break;
-                }
-            }
-        }
-        
-        log.debug("caught signal");
-        return true;
-    }
   
 }

Modified: jakarta/commons/sandbox/jci/trunk/fam/src/test/java/org/apache/commons/jci/monitor/FilesystemAlterationMonitorTestCase.java
URL: http://svn.apache.org/viewvc/jakarta/commons/sandbox/jci/trunk/fam/src/test/java/org/apache/commons/jci/monitor/FilesystemAlterationMonitorTestCase.java?view=diff&rev=498446&r1=498445&r2=498446
==============================================================================
--- jakarta/commons/sandbox/jci/trunk/fam/src/test/java/org/apache/commons/jci/monitor/FilesystemAlterationMonitorTestCase.java
(original)
+++ jakarta/commons/sandbox/jci/trunk/fam/src/test/java/org/apache/commons/jci/monitor/FilesystemAlterationMonitorTestCase.java
Sun Jan 21 12:33:37 2007
@@ -24,6 +24,7 @@
 import junit.framework.TestCase;
 
 import org.apache.commons.io.FileUtils;
+import org.apache.commons.jci.listeners.AbstractFilesystemAlterationListener;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 

Modified: jakarta/commons/sandbox/jci/trunk/tests/src/test/java/org/apache/commons/jci/AbstractTestCase.java
URL: http://svn.apache.org/viewvc/jakarta/commons/sandbox/jci/trunk/tests/src/test/java/org/apache/commons/jci/AbstractTestCase.java?view=diff&rev=498446&r1=498445&r2=498446
==============================================================================
--- jakarta/commons/sandbox/jci/trunk/tests/src/test/java/org/apache/commons/jci/AbstractTestCase.java
(original)
+++ jakarta/commons/sandbox/jci/trunk/tests/src/test/java/org/apache/commons/jci/AbstractTestCase.java
Sun Jan 21 12:33:37 2007
@@ -46,6 +46,9 @@
     */
     
     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());

Modified: jakarta/commons/sandbox/jci/trunk/tests/src/test/java/org/apache/commons/jci/CompilingClassLoaderTestCase.java
URL: http://svn.apache.org/viewvc/jakarta/commons/sandbox/jci/trunk/tests/src/test/java/org/apache/commons/jci/CompilingClassLoaderTestCase.java?view=diff&rev=498446&r1=498445&r2=498446
==============================================================================
--- jakarta/commons/sandbox/jci/trunk/tests/src/test/java/org/apache/commons/jci/CompilingClassLoaderTestCase.java
(original)
+++ jakarta/commons/sandbox/jci/trunk/tests/src/test/java/org/apache/commons/jci/CompilingClassLoaderTestCase.java
Sun Jan 21 12:33:37 2007
@@ -44,14 +44,14 @@
         delay();        
         writeFile("jci/Simple.java", JavaSources.simple);        
         writeFile("jci/Extended.java", JavaSources.extended);        
-        listener.waitForNotification();
+        listener.waitForEvent();
     }
     
     
     public void testCompileProblems() throws Exception {
         delay();        
         writeFile("jci/Simple.java", JavaSources.error);
-        listener.waitForNotification();
+        listener.waitForEvent();
         
         // FIXME
     }
@@ -77,7 +77,7 @@
 
         delay();
         writeFile("jci/Simple.java", JavaSources.SIMPLE);
-        listener.waitForNotification();
+        listener.waitForEvent();
     
         final Object SIMPLE = classloader.loadClass("jci.Simple").newInstance();        
         assertTrue("SIMPLE".equals(SIMPLE.toString()));
@@ -97,7 +97,7 @@
         
         delay();
         assertTrue(new File(directory, "jci/Extended.java").delete());
-        listener.waitForNotification();
+        listener.waitForEvent();
 
         final Object oldSimple = classloader.loadClass("jci.Simple").newInstance();     
  
         assertTrue("Simple".equals(oldSimple.toString()));
@@ -111,7 +111,7 @@
         
         delay();
         FileUtils.deleteDirectory(new File(directory, "jci"));
-        listener.waitForNotification();
+        listener.waitForEvent();
 
         try {
             classloader.loadClass("jci.Simple").newInstance();
@@ -133,7 +133,7 @@
         
         delay();
         assertTrue(new File(directory, "jci/Simple.java").delete());
-        listener.waitForNotification();
+        listener.waitForEvent();
 
         try {
             classloader.loadClass("jci.Extended").newInstance();
@@ -172,7 +172,7 @@
                 "    }\n" + 
                 "}"
                 );        
-        listener.waitForNotification();
+        listener.waitForEvent();
         
         final Object foo1 = classloader.loadClass("jci.Foo").newInstance();        
         assertTrue("foo1".equals(foo1.toString()));
@@ -192,7 +192,7 @@
                 "    }\n" + 
                 "}"
                 );        
-        listener.waitForNotification();
+        listener.waitForEvent();
 
         final Object foo2 = classloader.loadClass("jci.Foo").newInstance();        
         assertTrue("foo2".equals(foo2.toString()));
@@ -217,7 +217,7 @@
                 "    }\n" + 
                 "}"
                 );        
-        listener.waitForNotification();
+        listener.waitForEvent();
         
         final MyFoo foo1 = (MyFoo) classloader.loadClass("jci.Foo").newInstance();      
 
         assertTrue("foo1".equals(foo1.toString()));
@@ -236,7 +236,7 @@
                 "    }\n" + 
                 "}"
                 );        
-        listener.waitForNotification();
+        listener.waitForEvent();
 
         final MyFoo foo2 = (MyFoo) classloader.loadClass("jci.Foo").newInstance();      
 
         assertTrue("foo2".equals(foo2.toString()));

Modified: jakarta/commons/sandbox/jci/trunk/tests/src/test/java/org/apache/commons/jci/ReloadingClassLoaderTestCase.java
URL: http://svn.apache.org/viewvc/jakarta/commons/sandbox/jci/trunk/tests/src/test/java/org/apache/commons/jci/ReloadingClassLoaderTestCase.java?view=diff&rev=498446&r1=498445&r2=498446
==============================================================================
--- jakarta/commons/sandbox/jci/trunk/tests/src/test/java/org/apache/commons/jci/ReloadingClassLoaderTestCase.java
(original)
+++ jakarta/commons/sandbox/jci/trunk/tests/src/test/java/org/apache/commons/jci/ReloadingClassLoaderTestCase.java
Sun Jan 21 12:33:37 2007
@@ -26,7 +26,7 @@
 
 public final class ReloadingClassLoaderTestCase extends AbstractTestCase {
 
-    private final static Log log = LogFactory.getLog(ReloadingClassLoaderTestCase.class);
+    private final Log log = LogFactory.getLog(ReloadingClassLoaderTestCase.class);
     
     private ReloadingClassLoader classloader;
     private ReloadingListener listener;
@@ -72,7 +72,7 @@
         listener.waitForCheck();
         
         final Object simple = classloader.loadClass("jci.Simple").newInstance();        
-        assertTrue("Simple".equals(simple.toString()));        
+        assertEquals("Simple", simple.toString());        
     }
 
     public void testChange() throws Exception {        
@@ -85,16 +85,16 @@
         listener.waitForCheck();
 
         final Object simple = classloader.loadClass("jci.Simple").newInstance();        
-        assertTrue("Simple".equals(simple.toString()));
+        assertEquals("Simple", simple.toString());
         
         log.debug("changing class");
         
         delay();        
         writeFile("jci/Simple.class", clazzSIMPLE);
-        listener.waitForNotification();
+        listener.waitForEvent();
     
         final Object SIMPLE = classloader.loadClass("jci.Simple").newInstance();        
-        assertTrue("SIMPLE".equals(SIMPLE.toString()));        
+        assertEquals("SIMPLE", SIMPLE.toString());        
     }
 
     public void testDelete() throws Exception {
@@ -107,19 +107,19 @@
         listener.waitForCheck();
 
         final Object simple = classloader.loadClass("jci.Simple").newInstance();        
-        assertTrue("Simple".equals(simple.toString()));
+        assertEquals("Simple", simple.toString());
 
         log.debug("deleting class");
         
         assertTrue(new File(directory, "jci/Simple.class").delete());
         
-        listener.waitForNotification();
+        listener.waitForEvent();
 
         try {
             classloader.loadClass("jci.Simple").newInstance();        
             fail();
         } catch(final ClassNotFoundException e) {
-            assertTrue("jci.Simple".equals(e.getMessage()));
+            assertEquals("jci.Simple", e.getMessage());
         }        
     }
 
@@ -134,22 +134,22 @@
         listener.waitForCheck();
 
         final Object simple = classloader.loadClass("jci.Simple").newInstance();        
-        assertTrue("Simple".equals(simple.toString()));
+        assertEquals("Simple", simple.toString());
         
         final Object extended = classloader.loadClass("jci.Extended").newInstance();    
   
-        assertTrue("Extended:Simple".equals(extended.toString()));
+        assertEquals("Extended:Simple", extended.toString());
 
         log.debug("deleting class dependency");
         
         assertTrue(new File(directory, "jci/Simple.class").delete());
         
-        listener.waitForNotification();
+        listener.waitForEvent();
 
         try {
             classloader.loadClass("jci.Extended").newInstance();
             fail();
         } catch(final NoClassDefFoundError e) {
-            assertTrue("jci/Simple".equals(e.getMessage()));
+            assertEquals("jci/Simple", e.getMessage());
         }
     }
 



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


Mime
View raw message