Package org.apache.wink.server.internal.providers.entity

Source Code of org.apache.wink.server.internal.providers.entity.SourceProviderTest

/*******************************************************************************
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you 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 org.apache.wink.server.internal.providers.entity;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.StringTokenizer;

import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.ext.MessageBodyReader;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.TransformerFactoryConfigurationError;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.sax.SAXSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;

import org.apache.wink.common.RuntimeContext;
import org.apache.wink.common.internal.WinkConfiguration;
import org.apache.wink.common.internal.providers.entity.SourceProvider;
import org.apache.wink.common.internal.runtime.RuntimeContextTLS;
import org.apache.wink.server.internal.servlet.MockServletInvocationTest;
import org.apache.wink.test.mock.MockRequestConstructor;
import org.jmock.Expectations;
import org.jmock.Mockery;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.w3c.dom.Document;
import org.xml.sax.InputSource;

public class SourceProviderTest extends MockServletInvocationTest {

    private static final String SOURCE       =
                                                 "<?xml version=\"1.0\" encoding=\"UTF-8\"?><message>this is a test message</message>";
    private static final byte[] SOURCE_BYTES = SOURCE.getBytes();
    private String TEST_CLASSES_PATH = null;

    @Override
    public void setUp() throws Exception {
        super.setUp();
        Mockery mockery = new Mockery();
        final RuntimeContext context = mockery.mock(RuntimeContext.class);
        mockery.checking(new Expectations() {{
            allowing(context).getAttribute(WinkConfiguration.class); will(returnValue(null));
        }});
       
        RuntimeContextTLS.setRuntimeContext(context);
    }
   
    @Override
    public void tearDown() {
        RuntimeContextTLS.setRuntimeContext(null);
    }

    private String getPath() {
        if (TEST_CLASSES_PATH == null) {
          String classpath = System.getProperty("java.class.path");
          StringTokenizer tokenizer = new StringTokenizer(classpath, System.getProperty("path.separator"));
          TEST_CLASSES_PATH = null;
          while (tokenizer.hasMoreTokens()) {
              TEST_CLASSES_PATH = tokenizer.nextToken();
              if (TEST_CLASSES_PATH.endsWith("test-classes")) {
                  break;
              }
          }
          // for windows:
          int driveIndex = TEST_CLASSES_PATH.indexOf(":");
          if(driveIndex != -1) {
              TEST_CLASSES_PATH = TEST_CLASSES_PATH.substring(driveIndex + 1);
          }
        }
        return TEST_CLASSES_PATH;
    }
   
    @Override
    protected Class<?>[] getClasses() {
        return new Class<?>[] {SourceResource.class};
    }

    @Path("source")
    public static class SourceResource {

        private static final DocumentBuilderFactory documentBuilderFactory =
                                                                               DocumentBuilderFactory
                                                                                   .newInstance();
        private static final TransformerFactory     transformerFactory     =
                                                                               TransformerFactory
                                                                                   .newInstance();

        @GET
        @Path("stream")
        public Source getStream() {
            return new StreamSource(new ByteArrayInputStream(SOURCE_BYTES));
        }

        @GET
        @Path("sax")
        public Source getSax() {
            return new SAXSource(new InputSource(new ByteArrayInputStream(SOURCE_BYTES)));
        }

        @GET
        @Path("dom")
        public Source getDom() throws Exception {
            return new DOMSource(documentBuilderFactory.newDocumentBuilder()
                .parse(new ByteArrayInputStream(SOURCE_BYTES)));
        }

        @POST
        @Path("stream")
        public String postStream(StreamSource source) throws Exception {
            return extractXml(source);
        }

        @POST
        @Path("sax")
        public String postSax(SAXSource source) throws Exception {
            return extractXml(source);
        }
       
        @POST
        @Path("saxwithdtd")
        public String postSaxWithDTD(SAXSource source) throws Exception {
            /*
             * we don't want to trigger a parse in this resource method.  We're testing to see what happened
             * with the SAXSource on the way here.
             */
            StringBuilder sb = new StringBuilder();
            String line;
            InputStream is = source.getInputSource().getByteStream();
            try {
                BufferedReader reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
                while ((line = reader.readLine()) != null) {
                    sb.append(line).append("\n");
                }
            } finally {
                is.close();
            }
            return sb.toString();
        }

        @POST
        @Path("dom")
        public String postDom(DOMSource source) throws Exception {
            return extractXml(source);
        }
       
        @POST
        @Path("domwithdtd")
        public String postDomWithDTD(DOMSource source) throws Exception {
            /*
             * we don't want to trigger a parse in this resource method.  We're testing to see what happened
             * with the SAXSource on the way here.
             */
            return source.getNode().getFirstChild().getFirstChild().getTextContent();
        }

        private String extractXml(Source source) throws TransformerFactoryConfigurationError,
            TransformerConfigurationException, TransformerException {
            Transformer transformer = transformerFactory.newTransformer();
            StringWriter sw = new StringWriter();
            StreamResult sr = new StreamResult(sw);
            transformer.transform(source, sr);
            return sw.toString();
        }

    }

    public void testSourceProvider() throws Exception {
        // stream source
        SourceProvider provider = new SourceProvider.StreamSourceProvider();
        Source source = assertSourceReader(provider, StreamSource.class);
        assertSourceWriter(provider, source);

        // sax source
        provider = new SourceProvider.SAXSourceProvider();
        source = assertSourceReader(provider, SAXSource.class);
        assertSourceWriter(provider, source);

        // dom source
        provider = new SourceProvider.DOMSourceProvider();
        source = assertSourceReader(provider, DOMSource.class);
        assertSourceWriter(provider, source);
    }

    public void testSourceProviderInvocation() throws Exception {
        MockHttpServletRequest request =
            MockRequestConstructor.constructMockRequest("GET", "/source/stream", "text/xml");
        MockHttpServletResponse response = invoke(request);
        assertEquals(200, response.getStatus());
        assertEquals(SOURCE, response.getContentAsString());

        request = MockRequestConstructor.constructMockRequest("GET", "/source/sax", "text/xml");
        response = invoke(request);
        assertEquals(200, response.getStatus());
        assertEquals(SOURCE, response.getContentAsString());

        request = MockRequestConstructor.constructMockRequest("GET", "/source/dom", "text/xml");
        response = invoke(request);
        assertEquals(200, response.getStatus());
        // Ignore Xml declaration, since in 1.6 Transformer always generates xml
        // with "standalone" attribute
        // when DOMSource is serialized
        assertEqualsEgnoreXmlDecl(SOURCE, response.getContentAsString());

        request =
            MockRequestConstructor.constructMockRequest("POST",
                                                        "/source/stream",
                                                        "text/xml",
                                                        "text/xml",
                                                        SOURCE_BYTES);
        response = invoke(request);
        assertEquals(200, response.getStatus());
        assertEquals(SOURCE, response.getContentAsString());

        request =
            MockRequestConstructor.constructMockRequest("POST",
                                                        "/source/sax",
                                                        "text/xml",
                                                        "text/xml",
                                                        SOURCE_BYTES);
        response = invoke(request);
        assertEquals(200, response.getStatus());
        assertEquals(SOURCE, response.getContentAsString());

        request =
            MockRequestConstructor.constructMockRequest("POST",
                                                        "/source/dom",
                                                        "text/xml",
                                                        "text/xml",
                                                        SOURCE_BYTES);
        response = invoke(request);
        assertEquals(200, response.getStatus());
        // Ignore Xml declaration, since in 1.6 Transformer always generates xml
        // with "standalone" attribute
        // when DOMSource is serialized
        assertEqualsEgnoreXmlDecl(SOURCE, response.getContentAsString());

    }
   
    public void testSaxWithDTD() throws Exception {
       
        String path = getPath();
       
        final String SOURCE =
            "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
            "<!DOCTYPE data [<!ENTITY file SYSTEM \""+ path +"/etc/SourceProviderTest.txt\">]>" +
            "<message>&file;</message>";
       
        final byte[] SOURCE_BYTES = SOURCE.getBytes();
       
        MockHttpServletRequest request =
            MockRequestConstructor.constructMockRequest("POST",
                                                        "/source/saxwithdtd",
                                                        "application/xml",
                                                        "application/xml",
                                                        SOURCE_BYTES);
        MockHttpServletResponse response = invoke(request);
        assertEquals(200, response.getStatus());
        assertFalse("File content is visible but should not be.",
                response.getContentAsString().contains("YOU SHOULD NOT BE ABLE TO SEE THIS"));
        assertEquals(SOURCE, response.getContentAsString().trim());
    }
   
    public void testDomWithDTD() throws Exception {
       
        String path = getPath();
       
        final String SOURCE =
            "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
            "<!DOCTYPE data [<!ENTITY file SYSTEM \""+ path +"/etc/SourceProviderTest.txt\">]>" +
            "<message>&file;</message>";

        final byte[] SOURCE_BYTES = SOURCE.getBytes();
       
        MockHttpServletRequest request =
            MockRequestConstructor.constructMockRequest("POST",
                                                        "/source/domwithdtd",
                                                        "application/xml",
                                                        "application/xml",
                                                        SOURCE_BYTES);
        MockHttpServletResponse response = invoke(request);
        assertEquals(400, response.getStatus());
       
        // as a sanity check, let's make sure our xml is good:
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = factory.newDocumentBuilder();
        InputSource is = new InputSource( new StringReader(SOURCE) );
        Document d = builder.parse( is );
        assertEquals("xml is bad", "YOU SHOULD NOT BE ABLE TO SEE THIS", d.getElementsByTagName("message").item(0).getTextContent().trim());
    }

    // -- Helpers

    private void assertSourceWriter(SourceProvider provider, Source source) throws Exception {
        assertTrue(provider
            .isWriteable(source.getClass(), null, null, new MediaType("text", "xml")));
        assertTrue(provider.isWriteable(source.getClass(), null, null, new MediaType("application",
                                                                                     "xml")));
        assertTrue(provider.isWriteable(source.getClass(), null, null, new MediaType("application",
                                                                                     "atom+xml")));
        assertTrue(provider
            .isWriteable(source.getClass(), null, null, new MediaType("application", "atomsvc+xml")));
        assertFalse(provider.isWriteable(source.getClass(), null, null, new MediaType("text",
                                                                                      "plain")));

        ByteArrayOutputStream os = new ByteArrayOutputStream();
        provider.writeTo(source, null, null, null, new MediaType("text", "xml"), null, os);
        // Ignore Xml declaration, since in 1.6 Transformer always generates xml
        // with "standalone" attribute
        // when DOMSource is serialized
        assertEqualsEgnoreXmlDecl(SOURCE, os.toString());
    }

    @SuppressWarnings("unchecked")
    private Source assertSourceReader(SourceProvider provider, Class<?> sourceClass)
        throws Exception {
        ByteArrayInputStream inputStream = new ByteArrayInputStream(SOURCE.getBytes("UTF-8"));
        MessageBodyReader<Source> bodyReader = (MessageBodyReader<Source>)provider;
        assertTrue(bodyReader.isReadable(sourceClass, null, null, new MediaType("text", "xml")));
        assertTrue(bodyReader.isReadable(sourceClass, null, null, new MediaType("application",
                                                                                "xml")));
        assertTrue(bodyReader.isReadable(sourceClass, null, null, new MediaType("application",
                                                                                "atom+xml")));
        assertTrue(bodyReader.isReadable(sourceClass, null, null, new MediaType("application",
                                                                                "atomsvc+xml")));
        assertFalse(bodyReader.isReadable(sourceClass, null, null, new MediaType("text", "plain")));

        Source source =
            bodyReader.readFrom((Class<Source>)sourceClass,
                                null,
                                null,
                                new MediaType("text", "xml"),
                                null,
                                inputStream);
        assertNotNull(source);
        assertEquals(sourceClass, source.getClass());
        return source;
    }

    private void assertEqualsEgnoreXmlDecl(String expected, String actual) {
        expected = removeXmlDecl(expected);
        actual = removeXmlDecl(actual);
        assertEquals(expected, actual);
    }

    private String removeXmlDecl(String expected) {
        if (expected.indexOf("<?xml") >= 0) {
            expected = expected.substring(expected.indexOf("?>"));
        }
        return expected;
    }

}
TOP

Related Classes of org.apache.wink.server.internal.providers.entity.SourceProviderTest

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.