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