KickJava   Java API By Example, From Geeks To Geeks.

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


1 // $Id: EntityMetamodel.java,v 1.18 2005/07/21 01:11:52 oneovthafew Exp $
2
package org.hibernate.tuple;
3
4 import java.io.Serializable JavaDoc;
5 import java.util.ArrayList JavaDoc;
6 import java.util.HashMap JavaDoc;
7 import java.util.HashSet JavaDoc;
8 import java.util.Iterator JavaDoc;
9 import java.util.List JavaDoc;
10 import java.util.Map JavaDoc;
11 import java.util.Set JavaDoc;
12
13 import net.sf.cglib.transform.impl.InterceptFieldEnabled;
14
15 import org.apache.commons.logging.Log;
16 import org.apache.commons.logging.LogFactory;
17 import org.hibernate.EntityMode;
18 import org.hibernate.HibernateException;
19 import org.hibernate.MappingException;
20 import org.hibernate.engine.CascadeStyle;
21 import org.hibernate.engine.SessionFactoryImplementor;
22 import org.hibernate.engine.Versioning;
23 import org.hibernate.mapping.Component;
24 import org.hibernate.mapping.PersistentClass;
25 import org.hibernate.mapping.Property;
26 import org.hibernate.type.AbstractComponentType;
27 import org.hibernate.type.AssociationType;
28 import org.hibernate.type.EntityType;
29 import org.hibernate.type.Type;
30 import org.hibernate.type.TypeFactory;
31 import org.hibernate.util.ArrayHelper;
32 import org.hibernate.util.ReflectHelper;
33
34 /**
35  * Centralizes metamodel information about an entity.
36  *
37  * @author Steve Ebersole
38  */

39 public class EntityMetamodel implements Serializable JavaDoc {
40     
41     private static final Log log = LogFactory.getLog(EntityMetamodel.class);
42
43     private static final int NO_VERSION_INDX = -66;
44
45     private final SessionFactoryImplementor sessionFactory;
46
47     private final String JavaDoc name;
48     private final String JavaDoc rootName;
49     private final EntityType entityType;
50
51     private final IdentifierProperty identifierProperty;
52     private final boolean versioned;
53
54     private final int propertySpan;
55     private final int versionPropertyIndex;
56     private final StandardProperty[] properties;
57     // temporary ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
58
private final String JavaDoc[] propertyNames;
59     private final Type[] propertyTypes;
60     private final boolean[] propertyLaziness;
61     private final boolean[] propertyUpdateability;
62     private final boolean[] nonlazyPropertyUpdateability;
63     private final boolean[] propertyCheckability;
64     private final boolean[] propertyInsertability;
65     private final boolean[] propertyNullability;
66     private final boolean[] propertyVersionability;
67     private final CascadeStyle[] cascadeStyles;
68     // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
69
private final Map JavaDoc propertyIndexes = new HashMap JavaDoc();
70     private final boolean hasCollections;
71     private final boolean hasMutableProperties;
72     private final boolean hasLazyProperties;
73
74     private final int[] naturalIdPropertyNumbers;
75
76     private final boolean lazy;
77     private final boolean hasCascades;
78     private final boolean mutable;
79     private final boolean isAbstract;
80     private final boolean selectBeforeUpdate;
81     private final boolean dynamicUpdate;
82     private final boolean dynamicInsert;
83     private final int optimisticLockMode;
84
85     private final boolean polymorphic;
86     private final String JavaDoc superclass; // superclass entity-name
87
private final boolean explicitPolymorphism;
88     private final boolean inherited;
89     private final boolean hasSubclasses;
90     private final Set JavaDoc subclassEntityNames = new HashSet JavaDoc();
91     
92     private final TuplizerLookup tuplizers;
93     
94     public EntityTuplizer getTuplizer(EntityMode entityMode) {
95         return (EntityTuplizer) tuplizers.getTuplizer(entityMode);
96     }
97
98     public EntityTuplizer getTuplizerOrNull(EntityMode entityMode) {
99         return (EntityTuplizer) tuplizers.getTuplizerOrNull(entityMode);
100     }
101     
102     public EntityMode guessEntityMode(Object JavaDoc object) {
103         return tuplizers.guessEntityMode(object);
104     }
105
106     public EntityMetamodel(PersistentClass persistentClass, SessionFactoryImplementor sessionFactory) {
107         this.sessionFactory = sessionFactory;
108
109         name = persistentClass.getEntityName();
110         rootName = persistentClass.getRootClass().getEntityName();
111         entityType = TypeFactory.manyToOne( name );
112
113         identifierProperty = PropertyFactory.buildIdentifierProperty(
114                 persistentClass,
115                 sessionFactory.getIdentifierGenerator( rootName )
116             );
117
118         versioned = persistentClass.isVersioned();
119
120         boolean lazyAvailable = persistentClass.hasPojoRepresentation() &&
121                 InterceptFieldEnabled.class.isAssignableFrom( persistentClass.getMappedClass() );
122         boolean hasLazy = false;
123
124         propertySpan = persistentClass.getPropertyClosureSpan();
125         properties = new StandardProperty[propertySpan];
126         List JavaDoc naturalIdNumbers = new ArrayList JavaDoc();
127         // temporary ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
128
propertyNames = new String JavaDoc[propertySpan];
129         propertyTypes = new Type[propertySpan];
130         propertyUpdateability = new boolean[propertySpan];
131         propertyInsertability = new boolean[propertySpan];
132         nonlazyPropertyUpdateability = new boolean[propertySpan];
133         propertyCheckability = new boolean[propertySpan];
134         propertyNullability = new boolean[propertySpan];
135         propertyVersionability = new boolean[propertySpan];
136         propertyLaziness = new boolean[propertySpan];
137         cascadeStyles = new CascadeStyle[propertySpan];
138         // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
139

140
141         Iterator JavaDoc iter = persistentClass.getPropertyClosureIterator();
142         int i = 0;
143         int tempVersionProperty = NO_VERSION_INDX;
144         boolean foundCascade = false;
145         boolean foundCollection = false;
146         boolean foundMutable = false;
147         
148         while ( iter.hasNext() ) {
149             Property prop = ( Property ) iter.next();
150
151             if ( prop == persistentClass.getVersion() ) {
152                 tempVersionProperty = i;
153                 properties[i] = PropertyFactory.buildVersionProperty( prop, lazyAvailable );
154             }
155             else {
156                 properties[i] = PropertyFactory.buildStandardProperty( prop, lazyAvailable );
157             }
158             
159             if ( prop.isNaturalIdentifier() ) {
160                 naturalIdNumbers.add( new Integer JavaDoc(i) );
161             }
162
163             // temporary ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
164
boolean lazy = prop.isLazy() && lazyAvailable;
165             if ( lazy ) hasLazy = true;
166             propertyLaziness[i] = lazy;
167
168             propertyNames[i] = properties[i].getName();
169             propertyTypes[i] = properties[i].getType();
170             propertyNullability[i] = properties[i].isNullable();
171             propertyUpdateability[i] = properties[i].isUpdateable();
172             propertyInsertability[i] = properties[i].isInsertable();
173             propertyVersionability[i] = properties[i].isVersionable();
174             nonlazyPropertyUpdateability[i] = properties[i].isUpdateable() && !lazy;
175             propertyCheckability[i] = propertyUpdateability[i] ||
176                     ( propertyTypes[i].isAssociationType() && ( (AssociationType) propertyTypes[i] ).isAlwaysDirtyChecked() );
177
178             cascadeStyles[i] = properties[i].getCascadeStyle();
179             // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
180

181             if ( properties[i].isLazy() ) {
182                 hasLazy = true;
183             }
184
185             if ( properties[i].getCascadeStyle() != CascadeStyle.NONE ) {
186                 foundCascade = true;
187             }
188
189             if ( indicatesCollection( properties[i].getType() ) ) {
190                 foundCollection = true;
191             }
192             
193             if ( propertyTypes[i].isMutable() && propertyCheckability[i] ) {
194                 foundMutable = true;
195             }
196
197             mapPropertyToIndex(prop, i);
198             i++;
199         }
200         
201         if (naturalIdNumbers.size()==0) {
202             naturalIdPropertyNumbers = null;
203         }
204         else {
205             naturalIdPropertyNumbers = ArrayHelper.toIntArray(naturalIdNumbers);
206         }
207
208         hasCascades = foundCascade;
209         versionPropertyIndex = tempVersionProperty;
210         hasLazyProperties = hasLazy;
211         if (hasLazyProperties) log.info("lazy property fetching available for: " + name);
212
213         lazy = persistentClass.isLazy() && (
214                 // TODO: this disables laziness even in non-pojo entity modes:
215
!persistentClass.hasPojoRepresentation() ||
216                 !ReflectHelper.isFinalClass( persistentClass.getProxyInterface() )
217             );
218         mutable = persistentClass.isMutable();
219         isAbstract = persistentClass.isAbstract() || (
220                 persistentClass.hasPojoRepresentation() &&
221                 ReflectHelper.isAbstractClass( persistentClass.getMappedClass() )
222             );
223         selectBeforeUpdate = persistentClass.hasSelectBeforeUpdate();
224         dynamicUpdate = persistentClass.useDynamicUpdate();
225         dynamicInsert = persistentClass.useDynamicInsert();
226
227         polymorphic = persistentClass.isPolymorphic();
228         explicitPolymorphism = persistentClass.isExplicitPolymorphism();
229         inherited = persistentClass.isInherited();
230         superclass = inherited ?
231                 persistentClass.getSuperclass().getEntityName() :
232                 null;
233         hasSubclasses = persistentClass.hasSubclasses();
234
235         optimisticLockMode = persistentClass.getOptimisticLockMode();
236         if ( optimisticLockMode > Versioning.OPTIMISTIC_LOCK_VERSION && !dynamicUpdate ) {
237             throw new MappingException( "optimistic-lock setting requires dynamic-update=\"true\": " + name );
238         }
239
240         hasCollections = foundCollection;
241         hasMutableProperties = foundMutable;
242
243         tuplizers = TuplizerLookup.create(persistentClass, this);
244         
245         iter = persistentClass.getSubclassIterator();
246         while ( iter.hasNext() ) {
247             subclassEntityNames.add( ( (PersistentClass) iter.next() ).getEntityName() );
248         }
249         subclassEntityNames.add( name );
250
251     }
252
253     private void mapPropertyToIndex(Property prop, int i) {
254         propertyIndexes.put( prop.getName(), new Integer JavaDoc(i) );
255         if ( prop.getValue() instanceof Component ) {
256             Iterator JavaDoc iter = ( (Component) prop.getValue() ).getPropertyIterator();
257             while ( iter.hasNext() ) {
258                 Property subprop = (Property) iter.next();
259                 propertyIndexes.put(
260                         prop.getName() + '.' + subprop.getName(),
261                         new Integer JavaDoc(i)
262                     );
263             }
264         }
265     }
266     
267     public int[] getNaturalIdentifierProperties() {
268         return naturalIdPropertyNumbers;
269     }
270     
271     public boolean hasNaturalIdentifier() {
272         return naturalIdPropertyNumbers!=null;
273     }
274     
275     public Set JavaDoc getSubclassEntityNames() {
276         return subclassEntityNames;
277     }
278
279     private boolean indicatesCollection(Type type) {
280         if ( type.isCollectionType() ) {
281             return true;
282         }
283         else if ( type.isComponentType() ) {
284             Type[] subtypes = ( ( AbstractComponentType ) type ).getSubtypes();
285             for ( int i = 0; i < subtypes.length; i++ ) {
286                 if ( indicatesCollection( subtypes[i] ) ) {
287                     return true;
288                 }
289             }
290         }
291         return false;
292     }
293
294     public SessionFactoryImplementor getSessionFactory() {
295         return sessionFactory;
296     }
297
298     public String JavaDoc getName() {
299         return name;
300     }
301
302     public String JavaDoc getRootName() {
303         return rootName;
304     }
305
306     public EntityType getEntityType() {
307         return entityType;
308     }
309
310     public IdentifierProperty getIdentifierProperty() {
311         return identifierProperty;
312     }
313
314     public int getPropertySpan() {
315         return propertySpan;
316     }
317
318     public int getVersionPropertyIndex() {
319         return versionPropertyIndex;
320     }
321
322     public VersionProperty getVersionProperty() {
323         if ( NO_VERSION_INDX == versionPropertyIndex ) {
324             return null;
325         }
326         else {
327             return ( VersionProperty ) properties[ versionPropertyIndex ];
328         }
329     }
330
331     public StandardProperty[] getProperties() {
332         return properties;
333     }
334
335     public int getPropertyIndex(String JavaDoc propertyName) {
336         Integer JavaDoc index = getPropertyIndexOrNull(propertyName);
337         if ( index == null ) {
338             throw new HibernateException("Unable to resolve property: " + propertyName);
339         }
340         return index.intValue();
341     }
342     
343     public Integer JavaDoc getPropertyIndexOrNull(String JavaDoc propertyName) {
344         return (Integer JavaDoc) propertyIndexes.get( propertyName );
345     }
346
347     public boolean hasCollections() {
348         return hasCollections;
349     }
350     
351     public boolean hasMutableProperties() {
352         return hasMutableProperties;
353     }
354
355     public boolean hasLazyProperties() {
356         return hasLazyProperties;
357     }
358
359     public boolean hasCascades() {
360         return hasCascades;
361     }
362
363     public boolean isMutable() {
364         return mutable;
365     }
366
367     public boolean isSelectBeforeUpdate() {
368         return selectBeforeUpdate;
369     }
370
371     public boolean isDynamicUpdate() {
372         return dynamicUpdate;
373     }
374
375     public boolean isDynamicInsert() {
376         return dynamicInsert;
377     }
378
379     public int getOptimisticLockMode() {
380         return optimisticLockMode;
381     }
382
383     public boolean isPolymorphic() {
384         return polymorphic;
385     }
386
387     public String JavaDoc getSuperclass() {
388         return superclass;
389     }
390
391     public boolean isExplicitPolymorphism() {
392         return explicitPolymorphism;
393     }
394
395     public boolean isInherited() {
396         return inherited;
397     }
398
399     public boolean hasSubclasses() {
400         return hasSubclasses;
401     }
402
403     public boolean isLazy() {
404         return lazy;
405     }
406
407     public boolean isVersioned() {
408         return versioned;
409     }
410
411     public boolean isAbstract() {
412         return isAbstract;
413     }
414     
415     public String JavaDoc toString() {
416         return "EntityMetamodel(" + name + ':' + ArrayHelper.toString(properties) + ')';
417     }
418     
419     // temporary ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
420
public String JavaDoc[] getPropertyNames() {
421         return propertyNames;
422     }
423
424     public Type[] getPropertyTypes() {
425         return propertyTypes;
426     }
427
428     public boolean[] getPropertyLaziness() {
429         return propertyLaziness;
430     }
431
432     public boolean[] getPropertyUpdateability() {
433         return propertyUpdateability;
434     }
435
436     public boolean[] getPropertyCheckability() {
437         return propertyCheckability;
438     }
439
440     public boolean[] getNonlazyPropertyUpdateability() {
441         return nonlazyPropertyUpdateability;
442     }
443
444     public boolean[] getPropertyInsertability() {
445         return propertyInsertability;
446     }
447
448     public boolean[] getPropertyNullability() {
449         return propertyNullability;
450     }
451
452     public boolean[] getPropertyVersionability() {
453         return propertyVersionability;
454     }
455
456     public CascadeStyle[] getCascadeStyles() {
457         return cascadeStyles;
458     }
459     // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
460
}
461
Popular Tags