1 /*
2 * $Header: /cvsroot/jdbforms/dbforms/src/org/dbforms/taglib/DbBodyTag.java,v 1.30 2006/01/13 13:38:50 hkollmann Exp $
3 * $Revision: 1.30 $
4 * $Date: 2006/01/13 13:38:50 $
5 *
6 * DbForms - a Rapid Application Development Framework
7 * Copyright (C) 2001 Joachim Peer <joepeer@excite.com>
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
13 *
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 */
23
24 package org.dbforms.taglib;
25
26 import org.dbforms.config.ResultSetVector;
27
28 import org.dbforms.util.Util;
29
30 import java.io.UnsupportedEncodingException;
31
32 import java.util.Map;
33
34 import javax.servlet.jsp.JspException;
35
36
37
38 /***
39 * <p>
40 * this tag renders a Body-tag. it is supposed to be nested within a DbFormTag.
41 * because this tag is nested within a DbFormTag it is invoked every time the
42 * parent dbFormTag gets evaluated, AND it gets rendered in every
43 * evalation-loop (if there exists data to be rendered)
44 * </p>
45 *
46 * @author Joachim Peer
47 */
48 public class DbBodyTag extends AbstractDbBaseHandlerTag
49 implements javax.servlet.jsp.tagext.TryCatchFinally {
50 private String allowNew = "true";
51
52 /***
53 * DOCUMENT ME!
54 *
55 * @param allowNew DOCUMENT ME!
56 */
57 public void setAllowNew(String allowNew) {
58 this.allowNew = allowNew;
59 }
60
61
62 /***
63 * DOCUMENT ME!
64 *
65 * @return DOCUMENT ME!
66 */
67 public String getAllowNew() {
68 return allowNew;
69 }
70
71
72 /***
73 * DOCUMENT ME!
74 *
75 * @return DOCUMENT ME!
76 *
77 * @throws JspException DOCUMENT ME!
78 */
79 public int doAfterBody() throws JspException {
80 DbFormTag myParent = getParentForm();
81
82 try {
83 // each rendering loop represents one row of data.
84 // for every row we need to print some data needed by the controller servlet in order to
85 // correctly dispatching and eventually modifying our data.
86 //
87 // now the key of the current dataset is printed out (always)
88 // this key will be used by actions such as delete or update.
89 if (myParent.getTable() != null) {
90 String curKeyString = myParent.getTable()
91 .getKeyPositionString(myParent
92 .getResultSetVector());
93
94 if (!Util.isNull(curKeyString)) {
95 curKeyString = Util.encode(curKeyString,
96 pageContext.getRequest().getCharacterEncoding());
97 myParent.appendToChildElementOutput("<input type=\"hidden\" name=\"k_"
98 + myParent.getTable().getId()
99 + "_"
100 + myParent.getPositionPath()
101 + "\" value=\""
102 + curKeyString + "\"/>");
103 }
104 }
105 } catch (UnsupportedEncodingException uee) {
106 throw new JspException(uee.toString());
107 }
108 // field values that have not been rendered by html tags but that is determinated by field
109 // mapping between main- and subform are rendered now:
110 if (myParent.isSubForm() && myParent.isFooterReached() && Util.getTrue(getAllowNew())) {
111 myParent.appendToChildElementOutput(myParent.produceLinkedTags()); // print hidden-fields for missing insert-fields we can determinated
112 }
113
114
115 return SKIP_BODY;
116 }
117
118
119 /***
120 * DOCUMENT ME!
121 *
122 * @return DOCUMENT ME!
123 *
124 * @throws JspException DOCUMENT ME!
125 */
126 public int doEndTag() throws JspException {
127 try {
128 if (bodyContent != null) {
129 bodyContent.writeOut(bodyContent.getEnclosingWriter());
130 bodyContent.clearBody();
131
132 // workaround for duplicate rows in JRun 3.1
133 }
134 } catch (java.io.IOException e) {
135 throw new JspException("IO Error: " + e.getMessage());
136 }
137
138 return EVAL_PAGE;
139 }
140
141
142 // by default this is "true" - if so, the body is rendered at least 1 time, even if there are no data rows in the table. this enables the user to insert a new data row. - to disable this feature, allowNew has to be set to "false"
143
144 /***
145 * DOCUMENT ME!
146 */
147 public void doFinally() {
148 allowNew = "true";
149 }
150
151
152 /***
153 * DOCUMENT ME!
154 *
155 * @return DOCUMENT ME!
156 */
157 public int doStartTag() throws javax.servlet.jsp.JspException {
158 DbFormTag myParent = getParentForm();
159 ResultSetVector rsv = myParent.getResultSetVector();
160 // the body may be rendered under the following circumstances:
161 // - resultSetVector > 0 && not footer reached => render a row
162 // - resultSetVector == 0 && allowNew==true => insert a new row
163 if (
164 (!ResultSetVector.isNull(rsv) && myParent.isFooterReached())
165 ||
166 (ResultSetVector.isNull(rsv) && Util.getFalse(allowNew))
167 ) {
168 return SKIP_BODY;
169 }
170
171 myParent.updatePositionPath();
172 // to enable access from jsp we provide a variable
173 // #fixme: we need a more convenient data access structure
174 //
175 // #fixme: this is a CRAZY WEIRED ODD SQUARE WORKAROUND
176 //
177
178 if (!ResultSetVector.isNull(rsv)) {
179 Map dbforms = (Map) pageContext.getAttribute("dbforms");
180
181 if (dbforms != null) {
182 DbFormContext dbContext = (DbFormContext) dbforms.get(myParent
183 .getName());
184 if (dbContext != null) {
185 dbContext.setCurrentRow(rsv.getCurrentRowAsMap());
186 try {
187 dbContext.setPosition(Util.encode(myParent.getTable().getPositionString(rsv),
188 pageContext.getRequest().getCharacterEncoding()));
189 } catch (Exception e) {
190 throw new JspException(e.getMessage());
191 }
192 }
193 }
194
195 if (!rsv.isLast()) {
196 rsv.moveNext(); // teleport us to future...
197
198 // This must be done because currentRow_xxx is reread from
199 // the pagecontext after(!) the body of the tag. This means
200 // that the current body contains the currentRow of rsv(i - 1)
201 // # jp 27-06-2001: replacing "." by "_", so that SCHEMATA can be used
202 pageContext.setAttribute("currentRow_"
203 + myParent.getTableName().replace('.', '_'),
204 rsv.getCurrentRowAsMap());
205
206 try {
207 pageContext.setAttribute("position_"
208 + myParent.getTableName().replace('.',
209 '_'),
210 Util.encode(myParent.getTable().getPositionString(rsv),
211 pageContext.getRequest().getCharacterEncoding()));
212 } catch (Exception e) {
213 throw new JspException(e.getMessage());
214 }
215
216 rsv.movePrevious(); // ...and back to present ;=)
217 }
218 }
219
220 return EVAL_BODY_BUFFERED;
221 }
222 }