package org.jentrata.ebms.soap;
import org.apache.camel.Exchange;
import org.apache.camel.spi.DataFormat;
import org.jentrata.ebms.EbmsConstants;
import org.jentrata.ebms.utils.EbmsUtils;
import javax.xml.soap.AttachmentPart;
import javax.xml.soap.MessageFactory;
import javax.xml.soap.MimeHeaders;
import javax.xml.soap.SOAPConstants;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPHeader;
import javax.xml.soap.SOAPMessage;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
/**
* Marshals/Unmarshals org.wc3.Document into a SOAPMessage
* Also handles messages with attachments
*
* @author aaronwalker
*/
@SuppressWarnings("unchecked")
public class SoapMessageDataFormat implements DataFormat {
/**
* Converts a org.wc3.Document SOAPMessage
*
* @param exchange
* @param graph
* @param stream
* @throws Exception
*/
@Override
public void marshal(Exchange exchange, Object graph, OutputStream stream) throws Exception {
String soapVersion = exchange.getIn().getHeader(EbmsConstants.SOAP_VERSION,SOAPConstants.SOAP_1_2_PROTOCOL,String.class);
SOAPMessage soapMessage = EbmsUtils.parse(soapVersion,EbmsConstants.SOAP_XML_CONTENT_TYPE,exchange.getIn().getBody(InputStream.class));
soapMessage.getSOAPPart().addMimeHeader(EbmsConstants.CONTENT_ID,"<soapPart@jentrata.org>");
List<Map<String,Object>> payloads = (List<Map<String, Object>>) exchange.getIn().getHeader(EbmsConstants.MESSAGE_PAYLOADS);
for(Map<String,Object> payload : payloads) {
String payloadId = (String) payload.get("payloadId");
String contentType = (String) payload.get("contentType");
String compressionType = (String) payload.get("compressionType");
byte [] content = (byte[]) payload.get("content");
if(EbmsConstants.GZIP.equalsIgnoreCase(compressionType)) {
contentType = compressionType;
}
Map<String,String> mimeHeaders = (Map<String, String>) payload.get("mimeHeaders");
EbmsUtils.addAttachment(soapMessage,payloadId,contentType,content,mimeHeaders);
}
exchange.getOut().setHeader(EbmsConstants.CONTENT_TYPE,soapMessage.getMimeHeaders().getHeader(EbmsConstants.CONTENT_TYPE)[0]);
soapMessage.writeTo(stream);
}
/**
* Converts a SOAPMessage into a org.wc3.Document
*
* Using a custom message header you can which SOAP Version the message is in
*
* @param exchange
* @param stream
* @return
* @throws Exception
*/
@Override
public Object unmarshal(Exchange exchange, InputStream stream) throws Exception {
InputStream body = exchange.getContext().getTypeConverter().convertTo(InputStream.class,exchange.getIn().getBody());
String soapVersion = exchange.getIn().getHeader(EbmsConstants.SOAP_VERSION, SOAPConstants.SOAP_1_2_PROTOCOL, String.class);
MessageFactory messageFactory = MessageFactory.newInstance(soapVersion);
MimeHeaders mimeHeaders = new MimeHeaders();
mimeHeaders.addHeader(Exchange.CONTENT_TYPE, exchange.getIn().getHeader(Exchange.CONTENT_TYPE, String.class));
SOAPMessage message = messageFactory.createMessage(mimeHeaders, body);
SOAPHeader soapHeader = message.getSOAPPart().getEnvelope().getHeader();
if(message.countAttachments() > 0) {
addAttachments(message, exchange);
}
return soapHeader.getOwnerDocument();
}
private void addAttachments(SOAPMessage message, Exchange exchange) throws SOAPException {
Iterator<AttachmentPart> attachments = message.getAttachments();
while (attachments.hasNext()) {
AttachmentPart attachment = attachments.next();
String contentId = EbmsUtils. decodeContentID(attachment.getContentId());
exchange.getOut().addAttachment(contentId,attachment.getDataHandler());
}
}
}