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/20 22:19:01 UTC
svn commit: r424044 - in /tapestry/tapestry5/tapestry-core/trunk/src:
main/aspect/org/apache/tapestry/internal/aspects/
main/java/org/apache/tapestry/internal/annotations/
main/java/org/apache/tapestry/internal/ioc/
main/java/org/apache/tapestry/intern...
Author: hlship
Date: Thu Jul 20 13:19:01 2006
New Revision: 424044
URL: http://svn.apache.org/viewvc?rev=424044&view=rev
Log:
Removed unused interface MethodFab.
Create OneShot annotation and related aspects.
Mark RegistryBuilder and ClassFab as OneShot objects.
Added:
tapestry/tapestry5/tapestry-core/trunk/src/main/aspect/org/apache/tapestry/internal/aspects/InternalOneShotChecks.aj
tapestry/tapestry5/tapestry-core/trunk/src/main/aspect/org/apache/tapestry/internal/aspects/OneShotChecks.aj
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/annotations/OneShot.java
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/aspects/OneShotChecksAspectTest.java
Removed:
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/services/MethodFab.java
Modified:
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/IOCMessages.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/services/AbstractFab.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/RegistryBuilder.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/transform/MethodSignature.java
Added: tapestry/tapestry5/tapestry-core/trunk/src/main/aspect/org/apache/tapestry/internal/aspects/InternalOneShotChecks.aj
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/aspect/org/apache/tapestry/internal/aspects/InternalOneShotChecks.aj?rev=424044&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/aspect/org/apache/tapestry/internal/aspects/InternalOneShotChecks.aj (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/aspect/org/apache/tapestry/internal/aspects/InternalOneShotChecks.aj Thu Jul 20 13:19:01 2006
@@ -0,0 +1,7 @@
+package org.apache.tapestry.internal.aspects;
+
+public aspect InternalOneShotChecks extends OneShotChecks
+{
+ pointcut targetClasses() :
+ within(org.apache.tapestry..*);
+}
Added: tapestry/tapestry5/tapestry-core/trunk/src/main/aspect/org/apache/tapestry/internal/aspects/OneShotChecks.aj
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/aspect/org/apache/tapestry/internal/aspects/OneShotChecks.aj?rev=424044&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/aspect/org/apache/tapestry/internal/aspects/OneShotChecks.aj (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/aspect/org/apache/tapestry/internal/aspects/OneShotChecks.aj Thu Jul 20 13:19:01 2006
@@ -0,0 +1,54 @@
+package org.apache.tapestry.internal.aspects;
+
+import org.apache.tapestry.internal.annotations.OneShot;
+
+/**
+ * Adds checks related to the {@link org.apache.tapestry.internal.annotations.OneShot} annotation.
+ *
+ * @author Howard M. Lewis Ship
+ */
+
+public abstract aspect OneShotChecks extends AbstractClassTargetting
+perthis(annotatedClasses())
+{
+ private boolean _oneShotLock;
+
+ pointcut annotatedClasses(): targetClasses() && within(@OneShot Object+);
+
+ // Was thinking of adding a warning or error if no method of the class is annotated with @Lockdown.
+ // But since the flag is per instance, a subclass could provide that method. Unless the class
+ // is final, it is reasonable for no method to provide the @Lockdown annotation. Worse, it could be
+ // inherited from a base class itself. So ... no warning, but @OneShot without @Lockdown is
+ // useless.
+
+ /** Method inherited from java.lang.Object are never locked. */
+ pointcut excludedMethods() :
+ execution(public int hashCode()) ||
+ execution(public boolean equals(Object)) ||
+ execution(public String toString());
+
+ /** Locked methods are within annotated classes, aren't excluded, and are public. */
+ pointcut checkedMethods() :
+ annotatedClasses() && ! excludedMethods() && execution(public * *(..));
+
+ /** Methods with the OneShot.Lockdown annotation will set the lock. */
+ pointcut lockingMethods() : checkedMethods() && execution(@OneShot.Lockdown * *(..));
+
+ // Order here is important. The locked check must occur before
+ // the flag is set (for locking methods, which are also checked methods).
+
+ before() : checkedMethods()
+ {
+ if (_oneShotLock)
+ throw new IllegalStateException("Method " + thisJoinPointStaticPart.getSignature()
+ + " may no longer be invoked.");
+ }
+
+ // Now, after the check, turn the flag on for locking methods (with the @Lockdown annotation)
+
+ before() : lockingMethods()
+ {
+ _oneShotLock = true;
+ }
+
+}
Added: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/annotations/OneShot.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/annotations/OneShot.java?rev=424044&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/annotations/OneShot.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/annotations/OneShot.java Thu Jul 20 13:19:01 2006
@@ -0,0 +1,49 @@
+// Copyright 2006 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.tapestry.internal.annotations;
+
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+/**
+ * Used to mark a class as useable once. In such a class, one or more public methods (marked with
+ * the OneShot.Lockdown annotation) will lock the instance such that no further calls on public
+ * methods are allowed. This can be applied to a number of patterns, such as a factory pattern where
+ * a factory instance is created and configured, and the used to create a desired output class (at
+ * which point, the factory instance is of no futher use).
+ * <p>
+ * Methods inherited from java.lang.Object, such as toString(), are not subject to locking.
+ *
+ * @author Howard M. Lewis Ship
+ */
+@Target(TYPE)
+@Retention(RUNTIME)
+@Documented
+@Inherited
+public @interface OneShot {
+
+ @Target(METHOD)
+ @Retention(RUNTIME)
+ @Documented
+ public @interface Lockdown {
+
+ }
+}
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/IOCMessages.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/IOCMessages.java?rev=424044&r1=424043&r2=424044&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/IOCMessages.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/IOCMessages.java Thu Jul 20 13:19:01 2006
@@ -22,7 +22,6 @@
import org.apache.hivemind.Messages;
import org.apache.hivemind.impl.MessageFormatter;
import org.apache.tapestry.internal.annotations.Utility;
-import org.apache.tapestry.ioc.IOCUtilities;
/**
* @author Howard M. Lewis Ship
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/services/AbstractFab.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/services/AbstractFab.java?rev=424044&r1=424043&r2=424044&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/services/AbstractFab.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/services/AbstractFab.java Thu Jul 20 13:19:01 2006
@@ -18,6 +18,7 @@
import java.util.Map;
+import org.apache.tapestry.internal.annotations.OneShot;
import org.apache.tapestry.internal.annotations.SuppressNullCheck;
import javassist.CtClass;
@@ -29,6 +30,7 @@
*
* @author Howard M. Lewis Ship
*/
+@OneShot
public class AbstractFab
{
private final CtClass _ctClass;
@@ -85,6 +87,7 @@
return result;
}
+ @OneShot.Lockdown
public Class createClass()
{
return _source.createClass(_ctClass);
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/RegistryBuilder.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/RegistryBuilder.java?rev=424044&r1=424043&r2=424044&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/RegistryBuilder.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/RegistryBuilder.java Thu Jul 20 13:19:01 2006
@@ -19,6 +19,7 @@
import java.util.Map;
import org.apache.commons.logging.Log;
+import org.apache.tapestry.internal.annotations.OneShot;
import org.apache.tapestry.internal.ioc.DefaultModuleDefImpl;
import org.apache.tapestry.internal.ioc.IOCMessages;
import org.apache.tapestry.internal.ioc.RegistryImpl;
@@ -30,6 +31,7 @@
*
* @author Howard M. Lewis Ship
*/
+@OneShot
public final class RegistryBuilder
{
/** Module defs, keyed on module id. */
@@ -39,8 +41,6 @@
private final Log _log;
- private boolean _locked;
-
private final LogSource _logSource;
public RegistryBuilder()
@@ -62,8 +62,6 @@
public void add(ModuleDef moduleDef)
{
- checkLocked();
-
String id = moduleDef.getModuleId();
if (_modules.containsKey(id))
@@ -98,20 +96,9 @@
}
}
- private void checkLocked()
- {
- if (_locked)
- throw new RuntimeException(IOCMessages.builderLocked());
- }
-
+ @OneShot.Lockdown
public Registry build()
{
- checkLocked();
-
- _locked = true;
-
- // TODO: Consistency checks, once we have interceptors and contributions
-
return new RegistryImpl(_modules.values(), _logSource);
}
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/transform/MethodSignature.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/transform/MethodSignature.java?rev=424044&r1=424043&r2=424044&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/transform/MethodSignature.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/transform/MethodSignature.java Thu Jul 20 13:19:01 2006
@@ -25,7 +25,9 @@
* visibility), return type, parameter types, and declared exception types.
* <p>
* Types are stored as class names (or primitive names) because the MethodSignature is often used in
- * situations where the actual class has not been loaded yet.
+ * situations where the actual class has not been loaded yet. When classes are already loaded (such
+ * as, for use with {@link org.apache.hivemind.service.ClassFab}), then a different implementation
+ * with the same name, {@link org.apache.tapestry.ioc.services.MethodSignature} is used.
*
* @author Howard M. Lewis Ship
*/
Added: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/aspects/OneShotChecksAspectTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/aspects/OneShotChecksAspectTest.java?rev=424044&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/aspects/OneShotChecksAspectTest.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/aspects/OneShotChecksAspectTest.java Thu Jul 20 13:19:01 2006
@@ -0,0 +1,184 @@
+// Copyright 2006 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.tapestry.internal.aspects;
+
+import static org.testng.Assert.assertEquals;
+
+import org.apache.tapestry.internal.annotations.OneShot;
+import org.apache.tapestry.test.BaseTestCase;
+import org.testng.annotations.Test;
+
+/**
+ * @author Howard M. Lewis Ship
+ */
+public class OneShotChecksAspectTest extends BaseTestCase
+{
+ @OneShot
+ public static class Subject
+ {
+ public void go()
+ {
+ }
+
+ @OneShot.Lockdown
+ public void done()
+ {
+ }
+
+ public String toString()
+ {
+ return "SUBJECT";
+ }
+ }
+
+ public static class SubjectSubclass extends Subject
+ {
+ public void subclassMethod()
+ {
+
+ }
+
+ @OneShot.Lockdown
+ public void subclassLocker()
+ {
+ }
+
+ }
+
+ @Test
+ public void basic_locking()
+ {
+ Subject s = new Subject();
+
+ s.go();
+
+ s.done();
+
+ try
+ {
+ s.go();
+ unreachable();
+ }
+ catch (IllegalStateException ex)
+ {
+ assertEquals(ex.getMessage(), "Method void " + getClass().getName()
+ + ".Subject.go() may no longer be invoked.");
+ }
+ }
+
+ @Test
+ public void to_string_not_checked()
+ {
+ Subject s = new Subject();
+
+ assertEquals(s.toString(), "SUBJECT");
+
+ s.done();
+
+ assertEquals(s.toString(), "SUBJECT");
+ }
+
+ @Test
+ public void locking_method_includes_check()
+ {
+ Subject s = new Subject();
+
+ s.go();
+
+ s.done();
+
+ try
+ {
+ s.done();
+ unreachable();
+ }
+ catch (IllegalStateException ex)
+ {
+ assertEquals(ex.getMessage(), "Method void " + getClass().getName()
+ + ".Subject.done() may no longer be invoked.");
+ }
+ }
+
+ @Test
+ public void lock_is_per_instance()
+ {
+ Subject s1 = new Subject();
+ Subject s2 = new Subject();
+
+ s1.go();
+ s2.go();
+
+ s1.done();
+ s2.go();
+
+ try
+ {
+ s1.go();
+ unreachable();
+ }
+ catch (IllegalStateException ex)
+ {
+ // Expected
+ }
+
+ s2.done();
+
+ try
+ {
+ s2.go();
+ unreachable();
+ }
+ catch (IllegalStateException ex)
+ {
+ // Expected
+ }
+ }
+
+ @Test
+ public void base_class_methods_use_same_lock_as_subclass_methods()
+ {
+ SubjectSubclass ss = new SubjectSubclass();
+
+ ss.subclassLocker();
+
+ try
+ {
+ ss.go();
+ unreachable();
+ }
+ catch (IllegalStateException ex)
+ {
+ // Expected
+ }
+ }
+
+ @Test
+ public void subclass_methods_use_same_lock_as_base_class_methods()
+ {
+ SubjectSubclass ss = new SubjectSubclass();
+
+ ss.done();
+
+ try
+ {
+ ss.subclassMethod();
+ unreachable();
+ }
+ catch (IllegalStateException ex)
+ {
+ // Expected
+ }
+ }
+}