View Javadoc

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