package com.highway2urhell.transformer; import javassist.*; import javassist.expr.ExprEditor; import javassist.expr.MethodCall; import java.lang.instrument.ClassFileTransformer; import java.lang.instrument.IllegalClassFormatException; import java.security.ProtectionDomain; import java.util.ArrayList; import java.util.Arrays; import java.util.List; public abstract class AbstractLeechTransformer implements ClassFileTransformer { private final String classNameToTransformNormalized; private final String classNameToTransform; private List<String> importPackages = new ArrayList<String>(); public AbstractLeechTransformer(String classNameToTransform) { this.classNameToTransform = classNameToTransform; this.classNameToTransformNormalized = classNameToTransform.replace("/", "."); addImportPackage( "com.highway2urhell", "com.highway2urhell.domain", "com.highway2urhell.service", "com.highway2urhell.transformer"); } protected void addImportPackage(String... packages) { addImportPackage(Arrays.asList(packages)); } protected void addImportPackage(Iterable<String> packages) { for (String packageName : packages) { this.importPackages.add(packageName); } } public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException { if (className.equals(classNameToTransform)) { System.out.println("Going to Transform "+classNameToTransform+ this.getClass()); try { ClassPool cp = ClassPool.getDefault(); cp.insertClassPath(new LoaderClassPath(loader)); for (String importPackage : importPackages) { cp.importPackage(importPackage); } CtClass cc = cp.get(classNameToTransformNormalized); grabAllMethod(cc); doTransform(cc); classfileBuffer = cc.toBytecode(); cc.detach(); } catch (NotFoundException ex) { System.err.println("not found "+ ex); } catch (Exception ex) { System.err.println("Fail to Transform " +classNameToTransform+"with : "+this.getClass()+ ex); } } return classfileBuffer; } private void grabAllMethod(CtClass cc) { for (CtMethod method : cc.getMethods()) { System.err.println(method.getLongName() + "-" + method.getSignature() + " at line " + method.getMethodInfo().getLineNumber(0)); try { method.instrument( new ExprEditor() { public void edit(MethodCall m) throws CannotCompileException { System.err.println("method invoke into the method observe "+m.getClassName() + "." + m.getMethodName() + " " + m.getSignature()); } }); } catch (CannotCompileException e) { System.err.println("Cannot Compil Exception"+e.getMessage()); } } for (CtConstructor c : cc.getConstructors()) { System.err.println(c.getLongName() + "-" + c.getSignature()+" at line "+c.getMethodInfo().getLineNumber(0)); } } /** * Build receiveDataStatement to be produced by transformer where you want to collectdata * * @param frameworkName a given frameworkname to invoke * @param dataToCollect statement representing data * @return produced statement */ public String buildReceiveDataStatement(String frameworkName, String dataToCollect) { return "CoreEngine.getInstance().getFramework(\"" + frameworkName + "\").receiveData(" + dataToCollect + ");"; } protected abstract void doTransform(CtClass cc) throws Exception; }