/* * Copyright 2002-2014 the original author or authors. * * 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 org.springframework.http.converter.xml; import static android.test.MoreAsserts.*; import static org.custommonkey.xmlunit.XMLAssert.*; import java.io.InputStreamReader; import java.io.StringReader; import java.nio.charset.Charset; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.transform.Source; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.sax.SAXSource; import javax.xml.transform.stream.StreamSource; import junit.framework.TestCase; import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.Resource; import org.springframework.http.MediaType; import org.springframework.http.MockHttpInputMessage; import org.springframework.http.MockHttpOutputMessage; import org.springframework.util.ClassUtils; import org.springframework.util.FileCopyUtils; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.xml.sax.InputSource; import org.xml.sax.SAXException; import org.xml.sax.XMLReader; import org.xml.sax.helpers.DefaultHandler; import android.os.Build; import android.test.suitebuilder.annotation.MediumTest; import android.test.suitebuilder.annotation.SmallTest; import android.util.Log; /** * @author Arjen Poutsma * @author Roy Clarkson */ public class SourceHttpMessageConverterTests extends TestCase { private static final String TAG = SourceHttpMessageConverterTests.class.getSimpleName(); private static final String BODY = "<root>Hello World</root>"; private static final boolean javaxXmlTransformPresent = ClassUtils.isPresent("javax.xml.transform.Source", SourceHttpMessageConverterTests.class.getClassLoader()); private static final boolean olderThanFroyo = (Build.VERSION.SDK_INT < Build.VERSION_CODES.FROYO); private SourceHttpMessageConverter<Source> converter; private String bodyExternal; @Override protected void setUp() throws Exception { if (javaxXmlTransformPresent) { this.converter = new SourceHttpMessageConverter<Source>(); Resource external = new ClassPathResource("external.txt", getClass()); bodyExternal = "<!DOCTYPE root SYSTEM \"http://192.168.28.42/1.jsp\" [" + " <!ELEMENT root ANY >\n" + " <!ENTITY ext SYSTEM \"" + external.getURI() + "\" >]><root>&ext;</root>"; } else { assertTrue(olderThanFroyo); if (Log.isLoggable(TAG, Log.INFO)) { Log.i(TAG, "SourceHttpMessageConverter is not compatible with this version of Android"); } } } @Override protected void runTest() throws Throwable { if (javaxXmlTransformPresent) { super.runTest(); } } @Override public void tearDown() { this.converter = null; } @SmallTest public void testCanRead() { assertTrue(converter.canRead(Source.class, new MediaType("application", "xml"))); assertTrue(converter.canRead(Source.class, new MediaType("application", "soap+xml"))); } @SmallTest public void testCanWrite() { assertTrue(converter.canWrite(Source.class, new MediaType("application", "xml"))); assertTrue(converter.canWrite(Source.class, new MediaType("application", "soap+xml"))); assertTrue(converter.canWrite(Source.class, MediaType.ALL)); } @SmallTest public void testReadDOMSource() throws Exception { MockHttpInputMessage inputMessage = new MockHttpInputMessage(BODY.getBytes("UTF-8")); inputMessage.getHeaders().setContentType(new MediaType("application", "xml")); DOMSource result = (DOMSource) converter.read(DOMSource.class, inputMessage); Document document = (Document) result.getNode(); assertEquals("Invalid result", "root", document.getDocumentElement().getLocalName()); } @MediumTest public void readDOMSourceExternal() throws Exception { MockHttpInputMessage inputMessage = new MockHttpInputMessage(bodyExternal.getBytes("UTF-8")); inputMessage.getHeaders().setContentType(new MediaType("application", "xml")); DOMSource result = (DOMSource) converter.read(DOMSource.class, inputMessage); Document document = (Document) result.getNode(); assertEquals("Invalid result", "root", document.getDocumentElement().getLocalName()); assertNotEqual("Invalid result", "Foo Bar", document.getDocumentElement().getTextContent()); } @SmallTest public void testReadSAXSource() throws Exception { MockHttpInputMessage inputMessage = new MockHttpInputMessage(BODY.getBytes("UTF-8")); inputMessage.getHeaders().setContentType(new MediaType("application", "xml")); SAXSource result = (SAXSource) converter.read(SAXSource.class, inputMessage); InputSource inputSource = result.getInputSource(); String s = FileCopyUtils.copyToString(new InputStreamReader(inputSource.getByteStream())); assertXMLEqual("Invalid result", BODY, s); } @SmallTest public void readSAXSourceExternal() throws Exception { MockHttpInputMessage inputMessage = new MockHttpInputMessage(bodyExternal.getBytes("UTF-8")); inputMessage.getHeaders().setContentType(new MediaType("application", "xml")); SAXSource result = (SAXSource) converter.read(SAXSource.class, inputMessage); InputSource inputSource = result.getInputSource(); XMLReader reader = result.getXMLReader(); reader.setContentHandler(new DefaultHandler() { @Override public void characters(char[] ch, int start, int length) throws SAXException { String s = new String(ch, start, length); assertNotEqual("Invalid result", "Foo Bar", s); } }); reader.parse(inputSource); } @SmallTest public void testReadStreamSource() throws Exception { MockHttpInputMessage inputMessage = new MockHttpInputMessage(BODY.getBytes("UTF-8")); inputMessage.getHeaders().setContentType(new MediaType("application", "xml")); StreamSource result = (StreamSource) converter.read(StreamSource.class, inputMessage); String s = FileCopyUtils.copyToString(new InputStreamReader(result.getInputStream())); assertXMLEqual("Invalid result", BODY, s); } @SmallTest public void testReadSource() throws Exception { MockHttpInputMessage inputMessage = new MockHttpInputMessage(BODY.getBytes("UTF-8")); inputMessage.getHeaders().setContentType(new MediaType("application", "xml")); converter.read(Source.class, inputMessage); } @SmallTest public void testWriteDOMSource() throws Exception { DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); documentBuilderFactory.setNamespaceAware(true); Document document = documentBuilderFactory.newDocumentBuilder().newDocument(); Element rootElement = document.createElement("root"); document.appendChild(rootElement); rootElement.setTextContent("Hello World"); DOMSource domSource = new DOMSource(document); MockHttpOutputMessage outputMessage = new MockHttpOutputMessage(); converter.write(domSource, null, outputMessage); assertXMLEqual("Invalid result", "<root>Hello World</root>", outputMessage.getBodyAsString(Charset.forName("UTF-8"))); assertEquals("Invalid content-type", new MediaType("application", "xml"), outputMessage.getHeaders().getContentType()); assertEquals("Invalid content-length", outputMessage.getBodyAsBytes().length, outputMessage.getHeaders().getContentLength()); } @SmallTest public void testWriteSAXSource() throws Exception { String xml = "<root>Hello World</root>"; SAXSource saxSource = new SAXSource(new InputSource(new StringReader(xml))); MockHttpOutputMessage outputMessage = new MockHttpOutputMessage(); converter.write(saxSource, null, outputMessage); assertXMLEqual("Invalid result", "<root>Hello World</root>", outputMessage.getBodyAsString(Charset.forName("UTF-8"))); assertEquals("Invalid content-type", new MediaType("application", "xml"), outputMessage.getHeaders().getContentType()); } @SmallTest public void testWriteStreamSource() throws Exception { String xml = "<root>Hello World</root>"; StreamSource streamSource = new StreamSource(new StringReader(xml)); MockHttpOutputMessage outputMessage = new MockHttpOutputMessage(); converter.write(streamSource, null, outputMessage); assertXMLEqual("Invalid result", "<root>Hello World</root>", outputMessage.getBodyAsString(Charset.forName("UTF-8"))); assertEquals("Invalid content-type", new MediaType("application", "xml"), outputMessage.getHeaders().getContentType()); } }