From 2945253d20c07a540bb16273e4005d1698abe8b8 Mon Sep 17 00:00:00 2001 From: Arjen Poutsma Date: Tue, 6 Jan 2009 17:07:59 +0000 Subject: [PATCH] Added SimpleNamespaceContext --- .../util/xml/SimpleNamespaceContext.java | 159 ++++++++++++++++++ .../util/xml/SimpleNamespaceContextTests.java | 121 +++++++++++++ 2 files changed, 280 insertions(+) create mode 100644 org.springframework.core/src/main/java/org/springframework/util/xml/SimpleNamespaceContext.java create mode 100644 org.springframework.core/src/test/java/org/springframework/util/xml/SimpleNamespaceContextTests.java diff --git a/org.springframework.core/src/main/java/org/springframework/util/xml/SimpleNamespaceContext.java b/org.springframework.core/src/main/java/org/springframework/util/xml/SimpleNamespaceContext.java new file mode 100644 index 00000000000..4e8d6cbee76 --- /dev/null +++ b/org.springframework.core/src/main/java/org/springframework/util/xml/SimpleNamespaceContext.java @@ -0,0 +1,159 @@ +/* + * Copyright 2002-2009 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.util.xml; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import javax.xml.XMLConstants; +import javax.xml.namespace.NamespaceContext; + +import org.springframework.util.Assert; + +/** + * Simple javax.xml.namespace.NamespaceContext implementation. Follows the standard + * NamespaceContext contract, and is loadable via a java.util.Map or + * java.util.Properties object + * + * @author Arjen Poutsma + * @since 3.0 + */ +public class SimpleNamespaceContext implements NamespaceContext { + + private Map prefixToNamespaceUri = new HashMap(); + + private Map> namespaceUriToPrefixes = new HashMap>(); + + private String defaultNamespaceUri = ""; + + public String getNamespaceURI(String prefix) { + Assert.notNull(prefix, "prefix is null"); + if (XMLConstants.XML_NS_PREFIX.equals(prefix)) { + return XMLConstants.XML_NS_URI; + } + else if (XMLConstants.XMLNS_ATTRIBUTE.equals(prefix)) { + return XMLConstants.XMLNS_ATTRIBUTE_NS_URI; + } + else if (XMLConstants.DEFAULT_NS_PREFIX.equals(prefix)) { + return defaultNamespaceUri; + } + else if (prefixToNamespaceUri.containsKey(prefix)) { + return prefixToNamespaceUri.get(prefix); + } + return ""; + } + + public String getPrefix(String namespaceUri) { + List prefixes = getPrefixesInternal(namespaceUri); + return prefixes.isEmpty() ? null : (String) prefixes.get(0); + } + + public Iterator getPrefixes(String namespaceUri) { + return getPrefixesInternal(namespaceUri).iterator(); + } + + /** + * Sets the bindings for this namespace context. The supplied map must consist of string key value pairs. + * + * @param bindings the bindings + */ + public void setBindings(Map bindings) { + for (Map.Entry entry : bindings.entrySet()) { + bindNamespaceUri(entry.getKey(), entry.getValue()); + } + } + + /** + * Binds the given namespace as default namespace. + * + * @param namespaceUri the namespace uri + */ + public void bindDefaultNamespaceUri(String namespaceUri) { + bindNamespaceUri(XMLConstants.DEFAULT_NS_PREFIX, namespaceUri); + } + + /** + * Binds the given prefix to the given namespace. + * + * @param prefix the namespace prefix + * @param namespaceUri the namespace uri + */ + public void bindNamespaceUri(String prefix, String namespaceUri) { + Assert.notNull(prefix, "No prefix given"); + Assert.notNull(namespaceUri, "No namespaceUri given"); + if (XMLConstants.DEFAULT_NS_PREFIX.equals(prefix)) { + defaultNamespaceUri = namespaceUri; + } + else { + prefixToNamespaceUri.put(prefix, namespaceUri); + getPrefixesInternal(namespaceUri).add(prefix); + } + } + + /** Removes all declared prefixes. */ + public void clear() { + prefixToNamespaceUri.clear(); + } + + /** + * Returns all declared prefixes. + * + * @return the declared prefixes + */ + public Iterator getBoundPrefixes() { + return prefixToNamespaceUri.keySet().iterator(); + } + + private List getPrefixesInternal(String namespaceUri) { + if (defaultNamespaceUri.equals(namespaceUri)) { + return Collections.singletonList(XMLConstants.DEFAULT_NS_PREFIX); + } + else if (XMLConstants.XML_NS_URI.equals(namespaceUri)) { + return Collections.singletonList(XMLConstants.XML_NS_PREFIX); + } + else if (XMLConstants.XMLNS_ATTRIBUTE_NS_URI.equals(namespaceUri)) { + return Collections.singletonList(XMLConstants.XMLNS_ATTRIBUTE); + } + else { + List list = namespaceUriToPrefixes.get(namespaceUri); + if (list == null) { + list = new ArrayList(); + namespaceUriToPrefixes.put(namespaceUri, list); + } + return list; + } + } + + /** + * Removes the given prefix from this context. + * + * @param prefix the prefix to be removed + */ + public void removeBinding(String prefix) { + if (XMLConstants.DEFAULT_NS_PREFIX.equals(prefix)) { + defaultNamespaceUri = ""; + } + else { + String namespaceUri = prefixToNamespaceUri.remove(prefix); + List prefixes = getPrefixesInternal(namespaceUri); + prefixes.remove(prefix); + } + } +} diff --git a/org.springframework.core/src/test/java/org/springframework/util/xml/SimpleNamespaceContextTests.java b/org.springframework.core/src/test/java/org/springframework/util/xml/SimpleNamespaceContextTests.java new file mode 100644 index 00000000000..64f7de88231 --- /dev/null +++ b/org.springframework.core/src/test/java/org/springframework/util/xml/SimpleNamespaceContextTests.java @@ -0,0 +1,121 @@ +/* + * Copyright 2002-2009 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.util.xml; + +import java.util.Collections; +import java.util.Iterator; +import javax.xml.XMLConstants; + +import static org.junit.Assert.*; +import org.junit.Before; +import org.junit.Test; + +public class SimpleNamespaceContextTests { + + private SimpleNamespaceContext context; + + @Before + public void createContext() throws Exception { + context = new SimpleNamespaceContext(); + context.bindNamespaceUri("prefix", "namespaceURI"); + } + + @Test + public void getNamespaceURI() { + assertEquals("Invalid namespaceURI for default namespace", "", + context.getNamespaceURI(XMLConstants.DEFAULT_NS_PREFIX)); + String defaultNamespaceUri = "defaultNamespace"; + context.bindNamespaceUri(XMLConstants.DEFAULT_NS_PREFIX, defaultNamespaceUri); + assertEquals("Invalid namespaceURI for default namespace", defaultNamespaceUri, + context.getNamespaceURI(XMLConstants.DEFAULT_NS_PREFIX)); + assertEquals("Invalid namespaceURI for bound prefix", "namespaceURI", context.getNamespaceURI("prefix")); + assertEquals("Invalid namespaceURI for unbound prefix", "", context.getNamespaceURI("unbound")); + assertEquals("Invalid namespaceURI for namespace prefix", XMLConstants.XML_NS_URI, + context.getNamespaceURI(XMLConstants.XML_NS_PREFIX)); + assertEquals("Invalid namespaceURI for attribute prefix", XMLConstants.XMLNS_ATTRIBUTE_NS_URI, + context.getNamespaceURI(XMLConstants.XMLNS_ATTRIBUTE)); + + } + + @Test + public void getPrefix() { + assertEquals("Invalid prefix for default namespace", XMLConstants.DEFAULT_NS_PREFIX, context.getPrefix("")); + assertEquals("Invalid prefix for bound namespace", "prefix", context.getPrefix("namespaceURI")); + assertNull("Invalid prefix for unbound namespace", context.getPrefix("unbound")); + assertEquals("Invalid prefix for namespace", XMLConstants.XML_NS_PREFIX, + context.getPrefix(XMLConstants.XML_NS_URI)); + assertEquals("Invalid prefix for attribute namespace", XMLConstants.XMLNS_ATTRIBUTE, + context.getPrefix(XMLConstants.XMLNS_ATTRIBUTE_NS_URI)); + } + + @Test + public void getPrefixes() { + assertPrefixes("", XMLConstants.DEFAULT_NS_PREFIX); + assertPrefixes("namespaceURI", "prefix"); + assertFalse("Invalid prefix for unbound namespace", context.getPrefixes("unbound").hasNext()); + assertPrefixes(XMLConstants.XML_NS_URI, XMLConstants.XML_NS_PREFIX); + assertPrefixes(XMLConstants.XMLNS_ATTRIBUTE_NS_URI, XMLConstants.XMLNS_ATTRIBUTE); + } + + @Test + public void multiplePrefixes() { + context.bindNamespaceUri("prefix1", "namespace"); + context.bindNamespaceUri("prefix2", "namespace"); + Iterator iterator = context.getPrefixes("namespace"); + assertNotNull("getPrefixes returns null", iterator); + assertTrue("iterator is empty", iterator.hasNext()); + String result = (String) iterator.next(); + assertTrue("Invalid prefix", result.equals("prefix1") || result.equals("prefix2")); + assertTrue("iterator is empty", iterator.hasNext()); + result = (String) iterator.next(); + assertTrue("Invalid prefix", result.equals("prefix1") || result.equals("prefix2")); + assertFalse("iterator contains more than two values", iterator.hasNext()); + } + + private void assertPrefixes(String namespaceUri, String prefix) { + Iterator iterator = context.getPrefixes(namespaceUri); + assertNotNull("getPrefixes returns null", iterator); + assertTrue("iterator is empty", iterator.hasNext()); + String result = (String) iterator.next(); + assertEquals("Invalid prefix", prefix, result); + assertFalse("iterator contains multiple values", iterator.hasNext()); + } + + @Test + public void getBoundPrefixes() throws Exception { + Iterator iterator = context.getBoundPrefixes(); + assertNotNull("getPrefixes returns null", iterator); + assertTrue("iterator is empty", iterator.hasNext()); + String result = (String) iterator.next(); + assertEquals("Invalid prefix", "prefix", result); + assertFalse("iterator contains multiple values", iterator.hasNext()); + } + + @Test + public void setBindings() throws Exception { + context.setBindings(Collections.singletonMap("prefix", "namespace")); + assertEquals("Invalid namespace uri", "namespace", context.getNamespaceURI("prefix")); + } + + @Test + public void removeBinding() throws Exception { + context.removeBinding("prefix"); + assertNull("Invalid prefix for unbound namespace", context.getPrefix("prefix")); + + + } + +}