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

« back to all changes in this revision

Viewing changes to src/org/hibernate/tuple/component/PojoComponentTuplizer.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
//$Id: PojoComponentTuplizer.java 9619 2006-03-15 00:12:47Z steve.ebersole@jboss.com $
 
2
package org.hibernate.tuple.component;
 
3
 
 
4
import java.io.Serializable;
 
5
import java.lang.reflect.Method;
 
6
 
 
7
import org.hibernate.AssertionFailure;
 
8
import org.hibernate.HibernateException;
 
9
import org.hibernate.bytecode.BasicProxyFactory;
 
10
import org.hibernate.bytecode.ReflectionOptimizer;
 
11
import org.hibernate.cfg.Environment;
 
12
import org.hibernate.engine.SessionFactoryImplementor;
 
13
import org.hibernate.mapping.Component;
 
14
import org.hibernate.mapping.Property;
 
15
import org.hibernate.property.BackrefPropertyAccessor;
 
16
import org.hibernate.property.Getter;
 
17
import org.hibernate.property.PropertyAccessor;
 
18
import org.hibernate.property.PropertyAccessorFactory;
 
19
import org.hibernate.property.Setter;
 
20
import org.hibernate.tuple.Instantiator;
 
21
import org.hibernate.tuple.PojoInstantiator;
 
22
import org.hibernate.util.ReflectHelper;
 
23
 
 
24
/**
 
25
 * A {@link ComponentTuplizer} specific to the pojo entity mode.
 
26
 *
 
27
 * @author Gavin King
 
28
 * @author Steve Ebersole
 
29
 */
 
30
public class PojoComponentTuplizer extends AbstractComponentTuplizer {
 
31
 
 
32
        private final Class componentClass;
 
33
        private ReflectionOptimizer optimizer;
 
34
        private final Getter parentGetter;
 
35
        private final Setter parentSetter;
 
36
 
 
37
        public PojoComponentTuplizer(Component component) {
 
38
                super( component );
 
39
 
 
40
                this.componentClass = component.getComponentClass();
 
41
 
 
42
                String[] getterNames = new String[propertySpan];
 
43
                String[] setterNames = new String[propertySpan];
 
44
                Class[] propTypes = new Class[propertySpan];
 
45
                for ( int i = 0; i < propertySpan; i++ ) {
 
46
                        getterNames[i] = getters[i].getMethodName();
 
47
                        setterNames[i] = setters[i].getMethodName();
 
48
                        propTypes[i] = getters[i].getReturnType();
 
49
                }
 
50
 
 
51
                final String parentPropertyName = component.getParentProperty();
 
52
                if ( parentPropertyName == null ) {
 
53
                        parentSetter = null;
 
54
                        parentGetter = null;
 
55
                }
 
56
                else {
 
57
                        PropertyAccessor pa = PropertyAccessorFactory.getPropertyAccessor( null );
 
58
                        parentSetter = pa.getSetter( componentClass, parentPropertyName );
 
59
                        parentGetter = pa.getGetter( componentClass, parentPropertyName );
 
60
                }
 
61
 
 
62
                if ( hasCustomAccessors || !Environment.useReflectionOptimizer() ) {
 
63
                        optimizer = null;
 
64
                }
 
65
                else {
 
66
                        // TODO: here is why we need to make bytecode provider global :(
 
67
                        // TODO : again, fix this after HHH-1907 is complete
 
68
                        optimizer = Environment.getBytecodeProvider().getReflectionOptimizer(
 
69
                                        componentClass, getterNames, setterNames, propTypes
 
70
                        );
 
71
                }
 
72
        }
 
73
 
 
74
        public Class getMappedClass() {
 
75
                return componentClass;
 
76
        }
 
77
 
 
78
        public Object[] getPropertyValues(Object component) throws HibernateException {
 
79
                if ( component == BackrefPropertyAccessor.UNKNOWN ) {
 
80
                        return new Object[ propertySpan ];
 
81
                }
 
82
                if ( optimizer != null && optimizer.getAccessOptimizer() != null ) {
 
83
                        return optimizer.getAccessOptimizer().getPropertyValues( component );
 
84
                }
 
85
                else {
 
86
                        return super.getPropertyValues(component);
 
87
                }
 
88
        }
 
89
 
 
90
        public void setPropertyValues(Object component, Object[] values) throws HibernateException {
 
91
                if ( optimizer != null && optimizer.getAccessOptimizer() != null ) {
 
92
                                optimizer.getAccessOptimizer().setPropertyValues( component, values );
 
93
                }
 
94
                else {
 
95
                        super.setPropertyValues(component, values);
 
96
                }
 
97
 
 
98
        }
 
99
 
 
100
        public Object getParent(Object component) {
 
101
                return parentGetter.get( component );
 
102
        }
 
103
 
 
104
        public boolean hasParentProperty() {
 
105
                return parentGetter!=null;
 
106
        }
 
107
 
 
108
        public boolean isMethodOf(Method method) {
 
109
                for ( int i=0; i<propertySpan; i++ ) {
 
110
                        final Method getterMethod = getters[i].getMethod();
 
111
                        if ( getterMethod!=null && getterMethod.equals(method) ) return true;
 
112
                }
 
113
                return false;
 
114
        }
 
115
 
 
116
        public void setParent(Object component, Object parent, SessionFactoryImplementor factory) {
 
117
                parentSetter.set(component, parent, factory);
 
118
        }
 
119
 
 
120
        protected Instantiator buildInstantiator(Component component) {
 
121
                if ( component.isEmbedded() && ReflectHelper.isAbstractClass( component.getComponentClass() ) ) {
 
122
                        return new ProxiedInstantiator( component );
 
123
                }
 
124
                if ( optimizer == null ) {
 
125
                        return new PojoInstantiator( component, null );
 
126
                }
 
127
                else {
 
128
                        return new PojoInstantiator( component, optimizer.getInstantiationOptimizer() );
 
129
                }
 
130
        }
 
131
 
 
132
        protected Getter buildGetter(Component component, Property prop) {
 
133
                return prop.getGetter( component.getComponentClass() );
 
134
        }
 
135
 
 
136
        protected Setter buildSetter(Component component, Property prop) {
 
137
                return prop.getSetter( component.getComponentClass() );
 
138
        }
 
139
 
 
140
        private static class ProxiedInstantiator implements Instantiator {
 
141
                private final Class proxiedClass;
 
142
                private final BasicProxyFactory factory;
 
143
 
 
144
                public ProxiedInstantiator(Component component) {
 
145
                        proxiedClass = component.getComponentClass();
 
146
                        if ( proxiedClass.isInterface() ) {
 
147
                                factory = Environment.getBytecodeProvider()
 
148
                                                .getProxyFactoryFactory()
 
149
                                                .buildBasicProxyFactory( null, new Class[] { proxiedClass } );
 
150
                        }
 
151
                        else {
 
152
                                factory = Environment.getBytecodeProvider()
 
153
                                                .getProxyFactoryFactory()
 
154
                                                .buildBasicProxyFactory( proxiedClass, null );
 
155
                        }
 
156
                }
 
157
 
 
158
                public Object instantiate(Serializable id) {
 
159
                        throw new AssertionFailure( "ProxiedInstantiator can only be used to instantiate component" );
 
160
                }
 
161
 
 
162
                public Object instantiate() {
 
163
                        return factory.getProxy();
 
164
                }
 
165
 
 
166
                public boolean isInstance(Object object) {
 
167
                        return proxiedClass.isInstance( object );
 
168
                }
 
169
        }
 
170
}