From 617b98c6f30a03be3adf0acf094e40b45c377f18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Pfeuffer?= Date: Wed, 11 Jul 2018 13:42:09 +0200 Subject: [PATCH] Use optionals for get by name and namespace --- .../scm/repository/RepositoryManager.java | 6 ++-- .../resources/IdResourceManagerAdapter.java | 5 +-- .../api/v2/resources/RepositoryResource.java | 3 +- .../SingleResourceManagerAdapter.java | 32 ++++++++++--------- .../resources/RepositoryRootResourceTest.java | 7 +++- 5 files changed, 31 insertions(+), 22 deletions(-) diff --git a/scm-core/src/main/java/sonia/scm/repository/RepositoryManager.java b/scm-core/src/main/java/sonia/scm/repository/RepositoryManager.java index ca1d5ab743..0edd21f4c2 100644 --- a/scm-core/src/main/java/sonia/scm/repository/RepositoryManager.java +++ b/scm-core/src/main/java/sonia/scm/repository/RepositoryManager.java @@ -41,6 +41,7 @@ import sonia.scm.TypeManager; import javax.servlet.http.HttpServletRequest; import java.io.IOException; import java.util.Collection; +import java.util.Optional; //~--- JDK imports ------------------------------------------------------------ @@ -148,11 +149,10 @@ public interface RepositoryManager @Override public RepositoryHandler getHandler(String type); - default Repository getByNamespace(String namespace, String name) { + default Optional getByNamespace(String namespace, String name) { return getAll() .stream() .filter(r -> r.getName().equals(name) && r.getNamespace().equals(namespace)) - .findFirst() - .orElse(null); + .findFirst(); } } diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/IdResourceManagerAdapter.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/IdResourceManagerAdapter.java index be634a5fac..ded4bff309 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/IdResourceManagerAdapter.java +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/IdResourceManagerAdapter.java @@ -7,6 +7,7 @@ import sonia.scm.PageResult; import javax.ws.rs.core.Response; import java.io.IOException; +import java.util.Optional; import java.util.function.Function; import java.util.function.Predicate; import java.util.function.Supplier; @@ -55,8 +56,8 @@ class IdResourceManagerAdapter loadBy(String id) { - return () -> manager.get(id); + private Supplier> loadBy(String id) { + return () -> Optional.ofNullable(manager.get(id)); } private Predicate idStaysTheSame(String id) { diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/RepositoryResource.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/RepositoryResource.java index 1ff366cc0a..5972508c78 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/RepositoryResource.java +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/RepositoryResource.java @@ -18,6 +18,7 @@ import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.core.Response; +import java.util.Optional; import java.util.function.Predicate; import java.util.function.Supplier; @@ -153,7 +154,7 @@ public class RepositoryResource { return permissionRootResource.get(); } - private Supplier loadBy(String namespace, String name) { + private Supplier> loadBy(String namespace, String name) { return () -> manager.getByNamespace(namespace, name); } diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/SingleResourceManagerAdapter.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/SingleResourceManagerAdapter.java index 6cd12c9dd6..7f8b115dee 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/SingleResourceManagerAdapter.java +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/SingleResourceManagerAdapter.java @@ -8,6 +8,7 @@ import sonia.scm.api.rest.resources.AbstractManagerResource; import javax.ws.rs.core.GenericEntity; import javax.ws.rs.core.Response; import java.util.Collection; +import java.util.Optional; import java.util.function.Function; import java.util.function.Predicate; import java.util.function.Supplier; @@ -38,34 +39,35 @@ class SingleResourceManagerAdapter reader, Function mapToDto) { - MODEL_OBJECT modelObject = reader.get(); - if (modelObject == null) { - return Response.status(Response.Status.NOT_FOUND).build(); - } - DTO dto = mapToDto.apply(modelObject); - return Response.ok(dto).build(); + Response get(Supplier> reader, Function mapToDto) { + return reader.get() + .map(mapToDto) + .map(Response::ok) + .map(Response.ResponseBuilder::build) + .orElse(Response.status(Response.Status.NOT_FOUND).build()); } /** * Update the model object for the given id according to the given function and returns a corresponding http response. * This handles all corner cases, eg. no matching object for the id or missing privileges. */ - public Response update(Supplier reader, Function applyChanges, Predicate hasSameKey) { - MODEL_OBJECT existingModelObject = reader.get(); - if (existingModelObject == null) { + public Response update(Supplier> reader, Function applyChanges, Predicate hasSameKey) { + Optional existingModelObject = reader.get(); + if (!existingModelObject.isPresent()) { return Response.status(Response.Status.NOT_FOUND).build(); } - MODEL_OBJECT changedModelObject = applyChanges.apply(existingModelObject); + MODEL_OBJECT changedModelObject = applyChanges.apply(existingModelObject.get()); if (!hasSameKey.test(changedModelObject)) { return Response.status(BAD_REQUEST).entity("illegal change of id").build(); } - return update(getId(existingModelObject), changedModelObject); + return update(getId(existingModelObject.get()), changedModelObject); } - public Response delete(Supplier reader) { - MODEL_OBJECT existingModelObject = reader.get(); - return delete(existingModelObject.getId()); + public Response delete(Supplier> reader) { + return reader.get() + .map(MODEL_OBJECT::getId) + .map(this::delete) + .orElse(null); } @Override 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 c0fb0c0234..a0652708ce 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 @@ -25,6 +25,8 @@ import java.net.URISyntaxException; import java.net.URL; import static java.util.Collections.singletonList; +import static java.util.Optional.empty; +import static java.util.Optional.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; @@ -33,6 +35,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyObject; +import static org.mockito.Matchers.anyString; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; @@ -74,6 +77,7 @@ public class RepositoryRootResourceTest { @Test public void shouldFailForNotExistingRepository() throws URISyntaxException { + when(repositoryManager.getByNamespace(anyString(), anyString())).thenReturn(empty()); mockRepository("space", "repo"); MockHttpRequest request = MockHttpRequest.get("/" + RepositoryRootResource.REPOSITORIES_PATH_V2 + "space/other"); @@ -115,6 +119,7 @@ public class RepositoryRootResourceTest { public void shouldHandleUpdateForNotExistingRepository() throws URISyntaxException, IOException { URL url = Resources.getResource("sonia/scm/api/v2/repository-test-update.json"); byte[] repository = Resources.toByteArray(url); + when(repositoryManager.getByNamespace(anyString(), anyString())).thenReturn(empty()); MockHttpRequest request = MockHttpRequest .put("/" + RepositoryRootResource.REPOSITORIES_PATH_V2 + "space/repo") @@ -212,7 +217,7 @@ public class RepositoryRootResourceTest { repository.setName(name); String id = namespace + "-" + name; repository.setId(id); - when(repositoryManager.getByNamespace(namespace, name)).thenReturn(repository); + when(repositoryManager.getByNamespace(namespace, name)).thenReturn(of(repository)); when(repositoryManager.get(id)).thenReturn(repository); return repository; }