001: /**
002: * Licensed to the Apache Software Foundation (ASF) under one
003: * or more contributor license agreements. See the NOTICE file
004: * distributed with this work for additional information
005: * regarding copyright ownership. The ASF licenses this file
006: * to you under the Apache License, Version 2.0 (the
007: * "License"); you may not use this file except in compliance
008: * with the License. You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing,
013: * software distributed under the License is distributed on an
014: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015: * KIND, either express or implied. See the License for the
016: * specific language governing permissions and limitations
017: * under the License.
018: */package org.apache.cxf.transport.http;
019:
020: import java.io.IOException;
021: import java.util.Collection;
022: import java.util.HashSet;
023: import java.util.Iterator;
024: import java.util.List;
025: import java.util.Set;
026:
027: import javax.annotation.PostConstruct;
028: import javax.annotation.Resource;
029: import javax.wsdl.Port;
030: import javax.wsdl.extensions.http.HTTPAddress;
031: import javax.wsdl.extensions.soap.SOAPAddress;
032: import javax.xml.namespace.QName;
033:
034: import org.apache.cxf.Bus;
035: import org.apache.cxf.configuration.Configurer;
036: import org.apache.cxf.service.Service;
037: import org.apache.cxf.service.model.BindingInfo;
038: import org.apache.cxf.service.model.EndpointInfo;
039: import org.apache.cxf.service.model.ServiceInfo;
040: import org.apache.cxf.transport.AbstractTransportFactory;
041: import org.apache.cxf.transport.Conduit;
042: import org.apache.cxf.transport.ConduitInitiator;
043: import org.apache.cxf.transport.ConduitInitiatorManager;
044: import org.apache.cxf.transport.Destination;
045: import org.apache.cxf.transport.DestinationFactory;
046: import org.apache.cxf.transport.DestinationFactoryManager;
047: import org.apache.cxf.transport.https.HttpsURLConnectionFactory;
048: import org.apache.cxf.ws.addressing.EndpointReferenceType;
049: import org.apache.cxf.wsdl11.WSDLEndpointFactory;
050: import org.xmlsoap.schemas.wsdl.http.AddressType;
051:
052: /**
053: * As a ConduitInitiator, this class sets up new HTTPConduits for particular
054: * endpoints.
055: *
056: * TODO: Document DestinationFactory
057: * TODO: Document WSDLEndpointFactory
058: *
059: */
060: public abstract class AbstractHTTPTransportFactory extends
061: AbstractTransportFactory implements ConduitInitiator,
062: DestinationFactory, WSDLEndpointFactory {
063:
064: /**
065: * This constant holds the prefixes served by this factory.
066: */
067: private static final Set<String> URI_PREFIXES = new HashSet<String>();
068: static {
069: URI_PREFIXES.add("http://");
070: URI_PREFIXES.add("https://");
071: }
072:
073: /**
074: * The CXF Bus which this HTTPTransportFactory
075: * is governed.
076: */
077: private Bus bus;
078:
079: /**
080: * This collection contains "activationNamespaces" which is synominous
081: * with "transportId"s. TransportIds are already part of
082: * AbstractTransportFactory.
083: * TODO: Change these to "transportIds"?
084: */
085: private Collection<String> activationNamespaces;
086:
087: /**
088: * This method is used by Spring to inject the bus.
089: * @param b The CXF bus.
090: */
091: @Resource(name="bus")
092: public void setBus(Bus b) {
093: bus = b;
094: }
095:
096: /**
097: * This method returns the CXF Bus under which this HTTPTransportFactory
098: * is governed.
099: */
100: public Bus getBus() {
101: return bus;
102: }
103:
104: /**
105: * This call is used by spring to "inject" the transport ids.
106: * TODO: Change this to "setTransportIds"?
107: * @param ans The transport ids.
108: */
109: @Resource(name="activationNamespaces")
110: public void setActivationNamespaces(Collection<String> ans) {
111: activationNamespaces = ans;
112: }
113:
114: /**
115: * This call gets called after this class is instantiated by Spring.
116: * It registers itself as a ConduitInitiator and DestinationFactory under
117: * the many names that are considered "transportIds" (which are currently
118: * named "activationNamespaces").
119: */
120: @PostConstruct
121: void registerWithBindingManager() {
122: if (null == bus) {
123: return;
124: }
125: ConduitInitiatorManager cim = bus
126: .getExtension(ConduitInitiatorManager.class);
127:
128: //Note, activationNamespaces can be null
129: if (null != cim && null != activationNamespaces) {
130: for (String ns : activationNamespaces) {
131: cim.registerConduitInitiator(ns, this );
132: }
133: }
134: DestinationFactoryManager dfm = bus
135: .getExtension(DestinationFactoryManager.class);
136: if (null != dfm && null != activationNamespaces) {
137: for (String ns : activationNamespaces) {
138: dfm.registerDestinationFactory(ns, this );
139: }
140: }
141: }
142:
143: /**
144: * This call creates a new HTTPConduit for the endpoint. It is equivalent
145: * to calling getConduit without an EndpointReferenceType.
146: */
147: public Conduit getConduit(EndpointInfo endpointInfo)
148: throws IOException {
149: return getConduit(endpointInfo, endpointInfo.getTarget());
150: }
151:
152: /**
153: * This call creates a new HTTP Conduit based on the EndpointInfo and
154: * EndpointReferenceType.
155: * TODO: What are the formal constraints on EndpointInfo and
156: * EndpointReferenceType values?
157: */
158: public Conduit getConduit(EndpointInfo endpointInfo,
159: EndpointReferenceType target) throws IOException {
160: HTTPConduit conduit = target == null ? new HTTPConduit(bus,
161: endpointInfo) : new HTTPConduit(bus, endpointInfo,
162: target);
163:
164: // Spring configure the conduit.
165: configure(conduit);
166: conduit.finalizeConfig();
167: return conduit;
168: }
169:
170: public abstract Destination getDestination(EndpointInfo endpointInfo)
171: throws IOException;
172:
173: public EndpointInfo createEndpointInfo(ServiceInfo serviceInfo,
174: BindingInfo b, Port port) {
175: if (port != null) {
176: List ees = port.getExtensibilityElements();
177: for (Iterator itr = ees.iterator(); itr.hasNext();) {
178: Object extensor = itr.next();
179:
180: if (extensor instanceof HTTPAddress) {
181: final HTTPAddress httpAdd = (HTTPAddress) extensor;
182:
183: EndpointInfo info = new HttpEndpointInfo(
184: serviceInfo,
185: "http://schemas.xmlsoap.org/wsdl/http/");
186: info.setAddress(httpAdd.getLocationURI());
187: info.addExtensor(httpAdd);
188: return info;
189: } else if (extensor instanceof AddressType) {
190: final AddressType httpAdd = (AddressType) extensor;
191:
192: EndpointInfo info = new HttpEndpointInfo(
193: 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,
202: "http://schemas.xmlsoap.org/wsdl/http/");
203: AddressType at = new HttpAddressType();
204: hei.addExtensor(at);
205:
206: return hei;
207: }
208:
209: public void createPortExtensors(EndpointInfo ei, Service service) {
210: // TODO
211: }
212:
213: public Set<String> getUriPrefixes() {
214: return URI_PREFIXES;
215: }
216:
217: /**
218: * This call uses the Configurer from the bus to configure
219: * a bean.
220: *
221: * @param bean
222: */
223: protected void configure(Object bean) {
224: Configurer configurer = bus.getExtension(Configurer.class);
225: if (null != configurer) {
226: configurer.configureBean(bean);
227: }
228: }
229:
230: /**
231: * This static call creates a connection factory based on
232: * the existence of the SSL (TLS) client side configuration.
233: */
234: static HttpURLConnectionFactory getConnectionFactory(
235: HTTPConduit configuredConduit) {
236: HttpURLConnectionFactory fac = null;
237:
238: if (configuredConduit.getTlsClientParameters() != null) {
239: fac = new HttpsURLConnectionFactory(configuredConduit
240: .getTlsClientParameters());
241: } else {
242: fac = new HttpURLConnectionFactoryImpl();
243: }
244: return fac;
245: }
246:
247: private static class HttpEndpointInfo extends EndpointInfo {
248: AddressType saddress;
249:
250: HttpEndpointInfo(ServiceInfo serv, String trans) {
251: super (serv, trans);
252: }
253:
254: public void setAddress(String s) {
255: super .setAddress(s);
256: if (saddress != null) {
257: saddress.setLocation(s);
258: }
259: }
260:
261: public void addExtensor(Object el) {
262: super .addExtensor(el);
263: if (el instanceof AddressType) {
264: saddress = (AddressType) el;
265: }
266: }
267: }
268:
269: private static class HttpAddressType extends AddressType implements
270: HTTPAddress, SOAPAddress {
271: public HttpAddressType() {
272: super ();
273: setElementType(new QName(
274: "http://schemas.xmlsoap.org/wsdl/soap/", "address"));
275: }
276:
277: public String getLocationURI() {
278: return getLocation();
279: }
280:
281: public void setLocationURI(String locationURI) {
282: setLocation(locationURI);
283: }
284:
285: }
286:
287: }
|