View Javadoc

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