Files
corejava/corejava第8版/v2ch11/LogEntry/EntryLogger.java
T
2019-05-22 19:52:22 +08:00

106 lines
3.2 KiB
Java

import java.io.*;
import org.apache.bcel.*;
import org.apache.bcel.classfile.*;
import org.apache.bcel.generic.*;
/**
* Adds "entering" logs to all methods of a class that have the LogEntry annotation.
* @version 1.10 2007-10-27
* @author Cay Horstmann
*/
public class EntryLogger
{
/**
* Adds entry logging code to the given class
* @param args the name of the class file to patch
*/
public static void main(String[] args)
{
try
{
if (args.length == 0) System.out.println("USAGE: java EntryLogger classname");
else
{
JavaClass jc = Repository.lookupClass(args[0]);
ClassGen cg = new ClassGen(jc);
EntryLogger el = new EntryLogger(cg);
el.convert();
File f = new File(Repository.lookupClassFile(cg.getClassName()).getPath());
cg.getJavaClass().dump(f.getPath());
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
/**
* Constructs an EntryLogger that inserts logging into annotated methods of a given class
* @param cg the class
*/
public EntryLogger(ClassGen cg)
{
this.cg = cg;
cpg = cg.getConstantPool();
}
/**
* converts the class by inserting the logging calls.
*/
public void convert() throws IOException
{
for (Method m : cg.getMethods())
{
AnnotationEntry[] annotations = m.getAnnotationEntries();
for (AnnotationEntry a : annotations)
{
if (a.getAnnotationType().equals("LLogEntry;"))
{
for (ElementValuePair p : a.getElementValuePairs())
{
if (p.getNameString().equals("logger"))
{
String loggerName = p.getValue().stringifyValue();
cg.replaceMethod(m, insertLogEntry(m, loggerName));
}
}
}
}
}
}
/**
* Adds an "entering" call to the beginning of a method.
* @param m the method
* @param loggerName the name of the logger to call
*/
private Method insertLogEntry(Method m, String loggerName)
{
MethodGen mg = new MethodGen(m, cg.getClassName(), cpg);
String className = cg.getClassName();
String methodName = mg.getMethod().getName();
System.out.printf("Adding logging instructions to %s.%s%n", className, methodName);
int getLoggerIndex = cpg.addMethodref("java.util.logging.Logger", "getLogger",
"(Ljava/lang/String;)Ljava/util/logging/Logger;");
int enteringIndex = cpg.addMethodref("java.util.logging.Logger", "entering",
"(Ljava/lang/String;Ljava/lang/String;)V");
InstructionList il = mg.getInstructionList();
InstructionList patch = new InstructionList();
patch.append(new PUSH(cpg, loggerName));
patch.append(new INVOKESTATIC(getLoggerIndex));
patch.append(new PUSH(cpg, className));
patch.append(new PUSH(cpg, methodName));
patch.append(new INVOKEVIRTUAL(enteringIndex));
InstructionHandle[] ihs = il.getInstructionHandles();
il.insert(ihs[0], patch);
mg.setMaxStack();
return mg.getMethod();
}
private ClassGen cg;
private ConstantPoolGen cpg;
}