package org.jentrata.ebms.utils; import org.apache.camel.Exchange; import org.apache.commons.io.IOUtils; import org.jentrata.ebms.EbmsConstants; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.soap.AttachmentPart; import javax.xml.soap.MessageFactory; import javax.xml.soap.MimeHeaders; import javax.xml.soap.SOAPConstants; import javax.xml.soap.SOAPEnvelope; import javax.xml.soap.SOAPHeader; import javax.xml.soap.SOAPMessage; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import javax.xml.xpath.XPath; import javax.xml.xpath.XPathConstants; import javax.xml.xpath.XPathExpressionException; import javax.xml.xpath.XPathFactory; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.zip.GZIPInputStream; import java.util.zip.GZIPOutputStream; /** * Ebms Test Utility Class * * @author aaronwalker */ public class EbmsUtils { private EbmsUtils(){} public static final SOAPMessage createSOAP11MessageFromClasspath(String filename) throws Exception { String message = toStringFromClasspath(filename); return createSOAP11Message(message); } public static final SOAPMessage createSOAP12MessageFromClasspath(String filename) throws Exception { String message = toStringFromClasspath(filename); return createSOAP12Message(message); } public static final SOAPMessage createSOAP12Message(String ebmsMessage) throws Exception { return createSOAPMessage(SOAPConstants.SOAP_1_2_PROTOCOL,ebmsMessage); } public static final SOAPMessage createSOAP11Message(String ebmsMessage) throws Exception { return createSOAPMessage(SOAPConstants.SOAP_1_1_PROTOCOL,ebmsMessage); } public static final SOAPMessage createSOAPMessage(String soapProtocol, String ebmsMessage) throws Exception{ MessageFactory messageFactory = MessageFactory.newInstance(soapProtocol); SOAPMessage soapMessage = messageFactory.createMessage(); SOAPEnvelope soapEnvelope = soapMessage.getSOAPPart().getEnvelope(); soapMessage.getSOAPPart().addMimeHeader("Content-ID", "<soapPart@jentrata.org>"); SOAPHeader soapHeader = soapEnvelope.getHeader(); Element ebms = toXML(ebmsMessage).getDocumentElement(); Node node = soapEnvelope.getOwnerDocument().importNode(ebms,true); soapHeader.appendChild(node); soapMessage.saveChanges(); return soapMessage; } public static final SOAPMessage parse(String soapProtocol, String contentType, InputStream stream) throws Exception { MessageFactory messageFactory = MessageFactory.newInstance(soapProtocol); MimeHeaders mimeHeaders = new MimeHeaders(); mimeHeaders.addHeader(Exchange.CONTENT_TYPE, contentType); SOAPMessage message = messageFactory.createMessage(mimeHeaders, stream); SOAPHeader soapHeader = message.getSOAPPart().getEnvelope().getHeader(); return message; } public static final SOAPMessage parse(Exchange exchange) throws Exception { InputStream stream = exchange.getIn().getBody(InputStream.class); String contentType = exchange.getIn().getHeader(EbmsConstants.CONTENT_TYPE,String.class); String soapProtocol = exchange.getIn().getHeader(EbmsConstants.SOAP_VERSION,SOAPConstants.SOAP_1_2_PROTOCOL,String.class); return parse(soapProtocol,contentType,stream); } public static void addAttachment(SOAPMessage soapMessage,String contentId,String contentType,InputStream content) throws Exception { addAttachment(soapMessage, contentId, contentType, content, new HashMap<String, String>()); } public static void addAttachment(SOAPMessage soapMessage, String payloadId, String contentType, byte[] content) throws Exception { addAttachment(soapMessage,payloadId,contentType,new ByteArrayInputStream(content)); } public static void addAttachment(SOAPMessage soapMessage, String payloadId, String contentType, byte[] content, Map<String, String> mimeHeaders) throws Exception { addAttachment(soapMessage,payloadId,contentType,new ByteArrayInputStream(content),mimeHeaders); } public static void addGZippedAttachment(SOAPMessage soapMessage, String payloadId, byte[] content) throws Exception { addAttachment(soapMessage,payloadId, EbmsConstants.GZIP,compressStream(EbmsConstants.GZIP, content)); } public static void addAttachment(SOAPMessage soapMessage,String contentId,String contentType,InputStream content,Map<String,String> headers) throws Exception { AttachmentPart attachmentPart = soapMessage.createAttachmentPart(); //attachmentPart.setContentId(encodeContentId(contentId)); attachmentPart.setMimeHeader("Content-ID",encodeContentId(contentId)); // attachmentPart.setMimeHeader("Content-ID",contentId); attachmentPart.setContentType(contentType); attachmentPart.setRawContent(content,contentType); for(Map.Entry<String,String> header : headers.entrySet()) { attachmentPart.addMimeHeader(header.getKey(), header.getValue()); } soapMessage.addAttachmentPart(attachmentPart); soapMessage.saveChanges(); soapMessage.getMimeHeaders().setHeader("Content-Type",soapMessage.getMimeHeaders().getHeader("Content-Type")[0] + "; start=\"<soapPart@jentrata.org>\""); } public static String encodeContentId(String contentId) { if(contentId != null && !contentId.startsWith("<") && !contentId.endsWith(">")) { return "<" + contentId + ">"; } else { return contentId; } } public static String decodeContentID(String contentId) { if(contentId.startsWith("<") && contentId.endsWith(">")) { return contentId.substring(1,contentId.length()-1); } return contentId; } public static InputStream compressStream(String compressionType, byte [] content) throws IOException { return new ByteArrayInputStream(compress(compressionType, content)); } public static byte [] compress(String compressionType, byte [] content) throws IOException { if(EbmsConstants.GZIP.equalsIgnoreCase(compressionType)) { ByteArrayOutputStream bos = new ByteArrayOutputStream(); try(GZIPOutputStream gzip = new GZIPOutputStream(bos)) { gzip.write(content); } return bos.toByteArray(); } throw new UnsupportedOperationException("unsupported compression type " + compressionType); } public static byte [] decompress(String compressionType, byte [] content) throws IOException { if(EbmsConstants.GZIP.equalsIgnoreCase(compressionType)) { ByteArrayInputStream bis = new ByteArrayInputStream(content); try(GZIPInputStream gzip = new GZIPInputStream(bis)) { return IOUtils.toByteArray(gzip); } } throw new UnsupportedOperationException("unsupported compression type " + compressionType); } public static String toString(SOAPMessage soapMessage) throws Exception { return new String(toByteArray(soapMessage)); } public static String toString(Document doc) throws TransformerException { ByteArrayOutputStream baos = new ByteArrayOutputStream(); elementToStream(doc.getDocumentElement(), baos); return new String(baos.toByteArray()); } public static byte[] toByteArray(SOAPMessage soapMessage) throws Exception { ByteArrayOutputStream bos = new ByteArrayOutputStream(); soapMessage.writeTo(bos); return bos.toByteArray(); } public static void elementToStream(Element element, OutputStream out) throws TransformerException { DOMSource source = new DOMSource(element); StreamResult result = new StreamResult(out); TransformerFactory transFactory = TransformerFactory.newInstance(); Transformer transformer = transFactory.newTransformer(); transformer.transform(source, result); } public static final Document toXML(String xmlString) throws Exception { DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance(); docBuilderFactory.setNamespaceAware(true); DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder(); return docBuilder.parse(new ByteArrayInputStream(xmlString.getBytes())); } public static String toStringFromClasspath(String filename) throws IOException { File file = fileFromClasspath(filename); return IOUtils.toString(new FileInputStream(file)); } public static File fileFromClasspath(String filename) { File file = new File(Thread.currentThread().getContextClassLoader().getResource(filename).getFile()); return file; } public static final String ebmsXpathValue(Element element,String xpath) throws XPathExpressionException { XPath xPath = XPathFactory.newInstance().newXPath(); xPath.setNamespaceContext(Ebms3NamespaceContext.instance()); return (String)xPath.evaluate(xpath,element, XPathConstants.STRING); } public static final Node ebmsXpathNode(String xml,String xpath) throws Exception { return ebmsXpathNode(toXML(xml),xpath); } public static final Node ebmsXpathNode(Node xml,String xpath) throws Exception { XPath xPath = XPathFactory.newInstance().newXPath(); xPath.setNamespaceContext(Ebms3NamespaceContext.instance()); return (Node)xPath.evaluate(xpath,xml,XPathConstants.NODE); } public static final NodeList ebmsXpathNodeList(String xml,String xpath) throws Exception { return ebmsXpathNodeList(toXML(xml),xpath); } public static final NodeList ebmsXpathNodeList(Node xml,String xpath) throws Exception { XPath xPath = XPathFactory.newInstance().newXPath(); xPath.setNamespaceContext(Ebms3NamespaceContext.instance()); return (NodeList)xPath.evaluate(xpath,xml, XPathConstants.NODESET); } public static boolean hasEbmsXpath(Document element, String query) throws XPathExpressionException { XPath xPath = XPathFactory.newInstance().newXPath(); xPath.setNamespaceContext(Ebms3NamespaceContext.instance()); return xPath.evaluate(query,element, XPathConstants.NODE) != null; } public static List<Map<String, Object>> extractPartProperties(String partProperties) { List<Map<String,Object>> properites = new ArrayList<>(); if(partProperties != null && partProperties.length() > 0) { String [] propertyArray = partProperties.split(";"); for (String property : propertyArray) { String [] value = property.split("="); Map<String,Object> propertyMap = new HashMap<>(); propertyMap.put("name",value[0]); if(value.length == 2) { propertyMap.put("value",value[1]); } else { propertyMap.put("value",null); } properites.add(propertyMap); } } return properites; } }