implement svn client provider

This commit is contained in:
Sebastian Sdorra
2017-01-13 22:38:54 +01:00
parent b5aaf1ca4e
commit b5d59fabd4
8 changed files with 549 additions and 18 deletions

View File

@@ -0,0 +1,54 @@
/**
* Copyright (c) 2014, Sebastian Sdorra
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of SCM-Manager; nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* http://bitbucket.org/sdorra/scm-manager
*
*/
package sonia.scm.repository.client.spi;
import java.io.File;
import java.io.IOException;
import java.util.List;
/**
* Add files to subversion repository.
*
* @author Sebastian Sdorra
* @since 1.51
*/
public final class SvnAddCommand extends SvnFileCommand implements AddCommand {
SvnAddCommand(File workingCopy, List<File> pendingFiles) {
super(workingCopy, pendingFiles);
}
@Override
public void add(String path) throws IOException {
append(path);
}
}

View File

@@ -0,0 +1,142 @@
/**
* Copyright (c) 2014, Sebastian Sdorra
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of SCM-Manager; nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* http://bitbucket.org/sdorra/scm-manager
*
*/
package sonia.scm.repository.client.spi;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.tmatesoft.svn.core.SVNCommitInfo;
import org.tmatesoft.svn.core.SVNDepth;
import org.tmatesoft.svn.core.SVNErrorMessage;
import org.tmatesoft.svn.core.SVNException;
import org.tmatesoft.svn.core.wc.SVNClientManager;
import org.tmatesoft.svn.core.wc.SVNRevision;
import org.tmatesoft.svn.core.wc.SVNWCClient;
import org.tmatesoft.svn.core.wc2.SvnCommit;
import org.tmatesoft.svn.core.wc2.SvnLog;
import org.tmatesoft.svn.core.wc2.SvnRevisionRange;
import org.tmatesoft.svn.core.wc2.SvnTarget;
import sonia.scm.repository.Changeset;
import sonia.scm.repository.SvnUtil;
/**
*
* @author Sebastian Sdorra
*/
public class SvnCommitCommand implements CommitCommand {
private final SVNClientManager client;
private final File workingCopy;
private final List<File> addedFiles;
private final List<File> removedFiles;
SvnCommitCommand(SVNClientManager client, File workingCopy, List<File> addedFiles, List<File> removedFiles) {
this.client = client;
this.workingCopy = workingCopy;
this.addedFiles = addedFiles;
this.removedFiles = removedFiles;
}
@Override
public Changeset commit(CommitRequest request) throws IOException {
SVNWCClient wClient = client.getWCClient();
List<File> filesToCommit = new ArrayList<>();
// add files
try {
wClient.doAdd(addedFiles.toArray(new File[0]), true, false, false,
SVNDepth.INFINITY, false, false, false);
filesToCommit.addAll(addedFiles);
addedFiles.clear();
} catch (SVNException ex) {
throw new IOException("failed to add files", ex);
}
// remove files
try {
Iterator<File> removeIt = removedFiles.iterator();
while (removeIt.hasNext()) {
File file = removeIt.next();
wClient.doDelete(file, false, true, false);
removeIt.remove();
filesToCommit.add(file);
}
} catch (SVNException ex) {
throw new IOException("failed to remove files", ex);
}
SvnTarget workingCopyTarget = SvnTarget.fromFile(workingCopy);
Changeset changeset;
SVNCommitInfo info;
// commit files
try {
SvnCommit commit = client.getOperationFactory().createCommit();
commit.setDepth(SVNDepth.INFINITY);
commit.setCommitMessage(request.getMessage());
commit.setSingleTarget(workingCopyTarget);
info = commit.run();
SVNErrorMessage msg = info.getErrorMessage();
if (msg != null) {
throw new IOException(msg.getFullMessage());
}
} catch (SVNException ex) {
throw new IOException("failed to commit", ex);
}
// get log for commit
try {
SVNRevision revision = SVNRevision.create(info.getNewRevision());
SvnLog log = client.getOperationFactory().createLog();
log.addRange(SvnRevisionRange.create(revision, revision));
log.setSingleTarget(workingCopyTarget);
changeset = SvnUtil.createChangeset(log.run());
} catch (SVNException ex) {
throw new IOException("failed to create log entry for last commit", ex);
}
return changeset;
}
}

View File

@@ -0,0 +1,62 @@
/**
* Copyright (c) 2014, Sebastian Sdorra
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of SCM-Manager; nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* http://bitbucket.org/sdorra/scm-manager
*
*/
package sonia.scm.repository.client.spi;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.List;
/**
* Abstract file based svn command.
*
* @author Sebastian Sdorra
* @since 1.51
*/
public abstract class SvnFileCommand {
private final File workingCopy;
private final List<File> pendingFiles;
protected SvnFileCommand(File workingCopy, List<File> pendingFiles) {
this.workingCopy = workingCopy;
this.pendingFiles = pendingFiles;
}
protected void append(String path) throws FileNotFoundException {
File file = new File(workingCopy, path);
if (!file.exists()) {
throw new FileNotFoundException("could not find file ".concat(path));
}
pendingFiles.add(file);
}
}

View File

@@ -0,0 +1,54 @@
/**
* Copyright (c) 2014, Sebastian Sdorra
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of SCM-Manager; nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* http://bitbucket.org/sdorra/scm-manager
*
*/
package sonia.scm.repository.client.spi;
import java.io.File;
import java.io.IOException;
import java.util.List;
/**
* Remove files from subversion repository.
*
* @author Sebastian Sdorra
* @since 1.51
*/
public class SvnRemoveCommand extends SvnFileCommand implements RemoveCommand {
SvnRemoveCommand(File workingCopy, List<File> pendingFiles) {
super(workingCopy, pendingFiles);
}
@Override
public void remove(String path) throws IOException {
append(path);
}
}

View File

@@ -0,0 +1,124 @@
/**
* Copyright (c) 2014, Sebastian Sdorra
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of SCM-Manager; nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* http://bitbucket.org/sdorra/scm-manager
*
*/
package sonia.scm.repository.client.spi;
import java.io.File;
import java.io.IOException;
import org.tmatesoft.svn.core.SVNDepth;
import org.tmatesoft.svn.core.SVNException;
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.wc.DefaultSVNOptions;
import org.tmatesoft.svn.core.wc.SVNClientManager;
import org.tmatesoft.svn.core.wc.SVNRevision;
import org.tmatesoft.svn.core.wc.SVNUpdateClient;
import org.tmatesoft.svn.core.wc.SVNWCUtil;
import org.tmatesoft.svn.core.wc2.SvnOperationFactory;
import sonia.scm.repository.SvnRepositoryHandler;
/**
* Client provider factory for subversion.
*
* @author Sebastian Sdorra
* @since 1.51
*/
public class SvnRepositoryClientFactoryProvider implements RepositoryClientFactoryProvider {
@Override
public RepositoryClientProvider create(File main, File workingCopy) throws IOException {
// create uri from file
SVNURL source;
try {
source = SVNURL.fromFile(workingCopy);
} catch (SVNException ex) {
throw new IOException("failed to parse svn url", ex);
}
// create client
SVNClientManager client = SVNClientManager.newInstance();
SVNUpdateClient updateClient = client.getUpdateClient();
try {
updateClient.doCheckout(source, workingCopy, SVNRevision.HEAD, SVNRevision.HEAD, SVNDepth.INFINITY, true);
} catch (SVNException ex) {
throw new IOException("failed to checkout repository", ex);
}
// return client provider
return new SvnRepositoryClientProvider(client, source, workingCopy);
}
@Override
public RepositoryClientProvider create(String url, String username, String password, File workingCopy)
throws IOException {
// create svn options
DefaultSVNOptions options = new DefaultSVNOptions();
options.setAuthStorageEnabled(false);
options.setUseAutoProperties(false);
// create client
SVNClientManager client = SVNClientManager.newInstance(new SvnOperationFactory());
client.setOptions(options);
if ((username != null) && (password != null)) {
ISVNAuthenticationManager auth = SVNWCUtil.createDefaultAuthenticationManager(null, username, password, false);
client.setAuthenticationManager(auth);
}
// init dav
DAVRepositoryFactory.setup();
// parse remote uri
SVNURL remoteUrl;
try {
remoteUrl = SVNURL.parseURIEncoded(url);
} catch (SVNException ex) {
throw new IOException("failed to parse svn url", ex);
}
// initial checkout
SVNUpdateClient updateClient = client.getUpdateClient();
try {
updateClient.doCheckout(remoteUrl, workingCopy, SVNRevision.HEAD, SVNRevision.HEAD, SVNDepth.INFINITY, true);
} catch (SVNException ex) {
throw new IOException("failed to checkout repository", ex);
}
// return client provider
return new SvnRepositoryClientProvider(client, remoteUrl, workingCopy);
}
@Override
public String getType() {
return SvnRepositoryHandler.TYPE_NAME;
}
}

View File

@@ -0,0 +1,87 @@
/**
* Copyright (c) 2014, Sebastian Sdorra
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of SCM-Manager; nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* http://bitbucket.org/sdorra/scm-manager
*
*/
package sonia.scm.repository.client.spi;
import com.google.common.collect.ImmutableSet;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import org.tmatesoft.svn.core.SVNURL;
import org.tmatesoft.svn.core.wc.SVNClientManager;
import sonia.scm.repository.client.api.ClientCommand;
/**
* Subversion repository client provider.
*
* @author Sebastian Sdorra
* @since 1.51
*/
public class SvnRepositoryClientProvider extends RepositoryClientProvider {
private static final Set<ClientCommand> SUPPORTED_COMMANDS = ImmutableSet.of(
ClientCommand.ADD, ClientCommand.REMOVE, ClientCommand.COMMIT
);
private final SVNClientManager client;
private final SVNURL remoteRepositoryURL;
private final File workingCopy;
private final List<File> addedFiles = new ArrayList<>();
private final List<File> removedFiles = new ArrayList<>();
SvnRepositoryClientProvider(SVNClientManager client, SVNURL remoteRepositoryURL, File workingCopy) {
this.client = client;
this.remoteRepositoryURL = remoteRepositoryURL;
this.workingCopy = workingCopy;
}
@Override
public SvnAddCommand getAddCommand() {
return new SvnAddCommand(workingCopy, addedFiles);
}
@Override
public SvnRemoveCommand getRemoveCommand() {
return new SvnRemoveCommand(workingCopy, removedFiles);
}
@Override
public SvnCommitCommand getCommitCommand() {
return new SvnCommitCommand(client, workingCopy, addedFiles, removedFiles);
}
@Override
public Set<ClientCommand> getSupportedClientCommands() {
return SUPPORTED_COMMANDS;
}
}

View File

@@ -0,0 +1 @@
sonia.scm.repository.client.spi.SvnRepositoryClientFactoryProvider