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.cxfse;
018
019 import java.io.IOException;
020 import java.lang.reflect.Field;
021 import java.lang.reflect.Method;
022 import java.util.List;
023 import java.util.Map;
024 import java.util.concurrent.CopyOnWriteArrayList;
025
026 import javax.annotation.PostConstruct;
027 import javax.annotation.PreDestroy;
028 import javax.jbi.component.ComponentContext;
029 import javax.jbi.management.DeploymentException;
030 import javax.jbi.messaging.DeliveryChannel;
031 import javax.jbi.messaging.ExchangeStatus;
032 import javax.jbi.messaging.InOnly;
033 import javax.jbi.messaging.MessageExchange;
034 import javax.jbi.messaging.NormalizedMessage;
035 import javax.jbi.messaging.RobustInOnly;
036 import javax.wsdl.WSDLException;
037 import javax.wsdl.factory.WSDLFactory;
038 import javax.xml.namespace.QName;
039 import javax.xml.parsers.ParserConfigurationException;
040 import javax.xml.transform.TransformerException;
041 import javax.xml.ws.WebServiceRef;
042
043 import org.w3c.dom.Element;
044
045 import org.xml.sax.SAXException;
046
047 import org.apache.cxf.Bus;
048 import org.apache.cxf.aegis.databinding.AegisDatabinding;
049 import org.apache.cxf.binding.soap.SoapMessage;
050 import org.apache.cxf.binding.soap.SoapVersion;
051 import org.apache.cxf.binding.soap.model.SoapBindingInfo;
052 import org.apache.cxf.endpoint.Server;
053 import org.apache.cxf.frontend.ServerFactoryBean;
054 import org.apache.cxf.interceptor.Fault;
055 import org.apache.cxf.interceptor.Interceptor;
056 import org.apache.cxf.interceptor.InterceptorProvider;
057 import org.apache.cxf.jaxws.EndpointImpl;
058 import org.apache.cxf.jaxws.JaxWsServerFactoryBean;
059 import org.apache.cxf.jaxws.ServiceImpl;
060 import org.apache.cxf.jaxws.support.JaxWsImplementorInfo;
061 import org.apache.cxf.jaxws.support.JaxWsServiceFactoryBean;
062 import org.apache.cxf.message.Message;
063 import org.apache.cxf.service.model.BindingOperationInfo;
064 import org.apache.cxf.service.model.EndpointInfo;
065 import org.apache.cxf.transport.ConduitInitiatorManager;
066 import org.apache.cxf.transport.jbi.JBIDestination;
067 import org.apache.cxf.transport.jbi.JBIDispatcherUtil;
068 import org.apache.cxf.transport.jbi.JBITransportFactory;
069 import org.apache.cxf.wsdl11.ServiceWSDLBuilder;
070 import org.apache.cxf.xmlbeans.XmlBeansDataBinding;
071 import org.apache.servicemix.common.endpoints.ProviderEndpoint;
072 import org.apache.servicemix.cxfse.interceptors.AttachmentInInterceptor;
073 import org.apache.servicemix.cxfse.interceptors.AttachmentOutInterceptor;
074 import org.apache.servicemix.cxfse.support.ReflectionUtils;
075 import org.apache.servicemix.id.IdGenerator;
076 import org.apache.servicemix.jbi.jaxp.SourceTransformer;
077 import org.apache.servicemix.soap.util.DomUtil;
078 import org.springframework.util.ReflectionUtils.FieldCallback;
079
080 /**
081 * @author gnodet
082 * @org.apache.xbean.XBean element="endpoint" description="an endpoint using
083 * CXF's JAX-WS frontend"
084 */
085 public class CxfSeEndpoint extends ProviderEndpoint implements InterceptorProvider {
086
087 private static final IdGenerator ID_GENERATOR = new IdGenerator();
088
089 private Object pojo;
090
091 private EndpointImpl endpoint;
092
093 private String address;
094
095 private ServerFactoryBean sf;
096
097 private Server server;
098
099 private List<Interceptor> in = new CopyOnWriteArrayList<Interceptor>();
100
101 private List<Interceptor> out = new CopyOnWriteArrayList<Interceptor>();
102
103 private List<Interceptor> outFault = new CopyOnWriteArrayList<Interceptor>();
104
105 private List<Interceptor> inFault = new CopyOnWriteArrayList<Interceptor>();
106
107 private Map properties;
108
109 private boolean mtomEnabled;
110
111 private boolean useJBIWrapper = true;
112
113 private boolean useSOAPEnvelope = true;
114
115 private boolean useAegis;
116
117 private boolean useXmlBeans;
118
119 private QName pojoService;
120 private String pojoEndpoint;
121 private QName pojoInterfaceName;
122
123 private Server soapBindingServer;
124
125 /**
126 * Returns the object implementing the endpoint's functionality. It is
127 * returned as a generic Java <code>Object</code> that can be cast to the
128 * proper type.
129 *
130 * @return the pojo
131 */
132 public Object getPojo() {
133 return pojo;
134 }
135
136 /**
137 * Specifies the object implementing the endpoint's functionality. This
138 * object should use the JAX-WS annotations.
139 *
140 * @param pojo a JAX-WS annotated object
141 * @org.apache.xbean.Property description="a bean configuring the JAX-WS
142 * annotated implementation for the endpoint"
143 */
144 public void setPojo(Object pojo) {
145 this.pojo = pojo;
146 }
147
148 /**
149 * Returns the list of interceptors used to process fault messages being
150 * sent back to the consumer.
151 *
152 * @return a list of <code>Interceptor</code> objects
153 */
154 public List<Interceptor> getOutFaultInterceptors() {
155 return outFault;
156 }
157
158 /**
159 * Returns the list of interceptors used to process fault messages being
160 * recieved by the endpoint.
161 *
162 * @return a list of <code>Interceptor</code> objects
163 */
164 public List<Interceptor> getInFaultInterceptors() {
165 return inFault;
166 }
167
168 /**
169 * Returns the list of interceptors used to process messages being recieved
170 * by the endpoint.
171 *
172 * @return a list of <code>Interceptor</code> objects
173 */
174 public List<Interceptor> getInInterceptors() {
175 return in;
176 }
177
178 /**
179 * Returns the list of interceptors used to process responses being sent
180 * back to the consumer.
181 *
182 * @return a list of <code>Interceptor</code> objects
183 */
184 public List<Interceptor> getOutInterceptors() {
185 return out;
186 }
187
188 /**
189 * Specifies a list of interceptors used to process requests recieved by the
190 * endpoint.
191 *
192 * @param interceptors a list of <code>Interceptor</code> objects
193 * @org.apache.xbean.Property description="a list of beans configuring
194 * interceptors that process incoming requests"
195 */
196 public void setInInterceptors(List<Interceptor> interceptors) {
197 in.addAll(interceptors);
198 }
199
200 /**
201 * Specifies a list of interceptors used to process faults recieved by the
202 * endpoint.
203 *
204 * @param interceptors a list of <code>Interceptor</code> objects
205 * @org.apache.xbean.Property description="a list of beans configuring
206 * interceptors that process incoming faults"
207 */
208 public void setInFaultInterceptors(List<Interceptor> interceptors) {
209 inFault.addAll(interceptors);
210 }
211
212 /**
213 * Specifies a list of interceptors used to process responses sent by the
214 * endpoint.
215 *
216 * @param interceptors a list of <code>Interceptor</code> objects
217 * @org.apache.xbean.Property description="a list of beans configuring
218 * interceptors that process response messages"
219 */
220 public void setOutInterceptors(List<Interceptor> interceptors) {
221 out.addAll(interceptors);
222 }
223
224 /**
225 * Specifies a list of interceptors used to process faults sent by the
226 * endpoint.
227 *
228 * @param interceptors a list of <code>Interceptor</code> objects
229 * @org.apache.xbean.Property description="a list of beans configuring
230 * interceptors that process fault messages being
231 * returned to the consumer"
232 */
233 public void setOutFaultInterceptors(List<Interceptor> interceptors) {
234 outFault.addAll(interceptors);
235 }
236
237 public Map getProperties() {
238 return properties;
239 }
240
241 public void setProperties(Map properties) {
242 this.properties = properties;
243 }
244
245 /*
246 * (non-Javadoc)
247 *
248 * @see org.apache.servicemix.common.Endpoint#validate()
249 */
250 @Override
251 public void validate() throws DeploymentException {
252 if (getPojo() == null) {
253 throw new DeploymentException("pojo must be set");
254 }
255 if (isUseAegis()) {
256 sf = new ServerFactoryBean();
257 sf.setServiceBean(getPojo());
258 sf.setAddress("jbi://" + ID_GENERATOR.generateSanitizedId());
259 sf.getServiceFactory().setDataBinding(new AegisDatabinding());
260
261 sf.getServiceFactory().setPopulateFromClass(true);
262 sf.setStart(false);
263 if (isUseJBIWrapper()) {
264 sf.setBindingId(org.apache.cxf.binding.jbi.JBIConstants.NS_JBI_BINDING);
265 }
266 server = sf.create();
267 server.getEndpoint().getInInterceptors().addAll(getInInterceptors());
268 server.getEndpoint().getInFaultInterceptors().addAll(getInFaultInterceptors());
269 server.getEndpoint().getOutInterceptors().addAll(getOutInterceptors());
270 server.getEndpoint().getOutFaultInterceptors().addAll(getOutFaultInterceptors());
271 if (isMtomEnabled()) {
272 server.getEndpoint().getInInterceptors().add(new AttachmentInInterceptor());
273 server.getEndpoint().getOutInterceptors().add(new AttachmentOutInterceptor());
274 }
275 if (sf.getServiceFactory().getServiceQName() != null) {
276 setPojoService(sf.getServiceFactory().getServiceQName());
277 if (getService() == null) {
278 setService(sf.getServiceFactory().getServiceQName());
279 }
280 }
281 if (sf.getServiceFactory().getEndpointInfo().getName() != null) {
282 setPojoEndpoint(sf.getServiceFactory().getEndpointInfo().getName().getLocalPart());
283 if (getEndpoint() == null) {
284 setEndpoint(sf.getServiceFactory().getEndpointInfo().getName().getLocalPart());
285 }
286 }
287 if (sf.getServiceFactory().getInterfaceName() != null) {
288 setPojoInterfaceName(sf.getServiceFactory().getInterfaceName());
289 if (getInterfaceName() == null) {
290 setInterfaceName(sf.getServiceFactory().getInterfaceName());
291 }
292 }
293 } else {
294 JaxWsServiceFactoryBean serviceFactory = new JaxWsServiceFactoryBean();
295 serviceFactory.setPopulateFromClass(true);
296 endpoint = new EndpointImpl(getBus(), getPojo(), new JaxWsServerFactoryBean(serviceFactory));
297 if (isUseJBIWrapper()) {
298 endpoint.setBindingUri(org.apache.cxf.binding.jbi.JBIConstants.NS_JBI_BINDING);
299 }
300 if (isUseXmlBeans()) {
301 endpoint.setDataBinding(new XmlBeansDataBinding());
302 }
303 endpoint.setInInterceptors(getInInterceptors());
304 endpoint.setInFaultInterceptors(getInFaultInterceptors());
305 endpoint.setOutInterceptors(getOutInterceptors());
306 endpoint.setOutFaultInterceptors(getOutFaultInterceptors());
307 if (isMtomEnabled()) {
308 endpoint.getInInterceptors().add(new AttachmentInInterceptor());
309 endpoint.getOutInterceptors().add(new AttachmentOutInterceptor());
310 }
311 JaxWsImplementorInfo implInfo = new JaxWsImplementorInfo(getPojo().getClass());
312 setPojoService(implInfo.getServiceName());
313 setPojoInterfaceName(implInfo.getInterfaceName());
314 setPojoEndpoint(implInfo.getEndpointName().getLocalPart());
315 if (getService() == null) {
316 setService(implInfo.getServiceName());
317 }
318 if (getInterfaceName() == null) {
319 setInterfaceName(implInfo.getInterfaceName());
320 }
321 if (getEndpoint() == null) {
322 setEndpoint(implInfo.getEndpointName().getLocalPart());
323 }
324
325 }
326 super.validate();
327
328 }
329
330 private void removeInterceptor(List<Interceptor> interceptors, String whichInterceptor) {
331 for (Interceptor interceptor : interceptors) {
332 if (interceptor.getClass().getName().endsWith(whichInterceptor)) {
333 interceptors.remove(interceptor);
334 }
335 }
336 }
337
338 /*
339 * (non-Javadoc)
340 *
341 * @see org.apache.servicemix.common.endpoints.ProviderEndpoint#process(javax.jbi.messaging.MessageExchange)
342 */
343 @Override
344 public void process(MessageExchange exchange) throws Exception {
345 if (exchange.getStatus() != ExchangeStatus.ACTIVE) {
346 return;
347 }
348 JBIContext.setMessageExchange(exchange);
349 try {
350 QName opeName = exchange.getOperation();
351 EndpointInfo ei = server.getEndpoint().getEndpointInfo();
352
353 if (opeName == null) {
354 // if interface only have one operation, may not specify the
355 // opeName
356 // in MessageExchange
357 if (ei.getBinding().getOperations().size() == 1) {
358 opeName = ei.getBinding().getOperations().iterator().next().getName();
359 exchange.setOperation(opeName);
360 } else {
361 NormalizedMessage nm = exchange.getMessage("in");
362 if (soapBindingServer == null) {
363 ServerFactoryBean sfForSoapBinding = new ServerFactoryBean();
364 sfForSoapBinding.setServiceBean(getPojo());
365 //sfForSoapBinding.setAddress("http://dummyaddress");
366 sfForSoapBinding.getServiceFactory().setPopulateFromClass(true);
367 sfForSoapBinding.setStart(false);
368 sfForSoapBinding.setAddress("local://dummy");
369 soapBindingServer = sfForSoapBinding.create();
370 }
371 Message message = soapBindingServer.getEndpoint().getBinding().createMessage();
372 opeName = findOperation(nm, message, exchange);
373 exchange.setOperation(opeName);
374
375 }
376 }
377 JBITransportFactory jbiTransportFactory = (JBITransportFactory)getBus()
378 .getExtension(ConduitInitiatorManager.class)
379 .getConduitInitiator(CxfSeComponent.JBI_TRANSPORT_ID);
380
381 exchange.setService(getPojoService());
382 exchange.setInterfaceName(getPojoInterfaceName());
383 JBIDestination jbiDestination = jbiTransportFactory.getDestination(getPojoService().toString()
384 + getPojoInterfaceName().toString());
385 DeliveryChannel dc = getContext().getDeliveryChannel();
386 jbiTransportFactory.setDeliveryChannel(dc);
387
388 jbiDestination.setDeliveryChannel(dc);
389 if (exchange.getStatus() == ExchangeStatus.ACTIVE) {
390 jbiDestination.getJBIDispatcherUtil().dispatch(exchange);
391 }
392 if (exchange instanceof InOnly || exchange instanceof RobustInOnly) {
393 exchange.setStatus(ExchangeStatus.DONE);
394 dc.send(exchange);
395 }
396
397 } finally {
398 JBIContext.setMessageExchange(null);
399 }
400 }
401
402 /*
403 * (non-Javadoc)
404 *
405 * @see org.apache.servicemix.common.endpoints.ProviderEndpoint#start()
406 */
407 @Override
408 public void start() throws Exception {
409 super.start();
410 address = "jbi://" + ID_GENERATOR.generateSanitizedId();
411 try {
412 if (isUseAegis()) {
413 server.start();
414 } else {
415 endpoint.publish(address);
416 server = endpoint.getServer();
417 }
418 } catch (Exception e) {
419 e.printStackTrace();
420 }
421
422 if (getService() == null) {
423 setService(server.getEndpoint().getService().getName());
424 }
425 if (getEndpoint() == null) {
426 setEndpoint(server.getEndpoint().getEndpointInfo()
427 .getName().getLocalPart());
428 }
429 setPojoService(server.getEndpoint().getService().getName());
430 setPojoEndpoint(server.getEndpoint().getEndpointInfo()
431 .getName().getLocalPart());
432 if (!isUseJBIWrapper() && !isUseSOAPEnvelope()) {
433 removeInterceptor(server.getEndpoint().getBinding().getInInterceptors(), "ReadHeadersInterceptor");
434 removeInterceptor(server.getEndpoint().getBinding().getInFaultInterceptors(),
435 "ReadHeadersInterceptor");
436 removeInterceptor(server.getEndpoint().getBinding().getOutInterceptors(), "SoapOutInterceptor");
437 removeInterceptor(server.getEndpoint().getBinding().getOutFaultInterceptors(),
438 "SoapOutInterceptor");
439 removeInterceptor(server.getEndpoint().getBinding().getOutInterceptors(), "StaxOutInterceptor");
440 }
441
442 try {
443 definition = new ServiceWSDLBuilder(getBus(), server.getEndpoint().getService().getServiceInfos()
444 .iterator().next()).build();
445 description = WSDLFactory.newInstance().newWSDLWriter().getDocument(definition);
446 } catch (WSDLException e) {
447 throw new DeploymentException(e);
448 }
449 ReflectionUtils.doWithFields(getPojo().getClass(), new FieldCallback() {
450 public void doWith(Field field) throws IllegalArgumentException, IllegalAccessException {
451 if (field.getAnnotation(WebServiceRef.class) != null) {
452 ServiceImpl s = new ServiceImpl(getBus(), null, null, field.getType());
453 s
454 .addPort(new QName("port"), JBITransportFactory.TRANSPORT_ID,
455 "jbi://" + ID_GENERATOR.generateSanitizedId());
456 Object o = s.getPort(new QName("port"), field.getType());
457 field.setAccessible(true);
458 field.set(getPojo(), o);
459 }
460 }
461 });
462 ReflectionUtils.callLifecycleMethod(getPojo(), PostConstruct.class);
463 injectPojo();
464 }
465
466 /*
467 * (non-Javadoc)
468 *
469 * @see org.apache.servicemix.common.endpoints.ProviderEndpoint#stop()
470 */
471 @Override
472 public void stop() throws Exception {
473 if (isUseAegis()) {
474 server.stop();
475 } else {
476 endpoint.stop();
477 }
478 ReflectionUtils.callLifecycleMethod(getPojo(), PreDestroy.class);
479 JBIDispatcherUtil.clean();
480 JBITransportFactory jbiTransportFactory = (JBITransportFactory)getBus()
481 .getExtension(ConduitInitiatorManager.class).getConduitInitiator(CxfSeComponent.JBI_TRANSPORT_ID);
482 jbiTransportFactory.setDeliveryChannel(null);
483 jbiTransportFactory.removeDestination(getPojoService().toString() + getPojoInterfaceName().toString());
484 super.stop();
485 }
486
487 protected Bus getBus() {
488 return ((CxfSeComponent)getServiceUnit().getComponent()).getBus();
489 }
490
491 private QName findOperation(NormalizedMessage nm, Message message, MessageExchange exchange)
492 throws TransformerException, ParserConfigurationException, IOException, SAXException {
493 // try to figure out the operationName based on the incoming message
494 // payload and wsdl if use doc/literal/wrapped
495 Element element = new SourceTransformer().toDOMElement(nm.getContent());
496
497 if (!useJBIWrapper) {
498 SoapVersion soapVersion = ((SoapMessage)message).getVersion();
499 if (element != null) {
500 Element bodyElement = (Element)element.getElementsByTagNameNS(
501 element.getNamespaceURI(),
502 soapVersion.getBody()
503 .getLocalPart()).item(0);
504 if (bodyElement != null) {
505 element = (Element)bodyElement.getFirstChild();
506 }
507 }
508 } else {
509 element = DomUtil.getFirstChildElement(DomUtil.getFirstChildElement(element));
510 }
511
512 QName opeName = new QName(element.getNamespaceURI(), element.getLocalName());
513 SoapBindingInfo binding = (SoapBindingInfo)soapBindingServer.getEndpoint().getEndpointInfo()
514 .getBinding();
515 for (BindingOperationInfo op : binding.getOperations()) {
516 String style = binding.getStyle(op.getOperationInfo());
517 if (style == null) {
518 style = binding.getStyle();
519 }
520 if ("document".equals(style)) {
521 if (op.getName().getLocalPart().equals(opeName.getLocalPart())) {
522 return new QName(getPojoService().getNamespaceURI(), opeName.getLocalPart());
523 }
524 } else {
525 throw new Fault(new Exception("Operation must bound on this MessageExchange if use rpc mode"));
526 }
527 }
528 throw new Fault(new Exception("Operation not bound on this MessageExchange"));
529
530 }
531
532 @PostConstruct
533 protected void injectPojo() {
534 try {
535 ComponentContext context = getContext();
536 Method mth = pojo.getClass().getMethod("setContext", new Class[] {ComponentContext.class});
537 if (mth != null) {
538 mth.invoke(pojo, new Object[] {context});
539 }
540 } catch (Exception e) {
541 //setContext is optional for the pojo
542 }
543
544 }
545
546 /**
547 * Specifies if the endpoint can process messages with binary data.
548 *
549 * @param mtomEnabled a <code>boolean</code>
550 * @org.apache.xbean.Property description="Specifies if the service can
551 * consume MTOM formatted binary data. The
552 * default is <code>false</code>."
553 */
554 public void setMtomEnabled(boolean mtomEnabled) {
555 this.mtomEnabled = mtomEnabled;
556 }
557
558 public boolean isMtomEnabled() {
559 return mtomEnabled;
560 }
561
562 /**
563 * Specifies if the endpoint expects messages that are encased in the JBI
564 * wrapper used for SOAP messages. Ignore the value of useSOAPEnvelope if
565 * useJBIWrapper is true
566 *
567 * @org.apache.xbean.Property description="Specifies if the endpoint expects
568 * to receive the JBI wrapper in the message
569 * received from the NMR. The default is
570 * <code>true</code>. Ignore the value of
571 * useSOAPEnvelope if useJBIWrapper is true"
572 */
573 public void setUseJBIWrapper(boolean useJBIWrapper) {
574 this.useJBIWrapper = useJBIWrapper;
575 }
576
577 public boolean isUseJBIWrapper() {
578 return useJBIWrapper;
579 }
580
581 /**
582 * Specifies if the endpoint expects soap messages when useJBIWrapper is
583 * false, if useJBIWrapper is true then ignore useSOAPEnvelope
584 *
585 * @org.apache.xbean.Property description="Specifies if the endpoint expects
586 * soap messages when useJBIWrapper is false, if
587 * useJBIWrapper is true then ignore
588 * useSOAPEnvelope. The default is
589 * <code>true</code>.
590 */
591 public void setUseSOAPEnvelope(boolean useSOAPEnvelope) {
592 this.useSOAPEnvelope = useSOAPEnvelope;
593 }
594
595 public boolean isUseSOAPEnvelope() {
596 return useSOAPEnvelope;
597 }
598
599 /**
600 * Specifies if the endpoint use aegis databinding to marshell/unmarshell
601 * message
602 *
603 * @org.apache.xbean.Property description="Specifies if the endpoint use
604 * aegis databinding to marshell/unmarshell
605 * message. The default is <code>false</code>.
606 */
607 public void setUseAegis(boolean useAegis) {
608 this.useAegis = useAegis;
609 }
610
611 public boolean isUseAegis() {
612 return useAegis;
613 }
614
615 protected void setPojoService(QName pojoService) {
616 this.pojoService = pojoService;
617 }
618
619 protected QName getPojoService() {
620 return pojoService;
621 }
622
623 protected void setPojoEndpoint(String pojoEndpoint) {
624 this.pojoEndpoint = pojoEndpoint;
625 }
626
627 protected String getPojoEndpoint() {
628 return pojoEndpoint;
629 }
630
631 protected void setPojoInterfaceName(QName pojoInterfaceName) {
632 this.pojoInterfaceName = pojoInterfaceName;
633 }
634
635 protected QName getPojoInterfaceName() {
636 return pojoInterfaceName;
637 }
638
639
640 /**
641 * Specifies if the endpoint use xmlbeans databinding to marshell/unmarshell
642 * message
643 *
644 * @org.apache.xbean.Property description="Specifies if the endpoint use
645 * xmlbeans databinding to marshell/unmarshell
646 * message. The default is <code>false</code>.
647 */
648 public void setUseXmlBeans(boolean useXmlBeans) {
649 this.useXmlBeans = useXmlBeans;
650 }
651
652 public boolean isUseXmlBeans() {
653 return useXmlBeans;
654 }
655
656 }