You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by ju...@apache.org on 2009/08/12 16:36:51 UTC

svn commit: r803535 - in /jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock: LockImpl.java LockInfo.java LockManagerImpl.java LockToken.java XAEnvironment.java

Author: jukka
Date: Wed Aug 12 14:36:51 2009
New Revision: 803535

URL: http://svn.apache.org/viewvc?rev=803535&view=rev
Log:
JCR-1590: JSR 283: Locking

More code cleanup: Inline LockToken into LockInfo and make LockInfo member variables private.

Removed:
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/LockToken.java
Modified:
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/LockImpl.java
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/LockInfo.java
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/LockManagerImpl.java
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/XAEnvironment.java

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/LockImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/LockImpl.java?rev=803535&r1=803534&r2=803535&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/LockImpl.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/LockImpl.java Wed Aug 12 14:36:51 2009
@@ -79,7 +79,7 @@
      */
     public String getLockToken() {
         if (!info.isSessionScoped() && info.isLockHolder(node.getSession())) {
-            return info.getLockToken().toString();
+            return info.getLockToken();
         } else {
             return null;
         }

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/LockInfo.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/LockInfo.java?rev=803535&r1=803534&r2=803535&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/LockInfo.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/LockInfo.java Wed Aug 12 14:36:51 2009
@@ -37,24 +37,24 @@
     static final long TIMEOUT_EXPIRED = -1;
 
     /**
-     * Lock token
+     * Lock holder node id. Used also as the lock token.
      */
-    protected final LockToken lockToken;
+    private final NodeId id;
 
     /**
      * Flag indicating whether lock is session scoped
      */
-    protected final boolean sessionScoped;
+    private final boolean sessionScoped;
 
     /**
      * Flag indicating whether lock is deep
      */
-    protected final boolean deep;
+    private final boolean deep;
 
     /**
      * Lock owner, determined on creation time
      */
-    protected final String lockOwner;
+    private final String lockOwner;
 
     /**
      * Flag indicating whether this lock is live
@@ -69,28 +69,16 @@
     /**
      * Create a new instance of this class.
      *
-     * @param lockToken     lock token
-     * @param sessionScoped whether lock token is session scoped
-     * @param deep          whether lock is deep
-     * @param lockOwner     owner of lock
-     */
-    protected LockInfo(LockToken lockToken, boolean sessionScoped, boolean deep,
-                    String lockOwner) {
-        this(lockToken, sessionScoped, deep, lockOwner, TIMEOUT_INFINITE);
-    }
-
-    /**
-     * Create a new instance of this class.
-     *
-     * @param lockToken     lock token
+     * @param id            lock holder node id
      * @param sessionScoped whether lock token is session scoped
      * @param deep          whether lock is deep
      * @param lockOwner     owner of lock
      * @param timeoutHint   the timeoutHint
      */
-    protected LockInfo(LockToken lockToken, boolean sessionScoped, boolean deep,
-                            String lockOwner, long timeoutHint) {
-        this.lockToken = lockToken;
+    protected LockInfo(
+            NodeId id, boolean sessionScoped, boolean deep,
+            String lockOwner, long timeoutHint) {
+        this.id = id;
         this.sessionScoped = sessionScoped;
         this.deep = deep;
         this.lockOwner = lockOwner;
@@ -102,8 +90,9 @@
      *
      * @return lock token
      */
-    public LockToken getLockToken() {
-        return lockToken;
+    public String getLockToken() {
+        String uuid = id.toString();
+        return uuid + "-" + getLockTokenCheckDigit(uuid);
     }
 
     /**
@@ -111,7 +100,7 @@
      * @return the id
      */
     public NodeId getId() {
-        return lockToken.getId();
+        return id;
     }
 
     /**
@@ -231,4 +220,64 @@
         return buffer.toString();
     }
 
+    /**
+     * Parse a lock token string representation and return the lock
+     * holder node id.
+     *
+     * @param token string representation of lock token
+     * @return lock holder node id
+     * @throws IllegalArgumentException if some field is illegal
+     */
+    public static NodeId parseLockToken(String token)
+            throws IllegalArgumentException {
+        int sep = token.lastIndexOf('-');
+        if (sep == -1 || sep == token.length() - 1) {
+            throw new IllegalArgumentException("Separator not found.");
+        }
+        String uuid = token.substring(0, sep);
+        if (getLockTokenCheckDigit(uuid) != token.charAt(token.length() - 1)) {
+            throw new IllegalArgumentException("Bad check digit.");
+        }
+        return NodeId.valueOf(uuid);
+    }
+
+    /**
+     * Return the check digit for a lock token, given by its UUID
+     * @param uuid uuid
+     * @return check digit
+     */
+    private static char getLockTokenCheckDigit(String uuid) {
+        int result = 0;
+
+        int multiplier = 36;
+        for (int i = 0; i < uuid.length(); i++) {
+            char c = uuid.charAt(i);
+            if (c >= '0' && c <= '9') {
+                int num = c - '0';
+                result += multiplier * num;
+                multiplier--;
+            } else if (c >= 'A' && c <= 'F') {
+                int num = c - 'A' + 10;
+                result += multiplier * num;
+                multiplier--;
+            } else if (c >= 'a' && c <= 'f') {
+                int num = c - 'a' + 10;
+                result += multiplier * num;
+                multiplier--;
+            }
+        }
+
+        int rem = result % 37;
+        if (rem != 0) {
+            rem = 37 - rem;
+        }
+        if (rem >= 0 && rem <= 9) {
+            return (char) ('0' + rem);
+        } else if (rem >= 10 && rem <= 35) {
+            return (char) ('A' + rem - 10);
+        } else {
+            return '+';
+        }
+    }
+
 }

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/LockManagerImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/LockManagerImpl.java?rev=803535&r1=803534&r2=803535&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/LockManagerImpl.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/LockManagerImpl.java Wed Aug 12 14:36:51 2009
@@ -201,7 +201,7 @@
                 if (s == null || s.equals("")) {
                     break;
                 }
-                reapplyLock(LockToken.parse(s));
+                reapplyLock(s);
             }
         } catch (IOException e) {
             throw new FileSystemException("error while reading locks file", e);
@@ -215,13 +215,14 @@
      *
      * @param lockToken lock token to apply
      */
-    private void reapplyLock(LockToken lockToken) {
+    private void reapplyLock(String lockToken) {
         try {
-            NodeImpl node = (NodeImpl)
-                sysSession.getItemManager().getItem(lockToken.getId());
-            Path path = getPath(sysSession, lockToken.getId());
+            NodeId id = LockInfo.parseLockToken(lockToken);
+            NodeImpl node = (NodeImpl) sysSession.getItemManager().getItem(id);
+            Path path = getPath(sysSession, id);
 
-            InternalLockInfo info = new InternalLockInfo(lockToken, false,
+            InternalLockInfo info = new InternalLockInfo(
+                    id, false,
                     node.getProperty(NameConstants.JCR_LOCKISDEEP).getBoolean(),
                     node.getProperty(NameConstants.JCR_LOCKOWNER).getString());
             info.setLive(true);
@@ -259,7 +260,7 @@
             writer = new BufferedWriter(
                     new OutputStreamWriter(locksFile.getOutputStream()));
             for (LockInfo info : list) {
-                writer.write(info.getLockToken().toString());
+                writer.write(info.getLockToken());
                 writer.newLine();
             }
         } catch (FileSystemException fse) {
@@ -300,8 +301,8 @@
 
         SessionImpl session = (SessionImpl) node.getSession();
         String lockOwner = (ownerInfo != null) ? ownerInfo : session.getUserID();
-        InternalLockInfo info = new InternalLockInfo(new LockToken(node.getNodeId()),
-                isSessionScoped, isDeep, lockOwner, timeoutHint);
+        InternalLockInfo info = new InternalLockInfo(
+                node.getNodeId(), isSessionScoped, isDeep, lockOwner, timeoutHint);
 
         ClusterOperation operation = null;
         boolean successful = false;
@@ -327,7 +328,7 @@
                             "Parent node has a deep lock: " + node);
                 }
             }
-            if (info.deep && element.hasPath(path)
+            if (info.isDeep() && element.hasPath(path)
                     && element.getChildrenCount() > 0) {
                 throw new LockException("Some child node is locked.");
             }
@@ -337,8 +338,7 @@
             info.setLive(true);
             session.addListener(info);
             if (!info.isSessionScoped()) {
-                getSessionLockManager(session).lockTokenAdded(
-                        info.getLockToken().toString());
+                getSessionLockManager(session).lockTokenAdded(info.getLockToken());
             }
             lockMap.put(path, info);
 
@@ -388,8 +388,7 @@
             }
             checkUnlock(info, session);
 
-            getSessionLockManager(session).lockTokenRemoved(
-                    info.getLockToken().toString());
+            getSessionLockManager(session).lockTokenRemoved(info.getLockToken());
 
             element.set(null);
             info.setLive(false);
@@ -470,7 +469,7 @@
     public Lock lock(NodeImpl node, boolean isDeep, boolean isSessionScoped, long timoutHint, String ownerInfo)
             throws LockException, RepositoryException {
         LockInfo info = internalLock(node, isDeep, isSessionScoped, timoutHint, ownerInfo);
-        writeLockProperties(node, info.lockOwner, info.deep);
+        writeLockProperties(node, info.getLockOwner(), info.isDeep());
 
         return new LockImpl(info, node);
     }
@@ -675,10 +674,9 @@
      */
     public void addLockToken(SessionImpl session, String lt) throws LockException, RepositoryException {
         try {
-            LockToken lockToken = LockToken.parse(lt);
+            NodeId id = LockInfo.parseLockToken(lt);
 
-            NodeImpl node = (NodeImpl)
-                this.sysSession.getItemManager().getItem(lockToken.getId());
+            NodeImpl node = (NodeImpl) sysSession.getItemManager().getItem(id);
             PathMap.Element<LockInfo> element =
                 lockMap.map(node.getPrimaryPath(), true);
             if (element != null) {
@@ -714,10 +712,9 @@
             throws LockException, RepositoryException {
 
         try {
-            LockToken lockToken = LockToken.parse(lt);
+            NodeId id = LockInfo.parseLockToken(lt);
 
-            NodeImpl node = (NodeImpl) this.sysSession.getItemManager()
-                    .getItem(lockToken.getId());
+            NodeImpl node = (NodeImpl) sysSession.getItemManager().getItem(id);
             PathMap.Element<LockInfo> element =
                 lockMap.map(node.getPrimaryPath(), true);
             if (element != null) {
@@ -1174,7 +1171,7 @@
          * @param deep          whether lock is deep
          * @param lockOwner     owner of lock
          */
-        public InternalLockInfo(LockToken lockToken, boolean sessionScoped,
+        public InternalLockInfo(NodeId lockToken, boolean sessionScoped,
                                 boolean deep, String lockOwner) {
             this(lockToken, sessionScoped, deep, lockOwner, TIMEOUT_INFINITE);
         }
@@ -1188,7 +1185,7 @@
          * @param lockOwner     owner of lock
          * @param timeoutHint
          */
-        public InternalLockInfo(LockToken lockToken, boolean sessionScoped,
+        public InternalLockInfo(NodeId lockToken, boolean sessionScoped,
                                 boolean deep, String lockOwner, long timeoutHint) {
             super(lockToken, sessionScoped, deep, lockOwner, timeoutHint);
         }
@@ -1229,7 +1226,7 @@
                         }
                     }
                 } else if (isLockHolder(session)) {
-                    session.removeLockToken(getLockToken().toString());
+                    session.removeLockToken(getLockToken());
                     setLockHolder(null);
                 }
             }
@@ -1264,7 +1261,7 @@
             Path path = getPath(sysSession, nodeId);
 
             // create lock token
-            InternalLockInfo info = new InternalLockInfo(new LockToken(nodeId), false, isDeep, lockOwner);
+            InternalLockInfo info = new InternalLockInfo(nodeId, false, isDeep, lockOwner);
             info.setLive(true);
             lockMap.put(path, info);
 

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/XAEnvironment.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/XAEnvironment.java?rev=803535&r1=803534&r2=803535&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/XAEnvironment.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/XAEnvironment.java Wed Aug 12 14:36:51 2009
@@ -134,7 +134,7 @@
         XALockInfo info = unlockedNodesMap.get(id);
         if (info != null) {
             // if settings are compatible, this is effectively a no-op
-            if (info.deep == isDeep && info.sessionScoped == isSessionScoped) {
+            if (info.isDeep() == isDeep && info.isSessionScoped() == isSessionScoped) {
                 unlockedNodesMap.remove(id);
                 operations.remove(info);
                 return lockMgr.getLockInfo(id);
@@ -148,12 +148,12 @@
 
         // create a new lock info for this node
         String lockOwner = (ownerInfo != null) ? ownerInfo : node.getSession().getUserID();
-        info = new XALockInfo(node, new LockToken(id), isSessionScoped, isDeep, lockOwner);
+        info = new XALockInfo(node, isSessionScoped, isDeep, lockOwner);
         SessionImpl session = (SessionImpl) node.getSession();
         info.setLockHolder(session);
         info.setLive(true);
 
-        LockManagerImpl.getSessionLockManager(session).lockTokenAdded(info.lockToken.toString());
+        LockManagerImpl.getSessionLockManager(session).lockTokenAdded(info.getLockToken());
         lockedNodesMap.put(id, info);
         operations.add(info);
 
@@ -221,7 +221,7 @@
             for (;;) {
                 XALockInfo info = lockedNodesMap.get(current.getId());
                 if (info != null) {
-                    if (info.getId().equals(id) || info.deep) {
+                    if (info.getId().equals(id) || info.isDeep()) {
                         return info;
                     }
                     break;
@@ -268,8 +268,8 @@
      */
     public void addLockToken(SessionImpl session, String lt) throws RepositoryException {
         try {
-            LockToken lockToken = LockToken.parse(lt);
-            NodeImpl node = (NodeImpl) session.getItemManager().getItem(lockToken.getId());
+            NodeId id = LockInfo.parseLockToken(lt);
+            NodeImpl node = (NodeImpl) session.getItemManager().getItem(id);
             LockInfo info = getLockInfo(node);
             if (info != null) {
                 if (info.isLockHolder(session)) {
@@ -299,9 +299,9 @@
      */
     public void removeLockToken(SessionImpl session, String lt) throws RepositoryException {
         try {
-            LockToken lockToken = LockToken.parse(lt);
+            NodeId id = LockInfo.parseLockToken(lt);
 
-            NodeImpl node = (NodeImpl) session.getItemManager().getItem(lockToken.getId());
+            NodeImpl node = (NodeImpl) session.getItemManager().getItem(id);
             LockInfo info = getLockInfo(node);
             if (info != null) {
                 if (info.isLockHolder(session)) {
@@ -437,30 +437,14 @@
 
         /**
          * Create a new instance of this class.
-         * @param lockToken     lock token
          * @param sessionScoped whether lock token is session scoped
          * @param deep          whether lock is deep
          * @param lockOwner     owner of lock
          */
-        public XALockInfo(NodeImpl node, LockToken lockToken,
-                          boolean sessionScoped, boolean deep, String lockOwner) {
-
-            this(node, lockToken, sessionScoped, deep, lockOwner,
-                    TIMEOUT_INFINITE);
-        }
-
-        /**
-         * Create a new instance of this class.
-         * @param lockToken     lock token
-         * @param sessionScoped whether lock token is session scoped
-         * @param deep          whether lock is deep
-         * @param lockOwner     owner of lock
-         */
-        public XALockInfo(NodeImpl node, LockToken lockToken,
-                          boolean sessionScoped, boolean deep, String lockOwner,
-                          long timeoutHint) {
-
-            super(lockToken, sessionScoped, deep, lockOwner, timeoutHint);
+        public XALockInfo(
+                NodeImpl node,
+                boolean sessionScoped, boolean deep, String lockOwner) {
+            super(node.getNodeId(), sessionScoped, deep, lockOwner, TIMEOUT_INFINITE);
             this.node = node;
         }
 
@@ -469,7 +453,7 @@
          * unlock operation on some existing lock information.
          */
         public XALockInfo(NodeImpl node, LockInfo info) {
-            super(info.getLockToken(), info.isSessionScoped(), info.isDeep(),
+            super(info.getId(), info.isSessionScoped(), info.isDeep(),
                     info.getLockOwner(), info.getSecondsRemaining());
 
             this.node = node;
@@ -492,7 +476,9 @@
             if (isUnlock) {
                 lockMgr.internalUnlock(node);
             } else {
-                LockInfo internalLock = lockMgr.internalLock(node, deep, sessionScoped, getSecondsRemaining(), lockOwner);
+                LockInfo internalLock = lockMgr.internalLock(
+                        node, isDeep(), isSessionScoped(),
+                        getSecondsRemaining(), getLockOwner());
                 LockInfo xaEnvLock = getLockInfo(node);
                 // Check if the lockToken has been removed in the transaction ...
                 if (xaEnvLock != null && xaEnvLock.getLockHolder() == null) {
@@ -506,7 +492,9 @@
          */
         public void undo() throws LockException, RepositoryException {
             if (isUnlock) {
-                lockMgr.internalLock(node, deep, sessionScoped, getSecondsRemaining(), lockOwner);
+                lockMgr.internalLock(
+                        node, isDeep(), isSessionScoped(),
+                        getSecondsRemaining(), getLockOwner());
             } else {
                 lockMgr.internalUnlock(node);
             }