~ubuntu-branches/ubuntu/wily/libhibernate3-java/wily-proposed

« back to all changes in this revision

Viewing changes to src/org/hibernate/bytecode/cglib/ProxyFactoryFactoryImpl.java

  • Committer: Bazaar Package Importer
  • Author(s): Torsten Werner
  • Date: 2007-10-14 14:43:34 UTC
  • Revision ID: james.westby@ubuntu.com-20071014144334-eamc8i0q10gs1aro
Tags: upstream-3.2.5
ImportĀ upstreamĀ versionĀ 3.2.5

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
}