Created
September 8, 2012 12:03
-
-
Save nallachaitu/3674230 to your computer and use it in GitHub Desktop.
class generation -- I have added the name lukas for the areas you need to take a look
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package org.jboss.arquillian.qunit.junit; | |
//Javassist jar is needed to run this code. | |
import java.lang.reflect.Modifier; | |
import java.util.ArrayList; | |
import java.util.HashMap; | |
import java.util.Iterator; | |
import java.util.List; | |
import java.util.Set; | |
import javassist.CannotCompileException; | |
import javassist.ClassClassPath; | |
import javassist.ClassPool; | |
import javassist.CtClass; | |
import javassist.CtField; | |
import javassist.CtMethod; | |
import javassist.CtNewMethod; | |
import javassist.bytecode.AnnotationsAttribute; | |
import javassist.bytecode.ClassFile; | |
import javassist.bytecode.ConstPool; | |
import javassist.bytecode.annotation.Annotation; | |
import javassist.compiler.MemberResolver.Method; | |
public class ClassGenerator | |
{ | |
//Given a class Name and a list of method names,it generates | |
//a class that contain generated methods with a dummy stub. | |
public Class<?> getClass(String className, List<String> list) throws CannotCompileException | |
{ | |
try | |
{ | |
ClassPool pool = ClassPool.getDefault(); | |
//adding the classes in the target of this project --- Lukas you need to change it to point it to appropriate path | |
String path = "C:\\Users\\nallacha\\arquillian-qunit\\target\\classes\\org\\jboss\\arquillian\\qunit\\junit"; | |
pool.insertClassPath(path); | |
// pool.appendClassPath("C:\Users\nallacha\.m2\repository\org\seleniumhq\selenium\selenium-java\2.24.1\"); | |
// adding the classpath of the ClassGenerator class to include the search path for finding the ClassGenerator class. | |
pool.insertClassPath(new ClassClassPath(this.getClass())); | |
// Lukas -- i have tried adding the WebDriver classes path like below but it is not working. | |
//String WebDriverPath = "C:\\Users\\nallacha\\.m2\\repository\\org\\seleniumhq\\selenium\\selenium-java\\2.24.1\\org\\openqa\\selenium"; | |
//pool.insertClassPath(WebDriverPath); | |
//importing WebDriver as it is needed | |
pool.importPackage("org.openqa.selenium.WebDriver"); | |
// create the class | |
CtClass class_ = pool.makeClass(className); | |
/* | |
* adding WebDriver as a field | |
* For defining the type of the field,a CtClass should be created. | |
* representing the WebDriver. | |
* | |
*/ | |
ClassFile classFile = class_.getClassFile(); | |
ConstPool constPool = classFile.getConstPool(); | |
CtClass WebDriver_ = pool.getCtClass("WebDriver"); | |
//making WebDriver as an instance of the generated Class with @Drone annotation | |
CtField browser_ = new CtField(WebDriver_,"browser",class_); | |
//adding an annotation. | |
AnnotationsAttribute attr = new AnnotationsAttribute(constPool, AnnotationsAttribute.visibleTag); | |
Annotation annotation = new Annotation("org.arquillian.drone", constPool); | |
//TODO: need to add a drone annotation to the field browser_. | |
attr.addAnnotation(annotation); | |
class_.addField(browser_); | |
CtClass String_ = pool.getCtClass("String"); | |
String methodStub = ""; | |
// create the methods | |
for (String methodName : list) | |
{ | |
/* There are two ways of creating methods. First one is to create a method and add parameters, method body | |
* second way is to create abstract method with parameters and later add the method body. | |
* | |
* methodStub = "public void " +methodName+ "() {}"; | |
* CtMethod method = CtNewMethod.make(methodStub, class_); | |
* method.addParameter(WebDriver_); | |
* method.addParameter(String_); | |
* method.addParameter(String_); | |
* method.insertAfter("TestHandler.runQunitMethod($$);"); | |
*/ | |
/* Doing it by creating a abstract method first and making it non abstract later. | |
* The generated method takes first parameter type as WebDriver | |
* second type as String, third type as String | |
*/ | |
CtMethod method = new CtMethod(CtClass.voidType,methodName,new CtClass[]{WebDriver_,String_,String_},class_); | |
class_.addMethod(method); | |
method.setBody("TestHandler.runQunitMethod($$);"); | |
// create the annotation test for the constructed method | |
//AnnotationsAttribute attr = new AnnotationsAttribute(constPool, AnnotationsAttribute.visibleTag); | |
annotation = new Annotation("org.junit.Test", constPool); | |
attr.addAnnotation(annotation); | |
//add the annotation to the method | |
method.getMethodInfo().addAttribute(attr); | |
} | |
//changing all the methods from abstract to non-abstract. | |
class_.setModifiers(class_.getModifiers() & ~Modifier.ABSTRACT); | |
Class<?> generatedClass = class_.toClass(); | |
return generatedClass; | |
} catch (Exception e) { | |
e.printStackTrace(); | |
System.out.println("hello"); | |
throw new IllegalStateException(e); | |
} | |
} | |
//GetClasses takes a HashMap of class names corresponds to respective | |
//method names. | |
public List<Class<?>> getClasses(HashMap<String,List<String>> classes ) throws CannotCompileException //to be implemented | |
{ | |
List<Class<?>> classes_ = new ArrayList<Class<?>>(); | |
Set<String> names = classes.keySet(); | |
for(String name : names) | |
{ | |
classes_.add(getClass(name, classes.get(name))); | |
} | |
return classes_; | |
} | |
public static void main(String[] args) throws CannotCompileException | |
{ | |
ClassGenerator test = new ClassGenerator(); | |
ArrayList<String> names = new ArrayList<String>(); | |
names.add("method1"); | |
names.add("method2"); | |
Class<?> class_ = test.getClass("nalla",names); | |
System.out.println("class name: " + class_.getName()); | |
java.lang.reflect.Method[] methods = class_.getDeclaredMethods(); | |
System.out.println("method names: " + methods.length); | |
//How to call the methods using the class file once they are generated | |
/* ClassGenerator test = new ClassGenerator(); | |
ArrayList<String> names = new ArrayList<String>(); | |
names.add("hello"); | |
try { | |
Class<?> class_ = test.getClass("god",names); | |
} catch (CannotCompileException e) { | |
// TODO Auto-generated catch block | |
e.printStackTrace(); | |
}*/ | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment