Index: src/main/java/org/apache/jackrabbit/core/config/ClusterConfig.java =================================================================== --- src/main/java/org/apache/jackrabbit/core/config/ClusterConfig.java (revision 676201) +++ src/main/java/org/apache/jackrabbit/core/config/ClusterConfig.java (working copy) @@ -38,6 +38,11 @@ private final JournalConfig jc; /** + * Create workspaces if they do not already exist + */ + private final boolean createWorkspaces; + + /** * Creates a new cluster configuration. * * @param id custom cluster node id @@ -44,10 +49,11 @@ * @param syncDelay syncDelay, in milliseconds * @param jc journal configuration */ - public ClusterConfig(String id, long syncDelay, JournalConfig jc) { + public ClusterConfig(String id, long syncDelay, JournalConfig jc, boolean createWorkspaces) { this.id = id; this.syncDelay = syncDelay; this.jc = jc; + this.createWorkspaces = createWorkspaces; } /** @@ -69,6 +75,15 @@ } /** + * Returns the createWorkspace configuration attribute value + * + * @return createWorkspace + */ + public boolean isCreateWorkspaces() { + return createWorkspaces; + } + + /** * Returns the journal configuration. * * @return journal configuration Index: src/main/java/org/apache/jackrabbit/core/config/RepositoryConfigurationParser.java =================================================================== --- src/main/java/org/apache/jackrabbit/core/config/RepositoryConfigurationParser.java (revision 676201) +++ src/main/java/org/apache/jackrabbit/core/config/RepositoryConfigurationParser.java (working copy) @@ -126,6 +126,9 @@ /** Name of the syncDelay configuration attribute. */ public static final String SYNC_DELAY_ATTRIBUTE = "syncDelay"; + /** Name of the createWorkspace configuration attribute. */ + public static final String CREATE_WORKSPACES_ATTRIBUTE = "createWorkspaces"; + /** Name of the default search index implementation class. */ public static final String DEFAULT_QUERY_HANDLER = "org.apache.jackrabbit.core.query.lucene.SearchIndex"; @@ -135,6 +138,8 @@ /** Default synchronization delay, in milliseconds. */ public static final String DEFAULT_SYNC_DELAY = "5000"; + + public static final String DEFAULT_CREATE_WORKSPACES = "false"; /** Name of the workspace specific security configuration element */ private static final String WSP_SECURITY_ELEMENT = "WorkspaceSecurity"; @@ -629,8 +634,11 @@ long syncDelay = Long.parseLong( getAttribute(element, SYNC_DELAY_ATTRIBUTE, DEFAULT_SYNC_DELAY)); + boolean createWorkspaces = Boolean.parseBoolean( + getAttribute(element, CREATE_WORKSPACES_ATTRIBUTE, DEFAULT_CREATE_WORKSPACES)); + JournalConfig jc = parseJournalConfig(element); - return new ClusterConfig(id, syncDelay, jc); + return new ClusterConfig(id, syncDelay, jc, createWorkspaces); } } return null; Index: src/main/java/org/apache/jackrabbit/core/RepositoryImpl.java =================================================================== --- src/main/java/org/apache/jackrabbit/core/RepositoryImpl.java (revision 676201) +++ src/main/java/org/apache/jackrabbit/core/RepositoryImpl.java (working copy) @@ -738,14 +738,16 @@ /** * Returns the {@link WorkspaceInfo} for the named workspace. - * - * @param workspaceName The name of the workspace whose {@link WorkspaceInfo} - * is to be returned. This must not be null. + * + * @param workspaceName + * The name of the workspace whose {@link WorkspaceInfo} is to be + * returned. This must not be null. * @return The {@link WorkspaceInfo} for the named workspace. This will * never be null. - * @throws IllegalStateException If this repository has already been - * shut down. - * @throws NoSuchWorkspaceException If the named workspace does not exist. + * @throws IllegalStateException + * If this repository has already been shut down. + * @throws NoSuchWorkspaceException + * If the named workspace does not exist. */ protected WorkspaceInfo getWorkspaceInfo(String workspaceName) throws IllegalStateException, NoSuchWorkspaceException { @@ -763,7 +765,8 @@ try { initWorkspace(wspInfo); } catch (RepositoryException e) { - log.error("Unable to initialize workspace '" + workspaceName + "'", e); + log.error("Unable to initialize workspace '" + workspaceName + "'", + e); throw new NoSuchWorkspaceException(workspaceName); } return wspInfo; @@ -770,6 +773,54 @@ } /** + * Makes sure that the workspace is ready to get external update + * + * @param workspaceName + * @param createIfDoesNotExist + * create workspace if workspace with specified name does not + * exist + * @throws RepositoryException + */ + protected void ensureWorkspaceReady(String workspaceName, + boolean createIfDoesNotExist) throws RepositoryException { + // check sanity of this instance + sanityCheck(); + + WorkspaceInfo wspInfo; + synchronized (wspInfos) { + wspInfo = (WorkspaceInfo) wspInfos.get(workspaceName); + if (wspInfo == null) { + if (createIfDoesNotExist) { + createWorkspaceExternal(workspaceName); + wspInfo = (WorkspaceInfo) wspInfos.get(workspaceName); + } else { + throw new NoSuchWorkspaceException(workspaceName); + } + } + } + + try { + initWorkspace(wspInfo); + } catch (RepositoryException e) { + log.error("Unable to initialize workspace '" + workspaceName + "'", + e); + throw new NoSuchWorkspaceException(workspaceName); + } + } + + /** + * Creates workspace as a result of external event (update events from other + * cluster node). This method provides way to detect new workspace creation + * triggered by receiving workspace related events from other nodes. + * + * @param workspaceName + * @throws RepositoryException + */ + protected void createWorkspaceExternal(String workspaceName) throws RepositoryException { + createWorkspace(workspaceName); + } + + /** * Creates a workspace with the given name. * * @param workspaceName name of the new workspace @@ -2156,9 +2207,11 @@ /** * {@inheritDoc} */ - public void updateEventsReady(String workspace) throws RepositoryException { + public void updateEventsReady(String workspace) + throws RepositoryException { + // toggle the initialization of some workspace - getWorkspaceInfo(workspace); + ensureWorkspaceReady(workspace, getClusterConfig().isCreateWorkspaces()); } /** Index: src/main/resources/org/apache/jackrabbit/core/config/repository-1.5.dtd =================================================================== --- src/main/resources/org/apache/jackrabbit/core/config/repository-1.5.dtd (revision 676201) +++ src/main/resources/org/apache/jackrabbit/core/config/repository-1.5.dtd (working copy) @@ -187,8 +187,9 @@ automatically detected. --> - +