You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tapestry.apache.org by hl...@apache.org on 2006/07/28 18:04:35 UTC

svn commit: r426587 - in /tapestry/tapestry5/tapestry-core/trunk: ./ src/main/java/org/apache/tapestry/internal/ioc/ src/main/java/org/apache/tapestry/internal/ioc/services/ src/main/java/org/apache/tapestry/ioc/services/ src/main/resources/org/apache/...

Author: hlship
Date: Fri Jul 28 09:04:34 2006
New Revision: 426587

URL: http://svn.apache.org/viewvc?rev=426587&view=rev
Log:
Move TapestryIOCModule to the org.apache.tapestry.ioc.services package.
Add ThreadCleanupHub service, and ThreadCleanupListener event listener interface.

Added:
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/services/ThreadCleanupHubImpl.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/services/TapestryIOCModule.java
      - copied, changed from r426187, tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/TapestryIOCModule.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/services/ThreadCleanupHub.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/services/ThreadCleanupListener.java
    tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/services/ThreadCleanupHubImplTest.java
Removed:
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/TapestryIOCModule.java
Modified:
    tapestry/tapestry5/tapestry-core/trunk/pom.xml
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/services/ServiceMessages.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/resources/org/apache/tapestry/internal/ioc/services/ServiceStrings.properties
    tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/ModuleImplTest.java
    tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/ioc/IntegrationTest.java
    tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/ioc/RegistryBuilderTest.java

Modified: tapestry/tapestry5/tapestry-core/trunk/pom.xml
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/pom.xml?rev=426587&r1=426586&r2=426587&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/pom.xml (original)
+++ tapestry/tapestry5/tapestry-core/trunk/pom.xml Fri Jul 28 09:04:34 2006
@@ -82,21 +82,33 @@
                 <configuration>
                     <archive>
                         <manifestEntries>
-                            <Tapestry-Module-Classes>org.apache.tapestry.internal.ioc.TapestryIOCModule</Tapestry-Module-Classes>
+                            <Tapestry-Module-Classes>org.apache.tapestry.ioc.services.TapestryIOCModule</Tapestry-Module-Classes>
                         </manifestEntries>
                     </archive>
                 </configuration>
-            </plugin>
+            </plugin> <!--
+            <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>cobertura-maven-plugin</artifactId>
+                <configuration>
+                    <instrumentation>
+                        <ignores>
+                            <ignore>org.apache.tapestry.internal.aspect.*</ignore>
+                        </ignores>
+                    </instrumentation>
+                </configuration>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>clean</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin> -->
         </plugins>
     </build>
     <reporting>
         <plugins>
-            <!-- The surefire tests had 1 failure, not sure if I did something wrong
-            <plugin>
-                <groupId>org.codehaus.mojo</groupId>
-                <artifactId>surefire-report-maven-plugin</artifactId>
-                </plugin>
-            -->
             <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-javadoc-plugin</artifactId>
@@ -123,7 +135,11 @@
                     </links>
                     <stylesheetfile>${basedir}/src/site/resources/css/jdstyle.css</stylesheetfile>
                 </configuration>
-            </plugin>
+            </plugin> <!--
+            <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>cobertura-maven-plugin</artifactId>
+            </plugin> -->
         </plugins>
     </reporting>
     <distributionManagement>

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/services/ServiceMessages.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/services/ServiceMessages.java?rev=426587&r1=426586&r2=426587&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/services/ServiceMessages.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/services/ServiceMessages.java Fri Jul 28 09:04:34 2006
@@ -20,6 +20,7 @@
 import org.apache.hivemind.impl.MessageFormatter;
 import org.apache.tapestry.internal.annotations.Utility;
 import org.apache.tapestry.ioc.services.MethodSignature;
+import org.apache.tapestry.ioc.services.ThreadCleanupListener;
 
 /**
  * @author Howard M. Lewis Ship
@@ -69,4 +70,8 @@
         return MESSAGES.format("logging-interceptor", serviceId, serviceInterface.getName());
     }
 
+    static String threadCleanupError(ThreadCleanupListener listener, Throwable cause)
+    {
+        return MESSAGES.format("thread-cleanup-error", listener, cause);
+    }
 }

Added: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/services/ThreadCleanupHubImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/services/ThreadCleanupHubImpl.java?rev=426587&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/services/ThreadCleanupHubImpl.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/services/ThreadCleanupHubImpl.java Fri Jul 28 09:04:34 2006
@@ -0,0 +1,63 @@
+package org.apache.tapestry.internal.ioc.services;
+
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.tapestry.ioc.services.ThreadCleanupHub;
+import org.apache.tapestry.ioc.services.ThreadCleanupListener;
+
+import static org.apache.tapestry.util.CollectionFactory.newList;
+
+/**
+ * @author Howard M. Lewis Ship
+ */
+public class ThreadCleanupHubImpl implements ThreadCleanupHub
+{
+    private static class ListHolder extends ThreadLocal<List<ThreadCleanupListener>>
+    {
+        @Override
+        protected List<ThreadCleanupListener> initialValue()
+        {
+            return newList();
+        }
+    }
+
+    private final Log _log;
+
+    private final ListHolder _holder = new ListHolder();
+
+    public ThreadCleanupHubImpl(Log log)
+    {
+        _log = log;
+    }
+
+    public void addThreadCleanupListener(ThreadCleanupListener listener)
+    {
+        _holder.get().add(listener);
+    }
+
+    public void cleanup()
+    {
+        List<ThreadCleanupListener> listeners = _holder.get();
+
+        // Discard the listeners. In a perfect world, we would set a per-thread flag that prevented
+        // more listeners from being added, until a new thread begins. But we don't have a concept
+        // of thread start, just thread complete.
+
+        _holder.remove();
+
+        for (ThreadCleanupListener listener : listeners)
+        {
+            try
+            {
+                listener.threadDidCleanup();
+            }
+            catch (Exception ex)
+            {
+                _log.warn(ServiceMessages.threadCleanupError(listener, ex), ex);
+            }
+        }
+
+    }
+
+}

Copied: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/services/TapestryIOCModule.java (from r426187, tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/TapestryIOCModule.java)
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/services/TapestryIOCModule.java?p2=tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/services/TapestryIOCModule.java&p1=tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/TapestryIOCModule.java&r1=426187&r2=426587&rev=426587&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/TapestryIOCModule.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/services/TapestryIOCModule.java Fri Jul 28 09:04:34 2006
@@ -12,15 +12,15 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package org.apache.tapestry.internal.ioc;
+package org.apache.tapestry.ioc.services;
 
+import org.apache.commons.logging.Log;
 import org.apache.tapestry.internal.ioc.services.ClassFactoryImpl;
 import org.apache.tapestry.internal.ioc.services.LoggingDecoratorImpl;
+import org.apache.tapestry.internal.ioc.services.ThreadCleanupHubImpl;
 import org.apache.tapestry.ioc.annotations.Id;
 import org.apache.tapestry.ioc.annotations.InjectService;
 import org.apache.tapestry.ioc.annotations.Lifecycle;
-import org.apache.tapestry.ioc.services.ClassFactory;
-import org.apache.tapestry.ioc.services.LoggingDecorator;
 
 /**
  * Defines the base set of services for the Tapestry IOC container.
@@ -30,12 +30,28 @@
 @Id("tapestry.ioc")
 public class TapestryIOCModule
 {
+    /**
+     * The ClassFactory service is used to create new classes at runtime.
+     */
     @Lifecycle("primitive")
     public ClassFactory buildClassFactory()
     {
         return new ClassFactoryImpl();
     }
 
+    /**
+     * The ThreadCleanupHub service is used by listener objects that need to know about the end of
+     * the current request.
+     */
+    public ThreadCleanupHub buildThreadCleanupHub(Log log)
+    {
+        return new ThreadCleanupHubImpl(log);
+    }
+
+    /**
+     * The LoggingDecorator service is used to decorate a service implementation so that it logs
+     * method entry and exit (at level debug).
+     */
     public LoggingDecorator buildLoggingDecorator(@InjectService("ClassFactory")
     ClassFactory classFactory)
     {

Added: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/services/ThreadCleanupHub.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/services/ThreadCleanupHub.java?rev=426587&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/services/ThreadCleanupHub.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/services/ThreadCleanupHub.java Fri Jul 28 09:04:34 2006
@@ -0,0 +1,27 @@
+package org.apache.tapestry.ioc.services;
+
+/**
+ * Event hub used to identify when the end of thread cleanup (i.e., end of request cleanup in a
+ * typical web application) should occur. Tapestry IoC has any number of objects that need to know
+ * when this event occurs, so that they can clean up any per-thread/per-request state.
+ * 
+ * @author Howard M. Lewis Ship
+ */
+public interface ThreadCleanupHub
+{
+    /**
+     * Adds a listener to the hub. The hub maintains a seperate list of listeners for each thread
+     * (i.e., using a ThreadLocal). Further, the listener list is discarded at the end of the
+     * request.
+     * 
+     * @param listener
+     *            to add
+     */
+    void addThreadCleanupListener(ThreadCleanupListener listener);
+
+    /**
+     * Instructs the hub to notify all its listeners (for the current thread). It also discards its
+     * list of listeners.
+     */
+    void cleanup();
+}

Added: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/services/ThreadCleanupListener.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/services/ThreadCleanupListener.java?rev=426587&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/services/ThreadCleanupListener.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/services/ThreadCleanupListener.java Fri Jul 28 09:04:34 2006
@@ -0,0 +1,21 @@
+package org.apache.tapestry.ioc.services;
+
+import java.util.EventListener;
+
+/**
+ * Listener interface for object that need to know about thread event cleanup.
+ * <p>
+ * Note that registration with the {@link org.apache.tapestry.ioc.services.ThreadCleanupHub} is a
+ * one-shot affair; it lasts no longer than the next cleanup.
+ * 
+ * @author Howard M. Lewis Ship
+ * @see org.apache.tapestry.ioc.services.ThreadCleanupHub
+ */
+public interface ThreadCleanupListener extends EventListener
+{
+    /**
+     * Invoked by {@link org.apache.tapestry.ioc.services.ThreadCleanupHub} service when a thread
+     * performs and end-of-request cleanup.
+     */
+    void threadDidCleanup();
+}
\ No newline at end of file

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/resources/org/apache/tapestry/internal/ioc/services/ServiceStrings.properties
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/resources/org/apache/tapestry/internal/ioc/services/ServiceStrings.properties?rev=426587&r1=426586&r2=426587&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/resources/org/apache/tapestry/internal/ioc/services/ServiceStrings.properties (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/resources/org/apache/tapestry/internal/ioc/services/ServiceStrings.properties Fri Jul 28 09:04:34 2006
@@ -19,3 +19,4 @@
 unable-to-write-class=Unable to create class {0}: {1}
 duplicate-method-in-class=Attempt to redefine method {0} of class {1}.
 logging-interceptor=<Logging interceptor for {0}({1})>
+thread-cleanup-error=Error invoking listener {0}: {1}
\ No newline at end of file

Modified: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/ModuleImplTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/ModuleImplTest.java?rev=426587&r1=426586&r2=426587&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/ModuleImplTest.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/ModuleImplTest.java Fri Jul 28 09:04:34 2006
@@ -27,6 +27,7 @@
 import org.apache.tapestry.ioc.def.ModuleDef;
 import org.apache.tapestry.ioc.def.ServiceDef;
 import org.apache.tapestry.ioc.services.ClassFactory;
+import org.apache.tapestry.ioc.services.TapestryIOCModule;
 import org.testng.annotations.Test;
 
 import static org.testng.Assert.assertEquals;

Added: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/services/ThreadCleanupHubImplTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/services/ThreadCleanupHubImplTest.java?rev=426587&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/services/ThreadCleanupHubImplTest.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/services/ThreadCleanupHubImplTest.java Fri Jul 28 09:04:34 2006
@@ -0,0 +1,110 @@
+package org.apache.tapestry.internal.ioc.services;
+
+import org.apache.commons.logging.Log;
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.apache.tapestry.ioc.services.ThreadCleanupHub;
+import org.apache.tapestry.ioc.services.ThreadCleanupListener;
+import org.testng.annotations.Test;
+
+/**
+ * @author Howard M. Lewis Ship
+ */
+public class ThreadCleanupHubImplTest extends InternalBaseTestCase
+{
+    @Test
+    public void no_listeners()
+    {
+        Log log = newLog();
+
+        replay();
+
+        new ThreadCleanupHubImpl(log).cleanup();
+
+        verify();
+    }
+
+    @Test
+    public void listeners_are_one_shot()
+    {
+        Log log = newLog();
+        ThreadCleanupListener listener = newThreadCleanupListener();
+
+        listener.threadDidCleanup();
+
+        replay();
+
+        ThreadCleanupHub hub = new ThreadCleanupHubImpl(log);
+
+        hub.addThreadCleanupListener(listener);
+
+        hub.cleanup();
+
+        verify();
+
+        // No more training.
+
+        replay();
+
+        // Listener not invoked.
+
+        hub.cleanup();
+
+        verify();
+    }
+
+    private ThreadCleanupListener newThreadCleanupListener()
+    {
+        return newMock(ThreadCleanupListener.class);
+    }
+
+    @Test
+    public void listener_cleanup_failure()
+    {
+        final RuntimeException t = new RuntimeException("Boom!");
+
+        Log log = newLog();
+
+        ThreadCleanupListener listener = new ThreadCleanupListener()
+        {
+
+            public void threadDidCleanup()
+            {
+                throw t;
+            }
+
+        };
+
+        log.warn(ServiceMessages.threadCleanupError(listener, t), t);
+
+        replay();
+
+        ThreadCleanupHub hub = new ThreadCleanupHubImpl(log);
+
+        hub.addThreadCleanupListener(listener);
+
+        hub.cleanup();
+
+        verify();
+    }
+
+    // @Test
+    // public void listener_list_is_per_thread()
+    // {
+    // ThreadCleanupListener l1 = newThreadCleanupListener();
+    // final ThreadCleanupListener l2 = newThreadCleanupListener();
+    //
+    // Thread thread = new Thread();
+    //
+    // l1.threadDidCleanup();
+    //
+    // replay();
+    //
+    // final ThreadCleanupHub hub = new ThreadCleanupHubImpl(log);
+    //
+    // hub.addThreadCleanupListener(l1);
+    //
+    // hub.cleanup();
+    //
+    // verify();
+    // }
+}

Modified: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/ioc/IntegrationTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/ioc/IntegrationTest.java?rev=426587&r1=426586&r2=426587&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/ioc/IntegrationTest.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/ioc/IntegrationTest.java Fri Jul 28 09:04:34 2006
@@ -20,8 +20,8 @@
 import java.util.List;
 import java.util.Map;
 
-import org.apache.tapestry.internal.ioc.TapestryIOCModule;
 import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.apache.tapestry.ioc.services.TapestryIOCModule;
 import org.testng.annotations.Test;
 
 import static org.testng.Assert.assertEquals;

Modified: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/ioc/RegistryBuilderTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/ioc/RegistryBuilderTest.java?rev=426587&r1=426586&r2=426587&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/ioc/RegistryBuilderTest.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/ioc/RegistryBuilderTest.java Fri Jul 28 09:04:34 2006
@@ -17,8 +17,8 @@
 import java.util.jar.Manifest;
 
 import org.apache.hivemind.service.ClassFactory;
-import org.apache.tapestry.internal.ioc.TapestryIOCModule;
 import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.apache.tapestry.ioc.services.TapestryIOCModule;
 import org.testng.annotations.Test;
 
 import static org.testng.Assert.assertEquals;