Coverage Report - org.mule.transport.servlet.ServletMuleMessageFactory
 
Classes in this File Line Coverage Branch Coverage Complexity
ServletMuleMessageFactory
0%
0/108
0%
0/44
0
 
 1  
 /*
 2  
  * $Id: ServletMuleMessageFactory.java 20109 2010-11-07 05:20:30Z mike.schilling $
 3  
  * --------------------------------------------------------------------------------------
 4  
  * Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.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.servlet;
 12  
 
 13  
 import org.mule.DefaultMuleMessage;
 14  
 import org.mule.api.MuleContext;
 15  
 import org.mule.api.MuleMessage;
 16  
 import org.mule.transport.AbstractMuleMessageFactory;
 17  
 import org.mule.transport.http.HttpConstants;
 18  
 
 19  
 import java.util.Enumeration;
 20  
 import java.util.HashMap;
 21  
 import java.util.List;
 22  
 import java.util.Map;
 23  
 
 24  
 import javax.servlet.http.HttpServletRequest;
 25  
 import javax.servlet.http.HttpSession;
 26  
 
 27  
 import org.apache.commons.collections.EnumerationUtils;
 28  
 
 29  
 public class ServletMuleMessageFactory extends AbstractMuleMessageFactory
 30  
 {
 31  
     private static final String REMOTE_ADDRESS_HEADER = "remoteAddress";
 32  
 
 33  
     public ServletMuleMessageFactory(MuleContext context)
 34  
     {
 35  0
         super(context);
 36  0
     }
 37  
 
 38  
     @Override
 39  
     protected Class<?>[] getSupportedTransportMessageTypes()
 40  
     {
 41  0
         return new Class[] { HttpServletRequest.class };
 42  
     }
 43  
 
 44  
     @Override
 45  
     protected Object extractPayload(Object transportMessage, String encoding) throws Exception
 46  
     {
 47  0
         HttpServletRequest request = (HttpServletRequest) transportMessage;
 48  
 
 49  0
         String method = request.getMethod();
 50  0
         if (HttpConstants.METHOD_GET.equalsIgnoreCase(method))
 51  
         {
 52  0
             return queryString(request);
 53  
         }
 54  
         else
 55  
         {
 56  0
             return extractPayloadFromPostRequest(request);
 57  
         }
 58  
     }
 59  
 
 60  
     protected Object extractPayloadFromPostRequest(HttpServletRequest request) throws Exception
 61  
     {
 62  
         /*
 63  
          * Servlet Spec v2.5:
 64  
          *
 65  
          * SRV.3.1.1
 66  
          * When Parameters Are Available
 67  
          *
 68  
          * The following are the conditions that must be met before post form data will
 69  
          * be populated to the parameter set:
 70  
          *
 71  
          * 1. The request is an HTTP or HTTPS request.
 72  
          * 2. The HTTP method is POST.
 73  
          * 3. The content type is application/x-www-form-urlencoded.
 74  
          * 4. The servlet has made an initial call of any of the getParameter family of meth-
 75  
          *    ods on the request object.
 76  
          * 
 77  
          * If the conditions are not met and the post form data is not included in the
 78  
          * parameter set, the post data must still be available to the servlet via the request
 79  
          * object's input stream. If the conditions are met, post form data will no longer be
 80  
          * available for reading directly from the request object's input stream.
 81  
          *
 82  
          * -----------------------------------------------------------------------------------
 83  
          *
 84  
          * In plain english:if you call getInputStream on a POSTed request before you call one of
 85  
          * the getParameter* methods, you'll lose the parameters. So we touch the parameters first
 86  
          * and only then we return the input stream that will be the payload of the message.
 87  
          */
 88  0
         request.getParameterNames();
 89  
 
 90  0
         return request.getInputStream();
 91  
     }
 92  
 
 93  
     protected String queryString(HttpServletRequest request)
 94  
     {
 95  0
         StringBuilder buf = new StringBuilder(request.getRequestURI());
 96  
 
 97  0
         String queryString = request.getQueryString();
 98  0
         if (queryString != null)
 99  
         {
 100  0
             buf.append("?");
 101  0
             buf.append(queryString);
 102  
         }
 103  
 
 104  0
         return buf.toString();
 105  
     }
 106  
 
 107  
     @Override
 108  
     protected void addProperties(DefaultMuleMessage message, Object transportMessage) throws Exception
 109  
     {
 110  0
         HttpServletRequest request = (HttpServletRequest) transportMessage;
 111  
 
 112  0
         setupRequestParameters(request, message);
 113  0
         setupEncoding(request, message);
 114  0
         setupSessionId(request, message);
 115  0
         setupContentType(request, message);
 116  0
         setupCharacterEncoding(request, message);
 117  0
         setupRemoteAddress(request, message);
 118  0
         setupMessageProperties(request, message);
 119  0
     }
 120  
 
 121  
     @SuppressWarnings("unchecked")
 122  
     protected void setupRequestParameters(HttpServletRequest request, DefaultMuleMessage message)
 123  
     {
 124  0
         Enumeration<String> parameterNames = request.getParameterNames();
 125  0
         if (parameterNames != null)
 126  
         {
 127  0
             Map<String, Object> parameterProperties = new HashMap<String, Object>();
 128  0
             Map<String, Object> parameterMap = new HashMap<String, Object>();
 129  0
             while (parameterNames.hasMoreElements())
 130  
             {
 131  0
                 String name = parameterNames.nextElement();
 132  0
                 String key = ServletConnector.PARAMETER_PROPERTY_PREFIX + name;
 133  0
                 String value = request.getParameterValues(name)[0];
 134  
 
 135  0
                 parameterProperties.put(key, value);
 136  0
                 parameterMap.put(name, value);
 137  0
             }
 138  
 
 139  
             // support for the HttpRequestToParameterMap transformer: put the map of request
 140  
             // parameters under a well defined key into the message properties as well
 141  0
             parameterProperties.put(ServletConnector.PARAMETER_MAP_PROPERTY_KEY, parameterMap);
 142  
 
 143  0
             message.addInboundProperties(parameterProperties);
 144  
         }
 145  0
     }
 146  
 
 147  
     protected void setupEncoding(HttpServletRequest request, MuleMessage message)
 148  
     {
 149  0
         String contentType = request.getContentType();
 150  0
         if (contentType != null)
 151  
         {
 152  0
             int index = contentType.indexOf("charset");
 153  0
             if (index > -1)
 154  
             {
 155  0
                 int semicolonIndex = contentType.lastIndexOf(";");
 156  0
                 if (semicolonIndex > index)
 157  
                 {
 158  0
                     message.setEncoding(contentType.substring(index + 8, semicolonIndex));
 159  
                 }
 160  
                 else
 161  
                 {
 162  0
                     message.setEncoding(contentType.substring(index + 8));
 163  
                 }
 164  
             }
 165  
         }
 166  0
     }
 167  
 
 168  
     protected void setupSessionId(HttpServletRequest request, MuleMessage message)
 169  
     {
 170  
         try
 171  
         {
 172  
             // We wrap this call as on some App Servers (Websphere) it can cause an NPE
 173  0
             HttpSession session = request.getSession(false);
 174  0
             if (session != null)
 175  
             {
 176  0
                 ((DefaultMuleMessage) message).setInboundProperty(ServletConnector.SESSION_ID_PROPERTY_KEY, session.getId());
 177  
             }
 178  
         }
 179  0
         catch (Exception e)
 180  
         {
 181  
             // C'est la vie
 182  0
         }
 183  0
     }
 184  
 
 185  
     protected void setupContentType(HttpServletRequest request, DefaultMuleMessage message)
 186  
     {
 187  0
         String contentType = request.getContentType();
 188  
         
 189  0
         Map<String, Object> properties = new HashMap<String, Object>();
 190  0
         properties.put(ServletConnector.CONTENT_TYPE_PROPERTY_KEY, contentType);
 191  
      
 192  0
         message.addInboundProperties(properties);
 193  0
     }
 194  
     
 195  
     protected void setupCharacterEncoding(HttpServletRequest request, DefaultMuleMessage message)
 196  
     {
 197  0
         String characterEncoding = request.getCharacterEncoding();
 198  
         
 199  0
         Map<String, Object> properties = new HashMap<String, Object>();
 200  0
         properties.put(ServletConnector.CHARACTER_ENCODING_PROPERTY_KEY, characterEncoding);
 201  
      
 202  0
         message.addInboundProperties(properties);
 203  0
     }
 204  
     
 205  
     protected void setupRemoteAddress(HttpServletRequest request, DefaultMuleMessage message)
 206  
     {
 207  0
         message.setInboundProperty(REMOTE_ADDRESS_HEADER, request.getRemoteAddr());
 208  0
     }
 209  
 
 210  
     protected void setupMessageProperties(HttpServletRequest request, DefaultMuleMessage message)
 211  
     {
 212  0
         Map<String, Object> messageProperties = new HashMap<String, Object>();
 213  
         
 214  0
         copyParameters(request, messageProperties);
 215  0
         copyAttributes(request, messageProperties);
 216  0
         copyHeaders(request, messageProperties);
 217  
         
 218  0
         message.addInboundProperties(messageProperties);
 219  0
     }
 220  
 
 221  
     protected void copyParameters(HttpServletRequest request, Map<String, Object> messageProperties)
 222  
     {
 223  0
         Map<?, ?> parameterMap = request.getParameterMap();
 224  0
         if (parameterMap != null && parameterMap.size() > 0)
 225  
         {
 226  0
             for (Map.Entry<?, ?> entry : parameterMap.entrySet())
 227  
             {
 228  0
                 String key = (String) entry.getKey();
 229  0
                 Object value = entry.getValue();
 230  0
                 if (value != null)
 231  
                 {
 232  0
                     if (value.getClass().isArray() && ((Object[]) value).length == 1)
 233  
                     {
 234  0
                         value = ((Object[]) value)[0];
 235  
                     }
 236  
                 }
 237  
                 
 238  0
                 messageProperties.put(key, value);
 239  0
             }
 240  
         }
 241  0
     }
 242  
 
 243  
     protected void copyAttributes(HttpServletRequest request, Map<String, Object> messageProperties)
 244  
     {
 245  0
         for (Enumeration<?> e = request.getAttributeNames(); e.hasMoreElements();)
 246  
         {
 247  0
             String key = (String) e.nextElement();
 248  0
             messageProperties.put(key, request.getAttribute(key));
 249  0
         }
 250  0
     }
 251  
     
 252  
     protected void copyHeaders(HttpServletRequest request, Map<String, Object> messageProperties)
 253  
     {
 254  0
         for (Enumeration<?> e = request.getHeaderNames(); e.hasMoreElements();)
 255  
         {
 256  0
             String key = (String)e.nextElement();
 257  0
             String realKey = key;
 258  
             
 259  0
             if (key.startsWith(HttpConstants.X_PROPERTY_PREFIX))
 260  
             {
 261  0
                 realKey = key.substring(2);
 262  
             }
 263  
 
 264  
             // Workaround for containers that strip the port from the Host header.
 265  
             // This is needed so Mule components can figure out what port they're on.
 266  0
             if (HttpConstants.HEADER_HOST.equalsIgnoreCase(key))
 267  
             {
 268  0
                 realKey = HttpConstants.HEADER_HOST;
 269  
 
 270  0
                 String value = request.getHeader(key);
 271  0
                 int port = request.getLocalPort();
 272  0
                 if (!value.contains(":") && port != 80 && port != 443)
 273  
                 {
 274  0
                     value = value + ":" + port;
 275  
                 }
 276  0
                 messageProperties.put(realKey, value);
 277  0
             }
 278  
             else
 279  
             {
 280  0
                 Enumeration<?> valueEnum = request.getHeaders(key);
 281  0
                 List<?> values = EnumerationUtils.toList(valueEnum);
 282  0
                 if (values.size() > 1)
 283  
                 {
 284  0
                     messageProperties.put(realKey, values.toArray());
 285  
                 }
 286  
                 else
 287  
                 {
 288  0
                     messageProperties.put(realKey, values.get(0));
 289  
                 }
 290  
             }
 291  0
         }
 292  0
     }
 293  
 }