KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*
2  * $Header: /cvsroot/jdbforms/dbforms/src/org/dbforms/taglib/DbFormTag.java,v 1.143 2005/02/19 21:26:30 hkollmann Exp $
3  * $Revision: 1.143 $
4  * $Date: 2005/02/19 21:26:30 $
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 package org.dbforms.taglib;
24 import org.apache.commons.lang.StringUtils;
25 import org.apache.commons.logging.Log;
26 import org.apache.commons.logging.LogFactory;
27 import org.apache.commons.validator.ValidatorResources;
28
29 import org.dbforms.config.Constants;
30 import org.dbforms.config.DbEventInterceptor;
31 import org.dbforms.config.DbEventInterceptorData;
32 import org.dbforms.config.DbFormsErrors;
33 import org.dbforms.config.Field;
34 import org.dbforms.config.FieldTypes;
35 import org.dbforms.config.FieldValue;
36 import org.dbforms.config.FieldValues;
37 import org.dbforms.config.GrantedPrivileges;
38 import org.dbforms.config.ResultSetVector;
39 import org.dbforms.config.Table;
40
41 import org.dbforms.event.NavEventFactory;
42 import org.dbforms.event.NavEventFactoryImpl;
43 import org.dbforms.event.NavigationEvent;
44 import org.dbforms.event.WebEvent;
45 import org.dbforms.event.eventtype.EventType;
46
47 import org.dbforms.util.MessageResources;
48 import org.dbforms.util.MessageResourcesInternal;
49 import org.dbforms.util.ParseUtil;
50 import org.dbforms.util.SqlUtil;
51 import org.dbforms.util.TimeUtil;
52 import org.dbforms.util.Util;
53
54 import org.dbforms.validation.DbFormsValidatorUtil;
55 import org.dbforms.validation.ValidatorConstants;
56
57 import java.io.IOException JavaDoc;
58 import java.io.PrintWriter JavaDoc;
59 import java.io.StringWriter JavaDoc;
60
61 import java.sql.Connection JavaDoc;
62 import java.sql.SQLException JavaDoc;
63
64 import java.util.ArrayList JavaDoc;
65 import java.util.Date JavaDoc;
66 import java.util.Enumeration JavaDoc;
67 import java.util.Hashtable JavaDoc;
68 import java.util.Locale JavaDoc;
69 import java.util.Map JavaDoc;
70 import java.util.StringTokenizer JavaDoc;
71 import java.util.Vector JavaDoc;
72
73 import javax.servlet.http.HttpServletRequest JavaDoc;
74 import javax.servlet.http.HttpServletResponse JavaDoc;
75 import javax.servlet.jsp.JspException JavaDoc;
76 import javax.servlet.jsp.JspWriter JavaDoc;
77 import javax.servlet.jsp.tagext.Tag JavaDoc;
78 import javax.servlet.jsp.tagext.TryCatchFinally JavaDoc;
79
80
81
82 /**
83  * This is the root element of a data manipulation form
84  *
85  * @author Joachim Peer
86  */

87 public class DbFormTag extends TagSupportWithScriptHandler
88    implements TryCatchFinally JavaDoc {
89    /** logging category for this class */
90    private static Log logCat = LogFactory.getLog(DbFormTag.class.getName());
91
92    /** NavigationEvent factory */
93    private static NavEventFactory navEventFactory = NavEventFactoryImpl
94       .instance();
95
96    /** reference to a parent DBFormTag (if any) */
97    private transient DbFormTag parentForm;
98    private transient FieldValues orderFields = null;
99
100    /** List of all child field name with assosciate generated name. */
101
102    /* Ex: "champ1" : "f_0_3@root_3" */
103    private transient Hashtable JavaDoc childFieldNames = new Hashtable JavaDoc();
104
105    /** holds the list of fields of the sub forms (2003-02-04 HKK) */
106    private transient Hashtable JavaDoc fieldNames;
107    private transient Hashtable JavaDoc gotoHt = null;
108
109    /** Used to avoid creation of same javascript function. */
110    private transient Hashtable JavaDoc javascriptDistinctFunctions = new Hashtable JavaDoc();
111    private transient Hashtable JavaDoc validationFields;
112
113    /**
114     * Holds the locale the form is created with. Can be readed from other tags
115     */

116    private Locale JavaDoc locale = null;
117
118    /** the data to be rendered */
119    private transient ResultSetVector resultSetVector;
120
121    /** form's action attribute */
122    private String JavaDoc action;
123
124    /**
125     * if "true", at every action (navigation, insert, update, etc.) all input
126     * fields of ALL currently rendered rowsets are parsed and updated. Many
127     * rows may be affected. If "false", updates are only performed if an
128     * explicite "update"- action is launched (normally by hittig the
129     * updateAction-button). Up to 1 row may be affected. <br>
130     * Default is: "false"
131     */

132    private String JavaDoc autoUpdate = "false";
133
134    /** represents the HTML form tag attribute AUTOCOMPLETE. */
135    private String JavaDoc autocomplete = null;
136
137    /** support caption name resolution with ApplicationResources. */
138    private String JavaDoc captionResource = "false";
139
140    /**
141     * used in sub-form: field(s) in this forme that is/are linked to the parent
142     * form
143     */

144    private String JavaDoc childField;
145    private String JavaDoc dbConnectionName = null;
146
147    /** filter string */
148    private String JavaDoc filter;
149
150    /**
151     * site to be invoked after action - nota bene: this followUp may be
152     * overruled by "followUp"-attributes of actionButtons
153     */

154    private String JavaDoc followUp;
155
156    /**
157     * site to be invoked after action if previous form contained errors- nota
158     * bene: this followUp may be overruled by "followUp"-attributes of
159     * actionButtons
160     */

161    private String JavaDoc followUpOnError;
162
163    /** the form name to map with valdation.xml form name. */
164    private String JavaDoc formValidatorName;
165    private String JavaDoc gotoPrefix;
166
167    /** support caption name resolution with ApplicationResources. */
168    private String JavaDoc javascriptFieldsArray = "false";
169
170    /** support caption name resolution with ApplicationResources. */
171    private String JavaDoc javascriptValidation = "false";
172
173    /**
174     * File of validation javascript for include &lt;SCRIPT SRC="..."&gt;
175     * &lt;/SCRIPT&gt; For better performance. Else it's the webserver will
176     * generate it each time.
177     */

178    private String JavaDoc javascriptValidationSrcFile;
179    private String JavaDoc localWebEvent;
180
181    /** count of this form (n ||) */
182    private String JavaDoc maxRows;
183
184    /** is either "true" or "false" */
185    private String JavaDoc multipart;
186
187    /** holds name attribute */
188    private String JavaDoc name = null;
189
190    /** onSubmit form field (20020703-HKK) */
191    private String JavaDoc onSubmit;
192
193    /** SQL order by string */
194    private String JavaDoc orderBy;
195
196    /** true if update should be performed always */
197    private String JavaDoc overrideFieldCheck = null;
198
199    /**
200     * used in sub-form: field(s) in the main form that is/are linked to this
201     * form
202     */

203    private String JavaDoc parentField;
204
205    /**
206     * holds information about how many times the body of this tag has been
207     * rendered
208     */

209    private String JavaDoc positionPath;
210
211    /*
212     * important in subforms: 5th row of subform in 2nd row of main form has
213     * path: "5@2"; in mainforms
214     */

215    private String JavaDoc positionPathCore;
216
217    /** Indicate if the form is in read-only mode */
218    private String JavaDoc readOnly = "false";
219
220    /** redisplayFieldsOnError flag */
221    private String JavaDoc redisplayFieldsOnError = "false";
222
223    /** SQL filter string */
224    private String JavaDoc sqlFilter = null;
225
226    /** Supply table name list */
227    private String JavaDoc tableList;
228
229    /** the name of the underlying table */
230    private String JavaDoc tableName;
231
232    /**
233     * pedant to the html-target attribute in html-form tag: the target frame to
234     * jump to
235     */

236    private String JavaDoc target;
237
238    /** Free-form select query */
239    private String JavaDoc whereClause;
240
241    /** #fixme: description */
242    private StringBuffer JavaDoc childElementOutput;
243
244    /** the underlying table */
245    private transient Table table;
246    private Vector overrulingOrderFields;
247
248    /** holds the list of sub forms to validate (2003-02-04 HKK) */
249    private Vector validationForms;
250
251    /** Keep trace of witch event is use */
252    private transient WebEvent webEvent = null;
253
254    /**
255     * used in sub-form: this data structure holds the linked childfield(s) and
256     * their current values it/they derive from the main form
257     */

258    private transient FieldValue[] childFieldValues;
259
260    /**
261     * if rendering of header and body of the form is completed and only the
262     * footer needs to be rendered yet
263     */

264    private boolean footerReached = false;
265
266    /** subform flag */
267    private boolean isSubForm = false;
268
269    /**
270     * count (multiplicity, view-mode) of this form (n || -1), whereby n E N
271     * (==1,2..z)
272     */

273    private int count;
274
275    /**
276     * holds information about how many times the body of this tag has been
277     * rendered
278     */

279    private int currentCount = 0;
280
281    /** the id of the underlying table */
282    private int tableId = -1;
283
284    /**
285     * Set the action attribute value.
286     *
287     * @param newAction the new attribute value
288     */

289    public void setAction(java.lang.String JavaDoc newAction) {
290       action = newAction;
291    }
292
293
294    /**
295     * Get the action attribute value.
296     *
297     * @return the action attribute value
298     */

299    public java.lang.String JavaDoc getAction() {
300       return action;
301    }
302
303
304    /**
305     * Sets the autoUpdate attribute of the DbFormTag object
306     *
307     * @param autoUpdate The new autoUpdate value
308     */

309    public void setAutoUpdate(String JavaDoc autoUpdate) {
310       this.autoUpdate = autoUpdate;
311    }
312
313
314    /**
315     * Gets the autoUpdate attribute of the DbFormTag object
316     *
317     * @return The autoUpdate value
318     */

319    public String JavaDoc getAutoUpdate() {
320       return autoUpdate;
321    }
322
323
324    /**
325     * DOCUMENT ME!
326     *
327     * @param string
328     */

329    public void setAutocomplete(String JavaDoc string) {
330       autocomplete = string;
331    }
332
333
334    /**
335     * DOCUMENT ME!
336     *
337     * @return autocomplete
338     */

339    public String JavaDoc getAutocomplete() {
340       return autocomplete;
341    }
342
343
344    /**
345     * Sets the captionResource attribute of the DbFormTag object
346     *
347     * @param res The new captionResource value
348     */

349    public void setCaptionResource(String JavaDoc res) {
350       this.captionResource = res;
351    }
352
353
354    /**
355     * Sets the childField attribute of the DbFormTag object
356     *
357     * @param childField The new childField value
358     */

359    public void setChildField(String JavaDoc childField) {
360       this.childField = childField;
361    }
362
363
364    /**
365     * Gets the childField attribute of the DbFormTag object
366     *
367     * @return The childField value
368     */

369    public String JavaDoc getChildField() {
370       return childField;
371    }
372
373
374    /**
375     * Gets the count attribute of the DbFormTag object
376     *
377     * @return The count value
378     */

379    public int getCount() {
380       return count;
381    }
382
383
384    /**
385     * Gets the currentCount attribute of the DbFormTag object
386     *
387     * @return The currentCount value
388     */

389    public int getCurrentCount() {
390       return currentCount;
391    }
392
393
394    /**
395     * Sets the dbConnectionName attribute of the DbFormTag object
396     *
397     * @param dbConnectionName The new dbConnectionName value
398     */

399    public void setDbConnectionName(String JavaDoc dbConnectionName) {
400       this.dbConnectionName = dbConnectionName;
401    }
402
403
404    /**
405     * Gets the dbConnectionName attribute of the DbFormTag object
406     *
407     * @return The dbConnectionName value
408     */

409    public String JavaDoc getDbConnectionName() {
410       return dbConnectionName;
411    }
412
413
414    /**
415     * Sets the filter attribute of the DbFormTag object
416     *
417     * @param filter The new filter value
418     */

419    public void setFilter(String JavaDoc filter) {
420       this.filter = filter;
421    }
422
423
424    /**
425     * Gets the filter attribute of the DbFormTag object
426     *
427     * @return The filter value
428     */

429    public String JavaDoc getFilter() {
430       return filter;
431    }
432
433
434    /**
435     * Sets the followUp attribute of the DbFormTag object
436     *
437     * @param followUp The new followUp value
438     */

439    public void setFollowUp(String JavaDoc followUp) {
440       this.followUp = followUp;
441    }
442
443
444    /**
445     * Gets the followUp attribute of the DbFormTag object
446     *
447     * @return The followUp value
448     */

449    public String JavaDoc getFollowUp() {
450       return followUp;
451    }
452
453
454    /**
455     * Sets the followUpOnError attribute
456     *
457     * @param followUpOnError The followUpOnError to set
458     */

459    public void setFollowUpOnError(String JavaDoc followUpOnError) {
460       this.followUpOnError = followUpOnError;
461    }
462
463
464    /**
465     * Gets the followUpOnError
466     *
467     * @return Returns a String
468     */

469    public String JavaDoc getFollowUpOnError() {
470       return followUpOnError;
471    }
472
473
474    /**
475     * Sets the footerReached attribute of the DbFormTag object
476     *
477     * @param footerReached The new footerReached value
478     */

479    public void setFooterReached(boolean footerReached) {
480       this.footerReached = footerReached;
481    }
482
483
484    /**
485     * Gets the footerReached attribute of the DbFormTag object
486     *
487     * @return The footerReached value
488     */

489    public boolean isFooterReached() {
490       return footerReached;
491    }
492
493
494    /**
495     * Sets the formValidatorName attribute of the DbFormTag object
496     *
497     * @param fv The new formValidatorName value
498     */

499    public void setFormValidatorName(String JavaDoc fv) {
500       this.formValidatorName = fv;
501    }
502
503
504    /**
505     * Gets the formValidatorName attribute of the DbFormTag object
506     *
507     * @return The formValidatorName value
508     */

509    public String JavaDoc getFormValidatorName() {
510       return formValidatorName;
511    }
512
513
514    /**
515     * Sets the gotoHt attribute of the DbFormTag object
516     *
517     * @param gotoHt The new gotoHt value
518     */

519    public void setGotoHt(Hashtable JavaDoc gotoHt) {
520       this.gotoHt = gotoHt;
521    }
522
523
524    /**
525     * Gets the gotoHt attribute of the DbFormTag object
526     *
527     * @return The gotoHt value
528     */

529    public Hashtable JavaDoc getGotoHt() {
530       return gotoHt;
531    }
532
533
534    /**
535     * Sets the gotoPrefix attribute of the DbFormTag object
536     *
537     * @param gotoPrefix The new gotoPrefix value
538     */

539    public void setGotoPrefix(String JavaDoc gotoPrefix) {
540       this.gotoPrefix = gotoPrefix;
541    }
542
543
544    /**
545     * Gets the gotoPrefix attribute of the DbFormTag object
546     *
547     * @return The gotoPrefix value
548     */

549    public String JavaDoc getGotoPrefix() {
550       return gotoPrefix;
551    }
552
553
554    /**
555     * Sets the javascriptFieldsArray attribute of the DbFormTag object
556     *
557     * @param jfa The new javascriptFieldsArray value
558     */

559    public void setJavascriptFieldsArray(String JavaDoc jfa) {
560       this.javascriptFieldsArray = jfa;
561    }
562
563
564    /**
565     * Sets the javascriptValidation attribute of the DbFormTag object
566     *
567     * @param jsv The new javascriptValidation value
568     */

569    public void setJavascriptValidation(String JavaDoc jsv) {
570       this.javascriptValidation = jsv;
571    }
572
573
574    /**
575     * Sets the javascriptFieldsArray attribute of the DbFormTag object
576     *
577     * @param jsvs The javascriptFieldsArray value
578     */

579    public void setJavascriptValidationSrcFile(String JavaDoc jsvs) {
580       this.javascriptValidationSrcFile = jsvs;
581    }
582
583
584    /**
585     * Gets the javascriptValidationSrcFile attribute of the DbFormTag object
586     *
587     * @return The javascriptValidationSrcFile value
588     */

589    public String JavaDoc getJavascriptValidationSrcFile() {
590       return javascriptValidationSrcFile;
591    }
592
593
594    /**
595     * Sets the localWebEvent attribute of the DbFormTag object
596     *
597     * @param localWebEvent The new localWebEvent value
598     */

599    public void setLocalWebEvent(String JavaDoc localWebEvent) {
600       this.localWebEvent = localWebEvent;
601    }
602
603
604    /**
605     * Gets the localWebEvent attribute of the DbFormTag object
606     *
607     * @return The localWebEvent value
608     */

609    public String JavaDoc getLocalWebEvent() {
610       return localWebEvent;
611    }
612
613
614    /**
615     * Returns the locale the form is created with. Can be readed from other
616     * tags
617     *
618     * @return DOCUMENT ME!
619     */

620    public Locale JavaDoc getLocale() {
621       return locale;
622    }
623
624
625    /**
626     * Sets the maxRows attribute of the DbFormTag object
627     *
628     * @param maxRows The new maxRows value
629     */

630    public void setMaxRows(String JavaDoc maxRows) {
631       this.maxRows = maxRows;
632
633       if (maxRows.trim().equals("*")) {
634          this.count = 0;
635       } else {
636          this.count = Integer.parseInt(maxRows);
637       }
638    }
639
640
641    /**
642     * Gets the maxRows attribute of the DbFormTag object
643     *
644     * @return The maxRows value
645     */

646    public String JavaDoc getMaxRows() {
647       return maxRows;
648    }
649
650
651    /**
652     * Sets the multipart attribute of the DbFormTag object
653     *
654     * @param value The new multipart value
655     */

656    public void setMultipart(String JavaDoc value) {
657       this.multipart = value;
658    }
659
660
661    /**
662     * DOCUMENT ME!
663     *
664     * @param string
665     */

666    public void setName(String JavaDoc string) {
667       name = string;
668    }
669
670
671    /**
672     * DOCUMENT ME!
673     *
674     * @return
675     */

676    public String JavaDoc getName() {
677       return (name != null) ? name : tableName;
678    }
679
680
681    /**
682     * Set the onSubmit attribute value
683     *
684     * @param newonSubmit the new onSubmit value
685     */

686    public void setOnSubmit(String JavaDoc newonSubmit) {
687       onSubmit = newonSubmit;
688    }
689
690
691    /**
692     * Get the onSubmit attribute.
693     *
694     * @return the onSubmit attribute
695     */

696    public java.lang.String JavaDoc getOnSubmit() {
697       return onSubmit;
698    }
699
700
701    /**
702     * Sets the orderBy attribute of the DbFormTag object
703     *
704     * @param orderBy The new orderBy value
705     */

706    public void setOrderBy(String JavaDoc orderBy) {
707       this.orderBy = orderBy;
708    }
709
710
711    /**
712     * Gets the orderBy attribute of the DbFormTag object
713     *
714     * @return The orderBy value
715     */

716    public String JavaDoc getOrderBy() {
717       return orderBy;
718    }
719
720
721    /**
722     * DOCUMENT ME!
723     *
724     * @return DOCUMENT ME!
725     */

726    public FieldValues getOrderFields() {
727       return orderFields;
728    }
729
730
731    /**
732     * DOCUMENT ME!
733     *
734     * @param string
735     */

736    public void setOverrideFieldCheck(String JavaDoc string) {
737       overrideFieldCheck = string;
738    }
739
740
741    /**
742     * DOCUMENT ME!
743     *
744     * @return
745     */

746    public String JavaDoc getOverrideFieldCheck() {
747       return overrideFieldCheck;
748    }
749
750
751    /**
752     * Set the parent tag
753     *
754     * @param p the parent tag
755     */

756    public void setParent(Tag JavaDoc p) {
757       super.setParent(p);
758       this.parentForm = (DbFormTag) findAncestorWithClass(this, DbFormTag.class);
759    }
760
761
762    /**
763     * Sets the parentField attribute of the DbFormTag object
764     *
765     * @param parentField The new parentField value
766     */

767    public void setParentField(String JavaDoc parentField) {
768       this.parentField = parentField;
769    }
770
771
772    /**
773     * Gets the parentField attribute of the DbFormTag object
774     *
775     * @return The parentField value
776     */

777    public String JavaDoc getParentField() {
778       return parentField;
779    }
780
781
782    /**
783     * Gets the positionPath attribute of the DbFormTag object
784     *
785     * @return The positionPath value
786     */

787    public String JavaDoc getPositionPath() {
788       return positionPath;
789    }
790
791
792    /**
793     * Gets the positionPathCore attribute of the DbFormTag object.
794     *
795     * @return The positionPathCore value
796     */

797
798    /* eg. "root", "123@35@root" */
799    public String JavaDoc getPositionPathCore() {
800       return positionPathCore;
801    }
802
803
804    /**
805     * Sets the readOnly attribute of the DbFormTag object
806     *
807     * @param readOnly The new readOnly value
808     */

809    public void setReadOnly(String JavaDoc readOnly) {
810       this.readOnly = readOnly;
811    }
812
813
814    /**
815     * Set the redisplayFieldsOnError attribute
816     *
817     * @param newRedisplayFieldsOnError the new redisplayFieldsOnError value
818     */

819    public void setRedisplayFieldsOnError(
820       java.lang.String JavaDoc newRedisplayFieldsOnError) {
821       redisplayFieldsOnError = newRedisplayFieldsOnError;
822    }
823
824
825    /**
826     * Gets the resultSetVector attribute of the DbFormTag object
827     *
828     * @return The resultSetVector value
829     */

830    public ResultSetVector getResultSetVector() {
831       return resultSetVector;
832    }
833
834
835    /**
836     * DOCUMENT ME!
837     *
838     * @param string
839     */

840    public void setSqlFilter(String JavaDoc string) {
841       sqlFilter = string;
842    }
843
844
845    /**
846     * DOCUMENT ME!
847     *
848     * @return
849     */

850    public String JavaDoc getSqlFilter() {
851       return sqlFilter;
852    }
853
854
855    /**
856     * Gets the subForm attribute of the DbFormTag object
857     *
858     * @return The subForm value
859     */

860    public boolean isSubForm() {
861       return isSubForm;
862    }
863
864
865    /**
866     * Gets the table attribute of the DbFormTag object
867     *
868     * @return The table value
869     */

870    public Table getTable() {
871       return table;
872    }
873
874
875    /**
876     * Set the table list attribute value
877     *
878     * @param tableList the new tableList value
879     */

880    public void setTableList(String JavaDoc tableList) {
881       this.tableList = tableList;
882    }
883
884
885    /**
886     * Get the table list attribute.
887     *
888     * @return the table list string
889     */

890    public String JavaDoc getTableList() {
891       return tableList;
892    }
893
894
895    /**
896     * Sets the tableName attribute of the DbFormTag object
897     *
898     * @param tableName The new tableName value
899     *
900     * @throws Exception DOCUMENT ME!
901     */

902    public void setTableName(String JavaDoc tableName) throws Exception JavaDoc {
903       this.tableName = tableName;
904       this.table = getConfig().getTableByName(tableName);
905
906       if (getTable() == null) {
907          throw new Exception JavaDoc("Table " + tableName
908             + " not found in configuration");
909       }
910
911       this.tableId = getTable().getId();
912    }
913
914
915    /**
916     * Gets the tableName attribute of the DbFormTag object
917     *
918     * @return The tableName value
919     */

920    public String JavaDoc getTableName() {
921       return tableName;
922    }
923
924
925    /**
926     * Sets the target attribute of the DbFormTag object
927     *
928     * @param target The new target value
929     */

930    public void setTarget(String JavaDoc target) {
931       this.target = target;
932    }
933
934
935    /**
936     * Gets the target attribute of the DbFormTag object
937     *
938     * @return The target value
939     */

940    public String JavaDoc getTarget() {
941       return target;
942    }
943
944
945    /**
946     * DOCUMENT ME!
947     *
948     * @return
949     */

950    public WebEvent getWebEvent() {
951       return webEvent;
952    }
953
954
955    /**
956     * Sets the whereClause attribute of the DbFormTag object
957     *
958     * @param wc The new whereClause value
959     */

960    public void setWhereClause(String JavaDoc wc) {
961       this.whereClause = wc;
962    }
963
964
965    /**
966     * Gets the whereClause attribute of the DbFormTag object
967     *
968     * @return The whereClause value
969     */

970    public String JavaDoc getWhereClause() {
971       return whereClause;
972    }
973
974
975    /**
976     * Adds a feature to the ChildName attribute of the DbFormTag object
977     *
978     * @param tableFieldName The feature to be added to the ChildName attribute
979     * @param dbFormGeneratedName The feature to be added to the ChildName
980     * attribute
981     */

982    public void addChildName(String JavaDoc tableFieldName, String JavaDoc dbFormGeneratedName) {
983       childFieldNames.put(dbFormGeneratedName, tableFieldName);
984    }
985
986
987    /**
988     * Adds a feature to the JavascriptFunction attribute of the DbFormTag
989     * object
990     *
991     * @param jsFctName The feature to be added to the JavascriptFunction
992     * attribute
993     * @param jsFct The feature to be added to the JavascriptFunction attribute
994     */

995    public void addJavascriptFunction(String JavaDoc jsFctName, StringBuffer JavaDoc jsFct) {
996       if (!existJavascriptFunction(jsFctName)) {
997          javascriptDistinctFunctions.put(jsFctName, jsFct);
998       }
999    }
1000
1001
1002   /**
1003    * DOCUMENT ME!
1004    *
1005    * @param formName DOCUMENT ME!
1006    * @param childFields DOCUMENT ME!
1007    */

1008   public void addValidationForm(String JavaDoc formName, Hashtable JavaDoc childFields) {
1009      if (validationForms == null) {
1010         validationForms = new Vector();
1011      }
1012
1013      validationForms.add(formName);
1014
1015      if (validationFields == null) {
1016         validationFields = new Hashtable JavaDoc();
1017      }
1018
1019      validationFields.putAll(childFields);
1020   }
1021
1022
1023   /**
1024    * Append the input string to the childElementOutput stringBuffer.
1025    *
1026    * @param str the string to append
1027    */

1028   public void appendToChildElementOutput(String JavaDoc str) {
1029      if (!Util.isNull(str)) {
1030         this.childElementOutput.append(str);
1031      }
1032   }
1033
1034
1035   /**
1036    * DOCUMENT ME!
1037    *
1038    * @return DOCUMENT ME!
1039    *
1040    * @throws JspException DOCUMENT ME!
1041    */

1042   public int doAfterBody() throws JspException JavaDoc {
1043      if (ResultSetVector.isNull(resultSetVector)) {
1044         setFooterReached(true);
1045
1046         return SKIP_BODY;
1047      }
1048
1049      boolean renderPage = !isFooterReached();
1050
1051      currentCount++;
1052
1053      int pCount = getCount(); // pCount==-1 => endless form, else max nr. of eval.loops is pCount
1054

1055      logCat.info("we are talking about=" + getTableName() + " pcount="
1056         + pCount + " pcurrent=" + currentCount);
1057
1058      // field values that have not been rendered by html tags but that is determinated by field
1059
// mapping between main- and subform are rendered now:
1060
if (isSubForm() && !isFooterReached()) {
1061         appendToChildElementOutput(produceLinkedTags()); // print hidden-fields for missing insert-fields we can determinated
1062
}
1063
1064      if (((pCount != -1) && (currentCount == pCount)) // if the max-count is reached
1065
|| (ResultSetVector.isNull(getResultSetVector()))
1066               || (getResultSetVector().isLast())) {
1067         logCat.info("setting footerreached to true");
1068         setFooterReached(true); // tell parent form that there are no more loops do go and the only thing remaining to be rendered is this footerTag and its subelements
1069
}
1070
1071      getResultSetVector().moveNext();
1072
1073      // rsv may be null in empty-forms (where not tableName attribute is
1074
// provided)
1075
if (renderPage) {
1076         return EVAL_BODY_BUFFERED;
1077      } else {
1078         return SKIP_BODY;
1079      }
1080   }
1081
1082
1083   /**
1084    * DOCUMENT ME!
1085    *
1086    * @param t DOCUMENT ME!
1087    *
1088    * @throws Throwable DOCUMENT ME!
1089    */

1090   public void doCatch(Throwable JavaDoc t) throws Throwable JavaDoc {
1091      StringWriter JavaDoc sw = new StringWriter JavaDoc();
1092      PrintWriter JavaDoc pw = new PrintWriter JavaDoc(sw);
1093      t.printStackTrace(pw);
1094      logCat.error("DbFormTag.doCatch called - " + t.toString() + "\n"
1095         + sw.toString());
1096      throw t;
1097   }
1098
1099
1100   /**
1101    * D O E N D T A G
1102    *
1103    * @return Description of the Return Value
1104    *
1105    * @exception JspException Description of the Exception
1106    */

1107   public int doEndTag() throws JspException JavaDoc {
1108      JspWriter JavaDoc jspOut = pageContext.getOut();
1109
1110      // avoid to call getOut each time (Demeter law)
1111
try {
1112         if (bodyContent != null) {
1113            bodyContent.writeOut(bodyContent.getEnclosingWriter());
1114            bodyContent.clearBody();
1115
1116            // 2002116-HKK: workaround for duplicate rows in Tomcat 4.1
1117
}
1118
1119         logCat.debug("pageContext.getOut()=" + pageContext.getOut());
1120         logCat.debug("childElementOutput=" + childElementOutput);
1121
1122         // hidden fields and other stuff coming from child elements get
1123
// written out
1124
if (childElementOutput != null) {
1125            jspOut.println(childElementOutput.toString());
1126         }
1127
1128         if (parentForm == null) {
1129            jspOut.println("</form>");
1130         }
1131
1132         /* Generate Javascript validation methods & calls */
1133         if (!Util.isNull(getFormValidatorName())
1134                  && hasJavascriptValidationSet()) {
1135            jspOut.println(generateJavascriptValidation());
1136         }
1137
1138         /*
1139          * Generate Javascript array of fields. To help developper to work
1140          * with DbForms fields name.
1141          *
1142          * Ex: champ1 => f_0_1@root_4
1143          */

1144         if (hasJavascriptFieldsArraySet()) {
1145            jspOut.println(generateJavascriptFieldsArray());
1146         }
1147
1148         /* Write generic Javascript functions created from childs tag */
1149         if (javascriptDistinctFunctions.size() > 0) {
1150            jspOut.println("\n<SCRIPT language=\"javascript\">\n");
1151
1152            Enumeration JavaDoc e = javascriptDistinctFunctions.keys();
1153
1154            while (e.hasMoreElements()) {
1155               String JavaDoc aKey = (String JavaDoc) e.nextElement();
1156               StringBuffer JavaDoc sbFonction = (StringBuffer JavaDoc) javascriptDistinctFunctions
1157                  .get(aKey);
1158
1159               jspOut.println(sbFonction);
1160            }
1161
1162            jspOut.println("\n</SCRIPT>\n");
1163         }
1164      } catch (IOException JavaDoc ioe) {
1165         logCat.error("::doEndTag - IOException", ioe);
1166      }
1167
1168      logCat.info("end reached of " + tableName);
1169
1170      return EVAL_PAGE;
1171   }
1172
1173
1174   /**
1175    * DOCUMENT ME!
1176    */

1177   public void doFinally() {
1178      logCat.info("doFinally called");
1179
1180      if (validationForms != null) {
1181         validationForms.clear();
1182      }
1183
1184      if (validationFields != null) {
1185         validationFields.clear();
1186      }
1187
1188      if (fieldNames != null) {
1189         fieldNames.clear();
1190      }
1191
1192      if (childFieldNames != null) {
1193         childFieldNames.clear();
1194      }
1195
1196      sqlFilter = null;
1197      orderFields = null;
1198      overrideFieldCheck = null;
1199   }
1200
1201
1202   /**
1203    * Philip Grunikiewicz 2001-08-17 Added an attribute to allow developer to
1204    * bypass navigation: If we are not going to use navigation, eliminate the
1205    * creation of, and execution of "fancy!" queries. Henner Kollmann
1206    * 2002-07-03 Added onSubmit support Philip Grunikiewicz 2001-10-22
1207    * Sometimes we use dbForms to simply display information on screen but
1208    * wish to call another servlet to process the post. I've added the
1209    * 'action' attribute to allow a developer to set the wanted action instead
1210    * of defaulting to the dbforms control servlet. Important: Use a fully
1211    * qualified path. Philip Grunikiewicz 2001-11-28 Introducing Free-form
1212    * select queries. Using the whereClause attribute, developers are now able
1213    * to specify the ending of an actual DbForms query. Dbforms generates the
1214    * "Select From" part, and the developers have the responsibility of
1215    * completing the query. ie: adding the whereClause, an orderBy, etc...
1216    * Note that using this function renders navigation impossible!
1217    *
1218    * @return Description of the Return Value
1219    */

1220   public int doStartTag() {
1221      try {
1222         Connection JavaDoc con = getConfig().getConnection(dbConnectionName);
1223
1224         // *************************************************************
1225
// Part I - checking user access right, processing interceptor
1226
// *************************************************************
1227
HttpServletRequest JavaDoc request = (HttpServletRequest JavaDoc) pageContext
1228            .getRequest();
1229         HttpServletResponse JavaDoc response = (HttpServletResponse JavaDoc) pageContext
1230            .getResponse();
1231
1232         locale = MessageResources.getLocale(request);
1233
1234         logCat.info("servlet path = " + request.getServletPath());
1235         logCat.info("servlet getPathInfo = " + request.getPathInfo());
1236
1237         logCat.info("servlet getContextPath = " + request.getContextPath());
1238         logCat.info("servlet getRequestURI = " + request.getRequestURI());
1239
1240         String JavaDoc strFollowUp = getFollowUp();
1241
1242         if (Util.isNull(strFollowUp)) {
1243            strFollowUp = request.getRequestURI();
1244
1245            String JavaDoc contextPath = request.getContextPath();
1246
1247            if (!Util.isNull(contextPath)) {
1248               strFollowUp = strFollowUp.substring(contextPath.length(),
1249                     strFollowUp.length());
1250            }
1251
1252            if (!Util.isNull(request.getQueryString())) {
1253               strFollowUp += ("?" + request.getQueryString());
1254            }
1255         }
1256
1257         logCat.debug("pos1");
1258
1259         // part I/a - security
1260
JspWriter JavaDoc out = pageContext.getOut();
1261
1262         logCat.debug("pos2");
1263
1264         // check user privilege
1265
if ((getTable() != null)
1266                  && !getTable().hasUserPrivileg(request,
1267                     GrantedPrivileges.PRIVILEG_SELECT)) {
1268            logCat.debug("pos3");
1269
1270            String JavaDoc str = MessageResourcesInternal.getMessage("dbforms.events.view.nogrant",
1271                  getLocale(), new String JavaDoc[] {
1272                     getTable().getName()
1273                  });
1274            logCat.warn(str);
1275            out.println(str);
1276
1277            return SKIP_BODY;
1278         }
1279
1280         logCat.debug("pos4");
1281
1282         DbEventInterceptorData interceptorData = new DbEventInterceptorData(request,
1283               getConfig(), con, getTable());
1284         interceptorData.setAttribute(DbEventInterceptorData.CONNECTIONNAME,
1285            dbConnectionName);
1286         interceptorData.setAttribute(DbEventInterceptorData.PAGECONTEXT,
1287            pageContext);
1288
1289         // part II/b - processing interceptors
1290
if ((getTable() != null) && getTable().hasInterceptors()) {
1291            try {
1292               logCat.debug("pos5");
1293               getTable().processInterceptors(DbEventInterceptor.PRE_SELECT,
1294                  interceptorData);
1295            } catch (Exception JavaDoc sqle) {
1296               logCat.error("pos6");
1297               logCat.error(sqle.getMessage(), sqle);
1298               out.println(sqle.getMessage());
1299
1300               return SKIP_BODY;
1301            }
1302         }
1303
1304         logCat.debug("pos7");
1305
1306         // *************************************************************
1307
// Part II - WebEvent infrastructural stuff ----
1308
// write out data for the controller so that it
1309
// knows what it deals with if user hits a button
1310
// *************************************************************
1311
StringBuffer JavaDoc tagBuf = new StringBuffer JavaDoc();
1312
1313         // explicitly re-set all instance variables which get changed during
1314
// evaluation loops
1315
// and which are not reset by the jsp container trough setXxx()
1316
// methods and
1317
logCat.info("resetting values of tag");
1318         currentCount = 0;
1319         footerReached = false;
1320         resultSetVector = null;
1321         childElementOutput = new StringBuffer JavaDoc();
1322         logCat.debug("first steps finished");
1323
1324         // if main form
1325
// we write out the form-tag which points to the controller-servlet
1326
if (parentForm == null) {
1327            tagBuf.append("<form ");
1328
1329            if (!Util.isNull(getId())) {
1330               tagBuf.append("id=\"");
1331               tagBuf.append(getId());
1332               tagBuf.append("\" ");
1333            }
1334
1335            tagBuf.append("name=\"dbform\" action=\"");
1336
1337            //Check if developer has overriden action
1338
if ((this.getAction() != null)
1339                     && (this.getAction().trim().length() > 0)) {
1340               tagBuf.append(this.getAction());
1341            } else {
1342               tagBuf.append(response.encodeURL(request.getContextPath()
1343                     + "/servlet/control"));
1344            }
1345
1346            tagBuf.append("\"");
1347
1348            // JFM 20040309: additional attribute autocomplete
1349
if (getAutocomplete() != null) {
1350               tagBuf.append(" autocomplete=\"" + getAutocomplete() + "\"");
1351            }
1352
1353            // append target element
1354
if (target != null) {
1355               tagBuf.append(" target=\"");
1356               tagBuf.append(target);
1357               tagBuf.append("\"");
1358            }
1359
1360            tagBuf.append(" method=\"post\"");
1361
1362            if (hasMultipartSet()) {
1363               tagBuf.append(" enctype=\"multipart/form-data\"");
1364            }
1365
1366            String JavaDoc validationFct = null;
1367
1368            if (hasJavascriptValidationSet()) {
1369               validationFct = getFormValidatorName();
1370
1371               if (!Util.isNull(validationFct)) {
1372                  validationFct = Character.toUpperCase(validationFct.charAt(
1373                           0))
1374                     + validationFct.substring(1, validationFct.length());
1375                  validationFct = "validate" + validationFct + "(this)";
1376               }
1377            }
1378
1379            if (!Util.isNull(validationFct) && !Util.isNull(getOnSubmit())) {
1380               boolean found = false;
1381               String JavaDoc s = getOnSubmit();
1382               String JavaDoc[] cmds = StringUtils.split(s, ';');
1383
1384               for (int i = 0; i < cmds.length; i++) {
1385                  cmds[i] = cmds[i].trim();
1386
1387                  if (cmds[i].startsWith("return")) {
1388                     cmds[i] = cmds[i].substring("return".length());
1389                     cmds[i] = "return " + validationFct + " && " + cmds[i];
1390                     found = true;
1391
1392                     break;
1393                  }
1394               }
1395
1396               s = "";
1397
1398               for (int i = 0; i < cmds.length; i++) {
1399                  s = s + cmds[i] + ";";
1400               }
1401
1402               if (!found) {
1403                  s = s + "return " + validationFct + ";";
1404               }
1405
1406               tagBuf.append(" onSubmit=\"");
1407               tagBuf.append(s);
1408               tagBuf.append("\" ");
1409            } else if (!Util.isNull(validationFct)) {
1410               tagBuf.append(" onSubmit=\"");
1411               tagBuf.append("return " + validationFct);
1412               tagBuf.append("\" ");
1413            } else if (!Util.isNull(getOnSubmit())) {
1414               tagBuf.append(" onSubmit=\"");
1415               tagBuf.append(getOnSubmit());
1416               tagBuf.append("\" ");
1417            }
1418
1419            tagBuf.append(">");
1420
1421            // supports RFC 1867 - multipart upload, if some database-fields
1422
// represent filedata
1423
if (tableName == null) {
1424               appendSource(request, tagBuf);
1425               tagBuf.append("<input type=\"hidden\" name=\"fu_" + tableId
1426                  + "\" value=\"" + strFollowUp + "\"/>");
1427
1428               // if form is an emptyform -> we've fineshed yet - cancel
1429
// all further activities!
1430
out.println(tagBuf.toString());
1431
1432               return EVAL_BODY_BUFFERED;
1433            }
1434
1435            positionPathCore = "root";
1436         } else {
1437            // if sub-form, we dont write out html tags; this has been done
1438
// already by a parent form
1439
this.isSubForm = true;
1440            positionPathCore = parentForm.getPositionPath();
1441
1442            // If whereClause is not supplied by developer
1443
// determine the value(s) of the linked field(s)
1444
if (Util.isNull(getWhereClause())) {
1445               initChildFieldValues();
1446
1447               if (childFieldValues == null) {
1448                  return SKIP_BODY;
1449               }
1450            }
1451         }
1452
1453         // write out involved table
1454
tagBuf.append("<input type=\"hidden\" name=\"invtable\" value=\""
1455            + tableId + "\"/>");
1456
1457         // write out the name of the involved dbconnection.
1458
tagBuf.append("<input type='hidden' name='invname_" + tableId
1459            + "' value='"
1460            + (Util.isNull(dbConnectionName) ? "" : dbConnectionName) + "'/>");
1461
1462         // write out the autoupdate-policy of this form
1463
tagBuf.append("<input type=\"hidden\" name=\"autoupdate_" + tableId
1464            + "\" value=\"" + autoUpdate + "\"/>");
1465
1466         // write out the followup-default for this table
1467
tagBuf.append("<input type=\"hidden\" name=\"fu_" + tableId
1468            + "\" value=\"" + strFollowUp + "\"/>");
1469
1470         // write out the locale
1471
tagBuf.append("<input type=\"hidden\" name=\"lang" + "\" value=\""
1472            + locale.getLanguage() + "\"/>");
1473         tagBuf.append("<input type=\"hidden\" name=\"country" + "\" value=\""
1474            + locale.getCountry() + "\"/>");
1475
1476         // write out the followupOnError-default for this table
1477
if (!Util.isNull(getFollowUpOnError())) {
1478            tagBuf.append("<input type=\"hidden\" name=\"fue_" + tableId
1479               + "\" value=\"" + getFollowUpOnError() + "\"/>");
1480         }
1481
1482         if (!Util.isNull(getOverrideFieldCheck())) {
1483            tagBuf.append("<input type=\"hidden\" name=\""
1484               + Constants.FIELDNAME_OVERRIDEFIELDTEST + tableId
1485               + "\" value=\"" + getOverrideFieldCheck() + "\"/>");
1486         }
1487
1488         // write out the formValidatorName
1489
if (!Util.isNull(getFormValidatorName())) {
1490            tagBuf.append("<input type=\"hidden\" name=\""
1491               + ValidatorConstants.FORM_VALIDATOR_NAME + "_" + tableId
1492               + "\" value=\"" + getFormValidatorName() + "\"/>");
1493         }
1494
1495         appendSource(request, tagBuf);
1496
1497         // Allow to send action dynamicaly from javascript
1498
tagBuf.append("<input type=\"hidden\" name=\"customEvent\"/>");
1499
1500         // *************************************************************
1501
// Part III - fetching Data. This data is provided to all sub-
1502
// elements of this form.
1503
// *************************************************************
1504
// III/1:
1505
// initialize all of the different filters
1506
// retrieve sqlFilters
1507
String JavaDoc sqlFilterString = "";
1508         String JavaDoc requestSqlFilterString = DbFilterTag.getSqlFilter(request,
1509               this.getTable().getId());
1510         FieldValue[] sqlFilterParams = null;
1511
1512         if (!Util.isNull(getSqlFilter())
1513                  && !Util.isNull(requestSqlFilterString)) {
1514            sqlFilterString = " ( " + requestSqlFilterString + " ) AND ( "
1515               + getSqlFilter() + " ) ";
1516         } else if (!Util.isNull(getSqlFilter())) {
1517            sqlFilterString = getSqlFilter();
1518         } else if (!Util.isNull(requestSqlFilterString)) {
1519            sqlFilterString = requestSqlFilterString;
1520         }
1521
1522         logCat.debug("filter to apply : " + sqlFilterString);
1523
1524         if (!Util.isNull(requestSqlFilterString)) {
1525            sqlFilterParams = DbFilterTag.getSqlFilterParams(request,
1526                  this.getTable().getId());
1527         }
1528
1529         // overrules other default declarations eventually done in XML
1530
// config;
1531
FieldValue[] overrulingOrder = initOverrulingOrder(request);
1532
1533         // III/1: first we must determinate the ORDER clause to apply to the
1534
// query
1535
// the order may be specified in the dbforms-config.xml file or in
1536
// the current JSP file.
1537
// tells us which definintion of field order (global or local) to
1538
// use
1539
FieldValue[] orderConstraint;
1540
1541         // if developer provided orderBy - Attribute in <db:dbform> - tag
1542
if ((overrulingOrder != null) && (overrulingOrder.length > 0)) {
1543            orderConstraint = overrulingOrder;
1544            logCat.info("using OverrulingOrder (dbform tag attribute)");
1545         }
1546         // if developer provided orderBy - Attribute globally in
1547
// dbforms-config.xml - tag
1548
else {
1549            FieldValue[] tmpOrderConstraint = getTable().getDefaultOrder();
1550            orderConstraint = new FieldValue[tmpOrderConstraint.length];
1551
1552            // cloning is necessary to keep things thread-safe!
1553
// (we manipulate some fields in this structure.)
1554
for (int i = 0; i < tmpOrderConstraint.length; i++) {
1555               orderConstraint[i] = (FieldValue) tmpOrderConstraint[i].clone();
1556            }
1557
1558            logCat.info("using DefaultOrder (from config file)");
1559         }
1560
1561         // an orderBY - clause is a MUST. we can't query well without it.
1562
if (orderConstraint == null) {
1563            throw new IllegalArgumentException JavaDoc(
1564               "OrderBy-Clause must be specified either in table-element in config.xml or in dbform-tag on jsp view");
1565         }
1566
1567         FieldValue[] filterFieldValues = null;
1568
1569         if (!Util.isNull(filter)) {
1570            filterFieldValues = getTable().getFilterFieldArray(filter, locale);
1571         }
1572
1573         FieldValue[] mergedFieldValues = null;
1574
1575         if (childFieldValues == null) {
1576            mergedFieldValues = filterFieldValues;
1577         } else if (filterFieldValues == null) {
1578            mergedFieldValues = childFieldValues;
1579         } else {
1580            mergedFieldValues = new FieldValue[childFieldValues.length
1581               + filterFieldValues.length];
1582            System.arraycopy(childFieldValues, 0, mergedFieldValues, 0,
1583               childFieldValues.length);
1584            System.arraycopy(filterFieldValues, 0, mergedFieldValues,
1585               childFieldValues.length, filterFieldValues.length);
1586         }
1587
1588         // if we just habe a search request we do not need any other
1589
// constraints
1590
FieldValue[] searchFieldValues = initSearchFieldValues();
1591
1592         if (searchFieldValues != null) {
1593            mergedFieldValues = searchFieldValues;
1594         }
1595
1596         // III/2:
1597
// is there a POSITION we are supposed to navigate to?
1598
// positions are key values: for example "2", oder "2~454"
1599
//String position =
1600
// pageContext.getRequest().getParameter("pos_"+tableId);
1601
String JavaDoc firstPosition = Util.decode(ParseUtil.getParameter(request,
1602                  "firstpos_" + tableId),
1603               pageContext.getRequest().getCharacterEncoding());
1604         String JavaDoc lastPosition = Util.decode(ParseUtil.getParameter(request,
1605                  "lastpos_" + tableId),
1606               pageContext.getRequest().getCharacterEncoding());
1607
1608         if (firstPosition == null) {
1609            firstPosition = lastPosition;
1610         }
1611
1612         if (lastPosition == null) {
1613            lastPosition = firstPosition;
1614         }
1615
1616         // if we are in a subform we must check if the fieldvalue-list
1617
// provided in the
1618
// position strings is valid in the current state;
1619
// it might be invalid if the position of the parent form has been
1620
// changed (by a navigation event)
1621
// (=> the position-strings of childforms arent valid anymore)
1622
if ((childFieldValues != null) && (firstPosition != null)) {
1623            if (!checkLinkage(childFieldValues, firstPosition)) {
1624               // checking one of the 2 strings is sufficient
1625
// the position info is out of date. we dont use it.
1626
firstPosition = null;
1627               lastPosition = null;
1628            }
1629         }
1630
1631         logCat.info("firstposition " + firstPosition);
1632         logCat.info("lastPosition " + lastPosition);
1633
1634         /*
1635          * in the code above we examined lots of information which
1636          * determinates _which_ resultset gets retrieved and the way this
1637          * operation will be done.
1638          *
1639          * which are the "parameters" we have (eventually!) retrieved
1640          * ============================================================
1641          * ) WebEvent Object in request: if the jsp containing this tag was
1642          * invoked by the controller, then there is a Event which has been
1643          * processed (DatebasEvents) or which waits to be processed
1644          * (NavigationEvents, including GotoEvent)
1645          * ) firstPos, lastPos: Strings containing key-fieldValues and
1646          * indicating a line to go to if we have no other information. this
1647          * may happen if a subform gets navigated. the parentForm is not
1648          * involved in the operation but must be able to "navigate" to its
1649          * new old position. [#checkme: risk of wrong interpreation if jsp
1650          * calls jsp - compare source tags?]
1651          * ) mergedFieldValues: this is a cumulation of all rules which
1652          * restrict the result set in any way. it is build of
1653          * - childFieldValues: restricting a set in a subform that all
1654          * "childFields" in the resultset match their respective
1655          * "parentFields" in main form. (for instance if customerID == 100,
1656          * we only want to select orders from orders-table involving
1657          * customerID 100)
1658          * - filterFieldValues: if a filter is applied to the resultset we
1659          * always need to select the _filtered_ resultset
1660          * - searchFieldValues: if a search is performed we just want to
1661          * show fields belonging to the search result (naturally ;=)
1662          * ) orderConstraint: this is a cumulation of rules for ordering
1663          * (sorting) and restricting fields.
1664          *
1665          * one part of it is built either from a) orderBy - clause of dbform
1666          * element b) orderbY - definition in xml config (XPath:
1667          * dbform-config/table/field) this part tells dbforms which
1668          * orderby-clause to create
1669          *
1670          * but if we combine this "order constraint" with actual values (the
1671          * keys of a row, for example through "firstPos") then we can build
1672          * very powerful queries allowing us to select exectly what we need.
1673          * the order plays an important role in this game, because the
1674          * "order constraint" serves us as tool to make decisions if a row
1675          * has to be BEFORE or AFTER an other. (compare the rather complex
1676          * methods FieldValue.getWhereAfterClause(),
1677          * FieldValue.populateWhereAfterClause() and
1678          * FieldValue.fillWithValues() which are doing most of that stuff
1679          * describe above)
1680          *
1681          * ) count: this is a property of DbFormTag. Its relevance is that
1682          * certain operations need to be performed differently if count==0,
1683          * which means the form is an "endless form".
1684          */

1685         // III/3: fetching data (compare description above)
1686
// this code is still expermintal, pre alpha! We need to put this
1687
// logic into
1688
// etter (more readable, maintainable) code (evt. own method or
1689
// class)!
1690
// is there a NAVIGATION event (like "nav to first row" or "nav to
1691
// previous row", or "nav back 4 rows"?
1692
// if so...
1693
webEvent = (WebEvent) request.getAttribute("webEvent");
1694
1695         // set actual request to webEvent. Otherwise webEvent will not
1696
// reflect current requestURI!
1697
if (webEvent != null) {
1698            webEvent.setRequest(request);
1699         }
1700
1701         // if there comes no web event from controller,
1702
// then create a new NAVIGATION event;
1703
//
1704
// # 2002.11.xx-fossato added an event factory
1705
// # 20030320-HKK: Rewrite to use navEvent only
1706
// 2004-06-14 moretti: local event take precedence over NOOP
1707
if (((webEvent == null)
1708                  || webEvent instanceof org.dbforms.event.NoopEvent)
1709                  && (getLocalWebEvent() != null)) {
1710            webEvent = navEventFactory.createEvent(localWebEvent, request,
1711                  getConfig(), getTable());
1712
1713            // Setted with localWebEvent attribute.
1714
if (webEvent != null) {
1715               request.setAttribute("webEvent", webEvent);
1716            }
1717         }
1718
1719         // will be used to cast the webEvent to a navigation event;
1720
NavigationEvent navEvent = null;
1721
1722         //
1723
// 1. possibility: webEvent is a navigation event ?
1724
//
1725
if ((webEvent != null) && webEvent instanceof NavigationEvent) {
1726            navEvent = (NavigationEvent) webEvent;
1727
1728            if ((navEvent.getTable() == null)
1729                     || (navEvent.getTable().getId() != tableId)) {
1730               // navigation event is not for this table,
1731
// then just navigate to a position (if it exists) or just
1732
// select all data
1733
// (if no pos or if endless form).
1734
// best way to do this is to delete navEvent. Then a new
1735
// event will be created!
1736
navEvent = null;
1737            }
1738         }
1739
1740         //
1741
// 2. possibility: webEvent is a goto event ?
1742
//
1743
if (navEvent == null) {
1744            // we need to parse request using the given goto prefix
1745
if (!Util.isNull(gotoPrefix)) {
1746               logCat.info(" NAV GOTO ");
1747
1748               Vector v = ParseUtil.getParametersStartingWith(request,
1749                     gotoPrefix);
1750               gotoHt = new Hashtable JavaDoc();
1751
1752               for (int i = 0; i < v.size(); i++) {
1753                  String JavaDoc paramName = (String JavaDoc) v.elementAt(i);
1754                  String JavaDoc fieldName = paramName.substring(gotoPrefix.length());
1755                  logCat.debug("fieldName=" + fieldName);
1756
1757                  String JavaDoc fieldValue = ParseUtil.getParameter(request, paramName);
1758                  logCat.debug("fieldValue=" + fieldValue);
1759
1760                  if ((fieldName != null) && (fieldValue != null)) {
1761                     gotoHt.put(fieldName, fieldValue);
1762                  }
1763               }
1764            }
1765
1766            // try to create a new GOTO event
1767
if ((gotoHt != null) && (gotoHt.size() > 0)) {
1768               String JavaDoc positionString = getTable().getPositionString(gotoHt);
1769               navEvent = navEventFactory.createGotoEvent(getTable(), request,
1770                     getConfig(), positionString);
1771            }
1772         }
1773
1774         //
1775
// 3. a) error in insert event ?
1776
// b) create a GOTO event using a whereClause (free form select)
1777
// c) create a GOTO event using.. another constructor ;^)
1778
//
1779
if (navEvent == null) {
1780            // philip grunikiewicz
1781
// 2003-12-16
1782
// Commented code to fix the following problem:
1783
// Insert invoked in sub-form, validation error, suppose to
1784
// re-populate all fields (parent and child)
1785
// Commented code changes all field names to INSERT type -
1786
// making repopulate impossible!
1787
// Henner.Kollmann@gmx.de
1788
// 2004-01-29
1789
// Just commenting out do not work - insert errors on single
1790
// forms are not displayed then!
1791
// Check if table of event and table of form matches should do
1792
// the work!
1793
Vector errors = (Vector) request.getAttribute("errors");
1794
1795            if ((webEvent != null)
1796                     && EventType.EVENT_DATABASE_INSERT.equals(
1797                        webEvent.getType()) && (errors != null)
1798                     && (errors.size() > 0)
1799                     && (webEvent.getTable().getId() == getTable().getId())) {
1800               // error in insert event, nothing to do!
1801
navEvent = null;
1802               resultSetVector = null;
1803               setFooterReached(true);
1804            } else if (!Util.isNull(getWhereClause())) {
1805               // We should do a free form select
1806
navEvent = navEventFactory.createGotoEvent(getTable(), request,
1807                     getConfig(), whereClause, getTableList());
1808            } else {
1809               String JavaDoc myPosition = (count == 0) ? null : firstPosition;
1810
1811               if ((webEvent != null)
1812                        // && (webEvent instanceof
1813
// org.dbforms.event.DatabaseEvent)
1814
&& (webEvent instanceof org.dbforms.event.NoopEvent)) {
1815                  myPosition = null;
1816               }
1817
1818               navEvent = navEventFactory.createGotoEvent(getTable(), request,
1819                     getConfig(), myPosition);
1820            }
1821         }
1822
1823         // Now we have a NAVIGATION event to process
1824
logCat.info(" NAV/I ");
1825
1826         if (navEvent != null) {
1827            logCat.info("about to process nav event:"
1828               + navEvent.getClass().getName());
1829            resultSetVector = navEvent.processEvent(mergedFieldValues,
1830                  orderConstraint, sqlFilterString, sqlFilterParams, count,
1831                  firstPosition, lastPosition, interceptorData);
1832
1833            if (ResultSetVector.isNull(resultSetVector)) {
1834               setFooterReached(true);
1835            }
1836
1837            orderFields = new FieldValues(orderConstraint);
1838         }
1839
1840         // *** DONE! ***
1841
// We have now the underlying data, and this data is accessible to
1842
// all sub-elements
1843
// (labels, textFields, etc. of this form
1844
//
1845
// *************************************************************
1846
// Part IV - Again, some WebEvent infrastructural stuff:
1847
// write out data indicating the position we have
1848
// navigated to withing the rowset
1849
// *************************************************************
1850
// we process interceptor again (post-select)
1851
// #checkme: is the overhead of a POST_SELECT interceptor necessary
1852
// or a luxury? => use cases!
1853
if ((getTable() != null) && getTable().hasInterceptors()) {
1854            // process the interceptors associated to this table
1855
try {
1856               interceptorData.setAttribute(DbEventInterceptorData.RESULTSET,
1857                  resultSetVector);
1858               getTable().processInterceptors(DbEventInterceptor.POST_SELECT,
1859                  interceptorData);
1860            } catch (SQLException JavaDoc sqle) {
1861               // PG = 2001-12-04
1862
// No need to add extra comments, just re-throw the
1863
// exception
1864
// but first, better to log it !
1865
SqlUtil.logSqlException(sqle);
1866               throw sqle;
1867            }
1868         }
1869
1870         // End of interceptor processing
1871
// determinate new position-strings (== value of the first and the
1872
// last row of the current view)
1873
if (!ResultSetVector.isNull(resultSetVector)) {
1874            resultSetVector.moveFirst();
1875            firstPosition = getTable().getPositionString(resultSetVector);
1876            resultSetVector.moveLast();
1877            lastPosition = getTable().getPositionString(resultSetVector);
1878            resultSetVector.moveFirst();
1879         }
1880
1881         if (!footerReached) {
1882            // if not in insert mode
1883
if (firstPosition != null) {
1884               tagBuf.append("<input type=\"hidden\" name=\"firstpos_"
1885                  + tableId + "\" value=\""
1886                  + Util.encode(firstPosition,
1887                     pageContext.getRequest().getCharacterEncoding()) + "\"/>");
1888            }
1889
1890            if (lastPosition != null) {
1891               tagBuf.append("<input type=\"hidden\" name=\"lastpos_" + tableId
1892                  + "\" value=\""
1893                  + Util.encode(lastPosition,
1894                     pageContext.getRequest().getCharacterEncoding()) + "\"/>");
1895            }
1896         }
1897
1898         if (!isSubForm) {
1899            pageContext.setAttribute("dbforms", new Hashtable JavaDoc());
1900         }
1901
1902         Map JavaDoc dbforms = (Map JavaDoc) pageContext.getAttribute("dbforms");
1903         DbFormContext dbContext = new DbFormContext(getTable()
1904                                                        .getNamesHashtable(Constants.FIELDNAME_SEARCH),
1905               getTable().getNamesHashtable(Constants.FIELDNAME_SEARCHMODE),
1906               getTable().getNamesHashtable(Constants.FIELDNAME_SEARCHALGO),
1907               resultSetVector);
1908
1909         if (!ResultSetVector.isNull(resultSetVector)) {
1910            dbContext.setCurrentRow(resultSetVector.getCurrentRowAsMap());
1911            dbContext.setPosition(Util.encode(getTable().getPositionString(resultSetVector),
1912                  pageContext.getRequest().getCharacterEncoding()));
1913         }
1914
1915         dbforms.put(getName(), dbContext);
1916
1917         // construct TEI variables for access from JSP
1918
// # jp 27-06-2001: replacing "." by "_", so that SCHEMATA can be
1919
// used
1920
pageContext.setAttribute("searchFieldNames_"
1921            + tableName.replace('.', '_'),
1922            getTable().getNamesHashtable(Constants.FIELDNAME_SEARCH));
1923         pageContext.setAttribute("searchFieldModeNames_"
1924            + tableName.replace('.', '_'),
1925            getTable().getNamesHashtable(Constants.FIELDNAME_SEARCHMODE));
1926         pageContext.setAttribute("searchFieldAlgorithmNames_"
1927            + tableName.replace('.', '_'),
1928            getTable().getNamesHashtable(Constants.FIELDNAME_SEARCHALGO));
1929
1930         // #fixme:
1931
// this is a weired crazy workaround [this code is also used in
1932
// DbBodyTag!!]
1933
// why?
1934
// #fixme: explaination! -> initBody, spec, jsp container
1935
// synchronizing variables, etc.
1936
if (!ResultSetVector.isNull(resultSetVector)) {
1937            pageContext.setAttribute("rsv_" + tableName.replace('.', '_'),
1938               resultSetVector);
1939            pageContext.setAttribute("currentRow_"
1940               + tableName.replace('.', '_'),
1941               resultSetVector.getCurrentRowAsMap());
1942            pageContext.setAttribute("position_" + tableName.replace('.', '_'),
1943               Util.encode(getTable().getPositionString(resultSetVector),
1944                  pageContext.getRequest().getCharacterEncoding()));
1945         }
1946
1947         out.println(tagBuf.toString());
1948         SqlUtil.closeConnection(con);
1949      } catch (IOException JavaDoc e) {
1950         logCat.error("::doStartTag - IOException", e);
1951
1952         return SKIP_BODY;
1953      } catch (SQLException JavaDoc ne) {
1954         SqlUtil.logSqlException(ne);
1955
1956         return SKIP_BODY;
1957      }
1958
1959      return EVAL_BODY_BUFFERED;
1960   }
1961
1962
1963   /**
1964    * Check if the input name of the JavaScript function exists.
1965    *
1966    * @param jsFctName the name of the JS function
1967    *
1968    * @return true if the function exists, false otherwise
1969    */

1970   public boolean existJavascriptFunction(String JavaDoc jsFctName) {
1971      return javascriptDistinctFunctions.containsKey(jsFctName);
1972   }
1973
1974
1975   /**
1976    * Gets the captionResource attribute of the DbFormTag object
1977    *
1978    * @return The captionResource value
1979    */

1980   public boolean hasCaptionResourceSet() {
1981      return Util.getTrue(captionResource);
1982   }
1983
1984
1985   /**
1986    * Gets the javascriptFieldsArray attribute of the DbFormTag object
1987    *
1988    * @return The javascriptFieldsArray value
1989    */

1990   public boolean hasJavascriptFieldsArraySet() {
1991      return Util.getTrue(javascriptFieldsArray);
1992   }
1993
1994
1995   /**
1996    * Gets the javascriptValidation attribute of the DbFormTag object
1997    *
1998    * @return The javascriptValidation value
1999    */

2000   public boolean hasJavascriptValidationSet() {
2001      return Util.getTrue(javascriptValidation);
2002   }
2003
2004
2005   /**
2006    * Description of the Method
2007    *
2008    * @return Description of the Return Value
2009    */

2010   public boolean hasMultipartSet() {
2011      return Util.getTrue(multipart);
2012   }
2013
2014
2015   /**
2016    * Gets the readOnly attribute of the DbFormTag object
2017    *
2018    * @return The readOnly value
2019    */

2020   public boolean hasReadOnlySet() {
2021      return Util.getTrue(readOnly);
2022   }
2023
2024
2025   /**
2026    * Get the redisplayFieldsOnError attribute. <br>
2027    * author: philip grunikiewicz<br>
2028    * creation date: (2001-05-31 13:11:00) <br>
2029    *
2030    * @return the redisplayFieldsOnError
2031    */

2032   public boolean hasRedisplayFieldsOnErrorSet() {
2033      return Util.getTrue(redisplayFieldsOnError);
2034   }
2035
2036
2037   /**
2038    * DOCUMENT ME!
2039    *
2040    * @return DOCUMENT ME!
2041    */

2042   public String JavaDoc produceLinkedTags() {
2043      StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
2044
2045      // childFieldValues may be null, if we have
2046
// a free form select using attribute whereClause
2047
if (childFieldValues != null) {
2048         for (int i = 0; i < childFieldValues.length; i++) {
2049            if (childFieldValues[i].getRenderHiddenHtmlTag()) {
2050               TextFormatterUtil formatter = new TextFormatterUtil(childFieldValues[i]
2051                     .getField(), getLocale(), null,
2052                     childFieldValues[i].getFieldValueAsObject());
2053               buf.append("<input type=\"hidden\" name=\"");
2054               buf.append(formatter.getFormFieldName(this));
2055               buf.append("\" value=\"");
2056               buf.append(formatter.getFormattedFieldValue());
2057               buf.append("\" />");
2058               buf.append(formatter.renderPatternHtmlInputField());
2059            }
2060         }
2061      }
2062
2063      return buf.toString();
2064   }
2065
2066
2067   /**
2068    * This method gets called by input-tags like "DbTextFieldTag" and others.
2069    * they signalize that _they_ will generate the tag for the controller, not
2070    * this form. <br>
2071    * see produceLinkedTags(). <br>
2072    * This method is only used if this class is instantiated as sub-form (==
2073    * embedded in another form's body tag)
2074    *
2075    * @param f the Field object
2076    */

2077   public void strikeOut(Field f) {
2078      // childFieldValues may be null, if we have
2079
// a free form select using attribute whereClause
2080
if (childFieldValues != null) {
2081         for (int i = 0; i < childFieldValues.length; i++) {
2082            if ((f == childFieldValues[i].getField())
2083                     && childFieldValues[i].getRenderHiddenHtmlTag()) {
2084               childFieldValues[i].setRenderHiddenHtmlTag(false);
2085               logCat.info("stroke out field:" + f.getName());
2086
2087               return;
2088            }
2089         }
2090      }
2091   }
2092
2093
2094   /**
2095    * Update the position path.
2096    */

2097
2098   /* eg: "5" + "@" + "root", "5" + "@" + "123@35@root" */
2099   public void updatePositionPath() {
2100      StringBuffer JavaDoc positionPathBuf = new StringBuffer JavaDoc();
2101      positionPathBuf.append(this.currentCount);
2102      positionPathBuf.append("@");
2103      positionPathBuf.append(this.positionPathCore);
2104      this.positionPath = positionPathBuf.toString();
2105   }
2106
2107
2108   /**
2109    * DOCUMENT ME!
2110    *
2111    * @param fields DOCUMENT ME!
2112    */

2113   private void addFieldNames(Hashtable JavaDoc fields) {
2114      if (fieldNames == null) {
2115         fieldNames = new Hashtable JavaDoc();
2116      }
2117
2118      fieldNames.putAll(fields);
2119   }
2120
2121
2122   private void appendSource(HttpServletRequest JavaDoc request, StringBuffer JavaDoc tagBuf) {
2123      tagBuf.append("<input type=\"hidden\" name=\"source\" value=\"");
2124
2125      // J.Peer 03-19-2004: in template driven sites, we may need another
2126
// way of retrieving the source page, because getRequestURI may deliver
2127
// the template name and NOT the actual JSP...
2128
// to cicumvent the problem, the applicatoin may set a request attribute
2129
// "dbforms.source" for each templated page requested
2130
String JavaDoc reqSource = (String JavaDoc) request.getAttribute("dbforms.source");
2131
2132      // if not set, everything works as usual
2133
if (reqSource == null) {
2134         tagBuf.append(request.getRequestURI());
2135      }
2136      // if set, we use this value instead of getRequestURI()
2137
else {
2138         tagBuf.append(reqSource);
2139      }
2140
2141      if (request.getQueryString() != null) {
2142         tagBuf.append("?").append(request.getQueryString());
2143      }
2144
2145      tagBuf.append("\"/>");
2146   }
2147
2148
2149   /**
2150    * if we are in a subform we must check if the fieldvalue-list provided in
2151    * the position strings is valid in the current state it might be invalid
2152    * if the position of the parent form has been changed (by a navigation
2153    * event) (=> the position-strings of childforms arent valid anymore)
2154    *
2155    * @param childFieldValues Description of the Parameter
2156    * @param aPosition Description of the Parameter
2157    *
2158    * @return Description of the Return Value
2159    *
2160    * @throws IllegalArgumentException DOCUMENT ME!
2161    */

2162   private boolean checkLinkage(FieldValue[] achildFieldValues, String JavaDoc aPosition) {
2163      // at first build a hashtable of the provided values
2164
// 2003-03-29 HKK: Change from Hashtable to FieldValueTable
2165
FieldValues ht = getTable().getFieldValues(aPosition);
2166
2167      for (int i = 0; i < achildFieldValues.length; i++) {
2168         String JavaDoc actualValue = achildFieldValues[i].getFieldValue();
2169         logCat.debug("actualValue=" + actualValue);
2170
2171         Field f = achildFieldValues[i].getField();
2172         logCat.debug("f.getName=" + f.getName());
2173         logCat.debug("f.getId=" + f.getId());
2174
2175         FieldValue aFieldValue = ht.get(f.getName());
2176
2177         if (aFieldValue == null) {
2178            throw new IllegalArgumentException JavaDoc("ERROR: Make sure that field "
2179               + f.getName() + " is a KEY of the table " + getTable().getName()
2180               + "! Otherwise you can not use it as PARENT/CHILD LINK argument!");
2181         }
2182
2183         String JavaDoc valueInPos = aFieldValue.getFieldValue();
2184
2185         logCat.info("comparing " + actualValue + " TO " + valueInPos);
2186
2187         if (!actualValue.trim().equals(valueInPos.trim())) {
2188            return false;
2189         }
2190      }
2191
2192      return true;
2193   }
2194
2195
2196   /**
2197    * Generate Javascript Array of Original field name et DbForm generated name
2198    * Generate Array for each field name. Ex: dbFormFields
2199    *
2200    * @return Description of the Return Value
2201    */

2202   private StringBuffer JavaDoc generateJavascriptFieldsArray() {
2203      // This section looks hard to understand, but to avoid using
2204
// synchronized object like keySet ... don't want to alter
2205
// childFieldNames hashtable.
2206
// We use different step of enumeration.
2207
StringBuffer JavaDoc result = new StringBuffer JavaDoc();
2208      String JavaDoc key = null;
2209      String JavaDoc val = null;
2210      String JavaDoc values = "";
2211
2212      Hashtable JavaDoc fields = new Hashtable JavaDoc();
2213      Enumeration JavaDoc e = childFieldNames.keys();
2214
2215      //
2216
// Loop in each keys "f_0_0@root_2" and create hashtable of unique
2217
// fieldnames
2218
//
2219
while (e.hasMoreElements()) {
2220         key = (String JavaDoc) e.nextElement();
2221         val = (String JavaDoc) childFieldNames.get(key);
2222         values = "";
2223
2224         if (fields.containsKey(val)) {
2225            values = (String JavaDoc) fields.get(val);
2226         }
2227
2228         fields.put(val, values + ";" + key);
2229      }
2230
2231      if (isSubForm()) {
2232         parentForm.addFieldNames(fields);
2233      } else {
2234         if (fieldNames != null) {
2235            fields.putAll(fieldNames);
2236         }
2237
2238         result.append("<SCRIPT language=\"javascript\">\n");
2239         result.append("<!-- \n\n");
2240         result.append(" var dbFormFields = new Array();\n");
2241         e = fields.keys();
2242
2243         //
2244
// Loop for each fieldname and generate text for javascript Array
2245
//
2246
// Ex: dbFormFields["DESCRIPTIONDEMANDE"] = new
2247
// Array("f_0_0@root_4", "f_0_1@root_4", "f_0_insroot_4");
2248
//
2249
while (e.hasMoreElements()) {
2250            key = (String JavaDoc) e.nextElement();
2251            val = (String JavaDoc) fields.get(key);
2252            result.append(" dbFormFields[\"").append(key).append("\"] = new Array(");
2253
2254            // Sort the delimited string and return an ArrayList of it.
2255
ArrayList JavaDoc arrValues = sortFields(val);
2256
2257            if (arrValues.size() == 1) {
2258               result.append("\"").append((String JavaDoc) arrValues.get(0)).append("\"");
2259            } else {
2260               for (int i = 0; i <= (arrValues.size() - 1); i++) {
2261                  result.append("\"").append((String JavaDoc) arrValues.get(i)).append("\"");
2262
2263                  if (i != (arrValues.size() - 1)) {
2264                     result.append(", ");
2265                  }
2266               }
2267            }
2268
2269            result.append(");\n");
2270         }
2271
2272         result.append("\n function getDbFormFieldName(name){ \n");
2273         result.append(" return getDbFormFieldName(name,null); \n");
2274         result.append(" }\n\n");
2275         result.append("\n function getDbFormFieldName(name,pos){ \n");
2276         result.append(" var result = dbFormFields[name]; \n");
2277         result.append(" if(pos==null) return result[result.length-1]; \n");
2278         result.append(" return result[pos]; \n");
2279         result.append(" }\n");
2280         result.append("--></SCRIPT> \n");
2281      }
2282
2283      return result;
2284   }
2285
2286
2287   /**
2288    * Generate the Javascript of Validation fields
2289    *
2290    * @return Description of the Return Value
2291    */

2292   private StringBuffer JavaDoc generateJavascriptValidation() {
2293      if (isSubForm()) {
2294         parentForm.addValidationForm(getFormValidatorName(), childFieldNames);
2295
2296         return new StringBuffer JavaDoc();
2297      } else {
2298         ValidatorResources vr = (ValidatorResources) pageContext.getServletContext()
2299                                                                 .getAttribute(ValidatorConstants.VALIDATOR);
2300         DbFormsErrors errors = (DbFormsErrors) pageContext.getServletContext()
2301                                                                .getAttribute(DbFormsErrors.ERRORS);
2302         addValidationForm(getFormValidatorName(), childFieldNames);
2303
2304         return DbFormsValidatorUtil.getJavascript(validationForms,
2305            MessageResources.getLocale(
2306               (HttpServletRequest JavaDoc) pageContext.getRequest()),
2307            validationFields, vr, getJavascriptValidationSrcFile(), errors);
2308      }
2309   }
2310
2311
2312   /**
2313    * Initialize child values
2314    */

2315   private void initChildFieldValues() {
2316      // if parent form has no data, we can not render a subform!
2317
if (ResultSetVector.isNull(parentForm.getResultSetVector())) {
2318         childFieldValues = null;
2319
2320         // childFieldValues remains null
2321
return;
2322      }
2323
2324      String JavaDoc aPosition = parentForm.getTable().getPositionString(parentForm
2325            .getResultSetVector());
2326
2327      if (Util.isNull(aPosition)) {
2328         childFieldValues = null;
2329
2330         // childFieldValues remains null
2331
return;
2332      }
2333
2334      childFieldValues = getTable()
2335                            .mapChildFieldValues(parentForm.getTable(),
2336            parentField, childField, aPosition).toArray();
2337   }
2338
2339
2340   //------------------------ business, helper & utility methods
2341
// --------------------------------
2342

2343   /**
2344    * Initialise datastructures containing informations about how table should
2345    * be ordered. The information is specified in the JSP this tags lives in.
2346    * This declaration OVERRULES other default declarations eventually done in
2347    * XML config! (compara Table.java !)
2348    *
2349    * @param request the request object
2350    *
2351    * @return DOCUMENT ME!
2352    */

2353   private FieldValue[] initOverrulingOrder(HttpServletRequest JavaDoc request) {
2354      // if page A links to page B (via a gotoButton, for instance) then we do
2355
// not
2356
// want A's order constraints get applied to B
2357
if (request != null) {
2358         String JavaDoc refSource = request.getRequestURI();
2359
2360         if (request.getQueryString() != null) {
2361            refSource += ("?" + request.getQueryString());
2362         }
2363
2364         String JavaDoc sourceTag = ParseUtil.getParameter(request, "source");
2365         logCat.info("!comparing page " + refSource + " TO " + sourceTag);
2366
2367         //if (!Util.isNull(sourceTag) && !refSource.equals(sourceTag)) {
2368
// request = null;
2369
//}
2370
}
2371
2372      logCat.debug("orderBy=" + orderBy);
2373
2374      // if we have neither an orderby clause nor a request we may use then we
2375
// cant create orderconstraint
2376
if ((orderBy == null) && (request == null)) {
2377         return null;
2378      }
2379
2380      // otherwise we can:
2381
FieldValue[] overrulingOrder = getTable().createOrderFieldValues(orderBy,
2382            request, false);
2383      overrulingOrderFields = new Vector();
2384
2385      if (overrulingOrder != null) {
2386         for (int i = 0; i < overrulingOrder.length; i++)
2387            overrulingOrderFields.addElement(overrulingOrder[i].getField());
2388      }
2389
2390      return overrulingOrder;
2391   }
2392
2393
2394   /**
2395    * Initialize the value of the search fields.
2396    *
2397    * @return the field values array
2398    *
2399    * @todo Whats when there is more then one search field whith the same name?
2400    * Maybe we should parse all of them ....
2401    */

2402   private FieldValue[] initSearchFieldValues() {
2403      FieldValue[] fieldValues;
2404      HttpServletRequest JavaDoc request = (HttpServletRequest JavaDoc) pageContext
2405         .getRequest();
2406      Vector searchFieldNames = ParseUtil.getParametersStartingWith(request,
2407            Constants.FIELDNAME_SEARCH);
2408
2409      if ((searchFieldNames == null) || (searchFieldNames.size() == 0)) {
2410         return null;
2411      }
2412
2413      Vector mode_and = new Vector();
2414      Vector mode_or = new Vector();
2415
2416      for (int i = 0; i < searchFieldNames.size(); i++) {
2417         String JavaDoc searchFieldName = (String JavaDoc) searchFieldNames.elementAt(i);
2418         String JavaDoc aSearchFieldPattern = ParseUtil.getParameter(request,
2419               Constants.FIELDNAME_PATTERNTAG + searchFieldName);
2420         String JavaDoc aSearchFieldValue = ParseUtil.getParameter(request,
2421               searchFieldName);
2422         aSearchFieldValue = aSearchFieldValue.trim();
2423
2424         // ie. search_1_12 is mapped to "john"
2425
if (!Util.isNull(aSearchFieldValue)) {
2426            int firstUnderscore = searchFieldName.indexOf('_');
2427            int secondUnderscore = searchFieldName.indexOf('_',
2428                  firstUnderscore + 1);
2429            int ptableId = Integer.parseInt(searchFieldName.substring(firstUnderscore
2430                     + 1, secondUnderscore));
2431            int fieldId = Integer.parseInt(searchFieldName.substring(secondUnderscore
2432                     + 1));
2433
2434            Table ptable = getConfig().getTable(ptableId);
2435            Field f = ptable.getField(fieldId);
2436
2437            if (f != null) {
2438               String JavaDoc aSearchMode = ParseUtil.getParameter(request,
2439                     f.getSearchModeName());
2440               int mode = ("or".equals(aSearchMode))
2441                  ? Constants.SEARCHMODE_OR : Constants.SEARCHMODE_AND;
2442               String JavaDoc aSearchAlgorithm = ParseUtil.getParameter(request,
2443                     f.getSearchAlgoName());
2444
2445               if (ptable.getId() != getTable().getId()) {
2446                  // Table from request is different to table of form
2447
// Try to find field in the current table
2448
Field fTest = f;
2449                  f = getTable().getFieldByName(fTest.getName());
2450
2451                  if (f != null) {
2452                     // There is a field with the same name - now check fieldtype!
2453
if (!fTest.getFieldType().equals(f.getFieldType())) {
2454                        f = null;
2455                     } else {
2456                        // put the value into the request so that the SearchTag will find
2457
// it there with the changed value!
2458
request.setAttribute(f.getSearchFieldName(), aSearchFieldValue);
2459                     }
2460                  }
2461               }
2462
2463               if (f != null) {
2464                  // Check for operator
2465
int algorithm = Constants.SEARCH_ALGO_SHARP;
2466                  int operator = Constants.FILTER_EQUAL;
2467
2468                  if (!Util.isNull(aSearchAlgorithm)) {
2469                     if (aSearchAlgorithm.startsWith("sharpLT")) {
2470                        operator = Constants.FILTER_SMALLER_THEN;
2471                     } else if (aSearchAlgorithm.startsWith("sharpLE")) {
2472                        operator = Constants.FILTER_SMALLER_THEN_EQUAL;
2473                     } else if (aSearchAlgorithm.startsWith("sharpGT")) {
2474                        operator = Constants.FILTER_GREATER_THEN;
2475                     } else if (aSearchAlgorithm.startsWith("sharpGE")) {
2476                        operator = Constants.FILTER_GREATER_THEN_EQUAL;
2477                     } else if (aSearchAlgorithm.startsWith("sharpNE")) {
2478                        operator = Constants.FILTER_NOT_EQUAL;
2479                     } else if (aSearchAlgorithm.startsWith("sharpNULL")) {
2480                        operator = Constants.FILTER_NULL;
2481                     } else if (aSearchAlgorithm.startsWith("sharpNOTNULL")) {
2482                        operator = Constants.FILTER_NOT_NULL;
2483                     } else if (aSearchAlgorithm.startsWith("weakStartEnd")) {
2484                        algorithm = Constants.SEARCH_ALGO_WEAK_START_END;
2485                        operator = Constants.FILTER_LIKE;
2486                     } else if (aSearchAlgorithm.startsWith("weakStart")) {
2487                        algorithm = Constants.SEARCH_ALGO_WEAK_START;
2488                        operator = Constants.FILTER_LIKE;
2489                     } else if (aSearchAlgorithm.startsWith("weakEnd")) {
2490                        algorithm = Constants.SEARCH_ALGO_WEAK_END;
2491                        operator = Constants.FILTER_LIKE;
2492                     } else if (aSearchAlgorithm.startsWith("weak")) {
2493                        algorithm = Constants.SEARCH_ALGO_WEAK;
2494                        operator = Constants.FILTER_LIKE;
2495                     }
2496                  }
2497
2498                  if ((aSearchAlgorithm == null)
2499                           || (aSearchAlgorithm.toLowerCase().indexOf("extended") == -1)) {
2500                     // Extended not found, only append field
2501
FieldValue fv = FieldValue.createFieldValueForSearching(f,
2502                           aSearchFieldValue, getLocale(), operator, mode,
2503                           algorithm, false);
2504
2505                     if (!Util.isNull(aSearchFieldPattern)) {
2506                        fv.setPattern(aSearchFieldPattern);
2507                     }
2508
2509                     if (mode == Constants.SEARCHMODE_AND) {
2510                        mode_and.addElement(fv);
2511                     } else {
2512                        mode_or.addElement(fv);
2513                     }
2514                  } else if (aSearchFieldValue.indexOf("-") != -1) {
2515                     // is extended searching and delimiter found in
2516
// SearchFieldValue
2517
// create 2 searchfields
2518
algorithm = Constants.SEARCH_ALGO_EXTENDED;
2519
2520                     StringTokenizer JavaDoc st = new StringTokenizer JavaDoc(" "
2521                           + aSearchFieldValue + " ", "-");
2522                     int tokenCounter = 0;
2523
2524                     StringBuffer JavaDoc merkeDate = new StringBuffer JavaDoc();
2525                     StringBuffer JavaDoc merkeTime = new StringBuffer JavaDoc();
2526                     
2527                     while (st.hasMoreTokens()) {
2528                        aSearchFieldValue = st.nextToken().trim();
2529                        tokenCounter++;
2530
2531                        if (aSearchFieldValue.length() > 0) {
2532                           switch (tokenCounter) {
2533                              case 1:
2534                                 operator = Constants.FILTER_GREATER_THEN_EQUAL;
2535                                 TimeUtil.splitDate(aSearchFieldValue, merkeDate, merkeTime);
2536                                 break;
2537
2538                              case 2:
2539                                 operator = Constants.FILTER_SMALLER_THEN_EQUAL;
2540                                 StringBuffer JavaDoc mDate = new StringBuffer JavaDoc();
2541                                 StringBuffer JavaDoc mTime = new StringBuffer JavaDoc();
2542                                 TimeUtil.splitDate(aSearchFieldValue, mDate, mTime);
2543                                 if (mDate.length() == 0) {
2544                                    mDate.append(merkeDate);
2545                                 }
2546                                 mDate.append(" ");
2547                                 mDate.append(mTime);
2548                                 aSearchFieldValue = mDate.toString();
2549
2550                                 break;
2551
2552                              default:
2553                                 operator = -1;
2554
2555                                 break;
2556                           }
2557
2558                           if (operator != -1) {
2559                              FieldValue fv = FieldValue
2560                                 .createFieldValueForSearching(f,
2561                                    aSearchFieldValue, getLocale(), operator,
2562                                    mode, algorithm, false);
2563
2564                              if (!Util.isNull(aSearchFieldPattern)) {
2565                                 fv.setPattern(aSearchFieldPattern);
2566                              }
2567
2568                              if (mode == Constants.SEARCHMODE_AND) {
2569                                 mode_and.addElement(fv);
2570                              } else {
2571                                 mode_or.addElement(fv);
2572                              }
2573                           }
2574                        }
2575                     }
2576                  } else {
2577                     // parse special chars in SearchFieldValue
2578
int jump = 0;
2579
2580                     // Check for Not Equal
2581
if (aSearchFieldValue.startsWith("<>")) {
2582                        algorithm = Constants.SEARCH_ALGO_EXTENDED;
2583                        operator = Constants.FILTER_NOT_EQUAL;
2584                        jump = 2;
2585
2586                        // Check for not equal
2587
} else if (aSearchFieldValue.startsWith("!=")) {
2588                        // GreaterThenEqual found! - Store the operation for
2589
// use later on
2590
algorithm = Constants.SEARCH_ALGO_EXTENDED;
2591                        operator = Constants.FILTER_NOT_EQUAL;
2592                        jump = 2;
2593
2594                        // Check for GreaterThanEqual
2595
} else if (aSearchFieldValue.startsWith(">=")) {
2596                        // GreaterThenEqual found! - Store the operation for
2597
// use later on
2598
algorithm = Constants.SEARCH_ALGO_EXTENDED;
2599                        operator = Constants.FILTER_GREATER_THEN_EQUAL;
2600                        jump = 2;
2601
2602                        // Check for GreaterThan
2603
} else if (aSearchFieldValue.startsWith(">")) {
2604                        // GreaterThen found! - Store the operation for use
2605
// later on
2606
algorithm = Constants.SEARCH_ALGO_EXTENDED;
2607                        operator = Constants.FILTER_GREATER_THEN;
2608
2609                        // Check for SmallerThenEqual
2610
} else if (aSearchFieldValue.startsWith("<=")) {
2611                        // SmallerThenEqual found! - Store the operation for
2612
// use later on
2613
algorithm = Constants.SEARCH_ALGO_EXTENDED;
2614                        operator = Constants.FILTER_SMALLER_THEN_EQUAL;
2615                        jump = 2;
2616
2617                        // Check for SmallerThen
2618
} else if (aSearchFieldValue.startsWith("<")) {
2619                        // SmallerThen found! - Store the operation for use
2620
// later on
2621
algorithm = Constants.SEARCH_ALGO_EXTENDED;
2622                        operator = Constants.FILTER_SMALLER_THEN;
2623                        jump = 1;
2624
2625                        // Check for equal
2626
} else if (aSearchFieldValue.startsWith("=")) {
2627                        // Equal found! - Store the operator for use later
2628
// on
2629
algorithm = Constants.SEARCH_ALGO_EXTENDED;
2630                        operator = Constants.FILTER_EQUAL;
2631                        jump = 1;
2632                     } else if (aSearchFieldValue.startsWith("[NULL]")) {
2633                        algorithm = Constants.SEARCH_ALGO_EXTENDED;
2634                        operator = Constants.FILTER_NULL;
2635                        jump = 0;
2636                     } else if (aSearchFieldValue.startsWith("[!NULL]")) {
2637                        algorithm = Constants.SEARCH_ALGO_EXTENDED;
2638                        operator = Constants.FILTER_NOT_NULL;
2639                        jump = 0;
2640                     } else if (aSearchFieldValue.startsWith("[EMPTY]")) {
2641                        algorithm = Constants.SEARCH_ALGO_EXTENDED;
2642                        operator = Constants.FILTER_EMPTY;
2643                        jump = 0;
2644                     } else if (aSearchFieldValue.startsWith("[!EMPTY]")) {
2645                        algorithm = Constants.SEARCH_ALGO_EXTENDED;
2646                        operator = Constants.FILTER_NOT_EMPTY;
2647                        jump = 0;
2648                     }
2649
2650                     if (jump > 0) {
2651                        aSearchFieldValue = aSearchFieldValue.substring(jump)
2652                                                             .trim();
2653                     }
2654
2655                     Vector errors = (Vector) request.getAttribute("errors");
2656
2657                     if ((operator == Constants.FILTER_EQUAL) && (jump == 0)
2658                              && (f.getType() == FieldTypes.TIMESTAMP)) {
2659                        // found a single timestamp value. Extend it to
2660
// >value and <end of day of value
2661
operator = Constants.FILTER_GREATER_THEN_EQUAL;
2662
2663                        FieldValue fv = FieldValue.createFieldValueForSearching(f,
2664                              aSearchFieldValue, getLocale(), operator, mode,
2665                              algorithm, false);
2666
2667                        if (!Util.isNull(aSearchFieldPattern)) {
2668                           fv.setPattern(aSearchFieldPattern);
2669                        }
2670
2671                        Date JavaDoc d = (Date JavaDoc) fv.getFieldValueAsObject();
2672
2673                        if (d == null) {
2674                           errors.add(new Exception JavaDoc(
2675                                 MessageResourcesInternal.getMessage(
2676                                    "dbforms.error.filter.invalid.date",
2677                                    getLocale())));
2678                        } else {
2679                           if (mode == Constants.SEARCHMODE_AND) {
2680                              mode_and.addElement(fv);
2681                           } else {
2682                              mode_or.addElement(fv);
2683                           }
2684
2685                           operator = Constants.FILTER_SMALLER_THEN_EQUAL;
2686                           d = TimeUtil.findEndOfDay(d);
2687                           aSearchFieldValue = d.toString();
2688
2689                           fv = FieldValue.createFieldValueForSearching(f,
2690                                 aSearchFieldValue, getLocale(), operator,
2691                                 mode, algorithm, false);
2692
2693                           if (!Util.isNull(aSearchFieldPattern)) {
2694                              fv.setPattern(aSearchFieldPattern);
2695                           }
2696
2697                           if (mode == Constants.SEARCHMODE_AND) {
2698                              mode_and.addElement(fv);
2699                           } else {
2700                              mode_or.addElement(fv);
2701                           }
2702                        }
2703                     } else {
2704                        FieldValue fv = FieldValue.createFieldValueForSearching(f,
2705                              aSearchFieldValue, getLocale(), operator, mode,
2706                              algorithm, false);
2707
2708                        if (!Util.isNull(aSearchFieldPattern)) {
2709                           fv.setPattern(aSearchFieldPattern);
2710                        }
2711
2712                        Object JavaDoc obj = fv.getFieldValueAsObject();
2713
2714                        if (obj == null) {
2715                           errors.add(new Exception JavaDoc(
2716                                 MessageResourcesInternal.getMessage(
2717                                    "dbforms.error.filter.invalid", getLocale())));
2718                        } else {
2719                           if (mode == Constants.SEARCHMODE_AND) {
2720                              mode_and.addElement(fv);
2721                           } else {
2722                              mode_or.addElement(fv);
2723                           }
2724                        }
2725                     }
2726                  }
2727               }
2728            }
2729         }
2730      }
2731
2732      int andBagSize = mode_and.size();
2733      int orBagSize = mode_or.size();
2734      int criteriaFieldCount = andBagSize + orBagSize;
2735      logCat.info("criteriaFieldCount=" + criteriaFieldCount);
2736
2737      if (criteriaFieldCount == 0) {
2738         return null;
2739      }
2740
2741      // now we construct the fieldValues array
2742
// we ensure that the searchmodes are not mixed up
2743
fieldValues = new FieldValue[criteriaFieldCount];
2744
2745      int i = 0;
2746
2747      for (i = 0; i < andBagSize; i++) {
2748         fieldValues[i] = (FieldValue) mode_and.elementAt(i);
2749      }
2750
2751      for (int j = 0; j < orBagSize; j++) {
2752         fieldValues[j + i] = (FieldValue) mode_or.elementAt(j);
2753      }
2754
2755      return fieldValues;
2756   }
2757
2758
2759   /**
2760    * Use by generateJavascriptFieldsArray() to sort the order of field name.
2761    *
2762    * @param str Description of the Parameter
2763    *
2764    * @return Description of the Return Value
2765    */

2766   private ArrayList JavaDoc sortFields(String JavaDoc str) {
2767      /*
2768       * Sort delimited string of DbForms field, and return ArraList of this
2769       * result.
2770       *
2771       * Ex: "f_0_1@root_1;f_0_insroot_1;f_0_0@root_1;"
2772       *
2773       * result : "f_0_0@root_1" "f_0_1@root_1" "f_0_insroot_1;"
2774       */

2775      ArrayList JavaDoc arr = new ArrayList JavaDoc();
2776      String JavaDoc tmp = "";
2777      String JavaDoc tmp1 = null;
2778      String JavaDoc tmp2 = null;
2779      String JavaDoc insroot = null;
2780      int ident1 = 0;
2781      int ident2 = 0;
2782      StringTokenizer JavaDoc token = new StringTokenizer JavaDoc(str, ";");
2783
2784      while (token.hasMoreTokens()) {
2785         tmp = token.nextToken();
2786
2787         if (tmp.indexOf("@root") != -1) {
2788            arr.add(tmp);
2789         } else {
2790            insroot = tmp;
2791         }
2792      }
2793
2794      if (insroot != null) {
2795         arr.add(insroot);
2796      }
2797
2798      //String[] result = (String[]) arr.toArray(new String[arr.size()]);
2799
if (arr.size() == 1) {
2800         return arr;
2801      }
2802
2803      for (int i = 0; i <= (arr.size() - 2); i++) {
2804         tmp1 = (String JavaDoc) arr.get(i);
2805
2806         for (int j = i + 1; j <= (arr.size() - 1); j++) {
2807            tmp2 = (String JavaDoc) arr.get(j);
2808
2809            if ((tmp1.indexOf("@root") != -1) && (tmp2.indexOf("@root") != -1)) {
2810               try {
2811                  ident1 = Integer.parseInt(tmp1.substring(tmp1.indexOf(
2812                              "_", 2) + 1, tmp1.indexOf("@")));
2813                  ident2 = Integer.parseInt(tmp2.substring(tmp2.indexOf("_", 2)
2814                           + 1, tmp2.indexOf("@")));
2815               } catch (Exception JavaDoc e) {
2816                  ident1 = -1;
2817                  ident2 = -1;
2818               }
2819
2820               if (ident2 < ident1) {
2821                  arr.set(i, tmp2);
2822                  arr.set(j, tmp1);
2823                  tmp1 = tmp2;
2824               }
2825            }
2826         }
2827      }
2828
2829      return arr;
2830   }
2831}
2832
Popular Tags