View Javadoc

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