| Home >> All >> org >> hibernate >> bytecode >> [ javassist Javadoc ] |
Source code: org/hibernate/bytecode/javassist/JavassistClassTransformer.java
1 //$Id: $ 2 package org.hibernate.bytecode.javassist; 3 4 import java.io.ByteArrayInputStream; 5 import java.io.ByteArrayOutputStream; 6 import java.io.DataInputStream; 7 import java.io.DataOutputStream; 8 import java.io.IOException; 9 import java.security.ProtectionDomain; 10 11 import javassist.bytecode.ClassFile; 12 import org.apache.commons.logging.Log; 13 import org.apache.commons.logging.LogFactory; 14 import org.hibernate.HibernateException; 15 import org.hibernate.bytecode.AbstractClassTransformerImpl; 16 import org.hibernate.tool.instrument.javassist.FieldFilter; 17 import org.hibernate.tool.instrument.javassist.FieldHandled; 18 import org.hibernate.tool.instrument.javassist.FieldTransformer; 19 20 /** 21 * Enhance the classes allowing them to implements InterceptFieldEnabled 22 * This interface is then used by Hibernate for some optimizations. 23 * 24 * @author Emmanuel Bernard 25 */ 26 public class JavassistClassTransformer extends AbstractClassTransformerImpl { 27 28 private static Log log = LogFactory.getLog( JavassistClassTransformer.class.getName() ); 29 30 public JavassistClassTransformer(String[] packages, String[] classes) { 31 super(packages, classes); 32 } 33 34 protected byte[] doTransform( 35 ClassLoader loader, 36 String className, 37 Class classBeingRedefined, 38 ProtectionDomain protectionDomain, 39 byte[] classfileBuffer) { 40 ClassFile classfile; 41 try { 42 // WARNING: classfile only 43 classfile = new ClassFile( new DataInputStream( new ByteArrayInputStream( classfileBuffer ) ) ); 44 } 45 catch (IOException e) { 46 log.error( "Unable to build enhancement metamodel for " + className ); 47 return classfileBuffer; 48 } 49 FieldTransformer transformer = getFieldTransformer( classfile ); 50 if ( transformer != null ) { 51 if ( log.isDebugEnabled() ) { 52 log.debug( "Enhancing " + className ); 53 } 54 DataOutputStream out = null; 55 try { 56 transformer.transform( classfile ); 57 ByteArrayOutputStream byteStream = new ByteArrayOutputStream(); 58 out = new DataOutputStream( byteStream ); 59 classfile.write( out ); 60 return byteStream.toByteArray(); 61 } 62 catch (Exception e) { 63 log.error( "Unable to transform class", e ); 64 throw new HibernateException( "Unable to transform class: " + e.getMessage() ); 65 } 66 finally { 67 try { 68 if ( out != null ) out.close(); 69 } 70 catch (IOException e) { 71 //swallow 72 } 73 } 74 } 75 return classfileBuffer; 76 } 77 78 protected FieldTransformer getFieldTransformer(ClassFile classfile) { 79 if ( alreadyInstrumented( classfile ) ) { 80 return null; 81 } 82 else { 83 return new FieldTransformer( 84 new FieldFilter() { 85 public boolean handleRead(String desc, String name) { 86 return true; 87 } 88 89 public boolean handleWrite(String desc, String name) { 90 return true; 91 } 92 } 93 ); 94 } 95 } 96 97 private boolean alreadyInstrumented(ClassFile classfile) { 98 String[] intfs = classfile.getInterfaces(); 99 for ( int i = 0; i < intfs.length; i++ ) { 100 if ( FieldHandled.class.getName().equals( intfs[i] ) ) { 101 return true; 102 } 103 } 104 return false; 105 } 106 }