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;
47
48 import java.sql.PreparedStatement;
49 import java.sql.ResultSet;
50 import java.sql.SQLException;
51 import java.util.Enumeration;
52
53 import org.melati.poem.dbms.Dbms;
54 import org.melati.poem.util.ConsEnumeration;
55
56
57
58
59 public abstract class BasePoemType implements SQLPoemType, Cloneable {
60 private int sqlTypeCode;
61 protected boolean nullable;
62
63 private Comparable low = null, limit = null;
64
65 BasePoemType(int sqlTypeCode, boolean nullable) {
66 this.sqlTypeCode = sqlTypeCode;
67 this.nullable = nullable;
68 }
69
70
71
72
73
74
75 public void setRawRange(Comparable low, Comparable limit) {
76 this.low = low;
77 this.limit = limit;
78 }
79
80 protected Comparable getLowRaw() {
81 return low;
82 }
83
84 protected Comparable getLimitRaw() {
85 return limit;
86 }
87
88 protected abstract void _assertValidRaw(Object raw)
89 throws ValidationPoemException;
90
91 private void assertRawInRange(Object raw) {
92
93
94
95 Comparable asComparable;
96 try {
97 asComparable = (Comparable)raw;
98 }
99 catch (ClassCastException e) {
100 throw new NotComparablePoemException(raw, this);
101 }
102
103 if ((low != null && low.compareTo(asComparable) > 0) ||
104 (limit != null && limit.compareTo(asComparable) <= 0))
105 throw new ValidationPoemException(
106 this, raw, new OutsideRangePoemException(low, limit, raw));
107 }
108
109
110
111
112
113 public final void assertValidRaw(Object raw)
114 throws ValidationPoemException {
115 if (raw == null) {
116 if (!nullable)
117 throw new NullTypeMismatchPoemException(this);
118 }
119 else {
120 if (low != null || limit != null)
121 assertRawInRange(raw);
122 _assertValidRaw(raw);
123 }
124 }
125
126
127
128
129
130 private void doubleCheckValidRaw(Object raw) {
131 try {
132 assertValidRaw(raw);
133 }
134 catch (ValidationPoemException e) {
135 throw new UnexpectedValidationPoemException(e);
136 }
137 }
138
139 protected abstract Object _getRaw(ResultSet rs, int col)
140 throws SQLException;
141
142
143
144
145
146 public final Object getRaw(ResultSet rs, int col)
147 throws ValidationPoemException {
148 Object o;
149 try {
150 o = _getRaw(rs, col);
151 }
152 catch (SQLException e) {
153 throw new SQLSeriousPoemException(e);
154 }
155
156 assertValidRaw(o);
157 return o;
158 }
159
160 protected abstract void _setRaw(PreparedStatement ps, int col,
161 Object raw)
162 throws SQLException;
163
164
165
166
167
168 public final void setRaw(PreparedStatement ps, int col, Object raw) {
169 doubleCheckValidRaw(raw);
170 try {
171 if (raw == null)
172 ps.setNull(col, sqlTypeCode());
173 else
174 _setRaw(ps, col, raw);
175 }
176 catch (SQLException e) {
177 throw new SQLSeriousPoemException(e);
178 }
179 }
180
181 protected Enumeration _possibleRaws() {
182 return null;
183 }
184
185
186
187
188
189 public Enumeration possibleRaws() {
190 Enumeration them = _possibleRaws();
191 return them == null ? null :
192 getNullable() ? new ConsEnumeration(null, them) :
193 them;
194 }
195
196 protected abstract String _stringOfRaw(Object raw);
197
198
199
200
201
202
203 public final String stringOfRaw(Object raw)
204 throws ValidationPoemException {
205 return raw == null ? null : _stringOfRaw(raw);
206 }
207
208
209
210
211
212 protected abstract Object _rawOfString(String string)
213 throws ParsingPoemException;
214
215
216
217
218
219
220
221
222
223
224
225
226
227 public final Object rawOfString(String string)
228 throws ParsingPoemException, ValidationPoemException {
229 Object raw = string == null ? null : _rawOfString(string);
230 assertValidRaw(raw);
231 return raw;
232 }
233
234 protected abstract void _assertValidCooked(Object cooked)
235 throws ValidationPoemException;
236
237
238
239
240
241 public final void assertValidCooked(Object cooked)
242 throws ValidationPoemException {
243 if (cooked == null) {
244 if (!nullable)
245 throw new NullTypeMismatchPoemException(this);
246 }
247 else {
248 _assertValidCooked(cooked);
249 if (low != null || limit != null)
250 assertRawInRange(_rawOfCooked(cooked));
251 }
252 }
253
254
255
256
257
258
259 final void doubleCheckValidCooked(Object cooked) {
260 try {
261 assertValidCooked(cooked);
262 }
263 catch (ValidationPoemException e) {
264 throw new UnexpectedValidationPoemException(e);
265 }
266 }
267
268
269
270
271
272
273
274
275
276
277
278
279 protected abstract Object _cookedOfRaw(Object raw) throws PoemException;
280
281
282
283
284
285
286
287
288
289
290
291 public final Object cookedOfRaw(Object raw) throws PoemException {
292 doubleCheckValidRaw(raw);
293 return raw == null ? null : _cookedOfRaw(raw);
294 }
295
296 protected abstract Object _rawOfCooked(Object raw) throws PoemException;
297
298
299
300
301
302 public final Object rawOfCooked(Object cooked) {
303 doubleCheckValidCooked(cooked);
304 return cooked == null ? null : _rawOfCooked(cooked);
305 }
306
307 protected abstract String _stringOfCooked(Object cooked,
308 PoemLocale locale, int style)
309 throws PoemException;
310
311
312
313
314
315
316 public final String stringOfCooked(Object cooked,
317 PoemLocale locale, int style)
318 throws PoemException {
319 doubleCheckValidCooked(cooked);
320 return cooked == null ? "" : _stringOfCooked(cooked, locale, style);
321 }
322
323
324
325
326
327 public final boolean getNullable() {
328 return nullable;
329 }
330
331
332
333
334
335 public final int sqlTypeCode() {
336 return sqlTypeCode;
337 }
338
339 protected abstract String _sqlDefinition(Dbms dbms);
340
341
342
343
344
345 public String sqlDefinition(Dbms dbms) {
346 return sqlTypeDefinition(dbms) + (nullable ? "" : " NOT NULL");
347 }
348
349
350
351
352 public String sqlTypeDefinition(Dbms dbms) {
353 return _sqlDefinition(dbms);
354 }
355 protected abstract boolean _canRepresent(SQLPoemType other);
356
357
358
359
360
361 public PoemType canRepresent(PoemType other) {
362
363
364 if (!(other instanceof SQLPoemType))
365
366 return null;
367 else {
368 SQLPoemType q = (SQLPoemType)other;
369 return
370 !(!nullable && q.getNullable()) &&
371 _canRepresent(q) ?
372 q : null;
373 }
374 }
375
376
377
378
379
380 public final PoemType withNullable(boolean nullableP) {
381 if (this.nullable == nullableP)
382 return this;
383 else {
384 BasePoemType it = (BasePoemType)clone();
385 it.nullable = nullableP;
386 return it;
387 }
388 }
389
390 protected abstract void _saveColumnInfo(ColumnInfo info)
391 throws AccessPoemException;
392
393
394
395
396
397 public void saveColumnInfo(ColumnInfo info) throws AccessPoemException {
398 info.setNullable(nullable);
399 info.setSize(0);
400 info.setRangelow_string(
401 getLowRaw() == null ? null : stringOfRaw(getLowRaw()));
402
403 info.setRangelimit_string(
404 getLimitRaw() == null ? null : stringOfRaw(getLimitRaw()));
405 _saveColumnInfo(info);
406 }
407
408 protected abstract String _quotedRaw(Object raw);
409
410
411
412
413
414 public String quotedRaw(Object raw) throws ValidationPoemException {
415 assertValidRaw(raw);
416 return raw == null ? "NULL" : _quotedRaw(raw);
417 }
418
419 protected abstract String _toString();
420
421
422
423
424
425
426
427
428
429
430
431 public String toString() {
432 return (nullable ? "nullable " : "") + _toString() +
433 " (" + this.getClass().getName() + ")";
434 }
435
436
437
438
439
440 protected Object clone() {
441 try {
442 return super.clone();
443 }
444 catch (CloneNotSupportedException e) {
445 throw new PoemBugPoemException();
446 }
447 }
448 }