Coverage Report - org.mule.providers.http.transformers.ObjectToHttpClientMethodRequest
 
Classes in this File Line Coverage Branch Coverage Complexity
ObjectToHttpClientMethodRequest
59%
63/107
53%
35/66
8.4
 
 1  
 /*
 2  
  * $Id: ObjectToHttpClientMethodRequest.java 11728 2008-05-13 07:31:11Z dirk.olmes $
 3  
  * --------------------------------------------------------------------------------------
 4  
  * Copyright (c) MuleSource, Inc.  All rights reserved.  http://www.mulesource.com
 5  
  *
 6  
  * The software in this package is published under the terms of the CPAL v1.0
 7  
  * license, a copy of which has been included with this distribution in the
 8  
  * LICENSE.txt file.
 9  
  */
 10  
 
 11  
 package org.mule.providers.http.transformers;
 12  
 
 13  
 import org.mule.MuleManager;
 14  
 import org.mule.config.MuleProperties;
 15  
 import org.mule.providers.NullPayload;
 16  
 import org.mule.providers.http.HttpConnector;
 17  
 import org.mule.providers.http.HttpConstants;
 18  
 import org.mule.providers.http.i18n.HttpMessages;
 19  
 import org.mule.transformers.AbstractEventAwareTransformer;
 20  
 import org.mule.transformers.simple.SerializableToByteArray;
 21  
 import org.mule.umo.UMOEventContext;
 22  
 import org.mule.umo.UMOMessage;
 23  
 import org.mule.umo.transformer.TransformerException;
 24  
 import org.mule.util.StringUtils;
 25  
 
 26  
 import java.io.InputStream;
 27  
 import java.io.UnsupportedEncodingException;
 28  
 import java.net.URI;
 29  
 import java.net.URLEncoder;
 30  
 import java.util.Iterator;
 31  
 
 32  
 import org.apache.commons.httpclient.HttpMethod;
 33  
 import org.apache.commons.httpclient.HttpVersion;
 34  
 import org.apache.commons.httpclient.methods.ByteArrayRequestEntity;
 35  
 import org.apache.commons.httpclient.methods.DeleteMethod;
 36  
 import org.apache.commons.httpclient.methods.EntityEnclosingMethod;
 37  
 import org.apache.commons.httpclient.methods.GetMethod;
 38  
 import org.apache.commons.httpclient.methods.HeadMethod;
 39  
 import org.apache.commons.httpclient.methods.InputStreamRequestEntity;
 40  
 import org.apache.commons.httpclient.methods.OptionsMethod;
 41  
 import org.apache.commons.httpclient.methods.PostMethod;
 42  
 import org.apache.commons.httpclient.methods.PutMethod;
 43  
 import org.apache.commons.httpclient.methods.StringRequestEntity;
 44  
 import org.apache.commons.httpclient.methods.TraceMethod;
 45  
 import org.apache.commons.httpclient.params.HttpMethodParams;
 46  
 
 47  
 /**
 48  
  * <code>ObjectToHttpClientMethodRequest</code> transforms a UMOMessage into a
 49  
  * HttpClient HttpMethod that represents an HttpRequest.
 50  
  */
 51  
 
 52  
 public class ObjectToHttpClientMethodRequest extends AbstractEventAwareTransformer
 53  
 {
 54  
     private final SerializableToByteArray serializableToByteArray;
 55  
 
 56  
     public ObjectToHttpClientMethodRequest()
 57  146
     {
 58  148
         setReturnClass(HttpMethod.class);
 59  146
         serializableToByteArray = new SerializableToByteArray();
 60  146
     }
 61  
 
 62  
     private int addParameters(String queryString, PostMethod postMethod)
 63  
     {
 64  
         // Parse the HTTP argument list and convert to a NameValuePair
 65  
         // collection
 66  
 
 67  122
         if (StringUtils.isEmpty(queryString))
 68  
         {
 69  122
             return 0;
 70  
         }
 71  
 
 72  
         String currentParam;
 73  
         int equals;
 74  0
         equals = queryString.indexOf("&");
 75  0
         if (equals > -1)
 76  
         {
 77  0
             currentParam = queryString.substring(0, equals);
 78  0
             queryString = queryString.substring(equals + 1);
 79  
         }
 80  
         else
 81  
         {
 82  0
             currentParam = queryString;
 83  0
             queryString = StringUtils.EMPTY;
 84  
         }
 85  0
         int parameterIndex = -1;
 86  0
         while (StringUtils.isNotBlank(currentParam))
 87  
         {
 88  
             String paramName, paramValue;
 89  0
             equals = currentParam.indexOf("=");
 90  0
             if (equals > -1)
 91  
             {
 92  0
                 paramName = currentParam.substring(0, equals);
 93  0
                 paramValue = currentParam.substring(equals + 1);
 94  0
                 parameterIndex++;
 95  0
                 postMethod.addParameter(paramName, paramValue);
 96  
             }
 97  0
             equals = queryString.indexOf("&");
 98  0
             if (equals > -1)
 99  
             {
 100  0
                 currentParam = queryString.substring(0, equals);
 101  0
                 queryString = queryString.substring(equals + 1);
 102  
             }
 103  
             else
 104  
             {
 105  0
                 currentParam = queryString;
 106  0
                 queryString = StringUtils.EMPTY;
 107  
             }
 108  
         }
 109  0
         return parameterIndex + 1;
 110  
     }
 111  
 
 112  
     public Object transform(Object src, String encoding, UMOEventContext context) throws TransformerException
 113  
     {
 114  134
         UMOMessage msg = context.getMessage();
 115  
 
 116  134
         String endpoint = msg.getStringProperty(MuleProperties.MULE_ENDPOINT_PROPERTY, null);
 117  134
         if (endpoint == null)
 118  
         {
 119  0
             throw new TransformerException(
 120  
                 HttpMessages.eventPropertyNotSetCannotProcessRequest(MuleProperties.MULE_ENDPOINT_PROPERTY),
 121  
                 this);
 122  
         }
 123  
 
 124  134
         String method = msg.getStringProperty(HttpConnector.HTTP_METHOD_PROPERTY, "POST");
 125  
         try
 126  
         {
 127  134
             URI uri = new URI(endpoint);
 128  134
             HttpMethod httpMethod = null;
 129  
 
 130  134
             if (HttpConstants.METHOD_GET.equals(method))
 131  
             {
 132  12
                 httpMethod = new GetMethod(uri.toString());
 133  
 
 134  12
                 String paramName = URLEncoder.encode(msg.getStringProperty(
 135  
                     HttpConnector.HTTP_GET_BODY_PARAM_PROPERTY,
 136  
                     HttpConnector.DEFAULT_HTTP_GET_BODY_PARAM_PROPERTY), encoding);
 137  12
                 String paramValue = URLEncoder.encode(src.toString(), encoding);
 138  
 
 139  
                 // MULE-3236: use the raw query here so that properly encoded parameters from the 
 140  
                 // config file stay intact
 141  12
                 String query = uri.getRawQuery();
 142  12
                 if (!(src instanceof NullPayload) && !StringUtils.EMPTY.equals(src))
 143  
                 {
 144  2
                     if (query == null)
 145  
                     {
 146  0
                         query = paramName + "=" + paramValue;
 147  
                     }
 148  
                     else
 149  
                     {
 150  2
                         query += "&" + paramName + "=" + paramValue;
 151  
                     }
 152  
                 }
 153  12
                 httpMethod.setQueryString(query);
 154  12
             }
 155  122
             else if (HttpConstants.METHOD_POST.equalsIgnoreCase(method))
 156  
             {
 157  122
                 PostMethod postMethod = new PostMethod(uri.toString());
 158  
 
 159  122
                 String paramName = msg.getStringProperty(HttpConnector.HTTP_POST_BODY_PARAM_PROPERTY, null);
 160  
 
 161  122
                 if (paramName == null)
 162  
                 {
 163  
                     // Call method to manage the parameter array
 164  122
                     addParameters(uri.getQuery(), postMethod);
 165  122
                     setupEntityMethod(src, encoding, context, msg, uri, postMethod);
 166  
                 }
 167  
                 else
 168  
                 {
 169  0
                     postMethod.addParameter(paramName, src.toString());
 170  
                 }
 171  
 
 172  122
                 httpMethod = postMethod;
 173  122
             }
 174  0
             else if (HttpConstants.METHOD_PUT.equalsIgnoreCase(method))
 175  
             {
 176  0
                 PutMethod putMethod = new PutMethod(uri.toString());
 177  
 
 178  0
                 setupEntityMethod(src, encoding, context, msg, uri, putMethod);
 179  
 
 180  0
                 httpMethod = putMethod;
 181  0
             }
 182  0
             else if (HttpConstants.METHOD_DELETE.equalsIgnoreCase(method))
 183  
             {
 184  0
                 httpMethod = new DeleteMethod(uri.toString());
 185  
             }
 186  0
             else if (HttpConstants.METHOD_HEAD.equalsIgnoreCase(method))
 187  
             {
 188  0
                 httpMethod = new HeadMethod(uri.toString());
 189  
             }
 190  0
             else if (HttpConstants.METHOD_OPTIONS.equalsIgnoreCase(method))
 191  
             {
 192  0
                 httpMethod = new OptionsMethod(uri.toString());
 193  
             }
 194  0
             else if (HttpConstants.METHOD_TRACE.equalsIgnoreCase(method))
 195  
             {
 196  0
                 httpMethod = new TraceMethod(uri.toString());
 197  
             }
 198  
             else
 199  
             {
 200  0
                 throw new TransformerException(HttpMessages.unsupportedMethod(method));
 201  
             }
 202  
 
 203  
             // Allow the user to set HttpMethodParams as an object on the message
 204  134
             HttpMethodParams params = (HttpMethodParams) msg.removeProperty(HttpConnector.HTTP_PARAMS_PROPERTY);
 205  134
             if (params != null)
 206  
             {
 207  2
                 httpMethod.setParams(params);
 208  
             }
 209  
             else
 210  
             {
 211  
                 // TODO we should propbably set other propserties here
 212  132
                 String httpVersion = msg.getStringProperty(HttpConnector.HTTP_VERSION_PROPERTY,
 213  
                     HttpConstants.HTTP11);
 214  132
                 if (HttpConstants.HTTP10.equals(httpVersion))
 215  
                 {
 216  0
                     httpMethod.getParams().setVersion(HttpVersion.HTTP_1_0);
 217  
                 }
 218  
                 else
 219  
                 {
 220  132
                     httpMethod.getParams().setVersion(HttpVersion.HTTP_1_1);
 221  
                 }
 222  
             }
 223  134
             setHeaders(httpMethod, context);
 224  
 
 225  134
             return httpMethod;
 226  
         }
 227  0
         catch (Exception e)
 228  
         {
 229  0
             throw new TransformerException(this, e);
 230  
         }
 231  
     }
 232  
 
 233  
     private void setupEntityMethod(Object src,
 234  
                                    String encoding,
 235  
                                    UMOEventContext context,
 236  
                                    UMOMessage msg,
 237  
                                    URI uri,
 238  
                                    EntityEnclosingMethod postMethod)
 239  
         throws UnsupportedEncodingException, TransformerException
 240  
     {
 241  
         // Dont set a POST payload if the body is a Null Payload.
 242  
         // This way client calls
 243  
         // can control if a POST body is posted explicitly
 244  122
         if (!(context.getMessage().getPayload() instanceof NullPayload))
 245  
         {
 246  
             // See if we have a MIME type set
 247  122
             String mimeType = msg.getStringProperty(HttpConstants.HEADER_CONTENT_TYPE, null);
 248  
 
 249  122
             if (src instanceof String)
 250  
             {
 251  
                 // Ensure that we strip the encoding information from the
 252  
                 // encoding type
 253  118
                 if (mimeType != null)
 254  
                 {
 255  20
                     int parameterIndex = mimeType.indexOf(";");
 256  20
                     if (parameterIndex > 0)
 257  
                     {
 258  12
                         mimeType = mimeType.substring(0, parameterIndex);
 259  
                     }
 260  
                 }
 261  118
                 if (mimeType == null) mimeType = HttpConstants.DEFAULT_CONTENT_TYPE;
 262  118
                 if (encoding == null) encoding = MuleManager.getConfiguration().getEncoding();
 263  118
                 postMethod.setRequestEntity(new StringRequestEntity(src.toString(), mimeType, encoding));
 264  
             }
 265  4
             else if (src instanceof InputStream)
 266  
             {
 267  
                 // TODO Danger here! We don't know if the content is
 268  
                 // really text or not
 269  0
                 if (mimeType == null) mimeType = HttpConstants.DEFAULT_CONTENT_TYPE;
 270  0
                 postMethod.setRequestEntity(new InputStreamRequestEntity((InputStream) src, mimeType));
 271  
             }
 272  
             else
 273  
             {
 274  
                 // TODO Danger here! We don't know if the content is
 275  
                 // really text or not
 276  4
                 if (mimeType == null) mimeType = HttpConstants.DEFAULT_CONTENT_TYPE;
 277  4
                 byte[] buffer = (byte[]) serializableToByteArray.doTransform(src, encoding);
 278  4
                 postMethod.setRequestEntity(new ByteArrayRequestEntity(buffer, mimeType));
 279  
             }
 280  
         }
 281  122
     }
 282  
 
 283  
     protected void setHeaders(HttpMethod httpMethod, UMOEventContext context)
 284  
     {
 285  
         // Standard requestHeaders
 286  
         String headerValue;
 287  
         String headerName;
 288  134
         UMOMessage msg = context.getMessage();
 289  134
         for (Iterator iterator = msg.getPropertyNames().iterator(); iterator.hasNext();)
 290  
         {
 291  342
             headerName = (String) iterator.next();
 292  
 
 293  342
             headerValue = msg.getStringProperty(headerName, null);
 294  342
             if (HttpConstants.REQUEST_HEADER_NAMES.get(headerName) == null)
 295  
             {
 296  336
                 if (headerName.startsWith(MuleProperties.PROPERTY_PREFIX))
 297  
                 {
 298  266
                     headerName = new StringBuffer(30).append("X-").append(headerName).toString();
 299  
                 }
 300  
 
 301  336
                 httpMethod.addRequestHeader(headerName, headerValue);
 302  
             }
 303  
         }
 304  
 
 305  134
         if (context.getMessage().getPayload() instanceof InputStream)
 306  
         {
 307  
             // must set this for receiver to properly parse attachments
 308  0
             httpMethod.addRequestHeader(HttpConstants.HEADER_CONTENT_TYPE, "multipart/related");
 309  
         }
 310  134
     }
 311  
 }