Author: bcarothers
Date: 2010-01-05 07:50:08 -0500 (Tue, 05 Jan 2010)
New Revision: 1525
Added:
trunk/extensions/dna-connector-svn/src/main/java/org/jboss/dna/connector/svn/SvnActionExecutor.java
trunk/extensions/dna-connector-svn/src/main/java/org/jboss/dna/connector/svn/SvnRepository.java
trunk/extensions/dna-connector-svn/src/main/java/org/jboss/dna/connector/svn/SvnRepositoryConnectorI18n.java
trunk/extensions/dna-connector-svn/src/main/java/org/jboss/dna/connector/svn/SvnRepositoryLexicon.java
trunk/extensions/dna-connector-svn/src/main/java/org/jboss/dna/connector/svn/SvnRepositorySource.java
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/package-info.java
trunk/extensions/dna-connector-svn/src/main/resources/org/jboss/dna/connector/svn/
trunk/extensions/dna-connector-svn/src/test/java/org/jboss/dna/connector/svn/
Removed:
trunk/extensions/dna-connector-svn/src/main/java/org/jboss/dna/connector/svn2/
trunk/extensions/dna-connector-svn/src/main/resources/org/jboss/dna/connector/svn2/
trunk/extensions/dna-connector-svn/src/test/java/org/jboss/dna/connector/svn2/
Modified:
trunk/dna-integration-tests/src/test/java/org/jboss/dna/test/integration/svn/SvnAndJcrIntegrationTest.java
trunk/extensions/dna-connector-svn/src/test/java/org/jboss/dna/connector/svn/SvnConnectorTestUtil.java
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/SvnRepositoryConnectorI18nTest.java
trunk/extensions/dna-connector-svn/src/test/java/org/jboss/dna/connector/svn/SvnRepositoryConnectorNoCreateWorkspaceTest.java
trunk/extensions/dna-connector-svn/src/test/java/org/jboss/dna/connector/svn/SvnRepositoryConnectorNotWritableTest.java
trunk/extensions/dna-connector-svn/src/test/java/org/jboss/dna/connector/svn/SvnRepositoryConnectorWritableTest.java
trunk/extensions/dna-connector-svn/src/test/java/org/jboss/dna/connector/svn/SvnRepositorySourceTest.java
trunk/extensions/dna-connector-svn/src/test/java/org/jboss/dna/connector/svn/SvnRespositoryConnectorReadableTest.java
Log:
DNA-519 SVN Connector integration test runs in a very long time
Applied patch (DNA-519_repackage_svn.patch) that moves everything back into the svn
package. At this point, the SVN connector has now been fully converted to the path
repository framework and can start to leverage the caching support provided therein. The
next step is to write a CachePolicy and WorkspaceCache implementation for the SVN
connector to improve read performance. After that, connection pooling can be considered.
There is also a need to implement all-or-nothing transaction support. That will be
covered in a separate defect.
Modified:
trunk/dna-integration-tests/src/test/java/org/jboss/dna/test/integration/svn/SvnAndJcrIntegrationTest.java
===================================================================
---
trunk/dna-integration-tests/src/test/java/org/jboss/dna/test/integration/svn/SvnAndJcrIntegrationTest.java 2010-01-05
12:43:25 UTC (rev 1524)
+++
trunk/dna-integration-tests/src/test/java/org/jboss/dna/test/integration/svn/SvnAndJcrIntegrationTest.java 2010-01-05
12:50:08 UTC (rev 1525)
@@ -31,7 +31,7 @@
import javax.jcr.Property;
import javax.jcr.PropertyIterator;
import javax.jcr.Session;
-import org.jboss.dna.connector.svn2.SvnRepositorySource;
+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;
Copied:
trunk/extensions/dna-connector-svn/src/main/java/org/jboss/dna/connector/svn/SvnActionExecutor.java
(from rev 1524,
trunk/extensions/dna-connector-svn/src/main/java/org/jboss/dna/connector/svn2/SvnActionExecutor.java)
===================================================================
---
trunk/extensions/dna-connector-svn/src/main/java/org/jboss/dna/connector/svn/SvnActionExecutor.java
(rev 0)
+++
trunk/extensions/dna-connector-svn/src/main/java/org/jboss/dna/connector/svn/SvnActionExecutor.java 2010-01-05
12:50:08 UTC (rev 1525)
@@ -0,0 +1,73 @@
+/*
+ * 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 org.jboss.dna.connector.scm.ScmAction;
+import org.jboss.dna.connector.scm.ScmActionExecutor;
+import org.tmatesoft.svn.core.SVNErrorCode;
+import org.tmatesoft.svn.core.SVNErrorMessage;
+import org.tmatesoft.svn.core.SVNException;
+import org.tmatesoft.svn.core.io.ISVNEditor;
+import org.tmatesoft.svn.core.io.SVNRepository;
+
+/**
+ */
+public class SvnActionExecutor implements ScmActionExecutor {
+
+ private final SVNRepository repository;
+
+ /**
+ * @param repository
+ */
+ public SvnActionExecutor( SVNRepository repository ) {
+ this.repository = repository;
+ }
+
+ /**
+ * @return repository
+ */
+ public SVNRepository getRepository() {
+ return repository;
+ }
+
+ /**
+ * @param action
+ * @param message
+ * @throws SVNException
+ */
+ public void execute( ScmAction action,
+ String message ) throws SVNException {
+ ISVNEditor editor = this.repository.getCommitEditor(message, null);
+ editor.openRoot(-1);
+ try {
+ action.applyAction(editor);
+ } catch (Exception e) {
+ SVNErrorMessage err = SVNErrorMessage.create(SVNErrorCode.UNKNOWN, "This
error is appeared: '{0}'", e.getMessage());
+ throw new SVNException(err, e);
+ }
+ editor.closeDir();
+ editor.closeEdit();
+
+ }
+}
Copied:
trunk/extensions/dna-connector-svn/src/main/java/org/jboss/dna/connector/svn/SvnRepository.java
(from rev 1524,
trunk/extensions/dna-connector-svn/src/main/java/org/jboss/dna/connector/svn2/SvnRepository.java)
===================================================================
---
trunk/extensions/dna-connector-svn/src/main/java/org/jboss/dna/connector/svn/SvnRepository.java
(rev 0)
+++
trunk/extensions/dna-connector-svn/src/main/java/org/jboss/dna/connector/svn/SvnRepository.java 2010-01-05
12:50:08 UTC (rev 1525)
@@ -0,0 +1,889 @@
+package org.jboss.dna.connector.svn;
+
+import java.io.ByteArrayOutputStream;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.UUID;
+import org.jboss.dna.common.i18n.I18n;
+import org.jboss.dna.connector.scm.ScmAction;
+import org.jboss.dna.connector.svn.mgnt.AddDirectory;
+import org.jboss.dna.connector.svn.mgnt.AddFile;
+import org.jboss.dna.connector.svn.mgnt.DeleteEntry;
+import org.jboss.dna.connector.svn.mgnt.UpdateFile;
+import org.jboss.dna.graph.DnaIntLexicon;
+import org.jboss.dna.graph.DnaLexicon;
+import org.jboss.dna.graph.ExecutionContext;
+import org.jboss.dna.graph.JcrLexicon;
+import org.jboss.dna.graph.JcrNtLexicon;
+import org.jboss.dna.graph.NodeConflictBehavior;
+import org.jboss.dna.graph.connector.RepositorySourceException;
+import org.jboss.dna.graph.connector.path.AbstractWritablePathWorkspace;
+import org.jboss.dna.graph.connector.path.DefaultPathNode;
+import org.jboss.dna.graph.connector.path.PathNode;
+import org.jboss.dna.graph.connector.path.WritablePathRepository;
+import org.jboss.dna.graph.connector.path.WritablePathWorkspace;
+import org.jboss.dna.graph.connector.path.cache.WorkspaceCache;
+import org.jboss.dna.graph.property.Binary;
+import org.jboss.dna.graph.property.BinaryFactory;
+import org.jboss.dna.graph.property.DateTimeFactory;
+import org.jboss.dna.graph.property.Name;
+import org.jboss.dna.graph.property.NameFactory;
+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.Path.Segment;
+import org.jboss.dna.graph.request.InvalidRequestException;
+import org.tmatesoft.svn.core.SVNDirEntry;
+import org.tmatesoft.svn.core.SVNErrorCode;
+import org.tmatesoft.svn.core.SVNErrorMessage;
+import org.tmatesoft.svn.core.SVNException;
+import org.tmatesoft.svn.core.SVNNodeKind;
+import org.tmatesoft.svn.core.SVNProperties;
+import org.tmatesoft.svn.core.SVNProperty;
+import org.tmatesoft.svn.core.SVNURL;
+import org.tmatesoft.svn.core.auth.ISVNAuthenticationManager;
+import org.tmatesoft.svn.core.internal.io.dav.DAVRepositoryFactory;
+import org.tmatesoft.svn.core.internal.io.fs.FSRepositoryFactory;
+import org.tmatesoft.svn.core.internal.io.svn.SVNRepositoryFactoryImpl;
+import org.tmatesoft.svn.core.io.SVNRepository;
+import org.tmatesoft.svn.core.io.SVNRepositoryFactory;
+import org.tmatesoft.svn.core.wc.SVNWCUtil;
+
+public class SvnRepository extends WritablePathRepository {
+
+ private static final String DEFAULT_MIME_TYPE =
"application/octet-stream";
+ private static final byte[] EMPTY_BYTE_ARRAY = new byte[0];
+
+ private final SvnRepositorySource source;
+
+ static {
+ // for DAV (over http and https)
+ DAVRepositoryFactory.setup();
+ // For File
+ FSRepositoryFactory.setup();
+ // for SVN (over svn and svn+ssh)
+ SVNRepositoryFactoryImpl.setup();
+ }
+
+ public SvnRepository( SvnRepositorySource source ) {
+ super(source);
+
+ this.source = source;
+ initialize();
+ }
+
+ @Override
+ protected void initialize() {
+ ExecutionContext context = source.getRepositoryContext().getExecutionContext();
+ for (String workspaceName : source.getPredefinedWorkspaceNames()) {
+ doCreateWorkspace(context, workspaceName);
+ }
+
+ String defaultWorkspaceName = source.getDirectoryForDefaultWorkspace();
+ if (defaultWorkspaceName != null &&
!workspaces.containsKey(defaultWorkspaceName)) {
+ doCreateWorkspace(context, defaultWorkspaceName);
+ }
+
+ }
+
+ public WorkspaceCache getCache( String workspaceName ) {
+ return source.getPathRepositoryCache().getCache(workspaceName);
+ }
+
+ /**
+ * Internal method that creates a workspace and adds it to the map of active
workspaces without checking to see if the source
+ * allows creating workspaces. This is useful when setting up predefined workspaces.
+ *
+ * @param context the current execution context; may not be null
+ * @param name the name of the workspace to create; may not be null
+ * @return the newly created workspace; never null
+ */
+ private WritablePathWorkspace doCreateWorkspace( ExecutionContext context,
+ String name ) {
+ SvnWorkspace workspace = new SvnWorkspace(name, source.getRootNodeUuid());
+
+ workspaces.putIfAbsent(name, workspace);
+ return (WritablePathWorkspace)workspaces.get(name);
+
+ }
+
+ @Override
+ protected WritablePathWorkspace createWorkspace( ExecutionContext context,
+ String name ) {
+ if (!source.isCreatingWorkspacesAllowed()) {
+ String msg =
SvnRepositoryConnectorI18n.unableToCreateWorkspaces.text(getSourceName(), name);
+ throw new InvalidRequestException(msg);
+ }
+
+ return doCreateWorkspace(context, name);
+ }
+
+ class SvnWorkspace extends AbstractWritablePathWorkspace {
+
+ /**
+ * Only certain properties are tolerated when writing content (dna:resource or
jcr:resource) nodes. These properties are
+ * implicitly stored (primary type, data) or silently ignored (encoded, mimetype,
last modified). The silently ignored
+ * properties must be accepted to stay compatible with the JCR specification.
+ */
+ private final Set<Name> ALLOWABLE_PROPERTIES_FOR_CONTENT =
Collections.unmodifiableSet(new HashSet<Name>(
+
Arrays.asList(new Name[] {
+
JcrLexicon.PRIMARY_TYPE,
+
JcrLexicon.DATA,
+
JcrLexicon.ENCODED,
+
JcrLexicon.MIMETYPE,
+
JcrLexicon.LAST_MODIFIED,
+
JcrLexicon.UUID,
+
DnaIntLexicon.NODE_DEFINITON})));
+ /**
+ * Only certain properties are tolerated when writing files (nt:file) or folders
(nt:folder) nodes. These properties are
+ * implicitly stored in the file or folder (primary type, created).
+ */
+ private final Set<Name> ALLOWABLE_PROPERTIES_FOR_FILE_OR_FOLDER =
Collections.unmodifiableSet(new HashSet<Name>(
+
Arrays.asList(new Name[] {
+
JcrLexicon.PRIMARY_TYPE,
+
JcrLexicon.CREATED,
+
JcrLexicon.UUID,
+
DnaIntLexicon.NODE_DEFINITON})));
+
+ private final SVNRepository workspaceRoot;
+
+ public SvnWorkspace( String name,
+ UUID rootNodeUuid ) {
+ super(name, rootNodeUuid);
+
+ try {
+ workspaceRoot =
SVNRepositoryFactory.create(SVNURL.parseURIDecoded(name));
+
+ ISVNAuthenticationManager authManager =
SVNWCUtil.createDefaultAuthenticationManager(source.getUsername(),
+
source.getPassword());
+ workspaceRoot.setAuthenticationManager(authManager);
+ } catch (SVNException ex) {
+ throw new IllegalStateException(ex);
+ }
+ }
+
+ public Path getLowestExistingPath( Path path ) {
+ do {
+ path = path.getParent();
+
+ if (getNode(path) != null) {
+ return path;
+ }
+ } while (path != null);
+
+ assert false : "workspace root path was not a valid path";
+ return null;
+ }
+
+ public PathNode getNode( Path path ) {
+ WorkspaceCache cache = getCache(getName());
+
+ PathNode node = cache.get(path);
+ if (node != null) return node;
+
+ ExecutionContext context =
source.getRepositoryContext().getExecutionContext();
+ List<Property> properties = new LinkedList<Property>();
+ List<Segment> children = new LinkedList<Segment>();
+
+ try {
+ boolean result = readNode(context, this.getName(), path, properties,
children);
+ if (!result) return null;
+ } catch (SVNException ex) {
+ return null;
+ }
+
+ UUID uuid = path.isRoot() ? source.getRootNodeUuid() : null;
+ node = new DefaultPathNode(path, uuid, properties, children);
+
+ cache.set(node);
+ return node;
+ }
+
+ public PathNode createNode( ExecutionContext context,
+ PathNode parentNode,
+ Name name,
+ Map<Name, Property> properties,
+ NodeConflictBehavior conflictBehavior ) {
+
+ NamespaceRegistry registry = context.getNamespaceRegistry();
+ NameFactory nameFactory = context.getValueFactories().getNameFactory();
+ PathFactory pathFactory = context.getValueFactories().getPathFactory();
+
+ // New name to commit into the svn repos workspace
+ String newName = name.getString(registry);
+
+ Property primaryTypeProp = properties.get(JcrLexicon.PRIMARY_TYPE);
+ Name primaryType = primaryTypeProp == null ? null :
nameFactory.create(primaryTypeProp.getFirstValue());
+
+ Path parentPath = parentNode.getPath();
+ String parentPathAsString = parentPath.getString(registry);
+ Path newPath = pathFactory.create(parentPath, name);
+
+ String newChildPath = null;
+
+ // File
+ if (JcrNtLexicon.FILE.equals(primaryType)) {
+ ensureValidProperties(context, properties.values(),
ALLOWABLE_PROPERTIES_FOR_FILE_OR_FOLDER);
+ // Parent node already exist
+ boolean skipWrite = false;
+
+ if (parentPath.isRoot()) {
+ if (!source.getRepositoryRootUrl().equals(getName())) {
+ newChildPath = newName;
+ } else {
+ newChildPath = "/" + newName;
+ }
+ } else {
+ newChildPath = newPath.getString(registry);
+ if (!source.getRepositoryRootUrl().equals(getName())) {
+ newChildPath = newChildPath.substring(1);
+ }
+ }
+
+ // check if the new name already exist
+ try {
+ if (SvnRepositoryUtil.exists(workspaceRoot, newChildPath)) {
+ if (conflictBehavior.equals(NodeConflictBehavior.APPEND)) {
+ I18n msg =
SvnRepositoryConnectorI18n.sameNameSiblingsAreNotAllowed;
+ throw new InvalidRequestException(msg.text("SVN
Connector does not support Same Name Sibling"));
+ } else if
(conflictBehavior.equals(NodeConflictBehavior.DO_NOT_REPLACE)) {
+ skipWrite = true;
+ }
+ }
+ } catch (SVNException e1) {
+ throw new RepositorySourceException(getSourceName(),
e1.getMessage());
+ }
+
+ // Don't try to write if the node conflict behavior is
DO_NOT_REPLACE
+ if (!skipWrite) {
+ // create a new, empty file
+ if (newChildPath != null) {
+ try {
+ String rootPath = null;
+ if (parentPath.isRoot()) {
+ rootPath = "";
+ } else {
+ rootPath = parentPathAsString;
+ }
+ newFile(rootPath, newName, EMPTY_BYTE_ARRAY, null, getName(),
workspaceRoot);
+ } catch (SVNException e) {
+ I18n msg = SvnRepositoryConnectorI18n.couldNotCreateFile;
+ throw new RepositorySourceException(getSourceName(),
msg.text(parentPathAsString,
+
getName(),
+
getSourceName(),
+
e.getMessage()), e);
+ }
+ }
+ }
+ } else if (JcrNtLexicon.RESOURCE.equals(primaryType) ||
DnaLexicon.RESOURCE.equals(primaryType)) { // Resource
+ ensureValidProperties(context, properties.values(),
ALLOWABLE_PROPERTIES_FOR_CONTENT);
+ if (parentPath.isRoot()) {
+ newChildPath = parentPathAsString;
+ if (!source.getRepositoryRootUrl().equals(getName())) {
+ newChildPath = parentPathAsString.substring(1);
+ }
+ } else {
+ newChildPath = parentPathAsString;
+ if (!source.getRepositoryRootUrl().equals(getName())) {
+ newChildPath = newChildPath.substring(1);
+ }
+ }
+
+ if (!JcrLexicon.CONTENT.equals(name)) {
+ I18n msg = SvnRepositoryConnectorI18n.invalidNameForResource;
+ throw new RepositorySourceException(getSourceName(),
msg.text(parentPathAsString,
+
getName(),
+
getSourceName(),
+
newName));
+ }
+
+ Property parentPrimaryType =
parentNode.getProperty(JcrLexicon.PRIMARY_TYPE);
+ Name parentPrimaryTypeName = parentPrimaryType == null ? null :
nameFactory.create(parentPrimaryType.getFirstValue());
+ if (!JcrNtLexicon.FILE.equals(parentPrimaryTypeName)) {
+ I18n msg = SvnRepositoryConnectorI18n.invalidPathForResource;
+ throw new RepositorySourceException(getSourceName(),
msg.text(parentPathAsString, getName(), getSourceName()));
+ }
+
+ boolean skipWrite = false;
+ if (conflictBehavior.equals(NodeConflictBehavior.APPEND)) {
+ I18n msg = SvnRepositoryConnectorI18n.sameNameSiblingsAreNotAllowed;
+ throw new InvalidRequestException(msg.text("SVN Connector does
not support Same Name Sibling"));
+ } else if (conflictBehavior.equals(NodeConflictBehavior.DO_NOT_REPLACE))
{
+ // TODO check if the file already has content
+ skipWrite = true;
+ }
+
+ if (!skipWrite) {
+ Property dataProperty = properties.get(JcrLexicon.DATA);
+ if (dataProperty == null) {
+ I18n msg = SvnRepositoryConnectorI18n.missingRequiredProperty;
+ String dataPropName = JcrLexicon.DATA.getString(registry);
+ throw new RepositorySourceException(getSourceName(),
msg.text(parentPathAsString,
+
getName(),
+
getSourceName(),
+
dataPropName));
+ }
+
+ BinaryFactory binaryFactory =
context.getValueFactories().getBinaryFactory();
+ Binary binary =
binaryFactory.create(properties.get(JcrLexicon.DATA).getFirstValue());
+ // get old data
+ ByteArrayOutputStream contents = new ByteArrayOutputStream();
+ SVNProperties svnProperties = new SVNProperties();
+ try {
+ workspaceRoot.getFile(newChildPath, -1, svnProperties,
contents);
+ byte[] oldData = contents.toByteArray();
+
+ // modify the empty old data with the new resource
+ if (oldData != null) {
+ String pathToFile;
+ if (parentPath.isRoot()) {
+ pathToFile = "";
+ } else {
+ pathToFile = parentPath.getParent().getString(registry);
+ }
+ String fileName =
parentPath.getLastSegment().getString(registry);
+
+ modifyFile(pathToFile, fileName, oldData, binary.getBytes(),
null, getName(), workspaceRoot);
+ }
+ } catch (SVNException e) {
+ I18n msg = SvnRepositoryConnectorI18n.couldNotReadData;
+ throw new RepositorySourceException(getSourceName(),
msg.text(parentPathAsString,
+
getName(),
+
getSourceName(),
+
e.getMessage()), e);
+ }
+ }
+
+ } else if (JcrNtLexicon.FOLDER.equals(primaryType) || primaryType == null) {
// Folder
+ ensureValidProperties(context, properties.values(),
ALLOWABLE_PROPERTIES_FOR_FILE_OR_FOLDER);
+ try {
+ mkdir(parentPathAsString, newName, null, getName(), workspaceRoot);
+ } catch (SVNException e) {
+ I18n msg = SvnRepositoryConnectorI18n.couldNotCreateFile;
+ throw new RepositorySourceException(getSourceName(),
msg.text(parentPathAsString,
+
getName(),
+
getSourceName(),
+
e.getMessage()), e);
+ }
+ } else {
+ I18n msg = SvnRepositoryConnectorI18n.unsupportedPrimaryType;
+ throw new RepositorySourceException(getSourceName(),
msg.text(primaryType.getString(registry),
+
parentPathAsString,
+ getName(),
+
getSourceName()));
+ }
+
+ PathNode node = getNode(newPath);
+
+ List<Segment> newChildren = new
ArrayList<Segment>(parentNode.getChildSegments().size() + 1);
+ newChildren.addAll(parentNode.getChildSegments());
+ newChildren.add(node.getPath().getLastSegment());
+
+ WorkspaceCache cache = getCache(getName());
+ cache.set(new DefaultPathNode(parentNode.getPath(), parentNode.getUuid(),
parentNode.getProperties(), newChildren));
+ cache.set(node);
+
+ return node;
+ }
+
+ /**
+ * Create a directory .
+ *
+ * @param rootDirPath - the root directory where the created directory will
reside
+ * @param childDirPath - the name of the created directory.
+ * @param comment - comment for the creation.
+ * @param inWorkspace
+ * @param currentRepository
+ * @throws SVNException - if during the creation, there is an error.
+ */
+ private void mkdir( String rootDirPath,
+ String childDirPath,
+ String comment,
+ String inWorkspace,
+ SVNRepository currentRepository ) throws SVNException {
+
+ String tempParentPath = rootDirPath;
+ if (!source.getRepositoryRootUrl().equals(inWorkspace)) {
+ if (!tempParentPath.equals("/") &&
tempParentPath.startsWith("/")) {
+ tempParentPath = tempParentPath.substring(1);
+ } else if (tempParentPath.equals("/")) {
+ tempParentPath = "";
+ }
+ }
+ String checkPath = tempParentPath.length() == 0 ? childDirPath :
tempParentPath + "/" + childDirPath;
+ SVNNodeKind nodeKind = null;
+ try {
+ nodeKind = currentRepository.checkPath(checkPath, -1);
+ } catch (SVNException e) {
+ SVNErrorMessage err = SVNErrorMessage.create(SVNErrorCode.UNKNOWN,
+ "May be a Connecting
problem to the repository or a user's authentication failure: {0}",
+ e.getMessage());
+ throw new SVNException(err);
+ }
+
+ if (nodeKind != null && nodeKind == SVNNodeKind.NONE) {
+ ScmAction addNodeAction = new AddDirectory(rootDirPath, childDirPath);
+ SvnActionExecutor executor = new SvnActionExecutor(currentRepository);
+ comment = comment == null ? "Create a new file " + childDirPath
: comment;
+ executor.execute(addNodeAction, comment);
+ } else {
+ SVNErrorMessage err = SVNErrorMessage.create(SVNErrorCode.UNKNOWN,
+ "Node with name
'{0}' can't be created",
+ childDirPath);
+ throw new SVNException(err);
+ }
+ }
+
+ /**
+ * Create a file.
+ *
+ * @param rootDirPath
+ * @param childFilePath
+ * @param content
+ * @param comment
+ * @param inWorkspace
+ * @param currentRepository
+ * @throws SVNException
+ */
+ private void newFile( String rootDirPath,
+ String childFilePath,
+ byte[] content,
+ String comment,
+ String inWorkspace,
+ SVNRepository currentRepository ) throws SVNException {
+
+ String tempParentPath = rootDirPath;
+ if (!source.getRepositoryRootUrl().equals(inWorkspace)) {
+ if (!tempParentPath.equals("/") &&
tempParentPath.startsWith("/")) {
+ tempParentPath = tempParentPath.substring(1);
+ }
+ }
+ String checkPath = tempParentPath + "/" + childFilePath;
+ SVNNodeKind nodeKind = null;
+ try {
+ nodeKind = currentRepository.checkPath(checkPath, -1);
+ } catch (SVNException e) {
+ SVNErrorMessage err = SVNErrorMessage.create(SVNErrorCode.UNKNOWN,
+ "May be a Connecting
problem to the repository or a user's authentication failure: {0}",
+ e.getMessage());
+ throw new SVNException(err);
+ }
+
+ if (nodeKind != null && nodeKind == SVNNodeKind.NONE) {
+ ScmAction addFileNodeAction = new AddFile(rootDirPath, childFilePath,
content);
+ SvnActionExecutor executor = new SvnActionExecutor(currentRepository);
+ comment = comment == null ? "Create a new file " +
childFilePath : comment;
+ executor.execute(addFileNodeAction, comment);
+ } else {
+ SVNErrorMessage err = SVNErrorMessage.create(SVNErrorCode.UNKNOWN,
+ "Item with name
'{0}' can't be created (already exist)",
+ childFilePath);
+ throw new SVNException(err);
+ }
+ }
+
+ /**
+ * Modify a file
+ *
+ * @param rootPath
+ * @param fileName
+ * @param oldData
+ * @param newData
+ * @param comment
+ * @param inWorkspace
+ * @param currentRepository
+ * @throws SVNException
+ */
+ private void modifyFile( String rootPath,
+ String fileName,
+ byte[] oldData,
+ byte[] newData,
+ String comment,
+ String inWorkspace,
+ SVNRepository currentRepository ) throws SVNException {
+ assert rootPath != null;
+ assert fileName != null;
+ assert oldData != null;
+ assert inWorkspace != null;
+ assert currentRepository != null;
+
+ try {
+
+ if (!source.getRepositoryRootUrl().equals(inWorkspace)) {
+ if (rootPath.equals("/")) {
+ rootPath = "";
+ } else {
+ rootPath = rootPath.substring(1) + "/";
+ }
+ } else {
+ if (!rootPath.equals("/")) {
+ rootPath = rootPath + "/";
+ }
+ }
+ String path = rootPath + fileName;
+
+ SVNNodeKind nodeKind = currentRepository.checkPath(path, -1);
+ if (nodeKind == SVNNodeKind.NONE || nodeKind == SVNNodeKind.UNKNOWN) {
+ SVNErrorMessage err =
SVNErrorMessage.create(SVNErrorCode.ENTRY_NOT_FOUND,
+ "Item with name
'{0}' can't be found",
+ path);
+ throw new SVNException(err);
+ }
+
+ ScmAction modifyFileAction = new UpdateFile(rootPath, fileName, oldData,
newData);
+ SvnActionExecutor executor = new SvnActionExecutor(currentRepository);
+ comment = comment == null ? "modify the " + fileName :
comment;
+ executor.execute(modifyFileAction, comment);
+
+ } catch (SVNException e) {
+ SVNErrorMessage err = SVNErrorMessage.create(SVNErrorCode.UNKNOWN,
"This error is appeared: " + e.getMessage());
+ throw new SVNException(err, e);
+ }
+
+ }
+
+ /**
+ * Delete entry from the repository
+ *
+ * @param path
+ * @param comment
+ * @param inWorkspace
+ * @param currentRepository
+ * @throws SVNException
+ */
+ private void eraseEntry( String path,
+ String comment,
+ String inWorkspace,
+ SVNRepository currentRepository ) throws SVNException {
+ assert path != null;
+ assert inWorkspace != null;
+ if (path.equals("/") || path.equals("")) {
+ SVNErrorMessage err = SVNErrorMessage.create(SVNErrorCode.BAD_URL,
"The root directory cannot be deleted");
+ throw new SVNException(err);
+ }
+
+ try {
+ ScmAction deleteEntryAction = new DeleteEntry(path);
+ SvnActionExecutor executor = new SvnActionExecutor(currentRepository);
+ comment = comment == null ? "Delete the " + path : comment;
+ executor.execute(deleteEntryAction, comment);
+ } catch (SVNException e) {
+ SVNErrorMessage err = SVNErrorMessage.create(SVNErrorCode.UNKNOWN,
+ "unknow error during
delete action: {0)",
+ e.getMessage());
+ throw new SVNException(err);
+ }
+ }
+
+ public boolean removeNode( ExecutionContext context,
+ Path nodePath ) {
+
+ NamespaceRegistry registry = context.getNamespaceRegistry();
+
+ boolean isContentNode = !nodePath.isRoot() &&
JcrLexicon.CONTENT.equals(nodePath.getLastSegment().getName());
+ Path actualPath = isContentNode ? nodePath.getParent() : nodePath;
+
+ try {
+ SVNNodeKind kind = getNodeKind(context, actualPath,
source.getRepositoryRootUrl());
+
+ if (kind == SVNNodeKind.NONE) {
+ return false;
+ }
+
+ if (isContentNode) {
+ String rootPath = actualPath.getParent().getString(registry);
+ String fileName = actualPath.getLastSegment().getString(registry);
+ modifyFile(rootPath, fileName, EMPTY_BYTE_ARRAY, EMPTY_BYTE_ARRAY,
null, getName(), workspaceRoot);
+ } else {
+ eraseEntry(actualPath.getString(registry), null, getName(),
workspaceRoot);
+ }
+ } catch (SVNException e) {
+ throw new RepositorySourceException(getSourceName(),
+
SvnRepositoryConnectorI18n.deleteFailed.text(nodePath, getSourceName()));
+ }
+
+ getCache(getName()).invalidate(nodePath);
+
+ return true;
+ }
+
+ public PathNode setProperties( ExecutionContext context,
+ Path nodePath,
+ Map<Name, Property> properties ) {
+ PathNode targetNode = getNode(nodePath);
+ if (targetNode == null) return null;
+
+ /*
+ * You can't really remove any properties from SVN nodes.
+ * You can clear the data of a dna:resource though
+ */
+
+ NameFactory nameFactory = context.getValueFactories().getNameFactory();
+ Property primaryTypeProperty =
targetNode.getProperty(JcrLexicon.PRIMARY_TYPE);
+ Name primaryTypeName = primaryTypeProperty == null ? null :
nameFactory.create(primaryTypeProperty.getFirstValue());
+ if (DnaLexicon.RESOURCE.equals(primaryTypeName)) {
+
+ for (Map.Entry<Name, Property> entry : properties.entrySet()) {
+ if (JcrLexicon.DATA.equals(entry.getKey())) {
+ NamespaceRegistry registry = context.getNamespaceRegistry();
+ byte[] data;
+ if (entry.getValue() == null) {
+ data = EMPTY_BYTE_ARRAY;
+ } else {
+ BinaryFactory binaryFactory =
context.getValueFactories().getBinaryFactory();
+ data =
binaryFactory.create(entry.getValue().getFirstValue()).getBytes();
+
+ }
+
+ try {
+ Path actualPath = nodePath.getParent();
+ modifyFile(actualPath.getParent().getString(registry),
+ actualPath.getLastSegment().getString(registry),
+ EMPTY_BYTE_ARRAY,
+ data,
+ "",
+ getName(),
+ workspaceRoot);
+
+ PathNode node = getNode(nodePath);
+ getCache(getName()).set(node);
+
+ return node;
+ } catch (SVNException ex) {
+ throw new RepositorySourceException(getSourceName(),
+
SvnRepositoryConnectorI18n.deleteFailed.text(nodePath,
+
getSourceName()), ex);
+ }
+ }
+ }
+ }
+
+ return targetNode;
+ }
+
+ protected boolean readNode( ExecutionContext context,
+ String workspaceName,
+ Path requestedPath,
+ List<Property> properties,
+ List<Segment> children ) throws SVNException {
+ PathFactory pathFactory = context.getValueFactories().getPathFactory();
+ NamespaceRegistry registry = context.getNamespaceRegistry();
+
+ if (requestedPath.isRoot()) {
+ // workspace root must be a 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
+ // ...
+ children.add(pathFactory.createSegment(entry.getName()));
+ }
+ }
+ // There are no properties on the root ...
+ } else {
+ // Generate the properties for this File object ...
+ PropertyFactory factory = context.getPropertyFactory();
+ DateTimeFactory dateFactory =
context.getValueFactories().getDateFactory();
+
+ // Figure out the kind of node this represents ...
+ SVNNodeKind kind = getNodeKind(context, requestedPath,
source.getRepositoryRootUrl());
+ if (kind == SVNNodeKind.NONE) {
+ // The node doesn't exist
+ return false;
+ }
+ if (kind == SVNNodeKind.DIR) {
+ String directoryPath = requestedPath.getString(registry);
+ if (!source.getRepositoryRootUrl().equals(workspaceName)) {
+ directoryPath = directoryPath.substring(1);
+ }
+ if (children != null) {
+ // Decide how to represent the children ...
+ 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 ...
+ children.add(pathFactory.createSegment(entry.getName()));
+ }
+ }
+ 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.CREATED,
dateFactory.create(entry.getDate())));
+ }
+ }
+ } else {
+ // 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 =
requestedPath.getParent().getString(registry);
+ if (!source.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 ...
+ // Do NOT use "nt:resource", since it extends
"mix:referenceable". The JCR spec
+ // does not require that "jcr:content" is of
type "nt:resource", but rather just
+ // suggests it. Therefore, we can use
"dna:resource", which is identical to
+ // "nt:resource" except it does not extend
"mix:referenceable"
+ properties.add(factory.create(JcrLexicon.PRIMARY_TYPE,
DnaLexicon.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 =
context.getValueFactories().getBinaryFactory();
+ properties.add(factory.create(JcrLexicon.DATA,
binaryFactory.create(os.toByteArray())));
+ }
+ }
+ } else {
+ // Determine the corresponding file path for this object ...
+ String filePath = requestedPath.getString(registry);
+ if (!source.getRepositoryRootUrl().equals(workspaceName)) {
+ filePath = filePath.substring(1);
+ }
+ if (children != null) {
+ // Not a "jcr:content" child node but rather an
nt:file node, so add the child ...
+ children.add(pathFactory.createSegment(JcrLexicon.CONTENT));
+ }
+ 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);
+ properties.add(factory.create(JcrLexicon.CREATED,
dateFactory.create(created)));
+ }
+ }
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Get some important informations of a path
+ *
+ * @param repos
+ * @param path - the path
+ * @return - the {@link SVNDirEntry}, or null if there is no such entry
+ */
+ protected SVNDirEntry getEntryInfo( SVNRepository repos,
+ String path ) {
+ assert path != null;
+ SVNDirEntry entry = null;
+ try {
+ entry = repos.info(path, -1);
+ } catch (SVNException e) {
+ throw new RepositorySourceException(
+ getSourceName(),
+
SvnRepositoryConnectorI18n.connectingFailureOrUserAuthenticationProblem.text(getSourceName()));
+ }
+ return entry;
+ }
+
+ /**
+ * Get the content of a file.
+ *
+ * @param path - the path to that file.
+ * @param properties - the properties of the file.
+ * @param os - the output stream where to store the content.
+ * @throws SVNException - throws if such path is not at that revision or in case
of a connection problem.
+ */
+ protected void getData( String path,
+ SVNProperties properties,
+ OutputStream os ) throws SVNException {
+ workspaceRoot.getFile(path, -1, properties, os);
+
+ }
+
+ protected SVNNodeKind getNodeKind( ExecutionContext context,
+ Path path,
+ String repositoryRootUrl ) throws SVNException
{
+ assert path != null;
+ assert repositoryRootUrl != null;
+
+ // See if the path is a "jcr:content" node ...
+ if (path.endsWith(JcrLexicon.CONTENT)) {
+ // We only want to use the parent path to find the actual file ...
+ path = path.getParent();
+ }
+ String pathAsString = path.getString(context.getNamespaceRegistry());
+ if (!repositoryRootUrl.equals(getName())) {
+ pathAsString = pathAsString.substring(1);
+ }
+
+ String absolutePath = pathAsString;
+ SVNNodeKind kind = workspaceRoot.checkPath(absolutePath, -1);
+ if (kind == SVNNodeKind.UNKNOWN) {
+ // node is unknown
+ throw new RepositorySourceException(getSourceName(),
+
SvnRepositoryConnectorI18n.nodeIsActuallyUnknow.text(pathAsString));
+ }
+ return kind;
+ }
+
+ protected SVNRepository getWorkspaceDirectory( String workspaceName ) {
+ if (workspaceName == null) workspaceName =
source.getDirectoryForDefaultWorkspace();
+ SVNRepository repository = null;
+ SVNRepository repos = SvnRepositoryUtil.createRepository(workspaceName,
source.getUsername(), source.getPassword());
+ if (SvnRepositoryUtil.isDirectory(repos, "")) {
+ repository = repos;
+ } else {
+ return null;
+ }
+ return repository;
+ }
+
+ /**
+ * Checks that the collection of {@code properties} only contains properties with
allowable names.
+ *
+ * @param context
+ * @param properties
+ * @param validPropertyNames
+ * @throws RepositorySourceException if {@code properties} contains a
+ * @see #ALLOWABLE_PROPERTIES_FOR_CONTENT
+ * @see #ALLOWABLE_PROPERTIES_FOR_FILE_OR_FOLDER
+ */
+ protected void ensureValidProperties( ExecutionContext context,
+ Collection<Property> properties,
+ Set<Name> validPropertyNames ) {
+ List<String> invalidNames = new LinkedList<String>();
+ NamespaceRegistry registry = context.getNamespaceRegistry();
+
+ for (Property property : properties) {
+ if (!validPropertyNames.contains(property.getName())) {
+ invalidNames.add(property.getName().getString(registry));
+ }
+ }
+
+ if (!invalidNames.isEmpty()) {
+ throw new RepositorySourceException(getSourceName(),
+
SvnRepositoryConnectorI18n.invalidPropertyNames.text(invalidNames.toString()));
+ }
+ }
+
+ }
+
+}
Copied:
trunk/extensions/dna-connector-svn/src/main/java/org/jboss/dna/connector/svn/SvnRepositoryConnectorI18n.java
(from rev 1524,
trunk/extensions/dna-connector-svn/src/main/java/org/jboss/dna/connector/svn2/SvnRepositoryConnectorI18n.java)
===================================================================
---
trunk/extensions/dna-connector-svn/src/main/java/org/jboss/dna/connector/svn/SvnRepositoryConnectorI18n.java
(rev 0)
+++
trunk/extensions/dna-connector-svn/src/main/java/org/jboss/dna/connector/svn/SvnRepositoryConnectorI18n.java 2010-01-05
12:50:08 UTC (rev 1525)
@@ -0,0 +1,89 @@
+/*
+ * 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 java.util.Locale;
+import java.util.Set;
+import org.jboss.dna.common.i18n.I18n;
+
+/**
+ * The internationalized string constants for the
<code>org.jboss.dna.connector.svn*</code> packages.
+ */
+public final class SvnRepositoryConnectorI18n {
+
+ public static I18n connectorName;
+ public static I18n nodeDoesNotExist;
+ public static I18n nodeIsActuallyUnknow;
+ public static I18n propertyIsRequired;
+ public static I18n errorSerializingCachePolicyInSource;
+ public static I18n locationInRequestMustHavePath;
+ public static I18n sourceIsReadOnly;
+ public static I18n sourceDoesNotSupportCreatingWorkspaces;
+ public static I18n sourceDoesNotSupportCloningWorkspaces;
+ public static I18n sourceDoesNotSupportDeletingWorkspaces;
+ public static I18n connectingFailureOrUserAuthenticationProblem;
+ public static I18n pathForPredefinedWorkspaceDoesNotExist;
+ public static I18n pathForPredefinedWorkspaceIsNotDirectory;
+ public static I18n pathForPredefinedWorkspaceCannotBeRead;
+ public static I18n workspaceDoesNotExist;
+ public static I18n pathForDefaultWorkspaceDoesNotExist;
+ public static I18n pathForDefaultWorkspaceIsNotDirectory;
+ public static I18n pathForDefaultWorkspaceCannotBeRead;
+ public static I18n sameNameSiblingsAreNotAllowed;
+ public static I18n onlyTheDefaultNamespaceIsAllowed;
+ public static I18n unableToCreateWorkspaces;
+ public static I18n pathForRequestIsNotCorrect;
+ public static I18n pathForRequestMustStartWithAForwardSlash;
+ public static I18n nodeAlreadyExist;
+ public static I18n unsupportedPrimaryType;
+ public static I18n invalidPropertyNames;
+ public static I18n invalidNameForResource;
+ public static I18n invalidPathForResource;
+ public static I18n missingRequiredProperty;
+ public static I18n couldNotCreateFile;
+ public static I18n couldNotReadData;
+ public static I18n deleteFailed;
+
+ static {
+ try {
+ I18n.initialize(SvnRepositoryConnectorI18n.class);
+ } catch (final Exception err) {
+ System.err.println(err);
+ }
+ }
+
+ public static Set<Locale> getLocalizationProblemLocales() {
+ return I18n.getLocalizationProblemLocales(SvnRepositoryConnectorI18n.class);
+ }
+
+ public static Set<String> getLocalizationProblems() {
+ return I18n.getLocalizationProblems(SvnRepositoryConnectorI18n.class);
+ }
+
+ public static Set<String> getLocalizationProblems( Locale locale ) {
+ return I18n.getLocalizationProblems(SvnRepositoryConnectorI18n.class, locale);
+ }
+
+
+}
Copied:
trunk/extensions/dna-connector-svn/src/main/java/org/jboss/dna/connector/svn/SvnRepositoryLexicon.java
(from rev 1524,
trunk/extensions/dna-connector-svn/src/main/java/org/jboss/dna/connector/svn2/SvnRepositoryLexicon.java)
===================================================================
---
trunk/extensions/dna-connector-svn/src/main/java/org/jboss/dna/connector/svn/SvnRepositoryLexicon.java
(rev 0)
+++
trunk/extensions/dna-connector-svn/src/main/java/org/jboss/dna/connector/svn/SvnRepositoryLexicon.java 2010-01-05
12:50:08 UTC (rev 1525)
@@ -0,0 +1,43 @@
+/*
+ * 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 org.jboss.dna.connector.svn.SvnRepositorySource;
+import org.jboss.dna.graph.property.Name;
+import org.jboss.dna.graph.property.basic.BasicName;
+
+/**
+ * The namespace and property names used within a {@link SvnRepositorySource} to store
internal information.
+ */
+public class SvnRepositoryLexicon {
+
+ public static class Namespace {
+ public static final String URI =
"http://www.jboss.org/dna/connector/svn";
+ public static final String PREFIX = "dnasvn";
+ }
+
+ public static final Name CHILD_PATH_SEGMENT_LIST = new BasicName(Namespace.URI,
"orderedChildNames");
+ public static final Name UUID = new BasicName(Namespace.URI, "uuid");
+
+}
Copied:
trunk/extensions/dna-connector-svn/src/main/java/org/jboss/dna/connector/svn/SvnRepositorySource.java
(from rev 1524,
trunk/extensions/dna-connector-svn/src/main/java/org/jboss/dna/connector/svn2/SvnRepositorySource.java)
===================================================================
---
trunk/extensions/dna-connector-svn/src/main/java/org/jboss/dna/connector/svn/SvnRepositorySource.java
(rev 0)
+++
trunk/extensions/dna-connector-svn/src/main/java/org/jboss/dna/connector/svn/SvnRepositorySource.java 2010-01-05
12:50:08 UTC (rev 1525)
@@ -0,0 +1,408 @@
+/*
+ * 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 java.util.Hashtable;
+import java.util.List;
+import java.util.Map;
+import javax.naming.Context;
+import javax.naming.Name;
+import javax.naming.Reference;
+import javax.naming.StringRefAddr;
+import javax.naming.spi.ObjectFactory;
+import net.jcip.annotations.ThreadSafe;
+import org.jboss.dna.common.i18n.I18n;
+import org.jboss.dna.common.util.CheckArg;
+import org.jboss.dna.common.util.StringUtil;
+import org.jboss.dna.graph.connector.RepositoryConnection;
+import org.jboss.dna.graph.connector.RepositorySource;
+import org.jboss.dna.graph.connector.RepositorySourceCapabilities;
+import org.jboss.dna.graph.connector.RepositorySourceException;
+import org.jboss.dna.graph.connector.path.AbstractPathRepositorySource;
+import org.jboss.dna.graph.connector.path.PathRepositoryConnection;
+
+/**
+ * The {@link RepositorySource} for the connector that exposes an area of the
local/remote svn repository as content in a
+ * repository. This source considers a workspace name to be the path to the directory on
the repository's root directory location
+ * that represents the root of that workspace. New workspaces can be created, as long as
the names represent valid paths to
+ * existing directories.
+ */
+@ThreadSafe
+public class SvnRepositorySource extends AbstractPathRepositorySource implements
ObjectFactory {
+
+ /**
+ * The first serialized version of this source. Version {@value} .
+ */
+ private static final long serialVersionUID = 1L;
+
+ protected static final String SOURCE_NAME = "sourceName";
+ protected static final String SVN_REPOSITORY_ROOT_URL =
"repositoryRootURL";
+ protected static final String SVN_USERNAME = "username";
+ protected static final String SVN_PASSWORD = "password";
+ protected static final String CACHE_TIME_TO_LIVE_IN_MILLISECONDS =
"cacheTimeToLiveInMilliseconds";
+ protected static final String RETRY_LIMIT = "retryLimit";
+ protected static final String ROOT_NODE_UUID = "rootNodeUuid";
+ protected static final String DEFAULT_WORKSPACE = "defaultWorkspace";
+ protected static final String PREDEFINED_WORKSPACE_NAMES =
"predefinedWorkspaceNames";
+ protected static final String ALLOW_CREATING_WORKSPACES =
"allowCreatingWorkspaces";
+
+ /**
+ * This source supports events.
+ */
+ protected static final boolean SUPPORTS_EVENTS = true;
+ /**
+ * This source supports same-name-siblings.
+ */
+ protected static final boolean SUPPORTS_SAME_NAME_SIBLINGS = false;
+ /**
+ * This source does support creating workspaces.
+ */
+ protected static final boolean DEFAULT_SUPPORTS_CREATING_WORKSPACES = true;
+ /**
+ * This source supports udpates by default, but each instance may be configured to be
read-only or updateable}.
+ */
+ public static final boolean DEFAULT_SUPPORTS_UPDATES = false;
+
+ /**
+ * This source supports creating references.
+ */
+ protected static final boolean SUPPORTS_REFERENCES = false;
+
+ private volatile String repositoryRootUrl;
+ private volatile String username;
+ private volatile String password;
+ private volatile String defaultWorkspace;
+ private volatile String[] predefinedWorkspaces = new String[] {};
+ private volatile RepositorySourceCapabilities capabilities = new
RepositorySourceCapabilities(
+
SUPPORTS_SAME_NAME_SIBLINGS,
+
DEFAULT_SUPPORTS_UPDATES,
+
SUPPORTS_EVENTS,
+
DEFAULT_SUPPORTS_CREATING_WORKSPACES,
+
SUPPORTS_REFERENCES);
+
+ private transient SvnRepository repository;
+
+ /**
+ * Create a repository source instance.
+ */
+ public SvnRepositorySource() {
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.graph.connector.RepositorySource#getCapabilities()
+ */
+ public RepositorySourceCapabilities getCapabilities() {
+ return capabilities;
+ }
+
+ /**
+ * @return the url
+ */
+ public String getRepositoryRootUrl() {
+ return this.repositoryRootUrl;
+ }
+
+ /**
+ * Set the url for the subversion repository.
+ *
+ * @param url - the url location.
+ * @throws IllegalArgumentException If svn url is null or empty
+ */
+ public synchronized void setRepositoryRootUrl( String url ) {
+ CheckArg.isNotEmpty(url, "RepositoryRootUrl");
+ this.repositoryRootUrl = url;
+ }
+
+ public String getUsername() {
+ return this.username;
+ }
+
+ /**
+ * @param username
+ */
+ public synchronized void setUsername( String username ) {
+ this.username = username;
+ }
+
+ public String getPassword() {
+ return this.password;
+ }
+
+ /**
+ * @param password
+ */
+ public synchronized void setPassword( String password ) {
+ this.password = password;
+ }
+
+ /**
+ * Get whether this source supports updates.
+ *
+ * @return true if this source supports updates, or false if this source only
supports reading content.
+ */
+ public boolean getSupportsUpdates() {
+ return capabilities.supportsUpdates();
+ }
+
+ /**
+ * Get the file system path to the existing directory that should be used for the
default workspace. If the default is
+ * specified as a null String or is not a valid and resolvable path, this source will
consider the default to be the current
+ * working directory of this virtual machine, as defined by the <code>new
File(".")</code>.
+ *
+ * @return the file system path to the directory representing the default workspace,
or null if the default should be the
+ * current working directory
+ */
+ public String getDirectoryForDefaultWorkspace() {
+ return defaultWorkspace;
+ }
+
+ public String getDefaultWorkspaceName() {
+ return defaultWorkspace;
+ }
+
+ /**
+ * Set the file system path to the existing directory that should be used for the
default workspace. If the default is
+ * specified as a null String or is not a valid and resolvable path, this source will
consider the default to be the current
+ * working directory of this virtual machine, as defined by the <code>new
File(".")</code>.
+ *
+ * @param pathToDirectoryForDefaultWorkspace the valid and resolvable file system
path to the directory representing the
+ * default workspace, or null if the current working directory should be used
as the default workspace
+ */
+ public synchronized void setDirectoryForDefaultWorkspace( String
pathToDirectoryForDefaultWorkspace ) {
+ this.defaultWorkspace = pathToDirectoryForDefaultWorkspace;
+ }
+
+ /**
+ * Gets the names of the workspaces that are available when this source is created.
Each workspace name corresponds to a path
+ * to a directory on the file system.
+ *
+ * @return the names of the workspaces that this source starts with, or null if there
are no such workspaces
+ * @see #setPredefinedWorkspaceNames(String[])
+ * @see #setCreatingWorkspacesAllowed(boolean)
+ */
+ public synchronized String[] getPredefinedWorkspaceNames() {
+ String[] copy = new String[predefinedWorkspaces.length];
+ System.arraycopy(predefinedWorkspaces, 0, copy, 0, predefinedWorkspaces.length);
+ return copy;
+ }
+
+ /**
+ * Sets the names of the workspaces that are available when this source is created.
Each workspace name corresponds to a path
+ * to a directory on the file system.
+ *
+ * @param predefinedWorkspaceNames the names of the workspaces that this source
should start with, or null if there are no
+ * such workspaces
+ * @see #setCreatingWorkspacesAllowed(boolean)
+ * @see #getPredefinedWorkspaceNames()
+ */
+ public synchronized void setPredefinedWorkspaceNames( String[]
predefinedWorkspaceNames ) {
+ this.predefinedWorkspaces = predefinedWorkspaceNames;
+ }
+
+ /**
+ * Get whether this source allows workspaces to be created dynamically.
+ *
+ * @return true if this source allows workspaces to be created by clients, or false
if the set of workspaces is fixed
+ * @see #setPredefinedWorkspaceNames(String[])
+ * @see #getPredefinedWorkspaceNames()
+ * @see #setCreatingWorkspacesAllowed(boolean)
+ */
+ public boolean isCreatingWorkspacesAllowed() {
+ return capabilities.supportsCreatingWorkspaces();
+ }
+
+ /**
+ * Set whether this source allows workspaces to be created dynamically.
+ *
+ * @param allowWorkspaceCreation true if this source allows workspaces to be created
by clients, or false if the set of
+ * workspaces is fixed
+ * @see #setPredefinedWorkspaceNames(String[])
+ * @see #getPredefinedWorkspaceNames()
+ * @see #isCreatingWorkspacesAllowed()
+ */
+ public synchronized void setCreatingWorkspacesAllowed( boolean allowWorkspaceCreation
) {
+ capabilities = new
RepositorySourceCapabilities(capabilities.supportsSameNameSiblings(),
capabilities.supportsUpdates(),
+ capabilities.supportsEvents(),
allowWorkspaceCreation,
+
capabilities.supportsReferences());
+ }
+
+ /**
+ * Get whether this source allows updates.
+ *
+ * @return true if this source allows updates by clients, or false if no updates are
allowed
+ * @see #setUpdatesAllowed(boolean)
+ */
+ @Override
+ public boolean areUpdatesAllowed() {
+ return capabilities.supportsUpdates();
+ }
+
+ /**
+ * Set whether this source allows updates to data within workspaces
+ *
+ * @param allowUpdates true if this source allows updates to data within workspaces
clients, or false if updates are not
+ * allowed.
+ * @see #areUpdatesAllowed()
+ */
+ public synchronized void setUpdatesAllowed( boolean allowUpdates ) {
+ capabilities = new
RepositorySourceCapabilities(capabilities.supportsSameNameSiblings(), allowUpdates,
+ capabilities.supportsEvents(),
capabilities.supportsCreatingWorkspaces(),
+
capabilities.supportsReferences());
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean equals( Object obj ) {
+ if (obj == this) return true;
+ if (obj instanceof SvnRepositorySource) {
+ SvnRepositorySource that = (SvnRepositorySource)obj;
+ if (this.getName() == null) {
+ if (that.getName() != null) return false;
+ } else {
+ if (!this.getName().equals(that.getName())) return false;
+ }
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see javax.naming.Referenceable#getReference()
+ */
+ public synchronized Reference getReference() {
+ String className = getClass().getName();
+ String factoryClassName = this.getClass().getName();
+ Reference ref = new Reference(className, factoryClassName, null);
+
+ if (getName() != null) {
+ ref.add(new StringRefAddr(SOURCE_NAME, getName()));
+ }
+ if (getRepositoryRootUrl() != null) {
+ ref.add(new StringRefAddr(SVN_REPOSITORY_ROOT_URL, getRepositoryRootUrl()));
+ }
+ if (getUsername() != null) {
+ ref.add(new StringRefAddr(SVN_USERNAME, getUsername()));
+ }
+ if (getPassword() != null) {
+ ref.add(new StringRefAddr(SVN_PASSWORD, getPassword()));
+ }
+ ref.add(new StringRefAddr(RETRY_LIMIT, Integer.toString(getRetryLimit())));
+ ref.add(new StringRefAddr(ROOT_NODE_UUID, rootNodeUuid.toString()));
+ ref.add(new StringRefAddr(DEFAULT_WORKSPACE,
getDirectoryForDefaultWorkspace()));
+ ref.add(new StringRefAddr(ALLOW_CREATING_WORKSPACES,
Boolean.toString(isCreatingWorkspacesAllowed())));
+ String[] workspaceNames = getPredefinedWorkspaceNames();
+ if (workspaceNames != null && workspaceNames.length != 0) {
+ ref.add(new StringRefAddr(PREDEFINED_WORKSPACE_NAMES,
StringUtil.combineLines(workspaceNames)));
+ }
+ return ref;
+
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see javax.naming.spi.ObjectFactory#getObjectInstance(java.lang.Object,
javax.naming.Name, javax.naming.Context,
+ * java.util.Hashtable)
+ */
+ public Object getObjectInstance( Object obj,
+ Name name,
+ Context nameCtx,
+ Hashtable<?, ?> environment ) throws Exception
{
+ if (!(obj instanceof Reference)) return null;
+
+ Map<String, Object> values = valuesFrom((Reference)obj);
+
+ String sourceName = (String)values.get(SOURCE_NAME);
+ String repositoryRootUrl = (String)values.get(SVN_REPOSITORY_ROOT_URL);
+ String username = (String)values.get(SVN_USERNAME);
+ String password = (String)values.get(SVN_PASSWORD);
+ String retryLimit = (String)values.get(RETRY_LIMIT);
+ String rootNodeUuid = (String)values.get(ROOT_NODE_UUID);
+ String defaultWorkspace = (String)values.get(DEFAULT_WORKSPACE);
+ String createWorkspaces = (String)values.get(ALLOW_CREATING_WORKSPACES);
+
+ String combinedWorkspaceNames = (String)values.get(PREDEFINED_WORKSPACE_NAMES);
+ String[] workspaceNames = null;
+ if (combinedWorkspaceNames != null) {
+ List<String> paths = StringUtil.splitLines(combinedWorkspaceNames);
+ workspaceNames = paths.toArray(new String[paths.size()]);
+ }
+ // Create the source instance ...
+ SvnRepositorySource source = new SvnRepositorySource();
+ if (sourceName != null) source.setName(sourceName);
+ if (repositoryRootUrl != null && repositoryRootUrl.length() > 0)
source.setRepositoryRootUrl(repositoryRootUrl);
+ if (username != null) source.setUsername(username);
+ if (password != null) source.setPassword(password);
+ if (retryLimit != null) source.setRetryLimit(Integer.parseInt(retryLimit));
+ if (rootNodeUuid != null) source.setRootNodeUuid(rootNodeUuid);
+ if (defaultWorkspace != null)
source.setDirectoryForDefaultWorkspace(defaultWorkspace);
+ if (createWorkspaces != null)
source.setCreatingWorkspacesAllowed(Boolean.parseBoolean(createWorkspaces));
+ if (workspaceNames != null && workspaceNames.length != 0)
source.setPredefinedWorkspaceNames(workspaceNames);
+ return source;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.graph.connector.RepositorySource#getConnection()
+ */
+ public synchronized RepositoryConnection getConnection() throws
RepositorySourceException {
+
+ String sourceName = getName();
+ if (sourceName == null || sourceName.trim().length() == 0) {
+ I18n msg = SvnRepositoryConnectorI18n.propertyIsRequired;
+ throw new RepositorySourceException(getName(), msg.text("name"));
+ }
+
+ String sourceUsername = getUsername();
+ if (sourceUsername == null || sourceUsername.trim().length() == 0) {
+ I18n msg = SvnRepositoryConnectorI18n.propertyIsRequired;
+ throw new RepositorySourceException(getUsername(),
msg.text("username"));
+ }
+
+ String sourcePassword = getPassword();
+ if (sourcePassword == null) {
+ I18n msg = SvnRepositoryConnectorI18n.propertyIsRequired;
+ throw new RepositorySourceException(getPassword(),
msg.text("password"));
+ }
+
+ String repositoryRootURL = getRepositoryRootUrl();
+ if (repositoryRootURL == null || repositoryRootURL.trim().length() == 0) {
+ I18n msg = SvnRepositoryConnectorI18n.propertyIsRequired;
+ throw new RepositorySourceException(getRepositoryRootUrl(),
msg.text("repositoryRootURL"));
+ }
+
+ if (this.repository == null) {
+ this.repository = new SvnRepository(this);
+ }
+
+ return new PathRepositoryConnection(this, this.repository);
+ }
+}
Copied:
trunk/extensions/dna-connector-svn/src/main/java/org/jboss/dna/connector/svn/SvnRepositoryUtil.java
(from rev 1524,
trunk/extensions/dna-connector-svn/src/main/java/org/jboss/dna/connector/svn2/SvnRepositoryUtil.java)
===================================================================
---
trunk/extensions/dna-connector-svn/src/main/java/org/jboss/dna/connector/svn/SvnRepositoryUtil.java
(rev 0)
+++
trunk/extensions/dna-connector-svn/src/main/java/org/jboss/dna/connector/svn/SvnRepositoryUtil.java 2010-01-05
12:50:08 UTC (rev 1525)
@@ -0,0 +1,235 @@
+/*
+ * 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 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;
+import org.tmatesoft.svn.core.SVNErrorCode;
+import org.tmatesoft.svn.core.SVNErrorMessage;
+import org.tmatesoft.svn.core.SVNException;
+import org.tmatesoft.svn.core.SVNNodeKind;
+import org.tmatesoft.svn.core.SVNURL;
+import org.tmatesoft.svn.core.auth.ISVNAuthenticationManager;
+import org.tmatesoft.svn.core.internal.io.dav.DAVRepositoryFactory;
+import org.tmatesoft.svn.core.internal.io.fs.FSRepositoryFactory;
+import org.tmatesoft.svn.core.internal.io.svn.SVNRepositoryFactoryImpl;
+import org.tmatesoft.svn.core.io.SVNRepository;
+import org.tmatesoft.svn.core.io.SVNRepositoryFactory;
+import org.tmatesoft.svn.core.wc.SVNWCUtil;
+
+/**
+ */
+public class SvnRepositoryUtil {
+
+ /**
+ * @param url
+ * @param sourceName
+ * @return SVNURL
+ */
+ public static SVNURL createSVNURL( String url,
+ String sourceName ) {
+
+ SVNURL theUrl;
+ try {
+ theUrl = SVNURL.parseURIDecoded(url);
+ } catch (SVNException e) {
+ // protocol not supported by this connector
+ throw new RepositorySourceException(sourceName,
+ "Protocol is not supported by this
connector or there is problem in the svn url");
+ }
+ return theUrl;
+ }
+
+ public static void setNewSVNRepositoryLocation( SVNRepository oldRespository,
+ String url,
+ boolean forceReconnect,
+ String sourceName ) {
+ try {
+ oldRespository.setLocation(createSVNURL(url, sourceName), forceReconnect);
+ } catch (SVNException e) {
+ throw new RepositorySourceException(sourceName, "the old url and a new
one has got different protocols");
+ }
+ }
+
+ /**
+ * @param repository
+ * @param path
+ * @param revisionNumber
+ * @param sourceName
+ * @return SVNNodeKind
+ */
+ public static SVNNodeKind checkThePath( SVNRepository repository,
+ String path,
+ long revisionNumber,
+ String sourceName ) {
+ SVNNodeKind kind;
+ try {
+ kind = repository.checkPath(path, revisionNumber);
+
+ } catch (SVNException e) {
+ return null;
+ }
+ return kind;
+ }
+
+ /**
+ * Create a {@link SVNRepository} from a http protocol.
+ *
+ * @param url - the url of the repository.
+ * @param username - username credential.
+ * @param password - password credential
+ * @return {@link SVNRepository}.
+ */
+ public static SVNRepository createRepository( String url,
+ String username,
+ String password ) {
+ // for DAV (over http and https)
+ DAVRepositoryFactory.setup();
+ // For File
+ FSRepositoryFactory.setup();
+ // for SVN (over svn and svn+ssh)
+ SVNRepositoryFactoryImpl.setup();
+
+ // The factory knows how to create a DAVRepository
+ SVNRepository repository;
+ try {
+ repository = SVNRepositoryFactory.create(SVNURL.parseURIDecoded(url));
+
+ ISVNAuthenticationManager authManager =
SVNWCUtil.createDefaultAuthenticationManager(username, password);
+ repository.setAuthenticationManager(authManager);
+ } catch (SVNException e) {
+ throw new
InvalidWorkspaceException(SvnRepositoryConnectorI18n.workspaceDoesNotExist.text(e.getMessage()));
+ }
+ return repository;
+ }
+
+ /**
+ * Util to get the last segment from a path.
+ *
+ * @param repository
+ * @return last segment.
+ */
+ public static String getRepositoryWorspaceName( SVNRepository repository ) {
+ String[] segments = repository.getLocation().getPath().split("/");
+ return segments[segments.length - 1];
+ }
+
+ private SvnRepositoryUtil() {
+ // prvent construction
+ }
+
+ /**
+ * Check if the repository path exist.
+ *
+ * @param repos
+ * @return true if repository exist and false otherwise.
+ */
+ public static boolean exist( SVNRepository repos ) {
+ try {
+ SVNNodeKind kind = repos.checkPath("", -1);
+ if (kind == SVNNodeKind.NONE) {
+ return false;
+ }
+ return true;
+
+ } catch (SVNException e) {
+ return false;
+ }
+ }
+
+ /**
+ * Check if repository path is a directory.
+ *
+ * @param repos
+ * @param path
+ * @return true if repository path is a directory and false otherwise.
+ */
+ public static boolean isDirectory( SVNRepository repos,
+ String path ) {
+ try {
+ SVNNodeKind kind = repos.checkPath(path, -1);
+ if (kind == SVNNodeKind.DIR) {
+ return true;
+ }
+ } catch (SVNException e) {
+ return false;
+ }
+ return false;
+ }
+
+ /**
+ * @param repos
+ * @param path
+ * @return a collect of entry from directory path; never null
+ */
+ @SuppressWarnings( "unchecked" )
+ public static Collection<SVNDirEntry> getDir( SVNRepository repos,
+ String path ) {
+ try {
+ return repos.getDir(path, -1, null, (Collection<SVNDirEntry>)null);
+ } catch (SVNException e) {
+ return Collections.emptyList();
+ }
+ }
+
+ /**
+ * Check if the path is a file.
+ *
+ * @param repos
+ * @param path
+ * @return true if the path is a file and false otherwise.
+ */
+ public static boolean isFile( SVNRepository repos,
+ String path ) {
+ try {
+ SVNNodeKind kind = repos.checkPath(path, -1);
+ if (kind == SVNNodeKind.FILE) {
+ return true;
+ }
+ } catch (SVNException e) {
+ return false;
+ }
+ return false;
+ }
+
+ public static boolean exists( SVNRepository repository,
+ String path ) throws SVNException{
+ try {
+ if (repository.checkPath(path, -1) == SVNNodeKind.NONE) {
+ return false;
+ } else if (repository.checkPath(path, -1) == SVNNodeKind.UNKNOWN) {
+ return false;
+ }
+ } catch (SVNException e) {
+ SVNErrorMessage err = SVNErrorMessage.create(SVNErrorCode.UNKNOWN,
+ "unknow error during delete
action: {0)",
+ e.getMessage());
+ throw new SVNException(err);
+ }
+ return true;
+ }
+}
Copied:
trunk/extensions/dna-connector-svn/src/main/java/org/jboss/dna/connector/svn/package-info.java
(from rev 1524,
trunk/extensions/dna-connector-svn/src/main/java/org/jboss/dna/connector/svn2/package-info.java)
===================================================================
---
trunk/extensions/dna-connector-svn/src/main/java/org/jboss/dna/connector/svn/package-info.java
(rev 0)
+++
trunk/extensions/dna-connector-svn/src/main/java/org/jboss/dna/connector/svn/package-info.java 2010-01-05
12:50:08 UTC (rev 1525)
@@ -0,0 +1,29 @@
+/*
+ * 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.
+ */
+/**
+ * The classes that make up the connector that accesses content from an SVN repository.
+ */
+
+package org.jboss.dna.connector.svn;
+
Copied: trunk/extensions/dna-connector-svn/src/main/resources/org/jboss/dna/connector/svn
(from rev 1524,
trunk/extensions/dna-connector-svn/src/main/resources/org/jboss/dna/connector/svn2)
Copied: trunk/extensions/dna-connector-svn/src/test/java/org/jboss/dna/connector/svn (from
rev 1524, trunk/extensions/dna-connector-svn/src/test/java/org/jboss/dna/connector/svn2)
Modified:
trunk/extensions/dna-connector-svn/src/test/java/org/jboss/dna/connector/svn/SvnConnectorTestUtil.java
===================================================================
---
trunk/extensions/dna-connector-svn/src/test/java/org/jboss/dna/connector/svn2/SvnConnectorTestUtil.java 2010-01-05
12:43:25 UTC (rev 1524)
+++
trunk/extensions/dna-connector-svn/src/test/java/org/jboss/dna/connector/svn/SvnConnectorTestUtil.java 2010-01-05
12:50:08 UTC (rev 1525)
@@ -21,7 +21,7 @@
* 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.svn2;
+package org.jboss.dna.connector.svn;
import java.io.File;
import java.io.IOException;
Modified:
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/svn2/SvnIntegrationTest.java 2010-01-05
12:43:25 UTC (rev 1524)
+++
trunk/extensions/dna-connector-svn/src/test/java/org/jboss/dna/connector/svn/SvnIntegrationTest.java 2010-01-05
12:50:08 UTC (rev 1525)
@@ -21,12 +21,13 @@
* 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.svn2;
+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.connector.svn.SvnRepositorySource;
import org.jboss.dna.graph.ExecutionContext;
import org.jboss.dna.graph.Graph;
import org.jboss.dna.graph.Location;
Modified:
trunk/extensions/dna-connector-svn/src/test/java/org/jboss/dna/connector/svn/SvnRepositoryConnectorI18nTest.java
===================================================================
---
trunk/extensions/dna-connector-svn/src/test/java/org/jboss/dna/connector/svn2/SvnRepositoryConnectorI18nTest.java 2010-01-05
12:43:25 UTC (rev 1524)
+++
trunk/extensions/dna-connector-svn/src/test/java/org/jboss/dna/connector/svn/SvnRepositoryConnectorI18nTest.java 2010-01-05
12:50:08 UTC (rev 1525)
@@ -21,9 +21,10 @@
* 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.svn2;
+package org.jboss.dna.connector.svn;
import org.jboss.dna.common.AbstractI18nTest;
+import org.jboss.dna.connector.svn.SvnRepositoryConnectorI18n;
/**
*/
Modified:
trunk/extensions/dna-connector-svn/src/test/java/org/jboss/dna/connector/svn/SvnRepositoryConnectorNoCreateWorkspaceTest.java
===================================================================
---
trunk/extensions/dna-connector-svn/src/test/java/org/jboss/dna/connector/svn2/SvnRepositoryConnectorNoCreateWorkspaceTest.java 2010-01-05
12:43:25 UTC (rev 1524)
+++
trunk/extensions/dna-connector-svn/src/test/java/org/jboss/dna/connector/svn/SvnRepositoryConnectorNoCreateWorkspaceTest.java 2010-01-05
12:50:08 UTC (rev 1525)
@@ -1,5 +1,6 @@
-package org.jboss.dna.connector.svn2;
+package org.jboss.dna.connector.svn;
+import org.jboss.dna.connector.svn.SvnRepositorySource;
import org.jboss.dna.graph.Graph;
import org.jboss.dna.graph.connector.RepositorySource;
import org.jboss.dna.graph.connector.test.WorkspaceConnectorTest;
Modified:
trunk/extensions/dna-connector-svn/src/test/java/org/jboss/dna/connector/svn/SvnRepositoryConnectorNotWritableTest.java
===================================================================
---
trunk/extensions/dna-connector-svn/src/test/java/org/jboss/dna/connector/svn2/SvnRepositoryConnectorNotWritableTest.java 2010-01-05
12:43:25 UTC (rev 1524)
+++
trunk/extensions/dna-connector-svn/src/test/java/org/jboss/dna/connector/svn/SvnRepositoryConnectorNotWritableTest.java 2010-01-05
12:50:08 UTC (rev 1525)
@@ -1,5 +1,6 @@
-package org.jboss.dna.connector.svn2;
+package org.jboss.dna.connector.svn;
+import org.jboss.dna.connector.svn.SvnRepositorySource;
import org.jboss.dna.graph.Graph;
import org.jboss.dna.graph.connector.RepositorySource;
import org.jboss.dna.graph.connector.test.NotWritableConnectorTest;
Modified:
trunk/extensions/dna-connector-svn/src/test/java/org/jboss/dna/connector/svn/SvnRepositoryConnectorWritableTest.java
===================================================================
---
trunk/extensions/dna-connector-svn/src/test/java/org/jboss/dna/connector/svn2/SvnRepositoryConnectorWritableTest.java 2010-01-05
12:43:25 UTC (rev 1524)
+++
trunk/extensions/dna-connector-svn/src/test/java/org/jboss/dna/connector/svn/SvnRepositoryConnectorWritableTest.java 2010-01-05
12:50:08 UTC (rev 1525)
@@ -21,12 +21,13 @@
* 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.svn2;
+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.io.ByteArrayOutputStream;
+import org.jboss.dna.connector.svn.SvnRepositorySource;
import org.jboss.dna.graph.DnaLexicon;
import org.jboss.dna.graph.Graph;
import org.jboss.dna.graph.JcrLexicon;
Modified:
trunk/extensions/dna-connector-svn/src/test/java/org/jboss/dna/connector/svn/SvnRepositorySourceTest.java
===================================================================
---
trunk/extensions/dna-connector-svn/src/test/java/org/jboss/dna/connector/svn2/SvnRepositorySourceTest.java 2010-01-05
12:43:25 UTC (rev 1524)
+++
trunk/extensions/dna-connector-svn/src/test/java/org/jboss/dna/connector/svn/SvnRepositorySourceTest.java 2010-01-05
12:50:08 UTC (rev 1525)
@@ -21,7 +21,7 @@
* 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.svn2;
+package org.jboss.dna.connector.svn;
import static org.hamcrest.core.Is.is;
import static org.hamcrest.core.IsNull.notNullValue;
@@ -42,6 +42,7 @@
import javax.naming.RefAddr;
import javax.naming.Reference;
import javax.naming.spi.ObjectFactory;
+import org.jboss.dna.connector.svn.SvnRepositorySource;
import org.jboss.dna.graph.ExecutionContext;
import org.jboss.dna.graph.Subgraph;
import org.jboss.dna.graph.cache.BasicCachePolicy;
Modified:
trunk/extensions/dna-connector-svn/src/test/java/org/jboss/dna/connector/svn/SvnRespositoryConnectorReadableTest.java
===================================================================
---
trunk/extensions/dna-connector-svn/src/test/java/org/jboss/dna/connector/svn2/SvnRespositoryConnectorReadableTest.java 2010-01-05
12:43:25 UTC (rev 1524)
+++
trunk/extensions/dna-connector-svn/src/test/java/org/jboss/dna/connector/svn/SvnRespositoryConnectorReadableTest.java 2010-01-05
12:50:08 UTC (rev 1525)
@@ -21,12 +21,13 @@
* 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.svn2;
+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.List;
+import org.jboss.dna.connector.svn.SvnRepositorySource;
import org.jboss.dna.graph.Graph;
import org.jboss.dna.graph.JcrLexicon;
import org.jboss.dna.graph.JcrNtLexicon;