Author: jukka Date: Fri Aug 13 17:34:52 2010 New Revision: 985296 URL: http://svn.apache.org/viewvc?rev=985296&view=rev Log: JCR-890: concurrent read-only access to a session Add WorkspaceImpl into SessionContext Removed: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/XAWorkspace.java Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/BatchedItemOperations.java jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/ItemValidator.java jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/NodeImpl.java jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/RepositoryImpl.java jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/SessionImpl.java jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/WorkspaceImpl.java jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/XASessionImpl.java jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/XAEnvironment.java jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/session/SessionContext.java Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/BatchedItemOperations.java URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/BatchedItemOperations.java?rev=985296&r1=985295&r2=985296&view=diff ============================================================================== --- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/BatchedItemOperations.java (original) +++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/BatchedItemOperations.java Fri Aug 13 17:34:52 2010 @@ -1415,7 +1415,8 @@ public class BatchedItemOperations exten protected void verifyUnlocked(Path nodePath) throws LockException, RepositoryException { // make sure there's no foreign lock on node at nodePath - context.getSessionImpl().getLockManager().checkLock(nodePath, session); + context.getWorkspace().getInternalLockManager().checkLock( + nodePath, session); } /** Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/ItemValidator.java URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/ItemValidator.java?rev=985296&r1=985295&r2=985296&view=diff ============================================================================== --- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/ItemValidator.java (original) +++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/ItemValidator.java Fri Aug 13 17:34:52 2010 @@ -364,7 +364,7 @@ public class ItemValidator { return; } NodeImpl node = (item.isNode()) ? (NodeImpl) item : (NodeImpl) item.getParent(); - context.getSessionImpl().getLockManager().checkLock(node); + context.getWorkspace().getInternalLockManager().checkLock(node); } private boolean isProtected(ItemImpl item) throws RepositoryException { Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/NodeImpl.java URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/NodeImpl.java?rev=985296&r1=985295&r2=985296&view=diff ============================================================================== --- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/NodeImpl.java (original) +++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/NodeImpl.java Fri Aug 13 17:34:52 2010 @@ -2750,7 +2750,7 @@ public class NodeImpl extends ItemImpl i * Returns the version manager of this workspace. */ private VersionManagerImpl getVersionManagerImpl() { - return sessionContext.getSessionImpl().getWorkspaceImpl().getVersionManagerImpl(); + return sessionContext.getWorkspace().getVersionManagerImpl(); } /** @@ -2943,7 +2943,7 @@ public class NodeImpl extends ItemImpl i // a new node needs no check return; } - sessionContext.getSessionImpl().getLockManager().checkLock(this); + sessionContext.getWorkspace().getInternalLockManager().checkLock(this); } //--------------------------------------------------< new JSR 283 methods > Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/RepositoryImpl.java URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/RepositoryImpl.java?rev=985296&r1=985295&r2=985296&view=diff ============================================================================== --- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/RepositoryImpl.java (original) +++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/RepositoryImpl.java Fri Aug 13 17:34:52 2010 @@ -709,7 +709,7 @@ public class RepositoryImpl extends Abst * @param workspaceName name of the new workspace * @throws RepositoryException if a workspace with the given name * already exists or if another error occurs - * @see SessionImpl#createWorkspace(String) + * @see WorkspaceImpl#createWorkspace(String) */ protected void createWorkspace(String workspaceName) throws RepositoryException { @@ -758,7 +758,7 @@ public class RepositoryImpl extends Abst * workspace * @throws RepositoryException if a workspace with the given name already * exists or if another error occurs - * @see SessionImpl#createWorkspace(String,InputSource) + * @see WorkspaceImpl#createWorkspace(String,InputSource) */ private void createWorkspaceInternal(String workspaceName, InputSource configTemplate) @@ -785,7 +785,7 @@ public class RepositoryImpl extends Abst * workspace * @throws RepositoryException if a workspace with the given name already * exists or if another error occurs - * @see SessionImpl#createWorkspace(String,InputSource) + * @see WorkspaceImpl#createWorkspace(String,InputSource) */ protected void createWorkspace(String workspaceName, InputSource configTemplate) Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/SessionImpl.java URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/SessionImpl.java?rev=985296&r1=985295&r2=985296&view=diff ============================================================================== --- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/SessionImpl.java (original) +++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/SessionImpl.java Fri Aug 13 17:34:52 2010 @@ -70,7 +70,6 @@ import org.apache.jackrabbit.commons.Abs import org.apache.jackrabbit.core.config.WorkspaceConfig; import org.apache.jackrabbit.core.data.GarbageCollector; import org.apache.jackrabbit.core.id.NodeId; -import org.apache.jackrabbit.core.lock.LockManager; import org.apache.jackrabbit.core.nodetype.NodeTypeManagerImpl; import org.apache.jackrabbit.core.observation.ObservationManagerImpl; import org.apache.jackrabbit.core.retention.RetentionManagerImpl; @@ -103,7 +102,6 @@ import org.apache.jackrabbit.spi.commons import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.xml.sax.ContentHandler; -import org.xml.sax.InputSource; /** * A SessionImpl ... @@ -159,11 +157,6 @@ public class SessionImpl extends Abstrac new HashMap(); /** - * the Workspace associated with this session - */ - protected final WorkspaceImpl wsp; - - /** * Name and Path resolver */ protected NamePathResolver namePathResolver; @@ -233,14 +226,13 @@ public class SessionImpl extends Abstrac RepositoryContext repositoryContext, Subject subject, WorkspaceConfig wspConfig) throws AccessDeniedException, RepositoryException { - this.context = new SessionContext(repositoryContext, this); + this.context = new SessionContext(repositoryContext, this, wspConfig); this.repositoryContext = repositoryContext; this.subject = subject; userId = retrieveUserId(subject, wspConfig.getName()); namePathResolver = new DefaultNamePathResolver(this, this, true); - wsp = createWorkspaceInstance(wspConfig); context.setItemStateManager(createSessionItemStateManager()); context.setItemManager(createItemManager()); context.setAccessManager(createAccessManager(subject)); @@ -268,26 +260,13 @@ public class SessionImpl extends Abstrac protected SessionItemStateManager createSessionItemStateManager() { SessionItemStateManager mgr = new SessionItemStateManager( context.getRootNodeId(), - wsp.getItemStateManager(), - repositoryContext.getNodeTypeRegistry()); - wsp.getItemStateManager().addListener(mgr); + context.getWorkspace().getItemStateManager(), + context.getNodeTypeRegistry()); + context.getWorkspace().getItemStateManager().addListener(mgr); return mgr; } /** - * Creates the workspace instance backing this session. - * - * @param wspConfig The workspace configuration - * @return An instance of the {@link WorkspaceImpl} class or an extension - * thereof. - * @throws RepositoryException if the workspace can not be accessed - */ - protected WorkspaceImpl createWorkspaceInstance(WorkspaceConfig wspConfig) - throws RepositoryException { - return new WorkspaceImpl(wspConfig, context); - } - - /** * Create the item manager. * @return item manager */ @@ -301,9 +280,9 @@ public class SessionImpl extends Abstrac throws RepositoryException { try { return new ObservationManagerImpl( - repositoryContext.getRepository().getObservationDispatcher(wspName), + context.getRepository().getObservationDispatcher(wspName), this, context.getItemManager(), - repositoryContext.getClusterNode()); + context.getRepositoryContext().getClusterNode()); } catch (NoSuchWorkspaceException e) { // should never get here throw new RepositoryException( @@ -317,7 +296,7 @@ public class SessionImpl extends Abstrac */ protected InternalVersionManager createVersionManager() throws RepositoryException { - return repositoryContext.getInternalVersionManager(); + return context.getRepositoryContext().getInternalVersionManager(); } /** @@ -333,8 +312,8 @@ public class SessionImpl extends Abstrac throws AccessDeniedException, RepositoryException { String wspName = getWorkspace().getName(); AMContext ctx = new AMContext( - new File(repositoryContext.getRepository().getConfig().getHomeDir()), - repositoryContext.getFileSystem(), + new File(context.getRepository().getConfig().getHomeDir()), + context.getRepositoryContext().getFileSystem(), this, getSubject(), context.getHierarchyManager(), @@ -449,7 +428,7 @@ public class SessionImpl extends Abstrac * @throws RepositoryException */ protected RetentionRegistry getRetentionRegistry() throws RepositoryException { - return wsp.getRetentionRegistry(); + return context.getWorkspace().getRetentionRegistry(); } /** @@ -490,62 +469,6 @@ public class SessionImpl extends Abstrac } /** - * Returns the names of all workspaces of this repository with respect of the - * access rights of this session. - * - * @return the names of all accessible workspaces - * @throws RepositoryException if an error occurs - */ - protected String[] getWorkspaceNames() throws RepositoryException { - // filter workspaces according to access rights - List names = new ArrayList(); - for (String name : repositoryContext.getWorkspaceManager().getWorkspaceNames()) { - try { - if (context.getAccessManager().canAccess(name)) { - names.add(name); - } - } catch (NoSuchWorkspaceException e) { - log.warn("Workspace disappeared unexpectedly: " + name, e); - } - } - return names.toArray(new String[names.size()]); - } - - /** - * Creates a workspace with the given name. - * - * @param workspaceName name of the new workspace - * @throws AccessDeniedException if the current session is not allowed to - * create the workspace - * @throws RepositoryException if a workspace with the given name - * already exists or if another error occurs - */ - protected void createWorkspace(String workspaceName) - throws AccessDeniedException, RepositoryException { - // @todo verify that this session has the right privileges for this operation - repositoryContext.getWorkspaceManager().createWorkspace(workspaceName); - } - - /** - * Creates a workspace with the given name and a workspace configuration - * template. - * - * @param workspaceName name of the new workspace - * @param configTemplate the configuration template of the new workspace - * @throws AccessDeniedException if the current session is not allowed to - * create the workspace - * @throws RepositoryException if a workspace with the given name already - * exists or if another error occurs - */ - protected void createWorkspace( - String workspaceName, InputSource configTemplate) - throws AccessDeniedException, RepositoryException { - // @todo verify that this session has the right privileges for this operation - repositoryContext.getWorkspaceManager().createWorkspace( - workspaceName, configTemplate); - } - - /** * Notify the listeners that this session is about to be closed. */ protected void notifyLoggingOut() { @@ -719,11 +642,7 @@ public class SessionImpl extends Abstrac * {@inheritDoc} */ public Workspace getWorkspace() { - return getWorkspaceImpl(); - } - - WorkspaceImpl getWorkspaceImpl() { - return wsp; + return context.getWorkspace(); } /** @@ -884,7 +803,9 @@ public class SessionImpl extends Abstrac ItemValidator.CHECK_CONSTRAINTS | ItemValidator.CHECK_HOLD | ItemValidator.CHECK_RETENTION; context.getItemValidator().checkModify(parent, options, Permission.NONE); - SessionImporter importer = new SessionImporter(parent, this, uuidBehavior, wsp.getConfig().getImportConfig()); + SessionImporter importer = new SessionImporter( + parent, this, uuidBehavior, + context.getWorkspace().getConfig().getImportConfig()); return new ImportHandler(importer, this); } @@ -939,7 +860,7 @@ public class SessionImpl extends Abstrac // dispose item manager context.getItemManager().dispose(); // dispose workspace - wsp.dispose(); + context.getWorkspace().dispose(); // logout JAAS subject if (loginContext != null) { @@ -1016,7 +937,7 @@ public class SessionImpl extends Abstrac */ public void addLockToken(String lt) { try { - wsp.getLockManager().addLockToken(lt); + getWorkspace().getLockManager().addLockToken(lt); } catch (RepositoryException e) { log.debug("Error while adding lock token."); } @@ -1027,7 +948,7 @@ public class SessionImpl extends Abstrac */ public String[] getLockTokens() { try { - return wsp.getLockManager().getLockTokens(); + return getWorkspace().getLockManager().getLockTokens(); } catch (RepositoryException e) { log.debug("Error while accessing lock tokens."); return new String[0]; @@ -1039,21 +960,13 @@ public class SessionImpl extends Abstrac */ public void removeLockToken(String lt) { try { - wsp.getLockManager().removeLockToken(lt); + getWorkspace().getLockManager().removeLockToken(lt); } catch (RepositoryException e) { log.debug("Error while removing lock token."); } } /** - * Return the lock manager for this session. - * @return lock manager for this session - */ - public LockManager getLockManager() throws RepositoryException { - return wsp.getInternalLockManager(); - } - - /** * Returns all locks owned by this session. * * @return an array of Locks @@ -1067,7 +980,7 @@ public class SessionImpl extends Abstrac } try { - return getLockManager().getLocks(this); + return context.getWorkspace().getInternalLockManager().getLocks(this); } catch (RepositoryException e) { log.error("Lock manager not available.", e); return new Lock[0]; 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=985296&r1=985295&r2=985296&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 Fri Aug 13 17:34:52 2010 @@ -16,6 +16,9 @@ */ package org.apache.jackrabbit.core; +import java.util.ArrayList; +import java.util.List; + import javax.jcr.AccessDeniedException; import javax.jcr.InvalidItemStateException; import javax.jcr.ItemExistsException; @@ -42,15 +45,19 @@ import org.apache.jackrabbit.core.config import org.apache.jackrabbit.core.id.ItemId; import org.apache.jackrabbit.core.id.NodeId; import org.apache.jackrabbit.core.lock.LockManager; +import org.apache.jackrabbit.core.lock.LockManagerImpl; import org.apache.jackrabbit.core.lock.SessionLockManager; +import org.apache.jackrabbit.core.lock.XALockManager; import org.apache.jackrabbit.core.observation.EventStateCollection; import org.apache.jackrabbit.core.observation.EventStateCollectionFactory; import org.apache.jackrabbit.core.observation.ObservationManagerImpl; import org.apache.jackrabbit.core.query.QueryManagerImpl; import org.apache.jackrabbit.core.retention.RetentionRegistry; import org.apache.jackrabbit.core.session.SessionContext; +import org.apache.jackrabbit.core.state.ItemStateCacheFactory; import org.apache.jackrabbit.core.state.LocalItemStateManager; import org.apache.jackrabbit.core.state.SharedItemStateManager; +import org.apache.jackrabbit.core.state.XAItemStateManager; import org.apache.jackrabbit.core.xml.ImportHandler; import org.apache.jackrabbit.core.xml.Importer; import org.apache.jackrabbit.core.xml.WorkspaceImporter; @@ -71,19 +78,14 @@ public class WorkspaceImpl extends Abstr private static Logger log = LoggerFactory.getLogger(WorkspaceImpl.class); /** - * The configuration of this Workspace - */ - protected final WorkspaceConfig wspConfig; - - /** - * The component context of the repository that created this workspace. + * The component context of this session. */ - protected final RepositoryContext repositoryContext; + protected final SessionContext context; /** - * The component context of this session. + * The configuration of this Workspace */ - protected final SessionContext sessionContext; + protected final WorkspaceConfig wspConfig; /** * The persistent state mgr associated with the workspace represented by this @@ -136,22 +138,22 @@ public class WorkspaceImpl extends Abstr private RetentionRegistry retentionRegistry; /** - * Protected constructor. + * Creates a new workspace instance * + * @param context component context of this session * @param wspConfig The workspace configuration - * @param sessionContext component context of this session + * @throws RepositoryException if the workspace can not be accessed */ - protected WorkspaceImpl( - WorkspaceConfig wspConfig, SessionContext sessionContext) + public WorkspaceImpl( + SessionContext context, WorkspaceConfig wspConfig) throws RepositoryException { + this.context = context; this.wspConfig = wspConfig; - this.sessionContext = sessionContext; - this.repositoryContext = sessionContext.getRepositoryContext(); this.stateMgr = createItemStateManager(); this.hierMgr = new CachingHierarchyManager( - repositoryContext.getRootNodeId(), this.stateMgr); + context.getRootNodeId(), this.stateMgr); this.stateMgr.addListener(hierMgr); - this.session = sessionContext.getSessionImpl(); + this.session = context.getSessionImpl(); } /** @@ -196,7 +198,7 @@ public class WorkspaceImpl extends Abstr * for some reason */ public void sanityCheck() throws RepositoryException { - sessionContext.getSessionState().checkAlive(); + context.getSessionState().checkAlive(); } //--------------------------------------------------< new JSR 283 methods > @@ -204,24 +206,27 @@ public class WorkspaceImpl extends Abstr * {@inheritDoc} */ public void createWorkspace(String name, String srcWorkspace) - throws AccessDeniedException, UnsupportedRepositoryOperationException, - RepositoryException { + throws AccessDeniedException, RepositoryException { // check state of this instance sanityCheck(); - session.createWorkspace(name); + WorkspaceManager manager = + context.getRepositoryContext().getWorkspaceManager(); + + // TODO verify that this session has the right privileges + // for this operation + manager.createWorkspace(name); SessionImpl tmpSession = null; try { // create a temporary session on new workspace for current subject - tmpSession = repositoryContext.getWorkspaceManager().createSession( - session.getSubject(), name); + tmpSession = manager.createSession(session.getSubject(), name); WorkspaceImpl newWsp = (WorkspaceImpl) tmpSession.getWorkspace(); // Workspace#clone(String, String, String, booelan) doesn't // allow to clone to "/"... //newWsp.clone(srcWorkspace, "/", "/", false); - Node root = session.getRootNode(); + Node root = getSession().getRootNode(); for (NodeIterator it = root.getNodes(); it.hasNext(); ) { Node child = it.nextNode(); // skip nodes that already exist in newly created workspace @@ -246,7 +251,7 @@ public class WorkspaceImpl extends Abstr public void deleteWorkspace(String name) throws AccessDeniedException, UnsupportedRepositoryOperationException, RepositoryException { // check if workspace exists (will throw NoSuchWorkspaceException if not) - repositoryContext.getRepository().getWorkspaceInfo(name); + context.getRepository().getWorkspaceInfo(name); // todo implement deleteWorkspace throw new UnsupportedRepositoryOperationException("not yet implemented"); } @@ -258,7 +263,7 @@ public class WorkspaceImpl extends Abstr public javax.jcr.lock.LockManager getLockManager() throws UnsupportedRepositoryOperationException, RepositoryException { if (jcr283LockManager == null) { jcr283LockManager = - new SessionLockManager(sessionContext, session.getLockManager()); + new SessionLockManager(context, getInternalLockManager()); } return jcr283LockManager; } @@ -272,7 +277,7 @@ public class WorkspaceImpl extends Abstr VersionManagerImpl getVersionManagerImpl() { if (versionMgr == null) { - versionMgr = new VersionManagerImpl(sessionContext, stateMgr, hierMgr); + versionMgr = new VersionManagerImpl(context, stateMgr, hierMgr); } return versionMgr; } @@ -300,19 +305,17 @@ public class WorkspaceImpl extends Abstr * @throws AccessDeniedException if the session through which * this Workspace object was acquired does not have permission * to create the new workspace. - * @throws UnsupportedRepositoryOperationException if the repository does - * not support the creation of workspaces. * @throws RepositoryException if another error occurs. * @since JCR 2.0 */ public void createWorkspace(String name) - throws AccessDeniedException, - UnsupportedRepositoryOperationException, - RepositoryException { + throws AccessDeniedException, RepositoryException { // check state of this instance sanityCheck(); - session.createWorkspace(name); + // TODO verify that this session has the right privileges + // for this operation + context.getRepositoryContext().getWorkspaceManager().createWorkspace(name); } //--------------------------------------------------< JackrabbitWorkspace > @@ -328,14 +331,19 @@ public class WorkspaceImpl extends Abstr * already exists or if another error occurs * @see #getAccessibleWorkspaceNames() */ - public void createWorkspace(String workspaceName, InputSource configTemplate) + public void createWorkspace( + String workspaceName, InputSource configTemplate) throws AccessDeniedException, RepositoryException { // check state of this instance sanityCheck(); - session.createWorkspace(workspaceName, configTemplate); + // TODO verify that this session has the right privileges + // for this operation + context.getRepositoryContext().getWorkspaceManager().createWorkspace( + workspaceName, configTemplate); } + /** * Returns the configuration of this workspace. * @return the workspace configuration @@ -373,7 +381,7 @@ public class WorkspaceImpl extends Abstr Path srcPath; try { - srcPath = session.getQPath(srcAbsPath).getNormalizedPath(); + srcPath = context.getQPath(srcAbsPath).getNormalizedPath(); } catch (NameException e) { String msg = "invalid path: " + srcAbsPath; log.debug(msg); @@ -385,7 +393,7 @@ public class WorkspaceImpl extends Abstr Path destPath; try { - destPath = session.getQPath(destAbsPath).getNormalizedPath(); + destPath = context.getQPath(destAbsPath).getNormalizedPath(); } catch (NameException e) { String msg = "invalid path: " + destAbsPath; log.debug(msg); @@ -396,7 +404,7 @@ public class WorkspaceImpl extends Abstr } BatchedItemOperations ops = - new BatchedItemOperations(stateMgr, sessionContext); + new BatchedItemOperations(stateMgr, context); try { ops.edit(); @@ -411,11 +419,11 @@ public class WorkspaceImpl extends Abstr try { NodeId id = ops.copy(srcPath, srcWsp.getItemStateManager(), srcWsp.getHierarchyManager(), - srcWsp.sessionContext.getAccessManager(), + srcWsp.context.getAccessManager(), destPath, flag); ops.update(); succeeded = true; - return session.getJCRPath(hierMgr.getPath(id)); + return context.getJCRPath(hierMgr.getPath(id)); } finally { if (!succeeded) { // update operation failed, cancel all modifications @@ -448,7 +456,7 @@ public class WorkspaceImpl extends Abstr Path srcPath; try { - srcPath = session.getQPath(srcAbsPath).getNormalizedPath(); + srcPath = context.getQPath(srcAbsPath).getNormalizedPath(); } catch (NameException e) { String msg = "invalid path: " + srcAbsPath; log.debug(msg); @@ -460,7 +468,7 @@ public class WorkspaceImpl extends Abstr Path destPath; try { - destPath = session.getQPath(destAbsPath).getNormalizedPath(); + destPath = context.getQPath(destAbsPath).getNormalizedPath(); } catch (NameException e) { String msg = "invalid path: " + destAbsPath; log.debug(msg); @@ -471,7 +479,7 @@ public class WorkspaceImpl extends Abstr } BatchedItemOperations ops = - new BatchedItemOperations(stateMgr, sessionContext); + new BatchedItemOperations(stateMgr, context); try { ops.edit(); @@ -487,7 +495,7 @@ public class WorkspaceImpl extends Abstr ItemId id = ops.clone(srcPath, destPath); ops.update(); succeeded = true; - return session.getJCRPath(hierMgr.getPath(id)); + return context.getJCRPath(hierMgr.getPath(id)); } finally { if (!succeeded) { // update operation failed, cancel all modifications @@ -509,8 +517,12 @@ public class WorkspaceImpl extends Abstr sanityCheck(); if (lockMgr == null) { - lockMgr = repositoryContext.getRepository().getLockManager( - wspConfig.getName()); + lockMgr = + context.getRepository().getLockManager(wspConfig.getName()); + // FIXME Shouldn't need to use instanceof here + if (context.getSessionImpl() instanceof XASessionImpl) { + lockMgr = new XALockManager((LockManagerImpl) lockMgr); + } } return lockMgr; } @@ -527,7 +539,7 @@ public class WorkspaceImpl extends Abstr sanityCheck(); if (retentionRegistry == null) { retentionRegistry = - repositoryContext.getRepository().getRetentionRegistry(wspConfig.getName()); + context.getRepository().getRetentionRegistry(wspConfig.getName()); } return retentionRegistry; } @@ -551,10 +563,7 @@ public class WorkspaceImpl extends Abstr * {@inheritDoc} */ public NamespaceRegistry getNamespaceRegistry() throws RepositoryException { - // check state of this instance - sanityCheck(); - - return repositoryContext.getNamespaceRegistry(); + return context.getRepositoryContext().getNamespaceRegistry(); } /** @@ -564,7 +573,7 @@ public class WorkspaceImpl extends Abstr // check state of this instance sanityCheck(); - return sessionContext.getNodeTypeManager(); + return context.getNodeTypeManager(); } /** @@ -593,7 +602,7 @@ public class WorkspaceImpl extends Abstr } // check authorization for specified workspace - if (!sessionContext.getAccessManager().canAccess(srcWorkspace)) { + if (!context.getAccessManager().canAccess(srcWorkspace)) { throw new AccessDeniedException("not authorized to access " + srcWorkspace); } @@ -604,8 +613,9 @@ public class WorkspaceImpl extends Abstr try { // create session on other workspace for current subject // (may throw NoSuchWorkspaceException and AccessDeniedException) - srcSession = repositoryContext.getWorkspaceManager().createSession( - session.getSubject(), srcWorkspace); + WorkspaceManager manager = + context.getRepositoryContext().getWorkspaceManager(); + srcSession = manager.createSession(session.getSubject(), srcWorkspace); WorkspaceImpl srcWsp = (WorkspaceImpl) srcSession.getWorkspace(); // do cross-workspace copy @@ -655,7 +665,7 @@ public class WorkspaceImpl extends Abstr } // check authorization for specified workspace - if (!sessionContext.getAccessManager().canAccess(srcWorkspace)) { + if (!context.getAccessManager().canAccess(srcWorkspace)) { throw new AccessDeniedException("not authorized to access " + srcWorkspace); } @@ -666,8 +676,9 @@ public class WorkspaceImpl extends Abstr try { // create session on other workspace for current subject // (may throw NoSuchWorkspaceException and AccessDeniedException) - srcSession = repositoryContext.getWorkspaceManager().createSession( - session.getSubject(), srcWorkspace); + WorkspaceManager manager = + context.getRepositoryContext().getWorkspaceManager(); + srcSession = manager.createSession(session.getSubject(), srcWorkspace); WorkspaceImpl srcWsp = (WorkspaceImpl) srcSession.getWorkspace(); // do cross-workspace copy @@ -694,7 +705,7 @@ public class WorkspaceImpl extends Abstr Path srcPath; try { - srcPath = session.getQPath(srcAbsPath).getNormalizedPath(); + srcPath = context.getQPath(srcAbsPath).getNormalizedPath(); } catch (NameException e) { String msg = "invalid path: " + srcAbsPath; log.debug(msg); @@ -706,7 +717,7 @@ public class WorkspaceImpl extends Abstr Path destPath; try { - destPath = session.getQPath(destAbsPath).getNormalizedPath(); + destPath = context.getQPath(destAbsPath).getNormalizedPath(); } catch (NameException e) { String msg = "invalid path: " + destAbsPath; log.debug(msg); @@ -717,7 +728,7 @@ public class WorkspaceImpl extends Abstr } BatchedItemOperations ops = - new BatchedItemOperations(stateMgr, sessionContext); + new BatchedItemOperations(stateMgr, context); try { ops.edit(); @@ -747,7 +758,7 @@ public class WorkspaceImpl extends Abstr * @return the observation manager of this session */ public ObservationManager getObservationManager() { - return sessionContext.getObservationManager(); + return context.getObservationManager(); } /** @@ -761,7 +772,8 @@ public class WorkspaceImpl extends Abstr if (queryManager == null) { SearchManager searchManager; try { - searchManager = repositoryContext.getRepository().getSearchManager(wspConfig.getName()); + searchManager = + context.getRepository().getSearchManager(wspConfig.getName()); if (searchManager == null) { String msg = "no search manager configured for this workspace"; log.debug(msg); @@ -773,7 +785,7 @@ public class WorkspaceImpl extends Abstr log.debug(msg); throw new RepositoryException(msg, nswe); } - queryManager = new QueryManagerImpl(sessionContext, searchManager); + queryManager = new QueryManagerImpl(context, searchManager); } return queryManager; } @@ -792,15 +804,33 @@ public class WorkspaceImpl extends Abstr } /** - * {@inheritDoc} + * Returns the names of all workspaces of this repository with respect of the + * access rights of this session. + * + * @return the names of all accessible workspaces + * @throws RepositoryException if an error occurs */ public String[] getAccessibleWorkspaceNames() throws RepositoryException { // check state of this instance sanityCheck(); - return session.getWorkspaceNames(); + // filter workspaces according to access rights + List names = new ArrayList(); + WorkspaceManager manager = + context.getRepositoryContext().getWorkspaceManager(); + for (String name : manager.getWorkspaceNames()) { + try { + if (context.getAccessManager().canAccess(name)) { + names.add(name); + } + } catch (NoSuchWorkspaceException e) { + log.warn("Workspace disappeared unexpectedly: " + name, e); + } + } + return names.toArray(new String[names.size()]); } + /** * {@inheritDoc} */ @@ -814,7 +844,7 @@ public class WorkspaceImpl extends Abstr Path parentPath; try { - parentPath = session.getQPath(parentAbsPath).getNormalizedPath(); + parentPath = context.getQPath(parentAbsPath).getNormalizedPath(); } catch (NameException e) { String msg = "invalid path: " + parentAbsPath; log.debug(msg); @@ -825,9 +855,9 @@ public class WorkspaceImpl extends Abstr } Importer importer = new WorkspaceImporter( - parentPath, this, sessionContext, + parentPath, this, context, uuidBehavior, wspConfig.getImportConfig()); - return new ImportHandler(importer, session); + return new ImportHandler(importer, getSession()); } /** @@ -838,21 +868,33 @@ public class WorkspaceImpl extends Abstr */ protected SharedItemStateManager getSharedItemStateManager() throws RepositoryException { - WorkspaceManager manager = repositoryContext.getWorkspaceManager(); + WorkspaceManager manager = + context.getRepositoryContext().getWorkspaceManager(); return manager.getWorkspaceStateManager(getName()); } /** * Create the persistent item state manager on top of the shared item - * state manager. May be overridden by subclasses. - * @param shared shared item state manager + * state manager. + * * @return local item state manager + * @throws RepositoryException if the workspace can not be accessed */ protected LocalItemStateManager createItemStateManager() throws RepositoryException { - return LocalItemStateManager.createInstance( - getSharedItemStateManager(), this, - repositoryContext.getItemStateCacheFactory()); + SharedItemStateManager sism = getSharedItemStateManager(); + ItemStateCacheFactory iscf = + context.getRepositoryContext().getItemStateCacheFactory(); + + // FIXME We should be able to avoid the instanceof operator here + if (context.getSessionImpl() instanceof XASessionImpl) { + return XAItemStateManager.createInstance( + sism, this, null, iscf); + } else { + return LocalItemStateManager.createInstance( + sism, this, iscf); + } + } //------------------------------------------< EventStateCollectionFactory > Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/XASessionImpl.java URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/XASessionImpl.java?rev=985296&r1=985295&r2=985296&view=diff ============================================================================== --- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/XASessionImpl.java (original) +++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/XASessionImpl.java Fri Aug 13 17:34:52 2010 @@ -18,8 +18,6 @@ package org.apache.jackrabbit.core; import org.apache.jackrabbit.api.XASession; import org.apache.jackrabbit.core.config.WorkspaceConfig; -import org.apache.jackrabbit.core.lock.LockManager; -import org.apache.jackrabbit.core.lock.LockManagerImpl; import org.apache.jackrabbit.core.lock.XALockManager; import org.apache.jackrabbit.core.security.authentication.AuthContext; import org.apache.jackrabbit.core.state.XAItemStateManager; @@ -84,11 +82,6 @@ public class XASessionImpl extends Sessi private InternalXAResource[] txResources; /** - * Session-local lock manager. - */ - private LockManager lockMgr; - - /** * Create a new instance of this class. * * @param repositoryContext repository context @@ -129,9 +122,13 @@ public class XASessionImpl extends Sessi * Initialize this object. */ private void init() throws RepositoryException { - XAItemStateManager stateMgr = (XAItemStateManager) wsp.getItemStateManager(); - XALockManager lockMgr = (XALockManager) getLockManager(); - InternalXAVersionManager versionMgr = (InternalXAVersionManager) getInternalVersionManager(); + WorkspaceImpl workspace = context.getWorkspace(); + XAItemStateManager stateMgr = + (XAItemStateManager) workspace.getItemStateManager(); + XALockManager lockMgr = + (XALockManager) workspace.getInternalLockManager(); + InternalXAVersionManager versionMgr = + (InternalXAVersionManager) getInternalVersionManager(); /** * Create array that contains all resources that participate in this @@ -158,15 +155,6 @@ public class XASessionImpl extends Sessi * {@inheritDoc} */ @Override - protected WorkspaceImpl createWorkspaceInstance(WorkspaceConfig wspConfig) - throws RepositoryException { - return new XAWorkspace(wspConfig, context); - } - - /** - * {@inheritDoc} - */ - @Override protected InternalVersionManager createVersionManager() throws RepositoryException { return new InternalXAVersionManager( @@ -176,16 +164,6 @@ public class XASessionImpl extends Sessi repositoryContext.getItemStateCacheFactory()); } - /** - * {@inheritDoc} - */ - public LockManager getLockManager() throws RepositoryException { - if (lockMgr == null) { - LockManagerImpl lockMgr = (LockManagerImpl) wsp.getInternalLockManager(); - this.lockMgr = new XALockManager(lockMgr); - } - return lockMgr; - } //-------------------------------------------------------------< XASession > /** * {@inheritDoc} 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=985296&r1=985295&r2=985296&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 Fri Aug 13 17:34:52 2010 @@ -19,7 +19,7 @@ package org.apache.jackrabbit.core.lock; import org.apache.jackrabbit.core.TransactionException; import org.apache.jackrabbit.core.NodeImpl; import org.apache.jackrabbit.core.SessionImpl; -import org.apache.jackrabbit.core.XAWorkspace; +import org.apache.jackrabbit.core.WorkspaceImpl; import org.apache.jackrabbit.core.id.NodeId; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -475,7 +475,7 @@ class XAEnvironment { if (isUnlock) { // Only if we have a valid ItemState try to unlock // JCR-2332 - if (((XAWorkspace)((SessionImpl)node.getSession()).getWorkspace()).getItemStateManager().hasItemState(node.getId())) { + if (((WorkspaceImpl) node.getSession().getWorkspace()).getItemStateManager().hasItemState(node.getId())) { lockMgr.internalUnlock(node); } } else { Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/session/SessionContext.java URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/session/SessionContext.java?rev=985296&r1=985295&r2=985296&view=diff ============================================================================== --- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/session/SessionContext.java (original) +++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/session/SessionContext.java Fri Aug 13 17:34:52 2010 @@ -17,19 +17,24 @@ package org.apache.jackrabbit.core.session; import javax.jcr.NamespaceException; +import javax.jcr.RepositoryException; import javax.jcr.ValueFactory; import org.apache.jackrabbit.core.HierarchyManager; import org.apache.jackrabbit.core.ItemManager; import org.apache.jackrabbit.core.ItemValidator; import org.apache.jackrabbit.core.RepositoryContext; +import org.apache.jackrabbit.core.RepositoryImpl; import org.apache.jackrabbit.core.SessionImpl; +import org.apache.jackrabbit.core.WorkspaceImpl; +import org.apache.jackrabbit.core.config.WorkspaceConfig; import org.apache.jackrabbit.core.data.DataStore; import org.apache.jackrabbit.core.id.NodeId; import org.apache.jackrabbit.core.nodetype.NodeTypeManagerImpl; import org.apache.jackrabbit.core.nodetype.NodeTypeRegistry; import org.apache.jackrabbit.core.observation.ObservationManagerImpl; import org.apache.jackrabbit.core.security.AccessManager; +import org.apache.jackrabbit.core.security.JackrabbitSecurityManager; import org.apache.jackrabbit.core.state.SessionItemStateManager; import org.apache.jackrabbit.core.value.ValueFactoryImpl; import org.apache.jackrabbit.spi.Name; @@ -75,6 +80,11 @@ public class SessionContext implements N private final NodeTypeManagerImpl nodeTypeManager; /** + * The workspace of this session + */ + private final WorkspaceImpl workspace; + + /** * The item state manager of this session */ private volatile SessionItemStateManager itemStateManager; @@ -99,9 +109,12 @@ public class SessionContext implements N * * @param repositoryContext repository context of the session * @param session the session + * @param workspaceConfig workspace configuration + * @throws RepositoryException if the workspace can not be accessed */ public SessionContext( - RepositoryContext repositoryContext, SessionImpl session) { + RepositoryContext repositoryContext, SessionImpl session, + WorkspaceConfig workspaceConfig) throws RepositoryException { assert repositoryContext != null; assert session != null; this.repositoryContext = repositoryContext; @@ -111,8 +124,11 @@ public class SessionContext implements N new ValueFactoryImpl(session, repositoryContext.getDataStore()); this.itemValidator = new ItemValidator(this); this.nodeTypeManager = new NodeTypeManagerImpl(this); + this.workspace = new WorkspaceImpl(this, workspaceConfig); } + //-------------------------------------------< per-repository components > + /** * Returns the repository context of the session. * @@ -123,6 +139,15 @@ public class SessionContext implements N } /** + * Returns this repository. + * + * @return repository + */ + public RepositoryImpl getRepository() { + return repositoryContext.getRepository(); + } + + /** * Returns the root node identifier of the repository. * * @return root node identifier @@ -151,6 +176,17 @@ public class SessionContext implements N } /** + * Returns the security manager of this repository. + * + * @return security manager + */ + public JackrabbitSecurityManager getSecurityManager() { + return repositoryContext.getSecurityManager(); + } + + //----------------------------------------------< per-session components > + + /** * Returns this session. * * @return session @@ -195,6 +231,15 @@ public class SessionContext implements N return nodeTypeManager; } + /** + * Returns the workspace of this session. + * + * @return workspace + */ + public WorkspaceImpl getWorkspace() { + return workspace; + } + public SessionItemStateManager getItemStateManager() { assert itemStateManager != null; return itemStateManager;