View Javadoc

1   /*
2    * $Id: XFireServiceComponent.java 7963 2007-08-21 08:53:15Z 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.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   * The Xfire service component receives requests for Xfire services it manages and
61   * marshalls requests and responses
62   * 
63   */
64  public class XFireServiceComponent implements Callable, Initialisable, Lifecycle, UMODescriptorAware
65  {
66      /**
67       * logger used by this class
68       */
69      protected transient Log logger = LogFactory.getLog(getClass());
70  
71      protected XFire xfire;
72  
73      // manager to the component
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         //if http request
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 //if servlet request
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         // template method
177     }
178 
179     public void stop() throws UMOException
180     {
181         // template method
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         // template method
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      * @param response
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      * Gets the stream representation of the current message. If the message is set
224      * for streaming the input stream on the UMOStreamMEssageAdapter will be used,
225      * otherwise a byteArrayInputStream will be used to hold the byte[]
226      * representation of the current message.
227      * 
228      * @param context the event context
229      * @return The inputstream for the current message
230      * @throws UMOException
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      * Get the service that is mapped to the specified request.
258      * 
259      * @param context the context from which to find the service name
260      * @return the service that is mapped to the specified request.
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 }