1 package org.apache.torque.map;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 import java.util.Iterator;
20 import java.util.Hashtable;
21 import java.util.StringTokenizer;
22
23 import org.apache.commons.lang.StringUtils;
24
25 import org.apache.torque.adapter.IDMethod;
26 import org.apache.torque.oid.IdGenerator;
27
28 /***
29 * TableMap is used to model a table in a database.
30 *
31 * @author <a href="mailto:jmcnally@collab.net">John D. McNally</a>
32 * @author <a href="mailto:dlr@finemaltcoding.com">Daniel Rall</a>
33 * @version $Id: TableMap.java 326224 2005-10-18 20:35:33Z tfischer $
34 */
35 public class TableMap implements IDMethod, java.io.Serializable
36 {
37 /*** The list of valid ID generation methods. */
38 protected static final String[] VALID_ID_METHODS =
39 {
40 NATIVE, AUTO_INCREMENT, SEQUENCE, ID_BROKER, NO_ID_METHOD
41 };
42
43 /*** The columns in the table. */
44 private Hashtable columns;
45
46 /*** The database this table belongs to. */
47 private DatabaseMap dbMap;
48
49 /*** The name of the table. */
50 private String tableName;
51
52 /*** The prefix on the table name. */
53 private String prefix;
54
55 /*** The primary key generation method. */
56 private String primaryKeyMethod = NO_ID_METHOD;
57
58 /***
59 * Object to store information that is needed if the
60 * for generating primary keys.
61 */
62 private Object pkInfo = null;
63
64 /***
65 * Required by proxy. Not used.
66 */
67 public TableMap()
68 {
69 }
70
71 /***
72 * Constructor.
73 *
74 * @param tableName The name of the table.
75 * @param numberOfColumns The number of columns in the table.
76 * @param containingDB A DatabaseMap that this table belongs to.
77 */
78 public TableMap(String tableName,
79 int numberOfColumns,
80 DatabaseMap containingDB)
81 {
82 this.tableName = tableName;
83 dbMap = containingDB;
84 columns = new Hashtable((int) (1.25 * numberOfColumns) + 1);
85 }
86
87 /***
88 * Constructor.
89 *
90 * @param tableName The name of the table.
91 * @param containingDB A DatabaseMap that this table belongs to.
92 */
93 public TableMap(String tableName, DatabaseMap containingDB)
94 {
95 this.tableName = tableName;
96 dbMap = containingDB;
97 columns = new Hashtable(20);
98 }
99
100 /***
101 * Constructor.
102 *
103 * @param tableName The name of the table.
104 * @param prefix The prefix for the table name (ie: SCARAB for
105 * SCARAB_PROJECT).
106 * @param containingDB A DatabaseMap that this table belongs to.
107 */
108 public TableMap(String tableName,
109 String prefix,
110 DatabaseMap containingDB)
111 {
112 this.tableName = tableName;
113 this.prefix = prefix;
114 dbMap = containingDB;
115 columns = new Hashtable(20);
116 }
117
118 /***
119 * Does this table contain the specified column?
120 *
121 * @param column A ColumnMap.
122 * @return True if the table contains the column.
123 */
124 public boolean containsColumn(ColumnMap column)
125 {
126 return containsColumn(column.getColumnName());
127 }
128
129 /***
130 * Does this table contain the specified column?
131 *
132 * @param name A String with the name of the column.
133 * @return True if the table contains the column.
134 */
135 public boolean containsColumn(String name)
136 {
137 if (name.indexOf('.') > 0)
138 {
139 name = name.substring(name.indexOf('.') + 1);
140 }
141 return columns.containsKey(name);
142 }
143
144 /***
145 * Get the DatabaseMap containing this TableMap.
146 *
147 * @return A DatabaseMap.
148 */
149 public DatabaseMap getDatabaseMap()
150 {
151 return dbMap;
152 }
153
154 /***
155 * Returns true if this tableMap contains a column with object
156 * data. If the type of the column is not a string, a number or a
157 * date, it is assumed that it is object data.
158 *
159 * @return True if map contains a column with object data.
160 */
161 public boolean containsObjectColumn()
162 {
163 Iterator it = columns.values().iterator();
164 while (it.hasNext())
165 {
166 Object theType = ((ColumnMap) it.next()).getType();
167 if (!(theType instanceof String || theType instanceof Number
168 || theType instanceof java.util.Date))
169 {
170 return true;
171 }
172 }
173 return false;
174 }
175
176 /***
177 * Get the name of the Table.
178 *
179 * @return A String with the name of the table.
180 */
181 public String getName()
182 {
183 return tableName;
184 }
185
186 /***
187 * Get table prefix name.
188 *
189 * @return A String with the prefix.
190 */
191 public String getPrefix()
192 {
193 return this.prefix;
194 }
195
196 /***
197 * Set table prefix name.
198 *
199 * @param prefix The prefix for the table name (ie: SCARAB for
200 * SCARAB_PROJECT).
201 */
202 public void setPrefix(String prefix)
203 {
204 this.prefix = prefix;
205 }
206
207 /***
208 * Get the method used to generate primary keys for this table.
209 *
210 * @return A String with the method.
211 */
212 public String getPrimaryKeyMethod()
213 {
214 return primaryKeyMethod;
215 }
216
217 /***
218 * Get the value of idGenerator.
219 * @return value of idGenerator.
220 */
221 public IdGenerator getIdGenerator()
222 {
223 return getDatabaseMap().getIdGenerator(primaryKeyMethod);
224 }
225
226 /***
227 * Get the information used to generate a primary key
228 *
229 * @return An Object.
230 */
231 public Object getPrimaryKeyMethodInfo()
232 {
233 return pkInfo;
234 }
235
236 /***
237 * Get a ColumnMap[] of the columns in this table.
238 *
239 * @return A ColumnMap[].
240 */
241 public ColumnMap[] getColumns()
242 {
243 ColumnMap[] tableColumns = new ColumnMap[columns.size()];
244 Iterator it = columns.values().iterator();
245 int i = 0;
246 while (it.hasNext())
247 {
248 tableColumns[i++] = (ColumnMap) it.next();
249 }
250 return tableColumns;
251 }
252
253 /***
254 * Get a ColumnMap for the named table.
255 *
256 * @param name A String with the name of the table.
257 * @return A ColumnMap.
258 */
259 public ColumnMap getColumn(String name)
260 {
261 try
262 {
263 return (ColumnMap) columns.get(name);
264 }
265 catch (Exception e)
266 {
267 return null;
268 }
269 }
270
271 /***
272 * Add a pre-created column to this table. It will replace any
273 * existing column.
274 *
275 * @param cmap A ColumnMap.
276 */
277 public void addColumn (ColumnMap cmap)
278 {
279 columns.put (cmap.getColumnName(), cmap);
280 }
281
282 /***
283 * Add a column to this table of a certain type.
284 *
285 * @param columnName A String with the column name.
286 * @param type An Object specifying the type.
287 */
288 public void addColumn(String columnName, Object type)
289 {
290 addColumn(columnName, type, false, null, null, 0);
291 }
292
293 /***
294 * Add a column to this table of a certain type, size, and scale.
295 *
296 * @param columnName A String with the column name.
297 * @param type An Object specifying the type.
298 * @param size An int specifying the size.
299 * @param scale An int specifying the scale.
300 */
301 public void addColumn(String columnName, Object type, int size, int scale)
302 {
303 addColumn(columnName, type, false, null, null, size, scale);
304 }
305
306 /***
307 * Add a column to this table of a certain type and size.
308 *
309 * @param columnName A String with the column name.
310 * @param type An Object specifying the type.
311 * @param size An int specifying the size.
312 */
313 public void addColumn(String columnName, Object type, int size)
314 {
315 addColumn(columnName, type, false, null, null, size);
316 }
317
318 /***
319 * Add a primary key column to this Table.
320 *
321 * @param columnName A String with the column name.
322 * @param type An Object specifying the type.
323 */
324 public void addPrimaryKey(String columnName, Object type)
325 {
326 addColumn(columnName, type, true, null, null, 0);
327 }
328
329 /***
330 * Add a primary key column to this Table.
331 *
332 * @param columnName A String with the column name.
333 * @param type An Object specifying the type.
334 * @param size An int specifying the size.
335 */
336 public void addPrimaryKey(String columnName, Object type, int size)
337 {
338 addColumn(columnName, type, true, null, null, size);
339 }
340
341 /***
342 * Add a foreign key column to the table.
343 *
344 * @param columnName A String with the column name.
345 * @param type An Object specifying the type.
346 * @param fkTable A String with the foreign key table name.
347 * @param fkColumn A String with the foreign key column name.
348 */
349 public void addForeignKey(String columnName,
350 Object type,
351 String fkTable,
352 String fkColumn)
353 {
354 addColumn(columnName, type, false, fkTable, fkColumn, 0);
355 }
356
357 /***
358 * Add a foreign key column to the table.
359 *
360 * @param columnName A String with the column name.
361 * @param type An Object specifying the type.
362 * @param fkTable A String with the foreign key table name.
363 * @param fkColumn A String with the foreign key column name.
364 * @param size An int specifying the size.
365 */
366 public void addForeignKey(String columnName,
367 Object type,
368 String fkTable,
369 String fkColumn,
370 int size)
371 {
372 addColumn(columnName, type, false, fkTable, fkColumn, size);
373 }
374
375 /***
376 * Add a foreign primary key column to the table.
377 *
378 * @param columnName A String with the column name.
379 * @param type An Object specifying the type.
380 * @param fkTable A String with the foreign key table name.
381 * @param fkColumn A String with the foreign key column name.
382 */
383 public void addForeignPrimaryKey(String columnName,
384 Object type,
385 String fkTable,
386 String fkColumn)
387 {
388 addColumn(columnName, type, true, fkTable, fkColumn, 0);
389 }
390
391 /***
392 * Add a foreign primary key column to the table.
393 *
394 * @param columnName A String with the column name.
395 * @param type An Object specifying the type.
396 * @param fkTable A String with the foreign key table name.
397 * @param fkColumn A String with the foreign key column name.
398 * @param size An int specifying the size.
399 */
400 public void addForeignPrimaryKey(String columnName,
401 Object type,
402 String fkTable,
403 String fkColumn,
404 int size)
405 {
406 addColumn(columnName, type, true, fkTable, fkColumn, size);
407 }
408
409 /***
410 * Add a column to the table.
411 *
412 * @param name A String with the column name.
413 * @param type An Object specifying the type.
414 * @param pk True if column is a primary key.
415 * @param fkTable A String with the foreign key table name.
416 * @param fkColumn A String with the foreign key column name.
417 * @param size An int specifying the size.
418 */
419 private void addColumn(String name,
420 Object type,
421 boolean pk,
422 String fkTable,
423 String fkColumn,
424 int size)
425 {
426 addColumn(name, type, pk, fkTable,fkColumn, size, 0 );
427 }
428
429 /***
430 * Add a column to the table.
431 *
432 * @param name A String with the column name.
433 * @param type An Object specifying the type.
434 * @param pk True if column is a primary key.
435 * @param fkTable A String with the foreign key table name.
436 * @param fkColumn A String with the foreign key column name.
437 * @param size An int specifying the size.
438 * @param scale An int specifying the scale.
439 */
440 private void addColumn(String name,
441 Object type,
442 boolean pk,
443 String fkTable,
444 String fkColumn,
445 int size,
446 int scale)
447 {
448
449
450
451 if (name.indexOf('.') > 0 && name.indexOf(getName()) != -1)
452 {
453 name = name.substring(getName().length() + 1);
454 }
455 if (fkTable != null && fkTable.length() > 0 && fkColumn != null
456 && fkColumn.length() > 0)
457 {
458 if (fkColumn.indexOf('.') > 0 && fkColumn.indexOf(fkTable) != -1)
459 {
460 fkColumn = fkColumn.substring(fkTable.length() + 1);
461 }
462 }
463 ColumnMap col = new ColumnMap(name, this);
464 col.setType(type);
465 col.setPrimaryKey(pk);
466 col.setForeignKey(fkTable, fkColumn);
467 col.setSize(size);
468 col.setScale(scale);
469 columns.put(name, col);
470 }
471
472 /***
473 * Sets the method used to generate a key for this table. Valid
474 * values are as specified in the {@link
475 * org.apache.torque.adapter.IDMethod} interface.
476 *
477 * @param method The ID generation method type name.
478 */
479 public void setPrimaryKeyMethod(String method)
480 {
481 primaryKeyMethod = NO_ID_METHOD;
482
483
484 for (int i = 0; i < VALID_ID_METHODS.length; i++)
485 {
486 if (VALID_ID_METHODS[i].equalsIgnoreCase(method))
487 {
488 primaryKeyMethod = method;
489 break;
490 }
491 }
492 }
493
494 /***
495 * Sets the pk information needed to generate a key
496 *
497 * @param pkInfo information needed to generate a key
498 */
499 public void setPrimaryKeyMethodInfo(Object pkInfo)
500 {
501 this.pkInfo = pkInfo;
502 }
503
504
505
506 /***
507 * Tell me if i have PREFIX in my string.
508 *
509 * @param data A String.
510 * @return True if prefix is contained in data.
511 */
512 private final boolean hasPrefix(String data)
513 {
514 return (data.indexOf(getPrefix()) != -1);
515 }
516
517 /***
518 * Removes the PREFIX.
519 *
520 * @param data A String.
521 * @return A String with data, but with prefix removed.
522 */
523 private final String removePrefix(String data)
524 {
525 return data.substring(getPrefix().length());
526 }
527
528 /***
529 * Removes the PREFIX, removes the underscores and makes
530 * first letter caps.
531 *
532 * SCARAB_FOO_BAR becomes FooBar.
533 *
534 * @param data A String.
535 * @return A String with data processed.
536 */
537 public final String removeUnderScores(String data)
538 {
539 String tmp = null;
540 StringBuffer out = new StringBuffer();
541 if (hasPrefix(data))
542 {
543 tmp = removePrefix(data);
544 }
545 else
546 {
547 tmp = data;
548 }
549
550 StringTokenizer st = new StringTokenizer(tmp, "_");
551 while (st.hasMoreTokens())
552 {
553 String element = ((String) st.nextElement()).toLowerCase();
554 out.append(StringUtils.capitalize(element));
555 }
556 return out.toString();
557 }
558 }