diff --git a/scm-core/src/main/java/sonia/scm/repository/AbstactImportHandler.java b/scm-core/src/main/java/sonia/scm/repository/AbstactImportHandler.java index 124e712c5b..e8bb551da8 100644 --- a/scm-core/src/main/java/sonia/scm/repository/AbstactImportHandler.java +++ b/scm-core/src/main/java/sonia/scm/repository/AbstactImportHandler.java @@ -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 importRepositories(RepositoryManager manager) throws IOException, RepositoryException { - List imported = new ArrayList(); - - if (logger.isTraceEnabled()) - { - logger.trace("search for repositories to import"); - } - - List 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,113 @@ 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 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 + * + * @throws T + */ + private 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 (RepositoryException ex) + { + builder.addFailedDirectory(repositoryName); + handleException(ex, throwExceptions); + } + } + else if (logger.isDebugEnabled()) + { + logger.debug("repository {} is allready managed", repositoryName); + } + } + /** * Method description * diff --git a/scm-core/src/main/java/sonia/scm/repository/AdvancedImportHandler.java b/scm-core/src/main/java/sonia/scm/repository/AdvancedImportHandler.java new file mode 100644 index 0000000000..7c1127b4a6 --- /dev/null +++ b/scm-core/src/main/java/sonia/scm/repository/AdvancedImportHandler.java @@ -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); +} diff --git a/scm-core/src/main/java/sonia/scm/repository/ImportResult.java b/scm-core/src/main/java/sonia/scm/repository/ImportResult.java new file mode 100644 index 0000000000..992ac33010 --- /dev/null +++ b/scm-core/src/main/java/sonia/scm/repository/ImportResult.java @@ -0,0 +1,230 @@ +/** + * 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; + +//~--- JDK imports ------------------------------------------------------------ + +import java.util.List; + +/** + * Import result of the {@link AdvancedImportHandler}. + * + * @author Sebastian Sdorra + * @since 1.43 + */ +public final class ImportResult +{ + + /** + * Constructs ... + * + */ + ImportResult() {} + + /** + * Constructs a new import result. + * + * + * @param importedDirectories imported directories + * @param failedDirectories failed directories + */ + public ImportResult(List importedDirectories, + List failedDirectories) + { + this.importedDirectories = importedDirectories; + this.failedDirectories = failedDirectories; + } + + //~--- 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 getFailedDirectories() + { + return failedDirectories; + } + + /** + * Returns list of successfully imported directories. + * + * + * @return list of successfully imported directories + */ + public List 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 importedDirectories = Lists.newArrayList(); + + /** failed directories */ + private final List failedDirectories = Lists.newArrayList(); + } + + + //~--- fields --------------------------------------------------------------- + + /** failed directories */ + private List failedDirectories; + + /** successfully imported directories */ + private List importedDirectories; +}