1
package org.hibernate.bytecode.cglib;
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;
17
import java.lang.reflect.Method;
18
import java.util.HashMap;
21
* A factory for CGLIB-based {@link ProxyFactory} instances.
23
* @author Steve Ebersole
25
public class ProxyFactoryFactoryImpl implements ProxyFactoryFactory {
28
* Builds a CGLIB-based proxy factory.
30
* @return a new CGLIB-based proxy factory.
32
public ProxyFactory buildProxyFactory() {
33
return new CGLIBProxyFactory();
36
public BasicProxyFactory buildBasicProxyFactory(Class superClass, Class[] interfaces) {
37
return new BasicProxyFactoryImpl( superClass, interfaces );
40
public static class BasicProxyFactoryImpl implements BasicProxyFactory {
41
private final Class proxyClass;
42
private final Factory factory;
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" );
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 );
58
if ( interfaces != null && interfaces.length > 0 ) {
59
en.setInterfaces( interfaces );
61
proxyClass = en.createClass();
63
factory = ( Factory ) proxyClass.newInstance();
65
catch ( Throwable t ) {
66
throw new HibernateException( "Unable to build CGLIB Factory instance" );
70
public Object getProxy() {
72
return factory.newInstance(
73
new Callback[] { new PassThroughInterceptor( proxyClass.getName() ), NoOp.INSTANCE }
76
catch ( Throwable t ) {
77
throw new HibernateException( "Unable to instantiate proxy instance" );
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") ){
93
private static final Class[] CALLBACK_TYPES = new Class[] { MethodInterceptor.class, NoOp.class };
95
private static class PassThroughInterceptor implements MethodInterceptor {
96
private HashMap data = new HashMap();
97
private final String proxiedClassName;
99
public PassThroughInterceptor(String proxiedClassName) {
100
this.proxiedClassName = proxiedClassName;
103
public Object intercept(
107
MethodProxy proxy) throws Throwable {
108
String name = method.getName();
109
if ( "toString".equals( name ) ) {
110
return proxiedClassName + "@" + System.identityHashCode( obj );
112
else if ( "equals".equals( name ) ) {
113
return args[0] instanceof Factory && ( ( Factory ) args[0] ).getCallback( 0 ) == this
117
else if ( "hashCode".equals( name ) ) {
118
return new Integer( System.identityHashCode( obj ) );
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 );
126
else if ( name.startsWith( "is" ) && hasGetterSignature ) {
127
String propName = name.substring( 2 );
128
return data.get( propName );
130
else if ( name.startsWith( "set" ) && hasSetterSignature) {
131
String propName = name.substring( 3 );
132
data.put( propName, args[0] );
136
// todo : what else to do here?