package com.hapiware.asm.timemachine;
import java.lang.instrument.ClassFileTransformer;
import java.lang.instrument.IllegalClassFormatException;
import java.security.ProtectionDomain;
import java.util.regex.Pattern;
import org.objectweb.asm.ClassAdapter;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.MethodVisitor;
import com.hapiware.asm.timemachine.TimeMachineAgentDelegate.Milliseconds;
/**
* Initialises {@link TimeMachineAdapter} for class manipulation.
*
* @see TimeMachineAdapter
* @see TimeMachineTransformer#transform(ClassLoader, String, Class, ProtectionDomain, byte[])
*
* @author <a href="http://www.hapiware.com" target="_blank">hapi</a>
*
*/
public class TimeMachineTransformer
implements
ClassFileTransformer
{
private Pattern[] _includePatterns;
private Pattern[] _exludePatterns;
private final Milliseconds _timeShift;
public TimeMachineTransformer()
{
_timeShift = null;
}
public TimeMachineTransformer(
Pattern[] includePatterns,
Pattern[] excludePatterns,
Milliseconds timeShift
)
{
_includePatterns = includePatterns;
_exludePatterns = excludePatterns;
_timeShift = timeShift;
}
public byte[] transform(
ClassLoader loader,
final String className,
Class<?> classBeingRedefined,
ProtectionDomain protectionDomain,
byte[] classFileBuffer
)
throws IllegalClassFormatException
{
for(Pattern p : _exludePatterns)
if(p.matcher(className).matches())
return null;
for(Pattern p : _includePatterns) {
if(p.matcher(className).matches())
{
try
{
ClassReader cr = new ClassReader(classFileBuffer);
ClassWriter cw = new ClassWriter(0);
//ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
//ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
cr.accept(
new ClassAdapter(cw)
{
public MethodVisitor visitMethod(
int access,
String name,
String desc,
String signature,
String[] exceptions
)
{
MethodVisitor mv =
super.visitMethod(access, name, desc, signature, exceptions);
return new TimeMachineAdapter(_timeShift, mv);
}
},
0
);
return cw.toByteArray();
}
catch(Throwable e)
{
throw new Error("Instrumentation of a class " + className + " failed.", e);
}
}
}
return null;
}
}