diff --git a/scm-core/src/main/java/sonia/scm/repository/RepositoryPathMatcher.java b/scm-core/src/main/java/sonia/scm/repository/RepositoryPathMatcher.java new file mode 100644 index 0000000000..74d8c87f5f --- /dev/null +++ b/scm-core/src/main/java/sonia/scm/repository/RepositoryPathMatcher.java @@ -0,0 +1,60 @@ +/** + * 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; + +import sonia.scm.plugin.ExtensionPoint; + +/** + * ExtensionPoint to modify the path matching behaviour for a certain type of repositories. + * + * @author Sebastian Sdorra + * @since 1.54 + */ +@ExtensionPoint +public interface RepositoryPathMatcher { + + /** + * Returns {@code true} if the path matches the repository. + * + * @param repository repository + * @param path requested path without context and without type information extracted from uri + * + * @return {@code true} if the path matches + */ + boolean isPathMatching(Repository repository, String path); + + /** + * Returns the type of repository for which the matcher is responsible. + * + * @return type of repository + */ + String getType(); +} diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitRepositoryPathMatcher.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitRepositoryPathMatcher.java new file mode 100644 index 0000000000..e77ac03da1 --- /dev/null +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitRepositoryPathMatcher.java @@ -0,0 +1,71 @@ +/** + * 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; + +import sonia.scm.plugin.ext.Extension; +import sonia.scm.util.HttpUtil; +import sonia.scm.util.Util; + +/** + * Matches git repositories with ".git" and without ".git". + * + * @author Sebastian Sdorra + * @since 1.54 + */ +@Extension +public class GitRepositoryPathMatcher implements RepositoryPathMatcher { + + @Override + public boolean isPathMatching(Repository repository, String path) { + String repositoryName = repository.getName(); + + if (path.startsWith(repositoryName)) { + + String pathPart = path.substring(repositoryName.length()); + + // git repository may also be named <>.git by convention + if (pathPart.startsWith(GitRepositoryHandler.DOT_GIT)) { + // if this is the case, just also cut it away + pathPart = pathPart.substring(GitRepositoryHandler.DOT_GIT.length()); + } + + return Util.isEmpty(pathPart) || pathPart.startsWith(HttpUtil.SEPARATOR_PATH); + } + + return false; + } + + @Override + public String getType() { + return GitRepositoryHandler.TYPE_NAME; + } + +} diff --git a/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/GitRepositoryPathMatcherTest.java b/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/GitRepositoryPathMatcherTest.java new file mode 100644 index 0000000000..7adc4a6913 --- /dev/null +++ b/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/GitRepositoryPathMatcherTest.java @@ -0,0 +1,62 @@ +/** + * 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; + +import org.junit.Test; +import static org.junit.Assert.*; + +/** + * Unit tests for {@link GitRepositoryPathMatcher}. + * + * @author Sebastian Sdorra + * @since 1.54 + */ +public class GitRepositoryPathMatcherTest { + + private final GitRepositoryPathMatcher pathMatcher = new GitRepositoryPathMatcher(); + + @Test + public void testIsPathMatching() { + assertFalse(pathMatcher.isPathMatching(repository("my-repo"), "my-repoo")); + assertFalse(pathMatcher.isPathMatching(repository("my"), "my-repo")); + assertFalse(pathMatcher.isPathMatching(repository("my"), "my-repo/with/path")); + + assertTrue(pathMatcher.isPathMatching(repository("my-repo"), "my-repo")); + assertTrue(pathMatcher.isPathMatching(repository("my-repo"), "my-repo.git")); + assertTrue(pathMatcher.isPathMatching(repository("my-repo"), "my-repo/with/path")); + assertTrue(pathMatcher.isPathMatching(repository("my-repo"), "my-repo.git/with/path")); + } + + private Repository repository(String name) { + return new Repository(name, GitRepositoryHandler.TYPE_NAME, name); + } + +} diff --git a/scm-webapp/src/main/java/sonia/scm/repository/DefaultRepositoryManager.java b/scm-webapp/src/main/java/sonia/scm/repository/DefaultRepositoryManager.java index 5369ee1c11..1c40313f97 100644 --- a/scm-webapp/src/main/java/sonia/scm/repository/DefaultRepositoryManager.java +++ b/scm-webapp/src/main/java/sonia/scm/repository/DefaultRepositoryManager.java @@ -35,7 +35,6 @@ package sonia.scm.repository; //~--- non-JDK imports -------------------------------------------------------- -import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Strings; import com.google.common.collect.Lists; import com.google.common.util.concurrent.ThreadFactoryBuilder; @@ -110,6 +109,7 @@ public class DefaultRepositoryManager extends AbstractRepositoryManager * @param repositoryListenersProvider * @param repositoryHooksProvider * @param preProcessorUtil + * @param repositoryMatcher */ @Inject public DefaultRepositoryManager(ScmConfiguration configuration, @@ -117,7 +117,7 @@ public class DefaultRepositoryManager extends AbstractRepositoryManager RepositoryDAO repositoryDAO, Set handlerSet, Provider> repositoryListenersProvider, Provider> repositoryHooksProvider, - PreProcessorUtil preProcessorUtil) + PreProcessorUtil preProcessorUtil, RepositoryMatcher repositoryMatcher) { this.configuration = configuration; this.keyGenerator = keyGenerator; @@ -125,6 +125,7 @@ public class DefaultRepositoryManager extends AbstractRepositoryManager this.repositoryListenersProvider = repositoryListenersProvider; this.repositoryHooksProvider = repositoryHooksProvider; this.preProcessorUtil = preProcessorUtil; + this.repositoryMatcher = repositoryMatcher; //J- ThreadFactory factory = new ThreadFactoryBuilder() @@ -703,7 +704,7 @@ public class DefaultRepositoryManager extends AbstractRepositoryManager for (Repository r : repositories) { - if (type.equals(r.getType()) && isNameMatching(r, uri)) + if (repositoryMatcher.matches(r, type, uri)) { assertIsReader(r); repository = r.clone(); @@ -972,51 +973,6 @@ public class DefaultRepositoryManager extends AbstractRepositoryManager return handler; } - /** - * This method checks whether or not the provided path belongs to the provided repository. - * - * @param repository The repository to be tested. - * @param path The path that might be part of the repository. - * @return Returns true if path belongs to the repository. Returns false otherwise. - */ - private boolean isNameMatching(Repository repository, String path) { - return isNameMatching(repository.getType(), repository.getName(), path); - } - - /** - * This method checks whether or not the provided path belongs to the provided repository. - * - * @param repositoryType The type of the repository being tested. - * @param repositoryName The name of the repository being tested. - * @param path The path that might be part of the repository. - * @return Returns true if path belongs to the repository. Returns false otherwise. - */ - @VisibleForTesting - boolean isNameMatching(String repositoryType, String repositoryName, String path) { - boolean result = false; - - if (path.startsWith(repositoryName)) { - - String pathPart = path.substring(repositoryName.length()); - - //TODO: this introduces a strong coupling to the git plugin. This can be resolved with a "Repository Matcher" API. - //ausformulieren, ticketId weg - if (GitRepositoryHandler.TYPE_NAME.equals(repositoryType)) { - - //git repository may also be named <>.git by convention - if (pathPart.startsWith(GitRepositoryHandler.DOT_GIT)) { - //if this is the case, just also cut it away - pathPart = pathPart.substring(GitRepositoryHandler.DOT_GIT.length()); - } - } - - result = Util.isEmpty(pathPart) || pathPart.startsWith(HttpUtil.SEPARATOR_PATH); - - } - - return result; - } - /** * Method description * @@ -1072,4 +1028,6 @@ public class DefaultRepositoryManager extends AbstractRepositoryManager /** Field description */ private Set types; + + private RepositoryMatcher repositoryMatcher; } diff --git a/scm-webapp/src/main/java/sonia/scm/repository/RepositoryMatcher.java b/scm-webapp/src/main/java/sonia/scm/repository/RepositoryMatcher.java new file mode 100644 index 0000000000..d0ad30e84f --- /dev/null +++ b/scm-webapp/src/main/java/sonia/scm/repository/RepositoryMatcher.java @@ -0,0 +1,119 @@ + /** + * 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; + +import com.google.common.collect.Maps; +import java.util.Map; +import java.util.Set; +import javax.inject.Inject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import sonia.scm.util.HttpUtil; +import sonia.scm.util.Util; + +/** + * RepositoryMatcher is able to check if a repository matches the requested path. + * + * @author Sebastian Sdorra + * @since 1.54 + */ +public final class RepositoryMatcher { + + private static final Logger LOG = LoggerFactory.getLogger(RepositoryMatcher.class); + + private static final RepositoryPathMatcher DEFAULT_PATH_MATCHER = new DefaultRepositoryPathMatcher(); + + private final Map pathMatchers; + + /** + * Creates a new instance. + * + * @param pathMatchers injected set of {@link RepositoryPathMatcher}. + */ + @Inject + public RepositoryMatcher(Set pathMatchers) { + this.pathMatchers = Maps.newHashMap(); + for ( RepositoryPathMatcher pathMatcher : pathMatchers ) { + LOG.info("register custom repository path matcher for type {}", pathMatcher.getType()); + this.pathMatchers.put(pathMatcher.getType(), pathMatcher); + } + } + + /** + * Returns {@code true} is the repository matches the type and the name matches the requested path. + * + * @param repository repository + * @param type type of repository + * @param path requested path without context and without type information + * + * @return {@code true} is the repository matches + */ + public boolean matches(Repository repository, String type, String path) { + return type.equals(repository.getType()) && isPathMatching(repository, path); + } + + private boolean isPathMatching(Repository repository, String path) { + return getPathMatcherForType(repository.getType()).isPathMatching(repository, path); + } + + private RepositoryPathMatcher getPathMatcherForType(String type) { + RepositoryPathMatcher pathMatcher = pathMatchers.get(type); + if (pathMatcher == null) { + pathMatcher = DEFAULT_PATH_MATCHER; + } + return pathMatcher; + } + + private static class DefaultRepositoryPathMatcher implements RepositoryPathMatcher { + + @Override + public boolean isPathMatching(Repository repository, String path) { + String name = repository.getName(); + + if (path.startsWith(name)) { + String sub = path.substring(name.length()); + + return Util.isEmpty(sub) || sub.startsWith(HttpUtil.SEPARATOR_PATH); + } + + return false; + } + + @Override + public String getType() { + return "any"; + } + + } + +} diff --git a/scm-webapp/src/test/java/sonia/scm/it/GitRepositoryPathMatcherITCase.java b/scm-webapp/src/test/java/sonia/scm/it/GitRepositoryPathMatcherITCase.java new file mode 100644 index 0000000000..079e2c520e --- /dev/null +++ b/scm-webapp/src/test/java/sonia/scm/it/GitRepositoryPathMatcherITCase.java @@ -0,0 +1,143 @@ +/** + * 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.it; + +import com.google.common.base.Charsets; +import com.google.common.io.Files; +import com.sun.jersey.api.client.Client; +import java.io.File; +import java.io.IOException; +import org.junit.After; +import static org.junit.Assert.*; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import static sonia.scm.it.IntegrationTestUtil.*; +import static sonia.scm.it.RepositoryITUtil.*; +import sonia.scm.repository.Person; +import sonia.scm.repository.Repository; +import sonia.scm.repository.RepositoryTestData; +import sonia.scm.repository.client.api.ClientCommand; +import sonia.scm.repository.client.api.RepositoryClient; +import sonia.scm.repository.client.api.RepositoryClientFactory; + +/** + * Integration test for RepositoryPathMatching with ".git" and without ".git". + * + * @author Sebastian Sdorra + * @since 1.54 + */ +public class GitRepositoryPathMatcherITCase { + + private static final RepositoryClientFactory REPOSITORY_CLIENT_FACTORY = new RepositoryClientFactory(); + + @Rule + public TemporaryFolder tempFolder = new TemporaryFolder(); + + private Client apiClient; + private Repository repository; + + @Before + public void setUp() { + apiClient = createAdminClient(); + Repository testRepository = RepositoryTestData.createHeartOfGold("git"); + this.repository = createRepository(apiClient, testRepository); + } + + @After + public void tearDown() { + deleteRepository(apiClient, repository.getId()); + } + + // tests begin + + @Test + public void testWithoutDotGit() throws IOException { + String urlWithoutDotGit = createUrl(); + cloneAndPush(urlWithoutDotGit); + } + + @Test + public void testWithDotGit() throws IOException { + String urlWithDotGit = createUrl() + ".git"; + cloneAndPush(urlWithDotGit); + } + + // tests end + + private String createUrl() { + return BASE_URL + "git/" + repository.getName(); + } + + private void cloneAndPush( String url ) throws IOException { + cloneRepositoryAndPushFiles(url); + cloneRepositoryAndCheckFiles(url); + } + + private void cloneRepositoryAndPushFiles(String url) throws IOException { + RepositoryClient repositoryClient = createRepositoryClient(url); + + Files.write("a", new File(repositoryClient.getWorkingCopy(), "a.txt"), Charsets.UTF_8); + repositoryClient.getAddCommand().add("a.txt"); + commit(repositoryClient, "added a"); + + Files.write("b", new File(repositoryClient.getWorkingCopy(), "b.txt"), Charsets.UTF_8); + repositoryClient.getAddCommand().add("b.txt"); + commit(repositoryClient, "added b"); + } + + private void cloneRepositoryAndCheckFiles(String url) throws IOException { + RepositoryClient repositoryClient = createRepositoryClient(url); + File workingCopy = repositoryClient.getWorkingCopy(); + + File a = new File(workingCopy, "a.txt"); + assertTrue(a.exists()); + assertEquals("a", Files.toString(a, Charsets.UTF_8)); + + File b = new File(workingCopy, "b.txt"); + assertTrue(b.exists()); + assertEquals("b", Files.toString(b, Charsets.UTF_8)); + } + + private void commit(RepositoryClient repositoryClient, String message) throws IOException { + repositoryClient.getCommitCommand().commit( + new Person("scmadmin", "scmadmin@scm-manager.org"), message + ); + if ( repositoryClient.isCommandSupported(ClientCommand.PUSH) ) { + repositoryClient.getPushCommand().push(); + } + } + + private RepositoryClient createRepositoryClient(String url) throws IOException { + return REPOSITORY_CLIENT_FACTORY.create("git", url, ADMIN_USERNAME, ADMIN_PASSWORD, tempFolder.newFolder()); + } +} diff --git a/scm-webapp/src/test/java/sonia/scm/repository/DefaultRepositoryManagerPerfTest.java b/scm-webapp/src/test/java/sonia/scm/repository/DefaultRepositoryManagerPerfTest.java index e00b2ccd6d..56b688099c 100644 --- a/scm-webapp/src/test/java/sonia/scm/repository/DefaultRepositoryManagerPerfTest.java +++ b/scm-webapp/src/test/java/sonia/scm/repository/DefaultRepositoryManagerPerfTest.java @@ -117,6 +117,7 @@ public class DefaultRepositoryManagerPerfTest { Set handlerSet = ImmutableSet.of(repositoryHandler); Provider> repositoryListenersProvider = new SetProvider(); Provider> repositoryHooksProvider = new SetProvider(); + RepositoryMatcher repositoryMatcher = new RepositoryMatcher(Collections.emptySet()); repositoryManager = new DefaultRepositoryManager( configuration, @@ -126,7 +127,8 @@ public class DefaultRepositoryManagerPerfTest { handlerSet, repositoryListenersProvider, repositoryHooksProvider, - preProcessorUtil + preProcessorUtil, + repositoryMatcher ); setUpTestRepositories(); diff --git a/scm-webapp/src/test/java/sonia/scm/repository/DefaultRepositoryManagerTest.java b/scm-webapp/src/test/java/sonia/scm/repository/DefaultRepositoryManagerTest.java index 7b7c304230..28b8613b7b 100644 --- a/scm-webapp/src/test/java/sonia/scm/repository/DefaultRepositoryManagerTest.java +++ b/scm-webapp/src/test/java/sonia/scm/repository/DefaultRepositoryManagerTest.java @@ -46,7 +46,6 @@ import sonia.scm.security.DefaultKeyGenerator; import sonia.scm.store.JAXBStoreFactory; import sonia.scm.store.StoreFactory; -import static org.hamcrest.CoreMatchers.is; import static org.junit.Assert.*; import static org.mockito.Mockito.*; @@ -54,6 +53,7 @@ import static org.mockito.Mockito.*; //~--- JDK imports ------------------------------------------------------------ import java.io.IOException; +import java.util.Collections; import java.util.HashSet; import java.util.Set; @@ -77,45 +77,21 @@ public class DefaultRepositoryManagerTest extends RepositoryManagerTestBase throws RepositoryException, IOException { RepositoryManager m = createManager(); - m.init(contextProvider); + createRepository(m, new Repository("1", "hg", "scm")); createRepository(m, new Repository("2", "hg", "scm-test")); createRepository(m, new Repository("3", "git", "project1/test-1")); createRepository(m, new Repository("4", "git", "project1/test-2")); + assertEquals("scm", m.getFromUri("hg/scm").getName()); assertEquals("scm-test", m.getFromUri("hg/scm-test").getName()); assertEquals("scm-test", m.getFromUri("/hg/scm-test").getName()); - assertEquals("project1/test-1", - m.getFromUri("/git/project1/test-1").getName()); - assertEquals("project1/test-1", - m.getFromUri("/git/project1/test-1/ka/some/path").getName()); + assertEquals("project1/test-1", m.getFromUri("/git/project1/test-1").getName()); + assertEquals("project1/test-1", m.getFromUri("/git/project1/test-1/ka/some/path").getName()); assertNull(m.getFromUri("/git/project1/test-3/ka/some/path")); } - @Test - public void testNameIsMatching() throws Exception { - DefaultRepositoryManager m = createManager(); - - assertThat(m.isNameMatching(GitRepositoryHandler.TYPE_NAME, "repo-name", "repo-name"), is(true)); - assertThat(m.isNameMatching(GitRepositoryHandler.TYPE_NAME, "repo-name", "repo-name/"), is(true)); - assertThat(m.isNameMatching(GitRepositoryHandler.TYPE_NAME, "repo-name", "repo-name/and-more-is-valid"), is(true)); - assertThat(m.isNameMatching(GitRepositoryHandler.TYPE_NAME, "repo-name", "repo-name.git/and-more-is-valid"), - is(true)); - - - assertThat(m.isNameMatching(GitRepositoryHandler.TYPE_NAME, "repo-name", "not-the-name"), is(false)); - assertThat(m.isNameMatching(GitRepositoryHandler.TYPE_NAME, "repo-name", "repo-na"), is(false)); - - assertThat(m.isNameMatching(GitRepositoryHandler.TYPE_NAME, "repo-name", "/repo-name/"), is(false)); - - assertThat(m.isNameMatching(HgRepositoryHandler.TYPE_NAME, "repo-name", "repo-name.git/and-more-is-valid"), - is(false)); - assertThat(m.isNameMatching(SvnRepositoryHandler.TYPE_NAME, "repo-name", "repo-name.git/and-more-is-valid"), - is(false)); - - } - //~--- methods -------------------------------------------------------------- /** @@ -180,7 +156,7 @@ public class DefaultRepositoryManagerTest extends RepositoryManagerTestBase return new DefaultRepositoryManager(configuration, contextProvider, new DefaultKeyGenerator(), repositoryDAO, handlerSet, listenerProvider, - hookProvider, createEmptyPreProcessorUtil()); + hookProvider, createEmptyPreProcessorUtil(), createRepositoryMatcher()); } /** @@ -202,6 +178,10 @@ public class DefaultRepositoryManagerTest extends RepositoryManagerTestBase ); //J+ } + + private RepositoryMatcher createRepositoryMatcher() { + return new RepositoryMatcher(Collections.emptySet()); + } /** * Method description diff --git a/scm-webapp/src/test/java/sonia/scm/repository/RepositoryMatcherTest.java b/scm-webapp/src/test/java/sonia/scm/repository/RepositoryMatcherTest.java new file mode 100644 index 0000000000..c832bb8691 --- /dev/null +++ b/scm-webapp/src/test/java/sonia/scm/repository/RepositoryMatcherTest.java @@ -0,0 +1,88 @@ +/** + * 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; + +import com.google.common.collect.Sets; +import java.util.Set; +import org.junit.Test; +import static org.junit.Assert.*; +import org.junit.Before; + +/** + * Unit tests for {@link RepositoryMatcher}. + * + * @author Sebastian Sdorra + * @since 1.54 + */ +public class RepositoryMatcherTest { + + private RepositoryMatcher matcher; + + @Before + public void setUp() { + Set pathMatchers = Sets.newHashSet(new AbcRepositoryPathMatcher()); + this.matcher = new RepositoryMatcher(pathMatchers); + } + + @Test + public void testMatches() { + assertFalse(matcher.matches(repository("hg", "scm"), "hg", "scm-test/ka")); + assertFalse(matcher.matches(repository("git", "scm-test"), "hg", "scm-test")); + + assertTrue(matcher.matches(repository("hg", "scm-test"), "hg", "scm-test/ka")); + assertTrue(matcher.matches(repository("hg", "scm-test"), "hg", "scm-test")); + } + + @Test + public void testMatchesWithCustomPathMatcher() { + assertFalse(matcher.matches(repository("abc", "scm"), "hg", "/long/path/with/abc")); + assertTrue(matcher.matches(repository("abc", "scm"), "abc", "/long/path/with/abc")); + } + + private Repository repository(String type, String name) { + return new Repository(type + "-" + name, type, name); + } + + private static class AbcRepositoryPathMatcher implements RepositoryPathMatcher { + + @Override + public boolean isPathMatching(Repository repository, String path) { + return path.endsWith("abc"); + } + + @Override + public String getType() { + return "abc"; + } + + } + +}