KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > hibernate > mapping > PersistentClass


1 //$Id: PersistentClass.java,v 1.41 2005/07/21 01:11:51 oneovthafew Exp $
2
package org.hibernate.mapping;
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.Set JavaDoc;
10
11 import org.hibernate.MappingException;
12 import org.hibernate.EntityMode;
13 import org.hibernate.dialect.Dialect;
14 import org.hibernate.engine.Mapping;
15 import org.hibernate.sql.Alias;
16 import org.hibernate.util.EmptyIterator;
17 import org.hibernate.util.JoinedIterator;
18 import org.hibernate.util.ReflectHelper;
19 import org.hibernate.util.SingletonIterator;
20 import org.hibernate.util.StringHelper;
21
22 /**
23  * Mapping for an entity.
24  *
25  * @author Gavin King
26  */

27 public abstract class PersistentClass implements Serializable JavaDoc, Filterable, MetaAttributable {
28
29     private static final Alias PK_ALIAS = new Alias(15, "PK");
30
31     public static final String JavaDoc NULL_DISCRIMINATOR_MAPPING = "null";
32     public static final String JavaDoc NOT_NULL_DISCRIMINATOR_MAPPING = "not null";
33
34     private String JavaDoc entityName;
35
36     private String JavaDoc className;
37     private String JavaDoc proxyInterfaceName;
38     
39     private String JavaDoc nodeName;
40
41     private String JavaDoc discriminatorValue;
42     private boolean lazy;
43     private ArrayList JavaDoc properties = new ArrayList JavaDoc();
44     private final ArrayList JavaDoc subclasses = new ArrayList JavaDoc();
45     private final ArrayList JavaDoc subclassProperties = new ArrayList JavaDoc();
46     private final ArrayList JavaDoc subclassTables = new ArrayList JavaDoc();
47     private boolean dynamicInsert;
48     private boolean dynamicUpdate;
49     private int batchSize=-1;
50     private boolean selectBeforeUpdate;
51     private int optimisticLockMode;
52     private java.util.Map JavaDoc metaAttributes;
53     private ArrayList JavaDoc joins = new ArrayList JavaDoc();
54     private final ArrayList JavaDoc subclassJoins = new ArrayList JavaDoc();
55     private final java.util.Map JavaDoc filters = new HashMap JavaDoc();
56     protected final java.util.Set JavaDoc synchronizedTables = new HashSet JavaDoc();
57     private String JavaDoc loaderName;
58     private boolean isAbstract;
59     private boolean hasSubselectLoadableCollections;
60     private Component identifierMapper;
61
62     // Custom SQL
63
private String JavaDoc customSQLInsert;
64     private String JavaDoc customSQLUpdate;
65     private String JavaDoc customSQLDelete;
66     private boolean customInsertCallable;
67     private boolean customUpdateCallable;
68     private boolean customDeleteCallable;
69
70     private String JavaDoc temporaryIdTableName;
71     private String JavaDoc temporaryIdTableDDL;
72
73     private java.util.Map JavaDoc tuplizerImpls;
74
75     public String JavaDoc getClassName() {
76         return className;
77     }
78
79     public void setClassName(String JavaDoc className) {
80         this.className = className==null ? null : className.intern();
81     }
82
83     public String JavaDoc getProxyInterfaceName() {
84         return proxyInterfaceName;
85     }
86
87     public void setProxyInterfaceName(String JavaDoc proxyInterfaceName) {
88         this.proxyInterfaceName = proxyInterfaceName;
89     }
90
91     public Class JavaDoc getMappedClass() throws MappingException {
92         if (className==null) return null;
93         try {
94             return ReflectHelper.classForName(className);
95         }
96         catch (ClassNotFoundException JavaDoc cnfe) {
97             throw new MappingException("entity class not found: " + className, cnfe);
98         }
99     }
100
101     public Class JavaDoc getProxyInterface() {
102         if (proxyInterfaceName==null) return null;
103         try {
104             return ReflectHelper.classForName(proxyInterfaceName);
105         }
106         catch (ClassNotFoundException JavaDoc cnfe) {
107             throw new MappingException("proxy class not found: " + proxyInterfaceName, cnfe);
108         }
109     }
110     public boolean useDynamicInsert() {
111         return dynamicInsert;
112     }
113
114     abstract int nextSubclassId();
115     public abstract int getSubclassId();
116     
117     public boolean useDynamicUpdate() {
118         return dynamicUpdate;
119     }
120
121     public void setDynamicInsert(boolean dynamicInsert) {
122         this.dynamicInsert = dynamicInsert;
123     }
124
125     public void setDynamicUpdate(boolean dynamicUpdate) {
126         this.dynamicUpdate = dynamicUpdate;
127     }
128
129
130     public String JavaDoc getDiscriminatorValue() {
131         return discriminatorValue;
132     }
133
134     public void addSubclass(Subclass subclass) throws MappingException {
135         // inheritance cycle detection (paranoid check)
136
PersistentClass superclass = getSuperclass();
137         while (superclass!=null) {
138             if( subclass.getEntityName().equals( superclass.getEntityName() ) ) {
139                 throw new MappingException(
140                     "Circular inheritance mapping detected: " +
141                     subclass.getEntityName() +
142                     " will have it self as superclass when extending " +
143                     getEntityName()
144                 );
145             }
146             superclass = superclass.getSuperclass();
147         }
148         subclasses.add(subclass);
149     }
150
151     public boolean hasSubclasses() {
152         return subclasses.size() > 0;
153     }
154
155     public int getSubclassSpan() {
156         int n = subclasses.size();
157         Iterator JavaDoc iter = subclasses.iterator();
158         while ( iter.hasNext() ) {
159             n += ( (Subclass) iter.next() ).getSubclassSpan();
160         }
161         return n;
162     }
163     /**
164      * Iterate over subclasses in a special 'order', most derived subclasses
165      * first.
166      */

167     public Iterator JavaDoc getSubclassIterator() {
168         Iterator JavaDoc[] iters = new Iterator JavaDoc[ subclasses.size() + 1 ];
169         Iterator JavaDoc iter = subclasses.iterator();
170         int i=0;
171         while ( iter.hasNext() ) {
172             iters[i++] = ( (Subclass) iter.next() ).getSubclassIterator();
173         }
174         iters[i] = subclasses.iterator();
175         return new JoinedIterator(iters);
176     }
177
178     public Iterator JavaDoc getSubclassClosureIterator() {
179         ArrayList JavaDoc iters = new ArrayList JavaDoc();
180         iters.add( new SingletonIterator(this) );
181         Iterator JavaDoc iter = getSubclassIterator();
182         while ( iter.hasNext() ) {
183             PersistentClass clazz = (PersistentClass) iter.next();
184             iters.add( clazz.getSubclassClosureIterator() );
185         }
186         return new JoinedIterator(iters);
187     }
188     
189     public Table getIdentityTable() {
190         return getRootTable();
191     }
192     
193     public Iterator JavaDoc getDirectSubclasses() {
194         return subclasses.iterator();
195     }
196
197     public void addProperty(Property p) {
198         properties.add(p);
199         p.setPersistentClass(this);
200     }
201
202     public abstract Table getTable();
203
204     public String JavaDoc getEntityName() {
205         return entityName;
206     }
207
208     public abstract boolean isMutable();
209     public abstract boolean hasIdentifierProperty();
210     public abstract Property getIdentifierProperty();
211     public abstract KeyValue getIdentifier();
212     public abstract Property getVersion();
213     public abstract Value getDiscriminator();
214     public abstract boolean isInherited();
215     public abstract boolean isPolymorphic();
216     public abstract boolean isVersioned();
217     public abstract String JavaDoc getCacheConcurrencyStrategy();
218     public abstract PersistentClass getSuperclass();
219     public abstract boolean isExplicitPolymorphism();
220     public abstract boolean isDiscriminatorInsertable();
221
222     public abstract Iterator JavaDoc getPropertyClosureIterator();
223     public abstract Iterator JavaDoc getTableClosureIterator();
224     public abstract Iterator JavaDoc getKeyClosureIterator();
225
226     protected void addSubclassProperty(Property prop) {
227         subclassProperties.add(prop);
228     }
229     protected void addSubclassJoin(Join join) {
230         subclassJoins.add(join);
231     }
232     protected void addSubclassTable(Table subclassTable) {
233         subclassTables.add(subclassTable);
234     }
235     public Iterator JavaDoc getSubclassPropertyClosureIterator() {
236         ArrayList JavaDoc iters = new ArrayList JavaDoc();
237         iters.add( getPropertyClosureIterator() );
238         iters.add( subclassProperties.iterator() );
239         for ( int i=0; i<subclassJoins.size(); i++ ) {
240             Join join = (Join) subclassJoins.get(i);
241             iters.add( join.getPropertyIterator() );
242         }
243         return new JoinedIterator(iters);
244     }
245     public Iterator JavaDoc getSubclassJoinClosureIterator() {
246         return new JoinedIterator( getJoinClosureIterator(), subclassJoins.iterator() );
247     }
248     public Iterator JavaDoc getSubclassTableClosureIterator() {
249         return new JoinedIterator( getTableClosureIterator(), subclassTables.iterator() );
250     }
251
252     public boolean isClassOrSuperclassJoin(Join join) {
253         return joins.contains(join);
254     }
255
256     public boolean isClassOrSuperclassTable(Table closureTable) {
257         return getTable()==closureTable;
258     }
259
260     public boolean isLazy() {
261         return lazy;
262     }
263
264     public void setLazy(boolean lazy) {
265         this.lazy = lazy;
266     }
267
268     public abstract boolean hasEmbeddedIdentifier();
269     public abstract Class JavaDoc getEntityPersisterClass();
270     public abstract void setEntityPersisterClass(Class JavaDoc classPersisterClass);
271     public abstract Table getRootTable();
272     public abstract RootClass getRootClass();
273     public abstract KeyValue getKey();
274
275     public void setDiscriminatorValue(String JavaDoc discriminatorValue) {
276         this.discriminatorValue = discriminatorValue;
277     }
278
279     public void setEntityName(String JavaDoc entityName) {
280         this.entityName = entityName==null ? null : entityName.intern();
281     }
282
283     public void createPrimaryKey() {
284         //Primary key constraint
285
PrimaryKey pk = new PrimaryKey();
286         Table table = getTable();
287         pk.setTable(table);
288         pk.setName( PK_ALIAS.toAliasString( table.getName() ) );
289         table.setPrimaryKey(pk);
290
291         pk.addColumns( getKey().getColumnIterator() );
292     }
293
294     public abstract String JavaDoc getWhere();
295
296     public int getBatchSize() {
297         return batchSize;
298     }
299
300     public void setBatchSize(int batchSize) {
301         this.batchSize = batchSize;
302     }
303
304     public boolean hasSelectBeforeUpdate() {
305         return selectBeforeUpdate;
306     }
307
308     public void setSelectBeforeUpdate(boolean selectBeforeUpdate) {
309         this.selectBeforeUpdate = selectBeforeUpdate;
310     }
311     
312     public Iterator JavaDoc getReferenceablePropertyIterator() {
313         return getPropertyClosureIterator();
314     }
315     
316     public Property getReferencedProperty(String JavaDoc propertyPath) throws MappingException {
317         Iterator JavaDoc iter = getReferenceablePropertyIterator();
318         Property property = null;
319         while ( iter.hasNext() ) {
320             Property prop = (Property) iter.next();
321             if ( prop.getName().equals( StringHelper.root(propertyPath) ) ) {
322                 property = prop;
323                 break;
324             }
325         }
326         
327         if (property==null) {
328             throw new MappingException(
329                     "property-ref not found: " + propertyPath +
330                     "in entity: " + getEntityName()
331                 );
332         }
333         
334         if ( propertyPath.indexOf('.')>0 ) {
335             property = ( (Component) property.getValue() ).getProperty( StringHelper.unroot(propertyPath) );
336         }
337         
338         return property;
339     }
340
341     public Property getProperty(String JavaDoc propertyName) throws MappingException {
342         Iterator JavaDoc iter = getPropertyClosureIterator();
343         while ( iter.hasNext() ) {
344             Property prop = (Property) iter.next();
345             if ( prop.getName().equals( StringHelper.root(propertyName) ) ) {
346                 return prop;
347             }
348         }
349         throw new MappingException("property not found: " + propertyName);
350     }
351
352     public int getOptimisticLockMode() {
353         return optimisticLockMode;
354     }
355
356     public void setOptimisticLockMode(int optimisticLockMode) {
357         this.optimisticLockMode = optimisticLockMode;
358     }
359
360     public void validate(Mapping mapping) throws MappingException {
361         Iterator JavaDoc iter = getPropertyIterator();
362         while ( iter.hasNext() ) {
363             Property prop = (Property) iter.next();
364             if ( !prop.isValid(mapping) ) {
365                 throw new MappingException(
366                         "property mapping has wrong number of columns: " +
367                         StringHelper.qualify( getEntityName(), prop.getName() ) +
368                         " type: " +
369                         prop.getType().getName()
370                     );
371             }
372         }
373         checkPropertyDuplication();
374         checkColumnDuplication();
375     }
376     
377     private void checkPropertyDuplication() throws MappingException {
378         HashSet JavaDoc names = new HashSet JavaDoc();
379         Iterator JavaDoc iter = getPropertyIterator();
380         while ( iter.hasNext() ) {
381             Property prop = (Property) iter.next();
382             if ( !names.add( prop.getName() ) ) {
383                 throw new MappingException( "duplicate property mapping: " + prop.getName() );
384             }
385         }
386     }
387
388     public boolean isDiscriminatorValueNotNull() {
389         return NOT_NULL_DISCRIMINATOR_MAPPING.equals( getDiscriminatorValue() );
390     }
391     public boolean isDiscriminatorValueNull() {
392         return NULL_DISCRIMINATOR_MAPPING.equals( getDiscriminatorValue() );
393     }
394
395     public java.util.Map JavaDoc getMetaAttributes() {
396         return metaAttributes;
397     }
398
399     public void setMetaAttributes(java.util.Map JavaDoc metas) {
400         this.metaAttributes = metas;
401     }
402
403     public MetaAttribute getMetaAttribute(String JavaDoc name) {
404         return metaAttributes==null?null:(MetaAttribute) metaAttributes.get(name);
405     }
406
407     public String JavaDoc toString() {
408         return getClass().getName() + '(' + getEntityName() + ')';
409     }
410     
411     public Iterator JavaDoc getJoinIterator() {
412         return joins.iterator();
413     }
414
415     public Iterator JavaDoc getJoinClosureIterator() {
416         return joins.iterator();
417     }
418
419     public void addJoin(Join join) {
420         joins.add(join);
421         join.setPersistentClass(this);
422     }
423
424     public int getJoinClosureSpan() {
425         return joins.size();
426     }
427
428     public int getPropertyClosureSpan() {
429         int span = properties.size();
430         for ( int i=0; i<joins.size(); i++ ) {
431             Join join = (Join) joins.get(i);
432             span += join.getPropertySpan();
433         }
434         return span;
435     }
436
437     public int getJoinNumber(Property prop) {
438         int result=1;
439         Iterator JavaDoc iter = getSubclassJoinClosureIterator();
440         while ( iter.hasNext() ) {
441             Join join = (Join) iter.next();
442             if ( join.containsProperty(prop) ) return result;
443             result++;
444         }
445         return 0;
446     }
447
448     public Iterator JavaDoc getPropertyIterator() {
449         ArrayList JavaDoc iterators = new ArrayList JavaDoc();
450         iterators.add( properties.iterator() );
451         for ( int i=0; i<joins.size(); i++ ) {
452             Join join = (Join) joins.get(i);
453             iterators.add( join.getPropertyIterator() );
454         }
455         return new JoinedIterator(iterators);
456     }
457
458     public Iterator JavaDoc getUnjoinedPropertyIterator() {
459         return properties.iterator();
460     }
461
462     public void setCustomSQLInsert(String JavaDoc customSQLInsert, boolean callable) {
463         this.customSQLInsert = customSQLInsert;
464         this.customInsertCallable = callable;
465     }
466
467     public String JavaDoc getCustomSQLInsert() {
468         return customSQLInsert;
469     }
470
471     public boolean isCustomInsertCallable() {
472         return customInsertCallable;
473     }
474
475     public void setCustomSQLUpdate(String JavaDoc customSQLUpdate, boolean callable) {
476         this.customSQLUpdate = customSQLUpdate;
477         this.customUpdateCallable = callable;
478     }
479
480     public String JavaDoc getCustomSQLUpdate() {
481         return customSQLUpdate;
482     }
483
484     public boolean isCustomUpdateCallable() {
485         return customUpdateCallable;
486     }
487
488     public void setCustomSQLDelete(String JavaDoc customSQLDelete, boolean callable) {
489         this.customSQLDelete = customSQLDelete;
490         this.customDeleteCallable = callable;
491     }
492
493     public String JavaDoc getCustomSQLDelete() {
494         return customSQLDelete;
495     }
496
497     public boolean isCustomDeleteCallable() {
498         return customDeleteCallable;
499     }
500
501     public void addFilter(String JavaDoc name, String JavaDoc condition) {
502         filters.put(name, condition);
503     }
504
505     public java.util.Map JavaDoc getFilterMap() {
506         return filters;
507     }
508
509     public boolean isForceDiscriminator() {
510         return false;
511     }
512
513     public abstract boolean isJoinedSubclass();
514
515     public String JavaDoc getLoaderName() {
516         return loaderName;
517     }
518
519     public void setLoaderName(String JavaDoc loaderName) {
520         this.loaderName = loaderName==null ? null : loaderName.intern();
521     }
522
523     public abstract java.util.Set JavaDoc getSynchronizedTables();
524     
525     public void addSynchronizedTable(String JavaDoc table) {
526         synchronizedTables.add(table);
527     }
528     public boolean isAbstract() {
529         return isAbstract;
530     }
531
532     public void setAbstract(boolean isAbstract) {
533         this.isAbstract = isAbstract;
534     }
535
536     protected void checkColumnDuplication(Set distinctColumns, Iterator JavaDoc columns)
537     throws MappingException {
538         while ( columns.hasNext() ) {
539             Selectable columnOrFormula = (Selectable) columns.next();
540             if ( !columnOrFormula.isFormula() ) {
541                 Column col = (Column) columnOrFormula;
542                 if ( !distinctColumns.add( col.getName() ) ) {
543                     throw new MappingException(
544                             "Repeated column in mapping for entity: " +
545                             getEntityName() +
546                             " column: " +
547                             col.getName() +
548                             " (should be mapped with insert=\"false\" update=\"false\")"
549                         );
550                 }
551             }
552         }
553     }
554     
555     protected void checkPropertyColumnDuplication(Set distinctColumns, Iterator JavaDoc properties)
556     throws MappingException {
557         while ( properties.hasNext() ) {
558             Property prop = (Property) properties.next();
559             if ( prop.getValue() instanceof Component ) { //TODO: remove use of instanceof!
560
Component component = (Component) prop.getValue();
561                 checkPropertyColumnDuplication( distinctColumns, component.getPropertyIterator() );
562             }
563             else {
564                 if ( prop.isUpdateable() || prop.isInsertable() ) {
565                     checkColumnDuplication( distinctColumns, prop.getColumnIterator() );
566                 }
567             }
568         }
569     }
570     
571     protected Iterator JavaDoc getNonDuplicatedPropertyIterator() {
572         return getUnjoinedPropertyIterator();
573     }
574     
575     protected Iterator JavaDoc getDiscriminatorColumnIterator() {
576         return EmptyIterator.INSTANCE;
577     }
578     
579     protected void checkColumnDuplication() {
580         HashSet JavaDoc cols = new HashSet JavaDoc();
581         checkColumnDuplication( cols, getKey().getColumnIterator() );
582         checkColumnDuplication( cols, getDiscriminatorColumnIterator() );
583         checkPropertyColumnDuplication( cols, getNonDuplicatedPropertyIterator() );
584         Iterator JavaDoc iter = getJoinIterator();
585         while ( iter.hasNext() ) {
586             cols.clear();
587             Join join = (Join) iter.next();
588             checkColumnDuplication( cols, join.getKey().getColumnIterator() );
589             checkPropertyColumnDuplication( cols, join.getPropertyIterator() );
590         }
591     }
592     
593     public abstract Object JavaDoc accept(PersistentClassVisitor mv);
594     
595     public String JavaDoc getNodeName() {
596         return nodeName;
597     }
598     
599     public void setNodeName(String JavaDoc nodeName) {
600         this.nodeName = nodeName;
601     }
602     
603     public boolean hasPojoRepresentation() {
604         return getClassName()!=null;
605     }
606
607     public boolean hasDom4jRepresentation() {
608         return getNodeName()!=null;
609     }
610
611     public boolean hasSubselectLoadableCollections() {
612         return hasSubselectLoadableCollections;
613     }
614     
615     public void setSubselectLoadableCollections(boolean hasSubselectCollections) {
616         this.hasSubselectLoadableCollections = hasSubselectCollections;
617     }
618
619     public void prepareTemporaryTables(Mapping mapping, Dialect dialect) {
620         if ( dialect.supportsTemporaryTables() ) {
621             temporaryIdTableName = dialect.generateTemporaryTableName( getTable().getName() );
622             Table table = new Table();
623             table.setName( temporaryIdTableName );
624             Iterator JavaDoc itr = getTable().getPrimaryKey().getColumnIterator();
625             while( itr.hasNext() ) {
626                 table.addColumn( ( Column ) itr.next() );
627             }
628             temporaryIdTableDDL = table.sqlTemporaryTableCreateString( dialect, mapping );
629         }
630     }
631
632     public String JavaDoc getTemporaryIdTableName() {
633         return temporaryIdTableName;
634     }
635
636     public String JavaDoc getTemporaryIdTableDDL() {
637         return temporaryIdTableDDL;
638     }
639
640     public Component getIdentifierMapper() {
641         return identifierMapper;
642     }
643
644     public void setIdentifierMapper(Component handle) {
645         this.identifierMapper = handle;
646     }
647
648     public void addTuplizer(EntityMode entityMode, String JavaDoc implClassName) {
649         if ( tuplizerImpls == null ) {
650             tuplizerImpls = new HashMap JavaDoc();
651         }
652         tuplizerImpls.put( entityMode, implClassName );
653     }
654
655     public String JavaDoc getTuplizerImplClassName(EntityMode mode) {
656         if ( tuplizerImpls == null ) return null;
657         return ( String JavaDoc ) tuplizerImpls.get( mode );
658     }
659     
660     public boolean hasNaturalId() {
661         Iterator JavaDoc props = getRootClass().getPropertyIterator();
662         while ( props.hasNext() ) {
663             if ( ( (Property) props.next() ).isNaturalIdentifier() ) {
664                 return true;
665             }
666         }
667         return false;
668     }
669 }
Popular Tags