From commits-return-10175-apmail-jackrabbit-commits-archive=jackrabbit.apache.org@jackrabbit.apache.org Tue Aug 10 11:07:10 2010 Return-Path: Delivered-To: apmail-jackrabbit-commits-archive@www.apache.org Received: (qmail 29454 invoked from network); 10 Aug 2010 11:07:10 -0000 Received: from unknown (HELO mail.apache.org) (140.211.11.3) by 140.211.11.9 with SMTP; 10 Aug 2010 11:07:10 -0000 Received: (qmail 51640 invoked by uid 500); 10 Aug 2010 11:07:10 -0000 Delivered-To: apmail-jackrabbit-commits-archive@jackrabbit.apache.org Received: (qmail 51531 invoked by uid 500); 10 Aug 2010 11:07:08 -0000 Mailing-List: contact commits-help@jackrabbit.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@jackrabbit.apache.org Delivered-To: mailing list commits@jackrabbit.apache.org Received: (qmail 51514 invoked by uid 99); 10 Aug 2010 11:07:07 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 10 Aug 2010 11:07:07 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=10.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 10 Aug 2010 11:07:05 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id 9236E238890B; Tue, 10 Aug 2010 11:05:48 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r983926 - in /jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core: VersionManagerImpl.java WorkspaceImpl.java Date: Tue, 10 Aug 2010 11:05:48 -0000 To: commits@jackrabbit.apache.org From: jukka@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20100810110548.9236E238890B@eris.apache.org> Author: jukka Date: Tue Aug 10 11:05:48 2010 New Revision: 983926 URL: http://svn.apache.org/viewvc?rev=983926&view=rev Log: JCR-890: concurrent read-only access to a session Turn many versioning operations into SessionOperations Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/VersionManagerImpl.java jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/WorkspaceImpl.java Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/VersionManagerImpl.java URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/VersionManagerImpl.java?rev=983926&r1=983925&r2=983926&view=diff ============================================================================== --- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/VersionManagerImpl.java (original) +++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/VersionManagerImpl.java Tue Aug 10 11:05:48 2010 @@ -16,6 +16,11 @@ */ package org.apache.jackrabbit.core; +import static org.apache.jackrabbit.core.ItemValidator.CHECK_HOLD; +import static org.apache.jackrabbit.core.ItemValidator.CHECK_LOCK; +import static org.apache.jackrabbit.core.ItemValidator.CHECK_PENDING_CHANGES; +import static org.apache.jackrabbit.core.ItemValidator.CHECK_PENDING_CHANGES_ON_NODE; + import java.util.ArrayList; import java.util.Calendar; import java.util.HashMap; @@ -37,6 +42,8 @@ import javax.jcr.version.VersionManager; import org.apache.jackrabbit.core.id.ItemId; import org.apache.jackrabbit.core.id.NodeId; import org.apache.jackrabbit.core.security.authorization.Permission; +import org.apache.jackrabbit.core.session.SessionContext; +import org.apache.jackrabbit.core.session.SessionOperation; import org.apache.jackrabbit.core.state.ItemStateException; import org.apache.jackrabbit.core.state.NodeState; import org.apache.jackrabbit.core.state.UpdatableItemStateManager; @@ -70,20 +77,30 @@ public class VersionManagerImpl extends private static final Logger log = LoggerFactory.getLogger(VersionManagerImpl.class); /** - * Creates a new version manager for the given session - * @param session workspace sesion + * Component context of the current session + */ + private final SessionContext sessionContext; + + /** + * Creates a new version manager + * + * @param sessionContext component context of the current session * @param stateMgr the underlying state manager * @param hierMgr local hierarchy manager */ - public VersionManagerImpl(SessionImpl session, - UpdatableItemStateManager stateMgr, - HierarchyManager hierMgr) { - super(session, stateMgr, hierMgr); + public VersionManagerImpl( + SessionContext sessionContext, UpdatableItemStateManager stateMgr, + HierarchyManager hierMgr) { + super(sessionContext.getSessionImpl(), stateMgr, hierMgr); + this.sessionContext = sessionContext; } - /** - * {@inheritDoc} - */ + private T perform(SessionOperation operation) + throws RepositoryException { + return sessionContext.getSessionState().perform(operation); + } + + /** Wrapper around {@link #checkin(String, Calendar)}. */ public Version checkin(String absPath) throws RepositoryException { return checkin(absPath, null); } @@ -97,40 +114,55 @@ public class VersionManagerImpl extends * @return new version * @throws RepositoryException if the version can not be created */ - public Version checkin(String absPath, Calendar created) + public Version checkin(final String absPath, final Calendar created) throws RepositoryException { - NodeStateEx state = getNodeState(absPath, - ItemValidator.CHECK_LOCK | ItemValidator.CHECK_HOLD - | ItemValidator.CHECK_PENDING_CHANGES_ON_NODE, - Permission.VERSION_MNGMT); - NodeId baseId = checkoutCheckin(state, true, false, created); - return (VersionImpl) session.getNodeById(baseId); + return perform(new SessionOperation () { + public Version perform(SessionContext context) + throws RepositoryException { + NodeStateEx state = getNodeState( + absPath, + CHECK_LOCK | CHECK_HOLD | CHECK_PENDING_CHANGES_ON_NODE, + Permission.VERSION_MNGMT); + NodeId baseId = checkoutCheckin(state, true, false, created); + return (Version) session.getNodeById(baseId); + } + }); } /** * {@inheritDoc} */ - public void checkout(String absPath) throws RepositoryException { - NodeStateEx state = getNodeState(absPath, - ItemValidator.CHECK_LOCK | ItemValidator.CHECK_HOLD, - Permission.VERSION_MNGMT); - checkoutCheckin(state, false, true, null); + public void checkout(final String absPath) throws RepositoryException { + perform(new SessionOperation () { + public NodeId perform(SessionContext context) + throws RepositoryException { + NodeStateEx state = getNodeState( + absPath, + CHECK_LOCK | CHECK_HOLD, + Permission.VERSION_MNGMT); + return checkoutCheckin(state, false, true, null); + } + }); } /** * {@inheritDoc} */ - public Version checkpoint(String absPath) throws RepositoryException { - NodeStateEx state = getNodeState(absPath, - ItemValidator.CHECK_LOCK | ItemValidator.CHECK_HOLD | ItemValidator.CHECK_PENDING_CHANGES_ON_NODE, - Permission.VERSION_MNGMT); - NodeId baseId = checkoutCheckin(state, true, true, null); - return (VersionImpl) session.getNodeById(baseId); + public Version checkpoint(final String absPath) throws RepositoryException { + return perform(new SessionOperation () { + public Version perform(SessionContext context) + throws RepositoryException { + NodeStateEx state = getNodeState( + absPath, + CHECK_LOCK | CHECK_HOLD | CHECK_PENDING_CHANGES_ON_NODE, + Permission.VERSION_MNGMT); + NodeId baseId = checkoutCheckin(state, true, true, null); + return (Version) session.getNodeById(baseId); + } + }); } - /** - * {@inheritDoc} - */ + /** Wrapper around {@link Node#isCheckedOut()}. */ public boolean isCheckedOut(String absPath) throws RepositoryException { return session.getNode(absPath).isCheckedOut(); } @@ -138,26 +170,34 @@ public class VersionManagerImpl extends /** * {@inheritDoc} */ - public VersionHistory getVersionHistory(String absPath) + public VersionHistory getVersionHistory(final String absPath) throws RepositoryException { - NodeStateEx state = getNodeState(absPath); - InternalVersionHistory vh = getVersionHistory(state); - return (VersionHistory) session.getNodeById(vh.getId()); + return perform(new SessionOperation () { + public VersionHistory perform(SessionContext context) + throws RepositoryException { + NodeStateEx state = getNodeState(absPath); + InternalVersionHistory vh = getVersionHistory(state); + return (VersionHistory) session.getNodeById(vh.getId()); + } + }); } /** * {@inheritDoc} */ - public Version getBaseVersion(String absPath) + public Version getBaseVersion(final String absPath) throws RepositoryException { - NodeStateEx state = getNodeState(absPath); - InternalVersion v = getBaseVersion(state); - return (Version) session.getNodeById(v.getId()); + return perform(new SessionOperation () { + public Version perform(SessionContext context) + throws RepositoryException { + NodeStateEx state = getNodeState(absPath); + InternalVersion v = getBaseVersion(state); + return (Version) session.getNodeById(v.getId()); + } + }); } - /** - * {@inheritDoc} - */ + /** Wrapper around {@link #restore(Version[], boolean)}. */ public void restore(Version version, boolean removeExisting) throws RepositoryException { restore(new Version[]{version}, removeExisting); @@ -166,80 +206,106 @@ public class VersionManagerImpl extends /** * {@inheritDoc} */ - public void restore(Version[] versions, boolean removeExisting) + public void restore(final Version[] versions, final boolean removeExisting) throws RepositoryException { - // check for pending changes - if (session.hasPendingChanges()) { - String msg = "Unable to restore version. Session has pending changes."; - log.error(msg); - throw new InvalidItemStateException(msg); - } - // add all versions to map of versions to restore - Map toRestore = new HashMap(); - for (Version version : versions) { - InternalVersion v = vMgr.getVersion(((VersionImpl) version).getNodeId()); - // check for collision - NodeId historyId = v.getVersionHistory().getId(); - if (toRestore.containsKey(historyId)) { - String msg = "Unable to restore. Two or more versions have same version history."; - log.error(msg); - throw new VersionException(msg); + perform(new SessionOperation () { + public Object perform(SessionContext context) + throws RepositoryException { + // check for pending changes + if (session.hasPendingChanges()) { + throw new InvalidItemStateException( + "Unable to restore version. Session has pending changes."); + } + + // add all versions to map of versions to restore + Map toRestore = + new HashMap(); + for (Version version : versions) { + InternalVersion v = + vMgr.getVersion(((VersionImpl) version).getNodeId()); + // check for collision + NodeId historyId = v.getVersionHistory().getId(); + if (toRestore.containsKey(historyId)) { + throw new VersionException( + "Unable to restore. Two or more versions have same version history."); + } + toRestore.put(historyId, v); + } + + WriteOperation ops = startWriteOperation(); + try { + internalRestore( + new VersionSet(toRestore, true), removeExisting); + ops.save(); + } catch (ItemStateException e) { + throw new RepositoryException(e); + } finally { + ops.close(); + } + + return this; } - toRestore.put(historyId, v); - } - WriteOperation ops = startWriteOperation(); - try { - internalRestore(new VersionSet(toRestore, true), removeExisting); - ops.save(); - } catch (ItemStateException e) { - throw new RepositoryException(e); - } finally { - ops.close(); - } + }); } /** * {@inheritDoc} */ - public void restore(String absPath, String versionName, boolean removeExisting) - throws RepositoryException { - NodeStateEx state = getNodeState(absPath, - ItemValidator.CHECK_PENDING_CHANGES | ItemValidator.CHECK_LOCK | ItemValidator.CHECK_HOLD, - Permission.NONE); - restore(state, session.getQName(versionName), removeExisting); + public void restore( + final String absPath, final String versionName, + final boolean removeExisting) throws RepositoryException { + perform(new SessionOperation () { + public Object perform(SessionContext context) + throws RepositoryException { + NodeStateEx state = getNodeState( + absPath, + CHECK_PENDING_CHANGES | CHECK_LOCK | CHECK_HOLD, + Permission.NONE); + restore(state, context.getQName(versionName), removeExisting); + return this; + } + }); } /** * {@inheritDoc} */ - public void restore(String absPath, Version version, boolean removeExisting) + public void restore( + final String absPath, final Version version, final boolean removeExisting) throws RepositoryException { - // first check if node exists - if (session.nodeExists(absPath)) { - String msg = "VersionManager.restore(String, Version, boolean) not " + - "allowed on existing nodes. " + - "use VersionManager.restore(Version, boolean) instead: " + absPath; - log.error(msg); - throw new VersionException(msg); - } else { - // parent has to exist - Path path = session.getQPath(absPath); - Path parentPath = path.getAncestor(1); - Name name = path.getNameElement().getName(); - NodeImpl parent = session.getItemManager().getNode(parentPath); - - NodeStateEx state = getNodeState(parent, - ItemValidator.CHECK_PENDING_CHANGES | ItemValidator.CHECK_LOCK | ItemValidator.CHECK_HOLD, - Permission.NONE); - - // check if given version is a baseline - InternalVersion v = getVersion(version); - if (v instanceof InternalBaseline) { - restore(state, name, (InternalBaseline) v); - } else { - restore(state, name, v, removeExisting); + perform(new SessionOperation () { + public Object perform(SessionContext context) + throws RepositoryException { + // first check if node exists + if (session.nodeExists(absPath)) { + throw new VersionException( + "VersionManager.restore(String, Version, boolean)" + + " not allowed on existing nodes; use" + + " VersionManager.restore(Version, boolean) instead: " + + absPath); + } else { + // parent has to exist + Path path = context.getQPath(absPath); + Path parentPath = path.getAncestor(1); + Name name = path.getNameElement().getName(); + NodeImpl parent = context.getItemManager().getNode(parentPath); + + NodeStateEx state = getNodeState( + parent, + CHECK_PENDING_CHANGES | ItemValidator.CHECK_LOCK | CHECK_HOLD, + Permission.NONE); + + // check if given version is a baseline + InternalVersion v = getVersion(version); + if (v instanceof InternalBaseline) { + restore(state, name, (InternalBaseline) v); + } else { + restore(state, name, v, removeExisting); + } + } + return this; } - } + }); } /** @@ -253,8 +319,9 @@ public class VersionManagerImpl extends */ protected void restore(NodeImpl node, Version version, boolean removeExisting) throws RepositoryException { - NodeStateEx state = getNodeState(node.getPath(), - ItemValidator.CHECK_PENDING_CHANGES | ItemValidator.CHECK_LOCK | ItemValidator.CHECK_HOLD, + NodeStateEx state = getNodeState( + node.getPath(), + CHECK_PENDING_CHANGES | CHECK_LOCK | CHECK_HOLD, Permission.NONE); InternalVersion v = getVersion(version); restore(state, v, removeExisting); @@ -263,12 +330,21 @@ public class VersionManagerImpl extends /** * {@inheritDoc} */ - public void restoreByLabel(String absPath, String versionLabel, boolean removeExisting) - throws RepositoryException { - NodeStateEx state = getNodeState(absPath, - ItemValidator.CHECK_PENDING_CHANGES | ItemValidator.CHECK_LOCK | ItemValidator.CHECK_HOLD, - Permission.NONE); - restoreByLabel(state, session.getQName(versionLabel), removeExisting); + public void restoreByLabel( + final String absPath, final String versionLabel, + final boolean removeExisting) throws RepositoryException { + perform(new SessionOperation () { + public Object perform(SessionContext context) + throws RepositoryException { + NodeStateEx state = getNodeState( + absPath, + CHECK_PENDING_CHANGES | CHECK_LOCK | CHECK_HOLD, + Permission.NONE); + restoreByLabel( + state, context.getQName(versionLabel), removeExisting); + return this; + } + }); } /** @@ -287,11 +363,9 @@ public class VersionManagerImpl extends mergeOrUpdate(state, srcWorkspaceName, null, false, false); } - /** - * {@inheritDoc} - */ - public NodeIterator merge(String absPath, String srcWorkspace, - boolean bestEffort) + /** Wrapper around {@link #merge(String, String, boolean, boolean)}. */ + public NodeIterator merge( + String absPath, String srcWorkspace, boolean bestEffort) throws RepositoryException { return merge(absPath, srcWorkspace, bestEffort, false); } @@ -299,15 +373,22 @@ public class VersionManagerImpl extends /** * {@inheritDoc} */ - public NodeIterator merge(String absPath, String srcWorkspaceName, - boolean bestEffort, boolean isShallow) - throws RepositoryException { - NodeStateEx state = getNodeState(absPath, - ItemValidator.CHECK_PENDING_CHANGES, - Permission.VERSION_MNGMT); - List failedIds = new LinkedList(); - mergeOrUpdate(state, srcWorkspaceName, failedIds, bestEffort, isShallow); - return new LazyItemIterator(session.getItemManager(), failedIds); + public NodeIterator merge( + final String absPath, final String srcWorkspaceName, + final boolean bestEffort, final boolean isShallow) + throws RepositoryException { + return perform(new SessionOperation () { + public NodeIterator perform(SessionContext context) + throws RepositoryException { + NodeStateEx state = getNodeState( + absPath, + CHECK_PENDING_CHANGES, + Permission.VERSION_MNGMT); + List failedIds = new LinkedList(); + mergeOrUpdate(state, srcWorkspaceName, failedIds, bestEffort, isShallow); + return new LazyItemIterator(session.getItemManager(), failedIds); + } + }); } /** Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/WorkspaceImpl.java URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/WorkspaceImpl.java?rev=983926&r1=983925&r2=983926&view=diff ============================================================================== --- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/WorkspaceImpl.java (original) +++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/WorkspaceImpl.java Tue Aug 10 11:05:48 2010 @@ -271,7 +271,7 @@ public class WorkspaceImpl extends Abstr VersionManagerImpl getVersionManagerImpl() { if (versionMgr == null) { - versionMgr = new VersionManagerImpl(session, stateMgr, hierMgr); + versionMgr = new VersionManagerImpl(sessionContext, stateMgr, hierMgr); } return versionMgr; }