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/04/07 23:16:38 UTC
svn commit: r1090016 - in /tapestry/tapestry5/trunk/plastic/src:
main/java/org/apache/tapestry5/internal/plastic/
main/java/org/apache/tapestry5/plastic/
test/groovy/org/apache/tapestry5/plastic/
Author: hlship
Date: Thu Apr 7 21:16:38 2011
New Revision: 1090016
URL: http://svn.apache.org/viewvc?rev=1090016&view=rev
Log:
TAP5-853: Make it easy to efficiently inject an InstanceContext value
Modified:
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/PlasticClassImpl.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/plastic/InstructionBuilder.java
tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/plastic/PlasticField.java
tapestry/tapestry5/trunk/plastic/src/test/groovy/org/apache/tapestry5/plastic/FieldInjection.groovy
Modified: 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=1090016&r1=1090015&r2=1090016&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/InstructionBuilderImpl.java (original)
+++ tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/InstructionBuilderImpl.java Thu Apr 7 21:16:38 2011
@@ -170,6 +170,13 @@ public class InstructionBuilderImpl exte
cache.toMethodDescriptor(returnType, argumentTypes));
}
+ public InstructionBuilder invokeStatic(Class clazz, Class returnType, String methodName, Class... argumentTypes)
+ {
+ doInvoke(INVOKESTATIC, clazz, returnType, methodName, argumentTypes);
+
+ return this;
+ }
+
private void doInvoke(int opcode, Class clazz, Class returnType, String methodName, Class... argumentTypes)
{
doInvoke(opcode, clazz.getName(), cache.toTypeName(returnType), methodName,
Modified: tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/PlasticClassImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/PlasticClassImpl.java?rev=1090016&r1=1090015&r2=1090016&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/PlasticClassImpl.java (original)
+++ tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/PlasticClassImpl.java Thu Apr 7 21:16:38 2011
@@ -631,6 +631,34 @@ public class PlasticClassImpl extends Lo
constructorBuilder.putField(className, node.name, typeName);
}
+ public PlasticField injectFromInstanceContext()
+ {
+ check();
+
+ verifyInitialState("inject instance context value into");
+
+ // Easiest to load this, for the putField(), early, in case the field is
+ // wide (long or double primitive)
+
+ constructorBuilder.loadThis();
+
+ // Add the InstanceContext to the stack
+
+ constructorBuilder.loadArgument(1);
+ constructorBuilder.loadConstant(typeName);
+
+ constructorBuilder.invokeStatic(PlasticInternalUtils.class, Object.class, "getFromInstanceContext",
+ InstanceContext.class, String.class).castOrUnbox(typeName);
+
+ constructorBuilder.putField(className, node.name, typeName);
+
+ makeReadOnly();
+
+ state = FieldState.INJECTED;
+
+ return this;
+ }
+
public PlasticField setConduit(FieldConduit<?> conduit)
{
assert conduit != null;
Modified: tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/PlasticInternalUtils.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/PlasticInternalUtils.java?rev=1090016&r1=1090015&r2=1090016&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/PlasticInternalUtils.java (original)
+++ tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/PlasticInternalUtils.java Thu Apr 7 21:16:38 2011
@@ -31,6 +31,7 @@ import org.apache.tapestry5.internal.pla
import org.apache.tapestry5.internal.plastic.asm.tree.ClassNode;
import org.apache.tapestry5.internal.plastic.asm.tree.MethodNode;
import org.apache.tapestry5.internal.plastic.asm.util.TraceClassVisitor;
+import org.apache.tapestry5.plastic.InstanceContext;
import org.apache.tapestry5.plastic.MethodDescription;
@SuppressWarnings("rawtypes")
@@ -355,4 +356,20 @@ public class PlasticInternalUtils
return Class.forName(builder.toString(), true, loader);
}
+
+ public static Object getFromInstanceContext(InstanceContext context, String javaName)
+ {
+ ClassLoader loader = context.getInstanceType().getClassLoader();
+
+ try
+ {
+ Class valueType = toClass(loader, javaName);
+
+ return context.get(valueType);
+ }
+ catch (ClassNotFoundException ex)
+ {
+ throw new RuntimeException(ex);
+ }
+ }
}
Modified: tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/plastic/InstructionBuilder.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/plastic/InstructionBuilder.java?rev=1090016&r1=1090015&r2=1090016&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/plastic/InstructionBuilder.java (original)
+++ tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/plastic/InstructionBuilder.java Thu Apr 7 21:16:38 2011
@@ -98,6 +98,12 @@ public interface InstructionBuilder
InstructionBuilder invoke(Class clazz, Class returnType, String methodName, Class... argumentTypes);
/**
+ * Invokes a static method of a class.
+ */
+ @Opcodes("INVOKESTATIC")
+ InstructionBuilder invokeStatic(Class clazz, Class returnType, String methodName, Class... argumentTypes);
+
+ /**
* Returns the top value on the stack. For void methods, no value should
* be on the stack and the method will simply return.
*/
Modified: tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/plastic/PlasticField.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/plastic/PlasticField.java?rev=1090016&r1=1090015&r2=1090016&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/plastic/PlasticField.java (original)
+++ tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/plastic/PlasticField.java Thu Apr 7 21:16:38 2011
@@ -92,6 +92,13 @@ public interface PlasticField extends An
PlasticField injectComputed(ComputedValue<?> computedValue);
/**
+ * As with {@link #inject(Object)}, but the value is extracted from the {@link InstanceContext}.
+ *
+ * @return this field for further manipulation
+ */
+ PlasticField injectFromInstanceContext();
+
+ /**
* Intercepts all access to the field, replacing such access with calls on the conduit. Even access via
* the FieldHandle will instead delegate to the conduit. Once a conduit is provided, it is not possible
* to inject a value into the field.
Modified: tapestry/tapestry5/trunk/plastic/src/test/groovy/org/apache/tapestry5/plastic/FieldInjection.groovy
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/plastic/src/test/groovy/org/apache/tapestry5/plastic/FieldInjection.groovy?rev=1090016&r1=1090015&r2=1090016&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/plastic/src/test/groovy/org/apache/tapestry5/plastic/FieldInjection.groovy (original)
+++ tapestry/tapestry5/trunk/plastic/src/test/groovy/org/apache/tapestry5/plastic/FieldInjection.groovy Thu Apr 7 21:16:38 2011
@@ -72,6 +72,27 @@ class FieldInjection extends Specificati
thrown(IllegalStateException)
}
+ def "injection from instance context"() {
+
+ String injected = "InstanceContext value injected into the StringPropertyHolder class"
+
+ def pc = mgr.getPlasticClass("testsubjects.StringPropertyHolder")
+
+ pc.allFields.first().injectFromInstanceContext()
+
+ def o = pc.createInstantiator().with(String.class, injected).newInstance()
+
+ expect:
+
+ o.value.is(injected)
+
+ when:
+ o.value = "attempt to update"
+
+ then:
+ thrown(IllegalStateException)
+ }
+
def "injection of primitive value"() {
def pc = mgr.getPlasticClass("testsubjects.Empty")
@@ -94,9 +115,9 @@ class FieldInjection extends Specificati
def pc = mgr.getPlasticClass("testsubjects.InjectFieldSubject")
def pf = pc.allFields.first();
-
+
def handle = pf.handle;
-
+
pf.inject(99)
def ins = pc.createInstantiator()
@@ -111,12 +132,12 @@ class FieldInjection extends Specificati
then:
def e = thrown(IllegalStateException)
e.message == "Field value of class testsubjects.InjectFieldSubject is read-only."
-
+
when:
handle.set(o, 456)
-
+
then:
-
+
thrown(IllegalStateException)
}