View Javadoc

1   /*
2    * $Header: /cvsroot/jdbforms/dbforms/src/org/dbforms/taglib/DbLinkURLTag.java,v 1.33 2006/02/17 16:04:43 hkollmann Exp $
3    * $Revision: 1.33 $
4    * $Date: 2006/02/17 16:04:43 $
5    *
6    * DbForms - a Rapid Application Development Framework
7    * Copyright (C) 2001 Joachim Peer <joepeer@excite.com>
8    *
9    * This library is free software; you can redistribute it and/or
10   * modify it under the terms of the GNU Lesser General Public
11   * License as published by the Free Software Foundation; either
12   * version 2.1 of the License, or (at your option) any later version.
13   *
14   * This library is distributed in the hope that it will be useful,
15   * but WITHOUT ANY WARRANTY; without even the implied warranty of
16   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17   * Lesser General Public License for more details.
18   *
19   * You should have received a copy of the GNU Lesser General Public
20   * License along with this library; if not, write to the Free Software
21   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
22   */
23  
24  package org.dbforms.taglib;
25  
26  import org.apache.commons.logging.Log;
27  import org.apache.commons.logging.LogFactory;
28  
29  import org.dbforms.config.Field;
30  import org.dbforms.config.FieldValue;
31  import org.dbforms.config.FieldValues;
32  import org.dbforms.config.Table;
33  
34  import org.dbforms.util.Util;
35  
36  import java.io.UnsupportedEncodingException;
37  
38  import javax.servlet.http.HttpServletRequest;
39  import javax.servlet.http.HttpServletResponse;
40  import javax.servlet.jsp.JspException;
41  
42  
43  
44  /***
45   * <p>
46   * the 3 examples below produce all the same result
47   * </p>
48   *
49   * <p>
50   * &lt;linkURL href="customer.jsp" table="customer" position="1:2:12-3:4:1992"
51   * /&gt;
52   * </p>
53   *
54   * <p>
55   * &lt;linkURL href="customer.jsp" table="customer" position="&lt;%= currentKey
56   * %&gt;" /&gt;
57   * </p>
58   *
59   * <p>
60   * &lt;linkURL href="customer.jsp" table="customer" /&gt; &lt;position
61   * fieldName="id" value="103" /&gt; &lt;position fieldName="cust_lang"
62   * value="2" /&gt; &lt;/linkURL&gt;
63   * </p>
64   *
65   * <p>
66   * result (off course without the line feeds)
67   * </p>
68   * <pre>/servlet/control?
69   * ac_goto_x=t&
70   * data_ac_goto_x_fu=/customer.jsp&
71   * data_ac_goto_x_destTable=17&
72   * data_ac_goto_x_destPos=103~2</pre>
73   *
74   * <p>
75   * Use it like this:
76   * </p>
77   * <pre><a href="&lt;linkURL href="customer.jsp" tableName="customer" position="103~2" /&gt;"> some text </a></pre>
78   *
79   * @author Joachim Peer
80   */
81  public class DbLinkURLTag extends AbstractDbBaseHandlerTag
82     implements javax.servlet.jsp.tagext.TryCatchFinally {
83     private static Log            logCat = LogFactory.getLog(DbLinkURLTag.class
84                                                              .getName()); // logging category for this class
85     private transient FieldValues positionFv; // fields and their values, provided by embedded DbLinkPositionItem-Elements
86  
87     /***
88      * used if parentTable is different to tableName: field(s) in this forme
89      * that is/are linked to the parent form
90      */
91     private String childField;
92  
93     // -- properties
94     private String href;
95     private String keyToDestPos;
96     private String keyToKeyToDestPos;
97  
98     /***
99      * used if parentTable is different to tableName: field(s) in the main form
100     * that is/are linked to this form
101     */
102    private String parentField;
103    private String position;
104    private String singleRow = "false";
105    private String tableName;
106 
107    /***
108     * Sets the childField.
109     *
110     * @param childField The childField to set
111     */
112    public void setChildField(String childField) {
113       this.childField = childField;
114    }
115 
116 
117    /***
118     * Returns the childField.
119     *
120     * @return String
121     */
122    public String getChildField() {
123       return childField;
124    }
125 
126 
127    /***
128     * DOCUMENT ME!
129     *
130     * @param position DOCUMENT ME!
131     */
132    public void setDestPos(String position) {
133       this.position = position;
134    }
135 
136 
137    /***
138     * DOCUMENT ME!
139     *
140     * @return DOCUMENT ME!
141     */
142    public String getDestPos() {
143       return position;
144    }
145 
146 
147    /***
148     * DOCUMENT ME!
149     *
150     * @param href DOCUMENT ME!
151     */
152    public void setHref(String href) {
153       this.href = href;
154    }
155 
156 
157    /***
158     * DOCUMENT ME!
159     *
160     * @return DOCUMENT ME!
161     */
162    public String getHref() {
163       return href;
164    }
165 
166 
167    /***
168     * Sets the keyToDestPos.
169     *
170     * @param keyToDestPos The keyToDestPos to set
171     */
172    public void setKeyToDestPos(String keyToDestPos) {
173       this.keyToDestPos = keyToDestPos;
174    }
175 
176 
177    /***
178     * Returns the keyToDestPos.
179     *
180     * @return String
181     */
182    public String getKeyToDestPos() {
183       return keyToDestPos;
184    }
185 
186 
187    /***
188     * Sets the keyToKeyToDestPos.
189     *
190     * @param keyToKeyToDestPos The keyToKeyToDestPos to set
191     */
192    public void setKeyToKeyToDestPos(String keyToKeyToDestPos) {
193       this.keyToKeyToDestPos = keyToKeyToDestPos;
194    }
195 
196 
197    /***
198     * Returns the keyToKeyToDestPos.
199     *
200     * @return String
201     */
202    public String getKeyToKeyToDestPos() {
203       return keyToKeyToDestPos;
204    }
205 
206 
207    /***
208     * Sets the parentField.
209     *
210     * @param parentField The parentField to set
211     */
212    public void setParentField(String parentField) {
213       this.parentField = parentField;
214    }
215 
216 
217    /***
218     * Returns the parentField.
219     *
220     * @return String
221     */
222    public String getParentField() {
223       return parentField;
224    }
225 
226 
227    /***
228     * DOCUMENT ME!
229     *
230     * @param position DOCUMENT ME!
231     */
232    public void setPosition(String position) {
233       this.position = position;
234    }
235 
236 
237    /***
238     * DOCUMENT ME!
239     *
240     * @return DOCUMENT ME!
241     */
242    public String getPosition() {
243       return position;
244    }
245 
246 
247    /***
248     * DOCUMENT ME!
249     *
250     * @param string
251     */
252    public void setSingleRow(String string) {
253       singleRow = string;
254    }
255 
256 
257    /***
258     * DOCUMENT ME!
259     *
260     * @return the attribute
261     */
262    public String getSingleRow() {
263       return singleRow;
264    }
265 
266 
267    /***
268     * DOCUMENT ME!
269     *
270     * @return DOCUMENT ME!
271     */
272    public Table getTable() {
273       if (!Util.isNull(tableName)) {
274          return getConfig()
275                    .getTableByName(tableName);
276       } else if (getParentForm() != null) { // we must try if we get info from parentForm
277 
278          return getParentForm()
279                    .getTable();
280       } else {
281          throw new IllegalArgumentException("no table specified. either you define expliclty the attribute \"tableName\" or you put this tag inside a db:form!");
282       }
283    }
284 
285 
286    /***
287     * DOCUMENT ME!
288     *
289     * @param tableName DOCUMENT ME!
290     */
291    public void setTableName(String tableName) {
292       this.tableName = tableName;
293    }
294 
295 
296    /***
297     * to be called by DbLinkPositonItems
298     *
299     * @param field DOCUMENT ME!
300     * @param value DOCUMENT ME!
301     */
302    public void addPositionPart(Field  field,
303                                String value) {
304       if (positionFv == null) {
305          positionFv = new FieldValues();
306       }
307 
308       // 2003-03-29 HKK: Change from Hashtable to FieldValueTable
309       FieldValue fv = new FieldValue(field, value);
310       positionFv.put(fv);
311    }
312 
313 
314    /***
315     * DOCUMENT ME!
316     *
317     * @return DOCUMENT ME!
318     *
319     * @throws JspException thrown when error occurs in processing the body of
320     *         this method
321     */
322    public int doBodyEndTag() throws javax.servlet.jsp.JspException {
323       return SKIP_BODY;
324    }
325 
326 
327    /***
328     * DOCUMENT ME!
329     *
330     * @return DOCUMENT ME!
331     *
332     * @throws JspException thrown when error occurs in processing the body of
333     *         this method
334     */
335    public int doEndTag() throws javax.servlet.jsp.JspException {
336       try {
337          HttpServletResponse response = (HttpServletResponse) pageContext
338                                         .getResponse();
339 
340          String              s = makeUrl();
341          s = response.encodeURL(s);
342          pageContext.getOut()
343                     .write(s);
344       } catch (java.io.IOException ioe) {
345          throw new JspException("IO Error: " + ioe.getMessage());
346       } catch (Exception e) {
347          throw new JspException("Error: " + e.getMessage());
348       }
349 
350       return EVAL_PAGE;
351    }
352 
353 
354    /***
355     * DOCUMENT ME!
356     */
357    public void doFinally() {
358       logCat.info("doFinally called");
359       position = null;
360 
361       if (positionFv != null) {
362          positionFv.clear();
363       }
364 
365       positionFv        = null;
366       href              = null;
367       tableName         = null;
368       position          = null;
369       keyToDestPos      = null;
370       keyToKeyToDestPos = null;
371       singleRow         = "false";
372 
373       super.doFinally();
374    }
375 
376 
377    /***
378     * DOCUMENT ME!
379     *
380     * @return DOCUMENT ME!
381     *
382     * @throws JspException thrown when error occurs in processing the body of
383     *         this method
384     * @throws IllegalArgumentException thrown when some parameters are missing.
385     */
386    public int doStartTag() throws javax.servlet.jsp.JspException {
387       if (Util.isNull(getPosition())) { // if position was not set explicitly,
388 
389          return EVAL_BODY_BUFFERED; // we have to evaluate body and hopefully find DbLinkPositionItems there
390       } else {
391          return SKIP_BODY; // if position was provided we don't need to look into body
392       }
393    }
394 
395 
396    /***
397     * DOCUMENT ME!
398     *
399     * @return DOCUMENT ME!
400     *
401     * @throws UnsupportedEncodingException DOCUMENT ME!
402     */
403    protected String makeUrl() throws UnsupportedEncodingException {
404       // determinate position inside table (key)
405       if (this.position == null) { // not explic. def. by attribute
406 
407          if (positionFv != null) { // but (maybe) defined by sub-elements (DbLinkPositionItem)
408             position = getTable()
409                           .getKeyPositionString(positionFv);
410          }
411       }
412 
413       // build tag
414       StringBuffer       tagBuf      = new StringBuffer(200);
415       HttpServletRequest request     = (HttpServletRequest) pageContext
416                                        .getRequest();
417       String             contextPath = request.getContextPath();
418       tagBuf.append(contextPath);
419 
420       // 2002-01-17 Fix contributed by Dirk Kraemer and Bertram Gong//
421       if (!contextPath.endsWith("/")) {
422          tagBuf.append("/");
423       }
424 
425       tagBuf.append("servlet/control?");
426 
427       String tagName = "ac_goto";
428       tagBuf.append(getDataTag(tagName, "x", "t"));
429 
430       tagName = "data" + tagName + "_x";
431       tagBuf.append(getDataTag(tagName, "fu", href));
432 
433       // table is required. we force to define a valid table.
434       // because we do not want the developer to use this tag instead of
435       // normal <a href="">-tags to arbitrary (static) ressources, as this would slow down the application.
436       tagBuf.append(getDataTag(tagName, "destTable", getTable().getName()));
437 
438       // position within table is not required.
439       // if no position was provided/determinated, dbForm will navigate to the first row
440       // 2002-11-20 HKK: Fixed encoding bug!
441       tagBuf.append(getDataTag(tagName, "destPos",
442                                Util.encode(position,
443                                            pageContext.getRequest().getCharacterEncoding())));
444 
445       // 2002-11-21 HKK: Allow same keys as in dbgotobutton
446       tagBuf.append(getDataTag(tagName, "keyToDestPos",
447                                Util.encode(keyToDestPos,
448                                            pageContext.getRequest().getCharacterEncoding())));
449       tagBuf.append(getDataTag(tagName, "keyToKeyDestPos",
450                                Util.encode(keyToKeyToDestPos,
451                                            pageContext.getRequest().getCharacterEncoding())));
452 
453       // 2002-11-21 HKK: New: send parent table name as parameter if it is different to table
454       if ( (getParentForm().getTable() != null) && (getTable() != getParentForm().getTable()) ) {
455          tagBuf.append(getDataTag(tagName, "srcTable",
456                                   getParentForm().getTable().getName()));
457          tagBuf.append(getDataTag(tagName, "childField",
458                                   Util.encode(childField,
459                                               pageContext.getRequest().getCharacterEncoding())));
460          tagBuf.append(getDataTag(tagName, "parentField",
461                                   Util.encode(parentField,
462                                               pageContext.getRequest().getCharacterEncoding())));
463       }
464 
465       tagBuf.append(getDataTag(tagName, "singleRow", getSingleRow()));
466 
467       String s = tagBuf.toString();
468       s = s.substring(0, s.length() - 1);
469 
470       return s;
471    }
472 
473 
474    private String getDataTag(String primaryTagName,
475                              String dataKey,
476                              String dataValue) {
477       String s = "";
478 
479       if (!Util.isNull(dataValue)) {
480          StringBuffer tagBuf = new StringBuffer();
481          tagBuf.append(primaryTagName);
482          tagBuf.append("_");
483          tagBuf.append(dataKey);
484          tagBuf.append("=");
485          tagBuf.append(dataValue);
486          tagBuf.append("&");
487          s = tagBuf.toString();
488       }
489 
490       return s;
491    }
492 }