Author: rhauch
Date: 2009-08-26 16:43:45 -0400 (Wed, 26 Aug 2009)
New Revision: 1175
Added:
trunk/dna-integration-tests/src/test/java/org/jboss/dna/test/integration/SvnAndJcrIntegrationTest.java
trunk/extensions/dna-connector-svn/src/test/java/org/jboss/dna/connector/svn/SVNIntegrationTest.java
Modified:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/property/Path.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/property/basic/AbstractPath.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/property/basic/RootPath.java
trunk/dna-integration-tests/pom.xml
trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrRepository.java
trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/SessionCache.java
trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/JcrConfigurationTest.java
trunk/extensions/dna-connector-svn/src/main/java/org/jboss/dna/connector/svn/SVNRepositoryRequestProcessor.java
trunk/extensions/dna-connector-svn/src/main/java/org/jboss/dna/connector/svn/SVNRepositoryUtil.java
trunk/extensions/dna-connector-svn/src/test/java/org/jboss/dna/connector/svn/SVNRepositoryConnectorCreateWorspaceTest.java
Log:
DNA-505 Svn Repository Source with NPE and other issues while opening connection through
Jcr
DNA-240 code test case for SVNRepositoryConnection used for connection
One of the NPE issues (DNA-505) was more easily fixed by returning an empty collection;
the other was fixed as prescribed in the patch (though there was another situation that
required a similar change). A test case was added to the 'dna-connector-svn'
project to test using the DNA SVN repository, and this made apparent several other issues.
First, the children for a directory were being computed incorrectly; all of the child
directories were fine, but the locations of the nt:file nodes were being skipped and
instead the path to the nt:file's jcr:content child node were being returned. Second,
much of the JCR implementation relies upon ReadNodeRequest instead of the
ReadAllPropertiesRequest and ReadAllChildrenRequest. Although the default implementation
for ReadNodeRequest uses the other two and is technically correct, it can be quite
inefficient, and this was definitely true for the SVN connector. Therefore, the request
processor code was refactored to have a single me!
thod compute the children and/or the properties for a node. This not only dramatically
reduced the class size, but it dramatically reduced the amount of duplicated code, and it
appears to have slightly improved performance (though I think the SVNKit is still the
bottleneck).
Finally, a new integration test was added to the 'dna-integration-test' project
that very minimally tests using JCR on top of the SVN connector. This may need to be
rounded out in the future, but ideally we wouldn't be hitting a remote SVN repository
(simply because of the latency issue).
Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/property/Path.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/property/Path.java 2009-08-26
18:10:37 UTC (rev 1174)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/property/Path.java 2009-08-26
20:43:45 UTC (rev 1175)
@@ -398,6 +398,25 @@
public Segment getLastSegment();
/**
+ * Determine if the path's {@link #getLastSegment()} has the supplied name and no
{@link Segment#getIndex() SNS index}.
+ *
+ * @param nameOfLastSegment the name
+ * @return return true if the supplied name is the name in the path's last
segment (and there is no SNS index), or false
+ * otherwise
+ */
+ public boolean endsWith( Name nameOfLastSegment );
+
+ /**
+ * Determine if the path's {@link #getLastSegment()} has the supplied name and
{@link Segment#getIndex() SNS index}.
+ *
+ * @param nameOfLastSegment the name
+ * @param snsIndex the SNS index
+ * @return return true if the path's last segment has the supplied name and SNS,
or false otherwise
+ */
+ public boolean endsWith( Name nameOfLastSegment,
+ int snsIndex );
+
+ /**
* Get the segment at the supplied index.
*
* @param index the index
Modified:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/property/basic/AbstractPath.java
===================================================================
---
trunk/dna-graph/src/main/java/org/jboss/dna/graph/property/basic/AbstractPath.java 2009-08-26
18:10:37 UTC (rev 1174)
+++
trunk/dna-graph/src/main/java/org/jboss/dna/graph/property/basic/AbstractPath.java 2009-08-26
20:43:45 UTC (rev 1175)
@@ -35,6 +35,7 @@
import org.jboss.dna.common.util.CheckArg;
import org.jboss.dna.graph.GraphI18n;
import org.jboss.dna.graph.property.InvalidPathException;
+import org.jboss.dna.graph.property.Name;
import org.jboss.dna.graph.property.NamespaceRegistry;
import org.jboss.dna.graph.property.Path;
@@ -187,6 +188,27 @@
/**
* {@inheritDoc}
*
+ * @see
org.jboss.dna.graph.property.Path#endsWith(org.jboss.dna.graph.property.Name)
+ */
+ public boolean endsWith( Name nameOfLastSegment ) {
+ Segment segment = getLastSegment();
+ return segment != null && segment.getName().equals(nameOfLastSegment)
&& !segment.hasIndex();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.graph.property.Path#endsWith(org.jboss.dna.graph.property.Name,
int)
+ */
+ public boolean endsWith( Name nameOfLastSegment,
+ int snsIndex ) {
+ Segment segment = getLastSegment();
+ return segment != null && segment.getName().equals(nameOfLastSegment)
&& segment.getIndex() == snsIndex;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
* @see org.jboss.dna.graph.property.Path#getParent()
*/
public Path getParent() {
Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/property/basic/RootPath.java
===================================================================
---
trunk/dna-graph/src/main/java/org/jboss/dna/graph/property/basic/RootPath.java 2009-08-26
18:10:37 UTC (rev 1174)
+++
trunk/dna-graph/src/main/java/org/jboss/dna/graph/property/basic/RootPath.java 2009-08-26
20:43:45 UTC (rev 1175)
@@ -32,6 +32,7 @@
import org.jboss.dna.common.util.CheckArg;
import org.jboss.dna.graph.GraphI18n;
import org.jboss.dna.graph.property.InvalidPathException;
+import org.jboss.dna.graph.property.Name;
import org.jboss.dna.graph.property.NamespaceRegistry;
import org.jboss.dna.graph.property.Path;
@@ -114,6 +115,27 @@
/**
* {@inheritDoc}
*
+ * @see
org.jboss.dna.graph.property.basic.AbstractPath#endsWith(org.jboss.dna.graph.property.Name)
+ */
+ @Override
+ public boolean endsWith( Name nameOfLastSegment ) {
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see
org.jboss.dna.graph.property.basic.AbstractPath#endsWith(org.jboss.dna.graph.property.Name,
int)
+ */
+ @Override
+ public boolean endsWith( Name nameOfLastSegment,
+ int snsIndex ) {
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
* @see org.jboss.dna.graph.property.Path#getNormalizedPath()
*/
@Override
Modified: trunk/dna-integration-tests/pom.xml
===================================================================
--- trunk/dna-integration-tests/pom.xml 2009-08-26 18:10:37 UTC (rev 1174)
+++ trunk/dna-integration-tests/pom.xml 2009-08-26 20:43:45 UTC (rev 1175)
@@ -81,6 +81,12 @@
<version>${pom.version}</version>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>org.jboss.dna</groupId>
+ <artifactId>dna-connector-svn</artifactId>
+ <version>${pom.version}</version>
+ <scope>test</scope>
+ </dependency>
<!--
JPA Connector Dependencies
Added:
trunk/dna-integration-tests/src/test/java/org/jboss/dna/test/integration/SvnAndJcrIntegrationTest.java
===================================================================
---
trunk/dna-integration-tests/src/test/java/org/jboss/dna/test/integration/SvnAndJcrIntegrationTest.java
(rev 0)
+++
trunk/dna-integration-tests/src/test/java/org/jboss/dna/test/integration/SvnAndJcrIntegrationTest.java 2009-08-26
20:43:45 UTC (rev 1175)
@@ -0,0 +1,122 @@
+/*
+ * JBoss DNA (
http://www.jboss.org/dna)
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership. Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ * See the AUTHORS.txt file in the distribution for a full listing of
+ * individual contributors.
+ *
+ * JBoss DNA is free software. Unless otherwise indicated, all code in JBoss DNA
+ * is licensed to you under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * JBoss DNA is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.jboss.dna.test.integration;
+
+import static org.hamcrest.core.Is.is;
+import static org.hamcrest.core.IsNull.notNullValue;
+import static org.junit.Assert.assertThat;
+import javax.jcr.NodeIterator;
+import javax.jcr.Session;
+import org.jboss.dna.connector.svn.SVNRepositorySource;
+import org.jboss.dna.graph.SecurityContext;
+import org.jboss.dna.jcr.JcrConfiguration;
+import org.jboss.dna.jcr.JcrEngine;
+import org.jboss.dna.jcr.SecurityContextCredentials;
+import org.jboss.dna.jcr.JcrRepository.Option;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ *
+ */
+public class SvnAndJcrIntegrationTest {
+ private JcrEngine engine;
+ private Session session;
+
+ @Before
+ public void beforeEach() throws Exception {
+ final String repositoryUrl = "http://anonsvn.jboss.org/repos/dna/";
+ final String[] predefinedWorkspaceNames = {repositoryUrl + "trunk",
repositoryUrl + "tags", repositoryUrl + "branches"};
+ final String svnRepositorySource = "svnRepositorySource";
+ final String repositoryName = "svnRepository";
+ final JcrConfiguration configuration = new JcrConfiguration();
+ configuration.repositorySource(svnRepositorySource)
+ .usingClass(SVNRepositorySource.class)
+ .setProperty("password", "")
+ .setProperty("username", "anonymous")
+ .setProperty("repositoryRootURL", repositoryUrl)
+ .setProperty("predefinedWorkspaceNames",
predefinedWorkspaceNames)
+ .setProperty("directoryForDefaultWorkspace",
predefinedWorkspaceNames[0])
+ .setProperty("creatingWorkspacesAllowed", false);
+
+
configuration.repository(repositoryName).setSource(svnRepositorySource).setOption(Option.READ_DEPTH,
"1");
+ configuration.save();
+ this.engine = configuration.build();
+ this.engine.start();
+
+ this.session = this.engine.getRepository(repositoryName)
+ .login(new SecurityContextCredentials(new
MyCustomSecurityContext()));
+
+ }
+
+ @After
+ public void afterEach() throws Exception {
+ if (this.session != null) {
+ this.session.logout();
+ }
+ if (this.engine != null) {
+ this.engine.shutdown();
+ }
+ }
+
+ @Test
+ public void shouldIterateOverChildrenOfRoot() throws Exception {
+ NodeIterator nodeIterator = this.session.getRootNode().getNodes();
+
+ while (nodeIterator.hasNext()) {
+ System.out.println(nodeIterator.nextNode().getPath());
+ }
+ assertThat(this.session.getRootNode().getNode("dna-graph"),
is(notNullValue()));
+ }
+
+ protected class MyCustomSecurityContext implements SecurityContext {
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.graph.SecurityContext#getUserName()
+ */
+ public String getUserName() {
+ return "Fred";
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.graph.SecurityContext#hasRole(java.lang.String)
+ */
+ public boolean hasRole( String roleName ) {
+ return true;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.graph.SecurityContext#logout()
+ */
+ public void logout() {
+ // do something
+ }
+ }
+}
Property changes on:
trunk/dna-integration-tests/src/test/java/org/jboss/dna/test/integration/SvnAndJcrIntegrationTest.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
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-08-26 18:10:37
UTC (rev 1174)
+++ trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrRepository.java 2009-08-26 20:43:45
UTC (rev 1175)
@@ -132,9 +132,14 @@
* Also, any use of the '@' character in source and workspace names must
be escaped with a preceding backslash.
* </p>
*/
- SYSTEM_SOURCE_NAME;
+ SYSTEM_SOURCE_NAME,
/**
+ * The depth of the subgraphs that should be loaded the connectors. The default
value is 1.
+ */
+ READ_DEPTH;
+
+ /**
* Determine the option given the option name. This does more than {@link
Option#valueOf(String)}, since this method first
* tries to match the supplied string to the option's {@link Option#name()
name}, then the uppercase version of the
* supplied string to the option's name, and finally if the supplied string
is a camel-case version of the name (e.g.,
@@ -176,6 +181,11 @@
* The default value for the {@link Option#JAAS_LOGIN_CONFIG_NAME} option is
{@value} .
*/
public static final String JAAS_LOGIN_CONFIG_NAME = "dna-jcr";
+
+ /**
+ * The default value for the {@link Option#READ_DEPTH} option is {@value} .
+ */
+ public static final String READ_DEPTH = "1";
}
/**
@@ -188,6 +198,7 @@
EnumMap<Option, String> defaults = new EnumMap<Option,
String>(Option.class);
defaults.put(Option.PROJECT_NODE_TYPES, DefaultOption.PROJECT_NODE_TYPES);
defaults.put(Option.JAAS_LOGIN_CONFIG_NAME,
DefaultOption.JAAS_LOGIN_CONFIG_NAME);
+ defaults.put(Option.READ_DEPTH, DefaultOption.READ_DEPTH);
DEFAULT_OPTIONS = Collections.<Option, String>unmodifiableMap(defaults);
}
Modified: trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/SessionCache.java
===================================================================
--- trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/SessionCache.java 2009-08-26 18:10:37
UTC (rev 1174)
+++ trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/SessionCache.java 2009-08-26 20:43:45
UTC (rev 1175)
@@ -76,6 +76,7 @@
import org.jboss.dna.graph.session.GraphSession.NodeId;
import org.jboss.dna.graph.session.GraphSession.PropertyInfo;
import org.jboss.dna.graph.session.GraphSession.Status;
+import org.jboss.dna.jcr.JcrRepository.Option;
/**
* The class that manages the session's information that has been locally-cached
after reading from the underlying {@link Graph
@@ -172,6 +173,12 @@
// Create the graph session, customized for JCR ...
this.graphSession = new GraphSession<JcrNodePayload,
JcrPropertyPayload>(this.store, this.workspaceName,
new
JcrNodeOperations(), new JcrAuthorizer());
+ // Set the read-depth if we can...
+ try {
+ int depth =
Integer.parseInt(session.repository().getOptions().get(Option.READ_DEPTH));
+ if (depth > 0) this.graphSession.setDepthForLoadingNodes(depth);
+ } catch (RuntimeException e) {
+ }
}
final GraphSession<JcrNodePayload, JcrPropertyPayload> graphSession() {
@@ -937,8 +944,7 @@
true,
skipProtected);
if (definition == null) {
- throw new ConstraintViolationException(
-
JcrI18n.noDefinition.text("property",
+ throw new
ConstraintViolationException(JcrI18n.noDefinition.text("property",
readable(name),
readable(node.getPath()),
readable(payload.getPrimaryTypeName()),
@@ -1114,8 +1120,7 @@
newValues,
skipProtected);
if (definition == null) {
- throw new ConstraintViolationException(
-
JcrI18n.noDefinition.text("property",
+ throw new
ConstraintViolationException(JcrI18n.noDefinition.text("property",
readable(name),
readable(node.getPath()),
readable(payload.getPrimaryTypeName()),
@@ -1249,8 +1254,8 @@
// The node definition changed, so try to set the property ...
NodeEditor newChildEditor = getEditorFor(existingChild);
try {
- JcrValue value = new JcrValue(factories(), SessionCache.this,
PropertyType.STRING,
- defn.getId().getString());
+ JcrValue value = new JcrValue(factories(), SessionCache.this,
PropertyType.STRING, defn.getId()
+
.getString());
newChildEditor.setProperty(DnaIntLexicon.NODE_DEFINITON, value);
} catch (ConstraintViolationException e) {
// We can't set this property on the node (according to the
node definition).
Modified: trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/JcrConfigurationTest.java
===================================================================
--- trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/JcrConfigurationTest.java 2009-08-26
18:10:37 UTC (rev 1174)
+++ trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/JcrConfigurationTest.java 2009-08-26
20:43:45 UTC (rev 1175)
@@ -48,6 +48,7 @@
import org.jboss.dna.graph.connector.inmemory.InMemoryRepositorySource;
import org.jboss.dna.graph.mimetype.ExtensionBasedMimeTypeDetector;
import org.jboss.dna.graph.property.Path;
+import org.jboss.dna.jcr.JcrRepository.DefaultOption;
import org.jboss.dna.jcr.JcrRepository.Option;
import org.jboss.dna.repository.DnaConfiguration;
import org.jboss.dna.repository.DnaLexicon;
@@ -246,7 +247,8 @@
Map<Option, String> options = new HashMap<Option, String>();
options.put(Option.JAAS_LOGIN_CONFIG_NAME, "test");
- options.put(Option.PROJECT_NODE_TYPES, "false");
+ options.put(Option.PROJECT_NODE_TYPES, DefaultOption.PROJECT_NODE_TYPES);
+ options.put(Option.READ_DEPTH, DefaultOption.READ_DEPTH);
assertThat(repository.getOptions(), is(options));
}
Modified:
trunk/extensions/dna-connector-svn/src/main/java/org/jboss/dna/connector/svn/SVNRepositoryRequestProcessor.java
===================================================================
---
trunk/extensions/dna-connector-svn/src/main/java/org/jboss/dna/connector/svn/SVNRepositoryRequestProcessor.java 2009-08-26
18:10:37 UTC (rev 1174)
+++
trunk/extensions/dna-connector-svn/src/main/java/org/jboss/dna/connector/svn/SVNRepositoryRequestProcessor.java 2009-08-26
20:43:45 UTC (rev 1175)
@@ -29,6 +29,8 @@
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
import java.util.Set;
import org.jboss.dna.common.i18n.I18n;
import org.jboss.dna.common.util.Logger;
@@ -63,6 +65,7 @@
import org.jboss.dna.graph.request.MoveBranchRequest;
import org.jboss.dna.graph.request.ReadAllChildrenRequest;
import org.jboss.dna.graph.request.ReadAllPropertiesRequest;
+import org.jboss.dna.graph.request.ReadNodeRequest;
import org.jboss.dna.graph.request.RenameNodeRequest;
import org.jboss.dna.graph.request.Request;
import org.jboss.dna.graph.request.UpdatePropertiesRequest;
@@ -128,188 +131,176 @@
this.accessData = accessData;
}
- /**
- * {@inheritDoc}
- *
- * @see
org.jboss.dna.graph.request.processor.RequestProcessor#process(org.jboss.dna.graph.request.ReadAllChildrenRequest)
- */
- @Override
- public void process( ReadAllChildrenRequest request ) {
- logger.trace(request.toString());
+ protected boolean readNode( String workspaceName,
+ Location myLocation,
+ List<Property> properties,
+ List<Location> children,
+ Request request ) {
// Get the SVNRepository object that represents the workspace ...
- SVNRepository workspaceRoot = getWorkspaceDirectory(request.inWorkspace());
+ SVNRepository workspaceRoot = getWorkspaceDirectory(workspaceName);
if (workspaceRoot == null) {
- request.setError(new InvalidWorkspaceException(
-
SVNRepositoryConnectorI18n.workspaceDoesNotExist.text(request.inWorkspace())));
- return;
+ request.setError(new
InvalidWorkspaceException(SVNRepositoryConnectorI18n.workspaceDoesNotExist.text(workspaceName)));
+ return false;
}
- Location myLocation = request.of();
Path requestedPath = getPathFor(myLocation, request);
- // svn connector does not support same name sibling
- checkThePath(requestedPath, request);
- // requested path is the root
+ checkThePath(requestedPath, request); // same-name-sibling indexes are not
supported
+
if (requestedPath.isRoot()) {
// workspace root must be a directory
- final Collection<SVNDirEntry> entries =
SVNRepositoryUtil.getDir(workspaceRoot, "");
- for (SVNDirEntry entry : entries) {
- // Decide how to represent the children ...
- if (entry.getKind() == SVNNodeKind.DIR) {
- // Create a Location for each file and directory contained by the
parent directory ...
+ if (children != null) {
+ final Collection<SVNDirEntry> entries =
SVNRepositoryUtil.getDir(workspaceRoot, "");
+ for (SVNDirEntry entry : entries) {
+ // All of the children of a directory will be another directory or a
file, but never a "jcr:content" node ...
String localName = entry.getName();
Name childName = nameFactory().create(defaultNamespaceUri,
localName);
Path childPath = pathFactory().create(requestedPath, childName);
- request.addChild(Location.create(childPath));
- } else if (entry.getKind() == SVNNodeKind.FILE) {
- // The parent is a file, and the path may refer to the node that is
either the "nt:file" parent
- // node, or the child "jcr:content" node...
- String localName = entry.getName();
- Path contentPath = pathFactory().create(BACK_SLASH + localName);
- if
(!contentPath.getLastSegment().getName().equals(JcrLexicon.CONTENT)) {
- Location location =
Location.create(pathFactory().create(contentPath, JcrLexicon.CONTENT));
- request.addChild(location);
- }
+ children.add(Location.create(childPath));
}
}
+ // There are no properties on the root ...
} else {
try {
- SVNNodeKind kind = getNodeKind(workspaceRoot,
- requestedPath,
- accessData.getRepositoryRootUrl(),
- request.inWorkspace());
+ // Generate the properties for this File object ...
+ PropertyFactory factory = getExecutionContext().getPropertyFactory();
+ DateTimeFactory dateFactory =
getExecutionContext().getValueFactories().getDateFactory();
+
+ // Figure out the kind of node this represents ...
+ SVNNodeKind kind = getNodeKind(workspaceRoot, requestedPath,
accessData.getRepositoryRootUrl(), workspaceName);
if (kind == SVNNodeKind.DIR) {
String directoryPath = getPathAsString(requestedPath);
- // Decide how to represent the children ...
- if (!accessData.getRepositoryRootUrl().equals(request.inWorkspace()))
{
+ if (!accessData.getRepositoryRootUrl().equals(workspaceName)) {
directoryPath = directoryPath.substring(1);
}
- Collection<SVNDirEntry> dirEntries =
SVNRepositoryUtil.getDir(workspaceRoot, directoryPath);
- for (SVNDirEntry entry : dirEntries) {
+ if (children != null) {
// Decide how to represent the children ...
- if (entry.getKind() == SVNNodeKind.DIR) {
- // Create a Location for each file and directory contained by
the parent directory ...
+ Collection<SVNDirEntry> dirEntries =
SVNRepositoryUtil.getDir(workspaceRoot, directoryPath);
+ for (SVNDirEntry entry : dirEntries) {
+ // All of the children of a directory will be another
directory or a file,
+ // but never a "jcr:content" node ...
String localName = entry.getName();
Name childName = nameFactory().create(defaultNamespaceUri,
localName);
Path childPath = pathFactory().create(requestedPath,
childName);
- request.addChild(Location.create(childPath));
- } else if (entry.getKind() == SVNNodeKind.FILE) {
- // The parent is a file, and the path may refer to the node
that is either the "nt:file" parent
- // node, or the child "jcr:content" node...
- String localName = entry.getName();
- Path contentPath =
pathFactory().create(getPathAsString(requestedPath) + BACK_SLASH + localName);
- Location content =
Location.create(pathFactory().create(contentPath, JcrLexicon.CONTENT));
- request.addChild(content);
+ children.add(Location.create(childPath));
}
}
+ if (properties != null) {
+ // Load the properties for this directory ......
+ properties.add(factory.create(JcrLexicon.PRIMARY_TYPE,
JcrNtLexicon.FOLDER));
+ SVNDirEntry entry = getEntryInfo(workspaceRoot, directoryPath);
+ if (entry != null) {
+ properties.add(factory.create(JcrLexicon.LAST_MODIFIED,
dateFactory.create(entry.getDate())));
+ }
+ }
} else {
- if
(!requestedPath.getLastSegment().getName().equals(JcrLexicon.CONTENT)) {
- // Use leading '/' on the requested path
- // repository root URL is exactly the same as the workspace
- // Get the parent path
+ // It's not a directory, so must be a file; the only child of an
nt:file is the "jcr:content" node
+ // ...
+ if (requestedPath.endsWith(JcrLexicon.CONTENT)) {
+ // There are never any children of these nodes, just properties
...
+ if (properties != null) {
+ String contentPath =
getPathAsString(requestedPath.getParent());
+ if (!accessData.getRepositoryRootUrl().equals(workspaceName))
{
+ contentPath = contentPath.substring(1);
+ }
+ SVNDirEntry entry = getEntryInfo(workspaceRoot,
contentPath);
+ if (entry != null) {
+ // The request is to get properties of the
"jcr:content" child node ...
+ properties.add(factory.create(JcrLexicon.PRIMARY_TYPE,
JcrNtLexicon.RESOURCE));
+ properties.add(factory.create(JcrLexicon.LAST_MODIFIED,
dateFactory.create(entry.getDate())));
+ }
+
+ ByteArrayOutputStream os = new ByteArrayOutputStream();
+ SVNProperties fileProperties = new SVNProperties();
+ getData(contentPath, fileProperties, os);
+ String mimeType =
fileProperties.getStringValue(SVNProperty.MIME_TYPE);
+ if (mimeType == null) mimeType = DEFAULT_MIME_TYPE;
+ properties.add(factory.create(JcrLexicon.MIMETYPE,
mimeType));
+
+ if (os.toByteArray().length > 0) {
+ // Now put the file's content into the
"jcr:data" property ...
+ BinaryFactory binaryFactory =
getExecutionContext().getValueFactories().getBinaryFactory();
+ properties.add(factory.create(JcrLexicon.DATA,
binaryFactory.create(os.toByteArray())));
+ }
+ }
+ } else {
+ // Determine the corresponding file path for this object ...
String filePath = getPathAsString(requestedPath);
- if
(!accessData.getRepositoryRootUrl().equals(request.inWorkspace())) {
+ if (!accessData.getRepositoryRootUrl().equals(workspaceName)) {
filePath = filePath.substring(1);
}
- Path contentPath = pathFactory().create(requestedPath,
JcrLexicon.CONTENT);
- Location content = Location.create(contentPath);
- request.addChild(content);
+ if (children != null) {
+ // Not a "jcr:content" child node but rather an
nt:file node, so add the child ...
+ Path contentPath = pathFactory().create(requestedPath,
JcrLexicon.CONTENT);
+ children.add(Location.create(contentPath));
+ }
+ if (properties != null) {
+ // Now add the properties to "nt:file" ...
+ properties.add(factory.create(JcrLexicon.PRIMARY_TYPE,
JcrNtLexicon.FILE));
+ ByteArrayOutputStream os = new ByteArrayOutputStream();
+ SVNProperties fileProperties = new SVNProperties();
+ getData(filePath, fileProperties, os);
+ String created =
fileProperties.getStringValue(SVNProperty.COMMITTED_DATE);
+ if (created != null) {
+ properties.add(factory.create(JcrLexicon.CREATED,
dateFactory.create(created)));
+ }
+ }
}
}
} catch (SVNException e) {
request.setError(e);
}
}
- request.setActualLocationOfNode(myLocation);
- setCacheableInfo(request);
+ return true;
}
/**
* {@inheritDoc}
*
- * @see
org.jboss.dna.graph.request.processor.RequestProcessor#process(org.jboss.dna.graph.request.ReadAllPropertiesRequest)
+ * @see
org.jboss.dna.graph.request.processor.RequestProcessor#process(org.jboss.dna.graph.request.ReadNodeRequest)
*/
@Override
- public void process( ReadAllPropertiesRequest request ) {
+ public void process( ReadNodeRequest request ) {
logger.trace(request.toString());
-
- // Get the SVNRepository object that represents the workspace ...
- SVNRepository workspaceRoot = getWorkspaceDirectory(request.inWorkspace());
- if (workspaceRoot == null) {
- request.setError(new InvalidWorkspaceException(
-
SVNRepositoryConnectorI18n.workspaceDoesNotExist.text(request.inWorkspace())));
- return;
+ List<Location> children = new LinkedList<Location>();
+ List<Property> properties = new LinkedList<Property>();
+ if (readNode(request.inWorkspace(), request.at(), properties, children, request))
{
+ request.addChildren(children);
+ request.addProperties(properties);
+ request.setActualLocationOfNode(request.at());
+ setCacheableInfo(request);
}
+ }
- // Find the existing file for the parent ...
- Location myLocation = request.at();
- Path requestedPath = getPathFor(myLocation, request);
- if (requestedPath.isRoot()) {
- // There are no properties on the root ...
- request.setActualLocationOfNode(myLocation);
+ /**
+ * {@inheritDoc}
+ *
+ * @see
org.jboss.dna.graph.request.processor.RequestProcessor#process(org.jboss.dna.graph.request.ReadAllChildrenRequest)
+ */
+ @Override
+ public void process( ReadAllChildrenRequest request ) {
+ logger.trace(request.toString());
+ List<Location> children = new LinkedList<Location>();
+ if (readNode(request.inWorkspace(), request.of(), null, children, request)) {
+ request.addChildren(children);
+ request.setActualLocationOfNode(request.of());
setCacheableInfo(request);
- return;
}
- try {
+ }
- SVNNodeKind kind = getNodeKind(workspaceRoot, requestedPath,
accessData.getRepositoryRootUrl(), request.inWorkspace());
- // Generate the properties for this File object ...
- PropertyFactory factory = getExecutionContext().getPropertyFactory();
- DateTimeFactory dateFactory =
getExecutionContext().getValueFactories().getDateFactory();
- // Note that we don't have 'created' timestamps, just last
modified, so we'll have to use them
- if (kind == SVNNodeKind.DIR) {
- String directoryPath = getPathAsString(requestedPath);
- if (!accessData.getRepositoryRootUrl().equals(request.inWorkspace())) {
- directoryPath = directoryPath.substring(1);
- }
- request.addProperty(factory.create(JcrLexicon.PRIMARY_TYPE,
JcrNtLexicon.FOLDER));
- SVNDirEntry entry = getEntryInfo(workspaceRoot, directoryPath);
- request.addProperty(factory.create(JcrLexicon.LAST_MODIFIED,
dateFactory.create(entry.getDate())));
- } else {
- if (requestedPath.getLastSegment().getName().equals(JcrLexicon.CONTENT))
{
- String contentPath = getPathAsString(requestedPath.getParent());
- if (!accessData.getRepositoryRootUrl().equals(request.inWorkspace()))
{
- contentPath = contentPath.substring(1);
- }
- SVNDirEntry entry = getEntryInfo(workspaceRoot, contentPath);
- // The request is to get properties of the "jcr:content"
child node ...
- request.addProperty(factory.create(JcrLexicon.PRIMARY_TYPE,
JcrNtLexicon.RESOURCE));
- request.addProperty(factory.create(JcrLexicon.LAST_MODIFIED,
dateFactory.create(entry.getDate())));
-
- ByteArrayOutputStream os = new ByteArrayOutputStream();
- SVNProperties fileProperties = new SVNProperties();
- getData(contentPath, fileProperties, os);
- String mimeType =
fileProperties.getStringValue(SVNProperty.MIME_TYPE);
- if (mimeType == null) mimeType = DEFAULT_MIME_TYPE;
- request.addProperty(factory.create(JcrLexicon.MIMETYPE, mimeType));
-
- if (os.toByteArray().length > 0) {
- // Now put the file's content into the "jcr:data"
property ...
- BinaryFactory binaryFactory =
getExecutionContext().getValueFactories().getBinaryFactory();
- request.addProperty(factory.create(JcrLexicon.DATA,
binaryFactory.create(os.toByteArray())));
- }
-
- } else {
- String filePath = getPathAsString(requestedPath);
- if (!accessData.getRepositoryRootUrl().equals(request.inWorkspace()))
{
- filePath = filePath.substring(1);
- }
- // The request is to get properties for the node representing the
file
- request.addProperty(factory.create(JcrLexicon.PRIMARY_TYPE,
JcrNtLexicon.FILE));
- ByteArrayOutputStream os = new ByteArrayOutputStream();
- SVNProperties fileProperties = new SVNProperties();
- getData(filePath, fileProperties, os);
- String created =
fileProperties.getStringValue(SVNProperty.COMMITTED_DATE);
- if (created != null) {
- request.addProperty(factory.create(JcrLexicon.CREATED,
dateFactory.create(created)));
- }
- }
- }
- request.setActualLocationOfNode(myLocation);
+ /**
+ * {@inheritDoc}
+ *
+ * @see
org.jboss.dna.graph.request.processor.RequestProcessor#process(org.jboss.dna.graph.request.ReadAllPropertiesRequest)
+ */
+ @Override
+ public void process( ReadAllPropertiesRequest request ) {
+ logger.trace(request.toString());
+ List<Property> properties = new LinkedList<Property>();
+ if (readNode(request.inWorkspace(), request.at(), properties, null, request)) {
+ request.addProperties(properties);
+ request.setActualLocationOfNode(request.at());
setCacheableInfo(request);
-
- } catch (SVNException e) {
- request.setError(e);
}
}
@@ -626,7 +617,7 @@
String myPath;
if (getPathAsString(requestedPath).trim().equals("/")) {
myPath = getPathAsString(requestedPath);
- } else if (requestedPath.getLastSegment().getName().equals(JcrLexicon.CONTENT))
{
+ } else if (requestedPath.endsWith(JcrLexicon.CONTENT)) {
myPath = getPathAsString(requestedPath.getParent());
} else {
// directory and file
@@ -663,7 +654,7 @@
*
* @param repos
* @param path - the path
- * @return - the {@link SVNDirEntry}.
+ * @return - the {@link SVNDirEntry}, or null if there is no such entry
*/
protected SVNDirEntry getEntryInfo( SVNRepository repos,
String path ) {
@@ -1025,7 +1016,7 @@
assert repositoryRootUrl != null;
assert inWorkspace != null;
// See if the path is a "jcr:content" node ...
- if (path.getLastSegment().getName().equals(JcrLexicon.CONTENT)) {
+ if (path.endsWith(JcrLexicon.CONTENT)) {
// We only want to use the parent path to find the actual file ...
path = path.getParent();
}
Modified:
trunk/extensions/dna-connector-svn/src/main/java/org/jboss/dna/connector/svn/SVNRepositoryUtil.java
===================================================================
---
trunk/extensions/dna-connector-svn/src/main/java/org/jboss/dna/connector/svn/SVNRepositoryUtil.java 2009-08-26
18:10:37 UTC (rev 1174)
+++
trunk/extensions/dna-connector-svn/src/main/java/org/jboss/dna/connector/svn/SVNRepositoryUtil.java 2009-08-26
20:43:45 UTC (rev 1175)
@@ -1,6 +1,7 @@
package org.jboss.dna.connector.svn;
import java.util.Collection;
+import java.util.Collections;
import org.jboss.dna.graph.connector.RepositorySourceException;
import org.jboss.dna.graph.request.InvalidWorkspaceException;
import org.tmatesoft.svn.core.SVNDirEntry;
@@ -159,16 +160,15 @@
/**
* @param repos
* @param path
- * @return a collect of entry from directory path.
+ * @return a collect of entry from directory path; never null
*/
@SuppressWarnings( "unchecked" )
public static Collection<SVNDirEntry> getDir( SVNRepository repos,
String path ) {
- Collection<SVNDirEntry> entries = null;
try {
return repos.getDir(path, -1, null, (Collection<SVNDirEntry>)null);
} catch (SVNException e) {
- return entries;
+ return Collections.emptyList();
}
}
Added:
trunk/extensions/dna-connector-svn/src/test/java/org/jboss/dna/connector/svn/SVNIntegrationTest.java
===================================================================
---
trunk/extensions/dna-connector-svn/src/test/java/org/jboss/dna/connector/svn/SVNIntegrationTest.java
(rev 0)
+++
trunk/extensions/dna-connector-svn/src/test/java/org/jboss/dna/connector/svn/SVNIntegrationTest.java 2009-08-26
20:43:45 UTC (rev 1175)
@@ -0,0 +1,79 @@
+/*
+ * JBoss DNA (
http://www.jboss.org/dna)
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership. Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ * See the AUTHORS.txt file in the distribution for a full listing of
+ * individual contributors.
+ *
+ * JBoss DNA is free software. Unless otherwise indicated, all code in JBoss DNA
+ * is licensed to you under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * JBoss DNA is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.jboss.dna.connector.svn;
+
+import static org.hamcrest.core.Is.is;
+import static org.hamcrest.core.IsNull.notNullValue;
+import static org.junit.Assert.assertThat;
+import java.util.Map;
+import org.jboss.dna.graph.ExecutionContext;
+import org.jboss.dna.graph.Graph;
+import org.jboss.dna.graph.Location;
+import org.jboss.dna.graph.Node;
+import org.jboss.dna.graph.property.Name;
+import org.jboss.dna.graph.property.Property;
+import org.junit.Before;
+import org.junit.Test;
+
+public class SVNIntegrationTest {
+
+ private ExecutionContext context;
+ private SVNRepositorySource source;
+ private String repositoryUrl;
+ private String[] predefinedWorkspaceNames;
+
+ @Before
+ public void beforeEach() {
+ repositoryUrl = "http://anonsvn.jboss.org/repos/dna/";
+ predefinedWorkspaceNames = new String[] {repositoryUrl + "trunk",
repositoryUrl + "tags", repositoryUrl + "branches"};
+ context = new ExecutionContext();
+ source = new SVNRepositorySource();
+ source.setName("svn repository source");
+ source.setRepositoryRootURL(repositoryUrl);
+ source.setUsername("anonymous");
+ source.setPassword("");
+ source.setCreatingWorkspacesAllowed(true);
+ source.setPredefinedWorkspaceNames(predefinedWorkspaceNames);
+ source.setDirectoryForDefaultWorkspace(predefinedWorkspaceNames[0]);
+ source.setCreatingWorkspacesAllowed(false);
+ }
+
+ @Test
+ public void shouldConnectAndReadRootNode() {
+ Graph graph = Graph.create(source, context);
+ Map<Name, Property> properties =
graph.getPropertiesByName().on("/");
+ assertThat(properties, is(notNullValue()));
+
+ Node root = graph.getNodeAt("/");
+ assertThat(root, is(notNullValue()));
+ assertThat(root.getLocation(), is(notNullValue()));
+ assertThat(root.getChildren().isEmpty(), is(false));
+ for (Location childLocation : root.getChildren()) {
+ assertThat(childLocation.getPath().getParent().isRoot(), is(true));
+ // Node child = graph.getNodeAt(childLocation);
+ // assertThat(child.getLocation(), is(childLocation));
+ // assertThat(child.getLocation().getPath().getParent().isRoot(), is(true));
+ }
+ }
+}
Property changes on:
trunk/extensions/dna-connector-svn/src/test/java/org/jboss/dna/connector/svn/SVNIntegrationTest.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Modified:
trunk/extensions/dna-connector-svn/src/test/java/org/jboss/dna/connector/svn/SVNRepositoryConnectorCreateWorspaceTest.java
===================================================================
---
trunk/extensions/dna-connector-svn/src/test/java/org/jboss/dna/connector/svn/SVNRepositoryConnectorCreateWorspaceTest.java 2009-08-26
18:10:37 UTC (rev 1174)
+++
trunk/extensions/dna-connector-svn/src/test/java/org/jboss/dna/connector/svn/SVNRepositoryConnectorCreateWorspaceTest.java 2009-08-26
20:43:45 UTC (rev 1175)
@@ -85,4 +85,10 @@
assertThat(workspaceNames.isEmpty(), is(true));
}
+ @Test
+ @Override
+ public void shouldReadTheChildrenOfTheRootNodeInEachWorkspace() {
+ super.shouldReadTheChildrenOfTheRootNodeInEachWorkspace();
+ }
+
}