//: net/mindview/atunit/AtUnitRemover.java // Displays @Unit annotations in compiled class files. If // first argument is "-r", @Unit annotations are removed. // {Args: ..} // {Requires: javassist.bytecode.ClassFile; // You must install the Javassist library from // http://sourceforge.net/projects/jboss/ } package net.mindview.atunit; import javassist.ClassPool; import javassist.CtClass; import javassist.CtMethod; import javassist.bytecode.AnnotationsAttribute; import javassist.bytecode.MethodInfo; import javassist.bytecode.annotation.Annotation; import net.mindview.util.BinaryFile; import net.mindview.util.ProcessFiles; import java.io.DataOutputStream; import java.io.File; import java.io.FileOutputStream; import static net.mindview.util.Print.print; public class AtUnitRemover implements ProcessFiles.Strategy { private static boolean remove = false; public static void main(String[] args) throws Exception { if (args.length > 0 && args[0].equals("-r")) { remove = true; String[] nargs = new String[args.length - 1]; System.arraycopy(args, 1, nargs, 0, nargs.length); args = nargs; } new ProcessFiles(new AtUnitRemover(), "class").start(args); } public void process(File cFile) { boolean modified = false; try { String cName = ClassNameFinder.thisClass(BinaryFile.read(cFile)); if (!cName.contains(".")) return; // Ignore unpackaged classes ClassPool cPool = ClassPool.getDefault(); CtClass ctClass = cPool.get(cName); for (CtMethod method : ctClass.getDeclaredMethods()) { MethodInfo mi = method.getMethodInfo(); AnnotationsAttribute attr = (AnnotationsAttribute) mi .getAttribute(AnnotationsAttribute.visibleTag); if (attr == null) continue; for (Annotation ann : attr.getAnnotations()) { if (ann.getTypeName().startsWith("net.mindview.atunit")) { print(ctClass.getName() + " Method: " + mi.getName() + " " + ann); if (remove) { ctClass.removeMethod(method); modified = true; } } } } // Fields are not removed in this version (see text). if (modified) ctClass.toBytecode(new DataOutputStream(new FileOutputStream( cFile))); ctClass.detach(); } catch (Exception e) { throw new RuntimeException(e); } } } // /:~