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.module.cxf.support;
8   
9   import org.mule.module.cxf.i18n.CxfMessages;
10  
11  import java.util.Iterator;
12  import java.util.LinkedList;
13  import java.util.List;
14  import java.util.Map;
15  import java.util.logging.Logger;
16  
17  import javax.wsdl.Definition;
18  import javax.wsdl.Port;
19  import javax.wsdl.Service;
20  import javax.wsdl.WSDLException;
21  import javax.xml.namespace.QName;
22  
23  import org.apache.commons.collections.CollectionUtils;
24  import org.apache.commons.collections.Predicate;
25  import org.apache.cxf.common.i18n.Message;
26  import org.apache.cxf.common.logging.LogUtils;
27  import org.apache.cxf.service.factory.DefaultServiceConfiguration;
28  import org.apache.cxf.service.factory.ServiceConstructionException;
29  import org.apache.cxf.wsdl.WSDLManager;
30  
31  public class ProxyServiceConfiguration extends DefaultServiceConfiguration
32  {
33  
34      private static final Logger LOG = LogUtils.getLogger(ProxyServiceFactoryBean.class);
35  
36      /**
37       * Override to use port name from service definition in WSDL when we are doing
38       * WSDL-first. This is required so that CXF's internal endpointName and port name
39       * match and a CXF Service gets created. See:
40       * https://issues.apache.org/jira/browse/CXF-1920
41       * http://fisheye6.atlassian.com/changelog/cxf?cs=737994
42       */
43      @Override
44      public QName getEndpointName()
45      {
46          try
47          {
48              if (getServiceFactory().getWsdlURL() != null)
49              {
50                  Definition definition = getServiceFactory().getBus()
51                      .getExtension(WSDLManager.class)
52                      .getDefinition(getServiceFactory().getWsdlURL());
53                  Service service = getServiceFromDefinition(definition);
54                  setServiceNamespace(service.getQName().getNamespaceURI());
55                  return new QName(getServiceNamespace(), ((Port) service.getPorts().values().iterator().next()).getName());
56              }
57              else
58              {
59                  return super.getEndpointName();
60              }
61  
62          }
63          catch (WSDLException e)
64          {
65              throw new ServiceConstructionException(new Message("SERVICE_CREATION_MSG", LOG), e);
66          }
67      }
68  
69      protected Service getServiceFromDefinition(Definition definition)
70      {
71          Service service = definition.getService(getServiceFactory().getServiceQName());
72          if (service == null)
73          {
74              List<QName> probableServices = getProbableServices(definition);
75              List<QName> allServices = getAllServices(definition);
76              throw new ComponentNotFoundRuntimeException(CxfMessages.invalidOrMissingNamespace(
77                  getServiceFactory().getServiceQName(), probableServices, allServices));
78          }
79          return service;
80      }
81  
82      /**
83       * This method returns a list of all the services defined in the definition. Its
84       * current purpose is only for generating a better error message when the service
85       * cannot be found.
86       */
87      @SuppressWarnings("unchecked")
88      protected List<QName> getAllServices(Definition definition)
89      {
90          return new LinkedList<QName>(CollectionUtils.select(definition.getServices().keySet(),
91              new Predicate()
92              {
93                  public boolean evaluate(Object object)
94                  {
95                      return object instanceof QName;
96                  }
97              }));
98      }
99  
100     /**
101      * This method returns the list of services that matches with the local part of
102      * the service QName. Its current purpose is only for generating a better error
103      * message when the service cannot be found.
104      */
105     protected List<QName> getProbableServices(Definition definition)
106     {
107         QName serviceQName = getServiceFactory().getServiceQName();
108         List<QName> probableServices = new LinkedList<QName>();
109         Map<?, ?> services = definition.getServices();
110         for (Iterator<?> iterator = services.keySet().iterator(); iterator.hasNext();)
111         {
112             Object key = iterator.next();
113             if (key instanceof QName)
114             {
115                 QName qNameKey = (QName) key;
116                 if (qNameKey.getLocalPart() != null
117                     && qNameKey.getLocalPart().equals(serviceQName.getLocalPart()))
118                 {
119                     probableServices.add(qNameKey);
120                 }
121             }
122         }
123         return probableServices;
124     }
125 }