001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: package org.apache.servicemix.cxfbc;
018:
019: import java.io.InputStream;
020: import java.io.OutputStream;
021: import java.net.URI;
022: import java.util.ArrayList;
023: import java.util.List;
024: import java.util.concurrent.CopyOnWriteArrayList;
025: import java.util.logging.Logger;
026:
027: import javax.jbi.management.DeploymentException;
028: import javax.jbi.messaging.ExchangeStatus;
029: import javax.jbi.messaging.MessageExchange;
030: import javax.jbi.messaging.NormalizedMessage;
031: import javax.wsdl.factory.WSDLFactory;
032: import javax.wsdl.xml.WSDLReader;
033: import javax.xml.namespace.QName;
034: import javax.xml.stream.XMLStreamException;
035: import javax.xml.stream.XMLStreamWriter;
036: import javax.xml.transform.Source;
037: import javax.xml.transform.stream.StreamSource;
038:
039: import com.ibm.wsdl.Constants;
040:
041: import org.apache.cxf.Bus;
042: import org.apache.cxf.binding.AbstractBindingFactory;
043:
044: import org.apache.cxf.binding.soap.interceptor.SoapOutInterceptor;
045: import org.apache.cxf.binding.soap.interceptor.SoapPreProtocolOutInterceptor;
046: import org.apache.cxf.bus.spring.SpringBusFactory;
047: import org.apache.cxf.common.logging.LogUtils;
048: import org.apache.cxf.endpoint.Endpoint;
049: import org.apache.cxf.endpoint.EndpointImpl;
050: import org.apache.cxf.interceptor.AttachmentOutInterceptor;
051: import org.apache.cxf.interceptor.Interceptor;
052: import org.apache.cxf.interceptor.StaxOutInterceptor;
053:
054: import org.apache.cxf.message.Exchange;
055: import org.apache.cxf.message.ExchangeImpl;
056: import org.apache.cxf.message.Message;
057: import org.apache.cxf.phase.PhaseChainCache;
058: import org.apache.cxf.phase.PhaseInterceptorChain;
059: import org.apache.cxf.phase.PhaseManager;
060: import org.apache.cxf.service.Service;
061: import org.apache.cxf.service.model.BindingOperationInfo;
062: import org.apache.cxf.service.model.EndpointInfo;
063: import org.apache.cxf.service.model.ServiceInfo;
064: import org.apache.cxf.transport.Conduit;
065: import org.apache.cxf.transport.ConduitInitiator;
066: import org.apache.cxf.transport.ConduitInitiatorManager;
067: import org.apache.cxf.transport.jbi.JBIMessageHelper;
068: import org.apache.cxf.wsdl11.WSDLServiceFactory;
069: import org.apache.servicemix.common.endpoints.ProviderEndpoint;
070: import org.apache.servicemix.cxfbc.interceptors.JbiOutInterceptor;
071: import org.apache.servicemix.cxfbc.interceptors.JbiOutWsdl1Interceptor;
072: import org.apache.servicemix.cxfbc.interceptors.MtomCheckInterceptor;
073: import org.apache.servicemix.soap.util.DomUtil;
074: import org.springframework.core.io.Resource;
075:
076: /**
077: *
078: * @author gnodet
079: * @org.apache.xbean.XBean element="provider"
080: */
081: public class CxfBcProvider extends ProviderEndpoint implements
082: CxfBcEndpointWithInterceptor {
083:
084: private static final Logger LOG = LogUtils
085: .getL7dLogger(org.apache.servicemix.cxfbc.CxfBcProvider.class);
086:
087: List<Interceptor> in = new CopyOnWriteArrayList<Interceptor>();
088:
089: List<Interceptor> out = new CopyOnWriteArrayList<Interceptor>();
090:
091: List<Interceptor> outFault = new CopyOnWriteArrayList<Interceptor>();
092:
093: List<Interceptor> inFault = new CopyOnWriteArrayList<Interceptor>();
094:
095: private Resource wsdl;
096:
097: private String busCfg;
098:
099: private Bus bus;
100:
101: private ConduitInitiator conduitInit;
102:
103: private URI locationURI;
104:
105: private EndpointInfo ei;
106:
107: private Endpoint ep;
108:
109: private Service cxfService;
110:
111: private boolean mtomEnabled;
112:
113: private boolean useJBIWrapper = true;
114:
115: public void processExchange(MessageExchange exchange) {
116:
117: }
118:
119: public void process(MessageExchange exchange) throws Exception {
120:
121: if (exchange.getStatus() != ExchangeStatus.ACTIVE) {
122: return;
123: }
124: NormalizedMessage nm = exchange.getMessage("in");
125:
126: Conduit conduit = conduitInit.getConduit(ei);
127: CxfBcProviderMessageObserver obs = new CxfBcProviderMessageObserver(
128: exchange, this );
129: conduit.setMessageObserver(obs);
130: Message message = ep.getBinding().createMessage();
131: message.put(MessageExchange.class, exchange);
132: Exchange cxfExchange = new ExchangeImpl();
133: message.setExchange(cxfExchange);
134: cxfExchange.setOutMessage(message);
135:
136: QName opeName = exchange.getOperation();
137: BindingOperationInfo boi = null;
138: if (opeName == null) {
139: // if interface only have one operation, may not specify the opeName in MessageExchange
140: boi = ei.getBinding().getOperations().iterator().next();
141: } else {
142: boi = ei.getBinding().getOperation(exchange.getOperation());
143: }
144:
145: cxfExchange.put(BindingOperationInfo.class, boi);
146: cxfExchange.put(Endpoint.class, ep);
147: cxfExchange.put(Service.class, cxfService);
148: PhaseChainCache outboundChainCache = new PhaseChainCache();
149: PhaseManager pm = getBus().getExtension(PhaseManager.class);
150: List<Interceptor> outList = new ArrayList<Interceptor>();
151: if (isMtomEnabled()) {
152: outList.add(new JbiOutInterceptor());
153: outList.add(new MtomCheckInterceptor(true));
154: outList.add(new AttachmentOutInterceptor());
155:
156: }
157:
158: outList.add(new JbiOutWsdl1Interceptor(isUseJBIWrapper()));
159: outList.add(new SoapPreProtocolOutInterceptor());
160: outList.add(new SoapOutInterceptor(getBus()));
161:
162: PhaseInterceptorChain outChain = outboundChainCache.get(pm
163: .getOutPhases(), outList);
164: outChain.add(getOutInterceptors());
165: outChain.add(getOutFaultInterceptors());
166: message.setInterceptorChain(outChain);
167: InputStream is = JBIMessageHelper
168: .convertMessageToInputStream(nm.getContent());
169:
170: StreamSource source = new StreamSource(is);
171: message.setContent(Source.class, source);
172:
173: message.setContent(InputStream.class, is);
174:
175: conduit.prepare(message);
176: OutputStream os = message.getContent(OutputStream.class);
177: XMLStreamWriter writer = message
178: .getContent(XMLStreamWriter.class);
179:
180: String encoding = getEncoding(message);
181:
182: try {
183: writer = StaxOutInterceptor.getXMLOutputFactory(message)
184: .createXMLStreamWriter(os, encoding);
185: } catch (XMLStreamException e) {
186: //
187: }
188: message.setContent(XMLStreamWriter.class, writer);
189: message
190: .put(org.apache.cxf.message.Message.REQUESTOR_ROLE,
191: true);
192: outChain.doIntercept(message);
193: XMLStreamWriter xtw = message.getContent(XMLStreamWriter.class);
194: if (xtw != null) {
195: xtw.writeEndDocument();
196: xtw.close();
197: }
198:
199: os.flush();
200: is.close();
201: os.close();
202:
203: }
204:
205: public List<Interceptor> getOutFaultInterceptors() {
206: return outFault;
207: }
208:
209: public List<Interceptor> getInFaultInterceptors() {
210: return inFault;
211: }
212:
213: public List<Interceptor> getInInterceptors() {
214: return in;
215: }
216:
217: public List<Interceptor> getOutInterceptors() {
218: return out;
219: }
220:
221: public void setInInterceptors(List<Interceptor> interceptors) {
222: in = interceptors;
223: }
224:
225: public void setInFaultInterceptors(List<Interceptor> interceptors) {
226: inFault = interceptors;
227: }
228:
229: public void setOutInterceptors(List<Interceptor> interceptors) {
230: out = interceptors;
231: }
232:
233: public void setOutFaultInterceptors(List<Interceptor> interceptors) {
234: outFault = interceptors;
235: }
236:
237: public void setWsdl(Resource wsdl) {
238: this .wsdl = wsdl;
239: }
240:
241: public Resource getWsdl() {
242: return wsdl;
243: }
244:
245: @Override
246: public void validate() throws DeploymentException {
247: try {
248: if (definition == null) {
249: if (wsdl == null) {
250: throw new DeploymentException(
251: "wsdl property must be set");
252: }
253: description = DomUtil.parse(wsdl.getInputStream());
254: WSDLFactory wsdlFactory = WSDLFactory.newInstance();
255: WSDLReader reader = wsdlFactory.newWSDLReader();
256: reader.setFeature(Constants.FEATURE_VERBOSE, false);
257: definition = reader.readWSDL(wsdl.getURL().toString(),
258: description);
259: WSDLServiceFactory factory = new WSDLServiceFactory(
260: getBus(), definition, service);
261: cxfService = factory.create();
262: ei = cxfService.getServiceInfos().iterator().next()
263: .getEndpoints().iterator().next();
264: for (ServiceInfo serviceInfo : cxfService
265: .getServiceInfos()) {
266: if (serviceInfo.getName().equals(service)
267: && getEndpoint() != null
268: && serviceInfo.getEndpoint(new QName(
269: serviceInfo.getName()
270: .getNamespaceURI(),
271: getEndpoint())) != null) {
272: ei = serviceInfo
273: .getEndpoint(new QName(serviceInfo
274: .getName().getNamespaceURI(),
275: getEndpoint()));
276:
277: }
278: }
279:
280: if (endpoint == null) {
281: endpoint = ei.getName().getLocalPart();
282: }
283: ei.getBinding().setProperty(
284: AbstractBindingFactory.DATABINDING_DISABLED,
285: Boolean.TRUE);
286:
287: if (locationURI == null) {
288: // if not specify target address, get it from the wsdl
289: locationURI = new URI(ei.getAddress());
290: LOG.fine("address is " + locationURI.toString());
291: }
292: ep = new EndpointImpl(getBus(), cxfService, ei);
293:
294: //init transport
295: ei.setAddress(locationURI.toString());
296:
297: ConduitInitiatorManager conduitMgr = getBus()
298: .getExtension(ConduitInitiatorManager.class);
299: conduitInit = conduitMgr
300: .getConduitInitiator("http://schemas.xmlsoap.org/soap/http");
301: super .validate();
302: }
303: } catch (DeploymentException e) {
304: throw e;
305: } catch (Exception e) {
306: throw new DeploymentException(e);
307: }
308: }
309:
310: @Override
311: public void start() throws Exception {
312: super .start();
313:
314: }
315:
316: protected Bus getBus() {
317: if (getBusCfg() != null) {
318: if (bus == null) {
319: SpringBusFactory bf = new SpringBusFactory();
320: bus = bf.createBus(getBusCfg());
321: }
322: return bus;
323: } else {
324: return ((CxfBcComponent) getServiceUnit().getComponent())
325: .getBus();
326: }
327: }
328:
329: public void setBusCfg(String busCfg) {
330: this .busCfg = busCfg;
331: }
332:
333: public String getBusCfg() {
334: return busCfg;
335: }
336:
337: public void setLocationURI(URI locationURI) {
338: this .locationURI = locationURI;
339: }
340:
341: public URI getLocationURI() {
342: return locationURI;
343: }
344:
345: private String getEncoding(Message message) {
346: Exchange ex = message.getExchange();
347: String encoding = (String) message.get(Message.ENCODING);
348: if (encoding == null && ex.getInMessage() != null) {
349: encoding = (String) ex.getInMessage().get(Message.ENCODING);
350: message.put(Message.ENCODING, encoding);
351: }
352:
353: if (encoding == null) {
354: encoding = "UTF-8";
355: message.put(Message.ENCODING, encoding);
356: }
357: return encoding;
358: }
359:
360: Endpoint getCxfEndpoint() {
361: return this .ep;
362: }
363:
364: EndpointInfo getEndpointInfo() {
365: return this .ei;
366: }
367:
368: public void setMtomEnabled(boolean mtomEnabled) {
369: this .mtomEnabled = mtomEnabled;
370: }
371:
372: public boolean isMtomEnabled() {
373: return mtomEnabled;
374: }
375:
376: public void setUseJBIWrapper(boolean useJBIWrapper) {
377: this .useJBIWrapper = useJBIWrapper;
378: }
379:
380: public boolean isUseJBIWrapper() {
381: return useJBIWrapper;
382: }
383:
384: }
|