From 1ca6d2f5bc1136667c862d8433ccbbdb5a0c5cea Mon Sep 17 00:00:00 2001 From: chickenchickenlove Date: Tue, 30 Jul 2024 17:30:19 +0900 Subject: [PATCH] Support nested context paths. --- .../AbstractContextPathServicesBuilder.java | 47 ++++++++++++++++++- .../server/ContextPathServicesBuilder.java | 23 +++++++++ ...VirtualHostContextPathServicesBuilder.java | 19 ++++++++ 3 files changed, 88 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/com/linecorp/armeria/server/AbstractContextPathServicesBuilder.java b/core/src/main/java/com/linecorp/armeria/server/AbstractContextPathServicesBuilder.java index b61159cf6ed..fd8c360d8d8 100644 --- a/core/src/main/java/com/linecorp/armeria/server/AbstractContextPathServicesBuilder.java +++ b/core/src/main/java/com/linecorp/armeria/server/AbstractContextPathServicesBuilder.java @@ -20,12 +20,14 @@ import static com.linecorp.armeria.server.ServerBuilder.decorate; import static java.util.Objects.requireNonNull; +import java.util.HashSet; import java.util.Set; import java.util.function.Function; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; +import com.linecorp.armeria.common.annotation.Nullable; import com.linecorp.armeria.internal.server.RouteDecoratingService; import com.linecorp.armeria.internal.server.RouteUtil; import com.linecorp.armeria.internal.server.annotation.AnnotatedServiceExtensions; @@ -40,16 +42,33 @@ abstract class AbstractContextPathServicesBuilder contextPaths) { + this(parent, virtualHostBuilder, contextPaths, ImmutableSet.of(), null); + } + + AbstractContextPathServicesBuilder(T parent, + VirtualHostBuilder virtualHostBuilder, + Set contextPaths, + Set previousContextPaths, + @Nullable SELF previousNode) { checkArgument(!contextPaths.isEmpty(), "At least one context path is required"); for (String contextPath: contextPaths) { RouteUtil.ensureAbsolutePath(contextPath, "contextPath"); } + final Set mergedContextPaths = previousContextPaths.isEmpty() ? + contextPaths : + mergeContextPaths(previousContextPaths, contextPaths); + this.parent = parent; - this.contextPaths = ImmutableSet.copyOf(contextPaths); + this.contextPaths = ImmutableSet.copyOf(mergedContextPaths); this.virtualHostBuilder = virtualHostBuilder; + this.previousNode = previousNode; } @SuppressWarnings("unchecked") @@ -406,7 +425,33 @@ public T and() { return parent; } + public abstract SELF contextPath(String... contextPaths); + final Set contextPaths() { return contextPaths; } + + T parent() { + return parent; + } + + VirtualHostBuilder virtualHostBuilder() { + return virtualHostBuilder; + } + + @Nullable + public SELF before() { + return previousNode; + } + + private Set mergeContextPaths(Set previousContextPaths, Set contextPaths) { + final Set compositedPaths = new HashSet<>(); + for (String previousPath : previousContextPaths) { + for (String contextPath : contextPaths) { + compositedPaths.add(previousPath + contextPath); + } + } + return compositedPaths; + } + } diff --git a/core/src/main/java/com/linecorp/armeria/server/ContextPathServicesBuilder.java b/core/src/main/java/com/linecorp/armeria/server/ContextPathServicesBuilder.java index 607a8472660..0c88fbe4dbb 100644 --- a/core/src/main/java/com/linecorp/armeria/server/ContextPathServicesBuilder.java +++ b/core/src/main/java/com/linecorp/armeria/server/ContextPathServicesBuilder.java @@ -16,12 +16,17 @@ package com.linecorp.armeria.server; +import static com.google.common.base.Preconditions.checkArgument; import static java.util.Objects.requireNonNull; import java.util.Set; import java.util.function.Consumer; import java.util.function.Function; +import javax.naming.Context; + +import com.google.common.collect.ImmutableSet; + import com.linecorp.armeria.common.annotation.UnstableApi; import com.linecorp.armeria.server.annotation.ExceptionHandlerFunction; import com.linecorp.armeria.server.annotation.RequestConverterFunction; @@ -46,6 +51,24 @@ public final class ContextPathServicesBuilder super(parent, virtualHostBuilder, contextPaths); } + ContextPathServicesBuilder(ServerBuilder parent, + VirtualHostBuilder virtualHostBuilder, + Set contextPaths, + Set previousContextPaths, + ContextPathServicesBuilder contextPathServicesBuilder) { + super(parent, virtualHostBuilder, contextPaths, previousContextPaths, contextPathServicesBuilder); + } + + @Override + public ContextPathServicesBuilder contextPath(String... contextPaths) { + final ImmutableSet currentContextPaths = ImmutableSet.copyOf(requireNonNull(contextPaths, "contextPaths")); + return new ContextPathServicesBuilder(parent(), + virtualHostBuilder(), + currentContextPaths, + contextPaths(), + this); + } + /** * Configures an {@link HttpService} under the context path with the {@code customizer}. */ diff --git a/core/src/main/java/com/linecorp/armeria/server/VirtualHostContextPathServicesBuilder.java b/core/src/main/java/com/linecorp/armeria/server/VirtualHostContextPathServicesBuilder.java index 8763320042e..c894a368622 100644 --- a/core/src/main/java/com/linecorp/armeria/server/VirtualHostContextPathServicesBuilder.java +++ b/core/src/main/java/com/linecorp/armeria/server/VirtualHostContextPathServicesBuilder.java @@ -22,6 +22,8 @@ import java.util.function.Consumer; import java.util.function.Function; +import com.google.common.collect.ImmutableSet; + import com.linecorp.armeria.common.annotation.UnstableApi; import com.linecorp.armeria.server.annotation.ExceptionHandlerFunction; import com.linecorp.armeria.server.annotation.RequestConverterFunction; @@ -47,6 +49,23 @@ public final class VirtualHostContextPathServicesBuilder super(parent, virtualHostBuilder, contextPaths); } + VirtualHostContextPathServicesBuilder(VirtualHostBuilder parent, VirtualHostBuilder virtualHostBuilder, + Set contextPaths, + Set previousContextPaths, + VirtualHostContextPathServicesBuilder virtualHostContextPathServicesBuilder) { + super(parent, virtualHostBuilder, contextPaths, previousContextPaths, virtualHostContextPathServicesBuilder); + } + + @Override + public VirtualHostContextPathServicesBuilder contextPath(String... contextPaths) { + final ImmutableSet currentContextPaths = ImmutableSet.copyOf(requireNonNull(contextPaths, "contextPaths")); + return new VirtualHostContextPathServicesBuilder(parent(), + virtualHostBuilder(), + currentContextPaths, + contextPaths(), + this); + } + /** * Configures an {@link HttpService} under the context path with the {@code customizer}. */