[dna-commits] DNA SVN: r763 - in trunk: dna-jcr/src/main/java/org/jboss/dna/jcr and 1 other directories.

dna-commits at lists.jboss.org dna-commits at lists.jboss.org
Mon Mar 9 13:57:18 EDT 2009


Author: rhauch
Date: 2009-03-09 13:57:18 -0400 (Mon, 09 Mar 2009)
New Revision: 763

Added:
   trunk/dna-graph/src/main/java/org/jboss/dna/graph/LocationWithPathAndUuid.java
   trunk/dna-graph/src/main/java/org/jboss/dna/graph/LocationWithProperties.java
   trunk/dna-graph/src/main/java/org/jboss/dna/graph/LocationWithProperty.java
Modified:
   trunk/dna-graph/src/main/java/org/jboss/dna/graph/Location.java
   trunk/dna-graph/src/main/java/org/jboss/dna/graph/LocationWithPath.java
   trunk/dna-graph/src/main/java/org/jboss/dna/graph/LocationWithPathAndProperties.java
   trunk/dna-graph/src/main/java/org/jboss/dna/graph/LocationWithPathAndProperty.java
   trunk/dna-graph/src/main/java/org/jboss/dna/graph/LocationWithUuid.java
   trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/AbstractJcrNode.java
   trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/AbstractJcrProperty.java
   trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrMultiValueProperty.java
   trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrNode.java
   trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrRootNode.java
   trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrSession.java
   trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrSingleValueProperty.java
   trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/AbstractJcrNodeTest.java
   trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/AbstractJcrPropertyTest.java
   trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/JcrMultiValuePropertyTest.java
   trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/JcrNodeTest.java
   trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/JcrRootNodeTest.java
   trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/JcrSingleValuePropertyTest.java
Log:
DNA-194 Implement update JCR capability

Refactored the fields that are used in the JcrAbstractNode, JcrNode, and JcrRootNode implementations.  Because Location objects will play a much more significant role, several new implementations of Location were added, including an optimum implementation of a Location with a path and UUID.

Also made a number of the very-oft-used package-level methods final, hopefully increasing the chance they're inlined.  Minimal risk of overriding, although some tests were made a little more complicated (but probably better overall anyway).

Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/Location.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/Location.java	2009-03-06 17:03:00 UTC (rev 762)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/Location.java	2009-03-09 17:57:18 UTC (rev 763)
@@ -38,7 +38,6 @@
 import org.jboss.dna.graph.property.NamespaceRegistry;
 import org.jboss.dna.graph.property.Path;
 import org.jboss.dna.graph.property.Property;
-import org.jboss.dna.graph.property.basic.BasicSingleValueProperty;
 
 /**
  * The location of a node, as specified by either its path, UUID, and/or identification properties.
@@ -102,8 +101,12 @@
      */
     public static Location create( Path path,
                                    UUID uuid ) {
-        CheckArg.isNotNull(uuid, "uuid");
-        return new LocationWithPathAndProperty(path, new BasicSingleValueProperty(DnaLexicon.UUID, uuid));
+        if (path == null) {
+            CheckArg.isNotNull(uuid, "uuid");
+            return new LocationWithUuid(uuid);
+        }
+        if (uuid == null) return new LocationWithPath(path);
+        return new LocationWithPathAndUuid(path, uuid);
     }
 
     /**
@@ -182,7 +185,7 @@
      */
     public static Location create( Property idProperty ) {
         CheckArg.isNotNull(idProperty, "idProperty");
-        return new LocationWithPathAndProperty(null, idProperty);
+        return new LocationWithProperty(idProperty);
     }
 
     /**
@@ -197,6 +200,7 @@
                                    Property... remainingIdProperties ) {
         CheckArg.isNotNull(firstIdProperty, "firstIdProperty");
         CheckArg.isNotNull(remainingIdProperties, "remainingIdProperties");
+        if (remainingIdProperties.length == 0) return new LocationWithProperty(firstIdProperty);
         List<Property> idProperties = new ArrayList<Property>(1 + remainingIdProperties.length);
         Set<Name> names = new HashSet<Name>();
         names.add(firstIdProperty.getName());
@@ -227,9 +231,9 @@
                 assert false;
                 return null; // never get here
             case 1:
-                return new LocationWithPathAndProperty(null, idPropertiesList.get(0));
+                return new LocationWithProperty(idPropertiesList.get(0));
             default:
-                return new LocationWithPathAndProperties(null, idPropertiesList);
+                return new LocationWithProperties(idPropertiesList);
         }
     }
 

Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/LocationWithPath.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/LocationWithPath.java	2009-03-06 17:03:00 UTC (rev 762)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/LocationWithPath.java	2009-03-09 17:57:18 UTC (rev 763)
@@ -39,7 +39,7 @@
  * @see Location
  */
 @Immutable
-class LocationWithPath extends Location {
+final class LocationWithPath extends Location {
 
     private final Path path;
     private final int hashCode;

Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/LocationWithPathAndProperties.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/LocationWithPathAndProperties.java	2009-03-06 17:03:00 UTC (rev 762)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/LocationWithPathAndProperties.java	2009-03-09 17:57:18 UTC (rev 763)
@@ -40,7 +40,7 @@
  * @see Location
  */
 @Immutable
-class LocationWithPathAndProperties extends Location {
+final class LocationWithPathAndProperties extends Location {
 
     private final Path path;
     private final List<Property> idProperties;
@@ -54,7 +54,7 @@
      * @param idProperties the identification properties
      */
     LocationWithPathAndProperties( Path path,
-                            List<Property> idProperties ) {
+                                   List<Property> idProperties ) {
         assert idProperties != null;
         assert !idProperties.isEmpty();
         this.path = path;
@@ -125,7 +125,7 @@
             newIdProperties = Collections.unmodifiableList(newIdProperties);
             return new LocationWithPathAndProperties(path, newIdProperties);
         }
-        return Location.create(path, newIdProperty);
+        return new LocationWithPathAndProperty(path, newIdProperty);
     }
 
     /**
@@ -136,7 +136,7 @@
     @Override
     public Location with( Path newPath ) {
         if (newPath == null || this.getPath().equals(newPath)) return this;
-        return Location.create(newPath, idProperties);
+        return new LocationWithPathAndProperties(newPath, idProperties);
     }
 
     /**
@@ -156,6 +156,6 @@
         List<Property> newIdProperties = new ArrayList<Property>(idProperties.size() + 1);
         newIdProperties.addAll(idProperties);
         newIdProperties.add(newProperty);
-        return Location.create(path, newIdProperties);
+        return new LocationWithPathAndProperties(path, newIdProperties);
     }
 }

Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/LocationWithPathAndProperty.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/LocationWithPathAndProperty.java	2009-03-06 17:03:00 UTC (rev 762)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/LocationWithPathAndProperty.java	2009-03-09 17:57:18 UTC (rev 763)
@@ -41,7 +41,7 @@
  * @see Location
  */
 @Immutable
-class LocationWithPathAndProperty extends Location {
+final class LocationWithPathAndProperty extends Location {
 
     private final Path path;
     private final List<Property> idProperties;
@@ -56,16 +56,16 @@
      */
     LocationWithPathAndProperty( Path path,
                                  Property idProperty ) {
+        assert path != null;
         assert idProperty != null;
         assert !idProperty.isEmpty();
-        // The path could be null
         this.path = path;
         this.idProperties = Collections.singletonList(idProperty);
 
         // Paths are immutable, Properties are immutable, the idProperties list
         // is wrapped in an unmodifiableList by the Location factory methods...
         // ... so we can cache the hash code.
-        hashCode = HashCode.compute(path, idProperties);
+        hashCode = HashCode.compute(this.path, idProperties);
     }
 
     /**
@@ -81,6 +81,16 @@
     /**
      * {@inheritDoc}
      * 
+     * @see org.jboss.dna.graph.Location#hasPath()
+     */
+    @Override
+    public final boolean hasPath() {
+        return true;
+    }
+
+    /**
+     * {@inheritDoc}
+     * 
      * @see Location#getIdProperties()
      */
     @Override
@@ -146,9 +156,9 @@
         if (newIdProperty == null || newIdProperty.isEmpty()) return this;
         Property idProperty = idProperties.get(0); // fast
         if (newIdProperty.getName().equals(idProperty.getName())) {
-            return path == null ? Location.create(newIdProperty) : Location.create(path, newIdProperty);
+            return new LocationWithPathAndProperty(path, newIdProperty);
         }
-        return path == null ? Location.create(idProperty, newIdProperty) : Location.create(path, idProperty, newIdProperty);
+        return Location.create(path, idProperty, newIdProperty);
     }
 
     /**
@@ -158,10 +168,10 @@
      */
     @Override
     public Location with( Path newPath ) {
-        if (newPath == null && path == null) return this;
-        if (path != null && (path.equals(newPath))) return this;
+        if (newPath == null) return Location.create(idProperties);
+        if (path.equals(newPath)) return this;
         Property idProperty = idProperties.get(0); // fast
-        return Location.create(newPath, idProperty);
+        return new LocationWithPathAndProperty(newPath, idProperty);
     }
 
     /**
@@ -171,12 +181,10 @@
      */
     @Override
     public Location with( UUID uuid ) {
-        if (uuid == null) return this;
         Property idProperty = idProperties.get(0); // fast
-        if (DnaLexicon.UUID.equals(idProperty.getName())) {
-            return path == null ? Location.create(uuid) : Location.create(path, uuid);
-        }
+        assert !DnaLexicon.UUID.equals(idProperty.getName());
+        if (uuid == null) return Location.create(path);
         Property newUuidProperty = new BasicSingleValueProperty(DnaLexicon.UUID, uuid);
-        return path == null ? Location.create(idProperty, newUuidProperty) : Location.create(path, idProperty, newUuidProperty);
+        return Location.create(path, idProperty, newUuidProperty);
     }
 }

Added: trunk/dna-graph/src/main/java/org/jboss/dna/graph/LocationWithPathAndUuid.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/LocationWithPathAndUuid.java	                        (rev 0)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/LocationWithPathAndUuid.java	2009-03-09 17:57:18 UTC (rev 763)
@@ -0,0 +1,181 @@
+/*
+ * JBoss DNA (http://www.jboss.org/dna)
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership.  Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ * See the AUTHORS.txt file in the distribution for a full listing of 
+ * individual contributors. 
+ *
+ * JBoss DNA is free software. Unless otherwise indicated, all code in JBoss DNA
+ * is licensed to you 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.
+ *
+ * JBoss DNA is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.dna.graph;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.UUID;
+import net.jcip.annotations.Immutable;
+import org.jboss.dna.common.util.CheckArg;
+import org.jboss.dna.common.util.HashCode;
+import org.jboss.dna.graph.property.Name;
+import org.jboss.dna.graph.property.Path;
+import org.jboss.dna.graph.property.Property;
+import org.jboss.dna.graph.property.basic.BasicSingleValueProperty;
+
+/**
+ * General purpose location type that supports a path and a UUID property. This class should never be directly instantiated by
+ * users of the DNA framework. Instead, use @{link Location#create} to create the correct location.
+ * 
+ * @see Location
+ */
+ at Immutable
+final class LocationWithPathAndUuid extends Location {
+
+    private final Path path;
+    private final List<Property> idProperties;
+
+    private final int hashCode;
+
+    /**
+     * Create a new location with a given path and identification property.
+     * 
+     * @param path the path
+     * @param uuid the UUID
+     */
+    LocationWithPathAndUuid( Path path,
+                             UUID uuid ) {
+        assert path != null;
+        assert uuid != null;
+        this.path = path;
+        this.idProperties = Collections.singletonList((Property)new BasicSingleValueProperty(DnaLexicon.UUID, uuid));
+
+        // Paths are immutable, Properties are immutable, the idProperties list
+        // is wrapped in an unmodifiableList by the Location factory methods...
+        // ... so we can cache the hash code.
+        hashCode = HashCode.compute(this.path, idProperties);
+    }
+
+    /**
+     * {@inheritDoc}
+     * 
+     * @see Location#getPath()
+     */
+    @Override
+    public final Path getPath() {
+        return path;
+    }
+
+    /**
+     * {@inheritDoc}
+     * 
+     * @see org.jboss.dna.graph.Location#hasPath()
+     */
+    @Override
+    public final boolean hasPath() {
+        return true;
+    }
+
+    /**
+     * {@inheritDoc}
+     * 
+     * @see Location#getIdProperties()
+     */
+    @Override
+    public final List<Property> getIdProperties() {
+        return idProperties;
+    }
+
+    /**
+     * {@inheritDoc}
+     * 
+     * @see Location#hasIdProperties()
+     */
+    @Override
+    public final boolean hasIdProperties() {
+        return true;
+    }
+
+    /**
+     * {@inheritDoc}
+     * 
+     * @see Location#getIdProperty(Name)
+     */
+    @Override
+    public final Property getIdProperty( Name name ) {
+        CheckArg.isNotNull(name, "name");
+        Property property = idProperties.get(0); // this is fast
+        return property.getName().equals(name) ? property : null;
+    }
+
+    /**
+     * {@inheritDoc}
+     * 
+     * @see Location#getUuid()
+     */
+    @Override
+    public final UUID getUuid() {
+        return (UUID)idProperties.get(0).getFirstValue(); // this is fast, and we know this is a UUID object
+    }
+
+    /**
+     * {@inheritDoc}
+     * 
+     * @see Location#hashCode()
+     */
+    @Override
+    public int hashCode() {
+        return hashCode;
+    }
+
+    /**
+     * {@inheritDoc}
+     * 
+     * @see Location#with(Property)
+     */
+    @Override
+    public Location with( Property newIdProperty ) {
+        if (newIdProperty == null || newIdProperty.isEmpty()) return this;
+        Property idProperty = idProperties.get(0); // fast
+        if (newIdProperty.getName().equals(idProperty.getName())) {
+            return new LocationWithPathAndProperty(path, newIdProperty);
+        }
+        return Location.create(path, idProperty, newIdProperty);
+    }
+
+    /**
+     * {@inheritDoc}
+     * 
+     * @see Location#with(Path)
+     */
+    @Override
+    public Location with( Path newPath ) {
+        if (newPath == null) return Location.create(idProperties);
+        if (path.equals(newPath)) return this;
+        Property idProperty = idProperties.get(0); // fast
+        return new LocationWithPathAndProperty(newPath, idProperty);
+    }
+
+    /**
+     * {@inheritDoc}
+     * 
+     * @see Location#with(UUID)
+     */
+    @Override
+    public Location with( UUID uuid ) {
+        if (uuid == null) return Location.create(path);
+        if (uuid.equals(getUuid())) return this;
+        return new LocationWithPathAndUuid(path, uuid);
+    }
+}


Property changes on: trunk/dna-graph/src/main/java/org/jboss/dna/graph/LocationWithPathAndUuid.java
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Added: trunk/dna-graph/src/main/java/org/jboss/dna/graph/LocationWithProperties.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/LocationWithProperties.java	                        (rev 0)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/LocationWithProperties.java	2009-03-09 17:57:18 UTC (rev 763)
@@ -0,0 +1,164 @@
+/*
+ * JBoss DNA (http://www.jboss.org/dna)
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership.  Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ * See the AUTHORS.txt file in the distribution for a full listing of 
+ * individual contributors. 
+ *
+ * JBoss DNA is free software. Unless otherwise indicated, all code in JBoss DNA
+ * is licensed to you 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.
+ *
+ * JBoss DNA is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.dna.graph;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.UUID;
+import net.jcip.annotations.Immutable;
+import org.jboss.dna.common.util.HashCode;
+import org.jboss.dna.graph.property.Path;
+import org.jboss.dna.graph.property.Property;
+import org.jboss.dna.graph.property.basic.BasicSingleValueProperty;
+
+/**
+ * General purpose location type that supports a path and zero or more properties. This class should never be directly
+ * instantiated by users of the DNA framework. Instead, use @{link Location#create} to create the correct location.
+ * 
+ * @see Location
+ */
+ at Immutable
+final class LocationWithProperties extends Location {
+
+    private final List<Property> idProperties;
+    private final int hashCode;
+
+    /**
+     * Create a new location with a given path and set of identification properties.
+     * 
+     * @param idProperties the identification properties
+     */
+    LocationWithProperties( List<Property> idProperties ) {
+        assert idProperties != null;
+        assert !idProperties.isEmpty();
+        this.idProperties = Collections.unmodifiableList(idProperties);
+        // Paths are immutable, Properties are immutable, the idProperties list
+        // is wrapped in an unmodifiableList by the Location factory methods...
+        // ... so we can cache the hash code.
+        hashCode = HashCode.compute(null, idProperties);
+    }
+
+    /**
+     * {@inheritDoc}
+     * 
+     * @see Location#getPath()
+     */
+    @Override
+    public final Path getPath() {
+        return null;
+    }
+
+    /**
+     * {@inheritDoc}
+     * 
+     * @see org.jboss.dna.graph.Location#hasPath()
+     */
+    @Override
+    public final boolean hasPath() {
+        return false;
+    }
+
+    /**
+     * {@inheritDoc}
+     * 
+     * @see Location#getIdProperties()
+     */
+    @Override
+    public final List<Property> getIdProperties() {
+        return idProperties;
+    }
+
+    /**
+     * {@inheritDoc}
+     * 
+     * @see Location#hasIdProperties()
+     */
+    @Override
+    public final boolean hasIdProperties() {
+        return idProperties.size() > 0;
+    }
+
+    /**
+     * {@inheritDoc}
+     * 
+     * @see Location#hashCode()
+     */
+    @Override
+    public int hashCode() {
+        return hashCode;
+    }
+
+    /**
+     * {@inheritDoc}
+     * 
+     * @see Location#with(Property)
+     */
+    @Override
+    public Location with( Property newIdProperty ) {
+        if (newIdProperty == null || newIdProperty.isEmpty()) return this;
+
+        List<Property> newIdProperties;
+
+        assert hasIdProperties();
+        newIdProperties = new ArrayList<Property>(idProperties.size() + 1);
+        for (Property property : idProperties) {
+            if (!newIdProperty.getName().equals(property.getName())) newIdProperties.add(property);
+        }
+        newIdProperties.add(newIdProperty);
+        newIdProperties = Collections.unmodifiableList(newIdProperties);
+        return new LocationWithProperties(newIdProperties);
+    }
+
+    /**
+     * {@inheritDoc}
+     * 
+     * @see Location#with(Path)
+     */
+    @Override
+    public Location with( Path newPath ) {
+        if (newPath == null || this.getPath().equals(newPath)) return this;
+        return new LocationWithPathAndProperties(newPath, idProperties);
+    }
+
+    /**
+     * {@inheritDoc}
+     * 
+     * @see Location#with(UUID)
+     */
+    @Override
+    public Location with( UUID uuid ) {
+        if (uuid == null) return this;
+        Property newProperty = new BasicSingleValueProperty(DnaLexicon.UUID, uuid);
+        if (this.hasIdProperties()) {
+            Property existing = this.getIdProperty(DnaLexicon.UUID);
+            if (existing != null && existing.equals(newProperty)) return this;
+        }
+
+        List<Property> newIdProperties = new ArrayList<Property>(idProperties.size() + 1);
+        newIdProperties.addAll(idProperties);
+        newIdProperties.add(newProperty);
+        return new LocationWithProperties(newIdProperties);
+    }
+}


Property changes on: trunk/dna-graph/src/main/java/org/jboss/dna/graph/LocationWithProperties.java
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Added: trunk/dna-graph/src/main/java/org/jboss/dna/graph/LocationWithProperty.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/LocationWithProperty.java	                        (rev 0)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/LocationWithProperty.java	2009-03-09 17:57:18 UTC (rev 763)
@@ -0,0 +1,193 @@
+/*
+ * JBoss DNA (http://www.jboss.org/dna)
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership.  Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ * See the AUTHORS.txt file in the distribution for a full listing of 
+ * individual contributors. 
+ *
+ * JBoss DNA is free software. Unless otherwise indicated, all code in JBoss DNA
+ * is licensed to you 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.
+ *
+ * JBoss DNA is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.dna.graph;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.UUID;
+import net.jcip.annotations.Immutable;
+import org.jboss.dna.common.util.CheckArg;
+import org.jboss.dna.common.util.HashCode;
+import org.jboss.dna.graph.property.Name;
+import org.jboss.dna.graph.property.Path;
+import org.jboss.dna.graph.property.Property;
+import org.jboss.dna.graph.property.basic.BasicSingleValueProperty;
+
+/**
+ * General purpose location type that supports a path and a property. This class should never be directly instantiated by users of
+ * the DNA framework. Instead, use @{link Location#create} to create the correct location.
+ * 
+ * @see Location
+ */
+ at Immutable
+final class LocationWithProperty extends Location {
+
+    protected final List<Property> idProperties;
+
+    private final int hashCode;
+
+    /**
+     * Create a new location with a given path and identification property.
+     * 
+     * @param idProperty the identification property
+     */
+    LocationWithProperty( Property idProperty ) {
+        assert idProperty != null;
+        assert !idProperty.isEmpty();
+        // The path could be null
+        this.idProperties = Collections.singletonList(idProperty);
+
+        // Paths are immutable, Properties are immutable, the idProperties list
+        // is wrapped in an unmodifiableList by the Location factory methods...
+        // ... so we can cache the hash code.
+        hashCode = HashCode.compute(null, idProperties);
+    }
+
+    /**
+     * {@inheritDoc}
+     * 
+     * @see Location#getPath()
+     */
+    @Override
+    public final Path getPath() {
+        return null;
+    }
+
+    /**
+     * {@inheritDoc}
+     * 
+     * @see org.jboss.dna.graph.Location#hasPath()
+     */
+    @Override
+    public boolean hasPath() {
+        return false;
+    }
+
+    /**
+     * {@inheritDoc}
+     * 
+     * @see Location#getIdProperties()
+     */
+    @Override
+    public final List<Property> getIdProperties() {
+        return idProperties;
+    }
+
+    /**
+     * {@inheritDoc}
+     * 
+     * @see Location#hasIdProperties()
+     */
+    @Override
+    public final boolean hasIdProperties() {
+        return true;
+    }
+
+    /**
+     * {@inheritDoc}
+     * 
+     * @see Location#getIdProperty(Name)
+     */
+    @Override
+    public final Property getIdProperty( Name name ) {
+        CheckArg.isNotNull(name, "name");
+        Property property = idProperties.get(0); // this is fast
+        return property.getName().equals(name) ? property : null;
+    }
+
+    /**
+     * {@inheritDoc}
+     * 
+     * @see Location#getUuid()
+     */
+    @Override
+    public UUID getUuid() {
+        Property property = idProperties.get(0); // this is fast
+        if (DnaLexicon.UUID.equals(property.getName())) {
+            Object value = property.getFirstValue();
+            if (value instanceof UUID) return (UUID)value;
+            if (value instanceof String) return UUID.fromString((String)value);
+        }
+        return null;
+    }
+
+    /**
+     * {@inheritDoc}
+     * 
+     * @see Location#hashCode()
+     */
+    @Override
+    public int hashCode() {
+        return hashCode;
+    }
+
+    /**
+     * {@inheritDoc}
+     * 
+     * @see Location#with(Property)
+     */
+    @Override
+    public Location with( Property newIdProperty ) {
+        if (newIdProperty == null || newIdProperty.isEmpty()) return this;
+        Property idProperty = idProperties.get(0); // fast
+        if (newIdProperty.getName().equals(idProperty.getName())) {
+            return Location.create(newIdProperty);
+        }
+        List<Property> newIdProperties = new ArrayList<Property>(idProperties.size() + 1);
+        newIdProperties.add(newIdProperty);
+        newIdProperties.addAll(idProperties);
+        return new LocationWithProperties(newIdProperties);
+    }
+
+    /**
+     * {@inheritDoc}
+     * 
+     * @see Location#with(Path)
+     */
+    @Override
+    public Location with( Path newPath ) {
+        if (newPath == null) return this;
+        Property idProperty = idProperties.get(0); // fast
+        return new LocationWithPathAndProperty(newPath, idProperty);
+    }
+
+    /**
+     * {@inheritDoc}
+     * 
+     * @see Location#with(UUID)
+     */
+    @Override
+    public Location with( UUID uuid ) {
+        if (uuid == null) return this;
+        Property idProperty = idProperties.get(0); // fast
+        if (DnaLexicon.UUID.equals(idProperty.getName())) {
+            return new LocationWithUuid(uuid);
+        }
+        List<Property> newIdProperties = new ArrayList<Property>(idProperties.size() + 1);
+        newIdProperties.add(new BasicSingleValueProperty(DnaLexicon.UUID, uuid));
+        newIdProperties.addAll(idProperties);
+        return new LocationWithProperties(newIdProperties);
+    }
+}


Property changes on: trunk/dna-graph/src/main/java/org/jboss/dna/graph/LocationWithProperty.java
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/LocationWithUuid.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/LocationWithUuid.java	2009-03-06 17:03:00 UTC (rev 762)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/LocationWithUuid.java	2009-03-09 17:57:18 UTC (rev 763)
@@ -39,7 +39,7 @@
  * @see Location
  */
 @Immutable
-public class LocationWithUuid extends Location {
+final class LocationWithUuid extends Location {
 
     private final UUID uuid;
     private final int hashCode;

Modified: trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/AbstractJcrNode.java
===================================================================
--- trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/AbstractJcrNode.java	2009-03-06 17:03:00 UTC (rev 762)
+++ trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/AbstractJcrNode.java	2009-03-09 17:57:18 UTC (rev 763)
@@ -53,6 +53,7 @@
 import javax.jcr.version.VersionHistory;
 import net.jcip.annotations.NotThreadSafe;
 import org.jboss.dna.common.util.CheckArg;
+import org.jboss.dna.graph.Location;
 import org.jboss.dna.graph.property.Name;
 import org.jboss.dna.graph.property.NamespaceRegistry;
 import org.jboss.dna.graph.property.Path;
@@ -68,15 +69,18 @@
     private static final NodeType[] EMPTY_NODE_TYPES = new NodeType[] {};
 
     private final JcrSession session;
-    Map<Name, Property> properties;
-    List<Path.Segment> children;
-    private UUID uuid;
     private final NodeDefinition definition;
+    protected Location location;
+    private Map<Name, Property> properties;
+    private List<Path.Segment> children;
 
     AbstractJcrNode( JcrSession session,
+                     Location location,
                      NodeDefinition definition ) {
         assert session != null;
         assert definition != null;
+        assert location != null;
+        this.location = location;
         this.session = session;
         this.definition = definition;
     }
@@ -86,12 +90,16 @@
      * 
      * @see javax.jcr.Item#getSession()
      */
-    public final Session getSession() {
+    public Session getSession() {
         return session;
     }
 
+    final JcrSession session() {
+        return session;
+    }
+
     final UUID internalUuid() {
-        return uuid;
+        return location.getUuid();
     }
 
     /**
@@ -103,7 +111,7 @@
      */
     final void setInternalUuid( UUID uuid ) {
         assert uuid != null;
-        this.uuid = uuid;
+        location = location.with(uuid);
     }
 
     final void setChildren( List<Segment> children ) {

Modified: trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/AbstractJcrProperty.java
===================================================================
--- trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/AbstractJcrProperty.java	2009-03-06 17:03:00 UTC (rev 762)
+++ trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/AbstractJcrProperty.java	2009-03-09 17:57:18 UTC (rev 763)
@@ -43,23 +43,19 @@
 @NotThreadSafe
 abstract class AbstractJcrProperty extends AbstractJcrItem implements Property {
 
-    private final Node node;
-    private final ExecutionContext executionContext;
+    private final AbstractJcrNode node;
     private final org.jboss.dna.graph.property.Property dnaProperty;
     private final PropertyDefinition jcrPropertyDefinition;
     private final int propertyType;
 
-    AbstractJcrProperty( Node node,
-                         ExecutionContext executionContext,
+    AbstractJcrProperty( AbstractJcrNode node,
                          PropertyDefinition definition,
                          int propertyType,
                          org.jboss.dna.graph.property.Property dnaProperty ) {
         assert node != null;
-        assert executionContext != null;
         assert dnaProperty != null;
         assert definition != null;
         this.node = node;
-        this.executionContext = executionContext;
         this.dnaProperty = dnaProperty;
         this.jcrPropertyDefinition = definition;
         this.propertyType = propertyType;
@@ -77,11 +73,11 @@
     }
 
     JcrValue createValue( Object value ) {
-        return new JcrValue(executionContext.getValueFactories(), getType(), value);
+        return new JcrValue(getExecutionContext().getValueFactories(), getType(), value);
     }
 
     final ExecutionContext getExecutionContext() {
-        return executionContext;
+        return node.session().getExecutionContext();
     }
 
     final org.jboss.dna.graph.property.Property getDnaProperty() {
@@ -116,7 +112,7 @@
      * @see javax.jcr.Item#getName()
      */
     public final String getName() {
-        return dnaProperty.getName().getString(executionContext.getNamespaceRegistry());
+        return dnaProperty.getName().getString(node.namespaces());
     }
 
     /**
@@ -142,7 +138,7 @@
      * 
      * @see javax.jcr.Item#getSession()
      */
-    public final Session getSession() throws RepositoryException {
+    public final Session getSession() {
         return node.getSession();
     }
 

Modified: trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrMultiValueProperty.java
===================================================================
--- trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrMultiValueProperty.java	2009-03-06 17:03:00 UTC (rev 762)
+++ trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrMultiValueProperty.java	2009-03-09 17:57:18 UTC (rev 763)
@@ -32,7 +32,6 @@
 import javax.jcr.ValueFormatException;
 import javax.jcr.nodetype.PropertyDefinition;
 import net.jcip.annotations.NotThreadSafe;
-import org.jboss.dna.graph.ExecutionContext;
 import org.jboss.dna.graph.property.Property;
 
 /**
@@ -41,12 +40,11 @@
 @NotThreadSafe
 final class JcrMultiValueProperty extends AbstractJcrProperty {
 
-    JcrMultiValueProperty( Node node,
-                           ExecutionContext executionContext,
+    JcrMultiValueProperty( AbstractJcrNode node,
                            PropertyDefinition definition,
                            int propertyType,
                            Property dnaProperty ) {
-        super(node, executionContext, definition, propertyType, dnaProperty);
+        super(node, definition, propertyType, dnaProperty);
     }
 
     /**

Modified: trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrNode.java
===================================================================
--- trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrNode.java	2009-03-06 17:03:00 UTC (rev 762)
+++ trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrNode.java	2009-03-09 17:57:18 UTC (rev 763)
@@ -29,7 +29,8 @@
 import javax.jcr.RepositoryException;
 import javax.jcr.nodetype.NodeDefinition;
 import net.jcip.annotations.NotThreadSafe;
-import org.jboss.dna.graph.property.Path.Segment;
+import org.jboss.dna.graph.Location;
+import org.jboss.dna.graph.property.Path;
 
 /**
  * @author jverhaeg
@@ -38,26 +39,27 @@
 final class JcrNode extends AbstractJcrNode {
 
     private final UUID parentUuid;
-    private final Segment segment;
 
     JcrNode( JcrSession session,
              UUID parentUuid,
-             Segment segment,
+             Location location,
              NodeDefinition nodeDefinition ) {
-        super(session, nodeDefinition);
+        super(session, location, nodeDefinition);
         assert parentUuid != null;
-        assert segment != null;
         this.parentUuid = parentUuid;
-        this.segment = segment;
     }
 
+    final Path.Segment segment() {
+        return location.getPath().getLastSegment();
+    }
+
     /**
      * {@inheritDoc}
      * 
      * @see javax.jcr.Node#getIndex()
      */
     public int getIndex() {
-        return segment.getIndex();
+        return segment().getIndex();
     }
 
     /**
@@ -66,7 +68,7 @@
      * @see javax.jcr.Item#getName()
      */
     public String getName() {
-        return segment.getName().getString(((JcrSession)getSession()).getExecutionContext().getNamespaceRegistry());
+        return segment().getName().getString(((JcrSession)getSession()).getExecutionContext().getNamespaceRegistry());
     }
 
     /**
@@ -75,7 +77,7 @@
      * @see javax.jcr.Item#getParent()
      */
     public Node getParent() throws ItemNotFoundException {
-        Node node = ((JcrSession)getSession()).getNode(parentUuid);
+        Node node = session().getNode(parentUuid);
         if (node == null) {
             throw new ItemNotFoundException();
         }

Modified: trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrRootNode.java
===================================================================
--- trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrRootNode.java	2009-03-06 17:03:00 UTC (rev 762)
+++ trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrRootNode.java	2009-03-09 17:57:18 UTC (rev 763)
@@ -27,6 +27,7 @@
 import javax.jcr.Node;
 import javax.jcr.nodetype.NodeDefinition;
 import net.jcip.annotations.NotThreadSafe;
+import org.jboss.dna.graph.Location;
 
 /**
  * @author jverhaeg
@@ -35,8 +36,9 @@
 final class JcrRootNode extends AbstractJcrNode {
 
     JcrRootNode( JcrSession session,
+                 Location location,
                  NodeDefinition nodeDefinition ) {
-        super(session, nodeDefinition);
+        super(session, location, nodeDefinition);
     }
 
     /**

Modified: trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrSession.java
===================================================================
--- trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrSession.java	2009-03-06 17:03:00 UTC (rev 762)
+++ trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrSession.java	2009-03-09 17:57:18 UTC (rev 763)
@@ -506,7 +506,7 @@
             }
 
             // Create the new node ...
-            node = new JcrRootNode(this, definition);
+            node = new JcrRootNode(this, location, definition);
         } else {
             // Find the parent ...
             AbstractJcrNode parent = (AbstractJcrNode)getNode(path.getParent());
@@ -524,7 +524,7 @@
             }
 
             // Now create the node object ...
-            node = new JcrNode(this, parent.internalUuid(), path.getLastSegment(), definition);
+            node = new JcrNode(this, parent.internalUuid(), location, definition);
         }
 
         // Now populate the node and add to the cache ...
@@ -830,8 +830,8 @@
         Map<Name, Property> properties = new HashMap<Name, Property>();
         if (referenceable) {
             PropertyDefinition propertyDefinition = propertyDefinitionsByPropertyName.get(JcrLexicon.UUID);
-            properties.put(JcrLexicon.UUID, new JcrSingleValueProperty(node, executionContext, propertyDefinition,
-                                                                       PropertyType.STRING, uuidProperty));
+            properties.put(JcrLexicon.UUID, new JcrSingleValueProperty(node, propertyDefinition, PropertyType.STRING,
+                                                                       uuidProperty));
         }
 
         // Now create the JCR property object wrappers around the other properties ...
@@ -892,16 +892,16 @@
             }
 
             // Figure out the property type ...
-            int type = propertyDefinition.getRequiredType();
-            if (type == PropertyType.UNDEFINED) {
-                type = jcrPropertyTypeFor(dnaProp);
+            int propertyType = propertyDefinition.getRequiredType();
+            if (propertyType == PropertyType.UNDEFINED) {
+                propertyType = jcrPropertyTypeFor(dnaProp);
             }
 
             // Create the appropriate JCR property wrapper ...
             if (isMultiple) {
-                properties.put(name, new JcrMultiValueProperty(node, executionContext, propertyDefinition, type, dnaProp));
+                properties.put(name, new JcrMultiValueProperty(node, propertyDefinition, propertyType, dnaProp));
             } else {
-                properties.put(name, new JcrSingleValueProperty(node, executionContext, propertyDefinition, type, dnaProp));
+                properties.put(name, new JcrSingleValueProperty(node, propertyDefinition, propertyType, dnaProp));
             }
         }
 

Modified: trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrSingleValueProperty.java
===================================================================
--- trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrSingleValueProperty.java	2009-03-06 17:03:00 UTC (rev 762)
+++ trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrSingleValueProperty.java	2009-03-09 17:57:18 UTC (rev 763)
@@ -31,7 +31,6 @@
 import javax.jcr.Value;
 import javax.jcr.ValueFormatException;
 import javax.jcr.nodetype.PropertyDefinition;
-import org.jboss.dna.graph.ExecutionContext;
 import org.jboss.dna.graph.property.Binary;
 import org.jboss.dna.graph.property.Property;
 import org.jboss.dna.graph.property.Reference;
@@ -42,12 +41,11 @@
  */
 final class JcrSingleValueProperty extends AbstractJcrProperty {
 
-    JcrSingleValueProperty( Node node,
-                            ExecutionContext executionContext,
+    JcrSingleValueProperty( AbstractJcrNode node,
                             PropertyDefinition definition,
                             int propertyType,
                             Property dnaProperty ) {
-        super(node, executionContext, definition, propertyType, dnaProperty);
+        super(node, definition, propertyType, dnaProperty);
     }
 
     /**

Modified: trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/AbstractJcrNodeTest.java
===================================================================
--- trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/AbstractJcrNodeTest.java	2009-03-06 17:03:00 UTC (rev 762)
+++ trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/AbstractJcrNodeTest.java	2009-03-09 17:57:18 UTC (rev 763)
@@ -50,6 +50,7 @@
 import javax.jcr.nodetype.NodeDefinition;
 import javax.jcr.version.Version;
 import org.jboss.dna.graph.ExecutionContext;
+import org.jboss.dna.graph.Location;
 import org.jboss.dna.graph.property.Name;
 import org.jboss.dna.graph.property.Path.Segment;
 import org.junit.Before;
@@ -85,7 +86,7 @@
         MockAbstractJcrNode( JcrSession session,
                              String name,
                              Node parent ) {
-            super(session, mock(NodeDefinition.class));
+            super(session, Location.create(UUID.randomUUID()), mock(NodeDefinition.class));
             this.name = name;
             this.parent = parent;
         }

Modified: trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/AbstractJcrPropertyTest.java
===================================================================
--- trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/AbstractJcrPropertyTest.java	2009-03-06 17:03:00 UTC (rev 762)
+++ trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/AbstractJcrPropertyTest.java	2009-03-09 17:57:18 UTC (rev 763)
@@ -28,6 +28,7 @@
 import static org.mockito.Mockito.stub;
 import java.io.InputStream;
 import java.util.Calendar;
+import java.util.UUID;
 import javax.jcr.Item;
 import javax.jcr.ItemNotFoundException;
 import javax.jcr.ItemVisitor;
@@ -38,9 +39,12 @@
 import javax.jcr.Session;
 import javax.jcr.Value;
 import javax.jcr.Workspace;
+import javax.jcr.nodetype.NodeDefinition;
 import javax.jcr.nodetype.PropertyDefinition;
 import org.jboss.dna.common.util.StringUtil;
 import org.jboss.dna.graph.ExecutionContext;
+import org.jboss.dna.graph.Location;
+import org.jboss.dna.graph.property.Path;
 import org.junit.Before;
 import org.junit.Test;
 import org.mockito.Mockito;
@@ -58,13 +62,16 @@
     @Mock
     private Repository repository;
     @Mock
-    private Session session;
+    private JcrSession session;
+    private AbstractJcrNode node;
     @Mock
-    private Node node;
+    private NodeDefinition nodeDefinition;
     @Mock
     private PropertyDefinition propertyDefinition;
     private ExecutionContext executionContext;
     private org.jboss.dna.graph.property.Property dnaProperty;
+    private Location rootLocation;
+    private Location nodeLocation;
 
     @Before
     public void before() throws Exception {
@@ -74,8 +81,21 @@
         stub(propertyDefinition.getRequiredType()).toReturn(PropertyType.STRING);
         stub(session.getWorkspace()).toReturn(workspace);
         stub(session.getRepository()).toReturn(repository);
-        stub(node.getSession()).toReturn(session);
-        prop = new MockAbstractJcrProperty(node, executionContext, propertyDefinition, dnaProperty);
+        stub(session.getExecutionContext()).toReturn(executionContext);
+
+        UUID rootUuid = UUID.randomUUID();
+        Path rootPath = executionContext.getValueFactories().getPathFactory().createRootPath();
+        rootLocation = Location.create(rootPath, rootUuid);
+        JcrRootNode rootNode = new JcrRootNode(session, rootLocation, nodeDefinition);
+        stub(session.getNode(rootUuid)).toReturn(rootNode);
+
+        UUID uuid = UUID.randomUUID();
+        Path path = executionContext.getValueFactories().getPathFactory().create("/nodeName");
+        nodeLocation = Location.create(path, uuid);
+        node = new JcrNode(session, rootUuid, nodeLocation, nodeDefinition);
+        stub(session.getNode(uuid)).toReturn(node);
+
+        prop = new MockAbstractJcrProperty(node, propertyDefinition, dnaProperty);
     }
 
     @Test
@@ -99,19 +119,17 @@
     @Test
     public void shouldProvideAncestor() throws Exception {
         assertThat(prop.getAncestor(prop.getDepth()), is((Item)prop));
-        stub(node.getAncestor(node.getDepth())).toReturn(node);
         assertThat(prop.getAncestor(prop.getDepth() - 1), is((Item)node));
     }
 
     @Test( expected = ItemNotFoundException.class )
     public void shouldNotAllowAncestorDepthGreaterThanNodeDepth() throws Exception {
-        stub(node.getAncestor(1)).toThrow(new ItemNotFoundException());
-        prop.getAncestor(2);
+        prop.getAncestor(3);
     }
 
     @Test
     public void shouldProvideDepth() throws Exception {
-        assertThat(prop.getDepth(), is(1));
+        assertThat(prop.getDepth(), is(2));
     }
 
     @Test
@@ -126,20 +144,17 @@
 
     @Test
     public void shouldProvideParent() throws Exception {
-        assertThat(prop.getParent(), is(node));
+        assertThat(prop.getParent(), is((Node)node));
     }
 
     @Test
     public void shouldProvidePath() throws Exception {
-        stub(node.getPath()).toReturn("/nodeName");
         assertThat(prop.getPath(), is("/nodeName/jcr:mimeType"));
     }
 
     @Test
     public void shouldProvideSession() throws Exception {
-        Session session = Mockito.mock(Session.class);
-        stub(node.getSession()).toReturn(session);
-        assertThat(prop.getSession(), is(session));
+        assertThat(prop.getSession(), is((Session)session));
     }
 
     @Test
@@ -151,30 +166,40 @@
     public void shouldIndicateSameAsNodeWithSameParentAndSamePropertyName() throws Exception {
         org.jboss.dna.graph.property.Property otherDnaProperty = executionContext.getPropertyFactory()
                                                                                  .create(dnaProperty.getName());
-        Node otherNode = Mockito.mock(Node.class);
-        stub(otherNode.getSession()).toReturn(session);
-        stub(node.isSame(otherNode)).toReturn(true);
-        Property otherProp = new MockAbstractJcrProperty(otherNode, executionContext, propertyDefinition, otherDnaProperty);
+        // Make the other node have the same UUID ...
+        JcrNode otherNode = new JcrNode(session, rootLocation.getUuid(), nodeLocation, nodeDefinition);
+
+        assertThat(node.isSame(otherNode), is(true));
+        Property prop = new MockAbstractJcrProperty(node, propertyDefinition, otherDnaProperty);
+        Property otherProp = new MockAbstractJcrProperty(otherNode, propertyDefinition, otherDnaProperty);
         assertThat(prop.isSame(otherProp), is(true));
     }
 
     @Test
     public void shouldIndicateDifferentThanNodeWithDifferentParent() throws Exception {
-        org.jboss.dna.graph.property.Property otherDnaProperty = executionContext.getPropertyFactory().create(JcrLexicon.NAME);
-        Node otherNode = Mockito.mock(Node.class);
-        stub(otherNode.getSession()).toReturn(session);
-        stub(node.isSame(otherNode)).toReturn(false);
-        Property otherProp = new MockAbstractJcrProperty(otherNode, executionContext, propertyDefinition, otherDnaProperty);
+        org.jboss.dna.graph.property.Property otherDnaProperty = executionContext.getPropertyFactory()
+                                                                                 .create(dnaProperty.getName());
+        UUID otherUuid = UUID.randomUUID();
+        Path otherPath = executionContext.getValueFactories().getPathFactory().create("/nodeName");
+        Location location = Location.create(otherPath, otherUuid);
+        JcrNode otherNode = new JcrNode(session, rootLocation.getUuid(), location, nodeDefinition);
+        stub(session.getNode(otherUuid)).toReturn(otherNode);
+
+        assertThat(node.isSame(otherNode), is(false));
+        Property prop = new MockAbstractJcrProperty(node, propertyDefinition, otherDnaProperty);
+        Property otherProp = new MockAbstractJcrProperty(otherNode, propertyDefinition, otherDnaProperty);
         assertThat(prop.isSame(otherProp), is(false));
     }
 
     @Test
     public void shouldIndicateDifferentThanPropertyWithSameNodeWithDifferentPropertyName() throws Exception {
         org.jboss.dna.graph.property.Property otherDnaProperty = executionContext.getPropertyFactory().create(JcrLexicon.NAME);
-        Node otherNode = Mockito.mock(Node.class);
-        stub(otherNode.getSession()).toReturn(session);
-        stub(node.isSame(otherNode)).toReturn(true);
-        Property otherProp = new MockAbstractJcrProperty(otherNode, executionContext, propertyDefinition, otherDnaProperty);
+        // Make the other node have the same UUID ...
+        JcrNode otherNode = new JcrNode(session, rootLocation.getUuid(), nodeLocation, nodeDefinition);
+
+        assertThat(node.isSame(otherNode), is(true));
+        Property prop = new MockAbstractJcrProperty(node, propertyDefinition, dnaProperty);
+        Property otherProp = new MockAbstractJcrProperty(otherNode, propertyDefinition, otherDnaProperty);
         assertThat(prop.isSame(otherProp), is(false));
     }
 
@@ -230,11 +255,10 @@
 
     private class MockAbstractJcrProperty extends AbstractJcrProperty {
 
-        MockAbstractJcrProperty( Node node,
-                                 ExecutionContext executionContext,
+        MockAbstractJcrProperty( AbstractJcrNode node,
                                  PropertyDefinition propertyDefinition,
                                  org.jboss.dna.graph.property.Property dnaProperty ) {
-            super(node, executionContext, propertyDefinition, propertyDefinition.getRequiredType(), dnaProperty);
+            super(node, propertyDefinition, propertyDefinition.getRequiredType(), dnaProperty);
         }
 
         /**

Modified: trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/JcrMultiValuePropertyTest.java
===================================================================
--- trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/JcrMultiValuePropertyTest.java	2009-03-06 17:03:00 UTC (rev 762)
+++ trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/JcrMultiValuePropertyTest.java	2009-03-09 17:57:18 UTC (rev 763)
@@ -27,13 +27,16 @@
 import static org.hamcrest.core.IsNull.notNullValue;
 import static org.junit.Assert.assertThat;
 import static org.mockito.Mockito.stub;
-import javax.jcr.Node;
+import java.util.UUID;
 import javax.jcr.Property;
 import javax.jcr.PropertyType;
 import javax.jcr.Value;
 import javax.jcr.ValueFormatException;
+import javax.jcr.nodetype.NodeDefinition;
 import javax.jcr.nodetype.PropertyDefinition;
 import org.jboss.dna.graph.ExecutionContext;
+import org.jboss.dna.graph.Location;
+import org.jboss.dna.graph.property.Path;
 import org.junit.Before;
 import org.junit.Test;
 import org.mockito.MockitoAnnotations;
@@ -45,10 +48,13 @@
 public class JcrMultiValuePropertyTest {
 
     private Property prop;
-    @Mock
-    private Node node;
+    private AbstractJcrNode node;
     private ExecutionContext executionContext;
     @Mock
+    private JcrSession session;
+    @Mock
+    private NodeDefinition nodeDefinition;
+    @Mock
     private PropertyDefinition definition;
     private org.jboss.dna.graph.property.Property dnaProperty;
 
@@ -56,10 +62,17 @@
     public void before() {
         MockitoAnnotations.initMocks(this);
         executionContext = new ExecutionContext();
+
+        UUID rootUuid = UUID.randomUUID();
+        Path rootPath = executionContext.getValueFactories().getPathFactory().createRootPath();
+        Location rootLocation = Location.create(rootPath, rootUuid);
+        node = new JcrRootNode(session, rootLocation, nodeDefinition);
+        stub(session.getExecutionContext()).toReturn(executionContext);
+
         dnaProperty = executionContext.getPropertyFactory().create(JcrLexicon.MIMETYPE, true);
         stub(definition.getRequiredType()).toReturn(PropertyType.BOOLEAN);
         stub(definition.isMultiple()).toReturn(true);
-        prop = new JcrMultiValueProperty(node, executionContext, definition, definition.getRequiredType(), dnaProperty);
+        prop = new JcrMultiValueProperty(node, definition, definition.getRequiredType(), dnaProperty);
     }
 
     @Test
@@ -138,7 +151,7 @@
         dnaProperty = executionContext.getPropertyFactory().create(JcrLexicon.MIMETYPE, value);
         stub(definition.getRequiredType()).toReturn(PropertyType.STRING);
         stub(definition.isMultiple()).toReturn(true);
-        prop = new JcrMultiValueProperty(node, executionContext, definition, definition.getRequiredType(), dnaProperty);
+        prop = new JcrMultiValueProperty(node, definition, definition.getRequiredType(), dnaProperty);
         lengths = prop.getLengths();
         assertThat(lengths, notNullValue());
         assertThat(lengths.length, is(1));
@@ -149,7 +162,7 @@
         dnaProperty = executionContext.getPropertyFactory().create(JcrLexicon.MIMETYPE, value);
         stub(definition.getRequiredType()).toReturn(PropertyType.STRING);
         stub(definition.isMultiple()).toReturn(true);
-        prop = new JcrMultiValueProperty(node, executionContext, definition, definition.getRequiredType(), dnaProperty);
+        prop = new JcrMultiValueProperty(node, definition, definition.getRequiredType(), dnaProperty);
         lengths = prop.getLengths();
         assertThat(lengths, notNullValue());
         assertThat(lengths.length, is(1));
@@ -159,7 +172,7 @@
         dnaProperty = executionContext.getPropertyFactory().create(JcrLexicon.MIMETYPE, (Object[])values);
         stub(definition.getRequiredType()).toReturn(PropertyType.STRING);
         stub(definition.isMultiple()).toReturn(true);
-        prop = new JcrMultiValueProperty(node, executionContext, definition, definition.getRequiredType(), dnaProperty);
+        prop = new JcrMultiValueProperty(node, definition, definition.getRequiredType(), dnaProperty);
         lengths = prop.getLengths();
         assertThat(lengths, notNullValue());
         assertThat(lengths.length, is(values.length));

Modified: trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/JcrNodeTest.java
===================================================================
--- trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/JcrNodeTest.java	2009-03-06 17:03:00 UTC (rev 762)
+++ trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/JcrNodeTest.java	2009-03-09 17:57:18 UTC (rev 763)
@@ -25,7 +25,6 @@
 
 import static org.hamcrest.core.Is.is;
 import static org.junit.Assert.assertThat;
-import static org.mockito.Matchers.anyObject;
 import static org.mockito.Mockito.stub;
 import java.util.ArrayList;
 import java.util.HashMap;
@@ -35,12 +34,12 @@
 import javax.jcr.Property;
 import javax.jcr.nodetype.NodeDefinition;
 import org.jboss.dna.graph.ExecutionContext;
+import org.jboss.dna.graph.Location;
 import org.jboss.dna.graph.property.Name;
-import org.jboss.dna.graph.property.NamespaceRegistry;
+import org.jboss.dna.graph.property.Path;
 import org.jboss.dna.graph.property.Path.Segment;
 import org.junit.Before;
 import org.junit.Test;
-import org.mockito.Mockito;
 import org.mockito.MockitoAnnotations;
 import org.mockito.MockitoAnnotations.Mock;
 
@@ -61,17 +60,18 @@
     @Before
     public void before() throws Exception {
         MockitoAnnotations.initMocks(this);
-        root = new JcrRootNode(session, rootNodeDefinition);
-        Segment segment = Mockito.mock(Segment.class);
-        Name name = Mockito.mock(Name.class);
-        stub(name.getString((NamespaceRegistry)anyObject())).toReturn("name");
-        stub(segment.getName()).toReturn(name);
-        stub(segment.getIndex()).toReturn(2);
+        ExecutionContext context = new ExecutionContext();
+        UUID rootUuid = UUID.randomUUID();
+        Path rootPath = context.getValueFactories().getPathFactory().createRootPath();
+        Location rootLocation = Location.create(rootPath, rootUuid);
+        root = new JcrRootNode(session, rootLocation, rootNodeDefinition);
         UUID uuid = UUID.randomUUID();
-        node = new JcrNode(session, uuid, segment, nodeDefinition);
-        ExecutionContext context = Mockito.mock(ExecutionContext.class);
+        Path path = context.getValueFactories().getPathFactory().create("/name[2]");
+        Location location = Location.create(path, uuid);
+        node = new JcrNode(session, rootUuid, location, nodeDefinition);
         stub(session.getExecutionContext()).toReturn(context);
-        stub(session.getNode(uuid)).toReturn(root);
+        stub(session.getNode(rootUuid)).toReturn(root);
+        stub(session.getNode(uuid)).toReturn(node);
         node.setProperties(new HashMap<Name, Property>());
         node.setChildren(new ArrayList<Segment>());
     }

Modified: trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/JcrRootNodeTest.java
===================================================================
--- trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/JcrRootNodeTest.java	2009-03-06 17:03:00 UTC (rev 762)
+++ trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/JcrRootNodeTest.java	2009-03-09 17:57:18 UTC (rev 763)
@@ -28,10 +28,14 @@
 import static org.junit.Assert.assertThat;
 import java.util.HashMap;
 import java.util.Map;
+import java.util.UUID;
 import javax.jcr.ItemNotFoundException;
 import javax.jcr.Property;
 import javax.jcr.nodetype.NodeDefinition;
+import org.jboss.dna.graph.ExecutionContext;
+import org.jboss.dna.graph.Location;
 import org.jboss.dna.graph.property.Name;
+import org.jboss.dna.graph.property.Path;
 import org.junit.Before;
 import org.junit.Test;
 import org.mockito.MockitoAnnotations;
@@ -53,7 +57,11 @@
     public void before() throws Exception {
         MockitoAnnotations.initMocks(this);
         properties = new HashMap<Name, Property>();
-        root = new JcrRootNode(session, nodeDefinition);
+        ExecutionContext context = new ExecutionContext();
+        UUID rootUuid = UUID.randomUUID();
+        Path rootPath = context.getValueFactories().getPathFactory().createRootPath();
+        Location rootLocation = Location.create(rootPath, rootUuid);
+        root = new JcrRootNode(session, rootLocation, nodeDefinition);
         root.setProperties(properties);
     }
 

Modified: trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/JcrSingleValuePropertyTest.java
===================================================================
--- trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/JcrSingleValuePropertyTest.java	2009-03-06 17:03:00 UTC (rev 762)
+++ trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/JcrSingleValuePropertyTest.java	2009-03-09 17:57:18 UTC (rev 763)
@@ -35,8 +35,10 @@
 import javax.jcr.PropertyType;
 import javax.jcr.Value;
 import javax.jcr.ValueFormatException;
+import javax.jcr.nodetype.NodeDefinition;
 import javax.jcr.nodetype.PropertyDefinition;
 import org.jboss.dna.graph.ExecutionContext;
+import org.jboss.dna.graph.Location;
 import org.jboss.dna.graph.property.DateTime;
 import org.jboss.dna.graph.property.Name;
 import org.jboss.dna.graph.property.Path;
@@ -51,10 +53,13 @@
 public class JcrSingleValuePropertyTest {
 
     private Property prop;
-    @Mock
-    private Node node;
+    private AbstractJcrNode node;
     private ExecutionContext executionContext;
     @Mock
+    private JcrSession session;
+    @Mock
+    private NodeDefinition nodeDefinition;
+    @Mock
     Name name;
     @Mock
     private PropertyDefinition definition;
@@ -64,15 +69,22 @@
     public void before() {
         MockitoAnnotations.initMocks(this);
         executionContext = new ExecutionContext();
+
+        UUID rootUuid = UUID.randomUUID();
+        Path rootPath = executionContext.getValueFactories().getPathFactory().createRootPath();
+        Location rootLocation = Location.create(rootPath, rootUuid);
+        node = new JcrRootNode(session, rootLocation, nodeDefinition);
+        stub(session.getExecutionContext()).toReturn(executionContext);
+
         dnaProperty = executionContext.getPropertyFactory().create(JcrLexicon.MIMETYPE, "text/plain");
         stub(definition.isMultiple()).toReturn(false);
-        prop = new JcrSingleValueProperty(node, executionContext, definition, PropertyType.STRING, dnaProperty);
+        prop = new JcrSingleValueProperty(node, definition, PropertyType.STRING, dnaProperty);
     }
 
     @Test
     public void shouldProvideBoolean() throws Exception {
         dnaProperty = executionContext.getPropertyFactory().create(JcrLexicon.MIMETYPE, "true");
-        prop = new JcrSingleValueProperty(node, executionContext, definition, PropertyType.BOOLEAN, dnaProperty);
+        prop = new JcrSingleValueProperty(node, definition, PropertyType.BOOLEAN, dnaProperty);
         assertThat(prop.getBoolean(), is(true));
         assertThat(prop.getType(), is(PropertyType.BOOLEAN));
     }
@@ -88,7 +100,7 @@
     public void shouldProvideDate() throws Exception {
         DateTime dnaDate = executionContext.getValueFactories().getDateFactory().create();
         dnaProperty = executionContext.getPropertyFactory().create(JcrLexicon.MIMETYPE, dnaDate);
-        prop = new JcrSingleValueProperty(node, executionContext, definition, PropertyType.DATE, dnaProperty);
+        prop = new JcrSingleValueProperty(node, definition, PropertyType.DATE, dnaProperty);
         assertThat(prop.getDate(), is(dnaDate.toCalendar()));
         assertThat(prop.getLong(), is(dnaDate.getMilliseconds()));
         assertThat(prop.getType(), is(PropertyType.DATE));
@@ -100,10 +112,8 @@
         UUID referencedUuid = UUID.randomUUID();
         dnaProperty = executionContext.getPropertyFactory().create(JcrLexicon.MIMETYPE, referencedUuid);
         Node referencedNode = mock(Node.class);
-        JcrSession session = mock(JcrSession.class);
-        stub(node.getSession()).toReturn(session);
         stub(session.getNode(referencedUuid)).toReturn(referencedNode);
-        prop = new JcrSingleValueProperty(node, executionContext, definition, PropertyType.REFERENCE, dnaProperty);
+        prop = new JcrSingleValueProperty(node, definition, PropertyType.REFERENCE, dnaProperty);
         assertThat(prop.getNode(), is(referencedNode));
         assertThat(prop.getType(), is(PropertyType.REFERENCE));
         assertThat(prop.getName(), is(dnaProperty.getName().getString(executionContext.getNamespaceRegistry())));
@@ -112,12 +122,12 @@
     @Test
     public void shouldProvideDouble() throws Exception {
         dnaProperty = executionContext.getPropertyFactory().create(JcrLexicon.MIMETYPE, 1.0);
-        prop = new JcrSingleValueProperty(node, executionContext, definition, PropertyType.DOUBLE, dnaProperty);
+        prop = new JcrSingleValueProperty(node, definition, PropertyType.DOUBLE, dnaProperty);
         assertThat(prop.getDouble(), is(1.0));
         assertThat(prop.getType(), is(PropertyType.DOUBLE));
         assertThat(prop.getName(), is(dnaProperty.getName().getString(executionContext.getNamespaceRegistry())));
         dnaProperty = executionContext.getPropertyFactory().create(JcrLexicon.MIMETYPE, 1.0F);
-        prop = new JcrSingleValueProperty(node, executionContext, definition, PropertyType.DOUBLE, dnaProperty);
+        prop = new JcrSingleValueProperty(node, definition, PropertyType.DOUBLE, dnaProperty);
         assertThat(prop.getDouble(), is(1.0));
         assertThat(prop.getType(), is(PropertyType.DOUBLE));
         assertThat(prop.getName(), is(dnaProperty.getName().getString(executionContext.getNamespaceRegistry())));
@@ -126,13 +136,13 @@
     @Test
     public void shouldProvideLong() throws Exception {
         dnaProperty = executionContext.getPropertyFactory().create(JcrLexicon.MIMETYPE, 1);
-        prop = new JcrSingleValueProperty(node, executionContext, definition, PropertyType.DOUBLE, dnaProperty);
+        prop = new JcrSingleValueProperty(node, definition, PropertyType.DOUBLE, dnaProperty);
         assertThat(prop.getLong(), is(1L));
         assertThat(prop.getType(), is(PropertyType.DOUBLE));
         assertThat(prop.getName(), is(dnaProperty.getName().getString(executionContext.getNamespaceRegistry())));
 
         dnaProperty = executionContext.getPropertyFactory().create(JcrLexicon.MIMETYPE, 1L);
-        prop = new JcrSingleValueProperty(node, executionContext, definition, PropertyType.DOUBLE, dnaProperty);
+        prop = new JcrSingleValueProperty(node, definition, PropertyType.DOUBLE, dnaProperty);
         assertThat(prop.getLong(), is(1L));
         assertThat(prop.getString(), is("1"));
         assertThat(prop.getType(), is(PropertyType.DOUBLE));
@@ -142,7 +152,7 @@
     @Test
     public void shouldProvideStream() throws Exception {
         dnaProperty = executionContext.getPropertyFactory().create(JcrLexicon.MIMETYPE, new Object());
-        prop = new JcrSingleValueProperty(node, executionContext, definition, PropertyType.BINARY, dnaProperty);
+        prop = new JcrSingleValueProperty(node, definition, PropertyType.BINARY, dnaProperty);
         assertThat(prop.getType(), is(PropertyType.BINARY));
         assertThat(prop.getName(), is(dnaProperty.getName().getString(executionContext.getNamespaceRegistry())));
         InputStream stream = prop.getStream();
@@ -158,7 +168,7 @@
     @Test
     public void shouldProvideString() throws Exception {
         dnaProperty = executionContext.getPropertyFactory().create(JcrLexicon.MIMETYPE, "value");
-        prop = new JcrSingleValueProperty(node, executionContext, definition, PropertyType.STRING, dnaProperty);
+        prop = new JcrSingleValueProperty(node, definition, PropertyType.STRING, dnaProperty);
         assertThat(prop.getString(), is("value"));
         assertThat(prop.getType(), is(PropertyType.STRING));
         assertThat(prop.getName(), is(dnaProperty.getName().getString(executionContext.getNamespaceRegistry())));
@@ -168,7 +178,7 @@
     public void shouldAllowReferenceValue() throws Exception {
         UUID uuid = UUID.randomUUID();
         dnaProperty = executionContext.getPropertyFactory().create(JcrLexicon.MIMETYPE, uuid);
-        prop = new JcrSingleValueProperty(node, executionContext, definition, PropertyType.STRING, dnaProperty);
+        prop = new JcrSingleValueProperty(node, definition, PropertyType.STRING, dnaProperty);
         assertThat(prop.getString(), is(uuid.toString()));
         assertThat(prop.getType(), is(PropertyType.STRING));
         assertThat(prop.getName(), is(dnaProperty.getName().getString(executionContext.getNamespaceRegistry())));
@@ -179,7 +189,7 @@
         executionContext.getNamespaceRegistry().register("acme", "http://example.com");
         Name path = executionContext.getValueFactories().getNameFactory().create("acme:something");
         dnaProperty = executionContext.getPropertyFactory().create(JcrLexicon.MIMETYPE, path);
-        prop = new JcrSingleValueProperty(node, executionContext, definition, PropertyType.NAME, dnaProperty);
+        prop = new JcrSingleValueProperty(node, definition, PropertyType.NAME, dnaProperty);
         assertThat(prop.getString(), is("acme:something"));
         assertThat(prop.getType(), is(PropertyType.NAME));
         assertThat(prop.getName(), is(dnaProperty.getName().getString(executionContext.getNamespaceRegistry())));
@@ -193,7 +203,7 @@
         executionContext.getNamespaceRegistry().register("acme", "http://example.com");
         Path path = executionContext.getValueFactories().getPathFactory().create("/a/b/acme:c");
         dnaProperty = executionContext.getPropertyFactory().create(JcrLexicon.MIMETYPE, (Object)path);
-        prop = new JcrSingleValueProperty(node, executionContext, definition, PropertyType.PATH, dnaProperty);
+        prop = new JcrSingleValueProperty(node, definition, PropertyType.PATH, dnaProperty);
         assertThat(prop.getString(), is("/a/b/acme:c"));
         assertThat(prop.getType(), is(PropertyType.PATH));
         assertThat(prop.getName(), is(dnaProperty.getName().getString(executionContext.getNamespaceRegistry())));
@@ -220,13 +230,13 @@
 
         dnaValue = "some other value";
         dnaProperty = executionContext.getPropertyFactory().create(JcrLexicon.MIMETYPE, dnaValue);
-        prop = new JcrSingleValueProperty(node, executionContext, definition, PropertyType.STRING, dnaProperty);
+        prop = new JcrSingleValueProperty(node, definition, PropertyType.STRING, dnaProperty);
         assertThat(prop.getLength(), is((long)dnaValue.length()));
 
         Object obj = new Object();
         long binaryLength = executionContext.getValueFactories().getBinaryFactory().create(obj).getSize();
         dnaProperty = executionContext.getPropertyFactory().create(JcrLexicon.MIMETYPE, obj);
-        prop = new JcrSingleValueProperty(node, executionContext, definition, PropertyType.BINARY, dnaProperty);
+        prop = new JcrSingleValueProperty(node, definition, PropertyType.BINARY, dnaProperty);
         assertThat(prop.getLength(), is(binaryLength));
     }
 




More information about the dna-commits mailing list