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

Quick Search    Search Deep

Source code: org/hibernate/bytecode/cglib/ProxyFactoryFactoryImpl.java


1   package org.hibernate.bytecode.cglib;
2   
3   import org.hibernate.bytecode.ProxyFactoryFactory;
4   import org.hibernate.bytecode.BasicProxyFactory;
5   import org.hibernate.proxy.ProxyFactory;
6   import org.hibernate.proxy.pojo.cglib.CGLIBProxyFactory;
7   import org.hibernate.AssertionFailure;
8   import org.hibernate.HibernateException;
9   import net.sf.cglib.proxy.Enhancer;
10  import net.sf.cglib.proxy.CallbackFilter;
11  import net.sf.cglib.proxy.MethodInterceptor;
12  import net.sf.cglib.proxy.MethodProxy;
13  import net.sf.cglib.proxy.NoOp;
14  import net.sf.cglib.proxy.Callback;
15  import net.sf.cglib.proxy.Factory;
16  
17  import java.lang.reflect.Method;
18  import java.util.HashMap;
19  
20  /**
21   * A factory for CGLIB-based {@link ProxyFactory} instances.
22   *
23   * @author Steve Ebersole
24   */
25  public class ProxyFactoryFactoryImpl implements ProxyFactoryFactory {
26  
27    /**
28     * Builds a CGLIB-based proxy factory.
29     *
30     * @return a new CGLIB-based proxy factory.
31     */
32    public ProxyFactory buildProxyFactory() {
33      return new CGLIBProxyFactory();
34    }
35  
36    public BasicProxyFactory buildBasicProxyFactory(Class superClass, Class[] interfaces) {
37      return new BasicProxyFactoryImpl( superClass, interfaces );
38    }
39  
40    public static class BasicProxyFactoryImpl implements BasicProxyFactory {
41      private final Class proxyClass;
42      private final Factory factory;
43  
44      public BasicProxyFactoryImpl(Class superClass, Class[] interfaces) {
45        if ( superClass == null && ( interfaces == null || interfaces.length < 1 ) ) {
46          throw new AssertionFailure( "attempting to build proxy without any superclass or interfaces" );
47        }
48  
49        Enhancer en = new Enhancer();
50        en.setUseCache( false );
51        en.setInterceptDuringConstruction( false );
52        en.setUseFactory( true );
53        en.setCallbackTypes( CALLBACK_TYPES );
54        en.setCallbackFilter( FINALIZE_FILTER );
55        if ( superClass != null ) {
56          en.setSuperclass( superClass );
57        }
58        if ( interfaces != null && interfaces.length > 0 ) {
59          en.setInterfaces( interfaces );
60        }
61        proxyClass = en.createClass();
62        try {
63          factory = ( Factory ) proxyClass.newInstance();
64        }
65        catch ( Throwable t ) {
66          throw new HibernateException( "Unable to build CGLIB Factory instance" );
67        }
68      }
69  
70      public Object getProxy() {
71        try {
72          return factory.newInstance(
73              new Callback[] { new PassThroughInterceptor( proxyClass.getName() ), NoOp.INSTANCE }
74          );
75        }
76        catch ( Throwable t ) {
77          throw new HibernateException( "Unable to instantiate proxy instance" );
78        }
79      }
80    }
81  
82    private static final CallbackFilter FINALIZE_FILTER = new CallbackFilter() {
83      public int accept(Method method) {
84        if ( method.getParameterTypes().length == 0 && method.getName().equals("finalize") ){
85          return 1;
86        }
87        else {
88          return 0;
89        }
90      }
91    };
92  
93    private static final Class[] CALLBACK_TYPES = new Class[] { MethodInterceptor.class, NoOp.class };
94  
95    private static class PassThroughInterceptor implements MethodInterceptor {
96      private HashMap data = new HashMap();
97      private final String proxiedClassName;
98  
99      public PassThroughInterceptor(String proxiedClassName) {
100       this.proxiedClassName = proxiedClassName;
101     }
102 
103     public Object intercept(
104         Object obj,
105             Method method,
106             Object[] args,
107             MethodProxy proxy) throws Throwable {
108       String name = method.getName();
109       if ( "toString".equals( name ) ) {
110         return proxiedClassName + "@" + System.identityHashCode( obj );
111       }
112       else if ( "equals".equals( name ) ) {
113         return args[0] instanceof Factory && ( ( Factory ) args[0] ).getCallback( 0 ) == this
114             ? Boolean.TRUE
115                   : Boolean.FALSE;
116       }
117       else if ( "hashCode".equals( name ) ) {
118         return new Integer( System.identityHashCode( obj ) );
119       }
120       boolean hasGetterSignature = method.getParameterTypes().length == 0 && method.getReturnType() != null;
121       boolean hasSetterSignature = method.getParameterTypes().length == 1 && ( method.getReturnType() == null || method.getReturnType() == void.class );
122       if ( name.startsWith( "get" ) && hasGetterSignature ) {
123         String propName = name.substring( 3 );
124         return data.get( propName );
125       }
126       else if ( name.startsWith( "is" ) && hasGetterSignature ) {
127         String propName = name.substring( 2 );
128         return data.get( propName );
129       }
130       else if ( name.startsWith( "set" ) && hasSetterSignature) {
131         String propName = name.substring( 3 );
132         data.put( propName, args[0] );
133         return null;
134       }
135       else {
136         // todo : what else to do here?
137         return null;
138       }
139     }
140   }
141 }