From f5eb4cf69aae34ac7d9fe2384cfc02b643a96c6f Mon Sep 17 00:00:00 2001 From: Erik Brakkee Date: Tue, 1 Mar 2011 22:51:27 +0000 Subject: [PATCH] added namespace context class. --- .../wamblee/xml/SimpleNamespaceContext.java | 167 ++++++++++++++++++ .../xml/SimpleNamespaceContextTest.java | 125 +++++++++++++ 2 files changed, 292 insertions(+) create mode 100644 support/general/src/main/java/org/wamblee/xml/SimpleNamespaceContext.java create mode 100644 support/general/src/test/java/org/wamblee/xml/SimpleNamespaceContextTest.java diff --git a/support/general/src/main/java/org/wamblee/xml/SimpleNamespaceContext.java b/support/general/src/main/java/org/wamblee/xml/SimpleNamespaceContext.java new file mode 100644 index 00000000..7e8092a9 --- /dev/null +++ b/support/general/src/main/java/org/wamblee/xml/SimpleNamespaceContext.java @@ -0,0 +1,167 @@ +/* + * Copyright 2005-2011 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.wamblee.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; + +/** + * Implementation of {@link NamespaceContext} for binding namespace prefixes to + * namespaces. This class implements the full contract as defined by that interface. + * + * It provides a fluent interface style. In its simplest use, it can be constructed + * empty or with a single prefix using a constructor. In addition, the methods + * {@link #addPrefix(String, String)} and {@link #defaultNamespace(String)} can be used + * to add prefixes and to define the default namespace respectively. + * + * @author Erik Brakkee + */ +public class SimpleNamespaceContext implements NamespaceContext { + + private String defaultNs; + private Map prefixMap; + + /** + * Constructs an empty context without prefixes. + */ + public SimpleNamespaceContext() { + defaultNs = null; + prefixMap = new HashMap(); + } + + /** + * Constructs a context with a single prefix. + * @param aPrefix Prefix. + * @param aNamespace Namespace. + */ + public SimpleNamespaceContext(String aPrefix, String aNamespace) { + this(); + addPrefix(aPrefix, aNamespace); + } + + /** + * Constructs empty context (for use with static imports). + * @return Namespace context. + */ + public static SimpleNamespaceContext namespaceContext() { + return new SimpleNamespaceContext(); + } + + /** + * Constructs a context with a single prefix (for use with static imports). + * @param aPrefix Prefix + * @param aNamespace Namespace. + * @return + */ + public static SimpleNamespaceContext namespaceContext(String aPrefix, + String aNamespace) { + return new SimpleNamespaceContext(aPrefix, aNamespace); + } + + /** + * Sets the default namespace. + * @param aDefaultNs Default namespace. + * @return Current object for method chaining. + */ + public SimpleNamespaceContext defaultNamespace(String aDefaultNs) { + defaultNs = aDefaultNs; + return this; + } + + /** + * Adds a prefix. + * @param aPrefix Prefix to add. + * @param aNamespace Namespace to bind prefix to. + * @return Current object for method chaining. + */ + public SimpleNamespaceContext addPrefix(String aPrefix, String aNamespace) { + if (aPrefix == null) { + throw new IllegalArgumentException("prefix is null"); + } + if (aNamespace == null) { + throw new IllegalArgumentException("namespace is null"); + } + prefixMap.put(aPrefix, aNamespace); + return this; + } + + @Override + public String getNamespaceURI(String aPrefix) { + if (XMLConstants.DEFAULT_NS_PREFIX.equals(aPrefix)) { + if (defaultNs == null) { + return XMLConstants.NULL_NS_URI; + } + return defaultNs; + } + if (XMLConstants.XML_NS_PREFIX.equals(aPrefix)) { + return XMLConstants.XML_NS_URI; + } + if (XMLConstants.XMLNS_ATTRIBUTE.equals(aPrefix)) { + return XMLConstants.XMLNS_ATTRIBUTE_NS_URI; + } + String ns = prefixMap.get(aPrefix); + if (ns == null) { + return XMLConstants.NULL_NS_URI; + } + return ns; + } + + @Override + public String getPrefix(String aNamespaceURI) { + List prefixes = getPrefixList(aNamespaceURI); + if (prefixes.isEmpty()) { + return null; + } + return prefixes.get(0); + } + + @Override + public Iterator getPrefixes(String aNamespaceURI) { + return Collections.unmodifiableList(getPrefixList(aNamespaceURI)).iterator(); + } + + public List getPrefixList(String aNamespaceURI) { + List result = new ArrayList(); + + if ((aNamespaceURI == null && defaultNs == null) || + (defaultNs != null && defaultNs.equals(aNamespaceURI))) { + result.add(XMLConstants.DEFAULT_NS_PREFIX); + return result; // make sure not more prefixes added. + } + if (XMLConstants.XML_NS_URI.equals(aNamespaceURI)) { + result.add(XMLConstants.XML_NS_PREFIX); + return result; // make sure no more prefixes added. + } + if (XMLConstants.XMLNS_ATTRIBUTE_NS_URI.equals(aNamespaceURI)) { + result.add(XMLConstants.XMLNS_ATTRIBUTE); + return result; + } + for (Map.Entry entry: prefixMap.entrySet()) { + if (entry.getValue().equals(aNamespaceURI)) { + result.add(entry.getKey()); + } + } + return result; + } + +} diff --git a/support/general/src/test/java/org/wamblee/xml/SimpleNamespaceContextTest.java b/support/general/src/test/java/org/wamblee/xml/SimpleNamespaceContextTest.java new file mode 100644 index 00000000..26d8fddb --- /dev/null +++ b/support/general/src/test/java/org/wamblee/xml/SimpleNamespaceContextTest.java @@ -0,0 +1,125 @@ +/* + * Copyright 2005-2011 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.wamblee.xml; + +import static junit.framework.Assert.*; +import static org.wamblee.xml.SimpleNamespaceContext.*; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Iterator; +import java.util.List; + +import javax.xml.XMLConstants; +import javax.xml.namespace.NamespaceContext; + +import org.junit.Test; + +public class SimpleNamespaceContextTest { + + private List toList(Iterator aIterator) { + List result = new ArrayList(); + while (aIterator.hasNext()) { + result.add((String) aIterator.next()); + } + return result; + } + + @Test + public void testDefaultContextNoNamespace() { + NamespaceContext context = namespaceContext(); + assertEquals(XMLConstants.NULL_NS_URI, + context.getNamespaceURI(XMLConstants.DEFAULT_NS_PREFIX)); + assertEquals(XMLConstants.NULL_NS_URI, context.getNamespaceURI("xxx")); + assertEquals(XMLConstants.XML_NS_URI, + context.getNamespaceURI(XMLConstants.XML_NS_PREFIX)); + assertEquals(XMLConstants.XMLNS_ATTRIBUTE_NS_URI, + context.getNamespaceURI(XMLConstants.XMLNS_ATTRIBUTE)); + + assertNull(context.getPrefix(XMLConstants.DEFAULT_NS_PREFIX)); + assertFalse(context.getPrefixes(XMLConstants.DEFAULT_NS_PREFIX) + .hasNext()); + + assertEquals(XMLConstants.XML_NS_PREFIX, + context.getPrefix(XMLConstants.XML_NS_URI)); + assertEquals(Arrays.asList(XMLConstants.XML_NS_PREFIX), + toList(context.getPrefixes(XMLConstants.XML_NS_URI))); + + assertEquals(XMLConstants.XMLNS_ATTRIBUTE, + context.getPrefix(XMLConstants.XMLNS_ATTRIBUTE_NS_URI)); + assertEquals(Arrays.asList(XMLConstants.XMLNS_ATTRIBUTE), + toList(context.getPrefixes(XMLConstants.XMLNS_ATTRIBUTE_NS_URI))); + + assertNull(context.getPrefix("http://something.com")); + assertFalse(context.getPrefixes("http://something.com").hasNext()); + } + + @Test + public void testSinglePrefix() { + NamespaceContext context = namespaceContext("aaa", "http://example.com"); + singlePrefixAssertions(context); + } + + private void singlePrefixAssertions(NamespaceContext context) { + assertEquals(XMLConstants.NULL_NS_URI, + context.getNamespaceURI(XMLConstants.DEFAULT_NS_PREFIX)); + assertEquals(XMLConstants.NULL_NS_URI, context.getNamespaceURI("xxx")); + assertEquals("http://example.com", context.getNamespaceURI("aaa")); + assertEquals(XMLConstants.XML_NS_URI, + context.getNamespaceURI(XMLConstants.XML_NS_PREFIX)); + assertEquals(XMLConstants.XMLNS_ATTRIBUTE_NS_URI, + context.getNamespaceURI(XMLConstants.XMLNS_ATTRIBUTE)); + + assertNull(context.getPrefix(XMLConstants.DEFAULT_NS_PREFIX)); + assertEquals(XMLConstants.XML_NS_PREFIX, + context.getPrefix(XMLConstants.XML_NS_URI)); + assertEquals(XMLConstants.XMLNS_ATTRIBUTE, + context.getPrefix(XMLConstants.XMLNS_ATTRIBUTE_NS_URI)); + assertNull(context.getPrefix("http://something.com")); + assertEquals("aaa", context.getPrefix("http://example.com")); + } + + @Test + public void testMultiplePrefixes() { + NamespaceContext context = namespaceContext().addPrefix("aaa", + "http://example.com").addPrefix("bbb", "http://example.com").addPrefix("ccc", "http://example2.com").addPrefix("ddd", + XMLConstants.XML_NS_URI).addPrefix("eee", XMLConstants.XMLNS_ATTRIBUTE_NS_URI); + singlePrefixAssertions(context); + + List prefixes = toList(context + .getPrefixes("http://example.com")); + assertEquals(2, prefixes.size()); + assertTrue(prefixes.contains("aaa")); + assertTrue(prefixes.contains("bbb")); + + prefixes = toList(context + .getPrefixes("http://example2.com")); + assertEquals(1, prefixes.size()); + assertTrue(prefixes.contains("ccc")); + + // standard xml and xmlns namespaces are special. Only the standard prefixes should be returned for these. + + prefixes = toList(context + .getPrefixes(XMLConstants.XML_NS_URI)); + assertEquals(1, prefixes.size()); + assertTrue(prefixes.contains(XMLConstants.XML_NS_PREFIX)); + + prefixes = toList(context + .getPrefixes(XMLConstants.XMLNS_ATTRIBUTE_NS_URI)); + assertEquals(1, prefixes.size()); + assertTrue(prefixes.contains(XMLConstants.XMLNS_ATTRIBUTE)); + } +} -- 2.31.1