Author: jukka
Date: Tue Aug 13 09:46:29 2013
New Revision: 1513411
URL: http://svn.apache.org/r1513411
Log:
OAK-150: Basic JCR LockManager support
Move locking operations to the delegate level. Improve LockImpl
Modified:
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/delegate/NodeDelegate.java
jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/lock/LockImpl.java
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=1513411&r1=1513410&r2=1513411&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
Tue Aug 13 09:46:29 2013
@@ -75,12 +75,12 @@ import org.apache.jackrabbit.oak.jcr.del
import org.apache.jackrabbit.oak.jcr.delegate.VersionManagerDelegate;
import org.apache.jackrabbit.oak.jcr.lock.LockImpl;
import org.apache.jackrabbit.oak.jcr.operation.NodeOperation;
+import org.apache.jackrabbit.oak.jcr.operation.SessionOperation;
import org.apache.jackrabbit.oak.jcr.version.VersionHistoryImpl;
import org.apache.jackrabbit.oak.jcr.version.VersionImpl;
import org.apache.jackrabbit.oak.plugins.memory.PropertyStates;
import org.apache.jackrabbit.oak.plugins.nodetype.EffectiveNodeType;
import
org.apache.jackrabbit.oak.spi.security.authorization.permission.Permissions;
-import org.apache.jackrabbit.oak.util.TODO;
import org.apache.jackrabbit.value.ValueHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -90,6 +90,8 @@ import static java.util.Arrays.asList;
import static java.util.Collections.singleton;
import static javax.jcr.Property.JCR_LOCK_IS_DEEP;
import static javax.jcr.Property.JCR_LOCK_OWNER;
+import static org.apache.jackrabbit.JcrConstants.JCR_LOCKISDEEP;
+import static org.apache.jackrabbit.JcrConstants.JCR_LOCKOWNER;
import static org.apache.jackrabbit.JcrConstants.JCR_MIXINTYPES;
import static org.apache.jackrabbit.JcrConstants.JCR_PRIMARYTYPE;
import static org.apache.jackrabbit.JcrConstants.MIX_LOCKABLE;
@@ -1159,38 +1161,34 @@ public class NodeImpl<T extends NodeDele
/**
* @see javax.jcr.Node#lock(boolean, boolean)
*/
- @Override
- @Nonnull
+ @Override @Nonnull
public Lock lock(final boolean isDeep, boolean isSessionScoped)
throws RepositoryException {
- checkLockable();
- // TODO: use perform()
- ContentSession session = sessionDelegate.getContentSession();
- final String userID = session.getAuthInfo().getUserID();
-
- String lockOwner = getOakPathOrThrow(JCR_LOCK_OWNER);
- String lockIsDeep = getOakPathOrThrow(JCR_LOCK_IS_DEEP);
- try {
- Root root = session.getLatestRoot();
- Tree tree = root.getTree(dlg.getPath());
- if (!tree.exists()) {
- throw new ItemNotFoundException();
+ checkLockable(); // TODO: use perform()
+ perform(new SessionOperation<Void>(true) {
+ @Override
+ public Void perform() throws RepositoryException {
+ ContentSession session = sessionDelegate.getContentSession();
+ String path = dlg.getPath();
+ String userID = session.getAuthInfo().getUserID();
+
+ try {
+ Root root = session.getLatestRoot();
+ Tree tree = root.getTree(path);
+ if (!tree.exists()) {
+ throw new ItemNotFoundException();
+ }
+ tree.setProperty(JCR_LOCKOWNER, userID);
+ tree.setProperty(JCR_LOCKISDEEP, isDeep);
+ root.commit(); // TODO: fail instead?
+ } catch (CommitFailedException e) {
+ throw new RepositoryException("Unable to lock " + path, e);
+ }
+ return null;
}
- tree.setProperty(lockOwner, userID);
- tree.setProperty(lockIsDeep, isDeep);
- root.commit(); // TODO: fail instead?
- } catch (CommitFailedException e) {
- throw new RepositoryException("Unable to lock " + this, e);
- }
-
+ });
getSession().refresh(true);
-
- if (isSessionScoped) {
- return TODO.dummyImplementation().returnValue(
- new LockImpl(this, userID, isDeep));
- }
-
- return getLock();
+ return new LockImpl(sessionContext, dlg);
}
/**
Modified:
jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/NodeDelegate.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/NodeDelegate.java?rev=1513411&r1=1513410&r2=1513411&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/NodeDelegate.java
(original)
+++
jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/NodeDelegate.java
Tue Aug 13 09:46:29 2013
@@ -693,6 +693,16 @@ public class NodeDelegate extends ItemDe
return false;
}
+ public String getLockOwner() {
+ PropertyState property = tree.getProperty(JCR_LOCKOWNER);
+ if (property != null && property.getType() == Type.STRING) {
+ return property.getValue(Type.STRING);
+ } else {
+ return null;
+ }
+ }
+
+
@Override
public String toString() {
Modified:
jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/lock/LockImpl.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/lock/LockImpl.java?rev=1513411&r1=1513410&r2=1513411&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/lock/LockImpl.java
(original)
+++
jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/lock/LockImpl.java
Tue Aug 13 09:46:29 2013
@@ -17,39 +17,80 @@
package org.apache.jackrabbit.oak.jcr.lock;
import static com.google.common.base.Preconditions.checkNotNull;
+import static org.apache.jackrabbit.JcrConstants.JCR_LOCKISDEEP;
+import javax.annotation.CheckForNull;
+import javax.annotation.Nonnull;
import javax.jcr.Node;
+import javax.jcr.RepositoryException;
import javax.jcr.lock.Lock;
-public final class LockImpl implements Lock {
+import org.apache.jackrabbit.oak.api.PropertyState;
+import org.apache.jackrabbit.oak.api.Tree;
+import org.apache.jackrabbit.oak.api.Type;
+import org.apache.jackrabbit.oak.jcr.NodeImpl;
+import org.apache.jackrabbit.oak.jcr.SessionContext;
+import org.apache.jackrabbit.oak.jcr.delegate.NodeDelegate;
+import org.apache.jackrabbit.oak.jcr.operation.SessionOperation;
- private final Node node;
+public final class LockImpl implements Lock {
- private final String userID;
+ private final SessionContext context;
- private final boolean isDeep;
+ private final NodeDelegate delegate;
- public LockImpl(Node node, String userID, boolean isDeep) {
- this.node = checkNotNull(node);
- this.userID = userID;
- this.isDeep = isDeep;
+ public LockImpl(
+ @Nonnull SessionContext context, @Nonnull NodeDelegate delegate) {
+ this.context = checkNotNull(context);
+ this.delegate = checkNotNull(delegate);
}
@Override
public Node getNode() {
- return node;
+ try {
+ return NodeImpl.createNode(delegate, context);
+ } catch (RepositoryException e) {
+ throw new RuntimeException("Unable to access the lock node", e);
+ }
}
@Override
public String getLockOwner() {
- return userID;
+ return safePerform(new SessionOperation<String>() {
+ @Override
+ public String perform() throws RepositoryException {
+ return delegate.getLockOwner();
+ }
+ });
}
@Override
public boolean isDeep() {
- return isDeep;
+ return safePerform(new SessionOperation<Boolean>() {
+ @Override
+ public Boolean perform() throws RepositoryException {
+ Tree tree = delegate.getTree();
+ PropertyState property = tree.getProperty(JCR_LOCKISDEEP);
+ if (property != null && property.getType() == Type.BOOLEAN) {
+ return property.getValue(Type.BOOLEAN);
+ } else {
+ return false;
+ }
+ }
+ });
+ }
+
+ @Override
+ public boolean isLive() {
+ return safePerform(new SessionOperation<Boolean>() {
+ @Override
+ public Boolean perform() throws RepositoryException {
+ return delegate.getTree().hasProperty(JCR_LOCKISDEEP);
+ }
+ });
}
+
@Override
public String getLockToken() {
return null;
@@ -61,11 +102,6 @@ public final class LockImpl implements L
}
@Override
- public boolean isLive() {
- return true;
- }
-
- @Override
public boolean isSessionScoped() {
return true;
}
@@ -79,4 +115,25 @@ public final class LockImpl implements L
public void refresh() {
}
+ //-----------------------------------------------------------< private >--
+
+ /**
+ * Perform the passed {@link SessionOperation} assuming it does not
+ * throw a {@code RepositoryException}. If it does, wrap it into and
+ * throw it as a {@code RuntimeException}.
+ *
+ * @param op operation to perform
+ * @param <U> return type of the operation
+ * @return the result of {@code op.perform()}
+ */
+ @CheckForNull
+ private final <U> U safePerform(@Nonnull SessionOperation<U> op) {
+ try {
+ return context.getSessionDelegate().perform(op);
+ } catch (RepositoryException e) {
+ throw new RuntimeException(
+ "Unexpected exception thrown by operation " + op, e);
+ }
+ }
+
}