/* * Copyright 2005-2012 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.ws.soap.axiom; import static org.custommonkey.xmlunit.XMLAssert.*; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.StringReader; import java.util.Iterator; import javax.xml.XMLConstants; import javax.xml.namespace.NamespaceContext; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.sax.SAXResult; import org.apache.axiom.om.OMAbstractFactory; import org.apache.axiom.om.OMDocument; import org.apache.axiom.om.OMElement; import org.apache.axiom.om.OMFactory; import org.apache.axiom.om.OMNamespace; import org.junit.Before; import org.junit.Test; import org.w3c.dom.Document; import org.xml.sax.InputSource; import org.xml.sax.XMLReader; import org.xml.sax.helpers.XMLReaderFactory; public class AxiomHandlerTest { private static final String XML_1 = "<?xml version='1.0' encoding='UTF-8'?>" + "<?pi content?>" + "<root xmlns='namespace'>" + "<prefix:child xmlns:prefix='namespace2' xmlns:prefix2='namespace3' prefix2:attr='value'>content</prefix:child>" + "</root>"; private static final String XML_2_EXPECTED = "<?xml version='1.0' encoding='UTF-8'?>" + "<root xmlns='namespace'>" + "<child xmlns='namespace2' />" + "</root>"; private static final String XML_2_SNIPPET = "<?xml version='1.0' encoding='UTF-8'?>" + "<child xmlns='namespace2' />"; private static final String XML_3_ENTITY = "<predefined-entity-reference><>&"'</predefined-entity-reference>"; private static final String XML_4_SNIPPET = "<?xml version='1.0' encoding='UTF-8'?>" + "<child xmlns='namespace1' />"; private static final String XML_5_SNIPPET = "<?xml version='1.0' encoding='UTF-8'?>" + "<x:child xmlns:x='namespace1' />"; private static final String XML_6_SNIPPET = "<?xml version='1.0' encoding='UTF-8'?>" + "<parent xmlns='parent-namespace'><c:first-sibling xmlns:c='child-namespace' /><second-sibling /></parent>"; private AxiomHandler handler; private OMDocument result; private XMLReader xmlReader; private OMFactory factory; @Before public void setUp() throws Exception { factory = OMAbstractFactory.getOMFactory(); result = factory.createOMDocument(); xmlReader = XMLReaderFactory.createXMLReader(); } @Test public void testContentHandlerDocumentNamespacePrefixes() throws Exception { xmlReader.setFeature("http://xml.org/sax/features/namespace-prefixes", true); handler = new AxiomHandler(result, factory); xmlReader.setContentHandler(handler); xmlReader.setProperty("http://xml.org/sax/properties/lexical-handler", handler); xmlReader.parse(new InputSource(new StringReader(XML_1))); ByteArrayOutputStream bos = new ByteArrayOutputStream(); result.serialize(bos); assertXMLEqual("Invalid result", XML_1, bos.toString("UTF-8")); } @Test public void testContentHandlerDocumentNoNamespacePrefixes() throws Exception { xmlReader.setFeature("http://xml.org/sax/features/namespace-prefixes", false); handler = new AxiomHandler(result, factory); xmlReader.setContentHandler(handler); xmlReader.parse(new InputSource(new StringReader(XML_1))); ByteArrayOutputStream bos = new ByteArrayOutputStream(); result.serialize(bos); assertXMLEqual("Invalid result", XML_1, bos.toString("UTF-8")); } @Test public void testContentHandlerElement() throws Exception { OMNamespace namespace = factory.createOMNamespace("namespace", ""); OMElement rootElement = factory.createOMElement("root", namespace, result); handler = new AxiomHandler(rootElement, factory); xmlReader.setContentHandler(handler); xmlReader.parse(new InputSource(new StringReader(XML_2_SNIPPET))); ByteArrayOutputStream bos = new ByteArrayOutputStream(); result.serialize(bos); assertXMLEqual("Invalid result", XML_2_EXPECTED, bos.toString("UTF-8")); } @Test public void testContentHandlerElementWithSamePrefixAndDifferentNamespace() throws Exception { OMNamespace namespace = factory.createOMNamespace("namespace1", ""); OMElement rootElement = factory.createOMElement("root", namespace, result); handler = new AxiomHandler(rootElement, factory); xmlReader.setContentHandler(handler); xmlReader.parse(new InputSource(new StringReader(XML_2_SNIPPET))); Iterator<?> it = result.getOMDocumentElement().getChildrenWithLocalName("child"); assertTrue(it.hasNext()); OMElement child = (OMElement) it.next(); assertEquals("", child.getQName().getPrefix()); assertEquals("namespace2", child.getQName().getNamespaceURI()); } @Test public void testContentHandlerElementWithSameNamespacesAndPrefix() throws Exception { OMNamespace namespace = factory.createOMNamespace("namespace1", ""); OMElement rootElement = factory.createOMElement("root", namespace, result); handler = new AxiomHandler(rootElement, factory); xmlReader.setContentHandler(handler); xmlReader.parse(new InputSource(new StringReader(XML_4_SNIPPET))); Iterator<?> it = result.getOMDocumentElement().getChildrenWithLocalName("child"); assertTrue(it.hasNext()); OMElement child = (OMElement) it.next(); assertEquals("", child.getQName().getPrefix()); assertEquals("namespace1", child.getQName().getNamespaceURI()); } @Test public void testContentHandlerElementWithSameNamespacesAndDifferentPrefix() throws Exception { OMNamespace namespace = factory.createOMNamespace("namespace1", ""); OMElement rootElement = factory.createOMElement("root", namespace, result); handler = new AxiomHandler(rootElement, factory); xmlReader.setContentHandler(handler); xmlReader.parse(new InputSource(new StringReader(XML_5_SNIPPET))); Iterator<?> it = result.getOMDocumentElement().getChildrenWithLocalName("child"); assertTrue(it.hasNext()); OMElement child = (OMElement) it.next(); assertEquals("x", child.getQName().getPrefix()); assertEquals("namespace1", child.getQName().getNamespaceURI()); } @Test public void testContentHandlerSiblingPrefixMapping() throws Exception { handler = new AxiomHandler(result, factory); xmlReader.setContentHandler(handler); xmlReader.parse(new InputSource(new StringReader(XML_6_SNIPPET))); Iterator<?> it = result.getOMDocumentElement().getChildren(); assertTrue(it.hasNext()); OMElement firstSibling = (OMElement) it.next(); assertEquals("first-sibling", firstSibling.getLocalName()); Iterator<?> firstSiblingNsIt = firstSibling.getAllDeclaredNamespaces(); // Verify first sibling has a single namespace declaration (with child-namespace URI) assertTrue(firstSiblingNsIt.hasNext()); assertEquals("child-namespace", ((OMNamespace) firstSiblingNsIt.next()).getNamespaceURI()); assertFalse(firstSiblingNsIt.hasNext()); assertTrue(it.hasNext()); OMElement secondSibling = (OMElement) it.next(); // Verify second sibling has no namespace declarations as it's covered by <parent /> // This also verifies the child-namespace from the <first-sibling /> element isn't copied to second-sibling assertEquals("second-sibling", secondSibling.getLocalName()); Iterator<?> secondSiblingNsIt = secondSibling.getAllDeclaredNamespaces(); assertFalse(secondSiblingNsIt.hasNext()); } @Test public void testContentHandlerPredefinedEntityReference() throws Exception { handler = new AxiomHandler(result, factory); xmlReader.setContentHandler(handler); xmlReader.setProperty("http://xml.org/sax/properties/lexical-handler", handler); xmlReader.parse(new InputSource(new StringReader(XML_3_ENTITY))); ByteArrayOutputStream bos = new ByteArrayOutputStream(); result.serialize(bos); assertXMLEqual("Invalid result", XML_3_ENTITY, bos.toString("UTF-8")); } @Test public void testTransformDom() throws Exception { DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); documentBuilderFactory.setNamespaceAware(true); DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder(); String XML = "<root xmlns=\"http://www.springframework.org/spring-ws\" xmlns:attr=\"http://www.springframework.org/spring-ws/attr\" attr:attribute=\"value\">" + "<prefix:child xmlns:prefix=\"http://www.springframework.org/spring-ws/child\"/>" + "</root>"; Document document = documentBuilder.parse(new ByteArrayInputStream(XML.getBytes("UTF-8"))); DOMSource domSource = new DOMSource(document); handler = new AxiomHandler(result, factory); Transformer transformer = TransformerFactory.newInstance().newTransformer(); SAXResult saxResult = new SAXResult(handler); transformer.transform(domSource, saxResult); OMElement root = result.getOMDocumentElement(); assertEquals(2, getNamespaceCount(root)); NamespaceContext namespaceContext = root.getNamespaceContext(false); assertEquals("http://www.springframework.org/spring-ws", namespaceContext.getNamespaceURI(XMLConstants.DEFAULT_NS_PREFIX)); assertEquals("http://www.springframework.org/spring-ws/attr", namespaceContext.getNamespaceURI("attr")); OMElement child = root.getFirstElement(); assertEquals(1, getNamespaceCount(child)); namespaceContext = child.getNamespaceContext(false); assertEquals("http://www.springframework.org/spring-ws", namespaceContext.getNamespaceURI(XMLConstants.DEFAULT_NS_PREFIX)); assertEquals("http://www.springframework.org/spring-ws/child", namespaceContext.getNamespaceURI("prefix")); } private int getNamespaceCount(OMElement element) { int i = 0; Iterator<?> namespaces = element.getAllDeclaredNamespaces(); while (namespaces.hasNext()) { namespaces.next(); i++; } return i; } }