1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 package org.dbforms.config;
25
26 import org.apache.commons.logging.Log;
27 import org.apache.commons.logging.LogFactory;
28
29 import org.dbforms.interfaces.IEscaper;
30 import org.dbforms.util.MessageResourcesInternal;
31 import org.dbforms.util.ReflectionUtil;
32 import org.dbforms.util.Util;
33
34 import java.text.DateFormat;
35 import java.text.Format;
36
37 import java.util.Locale;
38
39 import java.io.Serializable;
40
41 /***
42 * This class represents a field tag in dbforms-config.xml.
43 *
44 * @author foxat
45 */
46 public class Field implements Serializable {
47 private static Log logCat = LogFactory.getLog(Field.class.getName());
48
49 private IEscaper escaper = null;
50
51 /***
52 * used only for DISKBLOB: holds the directory uploaded files should be
53 * stored to
54 */
55 private String directory = null;
56
57 private String escaperClass = null;
58
59 private String expression = null;
60
61 private String fieldType = null;
62
63 /*** stores if the field is a KEY */
64 private String key = "false";
65
66 /*** the field-name, as provided in xml-config file */
67 private String name;
68
69 private Table table = null;
70
71 /***
72 * used only for DISKBLOB: if "true" -> then files will be renamed to ensure
73 * that every file is unique and no file overwrites another. default is
74 * "false" (keep original names)
75 */
76 private boolean encoded = false;
77
78 /*** stores if the field is AUTOINCremental */
79 private boolean isAutoInc = false;
80
81 /*** stores if the field is sortable */
82 private boolean isSortable = false;
83
84 /*** the id of this field (for dbforms-internal use) */
85 private int id;
86
87 /*** the field-size */
88 private int size = -1;
89
90 /*** integer representation of the "fieldType"-value */
91 private int type;
92
93 /***
94 * Sets the autoInc attribute of the Field object
95 *
96 * @param autoInc
97 * The new autoInc value
98 */
99 public void setAutoInc(String autoInc) {
100 this.isAutoInc = Util.getTrue(autoInc);
101 }
102
103 /***
104 * Sets the directory attribute of the Field object
105 *
106 * @param directory
107 * The new directory value
108 */
109 public void setDirectory(String directory) {
110 this.directory = directory;
111 }
112
113 /***
114 * Gets the directory attribute of the Field object
115 *
116 * @return The directory value
117 */
118 public String getDirectory() {
119 return directory;
120 }
121
122 /***
123 * Sets the encoding attribute of the Field object
124 *
125 * @param encoding
126 * The new encoding value
127 */
128 public void setEncoding(String encoding) {
129 this.encoded = Util.getTrue(encoding);
130 }
131
132 /***
133 * DOCUMENT ME!
134 *
135 * @return DOCUMENT ME!
136 */
137 public IEscaper getEscaper() {
138 if (escaper == null) {
139 String s = getEscaperClass();
140
141 if (!Util.isNull(s)) {
142 try {
143 escaper = (IEscaper) ReflectionUtil.newInstance(s);
144 } catch (Exception e) {
145 logCat
146 .error("cannot create the new escaper [" + s + "]",
147 e);
148 }
149 }
150
151 if (escaper == null) {
152 if (getTable() == null) {
153 try {
154 escaper = DbFormsConfigRegistry.instance().lookup()
155 .getEscaper();
156 } catch (Exception e) {
157 logCat
158 .error("cannot create the new default escaper",
159 e);
160 }
161 } else {
162 escaper = getTable().getEscaper();
163 }
164 }
165 }
166
167 return escaper;
168 }
169
170 /***
171 * DOCUMENT ME!
172 *
173 * @param string
174 */
175 public void setEscaperClass(String string) {
176 escaperClass = string;
177 }
178
179 /***
180 * Sets the expression attribute of the Field object
181 *
182 * @param expression
183 * The new expression value
184 */
185 public void setExpression(String expression) {
186 this.expression = expression;
187 }
188
189 /***
190 * Gets the expression attribute of the Field object
191 *
192 * @return The expression value
193 */
194 public String getExpression() {
195 return expression;
196 }
197
198 /***
199 * DOCUMENT ME!
200 *
201 * @param core
202 * DOCUMENT ME!
203 *
204 * @return DOCUMENT ME!
205 */
206 public String getFieldName(String core) {
207 StringBuffer sb = new StringBuffer(core);
208 sb.append(getTable().getId());
209 sb.append("_");
210 sb.append(getId());
211
212 return sb.toString();
213 }
214
215 /***
216 * Maps the field type description to internal value. <br>
217 * We need this information in oder to call the appropriate
218 * PreparedStatement.setXxx(..) methods <br>
219 * this method is called by the digester framework to set the fieldType!
220 *
221 * @param aFieldType
222 * the type string value (example: "int", "char", "numeric", etc)
223 */
224 public void setFieldType(String aFieldType) {
225 this.fieldType = aFieldType;
226 String tFieldType = aFieldType.toLowerCase();
227
228 if (tFieldType.startsWith("char")
229 || tFieldType.startsWith("text")) {
230 type = FieldTypes.CHAR;
231 } else if (tFieldType.startsWith("varchar")
232 || tFieldType.startsWith("nvarchar")
233 || tFieldType.startsWith("longchar")) {
234 type = FieldTypes.VARCHAR;
235 } else if (tFieldType.startsWith("long varchar")) {
236 type = FieldTypes.LONGVARCHAR;
237 } else if (tFieldType.startsWith("int")
238 || tFieldType.startsWith("smallint")
239 || tFieldType.startsWith("long")
240 || tFieldType.startsWith("tinyint")) {
241 type = FieldTypes.INTEGER;
242 } else if (tFieldType.startsWith("numeric")
243 || tFieldType.startsWith("number")
244 || tFieldType.startsWith("decimal")) {
245 type = FieldTypes.NUMERIC;
246 } else if (tFieldType.startsWith("date")) {
247 type = FieldTypes.DATE;
248 } else if (tFieldType.startsWith("timestamp")) {
249 type = FieldTypes.TIMESTAMP;
250 } else if (tFieldType.startsWith("time")) {
251 type = FieldTypes.TIME;
252 } else if (tFieldType.startsWith("double")
253 || tFieldType.startsWith("float")) {
254 type = FieldTypes.DOUBLE;
255 } else if (tFieldType.startsWith("real")) {
256 type = FieldTypes.FLOAT;
257 } else if (tFieldType.startsWith("blob")
258 || tFieldType.startsWith("image")) {
259 type = FieldTypes.BLOB;
260 } else if (tFieldType.startsWith("diskblob")) {
261 type = FieldTypes.DISKBLOB;
262 } else if (tFieldType.startsWith("bool")) {
263 type = FieldTypes.BOOLEAN;
264 }
265 }
266
267 /***
268 * DOCUMENT ME!
269 *
270 * @return
271 */
272 public String getFieldType() {
273 return fieldType;
274 }
275
276 /***
277 * DOCUMENT ME!
278 *
279 * @param pattern
280 * DOCUMENT ME!
281 * @param locale
282 * DOCUMENT ME!
283 *
284 * @return DOCUMENT ME!
285 */
286 public Format getFormat(String pattern, Locale locale) {
287 switch (getType()) {
288 case FieldTypes.INTEGER:
289 case FieldTypes.NUMERIC:
290 case FieldTypes.DOUBLE:
291 case FieldTypes.FLOAT:
292 case FieldTypes.DATE:
293 case FieldTypes.TIME:
294 case FieldTypes.TIMESTAMP:
295 break;
296
297 default:
298 return null;
299 }
300
301 Format res = null;
302 int dateStyle = Constants.DATE_STYLE_DEFAULT;
303 int timeStyle = Constants.TIME_STYLE_DEFAULT;
304
305 if (Util.isNull(pattern)) {
306 pattern = MessageResourcesInternal.getMessage("dbforms.pattern."
307 + getFieldType(), locale);
308 }
309
310 if (!Util.isNull(pattern)) {
311 if ("short".startsWith(pattern.toLowerCase())) {
312 dateStyle = DateFormat.SHORT;
313 pattern = MessageResourcesInternal.getMessage(
314 "dbforms.pattern." + getFieldType() + "." + pattern,
315 locale);
316 } else if ("medium".startsWith(pattern.toLowerCase())) {
317 dateStyle = DateFormat.MEDIUM;
318 pattern = MessageResourcesInternal.getMessage(
319 "dbforms.pattern." + getFieldType() + "." + pattern,
320 locale);
321 } else if ("long".startsWith(pattern.toLowerCase())) {
322 dateStyle = DateFormat.LONG;
323 pattern = MessageResourcesInternal.getMessage(
324 "dbforms.pattern." + getFieldType() + "." + pattern,
325 locale);
326 } else if ("full".startsWith(pattern.toLowerCase())) {
327 dateStyle = DateFormat.FULL;
328 pattern = MessageResourcesInternal.getMessage(
329 "dbforms.pattern." + getFieldType() + "." + pattern,
330 locale);
331 }
332 }
333
334 switch (getType()) {
335 case FieldTypes.INTEGER:
336
337 try {
338 res = java.text.NumberFormat.getIntegerInstance(locale);
339 } catch (NoSuchMethodError nsme) {
340 res = java.text.NumberFormat.getNumberInstance(locale);
341 }
342
343 ((java.text.DecimalFormat) res).setParseIntegerOnly(true);
344
345 if (!Util.isNull(pattern)) {
346 try {
347 ((java.text.DecimalFormat) res).applyPattern(pattern);
348 } catch (Exception e) {
349 logCat.error(pattern, e);
350 }
351 }
352
353 break;
354
355 case FieldTypes.NUMERIC:
356 case FieldTypes.DOUBLE:
357 case FieldTypes.FLOAT:
358 res = java.text.NumberFormat.getNumberInstance(locale);
359 if (!Util.isNull(pattern)) {
360 try {
361 ((java.text.DecimalFormat) res).applyPattern(pattern);
362 } catch (Exception e) {
363 logCat.error(pattern, e);
364 }
365 }
366 break;
367
368 case FieldTypes.DATE:
369 res = java.text.DateFormat.getDateInstance(dateStyle, locale);
370 if (!Util.isNull(pattern)) {
371 try {
372 ((java.text.SimpleDateFormat) res).applyPattern(pattern);
373 } catch (Exception e) {
374 logCat.error(pattern, e);
375 }
376 }
377
378 break;
379
380 case FieldTypes.TIME:
381 res = java.text.DateFormat.getTimeInstance(timeStyle, locale);
382
383 if (!Util.isNull(pattern)) {
384 try {
385 ((java.text.SimpleDateFormat) res).applyPattern(pattern);
386 } catch (Exception e) {
387 logCat.error(pattern, e);
388 }
389 }
390
391 break;
392
393 case FieldTypes.TIMESTAMP:
394 res = java.text.DateFormat.getDateTimeInstance(dateStyle,
395 timeStyle, locale);
396
397 if (!Util.isNull(pattern)) {
398 try {
399 ((java.text.SimpleDateFormat) res).applyPattern(pattern);
400 } catch (Exception e) {
401 logCat.error(pattern, e);
402 }
403 }
404
405 break;
406
407 default:
408 break;
409 }
410
411 return res;
412 }
413
414 /***
415 * sets the id of this field-object (this method is called by Table on
416 * init).
417 *
418 * @param id
419 * The new id value
420 */
421 public void setId(int id) {
422 this.id = id;
423 }
424
425 /***
426 * Gets the id attribute of the Field object
427 *
428 * @return The id value
429 */
430 public int getId() {
431 return id;
432 }
433
434 /***
435 * Sets the isKey attribute of the Field object
436 *
437 * @param value
438 * The new isKey value
439 */
440 public void setIsKey(String value) {
441 this.key = value;
442 }
443
444 /***
445 * Sets the name attribute of the Field object
446 *
447 * @param name
448 * The new name value
449 */
450 public void setName(String name) {
451 this.name = name;
452 }
453
454 /***
455 * Gets the name attribute of the Field object
456 *
457 * @return The name value
458 */
459 public String getName() {
460 return name;
461 }
462
463 /***
464 * Sets the sortable attribute of the Field object
465 *
466 * @param sortable
467 * The new sortable value
468 */
469 public void setSortable(String sortable) {
470 this.isSortable = Util.getTrue(sortable);
471 }
472
473 /***
474 * Gets the type attribute of the Field object as numeric value. <br>
475 * It's read only because the field type is set by the digester during
476 * initialize!
477 *
478 * @return The type value
479 */
480 public int getType() {
481 return type;
482 }
483
484 /***
485 * DOCUMENT ME!
486 *
487 * @param obj
488 * DOCUMENT ME!
489 */
490 public void setTypeByObject(Object obj) {
491 if (obj == null) {
492 return;
493 }
494
495 Class clazz = obj.getClass();
496
497
498
499 fieldType = clazz.getName();
500 if (clazz.isAssignableFrom(java.lang.Integer.class)) {
501 type = FieldTypes.INTEGER;
502 } else if (clazz.isAssignableFrom(java.lang.Long.class)) {
503 type = FieldTypes.INTEGER;
504 } else if (clazz.isAssignableFrom(java.lang.String.class)) {
505 type = FieldTypes.CHAR;
506 } else if (clazz.isAssignableFrom(java.math.BigDecimal.class)) {
507 type = FieldTypes.NUMERIC;
508 } else if (clazz.isAssignableFrom(java.sql.Date.class)) {
509 type = FieldTypes.DATE;
510 } else if (clazz.isAssignableFrom(java.sql.Time.class)) {
511 type = FieldTypes.TIME;
512 } else if (clazz.isAssignableFrom(java.sql.Timestamp.class)) {
513 type = FieldTypes.TIMESTAMP;
514 } else if (clazz.isAssignableFrom(java.lang.Double.class)) {
515 type = FieldTypes.DOUBLE;
516 } else if (clazz.isAssignableFrom(java.lang.Float.class)) {
517 type = FieldTypes.FLOAT;
518 } else if (clazz.isAssignableFrom(java.lang.Boolean.class)) {
519 type = FieldTypes.BOOLEAN;
520 }
521 }
522
523 /***
524 * Dump the fieldValue objects contained into the input FieldValue array.
525 *
526 * @param fv
527 * the FieldValue array to dump
528 *
529 * @return the String object containing the dumped data, or null if the
530 * input array is null
531 */
532 public static final String dumpFieldValueArray(FieldValue[] fv) {
533 String s = null;
534
535 if (fv != null) {
536 StringBuffer sb = new StringBuffer();
537
538 for (int i = 0; i < fv.length; i++) {
539 FieldValue f = fv[i];
540 sb.append(" fv[").append(i).append("] = {").append(
541 f.toString()).append("}\n");
542 }
543
544 s = sb.toString();
545 }
546
547 return s;
548 }
549
550 /***
551 * DOCUMENT ME!
552 *
553 * @return
554 */
555 public String getEscaperClass() {
556 return escaperClass;
557 }
558
559 /***
560 * DOCUMENT ME!
561 *
562 * @return DOCUMENT ME!
563 */
564 public String getSearchAlgoName() {
565 return getFieldName(Constants.FIELDNAME_SEARCHALGO);
566 }
567
568 /***
569 * DOCUMENT ME!
570 *
571 * @return DOCUMENT ME!
572 */
573 public String getSearchFieldName() {
574 return getFieldName(Constants.FIELDNAME_SEARCH);
575 }
576
577 /***
578 * DOCUMENT ME!
579 *
580 * @return DOCUMENT ME!
581 */
582 public String getSearchModeName() {
583 return getFieldName(Constants.FIELDNAME_SEARCHMODE);
584 }
585
586 /***
587 * Sets the size attribute of the Field object
588 *
589 * @param size
590 * DOCUMENT ME!
591 */
592 public void setSize(int size) {
593 this.size = size;
594 }
595
596 /***
597 * Gets the size attribute of the Field object
598 *
599 * @return DOCUMENT ME!
600 */
601 public int getSize() {
602 return size;
603 }
604
605 /***
606 * DOCUMENT ME!
607 *
608 * @return DOCUMENT ME!
609 */
610 public String getSortFieldName() {
611 return getFieldName(Constants.FIELDNAME_SORT);
612 }
613
614 /***
615 * DOCUMENT ME!
616 *
617 * @param table
618 */
619 public void setTable(Table table) {
620 this.table = table;
621 }
622
623 /***
624 * DOCUMENT ME!
625 *
626 * @return
627 */
628 public Table getTable() {
629 return table;
630 }
631
632 /***
633 * Gets the isAutoInc attribute of the Field object
634 *
635 * @return The isAutoInc value
636 */
637 public boolean hasAutoIncSet() {
638 return isAutoInc;
639 }
640
641 /***
642 * Gets the encoding attribute of the Field object
643 *
644 * @return The encoding value
645 */
646 public boolean hasEncodedSet() {
647 return encoded;
648 }
649
650 /***
651 * Gets the key attribute of the Field object
652 *
653 * @return The key value
654 */
655 public boolean hasIsKeySet() {
656 return Util.getTrue(key);
657 }
658
659 /***
660 * Gets the fieldSortable attribute of the Field object
661 *
662 * @return The fieldSortable value
663 */
664 public boolean hasSortableSet() {
665 return isSortable;
666 }
667
668 /***
669 * Get the String representation of this Field object.
670 *
671 * @return the String representation of this Field object
672 */
673 public String toString() {
674 StringBuffer buf = new StringBuffer();
675
676 buf.append("name=");
677 buf.append(name);
678 buf.append(" type=");
679 buf.append(type);
680 buf.append(" key=");
681 buf.append(key);
682 buf.append(" isAutoinc=");
683 buf.append(isAutoInc);
684 buf.append(" issortable=");
685 buf.append(isSortable);
686 buf.append(" directory=");
687 buf.append(directory);
688 buf.append(" expression=");
689 buf.append(expression);
690
691 return buf.toString();
692 }
693 }