View Javadoc

1   /*
2    * $Id: MuleUniversalTransport.java 22409 2011-07-14 05:14:27Z 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.transport;
12  
13  import org.mule.module.cxf.CxfConfiguration;
14  
15  import java.io.IOException;
16  import java.util.ArrayList;
17  import java.util.HashMap;
18  import java.util.HashSet;
19  import java.util.Iterator;
20  import java.util.List;
21  import java.util.Map;
22  import java.util.Set;
23  
24  import javax.wsdl.Port;
25  import javax.wsdl.extensions.http.HTTPAddress;
26  import javax.wsdl.extensions.soap.SOAPAddress;
27  import javax.xml.namespace.QName;
28  
29  import org.apache.cxf.Bus;
30  import org.apache.cxf.service.Service;
31  import org.apache.cxf.service.model.BindingInfo;
32  import org.apache.cxf.service.model.EndpointInfo;
33  import org.apache.cxf.service.model.ServiceInfo;
34  import org.apache.cxf.transport.AbstractTransportFactory;
35  import org.apache.cxf.transport.Conduit;
36  import org.apache.cxf.transport.ConduitInitiator;
37  import org.apache.cxf.transport.Destination;
38  import org.apache.cxf.transport.DestinationFactory;
39  import org.apache.cxf.ws.addressing.AttributedURIType;
40  import org.apache.cxf.ws.addressing.EndpointReferenceType;
41  import org.apache.cxf.wsdl.http.AddressType;
42  import org.apache.cxf.wsdl11.WSDLEndpointFactory;
43  
44  public class MuleUniversalTransport extends AbstractTransportFactory
45      implements ConduitInitiator, DestinationFactory, WSDLEndpointFactory
46  {
47  
48      public static final String TRANSPORT_ID = "http://mule.codehaus.org/cxf";
49  
50      private static Set<String> PREFIXES = new HashSet<String>();
51      static
52      {
53          PREFIXES.add("http://");
54          PREFIXES.add("https://");
55          PREFIXES.add("jms://");
56          PREFIXES.add("vm://");
57          PREFIXES.add("xmpp://");
58          PREFIXES.add("smtp://");
59          PREFIXES.add("tcp://");
60      }
61  
62      private Map<String, Destination> destinations = new HashMap<String, Destination>();
63  
64      private Bus bus;
65  
66      private CxfConfiguration connector;
67  
68      public MuleUniversalTransport(CxfConfiguration connector)
69      {
70          super();
71  
72          ArrayList<String> tids = new ArrayList<String>();
73          tids.add("http://schemas.xmlsoap.org/soap/http");
74          setTransportIds(tids);
75  
76          this.connector = connector;
77      }
78  
79      @Override
80      public Destination getDestination(EndpointInfo ei) throws IOException
81      {
82          return getDestination(ei, createReference(ei));
83      }
84  
85      protected Destination getDestination(EndpointInfo ei, EndpointReferenceType reference) throws IOException
86      {
87          String uri = reference.getAddress().getValue();
88          int idx = uri.indexOf('?');
89          if (idx != -1)
90          {
91              uri = uri.substring(0, idx);
92          }
93  
94          synchronized (this)
95          {
96              Destination d = destinations.get(uri);
97              if (d == null)
98              {
99                  d = createDestination(ei, reference);
100                 destinations.put(uri, d);
101             }
102             return d;
103         }
104     }
105 
106     private Destination createDestination(EndpointInfo ei, EndpointReferenceType reference)
107     {
108         return new MuleUniversalDestination(this, reference, ei);
109     }
110 
111     @Override
112     public Conduit getConduit(EndpointInfo ei) throws IOException
113     {
114         return new MuleUniversalConduit(this, connector, ei, null);
115     }
116 
117     @Override
118     public Conduit getConduit(EndpointInfo ei, EndpointReferenceType target) throws IOException
119     {
120         return new MuleUniversalConduit(this, connector, ei, target);
121     }
122 
123     EndpointReferenceType createReference(EndpointInfo ei)
124     {
125         EndpointReferenceType epr = new EndpointReferenceType();
126         AttributedURIType address = new AttributedURIType();
127         address.setValue(ei.getAddress());
128         epr.setAddress(address);
129         return epr;
130     }
131 
132     @Override
133     public Set<String> getUriPrefixes()
134     {
135         return PREFIXES;
136     }
137 
138     @Override
139     public Bus getBus()
140     {
141         return bus;
142     }
143 
144     @Override
145     public void setBus(Bus bus)
146     {
147         this.bus = bus;
148     }
149 
150     void remove(MuleUniversalDestination destination)
151     {
152         destinations.remove(destination.getAddress().getAddress().getValue());
153     }
154 
155     public CxfConfiguration getConnector()
156     {
157         return connector;
158     }
159 
160     // Stuff relating to building of the <soap:address/> -
161     // I have no idea how this really works, but it does
162 
163     @Override
164     public void createPortExtensors(EndpointInfo ei, Service service)
165     {
166         // TODO
167     }
168 
169     @Override
170     public EndpointInfo createEndpointInfo(ServiceInfo serviceInfo, BindingInfo b, Port port)
171     {
172         if (port != null)
173         {
174             List<?> ees = port.getExtensibilityElements();
175             for (Iterator<?> itr = ees.iterator(); itr.hasNext();)
176             {
177                 Object extensor = itr.next();
178 
179                 if (extensor instanceof HTTPAddress)
180                 {
181                     final HTTPAddress httpAdd = (HTTPAddress) extensor;
182 
183                     EndpointInfo info = new HttpEndpointInfo(serviceInfo,
184                         "http://schemas.xmlsoap.org/wsdl/http/");
185                     info.setAddress(httpAdd.getLocationURI());
186                     info.addExtensor(httpAdd);
187                     return info;
188                 }
189                 else if (extensor instanceof AddressType)
190                 {
191                     final AddressType httpAdd = (AddressType) extensor;
192 
193                     EndpointInfo info = new HttpEndpointInfo(serviceInfo,
194                         "http://schemas.xmlsoap.org/wsdl/http/");
195                     info.setAddress(httpAdd.getLocation());
196                     info.addExtensor(httpAdd);
197                     return info;
198                 }
199             }
200         }
201         HttpEndpointInfo hei = new HttpEndpointInfo(serviceInfo, "http://schemas.xmlsoap.org/wsdl/http/");
202         AddressType at = new HttpAddressType();
203         hei.addExtensor(at);
204 
205         return hei;
206     }
207 
208     private static class HttpEndpointInfo extends EndpointInfo
209     {
210         AddressType saddress;
211 
212         HttpEndpointInfo(ServiceInfo serv, String trans)
213         {
214             super(serv, trans);
215         }
216 
217         @Override
218         public void setAddress(String s)
219         {
220             super.setAddress(s);
221             if (saddress != null)
222             {
223                 saddress.setLocation(s);
224             }
225         }
226 
227         @Override
228         public void addExtensor(Object el)
229         {
230             super.addExtensor(el);
231             if (el instanceof AddressType)
232             {
233                 saddress = (AddressType) el;
234             }
235         }
236     }
237 
238     private static class HttpAddressType extends AddressType implements HTTPAddress, SOAPAddress
239     {
240         public HttpAddressType()
241         {
242             super();
243             setElementType(new QName("http://schemas.xmlsoap.org/wsdl/soap/", "address"));
244         }
245 
246         @Override
247         public String getLocationURI()
248         {
249             return getLocation();
250         }
251 
252         @Override
253         public void setLocationURI(String locationURI)
254         {
255             setLocation(locationURI);
256         }
257 
258     }
259 }