Coverage Report - org.mule.transport.http.transformers.ObjectToHttpClientMethodRequest
 
Classes in this File Line Coverage Branch Coverage Complexity
ObjectToHttpClientMethodRequest
64%
96/151
47%
44/94
9.5
 
 1  
 /*
 2  
  * $Id: ObjectToHttpClientMethodRequest.java 12100 2008-06-19 08:58:48Z rossmason $
 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.transport.http.transformers;
 12  
 
 13  
 import org.mule.RequestContext;
 14  
 import org.mule.api.MuleEvent;
 15  
 import org.mule.api.MuleMessage;
 16  
 import org.mule.api.config.MuleProperties;
 17  
 import org.mule.api.transformer.TransformerException;
 18  
 import org.mule.api.transport.OutputHandler;
 19  
 import org.mule.transformer.AbstractMessageAwareTransformer;
 20  
 import org.mule.transport.NullPayload;
 21  
 import org.mule.transport.http.HttpConnector;
 22  
 import org.mule.transport.http.HttpConstants;
 23  
 import org.mule.transport.http.StreamPayloadRequestEntity;
 24  
 import org.mule.transport.http.i18n.HttpMessages;
 25  
 import org.mule.util.StringUtils;
 26  
 import org.mule.util.expression.ExpressionEvaluatorManager;
 27  
 
 28  
 import java.io.InputStream;
 29  
 import java.io.Serializable;
 30  
 import java.io.UnsupportedEncodingException;
 31  
 import java.net.URI;
 32  
 import java.net.URLEncoder;
 33  
 import java.util.Iterator;
 34  
 import java.util.List;
 35  
 import java.util.Map;
 36  
 import java.util.Set;
 37  
 
 38  
 import org.apache.commons.httpclient.HttpMethod;
 39  
 import org.apache.commons.httpclient.HttpVersion;
 40  
 import org.apache.commons.httpclient.methods.ByteArrayRequestEntity;
 41  
 import org.apache.commons.httpclient.methods.DeleteMethod;
 42  
 import org.apache.commons.httpclient.methods.EntityEnclosingMethod;
 43  
 import org.apache.commons.httpclient.methods.GetMethod;
 44  
 import org.apache.commons.httpclient.methods.HeadMethod;
 45  
 import org.apache.commons.httpclient.methods.InputStreamRequestEntity;
 46  
 import org.apache.commons.httpclient.methods.OptionsMethod;
 47  
 import org.apache.commons.httpclient.methods.PostMethod;
 48  
 import org.apache.commons.httpclient.methods.PutMethod;
 49  
 import org.apache.commons.httpclient.methods.StringRequestEntity;
 50  
 import org.apache.commons.httpclient.methods.TraceMethod;
 51  
 import org.apache.commons.httpclient.params.HttpMethodParams;
 52  
 import org.apache.commons.lang.SerializationUtils;
 53  
 
 54  
 /**
 55  
  * <code>ObjectToHttpClientMethodRequest</code> transforms a MuleMessage into a
 56  
  * HttpClient HttpMethod that represents an HttpRequest.
 57  
  */
 58  
 
 59  
 public class ObjectToHttpClientMethodRequest extends AbstractMessageAwareTransformer
 60  
 {
 61  
 
 62  
     public ObjectToHttpClientMethodRequest()
 63  126
     {
 64  126
         setReturnClass(HttpMethod.class);
 65  126
         registerSourceType(MuleMessage.class);
 66  126
         registerSourceType(byte[].class);
 67  126
         registerSourceType(String.class);
 68  126
         registerSourceType(InputStream.class);
 69  126
         registerSourceType(OutputHandler.class);
 70  126
         registerSourceType(NullPayload.class);
 71  126
     }
 72  
 
 73  
     protected int addParameters(String queryString, PostMethod postMethod, MuleMessage msg)
 74  
     {
 75  
         // Parse the HTTP argument list and convert to a NameValuePair
 76  
         // collection
 77  
 
 78  126
         if (StringUtils.isBlank(queryString))
 79  
         {
 80  122
             return 0;
 81  
         }
 82  
 
 83  
         String currentParam;
 84  
         int equals;
 85  4
         equals = queryString.indexOf("&");
 86  4
         if (equals > -1)
 87  
         {
 88  4
             currentParam = queryString.substring(0, equals);
 89  4
             queryString = queryString.substring(equals + 1);
 90  
         }
 91  
         else
 92  
         {
 93  0
             currentParam = queryString;
 94  0
             queryString = StringUtils.EMPTY;
 95  
         }
 96  4
         int parameterIndex = -1;
 97  12
         while (StringUtils.isNotBlank(currentParam))
 98  
         {
 99  
             String paramName, paramValue;
 100  8
             equals = currentParam.indexOf("=");
 101  8
             if (equals > -1)
 102  
             {
 103  8
                 paramName = currentParam.substring(0, equals);
 104  8
                 paramValue = currentParam.substring(equals + 1);
 105  
                 //Run query params through the expression evaluator
 106  
 //                Object temp = ExpressionEvaluatorManager.evaluate(paramValue, msg, "$[", true);
 107  
 //                if (temp != null)
 108  
 //                {
 109  
 //                    //Process param collections
 110  
 //                    if (temp instanceof List)
 111  
 //                    {
 112  
 //                        StringBuffer buf = new StringBuffer();
 113  
 //                        List list = (List) temp;
 114  
 //                        for (Iterator iterator = list.iterator(); iterator.hasNext();)
 115  
 //                        {
 116  
 //                            Object object = iterator.next();
 117  
 //                            buf.append(object).append(",");
 118  
 //                        }
 119  
 //                        parameterIndex++;
 120  
 //                        postMethod.addParameter(paramName, buf.toString());
 121  
 //                    }
 122  
 //                    else if (temp instanceof Map)
 123  
 //                    {
 124  
 //                        Map map = (Map) temp;
 125  
 //                        for (Iterator iterator = map.entrySet().iterator(); iterator.hasNext();)
 126  
 //                        {
 127  
 //                            Map.Entry entry = (Map.Entry) iterator.next();
 128  
 //                            parameterIndex++;
 129  
 //                            postMethod.addParameter(entry.getKey().toString(), entry.getValue().toString());
 130  
 //                        }
 131  
 //                    }
 132  
 //                    else
 133  
 //                    {
 134  
 //                        parameterIndex++;
 135  
 //                        postMethod.addParameter(paramName, temp.toString());
 136  
 //                    }
 137  
 //                }
 138  
 //                else
 139  
 //                {
 140  8
                     parameterIndex++;
 141  8
                     postMethod.addParameter(paramName, paramValue);
 142  
                 //}
 143  
 
 144  
 
 145  
             }
 146  8
             equals = queryString.indexOf("&");
 147  8
             if (equals > -1)
 148  
             {
 149  0
                 currentParam = queryString.substring(0, equals);
 150  0
                 queryString = queryString.substring(equals + 1);
 151  
             }
 152  
             else
 153  
             {
 154  8
                 currentParam = queryString;
 155  8
                 queryString = StringUtils.EMPTY;
 156  
             }
 157  
         }
 158  4
         return parameterIndex + 1;
 159  
     }
 160  
 
 161  
     public Object transform(MuleMessage msg, String outputEncoding) throws TransformerException
 162  
     {
 163  156
         Object src = msg.getPayload();
 164  
 
 165  156
         String endpoint = msg.getStringProperty(MuleProperties.MULE_ENDPOINT_PROPERTY, null);
 166  156
         if (endpoint == null)
 167  
         {
 168  0
             throw new TransformerException(
 169  
                     HttpMessages.eventPropertyNotSetCannotProcessRequest(
 170  
                             MuleProperties.MULE_ENDPOINT_PROPERTY), this);
 171  
         }
 172  
 
 173  156
         String method = msg.getStringProperty(HttpConnector.HTTP_METHOD_PROPERTY, "POST");
 174  
         try
 175  
         {
 176  
             //Allow Expressions to be embedded
 177  156
             endpoint = endpoint.replaceAll("\\[", "\\{");
 178  156
             endpoint = endpoint.replaceAll("\\]", "\\}");
 179  156
             endpoint = ExpressionEvaluatorManager.parse(endpoint, msg, true);
 180  150
             URI uri = new URI(endpoint);
 181  
             HttpMethod httpMethod;
 182  
 
 183  150
             if (HttpConstants.METHOD_GET.equals(method))
 184  
             {
 185  24
                 httpMethod = new GetMethod(uri.toString());
 186  24
                 String paramName = URLEncoder.encode(msg.getStringProperty(HttpConnector.HTTP_GET_BODY_PARAM_PROPERTY,
 187  
                         HttpConnector.DEFAULT_HTTP_GET_BODY_PARAM_PROPERTY), outputEncoding);
 188  24
                 String paramValue = URLEncoder.encode(src.toString(), outputEncoding);
 189  
 
 190  24
                 String query = uri.getRawQuery();
 191  24
                 if (!(src instanceof NullPayload) && !StringUtils.EMPTY.equals(src))
 192  
                 {
 193  2
                     if (query == null)
 194  
                     {
 195  0
                         query = paramName + "=" + paramValue;
 196  
                     }
 197  
                     else
 198  
                     {
 199  2
                         query += "&" + paramName + "=" + paramValue;
 200  
                     }
 201  
                 }
 202  24
                 httpMethod.setQueryString(query);
 203  
 
 204  24
             }
 205  126
             else if (HttpConstants.METHOD_POST.equalsIgnoreCase(method))
 206  
             {
 207  126
                 PostMethod postMethod = new PostMethod(uri.toString());
 208  126
                 String paramName = msg.getStringProperty(HttpConnector.HTTP_POST_BODY_PARAM_PROPERTY, null);
 209  
 
 210  126
                 if (paramName == null)
 211  
                 {
 212  
                     // Call method to manage the parameter array
 213  126
                     addParameters(uri.getQuery(), postMethod, msg);
 214  126
                     setupEntityMethod(src, outputEncoding, msg, uri, postMethod);
 215  
                 }
 216  
                 else
 217  
                 {
 218  0
                     postMethod.addParameter(paramName, src.toString());
 219  
                 }
 220  
 
 221  126
                 httpMethod = postMethod;
 222  126
             }
 223  0
             else if (HttpConstants.METHOD_PUT.equalsIgnoreCase(method))
 224  
             {
 225  0
                 PutMethod putMethod = new PutMethod(uri.toString());
 226  
 
 227  0
                 setupEntityMethod(src, outputEncoding, msg, uri, putMethod);
 228  
 
 229  0
                 httpMethod = putMethod;
 230  0
             }
 231  0
             else if (HttpConstants.METHOD_DELETE.equalsIgnoreCase(method))
 232  
             {
 233  0
                 httpMethod = new DeleteMethod(uri.toString());
 234  
             }
 235  0
             else if (HttpConstants.METHOD_HEAD.equalsIgnoreCase(method))
 236  
             {
 237  0
                 httpMethod = new HeadMethod(uri.toString());
 238  
             }
 239  0
             else if (HttpConstants.METHOD_OPTIONS.equalsIgnoreCase(method))
 240  
             {
 241  0
                 httpMethod = new OptionsMethod(uri.toString());
 242  
             }
 243  0
             else if (HttpConstants.METHOD_TRACE.equalsIgnoreCase(method))
 244  
             {
 245  0
                 httpMethod = new TraceMethod(uri.toString());
 246  
             }
 247  
             else
 248  
             {
 249  0
                 throw new TransformerException(HttpMessages.unsupportedMethod(method));
 250  
             }
 251  
 
 252  
             // Allow the user to set HttpMethodParams as an object on the message
 253  150
             HttpMethodParams params = (HttpMethodParams) msg.removeProperty(HttpConnector.HTTP_PARAMS_PROPERTY);
 254  150
             if (params != null)
 255  
             {
 256  2
                 httpMethod.setParams(params);
 257  
             }
 258  
             else
 259  
             {
 260  
                 // TODO we should probably set other properties here
 261  148
                 String httpVersion = msg.getStringProperty(HttpConnector.HTTP_VERSION_PROPERTY,
 262  
                         HttpConstants.HTTP11);
 263  148
                 if (HttpConstants.HTTP10.equals(httpVersion))
 264  
                 {
 265  0
                     httpMethod.getParams().setVersion(HttpVersion.HTTP_1_0);
 266  
                 }
 267  
                 else
 268  
                 {
 269  148
                     httpMethod.getParams().setVersion(HttpVersion.HTTP_1_1);
 270  
                 }
 271  
             }
 272  
 
 273  150
             setHeaders(httpMethod, msg);
 274  
 
 275  150
             return httpMethod;
 276  
         }
 277  6
         catch (Exception e)
 278  
         {
 279  6
             throw new TransformerException(this, e);
 280  
         }
 281  
     }
 282  
 
 283  
     protected void setupEntityMethod(Object src,
 284  
                                      String encoding,
 285  
                                      MuleMessage msg,
 286  
                                      URI uri,
 287  
                                      EntityEnclosingMethod postMethod)
 288  
             throws UnsupportedEncodingException, TransformerException
 289  
     {
 290  
         // Dont set a POST payload if the body is a Null Payload.
 291  
         // This way client calls
 292  
         // can control if a POST body is posted explicitly
 293  126
         if (!(msg.getPayload() instanceof NullPayload))
 294  
         {
 295  
             // See if we have a MIME type set
 296  122
             String mimeType = msg.getStringProperty(HttpConstants.HEADER_CONTENT_TYPE, null);
 297  
 
 298  122
             if (src instanceof String)
 299  
             {
 300  
                 // Ensure that we strip the encoding information from the
 301  
                 // encoding type
 302  120
                 if (mimeType != null)
 303  
                 {
 304  6
                     int parameterIndex = mimeType.indexOf(";");
 305  6
                     if (parameterIndex > 0)
 306  
                     {
 307  4
                         mimeType = mimeType.substring(0, parameterIndex);
 308  
                     }
 309  
                 }
 310  120
                 if (mimeType == null)
 311  
                 {
 312  114
                     mimeType = HttpConstants.DEFAULT_CONTENT_TYPE;
 313  
                 }
 314  
 
 315  120
                 postMethod.setRequestEntity(new StringRequestEntity(src.toString(), mimeType,
 316  
                         encoding));
 317  120
                 return;
 318  
             }
 319  
 
 320  
 
 321  2
             if (mimeType == null)
 322  
             {
 323  2
                 mimeType = HttpConstants.DEFAULT_CONTENT_TYPE;
 324  
             }
 325  
 
 326  2
             if (encoding != null
 327  
                     && !"UTF-8".equals(encoding.toUpperCase())
 328  
                     && mimeType.indexOf("charset") == -1)
 329  
             {
 330  2
                 mimeType += "; charset=" + encoding;
 331  
             }
 332  
 
 333  2
             if (src instanceof InputStream)
 334  
             {
 335  
                 // TODO Danger here! We don't know if the content is
 336  
                 // really text or not
 337  0
                 if (mimeType == null)
 338  
                 {
 339  0
                     mimeType = HttpConstants.DEFAULT_CONTENT_TYPE;
 340  
                 }
 341  0
                 postMethod.setRequestEntity(new InputStreamRequestEntity((InputStream) src,
 342  
                         mimeType));
 343  
             }
 344  2
             else if (src instanceof byte[])
 345  
             {
 346  2
                 if (mimeType == null)
 347  
                 {
 348  0
                     mimeType = HttpConstants.DEFAULT_CONTENT_TYPE;
 349  
                 }
 350  2
                 postMethod.setRequestEntity(new ByteArrayRequestEntity((byte[]) src,
 351  
                         mimeType));
 352  
             }
 353  0
             else if (src instanceof OutputHandler)
 354  
             {
 355  0
                 MuleEvent event = RequestContext.getEvent();
 356  0
                 postMethod.setRequestEntity(new StreamPayloadRequestEntity((OutputHandler) src, event));
 357  0
             }
 358  
             else
 359  
             {
 360  0
                 if (mimeType == null)
 361  
                 {
 362  0
                     mimeType = HttpConstants.DEFAULT_CONTENT_TYPE;
 363  
                 }
 364  
 
 365  0
                 byte[] buffer = SerializationUtils.serialize((Serializable) src);
 366  0
                 postMethod.setRequestEntity(new ByteArrayRequestEntity(buffer, mimeType));
 367  
             }
 368  
         }
 369  
 
 370  6
     }
 371  
 
 372  
     protected void setHeaders(HttpMethod httpMethod, MuleMessage msg)
 373  
     {
 374  
         // Standard requestHeaders
 375  
         String headerValue;
 376  
         String headerName;
 377  150
         for (Iterator iterator = msg.getPropertyNames().iterator(); iterator.hasNext();)
 378  
         {
 379  330
             headerName = (String) iterator.next();
 380  
 
 381  330
             headerValue = msg.getStringProperty(headerName, null);
 382  330
             if (HttpConstants.REQUEST_HEADER_NAMES.get(headerName) == null)
 383  
             {
 384  330
                 if (headerName.startsWith(MuleProperties.PROPERTY_PREFIX))
 385  
                 {
 386  280
                     headerName = new StringBuffer(30).append("X-").append(headerName).toString();
 387  
                 }
 388  
 
 389  330
                 httpMethod.addRequestHeader(headerName, headerValue);
 390  
             }
 391  
         }
 392  
 
 393  150
         Map customHeaders = (Map) msg.getProperty(HttpConnector.HTTP_CUSTOM_HEADERS_MAP_PROPERTY);
 394  150
         if (customHeaders != null)
 395  
         {
 396  
             Map.Entry entry;
 397  0
             for (Iterator iterator = customHeaders.entrySet().iterator(); iterator.hasNext();)
 398  
             {
 399  0
                 entry = (Map.Entry) iterator.next();
 400  0
                 if (entry.getValue() != null)
 401  
                 {
 402  0
                     httpMethod.addRequestHeader(entry.getKey().toString(), entry.getValue().toString());
 403  
                 }
 404  
             }
 405  
         }
 406  
 
 407  150
         Set attNams = msg.getAttachmentNames();
 408  150
         if (msg.getPayload() instanceof InputStream
 409  
                 && attNams != null && attNams.size() > 0)
 410  
         {
 411  
             // must set this for receiver to properly parse attachments
 412  0
             httpMethod.addRequestHeader(HttpConstants.HEADER_CONTENT_TYPE, "multipart/related");
 413  
         }
 414  150
     }
 415  
 
 416  
     protected String paramToString(Object param)
 417  
     {
 418  0
         StringBuffer buf = new StringBuffer();
 419  0
         if (param instanceof List)
 420  
         {
 421  0
             List list = (List) param;
 422  0
             for (Iterator iterator = list.iterator(); iterator.hasNext();)
 423  
             {
 424  0
                 Object object = iterator.next();
 425  0
                 buf.append(object).append(",");
 426  0
             }
 427  0
             return buf.toString();
 428  
         }
 429  0
         else if (param instanceof Map)
 430  
         {
 431  0
             Map map = (Map) param;
 432  0
             for (Iterator iterator = map.entrySet().iterator(); iterator.hasNext();)
 433  
             {
 434  0
                 Map.Entry entry = (Map.Entry) iterator.next();
 435  0
                 buf.append(entry.getKey()).append("=").append(entry.getValue()).append("&");
 436  0
             }
 437  0
             return buf.toString().substring(0, buf.length() - 1);
 438  
         }
 439  
         else
 440  
         {
 441  0
             return param.toString();
 442  
         }
 443  
     }
 444  
 }