1 package org.apache.torque.map;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.util.Collections;
23 import java.util.Iterator;
24 import java.util.Map;
25 import java.util.StringTokenizer;
26
27 import org.apache.commons.collections.map.ListOrderedMap;
28 import org.apache.commons.lang.StringUtils;
29 import org.apache.torque.adapter.IDMethod;
30 import org.apache.torque.oid.IdGenerator;
31
32 /***
33 * TableMap is used to model a table in a database.
34 *
35 * @author <a href="mailto:jmcnally@collab.net">John D. McNally</a>
36 * @author <a href="mailto:dlr@finemaltcoding.com">Daniel Rall</a>
37 * @author <a href="mailto:greg.monroe@dukece.com">Greg Monroe</a>
38 * @version $Id: TableMap.java 473821 2006-11-11 22:37:25Z tv $
39 */
40 public class TableMap implements IDMethod, java.io.Serializable
41 {
42 /*** The serialVersionUID for this class. */
43 private static final long serialVersionUID = -9053174532511492818L;
44
45 /*** The list of valid ID generation methods. */
46 protected static final String[] VALID_ID_METHODS =
47 {
48 NATIVE, AUTO_INCREMENT, SEQUENCE, ID_BROKER, NO_ID_METHOD
49 };
50
51 /*** The columns in the table. XML Order is preserved. */
52 private Map columns;
53
54 /*** The database this table belongs to. */
55 private DatabaseMap dbMap;
56
57 /*** The name of the table. */
58 private String tableName;
59
60 /*** The JavaName of the table as defined in XML */
61 private String javaName;
62
63 /*** The prefix on the table name. */
64 private String prefix;
65
66 /*** The primary key generation method. */
67 private String primaryKeyMethod = NO_ID_METHOD;
68
69 /*** The table description info. */
70 private String description = "";
71
72 /*** The Peer Class for this table. */
73 private Class peerClass;
74
75 /*** The OM Root Class for this table. */
76 private Class omClass;
77
78 /*** Whether any column uses Inheritance. */
79 private boolean useInheritance = false;
80
81 /*** Whether cache managers are used. */
82 private boolean useManager = false;
83
84 /*** The associated cache manager class. */
85 private Class managerClass;
86
87 /***
88 * Object to store information that is needed if the
89 * for generating primary keys.
90 */
91 private Object pkInfo = null;
92
93 /***
94 * Required by proxy. Not used.
95 */
96 public TableMap()
97 {
98 }
99
100 /***
101 * Constructor.
102 *
103 * @param tableName The name of the table.
104 * @param numberOfColumns The number of columns in the table.
105 * @param containingDB A DatabaseMap that this table belongs to.
106 */
107 public TableMap(String tableName,
108 int numberOfColumns,
109 DatabaseMap containingDB)
110 {
111 this.tableName = tableName;
112 dbMap = containingDB;
113 columns = Collections.synchronizedMap(new ListOrderedMap());
114 }
115
116 /***
117 * Constructor.
118 *
119 * @param tableName The name of the table.
120 * @param containingDB A DatabaseMap that this table belongs to.
121 */
122 public TableMap(String tableName, DatabaseMap containingDB)
123 {
124 this.tableName = tableName;
125 dbMap = containingDB;
126 columns = Collections.synchronizedMap(new ListOrderedMap());
127 }
128
129 /***
130 * Constructor.
131 *
132 * @param tableName The name of the table.
133 * @param prefix The prefix for the table name (ie: SCARAB for
134 * SCARAB_PROJECT).
135 * @param containingDB A DatabaseMap that this table belongs to.
136 */
137 public TableMap(String tableName,
138 String prefix,
139 DatabaseMap containingDB)
140 {
141 this.tableName = tableName;
142 this.prefix = prefix;
143 dbMap = containingDB;
144 columns = Collections.synchronizedMap(new ListOrderedMap());
145 }
146
147 /***
148 * Does this table contain the specified column?
149 *
150 * @param column A ColumnMap.
151 * @return True if the table contains the column.
152 */
153 public boolean containsColumn(ColumnMap column)
154 {
155 return containsColumn(column.getColumnName());
156 }
157
158 /***
159 * Does this table contain the specified column?
160 *
161 * @param name A String with the name of the column.
162 * @return True if the table contains the column.
163 */
164 public boolean containsColumn(String name)
165 {
166 if (name.indexOf('.') > 0)
167 {
168 name = name.substring(name.indexOf('.') + 1);
169 }
170 return columns.containsKey(name);
171 }
172
173 /***
174 * Get the DatabaseMap containing this TableMap.
175 *
176 * @return A DatabaseMap.
177 */
178 public DatabaseMap getDatabaseMap()
179 {
180 return dbMap;
181 }
182
183 /***
184 * Returns true if this tableMap contains a column with object
185 * data. If the type of the column is not a string, a number or a
186 * date, it is assumed that it is object data.
187 *
188 * @return True if map contains a column with object data.
189 */
190 public boolean containsObjectColumn()
191 {
192 synchronized (columns)
193 {
194 Iterator it = columns.values().iterator();
195 while (it.hasNext())
196 {
197 Object theType = ((ColumnMap) it.next()).getType();
198 if (!(theType instanceof String || theType instanceof Number
199 || theType instanceof java.util.Date))
200 {
201 return true;
202 }
203 }
204 }
205 return false;
206 }
207
208 /***
209 * Get the name of the Table.
210 *
211 * @return A String with the name of the table.
212 */
213 public String getName()
214 {
215 return tableName;
216 }
217
218 /***
219 * Get the Java name of the table as defined in XML.
220 *
221 * @return A String with the Java name of the table.
222 */
223 public String getJavaName()
224 {
225 return javaName;
226 }
227
228 /***
229 * Set the Java name of the table as defined by generator/XML.
230 *
231 * @param value A String with the Java name of the table.
232 */
233 public void setJavaName(String value)
234 {
235 this.javaName = value;
236 }
237
238 /***
239 * Get table prefix name.
240 *
241 * @return A String with the prefix.
242 */
243 public String getPrefix()
244 {
245 return this.prefix;
246 }
247
248 /***
249 * Set table prefix name.
250 *
251 * @param prefix The prefix for the table name (ie: SCARAB for
252 * SCARAB_PROJECT).
253 */
254 public void setPrefix(String prefix)
255 {
256 this.prefix = prefix;
257 }
258
259 /***
260 * Get the method used to generate primary keys for this table.
261 *
262 * @return A String with the method.
263 */
264 public String getPrimaryKeyMethod()
265 {
266 return primaryKeyMethod;
267 }
268
269 /***
270 * Get the value of idGenerator.
271 * @return value of idGenerator.
272 * @deprecated use DatabaseInfo.getIdGenerator(getPrimaryKeyMethod())
273 * instead. Will be removed in a future version of Torque.
274 */
275 public IdGenerator getIdGenerator()
276 {
277 return getDatabaseMap().getIdGenerator(primaryKeyMethod);
278 }
279
280 /***
281 * Get the information used to generate a primary key
282 *
283 * @return An Object.
284 */
285 public Object getPrimaryKeyMethodInfo()
286 {
287 return pkInfo;
288 }
289
290 /***
291 * Get a ColumnMap[] of the columns in this table.
292 *
293 * @return A ColumnMap[].
294 */
295 public ColumnMap[] getColumns()
296 {
297 ColumnMap[] tableColumns = new ColumnMap[columns.size()];
298 synchronized (columns)
299 {
300 Iterator it = columns.values().iterator();
301 int i = 0;
302 while (it.hasNext())
303 {
304 tableColumns[i++] = (ColumnMap) it.next();
305 }
306 }
307 return tableColumns;
308 }
309
310 /***
311 * Get a ColumnMap for the named table.
312 *
313 * @param name A String with the name of the table.
314 * @return A ColumnMap.
315 */
316 public ColumnMap getColumn(String name)
317 {
318 try
319 {
320 return (ColumnMap) columns.get(name);
321 }
322 catch (Exception e)
323 {
324 return null;
325 }
326 }
327
328 /***
329 * Add a pre-created column to this table. It will replace any
330 * existing column.
331 *
332 * @param cmap A ColumnMap.
333 */
334 public void addColumn(ColumnMap cmap)
335 {
336 columns.put(cmap.getColumnName(), cmap);
337 }
338
339 /***
340 * Add a column to this table of a certain type.
341 *
342 * @param columnName A String with the column name.
343 * @param type An Object specifying the type.
344 * @deprecated Associated Column maps should be populated using it's
345 * set methods, then added to table via addColumn(ColumnMap).
346 * This method will be removed in a future version of Torque.
347 */
348 public void addColumn(String columnName, Object type)
349 {
350 addColumn(columnName, type, false, null, null, 0);
351 }
352
353 /***
354 * Add a column to this table of a certain type, size, and scale.
355 *
356 * @param columnName A String with the column name.
357 * @param type An Object specifying the type.
358 * @param size An int specifying the size.
359 * @param scale An int specifying the scale.
360 * @deprecated Associated Column maps should be populated using it's set
361 * methods, then added to table via addColumn(ColumnMap).
362 * This method will be removed in a future version of Torque.
363 */
364 public void addColumn(String columnName, Object type, int size, int scale)
365 {
366 addColumn(columnName, type, false, null, null, size, scale);
367 }
368
369 /***
370 * Add a column to this table of a certain type and size.
371 *
372 * @param columnName A String with the column name.
373 * @param type An Object specifying the type.
374 * @param size An int specifying the size.
375 * @deprecated Associated Column maps should be populated using it's set
376 * methods, then added to table via addColumn(ColumnMap).
377 * This method will be removed in a future version of Torque.
378 */
379 public void addColumn(String columnName, Object type, int size)
380 {
381 addColumn(columnName, type, false, null, null, size);
382 }
383
384 /***
385 * Add a primary key column to this Table.
386 *
387 * @param columnName A String with the column name.
388 * @param type An Object specifying the type.
389 * @deprecated Associated Column maps should be populated using it's set
390 * methods, then added to table via addColumn(ColumnMap).
391 * This method will be removed in a future version of Torque.
392 */
393 public void addPrimaryKey(String columnName, Object type)
394 {
395 addColumn(columnName, type, true, null, null, 0);
396 }
397
398 /***
399 * Add a primary key column to this Table.
400 *
401 * @param columnName A String with the column name.
402 * @param type An Object specifying the type.
403 * @param size An int specifying the size.
404 * @deprecated Associated Column maps should be populated using it's set
405 * methods, then added to table via addColumn(ColumnMap).
406 * This method will be removed in a future version of Torque.
407 */
408 public void addPrimaryKey(String columnName, Object type, int size)
409 {
410 addColumn(columnName, type, true, null, null, size);
411 }
412
413 /***
414 * Add a foreign key column to the table.
415 *
416 * @param columnName A String with the column name.
417 * @param type An Object specifying the type.
418 * @param fkTable A String with the foreign key table name.
419 * @param fkColumn A String with the foreign key column name.
420 * @deprecated Associated Column maps should be populated using it's set
421 * methods, then added to table via addColumn(ColumnMap).
422 * This method will be removed in a future version of Torque.
423 */
424 public void addForeignKey(String columnName,
425 Object type,
426 String fkTable,
427 String fkColumn)
428 {
429 addColumn(columnName, type, false, fkTable, fkColumn, 0);
430 }
431
432 /***
433 * Add a foreign key column to the table.
434 *
435 * @param columnName A String with the column name.
436 * @param type An Object specifying the type.
437 * @param fkTable A String with the foreign key table name.
438 * @param fkColumn A String with the foreign key column name.
439 * @param size An int specifying the size.
440 * @deprecated Associated Column maps should be populated using it's set
441 * methods, then added to table via addColumn(ColumnMap).
442 * This method will be removed in a future version of Torque.
443 */
444 public void addForeignKey(String columnName,
445 Object type,
446 String fkTable,
447 String fkColumn,
448 int size)
449 {
450 addColumn(columnName, type, false, fkTable, fkColumn, size);
451 }
452
453 /***
454 * Add a foreign primary key column to the table.
455 *
456 * @param columnName A String with the column name.
457 * @param type An Object specifying the type.
458 * @param fkTable A String with the foreign key table name.
459 * @param fkColumn A String with the foreign key column name.
460 * @deprecated Associated Column maps should be populated using it's set
461 * methods, then added to table via addColumn(ColumnMap).
462 * This method will be removed in a future version of Torque.
463 */
464 public void addForeignPrimaryKey(String columnName,
465 Object type,
466 String fkTable,
467 String fkColumn)
468 {
469 addColumn(columnName, type, true, fkTable, fkColumn, 0);
470 }
471
472 /***
473 * Add a foreign primary key column to the table.
474 *
475 * @param columnName A String with the column name.
476 * @param type An Object specifying the type.
477 * @param fkTable A String with the foreign key table name.
478 * @param fkColumn A String with the foreign key column name.
479 * @param size An int specifying the size.
480 * @deprecated Associated Column maps should be populated using it's set
481 * methods, then added to table via addColumn(ColumnMap).
482 * This method will be removed in a future version of Torque.
483 */
484 public void addForeignPrimaryKey(String columnName,
485 Object type,
486 String fkTable,
487 String fkColumn,
488 int size)
489 {
490 addColumn(columnName, type, true, fkTable, fkColumn, size);
491 }
492
493 /***
494 * Add a column to the table.
495 *
496 * @param name A String with the column name.
497 * @param type An Object specifying the type.
498 * @param pk True if column is a primary key.
499 * @param fkTable A String with the foreign key table name.
500 * @param fkColumn A String with the foreign key column name.
501 * @param size An int specifying the size.
502 * @deprecated Associated Column maps should be populated using it's set
503 * methods, then added to table via addColumn(ColumnMap).
504 * This method will be removed in a future version of Torque.
505 */
506 private void addColumn(String name,
507 Object type,
508 boolean pk,
509 String fkTable,
510 String fkColumn,
511 int size)
512 {
513 addColumn(name, type, pk, fkTable, fkColumn, size, 0);
514 }
515
516 /***
517 * Add a column to the table.
518 *
519 * @param name A String with the column name.
520 * @param type An Object specifying the type.
521 * @param pk True if column is a primary key.
522 * @param fkTable A String with the foreign key table name.
523 * @param fkColumn A String with the foreign key column name.
524 * @param size An int specifying the size.
525 * @param scale An int specifying the scale.
526 * @deprecated Associated Column maps should be populated using it's set
527 * methods, then added to table via addColumn(ColumnMap).
528 * This method will be removed in a future version of Torque.
529 */
530 private void addColumn(String name,
531 Object type,
532 boolean pk,
533 String fkTable,
534 String fkColumn,
535 int size,
536 int scale)
537 {
538
539
540
541 if (name.indexOf('.') > 0 && name.indexOf(getName()) != -1)
542 {
543 name = name.substring(getName().length() + 1);
544 }
545 if (fkTable != null && fkTable.length() > 0 && fkColumn != null
546 && fkColumn.length() > 0)
547 {
548 if (fkColumn.indexOf('.') > 0 && fkColumn.indexOf(fkTable) != -1)
549 {
550 fkColumn = fkColumn.substring(fkTable.length() + 1);
551 }
552 }
553 ColumnMap col = new ColumnMap(name, this);
554 col.setType(type);
555 col.setPrimaryKey(pk);
556 col.setForeignKey(fkTable, fkColumn);
557 col.setSize(size);
558 col.setScale(scale);
559 columns.put(name, col);
560 }
561
562 /***
563 * Sets the method used to generate a key for this table. Valid
564 * values are as specified in the {@link
565 * org.apache.torque.adapter.IDMethod} interface.
566 *
567 * @param method The ID generation method type name.
568 */
569 public void setPrimaryKeyMethod(String method)
570 {
571 primaryKeyMethod = NO_ID_METHOD;
572
573
574 for (int i = 0; i < VALID_ID_METHODS.length; i++)
575 {
576 if (VALID_ID_METHODS[i].equalsIgnoreCase(method))
577 {
578 primaryKeyMethod = method;
579 break;
580 }
581 }
582 if (ID_BROKER.equalsIgnoreCase(method))
583 {
584 getDatabaseMap().startIdBroker();
585 }
586 }
587
588 /***
589 * Sets the pk information needed to generate a key
590 *
591 * @param pkInfo information needed to generate a key
592 */
593 public void setPrimaryKeyMethodInfo(Object pkInfo)
594 {
595 this.pkInfo = pkInfo;
596 }
597
598
599
600 /***
601 * Tell me if i have PREFIX in my string.
602 *
603 * @param data A String.
604 * @return True if prefix is contained in data.
605 */
606 private boolean hasPrefix(String data)
607 {
608 return (data.indexOf(getPrefix()) != -1);
609 }
610
611 /***
612 * Removes the PREFIX.
613 *
614 * @param data A String.
615 * @return A String with data, but with prefix removed.
616 */
617 private String removePrefix(String data)
618 {
619 return data.substring(getPrefix().length());
620 }
621
622 /***
623 * Removes the PREFIX, removes the underscores and makes
624 * first letter caps.
625 *
626 * SCARAB_FOO_BAR becomes FooBar.
627 *
628 * @param data A String.
629 * @return A String with data processed.
630 */
631 public final String removeUnderScores(String data)
632 {
633 String tmp = null;
634 StringBuffer out = new StringBuffer();
635 if (hasPrefix(data))
636 {
637 tmp = removePrefix(data);
638 }
639 else
640 {
641 tmp = data;
642 }
643
644 StringTokenizer st = new StringTokenizer(tmp, "_");
645 while (st.hasMoreTokens())
646 {
647 String element = ((String) st.nextElement()).toLowerCase();
648 out.append(StringUtils.capitalize(element));
649 }
650 return out.toString();
651 }
652
653 /***
654 * Returns the table description info.
655 *
656 * @return Returns the description.
657 */
658 public String getDescription()
659 {
660 return description;
661 }
662
663 /***
664 * Sets the table description.
665 *
666 * @param description The description to set.
667 */
668 public void setDescription(String description)
669 {
670 this.description = description;
671 }
672
673 /***
674 * Returns the OM class for this table.
675 *
676 * @return the OM class.
677 */
678 public Class getOMClass()
679 {
680 return omClass;
681 }
682
683 /***
684 * Sets the OM root class for this table.
685 *
686 * @param omClass The OM root class for this table.
687 */
688 public void setOMClass(Class omClass)
689 {
690 this.omClass = omClass;
691 }
692
693 /***
694 * Returns the Peer Class for this table.
695 *
696 * @return The peerClass for this table.
697 */
698 public Class getPeerClass()
699 {
700 return peerClass;
701 }
702
703 /***
704 * Sets the Peer class for this table.
705 *
706 * @param peerClass The peerClass to set.
707 */
708 public void setPeerClass(Class peerClass)
709 {
710 this.peerClass = peerClass;
711 }
712
713 /***
714 * Returns the database map for this table.
715 *
716 * @return the database map for this table.
717 */
718 public DatabaseMap getDbMap()
719 {
720 return dbMap;
721 }
722
723 /***
724 * Returns whether this table uses inheritance.
725 *
726 * @return whether inheritance is used.
727 */
728 public boolean isUseInheritance()
729 {
730 return useInheritance;
731 }
732
733 /***
734 * Sets whether this table uses inheritance.
735 *
736 * @param useInheritance whether this table uses inheritance.
737 */
738 public void setUseInheritance(boolean useInheritance)
739 {
740 this.useInheritance = useInheritance;
741 }
742
743 /***
744 * Returns whether managers are used for this table.
745 *
746 * @return whether managers are used for this table.
747 */
748 public boolean isUseManager()
749 {
750 return useManager;
751 }
752
753 /***
754 * Sets whether managers are used for this table.
755 *
756 * @param useManager whether managers are used for this table.
757 */
758 public void setUseManager(boolean useManager)
759 {
760 this.useManager = useManager;
761 }
762
763 /***
764 * Returns the manager class for this table.
765 *
766 * @return the managerClass.
767 */
768 public Class getManagerClass()
769 {
770 return managerClass;
771 }
772
773 /***
774 * Sets the manager class for this table.
775 *
776 * @param managerClass the manager class for this table.
777 */
778 public void setManagerClass(Class managerClass)
779 {
780 this.managerClass = managerClass;
781 }
782 }