Author: hlship
Date: Mon Apr 24 16:11:48 2006
New Revision: 396714

URL: http://svn.apache.org/viewcvs?rev=396714&view=rev
Log:
Refactor annotations ReadLock and WriteLock into Synchronization.Read and 
Synchronization.Write.

Added:
    
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/annotations/Synchronized.java
Removed:
    
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
Modified:
    
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/transform/ClassTransformerImpl.java
    
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/transform/ComponentInstantiatorSourceImpl.java
    
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/transform/ClassTransformation.java
    
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/util/CollectionFactory.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
    
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/util/CollectionFactoryTest.java

Modified: 
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=396714&r1=396713&r2=396714&view=diff
==============================================================================
--- 
tapestry/tapestry5/tapestry-core/trunk/src/main/aspect/org/apache/tapestry/internal/aspects/InternalSynchronization.aj
 (original)
+++ 
tapestry/tapestry5/tapestry-core/trunk/src/main/aspect/org/apache/tapestry/internal/aspects/InternalSynchronization.aj
 Mon Apr 24 16:11:48 2006
@@ -10,5 +10,5 @@
      * the ReadLock or WriteLock annotations.
      */
     pointcut targetClasses()  :
-        within(xxx.org.apache.tapestry.internal.aspects..*);
+        within(org.apache.tapestry.internal..*);
 }

Modified: 
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=396714&r1=396713&r2=396714&view=diff
==============================================================================
--- 
tapestry/tapestry5/tapestry-core/trunk/src/main/aspect/org/apache/tapestry/internal/aspects/Synchronization.aj
 (original)
+++ 
tapestry/tapestry5/tapestry-core/trunk/src/main/aspect/org/apache/tapestry/internal/aspects/Synchronization.aj
 Mon Apr 24 16:11:48 2006
@@ -3,17 +3,17 @@
 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;
+import org.apache.tapestry.internal.annotations.Synchronized;
 
 /**
  * Manages multi-threaded access to methods of an object instance using a
- * [EMAIL PROTECTED] java.util.concurrent.locks.ReadWriteLock}, driven by the 
[EMAIL PROTECTED] ReadLock} and
- * [EMAIL PROTECTED] 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.
+ * [EMAIL PROTECTED] java.util.concurrent.locks.ReentrantReadWriteLock}, 
driven by the
+ * [EMAIL PROTECTED] Synchronized.Read} and [EMAIL PROTECTED] 
Synchronized.Write} annotations. Methods that have the
+ * Synchronized.Read annotation witll be advised to obtain and release the 
read lock around their
+ * execution. Methods with the Synchronized.Write annotation will obtain and 
release the write lock
+ * around their execution. Methods with Synchronized.Read that call a 
Synchronized.Write-ed method
+ * (within the same instance) will release the read lock before invoking the 
Synchronized.Write-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.
@@ -21,36 +21,46 @@
  * TODO: read-into-write not yet implemented!
  * 
  * @author Howard M. Lewis Ship
+ * @see org.apache.tapestry.internal.annotations.Synchronized
  */
 public abstract aspect Synchronization extends AbstractClassTargetting
-perthis(readLockMethods() || writeLockMethods())
+perthis(annotatedClasses())
 {
     private final ReadWriteLock _lock = new ReentrantReadWriteLock();
 
+    pointcut annotatedClasses() :
+         targetClasses() && within(@Synchronized *);
+
+    declare error : 
+        targetClasses() &&
+        execution(@(Synchronized.Read || Synchronized.Write) static * *(..)) :
+            "Synchronized.Read and Synchronized.Write annotations may only be 
applied to instance methods.";
+
     declare error : 
         targetClasses() &&
-        execution(@(ReadLock || WriteLock) static * *(..)) :
-            "ReadLock and WriteLock annotations may only be applied to 
instance methods.";
+        execution(@(Synchronized.Read || Synchronized.Write) * *(..)) &&
+        within(!@(Synchronized) Object+) :
+            "The class must be annotated with Synchronized in order to use the 
Synchronized.Read or Synchronized.Write annotations.";
 
     declare error :
         targetClasses() &&
-        execution(@ReadLock @WriteLock * *(..)) :
-            "A method may be annotated with ReadLock or with WriteLock but not 
both.";
+        execution(@Synchronized.Read @Synchronized.Write * *(..)) :
+            "A method may be annotated with Synchronized.Read or with 
Synchronized.Write but not both.";
 
-    pointcut readLockMethods() :
-         execution(@ReadLock * *(..)) && targetClasses();
+    pointcut readMethods() :
+         execution(@Synchronized.Read * *(..)) && annotatedClasses();
 
-    pointcut writeLockMethods() :
-        execution(@WriteLock * *(..)) && targetClasses();
+    pointcut writeMethods() :
+        execution(@Synchronized.Write * *(..)) && annotatedClasses();
 
     /** Before read lock methods, acquire the read lock. */
-    before() : readLockMethods()
+    before() : readMethods()
     {
         _lock.readLock().lock();
     }
 
     /** After read lock methods (including thrown exceptions), release the 
read lock. */
-    after() : readLockMethods()
+    after() : readMethods()
     {
         _lock.readLock().unlock();
     }
@@ -61,13 +71,13 @@
      * case.
      */
 
-    before(): writeLockMethods()
+    before(): writeMethods()
     {
         _lock.writeLock().lock();
     }
 
     /** And release the write lock after the method completes (successfully, 
or with an exception). */
-    after() : writeLockMethods()
+    after() : writeMethods()
     {
         _lock.writeLock().unlock();
     }

Added: 
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/annotations/Synchronized.java
URL: 
http://svn.apache.org/viewcvs/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/annotations/Synchronized.java?rev=396714&view=auto
==============================================================================
--- 
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/annotations/Synchronized.java
 (added)
+++ 
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/annotations/Synchronized.java
 Mon Apr 24 16:11:48 2006
@@ -0,0 +1,60 @@
+package org.apache.tapestry.internal.annotations;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+/**
+ * Marker interface for classes whose methods may be annotated with 
Synchronized.Read or
+ * Synchronized.Write. It is the path of least AspectJ resistance to get 
things working as they
+ * should.
+ * 
+ * @author Howard M. Lewis Ship
+ */
[EMAIL PROTECTED](TYPE)
[EMAIL PROTECTED](RUNTIME)
[EMAIL PROTECTED]
[EMAIL PROTECTED]
+public @interface Synchronized {
+
+    /**
+     * Marker on methods that perform a read operation. A non-exclusive read 
lock will be acquired
+     * before the method executes, and will be released after the method 
completes (succesfully or
+     * otherwise).
+     * <p>
+     * This annotation may only be applied to methods within Synchronized 
types. It may only be
+     * applied to instance, not static methods. It may not be used in 
combination with the
+     * Synchronized.Write annotation.
+     */
+    @Target(METHOD)
+    @Retention(RUNTIME)
+    @Documented
+    public @interface Read {
+
+    }
+
+    /**
+     * Marker on methods that perform a write operation. An exclusive write 
lock will be acquired
+     * before the method executes, and will be released after the method 
completes (succesfully or
+     * otherwise).
+     * <p>
+     * This annotation may only be applied to methods within Synchronized 
types. It may only be
+     * applied to instance, not static methods. It may not be used in 
combination with the
+     * Synchronized.Write annotation.
+     * <p>
+     * TODO: To acquire the write lock, one must give up one's read lock (if 
any). This is not
+     * supported yet, so invoking a Synchronized.Write method (even 
indirectly) from a
+     * Synchronized.Read method will hang the thread.
+     */
+    @Target(METHOD)
+    @Retention(RUNTIME)
+    @Documented
+    public @interface Write {
+
+    }
+}

Modified: 
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/transform/ClassTransformerImpl.java
URL: 
http://svn.apache.org/viewcvs/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/transform/ClassTransformerImpl.java?rev=396714&r1=396713&r2=396714&view=diff
==============================================================================
--- 
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/transform/ClassTransformerImpl.java
 (original)
+++ 
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/transform/ClassTransformerImpl.java
 Mon Apr 24 16:11:48 2006
@@ -19,6 +19,7 @@
 import javassist.CtClass;
 
 import org.apache.tapestry.annotations.ComponentClass;
+import org.apache.tapestry.internal.annotations.Synchronized;
 import org.apache.tapestry.internal.model.MutableComponentModelImpl;
 import org.apache.tapestry.model.MutableComponentModel;
 import org.apache.tapestry.transform.ClassTransformWorker;
@@ -30,6 +31,7 @@
  * 
  * @author Howard M. Lewis Ship
  */
[EMAIL PROTECTED]
 public class ClassTransformerImpl implements ClassTransformer
 {
     /** Map from class name to class transformation. */
@@ -37,6 +39,7 @@
 
     private ClassTransformWorker _workers;
 
+    @Synchronized.Write
     public void transformClass(CtClass ctClass)
     {
         String classname = ctClass.getName();
@@ -61,6 +64,7 @@
         _nameToClassTransformation.put(classname, transformation);
     }
 
+    @Synchronized.Read
     public Instantiator createInstantiator(Class componentClass)
     {
         String className = componentClass.getName();

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=396714&r1=396713&r2=396714&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 16:11:48 2006
@@ -114,6 +114,7 @@
         }
     }
 
+    // This is called from well within a synchronized block.
     public void onLoad(ClassPool pool, String classname) throws 
NotFoundException,
             CannotCompileException
     {
@@ -218,7 +219,8 @@
         return input.substring(0, lastdot);
     }
 
-    public void addPackage(String packageName)
+    // synchronized may be overkill, but that's ok.
+    public synchronized void addPackage(String packageName)
     {
         Defense.notBlank(packageName, "packageName");
 

Modified: 
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/transform/ClassTransformation.java
URL: 
http://svn.apache.org/viewcvs/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/transform/ClassTransformation.java?rev=396714&r1=396713&r2=396714&view=diff
==============================================================================
--- 
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/transform/ClassTransformation.java
 (original)
+++ 
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/transform/ClassTransformation.java
 Mon Apr 24 16:11:48 2006
@@ -29,6 +29,10 @@
  * transformed. A number of <em>workers</em> will operate upon the 
ClassTransformation to effect
  * the desired changes before the true class is loaded into memory.
  * <p>
+ * Instances of this class are not designed to be thread safe, access to an 
instance should be
+ * restricted to a single thread. In fact, the design of this type is to allow 
stateless singletons
+ * in multiple threads to work on thread-specific data (within the 
ClassTransformation). *
+ * <p>
  * The majority of methods concern the <em>declared</em> members (field and 
methods) of a specific
  * class, rather than any fields or methods inherited from a base class.
  * 

Modified: 
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/util/CollectionFactory.java
URL: 
http://svn.apache.org/viewcvs/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/util/CollectionFactory.java?rev=396714&r1=396713&r2=396714&view=diff
==============================================================================
--- 
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/util/CollectionFactory.java
 (original)
+++ 
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/util/CollectionFactory.java
 Mon Apr 24 16:11:48 2006
@@ -22,6 +22,8 @@
 import java.util.Map;
 import java.util.Set;
 
+import org.apache.tapestry.internal.annotations.Utility;
+
 /**
  * Static factory methods to ease the creation of new collection types (when 
using generics). Most
  * of these method leverage the compiler's ability to match generic types by 
return value. Typical
@@ -40,14 +42,9 @@
  * 
  * @author Howard M. Lewis Ship
  */
[EMAIL PROTECTED]
 public final class CollectionFactory
 {
-
-    /** Prevent instantiation. */
-    private CollectionFactory()
-    {
-    }
-
     /** Constructs and returns a generic [EMAIL PROTECTED] HashMap} instance. 
*/
     public static <K, V> Map<K, V> newMap()
     {
@@ -61,10 +58,10 @@
     }
 
     /**
-     * Constructs a new [EMAIL PROTECTED] java.util.HashMap} instance from an 
existing Map instance.
+     * Constructs a new [EMAIL PROTECTED] java.util.HashMap} instance by 
copying an existing Map instance.
      */
 
-    public static <K, V> Map<K, V> copyMap(Map<K, V> map)
+    public static <K, V> Map<K, V> newMap(Map<K, V> map)
     {
         return new HashMap<K, V>(map);
     }
@@ -75,7 +72,7 @@
         return new ArrayList<T>();
     }
 
-    /** Easy way to convert a list of like-typed values into a list. */
+    /** Easy way to convert an array of like-typed values into a list. */
     public static <T> List<T> newList(T... values)
     {
         return Arrays.asList(values);

Modified: 
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=396714&r1=396713&r2=396714&view=diff
==============================================================================
--- 
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/aspects/SynchronizationAspectTest.java
 (original)
+++ 
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/aspects/SynchronizationAspectTest.java
 Mon Apr 24 16:11:48 2006
@@ -23,10 +23,13 @@
 
     private static final int THREAD_COUNT = 1000;
 
+    private static final int THREAD_BLOCK_SIZE = 50;
+
     @Test
     public void incrementCounter() throws Exception
     {
         List<Thread> threads = newList();
+        List<Thread> running = newList();
 
         for (int i = 0; i < THREAD_COUNT; i++)
         {
@@ -44,15 +47,28 @@
             });
 
             threads.add(t);
+
+            if (threads.size() >= THREAD_BLOCK_SIZE)
+                startThreads(threads, running);
         }
 
-        for (Thread t : threads)
-            t.start();
+        startThreads(threads, running);
 
-        for (Thread t : threads)
+        for (Thread t : running)
             t.join();
 
         assertEquals(_target.getCounter(), THREAD_COUNT);
+    }
+
+    private void startThreads(List<Thread> threads, List<Thread> running)
+    {
+        for (Thread t : threads)
+        {
+            t.start();
+            running.add(t);
+        }
+
+        threads.clear();
     }
 
 }

Modified: 
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=396714&r1=396713&r2=396714&view=diff
==============================================================================
--- 
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/aspects/SynchronizationTarget.java
 (original)
+++ 
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/aspects/SynchronizationTarget.java
 Mon Apr 24 16:11:48 2006
@@ -1,26 +1,23 @@
 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;
+import org.apache.tapestry.internal.annotations.Synchronized;
 
 /**
  * Class used to test the [EMAIL PROTECTED] Synchorization} aspect.
  * 
  * @author Howard M. Lewis Ship
  */
[EMAIL PROTECTED]
 public class SynchronizationTarget
 {
-    private final ReadWriteLock _lock = new ReentrantReadWriteLock();
+    // private final ReadWriteLock _lock = new ReentrantReadWriteLock();
 
     private int _counter;
 
-    @ReadLock
+    @Synchronized.Read
     public int getCounter()
     {
-        _lock.readLock().lock();
+        // _lock.readLock().lock();
 
         try
         {
@@ -28,14 +25,14 @@
         }
         finally
         {
-            _lock.readLock().unlock();
+            // _lock.readLock().unlock();
         }
     }
 
-    @WriteLock
+    @Synchronized.Write
     public void incrementCounter()
     {
-        _lock.writeLock().lock();
+        // _lock.writeLock().lock();
 
         try
         {
@@ -43,25 +40,25 @@
         }
         finally
         {
-            _lock.writeLock().unlock();
+            // _lock.writeLock().unlock();
         }
     }
 
-    @WriteLock
+    @Synchronized.Write
     public void setCounter(int newValue)
     {
-        _lock.writeLock().lock();
+        // _lock.writeLock().lock();
         try
         {
             _counter = newValue;
         }
         finally
         {
-            _lock.writeLock().unlock();
+            // _lock.writeLock().unlock();
         }
     }
 
-    @ReadLock
+    @Synchronized.Write
     public void incrementCounterHard()
     {
         setCounter(getCounter() + 1);

Modified: 
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/util/CollectionFactoryTest.java
URL: 
http://svn.apache.org/viewcvs/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/util/CollectionFactoryTest.java?rev=396714&r1=396713&r2=396714&view=diff
==============================================================================
--- 
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/util/CollectionFactoryTest.java
 (original)
+++ 
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/util/CollectionFactoryTest.java
 Mon Apr 24 16:11:48 2006
@@ -52,7 +52,7 @@
 
         map.put("this", CollectionFactoryTest.class);
 
-        Map<String, Class> copy = CollectionFactory.copyMap(map);
+        Map<String, Class> copy = CollectionFactory.newMap(map);
 
         assertEquals(copy, map);
 



---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to