1
2
3
4
5
6
7
8
9
10
11 package org.mule.providers.soap.xfire;
12
13 import org.mule.MuleRuntimeException;
14 import org.mule.config.ConfigurationException;
15 import org.mule.config.i18n.CoreMessages;
16 import org.mule.impl.MuleDescriptor;
17 import org.mule.impl.MuleMessage;
18 import org.mule.impl.UMODescriptorAware;
19 import org.mule.providers.http.HttpConnector;
20 import org.mule.providers.http.HttpConstants;
21 import org.mule.providers.soap.SoapConstants;
22 import org.mule.providers.soap.xfire.transport.MuleLocalChannel;
23 import org.mule.providers.soap.xfire.transport.MuleLocalTransport;
24 import org.mule.providers.soap.xfire.transport.MuleUniversalTransport;
25 import org.mule.providers.streaming.OutStreamMessageAdapter;
26 import org.mule.providers.streaming.StreamMessageAdapter;
27 import org.mule.umo.UMODescriptor;
28 import org.mule.umo.UMOEventContext;
29 import org.mule.umo.UMOException;
30 import org.mule.umo.UMOMessage;
31 import org.mule.umo.lifecycle.Callable;
32 import org.mule.umo.lifecycle.Initialisable;
33 import org.mule.umo.lifecycle.InitialisationException;
34 import org.mule.umo.lifecycle.Lifecycle;
35 import org.mule.umo.manager.UMOWorkManager;
36 import org.mule.umo.provider.UMOStreamMessageAdapter;
37 import org.mule.util.ClassUtils;
38 import org.mule.util.StringUtils;
39
40 import java.io.ByteArrayInputStream;
41 import java.io.IOException;
42 import java.io.InputStream;
43 import java.lang.reflect.Constructor;
44 import java.util.Enumeration;
45
46 import javax.xml.stream.XMLStreamException;
47
48 import org.apache.commons.io.output.ByteArrayOutputStream;
49 import org.apache.commons.logging.Log;
50 import org.apache.commons.logging.LogFactory;
51 import org.codehaus.xfire.XFire;
52 import org.codehaus.xfire.XFireFactory;
53 import org.codehaus.xfire.service.Service;
54 import org.codehaus.xfire.service.ServiceRegistry;
55 import org.codehaus.xfire.transport.Transport;
56 import org.codehaus.xfire.transport.TransportManager;
57 import org.codehaus.xfire.transport.http.HtmlServiceWriter;
58
59
60
61
62
63
64 public class XFireServiceComponent implements Callable, Initialisable, Lifecycle, UMODescriptorAware
65 {
66
67
68
69 protected transient Log logger = LogFactory.getLog(getClass());
70
71 protected XFire xfire;
72
73
74 protected Transport transport;
75 protected Transport universalTransport;
76 protected String transportClass;
77
78 public void setDescriptor(UMODescriptor descriptor) throws ConfigurationException
79 {
80 UMOWorkManager wm = ((MuleDescriptor)descriptor).getThreadingProfile().createWorkManager(
81 "xfire-local-transport");
82 try
83 {
84 wm.start();
85 }
86 catch (UMOException e)
87 {
88 throw new MuleRuntimeException(CoreMessages.failedToStart("local channel work manager"), e);
89 }
90 if(transportClass == null)
91 {
92 transport = new MuleLocalTransport(wm);
93 }
94 else
95 {
96 try {
97 Class transportClazz = ClassUtils.loadClass(transportClass, this.getClass());
98 try{
99 Constructor constructor = transportClazz.getConstructor(new Class[]{UMOWorkManager.class});
100 transport = (Transport)constructor.newInstance(new Object[]{wm});
101 }
102 catch(NoSuchMethodException ne)
103 {
104 if (logger.isDebugEnabled())
105 {
106 logger.debug(ne.getCause());
107 }
108 }
109 if(transport == null)
110 {
111 Constructor constructor = transportClazz.getConstructor(null);
112 transport = (Transport)constructor.newInstance(null);
113 }
114 }
115 catch(Exception e)
116 {
117 throw new MuleRuntimeException(CoreMessages.failedToLoad("xfire service transport"), e);
118 }
119 }
120
121 universalTransport = new MuleUniversalTransport();
122
123 if(xfire == null){
124 xfire = XFireFactory.newInstance().getXFire();
125 }
126 getTransportManager().register(transport);
127 getTransportManager().register(universalTransport);
128 }
129
130 public Object onCall(UMOEventContext eventContext) throws Exception
131 {
132 if(logger.isDebugEnabled())
133 {
134 logger.debug(eventContext);
135 }
136
137 boolean wsdlRequested = false;
138
139
140 String request = eventContext.getMessage().getStringProperty(HttpConnector.HTTP_REQUEST_PROPERTY,
141 StringUtils.EMPTY);
142 if (request.toLowerCase().endsWith(org.mule.providers.soap.SoapConstants.WSDL_PROPERTY))
143 {
144 wsdlRequested = true;
145 }
146 else
147 {
148 Enumeration keys = eventContext.getEndpointURI().getParams().keys();
149 while(keys.hasMoreElements()){
150 if ((keys.nextElement()).toString().equalsIgnoreCase(SoapConstants.WSDL_PROPERTY)) {
151 wsdlRequested = true;
152 break;
153 }
154 }
155 }
156
157 if (wsdlRequested)
158 {
159 ByteArrayOutputStream out = new ByteArrayOutputStream();
160 getXfire().generateWSDL(getServiceName(eventContext), out);
161 UMOMessage result = new MuleMessage(out.toString(eventContext.getEncoding()));
162 result.setProperty(HttpConstants.HEADER_CONTENT_TYPE, "text/xml");
163 return result;
164 }
165 else
166 {
167 MuleLocalChannel channel = (MuleLocalChannel)transport.createChannel(eventContext.getEndpointURI()
168 .getFullScheme());
169 return channel.onCall(eventContext);
170 }
171
172 }
173
174 public void start() throws UMOException
175 {
176
177 }
178
179 public void stop() throws UMOException
180 {
181
182 }
183
184 public void initialise() throws InitialisationException
185 {
186 if (xfire == null)
187 {
188 throw new InitialisationException(CoreMessages.objectIsNull("xfire"), this);
189 }
190 }
191
192 public void dispose()
193 {
194
195 }
196
197 protected TransportManager getTransportManager()
198 {
199 return getXfire().getTransportManager();
200 }
201
202 protected void generateServiceX(OutStreamMessageAdapter response, String serviceName)
203 throws IOException, XMLStreamException
204 {
205 response.setProperty(HttpConstants.HEADER_CONTENT_TYPE, "text/html");
206 Service endpoint = getServiceRegistry().getService(serviceName);
207 HtmlServiceWriter writer = new HtmlServiceWriter();
208 writer.write(response.getStream(), endpoint);
209 }
210
211
212
213
214 protected void generateServicesX(OutStreamMessageAdapter response) throws IOException, XMLStreamException
215 {
216 response.setProperty(HttpConstants.HEADER_CONTENT_TYPE, "text/html");
217
218 HtmlServiceWriter writer = new HtmlServiceWriter();
219 writer.write(response.getStream(), getServiceRegistry().getServices());
220 }
221
222
223
224
225
226
227
228
229
230
231
232
233 protected InputStream getMessageStream(UMOEventContext context) throws UMOException
234 {
235 InputStream is;
236 UMOMessage eventMsg = context.getMessage();
237 Object eventMsgPayload = eventMsg.getPayload();
238
239 if (eventMsgPayload instanceof InputStream)
240 {
241 is = (InputStream)eventMsgPayload;
242 }
243 else if (eventMsg.getAdapter() instanceof UMOStreamMessageAdapter)
244 {
245 StreamMessageAdapter sma = (StreamMessageAdapter)eventMsg.getAdapter();
246 is = sma.getInputStream();
247
248 }
249 else
250 {
251 is = new ByteArrayInputStream(context.getTransformedMessageAsBytes());
252 }
253 return is;
254 }
255
256
257
258
259
260
261
262 protected String getServiceName(UMOEventContext context)
263 {
264 String pathInfo = context.getEndpointURI().getPath();
265
266 if (StringUtils.isEmpty(pathInfo))
267 {
268 return context.getEndpointURI().getHost();
269 }
270
271 String serviceName;
272
273 int i = pathInfo.lastIndexOf("/");
274
275 if (i > -1)
276 {
277 serviceName = pathInfo.substring(i + 1);
278 }
279 else
280 {
281 serviceName = pathInfo;
282 }
283
284 return serviceName;
285 }
286
287 protected Service getService(String name)
288 {
289 return getXfire().getServiceRegistry().getService(name);
290 }
291
292 public XFire getXfire()
293 {
294 return xfire;
295 }
296
297 public void setXfire(XFire xfire)
298 {
299 this.xfire = xfire;
300 }
301
302 public void setTransport(Transport transport)
303 {
304 this.transport = transport;
305 }
306
307 public void setTransportClass(String clazz)
308 {
309 transportClass = clazz;
310 }
311
312 public ServiceRegistry getServiceRegistry()
313 {
314 return xfire.getServiceRegistry();
315 }
316 }