View Javadoc

1   /*
2    * $Id: AxisServiceComponent.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.soap.axis;
12  
13  import org.mule.MuleManager;
14  import org.mule.config.MuleProperties;
15  import org.mule.config.i18n.CoreMessages;
16  import org.mule.impl.MuleMessage;
17  import org.mule.impl.RequestContext;
18  import org.mule.impl.endpoint.MuleEndpointURI;
19  import org.mule.providers.WriterMessageAdapter;
20  import org.mule.providers.http.HttpConnector;
21  import org.mule.providers.http.HttpConstants;
22  import org.mule.providers.soap.SoapConstants;
23  import org.mule.providers.soap.axis.extensions.AxisMuleSession;
24  import org.mule.providers.soap.axis.extensions.MuleConfigProvider;
25  import org.mule.umo.MessagingException;
26  import org.mule.umo.UMOEventContext;
27  import org.mule.umo.UMOException;
28  import org.mule.umo.UMOMessage;
29  import org.mule.umo.endpoint.MalformedEndpointException;
30  import org.mule.umo.endpoint.UMOEndpointURI;
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.util.StringUtils;
35  
36  import java.io.ByteArrayInputStream;
37  import java.io.ByteArrayOutputStream;
38  import java.io.File;
39  import java.io.FileInputStream;
40  import java.io.IOException;
41  import java.io.StringWriter;
42  import java.util.ArrayList;
43  import java.util.Iterator;
44  import java.util.Map;
45  import java.util.Properties;
46  
47  import javax.xml.namespace.QName;
48  
49  import org.apache.axis.AxisEngine;
50  import org.apache.axis.AxisFault;
51  import org.apache.axis.ConfigurationException;
52  import org.apache.axis.Constants;
53  import org.apache.axis.Message;
54  import org.apache.axis.MessageContext;
55  import org.apache.axis.description.OperationDesc;
56  import org.apache.axis.description.ServiceDesc;
57  import org.apache.axis.handlers.soap.SOAPService;
58  import org.apache.axis.i18n.Messages;
59  import org.apache.axis.security.servlet.ServletSecurityProvider;
60  import org.apache.axis.server.AxisServer;
61  import org.apache.axis.transport.http.HTTPConstants;
62  import org.apache.axis.transport.http.ServletEndpointContextImpl;
63  import org.apache.axis.utils.Admin;
64  import org.apache.axis.utils.XMLUtils;
65  import org.apache.commons.logging.Log;
66  import org.w3c.dom.Document;
67  
68  /**
69   * <code>AxisServiceComponent</code> is a Mule component implementation of the Axis
70   * servlet. This component supports all the features of the Axis servlet except -
71   * <ol>
72   * <li>Jws class services are not supported as they don't add any value to the Mule
73   * model</li>
74   * <li>Currently there is no HttpSession support. This will be fixed when Session
75   * support is added to the Http Connector</li>
76   * </ol>
77   */
78  
79  public class AxisServiceComponent implements Initialisable, Callable
80  {
81      protected static final Log logger = org.apache.commons.logging.LogFactory.getLog(AxisServiceComponent.class);
82  
83      public static final String INIT_PROPERTY_TRANSPORT_NAME = "transport.name";
84      public static final String INIT_PROPERTY_USE_SECURITY = "use-servlet-security";
85      public static final String INIT_PROPERTY_ENABLE_LIST = "axis.enableListQuery";
86      public static final String DEFAULT_AXIS_HOME = "/axisHome";
87  
88      private String transportName = "http";
89      private ServletSecurityProvider securityProvider;
90      private boolean enableList;
91      private String homeDir;
92      private AxisServer axisServer;
93  
94      public AxisServiceComponent()
95      {
96          securityProvider = null;
97          enableList = true;
98      }
99  
100     /**
101      * Passes the context to the listener
102      * 
103      * @param context the context to process
104      * @return Object this object can be anything. When the
105      *         <code>UMOLifecycleAdapter</code> for the component receives this
106      *         object it will first see if the Object is an <code>UMOEvent</code>
107      *         if not and the Object is not null a new context will be created using
108      *         the returned object as the payload. This new context will then get
109      *         published to the configured outbound endpoint if-
110      *         <ol>
111      *         <li>One has been configured for the UMO.</li>
112      *         <li>the <code>setStopFurtherProcessing(true)</code> wasn't called
113      *         on the previous context.</li>
114      *         </ol>
115      * @throws Exception if the context fails to process properly. If exceptions
116      *             aren't handled by the implementation they will be handled by the
117      *             exceptionListener associated with the component
118      */
119     public Object onCall(UMOEventContext context) throws Exception
120     {
121         WriterMessageAdapter response = new WriterMessageAdapter(new StringWriter(4096));
122         String method = context.getMessage().getStringProperty(HttpConnector.HTTP_METHOD_PROPERTY,
123             HttpConstants.METHOD_POST);
124         if (HttpConstants.METHOD_GET.equalsIgnoreCase(method))
125         {
126             doGet(context, response);
127         }
128         else
129         {
130             doPost(context, response);
131         }
132         response.getWriter().close();
133         return new MuleMessage(response);
134     }
135 
136     public void initialise() throws InitialisationException
137     {
138         // template method
139     }
140 
141     public void doGet(UMOEventContext context, WriterMessageAdapter response)
142         throws UMOException, IOException
143     {
144         try
145         {
146             // We parse a new uri based on the listening host and port with the
147             // request parameters appended
148             // Using the soap prefix ensures that we use a soap endpoint builder
149             UMOEndpointURI endpointUri = context.getEndpointURI();
150             if (!"servlet".equalsIgnoreCase(context.getEndpointURI().getSchemeMetaInfo()))
151             {
152                 String uri = SoapConstants.SOAP_ENDPOINT_PREFIX + context.getEndpointURI().getScheme()
153                                 + "://" + context.getEndpointURI().getHost() + ":"
154                                 + context.getEndpointURI().getPort();
155                 uri += context.getMessageAsString();
156                 endpointUri = new MuleEndpointURI(uri);
157             }
158 
159             AxisEngine engine = getAxisServer();
160             String pathInfo = endpointUri.getPath();
161             boolean wsdlRequested = false;
162             boolean listRequested = false;
163 
164             if (endpointUri.getAddress().endsWith(".jws"))
165             {
166                 throw new AxisFault("Jws not supported by the Mule Axis service");
167             }
168 
169             String queryString = endpointUri.getQuery();
170             if (queryString != null)
171             {
172                 if (queryString.equalsIgnoreCase(SoapConstants.WSDL_PROPERTY))
173                 {
174                     wsdlRequested = true;
175                 }
176                 else
177                 {
178                     if (queryString.equalsIgnoreCase(SoapConstants.LIST_PROPERTY))
179                     {
180                         listRequested = true;
181                     }
182                 }
183             }
184 
185             boolean hasNoPath = (StringUtils.isEmpty(pathInfo) || pathInfo.equals("/"));
186             if (!wsdlRequested && !listRequested && hasNoPath)
187             {
188                 reportAvailableServices(context, response);
189             }
190             else
191             {
192                 MessageContext msgContext = new MessageContext(engine);
193                 populateMessageContext(msgContext, context, endpointUri);
194 
195                 msgContext.setProperty("transport.url", endpointUri.toString());
196                 if (wsdlRequested)
197                 {
198                     processWsdlRequest(msgContext, response);
199                 }
200                 else if (listRequested)
201                 {
202                     processListRequest(response);
203                 }
204                 else
205                 {
206                     processMethodRequest(msgContext, context, response, endpointUri);
207                 }
208             }
209         }
210         catch (AxisFault fault)
211         {
212             reportTroubleInGet(fault, response);
213         }
214         catch (Exception e)
215         {
216             reportTroubleInGet(e, response);
217         }
218     }
219 
220     private void reportTroubleInGet(Exception exception, WriterMessageAdapter response)
221     {
222         response.setProperty(HttpConstants.HEADER_CONTENT_TYPE, "text/html");
223         response.setProperty(HttpConnector.HTTP_STATUS_PROPERTY, "500");
224         response.write("<h2>" + Messages.getMessage("error00") + "</h2>");
225         response.write("<p>" + Messages.getMessage("somethingWrong00") + "</p>");
226         if (exception instanceof AxisFault)
227         {
228             AxisFault fault = (AxisFault)exception;
229             processAxisFault(fault);
230             writeFault(response, fault);
231         }
232         else
233         {
234             logger.error(exception.getMessage(), exception);
235             response.write("<pre>Exception - " + exception + "<br>");
236             response.write("</pre>");
237         }
238     }
239 
240     protected void processAxisFault(AxisFault fault)
241     {
242         org.w3c.dom.Element runtimeException = fault
243             .lookupFaultDetail(Constants.QNAME_FAULTDETAIL_RUNTIMEEXCEPTION);
244         if (runtimeException != null)
245         {
246             logger.info(Messages.getMessage("axisFault00"), fault);
247             fault.removeFaultDetail(Constants.QNAME_FAULTDETAIL_RUNTIMEEXCEPTION);
248         }
249         else if (logger.isDebugEnabled())
250         {
251             logger.debug(Messages.getMessage("axisFault00"), fault);
252         }
253 
254     }
255 
256     private void writeFault(WriterMessageAdapter response, AxisFault axisFault)
257     {
258         String localizedMessage = XMLUtils.xmlEncodeString(axisFault.getLocalizedMessage());
259         response.write("<pre>Fault - " + localizedMessage + "<br>");
260         response.write(axisFault.dumpToString());
261         response.write("</pre>");
262     }
263 
264     protected void processMethodRequest(MessageContext msgContext,
265                                         UMOEventContext context,
266                                         WriterMessageAdapter response,
267                                         UMOEndpointURI endpointUri) throws AxisFault
268     {
269         Properties params = endpointUri.getUserParams();
270 
271         String method = (String)params.remove(MuleProperties.MULE_METHOD_PROPERTY);
272         if (method == null)
273         {
274             method = endpointUri.getPath().substring(endpointUri.getPath().lastIndexOf("/") + 1);
275         }
276         StringBuffer args = new StringBuffer(64);
277 
278         Map.Entry entry;
279         for (Iterator iterator = params.entrySet().iterator(); iterator.hasNext();)
280         {
281             entry = (Map.Entry)iterator.next();
282             args.append("<").append(entry.getKey()).append(">");
283             args.append(entry.getValue());
284             args.append("</").append(entry.getKey()).append(">");
285         }
286 
287         if (method == null)
288         {
289             response.setProperty(HttpConstants.HEADER_CONTENT_TYPE, "text/html");
290             response.setProperty(HttpConnector.HTTP_STATUS_PROPERTY, "400");
291             response.write("<h2>" + Messages.getMessage("error00") + ":  "
292                             + Messages.getMessage("invokeGet00") + "</h2>");
293             response.write("<p>" + Messages.getMessage("noMethod01") + "</p>");
294         }
295         else
296         {
297             invokeEndpointFromGet(msgContext, response, method, args.toString());
298         }
299     }
300 
301     protected void processWsdlRequest(MessageContext msgContext, WriterMessageAdapter response)
302         throws AxisFault
303     {
304         AxisEngine engine = getAxisServer();
305         try
306         {
307             engine.generateWSDL(msgContext);
308             Document doc = (Document)msgContext.getProperty("WSDL");
309             if (doc != null)
310             {
311                 response.setProperty(HttpConstants.HEADER_CONTENT_TYPE, "text/xml");
312                 XMLUtils.DocumentToWriter(doc, response.getWriter());
313             }
314             else
315             {
316                 if (logger.isDebugEnabled())
317                 {
318                     logger.debug("processWsdlRequest: failed to create WSDL");
319                 }
320                 reportNoWSDL(response, "noWSDL02", null);
321             }
322         }
323         catch (AxisFault axisFault)
324         {
325             if (axisFault.getFaultCode().equals(Constants.QNAME_NO_SERVICE_FAULT_CODE))
326             {
327                 processAxisFault(axisFault);
328                 response.setProperty(HttpConnector.HTTP_STATUS_PROPERTY, "404");
329                 reportNoWSDL(response, "noWSDL01", axisFault);
330             }
331             else
332             {
333                 throw axisFault;
334             }
335         }
336     }
337 
338     protected void invokeEndpointFromGet(MessageContext msgContext,
339                                          WriterMessageAdapter response,
340                                          String method,
341                                          String args) throws AxisFault
342     {
343         String body = "<" + method + ">" + args + "</" + method + ">";
344         String msgtxt = "<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\"><SOAP-ENV:Body>"
345                         + body + "</SOAP-ENV:Body>" + "</SOAP-ENV:Envelope>";
346         Message responseMsg = null;
347         try
348         {
349             ByteArrayInputStream istream = new ByteArrayInputStream(msgtxt.getBytes("ISO-8859-1"));
350             AxisEngine engine = getAxisServer();
351             Message msg = new Message(istream, false);
352             msgContext.setRequestMessage(msg);
353             engine.invoke(msgContext);
354             responseMsg = msgContext.getResponseMessage();
355             response.setProperty(HTTPConstants.HEADER_CACHE_CONTROL, "no-cache");
356             response.setProperty(HTTPConstants.HEADER_PRAGMA, "no-cache");
357             if (responseMsg == null)
358             {
359                 throw new Exception(Messages.getMessage("noResponse01"));
360             }
361         }
362         catch (AxisFault fault)
363         {
364             processAxisFault(fault);
365             configureResponseFromAxisFault(response, fault);
366             responseMsg = new Message(fault);
367         }
368         catch (Exception e)
369         {
370             response.setProperty(HttpConnector.HTTP_STATUS_PROPERTY, "500");
371             responseMsg = convertExceptionToAxisFault(e, responseMsg);
372         }
373         response.setProperty(HTTPConstants.HEADER_CONTENT_TYPE, "text/xml");
374         response.write(responseMsg.getSOAPPartAsString());
375     }
376 
377     protected void reportServiceInfo(WriterMessageAdapter response, SOAPService service, String serviceName)
378     {
379         response.setProperty(HttpConstants.HEADER_CONTENT_TYPE, "text/html");
380         response.write("<h1>" + service.getName() + "</h1>");
381         response.write("<p>" + Messages.getMessage("axisService00") + "</p>");
382         response.write("<i>" + Messages.getMessage("perhaps00") + "</i>");
383     }
384 
385     protected void processListRequest(WriterMessageAdapter response) throws AxisFault
386     {
387         AxisEngine engine = getAxisServer();
388         response.setProperty(HTTPConstants.HEADER_CONTENT_TYPE, "text/html");
389         if (enableList)
390         {
391             Document doc = Admin.listConfig(engine);
392             if (doc != null)
393             {
394                 XMLUtils.DocumentToWriter(doc, response.getWriter());
395             }
396             else
397             {
398                 response.setProperty(HttpConnector.HTTP_STATUS_PROPERTY, "404");
399                 response.write("<h2>" + Messages.getMessage("error00") + "</h2>");
400                 response.write("<p>" + Messages.getMessage("noDeploy00") + "</p>");
401             }
402         }
403         else
404         {
405             response.setProperty(HttpConnector.HTTP_STATUS_PROPERTY, "403");
406             response.write("<h2>" + Messages.getMessage("error00") + "</h2>");
407             response.write("<p><i>?list</i> " + Messages.getMessage("disabled00") + "</p>");
408         }
409     }
410 
411     private void reportNoWSDL(WriterMessageAdapter response, String moreDetailCode, AxisFault axisFault)
412     {
413         response.setProperty(HttpConnector.HTTP_STATUS_PROPERTY, "404");
414         response.setProperty(HTTPConstants.HEADER_CONTENT_TYPE, "text/html");
415         response.write("<h2>" + Messages.getMessage("error00") + "</h2>");
416         response.write("<p>" + Messages.getMessage("noWSDL00") + "</p>");
417         if (moreDetailCode != null)
418         {
419             response.write("<p>" + Messages.getMessage(moreDetailCode) + "</p>");
420         }
421 
422     }
423 
424     protected void reportAvailableServices(UMOEventContext context, WriterMessageAdapter response)
425         throws ConfigurationException, AxisFault
426     {
427         AxisEngine engine = getAxisServer();
428         response.setProperty(HttpConstants.HEADER_CONTENT_TYPE, "text/html");
429         response.write("<h2>And now... Some Services</h2>");
430         String version = MuleManager.getConfiguration().getProductVersion();
431         if (version == null)
432         {
433             version = "Version Not Set";
434         }
435         response.write("<h5>(Mule - " + version + ")</h5>");
436         Iterator i;
437 
438         try
439         {
440             response
441                 .write("<table width=\"400\"><tr><th>Mule Component Services</th><th>Axis Services</th></tr><tr><td width=\"200\" valign=\"top\">");
442             i = engine.getConfig().getDeployedServices();
443             listServices(i, response);
444             response.write("</td><td width=\"200\" valign=\"top\">");
445             i = ((MuleConfigProvider)engine.getConfig()).getAxisDeployedServices();
446             listServices(i, response);
447             response.write("</td></tr></table>");
448         }
449         catch (ConfigurationException configException)
450         {
451             if (configException.getContainedException() instanceof AxisFault)
452             {
453                 throw (AxisFault)configException.getContainedException();
454             }
455             else
456             {
457                 throw configException;
458             }
459         }
460 
461     }
462 
463     private void listServices(Iterator i, WriterMessageAdapter response)
464     {
465         response.write("<ul>");
466         while (i.hasNext())
467         {
468             ServiceDesc sd = (ServiceDesc)i.next();
469             StringBuffer sb = new StringBuffer(512);
470             sb.append("<li>");
471             String name = sd.getName();
472             sb.append(name);
473             sb.append(" <a href=\"");
474             if (sd.getEndpointURL() != null)
475             {
476                 sb.append(sd.getEndpointURL());
477                 if (!sd.getEndpointURL().endsWith("/"))
478                 {
479                     sb.append("/");
480                 }
481             }
482             sb.append(name);
483             sb.append("?wsdl\"><i>(wsdl)</i></a></li>");
484             response.write(sb.toString());
485             if (sd.getDocumentation() != null)
486             {
487                 response.write("<ul><h6>" + sd.getDocumentation() + "</h6></ul>");
488             }
489             ArrayList operations = sd.getOperations();
490             if (!operations.isEmpty())
491             {
492                 response.write("<ul>");
493                 OperationDesc desc;
494                 for (Iterator it = operations.iterator(); it.hasNext();)
495                 {
496                     desc = (OperationDesc)it.next();
497                     response.write("<li>" + desc.getName());
498                 }
499                 response.write("</ul>");
500             }
501         }
502         response.write("</ul>");
503     }
504 
505     protected void reportCantGetAxisService(UMOEventContext context, WriterMessageAdapter response)
506     {
507         response.setProperty(HttpConnector.HTTP_STATUS_PROPERTY, "404");
508         response.setProperty(HttpConstants.HEADER_CONTENT_TYPE, "text/html");
509         response.write("<h2>" + Messages.getMessage("error00") + "</h2>");
510         response.write("<p>" + Messages.getMessage("noService06") + "</p>");
511     }
512 
513     protected void doPost(UMOEventContext context, WriterMessageAdapter response)
514         throws Exception
515     {
516         String soapAction;
517         Message responseMsg;
518         AxisEngine engine = getAxisServer();
519         if (engine == null)
520         {
521 
522             throw new MessagingException(CoreMessages.objectIsNull("Axis Engine"), context.getMessage());
523         }
524         MessageContext msgContext = new MessageContext(engine);
525 
526         String contentType;
527         try
528         {
529             UMOEndpointURI endpointUri = getEndpoint(context);
530             populateMessageContext(msgContext, context, endpointUri);
531             if (securityProvider != null)
532             {
533                 if (logger.isDebugEnabled())
534                 {
535                     logger.debug("securityProvider:" + securityProvider);
536                 }
537                 msgContext.setProperty("securityProvider", securityProvider);
538             }
539 
540             Object request = context.getTransformedMessage();
541             if (request instanceof File)
542             {
543                 request = new FileInputStream((File)request);
544             }
545             else if (request instanceof byte[])
546             {
547                 request = new ByteArrayInputStream((byte[])request);
548             }
549 
550             Message requestMsg = new Message(request, false, context.getMessage().getStringProperty(
551                 HTTPConstants.HEADER_CONTENT_TYPE, null), context.getMessage().getStringProperty(
552                 HTTPConstants.HEADER_CONTENT_LOCATION, null));
553 
554             if (logger.isDebugEnabled())
555             {
556                 logger.debug("Request Message:" + requestMsg);
557             }
558             msgContext.setRequestMessage(requestMsg);
559             msgContext.setProperty("transport.url", endpointUri.toString());
560 
561             soapAction = getSoapAction(context);
562             if (soapAction != null)
563             {
564                 msgContext.setUseSOAPAction(true);
565                 msgContext.setSOAPActionURI(soapAction);
566             }
567             msgContext.setSession(new AxisMuleSession(context.getSession()));
568 
569             if (logger.isDebugEnabled())
570             {
571                 logger.debug("Invoking Axis Engine.");
572             }
573             engine.invoke(msgContext);
574             if (logger.isDebugEnabled())
575             {
576                 logger.debug("Return from Axis Engine.");
577             }
578             if (RequestContext.getExceptionPayload() instanceof Exception)
579             {
580                 throw (Exception)RequestContext.getExceptionPayload().getException();
581             }
582             // remove temporary file used for soap message with attachment
583             if (request instanceof File)
584             {
585                 ((File)request).delete();
586             }
587             responseMsg = msgContext.getResponseMessage();
588             if (responseMsg == null)
589             {
590                 throw new Exception(Messages.getMessage("noResponse01"));
591             }
592         }
593         catch (AxisFault fault)
594         {
595             logger.error(fault.toString() + " target service is: " + msgContext.getTargetService()
596                             + ". Event is: " + context.toString(), fault);
597             processAxisFault(fault);
598             configureResponseFromAxisFault(response, fault);
599             responseMsg = msgContext.getResponseMessage();
600             if (responseMsg == null)
601             {
602                 responseMsg = new Message(fault);
603             }
604         }
605         catch (Exception e)
606         {
607             responseMsg = msgContext.getResponseMessage();
608             response.setProperty(HttpConnector.HTTP_STATUS_PROPERTY, "500");
609             responseMsg = convertExceptionToAxisFault(e, responseMsg);
610         }
611 
612         contentType = responseMsg.getContentType(msgContext.getSOAPConstants());
613 
614         sendResponse(contentType, response, responseMsg);
615 
616         if (logger.isDebugEnabled())
617         {
618             logger.debug("Response sent.");
619         }
620     }
621 
622     private UMOEndpointURI getEndpoint(UMOEventContext context) throws MalformedEndpointException
623     {
624         String endpoint = context.getEndpointURI().getAddress();
625         String request = context.getMessage().getStringProperty(HttpConnector.HTTP_REQUEST_PROPERTY, null);
626         if (request != null)
627         {
628             int i = endpoint.indexOf("/", endpoint.indexOf("://") + 3);
629             if (i > -1)
630             {
631                 endpoint = endpoint.substring(0, i);
632             }
633             endpoint += request;
634             return new MuleEndpointURI(endpoint);
635         }
636         return context.getEndpointURI();
637     }
638 
639     private void configureResponseFromAxisFault(WriterMessageAdapter response, AxisFault fault)
640     {
641         int status = getHttpResponseStatus(fault);
642         if (status == 401)
643         {
644             response.setProperty(HttpConstants.HEADER_WWW_AUTHENTICATE, "Basic realm=\"AXIS\"");
645         }
646         response.setProperty(HttpConnector.HTTP_STATUS_PROPERTY, String.valueOf(status));
647     }
648 
649     private Message convertExceptionToAxisFault(Exception exception, Message responseMsg)
650     {
651         logger.error(exception.getMessage(), exception);
652         if (responseMsg == null)
653         {
654             AxisFault fault = AxisFault.makeFault(exception);
655             processAxisFault(fault);
656             responseMsg = new Message(fault);
657         }
658         return responseMsg;
659     }
660 
661     protected int getHttpResponseStatus(AxisFault af)
662     {
663         return af.getFaultCode().getLocalPart().startsWith("Server.Unauth") ? 401 : '\u01F4';
664     }
665 
666     private void sendResponse(String contentType,
667                               WriterMessageAdapter response,
668                               Message responseMsg) throws Exception
669     {
670         if (responseMsg == null)
671         {
672             response.setProperty(HttpConnector.HTTP_STATUS_PROPERTY, "204");
673             if (logger.isDebugEnabled())
674             {
675                 logger.debug("NO AXIS MESSAGE TO RETURN!");
676             }
677         }
678         else
679         {
680             if (logger.isDebugEnabled())
681             {
682                 logger.debug("Returned Content-Type:" + contentType);
683             }
684                 response.setProperty(HttpConstants.HEADER_CONTENT_TYPE, contentType);
685                 ByteArrayOutputStream baos = new ByteArrayOutputStream(8192);
686                 responseMsg.writeTo(baos);
687                 response.write(baos.toString());
688         }
689     }
690 
691     private void populateMessageContext(MessageContext msgContext,
692                                         UMOEventContext context,
693                                         UMOEndpointURI endpointUri) throws AxisFault, ConfigurationException
694     {
695         UMOMessage msg = context.getMessage();
696 
697         if (logger.isDebugEnabled())
698         {
699             logger.debug("MessageContext:" + msgContext);
700             logger.debug("HEADER_CONTENT_TYPE:"
701                             + msg.getStringProperty(HttpConstants.HEADER_CONTENT_TYPE, null));
702             logger.debug("HEADER_CONTENT_LOCATION:"
703                             + msg.getStringProperty(HttpConstants.HEADER_CONTENT_LOCATION, null));
704             logger.debug("Constants.MC_HOME_DIR:" + String.valueOf(getHomeDir()));
705             logger.debug("Constants.MC_RELATIVE_PATH:" + endpointUri.getPath());
706             logger.debug("HTTPConstants.HEADER_AUTHORIZATION:" + msg.getStringProperty("Authorization", null));
707             logger.debug("Constants.MC_REMOTE_ADDR:" + endpointUri.getHost());
708         }
709 
710         msgContext.setTransportName(transportName);
711         msgContext.setProperty("home.dir", getHomeDir());
712         msgContext.setProperty("path", endpointUri.getPath());
713         msgContext.setProperty(HTTPConstants.MC_HTTP_SERVLET, this);
714         msgContext.setProperty(HTTPConstants.MC_HTTP_SERVLETLOCATION, endpointUri.getPath());
715         // determine service name
716         String serviceName = getServiceName(context, endpointUri);
717         // Validate Service path against request path
718         SOAPService service = msgContext.getAxisEngine().getConfig().getService(
719             new QName(serviceName.substring(1)));
720 
721         // if using jms or vm we can skip this
722         if (!("vm".equalsIgnoreCase(endpointUri.getScheme()) || "jms".equalsIgnoreCase(endpointUri.getScheme())))
723         {            
724             // Component Name is set by Mule so if its null we can skip this check
725             if (service.getOption(AxisConnector.SERVICE_PROPERTY_COMPONENT_NAME) != null)
726             {
727                 String servicePath = (String)service.getOption("servicePath");
728                 if (StringUtils.isEmpty(endpointUri.getPath()))
729                 {
730                     if (!("/" + endpointUri.getAddress()).startsWith(servicePath + serviceName))
731                     {
732                         throw new AxisFault("Failed to find service: " + "/" + endpointUri.getAddress());
733                     }
734                 }
735                 else if (!endpointUri.getPath().startsWith(servicePath + serviceName))
736                 {
737                     throw new AxisFault("Failed to find service: " + endpointUri.getPath());
738                 }
739             }
740         }
741 
742         msgContext.setProperty(HTTPConstants.MC_HTTP_SERVLETPATHINFO, serviceName);
743         msgContext.setProperty("serviceName", serviceName);
744 
745         msgContext.setProperty("Authorization", msg.getStringProperty("Authorization", null));
746         msgContext.setProperty("remoteaddr", endpointUri.getHost());
747         ServletEndpointContextImpl sec = new ServletEndpointContextImpl();
748         msgContext.setProperty("servletEndpointContext", sec);
749     }
750 
751     private String getSoapAction(UMOEventContext context) throws AxisFault
752     {
753         String soapAction = context.getMessage().getStringProperty("SOAPAction", null);
754         if (logger.isDebugEnabled())
755         {
756             logger.debug("Header Soap Action:" + soapAction);
757         }
758 
759         if (StringUtils.isEmpty(soapAction))
760         {
761             soapAction = context.getEndpointURI().getAddress();
762         }
763         return soapAction;
764     }
765 
766     protected String getServiceName(UMOEventContext context, UMOEndpointURI endpointUri) throws AxisFault
767     {
768         String serviceName = endpointUri.getPath();
769         if (StringUtils.isEmpty(serviceName))
770         {
771             serviceName = getSoapAction(context);
772             serviceName = serviceName.replaceAll("\"", "");
773             int i = serviceName.indexOf("/", serviceName.indexOf("//"));
774             if (i < -1)
775             {
776                 serviceName = serviceName.substring(i + 2);
777             }
778 
779         }
780 
781         int i = serviceName.lastIndexOf('/');
782         if (i > -1)
783         {
784             serviceName = serviceName.substring(i);
785         }
786         i = serviceName.lastIndexOf('?');
787         if (i > -1)
788         {
789             serviceName = serviceName.substring(0, i);
790         }
791         return serviceName;
792     }
793 
794     public String getTransportName()
795     {
796         return transportName;
797     }
798 
799     public void setTransportName(String transportName)
800     {
801         this.transportName = transportName;
802     }
803 
804     public boolean isEnableList()
805     {
806         return enableList;
807     }
808 
809     public void setEnableList(boolean enableList)
810     {
811         this.enableList = enableList;
812     }
813 
814     public String getHomeDir()
815     {
816         if (homeDir == null)
817         {
818             homeDir = MuleManager.getConfiguration().getWorkingDirectory() + DEFAULT_AXIS_HOME;
819         }
820         return homeDir;
821     }
822 
823     public void setHomeDir(String homeDir)
824     {
825         this.homeDir = homeDir;
826     }
827 
828     public AxisServer getAxisServer()
829     {
830         return axisServer;
831     }
832 
833     public void setAxisServer(AxisServer axisServer)
834     {
835         this.axisServer = axisServer;
836     }
837 }