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);
}