KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > mule > providers > soap > xfire > transport > MuleUniversalChannel


1 /*
2  * $Id: MuleUniversalChannel.java 3798 2006-11-04 04:07:14Z aperepel $
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 MuleSource MPL
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.soap.xfire.transport;
12
13 import org.apache.commons.io.output.ByteArrayOutputStream;
14 import org.apache.commons.logging.Log;
15 import org.apache.commons.logging.LogFactory;
16 import org.codehaus.xfire.MessageContext;
17 import org.codehaus.xfire.XFireException;
18 import org.codehaus.xfire.XFireRuntimeException;
19 import org.codehaus.xfire.attachments.Attachments;
20 import org.codehaus.xfire.attachments.ByteDataSource;
21 import org.codehaus.xfire.attachments.JavaMailAttachments;
22 import org.codehaus.xfire.attachments.SimpleAttachment;
23 import org.codehaus.xfire.exchange.AbstractMessage;
24 import org.codehaus.xfire.exchange.InMessage;
25 import org.codehaus.xfire.exchange.OutMessage;
26 import org.codehaus.xfire.soap.Soap12;
27 import org.codehaus.xfire.soap.SoapConstants;
28 import org.codehaus.xfire.soap.SoapVersion;
29 import org.codehaus.xfire.transport.AbstractChannel;
30 import org.codehaus.xfire.transport.Channel;
31 import org.codehaus.xfire.transport.Transport;
32 import org.codehaus.xfire.util.STAXUtils;
33 import org.mule.MuleRuntimeException;
34 import org.mule.config.MuleProperties;
35 import org.mule.config.i18n.CoreMessageConstants;
36 import org.mule.config.i18n.Message;
37 import org.mule.extras.client.MuleClient;
38 import org.mule.impl.RequestContext;
39 import org.mule.providers.http.HttpConnector;
40 import org.mule.providers.http.HttpConstants;
41 import org.mule.providers.streaming.StreamMessageAdapter;
42 import org.mule.umo.UMOEvent;
43 import org.mule.umo.UMOException;
44 import org.mule.umo.UMOMessage;
45 import org.mule.umo.provider.OutputHandler;
46 import org.mule.umo.provider.UMOStreamMessageAdapter;
47
48 import javax.activation.DataHandler JavaDoc;
49 import javax.mail.MessagingException JavaDoc;
50 import javax.xml.stream.XMLStreamException;
51 import javax.xml.stream.XMLStreamWriter;
52 import java.io.IOException JavaDoc;
53 import java.io.InputStream JavaDoc;
54 import java.io.OutputStream JavaDoc;
55 import java.util.HashMap JavaDoc;
56 import java.util.Iterator JavaDoc;
57 import java.util.Map JavaDoc;
58
59 /**
60  * The MuleUniversalChannel is an XFire Channel implementation that uses
61  * a Mule Transport under the covers. It theoretically can use any Mule transport
62  * but only transports that support streaming can be used with XFire.
63  *
64  * This channel is used for making Soap requests using XFire, not receiving them.
65  *
66  */

67 public class MuleUniversalChannel extends AbstractChannel
68 {
69     /**
70      * logger used by this class
71      */

72     protected transient final Log logger = LogFactory.getLog(getClass());
73
74     /**
75      * MuleClient used for sending "universal" requests
76      */

77     protected transient final MuleClient client;
78
79     public MuleUniversalChannel(String JavaDoc uri, Transport transport)
80     {
81         setTransport(transport);
82         setUri(uri);
83
84         try
85         {
86             this.client = new MuleClient();
87         }
88         catch (UMOException ex)
89         {
90             throw new MuleRuntimeException(new Message(CoreMessageConstants.X_FAILED_TO_INITIALISE,
91                 "MuleClient"), ex);
92         }
93     }
94
95     public void open()
96     {
97         // nothing to do here
98
}
99
100     public void send(MessageContext context, OutMessage message) throws XFireException
101     {
102         if (message.getUri().equals(Channel.BACKCHANNEL_URI))
103         {
104             final OutputStream out = (OutputStream)context.getProperty(Channel.BACKCHANNEL_URI);
105             if (out != null)
106             {
107                 final XMLStreamWriter writer = STAXUtils.createXMLStreamWriter(out, message.getEncoding(),
108                     context);
109
110                 message.getSerializer().writeMessage(message, writer, context);
111             }
112             else
113             {
114                 throw new XFireRuntimeException("No backchannel exists for message");
115             }
116
117             try
118             {
119                 Attachments atts = message.getAttachments();
120                 if (atts != null && atts.size() > 0)
121                 {
122                     writeAttachmentBody(context, message);
123                     // TODO response.setContentType(atts.getContentType());
124
atts.write(out);
125                 }
126                 else
127                 {
128                     // TODO response.setContentType(getSoapMimeType(message));
129
writeWithoutAttachments(context, message, out);
130                 }
131             }
132             catch (IOException JavaDoc e)
133             {
134                 throw new XFireException("Couldn't send message.", e);
135             }
136         }
137         else
138         {
139             try
140             {
141                 sendViaClient(context, message);
142             }
143             catch (Exception JavaDoc e)
144             {
145                 throw new XFireException("Failed to Send via MuleUniversalChannel: " + e.getMessage(), e);
146             }
147         }
148     }
149
150     void writeWithoutAttachments(MessageContext context, OutMessage message, OutputStream out)
151         throws XFireException
152     {
153         XMLStreamWriter writer = STAXUtils.createXMLStreamWriter(out, message.getEncoding(), context);
154
155         message.getSerializer().writeMessage(message, writer, context);
156
157         try
158         {
159             writer.flush();
160         }
161         catch (XMLStreamException e)
162         {
163             logger.error(e);
164             throw new XFireException("Couldn't send message.", e);
165         }
166     }
167
168     void writeAttachmentBody(MessageContext context, OutMessage message) throws XFireException
169     {
170         ByteArrayOutputStream bos = new ByteArrayOutputStream();
171         writeWithoutAttachments(context, message, bos);
172
173         Attachments atts = message.getAttachments();
174
175         ByteDataSource ds = new ByteDataSource(bos.toByteArray());
176         ds.setContentType(getSoapMimeType(message));
177         DataHandler JavaDoc dh = new DataHandler JavaDoc(ds);
178
179         SimpleAttachment att = new SimpleAttachment("soap-message.xml", dh);
180
181         atts.setSoapMessage(att);
182     }
183
184     String JavaDoc getMimeType(AbstractMessage msg)
185     {
186         Attachments atts = msg.getAttachments();
187
188         if (atts != null && atts.size() > 0)
189         {
190             return atts.getContentType();
191         }
192         else
193         {
194             return getSoapMimeType(msg);
195         }
196     }
197
198     static String JavaDoc getSoapMimeType(AbstractMessage msg)
199     {
200         SoapVersion soap = msg.getSoapVersion();
201         String JavaDoc encoding = msg.getEncoding();
202         StringBuffer JavaDoc soapMimeType = new StringBuffer JavaDoc(40);
203
204         if (soap instanceof Soap12)
205         {
206             soapMimeType.append("application/soap+xml; charset=");
207         }
208         else
209         {
210             // SOAP 1.1 & default
211
soapMimeType.append("text/xml; charset=");
212         }
213
214         return soapMimeType.append(encoding).toString();
215     }
216
217     private void sendViaClient(final MessageContext context, final OutMessage message) throws Exception JavaDoc
218     {
219         OutputHandler handler = new OutputHandler()
220         {
221             public void write(UMOEvent event, OutputStream out) throws IOException JavaDoc
222             {
223                 try
224                 {
225                     Attachments atts = message.getAttachments();
226                     if (atts != null && atts.size() > 0)
227                     {
228                         atts.write(out);
229                     }
230                     else
231                     {
232                         XMLStreamWriter writer = STAXUtils.createXMLStreamWriter(out, message.getEncoding(),
233                             context);
234                         message.getSerializer().writeMessage(message, writer, context);
235                         try
236                         {
237                             writer.flush();
238                         }
239                         catch (XMLStreamException e)
240                         {
241                             logger.error(e);
242                             throw new XFireException("Couldn't send message.", e);
243                         }
244                     }
245                 }
246                 catch (XFireException e)
247                 {
248                     logger.error("Couldn't send message.", e);
249                     throw new IOException JavaDoc(e.getMessage());
250                 }
251             }
252
253             public Map JavaDoc getHeaders(UMOEvent event)
254             {
255                 Map JavaDoc headers = new HashMap JavaDoc();
256                 headers.put(HttpConstants.HEADER_CONTENT_TYPE, getSoapMimeType(message));
257                 headers.put(SoapConstants.SOAP_ACTION, message.getProperty(SoapConstants.SOAP_ACTION));
258                 UMOMessage msg = event.getMessage();
259                 for (Iterator JavaDoc iterator = msg.getPropertyNames().iterator(); iterator.hasNext();)
260                 {
261                     String JavaDoc headerName = (String JavaDoc)iterator.next();
262                     Object JavaDoc headerValue = msg.getStringProperty(headerName, null);
263
264                     // let us filter only MULE properties except MULE_USER,
265
// Content-Type and Content-Lenght; all other properties are
266
// allowed through including custom headers
267
if ((!headerName.startsWith(MuleProperties.PROPERTY_PREFIX) || (MuleProperties.MULE_USER_PROPERTY.compareTo(headerName) == 0))
268                         && (!HttpConstants.HEADER_CONTENT_TYPE.equalsIgnoreCase(headerName))
269                         && (!HttpConstants.HEADER_CONTENT_LENGTH.equalsIgnoreCase(headerName)))
270                     {
271                         headers.put(headerName, headerValue);
272                     }
273                 }
274
275                 return headers;
276             }
277         };
278
279         // We can create a generic StreamMessageAdapter here as the underlying
280
// transport will create one specific to the transport
281
UMOStreamMessageAdapter sp = new StreamMessageAdapter(handler);
282         sp.setProperty(HttpConnector.HTTP_METHOD_PROPERTY, HttpConstants.METHOD_POST);
283
284         // set all properties on the message adapter
285
UMOMessage msg = RequestContext.getEvent().getMessage();
286         for (Iterator JavaDoc i = msg.getPropertyNames().iterator(); i.hasNext();)
287         {
288             String JavaDoc propertyName = (String JavaDoc)i.next();
289             sp.setProperty(propertyName, msg.getProperty(propertyName));
290         }
291
292         UMOStreamMessageAdapter result = null;
293
294         try
295         {
296             result = client.sendStream(getUri(), sp);
297             if (result != null)
298             {
299                 InMessage inMessage;
300                 String JavaDoc contentType = sp.getStringProperty(HttpConstants.HEADER_CONTENT_TYPE, "text/xml");
301                 InputStream JavaDoc in = result.getInputStream();
302                 if (contentType.toLowerCase().indexOf("multipart/related") != -1)
303                 {
304                     try
305                     {
306                         Attachments atts = new JavaMailAttachments(in, contentType);
307                         InputStream JavaDoc msgIs = atts.getSoapMessage().getDataHandler().getInputStream();
308                         inMessage = new InMessage(STAXUtils.createXMLStreamReader(msgIs,
309                             message.getEncoding(), context), getUri());
310                         inMessage.setAttachments(atts);
311                     }
312                     catch (MessagingException JavaDoc e)
313                     {
314                         throw new IOException JavaDoc(e.getMessage());
315                     }
316                 }
317                 else
318                 {
319                     inMessage = new InMessage(STAXUtils.createXMLStreamReader(in, message.getEncoding(),
320                         context), getUri());
321                 }
322                 getEndpoint().onReceive(context, inMessage);
323             }
324         }
325         finally
326         {
327             sp.release();
328             if (result != null)
329             {
330                 result.release();
331             }
332         }
333     }
334
335     public void close()
336     {
337         // nothing to do here
338
}
339
340     public boolean isAsync()
341     {
342         return false;
343     }
344
345 }
346
Popular Tags