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.Vector;
49 import java.io.StreamTokenizer;
50 import java.io.Writer;
51 import java.io.IOException;
52
53
54
55
56
57
58 public abstract class FieldDef {
59
60 protected final TableDef table;
61
62 protected final String name;
63
64 protected final String suffix;
65
66 protected int displayOrder;
67
68 String displayName;
69
70 String description;
71
72 protected final String type;
73
74 protected final String rawType;
75
76 protected final Vector qualifiers;
77
78 final String mainClass;
79
80 final String tableAccessorMethod;
81
82 protected String displayLevel = null;
83
84 protected String searchability = null;
85
86 private boolean sortDescending = false;
87
88 int displayOrderPriority = -1;
89
90 private boolean isNullable = false;
91
92 private boolean isTroidColumn = false;
93
94 private boolean isDeletedColumn = false;
95
96 private boolean isEditable = true;
97
98 private boolean isCreateable = true;
99
100 private boolean isIndexed = false;
101
102 private boolean isUnique = false;
103
104 boolean isCompareOnly = false;
105
106 private int width = -1, height = -1;
107
108 String renderinfo = null;
109
110 protected int lineNumber;
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131 public FieldDef(int lineNo, TableDef table, String name, String type,
132 String rawType, int displayOrder, Vector qualifiers)
133 throws IllegalityException {
134 this.lineNumber = lineNo;
135 this.table = table;
136 this.name = name;
137 this.displayOrder = displayOrder;
138 this.suffix = StringUtils.capitalised(name);
139 this.type = type;
140 this.rawType = rawType;
141 this.qualifiers = qualifiers;
142
143 this.mainClass = table.naming.mainClassUnambiguous();
144 this.tableAccessorMethod = table.naming.tableAccessorMethod();
145
146 for (int q = 0; q < qualifiers.size(); ++q) {
147 ((FieldQualifier)qualifiers.elementAt(q)).apply(this);
148 }
149
150 }
151
152
153 public String toString() {
154 return table.name + "." + name + " (" + (isNullable ? "nullable " : "")
155 + type + ")";
156 }
157
158 private static void fieldQualifiers(Vector qualifiers, StreamTokenizer tokens)
159 throws ParsingDSDException, IOException {
160 while (tokens.ttype == '(') {
161 tokens.nextToken();
162 qualifiers.addElement(FieldQualifier.from(tokens));
163 DSD.expect(tokens, ')');
164 tokens.nextToken();
165 }
166 }
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187 public static FieldDef from(TableDef table, StreamTokenizer tokens,
188 int displayOrder) throws ParsingDSDException, IOException,
189 IllegalityException {
190 table.addImport("org.melati.poem.AccessPoemException", "both");
191 table.addImport("org.melati.poem.ValidationPoemException", "table");
192 table.addImport("org.melati.poem.Persistent", "table");
193
194 table.definesColumns = true;
195 Vector qualifiers = new Vector();
196 fieldQualifiers(qualifiers, tokens);
197 if (tokens.ttype != StreamTokenizer.TT_WORD)
198 throw new ParsingDSDException("<field type>", tokens);
199 String type = tokens.sval;
200
201 if (type.equals("byte")) {
202 if (tokens.nextToken() != '[' || tokens.nextToken() != ']')
203 throw new ParsingDSDException("[", tokens);
204 type = "byte[]";
205 }
206
207 if (tokens.nextToken() != StreamTokenizer.TT_WORD)
208 throw new ParsingDSDException("<field name>", tokens);
209 String name = tokens.sval;
210 tokens.nextToken();
211 fieldQualifiers(qualifiers, tokens);
212 DSD.expect(tokens, ';');
213 int lineNo = tokens.lineno();
214 if (type.equals("Integer"))
215 return new IntegerFieldDef(lineNo, table, name, displayOrder, qualifiers);
216 if (type.equals("Long"))
217 return new LongFieldDef(lineNo, table, name, displayOrder, qualifiers);
218 else if (type.equals("Double"))
219 return new DoubleFieldDef(lineNo, table, name, displayOrder, qualifiers);
220 else if (type.equals("Boolean"))
221 return new BooleanFieldDef(lineNo, table, name, displayOrder, qualifiers);
222 else if (type.equals("String"))
223 return new StringFieldDef(lineNo, table, name, displayOrder, qualifiers);
224 else if (type.equals("Password"))
225 return new PasswordFieldDef(lineNo, table, name, displayOrder, qualifiers);
226 else if (type.equals("Date"))
227 return new DateFieldDef(lineNo, table, name, displayOrder, qualifiers);
228 else if (type.equals("Timestamp"))
229 return new TimestampFieldDef(lineNo, table, name, displayOrder,
230 qualifiers);
231 else if (type.equals("ColumnType"))
232 return new ColumnTypeFieldDef(lineNo, table, name, displayOrder,
233 qualifiers);
234 else if (type.equals("DisplayLevel"))
235 return new DisplayLevelFieldDef(lineNo, table, name, displayOrder,
236 qualifiers);
237 else if (type.equals("Searchability"))
238 return new SearchabilityFieldDef(lineNo, table, name, displayOrder,
239 qualifiers);
240 else if (type.equals("IntegrityFix"))
241 return new IntegrityFixFieldDef(lineNo, table, name, displayOrder,
242 qualifiers);
243 else if (type.equals("BigDecimal"))
244 return new BigDecimalFieldDef(lineNo, table, name, displayOrder,
245 qualifiers);
246 else if (type.equals("byte[]"))
247 return new BinaryFieldDef(lineNo, table, name, displayOrder, qualifiers);
248 else
249 return new ReferenceFieldDef(lineNo, table, name, displayOrder, type,
250 qualifiers);
251 }
252
253
254
255
256
257
258
259
260
261
262 public void generateBaseMethods(Writer w) throws IOException {
263 w.write("\n /**\n" + " * Retrieves the <code>" + suffix
264 + "</code> value, without locking, \n" + " * for this <code>"
265 + table.suffix + "</code> <code>Persistent</code>.\n" + " *\n"
266 + " * @see " + "org.melati.poem.prepro.FieldDef"
267 + "#generateBaseMethods \n" + " * @return the " + rawType + " " + name
268 + "\n" + " */\n");
269 w.write(" public " + rawType + " get" + suffix + "_unsafe() {\n"
270 + " return " + name + ";\n" + " }\n" + "\n");
271 w.write("\n /**\n" + " * Sets the <code>" + suffix
272 + "</code> value directly, without checking, \n" + " * for this "
273 + table.suffix + " <code>Persistent</code>.\n" + " * \n"
274 + " * @see " + "org.melati.poem.prepro.FieldDef"
275 + "#generateBaseMethods \n"
276 + " * @param cooked the pre-validated value to set\n" + " */\n");
277 w.write(" public void set" + suffix + "_unsafe(" + rawType
278 + " cooked) {\n" + " " + name + " = cooked;\n" + " }\n");
279 }
280
281
282
283
284
285
286
287
288
289 public void generateFieldCreator(Writer w) throws IOException {
290 w.write("\n /**\n" + " * Retrieves the <code>" + suffix
291 + "</code> value as a <code>Field</code>\n" + " * from this <code>"
292 + table.suffix + "</code> <code>Persistent</code>.\n" + " * \n"
293 + " * @see " + "org.melati.poem.prepro.FieldDef"
294 + "#generateFieldCreator \n" + " * @throws AccessPoemException \n"
295 + " * if the current <code>AccessToken</code> \n"
296 + " * does not confer write access rights\n"
297 + " * @return the " + rawType + " " + name + "\n" + " */\n");
298 w.write(" public Field get" + suffix + "Field() "
299 + "throws AccessPoemException {\n" + " Column c = _"
300 + tableAccessorMethod + "()." + "get" + suffix + "Column();\n"
301 + " return new Field(c.getRaw(this), c);\n" + " }\n");
302 }
303
304
305
306
307
308
309
310
311
312 public abstract void generateJavaDeclaration(Writer w) throws IOException;
313
314
315
316
317
318
319
320
321
322 public void generateColDecl(Writer w) throws IOException {
323 w.write("Column col_" + name);
324 }
325
326
327
328
329
330
331
332
333
334 public void generateColAccessor(Writer w) throws IOException {
335 w.write("\n /**\n" + " * Retrieves the <code>" + suffix
336 + "</code> <code>Column</code> for this \n" + " * <code>"
337 + table.suffix + "</code> <code>Table</code>.\n" + " * \n"
338 + " * @see " + "org.melati.poem.prepro.FieldDef"
339 + "#generateColAccessor \n" + " * @return the " + name
340 + " <code>Column</code>\n" + " */\n");
341 w.write(" public final Column get" + suffix + "Column() {\n"
342 + " return col_" + name + ";\n" + " }\n");
343 }
344
345
346
347
348
349
350
351
352
353
354 protected void generateColRawAccessors(Writer w) throws IOException {
355 w.write(" public Object getRaw_unsafe(Persistent g)\n"
356 + " throws AccessPoemException {\n"
357 + " return ((" + mainClass + ")g)." + "get" + suffix
358 + "_unsafe();\n" + " }\n" + "\n");
359
360 w.write(" public void setRaw_unsafe(Persistent g, Object raw)\n"
361 + " throws AccessPoemException {\n" + " (("
362 + mainClass + ")g).set" + suffix + "_unsafe((" + rawType + ")raw);\n"
363 + " }\n");
364 }
365
366
367
368
369
370
371
372
373
374
375 public void generateColDefinition(Writer w) throws IOException {
376 w
377 .write(" defineColumn(col_"
378 + name
379 + " =\n"
380 + " new Column(this, \""
381 + name
382 + "\",\n"
383 + " "
384 + poemTypeJava()
385 + ",\n"
386 + " DefinitionSource.dsd) { \n"
387 + " public Object getCooked(Persistent g)\n"
388 + " throws AccessPoemException, PoemException {\n"
389 + " return (("
390 + mainClass
391 + ")g).get"
392 + suffix
393 + "();\n"
394 + " }\n"
395 + "\n"
396 + " public void setCooked(Persistent g, Object cooked)\n"
397 + " throws AccessPoemException, ValidationPoemException {\n"
398 + " ((" + mainClass + ")g).set" + suffix + "((" + type
399 + ")cooked);\n" + " }\n" + "\n"
400 + " public Field asField(Persistent g) {\n"
401 + " return ((" + mainClass + ")g).get" + suffix
402 + "Field();\n" + " }\n" + "\n");
403
404 if (isTroidColumn || !isEditable)
405 w.write(" protected boolean defaultUserEditable() {\n"
406 + " return false;\n" + " }\n" + "\n");
407
408 if (isTroidColumn || !isCreateable)
409 w.write(" protected boolean defaultUserCreateable() {\n"
410 + " return false;\n" + " }\n" + "\n");
411
412 if (displayLevel != null)
413 w.write(" protected DisplayLevel defaultDisplayLevel() {\n"
414 + " return DisplayLevel." + displayLevel + ";\n"
415 + " }\n" + "\n");
416
417 if (searchability != null)
418 w.write(" protected Searchability defaultSearchability() {\n"
419 + " return Searchability." + searchability + ";\n"
420 + " }\n" + "\n");
421
422 if (displayOrderPriority != -1)
423 w.write(" protected Integer defaultDisplayOrderPriority() {\n"
424 + " return new Integer(" + displayOrderPriority + ");\n"
425 + " }\n" + "\n");
426
427 if (sortDescending)
428 w.write(" protected boolean defaultSortDescending() {\n"
429 + " return true;\n" + " }\n" + "\n");
430
431 if (displayName != null)
432 w.write(" protected String defaultDisplayName() {\n"
433 + " return " + StringUtils.quoted(displayName, '"')
434 + ";\n" + " }\n" + "\n");
435
436 w
437 .write(" protected int defaultDisplayOrder() {\n"
438 + " return " + displayOrder + ";\n" + " }\n"
439 + "\n");
440
441 if (description != null)
442 w.write(" protected String defaultDescription() {\n"
443 + " return " + StringUtils.quoted(description, '"')
444 + ";\n" + " }\n" + "\n");
445
446 if (isIndexed)
447 w.write(" protected boolean defaultIndexed() {\n"
448 + " return true;\n" + " }\n" + "\n");
449
450 if (isUnique)
451 w.write(" protected boolean defaultUnique() {\n"
452 + " return true;\n" + " }\n" + "\n");
453
454 if (width != -1)
455 w.write(" protected int defaultWidth() {\n"
456 + " return " + width + ";\n" + " }\n" + "\n");
457
458 if (height != -1)
459 w.write(" protected int defaultHeight() {\n"
460 + " return " + height + ";\n" + " }\n" + "\n");
461
462 if (renderinfo != null)
463 w.write(" protected String defaultRenderinfo() {\n"
464 + " return " + StringUtils.quoted(renderinfo, '"') + ";\n"
465 + " }\n" + "\n");
466
467 generateColRawAccessors(w);
468
469 w.write(" });\n");
470 }
471
472
473 public abstract String poemTypeJava();
474
475
476
477
478 public boolean isDeletedColumn() {
479 return isDeletedColumn;
480 }
481
482
483
484
485
486
487 public void setDeletedColumn(boolean isDeletedColumn) {
488 if (this.isDeletedColumn)
489 throw new IllegalityException(lineNumber,
490 "Deleted qualifier already set true.");
491 this.isDeletedColumn = isDeletedColumn;
492 }
493
494
495
496
497 public boolean isTroidColumn() {
498 return isTroidColumn;
499 }
500
501
502
503
504
505
506 public void setTroidColumn(boolean isTroidColumn) {
507 if (this.isTroidColumn)
508 throw new IllegalityException(lineNumber,
509 "Troid qualifier already set true.");
510 this.isTroidColumn = isTroidColumn;
511 }
512
513
514
515
516 public boolean isNullable() {
517 return isNullable;
518 }
519
520
521
522
523
524
525 public void setNullable(boolean isNullable) {
526 if (this.isNullable)
527 throw new IllegalityException(lineNumber,
528 "Nullable qualifier already set true.");
529 this.isNullable = isNullable;
530 }
531
532
533
534
535 public boolean isEditable() {
536 return isEditable;
537 }
538
539
540
541
542
543
544 public void setEditable(boolean isEditable) {
545 if (!this.isEditable)
546 throw new IllegalityException(lineNumber,
547 "Editable qualifier already set true.");
548 this.isEditable = isEditable;
549 }
550
551
552
553
554 public boolean isSortDescending() {
555 return sortDescending;
556 }
557
558
559
560
561
562
563 public void setSortDescending(boolean sortDescending) {
564 if (this.sortDescending)
565 throw new IllegalityException(lineNumber,
566 "Sort descending qualifier already set true.");
567 this.sortDescending = sortDescending;
568 }
569
570
571
572
573 public boolean isCreateable() {
574 return isCreateable;
575 }
576
577
578
579
580
581
582 public void setCreateable(boolean isCreateable) {
583 if (!this.isCreateable)
584 throw new IllegalityException(lineNumber,
585 "Creatable qualifier already set true.");
586 this.isCreateable = isCreateable;
587 }
588
589
590
591
592 public boolean isIndexed() {
593 return isIndexed;
594 }
595
596
597
598
599
600 public void setIndexed(boolean isIndexed) {
601 if (this.isIndexed)
602 throw new IllegalityException(lineNumber,
603 "Indexed qualifier already set true.");
604 this.isIndexed = isIndexed;
605 }
606
607
608
609
610 public boolean isUnique() {
611 return isUnique;
612 }
613
614
615
616
617
618
619 public void setUnique(boolean isUnique) {
620 if (this.isUnique)
621 throw new IllegalityException(lineNumber,
622 "Unique qualifier already set true.");
623 this.isUnique = isUnique;
624 }
625
626
627
628
629 public int getWidth() {
630 return width;
631 }
632
633
634
635
636
637
638 public void setWidth(int width) {
639 if (this.width != -1)
640 throw new IllegalityException(lineNumber, "Size already set to "
641 + this.width + " cannot overwrite with " + width);
642 this.width = width;
643 }
644
645
646
647
648 public int getHeight() {
649 return height;
650 }
651
652
653
654
655
656
657 public void setHeight(int height) {
658 if (this.height != -1)
659 throw new IllegalityException(lineNumber, "Height already set to "
660 + this.width + " cannot overwrite with " + width);
661 this.height = height;
662 }
663 }