From 145502a7b8dd1a21d3f0855227ff89d1f0d70f5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Pfeuffer?= Date: Thu, 13 Sep 2018 10:35:10 +0200 Subject: [PATCH] Introduce extension point for further protocol implementations --- .../scm/repository/api/RepositoryService.java | 44 +++++++++--------- .../api/RepositoryServiceFactory.java | 8 +++- .../repository/api/ScmProtocolProvider.java | 12 +++++ .../InitializingHttpScmProtocolWrapper.java | 7 ++- .../spi/RepositoryServiceProvider.java | 3 -- .../repository/api/RepositoryServiceTest.java | 43 +++++++++++++----- ...nitializingHttpScmProtocolWrapperTest.java | 19 +++++--- .../spi/GitRepositoryServiceProvider.java | 14 +----- .../spi/GitRepositoryServiceResolver.java | 11 ++--- .../web/GitScmProtocolProviderWrapper.java | 7 +++ .../spi/HgRepositoryServiceProvider.java | 12 +---- .../spi/HgRepositoryServiceResolver.java | 45 +++---------------- .../scm/web/HgScmProtocolProviderWrapper.java | 7 +++ .../spi/SvnRepositoryServiceProvider.java | 19 +------- .../spi/SvnRepositoryServiceResolver.java | 12 ++--- .../web/SvnScmProtocolProviderWrapper.java | 7 +++ .../RepositoryToRepositoryDtoMapper.java | 5 +-- .../resources/RepositoryRootResourceTest.java | 4 +- .../RepositoryToRepositoryDtoMapperTest.java | 11 +++-- 19 files changed, 137 insertions(+), 153 deletions(-) create mode 100644 scm-core/src/main/java/sonia/scm/repository/api/ScmProtocolProvider.java diff --git a/scm-core/src/main/java/sonia/scm/repository/api/RepositoryService.java b/scm-core/src/main/java/sonia/scm/repository/api/RepositoryService.java index 61c3ce5d87..4d388609d8 100644 --- a/scm-core/src/main/java/sonia/scm/repository/api/RepositoryService.java +++ b/scm-core/src/main/java/sonia/scm/repository/api/RepositoryService.java @@ -42,7 +42,8 @@ import sonia.scm.repository.spi.RepositoryServiceProvider; import java.io.Closeable; import java.io.IOException; -import java.util.Collection; +import java.util.Set; +import java.util.stream.Stream; /** * From the {@link RepositoryService} it is possible to access all commands for @@ -80,29 +81,30 @@ import java.util.Collection; * @since 1.17 */ public final class RepositoryService implements Closeable { - private CacheManager cacheManager; - private PreProcessorUtil preProcessorUtil; - private RepositoryServiceProvider provider; - private Repository repository; - private static final Logger logger = - LoggerFactory.getLogger(RepositoryService.class); + + private static final Logger logger = LoggerFactory.getLogger(RepositoryService.class); + + private final CacheManager cacheManager; + private final PreProcessorUtil preProcessorUtil; + private final RepositoryServiceProvider provider; + private final Repository repository; + private final Set protocolProviders; /** * Constructs a new {@link RepositoryService}. This constructor should only * be called from the {@link RepositoryServiceFactory}. - * - * @param cacheManager cache manager + * @param cacheManager cache manager * @param provider implementation for {@link RepositoryServiceProvider} * @param repository the repository - * @param preProcessorUtil */ RepositoryService(CacheManager cacheManager, - RepositoryServiceProvider provider, Repository repository, - PreProcessorUtil preProcessorUtil) { + RepositoryServiceProvider provider, Repository repository, + PreProcessorUtil preProcessorUtil, Set protocolProviders) { this.cacheManager = cacheManager; this.provider = provider; this.repository = repository; this.preProcessorUtil = preProcessorUtil; + this.protocolProviders = protocolProviders; } /** @@ -359,16 +361,18 @@ public final class RepositoryService implements Closeable { } - public Collection getSupportedProtocols() { - return provider.getSupportedProtocols(); + public Stream getSupportedProtocols() { + return protocolProviders.stream().filter(provider -> provider.getType().equals(getRepository().getType())).map(this::createProviderInstanceForRepository); + } + + private ScmProtocol createProviderInstanceForRepository(ScmProtocolProvider protocolProvider) { + return protocolProvider.get(repository); } public T getProtocol(Class clazz) { - for (ScmProtocol scmProtocol : getSupportedProtocols()) { - if (clazz.isAssignableFrom(scmProtocol.getClass())) { - return (T) scmProtocol; - } - } - throw new IllegalArgumentException("no implementation for " + clazz.getName() + " and repository type " + getRepository().getType()); + return (T) getSupportedProtocols() + .filter(scmProtocol -> clazz.isAssignableFrom(scmProtocol.getClass())) + .findFirst() + .orElseThrow(() -> new IllegalArgumentException("no implementation for " + clazz.getName() + " and repository type " + getRepository().getType())); } } diff --git a/scm-core/src/main/java/sonia/scm/repository/api/RepositoryServiceFactory.java b/scm-core/src/main/java/sonia/scm/repository/api/RepositoryServiceFactory.java index 33f57d4524..fbb1ee6b58 100644 --- a/scm-core/src/main/java/sonia/scm/repository/api/RepositoryServiceFactory.java +++ b/scm-core/src/main/java/sonia/scm/repository/api/RepositoryServiceFactory.java @@ -137,13 +137,15 @@ public final class RepositoryServiceFactory @Inject public RepositoryServiceFactory(ScmConfiguration configuration, CacheManager cacheManager, RepositoryManager repositoryManager, - Set resolvers, PreProcessorUtil preProcessorUtil) + Set resolvers, PreProcessorUtil preProcessorUtil, + Set protocolProviders) { this.configuration = configuration; this.cacheManager = cacheManager; this.repositoryManager = repositoryManager; this.resolvers = resolvers; this.preProcessorUtil = preProcessorUtil; + this.protocolProviders = protocolProviders; ScmEventBus.getInstance().register(new CacheClearHook(cacheManager)); } @@ -252,7 +254,7 @@ public final class RepositoryServiceFactory } service = new RepositoryService(cacheManager, provider, repository, - preProcessorUtil); + preProcessorUtil, protocolProviders); break; } @@ -367,4 +369,6 @@ public final class RepositoryServiceFactory /** service resolvers */ private final Set resolvers; + + private Set protocolProviders; } diff --git a/scm-core/src/main/java/sonia/scm/repository/api/ScmProtocolProvider.java b/scm-core/src/main/java/sonia/scm/repository/api/ScmProtocolProvider.java new file mode 100644 index 0000000000..d4be5dca59 --- /dev/null +++ b/scm-core/src/main/java/sonia/scm/repository/api/ScmProtocolProvider.java @@ -0,0 +1,12 @@ +package sonia.scm.repository.api; + +import sonia.scm.plugin.ExtensionPoint; +import sonia.scm.repository.Repository; + +@ExtensionPoint(multi = true) +public interface ScmProtocolProvider { + + String getType(); + + ScmProtocol get(Repository repository); +} diff --git a/scm-core/src/main/java/sonia/scm/repository/spi/InitializingHttpScmProtocolWrapper.java b/scm-core/src/main/java/sonia/scm/repository/spi/InitializingHttpScmProtocolWrapper.java index c5fd037cc8..6e59470c5e 100644 --- a/scm-core/src/main/java/sonia/scm/repository/spi/InitializingHttpScmProtocolWrapper.java +++ b/scm-core/src/main/java/sonia/scm/repository/spi/InitializingHttpScmProtocolWrapper.java @@ -5,6 +5,7 @@ import org.slf4j.LoggerFactory; import sonia.scm.api.v2.resources.ScmPathInfoStore; import sonia.scm.config.ScmConfiguration; import sonia.scm.repository.Repository; +import sonia.scm.repository.api.ScmProtocolProvider; import sonia.scm.web.filter.PermissionFilter; import javax.inject.Provider; @@ -18,7 +19,7 @@ import java.util.Optional; import static java.util.Optional.empty; import static java.util.Optional.of; -public abstract class InitializingHttpScmProtocolWrapper { +public abstract class InitializingHttpScmProtocolWrapper implements ScmProtocolProvider { private static final Logger logger = LoggerFactory.getLogger(InitializingHttpScmProtocolWrapper.class); @@ -41,7 +42,11 @@ public abstract class InitializingHttpScmProtocolWrapper { httpServlet.init(config); } + @Override public HttpScmProtocol get(Repository repository) { + if (!repository.getType().equals(getType())) { + throw new IllegalArgumentException("cannot handle repository with type " + repository.getType() + " with protocol for type " + getType()); + } return new ProtocolWrapper(repository); } diff --git a/scm-core/src/main/java/sonia/scm/repository/spi/RepositoryServiceProvider.java b/scm-core/src/main/java/sonia/scm/repository/spi/RepositoryServiceProvider.java index 0a56800f82..e0981b840c 100644 --- a/scm-core/src/main/java/sonia/scm/repository/spi/RepositoryServiceProvider.java +++ b/scm-core/src/main/java/sonia/scm/repository/spi/RepositoryServiceProvider.java @@ -36,7 +36,6 @@ package sonia.scm.repository.spi; import sonia.scm.repository.Feature; import sonia.scm.repository.api.Command; import sonia.scm.repository.api.CommandNotSupportedException; -import sonia.scm.repository.api.ScmProtocol; import java.io.Closeable; import java.io.IOException; @@ -240,6 +239,4 @@ public abstract class RepositoryServiceProvider implements Closeable { throw new CommandNotSupportedException(Command.UNBUNDLE); } - - public abstract Set getSupportedProtocols(); } diff --git a/scm-core/src/test/java/sonia/scm/repository/api/RepositoryServiceTest.java b/scm-core/src/test/java/sonia/scm/repository/api/RepositoryServiceTest.java index 9cb398b571..2ceafc19bb 100644 --- a/scm-core/src/test/java/sonia/scm/repository/api/RepositoryServiceTest.java +++ b/scm-core/src/test/java/sonia/scm/repository/api/RepositoryServiceTest.java @@ -8,38 +8,43 @@ import sonia.scm.repository.spi.RepositoryServiceProvider; import javax.servlet.ServletConfig; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import java.util.Collection; import java.util.Collections; +import java.util.stream.Collectors; +import java.util.stream.Stream; import static org.assertj.core.api.AssertionsForClassTypes.assertThat; import static org.assertj.core.util.IterableUtil.sizeOf; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; public class RepositoryServiceTest { private final RepositoryServiceProvider provider = mock(RepositoryServiceProvider.class); - private final Repository repository = mock(Repository.class); + private final Repository repository = new Repository("", "git", "space", "repo"); @Test - public void shouldReturnProtocolsFromProvider() { - when(provider.getSupportedProtocols()).thenReturn(Collections.singleton(new DummyHttpProtocol(repository))); + public void shouldReturnMatchingProtocolsFromProvider() { + RepositoryService repositoryService = new RepositoryService(null, provider, repository, null, Collections.singleton(new DummyScmProtocolProvider())); + Stream supportedProtocols = repositoryService.getSupportedProtocols(); - RepositoryService repositoryService = new RepositoryService(null, provider, repository, null); - Collection supportedProtocols = repositoryService.getSupportedProtocols(); + assertThat(sizeOf(supportedProtocols.collect(Collectors.toList()))).isEqualTo(1); + } - assertThat(sizeOf(supportedProtocols)).isEqualTo(1); + @Test + public void shouldFindKnownProtocol() { + RepositoryService repositoryService = new RepositoryService(null, provider, repository, null, Collections.singleton(new DummyScmProtocolProvider())); + + HttpScmProtocol protocol = repositoryService.getProtocol(HttpScmProtocol.class); + + assertThat(protocol).isNotNull(); } @Test public void shouldFailForUnknownProtocol() { - when(provider.getSupportedProtocols()).thenReturn(Collections.emptySet()); - - RepositoryService repositoryService = new RepositoryService(null, provider, repository, null); + RepositoryService repositoryService = new RepositoryService(null, provider, repository, null, Collections.singleton(new DummyScmProtocolProvider())); assertThrows(IllegalArgumentException.class, () -> { - repositoryService.getProtocol(HttpScmProtocol.class); + repositoryService.getProtocol(UnknownScmProtocol.class); }); } @@ -52,4 +57,18 @@ public class RepositoryServiceTest { public void serve(HttpServletRequest request, HttpServletResponse response, Repository repository, ServletConfig config) { } } + + private static class DummyScmProtocolProvider implements ScmProtocolProvider { + @Override + public String getType() { + return "git"; + } + + @Override + public ScmProtocol get(Repository repository) { + return new DummyHttpProtocol(repository); + } + } + + private interface UnknownScmProtocol extends ScmProtocol {} } diff --git a/scm-core/src/test/java/sonia/scm/repository/spi/InitializingHttpScmProtocolWrapperTest.java b/scm-core/src/test/java/sonia/scm/repository/spi/InitializingHttpScmProtocolWrapperTest.java index 1e742a768a..6d01232fe3 100644 --- a/scm-core/src/test/java/sonia/scm/repository/spi/InitializingHttpScmProtocolWrapperTest.java +++ b/scm-core/src/test/java/sonia/scm/repository/spi/InitializingHttpScmProtocolWrapperTest.java @@ -62,7 +62,12 @@ public class InitializingHttpScmProtocolWrapperTest { pathInfoStoreProvider = mock(Provider.class); when(pathInfoStoreProvider.get()).thenReturn(pathInfoStore); - wrapper = new InitializingHttpScmProtocolWrapper(Providers.of(this.delegateServlet), Providers.of(permissionFilter), pathInfoStoreProvider, scmConfiguration) {}; + wrapper = new InitializingHttpScmProtocolWrapper(Providers.of(this.delegateServlet), Providers.of(permissionFilter), pathInfoStoreProvider, scmConfiguration) { + @Override + public String getType() { + return "git"; + } + }; when(scmConfiguration.getBaseUrl()).thenReturn("http://example.com/scm"); } @@ -127,6 +132,11 @@ public class InitializingHttpScmProtocolWrapperTest { verify(delegateServlet, times(2)).service(request, response, REPOSITORY); } + @Test(expected = IllegalArgumentException.class) + public void shouldFailForIllegalScmType() { + HttpScmProtocol httpScmProtocol = wrapper.get(new Repository("", "other", "space", "name")); + } + private Answer proceedInvocation() { return invocation -> { ((PermissionFilter.ContinuationServlet) invocation.getArgument(3)).doService(); @@ -135,12 +145,7 @@ public class InitializingHttpScmProtocolWrapperTest { } private OngoingStubbing mockSetPathInfo() { - return when(pathInfoStore.get()).thenReturn(new ScmPathInfo() { - @Override - public URI getApiRestUri() { - return URI.create("http://example.com/scm/api/rest/"); - } - }); + return when(pathInfoStore.get()).thenReturn(() -> URI.create("http://example.com/scm/api/rest/")); } } diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitRepositoryServiceProvider.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitRepositoryServiceProvider.java index 235136938a..2d6b49a8e5 100644 --- a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitRepositoryServiceProvider.java +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitRepositoryServiceProvider.java @@ -37,10 +37,8 @@ import com.google.common.collect.ImmutableSet; import sonia.scm.repository.GitRepositoryHandler; import sonia.scm.repository.Repository; import sonia.scm.repository.api.Command; -import sonia.scm.repository.api.ScmProtocol; import java.io.IOException; -import java.util.Collections; import java.util.Set; /** @@ -69,12 +67,9 @@ public class GitRepositoryServiceProvider extends RepositoryServiceProvider //~--- constructors --------------------------------------------------------- - public GitRepositoryServiceProvider(GitRepositoryHandler handler, - Repository repository, HttpScmProtocol httpScmProtocol) - { + public GitRepositoryServiceProvider(GitRepositoryHandler handler, Repository repository) { this.handler = handler; this.repository = repository; - this.httpScmProtocol = httpScmProtocol; this.context = new GitContext(handler.getDirectory(repository)); } @@ -238,11 +233,6 @@ public class GitRepositoryServiceProvider extends RepositoryServiceProvider return new GitTagsCommand(context, repository); } - @Override - public Set getSupportedProtocols() { - return Collections.singleton(httpScmProtocol); - } - //~--- fields --------------------------------------------------------------- /** Field description */ @@ -253,6 +243,4 @@ public class GitRepositoryServiceProvider extends RepositoryServiceProvider /** Field description */ private Repository repository; - - private final HttpScmProtocol httpScmProtocol; } diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitRepositoryServiceResolver.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitRepositoryServiceResolver.java index d20eedca9f..b1e9143afd 100644 --- a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitRepositoryServiceResolver.java +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitRepositoryServiceResolver.java @@ -38,7 +38,6 @@ import com.google.inject.Inject; import sonia.scm.plugin.Extension; import sonia.scm.repository.GitRepositoryHandler; import sonia.scm.repository.Repository; -import sonia.scm.web.GitScmProtocolProviderWrapper; /** * @@ -49,10 +48,11 @@ public class GitRepositoryServiceResolver implements RepositoryServiceResolver { public static final String TYPE = "git"; + private final GitRepositoryHandler handler; + @Inject - public GitRepositoryServiceResolver(GitRepositoryHandler handler, GitScmProtocolProviderWrapper providerWrapper) { + public GitRepositoryServiceResolver(GitRepositoryHandler handler) { this.handler = handler; - this.providerWrapper = providerWrapper; } @Override @@ -60,12 +60,9 @@ public class GitRepositoryServiceResolver implements RepositoryServiceResolver { GitRepositoryServiceProvider provider = null; if (TYPE.equalsIgnoreCase(repository.getType())) { - provider = new GitRepositoryServiceProvider(handler, repository, providerWrapper.get(repository)); + provider = new GitRepositoryServiceProvider(handler, repository); } return provider; } - - private final GitRepositoryHandler handler; - private final GitScmProtocolProviderWrapper providerWrapper; } diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/web/GitScmProtocolProviderWrapper.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/web/GitScmProtocolProviderWrapper.java index 8ff0c6d421..3df7bcce3f 100644 --- a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/web/GitScmProtocolProviderWrapper.java +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/web/GitScmProtocolProviderWrapper.java @@ -2,6 +2,7 @@ package sonia.scm.web; import sonia.scm.api.v2.resources.ScmPathInfoStore; import sonia.scm.config.ScmConfiguration; +import sonia.scm.plugin.Extension; import sonia.scm.repository.spi.InitializingHttpScmProtocolWrapper; import javax.inject.Inject; @@ -9,9 +10,15 @@ import javax.inject.Provider; import javax.inject.Singleton; @Singleton +@Extension public class GitScmProtocolProviderWrapper extends InitializingHttpScmProtocolWrapper { @Inject public GitScmProtocolProviderWrapper(Provider servletProvider, Provider permissionFilter, Provider uriInfoStore, ScmConfiguration scmConfiguration) { super(servletProvider, permissionFilter, uriInfoStore, scmConfiguration); } + + @Override + public String getType() { + return "git"; + } } diff --git a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgRepositoryServiceProvider.java b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgRepositoryServiceProvider.java index 8c280a9915..164eb4e13a 100644 --- a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgRepositoryServiceProvider.java +++ b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgRepositoryServiceProvider.java @@ -39,11 +39,9 @@ import sonia.scm.repository.HgHookManager; import sonia.scm.repository.HgRepositoryHandler; import sonia.scm.repository.Repository; import sonia.scm.repository.api.Command; -import sonia.scm.repository.api.ScmProtocol; import java.io.File; import java.io.IOException; -import java.util.Collections; import java.util.EnumSet; import java.util.Set; @@ -78,11 +76,10 @@ public class HgRepositoryServiceProvider extends RepositoryServiceProvider //~--- constructors --------------------------------------------------------- HgRepositoryServiceProvider(HgRepositoryHandler handler, - HgHookManager hookManager, Repository repository, HttpScmProtocol httpScmProtocol) + HgHookManager hookManager, Repository repository) { this.repository = repository; this.handler = handler; - this.httpScmProtocol = httpScmProtocol; this.repositoryDirectory = handler.getDirectory(repository); this.context = new HgCommandContext(hookManager, handler, repository, repositoryDirectory); @@ -260,11 +257,6 @@ public class HgRepositoryServiceProvider extends RepositoryServiceProvider return new HgTagsCommand(context, repository); } - @Override - public Set getSupportedProtocols() { - return Collections.singleton(httpScmProtocol); - } - //~--- fields --------------------------------------------------------------- /** Field description */ @@ -278,6 +270,4 @@ public class HgRepositoryServiceProvider extends RepositoryServiceProvider /** Field description */ private File repositoryDirectory; - - private final HttpScmProtocol httpScmProtocol; } diff --git a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgRepositoryServiceResolver.java b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgRepositoryServiceResolver.java index c1accbad1a..f80dcd5ba8 100644 --- a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgRepositoryServiceResolver.java +++ b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgRepositoryServiceResolver.java @@ -38,7 +38,6 @@ import sonia.scm.plugin.Extension; import sonia.scm.repository.HgHookManager; import sonia.scm.repository.HgRepositoryHandler; import sonia.scm.repository.Repository; -import sonia.scm.web.HgScmProtocolProviderWrapper; /** * @@ -48,59 +47,27 @@ import sonia.scm.web.HgScmProtocolProviderWrapper; public class HgRepositoryServiceResolver implements RepositoryServiceResolver { - /** Field description */ private static final String TYPE = "hg"; - //~--- constructors --------------------------------------------------------- + private HgRepositoryHandler handler; + private HgHookManager hookManager; - /** - * Constructs ... - * - * - * - * @param hookManager - * @param handler - */ @Inject public HgRepositoryServiceResolver(HgRepositoryHandler handler, - HgHookManager hookManager, HgScmProtocolProviderWrapper providerWrapper) + HgHookManager hookManager) { this.handler = handler; this.hookManager = hookManager; - this.providerWrapper = providerWrapper; } - //~--- methods -------------------------------------------------------------- - - /** - * Method description - * - * - * @param repository - * - * @return - */ @Override - public HgRepositoryServiceProvider resolve(Repository repository) - { + public HgRepositoryServiceProvider resolve(Repository repository) { HgRepositoryServiceProvider provider = null; - if (TYPE.equalsIgnoreCase(repository.getType())) - { - provider = new HgRepositoryServiceProvider(handler, hookManager, - repository, providerWrapper.get(repository)); + if (TYPE.equalsIgnoreCase(repository.getType())) { + provider = new HgRepositoryServiceProvider(handler, hookManager, repository); } return provider; } - - //~--- fields --------------------------------------------------------------- - - /** Field description */ - private HgRepositoryHandler handler; - - /** Field description */ - private HgHookManager hookManager; - - private final HgScmProtocolProviderWrapper providerWrapper; } diff --git a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/web/HgScmProtocolProviderWrapper.java b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/web/HgScmProtocolProviderWrapper.java index e843f09ad4..5ea8e66501 100644 --- a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/web/HgScmProtocolProviderWrapper.java +++ b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/web/HgScmProtocolProviderWrapper.java @@ -2,6 +2,7 @@ package sonia.scm.web; import sonia.scm.api.v2.resources.ScmPathInfoStore; import sonia.scm.config.ScmConfiguration; +import sonia.scm.plugin.Extension; import sonia.scm.repository.spi.InitializingHttpScmProtocolWrapper; import javax.inject.Inject; @@ -9,9 +10,15 @@ import javax.inject.Provider; import javax.inject.Singleton; @Singleton +@Extension public class HgScmProtocolProviderWrapper extends InitializingHttpScmProtocolWrapper { @Inject public HgScmProtocolProviderWrapper(Provider servletProvider, Provider permissionFilter, Provider uriInfoStore, ScmConfiguration scmConfiguration) { super(servletProvider, permissionFilter, uriInfoStore, scmConfiguration); } + + @Override + public String getType() { + return "hg"; + } } diff --git a/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/spi/SvnRepositoryServiceProvider.java b/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/spi/SvnRepositoryServiceProvider.java index 6c08d35897..909daf7e36 100644 --- a/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/spi/SvnRepositoryServiceProvider.java +++ b/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/spi/SvnRepositoryServiceProvider.java @@ -38,10 +38,8 @@ import com.google.common.io.Closeables; import sonia.scm.repository.Repository; import sonia.scm.repository.SvnRepositoryHandler; import sonia.scm.repository.api.Command; -import sonia.scm.repository.api.ScmProtocol; import java.io.IOException; -import java.util.Collections; import java.util.Set; /** @@ -61,18 +59,10 @@ public class SvnRepositoryServiceProvider extends RepositoryServiceProvider //~--- constructors --------------------------------------------------------- - /** - * Constructs ... - * - * @param handler - * @param repository - * @param httpScmProtocol - */ SvnRepositoryServiceProvider(SvnRepositoryHandler handler, - Repository repository, HttpScmProtocol httpScmProtocol) + Repository repository) { this.repository = repository; - this.httpScmProtocol = httpScmProtocol; this.context = new SvnContext(handler.getDirectory(repository)); } @@ -188,11 +178,6 @@ public class SvnRepositoryServiceProvider extends RepositoryServiceProvider return new SvnUnbundleCommand(context, repository); } - @Override - public Set getSupportedProtocols() { - return Collections.singleton(httpScmProtocol); - } - //~--- fields --------------------------------------------------------------- /** Field description */ @@ -200,6 +185,4 @@ public class SvnRepositoryServiceProvider extends RepositoryServiceProvider /** Field description */ private final Repository repository; - - private final HttpScmProtocol httpScmProtocol; } diff --git a/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/spi/SvnRepositoryServiceResolver.java b/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/spi/SvnRepositoryServiceResolver.java index 9f5ea234ce..c674a7827a 100644 --- a/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/spi/SvnRepositoryServiceResolver.java +++ b/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/spi/SvnRepositoryServiceResolver.java @@ -36,17 +36,17 @@ import com.google.inject.Inject; import sonia.scm.plugin.Extension; import sonia.scm.repository.Repository; import sonia.scm.repository.SvnRepositoryHandler; -import sonia.scm.web.SvnScmProtocolProviderWrapper; @Extension public class SvnRepositoryServiceResolver implements RepositoryServiceResolver { public static final String TYPE = "svn"; + private SvnRepositoryHandler handler; + @Inject - public SvnRepositoryServiceResolver(SvnRepositoryHandler handler, SvnScmProtocolProviderWrapper protocolWrapper) { + public SvnRepositoryServiceResolver(SvnRepositoryHandler handler) { this.handler = handler; - this.protocolWrapper = protocolWrapper; } @Override @@ -54,13 +54,9 @@ public class SvnRepositoryServiceResolver implements RepositoryServiceResolver { SvnRepositoryServiceProvider provider = null; if (TYPE.equalsIgnoreCase(repository.getType())) { - provider = new SvnRepositoryServiceProvider(handler, repository, protocolWrapper.get(repository)); + provider = new SvnRepositoryServiceProvider(handler, repository); } return provider; } - - private SvnRepositoryHandler handler; - - private final InitializingHttpScmProtocolWrapper protocolWrapper; } diff --git a/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/web/SvnScmProtocolProviderWrapper.java b/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/web/SvnScmProtocolProviderWrapper.java index ebcfa138bc..14b946acc7 100644 --- a/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/web/SvnScmProtocolProviderWrapper.java +++ b/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/web/SvnScmProtocolProviderWrapper.java @@ -2,6 +2,7 @@ package sonia.scm.web; import sonia.scm.api.v2.resources.ScmPathInfoStore; import sonia.scm.config.ScmConfiguration; +import sonia.scm.plugin.Extension; import sonia.scm.repository.spi.InitializingHttpScmProtocolWrapper; import sonia.scm.repository.spi.ScmProviderHttpServlet; @@ -14,10 +15,16 @@ import javax.servlet.ServletException; import java.util.Enumeration; @Singleton +@Extension public class SvnScmProtocolProviderWrapper extends InitializingHttpScmProtocolWrapper { public static final String PARAMETER_SVN_PARENTPATH = "SVNParentPath"; + @Override + public String getType() { + return "svn"; + } + @Inject public SvnScmProtocolProviderWrapper(Provider servletProvider, Provider permissionFilter, Provider uriInfoStore, ScmConfiguration scmConfiguration) { super(servletProvider, permissionFilter, uriInfoStore, scmConfiguration); diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/RepositoryToRepositoryDtoMapper.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/RepositoryToRepositoryDtoMapper.java index ce716f2f6f..6675caac88 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/RepositoryToRepositoryDtoMapper.java +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/RepositoryToRepositoryDtoMapper.java @@ -14,7 +14,6 @@ import sonia.scm.repository.api.RepositoryService; import sonia.scm.repository.api.RepositoryServiceFactory; import sonia.scm.repository.api.ScmProtocol; -import java.util.Collection; import java.util.List; import static de.otto.edison.hal.Link.link; @@ -47,9 +46,7 @@ public abstract class RepositoryToRepositoryDtoMapper extends BaseMapper supportedProtocols = repositoryService.getSupportedProtocols(); - List protocolLinks = supportedProtocols - .stream() + List protocolLinks = repositoryService.getSupportedProtocols() .map(protocol -> createProtocolLink(protocol, repository)) .collect(toList()); linksBuilder.array(protocolLinks); diff --git a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/RepositoryRootResourceTest.java b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/RepositoryRootResourceTest.java index 4d0bb38785..04a4602a7c 100644 --- a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/RepositoryRootResourceTest.java +++ b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/RepositoryRootResourceTest.java @@ -30,8 +30,8 @@ import java.net.URI; import java.net.URISyntaxException; import java.net.URL; -import static java.util.Arrays.asList; import static java.util.Collections.singletonList; +import static java.util.stream.Stream.of; import static javax.servlet.http.HttpServletResponse.SC_BAD_REQUEST; import static javax.servlet.http.HttpServletResponse.SC_NOT_FOUND; import static javax.servlet.http.HttpServletResponse.SC_NO_CONTENT; @@ -281,7 +281,7 @@ public class RepositoryRootResourceTest { @Test public void shouldCreateArrayOfProtocolUrls() throws Exception { mockRepository("space", "repo"); - when(service.getSupportedProtocols()).thenReturn(asList(new MockScmProtocol("http", "http://"), new MockScmProtocol("ssh", "ssh://"))); + when(service.getSupportedProtocols()).thenReturn(of(new MockScmProtocol("http", "http://"), new MockScmProtocol("ssh", "ssh://"))); MockHttpRequest request = MockHttpRequest.get("/" + RepositoryRootResource.REPOSITORIES_PATH_V2 + "space/repo"); MockHttpResponse response = new MockHttpResponse(); diff --git a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/RepositoryToRepositoryDtoMapperTest.java b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/RepositoryToRepositoryDtoMapperTest.java index 0fbece9730..d60b62937e 100644 --- a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/RepositoryToRepositoryDtoMapperTest.java +++ b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/RepositoryToRepositoryDtoMapperTest.java @@ -20,9 +20,8 @@ import sonia.scm.repository.api.ScmProtocol; import java.net.URI; -import static java.util.Arrays.asList; -import static java.util.Collections.emptySet; import static java.util.Collections.singletonList; +import static java.util.stream.Stream.of; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; @@ -60,7 +59,7 @@ public class RepositoryToRepositoryDtoMapperTest { initMocks(this); when(serviceFactory.create(any(Repository.class))).thenReturn(repositoryService); when(repositoryService.isSupported(any(Command.class))).thenReturn(true); - when(repositoryService.getSupportedProtocols()).thenReturn(emptySet()); + when(repositoryService.getSupportedProtocols()).thenReturn(of()); when(scmPathInfoStore.get()).thenReturn(uriInfo); when(uriInfo.getApiRestUri()).thenReturn(URI.create("/x/y")); } @@ -182,7 +181,7 @@ public class RepositoryToRepositoryDtoMapperTest { @Test public void shouldCreateCorrectProtocolLinks() { when(repositoryService.getSupportedProtocols()).thenReturn( - asList(mockProtocol("http", "http://scm"), mockProtocol("other", "some://protocol")) + of(mockProtocol("http", "http://scm"), mockProtocol("other", "some://protocol")) ); RepositoryDto dto = mapper.map(createTestRepository()); @@ -194,7 +193,7 @@ public class RepositoryToRepositoryDtoMapperTest { @SubjectAware(username = "community") public void shouldCreateProtocolLinksForPullPermission() { when(repositoryService.getSupportedProtocols()).thenReturn( - asList(mockProtocol("http", "http://scm"), mockProtocol("other", "some://protocol")) + of(mockProtocol("http", "http://scm"), mockProtocol("other", "some://protocol")) ); RepositoryDto dto = mapper.map(createTestRepository()); @@ -205,7 +204,7 @@ public class RepositoryToRepositoryDtoMapperTest { @SubjectAware(username = "unpriv") public void shouldNotCreateProtocolLinksWithoutPullPermission() { when(repositoryService.getSupportedProtocols()).thenReturn( - asList(mockProtocol("http", "http://scm"), mockProtocol("other", "some://protocol")) + of(mockProtocol("http", "http://scm"), mockProtocol("other", "some://protocol")) ); RepositoryDto dto = mapper.map(createTestRepository());