Encapsulate dependencies for repository resource

This commit is contained in:
René Pfeuffer
2020-06-11 14:56:18 +02:00
parent 01164a247d
commit 0b30c4f94b
13 changed files with 165 additions and 113 deletions

View File

@@ -0,0 +1,105 @@
/*
* 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.api.v2.resources;
import javax.inject.Inject;
import javax.inject.Provider;
public class RepositoryBasedResourceProvider {
private final Provider<TagRootResource> tagRootResource;
private final Provider<BranchRootResource> branchRootResource;
private final Provider<ChangesetRootResource> changesetRootResource;
private final Provider<SourceRootResource> sourceRootResource;
private final Provider<ContentResource> contentResource;
private final Provider<RepositoryPermissionRootResource> permissionRootResource;
private final Provider<DiffRootResource> diffRootResource;
private final Provider<ModificationsRootResource> modificationsRootResource;
private final Provider<FileHistoryRootResource> fileHistoryRootResource;
private final Provider<IncomingRootResource> incomingRootResource;
@Inject
public RepositoryBasedResourceProvider(
Provider<TagRootResource> tagRootResource,
Provider<BranchRootResource> branchRootResource,
Provider<ChangesetRootResource> changesetRootResource,
Provider<SourceRootResource> sourceRootResource,
Provider<ContentResource> contentResource,
Provider<RepositoryPermissionRootResource> permissionRootResource,
Provider<DiffRootResource> diffRootResource,
Provider<ModificationsRootResource> modificationsRootResource,
Provider<FileHistoryRootResource> fileHistoryRootResource,
Provider<IncomingRootResource> incomingRootResource) {
this.tagRootResource = tagRootResource;
this.branchRootResource = branchRootResource;
this.changesetRootResource = changesetRootResource;
this.sourceRootResource = sourceRootResource;
this.contentResource = contentResource;
this.permissionRootResource = permissionRootResource;
this.diffRootResource = diffRootResource;
this.modificationsRootResource = modificationsRootResource;
this.fileHistoryRootResource = fileHistoryRootResource;
this.incomingRootResource = incomingRootResource;
}
public TagRootResource getTagRootResource() {
return tagRootResource.get();
}
public BranchRootResource getBranchRootResource() {
return branchRootResource.get();
}
public ChangesetRootResource getChangesetRootResource() {
return changesetRootResource.get();
}
public SourceRootResource getSourceRootResource() {
return sourceRootResource.get();
}
public ContentResource getContentResource() {
return contentResource.get();
}
public RepositoryPermissionRootResource getPermissionRootResource() {
return permissionRootResource.get();
}
public DiffRootResource getDiffRootResource() {
return diffRootResource.get();
}
public ModificationsRootResource getModificationsRootResource() {
return modificationsRootResource.get();
}
public FileHistoryRootResource getFileHistoryRootResource() {
return fileHistoryRootResource.get();
}
public IncomingRootResource getIncomingRootResource() {
return incomingRootResource.get();
}
}

View File

@@ -21,7 +21,7 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package sonia.scm.api.v2.resources;
import io.swagger.v3.oas.annotations.Operation;
@@ -58,46 +58,19 @@ public class RepositoryResource {
private final RepositoryManager manager;
private final SingleResourceManagerAdapter<Repository, RepositoryDto> adapter;
private final Provider<TagRootResource> tagRootResource;
private final Provider<BranchRootResource> branchRootResource;
private final Provider<ChangesetRootResource> changesetRootResource;
private final Provider<SourceRootResource> sourceRootResource;
private final Provider<ContentResource> contentResource;
private final Provider<RepositoryPermissionRootResource> permissionRootResource;
private final Provider<DiffRootResource> diffRootResource;
private final Provider<ModificationsRootResource> modificationsRootResource;
private final Provider<FileHistoryRootResource> fileHistoryRootResource;
private final Provider<IncomingRootResource> incomingRootResource;
private final RepositoryBasedResourceProvider resourceProvider;
@Inject
public RepositoryResource(
RepositoryToRepositoryDtoMapper repositoryToDtoMapper,
RepositoryDtoToRepositoryMapper dtoToRepositoryMapper, RepositoryManager manager,
Provider<TagRootResource> tagRootResource,
Provider<BranchRootResource> branchRootResource,
Provider<ChangesetRootResource> changesetRootResource,
Provider<SourceRootResource> sourceRootResource, Provider<ContentResource> contentResource,
Provider<RepositoryPermissionRootResource> permissionRootResource,
Provider<DiffRootResource> diffRootResource,
Provider<ModificationsRootResource> modificationsRootResource,
Provider<FileHistoryRootResource> fileHistoryRootResource,
Provider<IncomingRootResource> incomingRootResource
RepositoryBasedResourceProvider resourceProvider
) {
this.dtoToRepositoryMapper = dtoToRepositoryMapper;
this.manager = manager;
this.repositoryToDtoMapper = repositoryToDtoMapper;
this.adapter = new SingleResourceManagerAdapter<>(manager, Repository.class);
this.tagRootResource = tagRootResource;
this.branchRootResource = branchRootResource;
this.changesetRootResource = changesetRootResource;
this.sourceRootResource = sourceRootResource;
this.contentResource = contentResource;
this.permissionRootResource = permissionRootResource;
this.diffRootResource = diffRootResource;
this.modificationsRootResource = modificationsRootResource;
this.fileHistoryRootResource = fileHistoryRootResource;
this.incomingRootResource = incomingRootResource;
this.resourceProvider = resourceProvider;
}
/**
@@ -211,52 +184,52 @@ public class RepositoryResource {
@Path("tags/")
public TagRootResource tags() {
return tagRootResource.get();
return resourceProvider.getTagRootResource();
}
@Path("diff/")
public DiffRootResource diff() {
return diffRootResource.get();
return resourceProvider.getDiffRootResource();
}
@Path("branches/")
public BranchRootResource branches() {
return branchRootResource.get();
return resourceProvider.getBranchRootResource();
}
@Path("changesets/")
public ChangesetRootResource changesets() {
return changesetRootResource.get();
return resourceProvider.getChangesetRootResource();
}
@Path("history/")
public FileHistoryRootResource history() {
return fileHistoryRootResource.get();
return resourceProvider.getFileHistoryRootResource();
}
@Path("sources/")
public SourceRootResource sources() {
return sourceRootResource.get();
return resourceProvider.getSourceRootResource();
}
@Path("content/")
public ContentResource content() {
return contentResource.get();
return resourceProvider.getContentResource();
}
@Path("permissions/")
public RepositoryPermissionRootResource permissions() {
return permissionRootResource.get();
return resourceProvider.getPermissionRootResource();
}
@Path("modifications/")
public ModificationsRootResource modifications() {
return modificationsRootResource.get();
return resourceProvider.getModificationsRootResource();
}
@Path("incoming/")
public IncomingRootResource incoming() {
return incomingRootResource.get();
return resourceProvider.getIncomingRootResource();
}
private Supplier<Repository> loadBy(String namespace, String name) {

View File

@@ -103,8 +103,6 @@ public class BranchRootResourceTest extends RepositoryTestBase {
private BranchChangesetCollectionToDtoMapper changesetCollectionToDtoMapper;
private BranchRootResource branchRootResource;
@Mock
private BranchCollectionToDtoMapper branchCollectionToDtoMapper;
@@ -126,7 +124,6 @@ public class BranchRootResourceTest extends RepositoryTestBase {
changesetCollectionToDtoMapper = new BranchChangesetCollectionToDtoMapper(changesetToChangesetDtoMapper, resourceLinks);
BranchCollectionToDtoMapper branchCollectionToDtoMapper = new BranchCollectionToDtoMapper(branchToDtoMapper, resourceLinks);
branchRootResource = new BranchRootResource(serviceFactory, branchToDtoMapper, branchCollectionToDtoMapper, changesetCollectionToDtoMapper, resourceLinks);
super.branchRootResource = Providers.of(branchRootResource);
dispatcher.addSingletonResource(getRepositoryRootResource());
when(serviceFactory.create(new NamespaceAndName("space", "repo"))).thenReturn(service);
when(serviceFactory.create(any(Repository.class))).thenReturn(service);

View File

@@ -91,8 +91,6 @@ public class ChangesetRootResourceTest extends RepositoryTestBase {
@InjectMocks
private DefaultChangesetToChangesetDtoMapperImpl changesetToChangesetDtoMapper;
private ChangesetRootResource changesetRootResource;
private final Subject subject = mock(Subject.class);
private final ThreadState subjectThreadState = new SubjectThreadState(subject);
@@ -100,7 +98,6 @@ public class ChangesetRootResourceTest extends RepositoryTestBase {
public void prepareEnvironment() {
changesetCollectionToDtoMapper = new ChangesetCollectionToDtoMapper(changesetToChangesetDtoMapper, resourceLinks);
changesetRootResource = new ChangesetRootResource(serviceFactory, changesetCollectionToDtoMapper, changesetToChangesetDtoMapper);
super.changesetRootResource = Providers.of(changesetRootResource);
dispatcher.addSingletonResource(getRepositoryRootResource());
when(serviceFactory.create(new NamespaceAndName("space", "repo"))).thenReturn(repositoryService);
when(serviceFactory.create(any(Repository.class))).thenReturn(repositoryService);

View File

@@ -21,7 +21,7 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package sonia.scm.api.v2.resources;
@@ -90,9 +90,6 @@ public class DiffResourceTest extends RepositoryTestBase {
@Mock
private DiffResultToDiffResultDtoMapper diffResultToDiffResultDtoMapper;
private DiffRootResource diffRootResource;
private final Subject subject = mock(Subject.class);
private final ThreadState subjectThreadState = new SubjectThreadState(subject);
@@ -100,7 +97,6 @@ public class DiffResourceTest extends RepositoryTestBase {
@Before
public void prepareEnvironment() {
diffRootResource = new DiffRootResource(serviceFactory, diffResultToDiffResultDtoMapper);
super.diffRootResource = Providers.of(diffRootResource);
dispatcher.addSingletonResource(getRepositoryRootResource());
when(serviceFactory.create(new NamespaceAndName("space", "repo"))).thenReturn(service);
when(serviceFactory.create(any(Repository.class))).thenReturn(service);

View File

@@ -92,8 +92,6 @@ public class FileHistoryResourceTest extends RepositoryTestBase {
@InjectMocks
private DefaultChangesetToChangesetDtoMapperImpl changesetToChangesetDtoMapper;
private FileHistoryRootResource fileHistoryRootResource;
private RestDispatcher dispatcher = new RestDispatcher();
private final Subject subject = mock(Subject.class);
@@ -103,7 +101,6 @@ public class FileHistoryResourceTest extends RepositoryTestBase {
public void prepareEnvironment() {
fileHistoryCollectionToDtoMapper = new FileHistoryCollectionToDtoMapper(changesetToChangesetDtoMapper, resourceLinks);
fileHistoryRootResource = new FileHistoryRootResource(serviceFactory, fileHistoryCollectionToDtoMapper);
super.fileHistoryRootResource = Providers.of(fileHistoryRootResource);
dispatcher.addSingletonResource(getRepositoryRootResource());
when(serviceFactory.create(new NamespaceAndName("space", "repo"))).thenReturn(service);
when(serviceFactory.create(any(Repository.class))).thenReturn(service);

View File

@@ -110,9 +110,6 @@ public class IncomingRootResourceTest extends RepositoryTestBase {
@InjectMocks
private DefaultChangesetToChangesetDtoMapperImpl changesetToChangesetDtoMapper;
private IncomingRootResource incomingRootResource;
private final Subject subject = mock(Subject.class);
private final ThreadState subjectThreadState = new SubjectThreadState(subject);
@@ -121,7 +118,6 @@ public class IncomingRootResourceTest extends RepositoryTestBase {
public void prepareEnvironment() {
incomingChangesetCollectionToDtoMapper = new IncomingChangesetCollectionToDtoMapper(changesetToChangesetDtoMapper, resourceLinks);
incomingRootResource = new IncomingRootResource(serviceFactory, incomingChangesetCollectionToDtoMapper, diffResultToDiffResultDtoMapper);
super.incomingRootResource = Providers.of(incomingRootResource);
dispatcher.addSingletonResource(getRepositoryRootResource());
when(serviceFactory.create(new NamespaceAndName("space", "repo"))).thenReturn(repositoryService);
when(serviceFactory.create(REPOSITORY)).thenReturn(repositoryService);

View File

@@ -88,9 +88,6 @@ public class ModificationsResourceTest extends RepositoryTestBase {
@InjectMocks
private ModificationsToDtoMapperImpl modificationsToDtoMapper;
private ModificationsRootResource modificationsRootResource;
private final Subject subject = mock(Subject.class);
private final ThreadState subjectThreadState = new SubjectThreadState(subject);
@@ -98,7 +95,6 @@ public class ModificationsResourceTest extends RepositoryTestBase {
@Before
public void prepareEnvironment() {
modificationsRootResource = new ModificationsRootResource(serviceFactory, modificationsToDtoMapper);
super.modificationsRootResource = Providers.of(modificationsRootResource);
dispatcher.addSingletonResource(getRepositoryRootResource());
when(serviceFactory.create(new NamespaceAndName("space", "repo"))).thenReturn(repositoryService);
when(serviceFactory.create(any(Repository.class))).thenReturn(repositoryService);

View File

@@ -21,7 +21,7 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package sonia.scm.api.v2.resources;
import com.fasterxml.jackson.databind.JsonNode;
@@ -144,8 +144,6 @@ public class RepositoryPermissionRootResourceTest extends RepositoryTestBase {
private RepositoryPermissionCollectionToDtoMapper repositoryPermissionCollectionToDtoMapper;
private RepositoryPermissionRootResource repositoryPermissionRootResource;
private final Subject subject = mock(Subject.class);
private final ThreadState subjectThreadState = new SubjectThreadState(subject);
@@ -154,8 +152,7 @@ public class RepositoryPermissionRootResourceTest extends RepositoryTestBase {
public void prepareEnvironment() {
initMocks(this);
repositoryPermissionCollectionToDtoMapper = new RepositoryPermissionCollectionToDtoMapper(permissionToPermissionDtoMapper, resourceLinks);
repositoryPermissionRootResource = new RepositoryPermissionRootResource(permissionDtoToPermissionMapper, permissionToPermissionDtoMapper, repositoryPermissionCollectionToDtoMapper, resourceLinks, repositoryManager);
super.permissionRootResource = Providers.of(repositoryPermissionRootResource);
permissionRootResource = new RepositoryPermissionRootResource(permissionDtoToPermissionMapper, permissionToPermissionDtoMapper, repositoryPermissionCollectionToDtoMapper, resourceLinks, repositoryManager);
dispatcher.addSingletonResource(getRepositoryRootResource());
subjectThreadState.bind();
ThreadContext.bind(subject);

View File

@@ -21,7 +21,7 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package sonia.scm.api.v2.resources;
import com.github.sdorra.shiro.ShiroRule;
@@ -122,7 +122,7 @@ public class RepositoryRootResourceTest extends RepositoryTestBase {
super.dtoToRepositoryMapper = dtoToRepositoryMapper;
super.manager = repositoryManager;
RepositoryCollectionToDtoMapper repositoryCollectionToDtoMapper = new RepositoryCollectionToDtoMapper(repositoryToDtoMapper, resourceLinks);
super.repositoryCollectionResource = Providers.of(new RepositoryCollectionResource(repositoryManager, repositoryCollectionToDtoMapper, dtoToRepositoryMapper, resourceLinks, repositoryInitializer));
super.repositoryCollectionResource = new RepositoryCollectionResource(repositoryManager, repositoryCollectionToDtoMapper, dtoToRepositoryMapper, resourceLinks, repositoryInitializer);
dispatcher.addSingletonResource(getRepositoryRootResource());
when(serviceFactory.create(any(Repository.class))).thenReturn(service);
when(scmPathInfoStore.get()).thenReturn(uriInfo);

View File

@@ -21,49 +21,52 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package sonia.scm.api.v2.resources;
import com.google.inject.util.Providers;
import sonia.scm.repository.RepositoryManager;
import javax.inject.Provider;
import static com.google.inject.util.Providers.of;
import static org.mockito.Mockito.mock;
public abstract class RepositoryTestBase {
abstract class RepositoryTestBase {
protected RepositoryToRepositoryDtoMapper repositoryToDtoMapper;
protected RepositoryDtoToRepositoryMapper dtoToRepositoryMapper;
protected RepositoryManager manager;
protected Provider<TagRootResource> tagRootResource;
protected Provider<BranchRootResource> branchRootResource;
protected Provider<ChangesetRootResource> changesetRootResource;
protected Provider<SourceRootResource> sourceRootResource;
protected Provider<ContentResource> contentResource;
protected Provider<RepositoryPermissionRootResource> permissionRootResource;
protected Provider<DiffRootResource> diffRootResource;
protected Provider<ModificationsRootResource> modificationsRootResource;
protected Provider<FileHistoryRootResource> fileHistoryRootResource;
protected Provider<RepositoryCollectionResource> repositoryCollectionResource;
protected Provider<IncomingRootResource> incomingRootResource;
RepositoryToRepositoryDtoMapper repositoryToDtoMapper;
RepositoryDtoToRepositoryMapper dtoToRepositoryMapper;
RepositoryManager manager;
TagRootResource tagRootResource;
BranchRootResource branchRootResource;
ChangesetRootResource changesetRootResource;
SourceRootResource sourceRootResource;
ContentResource contentResource;
RepositoryPermissionRootResource permissionRootResource;
DiffRootResource diffRootResource;
ModificationsRootResource modificationsRootResource;
FileHistoryRootResource fileHistoryRootResource;
IncomingRootResource incomingRootResource;
RepositoryCollectionResource repositoryCollectionResource;
RepositoryRootResource getRepositoryRootResource() {
return new RepositoryRootResource(Providers.of(new RepositoryResource(
repositoryToDtoMapper,
dtoToRepositoryMapper,
manager,
tagRootResource,
branchRootResource,
changesetRootResource,
sourceRootResource,
contentResource,
permissionRootResource,
diffRootResource,
modificationsRootResource,
fileHistoryRootResource,
incomingRootResource)), repositoryCollectionResource);
RepositoryBasedResourceProvider repositoryBasedResourceProvider = new RepositoryBasedResourceProvider(
of(tagRootResource),
of(branchRootResource),
of(changesetRootResource),
of(sourceRootResource),
of(contentResource),
of(permissionRootResource),
of(diffRootResource),
of(modificationsRootResource),
of(fileHistoryRootResource),
of(incomingRootResource)
);
return new RepositoryRootResource(
of(new RepositoryResource(
repositoryToDtoMapper,
dtoToRepositoryMapper,
manager,
repositoryBasedResourceProvider
)),
of(repositoryCollectionResource));
}
}

View File

@@ -21,7 +21,7 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package sonia.scm.api.v2.resources;
import com.google.inject.util.Providers;
@@ -74,8 +74,7 @@ public class SourceRootResourceTest extends RepositoryTestBase {
when(serviceFactory.create(new NamespaceAndName("space", "repo"))).thenReturn(service);
when(service.getBrowseCommand()).thenReturn(browseCommandBuilder);
SourceRootResource sourceRootResource = new SourceRootResource(serviceFactory, browserResultToFileObjectDtoMapper);
super.sourceRootResource = Providers.of(sourceRootResource);
sourceRootResource = new SourceRootResource(serviceFactory, browserResultToFileObjectDtoMapper);
dispatcher.addSingletonResource(getRepositoryRootResource());
}

View File

@@ -21,7 +21,7 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package sonia.scm.api.v2.resources;
import com.google.inject.util.Providers;
@@ -84,9 +84,6 @@ public class TagRootResourceTest extends RepositoryTestBase {
@InjectMocks
private TagToTagDtoMapperImpl tagToTagDtoMapper;
private TagRootResource tagRootResource;
private final Subject subject = mock(Subject.class);
private final ThreadState subjectThreadState = new SubjectThreadState(subject);
@@ -95,7 +92,6 @@ public class TagRootResourceTest extends RepositoryTestBase {
public void prepareEnvironment() throws Exception {
tagCollectionToDtoMapper = new TagCollectionToDtoMapper(resourceLinks, tagToTagDtoMapper);
tagRootResource = new TagRootResource(serviceFactory, tagCollectionToDtoMapper, tagToTagDtoMapper);
super.tagRootResource = Providers.of(tagRootResource);
dispatcher.addSingletonResource(getRepositoryRootResource());
when(serviceFactory.create(new NamespaceAndName("space", "repo"))).thenReturn(repositoryService);
when(serviceFactory.create(any(Repository.class))).thenReturn(repositoryService);