KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > dbforms > taglib > DbFilterValueTag


1 /*
2  * $Header: /cvsroot/jdbforms/dbforms/src/org/dbforms/taglib/DbFilterValueTag.java,v 1.32 2004/10/17 07:02:27 hkollmann Exp $
3  * $Revision: 1.32 $
4  * $Date: 2004/10/17 07:02:27 $
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.taglib;
25
26 import org.apache.commons.logging.Log;
27 import org.apache.commons.logging.LogFactory;
28
29 import org.dbforms.config.Constants;
30 import org.dbforms.config.DbFormsConfigRegistry;
31 import org.dbforms.config.Field;
32 import org.dbforms.config.FieldValue;
33 import org.dbforms.config.FieldValues;
34 import org.dbforms.config.Table;
35
36 import org.dbforms.util.KeyValuePair;
37 import org.dbforms.util.MessageResources;
38 import org.dbforms.util.ParseUtil;
39 import org.dbforms.util.StringUtil;
40 import org.dbforms.util.Util;
41
42 import java.text.SimpleDateFormat JavaDoc;
43
44 import java.util.List JavaDoc;
45
46 import javax.servlet.http.HttpServletRequest JavaDoc;
47 import javax.servlet.jsp.JspException JavaDoc;
48 import javax.servlet.jsp.PageContext JavaDoc;
49
50
51
52 /**
53  * Map a placeholder (?) in sql code to an input tag. Used as nested tag inside
54  * filterCondition. Implements DataContainer interface to use the nested tags
55  * queryData, staticData ...
56  *
57  * @author Sergio Moretti
58  * @version $Revision: 1.32 $
59  */

60 public class DbFilterValueTag extends DbBaseHandlerTag implements DataContainer,
61                                                                   javax.servlet.jsp.tagext.TryCatchFinally JavaDoc {
62    /** DOCUMENT ME! */
63    private static String JavaDoc FLT_VALUETYPE_DATE = "date";
64
65    /** DOCUMENT ME! */
66    private static String JavaDoc FLT_VALUETYPE_NUMERIC = "numeric";
67
68    /** DOCUMENT ME! */
69    private static String JavaDoc FLT_VALUETYPE_SELECT = "select";
70
71    /** DOCUMENT ME! */
72    private static String JavaDoc FLT_VALUETYPE_TEXT = "text";
73
74    /** DOCUMENT ME! */
75    private static String JavaDoc FLT_VALUETYPE_TIMESTAMP = "timestamp";
76    private static Log logCat = LogFactory.getLog(DbFilterValueTag.class
77                                                     .getName());
78
79    /** contain the state of this tag object */
80    private transient State state;
81
82    /**
83                                                                                   *
84                                                                                   */

85    public DbFilterValueTag() {
86       super();
87       state = new State();
88    }
89
90    /**
91     * Allows an additional (independant) entry into the select list
92     *
93     * @param string
94     */

95    public void setCustomEntry(String JavaDoc string) {
96       state.customEntry = string;
97    }
98
99
100    /**
101     * This method is a "hookup" for EmbeddedData - Tags which can assign the
102     * lines of data they loaded (by querying a database, or by rendering
103     * data-subelements, etc. etc.) and make the data available to this tag.
104     * [this method is defined in Interface DataContainer]
105     *
106     * @param embeddedData DOCUMENT ME!
107     */

108    public void setEmbeddedData(List JavaDoc embeddedData) {
109       state.embeddedData = embeddedData;
110    }
111
112
113    /**
114     * property jsCalendarDateFormat.
115     *
116     * @param string
117     */

118    public void setJsCalendarDateFormat(String JavaDoc string) {
119       state.jsCalendarDateFormat = string;
120    }
121
122
123    /**
124     * DOCUMENT ME!
125     *
126     * @return
127     */

128    public String JavaDoc getJsCalendarDateFormat() {
129       return state.jsCalendarDateFormat;
130    }
131
132
133    /**
134     * property label showed before input tag
135     *
136     * @param string
137     */

138    public void setLabel(String JavaDoc string) {
139       state.label = string;
140    }
141
142
143    /**
144     * DOCUMENT ME!
145     *
146     * @return
147     */

148    public String JavaDoc getLabel() {
149       return state.label;
150    }
151
152
153    /**
154     * DOCUMENT ME!
155     *
156     * @param value DOCUMENT ME!
157     */

158    public void setSearchAlgo(String JavaDoc value) {
159       state.searchAlgo = value;
160    }
161
162
163    /**
164     * DOCUMENT ME!
165     *
166     * @return DOCUMENT ME!
167     */

168    public String JavaDoc getSearchAlgo() {
169       return state.searchAlgo;
170    }
171
172
173    /**
174     * property currently selected index, valid only when type = select
175     *
176     * @param string
177     */

178    public void setSelectedIndex(String JavaDoc string) {
179       state.selectedIndex = string;
180    }
181
182
183    /**
184     * property html input's attribute size
185     *
186     * @param string
187     */

188    public void setSize(String JavaDoc string) {
189       state.size = string;
190    }
191
192
193    /**
194     * DOCUMENT ME!
195     *
196     * @param pg DOCUMENT ME!
197     * @param parent DOCUMENT ME!
198     * @param state
199     */

200    public void setState(PageContext JavaDoc pg,
201                         DbFilterConditionTag parent,
202                         State state) {
203       setPageContext(pg);
204       setParent(parent);
205       this.state = state;
206    }
207
208
209    /**
210     * css class to be applied to input element
211     *
212     * @param string
213     */

214    public void setStyleClass(String JavaDoc string) {
215       state.styleClass = string;
216    }
217
218
219    /**
220     * type of the input element that will be rendered, possible values are:
221     *
222     * <dl>
223     * <dt>
224     * text
225     * </dt>
226     * <dd>
227     * text input
228     * </dd>
229     * <dt>
230     * date
231     * </dt>
232     * <dd>
233     * input text for date type, a validation of the value will be done, and it
234     * supports the jscal object
235     * </dd>
236     * <dt>
237     * timestamp
238     * </dt>
239     * <dd>
240     * input text for timestamp type, a validation of the value will be done,
241     * and it supports the jscal object (it doesn't fit very well, anyway ...)
242     * </dd>
243     * <dt>
244     * numeric
245     * </dt>
246     * <dd>
247     * input text for number, a validation of the value will be done
248     * </dd>
249     * <dt>
250     * select
251     * </dt>
252     * <dd>
253     * render an html select element, filled with nested tags like queryData,
254     * staticData and so on.
255     * </dd>
256     * </dl>
257     *
258     *
259     * @param string
260     */

261    public void setType(String JavaDoc string) {
262       state.type = string;
263    }
264
265
266    /**
267     * DOCUMENT ME!
268     *
269     * @param string
270     */

271    public void setUseJsCalendar(String JavaDoc string) {
272       state.useJsCalendar = string;
273    }
274
275
276    /**
277     * DOCUMENT ME!
278     *
279     * @return
280     */

281    public String JavaDoc getUseJsCalendar() {
282       return state.useJsCalendar;
283    }
284
285
286    /**
287     * @see javax.servlet.jsp.tagext.TryCatchFinally#doCatch(java.lang.Throwable)
288     */

289    public void doCatch(Throwable JavaDoc t) throws Throwable JavaDoc {
290       throw t;
291    }
292
293
294    /**
295     * reset tag state
296     *
297     * @see javax.servlet.jsp.tagext.TryCatchFinally#doFinally()
298     */

299    public void doFinally() {
300       state = new State();
301       super.doFinally();
302    }
303
304
305    /**
306     * initialize environment
307     *
308     * @see javax.servlet.jsp.tagext.Tag#doStartTag()
309     */

310    public int doStartTag() throws JspException JavaDoc {
311       init();
312
313       return EVAL_BODY_BUFFERED;
314    }
315
316
317    /**
318     * read from request all values associated to the condition identified with
319     * &lt;tableId&gt;, &lt;conditionId&gt;. It try to read the value with
320     * identifier 0, if succeded go on with identifier 1, and so on.
321     *
322     * @param request
323     * @param tableId identify filter in request's parameters
324     * @param conditionId identify condition in request's parameter
325     *
326     * @return list of all values readed from request
327     */

328    protected static FieldValue[] readValuesFromRequest(HttpServletRequest JavaDoc request,
329                                                        int tableId,
330                                                        int conditionId) {
331       FieldValues values = new FieldValues();
332
333       for (int valueId = 0; true; ++valueId) {
334          // read from parameter's request the value and the type having this
335
// id
336
String JavaDoc paramValue = DbFilterConditionTag.getConditionName(tableId,
337                                                                    conditionId)
338                              + DbFilterTag.FLT_VALUE + valueId;
339          String JavaDoc paramType = DbFilterConditionTag.getConditionName(tableId,
340                                                                   conditionId)
341                             + DbFilterTag.FLT_VALUETYPE + valueId;
342          String JavaDoc searchAlgoType = DbFilterConditionTag.getConditionName(tableId,
343                                                                        conditionId)
344                                  + DbFilterTag.FLT_SEARCHALGO + valueId;
345
346          String JavaDoc value = ParseUtil.getParameter(request, paramValue);
347          String JavaDoc valueType = ParseUtil.getParameter(request, paramType);
348
349          String JavaDoc aSearchAlgorithm = ParseUtil.getParameter(request,
350                                                           searchAlgoType);
351          int algorithm = Constants.SEARCH_ALGO_SHARP;
352
353          if (!Util.isNull(aSearchAlgorithm)) {
354             if (aSearchAlgorithm.startsWith("weakStartEnd")) {
355                algorithm = Constants.SEARCH_ALGO_WEAK_START_END;
356             } else if (aSearchAlgorithm.startsWith("weakStart")) {
357                algorithm = Constants.SEARCH_ALGO_WEAK_START;
358             } else if (aSearchAlgorithm.startsWith("weakEnd")) {
359                algorithm = Constants.SEARCH_ALGO_WEAK_END;
360             } else if (aSearchAlgorithm.startsWith("weak")) {
361                algorithm = Constants.SEARCH_ALGO_WEAK;
362             }
363          }
364
365          valueType = Util.isNull(valueType) ? FLT_VALUETYPE_TEXT
366                                             : valueType;
367
368          if (value != null) {
369             // add value, possibly converted, to list
370
Field f = new Field();
371             f.setName(paramValue);
372             f.setId(valueId);
373             f.setFieldType(valueType);
374
375             Table table = null;
376
377             try {
378                table = DbFormsConfigRegistry.instance()
379                                             .lookup()
380                                             .getTable(tableId);
381             } catch (Exception JavaDoc e) {
382                logCat.error("readValuesFromRequest", e);
383             }
384
385             f.setTable(table);
386
387             FieldValue fv = new FieldValue(f, value);
388             fv.setLocale(MessageResources.getLocale(request));
389             fv.setSearchAlgorithm(algorithm);
390             values.put(fv);
391          } else {
392             // didn't find any parameter with this id, so we have finished
393
break;
394          }
395       }
396
397       return values.toArray();
398    }
399
400
401    /**
402     * DOCUMENT ME!
403     *
404     * @return DOCUMENT ME!
405     */

406    protected Object JavaDoc getFieldObject() {
407       FieldValue fv = new FieldValue(getField(), state.value);
408       fv.setLocale(MessageResources.getLocale((HttpServletRequest JavaDoc) pageContext
409                                               .getRequest()));
410
411       return fv.getFieldValueAsObject();
412    }
413
414
415    /**
416     * DOCUMENT ME!
417     *
418     * @return
419     */

420    protected State getState() {
421       return state;
422    }
423
424
425    /**
426     * render output of this value object. This is called only if its parent's
427     * condition is selected
428     *
429     * @return
430     *
431     * @throws JspException
432     */

433    protected StringBuffer JavaDoc render() throws JspException JavaDoc {
434       StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
435
436       Field f = new Field();
437       f.setName(state.label);
438       f.setId(state.valueId);
439       f.setFieldType(state.type);
440       f.setTable(getParentForm().getTable());
441       setField(f);
442
443       if (state.label != null) {
444          buf.append("<b>" + state.label + "</b>\n");
445       }
446
447       if (state.type.equalsIgnoreCase(FLT_VALUETYPE_TEXT)
448                 || state.type.equalsIgnoreCase(FLT_VALUETYPE_NUMERIC)) {
449          renderTextElement(buf);
450       } else if (state.type.equalsIgnoreCase(FLT_VALUETYPE_DATE)
451                        || state.type.equalsIgnoreCase(FLT_VALUETYPE_TIMESTAMP)) {
452          renderDateElement(buf);
453       } else if (FLT_VALUETYPE_SELECT.equalsIgnoreCase(state.type)
454                        && (state.embeddedData != null)) {
455          renderSelectElement(buf);
456       } else {
457          throw new JspException JavaDoc("type not correct");
458       }
459
460       return buf;
461    }
462
463
464    private String JavaDoc getSearchAlgoType() {
465       return ((DbFilterConditionTag) getParent()).getConditionName()
466              + DbFilterTag.FLT_SEARCHALGO + state.valueId;
467    }
468
469
470    private String JavaDoc getValueName() {
471       return ((DbFilterConditionTag) getParent()).getConditionName()
472              + DbFilterTag.FLT_VALUE + state.valueId;
473    }
474
475
476    private String JavaDoc getValueType() {
477       return ((DbFilterConditionTag) getParent()).getConditionName()
478              + DbFilterTag.FLT_VALUETYPE + state.valueId;
479    }
480
481
482    /**
483     * generate option element for select. borrowed from
484     *
485     * @param value
486     * @param description
487     * @param selected
488     *
489     * @return string containing an html option element
490     *
491     * @see DbSearchComboTag#generateTagString
492     */

493    private String JavaDoc generateTagString(String JavaDoc value,
494                                     String JavaDoc description,
495                                     boolean selected) {
496       StringBuffer JavaDoc tagBuf = new StringBuffer JavaDoc();
497       tagBuf.append("<option value=\"");
498       tagBuf.append(value);
499       tagBuf.append("\"");
500
501       if (selected) {
502          tagBuf.append(" selected=\"selected\"");
503       }
504
505       tagBuf.append(">");
506       tagBuf.append(description.trim());
507       tagBuf.append("</option>");
508
509       return tagBuf.toString();
510    }
511
512
513    /**
514     * initialize tag's state before start using it
515     */

516    private void init() {
517       // state object is createad in constructor (for the first use) and in
518
// doEndTag next
519
if (state.type == null) {
520          state.type = "text";
521       }
522
523       if (state.styleClass == null) {
524          state.styleClass = "";
525       }
526
527       state.valueId = ((DbFilterConditionTag) getParent()).addValue(this);
528       state.value = ParseUtil.getParameter((HttpServletRequest JavaDoc) pageContext
529                                              .getRequest(), getValueName());
530
531       if (state.value == null) {
532          state.value = "";
533       }
534
535       // the type attribute can be read either from request, with
536
// FLT_VALUETYPE, or directly from page
537
state.embeddedData = null;
538    }
539
540
541    /**
542     * render input's type "date"
543     *
544     * @param buf
545     */

546    private void renderDateElement(StringBuffer JavaDoc buf) {
547       renderTextElement(buf);
548
549       // if property useJSCalendar is set to 'true' we will now add a little
550
// image that can be clicked to popup a small JavaScript Calendar
551
// written by Robert W. Husted to edit the field:
552
if ("true".equals(state.useJsCalendar)) {
553          buf.append(" <a HREF=\"javascript:doNothing()\" ")
554             .append(" onclick=\"");
555
556          setPattern(state.jsCalendarDateFormat);
557          state.jsCalendarDateFormat = ((SimpleDateFormat JavaDoc) getFormatter())
558                                       .toPattern();
559
560          if (state.jsCalendarDateFormat != null) // JS Date Format set ?
561
{
562             buf.append("calDateFormat='" + state.jsCalendarDateFormat + "';");
563          }
564
565          buf.append("setDateField(document.dbform['")
566             .append(getValueName())
567             .append("']);")
568             .append(" top.newWin = window.open('")
569             .append(((HttpServletRequest JavaDoc) pageContext.getRequest())
570                     .getContextPath())
571             .append("/jscal/calendar.html','cal','width=270,height=280')\">")
572             .append("<img SRC=\"")
573             .append(((HttpServletRequest JavaDoc) pageContext.getRequest())
574                     .getContextPath())
575             .append("/jscal/calendar.gif\" width=\"32\" height=\"32\" ")
576             .append(" border=0 alt=\"Click on the Calendar to activate the Pop-Up Calendar Window.\">")
577             .append("</img>")
578             .append("</a>");
579       }
580    }
581
582
583    /**
584     * render input's type "select"
585     *
586     * @param buf
587     */

588    private void renderSelectElement(StringBuffer JavaDoc buf) {
589       String JavaDoc sizestr = "";
590
591       if (state.size != null) {
592          sizestr = "size=\"" + state.size + "\" ";
593       }
594
595       buf.append("<select name=\"" + getValueName() + "\" " + sizestr
596                  + " class=\"" + state.styleClass + "\">\n");
597
598       if ((state.customEntry != null)
599                 && (state.customEntry.trim()
600                                            .length() > 0)) {
601          String JavaDoc aKey = org.dbforms.util.StringUtil.getEmbeddedStringWithoutDots(state.customEntry,
602                                                                                0,
603                                                                                ',');
604          String JavaDoc aValue = org.dbforms.util.StringUtil
605                          .getEmbeddedStringWithoutDots(state.customEntry, 1, ',');
606          boolean isSelected = false;
607
608          if ((state.selectedIndex == null)
609                    || (state.selectedIndex.trim()
610                                                 .length() == 0)) {
611             isSelected = "true".equals(StringUtil.getEmbeddedStringWithoutDots(state.customEntry,
612                                                                               2,
613                                                                               ','));
614          }
615
616          buf.append(generateTagString(aKey, aValue, isSelected));
617       }
618
619       int embeddedDataSize = state.embeddedData.size();
620
621       for (int i = 0; i < embeddedDataSize; i++) {
622          KeyValuePair aKeyValuePair = (KeyValuePair) state.embeddedData.get(i);
623          String JavaDoc aKey = aKeyValuePair.getKey();
624          String JavaDoc aValue = aKeyValuePair.getValue();
625
626          // select, if datadriven and data matches with current value OR if
627
// explicitly set by user
628
boolean isSelected = aKey.equals(state.value);
629          buf.append(generateTagString(aKey, aValue, isSelected));
630       }
631
632       buf.append("</select>\n");
633    }
634
635
636    /**
637     * render input's type "text"
638     *
639     * @param buf
640     */

641    private void renderTextElement(StringBuffer JavaDoc buf) {
642       String JavaDoc sizestr = "";
643
644       if (state.size != null) {
645          sizestr = "size=\"" + state.size + "\" ";
646       }
647
648       buf.append("<input type=\"text\" name=\"" + getValueName()
649                  + "\" value=\"" + this.getFormattedFieldValue() + "\""
650                  + sizestr + " class=\"" + state.styleClass + "\"/>\n");
651       buf.append("<input type=\"hidden\" name=\"" + getValueType()
652                  + "\" value=\"" + state.type.toLowerCase() + "\"/>\n");
653
654       if (!Util.isNull(state.searchAlgo)) {
655          buf.append("<input type=\"hidden\" name=\"" + getSearchAlgoType()
656                     + "\" value=\"" + state.searchAlgo + "\"/>\n");
657       }
658    }
659
660    /**
661     * tag's state holder. Used a separate class to hold tag's state to
662     * workaround to Tag pooling, in which an tag object is reused, but we have
663     * the need to store informations about all child tags in the parent, so we
664     * store the state, and apply it to a dummy tag when needed.
665     *
666     * @author Sergio Moretti
667     */

668    protected static class State {
669       /**
670        * contains list of elements to show as options when type is select,
671        * (DataContainer interface)
672        */

673       protected List JavaDoc embeddedData = null;
674
675       /** Allows an additional (independant) entry into the select list */
676       protected String JavaDoc customEntry = null;
677
678       /** Holds value of property jsCalendarDateFormat. */
679       protected String JavaDoc jsCalendarDateFormat = null;
680
681       /** label showed before input tag */
682       protected String JavaDoc label = null;
683
684       /*
685        * holds the searchAlgo
686        */

687       protected String JavaDoc searchAlgo = null;
688
689       /** currently selected index, valid only when type = select */
690       protected String JavaDoc selectedIndex = null;
691
692       /** html input's attribute size */
693       protected String JavaDoc size = null;
694
695       /** css class to be applied to input element */
696       protected String JavaDoc styleClass = null;
697
698       /** type of input */
699       protected String JavaDoc type = null;
700
701       /** Holds value of property useJsCalendar. */
702       protected String JavaDoc useJsCalendar = null;
703
704       /** current value, readed from request */
705       protected String JavaDoc value = null;
706
707       /** identifier of this value object */
708       protected int valueId = -1;
709    }
710 }
711
Popular Tags