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