You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by ju...@apache.org on 2010/09/15 08:50:37 UTC

svn commit: r997201 - in /jackrabbit/trunk: jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/name/ jackrabbit-spi-commons/src/test/java/org/apache/jackrabbit/spi/commons/conversion/ jackrabbit-spi-commons/src/test/java/org/apache/...

Author: jukka
Date: Wed Sep 15 06:50:36 2010
New Revision: 997201

URL: http://svn.apache.org/viewvc?rev=997201&view=rev
Log:
JCR-2744: Avoid element arrays in PathImpl

Start progress on deprecating the Element interface by adding relevant methods to Path

Modified:
    jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/name/AbstractPath.java
    jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/name/CurrentPath.java
    jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/name/IdentifierPath.java
    jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/name/NamePath.java
    jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/name/ParentPath.java
    jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/name/RelativePath.java
    jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/name/RootPath.java
    jackrabbit/trunk/jackrabbit-spi-commons/src/test/java/org/apache/jackrabbit/spi/commons/conversion/ParsingPathResolverTest.java
    jackrabbit/trunk/jackrabbit-spi-commons/src/test/java/org/apache/jackrabbit/spi/commons/conversion/PathParserTest.java
    jackrabbit/trunk/jackrabbit-spi-commons/src/test/java/org/apache/jackrabbit/spi/commons/name/PathFactoryTest.java
    jackrabbit/trunk/jackrabbit-spi/src/main/java/org/apache/jackrabbit/spi/Path.java

Modified: jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/name/AbstractPath.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/name/AbstractPath.java?rev=997201&r1=997200&r2=997201&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/name/AbstractPath.java (original)
+++ jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/name/AbstractPath.java Wed Sep 15 06:50:36 2010
@@ -28,6 +28,76 @@ abstract class AbstractPath implements P
     /** Serial version UID */
     private static final long serialVersionUID = 3018771833963770499L;
 
+    /**
+     * Returns {@link Path#INDEX_UNDEFINED}, except when overridden by the
+     * {@link NamePath} subclass.
+     *
+     * @return {@link Path#INDEX_UNDEFINED}
+     */
+    public int getIndex() {
+        return INDEX_UNDEFINED;
+    }
+
+    /**
+     * Returns {@link Path#INDEX_DEFAULT}, except when overridden by the
+     * {@link NamePath} subclass.
+     *
+     * @return {@link Path#INDEX_DEFAULT}
+     */
+    public int getNormalizedIndex() {
+        return INDEX_DEFAULT;
+    }
+
+    /**
+     * Returns <code>false</code>, except when overridden by the
+     * {@link RootPath} subclass.
+     *
+     * @return <code>false</code>
+     */
+    public boolean denotesRoot() {
+        return false;
+    }
+
+    /**
+     * Returns <code>false</code>, except when overridden by the
+     * {@link IdentifierPath} subclass.
+     *
+     * @return <code>false</code>
+     */
+    public boolean denotesIdentifier() {
+        return false;
+    }
+
+    /**
+     * Returns <code>false</code>, except when overridden by the
+     * {@link ParentPath} subclass.
+     *
+     * @return <code>false</code>
+     */
+    public boolean denotesParent() {
+        return false;
+    }
+
+    /**
+     * Returns <code>false</code>, except when overridden by the
+     * {@link CurrentPath} subclass.
+     *
+     * @return <code>false</code>
+     */
+    public boolean denotesCurrent() {
+        return false;
+    }
+
+    /**
+     * Returns <code>false</code>, except when overridden by the
+     * {@link NamePath} subclass.
+     *
+     * @return <code>false</code>
+     */
+    public boolean denotesName() {
+        return false;
+    }
+
     public final Path resolve(Element element) {
         if (element.denotesName()) {
             return new NamePath(this, element);
@@ -160,7 +230,7 @@ abstract class AbstractPath implements P
             throws IllegalArgumentException, RepositoryException {
         if (other != null
                 && isAbsolute() == other.isAbsolute()
-                && denotesIdentifier() == other.denotesIdentifier()) {
+                && isIdentifierBased() == other.isIdentifierBased()) {
             int d = other.getDepth() - getDepth();
             return d > 0 && isEquivalentTo(other.getAncestor(d));
         } else {
@@ -186,7 +256,7 @@ abstract class AbstractPath implements P
             throws IllegalArgumentException, RepositoryException {
         if (other != null
                 && isAbsolute() == other.isAbsolute()
-                && denotesIdentifier() == other.denotesIdentifier()) {
+                && isIdentifierBased() == other.isIdentifierBased()) {
             int d = getDepth() - other.getDepth();
             return d > 0 && getAncestor(d).isEquivalentTo(other);
         } else {

Modified: jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/name/CurrentPath.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/name/CurrentPath.java?rev=997201&r1=997200&r2=997201&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/name/CurrentPath.java (original)
+++ jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/name/CurrentPath.java Wed Sep 15 06:50:36 2010
@@ -18,6 +18,7 @@ package org.apache.jackrabbit.spi.common
 
 import javax.jcr.RepositoryException;
 
+import org.apache.jackrabbit.spi.Name;
 import org.apache.jackrabbit.spi.Path;
 
 /**
@@ -46,6 +47,20 @@ final class CurrentPath extends Relative
         }
     }
 
+    public Name getName() {
+        return CurrentElement.INSTANCE.getName();
+    }
+
+    /**
+     * Returns <code>true</code> as this path ends in the current element.
+     *
+     * @return <code>true</code>
+     */
+    @Override
+    public boolean denotesCurrent() {
+        return true;
+    }
+
     /**
      * Returns <code>false</code> as a path with a "." element is
      * never canonical.

Modified: jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/name/IdentifierPath.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/name/IdentifierPath.java?rev=997201&r1=997200&r2=997201&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/name/IdentifierPath.java (original)
+++ jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/name/IdentifierPath.java Wed Sep 15 06:50:36 2010
@@ -18,6 +18,7 @@ package org.apache.jackrabbit.spi.common
 
 import javax.jcr.RepositoryException;
 
+import org.apache.jackrabbit.spi.Name;
 import org.apache.jackrabbit.spi.Path;
 
 final class IdentifierPath extends AbstractPath {
@@ -34,12 +35,12 @@ final class IdentifierPath extends Abstr
     }
 
     /**
-     * Returns <code>false</code> as this is an identifier-based path.
+     * Returns <code>null</code> as an identifier element has no name.
      *
-     * @return <code>false</code>
+     * @return <code>null</code>
      */
-    public boolean denotesRoot() {
-        return false;
+    public Name getName() {
+        return null;
     }
 
     /**
@@ -47,11 +48,21 @@ final class IdentifierPath extends Abstr
      *
      * @return <code>true</code>
      */
+    @Override
     public boolean denotesIdentifier() {
         return true;
     }
 
     /**
+     * Returns <code>true</code> as this is an identifier-based path.
+     *
+     * @return <code>true</code>
+     */
+    public boolean isIdentifierBased() {
+        return true;
+    }
+
+    /**
      * Returns <code>true</code> as an identifier-based path with no other
      * elements is absolute.
      *

Modified: jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/name/NamePath.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/name/NamePath.java?rev=997201&r1=997200&r2=997201&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/name/NamePath.java (original)
+++ jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/name/NamePath.java Wed Sep 15 06:50:36 2010
@@ -18,6 +18,7 @@ package org.apache.jackrabbit.spi.common
 
 import javax.jcr.RepositoryException;
 
+import org.apache.jackrabbit.spi.Name;
 import org.apache.jackrabbit.spi.Path;
 
 final class NamePath extends RelativePath {
@@ -45,6 +46,30 @@ final class NamePath extends RelativePat
         }
     }
 
+    public Name getName() {
+        return element.getName();
+    }
+
+    @Override
+    public int getIndex() {
+        return element.getIndex();
+    }
+
+    @Override
+    public int getNormalizedIndex() {
+        return element.getNormalizedIndex();
+    }
+
+    /**
+     * Returns <code>true</code> as this path ends in a named element.
+     *
+     * @return <code>true</code>
+     */
+    @Override
+    public boolean denotesName() {
+        return true;
+    }
+
     public boolean isCanonical() {
         return parent != null && parent.isCanonical();
     }

Modified: jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/name/ParentPath.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/name/ParentPath.java?rev=997201&r1=997200&r2=997201&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/name/ParentPath.java (original)
+++ jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/name/ParentPath.java Wed Sep 15 06:50:36 2010
@@ -18,6 +18,7 @@ package org.apache.jackrabbit.spi.common
 
 import javax.jcr.RepositoryException;
 
+import org.apache.jackrabbit.spi.Name;
 import org.apache.jackrabbit.spi.Path;
 
 /**
@@ -46,6 +47,20 @@ final class ParentPath extends RelativeP
         }
     }
 
+    public Name getName() {
+        return ParentElement.INSTANCE.getName();
+    }
+
+    /**
+     * Returns <code>true</code> as this path ends in the parent element.
+     *
+     * @return <code>true</code>
+     */
+    @Override
+    public boolean denotesParent() {
+        return true;
+    }
+
     /**
      * Returns <code>false</code> as a path with a ".." element is
      * never canonical.

Modified: jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/name/RelativePath.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/name/RelativePath.java?rev=997201&r1=997200&r2=997201&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/name/RelativePath.java (original)
+++ jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/name/RelativePath.java Wed Sep 15 06:50:36 2010
@@ -39,7 +39,7 @@ abstract class RelativePath extends Abst
         this.parent = parent;
         if (parent != null) {
             this.absolute = parent.isAbsolute();
-            this.identifier = parent.denotesIdentifier();
+            this.identifier = parent.isIdentifierBased();
             this.depth = parent.getDepth() + getDepthModifier();
             this.length = parent.getLength() + 1;
         } else {
@@ -54,11 +54,7 @@ abstract class RelativePath extends Abst
 
     protected abstract Path getParent() throws RepositoryException;
 
-    public final boolean denotesRoot() {
-        return false;
-    }
-
-    public final boolean denotesIdentifier() {
+    public final boolean isIdentifierBased() {
         return identifier;
     }
 

Modified: jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/name/RootPath.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/name/RootPath.java?rev=997201&r1=997200&r2=997201&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/name/RootPath.java (original)
+++ jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/name/RootPath.java Wed Sep 15 06:50:36 2010
@@ -18,6 +18,7 @@ package org.apache.jackrabbit.spi.common
 
 import javax.jcr.PathNotFoundException;
 
+import org.apache.jackrabbit.spi.Name;
 import org.apache.jackrabbit.spi.Path;
 
 final class RootPath extends AbstractPath {
@@ -32,11 +33,16 @@ final class RootPath extends AbstractPat
     private RootPath() {
     }
 
+    public Name getName() {
+        return RootElement.INSTANCE.getName();
+    }
+
     /**
      * Returns <code>true</code> as this is the root path.
      *
      * @return <code>true</code>
      */
+    @Override
     public boolean denotesRoot() {
         return true;
     }
@@ -46,7 +52,7 @@ final class RootPath extends AbstractPat
      *
      * @return <code>false</code>
      */
-    public boolean denotesIdentifier() {
+    public boolean isIdentifierBased() {
         return false;
     }
 

Modified: jackrabbit/trunk/jackrabbit-spi-commons/src/test/java/org/apache/jackrabbit/spi/commons/conversion/ParsingPathResolverTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-spi-commons/src/test/java/org/apache/jackrabbit/spi/commons/conversion/ParsingPathResolverTest.java?rev=997201&r1=997200&r2=997201&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-spi-commons/src/test/java/org/apache/jackrabbit/spi/commons/conversion/ParsingPathResolverTest.java (original)
+++ jackrabbit/trunk/jackrabbit-spi-commons/src/test/java/org/apache/jackrabbit/spi/commons/conversion/ParsingPathResolverTest.java Wed Sep 15 06:50:36 2010
@@ -166,14 +166,14 @@ public class ParsingPathResolverTest ext
             String jcrPath = "[" + it.next().toString() + "]";
 
             Path p = resolverV2.getQPath(jcrPath, true);
-            assertFalse(p.denotesIdentifier());
+            assertFalse(p.isIdentifierBased());
             assertTrue(p.isAbsolute());
             assertTrue(p.isNormalized());
             assertTrue(p.isCanonical());
             assertEquals(DummyIdentifierResolver.JCR_PATH, resolverV2.getJCRPath(p));
 
             p = resolverV2.getQPath(jcrPath, false);
-            assertTrue(p.denotesIdentifier());
+            assertTrue(p.isIdentifierBased());
             assertEquals(1, p.getLength());
             assertTrue(p.isAbsolute());
             assertFalse(p.isNormalized());

Modified: jackrabbit/trunk/jackrabbit-spi-commons/src/test/java/org/apache/jackrabbit/spi/commons/conversion/PathParserTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-spi-commons/src/test/java/org/apache/jackrabbit/spi/commons/conversion/PathParserTest.java?rev=997201&r1=997200&r2=997201&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-spi-commons/src/test/java/org/apache/jackrabbit/spi/commons/conversion/PathParserTest.java (original)
+++ jackrabbit/trunk/jackrabbit-spi-commons/src/test/java/org/apache/jackrabbit/spi/commons/conversion/PathParserTest.java Wed Sep 15 06:50:36 2010
@@ -228,10 +228,10 @@ public class PathParserTest extends Test
             }
 
             Path p = PathParser.parse(jcrPath, resolver, idResolver, factory, true);
-            assertFalse(p.denotesIdentifier());
+            assertFalse(p.isIdentifierBased());
 
             p = PathParser.parse(jcrPath, resolver, idResolver, factory, false);
-            assertTrue(p.denotesIdentifier());
+            assertTrue(p.isIdentifierBased());
 
             try {
                 PathParser.parse(factory.getRootPath(), jcrPath, resolver, idResolver, factory);

Modified: jackrabbit/trunk/jackrabbit-spi-commons/src/test/java/org/apache/jackrabbit/spi/commons/name/PathFactoryTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-spi-commons/src/test/java/org/apache/jackrabbit/spi/commons/name/PathFactoryTest.java?rev=997201&r1=997200&r2=997201&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-spi-commons/src/test/java/org/apache/jackrabbit/spi/commons/name/PathFactoryTest.java (original)
+++ jackrabbit/trunk/jackrabbit-spi-commons/src/test/java/org/apache/jackrabbit/spi/commons/name/PathFactoryTest.java Wed Sep 15 06:50:36 2010
@@ -214,7 +214,7 @@ public class PathFactoryTest extends Tes
         assertEquals(Path.INDEX_DEFAULT, elem.getNormalizedIndex());
 
         Path p = factory.create(new Path.Element[] {elem});
-        assertTrue(p.denotesIdentifier());
+        assertTrue(p.isIdentifierBased());
         assertTrue(p.isAbsolute());
 
         assertFalse(p.denotesRoot());

Modified: jackrabbit/trunk/jackrabbit-spi/src/main/java/org/apache/jackrabbit/spi/Path.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-spi/src/main/java/org/apache/jackrabbit/spi/Path.java?rev=997201&r1=997200&r2=997201&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-spi/src/main/java/org/apache/jackrabbit/spi/Path.java (original)
+++ jackrabbit/trunk/jackrabbit-spi/src/main/java/org/apache/jackrabbit/spi/Path.java Wed Sep 15 06:50:36 2010
@@ -24,45 +24,44 @@ import javax.jcr.RepositoryException;
 /**
  * The <code>Path</code> interface defines the SPI level representation of
  * a JCR path. It consists of an ordered list of {@link Path.Element} objects
- * and is immutable.<p/>
- *
+ * and is immutable.
+ * <p>
  * A {@link Path.Element} is either {@link Path.Element#denotesName() named}
  * or one of the following special elements:
  * <ul>
  * <li>the {@link Element#denotesCurrent() current} element (Notation: "."),</li>
  * <li>the {@link Element#denotesParent() parent} element (Notation: ".."),</li>
  * <li>the {@link Element#denotesRoot() root} element (Notation: {}), which can
+ * only occur as the first element in a path, or</li>
+ * <li>an {@link Element#denotesIdentifier() identifier} element, which can
  * only occur as the first element in a path.</li>
  * </ul>
- *
+ * <p>
  * A <code>Path</code> is defined to have the following characteristics:
- * <p/>
- *
+ * <p>
  * <strong>Equality:</strong><br>
  * Two paths are equal if they consist of the same elements.
- * <p/>
- *
+ * <p>
  * <strong>Length:</strong><br>
  * The {@link Path#getLength() length} of a path is the number of its elements.
- * <p/>
- *
+ * <p>
  * <strong>Depth:</strong><br>
  * The {@link Path#getDepth() depth} of a path is
  * <ul>
  * <li>0 for the root path,</li>
+ * <li>0 for a path consisting of an identifier element only,</li>
  * <li>0 for the path consisting of the current element only,</li>
  * <li>-1 for the path consisting of the parent element only,</li>
- * <li>1 for the path consisting of any other single element,</li>
+ * <li>1 for the path consisting of a single named element,</li>
  * <li>depth(P) + depth(Q) for the path P/Q.</li>
  * </ul>
- * The depth of a valid absolute path equals the length of its
- * normalization minus 1.
- * <p/>
- *
+ * <p>
+ * The depth of a normalized absolute path equals its length minus 1.
+ * <p>
  * <strong>Absolute vs. Relative</strong><br>
  * A path can be absolute or relative:<br>
  * A path {@link #isAbsolute() is absolute} if its first element is the root
- * element. A path is relative if it is not absolute.
+ * or an identifier element. A path is relative if it is not absolute.
  * <ul>
  * <li>An absolute path is valid if its depth is greater or equals 0. A relative
  * path is always valid.</li>
@@ -71,27 +70,24 @@ import javax.jcr.RepositoryException;
  * <li>Two relative paths P and Q are equivalent if for every absolute path R such
  * that R/P and R/Q are valid, R/P and R/Q are equivalent.</li>
  * </ul>
- * <p/>
- *
+ * <p>
  * <strong>Normalization:</strong><br>
  * A path P {@link Path#isNormalized() is normalized} if P has minimal length
  * amongst the set of all paths Q which are equivalent to P.<br>
  * This means that '.' and '..' elements are resolved as much as possible.
- * An absolute path it is normalized if it contains no current nor parent
- * element. The normalization of a path is unique.<br>
- * <p/>
- *
- * <strong>Equalivalence:</strong><br>
+ * An absolute path it is normalized if it is not identifier-based and
+ * contains no current or parent elements. The normalization of a path
+ * is unique.<br>
+ * <p>
+ * <strong>Equivalence:</strong><br>
  * Path P is {@link Path#isEquivalentTo(Path) equivalent} to path Q (in the above sense)
  * if the normalization of P is equal to the normalization of Q. This is
  * an equivalence relation (i.e. reflexive, transitive,
  * and symmetric).
- * <p/>
- *
+ * <p>
  * <strong>Canonical Paths:</strong><br>
  * A path {@link Path#isCanonical() is canonical} if its absolute and normalized.
- * <p/>
- *
+ * <p>
  * <strong>Hierarchical Relationship:</strong><br>
  * The ancestor relationship is a strict partial order (i.e. irreflexive, transitive,
  * and asymmetric). Path P is a direct ancestor of path Q if P is equivalent to Q/..
@@ -101,7 +97,7 @@ import javax.jcr.RepositoryException;
  * <li>P is a direct ancestor of Q or</li>
  * <li>P is a direct ancestor of some path S which is an ancestor of Q.</li>
  * </ul>
- *
+ * <p>
  * Path P is an {@link Path#isDescendantOf(Path) descendant} of path Q if
  * <ul>
  * <li>Path P is a descendant of path Q if Q is an ancestor of P.</li>
@@ -131,11 +127,71 @@ public interface Path extends Serializab
     public static final char DELIMITER = '\t';
 
     /**
-     * Tests whether this path represents the root path, i.e. "/".
+     * Returns the name of the last path element, or <code>null</code>
+     * for an identifier. The names of the special root, current and parent
+     * elements are "", "." and ".." in the default namespace.
      *
-     * @return true if this path represents the root path; false otherwise.
+     * @return name of the last path element, or <code>null</code>
      */
-    public boolean denotesRoot();
+    Name getName();
+
+    /**
+     * Returns the index of the last path element, or {@link #INDEX_UNDEFINED}
+     * if the index is not defined or not applicable. The index of an
+     * identifier or the special root, current or parent element is always
+     * undefined.
+     *
+     * @return index of the last path element, or {@link #INDEX_UNDEFINED}
+     */
+    int getIndex();
+
+    /**
+     * Returns the normalized index of the last path element. The normalized
+     * index of an element with an undefined index is {@link #INDEX_DEFAULT}.
+     *
+     * @return normalized index of the last path element
+     */
+    int getNormalizedIndex();
+
+    /**
+     * Tests whether this is the root path, i.e. "/".
+     *
+     * @return <code>true</code> if this is the root path,
+     *         <code>false</code> otherwise.
+     */
+    boolean denotesRoot();
+
+    /**
+     * Test if this path consists of a single identifier element.
+     *
+     * @return <code>true</code> if this path is an identifier
+     */
+    boolean denotesIdentifier();
+
+    /**
+     * Checks if the last path element is the parent element ("..").
+     *
+     * @return <code>true</code> if the last path element is the parent element,
+     *         <code>false</code> otherwise
+     */
+    boolean denotesParent();
+
+    /**
+     * Checks if the last path element is the current element (".").
+     *
+     * @return <code>true</code> if the last path element is the current element,
+     *         <code>false</code> otherwise
+     */
+    boolean denotesCurrent();
+
+    /**
+     * Checks if the last path element is a named and optionally indexed
+     * element.
+     *
+     * @return <code>true</code> if the last path element is a named element,
+     *         <code>false</code> otherwise
+     */
+    boolean denotesName();
 
     /**
      * Test if this path represents an unresolved identifier-based path.
@@ -143,7 +199,7 @@ public interface Path extends Serializab
      * @return <code>true</code> if this path represents an unresolved
      * identifier-based path.
      */
-    public boolean denotesIdentifier();
+    boolean isIdentifierBased();
 
     /**
      * Tests whether this path is absolute, i.e. whether it starts with "/" or