Coverage report

  %line %branch
org.apache.turbine.util.parser.DefaultParameterParser
4% 
69% 

 1  
 package org.apache.turbine.util.parser;
 2  
 
 3  
 /*
 4  
  * Copyright 2001-2004 The Apache Software Foundation.
 5  
  *
 6  
  * Licensed under the Apache License, Version 2.0 (the "License")
 7  
  * you may not use this file except in compliance with the License.
 8  
  * You may obtain a copy of the License at
 9  
  *
 10  
  *     http://www.apache.org/licenses/LICENSE-2.0
 11  
  *
 12  
  * Unless required by applicable law or agreed to in writing, software
 13  
  * distributed under the License is distributed on an "AS IS" BASIS,
 14  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 15  
  * See the License for the specific language governing permissions and
 16  
  * limitations under the License.
 17  
  */
 18  
 
 19  
 import java.net.URLDecoder;
 20  
 
 21  
 import java.util.Enumeration;
 22  
 import java.util.HashMap;
 23  
 import java.util.Iterator;
 24  
 import java.util.Map;
 25  
 import java.util.StringTokenizer;
 26  
 
 27  
 import javax.servlet.http.HttpServletRequest;
 28  
 
 29  
 import org.apache.commons.fileupload.FileItem;
 30  
 
 31  
 import org.apache.commons.logging.Log;
 32  
 import org.apache.commons.logging.LogFactory;
 33  
 
 34  
 import org.apache.turbine.services.upload.TurbineUpload;
 35  
 import org.apache.turbine.services.upload.UploadService;
 36  
 
 37  
 import org.apache.turbine.util.TurbineException;
 38  
 import org.apache.turbine.util.pool.Recyclable;
 39  
 
 40  
 /**
 41  
  * DefaultParameterParser is a utility object to handle parsing and
 42  
  * retrieving the data passed via the GET/POST/PATH_INFO arguments.
 43  
  *
 44  
  * <p>NOTE: The name= portion of a name=value pair may be converted
 45  
  * to lowercase or uppercase when the object is initialized and when
 46  
  * new data is added.  This behaviour is determined by the url.case.folding
 47  
  * property in TurbineResources.properties.  Adding a name/value pair may
 48  
  * overwrite existing name=value pairs if the names match:
 49  
  *
 50  
  * <pre>
 51  
  * ParameterParser pp = data.getParameters();
 52  
  * pp.add("ERROR",1);
 53  
  * pp.add("eRrOr",2);
 54  
  * int result = pp.getInt("ERROR");
 55  
  * </pre>
 56  
  *
 57  
  * In the above example, result is 2.
 58  
  *
 59  
  * @author <a href="mailto:ilkka.priha@simsoft.fi">Ilkka Priha</a>
 60  
  * @author <a href="mailto:jon@clearink.com">Jon S. Stevens</a>
 61  
  * @author <a href="mailto:sean@informage.net">Sean Legassick</a>
 62  
  * @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a>
 63  
  * @version $Id: DefaultParameterParser.java,v 1.20.2.2 2004/05/20 03:33:43 seade Exp $
 64  
  */
 65  
 public class DefaultParameterParser
 66  
     extends BaseValueParser
 67  
     implements ParameterParser, Recyclable
 68  
 {
 69  
     /** Logging */
 70  34
     private static Log log = LogFactory.getLog(DefaultParameterParser.class);
 71  
 
 72  
     /** The servlet request to parse. */
 73  0
     private HttpServletRequest request = null;
 74  
 
 75  
     /** The raw data of a file upload. */
 76  0
     private byte[] uploadData = null;
 77  
 
 78  
     /** Map of request parameters to FileItem[]'s */
 79  0
     private Map fileParameters = new HashMap();
 80  
 
 81  
     /** Turbine Upload Service reference */
 82  17
     private static UploadService uploadService = null;
 83  
 
 84  
     /** Do we have an upload Service? */
 85  17
     private static boolean uploadServiceIsAvailable = false;
 86  
 
 87  
     /**
 88  
      * Create a new empty instance of ParameterParser.  Uses the
 89  
      * default character encoding (US-ASCII).
 90  
      *
 91  
      * <p>To add name/value pairs to this set of parameters, use the
 92  
      * <code>add()</code> methods.
 93  
      */
 94  
     public DefaultParameterParser()
 95  
     {
 96  0
         super();
 97  0
         configureUploadService();
 98  0
     }
 99  
 
 100  
     /**
 101  
      * Create a new empty instance of ParameterParser. Takes a
 102  
      * character encoding name to use when converting strings to
 103  
      * bytes.
 104  
      *
 105  
      * <p>To add name/value pairs to this set of parameters, use the
 106  
      * <code>add()</code> methods.
 107  
      *
 108  
      * @param characterEncoding The character encoding of strings.
 109  
      */
 110  
     public DefaultParameterParser(String characterEncoding)
 111  
     {
 112  0
         super (characterEncoding);
 113  0
         configureUploadService();
 114  0
     }
 115  
 
 116  
     /**
 117  
      * Checks for availability of the Upload Service. We do this
 118  
      * check only once at Startup, because the getService() call
 119  
      * is really expensive and we don't have to run it every time
 120  
      * we process a request.
 121  
      */
 122  
     private void configureUploadService()
 123  
     {
 124  0
         uploadServiceIsAvailable = TurbineUpload.isAvailable();
 125  0
         if (uploadServiceIsAvailable)
 126  
         {
 127  0
             uploadService = TurbineUpload.getService();
 128  
         }
 129  0
     }
 130  
 
 131  
     /**
 132  
      * Disposes the parser.
 133  
      */
 134  
     public void dispose()
 135  
     {
 136  0
         this.request = null;
 137  0
         this.uploadData = null;
 138  0
         this.fileParameters.clear();
 139  0
         super.dispose();
 140  0
     }
 141  
 
 142  
     /**
 143  
      * Gets the parsed servlet request.
 144  
      *
 145  
      * @return the parsed servlet request or null.
 146  
      */
 147  
     public HttpServletRequest getRequest()
 148  
     {
 149  0
         return this.request;
 150  
     }
 151  
 
 152  
     /**
 153  
      * Sets the servlet request to be parser.  This requires a
 154  
      * valid HttpServletRequest object.  It will attempt to parse out
 155  
      * the GET/POST/PATH_INFO data and store the data into a Map.
 156  
      * There are convenience methods for retrieving the data as a
 157  
      * number of different datatypes.  The PATH_INFO data must be a
 158  
      * URLEncoded() string.
 159  
      * <p>
 160  
      * To add name/value pairs to this set of parameters, use the
 161  
      * <code>add()</code> methods.
 162  
      *
 163  
      * @param request An HttpServletRequest.
 164  
      */
 165  
     public void setRequest(HttpServletRequest request)
 166  
     {
 167  0
         clear();
 168  
 
 169  0
         uploadData = null;
 170  
 
 171  0
         String enc = request.getCharacterEncoding();
 172  0
         setCharacterEncoding(enc != null ? enc : "US-ASCII");
 173  
 
 174  
         // String object re-use at its best.
 175  0
         String tmp = null;
 176  
 
 177  0
         tmp = request.getHeader("Content-type");
 178  
 
 179  0
         if (uploadServiceIsAvailable
 180  
                 && uploadService.getAutomatic()
 181  
                 && tmp != null
 182  
                 && tmp.startsWith("multipart/form-data"))
 183  
         {
 184  0
             log.debug("Running the Turbine Upload Service");
 185  
             try
 186  
             {
 187  0
                 TurbineUpload.parseRequest(request, this);
 188  
             }
 189  0
             catch (TurbineException e)
 190  
             {
 191  0
                 log.error("File upload failed", e);
 192  0
             }
 193  
         }
 194  
 
 195  0
         for (Enumeration names = request.getParameterNames();
 196  0
              names.hasMoreElements();)
 197  
         {
 198  0
             tmp = (String) names.nextElement();
 199  0
             add(convert(tmp),
 200  
                     request.getParameterValues(tmp));
 201  
         }
 202  
 
 203  
         // Also cache any pathinfo variables that are passed around as
 204  
         // if they are query string data.
 205  
         try
 206  
         {
 207  0
             StringTokenizer st =
 208  
                     new StringTokenizer(request.getPathInfo(), "/");
 209  0
             boolean isNameTok = true;
 210  0
             String pathPart = null;
 211  0
             while (st.hasMoreTokens())
 212  
             {
 213  0
                 if (isNameTok)
 214  
                 {
 215  0
                     tmp = URLDecoder.decode(st.nextToken());
 216  0
                     isNameTok = false;
 217  
                 }
 218  
                 else
 219  
                 {
 220  0
                     pathPart = URLDecoder.decode(st.nextToken());
 221  0
                     if (tmp.length() > 0)
 222  
                     {
 223  0
                         add(convert(tmp), pathPart);
 224  
                     }
 225  0
                     isNameTok = true;
 226  
                 }
 227  
             }
 228  
         }
 229  0
         catch (Exception e)
 230  
         {
 231  
             // If anything goes wrong above, don't worry about it.
 232  
             // Chances are that the path info was wrong anyways and
 233  
             // things that depend on it being right will fail later
 234  
             // and should be caught later.
 235  0
         }
 236  
 
 237  0
         this.request = request;
 238  
 
 239  0
         if (log.isDebugEnabled())
 240  
         {
 241  0
             log.debug("Parameters found in the Request:");
 242  0
             for (Iterator it = keySet().iterator(); it.hasNext();)
 243  
             {
 244  0
                 String key = (String) it.next();
 245  0
                 log.debug("Key: " + key + " -> " + getString(key));
 246  
             }
 247  
         }
 248  0
     }
 249  
 
 250  
     /**
 251  
      * Sets the uploadData byte[]
 252  
      *
 253  
      * @param uploadData A byte[] with data.
 254  
      */
 255  
     public void setUploadData(byte[] uploadData)
 256  
     {
 257  0
         this.uploadData = uploadData;
 258  0
     }
 259  
 
 260  
     /**
 261  
      * Gets the uploadData byte[]
 262  
      *
 263  
      * @return uploadData A byte[] with data.
 264  
      */
 265  
     public byte[] getUploadData()
 266  
     {
 267  0
         return this.uploadData;
 268  
     }
 269  
 
 270  
     /**
 271  
      * Add a FileItem object as a parameters.  If there are any
 272  
      * FileItems already associated with the name, append to the
 273  
      * array.  The reason for this is that RFC 1867 allows multiple
 274  
      * files to be associated with single HTML input element.
 275  
      *
 276  
      * @param name A String with the name.
 277  
      * @param value A FileItem with the value.
 278  
      */
 279  
     public void append(String name, FileItem value)
 280  
     {
 281  0
         FileItem[] items = this.getFileItems(name);
 282  0
         if (items == null)
 283  
         {
 284  0
             items = new FileItem[1];
 285  0
             items[0] = value;
 286  0
             fileParameters.put(convert(name), items);
 287  
         }
 288  
         else
 289  
         {
 290  0
             FileItem[] newItems = new FileItem[items.length + 1];
 291  0
             System.arraycopy(items, 0, newItems, 0, items.length);
 292  0
             newItems[items.length] = value;
 293  0
             fileParameters.put(convert(name), newItems);
 294  
         }
 295  0
     }
 296  
 
 297  
     /**
 298  
      * Return a FileItem object for the given name.  If the name does
 299  
      * not exist or the object stored is not a FileItem, return null.
 300  
      *
 301  
      * @param name A String with the name.
 302  
      * @return A FileItem.
 303  
      */
 304  
     public FileItem getFileItem(String name)
 305  
     {
 306  
         try
 307  
         {
 308  0
             FileItem value = null;
 309  0
             Object object = fileParameters.get(convert(name));
 310  0
             if (object != null)
 311  
             {
 312  0
                 value = ((FileItem[]) object)[0];
 313  
             }
 314  0
             return value;
 315  
         }
 316  0
         catch (ClassCastException e)
 317  
         {
 318  0
             log.error("Parameter ("
 319  
                     + name + ") is not an instance of FileItem", e);
 320  0
             return null;
 321  
         }
 322  
     }
 323  
 
 324  
     /**
 325  
      * Return an array of FileItem objects for the given name.  If the
 326  
      * name does not exist or the object stored is not a FileItem
 327  
      * array, return null.
 328  
      *
 329  
      * @param name A String with the name.
 330  
      * @return A FileItem[].
 331  
      */
 332  
     public FileItem[] getFileItems(String name)
 333  
     {
 334  
         try
 335  
         {
 336  0
             return (FileItem[]) fileParameters.get(convert(name));
 337  
         }
 338  0
         catch (ClassCastException e)
 339  
         {
 340  0
             log.error("Parameter ("
 341  
                     + name + ") is not an instance of FileItem[]", e);
 342  0
             return null;
 343  
         }
 344  
     }
 345  
 }

This report is generated by jcoverage, Maven and Maven JCoverage Plugin.