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