1 /*
2 * $Source$
3 * $Revision$
4 *
5 * Copyright (C) 2000 William Chesters
6 *
7 * Part of Melati (http://melati.org), a framework for the rapid
8 * development of clean, maintainable web applications.
9 *
10 * Melati is free software; Permission is granted to copy, distribute
11 * and/or modify this software under the terms either:
12 *
13 * a) the GNU General Public License as published by the Free Software
14 * Foundation; either version 2 of the License, or (at your option)
15 * any later version,
16 *
17 * or
18 *
19 * b) any version of the Melati Software License, as published
20 * at http://melati.org
21 *
22 * You should have received a copy of the GNU General Public License and
23 * the Melati Software License along with this program;
24 * if not, write to the Free Software Foundation, Inc.,
25 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA to obtain the
26 * GNU General Public License and visit http://melati.org to obtain the
27 * Melati Software License.
28 *
29 * Feel free to contact the Developers of Melati (http://melati.org),
30 * if you would like to work out a different arrangement than the options
31 * outlined here. It is our intention to allow Melati to be used by as
32 * wide an audience as possible.
33 *
34 * This program is distributed in the hope that it will be useful,
35 * but WITHOUT ANY WARRANTY; without even the implied warranty of
36 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
37 * GNU General Public License for more details.
38 *
39 * Contact details for copyright holder:
40 *
41 * William Chesters <williamc At paneris.org>
42 * http://paneris.org/~williamc
43 * Obrechtstraat 114, 2517VX Den Haag, The Netherlands
44 */
45
46 package org.melati.poem;
47
48 import java.sql.Date;
49 import java.sql.Timestamp;
50
51 /**
52 * An object factory which produces {@link PoemType} objects
53 * given a {@link Database} and a code.
54 *
55 * See {@link #forCode(Database, int)}.
56 *
57 * I'd just like you to know that I had to type this file in again after
58 * deleting it. It's not even very nice is it?
59 */
60
61 public abstract class PoemTypeFactory {
62
63 /**
64 * Integer code for this type factory.
65 * <p>
66 * Negative for atomic types and the troid of the table metadata
67 * object for row types.
68 */
69 final Integer code;
70
71 /**
72 * Constructor.
73 * @param c PoemType code
74 */
75 public PoemTypeFactory(int c) {
76 this.code = new Integer(c);
77 }
78
79 /**
80 * A Parameter object which knows whether a {@link PoemType}
81 * is <tt>nullable</tt> and its <tt>size</tt>.
82 */
83 public interface Parameter {
84 /**
85 * @return the nullability of the parameter
86 */
87 boolean getNullable();
88 /**
89 * @return its size
90 */
91 int getSize();
92 }
93
94 abstract <T>SQLPoemType<T> typeOf(Database database, Parameter info);
95
96 /**
97 * @return the arbitrary code for this type
98 */
99 public Integer getCode() {
100 return code;
101 }
102
103 /**
104 * @return the machine name of this type
105 */
106 public abstract String getName();
107
108 /**
109 * @return the display name of this type
110 */
111 public String getDisplayName() {
112 return getName();
113 }
114
115 /**
116 * @return a description for this type
117 */
118 public abstract String getDescription();
119
120 /** Troid column factory. */
121 public static final PoemTypeFactory TROID;
122 /** Deleted column factory. */
123 public static final PoemTypeFactory DELETED;
124 /** Type column factory. Used to denote a column which contains a PoemTypeFactory. */
125 public static final PoemTypeFactory TYPE;
126
127 /* Base type factories. */
128 /** Boolean base-type factory. */
129 public static final PoemTypeFactory BOOLEAN;
130 /** Integer base-type factory. */
131 public static final PoemTypeFactory INTEGER;
132 /** Double base-type factory. */
133 public static final PoemTypeFactory DOUBLE;
134 /** Long base-type factory. */
135 public static final PoemTypeFactory LONG;
136 /** BigDecimal base-type factory. */
137 public static final PoemTypeFactory BIGDECIMAL;
138 /** String base-type factory. */
139 public static final PoemTypeFactory STRING;
140 /** Password base-type factory. */
141 public static final PoemTypeFactory PASSWORD;
142 /** Date base-type factory. */
143 public static final PoemTypeFactory DATE;
144 /** Timestamp base-type factory. */
145 public static final PoemTypeFactory TIMESTAMP;
146 /** Binary base-type factory. */
147 public static final PoemTypeFactory BINARY;
148
149 /** Poem Displaylevel factory. */
150 public static final PoemTypeFactory DISPLAYLEVEL;
151 /** Poem Searchability factory. */
152 public static final PoemTypeFactory SEARCHABILITY;
153 /** Poem IntegrityFix factory. */
154 public static final PoemTypeFactory INTEGRITYFIX;
155
156 /** Time base-type factory. */
157 public static final PoemTypeFactory TIME;
158
159 // Add new types here, at the end, or types in columnInfo will break
160
161
162 // private static final void extractRange(Parameter info, BasePoemType type) {
163 // try {
164 // type.setRawRange(type.rawOfString(info.getRangelow_string()),
165 // type.rawOfString(into.getRangehigh_string()));
166 // }
167 // catch (ValidationPoemException e) {
168 // throw new RangeExtractionException(info, type, e);
169 // }
170 // }
171
172 // YUCK this counter means you will need to add new base types to the end of the list
173 private static int n = -1;
174 static final PoemTypeFactory[] atomTypeFactories =
175 {
176 TROID = new PoemTypeFactory(n--) {
177 /**
178 * {@inheritDoc}
179 * @see org.melati.poem.PoemTypeFactory#typeOf
180 * (org.melati.poem.Database, org.melati.poem.PoemTypeFactory.Parameter)
181 */
182 @SuppressWarnings("unchecked")
183 public SQLPoemType<?> typeOf(Database database, Parameter info) {
184 return TroidPoemType.it;
185 }
186
187 /**
188 * {@inheritDoc}
189 * @see org.melati.poem.PoemTypeFactory#getName()
190 */
191 public String getName() {
192 return "TROID";
193 }
194
195 /**
196 * @see org.melati.poem.PoemTypeFactory#getDescription()
197 */
198 public String getDescription() {
199 return "...";
200 }
201 }, DELETED = new PoemTypeFactory(n--) {
202 /**
203 * @see org.melati.poem.PoemTypeFactory#typeOf
204 * (org.melati.poem.Database, org.melati.poem.PoemTypeFactory.Parameter)
205 */
206 @SuppressWarnings("unchecked")
207 public SQLPoemType<?> typeOf(Database database, Parameter info) {
208 return DeletedPoemType.it;
209 }
210
211 /**
212 * {@inheritDoc}
213 * @see org.melati.poem.PoemTypeFactory#getName()
214 */
215 public String getName() {
216 return "DELETED";
217 }
218
219 /**
220 * {@inheritDoc}
221 * @see org.melati.poem.PoemTypeFactory#getDescription()
222 */
223 public String getDescription() {
224 return "...";
225 }
226 }, TYPE = new PoemTypeFactory(n--) {
227 /**
228 * {@inheritDoc}
229 * @see org.melati.poem.PoemTypeFactory#typeOf
230 * (org.melati.poem.Database, org.melati.poem.PoemTypeFactory.Parameter)
231 */
232 @SuppressWarnings("unchecked")
233 public SQLPoemType<?> typeOf(Database database, Parameter info) {
234 return new ColumnTypePoemType(database);
235 }
236
237 /**
238 * {@inheritDoc}
239 * @see org.melati.poem.PoemTypeFactory#getName()
240 */
241 public String getName() {
242 return "TYPE";
243 }
244
245 /**
246 * {@inheritDoc}
247 * @see org.melati.poem.PoemTypeFactory#getDescription()
248 */
249 public String getDescription() {
250 return "...";
251 }
252 }, BOOLEAN = new PoemTypeFactory(n--) {
253 /**
254 * {@inheritDoc}
255 * @see org.melati.poem.PoemTypeFactory#typeOf
256 * (org.melati.poem.Database, org.melati.poem.PoemTypeFactory.Parameter)
257 */
258 @SuppressWarnings("unchecked")
259 public SQLPoemType<?> typeOf(Database database, Parameter info) {
260 return new BooleanPoemType(info.getNullable());
261 }
262
263 /**
264 * {@inheritDoc}
265 * @see org.melati.poem.PoemTypeFactory#getName()
266 */
267 public String getName() {
268 return "BOOLEAN";
269 }
270
271 /**
272 * {@inheritDoc}
273 * @see org.melati.poem.PoemTypeFactory#getDescription()
274 */
275 public String getDescription() {
276 return "...";
277 }
278 }, INTEGER = new PoemTypeFactory(n--) {
279 /**
280 * {@inheritDoc}
281 * @see org.melati.poem.PoemTypeFactory#typeOf
282 * (org.melati.poem.Database, org.melati.poem.PoemTypeFactory.Parameter)
283 */
284 @SuppressWarnings("unchecked")
285 public SQLPoemType<?> typeOf(Database database, Parameter info) {
286 return new IntegerPoemType(info.getNullable());
287 }
288
289 /**
290 * @see org.melati.poem.PoemTypeFactory#getName()
291 */
292 public String getName() {
293 return "INTEGER";
294 }
295
296 /**
297 * @see org.melati.poem.PoemTypeFactory#getDescription()
298 */
299 public String getDescription() {
300 return "...";
301 }
302 }, DOUBLE = new PoemTypeFactory(n--) {
303 /**
304 * {@inheritDoc}
305 * @see org.melati.poem.PoemTypeFactory#typeOf
306 * (org.melati.poem.Database, org.melati.poem.PoemTypeFactory.Parameter)
307 */
308 @SuppressWarnings("unchecked")
309 public SQLPoemType<?> typeOf(Database database, Parameter info) {
310 return new DoublePoemType(info.getNullable());
311 }
312
313 /**
314 * {@inheritDoc}
315 * @see org.melati.poem.PoemTypeFactory#getName()
316 */
317 public String getName() {
318 return "DOUBLE";
319 }
320
321 /**
322 * {@inheritDoc}
323 * @see org.melati.poem.PoemTypeFactory#getDescription()
324 */
325 public String getDescription() {
326 return "...";
327 }
328 }, STRING = new PoemTypeFactory(n--) {
329 /**
330 * {@inheritDoc}
331 * @see org.melati.poem.PoemTypeFactory#typeOf
332 * (org.melati.poem.Database, org.melati.poem.PoemTypeFactory.Parameter)
333 */
334 @SuppressWarnings("unchecked")
335 public SQLPoemType<?> typeOf(Database database, Parameter info) {
336 return new StringPoemType(info.getNullable(), info.getSize());
337 }
338
339 /**
340 * {@inheritDoc}
341 * @see org.melati.poem.PoemTypeFactory#getName()
342 */
343 public String getName() {
344 return "STRING";
345 }
346
347 /**
348 * {@inheritDoc}
349 * @see org.melati.poem.PoemTypeFactory#getDescription()
350 */
351 public String getDescription() {
352 return "...";
353 }
354 }, DATE = new PoemTypeFactory(n--) {
355 /**
356 * @see org.melati.poem.PoemTypeFactory#typeOf
357 * (org.melati.poem.Database, org.melati.poem.PoemTypeFactory.Parameter)
358 */
359 @SuppressWarnings("unchecked")
360 public SQLPoemType<Date> typeOf(Database database, Parameter info) {
361 return new DatePoemType(info.getNullable());
362 }
363
364 /**
365 * {@inheritDoc}
366 * @see org.melati.poem.PoemTypeFactory#getName()
367 */
368 public String getName() {
369 return "DATE";
370 }
371
372 /**
373 * {@inheritDoc}
374 * @see org.melati.poem.PoemTypeFactory#getDescription()
375 */
376 public String getDescription() {
377 return "...";
378 }
379 }, PASSWORD = new PoemTypeFactory(n--) {
380 /**
381 * @see org.melati.poem.PoemTypeFactory#typeOf
382 * (org.melati.poem.Database, org.melati.poem.PoemTypeFactory.Parameter)
383 */
384 @SuppressWarnings("unchecked")
385 public SQLPoemType<?> typeOf(Database database, Parameter info) {
386 return new PasswordPoemType(info.getNullable(), info.getSize());
387 }
388
389 /**
390 * @see org.melati.poem.PoemTypeFactory#getName()
391 */
392 public String getName() {
393 return "PASSWORD";
394 }
395
396 /**
397 * {@inheritDoc}
398 * @see org.melati.poem.PoemTypeFactory#getDescription()
399 */
400 public String getDescription() {
401 return "...";
402 }
403 }, TIMESTAMP = new PoemTypeFactory(n--) {
404 /**
405 * {@inheritDoc}
406 * @see org.melati.poem.PoemTypeFactory#typeOf
407 * (org.melati.poem.Database, org.melati.poem.PoemTypeFactory.Parameter)
408 */
409 @SuppressWarnings("unchecked")
410 public SQLPoemType<Timestamp> typeOf(Database database, Parameter info) {
411 return new TimestampPoemType(info.getNullable());
412 }
413
414 /**
415 * @see org.melati.poem.PoemTypeFactory#getName()
416 */
417 public String getName() {
418 return "TIMESTAMP";
419 }
420
421 /**
422 * {@inheritDoc}
423 * @see org.melati.poem.PoemTypeFactory#getDescription()
424 */
425 public String getDescription() {
426 return "...";
427 }
428 }, DISPLAYLEVEL = new PoemTypeFactory(n--) {
429 /**
430 * @see org.melati.poem.PoemTypeFactory#typeOf
431 * (org.melati.poem.Database, org.melati.poem.PoemTypeFactory.Parameter)
432 */
433 @SuppressWarnings("unchecked")
434 public SQLPoemType<?> typeOf(Database database, Parameter info) {
435 return new DisplayLevelPoemType();
436 }
437
438 /**
439 * {@inheritDoc}
440 * @see org.melati.poem.PoemTypeFactory#getName()
441 */
442 public String getName() {
443 return "DISPLAYLEVEL";
444 }
445
446 /**
447 * {@inheritDoc}
448 * @see org.melati.poem.PoemTypeFactory#getDescription()
449 */
450 public String getDescription() {
451 return "...";
452 }
453 }, SEARCHABILITY = new PoemTypeFactory(n--) {
454 /**
455 * {@inheritDoc}
456 * @see org.melati.poem.PoemTypeFactory#typeOf
457 * (org.melati.poem.Database, org.melati.poem.PoemTypeFactory.Parameter)
458 */
459 @SuppressWarnings("unchecked")
460 public SQLPoemType<?> typeOf(Database database, Parameter info) {
461 return new SearchabilityPoemType();
462 }
463
464 /**
465 * {@inheritDoc}
466 * @see org.melati.poem.PoemTypeFactory#getName()
467 */
468 public String getName() {
469 return "SEARCHABILITY";
470 }
471
472 /**
473 * @see org.melati.poem.PoemTypeFactory#getDescription()
474 */
475 public String getDescription() {
476 return "...";
477 }
478 }, BINARY = new PoemTypeFactory(n--) {
479 /**
480 * @see org.melati.poem.PoemTypeFactory#typeOf
481 * (org.melati.poem.Database, org.melati.poem.PoemTypeFactory.Parameter)
482 */
483 @SuppressWarnings("unchecked")
484 public SQLPoemType<?> typeOf(Database database, Parameter info) {
485 return new BinaryPoemType(info.getNullable(), info.getSize());
486 }
487
488 /**
489 * {@inheritDoc}
490 * @see org.melati.poem.PoemTypeFactory#getName()
491 */
492 public String getName() {
493 return "BINARY";
494 }
495
496 /**
497 * {@inheritDoc}
498 * @see org.melati.poem.PoemTypeFactory#getDescription()
499 */
500 public String getDescription() {
501 return "...";
502 }
503 }, LONG = new PoemTypeFactory(n--) {
504 /**
505 * {@inheritDoc}
506 * @see org.melati.poem.PoemTypeFactory#typeOf
507 * (org.melati.poem.Database, org.melati.poem.PoemTypeFactory.Parameter)
508 */
509 @SuppressWarnings("unchecked")
510 public SQLPoemType<?> typeOf(Database database, Parameter info) {
511 return new LongPoemType(info.getNullable());
512 }
513
514 /**
515 * {@inheritDoc}
516 * @see org.melati.poem.PoemTypeFactory#getName()
517 */
518 public String getName() {
519 return "LONG";
520 }
521
522 /**
523 * {@inheritDoc}
524 * @see org.melati.poem.PoemTypeFactory#getDescription()
525 */
526 public String getDescription() {
527 return "...";
528 }
529 }, INTEGRITYFIX = new PoemTypeFactory(n--) {
530 /**
531 * {@inheritDoc}
532 * @see org.melati.poem.PoemTypeFactory#typeOf
533 * (org.melati.poem.Database, org.melati.poem.PoemTypeFactory.Parameter)
534 */
535 @SuppressWarnings("unchecked")
536 public SQLPoemType<?> typeOf(Database database, Parameter info) {
537 return new IntegrityFixPoemType(info.getNullable());
538 }
539
540 /**
541 * @see org.melati.poem.PoemTypeFactory#getName()
542 */
543 public String getName() {
544 return "INTEGRITYFIX";
545 }
546
547 /**
548 * {@inheritDoc}
549 * @see org.melati.poem.PoemTypeFactory#getDescription()
550 */
551 public String getDescription() {
552 return "...";
553 }
554 }, BIGDECIMAL = new PoemTypeFactory(n--) {
555 /**
556 * {@inheritDoc}
557 * @see org.melati.poem.PoemTypeFactory#typeOf
558 * (org.melati.poem.Database, org.melati.poem.PoemTypeFactory.Parameter)
559 */
560 @SuppressWarnings("unchecked")
561 public SQLPoemType<?> typeOf(Database database, Parameter info) {
562 return new BigDecimalPoemType(info.getNullable());
563 }
564
565 /**
566 * {@inheritDoc}
567 * @see org.melati.poem.PoemTypeFactory#getName()
568 */
569 public String getName() {
570 return "BIGDECIMAL";
571 }
572
573 /**
574 * {@inheritDoc}
575 * @see org.melati.poem.PoemTypeFactory#getDescription()
576 */
577 public String getDescription() {
578 return "...";
579 }
580 }, TIME = new PoemTypeFactory(n--) {
581 /**
582 * {@inheritDoc}
583 * @see org.melati.poem.PoemTypeFactory#typeOf
584 * (org.melati.poem.Database, org.melati.poem.PoemTypeFactory.Parameter)
585 */
586 @SuppressWarnings("unchecked")
587 public SQLPoemType<?> typeOf(Database database, Parameter info) {
588 return new TimePoemType(info.getNullable());
589 }
590
591 /**
592 * {@inheritDoc}
593 * @see org.melati.poem.PoemTypeFactory#getName()
594 */
595 public String getName() {
596 return "TIME";
597 }
598
599 /**
600 * {@inheritDoc}
601 * @see org.melati.poem.PoemTypeFactory#getDescription()
602 */
603 public String getDescription() {
604 return "...";
605 }
606 },
607
608 };
609
610 /**
611 * Returns an instance given a database and the integer code for
612 * the instance.
613 * @param database to get tables from
614 * @param code TypeCode
615 * @return a new PoemTypeFactory
616 */
617 public static PoemTypeFactory forCode(Database database, int code) {
618 if (code < 0)
619 return atomTypeFactories[(-code) - 1];
620 else {
621 final Table<?> table = database.tableWithTableInfoID(code);
622 return new PoemTypeFactory(code) {
623 /**
624 * {@inheritDoc}
625 * @see org.melati.poem.PoemTypeFactory#typeOf
626 * (org.melati.poem.Database, org.melati.poem.PoemTypeFactory.Parameter)
627 */
628 @SuppressWarnings("unchecked")
629 public SQLPoemType<?> typeOf(Database db, Parameter info) {
630 return new ReferencePoemType(table, info.getNullable());
631 }
632
633 /**
634 * {@inheritDoc}
635 * @see org.melati.poem.PoemTypeFactory#getName()
636 */
637 public String getName() {
638 return table.getName();
639 }
640
641 /**
642 * {@inheritDoc}
643 * @see org.melati.poem.PoemTypeFactory#getDisplayName()
644 */
645 public String getDisplayName() {
646 return table.getDisplayName();
647 }
648
649 /**
650 * {@inheritDoc}
651 * @see org.melati.poem.PoemTypeFactory#getDescription()
652 */
653 public String getDescription() {
654 return table.getDescription();
655 }
656 };
657 }
658 }
659 }