KickJava   Java API By Example, From Geeks To Geeks.

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


1 //$Id: Table.java,v 1.42 2005/07/04 02:38:00 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.Iterator JavaDoc;
8 import java.util.List JavaDoc;
9 import java.util.Map JavaDoc;
10
11 import org.apache.commons.collections.SequencedHashMap;
12 import org.hibernate.HibernateException;
13 import org.hibernate.MappingException;
14 import org.hibernate.dialect.Dialect;
15 import org.hibernate.engine.Mapping;
16 import org.hibernate.tool.hbm2ddl.ColumnMetadata;
17 import org.hibernate.tool.hbm2ddl.TableMetadata;
18 import org.hibernate.util.CollectionHelper;
19
20 /**
21  * A relational table
22  *
23  * @author Gavin King
24  */

25 public class Table implements RelationalModel, Serializable JavaDoc {
26
27     private String JavaDoc name;
28     private String JavaDoc schema;
29     private String JavaDoc catalog;
30     /**
31      * contains all columns, including the primary key
32      */

33     private Map columns = new SequencedHashMap();
34     private KeyValue idValue;
35     private PrimaryKey primaryKey;
36     private Map indexes = new HashMap JavaDoc();
37     private Map foreignKeys = new HashMap JavaDoc();
38     private Map uniqueKeys = new HashMap JavaDoc();
39     private final int uniqueInteger;
40     private boolean quoted;
41     private boolean schemaQuoted;
42     private static int tableCounter = 0;
43     private List checkConstraints = new ArrayList JavaDoc();
44     private String JavaDoc rowId;
45     private String JavaDoc subselect;
46     private boolean isAbstract;
47     private boolean hasDenormalizedTables = false;
48     private String JavaDoc comment;
49
50     static class ForeignKeyKey implements Serializable JavaDoc {
51         String JavaDoc referencedClassName;
52         List columns;
53         List referencedColumns;
54         
55         ForeignKeyKey(List columns, String JavaDoc referencedClassName, List referencedColumns) {
56             this.referencedClassName = referencedClassName;
57             this.columns = new ArrayList JavaDoc();
58             this.columns.addAll( columns );
59             if(referencedColumns!=null) {
60                 this.referencedColumns = new ArrayList JavaDoc();
61                 this.referencedColumns.addAll( referencedColumns );
62             }
63             else {
64                 this.referencedColumns = CollectionHelper.EMPTY_LIST;
65             }
66         }
67
68         public int hashCode() {
69             return columns.hashCode() + referencedColumns.hashCode();
70         }
71
72         public boolean equals(Object JavaDoc other) {
73             ForeignKeyKey fkk = ( ForeignKeyKey ) other;
74             return fkk.columns.equals( columns ) &&
75                     fkk.referencedClassName.equals( referencedClassName ) && fkk.referencedColumns.equals( referencedColumns );
76         }
77     }
78
79     public Table() {
80         uniqueInteger = tableCounter++;
81     }
82     
83     public Table(String JavaDoc name) {
84         this();
85         setName(name);
86     }
87
88     public String JavaDoc getQualifiedName(Dialect dialect, String JavaDoc defaultCatalog, String JavaDoc defaultSchema) {
89         if ( subselect != null ) return "( " + subselect + " )";
90         String JavaDoc quotedName = getQuotedName(dialect);
91         String JavaDoc usedSchema = schema == null ? defaultSchema : getQuotedSchema(dialect);
92         String JavaDoc usedCatalog = catalog == null ? defaultCatalog : catalog;
93         return qualify( usedCatalog, usedSchema, quotedName, dialect.getSchemaSeparator() );
94     }
95
96     public static String JavaDoc qualify(String JavaDoc catalog, String JavaDoc schema, String JavaDoc table, char schemaSeparator) {
97         StringBuffer JavaDoc qualifiedName = new StringBuffer JavaDoc();
98         if ( catalog != null ) {
99             qualifiedName.append( catalog ).append( '.' );
100         }
101         if ( schema != null ) {
102             qualifiedName.append( schema ).append( schemaSeparator );
103         }
104         return qualifiedName.append( table ).toString();
105     }
106
107     public String JavaDoc getName() {
108         return name;
109     }
110
111     public String JavaDoc getQuotedName(Dialect dialect) {
112         return quoted ?
113                 dialect.openQuote() + name + dialect.closeQuote() :
114                 name;
115     }
116
117     public String JavaDoc getQuotedSchema(Dialect dialect) {
118         return schemaQuoted ?
119                 dialect.openQuote() + schema + dialect.closeQuote() :
120                 schema;
121     }
122     
123     public void setName(String JavaDoc name) {
124         if ( name.charAt( 0 ) == '`' ) {
125             quoted = true;
126             this.name = name.substring( 1, name.length() - 1 );
127         }
128         else {
129             this.name = name;
130         }
131     }
132
133     /**
134      * Return the column which is identified by column provided as argument.
135      *
136      * @param column column with atleast a name.
137      * @return the underlying column or null if not inside this table. Note: the instance *can* be different than the input parameter, but the name will be the same.
138      */

139     public Column getColumn(Column column) {
140         Column myColumn = ( Column ) columns.get( column.getName() );
141
142         if ( column.equals( myColumn ) ) {
143             return myColumn;
144         }
145         else {
146             return null;
147         }
148     }
149
150     public Column getColumn(int n) {
151         Iterator JavaDoc iter = columns.values().iterator();
152         for ( int i = 0; i < n - 1; i++ ) iter.next();
153         return ( Column ) iter.next();
154     }
155
156     public void addColumn(Column column) {
157         Column old = ( Column ) columns.get( column.getName() );
158         if ( old == null ) {
159             columns.put( column.getName(), column );
160             column.uniqueInteger = columns.size();
161         }
162         else {
163             column.uniqueInteger = old.uniqueInteger;
164         }
165     }
166
167     public int getColumnSpan() {
168         return columns.size();
169     }
170
171     public Iterator JavaDoc getColumnIterator() {
172         return columns.values().iterator();
173     }
174
175     public Iterator JavaDoc getIndexIterator() {
176         return indexes.values().iterator();
177     }
178
179     public Iterator JavaDoc getForeignKeyIterator() {
180         return foreignKeys.values().iterator();
181     }
182
183     public Iterator JavaDoc getUniqueKeyIterator() {
184         return uniqueKeys.values().iterator();
185     }
186
187     public Iterator JavaDoc sqlAlterStrings(Dialect dialect, Mapping p, TableMetadata tableInfo, String JavaDoc defaultCatalog, String JavaDoc defaultSchema)
188             throws HibernateException {
189
190         StringBuffer JavaDoc root = new StringBuffer JavaDoc( "alter table " )
191                 .append( getQualifiedName( dialect, defaultCatalog, defaultSchema ) )
192                 .append( ' ' )
193                 .append( dialect.getAddColumnString() );
194
195         Iterator JavaDoc iter = getColumnIterator();
196         List results = new ArrayList JavaDoc();
197         while ( iter.hasNext() ) {
198             Column col = ( Column ) iter.next();
199
200             ColumnMetadata columnInfo = tableInfo.getColumnMetadata( col.getName() );
201
202             if ( columnInfo == null ) {
203                 // the column doesnt exist at all.
204
StringBuffer JavaDoc alter = new StringBuffer JavaDoc( root.toString() )
205                         .append( ' ' )
206                         .append( col.getQuotedName( dialect ) )
207                         .append( ' ' )
208                         .append( col.getSqlType( dialect, p ) );
209                 
210                 boolean useUniqueConstraint = col.isUnique() &&
211                         dialect.supportsUnique() &&
212                         ( !col.isNullable() || dialect.supportsNotNullUnique() );
213                 if ( useUniqueConstraint ) {
214                     alter.append( " unique" );
215                 }
216                 
217                 if ( col.hasCheckConstraint() && dialect.supportsColumnCheck() ) {
218                     alter.append( " check(" )
219                             .append( col.getCheckConstraint() )
220                             .append( ")" );
221                 }
222
223                 String JavaDoc columnComment = col.getComment();
224                 if (columnComment!=null) alter.append( dialect.getColumnComment(columnComment) );
225
226                 results.add( alter.toString() );
227             }
228
229         }
230
231         return results.iterator();
232     }
233     
234     public boolean hasPrimaryKey() {
235         return getPrimaryKey()!=null;
236     }
237
238     public String JavaDoc sqlTemporaryTableCreateString(Dialect dialect, Mapping mapping) throws HibernateException {
239         StringBuffer JavaDoc buffer = new StringBuffer JavaDoc( dialect.getTemporaryTableCreationCommand() )
240                 .append( ' ' )
241                 .append( name )
242                 .append( " (" );
243         Iterator JavaDoc itr = getColumnIterator();
244         while( itr.hasNext() ) {
245             final Column column = ( Column ) itr.next();
246             buffer.append( column.getQuotedName( dialect ) ).append( ' ' );
247             buffer.append( column.getSqlType( dialect, mapping ) );
248             if ( column.isNullable() ) {
249                 buffer.append( dialect.getNullColumnString() );
250             }
251             else {
252                 buffer.append( " not null" );
253             }
254             if ( itr.hasNext() ) {
255                 buffer.append( ", " );
256             }
257         }
258         buffer.append( ") " );
259         buffer.append( dialect.getTemporaryTableCreationPostfix() );
260         return buffer.toString();
261     }
262
263     public String JavaDoc sqlCreateString(Dialect dialect, Mapping p, String JavaDoc defaultCatalog, String JavaDoc defaultSchema) throws HibernateException {
264         StringBuffer JavaDoc buf = new StringBuffer JavaDoc( "create table " )
265                 .append( getQualifiedName( dialect , defaultCatalog, defaultSchema ) )
266                 .append( " (" );
267
268         boolean identityColumn = idValue != null && idValue.isIdentityColumn(dialect);
269
270         // Try to find out the name of the primary key to create it as identity if the IdentityGenerator is used
271
String JavaDoc pkname = null;
272         if ( hasPrimaryKey() && identityColumn ) {
273             pkname = ( ( Column ) getPrimaryKey().getColumnIterator().next() ).getQuotedName( dialect );
274         }
275
276         Iterator JavaDoc iter = getColumnIterator();
277         while ( iter.hasNext() ) {
278             Column col = ( Column ) iter.next();
279
280             buf.append( col.getQuotedName( dialect ) )
281                     .append( ' ' );
282
283             if ( identityColumn && col.getQuotedName( dialect ).equals( pkname ) ) {
284                 // to support dialects that have their own identity data type
285
if ( dialect.hasDataTypeInIdentityColumn() ) {
286                     buf.append( col.getSqlType( dialect, p ) );
287                 }
288                 buf.append( ' ' )
289                         .append( dialect.getIdentityColumnString( col.getSqlTypeCode( p ) ) );
290             }
291             else {
292                 buf.append( col.getSqlType( dialect, p ) );
293                 if ( col.isNullable() ) {
294                     buf.append( dialect.getNullColumnString() );
295                 }
296                 else {
297                     buf.append( " not null" );
298                 }
299             }
300
301             boolean useUniqueConstraint = col.isUnique() &&
302                     ( !col.isNullable() || dialect.supportsNotNullUnique() );
303             if ( useUniqueConstraint ) {
304                 if ( dialect.supportsUnique() ) {
305                     buf.append( " unique" );
306                 }
307                 else {
308                     UniqueKey uk = getOrCreateUniqueKey( col.getQuotedName( dialect ) + '_' );
309                     uk.addColumn( col );
310                 }
311             }
312             
313             if ( col.hasCheckConstraint() && dialect.supportsColumnCheck() ) {
314                 buf.append( " check (" )
315                         .append( col.getCheckConstraint() )
316                         .append( ")" );
317             }
318             
319             String JavaDoc columnComment = col.getComment();
320             if (columnComment!=null) buf.append( dialect.getColumnComment(columnComment) );
321
322             if ( iter.hasNext() ) buf.append( ", " );
323
324         }
325         if ( hasPrimaryKey() ) {
326             buf.append( ", " )
327                 .append( getPrimaryKey().sqlConstraintString( dialect ) );
328         }
329
330         if ( dialect.supportsUniqueConstraintInCreateAlterTable() ) {
331             Iterator JavaDoc ukiter = getUniqueKeyIterator();
332             while ( ukiter.hasNext() ) {
333                 UniqueKey uk = ( UniqueKey ) ukiter.next();
334                 buf.append( ", " )
335                 .append( uk.sqlConstraintString( dialect ) );
336             }
337         }
338         /*Iterator idxiter = getIndexIterator();
339         while ( idxiter.hasNext() ) {
340             Index idx = (Index) idxiter.next();
341             buf.append(',').append( idx.sqlConstraintString(dialect) );
342         }*/

343
344         if ( dialect.supportsTableCheck() ) {
345             Iterator JavaDoc chiter = checkConstraints.iterator();
346             while ( chiter.hasNext() ) {
347                 buf.append( ", check (" )
348                 .append( chiter.next() )
349                 .append( ')' );
350             }
351         }
352         
353         buf.append( ')' );
354         
355         if (comment!=null) buf.append( dialect.getTableComment(comment) );
356         
357         return buf.append( dialect.getTableTypeString() ).toString();
358     }
359
360     public String JavaDoc sqlDropString(Dialect dialect, String JavaDoc defaultCatalog, String JavaDoc defaultSchema) {
361         StringBuffer JavaDoc buf = new StringBuffer JavaDoc( "drop table " );
362         if ( dialect.supportsIfExistsBeforeTableName() ) buf.append( "if exists " );
363         buf.append( getQualifiedName( dialect , defaultCatalog, defaultSchema ) )
364                 .append( dialect.getCascadeConstraintsString() );
365         if ( dialect.supportsIfExistsAfterTableName() ) buf.append( " if exists" );
366         return buf.toString();
367     }
368
369     public PrimaryKey getPrimaryKey() {
370         return primaryKey;
371     }
372
373     public void setPrimaryKey(PrimaryKey primaryKey) {
374         this.primaryKey = primaryKey;
375     }
376
377     /*public Index createIndex(String indexName, List indexColumns) {
378         if ( indexName == null ) indexName = "IX" + uniqueColumnString( indexColumns.iterator() );
379         Index idx = getOrCreateIndex( indexName );
380         idx.addColumns( indexColumns.iterator() );
381         return idx;
382     }*/

383
384     public Index getOrCreateIndex(String JavaDoc indexName) {
385         Index index = ( Index ) indexes.get( indexName );
386
387         if ( index == null ) {
388             index = new Index();
389             index.setName( indexName );
390             index.setTable( this );
391             indexes.put( indexName, index );
392         }
393
394         return index;
395     }
396
397     public Index getIndex(String JavaDoc indexName) {
398         return ( Index ) indexes.get( indexName );
399     }
400
401     public Index addIndex(Index index) {
402         Index current = ( Index ) indexes.get( index.getName() );
403         if ( current != null ) {
404             throw new MappingException( "Index " + index.getName() + " already exists!" );
405         }
406         indexes.put( index.getName(), index );
407         return index;
408     }
409
410     public UniqueKey addUniqueKey(UniqueKey uniqueKey) {
411         UniqueKey current = ( UniqueKey ) uniqueKeys.get( uniqueKey.getName() );
412         if ( current != null ) {
413             throw new MappingException( "UniqueKey " + uniqueKey.getName() + " already exists!" );
414         }
415         uniqueKeys.put( uniqueKey.getName(), uniqueKey );
416         return uniqueKey;
417     }
418
419     public UniqueKey createUniqueKey(List keyColumns) {
420         String JavaDoc keyName = "UK" + uniqueColumnString( keyColumns.iterator() );
421         UniqueKey uk = getOrCreateUniqueKey( keyName );
422         uk.addColumns( keyColumns.iterator() );
423         return uk;
424     }
425
426     public UniqueKey getUniqueKey(String JavaDoc keyName) {
427         return (UniqueKey) uniqueKeys.get( keyName );
428     }
429     
430     public UniqueKey getOrCreateUniqueKey(String JavaDoc keyName) {
431         UniqueKey uk = ( UniqueKey ) uniqueKeys.get( keyName );
432
433         if ( uk == null ) {
434             uk = new UniqueKey();
435             uk.setName( keyName );
436             uk.setTable( this );
437             uniqueKeys.put( keyName, uk );
438         }
439         return uk;
440     }
441
442     public void createForeignKeys() {
443     }
444
445     public ForeignKey createForeignKey(String JavaDoc keyName, List keyColumns, String JavaDoc referencedEntityName) {
446         return createForeignKey(keyName, keyColumns, referencedEntityName, null);
447     }
448     
449     public ForeignKey createForeignKey(String JavaDoc keyName, List keyColumns, String JavaDoc referencedEntityName, List referencedColumns) {
450         Object JavaDoc key = new ForeignKeyKey( keyColumns, referencedEntityName, referencedColumns );
451
452         ForeignKey fk = ( ForeignKey ) foreignKeys.get( key );
453         if ( fk == null ) {
454             fk = new ForeignKey();
455             if ( keyName != null ) {
456                 fk.setName( keyName );
457             }
458             else {
459                 fk.setName( "FK" + uniqueColumnString( keyColumns.iterator(), referencedEntityName ) );
460                 //TODO: add referencedClass to disambiguate to FKs on the same
461
// columns, pointing to different tables
462
}
463             fk.setTable( this );
464             foreignKeys.put( key, fk );
465             fk.setReferencedEntityName( referencedEntityName );
466             fk.addColumns( keyColumns.iterator() );
467             if(referencedColumns!=null) fk.addReferencedColumns( referencedColumns.iterator() );
468         }
469
470         if ( keyName != null ) fk.setName( keyName );
471
472         return fk; }
473
474     
475     public String JavaDoc uniqueColumnString(Iterator JavaDoc iterator) {
476         return uniqueColumnString(iterator, null);
477     }
478
479     public String JavaDoc uniqueColumnString(Iterator JavaDoc iterator, String JavaDoc referencedEntityName) {
480         int result = 0;
481         if (referencedEntityName!=null) result += referencedEntityName.hashCode();
482         while ( iterator.hasNext() ) result += iterator.next().hashCode();
483         return ( Integer.toHexString( name.hashCode() ) + Integer.toHexString( result ) ).toUpperCase();
484     }
485
486
487     public String JavaDoc getSchema() {
488         return schema;
489     }
490
491     public void setSchema(String JavaDoc schema) {
492         if ( schema!=null && schema.charAt( 0 ) == '`' ) {
493             schemaQuoted = true;
494             this.schema = schema.substring( 1, schema.length() - 1 );
495         }
496         else {
497             this.schema = schema;
498         }
499     }
500
501     public String JavaDoc getCatalog() {
502         return catalog;
503     }
504
505     public void setCatalog(String JavaDoc catalog) {
506         this.catalog = catalog;
507     }
508
509     public int getUniqueInteger() {
510         return uniqueInteger;
511     }
512
513     public void setIdentifierValue(KeyValue idValue) {
514         this.idValue = idValue;
515     }
516
517     public boolean isQuoted() {
518         return quoted;
519     }
520
521     public void setQuoted(boolean quoted) {
522         this.quoted = quoted;
523     }
524
525     public void addCheckConstraint(String JavaDoc constraint) {
526         checkConstraints.add( constraint );
527     }
528
529     public boolean containsColumn(Column column) {
530         return columns.containsValue( column );
531     }
532
533     public String JavaDoc getRowId() {
534         return rowId;
535     }
536
537     public void setRowId(String JavaDoc rowId) {
538         this.rowId = rowId;
539     }
540
541     public String JavaDoc toString() {
542         StringBuffer JavaDoc buf = new StringBuffer JavaDoc().append( getClass().getName() )
543             .append('(');
544         if ( getCatalog()!=null ) buf.append( getCatalog() + "." );
545         if ( getSchema()!=null ) buf.append( getSchema()+ ".");
546         buf.append( getName() ).append(')');
547         return buf.toString();
548     }
549
550     public String JavaDoc getSubselect() {
551         return subselect;
552     }
553
554     public void setSubselect(String JavaDoc subselect) {
555         this.subselect = subselect;
556     }
557
558     public boolean isSubselect() {
559         return subselect != null;
560     }
561
562     public boolean isAbstractUnionTable() {
563         return hasDenormalizedTables && isAbstract;
564     }
565
566     void setHasDenormalizedTables() {
567         hasDenormalizedTables = true;
568     }
569     
570     public boolean hasDenormalizedTables() {
571         return hasDenormalizedTables;
572     }
573
574     public void setAbstract(boolean isAbstract) {
575         this.isAbstract = isAbstract;
576     }
577
578     public boolean isAbstract() {
579         return isAbstract;
580     }
581
582     public boolean isPhysicalTable() {
583         return !isSubselect() && !isAbstractUnionTable();
584     }
585
586     public String JavaDoc getComment() {
587         return comment;
588     }
589
590     public void setComment(String JavaDoc comment) {
591         this.comment = comment;
592     }
593     
594     public Iterator JavaDoc sqlCommentStrings(Dialect dialect, String JavaDoc defaultCatalog, String JavaDoc defaultSchema) {
595         List comments = new ArrayList JavaDoc();
596         if ( dialect.supportsCommentOn() ) {
597             String JavaDoc tableName = getQualifiedName( dialect , defaultCatalog, defaultSchema );
598             if ( comment!=null ) {
599                 StringBuffer JavaDoc buf = new StringBuffer JavaDoc()
600                     .append("comment on table ")
601                     .append( tableName )
602                     .append(" is '")
603                     .append(comment)
604                     .append("'");
605                 comments.add( buf.toString() );
606             }
607             Iterator JavaDoc iter = getColumnIterator();
608             while ( iter.hasNext() ) {
609                 Column column = (Column) iter.next();
610                 String JavaDoc columnComment = column.getComment();
611                 if ( columnComment!=null ) {
612                     StringBuffer JavaDoc buf = new StringBuffer JavaDoc()
613                         .append("comment on column ")
614                         .append( tableName )
615                         .append('.')
616                         .append( column.getQuotedName(dialect) )
617                         .append(" is '")
618                         .append(columnComment)
619                         .append("'");
620                     comments.add( buf.toString() );
621                 }
622             }
623         }
624         return comments.iterator();
625     }
626
627 }
628
Popular Tags