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.IOException;
020    import java.io.InputStream;
021    import java.io.OutputStream;
022    import java.net.URI;
023    import java.util.ArrayList;
024    import java.util.HashMap;
025    import java.util.List;
026    import java.util.Map;
027    import java.util.concurrent.CopyOnWriteArrayList;
028    
029    import javax.jbi.management.DeploymentException;
030    import javax.jbi.messaging.ExchangeStatus;
031    import javax.jbi.messaging.MessageExchange;
032    import javax.jbi.messaging.MessagingException;
033    import javax.jbi.messaging.NormalizedMessage;
034    import javax.wsdl.WSDLException;
035    import javax.wsdl.factory.WSDLFactory;
036    import javax.wsdl.xml.WSDLReader;
037    import javax.xml.namespace.QName;
038    import javax.xml.parsers.ParserConfigurationException;
039    import javax.xml.transform.Source;
040    import javax.xml.transform.TransformerException;
041    import javax.xml.transform.dom.DOMSource;
042    import javax.xml.transform.stream.StreamSource;
043    
044    import org.w3c.dom.Document;
045    import org.w3c.dom.Element;
046    import org.w3c.dom.Node;
047    import org.xml.sax.SAXException;
048    
049    import com.ibm.wsdl.Constants;
050    
051    import org.apache.cxf.Bus;
052    import org.apache.cxf.binding.AbstractBindingFactory;
053    
054    import org.apache.cxf.binding.jbi.JBIConstants;
055    import org.apache.cxf.binding.jbi.JBIFault;
056    
057    import org.apache.cxf.binding.soap.SoapMessage;
058    import org.apache.cxf.binding.soap.SoapVersion;
059    import org.apache.cxf.binding.soap.interceptor.ReadHeadersInterceptor;
060    import org.apache.cxf.binding.soap.interceptor.SoapActionOutInterceptor;
061    import org.apache.cxf.binding.soap.interceptor.SoapOutInterceptor;
062    import org.apache.cxf.binding.soap.interceptor.SoapPreProtocolOutInterceptor;
063    import org.apache.cxf.binding.soap.model.SoapBindingInfo;
064    import org.apache.cxf.binding.soap.model.SoapBodyInfo;
065    import org.apache.cxf.bus.spring.SpringBusFactory;
066    import org.apache.cxf.catalog.OASISCatalogManager;
067    import org.apache.cxf.endpoint.Client;
068    import org.apache.cxf.endpoint.ClientImpl;
069    import org.apache.cxf.endpoint.Endpoint;
070    import org.apache.cxf.endpoint.EndpointImpl;
071    import org.apache.cxf.feature.AbstractFeature;
072    import org.apache.cxf.interceptor.AttachmentOutInterceptor;
073    import org.apache.cxf.interceptor.Fault;
074    import org.apache.cxf.interceptor.Interceptor;
075    import org.apache.cxf.interceptor.StaxInInterceptor;
076    import org.apache.cxf.interceptor.StaxOutInterceptor;
077    
078    import org.apache.cxf.message.Exchange;
079    import org.apache.cxf.message.ExchangeImpl;
080    import org.apache.cxf.message.Message;
081    import org.apache.cxf.phase.PhaseChainCache;
082    import org.apache.cxf.phase.PhaseInterceptorChain;
083    import org.apache.cxf.phase.PhaseManager;
084    import org.apache.cxf.service.Service;
085    import org.apache.cxf.service.model.BindingMessageInfo;
086    import org.apache.cxf.service.model.BindingOperationInfo;
087    import org.apache.cxf.service.model.EndpointInfo;
088    import org.apache.cxf.service.model.OperationInfo;
089    import org.apache.cxf.service.model.SchemaInfo;
090    import org.apache.cxf.service.model.ServiceInfo;
091    import org.apache.cxf.transport.Conduit;
092    import org.apache.cxf.transport.ConduitInitiator;
093    import org.apache.cxf.transport.ConduitInitiatorManager;
094    import org.apache.cxf.transport.jbi.JBIMessageHelper;
095    import org.apache.cxf.wsdl.WSDLManager;
096    import org.apache.cxf.wsdl11.SchemaUtil;
097    import org.apache.cxf.wsdl11.ServiceWSDLBuilder;
098    import org.apache.cxf.wsdl11.WSDLServiceBuilder;
099    import org.apache.cxf.wsdl11.WSDLServiceFactory;
100    import org.apache.servicemix.JbiConstants;
101    import org.apache.servicemix.common.endpoints.ProviderEndpoint;
102    import org.apache.servicemix.cxfbc.interceptors.JbiOutInterceptor;
103    import org.apache.servicemix.cxfbc.interceptors.JbiOutWsdl1Interceptor;
104    import org.apache.servicemix.cxfbc.interceptors.MtomCheckInterceptor;
105    import org.apache.servicemix.jbi.jaxp.SourceTransformer;
106    import org.apache.servicemix.soap.util.DomUtil;
107    import org.springframework.core.io.Resource;
108    
109    /**
110     * 
111     * @author gnodet
112     * @org.apache.xbean.XBean element="provider" description="a provider endpoint
113     *                         that is capable of exposing SOAP/HTTP or SOAP/JMS
114     *                         services"
115     */
116    public class CxfBcProvider extends ProviderEndpoint implements
117            CxfBcEndpointWithInterceptor {
118    
119        List<Interceptor> in = new CopyOnWriteArrayList<Interceptor>();
120    
121        List<Interceptor> out = new CopyOnWriteArrayList<Interceptor>();
122    
123        List<Interceptor> outFault = new CopyOnWriteArrayList<Interceptor>();
124    
125        List<Interceptor> inFault = new CopyOnWriteArrayList<Interceptor>();
126    
127        private Resource wsdl;
128    
129        private String busCfg;
130    
131        private Bus bus;
132    
133        private ConduitInitiator conduitInit;
134    
135        private Conduit conduit;
136    
137        private URI locationURI;
138    
139        private EndpointInfo ei;
140    
141        private Endpoint ep;
142    
143        private Service cxfService;
144    
145        private boolean mtomEnabled;
146    
147        private boolean useJBIWrapper = true;
148    
149        private boolean useSOAPEnvelope = true;
150    
151        private boolean synchronous = true;
152        
153        private List<AbstractFeature> features = new CopyOnWriteArrayList<AbstractFeature>();
154    
155        public void processExchange(MessageExchange exchange) {
156    
157        }
158    
159        public void process(MessageExchange exchange) throws Exception {
160    
161            if (exchange.getStatus() != ExchangeStatus.ACTIVE) {
162                return;
163            }
164            NormalizedMessage nm = exchange.getMessage("in");
165    
166            Object newDestinationURI = nm
167                    .getProperty(JbiConstants.HTTP_DESTINATION_URI);
168            if (newDestinationURI != null) {
169                ei.setAddress((String) newDestinationURI);
170            }
171    
172            Message message = ep.getBinding().createMessage();
173            message.put(MessageExchange.class, exchange);
174            Exchange cxfExchange = new ExchangeImpl();
175            cxfExchange.setConduit(conduit);
176            cxfExchange.setSynchronous(isSynchronous());
177            cxfExchange.put(MessageExchange.class, exchange);
178            message.setExchange(cxfExchange);
179            cxfExchange.setOutMessage(message);
180    
181            QName opeName = exchange.getOperation();
182            BindingOperationInfo boi = null;
183            
184            if (opeName == null) {
185                // if interface only have one operation, may not specify the opeName
186                // in MessageExchange
187                if (ei.getBinding().getOperations().size() == 1) {
188                    boi = ei.getBinding().getOperations().iterator().next();
189                } else {
190                    boi = findOperation(nm, message, boi, exchange);
191                    cxfExchange.put(MessageExchange.class, exchange);
192                    
193                }
194            } else {
195                boi = ei.getBinding().getOperation(exchange.getOperation());
196            }
197            InputStream is = JBIMessageHelper.convertMessageToInputStream(nm
198                    .getContent());
199    
200            StreamSource source = new StreamSource(is);
201            message.setContent(Source.class, source);
202    
203            message.setContent(InputStream.class, is);
204            cxfExchange.setOneWay(boi.getOperationInfo().isOneWay());
205            cxfExchange.put(BindingOperationInfo.class, boi);
206            cxfExchange.put(Endpoint.class, ep);
207            cxfExchange.put(Service.class, cxfService);
208            cxfExchange.put(Bus.class, getBus());
209            PhaseInterceptorChain outChain = createInterceptorChain(message);
210            
211    
212            conduit.prepare(message);
213            OutputStream os = message.getContent(OutputStream.class);
214            message.put(org.apache.cxf.message.Message.REQUESTOR_ROLE, true);
215            try {
216                outChain.doIntercept(message);
217                // Check to see if there is a Fault from the outgoing chain
218                Exception ex = message.getContent(Exception.class);
219                if (ex != null) {
220                    throw ex;
221                }
222                ex = message.getExchange().get(Exception.class);
223                if (ex != null) {
224                    throw ex;
225                }
226                os = message.getContent(OutputStream.class);
227                os.flush();
228                is.close();
229                os.close();
230            } catch (Exception e) {
231                faultProcess(exchange, message, e);
232            }
233            if (boi.getOperationInfo().isOneWay()) {
234                exchange.setStatus(ExchangeStatus.DONE);
235                this.getChannel().send(exchange);
236            }
237    
238        }
239    
240        private BindingOperationInfo findOperation(NormalizedMessage nm, 
241                                                   Message message, 
242                                                   BindingOperationInfo boi, 
243                                                   MessageExchange exchange) 
244            throws TransformerException, ParserConfigurationException, IOException, SAXException {
245            //try to figure out the operationName based on the incoming message
246            //payload and wsdl if use doc/literal/wrapped
247            Element element = new SourceTransformer().toDOMElement(nm.getContent());
248            
249            if (!useJBIWrapper) {
250                SoapVersion soapVersion = ((SoapMessage)message).getVersion();                
251                if (element != null) {                                                      
252                    Element bodyElement = (Element) element.getElementsByTagNameNS(
253                            element.getNamespaceURI(),
254                            soapVersion.getBody().getLocalPart()).item(0);
255                    if (bodyElement != null) {
256                        element = (Element) bodyElement.getFirstChild();                           
257                    } 
258                }
259            } else {
260                element = DomUtil.getFirstChildElement(DomUtil.getFirstChildElement(element));
261            }
262            
263            QName opeName = new QName(element.getNamespaceURI(), element.getLocalName());
264            SoapBindingInfo binding = (SoapBindingInfo) ei.getBinding();
265            for (BindingOperationInfo op : binding.getOperations()) {
266                String style = binding.getStyle(op.getOperationInfo());
267                if (style == null) {
268                    style = binding.getStyle();
269                }
270                if ("document".equals(style)) {
271                    BindingMessageInfo msg = op.getInput();
272                    if (msg.getExtensor(SoapBodyInfo.class)
273                                .getParts().get(0).getElementQName().equals(opeName)) {
274                        boi = op;
275                        exchange.setOperation(new QName(boi.getName().getNamespaceURI(), opeName.getLocalPart()));
276                        break;
277                    }
278                } else {
279                    throw new Fault(new Exception(
280                        "Operation must bound on this MessageExchange if use rpc mode"));
281                }
282            }
283            if (boi == null) {
284                throw new Fault(new Exception(
285                    "Operation not bound on this MessageExchange"));
286            }
287            return boi;
288        }
289    
290        private PhaseInterceptorChain createInterceptorChain(Message message) {
291            PhaseChainCache outboundChainCache = new PhaseChainCache();
292            PhaseManager pm = getBus().getExtension(PhaseManager.class);
293            List<Interceptor> outList = new ArrayList<Interceptor>();
294            if (isMtomEnabled()) {
295                outList.add(new JbiOutInterceptor());
296                outList.add(new MtomCheckInterceptor(true));
297                outList.add(new AttachmentOutInterceptor());
298    
299            }
300    
301            outList.add(new JbiOutInterceptor());
302            outList.add(new JbiOutWsdl1Interceptor(isUseJBIWrapper()));
303            outList.add(new SoapPreProtocolOutInterceptor());
304            outList.add(new SoapOutInterceptor(getBus()));
305            outList.add(new SoapActionOutInterceptor());
306            outList.add(new StaxOutInterceptor());
307    
308            getInInterceptors().addAll(getBus().getInInterceptors());
309            getInFaultInterceptors().addAll(getBus().getInFaultInterceptors());
310            getOutInterceptors().addAll(getBus().getOutInterceptors());
311            getOutFaultInterceptors().addAll(getBus().getOutFaultInterceptors());
312            PhaseInterceptorChain outChain = outboundChainCache.get(pm
313                    .getOutPhases(), outList);
314            outChain.add(getOutInterceptors());
315            outChain.add(getOutFaultInterceptors());
316            message.setInterceptorChain(outChain);
317            return outChain;
318        }
319    
320    
321        private void faultProcess(MessageExchange exchange, Message message,
322                Exception e) throws MessagingException {
323            javax.jbi.messaging.Fault fault = exchange.createFault();
324            if (e.getCause() != null) {
325                handleJBIFault(message, e.getCause().getMessage());
326            } else {
327                handleJBIFault(message, e.getMessage());
328            }
329            fault.setContent(message.getContent(Source.class));
330            exchange.setFault(fault);
331            boolean txSync = exchange.getStatus() == ExchangeStatus.ACTIVE
332                    && exchange.isTransacted()
333                    && Boolean.TRUE.equals(exchange
334                            .getProperty(JbiConstants.SEND_SYNC));
335            if (txSync) {
336                getContext().getDeliveryChannel().sendSync(exchange);
337            } else {
338                getContext().getDeliveryChannel().send(exchange);
339            }
340        }
341    
342        private void handleJBIFault(Message message, String detail) {
343            Document doc = DomUtil.createDocument();
344            Element jbiFault = DomUtil.createElement(doc, new QName(
345                    JBIConstants.NS_JBI_BINDING, JBIFault.JBI_FAULT_ROOT));
346            Node jbiFaultDetail = DomUtil.createElement(jbiFault, new QName("",
347                    JBIFault.JBI_FAULT_DETAIL));
348            jbiFaultDetail.setTextContent(detail);
349            jbiFault.appendChild(jbiFaultDetail);
350            message.setContent(Source.class, new DOMSource(doc));
351            message.put("jbiFault", true);
352        }
353    
354        /**
355         * Returns the list of interceptors used to process fault messages being
356         * sent back to the consumer.
357         * 
358         * @return a list of <code>Interceptor</code> objects
359         */
360        public List<Interceptor> getOutFaultInterceptors() {
361            return outFault;
362        }
363    
364        /**
365         * Returns the list of interceptors used to process fault messages being
366         * recieved by the endpoint.
367         * 
368         * @return a list of <code>Interceptor</code> objects
369         */
370        public List<Interceptor> getInFaultInterceptors() {
371            return inFault;
372        }
373    
374        /**
375         * Returns the list of interceptors used to process requests being recieved
376         * by the endpoint.
377         * 
378         * @return a list of <code>Interceptor</code> objects
379         */
380        public List<Interceptor> getInInterceptors() {
381            return in;
382        }
383    
384        /**
385         * Returns the list of interceptors used to process responses being sent
386         * back to the consumer.
387         * 
388         * @return a list of <code>Interceptor</code> objects
389         */
390        public List<Interceptor> getOutInterceptors() {
391            return out;
392        }
393    
394        /**
395         * Specifies a list of interceptors used to process requests recieved by the
396         * endpoint.
397         * 
398         * @param interceptors
399         *            a list of <code>Interceptor</code> objects
400         * @org.apache.xbean.Property description="a list of beans configuring
401         *                            interceptors that process incoming requests"
402         */
403        public void setInInterceptors(List<Interceptor> interceptors) {
404            in.addAll(interceptors);
405        }
406    
407        /**
408         * Specifies a list of interceptors used to process faults recieved by the
409         * endpoint.
410         * 
411         * @param interceptors
412         *            a list of <code>Interceptor</code> objects
413         * @org.apache.xbean.Property description="a list of beans configuring
414         *                            interceptors that process incoming faults"
415         */
416        public void setInFaultInterceptors(List<Interceptor> interceptors) {
417            inFault.addAll(interceptors);
418        }
419    
420        /**
421         * Specifies a list of interceptors used to process responses sent by the
422         * endpoint.
423         * 
424         * @param interceptors
425         *            a list of <code>Interceptor</code> objects
426         * @org.apache.xbean.Property description="a list of beans configuring
427         *                            interceptors that process responses"
428         */
429        public void setOutInterceptors(List<Interceptor> interceptors) {
430            out.addAll(interceptors);
431        }
432    
433        /**
434         * Specifies a list of interceptors used to process faults sent by the
435         * endpoint.
436         * 
437         * @param interceptors
438         *            a list of <code>Interceptor</code> objects
439         * @org.apache.xbean.Property description="a list of beans configuring
440         *                            interceptors that process fault messages being
441         *                            returned to the consumer"
442         */
443        public void setOutFaultInterceptors(List<Interceptor> interceptors) {
444            outFault.addAll(interceptors);
445        }
446    
447        /**
448         * Specifies the location of the WSDL defining the endpoint's interface.
449         * 
450         * @param wsdl
451         *            the location of the WSDL contract as a <code>Resource</code>
452         *            object
453         * @org.apache.xbean.Property description="the location of the WSDL document
454         *                            defining the endpoint's interface"
455         */
456        public void setWsdl(Resource wsdl) {
457            this.wsdl = wsdl;
458        }
459    
460        public Resource getWsdl() {
461            return wsdl;
462        }
463    
464        @Override
465        public void validate() throws DeploymentException {
466            try {
467                if (definition == null) {
468                    if (wsdl == null) {
469                        throw new DeploymentException("wsdl property must be set");
470                    }
471                    description = DomUtil.parse(wsdl.getInputStream());
472                    WSDLFactory wsdlFactory = WSDLFactory.newInstance();
473                    WSDLReader reader = wsdlFactory.newWSDLReader();
474                    reader.setFeature(Constants.FEATURE_VERBOSE, false);
475                    try {
476                        //ensure the jax-ws-catalog is loaded
477                        OASISCatalogManager.getCatalogManager(getBus()).loadContextCatalogs();
478                        // use wsdl manager to parse wsdl or get cached definition
479                        definition = getBus().getExtension(WSDLManager.class)
480                                .getDefinition(wsdl.getURL());
481    
482                    } catch (WSDLException ex) {
483                        // 
484                    }
485                    WSDLServiceFactory factory = new WSDLServiceFactory(getBus(),
486                            definition, service);
487                    cxfService = factory.create();
488                    ei = cxfService.getServiceInfos().iterator().next()
489                            .getEndpoints().iterator().next();
490    
491                    for (ServiceInfo serviceInfo : cxfService.getServiceInfos()) {
492                        if (serviceInfo.getName().equals(service)
493                                && getEndpoint() != null
494                                && serviceInfo
495                                        .getEndpoint(new QName(serviceInfo
496                                                .getName().getNamespaceURI(),
497                                                getEndpoint())) != null) {
498                            ei = serviceInfo.getEndpoint(new QName(serviceInfo
499                                    .getName().getNamespaceURI(), getEndpoint()));
500    
501                        }
502                    }
503    
504                    ServiceInfo serInfo = new ServiceInfo();
505    
506                    Map<String, Element> schemaList = new HashMap<String, Element>();
507                    SchemaUtil schemaUtil = new SchemaUtil(bus, schemaList);
508                    schemaUtil.getSchemas(definition, serInfo);
509    
510                    serInfo = ei.getService();
511                    List<ServiceInfo> serviceInfos = new ArrayList<ServiceInfo>();
512                    serviceInfos.add(serInfo);
513                    // transform import xsd to inline xsd
514                    ServiceWSDLBuilder swBuilder = new ServiceWSDLBuilder(getBus(),
515                            serviceInfos);
516                    for (String key : schemaList.keySet()) {
517                        Element ele = schemaList.get(key);
518                        for (SchemaInfo sInfo : serInfo.getSchemas()) {
519                            Node nl = sInfo.getElement().getElementsByTagNameNS(
520                                    "http://www.w3.org/2001/XMLSchema", "import")
521                                    .item(0);
522                            if (sInfo.getNamespaceURI() == null // it's import
523                                    // schema
524                                    && nl != null
525                                    && ((Element) nl)
526                                            .getAttribute("namespace")
527                                            .equals(
528                                                    ele
529                                                            .getAttribute("targetNamespace"))) {
530    
531                                sInfo.setElement(ele);
532                            }
533                        }
534                    }
535    
536                    serInfo.setProperty(WSDLServiceBuilder.WSDL_DEFINITION, null);
537                    serInfo.getInterface().setProperty(WSDLServiceBuilder.WSDL_PORTTYPE, null);
538                    for (OperationInfo opInfo : serInfo.getInterface().getOperations()) {
539                        opInfo.setProperty(WSDLServiceBuilder.WSDL_OPERATION, null);
540                    }
541                    description = WSDLFactory.newInstance().newWSDLWriter()
542                            .getDocument(swBuilder.build());
543    
544                    if (endpoint == null) {
545                        endpoint = ei.getName().getLocalPart();
546                    }
547                    ei.getBinding().setProperty(
548                            AbstractBindingFactory.DATABINDING_DISABLED,
549                            Boolean.TRUE);
550    
551                    ep = new EndpointImpl(getBus(), cxfService, ei);
552    
553                    // init transport
554                    if (locationURI != null) {
555                        ei.setAddress(locationURI.toString());
556                    }
557    
558                    ConduitInitiatorManager conduitMgr = getBus().getExtension(
559                            ConduitInitiatorManager.class);
560                    conduitInit = conduitMgr.getConduitInitiator(ei
561                            .getTransportId());
562                    conduit = conduitInit.getConduit(ei);
563                    CxfBcProviderMessageObserver obs = new CxfBcProviderMessageObserver(
564                            this);
565                    conduit.setMessageObserver(obs);
566    
567                    checkWSRMInterceptors();
568                              
569    
570                    super.validate();
571                }
572            } catch (DeploymentException e) {
573                throw e;
574            } catch (Exception e) {
575                throw new DeploymentException(e);
576            }
577        }
578    
579        private void checkWSRMInterceptors() {
580            //to handle WS-RM requests and responses
581            for (Interceptor interceptor : getBus().getOutInterceptors()) {
582                if (interceptor.getClass().getName().equals("org.apache.cxf.ws.rm.RMOutInterceptor")) {
583                    ep.getOutInterceptors().add(new SoapOutInterceptor(getBus()));
584                    ep.getOutInterceptors().add(new StaxOutInterceptor());
585                    ep.getInInterceptors().add(new StaxInInterceptor());
586                    ep.getInInterceptors().add(new ReadHeadersInterceptor(getBus()));
587                    break;
588                }
589            }
590    
591        }
592    
593        @Override
594        public void start() throws Exception {
595            applyFeatures();
596            super.start();
597    
598        }
599    
600        private void applyFeatures() {
601            Client client = new ClientImpl(getBus(), ep, conduit);
602            if (getFeatures() != null) {
603                for (AbstractFeature feature : getFeatures()) {
604                    feature.initialize(client, getBus());
605                }
606            }
607        }
608        
609        protected Bus getBus() {
610            if (getBusCfg() != null) {
611                if (bus == null) {
612                    SpringBusFactory bf = new SpringBusFactory();
613                    bus = bf.createBus(getBusCfg());
614                }
615                return bus;
616            } else {
617                return ((CxfBcComponent) getServiceUnit().getComponent()).getBus();
618            }
619        }
620    
621        /**
622         * Specifies the location of the CXF configuraiton file used to configure
623         * the CXF bus. This allows you to access features like JMS runtime behavior
624         * and WS-RM.
625         * 
626         * @param busCfg
627         *            a string containing the relative path to the configuration
628         *            file
629         * @org.apache.xbean.Property description="the location of the CXF
630         *                            configuration file used to configure the CXF
631         *                            bus. This allows you to configure features
632         *                            like WS-RM and JMS runtime behavior."
633         */
634        public void setBusCfg(String busCfg) {
635            this.busCfg = busCfg;
636        }
637    
638        public String getBusCfg() {
639            return busCfg;
640        }
641    
642        /**
643         * Specifies the HTTP address of the exposed service. This value will
644         * overide any value specified in the WSDL.
645         * 
646         * @param locationURI
647         *            a <code>URI</code> object
648         * @org.apache.xbean.Property description="the HTTP address of the exposed
649         *                            service. This value will overide any value
650         *                            specified in the WSDL."
651         */
652        public void setLocationURI(URI locationURI) {
653            this.locationURI = locationURI;
654        }
655    
656        public URI getLocationURI() {
657            return locationURI;
658        }
659    
660        Endpoint getCxfEndpoint() {
661            return this.ep;
662        }
663    
664        EndpointInfo getEndpointInfo() {
665            return this.ei;
666        }
667    
668        /**
669         * Specifies if the endpoint can support binnary attachments.
670         * 
671         * @param mtomEnabled
672         *            a boolean
673         * @org.apache.xbean.Property description="Specifies if MTOM / attachment
674         *                            support is enabled. Default is
675         *                            <code>false</code>."
676         */
677        public void setMtomEnabled(boolean mtomEnabled) {
678            this.mtomEnabled = mtomEnabled;
679        }
680    
681        public boolean isMtomEnabled() {
682            return mtomEnabled;
683        }
684    
685        /**
686         * Specifies if the endpoint expects messages to use the JBI wrapper for
687         * SOAP messages.
688         * 
689         * @param useJBIWrapper
690         *            a boolean
691         * @org.apache.xbean.Property description="Specifies if the JBI wrapper is
692         *                            sent in the body of the message. Default is
693         *                            <code>true</code>. Ignore the value of
694         *                            useSOAPEnvelope if useJBIWrapper is true"
695         */
696        public void setUseJBIWrapper(boolean useJBIWrapper) {
697            this.useJBIWrapper = useJBIWrapper;
698        }
699    
700        public boolean isUseJBIWrapper() {
701            return useJBIWrapper;
702        }
703    
704        /**
705         * Specifies if the endpoint expects soap messages when useJBIWrapper is
706         * false, if useJBIWrapper is true then ignore useSOAPEnvelope
707         * 
708         * @org.apache.xbean.Property description="Specifies if the endpoint expects
709         *                            soap messages when useJBIWrapper is false, if
710         *                            useJBIWrapper is true then ignore
711         *                            useSOAPEnvelope. The default is
712         *                            <code>true</code>.
713         */
714        public void setUseSOAPEnvelope(boolean useSOAPEnvelope) {
715            this.useSOAPEnvelope = useSOAPEnvelope;
716        }
717    
718        public boolean isUseSOAPEnvelope() {
719            return useSOAPEnvelope;
720        }
721    
722        /**
723         * Specifies if the endpoints send message synchronously to external server
724         * using underlying jms/http transport *
725         * 
726         * @param synchronous
727         *            a boolean
728         * @org.apache.xbean.Property description="Specifies if the endpoints send
729         *                            message synchronously to external server using
730         *                            underlying jms/http transport. Default is
731         *                            <code>true</code>."
732         */
733        public void setSynchronous(boolean synchronous) {
734            this.synchronous = synchronous;
735        }
736    
737        public boolean isSynchronous() {
738            return synchronous;
739        }
740    
741        public void setFeatures(List<AbstractFeature> features) {
742            this.features = features;
743        }
744    
745        public List<AbstractFeature> getFeatures() {
746            return features;
747        }
748    
749    }