tapestry-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From hls...@apache.org
Subject svn commit: r1196370 - in /tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services: ClassCreationHelper.java ComponentInstantiatorSourceImplTest.java
Date Tue, 01 Nov 2011 23:11:10 GMT
Author: hlship
Date: Tue Nov  1 23:11:10 2011
New Revision: 1196370

URL: http://svn.apache.org/viewvc?rev=1196370&view=rev
Log:
TAP5-1739: Recode component class reload tests around ASM instead of Javassist

Added:
    tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/ClassCreationHelper.java
Modified:
    tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/ComponentInstantiatorSourceImplTest.java

Added: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/ClassCreationHelper.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/ClassCreationHelper.java?rev=1196370&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/ClassCreationHelper.java
(added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/ClassCreationHelper.java
Tue Nov  1 23:11:10 2011
@@ -0,0 +1,135 @@
+// 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.services;
+
+import org.apache.tapestry5.internal.plastic.PlasticInternalUtils;
+import org.apache.tapestry5.internal.plastic.asm.ClassWriter;
+import org.apache.tapestry5.internal.plastic.asm.MethodVisitor;
+import org.apache.tapestry5.ioc.Registry;
+import org.apache.tapestry5.ioc.RegistryBuilder;
+import org.apache.tapestry5.services.TapestryModule;
+
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.OutputStream;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.net.URLConnection;
+import java.util.UUID;
+
+import static org.apache.tapestry5.internal.plastic.asm.Opcodes.*;
+
+public class ClassCreationHelper
+{
+    private static final ClassLoader contextLoader = Thread.currentThread().getContextClassLoader();
+
+    private String tempDir;
+
+    private URLClassLoader extraLoader;
+
+    public final Registry registry;
+
+    public ClassCreationHelper(Class... extraModules) throws Exception
+    {
+        tempDir = String.format("%s/tapestry-test-classpath/%s",
+                System.getProperty("java.io.tmpdir"),
+                UUID.randomUUID().toString());
+
+        File extraClasspath = new File(tempDir);
+
+        extraClasspath.mkdirs();
+
+        URL url = extraClasspath.toURL();
+
+        URLClassLoader extraLoader = new URLClassLoader(new URL[]
+                {url}, contextLoader);
+
+        RegistryBuilder builder = new RegistryBuilder(extraLoader);
+
+        builder.add(TapestryModule.class);
+        builder.add(extraModules);
+
+        registry = builder.build();
+    }
+
+    public void writeFile(ClassWriter writer, String className) throws Exception
+    {
+        File classFile = toFile(className);
+
+        classFile.getParentFile().mkdirs();
+
+        OutputStream os = new BufferedOutputStream(new FileOutputStream(classFile));
+
+        os.write(writer.toByteArray());
+
+        os.close();
+    }
+
+    public ClassWriter createWriter(String className, String superClassName, String... interfaceNames)
+    {
+        String[] interfaceInternalNames = new String[interfaceNames.length];
+        for (int i = 0; i < interfaceNames.length; i++)
+        {
+            interfaceInternalNames[i] = PlasticInternalUtils.toInternalName(interfaceNames[i]);
+        }
+
+        ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES + ClassWriter.COMPUTE_MAXS);
+
+        cw.visit(V1_5, ACC_PUBLIC, PlasticInternalUtils.toInternalName(className), null,
+                PlasticInternalUtils.toInternalName(superClassName), interfaceInternalNames);
+
+        return cw;
+    }
+
+    public void implementPublicConstructor(ClassWriter cw, String superClassName)
+    {
+
+        MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
+        mv.visitCode();
+        mv.visitVarInsn(ALOAD, 0);
+        mv.visitMethodInsn(INVOKESPECIAL, PlasticInternalUtils.toInternalName(superClassName),
"<init>", "()V");
+        mv.visitInsn(RETURN);
+        mv.visitEnd();
+    }
+
+
+    public long readDTM(String className) throws Exception
+    {
+        URL url = toFile(className).toURL();
+
+        return readDTM(url);
+    }
+
+    private File toFile(String className)
+    {
+        String path = String.format("%s/%s.class",
+                tempDir,
+                PlasticInternalUtils.toInternalName(className));
+
+        return new File(path);
+    }
+
+    private long readDTM(URL url) throws Exception
+    {
+        URLConnection connection = url.openConnection();
+
+        connection.connect();
+
+        return connection.getLastModified();
+    }
+
+
+}

Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/ComponentInstantiatorSourceImplTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/ComponentInstantiatorSourceImplTest.java?rev=1196370&r1=1196369&r2=1196370&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/ComponentInstantiatorSourceImplTest.java
(original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/ComponentInstantiatorSourceImplTest.java
Tue Nov  1 23:11:10 2011
@@ -14,52 +14,36 @@
 
 package org.apache.tapestry5.internal.services;
 
-import java.io.File;
-import java.io.IOException;
-import java.net.URL;
-import java.net.URLClassLoader;
-import java.net.URLConnection;
-import java.util.UUID;
-
-import javassist.CannotCompileException;
-import javassist.ClassPool;
-import javassist.CtClass;
-import javassist.CtMethod;
-import javassist.CtNewMethod;
-import javassist.LoaderClassPath;
-import javassist.NotFoundException;
-
 import org.apache.tapestry5.internal.InternalComponentResources;
+import org.apache.tapestry5.internal.plastic.asm.ClassWriter;
+import org.apache.tapestry5.internal.plastic.asm.MethodVisitor;
 import org.apache.tapestry5.internal.test.InternalBaseTestCase;
 import org.apache.tapestry5.internal.transform.pages.BasicComponent;
 import org.apache.tapestry5.ioc.Registry;
-import org.apache.tapestry5.ioc.RegistryBuilder;
 import org.apache.tapestry5.runtime.Component;
-import org.apache.tapestry5.services.TapestryModule;
 import org.apache.tapestry5.services.UpdateListenerHub;
 import org.testng.annotations.AfterClass;
 import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
+import static org.apache.tapestry5.internal.plastic.asm.Opcodes.ACC_PUBLIC;
+import static org.apache.tapestry5.internal.plastic.asm.Opcodes.ARETURN;
+
 /**
  * Tests for {@link org.apache.tapestry5.internal.services.ComponentInstantiatorSourceImpl}.
Several of these tests are
  * more of the form of integration tests that instantiate the Tapestry IoC Registry.
  */
 public class ComponentInstantiatorSourceImplTest extends InternalBaseTestCase
 {
-    private static final ClassLoader contextLoader = Thread.currentThread().getContextClassLoader();
+    private static final String BASIC_COMPONENT_CLASSNAME = BasicComponent.class.getName();
 
     private static final String SYNTH_COMPONENT_CLASSNAME = "org.apache.tapestry5.internal.transform.pages.SynthComponent";
 
-    private File extraClasspath;
-
     private ComponentInstantiatorSource source;
 
-    private Registry registry;
-
-    private ClassLoader extraLoader;
+    private ClassCreationHelper helper;
 
-    private String tempDir;
+    private Registry registry;
 
     /**
      * This allows tests the exists() method.
@@ -83,19 +67,16 @@ public class ComponentInstantiatorSource
 
         assertEquals(named.getName(), "Original");
 
-        String path = tempDir + "/" + SYNTH_COMPONENT_CLASSNAME.replace('.', '/') + ".class";
-        URL url = new File(path).toURL();
-
-        long dtm = readDTM(url);
+        long dtm = helper.readDTM(SYNTH_COMPONENT_CLASSNAME);
 
         while (true)
         {
-            if (readDTM(url) != dtm)
+            createSynthComponentClass("Updated");
+
+            if (helper.readDTM(SYNTH_COMPONENT_CLASSNAME) != dtm)
                 break;
 
             // Keep re-writing the file until we see the DTM change.
-
-            createSynthComponentClass("Updated");
         }
 
         // Detect the change and clear out the internal caches
@@ -111,34 +92,22 @@ public class ComponentInstantiatorSource
         assertEquals(named.getName(), "Updated");
     }
 
-    private long readDTM(URL url) throws Exception
-    {
-        URLConnection connection = url.openConnection();
 
-        connection.connect();
-
-        return connection.getLastModified();
-    }
-
-    private void createSynthComponentClass(String name) throws CannotCompileException, NotFoundException,
IOException
+    private void createSynthComponentClass(String name) throws Exception
     {
-        ClassPool pool = new ClassPool();
-        // Inside Maven Surefire, the system classpath is not sufficient to find all
-        // the necessary files.
-        pool.appendClassPath(new LoaderClassPath(extraLoader));
+        ClassWriter cw = helper.createWriter(SYNTH_COMPONENT_CLASSNAME, BASIC_COMPONENT_CLASSNAME,
Named.class.getName());
 
-        CtClass ctClass = pool.makeClass(SYNTH_COMPONENT_CLASSNAME);
+        helper.implementPublicConstructor(cw, BASIC_COMPONENT_CLASSNAME);
 
-        ctClass.setSuperclass(pool.get(BasicComponent.class.getName()));
+        MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "getName", "()Ljava/lang/String;",
null, null);
+        mv.visitCode();
+        mv.visitLdcInsn(name);
+        mv.visitInsn(ARETURN);
+        mv.visitEnd();
 
-        // Implement method getName()
+        cw.visitEnd();
 
-        CtMethod method = CtNewMethod.make("public String getName() { return \"" + name +
"\"; }", ctClass);
-        ctClass.addMethod(method);
-
-        ctClass.addInterface(pool.get(Named.class.getName()));
-
-        ctClass.writeFile(extraClasspath.getAbsolutePath());
+        helper.writeFile(cw, SYNTH_COMPONENT_CLASSNAME);
     }
 
     private Component createComponent(String classname)
@@ -159,25 +128,9 @@ public class ComponentInstantiatorSource
     @BeforeClass
     public void setup_tests() throws Exception
     {
-        String tempdir = System.getProperty("java.io.tmpdir");
-        String uid = UUID.randomUUID().toString();
-
-        tempDir = tempdir + "/tapestry-test-classpath/" + uid;
-        extraClasspath = new File(tempDir);
-
-        System.out.println("Creating dir: " + extraClasspath);
-
-        extraClasspath.mkdirs();
-
-        URL url = extraClasspath.toURL();
-
-        extraLoader = new URLClassLoader(new URL[]
-        { url }, contextLoader);
-        RegistryBuilder builder = new RegistryBuilder(extraLoader);
-
-        builder.add(TapestryModule.class, ForceDevelopmentModeModule.class, AddTransformPagesToCISModule.class);
+        helper = new ClassCreationHelper(ForceDevelopmentModeModule.class, AddTransformPagesToCISModule.class);
 
-        registry = builder.build();
+        registry = helper.registry;
 
         source = registry.getService(ComponentInstantiatorSource.class);
     }



Mime
View raw message