Index: src/main/java/org/apache/jackrabbit/core/RepositoryImpl.java =================================================================== --- src/main/java/org/apache/jackrabbit/core/RepositoryImpl.java (revision 759860) +++ src/main/java/org/apache/jackrabbit/core/RepositoryImpl.java (working copy) @@ -481,7 +481,7 @@ secWspName = smc.getWorkspaceName(); } try { - initWorkspace((WorkspaceInfo) wspInfos.get(wspName)); + ((WorkspaceInfo) wspInfos.get(wspName)).initialize(); if (secWspName != null && !wspInfos.containsKey(secWspName)) { createWorkspace(secWspName); log.info("created system workspace: {}", secWspName); @@ -636,48 +636,6 @@ } } - private void initWorkspace(WorkspaceInfo wspInfo) throws RepositoryException { - // first initialize workspace info - if (!wspInfo.initialize()) { - // workspace has already been initialized, we're done - return; - } - - // get system session and Workspace instance - SessionImpl sysSession = wspInfo.getSystemSession(); - WorkspaceImpl wsp = (WorkspaceImpl) sysSession.getWorkspace(); - - /** - * todo implement 'System' workspace - * FIXME - * - there should be one 'System' workspace per repository - * - the 'System' workspace should have the /jcr:system node - * - versions, version history and node types should be reflected in - * this system workspace as content under /jcr:system - * - all other workspaces should be dynamic workspaces based on - * this 'read-only' system workspace - * - * for now, the jcr:system node is created in - * {@link org.apache.jackrabbit.core.state.SharedItemStateManager#createRootNodeState} - */ - - // register the repository as event listener for keeping repository statistics - wsp.getObservationManager().addEventListener(this, - Event.NODE_ADDED | Event.NODE_REMOVED - | Event.PROPERTY_ADDED | Event.PROPERTY_REMOVED, - "/", true, null, null, false); - - // register SearchManager as event listener - SearchManager searchMgr = wspInfo.getSearchManager(); - if (searchMgr != null) { - wsp.getObservationManager().addEventListener(searchMgr, - Event.NODE_ADDED | Event.NODE_REMOVED - | Event.PROPERTY_ADDED | Event.PROPERTY_REMOVED - | Event.PROPERTY_CHANGED, - "/", true, null, null, false); - } - } - /** * Returns the system search manager or null if none is * configured. @@ -769,7 +727,7 @@ } try { - initWorkspace(wspInfo); + wspInfo.initialize(); } catch (RepositoryException e) { log.error("Unable to initialize workspace '" + workspaceName + "'", e); throw new NoSuchWorkspaceException(workspaceName); @@ -1929,6 +1887,7 @@ log.info("initializing workspace '" + getName() + "'..."); doInitialize(); initialized = true; + doPostInitialize(); log.info("workspace '" + getName() + "' initialized"); return true; } finally { @@ -1983,6 +1942,49 @@ } /** + * Initializes the search manager of this workspace info. This method + * is called while still holding the write lock on this workspace + * info, but {@link #initialized} is already set to true. + * + * @throws RepositoryException if the search manager could not be created + */ + protected void doPostInitialize() + throws RepositoryException { + // get system Workspace instance + WorkspaceImpl wsp = (WorkspaceImpl) getSystemSession().getWorkspace(); + + /** + * todo implement 'System' workspace + * FIXME + * - there should be one 'System' workspace per repository + * - the 'System' workspace should have the /jcr:system node + * - versions, version history and node types should be reflected in + * this system workspace as content under /jcr:system + * - all other workspaces should be dynamic workspaces based on + * this 'read-only' system workspace + * + * for now, the jcr:system node is created in + * {@link org.apache.jackrabbit.core.state.SharedItemStateManager#createRootNodeState} + */ + + // register the repository as event listener for keeping repository statistics + wsp.getObservationManager().addEventListener(RepositoryImpl.this, + Event.NODE_ADDED | Event.NODE_REMOVED + | Event.PROPERTY_ADDED | Event.PROPERTY_REMOVED, + "/", true, null, null, false); + + // register SearchManager as event listener + SearchManager searchMgr = getSearchManager(); + if (searchMgr != null) { + wsp.getObservationManager().addEventListener(searchMgr, + Event.NODE_ADDED | Event.NODE_REMOVED + | Event.PROPERTY_ADDED | Event.PROPERTY_REMOVED + | Event.PROPERTY_CHANGED, + "/", true, null, null, false); + } + } + + /** * Disposes this WorkspaceInfo if it has been idle for more * than maxIdleTime milliseconds. * Index: src/test/java/org/apache/jackrabbit/core/integration/WorkspaceInitTest.java =================================================================== --- src/test/java/org/apache/jackrabbit/core/integration/WorkspaceInitTest.java (revision 0) +++ src/test/java/org/apache/jackrabbit/core/integration/WorkspaceInitTest.java (revision 0) @@ -0,0 +1,53 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.jackrabbit.core.integration; + +import java.util.List; +import java.util.ArrayList; +import java.util.Iterator; + +import javax.jcr.RepositoryException; + +import org.apache.jackrabbit.test.AbstractJCRTest; + +/** + * WorkspaceInitTest... + */ +public class WorkspaceInitTest extends AbstractJCRTest { + + public void testIdleTime() throws Exception { + // simply access the workspace, which will cause + // initialization of SlowQueryHandler. + List threads = new ArrayList(); + for (int i = 0; i < 10; i++) { + Thread t = new Thread(new Runnable() { + public void run() { + try { + helper.getSuperuserSession("workspace-init-test").logout(); + } catch (RepositoryException e) { + throw new RuntimeException(e); + } + } + }); + t.start(); + threads.add(t); + } + for (Iterator it = threads.iterator(); it.hasNext(); ) { + ((Thread) it.next()).join(); + } + } +} Property changes on: src\test\java\org\apache\jackrabbit\core\integration\WorkspaceInitTest.java ___________________________________________________________________ Added: svn:eol-style + native Index: src/test/java/org/apache/jackrabbit/core/query/lucene/SlowQueryHandler.java =================================================================== --- src/test/java/org/apache/jackrabbit/core/query/lucene/SlowQueryHandler.java (revision 0) +++ src/test/java/org/apache/jackrabbit/core/query/lucene/SlowQueryHandler.java (revision 0) @@ -0,0 +1,73 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.jackrabbit.core.query.lucene; + +import java.io.IOException; + +import javax.jcr.RepositoryException; +import javax.jcr.query.InvalidQueryException; + +import org.apache.jackrabbit.core.query.AbstractQueryHandler; +import org.apache.jackrabbit.core.query.ExecutableQuery; +import org.apache.jackrabbit.core.state.NodeState; +import org.apache.jackrabbit.core.NodeId; +import org.apache.jackrabbit.core.SessionImpl; +import org.apache.jackrabbit.core.ItemManager; +import org.apache.jackrabbit.spi.commons.query.qom.QueryObjectModelTree; +import org.apache.jackrabbit.uuid.UUID; + +/** + * SlowQueryHandler implements a dummy query handler for testing + * purpose. + */ +public class SlowQueryHandler extends AbstractQueryHandler { + + protected void doInit() throws IOException { + // sleep for 10 seconds then try to read from the item state manager + // the repository.xml is configured with a 5 second maxIdleTime + try { + Thread.sleep(10 * 1000); + } catch (InterruptedException e) { + // ignore + } + NodeId id = new NodeId(UUID.randomUUID()); + getContext().getItemStateManager().hasItemState(id); + } + + public void addNode(NodeState node) throws RepositoryException, IOException { + } + + public void deleteNode(NodeId id) throws IOException { + } + + public void close() throws IOException { + } + + public ExecutableQuery createExecutableQuery(SessionImpl session, + ItemManager itemMgr, String statement, + String language) + throws InvalidQueryException { + return null; + } + + public ExecutableQuery createExecutableQuery(SessionImpl session, + ItemManager itemMgr, + QueryObjectModelTree qomTree) + throws InvalidQueryException { + return null; + } +} Property changes on: src\test\java\org\apache\jackrabbit\core\query\lucene\SlowQueryHandler.java ___________________________________________________________________ Added: svn:eol-style + native Index: src/test/repository/repository.xml =================================================================== --- src/test/repository/repository.xml (revision 759860) +++ src/test/repository/repository.xml (working copy) @@ -72,7 +72,7 @@ - + + + + + + + + + + + + + + Property changes on: src\test\repository\workspaces\workspace-init-test\workspace.xml ___________________________________________________________________ Added: svn:eol-style + native