[dna-commits] DNA SVN: r1120 - in trunk: dna-jcr/src/test/java/org/jboss/dna/jcr and 2 other directories.

dna-commits at lists.jboss.org dna-commits at lists.jboss.org
Mon Jul 20 23:19:33 EDT 2009


Author: rhauch
Date: 2009-07-20 23:19:32 -0400 (Mon, 20 Jul 2009)
New Revision: 1120

Modified:
   trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrRepository.java
   trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrSession.java
   trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrWorkspace.java
   trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/AbstractJcrAccessTest.java
   trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/AbstractSessionTest.java
   trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/ImportExportTest.java
   trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/JcrRepositoryTest.java
   trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/RepositoryNodeTypeManagerTest.java
   trunk/docs/examples/gettingstarted/repositories/src/main/resources/configRepository.xml
   trunk/docs/examples/gettingstarted/repositories/src/test/java/org/jboss/example/dna/repository/RepositoryClientTest.java
Log:
DNA-392 All sessions in a repository should share the same /jcr:system content

Initial commit that changed to use the federated connector within a JcrRepository implementation, and that results in all JcrSession and JcrWorkspace instances created by that JcrRepository instance to have the exact same (projected) content for the 'jcr:system' branch.  All tests do pass.

Modified: trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrRepository.java
===================================================================
--- trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrRepository.java	2009-07-21 03:17:04 UTC (rev 1119)
+++ trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrRepository.java	2009-07-21 03:19:32 UTC (rev 1120)
@@ -28,9 +28,11 @@
 import java.security.AccessControlContext;
 import java.security.AccessControlException;
 import java.security.AccessController;
+import java.util.ArrayList;
 import java.util.Collections;
 import java.util.EnumMap;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import javax.jcr.Credentials;
@@ -49,8 +51,25 @@
 import org.jboss.dna.graph.ExecutionContext;
 import org.jboss.dna.graph.Graph;
 import org.jboss.dna.graph.JaasSecurityContext;
+import org.jboss.dna.graph.Subgraph;
+import org.jboss.dna.graph.connector.RepositoryConnection;
 import org.jboss.dna.graph.connector.RepositoryConnectionFactory;
+import org.jboss.dna.graph.connector.RepositoryContext;
+import org.jboss.dna.graph.connector.RepositorySource;
 import org.jboss.dna.graph.connector.RepositorySourceException;
+import org.jboss.dna.graph.connector.federation.FederatedRepositorySource;
+import org.jboss.dna.graph.connector.federation.Projection;
+import org.jboss.dna.graph.connector.federation.ProjectionParser;
+import org.jboss.dna.graph.connector.inmemory.InMemoryRepositorySource;
+import org.jboss.dna.graph.observe.Changes;
+import org.jboss.dna.graph.observe.Observer;
+import org.jboss.dna.graph.property.Name;
+import org.jboss.dna.graph.property.NamespaceRegistry;
+import org.jboss.dna.graph.property.Path;
+import org.jboss.dna.graph.property.PathFactory;
+import org.jboss.dna.graph.property.Property;
+import org.jboss.dna.graph.property.PropertyFactory;
+import org.jboss.dna.graph.property.basic.GraphNamespaceRegistry;
 import org.jboss.dna.graph.request.InvalidWorkspaceException;
 
 /**
@@ -161,6 +180,11 @@
     private final RepositoryConnectionFactory connectionFactory;
     private final RepositoryNodeTypeManager repositoryTypeManager;
     private final Map<Option, String> options;
+    private final RepositorySource systemSource;
+    private final Projection systemSourceProjection;
+    private final FederatedRepositorySource federatedSource;
+    private final Observer observer;
+    private final NamespaceRegistry persistentRegistry;
 
     /**
      * Creates a JCR repository that uses the supplied {@link RepositoryConnectionFactory repository connection factory} to
@@ -198,9 +222,6 @@
         CheckArg.isNotNull(executionContext, "executionContext");
         CheckArg.isNotNull(connectionFactory, "connectionFactory");
         CheckArg.isNotNull(repositorySourceName, "repositorySourceName");
-        this.executionContext = executionContext;
-        this.connectionFactory = connectionFactory;
-        this.sourceName = repositorySourceName;
         Map<String, String> modifiableDescriptors;
         if (descriptors == null) {
             modifiableDescriptors = new HashMap<String, String>();
@@ -234,9 +255,53 @@
         modifiableDescriptors.put(Repository.SPEC_VERSION_DESC, "1.0");
         this.descriptors = Collections.unmodifiableMap(modifiableDescriptors);
 
-        this.repositoryTypeManager = new RepositoryNodeTypeManager(this.executionContext);
+        // Set up the options ...
+        if (options == null) {
+            this.options = DEFAULT_OPTIONS;
+        } else {
+            // Initialize with defaults, then add supplied options ...
+            EnumMap<Option, String> localOptions = new EnumMap<Option, String>(DEFAULT_OPTIONS);
+            localOptions.putAll(options);
+            this.options = Collections.unmodifiableMap(localOptions);
+        }
 
+        // Initialize the observer, which receives events from all repository sources ...
+        this.observer = new RepositoryObserver();
+
+        // Create the in-memory repository source that we'll use for the "/jcr:system" branch in this repository.
+        // All workspaces will be set up with a federation connector that projects this system repository into
+        // "/jcr:system", and all other content is projected to the repositories actual source (and workspace).
+        // (The federation connector refers to this configuration as an "offset mirror".)
+        InMemoryRepositorySource systemSource = new InMemoryRepositorySource();
+        String systemWorkspaceName = "jcr:system";
+        String systemSourceName = "jcr:system source";
+        systemSource.setName(systemSourceName);
+        systemSource.setDefaultWorkspaceName(systemWorkspaceName);
+        this.systemSource = systemSource;
+        this.connectionFactory = new ConnectionFactoryWithSystem(connectionFactory, this.systemSource);
+
+        // Set up the "/jcr:system" branch ...
+        Graph systemGraph = Graph.create(this.systemSource, executionContext);
+        systemGraph.useWorkspace(systemWorkspaceName);
+        initializeSystemContent(systemGraph);
+        this.sourceName = repositorySourceName;
+
+        // Create the namespace registry and corresponding execution context.
+        // Note that this persistent registry has direct access to the system workspace.
+        Name uriProperty = DnaLexicon.NAMESPACE_URI;
+        PathFactory pathFactory = executionContext.getValueFactories().getPathFactory();
+        Path systemPath = pathFactory.create(JcrLexicon.SYSTEM);
+        Path namespacesPath = pathFactory.create(systemPath, DnaLexicon.NAMESPACES);
+        PropertyFactory propertyFactory = executionContext.getPropertyFactory();
+        Property namespaceType = propertyFactory.create(JcrLexicon.PRIMARY_TYPE, DnaLexicon.NAMESPACE);
+
+        // Now create the registry implementation ...
+        this.persistentRegistry = new GraphNamespaceRegistry(systemGraph, namespacesPath, uriProperty, namespaceType);
+        this.executionContext = executionContext.with(persistentRegistry);
+
+        // Set up the repository type manager ...
         try {
+            this.repositoryTypeManager = new RepositoryNodeTypeManager(this.executionContext);
             this.repositoryTypeManager.registerNodeTypes(new CndNodeTypeSource(new String[] {
                 "/org/jboss/dna/jcr/jsr_170_builtins.cnd", "/org/jboss/dna/jcr/dna_builtins.cnd"}));
         } catch (RepositoryException re) {
@@ -246,17 +311,47 @@
             ioe.printStackTrace();
             throw new IllegalStateException("Could not access node type definition files", ioe);
         }
+        if (Boolean.valueOf(this.options.get(Option.PROJECT_NODE_TYPES))) {
+            // Note that the node types are written directly to the system workspace.
+            Path parentOfTypeNodes = pathFactory.create(systemPath, JcrLexicon.NODE_TYPES);
+            this.repositoryTypeManager.projectOnto(systemGraph, parentOfTypeNodes);
+        }
 
-        if (options == null) {
-            this.options = DEFAULT_OPTIONS;
-        } else {
-            // Initialize with defaults, then add supplied options ...
-            EnumMap<Option, String> localOptions = new EnumMap<Option, String>(DEFAULT_OPTIONS);
-            localOptions.putAll(options);
-            this.options = Collections.unmodifiableMap(localOptions);
-        }
+        // Create the projection for the system repository ...
+        ProjectionParser projectionParser = ProjectionParser.getInstance();
+        String rule = "/jcr:system => /jcr:system";
+        Projection.Rule[] systemProjectionRules = projectionParser.rulesFromString(this.executionContext, rule);
+        this.systemSourceProjection = new Projection(systemSourceName, systemWorkspaceName, true, systemProjectionRules);
+
+        // Define the federated repository source. Use the same name as the repository, since this federated source
+        // will not be in the connection factory ...
+        this.federatedSource = new FederatedRepositorySource();
+        this.federatedSource.setName("JCR " + repositorySourceName);
+        this.federatedSource.initialize(new FederatedRepositoryContext(this.connectionFactory));
     }
 
+    protected void initializeSystemContent( Graph systemGraph ) {
+        // Make sure the "/jcr:system" node exists ...
+        ExecutionContext context = systemGraph.getContext();
+        PathFactory pathFactory = context.getValueFactories().getPathFactory();
+        Path systemPath = pathFactory.create(pathFactory.createRootPath(), JcrLexicon.SYSTEM);
+        Property systemPrimaryType = context.getPropertyFactory().create(JcrLexicon.PRIMARY_TYPE, DnaLexicon.SYSTEM);
+        systemGraph.create(systemPath, systemPrimaryType).ifAbsent().and();
+
+        // Right now, the other nodes will be created as needed
+    }
+
+    Graph createWorkspaceGraph( String workspaceName ) {
+        Graph graph = Graph.create(this.federatedSource, this.executionContext);
+        graph.useWorkspace(workspaceName);
+        return graph;
+    }
+
+    Graph createSystemGraph() {
+        // The default workspace should be the system workspace ...
+        return Graph.create(this.systemSource, this.executionContext);
+    }
+
     /**
      * Returns the repository-level node type manager
      * 
@@ -279,19 +374,32 @@
      * Get the name of the repository source that this repository is using.
      * 
      * @return the name of the RepositorySource
-     * @see #getConnectionFactory()
      */
     String getRepositorySourceName() {
         return sourceName;
     }
 
     /**
-     * Get the connection factory that this repository is using.
+     * @return executionContext
+     */
+    ExecutionContext getExecutionContext() {
+        return executionContext;
+    }
+
+    /**
+     * @return persistentRegistry
+     */
+    NamespaceRegistry getPersistentRegistry() {
+        return persistentRegistry;
+    }
+
+    /**
+     * The observer to which all source events are sent.
      * 
-     * @return the connection factory; never null
+     * @return the current observer, or null if there is no observer
      */
-    RepositoryConnectionFactory getConnectionFactory() {
-        return this.connectionFactory;
+    Observer getObserver() {
+        return observer;
     }
 
     /**
@@ -412,7 +520,8 @@
             }
         }
 
-        // Ensure valid workspace name
+        // Ensure valid workspace name by talking directly to the source ...
+        boolean isDefault = false;
         Graph graph = Graph.create(sourceName, connectionFactory, executionContext);
         if (workspaceName == null) {
             try {
@@ -421,15 +530,19 @@
             } catch (RepositorySourceException e) {
                 throw new RepositoryException(JcrI18n.errorObtainingDefaultWorkspaceName.text(sourceName, e.getMessage()), e);
             }
+            isDefault = true;
         } else {
+            // There is a non-null workspace name ...
             try {
                 // Verify that the workspace exists (or can be created) ...
                 Set<String> workspaces = graph.getWorkspaces();
                 if (!workspaces.contains(workspaceName)) {
+                    // Make sure there isn't a federated workspace ...
+                    this.federatedSource.removeWorkspace(workspaceName);
                     // Per JCR 1.0 6.1.1, if the workspaceName is not recognized, a NoSuchWorkspaceException is thrown
                     throw new NoSuchWorkspaceException(JcrI18n.workspaceNameIsInvalid.text(sourceName, workspaceName));
                 }
-                
+
                 graph.useWorkspace(workspaceName);
             } catch (InvalidWorkspaceException e) {
                 throw new NoSuchWorkspaceException(JcrI18n.workspaceNameIsInvalid.text(sourceName, workspaceName), e);
@@ -439,17 +552,28 @@
             }
         }
 
+        synchronized (this.federatedSource) {
+            if (!this.federatedSource.hasWorkspace(workspaceName)) {
+                // Add the workspace to the federated source ...
+                ProjectionParser projectionParser = ProjectionParser.getInstance();
+                Projection.Rule[] mirrorRules = projectionParser.rulesFromString(this.executionContext, "/ => /");
+                List<Projection> projections = new ArrayList<Projection>(2);
+                projections.add(new Projection(sourceName, workspaceName, false, mirrorRules));
+                projections.add(this.systemSourceProjection);
+                this.federatedSource.addWorkspace(workspaceName, projections, isDefault);
+            }
+        }
+
         // Create the workspace, which will create its own session ...
         sessionAttributes = Collections.unmodifiableMap(sessionAttributes);
         JcrWorkspace workspace = new JcrWorkspace(this, workspaceName, execContext, sessionAttributes);
-        
-        JcrSession session = (JcrSession) workspace.getSession();
-        
+
+        JcrSession session = (JcrSession)workspace.getSession();
+
         // Need to make sure that the user has access to this session
         try {
             session.checkPermission(workspaceName, null, JcrSession.JCR_READ_PERMISSION);
-        }
-        catch (AccessControlException ace) {
+        } catch (AccessControlException ace) {
             throw new NoSuchWorkspaceException(JcrI18n.workspaceNameIsInvalid.text(sourceName, workspaceName));
         }
         return session;
@@ -464,4 +588,84 @@
     String getName() {
         return this.sourceName;
     }
+
+    protected class FederatedRepositoryContext implements RepositoryContext {
+        private final RepositoryConnectionFactory connectionFactory;
+
+        protected FederatedRepositoryContext( RepositoryConnectionFactory nonFederatingConnectionFactory ) {
+            this.connectionFactory = nonFederatingConnectionFactory;
+        }
+
+        /**
+         * {@inheritDoc}
+         * 
+         * @see org.jboss.dna.graph.connector.RepositoryContext#getConfiguration(int)
+         */
+        public Subgraph getConfiguration( int depth ) {
+            throw new UnsupportedOperationException();
+        }
+
+        /**
+         * {@inheritDoc}
+         * 
+         * @see org.jboss.dna.graph.connector.RepositoryContext#getExecutionContext()
+         */
+        public ExecutionContext getExecutionContext() {
+            return JcrRepository.this.getExecutionContext();
+        }
+
+        /**
+         * {@inheritDoc}
+         * 
+         * @see org.jboss.dna.graph.connector.RepositoryContext#getObserver()
+         */
+        public Observer getObserver() {
+            return JcrRepository.this.getObserver();
+        }
+
+        /**
+         * {@inheritDoc}
+         * 
+         * @see org.jboss.dna.graph.connector.RepositoryContext#getRepositoryConnectionFactory()
+         */
+        public RepositoryConnectionFactory getRepositoryConnectionFactory() {
+            return connectionFactory;
+        }
+    }
+
+    protected class ConnectionFactoryWithSystem implements RepositoryConnectionFactory {
+        private final RepositoryConnectionFactory delegate;
+        private final RepositorySource system;
+
+        protected ConnectionFactoryWithSystem( RepositoryConnectionFactory delegate,
+                                               RepositorySource source ) {
+            assert delegate != null;
+            this.delegate = delegate;
+            this.system = source;
+        }
+
+        /**
+         * {@inheritDoc}
+         * 
+         * @see org.jboss.dna.graph.connector.RepositoryConnectionFactory#createConnection(java.lang.String)
+         */
+        public RepositoryConnection createConnection( String sourceName ) throws RepositorySourceException {
+            if (this.system.getName().equals(sourceName)) {
+                return this.system.getConnection();
+            }
+            return delegate.createConnection(sourceName);
+        }
+    }
+
+    protected class RepositoryObserver implements Observer {
+        /**
+         * {@inheritDoc}
+         * 
+         * @see org.jboss.dna.graph.observe.Observer#notify(org.jboss.dna.graph.observe.Changes)
+         */
+        public void notify( Changes changes ) {
+            // does nothing at the moment, but eventually will fire to all of the listeners on the appropriate sessions
+        }
+    }
+
 }

Modified: trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrSession.java
===================================================================
--- trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrSession.java	2009-07-21 03:17:04 UTC (rev 1119)
+++ trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrSession.java	2009-07-21 03:19:32 UTC (rev 1120)
@@ -156,10 +156,7 @@
         this.rootPath = this.executionContext.getValueFactories().getPathFactory().createRootPath();
 
         // Set up the graph to use for this session (which uses the session's namespace registry and context) ...
-        this.graph = Graph.create(this.repository.getRepositorySourceName(),
-                                  this.repository.getConnectionFactory(),
-                                  this.executionContext);
-        this.graph.useWorkspace(workspace.getName());
+        this.graph = repository.createWorkspaceGraph(workspace.getName());
 
         this.cache = new SessionCache(this);
         this.isLive = true;

Modified: trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrWorkspace.java
===================================================================
--- trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrWorkspace.java	2009-07-21 03:17:04 UTC (rev 1119)
+++ trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrWorkspace.java	2009-07-21 03:19:32 UTC (rev 1120)
@@ -62,17 +62,13 @@
 import org.jboss.dna.graph.property.Name;
 import org.jboss.dna.graph.property.Path;
 import org.jboss.dna.graph.property.PathFactory;
-import org.jboss.dna.graph.property.Property;
-import org.jboss.dna.graph.property.PropertyFactory;
 import org.jboss.dna.graph.property.ValueFormatException;
-import org.jboss.dna.graph.property.basic.GraphNamespaceRegistry;
 import org.jboss.dna.graph.request.InvalidWorkspaceException;
 import org.jboss.dna.graph.request.ReadBranchRequest;
 import org.jboss.dna.graph.session.GraphSession;
 import org.jboss.dna.graph.session.GraphSession.Node;
 import org.jboss.dna.jcr.JcrContentHandler.EnclosingSAXException;
 import org.jboss.dna.jcr.JcrContentHandler.SaveMode;
-import org.jboss.dna.jcr.JcrRepository.Option;
 import org.jboss.dna.jcr.SessionCache.JcrNodePayload;
 import org.jboss.dna.jcr.SessionCache.JcrPropertyPayload;
 import org.xml.sax.ContentHandler;
@@ -102,8 +98,8 @@
 
     /**
      * The reference to the {@link JcrRepository} instance that owns this {@link Workspace} instance. Very few methods on this
-     * repository object are used; mainly {@link JcrRepository#getConnectionFactory()} and
-     * {@link JcrRepository#getRepositorySourceName()}.
+     * repository object are used; mainly {@link JcrRepository#createWorkspaceGraph(String)},
+     * {@link JcrRepository#getPersistentRegistry()} and {@link JcrRepository#getRepositorySourceName()}.
      */
     private final JcrRepository repository;
 
@@ -149,48 +145,46 @@
         this.name = workspaceName;
         this.repository = repository;
 
-        // Set up the execution context for this workspace, which should use the namespace registry that persists
-        // the namespaces in the graph ...
-        Graph namespaceGraph = Graph.create(this.repository.getRepositorySourceName(),
-                                            this.repository.getConnectionFactory(),
-                                            context);
-        namespaceGraph.useWorkspace(workspaceName);
+        // // Set up the execution context for this workspace, which should use the namespace registry that persists
+        // // the namespaces in the graph ...
+        // Graph namespaceGraph = Graph.create(this.repository.getRepositorySourceName(),
+        // this.repository.getConnectionFactory(),
+        // context);
+        // namespaceGraph.useWorkspace(workspaceName);
+        //
+        // // Make sure the "/jcr:system" node exists ...
+        // PathFactory pathFactory = context.getValueFactories().getPathFactory();
+        // Path root = pathFactory.createRootPath();
+        // Path systemPath = pathFactory.create(root, JcrLexicon.SYSTEM);
+        // Property systemPrimaryType = context.getPropertyFactory().create(JcrLexicon.PRIMARY_TYPE, DnaLexicon.SYSTEM);
+        // namespaceGraph.create(systemPath, systemPrimaryType).ifAbsent().and();
+        //
+        // Name uriProperty = DnaLexicon.NAMESPACE_URI;
+        // Path namespacesPath = pathFactory.create(systemPath, DnaLexicon.NAMESPACES);
+        // PropertyFactory propertyFactory = context.getPropertyFactory();
+        // Property namespaceType = propertyFactory.create(JcrLexicon.PRIMARY_TYPE, DnaLexicon.NAMESPACE);
+        // org.jboss.dna.graph.property.NamespaceRegistry persistentRegistry = new GraphNamespaceRegistry(namespaceGraph,
+        // namespacesPath,
+        // uriProperty, namespaceType);
+        this.context = context;
 
-        // Make sure the "/jcr:system" node exists ...
-        PathFactory pathFactory = context.getValueFactories().getPathFactory();
-        Path root = pathFactory.createRootPath();
-        Path systemPath = pathFactory.create(root, JcrLexicon.SYSTEM);
-        Property systemPrimaryType = context.getPropertyFactory().create(JcrLexicon.PRIMARY_TYPE, DnaLexicon.SYSTEM);
-        namespaceGraph.create(systemPath, systemPrimaryType).ifAbsent().and();
+        // Now create a graph for the session ...
+        this.graph = this.repository.createWorkspaceGraph(workspaceName);
 
-        Name uriProperty = DnaLexicon.NAMESPACE_URI;
-        Path namespacesPath = pathFactory.create(systemPath, DnaLexicon.NAMESPACES);
-        PropertyFactory propertyFactory = context.getPropertyFactory();
-        Property namespaceType = propertyFactory.create(JcrLexicon.PRIMARY_TYPE, DnaLexicon.NAMESPACE);
-        org.jboss.dna.graph.property.NamespaceRegistry persistentRegistry = new GraphNamespaceRegistry(namespaceGraph,
-                                                                                                       namespacesPath,
-                                                                                                       uriProperty, namespaceType);
-        this.context = context.with(persistentRegistry);
-
-        // Now create a graph with this new execution context ...
-        this.graph = Graph.create(this.repository.getRepositorySourceName(), this.repository.getConnectionFactory(), this.context);
-        this.graph.useWorkspace(workspaceName);
-
         // Set up the session for this workspace ...
         this.session = new JcrSession(this.repository, this, this.context, sessionAttributes);
 
         // This must be initialized after the session
-        RepositoryNodeTypeManager repoTypeManager = repository.getRepositoryTypeManager();
-        this.nodeTypeManager = new JcrNodeTypeManager(session, repoTypeManager);
+        this.nodeTypeManager = new JcrNodeTypeManager(session, this.repository.getRepositoryTypeManager());
         this.queryManager = new JcrQueryManager(this.session);
 
-        if (Boolean.valueOf(repository.getOptions().get(Option.PROJECT_NODE_TYPES))) {
-            Path parentOfTypeNodes = context.getValueFactories().getPathFactory().create(systemPath, JcrLexicon.NODE_TYPES);
-            repoTypeManager.projectOnto(this.graph, parentOfTypeNodes);
-        }
-
+        // if (Boolean.valueOf(repository.getOptions().get(Option.PROJECT_NODE_TYPES))) {
+        // Path parentOfTypeNodes = context.getValueFactories().getPathFactory().create(systemPath, JcrLexicon.NODE_TYPES);
+        // repoTypeManager.projectOnto(this.graph, parentOfTypeNodes);
+        // }
+        //
         // Set up and initialize the persistent JCR namespace registry ...
-        this.workspaceRegistry = new JcrNamespaceRegistry(persistentRegistry, this.session);
+        this.workspaceRegistry = new JcrNamespaceRegistry(this.repository.getPersistentRegistry(), this.session);
 
     }
 

Modified: trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/AbstractJcrAccessTest.java
===================================================================
--- trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/AbstractJcrAccessTest.java	2009-07-21 03:17:04 UTC (rev 1119)
+++ trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/AbstractJcrAccessTest.java	2009-07-21 03:19:32 UTC (rev 1120)
@@ -32,7 +32,6 @@
 import javax.jcr.NodeIterator;
 import org.jboss.dna.common.statistic.Stopwatch;
 import org.jboss.dna.graph.ExecutionContext;
-import org.jboss.dna.graph.Graph;
 import org.jboss.dna.graph.MockSecurityContext;
 import org.jboss.dna.graph.SecurityContext;
 import org.jboss.dna.graph.connector.RepositoryConnection;
@@ -53,7 +52,7 @@
     private InMemoryRepositorySource source;
     private JcrSession session;
     private JcrRepository repository;
-    
+
     @Before
     public void beforeEach() throws Exception {
         MockitoAnnotations.initMocks(this);
@@ -70,13 +69,6 @@
         // Register the test namespace
         context.getNamespaceRegistry().register(TestLexicon.Namespace.PREFIX, TestLexicon.Namespace.URI);
 
-        // Set up the initial content ...
-        Graph graph = Graph.create(source, context);
-
-        // Make sure the path to the namespaces exists ...
-        graph.create("/jcr:system").and(); // .and().create("/jcr:system/dna:namespaces");
-        graph.set("jcr:primaryType").on("/jcr:system").to(DnaLexicon.SYSTEM);
-
         // Stub out the connection factory ...
         RepositoryConnectionFactory connectionFactory = new RepositoryConnectionFactory() {
             /**
@@ -92,8 +84,9 @@
 
         repository = new JcrRepository(context, connectionFactory, "unused");
 
-        SecurityContext mockSecurityContext = new MockSecurityContext("testuser", Collections.singleton(JcrSession.DNA_WRITE_PERMISSION));
-        session = (JcrSession) repository.login(new SecurityContextCredentials(mockSecurityContext));
+        SecurityContext mockSecurityContext = new MockSecurityContext("testuser",
+                                                                      Collections.singleton(JcrSession.DNA_WRITE_PERMISSION));
+        session = (JcrSession)repository.login(new SecurityContextCredentials(mockSecurityContext));
     }
 
     @After
@@ -102,34 +95,35 @@
             session.logout();
         }
     }
-    
+
     protected JcrSession session() {
         return this.session;
     }
-    
-    private String getRandomString(int length) {
+
+    private String getRandomString( int length ) {
         StringBuffer buff = new StringBuffer(length);
-        
+
         for (int i = 0; i < length; i++) {
-            buff.append((char) ((Math.random() *26) + 'a'));
+            buff.append((char)((Math.random() * 26) + 'a'));
         }
-        
+
         return buff.toString();
     }
-    
-    private int createChildren(Node parent, int numProperties, int width, int depth) 
-        throws Exception
-    {
+
+    private int createChildren( Node parent,
+                                int numProperties,
+                                int width,
+                                int depth ) throws Exception {
         if (depth < 1) {
             return 0;
-            
+
         }
 
         int count = width;
-        
+
         for (int i = 0; i < width; i++) {
             Node newNode = parent.addNode(getRandomString(9), "nt:unstructured");
-            
+
             for (int j = 0; j < numProperties; j++) {
                 newNode.setProperty(getRandomString(8), getRandomString(16));
             }
@@ -138,7 +132,7 @@
         }
         return count;
     }
-    
+
     protected int createSubgraph( JcrSession session,
                                   String initialPath,
                                   int depth,
@@ -147,9 +141,7 @@
                                   boolean oneBatch,
                                   Stopwatch stopwatch,
                                   PrintStream output,
-                                  String description )
-        throws Exception
-    {
+                                  String description ) throws Exception {
         // Calculate the number of nodes that we'll created, but subtract 1 since it doesn't create the root
         long totalNumber = calculateTotalNumberOfNodesInTree(numberOfChildrenPerNode, depth, false);
         if (initialPath == null) initialPath = "";
@@ -160,22 +152,18 @@
 
         if (output != null) output.println(description + " (" + totalNumber + " nodes):");
         long totalNumberCreated = 0;
-        
+
         PathFactory pathFactory = session.getExecutionContext().getValueFactories().getPathFactory();
         Node parentNode = session.getNode(pathFactory.create(initialPath));
-        
+
         if (stopwatch != null) stopwatch.start();
 
-        totalNumberCreated += createChildren(parentNode,
-                                             numberOfPropertiesPerNode,
-                                             numberOfChildrenPerNode,
-                                             depth);
+        totalNumberCreated += createChildren(parentNode, numberOfPropertiesPerNode, numberOfChildrenPerNode, depth);
 
         assertThat(totalNumberCreated, is(totalNumber));
 
         session.save();
 
-        
         if (stopwatch != null) {
             stopwatch.stop();
             if (output != null) {
@@ -187,16 +175,14 @@
     }
 
     protected int traverseSubgraph( JcrSession session,
-                                  String initialPath,
-                                  int depth,
-                                  int numberOfChildrenPerNode,
-                                  int numberOfPropertiesPerNode,
-                                  boolean oneBatch,
-                                  Stopwatch stopwatch,
-                                  PrintStream output,
-                                  String description )
-        throws Exception
-    {
+                                    String initialPath,
+                                    int depth,
+                                    int numberOfChildrenPerNode,
+                                    int numberOfPropertiesPerNode,
+                                    boolean oneBatch,
+                                    Stopwatch stopwatch,
+                                    PrintStream output,
+                                    String description ) throws Exception {
         // Calculate the number of nodes that we'll created, but subtract 1 since it doesn't create the root
         long totalNumber = calculateTotalNumberOfNodesInTree(numberOfChildrenPerNode, depth, false);
         if (initialPath == null) initialPath = "";
@@ -207,10 +193,10 @@
 
         if (output != null) output.println(description + " (" + totalNumber + " nodes):");
         long totalNumberTraversed = 0;
-        
+
         PathFactory pathFactory = session.getExecutionContext().getValueFactories().getPathFactory();
         Node parentNode = session.getNode(pathFactory.create(initialPath));
-        
+
         if (stopwatch != null) stopwatch.start();
 
         totalNumberTraversed += traverseChildren(parentNode);
@@ -219,7 +205,6 @@
 
         session.save();
 
-        
         if (stopwatch != null) {
             stopwatch.stop();
             if (output != null) {
@@ -230,20 +215,20 @@
 
     }
 
-    protected int traverseChildren(Node parentNode) throws Exception {
+    protected int traverseChildren( Node parentNode ) throws Exception {
 
         int childCount = 0;
         NodeIterator children = parentNode.getNodes();
 
         while (children.hasNext()) {
             childCount++;
-            
+
             childCount += traverseChildren(children.nextNode());
         }
-        
+
         return childCount;
     }
-    
+
     protected String getTotalAndAverageDuration( Stopwatch stopwatch,
                                                  long numNodes ) {
         long totalDurationInMilliseconds = TimeUnit.NANOSECONDS.toMillis(stopwatch.getTotalDuration().longValue());
@@ -269,7 +254,5 @@
         }
         return countRoot ? totalNumber : totalNumber - 1;
     }
-    
-    
 
 }

Modified: trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/AbstractSessionTest.java
===================================================================
--- trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/AbstractSessionTest.java	2009-07-21 03:17:04 UTC (rev 1119)
+++ trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/AbstractSessionTest.java	2009-07-21 03:19:32 UTC (rev 1120)
@@ -23,6 +23,7 @@
  */
 package org.jboss.dna.jcr;
 
+import static org.mockito.Matchers.anyString;
 import static org.mockito.Mockito.stub;
 import java.io.IOException;
 import java.util.Collections;
@@ -40,9 +41,12 @@
 import org.jboss.dna.graph.connector.RepositorySourceException;
 import org.jboss.dna.graph.connector.inmemory.InMemoryRepositorySource;
 import org.jboss.dna.graph.property.NamespaceRegistry;
+import org.jboss.dna.graph.property.PathFactory;
 import org.jboss.dna.jcr.nodetype.NodeTypeTemplate;
 import org.mockito.MockitoAnnotations;
 import org.mockito.MockitoAnnotations.Mock;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
 
 /**
  * Abstract test class that sets up a working JcrSession environment, albeit with a mocked JcrRepository.
@@ -80,9 +84,18 @@
         context = new ExecutionContext();
         // Register the test namespace
         context.getNamespaceRegistry().register(TestLexicon.Namespace.PREFIX, TestLexicon.Namespace.URI);
+        PathFactory pathFactory = context.getValueFactories().getPathFactory();
 
         // Set up the initial content ...
         graph = Graph.create(source, context);
+
+        // Make sure the path to the namespaces exists ...
+        graph.create("/jcr:system").and(); // .and().create("/jcr:system/dna:namespaces");
+        graph.set("jcr:primaryType").on("/jcr:system").to(DnaLexicon.SYSTEM);
+
+        graph.create("/jcr:system/dna:namespaces").and();
+        graph.set("jcr:primaryType").on("/jcr:system/dna:namespaces").to(DnaLexicon.NAMESPACES);
+
         initializeContent();
 
         // Stub out the connection factory ...
@@ -112,10 +125,16 @@
             ioe.printStackTrace();
             throw new IllegalStateException("Could not access node type definition files", ioe);
         }
+        this.repoTypeManager.projectOnto(graph, pathFactory.create("/jcr:system/jcr:nodeTypes"));
 
         stub(repository.getRepositoryTypeManager()).toReturn(repoTypeManager);
         stub(repository.getRepositorySourceName()).toReturn(repositorySourceName);
-        stub(repository.getConnectionFactory()).toReturn(connectionFactory);
+        stub(repository.getPersistentRegistry()).toReturn(context.getNamespaceRegistry());
+        stub(repository.createWorkspaceGraph(anyString())).toAnswer(new Answer<Graph>() {
+            public Graph answer( InvocationOnMock invocation ) throws Throwable {
+                return graph;
+            }
+        });
 
         initializeOptions();
         stub(repository.getOptions()).toReturn(options);

Modified: trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/ImportExportTest.java
===================================================================
--- trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/ImportExportTest.java	2009-07-21 03:17:04 UTC (rev 1119)
+++ trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/ImportExportTest.java	2009-07-21 03:19:32 UTC (rev 1120)
@@ -31,7 +31,6 @@
 import javax.jcr.ImportUUIDBehavior;
 import javax.jcr.Node;
 import org.jboss.dna.graph.ExecutionContext;
-import org.jboss.dna.graph.Graph;
 import org.jboss.dna.graph.MockSecurityContext;
 import org.jboss.dna.graph.SecurityContext;
 import org.jboss.dna.graph.connector.RepositoryConnection;
@@ -76,20 +75,8 @@
         // Register the test namespace
         context.getNamespaceRegistry().register(TestLexicon.Namespace.PREFIX, TestLexicon.Namespace.URI);
 
-        // Set up the initial content ...
-        Graph graph = Graph.create(source, context);
-
-        // Make sure the path to the namespaces exists ...
-        graph.create("/jcr:system").and(); // .and().create("/jcr:system/dna:namespaces");
-        graph.set("jcr:primaryType").on("/jcr:system").to(DnaLexicon.SYSTEM);
-
         // Stub out the connection factory ...
         RepositoryConnectionFactory connectionFactory = new RepositoryConnectionFactory() {
-            /**
-             * {@inheritDoc}
-             * 
-             * @see org.jboss.dna.graph.connector.RepositoryConnectionFactory#createConnection(java.lang.String)
-             */
             @SuppressWarnings( "synthetic-access" )
             public RepositoryConnection createConnection( String sourceName ) throws RepositorySourceException {
                 return source.getConnection();
@@ -157,6 +144,7 @@
     public void shouldImportExportEscapedXmlCharactersInSystemViewUsingWorkspace() throws Exception {
         String testName = "importExportEscapedXmlCharacters";
         Node rootNode = session.getRootNode();
+        System.out.println(session);
         Node sourceNode = rootNode.addNode(testName + "Source", "nt:unstructured");
         Node targetNode = rootNode.addNode(testName + "Target", "nt:unstructured");
 

Modified: trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/JcrRepositoryTest.java
===================================================================
--- trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/JcrRepositoryTest.java	2009-07-21 03:17:04 UTC (rev 1119)
+++ trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/JcrRepositoryTest.java	2009-07-21 03:19:32 UTC (rev 1120)
@@ -33,6 +33,7 @@
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.Map;
+import java.util.UUID;
 import javax.jcr.Credentials;
 import javax.jcr.Repository;
 import javax.jcr.Session;
@@ -42,12 +43,14 @@
 import org.jboss.dna.graph.ExecutionContext;
 import org.jboss.dna.graph.Graph;
 import org.jboss.dna.graph.MockSecurityContext;
+import org.jboss.dna.graph.Node;
 import org.jboss.dna.graph.JaasSecurityContext.UserPasswordCallbackHandler;
 import org.jboss.dna.graph.connector.RepositoryConnection;
 import org.jboss.dna.graph.connector.RepositoryConnectionFactory;
 import org.jboss.dna.graph.connector.RepositorySourceException;
 import org.jboss.dna.graph.connector.inmemory.InMemoryRepositorySource;
 import org.jboss.security.config.IDTrustConfiguration;
+import org.junit.After;
 import org.junit.Before;
 import org.junit.BeforeClass;
 import org.junit.Test;
@@ -55,7 +58,6 @@
 import org.mockito.MockitoAnnotations;
 
 /**
- * @author jverhaeg
  */
 public class JcrRepositoryTest {
 
@@ -66,6 +68,9 @@
     private Map<String, String> descriptors;
     private RepositoryConnectionFactory connectionFactory;
     private Credentials credentials;
+    private Graph sourceGraph;
+    private Graph systemGraph;
+    private JcrSession session;
 
     @BeforeClass
     public static void beforeClass() {
@@ -106,15 +111,28 @@
             }
         };
 
-        // Make sure the path to the namespaces exists ...
-        Graph graph = Graph.create(source, context);
-        graph.create("/jcr:system").and().create("/jcr:system/dna:namespaces");
-
         // Set up the repository ...
         descriptors = new HashMap<String, String>();
         repository = new JcrRepository(context, connectionFactory, sourceName, descriptors, null);
+
+        // Set up the graph that goes directly to the source ...
+        sourceGraph = Graph.create(source, context);
+
+        // Set up the graph that goes directly to the system source ...
+        systemGraph = repository.createSystemGraph();
     }
 
+    @After
+    public void afterEach() {
+        if (session != null) {
+            try {
+                session.logout();
+            } finally {
+                session = null;
+            }
+        }
+    }
+
     @Test
     public void shouldAllowNullDescriptors() {
         new JcrRepository(context, connectionFactory, sourceName, null, null);
@@ -260,6 +278,67 @@
         });
     }
 
+    @Test
+    public void shouldHaveRootNode() throws Exception {
+        session = createSession();
+        javax.jcr.Node root = session.getRootNode();
+        String uuid = root.getUUID();
+
+        // Get the root via the direct graph ...
+        Node dnaRoot = sourceGraph.getNodeAt("/");
+        UUID dnaRootUuid = dnaRoot.getLocation().getUuid();
+
+        // They should have the same UUID ...
+        assertThat(uuid, is(dnaRootUuid.toString()));
+
+        // Get the children of the root node ...
+        javax.jcr.NodeIterator iter = root.getNodes();
+        javax.jcr.Node system = iter.nextNode();
+        assertThat(system.getName(), is("jcr:system"));
+
+        // Add a child node ...
+        javax.jcr.Node childA = root.addNode("childA", "nt:unstructured");
+        assertThat(childA, is(notNullValue()));
+        iter = root.getNodes();
+        javax.jcr.Node system2 = iter.nextNode();
+        javax.jcr.Node childA2 = iter.nextNode();
+        assertThat(system2.getName(), is("jcr:system"));
+        assertThat(childA2.getName(), is("childA"));
+    }
+
+    @Test
+    public void shouldHaveSystemBranch() throws Exception {
+        session = createSession();
+        javax.jcr.Node root = session.getRootNode();
+        AbstractJcrNode system = (AbstractJcrNode)root.getNode("jcr:system");
+        UUID uuid = system.location.getUuid();
+
+        for (int i = 0; i != 3; ++i) {
+            // Get the same node via the direct graph ...
+            Node dnaSystem = systemGraph.getNodeAt("/jcr:system");
+            UUID dnaSystemUuid = dnaSystem.getLocation().getUuid();
+
+            // They should have the same UUID ...
+            assertThat(uuid, is(dnaSystemUuid));
+        }
+    }
+
+    protected JcrSession createSession() throws Exception {
+        LoginContext login = new LoginContext("dna-jcr", new UserPasswordCallbackHandler("superuser", "superuser".toCharArray()));
+        login.login();
+
+        Subject subject = login.getSubject();
+        JcrSession session = (JcrSession)Subject.doAsPrivileged(subject, new PrivilegedExceptionAction<Session>() {
+
+            @SuppressWarnings( "synthetic-access" )
+            public Session run() throws Exception {
+                return repository.login();
+            }
+
+        }, AccessController.getContext());
+        return session;
+    }
+
     private void testDescriptorKeys( Repository repository ) {
         String[] keys = repository.getDescriptorKeys();
         assertThat(keys, notNullValue());

Modified: trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/RepositoryNodeTypeManagerTest.java
===================================================================
--- trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/RepositoryNodeTypeManagerTest.java	2009-07-21 03:17:04 UTC (rev 1119)
+++ trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/RepositoryNodeTypeManagerTest.java	2009-07-21 03:19:32 UTC (rev 1120)
@@ -57,20 +57,13 @@
     @Before
     public void beforeEach() throws Exception {
         super.beforeEach();
-
-        graph.set("jcr:primaryType").on("/jcr:system/dna:namespaces").to(DnaLexicon.NAMESPACES);
-
     }
 
     @Override
     protected void initializeContent() {
-        // Make sure the path to the namespaces exists ...
-        graph.create("/jcr:system").and(); // .and().create("/jcr:system/dna:namespaces");
-        graph.set("jcr:primaryType").on("/jcr:system").to(DnaLexicon.SYSTEM);
-
+        super.initializeContent();
         graph.create("/a").and().create("/a/b").and().create("/a/b/c").and();
         graph.set("jcr:mixinTypes").on("/a").to(JcrMixLexicon.REFERENCEABLE);
-
     }
 
     @Override
@@ -78,7 +71,6 @@
         // Stub out the repository options ...
         options = new EnumMap<JcrRepository.Option, String>(JcrRepository.Option.class);
         options.put(JcrRepository.Option.PROJECT_NODE_TYPES, Boolean.TRUE.toString());
-
     }
 
     @After

Modified: trunk/docs/examples/gettingstarted/repositories/src/main/resources/configRepository.xml
===================================================================
--- trunk/docs/examples/gettingstarted/repositories/src/main/resources/configRepository.xml	2009-07-21 03:17:04 UTC (rev 1119)
+++ trunk/docs/examples/gettingstarted/repositories/src/main/resources/configRepository.xml	2009-07-21 03:19:32 UTC (rev 1120)
@@ -69,9 +69,9 @@
                             <dna:projectionRules>/Vehicles/Aircraft => /Aircraft</dna:projectionRules>
                         </dna:projection>
                         <!-- Project the 'System' content. Only needed when this source is accessed through JCR. -->
-                        <dna:projection jcr:name="System projection" dna:source="System" dna:workspaceName="default">
+                        <!-- dna:projection jcr:name="System projection" dna:source="System" dna:workspaceName="default">
                             <dna:projectionRules>/jcr:system => /</dna:projectionRules>
-                        </dna:projection>
+                        </dna:projection-->
                     </dna:projections>
                 </dna:workspace>
             </dna:workspaces>
@@ -79,7 +79,7 @@
         <!-- 
         A 'System' source needed for the '/jcr:system' branch of the Vehicles source when it is access through JCR.
         -->
-        <dna:source jcr:name="System" dna:classname="org.jboss.dna.graph.connector.inmemory.InMemoryRepositorySource" dna:retryLimit="3" dna:defaultWorkspaceName="default"/>
+        <!-- dna:source jcr:name="System" dna:classname="org.jboss.dna.graph.connector.inmemory.InMemoryRepositorySource" dna:retryLimit="3" dna:defaultWorkspaceName="default"/-->
     </dna:sources>
     <!-- 
     Define the sequencers. This is an optional section. For this example, we're not using any sequencers. 

Modified: trunk/docs/examples/gettingstarted/repositories/src/test/java/org/jboss/example/dna/repository/RepositoryClientTest.java
===================================================================
--- trunk/docs/examples/gettingstarted/repositories/src/test/java/org/jboss/example/dna/repository/RepositoryClientTest.java	2009-07-21 03:17:04 UTC (rev 1119)
+++ trunk/docs/examples/gettingstarted/repositories/src/test/java/org/jboss/example/dna/repository/RepositoryClientTest.java	2009-07-21 03:19:32 UTC (rev 1120)
@@ -243,6 +243,7 @@
         client.startRepositories();
 
         getNodeInfo("Vehicles", "/");
+        // The non-JCR configuration does not have a "jcr:system"
         // assertThat(children, hasItems("Vehicles", "jcr:system"));
 
         getNodeInfo("Vehicles", "/Vehicles");



More information about the dna-commits mailing list