com.eviware.soapui.impl.wsdl.submit.transports.http.AttachmentUtils.java Source code

Java tutorial

Introduction

Here is the source code for com.eviware.soapui.impl.wsdl.submit.transports.http.AttachmentUtils.java

Source

/*
 *  soapui, copyright (C) 2006 eviware.com 
 *
 *  SoapUI is free software; you can redistribute it and/or modify it under the 
 *  terms of the GNU Lesser General Public License as published by the Free Software Foundation; 
 *  either version 2.1 of the License, or (at your option) any later version.
 *
 *  SoapUI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without 
 *  even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
 *  See the GNU Lesser General Public License for more details at gnu.org.
 */

package com.eviware.soapui.impl.wsdl.submit.transports.http;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

import javax.activation.DataHandler;
import javax.mail.MessagingException;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMultipart;
import javax.mail.internet.PreencodedMimeBodyPart;
import javax.xml.namespace.QName;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.binary.Hex;
import org.apache.xmlbeans.SchemaType;
import org.apache.xmlbeans.XmlBase64Binary;
import org.apache.xmlbeans.XmlCursor;
import org.apache.xmlbeans.XmlHexBinary;

import com.eviware.soapui.impl.wsdl.WsdlRequest;
import com.eviware.soapui.impl.wsdl.support.RequestXmlPart;
import com.eviware.soapui.impl.wsdl.support.xsd.SchemaUtils;
import com.eviware.soapui.model.iface.Attachment;
import com.eviware.soapui.support.Tools;
import com.eviware.soapui.support.types.StringToStringMap;

public class AttachmentUtils {
    public static boolean isBinaryType(SchemaType schemaType) {
        return SchemaUtils.isInstanceOf(schemaType, XmlHexBinary.type)
                || SchemaUtils.isInstanceOf(schemaType, XmlBase64Binary.type);
    }

    public static boolean prepareRequestPart(WsdlRequest wsdlRequest, MimeMultipart mp, RequestXmlPart requestPart,
            StringToStringMap contentIds) throws Exception, MessagingException {
        boolean isXop = false;

        XmlCursor cursor = requestPart.newCursor();

        try {
            while (!cursor.isEnddoc()) {
                if (cursor.isContainer()) {
                    // could be an attachment part (as of "old" SwA specs which specify a content 
                    // element referring to the attachment)
                    if (requestPart.isAttachmentPart()) {
                        String href = cursor.getAttributeText(new QName("href"));
                        if (href != null && href.length() > 0) {
                            contentIds.put(requestPart.getPart().getName(), href);
                        }

                        break;
                    }

                    SchemaType schemaType = cursor.getObject().schemaType();
                    if (isBinaryType(schemaType)) {
                        String contentType = getXmlMimeContentType(cursor);

                        // extract contentId
                        String textContent = cursor.getTextValue();
                        Attachment attachment = null;
                        boolean isXopAttachment = false;

                        // is content a reference to a file?
                        if (textContent.startsWith("file:")) {
                            String filename = textContent.substring(5);
                            if (contentType == null) {
                                inlineData(cursor, schemaType, new FileInputStream(filename));
                            } else if (wsdlRequest.isMtomEnabled()) {
                                MimeBodyPart part = new PreencodedMimeBodyPart("binary");

                                part.setDataHandler(new DataHandler(
                                        new XOPPartDataSource(new File(filename), contentType, schemaType)));
                                part.setContentID("<" + filename + ">");
                                mp.addBodyPart(part);

                                isXopAttachment = true;
                            }
                        }
                        // is content a reference to an attachment?
                        else if (textContent.startsWith("cid:")) {
                            textContent = textContent.substring(4);
                            Attachment[] attachments = wsdlRequest.getAttachmentsForPart(textContent);
                            if (attachments.length == 1) {
                                attachment = attachments[0];
                            } else if (attachments.length > 1) {
                                attachment = buildMulitpartAttachment(attachments);
                            }

                            isXopAttachment = contentType != null;
                            contentIds.put(textContent, textContent);
                        }
                        // content should be binary data; is this an XOP element which should be serialized with MTOM?
                        else if (wsdlRequest.isMtomEnabled() && contentType != null) {
                            MimeBodyPart part = new PreencodedMimeBodyPart("binary");

                            part.setDataHandler(
                                    new DataHandler(new XOPPartDataSource(textContent, contentType, schemaType)));

                            textContent = "http://www.soapui.org/" + System.nanoTime();

                            part.setContentID("<" + textContent + ">");
                            mp.addBodyPart(part);

                            isXopAttachment = true;
                        }

                        // add XOP include?
                        if (isXopAttachment && wsdlRequest.isMtomEnabled()) {
                            buildXopInclude(cursor, textContent);
                            isXop = true;
                        }
                        // inline?
                        else if (attachment != null) {
                            inlineAttachment(cursor, schemaType, attachment);
                        }
                    }
                }

                cursor.toNextToken();
            }
        } finally {
            cursor.dispose();
        }

        return isXop;
    }

    private static void inlineAttachment(XmlCursor cursor, SchemaType schemaType, Attachment attachment)
            throws IOException {
        inlineData(cursor, schemaType, attachment.getInputStream());
    }

    private static void inlineData(XmlCursor cursor, SchemaType schemaType, InputStream in) throws IOException {
        String content = null;
        byte[] data = Tools.readAll(in, -1).toByteArray();

        if (SchemaUtils.isInstanceOf(schemaType, XmlHexBinary.type)) {
            content = new String(Hex.encodeHex(data));
        } else if (SchemaUtils.isInstanceOf(schemaType, XmlBase64Binary.type)) {
            content = new String(Base64.encodeBase64(data));
        }

        XmlCursor c = cursor.newCursor();
        c.setTextValue(content);
        c.dispose();
    }

    private static void buildXopInclude(XmlCursor cursor, String contentId) {
        // build xop:Include
        XmlCursor c = cursor.newCursor();
        c.removeXmlContents();
        c.toFirstContentToken();
        c.beginElement(new QName("http://www.w3.org/2004/08/xop/include", "Include"));
        c.insertAttributeWithValue(new QName("href"), "cid:" + contentId);
        c.toNextSibling();
        c.removeXml();
        c.dispose();
    }

    private static Attachment buildMulitpartAttachment(Attachment[] attachments) {
        System.out.println("buildMulitpartAttachment(Attachment[] attachments) not implemented!");
        return null;
    }

    public static String buildRootPartContentType(String action) {
        return "application/xop+xml; charset=UTF-8; type=\"application/soap+xml; action=\\\"" + action + "\\\"\"";
    }

    public static String buildMTOMContentType(String header, String action) {
        int ix = header.indexOf("boundary");
        return "multipart/related; type=\"application/xop+xml\"; start=\""
                + HttpClientRequestTransport.ROOTPART_SOAPUI_ORG + "\"; "
                + "startinfo=\"application/soap+xml; action=\\\"" + action + "\\\"\"; " + header.substring(ix);
    }

    public static boolean isSwaRefType(SchemaType schemaType) {
        return schemaType.getName() != null
                && schemaType.getName().equals(new QName("http://ws-i.org/profiles/basic/1.1/xsd", "swaRef"));
    }

    public static String getXmlMimeContentType(XmlCursor cursor) {
        String attributeText = cursor
                .getAttributeText(new QName("http://www.w3.org/2004/11/xmlmime", "contentType"));
        if (attributeText == null)
            attributeText = cursor.getAttributeText(new QName("http://www.w3.org/2005/05/xmlmime", "contentType"));
        return attributeText;
    }

}