View Javadoc

1   /*
2    * $Header: /cvsroot/jdbforms/dbforms/src/org/dbforms/config/Field.java,v 1.38 2006/03/16 14:23:02 hkollmann Exp $
3    * $Revision: 1.38 $
4    * $Date: 2006/03/16 14:23:02 $
5    *
6    * DbForms - a Rapid Application Development Framework
7    * Copyright (C) 2001 Joachim Peer <joepeer@excite.com>
8    *
9    * This library is free software; you can redistribute it and/or
10   * modify it under the terms of the GNU Lesser General Public
11   * License as published by the Free Software Foundation; either
12   * version 2.1 of the License, or (at your option) any later version.
13   *
14   * This library is distributed in the hope that it will be useful,
15   * but WITHOUT ANY WARRANTY; without even the implied warranty of
16   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17   * Lesser General Public License for more details.
18   *
19   * You should have received a copy of the GNU Lesser General Public
20   * License along with this library; if not, write to the Free Software
21   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
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 		//  FIXME - someone check is this types are good for all databases
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 //		Vector v = StringUtil.splitString(clazz.getName().toLowerCase(), ".");
497 //		fieldType = (String) v.lastElement();
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 }