Coverage Report - org.melati.servlet.Form
 
Classes in this File Line Coverage Branch Coverage Complexity
Form
55%
42/77
57%
23/40
2.643
 
 1  
 /*
 2  
  * $Source: /usr/cvsroot/melati/melati/src/main/java/org/melati/servlet/Form.java,v $
 3  
  * $Revision: 1.9 $
 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.io.UnsupportedEncodingException;
 49  
 import java.util.Enumeration;
 50  
 import java.util.Hashtable;
 51  
 
 52  
 
 53  
 import javax.servlet.http.HttpServletRequest;
 54  
 
 55  
 import org.melati.poem.Persistent;
 56  
 import org.melati.poem.Column;
 57  
 import org.melati.template.ServletTemplateContext;
 58  
 import org.melati.template.TempletAdaptor;
 59  
 import org.melati.template.TempletAdaptorConstructionMelatiException;
 60  
 import org.melati.util.MelatiBugMelatiException;
 61  
 import org.melati.util.UTF8URLEncoder;
 62  
 
 63  
 /**
 64  
  * An object to hold useful static methods for manipulation of a Form in a 
 65  
  * {@link ServletTemplateContext}.
 66  
  */
 67  
 
 68  
 public final class Form {
 69  
   
 70  1
   static Hashtable adaptorCache = new Hashtable();
 71  
 
 72  0
   private Form() {}
 73  
   
 74  
   /**
 75  
    * Retrieve updated persistent fields from a context modified in a template.
 76  
    * <p>
 77  
    * The context can specify an adaptor for each field using another HTML
 78  
    * field with name suffix &quot;-adaptor&quot; and value the classname of
 79  
    * a <code>TempletAdaptor</code>.
 80  
    * Hence the templet that renders the field can specify how
 81  
    * the result is parsed. 
 82  
    * This is currently used for dates.
 83  
    *
 84  
    * @param context the current {@link ServletTemplateContext} to get values from
 85  
    * @param object  the {@link Persistent} to update
 86  
    */
 87  
   public static void extractFields(ServletTemplateContext context, 
 88  
                                    Persistent object) {
 89  8
     for (Enumeration c = object.getTable().columns(); c.hasMoreElements();) {
 90  51
       Column column = (Column)c.nextElement();
 91  51
       String formFieldName = "field_" + column.getName();
 92  51
       String rawString = context.getForm(formFieldName);
 93  
 
 94  51
       String adaptorFieldName = formFieldName + "-adaptor";
 95  51
       String adaptorName = context.getForm(adaptorFieldName);
 96  51
       if (adaptorName != null) {
 97  0
         TempletAdaptor adaptor = getAdaptor(adaptorFieldName, adaptorName);
 98  0
         column.setRaw(object, adaptor.rawFrom(context, formFieldName));
 99  0
       } else {
 100  51
         if (rawString != null) {
 101  42
           rawString = rawString.trim();
 102  42
           if (rawString.equals("")) {
 103  11
             if (column.getType().getNullable())
 104  11
               column.setRaw(object, null);
 105  
             else
 106  0
               column.setRawString(object, "");
 107  
           } else {
 108  
             String branch;
 109  31
             String utf8StringISO = null;
 110  31
             String utf8StringUTF8 = null;
 111  
             byte[] stringBytesISO;
 112  
             byte[] stringBytesUTF8;
 113  
             try {
 114  31
               stringBytesISO = rawString.getBytes("ISO-8859-1");
 115  31
               utf8StringISO = new String(stringBytesISO, "ISO-8859-1");
 116  31
               stringBytesUTF8 = rawString.getBytes("UTF-8");
 117  31
               utf8StringUTF8 = new String(stringBytesUTF8, "UTF-8");
 118  
             
 119  31
               if (utf8StringISO.equals(rawString)) {
 120  31
                 column.setRawString(object, utf8StringISO);
 121  31
                 branch = "1";
 122  0
               } else if (utf8StringUTF8.equals(rawString)) {
 123  0
                 column.setRawString(object, utf8StringUTF8);
 124  0
                 branch = "2";
 125  
               } else {
 126  0
                 column.setRawString(object, rawString);              
 127  0
                 branch = "3";
 128  
               }
 129  0
             } catch (UnsupportedEncodingException e) {
 130  0
               throw new MelatiBugMelatiException("UTF-8 or ISO-8859-1 not supported", e);
 131  31
             }
 132  31
             System.err.println("Branch:"+branch+":"+rawString +":"+utf8StringUTF8+":"+utf8StringISO);
 133  
           }
 134  
         }
 135  
       }
 136  51
     }
 137  8
   }
 138  
 
 139  
   /**
 140  
    * Fill in value of a Field from a ServletTemplateContext.
 141  
    *
 142  
    * @param context    the current {@link ServletTemplateContext} to get values from
 143  
    * @param fieldName  the name of the field to extract
 144  
    * @return the value of the field 
 145  
    * @throws TempletAdaptorConstructionMelatiException 
 146  
    *             if there is a problem, for example with the class name
 147  
    */
 148  
   public static Object extractField(ServletTemplateContext context, String fieldName)
 149  
       throws TempletAdaptorConstructionMelatiException {
 150  
 
 151  0
     String rawString = context.getForm(fieldName);
 152  
 
 153  0
     String adaptorFieldName = fieldName + "-adaptor";
 154  0
     String adaptorName = context.getForm(adaptorFieldName);
 155  
 
 156  0
     if (adaptorName != null) {
 157  0
       TempletAdaptor adaptor = getAdaptor(adaptorFieldName, adaptorName);
 158  0
       return adaptor.rawFrom(context, fieldName);
 159  
     }
 160  0
     return rawString;
 161  
   }
 162  
 
 163  
 
 164  
   private static TempletAdaptor getAdaptor(String adaptorFieldName, String adaptorName) {
 165  0
     TempletAdaptor adaptor = (TempletAdaptor)adaptorCache.get(adaptorName);
 166  0
     if(adaptor == null)
 167  
       try {
 168  0
         adaptor = (TempletAdaptor)Class.forName(adaptorName).newInstance();
 169  0
         adaptorCache.put(adaptorName, adaptor);
 170  
       }
 171  0
       catch (Exception e) {
 172  0
         throw new TempletAdaptorConstructionMelatiException(
 173  
         adaptorFieldName, adaptorName, e);
 174  0
       }
 175  
 
 176  0
     return adaptor;
 177  
   }
 178  
   
 179  
   /**
 180  
   * A utility method that gets a value from the Form.  It will return
 181  
   * null if the value is "" or not present.
 182  
   *
 183  
   * @param context - a template context
 184  
   * @param field - the name of the field to get
 185  
   *
 186  
   * @return - the value of the field requested
 187  
   */
 188  
   public static String getFieldNulled(ServletTemplateContext context, String field) {
 189  853
     return getField(context, field, null);
 190  
   }
 191  
   
 192  
     
 193  
   /**
 194  
   * A utility method that gets a value from the Form.  It will return
 195  
   * the default if the value is "" or not present.
 196  
   *
 197  
   * @param context - a template context
 198  
   * @param field - the name of the field to get
 199  
   * @param defaultValue - the default value if the field is "" or not present
 200  
   *
 201  
   * @return - the value of the field requested
 202  
   */
 203  
   public static String getField(ServletTemplateContext context, String field, 
 204  
                                String defaultValue) {
 205  1234
     String val = context.getForm(field);
 206  1234
     if (val == null) return defaultValue;
 207  65
     return val.trim().equals("") ? defaultValue : val;
 208  
   }
 209  
 
 210  
   /**
 211  
   * A utility method that gets a value from the Form as an Integer.  
 212  
   * It will return null if the value is "" or not present.
 213  
   *
 214  
   * @param context - a template context
 215  
   * @param field - the name of the field to get
 216  
   * @param defaultValue - the default value if the field is "" or not present
 217  
   *
 218  
   * @return - the value of the field requested
 219  
   */
 220  
   public static Integer getIntegerField(ServletTemplateContext context, String field, 
 221  
                                 Integer defaultValue) {
 222  0
     String val = getFieldNulled(context, field);
 223  0
     return val == null ? defaultValue : new Integer(val);
 224  
   }
 225  
 
 226  
   /**
 227  
   * A utility method that gets a value from the Form as an Integer.  
 228  
   * It will return null if the value is "" or not present.
 229  
   *
 230  
   * @param context - a template context
 231  
   * @param field - the name of the field to get
 232  
   *
 233  
   * @return - the value of the field requested
 234  
   */
 235  
   public static Integer getIntegerField(ServletTemplateContext context, String field) {
 236  0
     return getIntegerField(context, field, null);
 237  
   }
 238  
 
 239  
   /**
 240  
   * A utility method that tests whether a field is present in a Form,
 241  
   * returning a Boolean.  
 242  
   *
 243  
   * @param context - a template context
 244  
   * @param field - the name of the field to get
 245  
   *
 246  
   * @return - TRUE or FALSE depending if the field is present
 247  
   */
 248  
   public static Boolean getBooleanField(ServletTemplateContext context, String field) {
 249  0
     return getFieldNulled(context, field) ==  null ? 
 250  
                                              Boolean.FALSE : Boolean.TRUE;
 251  
   }
 252  
   
 253  
   /**
 254  
    * Modify or add a form parameter setting (query string component) in a URL.
 255  
    *
 256  
    * @param uri     A URI
 257  
    * @param query   A query string
 258  
    * @param field   The parameter's name
 259  
    * @param value   The new value for the parameter (unencoded)
 260  
    * @return        <TT><I>uri</I>?<I>query</I></TT> with <TT>field=value</TT>.
 261  
    *                If there is already a binding for <TT>field</TT> in the
 262  
    *                query string it is replaced, not duplicated.
 263  
    */
 264  
 
 265  
   public static String sameURLWith(String uri, String query,
 266  
                                    String field, String value) {
 267  159
     return uri + "?" + sameQueryWith(query, field, value);
 268  
   }
 269  
 
 270  
   /**
 271  
    * Modify or add a form parameter setting (query string component) in the URL
 272  
    * for a servlet request.
 273  
    *
 274  
    * @param request A servlet request
 275  
    * @param field   The parameter's name
 276  
    * @param value   The new value for the parameter (unencoded)
 277  
    * @return        The request's URL with <TT>field=value</TT>.  If there is
 278  
    *                already a binding for <TT>field</TT> in the query string
 279  
    *                it is replaced, not duplicated.  If there is no query
 280  
    *                string, one is added.
 281  
    */
 282  
 
 283  
   public static String sameURLWith(HttpServletRequest request,
 284  
                                    String field, String value) {
 285  159
     return sameURLWith(request.getRequestURI(), request.getQueryString(),
 286  
                        field, value);
 287  
   }
 288  
 
 289  
   /**
 290  
    * Modify or add a form parameter setting (query string component) in a query
 291  
    * string.
 292  
    * Note this uses the default encoding. 
 293  
    * 
 294  
    * @param qs      A query string
 295  
    * @param field   The parameter's name
 296  
    * @param value   The new value for the parameter (unencoded)
 297  
    * @return        <TT>qs</TT> with <TT>field=value</TT>.
 298  
    *                If there is already a binding for <TT>field</TT> in the
 299  
    *                query string it is replaced, not duplicated.
 300  
    */
 301  
   public static String sameQueryWith(String qs, String field, String value) {
 302  
     
 303  162
     String fenc = UTF8URLEncoder.encode(field);
 304  162
     String fenceq = fenc + '=';
 305  162
     String fev = fenceq + UTF8URLEncoder.encode(value);
 306  
 
 307  162
     if (qs == null || qs.equals("")) return fev;
 308  
 
 309  
     int i;
 310  154
     if (qs.startsWith(fenceq)) i = 0;
 311  
     else {
 312  153
       i = qs.indexOf('&' + fenceq);
 313  153
       if (i == -1) return qs + '&' + fev;
 314  32
       ++i;
 315  
     }
 316  
 
 317  33
     int a = qs.indexOf('&', i);
 318  33
     return qs.substring(0, i) + fev + (a == -1 ? "" : qs.substring(a));
 319  
   }
 320  
   
 321  
 
 322  
   /**
 323  
   * A utility method that gets a value from the Form.  It will return
 324  
   * null if the value is "" or not present.
 325  
   *
 326  
   * @param context - a template context
 327  
   * @param field - the name of the field to get
 328  
   *
 329  
   * @return - the value of the field requested
 330  
   */
 331  
   public static String getFormNulled(ServletTemplateContext context, String field) {
 332  0
     return getForm(context, field, null);
 333  
   }
 334  
 
 335  
  /**
 336  
   * A utility method that gets a value from the Form.  It will return
 337  
   * the default if the value is "" or not present.
 338  
   *
 339  
   * @param context - a template context
 340  
   * @param field - the name of the field to get
 341  
   * @param def - the default value if the field is "" or not present
 342  
   *
 343  
   * @return - the value of the field requested
 344  
   */
 345  
   public static String getForm(ServletTemplateContext context, String field, 
 346  
                                String def) {
 347  0
     String val = context.getForm(field);
 348  0
     if (val == null) return def;
 349  0
     return val.trim().equals("") ? def : val;
 350  
   }
 351  
 
 352  
 }
 353  
 
 354  
 
 355  
 
 356  
 
 357  
 
 358  
 
 359  
 
 360  
 
 361