You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tapestry.apache.org by hl...@apache.org on 2006/04/24 19:04:32 UTC

svn commit: r396607 - in /tapestry/tapestry5/tapestry-core/trunk: ./ src/main/aspect/org/apache/tapestry/internal/aspects/ src/main/java/org/apache/tapestry/internal/annotations/ src/main/java/org/apache/tapestry/internal/transform/ src/test/java/org/a...

Author: hlship
Date: Mon Apr 24 10:04:25 2006
New Revision: 396607

URL: http://svn.apache.org/viewcvs?rev=396607&view=rev
Log:
Update to TestNG 4.7.
Refactor some aspect code.

Added:
    tapestry/tapestry5/tapestry-core/trunk/src/main/aspect/org/apache/tapestry/internal/aspects/AbstractClassTargetting.aj
    tapestry/tapestry5/tapestry-core/trunk/src/main/aspect/org/apache/tapestry/internal/aspects/InternalSynchronization.aj
    tapestry/tapestry5/tapestry-core/trunk/src/main/aspect/org/apache/tapestry/internal/aspects/Synchronization.aj
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/annotations/ReadLock.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/annotations/WriteLock.java
    tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/aspects/SynchronizationAspectTest.java
    tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/aspects/SynchronizationTarget.java
Modified:
    tapestry/tapestry5/tapestry-core/trunk/.classpath
    tapestry/tapestry5/tapestry-core/trunk/pom.xml
    tapestry/tapestry5/tapestry-core/trunk/src/main/aspect/org/apache/tapestry/internal/aspects/CatchNullParameters.aj
    tapestry/tapestry5/tapestry-core/trunk/src/main/aspect/org/apache/tapestry/internal/aspects/UtilityChecks.aj
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/annotations/SuppressNullCheck.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/transform/ComponentInstantiatorSourceImpl.java

Modified: tapestry/tapestry5/tapestry-core/trunk/.classpath
URL: http://svn.apache.org/viewcvs/tapestry/tapestry5/tapestry-core/trunk/.classpath?rev=396607&r1=396606&r2=396607&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/.classpath (original)
+++ tapestry/tapestry5/tapestry-core/trunk/.classpath Mon Apr 24 10:04:25 2006
@@ -7,7 +7,7 @@
 	<classpathentry kind="lib" path="src/test/resources"/>
 	<classpathentry kind="lib" path="src/test/conf"/>
 	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
-	<classpathentry kind="var" path="M2_REPO/org/testng/testng/4.4.7/testng-4.4.7-jdk15.jar"/>
+	<classpathentry kind="var" path="M2_REPO/org/testng/testng/4.7/testng-4.7-jdk15.jar"/>
 	<classpathentry sourcepath="M2_REPO/commons-logging/commons-logging/1.0.4/commons-logging-1.0.4-sources.jar" kind="var" path="M2_REPO/commons-logging/commons-logging/1.0.4/commons-logging-1.0.4.jar"/>
 	<classpathentry kind="var" path="M2_REPO/org/easymock/easymock/2.0/easymock-2.0.jar"/>
 	<classpathentry kind="var" path="M2_REPO/qdox/qdox/1.5/qdox-1.5.jar"/>

Modified: tapestry/tapestry5/tapestry-core/trunk/pom.xml
URL: http://svn.apache.org/viewcvs/tapestry/tapestry5/tapestry-core/trunk/pom.xml?rev=396607&r1=396606&r2=396607&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/pom.xml (original)
+++ tapestry/tapestry5/tapestry-core/trunk/pom.xml Mon Apr 24 10:04:25 2006
@@ -58,7 +58,7 @@
         <dependency>
             <groupId>org.testng</groupId>
             <artifactId>testng</artifactId>
-            <version>4.4.7</version>
+            <version>4.7</version>
             <classifier>jdk15</classifier>
             <scope>compile</scope>
         </dependency>

Added: tapestry/tapestry5/tapestry-core/trunk/src/main/aspect/org/apache/tapestry/internal/aspects/AbstractClassTargetting.aj
URL: http://svn.apache.org/viewcvs/tapestry/tapestry5/tapestry-core/trunk/src/main/aspect/org/apache/tapestry/internal/aspects/AbstractClassTargetting.aj?rev=396607&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/aspect/org/apache/tapestry/internal/aspects/AbstractClassTargetting.aj (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/aspect/org/apache/tapestry/internal/aspects/AbstractClassTargetting.aj Mon Apr 24 10:04:25 2006
@@ -0,0 +1,17 @@
+package org.apache.tapestry.internal.aspects;
+
+/**
+ * Abstract base class for many aspects. This aspect establishes an abstract targetClasses pointcut.
+ * Intermediate sub-aspects extend this with additional pointcuts and advise (but are still
+ * abstract), and then concrete aspects "apply" these aspects to particular sets of classes.
+ * 
+ * @author Howard M. Lewis Ship
+ */
+public abstract aspect AbstractClassTargetting
+{
+    /**
+     * Overridden in concrete aspects to identify which classes are affected (typically, all within
+     * a particular package or set of packages).
+     */
+    abstract pointcut targetClasses();
+}

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/aspect/org/apache/tapestry/internal/aspects/CatchNullParameters.aj
URL: http://svn.apache.org/viewcvs/tapestry/tapestry5/tapestry-core/trunk/src/main/aspect/org/apache/tapestry/internal/aspects/CatchNullParameters.aj?rev=396607&r1=396606&r2=396607&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/aspect/org/apache/tapestry/internal/aspects/CatchNullParameters.aj (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/aspect/org/apache/tapestry/internal/aspects/CatchNullParameters.aj Mon Apr 24 10:04:25 2006
@@ -9,14 +9,8 @@
  * @author Howard M. Lewis Ship
  */
 @SuppressNullCheck
-public abstract aspect CatchNullParameters
+public abstract aspect CatchNullParameters extends AbstractClassTargetting
 {
-    /**
-     * Overridden in concrete aspects to identify which classes are affected (typically, all within
-     * a particular package).
-     */
-    abstract pointcut targetClasses();
-
     pointcut typeNotMarkedAsSuppressed() : 
         !within(@SuppressNullCheck Object+);
 

Added: tapestry/tapestry5/tapestry-core/trunk/src/main/aspect/org/apache/tapestry/internal/aspects/InternalSynchronization.aj
URL: http://svn.apache.org/viewcvs/tapestry/tapestry5/tapestry-core/trunk/src/main/aspect/org/apache/tapestry/internal/aspects/InternalSynchronization.aj?rev=396607&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/aspect/org/apache/tapestry/internal/aspects/InternalSynchronization.aj (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/aspect/org/apache/tapestry/internal/aspects/InternalSynchronization.aj Mon Apr 24 10:04:25 2006
@@ -0,0 +1,14 @@
+package org.apache.tapestry.internal.aspects;
+
+/** @author Howard M. Lewis Ship */
+public aspect InternalSynchronization extends Synchronization
+{
+
+    /**
+     * This aspect is very expensive (due to limitations on AspectJ), it tends to add methods,
+     * interfaces, and variables to every target class, even those that do not contain methods with
+     * the ReadLock or WriteLock annotations.
+     */
+    pointcut targetClasses()  :
+        within(xxx.org.apache.tapestry.internal.aspects..*);
+}

Added: tapestry/tapestry5/tapestry-core/trunk/src/main/aspect/org/apache/tapestry/internal/aspects/Synchronization.aj
URL: http://svn.apache.org/viewcvs/tapestry/tapestry5/tapestry-core/trunk/src/main/aspect/org/apache/tapestry/internal/aspects/Synchronization.aj?rev=396607&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/aspect/org/apache/tapestry/internal/aspects/Synchronization.aj (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/aspect/org/apache/tapestry/internal/aspects/Synchronization.aj Mon Apr 24 10:04:25 2006
@@ -0,0 +1,75 @@
+package org.apache.tapestry.internal.aspects;
+
+import java.util.concurrent.locks.ReadWriteLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+
+import org.apache.tapestry.internal.annotations.ReadLock;
+import org.apache.tapestry.internal.annotations.WriteLock;
+
+/**
+ * Manages multi-threaded access to methods of an object instance using a
+ * {@link java.util.concurrent.locks.ReadWriteLock}, driven by the {@link ReadLock} and
+ * {@link WriteLock} annotations. Methods that have the ReadLock annotation witll be advised to
+ * obtain and release the read lock around their execution. Methods with the WriteLock annotation
+ * will obtain and release the write lock around their execution. Methods with ReadLock that call a
+ * WriteLock-ed method (within the same instance) will release the read lock before invoking the
+ * WriteLock-ed method.
+ * <p>
+ * This aspect also enforces that the annotations are only applied to instance (not static) methods,
+ * and that a method may be either read or write, but not both.
+ * <p>
+ * TODO: read-into-write not yet implemented!
+ * 
+ * @author Howard M. Lewis Ship
+ */
+public abstract aspect Synchronization extends AbstractClassTargetting
+perthis(readLockMethods() || writeLockMethods())
+{
+    private final ReadWriteLock _lock = new ReentrantReadWriteLock();
+
+    declare error : 
+        targetClasses() &&
+        execution(@(ReadLock || WriteLock) static * *(..)) :
+            "ReadLock and WriteLock annotations may only be applied to instance methods.";
+
+    declare error :
+        targetClasses() &&
+        execution(@ReadLock @WriteLock * *(..)) :
+            "A method may be annotated with ReadLock or with WriteLock but not both.";
+
+    pointcut readLockMethods() :
+         execution(@ReadLock * *(..)) && targetClasses();
+
+    pointcut writeLockMethods() :
+        execution(@WriteLock * *(..)) && targetClasses();
+
+    /** Before read lock methods, acquire the read lock. */
+    before() : readLockMethods()
+    {
+        _lock.readLock().lock();
+    }
+
+    /** After read lock methods (including thrown exceptions), release the read lock. */
+    after() : readLockMethods()
+    {
+        _lock.readLock().unlock();
+    }
+
+    /**
+     * Before write lock methods, acquire the write lock. Note that obtaining the write lock will
+     * block indefinately if the current thread has a read lock, but we handle that as a special
+     * case.
+     */
+
+    before(): writeLockMethods()
+    {
+        _lock.writeLock().lock();
+    }
+
+    /** And release the write lock after the method completes (successfully, or with an exception). */
+    after() : writeLockMethods()
+    {
+        _lock.writeLock().unlock();
+    }
+
+}

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/aspect/org/apache/tapestry/internal/aspects/UtilityChecks.aj
URL: http://svn.apache.org/viewcvs/tapestry/tapestry5/tapestry-core/trunk/src/main/aspect/org/apache/tapestry/internal/aspects/UtilityChecks.aj?rev=396607&r1=396606&r2=396607&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/aspect/org/apache/tapestry/internal/aspects/UtilityChecks.aj (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/aspect/org/apache/tapestry/internal/aspects/UtilityChecks.aj Mon Apr 24 10:04:25 2006
@@ -7,14 +7,8 @@
  * 
  * @author Howard M. Lewis Ship
  */
-public abstract aspect UtilityChecks
+public abstract aspect UtilityChecks extends AbstractClassTargetting
 {
-    /**
-     * Overridden in concrete aspects to identify which classes are affected (typically, all within
-     * a particular package).
-     */
-    abstract pointcut targetClasses();
-
     pointcut markedClasses(): @within(Utility) && targetClasses();
 
     pointcut instanceMethods():

Added: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/annotations/ReadLock.java
URL: http://svn.apache.org/viewcvs/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/annotations/ReadLock.java?rev=396607&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/annotations/ReadLock.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/annotations/ReadLock.java Mon Apr 24 10:04:25 2006
@@ -0,0 +1,21 @@
+package org.apache.tapestry.internal.annotations;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+/**
+ * Marker interface placed on methods that require a shared read lock to execute. Such methods will
+ * obtain a non-exclusive read lock (associated with the object instance).
+ * 
+ * @author Howard M. Lewis Ship
+ */
+@Target(METHOD)
+@Retention(RUNTIME)
+@Documented
+public @interface ReadLock {
+
+}

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/annotations/SuppressNullCheck.java
URL: http://svn.apache.org/viewcvs/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/annotations/SuppressNullCheck.java?rev=396607&r1=396606&r2=396607&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/annotations/SuppressNullCheck.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/annotations/SuppressNullCheck.java Mon Apr 24 10:04:25 2006
@@ -14,6 +14,7 @@
 
 package org.apache.tapestry.internal.annotations;
 
+import java.lang.annotation.Documented;
 import java.lang.annotation.Retention;
 import java.lang.annotation.Target;
 
@@ -32,6 +33,7 @@
 @Target(
 { TYPE, CONSTRUCTOR, METHOD })
 @Retention(RUNTIME)
+@Documented
 public @interface SuppressNullCheck {
 
 }

Added: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/annotations/WriteLock.java
URL: http://svn.apache.org/viewcvs/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/annotations/WriteLock.java?rev=396607&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/annotations/WriteLock.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/annotations/WriteLock.java Mon Apr 24 10:04:25 2006
@@ -0,0 +1,20 @@
+package org.apache.tapestry.internal.annotations;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+/**
+ * Marker interface placed on methods that require an exclusive write lock to execute.
+ * 
+ * @author Howard M. Lewis Ship
+ */
+@Target(METHOD)
+@Retention(RUNTIME)
+@Documented
+public @interface WriteLock {
+
+}

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/transform/ComponentInstantiatorSourceImpl.java
URL: http://svn.apache.org/viewcvs/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/transform/ComponentInstantiatorSourceImpl.java?rev=396607&r1=396606&r2=396607&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/transform/ComponentInstantiatorSourceImpl.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/transform/ComponentInstantiatorSourceImpl.java Mon Apr 24 10:04:25 2006
@@ -180,10 +180,7 @@
     {
         try
         {
-            if (inControlledPackage(classname))
-                return _loader.loadClass(classname);
-
-            return _parent.loadClass(classname);
+            return _loader.loadClass(classname);
         }
         catch (ClassNotFoundException ex)
         {

Added: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/aspects/SynchronizationAspectTest.java
URL: http://svn.apache.org/viewcvs/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/aspects/SynchronizationAspectTest.java?rev=396607&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/aspects/SynchronizationAspectTest.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/aspects/SynchronizationAspectTest.java Mon Apr 24 10:04:25 2006
@@ -0,0 +1,58 @@
+package org.apache.tapestry.internal.aspects;
+
+import java.util.List;
+
+import org.apache.tapestry.test.TestBase;
+import org.testng.annotations.Configuration;
+import org.testng.annotations.Test;
+
+import static org.apache.tapestry.util.CollectionFactory.newList;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+
+/** @author Howard M. Lewis Ship */
+public class SynchronizationAspectTest extends TestBase
+{
+    private SynchronizationTarget _target;
+
+    @Configuration(beforeTestClass = true)
+    public void createTarget()
+    {
+        _target = new SynchronizationTarget();
+    }
+
+    private static final int THREAD_COUNT = 1000;
+
+    @Test
+    public void incrementCounter() throws Exception
+    {
+        List<Thread> threads = newList();
+
+        for (int i = 0; i < THREAD_COUNT; i++)
+        {
+            Thread t = new Thread(new Runnable()
+            {
+                public void run()
+                {
+
+                    int start = _target.getCounter();
+
+                    _target.incrementCounter();
+
+                    assertTrue(_target.getCounter() > start);
+                }
+            });
+
+            threads.add(t);
+        }
+
+        for (Thread t : threads)
+            t.start();
+
+        for (Thread t : threads)
+            t.join();
+
+        assertEquals(_target.getCounter(), THREAD_COUNT);
+    }
+
+}

Added: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/aspects/SynchronizationTarget.java
URL: http://svn.apache.org/viewcvs/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/aspects/SynchronizationTarget.java?rev=396607&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/aspects/SynchronizationTarget.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/aspects/SynchronizationTarget.java Mon Apr 24 10:04:25 2006
@@ -0,0 +1,69 @@
+package org.apache.tapestry.internal.aspects;
+
+import java.util.concurrent.locks.ReadWriteLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+
+import org.apache.tapestry.internal.annotations.ReadLock;
+import org.apache.tapestry.internal.annotations.WriteLock;
+
+/**
+ * Class used to test the {@link Synchorization} aspect.
+ * 
+ * @author Howard M. Lewis Ship
+ */
+public class SynchronizationTarget
+{
+    private final ReadWriteLock _lock = new ReentrantReadWriteLock();
+
+    private int _counter;
+
+    @ReadLock
+    public int getCounter()
+    {
+        _lock.readLock().lock();
+
+        try
+        {
+            return _counter;
+        }
+        finally
+        {
+            _lock.readLock().unlock();
+        }
+    }
+
+    @WriteLock
+    public void incrementCounter()
+    {
+        _lock.writeLock().lock();
+
+        try
+        {
+            _counter++;
+        }
+        finally
+        {
+            _lock.writeLock().unlock();
+        }
+    }
+
+    @WriteLock
+    public void setCounter(int newValue)
+    {
+        _lock.writeLock().lock();
+        try
+        {
+            _counter = newValue;
+        }
+        finally
+        {
+            _lock.writeLock().unlock();
+        }
+    }
+
+    @ReadLock
+    public void incrementCounterHard()
+    {
+        setCounter(getCounter() + 1);
+    }
+}



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