use child injector pattern for git commands

We are using a Google Guice child injector to reduce the amount of injection dependencies for the GitRepositoryServiceResolver and the GitRepositoryServiceProvider.
This commit is contained in:
Sebastian Sdorra
2020-07-20 16:17:18 +02:00
parent 1015445ba5
commit 6e27051ed9
23 changed files with 290 additions and 199 deletions

View File

@@ -41,6 +41,7 @@ import sonia.scm.repository.GitUtil;
import sonia.scm.repository.InternalRepositoryException;
import sonia.scm.repository.Person;
import javax.inject.Inject;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
@@ -64,6 +65,7 @@ public class GitBlameCommand extends AbstractGitCommand implements BlameCommand
//~--- constructors ---------------------------------------------------------
@Inject
public GitBlameCommand(GitContext context)
{
super(context);

View File

@@ -42,6 +42,7 @@ import sonia.scm.repository.api.HookContext;
import sonia.scm.repository.api.HookContextFactory;
import sonia.scm.repository.api.HookFeature;
import javax.inject.Inject;
import java.io.IOException;
import java.util.List;
import java.util.Set;
@@ -56,6 +57,7 @@ public class GitBranchCommand extends AbstractGitCommand implements BranchComman
private final HookContextFactory hookContextFactory;
private final ScmEventBus eventBus;
@Inject
GitBranchCommand(GitContext context, HookContextFactory hookContextFactory, ScmEventBus eventBus) {
super(context);
this.hookContextFactory = hookContextFactory;

View File

@@ -38,6 +38,7 @@ import sonia.scm.repository.Branch;
import sonia.scm.repository.GitUtil;
import sonia.scm.repository.InternalRepositoryException;
import javax.inject.Inject;
import java.io.IOException;
import java.util.List;
import java.util.Optional;
@@ -53,6 +54,7 @@ public class GitBranchesCommand extends AbstractGitCommand implements BranchesCo
private static final Logger LOG = LoggerFactory.getLogger(GitBranchesCommand.class);
@Inject
public GitBranchesCommand(GitContext context)
{
super(context);

View File

@@ -57,6 +57,7 @@ import sonia.scm.store.BlobStore;
import sonia.scm.util.Util;
import sonia.scm.web.lfs.LfsBlobStoreFactory;
import javax.inject.Inject;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
@@ -111,6 +112,11 @@ public class GitBrowseCommand extends AbstractGitCommand
private int resultCount = 0;
@Inject
public GitBrowseCommand(GitContext context, LfsBlobStoreFactory lfsBlobStoreFactory, SyncAsyncExecutorProvider executorProvider) {
this(context, lfsBlobStoreFactory, executorProvider.createExecutorWithDefaultTimeout());
}
public GitBrowseCommand(GitContext context, LfsBlobStoreFactory lfsBlobStoreFactory, SyncAsyncExecutor executor) {
super(context);
this.lfsBlobStoreFactory = lfsBlobStoreFactory;

View File

@@ -44,6 +44,7 @@ import sonia.scm.util.IOUtil;
import sonia.scm.util.Util;
import sonia.scm.web.lfs.LfsBlobStoreFactory;
import javax.inject.Inject;
import java.io.Closeable;
import java.io.FilterInputStream;
import java.io.IOException;
@@ -61,6 +62,7 @@ public class GitCatCommand extends AbstractGitCommand implements CatCommand {
private final LfsBlobStoreFactory lfsBlobStoreFactory;
@Inject
public GitCatCommand(GitContext context, LfsBlobStoreFactory lfsBlobStoreFactory) {
super(context);
this.lfsBlobStoreFactory = lfsBlobStoreFactory;

View File

@@ -0,0 +1,48 @@
/*
* MIT License
*
* Copyright (c) 2020-present Cloudogu GmbH and Contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package sonia.scm.repository.spi;
import sonia.scm.api.v2.resources.GitRepositoryConfigStoreProvider;
import sonia.scm.repository.GitRepositoryHandler;
import sonia.scm.repository.Repository;
import javax.inject.Inject;
class GitContextFactory {
private final GitRepositoryHandler handler;
private final GitRepositoryConfigStoreProvider storeProvider;
@Inject
GitContextFactory(GitRepositoryHandler handler, GitRepositoryConfigStoreProvider storeProvider) {
this.handler = handler;
this.storeProvider = storeProvider;
}
GitContext create(Repository repository) {
return new GitContext(handler.getDirectory(repository.getId()), repository, storeProvider);
}
}

View File

@@ -29,6 +29,7 @@ import org.eclipse.jgit.diff.DiffFormatter;
import org.eclipse.jgit.util.QuotedString;
import sonia.scm.repository.api.DiffCommandBuilder;
import javax.inject.Inject;
import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
@@ -41,6 +42,7 @@ import static java.nio.charset.StandardCharsets.UTF_8;
*/
public class GitDiffCommand extends AbstractGitCommand implements DiffCommand {
@Inject
GitDiffCommand(GitContext context) {
super(context);
}

View File

@@ -32,6 +32,7 @@ import sonia.scm.repository.api.DiffFile;
import sonia.scm.repository.api.DiffResult;
import sonia.scm.repository.api.Hunk;
import javax.inject.Inject;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Iterator;
@@ -39,6 +40,7 @@ import java.util.stream.Collectors;
public class GitDiffResultCommand extends AbstractGitCommand implements DiffResultCommand {
@Inject
GitDiffResultCommand(GitContext context) {
super(context);
}

View File

@@ -31,6 +31,7 @@ import org.eclipse.jgit.lib.ObjectId;
import sonia.scm.repository.ChangesetPagingResult;
import sonia.scm.repository.GitRepositoryHandler;
import javax.inject.Inject;
import java.io.IOException;
//~--- JDK imports ------------------------------------------------------------
@@ -49,6 +50,7 @@ public class GitIncomingCommand extends AbstractGitIncomingOutgoingCommand
* @param handler
* @param context
*/
@Inject
GitIncomingCommand(GitRepositoryHandler handler, GitContext context)
{
super(handler, context);

View File

@@ -47,6 +47,7 @@ import sonia.scm.repository.GitUtil;
import sonia.scm.repository.InternalRepositoryException;
import sonia.scm.util.IOUtil;
import javax.inject.Inject;
import java.io.IOException;
import java.util.Collections;
import java.util.Iterator;
@@ -80,6 +81,7 @@ public class GitLogCommand extends AbstractGitCommand implements LogCommand
* @param context
*
*/
@Inject
GitLogCommand(GitContext context)
{
super(context);

View File

@@ -36,6 +36,7 @@ import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.merge.ResolveMerger;
import org.eclipse.jgit.treewalk.CanonicalTreeParser;
import org.eclipse.jgit.treewalk.filter.PathFilter;
import sonia.scm.repository.GitRepositoryHandler;
import sonia.scm.repository.GitWorkingCopyFactory;
import sonia.scm.repository.InternalRepositoryException;
import sonia.scm.repository.api.MergeCommandResult;
@@ -43,6 +44,7 @@ import sonia.scm.repository.api.MergeDryRunCommandResult;
import sonia.scm.repository.api.MergeStrategy;
import sonia.scm.repository.api.MergeStrategyNotSupportedException;
import javax.inject.Inject;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Set;
@@ -61,6 +63,11 @@ public class GitMergeCommand extends AbstractGitCommand implements MergeCommand
MergeStrategy.SQUASH
);
@Inject
GitMergeCommand(GitContext context, GitRepositoryHandler handler) {
this(context, handler.getWorkingCopyFactory());
}
GitMergeCommand(GitContext context, GitWorkingCopyFactory workingCopyFactory) {
super(context);
this.workingCopyFactory = workingCopyFactory;

View File

@@ -41,6 +41,7 @@ import sonia.scm.repository.Modified;
import sonia.scm.repository.Removed;
import sonia.scm.repository.Renamed;
import javax.inject.Inject;
import java.io.IOException;
import java.text.MessageFormat;
import java.util.ArrayList;
@@ -53,7 +54,8 @@ import static sonia.scm.ContextEntry.ContextBuilder.entity;
@Slf4j
public class GitModificationsCommand extends AbstractGitCommand implements ModificationsCommand {
protected GitModificationsCommand(GitContext context) {
@Inject
GitModificationsCommand(GitContext context) {
super(context);
}

View File

@@ -34,11 +34,13 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import sonia.scm.ConcurrentModificationException;
import sonia.scm.NoChangesMadeException;
import sonia.scm.repository.GitRepositoryHandler;
import sonia.scm.repository.GitWorkingCopyFactory;
import sonia.scm.repository.InternalRepositoryException;
import sonia.scm.repository.Repository;
import sonia.scm.web.lfs.LfsBlobStoreFactory;
import javax.inject.Inject;
import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
@@ -53,6 +55,11 @@ public class GitModifyCommand extends AbstractGitCommand implements ModifyComman
private final GitWorkingCopyFactory workingCopyFactory;
private final LfsBlobStoreFactory lfsBlobStoreFactory;
@Inject
GitModifyCommand(GitContext context, GitRepositoryHandler repositoryHandler, LfsBlobStoreFactory lfsBlobStoreFactory) {
this(context, repositoryHandler.getWorkingCopyFactory(), lfsBlobStoreFactory);
}
GitModifyCommand(GitContext context, GitWorkingCopyFactory workingCopyFactory, LfsBlobStoreFactory lfsBlobStoreFactory) {
super(context);
this.workingCopyFactory = workingCopyFactory;

View File

@@ -31,6 +31,7 @@ import org.eclipse.jgit.lib.ObjectId;
import sonia.scm.repository.ChangesetPagingResult;
import sonia.scm.repository.GitRepositoryHandler;
import javax.inject.Inject;
import java.io.IOException;
//~--- JDK imports ------------------------------------------------------------
@@ -49,6 +50,7 @@ public class GitOutgoingCommand extends AbstractGitIncomingOutgoingCommand
* @param handler
* @param context
*/
@Inject
GitOutgoingCommand(GitRepositoryHandler handler, GitContext context)
{
super(handler, context);

View File

@@ -44,6 +44,7 @@ import sonia.scm.repository.InternalRepositoryException;
import sonia.scm.repository.Repository;
import sonia.scm.repository.api.PullResponse;
import javax.inject.Inject;
import java.io.File;
import java.io.IOException;
import java.net.URL;
@@ -73,6 +74,7 @@ public class GitPullCommand extends AbstractGitPushOrPullCommand
* @param handler
* @param context
*/
@Inject
public GitPullCommand(GitRepositoryHandler handler, GitContext context)
{
super(handler, context);

View File

@@ -31,6 +31,7 @@ import org.slf4j.LoggerFactory;
import sonia.scm.repository.GitRepositoryHandler;
import sonia.scm.repository.api.PushResponse;
import javax.inject.Inject;
import java.io.IOException;
//~--- JDK imports ------------------------------------------------------------
@@ -55,8 +56,8 @@ public class GitPushCommand extends AbstractGitPushOrPullCommand
* @param handler
* @param context
*/
public GitPushCommand(GitRepositoryHandler handler, GitContext context)
{
@Inject
public GitPushCommand(GitRepositoryHandler handler, GitContext context) {
super(handler, context);
this.handler = handler;
}

View File

@@ -25,21 +25,14 @@
package sonia.scm.repository.spi;
import com.google.common.collect.ImmutableSet;
import sonia.scm.api.v2.resources.GitRepositoryConfigStoreProvider;
import sonia.scm.event.ScmEventBus;
import com.google.inject.AbstractModule;
import com.google.inject.Injector;
import sonia.scm.repository.Feature;
import sonia.scm.repository.GitRepositoryHandler;
import sonia.scm.repository.Repository;
import sonia.scm.repository.api.Command;
import sonia.scm.repository.api.HookContextFactory;
import sonia.scm.web.lfs.LfsBlobStoreFactory;
import java.io.IOException;
import java.util.EnumSet;
import java.util.Set;
//~--- JDK imports ------------------------------------------------------------
/**
*
* @author Sebastian Sdorra
@@ -47,8 +40,6 @@ import java.util.Set;
public class GitRepositoryServiceProvider extends RepositoryServiceProvider
{
/** Field description */
//J-
public static final Set<Command> COMMANDS = ImmutableSet.of(
Command.BLAME,
Command.BROWSE,
@@ -66,105 +57,51 @@ public class GitRepositoryServiceProvider extends RepositoryServiceProvider
Command.MERGE,
Command.MODIFY
);
protected static final Set<Feature> FEATURES = EnumSet.of(Feature.INCOMING_REVISION);
//J+
private final GitContext context;
private final Injector commandInjector;
//~--- constructors ---------------------------------------------------------
public GitRepositoryServiceProvider(GitRepositoryHandler handler, Repository repository, GitRepositoryConfigStoreProvider storeProvider, LfsBlobStoreFactory lfsBlobStoreFactory, HookContextFactory hookContextFactory, ScmEventBus eventBus, SyncAsyncExecutorProvider executorProvider) {
this.handler = handler;
this.lfsBlobStoreFactory = lfsBlobStoreFactory;
this.hookContextFactory = hookContextFactory;
this.eventBus = eventBus;
this.executorProvider = executorProvider;
this.context = new GitContext(handler.getDirectory(repository.getId()), repository, storeProvider);
GitRepositoryServiceProvider(Injector injector, GitContext context) {
this.context = context;
commandInjector = injector.createChildInjector(new AbstractModule() {
@Override
protected void configure() {
bind(GitContext.class).toInstance(context);
}
});
}
//~--- methods --------------------------------------------------------------
/**
* Method description
*
*
* @throws IOException
*/
@Override
public void close() throws IOException
{
context.close();
}
//~--- get methods ----------------------------------------------------------
/**
* Method description
*
*
* @return
*/
@Override
public BlameCommand getBlameCommand()
{
public BlameCommand getBlameCommand() {
return new GitBlameCommand(context);
}
/**
* Method description
*
*
* @return
*/
@Override
public BranchesCommand getBranchesCommand()
{
public BranchesCommand getBranchesCommand() {
return new GitBranchesCommand(context);
}
/**
* Method description
*
*
* @return
*/
@Override
public BranchCommand getBranchCommand()
{
return new GitBranchCommand(context, hookContextFactory, eventBus);
public BranchCommand getBranchCommand() {
return commandInjector.getInstance(GitBranchCommand.class);
}
/**
* Method description
*
*
* @return
*/
@Override
public BrowseCommand getBrowseCommand()
{
return new GitBrowseCommand(context, lfsBlobStoreFactory, executorProvider.createExecutorWithDefaultTimeout());
public BrowseCommand getBrowseCommand() {
return commandInjector.getInstance(GitBrowseCommand.class);
}
/**
* Method description
*
*
* @return
*/
@Override
public CatCommand getCatCommand()
{
return new GitCatCommand(context, lfsBlobStoreFactory);
public CatCommand getCatCommand() {
return commandInjector.getInstance(GitCatCommand.class);
}
/**
* Method description
*
*
* @return
*/
@Override
public DiffCommand getDiffCommand()
{
public DiffCommand getDiffCommand() {
return new GitDiffCommand(context);
}
@@ -173,27 +110,13 @@ public class GitRepositoryServiceProvider extends RepositoryServiceProvider
return new GitDiffResultCommand(context);
}
/**
* Method description
*
*
* @return
*/
@Override
public IncomingCommand getIncomingCommand()
{
return new GitIncomingCommand(handler, context);
public IncomingCommand getIncomingCommand() {
return commandInjector.getInstance(GitIncomingCommand.class);
}
/**
* Method description
*
*
* @return
*/
@Override
public LogCommand getLogCommand()
{
public LogCommand getLogCommand() {
return new GitLogCommand(context);
}
@@ -202,93 +125,48 @@ public class GitRepositoryServiceProvider extends RepositoryServiceProvider
return new GitModificationsCommand(context);
}
/**
* Method description
*
*
* @return
*/
@Override
public OutgoingCommand getOutgoingCommand()
{
return new GitOutgoingCommand(handler, context);
public OutgoingCommand getOutgoingCommand() {
return commandInjector.getInstance(GitOutgoingCommand.class);
}
/**
* Method description
*
*
* @return
*/
@Override
public PullCommand getPullCommand()
{
return new GitPullCommand(handler, context);
public PullCommand getPullCommand() {
return commandInjector.getInstance(GitPullCommand.class);
}
/**
* Method description
*
*
* @return
*/
@Override
public PushCommand getPushCommand()
{
return new GitPushCommand(handler, context);
public PushCommand getPushCommand() {
return commandInjector.getInstance(GitPushCommand.class);
}
/**
* Method description
*
*
* @return
*/
@Override
public Set<Command> getSupportedCommands()
{
return COMMANDS;
}
/**
* Method description
*
*
* @return
*/
@Override
public TagsCommand getTagsCommand()
{
public TagsCommand getTagsCommand() {
return new GitTagsCommand(context);
}
@Override
public MergeCommand getMergeCommand() {
return new GitMergeCommand(context, handler.getWorkingCopyFactory());
return commandInjector.getInstance(GitMergeCommand.class);
}
@Override
public ModifyCommand getModifyCommand() {
return new GitModifyCommand(context, handler.getWorkingCopyFactory(), lfsBlobStoreFactory);
return commandInjector.getInstance(GitModifyCommand.class);
}
@Override
public Set<Command> getSupportedCommands() {
return COMMANDS;
}
@Override
public Set<Feature> getSupportedFeatures() {
return FEATURES;
}
//~--- fields ---------------------------------------------------------------
/** Field description */
private final GitContext context;
/** Field description */
private final GitRepositoryHandler handler;
private final LfsBlobStoreFactory lfsBlobStoreFactory;
private final HookContextFactory hookContextFactory;
private final ScmEventBus eventBus;
private final SyncAsyncExecutorProvider executorProvider;
@Override
public void close() {
context.close();
}
}

View File

@@ -21,19 +21,16 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package sonia.scm.repository.spi;
//~--- non-JDK imports --------------------------------------------------------
import com.google.inject.Inject;
import sonia.scm.api.v2.resources.GitRepositoryConfigStoreProvider;
import sonia.scm.event.ScmEventBus;
import com.google.inject.Injector;
import sonia.scm.plugin.Extension;
import sonia.scm.repository.GitRepositoryHandler;
import sonia.scm.repository.Repository;
import sonia.scm.repository.api.HookContextFactory;
import sonia.scm.web.lfs.LfsBlobStoreFactory;
/**
*
@@ -42,31 +39,20 @@ import sonia.scm.web.lfs.LfsBlobStoreFactory;
@Extension
public class GitRepositoryServiceResolver implements RepositoryServiceResolver {
private final GitRepositoryHandler handler;
private final GitRepositoryConfigStoreProvider storeProvider;
private final LfsBlobStoreFactory lfsBlobStoreFactory;
private final HookContextFactory hookContextFactory;
private final ScmEventBus eventBus;
private final SyncAsyncExecutorProvider executorProvider;
private final Injector injector;
private final GitContextFactory contextFactory;
@Inject
public GitRepositoryServiceResolver(GitRepositoryHandler handler, GitRepositoryConfigStoreProvider storeProvider, LfsBlobStoreFactory lfsBlobStoreFactory, HookContextFactory hookContextFactory, ScmEventBus eventBus, SyncAsyncExecutorProvider executorProvider) {
this.handler = handler;
this.storeProvider = storeProvider;
this.lfsBlobStoreFactory = lfsBlobStoreFactory;
this.hookContextFactory = hookContextFactory;
this.eventBus = eventBus;
this.executorProvider = executorProvider;
public GitRepositoryServiceResolver(Injector injector, GitContextFactory contextFactory) {
this.injector = injector;
this.contextFactory = contextFactory;
}
@Override
public GitRepositoryServiceProvider resolve(Repository repository) {
GitRepositoryServiceProvider provider = null;
if (GitRepositoryHandler.TYPE_NAME.equalsIgnoreCase(repository.getType())) {
provider = new GitRepositoryServiceProvider(handler, repository, storeProvider, lfsBlobStoreFactory, hookContextFactory, eventBus, executorProvider);
return new GitRepositoryServiceProvider(injector, contextFactory.create(repository));
}
return provider;
return null;
}
}