Index: modeshape-jcr-api/src/main/java/org/modeshape/jcr/api/Repository.java =================================================================== --- modeshape-jcr-api/src/main/java/org/modeshape/jcr/api/Repository.java (revision 2198) +++ modeshape-jcr-api/src/main/java/org/modeshape/jcr/api/Repository.java (working copy) @@ -9,10 +9,12 @@ import java.util.Set; * Replicates JCR 2.0's Repository interface. */ public interface Repository extends javax.jcr.Repository { - - static final String REPOSITORY_NAME = "custom.rep.name"; - - /** + + static final String REPOSITORY_NAME = "custom.rep.name"; + + static final String REPOSITORY_WORKSPACES = "custom.rep.workspace.names"; + + /** * An immutable collection of "standard" descriptors, as defined in the JSR-283 specification. */ @SuppressWarnings( "deprecation" ) @@ -71,6 +73,4 @@ public interface Repository extends javax.jcr.Repository { REP_VENDOR_URL_DESC, REP_VERSION_DESC,}))); - - } Index: modeshape-jcr/src/main/java/org/modeshape/jcr/JcrRepository.java =================================================================== --- modeshape-jcr/src/main/java/org/modeshape/jcr/JcrRepository.java (revision 2198) +++ modeshape-jcr/src/main/java/org/modeshape/jcr/JcrRepository.java (working copy) @@ -37,6 +37,7 @@ import java.util.EnumMap; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; +import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Properties; @@ -402,7 +403,7 @@ public class JcrRepository implements Repository { } private final String sourceName; - private final Map descriptors; + private final Map descriptors = new HashMap(); private final ExecutionContext executionContext; private final RepositoryConnectionFactory connectionFactory; private final RepositoryNodeTypeManager repositoryTypeManager; @@ -611,7 +612,7 @@ public class JcrRepository implements Repository { } // Initialize required JCR descriptors. - this.descriptors = initializeDescriptors(executionContext.getValueFactories(), descriptors); + this.descriptors.putAll(initializeDescriptors(executionContext.getValueFactories(), descriptors)); // If the repository is to support searching ... if (Boolean.valueOf(this.options.get(Option.QUERY_EXECUTION_ENABLED)) && WORKSPACES_SHARE_SYSTEM_BRANCH) { @@ -728,6 +729,18 @@ public class JcrRepository implements Repository { // This observer picks up notification of changes to the system graph in a cluster. It's a NOP if there is no cluster. repositoryObservationManager.register(new SystemChangeObserver(Arrays.asList(new JcrSystemObserver[] { repositoryLockManager, namespaceObserver, repositoryTypeManager}))); + + // Make sure the workspace names are in the descriptor ... + updateWorkspaceNames(); + } + + protected void updateWorkspaceNames() { + ValueFactories factories = this.getExecutionContext().getValueFactories(); + List values = new LinkedList(); + for (String name : workspaceNames()) { + values.add(new JcrValue(factories, null, PropertyType.STRING, name)); + } + descriptors.put(Repository.REPOSITORY_WORKSPACES, values.toArray(new JcrValue[values.size()])); } protected void addWorkspace( String workspaceName, @@ -746,6 +759,7 @@ public class JcrRepository implements Repository { this.federatedSource.addWorkspace(workspaceName, projections, isDefault); } } + updateWorkspaceNames(); } /** @@ -779,6 +793,7 @@ public class JcrRepository implements Repository { } String actualName = graphWorkspace.getName(); addWorkspace(actualName, false); + updateWorkspaceNames(); } /** @@ -827,6 +842,7 @@ public class JcrRepository implements Repository { // And now destroy the workspace ... graph.destroyWorkspace().named(workspaceName); + updateWorkspaceNames(); } protected void initializeSystemContent( Graph systemGraph ) { @@ -1046,6 +1062,7 @@ public class JcrRepository implements Repository { * @see javax.jcr.Repository#getDescriptorKeys() */ public String[] getDescriptorKeys() { + Map descriptors = this.descriptors; return descriptors.keySet().toArray(new String[descriptors.size()]); } Index: modeshape-jcr/src/test/java/org/modeshape/jcr/JcrRepositoryTest.java =================================================================== --- modeshape-jcr/src/test/java/org/modeshape/jcr/JcrRepositoryTest.java (revision 2198) +++ modeshape-jcr/src/test/java/org/modeshape/jcr/JcrRepositoryTest.java (working copy) @@ -32,6 +32,7 @@ import java.security.AccessController; import java.security.PrivilegedExceptionAction; import java.util.Collections; import java.util.HashMap; +import java.util.HashSet; import java.util.Map; import java.util.Set; import java.util.UUID; @@ -39,6 +40,7 @@ import javax.jcr.Credentials; import javax.jcr.Repository; import javax.jcr.Session; import javax.jcr.SimpleCredentials; +import javax.jcr.ValueFormatException; import javax.security.auth.Subject; import javax.security.auth.login.LoginContext; import org.jboss.security.config.IDTrustConfiguration; @@ -201,6 +203,16 @@ public class JcrRepositoryTest { } @Test + public void shouldProvideRepositoryWorkspaceNamesDescriptor() throws ValueFormatException { + Set workspaceNames = repository.workspaceNames(); + Set descriptorValues = new HashSet(); + for (JcrValue value : repository.getDescriptorValues(org.modeshape.jcr.api.Repository.REPOSITORY_WORKSPACES)) { + descriptorValues.add(value.getString()); + } + assertThat(descriptorValues, is(workspaceNames)); + } + + @Test public void shouldProvideObserver() { assertThat(this.repository.getObserver(), is(notNullValue())); } @@ -283,8 +295,8 @@ public class JcrRepositoryTest { @Test public void shouldAllowLoginWithProperCredentials() throws Exception { repository.login(credentials); - repository.login(new JcrSecurityContextCredentials( - new MockSecurityContext(null, Collections.singleton(ModeShapeRoles.ADMIN)))); + repository.login(new JcrSecurityContextCredentials(new MockSecurityContext(null, + Collections.singleton(ModeShapeRoles.ADMIN)))); } @Test @@ -293,9 +305,9 @@ public class JcrRepositoryTest { assertThat(session, notNullValue()); session.logout(); session = repository.login(new JcrSecurityContextCredentials( - new MockSecurityContext( - null, - Collections.singleton(ModeShapeRoles.ADMIN))), + new MockSecurityContext( + null, + Collections.singleton(ModeShapeRoles.ADMIN))), (String)null); assertThat(session, notNullValue()); session.logout();