View Javadoc

1   /*
2    * $Id: XFireMessageReceiver.java 9522 2007-10-31 16:18:38Z holger $
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.config.converters.QNameConverter;
14  import org.mule.providers.AbstractMessageReceiver;
15  import org.mule.providers.soap.SoapConstants;
16  import org.mule.umo.UMOComponent;
17  import org.mule.umo.UMOException;
18  import org.mule.umo.endpoint.UMOEndpoint;
19  import org.mule.umo.lifecycle.InitialisationException;
20  import org.mule.umo.provider.UMOConnector;
21  import org.mule.util.ClassUtils;
22  import org.mule.util.MapUtils;
23  import org.mule.util.StringUtils;
24  
25  import java.net.MalformedURLException;
26  import java.net.URL;
27  import java.util.HashMap;
28  import java.util.List;
29  import java.util.Map;
30  
31  import javax.xml.namespace.QName;
32  
33  import org.codehaus.xfire.annotations.WebAnnotations;
34  import org.codehaus.xfire.annotations.WebServiceAnnotation;
35  import org.codehaus.xfire.handler.Handler;
36  import org.codehaus.xfire.service.Service;
37  
38  /**
39   * Used to register an Xfire endpoint registered with Mule and associated with a
40   * component This receiver is responsible or registering the transport endpoint i.e.
41   * http:// as well as managing the association of this transport endpoint with the
42   * Xfire service.
43   */
44  public class XFireMessageReceiver extends AbstractMessageReceiver
45  {
46      private static final String PORT_TYPE = "portType";
47  
48      protected XFireConnector connector;
49      protected Service service;
50  
51      protected List serviceInterfaces;
52  
53      public XFireMessageReceiver(UMOConnector umoConnector,
54                                  UMOComponent component,
55                                  UMOEndpoint umoEndpoint) throws InitialisationException
56      {
57          super(umoConnector, component, umoEndpoint);
58          connector = (XFireConnector) umoConnector;
59          init();
60      }
61  
62      protected void init() throws InitialisationException
63      {
64          try
65          {
66              Map props = new HashMap(component.getDescriptor().getProperties());
67              props.putAll(endpoint.getProperties());
68  
69              // convert port Type to QName if specified
70              if (props.containsKey(PORT_TYPE))
71              {
72                  Object value = props.get(PORT_TYPE);
73                  QNameConverter converter = new QNameConverter(true);
74                  QName portTypeQName = (QName) converter.convert(QName.class, value);
75                  props.put(PORT_TYPE, portTypeQName);
76              }
77  
78              // check if there is the namespace property on the component
79              String namespace = (String) component.getDescriptor().getProperties().get(
80                  SoapConstants.SOAP_NAMESPACE_PROPERTY);
81  
82              // check for namespace set as annotation
83              if (connector.isEnableJSR181Annotations())
84              {
85                  WebAnnotations wa = (WebAnnotations) ClassUtils.instanciateClass(
86                      XFireConnector.CLASSNAME_ANNOTATIONS, null, this.getClass());
87                  WebServiceAnnotation webServiceAnnotation = wa.getWebServiceAnnotation(component
88                      .getDescriptor().getImplementationClass());
89                  namespace = webServiceAnnotation.getTargetNamespace();
90              }
91  
92              if ((namespace == null) || (namespace.equalsIgnoreCase("")))
93              {
94                  namespace = MapUtils.getString(props, "namespace",
95                      XFireConnector.DEFAULT_MULE_NAMESPACE_URI);
96              }
97              
98              //Convert createDefaultBindings string to boolean before rewriting as xfire property
99              if (props.get("createDefaultBindings") != null)
100             {
101                 props.put("createDefaultBindings", Boolean.valueOf((String) props.get("createDefaultBindings")));  
102             }
103 
104             if (props.size() == 0)
105             {
106                 // Xfire checks that properties are null rather than empty
107                 props = null;
108             }
109             else
110             {
111                 rewriteProperty(props, PORT_TYPE);
112                 rewriteProperty(props, "style");
113                 rewriteProperty(props, "use");
114                 rewriteProperty(props, "createDefaultBindings");
115                 rewriteProperty(props, "soap12Transports");
116                 rewriteProperty(props, "soap11Transports");
117                 rewriteProperty(props, "scope");
118                 rewriteProperty(props, "schemas");
119             }
120 
121             serviceInterfaces = (List) component.getDescriptor().getProperties().get("serviceInterfaces");
122             Class exposedInterface;
123 
124             if (serviceInterfaces == null)
125             {
126                 exposedInterface = component.getDescriptor().getImplementationClass();
127             }
128 
129             else
130             {
131                 String className = (String) serviceInterfaces.get(0);
132                 exposedInterface = ClassUtils.loadClass(className, this.getClass());
133                 logger.info(className + " class was used to expose your service");
134 
135                 if (serviceInterfaces.size() > 1)
136                 {
137                     logger.info("Only the first class was used to expose your method");
138                 }
139             }
140 
141             String wsdlUrl = (String) component.getDescriptor().getProperties().get(
142                 SoapConstants.WSDL_URL_PROPERTY);
143 
144             if (StringUtils.isBlank(wsdlUrl))
145             {
146                 service = connector.getServiceFactory().create(exposedInterface,
147                     component.getDescriptor().getName(), namespace, props);
148             }
149             else
150             {
151                 service = connector.getServiceFactory().create(exposedInterface,
152                     new QName(namespace, component.getDescriptor().getName()), new URL(wsdlUrl),
153                     props);
154             }
155 
156             List inList = connector.getServerInHandlers();
157             if (inList != null)
158             {
159                 for (int i = 0; i < inList.size(); i++)
160                 {
161                     Class clazz = ClassUtils.loadClass(inList.get(i).toString(), this.getClass());
162                     Handler handler = (Handler) clazz.getConstructor(null).newInstance(null);
163                     service.addInHandler(handler);
164                 }
165             }
166 
167             boolean sync = endpoint.isSynchronous();
168             // default to synchronous if using http
169             if (endpoint.getEndpointURI().getScheme().startsWith("http")
170                 || endpoint.getEndpointURI().getScheme().startsWith("servlet"))
171             {
172                 sync = true;
173             }
174             service.setInvoker(new MuleInvoker(this, sync));
175 
176         }
177         catch (UMOException e)
178         {
179             throw new InitialisationException(e, this);
180         }
181         catch (ClassNotFoundException e)
182         {
183             // will be thrown in the case that the ClassUtils.loadClass() does
184             // not find the class to load
185             throw new InitialisationException(e, this);
186         }
187         catch (MalformedURLException e)
188         {
189             throw new InitialisationException(e, this);
190         }
191         catch (Exception e)
192         {
193             throw new InitialisationException(e, this);
194         }
195     }
196 
197     protected void doDispose()
198     {
199         // template method
200     }
201 
202     public void doConnect() throws Exception
203     {
204         // Tell the Xfire registry about our new service.
205         connector.getXfire().getServiceRegistry().register(service);
206         connector.registerReceiverWithMuleService(this, endpoint.getEndpointURI());
207     }
208 
209     public void doDisconnect() throws Exception
210     {
211         connector.getXfire().getServiceRegistry().unregister(service);
212     }
213 
214     public void doStart() throws UMOException
215     {
216         // nothing to do
217     }
218 
219     public void doStop() throws UMOException
220     {
221         // nothing to do
222     }
223 
224     protected void rewriteProperty(Map props, String name)
225     {
226         if (props.containsKey(name))
227         {
228             Object temp = props.remove(name);
229             props.put("objectServiceFactory." + name, temp);
230         }
231     }
232 
233 }