Author: rhauch
Date: 2008-10-30 13:34:02 -0400 (Thu, 30 Oct 2008)
New Revision: 603
Added:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/properties/basic/LocalNamespaceRegistry.java
trunk/dna-graph/src/test/java/org/jboss/dna/graph/properties/basic/BasicNamespaceTest.java
trunk/dna-graph/src/test/java/org/jboss/dna/graph/properties/basic/LocalNamespaceRegistryTest.java
trunk/dna-graph/src/test/resources/xmlHandler/docWithNamespacesWithoutDefault.xml
Modified:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/connectors/BasicExecutionContext.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/properties/NamespaceRegistry.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/xml/XmlHandler.java
trunk/dna-graph/src/test/java/org/jboss/dna/graph/xml/XmlHandlerTest.java
Log:
DNA-242 - Change the XML importer code to no longer use XmlSequencer
http://jira.jboss.com/jira/browse/DNA-242
Enhanced the XmlHandler to provide a local NamespaceRegistry that mirrors the XML
namespaces in the document, and various factories in the XmlHandler that use this local
namespace registry. The benefit is that XmlHandler (and subclasses) can simply just use
the factories to process any names that use the XML namespace prefixes.
Modified:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/connectors/BasicExecutionContext.java
===================================================================
---
trunk/dna-graph/src/main/java/org/jboss/dna/graph/connectors/BasicExecutionContext.java 2008-10-30
17:31:14 UTC (rev 602)
+++
trunk/dna-graph/src/main/java/org/jboss/dna/graph/connectors/BasicExecutionContext.java 2008-10-30
17:34:02 UTC (rev 603)
@@ -71,6 +71,10 @@
this(null, null, namespaceRegistry, valueFactories, propertyFactory);
}
+ public BasicExecutionContext( NamespaceRegistry namespaceRegistry ) {
+ this(null, null, namespaceRegistry, null, null);
+ }
+
public BasicExecutionContext( LoginContext loginContext,
NamespaceRegistry namespaceRegistry,
ValueFactories valueFactories,
@@ -85,6 +89,11 @@
this(null, accessControlContext, namespaceRegistry, valueFactories,
propertyFactory);
}
+ public BasicExecutionContext( ExecutionContext inheritedContext,
+ NamespaceRegistry namespaceRegistry ) {
+ this(inheritedContext.getLoginContext(),
inheritedContext.getAccessControlContext(), namespaceRegistry, null, null);
+ }
+
/*
* This constructor exists to deal with mutually-exclusive parameters, such as
LoginContext and AccessControlContext.
*/
Modified:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/properties/NamespaceRegistry.java
===================================================================
---
trunk/dna-graph/src/main/java/org/jboss/dna/graph/properties/NamespaceRegistry.java 2008-10-30
17:31:14 UTC (rev 602)
+++
trunk/dna-graph/src/main/java/org/jboss/dna/graph/properties/NamespaceRegistry.java 2008-10-30
17:34:02 UTC (rev 603)
@@ -109,10 +109,27 @@
*/
Set<Namespace> getNamespaces();
+ /**
+ * Representation of a single namespace at a single point in time. This object does
not change to reflect changes made to the
+ * {@link NamespaceRegistry registry}.
+ *
+ * @see NamespaceRegistry#getNamespaces()
+ * @author Randall Hauch
+ */
@Immutable
interface Namespace {
+ /**
+ * Get the prefix for the namespace
+ *
+ * @return the prefix; never null but possibly the empty string
+ */
String getPrefix();
+ /**
+ * Get the URI for the namespace
+ *
+ * @return the namespace URI; never null but possibly the empty string
+ */
String getNamespaceUri();
}
Added:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/properties/basic/LocalNamespaceRegistry.java
===================================================================
---
trunk/dna-graph/src/main/java/org/jboss/dna/graph/properties/basic/LocalNamespaceRegistry.java
(rev 0)
+++
trunk/dna-graph/src/main/java/org/jboss/dna/graph/properties/basic/LocalNamespaceRegistry.java 2008-10-30
17:34:02 UTC (rev 603)
@@ -0,0 +1,176 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.jboss.dna.graph.properties.basic;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import net.jcip.annotations.ThreadSafe;
+import org.jboss.dna.common.util.CheckArg;
+import org.jboss.dna.graph.properties.NamespaceRegistry;
+
+/**
+ * @author Randall Hauch
+ */
+@ThreadSafe
+public class LocalNamespaceRegistry extends BasicNamespaceRegistry {
+
+ private final NamespaceRegistry delegate;
+
+ /**
+ * @param delegate the namespace registry that this registry should delegate to if
not found locally
+ */
+ public LocalNamespaceRegistry( NamespaceRegistry delegate ) {
+ super();
+ CheckArg.isNotNull(delegate, "delegate");
+ this.delegate = delegate;
+ unregister(DEFAULT_NAMESPACE_URI);
+ }
+
+ /**
+ * @param delegate the namespace registry that this registry should delegate to if
not found locally
+ * @param defaultNamespaceUri the namespace URI to use for the default prefix
+ */
+ public LocalNamespaceRegistry( NamespaceRegistry delegate,
+ final String defaultNamespaceUri ) {
+ super();
+ CheckArg.isNotNull(delegate, "delegate");
+ this.delegate = delegate;
+ register("", defaultNamespaceUri);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see
org.jboss.dna.graph.properties.basic.BasicNamespaceRegistry#getDefaultNamespaceUri()
+ */
+ @Override
+ public String getDefaultNamespaceUri() {
+ String result = super.getDefaultNamespaceUri();
+ if (result == null) result = this.delegate.getDefaultNamespaceUri();
+ return result;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see
org.jboss.dna.graph.properties.basic.BasicNamespaceRegistry#getNamespaceForPrefix(java.lang.String)
+ */
+ @Override
+ public String getNamespaceForPrefix( String prefix ) {
+ String result = super.getNamespaceForPrefix(prefix);
+ if (result == null) result = this.delegate.getNamespaceForPrefix(prefix);
+ return result;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.graph.properties.basic.BasicNamespaceRegistry#getNamespaces()
+ */
+ @Override
+ public Set<Namespace> getNamespaces() {
+ Set<Namespace> delegateNamespaces = this.delegate.getNamespaces();
+ Set<Namespace> localNamespaces = super.getNamespaces();
+
+ // Load the local namespaces first ...
+ Set<Namespace> namespaces = new HashSet<Namespace>(localNamespaces);
+
+ // Now build a map of the local prefixes so we can check for prefixes
+ Map<String, Namespace> localNamespacesByPrefix = new HashMap<String,
Namespace>();
+ for (Namespace ns : localNamespaces)
+ localNamespacesByPrefix.put(ns.getPrefix(), ns);
+
+ // Now iterate over the local namespaces, removing any existing namespace with
the same prefix
+ for (Namespace ns : delegateNamespaces) {
+ if (localNamespacesByPrefix.get(ns.getPrefix()) != null) continue;
+ // Try to add the delegate namespace, which won't work if a local with
the same URI was already added...
+ namespaces.add(ns);
+ }
+ return Collections.unmodifiableSet(namespaces);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see
org.jboss.dna.graph.properties.basic.BasicNamespaceRegistry#getPrefixForNamespaceUri(java.lang.String,
boolean)
+ */
+ @Override
+ public String getPrefixForNamespaceUri( String namespaceUri,
+ boolean generateIfMissing ) {
+ String result = super.getPrefixForNamespaceUri(namespaceUri, false);
+ if (result == null) result = this.delegate.getPrefixForNamespaceUri(namespaceUri,
false);
+ if (result == null && generateIfMissing) result =
super.getPrefixForNamespaceUri(namespaceUri, true);
+ return result;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see
org.jboss.dna.graph.properties.basic.BasicNamespaceRegistry#getRegisteredNamespaceUris()
+ */
+ @Override
+ public Set<String> getRegisteredNamespaceUris() {
+ Set<String> uris = new
HashSet<String>(this.delegate.getRegisteredNamespaceUris());
+ uris.addAll(super.getRegisteredNamespaceUris());
+ return Collections.unmodifiableSet(uris);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see
org.jboss.dna.graph.properties.basic.BasicNamespaceRegistry#isRegisteredNamespaceUri(java.lang.String)
+ */
+ @Override
+ public boolean isRegisteredNamespaceUri( String namespaceUri ) {
+ return super.isRegisteredNamespaceUri(namespaceUri) ||
this.delegate.isRegisteredNamespaceUri(namespaceUri);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see
org.jboss.dna.graph.properties.basic.BasicNamespaceRegistry#register(java.lang.String,
java.lang.String)
+ */
+ @Override
+ public String register( String prefix,
+ String namespaceUri ) {
+ // Just register the namespace locally ...
+ String previous = super.register(prefix, namespaceUri);
+ // But check whether there is a "previous" from the delegate ...
+ if (previous == null && delegate != null) previous =
delegate.getPrefixForNamespaceUri(namespaceUri, false);
+ return previous;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see
org.jboss.dna.graph.properties.basic.BasicNamespaceRegistry#unregister(java.lang.String)
+ */
+ @Override
+ public boolean unregister( String namespaceUri ) {
+ // Unregister locally ...
+ return super.unregister(namespaceUri);
+ }
+
+}
Property changes on:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/properties/basic/LocalNamespaceRegistry.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/xml/XmlHandler.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/xml/XmlHandler.java 2008-10-30
17:31:14 UTC (rev 602)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/xml/XmlHandler.java 2008-10-30
17:34:02 UTC (rev 603)
@@ -22,15 +22,17 @@
package org.jboss.dna.graph.xml;
import java.util.ArrayList;
-import java.util.HashSet;
+import java.util.HashMap;
+import java.util.LinkedList;
import java.util.List;
-import java.util.Set;
+import java.util.Map;
import javax.xml.parsers.SAXParser;
import net.jcip.annotations.NotThreadSafe;
import org.jboss.dna.common.text.TextDecoder;
import org.jboss.dna.common.text.XmlNameEncoder;
import org.jboss.dna.common.util.CheckArg;
import org.jboss.dna.graph.ExecutionContext;
+import org.jboss.dna.graph.connectors.BasicExecutionContext;
import org.jboss.dna.graph.properties.Name;
import org.jboss.dna.graph.properties.NameFactory;
import org.jboss.dna.graph.properties.NamespaceRegistry;
@@ -38,6 +40,7 @@
import org.jboss.dna.graph.properties.PathFactory;
import org.jboss.dna.graph.properties.Property;
import org.jboss.dna.graph.properties.PropertyFactory;
+import org.jboss.dna.graph.properties.basic.LocalNamespaceRegistry;
import org.xml.sax.Attributes;
import org.xml.sax.ext.DefaultHandler2;
@@ -68,6 +71,8 @@
INHERIT_ELEMENT_NAMESPACE;
}
+ private final ExecutionContext context;
+
/**
* Decoder for XML names, to turn '_xHHHH_' sequences in the XML element and
attribute names into the corresponding UTF-16
* characters.
@@ -125,10 +130,10 @@
protected final TextDecoder decoder;
/**
- * Local set of the namespace URIs that are registered. This is an optimization,
rather than relying upon the (thread-safe)
- * {@link #namespaceRegistry}.
+ * The stack of prefixes for each namespace, which is used to keep the {@link
#namespaceRegistry local namespace registry} in
+ * sync with the namespaces in the XML document.
*/
- private final Set<String> namespaceUris = new HashSet<String>();
+ private final Map<String, LinkedList<String>> prefixStackByUri = new
HashMap<String, LinkedList<String>>();
private final AttributeScoping attributeScoping;
@@ -191,13 +196,19 @@
this.skipFirstElement = skipRootElement;
this.attributeScoping = scoping != null ? scoping : DEFAULT_ATTRIBUTE_SCOPING;
+ // Use the execution context ...
+ this.context = destination.getExecutionContext();
+ assert this.context != null;
+
+ // Set up a local namespace registry that is kept in sync with the namespaces
found in this XML document ...
+ NamespaceRegistry namespaceRegistry = new
LocalNamespaceRegistry(this.context.getNamespaceRegistry());
+ final ExecutionContext localContext = new BasicExecutionContext(this.context,
namespaceRegistry);
+
// Set up references to frequently-used objects in the context ...
- final ExecutionContext context = destination.getExecutionContext();
- assert context != null;
- this.nameFactory = context.getValueFactories().getNameFactory();
- this.pathFactory = context.getValueFactories().getPathFactory();
- this.propertyFactory = context.getPropertyFactory();
- this.namespaceRegistry = context.getNamespaceRegistry();
+ this.nameFactory = localContext.getValueFactories().getNameFactory();
+ this.pathFactory = localContext.getValueFactories().getPathFactory();
+ this.propertyFactory = localContext.getPropertyFactory();
+ this.namespaceRegistry = localContext.getNamespaceRegistry();
assert this.nameFactory != null;
assert this.pathFactory != null;
assert this.propertyFactory != null;
@@ -222,18 +233,65 @@
public void startPrefixMapping( String prefix,
String uri ) {
assert uri != null;
- if (namespaceUris.add(uri)) {
- // This is a new namespace for this document ...
- if (!namespaceRegistry.isRegisteredNamespaceUri(uri)) {
- if (prefix != null && prefix.length() == 0) prefix = null;
+ // Add the prefix to the stack ...
+ LinkedList<String> prefixStack = this.prefixStackByUri.get(uri);
+ if (prefixStack == null) {
+ prefixStack = new LinkedList<String>();
+ this.prefixStackByUri.put(uri, prefixStack);
+ }
+ prefixStack.addFirst(prefix);
+
+ // If the namespace is already registered, then we'll have to register it in
the context's registry, too.
+ if (!namespaceRegistry.isRegisteredNamespaceUri(uri)) {
+ // The namespace is not already registered (locally or in the context's
registry), so we have to
+ // register it with the context's registry (which the local register then
inherits).
+ NamespaceRegistry contextRegistry = context.getNamespaceRegistry();
+ if (contextRegistry.getNamespaceForPrefix(prefix) != null) {
+ // The prefix is already bound, so register and generate a unique prefix
+ context.getNamespaceRegistry().getPrefixForNamespaceUri(uri, true);
+ // Now register locally with the supplied prefix ...
namespaceRegistry.register(prefix, uri);
+ } else {
+ context.getNamespaceRegistry().register(prefix, uri);
}
+ } else {
+ // It is already registered, but re-register it locally using the supplied
prefix ...
+ namespaceRegistry.register(prefix, uri);
}
}
/**
* {@inheritDoc}
*
+ * @see org.xml.sax.helpers.DefaultHandler#endPrefixMapping(java.lang.String)
+ */
+ @Override
+ public void endPrefixMapping( String prefix ) {
+ assert prefix != null;
+ // Get the current URI for this prefix ...
+ String uri = namespaceRegistry.getNamespaceForPrefix(prefix);
+ assert uri != null;
+
+ // Get the previous prefix from the stack ...
+ LinkedList<String> prefixStack = this.prefixStackByUri.get(uri);
+ assert prefixStack != null;
+ assert !prefixStack.isEmpty();
+ String existingPrefix = prefixStack.removeFirst();
+ assert prefix.equals(existingPrefix);
+
+ // If there are no previous prefixes, then remove the mapping ...
+ if (prefixStack.isEmpty()) {
+ namespaceRegistry.unregister(uri);
+ prefixStackByUri.remove(uri);
+ } else {
+ String previous = prefixStack.getFirst();
+ namespaceRegistry.register(previous, uri);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ *
* @see org.xml.sax.helpers.DefaultHandler#startElement(java.lang.String,
java.lang.String, java.lang.String,
* org.xml.sax.Attributes)
*/
Added:
trunk/dna-graph/src/test/java/org/jboss/dna/graph/properties/basic/BasicNamespaceTest.java
===================================================================
---
trunk/dna-graph/src/test/java/org/jboss/dna/graph/properties/basic/BasicNamespaceTest.java
(rev 0)
+++
trunk/dna-graph/src/test/java/org/jboss/dna/graph/properties/basic/BasicNamespaceTest.java 2008-10-30
17:34:02 UTC (rev 603)
@@ -0,0 +1,96 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.jboss.dna.graph.properties.basic;
+
+import static org.hamcrest.core.Is.is;
+import static org.junit.Assert.assertThat;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * @author Randall Hauch
+ */
+public class BasicNamespaceTest {
+
+ private BasicNamespace ns1;
+ private BasicNamespace ns2;
+ private BasicNamespace ns3;
+ private BasicNamespace ns4;
+ private BasicNamespace ns5;
+ private String validUri1;
+ private String validUri2;
+ private String validUri3;
+ private String validPrefix1;
+ private String validPrefix2;
+ private String validPrefix3;
+
+ @Before
+ public void beforeEach() {
+ validUri1 = "";
+ validUri2 = "http://www.example.com";
+ validUri3 = "http://www.acme.com";
+ validPrefix1 = "";
+ validPrefix2 = "a";
+ validPrefix3 = "b";
+ ns1 = new BasicNamespace(validPrefix1, validUri1);
+ ns2 = new BasicNamespace(validPrefix1, validUri2);
+ ns3 = new BasicNamespace(validPrefix2, validUri1);
+ ns4 = new BasicNamespace(validPrefix2, validUri2);
+ ns5 = new BasicNamespace(validPrefix3, validUri3);
+ }
+
+ @Test
+ public void shouldHaveSamePrefixPassedIntoConstructor() {
+ assertThat(ns1.getPrefix(), is(validPrefix1));
+ assertThat(ns2.getPrefix(), is(validPrefix1));
+ assertThat(ns3.getPrefix(), is(validPrefix2));
+ assertThat(ns4.getPrefix(), is(validPrefix2));
+ assertThat(ns5.getPrefix(), is(validPrefix3));
+ }
+
+ @Test
+ public void shouldHaveSameNamespaceUriPassedIntoConstructor() {
+ assertThat(ns1.getNamespaceUri(), is(validUri1));
+ assertThat(ns2.getNamespaceUri(), is(validUri2));
+ assertThat(ns3.getNamespaceUri(), is(validUri1));
+ assertThat(ns4.getNamespaceUri(), is(validUri2));
+ assertThat(ns5.getNamespaceUri(), is(validUri3));
+ }
+
+ @Test
+ public void shouldConsiderAsEqualAnyNamespacesWithSameUri() {
+ assertThat(ns1.equals(ns3), is(true));
+ assertThat(ns3.equals(ns1), is(true));
+ assertThat(ns2.equals(ns4), is(true));
+ assertThat(ns4.equals(ns2), is(true));
+ assertThat(ns5.equals(ns5), is(true));
+ }
+
+ @Test
+ public void shouldNotConsiderAsEqualAnyNamespacesWithDifferentUris() {
+ assertThat(ns1.equals(ns2), is(false));
+ assertThat(ns2.equals(ns1), is(false));
+ assertThat(ns3.equals(ns4), is(false));
+ assertThat(ns4.equals(ns3), is(false));
+ }
+
+}
Property changes on:
trunk/dna-graph/src/test/java/org/jboss/dna/graph/properties/basic/BasicNamespaceTest.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added:
trunk/dna-graph/src/test/java/org/jboss/dna/graph/properties/basic/LocalNamespaceRegistryTest.java
===================================================================
---
trunk/dna-graph/src/test/java/org/jboss/dna/graph/properties/basic/LocalNamespaceRegistryTest.java
(rev 0)
+++
trunk/dna-graph/src/test/java/org/jboss/dna/graph/properties/basic/LocalNamespaceRegistryTest.java 2008-10-30
17:34:02 UTC (rev 603)
@@ -0,0 +1,92 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.jboss.dna.graph.properties.basic;
+
+import static org.hamcrest.core.Is.is;
+import static org.junit.Assert.assertThat;
+import java.util.HashMap;
+import java.util.Map;
+import org.jboss.dna.graph.properties.NamespaceRegistry;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * @author Randall Hauch
+ */
+public class LocalNamespaceRegistryTest {
+
+ private NamespaceRegistry local;
+ private NamespaceRegistry delegate;
+ private String uri;
+
+ @Before
+ public void beforeEach() {
+ delegate = new BasicNamespaceRegistry();
+ local = new LocalNamespaceRegistry(delegate);
+ uri = "http://www.example.com";
+ }
+
+ @Test
+ public void shouldMirrorDelegateIfLocalIsEmpty() {
+ assertNamespaces(delegate, "");
+ assertNamespaces(local, "");
+ }
+
+ @Test
+ public void shouldAllowLocalRegistryToChangeDefaultNamespace() {
+ local.register("", uri);
+ assertNamespaces(delegate, "");
+ assertNamespaces(local, "=" + uri);
+ }
+
+ protected void assertNamespaces( NamespaceRegistry registry,
+ String... namespaces ) {
+ // Create the list of expected namespaces ...
+ Map<String, String> expected = new HashMap<String, String>();
+ for (String str : namespaces) {
+ String[] parts = str.length() != 0 ? str.split("=") : new String[]
{"", ""};
+ assertThat("invalid namespace string \"" + str +
"\"", parts.length, is(2));
+ expected.put(parts[0], parts[1]);
+ }
+ // Now compare the actual to expected ...
+ for (NamespaceRegistry.Namespace actual : registry.getNamespaces()) {
+ String expectedUri = expected.remove(actual.getPrefix());
+ assertThat("namespace URIs differ", actual.getNamespaceUri(),
is(expectedUri));
+ String prefix = actual.getPrefix();
+ String uri = actual.getNamespaceUri();
+ assertThat(registry.isRegisteredNamespaceUri(uri), is(true));
+ assertThat(registry.getPrefixForNamespaceUri(uri, false), is(prefix));
+ assertThat(registry.getNamespaceForPrefix(prefix), is(uri));
+ }
+ // Check that there are no more expected ...
+ if (!expected.isEmpty()) {
+ StringBuilder msg = new StringBuilder("actual is missing namespaces
");
+ boolean first = true;
+ for (Map.Entry<String, String> entry : expected.entrySet()) {
+ if (first) first = false;
+ else msg.append(", ");
+
msg.append(entry.getKey()).append("=").append(entry.getValue());
+ }
+ assertThat(msg.toString(), registry.getNamespaces().isEmpty(), is(true));
+ }
+ }
+}
Property changes on:
trunk/dna-graph/src/test/java/org/jboss/dna/graph/properties/basic/LocalNamespaceRegistryTest.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Modified: trunk/dna-graph/src/test/java/org/jboss/dna/graph/xml/XmlHandlerTest.java
===================================================================
--- trunk/dna-graph/src/test/java/org/jboss/dna/graph/xml/XmlHandlerTest.java 2008-10-30
17:31:14 UTC (rev 602)
+++ trunk/dna-graph/src/test/java/org/jboss/dna/graph/xml/XmlHandlerTest.java 2008-10-30
17:34:02 UTC (rev 603)
@@ -159,15 +159,17 @@
public void shouldParseXmlDocumentWithNamespaces() throws IOException, SAXException
{
context.getNamespaceRegistry().register("c",
"http://default.namespace.com");
parse("xmlHandler/docWithNamespaces.xml");
- // Check the generated content; note that the attribute name DOES match, so the
nodes names come from "jcr:name" attribute
+ // Check the generated content.
+ // Note that the attribute name DOES match, so the nodes names come from
"jcr:name" attribute
+ // Also, the "jcr:name" attribute values use the default namespace,
which is "c" in the registry
assertNode("c:Cars");
assertNode("c:Cars/c:Hybrid");
- assertNode("c:Cars/c:Hybrid/Toyota Prius", "maker=Toyota",
"model=Prius");
- assertNode("c:Cars/c:Hybrid/Toyota Highlander",
"maker=Toyota", "model=Highlander");
- assertNode("c:Cars/c:Hybrid/Nissan Altima", "maker=Nissan",
"model=Altima");
+ assertNode("c:Cars/c:Hybrid/c:Toyota Prius",
"c:maker=Toyota", "c:model=Prius");
+ assertNode("c:Cars/c:Hybrid/c:Toyota Highlander",
"c:maker=Toyota", "c:model=Highlander");
+ assertNode("c:Cars/c:Hybrid/c:Nissan Altima",
"c:maker=Nissan", "c:model=Altima");
assertNode("c:Cars/c:Sports");
- assertNode("c:Cars/c:Sports/Aston Martin DB9", "maker=Aston
Martin", "model=DB9");
- assertNode("c:Cars/c:Sports/Infiniti G37", "maker=Infiniti",
"model=G37");
+ assertNode("c:Cars/c:Sports/c:Aston Martin DB9", "c:maker=Aston
Martin", "c:model=DB9");
+ assertNode("c:Cars/c:Sports/c:Infiniti G37",
"c:maker=Infiniti", "c:model=G37");
}
@Test
@@ -178,9 +180,9 @@
// Check the generated content; note that the attribute name DOES match, so the
nodes names come from "jcr:name" attribute
assertNode("Cars");
assertNode("Cars/c:Hybrid");
- assertNode("Cars/c:Hybrid/Toyota Prius", "maker=Toyota",
"model=Prius");
- assertNode("Cars/c:Hybrid/Toyota Highlander", "maker=Toyota",
"model=Highlander");
- assertNode("Cars/c:Hybrid/Nissan Altima", "maker=Nissan",
"model=Altima");
+ assertNode("Cars/c:Hybrid/c:Toyota Prius", "c:maker=Toyota",
"c:model=Prius");
+ assertNode("Cars/c:Hybrid/c:Toyota Highlander",
"c:maker=Toyota", "c:model=Highlander");
+ assertNode("Cars/c:Hybrid/c:Nissan Altima", "c:maker=Nissan",
"c:model=Altima");
assertNode("Cars/Sports");
assertNode("Cars/Sports/Aston Martin DB9", "i:maker=Aston
Martin", "model=DB9");
assertNode("Cars/Sports/Infiniti G37", "i:maker=Infiniti",
"model=G37");
@@ -193,12 +195,12 @@
// Check the generated content; note that the attribute name DOES match, so the
nodes names come from "jcr:name" attribute
assertNode("c:Cars");
assertNode("c:Cars/c:Hybrid");
- assertNode("c:Cars/c:Hybrid/Toyota Prius", "maker=Toyota",
"model=Prius");
- assertNode("c:Cars/c:Hybrid/Toyota Highlander",
"maker=Toyota", "model=Highlander");
- assertNode("c:Cars/c:Hybrid/Nissan Altima", "maker=Nissan",
"model=Altima");
+ assertNode("c:Cars/c:Hybrid/c:Toyota Prius",
"c:maker=Toyota", "c:model=Prius");
+ assertNode("c:Cars/c:Hybrid/c:Toyota Highlander",
"c:maker=Toyota", "c:model=Highlander");
+ assertNode("c:Cars/c:Hybrid/c:Nissan Altima",
"c:maker=Nissan", "c:model=Altima");
assertNode("c:Cars/c:Sports");
- assertNode("c:Cars/c:Sports/Aston Martin DB9", "maker=Aston
Martin", "model=DB9");
- assertNode("c:Cars/c:Sports/Infiniti G37", "maker=Infiniti",
"model=G37");
+ assertNode("c:Cars/c:Sports/c:Aston Martin DB9", "c:maker=Aston
Martin", "c:model=DB9");
+ assertNode("c:Cars/c:Sports/c:Infiniti G37",
"c:maker=Infiniti", "c:model=G37");
}
@Test
@@ -216,15 +218,18 @@
String c = reg.getPrefixForNamespaceUri("http://default.namespace.com",
false);
String i = reg.getPrefixForNamespaceUri("http://attributes.com",
false);
String d = reg.getPrefixForNamespaceUri(reg.getDefaultNamespaceUri(), false);
+ assertThat("Namespace not properly registered in primary registry", c,
is(notNullValue()));
+ assertThat("Namespace not properly registered in primary registry", d,
is(notNullValue()));
+ assertThat("Namespace not properly registered in primary registry", i,
is(notNullValue()));
if (c.length() != 0) c = c + ":";
if (d.length() != 0) d = d + ":";
if (i.length() != 0) i = i + ":";
// Check the generated content; note that the attribute name DOES match, so the
nodes names come from "jcr:name" attribute
assertNode(d + "Cars");
assertNode(d + "Cars/" + c + "Hybrid");
- assertNode(d + "Cars/" + c + "Hybrid/Toyota Prius",
"maker=Toyota", "model=Prius");
- assertNode(d + "Cars/" + c + "Hybrid/Toyota Highlander",
"maker=Toyota", "model=Highlander");
- assertNode(d + "Cars/" + c + "Hybrid/Nissan Altima",
"maker=Nissan", "model=Altima");
+ assertNode(d + "Cars/" + c + "Hybrid/" + c + "Toyota
Prius", c + "maker=Toyota", c + "model=Prius");
+ assertNode(d + "Cars/" + c + "Hybrid/" + c + "Toyota
Highlander", c + "maker=Toyota", c + "model=Highlander");
+ assertNode(d + "Cars/" + c + "Hybrid/" + c + "Nissan
Altima", c + "maker=Nissan", c + "model=Altima");
assertNode(d + "Cars/" + d + "Sports");
assertNode(d + "Cars/" + d + "Sports/Aston Martin DB9", i +
"maker=Aston Martin", "model=DB9");
assertNode(d + "Cars/" + d + "Sports/Infiniti G37", i +
"maker=Infiniti", "model=G37");
@@ -237,15 +242,29 @@
// Check the generated content; note that the attribute name DOES match, so the
nodes names come from "jcr:name" attribute
assertNode("c:Cars");
assertNode("c:Cars/c:Hybrid");
- assertNode("c:Cars/c:Hybrid/Toyota Prius", "maker=Toyota",
"model=Prius");
- assertNode("c:Cars/c:Hybrid/Toyota Highlander",
"maker=Toyota", "model=Highlander");
- assertNode("c:Cars/c:Hybrid/Nissan Altima", "maker=Nissan",
"model=Altima");
+ assertNode("c:Cars/c:Hybrid/c:Toyota Prius",
"c:maker=Toyota", "c:model=Prius");
+ assertNode("c:Cars/c:Hybrid/c:Toyota Highlander",
"c:maker=Toyota", "c:model=Highlander");
+ assertNode("c:Cars/c:Hybrid/c:Nissan Altima",
"c:maker=Nissan", "c:model=Altima");
assertNode("c:Cars/c:Sports");
- assertNode("c:Cars/c:Sports/Aston Martin DB9", "maker=Aston
Martin", "model=DB9");
- assertNode("c:Cars/c:Sports/Infiniti G37", "maker=Infiniti",
"model=G37");
+ assertNode("c:Cars/c:Sports/c:Aston Martin DB9", "c:maker=Aston
Martin", "c:model=DB9");
+ assertNode("c:Cars/c:Sports/c:Infiniti G37",
"c:maker=Infiniti", "c:model=G37");
}
@Test
+ public void shouldParseXmlDocumentWithoutDefaultNamespaceThatUsesNameAttribute()
throws IOException, SAXException {
+ parse("xmlHandler/docWithNamespacesWithoutDefault.xml");
+ // Check the generated content; note that the attribute name DOES match, so the
nodes names come from "jcr:name" attribute
+ assertNode("Cars");
+ assertNode("Cars/Hybrid");
+ assertNode("Cars/Hybrid/Toyota Prius", "maker=Toyota",
"model=Prius");
+ assertNode("Cars/Hybrid/Toyota Highlander", "maker=Toyota",
"model=Highlander");
+ assertNode("Cars/Hybrid/Nissan Altima", "maker=Nissan",
"model=Altima");
+ assertNode("Cars/Sports");
+ assertNode("Cars/Sports/Aston Martin DB9", "maker=Aston
Martin", "model=DB9");
+ assertNode("Cars/Sports/Infiniti G37", "maker=Infiniti",
"model=G37");
+ }
+
+ @Test
public void shouldParseXmlDocumentThatContainsNoContent() throws IOException,
SAXException {
parse("xmlHandler/docWithOnlyRootElement.xml");
assertNode("Cars");
@@ -261,12 +280,12 @@
parse("xmlHandler/docWithNamespaces.xml");
// Check the generated content; note that the attribute name DOES match, so the
nodes names come from "jcr:name" attribute
assertNode("c:Hybrid");
- assertNode("c:Hybrid/Toyota Prius", "maker=Toyota",
"model=Prius");
- assertNode("c:Hybrid/Toyota Highlander", "maker=Toyota",
"model=Highlander");
- assertNode("c:Hybrid/Nissan Altima", "maker=Nissan",
"model=Altima");
+ assertNode("c:Hybrid/c:Toyota Prius", "c:maker=Toyota",
"c:model=Prius");
+ assertNode("c:Hybrid/c:Toyota Highlander", "c:maker=Toyota",
"c:model=Highlander");
+ assertNode("c:Hybrid/c:Nissan Altima", "c:maker=Nissan",
"c:model=Altima");
assertNode("c:Sports");
- assertNode("c:Sports/Aston Martin DB9", "maker=Aston Martin",
"model=DB9");
- assertNode("c:Sports/Infiniti G37", "maker=Infiniti",
"model=G37");
+ assertNode("c:Sports/c:Aston Martin DB9", "c:maker=Aston
Martin", "c:model=DB9");
+ assertNode("c:Sports/c:Infiniti G37", "c:maker=Infiniti",
"c:model=G37");
}
@Test
@@ -279,12 +298,12 @@
// Check the generated content; note that the attribute name DOES match, so the
nodes names come from "jcr:name" attribute
assertNode("c:Cars");
assertNode("c:Cars/c:Hybrid");
- assertNode("c:Cars/c:Hybrid/Toyota Prius", "maker=Toyota",
"model=Prius");
- assertNode("c:Cars/c:Hybrid/Toyota Highlander",
"maker=Toyota", "model=Highlander");
- assertNode("c:Cars/c:Hybrid/Nissan Altima", "maker=Nissan",
"model=Altima");
+ assertNode("c:Cars/c:Hybrid/c:Toyota Prius",
"c:maker=Toyota", "c:model=Prius");
+ assertNode("c:Cars/c:Hybrid/c:Toyota Highlander",
"c:maker=Toyota", "c:model=Highlander");
+ assertNode("c:Cars/c:Hybrid/c:Nissan Altima",
"c:maker=Nissan", "c:model=Altima");
assertNode("c:Cars/c:Sports");
- assertNode("c:Cars/c:Sports/Aston Martin DB9", "maker=Aston
Martin", "model=DB9");
- assertNode("c:Cars/c:Sports/Infiniti G37", "maker=Infiniti",
"model=G37");
+ assertNode("c:Cars/c:Sports/c:Aston Martin DB9", "c:maker=Aston
Martin", "c:model=DB9");
+ assertNode("c:Cars/c:Sports/c:Infiniti G37",
"c:maker=Infiniti", "c:model=G37");
}
@Test
@@ -297,12 +316,12 @@
// Check the generated content; note that the attribute name DOES match, so the
nodes names come from "jcr:name" attribute
assertNode("c:Cars");
assertNode("c:Cars/c:Hybrid");
- assertNode("c:Cars/c:Hybrid/Toyota Prius", "maker=Toyota",
"model=Prius");
- assertNode("c:Cars/c:Hybrid/Toyota Highlander",
"maker=Toyota", "model=Highlander");
- assertNode("c:Cars/c:Hybrid/Nissan Altima", "maker=Nissan",
"model=Altima");
+ assertNode("c:Cars/c:Hybrid/c:Toyota Prius",
"c:maker=Toyota", "c:model=Prius");
+ assertNode("c:Cars/c:Hybrid/c:Toyota Highlander",
"c:maker=Toyota", "c:model=Highlander");
+ assertNode("c:Cars/c:Hybrid/c:Nissan Altima",
"c:maker=Nissan", "c:model=Altima");
assertNode("c:Cars/c:Sports");
- assertNode("c:Cars/c:Sports/Aston Martin DB9", "maker=Aston
Martin", "model=DB9");
- assertNode("c:Cars/c:Sports/Infiniti G37", "maker=Infiniti",
"model=G37");
+ assertNode("c:Cars/c:Sports/c:Aston Martin DB9", "c:maker=Aston
Martin", "c:model=DB9");
+ assertNode("c:Cars/c:Sports/c:Infiniti G37",
"c:maker=Infiniti", "c:model=G37");
}
@Test
@@ -311,12 +330,12 @@
parse("xmlHandler/docWithComments.xml");
assertNode("c:Cars");
assertNode("c:Cars/c:Hybrid");
- assertNode("c:Cars/c:Hybrid/Toyota Prius", "maker=Toyota",
"model=Prius");
- assertNode("c:Cars/c:Hybrid/Toyota Highlander",
"maker=Toyota", "model=Highlander");
- assertNode("c:Cars/c:Hybrid/Nissan Altima", "maker=Nissan",
"model=Altima");
+ assertNode("c:Cars/c:Hybrid/c:Toyota Prius",
"c:maker=Toyota", "c:model=Prius");
+ assertNode("c:Cars/c:Hybrid/c:Toyota Highlander",
"c:maker=Toyota", "c:model=Highlander");
+ assertNode("c:Cars/c:Hybrid/c:Nissan Altima",
"c:maker=Nissan", "c:model=Altima");
assertNode("c:Cars/c:Sports");
- assertNode("c:Cars/c:Sports/Aston Martin DB9", "maker=Aston
Martin", "model=DB9");
- assertNode("c:Cars/c:Sports/Infiniti G37", "maker=Infiniti",
"model=G37");
+ assertNode("c:Cars/c:Sports/c:Aston Martin DB9", "c:maker=Aston
Martin", "c:model=DB9");
+ assertNode("c:Cars/c:Sports/c:Infiniti G37",
"c:maker=Infiniti", "c:model=G37");
}
@Test
@@ -351,12 +370,12 @@
String carPrimaryType =
"jcr:primaryType={http://default.namespace.com}car";
assertNode("c:Cars", unstructPrimaryType);
assertNode("c:Cars/c:Hybrid", unstructPrimaryType);
- assertNode("c:Cars/c:Hybrid/Toyota Prius", carPrimaryType,
"maker=Toyota", "model=Prius");
- assertNode("c:Cars/c:Hybrid/Toyota Highlander", carPrimaryType,
"maker=Toyota", "model=Highlander");
- assertNode("c:Cars/c:Hybrid/Nissan Altima", carPrimaryType,
"maker=Nissan", "model=Altima");
+ assertNode("c:Cars/c:Hybrid/c:Toyota Prius", carPrimaryType,
"c:maker=Toyota", "c:model=Prius");
+ assertNode("c:Cars/c:Hybrid/c:Toyota Highlander", carPrimaryType,
"c:maker=Toyota", "c:model=Highlander");
+ assertNode("c:Cars/c:Hybrid/c:Nissan Altima", carPrimaryType,
"c:maker=Nissan", "c:model=Altima");
assertNode("c:Cars/c:Sports", unstructPrimaryType);
- assertNode("c:Cars/c:Sports/Aston Martin DB9", carPrimaryType,
"maker=Aston Martin", "model=DB9");
- assertNode("c:Cars/c:Sports/Infiniti G37", carPrimaryType,
"maker=Infiniti", "model=G37");
+ assertNode("c:Cars/c:Sports/c:Aston Martin DB9", carPrimaryType,
"c:maker=Aston Martin", "c:model=DB9");
+ assertNode("c:Cars/c:Sports/c:Infiniti G37", carPrimaryType,
"c:maker=Infiniti", "c:model=G37");
}
protected void assertNode( String path,
@@ -382,7 +401,7 @@
assertThat(request.at().getPath(), is(expectedPath));
for (Property actual : request.properties()) {
Property expected = expectedProperties.remove(actual.getName());
- assertThat(expected, is(notNullValue()));
+ assertThat("unexpected property: " + actual, expected,
is(notNullValue()));
assertThat(actual, is(expected));
}
if (!expectedProperties.isEmpty()) {
Added: trunk/dna-graph/src/test/resources/xmlHandler/docWithNamespacesWithoutDefault.xml
===================================================================
--- trunk/dna-graph/src/test/resources/xmlHandler/docWithNamespacesWithoutDefault.xml
(rev 0)
+++
trunk/dna-graph/src/test/resources/xmlHandler/docWithNamespacesWithoutDefault.xml 2008-10-30
17:34:02 UTC (rev 603)
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Cars
xmlns:jcr="http://www.jcp.org/jcr/1.0">
+ <Hybrid>
+ <car jcr:name="Toyota Prius" maker="Toyota"
model="Prius"/>
+ <car jcr:name="Toyota Highlander" maker="Toyota"
model="Highlander"/>
+ <car jcr:name="Nissan Altima" maker="Nissan"
model="Altima"/>
+ </Hybrid>
+ <Sports>
+ <car jcr:name="Aston Martin DB9" maker="Aston Martin"
model="DB9"/>
+ <car jcr:name="Infiniti G37" maker="Infiniti"
model="G37" />
+ </Sports>
+</Cars>
\ No newline at end of file
Property changes on:
trunk/dna-graph/src/test/resources/xmlHandler/docWithNamespacesWithoutDefault.xml
___________________________________________________________________
Name: svn:mime-type
+ text/plain