From 992188ae4188b1833ae2ea9c15149115a39aa39b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Pfeuffer?= Date: Thu, 31 May 2018 10:32:51 +0200 Subject: [PATCH] Use guava immutable collection --- .../scm/api/rest/resources/LinkBuilder.java | 99 +++++++++++-------- 1 file changed, 60 insertions(+), 39 deletions(-) diff --git a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/LinkBuilder.java b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/LinkBuilder.java index 4007952227..721838da08 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/LinkBuilder.java +++ b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/LinkBuilder.java @@ -1,29 +1,43 @@ package sonia.scm.api.rest.resources; +import com.google.common.collect.ImmutableList; + import javax.ws.rs.core.UriBuilder; import javax.ws.rs.core.UriInfo; import java.net.URI; -import java.util.ArrayList; import java.util.Arrays; -import java.util.Collections; -import java.util.List; +/** + * This class is used to create links for JAX-RS resources. Create a new instance specifying all resource classes used + * to process the request. Than for each of these classes call builder.method(...).parameters(...) for each + * of these classes consecutively. The builder itself is immutable, so that each instance is reusable and you get a new + * builder for each method. + * + *
+ * LinkBuilder builder = new LinkBuilder(uriInfo, MainResource.class, SubResource.class);
+ * Link link = builder
+ *     .method("sub")
+ *     .parameters("param")
+ *     .method("x")
+ *     .parameters("param_1", "param_2")
+ *     .create();
+ * 
+ */ class LinkBuilder { private final UriInfo uriInfo; private final Class[] classes; - private final List calls; + private final ImmutableList calls; LinkBuilder(UriInfo uriInfo, Class... classes) { - this(uriInfo, classes, Collections.emptyList()); + this(uriInfo, classes, ImmutableList.of()); } - private LinkBuilder(UriInfo uriInfo, Class[] classes, List calls) { + private LinkBuilder(UriInfo uriInfo, Class[] classes, ImmutableList calls) { this.uriInfo = uriInfo; this.classes = classes; this.calls = calls; } - public Parameters method(String method) { if (calls.size() >= classes.length) { throw new IllegalStateException("no more classes for methods"); @@ -31,6 +45,44 @@ class LinkBuilder { return new Parameters(method); } + public Link create() { + if (calls.size() < classes.length) { + throw new IllegalStateException("not enough methods for all classes"); + } + + URI baseUri = uriInfo.getBaseUri(); + URI relativeUri = createRelativeUri(); + URI absoluteUri = baseUri.resolve(relativeUri); + return new Link(absoluteUri); + } + + private LinkBuilder add(String method, String[] parameters) { + return new LinkBuilder(uriInfo, classes, appendNewCall(method, parameters)); + } + + private ImmutableList appendNewCall(String method, String[] parameters) { + return ImmutableList. builder().addAll(calls).add(createNewCall(method, parameters)).build(); + } + + private Call createNewCall(String method, String[] parameters) { + return new Call(LinkBuilder.this.classes[calls.size()], method, parameters); + } + + private URI createRelativeUri() { + UriBuilder uriBuilder = userUriBuilder(); + calls.forEach(call -> uriBuilder.path(call.clazz, call.method)); + String[] concatenatedParameters = calls + .stream() + .map(call -> call.parameters) + .flatMap(Arrays::stream) + .toArray(String[]::new); + return uriBuilder.build((Object[]) concatenatedParameters); + } + + private UriBuilder userUriBuilder() { + return UriBuilder.fromResource(classes[0]); + } + class Parameters { private final String method; @@ -44,41 +96,10 @@ class LinkBuilder { } } - private LinkBuilder add(String method, String[] parameters) { - List newCalls = new ArrayList<>(this.calls); - newCalls.add(new Call(LinkBuilder.this.classes[calls.size()], method, parameters)); - return new LinkBuilder(uriInfo, classes, newCalls); - } - - public Link create() { - if (calls.size() < classes.length) { - throw new IllegalStateException("not enough methods for all classes"); - } - - URI baseUri = uriInfo.getBaseUri(); - URI relativeUri = createRelativeUri(); - URI absoluteUri = baseUri.resolve(relativeUri); - return new Link(absoluteUri); - } - - private URI createRelativeUri() { - UriBuilder uriBuilder = userUriBuilder(); - calls.forEach(call -> uriBuilder.path(call.clazz, call.method)); - String[] concatenatedParameters = calls - .stream() - .map(call -> call.parameters) - .flatMap(Arrays::stream) - .toArray(String[]::new); - return uriBuilder.build(concatenatedParameters); - } - - private UriBuilder userUriBuilder() { - return UriBuilder.fromResource(classes[0]); - } - private static class Call { private final Class clazz; private final String method; + private final String[] parameters; private Call(Class clazz, String method, String[] parameters) {