View Javadoc

1   /*
2    * $Id: HttpRequestMessageAdapter.java 7976 2007-08-21 14:26:13Z 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.servlet;
12  
13  import org.mule.config.MuleProperties;
14  import org.mule.config.i18n.CoreMessages;
15  import org.mule.impl.ThreadSafeAccess;
16  import org.mule.providers.AbstractMessageAdapter;
17  import org.mule.providers.http.HttpConstants;
18  import org.mule.providers.http.i18n.ServletMessages;
19  import org.mule.umo.MessagingException;
20  import org.mule.umo.provider.MessageTypeNotSupportedException;
21  import org.mule.umo.provider.UniqueIdNotSupportedException;
22  import org.mule.util.SystemUtils;
23  
24  import java.io.BufferedReader;
25  import java.io.IOException;
26  import java.util.Enumeration;
27  import java.util.Iterator;
28  import java.util.Map;
29  
30  import javax.servlet.http.HttpServletRequest;
31  import javax.servlet.http.HttpSession;
32  
33  import org.apache.commons.io.IOUtils;
34  import org.apache.commons.io.output.ByteArrayOutputStream;
35  
36  /**
37   * <code>HttpRequestMessageAdapter</code> is a Mule message adapter for
38   * javax.servletHttpServletRequest objects.
39   */
40  
41  public class HttpRequestMessageAdapter extends AbstractMessageAdapter
42  {
43      /**
44       * Serial version
45       */
46      private static final long serialVersionUID = -4238448252206941125L;
47  
48      private Object message = null;
49  
50      private HttpServletRequest request;
51  
52      public HttpRequestMessageAdapter(Object message) throws MessagingException
53      {
54          if (message instanceof HttpServletRequest)
55          {
56              setPayload((HttpServletRequest)message);
57              final Map parameterMap = request.getParameterMap();
58              if (parameterMap != null && parameterMap.size() > 0)
59              {
60                  for (Iterator iterator = parameterMap.entrySet().iterator(); iterator.hasNext();)
61                  {
62                      Map.Entry entry = (Map.Entry)iterator.next();
63                      String key = (String)entry.getKey();
64                      Object value = entry.getValue();
65                      if (value != null)
66                      {
67                          if (value.getClass().isArray() && ((Object[])value).length == 1)
68                          {
69                              setProperty(key, ((Object[])value)[0]);
70                          }
71                          else
72                          {
73                              setProperty(key, value);
74                          }
75                      }
76                  }
77              }
78              String key;
79              for (Enumeration e = request.getAttributeNames(); e.hasMoreElements();)
80              {
81                  key = (String)e.nextElement();
82                  properties.put(key, request.getAttribute(key));
83              }
84              String realKey;
85              for (Enumeration e = request.getHeaderNames(); e.hasMoreElements();)
86              {
87                  key = (String)e.nextElement();
88                  realKey = key;
89                  if (key.startsWith(HttpConstants.X_PROPERTY_PREFIX))
90                  {
91                      realKey = key.substring(2);
92                  }
93                  setProperty(realKey, request.getHeader(key));
94              }
95          }
96          else
97          {
98              throw new MessageTypeNotSupportedException(message, getClass());
99          }
100     }
101 
102     protected HttpRequestMessageAdapter(HttpRequestMessageAdapter template)
103     {
104         super(template);
105         message = template.message;
106         request = template.request;
107     }
108 
109     /*
110      * (non-Javadoc)
111      * 
112      * @see org.mule.umo.providers.UMOMessageAdapter#getMessage()
113      */
114     public Object getPayload()
115     {
116         return message;
117     }
118 
119     public boolean isBinary()
120     {
121         return message instanceof byte[];
122     }
123 
124     /*
125      * (non-Javadoc)
126      * 
127      * @see org.mule.umo.providers.UMOMessageAdapter#getMessageAsBytes()
128      */
129     public byte[] getPayloadAsBytes() throws Exception
130     {
131         if (isBinary())
132         {
133             return (byte[])message;
134         }
135         else
136         {
137             return ((String)message).getBytes();
138         }
139     }
140 
141     /**
142      * Converts the message implementation into a String representation
143      * 
144      * @param encoding The encoding to use when transforming the message (if
145      *            necessary). The parameter is used when converting from a byte array
146      * @return String representation of the message payload
147      * @throws Exception Implementation may throw an endpoint specific exception
148      */
149     public String getPayloadAsString(String encoding) throws Exception
150     {
151         if (isBinary())
152         {
153             return new String((byte[])message, encoding);
154         }
155         else
156         {
157             return (String)message;
158         }
159     }
160 
161     /*
162      * (non-Javadoc)
163      * 
164      * @see org.mule.umo.providers.UMOMessageAdapter#setMessage(java.lang.Object)
165      */
166     private void setPayload(HttpServletRequest message) throws MessagingException
167     {
168         try
169         {
170 
171             request = message;
172             // String httpRequest = null;
173             // httpRequest = request.getScheme() + "://" + request.getServerName() +
174             // ":" + request.getServerPort() + request.getServletPath();
175             // httpRequest += request.getPathInfo();
176             // if(StringUtils.isNotBlank(request.getQueryString())) {
177             // httpRequest += "?" + request.getQueryString();
178             // }
179             // setProperty(HttpConnector.HTTP_REQUEST_PROPERTY, httpRequest);
180             // this.message = httpRequest;
181 
182             // Check if a payload parameter has been set, if so use it
183             // otherwise we'll use the request payload
184             String payloadParam = (String)request
185                 .getAttribute(AbstractReceiverServlet.PAYLOAD_PARAMETER_NAME);
186 
187             if (payloadParam == null)
188             {
189                 payloadParam = AbstractReceiverServlet.DEFAULT_PAYLOAD_PARAMETER_NAME;
190             }
191             String payload = request.getParameter(payloadParam);
192             if (payload == null)
193             {
194                 if (isText(request.getContentType()))
195                 {
196                     BufferedReader reader = request.getReader();
197                     StringBuffer buffer = new StringBuffer(8192);
198                     String line = reader.readLine();
199                     while (line != null)
200                     {
201                         buffer.append(line);
202                         line = reader.readLine();
203                         if (line != null) buffer.append(SystemUtils.LINE_SEPARATOR);
204                     }
205                     this.message = buffer.toString();
206                 }
207                 else
208                 {
209                     ByteArrayOutputStream baos = new ByteArrayOutputStream(8192);
210                     IOUtils.copy(request.getInputStream(), baos);
211                     this.message = baos.toByteArray();
212                 }
213             }
214             else
215             {
216                 this.message = payload;
217             }
218         }
219         catch (IOException e)
220         {
221             throw new MessagingException(
222                 ServletMessages.failedToReadPayload(request.getRequestURL().toString()), e);
223         }
224     }
225 
226     public HttpServletRequest getRequest()
227     {
228         return request;
229     }
230 
231     public String getUniqueId()
232     {
233         HttpSession session = null;
234 
235         try
236         {
237             // We wrap this call as on some App Servers (Websfear) it can cause an
238             // NPE
239             session = getRequest().getSession();
240         }
241         catch (Exception e)
242         {
243             throw new UniqueIdNotSupportedException(this, CoreMessages.objectIsNull("Http session"));
244         }
245         if (session == null)
246         {
247             throw new UniqueIdNotSupportedException(this, CoreMessages.objectIsNull("Http session"));
248         }
249         return session.getId();
250     }
251 
252     protected boolean isText(String contentType)
253     {
254         if (contentType == null)
255         {
256             return true;
257         }
258         return (contentType.startsWith("text/"));
259     }
260 
261     /**
262      * Sets a replyTo address for this message. This is useful in an asynchronous
263      * environment where the caller doesn't wait for a response and the response
264      * needs to be routed somewhere for further processing. The value of this field
265      * can be any valid endpointUri url.
266      * 
267      * @param replyTo the endpointUri url to reply to
268      */
269     public void setReplyTo(Object replyTo)
270     {
271         if (replyTo != null && replyTo.toString().startsWith("http"))
272         {
273             setProperty(HttpConstants.HEADER_LOCATION, replyTo);
274         }
275         setProperty(MuleProperties.MULE_CORRELATION_ID_PROPERTY, replyTo);
276     }
277 
278     /**
279      * Sets a replyTo address for this message. This is useful in an asynchronous
280      * environment where the caller doesn't wait for a response and the response
281      * needs to be routed somewhere for further processing. The value of this field
282      * can be any valid endpointUri url.
283      * 
284      * @return the endpointUri url to reply to or null if one has not been set
285      */
286     public Object getReplyTo()
287     {
288         String replyto = (String)getProperty(MuleProperties.MULE_REPLY_TO_PROPERTY);
289         if (replyto == null)
290         {
291             replyto = (String)getProperty(HttpConstants.HEADER_LOCATION);
292         }
293         return replyto;
294     }
295 
296     public ThreadSafeAccess newThreadCopy()
297     {
298         return new HttpRequestMessageAdapter(this);
299     }
300 
301 }