com.googlecode.ddom.saaj.SOAPMessageTest.java Source code

Java tutorial

Introduction

Here is the source code for com.googlecode.ddom.saaj.SOAPMessageTest.java

Source

/*
 * Copyright 2009-2011 Andreas Veithen
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.googlecode.ddom.saaj;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.util.Arrays;
import java.util.Iterator;

import javax.activation.DataHandler;
import javax.activation.MimeType;
import javax.mail.BodyPart;
import javax.mail.internet.MimeMultipart;
import javax.mail.util.ByteArrayDataSource;
import javax.xml.namespace.QName;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.soap.AttachmentPart;
import javax.xml.soap.MessageFactory;
import javax.xml.soap.MimeHeaders;
import javax.xml.soap.SOAPBody;
import javax.xml.soap.SOAPEnvelope;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPMessage;
import javax.xml.soap.SOAPPart;

import org.apache.commons.io.IOUtils;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import com.github.veithen.ddom.ts.saaj.MessageSet;
import com.google.code.ddom.utils.test.Validated;
import com.google.code.ddom.utils.test.ValidatedTestRunner;

@RunWith(ValidatedTestRunner.class)
public abstract class SOAPMessageTest {
    private final MessageSet messageSet;

    public SOAPMessageTest(MessageSet messageSet) {
        this.messageSet = messageSet;
    }

    protected abstract MessageFactory getFactory();

    /**
     * Tests the behavior of {@link SOAPMessage#getSOAPHeader()} after removing the header from the
     * message. Note that the SAAJ specification requires the implementation to throw an exception
     * in this case. However, the reference implementation simply returns <code>null</code> (see
     * also <a href="http://java.net/jira/browse/SAAJ-15">SAAJ-15</a>). We stick to the behavior of
     * the reference implementation.
     * 
     * @throws Exception
     */
    @Validated
    @Test
    public void testGetSOAPHeaderWithNoHeader() throws Exception {
        SOAPMessage message = getFactory().createMessage();
        SOAPEnvelope envelope = message.getSOAPPart().getEnvelope();
        // Remove the SOAP header (created by default by MessageFactory) using plain DOM methods
        Node child = envelope.getFirstChild();
        while (child != null) {
            if (child instanceof Element && ((Element) child).getLocalName().equals("Header")) {
                envelope.removeChild(child);
                break;
            }
        }
        assertNull(message.getSOAPHeader());
    }

    @Validated
    @Test
    public void testCreateAttachmentPart() throws Exception {
        SOAPMessage message = getFactory().createMessage();
        message.createAttachmentPart();
        // The attachment part is not added to the message
        assertEquals(0, message.countAttachments());
    }

    @Validated
    @Test
    public void testAddAttachmentPart() throws Exception {
        SOAPMessage message = getFactory().createMessage();
        AttachmentPart attachment = message.createAttachmentPart();
        message.addAttachmentPart(attachment);
        Iterator it = message.getAttachments();
        assertTrue(it.hasNext());
        assertSame(attachment, it.next());
        assertFalse(it.hasNext());
        // Check that the content type automatically changes to SwA
        if (message.saveRequired()) {
            message.saveChanges();
        }
        String[] contentTypeArray = message.getMimeHeaders().getHeader("Content-Type");
        assertNotNull(contentTypeArray);
        assertEquals(1, contentTypeArray.length);
        MimeType contentType = new MimeType(contentTypeArray[0]);
        assertEquals("multipart/related", contentType.getBaseType());
        assertEquals(messageSet.getVersion().getContentType(), contentType.getParameter("type"));
        assertNotNull(contentType.getParameter("boundary"));
    }

    @Validated
    @Test
    public void testGetAttachmentsFiltered() throws Exception {
        SOAPMessage message = getFactory().createMessage();

        AttachmentPart att1 = message.createAttachmentPart();
        att1.addMimeHeader("Content-Type", "text/plain");
        message.addAttachmentPart(att1);

        AttachmentPart att2 = message.createAttachmentPart();
        att2.addMimeHeader("Content-Type", "application/octet-stream");
        message.addAttachmentPart(att2);

        AttachmentPart att3 = message.createAttachmentPart();
        att3.addMimeHeader("Content-ID", "<123456@example.com>");
        att3.addMimeHeader("Content-Type", "text/plain");
        message.addAttachmentPart(att3);

        MimeHeaders headers = new MimeHeaders();
        headers.addHeader("Content-Type", "text/plain");
        Iterator it = message.getAttachments(headers);
        assertTrue(it.hasNext());
        assertSame(att1, it.next());
        assertTrue(it.hasNext());
        assertSame(att3, it.next());
        assertFalse(it.hasNext());
    }

    @Validated
    @Test
    public final void testRemoveAllAttachments() throws Exception {
        SOAPMessage message = getFactory().createMessage();
        for (int i = 0; i < 5; i++) {
            AttachmentPart att = message.createAttachmentPart("test" + i, "text/plain");
            message.addAttachmentPart(att);
        }
        assertEquals(5, message.countAttachments());
        message.removeAllAttachments();
        assertEquals(0, message.countAttachments());
        if (message.saveRequired()) {
            message.saveChanges();
        }
        String[] contentType = message.getMimeHeaders().getHeader("Content-Type");
        assertNotNull(contentType);
        assertEquals(1, contentType.length);
        assertEquals(messageSet.getVersion().getContentType(), new MimeType(contentType[0]).getBaseType());
    }

    @Validated
    @Test
    public void testGetSetCharacterSetEncoding() throws Exception {
        SOAPMessage message = getFactory().createMessage();
        String encoding = "ISO-8859-15";
        message.setProperty(SOAPMessage.CHARACTER_SET_ENCODING, encoding);
        assertEquals(encoding, message.getProperty(SOAPMessage.CHARACTER_SET_ENCODING));
    }

    /**
     * Tests that calling {@link SOAPMessage#setProperty(String, Object)} doesn't throw an exception
     * for unknown property names. Although that the Javadoc of that method suggests that a
     * {@link SOAPException} should be thrown, this is not the case for the reference
     * implementation.
     * 
     * @throws Exception
     */
    @Validated
    @Test
    public void testSetPropertyUnknown() throws Exception {
        SOAPMessage message = getFactory().createMessage();
        message.setProperty("some.unknown.property", "test");
    }

    /**
     * Tests the behavior of {@link SOAPPart#getContent()} for a plain SOAP message created from an
     * input stream.
     * 
     * @throws Exception
     * 
     * @see SOAPPartTest#testGetContent()
     */
    @Validated
    @Test
    public void testWriteTo() throws Exception {
        MimeHeaders headers = new MimeHeaders();
        headers.addHeader("Content-Type", messageSet.getVersion().getContentType() + "; charset=utf-8");
        InputStream in = messageSet.getTestMessage("message.xml");
        byte[] orgContent = IOUtils.toByteArray(in);
        SOAPMessage message = getFactory().createMessage(headers, new ByteArrayInputStream(orgContent));

        // Get the content before accessing the SOAP part
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        message.writeTo(baos);
        byte[] content1 = baos.toByteArray();
        assertTrue(Arrays.equals(orgContent, content1));

        // Now access the SOAP part and get the content again
        message.getSOAPPart().getEnvelope();
        baos = new ByteArrayOutputStream();
        message.writeTo(baos);
        byte[] content2 = baos.toByteArray();
        // The content is equivalent, but not exactly the same
        assertFalse(Arrays.equals(orgContent, content2));
    }

    /**
     * Tests that {@link SOAPMessage#writeTo(java.io.OutputStream)} performs namespace repairing.
     * 
     * @throws Exception
     */
    @Validated
    @Test
    public void testWriteToNamespaceRepairing() throws Exception {
        SOAPMessage message = getFactory().createMessage();
        SOAPPart part = message.getSOAPPart();
        SOAPBody body = part.getEnvelope().getBody();
        body.appendChild(part.createElementNS("urn:ns", "p:test"));
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        message.writeTo(baos);
        String content = baos.toString("UTF-8");
        assertTrue(content.contains("<p:test xmlns:p=\"urn:ns\"/>"));
    }

    @Validated
    @Test
    public void testWriteToWithAttachment() throws Exception {
        SOAPMessage message = getFactory().createMessage();
        message.getSOAPPart().getEnvelope().getBody().addBodyElement(new QName("urn:ns", "test", "p"));
        AttachmentPart attachment = message.createAttachmentPart();
        attachment.setDataHandler(new DataHandler("This is a test", "text/plain; charset=iso-8859-15"));
        message.addAttachmentPart(attachment);
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        message.writeTo(baos);
        System.out.write(baos.toByteArray());
        MimeMultipart mp = new MimeMultipart(new ByteArrayDataSource(baos.toByteArray(), "multipart/related"));
        assertEquals(2, mp.getCount());
        BodyPart part1 = mp.getBodyPart(0);
        // TODO
        //        assertEquals(messageSet.getVersion().getContentType(), part1.getContentType());
        BodyPart part2 = mp.getBodyPart(1);
        // Note: text/plain is the default content type, so we need to include the parameters in the assertion
        assertEquals("text/plain; charset=iso-8859-15", part2.getContentType());
    }

    /**
     * Tests the behavior of {@link SOAPMessage#writeTo(java.io.OutputStream)} on a message for
     * which no content has been specified.
     * 
     * @throws Exception
     */
    @Validated
    @Test
    public void testWriteToEmpty() throws Exception {
        SOAPMessage message = getFactory().createMessage();
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        message.writeTo(baos);
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        dbf.setNamespaceAware(true);
        Document doc = dbf.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray()));
        Element envelope = doc.getDocumentElement();
        assertEquals("Envelope", envelope.getLocalName());
        NodeList children = envelope.getElementsByTagNameNS("*", "*");
        assertEquals(2, children.getLength());
        assertEquals("Header", children.item(0).getLocalName());
        assertEquals("Body", children.item(1).getLocalName());
    }
}