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/09 00:19:01 UTC

svn commit: r1454622 - in /jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr: ItemImpl.java NodeImpl.java PropertyImpl.java SessionImpl.java delegate/SessionDelegate.java delegate/SessionOperation.java

Author: mduerig
Date: Fri Mar  8 23:19:00 2013
New Revision: 1454622

URL: http://svn.apache.org/r1454622
Log:
OAK-672: Avoid JCR APIs calling other JCR APIs
Extend SessionOperation with preconditions

Modified:
    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/SessionImpl.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/SessionOperation.java

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=1454622&r1=1454621&r2=1454622&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 Fri Mar  8 23:19:00 2013
@@ -88,9 +88,13 @@ abstract class ItemImpl<T extends ItemDe
     @Override
     @Nonnull
     public String getPath() throws RepositoryException {
-        checkStatus();
         return perform(new SessionOperation<String>() {
             @Override
+            protected void checkPreconditions() throws RepositoryException {
+                checkStatus();
+            }
+
+            @Override
             public String perform() throws RepositoryException {
                 return toJcrPath(dlg.getPath());
             }

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=1454622&r1=1454621&r2=1454622&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 Fri Mar  8 23:19:00 2013
@@ -120,10 +120,13 @@ public class NodeImpl<T extends NodeDele
     @Override
     @Nonnull
     public Node getParent() throws RepositoryException {
-        checkStatus();
-
         return perform(new SessionOperation<NodeImpl<NodeDelegate>>() {
             @Override
+            protected void checkPreconditions() throws RepositoryException {
+                checkStatus();
+            }
+
+            @Override
             public NodeImpl<NodeDelegate> perform() throws RepositoryException {
                 if (dlg.isRoot()) {
                     throw new ItemNotFoundException("Root has no parent");
@@ -177,11 +180,14 @@ public class NodeImpl<T extends NodeDele
      */
     @Override
     public void remove() throws RepositoryException {
-        checkStatus();
-        checkProtected();
-
         perform(new SessionOperation<Void>() {
             @Override
+            protected void checkPreconditions() throws RepositoryException {
+                checkStatus();
+                checkProtected();
+            }
+
+            @Override
             public Void perform() throws RepositoryException {
                 if (dlg.isRoot()) {
                     throw new RepositoryException("Cannot remove the root node");
@@ -290,11 +296,14 @@ public class NodeImpl<T extends NodeDele
 
     @Override
     public void orderBefore(final String srcChildRelPath, final String destChildRelPath) throws RepositoryException {
-        checkStatus();
-        checkProtected();
-
         perform(new SessionOperation<Void>() {
             @Override
+            protected void checkPreconditions() throws RepositoryException {
+                checkStatus();
+                checkProtected();
+            }
+
+            @Override
             public Void perform() throws RepositoryException {
                 getEffectiveNodeType().checkOrderableChildNodes();
                 String oakSrcChildRelPath =
@@ -479,10 +488,13 @@ public class NodeImpl<T extends NodeDele
     @Override
     @Nonnull
     public Node getNode(final String relPath) throws RepositoryException {
-        checkStatus();
-
         return perform(new SessionOperation<NodeImpl<?>>() {
             @Override
+            protected void checkPreconditions() throws RepositoryException {
+                checkStatus();
+            }
+
+            @Override
             public NodeImpl<?> perform() throws RepositoryException {
                 String oakPath = sessionDelegate.getOakPathOrThrowNotFound(relPath);
 
@@ -499,10 +511,13 @@ public class NodeImpl<T extends NodeDele
     @Override
     @Nonnull
     public NodeIterator getNodes() throws RepositoryException {
-        checkStatus();
-
         return perform(new SessionOperation<NodeIterator>() {
             @Override
+            protected void checkPreconditions() throws RepositoryException {
+                checkStatus();
+            }
+
+            @Override
             public NodeIterator perform() throws RepositoryException {
                 Iterator<NodeDelegate> children = dlg.getChildren();
                 long size = dlg.getChildCount();
@@ -515,10 +530,14 @@ public class NodeImpl<T extends NodeDele
     @Nonnull
     public NodeIterator getNodes(final String namePattern)
             throws RepositoryException {
-        checkStatus();
 
         return perform(new SessionOperation<NodeIterator>() {
             @Override
+            protected void checkPreconditions() throws RepositoryException {
+                checkStatus();
+            }
+
+            @Override
             public NodeIterator perform() throws RepositoryException {
                 Iterator<NodeDelegate> children = Iterators.filter(dlg.getChildren(),
                         new Predicate<NodeDelegate>() {
@@ -540,10 +559,13 @@ public class NodeImpl<T extends NodeDele
     @Override
     @Nonnull
     public NodeIterator getNodes(final String[] nameGlobs) throws RepositoryException {
-        checkStatus();
-
         return perform(new SessionOperation<NodeIterator>() {
             @Override
+            protected void checkPreconditions() throws RepositoryException {
+                checkStatus();
+            }
+
+            @Override
             public NodeIterator perform() throws RepositoryException {
                 Iterator<NodeDelegate> children = Iterators.filter(dlg.getChildren(),
                         new Predicate<NodeDelegate>() {
@@ -565,10 +587,13 @@ public class NodeImpl<T extends NodeDele
     @Override
     @Nonnull
     public Property getProperty(final String relPath) throws RepositoryException {
-        checkStatus();
-
         return perform(new SessionOperation<PropertyImpl>() {
             @Override
+            protected void checkPreconditions() throws RepositoryException {
+                checkStatus();
+            }
+
+            @Override
             public PropertyImpl perform() throws RepositoryException {
                 String oakPath = sessionDelegate.getOakPathOrThrowNotFound(relPath);
                 PropertyDelegate pd = dlg.getProperty(oakPath);
@@ -584,10 +609,13 @@ public class NodeImpl<T extends NodeDele
     @Override
     @Nonnull
     public PropertyIterator getProperties() throws RepositoryException {
-        checkStatus();
-
         return perform(new SessionOperation<PropertyIterator>() {
             @Override
+            protected void checkPreconditions() throws RepositoryException {
+                checkStatus();
+            }
+
+            @Override
             public PropertyIterator perform() throws RepositoryException {
                 Iterator<PropertyDelegate> properties = dlg.getProperties();
                 long size = dlg.getPropertyCount();
@@ -599,10 +627,13 @@ public class NodeImpl<T extends NodeDele
     @Override
     @Nonnull
     public PropertyIterator getProperties(final String namePattern) throws RepositoryException {
-        checkStatus();
-
         return perform(new SessionOperation<PropertyIterator>() {
             @Override
+            protected void checkPreconditions() throws RepositoryException {
+                checkStatus();
+            }
+
+            @Override
             public PropertyIterator perform() throws RepositoryException {
                 Iterator<PropertyDelegate> properties = Iterators.filter(dlg.getProperties(),
                         new Predicate<PropertyDelegate>() {
@@ -624,10 +655,13 @@ public class NodeImpl<T extends NodeDele
     @Override
     @Nonnull
     public PropertyIterator getProperties(final String[] nameGlobs) throws RepositoryException {
-        checkStatus();
-
         return perform(new SessionOperation<PropertyIterator>() {
             @Override
+            protected void checkPreconditions() throws RepositoryException {
+                checkStatus();
+            }
+
+            @Override
             public PropertyIterator perform() throws RepositoryException {
                 Iterator<PropertyDelegate> propertyNames = Iterators.filter(dlg.getProperties(),
                         new Predicate<PropertyDelegate>() {
@@ -652,10 +686,13 @@ public class NodeImpl<T extends NodeDele
     @Override
     @Nonnull
     public Item getPrimaryItem() throws RepositoryException {
-        checkStatus();
-
         return perform(new SessionOperation<Item>() {
             @Override
+            protected void checkPreconditions() throws RepositoryException {
+                checkStatus();
+            }
+
+            @Override
             public Item perform() throws RepositoryException {
                 String name = getPrimaryNodeType().getPrimaryItemName();
                 if (name == null) {
@@ -678,10 +715,13 @@ public class NodeImpl<T extends NodeDele
     @Override
     @Nonnull
     public String getUUID() throws RepositoryException {
-        checkStatus();
-
         return perform(new SessionOperation<String>() {
             @Override
+            protected void checkPreconditions() throws RepositoryException {
+                checkStatus();
+            }
+
+            @Override
             public String perform() throws RepositoryException {
                 if (isNodeType(NodeType.MIX_REFERENCEABLE)) {
                     return getIdentifier();
@@ -695,10 +735,13 @@ public class NodeImpl<T extends NodeDele
     @Override
     @Nonnull
     public String getIdentifier() throws RepositoryException {
-        checkStatus();
-
         return perform(new SessionOperation<String>() {
             @Override
+            protected void checkPreconditions() throws RepositoryException {
+                checkStatus();
+            }
+
+            @Override
             public String perform() throws RepositoryException {
                 return dlg.getIdentifier();
             }
@@ -768,10 +811,13 @@ public class NodeImpl<T extends NodeDele
 
     @Override
     public boolean hasNode(final String relPath) throws RepositoryException {
-        checkStatus();
-
         return perform(new SessionOperation<Boolean>() {
             @Override
+            protected void checkPreconditions() throws RepositoryException {
+                checkStatus();
+            }
+
+            @Override
             public Boolean perform() throws RepositoryException {
                 String oakPath = sessionDelegate.getOakPath(relPath);
                 return dlg.getChild(oakPath) != null;
@@ -781,10 +827,13 @@ public class NodeImpl<T extends NodeDele
 
     @Override
     public boolean hasProperty(final String relPath) throws RepositoryException {
-        checkStatus();
-
         return perform(new SessionOperation<Boolean>() {
             @Override
+            protected void checkPreconditions() throws RepositoryException {
+                checkStatus();
+            }
+
+            @Override
             public Boolean perform() throws RepositoryException {
                 String oakPath = sessionDelegate.getOakPath(relPath);
                 return dlg.getProperty(oakPath) != null;
@@ -794,10 +843,13 @@ public class NodeImpl<T extends NodeDele
 
     @Override
     public boolean hasNodes() throws RepositoryException {
-        checkStatus();
-
         return perform(new SessionOperation<Boolean>() {
             @Override
+            protected void checkPreconditions() throws RepositoryException {
+                checkStatus();
+            }
+
+            @Override
             public Boolean perform() throws RepositoryException {
                 return dlg.getChildCount() != 0;
             }
@@ -806,10 +858,13 @@ public class NodeImpl<T extends NodeDele
 
     @Override
     public boolean hasProperties() throws RepositoryException {
-        checkStatus();
-
         return perform(new SessionOperation<Boolean>() {
             @Override
+            protected void checkPreconditions() throws RepositoryException {
+                checkStatus();
+            }
+
+            @Override
             public Boolean perform() throws RepositoryException {
                 return dlg.getPropertyCount() != 0;
             }
@@ -822,10 +877,13 @@ public class NodeImpl<T extends NodeDele
     @Override
     @Nonnull
     public NodeType getPrimaryNodeType() throws RepositoryException {
-        checkStatus();
-
         return perform(new SessionOperation<NodeType>() {
             @Override
+            protected void checkPreconditions() throws RepositoryException {
+                checkStatus();
+            }
+
+            @Override
             public NodeType perform() throws RepositoryException {
                 NodeTypeManager ntMgr = sessionDelegate.getNodeTypeManager();
                 String primaryNtName;
@@ -845,10 +903,13 @@ public class NodeImpl<T extends NodeDele
     @Override
     @Nonnull
     public NodeType[] getMixinNodeTypes() throws RepositoryException {
-        checkStatus();
-
         return perform(new SessionOperation<NodeType[]>() {
             @Override
+            protected void checkPreconditions() throws RepositoryException {
+                checkStatus();
+            }
+
+            @Override
             public NodeType[] perform() throws RepositoryException {
                 // TODO: check if transient changes to mixin-types are reflected here
                 if (hasProperty(Property.JCR_MIXIN_TYPES)) {
@@ -888,11 +949,14 @@ public class NodeImpl<T extends NodeDele
 
     @Override
     public void addMixin(final String mixinName) throws RepositoryException {
-        checkStatus();
-        checkProtected();
-
         perform(new SessionOperation<Void>() {
             @Override
+            protected void checkPreconditions() throws RepositoryException {
+                checkStatus();
+                checkProtected();
+            }
+
+            @Override
             public Void perform() throws RepositoryException {
                 // TODO: figure out the right place for this check
                 NodeTypeManager ntm = sessionDelegate.getNodeTypeManager();
@@ -929,11 +993,14 @@ public class NodeImpl<T extends NodeDele
 
     @Override
     public void removeMixin(final String mixinName) throws RepositoryException {
-        checkStatus();
-        checkProtected();
-
         perform(new SessionOperation<Void>() {
             @Override
+            protected void checkPreconditions() throws RepositoryException {
+                checkStatus();
+                checkProtected();
+            }
+
+            @Override
             public Void perform() throws RepositoryException {
                 if (!isNodeType(mixinName)) {
                     throw new NoSuchNodeTypeException();
@@ -946,10 +1013,13 @@ public class NodeImpl<T extends NodeDele
 
     @Override
     public boolean canAddMixin(final String mixinName) throws RepositoryException {
-        checkStatus();
-
         return perform(new SessionOperation<Boolean>() {
             @Override
+            protected void checkPreconditions() throws RepositoryException {
+                checkStatus();
+            }
+
+            @Override
             public Boolean perform() throws RepositoryException {
                 // TODO: figure out the right place for this check
                 NodeTypeManager ntm = sessionDelegate.getNodeTypeManager();
@@ -1457,11 +1527,14 @@ public class NodeImpl<T extends NodeDele
 
     private Property internalSetProperty(final String jcrName, final Value value,
                                          final int type, final boolean exactTypeMatch) throws RepositoryException {
-        checkStatus();
-        checkProtected();
-
         return perform(new SessionOperation<Property>() {
             @Override
+            protected void checkPreconditions() throws RepositoryException {
+                checkStatus();
+                checkProtected();
+            }
+
+            @Override
             public Property perform() throws RepositoryException {
                 String oakName = sessionDelegate.getOakPath(jcrName);
                 if (value == null) {
@@ -1502,11 +1575,14 @@ public class NodeImpl<T extends NodeDele
 
     private Property internalSetProperty(final String jcrName, final Value[] values,
                                          final int type, final boolean exactTypeMatch) throws RepositoryException {
-        checkStatus();
-        checkProtected();
-
         return perform(new SessionOperation<Property>() {
             @Override
+            protected void checkPreconditions() throws RepositoryException {
+                checkStatus();
+                checkProtected();
+            }
+
+            @Override
             public Property perform() throws RepositoryException {
                 String oakName = sessionDelegate.getOakPath(jcrName);
                 if (values == null) {

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=1454622&r1=1454621&r2=1454622&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 Fri Mar  8 23:19:00 2013
@@ -133,11 +133,14 @@ public class PropertyImpl extends ItemIm
      */
     @Override
     public void remove() throws RepositoryException {
-        checkStatus();
-        checkProtected();
-
         perform(new SessionOperation<Void>() {
             @Override
+            protected void checkPreconditions() throws RepositoryException {
+                checkStatus();
+                checkProtected();
+            }
+
+            @Override
             public Void perform() throws RepositoryException {
                 dlg.remove();
                 return null;
@@ -173,10 +176,13 @@ public class PropertyImpl extends ItemIm
      */
     @Override
     public void setValue(final Value[] values) throws RepositoryException {
-        checkStatus();
-
         perform(new SessionOperation<Void>() {
             @Override
+            protected void checkPreconditions() throws RepositoryException {
+                checkStatus();
+            }
+
+            @Override
             public Void perform() throws RepositoryException {
                 // assert equal types for all values entries
                 int valueType = PropertyType.UNDEFINED;
@@ -351,10 +357,13 @@ public class PropertyImpl extends ItemIm
     @Override
     @Nonnull
     public Value getValue() throws RepositoryException {
-        checkStatus();
-
         return perform(new SessionOperation<Value>() {
             @Override
+            protected void checkPreconditions() throws RepositoryException {
+                checkStatus();
+            }
+
+            @Override
             public Value perform() throws RepositoryException {
                 return dlg.getValue();
             }
@@ -364,10 +373,13 @@ public class PropertyImpl extends ItemIm
     @Override
     @Nonnull
     public Value[] getValues() throws RepositoryException {
-        checkStatus();
-
         return perform(new SessionOperation<List<Value>>() {
             @Override
+            protected void checkPreconditions() throws RepositoryException {
+                checkStatus();
+            }
+
+            @Override
             public List<Value> perform() throws RepositoryException {
                 return dlg.getValues();
             }
@@ -574,10 +586,13 @@ public class PropertyImpl extends ItemIm
 
     @Override
     public boolean isMultiple() throws RepositoryException {
-        checkStatus();
-
         return perform(new SessionOperation<Boolean>() {
             @Override
+            protected void checkPreconditions() throws RepositoryException {
+                checkStatus();
+            }
+
+            @Override
             public Boolean perform() throws RepositoryException {
                 return dlg.isMultivalue();
             }

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=1454622&r1=1454621&r2=1454622&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 Fri Mar  8 23:19:00 2013
@@ -132,10 +132,13 @@ public class SessionImpl extends Abstrac
     @Override
     @Nonnull
     public Node getRootNode() throws RepositoryException {
-        ensureIsAlive();
-
         return dlg.perform(new SessionOperation<NodeImpl<?>>() {
             @Override
+            protected void checkPreconditions() throws RepositoryException {
+                ensureIsAlive();
+            }
+
+            @Override
             public NodeImpl<?> perform() throws AccessDeniedException {
                 NodeDelegate nd = dlg.getRootNode();
                 if (nd == null) {
@@ -156,10 +159,13 @@ public class SessionImpl extends Abstrac
     @Override
     @Nonnull
     public Node getNodeByIdentifier(final String id) throws RepositoryException {
-        ensureIsAlive();
-
         return dlg.perform(new SessionOperation<NodeImpl<?>>() {
             @Override
+            protected void checkPreconditions() throws RepositoryException {
+                ensureIsAlive();
+            }
+
+            @Override
             public NodeImpl<?> perform() throws RepositoryException {
                 NodeDelegate d = dlg.getNodeByIdentifier(id);
                 if (d == null) {
@@ -186,10 +192,13 @@ public class SessionImpl extends Abstrac
 
     @Override
     public Node getNode(final String absPath) throws RepositoryException {
-        ensureIsAlive();
-
         return dlg.perform(new SessionOperation<NodeImpl<?>>() {
             @Override
+            protected void checkPreconditions() throws RepositoryException {
+                ensureIsAlive();
+            }
+
+            @Override
             public NodeImpl<?> perform() throws RepositoryException {
                 String oakPath = dlg.getOakPath(absPath);
                 NodeDelegate d = dlg.getNode(oakPath);
@@ -203,10 +212,13 @@ public class SessionImpl extends Abstrac
 
     @Override
     public boolean nodeExists(final String absPath) throws RepositoryException {
-        ensureIsAlive();
-
         return dlg.perform(new SessionOperation<Boolean>() {
             @Override
+            protected void checkPreconditions() throws RepositoryException {
+                ensureIsAlive();
+            }
+
+            @Override
             public Boolean perform() throws RepositoryException {
                 String oakPath = dlg.getOakPath(absPath);
                 return dlg.getNode(oakPath) != null;
@@ -252,10 +264,13 @@ public class SessionImpl extends Abstrac
 
     @Override
     public void move(final String srcAbsPath, final String destAbsPath) throws RepositoryException {
-        ensureIsAlive();
-
         dlg.perform(new SessionOperation<Void>() {
             @Override
+            protected void checkPreconditions() throws RepositoryException {
+                ensureIsAlive();
+            }
+
+            @Override
             public Void perform() throws RepositoryException {
                 dlg.checkProtectedNodes(Text.getRelativeParent(srcAbsPath, 1), Text.getRelativeParent(destAbsPath, 1));
                 String oakPath = dlg.getOakPathKeepIndexOrThrowNotFound(destAbsPath);

Modified: jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/SessionDelegate.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/SessionDelegate.java?rev=1454622&r1=1454621&r2=1454622&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/SessionDelegate.java (original)
+++ jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/SessionDelegate.java Fri Mar  8 23:19:00 2013
@@ -96,6 +96,23 @@ public class SessionDelegate {
     private int sessionOpCount;
     private int revision;
 
+    private abstract class SessionReadOperation<T> extends SessionOperation<T> {
+        @Override
+        protected void checkPreconditions() throws RepositoryException {
+            checkAlive();
+        }
+    }
+
+    private abstract class SessionWriteOperation<T> extends SessionReadOperation<T> {
+        @Override
+        protected void checkPreconditions() throws RepositoryException {
+            super.checkPreconditions();
+            if (isReadOnly()) {
+                throw new RepositoryException("This session is read only");
+            }
+        }
+    }
+
     public SessionDelegate(@Nonnull Repository repository, @Nonnull ScheduledExecutorService executor,
                     @Nonnull ContentSession contentSession, @Nonnull SecurityProvider securityProvider,
                     boolean autoRefresh) {
@@ -123,6 +140,14 @@ public class SessionDelegate {
         this.valueFactory = new ValueFactoryImpl(root.getBlobFactory(), namePathMapper);
     }
 
+    private boolean needsRefresh() {
+        // Refresh is always needed if this is an auto refresh session. Otherwise
+        // refresh in only needed for non re-entrant session operations and only if
+        // observation events have actually been delivered
+        return autoRefresh ||
+                (sessionOpCount <= 1 && observationManager != null && observationManager.hasEvents());
+    }
+
     /**
      * Performs the passed {@code SessionOperation} in a safe execution context. This
      * context ensures that the session is refreshed if necessary and that refreshing
@@ -136,23 +161,41 @@ public class SessionDelegate {
      */
     public synchronized <T> T perform(SessionOperation<T> sessionOperation) throws RepositoryException {
         // Synchronize to avoid conflicting refreshes from concurrent JCR API calls
-        sessionOpCount++;
         try {
             if (needsRefresh()) {
                 refresh(true);
             }
+
+            sessionOpCount++;
+            sessionOperation.checkPreconditions();
             return sessionOperation.perform();
         } finally {
             sessionOpCount--;
         }
     }
 
-    private boolean needsRefresh() {
-        // Refresh is always needed if this is an auto refresh session. Otherwise
-        // refresh in only needed for non re-entrant session operations and only if
-        // observation events have actually been delivered
-        return autoRefresh ||
-                (sessionOpCount <= 1 && observationManager != null && observationManager.hasEvents());
+    public <T> T safePerform(SessionOperation<T> sessionOperation) {
+        try {
+            return perform(sessionOperation);
+        } catch (RepositoryException e) {
+            String msg = sessionOperation + "threw an unexpected exception";
+            log.error(msg, e);
+            throw new IllegalArgumentException(msg, e);
+        }
+    }
+
+    public boolean isAlive() {
+        return isAlive;
+    }
+
+    public void checkAlive() throws RepositoryException {
+        if (!isAlive()) {
+            throw new RepositoryException("This session has been closed.");
+        }
+    }
+
+    public boolean isReadOnly() {
+        return false;
     }
 
     /**
@@ -165,10 +208,6 @@ public class SessionDelegate {
         return revision;
     }
 
-    public boolean isAlive() {
-        return isAlive;
-    }
-
     @Nonnull
     public Session getSession() {
         return session;

Modified: jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/SessionOperation.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/SessionOperation.java?rev=1454622&r1=1454621&r2=1454622&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/SessionOperation.java (original)
+++ jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/SessionOperation.java Fri Mar  8 23:19:00 2013
@@ -23,6 +23,7 @@ import javax.jcr.RepositoryException;
 /**
  * A {@code SessionOperation} provides an execution context for executing session scoped operations.
  */
-public interface SessionOperation<T> {
-    T perform() throws RepositoryException;
+public abstract class SessionOperation<T> {
+    protected void checkPreconditions() throws RepositoryException {}
+    protected abstract T perform() throws RepositoryException;
 }