You are viewing a plain text version of this content. The canonical link for it is here.
Posted to oak-commits@jackrabbit.apache.org by md...@apache.org on 2013/03/13 17:23:29 UTC

svn commit: r1456022 [1/2] - in /jackrabbit/oak/trunk: oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/nodetype/ oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/value/ oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/ oak-jcr/src/m...

Author: mduerig
Date: Wed Mar 13 16:23:28 2013
New Revision: 1456022

URL: http://svn.apache.org/r1456022
Log:
OAK-672: Avoid JCR APIs calling other JCR APIs
- Introduce SessionContext providing access to session scoped instances
- Introduce SessionContextProvider as temporary solution for mapping SessionDelegate instances to SessionContext instances

Added:
    jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/SessionContextProvider.java   (with props)
Modified:
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/nodetype/EffectiveNodeTypeImpl.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/value/ValueFactoryImpl.java
    jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/ItemImpl.java
    jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/NodeImpl.java
    jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/PropertyImpl.java
    jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/RepositoryImpl.java
    jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/SessionImpl.java
    jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/WorkspaceImpl.java
    jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/PropertyDelegate.java
    jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/SessionDelegate.java
    jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/VersionHistoryDelegate.java
    jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/lock/LockManagerImpl.java
    jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/query/QueryImpl.java
    jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/query/QueryManagerImpl.java
    jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/query/QueryResultImpl.java
    jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/query/qom/QueryObjectModelFactoryImpl.java
    jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/version/VersionHistoryImpl.java
    jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/version/VersionImpl.java
    jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/version/VersionManagerImpl.java
    jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/xml/SessionImporter.java

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/nodetype/EffectiveNodeTypeImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/nodetype/EffectiveNodeTypeImpl.java?rev=1456022&r1=1456021&r2=1456022&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/nodetype/EffectiveNodeTypeImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/nodetype/EffectiveNodeTypeImpl.java Wed Mar 13 16:23:28 2013
@@ -21,6 +21,7 @@ import java.util.Collection;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
+
 import javax.annotation.Nullable;
 import javax.jcr.RepositoryException;
 import javax.jcr.UnsupportedRepositoryOperationException;
@@ -326,7 +327,7 @@ class EffectiveNodeTypeImpl implements E
         return ntMgr.getDefinition(nodeTypes, nameToCheck, nodeType);
     }
 
-    private class DefinitionNamePredicate implements Predicate<ItemDefinition> {
+    private static class DefinitionNamePredicate implements Predicate<ItemDefinition> {
 
         private final String oakName;
 

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/value/ValueFactoryImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/value/ValueFactoryImpl.java?rev=1456022&r1=1456021&r2=1456022&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/value/ValueFactoryImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/value/ValueFactoryImpl.java Wed Mar 13 16:23:28 2013
@@ -81,14 +81,26 @@ public class ValueFactoryImpl implements
     }
 
     /**
+     * Utility method for creating a {@code Value} based on a {@code PropertyState}.
+     * @param property  The property state
+     * @return  New {@code Value} instance
+     * @throws IllegalArgumentException if {@code property.isArray()} is {@code true}.
+     */
+    public Value createValue(PropertyState property) {
+        return new ValueImpl(property, namePathMapper);
+    }
+
+    public static Value createValue(PropertyValue property, NamePathMapper namePathMapper) {
+        return new ValueImpl(PropertyValues.create(property), namePathMapper);
+    }
+
+    /**
      * Utility method for creating a {@code Value} based on a {@code PropertyValue}.
      * @param property  The property value
-     * @param namePathMapper The name/path mapping used for converting JCR names/paths to
-     * the internal representation.
      * @return  New {@code Value} instance
      * @throws IllegalArgumentException if {@code property.isArray()} is {@code true}.
      */
-    public static Value createValue(PropertyValue property, NamePathMapper namePathMapper) {
+    public Value createValue(PropertyValue property) {
         return new ValueImpl(PropertyValues.create(property), namePathMapper);
     }
 
@@ -107,6 +119,19 @@ public class ValueFactoryImpl implements
         return values;
     }
 
+    /**
+     * Utility method for creating {@code Value}s based on a {@code PropertyState}.
+     * @param property  The property state
+     * @return  A list of new {@code Value} instances
+     */
+    public List<Value> createValues(PropertyState property) {
+        List<Value> values = Lists.newArrayList();
+        for (int i = 0; i < property.count(); i++) {
+            values.add(new ValueImpl(property, i, namePathMapper));
+        }
+        return values;
+    }
+
     //-------------------------------------------------------< ValueFactory >---
 
     @Override

Modified: jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/ItemImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/ItemImpl.java?rev=1456022&r1=1456021&r2=1456022&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/ItemImpl.java (original)
+++ jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/ItemImpl.java Wed Mar 13 16:23:28 2013
@@ -23,14 +23,17 @@ import javax.jcr.Node;
 import javax.jcr.Property;
 import javax.jcr.RepositoryException;
 import javax.jcr.Session;
-import javax.jcr.ValueFactory;
 import javax.jcr.nodetype.ConstraintViolationException;
 import javax.jcr.nodetype.ItemDefinition;
+import javax.jcr.nodetype.NodeTypeManager;
 
 import org.apache.jackrabbit.commons.AbstractItem;
 import org.apache.jackrabbit.oak.jcr.delegate.ItemDelegate;
 import org.apache.jackrabbit.oak.jcr.delegate.SessionDelegate;
 import org.apache.jackrabbit.oak.jcr.delegate.SessionOperation;
+import org.apache.jackrabbit.oak.namepath.NamePathMapper;
+import org.apache.jackrabbit.oak.plugins.nodetype.DefinitionProvider;
+import org.apache.jackrabbit.oak.plugins.value.ValueFactoryImpl;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -104,7 +107,7 @@ abstract class ItemImpl<T extends ItemDe
     @Override
     @Nonnull
     public Session getSession() throws RepositoryException {
-        return sessionDelegate.getSession();
+        return SessionContextProvider.getSession(sessionDelegate);
     }
 
     /**
@@ -231,12 +234,23 @@ abstract class ItemImpl<T extends ItemDe
      * @return the value factory
      */
     @Nonnull
-    ValueFactory getValueFactory() {
-        return sessionDelegate.getValueFactory();
+    ValueFactoryImpl getValueFactory() {
+        return SessionContextProvider.getValueFactory(sessionDelegate);
+    }
+
+    @Nonnull
+    NodeTypeManager getNodeTypeManager() {
+        return SessionContextProvider.getNodeTypeManager(sessionDelegate);
+    }
+
+    @Nonnull
+    DefinitionProvider getDefinitionProvider() {
+        return SessionContextProvider.getDefinitionProvider(sessionDelegate);
     }
 
     @Nonnull
     String toJcrPath(String oakPath) {
-        return sessionDelegate.getNamePathMapper().getJcrPath(oakPath);
+        NamePathMapper namePathMapper = SessionContextProvider.getNamePathMapper(sessionDelegate);
+        return namePathMapper.getJcrPath(oakPath);
     }
 }

Modified: jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/NodeImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/NodeImpl.java?rev=1456022&r1=1456021&r2=1456022&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/NodeImpl.java (original)
+++ jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/NodeImpl.java Wed Mar 13 16:23:28 2013
@@ -45,6 +45,7 @@ import javax.jcr.RepositoryException;
 import javax.jcr.UnsupportedRepositoryOperationException;
 import javax.jcr.Value;
 import javax.jcr.ValueFormatException;
+import javax.jcr.Workspace;
 import javax.jcr.lock.Lock;
 import javax.jcr.nodetype.ConstraintViolationException;
 import javax.jcr.nodetype.NoSuchNodeTypeException;
@@ -55,6 +56,7 @@ import javax.jcr.nodetype.PropertyDefini
 import javax.jcr.version.Version;
 import javax.jcr.version.VersionException;
 import javax.jcr.version.VersionHistory;
+import javax.jcr.version.VersionManager;
 
 import com.google.common.base.Function;
 import com.google.common.base.Predicate;
@@ -69,9 +71,11 @@ import org.apache.jackrabbit.commons.ite
 import org.apache.jackrabbit.commons.iterator.PropertyIteratorAdapter;
 import org.apache.jackrabbit.oak.api.CommitFailedException;
 import org.apache.jackrabbit.oak.api.ContentSession;
+import org.apache.jackrabbit.oak.api.PropertyState;
 import org.apache.jackrabbit.oak.api.Root;
 import org.apache.jackrabbit.oak.api.Tree;
 import org.apache.jackrabbit.oak.api.Tree.Status;
+import org.apache.jackrabbit.oak.api.Type;
 import org.apache.jackrabbit.oak.commons.PathUtils;
 import org.apache.jackrabbit.oak.core.IdentifierManager;
 import org.apache.jackrabbit.oak.jcr.delegate.NodeDelegate;
@@ -79,6 +83,7 @@ import org.apache.jackrabbit.oak.jcr.del
 import org.apache.jackrabbit.oak.jcr.delegate.SessionOperation;
 import org.apache.jackrabbit.oak.plugins.nodetype.DefinitionProvider;
 import org.apache.jackrabbit.oak.plugins.nodetype.EffectiveNodeType;
+import org.apache.jackrabbit.oak.plugins.nodetype.EffectiveNodeTypeProvider;
 import org.apache.jackrabbit.oak.plugins.nodetype.NodeTypeConstants;
 import org.apache.jackrabbit.oak.util.TODO;
 import org.apache.jackrabbit.value.ValueHelper;
@@ -220,6 +225,10 @@ public class NodeImpl<T extends NodeDele
         return addNode(relPath, null);
     }
 
+    private String getOakPath(String jcrPath) throws RepositoryException {
+        return SessionContextProvider.getOakPath(sessionDelegate, jcrPath);
+    }
+
     @Override
     @Nonnull
     public Node addNode(final String relPath, final String primaryNodeTypeName) throws RepositoryException {
@@ -229,9 +238,9 @@ public class NodeImpl<T extends NodeDele
         return perform(new SessionOperation<Node>() {
             @Override
             public Node perform() throws RepositoryException {
-                String oakPath = sessionDelegate.getOakPathKeepIndexOrThrowNotFound(relPath);
+                String oakPath = SessionContextProvider.getOakPathKeepIndexOrThrowNotFound(sessionDelegate, relPath);
                 String oakName = PathUtils.getName(oakPath);
-                String parentPath = sessionDelegate.getOakPath(PathUtils.getParentPath(oakPath));
+                String parentPath = getOakPath(PathUtils.getParentPath(oakPath));
 
                 // handle index
                 if (oakName.contains("[")) {
@@ -259,8 +268,8 @@ public class NodeImpl<T extends NodeDele
 
                 String ntName = primaryNodeTypeName;
                 if (ntName == null) {
-                    DefinitionProvider dp = sessionDelegate.getDefinitionProvider();
-                    String childName = sessionDelegate.getOakName(PathUtils.getName(relPath));
+                    DefinitionProvider dp = getDefinitionProvider();
+                    String childName = getOakName(PathUtils.getName(relPath));
                     NodeDefinition def = dp.getDefinition(new NodeImpl<NodeDelegate>(parent), childName);
                     ntName = def.getDefaultPrimaryTypeName();
                     if (ntName == null) {
@@ -270,8 +279,7 @@ public class NodeImpl<T extends NodeDele
                 }
 
                 // TODO: figure out the right place for this check
-                NodeTypeManager ntm = sessionDelegate.getNodeTypeManager();
-                NodeType nt = ntm.getNodeType(ntName); // throws on not found
+                NodeType nt = getNodeTypeManager().getNodeType(ntName); // throws on not found
                 if (nt.isAbstract() || nt.isMixin()) {
                     throw new ConstraintViolationException();
                 }
@@ -294,6 +302,11 @@ public class NodeImpl<T extends NodeDele
         });
     }
 
+    @Nonnull
+    private String getOakName(String name) throws RepositoryException {
+        return SessionContextProvider.getOakName(sessionDelegate, name);
+    }
+
     @Override
     public void orderBefore(final String srcChildRelPath, final String destChildRelPath) throws RepositoryException {
         perform(new SessionOperation<Void>() {
@@ -307,11 +320,11 @@ public class NodeImpl<T extends NodeDele
             public Void perform() throws RepositoryException {
                 getEffectiveNodeType().checkOrderableChildNodes();
                 String oakSrcChildRelPath =
-                        sessionDelegate.getOakPathOrThrowNotFound(srcChildRelPath);
+                        getOakPathOrThrowNotFound(srcChildRelPath);
                 String oakDestChildRelPath = null;
                 if (destChildRelPath != null) {
                     oakDestChildRelPath =
-                            sessionDelegate.getOakPathOrThrowNotFound(destChildRelPath);
+                            getOakPathOrThrowNotFound(destChildRelPath);
                 }
                 dlg.orderBefore(oakSrcChildRelPath, oakDestChildRelPath);
                 return null;
@@ -319,6 +332,10 @@ public class NodeImpl<T extends NodeDele
         });
     }
 
+    private String getOakPathOrThrowNotFound(String relPath) throws PathNotFoundException {
+        return SessionContextProvider.getOakPathOrThrowNotFound(sessionDelegate, relPath);
+    }
+
     /**
      * @see Node#setProperty(String, javax.jcr.Value)
      */
@@ -496,7 +513,7 @@ public class NodeImpl<T extends NodeDele
 
             @Override
             public NodeImpl<?> perform() throws RepositoryException {
-                String oakPath = sessionDelegate.getOakPathOrThrowNotFound(relPath);
+                String oakPath = getOakPathOrThrowNotFound(relPath);
 
                 NodeDelegate nd = dlg.getChild(oakPath);
                 if (nd == null) {
@@ -595,7 +612,7 @@ public class NodeImpl<T extends NodeDele
 
             @Override
             public PropertyImpl perform() throws RepositoryException {
-                String oakPath = sessionDelegate.getOakPathOrThrowNotFound(relPath);
+                String oakPath = getOakPathOrThrowNotFound(relPath);
                 PropertyDelegate pd = dlg.getProperty(oakPath);
                 if (pd == null) {
                     throw new PathNotFoundException(relPath + " not found on " + getPath());
@@ -819,7 +836,7 @@ public class NodeImpl<T extends NodeDele
 
             @Override
             public Boolean perform() throws RepositoryException {
-                String oakPath = sessionDelegate.getOakPath(relPath);
+                String oakPath = getOakPath(relPath);
                 return dlg.getChild(oakPath) != null;
             }
         });
@@ -835,7 +852,7 @@ public class NodeImpl<T extends NodeDele
 
             @Override
             public Boolean perform() throws RepositoryException {
-                String oakPath = sessionDelegate.getOakPath(relPath);
+                String oakPath = getOakPath(relPath);
                 return dlg.getProperty(oakPath) != null;
             }
         });
@@ -885,14 +902,13 @@ public class NodeImpl<T extends NodeDele
 
             @Override
             public NodeType perform() throws RepositoryException {
-                NodeTypeManager ntMgr = sessionDelegate.getNodeTypeManager();
                 String primaryNtName;
                 if (hasProperty(Property.JCR_PRIMARY_TYPE)) {
                     primaryNtName = getProperty(Property.JCR_PRIMARY_TYPE).getString();
                 } else {
                     throw new RepositoryException("Node " + getPath() + " doesn't have primary type set.");
                 }
-                return ntMgr.getNodeType(primaryNtName);
+                return getNodeTypeManager().getNodeType(primaryNtName);
             }
         });
     }
@@ -913,7 +929,7 @@ public class NodeImpl<T extends NodeDele
             public NodeType[] perform() throws RepositoryException {
                 // TODO: check if transient changes to mixin-types are reflected here
                 if (hasProperty(Property.JCR_MIXIN_TYPES)) {
-                    NodeTypeManager ntMgr = sessionDelegate.getNodeTypeManager();
+                    NodeTypeManager ntMgr = getNodeTypeManager();
                     Value[] mixinNames = getProperty(Property.JCR_MIXIN_TYPES).getValues();
                     NodeType[] mixinTypes = new NodeType[mixinNames.length];
                     for (int i = 0; i < mixinNames.length; i++) {
@@ -927,12 +943,17 @@ public class NodeImpl<T extends NodeDele
         });
     }
 
+    @Nonnull
+    private EffectiveNodeTypeProvider getEffectiveNodeTypeProvider() {
+        return SessionContextProvider.getEffectiveNodeTypeProvider(sessionDelegate);
+    }
+
     @Override
     public boolean isNodeType(final String nodeTypeName) throws RepositoryException {
         checkStatus();
 
-        String oakName = sessionDelegate.getOakName(nodeTypeName);
-        return sessionDelegate.getEffectiveNodeTypeProvider().isNodeType(dlg.getTree(), oakName);
+        String oakName = getOakName(nodeTypeName);
+        return getEffectiveNodeTypeProvider().isNodeType(dlg.getTree(), oakName);
     }
 
     @Override
@@ -959,8 +980,7 @@ public class NodeImpl<T extends NodeDele
             @Override
             public Void perform() throws RepositoryException {
                 // TODO: figure out the right place for this check
-                NodeTypeManager ntm = sessionDelegate.getNodeTypeManager();
-                ntm.getNodeType(mixinName); // throws on not found
+                getNodeTypeManager().getNodeType(mixinName); // throws on not found
                 // TODO: END
 
                 if (isNodeType(mixinName)) {
@@ -968,14 +988,21 @@ public class NodeImpl<T extends NodeDele
                 }
 
                 PropertyDelegate mixins = dlg.getProperty(JcrConstants.JCR_MIXINTYPES);
-                Value value = sessionDelegate.getValueFactory().createValue(mixinName, PropertyType.NAME);
+                Value value = getValueFactory().createValue(mixinName, PropertyType.NAME);
 
                 boolean nodeModified = false;
                 if (mixins == null) {
                     nodeModified = true;
                     dlg.setProperty(JcrConstants.JCR_MIXINTYPES, Collections.singletonList(value));
                 } else {
-                    List<Value> values = mixins.getValues();
+                    PropertyState property = mixins.getPropertyState();
+                    if (property == null) {
+                        throw new InvalidItemStateException();
+                    }
+                    if (!property.isArray()) {
+                        throw new ValueFormatException(mixins + " is single-valued.");
+                    }
+                    List<Value> values = getValueFactory().createValues(property);
                     if (!values.contains(value)) {
                         values.add(value);
                         nodeModified = true;
@@ -1022,8 +1049,7 @@ public class NodeImpl<T extends NodeDele
             @Override
             public Boolean perform() throws RepositoryException {
                 // TODO: figure out the right place for this check
-                NodeTypeManager ntm = sessionDelegate.getNodeTypeManager();
-                ntm.getNodeType(mixinName); // throws on not found
+                getNodeTypeManager().getNodeType(mixinName); // throws on not found
                 // TODO: END
 
                 return getEffectiveNodeType().supportsMixin(mixinName);
@@ -1032,16 +1058,16 @@ public class NodeImpl<T extends NodeDele
     }
 
     private EffectiveNodeType getEffectiveNodeType() throws RepositoryException {
-        return sessionDelegate.getEffectiveNodeTypeProvider().getEffectiveNodeType(this);
+        return getEffectiveNodeTypeProvider().getEffectiveNodeType(this);
     }
 
     @Override
     @Nonnull
     public NodeDefinition getDefinition() throws RepositoryException {
         if (getDepth() == 0) {
-            return dlg.getSessionDelegate().getDefinitionProvider().getRootDefinition();
+            return getDefinitionProvider().getRootDefinition();
         } else {
-            return dlg.getSessionDelegate().getDefinitionProvider().getDefinition(getParent(), this);
+            return getDefinitionProvider().getDefinition(getParent(), this);
         }
     }
 
@@ -1063,13 +1089,18 @@ public class NodeImpl<T extends NodeDele
         // TODO
     }
 
+    @Nonnull
+    private VersionManager getVersionManager() throws RepositoryException {
+        return SessionContextProvider.getVersionManager(sessionDelegate);
+    }
+
     /**
      * @see javax.jcr.Node#checkin()
      */
     @Override
     @Nonnull
     public Version checkin() throws RepositoryException {
-        return sessionDelegate.getVersionManager().checkin(getPath());
+        return getVersionManager().checkin(getPath());
     }
 
     /**
@@ -1077,7 +1108,7 @@ public class NodeImpl<T extends NodeDele
      */
     @Override
     public void checkout() throws RepositoryException {
-        sessionDelegate.getVersionManager().checkout(getPath());
+        getVersionManager().checkout(getPath());
     }
 
     /**
@@ -1085,7 +1116,7 @@ public class NodeImpl<T extends NodeDele
      */
     @Override
     public void doneMerge(Version version) throws RepositoryException {
-        sessionDelegate.getVersionManager().doneMerge(getPath(), version);
+        getVersionManager().doneMerge(getPath(), version);
     }
 
     /**
@@ -1093,7 +1124,7 @@ public class NodeImpl<T extends NodeDele
      */
     @Override
     public void cancelMerge(Version version) throws RepositoryException {
-        sessionDelegate.getVersionManager().cancelMerge(getPath(), version);
+        getVersionManager().cancelMerge(getPath(), version);
     }
 
     /**
@@ -1102,7 +1133,7 @@ public class NodeImpl<T extends NodeDele
     @Override
     @Nonnull
     public NodeIterator merge(String srcWorkspace, boolean bestEffort) throws RepositoryException {
-        return sessionDelegate.getVersionManager().merge(getPath(), srcWorkspace, bestEffort);
+        return getVersionManager().merge(getPath(), srcWorkspace, bestEffort);
     }
 
     /**
@@ -1111,7 +1142,7 @@ public class NodeImpl<T extends NodeDele
     @Override
     public boolean isCheckedOut() throws RepositoryException {
         try {
-            return sessionDelegate.getVersionManager().isCheckedOut(getPath());
+            return getVersionManager().isCheckedOut(getPath());
         } catch (UnsupportedRepositoryOperationException ex) {
             // when versioning is not supported all nodes are considered to be
             // checked out
@@ -1124,7 +1155,7 @@ public class NodeImpl<T extends NodeDele
      */
     @Override
     public void restore(String versionName, boolean removeExisting) throws RepositoryException {
-        sessionDelegate.getVersionManager().restore(getPath(), versionName, removeExisting);
+        getVersionManager().restore(getPath(), versionName, removeExisting);
     }
 
     /**
@@ -1132,7 +1163,7 @@ public class NodeImpl<T extends NodeDele
      */
     @Override
     public void restore(Version version, boolean removeExisting) throws RepositoryException {
-        sessionDelegate.getVersionManager().restore(version, removeExisting);
+        getVersionManager().restore(version, removeExisting);
     }
 
     /**
@@ -1154,7 +1185,7 @@ public class NodeImpl<T extends NodeDele
      */
     @Override
     public void restoreByLabel(String versionLabel, boolean removeExisting) throws RepositoryException {
-        sessionDelegate.getVersionManager().restoreByLabel(getPath(), versionLabel, removeExisting);
+        getVersionManager().restoreByLabel(getPath(), versionLabel, removeExisting);
     }
 
     /**
@@ -1163,7 +1194,7 @@ public class NodeImpl<T extends NodeDele
     @Override
     @Nonnull
     public VersionHistory getVersionHistory() throws RepositoryException {
-        return sessionDelegate.getVersionManager().getVersionHistory(getPath());
+        return getVersionManager().getVersionHistory(getPath());
     }
 
     /**
@@ -1172,7 +1203,7 @@ public class NodeImpl<T extends NodeDele
     @Override
     @Nonnull
     public Version getBaseVersion() throws RepositoryException {
-        return sessionDelegate.getVersionManager().getBaseVersion(getPath());
+        return getVersionManager().getBaseVersion(getPath());
     }
 
     /**
@@ -1183,8 +1214,8 @@ public class NodeImpl<T extends NodeDele
      */
     @Override
     public boolean isLocked() throws RepositoryException {
-        String lockOwner = sessionDelegate.getOakPath(JCR_LOCK_OWNER);
-        String lockIsDeep = sessionDelegate.getOakPath(JCR_LOCK_IS_DEEP);
+        String lockOwner = getOakPath(JCR_LOCK_OWNER);
+        String lockIsDeep = getOakPath(JCR_LOCK_IS_DEEP);
 
         if (dlg.getProperty(lockOwner) != null) {
             return true;
@@ -1194,9 +1225,11 @@ public class NodeImpl<T extends NodeDele
         while (parent != null) {
             if (parent.getProperty(lockOwner) != null) {
                 PropertyDelegate isDeep = parent.getProperty(lockIsDeep);
-                if (isDeep != null && !isDeep.isMultivalue()
-                        && isDeep.getValue().getBoolean()) {
-                    return true;
+                if (isDeep != null) {
+                    PropertyState p = isDeep.getPropertyState();
+                    if (p != null && !p.isArray() && p.getValue(Type.BOOLEAN)) {
+                        return true;
+                    }
                 }
             }
             parent = parent.getParent();
@@ -1211,7 +1244,7 @@ public class NodeImpl<T extends NodeDele
      */
     @Override
     public boolean holdsLock() throws RepositoryException {
-        String lockOwner = sessionDelegate.getOakPath(JCR_LOCK_OWNER);
+        String lockOwner = getOakPath(JCR_LOCK_OWNER);
         return dlg.getProperty(lockOwner) != null;
     }
 
@@ -1233,8 +1266,8 @@ public class NodeImpl<T extends NodeDele
             throws RepositoryException {
         final String userID = getSession().getUserID();
 
-        String lockOwner = sessionDelegate.getOakPath(JCR_LOCK_OWNER);
-        String lockIsDeep = sessionDelegate.getOakPath(JCR_LOCK_IS_DEEP);
+        String lockOwner = getOakPath(JCR_LOCK_OWNER);
+        String lockIsDeep = getOakPath(JCR_LOCK_IS_DEEP);
         try {
             ContentSession session = sessionDelegate.getContentSession();
             Root root = session.getLatestRoot();
@@ -1307,8 +1340,8 @@ public class NodeImpl<T extends NodeDele
      */
     @Override
     public void unlock() throws RepositoryException {
-        String lockOwner = sessionDelegate.getOakPath(JCR_LOCK_OWNER);
-        String lockIsDeep = sessionDelegate.getOakPath(JCR_LOCK_IS_DEEP);
+        String lockOwner = getOakPath(JCR_LOCK_OWNER);
+        String lockIsDeep = getOakPath(JCR_LOCK_IS_DEEP);
         try {
             Root root = sessionDelegate.getContentSession().getLatestRoot();
             Tree tree = root.getTree(dlg.getPath());
@@ -1412,7 +1445,7 @@ public class NodeImpl<T extends NodeDele
     }
 
     private void autoCreateItems() throws RepositoryException {
-        EffectiveNodeType effective = dlg.getSessionDelegate().getEffectiveNodeTypeProvider().getEffectiveNodeType(this);
+        EffectiveNodeType effective = getEffectiveNodeTypeProvider().getEffectiveNodeType(this);
         for (PropertyDefinition pd : effective.getAutoCreatePropertyDefinitions()) {
             if (dlg.getProperty(pd.getName()) == null) {
                 if (pd.isMultiple()) {
@@ -1494,7 +1527,8 @@ public class NodeImpl<T extends NodeDele
     }
 
     private void checkValidWorkspace(String workspaceName) throws RepositoryException {
-        for (String wn : sessionDelegate.getWorkspace().getAccessibleWorkspaceNames()) {
+        Workspace workspace = SessionContextProvider.getWorkspace(sessionDelegate);
+        for (String wn : workspace.getAccessibleWorkspaceNames()) {
             if (wn.equals(workspaceName)) {
                 return;
             }
@@ -1507,15 +1541,14 @@ public class NodeImpl<T extends NodeDele
             @Override
             public Void perform() throws RepositoryException {
                 // TODO: figure out the right place for this check
-                NodeTypeManager ntm = sessionDelegate.getNodeTypeManager();
-                NodeType nt = ntm.getNodeType(nodeTypeName); // throws on not found
+                NodeType nt = getNodeTypeManager().getNodeType(nodeTypeName); // throws on not found
                 if (nt.isAbstract() || nt.isMixin()) {
                     throw new ConstraintViolationException();
                 }
                 // TODO: END
 
-                String jcrPrimaryType = sessionDelegate.getOakPath(Property.JCR_PRIMARY_TYPE);
-                Value value = sessionDelegate.getValueFactory().createValue(nodeTypeName, PropertyType.NAME);
+                String jcrPrimaryType = getOakPath(Property.JCR_PRIMARY_TYPE);
+                Value value = getValueFactory().createValue(nodeTypeName, PropertyType.NAME);
                 dlg.setProperty(jcrPrimaryType, value);
 
                 dlg.setOrderableChildren(nt.hasOrderableChildNodes());
@@ -1536,7 +1569,7 @@ public class NodeImpl<T extends NodeDele
 
             @Override
             public Property perform() throws RepositoryException {
-                String oakName = sessionDelegate.getOakPath(jcrName);
+                String oakName = getOakPath(jcrName);
                 if (value == null) {
                     if (hasProperty(jcrName)) {
                         Property property = getProperty(jcrName);
@@ -1556,7 +1589,7 @@ public class NodeImpl<T extends NodeDele
                         if (hasProperty(jcrName)) {
                             definition = getProperty(jcrName).getDefinition();
                         } else {
-                            definition = dlg.getSessionDelegate().getDefinitionProvider().getDefinition(NodeImpl.this, oakName, false, type, exactTypeMatch);
+                            definition = getDefinitionProvider().getDefinition(NodeImpl.this, oakName, false, type, exactTypeMatch);
                         }
                         checkProtected(definition);
                         if (definition.isMultiple()) {
@@ -1584,7 +1617,7 @@ public class NodeImpl<T extends NodeDele
 
             @Override
             public Property perform() throws RepositoryException {
-                String oakName = sessionDelegate.getOakPath(jcrName);
+                String oakName = getOakPath(jcrName);
                 if (values == null) {
                     if (hasProperty(jcrName)) {
                         Property property = getProperty(jcrName);
@@ -1603,7 +1636,7 @@ public class NodeImpl<T extends NodeDele
                         if (hasProperty(jcrName)) {
                             definition = getProperty(jcrName).getDefinition();
                         } else {
-                            definition = dlg.getSessionDelegate().getDefinitionProvider().getDefinition(NodeImpl.this, oakName, true, type, exactTypeMatch);
+                            definition = getDefinitionProvider().getDefinition(NodeImpl.this, oakName, true, type, exactTypeMatch);
                         }
                         checkProtected(definition);
                         if (!definition.isMultiple()) {

Modified: jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/PropertyImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/PropertyImpl.java?rev=1456022&r1=1456021&r2=1456022&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/PropertyImpl.java (original)
+++ jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/PropertyImpl.java Wed Mar 13 16:23:28 2013
@@ -26,6 +26,7 @@ import java.util.List;
 import javax.annotation.Nonnull;
 import javax.jcr.AccessDeniedException;
 import javax.jcr.Binary;
+import javax.jcr.InvalidItemStateException;
 import javax.jcr.ItemNotFoundException;
 import javax.jcr.ItemVisitor;
 import javax.jcr.Node;
@@ -39,6 +40,7 @@ import javax.jcr.nodetype.PropertyDefini
 
 import com.google.common.base.Predicates;
 import com.google.common.collect.Iterables;
+import org.apache.jackrabbit.oak.api.PropertyState;
 import org.apache.jackrabbit.oak.api.Tree.Status;
 import org.apache.jackrabbit.oak.jcr.delegate.NodeDelegate;
 import org.apache.jackrabbit.oak.jcr.delegate.PropertyDelegate;
@@ -248,7 +250,6 @@ public class PropertyImpl extends ItemIm
     /**
      * @see Property#setValue(InputStream)
      */
-    @SuppressWarnings("deprecation")
     @Override
     public void setValue(InputStream value) throws RepositoryException {
         checkStatus();
@@ -354,6 +355,14 @@ public class PropertyImpl extends ItemIm
         }
     }
 
+    private PropertyState getPropertyState() throws InvalidItemStateException {
+        PropertyState property = dlg.getPropertyState();
+        if (property == null) {
+            throw new InvalidItemStateException();
+        }
+        return property;
+    }
+
     @Override
     @Nonnull
     public Value getValue() throws RepositoryException {
@@ -365,7 +374,11 @@ public class PropertyImpl extends ItemIm
 
             @Override
             public Value perform() throws RepositoryException {
-                return dlg.getValue();
+                PropertyState property = getPropertyState();
+                if (property.isArray()) {
+                    throw new ValueFormatException(dlg + " is multi-valued.");
+                }
+                return getValueFactory().createValue(property);
             }
         });
     }
@@ -381,7 +394,14 @@ public class PropertyImpl extends ItemIm
 
             @Override
             public List<Value> perform() throws RepositoryException {
-                return dlg.getValues();
+                PropertyState property = dlg.getPropertyState();
+                if (property == null) {
+                    throw new InvalidItemStateException();
+                }
+                if (!property.isArray()) {
+                    throw new ValueFormatException(dlg + " is single-valued.");
+                }
+                return getValueFactory().createValues(property);
             }
         }).toArray(NO_VALUES);
     }
@@ -558,7 +578,7 @@ public class PropertyImpl extends ItemIm
     @Override
     @Nonnull
     public PropertyDefinition getDefinition() throws RepositoryException {
-        return dlg.getSessionDelegate().getDefinitionProvider().getDefinition(getParent(), this);
+        return getDefinitionProvider().getDefinition(getParent(), this);
     }
 
     /**
@@ -594,7 +614,7 @@ public class PropertyImpl extends ItemIm
 
             @Override
             public Boolean perform() throws RepositoryException {
-                return dlg.isMultivalue();
+                return getPropertyState().isArray();
             }
         });
     }
@@ -650,7 +670,7 @@ public class PropertyImpl extends ItemIm
         if (value == null) {
             dlg.remove();
         } else {
-            Value targetValue = ValueHelper.convert(value, requiredType, sessionDelegate.getValueFactory());
+            Value targetValue = ValueHelper.convert(value, requiredType, getValueFactory());
             dlg.setValue(targetValue);
         }
     }
@@ -671,7 +691,7 @@ public class PropertyImpl extends ItemIm
         if (values == null) {
             dlg.remove();
         } else {
-            Value[] targetValues = ValueHelper.convert(values, requiredType, sessionDelegate.getValueFactory());
+            Value[] targetValues = ValueHelper.convert(values, requiredType, getValueFactory());
             Iterable<Value> nonNullValues = Iterables.filter(
                     Arrays.asList(targetValues),
                     Predicates.notNull());

Modified: jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/RepositoryImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/RepositoryImpl.java?rev=1456022&r1=1456021&r2=1456022&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/RepositoryImpl.java (original)
+++ jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/RepositoryImpl.java Wed Mar 13 16:23:28 2013
@@ -17,6 +17,7 @@
 package org.apache.jackrabbit.oak.jcr;
 
 import java.util.concurrent.ScheduledExecutorService;
+
 import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
 import javax.jcr.Credentials;
@@ -34,6 +35,8 @@ import org.apache.jackrabbit.oak.spi.sec
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import static com.google.common.base.Preconditions.checkNotNull;
+
 /**
  * TODO document
  */
@@ -52,9 +55,9 @@ public class RepositoryImpl implements R
     public RepositoryImpl(@Nonnull ContentRepository contentRepository,
                           @Nonnull ScheduledExecutorService executor,
                           @Nonnull SecurityProvider securityProvider) {
-        this.contentRepository = contentRepository;
-        this.executor = executor;
-        this.securityProvider = securityProvider;
+        this.contentRepository = checkNotNull(contentRepository);
+        this.executor = checkNotNull(executor);
+        this.securityProvider = checkNotNull(securityProvider);
     }
 
     //---------------------------------------------------------< Repository >---
@@ -119,9 +122,24 @@ public class RepositoryImpl implements R
      */
     @Override
     public Session login(@Nullable Credentials credentials, @Nullable String workspaceName) throws RepositoryException {
+        final boolean autoRefresh = false; // TODO implement auto refresh configuration
         try {
             ContentSession contentSession = contentRepository.login(credentials, workspaceName);
-            return new SessionDelegate(this, executor, contentSession, securityProvider, false).getSession();
+            SessionDelegate sessionDelegate = new SessionDelegate(contentSession) {
+                @Override
+                protected void refresh() {
+                    if (needsRefresh()) {
+                        refresh(true);
+                    }
+                }
+
+                private boolean needsRefresh() {
+                    // Refresh is always needed if this is an auto refresh session or there
+                    // are pending observation events
+                    return autoRefresh || SessionContextProvider.hasPendingEvents(this);
+                }
+            };
+            return SessionContextProvider.newSession(sessionDelegate, this);
         } catch (LoginException e) {
             throw new javax.jcr.LoginException(e.getMessage(), e);
         }
@@ -165,4 +183,15 @@ public class RepositoryImpl implements R
         return login(null, workspace);
     }
 
+    //------------------------------------------------------------< internal >---
+
+    SecurityProvider getSecurityProvider() {
+        return securityProvider;
+    }
+
+    ScheduledExecutorService getObservationExecutor() {
+        return executor;
+    }
+
+
 }
\ No newline at end of file

Added: jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/SessionContextProvider.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/SessionContextProvider.java?rev=1456022&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/SessionContextProvider.java (added)
+++ jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/SessionContextProvider.java Wed Mar 13 16:23:28 2013
@@ -0,0 +1,398 @@
+package org.apache.jackrabbit.oak.jcr;
+
+import java.util.Map;
+
+import javax.annotation.CheckForNull;
+import javax.annotation.Nonnull;
+import javax.jcr.PathNotFoundException;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.lock.LockManager;
+import javax.jcr.nodetype.NodeTypeManager;
+import javax.jcr.observation.ObservationManager;
+import javax.jcr.security.AccessControlManager;
+import javax.jcr.version.VersionManager;
+
+import com.google.common.collect.Maps;
+import org.apache.jackrabbit.api.security.authorization.PrivilegeManager;
+import org.apache.jackrabbit.api.security.principal.PrincipalManager;
+import org.apache.jackrabbit.api.security.user.UserManager;
+import org.apache.jackrabbit.oak.api.Root;
+import org.apache.jackrabbit.oak.jcr.delegate.SessionDelegate;
+import org.apache.jackrabbit.oak.namepath.LocalNameMapper;
+import org.apache.jackrabbit.oak.namepath.NamePathMapperImpl;
+import org.apache.jackrabbit.oak.plugins.name.Namespaces;
+import org.apache.jackrabbit.oak.plugins.nodetype.DefinitionProvider;
+import org.apache.jackrabbit.oak.plugins.nodetype.EffectiveNodeTypeProvider;
+import org.apache.jackrabbit.oak.plugins.observation.ObservationManagerImpl;
+import org.apache.jackrabbit.oak.plugins.value.ValueFactoryImpl;
+import org.apache.jackrabbit.oak.spi.security.SecurityProvider;
+import org.apache.jackrabbit.oak.spi.security.authorization.AccessControlConfiguration;
+import org.apache.jackrabbit.oak.spi.security.authorization.PermissionProvider;
+import org.apache.jackrabbit.oak.spi.security.user.UserConfiguration;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+public final class SessionContextProvider {
+    private static final Map<SessionDelegate, SessionContext> CONTEXTS = Maps.newConcurrentMap();
+
+    private SessionContextProvider() { }
+
+    @Nonnull
+    public static Session newSession(@Nonnull SessionDelegate delegate, @Nonnull RepositoryImpl repository) {
+        Map<String, String> namespaces = Maps.newHashMap();
+        final Root root = delegate.getRoot();
+
+        NamePathMapperImpl namePathMapper = new NamePathMapperImpl(new LocalNameMapper(namespaces) {
+            @Override
+            protected Map<String, String> getNamespaceMap() {
+                return Namespaces.getNamespaceMap(root.getTree("/"));
+            }
+        }, delegate.getIdManager());
+        ValueFactoryImpl valueFactory = new ValueFactoryImpl(root.getBlobFactory(), namePathMapper);
+        SessionImpl session = new SessionImpl(checkNotNull(delegate), namespaces);
+        WorkspaceImpl workspace = new WorkspaceImpl(delegate);
+
+        CONTEXTS.put(delegate, new SessionContext(
+                checkNotNull(repository), session, workspace, namePathMapper, valueFactory));
+        return session;
+    }
+
+    public static void remove(SessionDelegate delegate) {
+        SessionContext context = CONTEXTS.remove(delegate);
+        if (context == null) {
+            throw new IllegalStateException();
+        }
+        context.dispose();
+    }
+
+    @Nonnull
+    public static SessionImpl getSession(@Nonnull SessionDelegate delegate) {
+        return getSessionContext(delegate).session;
+    }
+
+    @Nonnull
+    public static RepositoryImpl getRepository(@Nonnull SessionDelegate delegate) {
+        return getSessionContext(delegate).repository;
+    }
+
+    @Nonnull
+    public static WorkspaceImpl getWorkspace(@Nonnull SessionDelegate delegate) {
+        return getSessionContext(delegate).workspace;
+    }
+
+    @Nonnull
+    public static LockManager getLockManager(@Nonnull SessionDelegate delegate) {
+        return getWorkspace(delegate).getLockManager();
+    }
+
+    @Nonnull
+    public static NodeTypeManager getNodeTypeManager(@Nonnull SessionDelegate delegate) {
+        return getWorkspace(delegate).getNodeTypeManager();
+    }
+
+    @Nonnull
+    public static VersionManager getVersionManager(@Nonnull SessionDelegate delegate)
+            throws RepositoryException {
+        return getWorkspace(delegate).getVersionManager();
+    }
+
+    @Nonnull
+    public static EffectiveNodeTypeProvider getEffectiveNodeTypeProvider(@Nonnull SessionDelegate delegate) {
+        return getWorkspace(delegate).getReadWriteNodeTypeManager();
+    }
+
+    @Nonnull
+    public static DefinitionProvider getDefinitionProvider(@Nonnull SessionDelegate delegate) {
+        return getWorkspace(delegate).getReadWriteNodeTypeManager();
+    }
+
+    @Nonnull
+    public static NamePathMapperImpl getNamePathMapper(@Nonnull SessionDelegate delegate) {
+        return getSessionContext(delegate).namePathMapper;
+    }
+
+    @Nonnull
+    public static ValueFactoryImpl getValueFactory(@Nonnull SessionDelegate delegate) {
+        return getSessionContext(delegate).valueFactory;
+    }
+
+    @Nonnull
+    public static String getOakName(@Nonnull SessionDelegate delegate, String jcrName)
+            throws RepositoryException {
+        return getSessionContext(delegate).getOakName(jcrName);
+    }
+
+    @CheckForNull
+    public static String getOakPathOrNull(@Nonnull SessionDelegate delegate, String jcrPath) {
+        return getSessionContext(delegate).getOakPathOrNull(jcrPath);
+    }
+
+    @Nonnull
+    public static String getOakPathKeepIndexOrThrowNotFound(@Nonnull SessionDelegate delegate, String jcrPath)
+            throws PathNotFoundException {
+        return getSessionContext(delegate).getOakPathKeepIndexOrThrowNotFound(jcrPath);
+    }
+
+    @Nonnull
+    public static String getOakPathOrThrowNotFound(@Nonnull SessionDelegate delegate, String jcrPath)
+            throws PathNotFoundException {
+        return getSessionContext(delegate).getOakPathOrThrowNotFound(jcrPath);
+    }
+
+    @Nonnull
+    public static String getOakPath(@Nonnull SessionDelegate delegate, String jcrPath)
+            throws RepositoryException {
+        return getSessionContext(delegate).getOakPath(jcrPath);
+    }
+
+    @Nonnull
+    public static SecurityProvider getSecurityProvider(SessionDelegate delegate) {
+        return getRepository(delegate).getSecurityProvider();
+    }
+
+    @Nonnull
+    public static AccessControlManager getAccessControlManager(SessionDelegate delegate) {
+        SessionContext context = getSessionContext(delegate);
+        return context.getAccessControlManager(delegate);
+    }
+
+    @Nonnull
+    public static PermissionProvider getPermissionProvider(SessionDelegate delegate) {
+        SecurityProvider securityProvider = getSecurityProvider(delegate);
+
+        // TODO
+        return securityProvider.getAccessControlConfiguration()
+                .getPermissionProvider(delegate.getRoot(), delegate.getAuthInfo().getPrincipals());
+    }
+
+    @Nonnull
+    public static PrincipalManager getPrincipalManager(SessionDelegate delegate) {
+        SessionContext context = getSessionContext(delegate);
+        return context.getPrincipalManager(delegate);
+    }
+
+    @Nonnull
+    public static UserManager getUserManager(SessionDelegate delegate) {
+        SessionContext context = getSessionContext(delegate);
+        return context.getUserManager(delegate);
+    }
+
+    @Nonnull
+    public static PrivilegeManager getPrivilegeManager(SessionDelegate delegate) {
+        SessionContext context = getSessionContext(delegate);
+        return context.getPrivilegeManager(delegate);
+    }
+
+    @Nonnull
+    public static UserConfiguration getUserConfiguration(SessionDelegate delegate) {
+        SessionContext context = getSessionContext(delegate);
+        return context.getUserConfiguration();
+    }
+
+    @Nonnull
+    public static AccessControlConfiguration getAccessControlConfiguration(SessionDelegate delegate) {
+        SessionContext context = getSessionContext(delegate);
+        return context.getAccessControlConfiguration();
+    }
+
+    @Nonnull
+    public static ObservationManager getObservationManager(SessionDelegate delegate) {
+        SessionContext context = getSessionContext(delegate);
+        return context.getObservationManager(delegate);
+    }
+
+    public static boolean hasPendingEvents(SessionDelegate delegate) {
+        SessionContext context = getSessionContext(delegate);
+        return context.hasPendingEvents();
+    }
+
+    //------------------------------------------------------------< private >---
+
+    @Nonnull
+    private static SessionContext getSessionContext(SessionDelegate delegate) {
+        SessionContext context = CONTEXTS.get(checkNotNull(delegate));
+        if (context == null) {
+            throw new IllegalStateException();
+        }
+        return context;
+    }
+
+    private static class SessionContext {
+        final RepositoryImpl repository;
+        final SessionImpl session;
+        final WorkspaceImpl workspace;
+        final NamePathMapperImpl namePathMapper;
+        final ValueFactoryImpl valueFactory;
+
+        private AccessControlManager accessControlManager;
+        private PrincipalManager principalManager;
+        private UserManager userManager;
+        private PrivilegeManager privilegeManager;
+        private UserConfiguration userConfiguration;
+        private AccessControlConfiguration accessControlConfiguration;
+        private ObservationManagerImpl observationManager;
+
+        SessionContext(RepositoryImpl repository, SessionImpl session, WorkspaceImpl workspace,
+                NamePathMapperImpl namePathMapper, ValueFactoryImpl valueFactory) {
+            this.repository = repository;
+            this.session = session;
+            this.workspace = workspace;
+            this.namePathMapper = namePathMapper;
+            this.valueFactory = valueFactory;
+        }
+
+        /**
+         * Returns the Oak name for the given JCR name, or throws a
+         * {@link RepositoryException} if the name is invalid or can
+         * otherwise not be mapped.
+         *
+         * @param jcrName JCR name
+         * @return Oak name
+         * @throws RepositoryException if the name is invalid
+         */
+        @Nonnull
+        String getOakName(String jcrName) throws RepositoryException {
+            return namePathMapper.getOakName(jcrName);
+        }
+
+        /**
+         * Shortcut for {@code SessionDelegate.getNamePathMapper().getOakPath(jcrPath)}.
+         *
+         * @param jcrPath JCR path
+         * @return Oak path, or {@code null}
+         */
+        @CheckForNull
+        String getOakPathOrNull(String jcrPath) {
+            return namePathMapper.getOakPath(jcrPath);
+        }
+
+        /**
+         * Shortcut for {@code SessionDelegate.getOakPathKeepIndex(jcrPath)}.
+         *
+         * @param jcrPath JCR path
+         * @return Oak path, or {@code null}, with indexes left intact
+         * @throws javax.jcr.PathNotFoundException
+         */
+        @Nonnull
+        String getOakPathKeepIndexOrThrowNotFound(String jcrPath) throws PathNotFoundException {
+            String oakPath = namePathMapper.getOakPathKeepIndex(jcrPath);
+            if (oakPath != null) {
+                return oakPath;
+            } else {
+                throw new PathNotFoundException(jcrPath);
+            }
+        }
+
+        /**
+         * Returns the Oak path for the given JCR path, or throws a
+         * {@link PathNotFoundException} if the path can not be mapped.
+         *
+         * @param jcrPath JCR path
+         * @return Oak path
+         * @throws PathNotFoundException if the path can not be mapped
+         */
+        @Nonnull
+        String getOakPathOrThrowNotFound(String jcrPath) throws PathNotFoundException {
+            String oakPath = getOakPathOrNull(jcrPath);
+            if (oakPath != null) {
+                return oakPath;
+            } else {
+                throw new PathNotFoundException(jcrPath);
+            }
+        }
+
+        /**
+         * Returns the Oak path for the given JCR path, or throws a
+         * {@link RepositoryException} if the path can not be mapped.
+         *
+         * @param jcrPath JCR path
+         * @return Oak path
+         * @throws RepositoryException if the path can not be mapped
+         */
+        @Nonnull
+        String getOakPath(String jcrPath) throws RepositoryException {
+            String oakPath = getOakPathOrNull(jcrPath);
+            if (oakPath != null) {
+                return oakPath;
+            } else {
+                throw new RepositoryException("Invalid name or path: " + jcrPath);
+            }
+        }
+
+        @Nonnull
+        AccessControlManager getAccessControlManager(SessionDelegate delegate) {
+            if (accessControlManager == null) {
+                SecurityProvider securityProvider = repository.getSecurityProvider();
+                accessControlManager = securityProvider.getAccessControlConfiguration()
+                        .getAccessControlManager(delegate.getRoot(), namePathMapper);
+            }
+            return accessControlManager;
+        }
+
+        @Nonnull
+        PrincipalManager getPrincipalManager(SessionDelegate delegate) {
+            if (principalManager == null) {
+                SecurityProvider securityProvider = repository.getSecurityProvider();
+                principalManager = securityProvider.getPrincipalConfiguration()
+                        .getPrincipalManager(delegate.getRoot(), namePathMapper);
+            }
+            return principalManager;
+        }
+
+        @Nonnull
+        UserManager getUserManager(SessionDelegate delegate) {
+            if (userManager == null) {
+                SecurityProvider securityProvider = repository.getSecurityProvider();
+                userManager = securityProvider.getUserConfiguration().getUserManager(delegate.getRoot(), namePathMapper);
+            }
+            return userManager;
+        }
+
+        @Nonnull
+        PrivilegeManager getPrivilegeManager(SessionDelegate delegate) {
+            if (privilegeManager == null) {
+                SecurityProvider securityProvider = repository.getSecurityProvider();
+                privilegeManager = securityProvider.getPrivilegeConfiguration().getPrivilegeManager(delegate.getRoot(), namePathMapper);
+            }
+            return privilegeManager;
+        }
+
+        @Nonnull
+        UserConfiguration getUserConfiguration() {
+            if (userConfiguration == null) {
+                SecurityProvider securityProvider = repository.getSecurityProvider();
+                userConfiguration = securityProvider.getUserConfiguration();
+            }
+            return userConfiguration;
+        }
+
+        @Nonnull
+        AccessControlConfiguration getAccessControlConfiguration() {
+            if (accessControlConfiguration == null) {
+                SecurityProvider securityProvider = repository.getSecurityProvider();
+                accessControlConfiguration = securityProvider.getAccessControlConfiguration();
+            }
+            return accessControlConfiguration;
+        }
+
+        @Nonnull
+        ObservationManager getObservationManager(SessionDelegate delegate) {
+            if (observationManager == null) {
+                observationManager = new ObservationManagerImpl(
+                        delegate.getRoot(), namePathMapper, repository.getObservationExecutor());
+            }
+            return observationManager;
+        }
+
+        void dispose() {
+            if (observationManager != null) {
+                observationManager.dispose();
+            }
+        }
+
+        public boolean hasPendingEvents() {
+            return observationManager != null && observationManager.hasEvents();
+        }
+    }
+}

Propchange: jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/SessionContextProvider.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/SessionContextProvider.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev URL

Modified: jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/SessionImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/SessionImpl.java?rev=1456022&r1=1456021&r2=1456022&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/SessionImpl.java (original)
+++ jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/SessionImpl.java Wed Mar 13 16:23:28 2013
@@ -36,6 +36,7 @@ import javax.jcr.Session;
 import javax.jcr.UnsupportedRepositoryOperationException;
 import javax.jcr.ValueFactory;
 import javax.jcr.Workspace;
+import javax.jcr.lock.LockManager;
 import javax.jcr.retention.RetentionManager;
 import javax.jcr.security.AccessControlException;
 import javax.jcr.security.AccessControlManager;
@@ -51,7 +52,11 @@ import org.apache.jackrabbit.oak.jcr.del
 import org.apache.jackrabbit.oak.jcr.delegate.SessionDelegate;
 import org.apache.jackrabbit.oak.jcr.delegate.SessionOperation;
 import org.apache.jackrabbit.oak.jcr.xml.ImportHandler;
+import org.apache.jackrabbit.oak.namepath.NamePathMapper;
 import org.apache.jackrabbit.oak.spi.security.authentication.ImpersonationCredentials;
+import org.apache.jackrabbit.oak.spi.security.authorization.AccessControlConfiguration;
+import org.apache.jackrabbit.oak.spi.security.authorization.PermissionProvider;
+import org.apache.jackrabbit.oak.spi.security.user.UserConfiguration;
 import org.apache.jackrabbit.oak.util.TODO;
 import org.apache.jackrabbit.util.Text;
 import org.apache.jackrabbit.util.XMLChar;
@@ -89,7 +94,7 @@ public class SessionImpl extends Abstrac
     @Override
     @Nonnull
     public Repository getRepository() {
-        return dlg.getRepository();
+        return SessionContextProvider.getRepository(dlg);
     }
 
     @Override
@@ -110,7 +115,7 @@ public class SessionImpl extends Abstrac
     @Override
     @Nonnull
     public Workspace getWorkspace() {
-        return dlg.getWorkspace();
+        return SessionContextProvider.getWorkspace(dlg);
     }
 
     @Override
@@ -126,7 +131,7 @@ public class SessionImpl extends Abstrac
     @Nonnull
     public ValueFactory getValueFactory() throws RepositoryException {
         ensureIsAlive();
-        return dlg.getValueFactory();
+        return SessionContextProvider.getValueFactory(dlg);
     }
 
     @Override
@@ -190,6 +195,10 @@ public class SessionImpl extends Abstrac
         return nodeExists(absPath) || propertyExists(absPath);
     }
 
+    private String getOakPath(String absPath) throws RepositoryException {
+        return SessionContextProvider.getOakPath(dlg, absPath);
+    }
+
     @Override
     public Node getNode(final String absPath) throws RepositoryException {
         return dlg.perform(new SessionOperation<NodeImpl<?>>() {
@@ -200,7 +209,7 @@ public class SessionImpl extends Abstrac
 
             @Override
             public NodeImpl<?> perform() throws RepositoryException {
-                String oakPath = dlg.getOakPath(absPath);
+                String oakPath = getOakPath(absPath);
                 NodeDelegate d = dlg.getNode(oakPath);
                 if (d == null) {
                     throw new PathNotFoundException("Node with path " + absPath + " does not exist.");
@@ -220,7 +229,7 @@ public class SessionImpl extends Abstrac
 
             @Override
             public Boolean perform() throws RepositoryException {
-                String oakPath = dlg.getOakPath(absPath);
+                String oakPath = getOakPath(absPath);
                 return dlg.getNode(oakPath) != null;
             }
         });
@@ -234,7 +243,7 @@ public class SessionImpl extends Abstrac
             return dlg.perform(new SessionOperation<PropertyImpl>() {
                 @Override
                 public PropertyImpl perform() throws RepositoryException {
-                    String oakPath = dlg.getOakPathOrThrowNotFound(absPath);
+                    String oakPath = getOakPathOrThrowNotFound(absPath);
                     TreeLocation loc = dlg.getLocation(oakPath);
                     if (loc.getProperty() == null) {
                         throw new PathNotFoundException(absPath);
@@ -246,6 +255,10 @@ public class SessionImpl extends Abstrac
         }
     }
 
+    private String getOakPathOrThrowNotFound(String absPath) throws PathNotFoundException {
+        return SessionContextProvider.getOakPathOrThrowNotFound(dlg, absPath);
+    }
+
     @Override
     public boolean propertyExists(final String absPath) throws RepositoryException {
         if (absPath.equals("/")) {
@@ -254,7 +267,7 @@ public class SessionImpl extends Abstrac
             return dlg.perform(new SessionOperation<Boolean>() {
                 @Override
                 public Boolean perform() throws RepositoryException {
-                    String oakPath = dlg.getOakPathOrThrowNotFound(absPath);
+                    String oakPath = getOakPathOrThrowNotFound(absPath);
                     TreeLocation loc = dlg.getLocation(oakPath);
                     return loc.getProperty() != null;
                 }
@@ -273,7 +286,7 @@ public class SessionImpl extends Abstrac
             @Override
             public Void perform() throws RepositoryException {
                 dlg.checkProtectedNodes(Text.getRelativeParent(srcAbsPath, 1), Text.getRelativeParent(destAbsPath, 1));
-                String oakPath = dlg.getOakPathKeepIndexOrThrowNotFound(destAbsPath);
+                String oakPath = SessionContextProvider.getOakPathKeepIndexOrThrowNotFound(dlg, destAbsPath);
                 String oakName = PathUtils.getName(oakPath);
                 // handle index
                 if (oakName.contains("[")) {
@@ -281,8 +294,8 @@ public class SessionImpl extends Abstrac
                 }
 
                 dlg.move(
-                        dlg.getOakPathOrThrowNotFound(srcAbsPath),
-                        dlg.getOakPathOrThrowNotFound(oakPath),
+                        getOakPathOrThrowNotFound(srcAbsPath),
+                        getOakPathOrThrowNotFound(oakPath),
                         true);
 
                 return null;
@@ -316,6 +329,7 @@ public class SessionImpl extends Abstrac
 
     @Override
     public void logout() {
+        SessionContextProvider.remove(dlg);
         dlg.logout();
         synchronized (namespaces) {
             namespaces.clear();
@@ -326,8 +340,15 @@ public class SessionImpl extends Abstrac
     @Nonnull
     public ContentHandler getImportContentHandler(
             String parentAbsPath, int uuidBehavior) throws RepositoryException {
+        UserConfiguration userConfiguration = SessionContextProvider.getUserConfiguration(dlg);
+        AccessControlConfiguration accessControlConfiguration = SessionContextProvider.getAccessControlConfiguration(dlg);
         return new ImportHandler(getNode(parentAbsPath), dlg.getRoot(), this,
-                dlg, dlg.getUserConfiguration(), dlg.getAccessControlConfiguration(), uuidBehavior);
+                dlg, userConfiguration, accessControlConfiguration, uuidBehavior);
+    }
+
+    @Nonnull
+    private LockManager getLockManager() {
+        return SessionContextProvider.getLockManager(dlg);
     }
 
     /**
@@ -336,7 +357,7 @@ public class SessionImpl extends Abstrac
     @Override
     public void addLockToken(String lt) {
         try {
-            dlg.getLockManager().addLockToken(lt);
+            getLockManager().addLockToken(lt);
         } catch (RepositoryException e) {
             log.warn("Unable to add lock token '{}' to this session: {}", lt, e.getMessage());
         }
@@ -349,7 +370,7 @@ public class SessionImpl extends Abstrac
     @Nonnull
     public String[] getLockTokens() {
         try {
-            return dlg.getLockManager().getLockTokens();
+            return getLockManager().getLockTokens();
         } catch (RepositoryException e) {
             log.warn("Unable to retrieve lock tokens for this session: {}", e.getMessage());
             return new String[0];
@@ -362,7 +383,7 @@ public class SessionImpl extends Abstrac
     @Override
     public void removeLockToken(String lt) {
         try {
-            dlg.getLockManager().addLockToken(lt);
+            getLockManager().addLockToken(lt);
         } catch (RepositoryException e) {
             log.warn("Unable to add lock token '{}' to this session: {}", lt, e.getMessage());
         }
@@ -372,12 +393,14 @@ public class SessionImpl extends Abstrac
     public boolean hasPermission(String absPath, String actions) throws RepositoryException {
         ensureIsAlive();
 
-        String oakPath = dlg.getNamePathMapper().getOakPathKeepIndex(absPath);
+        NamePathMapper namePathMapper = SessionContextProvider.getNamePathMapper(dlg);
+        String oakPath = namePathMapper.getOakPathKeepIndex(absPath);
         if (oakPath == null) {
             throw new RepositoryException("Invalid JCR path: " + absPath);
         }
 
-        return dlg.getPermissionProvider().hasPermission(absPath, actions);
+        PermissionProvider permissionProvider = SessionContextProvider.getPermissionProvider(dlg);
+        return permissionProvider.hasPermission(absPath, actions);
     }
 
     @Override
@@ -398,7 +421,7 @@ public class SessionImpl extends Abstrac
     @Override
     @Nonnull
     public AccessControlManager getAccessControlManager() throws RepositoryException {
-        return dlg.getAccessControlManager();
+        return SessionContextProvider.getAccessControlManager(dlg);
     }
 
     /**
@@ -516,13 +539,13 @@ public class SessionImpl extends Abstrac
     @Override
     @Nonnull
     public PrincipalManager getPrincipalManager() throws RepositoryException {
-        return dlg.getPrincipalManager();
+        return SessionContextProvider.getPrincipalManager(dlg);
     }
 
     @Override
     @Nonnull
     public UserManager getUserManager() throws RepositoryException {
-        return dlg.getUserManager();
+        return SessionContextProvider.getUserManager(dlg);
     }
 
     //------------------------------------------------------------< private >---

Modified: jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/WorkspaceImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/WorkspaceImpl.java?rev=1456022&r1=1456021&r2=1456022&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/WorkspaceImpl.java (original)
+++ jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/WorkspaceImpl.java Wed Mar 13 16:23:28 2013
@@ -20,6 +20,7 @@ import java.io.IOException;
 import java.io.InputStream;
 import javax.annotation.Nonnull;
 import javax.jcr.NamespaceRegistry;
+import javax.jcr.PathNotFoundException;
 import javax.jcr.RepositoryException;
 import javax.jcr.Session;
 import javax.jcr.UnsupportedRepositoryOperationException;
@@ -58,18 +59,49 @@ public class WorkspaceImpl implements Ja
     private final QueryManagerImpl queryManager;
     private final LockManager lockManager;
     private final VersionManagerImpl versionManager;
+    private final ReadWriteNodeTypeManager nodeTypeManager;
 
-    public WorkspaceImpl(SessionDelegate sessionDelegate) {
+    public WorkspaceImpl(final SessionDelegate sessionDelegate) {
         this.sessionDelegate = sessionDelegate;
         this.queryManager = new QueryManagerImpl(sessionDelegate);
         this.lockManager = new LockManagerImpl(sessionDelegate);
         this.versionManager = new VersionManagerImpl(sessionDelegate);
+        this.nodeTypeManager = new ReadWriteNodeTypeManager() {
+            @Override
+            protected void refresh() throws RepositoryException {
+                getSession().refresh(true);
+            }
+
+            @Override
+            protected Tree getTypes() {
+                return sessionDelegate.getRoot().getTree(NODE_TYPES_PATH);
+            }
+
+            @Nonnull
+            @Override
+            protected Root getWriteRoot() {
+                return sessionDelegate.getContentSession().getLatestRoot();
+            }
+
+            @Override
+            @Nonnull
+            protected ValueFactory getValueFactory() {
+                return SessionContextProvider.getValueFactory(sessionDelegate);
+            }
+
+            @Nonnull
+            @Override
+            protected NamePathMapper getNamePathMapper() {
+                return SessionContextProvider.getNamePathMapper(sessionDelegate);
+            }
+        };
     }
 
     //----------------------------------------------------------< Workspace >---
     @Override
+    @Nonnull
     public Session getSession() {
-        return sessionDelegate.getSession();
+        return SessionContextProvider.getSession(sessionDelegate);
     }
 
     @Override
@@ -82,6 +114,10 @@ public class WorkspaceImpl implements Ja
         copy(getName(), srcAbsPath, destAbsPath);
     }
 
+    private String getOakPathKeepIndexOrThrowNotFound(String absPath) throws PathNotFoundException {
+        return SessionContextProvider.getOakPathKeepIndexOrThrowNotFound(sessionDelegate, absPath);
+    }
+
     @Override
     public void copy(String srcWorkspace, String srcAbsPath, String destAbsPath) throws RepositoryException {
         ensureIsAlive();
@@ -92,7 +128,7 @@ public class WorkspaceImpl implements Ja
 
         sessionDelegate.checkProtectedNodes(Text.getRelativeParent(srcAbsPath, 1), Text.getRelativeParent(destAbsPath, 1));
 
-        String oakPath = sessionDelegate.getOakPathKeepIndexOrThrowNotFound(destAbsPath);
+        String oakPath = getOakPathKeepIndexOrThrowNotFound(destAbsPath);
         String oakName = PathUtils.getName(oakPath);
         // handle index
         if (oakName.contains("[")) {
@@ -100,8 +136,12 @@ public class WorkspaceImpl implements Ja
         }
 
         sessionDelegate.copy(
-                sessionDelegate.getOakPathOrThrowNotFound(srcAbsPath),
-                sessionDelegate.getOakPathOrThrowNotFound(oakPath));
+                getOakPathOrThrowNotFound(srcAbsPath),
+                getOakPathOrThrowNotFound(oakPath));
+    }
+
+    private String getOakPathOrThrowNotFound(String srcAbsPath) throws PathNotFoundException {
+        return SessionContextProvider.getOakPathOrThrowNotFound(sessionDelegate, srcAbsPath);
     }
 
     @Override
@@ -120,7 +160,7 @@ public class WorkspaceImpl implements Ja
 
         sessionDelegate.checkProtectedNodes(Text.getRelativeParent(srcAbsPath, 1), Text.getRelativeParent(destAbsPath, 1));
 
-        String oakPath = sessionDelegate.getOakPathKeepIndexOrThrowNotFound(destAbsPath);
+        String oakPath = getOakPathKeepIndexOrThrowNotFound(destAbsPath);
         String oakName = PathUtils.getName(oakPath);
         // handle index
         if (oakName.contains("[")) {
@@ -128,8 +168,8 @@ public class WorkspaceImpl implements Ja
         }
 
         sessionDelegate.move(
-                sessionDelegate.getOakPathOrThrowNotFound(srcAbsPath),
-                sessionDelegate.getOakPathOrThrowNotFound(oakPath),
+                getOakPathOrThrowNotFound(srcAbsPath),
+                getOakPathOrThrowNotFound(oakPath),
                 false);
     }
 
@@ -171,41 +211,14 @@ public class WorkspaceImpl implements Ja
 
     @Override
     public NodeTypeManager getNodeTypeManager() {
-        return new ReadWriteNodeTypeManager() {
-            @Override
-            protected void refresh() throws RepositoryException {
-                getSession().refresh(true);
-            }
-
-            @Override
-            protected Tree getTypes() {
-                return sessionDelegate.getRoot().getTree(NODE_TYPES_PATH);
-            }
-
-            @Nonnull
-            @Override
-            protected Root getWriteRoot() {
-                return sessionDelegate.getContentSession().getLatestRoot();
-            }
-
-            @Override
-            protected ValueFactory getValueFactory() {
-                return sessionDelegate.getValueFactory();
-            }
-
-            @Nonnull
-            @Override
-            protected NamePathMapper getNamePathMapper() {
-                return sessionDelegate.getNamePathMapper();
-            }
-        };
+        return getReadWriteNodeTypeManager();
     }
 
     @Override
     public ObservationManager getObservationManager() throws RepositoryException {
         ensureIsAlive();
 
-        return sessionDelegate.getObservationManager();
+        return SessionContextProvider.getObservationManager(sessionDelegate);
     }
 
     @Override
@@ -277,7 +290,13 @@ public class WorkspaceImpl implements Ja
      */
     @Override
     public PrivilegeManager getPrivilegeManager() throws RepositoryException {
-        return sessionDelegate.getPrivilegeManager();
+        return SessionContextProvider.getPrivilegeManager(sessionDelegate);
+    }
+
+    //------------------------------------------------------------< internal >---
+
+    ReadWriteNodeTypeManager getReadWriteNodeTypeManager() {
+        return nodeTypeManager;
     }
 
     //------------------------------------------------------------< private >---

Modified: jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/PropertyDelegate.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/PropertyDelegate.java?rev=1456022&r1=1456021&r2=1456022&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/PropertyDelegate.java (original)
+++ jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/PropertyDelegate.java Wed Mar 13 16:23:28 2013
@@ -16,18 +16,14 @@
  */
 package org.apache.jackrabbit.oak.jcr.delegate;
 
-import java.util.List;
-
-import javax.annotation.Nonnull;
+import javax.annotation.CheckForNull;
 import javax.jcr.InvalidItemStateException;
 import javax.jcr.RepositoryException;
 import javax.jcr.Value;
-import javax.jcr.ValueFormatException;
 
 import org.apache.jackrabbit.oak.api.PropertyState;
 import org.apache.jackrabbit.oak.api.TreeLocation;
 import org.apache.jackrabbit.oak.plugins.memory.PropertyStates;
-import org.apache.jackrabbit.oak.plugins.value.ValueFactoryImpl;
 
 /**
  * {@code PropertyDelegate} serve as internal representations of {@code Property}s.
@@ -42,47 +38,6 @@ public class PropertyDelegate extends It
     }
 
     /**
-     * Get the value of the property
-     *
-     * @return the value of the property
-     * @throws InvalidItemStateException
-     * @throws ValueFormatException if this property is multi-valued
-     */
-    @Nonnull
-    public Value getValue() throws InvalidItemStateException, ValueFormatException {
-        PropertyState property = getPropertyState();
-        if (property.isArray()) {
-            throw new ValueFormatException(this + " is multi-valued.");
-        }
-        return ValueFactoryImpl.createValue(property, sessionDelegate.getNamePathMapper());
-    }
-
-    /**
-     * Get the values of the property
-     *
-     * @return the values of the property
-     * @throws InvalidItemStateException
-     * @throws ValueFormatException if this property is single-valued
-     */
-    @Nonnull
-    public List<Value> getValues() throws InvalidItemStateException, ValueFormatException {
-        PropertyState property = getPropertyState();
-        if (!property.isArray()) {
-            throw new ValueFormatException(this + " is single-valued.");
-        }
-        return ValueFactoryImpl.createValues(property, sessionDelegate.getNamePathMapper());
-    }
-
-    /**
-     * Determine whether the property is multi valued
-     *
-     * @return {@code true} if multi valued
-     */
-    public boolean isMultivalue() throws InvalidItemStateException {
-        return getPropertyState().isArray();
-    }
-
-    /**
      * Set the value of the property
      *
      * @param value
@@ -111,15 +66,9 @@ public class PropertyDelegate extends It
         getLocation().remove();
     }
 
-    //------------------------------------------------------------< private >---
-
-    @Nonnull
-    private PropertyState getPropertyState() throws InvalidItemStateException {
-        PropertyState property = getLocation().getProperty();
-        if (property == null) {
-            throw new InvalidItemStateException();
-        }
-        return property;
+    @CheckForNull
+    public PropertyState getPropertyState() throws InvalidItemStateException {
+        return getLocation().getProperty();
     }
 
 }