[dna-commits] DNA SVN: r185 - in branches/federation: dna-common/src/main/java/org/jboss/dna/common/util and 13 other directories.

dna-commits at lists.jboss.org dna-commits at lists.jboss.org
Fri May 23 12:12:06 EDT 2008


Author: rhauch
Date: 2008-05-23 12:12:06 -0400 (Fri, 23 May 2008)
New Revision: 185

Added:
   branches/federation/dna-repository/src/main/java/org/jboss/dna/repository/util/JcrNamespaceRegistry.java
   branches/federation/dna-spi/src/main/java/org/jboss/dna/spi/graph/NamespaceException.java
   branches/federation/dna-spi/src/main/java/org/jboss/dna/spi/graph/ValueComparators.java
   branches/federation/dna-spi/src/main/java/org/jboss/dna/spi/graph/impl/BasicNamespaceRegistry.java
   branches/federation/dna-spi/src/main/java/org/jboss/dna/spi/graph/impl/ObjectValueFactory.java
   branches/federation/dna-spi/src/test/java/org/jboss/dna/spi/graph/AbstractValueComparatorsTest.java
   branches/federation/dna-spi/src/test/java/org/jboss/dna/spi/graph/BinaryValueComparatorTest.java
   branches/federation/dna-spi/src/test/java/org/jboss/dna/spi/graph/BooleanValueComparatorTest.java
   branches/federation/dna-spi/src/test/java/org/jboss/dna/spi/graph/DateValueComparatorTest.java
   branches/federation/dna-spi/src/test/java/org/jboss/dna/spi/graph/DecimalValueComparatorTest.java
   branches/federation/dna-spi/src/test/java/org/jboss/dna/spi/graph/DoubleValueComparatorTest.java
   branches/federation/dna-spi/src/test/java/org/jboss/dna/spi/graph/LongValueComparatorTest.java
   branches/federation/dna-spi/src/test/java/org/jboss/dna/spi/graph/NameValueComparatorTest.java
   branches/federation/dna-spi/src/test/java/org/jboss/dna/spi/graph/StringValueComparatorTest.java
   branches/federation/dna-spi/src/test/java/org/jboss/dna/spi/graph/impl/BasicNameTest.java
   branches/federation/dna-spi/src/test/java/org/jboss/dna/spi/graph/impl/BasicPathSegmentTest.java
   branches/federation/dna-spi/src/test/java/org/jboss/dna/spi/graph/impl/BasicPathTest.java
   branches/federation/dna-spi/src/test/java/org/jboss/dna/spi/graph/impl/IsPathContaining.java
   branches/federation/dna-spi/src/test/java/org/jboss/dna/spi/graph/impl/NameValueFactoryTest.java
   branches/federation/dna-spi/src/test/java/org/jboss/dna/spi/graph/impl/PathValueFactoryTest.java
Removed:
   branches/federation/dna-common/src/main/java/org/jboss/dna/common/jcr/
   branches/federation/dna-common/src/test/java/org/jboss/dna/common/jcr/PathTest.java
   branches/federation/dna-spi/src/main/java/org/jboss/dna/spi/graph/PropertyValues.java
Modified:
   branches/federation/dna-common/src/main/java/org/jboss/dna/common/CommonI18n.java
   branches/federation/dna-common/src/main/java/org/jboss/dna/common/util/ArgCheck.java
   branches/federation/dna-common/src/main/resources/org/jboss/dna/common/CommonI18n.properties
   branches/federation/dna-repository/src/main/java/org/jboss/dna/repository/sequencers/SequencerOutputMap.java
   branches/federation/dna-repository/src/main/java/org/jboss/dna/repository/sequencers/SequencingService.java
   branches/federation/dna-repository/src/main/java/org/jboss/dna/repository/sequencers/StreamSequencerAdapter.java
   branches/federation/dna-repository/src/main/java/org/jboss/dna/repository/util/ExecutionContext.java
   branches/federation/dna-repository/src/main/java/org/jboss/dna/repository/util/SimpleExecutionContext.java
   branches/federation/dna-repository/src/test/java/org/jboss/dna/repository/sequencers/StreamSequencerAdapterTest.java
   branches/federation/dna-repository/src/test/java/org/jboss/dna/repository/util/MockExecutionContext.java
   branches/federation/dna-spi/src/main/java/org/jboss/dna/spi/SpiI18n.java
   branches/federation/dna-spi/src/main/java/org/jboss/dna/spi/graph/NamespaceRegistry.java
   branches/federation/dna-spi/src/main/java/org/jboss/dna/spi/graph/Path.java
   branches/federation/dna-spi/src/main/java/org/jboss/dna/spi/graph/PathFactory.java
   branches/federation/dna-spi/src/main/java/org/jboss/dna/spi/graph/PropertyType.java
   branches/federation/dna-spi/src/main/java/org/jboss/dna/spi/graph/ValueFactories.java
   branches/federation/dna-spi/src/main/java/org/jboss/dna/spi/graph/impl/BasicName.java
   branches/federation/dna-spi/src/main/java/org/jboss/dna/spi/graph/impl/BasicPath.java
   branches/federation/dna-spi/src/main/java/org/jboss/dna/spi/graph/impl/BasicPathSegment.java
   branches/federation/dna-spi/src/main/java/org/jboss/dna/spi/graph/impl/InMemoryBinary.java
   branches/federation/dna-spi/src/main/java/org/jboss/dna/spi/graph/impl/NameValueFactory.java
   branches/federation/dna-spi/src/main/java/org/jboss/dna/spi/graph/impl/PathValueFactory.java
   branches/federation/dna-spi/src/main/java/org/jboss/dna/spi/graph/impl/StandardValueFactories.java
   branches/federation/dna-spi/src/main/java/org/jboss/dna/spi/graph/impl/UuidReference.java
   branches/federation/dna-spi/src/main/resources/org/jboss/dna/spi/SpiI18n.properties
   branches/federation/docs/examples/gettingstarted/sequencers/src/main/java/org/jboss/example/dna/sequencers/SequencingClient.java
Log:
DNA-67: Create graph API for federation engine
http://jira.jboss.org/jira/browse/DNA-67

Created unit tests for several of the basic implementation classes, and in the process changes some of the interfaces to handle functionality that was missing or incorrect.

Modified: branches/federation/dna-common/src/main/java/org/jboss/dna/common/CommonI18n.java
===================================================================
--- branches/federation/dna-common/src/main/java/org/jboss/dna/common/CommonI18n.java	2008-05-22 20:22:50 UTC (rev 184)
+++ branches/federation/dna-common/src/main/java/org/jboss/dna/common/CommonI18n.java	2008-05-23 16:12:06 UTC (rev 185)
@@ -41,21 +41,23 @@
     public static I18n i18nFieldNotPublic;
     public static I18n i18nFieldNotStatic;
     public static I18n i18nLocalizationFileNotFound;
-	public static I18n i18nLocalizationProblems;
-	public static I18n i18nRequiredToSuppliedParameterMismatch;
+    public static I18n i18nLocalizationProblems;
+    public static I18n i18nRequiredToSuppliedParameterMismatch;
 
-	/**
-	 * Parameters:
-	 * <ol>
-	 * <li>{@link I18n#id() Property}</li>
-	 * <li>Localization file URL</li>
-	 * </ol>
-	 */
+    /**
+     * Parameters:
+     * <ol>
+     * <li>{@link I18n#id() Property}</li>
+     * <li>Localization file URL</li>
+     * </ol>
+     */
     public static I18n i18nPropertyDuplicate;
     public static I18n i18nPropertyMissing;
     public static I18n i18nPropertyUnused;
 
     // Core-related fields
+    public static I18n argumentMayNotBeLessThan;
+    public static I18n argumentMayNotBeGreaterThan;
     public static I18n argumentMayNotBeNegative;
     public static I18n argumentMayNotBePositive;
     public static I18n argumentMustBeNegative;
@@ -75,7 +77,7 @@
     public static I18n argumentDidNotContainKey;
     public static I18n argumentMayNotContainNullValue;
     public static I18n componentClassnameNotValid;
-	public static I18n componentNotConfigured;
+    public static I18n componentNotConfigured;
     public static I18n dateParsingFailure;
     public static I18n initialProgressMonitorTaskName;
     public static I18n nullProgressMonitorTaskName;
@@ -85,7 +87,7 @@
     public static I18n pathIsNotRelative;
     public static I18n pathCannotBeNormalized;
     public static I18n progressMonitorBeginTask;
-	public static I18n progressMonitorStatus;
+    public static I18n progressMonitorStatus;
     public static I18n requiredToSuppliedParameterMismatch;
 
     static {
@@ -97,14 +99,14 @@
     }
 
     public static Set<Locale> getLocalizationProblemLocales() {
-		return I18n.getLocalizationProblemLocales(CommonI18n.class);
-	}
+        return I18n.getLocalizationProblemLocales(CommonI18n.class);
+    }
 
     public static Set<String> getLocalizationProblems() {
-		return I18n.getLocalizationProblems(CommonI18n.class);
-	}
+        return I18n.getLocalizationProblems(CommonI18n.class);
+    }
 
     public static Set<String> getLocalizationProblems( Locale locale ) {
-		return I18n.getLocalizationProblems(CommonI18n.class, locale);
-	}
+        return I18n.getLocalizationProblems(CommonI18n.class, locale);
+    }
 }

Modified: branches/federation/dna-common/src/main/java/org/jboss/dna/common/util/ArgCheck.java
===================================================================
--- branches/federation/dna-common/src/main/java/org/jboss/dna/common/util/ArgCheck.java	2008-05-22 20:22:50 UTC (rev 184)
+++ branches/federation/dna-common/src/main/java/org/jboss/dna/common/util/ArgCheck.java	2008-05-23 16:12:06 UTC (rev 185)
@@ -35,6 +35,32 @@
     // ########################## int METHODS ###################################
 
     /**
+     * Check that the argument is not less than the supplied value
+     * @param argument The argument
+     * @param notLessThanValue the value that is to be used to check the value
+     * @param name The name of the argument
+     * @throws IllegalArgumentException If argument is negative (<0)
+     */
+    public static void isNotLessThan( int argument, int notLessThanValue, String name ) {
+        if (argument < notLessThanValue) {
+            throw new IllegalArgumentException(CommonI18n.argumentMayNotBeLessThan.text(name, argument, notLessThanValue));
+        }
+    }
+
+    /**
+     * Check that the argument is not greater than the supplied value
+     * @param argument The argument
+     * @param notGreaterThanValue the value that is to be used to check the value
+     * @param name The name of the argument
+     * @throws IllegalArgumentException If argument is negative (<0)
+     */
+    public static void isNotGreaterThan( int argument, int notGreaterThanValue, String name ) {
+        if (argument < notGreaterThanValue) {
+            throw new IllegalArgumentException(CommonI18n.argumentMayNotBeGreaterThan.text(name, argument, notGreaterThanValue));
+        }
+    }
+
+    /**
      * Check that the argument is non-negative (>=0).
      * @param argument The argument
      * @param name The name of the argument

Modified: branches/federation/dna-common/src/main/resources/org/jboss/dna/common/CommonI18n.properties
===================================================================
--- branches/federation/dna-common/src/main/resources/org/jboss/dna/common/CommonI18n.properties	2008-05-22 20:22:50 UTC (rev 184)
+++ branches/federation/dna-common/src/main/resources/org/jboss/dna/common/CommonI18n.properties	2008-05-23 16:12:06 UTC (rev 185)
@@ -15,6 +15,8 @@
 i18nRequiredToSuppliedParameterMismatch = Internationalization field "{0}" in {1}: {2}
 
 # Core-related fields
+argumentMayNotBeGreaterThan = The {0} argument value, {1}, may not be greater than {2}
+argumentMayNotBeLessThan = The {0} argument value, {1}, may not be less than {2}
 argumentMayNotBeNegative = The {0} argument value, {1}, may not be negative
 argumentMayNotBePositive = The {0} argument value, {1}, may not be positive
 argumentMustBeNegative = The {0} argument value, {1}, must be negative

Deleted: branches/federation/dna-common/src/test/java/org/jboss/dna/common/jcr/PathTest.java
===================================================================
--- branches/federation/dna-common/src/test/java/org/jboss/dna/common/jcr/PathTest.java	2008-05-22 20:22:50 UTC (rev 184)
+++ branches/federation/dna-common/src/test/java/org/jboss/dna/common/jcr/PathTest.java	2008-05-23 16:12:06 UTC (rev 185)
@@ -1,438 +0,0 @@
-/*
- * 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.common.jcr;
-
-import static org.hamcrest.core.Is.is;
-import static org.hamcrest.core.IsEqual.equalTo;
-import static org.hamcrest.core.IsInstanceOf.instanceOf;
-import static org.hamcrest.core.IsNot.not;
-import static org.hamcrest.core.IsSame.sameInstance;
-import static org.junit.Assert.assertThat;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import org.jboss.dna.common.text.Jsr283Encoder;
-import org.junit.Before;
-import org.junit.Test;
-
-/**
- * @author Randall Hauch
- */
-public class PathTest {
-
-    private Path validPath;
-
-    @Before
-    public void beforeEach() throws Exception {
-        this.validPath = new Path("/a/b/c/d/e/f");
-    }
-
-    @Test( expected = InvalidPathException.class )
-    public void shouldNotConstructPathFromEmptyString() {
-        new Path("");
-    }
-
-    @Test( expected = InvalidPathException.class )
-    public void shouldNotConstructPathFromStringWithOnlyWhitespace() {
-        new Path("   \t  ");
-    }
-
-    @Test( expected = InvalidPathException.class )
-    public void shouldNotConstructPathWithSuccessiveDelimiters() {
-        new Path("///a/b///c//d//");
-    }
-
-    @Test( expected = InvalidPathException.class )
-    public void shouldNotConstructPathWithOnlyDelimiters() {
-        new Path("///");
-    }
-
-    @Test( expected = InvalidPathException.class )
-    public void shouldNotConstructPathFromNullString() {
-        new Path((String)null);
-    }
-
-    @Test
-    public void shouldConstructPathFromStringAndShouldIgnoreLeadingAndTrailingWhitespace() {
-        assertThat(new Path(" \t /  \t").toString(), is("/"));
-    }
-
-    @Test
-    public void shouldConstructRelativePathIfSuppliedPathHasNoLeadingDelimiter() {
-        assertThat(new Path("a").toString(), is("a"));
-    }
-
-    @Test
-    public void shouldConstructRootPathFromStringWithSingleDelimiter() {
-        assertThat(new Path("/"), is(Path.ROOT));
-        assertThat(new Path("/").isRoot(), is(true));
-    }
-
-    @Test
-    public void shouldConstructRelativePath() {
-        assertThat(new Path("a/b/c").isAbsolute(), is(false));
-        assertThat(new Path("a/b/c").isNormalized(), is(true));
-        assertThat(new Path("a/b/c").size(), is(3));
-        assertThat(new Path("a/b/c").getString(), is("a/b/c"));
-        assertThat(new Path("a/b/c").toStringArray(), is(new String[] {"a", "b", "c"}));
-    }
-
-    @Test
-    public void shouldConstructRelativePathToSelf() {
-        assertThat(new Path(".").isAbsolute(), is(false));
-        assertThat(new Path(".").size(), is(1));
-        assertThat(new Path(".").getSegment(0), is(Path.SELF_SEGMENT));
-
-        assertThat(new Path("./").isAbsolute(), is(false));
-        assertThat(new Path("./").size(), is(1));
-        assertThat(new Path("./").getSegment(0), is(Path.SELF_SEGMENT));
-    }
-
-    @Test
-    public void shouldConstructRelativePathToParent() {
-        assertThat(new Path("..").isAbsolute(), is(false));
-        assertThat(new Path("..").size(), is(1));
-        assertThat(new Path("..").getSegment(0), is(Path.PARENT_SEGMENT));
-
-        assertThat(new Path("../").isAbsolute(), is(false));
-        assertThat(new Path("../").size(), is(1));
-        assertThat(new Path("../").getSegment(0), is(Path.PARENT_SEGMENT));
-    }
-
-    @Test
-    public void shouldConstructPathCorrectlyFromStrings() {
-        assertThat(new Path("/a/b/c/d").toStringArray(), is(new String[] {"a", "b", "c", "d"}));
-        assertThat(new Path("/a").toStringArray(), is(new String[] {"a"}));
-    }
-
-    @Test
-    public void shouldSupportClone() {
-        assertThat(validPath.clone(), is(validPath));
-        assertThat(validPath.clone(), is(not(sameInstance(validPath))));
-    }
-
-    @Test
-    public void shouldConstructPathCorrectlyFromStringsWithEncodedCharactersUsingUrlEncoder() {
-        assertThat(new Path("/a%3c%20_%2fc", Path.URL_ENCODER).toStringArray(), is(new String[] {"a< _/c"}));
-        assertThat(new Path("/%2f", Path.URL_ENCODER).toStringArray(), is(new String[] {"/"}));
-        assertThat(new Path("/abcdefghijklmnopqrstuvwxyz", Path.URL_ENCODER).toStringArray(), is(new String[] {"abcdefghijklmnopqrstuvwxyz"}));
-        assertThat(new Path("/ABCDEFGHIJKLMNOPQRSTUVWXYZ", Path.URL_ENCODER).toStringArray(), is(new String[] {"ABCDEFGHIJKLMNOPQRSTUVWXYZ"}));
-        assertThat(new Path("/0123456789", Path.URL_ENCODER).toStringArray(), is(new String[] {"0123456789"}));
-        assertThat(new Path("/-_.!~*\'()", Path.URL_ENCODER).toStringArray(), is(new String[] {"-_.!~*\'()"}));
-        assertThat(new Path("/%60%40%23%24%5e%26%7b%5b%7d%5d%7c%3a%3b%22%3c%2c%3e%3f%2f%20", Path.URL_ENCODER).toStringArray(), is(new String[] {"`@#$^&{[}]|:;\"<,>?/ "}));
-    }
-
-    @Test
-    public void shouldConstructPathCorrectlyFromStringsWithEncodedCharactersUsingJsr283Encoder() {
-        assertThat(new Path("/abcdefghijklmnopqrstuvwxyz", Path.JSR283_ENCODER).toStringArray(), is(new String[] {"abcdefghijklmnopqrstuvwxyz"}));
-        assertThat(new Path("/ABCDEFGHIJKLMNOPQRSTUVWXYZ", Path.JSR283_ENCODER).toStringArray(), is(new String[] {"ABCDEFGHIJKLMNOPQRSTUVWXYZ"}));
-        assertThat(new Path("/0123456789", Path.JSR283_ENCODER).toStringArray(), is(new String[] {"0123456789"}));
-        assertThat(new Path("/\uF02F-_.!~\uF02A\'()`@#$^&{\uF05B}\uF05D\uF07C\uF03A;\"<,>?", Path.JSR283_ENCODER).toStringArray(), is(new String[] {"/-_.!~*\'()`@#$^&{[}]|:;\"<,>?"}));
-    }
-
-    @Test
-    public void shouldConstructPathCorrectlyFromStringsWithEncodedCharactersUsingDefaultEncoder() {
-        assertThat(new Path("/abcdefghijklmnopqrstuvwxyz", Path.DEFAULT_ENCODER).toStringArray(), is(new String[] {"abcdefghijklmnopqrstuvwxyz"}));
-        assertThat(new Path("/ABCDEFGHIJKLMNOPQRSTUVWXYZ", Path.DEFAULT_ENCODER).toStringArray(), is(new String[] {"ABCDEFGHIJKLMNOPQRSTUVWXYZ"}));
-        assertThat(new Path("/0123456789", Path.DEFAULT_ENCODER).toStringArray(), is(new String[] {"0123456789"}));
-        assertThat(new Path("/\uF02F-_.!~\uF02A\'()`@#$^&{\uF05B}\uF05D\uF07C\uF03A;\"<,>?", Path.DEFAULT_ENCODER).toStringArray(), is(new String[] {"/-_.!~*\'()`@#$^&{[}]|:;\"<,>?"}));
-
-        assertThat(new Path("/abcdefghijklmnopqrstuvwxyz", null).toStringArray(), is(new String[] {"abcdefghijklmnopqrstuvwxyz"}));
-        assertThat(new Path("/ABCDEFGHIJKLMNOPQRSTUVWXYZ", null).toStringArray(), is(new String[] {"ABCDEFGHIJKLMNOPQRSTUVWXYZ"}));
-        assertThat(new Path("/0123456789", null).toStringArray(), is(new String[] {"0123456789"}));
-        assertThat(new Path("/\uF02F-_.!~\uF02A\'()`@#$^&{\uF05B}\uF05D\uF07C\uF03A;\"<,>?", null).toStringArray(), is(new String[] {"/-_.!~*\'()`@#$^&{[}]|:;\"<,>?"}));
-
-        assertThat(new Path("/abcdefghijklmnopqrstuvwxyz").toStringArray(), is(new String[] {"abcdefghijklmnopqrstuvwxyz"}));
-        assertThat(new Path("/ABCDEFGHIJKLMNOPQRSTUVWXYZ").toStringArray(), is(new String[] {"ABCDEFGHIJKLMNOPQRSTUVWXYZ"}));
-        assertThat(new Path("/0123456789").toStringArray(), is(new String[] {"0123456789"}));
-        assertThat(new Path("/\uF02F-_.!~\uF02A\'()`@#$^&{\uF05B}\uF05D\uF07C\uF03A;\"<,>?").toStringArray(), is(new String[] {"/-_.!~*\'()`@#$^&{[}]|:;\"<,>?"}));
-    }
-
-    @Test
-    public void shouldUseTheJsr283EncoderForTheDefaultEncoder() {
-        assertThat(Path.DEFAULT_ENCODER, is(sameInstance(Path.JSR283_ENCODER)));
-        assertThat(Path.DEFAULT_ENCODER, is(instanceOf(Jsr283Encoder.class)));
-    }
-
-    @Test
-    public void shouldReturnEmptyIteratorForRootPath() {
-        assertThat(Path.ROOT.iterator().hasNext(), is(false));
-    }
-
-    @Test( expected = UnsupportedOperationException.class )
-    public void shouldReturnUnmodifiableList() {
-        validPath.toList().remove(1);
-    }
-
-    @Test
-    public void shouldReturnEquivalentListAndArray() {
-        List<Path.Segment> list = validPath.toList();
-        Path.Segment[] array = validPath.toArray();
-        assertThat(list.size(), is(validPath.size()));
-        assertThat(array.length, is(validPath.size()));
-        assertThat(list.toArray(), is(equalTo((Object[])array)));
-    }
-
-    @Test
-    public void shouldConsiderRootToHaveNoElements() {
-        assertThat(Path.ROOT.isRoot(), is(true));
-        assertThat(Path.ROOT.size(), is(0));
-        assertThat(Path.ROOT.toArray(), is(new Path.Segment[] {}));
-        assertThat(Path.ROOT.toList(), is((List<Path.Segment>)new ArrayList<Path.Segment>()));
-        assertThat(Path.ROOT.getString(), is("/"));
-        assertThat(Path.ROOT.getString(Path.DEFAULT_ENCODER), is("/"));
-        assertThat(Path.ROOT.getString(Path.JSR283_ENCODER), is("/"));
-        assertThat(Path.ROOT.getString(Path.URL_ENCODER), is("/"));
-        assertThat(new Path("/"), is(Path.ROOT));
-    }
-
-    @Test
-    public void shouldReturnSameObjectWhenGettingParentOfRoot() {
-        assertThat(Path.ROOT.getAncestor(), is(sameInstance(Path.ROOT)));
-    }
-
-    @Test
-    public void shouldUseSameSegmentListInstanceInClone() {
-        assertThat(validPath.clone().toList(), is(sameInstance(validPath.toList())));
-    }
-
-    @Test
-    public void shouldConsiderTwoPathsEqualIfTheyHaveTheSamePathSegments() {
-        assertThat(new Path("/a/b/c"), is(new Path("/a/b/c")));
-        assertThat(new Path("/a/b/c"), is(new Path("/a/b/c/")));
-        assertThat(new Path("/"), is(new Path("/")));
-    }
-
-    @Test
-    public void shouldBeCaseSensitiveInEqualsAndCompareToAndSameAs() {
-        assertThat(new Path("/a/b/c"), is(not(new Path("/a/B/c"))));
-        assertThat(new Path("/a/b/c").isSame(new Path("/a/B/c")), is(false));
-        assertThat(new Path("/a/b/c").equals(new Path("/a/B/c")), is(false));
-        assertThat(new Path("/a/b/c").compareTo(new Path("/a/B/c")) != 0, is(true));
-    }
-
-    @Test
-    public void shouldGetNormalizedPathOfSelfShouldBeSame() {
-        assertThat(new Path(".").getNormalizedPath(), is(new Path(".")));
-        assertThat(new Path("./").getNormalizedPath(), is(new Path(".")));
-        assertThat(new Path("./././").getNormalizedPath(), is(new Path(".")));
-    }
-
-    @Test
-    public void shouldGetNormalizedPathWithParentReferences() {
-        assertThat(new Path("..").getNormalizedPath(), is(new Path("..")));
-        assertThat(new Path("../").getNormalizedPath(), is(new Path("../")));
-        assertThat(new Path("../../../../../..").getNormalizedPath(), is(new Path("../../../../../..")));
-    }
-
-    @Test
-    public void shouldGetRelativePathUsingSelf() {
-        assertThat(validPath.resolve("."), is(sameInstance(validPath)));
-        assertThat(validPath.resolve("././."), is(sameInstance(validPath)));
-    }
-
-    @Test
-    public void shouldResolveRelativePathToParent() {
-        assertThat(validPath.resolve(".."), is(validPath.getAncestor()));
-        assertThat(validPath.resolve("..").toStringArray(), is(new String[] {"a", "b", "c", "d", "e"}));
-    }
-
-    @Test
-    public void shouldResolveRelativePaths() {
-        assertThat(validPath.resolve("../../../../../.."), is(sameInstance(Path.ROOT)));
-        assertThat(validPath.resolve("../.."), is(validPath.getAncestor().getAncestor()));
-        assertThat(validPath.resolve("../..").toStringArray(), is(new String[] {"a", "b", "c", "d"}));
-        assertThat(validPath.resolve("../x/../y/../z/.."), is(validPath.getAncestor()));
-        assertThat(validPath.resolve("../x/../y/../z/..").toStringArray(), is(new String[] {"a", "b", "c", "d", "e"}));
-        assertThat(validPath.resolve("../x").toStringArray(), is(new String[] {"a", "b", "c", "d", "e", "x"}));
-    }
-
-    @Test( expected = InvalidPathException.class )
-    public void shouldNotResolveRelativePathWithMoreParentReferencesThanThePath() {
-        validPath.resolve("../../../../../../..");
-    }
-
-    @Test
-    public void shouldResolveNonAbsolutePaths() {
-        validPath = new Path("a/b/c");
-        assertThat(validPath.toStringArray(), is(new String[] {"a", "b", "c"}));
-    }
-
-    @Test
-    public void shouldResolveAbsolutePathsWithIndexes() {
-        validPath = new Path("/a/b[3]/c");
-        assertThat(validPath.toStringArray(), is(new String[] {"a", "b[3]", "c"}));
-
-        validPath = new Path("/a/b[3]/c[4]");
-        assertThat(validPath.toStringArray(), is(new String[] {"a", "b[3]", "c[4]"}));
-    }
-
-    @Test
-    public void shouldResolveNonAbsolutePathsWithIndexes() {
-        validPath = new Path("a/b[3]/c");
-        assertThat(validPath.toStringArray(), is(new String[] {"a", "b[3]", "c"}));
-
-        validPath = new Path("a/b[3]/c[4]");
-        assertThat(validPath.toStringArray(), is(new String[] {"a", "b[3]", "c[4]"}));
-    }
-
-    @Test
-    public void shouldReturnRootInstanceForParentOfPathWithOneSegment() {
-        assertThat(new Path("/a").getAncestor(), is(sameInstance(Path.ROOT)));
-    }
-
-    @Test
-    public void shouldNotConsiderPathToBeAncestorOfItself() {
-        assertThat(validPath.isAncestorOf(validPath), is(false));
-        assertThat(validPath.isAncestorOf(validPath.clone()), is(false));
-    }
-
-    @Test
-    public void shouldNotConsiderPathToBeDecendantOfItself() {
-        assertThat(validPath.isDecendantOf(validPath), is(false));
-        assertThat(validPath.isDecendantOf(validPath.clone()), is(false));
-    }
-
-    @Test
-    public void shouldConsiderParentPathTransitivelyToAllBeAncestors() {
-        Path path = validPath;
-        while (!path.isRoot()) {
-            Path parent = path.getAncestor();
-            // Check ancestry ...
-            assertThat(parent.isAncestorOf(validPath), is(true));
-            assertThat(parent.isAncestorOf(path), is(true));
-            assertThat(path.isAncestorOf(parent), is(false));
-            assertThat(validPath.isAncestorOf(parent), is(false));
-
-            assertThat(validPath.isDecendantOf(parent), is(true));
-            assertThat(path.isDecendantOf(parent), is(true));
-            assertThat(parent.isDecendantOf(validPath), is(false));
-            assertThat(parent.isDecendantOf(path), is(false));
-
-            // Check whether the parent is the root ...
-            if (parent.size() == 0) {
-                assertThat(parent, is(sameInstance(Path.ROOT)));
-                assertThat(parent.getAncestor(), is(sameInstance(Path.ROOT)));
-            }
-            assertThat(parent.size() + 1, is(path.size()));
-            path = parent;
-        }
-    }
-
-    @Test
-    public void shouldReturnSameInstanceWhenAppendingNullSegment() {
-        assertThat(validPath.append((String)null), is(sameInstance(validPath)));
-    }
-
-    @Test( expected = InvalidPathException.class )
-    public void shouldFailWhenAppendingBlankSegment() {
-        validPath.append("  \t  ");
-    }
-
-    @Test( expected = InvalidPathException.class )
-    public void shouldFailWhenAppendingEmptySegment() {
-        validPath.append("");
-    }
-
-    @Test( expected = InvalidPathException.class )
-    public void shouldFailWhenAppendingBlankSegmentWithMultipleSegments() {
-        validPath.append("a", "b", "  \t  ");
-    }
-
-    @Test( expected = InvalidPathException.class )
-    public void shouldFailWhenAppendingEmptySegmentWithMultipleSegments() {
-        validPath.append("a", "b", "");
-    }
-
-    @Test
-    public void shouldReturnEquivalentPathsWhetherAppendingMultipleSegmentsOrAppendingMultipleTimes() {
-        assertThat(validPath.append("x", "y", "z"), is(validPath.append("x").append("y").append("z")));
-    }
-
-    @Test
-    public void shouldDecodeSegmentsWhenAppendingWithSpecificTextEncoder() {
-        assertThat(validPath.append("^/ ", Path.JSR283_ENCODER).getString(), is(validPath.getString() + "/^\uF02F "));
-        assertThat(validPath.append("^/", Path.URL_ENCODER).getString(Path.URL_ENCODER), is(validPath.getString(Path.URL_ENCODER) + "/%5e%2f"));
-    }
-
-    @Test( expected = InvalidPathException.class )
-    public void shouldNotDecodeSegmentsWhenAppendingWithoutSpecificTextEncoder() {
-        validPath.append("^/ ");
-    }
-
-    @Test
-    public void shouldOrderPathsCorrectly() {
-        List<Path> paths = new ArrayList<Path>();
-        paths.add(new Path("/a"));
-        paths.add(new Path("/a/b"));
-        paths.add(new Path("/a/b/alpha"));
-        paths.add(new Path("/a/b/beta"));
-        paths.add(new Path("/a/b/jcr:mixinTypes"));
-        paths.add(new Path("/a/b/jcr:name"));
-        paths.add(new Path("/a/b/jcr:primaryType"));
-        paths.add(new Path("/a/c[1]"));
-        paths.add(new Path("/a/c[1]/alpha"));
-        paths.add(new Path("/a/c[1]/beta"));
-        paths.add(new Path("/a/c[1]/jcr:mixinTypes"));
-        paths.add(new Path("/a/c[1]/jcr:name"));
-        paths.add(new Path("/a/c[1]/jcr:primaryType"));
-        paths.add(new Path("/a/c[2]"));
-        paths.add(new Path("/a/c[2]/alpha"));
-        paths.add(new Path("/a/c[2]/beta"));
-        paths.add(new Path("/a/c[2]/jcr:mixinTypes"));
-        paths.add(new Path("/a/c[2]/jcr:name"));
-        paths.add(new Path("/a/c[2]/jcr:primaryType"));
-
-        // Randomize the list of paths, so we have something to sort ...
-        List<Path> randomizedPaths = new ArrayList<Path>(paths);
-        Collections.shuffle(randomizedPaths);
-        assertThat(randomizedPaths, is(not(paths)));
-
-        // Sort ...
-        Collections.sort(randomizedPaths);
-        assertThat(randomizedPaths, is(paths));
-    }
-
-    @Test
-    public void shouldGetRelativePathToAncestorPath() {
-        assertThat(new Path("/a/b/c/d").relativeTo(new Path("/a/b/c")), is(new Path("d")));
-        assertThat(new Path("/a/b/c/d/e").relativeTo(new Path("/a/b/c")), is(new Path("d/e")));
-    }
-
-    @Test
-    public void shouldGetRelativePathToDecendantPath() {
-        assertThat(new Path("/a/b/c").relativeTo(new Path("/a/b/c/d")), is(new Path("..")));
-        assertThat(new Path("/a/b/c").relativeTo(new Path("/a/b/c/d/e")), is(new Path("../..")));
-    }
-
-    @Test
-    public void shouldGetRelativePathToPathWithCommonAncestor() {
-        assertThat(new Path("/a/b/c/d").relativeTo(new Path("/a/b/e/f")), is(new Path("../../c/d")));
-    }
-
-    @Test
-    public void shouldGetRelativePathToPathWithNoCommonAncestor() {
-        assertThat(new Path("/a/b/c").relativeTo(new Path("/e/f")), is(new Path("../../a/b/c")));
-        assertThat(new Path("/e/f/").relativeTo(new Path("/a/b/c")), is(new Path("../../../e/f")));
-    }
-
-}

Modified: branches/federation/dna-repository/src/main/java/org/jboss/dna/repository/sequencers/SequencerOutputMap.java
===================================================================
--- branches/federation/dna-repository/src/main/java/org/jboss/dna/repository/sequencers/SequencerOutputMap.java	2008-05-22 20:22:50 UTC (rev 184)
+++ branches/federation/dna-repository/src/main/java/org/jboss/dna/repository/sequencers/SequencerOutputMap.java	2008-05-23 16:12:06 UTC (rev 185)
@@ -30,8 +30,10 @@
 import java.util.Map;
 import net.jcip.annotations.Immutable;
 import net.jcip.annotations.NotThreadSafe;
-import org.jboss.dna.common.jcr.Path;
+import org.jboss.dna.common.util.ArgCheck;
 import org.jboss.dna.common.util.StringUtil;
+import org.jboss.dna.spi.graph.Path;
+import org.jboss.dna.spi.graph.PathFactory;
 import org.jboss.dna.spi.sequencers.SequencerOutput;
 
 /**
@@ -47,9 +49,12 @@
 
     private final Map<Path, List<PropertyValue>> data;
     private boolean valuesSorted = true;
+    private final PathFactory pathFactory;
 
-    public SequencerOutputMap() {
+    public SequencerOutputMap( PathFactory pathFactory ) {
+        ArgCheck.isNotNull(pathFactory, "pathFactory");
         this.data = new HashMap<Path, List<PropertyValue>>();
+        this.pathFactory = pathFactory;
     }
 
     /**
@@ -62,7 +67,7 @@
         if (nodePath.endsWith("/")) nodePath = nodePath.replaceFirst("/+$", "");
 
         // Find or create the entry for this node ...
-        Path path = new Path(nodePath);
+        Path path = pathFactory.create(nodePath);
         List<PropertyValue> properties = this.data.get(path);
         if (properties == null) {
             if (values == null || values.length == 0) return; // do nothing
@@ -86,11 +91,11 @@
         if (paths == null || paths.length == 0) {
             setProperty(nodePath, property, (Object[])null);
         } else if (paths.length == 1) {
-            setProperty(nodePath, property, new Path(paths[0]));
+            setProperty(nodePath, property, pathFactory.create(paths[0]));
         } else {
             Path[] pathsArray = new Path[paths.length];
             for (int i = 0; i != paths.length; ++i) {
-                pathsArray[i] = new Path(paths[i]);
+                pathsArray[i] = pathFactory.create(paths[i]);
             }
             setProperty(nodePath, property, (Object[])pathsArray);
         }

Modified: branches/federation/dna-repository/src/main/java/org/jboss/dna/repository/sequencers/SequencingService.java
===================================================================
--- branches/federation/dna-repository/src/main/java/org/jboss/dna/repository/sequencers/SequencingService.java	2008-05-22 20:22:50 UTC (rev 184)
+++ branches/federation/dna-repository/src/main/java/org/jboss/dna/repository/sequencers/SequencingService.java	2008-05-23 16:12:06 UTC (rev 185)
@@ -60,6 +60,8 @@
 import org.jboss.dna.repository.util.JcrTools;
 import org.jboss.dna.repository.util.RepositoryNodePath;
 import org.jboss.dna.repository.util.SessionFactory;
+import org.jboss.dna.spi.graph.NamespaceRegistry;
+import org.jboss.dna.spi.graph.ValueFactories;
 
 /**
  * A sequencing system is used to monitor changes in the content of {@link Repository JCR repositories} and to sequence the
@@ -564,17 +566,19 @@
 
     protected class Context implements ExecutionContext {
 
+        protected final ExecutionContext delegate;
         protected final SessionFactory factory;
         private final Set<Session> sessions = new HashSet<Session>();
         protected final AtomicBoolean closed = new AtomicBoolean(false);
 
         protected Context() {
-            final SessionFactory delegate = SequencingService.this.getExecutionContext().getSessionFactory();
+            this.delegate = SequencingService.this.getExecutionContext();
+            final SessionFactory delegateSessionFactory = this.delegate.getSessionFactory();
             this.factory = new SessionFactory() {
 
                 public Session createSession( String name ) throws RepositoryException {
                     if (closed.get()) throw new IllegalStateException(RepositoryI18n.executionContextHasBeenClosed.text());
-                    Session session = delegate.createSession(name);
+                    Session session = delegateSessionFactory.createSession(name);
                     recordSession(session);
                     return session;
                 }
@@ -588,6 +592,20 @@
         /**
          * {@inheritDoc}
          */
+        public NamespaceRegistry getNamespaceRegistry() {
+            return this.delegate.getNamespaceRegistry();
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public ValueFactories getValueFactories() {
+            return this.delegate.getValueFactories();
+        }
+
+        /**
+         * {@inheritDoc}
+         */
         public SessionFactory getSessionFactory() {
             return this.factory;
         }

Modified: branches/federation/dna-repository/src/main/java/org/jboss/dna/repository/sequencers/StreamSequencerAdapter.java
===================================================================
--- branches/federation/dna-repository/src/main/java/org/jboss/dna/repository/sequencers/StreamSequencerAdapter.java	2008-05-22 20:22:50 UTC (rev 184)
+++ branches/federation/dna-repository/src/main/java/org/jboss/dna/repository/sequencers/StreamSequencerAdapter.java	2008-05-23 16:12:06 UTC (rev 185)
@@ -29,13 +29,15 @@
 import javax.jcr.Property;
 import javax.jcr.RepositoryException;
 import javax.jcr.Session;
-import org.jboss.dna.common.jcr.Path;
 import org.jboss.dna.common.monitor.ProgressMonitor;
 import org.jboss.dna.common.util.Logger;
 import org.jboss.dna.repository.RepositoryI18n;
 import org.jboss.dna.repository.observation.NodeChange;
 import org.jboss.dna.repository.util.ExecutionContext;
 import org.jboss.dna.repository.util.RepositoryNodePath;
+import org.jboss.dna.spi.graph.NamespaceRegistry;
+import org.jboss.dna.spi.graph.Path;
+import org.jboss.dna.spi.graph.PathFactory;
 import org.jboss.dna.spi.sequencers.StreamSequencer;
 
 /**
@@ -88,7 +90,7 @@
             progressMonitor.worked(10);
 
             // Get the binary property with the image content, and build the image metadata from the image ...
-            SequencerOutputMap output = new SequencerOutputMap();
+            SequencerOutputMap output = new SequencerOutputMap(context.getValueFactories().getPathFactory());
             InputStream stream = null;
             Throwable firstError = null;
             ProgressMonitor sequencingMonitor = progressMonitor.createSubtask(50);
@@ -159,7 +161,9 @@
      */
     protected boolean saveOutput( Node outputNode, SequencerOutputMap output, ExecutionContext context ) throws RepositoryException {
         if (output.isEmpty()) return false;
-        final Path outputNodePath = new Path(outputNode.getPath());
+        final PathFactory pathFactory = context.getValueFactories().getPathFactory();
+        final NamespaceRegistry namespaceRegistry = context.getNamespaceRegistry();
+        final Path outputNodePath = pathFactory.create(outputNode.getPath());
 
         // Iterate over the entries in the output, in Path's natural order (shorter paths first and in lexicographical order by
         // prefix and name)
@@ -175,14 +179,14 @@
             Node targetNode = outputNode;
             for (int i = 0, max = relativePath.size(); i != max; ++i) {
                 Path.Segment segment = relativePath.getSegment(i);
-                String qualifiedName = segment.getQualifiedName(true);
+                String qualifiedName = segment.getString(namespaceRegistry);
                 if (targetNode.hasNode(qualifiedName)) {
                     targetNode = targetNode.getNode(qualifiedName);
                 } else {
                     // It doesn't exist, so create it ...
                     if (segment.hasIndex()) {
                         // Use a name without an index ...
-                        qualifiedName = segment.getQualifiedName(false);
+                        qualifiedName = segment.getName().getString(namespaceRegistry);
                     }
                     // We only have the primary type for the final one ...
                     if (i == (max - 1) && primaryType != null) {

Modified: branches/federation/dna-repository/src/main/java/org/jboss/dna/repository/util/ExecutionContext.java
===================================================================
--- branches/federation/dna-repository/src/main/java/org/jboss/dna/repository/util/ExecutionContext.java	2008-05-22 20:22:50 UTC (rev 184)
+++ branches/federation/dna-repository/src/main/java/org/jboss/dna/repository/util/ExecutionContext.java	2008-05-23 16:12:06 UTC (rev 185)
@@ -22,6 +22,8 @@
 package org.jboss.dna.repository.util;
 
 import javax.jcr.Session;
+import org.jboss.dna.spi.graph.NamespaceRegistry;
+import org.jboss.dna.spi.graph.ValueFactories;
 
 /**
  * The context of an execution.
@@ -30,6 +32,18 @@
 public interface ExecutionContext {
 
     /**
+     * Get the namespace registry.
+     * @return the namespace registry; never null
+     */
+    NamespaceRegistry getNamespaceRegistry();
+
+    /**
+     * Get the factories that are to be used to create property values of various types.
+     * @return the set of value factories; never null
+     */
+    ValueFactories getValueFactories();
+
+    /**
      * Get the session factory, which can be used to obtain sessions temporarily for this context. Any session obtained from this
      * factory should be {@link Session#logout() closed} before the execution finishes.
      * @return the session factory

Added: branches/federation/dna-repository/src/main/java/org/jboss/dna/repository/util/JcrNamespaceRegistry.java
===================================================================
--- branches/federation/dna-repository/src/main/java/org/jboss/dna/repository/util/JcrNamespaceRegistry.java	                        (rev 0)
+++ branches/federation/dna-repository/src/main/java/org/jboss/dna/repository/util/JcrNamespaceRegistry.java	2008-05-23 16:12:06 UTC (rev 185)
@@ -0,0 +1,116 @@
+/*
+ * 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.repository.util;
+
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import org.jboss.dna.common.util.ArgCheck;
+import org.jboss.dna.spi.graph.NamespaceException;
+import org.jboss.dna.spi.graph.NamespaceRegistry;
+
+/**
+ * @author Randall Hauch
+ */
+public class JcrNamespaceRegistry implements NamespaceRegistry {
+
+    private final String repositoryWorkspaceName;
+    private final SessionFactory sessionFactory;
+
+    public JcrNamespaceRegistry( SessionFactory sessionFactory, String repositoryWorkspaceName ) {
+        ArgCheck.isNotNull(sessionFactory, "sessionFactory");
+        ArgCheck.isNotNull(repositoryWorkspaceName, "repositoryWorkspaceName");
+        this.repositoryWorkspaceName = repositoryWorkspaceName;
+        this.sessionFactory = sessionFactory;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String getDefaultNamespaceUri() {
+        Session session = null;
+        try {
+            session = this.sessionFactory.createSession(this.repositoryWorkspaceName);
+            return session.getNamespaceURI("");
+        } catch (RepositoryException e) {
+            throw new NamespaceException(e);
+        } finally {
+            if (session != null) {
+                session.logout();
+            }
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String getNamespaceForPrefix( String prefix ) {
+        Session session = null;
+        try {
+            session = this.sessionFactory.createSession(this.repositoryWorkspaceName);
+            return session.getNamespaceURI(prefix);
+        } catch (RepositoryException e) {
+            throw new NamespaceException(e);
+        } finally {
+            if (session != null) {
+                session.logout();
+            }
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String getPrefixForNamespaceUri( String namespaceUri ) {
+        Session session = null;
+        try {
+            session = this.sessionFactory.createSession(this.repositoryWorkspaceName);
+            return session.getNamespacePrefix(namespaceUri);
+        } catch (RepositoryException e) {
+            throw new NamespaceException(e);
+        } finally {
+            if (session != null) {
+                session.logout();
+            }
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean isRegisteredNamespaceUri( String namespaceUri ) {
+        Session session = null;
+        try {
+            session = this.sessionFactory.createSession(this.repositoryWorkspaceName);
+            session.getNamespacePrefix(namespaceUri);
+            return true;
+        } catch (javax.jcr.NamespaceException e) {
+            return false;
+        } catch (RepositoryException e) {
+            throw new NamespaceException(e);
+        } finally {
+            if (session != null) {
+                session.logout();
+            }
+        }
+    }
+
+}


Property changes on: branches/federation/dna-repository/src/main/java/org/jboss/dna/repository/util/JcrNamespaceRegistry.java
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Modified: branches/federation/dna-repository/src/main/java/org/jboss/dna/repository/util/SimpleExecutionContext.java
===================================================================
--- branches/federation/dna-repository/src/main/java/org/jboss/dna/repository/util/SimpleExecutionContext.java	2008-05-22 20:22:50 UTC (rev 184)
+++ branches/federation/dna-repository/src/main/java/org/jboss/dna/repository/util/SimpleExecutionContext.java	2008-05-23 16:12:06 UTC (rev 185)
@@ -22,6 +22,9 @@
 package org.jboss.dna.repository.util;
 
 import org.jboss.dna.common.util.ArgCheck;
+import org.jboss.dna.spi.graph.NamespaceRegistry;
+import org.jboss.dna.spi.graph.ValueFactories;
+import org.jboss.dna.spi.graph.impl.StandardValueFactories;
 
 /**
  * @author Randall Hauch
@@ -30,15 +33,42 @@
 
     private final JcrTools tools = new JcrTools();
     private final SessionFactory sessionFactory;
+    private final ValueFactories valueFactories;
+    private final NamespaceRegistry namespaceRegistry;
 
-    public SimpleExecutionContext( SessionFactory sessionFactory ) {
+    public SimpleExecutionContext( SessionFactory sessionFactory, String repositoryWorkspaceForNamespaceRegistry ) {
+        this(sessionFactory, new JcrNamespaceRegistry(sessionFactory, repositoryWorkspaceForNamespaceRegistry), null);
+    }
+
+    public SimpleExecutionContext( SessionFactory sessionFactory, NamespaceRegistry namespaceRegistry ) {
+        this(sessionFactory, namespaceRegistry, null);
+    }
+
+    public SimpleExecutionContext( SessionFactory sessionFactory, NamespaceRegistry namespaceRegistry, ValueFactories valueFactories ) {
         ArgCheck.isNotNull(sessionFactory, "session factory");
+        ArgCheck.isNotNull(namespaceRegistry, "namespace registry");
         this.sessionFactory = sessionFactory;
+        this.namespaceRegistry = namespaceRegistry;
+        this.valueFactories = valueFactories != null ? valueFactories : new StandardValueFactories(this.namespaceRegistry);
     }
 
     /**
      * {@inheritDoc}
      */
+    public NamespaceRegistry getNamespaceRegistry() {
+        return this.namespaceRegistry;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public ValueFactories getValueFactories() {
+        return this.valueFactories;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
     public SessionFactory getSessionFactory() {
         return this.sessionFactory;
     }

Modified: branches/federation/dna-repository/src/test/java/org/jboss/dna/repository/sequencers/StreamSequencerAdapterTest.java
===================================================================
--- branches/federation/dna-repository/src/test/java/org/jboss/dna/repository/sequencers/StreamSequencerAdapterTest.java	2008-05-22 20:22:50 UTC (rev 184)
+++ branches/federation/dna-repository/src/test/java/org/jboss/dna/repository/sequencers/StreamSequencerAdapterTest.java	2008-05-23 16:12:06 UTC (rev 185)
@@ -47,6 +47,8 @@
 import org.jboss.dna.repository.util.JcrTools;
 import org.jboss.dna.repository.util.RepositoryNodePath;
 import org.jboss.dna.repository.util.SessionFactory;
+import org.jboss.dna.repository.util.SimpleExecutionContext;
+import org.jboss.dna.spi.graph.impl.BasicNamespaceRegistry;
 import org.jboss.dna.spi.sequencers.SequencerOutput;
 import org.jboss.dna.spi.sequencers.StreamSequencer;
 import org.junit.After;
@@ -74,26 +76,17 @@
     public void beforeEach() throws Exception {
         final JcrTools tools = new JcrTools();
         this.tools = tools;
-        sequencerOutput = new SequencerOutputMap();
-        progressMonitor = new RecordingProgressMonitor(StreamSequencerAdapterTest.class.getName());
         final SessionFactory sessionFactory = new SessionFactory() {
 
             public Session createSession( String name ) {
                 return createTestSession();
             }
         };
-        context = new ExecutionContext() {
-
-            public SessionFactory getSessionFactory() {
-                return sessionFactory;
-            }
-
-            public JcrTools getTools() {
-                return tools;
-            }
-        };
+        this.context = new SimpleExecutionContext(sessionFactory, new BasicNamespaceRegistry(), null);
+        this.sequencerOutput = new SequencerOutputMap(this.context.getValueFactories().getPathFactory());
+        this.progressMonitor = new RecordingProgressMonitor(StreamSequencerAdapterTest.class.getName());
         final SequencerOutputMap finalOutput = sequencerOutput;
-        streamSequencer = new StreamSequencer() {
+        this.streamSequencer = new StreamSequencer() {
 
             /**
              * This method always copies the {@link StreamSequencerAdapterTest#sequencerOutput} data into the output {@inheritDoc},

Modified: branches/federation/dna-repository/src/test/java/org/jboss/dna/repository/util/MockExecutionContext.java
===================================================================
--- branches/federation/dna-repository/src/test/java/org/jboss/dna/repository/util/MockExecutionContext.java	2008-05-22 20:22:50 UTC (rev 184)
+++ branches/federation/dna-repository/src/test/java/org/jboss/dna/repository/util/MockExecutionContext.java	2008-05-23 16:12:06 UTC (rev 185)
@@ -28,20 +28,14 @@
 import javax.jcr.Session;
 import org.jboss.dna.common.SystemFailureException;
 import org.jboss.dna.common.jcr.AbstractJcrRepositoryTest;
-import org.jboss.dna.repository.util.ExecutionContext;
-import org.jboss.dna.repository.util.JcrTools;
-import org.jboss.dna.repository.util.SessionFactory;
 
 /**
  * @author Randall Hauch
  */
-public class MockExecutionContext implements ExecutionContext {
+public class MockExecutionContext extends SimpleExecutionContext {
 
-    private JcrTools tools = new JcrTools();
-    private SessionFactory sessionFactory;
-
     public MockExecutionContext( final AbstractJcrRepositoryTest test, final String repositoryName ) {
-        this.sessionFactory = new SessionFactory() {
+        super(new SessionFactory() {
 
             public Session createSession( String name ) throws RepositoryException {
                 assertThat(name, is(repositoryName));
@@ -51,17 +45,7 @@
                     throw new SystemFailureException(e);
                 }
             }
-        };
+        }, repositoryName);
     }
 
-    public SessionFactory getSessionFactory() {
-        return sessionFactory;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public JcrTools getTools() {
-        return tools;
-    }
 }

Modified: branches/federation/dna-spi/src/main/java/org/jboss/dna/spi/SpiI18n.java
===================================================================
--- branches/federation/dna-spi/src/main/java/org/jboss/dna/spi/SpiI18n.java	2008-05-22 20:22:50 UTC (rev 184)
+++ branches/federation/dna-spi/src/main/java/org/jboss/dna/spi/SpiI18n.java	2008-05-23 16:12:06 UTC (rev 185)
@@ -31,21 +31,23 @@
  */
 public final class SpiI18n {
 
-    public static I18n unableToDiscoverPropertyType;
+    public static I18n unableToDiscoverPropertyTypeForNullValue;
     public static I18n errorReadingPropertyValueBytes;
     public static I18n valueJavaTypeNotCompatibleWithPropertyType;
 
     public static I18n errorConvertingBinaryValueToString;
     public static I18n errorCreatingValue;
     public static I18n unableToCreateValue;
-    public static I18n unableToCreatePathFromEmptyString;
     public static I18n validPathMayNotContainEmptySegment;
+    public static I18n noNamespaceRegisteredForPrefix;
 
     public static I18n pathAncestorDegreeIsInvalid;
     public static I18n pathIsAlreadyAbsolute;
     public static I18n pathIsNotAbsolute;
     public static I18n pathIsNotRelative;
     public static I18n pathCannotBeNormalized;
+    public static I18n unbleToCreateSubpathBeginIndexGreaterThanOrEqualToSize;
+    public static I18n unbleToCreateSubpathBeginIndexGreaterThanOrEqualToEndingIndex;
 
     public static I18n invalidQualifiedNameString;
 

Added: branches/federation/dna-spi/src/main/java/org/jboss/dna/spi/graph/NamespaceException.java
===================================================================
--- branches/federation/dna-spi/src/main/java/org/jboss/dna/spi/graph/NamespaceException.java	                        (rev 0)
+++ branches/federation/dna-spi/src/main/java/org/jboss/dna/spi/graph/NamespaceException.java	2008-05-23 16:12:06 UTC (rev 185)
@@ -0,0 +1,60 @@
+/*
+ * 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.spi.graph;
+
+/**
+ * @author Randall Hauch
+ */
+public class NamespaceException extends RuntimeException {
+
+    /**
+     * 
+     */
+    public NamespaceException() {
+    }
+
+    /**
+     * @param message
+     */
+    public NamespaceException( String message ) {
+        super(message);
+
+    }
+
+    /**
+     * @param cause
+     */
+    public NamespaceException( Throwable cause ) {
+        super(cause);
+
+    }
+
+    /**
+     * @param message
+     * @param cause
+     */
+    public NamespaceException( String message, Throwable cause ) {
+        super(message, cause);
+
+    }
+
+}


Property changes on: branches/federation/dna-spi/src/main/java/org/jboss/dna/spi/graph/NamespaceException.java
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Modified: branches/federation/dna-spi/src/main/java/org/jboss/dna/spi/graph/NamespaceRegistry.java
===================================================================
--- branches/federation/dna-spi/src/main/java/org/jboss/dna/spi/graph/NamespaceRegistry.java	2008-05-22 20:22:50 UTC (rev 184)
+++ branches/federation/dna-spi/src/main/java/org/jboss/dna/spi/graph/NamespaceRegistry.java	2008-05-23 16:12:06 UTC (rev 185)
@@ -26,8 +26,36 @@
  */
 public interface NamespaceRegistry {
 
+    /**
+     * Return the namespace URI that is currently mapped to the empty prefix, or null if there is no current default namespace.
+     * @return the namespace URI that represents the default namespace, or null if there is no default namespace
+     */
+    String getDefaultNamespaceUri();
+
+    /**
+     * Get the namespace URI for the supplied prefix.
+     * @param prefix the namespace prefix
+     * @return the namespace URI for the supplied prefix, or null if there is no namespace currently registered to use that prefix
+     * @throws IllegalArgumentException if the prefix is null
+     */
     String getNamespaceForPrefix( String prefix );
 
+    /**
+     * Return the prefix used for the supplied namespace URI. In effect, every URI should have a corresponding prefix, even if
+     * that prefix is automatically generated. Therefore,
+     * @param namespaceUri
+     * @return the prefix currently being used for the namespace; never null but possibly empty for the default namespace
+     * @throws IllegalArgumentException if the namespace URI is null
+     */
     String getPrefixForNamespaceUri( String namespaceUri );
 
+    /**
+     * Return whether there is a registered prefix for the supplied namespace URI. Those namespace URIs that have not been
+     * registered may result in {@link #getPrefixForNamespaceUri(String) automatically generated prefixes}.
+     * @param namespaceUri the namespace URI
+     * @return true if the supplied namespace has been registered with a prefix, or false otherwise
+     * @throws IllegalArgumentException if the namespace URI is null
+     */
+    boolean isRegisteredNamespaceUri( String namespaceUri );
+
 }

Modified: branches/federation/dna-spi/src/main/java/org/jboss/dna/spi/graph/Path.java
===================================================================
--- branches/federation/dna-spi/src/main/java/org/jboss/dna/spi/graph/Path.java	2008-05-22 20:22:50 UTC (rev 184)
+++ branches/federation/dna-spi/src/main/java/org/jboss/dna/spi/graph/Path.java	2008-05-23 16:12:06 UTC (rev 185)
@@ -114,7 +114,7 @@
     /**
      * The index that will be returned for a {@link Segment} that {@link Segment#hasIndex() has no index}.
      */
-    public static final int NO_INDEX = 0;
+    public static final int NO_INDEX = -1;
 
     /**
      * Representation of the segments that occur within a path.
@@ -169,6 +169,29 @@
          * @see #getString()
          */
         public String getString( TextEncoder encoder );
+
+        /**
+         * Get the string form of the segment, using the supplied namespace registry to convert the name's namespace URI to a
+         * prefix. The {@link #DEFAULT_ENCODER default encoder} is used to encode characters in each of the path segments.
+         * @param namespaceRegistry the namespace registry that should be used to obtain the prefix for the
+         * {@link Name#getNamespaceUri() namespace URI} in the segment's {@link #getName() name}
+         * @return the encoded string
+         * @throws IllegalArgumentException if the namespace registry is null
+         * @see #getString(NamespaceRegistry,TextEncoder)
+         */
+        public String getString( NamespaceRegistry namespaceRegistry );
+
+        /**
+         * Get the encoded string form of the segment, using the supplied namespace registry to convert the name's namespace URI
+         * to a prefix and the supplied encoder to encode characters in each of the path segments.
+         * @param namespaceRegistry the namespace registry that should be used to obtain the prefix for the
+         * {@link Name#getNamespaceUri() namespace URI} in the segment's {@link #getName() name}
+         * @param encoder the encoder to use, or null if the {@link #DEFAULT_ENCODER default encoder} should be used
+         * @return the encoded string
+         * @throws IllegalArgumentException if the namespace registry is null
+         * @see #getString(NamespaceRegistry)
+         */
+        public String getString( NamespaceRegistry namespaceRegistry, TextEncoder encoder );
     }
 
     /**
@@ -315,11 +338,21 @@
     public Segment getSegment( int index );
 
     /**
+     * Return a new path consisting of the segments starting at <code>beginIndex</code> index (inclusive). This is equivalent to
+     * calling <code>path.subpath(beginIndex,path.size()-1)</code>.
+     * @param beginIndex the beginning index, inclusive.
+     * @return the specified subpath
+     * @exception IndexOutOfBoundsException if the <code>beginIndex</code> is negative or larger than the length of this
+     * <code>Path</code> object
+     */
+    public Path subpath( int beginIndex );
+
+    /**
      * Return a new path consisting of the segments between the <code>beginIndex</code> index (inclusive) and the
      * <code>endIndex</code> index (exclusive).
      * @param beginIndex the beginning index, inclusive.
      * @param endIndex the ending index, exclusive.
-     * @return the specified substring.
+     * @return the specified subpath
      * @exception IndexOutOfBoundsException if the <code>beginIndex</code> is negative, or <code>endIndex</code> is larger
      * than the length of this <code>Path</code> object, or <code>beginIndex</code> is larger than <code>endIndex</code>.
      */

Modified: branches/federation/dna-spi/src/main/java/org/jboss/dna/spi/graph/PathFactory.java
===================================================================
--- branches/federation/dna-spi/src/main/java/org/jboss/dna/spi/graph/PathFactory.java	2008-05-22 20:22:50 UTC (rev 184)
+++ branches/federation/dna-spi/src/main/java/org/jboss/dna/spi/graph/PathFactory.java	2008-05-23 16:12:06 UTC (rev 185)
@@ -98,6 +98,23 @@
      * @return the segment
      * @throws IllegalArgumentException if the segment name reference is null
      */
+    Path.Segment createSegment( String segmentName );
+
+    /**
+     * Create a path segment given the supplied segment name and index.
+     * @param segmentName the name of the new segment
+     * @param index the index of the new segment
+     * @return the segment
+     * @throws IllegalArgumentException if the segment name reference is null or if the index is invalid
+     */
+    Path.Segment createSegment( String segmentName, int index );
+
+    /**
+     * Create a path segment given the supplied segment name. The resulting segment will have no index.
+     * @param segmentName the name of the segment
+     * @return the segment
+     * @throws IllegalArgumentException if the segment name reference is null
+     */
     Path.Segment createSegment( Name segmentName );
 
     /**

Modified: branches/federation/dna-spi/src/main/java/org/jboss/dna/spi/graph/PropertyType.java
===================================================================
--- branches/federation/dna-spi/src/main/java/org/jboss/dna/spi/graph/PropertyType.java	2008-05-22 20:22:50 UTC (rev 184)
+++ branches/federation/dna-spi/src/main/java/org/jboss/dna/spi/graph/PropertyType.java	2008-05-23 16:12:06 UTC (rev 185)
@@ -26,7 +26,6 @@
 import java.util.Calendar;
 import java.util.Comparator;
 import net.jcip.annotations.Immutable;
-import org.jboss.dna.common.util.StringUtil;
 import org.jboss.dna.spi.SpiI18n;
 import com.sun.tools.javac.tree.Tree.Binary;
 
@@ -36,18 +35,18 @@
 @Immutable
 public enum PropertyType {
 
-    STRING("String", PropertyValues.STRING_COMPARATOR, String.class),
-    BINARY("Binary", PropertyValues.BINARY_COMPARATOR, Binary.class),
-    LONG("Long", PropertyValues.LONG_COMPARATOR, Long.class),
-    DOUBLE("Double", PropertyValues.DOUBLE_COMPARATOR, Double.class),
-    DECIMAL("Decimal", PropertyValues.DECIMAL_COMPARATOR, BigDecimal.class),
-    DATE("Date", PropertyValues.DATE_COMPARATOR, Calendar.class),
-    BOOLEAN("Boolean", PropertyValues.BOOLEAN_COMPARATOR, Boolean.class),
-    NAME("Name", PropertyValues.NAME_COMPARATOR, Name.class),
-    PATH("Path", PropertyValues.PATH_COMPARATOR, Path.class),
-    REFERENCE("Reference", PropertyValues.REFERENCE_COMPARATOR, Reference.class),
-    URI("URI", PropertyValues.URI_COMPARATOR, URI.class),
-    UNDEFINED("undefined", PropertyValues.UNDEFINED_COMPARATOR, Comparable.class);
+    STRING("String", ValueComparators.STRING_COMPARATOR, String.class),
+    BINARY("Binary", ValueComparators.BINARY_COMPARATOR, Binary.class),
+    LONG("Long", ValueComparators.LONG_COMPARATOR, Long.class),
+    DOUBLE("Double", ValueComparators.DOUBLE_COMPARATOR, Double.class),
+    DECIMAL("Decimal", ValueComparators.DECIMAL_COMPARATOR, BigDecimal.class),
+    DATE("Date", ValueComparators.CALENDAR_COMPARATOR, Calendar.class),
+    BOOLEAN("Boolean", ValueComparators.BOOLEAN_COMPARATOR, Boolean.class),
+    NAME("Name", ValueComparators.NAME_COMPARATOR, Name.class),
+    PATH("Path", ValueComparators.PATH_COMPARATOR, Path.class),
+    REFERENCE("Reference", ValueComparators.REFERENCE_COMPARATOR, Reference.class),
+    URI("URI", ValueComparators.URI_COMPARATOR, URI.class),
+    OBJECT("Object", ValueComparators.OBJECT_COMPARATOR, Object.class);
 
     private final String name;
     private final Comparator comparator;
@@ -77,11 +76,12 @@
 
     public static PropertyType discoverType( Object value ) {
         if (value == null) {
-            throw new ValueFormatException(SpiI18n.unableToDiscoverPropertyType.text(value));
+            throw new ValueFormatException(SpiI18n.unableToDiscoverPropertyTypeForNullValue.text());
         }
         for (PropertyType type : PropertyType.values()) {
+            if (type == OBJECT) continue;
             if (type.isInstance(value)) return type;
         }
-        throw new ValueFormatException(SpiI18n.unableToDiscoverPropertyType.text(StringUtil.readableString(value)));
+        return OBJECT;
     }
 }

Deleted: branches/federation/dna-spi/src/main/java/org/jboss/dna/spi/graph/PropertyValues.java
===================================================================
--- branches/federation/dna-spi/src/main/java/org/jboss/dna/spi/graph/PropertyValues.java	2008-05-22 20:22:50 UTC (rev 184)
+++ branches/federation/dna-spi/src/main/java/org/jboss/dna/spi/graph/PropertyValues.java	2008-05-23 16:12:06 UTC (rev 185)
@@ -1,441 +0,0 @@
-/*
- * 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.spi.graph;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.UnsupportedEncodingException;
-import java.math.BigDecimal;
-import java.net.URI;
-import java.util.Calendar;
-import java.util.Comparator;
-import java.util.Date;
-import java.util.UUID;
-import org.jboss.dna.common.util.DateUtil;
-import org.jboss.dna.spi.SpiI18n;
-
-/**
- * @author Randall Hauch
- */
-public class PropertyValues {
-
-    /**
-     * A comparator of string values.
-     */
-    public static final Comparator<String> STRING_COMPARATOR = new Comparator<String>() {
-
-        public int compare( String o1, String o2 ) {
-            if (o1 == o2) return 0;
-            if (o1 == null) return -1;
-            if (o2 == null) return 1;
-            return o1.compareTo(o2);
-        }
-    };
-    /**
-     * A comparator of integer values.
-     */
-    public static final Comparator<Integer> INTEGER_COMPARATOR = new Comparator<Integer>() {
-
-        public int compare( Integer o1, Integer o2 ) {
-            if (o1 == o2) return 0;
-            if (o1 == null) return -1;
-            if (o2 == null) return 1;
-            return o1.compareTo(o2);
-        }
-    };
-    /**
-     * A comparator of long values.
-     */
-    public static final Comparator<Long> LONG_COMPARATOR = new Comparator<Long>() {
-
-        public int compare( Long o1, Long o2 ) {
-            if (o1 == o2) return 0;
-            if (o1 == null) return -1;
-            if (o2 == null) return 1;
-            return o1.compareTo(o2);
-        }
-    };
-    /**
-     * A comparator of float values.
-     */
-    public static final Comparator<Float> FLOAT_COMPARATOR = new Comparator<Float>() {
-
-        public int compare( Float o1, Float o2 ) {
-            if (o1 == o2) return 0;
-            if (o1 == null) return -1;
-            if (o2 == null) return 1;
-            return o1.compareTo(o2);
-        }
-    };
-    /**
-     * A comparator of double values.
-     */
-    public static final Comparator<Double> DOUBLE_COMPARATOR = new Comparator<Double>() {
-
-        public int compare( Double o1, Double o2 ) {
-            if (o1 == o2) return 0;
-            if (o1 == null) return -1;
-            if (o2 == null) return 1;
-            return o1.compareTo(o2);
-        }
-    };
-    /**
-     * A comparator of decimal values.
-     */
-    public static final Comparator<BigDecimal> DECIMAL_COMPARATOR = new Comparator<BigDecimal>() {
-
-        public int compare( BigDecimal o1, BigDecimal o2 ) {
-            if (o1 == o2) return 0;
-            if (o1 == null) return -1;
-            if (o2 == null) return 1;
-            return o1.compareTo(o2);
-        }
-    };
-    /**
-     * A comparator of binary values. Although {@link Binary} is {@link Comparable}, this comparator does not rely upon any
-     * particular Binary implementation. Thus, Binary implementations can use this for their {@link Comparable#compareTo(Object)}
-     * implementation.
-     */
-    public static final Comparator<Binary> BINARY_COMPARATOR = new Comparator<Binary>() {
-
-        public int compare( Binary o1, Binary o2 ) {
-            if (o1 == o2) return 0;
-            if (o1 == null) return -1;
-            if (o2 == null) return 1;
-            try {
-                o1.acquire();
-                try {
-                    o2.acquire();
-                    final long len1 = o1.getSize();
-                    final long len2 = o2.getSize();
-                    if (len1 < len2) return -1;
-                    if (len1 > len2) return 1;
-                    // Otherwise they are the same length ...
-                    InputStream stream1 = null;
-                    InputStream stream2 = null;
-                    try {
-                        stream1 = o1.getStream();
-                        stream2 = o2.getStream();
-                        byte[] buffer1 = new byte[1024];
-                        byte[] buffer2 = new byte[1024];
-                        while (true) {
-                            int numRead1 = stream1.read(buffer1);
-                            if (numRead1 < 0) break;
-                            int numRead2 = stream2.read(buffer2);
-                            if (numRead1 != numRead2) {
-                                throw new ValueFormatException(SpiI18n.errorReadingPropertyValueBytes.text());
-                            }
-                            for (int i = 0; i != numRead1; ++i) {
-                                int diff = buffer1[i] - buffer2[i];
-                                if (diff != 0) return diff;
-                            }
-                        }
-                        return 0;
-                    } catch (IOException e) {
-                        throw new ValueFormatException(SpiI18n.errorReadingPropertyValueBytes.text());
-                    } finally {
-                        if (stream1 != null) {
-                            try {
-                                stream1.close();
-                            } catch (IOException e) {
-                                // do nothing
-                            }
-                        }
-                        if (stream2 != null) {
-                            try {
-                                stream2.close();
-                            } catch (IOException e) {
-                                // do nothing
-                            }
-                        }
-                    }
-                } finally {
-                    o2.release();
-                }
-            } finally {
-                o1.release();
-            }
-        }
-    };
-    /**
-     * A comparator of boolean values.
-     */
-    public static final Comparator<Boolean> BOOLEAN_COMPARATOR = new Comparator<Boolean>() {
-
-        public int compare( Boolean o1, Boolean o2 ) {
-            if (o1 == o2) return 0;
-            if (o1 == null) return -1;
-            if (o2 == null) return 1;
-            return o1.compareTo(o2);
-        }
-    };
-    /**
-     * A comparator of date values.
-     */
-    public static final Comparator<Date> DATE_COMPARATOR = new Comparator<Date>() {
-
-        public int compare( Date o1, Date o2 ) {
-            if (o1 == o2) return 0;
-            if (o1 == null) return -1;
-            if (o2 == null) return 1;
-            return o1.compareTo(o2);
-        }
-    };
-    /**
-     * A comparator of calendar values.
-     */
-    public static final Comparator<Calendar> CALENDAR_COMPARATOR = new Comparator<Calendar>() {
-
-        public int compare( Calendar o1, Calendar o2 ) {
-            if (o1 == o2) return 0;
-            if (o1 == null) return -1;
-            if (o2 == null) return 1;
-            return o1.compareTo(o2);
-        }
-    };
-    /**
-     * A comparator of name values.
-     */
-    public static final Comparator<Name> NAME_COMPARATOR = new Comparator<Name>() {
-
-        public int compare( Name o1, Name o2 ) {
-            if (o1 == o2) return 0;
-            if (o1 == null) return -1;
-            if (o2 == null) return 1;
-            return o1.compareTo(o2);
-        }
-    };
-    /**
-     * A comparator of path values.
-     */
-    public static final Comparator<Path> PATH_COMPARATOR = new Comparator<Path>() {
-
-        public int compare( Path o1, Path o2 ) {
-            if (o1 == o2) return 0;
-            if (o1 == null) return -1;
-            if (o2 == null) return 1;
-            return o1.compareTo(o2);
-        }
-    };
-    /**
-     * A comparator of URI values.
-     */
-    public static final Comparator<URI> URI_COMPARATOR = new Comparator<URI>() {
-
-        public int compare( URI o1, URI o2 ) {
-            if (o1 == o2) return 0;
-            if (o1 == null) return -1;
-            if (o2 == null) return 1;
-            return o1.compareTo(o2);
-        }
-    };
-    /**
-     * A comparator of reference values.
-     */
-    public static final Comparator<Reference> REFERENCE_COMPARATOR = new Comparator<Reference>() {
-
-        public int compare( Reference o1, Reference o2 ) {
-            if (o1 == o2) return 0;
-            if (o1 == null) return -1;
-            if (o2 == null) return 1;
-            return o1.compareTo(o2);
-        }
-    };
-    /**
-     * A comparator of other values.
-     */
-    public static final Comparator<Object> UNDEFINED_COMPARATOR = new Comparator<Object>() {
-
-        @SuppressWarnings( "unchecked" )
-        public int compare( Object o1, Object o2 ) {
-            if (o1 == o2) return 0;
-            if (o1 == null) return -1;
-            if (o2 == null) return 1;
-            PropertyType type1 = PropertyType.discoverType(o1);
-            PropertyType type2 = PropertyType.discoverType(o2);
-            if (type1 == type2) return type1.getComparator().compare(o1, o2);
-            // The types are different but the classes are the same ...
-            if (type1.getDeclaringClass().isAssignableFrom(type2.getDeclaringClass())) {
-                return type1.getComparator().compare(o1, o2);
-            }
-            if (type2.getDeclaringClass().isAssignableFrom(type1.getDeclaringClass())) {
-                return type2.getComparator().compare(o1, o2);
-            }
-            // The types are different and must be converted ...
-            String value1 = PropertyValues.getString(o1);
-            String value2 = PropertyValues.getString(o2);
-            return value1.compareTo(value2);
-        }
-    };
-
-    /**
-     * Get the string representation of the supplied value. This method may perform an conversion that may lose information.
-     * @param value the value to be interpreted as a string
-     * @return the string representation
-     */
-    public static String getString( Object value ) {
-        if (value == null) return null;
-        if (value instanceof String) return (String)value;
-        if (value instanceof Boolean) return getString(((Boolean)value).booleanValue());
-        if (value instanceof Double) return getString(((Double)value).doubleValue());
-        if (value instanceof Long) return getString(((Long)value).longValue());
-        if (value instanceof Date) return getString((Date)value);
-        if (value instanceof Binary) return getString((Binary)value);
-        if (value instanceof Calendar) return getString((Calendar)value);
-        if (value instanceof BigDecimal) return getString((BigDecimal)value);
-        if (value instanceof Name) return getString((Name)value);
-        if (value instanceof Path) return getString((Path)value);
-        if (value instanceof URI) return getString((URI)value);
-        if (value instanceof UUID) return getString((UUID)value);
-        return value.toString();
-    }
-
-    /**
-     * Get the string representation of the supplied boolean value. This method is implemented by calling
-     * {@link Boolean#toString(boolean) Boolean.toString(boolean)}.
-     * @param value the boolean value
-     * @return the string representation
-     */
-    public static String getString( boolean value ) {
-        return Boolean.toString(value);
-    }
-
-    /**
-     * Get the string representation of the supplied double value. This method is implemented by calling
-     * {@link Double#toString(double) Double.toString(double)}.
-     * @param value the double value
-     * @return the string representation
-     */
-    public static String getString( double value ) {
-        return Double.toString(value);
-    }
-
-    /**
-     * Get the string representation of the supplied long value. This method is implemented by calling
-     * {@link Long#toString(long) Long.toString(long)}.
-     * @param value the long value
-     * @return the string representation
-     */
-    public static String getString( long value ) {
-        return Long.toString(value);
-    }
-
-    /**
-     * Get the string representation of the supplied binary value. This method attempts to interpret the binary value as a UTF-8
-     * encoded string.
-     * @param value the binary value
-     * @return the string representation
-     */
-    public static String getString( Binary value ) {
-        if (value == null) return null;
-        try {
-            value.acquire();
-            byte[] bytes = value.getBytes();
-            try {
-                return new String(bytes, "UTF-8");
-            } catch (UnsupportedEncodingException e) {
-                throw new ValueFormatException(SpiI18n.errorConvertingBinaryValueToString.text());
-            }
-        } finally {
-            value.release();
-        }
-    }
-
-    /**
-     * Get the ISO 8601:2004 string representation of the supplied date value.
-     * @param value the date value
-     * @return the string representation
-     */
-    public static String getString( Date value ) {
-        if (value == null) return null;
-        return DateUtil.getDateAsStandardString(value);
-    }
-
-    /**
-     * Get the ISO 8601:2004 string representation of the supplied calendar value.
-     * @param value the calendar value
-     * @return the string representation
-     */
-    public static String getString( Calendar value ) {
-        if (value == null) return null;
-        return getString(value.getTime());
-    }
-
-    /**
-     * Get the string representation of the supplied decimal value.
-     * @param value the decimal value
-     * @return the string representation
-     */
-    public static String getString( BigDecimal value ) {
-        if (value == null) return null;
-        return value.toString();
-    }
-
-    /**
-     * Get the string representation of the supplied name. This method calls {@link Name#getString() Name.getString()}.
-     * @param value the name value
-     * @return the string representation
-     */
-    public static String getString( Name value ) {
-        if (value == null) return null;
-        return value.getString();
-    }
-
-    /**
-     * Get the string representation of the supplied path. This method calls {@link Path#getString() Path.getString()}.
-     * @param value the path value
-     * @return the string representation
-     */
-    public static String getString( Path value ) {
-        if (value == null) return null;
-        return value.getString();
-    }
-
-    /**
-     * Get the string representation of the supplied URI. This method calls {@link URI#toASCIIString() URI.toASCIIString()}.
-     * @param value the URI value
-     * @return the string representation
-     */
-    public static String getString( URI value ) {
-        if (value == null) return null;
-        return value.toASCIIString();
-    }
-
-    /**
-     * Get the string representation of the supplied UUID.
-     * @param value the UUID value
-     * @return the string representation
-     */
-    public static String getString( UUID value ) {
-        if (value == null) return null;
-        return value.toString();
-    }
-
-    /**
-     * Get the string representation of the supplied string value. This method simply returns the supplied value.
-     * @param value the date value
-     * @return the string representation
-     */
-    public static String getString( String value ) {
-        return value;
-    }
-}

Copied: branches/federation/dna-spi/src/main/java/org/jboss/dna/spi/graph/ValueComparators.java (from rev 176, branches/federation/dna-spi/src/main/java/org/jboss/dna/spi/graph/PropertyValues.java)
===================================================================
--- branches/federation/dna-spi/src/main/java/org/jboss/dna/spi/graph/ValueComparators.java	                        (rev 0)
+++ branches/federation/dna-spi/src/main/java/org/jboss/dna/spi/graph/ValueComparators.java	2008-05-23 16:12:06 UTC (rev 185)
@@ -0,0 +1,279 @@
+/*
+ * 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.spi.graph;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.math.BigDecimal;
+import java.net.URI;
+import java.util.Calendar;
+import java.util.Comparator;
+import java.util.Date;
+import org.jboss.dna.spi.SpiI18n;
+import org.jboss.dna.spi.graph.impl.StringValueFactory;
+
+/**
+ * @author Randall Hauch
+ */
+public class ValueComparators {
+
+    /**
+     * A comparator of string values.
+     */
+    public static final Comparator<String> STRING_COMPARATOR = new Comparator<String>() {
+
+        public int compare( String o1, String o2 ) {
+            if (o1 == o2) return 0;
+            if (o1 == null) return -1;
+            if (o2 == null) return 1;
+            return o1.compareTo(o2);
+        }
+    };
+    /**
+     * A comparator of long values.
+     */
+    public static final Comparator<Long> LONG_COMPARATOR = new Comparator<Long>() {
+
+        public int compare( Long o1, Long o2 ) {
+            if (o1 == o2) return 0;
+            if (o1 == null) return -1;
+            if (o2 == null) return 1;
+            return o1.compareTo(o2);
+        }
+    };
+    /**
+     * A comparator of double values.
+     */
+    public static final Comparator<Double> DOUBLE_COMPARATOR = new Comparator<Double>() {
+
+        public int compare( Double o1, Double o2 ) {
+            if (o1 == o2) return 0;
+            if (o1 == null) return -1;
+            if (o2 == null) return 1;
+            return o1.compareTo(o2);
+        }
+    };
+    /**
+     * A comparator of decimal values.
+     */
+    public static final Comparator<BigDecimal> DECIMAL_COMPARATOR = new Comparator<BigDecimal>() {
+
+        public int compare( BigDecimal o1, BigDecimal o2 ) {
+            if (o1 == o2) return 0;
+            if (o1 == null) return -1;
+            if (o2 == null) return 1;
+            return o1.compareTo(o2);
+        }
+    };
+    /**
+     * A comparator of binary values. Although {@link Binary} is {@link Comparable}, this comparator does not rely upon any
+     * particular Binary implementation. Thus, Binary implementations can use this for their {@link Comparable#compareTo(Object)}
+     * implementation.
+     */
+    public static final Comparator<Binary> BINARY_COMPARATOR = new Comparator<Binary>() {
+
+        public int compare( Binary o1, Binary o2 ) {
+            if (o1 == o2) return 0;
+            if (o1 == null) return -1;
+            if (o2 == null) return 1;
+            try {
+                o1.acquire();
+                try {
+                    o2.acquire();
+                    final long len1 = o1.getSize();
+                    final long len2 = o2.getSize();
+                    if (len1 < len2) return -1;
+                    if (len1 > len2) return 1;
+                    // Otherwise they are the same length ...
+                    InputStream stream1 = null;
+                    InputStream stream2 = null;
+                    try {
+                        stream1 = o1.getStream();
+                        stream2 = o2.getStream();
+                        byte[] buffer1 = new byte[1024];
+                        byte[] buffer2 = new byte[1024];
+                        while (true) {
+                            int numRead1 = stream1.read(buffer1);
+                            if (numRead1 < 0) break;
+                            int numRead2 = stream2.read(buffer2);
+                            if (numRead1 != numRead2) {
+                                throw new ValueFormatException(SpiI18n.errorReadingPropertyValueBytes.text());
+                            }
+                            for (int i = 0; i != numRead1; ++i) {
+                                int diff = buffer1[i] - buffer2[i];
+                                if (diff != 0) return diff;
+                            }
+                        }
+                        return 0;
+                    } catch (IOException e) {
+                        throw new ValueFormatException(SpiI18n.errorReadingPropertyValueBytes.text());
+                    } finally {
+                        if (stream1 != null) {
+                            try {
+                                stream1.close();
+                            } catch (IOException e) {
+                                // do nothing
+                            }
+                        }
+                        if (stream2 != null) {
+                            try {
+                                stream2.close();
+                            } catch (IOException e) {
+                                // do nothing
+                            }
+                        }
+                    }
+                } finally {
+                    o2.release();
+                }
+            } finally {
+                o1.release();
+            }
+        }
+    };
+    /**
+     * A comparator of boolean values.
+     */
+    public static final Comparator<Boolean> BOOLEAN_COMPARATOR = new Comparator<Boolean>() {
+
+        public int compare( Boolean o1, Boolean o2 ) {
+            if (o1 == o2) return 0;
+            if (o1 == null) return -1;
+            if (o2 == null) return 1;
+            return o1.compareTo(o2);
+        }
+    };
+    /**
+     * A comparator of date values.
+     */
+    public static final Comparator<Date> DATE_COMPARATOR = new Comparator<Date>() {
+
+        public int compare( Date o1, Date o2 ) {
+            if (o1 == o2) return 0;
+            if (o1 == null) return -1;
+            if (o2 == null) return 1;
+            return o1.compareTo(o2);
+        }
+    };
+    /**
+     * A comparator of calendar values.
+     */
+    public static final Comparator<Calendar> CALENDAR_COMPARATOR = new Comparator<Calendar>() {
+
+        public int compare( Calendar o1, Calendar o2 ) {
+            if (o1 == o2) return 0;
+            if (o1 == null) return -1;
+            if (o2 == null) return 1;
+            return o1.compareTo(o2);
+        }
+    };
+    /**
+     * A comparator of name values.
+     */
+    public static final Comparator<Name> NAME_COMPARATOR = new Comparator<Name>() {
+
+        public int compare( Name o1, Name o2 ) {
+            if (o1 == o2) return 0;
+            if (o1 == null) return -1;
+            if (o2 == null) return 1;
+            return o1.compareTo(o2);
+        }
+    };
+    /**
+     * A comparator of path values.
+     */
+    public static final Comparator<Path> PATH_COMPARATOR = new Comparator<Path>() {
+
+        public int compare( Path o1, Path o2 ) {
+            if (o1 == o2) return 0;
+            if (o1 == null) return -1;
+            if (o2 == null) return 1;
+            return o1.compareTo(o2);
+        }
+    };
+    /**
+     * A comparator of URI values.
+     */
+    public static final Comparator<URI> URI_COMPARATOR = new Comparator<URI>() {
+
+        public int compare( URI o1, URI o2 ) {
+            if (o1 == o2) return 0;
+            if (o1 == null) return -1;
+            if (o2 == null) return 1;
+            return o1.compareTo(o2);
+        }
+    };
+    /**
+     * A comparator of reference values.
+     */
+    public static final Comparator<Reference> REFERENCE_COMPARATOR = new Comparator<Reference>() {
+
+        public int compare( Reference o1, Reference o2 ) {
+            if (o1 == o2) return 0;
+            if (o1 == null) return -1;
+            if (o2 == null) return 1;
+            return o1.compareTo(o2);
+        }
+    };
+    /**
+     * A comparator of other values.
+     */
+    public static final Comparator<Object> OBJECT_COMPARATOR = new Comparator<Object>() {
+
+        @SuppressWarnings( "unchecked" )
+        public int compare( Object o1, Object o2 ) {
+            if (o1 == o2) return 0;
+            if (o1 == null) return -1;
+            if (o2 == null) return 1;
+            PropertyType type1 = PropertyType.discoverType(o1);
+            PropertyType type2 = PropertyType.discoverType(o2);
+            if (type1 != PropertyType.OBJECT && type2 != PropertyType.OBJECT) {
+                if (type1 == type2) return type1.getComparator().compare(o1, o2);
+
+                // The types are different but the classes are the same ...
+                if (type1.getDeclaringClass().isAssignableFrom(type2.getDeclaringClass())) {
+                    return type1.getComparator().compare(o1, o2);
+                }
+                if (type2.getDeclaringClass().isAssignableFrom(type1.getDeclaringClass())) {
+                    return type2.getComparator().compare(o1, o2);
+                }
+            }
+
+            // The types are different and must be converted ...
+            String value1 = getStringValueFactory().create(o1);
+            String value2 = getStringValueFactory().create(o2);
+            return value1.compareTo(value2);
+        }
+    };
+
+    // This is loaded lazily so that there is not a circular dependency between PropertyType (depends on this),
+    // StringValueFactory (depends on PropertyType), and OBJECT_COMPARATOR (which depends on StringValueFactory) ...
+    private static ValueFactory<String> STRING_VALUE_FACTORY;
+
+    protected static final ValueFactory<String> getStringValueFactory() {
+        // No locking is required, because it doesn't matter if we create several instances during initialization ...
+        if (STRING_VALUE_FACTORY == null) {
+            STRING_VALUE_FACTORY = new StringValueFactory(Path.NO_OP_ENCODER);
+        }
+        return STRING_VALUE_FACTORY;
+    }
+}

Modified: branches/federation/dna-spi/src/main/java/org/jboss/dna/spi/graph/ValueFactories.java
===================================================================
--- branches/federation/dna-spi/src/main/java/org/jboss/dna/spi/graph/ValueFactories.java	2008-05-22 20:22:50 UTC (rev 184)
+++ branches/federation/dna-spi/src/main/java/org/jboss/dna/spi/graph/ValueFactories.java	2008-05-23 16:12:06 UTC (rev 185)
@@ -93,7 +93,7 @@
      * Get the value factory for {@link PropertyType#NAME name} properties.
      * @return the factory; never null
      */
-    ValueFactory<Name> getNameFactory();
+    NameFactory getNameFactory();
 
     /**
      * Get the value factory for {@link PropertyType#REFERENCE reference} properties.
@@ -105,7 +105,7 @@
      * Get the value factory for {@link PropertyType#PATH path} properties.
      * @return the factory; never null
      */
-    ValueFactory<Path> getPathFactory();
+    PathFactory getPathFactory();
 
     /**
      * Get the value factory for {@link PropertyType#URI URI} properties.
@@ -113,4 +113,10 @@
      */
     ValueFactory<URI> getUriFactory();
 
+    /**
+     * Get the value factory for {@link PropertyType#OBJECT object} properties.
+     * @return the factory; never null
+     */
+    ValueFactory<Object> getObjectFactory();
+
 }

Modified: branches/federation/dna-spi/src/main/java/org/jboss/dna/spi/graph/impl/BasicName.java
===================================================================
--- branches/federation/dna-spi/src/main/java/org/jboss/dna/spi/graph/impl/BasicName.java	2008-05-22 20:22:50 UTC (rev 184)
+++ branches/federation/dna-spi/src/main/java/org/jboss/dna/spi/graph/impl/BasicName.java	2008-05-23 16:12:06 UTC (rev 185)
@@ -71,6 +71,10 @@
      * {@inheritDoc}
      */
     public String getString( TextEncoder encoder ) {
+        if (this.getNamespaceUri().length() == 0) {
+            if (this.getLocalName().equals(Path.SELF)) return Path.SELF;
+            if (this.getLocalName().equals(Path.PARENT)) return Path.PARENT;
+        }
         if (encoder == null) encoder = Path.DEFAULT_ENCODER;
         return "{" + encoder.encode(this.namespaceUri) + "}" + encoder.encode(this.localName);
     }

Added: branches/federation/dna-spi/src/main/java/org/jboss/dna/spi/graph/impl/BasicNamespaceRegistry.java
===================================================================
--- branches/federation/dna-spi/src/main/java/org/jboss/dna/spi/graph/impl/BasicNamespaceRegistry.java	                        (rev 0)
+++ branches/federation/dna-spi/src/main/java/org/jboss/dna/spi/graph/impl/BasicNamespaceRegistry.java	2008-05-23 16:12:06 UTC (rev 185)
@@ -0,0 +1,124 @@
+/*
+ * 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.spi.graph.impl;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReadWriteLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+import net.jcip.annotations.ThreadSafe;
+import org.jboss.dna.common.util.ArgCheck;
+import org.jboss.dna.spi.graph.NamespaceRegistry;
+
+/**
+ * @author Randall Hauch
+ */
+ at ThreadSafe
+public class BasicNamespaceRegistry implements NamespaceRegistry {
+
+    private final ReadWriteLock registryLock = new ReentrantReadWriteLock();
+    private final Map<String, String> namespacesByPrefix = new HashMap<String, String>();
+    private final Map<String, String> prefixesByNamespace = new HashMap<String, String>();
+
+    /**
+     * 
+     */
+    public BasicNamespaceRegistry() {
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String getNamespaceForPrefix( String prefix ) {
+        ArgCheck.isNotNull(prefix, "prefix");
+        Lock lock = this.registryLock.readLock();
+        try {
+            lock.lock();
+            return this.namespacesByPrefix.get(prefix);
+        } finally {
+            lock.unlock();
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String getPrefixForNamespaceUri( String namespaceUri ) {
+        ArgCheck.isNotNull(namespaceUri, "namespaceUri");
+        Lock lock = this.registryLock.readLock();
+        try {
+            lock.lock();
+            return this.prefixesByNamespace.get(namespaceUri);
+        } finally {
+            lock.unlock();
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean isRegisteredNamespaceUri( String namespaceUri ) {
+        ArgCheck.isNotNull(namespaceUri, "namespaceUri");
+        Lock lock = this.registryLock.readLock();
+        try {
+            lock.lock();
+            return this.prefixesByNamespace.containsKey(namespaceUri);
+        } finally {
+            lock.unlock();
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String getDefaultNamespaceUri() {
+        Lock lock = this.registryLock.readLock();
+        try {
+            lock.lock();
+            return this.namespacesByPrefix.get("");
+        } finally {
+            lock.unlock();
+        }
+    }
+
+    public String register( String prefix, String namespaceUri ) {
+        ArgCheck.isNotNull(prefix, "prefix");
+        ArgCheck.isNotEmpty(namespaceUri, "namespaceUri");
+        String previousNamespaceForPrefix = null;
+        prefix = prefix.trim();
+        namespaceUri = namespaceUri.trim();
+        Lock lock = this.registryLock.writeLock();
+        try {
+            lock.lock();
+            previousNamespaceForPrefix = this.namespacesByPrefix.put(prefix, namespaceUri);
+            String previousPrefix = this.prefixesByNamespace.put(namespaceUri, prefix);
+            if (previousPrefix != null) {
+                this.namespacesByPrefix.remove(previousPrefix);
+            }
+        } finally {
+            lock.unlock();
+        }
+        return previousNamespaceForPrefix;
+    }
+
+}


Property changes on: branches/federation/dna-spi/src/main/java/org/jboss/dna/spi/graph/impl/BasicNamespaceRegistry.java
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Modified: branches/federation/dna-spi/src/main/java/org/jboss/dna/spi/graph/impl/BasicPath.java
===================================================================
--- branches/federation/dna-spi/src/main/java/org/jboss/dna/spi/graph/impl/BasicPath.java	2008-05-22 20:22:50 UTC (rev 184)
+++ branches/federation/dna-spi/src/main/java/org/jboss/dna/spi/graph/impl/BasicPath.java	2008-05-23 16:12:06 UTC (rev 185)
@@ -44,12 +44,12 @@
 @Immutable
 public class BasicPath implements Path {
 
-    public static final Path ROOT = new BasicPath(null, true);
+    private static final List<Segment> EMPTY_SEGMENTS = Collections.emptyList();
 
+    public static final Path ROOT = new BasicPath(EMPTY_SEGMENTS, true);
+
     protected static final Path SELF_PATH = new BasicPath(Collections.singletonList(BasicPathSegment.SELF_SEGMENT), false);
 
-    private static final List<Segment> EMPTY_SEGMENTS = Collections.emptyList();
-
     private final List<Segment> segments;
     private final boolean absolute;
     private final boolean normalized;
@@ -60,9 +60,10 @@
      * @param absolute true if this path is absolute, or false otherwise
      */
     public BasicPath( List<Segment> segments, boolean absolute ) {
-        this.segments = segments != null && segments.size() > 0 ? Collections.unmodifiableList(segments) : EMPTY_SEGMENTS;
+        ArgCheck.isNotNull(segments, "segments");
+        this.segments = segments.isEmpty() ? EMPTY_SEGMENTS : Collections.unmodifiableList(segments);
         this.absolute = absolute;
-        this.normalized = isNormalized(segments);
+        this.normalized = isNormalized(this.segments);
     }
 
     protected boolean isNormalized( List<Segment> segments ) {
@@ -87,6 +88,7 @@
     public Path getAncestor( int degree ) {
         ArgCheck.isNonNegative(degree, "degree");
         if (this.isRoot()) return this;
+        if (degree == 0) return this;
         int endIndex = this.segments.size() - degree;
         if (endIndex < 0) {
             String msg = SpiI18n.pathAncestorDegreeIsInvalid.text(this.getString(), Inflector.getInstance().ordinalize(degree));
@@ -112,20 +114,21 @@
      */
     public Path getCommonAncestor( Path that ) {
         if (that == null) return null;
+        if (this.isRoot() || that.isRoot()) return ROOT;
         Path normalizedPath = this.getNormalizedPath();
-        int lastIndex = normalizedPath.size();
+        int lastIndex = 0;
         Iterator<Segment> thisIter = normalizedPath.iterator();
         Iterator<Segment> thatIter = that.getNormalizedPath().iterator();
         while (thisIter.hasNext() && thatIter.hasNext()) {
             Segment thisSeg = thisIter.next();
             Segment thatSeg = thatIter.next();
             if (thisSeg.equals(thatSeg)) {
-                --lastIndex;
+                ++lastIndex;
             } else {
                 break;
             }
         }
-        if (lastIndex <= 0) return ROOT;
+        if (lastIndex == 0) return ROOT;
         return normalizedPath.subpath(0, lastIndex);
     }
 
@@ -146,12 +149,11 @@
         for (Segment segment : segments) {
             if (segment.isSelfReference()) continue;
             if (segment.isParentReference()) {
-                if (newSegments.size() <= 0) {
+                if (newSegments.isEmpty()) {
                     if (this.isAbsolute()) {
                         throw new InvalidPathException(CommonI18n.pathCannotBeNormalized.text(this));
                     }
-                }
-                if (newSegments.size() > 0 && !newSegments.getLast().isParentReference()) {
+                } else if (!newSegments.getLast().isParentReference()) {
                     newSegments.removeLast();
                     continue;
                 }
@@ -241,7 +243,7 @@
             }
             assert segment != null;
             if (namespaceRegistry != null) {
-                sb.append(segment.getString(encoder));
+                sb.append(segment.getString(namespaceRegistry, encoder));
             } else {
                 sb.append(segment.getString(encoder));
             }
@@ -416,8 +418,31 @@
     /**
      * {@inheritDoc}
      */
+    public Path subpath( int beginIndex ) {
+        if (beginIndex == 0) return this;
+        int size = size();
+        if (beginIndex >= size) {
+            throw new IndexOutOfBoundsException(SpiI18n.unbleToCreateSubpathBeginIndexGreaterThanOrEqualToSize.text(beginIndex, size));
+        }
+        if (size == 0) return ROOT;
+        return new BasicPath(this.segments.subList(beginIndex, size), this.isAbsolute());
+    }
+
+    /**
+     * {@inheritDoc}
+     */
     public Path subpath( int beginIndex, int endIndex ) {
-        if (beginIndex == 0 && endIndex == 0) return ROOT;
+        int size = size();
+        if (beginIndex == 0) {
+            if (endIndex == 0) return ROOT;
+            if (endIndex == size) return this;
+        }
+        if (beginIndex >= size) {
+            throw new IndexOutOfBoundsException(SpiI18n.unbleToCreateSubpathBeginIndexGreaterThanOrEqualToSize.text(beginIndex, size));
+        }
+        if (beginIndex > endIndex) {
+            throw new IndexOutOfBoundsException(SpiI18n.unbleToCreateSubpathBeginIndexGreaterThanOrEqualToEndingIndex.text(beginIndex, endIndex));
+        }
         // This reuses the same list, so it's pretty efficient ...
         return new BasicPath(this.segments.subList(beginIndex, endIndex), this.isAbsolute());
     }

Modified: branches/federation/dna-spi/src/main/java/org/jboss/dna/spi/graph/impl/BasicPathSegment.java
===================================================================
--- branches/federation/dna-spi/src/main/java/org/jboss/dna/spi/graph/impl/BasicPathSegment.java	2008-05-22 20:22:50 UTC (rev 184)
+++ branches/federation/dna-spi/src/main/java/org/jboss/dna/spi/graph/impl/BasicPathSegment.java	2008-05-23 16:12:06 UTC (rev 185)
@@ -25,6 +25,7 @@
 import org.jboss.dna.common.text.TextEncoder;
 import org.jboss.dna.common.util.ArgCheck;
 import org.jboss.dna.spi.graph.Name;
+import org.jboss.dna.spi.graph.NamespaceRegistry;
 import org.jboss.dna.spi.graph.Path;
 
 /**
@@ -55,9 +56,9 @@
      */
     public BasicPathSegment( Name name, int index ) {
         ArgCheck.isNotNull(name, "name");
-        ArgCheck.isNonNegative(index, "index");
+        ArgCheck.isNotLessThan(index, Path.NO_INDEX, "index");
         this.name = name;
-        this.index = index;
+        this.index = (this.isSelfReference() || this.isParentReference()) ? Path.NO_INDEX : index;
     }
 
     /**
@@ -85,14 +86,14 @@
      * {@inheritDoc}
      */
     public boolean isParentReference() {
-        return this.hasIndex() == false && this.name.getNamespaceUri().length() == 0 && this.name.getLocalName().equals(Path.PARENT);
+        return this.name.getNamespaceUri().length() == 0 && this.name.getLocalName().equals(Path.PARENT);
     }
 
     /**
      * {@inheritDoc}
      */
     public boolean isSelfReference() {
-        return this.hasIndex() == false && this.name.getNamespaceUri().length() == 0 && this.name.getLocalName().equals(Path.SELF);
+        return this.name.getNamespaceUri().length() == 0 && this.name.getLocalName().equals(Path.SELF);
     }
 
     /**
@@ -122,7 +123,7 @@
         if (obj instanceof Path.Segment) {
             Path.Segment that = (Path.Segment)obj;
             if (!this.getName().equals(that.getName())) return false;
-            return this.getIndex() != that.getIndex();
+            return this.getIndex() == that.getIndex();
         }
         return false;
     }
@@ -157,4 +158,24 @@
         return encodedName;
     }
 
+    /**
+     * {@inheritDoc}
+     */
+    public String getString( NamespaceRegistry namespaceRegistry ) {
+        return getString(namespaceRegistry, Path.DEFAULT_ENCODER);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String getString( NamespaceRegistry namespaceRegistry, TextEncoder encoder ) {
+        ArgCheck.isNotNull(namespaceRegistry, "namespaceRegistry");
+        if (encoder == null) encoder = Path.DEFAULT_ENCODER;
+        String encodedName = this.getName().getString(namespaceRegistry, encoder);
+        if (this.hasIndex()) {
+            return encodedName + "[" + this.getIndex() + "]";
+        }
+        return encodedName;
+    }
+
 }

Modified: branches/federation/dna-spi/src/main/java/org/jboss/dna/spi/graph/impl/InMemoryBinary.java
===================================================================
--- branches/federation/dna-spi/src/main/java/org/jboss/dna/spi/graph/impl/InMemoryBinary.java	2008-05-22 20:22:50 UTC (rev 184)
+++ branches/federation/dna-spi/src/main/java/org/jboss/dna/spi/graph/impl/InMemoryBinary.java	2008-05-23 16:12:06 UTC (rev 185)
@@ -29,7 +29,7 @@
 import net.jcip.annotations.Immutable;
 import org.jboss.dna.common.util.ArgCheck;
 import org.jboss.dna.spi.graph.Binary;
-import org.jboss.dna.spi.graph.PropertyValues;
+import org.jboss.dna.spi.graph.ValueComparators;
 
 /**
  * An implementation of {@link Binary} that keeps the binary data in-memory.
@@ -84,7 +84,7 @@
      * {@inheritDoc}
      */
     public int compareTo( Binary o ) {
-        return PropertyValues.BINARY_COMPARATOR.compare(this, o);
+        return ValueComparators.BINARY_COMPARATOR.compare(this, o);
     }
 
     /**

Modified: branches/federation/dna-spi/src/main/java/org/jboss/dna/spi/graph/impl/NameValueFactory.java
===================================================================
--- branches/federation/dna-spi/src/main/java/org/jboss/dna/spi/graph/impl/NameValueFactory.java	2008-05-22 20:22:50 UTC (rev 184)
+++ branches/federation/dna-spi/src/main/java/org/jboss/dna/spi/graph/impl/NameValueFactory.java	2008-05-23 16:12:06 UTC (rev 185)
@@ -36,6 +36,7 @@
 import org.jboss.dna.spi.SpiI18n;
 import org.jboss.dna.spi.graph.Name;
 import org.jboss.dna.spi.graph.NameFactory;
+import org.jboss.dna.spi.graph.NamespaceException;
 import org.jboss.dna.spi.graph.NamespaceRegistry;
 import org.jboss.dna.spi.graph.Path;
 import org.jboss.dna.spi.graph.PropertyType;
@@ -83,8 +84,8 @@
             // First see whether the value fits the internal pattern ...
             Matcher matcher = FULLY_QUALIFIED_NAME_PATTERN.matcher(value);
             if (matcher.matches()) {
-                String namespaceUri = matcher.group(2);
-                String localName = matcher.group(3);
+                String namespaceUri = matcher.group(1);
+                String localName = matcher.group(2);
                 // Decode the parts ...
                 namespaceUri = decoder.decode(namespaceUri);
                 localName = decoder.decode(localName);
@@ -93,15 +94,20 @@
             // Second, see whether the value fits the prefixed name pattern ...
             matcher = PREFIXED_NAME_PATTERN.matcher(value);
             if (matcher.matches()) {
-                String prefix = matcher.group(1);
-                String localName = matcher.group(2);
+                String prefix = matcher.group(2);
+                String localName = matcher.group(3);
                 // Decode the parts ...
                 prefix = decoder.decode(prefix);
                 localName = decoder.decode(localName);
                 // Look for a namespace match ...
-                String namespaceUri = this.namespaceRegistry.getNamespaceForPrefix(prefix);
-                // If no namespace is found, use the prefix ...
-                if (namespaceUri == null) namespaceUri = prefix;
+                String namespaceUri = "";
+                if (prefix != null) {
+                    namespaceUri = this.namespaceRegistry.getNamespaceForPrefix(prefix);
+                    // Fail if no namespace is found ...
+                    if (namespaceUri == null) {
+                        throw new NamespaceException(SpiI18n.noNamespaceRegisteredForPrefix.text(prefix));
+                    }
+                }
                 return new BasicName(namespaceUri, localName);
             }
         } catch (Throwable t) {

Added: branches/federation/dna-spi/src/main/java/org/jboss/dna/spi/graph/impl/ObjectValueFactory.java
===================================================================
--- branches/federation/dna-spi/src/main/java/org/jboss/dna/spi/graph/impl/ObjectValueFactory.java	                        (rev 0)
+++ branches/federation/dna-spi/src/main/java/org/jboss/dna/spi/graph/impl/ObjectValueFactory.java	2008-05-23 16:12:06 UTC (rev 185)
@@ -0,0 +1,183 @@
+/*
+ * 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.spi.graph.impl;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+import java.math.BigDecimal;
+import java.net.URI;
+import java.util.Calendar;
+import java.util.Date;
+import net.jcip.annotations.Immutable;
+import org.jboss.dna.common.text.TextEncoder;
+import org.jboss.dna.common.util.ArgCheck;
+import org.jboss.dna.spi.graph.Binary;
+import org.jboss.dna.spi.graph.Name;
+import org.jboss.dna.spi.graph.Path;
+import org.jboss.dna.spi.graph.PropertyType;
+import org.jboss.dna.spi.graph.Reference;
+import org.jboss.dna.spi.graph.ValueFactory;
+import org.jboss.dna.spi.graph.ValueFormatException;
+
+/**
+ * The standard {@link ValueFactory} for {@link PropertyType#OBJECT} values.
+ * @author Randall Hauch
+ */
+ at Immutable
+public class ObjectValueFactory extends AbstractValueFactory<Object> {
+
+    private final ValueFactory<Binary> binaryValueFactory;
+
+    public ObjectValueFactory( TextEncoder encoder, ValueFactory<String> stringValueFactory, ValueFactory<Binary> binaryValueFactory ) {
+        super(PropertyType.OBJECT, encoder, stringValueFactory);
+        ArgCheck.isNotNull(binaryValueFactory, "binaryValueFactory");
+        this.binaryValueFactory = binaryValueFactory;
+    }
+
+    /**
+     * @return binaryValueFactory
+     */
+    protected ValueFactory<Binary> getBinaryValueFactory() {
+        return this.binaryValueFactory;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Object create( String value ) {
+        return this.getStringValueFactory().create(value);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Object create( String value, TextEncoder decoder ) {
+        return this.getStringValueFactory().create(value, decoder);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Object create( int value ) {
+        return Integer.valueOf(value);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Object create( long value ) {
+        return Long.valueOf(value);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Object create( boolean value ) {
+        return Boolean.valueOf(value);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Object create( float value ) {
+        return Float.valueOf(value);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Object create( double value ) {
+        return Double.valueOf(value);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Object create( BigDecimal value ) {
+        return value;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Object create( Calendar value ) {
+        return value;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Object create( Date value ) {
+        return value;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Object create( Name value ) {
+        return value;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Object create( Path value ) {
+        return value;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Object create( Reference value ) {
+        return value;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Object create( URI value ) {
+        return value;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Object create( byte[] value ) throws ValueFormatException {
+        return getBinaryValueFactory().create(value);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Object create( InputStream stream, int approximateLength ) throws IOException {
+        return getBinaryValueFactory().create(stream, approximateLength);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Object create( Reader reader, int approximateLength ) throws IOException {
+        return getBinaryValueFactory().create(reader, approximateLength);
+    }
+
+}


Property changes on: branches/federation/dna-spi/src/main/java/org/jboss/dna/spi/graph/impl/ObjectValueFactory.java
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Modified: branches/federation/dna-spi/src/main/java/org/jboss/dna/spi/graph/impl/PathValueFactory.java
===================================================================
--- branches/federation/dna-spi/src/main/java/org/jboss/dna/spi/graph/impl/PathValueFactory.java	2008-05-22 20:22:50 UTC (rev 184)
+++ branches/federation/dna-spi/src/main/java/org/jboss/dna/spi/graph/impl/PathValueFactory.java	2008-05-23 16:12:06 UTC (rev 185)
@@ -32,10 +32,10 @@
 import java.util.List;
 import java.util.regex.Pattern;
 import net.jcip.annotations.Immutable;
-import org.jboss.dna.common.jcr.InvalidPathException;
 import org.jboss.dna.common.text.TextEncoder;
 import org.jboss.dna.common.util.ArgCheck;
 import org.jboss.dna.spi.SpiI18n;
+import org.jboss.dna.spi.graph.InvalidPathException;
 import org.jboss.dna.spi.graph.Name;
 import org.jboss.dna.spi.graph.Path;
 import org.jboss.dna.spi.graph.PathFactory;
@@ -79,7 +79,7 @@
     private final ValueFactory<Name> nameValueFactory;
 
     public PathValueFactory( TextEncoder encoder, ValueFactory<String> stringValueFactory, ValueFactory<Name> nameValueFactory ) {
-        super(PropertyType.NAME, encoder, stringValueFactory);
+        super(PropertyType.PATH, encoder, stringValueFactory);
         ArgCheck.isNotNull(nameValueFactory, "nameValueFactory");
         this.nameValueFactory = nameValueFactory;
     }
@@ -108,7 +108,7 @@
         int length = trimmedValue.length();
         boolean absolute = false;
         if (length == 0) {
-            throw new ValueFormatException(SpiI18n.unableToCreatePathFromEmptyString.text());
+            return BasicPath.ROOT;
         }
 
         // Remove the leading delimiter ...
@@ -123,12 +123,15 @@
             length = trimmedValue.length();
         }
         if (length == 0) {
-            throw new ValueFormatException(SpiI18n.unableToCreatePathFromEmptyString.text());
+            return BasicPath.ROOT;
         }
 
         // Parse the path into its segments ...
         List<Segment> segments = new ArrayList<Segment>();
         String[] pathSegments = DELIMITER_PATTERN.split(trimmedValue);
+        if (pathSegments.length == 0) {
+            throw new InvalidPathException(SpiI18n.validPathMayNotContainEmptySegment.text(value));
+        }
         assert pathSegments.length != 0;
         for (String segment : pathSegments) {
             assert segment != null;
@@ -345,6 +348,22 @@
     /**
      * {@inheritDoc}
      */
+    public Segment createSegment( String segmentName ) {
+        ArgCheck.isNotNull(segmentName, "segment name");
+        return new BasicPathSegment(this.nameValueFactory.create(segmentName));
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Segment createSegment( String segmentName, int index ) {
+        ArgCheck.isNotNull(segmentName, "segment name");
+        return new BasicPathSegment(this.nameValueFactory.create(segmentName), index);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
     public Path create( Reference value ) throws ValueFormatException {
         throw new ValueFormatException(SpiI18n.unableToCreateValue.text(getPropertyType().getName(), Reference.class.getSimpleName(), value));
     }

Modified: branches/federation/dna-spi/src/main/java/org/jboss/dna/spi/graph/impl/StandardValueFactories.java
===================================================================
--- branches/federation/dna-spi/src/main/java/org/jboss/dna/spi/graph/impl/StandardValueFactories.java	2008-05-22 20:22:50 UTC (rev 184)
+++ branches/federation/dna-spi/src/main/java/org/jboss/dna/spi/graph/impl/StandardValueFactories.java	2008-05-23 16:12:06 UTC (rev 185)
@@ -29,13 +29,12 @@
 import java.util.Iterator;
 import java.util.Map;
 import net.jcip.annotations.Immutable;
-import org.jboss.dna.common.SystemFailureException;
 import org.jboss.dna.common.text.TextEncoder;
 import org.jboss.dna.common.util.ArgCheck;
 import org.jboss.dna.spi.graph.Binary;
-import org.jboss.dna.spi.graph.Name;
+import org.jboss.dna.spi.graph.NameFactory;
 import org.jboss.dna.spi.graph.NamespaceRegistry;
-import org.jboss.dna.spi.graph.Path;
+import org.jboss.dna.spi.graph.PathFactory;
 import org.jboss.dna.spi.graph.PropertyType;
 import org.jboss.dna.spi.graph.Reference;
 import org.jboss.dna.spi.graph.ValueFactories;
@@ -56,12 +55,16 @@
     private final ValueFactory<BigDecimal> decimalFactory;
     private final ValueFactory<Double> doubleFactory;
     private final ValueFactory<Long> longFactory;
-    private final ValueFactory<Name> nameFactory;
-    private final ValueFactory<Path> pathFactory;
+    private final NameFactory nameFactory;
+    private final PathFactory pathFactory;
     private final ValueFactory<Reference> referenceFactory;
     private final ValueFactory<URI> uriFactory;
+    private final ValueFactory<Object> objectFactory;
     private final Map<PropertyType, ValueFactory<?>> factories;
 
+    private final NamespaceRegistry namespaceRegistry;
+    private final TextEncoder encoder;
+
     /**
      * Create a standard set of value factories, using the {@link ValueFactory#DEFAULT_ENCODER default encoder/decoder}.
      * @param namespaceRegistry the namespace registry
@@ -80,7 +83,9 @@
      * @throws IllegalArgumentException if the namespace registry is null
      */
     public StandardValueFactories( NamespaceRegistry namespaceRegistry, TextEncoder encoder, ValueFactory<?>... extraFactories ) {
-        if (encoder == null) encoder = ValueFactory.DEFAULT_ENCODER;
+        ArgCheck.isNotNull(namespaceRegistry, "namespaceRegistry");
+        this.namespaceRegistry = namespaceRegistry;
+        this.encoder = encoder != null ? encoder : ValueFactory.DEFAULT_ENCODER;
         Map<PropertyType, ValueFactory<?>> factories = new HashMap<PropertyType, ValueFactory<?>>();
 
         // Put the extra factories into the map first ...
@@ -90,23 +95,19 @@
         }
 
         // Now assign the members, using the factories in the map or (if null) the supplied default ...
-        this.stringFactory = getFactory(factories, new StringValueFactory(encoder));
-        this.binaryFactory = getFactory(factories, new InMemoryBinaryValueFactory(encoder, this.stringFactory));
-        this.booleanFactory = getFactory(factories, new BooleanValueFactory(encoder, this.stringFactory));
-        this.dateFactory = getFactory(factories, new DateValueFactory(encoder, this.stringFactory));
-        this.decimalFactory = getFactory(factories, new DecimalValueFactory(encoder, this.stringFactory));
-        this.doubleFactory = getFactory(factories, new DoubleValueFactory(encoder, this.stringFactory));
-        this.longFactory = getFactory(factories, new LongValueFactory(encoder, this.stringFactory));
-        this.nameFactory = getFactory(factories, new NameValueFactory(namespaceRegistry, encoder, this.stringFactory));
-        this.pathFactory = getFactory(factories, new PathValueFactory(encoder, this.stringFactory, this.nameFactory));
-        this.referenceFactory = getFactory(factories, new UuidReferenceValueFactory(encoder, this.stringFactory));
-        this.uriFactory = getFactory(factories, new UriValueFactory(namespaceRegistry, encoder, this.stringFactory));
+        this.stringFactory = getFactory(factories, new StringValueFactory(this.encoder));
+        this.binaryFactory = getFactory(factories, new InMemoryBinaryValueFactory(this.encoder, this.stringFactory));
+        this.booleanFactory = getFactory(factories, new BooleanValueFactory(this.encoder, this.stringFactory));
+        this.dateFactory = getFactory(factories, new DateValueFactory(this.encoder, this.stringFactory));
+        this.decimalFactory = getFactory(factories, new DecimalValueFactory(this.encoder, this.stringFactory));
+        this.doubleFactory = getFactory(factories, new DoubleValueFactory(this.encoder, this.stringFactory));
+        this.longFactory = getFactory(factories, new LongValueFactory(this.encoder, this.stringFactory));
+        this.nameFactory = (NameFactory)getFactory(factories, new NameValueFactory(this.namespaceRegistry, this.encoder, this.stringFactory));
+        this.pathFactory = (PathFactory)getFactory(factories, new PathValueFactory(this.encoder, this.stringFactory, this.nameFactory));
+        this.referenceFactory = getFactory(factories, new UuidReferenceValueFactory(this.encoder, this.stringFactory));
+        this.uriFactory = getFactory(factories, new UriValueFactory(this.namespaceRegistry, this.encoder, this.stringFactory));
+        this.objectFactory = getFactory(factories, new ObjectValueFactory(this.encoder, this.stringFactory, this.binaryFactory));
 
-        // Make sure there is a PropertyType.UNDEFINED factory ...
-        if (factories.get(PropertyType.UNDEFINED) == null) {
-            factories.put(PropertyType.UNDEFINED, this.stringFactory);
-        }
-
         // Wrap the factories with an unmodifiable ...
         this.factories = Collections.unmodifiableMap(factories);
     }
@@ -123,6 +124,27 @@
     }
 
     /**
+     * @return encoder
+     */
+    public TextEncoder getTextEncoder() {
+        return this.encoder;
+    }
+
+    /**
+     * @return namespaceRegistry
+     */
+    public NamespaceRegistry getNamespaceRegistry() {
+        return this.namespaceRegistry;
+    }
+
+    /**
+     * @return factories
+     */
+    public Map<PropertyType, ValueFactory<?>> getMapOfValueFactories() {
+        return this.factories;
+    }
+
+    /**
      * {@inheritDoc}
      */
     public ValueFactory<Binary> getBinaryFactory() {
@@ -160,29 +182,6 @@
     /**
      * {@inheritDoc}
      */
-    public ValueFactory<?> getValueFactory( PropertyType type ) {
-        ArgCheck.isNotNull(type, "type");
-        ValueFactory<?> factory = this.factories.get(type);
-        if (factory == null) {
-            // Should never happen
-            throw new SystemFailureException("Unexpected PropertyType");
-        }
-        return factory;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public ValueFactory<?> getValueFactory( Object prototype ) {
-        ArgCheck.isNotNull(prototype, "prototype");
-        PropertyType inferredType = PropertyType.discoverType(prototype);
-        if (inferredType == null) inferredType = PropertyType.STRING;
-        return getValueFactory(inferredType);
-    }
-
-    /**
-     * {@inheritDoc}
-     */
     public ValueFactory<Long> getLongFactory() {
         return this.longFactory;
     }
@@ -190,14 +189,14 @@
     /**
      * {@inheritDoc}
      */
-    public ValueFactory<Name> getNameFactory() {
+    public NameFactory getNameFactory() {
         return this.nameFactory;
     }
 
     /**
      * {@inheritDoc}
      */
-    public ValueFactory<Path> getPathFactory() {
+    public PathFactory getPathFactory() {
         return this.pathFactory;
     }
 
@@ -225,8 +224,33 @@
     /**
      * {@inheritDoc}
      */
+    public ValueFactory<Object> getObjectFactory() {
+        return this.objectFactory;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
     public Iterator<ValueFactory<?>> iterator() {
         return this.factories.values().iterator();
     }
 
+    /**
+     * {@inheritDoc}
+     */
+    public ValueFactory<?> getValueFactory( PropertyType type ) {
+        ArgCheck.isNotNull(type, "type");
+        return this.factories.get(type);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public ValueFactory<?> getValueFactory( Object prototype ) {
+        ArgCheck.isNotNull(prototype, "prototype");
+        PropertyType inferredType = PropertyType.discoverType(prototype);
+        assert inferredType != null;
+        return this.factories.get(inferredType);
+    }
+
 }

Modified: branches/federation/dna-spi/src/main/java/org/jboss/dna/spi/graph/impl/UuidReference.java
===================================================================
--- branches/federation/dna-spi/src/main/java/org/jboss/dna/spi/graph/impl/UuidReference.java	2008-05-22 20:22:50 UTC (rev 184)
+++ branches/federation/dna-spi/src/main/java/org/jboss/dna/spi/graph/impl/UuidReference.java	2008-05-23 16:12:06 UTC (rev 185)
@@ -26,8 +26,8 @@
 import java.io.ObjectOutput;
 import java.util.UUID;
 import net.jcip.annotations.Immutable;
-import org.jboss.dna.common.jcr.Path;
 import org.jboss.dna.common.text.TextEncoder;
+import org.jboss.dna.spi.graph.Path;
 import org.jboss.dna.spi.graph.Reference;
 
 /**

Modified: branches/federation/dna-spi/src/main/resources/org/jboss/dna/spi/SpiI18n.properties
===================================================================
--- branches/federation/dna-spi/src/main/resources/org/jboss/dna/spi/SpiI18n.properties	2008-05-22 20:22:50 UTC (rev 184)
+++ branches/federation/dna-spi/src/main/resources/org/jboss/dna/spi/SpiI18n.properties	2008-05-23 16:12:06 UTC (rev 185)
@@ -1,17 +1,19 @@
-unableToDiscoverPropertyType = Unable to discover property type for {0}
+unableToDiscoverPropertyTypeForNullValue = Unable to discover property type for null value
 errorReadingPropertyValueBytes = Error reading bytes
 valueJavaTypeNotCompatibleWithPropertyType = Value is instance of Java type "{0}" and is not compatible with the "{1}" property type
 
 errorConvertingBinaryValueToString = Error while interpretting binary value as a UTF-8 string
 errorCreatingValue = Error creating {0} value from {1} '{2}'
 unableToCreateValue = Unable to create {0} value from {1} '{2}': undefined type conversion
-unableToCreatePathFromEmptyString = Unable to create a path from an empty string
 validPathMayNotContainEmptySegment = The path '{0}' is not valid because it contains an empty segment
+noNamespaceRegisteredForPrefix = There is no namespace registered for the prefix '{0}'
 
 pathAncestorDegreeIsInvalid = Unable to obtain the {1} ancestor for {0}
 pathIsAlreadyAbsolute = The path {0} is already an absolute path
 pathIsNotAbsolute = The path {0} is not an absolute path
 pathIsNotRelative = The path {0} is not a relative path
 pathCannotBeNormalized = The path {0} is invalid and cannot be normalized
+unbleToCreateSubpathBeginIndexGreaterThanOrEqualToSize = Unable to create subpath: fromIndex({0}) >= size({1})
+unbleToCreateSubpathBeginIndexGreaterThanOrEqualToEndingIndex = Unable to create subpath: fromIndex({0}) >= toIndex({1})
 
 invalidQualifiedNameString = Unable to parse qualified name from "{0}"
\ No newline at end of file

Added: branches/federation/dna-spi/src/test/java/org/jboss/dna/spi/graph/AbstractValueComparatorsTest.java
===================================================================
--- branches/federation/dna-spi/src/test/java/org/jboss/dna/spi/graph/AbstractValueComparatorsTest.java	                        (rev 0)
+++ branches/federation/dna-spi/src/test/java/org/jboss/dna/spi/graph/AbstractValueComparatorsTest.java	2008-05-23 16:12:06 UTC (rev 185)
@@ -0,0 +1,136 @@
+/*
+ * 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.spi.graph;
+
+import static org.hamcrest.core.Is.is;
+import static org.hamcrest.core.IsInstanceOf.instanceOf;
+import static org.hamcrest.core.IsNull.notNullValue;
+import static org.junit.Assert.assertThat;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+import org.jboss.dna.common.util.ArgCheck;
+import org.jboss.dna.spi.graph.impl.BasicNamespaceRegistry;
+import org.jboss.dna.spi.graph.impl.StandardValueFactories;
+import org.junit.Test;
+
+/**
+ * @author Randall Hauch
+ * @param <T>
+ */
+public abstract class AbstractValueComparatorsTest<T> {
+
+    public static final BasicNamespaceRegistry NAMESPACE_REGISTRY = new BasicNamespaceRegistry();
+    public static final ValueFactories VALUE_FACTORIES = new StandardValueFactories(NAMESPACE_REGISTRY);
+
+    protected final Comparator<T> comparator;
+    protected final T[] validNonNullValues;
+
+    protected AbstractValueComparatorsTest( Comparator<T> comparator, T... validNonNullValues ) {
+        ArgCheck.isNotNull(comparator, "comparator");
+        ArgCheck.isNotEmpty(validNonNullValues, "validNonNullValues");
+        this.comparator = comparator;
+        this.validNonNullValues = validNonNullValues;
+    }
+
+    protected Comparator<T> getComparator() {
+        return this.comparator;
+    }
+
+    @Test
+    public void shouldConsiderNullLessThanValidNonNull() {
+        assertThat(comparator.compare(validNonNullValues[0], null) > 0, is(true));
+        assertThat(comparator.compare(null, validNonNullValues[0]) < 0, is(true));
+    }
+
+    @Test
+    public void shouldConsiderTwoNullsToBeEquivalent() {
+        assertThat(comparator.compare(null, null), is(0));
+    }
+
+    @Test
+    public void shouldConsiderSameInstanceToBeEquivalent() {
+        for (T validNonNullValue : validNonNullValues) {
+            assertThat(comparator.compare(validNonNullValue, validNonNullValue), is(0));
+        }
+    }
+
+    protected List<T> getValues( boolean includeNull ) {
+        List<T> values = new ArrayList<T>(validNonNullValues.length);
+        for (T validNonNullValue : validNonNullValues) {
+            assertThat(validNonNullValue, is(notNullValue()));
+            values.add(validNonNullValue);
+        }
+        if (includeNull) values.add(null);
+        return values;
+    }
+
+    protected List<T> getSortedValues( boolean includeNull ) {
+        List<T> values = getValues(includeNull);
+        Collections.sort(values, comparator);
+        return values;
+    }
+
+    // protected void assertSortsSimilarTo( Comparator<T> otherComparator ) {
+    // assertThat(otherComparator, is(notNullValue()));
+    // List<T> values = getValues(true);
+    // List<T> otherValues = getValues(true);
+    // Collections.sort(values, comparator);
+    // Collections.sort(otherValues, comparator);
+    // assertThat(values, is(otherValues));
+    //
+    // values = getValues(false);
+    // otherValues = getValues(false);
+    // Collections.sort(values, comparator);
+    // Collections.sort(otherValues, comparator);
+    // assertThat(values, is(otherValues));
+    // }
+
+    @SuppressWarnings( "unchecked" )
+    @Test
+    public void shouldBeCompatibleWithCompareTo() {
+        List<T> values = getValues(false);
+        Collections.sort(values, comparator);
+        for (int i = 0; i != (values.size() - 1); ++i) {
+            T value1 = values.get(i);
+            T value2 = values.get(i + 1);
+            assertThat(value1, is(instanceOf(Comparable.class)));
+            Comparable<T> comparable1 = (Comparable<T>)value1;
+            int result = comparable1.compareTo(value2);
+            assertThat(result < 0 || result == 0, is(true));
+            assertThat(comparable1.compareTo(value1), is(0));
+        }
+    }
+
+    protected void assertValuesCompareUsing( T value1, T value2 ) {
+        int value1ToValue2 = comparator.compare(value1, value2);
+        int value2ToValue1 = comparator.compare(value2, value1);
+        if (value1ToValue2 == 0) {
+            assertThat(value2ToValue1, is(0));
+        } else if (value1ToValue2 < 0) {
+            assertThat(value2ToValue1 > 0, is(true));
+        } else { // if ( value1ToValue2 > 0 )
+            assertThat(value2ToValue1 < 0, is(true));
+        }
+    }
+}


Property changes on: branches/federation/dna-spi/src/test/java/org/jboss/dna/spi/graph/AbstractValueComparatorsTest.java
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Added: branches/federation/dna-spi/src/test/java/org/jboss/dna/spi/graph/BinaryValueComparatorTest.java
===================================================================
--- branches/federation/dna-spi/src/test/java/org/jboss/dna/spi/graph/BinaryValueComparatorTest.java	                        (rev 0)
+++ branches/federation/dna-spi/src/test/java/org/jboss/dna/spi/graph/BinaryValueComparatorTest.java	2008-05-23 16:12:06 UTC (rev 185)
@@ -0,0 +1,44 @@
+/*
+ * 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.spi.graph;
+
+/**
+ * @author Randall Hauch
+ */
+public class BinaryValueComparatorTest extends AbstractValueComparatorsTest<Binary> {
+
+    private static final ValueFactory<Binary> FACTORY;
+    private static final Binary BINARY1;
+    private static final Binary BINARY2;
+    private static final Binary BINARY3;
+
+    static {
+        FACTORY = VALUE_FACTORIES.getBinaryFactory();
+        BINARY1 = FACTORY.create("This is the binary 1 value");
+        BINARY2 = FACTORY.create("This is the binary 2 value");
+        BINARY3 = FACTORY.create("This is the binary 3 value");
+    }
+
+    public BinaryValueComparatorTest() {
+        super(ValueComparators.BINARY_COMPARATOR, BINARY1, BINARY2, BINARY3);
+    }
+}


Property changes on: branches/federation/dna-spi/src/test/java/org/jboss/dna/spi/graph/BinaryValueComparatorTest.java
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Added: branches/federation/dna-spi/src/test/java/org/jboss/dna/spi/graph/BooleanValueComparatorTest.java
===================================================================
--- branches/federation/dna-spi/src/test/java/org/jboss/dna/spi/graph/BooleanValueComparatorTest.java	                        (rev 0)
+++ branches/federation/dna-spi/src/test/java/org/jboss/dna/spi/graph/BooleanValueComparatorTest.java	2008-05-23 16:12:06 UTC (rev 185)
@@ -0,0 +1,32 @@
+/*
+ * 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.spi.graph;
+
+/**
+ * @author Randall Hauch
+ */
+public class BooleanValueComparatorTest extends AbstractValueComparatorsTest<Boolean> {
+
+    public BooleanValueComparatorTest() {
+        super(ValueComparators.BOOLEAN_COMPARATOR, Boolean.TRUE, Boolean.FALSE);
+    }
+}


Property changes on: branches/federation/dna-spi/src/test/java/org/jboss/dna/spi/graph/BooleanValueComparatorTest.java
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Added: branches/federation/dna-spi/src/test/java/org/jboss/dna/spi/graph/DateValueComparatorTest.java
===================================================================
--- branches/federation/dna-spi/src/test/java/org/jboss/dna/spi/graph/DateValueComparatorTest.java	                        (rev 0)
+++ branches/federation/dna-spi/src/test/java/org/jboss/dna/spi/graph/DateValueComparatorTest.java	2008-05-23 16:12:06 UTC (rev 185)
@@ -0,0 +1,46 @@
+/*
+ * 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.spi.graph;
+
+import java.util.Calendar;
+
+/**
+ * @author Randall Hauch
+ */
+public class DateValueComparatorTest extends AbstractValueComparatorsTest<Calendar> {
+
+    private static final Calendar TODAY = Calendar.getInstance();
+    private static final Calendar YESTERDAY;
+    private static final Calendar TOMORROW;
+
+    static {
+        YESTERDAY = (Calendar)TODAY.clone();
+        YESTERDAY.roll(Calendar.DAY_OF_YEAR, false);
+
+        TOMORROW = (Calendar)TODAY.clone();
+        TOMORROW.roll(Calendar.DAY_OF_YEAR, true);
+    }
+
+    public DateValueComparatorTest() {
+        super(ValueComparators.CALENDAR_COMPARATOR, TODAY, TOMORROW, YESTERDAY);
+    }
+}


Property changes on: branches/federation/dna-spi/src/test/java/org/jboss/dna/spi/graph/DateValueComparatorTest.java
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Added: branches/federation/dna-spi/src/test/java/org/jboss/dna/spi/graph/DecimalValueComparatorTest.java
===================================================================
--- branches/federation/dna-spi/src/test/java/org/jboss/dna/spi/graph/DecimalValueComparatorTest.java	                        (rev 0)
+++ branches/federation/dna-spi/src/test/java/org/jboss/dna/spi/graph/DecimalValueComparatorTest.java	2008-05-23 16:12:06 UTC (rev 185)
@@ -0,0 +1,34 @@
+/*
+ * 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.spi.graph;
+
+import java.math.BigDecimal;
+
+/**
+ * @author Randall Hauch
+ */
+public class DecimalValueComparatorTest extends AbstractValueComparatorsTest<BigDecimal> {
+
+    public DecimalValueComparatorTest() {
+        super(ValueComparators.DECIMAL_COMPARATOR, new BigDecimal(100), new BigDecimal(200.0), new BigDecimal(300.0), new BigDecimal(-1.0), new BigDecimal(0.0));
+    }
+}


Property changes on: branches/federation/dna-spi/src/test/java/org/jboss/dna/spi/graph/DecimalValueComparatorTest.java
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Added: branches/federation/dna-spi/src/test/java/org/jboss/dna/spi/graph/DoubleValueComparatorTest.java
===================================================================
--- branches/federation/dna-spi/src/test/java/org/jboss/dna/spi/graph/DoubleValueComparatorTest.java	                        (rev 0)
+++ branches/federation/dna-spi/src/test/java/org/jboss/dna/spi/graph/DoubleValueComparatorTest.java	2008-05-23 16:12:06 UTC (rev 185)
@@ -0,0 +1,32 @@
+/*
+ * 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.spi.graph;
+
+/**
+ * @author Randall Hauch
+ */
+public class DoubleValueComparatorTest extends AbstractValueComparatorsTest<Double> {
+
+    public DoubleValueComparatorTest() {
+        super(ValueComparators.DOUBLE_COMPARATOR, 100.0d, 200.0d, 300.0d, -1.0d, 0.0d);
+    }
+}


Property changes on: branches/federation/dna-spi/src/test/java/org/jboss/dna/spi/graph/DoubleValueComparatorTest.java
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Added: branches/federation/dna-spi/src/test/java/org/jboss/dna/spi/graph/LongValueComparatorTest.java
===================================================================
--- branches/federation/dna-spi/src/test/java/org/jboss/dna/spi/graph/LongValueComparatorTest.java	                        (rev 0)
+++ branches/federation/dna-spi/src/test/java/org/jboss/dna/spi/graph/LongValueComparatorTest.java	2008-05-23 16:12:06 UTC (rev 185)
@@ -0,0 +1,32 @@
+/*
+ * 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.spi.graph;
+
+/**
+ * @author Randall Hauch
+ */
+public class LongValueComparatorTest extends AbstractValueComparatorsTest<Long> {
+
+    public LongValueComparatorTest() {
+        super(ValueComparators.LONG_COMPARATOR, 100l, 200l, 300l, -1l, 0l);
+    }
+}


Property changes on: branches/federation/dna-spi/src/test/java/org/jboss/dna/spi/graph/LongValueComparatorTest.java
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Added: branches/federation/dna-spi/src/test/java/org/jboss/dna/spi/graph/NameValueComparatorTest.java
===================================================================
--- branches/federation/dna-spi/src/test/java/org/jboss/dna/spi/graph/NameValueComparatorTest.java	                        (rev 0)
+++ branches/federation/dna-spi/src/test/java/org/jboss/dna/spi/graph/NameValueComparatorTest.java	2008-05-23 16:12:06 UTC (rev 185)
@@ -0,0 +1,73 @@
+/*
+ * 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.spi.graph;
+
+import static org.hamcrest.core.Is.is;
+import static org.hamcrest.core.IsNot.not;
+import static org.junit.Assert.assertThat;
+import org.junit.Test;
+
+/**
+ * @author Randall Hauch
+ */
+public class NameValueComparatorTest extends AbstractValueComparatorsTest<Name> {
+
+    private static final ValueFactory<Name> FACTORY;
+    private static final Name NAME1;
+    private static final Name NAME2;
+    private static final Name NAME3;
+    private static final Name NAME4;
+    private static final Name NAME5;
+    private static final Name NAME6;
+
+    static {
+        NAMESPACE_REGISTRY.register("dna", "http://www.jboss.org/dna/namespaces/Test");
+        NAMESPACE_REGISTRY.register("acme", "http://www.acme.com/");
+        NAMESPACE_REGISTRY.register("dna-b", "http://www.jboss.org/dna/namespaces/Test/b");
+        NAMESPACE_REGISTRY.register("dna-c", "http://www.jboss.org/dna/namespaces/TEST");
+        FACTORY = VALUE_FACTORIES.getNameFactory();
+        NAME1 = FACTORY.create("dna:alpha");
+        NAME2 = FACTORY.create("dna:beta");
+        NAME3 = FACTORY.create("acme:beta");
+        NAME4 = FACTORY.create("dna:beta");
+        NAME5 = FACTORY.create("dna:ALPHA");
+        NAME6 = FACTORY.create("dna-c:ALPHA");
+    }
+
+    public NameValueComparatorTest() {
+        super(ValueComparators.NAME_COMPARATOR, NAME1, NAME2, NAME3, NAME4, NAME5, NAME6);
+    }
+
+    @Test
+    public void shouldConsiderNamesWithSameNamespaceUriAndLocalPartToBeComparable() {
+        System.out.println(NAME2);
+        System.out.println(NAME4);
+        assertThat(comparator.compare(NAME2, NAME4), is(0));
+    }
+
+    @Test
+    public void shouldBeCaseSensitive() {
+        assertThat(comparator.compare(NAME2, NAME4), is(0));
+        assertThat(comparator.compare(NAME1, NAME5), is(not(0)));
+        assertThat(comparator.compare(NAME6, NAME5), is(not(0)));
+    }
+}


Property changes on: branches/federation/dna-spi/src/test/java/org/jboss/dna/spi/graph/NameValueComparatorTest.java
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Added: branches/federation/dna-spi/src/test/java/org/jboss/dna/spi/graph/StringValueComparatorTest.java
===================================================================
--- branches/federation/dna-spi/src/test/java/org/jboss/dna/spi/graph/StringValueComparatorTest.java	                        (rev 0)
+++ branches/federation/dna-spi/src/test/java/org/jboss/dna/spi/graph/StringValueComparatorTest.java	2008-05-23 16:12:06 UTC (rev 185)
@@ -0,0 +1,57 @@
+/*
+ * 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.spi.graph;
+
+import static org.hamcrest.core.Is.is;
+import static org.hamcrest.core.IsNot.not;
+import static org.junit.Assert.assertThat;
+import static org.junit.matchers.JUnitMatchers.hasItems;
+import org.junit.Test;
+
+/**
+ * @author Randall Hauch
+ */
+public class StringValueComparatorTest extends AbstractValueComparatorsTest<String> {
+
+    public StringValueComparatorTest() {
+        super(ValueComparators.STRING_COMPARATOR, "valid value 1", "Valid valid 2");
+    }
+
+    @Test
+    public void shouldBeCaseInsensitive() {
+        assertThat(comparator.compare(validNonNullValues[0].toUpperCase(), validNonNullValues[0].toLowerCase()), is(not(0)));
+    }
+
+    @Test
+    public void shouldMatchStringCompareToMethod() {
+        assertThat(comparator.compare(validNonNullValues[0], validNonNullValues[1]), is(validNonNullValues[0].compareTo(validNonNullValues[1])));
+        assertThat(comparator.compare(validNonNullValues[1], validNonNullValues[0]), is(validNonNullValues[1].compareTo(validNonNullValues[0])));
+        assertThat(comparator.compare(validNonNullValues[1], validNonNullValues[1]), is(validNonNullValues[1].compareTo(validNonNullValues[1])));
+        assertThat(comparator.compare(validNonNullValues[0], validNonNullValues[0]), is(validNonNullValues[0].compareTo(validNonNullValues[0])));
+    }
+
+    @Test
+    public void shouldSortValues() {
+        assertThat(getSortedValues(false), hasItems(validNonNullValues[0], validNonNullValues[1]));
+    }
+
+}


Property changes on: branches/federation/dna-spi/src/test/java/org/jboss/dna/spi/graph/StringValueComparatorTest.java
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Added: branches/federation/dna-spi/src/test/java/org/jboss/dna/spi/graph/impl/BasicNameTest.java
===================================================================
--- branches/federation/dna-spi/src/test/java/org/jboss/dna/spi/graph/impl/BasicNameTest.java	                        (rev 0)
+++ branches/federation/dna-spi/src/test/java/org/jboss/dna/spi/graph/impl/BasicNameTest.java	2008-05-23 16:12:06 UTC (rev 185)
@@ -0,0 +1,158 @@
+/*
+ * 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.spi.graph.impl;
+
+import static org.hamcrest.core.Is.is;
+import static org.junit.Assert.assertThat;
+import static org.junit.matchers.JUnitMatchers.containsString;
+import org.jboss.dna.common.text.TextEncoder;
+import org.jboss.dna.spi.graph.Name;
+import org.jboss.dna.spi.graph.Path;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * @author Randall Hauch
+ */
+public class BasicNameTest {
+
+    private BasicNamespaceRegistry namespaceRegistry;
+    private Name name;
+    private String validNamespaceUri;
+    private String validLocalName;
+    private TextEncoder encoder;
+    private String validNamespacePrefix;
+
+    @Before
+    public void beforeEach() throws Exception {
+        this.validNamespaceUri = "http://www.jboss.org/dna";
+        this.validLocalName = "localPart";
+        this.validNamespacePrefix = "dna";
+        this.name = new BasicName(validNamespaceUri, validLocalName);
+        this.encoder = Path.URL_ENCODER;
+        this.namespaceRegistry = new BasicNamespaceRegistry();
+        this.namespaceRegistry.register(validNamespacePrefix, validNamespaceUri);
+    }
+
+    @Test
+    public void shouldAllowNullNamespaceUriInConstructorAndConvertToEmptyString() {
+        name = new BasicName(null, validLocalName);
+        assertThat(name.getNamespaceUri(), is(""));
+    }
+
+    @Test
+    public void shouldAllowEmptyNamespaceUriInConstructor() {
+        name = new BasicName("", validLocalName);
+        assertThat(name.getNamespaceUri(), is(""));
+    }
+
+    @Test
+    public void shouldTrimNamespaceUriInConstructor() {
+        name = new BasicName("  " + validNamespaceUri + "\t \t", validLocalName);
+        assertThat(name.getNamespaceUri(), is(validNamespaceUri.trim()));
+
+        name = new BasicName("  \t  \t", validLocalName);
+        assertThat(name.getNamespaceUri(), is(""));
+    }
+
+    @Test
+    public void shouldAllowNullLocalNameInConstructorAndConvertToEmptyString() {
+        name = new BasicName(validNamespaceUri, null);
+        assertThat(name.getLocalName(), is(""));
+    }
+
+    @Test
+    public void shouldAllowEmptyLocalNameInConstructorAndConvertToEmptyString() {
+        name = new BasicName(validNamespaceUri, "");
+        assertThat(name.getLocalName(), is(""));
+    }
+
+    @Test
+    public void shouldAcceptLocalNameWithColon() {
+        validLocalName = "some:name:with:colons";
+        name = new BasicName(validNamespaceUri, validLocalName);
+        assertThat(name.getLocalName(), is(validLocalName));
+    }
+
+    @Test
+    public void shouldReturnSameHashCodeForNamesWithSameNamespaceUriAndLocalPart() {
+        Name other = new BasicName(name.getNamespaceUri(), name.getLocalName());
+        assertThat(name.hashCode(), is(other.hashCode()));
+    }
+
+    @Test
+    public void shouldConsiderNamesEqualIfTheyHaveTheSameNamespaceUriAndLocalPart() {
+        Name other = new BasicName(name.getNamespaceUri(), name.getLocalName());
+        assertThat(name.equals(other), is(true));
+        assertThat(name.compareTo(other), is(0));
+    }
+
+    @Test
+    public void shouldConsiderSameInstanceEqualToItself() {
+        assertThat(name.equals(name), is(true));
+        assertThat(name.compareTo(name), is(0));
+    }
+
+    @Test( expected = NullPointerException.class )
+    public void shouldNotSupportNullInCompareTo() {
+        name.compareTo(null);
+    }
+
+    @Test
+    public void shouldSupportNullInEquals() {
+        assertThat(name.equals(null), is(false));
+    }
+
+    @Test
+    public void shouldUseFullNamespaceUriInResultFromGetStringWithoutNamespaceRegistry() {
+        String encodedNamespaceUri = Path.DEFAULT_ENCODER.encode(validNamespaceUri);
+        String encodedLocalName = Path.DEFAULT_ENCODER.encode(validLocalName);
+        String result = name.getString();
+        assertThat(result, containsString(encodedNamespaceUri));
+        assertThat(result, containsString(encodedLocalName));
+        assertThat(result, is("{" + encodedNamespaceUri + "}" + encodedLocalName));
+    }
+
+    @Test
+    public void shouldEncodeColonInLocalNameAndNamespaceUriInResultFromGetStringWithoutNamespaceRegistry() {
+        validLocalName = "some:name:with:colons";
+        name = new BasicName(validNamespaceUri, validLocalName);
+        String encodedNamespaceUri = encoder.encode(validNamespaceUri);
+        String encodedLocalName = encoder.encode(validLocalName);
+        String result = name.getString(encoder);
+        assertThat(result, is("{" + encodedNamespaceUri + "}" + encodedLocalName));
+        assertThat(encodedNamespaceUri, is("http%3a%2f%2fwww.jboss.org%2fdna"));
+        assertThat(encodedLocalName, is("some%3aname%3awith%3acolons"));
+    }
+
+    @Test
+    public void shouldUseNamespacePrefixInResultFromGetStringWithNamespaceRegistry() {
+        String result = name.getString(namespaceRegistry, encoder);
+        assertThat(result, is("dna:" + validLocalName));
+
+        validLocalName = "some:name:with:colons";
+        name = new BasicName(validNamespaceUri, validLocalName);
+        result = name.getString(namespaceRegistry, encoder);
+        assertThat(result, is("dna:some%3aname%3awith%3acolons"));
+    }
+
+}


Property changes on: branches/federation/dna-spi/src/test/java/org/jboss/dna/spi/graph/impl/BasicNameTest.java
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Added: branches/federation/dna-spi/src/test/java/org/jboss/dna/spi/graph/impl/BasicPathSegmentTest.java
===================================================================
--- branches/federation/dna-spi/src/test/java/org/jboss/dna/spi/graph/impl/BasicPathSegmentTest.java	                        (rev 0)
+++ branches/federation/dna-spi/src/test/java/org/jboss/dna/spi/graph/impl/BasicPathSegmentTest.java	2008-05-23 16:12:06 UTC (rev 185)
@@ -0,0 +1,145 @@
+/*
+ * 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.spi.graph.impl;
+
+import static org.hamcrest.core.Is.is;
+import static org.junit.Assert.assertThat;
+import org.jboss.dna.common.text.TextEncoder;
+import org.jboss.dna.spi.graph.Name;
+import org.jboss.dna.spi.graph.Path;
+import org.jboss.dna.spi.graph.ValueFactory;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * @author Randall Hauch
+ */
+public class BasicPathSegmentTest {
+
+    public static final TextEncoder NO_OP_ENCODER = Path.NO_OP_ENCODER;
+
+    private BasicNamespaceRegistry registry;
+    private ValueFactory<String> stringValueFactory;
+    private NameValueFactory nameFactory;
+    private PathValueFactory factory;
+    private TextEncoder encoder;
+    private Name validName;
+    private Path.Segment segment;
+    private Path.Segment segment2;
+
+    @Before
+    public void beforeEach() throws Exception {
+        this.registry = new BasicNamespaceRegistry();
+        this.registry.register("dna", "http://www.jboss.org/dna/namespace");
+        this.encoder = Path.DEFAULT_ENCODER;
+        this.stringValueFactory = new StringValueFactory(encoder);
+        this.nameFactory = new NameValueFactory(registry, encoder, stringValueFactory);
+        this.validName = nameFactory.create("dna:something");
+        this.factory = new PathValueFactory(encoder, stringValueFactory, nameFactory);
+    }
+
+    @Test( expected = IllegalArgumentException.class )
+    public void shouldNotAllowNegativeIndex() {
+        new BasicPathSegment(validName, -2);
+    }
+
+    @Test
+    public void shouldConsiderEqualTwoSegmentsWithSameNameAndIndex() {
+        segment = new BasicPathSegment(validName);
+        segment2 = new BasicPathSegment(validName);
+        assertThat(segment.equals(segment2), is(true));
+        assertThat(segment.isSelfReference(), is(false));
+        assertThat(segment.isParentReference(), is(false));
+        assertThat(segment.getName(), is(validName));
+    }
+
+    @Test
+    public void shouldHaveIndexSpecifiedInConstructor() {
+        segment = new BasicPathSegment(validName, 3);
+        assertThat(segment.getIndex(), is(3));
+        assertThat(segment.hasIndex(), is(true));
+        assertThat(segment.isSelfReference(), is(false));
+        assertThat(segment.isParentReference(), is(false));
+        assertThat(segment.getName(), is(validName));
+    }
+
+    @Test
+    public void shouldNotHaveIndexByDefault() {
+        segment = new BasicPathSegment(validName);
+        assertThat(segment.getIndex(), is(Path.NO_INDEX));
+        assertThat(segment.hasIndex(), is(false));
+        assertThat(segment.isSelfReference(), is(false));
+        assertThat(segment.isParentReference(), is(false));
+        assertThat(segment.getName(), is(validName));
+    }
+
+    @Test
+    public void shouldCreateSelfReferenceSegmentIfPassedSelfReferenceStringRegardlessOfIndex() {
+        segment = factory.createSegment(Path.SELF);
+        assertThat(segment.getIndex(), is(Path.NO_INDEX));
+        assertThat(segment.hasIndex(), is(false));
+        assertThat(segment.isSelfReference(), is(true));
+        assertThat(segment.isParentReference(), is(false));
+        assertThat(segment.getName().getLocalName(), is(Path.SELF));
+        assertThat(segment.getName().getNamespaceUri().length(), is(0));
+
+        segment = factory.createSegment(Path.SELF, 1);
+        assertThat(segment.getIndex(), is(Path.NO_INDEX));
+        assertThat(segment.hasIndex(), is(false));
+        assertThat(segment.isSelfReference(), is(true));
+        assertThat(segment.isParentReference(), is(false));
+        assertThat(segment.getName().getLocalName(), is(Path.SELF));
+        assertThat(segment.getName().getNamespaceUri().length(), is(0));
+    }
+
+    @Test
+    public void shouldCreateParentReferenceSegmentIfPassedParentReferenceStringRegardlessOfIndex() {
+        segment = factory.createSegment(Path.PARENT);
+        assertThat(segment.getIndex(), is(Path.NO_INDEX));
+        assertThat(segment.hasIndex(), is(false));
+        assertThat(segment.isSelfReference(), is(false));
+        assertThat(segment.isParentReference(), is(true));
+        assertThat(segment.getName().getLocalName(), is(Path.PARENT));
+        assertThat(segment.getName().getNamespaceUri().length(), is(0));
+
+        segment = factory.createSegment(Path.PARENT, 1);
+        assertThat(segment.getIndex(), is(Path.NO_INDEX));
+        assertThat(segment.hasIndex(), is(false));
+        assertThat(segment.isSelfReference(), is(false));
+        assertThat(segment.isParentReference(), is(true));
+        assertThat(segment.getName().getLocalName(), is(Path.PARENT));
+        assertThat(segment.getName().getNamespaceUri().length(), is(0));
+    }
+
+    @Test
+    public void shouldConsiderSegmentCreatedWithSelfReferenceToBeEqualToStaticSingleton() {
+        segment = factory.createSegment(Path.SELF);
+        assertThat(segment.equals(BasicPathSegment.SELF_SEGMENT), is(true));
+    }
+
+    @Test
+    public void shouldConsiderSegmentCreatedWithParentReferenceToBeEqualToStaticSingleton() {
+        segment = factory.createSegment(Path.PARENT);
+        assertThat(segment.equals(BasicPathSegment.PARENT_SEGMENT), is(true));
+    }
+
+}


Property changes on: branches/federation/dna-spi/src/test/java/org/jboss/dna/spi/graph/impl/BasicPathSegmentTest.java
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Added: branches/federation/dna-spi/src/test/java/org/jboss/dna/spi/graph/impl/BasicPathTest.java
===================================================================
--- branches/federation/dna-spi/src/test/java/org/jboss/dna/spi/graph/impl/BasicPathTest.java	                        (rev 0)
+++ branches/federation/dna-spi/src/test/java/org/jboss/dna/spi/graph/impl/BasicPathTest.java	2008-05-23 16:12:06 UTC (rev 185)
@@ -0,0 +1,761 @@
+/*
+ * 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.spi.graph.impl;
+
+import static org.hamcrest.core.Is.is;
+import static org.hamcrest.core.IsNot.not;
+import static org.hamcrest.core.IsNull.nullValue;
+import static org.hamcrest.core.IsSame.sameInstance;
+import static org.jboss.dna.spi.graph.impl.IsPathContaining.hasSegments;
+import static org.junit.Assert.assertThat;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import org.jboss.dna.common.text.TextEncoder;
+import org.jboss.dna.spi.graph.InvalidPathException;
+import org.jboss.dna.spi.graph.Name;
+import org.jboss.dna.spi.graph.Path;
+import org.jboss.dna.spi.graph.PathNotFoundException;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * @author Randall Hauch
+ */
+public class BasicPathTest {
+
+    public static final TextEncoder NO_OP_ENCODER = Path.NO_OP_ENCODER;
+    public static final Path ROOT = BasicPath.ROOT;
+
+    private BasicNamespaceRegistry namespaceRegistry;
+    private String validNamespaceUri;
+    private Path path;
+    private Path path2;
+    private Path.Segment[] validSegments;
+    private List<Path.Segment> validSegmentsList;
+    private Name[] validSegmentNames;
+    private String validNamespacePrefix;
+    private PathValueFactory pathFactory;
+
+    @Before
+    public void beforeEach() throws Exception {
+        validNamespacePrefix = "dna";
+        validNamespaceUri = "http://www.jboss.org/dna";
+        validSegmentNames = new Name[] {new BasicName(validNamespaceUri, "a"), new BasicName(validNamespaceUri, "b"), new BasicName(validNamespaceUri, "c")};
+        validSegments = new Path.Segment[] {new BasicPathSegment(validSegmentNames[0]), new BasicPathSegment(validSegmentNames[1]), new BasicPathSegment(validSegmentNames[1])};
+        validSegmentsList = new ArrayList<Path.Segment>();
+        for (Path.Segment segment : validSegments) {
+            validSegmentsList.add(segment);
+        }
+        path = new BasicPath(validSegmentsList, true);
+        namespaceRegistry = new BasicNamespaceRegistry();
+        namespaceRegistry.register(validNamespacePrefix, validNamespaceUri);
+        StringValueFactory stringValueFactory = new StringValueFactory(Path.DEFAULT_ENCODER);
+        NameValueFactory nameValueFactory = new NameValueFactory(namespaceRegistry, Path.DEFAULT_ENCODER, stringValueFactory);
+        pathFactory = new PathValueFactory(Path.DEFAULT_ENCODER, stringValueFactory, nameValueFactory);
+    }
+
+    @Test
+    public void shouldCreateAbsolutePathFromListOfValidSegments() {
+        path = new BasicPath(validSegmentsList, true);
+        assertThat(path.isAbsolute(), is(true));
+        assertThat(path.isNormalized(), is(true));
+        assertThat(path.getSegmentsList(), is(validSegmentsList));
+        assertThat(path.size(), is(validSegmentsList.size()));
+    }
+
+    @Test
+    public void shouldCreateRelativePathFromListOfValidSegments() {
+        path = new BasicPath(validSegmentsList, false);
+        assertThat(path.isAbsolute(), is(false));
+        assertThat(path.isNormalized(), is(true));
+        assertThat(path.getSegmentsList(), is(validSegmentsList));
+        assertThat(path.size(), is(validSegmentsList.size()));
+    }
+
+    @Test
+    public void shouldCreateAbsolutePathWithParentSegment() {
+        validSegmentsList.add(BasicPathSegment.PARENT_SEGMENT);
+        path = new BasicPath(validSegmentsList, true);
+        assertThat(path.isAbsolute(), is(true));
+        assertThat(path.isNormalized(), is(false));
+        assertThat(path.getSegmentsList(), is(validSegmentsList));
+        assertThat(path.size(), is(validSegmentsList.size()));
+    }
+
+    @Test
+    public void shouldCreateRelativePathWithParentSegment() {
+        validSegmentsList.add(BasicPathSegment.PARENT_SEGMENT);
+        path = new BasicPath(validSegmentsList, false);
+        assertThat(path.isAbsolute(), is(false));
+        assertThat(path.isNormalized(), is(false));
+        assertThat(path.getSegmentsList(), is(validSegmentsList));
+        assertThat(path.size(), is(validSegmentsList.size()));
+    }
+
+    @Test
+    public void shouldCreateAbsolutePathWithSelfSegment() {
+        validSegmentsList.add(BasicPathSegment.SELF_SEGMENT);
+        path = new BasicPath(validSegmentsList, true);
+        assertThat(path.isAbsolute(), is(true));
+        assertThat(path.isNormalized(), is(false));
+        assertThat(path.getSegmentsList(), is(validSegmentsList));
+        assertThat(path.size(), is(validSegmentsList.size()));
+    }
+
+    @Test
+    public void shouldCreateRelativePathWithSelfSegment() {
+        validSegmentsList.add(BasicPathSegment.SELF_SEGMENT);
+        path = new BasicPath(validSegmentsList, false);
+        assertThat(path.isAbsolute(), is(false));
+        assertThat(path.isNormalized(), is(false));
+        assertThat(path.getSegmentsList(), is(validSegmentsList));
+        assertThat(path.size(), is(validSegmentsList.size()));
+    }
+
+    @Test
+    public void shouldCreatePathWithNoNamespacePrefixes() {
+        path = pathFactory.create("/a/b/c/");
+        assertThat(path.size(), is(3));
+        assertThat(path, hasSegments(pathFactory, "a", "b", "c"));
+    }
+
+    @Test
+    public void shouldConstructRelativePath() {
+        assertThat(pathFactory.create("a/b/c").isAbsolute(), is(false));
+        assertThat(pathFactory.create("a/b/c").isNormalized(), is(true));
+        assertThat(pathFactory.create("a/b/c").size(), is(3));
+        assertThat(pathFactory.create("a/b/c").getString(namespaceRegistry), is("a/b/c"));
+    }
+
+    @Test
+    public void shouldConstructRelativePathToSelf() {
+        assertThat(pathFactory.create(".").isAbsolute(), is(false));
+        assertThat(pathFactory.create(".").size(), is(1));
+        assertThat(pathFactory.create("."), hasSegments(pathFactory, Path.SELF));
+
+        assertThat(pathFactory.create("./").isAbsolute(), is(false));
+        assertThat(pathFactory.create("./").size(), is(1));
+        assertThat(pathFactory.create("./"), hasSegments(pathFactory, Path.SELF));
+    }
+
+    @Test
+    public void shouldConstructRelativePathToParent() {
+        assertThat(pathFactory.create("..").isAbsolute(), is(false));
+        assertThat(pathFactory.create("..").size(), is(1));
+        assertThat(pathFactory.create(".."), hasSegments(pathFactory, Path.PARENT));
+
+        assertThat(pathFactory.create("../").isAbsolute(), is(false));
+        assertThat(pathFactory.create("../").size(), is(1));
+        assertThat(pathFactory.create("../"), hasSegments(pathFactory, Path.PARENT));
+    }
+
+    @Test
+    public void shouldConstructRootPathFromStringWithSingleDelimiter() {
+        assertThat(pathFactory.create("/"), is(ROOT));
+        assertThat(pathFactory.create("/").isRoot(), is(true));
+    }
+
+    @Test( expected = InvalidPathException.class )
+    public void shouldNotConstructPathWithSuccessiveDelimiters() {
+        pathFactory.create("///a/b///c//d//");
+    }
+
+    @Test( expected = InvalidPathException.class )
+    public void shouldNotConstructPathWithOnlyDelimiters() {
+        pathFactory.create("///");
+    }
+
+    @Test( expected = IllegalArgumentException.class )
+    public void shouldNotConstructPathFromNullList() {
+        new BasicPath(null, true);
+    }
+
+    @Test
+    public void shouldConstructPathFromStringAndShouldIgnoreLeadingAndTrailingWhitespace() {
+        assertThat(pathFactory.create(" \t /  \t").toString(), is("/"));
+    }
+
+    @Test
+    public void shouldConstructRelativePathIfSuppliedPathHasNoLeadingDelimiter() {
+        assertThat(pathFactory.create("a"), hasSegments(pathFactory, "a"));
+    }
+
+    @Test
+    public void shouldHaveSizeThatReflectsNumberOfSegments() {
+        assertThat(path.size(), is(validSegmentsList.size()));
+    }
+
+    @Test
+    public void shouldIterateOverAllSegmentsReturnedByList() {
+        Iterator<Path.Segment> expectedIter = validSegmentsList.iterator();
+        for (Path.Segment segment : path) {
+            assertThat(segment, is(expectedIter.next()));
+        }
+
+        expectedIter = path.getSegmentsList().iterator();
+        for (Path.Segment segment : path) {
+            assertThat(segment, is(expectedIter.next()));
+        }
+    }
+
+    @Test
+    public void shouldReturnRootForAncestorOfRoot() {
+        assertThat(BasicPath.ROOT.getAncestor(), is(ROOT));
+    }
+
+    @Test
+    public void shouldReturnAncestorForNodeOtherThanRoot() {
+        assertThat(path.getAncestor(), is(pathFactory.create("/dna:a/dna:b")));
+        assertThat(path.getAncestor().getAncestor(), is(pathFactory.create("/dna:a")));
+        assertThat(path.getAncestor().getAncestor().getAncestor(), is(ROOT));
+    }
+
+    @Test
+    public void shouldReturnNthDegreeAncestor() {
+        assertThat(path.getAncestor(1), is(pathFactory.create("/dna:a/dna:b")));
+        assertThat(path.getAncestor(2), is(pathFactory.create("/dna:a")));
+        assertThat(path.getAncestor(3), is(ROOT));
+    }
+
+    @Test( expected = PathNotFoundException.class )
+    public void shouldNotAllowAncestorDegreeLargerThanSize() {
+        path.getAncestor(path.size() + 1);
+    }
+
+    @Test( expected = IllegalArgumentException.class )
+    public void shouldNotAllowNegativeAncestorDegree() {
+        path.getAncestor(-1);
+    }
+
+    @Test
+    public void shouldReturnRootForAnyAncestorExactDegreeFromRoot() {
+        assertThat(path.getAncestor(path.size()), is(ROOT));
+        assertThat(ROOT.getAncestor(0), is(ROOT));
+    }
+
+    @Test
+    public void shouldConsiderRootTheLowestCommonAncestorOfAnyNodeAndRoot() {
+        assertThat(path.getCommonAncestor(ROOT), is(ROOT));
+        assertThat(ROOT.getCommonAncestor(path), is(ROOT));
+    }
+
+    @Test
+    public void shouldReturnNullForLowestCommonAncestorWithNullPath() {
+        assertThat(path.getCommonAncestor(null), is(nullValue()));
+    }
+
+    @Test
+    public void shouldFindLowestCommonAncestorBetweenTwoNonRootNodesOnCommonBranch() {
+        Path path1 = pathFactory.create("/a/y/z");
+        Path path2 = pathFactory.create("/a/b/c");
+        Path common = pathFactory.create("/a");
+        assertThat(path1.getCommonAncestor(path2), is(common));
+
+        path1 = pathFactory.create("/a/b/c");
+        path2 = pathFactory.create("/a/b/c/d");
+        common = path1;
+        assertThat(path1.getCommonAncestor(path2), is(common));
+
+        path1 = pathFactory.create("/a/b/c/x/y/");
+        path2 = pathFactory.create("/a/b/c/d/e/f/");
+        common = pathFactory.create("/a/b/c");
+        assertThat(path1.getCommonAncestor(path2), is(common));
+    }
+
+    @Test
+    public void shouldConsiderRootTheLowestCommonAncestorOfAnyNodesOnSeparateBrances() {
+        Path path1 = pathFactory.create("/x/y/z");
+        Path path2 = pathFactory.create("/a/b/c");
+        Path common = ROOT;
+        assertThat(path1.getCommonAncestor(path2), is(common));
+    }
+
+    @Test
+    public void shouldConsiderNodeToBeAncestorOfEveryDecendantNode() {
+        Path path1 = pathFactory.create("/a/y/z");
+        Path path2 = pathFactory.create("/a/b/c");
+        Path path3 = pathFactory.create("/x/b/c");
+        Path path4 = pathFactory.create("/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z");
+        Path common = pathFactory.create("/a");
+        assertThat(common.isAncestorOf(path1), is(true));
+        assertThat(common.isAncestorOf(path2), is(true));
+        assertThat(common.isAncestorOf(path3), is(false));
+
+        assertThat(path1.getAncestor().isAncestorOf(path1), is(true));
+        for (int i = 1; i < path1.size(); ++i) {
+            assertThat(path1.getAncestor(i).isAncestorOf(path1), is(true));
+        }
+        for (int i = 1; i < path2.size(); ++i) {
+            assertThat(path2.getAncestor(i).isAncestorOf(path2), is(true));
+        }
+        for (int i = 1; i < path3.size(); ++i) {
+            assertThat(path3.getAncestor(i).isAncestorOf(path3), is(true));
+        }
+        for (int i = 1; i < path4.size(); ++i) {
+            assertThat(path4.getAncestor(i).isAncestorOf(path4), is(true));
+        }
+    }
+
+    @Test
+    public void shouldConsiderNodeToBeDecendantOfEveryAncestorNode() {
+        Path path1 = pathFactory.create("/a/y/z");
+        Path path2 = pathFactory.create("/a/b/c");
+        Path path3 = pathFactory.create("/x/b/c");
+        Path path4 = pathFactory.create("/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z");
+        Path common = pathFactory.create("/a");
+        assertThat(path1.isDecendantOf(common), is(true));
+        assertThat(path2.isDecendantOf(common), is(true));
+        assertThat(path3.isDecendantOf(common), is(false));
+
+        assertThat(path1.getAncestor().isAncestorOf(path1), is(true));
+        for (int i = 1; i < path1.size(); ++i) {
+            assertThat(path1.isDecendantOf(path1.getAncestor(i)), is(true));
+        }
+        for (int i = 1; i < path2.size(); ++i) {
+            assertThat(path2.isDecendantOf(path2.getAncestor(i)), is(true));
+        }
+        for (int i = 1; i < path3.size(); ++i) {
+            assertThat(path3.isDecendantOf(path3.getAncestor(i)), is(true));
+        }
+        for (int i = 1; i < path4.size(); ++i) {
+            assertThat(path4.isDecendantOf(path4.getAncestor(i)), is(true));
+        }
+    }
+
+    @Test
+    public void shouldNotConsiderNodeToBeAncestorOfItself() {
+        Path path1 = pathFactory.create("/a/y/z");
+        Path path2 = pathFactory.create("/a/b/c");
+        Path path3 = pathFactory.create("/x/b/c");
+        assertThat(path1.isAncestorOf(path1), is(false));
+        assertThat(path2.isAncestorOf(path2), is(false));
+        assertThat(path3.isAncestorOf(path3), is(false));
+        assertThat(ROOT.isAncestorOf(ROOT), is(false));
+    }
+
+    @Test
+    public void shouldNotConsiderNodeToBeDecendantOfItself() {
+        Path path1 = pathFactory.create("/a/y/z");
+        Path path2 = pathFactory.create("/a/b/c");
+        Path path3 = pathFactory.create("/x/b/c");
+        assertThat(path1.isDecendantOf(path1), is(false));
+        assertThat(path2.isDecendantOf(path2), is(false));
+        assertThat(path3.isDecendantOf(path3), is(false));
+        assertThat(ROOT.isDecendantOf(ROOT), is(false));
+    }
+
+    @Test
+    public void shouldNotConsiderRootToBeDecendantOfAnyNode() {
+        Path path1 = pathFactory.create("/a/y/z");
+        Path path2 = pathFactory.create("/a/b/c");
+        Path path3 = pathFactory.create("/x/b/c");
+        Path common = pathFactory.create("/a");
+        assertThat(ROOT.isDecendantOf(path1), is(false));
+        assertThat(ROOT.isDecendantOf(path2), is(false));
+        assertThat(ROOT.isDecendantOf(path3), is(false));
+        assertThat(ROOT.isDecendantOf(common), is(false));
+    }
+
+    @Test
+    public void shouldConsiderRootToBeAncestorOfAnyNode() {
+        Path path1 = pathFactory.create("/a/y/z");
+        Path path2 = pathFactory.create("/a/b/c");
+        Path path3 = pathFactory.create("/x/b/c");
+        Path common = pathFactory.create("/a");
+        assertThat(ROOT.isAncestorOf(path1), is(true));
+        assertThat(ROOT.isAncestorOf(path2), is(true));
+        assertThat(ROOT.isAncestorOf(path3), is(true));
+        assertThat(ROOT.isAncestorOf(common), is(true));
+    }
+
+    @Test
+    public void shouldNotConsiderRootToBeAncestorOfItself() {
+        assertThat(ROOT.isAncestorOf(ROOT), is(false));
+    }
+
+    @Test
+    public void shouldNotConsiderRootToBeDecendantOfItself() {
+        assertThat(ROOT.isDecendantOf(ROOT), is(false));
+    }
+
+    @Test
+    public void shouldNeverBeDecendantOfNullPath() {
+        assertThat(path.isDecendantOf(null), is(false));
+        assertThat(ROOT.isDecendantOf(null), is(false));
+    }
+
+    @Test
+    public void shouldReturnNullForLastSegmentOfRoot() {
+        assertThat(ROOT.getLastSegment(), is(nullValue()));
+    }
+
+    @Test
+    public void shouldReturnLastSegmentOfNonRootPath() {
+        Path path1 = pathFactory.create("/a/y/z");
+        Path path2 = pathFactory.create("/a/b/c");
+        Path path3 = pathFactory.create("/x/b/c");
+        Path path4 = pathFactory.create("/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x");
+        assertThat(path1.getLastSegment().getName().getLocalName(), is("z"));
+        assertThat(path2.getLastSegment().getName().getLocalName(), is("c"));
+        assertThat(path3.getLastSegment().getName().getLocalName(), is("c"));
+        assertThat(path4.getLastSegment().getName().getLocalName(), is("x"));
+    }
+
+    @Test
+    public void shouldNormalizePathWithSelfAndParentReferences() {
+        path = pathFactory.create("/a/b/c/../d/./e/../..");
+        assertThat(path.isNormalized(), is(false));
+        assertThat(path.getNormalizedPath(), hasSegments(pathFactory, "a", "b"));
+        assertThat(path.getNormalizedPath().isAbsolute(), is(true));
+        assertThat(path.getNormalizedPath().isNormalized(), is(true));
+
+        path = pathFactory.create("a/b/c/../d/./e/../..");
+        assertThat(path.isNormalized(), is(false));
+        assertThat(path.getNormalizedPath(), hasSegments(pathFactory, "a", "b"));
+        assertThat(path.getNormalizedPath().isAbsolute(), is(false));
+        assertThat(path.getNormalizedPath().isNormalized(), is(true));
+    }
+
+    @Test
+    public void shouldAlreadyBeNormalizedIfPathContainsNoParentOrSelfReferences() {
+        assertThat(pathFactory.create("/a/b/c/d/e").isNormalized(), is(true));
+        assertThat(pathFactory.create("a/b/c/d/e").isNormalized(), is(true));
+        assertThat(pathFactory.create("a").isNormalized(), is(true));
+        assertThat(pathFactory.create("/a").isNormalized(), is(true));
+        assertThat(ROOT.isNormalized(), is(true));
+    }
+
+    @Test
+    public void shouldNotBeNormalizedIfPathContainsParentOrSelfReferences() {
+        assertThat(pathFactory.create("/a/b/c/../d/./e/../..").isNormalized(), is(false));
+        assertThat(pathFactory.create("a/b/c/../d/./e/../..").isNormalized(), is(false));
+        assertThat(pathFactory.create("a/b/c/./d").isNormalized(), is(false));
+        assertThat(pathFactory.create("/a/b/c/../d").isNormalized(), is(false));
+        assertThat(pathFactory.create(".").isNormalized(), is(false));
+        assertThat(pathFactory.create("/.").isNormalized(), is(false));
+    }
+
+    @Test( expected = InvalidPathException.class )
+    public void shouldFailToReturnNormalizedPathIfPathContainsReferencesToParentsAboveRoot() {
+        path = pathFactory.create("/a/../../../..");
+        assertThat(path.isNormalized(), is(false));
+        path.getNormalizedPath();
+    }
+
+    @Test
+    public void shouldReturnRootPathAsTheNormalizedPathForAnAbsolutePathWithZeroSegmentsAfterParentAndSelfReferencesRemoved() {
+        // "/a/../b/../c/.." => "/"
+        path = pathFactory.create("/a/../b/../c/../");
+        assertThat(path.isNormalized(), is(false));
+        assertThat(path.getNormalizedPath(), is(ROOT));
+    }
+
+    @Test
+    public void shouldReturnSelfPathAsTheNormalizedPathForARelativePathWithZeroSegmentsAfterParentAndSelfReferencesRemoved() {
+        // "a/../b/../c/.." => "."
+        path = pathFactory.create("a/../b/../c/../");
+        assertThat(path.isNormalized(), is(false));
+        assertThat(path.getNormalizedPath().size(), is(1));
+        assertThat(path.getNormalizedPath(), hasSegments(pathFactory, "."));
+    }
+
+    @Test
+    public void shouldNotHaveAnyParentOrSelfReferencesInTheNormalizedPathOfAnAbsolutePath() {
+        path = pathFactory.create("/a/b/c/../d/./e/../..");
+        assertThat(path.isNormalized(), is(false));
+        assertThat(path.getNormalizedPath(), hasSegments(pathFactory, "a", "b"));
+        assertThat(path.getNormalizedPath().isAbsolute(), is(true));
+        assertThat(path.getNormalizedPath().isNormalized(), is(true));
+    }
+
+    @Test
+    public void shouldNotHaveAnyParentReferencesInTheNormalizedPathOfARelativePath() {
+        path = pathFactory.create("a/b/c/../d/./e/../..");
+        assertThat(path.isNormalized(), is(false));
+        assertThat(path.getNormalizedPath(), hasSegments(pathFactory, "a", "b"));
+        assertThat(path.getNormalizedPath().isAbsolute(), is(false));
+        assertThat(path.getNormalizedPath().isNormalized(), is(true));
+    }
+
+    @Test( expected = InvalidPathException.class )
+    public void shouldNotComputeCanonicalPathOfNodeThatIsNotAbsolute() {
+        pathFactory.create("a/b/c/../d/./e/../..").getCanonicalPath();
+    }
+
+    @Test
+    public void shouldReturnNormalizedPathForTheCanonicalPathOfAbsolutePath() {
+        path = pathFactory.create("/a/b/c/../d/./e/../..");
+        assertThat(path.isNormalized(), is(false));
+        assertThat(path.isAbsolute(), is(true));
+        assertThat(path.getCanonicalPath(), hasSegments(pathFactory, "a", "b"));
+        assertThat(path.getCanonicalPath().isAbsolute(), is(true));
+        assertThat(path.getCanonicalPath().isNormalized(), is(true));
+    }
+
+    @Test
+    public void shouldReturnSameSegmentsInIteratorAndArrayAndList() {
+        testSegmentsByIteratorAndListAndArray("/a/b/c/../d/./e/../..", "a", "b", "c", "..", "d", ".", "e", "..", "..");
+        testSegmentsByIteratorAndListAndArray("/a/b/c", "a", "b", "c");
+        testSegmentsByIteratorAndListAndArray("a/b/c/../d/./e/../..", "a", "b", "c", "..", "d", ".", "e", "..", "..");
+        testSegmentsByIteratorAndListAndArray("a/b/c", "a", "b", "c");
+        testSegmentsByIteratorAndListAndArray("");
+        testSegmentsByIteratorAndListAndArray(ROOT.getString());
+    }
+
+    public void testSegmentsByIteratorAndListAndArray( String pathStr, String... expectedSegmentStrings ) {
+        path = pathFactory.create(pathStr);
+        assertThat(expectedSegmentStrings.length, is(path.size()));
+        Path.Segment[] segmentArray = path.getSegmentsArray();
+        List<Path.Segment> segmentList = path.getSegmentsList();
+        assertThat(segmentArray.length, is(path.size()));
+        assertThat(segmentList.size(), is(path.size()));
+        Iterator<Path.Segment> iter = path.iterator();
+        Iterator<Path.Segment> listIter = segmentList.iterator();
+        for (int i = 0; i != path.size(); ++i) {
+            Path.Segment expected = pathFactory.createSegment(expectedSegmentStrings[i]);
+            assertThat(path.getSegment(i), is(expected));
+            assertThat(segmentArray[i], is(expected));
+            assertThat(segmentList.get(i), is(expected));
+            assertThat(iter.next(), is(expected));
+            assertThat(listIter.next(), is(expected));
+        }
+        assertThat(iter.hasNext(), is(false));
+        assertThat(listIter.hasNext(), is(false));
+    }
+
+    @Test
+    public void shouldGetStringWithNamespaceUrisIfNoNamespaceRegistryIsProvided() {
+        path = pathFactory.create("/dna:a/b/dna:c/../d/./dna:e/../..");
+        assertThat(path.getString(NO_OP_ENCODER), is("/{http://www.jboss.org/dna}a/{}b/{http://www.jboss.org/dna}c/../{}d/./{http://www.jboss.org/dna}e/../.."));
+    }
+
+    @Test
+    public void shouldGetStringWithNamespacePrefixesForAllNamesIfNamespaceRegistryIsProvided() {
+        path = pathFactory.create("/dna:a/b/dna:c/../d/./dna:e/../..");
+        assertThat(path.getString(namespaceRegistry, NO_OP_ENCODER), is("/dna:a/b/dna:c/../d/./dna:e/../.."));
+        namespaceRegistry.register("dna2", validNamespaceUri);
+        assertThat(path.getString(namespaceRegistry, NO_OP_ENCODER), is("/dna2:a/b/dna2:c/../d/./dna2:e/../.."));
+    }
+
+    @Test( expected = IndexOutOfBoundsException.class )
+    public void shouldFailToReturnSubpathIfStartingIndexIsNegative() {
+        path = pathFactory.create("/dna:a/b/dna:c/../d/./dna:e/../..");
+        path.subpath(-1);
+    }
+
+    @Test( expected = IndexOutOfBoundsException.class )
+    public void shouldFailToReturnSubpathWithoutEndingIndexIfStartingIndexIsEqualToOrLargerThanSize() {
+        path = pathFactory.create("/dna:a/b/dna:c/../d/./dna:e/../..");
+        path.subpath(path.size() + 1);
+    }
+
+    @Test( expected = IndexOutOfBoundsException.class )
+    public void shouldFailToReturnSubpathWithEndingIndexIfStartingIndexIsEqualToOrLargerThanSize() {
+        path = pathFactory.create("/dna:a/b/dna:c/../d/./dna:e/../..");
+        path.subpath(path.size() + 1, path.size() + 2);
+    }
+
+    @Test( expected = IndexOutOfBoundsException.class )
+    public void shouldFailToReturnSubpathIfEndingIndexIsSmallerThanStartingIndex() {
+        path = pathFactory.create("/dna:a/b/dna:c/../d/./dna:e/../..");
+        path.subpath(2, 1);
+    }
+
+    @Test( expected = IndexOutOfBoundsException.class )
+    public void shouldFailToReturnSubpathIfEndingIndexIsEqualToOrLargerThanSize() {
+        path = pathFactory.create("/dna:a/b/dna:c/../d/./dna:e/../..");
+        path.subpath(2, path.size() + 1);
+    }
+
+    @Test
+    public void shouldReturnRootAsSubpathIfStartingIndexAndEndingIndexAreBothZero() {
+        path = pathFactory.create("/dna:a/b/dna:c/../d/./dna:e/../..");
+        assertThat(path.subpath(0, 0), is(ROOT));
+    }
+
+    @Test
+    public void shouldReturnSubpathIfValidStartingIndexAndNoEndingIndexAreProvided() {
+        path = pathFactory.create("/dna:a/b/dna:c/../d/./dna:e/../..");
+        assertThat(path.subpath(0), hasSegments(pathFactory, "dna:a", "b", "dna:c", "..", "d", ".", "dna:e", "..", ".."));
+        assertThat(path.subpath(0), is(path));
+        assertThat(path.subpath(0), is(sameInstance(path)));
+        assertThat(path.subpath(1), hasSegments(pathFactory, "b", "dna:c", "..", "d", ".", "dna:e", "..", ".."));
+        assertThat(path.subpath(2), hasSegments(pathFactory, "dna:c", "..", "d", ".", "dna:e", "..", ".."));
+        assertThat(path.subpath(3), hasSegments(pathFactory, "..", "d", ".", "dna:e", "..", ".."));
+        assertThat(path.subpath(4), hasSegments(pathFactory, "d", ".", "dna:e", "..", ".."));
+        assertThat(path.subpath(5), hasSegments(pathFactory, ".", "dna:e", "..", ".."));
+        assertThat(path.subpath(6), hasSegments(pathFactory, "dna:e", "..", ".."));
+        assertThat(path.subpath(7), hasSegments(pathFactory, "..", ".."));
+        assertThat(path.subpath(8), hasSegments(pathFactory, ".."));
+
+        path = pathFactory.create("dna:a/b/dna:c/../d/./dna:e/../..");
+        assertThat(path.subpath(0), hasSegments(pathFactory, "dna:a", "b", "dna:c", "..", "d", ".", "dna:e", "..", ".."));
+        assertThat(path.subpath(0), is(path));
+        assertThat(path.subpath(0), is(sameInstance(path)));
+        assertThat(path.subpath(1), hasSegments(pathFactory, "b", "dna:c", "..", "d", ".", "dna:e", "..", ".."));
+        assertThat(path.subpath(2), hasSegments(pathFactory, "dna:c", "..", "d", ".", "dna:e", "..", ".."));
+        assertThat(path.subpath(3), hasSegments(pathFactory, "..", "d", ".", "dna:e", "..", ".."));
+        assertThat(path.subpath(4), hasSegments(pathFactory, "d", ".", "dna:e", "..", ".."));
+        assertThat(path.subpath(5), hasSegments(pathFactory, ".", "dna:e", "..", ".."));
+        assertThat(path.subpath(6), hasSegments(pathFactory, "dna:e", "..", ".."));
+        assertThat(path.subpath(7), hasSegments(pathFactory, "..", ".."));
+        assertThat(path.subpath(8), hasSegments(pathFactory, ".."));
+    }
+
+    @Test
+    public void shouldReturnSubpathIfValidStartingIndexAndEndingIndexAreProvided() {
+        path = pathFactory.create("/dna:a/b/dna:c/../d/./dna:e/../..");
+        assertThat(path.subpath(0, path.size()), hasSegments(pathFactory, "dna:a", "b", "dna:c", "..", "d", ".", "dna:e", "..", ".."));
+        assertThat(path.subpath(0, path.size()), is(path));
+        assertThat(path.subpath(0, path.size()), is(sameInstance(path)));
+        assertThat(path.subpath(1, path.size()), hasSegments(pathFactory, "b", "dna:c", "..", "d", ".", "dna:e", "..", ".."));
+        assertThat(path.subpath(2, path.size()), hasSegments(pathFactory, "dna:c", "..", "d", ".", "dna:e", "..", ".."));
+        assertThat(path.subpath(3, path.size()), hasSegments(pathFactory, "..", "d", ".", "dna:e", "..", ".."));
+        assertThat(path.subpath(4, path.size()), hasSegments(pathFactory, "d", ".", "dna:e", "..", ".."));
+        assertThat(path.subpath(5, path.size()), hasSegments(pathFactory, ".", "dna:e", "..", ".."));
+        assertThat(path.subpath(6, path.size()), hasSegments(pathFactory, "dna:e", "..", ".."));
+        assertThat(path.subpath(7, path.size()), hasSegments(pathFactory, "..", ".."));
+        assertThat(path.subpath(8, path.size()), hasSegments(pathFactory, ".."));
+
+        assertThat(path.subpath(0, 2), hasSegments(pathFactory, "dna:a", "b"));
+        assertThat(path.subpath(1, 2), hasSegments(pathFactory, "b"));
+        assertThat(path.subpath(1, 5), hasSegments(pathFactory, "b", "dna:c", "..", "d"));
+        assertThat(path.subpath(2, 5), hasSegments(pathFactory, "dna:c", "..", "d"));
+        assertThat(path.subpath(3, 5), hasSegments(pathFactory, "..", "d"));
+    }
+
+    @Test
+    public void shouldFindRelativePaths() {
+        path = pathFactory.create("/a/b/c/d");
+        assertThat(path.relativeTo(pathFactory.create("/a/e/f")), is(pathFactory.create("../../b/c/d")));
+        assertThat(path.relativeTo(pathFactory.create("/e/f")), is(pathFactory.create("../../a/b/c/d")));
+
+    }
+
+    @Test( expected = InvalidPathException.class )
+    public void shouldNotAllowFindingRelativePathsFromRelativePaths() {
+        path = pathFactory.create("a/b/c/d");
+        path.relativeTo(pathFactory.create("/e/f"));
+
+    }
+
+    @Test( expected = InvalidPathException.class )
+    public void shouldNotResolveRelativePathToAnotherRelativePath() {
+        path = pathFactory.create("/a/b/c/d");
+        path.relativeTo(pathFactory.create("e/f"));
+
+    }
+
+    @Test( expected = InvalidPathException.class )
+    public void shouldNotResolveRelativePathUsingAnAbsolutePath() {
+        path = pathFactory.create("/a/b/c/d");
+        path.resolve(pathFactory.create("/e/f"));
+    }
+
+    @Test
+    public void shouldResolveRelativePathToAbsolutePath() {
+        path = pathFactory.create("/a/b/c/d");
+        path2 = path.resolve(pathFactory.create("../../e/f"));
+        assertThat(path2, is(pathFactory.create("/a/b/e/f")));
+        assertThat(path2.isAbsolute(), is(true));
+        assertThat(path2.isNormalized(), is(true));
+    }
+
+    @Test
+    public void shouldOrderPathsCorrectly() {
+        List<Path> paths = new ArrayList<Path>();
+        paths.add(pathFactory.create("/a"));
+        paths.add(pathFactory.create("/a/b"));
+        paths.add(pathFactory.create("/a/b/alpha"));
+        paths.add(pathFactory.create("/a/b/beta"));
+        paths.add(pathFactory.create("/a/b/dna:mixinTypes"));
+        paths.add(pathFactory.create("/a/b/dna:name"));
+        paths.add(pathFactory.create("/a/b/dna:primaryType"));
+        paths.add(pathFactory.create("/a/c[1]"));
+        paths.add(pathFactory.create("/a/c[1]/alpha"));
+        paths.add(pathFactory.create("/a/c[1]/beta"));
+        paths.add(pathFactory.create("/a/c[1]/dna:mixinTypes"));
+        paths.add(pathFactory.create("/a/c[1]/dna:name"));
+        paths.add(pathFactory.create("/a/c[1]/dna:primaryType"));
+        paths.add(pathFactory.create("/a/c[2]"));
+        paths.add(pathFactory.create("/a/c[2]/alpha"));
+        paths.add(pathFactory.create("/a/c[2]/beta"));
+        paths.add(pathFactory.create("/a/c[2]/dna:mixinTypes"));
+        paths.add(pathFactory.create("/a/c[2]/dna:name"));
+        paths.add(pathFactory.create("/a/c[2]/dna:primaryType"));
+
+        // Randomize the list of paths, so we have something to sort ...
+        List<Path> randomizedPaths = new ArrayList<Path>(paths);
+        Collections.shuffle(randomizedPaths);
+        assertThat(randomizedPaths, is(not(paths)));
+
+        // Sort ...
+        Collections.sort(randomizedPaths);
+        assertThat(randomizedPaths, is(paths));
+    }
+
+    @Test
+    public void shouldGetNormalizedPathOfSelfShouldBeSame() {
+        assertThat(pathFactory.create(".").getNormalizedPath(), is(pathFactory.create(".")));
+        assertThat(pathFactory.create("./").getNormalizedPath(), is(pathFactory.create(".")));
+        assertThat(pathFactory.create("./././").getNormalizedPath(), is(pathFactory.create(".")));
+    }
+
+    @Test
+    public void shouldGetNormalizedPathWithParentReferences() {
+        assertThat(pathFactory.create("..").getNormalizedPath(), is(pathFactory.create("..")));
+        assertThat(pathFactory.create("../").getNormalizedPath(), is(pathFactory.create("../")));
+        assertThat(pathFactory.create("../../../../../..").getNormalizedPath(), is(pathFactory.create("../../../../../..")));
+    }
+
+    @Test
+    public void shouldGetRelativePathUsingSelf() {
+        path = pathFactory.create("/a/b/c/d/e/f");
+        assertThat(path.resolve(pathFactory.create(".")), is(sameInstance(path)));
+        assertThat(path.resolve(pathFactory.create("././.")), is(sameInstance(path)));
+    }
+
+    @Test
+    public void shouldResolveRelativePathToParent() {
+        path = pathFactory.create("/a/b/c/d/e/f");
+        assertThat(path.resolve(pathFactory.create("..")), is(path.getAncestor()));
+        assertThat(path.resolve(pathFactory.create("..")), hasSegments(pathFactory, "a", "b", "c", "d", "e"));
+    }
+
+    @Test
+    public void shouldResolveRelativePaths() {
+        path = pathFactory.create("/a/b/c/d/e/f");
+        assertThat(path.resolve(pathFactory.create("../../../../../..")), is(sameInstance(ROOT)));
+        assertThat(path.resolve(pathFactory.create("../..")), is(path.getAncestor().getAncestor()));
+        assertThat(path.resolve(pathFactory.create("../..")), hasSegments(pathFactory, "a", "b", "c", "d"));
+        assertThat(path.resolve(pathFactory.create("../x/../y/../z/..")), is(path.getAncestor()));
+        assertThat(path.resolve(pathFactory.create("../x/../y/../z/..")), hasSegments(pathFactory, "a", "b", "c", "d", "e"));
+        assertThat(path.resolve(pathFactory.create("../x")), hasSegments(pathFactory, "a", "b", "c", "d", "e", "x"));
+    }
+
+    public void shouldResolveNonAbsolutePaths() {
+        path = pathFactory.create("a/b/c");
+        assertThat(path, hasSegments(pathFactory, "a", "b", "c"));
+    }
+}


Property changes on: branches/federation/dna-spi/src/test/java/org/jboss/dna/spi/graph/impl/BasicPathTest.java
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Added: branches/federation/dna-spi/src/test/java/org/jboss/dna/spi/graph/impl/IsPathContaining.java
===================================================================
--- branches/federation/dna-spi/src/test/java/org/jboss/dna/spi/graph/impl/IsPathContaining.java	                        (rev 0)
+++ branches/federation/dna-spi/src/test/java/org/jboss/dna/spi/graph/impl/IsPathContaining.java	2008-05-23 16:12:06 UTC (rev 185)
@@ -0,0 +1,106 @@
+/*
+ * 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.spi.graph.impl;
+
+import static org.hamcrest.core.AllOf.allOf;
+import static org.hamcrest.core.IsEqual.equalTo;
+import java.util.ArrayList;
+import java.util.Collection;
+import org.hamcrest.Description;
+import org.hamcrest.Factory;
+import org.hamcrest.Matcher;
+import org.jboss.dna.spi.graph.Path;
+import org.jboss.dna.spi.graph.PathFactory;
+import org.jboss.dna.spi.graph.Path.Segment;
+import org.junit.matchers.TypeSafeMatcher;
+
+/**
+ * @author Randall Hauch
+ */
+public class IsPathContaining extends TypeSafeMatcher<Iterable<Segment>> {
+
+    private final Matcher<? super Segment> elementMatcher;
+
+    public IsPathContaining( Matcher<? super Segment> elementMatcher ) {
+        this.elementMatcher = elementMatcher;
+    }
+
+    @Override
+    public boolean matchesSafely( Iterable<Segment> collection ) {
+        for (Segment item : collection) {
+            if (elementMatcher.matches(item)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    public void describeTo( Description description ) {
+        description.appendText("a path containing ").appendDescriptionOf(elementMatcher);
+    }
+
+    @Factory
+    public static Matcher<Iterable<Segment>> hasSegment( Matcher<? super Segment> elementMatcher ) {
+        return new IsPathContaining(elementMatcher);
+    }
+
+    @Factory
+    public static Matcher<Iterable<Segment>> hasSegment( Segment element ) {
+        return hasSegment(equalTo(element));
+    }
+
+    @Factory
+    public static Matcher<Iterable<Segment>> hasSegments( Matcher<Path.Segment>... elementMatchers ) {
+        Collection<Matcher<? extends Iterable<Path.Segment>>> all = new ArrayList<Matcher<? extends Iterable<Path.Segment>>>(elementMatchers.length);
+
+        for (Matcher<Path.Segment> elementMatcher : elementMatchers) {
+            Matcher<Iterable<Path.Segment>> itemMatcher = hasSegment(elementMatcher);
+            all.add(itemMatcher);
+        }
+
+        return allOf(all);
+    }
+
+    @Factory
+    public static Matcher<Iterable<Segment>> hasSegments( Segment... elements ) {
+        Collection<Matcher<? extends Iterable<Segment>>> all = new ArrayList<Matcher<? extends Iterable<Segment>>>(elements.length);
+        for (Segment element : elements) {
+            all.add(hasSegment(element));
+        }
+        return allOf(all);
+    }
+
+    @Factory
+    public static Matcher<Iterable<Segment>> hasSegment( PathFactory pathFactory, String element ) {
+        Path.Segment segment = pathFactory.createSegment(element);
+        return hasSegment(equalTo(segment));
+    }
+
+    @Factory
+    public static Matcher<Iterable<Segment>> hasSegments( PathFactory pathFactory, String... segments ) {
+        Collection<Matcher<? extends Iterable<Segment>>> all = new ArrayList<Matcher<? extends Iterable<Segment>>>(segments.length);
+        for (String element : segments) {
+            all.add(hasSegment(pathFactory, element));
+        }
+        return allOf(all);
+    }
+}


Property changes on: branches/federation/dna-spi/src/test/java/org/jboss/dna/spi/graph/impl/IsPathContaining.java
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Added: branches/federation/dna-spi/src/test/java/org/jboss/dna/spi/graph/impl/NameValueFactoryTest.java
===================================================================
--- branches/federation/dna-spi/src/test/java/org/jboss/dna/spi/graph/impl/NameValueFactoryTest.java	                        (rev 0)
+++ branches/federation/dna-spi/src/test/java/org/jboss/dna/spi/graph/impl/NameValueFactoryTest.java	2008-05-23 16:12:06 UTC (rev 185)
@@ -0,0 +1,87 @@
+/*
+ * 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.spi.graph.impl;
+
+import static org.hamcrest.core.Is.is;
+import static org.junit.Assert.assertThat;
+import org.jboss.dna.common.text.TextEncoder;
+import org.jboss.dna.spi.graph.Name;
+import org.jboss.dna.spi.graph.Path;
+import org.jboss.dna.spi.graph.ValueFactory;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * @author Randall Hauch
+ */
+public class NameValueFactoryTest {
+
+    public static final TextEncoder NO_OP_ENCODER = Path.NO_OP_ENCODER;
+
+    private BasicNamespaceRegistry registry;
+    private ValueFactory<String> stringValueFactory;
+    private NameValueFactory factory;
+    private TextEncoder encoder;
+    private Name name;
+
+    @Before
+    public void beforeEach() throws Exception {
+        this.registry = new BasicNamespaceRegistry();
+        this.registry.register("dna", "http://www.jboss.org/dna/namespace");
+        this.encoder = Path.DEFAULT_ENCODER;
+        this.stringValueFactory = new StringValueFactory(encoder);
+        this.factory = new NameValueFactory(registry, encoder, stringValueFactory);
+    }
+
+    @Test
+    public void shouldCreateNameFromSingleStringInPrefixedNamespaceFormat() {
+        name = factory.create("dna:something");
+        assertThat(name.getLocalName(), is("something"));
+        assertThat(name.getNamespaceUri(), is("http://www.jboss.org/dna/namespace"));
+        assertThat(name.getString(NO_OP_ENCODER), is("{http://www.jboss.org/dna/namespace}something"));
+    }
+
+    @Test
+    public void shouldCreateNameFromSingleEncodedStringInPrefixedNamespaceFormat() {
+        name = factory.create(encoder.encode("dna") + ":" + encoder.encode("some/thing"));
+        assertThat(name.getLocalName(), is("some/thing"));
+        assertThat(name.getNamespaceUri(), is("http://www.jboss.org/dna/namespace"));
+        assertThat(name.getString(NO_OP_ENCODER), is("{http://www.jboss.org/dna/namespace}some/thing"));
+    }
+
+    @Test
+    public void shouldCreateNameFromSingleStringInStandardFullNamespaceFormat() {
+        name = factory.create("{http://www.jboss.org/dna/namespace}something");
+        assertThat(name.getLocalName(), is("something"));
+        assertThat(name.getNamespaceUri(), is("http://www.jboss.org/dna/namespace"));
+        assertThat(name.getString(NO_OP_ENCODER), is("{http://www.jboss.org/dna/namespace}something"));
+    }
+
+    @Test
+    public void shouldCreateNameFromSingleEncodedStringInStandardFullNamespaceFormat() {
+        name = factory.create("{" + encoder.encode("http://www.jboss.org/dna/namespace") + "}" + encoder.encode("some/thing"));
+        assertThat(name.getLocalName(), is("some/thing"));
+        assertThat(name.getNamespaceUri(), is("http://www.jboss.org/dna/namespace"));
+        assertThat(name.getString(NO_OP_ENCODER), is("{http://www.jboss.org/dna/namespace}some/thing"));
+    }
+
+}


Property changes on: branches/federation/dna-spi/src/test/java/org/jboss/dna/spi/graph/impl/NameValueFactoryTest.java
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Added: branches/federation/dna-spi/src/test/java/org/jboss/dna/spi/graph/impl/PathValueFactoryTest.java
===================================================================
--- branches/federation/dna-spi/src/test/java/org/jboss/dna/spi/graph/impl/PathValueFactoryTest.java	                        (rev 0)
+++ branches/federation/dna-spi/src/test/java/org/jboss/dna/spi/graph/impl/PathValueFactoryTest.java	2008-05-23 16:12:06 UTC (rev 185)
@@ -0,0 +1,121 @@
+/*
+ * 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.spi.graph.impl;
+
+import static org.hamcrest.core.Is.is;
+import static org.jboss.dna.spi.graph.impl.IsPathContaining.hasSegments;
+import static org.junit.Assert.assertThat;
+import java.util.ArrayList;
+import java.util.List;
+import org.jboss.dna.common.text.TextEncoder;
+import org.jboss.dna.spi.graph.Name;
+import org.jboss.dna.spi.graph.Path;
+import org.jboss.dna.spi.graph.ValueFactory;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * @author Randall Hauch
+ */
+public class PathValueFactoryTest {
+
+    public static final TextEncoder NO_OP_ENCODER = Path.NO_OP_ENCODER;
+
+    private BasicNamespaceRegistry registry;
+    private ValueFactory<String> stringValueFactory;
+    private NameValueFactory nameFactory;
+    private PathValueFactory factory;
+    private TextEncoder encoder;
+    private Path path;
+    private Path path2;
+
+    @Before
+    public void beforeEach() throws Exception {
+        this.registry = new BasicNamespaceRegistry();
+        this.registry.register("dna", "http://www.jboss.org/dna/namespace");
+        this.encoder = Path.DEFAULT_ENCODER;
+        this.stringValueFactory = new StringValueFactory(encoder);
+        this.nameFactory = new NameValueFactory(registry, encoder, stringValueFactory);
+        this.factory = new PathValueFactory(encoder, stringValueFactory, nameFactory);
+    }
+
+    protected List<Path.Segment> getSegments( String... segments ) {
+        List<Path.Segment> result = new ArrayList<Path.Segment>();
+        for (String segmentStr : segments) {
+            Name name = nameFactory.create(segmentStr);
+            BasicPathSegment segment = new BasicPathSegment(name);
+            result.add(segment);
+        }
+        return result;
+    }
+
+    @Test
+    public void shouldCreateFromStringWithAbsolutePathAndNoParentOrSelfReferences() {
+        path = factory.create("/a/b/c/d/dna:e/dna:f");
+        assertThat(path, hasSegments(factory, "a", "b", "c", "d", "dna:e", "dna:f"));
+    }
+
+    @Test
+    public void shouldCreateFromStringWithRelativePathAndNoParentOrSelfReferences() {
+        path = factory.create("a/b/c/d/dna:e/dna:f");
+        assertThat(path, hasSegments(factory, "a", "b", "c", "d", "dna:e", "dna:f"));
+    }
+
+    @Test
+    public void shouldCreateFromStringWithAbsolutePathAndParentReference() {
+        path = factory.create("/a/b/c/../dna:e/dna:f");
+        assertThat(path, hasSegments(factory, "a", "b", "c", "..", "dna:e", "dna:f"));
+    }
+
+    @Test
+    public void shouldCreateFromStringWithRelativePathAndParentReference() {
+        path = factory.create("a/b/c/../dna:e/dna:f");
+        assertThat(path, hasSegments(factory, "a", "b", "c", "..", "dna:e", "dna:f"));
+    }
+
+    @Test
+    public void shouldCreateFromStringWithAbsolutePathAndSelfReference() {
+        path = factory.create("/a/b/c/./dna:e/dna:f");
+        assertThat(path, hasSegments(factory, "a", "b", "c", ".", "dna:e", "dna:f"));
+    }
+
+    @Test
+    public void shouldCreateFromStringWithRelativePathAndSelfReference() {
+        path = factory.create("a/b/c/./dna:e/dna:f");
+        assertThat(path, hasSegments(factory, "a", "b", "c", ".", "dna:e", "dna:f"));
+    }
+
+    @Test
+    public void shouldCreateFromStringWithRelativePathBeginningWithSelfReference() {
+        path = factory.create("./a/b/c/./dna:e/dna:f");
+        assertThat(path, hasSegments(factory, ".", "a", "b", "c", ".", "dna:e", "dna:f"));
+    }
+
+    @Test
+    public void shouldCreateEquivalentPathsWhetherOrNotThereIsATrailingDelimiter() {
+        path = factory.create("/a/b/c/d/dna:e/dna:f");
+        path2 = factory.create("/a/b/c/d/dna:e/dna:f/");
+        assertThat(path.equals(path2), is(true));
+        assertThat(path.compareTo(path2), is(0));
+    }
+
+}


Property changes on: branches/federation/dna-spi/src/test/java/org/jboss/dna/spi/graph/impl/PathValueFactoryTest.java
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Modified: branches/federation/docs/examples/gettingstarted/sequencers/src/main/java/org/jboss/example/dna/sequencers/SequencingClient.java
===================================================================
--- branches/federation/docs/examples/gettingstarted/sequencers/src/main/java/org/jboss/example/dna/sequencers/SequencingClient.java	2008-05-22 20:22:50 UTC (rev 184)
+++ branches/federation/docs/examples/gettingstarted/sequencers/src/main/java/org/jboss/example/dna/sequencers/SequencingClient.java	2008-05-23 16:12:06 UTC (rev 185)
@@ -200,13 +200,14 @@
             // for the DNA services which knows about the JCR repositories, workspaces, and credentials used to
             // establish sessions to these workspaces. This example uses the SimpleExecutionContext, but there is
             // implementation for use with JCR repositories registered in JNDI.
+            final String repositoryWorkspaceName = this.repositoryName + "/" + this.workspaceName;
             SimpleSessionFactory sessionFactory = new SimpleSessionFactory();
             sessionFactory.registerRepository(this.repositoryName, this.repository);
             if (this.username != null) {
                 Credentials credentials = new SimpleCredentials(this.username, this.password);
-                sessionFactory.registerCredentials(this.repositoryName + "/" + this.workspaceName, credentials);
+                sessionFactory.registerCredentials(repositoryWorkspaceName, credentials);
             }
-            this.executionContext = new SimpleExecutionContext(sessionFactory);
+            this.executionContext = new SimpleExecutionContext(sessionFactory, repositoryWorkspaceName);
 
             // Create the sequencing service, passing in the execution context ...
             this.sequencingService = new SequencingService();
@@ -247,7 +248,7 @@
             this.observationService = new ObservationService(this.executionContext.getSessionFactory());
             this.observationService.getAdministrator().start();
             this.observationService.addListener(this.sequencingService);
-            this.observationService.monitor(this.repositoryName + "/" + this.workspaceName, Event.NODE_ADDED | Event.PROPERTY_ADDED | Event.PROPERTY_CHANGED);
+            this.observationService.monitor(repositoryWorkspaceName, Event.NODE_ADDED | Event.PROPERTY_ADDED | Event.PROPERTY_CHANGED);
         }
         // Start up the sequencing service ...
         this.sequencingService.getAdministrator().start();




More information about the dna-commits mailing list