From 75c244fcdbd9d5897f13298527872432f5e9cdcd Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Sun, 2 Nov 2014 10:44:17 +0100 Subject: [PATCH] improve bundle/unbundle api, by using ByteSource and ByteSink --- .../repository/api/BundleCommandBuilder.java | 80 ++++++++++- .../scm/repository/api/BundleResponse.java | 2 +- .../api/UnbundleCommandBuilder.java | 78 +++++++++- .../scm/repository/api/UnbundleResponse.java | 2 +- .../repository/spi/ArchiveCommandRequest.java | 136 ------------------ .../scm/repository/spi/BundleCommand.java | 2 +- .../repository/spi/BundleCommandRequest.java | 80 ++++++++++- .../scm/repository/spi/UnbundleCommand.java | 2 +- .../spi/UnbundleCommandRequest.java | 80 ++++++++++- .../spi/AbstractHgPushOrPullCommand.java | 2 +- .../scm/repository/spi/SvnBundleCommand.java | 11 +- .../repository/spi/SvnUnbundleCommand.java | 12 +- 12 files changed, 326 insertions(+), 161 deletions(-) delete mode 100644 scm-core/src/main/java/sonia/scm/repository/spi/ArchiveCommandRequest.java diff --git a/scm-core/src/main/java/sonia/scm/repository/api/BundleCommandBuilder.java b/scm-core/src/main/java/sonia/scm/repository/api/BundleCommandBuilder.java index f2a2d93ddc..864ce62de1 100644 --- a/scm-core/src/main/java/sonia/scm/repository/api/BundleCommandBuilder.java +++ b/scm-core/src/main/java/sonia/scm/repository/api/BundleCommandBuilder.java @@ -35,6 +35,11 @@ package sonia.scm.repository.api; //~--- non-JDK imports -------------------------------------------------------- +import com.google.common.io.ByteSink; +import com.google.common.io.ByteStreams; +import com.google.common.io.Files; +import com.google.common.io.OutputSupplier; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -43,14 +48,17 @@ import sonia.scm.repository.RepositoryException; import sonia.scm.repository.spi.BundleCommand; import sonia.scm.repository.spi.BundleCommandRequest; +import static com.google.common.base.Preconditions.*; + //~--- JDK imports ------------------------------------------------------------ import java.io.File; import java.io.IOException; +import java.io.OutputStream; /** * - * @author Sebastian Sdorra + * @author Sebastian Sdorra * @since 1.43 */ public final class BundleCommandBuilder @@ -92,15 +100,81 @@ public final class BundleCommandBuilder public BundleResponse bundle(File outputFile) throws IOException, RepositoryException { - BundleCommandRequest request = new BundleCommandRequest(); + checkArgument((outputFile != null) &&!outputFile.exists(), + "file is null or exists already"); + + BundleCommandRequest request = + new BundleCommandRequest(Files.asByteSink(outputFile)); - request.setArchive(outputFile); logger.info("create bundle at {} for repository {}", outputFile, repository.getId()); return bundleCommand.bundle(request); } + /** + * Method description + * + * + * @param outputStream + * + * @return + * + * @throws IOException + * @throws RepositoryException + */ + public BundleResponse bundle(OutputStream outputStream) + throws IOException, RepositoryException + { + checkNotNull(outputStream, "output stream is required"); + + logger.info("bundle {} to output stream", repository.getId()); + + return bundleCommand.bundle( + new BundleCommandRequest(asByteSink(outputStream))); + } + + /** + * Method description + * + * + * @param sink + * + * @return + * + * @throws IOException + * @throws RepositoryException + */ + public BundleResponse bundle(ByteSink sink) + throws IOException, RepositoryException + { + checkNotNull(sink, "byte sink is required"); + logger.info("bundle {} to byte sink"); + + return bundleCommand.bundle(new BundleCommandRequest(sink)); + } + + /** + * Method description + * + * + * @param outputStream + * + * @return + */ + private ByteSink asByteSink(final OutputStream outputStream) + { + return ByteStreams.asByteSink(new OutputSupplier() + { + + @Override + public OutputStream getOutput() throws IOException + { + return outputStream; + } + }); + } + //~--- fields --------------------------------------------------------------- /** Field description */ diff --git a/scm-core/src/main/java/sonia/scm/repository/api/BundleResponse.java b/scm-core/src/main/java/sonia/scm/repository/api/BundleResponse.java index 473161963d..ee0b51a06d 100644 --- a/scm-core/src/main/java/sonia/scm/repository/api/BundleResponse.java +++ b/scm-core/src/main/java/sonia/scm/repository/api/BundleResponse.java @@ -35,7 +35,7 @@ package sonia.scm.repository.api; /** * - * @author Sebastian Sdorra + * @author Sebastian Sdorra * @since 1.43 */ public class BundleResponse {} diff --git a/scm-core/src/main/java/sonia/scm/repository/api/UnbundleCommandBuilder.java b/scm-core/src/main/java/sonia/scm/repository/api/UnbundleCommandBuilder.java index 7da034ade9..7ae836e682 100644 --- a/scm-core/src/main/java/sonia/scm/repository/api/UnbundleCommandBuilder.java +++ b/scm-core/src/main/java/sonia/scm/repository/api/UnbundleCommandBuilder.java @@ -35,6 +35,11 @@ package sonia.scm.repository.api; //~--- non-JDK imports -------------------------------------------------------- +import com.google.common.io.ByteSource; +import com.google.common.io.ByteStreams; +import com.google.common.io.Files; +import com.google.common.io.InputSupplier; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -43,14 +48,17 @@ import sonia.scm.repository.RepositoryException; import sonia.scm.repository.spi.UnbundleCommand; import sonia.scm.repository.spi.UnbundleCommandRequest; +import static com.google.common.base.Preconditions.*; + //~--- JDK imports ------------------------------------------------------------ import java.io.File; import java.io.IOException; +import java.io.InputStream; /** * - * @author Sebastian Sdorra + * @author Sebastian Sdorra * @since 1.43 */ public final class UnbundleCommandBuilder @@ -92,15 +100,79 @@ public final class UnbundleCommandBuilder public UnbundleResponse unbundle(File inputFile) throws IOException, RepositoryException { - UnbundleCommandRequest request = new UnbundleCommandRequest(); + checkArgument((inputFile != null) && inputFile.exists(), + "existing file is required"); - request.setArchive(inputFile); + UnbundleCommandRequest request = + new UnbundleCommandRequest(Files.asByteSource(inputFile)); logger.info("unbundle archive {} at {}", inputFile, repository.getId()); return unbundleCommand.unbundle(request); } + /** + * Method description + * + * + * @param inputStream + * + * @return + * + * @throws IOException + * @throws RepositoryException + */ + public UnbundleResponse unbundle(InputStream inputStream) + throws IOException, RepositoryException + { + checkNotNull(inputStream, "input stream is required"); + logger.info("unbundle archive from stream"); + + return unbundleCommand.unbundle( + new UnbundleCommandRequest(asByteSource(inputStream))); + } + + /** + * Method description + * + * + * @param byteSource + * + * @return + * + * @throws IOException + * @throws RepositoryException + */ + public UnbundleResponse unbundle(ByteSource byteSource) + throws IOException, RepositoryException + { + checkNotNull(byteSource, "byte source is required"); + logger.info("unbundle from byte source"); + + return unbundleCommand.unbundle(new UnbundleCommandRequest(byteSource)); + } + + /** + * Method description + * + * + * @param inputStream + * + * @return + */ + private ByteSource asByteSource(final InputStream inputStream) + { + return ByteStreams.asByteSource(new InputSupplier() + { + + @Override + public InputStream getInput() throws IOException + { + return inputStream; + } + }); + } + //~--- fields --------------------------------------------------------------- /** Field description */ diff --git a/scm-core/src/main/java/sonia/scm/repository/api/UnbundleResponse.java b/scm-core/src/main/java/sonia/scm/repository/api/UnbundleResponse.java index 12c8cbff2f..bf5c115ff8 100644 --- a/scm-core/src/main/java/sonia/scm/repository/api/UnbundleResponse.java +++ b/scm-core/src/main/java/sonia/scm/repository/api/UnbundleResponse.java @@ -35,7 +35,7 @@ package sonia.scm.repository.api; /** * - * @author Sebastian Sdorra + * @author Sebastian Sdorra * @since 1.43 */ public class UnbundleResponse {} diff --git a/scm-core/src/main/java/sonia/scm/repository/spi/ArchiveCommandRequest.java b/scm-core/src/main/java/sonia/scm/repository/spi/ArchiveCommandRequest.java deleted file mode 100644 index 478afc6cf0..0000000000 --- a/scm-core/src/main/java/sonia/scm/repository/spi/ArchiveCommandRequest.java +++ /dev/null @@ -1,136 +0,0 @@ -/** - * Copyright (c) 2010, 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.spi; - -//~--- non-JDK imports -------------------------------------------------------- - -import com.google.common.base.Objects; - -//~--- JDK imports ------------------------------------------------------------ - -import java.io.File; - -/** - * - * @author Sebastian Sdorra - * @since 1.43 - */ -public abstract class ArchiveCommandRequest -{ - - /** - * Method description - * - * - * @param obj - * - * @return - */ - @Override - public boolean equals(Object obj) - { - if (obj == null) - { - return false; - } - - if (getClass() != obj.getClass()) - { - return false; - } - - final ArchiveCommandRequest other = (ArchiveCommandRequest) obj; - - return Objects.equal(archive, other.archive); - } - - /** - * Method description - * - * - * @return - */ - @Override - public int hashCode() - { - return Objects.hashCode(archive); - } - - /** - * Method description - * - * - * @return - */ - @Override - public String toString() - { - //J- - return Objects.toStringHelper(this) - .add("archive", archive) - .toString(); - //J+ - } - - //~--- get methods ---------------------------------------------------------- - - /** - * Method description - * - * - * @return - */ - public File getArchive() - { - return archive; - } - - //~--- set methods ---------------------------------------------------------- - - /** - * Method description - * - * - * @param archive - */ - public void setArchive(File archive) - { - this.archive = archive; - } - - //~--- fields --------------------------------------------------------------- - - /** Field description */ - private File archive; -} diff --git a/scm-core/src/main/java/sonia/scm/repository/spi/BundleCommand.java b/scm-core/src/main/java/sonia/scm/repository/spi/BundleCommand.java index 69cf3be387..44500b5709 100644 --- a/scm-core/src/main/java/sonia/scm/repository/spi/BundleCommand.java +++ b/scm-core/src/main/java/sonia/scm/repository/spi/BundleCommand.java @@ -44,7 +44,7 @@ import java.io.IOException; /** * - * @author Sebastian Sdorra + * @author Sebastian Sdorra * @since 1.43 */ public interface BundleCommand diff --git a/scm-core/src/main/java/sonia/scm/repository/spi/BundleCommandRequest.java b/scm-core/src/main/java/sonia/scm/repository/spi/BundleCommandRequest.java index 6ebd054035..f354ae94a1 100644 --- a/scm-core/src/main/java/sonia/scm/repository/spi/BundleCommandRequest.java +++ b/scm-core/src/main/java/sonia/scm/repository/spi/BundleCommandRequest.java @@ -33,9 +33,85 @@ package sonia.scm.repository.spi; +//~--- non-JDK imports -------------------------------------------------------- + +import com.google.common.base.Objects; +import com.google.common.io.ByteSink; + /** * - * @author Sebastian Sdorra + * @author Sebastian Sdorra * @since 1.43 */ -public class BundleCommandRequest extends ArchiveCommandRequest {} +public final class BundleCommandRequest +{ + + /** + * Constructs ... + * + * + * @param archive + */ + public BundleCommandRequest(ByteSink archive) + { + this.archive = archive; + } + + //~--- methods -------------------------------------------------------------- + + /** + * Method description + * + * + * @param obj + * + * @return + */ + @Override + public boolean equals(Object obj) + { + if (obj == null) + { + return false; + } + + if (getClass() != obj.getClass()) + { + return false; + } + + final BundleCommandRequest other = (BundleCommandRequest) obj; + + return Objects.equal(archive, other.archive); + } + + /** + * Method description + * + * + * @return + */ + @Override + public int hashCode() + { + return Objects.hashCode(archive); + } + + //~--- get methods ---------------------------------------------------------- + + /** + * Method description + * + * + * @return + */ + ByteSink getArchive() + { + return archive; + } + + //~--- fields --------------------------------------------------------------- + + /** Field description */ + private final ByteSink archive; +} diff --git a/scm-core/src/main/java/sonia/scm/repository/spi/UnbundleCommand.java b/scm-core/src/main/java/sonia/scm/repository/spi/UnbundleCommand.java index 5a3ac0b786..6861e481fe 100644 --- a/scm-core/src/main/java/sonia/scm/repository/spi/UnbundleCommand.java +++ b/scm-core/src/main/java/sonia/scm/repository/spi/UnbundleCommand.java @@ -44,7 +44,7 @@ import java.io.IOException; /** * - * @author Sebastian Sdorra + * @author Sebastian Sdorra * @since 1.43 */ public interface UnbundleCommand diff --git a/scm-core/src/main/java/sonia/scm/repository/spi/UnbundleCommandRequest.java b/scm-core/src/main/java/sonia/scm/repository/spi/UnbundleCommandRequest.java index 57400d0f9a..0378a385c0 100644 --- a/scm-core/src/main/java/sonia/scm/repository/spi/UnbundleCommandRequest.java +++ b/scm-core/src/main/java/sonia/scm/repository/spi/UnbundleCommandRequest.java @@ -33,9 +33,85 @@ package sonia.scm.repository.spi; +//~--- non-JDK imports -------------------------------------------------------- + +import com.google.common.base.Objects; +import com.google.common.io.ByteSource; + /** * - * @author Sebastian Sdorra + * @author Sebastian Sdorra * @since 1.43 */ -public class UnbundleCommandRequest extends ArchiveCommandRequest {} +public final class UnbundleCommandRequest +{ + + /** + * Constructs ... + * + * + * @param archive + */ + public UnbundleCommandRequest(ByteSource archive) + { + this.archive = archive; + } + + //~--- methods -------------------------------------------------------------- + + /** + * Method description + * + * + * @param obj + * + * @return + */ + @Override + public boolean equals(Object obj) + { + if (obj == null) + { + return false; + } + + if (getClass() != obj.getClass()) + { + return false; + } + + final UnbundleCommandRequest other = (UnbundleCommandRequest) obj; + + return Objects.equal(archive, other.archive); + } + + /** + * Method description + * + * + * @return + */ + @Override + public int hashCode() + { + return Objects.hashCode(archive); + } + + //~--- get methods ---------------------------------------------------------- + + /** + * Method description + * + * + * @return + */ + ByteSource getArchive() + { + return archive; + } + + //~--- fields --------------------------------------------------------------- + + /** Field description */ + private final ByteSource archive; +} diff --git a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/AbstractHgPushOrPullCommand.java b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/AbstractHgPushOrPullCommand.java index a3b159fbfb..43fb759433 100644 --- a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/AbstractHgPushOrPullCommand.java +++ b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/AbstractHgPushOrPullCommand.java @@ -40,7 +40,7 @@ import sonia.scm.repository.Repository; /** * - * @author Sebastian Sdorra + * @author Sebastian Sdorra */ public class AbstractHgPushOrPullCommand extends AbstractCommand { diff --git a/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/spi/SvnBundleCommand.java b/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/spi/SvnBundleCommand.java index d514a51ac1..bf02cc7d0e 100644 --- a/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/spi/SvnBundleCommand.java +++ b/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/spi/SvnBundleCommand.java @@ -35,6 +35,7 @@ package sonia.scm.repository.spi; //~--- non-JDK imports -------------------------------------------------------- +import com.google.common.io.ByteSink; import com.google.common.io.Closeables; import org.tmatesoft.svn.core.SVNException; @@ -52,13 +53,12 @@ import static com.google.common.base.Preconditions.*; //~--- JDK imports ------------------------------------------------------------ import java.io.File; -import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; /** * - * @author Sebastian Sdorra + * @author Sebastian Sdorra */ public class SvnBundleCommand extends AbstractSvnCommand implements BundleCommand @@ -90,14 +90,14 @@ public class SvnBundleCommand extends AbstractSvnCommand * @throws SVNException */ private static void dump(SVNAdminClient adminClient, File repository, - File target) + ByteSink target) throws SVNException, IOException { OutputStream outputStream = null; try { - outputStream = new FileOutputStream(target); + outputStream = target.openBufferedStream(); adminClient.doDump(repository, outputStream, SVNRevision.create(-1l), SVNRevision.HEAD, false, false); } @@ -122,7 +122,8 @@ public class SvnBundleCommand extends AbstractSvnCommand public BundleResponse bundle(BundleCommandRequest request) throws IOException, RepositoryException { - File archive = checkNotNull(request.getArchive(), "archive is required"); + ByteSink archive = checkNotNull(request.getArchive(), + "archive is required"); SVNClientManager clientManager = null; diff --git a/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/spi/SvnUnbundleCommand.java b/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/spi/SvnUnbundleCommand.java index e83d0664e0..f7479caeaa 100644 --- a/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/spi/SvnUnbundleCommand.java +++ b/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/spi/SvnUnbundleCommand.java @@ -35,6 +35,7 @@ package sonia.scm.repository.spi; //~--- non-JDK imports -------------------------------------------------------- +import com.google.common.io.ByteSource; import com.google.common.io.Closeables; import org.slf4j.Logger; @@ -53,13 +54,12 @@ import static com.google.common.base.Preconditions.*; //~--- JDK imports ------------------------------------------------------------ import java.io.File; -import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; /** * - * @author Sebastian Sdorra + * @author Sebastian Sdorra */ public class SvnUnbundleCommand extends AbstractSvnCommand implements UnbundleCommand @@ -99,7 +99,8 @@ public class SvnUnbundleCommand extends AbstractSvnCommand public UnbundleResponse unbundle(UnbundleCommandRequest request) throws IOException { - File archive = checkNotNull(request.getArchive(), "archive is required"); + ByteSource archive = checkNotNull(request.getArchive(), + "archive is required"); logger.debug("archive repository {} to {}", context.getDirectory(), archive); @@ -137,14 +138,15 @@ public class SvnUnbundleCommand extends AbstractSvnCommand * @throws IOException * @throws SVNException */ - private void restore(SVNAdminClient adminClient, File dump, File repository) + private void restore(SVNAdminClient adminClient, ByteSource dump, + File repository) throws SVNException, IOException { InputStream inputStream = null; try { - inputStream = new FileInputStream(dump); + inputStream = dump.openBufferedStream(); adminClient.doLoad(repository, inputStream); } finally