mirror of
https://github.com/scm-manager/scm-manager.git
synced 2025-11-18 03:01:05 +01:00
merge with branch 1.x
This commit is contained in:
@@ -35,23 +35,28 @@ package sonia.scm.repository;
|
||||
|
||||
//~--- non-JDK imports --------------------------------------------------------
|
||||
|
||||
import com.google.common.base.Throwables;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import sonia.scm.repository.ImportResult.Builder;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Abstract base class for directory based {@link ImportHandler} and
|
||||
* {@link AdvancedImportHandler}.
|
||||
*
|
||||
* @author Sebastian Sdorra
|
||||
* @since 1.12
|
||||
*/
|
||||
public abstract class AbstactImportHandler implements ImportHandler
|
||||
public abstract class AbstactImportHandler implements AdvancedImportHandler
|
||||
{
|
||||
|
||||
/**
|
||||
@@ -63,80 +68,65 @@ public abstract class AbstactImportHandler implements ImportHandler
|
||||
//~--- get methods ----------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Method description
|
||||
* Returns array of repository directory names.
|
||||
*
|
||||
*
|
||||
* @return
|
||||
* @return repository directory names
|
||||
*/
|
||||
protected abstract String[] getDirectoryNames();
|
||||
|
||||
/**
|
||||
* Method description
|
||||
* Returns repository handler.
|
||||
*
|
||||
*
|
||||
* @return
|
||||
* @return repository handler
|
||||
*/
|
||||
protected abstract AbstractRepositoryHandler<?> getRepositoryHandler();
|
||||
|
||||
//~--- methods --------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param manager
|
||||
*
|
||||
*
|
||||
* @return
|
||||
* @throws IOException
|
||||
* @throws RepositoryException
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public List<String> importRepositories(RepositoryManager manager)
|
||||
throws IOException, RepositoryException
|
||||
{
|
||||
List<String> imported = new ArrayList<String>();
|
||||
|
||||
if (logger.isTraceEnabled())
|
||||
{
|
||||
logger.trace("search for repositories to import");
|
||||
}
|
||||
|
||||
List<String> repositoryNames =
|
||||
RepositoryUtil.getRepositoryNames(getRepositoryHandler(),
|
||||
getDirectoryNames());
|
||||
|
||||
for (String repositoryName : repositoryNames)
|
||||
{
|
||||
if (logger.isTraceEnabled())
|
||||
{
|
||||
logger.trace("check repository {} for import", repositoryName);
|
||||
}
|
||||
|
||||
Repository repository = manager.get(getTypeName(), repositoryName);
|
||||
|
||||
if (repository == null)
|
||||
{
|
||||
importRepository(manager, repositoryName);
|
||||
imported.add(repositoryName);
|
||||
}
|
||||
else if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("repository {} is allready managed", repositoryName);
|
||||
}
|
||||
}
|
||||
|
||||
return imported;
|
||||
return doRepositoryImport(manager, true).getImportedDirectories();
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public ImportResult importRepositoriesFromDirectory(RepositoryManager manager)
|
||||
{
|
||||
try
|
||||
{
|
||||
return doRepositoryImport(manager, false);
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
|
||||
// should never happen
|
||||
throw Throwables.propagate(ex);
|
||||
}
|
||||
catch (RepositoryException ex)
|
||||
{
|
||||
|
||||
// should never happen
|
||||
throw Throwables.propagate(ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a repository.
|
||||
*
|
||||
*
|
||||
* @param repositoryDirectory
|
||||
* @param repositoryName
|
||||
* @param repositoryDirectory repository base directory
|
||||
* @param repositoryName name of the repository
|
||||
*
|
||||
* @return
|
||||
* @return repository
|
||||
*
|
||||
* @throws IOException
|
||||
* @throws RepositoryException
|
||||
@@ -154,6 +144,118 @@ public abstract class AbstactImportHandler implements ImportHandler
|
||||
return repository;
|
||||
}
|
||||
|
||||
/**
|
||||
* Repository import.
|
||||
*
|
||||
*
|
||||
* @param manager repository manager
|
||||
* @param throwExceptions true to throw exception
|
||||
*
|
||||
* @return import result
|
||||
*
|
||||
* @throws IOException
|
||||
* @throws RepositoryException
|
||||
*/
|
||||
private ImportResult doRepositoryImport(RepositoryManager manager,
|
||||
boolean throwExceptions)
|
||||
throws IOException, RepositoryException
|
||||
{
|
||||
Builder builder = ImportResult.builder();
|
||||
|
||||
logger.trace("search for repositories to import");
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
List<String> repositoryNames =
|
||||
RepositoryUtil.getRepositoryNames(getRepositoryHandler(),
|
||||
getDirectoryNames());
|
||||
|
||||
for (String repositoryName : repositoryNames)
|
||||
{
|
||||
importRepository(manager, builder, throwExceptions, repositoryName);
|
||||
}
|
||||
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
handleException(ex, throwExceptions);
|
||||
}
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param ex
|
||||
* @param throwExceptions
|
||||
* @param <T>
|
||||
*
|
||||
* @throws T
|
||||
*/
|
||||
private <T extends Exception> void handleException(T ex,
|
||||
boolean throwExceptions)
|
||||
throws T
|
||||
{
|
||||
logger.warn("error durring repository directory import", ex);
|
||||
|
||||
if (throwExceptions)
|
||||
{
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param manager
|
||||
* @param builder
|
||||
* @param throwExceptions
|
||||
* @param repositoryName
|
||||
*
|
||||
* @throws IOException
|
||||
* @throws RepositoryException
|
||||
*/
|
||||
private void importRepository(RepositoryManager manager, Builder builder,
|
||||
boolean throwExceptions, String repositoryName)
|
||||
throws IOException, RepositoryException
|
||||
{
|
||||
logger.trace("check repository {} for import", repositoryName);
|
||||
|
||||
Repository repository = manager.get(getTypeName(), repositoryName);
|
||||
|
||||
if (repository == null)
|
||||
{
|
||||
try
|
||||
{
|
||||
importRepository(manager, repositoryName);
|
||||
builder.addImportedDirectory(repositoryName);
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
builder.addFailedDirectory(repositoryName);
|
||||
handleException(ex, throwExceptions);
|
||||
}
|
||||
catch (IllegalStateException ex)
|
||||
{
|
||||
builder.addFailedDirectory(repositoryName);
|
||||
handleException(ex, throwExceptions);
|
||||
}
|
||||
catch (RepositoryException ex)
|
||||
{
|
||||
builder.addFailedDirectory(repositoryName);
|
||||
handleException(ex, throwExceptions);
|
||||
}
|
||||
}
|
||||
else if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("repository {} is allready managed", repositoryName);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
/**
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* Searches and import existing repositories. The {@link AdvancedImportHandler}
|
||||
* gives more control over the result of the import as the
|
||||
* {@link ImportHandler}.
|
||||
*
|
||||
* @author Sebastian Sdorra
|
||||
* @since 1.43
|
||||
*/
|
||||
public interface AdvancedImportHandler extends ImportHandler
|
||||
{
|
||||
|
||||
/**
|
||||
* Import existing and non managed repositories. Returns result which
|
||||
* contains names of the successfully imported directories and the names of
|
||||
* the failed directories
|
||||
*
|
||||
*
|
||||
* @param manager The global {@link RepositoryManager}
|
||||
*
|
||||
* @return result which contains names of the successfully imported
|
||||
* directories and the names of the failed directories.
|
||||
*/
|
||||
public ImportResult importRepositoriesFromDirectory(
|
||||
RepositoryManager manager);
|
||||
}
|
||||
239
scm-core/src/main/java/sonia/scm/repository/ImportResult.java
Normal file
239
scm-core/src/main/java/sonia/scm/repository/ImportResult.java
Normal file
@@ -0,0 +1,239 @@
|
||||
/**
|
||||
* 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;
|
||||
|
||||
//~--- non-JDK imports --------------------------------------------------------
|
||||
|
||||
import com.google.common.base.Objects;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import static com.google.common.base.Preconditions.*;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
import java.util.List;
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
|
||||
/**
|
||||
* Import result of the {@link AdvancedImportHandler}.
|
||||
*
|
||||
* @author Sebastian Sdorra
|
||||
* @since 1.43
|
||||
*/
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@XmlRootElement(name = "import-result")
|
||||
public final class ImportResult
|
||||
{
|
||||
|
||||
/**
|
||||
* Constructs ...
|
||||
*
|
||||
*/
|
||||
ImportResult() {}
|
||||
|
||||
/**
|
||||
* Constructs a new import result.
|
||||
*
|
||||
*
|
||||
* @param importedDirectories imported directories
|
||||
* @param failedDirectories failed directories
|
||||
*/
|
||||
public ImportResult(List<String> importedDirectories,
|
||||
List<String> failedDirectories)
|
||||
{
|
||||
this.importedDirectories = checkNotNull(importedDirectories,
|
||||
"list of imported directories is required");
|
||||
this.failedDirectories = checkNotNull(failedDirectories,
|
||||
"list of failed directories is required");
|
||||
}
|
||||
|
||||
//~--- methods --------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Returns a import result builder.
|
||||
*
|
||||
*
|
||||
* @return import result builder
|
||||
*/
|
||||
public static Builder builder()
|
||||
{
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object obj)
|
||||
{
|
||||
if (obj == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (getClass() != obj.getClass())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
final ImportResult other = (ImportResult) obj;
|
||||
|
||||
return Objects.equal(importedDirectories, other.importedDirectories)
|
||||
&& Objects.equal(failedDirectories, other.failedDirectories);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public int hashCode()
|
||||
{
|
||||
return Objects.hashCode(importedDirectories, failedDirectories);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
//J-
|
||||
return Objects.toStringHelper(this)
|
||||
.add("importedDirectories", importedDirectories)
|
||||
.add("failedDirectories", failedDirectories)
|
||||
.toString();
|
||||
//J+
|
||||
}
|
||||
|
||||
//~--- get methods ----------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Returns list of failed directories.
|
||||
*
|
||||
*
|
||||
* @return list of failed directories
|
||||
*/
|
||||
public List<String> getFailedDirectories()
|
||||
{
|
||||
return failedDirectories;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns list of successfully imported directories.
|
||||
*
|
||||
*
|
||||
* @return list of successfully imported directories
|
||||
*/
|
||||
public List<String> getImportedDirectories()
|
||||
{
|
||||
return importedDirectories;
|
||||
}
|
||||
|
||||
//~--- inner classes --------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Builder for {@link ImportResult}.
|
||||
*/
|
||||
public static class Builder
|
||||
{
|
||||
|
||||
/**
|
||||
* Constructs ...
|
||||
*
|
||||
*/
|
||||
private Builder() {}
|
||||
|
||||
//~--- methods ------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Adds a failed directory to the import result.
|
||||
*
|
||||
*
|
||||
* @param name name of the directory
|
||||
*
|
||||
* @return {@code this}
|
||||
*/
|
||||
public Builder addFailedDirectory(String name)
|
||||
{
|
||||
this.failedDirectories.add(name);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a successfully imported directory to the import result.
|
||||
*
|
||||
*
|
||||
* @param name name of the directory
|
||||
*
|
||||
* @return {@code this}
|
||||
*/
|
||||
public Builder addImportedDirectory(String name)
|
||||
{
|
||||
this.importedDirectories.add(name);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the final import result.
|
||||
*
|
||||
*
|
||||
* @return final import result
|
||||
*/
|
||||
public ImportResult build()
|
||||
{
|
||||
return new ImportResult(ImmutableList.copyOf(importedDirectories),
|
||||
ImmutableList.copyOf(failedDirectories));
|
||||
}
|
||||
|
||||
//~--- fields -------------------------------------------------------------
|
||||
|
||||
/** successfully imported directories */
|
||||
private final List<String> importedDirectories = Lists.newArrayList();
|
||||
|
||||
/** failed directories */
|
||||
private final List<String> failedDirectories = Lists.newArrayList();
|
||||
}
|
||||
|
||||
|
||||
//~--- fields ---------------------------------------------------------------
|
||||
|
||||
/** failed directories */
|
||||
private List<String> failedDirectories;
|
||||
|
||||
/** successfully imported directories */
|
||||
private List<String> importedDirectories;
|
||||
}
|
||||
@@ -0,0 +1,121 @@
|
||||
/**
|
||||
* 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.api;
|
||||
|
||||
//~--- non-JDK imports --------------------------------------------------------
|
||||
|
||||
import com.google.common.base.Objects;
|
||||
|
||||
/**
|
||||
* Abstract class for bundle or unbundle command.
|
||||
*
|
||||
* @author Sebastian Sdorra
|
||||
* @since 1.43
|
||||
*/
|
||||
public abstract class AbstractBundleOrUnbundleCommandResponse
|
||||
{
|
||||
|
||||
/**
|
||||
* Constructs a new bundle/unbundle response.
|
||||
*
|
||||
*
|
||||
* @param changesetCount count of bundled/unbundled changesets
|
||||
*/
|
||||
protected AbstractBundleOrUnbundleCommandResponse(long changesetCount)
|
||||
{
|
||||
this.changesetCount = changesetCount;
|
||||
}
|
||||
|
||||
//~--- methods --------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object obj)
|
||||
{
|
||||
if (obj == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (getClass() != obj.getClass())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
final AbstractBundleOrUnbundleCommandResponse other =
|
||||
(AbstractBundleOrUnbundleCommandResponse) obj;
|
||||
|
||||
return Objects.equal(changesetCount, other.changesetCount);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public int hashCode()
|
||||
{
|
||||
return Objects.hashCode(changesetCount);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
//J-
|
||||
return Objects.toStringHelper(this)
|
||||
.add("changesetCount", changesetCount)
|
||||
.toString();
|
||||
//J+
|
||||
}
|
||||
|
||||
//~--- get methods ----------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Returns the count of bundled/unbundled changesets.
|
||||
*
|
||||
*
|
||||
* @return count of bundled/unbundled changesets
|
||||
*/
|
||||
public long getChangesetCount()
|
||||
{
|
||||
return changesetCount;
|
||||
}
|
||||
|
||||
//~--- fields ---------------------------------------------------------------
|
||||
|
||||
/** count of bundled/unbundled changesets */
|
||||
private final long changesetCount;
|
||||
}
|
||||
@@ -0,0 +1,185 @@
|
||||
/**
|
||||
* 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.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;
|
||||
|
||||
import sonia.scm.repository.Repository;
|
||||
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;
|
||||
|
||||
/**
|
||||
* The bundle command dumps a repository to a byte source such as a file. The
|
||||
* created bundle can be restored to an empty repository with the
|
||||
* {@link UnbundleCommandBuilder}.
|
||||
*
|
||||
* @author Sebastian Sdorra <s.sdorra@gmail.com>
|
||||
* @since 1.43
|
||||
*/
|
||||
public final class BundleCommandBuilder
|
||||
{
|
||||
|
||||
/** logger for BundleCommandBuilder */
|
||||
private static final Logger logger =
|
||||
LoggerFactory.getLogger(BundleCommandBuilder.class);
|
||||
|
||||
//~--- constructors ---------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Constructs a new {@link BundleCommandBuilder}.
|
||||
*
|
||||
*
|
||||
* @param bundleCommand bundle command implementation
|
||||
* @param repository repository
|
||||
*/
|
||||
BundleCommandBuilder(BundleCommand bundleCommand, Repository repository)
|
||||
{
|
||||
this.bundleCommand = bundleCommand;
|
||||
this.repository = repository;
|
||||
}
|
||||
|
||||
//~--- methods --------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Dumps the repository to the given {@link File}.
|
||||
*
|
||||
* @param outputFile output file
|
||||
*
|
||||
* @return bundle response
|
||||
*
|
||||
* @throws IOException
|
||||
* @throws RepositoryException
|
||||
*/
|
||||
public BundleResponse bundle(File outputFile)
|
||||
throws IOException, RepositoryException
|
||||
{
|
||||
checkArgument((outputFile != null) &&!outputFile.exists(),
|
||||
"file is null or exists already");
|
||||
|
||||
BundleCommandRequest request =
|
||||
new BundleCommandRequest(Files.asByteSink(outputFile));
|
||||
|
||||
logger.info("create bundle at {} for repository {}", outputFile,
|
||||
repository.getId());
|
||||
|
||||
return bundleCommand.bundle(request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Dumps the repository to the given {@link OutputStream}.
|
||||
*
|
||||
*
|
||||
* @param outputStream output stream
|
||||
*
|
||||
* @return bundle response
|
||||
*
|
||||
* @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)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Dumps the repository to the given {@link ByteSink}.
|
||||
*
|
||||
* @param sink byte sink
|
||||
*
|
||||
* @return bundle response
|
||||
*
|
||||
* @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));
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts an {@link OutputStream} into a {@link ByteSink}.
|
||||
*
|
||||
*
|
||||
* @param outputStream ouput stream to convert
|
||||
*
|
||||
* @return converted byte sink
|
||||
*/
|
||||
private ByteSink asByteSink(final OutputStream outputStream)
|
||||
{
|
||||
return ByteStreams.asByteSink(new OutputSupplier<OutputStream>()
|
||||
{
|
||||
|
||||
@Override
|
||||
public OutputStream getOutput() throws IOException
|
||||
{
|
||||
return outputStream;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
//~--- fields ---------------------------------------------------------------
|
||||
|
||||
/** bundle command implementation */
|
||||
private final BundleCommand bundleCommand;
|
||||
|
||||
/** repository */
|
||||
private final Repository repository;
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/**
|
||||
* 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.api;
|
||||
|
||||
/**
|
||||
* Response of bundle command.
|
||||
*
|
||||
* @author Sebastian Sdorra <s.sdorra@gmail.com>
|
||||
* @since 1.43
|
||||
*/
|
||||
public final class BundleResponse
|
||||
extends AbstractBundleOrUnbundleCommandResponse
|
||||
{
|
||||
|
||||
/**
|
||||
* Constructs a new bundle response.
|
||||
*
|
||||
*
|
||||
* @param changesetCount count of bundled changesets
|
||||
*/
|
||||
public BundleResponse(long changesetCount)
|
||||
{
|
||||
super(changesetCount);
|
||||
}
|
||||
}
|
||||
@@ -56,5 +56,10 @@ public enum Command
|
||||
/**
|
||||
* @since 1.31
|
||||
*/
|
||||
INCOMING, OUTGOING, PUSH, PULL;
|
||||
INCOMING, OUTGOING, PUSH, PULL,
|
||||
|
||||
/**
|
||||
* @since 1.43
|
||||
*/
|
||||
BUNDLE, UNBUNDLE;
|
||||
}
|
||||
|
||||
@@ -50,6 +50,7 @@ import sonia.scm.security.RepositoryPermission;
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
|
||||
/**
|
||||
* The pull command pull changes from a other repository.
|
||||
@@ -83,6 +84,38 @@ public final class PullCommandBuilder
|
||||
|
||||
//~--- methods --------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Pull all changes from the given remote url.
|
||||
*
|
||||
*
|
||||
* @param url remote url
|
||||
*
|
||||
* @return informations over the executed pull command
|
||||
*
|
||||
* @throws IOException
|
||||
* @throws RepositoryException
|
||||
*
|
||||
* @since 1.43
|
||||
*/
|
||||
public PullResponse pull(String url)
|
||||
throws IOException, RepositoryException
|
||||
{
|
||||
Subject subject = SecurityUtils.getSubject();
|
||||
//J-
|
||||
subject.checkPermission(
|
||||
new RepositoryPermission(localRepository, PermissionType.WRITE)
|
||||
);
|
||||
//J+
|
||||
|
||||
URL remoteUrl = new URL(url);
|
||||
request.reset();
|
||||
request.setRemoteUrl(remoteUrl);
|
||||
|
||||
logger.info("pull changes from url {}", url);
|
||||
|
||||
return command.pull(request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Pull all changes from the given remote repository.
|
||||
*
|
||||
@@ -108,6 +141,7 @@ public final class PullCommandBuilder
|
||||
);
|
||||
//J+
|
||||
|
||||
request.reset();
|
||||
request.setRemoteRepository(remoteRepository);
|
||||
|
||||
logger.info("pull changes from {}", remoteRepository);
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package sonia.scm.repository.api;
|
||||
|
||||
//~--- non-JDK imports --------------------------------------------------------
|
||||
@@ -37,6 +38,9 @@ package sonia.scm.repository.api;
|
||||
import org.apache.shiro.SecurityUtils;
|
||||
import org.apache.shiro.subject.Subject;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import sonia.scm.repository.PermissionType;
|
||||
import sonia.scm.repository.Repository;
|
||||
import sonia.scm.repository.RepositoryException;
|
||||
@@ -48,15 +52,25 @@ import sonia.scm.security.RepositoryPermission;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import java.net.URL;
|
||||
|
||||
/**
|
||||
* The push command push changes to a other repository.
|
||||
*
|
||||
*
|
||||
* @author Sebastian Sdorra
|
||||
* @since 1.31
|
||||
*/
|
||||
public final class PushCommandBuilder
|
||||
{
|
||||
|
||||
/**
|
||||
* the logger for PushCommandBuilder
|
||||
*/
|
||||
private static final Logger logger =
|
||||
LoggerFactory.getLogger(PushCommandBuilder.class);
|
||||
|
||||
//~--- constructors ---------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Constructs a new PushCommandBuilder.
|
||||
*
|
||||
@@ -90,11 +104,39 @@ public final class PushCommandBuilder
|
||||
);
|
||||
//J+
|
||||
|
||||
logger.info("push changes to repository {}", remoteRepository.getId());
|
||||
|
||||
request.reset();
|
||||
request.setRemoteRepository(remoteRepository);
|
||||
|
||||
return command.push(request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Push all changes to the given remote url.
|
||||
*
|
||||
* @param url url of a remote repository
|
||||
*
|
||||
* @return informations of the executed push command
|
||||
*
|
||||
* @throws IOException
|
||||
* @throws RepositoryException
|
||||
*
|
||||
* @since 1.43
|
||||
*/
|
||||
public PushResponse push(String url) throws IOException, RepositoryException
|
||||
{
|
||||
|
||||
URL remoteUrl = new URL(url);
|
||||
|
||||
logger.info("push changes to url {}", url);
|
||||
|
||||
request.reset();
|
||||
request.setRemoteUrl(remoteUrl);
|
||||
|
||||
return command.push(request);
|
||||
}
|
||||
|
||||
//~--- fields ---------------------------------------------------------------
|
||||
|
||||
/** push command implementation */
|
||||
|
||||
@@ -83,6 +83,8 @@ import java.io.IOException;
|
||||
* @apiviz.uses sonia.scm.repository.api.OutgoingCommandBuilder
|
||||
* @apiviz.uses sonia.scm.repository.api.PullCommandBuilder
|
||||
* @apiviz.uses sonia.scm.repository.api.PushCommandBuilder
|
||||
* @apiviz.uses sonia.scm.repository.api.BundleCommandBuilder
|
||||
* @apiviz.uses sonia.scm.repository.api.UnbundleCommandBuilder
|
||||
*/
|
||||
public final class RepositoryService implements Closeable
|
||||
{
|
||||
@@ -204,6 +206,25 @@ public final class RepositoryService implements Closeable
|
||||
repository, preProcessorUtil);
|
||||
}
|
||||
|
||||
/**
|
||||
* The bundle command creates an archive from the repository.
|
||||
*
|
||||
* @return instance of {@link BundleCommandBuilder}
|
||||
* @throws CommandNotSupportedException if the command is not supported
|
||||
* by the implementation of the repository service provider.
|
||||
* @since 1.43
|
||||
*/
|
||||
public BundleCommandBuilder getBundleCommand()
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("create bundle command for repository {}",
|
||||
repository.getName());
|
||||
}
|
||||
|
||||
return new BundleCommandBuilder(provider.getBundleCommand(), repository);
|
||||
}
|
||||
|
||||
/**
|
||||
* The cat command show the content of a given file.
|
||||
*
|
||||
@@ -370,6 +391,26 @@ public final class RepositoryService implements Closeable
|
||||
repository);
|
||||
}
|
||||
|
||||
/**
|
||||
* The unbundle command restores a repository from the given bundle.
|
||||
*
|
||||
* @return instance of {@link UnbundleCommandBuilder}
|
||||
* @throws CommandNotSupportedException if the command is not supported
|
||||
* by the implementation of the repository service provider.
|
||||
* @since 1.43
|
||||
*/
|
||||
public UnbundleCommandBuilder getUnbundleCommand()
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("create bundle command for repository {}",
|
||||
repository.getName());
|
||||
}
|
||||
|
||||
return new UnbundleCommandBuilder(provider.getUnbundleCommand(),
|
||||
repository);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the command is supported by the repository service.
|
||||
*
|
||||
@@ -390,7 +431,7 @@ public final class RepositoryService implements Closeable
|
||||
* @param feature feature
|
||||
*
|
||||
* @return true if the feature is supported
|
||||
*
|
||||
*
|
||||
* @since 1.25
|
||||
*/
|
||||
public boolean isSupported(Feature feature)
|
||||
|
||||
@@ -0,0 +1,275 @@
|
||||
/**
|
||||
* 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.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;
|
||||
|
||||
import sonia.scm.repository.Repository;
|
||||
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;
|
||||
|
||||
import java.util.zip.GZIPInputStream;
|
||||
|
||||
/**
|
||||
* The unbundle command can restore an empty repository from a bundle. The
|
||||
* bundle can be created with the {@link BundleCommandBuilder}.
|
||||
*
|
||||
* @author Sebastian Sdorra <s.sdorra@gmail.com>
|
||||
* @since 1.43
|
||||
*/
|
||||
public final class UnbundleCommandBuilder
|
||||
{
|
||||
|
||||
/** logger for UnbundleCommandBuilder */
|
||||
private static final Logger logger =
|
||||
LoggerFactory.getLogger(UnbundleCommandBuilder.class);
|
||||
|
||||
//~--- constructors ---------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Constructs a new UnbundleCommandBuilder.
|
||||
*
|
||||
*
|
||||
* @param unbundleCommand unbundle command implementation
|
||||
* @param repository repository
|
||||
*/
|
||||
public UnbundleCommandBuilder(UnbundleCommand unbundleCommand,
|
||||
Repository repository)
|
||||
{
|
||||
this.unbundleCommand = unbundleCommand;
|
||||
this.repository = repository;
|
||||
}
|
||||
|
||||
//~--- methods --------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Restores the repository from the given bundle.
|
||||
*
|
||||
*
|
||||
* @param inputFile input file
|
||||
*
|
||||
* @return unbundle response
|
||||
*
|
||||
* @throws IOException
|
||||
* @throws RepositoryException
|
||||
*/
|
||||
public UnbundleResponse unbundle(File inputFile)
|
||||
throws IOException, RepositoryException
|
||||
{
|
||||
checkArgument((inputFile != null) && inputFile.exists(),
|
||||
"existing file is required");
|
||||
|
||||
UnbundleCommandRequest request =
|
||||
createRequest(Files.asByteSource(inputFile));
|
||||
|
||||
logger.info("unbundle archive {} at {}", inputFile, repository.getId());
|
||||
|
||||
return unbundleCommand.unbundle(request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Restores the repository from the given bundle.
|
||||
*
|
||||
*
|
||||
* @param inputStream input stream
|
||||
*
|
||||
* @return unbundle response
|
||||
*
|
||||
* @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(createRequest(asByteSource(inputStream)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Restores the repository from the given bundle.
|
||||
*
|
||||
*
|
||||
* @param byteSource byte source
|
||||
*
|
||||
* @return unbundle response
|
||||
*
|
||||
* @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(createRequest(byteSource));
|
||||
}
|
||||
|
||||
//~--- set methods ----------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Set to {@code true} if bundle is gzip compressed. Default is {@code false}.
|
||||
*
|
||||
*
|
||||
* @param compressed {@code true} if bundle is gzip compressed
|
||||
*
|
||||
* @return {@code this}
|
||||
*/
|
||||
public UnbundleCommandBuilder setCompressed(boolean compressed)
|
||||
{
|
||||
this.compressed = compressed;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
//~--- methods --------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Converts an {@link InputStream} into a {@link ByteSource}.
|
||||
*
|
||||
*
|
||||
* @param inputStream input stream
|
||||
*
|
||||
* @return byte source
|
||||
*/
|
||||
private ByteSource asByteSource(final InputStream inputStream)
|
||||
{
|
||||
return ByteStreams.asByteSource(new InputSupplier<InputStream>()
|
||||
{
|
||||
|
||||
@Override
|
||||
public InputStream getInput() throws IOException
|
||||
{
|
||||
return inputStream;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the {@link UnbundleCommandRequest}.
|
||||
*
|
||||
*
|
||||
* @param source byte source
|
||||
*
|
||||
* @return the create request
|
||||
*/
|
||||
private UnbundleCommandRequest createRequest(ByteSource source)
|
||||
{
|
||||
ByteSource bs;
|
||||
|
||||
if (compressed)
|
||||
{
|
||||
logger.debug("decode gzip stream for unbundle command");
|
||||
bs = new CompressedByteSource(source);
|
||||
}
|
||||
else
|
||||
{
|
||||
bs = source;
|
||||
}
|
||||
|
||||
return new UnbundleCommandRequest(bs);
|
||||
}
|
||||
|
||||
//~--- inner classes --------------------------------------------------------
|
||||
|
||||
/**
|
||||
* ByteSource which is able to handle gzip compressed resources.
|
||||
*/
|
||||
private static class CompressedByteSource extends ByteSource
|
||||
{
|
||||
|
||||
/**
|
||||
* Constructs ...
|
||||
*
|
||||
*
|
||||
* @param wrapped
|
||||
*/
|
||||
public CompressedByteSource(ByteSource wrapped)
|
||||
{
|
||||
this.wrapped = wrapped;
|
||||
}
|
||||
|
||||
//~--- methods ------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Opens the stream for reading the compressed source.
|
||||
*
|
||||
*
|
||||
* @return input stream
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
@Override
|
||||
public InputStream openStream() throws IOException
|
||||
{
|
||||
return new GZIPInputStream(wrapped.openStream());
|
||||
}
|
||||
|
||||
//~--- fields -------------------------------------------------------------
|
||||
|
||||
/** Field description */
|
||||
private final ByteSource wrapped;
|
||||
}
|
||||
|
||||
|
||||
//~--- fields ---------------------------------------------------------------
|
||||
|
||||
/** repository */
|
||||
private final Repository repository;
|
||||
|
||||
/** unbundle command implementation */
|
||||
private final UnbundleCommand unbundleCommand;
|
||||
|
||||
/** Field description */
|
||||
private boolean compressed = false;
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
/**
|
||||
* 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.api;
|
||||
|
||||
/**
|
||||
* Response of unbundle command.
|
||||
*
|
||||
* @author Sebastian Sdorra <s.sdorra@gmail.com>
|
||||
* @since 1.43
|
||||
*/
|
||||
public class UnbundleResponse extends AbstractBundleOrUnbundleCommandResponse
|
||||
{
|
||||
|
||||
/**
|
||||
* Constructs a new unbundle response.
|
||||
*
|
||||
*
|
||||
* @param changesetCount count of unbundled changesets
|
||||
*/
|
||||
public UnbundleResponse(long changesetCount)
|
||||
{
|
||||
super(changesetCount);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
/**
|
||||
* 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 sonia.scm.repository.RepositoryException;
|
||||
import sonia.scm.repository.api.BundleResponse;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Service provider implementation for the bundle command.
|
||||
*
|
||||
* @author Sebastian Sdorra <s.sdorra@gmail.com>
|
||||
* @since 1.43
|
||||
*/
|
||||
public interface BundleCommand
|
||||
{
|
||||
|
||||
/**
|
||||
* The bundle command dumps a repository to a byte source such as a file.
|
||||
*
|
||||
*
|
||||
* @param request bundle command request
|
||||
*
|
||||
* @return bundle response
|
||||
*
|
||||
* @throws IOException
|
||||
* @throws RepositoryException
|
||||
*/
|
||||
public BundleResponse bundle(BundleCommandRequest request)
|
||||
throws IOException, RepositoryException;
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
/**
|
||||
* 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;
|
||||
import com.google.common.io.ByteSink;
|
||||
|
||||
/**
|
||||
* Request for the bundle command.
|
||||
*
|
||||
* @author Sebastian Sdorra <s.sdorra@gmail.com>
|
||||
* @since 1.43
|
||||
*/
|
||||
public final class BundleCommandRequest
|
||||
{
|
||||
|
||||
/**
|
||||
* Constructs a new bundle command request.
|
||||
*
|
||||
*
|
||||
* @param archive byte sink archive
|
||||
*/
|
||||
public BundleCommandRequest(ByteSink archive)
|
||||
{
|
||||
this.archive = archive;
|
||||
}
|
||||
|
||||
//~--- methods --------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@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);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public int hashCode()
|
||||
{
|
||||
return Objects.hashCode(archive);
|
||||
}
|
||||
|
||||
//~--- get methods ----------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Returns the archive as {@link ByteSink}.
|
||||
*
|
||||
*
|
||||
* @return {@link ByteSink} archive.
|
||||
*/
|
||||
ByteSink getArchive()
|
||||
{
|
||||
return archive;
|
||||
}
|
||||
|
||||
//~--- fields ---------------------------------------------------------------
|
||||
|
||||
/** byte sink archive */
|
||||
private final ByteSink archive;
|
||||
}
|
||||
@@ -33,7 +33,8 @@
|
||||
package sonia.scm.repository.spi;
|
||||
|
||||
/**
|
||||
*
|
||||
* Request object for {@link PullCommand}.
|
||||
*
|
||||
* @author Sebastian Sdorra
|
||||
* @since 1.31
|
||||
*/
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
package sonia.scm.repository.spi;
|
||||
|
||||
/**
|
||||
* Request object for {@link PushCommand}.
|
||||
*
|
||||
* @author Sebastian Sdorra
|
||||
* @since 1.31
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package sonia.scm.repository.spi;
|
||||
|
||||
//~--- non-JDK imports --------------------------------------------------------
|
||||
@@ -38,12 +39,16 @@ import com.google.common.base.Objects;
|
||||
|
||||
import sonia.scm.repository.Repository;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
import java.net.URL;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Sebastian Sdorra
|
||||
* @since 1.31
|
||||
*/
|
||||
public abstract class RemoteCommandRequest
|
||||
public abstract class RemoteCommandRequest implements Resetable
|
||||
{
|
||||
|
||||
/**
|
||||
@@ -64,7 +69,8 @@ public abstract class RemoteCommandRequest
|
||||
|
||||
final RemoteCommandRequest other = (RemoteCommandRequest) obj;
|
||||
|
||||
return Objects.equal(remoteRepository, other.remoteRepository);
|
||||
return Objects.equal(remoteRepository, other.remoteRepository)
|
||||
&& Objects.equal(remoteUrl, other.remoteUrl);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -73,7 +79,19 @@ public abstract class RemoteCommandRequest
|
||||
@Override
|
||||
public int hashCode()
|
||||
{
|
||||
return Objects.hashCode(remoteRepository);
|
||||
return Objects.hashCode(remoteRepository, remoteUrl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the request object.
|
||||
*
|
||||
* @since 1.43
|
||||
*/
|
||||
@Override
|
||||
public void reset()
|
||||
{
|
||||
remoteRepository = null;
|
||||
remoteUrl = null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -82,10 +100,10 @@ public abstract class RemoteCommandRequest
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
|
||||
//J-
|
||||
return Objects.toStringHelper(this)
|
||||
.add("remoteRepository", remoteRepository)
|
||||
.add("remoteUrl", remoteUrl)
|
||||
.toString();
|
||||
//J+
|
||||
}
|
||||
@@ -102,6 +120,19 @@ public abstract class RemoteCommandRequest
|
||||
this.remoteRepository = remoteRepository;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param remoteUrl
|
||||
*
|
||||
* @since 1.43
|
||||
*/
|
||||
public void setRemoteUrl(URL remoteUrl)
|
||||
{
|
||||
this.remoteUrl = remoteUrl;
|
||||
}
|
||||
|
||||
//~--- get methods ----------------------------------------------------------
|
||||
|
||||
/**
|
||||
@@ -115,8 +146,24 @@ public abstract class RemoteCommandRequest
|
||||
return remoteRepository;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* @since 1.43
|
||||
*/
|
||||
URL getRemoteUrl()
|
||||
{
|
||||
return remoteUrl;
|
||||
}
|
||||
|
||||
//~--- fields ---------------------------------------------------------------
|
||||
|
||||
/** Field description */
|
||||
protected Repository remoteRepository;
|
||||
|
||||
/** remote url */
|
||||
protected URL remoteUrl;
|
||||
}
|
||||
|
||||
@@ -115,6 +115,19 @@ public abstract class RepositoryServiceProvider implements Closeable
|
||||
throw new CommandNotSupportedException(Command.BROWSE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* @since 1.43
|
||||
*/
|
||||
public BundleCommand getBundleCommand()
|
||||
{
|
||||
throw new CommandNotSupportedException(Command.BUNDLE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
@@ -218,4 +231,17 @@ public abstract class RepositoryServiceProvider implements Closeable
|
||||
{
|
||||
throw new CommandNotSupportedException(Command.TAGS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* @since 1.43
|
||||
*/
|
||||
public UnbundleCommand getUnbundleCommand()
|
||||
{
|
||||
throw new CommandNotSupportedException(Command.UNBUNDLE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
/**
|
||||
* 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 sonia.scm.repository.RepositoryException;
|
||||
import sonia.scm.repository.api.UnbundleResponse;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Service provider implementation for the unbundle command.
|
||||
*
|
||||
* @author Sebastian Sdorra <s.sdorra@gmail.com>
|
||||
* @since 1.43
|
||||
*/
|
||||
public interface UnbundleCommand
|
||||
{
|
||||
|
||||
/**
|
||||
* The unbundle command can restore an empty repository from a bundle.
|
||||
*
|
||||
*
|
||||
* @param request unbundle request
|
||||
*
|
||||
* @return unbundle response
|
||||
*
|
||||
* @throws IOException
|
||||
* @throws RepositoryException
|
||||
*/
|
||||
public UnbundleResponse unbundle(UnbundleCommandRequest request)
|
||||
throws IOException, RepositoryException;
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
/**
|
||||
* 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;
|
||||
import com.google.common.io.ByteSource;
|
||||
|
||||
/**
|
||||
* Request object for the unbundle command.
|
||||
*
|
||||
* @author Sebastian Sdorra <s.sdorra@gmail.com>
|
||||
* @since 1.43
|
||||
*/
|
||||
public final class UnbundleCommandRequest
|
||||
{
|
||||
|
||||
/**
|
||||
* Constructs a new unbundle command request.
|
||||
*
|
||||
*
|
||||
* @param archive byte source archive
|
||||
*/
|
||||
public UnbundleCommandRequest(ByteSource archive)
|
||||
{
|
||||
this.archive = archive;
|
||||
}
|
||||
|
||||
//~--- methods --------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@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);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public int hashCode()
|
||||
{
|
||||
return Objects.hashCode(archive);
|
||||
}
|
||||
|
||||
//~--- get methods ----------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Returns the archive as {@link ByteSource}.
|
||||
*
|
||||
*
|
||||
* @return {@link ByteSource} archive
|
||||
*/
|
||||
ByteSource getArchive()
|
||||
{
|
||||
return archive;
|
||||
}
|
||||
|
||||
//~--- fields ---------------------------------------------------------------
|
||||
|
||||
/** byte source archive */
|
||||
private final ByteSource archive;
|
||||
}
|
||||
@@ -94,6 +94,20 @@ public class RestUrlProvider implements UrlProvider
|
||||
return HttpUtil.append(baseUrl, PART_AUTHENTICATION).concat(extension);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* @since 1.43
|
||||
*/
|
||||
@Override
|
||||
public String getBaseUrl()
|
||||
{
|
||||
return baseUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
|
||||
@@ -48,6 +48,16 @@ public interface UrlProvider
|
||||
*/
|
||||
public String getAuthenticationUrl();
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* @since 1.43
|
||||
*/
|
||||
public String getBaseUrl();
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
@@ -77,7 +87,7 @@ public interface UrlProvider
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*
|
||||
*
|
||||
* @since 1.41
|
||||
*/
|
||||
public SecurityUrlProvider getSecurityUrlProvider();
|
||||
|
||||
@@ -88,6 +88,20 @@ public class WUIUrlProvider implements UrlProvider
|
||||
return baseUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* @since 1.43
|
||||
*/
|
||||
@Override
|
||||
public String getBaseUrl()
|
||||
{
|
||||
return baseUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
|
||||
@@ -73,6 +73,12 @@ public final class HttpUtil
|
||||
/** Field description */
|
||||
public static final String ENCODING = "UTF-8";
|
||||
|
||||
/**
|
||||
* location header
|
||||
* @since 1.43
|
||||
*/
|
||||
public static final String HEADER_LOCATION = "Location";
|
||||
|
||||
/**
|
||||
* header for identifying the scm-manager client
|
||||
* @since 1.19
|
||||
|
||||
@@ -0,0 +1,111 @@
|
||||
/**
|
||||
* 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.web.filter;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
/**
|
||||
* Helper methods for implementations of the {@link AutoLoginModule}.
|
||||
*
|
||||
* @author Sebastian Sdorra <sebastian.sdorra@gmail.com>
|
||||
*
|
||||
* @since 1.42
|
||||
*/
|
||||
public final class AutoLoginModules
|
||||
{
|
||||
|
||||
/** Field description */
|
||||
private static final String FLAG_COMPLETE =
|
||||
AutoLoginModules.class.getName().concat("complete");
|
||||
|
||||
//~--- constructors ---------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Constructs ...
|
||||
*
|
||||
*/
|
||||
private AutoLoginModules() {}
|
||||
|
||||
//~--- methods --------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Mark the request as completed. No further actions will be executed.
|
||||
*
|
||||
* @param request http servlet request
|
||||
*/
|
||||
public static void markAsComplete(HttpServletRequest request)
|
||||
{
|
||||
request.setAttribute(FLAG_COMPLETE, Boolean.TRUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a redirect to the specified url and marks the request as completed.
|
||||
* This method is useful for SSO solutions which have to redirect the user
|
||||
* to a central login page. This method must be used in favor of
|
||||
* {@link HttpServletResponse#sendRedirect(java.lang.String)} which could
|
||||
* result in an error.
|
||||
*
|
||||
* @param request http servlet request
|
||||
* @param response http servlet response
|
||||
* @param url redirect target
|
||||
*
|
||||
* @throws IOException if client could not be redirected
|
||||
*/
|
||||
public static void sendRedirect(HttpServletRequest request,
|
||||
HttpServletResponse response, String url)
|
||||
throws IOException
|
||||
{
|
||||
markAsComplete(request);
|
||||
response.sendRedirect(url);
|
||||
}
|
||||
|
||||
//~--- get methods ----------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Returns {@code true} is the request is marked as complete.
|
||||
*
|
||||
* @param request http servlet request
|
||||
*
|
||||
* @return {@code true} if request is complete
|
||||
*/
|
||||
public static boolean isComplete(HttpServletRequest request)
|
||||
{
|
||||
return request.getAttribute(FLAG_COMPLETE) != null;
|
||||
}
|
||||
}
|
||||
@@ -126,60 +126,17 @@ public class BasicAuthenticationFilter extends AutoLoginFilter
|
||||
throws IOException, ServletException
|
||||
{
|
||||
Subject subject = SecurityUtils.getSubject();
|
||||
// get authenticated user or process AutoLoginModule's
|
||||
User user = getAuthenticatedUser(request, response);
|
||||
|
||||
// Fallback to basic authentication scheme
|
||||
if (user == null)
|
||||
if (AutoLoginModules.isComplete(request))
|
||||
{
|
||||
String authentication = request.getHeader(HEADER_AUTHORIZATION);
|
||||
|
||||
if (Util.startWithIgnoreCase(authentication, AUTHORIZATION_BASIC_PREFIX))
|
||||
{
|
||||
if (logger.isTraceEnabled())
|
||||
{
|
||||
logger.trace(
|
||||
"found basic authorization header, start authentication");
|
||||
}
|
||||
|
||||
user = authenticate(request, response, subject, authentication);
|
||||
|
||||
if (logger.isTraceEnabled())
|
||||
{
|
||||
if (user != null)
|
||||
{
|
||||
logger.trace("user {} successfully authenticated", user.getName());
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.trace("authentcation failed, user object is null");
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ((configuration != null)
|
||||
&& configuration.isAnonymousAccessEnabled())
|
||||
{
|
||||
if (logger.isTraceEnabled())
|
||||
{
|
||||
logger.trace("anonymous access granted");
|
||||
}
|
||||
|
||||
user = SCMContext.ANONYMOUS;
|
||||
}
|
||||
}
|
||||
|
||||
if (user == null)
|
||||
{
|
||||
if (logger.isTraceEnabled())
|
||||
{
|
||||
logger.trace("could not find user send unauthorized");
|
||||
}
|
||||
|
||||
handleUnauthorized(request, response, chain);
|
||||
logger.debug("request marked as complete from an auto login module");
|
||||
}
|
||||
else
|
||||
{
|
||||
chain.doFilter(new SecurityHttpServletRequestWrapper(request, user),
|
||||
response);
|
||||
// process with basic authentication
|
||||
processRequest(request, response, chain, subject, user);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -318,6 +275,79 @@ public class BasicAuthenticationFilter extends AutoLoginFilter
|
||||
return user;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param request
|
||||
* @param response
|
||||
* @param chain
|
||||
* @param subject
|
||||
* @param user
|
||||
*
|
||||
* @throws IOException
|
||||
* @throws ServletException
|
||||
*/
|
||||
private void processRequest(HttpServletRequest request,
|
||||
HttpServletResponse response, FilterChain chain, Subject subject, User user)
|
||||
throws IOException, ServletException
|
||||
{
|
||||
|
||||
// Fallback to basic authentication scheme
|
||||
if (user == null)
|
||||
{
|
||||
String authentication = request.getHeader(HEADER_AUTHORIZATION);
|
||||
|
||||
if (Util.startWithIgnoreCase(authentication, AUTHORIZATION_BASIC_PREFIX))
|
||||
{
|
||||
if (logger.isTraceEnabled())
|
||||
{
|
||||
logger.trace(
|
||||
"found basic authorization header, start authentication");
|
||||
}
|
||||
|
||||
user = authenticate(request, response, subject, authentication);
|
||||
|
||||
if (logger.isTraceEnabled())
|
||||
{
|
||||
if (user != null)
|
||||
{
|
||||
logger.trace("user {} successfully authenticated", user.getName());
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.trace("authentcation failed, user object is null");
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ((configuration != null)
|
||||
&& configuration.isAnonymousAccessEnabled())
|
||||
{
|
||||
if (logger.isTraceEnabled())
|
||||
{
|
||||
logger.trace("anonymous access granted");
|
||||
}
|
||||
|
||||
user = SCMContext.ANONYMOUS;
|
||||
}
|
||||
}
|
||||
|
||||
if (user == null)
|
||||
{
|
||||
if (logger.isTraceEnabled())
|
||||
{
|
||||
logger.trace("could not find user send unauthorized");
|
||||
}
|
||||
|
||||
handleUnauthorized(request, response, chain);
|
||||
}
|
||||
else
|
||||
{
|
||||
chain.doFilter(new SecurityHttpServletRequestWrapper(request, user),
|
||||
response);
|
||||
}
|
||||
}
|
||||
|
||||
//~--- fields ---------------------------------------------------------------
|
||||
|
||||
/** scm main configuration */
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
<body>
|
||||
<div style="text-align: justify;">
|
||||
<p>
|
||||
<img src="http://download.scm-manager.org/images/logo/scm-manager_logo.jpg" />
|
||||
<img src="//download.scm-manager.org/images/logo/scm-manager_logo.jpg" alt="SCM-Manager" />
|
||||
</p>
|
||||
</div>
|
||||
<p></p>
|
||||
@@ -62,7 +62,7 @@
|
||||
<h3>Architecture</h3>
|
||||
|
||||
<div style="text-align: center;">
|
||||
<img src="http://download.scm-manager.org/images/architecture/architecture.001.png" alt="Architecture Overview">
|
||||
<img src="//download.scm-manager.org/images/architecture/architecture.001.png" alt="Architecture Overview">
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -33,4 +33,7 @@ http://bitbucket.org/sdorra/scm-manager
|
||||
<extension-point>
|
||||
<class>javax.servlet.ServletContextListener</class>
|
||||
</extension-point>
|
||||
<extension-point>
|
||||
<class>javax.servlet.http.HttpSessionListener</class>
|
||||
</extension-point>
|
||||
</module>
|
||||
|
||||
Reference in New Issue
Block a user