View Javadoc

1   package org.paneris.jal.model;
2   
3   import java.sql.Connection;
4   import java.sql.ResultSet;
5   import java.sql.Statement;
6   import java.text.NumberFormat;
7   import java.text.ParsePosition;
8   import java.text.SimpleDateFormat;
9   import java.util.Locale;
10  import java.util.StringTokenizer;
11  
12  import org.paneris.util.ValidationProblem;
13  
14  /**
15   <p>This represents the results data for an individual Field in the database.</p>
16  
17   <help>
18     <question>How come setValue(Object O) doesn't supercede setValue(string v)?</question>
19     <answer>Cos object is an object so the signature is different to compiler and 
20             JVM looks for methods with exactly this object type, then one with an object.
21             ????????????????
22     </answer>
23     <confirmation>Exactly. To get a String passed into the setValue(Object) form you
24                   would need to cast it explicitly, e.g.:
25                   String s="hello";
26                   setValue((Object)s);
27   </help>
28  
29  
30  */
31  public class DDField {
32  
33    private Object value;
34    private ValidationProblem problem;
35    private FieldMetaData metaData;
36    private String database;
37    private DBConnectionManager connMgr = DBConnectionManager.getInstance();
38    private static SimpleDateFormat dateFormatter1 =
39      new SimpleDateFormat("dd/MM/yyyy");
40    // allow other forms of date - this one yyyyMMdd
41    private static SimpleDateFormat dateFormatter2 =
42      new SimpleDateFormat("yyyyMMdd");
43    private static SimpleDateFormat datetimeFormatter =
44      new SimpleDateFormat("dd/MM/yyyy HH:mm");
45    private DataCache dataCache = DataCache.getInstance();
46  
47    /**
48     * Construct a results field given a database, and a field number.
49     */
50    public DDField(String db, Integer fieldNumber) throws Exception {
51      database = db;
52      metaData = dataCache.getFieldMetaData(db, fieldNumber);
53    }
54  
55    /**
56     * Gos and gets the results set if this field has a lookup.  
57     * If not it will just return null
58     */
59    public DDRecord getLookup() throws Exception {
60      if (metaData.getRelationshipTable().equals("")) {
61        return null;
62      }
63      else {
64        if ((value == null) || (value.toString().equals("0"))) {
65          return new DDRecord(database, metaData.getRelationshipTable());
66        }
67        else {
68          String reltab = metaData.getRelationshipTable();
69          return dataCache.getDDRecord(database, reltab, (Integer)value);
70        }
71      }
72    }
73  
74    /**
75    formats this field to be displayed on a web page.    this method will return null if the value
76    is not set - bit controversial, but it allows the value to be used in the webmacro #if directive
77    **/
78    public String getJavascriptDisplayValue() throws Exception {
79      return HTMLUtil.escapeJavascript(getDisplayValue());
80    }
81  
82    public String getDisplayValue() throws Exception {
83      if (value == null) {
84        return "";
85      }
86      if (metaData.getType().equals("currency")) {
87        return new String(
88          NumberFormat.getCurrencyInstance(Locale.UK).format(value));
89      }
90      if (metaData.getType().equals("date")
91        || metaData.getType().equals("datedrop")) {
92        return new String(dateFormatter1.format((java.util.Date)value));
93      }
94      if (metaData.getType().equals("datetime")
95        || metaData.getType().equals("datetimedrop")
96        || metaData.getType().equals("timestamp")) {
97        return new String(datetimeFormatter.format((java.util.Date)value));
98      }
99      if (metaData.getType().equals("textarea")) {
100       String returnString = "";
101       StringTokenizer st =
102         new StringTokenizer(value.toString().trim(), "\n", false);
103       while (st.hasMoreTokens()) {
104         returnString += st.nextToken() + "&nbsp;<br>";
105       }
106       return returnString;
107     }
108     if (metaData.getType().equals("boolean")) {
109       if (((Boolean)value).booleanValue()) {
110         return "Yes";
111       }
112       else {
113         return "No";
114       }
115     }
116     if (metaData.getType().equals("password")) {
117       String returnString = "";
118       for (int i = 0; i < value.toString().trim().length(); i++) {
119         returnString += "*";
120       }
121       return returnString;
122     }
123     if (!metaData.getRelationshipTable().equals("")) {
124       if (value.toString().equals("0") || value.toString().equals("")) {
125         return "None";
126       }
127       else {
128         DDRecord rs = getLookup();
129         DDField field = (DDField)rs.get(metaData.getRelationshipField());
130         return field.getDisplayValue();
131       }
132     }
133     if (metaData.getType().equals("escapedtext")) {
134       return HTMLUtil.escapeHTML(value.toString().trim());
135     }
136     return (value.toString().trim());
137   }
138 
139   /**
140   formats this field to be output to a CSV format file
141   We delegate all this work to the (static) class CSVUtil
142   **/
143   public String getCSVValue() throws Exception {
144     return CSVUtil.getCSVValue(
145       this,
146       database,
147       dateFormatter1,
148       datetimeFormatter);
149   }
150 
151   /**
152   formats this field to be displayed on a html page as a hidden input of the correct type
153   We delegate all this work of creating HTML to (the static class) HTMLUtil
154   **/
155   public String getHiddenValue() throws Exception {
156     return HTMLUtil.getHiddenValue(
157       this,
158       database,
159       dateFormatter1,
160       datetimeFormatter,
161       null);
162   }
163   public String getHiddenValueWithPostfix(String postfix) throws Exception {
164     return HTMLUtil.getHiddenValue(
165       this,
166       database,
167       dateFormatter1,
168       datetimeFormatter,
169       postfix);
170   }
171 
172   /**
173   formats this field to be displayed on a html page as in input box of the correct type
174   **/
175   public String getInputValue() throws Exception {
176     return getInputValue(null);
177   }
178 
179   /**
180   formats this field to be displayed on a html page as in input box of the correct type
181   If it is a lookup field then set allValue if you would like an extra
182   option with value 0 (and display value allValue)
183   **/
184   public String getInputValue(String allValue) throws Exception {
185     return HTMLUtil.getInputValue(
186       this,
187       database,
188       dateFormatter1,
189       datetimeFormatter,
190       allValue,
191       null);
192   }
193 
194   public String getInputValueWithPostfix(String postfix) throws Exception {
195     return HTMLUtil.getInputValue(
196       this,
197       database,
198       dateFormatter1,
199       datetimeFormatter,
200       null,
201       postfix);
202   }
203 
204   /**
205   * build a drop down list for this field (with the current value selected)
206   **/
207   public String getLinkedSelect() throws Exception {
208     return getLinkedSelect(metaData.getFieldName(), true, true, "", "");
209   }
210 
211   /**
212   * build a drop down list for this field (with the current value selected), this
213   * would normally be used to build drop-downs for templates
214   **/
215   public String getLinkedSelect(String allName) throws Exception {
216     return getLinkedSelect(metaData.getFieldName(), false, true, "0", allName);
217   }
218 
219   public String getLinkedSelect(
220     String fieldname,
221     boolean mandatory,
222     boolean unique,
223     String allValue,
224     String allName)
225     throws Exception {
226     return HTMLUtil.getLinkedSelect(
227       this,
228       database,
229       fieldname,
230       mandatory,
231       unique,
232       allValue,
233       allName);
234   }
235 
236   /**
237   * build a drop down list for this field (with the current value selected)
238   **/
239   public String getDropDown() throws Exception {
240     return getDropDown(metaData.getFieldName(), true, "");
241   }
242 
243   /**
244   * build a drop down list for this field (with the current value selected), this
245   * would normally be used to build drop-downs for templates
246   **/
247   public String getDropDown(String allValue) throws Exception {
248     return getDropDown(metaData.getFieldName(), false, allValue);
249   }
250 
251   /**
252   * build a drop down list for this field (with the current value selected), this
253   * would normally be used to build drop-downs for templates
254   **/
255   public String getDropDown(String name, String allValue) throws Exception {
256     return getDropDown(name, false, allValue);
257   }
258 
259   /**
260   * Does the work of creating HTML select tags.
261   * We delegate all this work of creating HTML to (the static class) HTMLUtil
262   **/
263   public String getDropDown(
264     String fieldname,
265     boolean mandatory,
266     String allName)
267     throws Exception {
268     String allValue = "0";
269     return HTMLUtil.getDropDown(
270       this,
271       database,
272       fieldname,
273       mandatory,
274       allValue,
275       allName);
276   }
277 
278   /**
279   * Does the work of creating JavaScript functions for validation.
280   * We delegate all this work of creating HTML to (the static class) HTMLUtil
281   **/
282   public String getJSValidation(
283     String fieldname,
284     String displayname,
285     boolean mandatory)
286     throws Exception {
287     return HTMLUtil.getJSValidation(this, fieldname, displayname, mandatory);
288   }
289 
290   public String getJSValidation(String fieldname, String displayname)
291     throws Exception {
292     return getJSValidation(fieldname, displayname, metaData.getMandatory());
293   }
294 
295   public String getJSValidation(String displayname) throws Exception {
296     return getJSValidation(
297       metaData.getFieldName(),
298       displayname,
299       metaData.getMandatory());
300   }
301 
302   public String getJSValidation() throws Exception {
303     return getJSValidation(
304       metaData.getFieldName(),
305       metaData.getDisplayName(),
306       metaData.getMandatory());
307   }
308 
309   /**
310   * Utility for multiple record editing
311   */
312   public String getJSValidationWithPostfix(String postfix) throws Exception {
313     return getJSValidation(
314       metaData.getFieldName() + postfix,
315       metaData.getDisplayName() + " for record " + postfix,
316       metaData.getMandatory());
317   }
318 
319   /**
320   returns the value
321   **/
322   public Object getValue() {
323     return value;
324   }
325 
326   /**
327   returns the metaData
328   **/
329   public FieldMetaData getMetaData() {
330     return metaData;
331   }
332 
333   /**
334   return the string value
335   **/
336   public String getStringValue() {
337     return (getValue() != null) ? getValue().toString() : "";
338   }
339 
340   /**
341   Does some checks and returns any problems
342   **/
343   public ValidationProblem getProblem() {
344     if (problem != null)
345       return problem;
346     if (metaData.getMandatory() && value == null)
347       return new ValidationProblem(
348         ValidationProblem.EMPTY_MANDATORY_FIELD,
349         metaData.getDisplayName());
350     return null;
351   }
352 
353   /**
354   Sets the problem field
355   **/
356   public void setProblem(ValidationProblem prob) {
357     problem = prob;
358   }
359 
360   /**
361   sets the value from an object. It is intended that this function be used to
362   quickly insert objects into our DDField which have been extracted from a
363   database (via JDBC). Hence we do not expect any validation errors (famous last
364   words :-) and do not validate. I've left the code in, though, so we can change
365   our minds.
366   **/
367   public void setValue(Object v) {
368 
369     // Reset any previously set problem
370     problem = null;
371 
372     /*
373             try {
374                 if (v == null && metaData.getMandatory()) {
375                     problem = new ValidationProblem(ValidationProblem.EMPTY_MANDATORY_FIELD, metaData.getDisplayName(), v);
376                     return;
377                 }
378                 if (metaData.getType().equals("integer") || metaData.getType().equals("lookup") || metaData.getType().equals("id")) {
379                     value = (Integer)v;
380                 }
381     // autorandom should be stored in the database as a string cos otherwise we have problems with precision (certainly with access)
382                 if (metaData.getType().equals("text") || metaData.getType().equals("textarea") ||
383                          metaData.getType().equals("password") || metaData.getType().equals("autorandom") ||
384                          metaData.getType().equals("preformattedtextarea") ||
385                          metaData.getType().equals("uploadurl")
386                     ) {
387                     value = (String)v;
388                 }
389                 if (metaData.getType().equals("number")) {
390                     value = (Double)v;
391                 }
392                 if (metaData.getType().equals("long")) {
393                     value = (Long)v;
394                 }
395                 if (metaData.getType().equals("date")) {
396                     if (v instanceof java.sql.Date) {
397                         value = v;
398                     } else if (v instanceof java.util.Date) {
399                         value = new java.sql.Date(((java.util.Date)v).getTime());
400                     } else {
401                         problem = new ValidationProblem(ValidationProblem.INCORRECT_VALUE_TYPE, metaData.getDisplayName(), v);
402                     }
403                 }
404                 if (metaData.getType().equals("datetime")) {
405                     if (v instanceof java.sql.Timestamp) {
406                         value = v;
407                     } else if (v instanceof java.util.Date) {
408                         value = new java.sql.Timestamp(((java.util.Date)v).getTime());
409                     } else {
410                         problem = new ValidationProblem(ValidationProblem.INCORRECT_VALUE_TYPE, metaData.getDisplayName(), v);
411                     }
412                 }
413                 if (metaData.getType().equals("boolean")) {
414                     value = (Boolean)v;
415                 }
416             } catch (Exception e) {
417                 problem = new ValidationProblem(ValidationProblem.INCORRECT_VALUE_TYPE, metaData.getDisplayName(), v);
418             }
419     */
420     value = v;
421   }
422 
423   /**
424   sets the value
425   **/
426   public void setValueFromLookup(String v) throws Exception {
427     if (!metaData.getRelationshipTable().equals("")) {
428       try {
429         Connection conn = connMgr.getConnection("DDField", database);
430         Statement s = conn.createStatement();
431         String sqlString =
432           "SELECT id FROM "
433             + metaData.getRelationshipTable()
434             + " WHERE "
435             + metaData.getRelationshipField()
436             + "='"
437             + v
438             + "'";
439         ResultSet rs = s.executeQuery(sqlString);
440         if (rs.next()) {
441           setValue((new Integer(rs.getInt("id"))).toString());
442         }
443         else {
444           problem =
445             new ValidationProblem(
446               ValidationProblem.INCORRECT_LOOKUP_STRING,
447               metaData.getDisplayName(),
448               v);
449         }
450         connMgr.freeConnection(database, conn);
451       }
452       catch (Exception e) {
453         throw new Exception("Failed to setValueFromLookup:" + e.toString());
454       }
455     }
456     else {
457       setValue(v);
458     }
459   }
460 
461   /**
462   sets the value
463   **/
464   public void setValue(String v) {
465 
466     // Reset any previously set problem
467     problem = null;
468     if ((v == null) || (v.equals(""))) {
469       if (metaData.getMandatory())
470         problem =
471           new ValidationProblem(
472             ValidationProblem.EMPTY_MANDATORY_FIELD,
473             metaData.getDisplayName(),
474             v);
475     }
476     if (v == null) {
477       value = null;
478       return;
479     }
480     if (metaData.getType().equals("integer")
481       || metaData.getType().equals("lookup")
482       || metaData.getType().equals("lookupnodrop")
483       || metaData.getType().equals("id")
484       || metaData.getType().equals("lookupwindow")) {
485       // be clever, "" equals 0.  hope this doesn't trash anything
486       // changed again to set null for ""  09/11/1999 tim@hoop.co.uk
487       if (v.equals("")) {
488         v = null;
489       }
490       if (v == null) {
491         value = null;
492       }
493       else {
494         try {
495           value = new Integer(v);
496         }
497         catch (NumberFormatException e) {
498           if (metaData.getType().equals("lookup")
499             || metaData.getType().equals("lookupwindow")) {
500             try {
501               setValueFromLookup(v);
502             }
503             catch (Exception e1) {
504               System.err.println(e1);
505               // ignore this problem (don't throw an exception)
506             }
507           }
508           else
509             problem =
510               new ValidationProblem(
511                 ValidationProblem.INCORRECT_STRING_FORMAT,
512                 metaData.getDisplayName(),
513                 v);
514         }
515       }
516       return;
517     }
518     // autorandom should be stored in the database as a string cos otherwise 
519     // we have problems with precision (certainly with access)
520 
521     if (metaData.getType().equals("text")
522       || metaData.getType().equals("textarea")
523       || metaData.getType().equals("escapedtext")
524       || metaData.getType().equals("password")
525       || metaData.getType().equals("autorandom")
526       || metaData.getType().equals("preformattedtextarea")
527       || metaData.getType().equals("uploadurl")) {
528       value = v;
529       return;
530     }
531     if (metaData.getType().equals("number")
532       || metaData.getType().equals("currency")) {
533       // be clever, "" equals 0.  hope this doesn't trash anything
534       // changed again to set null for ""  09/11/1999 tim@hoop.co.uk
535       // Debugged - 09/11/1999 tim@paneris.co.uk
536       if (v.equals("")) {
537         v = null;
538       }
539       if (v == null) {
540         value = null;
541       }
542       else {
543         try {
544           value = new Double(v);
545         }
546         catch (NumberFormatException e) {
547           problem =
548             new ValidationProblem(
549               ValidationProblem.INCORRECT_STRING_FORMAT,
550               metaData.getDisplayName(),
551               v);
552         }
553       }
554       return;
555     }
556     if (metaData.getType().equals("long")) {
557       // be clever, "" equals zero.  hope this doesn't trash anything
558       // changed again to set null for ""  09/11/1999 tim@hoop.co.uk
559       if (v.equals("")) {
560         v = null;
561       }
562       if (v == null) {
563         value = null;
564       }
565       else {
566         try {
567           value = new Long(v);
568         }
569         catch (NumberFormatException e) {
570           problem =
571             new ValidationProblem(
572               ValidationProblem.INCORRECT_STRING_FORMAT,
573               metaData.getDisplayName(),
574               v);
575         }
576       }
577       return;
578     }
579     if (metaData.getType().equals("date")
580       || metaData.getType().equals("datedrop")) {
581       if (v.equals("")) {
582         value = null;
583       }
584       else {
585         java.util.Date d = dateFormatter1.parse(v, new ParsePosition(0));
586         if (d == null)
587           d = dateFormatter2.parse(v, new ParsePosition(0));
588         if (d == null) {
589           value = null;
590           problem =
591             new ValidationProblem(
592               ValidationProblem.INCORRECT_STRING_FORMAT,
593               metaData.getDisplayName(),
594               v);
595         }
596         else {
597           value = new java.sql.Date(d.getTime());
598         }
599       }
600       return;
601     }
602     if (metaData.getType().equals("datetime")
603       || metaData.getType().equals("timestamp")
604       || metaData.getType().equals("datetimedrop")) {
605       if (v.equals("")) {
606         value = null;
607       }
608       else {
609         java.util.Date d = datetimeFormatter.parse(v, new ParsePosition(0));
610         if (d == null) {
611           value = null;
612           problem =
613             new ValidationProblem(
614               ValidationProblem.INCORRECT_STRING_FORMAT,
615               metaData.getDisplayName(),
616               v);
617         }
618         else {
619           value = new java.sql.Timestamp(d.getTime());
620         }
621       }
622       return;
623     }
624     if (metaData.getType().equals("boolean")) {
625       if (v.equals("")
626         || v.equals("0")
627         || v.equalsIgnoreCase("false")
628         || v.equalsIgnoreCase("f")
629         || v.equalsIgnoreCase("n")) {
630         value = Boolean.FALSE;
631       }
632       else {
633         value = Boolean.TRUE;
634       }
635       return;
636     }
637     value = v;
638   }
639 
640 }