1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46 package org.melati.poem.prepro;
47
48 import java.util.Enumeration;
49 import java.util.Vector;
50 import java.util.Hashtable;
51 import java.util.Arrays;
52 import java.io.StreamTokenizer;
53 import java.io.Writer;
54 import java.io.IOException;
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81 public class TableDef {
82
83 DSD dsd;
84
85 final String nameFromDsd;
86 final String capitalisedName;
87
88 final String name;
89 String displayName;
90 String description;
91 String category;
92 String superclass;
93 int displayOrder;
94 boolean seqCached;
95 int cacheSize = CacheSizeTableQualifier.DEFAULT;
96 private Vector<FieldDef> fields = new Vector<FieldDef>();
97 boolean isAbstract;
98 boolean definesColumns;
99 TableNamingInfo tableNamingInfo = null;
100
101 int nextFieldDisplayOrder = 0;
102
103
104
105 private final Hashtable<String, String> imports = new Hashtable<String, String>();
106 private final Vector<String> tableBaseImports = new Vector<String>();
107 private final Vector<String> persistentBaseImports = new Vector<String>();
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129 public TableDef(DSD dsd, StreamTokenizer tokens, int displayOrder,
130 boolean isAbstract, TableNamingStore nameStore)
131 throws ParsingDSDException,
132 IOException,
133 IllegalityException {
134 this.dsd = dsd;
135 this.displayOrder = displayOrder;
136 this.isAbstract = isAbstract;
137 if (tokens.ttype != StreamTokenizer.TT_WORD)
138 throw new ParsingDSDException("<table name>", tokens);
139 nameFromDsd = tokens.sval;
140 name = nameFromDsd.toLowerCase();
141 capitalisedName = nameFromDsd.substring(0,1).toUpperCase() + nameFromDsd.substring(1);
142
143 if (tokens.nextToken() == StreamTokenizer.TT_WORD) {
144 if (!tokens.sval.equals("extends"))
145 throw new ParsingDSDException("{", tokens);
146 tokens.wordChars('.', '.');
147 try {
148 if (tokens.nextToken() != StreamTokenizer.TT_WORD)
149 throw new ParsingDSDException("<class name>", tokens);
150 } finally {
151 tokens.ordinaryChar('.');
152 }
153 superclass = tokens.sval;
154 } else
155 tokens.pushBack();
156
157 tableNamingInfo = nameStore.add(dsd, dsd.packageName, nameFromDsd, superclass);
158
159 while (tokens.nextToken() == '(') {
160 tokens.nextToken();
161 TableQualifier.from(tokens).apply(this);
162 DSD.expect(tokens, ')');
163 }
164
165 DSD.expect(tokens, '{');
166 while (tokens.nextToken() != '}')
167 fields.addElement(FieldDef.from(this, tokens, nextFieldDisplayOrder++));
168
169 tokens.nextToken();
170
171 }
172
173
174
175
176
177 void addImport(String importName, String destination) {
178 if (!destination.equals("table") && !destination.equals("persistent")
179 && !destination.equals("both"))
180 throw new RuntimeException(
181 "Destination other than 'table', 'persistent' or 'both' used:"
182 + destination);
183
184 String existing = null;
185 existing = imports.put(importName, destination);
186 if (existing != null && existing != destination)
187 imports.put(importName, "both");
188 }
189
190 private final TableDef this_ = this;
191
192
193
194
195
196
197
198 public void generateTableDeclarationJava(Writer w)
199 throws IOException {
200 if (!isAbstract)
201 w.write(" private " + tableNamingInfo.tableMainClassRootReturnClass() +
202 "<" + tableNamingInfo.mainClassRootReturnClass() + ">" +
203 " tab_" + name + " = null;\n");
204 }
205
206
207
208
209
210
211
212 public void generateTableDefinitionJava(Writer w)
213 throws IOException {
214 if (!isAbstract)
215 w.write(" redefineTable(tab_" + name + " = " + "new "
216 + tableNamingInfo.tableMainClassUnambiguous()
217 + (
218 (tableNamingInfo.tableMainClassRootReturnClass().equals(tableNamingInfo.tableMainClassUnambiguous())
219 ?
220 "<"+ tableNamingInfo.mainClassUnambiguous() +">"
221 : "")
222 )
223 + "(this, \"" + nameFromDsd + "\", "
224 + "DefinitionSource.dsd));\n");
225 }
226
227
228
229
230
231
232
233 public void generateTableAccessorJava(Writer w)
234 throws IOException {
235 if (isAbstract)
236 return;
237
238 generateTableAccessorDeclaration(w, false);
239
240 w.write(" {\n" + " return ");
241
242
243 if (!tableNamingInfo.tableMainClassRootReturnClass().equals(tableNamingInfo.tableMainClassUnambiguous()))
244 w.write("(" + tableNamingInfo.tableMainClassRootReturnClass() + ")");
245 w.write("tab_" + name + ";\n }\n");
246 }
247
248
249
250
251
252
253
254
255 public void generateTableAccessorDefnJava(Writer w)
256 throws IOException {
257 if (isAbstract)
258 return;
259
260 generateTableAccessorDeclaration(w, true);
261 w.write(";\n");
262 }
263
264 private void generateTableAccessorDeclaration(Writer w, boolean inInterface) throws IOException {
265 w.write("\n /**\n"
266 + " * Retrieves the " + tableNamingInfo.tableMainClassShortName() + " table.\n"
267 + " *\n"
268 + " * see " + "org.melati.poem.prepro.TableDef"
269 + "#generateTableAccessorJava \n"
270 + " * @return the " + tableNamingInfo.tableMainClassRootReturnClass() + " from this database\n" + " */\n");
271 if (!inInterface)
272 if (!tableNamingInfo.tableMainClassRootReturnClass().equals(tableNamingInfo.tableMainClassUnambiguous()))
273 w.write(" @SuppressWarnings({ \"rawtypes\", \"unchecked\" })\n");
274 w.write(" public " + tableNamingInfo.tableMainClassRootReturnClass() + "<" + tableNamingInfo.mainClassRootReturnClass() + "> get"
275 + tableNamingInfo.tableMainClassShortName() + "()");
276 }
277
278
279
280
281
282
283
284 public void generatePersistentBaseJava(Writer w)
285 throws IOException {
286 for (Enumeration<String> e = persistentBaseImports.elements(); e.hasMoreElements();) {
287 String packageName = e.nextElement();
288 TableNamingInfo tni = dsd.tableNamingStore.tableInfoByTableOrPersistentFQName.get(packageName);
289
290 if (tableNamingInfo.extended != null) {
291 if (tni!=null)
292 if (tni.equals(tableNamingInfo) || tni.equals(tableNamingInfo.extended))
293 w.write("// import " + packageName + ";\n");
294 else
295 w.write("import " + packageName + ";\n");
296 else
297 w.write("import " + packageName + ";\n");
298 } else
299 w.write("import " + packageName + ";\n");
300 }
301 w.write("\n");
302
303
304
305 String requiredReturnClass = tableNamingInfo.tableMainClassRootReturnClass();
306
307 w.write("\n" + "/**\n"
308 + " * Melati POEM generated abstract base class for a "
309 + "<code>Persistent</code> \n" +
310 " * <code>" + nameFromDsd + "</code> Object.\n" + " *\n" +
311 " * see org.melati.poem.prepro.TableDef#generatePersistentBaseJava \n" +
312 " */\n");
313 w.write("public abstract class " + tableNamingInfo.baseClassUnambiguous()
314 + " extends " + tableNamingInfo.superclassMainUnambiguous() + " {\n" + "\n");
315
316 w.write("\n /**\n" +
317 " * Retrieves the Database object.\n" + " * \n" +
318 " * see org.melati.poem.prepro.TableDef#generatePersistentBaseJava \n" +
319 " * @return the database\n" + " */\n");
320 w.write(" public " + dsd.databaseTablesClassName + " get"
321 + dsd.databaseTablesClassName + "() {\n" + " return ("
322 + dsd.databaseTablesClassName + ")getDatabase();\n" + " }\n" + "\n");
323
324 w.write("\n /**\n" + " * Retrieves the <code>" + tableNamingInfo.tableMainClassShortName() + "</code> table \n"
325 + " * which this <code>Persistent</code> is from.\n" + " * \n"
326 + " * see org.melati.poem.prepro.TableDef"
327 + "#generatePersistentBaseJava \n"
328 + " * @return the " + requiredReturnClass + "\n"
329 + " */\n");
330 w.write(" @SuppressWarnings(\"unchecked\")\n");
331 w.write(" public " + requiredReturnClass + "<"+tableNamingInfo.mainClassRootReturnClass()+"> "
332 + tableNamingInfo.tableAccessorMethod() + "() {\n" + " return ("
333 + requiredReturnClass + "<"+tableNamingInfo.mainClassRootReturnClass()+">)getTable();\n" + " }\n\n");
334
335 if (!fields.elements().hasMoreElements()) {
336 w.write(" // There are no Fields in this table, only in its ancestors \n");
337 } else {
338 w.write(" @SuppressWarnings(\"unchecked\")\n");
339 w.write(" private " + tableNamingInfo.tableMainClassUnambiguous() +"<"+tableNamingInfo.mainClassUnambiguous()+"> _"
340 + tableNamingInfo.tableAccessorMethod() + "() {\n" + " return ("
341 + tableNamingInfo.tableMainClassUnambiguous() + "<"+tableNamingInfo.mainClassUnambiguous()+">)getTable();\n" + " }\n\n");
342
343 w.write(" // Fields in this table \n");
344 for (Enumeration<FieldDef> f = fields.elements(); f.hasMoreElements();) {
345 FieldDef fd = f.nextElement();
346 w.write(" /**\n");
347 w.write(DSD.javadocFormat(2, 1,
348 ((fd.displayName != null) ? fd.displayName : fd.name)
349 + ((fd.description != null) ? " - " + fd.description : "")));
350 w.write(" */\n");
351 w.write(" protected ");
352 fd.generateJavaDeclaration(w);
353
354 w.write(";\n");
355 }
356
357 for (Enumeration<FieldDef> f = fields.elements(); f.hasMoreElements();) {
358 FieldDef field = f.nextElement();
359 w.write('\n');
360 field.generateBaseMethods(w);
361 w.write('\n');
362 field.generateFieldCreator(w);
363 }
364 }
365
366
367
368 for (TableDef t : dsd.tablesInDatabase) {
369 if (!t.isAbstract && t.superclass == null) {
370 for (FieldDef f : t.fields) {
371 if (f instanceof ReferenceFieldDef) {
372 ReferenceFieldDef rfd = (ReferenceFieldDef) f;
373 if (rfd.getTargetTableNamingInfo() != null && rfd.getTargetTableNamingInfo().mainClassFQName().equals(tableNamingInfo.mainClassFQName())) {
374 w.write('\n');
375 w.write(" private CachedSelection<" + rfd.shortestUnambiguousClassname +"> "+rfd.name+rfd.shortestUnambiguousClassname + "s = null;\n");
376 w.write(" /** References to this "+tableNamingInfo.mainClassShortName()+" in the " + rfd.shortestUnambiguousClassname+" table via its "+ rfd.name+" field.*/\n");
377 w.write(" @SuppressWarnings(\"unchecked\")\n");
378 w.write(" public Enumeration<" + rfd.shortestUnambiguousClassname +"> get" + StringUtils.capitalised(rfd.name)+rfd.shortestUnambiguousClassname + "s() {\n");
379 w.write(" if (getTroid() == null)\n");
380 w.write(" return new EmptyEnumeration<" + rfd.shortestUnambiguousClassname +">();\n");
381 w.write(" else {\n");
382 w.write(" if (" + rfd.name+rfd.shortestUnambiguousClassname + "s == null)\n");
383 w.write(" " + rfd.name+rfd.shortestUnambiguousClassname + "s =\n");
384 w.write(" get" + dsd.databaseTablesClassName + "().get"+rfd.shortestUnambiguousClassname+"Table().get"+StringUtils.capitalised(rfd.name)+"Column().cachedSelectionWhereEq(getTroid());\n");
385 w.write(" return " + rfd.name+rfd.shortestUnambiguousClassname + "s.objects();\n");
386 w.write(" }\n");
387 w.write(" }\n");
388 w.write("\n");
389 w.write("\n");
390 w.write(" /** References to this "+tableNamingInfo.mainClassShortName()+" in the " + rfd.shortestUnambiguousClassname+" table via its "+ rfd.name+" field, as a List.*/\n");
391 w.write(" public List<" + StringUtils.capitalised(rfd.shortestUnambiguousClassname) +"> get" + StringUtils.capitalised(rfd.name)+rfd.shortestUnambiguousClassname + "List() {\n");
392 w.write(" return Collections.list(get" + StringUtils.capitalised(rfd.name)+rfd.shortestUnambiguousClassname + "s());\n");
393 w.write(" }\n");
394 w.write("\n");
395 w.write("\n");
396 }
397 }
398 }
399 }
400 }
401 w.write('\n');
402
403 w.write("}\n");
404 }
405
406
407
408
409
410
411
412 public void generatePersistentJava(Writer w)
413 throws IOException {
414
415 w.write("import " + dsd.packageName + ".generated."
416 + tableNamingInfo.baseClassShortName() + ";\n");
417 w.write("\n/**\n"
418 + " * Melati POEM generated, programmer modifiable stub \n"
419 + " * for a <code>Persistent</code> <code>"
420 + tableNamingInfo.mainClassShortName() + "</code> object.\n");
421 w.write(" * \n"
422 + (description != null ? " * <p> \n"
423 + " * Description: \n"
424 + DSD.javadocFormat(1, 3, (description + ((description
425 .lastIndexOf(".") != description.length() - 1) ? "." : "")))
426 + " * </p>\n" : ""));
427 w.write(fieldSummaryTable());
428 w.write(" * \n" + " * see org.melati.poem.prepro.TableDef"
429 + "#generatePersistentJava \n" + " */\n");
430 w.write("public class " + tableNamingInfo.mainClassShortName() + " extends "
431 + tableNamingInfo.baseClassShortName() + " {\n");
432
433 w.write("\n /**\n"
434 + " * Constructor \n"
435 + " * for a <code>Persistent</code> <code>"
436 + tableNamingInfo.mainClassShortName()
437 + "</code> object.\n"
438 + (description != null ? (" * <p>\n"
439 + " * Description: \n"
440 + DSD
441 .javadocFormat(2, 3, (description + ((description
442 .lastIndexOf(".") != description.length() - 1) ? "."
443 : ""))) + " * </p>\n") : "") + " * \n"
444 + " * see org.melati.poem.prepro.TableDef"
445 + "#generatePersistentJava \n" + " */\n");
446
447 w.write(" public " + tableNamingInfo.mainClassShortName() + "() { \n"
448 + " super();\n"
449 + "}\n" + "\n"
450 + " // programmer's domain-specific code here\n" + "}\n");
451 }
452
453
454
455
456
457
458
459 public void generateTableBaseJava(Writer w)
460 throws IOException {
461
462 for (Enumeration<String> e = tableBaseImports.elements(); e.hasMoreElements();) {
463 String packageName = e.nextElement();
464 if (ambiguous(packageName))
465 w.write("// FIXME extended table \nimport " + packageName + ";\n");
466 else
467 w.write("import " + packageName + ";\n");
468 }
469
470 w.write("\n");
471 w.write("\n"
472 + "/**\n"
473 + " * Melati POEM generated base class for " + "<code>Table</code> <code>" + nameFromDsd + "</code>.\n");
474 w.write(" *\n"
475 + " * see org.melati.poem.prepro.TableDef"
476 + "#generateTableBaseJava \n" + " */\n\n");
477 w.write("public class " + tableNamingInfo.tableBaseClassShortName() + "<T extends "+tableNamingInfo.mainClassShortName()+"> extends "
478 + tableNamingInfo.superclassTableShortName() + "<T> {\n"
479 + "\n");
480
481 for (Enumeration<FieldDef> f = fields.elements(); f.hasMoreElements();) {
482 w.write(" private ");
483 (f.nextElement()).generateColDecl(w);
484 w.write(" = null;\n");
485 }
486
487 w.write("\n /**\n" + " * Constructor. \n"
488 + " * \n"
489 + " * see org.melati.poem.prepro.TableDef" + "#generateTableBaseJava \n"
490 + " * @param database the POEM database we are using\n"
491 + " * @param name the name of this <code>Table</code>\n"
492 + " * @param definitionSource which definition is being used\n"
493 + " * @throws PoemException if anything goes wrong\n" + " */\n");
494 w.write("\n" + " public " + tableNamingInfo.tableBaseClassShortName() + "(\n"
495 + " Database database, String name,\n"
496 + " DefinitionSource definitionSource)"
497 + " throws PoemException {\n"
498 + " super(database, name, definitionSource);\n" + " }\n" + "\n");
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514 w.write("\n /**\n"
515 + " * Get the database tables.\n" + " *\n"
516 + " * see org.melati.poem.prepro.TableDef#generateTableBaseJava \n"
517 + " * @return the database tables\n"
518 + " */\n");
519 w.write(" public " + dsd.databaseTablesClassName + " get"+ dsd.databaseTablesClassName + "() {\n" +
520 " return (" + dsd.databaseTablesClassName + ")getDatabase();\n" +
521 " }\n" +
522 "\n");
523 Enumeration<FieldDef> fs = fields.elements();
524 w.write(
525 " public void init() throws PoemException {\n" +
526 " super.init();\n");
527
528 for (; fs.hasMoreElements();) {
529 (fs.nextElement()).generateColDefinition(w);
530 if (fs.hasMoreElements())
531 w.write('\n');
532 }
533
534 w.write(" }\n" + "\n");
535
536 for (Enumeration<FieldDef> f = fields.elements(); f.hasMoreElements();) {
537 (f.nextElement()).generateColAccessor(w);
538 w.write('\n');
539 }
540
541
542
543 String requiredReturnClass = tableNamingInfo.mainClassRootReturnClass();
544
545 w.write("\n /**\n" + " * Retrieve the <code>"
546 + tableNamingInfo.mainClassShortName() + "</code> as a <code>"
547 + requiredReturnClass + "</code>.\n"
548 + " *\n"
549 + " * see org.melati.poem.prepro.TableDef" + "#generateTableBaseJava \n"
550 + " * @param troid a Table Row Oject ID\n"
551 + " * @return the <code>Persistent</code> identified "
552 + "by the <code>troid</code>\n" + " */\n");
553 w.write(" public " + requiredReturnClass + " get"
554 + tableNamingInfo.mainClassShortName() + "Object(" + "Integer troid) {\n"
555 + " return (" + requiredReturnClass + ")getObject(troid);\n"
556 + " }\n" + "\n");
557
558 w.write("\n /**\n" + " * Retrieve the <code>"
559 + tableNamingInfo.mainClassShortName() + "</code> \n"
560 + " * as a <code>" + requiredReturnClass + "</code>.\n"
561 + " *\n"
562 + " * see org.melati.poem.prepro.TableDef" + "#generateTableBaseJava \n"
563 + " * @param troid a Table Row Object ID\n"
564 + " * @return the <code>Persistent</code> identified " + " */\n");
565 w.write(" public " + requiredReturnClass + " get"
566 + tableNamingInfo.mainClassShortName() + "Object(" + "int troid) {\n"
567 + " return (" + requiredReturnClass + ")getObject(troid);\n"
568 + " }\n");
569
570 if (!isAbstract)
571 w.write("\n" + " protected JdbcPersistent _newPersistent() {\n"
572 + " return new " + tableNamingInfo.mainClassUnambiguous() + "();\n" + " }"
573 + "\n");
574
575 if (displayName != null)
576 w.write(" public String defaultDisplayName() {\n" + " return "
577 + StringUtils.quoted(displayName, '"') + ";\n" + " }\n" + "\n");
578
579 if (description != null)
580 w.write(" public String defaultDescription() {\n" + " return "
581 + StringUtils.quoted(description, '"') + ";\n" + " }\n" + "\n");
582
583 if (seqCached)
584 w.write(" public boolean defaultRememberAllTroids() {\n"
585 + " return true;\n" + " }\n" + "\n");
586
587 if (cacheSize != CacheSizeTableQualifier.DEFAULT)
588 w.write(" public Integer defaultCacheLimit() {\n"
589 + " return new Integer("
590 + (cacheSize == CacheSizeTableQualifier.UNLIMITED ? "999999999" : ""
591 + cacheSize) + ");\n" + " }\n" + "\n");
592
593 if (category != null)
594 w.write(" public String defaultCategory() {\n" + " return "
595 + StringUtils.quoted(category, '"') + ";\n" + " }\n" + "\n");
596
597 w.write(" public int defaultDisplayOrder() {\n" + " return "
598 + displayOrder + ";\n" + " }\n");
599
600 w.write("}\n");
601 }
602
603 private boolean ambiguous(String packageName) {
604 TableNamingInfo tni = dsd.tableNamingStore.tableInfoByTableOrPersistentFQName.get(packageName);
605 if (tni == null)
606 return false;
607 else if(tni.hidden || tni.hidesOther)
608 return true;
609 return false;
610 }
611
612
613
614
615
616
617
618 public void generateTableJava(Writer w)
619 throws IOException {
620
621 w.write("import " + tableNamingInfo.tableBaseClassFQName() + ";\n");
622 w.write("import org.melati.poem.DefinitionSource;\n");
623 w.write("import org.melati.poem.Database;\n");
624 w.write("import org.melati.poem.PoemException;\n");
625
626 w.write("\n/**\n"
627 + " * Melati POEM generated, programmer modifiable stub \n"
628 + " * for a <code>"
629 + tableNamingInfo.tableMainClassShortName()
630 + "</code> object.\n"
631 + (description != null ? " * <p>\n"
632 + " * Description: \n"
633 + DSD.javadocFormat(1, 3, (description + ((description
634 .lastIndexOf(".") != description.length() - 1) ? "." : "")))
635 + " * </p>\n" : "") + " *\n");
636 w.write(fieldSummaryTable());
637 w.write(" * \n"
638 + " * see org.melati.poem.prepro.TableDef" + "#generateTableJava \n" + " */\n");
639 w.write("public class " + tableNamingInfo.tableMainClassShortName() + "<T extends "+tableNamingInfo.mainClassShortName()+"> extends "
640 + tableNamingInfo.tableBaseClassShortName() + "<"+tableNamingInfo.mainClassShortName()+"> {\n");
641
642 Object o = new Object() {
643 public String toString() {
644 return "\n /**\n"
645 + " * Constructor.\n"
646 + " * \n"
647 + " * see org.melati.poem.prepro.TableDef" + "#generateTableJava \n"
648 + " * @param database the POEM database we are using\n"
649 + " * @param name the name of this <code>Table</code>\n"
650 + " * @param definitionSource which definition is being used\n"
651 + " * @throws PoemException if anything goes wrong\n"
652 + " */\n";
653 }
654 };
655 w.write(o.toString());
656 w.write(" public " + tableNamingInfo.tableMainClassShortName() + "(\n"
657 + " Database database, String name,\n"
658 + " DefinitionSource definitionSource)"
659 + " throws PoemException {\n"
660 + " super(database, name, definitionSource);\n" + " }\n" + "\n"
661 + " // programmer's domain-specific code here\n" + "}\n");
662 }
663
664
665
666
667
668
669
670
671
672 public void generateJava()
673 throws IOException, IllegalityException {
674
675 boolean hasDisplayLevel = false;
676 boolean hasSearchability = false;
677
678 boolean needSelectionImports = false;
679 for (TableDef t : dsd.tablesInDatabase) {
680 if (!t.isAbstract && t.superclass == null)
681 for (FieldDef f : t.fields) {
682 if (f instanceof ReferenceFieldDef) {
683 ReferenceFieldDef rfd = (ReferenceFieldDef) f;
684 if (!(rfd.getTargetTableNamingInfo() == null) &&
685 rfd.getTargetTableNamingInfo().mainClassFQName().equals(tableNamingInfo.mainClassFQName())) {
686 needSelectionImports = true;
687 addImport(rfd.table.tableNamingInfo.mainClassFQName(), "persistent");
688 }
689 }
690 }
691 }
692 if (needSelectionImports) {
693 addImport("org.melati.poem.CachedSelection", "persistent");
694 addImport("org.melati.poem.util.EmptyEnumeration","persistent");
695 addImport("java.util.Enumeration","persistent");
696 addImport("java.util.List","persistent");
697 addImport("java.util.Collections","persistent");
698 }
699
700 int fieldCount = 0;
701 for (Enumeration<FieldDef> e = fields.elements(); e.hasMoreElements();) {
702 fieldCount++;
703 FieldDef f = e.nextElement();
704 if (f.displayLevel != null)
705 hasDisplayLevel = true;
706 if (f.searchability != null)
707 hasSearchability = true;
708 }
709 if (fieldCount == 0 && !isAbstract && tableNamingInfo.superclass == null)
710 throw new NonAbstractEmptyTableException(name);
711
712 if (!isAbstract)
713 addImport("org.melati.poem.JdbcPersistent", "table");
714 if (hasDisplayLevel)
715 addImport("org.melati.poem.DisplayLevel", "table");
716 if (hasSearchability)
717 addImport("org.melati.poem.Searchability", "table");
718 addImport(tableNamingInfo.objectFQName, "table");
719 if (definesColumns) {
720 addImport("org.melati.poem.Column", "both");
721 addImport("org.melati.poem.Field", "both");
722 }
723 if (tableNamingInfo.superclassMainUnambiguous().equals("JdbcPersistent")) {
724 addImport("org.melati.poem.JdbcPersistent", "persistent");
725 } else {
726 addImport(tableNamingInfo.superclassMainFQName(), "persistent");
727 }
728
729
730
731 addImport(tableNamingInfo.tableMainClassFQName(), "persistent");
732 addImport(dsd.packageName + "." + dsd.databaseTablesClassName, "persistent");
733
734 addImport("org.melati.poem.Database", "table");
735 addImport("org.melati.poem.DefinitionSource", "table");
736 addImport("org.melati.poem.PoemException", "table");
737
738 if (!isAbstract)
739 addImport("org.melati.poem.Persistent", "table");
740
741 if (tableNamingInfo.superclassTableUnambiguous().equals("Table")) {
742 addImport("org.melati.poem.Table", "table");
743 } else {
744 addImport(tableNamingInfo.superclassTableFQName(), "table");
745 }
746 addImport(dsd.packageName + "." + dsd.databaseTablesClassName, "table");
747 addImport(tableNamingInfo.mainClassFQName(), "persistent");
748
749
750 for (Enumeration<String> i = imports.keys(); i.hasMoreElements();) {
751 String fqKey;
752 String key = i.nextElement();
753 if (key.indexOf(".") == -1) {
754 TableNamingInfo targetTable = (TableNamingInfo) dsd.tableNamingStore.tableInfoByPersistentShortName
755 .get(key);
756 if (targetTable == null)
757 throw new RuntimeException("No TableNamingInfo for " + key +
758 ". This is probably a typo either in the table definition name or in a reference field.");
759 fqKey = targetTable.objectFQName;
760 String destination = imports.get(key);
761 imports.remove(key);
762 addImport(fqKey, destination);
763 }
764 }
765 for (Enumeration<String> i = imports.keys(); i.hasMoreElements();) {
766 String fqKey;
767 String key = i.nextElement();
768
769 if (key.indexOf(".") == -1) {
770 TableNamingInfo targetTable =
771 (TableNamingInfo)dsd.tableNamingStore.tableInfoByPersistentShortName.get(key);
772 fqKey = targetTable.objectFQName;
773 } else {
774 fqKey = key;
775 }
776 String destination = imports.get(key);
777 if (destination == "table") {
778 tableBaseImports.addElement(fqKey);
779 } else if (destination == "persistent") {
780 persistentBaseImports.addElement(fqKey);
781 } else {
782 tableBaseImports.addElement(fqKey);
783 persistentBaseImports.addElement(fqKey);
784 }
785 }
786 Object[] t = tableBaseImports.toArray();
787 Object[] p = persistentBaseImports.toArray();
788 Arrays.sort(t);
789 Arrays.sort(p);
790 tableBaseImports.removeAllElements();
791 persistentBaseImports.removeAllElements();
792 for (int i = 0; i < t.length; i++)
793 tableBaseImports.addElement((String)t[i]);
794 for (int i = 0; i < p.length; i++)
795 persistentBaseImports.addElement((String)p[i]);
796
797 dsd.createJava(tableNamingInfo.baseClassShortName(), new Generator() {
798 public void process(Writer w)
799 throws IOException {
800 this_.generatePersistentBaseJava(w);
801 }
802 }, true);
803
804 dsd.createJava(tableNamingInfo.mainClassShortName(), new Generator() {
805 public void process(Writer w)
806 throws IOException {
807 this_.generatePersistentJava(w);
808 }
809 }, false);
810
811 dsd.createJava(tableNamingInfo.tableBaseClassShortName(), new Generator() {
812 public void process(Writer w)
813 throws IOException {
814 this_.generateTableBaseJava(w);
815 }
816 }, true);
817
818 dsd.createJava(tableNamingInfo.tableMainClassShortName(), new Generator() {
819 public void process(Writer w)
820 throws IOException {
821 this_.generateTableJava(w);
822 }
823 }, false);
824 }
825
826 String fieldSummaryTable() {
827 StringBuffer table = new StringBuffer();
828 table.append(" * \n" + " * <table> \n" + " * <tr><th colspan='3'>\n"
829 + " * Field summary for SQL table <code>" + nameFromDsd + "</code>\n"
830 + " * </th></tr>\n"
831 + " * <tr><th>Name</th><th>Type</th><th>Description</th></tr>\n");
832 for (Enumeration<FieldDef> f = fields.elements(); f.hasMoreElements();) {
833 FieldDef fd = f.nextElement();
834 table.append(DSD.javadocFormat(1, 1, "<tr><td> " + fd.name
835 + " </td><td> " + fd.typeShortName + " </td><td> "
836 + ((fd.description != null) ? fd.description : " ")
837 + " </td></tr>"));
838 }
839 table.append(" * </table> \n");
840 return table.toString();
841 }
842 }