View Javadoc

1   /*
2    * $Source: /usr/cvsroot/melati/melati/src/main/java/org/melati/servlet/Form.java,v $
3    * $Revision: 1.15 $
4    *
5    * Copyright (C) 2000 Tim Joyce
6    *
7    * Part of Melati (http://melati.org), a framework for the rapid
8    * development of clean, maintainable web applications.
9    *
10   * Melati is free software; Permission is granted to copy, distribute
11   * and/or modify this software under the terms either:
12   *
13   * a) the GNU General Public License as published by the Free Software
14   *    Foundation; either version 2 of the License, or (at your option)
15   *    any later version,
16   *
17   *    or
18   *
19   * b) any version of the Melati Software License, as published
20   *    at http://melati.org
21   *
22   * You should have received a copy of the GNU General Public License and
23   * the Melati Software License along with this program;
24   * if not, write to the Free Software Foundation, Inc.,
25   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA to obtain the
26   * GNU General Public License and visit http://melati.org to obtain the
27   * Melati Software License.
28   *
29   * Feel free to contact the Developers of Melati (http://melati.org),
30   * if you would like to work out a different arrangement than the options
31   * outlined here.  It is our intention to allow Melati to be used by as
32   * wide an audience as possible.
33   *
34   * This program is distributed in the hope that it will be useful,
35   * but WITHOUT ANY WARRANTY; without even the implied warranty of
36   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
37   * GNU General Public License for more details.
38   *
39   * Contact details for copyright holder:
40   *
41   *     Tim Joyce <timj At paneris.org>
42   *     http://paneris.org/
43   *     68 Sandbanks Rd, Poole, Dorset. BH14 8BY. UK
44   */
45  
46  package org.melati.servlet;
47  
48  import java.util.Enumeration;
49  import java.util.Hashtable;
50  
51  
52  import javax.servlet.http.HttpServletRequest;
53  
54  import org.melati.poem.Persistent;
55  import org.melati.poem.Column;
56  import org.melati.template.ServletTemplateContext;
57  import org.melati.template.TempletAdaptor;
58  import org.melati.template.TempletAdaptorConstructionMelatiException;
59  import org.melati.util.UTF8URLEncoder;
60  
61  /**
62   * An object to hold useful static methods for manipulation of a Form in a 
63   * {@link ServletTemplateContext}.
64   */
65  
66  public final class Form {
67    
68    static Hashtable<String, TempletAdaptor> adaptorCache = new Hashtable<String, TempletAdaptor>();
69  
70    private Form() {}
71    
72    /**
73     * Retrieve updated persistent fields from a context modified in a template.
74     * <p>
75     * The context can specify an adaptor for each field using another HTML
76     * field with name suffix &quot;-adaptor&quot; and value the classname of
77     * a <code>TempletAdaptor</code>.
78     * Hence the templet that renders the field can specify how the result is parsed. 
79     * This is currently used for dates.
80     *
81     * @param context the current {@link ServletTemplateContext} to get values from
82     * @param persistent  the {@link Persistent} to update
83     */
84    public static void extractFields(ServletTemplateContext context, 
85                                     Persistent object) {
86      for (Enumeration<Column> c = object.getTable().columns(); c.hasMoreElements();) {
87        Column column = c.nextElement();
88        String formFieldName = "field_" + column.getName();
89        String rawString = context.getFormField(formFieldName);
90  
91        String adaptorFieldName = formFieldName + "-adaptor";
92        String adaptorName = context.getFormField(adaptorFieldName);
93        if (adaptorName != null) {
94          TempletAdaptor adaptor = getAdaptor(adaptorFieldName, adaptorName);
95          column.setRaw(object, adaptor.rawFrom(context, formFieldName));
96        } else {
97          if (rawString != null) {
98            rawString = rawString.trim();
99            if (rawString.equals("")) {
100             if (column.getType().getNullable())
101               column.setRaw(object, null);
102             else 
103               column.setRawString(object, "");
104           } else {
105             column.setRawString(object, rawString);
106           }
107         } // else it is not present in form 
108       }
109     }
110   }
111 
112 
113   private static TempletAdaptor getAdaptor(String adaptorFieldName, String adaptorName) {
114     TempletAdaptor adaptor = adaptorCache.get(adaptorName);
115     if(adaptor == null)
116       try {
117         adaptor = (TempletAdaptor)Class.forName(adaptorName).newInstance();
118         adaptorCache.put(adaptorName, adaptor);
119       }
120       catch (Exception e) {
121         throw new TempletAdaptorConstructionMelatiException(
122         adaptorFieldName, adaptorName, e);
123       }
124 
125     return adaptor;
126   }
127   
128   /**
129   * A utility method that gets a value from the Form.  It will return
130   * null if the value is "" or not present.
131   *
132   * @param context - a template context
133   * @param field - the name of the field to get
134   *
135   * @return - the value of the field requested
136   */
137   public static String getFieldNulled(ServletTemplateContext context, String field) {
138     return getField(context, field, null);
139   }
140   
141   /**
142   * A utility method that gets a value from the Form.  It will return
143   * the default if the value is "" or not present.
144   *
145   * @param context - a template context
146   * @param field - the name of the field to get
147   * @param defaultValue - the default value if the field is "" or not present
148   *
149   * @return - the value of the field requested
150   */
151   public static String getField(ServletTemplateContext context, String field, 
152                                String defaultValue) {
153     String val = context.getFormField(field);
154     if (val == null) // field not present in form 
155       return defaultValue;
156     return val.trim().equals("") ? defaultValue : val;
157   }
158 
159   
160   /**
161   * A utility method that gets a value from the Form as an Integer.  
162   * It will return null if the value is "" or not present.
163   *
164   * @param context - a template context
165   * @param field - the name of the field to get
166   * @param defaultValue - the default value if the field is "" or not present
167   *
168   * @return - the value of the field requested
169   */
170   public static Integer getIntegerField(ServletTemplateContext context, String field, 
171                                 Integer defaultValue) {
172     String val = getFieldNulled(context, field);
173     return val == null ? defaultValue : new Integer(val);
174   }
175 
176   /**
177   * A utility method that gets a value from the Form as an Integer.  
178   * It will return null if the value is "" or not present.
179   *
180   * @param context - a template context
181   * @param field - the name of the field to get
182   *
183   * @return - the value of the field requested
184   */
185   public static Integer getIntegerField(ServletTemplateContext context, String field) {
186     return getIntegerField(context, field, null);
187   }
188 
189   /**
190   * A utility method that tests whether a field is present in a Form,
191   * returning a Boolean.  
192   *
193   * @param context - a template context
194   * @param field - the name of the field to get
195   *
196   * @return - TRUE or FALSE depending if the field is present
197   */
198   public static Boolean getBooleanField(ServletTemplateContext context, String field) {
199     return getFieldNulled(context, field) ==  null ? 
200                                              Boolean.FALSE : Boolean.TRUE;
201   }
202   
203   /**
204    * Modify or add a form parameter setting (query string component) in a URL.
205    *
206    * @param uri     A URI
207    * @param query   A query string
208    * @param field   The parameter's name
209    * @param value   The new value for the parameter (unencoded)
210    * @return        <TT><I>uri</I>?<I>query</I></TT> with <TT>field=value</TT>.
211    *                If there is already a binding for <TT>field</TT> in the
212    *                query string it is replaced, not duplicated.
213    */
214 
215   public static String sameURLWith(String uri, String query,
216                                    String field, String value) {
217     return uri + "?" + sameQueryWith(query, field, value);
218   }
219 
220   /**
221    * Modify or add a form parameter setting (query string component) in the URL
222    * for a servlet request.
223    *
224    * @param request A servlet request
225    * @param field   The parameter's name
226    * @param value   The new value for the parameter (unencoded)
227    * @return        The request's URL with <TT>field=value</TT>.  If there is
228    *                already a binding for <TT>field</TT> in the query string
229    *                it is replaced, not duplicated.  If there is no query
230    *                string, one is added.
231    */
232 
233   public static String sameURLWith(HttpServletRequest request,
234                                    String field, String value) {
235     return sameURLWith(request.getRequestURI(), request.getQueryString(),
236                        field, value);
237   }
238 
239   /**
240    * Modify or add a form parameter setting (query string component) in a query
241    * string.
242    * Note this uses the default encoding. 
243    * 
244    * @param qs      A query string
245    * @param field   The parameter's name
246    * @param value   The new value for the parameter (unencoded)
247    * @return        <TT>qs</TT> with <TT>field=value</TT>.
248    *                If there is already a binding for <TT>field</TT> in the
249    *                query string it is replaced, not duplicated.
250    */
251   public static String sameQueryWith(String qs, String field, String value) {
252     
253     String fenc = UTF8URLEncoder.encode(field);
254     String fenceq = fenc + '=';
255     String fev = fenceq + UTF8URLEncoder.encode(value);
256 
257     if (qs == null || qs.equals("")) return fev;
258 
259     int i;
260     if (qs.startsWith(fenceq)) i = 0;
261     else {
262       i = qs.indexOf('&' + fenceq);
263       if (i == -1) return qs + '&' + fev;
264       ++i;
265     }
266 
267     int a = qs.indexOf('&', i);
268     return qs.substring(0, i) + fev + (a == -1 ? "" : qs.substring(a));
269   }
270   
271 
272 }
273 
274 
275 
276 
277 
278 
279 
280 
281