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/21 17:19:15 UTC
svn commit: r395912 [2/3] - in /tapestry/tapestry5/tapestry-core/trunk: ./
.settings/ src/ src/main/ src/main/java/ src/main/java/org/
src/main/java/org/apache/ src/main/java/org/apache/tapestry/
src/main/java/org/apache/tapestry/annotations/ src/main/...
Added: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/transform/TransformConstants.java
URL: http://svn.apache.org/viewcvs/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/transform/TransformConstants.java?rev=395912&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/transform/TransformConstants.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/transform/TransformConstants.java Fri Apr 21 08:19:11 2006
@@ -0,0 +1,40 @@
+// Copyright 2006 The Howard M. Lewis Ship
+//
+// 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.transform;
+
+import org.apache.tapestry.transform.MethodSignature;
+
+/**
+ * Constants used by various transformations.
+ *
+ * @author Howard M. Lewis Ship
+ */
+public final class TransformConstants
+{
+ /** Signature for {@link org.apache.tapestry.events.ComponentLifecycle#containingPageDidLoad()}. */
+ public static final MethodSignature CONTAINING_PAGE_DID_LOAD_SIGNATURE = new MethodSignature(
+ "containingPageDidLoad");
+
+ /**
+ * Signature for {@link org.apache.tapestry.events.ComponentLifecycle#containingPageDidDetach()}.
+ */
+ public static final MethodSignature CONTAINING_PAGE_DID_DETACH = new MethodSignature(
+ "containingPageDidDetach");
+
+ /** Prevent instantiation. */
+ private TransformConstants()
+ {
+ }
+}
Added: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/transform/TransformMessages.java
URL: http://svn.apache.org/viewcvs/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/transform/TransformMessages.java?rev=395912&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/transform/TransformMessages.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/transform/TransformMessages.java Fri Apr 21 08:19:11 2006
@@ -0,0 +1,55 @@
+// Copyright 2006 The Howard M. Lewis Ship
+//
+// 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.transform;
+
+import javassist.CtClass;
+
+import org.apache.hivemind.Messages;
+import org.apache.hivemind.impl.MessageFormatter;
+
+/**
+ * @author Howard M. Lewis Ship
+ */
+final class TransformMessages
+{
+ private static final Messages MESSAGES = new MessageFormatter(TransformMessages.class);
+
+ /** Prevent instantiation. */
+ private TransformMessages()
+ {
+ }
+
+ static String noConstructorFound(Class instanceClass)
+ {
+ return MESSAGES.format("no-constructor-found", instanceClass.getName());
+ }
+
+ static String missingDeclaredField(CtClass ctClass, String fieldName)
+ {
+ return MESSAGES.format("missing-declared-field", ctClass.getName(), fieldName);
+ }
+
+ static String errorAddingMethod(CtClass ctClass, String methodName, Throwable cause)
+ {
+ return MESSAGES.format("error-adding-method", ctClass.getName(), methodName, cause);
+ }
+
+ static String fieldAlreadyClaimed(String fieldName, CtClass ctClass, Object existingTag,
+ Object newTag)
+ {
+ return MESSAGES.format("field-already-claimed", new Object[]
+ { fieldName, ctClass.getName(), existingTag, newTag });
+ }
+}
Added: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/transform/worker/RetainWorker.java
URL: http://svn.apache.org/viewcvs/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/transform/worker/RetainWorker.java?rev=395912&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/transform/worker/RetainWorker.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/transform/worker/RetainWorker.java Fri Apr 21 08:19:11 2006
@@ -0,0 +1,48 @@
+// Copyright 2006 The Howard M. Lewis Ship
+//
+// 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.transform.worker;
+
+import java.util.List;
+
+import org.apache.tapestry.annotations.Retain;
+import org.apache.tapestry.internal.transform.ClassTransformWorker;
+import org.apache.tapestry.model.MutableComponentModel;
+import org.apache.tapestry.transform.ClassTransformation;
+
+/**
+ * Identifies fields with the {@link org.apache.tapestry.annotations.Retain} annotation, and
+ * "claims" them so that no special work will occur on them.
+ *
+ * @author Howard M. Lewis Ship
+ */
+public final class RetainWorker implements ClassTransformWorker
+{
+ /**
+ * Claims each field with the {@link org.apache.tapestry.annotations.Retain} annotation,
+ * claiming it using the annotation as the tag.
+ */
+ public void transform(ClassTransformation transformation, MutableComponentModel model)
+ {
+ List<String> fieldNames = transformation.findFieldsWithAnnotation(Retain.class);
+
+ for (String fieldName : fieldNames)
+ {
+ Retain annotation = transformation.getFieldAnnotation(fieldName, Retain.class);
+
+ transformation.claimField(fieldName, annotation);
+ }
+ }
+
+}
Added: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/transform/worker/UnclaimedFieldWorker.java
URL: http://svn.apache.org/viewcvs/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/transform/worker/UnclaimedFieldWorker.java?rev=395912&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/transform/worker/UnclaimedFieldWorker.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/transform/worker/UnclaimedFieldWorker.java Fri Apr 21 08:19:11 2006
@@ -0,0 +1,78 @@
+// Copyright 2006 The Howard M. Lewis Ship
+//
+// 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.transform.worker;
+
+import java.lang.reflect.Modifier;
+
+import org.apache.hivemind.service.BodyBuilder;
+import org.apache.tapestry.events.ComponentLifecycle;
+import org.apache.tapestry.internal.transform.ClassTransformWorker;
+import org.apache.tapestry.internal.transform.TransformConstants;
+import org.apache.tapestry.model.MutableComponentModel;
+import org.apache.tapestry.transform.ClassTransformation;
+
+/**
+ * Designed to be just about the last worker in the pipeline. Its job is to add cleanup code that
+ * restores transient fields back to their initial (null) value.
+ *
+ * @author Howard M. Lewis Ship
+ */
+public final class UnclaimedFieldWorker implements ClassTransformWorker
+{
+
+ public void transform(ClassTransformation transformation, MutableComponentModel model)
+ {
+ String[] fieldNames = transformation.findUnclaimedFields();
+
+ for (String fieldName : fieldNames)
+ {
+ transformField(fieldName, transformation);
+ }
+ }
+
+ private void transformField(String fieldName, ClassTransformation transformation)
+ {
+ String type = transformation.getFieldType(fieldName);
+
+ String defaultFieldName = transformation.newField(Modifier.PRIVATE, type, fieldName
+ + "Default");
+
+ // Add the the interface and an implementation that squirrels away the
+ // initial value of the field.
+ transformation.addImplementedInterface(ComponentLifecycle.class);
+
+ BodyBuilder builder = new BodyBuilder();
+ builder.begin();
+ builder.addln("$proceed($$);");
+ builder.addln("{0} = {1};", defaultFieldName, fieldName);
+ builder.end();
+
+ transformation.extendMethod(TransformConstants.CONTAINING_PAGE_DID_LOAD_SIGNATURE, builder
+ .toString());
+
+ // At the end of the request, we want to move the default value back over the
+ // active field value. This will most often be null.
+
+ builder.clear();
+
+ builder.begin();
+ builder.addln("$proceed($$);");
+ builder.addln("{0} = {1};", fieldName, defaultFieldName);
+ builder.end();
+
+ transformation.extendMethod(TransformConstants.CONTAINING_PAGE_DID_DETACH, builder
+ .toString());
+ }
+}
Added: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/model/ComponentModel.java
URL: http://svn.apache.org/viewcvs/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/model/ComponentModel.java?rev=395912&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/model/ComponentModel.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/model/ComponentModel.java Fri Apr 21 08:19:11 2006
@@ -0,0 +1,28 @@
+// Copyright 2006 The Howard M. Lewis Ship
+//
+// 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.model;
+
+/**
+ * Defines a component in terms of its capabilities, parameters, sub-components, etc. During
+ * <em>runtime</em>, the component model is immutable. During <em>construction</em> time, when
+ * the class is being transformed a loaded, the model is mutable.
+ *
+ * @author Howard M. Lewis Ship
+ * @see
+ */
+public interface ComponentModel
+{
+
+}
Added: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/model/MutableComponentModel.java
URL: http://svn.apache.org/viewcvs/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/model/MutableComponentModel.java?rev=395912&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/model/MutableComponentModel.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/model/MutableComponentModel.java Fri Apr 21 08:19:11 2006
@@ -0,0 +1,26 @@
+// Copyright 2006 The Howard M. Lewis Ship
+//
+// 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.model;
+
+/**
+ * Mutable version of {@link org.apache.tapestry.model.ComponentModel} used during the
+ * transformation phase.
+ *
+ * @author Howard M. Lewis Ship
+ */
+public interface MutableComponentModel extends ComponentModel
+{
+
+}
Added: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/test/BaseTestCase.java
URL: http://svn.apache.org/viewcvs/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/test/BaseTestCase.java?rev=395912&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/test/BaseTestCase.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/test/BaseTestCase.java Fri Apr 21 08:19:11 2006
@@ -0,0 +1,58 @@
+// Copyright 2006 The Howard M. Lewis Ship
+//
+// 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.test;
+
+import java.lang.annotation.Annotation;
+import java.util.List;
+
+import org.apache.tapestry.annotations.Retain;
+import org.apache.tapestry.model.MutableComponentModel;
+import org.apache.tapestry.transform.ClassTransformation;
+
+/**
+ * Base test case that adds a number of convienience factory and training methods to
+ * {@link org.apache.tapestry.test.TestBase}.
+ *
+ * @author Howard M. Lewis Ship
+ */
+public abstract class BaseTestCase extends TestBase
+{
+
+ protected final void trainFindFieldsWithAnnotation(ClassTransformation transformation,
+ Class<? extends Annotation> annotationClass, List<String> fieldNames)
+ {
+ transformation.findFieldsWithAnnotation(annotationClass);
+ setReturnValue(fieldNames);
+ }
+
+ protected final <T extends Annotation> void trainGetFieldAnnotation(
+ ClassTransformation transformation, String fieldName,
+ Class<? extends Annotation> annotationClass, T annotation)
+ {
+ transformation.getFieldAnnotation(fieldName, annotationClass);
+ setReturnValue(annotation);
+ }
+
+ protected final MutableComponentModel newMutableComponentModel()
+ {
+ return newMock(MutableComponentModel.class);
+ }
+
+ protected final ClassTransformation newClassTransformation()
+ {
+ return newMock(ClassTransformation.class);
+ }
+
+}
Added: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/test/TestBase.java
URL: http://svn.apache.org/viewcvs/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/test/TestBase.java?rev=395912&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/test/TestBase.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/test/TestBase.java Fri Apr 21 08:19:11 2006
@@ -0,0 +1,111 @@
+// Copyright 2006 The Howard M. Lewis Ship
+//
+// 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.test;
+
+import org.easymock.EasyMock;
+import org.easymock.IMocksControl;
+import org.testng.annotations.Configuration;
+
+import static org.easymock.EasyMock.expectLastCall;
+import static org.testng.Assert.fail;
+
+/**
+ * Manages a set of EasyMock mock objects. Used as a base class for test cases.
+ *
+ * @author Howard M. Lewis Ship
+ */
+public class TestBase
+{
+ private IMocksControl _control;
+
+ /**
+ * Discards any mock objects created during the test.
+ */
+ @Configuration(afterTestMethod = true, alwaysRun = true)
+ protected final void tearDown()
+ {
+ // TestNG reuses the same class instance across all tests methods within that class, so if
+ // we don't clear out the mocks, they will tend to accumulate (which isn't the end of the
+ // world, but it's nice to save unneccessary cycles even inside a test case).
+ _control = null;
+ }
+
+ /**
+ * Creates a new mock object of the indicated type. Creates a <em>strict</em> mock, which
+ * enforces an exact order of method invocation.
+ *
+ * @param <T>
+ * the type of the mock object
+ * @param mockClass
+ * the class to mock
+ * @return the mock object, ready for training
+ */
+ protected final <T> T newMock(Class<T> mockClass)
+ {
+ if (_control == null)
+ _control = EasyMock.createStrictControl();
+
+ return _control.createMock(mockClass);
+ }
+
+ /**
+ * Replay's each mock object created by {@link #newMock(Class)}. .
+ */
+ protected final void replay()
+ {
+ _control.replay();
+ }
+
+ /**
+ * Verifies each created mock object, then resets the mock for additional training.
+ */
+ protected final void verify()
+ {
+ _control.verify();
+ _control.reset();
+ }
+
+ /**
+ * Sets the return value for the most recent method call upon the mock.
+ *
+ * @param returnValue
+ * value to be returned from the method call
+ */
+ protected final void setReturnValue(Object returnValue)
+ {
+ expectLastCall().andReturn(returnValue);
+ }
+
+ /**
+ * Trains a mock object to throw an exception (for the most recent method call).
+ *
+ * @param throwable
+ * the exception to be thrown by the most recent method call on the mock
+ */
+ protected final void setThrowable(Throwable throwable)
+ {
+ expectLastCall().andThrow(throwable);
+ }
+
+ /**
+ * unreachable().
+ */
+
+ protected final void unreachable()
+ {
+ fail("This code should not be reachable.");
+ }
+
+}
Added: 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=395912&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/transform/ClassTransformation.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/transform/ClassTransformation.java Fri Apr 21 08:19:11 2006
@@ -0,0 +1,161 @@
+// Copyright 2006 The Howard M. Lewis Ship
+//
+// 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.transform;
+
+import java.lang.annotation.Annotation;
+import java.util.List;
+
+/**
+ * Contains class-specific information used when transforming an raw class into an executable class.
+ * Much of this information is somewhat like ordinary reflection, but applies to a class that has
+ * not yet been loaded.
+ * <p>
+ * Transformation is primarily about identifying annotations on fields and on methods and changing
+ * the class, adding new interfaces, fields and methods, and deleting some existing fields.
+ * <p>
+ * A ClassTransformation contains all the state data specific to a particular class being
+ * 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>
+ * 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.
+ *
+ * @author Howard M. Lewis Ship
+ */
+public interface ClassTransformation
+{
+
+ /**
+ * Returns the name of a new member (field or method). Ensures that the resulting name does not
+ * conflict with any existing member (declared by the underlying class, or inherited from a base
+ * class).
+ * <p>
+ * TODO: This method may be removed (see {@link #newField(int, String, String)})
+ *
+ * @param suggested
+ * the suggested value for the member
+ * @return a unique name for the member
+ */
+ String newMemberName(String suggested);
+
+ /**
+ * Generates a list of the names of declared instance fields that have the indicated annotation.
+ */
+ List<String> findFieldsWithAnnotation(Class<? extends Annotation> annotationClass);
+
+ /**
+ * Finds an annotation for the class itself. TODO: Deal with the fact that Javassist does not
+ * handled Inherited annotations properly.
+ *
+ * @param <T>
+ * @param annotationClass
+ * the type of annotation to access
+ * @return the annotation if present, or null otherwise
+ */
+ <T extends Annotation> T getAnnotation(Class<T> annotationClass);
+
+ /**
+ * Finds an annotation on a declared instance field.
+ *
+ * @param <T>
+ * constrains parameter and return value to Annotation types
+ * @param fieldName
+ * the name of the field, which must exist
+ * @param annotationClass
+ * the type of annotation to access
+ * @return the annotation if present, or null otherwise
+ * @throws IllegalArgumentException
+ * if the fieldName does not correspond to a declared field
+ */
+ <T extends Annotation> T getFieldAnnotation(String fieldName, Class<T> annotationClass);
+
+ /**
+ * Claims a field so as to ensure that only a single annotation is applied to any single field.
+ * When a transformation occurs (driven by a field annotation), the first thing that occurs is
+ * to claim the field, on behalf of the annotation.
+ *
+ * @param fieldName
+ * the name of the field that is being claimed
+ * @param tag
+ * a non-null object that represents why the field is being tagged (this is typically
+ * a specific annotation on the field)
+ * @throws IllegalArgumentException
+ * if the fieldName does not correspond to a declared instance field
+ * @throws IllegalStateException
+ * if the field is already claimed for some other tag
+ */
+ void claimField(String fieldName, Object tag);
+
+ /**
+ * Finds any declared <em>instance</em> fields that have not been claimed (via
+ * {@link #claimField(String, Object)}) and returns the names of those fields. May return an
+ * empty array.
+ */
+ String[] findUnclaimedFields();
+
+ /**
+ * Obtains the type of a declared instance field.
+ *
+ * @param fieldName
+ * @return the type of the field, as a string
+ * @throws IllegalArgumentException
+ * if the fieldName does not correspond to a declared instance field
+ */
+ String getFieldType(String fieldName);
+
+ /**
+ * Defines a new declared field for the class. The suggestedName may be modified to ensure
+ * uniqueness.
+ *
+ * @param modifiers
+ * modifiers for the field (typically, {@link java.lang.reflect.Modifier#PRIVATE})
+ * @param type
+ * the type for the field, as a string
+ * @param suggestedName
+ * the desired name for the field, which may be modified (for uniqueness) when
+ * returned
+ * @return the (uniqued) name for the field
+ */
+ String newField(int modifiers, String type, String suggestedName);
+
+ /**
+ * Transforms the class to implement the indicated interface. If the class (or its super class)
+ * does not already implement the interface, then the interface is added, and default
+ * implementations of any methods of the interface are added.
+ * <p>
+ * TODO: Checking that the names of methods in the interface do not conflict with the names of
+ * methods present in the (unmodified) class.
+ *
+ * @param interfaceClass
+ * the interface to be implemented by the class
+ * @throws IllegalArgumentException
+ * if the interfaceClass argument does not represent an interface
+ */
+ void addImplementedInterface(Class interfaceClass);
+
+ /**
+ * Extends an existing method. The body of the method is replaced with the provided body.
+ * However, a call to the Javassist pseudo-method $proceed() is required.
+ *
+ * @param signature
+ * the signature of the method to extend
+ * @param methodBody
+ * the body of code
+ * @throws IllegalArgumentException
+ * if the method body does not include a call to $proceed, or if the provided
+ * Javassist method body can not be compiled
+ */
+ void extendMethod(MethodSignature methodSignature, String methodBody);
+}
Added: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/transform/MethodSignature.java
URL: http://svn.apache.org/viewcvs/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/transform/MethodSignature.java?rev=395912&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/transform/MethodSignature.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/transform/MethodSignature.java Fri Apr 21 08:19:11 2006
@@ -0,0 +1,192 @@
+// Copyright 2006 The Howard M. Lewis Ship
+//
+// 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.transform;
+
+import static org.apache.tapestry.util.Defense.notBlank;
+import static org.apache.tapestry.util.Defense.notNull;
+
+import java.lang.reflect.Modifier;
+
+/**
+ * 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 MethodSignature is often used in
+ * situations where the actual class has not been loaded yet.
+ *
+ * @author Howard M. Lewis Ship
+ */
+public class MethodSignature
+{
+
+ private int _hashCode = -1;
+
+ private final int _modifiers;
+
+ private final String _returnType;
+
+ private final String _methodName;
+
+ private final String[] _parameterTypes;
+
+ private final String[] _exceptionTypes;
+
+ private static final String[] EMPTY_STRINGS = new String[0];
+
+ /** Convienience for adding a public void method with no parameters or exception types. */
+
+ public MethodSignature(String name)
+ {
+ this(Modifier.PUBLIC, "void", name, EMPTY_STRINGS, EMPTY_STRINGS);
+ }
+
+ public MethodSignature(int modifiers, String type, String name, String[] parameterTypes,
+ String[] exceptionTypes)
+ {
+ _modifiers = modifiers;
+
+ _returnType = notBlank(type, "type");
+ _methodName = notBlank(name, "name");
+
+ // TODO: Checks that no element within the two arrays
+ // is null or blank.
+
+ _parameterTypes = notNull(parameterTypes, "parameterTypes");
+ _exceptionTypes = notNull(exceptionTypes, "exceptionTypes");
+ }
+
+ /**
+ * Returns a non-null array of the names of each declared exception type thrown by the method.
+ * Calling code should not modify the array.
+ */
+ public String[] getExceptionTypes()
+ {
+ return _exceptionTypes;
+ }
+
+ /** Returns the name of the method. */
+ public String getMethodName()
+ {
+ return _methodName;
+ }
+
+ /**
+ * Returns the set of modifier flags for this method.
+ *
+ * @see java.lang.reflect.Modifier
+ */
+ public int getModifiers()
+ {
+ return _modifiers;
+ }
+
+ /**
+ * Returns an array of the type name for each parameter. Calling code should not modify the
+ * array.
+ */
+ public String[] getParameterTypes()
+ {
+ return _parameterTypes;
+ }
+
+ /** Return the type name of the return type of the method. */
+ public String getReturnType()
+ {
+ return _returnType;
+ }
+
+ public int hashCode()
+ {
+ if (_hashCode == -1)
+ {
+ _hashCode = 17 * _modifiers;
+ _hashCode += 31 * _returnType.hashCode();
+ _hashCode += 31 * _methodName.hashCode();
+
+ for (String parameterType : _parameterTypes)
+ {
+ _hashCode += 31 * parameterType.hashCode();
+ }
+
+ for (String exceptionType : _exceptionTypes)
+ {
+ _hashCode += 31 * exceptionType.hashCode();
+ }
+ }
+
+ return _hashCode;
+ }
+
+ public boolean equals(Object other)
+ {
+ if (other == null || !(other instanceof MethodSignature))
+ return false;
+
+ MethodSignature ms = (MethodSignature) other;
+
+ return _modifiers == ms._modifiers && _returnType.equals(ms._returnType)
+ && _methodName.equals(ms._methodName)
+ && matches(_parameterTypes, ms._parameterTypes)
+ && matches(_exceptionTypes, ms._exceptionTypes);
+ }
+
+ private boolean matches(String[] values, String[] otherValues)
+ {
+ if (values.length != otherValues.length)
+ return false;
+
+ for (int i = 0; i < values.length; i++)
+ {
+ if (!values[i].equals(otherValues[i]))
+ return false;
+ }
+
+ return true;
+ }
+
+ public String toString()
+ {
+ StringBuilder builder = new StringBuilder();
+
+ builder.append(Modifier.toString(_modifiers));
+ builder.append(' ');
+ builder.append(_returnType);
+ builder.append(' ');
+ builder.append(_methodName);
+ builder.append('(');
+
+ for (int i = 0; i < _parameterTypes.length; i++)
+ {
+ if (i > 0)
+ builder.append(", ");
+
+ builder.append(_parameterTypes[i]);
+ }
+
+ builder.append(')');
+
+ for (int i = 0; i < _exceptionTypes.length; i++)
+ {
+ if (i == 0)
+ builder.append(" throws ");
+ else
+ builder.append(", ");
+
+ builder.append(_exceptionTypes[i]);
+ }
+
+ return builder.toString();
+ }
+}
Added: 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=395912&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/util/CollectionFactory.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/util/CollectionFactory.java Fri Apr 21 08:19:11 2006
@@ -0,0 +1,83 @@
+// Copyright 2006 The Howard M. Lewis Ship
+//
+// 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.util;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * 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
+ * usage:
+ *
+ * <pre>
+ * Map<Foo, Bar> map = newMap();
+ * </pre>
+ *
+ * <p>
+ * This is a replacement for:
+ *
+ * <pre>
+ * Map<Foo, Bar> map = new HashMap<Foo, Bar>();
+ * </pre>
+ *
+ * @author Howard M. Lewis Ship
+ */
+public final class CollectionFactory
+{
+
+ /** Prevent instantiation. */
+ private CollectionFactory()
+ {
+ }
+
+ /** Constructs and returns a generic {@link HashMap} instance. */
+ public static <K, V> Map<K, V> newMap()
+ {
+ return new HashMap<K, V>();
+ }
+
+ /** Constructs and returns a generic {@link java.util.HashSet} instance. */
+ public static <T> Set<T> newSet()
+ {
+ return new HashSet<T>();
+ }
+
+ /**
+ * Constructs a new {@link java.util.HashMap} instance from an existing Map instance.
+ */
+
+ public static <K, V> Map<K, V> copyMap(Map<K, V> map)
+ {
+ return new HashMap<K, V>(map);
+ }
+
+ /** Contructs and returns a new generic {@link java.util.ArrayList} instance. */
+ public static <T> List<T> newList()
+ {
+ return new ArrayList<T>();
+ }
+
+ /** Easy way to convert a list of like-typed values into a list. */
+ public static <T> List<T> newList(T... values)
+ {
+ return Arrays.asList(values);
+ }
+}
Added: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/util/Defense.java
URL: http://svn.apache.org/viewcvs/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/util/Defense.java?rev=395912&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/util/Defense.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/util/Defense.java Fri Apr 21 08:19:11 2006
@@ -0,0 +1,72 @@
+// Copyright 2006 The Howard M. Lewis Ship
+//
+// 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.util;
+
+/**
+ * Static utility methods for defensive programming.
+ *
+ * @author Howard M. Lewis Ship
+ */
+public final class Defense
+{
+
+ /**
+ * Checks that a method parameter value is not null, and returns it.
+ *
+ * @param <T>
+ * the value type
+ * @param value
+ * the value (which is checked to ensure non-nullness)
+ * @param parameterName
+ * the name of the parameter, used for exception messages
+ * @return the value
+ * @throws NullPointerException
+ * if the value is null
+ */
+ public static <T> T notNull(T value, String parameterName)
+ {
+ if (value == null) throw new NullPointerException(UtilMessages.parameterWasNull(parameterName));
+
+ return value;
+ }
+
+ /** Prevent instantiation. */
+ private Defense()
+ {
+ }
+
+ /**
+ * Checks that a parameter value is not null and not empty.
+ *
+ * @param value
+ * value to check (which is returned)
+ * @param parameterName
+ * the name of the parameter, used for exception messages
+ * @return the value, trimmed, if non-blank
+ * @throws IllegalArgumentException
+ * if the value is null or empty
+ */
+ public static String notBlank(String value, String parameterName)
+ {
+ if (value != null)
+ {
+ String trimmedValue = value.trim();
+
+ if (!trimmedValue.equals("")) return trimmedValue;
+ }
+
+ throw new IllegalArgumentException(UtilMessages.parameterWasBlank(parameterName));
+ }
+}
Added: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/util/IdAllocator.java
URL: http://svn.apache.org/viewcvs/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/util/IdAllocator.java?rev=395912&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/util/IdAllocator.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/util/IdAllocator.java Fri Apr 21 08:19:11 2006
@@ -0,0 +1,160 @@
+// Copyright 2004, 2005, 2006 The Howard M. Lewis Ship
+//
+// 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.util;
+
+import static org.apache.tapestry.util.CollectionFactory.newMap;
+import static org.apache.tapestry.util.Defense.notNull;
+
+import java.util.HashMap;
+import java.util.IdentityHashMap;
+import java.util.Map;
+
+/**
+ * Used to "uniquify" names within a given context. A base name is passed in, and the return value
+ * is the base name, or the base name extended with a suffix to make it unique.
+ *
+ * @author Howard Lewis Ship
+ * @since 3.0
+ */
+
+public final class IdAllocator
+{
+ private static final String SEPARATOR = "_";
+
+ private final Map<String, NameGenerator> _generatorMap;
+
+ private final String _namespace;
+
+ /** Generates unique names with a particular prefix. */
+ private static class NameGenerator implements Cloneable
+ {
+ private final String _baseId;
+
+ private int _index;
+
+ NameGenerator(String baseId)
+ {
+ _baseId = baseId + SEPARATOR;
+ }
+
+ public String nextId()
+ {
+ return _baseId + _index++;
+ }
+
+ /** Clones this instance, returning an equivalent but seperate copy. */
+ public NameGenerator clone()
+ {
+ try
+ {
+ return (NameGenerator) super.clone();
+ }
+ catch (CloneNotSupportedException ex)
+ {
+ // Unreachable!
+ throw new RuntimeException(ex);
+ }
+ }
+ }
+
+ /** Creates a new allocator with no namespace. */
+ public IdAllocator()
+ {
+ this("");
+ }
+
+ /** Creates a new allocator with the provided namespace. */
+ public IdAllocator(String namespace)
+ {
+ this(namespace, new HashMap<String, NameGenerator>());
+ }
+
+ private IdAllocator(String namespace, Map<String, NameGenerator> generatorMap)
+ {
+ _namespace = notNull(namespace, "namespace");
+ _generatorMap = generatorMap;
+ }
+
+ /**
+ * Creates a clone of this IdAllocator instance, copying the allocator's namespace and key map.
+ */
+ public IdAllocator clone()
+ {
+ // Copying the _generatorMap is tricky; multiple keys will point to the same NameGenerator
+ // instance.
+ // We need to clone the NameGenerators, then buld a new map around the clones.
+
+ IdentityHashMap<NameGenerator, NameGenerator> transformMap = new IdentityHashMap<NameGenerator, NameGenerator>();
+
+ for (NameGenerator original : _generatorMap.values())
+ {
+ NameGenerator copy = original.clone();
+
+ transformMap.put(original, copy);
+ }
+
+ Map<String, NameGenerator> mapCopy = newMap();
+
+ for (String key : _generatorMap.keySet())
+ {
+ NameGenerator original = _generatorMap.get(key);
+ NameGenerator copy = transformMap.get(original);
+
+ mapCopy.put(key, copy);
+ }
+
+ return new IdAllocator(_namespace, mapCopy);
+ }
+
+ /**
+ * Allocates the id. Repeated calls for the same name will return "name", "name_0", "name_1",
+ * etc.
+ */
+
+ public String allocateId(String name)
+ {
+ String key = name + _namespace;
+
+ NameGenerator g = _generatorMap.get(key);
+ String result = null;
+
+ if (g == null)
+ {
+ g = new NameGenerator(key);
+ result = key;
+ }
+ else
+ result = g.nextId();
+
+ // Handle the degenerate case, where a base name of the form "foo_0" has been
+ // requested. Skip over any duplicates thus formed.
+
+ while (_generatorMap.containsKey(result))
+ result = g.nextId();
+
+ _generatorMap.put(result, g);
+
+ return result;
+ }
+
+ /**
+ * Clears the allocator, resetting it to freshly allocated state.
+ */
+
+ public void clear()
+ {
+ _generatorMap.clear();
+ }
+}
\ No newline at end of file
Added: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/util/UtilMessages.java
URL: http://svn.apache.org/viewcvs/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/util/UtilMessages.java?rev=395912&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/util/UtilMessages.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/util/UtilMessages.java Fri Apr 21 08:19:11 2006
@@ -0,0 +1,44 @@
+// Copyright 2006 The Howard M. Lewis Ship
+//
+// 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.util;
+
+import org.apache.hivemind.Messages;
+import org.apache.hivemind.impl.MessageFormatter;
+
+/**
+ * Static messages
+ *
+ * @author Howard M. Lewis Ship
+ */
+final class UtilMessages
+{
+
+ private static final Messages MESSAGES = new MessageFormatter(UtilMessages.class);
+
+ /** Prevent instantiaton. */
+ private UtilMessages()
+ {
+ }
+
+ static String parameterWasNull(String parameterName)
+ {
+ return MESSAGES.format("parameter-was-null", parameterName);
+ }
+
+ static String parameterWasBlank(String parameterName)
+ {
+ return MESSAGES.format("parameter-was-blank", parameterName);
+ }
+}
Added: tapestry/tapestry5/tapestry-core/trunk/src/main/resources/org/apache/tapestry/internal/transform/TransformStrings.properties
URL: http://svn.apache.org/viewcvs/tapestry/tapestry5/tapestry-core/trunk/src/main/resources/org/apache/tapestry/internal/transform/TransformStrings.properties?rev=395912&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/resources/org/apache/tapestry/internal/transform/TransformStrings.properties (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/resources/org/apache/tapestry/internal/transform/TransformStrings.properties Fri Apr 21 08:19:11 2006
@@ -0,0 +1,18 @@
+# Copyright 2006 The Howard M. Lewis Ship
+#
+# 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.
+
+no-constructor-found=Unable to find an applicable constructor for class {0}.
+missing-declared-field=Class {0} does not contain a field named ''{1}''.
+error-adding-method=Error adding method {1} to class {0}: {2}
+field-already-claimed=Field {0} of class {1} is already claimed by {2} and can not be claimed by {3}.
\ No newline at end of file
Added: tapestry/tapestry5/tapestry-core/trunk/src/main/resources/org/apache/tapestry/util/UtilStrings.properties
URL: http://svn.apache.org/viewcvs/tapestry/tapestry5/tapestry-core/trunk/src/main/resources/org/apache/tapestry/util/UtilStrings.properties?rev=395912&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/resources/org/apache/tapestry/util/UtilStrings.properties (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/resources/org/apache/tapestry/util/UtilStrings.properties Fri Apr 21 08:19:11 2006
@@ -0,0 +1,16 @@
+# Copyright 2006 The Howard M. Lewis Ship
+#
+# 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.
+
+parameter-was-null=Parameter {0} was null.
+parameter-was-blank=Parameter {0} was null or contained only whitespace.
\ No newline at end of file
Added: tapestry/tapestry5/tapestry-core/trunk/src/test/conf/testng.xml
URL: http://svn.apache.org/viewcvs/tapestry/tapestry5/tapestry-core/trunk/src/test/conf/testng.xml?rev=395912&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/conf/testng.xml (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/conf/testng.xml Fri Apr 21 08:19:11 2006
@@ -0,0 +1,27 @@
+<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
+<!--
+ Copyright 2006 The Howard M. Lewis Ship
+
+ 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.
+-->
+
+<suite name="Tapestry 5">
+ <test verbose="2" name="General" annotations="1.5">
+ <packages>
+ <package name="org.apache.tapestry.transform"/>
+ <package name="org.apache.tapestry.internal.transform"/>
+ <package name="org.apache.tapestry.internal.transform.worker"/>
+ <package name="org.apache.tapestry.util"/>
+ </packages>
+ </test>
+</suite>
Added: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/transform/BarInterface.java
URL: http://svn.apache.org/viewcvs/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/transform/BarInterface.java?rev=395912&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/transform/BarInterface.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/transform/BarInterface.java Fri Apr 21 08:19:11 2006
@@ -0,0 +1,20 @@
+// Copyright 2006 The Howard M. Lewis Ship
+//
+// 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.transform;
+
+public interface BarInterface
+{
+ void bar();
+}
Added: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/transform/ComponentInstantiatorSourceImplTest.java
URL: http://svn.apache.org/viewcvs/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/transform/ComponentInstantiatorSourceImplTest.java?rev=395912&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/transform/ComponentInstantiatorSourceImplTest.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/transform/ComponentInstantiatorSourceImplTest.java Fri Apr 21 08:19:11 2006
@@ -0,0 +1,64 @@
+// Copyright 2006 The Howard M. Lewis Ship
+//
+// 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.transform;
+
+import static java.lang.Thread.currentThread;
+import static org.testng.Assert.assertEquals;
+
+import org.apache.commons.logging.Log;
+import org.apache.tapestry.internal.transform.ComponentInstantiatorSourceImpl;
+import org.apache.tapestry.test.TestBase;
+import org.testng.annotations.Test;
+
+/**
+ * Tests for {@link org.apache.tapestry.internal.transform.ComponentInstantiatorSourceImpl}.
+ *
+ * @author Howard M. Lewis Ship
+ */
+public class ComponentInstantiatorSourceImplTest extends TestBase
+{
+ private final ClassLoader _defaultClassLoader = currentThread().getContextClassLoader();
+
+ protected final Log newLog()
+ {
+ return newMock(Log.class);
+ }
+
+ @Test
+ public void controlledPackagesTest() throws Exception
+ {
+ ComponentInstantiatorSourceImpl e = new ComponentInstantiatorSourceImpl(_defaultClassLoader);
+
+ assertEquals(e.inControlledPackage("foo.bar.Baz"), false);
+
+ // Check that classes in the default package are never controlled
+
+ assertEquals(e.inControlledPackage("Biff"), false);
+
+ // Now add a controlled package
+
+ e.addPackage("foo.bar");
+
+ assertEquals(e.inControlledPackage("foo.bar.Baz"), true);
+
+ // Sub-packages of controlled packages are controlled as well
+
+ assertEquals(e.inControlledPackage("foo.bar.biff.Pop"), true);
+
+ // Parents of controlled packages are not controlled
+
+ assertEquals(e.inControlledPackage("foo.Gloop"), false);
+ }
+}
Added: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/transform/FooBarInterface.java
URL: http://svn.apache.org/viewcvs/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/transform/FooBarInterface.java?rev=395912&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/transform/FooBarInterface.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/transform/FooBarInterface.java Fri Apr 21 08:19:11 2006
@@ -0,0 +1,20 @@
+// Copyright 2006 The Howard M. Lewis Ship
+//
+// 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.transform;
+
+public interface FooBarInterface extends FooInterface, BarInterface
+{
+
+}
Added: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/transform/FooInterface.java
URL: http://svn.apache.org/viewcvs/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/transform/FooInterface.java?rev=395912&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/transform/FooInterface.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/transform/FooInterface.java Fri Apr 21 08:19:11 2006
@@ -0,0 +1,23 @@
+// Copyright 2006 The Howard M. Lewis Ship
+//
+// 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.transform;
+
+/**
+ * @author Howard M. Lewis Ship
+ */
+public interface FooInterface
+{
+ void foo();
+}
Added: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/transform/GetterMethodsInterface.java
URL: http://svn.apache.org/viewcvs/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/transform/GetterMethodsInterface.java?rev=395912&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/transform/GetterMethodsInterface.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/transform/GetterMethodsInterface.java Fri Apr 21 08:19:11 2006
@@ -0,0 +1,41 @@
+// Copyright 2006 The Howard M. Lewis Ship
+//
+// 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.transform;
+
+/**
+ * @author Howard M. Lewis Ship
+ */
+public interface GetterMethodsInterface
+{
+ boolean getBoolean();
+
+ byte getByte();
+
+ short getShort();
+
+ int getInt();
+
+ long getLong();
+
+ float getFloat();
+
+ double getDouble();
+
+ String getString();
+
+ int[] getIntArray();
+
+ Object[] getObjectArray();
+}
Added: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/transform/InternalClassTransformationImplTest.java
URL: http://svn.apache.org/viewcvs/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/transform/InternalClassTransformationImplTest.java?rev=395912&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/transform/InternalClassTransformationImplTest.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/transform/InternalClassTransformationImplTest.java Fri Apr 21 08:19:11 2006
@@ -0,0 +1,357 @@
+// Copyright 2006 The Howard M. Lewis Ship
+//
+// 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.transform;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Target;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.Arrays;
+import java.util.List;
+
+import javassist.ClassPool;
+import javassist.CtClass;
+import javassist.CtMethod;
+import javassist.Loader;
+import javassist.NotFoundException;
+
+import org.apache.tapestry.annotations.ComponentClass;
+import org.apache.tapestry.annotations.Retain;
+import org.apache.tapestry.internal.transform.pages.AbstractFoo;
+import org.apache.tapestry.internal.transform.pages.BarImpl;
+import org.apache.tapestry.internal.transform.pages.ChildClassInheritsAnnotation;
+import org.apache.tapestry.internal.transform.pages.ClaimedFields;
+import org.apache.tapestry.internal.transform.pages.ParentClass;
+import org.apache.tapestry.internal.transform.pages.TargetObject;
+import org.apache.tapestry.test.TestBase;
+import org.apache.tapestry.transform.ClassTransformation;
+import org.testng.annotations.Configuration;
+import org.testng.annotations.Test;
+
+import static java.lang.Thread.currentThread;
+import static org.apache.tapestry.util.CollectionFactory.newList;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertNull;
+import static org.testng.Assert.assertTrue;
+
+/**
+ * @author Howard M. Lewis Ship
+ */
+public class InternalClassTransformationImplTest extends TestBase
+{
+ private ClassPool _classPool;
+
+ private final ClassLoader _contextClassLoader = currentThread().getContextClassLoader();
+
+ /**
+ * We need a new ClassPool for each individual test, since many of the tests will end up
+ * modifying one or more CtClass instances.
+ */
+ @Configuration(beforeTestMethod = true)
+ public void setupClassPool()
+ {
+ _classPool = new ClassPool();
+ _classPool.appendSystemPath();
+ }
+
+ private CtClass findCtClass(Class targetClass) throws NotFoundException
+ {
+ return _classPool.get(targetClass.getName());
+ }
+
+ @Test
+ public void newMemberNameTest() throws Exception
+ {
+ ClassTransformation ct = createClassTransformation(ParentClass.class);
+
+ assertEquals(ct.newMemberName("fred"), "_$fred");
+ assertEquals(ct.newMemberName("fred"), "_$fred_0");
+
+ // Here we're exposing a bit of the internal algorithm, which strips
+ // of '$' and '_' before tacking "_$" in front.
+
+ assertEquals(ct.newMemberName("_fred"), "_$fred_1");
+ assertEquals(ct.newMemberName("_$fred"), "_$fred_2");
+ assertEquals(ct.newMemberName("__$___$____$_fred"), "_$fred_3");
+
+ // Here we're trying to force conflicts with existing declared
+ // fields and methods of the class.
+
+ assertEquals(ct.newMemberName("_parentField"), "_$parentField");
+ assertEquals(ct.newMemberName("conflictField"), "_$conflictField_0");
+ assertEquals(ct.newMemberName("conflictMethod"), "_$conflictMethod_0");
+ }
+
+ private ClassTransformation createClassTransformation(Class targetClass)
+ throws NotFoundException
+ {
+ CtClass ctClass = findCtClass(targetClass);
+ return new InternalClassTransformationImpl(ctClass);
+ }
+
+ @Test
+ public void findAnnotationOnUnknownField() throws Exception
+ {
+ ClassTransformation ct = createClassTransformation(ParentClass.class);
+
+ try
+ {
+ ct.getFieldAnnotation("unknownField", Retain.class);
+ unreachable();
+ }
+ catch (RuntimeException ex)
+ {
+ assertEquals(
+ ex.getMessage(),
+ "Class org.apache.tapestry.internal.transform.pages.ParentClass does not contain a field named 'unknownField'.");
+ }
+ }
+
+ @Test
+ public void findFieldAnnotation() throws Exception
+ {
+ ClassTransformation ct = createClassTransformation(ParentClass.class);
+
+ Retain retain = ct.getFieldAnnotation("_annotatedField", Retain.class);
+
+ assertNotNull(retain);
+ }
+
+ @Test
+ public void findMissingFieldAnnotation() throws Exception
+ {
+ ClassTransformation ct = createClassTransformation(ParentClass.class);
+
+ // Field with annotations, but not that annotation
+ assertNull(ct.getFieldAnnotation("_annotatedField", Override.class));
+
+ // Field with no annotations
+ assertNull(ct.getFieldAnnotation("_parentField", Override.class));
+ }
+
+ @Test
+ public void fieldsWithAnnotation() throws Exception
+ {
+ ClassTransformation ct = createClassTransformation(ParentClass.class);
+
+ List<String> fields = ct.findFieldsWithAnnotation(Retain.class);
+
+ assertEquals(fields.size(), 1);
+ assertEquals(fields.get(0), "_annotatedField");
+ }
+
+ @Test
+ public void noFieldsWithAnnotation() throws Exception
+ {
+ ClassTransformation ct = createClassTransformation(ParentClass.class);
+
+ List<String> fields = ct.findFieldsWithAnnotation(Documented.class);
+
+ assertTrue(fields.isEmpty());
+ }
+
+ @Test
+ public void claimFields() throws Exception
+ {
+ ClassTransformation ct = createClassTransformation(ClaimedFields.class);
+
+ String[] unclaimed = ct.findUnclaimedFields();
+
+ assertEquals(Arrays.asList(unclaimed), newList("_field1", "_field4", "_zzfield"));
+
+ ct.claimField("_field4", "Fred");
+
+ unclaimed = ct.findUnclaimedFields();
+
+ assertEquals(Arrays.asList(unclaimed), newList("_field1", "_zzfield"));
+
+ try
+ {
+ ct.claimField("_field4", "Barney");
+ unreachable();
+ }
+ catch (RuntimeException ex)
+ {
+ assertEquals(
+ ex.getMessage(),
+ "Field _field4 of class org.apache.tapestry.internal.transform.pages.ClaimedFields is already claimed by Fred and can not be claimed by Barney.");
+ }
+
+ }
+
+ @Test
+ public void claimFieldsOmitsAddedFields() throws Exception
+ {
+ ClassTransformation ct = createClassTransformation(ClaimedFields.class);
+
+ ct.newField(Modifier.PRIVATE, "int", "newField");
+
+ String[] unclaimed = ct.findUnclaimedFields();
+
+ assertEquals(Arrays.asList(unclaimed), newList("_field1", "_field4", "_zzfield"));
+ }
+
+ @Test
+ public void findAnnotationsOnClass() throws Exception
+ {
+ ClassTransformation ct = createClassTransformation(ParentClass.class);
+
+ ComponentClass cc = ct.getAnnotation(ComponentClass.class);
+
+ assertNotNull(cc);
+
+ // Try again (the annotations will be cached). Use an annotation
+ // that will not be present.
+
+ Target t = ct.getAnnotation(Target.class);
+
+ assertNull(t);
+ }
+
+ /**
+ * More a test of how Javassist works. Javassist does not honor the Inherited annotation for
+ * classes (this kind of makes sense, since it won't necessarily have the super-class in
+ * memory). Eventually we'll sort that out inside of InternalClassTransformationImpl. In the
+ * meantime, we just make sure Javassist works the way we think it does (in case a later
+ * Javassist changes this behavior).
+ */
+ @Test
+ public void ensureSubclassesDoNotInheritAnnotations() throws Exception
+ {
+ // The Java runtime does honor @Inherited
+ assertNotNull(ChildClassInheritsAnnotation.class.getAnnotation(ComponentClass.class));
+
+ ClassTransformation ct = createClassTransformation(ChildClassInheritsAnnotation.class);
+
+ ComponentClass cc = ct.getAnnotation(ComponentClass.class);
+
+ // But Javassist does not.
+ assertNull(cc);
+ }
+
+ /**
+ * These tests are really to assert my understanding of Javassist's API. I guess we should keep
+ * them around to make sure that future versions of Javassist work the same as our expectations.
+ */
+ @Test
+ public void javassistGetInterfacesDoesNotIncludeInheritedInterfaces() throws Exception
+ {
+ CtClass ctClass = findCtClass(BarImpl.class);
+
+ CtClass[] interfaces = ctClass.getInterfaces();
+
+ // Just the interfaces implemented by this particular class, not
+ // inherited interfaces.
+
+ assertEquals(interfaces.length, 1);
+
+ assertEquals(interfaces[0].getName(), BarInterface.class.getName());
+
+ CtClass parentClass = ctClass.getSuperclass();
+
+ interfaces = parentClass.getInterfaces();
+
+ assertEquals(interfaces.length, 1);
+
+ assertEquals(interfaces[0].getName(), FooInterface.class.getName());
+ }
+
+ @Test
+ public void javassistGetInterfacesOnAbstractClass() throws Exception
+ {
+ CtClass ctClass = findCtClass(AbstractFoo.class);
+
+ CtClass[] interfaces = ctClass.getInterfaces();
+
+ assertEquals(interfaces.length, 1);
+
+ assertEquals(interfaces[0].getName(), FooInterface.class.getName());
+
+ // In some cases, Java reflection on an abstract class implementing an interface
+ // will show the interface methods as abstract methods on the class. This seems
+ // to vary from JVM to JVM. I believe Javassist is more consistent here.
+
+ CtMethod[] methods = ctClass.getDeclaredMethods();
+
+ assertEquals(methods.length, 0);
+ }
+
+ @Test
+ public void javassistMethodsOnSubInterface() throws Exception
+ {
+ CtClass ctClass = findCtClass(FooBarInterface.class);
+
+ // Just want to check that an interface that extends other interfaces
+ // doesn't show those other interface's methods.
+
+ CtMethod[] methods = ctClass.getDeclaredMethods();
+
+ assertEquals(methods.length, 0);
+ }
+
+ @Test
+ public void addImplementedInterface() throws Exception
+ {
+ ClassLoader childLoader = new Loader(_contextClassLoader, _classPool);
+
+ CtClass targetObjectCtClass = findCtClass(TargetObject.class);
+
+ ClassTransformation ct = new InternalClassTransformationImpl(targetObjectCtClass);
+
+ ct.addImplementedInterface(FooInterface.class);
+ ct.addImplementedInterface(GetterMethodsInterface.class);
+
+ // Inside this test case, we're a bit limited, because
+ // when the modified version of the TargetObject class is loaded,
+ // the FooInterface and GetterMethodsInterface classes are also loaded
+ // into the child class loader. Therefore, we need to use reflection
+ // to check that the methods are implemented correctly.
+
+ Class modified = _classPool.toClass(targetObjectCtClass, childLoader);
+
+ Class[] interfaces = modified.getInterfaces();
+
+ assertEquals(interfaces.length, 2);
+ assertEquals(FooInterface.class.getName(), interfaces[0].getName());
+ assertEquals(GetterMethodsInterface.class.getName(), interfaces[1].getName());
+
+ Object target = modified.newInstance();
+
+ invoke(target, "foo");
+
+ assertEquals(invoke(target, "getBoolean"), false);
+ assertEquals(invoke(target, "getByte"), (byte) 0);
+ assertEquals(invoke(target, "getShort"), (short) 0);
+ assertEquals(invoke(target, "getInt"), 0);
+ assertEquals(invoke(target, "getLong"), 0l);
+ assertEquals(invoke(target, "getFloat"), 0.0f);
+ assertEquals(invoke(target, "getDouble"), 0.0d);
+ assertNull(invoke(target, "getString"));
+ assertNull(invoke(target, "getObjectArray"));
+ assertNull(invoke(target, "getIntArray"));
+ }
+
+ @SuppressWarnings("unchecked")
+ private <T> T invoke(Object target, String methodName) throws Exception
+ {
+ Class targetClass = target.getClass();
+
+ Method method = targetClass.getMethod(methodName);
+
+ return (T) method.invoke(target);
+ }
+
+}
Added: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/transform/pages/AbstractFoo.java
URL: http://svn.apache.org/viewcvs/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/transform/pages/AbstractFoo.java?rev=395912&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/transform/pages/AbstractFoo.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/transform/pages/AbstractFoo.java Fri Apr 21 08:19:11 2006
@@ -0,0 +1,25 @@
+// Copyright 2006 The Howard M. Lewis Ship
+//
+// 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.transform.pages;
+
+import org.apache.tapestry.internal.transform.FooInterface;
+
+/**
+ * @author Howard M. Lewis Ship
+ */
+public abstract class AbstractFoo implements FooInterface
+{
+
+}
Added: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/transform/pages/BarImpl.java
URL: http://svn.apache.org/viewcvs/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/transform/pages/BarImpl.java?rev=395912&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/transform/pages/BarImpl.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/transform/pages/BarImpl.java Fri Apr 21 08:19:11 2006
@@ -0,0 +1,29 @@
+// Copyright 2006 The Howard M. Lewis Ship
+//
+// 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.transform.pages;
+
+import org.apache.tapestry.internal.transform.BarInterface;
+
+/**
+ * @author Howard M. Lewis Ship
+ */
+public class BarImpl extends FooImpl implements BarInterface
+{
+
+ public void bar()
+ {
+ }
+
+}
Added: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/transform/pages/ChildClassInheritsAnnotation.java
URL: http://svn.apache.org/viewcvs/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/transform/pages/ChildClassInheritsAnnotation.java?rev=395912&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/transform/pages/ChildClassInheritsAnnotation.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/transform/pages/ChildClassInheritsAnnotation.java Fri Apr 21 08:19:11 2006
@@ -0,0 +1,12 @@
+package org.apache.tapestry.internal.transform.pages;
+
+/**
+ * Used to check that Javassist does make child classes inherit class annotations.
+ *
+ *
+ * @author Howard M. Lewis Ship
+ */
+public class ChildClassInheritsAnnotation extends ParentClass
+{
+
+}
Added: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/transform/pages/ClaimedFields.java
URL: http://svn.apache.org/viewcvs/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/transform/pages/ClaimedFields.java?rev=395912&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/transform/pages/ClaimedFields.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/transform/pages/ClaimedFields.java Fri Apr 21 08:19:11 2006
@@ -0,0 +1,92 @@
+package org.apache.tapestry.internal.transform.pages;
+
+public class ClaimedFields
+{
+ // Make sure results are sorted by putting this first
+ // but expecting them last.
+
+ private int _zzfield;
+
+ private int _field1;
+
+ private static int field2;
+
+ public int _field3;
+
+ private String _field4;
+
+ protected boolean _field5;
+
+ long _field6;
+
+ public static final int getField2()
+ {
+ return field2;
+ }
+
+ public static final void setField2(int field2)
+ {
+ field2 = field2;
+ }
+
+ public final int getField1()
+ {
+ return _field1;
+ }
+
+ public final void setField1(int field1)
+ {
+ _field1 = field1;
+ }
+
+ public final int getField3()
+ {
+ return _field3;
+ }
+
+ public final void setField3(int field3)
+ {
+ _field3 = field3;
+ }
+
+ public final String getField4()
+ {
+ return _field4;
+ }
+
+ public final void setField4(String field4)
+ {
+ _field4 = field4;
+ }
+
+ public final boolean isField5()
+ {
+ return _field5;
+ }
+
+ public final void setField5(boolean field5)
+ {
+ _field5 = field5;
+ }
+
+ public final long getField6()
+ {
+ return _field6;
+ }
+
+ public final void setField6(long field6)
+ {
+ _field6 = field6;
+ }
+
+ public final int getZzfield()
+ {
+ return _zzfield;
+ }
+
+ public final void setZzfield(int zzfield)
+ {
+ _zzfield = zzfield;
+ }
+
+}
Added: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/transform/pages/FooImpl.java
URL: http://svn.apache.org/viewcvs/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/transform/pages/FooImpl.java?rev=395912&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/transform/pages/FooImpl.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/transform/pages/FooImpl.java Fri Apr 21 08:19:11 2006
@@ -0,0 +1,29 @@
+// Copyright 2006 The Howard M. Lewis Ship
+//
+// 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.transform.pages;
+
+import org.apache.tapestry.internal.transform.FooInterface;
+
+/**
+ * @author Howard M. Lewis Ship
+ */
+public class FooImpl implements FooInterface
+{
+
+ public void foo()
+ {
+ }
+
+}
Added: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/transform/pages/ParentClass.java
URL: http://svn.apache.org/viewcvs/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/transform/pages/ParentClass.java?rev=395912&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/transform/pages/ParentClass.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/transform/pages/ParentClass.java Fri Apr 21 08:19:11 2006
@@ -0,0 +1,48 @@
+// Copyright 2006 The Howard M. Lewis Ship
+//
+// 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.transform.pages;
+
+import org.apache.tapestry.annotations.ComponentClass;
+import org.apache.tapestry.annotations.Retain;
+
+/**
+ * Test class used with
+ * {@link org.apache.tapestry.internal.transform.InternalClassTransformationImplTest}
+ *
+ * @author Howard M. Lewis Ship
+ */
+@ComponentClass
+public class ParentClass
+{
+ public int _parentField;
+
+ // Named so that we can force a name conflict
+
+ public String _$conflictField;
+
+ @Retain
+ public boolean _annotatedField;
+
+ public void doNothingParentMethod()
+ {
+
+ }
+
+ public void _$conflictMethod()
+ {
+
+ }
+
+}
Added: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/transform/pages/TargetObject.java
URL: http://svn.apache.org/viewcvs/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/transform/pages/TargetObject.java?rev=395912&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/transform/pages/TargetObject.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/transform/pages/TargetObject.java Fri Apr 21 08:19:11 2006
@@ -0,0 +1,25 @@
+// Copyright 2006 The Howard M. Lewis Ship
+//
+// 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.transform.pages;
+
+/**
+ * An empty object to which fields, methods and interfaces are added.
+ *
+ * @author Howard M. Lewis Ship
+ */
+public class TargetObject
+{
+
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: tapestry-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tapestry-dev-help@jakarta.apache.org