001: /**
002: * Licensed to the Apache Software Foundation (ASF) under one
003: * or more contributor license agreements. See the NOTICE file
004: * distributed with this work for additional information
005: * regarding copyright ownership. The ASF licenses this file
006: * to you under the Apache License, Version 2.0 (the
007: * "License"); you may not use this file except in compliance
008: * with the License. You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing,
013: * software distributed under the License is distributed on an
014: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015: * KIND, either express or implied. See the License for the
016: * specific language governing permissions and limitations
017: * under the License.
018: */package org.apache.cxf.binding.soap;
019:
020: import java.util.ArrayList;
021: import java.util.Iterator;
022: import java.util.LinkedList;
023: import java.util.List;
024:
025: import javax.wsdl.BindingInput;
026: import javax.wsdl.BindingOutput;
027: import javax.wsdl.Definition;
028: import javax.wsdl.Part;
029: import javax.wsdl.WSDLException;
030: import javax.wsdl.extensions.ExtensibilityElement;
031: import javax.wsdl.extensions.ExtensionRegistry;
032: import javax.wsdl.extensions.mime.MIMEContent;
033: import javax.wsdl.extensions.mime.MIMEMultipartRelated;
034: import javax.wsdl.extensions.mime.MIMEPart;
035: import javax.xml.namespace.QName;
036:
037: import org.apache.cxf.binding.AbstractBindingFactory;
038: import org.apache.cxf.binding.Binding;
039: import org.apache.cxf.binding.soap.interceptor.EndpointSelectionInterceptor;
040: import org.apache.cxf.binding.soap.interceptor.MustUnderstandInterceptor;
041: import org.apache.cxf.binding.soap.interceptor.RPCInInterceptor;
042: import org.apache.cxf.binding.soap.interceptor.RPCOutInterceptor;
043: import org.apache.cxf.binding.soap.interceptor.ReadHeadersInterceptor;
044: import org.apache.cxf.binding.soap.interceptor.Soap11FaultInInterceptor;
045: import org.apache.cxf.binding.soap.interceptor.Soap11FaultOutInterceptor;
046: import org.apache.cxf.binding.soap.interceptor.Soap12FaultInInterceptor;
047: import org.apache.cxf.binding.soap.interceptor.Soap12FaultOutInterceptor;
048: import org.apache.cxf.binding.soap.interceptor.SoapActionInInterceptor;
049: import org.apache.cxf.binding.soap.interceptor.SoapActionOutInterceptor;
050: import org.apache.cxf.binding.soap.interceptor.SoapHeaderInterceptor;
051: import org.apache.cxf.binding.soap.interceptor.SoapHeaderOutFilterInterceptor;
052: import org.apache.cxf.binding.soap.interceptor.SoapOutInterceptor;
053: import org.apache.cxf.binding.soap.interceptor.SoapPreProtocolOutInterceptor;
054: import org.apache.cxf.binding.soap.model.SoapBindingInfo;
055: import org.apache.cxf.binding.soap.model.SoapBodyInfo;
056: import org.apache.cxf.binding.soap.model.SoapHeaderInfo;
057: import org.apache.cxf.binding.soap.model.SoapOperationInfo;
058: import org.apache.cxf.common.util.StringUtils;
059: import org.apache.cxf.endpoint.Endpoint;
060: import org.apache.cxf.interceptor.AttachmentInInterceptor;
061: import org.apache.cxf.interceptor.AttachmentOutInterceptor;
062: import org.apache.cxf.interceptor.BareOutInterceptor;
063: import org.apache.cxf.interceptor.DocLiteralInInterceptor;
064: import org.apache.cxf.interceptor.StaxInInterceptor;
065: import org.apache.cxf.interceptor.StaxOutInterceptor;
066: import org.apache.cxf.interceptor.URIMappingInterceptor;
067: import org.apache.cxf.interceptor.WrappedOutInterceptor;
068: import org.apache.cxf.message.Message;
069: import org.apache.cxf.service.model.BindingFaultInfo;
070: import org.apache.cxf.service.model.BindingInfo;
071: import org.apache.cxf.service.model.BindingMessageInfo;
072: import org.apache.cxf.service.model.BindingOperationInfo;
073: import org.apache.cxf.service.model.MessageInfo;
074: import org.apache.cxf.service.model.MessagePartInfo;
075: import org.apache.cxf.service.model.OperationInfo;
076: import org.apache.cxf.service.model.ServiceInfo;
077: import org.apache.cxf.tools.common.extensions.soap.SoapBinding;
078: import org.apache.cxf.tools.common.extensions.soap.SoapBody;
079: import org.apache.cxf.tools.common.extensions.soap.SoapFault;
080: import org.apache.cxf.tools.common.extensions.soap.SoapHeader;
081: import org.apache.cxf.tools.common.extensions.soap.SoapOperation;
082: import org.apache.cxf.tools.util.SOAPBindingUtil;
083: import org.apache.cxf.transport.ChainInitiationObserver;
084: import org.apache.cxf.transport.Destination;
085: import org.apache.cxf.transport.MessageObserver;
086: import org.apache.cxf.transport.MultipleEndpointObserver;
087: import org.apache.cxf.wsdl.WSDLConstants;
088: import org.apache.cxf.wsdl.WSDLManager;
089: import org.apache.cxf.wsdl11.WSDLServiceBuilder;
090: import org.apache.ws.commons.schema.XmlSchemaCollection;
091:
092: import static org.apache.cxf.helpers.CastUtils.cast;
093:
094: public class SoapBindingFactory extends AbstractBindingFactory {
095:
096: public static final String SOAP_11_BINDING = "http://schemas.xmlsoap.org/wsdl/soap/";
097: public static final String SOAP_12_BINDING = "http://schemas.xmlsoap.org/wsdl/soap12/";
098:
099: public static final String HEADER = "messagepart.isheader";
100: public static final String OUT_OF_BAND_HEADER = "messagepart.is_out_of_band_header";
101:
102: private boolean mtomEnabled = true;
103:
104: public BindingInfo createBindingInfo(ServiceInfo si,
105: String bindingid, Object conf) {
106: SoapBindingConfiguration config;
107: if (conf instanceof SoapBindingConfiguration) {
108: config = (SoapBindingConfiguration) conf;
109: } else {
110: config = new SoapBindingConfiguration();
111: }
112: if (WSDLConstants.SOAP12_NAMESPACE.equals(bindingid)
113: || WSDLConstants.SOAP12_HTTP_TRANSPORT
114: .equals(bindingid)) {
115: config.setVersion(Soap12.getInstance());
116: config.setTransportURI(WSDLConstants.SOAP12_HTTP_TRANSPORT);
117: }
118: SoapBindingInfo info = new SoapBindingInfo(si, bindingid,
119: config.getVersion());
120:
121: info.setName(new QName(si.getName().getNamespaceURI(), si
122: .getName().getLocalPart()
123: + "SoapBinding"));
124: info.setStyle(config.getStyle());
125: info.setTransportURI(config.getTransportURI());
126:
127: if (config.isMtomEnabled()) {
128: info.setProperty(Message.MTOM_ENABLED, Boolean.TRUE);
129: }
130:
131: for (OperationInfo op : si.getInterface().getOperations()) {
132: SoapOperationInfo sop = new SoapOperationInfo();
133: sop.setAction(config.getSoapAction(op));
134: sop.setStyle(config.getStyle(op));
135:
136: BindingOperationInfo bop = info
137: .buildOperation(op.getName(), op.getInputName(), op
138: .getOutputName());
139:
140: bop.addExtensor(sop);
141:
142: info.addOperation(bop);
143:
144: BindingMessageInfo bInput = bop.getInput();
145: if (bInput != null) {
146: MessageInfo input = null;
147: BindingMessageInfo unwrappedMsg = bInput;
148: if (bop.isUnwrappedCapable()) {
149: input = bop.getOperationInfo()
150: .getUnwrappedOperation().getInput();
151: unwrappedMsg = bop.getUnwrappedOperation()
152: .getInput();
153: } else {
154: input = bop.getOperationInfo().getInput();
155: }
156: setupHeaders(bop, bInput, unwrappedMsg, input, config);
157: }
158:
159: BindingMessageInfo bOutput = bop.getOutput();
160: if (bOutput != null) {
161: MessageInfo output = null;
162: BindingMessageInfo unwrappedMsg = bOutput;
163: if (bop.isUnwrappedCapable()) {
164: output = bop.getOperationInfo()
165: .getUnwrappedOperation().getOutput();
166: unwrappedMsg = bop.getUnwrappedOperation()
167: .getOutput();
168: } else {
169: output = bop.getOperationInfo().getOutput();
170: }
171: setupHeaders(bop, bOutput, unwrappedMsg, output, config);
172: }
173: }
174:
175: try {
176: createSoapBinding(info);
177: } catch (WSDLException e) {
178: e.printStackTrace();
179: }
180:
181: return info;
182: }
183:
184: private void createSoapBinding(final SoapBindingInfo bi)
185: throws WSDLException {
186: boolean isSoap12 = bi.getSoapVersion() instanceof Soap12;
187: ExtensionRegistry extensionRegistry = getBus().getExtension(
188: WSDLManager.class).getExtenstionRegistry();
189:
190: SoapBinding soapBinding = SOAPBindingUtil.createSoapBinding(
191: extensionRegistry, isSoap12);
192: soapBinding.setStyle(bi.getStyle());
193: soapBinding.setTransportURI(bi.getTransportURI());
194: bi.addExtensor(soapBinding);
195:
196: for (BindingOperationInfo b : bi.getOperations()) {
197: for (BindingFaultInfo faultInfo : b.getFaults()) {
198: SoapFault soapFault = SOAPBindingUtil.createSoapFault(
199: extensionRegistry, isSoap12);
200: soapFault.setUse("literal");
201: soapFault.setName(faultInfo.getFaultInfo()
202: .getFaultName().getLocalPart());
203: faultInfo.addExtensor(soapFault);
204: }
205: SoapOperationInfo soi = b
206: .getExtensor(SoapOperationInfo.class);
207:
208: SoapOperation soapOperation = SOAPBindingUtil
209: .createSoapOperation(extensionRegistry, isSoap12);
210: soapOperation.setSoapActionURI(soi.getAction());
211: soapOperation.setStyle(soi.getStyle());
212: boolean isRpc = "rpc".equals(soapOperation.getStyle());
213:
214: b.addExtensor(soapOperation);
215:
216: if (b.getInput() != null) {
217: List<String> bodyParts = null;
218: List<SoapHeaderInfo> headerInfos = b.getInput()
219: .getExtensors(SoapHeaderInfo.class);
220: if (headerInfos != null && headerInfos.size() > 0) {
221: bodyParts = new ArrayList<String>();
222: for (MessagePartInfo part : b.getInput()
223: .getMessageParts()) {
224: bodyParts.add(part.getName().getLocalPart());
225: }
226:
227: for (SoapHeaderInfo headerInfo : headerInfos) {
228: SoapHeader soapHeader = SOAPBindingUtil
229: .createSoapHeader(extensionRegistry,
230: BindingInput.class, isSoap12);
231: soapHeader.setMessage(b.getInput()
232: .getMessageInfo().getName());
233: soapHeader.setPart(headerInfo.getPart()
234: .getName().getLocalPart());
235: soapHeader.setUse("literal");
236: bodyParts.remove(headerInfo.getPart().getName()
237: .getLocalPart());
238: b.getInput().addExtensor(soapHeader);
239: }
240: }
241: SoapBody body = SOAPBindingUtil
242: .createSoapBody(extensionRegistry,
243: BindingInput.class, isSoap12);
244: body.setUse("literal");
245: if (isRpc) {
246: body.setNamespaceURI(b.getName().getNamespaceURI());
247: }
248:
249: if (bodyParts != null) {
250: body.setParts(bodyParts);
251: }
252:
253: b.getInput().addExtensor(body);
254: }
255:
256: if (b.getOutput() != null) {
257: List<String> bodyParts = null;
258: List<SoapHeaderInfo> headerInfos = b.getOutput()
259: .getExtensors(SoapHeaderInfo.class);
260: if (headerInfos != null && headerInfos.size() > 0) {
261: bodyParts = new ArrayList<String>();
262: for (MessagePartInfo part : b.getOutput()
263: .getMessageParts()) {
264: bodyParts.add(part.getName().getLocalPart());
265: }
266: for (SoapHeaderInfo headerInfo : headerInfos) {
267: SoapHeader soapHeader = SOAPBindingUtil
268: .createSoapHeader(extensionRegistry,
269: BindingOutput.class, isSoap12);
270: soapHeader.setMessage(b.getOutput()
271: .getMessageInfo().getName());
272: soapHeader.setPart(headerInfo.getPart()
273: .getName().getLocalPart());
274: soapHeader.setUse("literal");
275: bodyParts.remove(headerInfo.getPart().getName()
276: .getLocalPart());
277: b.getOutput().addExtensor(soapHeader);
278: }
279: }
280: SoapBody body = SOAPBindingUtil.createSoapBody(
281: extensionRegistry, BindingOutput.class,
282: isSoap12);
283: body.setUse("literal");
284: if (isRpc) {
285: body.setNamespaceURI(b.getName().getNamespaceURI());
286: }
287:
288: if (bodyParts != null) {
289: body.setParts(bodyParts);
290: }
291:
292: b.getOutput().addExtensor(body);
293: }
294: }
295: }
296:
297: private void setupHeaders(BindingOperationInfo op,
298: BindingMessageInfo bMsg, BindingMessageInfo unwrappedBMsg,
299: MessageInfo msg, SoapBindingConfiguration config) {
300: List<MessagePartInfo> parts = new ArrayList<MessagePartInfo>();
301: for (MessagePartInfo part : msg.getMessageParts()) {
302: if (config.isHeader(op, part)) {
303: SoapHeaderInfo headerInfo = new SoapHeaderInfo();
304: headerInfo.setPart(part);
305: headerInfo.setUse(config.getUse());
306:
307: bMsg.addExtensor(headerInfo);
308: } else {
309: parts.add(part);
310: }
311: }
312: unwrappedBMsg.setMessageParts(parts);
313: }
314:
315: public Binding createBinding(BindingInfo binding) {
316: // TODO what about the mix style/use?
317:
318: // The default style should be doc-lit wrapped.
319: String parameterStyle = SoapConstants.PARAMETER_STYLE_WRAPPED;
320: String bindingStyle = SoapConstants.BINDING_STYLE_DOC;
321:
322: org.apache.cxf.binding.soap.SoapBinding sb = null;
323: SoapVersion version = null;
324: if (binding instanceof SoapBindingInfo) {
325: SoapBindingInfo sbi = (SoapBindingInfo) binding;
326: version = sbi.getSoapVersion();
327: sb = new org.apache.cxf.binding.soap.SoapBinding(binding,
328: version);
329: // Service wide style
330: if (!StringUtils.isEmpty(sbi.getStyle())) {
331: bindingStyle = sbi.getStyle();
332: }
333:
334: // Operation wide style, what to do with the mixed style/use?
335: for (BindingOperationInfo boi : sbi.getOperations()) {
336: if (sbi.getStyle(boi.getOperationInfo()) != null) {
337: bindingStyle = sbi.getStyle(boi.getOperationInfo());
338: }
339: if (boi.getUnwrappedOperation() == null) {
340: parameterStyle = SoapConstants.PARAMETER_STYLE_BARE;
341: }
342: }
343: } else {
344: throw new RuntimeException(
345: "Can not initialize SoapBinding, BindingInfo is not SoapBindingInfo");
346: }
347:
348: sb.getOutFaultInterceptors().add(new StaxOutInterceptor());
349:
350: //Do not add any interceptors if it is Provider/Dispatch
351: if (!Boolean.TRUE.equals(binding
352: .getProperty(DATABINDING_DISABLED))) {
353: sb.getInInterceptors().add(new AttachmentInInterceptor());
354: sb.getInInterceptors().add(new StaxInInterceptor());
355: sb.getInInterceptors().add(new SoapActionInInterceptor());
356:
357: sb.getOutInterceptors().add(new SoapActionOutInterceptor());
358: sb.getOutInterceptors().add(new AttachmentOutInterceptor());
359: sb.getOutInterceptors().add(new StaxOutInterceptor());
360: sb.getOutInterceptors().add(
361: new SoapHeaderOutFilterInterceptor());
362:
363: if (SoapConstants.BINDING_STYLE_RPC
364: .equalsIgnoreCase(bindingStyle)) {
365: sb.getInInterceptors().add(new RPCInInterceptor());
366: sb.getOutInterceptors().add(new RPCOutInterceptor());
367: } else if (SoapConstants.BINDING_STYLE_DOC
368: .equalsIgnoreCase(bindingStyle)
369: && SoapConstants.PARAMETER_STYLE_BARE
370: .equalsIgnoreCase(parameterStyle)) {
371: //sb.getInInterceptors().add(new BareInInterceptor());
372: sb.getInInterceptors().add(
373: new DocLiteralInInterceptor());
374: sb.getOutInterceptors().add(new BareOutInterceptor());
375: } else {
376: //sb.getInInterceptors().add(new WrappedInInterceptor());
377: sb.getInInterceptors().add(
378: new DocLiteralInInterceptor());
379: sb.getOutInterceptors()
380: .add(new WrappedOutInterceptor());
381: sb.getOutInterceptors().add(new BareOutInterceptor());
382: }
383: sb.getInInterceptors().add(new SoapHeaderInterceptor());
384:
385: sb.getInInterceptors().add(
386: new ReadHeadersInterceptor(getBus()));
387: sb.getInInterceptors().add(new MustUnderstandInterceptor());
388: sb.getOutInterceptors().add(
389: new SoapPreProtocolOutInterceptor());
390: sb.getOutInterceptors().add(
391: new SoapOutInterceptor(getBus()));
392: sb.getOutFaultInterceptors().add(
393: new SoapOutInterceptor(getBus()));
394:
395: // REVISIT: The phase interceptor chain seems to freak out if this added
396: // first. Not sure what the deal is at the moment, I suspect the
397: // ordering algorithm needs to be improved
398: sb.getInInterceptors().add(new URIMappingInterceptor());
399: }
400:
401: if (version.getVersion() == 1.1) {
402: sb.getInFaultInterceptors().add(
403: new Soap11FaultInInterceptor());
404: sb.getOutFaultInterceptors().add(
405: new Soap11FaultOutInterceptor());
406: } else if (version.getVersion() == 1.2) {
407: sb.getInFaultInterceptors().add(
408: new Soap12FaultInInterceptor());
409: sb.getOutFaultInterceptors().add(
410: new Soap12FaultOutInterceptor());
411: }
412:
413: return sb;
414: }
415:
416: protected void addMessageFromBinding(ExtensibilityElement ext,
417: BindingOperationInfo bop, boolean isInput) {
418: SoapHeader header = SOAPBindingUtil.getSoapHeader(ext);
419:
420: ServiceInfo serviceInfo = bop.getBinding().getService();
421:
422: if (header != null
423: && serviceInfo.getMessage(header.getMessage()) == null) {
424: Definition def = (Definition) serviceInfo
425: .getProperty(WSDLServiceBuilder.WSDL_DEFINITION);
426: XmlSchemaCollection schemas = (XmlSchemaCollection) serviceInfo
427: .getProperty(WSDLServiceBuilder.WSDL_SCHEMA_LIST);
428:
429: if (def != null && schemas != null) {
430: javax.wsdl.Message msg = def.getMessage(header
431: .getMessage());
432: if (msg != null) {
433: addOutOfBandParts(bop, msg, schemas, isInput);
434: serviceInfo.refresh();
435: } else {
436: //TODO: The header message is not defined in this wsdl, what to do
437: }
438: }
439: }
440: }
441:
442: private void addOutOfBandParts(final BindingOperationInfo bop,
443: final javax.wsdl.Message msg,
444: final XmlSchemaCollection schemas, boolean isInput) {
445: MessageInfo minfo = null;
446: if (isInput) {
447: minfo = bop.getOperationInfo().getInput();
448: } else {
449: minfo = bop.getOperationInfo().getOutput();
450: }
451:
452: if (minfo == null) {
453: minfo = new MessageInfo(null, msg.getQName());
454: }
455: buildMessage(minfo, msg, schemas);
456:
457: // for wrapped style
458: OperationInfo unwrapped = bop.getOperationInfo()
459: .getUnwrappedOperation();
460: if (unwrapped == null) {
461: return;
462: }
463: if (isInput) {
464: minfo = unwrapped.getInput();
465: } else {
466: minfo = unwrapped.getOutput();
467: }
468:
469: if (minfo == null) {
470: minfo = new MessageInfo(unwrapped, msg.getQName());
471: }
472: buildMessage(minfo, msg, schemas);
473: }
474:
475: private void buildMessage(MessageInfo minfo,
476: javax.wsdl.Message msg, XmlSchemaCollection schemas) {
477: for (Part part : cast(msg.getParts().values(), Part.class)) {
478: MessagePartInfo pi = minfo.addMessagePart(new QName(minfo
479: .getName().getNamespaceURI(), part.getName()));
480: if (part.getTypeName() != null) {
481: pi.setTypeQName(part.getTypeName());
482: pi.setElement(false);
483: pi.setXmlSchema(schemas.getTypeByQName(part
484: .getTypeName()));
485: } else {
486: pi.setElementQName(part.getElementName());
487: pi.setElement(true);
488: pi.setXmlSchema(schemas.getElementByQName(part
489: .getElementName()));
490: }
491: pi.setProperty(OUT_OF_BAND_HEADER, Boolean.TRUE);
492: }
493: }
494:
495: public BindingInfo createBindingInfo(ServiceInfo service,
496: javax.wsdl.Binding binding, String ns) {
497: SoapBindingInfo bi = new SoapBindingInfo(service, ns);
498: // Copy all the extensors
499: initializeBindingInfo(service, binding, bi);
500:
501: SoapBinding wSoapBinding = SOAPBindingUtil.getSoapBinding(bi
502: .getExtensors(ExtensibilityElement.class));
503:
504: bi.setTransportURI(wSoapBinding.getTransportURI());
505: bi.setStyle(wSoapBinding.getStyle());
506:
507: for (BindingOperationInfo boi : bi.getOperations()) {
508: initializeBindingOperation(bi, boi);
509: }
510:
511: return bi;
512: }
513:
514: private void initializeBindingOperation(SoapBindingInfo bi,
515: BindingOperationInfo boi) {
516: SoapOperationInfo soi = new SoapOperationInfo();
517:
518: SoapOperation soapOp = SOAPBindingUtil.getSoapOperation(boi
519: .getExtensors(ExtensibilityElement.class));
520:
521: if (soapOp != null) {
522: String action = soapOp.getSoapActionURI();
523: if (action == null) {
524: action = "";
525: }
526:
527: soi.setAction(action);
528: soi.setStyle(soapOp.getStyle());
529: }
530:
531: boi.addExtensor(soi);
532:
533: if (boi.getInput() != null) {
534: initializeMessage(bi, boi, boi.getInput());
535: }
536:
537: if (boi.getOutput() != null) {
538: initializeMessage(bi, boi, boi.getOutput());
539: }
540: }
541:
542: private void initializeMessage(SoapBindingInfo bi,
543: BindingOperationInfo boi, BindingMessageInfo bmsg) {
544: MessageInfo msg = bmsg.getMessageInfo();
545:
546: List<MessagePartInfo> messageParts = new ArrayList<MessagePartInfo>();
547: messageParts.addAll(msg.getMessageParts());
548:
549: List<SoapHeader> headers = SOAPBindingUtil.getSoapHeaders(bmsg
550: .getExtensors(ExtensibilityElement.class));
551: if (headers != null) {
552: for (SoapHeader header : headers) {
553: SoapHeaderInfo headerInfo = new SoapHeaderInfo();
554: headerInfo.setUse(header.getUse());
555: MessagePartInfo part = msg
556: .getMessagePart(new QName(msg.getName()
557: .getNamespaceURI(), header.getPart()));
558: if (part != null) {
559: headerInfo.setPart(part);
560: messageParts.remove(part);
561: bmsg.addExtensor(headerInfo);
562: }
563: }
564:
565: // Exclude the header parts from the message part list.
566: bmsg.setMessageParts(messageParts);
567: }
568:
569: SoapBodyInfo bodyInfo = new SoapBodyInfo();
570: SoapBody soapBody = SOAPBindingUtil.getSoapBody(bmsg
571: .getExtensors(ExtensibilityElement.class));
572: List parts = null;
573: if (soapBody == null) {
574: MIMEMultipartRelated mmr = bmsg
575: .getExtensor(MIMEMultipartRelated.class);
576: if (mmr != null) {
577: parts = mmr.getMIMEParts();
578: }
579: } else {
580: bodyInfo.setUse(soapBody.getUse());
581: parts = soapBody.getParts();
582: }
583:
584: // Initialize the body parts.
585: List<MessagePartInfo> attParts = null;
586: if (parts != null) {
587: List<MessagePartInfo> bodyParts = new ArrayList<MessagePartInfo>();
588: for (Iterator itr = parts.iterator(); itr.hasNext();) {
589: Object part = itr.next();
590: String partName = null;
591: if (part instanceof MIMEPart) {
592: MIMEPart mpart = (MIMEPart) part;
593: if (mpart.getExtensibilityElements().size() < 1) {
594: throw new RuntimeException(
595: "MIMEPart should at least contain one element!");
596: }
597: for (Object content : mpart
598: .getExtensibilityElements()) {
599: if (content instanceof MIMEContent) {
600: MIMEContent mc = (MIMEContent) content;
601: partName = mc.getPart();
602:
603: if (attParts == null) {
604: attParts = new LinkedList<MessagePartInfo>();
605: }
606:
607: MessagePartInfo mpi = msg
608: .getMessagePart(new QName(msg
609: .getName()
610: .getNamespaceURI(),
611: partName));
612: mpi.setProperty(Message.CONTENT_TYPE, mc
613: .getType());
614: attParts.add(mpi);
615: // Attachments shouldn't be part of the body message
616: bmsg.getMessageParts().remove(mpi);
617: } else if (SOAPBindingUtil.isSOAPBody(content)) {
618: SoapBody sb = SOAPBindingUtil
619: .getSoapBody(content);
620: if (sb.getParts().size() == 1) {
621: partName = (String) sb.getParts()
622: .get(0);
623: }
624:
625: // We can have a list of empty part names here.
626: if (partName != null) {
627: addSoapBodyPart(msg, bodyParts,
628: partName);
629: }
630: } else if (SOAPBindingUtil
631: .isSOAPHeader(content)) {
632: SoapHeader header = SOAPBindingUtil
633: .getSoapHeader(content);
634:
635: SoapHeaderInfo headerInfo = new SoapHeaderInfo();
636: headerInfo.setUse(header.getUse());
637: MessagePartInfo mpi = msg
638: .getMessagePart(new QName(msg
639: .getName()
640: .getNamespaceURI(), header
641: .getPart()));
642: if (mpi != null) {
643: headerInfo.setPart(mpi);
644: messageParts.remove(part);
645: bmsg.getMessageParts().remove(mpi);
646: bmsg.addExtensor(headerInfo);
647: }
648: }
649: }
650: } else {
651: addSoapBodyPart(msg, bodyParts, (String) part);
652: }
653: }
654: bodyInfo.setParts(bodyParts);
655: bodyInfo.setAttachments(attParts);
656: } else {
657: bodyInfo.setParts(messageParts);
658: }
659:
660: bmsg.addExtensor(bodyInfo);
661: }
662:
663: private void addSoapBodyPart(MessageInfo msg,
664: List<MessagePartInfo> bodyParts, String partName) {
665: MessagePartInfo mpi = msg.getMessagePart(new QName(msg
666: .getName().getNamespaceURI(), partName));
667: bodyParts.add(mpi);
668: }
669:
670: @Override
671: public synchronized void addListener(Destination d, Endpoint e) {
672: MessageObserver mo = d.getMessageObserver();
673: if (mo == null) {
674: super .addListener(d, e);
675: return;
676: }
677:
678: if (mo instanceof ChainInitiationObserver) {
679: ChainInitiationObserver cio = (ChainInitiationObserver) mo;
680: MultipleEndpointObserver newMO = new MultipleEndpointObserver(
681: getBus()) {
682: @Override
683: protected Message createMessage(Message message) {
684: return new SoapMessage(message);
685: }
686: };
687:
688: newMO.getBindingInterceptors().add(
689: new AttachmentInInterceptor());
690: newMO.getBindingInterceptors().add(new StaxInInterceptor());
691:
692: // This will not work if we one of the endpoints disables message
693: // processing. But, if you've disabled message processing, you
694: // probably aren't going to use this feature.
695: newMO.getBindingInterceptors().add(
696: new ReadHeadersInterceptor(getBus()));
697:
698: // Add in a default selection interceptor
699: newMO.getRoutingInterceptors().add(
700: new EndpointSelectionInterceptor());
701:
702: newMO.getEndpoints().add(cio.getEndpoint());
703:
704: mo = newMO;
705: }
706:
707: if (mo instanceof MultipleEndpointObserver) {
708: MultipleEndpointObserver meo = (MultipleEndpointObserver) mo;
709: meo.getEndpoints().add(e);
710: }
711:
712: d.setMessageObserver(mo);
713: }
714:
715: public void setMtomEnabled(boolean mtomEnabled) {
716: this .mtomEnabled = mtomEnabled;
717: }
718:
719: public boolean isMtomEnabled() {
720: return mtomEnabled;
721: }
722: }
|