View Javadoc
1   /*
2    * Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.com
3    * The software in this package is published under the terms of the CPAL v1.0
4    * license, a copy of which has been included with this distribution in the
5    * LICENSE.txt file.
6    */
7   package org.mule.transport.soap.axis.extensions;
8   
9   import org.mule.RequestContext;
10  import org.mule.api.service.Service;
11  import org.mule.transport.soap.axis.AxisConnector;
12  import org.mule.transport.soap.axis.AxisMessageReceiver;
13  import org.mule.transport.soap.axis.AxisServiceProxy;
14  
15  import java.lang.reflect.Proxy;
16  
17  import org.apache.axis.AxisFault;
18  import org.apache.axis.Constants;
19  import org.apache.axis.MessageContext;
20  import org.apache.axis.description.OperationDesc;
21  import org.apache.axis.handlers.soap.SOAPService;
22  import org.apache.axis.providers.java.MsgProvider;
23  import org.apache.commons.logging.Log;
24  import org.apache.commons.logging.LogFactory;
25  
26  /**
27   * <code>MuleMsgProvider</code> is an Axis service endpoint that builds services
28   * from Mule managed components.
29   */
30  public class MuleMsgProvider extends MsgProvider
31  {
32      /**
33       * Serial version
34       */
35      private static final long serialVersionUID = -4399291846942449361L;
36  
37      private AxisConnector connector;
38  
39      private static Log logger = LogFactory.getLog(MuleMsgProvider.class);
40  
41      private String METHOD_BODYARRAY = "soapbodyelement";
42      private String METHOD_ELEMENTARRAY = "element";
43      private String METHOD_DOCUMENT = "document";
44  
45      public MuleMsgProvider(AxisConnector connector)
46      {
47          this.connector = connector;
48      }
49  
50      protected Object makeNewServiceObject(MessageContext messageContext, String s) throws Exception
51      {
52          String transUrl = (String)messageContext.getProperty("transport.url");
53          int i = transUrl.indexOf('?');
54          if (i > -1)
55          {
56              transUrl = transUrl.substring(0, i);
57          }
58          AxisMessageReceiver receiver = (AxisMessageReceiver)connector.lookupReceiver(transUrl);
59          if (receiver == null)
60          {
61              receiver = (AxisMessageReceiver)connector.lookupReceiver(messageContext.getTargetService());
62          }
63          if (receiver == null)
64          {
65              throw new AxisFault("Could not find Mule registered service: " + s);
66          }
67          
68          if (!(receiver.getFlowConstruct() instanceof Service))
69          {
70              throw new IllegalArgumentException(
71                  "Only the Service flow constuct is supported by the axis transport");
72          }
73          Service service = (Service) receiver.getFlowConstruct();
74          
75          Class[] classes = AxisServiceProxy.getInterfacesForComponent(service);
76          return AxisServiceProxy.createProxy(receiver, true, classes);
77      }
78  
79      protected Class getServiceClass(String s, SOAPService soapService, MessageContext messageContext)
80          throws AxisFault
81      {
82          Service component = connector.getMuleContext().getRegistry().lookupService(soapService.getName());
83          try
84          {
85              Class[] classes = AxisServiceProxy.getInterfacesForComponent(component);
86              return Proxy.getProxyClass(Thread.currentThread().getContextClassLoader(), classes);
87          }
88          catch (Exception e)
89          {
90              throw new AxisFault("Failed to implementation class for component: " + e.getMessage(), e);
91          }
92      }
93  
94      /**
95       * @param msgContext
96       * @deprecated I dont think this is necessary, but leaving it here for a while
97       */
98      protected void setOperationStyle(MessageContext msgContext)
99      {
100         /*
101          * Axis requires that the OperationDesc.operationStyle be set to match the
102          * method signature This does not appear to be an automated process so
103          * determine from the 4 allowed forms public Element [] method(Element []
104          * bodies); public SOAPBodyElement [] method (SOAPBodyElement [] bodies);
105          * public Document method(Document body); public void method(SOAPEnvelope
106          * req, SOAPEnvelope resp);
107          */
108         int methodType = msgContext.getOperation().getMessageOperationStyle();
109         if (methodType > -1)
110         {
111             // Already set, nothing more to do
112             return;
113         }
114         OperationDesc operation = msgContext.getOperation();
115         String methodSignature = operation.getMethod().toString().toLowerCase();
116         if (methodSignature.indexOf(METHOD_BODYARRAY) != -1)
117         {
118             methodType = OperationDesc.MSG_METHOD_BODYARRAY;
119         }
120         else if (methodSignature.indexOf(METHOD_ELEMENTARRAY) != -1)
121         {
122             methodType = OperationDesc.MSG_METHOD_ELEMENTARRAY;
123         }
124         else if (methodSignature.indexOf(METHOD_DOCUMENT) != -1)
125         {
126             methodType = OperationDesc.MSG_METHOD_DOCUMENT;
127         }
128         else
129         {
130             methodType = OperationDesc.MSG_METHOD_SOAPENVELOPE;
131         }
132         operation.setMessageOperationStyle(methodType);
133         logger.debug("Now Invoking service (Method Format) " + operation.getMethod().toString());
134         logger.debug("Now Invoking service (MethodType) "
135                      + String.valueOf(operation.getMessageOperationStyle()));
136     }
137 
138     public void invoke(MessageContext msgContext) throws AxisFault
139     {
140         // Make sure that the method style is correctly set (This does not appear to
141         // be handled by default)
142         // setOperationStyle(msgContext);
143         super.invoke(msgContext);
144         if (RequestContext.getExceptionPayload() != null)
145         {
146             Throwable t = RequestContext.getExceptionPayload().getException();
147             if (t instanceof Exception)
148             {
149                 AxisFault fault = AxisFault.makeFault((Exception)t);
150                 if (t instanceof RuntimeException)
151                 {
152                     fault.addFaultDetail(Constants.QNAME_FAULTDETAIL_RUNTIMEEXCEPTION, "true");
153                 }
154                 throw fault;
155             }
156             else
157             {
158                 throw (Error)t;
159             }
160         }
161     }
162 
163 }