org.hibernate.tool.instrument.cglib.InstrumentTask Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of hibernate Show documentation
Show all versions of hibernate Show documentation
Relational Persistence for Java
//$Id: InstrumentTask.java 10209 2006-08-03 20:35:26Z [email protected] $
package org.hibernate.tool.instrument.cglib;
import org.hibernate.bytecode.util.BasicClassFilter;
import org.hibernate.bytecode.util.ClassDescriptor;
import org.hibernate.bytecode.cglib.BytecodeProviderImpl;
import org.hibernate.bytecode.ClassTransformer;
import org.hibernate.tool.instrument.BasicInstrumentationTask;
import org.objectweb.asm.ClassReader;
import java.io.ByteArrayInputStream;
import net.sf.cglib.core.ClassNameReader;
import net.sf.cglib.transform.impl.InterceptFieldEnabled;
/**
* An Ant task for instrumenting persistent classes in order to enable
* field-level interception using CGLIB.
*
* In order to use this task, typically you would define a a taskdef
* similiar to:
*
*
*
*
* where lib.class.path is an ANT path reference containing all the
* required Hibernate and CGLIB libraries.
*
* And then use it like:
*
*
*
* ...
*
*
*
* where the nested ANT fileset includes the class you would like to have
* instrumented.
*
* Optionally you can chose to enable "Extended Instrumentation" if desired
* by specifying the extended attriubute on the task:
*
* ...
*
*
* See the Hibernate manual regarding this option.
*
* @author Gavin King
* @author Steve Ebersole
*/
public class InstrumentTask extends BasicInstrumentationTask {
private static final BasicClassFilter CLASS_FILTER = new BasicClassFilter();
private final BytecodeProviderImpl provider = new BytecodeProviderImpl();
protected ClassDescriptor getClassDescriptor(byte[] byecode) throws Exception {
return new CustomClassDescriptor( byecode );
}
protected ClassTransformer getClassTransformer(ClassDescriptor descriptor) {
if ( descriptor.isInstrumented() ) {
logger.verbose( "class [" + descriptor.getName() + "] already instrumented" );
return null;
}
else {
return provider.getTransformer( CLASS_FILTER, new CustomFieldFilter( descriptor ) );
}
}
private static class CustomClassDescriptor implements ClassDescriptor {
private final byte[] bytecode;
private final String name;
private final boolean isInstrumented;
public CustomClassDescriptor(byte[] bytecode) throws Exception {
this.bytecode = bytecode;
ClassReader reader = new ClassReader( new ByteArrayInputStream( bytecode ) );
String[] names = ClassNameReader.getClassInfo( reader );
this.name = names[0];
boolean instrumented = false;
for ( int i = 1; i < names.length; i++ ) {
if ( InterceptFieldEnabled.class.getName().equals( names[i] ) ) {
instrumented = true;
break;
}
}
this.isInstrumented = instrumented;
}
public String getName() {
return name;
}
public boolean isInstrumented() {
return isInstrumented;
}
public byte[] getBytes() {
return bytecode;
}
}
}