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 2011/03/29 19:24:35 UTC
svn commit: r1086644 [1/5] - in /tapestry/tapestry5/trunk: ./ plastic/
plastic/src/ plastic/src/main/ plastic/src/main/java/
plastic/src/main/java/org/ plastic/src/main/java/org/apache/
plastic/src/main/java/org/apache/tapestry5/ plastic/src/main/java/...
Author: hlship
Date: Tue Mar 29 17:24:31 2011
New Revision: 1086644
URL: http://svn.apache.org/viewvc?rev=1086644&view=rev
Log:
Initial import of Plastic as a Tapestry sub-project
Added:
tapestry/tapestry5/trunk/plastic/
tapestry/tapestry5/trunk/plastic/build.gradle
tapestry/tapestry5/trunk/plastic/src/
tapestry/tapestry5/trunk/plastic/src/main/
tapestry/tapestry5/trunk/plastic/src/main/java/
tapestry/tapestry5/trunk/plastic/src/main/java/org/
tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/
tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/
tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/
tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/
tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/AbstractAnnotationBuilder.java
tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/AbstractMethodInvocation.java
tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/AnnotationBuilder.java
tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/Cache.java
tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/ClassInstantiatorImpl.java
tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/ClassLoaderDelegate.java
tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/EmptyAnnotationAccess.java
tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/FailureMethodInvocationResult.java
tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/FieldHandleImpl.java
tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/FieldState.java
tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/InstructionBuilderImpl.java
tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/InstructionBuilderState.java
tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/LocalVariable.java
tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/Lockable.java
tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/MethodBundle.java
tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/MethodHandleImpl.java
tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/NameCache.java
tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/NoopDelegate.java
tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/PlasticClassHandleShim.java
tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/PlasticClassImpl.java
tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/PlasticClassLoader.java
tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/PlasticClassPool.java
tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/PlasticClassTransformation.java
tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/PlasticInternalUtils.java
tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/PrimitiveType.java
tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/StandardDelegate.java
tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/StaticContext.java
tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/SuccessMethodInvocationResult.java
tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/SwitchBlockImpl.java
tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/TryCatchBlockImpl.java
tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/TypeCategory.java
tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/plastic/
tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/plastic/AnnotationAccess.java
tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/plastic/ClassInstantiator.java
tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/plastic/ComputedValue.java
tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/plastic/FieldConduit.java
tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/plastic/FieldHandle.java
tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/plastic/InstanceContext.java
tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/plastic/InstructionBuilder.java
tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/plastic/InstructionBuilderCallback.java
tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/plastic/MethodAdvice.java
tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/plastic/MethodDescription.java
tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/plastic/MethodHandle.java
tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/plastic/MethodInvocation.java
tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/plastic/MethodInvocationResult.java
tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/plastic/MethodParameter.java
tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/plastic/Opcodes.java
tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/plastic/PlasticClass.java
tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/plastic/PlasticClassTransformer.java
tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/plastic/PlasticField.java
tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/plastic/PlasticManager.java
tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/plastic/PlasticManagerDelegate.java
tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/plastic/PlasticMethod.java
tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/plastic/PlasticUtils.java
tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/plastic/PropertyAccessType.java
tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/plastic/SwitchBlock.java
tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/plastic/SwitchCallback.java
tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/plastic/TryCatchBlock.java
tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/plastic/TryCatchCallback.java
tapestry/tapestry5/trunk/plastic/src/test/
tapestry/tapestry5/trunk/plastic/src/test/groovy/
tapestry/tapestry5/trunk/plastic/src/test/groovy/org/
tapestry/tapestry5/trunk/plastic/src/test/groovy/org/apache/
tapestry/tapestry5/trunk/plastic/src/test/groovy/org/apache/tapestry5/
tapestry/tapestry5/trunk/plastic/src/test/groovy/org/apache/tapestry5/internal/
tapestry/tapestry5/trunk/plastic/src/test/groovy/org/apache/tapestry5/internal/plastic/
tapestry/tapestry5/trunk/plastic/src/test/groovy/org/apache/tapestry5/internal/plastic/ClassInstantiatorTests.groovy
tapestry/tapestry5/trunk/plastic/src/test/groovy/org/apache/tapestry5/internal/plastic/PlasticUtilsTests.groovy
tapestry/tapestry5/trunk/plastic/src/test/groovy/org/apache/tapestry5/plastic/
tapestry/tapestry5/trunk/plastic/src/test/groovy/org/apache/tapestry5/plastic/AbstractPlasticSpecification.groovy
tapestry/tapestry5/trunk/plastic/src/test/groovy/org/apache/tapestry5/plastic/ArrayAttributeAnnotations.groovy
tapestry/tapestry5/trunk/plastic/src/test/groovy/org/apache/tapestry5/plastic/ClassAnnotationAccess.groovy
tapestry/tapestry5/trunk/plastic/src/test/groovy/org/apache/tapestry5/plastic/FieldAnnotationAccess.groovy
tapestry/tapestry5/trunk/plastic/src/test/groovy/org/apache/tapestry5/plastic/FieldClaiming.groovy
tapestry/tapestry5/trunk/plastic/src/test/groovy/org/apache/tapestry5/plastic/FieldConduitTests.groovy
tapestry/tapestry5/trunk/plastic/src/test/groovy/org/apache/tapestry5/plastic/FieldHandleTests.groovy
tapestry/tapestry5/trunk/plastic/src/test/groovy/org/apache/tapestry5/plastic/FieldInjection.groovy
tapestry/tapestry5/trunk/plastic/src/test/groovy/org/apache/tapestry5/plastic/FieldPropertyMethodCreation.groovy
tapestry/tapestry5/trunk/plastic/src/test/groovy/org/apache/tapestry5/plastic/IntroduceFieldTests.groovy
tapestry/tapestry5/trunk/plastic/src/test/groovy/org/apache/tapestry5/plastic/MethodAdviceTests.groovy
tapestry/tapestry5/trunk/plastic/src/test/groovy/org/apache/tapestry5/plastic/MethodAnnotationAccess.groovy
tapestry/tapestry5/trunk/plastic/src/test/groovy/org/apache/tapestry5/plastic/MethodHandleAccess.groovy
tapestry/tapestry5/trunk/plastic/src/test/groovy/org/apache/tapestry5/plastic/MethodImplementationTests.groovy
tapestry/tapestry5/trunk/plastic/src/test/groovy/org/apache/tapestry5/plastic/MethodIntroduction.groovy
tapestry/tapestry5/trunk/plastic/src/test/groovy/org/apache/tapestry5/plastic/MethodProxying.groovy
tapestry/tapestry5/trunk/plastic/src/test/groovy/org/apache/tapestry5/plastic/ObtainPlasticClass.groovy
tapestry/tapestry5/trunk/plastic/src/test/groovy/org/apache/tapestry5/plastic/ParameterAnnotationsTest.groovy
tapestry/tapestry5/trunk/plastic/src/test/groovy/org/apache/tapestry5/plastic/SimpleClassLoading.groovy
tapestry/tapestry5/trunk/plastic/src/test/groovy/org/apache/tapestry5/plastic/ToStringTests.groovy
tapestry/tapestry5/trunk/plastic/src/test/java/
tapestry/tapestry5/trunk/plastic/src/test/java/org/
tapestry/tapestry5/trunk/plastic/src/test/java/org/apache/
tapestry/tapestry5/trunk/plastic/src/test/java/org/apache/tapestry5/
tapestry/tapestry5/trunk/plastic/src/test/java/org/apache/tapestry5/plastic/
tapestry/tapestry5/trunk/plastic/src/test/java/org/apache/tapestry5/plastic/test/
tapestry/tapestry5/trunk/plastic/src/test/java/org/apache/tapestry5/plastic/test/NoopAdvice.java
tapestry/tapestry5/trunk/plastic/src/test/java/org/apache/tapestry5/plastic/test/TestInject.java
tapestry/tapestry5/trunk/plastic/src/test/java/testsubjects/
tapestry/tapestry5/trunk/plastic/src/test/java/testsubjects/AlternateConstructor.java
tapestry/tapestry5/trunk/plastic/src/test/java/testsubjects/AnnotationSubject.java
tapestry/tapestry5/trunk/plastic/src/test/java/testsubjects/ArrayAnnotation.java
tapestry/tapestry5/trunk/plastic/src/test/java/testsubjects/ArrayAttributesSubject.java
tapestry/tapestry5/trunk/plastic/src/test/java/testsubjects/BaseClass.java
tapestry/tapestry5/trunk/plastic/src/test/java/testsubjects/ChildClass.java
tapestry/tapestry5/trunk/plastic/src/test/java/testsubjects/ContextCatcher.java
tapestry/tapestry5/trunk/plastic/src/test/java/testsubjects/CreateAccessorsSubject.java
tapestry/tapestry5/trunk/plastic/src/test/java/testsubjects/Empty.java
tapestry/tapestry5/trunk/plastic/src/test/java/testsubjects/ExplicityEmptyArrayAttributesSubject.java
tapestry/tapestry5/trunk/plastic/src/test/java/testsubjects/HasToString.java
tapestry/tapestry5/trunk/plastic/src/test/java/testsubjects/InjectFieldSubject.java
tapestry/tapestry5/trunk/plastic/src/test/java/testsubjects/InjectionSubject.java
tapestry/tapestry5/trunk/plastic/src/test/java/testsubjects/InjectionSubjectSubclass.java
tapestry/tapestry5/trunk/plastic/src/test/java/testsubjects/IntFieldHolder.java
tapestry/tapestry5/trunk/plastic/src/test/java/testsubjects/LongFieldHolder.java
tapestry/tapestry5/trunk/plastic/src/test/java/testsubjects/Maybe.java
tapestry/tapestry5/trunk/plastic/src/test/java/testsubjects/Memory.java
tapestry/tapestry5/trunk/plastic/src/test/java/testsubjects/MethodAdviceTarget.java
tapestry/tapestry5/trunk/plastic/src/test/java/testsubjects/MethodHandleSubject.java
tapestry/tapestry5/trunk/plastic/src/test/java/testsubjects/MethodReimplementationSubject.java
tapestry/tapestry5/trunk/plastic/src/test/java/testsubjects/MiddleClass.java
tapestry/tapestry5/trunk/plastic/src/test/java/testsubjects/MultipleFields.java
tapestry/tapestry5/trunk/plastic/src/test/java/testsubjects/MultipleMethods.java
tapestry/tapestry5/trunk/plastic/src/test/java/testsubjects/NonPrivateInstanceField.java
tapestry/tapestry5/trunk/plastic/src/test/java/testsubjects/Outer.java
tapestry/tapestry5/trunk/plastic/src/test/java/testsubjects/ParameterAnnotationsSubject.java
tapestry/tapestry5/trunk/plastic/src/test/java/testsubjects/PrimitiveValues.java
tapestry/tapestry5/trunk/plastic/src/test/java/testsubjects/Property.java
tapestry/tapestry5/trunk/plastic/src/test/java/testsubjects/ScratchPad.java
tapestry/tapestry5/trunk/plastic/src/test/java/testsubjects/SimpleAnnotation.java
tapestry/tapestry5/trunk/plastic/src/test/java/testsubjects/SingleField.java
tapestry/tapestry5/trunk/plastic/src/test/java/testsubjects/SingleMethod.java
tapestry/tapestry5/trunk/plastic/src/test/java/testsubjects/StaticFields.java
tapestry/tapestry5/trunk/plastic/src/test/java/testsubjects/StaticMethodsIgnored.java
tapestry/tapestry5/trunk/plastic/src/test/java/testsubjects/StringHolder.java
tapestry/tapestry5/trunk/plastic/src/test/java/testsubjects/StringPropertyHolder.java
tapestry/tapestry5/trunk/plastic/src/test/java/testsubjects/TestInjectTransformer.java
tapestry/tapestry5/trunk/plastic/src/test/java/testsubjects/Truth.java
tapestry/tapestry5/trunk/plastic/src/test/java/testsubjects/WillNotDoubleException.java
Modified:
tapestry/tapestry5/trunk/settings.gradle
Added: tapestry/tapestry5/trunk/plastic/build.gradle
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/plastic/build.gradle?rev=1086644&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/plastic/build.gradle (added)
+++ tapestry/tapestry5/trunk/plastic/build.gradle Tue Mar 29 17:24:31 2011
@@ -0,0 +1,11 @@
+description = "Plastic core framework"
+
+dependencies {
+ compile "asm:asm-all:3.3.1"
+
+ testCompile "org.spockframework:spock-core:0.5-groovy-1.7"
+}
+
+test {
+ useJUnit()
+}
\ No newline at end of file
Added: tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/AbstractAnnotationBuilder.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/AbstractAnnotationBuilder.java?rev=1086644&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/AbstractAnnotationBuilder.java (added)
+++ tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/AbstractAnnotationBuilder.java Tue Mar 29 17:24:31 2011
@@ -0,0 +1,140 @@
+// Copyright 2011 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.plastic;
+
+import java.lang.reflect.Array;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.objectweb.asm.AnnotationVisitor;
+import org.objectweb.asm.Type;
+
+@SuppressWarnings(
+{ "rawtypes", "unchecked" })
+public abstract class AbstractAnnotationBuilder implements AnnotationVisitor
+{
+ protected final PlasticClassPool pool;
+
+ public AbstractAnnotationBuilder(PlasticClassPool pool)
+ {
+ this.pool = pool;
+ }
+
+ protected abstract void store(String name, Object value);
+
+ protected Class elementTypeForArrayAttribute(String name)
+ {
+ throw new IllegalStateException("elementTypeForArrayAttribute() may not be invoked here.");
+ }
+
+ public void visit(String name, Object value)
+ {
+ if (value instanceof Type)
+ {
+ Type type = (Type) value;
+
+ Class valueType = pool.loadClass(type.getClassName());
+ store(name, valueType);
+ return;
+ }
+
+ store(name, value);
+ }
+
+ public void visitEnum(String name, String desc, String value)
+ {
+
+ try
+ {
+ String enumClassName = PlasticInternalUtils.objectDescriptorToClassName(desc);
+
+ Class enumClass = pool.loader.loadClass(enumClassName);
+
+ Object enumValue = Enum.valueOf(enumClass, value);
+
+ store(name, enumValue);
+ }
+ catch (Exception ex)
+ {
+ throw new IllegalArgumentException(String.format("Unable to convert enum annotation attribute %s %s: %s",
+ value, desc, PlasticInternalUtils.toMessage(ex)), ex);
+ }
+ }
+
+ public AnnotationVisitor visitAnnotation(final String name, String desc)
+ {
+ final AbstractAnnotationBuilder outerBuilder = this;
+
+ final Class nestedAnnotationType = pool.loadClass(PlasticInternalUtils.objectDescriptorToClassName(desc));
+
+ // Return a nested builder that constructs the inner annotation and, at the end of
+ // construction, pushes the final Annotation object into this builder's attributes.
+
+ return new AnnotationBuilder(nestedAnnotationType, pool)
+ {
+ @Override
+ public void visitEnd()
+ {
+ outerBuilder.store(name, createAnnotation());
+ };
+ };
+ }
+
+ /**
+ * Because of how ASM works, this should only be invoked when the array values are not
+ * primitives and not Class/Type; i.e. the inner values will be either Class/Type, enum, or
+ * nested annotations. All the arrays of strings and primitives are handled by ASM and become
+ * a single call to {@link #visit(String, Object)}.
+ */
+ public AnnotationVisitor visitArray(final String name)
+ {
+ final List<Object> values = new ArrayList<Object>();
+
+ final Class componentType = elementTypeForArrayAttribute(name);
+
+ final AbstractAnnotationBuilder outerBuilder = this;
+
+ return new AbstractAnnotationBuilder(pool)
+ {
+ @Override
+ protected void store(String name, Object value)
+ {
+ values.add(value);
+ }
+
+ @Override
+ public void visitEnd()
+ {
+ Object array = Array.newInstance(componentType, values.size());
+
+ // Now, empty arrays may be primitive types and will not cast to Object[], but
+ // non empty arrays indicate that it was a Class/Enum/Annotation, which can cast
+ // to Object[]
+
+ if (values.size() != 0)
+ array = values.toArray((Object[]) array);
+
+ outerBuilder.store(name, array);
+ }
+ };
+ }
+
+ public void visitEnd()
+ {
+ // Nothing to do here. Subclasses use this as a chance to store a value into an outer
+ // builder.
+ }
+
+}
Added: tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/AbstractMethodInvocation.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/AbstractMethodInvocation.java?rev=1086644&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/AbstractMethodInvocation.java (added)
+++ tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/AbstractMethodInvocation.java Tue Mar 29 17:24:31 2011
@@ -0,0 +1,89 @@
+// Copyright 2011 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.plastic;
+
+import org.apache.tapestry5.plastic.InstanceContext;
+import org.apache.tapestry5.plastic.MethodAdvice;
+import org.apache.tapestry5.plastic.MethodInvocation;
+
+public abstract class AbstractMethodInvocation implements MethodInvocation
+{
+ private final Object instance;
+
+ private final InstanceContext instanceContext;
+
+ private final MethodAdvice[] advice;
+
+ private int adviceIndex;
+
+ protected AbstractMethodInvocation(Object instance, InstanceContext instanceContext, MethodAdvice[] advice)
+ {
+ this.instance = instance;
+ this.instanceContext = instanceContext;
+ this.advice = advice;
+ }
+
+ private Exception checkedException;
+
+ public void rethrow()
+ {
+ if (checkedException != null)
+ throw new RuntimeException(checkedException);
+ }
+
+ public boolean didThrowCheckedException()
+ {
+ return checkedException != null;
+ }
+
+ public <T extends Throwable> T getCheckedException(Class<T> exceptionType)
+ {
+ assert exceptionType != null;
+
+ if (exceptionType.isInstance(checkedException))
+ return exceptionType.cast(checkedException);
+
+ return null;
+ }
+
+ public Object getInstance()
+ {
+ return instance;
+ }
+
+ public InstanceContext getInstanceContext()
+ {
+ return instanceContext;
+ }
+
+ public MethodInvocation proceed()
+ {
+ if (adviceIndex == advice.length)
+ proceedToAdvisedMethod();
+ else
+ advice[adviceIndex++].advise(this);
+
+ return this;
+ }
+
+ public MethodInvocation setCheckedException(Exception exception)
+ {
+ checkedException = exception;
+
+ return this;
+ }
+
+ protected abstract void proceedToAdvisedMethod();
+}
Added: tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/AnnotationBuilder.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/AnnotationBuilder.java?rev=1086644&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/AnnotationBuilder.java (added)
+++ tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/AnnotationBuilder.java Tue Mar 29 17:24:31 2011
@@ -0,0 +1,118 @@
+// Copyright 2011 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.plastic;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.util.Map;
+
+@SuppressWarnings(
+{ "rawtypes", "unchecked" })
+public class AnnotationBuilder extends AbstractAnnotationBuilder
+{
+ private static final class AnnotationValueHandler implements InvocationHandler
+ {
+ private final Class annotationType;
+
+ private final Map<String, Object> attributes;
+
+ public AnnotationValueHandler(final Class annotationType, Map<String, Object> attributes)
+ {
+ this.annotationType = annotationType;
+ this.attributes = attributes;
+ }
+
+ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
+ {
+ // args is null for no-arguments methods
+ if (args == null)
+ {
+ String attributeName = method.getName();
+
+ if (attributes.containsKey(attributeName)) { return attributes.get(attributeName); }
+ }
+
+ // TODO: Handling of equals() and hashCode() and toString(), plus other methods
+ // inherited from Object
+
+ throw new RuntimeException(String.format("Annotation proxy for class %s does not handle method %s.",
+ annotationType.getName(), method));
+ }
+ }
+
+ private final Class annotationType;
+
+ final Map<String, Object> attributes = PlasticInternalUtils.newMap();
+
+ public AnnotationBuilder(Class annotationType, PlasticClassPool pool)
+ {
+ super(pool);
+
+ this.annotationType = annotationType;
+
+ attributes.put("annotationType", annotationType);
+
+ // Annotation attributes are represented as methods, and for each method there may be a
+ // default value. Preload the default values, which may be overwritten by explicit
+ // values.
+
+ for (Method m : annotationType.getMethods())
+ {
+ Object defaultValue = m.getDefaultValue();
+
+ if (defaultValue != null)
+ attributes.put(m.getName(), defaultValue);
+ }
+ }
+
+ protected void store(String name, Object value)
+ {
+ attributes.put(name, value);
+ }
+
+ protected Class elementTypeForArrayAttribute(String name)
+ {
+ try
+ {
+ return annotationType.getMethod(name).getReturnType().getComponentType();
+ }
+ catch (Exception ex)
+ {
+ throw new RuntimeException(String.format(
+ "Unable to determine element type for attribute '%s' of annotation %s: %s", name,
+ annotationType.getName(), PlasticInternalUtils.toMessage(ex)), ex);
+ }
+ }
+
+ public Object createAnnotation()
+ {
+ // Use a static inner class to keep the AnnotationBuilder from being retained
+
+ InvocationHandler handler = new AnnotationValueHandler(annotationType, attributes);
+
+ try
+ {
+ return Proxy.newProxyInstance(pool.loader, new Class[]
+ { annotationType }, handler);
+ }
+ catch (IllegalArgumentException ex)
+ {
+ throw new IllegalArgumentException(String.format("Unable to create instance of annotation type %s: %s",
+ annotationType.getName(), PlasticInternalUtils.toMessage(ex)), ex);
+ }
+ }
+
+}
Added: tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/Cache.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/Cache.java?rev=1086644&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/Cache.java (added)
+++ tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/Cache.java Tue Mar 29 17:24:31 2011
@@ -0,0 +1,45 @@
+// Copyright 2011 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.plastic;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Quick and dirty key/value cache that is subclassed to provide the logic that generates the value for
+ * a missing key.
+ *
+ * @param <S>
+ * @param <T>
+ */
+public abstract class Cache<S, T>
+{
+ private Map<S, T> innerCache = new HashMap<S, T>();
+
+ public T get(S input)
+ {
+ T result = innerCache.get(input);
+
+ if (result == null)
+ {
+ result = convert(input);
+ innerCache.put(input, result);
+ }
+
+ return result;
+ }
+
+ protected abstract T convert(S input);
+}
Added: tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/ClassInstantiatorImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/ClassInstantiatorImpl.java?rev=1086644&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/ClassInstantiatorImpl.java (added)
+++ tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/ClassInstantiatorImpl.java Tue Mar 29 17:24:31 2011
@@ -0,0 +1,107 @@
+// Copyright 2011 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.plastic;
+
+import java.lang.reflect.Constructor;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.tapestry5.plastic.ClassInstantiator;
+import org.apache.tapestry5.plastic.InstanceContext;
+
+@SuppressWarnings("all")
+public class ClassInstantiatorImpl implements ClassInstantiator, InstanceContext
+{
+ private final Class clazz;
+
+ private final Constructor ctor;
+
+ private final StaticContext staticContext;
+
+ // Keeping a whole HashMap around for just one or two values feels wasteful, perhaps
+ // come up with something else later.
+
+ private final Map instanceContextMap;
+
+ ClassInstantiatorImpl(Class clazz, Constructor ctor, StaticContext staticContext)
+ {
+ this(clazz, ctor, staticContext, null);
+ }
+
+ private ClassInstantiatorImpl(Class clazz, Constructor ctor, StaticContext staticContext, Map instanceContextMap)
+ {
+ this.clazz = clazz;
+ this.ctor = ctor;
+ this.staticContext = staticContext;
+ this.instanceContextMap = instanceContextMap;
+ }
+
+ public <T> ClassInstantiator with(Class<T> valueType, T instanceContextValue)
+ {
+ assert valueType != null;
+ assert instanceContextValue != null;
+
+ Object existing = getFromMap(valueType);
+
+ if (existing != null)
+ throw new IllegalStateException(String.format(
+ "An instance context value of type %s has already been added.", valueType.getName()));
+
+ Map newMap = instanceContextMap == null ? new HashMap() : new HashMap(instanceContextMap);
+
+ newMap.put(valueType, instanceContextValue);
+
+ return new ClassInstantiatorImpl(clazz, ctor, staticContext, newMap);
+ }
+
+ public <T> T get(Class<T> valueType)
+ {
+ T result = getFromMap(valueType);
+
+ if (result == null)
+ throw new IllegalArgumentException(String.format(
+ "Instance context for class %s does not contain a value for type %s.", clazz.getName(), valueType));
+
+ return result;
+ }
+
+ private <T> T getFromMap(Class<T> valueType)
+ {
+ return instanceContextMap == null ? null : valueType.cast(instanceContextMap.get(valueType));
+ }
+
+ public Object newInstance()
+ {
+ try
+ {
+ return ctor.newInstance(staticContext, this);
+ }
+ catch (Throwable ex)
+ {
+ throw new RuntimeException(String.format("Unable to instantiate instance of transformed class %s: %s",
+ clazz.getName(), PlasticInternalUtils.toMessage(ex)), ex);
+ }
+ }
+
+ public Class<?> getInstanceType()
+ {
+ return clazz;
+ }
+
+ public String toString()
+ {
+ return String.format("ClassInstantiator[%s]", clazz.getName());
+ }
+}
Added: tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/ClassLoaderDelegate.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/ClassLoaderDelegate.java?rev=1086644&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/ClassLoaderDelegate.java (added)
+++ tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/ClassLoaderDelegate.java Tue Mar 29 17:24:31 2011
@@ -0,0 +1,41 @@
+// Copyright 2011 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.plastic;
+
+/**
+ * Externalizes the logic for defining which classes will be loaded (and possibly transformed) by the class loader, and
+ * which will be loaded by the parent class loader.
+ */
+public interface ClassLoaderDelegate
+{
+ /**
+ * Identifies which classes are to be loaded.
+ *
+ * @param className
+ * fully qualified class name
+ * @return true if the class should be intercepted, false to let parent class loader load class
+ */
+ boolean shouldInterceptClassLoading(String className);
+
+ /**
+ * Load the class, transforming it as necessary.
+ *
+ * @param className
+ * binary class name
+ * @return loaded and (if not an inner class) transformed class
+ * @throws ClassNotFoundException
+ */
+ Class<?> loadAndTransformClass(String className) throws ClassNotFoundException;
+}
Added: tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/EmptyAnnotationAccess.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/EmptyAnnotationAccess.java?rev=1086644&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/EmptyAnnotationAccess.java (added)
+++ tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/EmptyAnnotationAccess.java Tue Mar 29 17:24:31 2011
@@ -0,0 +1,38 @@
+// Copyright 2011 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.plastic;
+
+import java.lang.annotation.Annotation;
+
+import org.apache.tapestry5.plastic.AnnotationAccess;
+
+public class EmptyAnnotationAccess implements AnnotationAccess
+{
+ public static final AnnotationAccess SINGLETON = new EmptyAnnotationAccess();
+
+ private EmptyAnnotationAccess()
+ {
+ }
+
+ public <T extends Annotation> boolean hasAnnotation(Class<T> annotationType)
+ {
+ return false;
+ }
+
+ public <T extends Annotation> T getAnnotation(Class<T> annotationType)
+ {
+ return null;
+ }
+}
Added: tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/FailureMethodInvocationResult.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/FailureMethodInvocationResult.java?rev=1086644&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/FailureMethodInvocationResult.java (added)
+++ tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/FailureMethodInvocationResult.java Tue Mar 29 17:24:31 2011
@@ -0,0 +1,53 @@
+// Copyright 2011 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.plastic;
+
+import org.apache.tapestry5.plastic.MethodInvocationResult;
+
+public class FailureMethodInvocationResult implements MethodInvocationResult
+{
+ private final Throwable thrown;
+
+ public FailureMethodInvocationResult(Throwable thrown)
+ {
+ assert thrown != null;
+
+ this.thrown = thrown;
+ }
+
+ public Object getReturnValue()
+ {
+ return null;
+ }
+
+ public void rethrow()
+ {
+ throw new RuntimeException(thrown);
+ }
+
+ public boolean didThrowCheckedException()
+ {
+ return true;
+ }
+
+ public <T extends Throwable> T getCheckedException(Class<T> exceptionType)
+ {
+ if (exceptionType.isInstance(thrown))
+ return exceptionType.cast(thrown);
+
+ return null;
+ }
+
+}
Added: tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/FieldHandleImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/FieldHandleImpl.java?rev=1086644&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/FieldHandleImpl.java (added)
+++ tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/FieldHandleImpl.java Tue Mar 29 17:24:31 2011
@@ -0,0 +1,61 @@
+// Copyright 2011 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.plastic;
+
+import org.apache.tapestry5.plastic.FieldHandle;
+
+public class FieldHandleImpl implements FieldHandle
+{
+ private final String className, fieldName;
+
+ private final int fieldIndex;
+
+ protected volatile PlasticClassHandleShim shim;
+
+ public FieldHandleImpl(String className, String fieldName, int fieldIndex)
+ {
+ this.className = className;
+ this.fieldName = fieldName;
+ this.fieldIndex = fieldIndex;
+ }
+
+ @Override
+ public String toString()
+ {
+ return String.format("FieldHandle[%s#%s]", className, fieldName);
+ }
+
+ public Object get(Object instance)
+ {
+ checkNullInstance(instance, "get");
+
+ return shim.get(instance, fieldIndex);
+ }
+
+ private void checkNullInstance(Object instance, String action)
+ {
+ if (instance == null)
+ throw new NullPointerException(String.format(
+ "Unable to %s value of field %s of class %s, as provided instance is null.", action, fieldName,
+ className));
+ }
+
+ public void set(Object instance, Object newValue)
+ {
+ checkNullInstance(instance, "set");
+
+ shim.set(instance, fieldIndex, newValue);
+ }
+}
Added: tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/FieldState.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/FieldState.java?rev=1086644&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/FieldState.java (added)
+++ tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/FieldState.java Tue Mar 29 17:24:31 2011
@@ -0,0 +1,27 @@
+// Copyright 2011 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.plastic;
+
+public enum FieldState
+{
+ INITIAL("in initial state"), INJECTED("has an injection"), CONDUIT("has a FieldConduit");
+
+ private FieldState(String description)
+ {
+ this.description = description;
+ }
+
+ public final String description;
+}
Added: tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/InstructionBuilderImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/InstructionBuilderImpl.java?rev=1086644&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/InstructionBuilderImpl.java (added)
+++ tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/InstructionBuilderImpl.java Tue Mar 29 17:24:31 2011
@@ -0,0 +1,574 @@
+// Copyright 2011 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.plastic;
+
+import org.apache.tapestry5.plastic.InstructionBuilder;
+import org.apache.tapestry5.plastic.InstructionBuilderCallback;
+import org.apache.tapestry5.plastic.MethodDescription;
+import org.apache.tapestry5.plastic.SwitchCallback;
+import org.apache.tapestry5.plastic.TryCatchCallback;
+import org.objectweb.asm.Label;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.Type;
+
+@SuppressWarnings("rawtypes")
+public class InstructionBuilderImpl extends Lockable implements Opcodes, InstructionBuilder
+{
+ private static final int[] DUPE_OPCODES = new int[]
+ { DUP, DUP_X1, DUP_X2 };
+
+ protected final InstructionBuilderState state;
+
+ protected final MethodVisitor v;
+
+ protected final NameCache cache;
+
+ InstructionBuilderImpl(MethodDescription description, MethodVisitor visitor, NameCache cache)
+ {
+ this(new InstructionBuilderState(description, visitor, cache));
+ }
+
+ InstructionBuilderImpl(InstructionBuilderState state)
+ {
+ this.state = state;
+
+ // These are conveniences for values stored inside the state. In fact,
+ // these fields predate the InstructionBuilderState type.
+ this.v = state.visitor;
+ this.cache = state.nameCache;
+ }
+
+ public InstructionBuilder returnDefaultValue()
+ {
+ check();
+
+ PrimitiveType type = PrimitiveType.getByName(state.description.returnType);
+
+ if (type == null)
+ {
+ v.visitInsn(ACONST_NULL);
+ v.visitInsn(ARETURN);
+ }
+ else
+ {
+ switch (type)
+ {
+ case VOID:
+ break;
+
+ case LONG:
+ v.visitInsn(LCONST_0);
+ break;
+
+ case FLOAT:
+ v.visitInsn(FCONST_0);
+ break;
+
+ case DOUBLE:
+ v.visitInsn(DCONST_0);
+ break;
+
+ default:
+ v.visitInsn(ICONST_0);
+ break;
+ }
+
+ v.visitInsn(type.returnOpcode);
+ }
+
+ return this;
+ }
+
+ public InstructionBuilder loadThis()
+ {
+ check();
+
+ v.visitVarInsn(ALOAD, 0);
+
+ return this;
+ }
+
+ public InstructionBuilder loadNull()
+ {
+ check();
+
+ v.visitInsn(ACONST_NULL);
+
+ return this;
+ }
+
+ public InstructionBuilder loadArgument(int index)
+ {
+ check();
+
+ PrimitiveType type = PrimitiveType.getByName(state.description.argumentTypes[index]);
+
+ int opcode = type == null ? ALOAD : type.loadOpcode;
+
+ // TODO: May need to adjust offset for static (0) vs. instance (1) method.
+
+ v.visitVarInsn(opcode, index + 1);
+
+ return this;
+ }
+
+ public InstructionBuilder loadArguments()
+ {
+ check();
+
+ for (int i = 0; i < state.description.argumentTypes.length; i++)
+ {
+ loadArgument(i);
+ }
+
+ return this;
+ }
+
+ public InstructionBuilder invokeSpecial(String containingClassName, MethodDescription description)
+ {
+ check();
+
+ doInvoke(INVOKESPECIAL, containingClassName, description);
+
+ return this;
+ }
+
+ public InstructionBuilder invokeVirtual(String className, String returnType, String methodName,
+ String... argumentTypes)
+ {
+ check();
+
+ doInvoke(INVOKEVIRTUAL, className, returnType, methodName, argumentTypes);
+
+ return this;
+ }
+
+ public InstructionBuilder invokeInterface(String interfaceName, String returnType, String methodName,
+ String... argumentTypes)
+ {
+ check();
+
+ doInvoke(INVOKEINTERFACE, interfaceName, returnType, methodName, argumentTypes);
+
+ return this;
+ }
+
+ private void doInvoke(int opcode, String className, String returnType, String methodName, String... argumentTypes)
+ {
+ v.visitMethodInsn(opcode, cache.toInternalName(className), methodName,
+ cache.toMethodDescriptor(returnType, argumentTypes));
+ }
+
+ private void doInvoke(int opcode, Class clazz, Class returnType, String methodName, Class... argumentTypes)
+ {
+ doInvoke(opcode, clazz.getName(), cache.toTypeName(returnType), methodName,
+ PlasticInternalUtils.toTypeNames(argumentTypes));
+ }
+
+ public InstructionBuilder invoke(Class clazz, Class returnType, String methodName, Class... argumentTypes)
+ {
+ check();
+
+ doInvoke(clazz.isInterface() ? INVOKEINTERFACE : INVOKEVIRTUAL, clazz, returnType, methodName, argumentTypes);
+
+ return this;
+ }
+
+ private void doInvoke(int opcode, String containingClassName, MethodDescription description)
+ {
+ v.visitMethodInsn(opcode, cache.toInternalName(containingClassName), description.methodName,
+ cache.toDesc(description));
+ }
+
+ public InstructionBuilder returnResult()
+ {
+ check();
+
+ PrimitiveType type = PrimitiveType.getByName(state.description.returnType);
+
+ int opcode = type == null ? ARETURN : type.returnOpcode;
+
+ v.visitInsn(opcode);
+
+ return this;
+ }
+
+ public InstructionBuilder boxPrimitive(String typeName)
+ {
+ check();
+
+ PrimitiveType type = PrimitiveType.getByName(typeName);
+
+ if (type != null && type != PrimitiveType.VOID)
+ {
+ v.visitMethodInsn(INVOKESTATIC, type.wrapperInternalName, "valueOf", type.valueOfMethodDescriptor);
+ }
+
+ return this;
+ }
+
+ public InstructionBuilder unboxPrimitive(String typeName)
+ {
+ check();
+
+ PrimitiveType type = PrimitiveType.getByName(typeName);
+
+ if (type != null)
+ {
+ doUnbox(type);
+ }
+
+ return this;
+ }
+
+ private void doUnbox(PrimitiveType type)
+ {
+ v.visitMethodInsn(INVOKEVIRTUAL, type.wrapperInternalName, type.toValueMethodName, type.toValueMethodDescriptor);
+ }
+
+ public InstructionBuilder getField(String className, String fieldName, String typeName)
+ {
+ check();
+
+ v.visitFieldInsn(GETFIELD, cache.toInternalName(className), fieldName, cache.toDesc(typeName));
+
+ return this;
+ }
+
+ public InstructionBuilder putField(String className, String fieldName, String typeName)
+ {
+ check();
+
+ v.visitFieldInsn(PUTFIELD, cache.toInternalName(className), fieldName, cache.toDesc(typeName));
+
+ return this;
+ }
+
+ public InstructionBuilder putField(String className, String fieldName, Class fieldType)
+ {
+ check();
+
+ return putField(className, fieldName, cache.toTypeName(fieldType));
+ }
+
+ public InstructionBuilder getField(String className, String fieldName, Class fieldType)
+ {
+ check();
+
+ return getField(className, fieldName, fieldType.getName());
+ }
+
+ public InstructionBuilder loadArrayElement(int index, String elementType)
+ {
+ check();
+
+ v.visitLdcInsn(index);
+
+ PrimitiveType type = PrimitiveType.getByName(elementType);
+
+ if (type == null)
+ {
+ v.visitInsn(AALOAD);
+ }
+ else
+ {
+ throw new RuntimeException("Access to non-object arrays is not yet supported.");
+ }
+
+ return this;
+ }
+
+ public InstructionBuilder checkcast(String className)
+ {
+ check();
+
+ // Found out the hard way that array names are handled differently; you cast to the descriptor, not the internal
+ // name.
+
+ String internalName = className.contains("[") ? cache.toDesc(className) : cache.toInternalName(className);
+
+ v.visitTypeInsn(CHECKCAST, internalName);
+
+ return this;
+ }
+
+ public InstructionBuilder checkcast(Class clazz)
+ {
+ check();
+
+ return checkcast(cache.toTypeName(clazz));
+ }
+
+ public InstructionBuilder startTryCatch(TryCatchCallback callback)
+ {
+ check();
+
+ new TryCatchBlockImpl(state).doCallback(callback);
+
+ return this;
+ }
+
+ public InstructionBuilder newInstance(String className)
+ {
+ check();
+
+ v.visitTypeInsn(NEW, cache.toInternalName(className));
+
+ return this;
+ }
+
+ public InstructionBuilder newInstance(Class clazz)
+ {
+ check();
+
+ return newInstance(clazz.getName());
+ }
+
+ public InstructionBuilder invokeConstructor(String className, String... argumentTypes)
+ {
+ check();
+
+ doInvoke(INVOKESPECIAL, className, "void", "<init>", argumentTypes);
+
+ return this;
+ }
+
+ public InstructionBuilder invokeConstructor(Class clazz, Class... argumentTypes)
+ {
+ check();
+
+ return invokeConstructor(clazz.getName(), PlasticInternalUtils.toTypeNames(argumentTypes));
+ }
+
+ public InstructionBuilder dupe(int depth)
+ {
+ check();
+
+ if (depth < 0 || depth >= DUPE_OPCODES.length)
+ throw new IllegalArgumentException(String.format(
+ "Dupe depth %d is invalid; values from 0 to %d are allowed.", depth, DUPE_OPCODES.length - 1));
+
+ v.visitInsn(DUPE_OPCODES[depth]);
+
+ return this;
+ }
+
+ public InstructionBuilder pop()
+ {
+ check();
+
+ v.visitInsn(POP);
+
+ return this;
+ }
+
+ public InstructionBuilder swap()
+ {
+ check();
+
+ v.visitInsn(SWAP);
+
+ return this;
+ }
+
+ public InstructionBuilder loadConstant(Object constant)
+ {
+ check();
+
+ v.visitLdcInsn(constant);
+
+ return this;
+ }
+
+ public InstructionBuilder loadTypeConstant(String typeName)
+ {
+ check();
+
+ Type type = Type.getType(cache.toDesc(typeName));
+
+ v.visitLdcInsn(type);
+
+ return this;
+ }
+
+ public InstructionBuilder loadTypeConstant(Class clazz)
+ {
+ check();
+
+ Type type = Type.getType(clazz);
+
+ v.visitLdcInsn(type);
+
+ return this;
+ }
+
+ public InstructionBuilder castOrUnbox(String typeName)
+ {
+ check();
+
+ PrimitiveType type = PrimitiveType.getByName(typeName);
+
+ if (type == null)
+ return checkcast(typeName);
+
+ v.visitTypeInsn(CHECKCAST, type.wrapperInternalName);
+ doUnbox(type);
+
+ return this;
+ }
+
+ public InstructionBuilder throwException(String className, String message)
+ {
+ check();
+
+ newInstance(className);
+ dupe(0);
+ loadConstant(message);
+ invokeConstructor(className, "java.lang.String");
+ v.visitInsn(ATHROW);
+
+ return this;
+ }
+
+ public InstructionBuilder throwException(Class<? extends Throwable> exceptionType, String message)
+ {
+ check();
+
+ return throwException(cache.toTypeName(exceptionType), message);
+ }
+
+ public InstructionBuilder throwException()
+ {
+ check();
+
+ v.visitInsn(ATHROW);
+
+ return this;
+ }
+
+ public InstructionBuilder startSwitch(int min, int max, SwitchCallback callback)
+ {
+ check();
+
+ assert callback != null;
+
+ new SwitchBlockImpl(state, min, max).doCallback(callback);
+
+ return this;
+ }
+
+ public InstructionBuilder startVariable(String name, String type, InstructionBuilderCallback callback)
+ {
+ check();
+
+ Label start = state.newLabel();
+ Label end = new Label();
+
+ LocalVariable var = new LocalVariable(name, type, state.localIndex++);
+
+ v.visitLocalVariable(name, cache.toDesc(type), null, start, end, var.index);
+
+ LocalVariable prior = state.locals.put(name, var);
+
+ new InstructionBuilderImpl(state).doCallback(callback);
+
+ v.visitLabel(end);
+
+ state.localIndex--;
+
+ // Restore the original variable with this name, probably just null though.
+
+ state.locals.put(name, prior);
+
+ return this;
+ }
+
+ public InstructionBuilder storeVariable(String name)
+ {
+ check();
+
+ LocalVariable var = state.locals.get(name);
+
+ PrimitiveType type = PrimitiveType.getByName(var.type);
+
+ int opcode = type == null ? ASTORE : type.storeOpcode;
+
+ v.visitVarInsn(opcode, var.index);
+
+ return this;
+ }
+
+ public InstructionBuilder loadVariable(String name)
+ {
+ check();
+
+ LocalVariable var = state.locals.get(name);
+
+ PrimitiveType type = PrimitiveType.getByName(var.type);
+
+ int opcode = type == null ? ALOAD : type.loadOpcode;
+
+ v.visitVarInsn(opcode, var.index);
+
+ return this;
+ }
+
+ public InstructionBuilder ifZero(InstructionBuilderCallback ifTrue, InstructionBuilderCallback ifFalse)
+ {
+ doConditional(IFEQ, ifTrue, ifFalse);
+
+ return this;
+ }
+
+ public InstructionBuilder ifNull(InstructionBuilderCallback ifTrue, InstructionBuilderCallback ifFalse)
+ {
+ doConditional(IFNULL, ifTrue, ifFalse);
+
+ return this;
+ }
+
+ private void doConditional(int opcode, InstructionBuilderCallback ifTrueCallback,
+ InstructionBuilderCallback ifFalseCallback)
+ {
+ check();
+
+ Label ifTrueLabel = new Label();
+ Label endIfLabel = new Label();
+
+ // Kind of clumsy code, but it will work.
+
+ v.visitJumpInsn(opcode, ifTrueLabel);
+
+ new InstructionBuilderImpl(state).doCallback(ifFalseCallback);
+
+ v.visitJumpInsn(GOTO, endIfLabel);
+ v.visitLabel(ifTrueLabel);
+
+ new InstructionBuilderImpl(state).doCallback(ifTrueCallback);
+
+ v.visitLabel(endIfLabel);
+ }
+
+ void doCallback(InstructionBuilderCallback callback)
+ {
+ check();
+
+ if (callback != null)
+ callback.doBuild(this);
+
+ lock();
+ }
+}
Added: tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/InstructionBuilderState.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/InstructionBuilderState.java?rev=1086644&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/InstructionBuilderState.java (added)
+++ tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/InstructionBuilderState.java Tue Mar 29 17:24:31 2011
@@ -0,0 +1,58 @@
+// Copyright 2011 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.plastic;
+
+import java.util.Map;
+
+import org.apache.tapestry5.plastic.MethodDescription;
+import org.objectweb.asm.Label;
+import org.objectweb.asm.MethodVisitor;
+
+/**
+ * Stores information about the method whose instructions are being constructed, to make it easier
+ * to share data across multiple instances.
+ */
+public class InstructionBuilderState
+{
+ final MethodDescription description;
+
+ final MethodVisitor visitor;
+
+ final NameCache nameCache;
+
+ int localIndex;
+
+ final Map<String, LocalVariable> locals = PlasticInternalUtils.newMap();
+
+ protected InstructionBuilderState(MethodDescription description, MethodVisitor visitor, NameCache nameCache)
+ {
+ this.description = description;
+ this.visitor = visitor;
+ this.nameCache = nameCache;
+
+ // TODO: Account for static methods?
+
+ localIndex = 1 + description.argumentTypes.length;
+ }
+
+ Label newLabel()
+ {
+ Label result = new Label();
+
+ visitor.visitLabel(result);
+
+ return result;
+ }
+}
Added: tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/LocalVariable.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/LocalVariable.java?rev=1086644&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/LocalVariable.java (added)
+++ tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/LocalVariable.java Tue Mar 29 17:24:31 2011
@@ -0,0 +1,32 @@
+// Copyright 2011 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.plastic;
+
+public class LocalVariable
+{
+ final String name;
+
+ final String type;
+
+ // Adjusted index i.e., 1 + # of args + var index
+ final int index;
+
+ LocalVariable(String name, String type, int index)
+ {
+ this.name = name;
+ this.type = type;
+ this.index = index;
+ }
+}
Added: tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/Lockable.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/Lockable.java?rev=1086644&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/Lockable.java (added)
+++ tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/Lockable.java Tue Mar 29 17:24:31 2011
@@ -0,0 +1,38 @@
+// Copyright 2011 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.plastic;
+
+/**
+ * An object that can be locked, at which point most of its functionality is disabled. This conforms to general
+ * builder approach used throughout Plastic where objects have an active construction phase, but are then locked
+ * (to encourage user code to discard them after they are no longer of any use).
+ */
+public class Lockable
+{
+ private boolean locked;
+
+ protected void check()
+ {
+ if (locked)
+ throw new IllegalStateException(toString() + " has been locked and can no longer be used.");
+ }
+
+ protected void lock()
+ {
+ check();
+
+ locked = true;
+ }
+}
Added: tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/MethodBundle.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/MethodBundle.java?rev=1086644&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/MethodBundle.java (added)
+++ tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/MethodBundle.java Tue Mar 29 17:24:31 2011
@@ -0,0 +1,115 @@
+// Copyright 2011 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.plastic;
+
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * Used to track which methods are implemented by a base class, which is often needed when transforming
+ * a subclass.
+ */
+public class MethodBundle
+{
+ private final MethodBundle parent;
+
+ private final Set<String> methods = new HashSet<String>();
+
+ // TODO: So far, this is just a placeholder until we figure out what the API should look like.
+ // TODO: Possibly, rename this class and have it store additional information, such as the name of a
+ // (protected final) field storing the InstanceContext.
+
+ public MethodBundle()
+ {
+ this(null);
+ }
+
+ private MethodBundle(MethodBundle parent)
+ {
+ this.parent = parent;
+ }
+
+ /**
+ * Is this bundle for a transformed class, or for a base class (typically Object)?
+ *
+ * @return
+ * true if this bundle is for transformed class, false otherwise
+ */
+ public boolean isTransformed()
+ {
+ return parent != null;
+ }
+
+ /**
+ * Returns a new MethodBundle that represents the methods of a child class
+ * of this bundle. The returned bundle will always be {@linkplain #isTransformed() transformed}.
+ *
+ * @param childClassName
+ * name of subclass
+ * @return new method bundle
+ */
+ public MethodBundle createChild(String childClassName)
+ {
+ return new MethodBundle(this);
+ }
+
+ /**
+ * Adds a new instance method. Only non-private, non-abstract methods should be added (that is, methods which might
+ * be overridden in subclasses). This can later be queried to see if any base class implements the method.
+ *
+ * @param name
+ * name of method
+ * @param desc
+ * method descriptor
+ */
+ public void addMethod(String name, String desc)
+ {
+ String value = toValue(name, desc);
+
+ methods.add(value);
+ }
+
+ /**
+ * Returns true if a transformed parent class contains the indicated method.
+ *
+ * @param name
+ * method name
+ * @param desc
+ * method descriptor
+ * @return the <em>internal name</em> of the implementing base class for this method,
+ * or null if no base class implements the method
+ */
+ public boolean isImplemented(String name, String desc)
+ {
+ return checkForMethod(toValue(name, desc));
+ }
+
+ private boolean checkForMethod(String value)
+ {
+ if (methods.contains(value))
+ return true;
+
+ return parent == null ? false : parent.checkForMethod(value);
+ }
+
+ /**
+ * Combines a method name and its desc (which describes parameter types and return value) to form
+ * a value, which is how methods are tracked.
+ */
+ private String toValue(String name, String desc)
+ {
+ return name + ":" + desc;
+ }
+}
Added: tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/MethodHandleImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/MethodHandleImpl.java?rev=1086644&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/MethodHandleImpl.java (added)
+++ tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/MethodHandleImpl.java Tue Mar 29 17:24:31 2011
@@ -0,0 +1,51 @@
+// Copyright 2011 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.plastic;
+
+import org.apache.tapestry5.plastic.MethodHandle;
+import org.apache.tapestry5.plastic.MethodInvocationResult;
+
+public class MethodHandleImpl implements MethodHandle
+{
+ private final String className, methodDescription;
+
+ private final int methodIndex;
+
+ protected volatile PlasticClassHandleShim shim;
+
+ public MethodHandleImpl(String className, String methodDescription, int methodIndex)
+ {
+ this.className = className;
+ this.methodDescription = methodDescription;
+ this.methodIndex = methodIndex;
+ }
+
+ public String toString()
+ {
+ return String.format("MethodHandle[%s %s]", className, methodDescription);
+ }
+
+ public MethodInvocationResult invoke(Object instance, Object... arguments)
+ {
+
+ if (instance == null)
+ throw new NullPointerException(String.format(
+ "Unable to invoke method %s of class %s, as provided instance is null.", methodDescription,
+ className));
+
+ return shim.invoke(instance, methodIndex, arguments);
+ }
+
+}
Added: tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/NameCache.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/NameCache.java?rev=1086644&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/NameCache.java (added)
+++ tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/NameCache.java Tue Mar 29 17:24:31 2011
@@ -0,0 +1,125 @@
+// Copyright 2011 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.plastic;
+
+import org.apache.tapestry5.plastic.MethodDescription;
+
+/**
+ * A cache of translations from type names to internal names and descriptors, as well as a cache from MethodDescription
+ * to method descriptor.
+ */
+@SuppressWarnings("rawtypes")
+public class NameCache
+{
+ private final Cache<String, String> class2internal = new Cache<String, String>()
+ {
+
+ @Override
+ protected String convert(String className)
+ {
+ return PlasticInternalUtils.toInternalName(className);
+ }
+ };
+
+ private final Cache<Class, String> type2internal = new Cache<Class, String>()
+ {
+ @Override
+ protected String convert(Class input)
+ {
+ return toInternalName(input.getName());
+ };
+ };
+
+ private final Cache<MethodDescription, String> md2desc = new Cache<MethodDescription, String>()
+ {
+ @Override
+ protected String convert(MethodDescription methodDescription)
+ {
+ return toMethodDescriptor(methodDescription.returnType, methodDescription.argumentTypes);
+ }
+ };
+
+ private final Cache<String, String> type2desc = new Cache<String, String>()
+ {
+ @Override
+ protected String convert(String typeName)
+ {
+ return PlasticInternalUtils.toDescriptor(typeName);
+ }
+ };
+
+ private final Cache<Class, String> typeToTypeName = new Cache<Class, String>()
+ {
+ @Override
+ protected String convert(Class type)
+ {
+ return PlasticInternalUtils.toTypeName(type);
+ };
+ };
+
+ public String toInternalName(String className)
+ {
+ return class2internal.get(className);
+ }
+
+ public String toInternalName(Class type)
+ {
+ return type2internal.get(type);
+ }
+
+ public String toDesc(MethodDescription md)
+ {
+ return md2desc.get(md);
+ }
+
+ public String toDesc(String typeName)
+ {
+ return type2desc.get(typeName);
+ }
+
+ public String toTypeName(Class type)
+ {
+ return typeToTypeName.get(type);
+ }
+
+ public String[] toTypeNames(Class... types)
+ {
+ String[] result = new String[types.length];
+
+ for (int i = 0; i < result.length; i++)
+ result[i] = toTypeName(types[i]);
+
+ return result;
+ }
+
+ public String toMethodDescriptor(Class returnType, Class... argumentTypes)
+ {
+ return toMethodDescriptor(toTypeName(returnType), toTypeNames(argumentTypes));
+ }
+
+ public String toMethodDescriptor(String returnType, String... argumentTypes)
+ {
+ StringBuilder builder = new StringBuilder("(");
+
+ for (String argumentType : argumentTypes)
+ {
+ builder.append(toDesc(argumentType));
+ }
+
+ builder.append(")").append(toDesc(returnType));
+
+ return builder.toString();
+ }
+}
Added: tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/NoopDelegate.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/NoopDelegate.java?rev=1086644&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/NoopDelegate.java (added)
+++ tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/NoopDelegate.java Tue Mar 29 17:24:31 2011
@@ -0,0 +1,32 @@
+// Copyright 2011 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.plastic;
+
+import org.apache.tapestry5.plastic.ClassInstantiator;
+import org.apache.tapestry5.plastic.PlasticClass;
+import org.apache.tapestry5.plastic.PlasticManagerDelegate;
+
+public class NoopDelegate implements PlasticManagerDelegate
+{
+ public void transform(PlasticClass plasticClass)
+ {
+ }
+
+ public ClassInstantiator configureInstantiator(String className, ClassInstantiator instantiator)
+ {
+ return instantiator;
+ }
+
+}
Added: tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/PlasticClassHandleShim.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/PlasticClassHandleShim.java?rev=1086644&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/PlasticClassHandleShim.java (added)
+++ tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/PlasticClassHandleShim.java Tue Mar 29 17:24:31 2011
@@ -0,0 +1,74 @@
+// Copyright 2011 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.plastic;
+
+import org.apache.tapestry5.plastic.FieldHandle;
+import org.apache.tapestry5.plastic.MethodHandle;
+import org.apache.tapestry5.plastic.MethodInvocationResult;
+import org.apache.tapestry5.plastic.PlasticClass;
+
+/**
+ * The interface for a "shim" class that provides the necessary hooks needed
+ * by {@link FieldHandle} and {@link MethodHandle} implementations for a particular,
+ * instantiated {@link PlasticClass}.
+ */
+public abstract class PlasticClassHandleShim
+{
+ /**
+ * Gets the field at the given index.
+ *
+ * @param instance
+ * object to read instance field from
+ * @param fieldIndex
+ * assigned index for the field
+ * @return the field's value
+ * @see FieldHandle#get(Object)
+ */
+ public Object get(Object instance, int fieldIndex)
+ {
+ return null;
+ }
+
+ /**
+ * Sets the value of a field.
+ *
+ * @param instance
+ * object to update instance field in
+ * @param fieldIndex
+ * assigned index for the field
+ * @param newValue
+ * new value for field
+ * @see FieldHandle#set(Object, Object)
+ */
+ public void set(Object instance, int fieldIndex, Object newValue)
+ {
+ }
+
+ /**
+ * Invokes a method.
+ *
+ * @param instance
+ * object to invoke a method upon
+ * @param methodIndex
+ * assigned index for the method
+ * @param arguments
+ * arguments to pass to the method
+ * @return result of invoking the method
+ */
+ public MethodInvocationResult invoke(Object instance, int methodIndex, Object[] arguments)
+ {
+ return null;
+ }
+}