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 2010/01/31 20:03:37 UTC
svn commit: r905099 - in /tapestry/tapestry5/trunk/tapestry-core/src:
main/java/org/apache/tapestry5/internal/services/
main/java/org/apache/tapestry5/services/
test/java/org/apache/tapestry5/internal/services/
test/java/org/apache/tapestry5/internal/t...
Author: hlship
Date: Sun Jan 31 19:03:37 2010
New Revision: 905099
URL: http://svn.apache.org/viewvc?rev=905099&view=rev
Log:
Rename TransformMethod.advice() to TransformMethod.addAdvice(), start work on making comnponent methods accessible (MethodAccess)
Added:
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/AbstractMethodAccess.java (with props)
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/MethodInvocationFailResult.java (with props)
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/MethodInvocationSuccessfulResult.java (with props)
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/MethodAccess.java (with props)
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/MethodInvocationResult.java (with props)
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/transform/pages/MethodAccessSubject.java (with props)
Modified:
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/InternalClassTransformationImpl.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/ClassTransformation.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/ComponentMethodAdvice.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TransformMethod.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TransformMethodSignature.java
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/InternalClassTransformationImplTest.java
Added: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/AbstractMethodAccess.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/AbstractMethodAccess.java?rev=905099&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/AbstractMethodAccess.java (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/AbstractMethodAccess.java Sun Jan 31 19:03:37 2010
@@ -0,0 +1,36 @@
+// Copyright 2010 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.tapestry5.internal.services;
+
+import org.apache.tapestry5.services.MethodAccess;
+import org.apache.tapestry5.services.MethodInvocationResult;
+
+/**
+ * Base class used for dynamically-created subclasses that implement {@link MethodAccess}
+ *
+ * @since 5.2.0
+ */
+public abstract class AbstractMethodAccess implements MethodAccess
+{
+ protected MethodInvocationResult success(Object result)
+ {
+ return new MethodInvocationSuccessfulResult(result);
+ }
+
+ protected MethodInvocationResult fail(Throwable exception)
+ {
+ return new MethodInvocationFailResult(exception);
+ }
+}
Propchange: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/AbstractMethodAccess.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/InternalClassTransformationImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/InternalClassTransformationImpl.java?rev=905099&r1=905098&r2=905099&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/InternalClassTransformationImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/InternalClassTransformationImpl.java Sun Jan 31 19:03:37 2010
@@ -43,14 +43,7 @@
import org.apache.tapestry5.model.ComponentModel;
import org.apache.tapestry5.model.MutableComponentModel;
import org.apache.tapestry5.runtime.Component;
-import org.apache.tapestry5.services.ComponentMethodAdvice;
-import org.apache.tapestry5.services.ComponentValueProvider;
-import org.apache.tapestry5.services.FieldFilter;
-import org.apache.tapestry5.services.MethodFilter;
-import org.apache.tapestry5.services.TransformField;
-import org.apache.tapestry5.services.TransformMethod;
-import org.apache.tapestry5.services.TransformMethodSignature;
-import org.apache.tapestry5.services.TransformUtils;
+import org.apache.tapestry5.services.*;
import org.slf4j.Logger;
/**
@@ -58,6 +51,9 @@
*/
public final class InternalClassTransformationImpl implements InternalClassTransformation
{
+ public static final MethodSignature INVOKE_SIGNATURE = new MethodSignature(
+ MethodInvocationResult.class, "invoke", new Class[]
+ { Object.class, Object[].class }, null);
private static final int INIT_BUFFER_SIZE = 100;
@@ -87,6 +83,8 @@
private ComponentMethodInvocationBuilder builder;
+ private MethodAccess access;
+
TransformMethodImpl(CtMethod method, boolean added)
{
this.method = method;
@@ -113,7 +111,7 @@
return sig;
}
- public void advise(ComponentMethodAdvice advice)
+ public void addAdvice(ComponentMethodAdvice advice)
{
failIfFrozen();
@@ -125,10 +123,105 @@
builder.addAdvice(advice);
}
+ public MethodAccess getAccess()
+ {
+ failIfFrozen();
+
+ if (access == null)
+ access = createMethodAccess();
+
+ return access;
+ }
+
+ private MethodAccess createMethodAccess()
+ {
+ if (isPublic())
+ return createPublicMethodAccess();
+
+ return null;
+ }
+
+ private boolean isPublic()
+ {
+ return Modifier.isPublic(sig.getModifiers());
+ }
+
+ private MethodAccess createPublicMethodAccess()
+ {
+
+ ClassFab cf = classFactory
+ .newClass(ClassFabUtils.generateClassName(MethodAccess.class),
+ AbstractMethodAccess.class);
+
+ boolean isVoid = sig.getReturnType().equals("void");
+
+ BodyBuilder builder = new BodyBuilder().begin();
+
+ builder.addln("%s instance = (%<s) $1;", getClassName());
+
+ builder.addln("try").begin();
+
+ if (!isVoid)
+ {
+ builder.add("return success(($w) ");
+ }
+
+ // Call the instance method, even if its void.
+
+ builder.add("instance.%s(", sig.getMethodName());
+
+ int p = 0;
+
+ for (String type : sig.getParameterTypes())
+ {
+ if (p != 0)
+ builder.add(", ");
+
+ String ref = String.format("$2[%d]", p++);
+ builder.add(ClassFabUtils.castReference(ref, type));
+ p++;
+ }
+
+ // Balance the call to success()
+ if (!isVoid)
+ builder.add(")");
+
+ builder.addln(");");
+
+ if (isVoid)
+ builder.addln("return success(null);");
+
+ builder.end(); // try
+ builder.addln("catch (java.lang.RuntimeException ex) { throw ex; }");
+ builder.addln("catch (java.lang.Exception ex) { return fail(ex); }");
+
+ builder.end();
+
+ cf.addMethod(Modifier.PUBLIC, INVOKE_SIGNATURE, builder.toString());
+
+ cf.addToString(String.format("MethodAccess[method %s of class %s]", sig
+ .getMediumDescription(), getClassName()));
+
+ Class accessClass = cf.createClass();
+
+ try
+ {
+ Object accessInstance = accessClass.newInstance();
+
+ return (MethodAccess) accessInstance;
+ }
+ catch (Exception ex)
+ {
+ throw new RuntimeException(ex);
+ }
+ }
+
public void extend(String body)
{
failIfFrozen();
+ Defense.notBlank(body, "body");
+
try
{
method.insertAfter(body);
@@ -1519,7 +1612,7 @@
public void advise(TransformMethodSignature methodSignature, ComponentMethodAdvice advice)
{
- getMethod(methodSignature).advise(advice);
+ getMethod(methodSignature).addAdvice(advice);
}
public boolean isMethodOverride(TransformMethodSignature methodSignature)
Added: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/MethodInvocationFailResult.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/MethodInvocationFailResult.java?rev=905099&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/MethodInvocationFailResult.java (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/MethodInvocationFailResult.java Sun Jan 31 19:03:37 2010
@@ -0,0 +1,56 @@
+// Copyright 2010 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.tapestry5.internal.services;
+
+import org.apache.tapestry5.services.MethodInvocationResult;
+
+/**
+ * Implementation of {@link MethodInvocationResult} for failed
+ * invocations (where a checked exception was thrown).
+ *
+ * @since 5.2.0
+ */
+public class MethodInvocationFailResult implements MethodInvocationResult
+{
+ private final Throwable thrown;
+
+ public MethodInvocationFailResult(Throwable thrown)
+ {
+ this.thrown = thrown;
+ }
+
+ public Object getReturnValue()
+ {
+ return null;
+ }
+
+ public <T extends Throwable> T getThrown(Class<T> throwableClass)
+ {
+ if (throwableClass.isInstance(thrown))
+ return throwableClass.cast(thrown);
+
+ return null;
+ }
+
+ public boolean isFail()
+ {
+ return true;
+ }
+
+ public void rethrow()
+ {
+ throw new RuntimeException(thrown);
+ }
+}
Propchange: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/MethodInvocationFailResult.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/MethodInvocationSuccessfulResult.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/MethodInvocationSuccessfulResult.java?rev=905099&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/MethodInvocationSuccessfulResult.java (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/MethodInvocationSuccessfulResult.java Sun Jan 31 19:03:37 2010
@@ -0,0 +1,53 @@
+// Copyright 2010 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.tapestry5.internal.services;
+
+import org.apache.tapestry5.services.MethodInvocationResult;
+
+/**
+ * Implementation of {@link MethodInvocationResult} for successful
+ * method invocations.
+ *
+ * @since 5.2.0
+ */
+public class MethodInvocationSuccessfulResult implements MethodInvocationResult
+{
+ private final Object returnValue;
+
+ public MethodInvocationSuccessfulResult(Object returnValue)
+ {
+ this.returnValue = returnValue;
+ }
+
+ public Object getReturnValue()
+ {
+ return returnValue;
+ }
+
+ public <T extends Throwable> T getThrown(Class<T> throwableClass)
+ {
+ return null;
+ }
+
+ public boolean isFail()
+ {
+ return false;
+ }
+
+ public void rethrow()
+ {
+ }
+
+}
Propchange: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/MethodInvocationSuccessfulResult.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/ClassTransformation.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/ClassTransformation.java?rev=905099&r1=905098&r2=905099&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/ClassTransformation.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/ClassTransformation.java Sun Jan 31 19:03:37 2010
@@ -532,7 +532,7 @@
/**
* Adds method advice for the indicated method.
*
- * @deprecated Use {@link TransformMethod#advise(ComponentMethodAdvice)} instead
+ * @deprecated Use {@link TransformMethod#addAdvice(ComponentMethodAdvice)} instead
*/
void advise(TransformMethodSignature methodSignature, ComponentMethodAdvice advice);
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/ComponentMethodAdvice.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/ComponentMethodAdvice.java?rev=905099&r1=905098&r2=905099&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/ComponentMethodAdvice.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/ComponentMethodAdvice.java Sun Jan 31 19:03:37 2010
@@ -19,7 +19,7 @@
* method parameters. After invoking {@link org.apache.tapestry5.services.ComponentMethodInvocation#proceed()}, the
* advice may query and override thrown exceptions or the return value of the invocation.
*
- * @see TransformMethod#advise(ComponentMethodAdvice)
+ * @see TransformMethod#addAdvice(ComponentMethodAdvice)
*/
public interface ComponentMethodAdvice
{
Added: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/MethodAccess.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/MethodAccess.java?rev=905099&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/MethodAccess.java (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/MethodAccess.java Sun Jan 31 19:03:37 2010
@@ -0,0 +1,37 @@
+// Copyright 2010 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.tapestry5.services;
+
+/**
+ * Represents a bridge to an object method, when that method may not be public. A MethodAccess object
+ * encapsulates the approach for invoking the method and capturing the result (either the return value,
+ * or the checked exception that is thrown).
+ *
+ * @since 5.2.0
+ */
+public interface MethodAccess
+{
+ /**
+ * Invoke the method on the target, passing a number of arguments to the method.
+ * If the method throws a RuntimeException, that is passed through unchanged.
+ * If the method throws a checked exception, that will be reflected in the invocation result.
+ *
+ * @param target
+ * object on which to invoke a method
+ * @param arguments
+ * arguments to pass to the method
+ */
+ MethodInvocationResult invoke(Object target, Object... arguments);
+}
Propchange: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/MethodAccess.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/MethodInvocationResult.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/MethodInvocationResult.java?rev=905099&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/MethodInvocationResult.java (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/MethodInvocationResult.java Sun Jan 31 19:03:37 2010
@@ -0,0 +1,52 @@
+// Copyright 2010 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.tapestry5.services;
+
+/**
+ * Captures the result of invoking a method.
+ *
+ * @since 5.2.0
+ */
+public interface MethodInvocationResult
+{
+ /**
+ * The return value from the method invocation. This will be null if the method returns null,
+ * is a void method, or if a checked exception was thrown by the method.
+ */
+ Object getReturnValue();
+
+ /**
+ * If true, then the method invocation ended with a checked exception being thrown.
+ */
+ boolean isFail();
+
+ /**
+ * If the invocation threw a checked exception, this method will wrap that exception in a
+ * RuntimeException and throw that. For most code that doesn't specifically care about
+ * the thrown exception, this method should be invoked before continuing on to
+ * examine {@link #getReturnValue()}.
+ */
+ void rethrow();
+
+ /**
+ * If {@link #isFail()} is true, this method provides access to the actual checked exception that was thrown.
+ *
+ * @param throwableClass
+ * the type of exception to match
+ * @return the exception, if the method invocation threw a checked exception, and the exception is assignable to
+ * the provided type. In other cases, null is returned.
+ */
+ <T extends Throwable> T getThrown(Class<T> throwableClass);
+}
Propchange: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/MethodInvocationResult.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TransformMethod.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TransformMethod.java?rev=905099&r1=905098&r2=905099&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TransformMethod.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TransformMethod.java Sun Jan 31 19:03:37 2010
@@ -43,24 +43,31 @@
* The extended method is considered <em>new</em>. New methods <em>are not</em> scanned for removed fields, field
* access changes, etc.
* <p>
- * This method will eventually be removed, using {@link #advise(ComponentMethodAdvice)} or some other alternative is
+ * This method will eventually be removed, using {@link #addAdvice(ComponentMethodAdvice)} or some other alternative is
* preferred.
*
* @param body
* the body of Javassist psuedo-code
* @throws RuntimeException
* if the provided Javassist method body can not be compiled
+ * @deprecated Use {@link #addAdvice(ComponentMethodAdvice)} instead
*/
void extend(String body);
/**
+ * Returns an object that can be used to invoke the method on an instance of the component class (regardless
+ * of the actual visibility of the method).
+ */
+ MethodAccess getAccess();
+
+ /**
* Add advice for the method; the advice will be threaded into method invocations of the indicated method.
- * A method may be given multiple advice; each advice will recieve control in turn (assuming
+ * A method may be given multiple advice; each advice will receive control in turn (assuming
* the previous advice invokes {@link ComponentMethodInvocation#proceed()}) in the order the advice
* is added. The last advice will proceed to the original method implementation.
*
* @param advice
* to receive control when the method is invoked
*/
- void advise(ComponentMethodAdvice advice);
+ void addAdvice(ComponentMethodAdvice advice);
}
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TransformMethodSignature.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TransformMethodSignature.java?rev=905099&r1=905098&r2=905099&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TransformMethodSignature.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TransformMethodSignature.java Sun Jan 31 19:03:37 2010
@@ -16,17 +16,19 @@
import static org.apache.tapestry5.ioc.internal.util.Defense.notBlank;
+import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import org.apache.tapestry5.internal.InternalConstants;
+import org.apache.tapestry5.ioc.services.ClassFabUtils;
/**
* A representation of a method signature, which consists of its name, modifiers (primarily,
* visibility), return type,
* parameter types, and declared exception types.
* <p/>
- * Types are stored as class names (or primitive names) because the signature is used with
- * {@link ClassTransformation} (which operates on as-yet unloaded classes).
+ * Types are stored as class names (or primitive names) because the signature is used with {@link ClassTransformation}
+ * (which operates on as-yet unloaded classes).
*/
public class TransformMethodSignature implements Comparable<TransformMethodSignature>
{
Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/InternalClassTransformationImplTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/InternalClassTransformationImplTest.java?rev=905099&r1=905098&r2=905099&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/InternalClassTransformationImplTest.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/InternalClassTransformationImplTest.java Sun Jan 31 19:03:37 2010
@@ -1,10 +1,10 @@
-// Copyright 2006, 2007, 2008 The Apache Software Foundation
+// Copyright 2006, 2007, 2008, 2010 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
+// 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,
@@ -20,7 +20,11 @@
import java.lang.annotation.Documented;
import java.lang.annotation.Target;
import java.lang.reflect.Field;
+import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.sql.SQLException;
import java.util.List;
import java.util.Map;
@@ -41,8 +45,10 @@
import org.apache.tapestry5.internal.transform.InheritedAnnotation;
import org.apache.tapestry5.internal.transform.TestPackageAwareLoader;
import org.apache.tapestry5.internal.transform.pages.*;
+import org.apache.tapestry5.internal.util.Holder;
import org.apache.tapestry5.ioc.internal.services.ClassFactoryClassPool;
import org.apache.tapestry5.ioc.internal.services.ClassFactoryImpl;
+import org.apache.tapestry5.ioc.internal.services.CtClassSourceImpl;
import org.apache.tapestry5.ioc.services.ClassFactory;
import org.apache.tapestry5.ioc.services.PropertyAccess;
import org.apache.tapestry5.ioc.util.BodyBuilder;
@@ -50,7 +56,13 @@
import org.apache.tapestry5.runtime.Component;
import org.apache.tapestry5.runtime.ComponentResourcesAware;
import org.apache.tapestry5.services.ClassTransformation;
+import org.apache.tapestry5.services.ComponentClassTransformWorker;
+import org.apache.tapestry5.services.ComponentMethodAdvice;
+import org.apache.tapestry5.services.ComponentMethodInvocation;
+import org.apache.tapestry5.services.MethodAccess;
import org.apache.tapestry5.services.MethodFilter;
+import org.apache.tapestry5.services.MethodInvocationResult;
+import org.apache.tapestry5.services.TransformMethod;
import org.apache.tapestry5.services.TransformMethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -62,7 +74,7 @@
/**
* The tests share a number of resources, and so are run sequentially.
*/
-@Test(sequential = true)
+@Test
public class InternalClassTransformationImplTest extends InternalBaseTestCase
{
private static final String STRING_CLASS_NAME = "java.lang.String";
@@ -77,6 +89,8 @@
private ClassFactoryClassPool classFactoryClassPool;
+ private CtClassSourceImpl classSource;
+
@BeforeClass
public void setup_access()
{
@@ -96,11 +110,11 @@
@BeforeMethod
public void setup_classpool()
{
- // _classPool = new ClassPool();
+ ClassLoader threadDeadlockBuffer = new URLClassLoader(new URL[0], contextClassLoader);
- classFactoryClassPool = new ClassFactoryClassPool(contextClassLoader);
+ classFactoryClassPool = new ClassFactoryClassPool(threadDeadlockBuffer);
- loader = new TestPackageAwareLoader(contextClassLoader, classFactoryClassPool);
+ loader = new TestPackageAwareLoader(threadDeadlockBuffer, classFactoryClassPool);
// Inside Maven Surefire, the system classpath is not sufficient to find all
// the necessary files.
@@ -109,6 +123,42 @@
Logger logger = LoggerFactory.getLogger(InternalClassTransformationImplTest.class);
classFactory = new ClassFactoryImpl(loader, classFactoryClassPool, logger);
+
+ classSource = new CtClassSourceImpl(classFactoryClassPool, loader);
+ }
+
+ private Object transform(Class componentClass, ComponentClassTransformWorker worker)
+ throws Exception
+ {
+ InternalComponentResources resources = mockInternalComponentResources();
+
+ CtClass targetObjectCtClass = findCtClass(componentClass);
+
+ Logger logger = mockLogger();
+ MutableComponentModel model = mockMutableComponentModel(logger);
+
+ replay();
+
+ InternalClassTransformation ct = new InternalClassTransformationImpl(classFactory,
+ targetObjectCtClass, new ComponentClassCacheImpl(classFactory), model, classSource);
+
+ worker.transform(ct, model);
+
+ ct.finish();
+
+ Instantiator instantiator = ct.createInstantiator();
+
+ Component instance = instantiator.newInstance(resources);
+
+ verify();
+
+ expect(resources.getComponent()).andReturn(instance).anyTimes();
+
+ replay();
+
+ // Return the instance for further testing
+
+ return instance;
}
private CtClass findCtClass(Class targetClass) throws NotFoundException
@@ -203,8 +253,9 @@
}
catch (RuntimeException ex)
{
- assertEquals(ex.getMessage(),
- "Class org.apache.tapestry5.internal.transform.pages.ParentClass does not contain a field named 'unknownField'.");
+ assertEquals(
+ ex.getMessage(),
+ "Class org.apache.tapestry5.internal.transform.pages.ParentClass does not contain a field named 'unknownField'.");
}
verify();
@@ -331,8 +382,9 @@
}
catch (RuntimeException ex)
{
- assertEquals(ex.getMessage(),
- "Field _field4 of class org.apache.tapestry5.internal.transform.pages.ClaimedFields is already claimed by Fred and can not be claimed by Barney.");
+ assertEquals(
+ ex.getMessage(),
+ "Field _field4 of class org.apache.tapestry5.internal.transform.pages.ClaimedFields is already claimed by Fred and can not be claimed by Barney.");
}
verify();
@@ -393,7 +445,8 @@
replay();
- ClassTransformation ct = createClassTransformation(ChildClassInheritsAnnotation.class, logger);
+ ClassTransformation ct = createClassTransformation(ChildClassInheritsAnnotation.class,
+ logger);
InheritedAnnotation ia = ct.getAnnotation(InheritedAnnotation.class);
@@ -412,7 +465,8 @@
replay();
- ClassTransformation ct = createClassTransformation(ChildClassInheritsAnnotation.class, logger);
+ ClassTransformation ct = createClassTransformation(ChildClassInheritsAnnotation.class,
+ logger);
Meta meta = ct.getAnnotation(Meta.class);
@@ -449,7 +503,8 @@
}
@Test
- public void ensure_javassist_does_not_show_interface_methods_on_abstract_class() throws Exception
+ public void ensure_javassist_does_not_show_interface_methods_on_abstract_class()
+ throws Exception
{
CtClass ctClass = findCtClass(AbstractFoo.class);
@@ -469,7 +524,8 @@
}
@Test
- public void ensure_javassist_does_not_show_extended_interface_methods_on_interface() throws Exception
+ public void ensure_javassist_does_not_show_extended_interface_methods_on_interface()
+ throws Exception
{
CtClass ctClass = findCtClass(FooBarInterface.class);
@@ -481,6 +537,147 @@
assertEquals(methods.length, 0);
}
+ public static final TransformMethodSignature RUN = new TransformMethodSignature("run");
+
+ @Test
+ public void access_to_public_void_no_args_method() throws Exception
+ {
+ Object instance = transform(MethodAccessSubject.class, new ComponentClassTransformWorker()
+ {
+ public void transform(ClassTransformation transformation, MutableComponentModel model)
+ {
+ transformation.addImplementedInterface(Runnable.class);
+
+ TransformMethodSignature targetMethodSignature = new TransformMethodSignature(
+ "publicVoidNoArgs");
+ TransformMethod pvna = transformation.getMethod(targetMethodSignature);
+
+ final MethodAccess pvnaAccess = pvna.getAccess();
+
+ transformation.getMethod(RUN).addAdvice(new ComponentMethodAdvice()
+ {
+ public void advise(ComponentMethodInvocation invocation)
+ {
+ invocation.proceed();
+
+ MethodInvocationResult invocationResult = pvnaAccess.invoke(invocation
+ .getInstance());
+
+ assertFalse(invocationResult.isFail(),
+ "fail should be false, no checked exception thrown");
+ }
+ });
+ }
+ });
+
+ Runnable r = (Runnable) instance;
+
+ r.run();
+
+ assertEquals(access.get(r, "marker"), "publicVoidNoArgs");
+ }
+
+ @Test
+ public void access_to_public_void_throws_exception() throws Exception
+ {
+ Object instance = transform(MethodAccessSubject.class, new ComponentClassTransformWorker()
+ {
+ public void transform(ClassTransformation transformation, MutableComponentModel model)
+ {
+ transformation.addImplementedInterface(Runnable.class);
+
+ TransformMethodSignature targetMethodSignature = new TransformMethodSignature(
+ Modifier.PUBLIC, "void", "publicVoidThrowsException", null, new String[]
+ { SQLException.class.getName() });
+ TransformMethod targetMethod = transformation.getMethod(targetMethodSignature);
+
+ final MethodAccess targetAccess = targetMethod.getAccess();
+
+ transformation.getMethod(RUN).addAdvice(new ComponentMethodAdvice()
+ {
+ public void advise(ComponentMethodInvocation invocation)
+ {
+ invocation.proceed();
+
+ MethodInvocationResult invocationResult = targetAccess.invoke(invocation
+ .getInstance());
+
+ assertTrue(invocationResult.isFail(),
+ "fail should be true; checked exception thrown");
+
+ SQLException ex = invocationResult.getThrown(SQLException.class);
+
+ assertNotNull(ex);
+ assertEquals(ex.getMessage(), "From publicVoidThrowsException()");
+ }
+ });
+ }
+ });
+
+ Runnable r = (Runnable) instance;
+
+ r.run();
+
+ assertEquals(access.get(r, "marker"), "publicVoidThrowsException");
+ }
+
+ public interface ProcessInteger
+ {
+ int operate(int input);
+ }
+
+ @Test
+ public void access_to_public_method_with_argument_and_return_value() throws Exception
+ {
+ Object instance = transform(MethodAccessSubject.class, new ComponentClassTransformWorker()
+ {
+ public void transform(ClassTransformation transformation, MutableComponentModel model)
+ {
+ transformation.addImplementedInterface(ProcessInteger.class);
+
+ TransformMethod incrementer = transformation
+ .getMethod(new TransformMethodSignature(Modifier.PUBLIC, "int",
+ "incrementer", new String[]
+ { "int" }, null));
+
+ final MethodAccess incrementerAccess = incrementer.getAccess();
+
+ TransformMethodSignature operateSig = new TransformMethodSignature(Modifier.PUBLIC,
+ "int", "operate", new String[]
+ { "int" }, null);
+
+ TransformMethod operate = transformation.getMethod(operateSig);
+
+ operate.addAdvice(new ComponentMethodAdvice()
+ {
+ public void advise(ComponentMethodInvocation invocation)
+ {
+ // This advice *replaces* the original do-nothing method, because
+ // it never calls invocation.proceed().
+
+ // This kind of advice always needs some special knowledge of
+ // the parameters to the original method, so that they can be mapped
+ // to some other method (including a MethodAccess).
+
+ Integer parameter = (Integer) invocation.getParameter(0);
+
+ MethodInvocationResult result = incrementerAccess.invoke(invocation
+ .getInstance(), parameter);
+
+ invocation.overrideResult(result.getReturnValue());
+ }
+ });
+ }
+ });
+
+ ProcessInteger pi = (ProcessInteger) instance;
+
+ assertEquals(pi.operate(99), 100);
+
+ assertEquals(access.get(instance, "marker"), "incrementer(99)");
+
+ }
+
@Test
public void add_injected_field() throws Exception
{
@@ -493,8 +690,8 @@
replay();
- InternalClassTransformation ct = new InternalClassTransformationImpl(classFactory, targetObjectCtClass, null,
- model, null);
+ InternalClassTransformation ct = new InternalClassTransformationImpl(classFactory,
+ targetObjectCtClass, null, model, null);
// Default behavior is to add an injected field for the InternalComponentResources object,
// so we'll just check that.
@@ -526,8 +723,8 @@
replay();
- InternalClassTransformation ct = new InternalClassTransformationImpl(classFactory, targetObjectCtClass, null,
- model, null);
+ InternalClassTransformation ct = new InternalClassTransformationImpl(classFactory,
+ targetObjectCtClass, null, model, null);
String parentFieldName = ct.addInjectedField(String.class, "_value", value);
@@ -550,8 +747,8 @@
// This proves the the field is protected and can be used in subclasses.
- ct.addMethod(new TransformMethodSignature(Modifier.PUBLIC, "java.lang.String", "getValue", null, null),
- "return " + subclassFieldName + ";");
+ ct.addMethod(new TransformMethodSignature(Modifier.PUBLIC, "java.lang.String", "getValue",
+ null, null), "return " + subclassFieldName + ";");
ct.finish();
@@ -578,8 +775,8 @@
replay();
- InternalClassTransformation ct = new InternalClassTransformationImpl(classFactory, targetObjectCtClass, null,
- model, null);
+ InternalClassTransformation ct = new InternalClassTransformationImpl(classFactory,
+ targetObjectCtClass, null, model, null);
ct.addImplementedInterface(FooInterface.class);
ct.addImplementedInterface(GetterMethodsInterface.class);
@@ -590,7 +787,8 @@
Class[] interfaces = transformed.getInterfaces();
- assertEquals(interfaces, new Class[] { Component.class, FooInterface.class, GetterMethodsInterface.class });
+ assertEquals(interfaces, new Class[]
+ { Component.class, FooInterface.class, GetterMethodsInterface.class });
Object target = ct.createInstantiator().newInstance(resources);
@@ -626,8 +824,8 @@
CtClass targetObjectCtClass = findCtClass(ReadOnlyBean.class);
- InternalClassTransformation ct = new InternalClassTransformationImpl(classFactory, targetObjectCtClass, null,
- model, null);
+ InternalClassTransformation ct = new InternalClassTransformationImpl(classFactory,
+ targetObjectCtClass, null, model, null);
ct.makeReadOnly("_value");
@@ -645,7 +843,7 @@
// The PropertyAccess layer adds a wrapper exception around the real one.
assertEquals(ex.getCause().getMessage(),
- "Field org.apache.tapestry5.internal.transform.pages.ReadOnlyBean._value is read-only.");
+ "Field org.apache.tapestry5.internal.transform.pages.ReadOnlyBean._value is read-only.");
}
verify();
@@ -661,8 +859,8 @@
CtClass targetObjectCtClass = findCtClass(RemoveFieldBean.class);
- InternalClassTransformation ct = new InternalClassTransformationImpl(null, targetObjectCtClass, null, model,
- null);
+ InternalClassTransformation ct = new InternalClassTransformationImpl(null,
+ targetObjectCtClass, null, model, null);
ct.removeField("_barney");
@@ -683,8 +881,8 @@
CtClass targetObjectCtClass = findCtClass(ReadOnlyBean.class);
- InternalClassTransformation ct = new InternalClassTransformationImpl(classFactory, targetObjectCtClass, null,
- model, null);
+ InternalClassTransformation ct = new InternalClassTransformationImpl(classFactory,
+ targetObjectCtClass, null, model, null);
ct.extendConstructor("_value = \"from constructor\";");
@@ -709,8 +907,8 @@
CtClass targetObjectCtClass = findCtClass(ReadOnlyBean.class);
- InternalClassTransformation ct = new InternalClassTransformationImpl(classFactory, targetObjectCtClass, null,
- model, null);
+ InternalClassTransformation ct = new InternalClassTransformationImpl(classFactory,
+ targetObjectCtClass, null, model, null);
ct.injectField("_value", "Tapestry");
@@ -730,7 +928,7 @@
// The PropertyAccess layer adds a wrapper exception around the real one.
assertEquals(ex.getCause().getMessage(),
- "Field org.apache.tapestry5.internal.transform.pages.ReadOnlyBean._value is read-only.");
+ "Field org.apache.tapestry5.internal.transform.pages.ReadOnlyBean._value is read-only.");
}
verify();
@@ -752,8 +950,8 @@
CtClass targetObjectCtClass = findCtClass(FieldAccessBean.class);
- InternalClassTransformation ct = new InternalClassTransformationImpl(classFactory, targetObjectCtClass, null,
- model, null);
+ InternalClassTransformation ct = new InternalClassTransformationImpl(classFactory,
+ targetObjectCtClass, null, model, null);
replaceAccessToField(ct, "foo");
replaceAccessToField(ct, "bar");
@@ -804,20 +1002,21 @@
String fieldName = "_" + baseName;
String readMethodName = "_read_" + baseName;
- TransformMethodSignature readMethodSignature = new TransformMethodSignature(Modifier.PRIVATE, STRING_CLASS_NAME,
- readMethodName, null, null);
+ TransformMethodSignature readMethodSignature = new TransformMethodSignature(
+ Modifier.PRIVATE, STRING_CLASS_NAME, readMethodName, null, null);
- ct.addMethod(readMethodSignature, String.format("throw new RuntimeException(\"read %s\");", baseName));
+ ct.addMethod(readMethodSignature, String.format("throw new RuntimeException(\"read %s\");",
+ baseName));
ct.replaceReadAccess(fieldName, readMethodName);
String writeMethodName = "_write_" + baseName;
- TransformMethodSignature writeMethodSignature = new TransformMethodSignature(Modifier.PRIVATE, "void",
- writeMethodName,
- new String[] { STRING_CLASS_NAME },
- null);
- ct.addMethod(writeMethodSignature, String.format("throw new RuntimeException(\"write %s\");", baseName));
+ TransformMethodSignature writeMethodSignature = new TransformMethodSignature(
+ Modifier.PRIVATE, "void", writeMethodName, new String[]
+ { STRING_CLASS_NAME }, null);
+ ct.addMethod(writeMethodSignature, String.format(
+ "throw new RuntimeException(\"write %s\");", baseName));
ct.replaceWriteAccess(fieldName, writeMethodName);
}
@@ -932,8 +1131,8 @@
}
catch (RuntimeException ex)
{
- assertMessageContains(ex, "Class " + VisibilityBean.class.getName() + " contains field(s)",
- "_$myPackagePrivate", "_$myProtected", "_$myPublic");
+ assertMessageContains(ex, "Class " + VisibilityBean.class.getName()
+ + " contains field(s)", "_$myPackagePrivate", "_$myProtected", "_$myPublic");
}
verify();
@@ -948,7 +1147,8 @@
ClassTransformation ct = createClassTransformation(EventHandlerTarget.class, logger);
- OnEvent annotation = ct.getMethodAnnotation(new TransformMethodSignature("handler"), OnEvent.class);
+ OnEvent annotation = ct.getMethodAnnotation(new TransformMethodSignature("handler"),
+ OnEvent.class);
// Check that the attributes of the annotation match the expectation.
@@ -974,8 +1174,9 @@
}
catch (IllegalArgumentException ex)
{
- assertEquals(ex.getMessage(),
- "Class org.apache.tapestry5.internal.transform.pages.ParentClass does not declare method 'public void foo()'.");
+ assertEquals(
+ ex.getMessage(),
+ "Class org.apache.tapestry5.internal.transform.pages.ParentClass does not declare method 'public void foo()'.");
}
verify();
@@ -985,8 +1186,8 @@
public void prefix_method() throws Exception
{
Logger logger = mockLogger();
- TransformMethodSignature sig = new TransformMethodSignature(Modifier.PUBLIC, "int", "getParentField", null,
- null);
+ TransformMethodSignature sig = new TransformMethodSignature(Modifier.PUBLIC, "int",
+ "getParentField", null, null);
replay();
@@ -1008,7 +1209,6 @@
{
}
-
verify();
}
@@ -1016,8 +1216,8 @@
public void fields_in_prefixed_methods_are_transformed() throws Exception
{
Logger logger = mockLogger();
- TransformMethodSignature sig = new TransformMethodSignature(Modifier.PUBLIC, "int", "getTargetValue", null,
- null);
+ TransformMethodSignature sig = new TransformMethodSignature(Modifier.PUBLIC, "int",
+ "getTargetValue", null, null);
Runnable runnable = mockRunnable();
runnable.run();
@@ -1030,8 +1230,8 @@
// Transform the field.
- TransformMethodSignature reader = new TransformMethodSignature(Modifier.PRIVATE, "int", "read_target_value",
- null, null);
+ TransformMethodSignature reader = new TransformMethodSignature(Modifier.PRIVATE, "int",
+ "read_target_value", null, null);
ct.addMethod(reader, "return 66;");
@@ -1051,7 +1251,7 @@
}
private Component instantiate(Class<?> expectedClass, InternalClassTransformation ct,
- InternalComponentResources resources) throws Exception
+ InternalComponentResources resources) throws Exception
{
Instantiator ins = ct.createInstantiator();
@@ -1062,8 +1262,8 @@
public void extend_existing_method_fields_are_transformed() throws Exception
{
Logger logger = mockLogger();
- TransformMethodSignature sig = new TransformMethodSignature(Modifier.PUBLIC, "int", "getTargetValue", null,
- null);
+ TransformMethodSignature sig = new TransformMethodSignature(Modifier.PUBLIC, "int",
+ "getTargetValue", null, null);
Runnable runnable = mockRunnable();
runnable.run();
@@ -1076,8 +1276,8 @@
// Transform the field.
- TransformMethodSignature reader = new TransformMethodSignature(Modifier.PRIVATE, "int", "read_target_value",
- null, null);
+ TransformMethodSignature reader = new TransformMethodSignature(Modifier.PRIVATE, "int",
+ "read_target_value", null, null);
ct.addMethod(reader, "return 66;");
@@ -1106,8 +1306,8 @@
public void invalid_code() throws Exception
{
Logger logger = mockLogger();
- TransformMethodSignature sig = new TransformMethodSignature(Modifier.PUBLIC, "int", "getParentField", null,
- null);
+ TransformMethodSignature sig = new TransformMethodSignature(Modifier.PUBLIC, "int",
+ "getParentField", null, null);
replay();
@@ -1126,7 +1326,6 @@
verify();
}
-
@Test
public void remove_field() throws Exception
{
@@ -1137,8 +1336,8 @@
CtClass targetObjectCtClass = findCtClass(FieldRemoval.class);
- InternalClassTransformation ct = new InternalClassTransformationImpl(classFactory, targetObjectCtClass, null,
- model, null);
+ InternalClassTransformation ct = new InternalClassTransformationImpl(classFactory,
+ targetObjectCtClass, null, model, null);
ct.removeField("_fieldToRemove");
@@ -1170,8 +1369,9 @@
TransformMethodSignature sig = sigs.get(0);
- assertEquals(ct.getMethodIdentifier(sig),
- "org.apache.tapestry5.internal.transform.pages.MethodIdentifier.makeWaves(java.lang.String, int[]) (at MethodIdentifier.java:24)");
+ assertEquals(
+ ct.getMethodIdentifier(sig),
+ "org.apache.tapestry5.internal.transform.pages.MethodIdentifier.makeWaves(java.lang.String, int[]) (at MethodIdentifier.java:24)");
verify();
}
@@ -1202,7 +1402,6 @@
assertFalse(ct.isMethodOverride(sig));
}
-
verify();
}
@@ -1224,8 +1423,9 @@
}
catch (IllegalArgumentException ex)
{
- assertEquals(ex.getMessage(),
- "Method public void methodDoesNotExist() is not implemented by transformed class org.apache.tapestry5.internal.services.SimpleBean.");
+ assertEquals(
+ ex.getMessage(),
+ "Method public void methodDoesNotExist() is not implemented by transformed class org.apache.tapestry5.internal.services.SimpleBean.");
}
verify();
@@ -1239,21 +1439,21 @@
replay();
- InternalClassTransformation parentTransform = createClassTransformation(SimpleBean.class, logger);
+ InternalClassTransformation parentTransform = createClassTransformation(SimpleBean.class,
+ logger);
parentTransform.finish();
CtClass childClass = findCtClass(SimpleBeanSubclass.class);
ClassTransformation childTransform = parentTransform.createChildTransformation(childClass,
- stubMutableComponentModel(
- logger));
+ stubMutableComponentModel(logger));
assertFalse(childTransform.isMethodOverride(new TransformMethodSignature("notOverridden")));
- assertTrue(childTransform.isMethodOverride(
- new TransformMethodSignature(Modifier.PUBLIC, "void", "setAge", new String[] { "int" }, null)));
+ assertTrue(childTransform.isMethodOverride(new TransformMethodSignature(Modifier.PUBLIC,
+ "void", "setAge", new String[]
+ { "int" }, null)));
}
-
}
Added: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/transform/pages/MethodAccessSubject.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/transform/pages/MethodAccessSubject.java?rev=905099&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/transform/pages/MethodAccessSubject.java (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/transform/pages/MethodAccessSubject.java Sun Jan 31 19:03:37 2010
@@ -0,0 +1,59 @@
+// Copyright 2010 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.tapestry5.internal.transform.pages;
+
+import java.sql.SQLException;
+
+import org.apache.tapestry5.internal.services.InternalClassTransformationImplTest;
+
+/**
+ * Used by {@link InternalClassTransformationImplTest} for a number of tests related to
+ * method access.
+ */
+public class MethodAccessSubject
+{
+ private String marker;
+
+ public String getMarker()
+ {
+ return marker;
+ }
+
+ public void publicVoidNoArgs()
+ {
+ marker = "publicVoidNoArgs";
+ }
+
+ public void publicVoidNoArgsFail()
+ {
+ marker = "publicVoidNoArgsFail";
+
+ throw new RuntimeException("Fail inside pvnoaf.");
+ }
+
+ public int incrementer(int input)
+ {
+ marker = "incrementer(" + input + ")";
+
+ return input + 1;
+ }
+
+ public void publicVoidThrowsException() throws SQLException
+ {
+ marker = "publicVoidThrowsException";
+
+ throw new SQLException("From publicVoidThrowsException()");
+ }
+}
Propchange: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/transform/pages/MethodAccessSubject.java
------------------------------------------------------------------------------
svn:eol-style = native