You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by ro...@apache.org on 2017/11/07 10:17:32 UTC

[sling-org-apache-sling-testing-jcr-mock] 05/10: SLING-4042 make sure JCR mock supports accessing data using multiple sessions

This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.testing.jcr-mock-1.0.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-testing-jcr-mock.git

commit 3c1c4ddba01d15e1ec7abcd9acac2c5e34ac7fd4
Author: sseifert <ss...@unknown>
AuthorDate: Thu Oct 16 17:53:47 2014 +0000

    SLING-4042 make sure JCR mock supports accessing data using multiple sessions
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/testing/mocks/jcr-mock@1632397 13f79535-47bb-0310-9956-ffa450edef68
---
 .../apache/sling/testing/mock/jcr/ItemData.java    | 136 +++++++++++++++++++++
 .../apache/sling/testing/mock/jcr/ItemFilter.java  |   3 +-
 .../apache/sling/testing/mock/jcr/MockNode.java    | 110 ++++++++++-------
 .../sling/testing/mock/jcr/MockProperty.java       | 106 +++++++++-------
 .../sling/testing/mock/jcr/MockRepository.java     |  12 +-
 .../apache/sling/testing/mock/jcr/MockSession.java |  40 +++---
 .../sling/testing/mock/jcr/MockNodeTest.java       |  13 +-
 .../sling/testing/mock/jcr/MockRepositoryTest.java |  53 ++++++--
 .../sling/testing/mock/jcr/MockSessionTest.java    |  31 +++--
 9 files changed, 362 insertions(+), 142 deletions(-)

diff --git a/src/main/java/org/apache/sling/testing/mock/jcr/ItemData.java b/src/main/java/org/apache/sling/testing/mock/jcr/ItemData.java
new file mode 100644
index 0000000..21b2678
--- /dev/null
+++ b/src/main/java/org/apache/sling/testing/mock/jcr/ItemData.java
@@ -0,0 +1,136 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.testing.mock.jcr;
+
+import java.util.UUID;
+
+import javax.jcr.Item;
+import javax.jcr.Session;
+import javax.jcr.Value;
+import javax.jcr.nodetype.NodeType;
+
+/**
+ * Holds node and property item data independently from session.
+ */
+class ItemData {
+    
+    private final String path;
+    private final boolean isNode;
+    private final String uuid;
+    private final NodeType nodeType;
+    private Value[] values;
+    private boolean isMultiple;
+    
+    private ItemData(String path, boolean isNode, String uuid, NodeType nodeType) {
+        super();
+        this.path = path;
+        this.uuid = uuid;
+        this.isNode = isNode;
+        this.nodeType = nodeType;
+    }
+    
+    public String getPath() {
+        return path;
+    }
+    
+    public String getName() {
+        return ResourceUtil.getName(path);
+    }
+
+    public boolean isNode() {
+        return isNode;
+    }
+    
+    public boolean isProperty() {
+        return !isNode;
+    }
+    
+    public String getUuid() {
+        if (!isNode()) {
+            throw new UnsupportedOperationException();
+        }
+        return uuid;
+    }
+
+    public NodeType getNodeType() {
+        if (!isNode()) {
+            throw new UnsupportedOperationException();
+        }
+        return nodeType;
+    }
+
+    public Value[] getValues() {
+        if (!isProperty()) {
+            throw new UnsupportedOperationException();
+        }
+        return values;
+    }
+
+    public void setValues(Value[] values) {
+        if (!isProperty()) {
+            throw new UnsupportedOperationException();
+        }
+        this.values = values;
+    }
+
+    public boolean isMultiple() {
+        if (!isProperty()) {
+            throw new UnsupportedOperationException();
+        }
+        return isMultiple;
+    }
+
+    public void setMultiple(boolean isMultiple) {
+        if (!isProperty()) {
+            throw new UnsupportedOperationException();
+        }
+        this.isMultiple = isMultiple;
+    }
+    
+    public Item getItem(Session session) {
+        if (isNode) {
+            return new MockNode(this, session);
+        }
+        else {
+            return new MockProperty(this, session);
+        }
+    }
+    
+    @Override
+    public int hashCode() {
+        return path.hashCode();
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj instanceof ItemData) {
+            return path.equals(((ItemData)obj).path);
+        }
+        return false;
+    }
+
+    public static ItemData newNode(String path, NodeType nodeType) {
+        return new ItemData(path, true, UUID.randomUUID().toString(), nodeType);
+    }
+    
+    public static ItemData newProperty(String path) {
+        return new ItemData(path, false, null, null);
+    }
+    
+}
diff --git a/src/main/java/org/apache/sling/testing/mock/jcr/ItemFilter.java b/src/main/java/org/apache/sling/testing/mock/jcr/ItemFilter.java
index 2e144a1..cda6b42 100644
--- a/src/main/java/org/apache/sling/testing/mock/jcr/ItemFilter.java
+++ b/src/main/java/org/apache/sling/testing/mock/jcr/ItemFilter.java
@@ -18,7 +18,6 @@
  */
 package org.apache.sling.testing.mock.jcr;
 
-import javax.jcr.Item;
 import javax.jcr.RepositoryException;
 
 /**
@@ -26,6 +25,6 @@ import javax.jcr.RepositoryException;
  */
 interface ItemFilter {
 
-    boolean accept(Item item) throws RepositoryException;
+    boolean accept(ItemData item) throws RepositoryException;
 
 }
diff --git a/src/main/java/org/apache/sling/testing/mock/jcr/MockNode.java b/src/main/java/org/apache/sling/testing/mock/jcr/MockNode.java
index 41350d6..d53f43c 100644
--- a/src/main/java/org/apache/sling/testing/mock/jcr/MockNode.java
+++ b/src/main/java/org/apache/sling/testing/mock/jcr/MockNode.java
@@ -21,7 +21,6 @@ package org.apache.sling.testing.mock.jcr;
 import java.io.InputStream;
 import java.math.BigDecimal;
 import java.util.Calendar;
-import java.util.UUID;
 import java.util.regex.Pattern;
 
 import javax.jcr.Binary;
@@ -50,12 +49,11 @@ import org.apache.jackrabbit.commons.iterator.PropertyIteratorAdapter;
  */
 class MockNode extends AbstractItem implements Node {
 
-    private final UUID uuid = UUID.randomUUID();
-    private final NodeType nodeType;
+    private final ItemData itemData;
 
-    public MockNode(final String path, final Session session, final NodeType nodeType) {
-        super(path, session);
-        this.nodeType = nodeType;
+    public MockNode(final ItemData itemData, final Session session) {
+        super(itemData.getPath(), session);
+        this.itemData = itemData;
     }
 
     @Override
@@ -66,8 +64,9 @@ class MockNode extends AbstractItem implements Node {
     @Override
     public Node addNode(final String relPath, final String primaryNodeTypeName) throws RepositoryException {
         String path = makeAbsolutePath(relPath);
-        Node node = new MockNode(path, getSession(), new MockNodeType(primaryNodeTypeName));
-        getMockedSession().addItem(node);
+        ItemData itemData = ItemData.newNode(path, new MockNodeType(primaryNodeTypeName));
+        Node node = new MockNode(itemData, getSession());
+        getMockedSession().addItem(itemData);
         return node;
     }
 
@@ -81,8 +80,8 @@ class MockNode extends AbstractItem implements Node {
     public NodeIterator getNodes() throws RepositoryException {
         RangeIterator items = getMockedSession().listChildren(getPath(), new ItemFilter() {
             @Override
-            public boolean accept(final Item item) {
-                return item instanceof Node;
+            public boolean accept(final ItemData item) {
+                return item.isNode();
             }
         });
         return new NodeIteratorAdapter(items, items.getSize());
@@ -93,8 +92,8 @@ class MockNode extends AbstractItem implements Node {
         final Pattern pattern = Pattern.compile(namePattern);
         RangeIterator items = getMockedSession().listChildren(getPath(), new ItemFilter() {
             @Override
-            public boolean accept(final Item item) throws RepositoryException {
-                return (item instanceof Node) && pattern.matcher(item.getName()).matches();
+            public boolean accept(final ItemData item) throws RepositoryException {
+                return item.isNode() && pattern.matcher(item.getName()).matches();
             }
         });
         return new NodeIteratorAdapter(items, items.getSize());
@@ -104,8 +103,8 @@ class MockNode extends AbstractItem implements Node {
     public PropertyIterator getProperties() throws RepositoryException {
         RangeIterator items = getMockedSession().listChildren(getPath(), new ItemFilter() {
             @Override
-            public boolean accept(final Item item) {
-                return item instanceof Property;
+            public boolean accept(final ItemData item) {
+                return item.isProperty();
             }
         });
         return new PropertyIteratorAdapter(items, items.getSize());
@@ -116,8 +115,8 @@ class MockNode extends AbstractItem implements Node {
         final Pattern pattern = Pattern.compile(namePattern);
         RangeIterator items = getMockedSession().listChildren(getPath(), new ItemFilter() {
             @Override
-            public boolean accept(final Item item) throws RepositoryException {
-                return (item instanceof Property) && pattern.matcher(item.getName()).matches();
+            public boolean accept(final ItemData item) throws RepositoryException {
+                return item.isProperty() && pattern.matcher(item.getName()).matches();
             }
         });
         return new PropertyIteratorAdapter(items, items.getSize());
@@ -131,7 +130,7 @@ class MockNode extends AbstractItem implements Node {
 
     @Override
     public String getIdentifier() {
-        return this.uuid.toString();
+        return this.itemData.getUuid();
     }
 
     @Override
@@ -163,98 +162,110 @@ class MockNode extends AbstractItem implements Node {
 
     @Override
     public Property setProperty(final String name, final Value value) throws RepositoryException {
-        Property property = new MockProperty(getPath() + "/" + name, getSession());
+        ItemData itemData = ItemData.newProperty(getPath() + "/" + name);
+        Property property = new MockProperty(itemData, getSession());
         property.setValue(value);
-        getMockedSession().addItem(property);
+        getMockedSession().addItem(itemData);
         return property;
     }
 
     @Override
     public Property setProperty(final String name, final Value[] values) throws RepositoryException {
-        Property property = new MockProperty(getPath() + "/" + name, getSession());
+        ItemData itemData = ItemData.newProperty(getPath() + "/" + name);
+        Property property = new MockProperty(itemData, getSession());
         property.setValue(values);
-        getMockedSession().addItem(property);
+        getMockedSession().addItem(itemData);
         return property;
     }
 
     @Override
     public Property setProperty(final String name, final String[] values) throws RepositoryException {
-        Property property = new MockProperty(getPath() + "/" + name, getSession());
+        ItemData itemData = ItemData.newProperty(getPath() + "/" + name);
+        Property property = new MockProperty(itemData, getSession());
         property.setValue(values);
-        getMockedSession().addItem(property);
+        getMockedSession().addItem(itemData);
         return property;
     }
 
     @Override
     public Property setProperty(final String name, final String value) throws RepositoryException {
-        Property property = new MockProperty(getPath() + "/" + name, getSession());
+        ItemData itemData = ItemData.newProperty(getPath() + "/" + name);
+        Property property = new MockProperty(itemData, getSession());
         property.setValue(value);
-        getMockedSession().addItem(property);
+        getMockedSession().addItem(itemData);
         return property;
     }
 
     @Override
     @SuppressWarnings("deprecation")
     public Property setProperty(final String name, final InputStream value) throws RepositoryException {
-        Property property = new MockProperty(getPath() + "/" + name, getSession());
+        ItemData itemData = ItemData.newProperty(getPath() + "/" + name);
+        Property property = new MockProperty(itemData, getSession());
         property.setValue(value);
-        getMockedSession().addItem(property);
+        getMockedSession().addItem(itemData);
         return property;
     }
 
     @Override
     public Property setProperty(final String name, final boolean value) throws RepositoryException {
-        Property property = new MockProperty(getPath() + "/" + name, getSession());
+        ItemData itemData = ItemData.newProperty(getPath() + "/" + name);
+        Property property = new MockProperty(itemData, getSession());
         property.setValue(value);
-        getMockedSession().addItem(property);
+        getMockedSession().addItem(itemData);
         return property;
     }
 
     @Override
     public Property setProperty(final String name, final double value) throws RepositoryException {
-        Property property = new MockProperty(getPath() + "/" + name, getSession());
+        ItemData itemData = ItemData.newProperty(getPath() + "/" + name);
+        Property property = new MockProperty(itemData, getSession());
         property.setValue(value);
-        getMockedSession().addItem(property);
+        getMockedSession().addItem(itemData);
         return property;
     }
 
     @Override
     public Property setProperty(final String name, final long value) throws RepositoryException {
-        Property property = new MockProperty(getPath() + "/" + name, getSession());
+        ItemData itemData = ItemData.newProperty(getPath() + "/" + name);
+        Property property = new MockProperty(itemData, getSession());
         property.setValue(value);
-        getMockedSession().addItem(property);
+        getMockedSession().addItem(itemData);
         return property;
     }
 
     @Override
     public Property setProperty(final String name, final Calendar value) throws RepositoryException {
-        Property property = new MockProperty(getPath() + "/" + name, getSession());
+        ItemData itemData = ItemData.newProperty(getPath() + "/" + name);
+        Property property = new MockProperty(itemData, getSession());
         property.setValue(value);
-        getMockedSession().addItem(property);
+        getMockedSession().addItem(itemData);
         return property;
     }
 
     @Override
     public Property setProperty(final String name, final Node value) throws RepositoryException {
-        Property property = new MockProperty(getPath() + "/" + name, getSession());
+        ItemData itemData = ItemData.newProperty(getPath() + "/" + name);
+        Property property = new MockProperty(itemData, getSession());
         property.setValue(value);
-        getMockedSession().addItem(property);
+        getMockedSession().addItem(itemData);
         return property;
     }
 
     @Override
     public Property setProperty(final String name, final Binary value) throws RepositoryException {
-        Property property = new MockProperty(getPath() + "/" + name, getSession());
+        ItemData itemData = ItemData.newProperty(getPath() + "/" + name);
+        Property property = new MockProperty(itemData, getSession());
         property.setValue(value);
-        getMockedSession().addItem(property);
+        getMockedSession().addItem(itemData);
         return property;
     }
 
     @Override
     public Property setProperty(final String name, final BigDecimal value) throws RepositoryException {
-        Property property = new MockProperty(getPath() + "/" + name, getSession());
+        ItemData itemData = ItemData.newProperty(getPath() + "/" + name);
+        Property property = new MockProperty(itemData, getSession());
         property.setValue(value);
-        getMockedSession().addItem(property);
+        getMockedSession().addItem(itemData);
         return property;
     }
 
@@ -265,12 +276,12 @@ class MockNode extends AbstractItem implements Node {
 
     @Override
     public boolean isNodeType(final String nodeTypeName) throws RepositoryException {
-        return this.nodeType.isNodeType(nodeTypeName);
+        return this.itemData.getNodeType().isNodeType(nodeTypeName);
     }
 
     @Override
     public NodeType getPrimaryNodeType() {
-        return this.nodeType;
+        return this.itemData.getNodeType();
     }
 
     @Override
@@ -284,6 +295,19 @@ class MockNode extends AbstractItem implements Node {
             throw new ItemNotFoundException();
         }
     }
+    
+    @Override
+    public int hashCode() {
+        return itemData.hashCode();
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj instanceof MockNode) {
+            return itemData.equals(((MockNode)obj).itemData);
+        }
+        return false;
+    }
 
     // --- unsupported operations ---
     @Override
diff --git a/src/main/java/org/apache/sling/testing/mock/jcr/MockProperty.java b/src/main/java/org/apache/sling/testing/mock/jcr/MockProperty.java
index 468a840..40a3b40 100644
--- a/src/main/java/org/apache/sling/testing/mock/jcr/MockProperty.java
+++ b/src/main/java/org/apache/sling/testing/mock/jcr/MockProperty.java
@@ -39,20 +39,27 @@ import org.apache.jackrabbit.value.BinaryValue;
  */
 class MockProperty extends AbstractItem implements Property {
 
-    private Value[] values;
-    private boolean isMultiple;
-
-    public MockProperty(final String path, final Session session) throws RepositoryException {
-        super(path, session);
-        this.values = new Value[] { getSession().getValueFactory().createValue("") };
+    private final ItemData itemData;
+
+    public MockProperty(final ItemData itemData, final Session session) {
+        super(itemData.getPath(), session);
+        this.itemData = itemData;
+        if (this.itemData.getValues() == null) {
+            try {
+                this.itemData.setValues(new Value[] { getSession().getValueFactory().createValue("") });
+            }
+            catch (RepositoryException ex) {
+                throw new RuntimeException("Initializing property failed.", ex);
+            }
+        }
     }
 
     private Value internalGetValue() throws ValueFormatException {
-        if (this.values.length > 1) {
+        if (this.itemData.getValues().length > 1) {
             throw new ValueFormatException(this
                     + " is a multi-valued property, so it's values can only be retrieved as an array");
         } else {
-            return this.values[0];
+            return this.itemData.getValues()[0];
         }
     }
 
@@ -63,89 +70,91 @@ class MockProperty extends AbstractItem implements Property {
 
     @Override
     public Value[] getValues() {
-        Value[] valuesCopy = new Value[this.values.length];
-        for (int i = 0; i < this.values.length; i++) {
-            valuesCopy[i] = this.values[i];
+        Value[] valuesCopy = new Value[this.itemData.getValues().length];
+        for (int i = 0; i < this.itemData.getValues().length; i++) {
+            valuesCopy[i] = this.itemData.getValues()[i];
         }
         return valuesCopy;
     }
 
     @Override
     public void setValue(final Value newValue) {
-        this.values = new Value[] { newValue };
-        this.isMultiple = false;
+        this.itemData.setValues(new Value[] { newValue });
+        this.itemData.setMultiple(false);
     }
 
     @Override
     public void setValue(final Value[] newValues) {
-        this.values = new Value[newValues.length];
+        Value[] values = new Value[newValues.length];
         for (int i = 0; i < newValues.length; i++) {
-            this.values[i] = newValues[i];
+            values[i] = newValues[i];
         }
-        this.isMultiple = true;
+        this.itemData.setValues(values);
+        this.itemData.setMultiple(true);
     }
 
     @Override
     public void setValue(final String newValue) throws RepositoryException {
-        this.values = new Value[] { getSession().getValueFactory().createValue(newValue) };
-        this.isMultiple = false;
+        this.itemData.setValues(new Value[] { getSession().getValueFactory().createValue(newValue) });
+        this.itemData.setMultiple(false);
     }
 
     @Override
     public void setValue(final String[] newValues) throws RepositoryException {
-        this.values = new Value[newValues.length];
+        Value[] values = new Value[newValues.length];
         for (int i = 0; i < newValues.length; i++) {
-            this.values[i] = getSession().getValueFactory().createValue(newValues[i]);
+            values[i] = getSession().getValueFactory().createValue(newValues[i]);
         }
-        this.isMultiple = true;
+        this.itemData.setValues(values);
+        this.itemData.setMultiple(true);
     }
 
     @Override
     public void setValue(final InputStream newValue) throws RepositoryException {
-        this.values = new Value[] { new BinaryValue(newValue) };
-        this.isMultiple = false;
+        this.itemData.setValues(new Value[] { new BinaryValue(newValue) });
+        this.itemData.setMultiple(false);
     }
 
     @Override
     public void setValue(final long newValue) throws RepositoryException {
-        this.values = new Value[] { getSession().getValueFactory().createValue(newValue) };
-        this.isMultiple = false;
+        this.itemData.setValues(new Value[] { getSession().getValueFactory().createValue(newValue) });
+        this.itemData.setMultiple(false);
     }
 
     @Override
     public void setValue(final double newValue) throws RepositoryException {
-        this.values = new Value[] { getSession().getValueFactory().createValue(newValue) };
-        this.isMultiple = false;
+        this.itemData.setValues(new Value[] { getSession().getValueFactory().createValue(newValue) });
+        this.itemData.setMultiple(false);
     }
 
     @Override
     public void setValue(final Calendar newValue) throws RepositoryException {
-        this.values = new Value[] { getSession().getValueFactory().createValue(newValue) };
-        this.isMultiple = false;
+        this.itemData.setValues(new Value[] { getSession().getValueFactory().createValue(newValue) });
+        this.itemData.setMultiple(false);
     }
 
     @Override
     public void setValue(final boolean newValue) throws RepositoryException {
-        this.values = new Value[] { getSession().getValueFactory().createValue(newValue) };
-        this.isMultiple = false;
+        this.itemData.setValues(new Value[] { getSession().getValueFactory().createValue(newValue) });
+        this.itemData.setMultiple(false);
     }
 
     @Override
     public void setValue(final Node newValue) throws RepositoryException {
-        this.values = new Value[] { getSession().getValueFactory().createValue(newValue) };
-        this.isMultiple = false;
+        this.itemData.setValues(new Value[] { getSession().getValueFactory().createValue(newValue) });
+        this.itemData.setMultiple(false);
     }
 
     @Override
     public void setValue(final Binary newValue) throws RepositoryException {
-        this.values = new Value[] { new BinaryValue(newValue) };
-        this.isMultiple = false;
+        this.itemData.setValues(new Value[] { new BinaryValue(newValue) });
+        this.itemData.setMultiple(false);
     }
 
     @Override
     public void setValue(final BigDecimal newValue) throws RepositoryException {
-        this.values = new Value[] { getSession().getValueFactory().createValue(newValue) };
-        this.isMultiple = false;
+        this.itemData.setValues(new Value[] { getSession().getValueFactory().createValue(newValue) });
+        this.itemData.setMultiple(false);
     }
 
     @Override
@@ -191,7 +200,7 @@ class MockProperty extends AbstractItem implements Property {
 
     @Override
     public int getType() throws RepositoryException {
-        return this.values[0].getType();
+        return this.itemData.getValues()[0].getType();
     }
 
     @Override
@@ -201,9 +210,9 @@ class MockProperty extends AbstractItem implements Property {
 
     @Override
     public long[] getLengths() throws RepositoryException {
-        long[] lengths = new long[this.values.length];
-        for (int i = 0; i < this.values.length; i++) {
-            lengths[i] = this.values[i].getString().length();
+        long[] lengths = new long[this.itemData.getValues().length];
+        for (int i = 0; i < this.itemData.getValues().length; i++) {
+            lengths[i] = this.itemData.getValues()[i].getString().length();
         }
         return lengths;
     }
@@ -215,7 +224,7 @@ class MockProperty extends AbstractItem implements Property {
 
     @Override
     public boolean isMultiple() {
-        return this.isMultiple;
+        return this.itemData.isMultiple();
     }
 
     @Override
@@ -223,6 +232,19 @@ class MockProperty extends AbstractItem implements Property {
         return new MockPropertyDefinition();
     }
 
+    @Override
+    public int hashCode() {
+        return itemData.hashCode();
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj instanceof MockProperty) {
+            return itemData.equals(((MockProperty)obj).itemData);
+        }
+        return false;
+    }
+    
     // --- unsupported operations ---
     @Override
     public Node getNode() {
diff --git a/src/main/java/org/apache/sling/testing/mock/jcr/MockRepository.java b/src/main/java/org/apache/sling/testing/mock/jcr/MockRepository.java
index 324820e..84e342b 100644
--- a/src/main/java/org/apache/sling/testing/mock/jcr/MockRepository.java
+++ b/src/main/java/org/apache/sling/testing/mock/jcr/MockRepository.java
@@ -18,6 +18,9 @@
  */
 package org.apache.sling.testing.mock.jcr;
 
+import java.util.LinkedHashMap;
+import java.util.Map;
+
 import javax.jcr.Credentials;
 import javax.jcr.Repository;
 import javax.jcr.Session;
@@ -32,9 +35,16 @@ import org.apache.commons.lang3.ArrayUtils;
  */
 class MockRepository implements Repository {
 
+    // Use linked hashmap to ensure ordering when adding items is preserved.
+    private final Map<String, ItemData> items = new LinkedHashMap<String, ItemData>();
+    
+    public MockRepository() {
+        this.items.put("/", ItemData.newNode("/", MockNodeTypes.NT_UNSTRUCTURED));
+    }
+    
     @Override
     public Session login() {
-        return new MockSession(this);
+        return new MockSession(this, items);
     }
 
     @Override
diff --git a/src/main/java/org/apache/sling/testing/mock/jcr/MockSession.java b/src/main/java/org/apache/sling/testing/mock/jcr/MockSession.java
index 5567318..37f5876 100644
--- a/src/main/java/org/apache/sling/testing/mock/jcr/MockSession.java
+++ b/src/main/java/org/apache/sling/testing/mock/jcr/MockSession.java
@@ -21,7 +21,6 @@ package org.apache.sling.testing.mock.jcr;
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.util.ArrayList;
-import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.regex.Pattern;
@@ -41,6 +40,7 @@ import javax.jcr.Workspace;
 import javax.jcr.retention.RetentionManager;
 import javax.jcr.security.AccessControlManager;
 
+import org.apache.commons.lang3.StringUtils;
 import org.apache.jackrabbit.commons.iterator.RangeIteratorAdapter;
 import org.apache.jackrabbit.value.ValueFactoryImpl;
 import org.xml.sax.ContentHandler;
@@ -53,14 +53,12 @@ class MockSession implements Session {
 
     private final Repository repository;
     private final Workspace workspace;
+    private final Map<String, ItemData> items;
 
-    // Use linked hashmap to ensure ordering when adding items is preserved.
-    private final Map<String, Item> items = new LinkedHashMap<String, Item>();
-
-    public MockSession(final Repository repository) {
+    public MockSession(Repository repository, Map<String,ItemData> items) {
         this.repository = repository;
         this.workspace = new MockWorkspace(this);
-        this.items.put("/", new MockNode("/", this, MockNodeTypes.NT_UNSTRUCTURED));
+        this.items = items;
     }
 
     @Override
@@ -70,9 +68,14 @@ class MockSession implements Session {
 
     @Override
     public Item getItem(final String absPath) throws RepositoryException {
-        Item item = this.items.get(absPath);
-        if (item != null) {
-            return item;
+        ItemData itemData = this.items.get(absPath);
+        if (itemData != null) {
+            if (itemData.isNode()) {
+                return new MockNode(itemData, this);
+            }
+            else {
+                return new MockProperty(itemData, this);
+            }
         } else {
             throw new PathNotFoundException(String.format("No item found at: %s.", absPath));
         }
@@ -90,12 +93,9 @@ class MockSession implements Session {
 
     @Override
     public Node getNodeByIdentifier(final String id) throws RepositoryException {
-        for (Item item : this.items.values()) {
-            if (item instanceof Node) {
-                Node node = (Node) item;
-                if (node.getIdentifier().equals(id)) {
-                    return node;
-                }
+        for (ItemData item : this.items.values()) {
+            if (item.isNode() && StringUtils.equals(item.getUuid(), id)) {
+                return new MockNode(item, this);
             }
         }
         throw new ItemNotFoundException(String.format("No node found with id: %s.", id));
@@ -138,7 +138,7 @@ class MockSession implements Session {
 
     @Override
     public Node getRootNode() {
-        return (Node) this.items.get("/");
+        return (Node)this.items.get("/").getItem(this);
     }
 
     @Override
@@ -151,8 +151,8 @@ class MockSession implements Session {
      * @param item item
      * @throws RepositoryException
      */
-    void addItem(final Item item) throws RepositoryException {
-        this.items.put(item.getPath(), item);
+    void addItem(final ItemData itemData) throws RepositoryException {
+        this.items.put(itemData.getPath(), itemData);
     }
 
     /**
@@ -182,9 +182,9 @@ class MockSession implements Session {
         Pattern pattern = Pattern.compile("^" + Pattern.quote(parentPath) + "/[^/]+$");
 
         // collect child resources
-        for (Item item : this.items.values()) {
+        for (ItemData item : this.items.values()) {
             if (pattern.matcher(item.getPath()).matches() && (filter == null || filter.accept(item))) {
-                children.add(item);
+                children.add(item.getItem(this));
             }
         }
 
diff --git a/src/test/java/org/apache/sling/testing/mock/jcr/MockNodeTest.java b/src/test/java/org/apache/sling/testing/mock/jcr/MockNodeTest.java
index f02df0e..ef1bed3 100644
--- a/src/test/java/org/apache/sling/testing/mock/jcr/MockNodeTest.java
+++ b/src/test/java/org/apache/sling/testing/mock/jcr/MockNodeTest.java
@@ -20,7 +20,6 @@ package org.apache.sling.testing.mock.jcr;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertSame;
 import static org.junit.Assert.assertTrue;
 
 import javax.jcr.ItemNotFoundException;
@@ -56,14 +55,14 @@ public class MockNodeTest {
     public void testGetNodes() throws RepositoryException {
         NodeIterator nodes = this.node1.getNodes();
         assertEquals(1, nodes.getSize());
-        assertSame(this.node11, nodes.next());
+        assertEquals(this.node11, nodes.nextNode());
 
         assertTrue(this.node1.hasNodes());
         assertFalse(this.node11.hasNodes());
 
         nodes = this.node1.getNodes("^node.*$");
         assertEquals(1, nodes.getSize());
-        assertSame(this.node11, nodes.next());
+        assertEquals(this.node11, nodes.nextNode());
 
         nodes = this.node1.getNodes("unknown?");
         assertEquals(0, nodes.getSize());
@@ -73,14 +72,14 @@ public class MockNodeTest {
     public void testGetProperties() throws RepositoryException {
         PropertyIterator properties = this.node1.getProperties();
         assertEquals(1, properties.getSize());
-        assertSame(this.prop1, properties.next());
+        assertEquals(this.prop1, properties.next());
 
         assertTrue(this.node1.hasProperties());
         assertFalse(this.node11.hasProperties());
 
         properties = this.node1.getProperties("^prop.*$");
         assertEquals(1, properties.getSize());
-        assertSame(this.prop1, properties.next());
+        assertEquals(this.prop1, properties.next());
 
         properties = this.node1.getProperties("unknown?");
         assertEquals(0, properties.getSize());
@@ -114,11 +113,11 @@ public class MockNodeTest {
     public void testGetPrimaryItem() throws RepositoryException {
         Node dataParent = this.node1.addNode("dataParent");
         Property dataProperty = dataParent.setProperty(JcrConstants.JCR_DATA, "data");
-        assertSame(dataProperty, dataParent.getPrimaryItem());
+        assertEquals(dataProperty, dataParent.getPrimaryItem());
 
         Node contentParent = this.node1.addNode("contentParent");
         Node contentNode = contentParent.addNode(JcrConstants.JCR_CONTENT);
-        assertSame(contentNode, contentParent.getPrimaryItem());
+        assertEquals(contentNode, contentParent.getPrimaryItem());
     }
 
     @Test(expected = ItemNotFoundException.class)
diff --git a/src/test/java/org/apache/sling/testing/mock/jcr/MockRepositoryTest.java b/src/test/java/org/apache/sling/testing/mock/jcr/MockRepositoryTest.java
index 6143456..b5f2add 100644
--- a/src/test/java/org/apache/sling/testing/mock/jcr/MockRepositoryTest.java
+++ b/src/test/java/org/apache/sling/testing/mock/jcr/MockRepositoryTest.java
@@ -22,9 +22,13 @@ import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
+import static org.junit.Assert.fail;
 
+import javax.jcr.Node;
+import javax.jcr.PathNotFoundException;
 import javax.jcr.Repository;
 import javax.jcr.RepositoryException;
+import javax.jcr.Session;
 import javax.jcr.SimpleCredentials;
 
 import org.junit.Before;
@@ -39,25 +43,52 @@ public class MockRepositoryTest {
 
     @Before
     public void setUp() {
-        this.repository = MockJcr.newRepository();
+        repository = MockJcr.newRepository();
     }
 
     @Test
     public void testLogin() throws RepositoryException {
-        assertNotNull(this.repository.login());
-        assertNotNull(this.repository.login(new SimpleCredentials(USER_NAME, PASSWORD)));
-        assertNotNull(this.repository.login(MockJcr.DEFAULT_WORKSPACE));
-        assertNotNull(this.repository.login(new SimpleCredentials(USER_NAME, PASSWORD), MockJcr.DEFAULT_WORKSPACE));
+        assertNotNull(repository.login());
+        assertNotNull(repository.login(new SimpleCredentials(USER_NAME, PASSWORD)));
+        assertNotNull(repository.login(MockJcr.DEFAULT_WORKSPACE));
+        assertNotNull(repository.login(new SimpleCredentials(USER_NAME, PASSWORD), MockJcr.DEFAULT_WORKSPACE));
     }
 
     @Test
     public void testDescriptor() {
-        assertEquals(0, this.repository.getDescriptorKeys().length);
-        assertNull(this.repository.getDescriptor("test"));
-        assertNull(this.repository.getDescriptorValue("test"));
-        assertNull(this.repository.getDescriptorValues("test"));
-        assertFalse(this.repository.isStandardDescriptor("test"));
-        assertFalse(this.repository.isSingleValueDescriptor("test"));
+        assertEquals(0, repository.getDescriptorKeys().length);
+        assertNull(repository.getDescriptor("test"));
+        assertNull(repository.getDescriptorValue("test"));
+        assertNull(repository.getDescriptorValues("test"));
+        assertFalse(repository.isStandardDescriptor("test"));
+        assertFalse(repository.isSingleValueDescriptor("test"));
+    }
+    
+    @Test
+    public void testMultipleSessions() throws RepositoryException {
+        Session session1 = repository.login();
+        Session session2 = repository.login();
+
+        // add a node in session 1
+        Node root = session1.getRootNode();
+        root.addNode("test");
+        session1.save();
+        
+        // try to get node in session 2
+        Node testNode2 = session2.getNode("/test");
+        assertNotNull(testNode2);
+        
+        // delete node and make sure it is removed in session 1 as well
+        testNode2.remove();
+        session2.save();
+        
+        try {
+            session1.getNode("/test");
+            fail("Node was not removed");
+        }
+        catch (PathNotFoundException ex) {
+            // expected
+        }
     }
 
 }
diff --git a/src/test/java/org/apache/sling/testing/mock/jcr/MockSessionTest.java b/src/test/java/org/apache/sling/testing/mock/jcr/MockSessionTest.java
index 4c297c1..5f9d895 100644
--- a/src/test/java/org/apache/sling/testing/mock/jcr/MockSessionTest.java
+++ b/src/test/java/org/apache/sling/testing/mock/jcr/MockSessionTest.java
@@ -22,7 +22,6 @@ import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertSame;
 import static org.junit.Assert.assertTrue;
 
 import javax.jcr.ItemNotFoundException;
@@ -60,7 +59,7 @@ public class MockSessionTest {
     @Test
     public void testNodePropertyCreateRead() throws RepositoryException {
         Node rootNode = this.session.getNode("/");
-        assertSame(rootNode, this.session.getRootNode());
+        assertEquals(rootNode, this.session.getRootNode());
 
         Node node1 = rootNode.addNode("node1");
         node1.setProperty("prop1a", "value1a");
@@ -69,16 +68,16 @@ public class MockSessionTest {
         Node node2 = rootNode.addNode("node2");
         node2.setProperty("prop2", "value2");
 
-        assertSame(node1, rootNode.getNode("node1"));
-        assertSame(node1, this.session.getNode("/node1"));
-        assertSame(node1, this.session.getItem("/node1"));
-        assertSame(node1, this.session.getNodeByIdentifier(node1.getIdentifier()));
+        assertEquals(node1, rootNode.getNode("node1"));
+        assertEquals(node1, this.session.getNode("/node1"));
+        assertEquals(node1, this.session.getItem("/node1"));
+        assertEquals(node1, this.session.getNodeByIdentifier(node1.getIdentifier()));
         assertTrue(this.session.nodeExists("/node1"));
         assertTrue(this.session.itemExists("/node1"));
-        assertSame(node2, rootNode.getNode("node2"));
-        assertSame(node2, this.session.getNode("/node2"));
-        assertSame(node2, this.session.getItem("/node2"));
-        assertSame(node2, this.session.getNodeByIdentifier(node2.getIdentifier()));
+        assertEquals(node2, rootNode.getNode("node2"));
+        assertEquals(node2, this.session.getNode("/node2"));
+        assertEquals(node2, this.session.getItem("/node2"));
+        assertEquals(node2, this.session.getNodeByIdentifier(node2.getIdentifier()));
         assertTrue(this.session.nodeExists("/node2"));
         assertTrue(this.session.itemExists("/node2"));
 
@@ -86,16 +85,16 @@ public class MockSessionTest {
         Property prop1b = node1.getProperty("prop1b");
         Property prop2 = node2.getProperty("prop2");
 
-        assertSame(prop1a, this.session.getProperty("/node1/prop1a"));
-        assertSame(prop1a, this.session.getItem("/node1/prop1a"));
+        assertEquals(prop1a, this.session.getProperty("/node1/prop1a"));
+        assertEquals(prop1a, this.session.getItem("/node1/prop1a"));
         assertTrue(this.session.propertyExists("/node1/prop1a"));
         assertTrue(this.session.itemExists("/node1/prop1a"));
-        assertSame(prop1b, this.session.getProperty("/node1/prop1b"));
-        assertSame(prop1b, this.session.getItem("/node1/prop1b"));
+        assertEquals(prop1b, this.session.getProperty("/node1/prop1b"));
+        assertEquals(prop1b, this.session.getItem("/node1/prop1b"));
         assertTrue(this.session.propertyExists("/node1/prop1b"));
         assertTrue(this.session.itemExists("/node1/prop1b"));
-        assertSame(prop2, this.session.getProperty("/node2/prop2"));
-        assertSame(prop2, this.session.getItem("/node2/prop2"));
+        assertEquals(prop2, this.session.getProperty("/node2/prop2"));
+        assertEquals(prop2, this.session.getItem("/node2/prop2"));
         assertTrue(this.session.propertyExists("/node2/prop2"));
         assertTrue(this.session.itemExists("/node2/prop2"));
 

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.