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");