/* * Copyright (c) 2010-2013 Evolveum * * 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.evolveum.midpoint.util; import java.util.Map; import org.testng.annotations.Test; import org.testng.AssertJUnit; import static org.testng.AssertJUnit.*; import static javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI; import org.w3c.dom.Document; import org.w3c.dom.Element; import javax.xml.XMLConstants; import javax.xml.namespace.QName; /** * @author Radovan Semancik * */ public class DOMUtilTest { private static final String QNAME_IN_NS = "http://foo.com/bar"; private static final String QNAME_IN_LOCAL = "baz"; private static final String ELEMENT_NS = "http://foo.com/barbar"; private static final String ELEMENT_LOCAL = "el"; private static final String DEFAULT_NS = "http://foo.com/default"; private static final String ELEMENT_TOP_LOCAL = "top"; private static final String FOO_NS = "http://foo.com/foo"; private static final QName QNAME_ATTR_QNAME = new QName(ELEMENT_NS, "qname"); private static final String XSD_TYPE_FILENAME = "src/test/resources/domutil/xsi-type.xml"; private static final String QNAMES_FILENAME = "src/test/resources/domutil/qnames.xml"; private static final String FIX_NAMESPACE_FILENAME = "src/test/resources/domutil/fix-namespace.xml"; public static final String NS_W3C_XML_SCHEMA_PREFIX = "xsd"; public static final QName XSD_SCHEMA_ELEMENT = new QName(W3C_XML_SCHEMA_NS_URI, "schema", NS_W3C_XML_SCHEMA_PREFIX); public static final QName XSD_STRING = new QName(W3C_XML_SCHEMA_NS_URI, "string", NS_W3C_XML_SCHEMA_PREFIX); public static final QName XSD_INTEGER = new QName(W3C_XML_SCHEMA_NS_URI, "integer", NS_W3C_XML_SCHEMA_PREFIX); private static final int MAX_GENERATE_QNAME_ITERATIONS = 200; public DOMUtilTest() { } @Test public void testQNameRoundTrip() { System.out.println("===[ testQNameRoundTrip ]==="); // GIVEN Document doc = DOMUtil.getDocument(); QName in = new QName(QNAME_IN_NS, QNAME_IN_LOCAL, "x"); Element e = doc.createElementNS(ELEMENT_NS, ELEMENT_LOCAL); // WHEN DOMUtil.setQNameValue(e, in); // THEN System.out.println(DOMUtil.serializeDOMToString(e)); String content = e.getTextContent(); String[] split = content.split(":"); // Default namespace should not be used unless explicitly matches existing declaration // therefore there should be a prefix AssertJUnit.assertEquals(2,split.length); String prefix = split[0]; String localPart = split[1]; AssertJUnit.assertFalse(prefix.isEmpty()); String namespaceURI = e.lookupNamespaceURI(prefix); AssertJUnit.assertEquals(QNAME_IN_NS, namespaceURI); AssertJUnit.assertEquals(QNAME_IN_LOCAL, localPart); // WHEN QName out = DOMUtil.getQNameValue(e); // THEN AssertJUnit.assertEquals(in, out); } @Test public void testQNameDefaultNamespace1() { System.out.println("===[ testQNameDefaultNamespace1 ]==="); // GIVEN Document doc = DOMUtil.getDocument(); QName in = new QName(DEFAULT_NS, QNAME_IN_LOCAL); Element topElement = doc.createElementNS(DEFAULT_NS, ELEMENT_TOP_LOCAL); // Make sure there is a default ns declaration DOMUtil.setNamespaceDeclaration(topElement,"",DEFAULT_NS); DOMUtil.setNamespaceDeclaration(topElement,"e",ELEMENT_NS); doc.appendChild(topElement); Element e = doc.createElementNS(ELEMENT_NS, ELEMENT_LOCAL); e.setPrefix("e"); e.setTextContent("foofoo"); topElement.appendChild(e); System.out.println(DOMUtil.serializeDOMToString(topElement)); // WHEN DOMUtil.setQNameValue(e, in); // THEN System.out.println(DOMUtil.serializeDOMToString(topElement)); String content = e.getTextContent(); // Default namespace should NOT be reused AssertJUnit.assertTrue(content.contains(":")); AssertJUnit.assertTrue(content.contains(":" + QNAME_IN_LOCAL)); } @Test public void testQNameDefaultNamespace2() { System.out.println("===[ testQNameDefaultNamespace2 ]==="); // GIVEN Document doc = DOMUtil.getDocument(); QName in = new QName(DEFAULT_NS, QNAME_IN_LOCAL, "f"); // the difference w.r.t. testQNameDefaultNamespace1 Element topElement = doc.createElementNS(DEFAULT_NS, ELEMENT_TOP_LOCAL); // Make sure there is a default ns declaration DOMUtil.setNamespaceDeclaration(topElement,"",DEFAULT_NS); DOMUtil.setNamespaceDeclaration(topElement,"e",ELEMENT_NS); doc.appendChild(topElement); Element e = doc.createElementNS(ELEMENT_NS, ELEMENT_LOCAL); e.setPrefix("e"); e.setTextContent("foofoo"); topElement.appendChild(e); System.out.println(DOMUtil.serializeDOMToString(topElement)); // WHEN DOMUtil.setQNameValue(e, in); // THEN System.out.println(DOMUtil.serializeDOMToString(topElement)); String content = e.getTextContent(); // Default namespace should NOT be reused AssertJUnit.assertEquals("f:"+QNAME_IN_LOCAL, content); } @Test public void testQNameNoNamespace() { System.out.println("===[ testQNameNoNamespace ]==="); // GIVEN Document doc = DOMUtil.getDocument(); QName in = new QName(XMLConstants.NULL_NS_URI, QNAME_IN_LOCAL); // no namespace Element topElement = doc.createElementNS(DEFAULT_NS, ELEMENT_TOP_LOCAL); // Make sure there is a default ns declaration DOMUtil.setNamespaceDeclaration(topElement,"",DEFAULT_NS); DOMUtil.setNamespaceDeclaration(topElement,"e",ELEMENT_NS); doc.appendChild(topElement); Element e = doc.createElementNS(ELEMENT_NS, ELEMENT_LOCAL); e.setPrefix("e"); e.setTextContent("foofoo"); topElement.appendChild(e); System.out.println(DOMUtil.serializeDOMToString(topElement)); // WHEN DOMUtil.setQNameValue(e, in); // THEN System.out.println(DOMUtil.serializeDOMToString(topElement)); String content = e.getTextContent(); // There should be no namespace prefix AssertJUnit.assertEquals(QNAME_IN_LOCAL, content); } @Test public void testXsiType() { System.out.println("===[ testXsiType ]==="); // GIVEN Document doc = DOMUtil.parseFile(XSD_TYPE_FILENAME); Element root = DOMUtil.getFirstChildElement(doc); Element el1 = DOMUtil.getFirstChildElement(root); // WHEN QName xsiType = DOMUtil.resolveXsiType(el1); // THEN assertNotNull(xsiType); AssertJUnit.assertTrue(XSD_INTEGER.equals(xsiType)); AssertJUnit.assertTrue("Failed to detect xsi:type", DOMUtil.hasXsiType(el1)); } @Test public void testQNameMethods() { System.out.println("===[ testQNameMethods ]==="); Document doc = DOMUtil.parseFile(QNAMES_FILENAME); Element root = DOMUtil.getFirstChildElement(doc); Element el1 = (Element) root.getElementsByTagNameNS(DEFAULT_NS, "el1").item(0); QName refAttrValue = DOMUtil.getQNameAttribute(el1, "ref"); assertEquals("getQNameAttribute failed",new QName(FOO_NS,"bar"),refAttrValue); Element el2 = (Element) root.getElementsByTagNameNS(DEFAULT_NS, "el2").item(0); QName el2Value = DOMUtil.getQNameValue(el2); assertEquals("getQNameValue failed",new QName(FOO_NS,"BAR"),el2Value); } @Test public void testFixNamespaceDeclarations() { System.out.println("===[ testFixNamespaceDeclarations ]==="); Document doc = DOMUtil.parseFile(FIX_NAMESPACE_FILENAME); System.out.println("Original XML:"); System.out.println(DOMUtil.serializeDOMToString(doc)); Element root = DOMUtil.getFirstChildElement(doc); Element target = (Element) root.getElementsByTagNameNS(DEFAULT_NS, "target").item(0); DOMUtil.fixNamespaceDeclarations(target); System.out.println("Fixed namespaces (doc):"); System.out.println(DOMUtil.serializeDOMToString(doc)); System.out.println("Fixed namespaces (target):"); System.out.println(DOMUtil.serializeDOMToString(target)); Map<String, String> decls = DOMUtil.getNamespaceDeclarations(target); assertEquals("bar decl", "http://foo.com/bar", decls.get("bar")); assertEquals("foo decl", "http://foo.com/foo", decls.get("foo")); assertEquals("default decl", "http://foo.com/default", decls.get(null)); } @Test public void testGeneratedQNamePrefixes() { System.out.println("===[ testGeneratedQNamePrefixes ]==="); // GIVEN Document doc = DOMUtil.getDocument(); Element topElement = doc.createElementNS(ELEMENT_NS, ELEMENT_TOP_LOCAL); doc.appendChild(topElement); System.out.println("Before"); System.out.println(DOMUtil.serializeDOMToString(topElement)); // WHEN for(int i=0; i<MAX_GENERATE_QNAME_ITERATIONS; i++) { Element el = DOMUtil.createElement(doc, new QName(ELEMENT_NS, ELEMENT_LOCAL+i), topElement, topElement); topElement.appendChild(el); String namespace = "http://exaple.com/gen/"+i; QName qNameValue = new QName(namespace, "val"+i); DOMUtil.setQNameAttribute(el, QNAME_ATTR_QNAME, qNameValue, topElement); QName qNameValueAfter = DOMUtil.getQNameAttribute(el, QNAME_ATTR_QNAME); assertEquals("Bada boom! wrong element QName in iteration "+i, qNameValue, qNameValueAfter); } // THEN System.out.println("After"); System.out.println(DOMUtil.serializeDOMToString(topElement)); for(int i=0; i<MAX_GENERATE_QNAME_ITERATIONS; i++) { Element el = DOMUtil.getChildElement(topElement, ELEMENT_LOCAL+i); String namespace = "http://exaple.com/gen/"+i; QName qNameValue = new QName(namespace, "val"+i); QName qNameValueAfter = DOMUtil.getQNameAttribute(el, QNAME_ATTR_QNAME); assertEquals("BIG bada boom! wrong element QName in iteration "+i, qNameValue, qNameValueAfter); } } }