KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > hibernate > tuple > AbstractEntityTuplizer


1 // $Id: AbstractEntityTuplizer.java,v 1.2 2005/07/16 22:20:47 oneovthafew Exp $
2
package org.hibernate.tuple;
3
4 import java.io.Serializable JavaDoc;
5 import java.util.Iterator JavaDoc;
6 import java.util.Map JavaDoc;
7 import java.util.Set JavaDoc;
8
9 import org.hibernate.EntityMode;
10 import org.hibernate.HibernateException;
11 import org.hibernate.MappingException;
12 import org.hibernate.engine.SessionFactoryImplementor;
13 import org.hibernate.engine.SessionImplementor;
14 import org.hibernate.id.Assigned;
15 import org.hibernate.intercept.LazyPropertyInitializer;
16 import org.hibernate.mapping.Component;
17 import org.hibernate.mapping.PersistentClass;
18 import org.hibernate.mapping.Property;
19 import org.hibernate.property.Getter;
20 import org.hibernate.property.Setter;
21 import org.hibernate.proxy.ProxyFactory;
22 import org.hibernate.type.AbstractComponentType;
23 import org.hibernate.type.ComponentType;
24
25
26 /**
27  * Support base class for EntityTuplizer implementations.
28  *
29  * @author Steve Ebersole
30  */

31 public abstract class AbstractEntityTuplizer implements EntityTuplizer {
32
33     //TODO: currently keeps Getters and Setters (instead of PropertyAccessors) because of the way getGetter() and getSetter() are implemented currently; yuck!
34

35     private final EntityMetamodel entityMetamodel;
36
37     private final Getter idGetter;
38     private final Setter idSetter;
39
40     protected final Getter[] getters;
41     protected final Setter[] setters;
42     protected final int propertySpan;
43     protected final boolean hasCustomAccessors;
44     private final Instantiator instantiator;
45     private final ProxyFactory proxyFactory;
46     private final AbstractComponentType identifierMapperType;
47
48
49     /**
50      * Return the entity-mode handled by this tuplizer instance.
51      *
52      * @return The entity-mode
53      */

54     protected abstract EntityMode getEntityMode();
55
56     /**
57      * Build an appropriate Getter for the given property.
58      *
59      * @param mappedProperty The property to be accessed via the built Getter.
60      * @param mappedEntity The entity information regarding the mapped entity owning this property.
61      * @return An appropriate Getter instance.
62      */

63     protected abstract Getter buildPropertyGetter(Property mappedProperty, PersistentClass mappedEntity);
64
65     /**
66      * Build an appropriate Setter for the given property.
67      *
68      * @param mappedProperty The property to be accessed via the built Setter.
69      * @param mappedEntity The entity information regarding the mapped entity owning this property.
70      * @return An appropriate Setter instance.
71      */

72     protected abstract Setter buildPropertySetter(Property mappedProperty, PersistentClass mappedEntity);
73
74     /**
75      * Build an appropriate Instantiator for the given mapped entity.
76      *
77      * @param mappingInfo The mapping information regarding the mapped entity.
78      * @return An appropriate Instantiator instance.
79      */

80     protected abstract Instantiator buildInstantiator(PersistentClass mappingInfo);
81
82     /**
83      * Build an appropriate ProxyFactory for the given mapped entity.
84      *
85      * @param mappingInfo The mapping information regarding the mapped entity.
86      * @param idGetter The constructed Getter relating to the entity's id property.
87      * @param idSetter The constructed Setter relating to the entity's id property.
88      * @return An appropriate ProxyFactory instance.
89      */

90     protected abstract ProxyFactory buildProxyFactory(PersistentClass mappingInfo, Getter idGetter, Setter idSetter);
91
92     /**
93      * Constructs a new AbstractEntityTuplizer instance.
94      *
95      * @param entityMetamodel The "interpreted" information relating to the mapped entity.
96      * @param mappingInfo The parsed "raw" mapping data relating to the given entity.
97      */

98     public AbstractEntityTuplizer(EntityMetamodel entityMetamodel, PersistentClass mappingInfo) {
99         this.entityMetamodel = entityMetamodel;
100
101         if ( !entityMetamodel.getIdentifierProperty().isVirtual() ) {
102             idGetter = buildPropertyGetter( mappingInfo.getIdentifierProperty(), mappingInfo );
103             idSetter = buildPropertySetter( mappingInfo.getIdentifierProperty(), mappingInfo );
104         }
105         else {
106             idGetter = null;
107             idSetter = null;
108         }
109
110         propertySpan = entityMetamodel.getPropertySpan();
111
112         getters = new Getter[propertySpan];
113         setters = new Setter[propertySpan];
114
115         Iterator JavaDoc iter = mappingInfo.getPropertyClosureIterator();
116         boolean foundCustomAccessor=false;
117         int i=0;
118         while ( iter.hasNext() ) {
119             //TODO: redesign how PropertyAccessors are acquired...
120
Property property = (Property) iter.next();
121             getters[i] = buildPropertyGetter(property, mappingInfo);
122             setters[i] = buildPropertySetter(property, mappingInfo);
123             if ( !property.isBasicPropertyAccessor() ) foundCustomAccessor = true;
124             i++;
125         }
126         hasCustomAccessors = foundCustomAccessor;
127
128         instantiator = buildInstantiator( mappingInfo );
129
130         if ( entityMetamodel.isLazy() ) {
131             proxyFactory = buildProxyFactory( mappingInfo, idGetter, idSetter );
132         }
133         else {
134             proxyFactory = null;
135         }
136         
137         Component mapper = mappingInfo.getIdentifierMapper();
138         identifierMapperType = mapper==null ? null : (AbstractComponentType) mapper.getType();
139     }
140
141     /** Retreives the defined entity-name for the tuplized entity.
142      *
143      * @return The entity-name.
144      */

145     protected String JavaDoc getEntityName() {
146         return entityMetamodel.getName();
147     }
148
149     /**
150      * Retreives the defined entity-names for any subclasses defined for this
151      * entity.
152      *
153      * @return Any subclass entity-names.
154      */

155     protected Set JavaDoc getSubclassEntityNames() {
156         return entityMetamodel.getSubclassEntityNames();
157     }
158
159     public Serializable JavaDoc getIdentifier(Object JavaDoc entity) throws HibernateException {
160         final Object JavaDoc id;
161         if ( entityMetamodel.getIdentifierProperty().isEmbedded() ) {
162             id = entity;
163         }
164         else {
165             if ( idGetter == null ) {
166                 if (identifierMapperType==null) {
167                     throw new HibernateException( "The class has no identifier property: " + getEntityName() );
168                 }
169                 else {
170                     ComponentType copier = (ComponentType) entityMetamodel.getIdentifierProperty().getType();
171                     id = copier.instantiate( getEntityMode() );
172                     copier.setPropertyValues( id, identifierMapperType.getPropertyValues( entity, getEntityMode() ), getEntityMode() );
173                 }
174             }
175             else {
176                 id = idGetter.get( entity );
177             }
178         }
179
180         try {
181             return (Serializable JavaDoc) id;
182         }
183         catch ( ClassCastException JavaDoc cce ) {
184             StringBuffer JavaDoc msg = new StringBuffer JavaDoc( "Identifier classes must be serializable. " );
185             if ( id != null ) {
186                 msg.append( id.getClass().getName() + " is not serializable. " );
187             }
188             if ( cce.getMessage() != null ) {
189                 msg.append( cce.getMessage() );
190             }
191             throw new ClassCastException JavaDoc( msg.toString() );
192         }
193     }
194
195
196     public void setIdentifier(Object JavaDoc entity, Serializable JavaDoc id) throws HibernateException {
197         if ( entityMetamodel.getIdentifierProperty().isEmbedded() ) {
198             if ( entity != id ) {
199                 AbstractComponentType copier = (AbstractComponentType) entityMetamodel.getIdentifierProperty().getType();
200                 copier.setPropertyValues( entity, copier.getPropertyValues( id, getEntityMode() ), getEntityMode() );
201             }
202         }
203         else if ( idSetter != null ) {
204             idSetter.set( entity, id, getFactory() );
205         }
206     }
207
208     public void resetIdentifier(Object JavaDoc entity, Serializable JavaDoc currentId, Object JavaDoc currentVersion) {
209         if ( entityMetamodel.getIdentifierProperty().getIdentifierGenerator() instanceof Assigned ) {
210             //return currentId;
211
}
212         else {
213             //reset the id
214
Serializable JavaDoc result = entityMetamodel.getIdentifierProperty()
215                     .getUnsavedValue()
216                     .getDefaultValue( currentId );
217             setIdentifier( entity, result );
218             //reset the version
219
VersionProperty versionProperty = entityMetamodel.getVersionProperty();
220             if ( entityMetamodel.isVersioned() ) {
221                 setPropertyValue(
222                         entity,
223                         entityMetamodel.getVersionPropertyIndex(),
224                         versionProperty.getUnsavedValue().getDefaultValue( currentVersion )
225                     );
226             }
227             //return the id, so we can use it to reset the proxy id
228
//return result;
229
}
230     }
231
232     public Object JavaDoc getVersion(Object JavaDoc entity) throws HibernateException {
233         if ( !entityMetamodel.isVersioned() ) return null;
234         return getters[ entityMetamodel.getVersionPropertyIndex() ].get( entity );
235     }
236
237     protected boolean shouldGetAllProperties(Object JavaDoc entity) {
238         return !hasUninitializedLazyProperties( entity );
239     }
240
241     public Object JavaDoc[] getPropertyValues(Object JavaDoc entity) throws HibernateException {
242         boolean getAll = shouldGetAllProperties( entity );
243         final int span = entityMetamodel.getPropertySpan();
244         final Object JavaDoc[] result = new Object JavaDoc[span];
245
246         for ( int j = 0; j < span; j++ ) {
247             StandardProperty property = entityMetamodel.getProperties()[j];
248             if ( getAll || !property.isLazy() ) {
249                 result[j] = getters[j].get( entity );
250             }
251             else {
252                 result[j] = LazyPropertyInitializer.UNFETCHED_PROPERTY;
253             }
254         }
255         return result;
256     }
257
258     public Object JavaDoc[] getPropertyValuesToInsert(Object JavaDoc entity, Map JavaDoc mergeMap, SessionImplementor session)
259     throws HibernateException {
260         final int span = entityMetamodel.getPropertySpan();
261         final Object JavaDoc[] result = new Object JavaDoc[span];
262
263         for ( int j = 0; j < span; j++ ) {
264             result[j] = getters[j].getForInsert( entity, mergeMap, session );
265         }
266         return result;
267     }
268
269     public Object JavaDoc getPropertyValue(Object JavaDoc entity, int i) throws HibernateException {
270         return getters[i].get( entity );
271     }
272
273     public Object JavaDoc getPropertyValue(Object JavaDoc entity, String JavaDoc propertyPath) throws HibernateException {
274         
275         int loc = propertyPath.indexOf('.');
276         String JavaDoc basePropertyName = loc>0 ?
277             propertyPath.substring(0, loc) : propertyPath;
278             
279         int index = entityMetamodel.getPropertyIndex( basePropertyName );
280         Object JavaDoc baseValue = getPropertyValue( entity, index );
281         if ( loc>0 ) {
282             ComponentType type = (ComponentType) entityMetamodel.getPropertyTypes()[index];
283             return getComponentValue( type, baseValue, propertyPath.substring(loc+1) );
284         }
285         else {
286             return baseValue;
287         }
288     }
289
290     /**
291      * Extract a component property value.
292      *
293      * @param type The component property types.
294      * @param component The component instance itself.
295      * @param propertyPath The property path for the property to be extracted.
296      * @return The property value extracted.
297      */

298     protected Object JavaDoc getComponentValue(ComponentType type, Object JavaDoc component, String JavaDoc propertyPath) {
299         
300         int loc = propertyPath.indexOf('.');
301         String JavaDoc basePropertyName = loc>0 ?
302             propertyPath.substring(0, loc) : propertyPath;
303         
304         String JavaDoc[] propertyNames = type.getPropertyNames();
305         int index=0;
306         for ( ; index<propertyNames.length; index++ ) {
307             if ( basePropertyName.equals( propertyNames[index] ) ) break;
308         }
309         if (index==propertyNames.length) {
310             throw new MappingException( "component property not found: " + basePropertyName );
311         }
312         
313         Object JavaDoc baseValue = type.getPropertyValue( component, index, getEntityMode() );
314         
315         if ( loc>0 ) {
316             ComponentType subtype = (ComponentType) type.getSubtypes()[index];
317             return getComponentValue( subtype, baseValue, propertyPath.substring(loc+1) );
318         }
319         else {
320             return baseValue;
321         }
322         
323     }
324
325     public void setPropertyValues(Object JavaDoc entity, Object JavaDoc[] values) throws HibernateException {
326         boolean setAll = !entityMetamodel.hasLazyProperties();
327
328         for ( int j = 0; j < entityMetamodel.getPropertySpan(); j++ ) {
329             if ( setAll || values[j] != LazyPropertyInitializer.UNFETCHED_PROPERTY ) {
330                 setters[j].set( entity, values[j], getFactory() );
331             }
332         }
333     }
334
335     public void setPropertyValue(Object JavaDoc entity, int i, Object JavaDoc value) throws HibernateException {
336         setters[i].set( entity, value, getFactory() );
337     }
338
339     public void setPropertyValue(Object JavaDoc entity, String JavaDoc propertyName, Object JavaDoc value) throws HibernateException {
340         setters[ entityMetamodel.getPropertyIndex( propertyName ) ].set( entity, value, getFactory() );
341     }
342
343     public final Object JavaDoc instantiate(Serializable JavaDoc id) throws HibernateException {
344         Object JavaDoc result = getInstantiator().instantiate( id );
345         if ( id != null ) {
346             setIdentifier( result, id );
347         }
348         return result;
349     }
350
351     public final Object JavaDoc instantiate() throws HibernateException {
352         return instantiate( null );
353     }
354
355     public void afterInitialize(Object JavaDoc entity, boolean lazyPropertiesAreUnfetched, SessionImplementor session) {}
356
357     public boolean hasUninitializedLazyProperties(Object JavaDoc entity) {
358         // the default is to simply not lazy fetch properties for now...
359
return false;
360     }
361
362     public final boolean isInstance(Object JavaDoc object) {
363         return getInstantiator().isInstance( object );
364     }
365
366     public boolean hasProxy() {
367         return entityMetamodel.isLazy();
368     }
369
370     public final Object JavaDoc createProxy(Serializable JavaDoc id, SessionImplementor session)
371     throws HibernateException {
372         return getProxyFactory().getProxy( id, session );
373     }
374
375     public boolean isLifecycleImplementor() {
376         return false;
377     }
378
379     public boolean isValidatableImplementor() {
380         return false;
381     }
382     
383     protected final EntityMetamodel getEntityMetamodel() {
384         return entityMetamodel;
385     }
386
387     protected final SessionFactoryImplementor getFactory() {
388         return entityMetamodel.getSessionFactory();
389     }
390
391     protected final Instantiator getInstantiator() {
392         return instantiator;
393     }
394
395     protected final ProxyFactory getProxyFactory() {
396         return proxyFactory;
397     }
398     
399     public String JavaDoc toString() {
400         return getClass().getName() + '(' + getEntityMetamodel().getName() + ')';
401     }
402
403 }
404
Popular Tags