1 package org.apache.torque.engine.database.model;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 import java.util.ArrayList;
17 import java.util.Collections;
18 import java.util.HashMap;
19 import java.util.Hashtable;
20 import java.util.Iterator;
21 import java.util.List;
22 import java.util.Map;
23
24 import org.apache.commons.collections.map.ListOrderedMap;
25 import org.apache.commons.logging.Log;
26 import org.apache.commons.logging.LogFactory;
27 import org.apache.torque.engine.EngineException;
28 import org.apache.torque.engine.database.transform.DTDResolver;
29 import org.apache.torque.engine.platform.Platform;
30 import org.apache.torque.engine.platform.PlatformFactory;
31 import org.xml.sax.Attributes;
32
33
34
35
36
37
38
39
40
41
42
43
44 public class Database {
45
46 private static Log log = LogFactory.getLog(Database.class);
47
48 private String databaseType = null;
49 private List tableList = new ArrayList(100);
50 private Map domainMap = new HashMap();
51 private String name;
52 private String javaName;
53 private String pkg;
54 private String baseClass;
55 private String basePeer;
56 private String defaultIdMethod;
57 private String defaultJavaType;
58 private String defaultJavaNamingMethod;
59 private Hashtable tablesByName = new Hashtable();
60 private Hashtable tablesByJavaName = new Hashtable();
61 private boolean heavyIndexing;
62
63 private String fileName;
64 private Map options = Collections.synchronizedMap(new ListOrderedMap());
65
66
67
68
69
70
71
72 public Database(String databaseType) {
73 this.databaseType = databaseType;
74 }
75
76
77
78
79
80
81
82 public void loadFromXML(Attributes attrib) {
83 setName(attrib.getValue("name"));
84 pkg = attrib.getValue("package");
85 baseClass = attrib.getValue("baseClass");
86 basePeer = attrib.getValue("basePeer");
87 defaultJavaType = attrib.getValue("defaultJavaType");
88 defaultIdMethod = attrib.getValue("defaultIdMethod");
89 defaultJavaNamingMethod = attrib.getValue("defaultJavaNamingMethod");
90 if (defaultJavaNamingMethod == null) {
91 defaultJavaNamingMethod = NameGenerator.CONV_METHOD_UNDERSCORE;
92 }
93 heavyIndexing = "true".equals(attrib.getValue("heavyIndexing"));
94 }
95
96
97
98
99
100
101 public String getName() {
102 return name;
103 }
104
105
106
107
108
109
110
111 public void setName(String name) {
112
113
114 this.name = (name == null ? "default" : name);
115 }
116
117 public String getFileName() {
118 return fileName;
119 }
120
121 public void setFileName(String name) {
122 this.fileName = name;
123 }
124
125
126
127
128
129
130 public String getPackage() {
131 return pkg;
132 }
133
134
135
136
137
138
139
140 public void setPackage(String v) {
141 this.pkg = v;
142 }
143
144
145
146
147
148
149 public String getBaseClass() {
150 if (baseClass == null) {
151 return "BaseObject";
152 }
153 return baseClass;
154 }
155
156
157
158
159
160
161
162 public void setBaseClass(String v) {
163 this.baseClass = v;
164 }
165
166
167
168
169
170
171 public String getBasePeer() {
172 if (basePeer == null) {
173 return "BasePeer";
174 }
175 return basePeer;
176 }
177
178
179
180
181
182
183
184 public void setBasePeer(String v) {
185 this.basePeer = v;
186 }
187
188
189
190
191
192
193 public String getDefaultIdMethod() {
194 return defaultIdMethod;
195 }
196
197
198
199
200
201
202
203 public void setDefaultIdMethod(String v) {
204 this.defaultIdMethod = v;
205 }
206
207
208
209
210
211
212 public String getDefaultJavaType() {
213 return defaultJavaType;
214 }
215
216
217
218
219
220
221
222 public String getDefaultJavaNamingMethod() {
223 return defaultJavaNamingMethod;
224 }
225
226
227
228
229
230
231
232 public void setDefaultJavaNamingMethod(String v) {
233 this.defaultJavaNamingMethod = v;
234 }
235
236
237
238
239
240
241 public boolean isHeavyIndexing() {
242 return heavyIndexing;
243 }
244
245
246
247
248
249
250
251 public void setHeavyIndexing(boolean v) {
252 this.heavyIndexing = v;
253 }
254
255
256
257
258
259
260 public List getTables() {
261 return tableList;
262 }
263
264
265
266
267
268
269
270
271 public Table getTable(String name) {
272 return (Table) tablesByName.get(name);
273 }
274
275
276
277
278
279
280
281
282 public Table getTableByJavaName(String javaName) {
283 return (Table) tablesByJavaName.get(javaName);
284 }
285
286
287
288
289
290
291
292
293 public Table addTable(Attributes attrib) {
294 Table tbl = new Table();
295 tbl.setDatabase(this);
296 tbl.loadFromXML(attrib, this.getDefaultIdMethod());
297 addTable(tbl);
298 return tbl;
299 }
300
301
302
303
304
305
306
307 public void addTable(Table tbl) {
308 tbl.setDatabase(this);
309 tbl.setPackage(getPackage());
310 tableList.add(tbl);
311 List<String> tableNames = getTableNames(tbl);
312 for (String tableName : tableNames) {
313 tablesByName.put(tableName, tbl);
314 }
315 tablesByJavaName.put(tbl.getJavaName(), tbl);
316 }
317
318
319
320
321 public void removeTable(Table tbl) {
322 removeFromList(tbl);
323 List<String> tableNames = getTableNames(tbl);
324 for (String tableName : tableNames) {
325 tablesByName.remove(tableName);
326 }
327 tablesByJavaName.remove(tbl.getJavaName());
328 }
329
330 protected List<String> getTableNames(Table table) {
331 List<String> tableNames = new ArrayList<String>();
332 tableNames.add(table.getName());
333 tableNames.add(table.getName().toLowerCase());
334 tableNames.add(table.getName().toUpperCase());
335 return tableNames;
336 }
337
338 protected void removeFromList(Table targetTable) {
339 for (int i = 0; i < tableList.size(); i++) {
340 Table table = (Table) tableList.get(i);
341 String name1 = table.getName();
342 String name2 = targetTable.getName();
343 if (name1.equalsIgnoreCase(name2)) {
344 tableList.remove(i);
345 return;
346 }
347 }
348
349 }
350
351 public void addDomain(Domain domain) {
352 domainMap.put(domain.getName(), domain);
353 }
354
355 public Domain getDomain(String domainName) {
356 return (Domain) domainMap.get(domainName);
357 }
358
359 protected String getDatabaseType() {
360 return databaseType;
361 }
362
363 public void setDatabaseType(String databaseType) {
364 this.databaseType = databaseType;
365 }
366
367
368
369
370
371
372 public Platform getPlatform() {
373 return PlatformFactory.getPlatformFor(databaseType);
374 }
375
376
377
378
379
380
381
382
383 public boolean requiresIdTable() {
384 Iterator iter = getTables().iterator();
385 while (iter.hasNext()) {
386 Table table = (Table) iter.next();
387 if (table.getIdMethod().equals(IDMethod.ID_BROKER)) {
388 return true;
389 }
390 }
391 return false;
392 }
393
394
395
396
397
398
399 public void doFinalInitialization() throws EngineException {
400 Iterator iter = getTables().iterator();
401 while (iter.hasNext()) {
402 Table currTable = (Table) iter.next();
403
404
405
406
407
408
409 if (currTable.getIdMethod().equals("autoincrement")) {
410 boolean foundOne = false;
411 Iterator colIter = currTable.getColumns().iterator();
412 while (colIter.hasNext() && !foundOne) {
413 foundOne = ((Column) colIter.next()).isAutoIncrement();
414 }
415
416 if (!foundOne) {
417 String errorMessage = "Table '" + currTable.getName()
418 + "' is marked as autoincrement, but it does not "
419 + "have a column which declared as the one to "
420 + "auto increment (i.e. autoIncrement=\"true\")\n";
421 throw new EngineException("Error in XML schema: " + errorMessage);
422 }
423 }
424
425 currTable.doFinalInitialization();
426
427
428 Iterator fks = currTable.getForeignKeys().iterator();
429 while (fks.hasNext()) {
430 ForeignKey currFK = (ForeignKey) fks.next();
431 Table foreignTable = getTable(currFK.getForeignTableName());
432 if (foreignTable == null) {
433 throw new EngineException("Attempt to set foreign" + " key to nonexistent table, "
434 + currFK.getForeignTableName());
435 } else {
436
437 List referrers = foreignTable.getReferrers();
438 if ((referrers == null || !referrers.contains(currFK))) {
439 foreignTable.addReferrer(currFK);
440 }
441
442
443 Iterator localColumnNames = currFK.getLocalColumns().iterator();
444 while (localColumnNames.hasNext()) {
445 Column local = currTable.getColumn((String) localColumnNames.next());
446
447
448
449 if (local == null) {
450 throw new EngineException("Attempt to define foreign"
451 + " key with nonexistent column in table, " + currTable.getName());
452 } else {
453
454 if (local.isPrimaryKey()) {
455 currTable.setContainsForeignPK(true);
456 }
457 }
458 }
459
460
461 Iterator foreignColumnNames = currFK.getForeignColumns().iterator();
462 while (foreignColumnNames.hasNext()) {
463 String foreignColumnName = (String) foreignColumnNames.next();
464 Column foreign = foreignTable.getColumn(foreignColumnName);
465
466
467 if (foreign == null) {
468 throw new EngineException("Attempt to set foreign" + " key to nonexistent column: table="
469 + currTable.getName() + ", foreign column=" + foreignColumnName);
470 } else {
471 foreign.addReferrer(currFK);
472 }
473 }
474 }
475 }
476 }
477 }
478
479
480
481
482
483
484
485 public String getJavaName() {
486 if (javaName == null) {
487 List inputs = new ArrayList(2);
488 inputs.add(name);
489 inputs.add(defaultJavaNamingMethod);
490 try {
491 javaName = NameFactory.generateName(NameFactory.JAVA_GENERATOR, inputs);
492 } catch (EngineException e) {
493 log.error(e, e);
494 }
495 }
496 return javaName;
497 }
498
499
500
501
502
503
504 public String getStandardJavaName() {
505 if (javaName == null) {
506 List inputs = new ArrayList(2);
507 inputs.add(name);
508 inputs.add(NameGenerator.CONV_METHOD_JAVANAME);
509 try {
510 javaName = NameFactory.generateName(NameFactory.JAVA_GENERATOR, inputs);
511 } catch (EngineException e) {
512 log.error(e, e);
513 }
514 }
515 return javaName;
516 }
517
518
519
520
521
522
523 @Override
524 public String toString() {
525 StringBuffer result = new StringBuffer();
526
527 result.append("<?xml version=\"1.0\"?>\n");
528 result.append("<!DOCTYPE database SYSTEM \"" + DTDResolver.WEB_SITE_DTD + "\">\n");
529 result.append("<!-- Autogenerated by SQLToXMLSchema! -->\n");
530 result.append("<database name=\"").append(getName()).append('"').append(" package=\"").append(getPackage())
531 .append('"').append(" defaultIdMethod=\"").append(getDefaultIdMethod()).append('"')
532 .append(" baseClass=\"").append(getBaseClass()).append('"').append(" basePeer=\"")
533 .append(getBasePeer()).append('"').append(">\n");
534
535 for (Iterator i = tableList.iterator(); i.hasNext();) {
536 result.append(i.next());
537 }
538
539 result.append("</database>");
540 return result.toString();
541 }
542
543
544
545
546
547
548
549
550
551 public void addOption(String key, String value) {
552 options.put(key, value);
553 }
554
555
556
557
558
559
560
561
562 public String getOption(String key) {
563 return (String) options.get(key);
564 }
565
566
567
568
569
570
571
572
573
574
575 public Map getOptions() {
576 return options;
577 }
578 }