Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

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 }