From cb49cfa0332c8001001e7ae0a0c28aa518d68b34 Mon Sep 17 00:00:00 2001 From: "kate.pham" Date: Fri, 17 Feb 2023 14:14:09 +0700 Subject: [PATCH 01/39] draft proposal for pathPatternBuilder methods endsWith, under, and of class --- .../centraldogma/common/PathPattern.java | 44 ++++++++++ .../common/PathPatternBuilder.java | 83 +++++++++++++++++++ 2 files changed, 127 insertions(+) create mode 100644 common/src/main/java/com/linecorp/centraldogma/common/PathPatternBuilder.java diff --git a/common/src/main/java/com/linecorp/centraldogma/common/PathPattern.java b/common/src/main/java/com/linecorp/centraldogma/common/PathPattern.java index 05752b0142..e42c1f6620 100644 --- a/common/src/main/java/com/linecorp/centraldogma/common/PathPattern.java +++ b/common/src/main/java/com/linecorp/centraldogma/common/PathPattern.java @@ -19,6 +19,9 @@ import static com.linecorp.centraldogma.common.DefaultPathPattern.allPattern; import static java.util.Objects.requireNonNull; +import java.util.Arrays; +import java.util.stream.Collectors; + import com.google.common.collect.ImmutableSet; import com.google.common.collect.Streams; @@ -36,6 +39,13 @@ */ public interface PathPattern { + /** + *Returns a newly created {@link PathPatternBuilder}. + */ + static PathPatternBuilder builder() { + return new PathPatternBuilder(); + } + /** * Returns the path pattern that represents all files. */ @@ -50,6 +60,16 @@ static PathPattern of(String... patterns) { return of(ImmutableSet.copyOf(requireNonNull(patterns, "patterns"))); } + /** + * Creates a path pattern with the {@code pathPatterns}. + */ + static PathPattern of(PathPattern... pathPatterns) { + requireNonNull(pathPatterns, "pathPatterns"); + return of(ImmutableSet.copyOf(Arrays.stream(pathPatterns) + .map(PathPattern::patternString) + .collect(Collectors.toList()))); + } + /** * Creates a path pattern with the {@code patterns}. */ @@ -62,6 +82,30 @@ static PathPattern of(Iterable patterns) { return new DefaultPathPattern(ImmutableSet.copyOf(patterns)); } + /** + * Returns the path pattern for matching file(s) ending in {@code pattern}. + */ + static PathPattern endsWith(String pattern) { + requireNonNull(pattern, "pattern"); + final int extSeparatorPos = pattern.lastIndexOf('.'); + if (extSeparatorPos > 0) { // filename + extension + return new DefaultPathPattern(ImmutableSet.of(pattern)); + } else if (extSeparatorPos == 0) { // extension with separator + return new DefaultPathPattern(ImmutableSet.of("/**/*" + pattern)); + } else { // extension without separator + return new DefaultPathPattern(ImmutableSet.of("/**/*." + pattern)); + } + } + + /** + * Returns the path pattern for file(s) under {@code dirPattern}. + */ + static PathPattern under(String dirPattern) { + requireNonNull(dirPattern, "dirPattern"); + return dirPattern.endsWith("/") ? new DefaultPathPattern(ImmutableSet.of(dirPattern + "**")) + : new DefaultPathPattern(ImmutableSet.of(dirPattern + "/**")); + } + /** * Returns the path pattern that concatenates the {@code patterns} using ','. */ diff --git a/common/src/main/java/com/linecorp/centraldogma/common/PathPatternBuilder.java b/common/src/main/java/com/linecorp/centraldogma/common/PathPatternBuilder.java new file mode 100644 index 0000000000..d12c8e5922 --- /dev/null +++ b/common/src/main/java/com/linecorp/centraldogma/common/PathPatternBuilder.java @@ -0,0 +1,83 @@ +/* + * Copyright 2023 LINE Corporation + * + * LINE Corporation licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package com.linecorp.centraldogma.common; + +import static com.google.common.base.Preconditions.checkArgument; +import static java.util.Objects.requireNonNull; + +import java.util.Collections; +import java.util.List; + +import com.google.common.collect.ImmutableSet; + +/** + * Builds a new {@link PathPattern}. + * + *

Example

+ *
{@code
+ * final PathPattern factory =
+ *         PathPattern.builder()
+ *                    .under("/foo/bar")
+ *                    .endsWith("json")
+ *                    .build();
+ * }
+ */ +public final class PathPatternBuilder { + + private List patternsList = Collections.emptyList(); + + /** + * Add {@link PathPattern#endsWith(String)} patternString. + */ + public PathPatternBuilder endsWith(String pattern) { + patternsList.add(PathPattern.endsWith(pattern).patternString()); + return this; + } + + /** + * Add {@link PathPattern#under(String)} patternString. + */ + public PathPatternBuilder under(String dirPattern) { + patternsList.add(PathPattern.under(dirPattern).patternString()); + return this; + } + + /** + * Returns combined under patternString and endsWith patternString. + */ + private static String combineUnderAndEndsWith(String under, String endsWith) { + checkArgument(!under.endsWith("/**"), "under patternString should end with \"/**\""); + checkArgument(!endsWith.startsWith("/**/"), "endsWith should start with \"/**/\""); + return under + endsWith.substring(2); + } + + /** + * Combine 2 patternStrings in {@code patternsList} into one path pattern. + */ + public PathPattern build() { + checkArgument(patternsList.size() >= 2, "Need 2 or more patternStrings to build in PathPatternBuilder"); + final String startsWithPattern = patternsList.stream() + .filter(pattern -> pattern.startsWith("/**/")) + .findAny() + .get(); + final String endsWithPattern = patternsList.stream() + .filter(pattern -> pattern.endsWith("/**")) + .findAny() + .get(); + return new DefaultPathPattern(ImmutableSet.of( + combineUnderAndEndsWith(requireNonNull(startsWithPattern), requireNonNull(endsWithPattern)))); + } +} From dd52fb4d27018d2afd2de8a3a54acd4fbb026262 Mon Sep 17 00:00:00 2001 From: "kate.pham" Date: Tue, 21 Feb 2023 12:39:21 +0700 Subject: [PATCH 02/39] add tests, add contains and extension option in PathPatternBuilder, rename under to startWith --- .../centraldogma/common/PathPattern.java | 37 +-- .../common/PathPatternBuilder.java | 238 ++++++++++++++++-- .../common/DefaultPathPatternTest.java | 5 + .../common/PathPatternBuilderTest.java | 43 ++++ 4 files changed, 281 insertions(+), 42 deletions(-) create mode 100644 common/src/test/java/com/linecorp/centraldogma/common/PathPatternBuilderTest.java diff --git a/common/src/main/java/com/linecorp/centraldogma/common/PathPattern.java b/common/src/main/java/com/linecorp/centraldogma/common/PathPattern.java index e42c1f6620..7df15ad252 100644 --- a/common/src/main/java/com/linecorp/centraldogma/common/PathPattern.java +++ b/common/src/main/java/com/linecorp/centraldogma/common/PathPattern.java @@ -83,27 +83,32 @@ static PathPattern of(Iterable patterns) { } /** - * Returns the path pattern for matching file(s) ending in {@code pattern}. + * Returns the path pattern for matching file(s) ending in {@code filename}. */ - static PathPattern endsWith(String pattern) { - requireNonNull(pattern, "pattern"); - final int extSeparatorPos = pattern.lastIndexOf('.'); - if (extSeparatorPos > 0) { // filename + extension - return new DefaultPathPattern(ImmutableSet.of(pattern)); - } else if (extSeparatorPos == 0) { // extension with separator - return new DefaultPathPattern(ImmutableSet.of("/**/*" + pattern)); - } else { // extension without separator - return new DefaultPathPattern(ImmutableSet.of("/**/*." + pattern)); - } + static PathPattern endsWith(String filename) { + return builder().endsWith(filename).build(); + } + + /** + * Returns the path pattern for file(s) that start with {@code dirPath}. + */ + static PathPattern startsWith(String dirPath) { + return builder().startsWith(dirPath).build(); + } + + + /** + * Returns the path pattern for file(s) that contains {@code dirPath}. + */ + static PathPattern contains(String dirPath) { + return builder().contains(dirPath).build(); } /** - * Returns the path pattern for file(s) under {@code dirPattern}. + * Returns the path pattern for file(s) with {@code extension}. */ - static PathPattern under(String dirPattern) { - requireNonNull(dirPattern, "dirPattern"); - return dirPattern.endsWith("/") ? new DefaultPathPattern(ImmutableSet.of(dirPattern + "**")) - : new DefaultPathPattern(ImmutableSet.of(dirPattern + "/**")); + static PathPattern extension(String extension) { + return builder().extension(extension).build(); } /** diff --git a/common/src/main/java/com/linecorp/centraldogma/common/PathPatternBuilder.java b/common/src/main/java/com/linecorp/centraldogma/common/PathPatternBuilder.java index d12c8e5922..a03dc90572 100644 --- a/common/src/main/java/com/linecorp/centraldogma/common/PathPatternBuilder.java +++ b/common/src/main/java/com/linecorp/centraldogma/common/PathPatternBuilder.java @@ -16,13 +16,19 @@ package com.linecorp.centraldogma.common; import static com.google.common.base.Preconditions.checkArgument; -import static java.util.Objects.requireNonNull; -import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; +import java.util.regex.Pattern; +import java.util.stream.Collectors; import com.google.common.collect.ImmutableSet; +import com.linecorp.centraldogma.internal.Util; + /** * Builds a new {@link PathPattern}. * @@ -37,47 +43,227 @@ */ public final class PathPatternBuilder { - private List patternsList = Collections.emptyList(); + private static final Pattern FILE_EXTENSION_PATTERN = Pattern.compile("^.{0,1}[0-9a-z]+$"); + + /** + * A {@link PathPatternBuilder} option. + */ + public enum Option { + /** + * Enum for {@link PathPatternBuilder#startsWith(String)}. + */ + STARTS_WITH(1, 1), + /** + * Enum for {@link PathPatternBuilder#contains(String)}. + */ + CONTAINS(2, 1), + /** + * Enum for {@link PathPatternBuilder#endsWith(String)}. + */ + ENDS_WITH(3, 1), + /** + * Enum for {@link PathPatternBuilder#extension(String)}. + */ + EXTENSION(3, 1); + + /** + * Determines the relative ordering of the group. + * + */ + private final int group; + + /** + * Precedence is the priority of an option + * relative to others in the same {@link PathPatternBuilder.Option#group()}. + * Precedence level (n+1) has a higher precedence than level (n). + */ + private final int precedence; + + Option(int group, int precedence) { + this.group = group; + this.precedence = precedence; + } + + /** + * Returns the group order of the option. + */ + public int group() { + return group; + } + + /** + * Returns the group precedence level of the option. + */ + public int precedence() { + return precedence; + } + } + + private final class EnrichedPathPattern { + private final Option option; + private final PathPattern pathPattern; + + /** + * Creates a new instance. + * + * @param option the option of the enrichedPathPattern + * @param pathPattern the pathPattern of the enrichedPathPattern + */ + private EnrichedPathPattern(Option option, PathPattern pathPattern) { + this.option = option; + this.pathPattern = pathPattern; + } + + /** + * Returns the option of this {@link EnrichedPathPattern}. + */ + public Option getOption() { + return option; + } + + /** + * Returns the pathPattern of this {@link EnrichedPathPattern}. + */ + public PathPattern getPathPattern() { + return pathPattern; + } + } + + private final Map patterns = new LinkedHashMap<>(); + + /** + * Prepends "/**/" to {@code filename}. + * Returns the path pattern for matching file(s) ending in {@code filename}. + */ + private static PathPattern endsWithPathPattern(String filename) { + checkArgument(Util.isValidFileName(filename), "filename"); + return new DefaultPathPattern(ImmutableSet.of(filename)); + } /** - * Add {@link PathPattern#endsWith(String)} patternString. + * Adds {@link #endsWithPathPattern(String)}. */ - public PathPatternBuilder endsWith(String pattern) { - patternsList.add(PathPattern.endsWith(pattern).patternString()); + public PathPatternBuilder endsWith(String filename) { + patterns.put(Option.ENDS_WITH, + new EnrichedPathPattern(Option.ENDS_WITH, endsWithPathPattern(filename))); return this; } /** - * Add {@link PathPattern#under(String)} patternString. + * Prepends "/**/*" to {@code extension}. + * Returns the path pattern for matching file(s) ending in {@code extension}. */ - public PathPatternBuilder under(String dirPattern) { - patternsList.add(PathPattern.under(dirPattern).patternString()); + private static PathPattern extensionPathPattern(String extension) { + checkArgument(isValidFileExtension(extension), "extension"); + if (extension.startsWith(".")) { + return new DefaultPathPattern(ImmutableSet.of("/**/*" + extension)); + } else { // need to add extension separator + return new DefaultPathPattern(ImmutableSet.of("/**/*." + extension)); + } + } + + /** + * Adds {@link #extensionPathPattern(String)}. + */ + public PathPatternBuilder extension(String extension) { + patterns.put(Option.EXTENSION, + new EnrichedPathPattern(Option.EXTENSION, extensionPathPattern(extension))); return this; } /** - * Returns combined under patternString and endsWith patternString. + * Appends "/**" to {@code dirPath}. + * Returns the path pattern for matching all file(s) under {@code dirPath}. */ - private static String combineUnderAndEndsWith(String under, String endsWith) { - checkArgument(!under.endsWith("/**"), "under patternString should end with \"/**\""); - checkArgument(!endsWith.startsWith("/**/"), "endsWith should start with \"/**/\""); - return under + endsWith.substring(2); + private static PathPattern startsWithPathPattern(String dirPath) { + checkArgument(Util.isValidDirPath(dirPath), "dir"); + return dirPath.endsWith("/") ? new DefaultPathPattern(ImmutableSet.of(dirPath + "**")) + : new DefaultPathPattern(ImmutableSet.of(dirPath + "/**")); } /** - * Combine 2 patternStrings in {@code patternsList} into one path pattern. + * Adds {@link #startsWithPathPattern(String)}}. + */ + public PathPatternBuilder startsWith(String dirPath) { + patterns.put(Option.STARTS_WITH, + new EnrichedPathPattern(Option.STARTS_WITH, startsWithPathPattern(dirPath))); + return this; + } + + /** + * Prepends and appends "/**" to target {@code dirPath}. + * Returns the path pattern for matching all file(s) containing {@code dirPath}. + */ + private static PathPattern containsPathPattern(String dirPath) { + checkArgument(Util.isValidDirPath(dirPath), "dirPath"); + return dirPath.endsWith("/") ? new DefaultPathPattern(ImmutableSet.of("/**" + dirPath + "**")) + : new DefaultPathPattern(ImmutableSet.of("/**" + dirPath + "/**")); + } + + /** + * Adds {@link #containsPathPattern(String)}}. + */ + public PathPatternBuilder contains(String dirPath) { + patterns.put(Option.CONTAINS, + new EnrichedPathPattern(Option.CONTAINS, containsPathPattern(dirPath))); + return this; + } + + + /** + * Returns combined startsWith pathPatternString and endsWith pathPatternString. + */ + private static String combinePatterns(String left, String right) { + checkArgument(left.endsWith("/**"), "left should end with \"/**\""); + checkArgument(right.startsWith("/**/"), "right should start with \"/**/\""); + return left + right.substring(3); + } + + /** + * Compose one pathPattern from a list of {@code patterns}. + */ + private static String combine(Iterable patterns) { + final Iterator iter = patterns.iterator(); + String combinedPattern = iter.next().patternString(); + while (iter.hasNext()) { + combinedPattern = combinePatterns(combinedPattern, iter.next().patternString()); + } + return combinedPattern; + } + + /** + * Returns a newly-created {@link PathPattern} based on the options of this builder. */ public PathPattern build() { - checkArgument(patternsList.size() >= 2, "Need 2 or more patternStrings to build in PathPatternBuilder"); - final String startsWithPattern = patternsList.stream() - .filter(pattern -> pattern.startsWith("/**/")) - .findAny() - .get(); - final String endsWithPattern = patternsList.stream() - .filter(pattern -> pattern.endsWith("/**")) - .findAny() - .get(); - return new DefaultPathPattern(ImmutableSet.of( - combineUnderAndEndsWith(requireNonNull(startsWithPattern), requireNonNull(endsWithPattern)))); + checkArgument(!patterns.isEmpty(), "Requires at least one pattern to build in PathPatternBuilder"); + + if (patterns.size() == 1) { + return patterns.entrySet().iterator().next().getValue().getPathPattern(); + } + + final Map patternsGrouped = new HashMap<>(); + for (Map.Entry entry : patterns.entrySet()) { + final Option option = entry.getKey(); + final int optionGroup = option.group(); + final int optionPrecedence = option.precedence(); + if (patternsGrouped.containsKey(optionGroup) && + optionPrecedence > patternsGrouped.get(optionGroup).getOption().precedence) { + patternsGrouped.put(optionGroup, entry.getValue()); + } else { + patternsGrouped.put(optionGroup, entry.getValue()); + } + } + final List collect = patternsGrouped.entrySet() + .stream() + .sorted(Map.Entry.comparingByKey()) + .map(Map.Entry::getValue) + .map(EnrichedPathPattern::getPathPattern) + .collect(Collectors.toList()); + return new DefaultPathPattern(ImmutableSet.of(combine(collect))); + } + + private static boolean isValidFileExtension(String extension) { + checkArgument(!extension.isEmpty(), "extension"); + return FILE_EXTENSION_PATTERN.matcher(extension).matches(); } } diff --git a/common/src/test/java/com/linecorp/centraldogma/common/DefaultPathPatternTest.java b/common/src/test/java/com/linecorp/centraldogma/common/DefaultPathPatternTest.java index 13787c2c6c..a55b06f4ba 100644 --- a/common/src/test/java/com/linecorp/centraldogma/common/DefaultPathPatternTest.java +++ b/common/src/test/java/com/linecorp/centraldogma/common/DefaultPathPatternTest.java @@ -38,6 +38,11 @@ void pathPattern() { pathPattern = PathPattern.of(ImmutableSet.of("/foo/*.json", "/*/foo.txt", "/**")); assertThat(pathPattern.patternString()).isEqualTo("/**"); assertThat(pathPattern.encoded()).isEqualTo("/**"); + + pathPattern = PathPattern.of(PathPattern.of("*.json"), + PathPattern.startsWith("/foo/bar")); + assertThat(pathPattern.patternString()).isEqualTo("/**/*.json,/foo/bar/**"); + assertThat(pathPattern.encoded()).isEqualTo("/**/*.json,/foo/bar/**"); } @Test diff --git a/common/src/test/java/com/linecorp/centraldogma/common/PathPatternBuilderTest.java b/common/src/test/java/com/linecorp/centraldogma/common/PathPatternBuilderTest.java new file mode 100644 index 0000000000..5773df7654 --- /dev/null +++ b/common/src/test/java/com/linecorp/centraldogma/common/PathPatternBuilderTest.java @@ -0,0 +1,43 @@ +package com.linecorp.centraldogma.common; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.jupiter.api.Test; + +public class PathPatternBuilderTest { + + @Test + void testSingleOption() { + assertThat(PathPattern.startsWith("/foo/bar") + .patternString()).isEqualTo("/foo/bar/**"); + assertThat(PathPattern.endsWith("json") + .patternString()).isEqualTo("/**/json"); + assertThat(PathPattern.contains("/bar") + .patternString()).isEqualTo("/**/bar/**"); + assertThat(PathPattern.extension("json") + .patternString()).isEqualTo("/**/*.json"); + } + + @Test + void testPathPatternBuilder() { + assertThat(PathPattern.builder() + .startsWith("/foo/bar") + .endsWith("foo.txt") + .build() + .patternString()).isEqualTo("/foo/bar/**/foo.txt"); + + assertThat(PathPattern.builder() + .startsWith("/foo/bar") + .startsWith("/override") + .extension("json") + .build() + .patternString()).isEqualTo("/override/**/*.json"); + + assertThat(PathPattern.builder() + .startsWith("/foo") + .contains("/bar/") + .extension("json") + .build() + .patternString()).isEqualTo("/foo/**/bar/**/*.json"); + } +} From 1e5be70d31d583780f0ac0e54f4da0ec20a91c7e Mon Sep 17 00:00:00 2001 From: "kate.pham" Date: Wed, 22 Feb 2023 08:40:31 +0700 Subject: [PATCH 03/39] refactoring, add rules: option can only be added once to PathPatternBuilder, given same precedence, option added after overrides previous --- .../centraldogma/common/PathPattern.java | 1 - .../common/PathPatternBuilder.java | 220 ++++-------------- .../common/PathPatternOption.java | 66 ++++++ .../common/PathPatternOptions.java | 113 +++++++++ .../common/PathPatternBuilderTest.java | 36 ++- 5 files changed, 249 insertions(+), 187 deletions(-) create mode 100644 common/src/main/java/com/linecorp/centraldogma/common/PathPatternOption.java create mode 100644 common/src/main/java/com/linecorp/centraldogma/common/PathPatternOptions.java diff --git a/common/src/main/java/com/linecorp/centraldogma/common/PathPattern.java b/common/src/main/java/com/linecorp/centraldogma/common/PathPattern.java index 7df15ad252..69c9175a3e 100644 --- a/common/src/main/java/com/linecorp/centraldogma/common/PathPattern.java +++ b/common/src/main/java/com/linecorp/centraldogma/common/PathPattern.java @@ -96,7 +96,6 @@ static PathPattern startsWith(String dirPath) { return builder().startsWith(dirPath).build(); } - /** * Returns the path pattern for file(s) that contains {@code dirPath}. */ diff --git a/common/src/main/java/com/linecorp/centraldogma/common/PathPatternBuilder.java b/common/src/main/java/com/linecorp/centraldogma/common/PathPatternBuilder.java index a03dc90572..55fce9d8e7 100644 --- a/common/src/main/java/com/linecorp/centraldogma/common/PathPatternBuilder.java +++ b/common/src/main/java/com/linecorp/centraldogma/common/PathPatternBuilder.java @@ -17,17 +17,17 @@ import static com.google.common.base.Preconditions.checkArgument; -import java.util.HashMap; +import java.util.Comparator; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; -import java.util.regex.Pattern; +import java.util.function.Function; import java.util.stream.Collectors; import com.google.common.collect.ImmutableSet; -import com.linecorp.centraldogma.internal.Util; +import com.linecorp.centraldogma.common.PathPatternOptions.PathPatternOptionFactory; /** * Builds a new {@link PathPattern}. @@ -36,184 +36,52 @@ *
{@code
  * final PathPattern factory =
  *         PathPattern.builder()
- *                    .under("/foo/bar")
- *                    .endsWith("json")
+ *                    .startsWith("/foo/bar")
+ *                    .contains("/ext")
+ *                    .extension("json")
  *                    .build();
  * }
*/ public final class PathPatternBuilder { - private static final Pattern FILE_EXTENSION_PATTERN = Pattern.compile("^.{0,1}[0-9a-z]+$"); + private final Map options = new LinkedHashMap<>(); /** - * A {@link PathPatternBuilder} option. - */ - public enum Option { - /** - * Enum for {@link PathPatternBuilder#startsWith(String)}. - */ - STARTS_WITH(1, 1), - /** - * Enum for {@link PathPatternBuilder#contains(String)}. - */ - CONTAINS(2, 1), - /** - * Enum for {@link PathPatternBuilder#endsWith(String)}. - */ - ENDS_WITH(3, 1), - /** - * Enum for {@link PathPatternBuilder#extension(String)}. - */ - EXTENSION(3, 1); - - /** - * Determines the relative ordering of the group. - * - */ - private final int group; - - /** - * Precedence is the priority of an option - * relative to others in the same {@link PathPatternBuilder.Option#group()}. - * Precedence level (n+1) has a higher precedence than level (n). - */ - private final int precedence; - - Option(int group, int precedence) { - this.group = group; - this.precedence = precedence; - } - - /** - * Returns the group order of the option. - */ - public int group() { - return group; - } - - /** - * Returns the group precedence level of the option. - */ - public int precedence() { - return precedence; - } - } - - private final class EnrichedPathPattern { - private final Option option; - private final PathPattern pathPattern; - - /** - * Creates a new instance. - * - * @param option the option of the enrichedPathPattern - * @param pathPattern the pathPattern of the enrichedPathPattern - */ - private EnrichedPathPattern(Option option, PathPattern pathPattern) { - this.option = option; - this.pathPattern = pathPattern; - } - - /** - * Returns the option of this {@link EnrichedPathPattern}. - */ - public Option getOption() { - return option; - } - - /** - * Returns the pathPattern of this {@link EnrichedPathPattern}. - */ - public PathPattern getPathPattern() { - return pathPattern; - } - } - - private final Map patterns = new LinkedHashMap<>(); - - /** - * Prepends "/**/" to {@code filename}. - * Returns the path pattern for matching file(s) ending in {@code filename}. - */ - private static PathPattern endsWithPathPattern(String filename) { - checkArgument(Util.isValidFileName(filename), "filename"); - return new DefaultPathPattern(ImmutableSet.of(filename)); - } - - /** - * Adds {@link #endsWithPathPattern(String)}. + * Adds {@link PathPatternOptions#ENDS_WITH_OPTION}. */ public PathPatternBuilder endsWith(String filename) { - patterns.put(Option.ENDS_WITH, - new EnrichedPathPattern(Option.ENDS_WITH, endsWithPathPattern(filename))); + put(PathPatternOptions.ENDS_WITH_OPTION, filename); return this; } /** - * Prepends "/**/*" to {@code extension}. - * Returns the path pattern for matching file(s) ending in {@code extension}. - */ - private static PathPattern extensionPathPattern(String extension) { - checkArgument(isValidFileExtension(extension), "extension"); - if (extension.startsWith(".")) { - return new DefaultPathPattern(ImmutableSet.of("/**/*" + extension)); - } else { // need to add extension separator - return new DefaultPathPattern(ImmutableSet.of("/**/*." + extension)); - } - } - - /** - * Adds {@link #extensionPathPattern(String)}. + * Adds {@link PathPatternOptions#EXTENSION_OPTION}. */ public PathPatternBuilder extension(String extension) { - patterns.put(Option.EXTENSION, - new EnrichedPathPattern(Option.EXTENSION, extensionPathPattern(extension))); + put(PathPatternOptions.EXTENSION_OPTION, extension); return this; } /** - * Appends "/**" to {@code dirPath}. - * Returns the path pattern for matching all file(s) under {@code dirPath}. - */ - private static PathPattern startsWithPathPattern(String dirPath) { - checkArgument(Util.isValidDirPath(dirPath), "dir"); - return dirPath.endsWith("/") ? new DefaultPathPattern(ImmutableSet.of(dirPath + "**")) - : new DefaultPathPattern(ImmutableSet.of(dirPath + "/**")); - } - - /** - * Adds {@link #startsWithPathPattern(String)}}. + * Adds {@link PathPatternOptions#STARTS_WITH_OPTION}. */ public PathPatternBuilder startsWith(String dirPath) { - patterns.put(Option.STARTS_WITH, - new EnrichedPathPattern(Option.STARTS_WITH, startsWithPathPattern(dirPath))); + put(PathPatternOptions.STARTS_WITH_OPTION, dirPath); return this; } /** - * Prepends and appends "/**" to target {@code dirPath}. - * Returns the path pattern for matching all file(s) containing {@code dirPath}. - */ - private static PathPattern containsPathPattern(String dirPath) { - checkArgument(Util.isValidDirPath(dirPath), "dirPath"); - return dirPath.endsWith("/") ? new DefaultPathPattern(ImmutableSet.of("/**" + dirPath + "**")) - : new DefaultPathPattern(ImmutableSet.of("/**" + dirPath + "/**")); - } - - /** - * Adds {@link #containsPathPattern(String)}}. + * Adds {@link PathPatternOptions#CONTAINS_OPTION}. */ public PathPatternBuilder contains(String dirPath) { - patterns.put(Option.CONTAINS, - new EnrichedPathPattern(Option.CONTAINS, containsPathPattern(dirPath))); + put(PathPatternOptions.CONTAINS_OPTION, dirPath); return this; } - /** - * Returns combined startsWith pathPatternString and endsWith pathPatternString. + * Combine 2 patterns into one. */ - private static String combinePatterns(String left, String right) { + private static String combine(String left, String right) { checkArgument(left.endsWith("/**"), "left should end with \"/**\""); checkArgument(right.startsWith("/**/"), "right should start with \"/**/\""); return left + right.substring(3); @@ -226,7 +94,7 @@ private static String combine(Iterable patterns) { final Iterator iter = patterns.iterator(); String combinedPattern = iter.next().patternString(); while (iter.hasNext()) { - combinedPattern = combinePatterns(combinedPattern, iter.next().patternString()); + combinedPattern = combine(combinedPattern, iter.next().patternString()); } return combinedPattern; } @@ -235,35 +103,35 @@ private static String combine(Iterable patterns) { * Returns a newly-created {@link PathPattern} based on the options of this builder. */ public PathPattern build() { - checkArgument(!patterns.isEmpty(), "Requires at least one pattern to build in PathPatternBuilder"); - - if (patterns.size() == 1) { - return patterns.entrySet().iterator().next().getValue().getPathPattern(); - } + checkArgument(!options.isEmpty(), "Requires at least one pattern to build in PathPatternBuilder"); - final Map patternsGrouped = new HashMap<>(); - for (Map.Entry entry : patterns.entrySet()) { - final Option option = entry.getKey(); - final int optionGroup = option.group(); - final int optionPrecedence = option.precedence(); - if (patternsGrouped.containsKey(optionGroup) && - optionPrecedence > patternsGrouped.get(optionGroup).getOption().precedence) { - patternsGrouped.put(optionGroup, entry.getValue()); - } else { - patternsGrouped.put(optionGroup, entry.getValue()); - } + if (options.size() == 1) { + return options.entrySet().iterator().next().getValue().getPathPattern(); } - final List collect = patternsGrouped.entrySet() - .stream() - .sorted(Map.Entry.comparingByKey()) - .map(Map.Entry::getValue) - .map(EnrichedPathPattern::getPathPattern) - .collect(Collectors.toList()); - return new DefaultPathPattern(ImmutableSet.of(combine(collect))); + // given the same precedence, option added after overrides previous one + final Map optionByPrecedence = options.values() + .stream() + .collect(Collectors.toMap( + PathPatternOption::getPrecedence, + Function.identity(), + (a, b) -> b)); + final List patterns = optionByPrecedence.values() + .stream() + .sorted(Comparator.comparing( + PathPatternOption::getPrecedence)) + .map(PathPatternOption::getPathPattern) + .collect(Collectors.toList()); + + return new DefaultPathPattern(ImmutableSet.of(combine(patterns))); } - private static boolean isValidFileExtension(String extension) { - checkArgument(!extension.isEmpty(), "extension"); - return FILE_EXTENSION_PATTERN.matcher(extension).matches(); + /** + * Adds the specified {@link PathPatternOption}. + */ + private void put(PathPatternOptionFactory optionHelper, String pattern) { + final PathPatternOption pathPatternOption = optionHelper.create(pattern); + checkArgument(!options.containsKey(pathPatternOption.getName()), " %s option exists", + pathPatternOption.getName()); + options.put(pathPatternOption.getName(), pathPatternOption); } } diff --git a/common/src/main/java/com/linecorp/centraldogma/common/PathPatternOption.java b/common/src/main/java/com/linecorp/centraldogma/common/PathPatternOption.java new file mode 100644 index 0000000000..ae95c0624c --- /dev/null +++ b/common/src/main/java/com/linecorp/centraldogma/common/PathPatternOption.java @@ -0,0 +1,66 @@ +/* + * Copyright 2021 LINE Corporation + * + * LINE Corporation licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package com.linecorp.centraldogma.common; + +import java.util.function.Function; + +/** + * A {@link PathPatternBuilder} option. + */ +public class PathPatternOption { + private final String name; + /** + * Precedence is the priority of an option relative to others. + * Precedence level 1 is the highest precedence level, followed by level 2 v.v... + * In other words, n has a higher precedence than n+ 1. + */ + private final Integer precedence; + + private final String pattern; + /** + * Create {@link PathPattern} from {@code pattern}. + */ + private final Function pathPatternCreator; + + PathPatternOption(int precedence, String name, String pattern, + Function pathPatternCreator) { + this.precedence = precedence; + this.name = name; + this.pattern = pattern; + this.pathPatternCreator = pathPatternCreator; + } + + /** + * Returns the option name. + */ + public String getName() { + return name; + } + + /** + * Returns the precedence level of the option. + */ + public int getPrecedence() { + return precedence; + } + + /** + * Returns the {@link PathPattern} of the option. + */ + public PathPattern getPathPattern() { + return pathPatternCreator.apply(pattern); + } +} diff --git a/common/src/main/java/com/linecorp/centraldogma/common/PathPatternOptions.java b/common/src/main/java/com/linecorp/centraldogma/common/PathPatternOptions.java new file mode 100644 index 0000000000..1c93bbd8e4 --- /dev/null +++ b/common/src/main/java/com/linecorp/centraldogma/common/PathPatternOptions.java @@ -0,0 +1,113 @@ +package com.linecorp.centraldogma.common; + +/* + * Copyright 2023 LINE Corporation + * + * LINE Corporation licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ + +import static com.google.common.base.Preconditions.checkArgument; + +import java.util.regex.Pattern; + +import com.google.common.collect.ImmutableSet; + +import com.linecorp.centraldogma.internal.Util; + +/** + * A set of {@link PathPatternOption}s. + */ +public final class PathPatternOptions { + + private static final Pattern FILE_EXTENSION_PATTERN = Pattern.compile("^.{0,1}[0-9a-z]+$"); + + private PathPatternOptions() {} + + /** + * A factory to create an {@link PathPatternOption} instance. + */ + @FunctionalInterface + public interface PathPatternOptionFactory { + /** + * Creates a new {@link PathPatternOption} for {@code pattern}. + */ + PathPatternOption create(String pattern); + } + + /** + * Appends "/**" to {@code dirPath}. + * Returns the path pattern for matching all file(s) under {@code dirPath}. + */ + public static final PathPatternOptionFactory STARTS_WITH_OPTION = pattern -> + new PathPatternOption(1, + "startsWith", + pattern, + dirPath -> { + checkArgument(Util.isValidDirPath(dirPath), "dir"); + return new DefaultPathPattern(ImmutableSet.of( + dirPath + (dirPath.endsWith("/") ? "" : "/") + "**")); + }); + + /** + * Prepends and appends "/**" to target {@code dirPath}. + * Returns the path pattern for matching all file(s) containing {@code dirPath}. + */ + public static final PathPatternOptionFactory CONTAINS_OPTION = pattern -> + new PathPatternOption(2, + "contains", + pattern, + dirPath -> { + checkArgument(Util.isValidDirPath(dirPath), "dirPath"); + return dirPath.endsWith("/") ? new DefaultPathPattern( + ImmutableSet.of("/**" + dirPath + "**")) + : new DefaultPathPattern( + ImmutableSet.of("/**" + dirPath + "/**")); + }); + + /** + * Prepends "/**/" to {@code filename}. + * Returns the path pattern for matching file(s) ending in {@code filename}. + */ + public static final PathPatternOptionFactory ENDS_WITH_OPTION = pattern -> + new PathPatternOption(3, + "endsWith", + pattern, + filename -> { + checkArgument(Util.isValidFileName(filename), "filename"); + return new DefaultPathPattern(ImmutableSet.of(filename)); + }); + + /** + * Prepends "/**/*" to {@code extension}. + * Returns the path pattern for matching file(s) ending in {@code extension}. + */ + public static final PathPatternOptionFactory EXTENSION_OPTION = pattern -> + new PathPatternOption(3, + "extension", + pattern, + extension -> { + checkArgument(isValidFileExtension(extension), "extension"); + if (extension.startsWith(".")) { + return new DefaultPathPattern( + ImmutableSet.of("/**/*" + extension)); + } else { // need to add extension separator + return new DefaultPathPattern( + ImmutableSet.of("/**/*." + extension)); + } + }); + + private static boolean isValidFileExtension(String extension) { + checkArgument(!extension.isEmpty(), "extension"); + return FILE_EXTENSION_PATTERN.matcher(extension).matches(); + } +} diff --git a/common/src/test/java/com/linecorp/centraldogma/common/PathPatternBuilderTest.java b/common/src/test/java/com/linecorp/centraldogma/common/PathPatternBuilderTest.java index 5773df7654..7070047621 100644 --- a/common/src/test/java/com/linecorp/centraldogma/common/PathPatternBuilderTest.java +++ b/common/src/test/java/com/linecorp/centraldogma/common/PathPatternBuilderTest.java @@ -1,6 +1,7 @@ package com.linecorp.centraldogma.common; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; import org.junit.jupiter.api.Test; @@ -8,13 +9,13 @@ public class PathPatternBuilderTest { @Test void testSingleOption() { - assertThat(PathPattern.startsWith("/foo/bar") + assertThat(PathPattern.builder().startsWith("/foo/bar").build() .patternString()).isEqualTo("/foo/bar/**"); - assertThat(PathPattern.endsWith("json") + assertThat(PathPattern.builder().endsWith("json").build() .patternString()).isEqualTo("/**/json"); - assertThat(PathPattern.contains("/bar") + assertThat(PathPattern.builder().contains("/bar").build() .patternString()).isEqualTo("/**/bar/**"); - assertThat(PathPattern.extension("json") + assertThat(PathPattern.builder().extension("json").build() .patternString()).isEqualTo("/**/*.json"); } @@ -25,19 +26,34 @@ void testPathPatternBuilder() { .endsWith("foo.txt") .build() .patternString()).isEqualTo("/foo/bar/**/foo.txt"); - assertThat(PathPattern.builder() - .startsWith("/foo/bar") - .startsWith("/override") + .startsWith("/foo") + .contains("/bar/") .extension("json") .build() - .patternString()).isEqualTo("/override/**/*.json"); + .patternString()).isEqualTo("/foo/**/bar/**/*.json"); assertThat(PathPattern.builder() .startsWith("/foo") - .contains("/bar/") + .endsWith("qux.json") .extension("json") .build() - .patternString()).isEqualTo("/foo/**/bar/**/*.json"); + .patternString()).isEqualTo("/foo/**/*.json"); + assertThat(PathPattern.builder() + .startsWith("/foo") + .extension("json") + .endsWith("qux.json") + .build() + .patternString()).isEqualTo("/foo/**/qux.json"); + } + + @Test + void testInvalidPathPatternBuilder() { + assertThatThrownBy(() -> PathPattern.builder() + .startsWith("/foo/bar") + .startsWith("/override") + .extension("json") + .build() + ).isInstanceOf(IllegalArgumentException.class); } } From 8a04af49560c3b7cbacf40d6a586db5eab7ced5f Mon Sep 17 00:00:00 2001 From: "kate.pham" Date: Wed, 22 Feb 2023 09:12:17 +0700 Subject: [PATCH 04/39] add cop[right header to PathPatternBuilderTest --- .../common/PathPatternBuilderTest.java | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/common/src/test/java/com/linecorp/centraldogma/common/PathPatternBuilderTest.java b/common/src/test/java/com/linecorp/centraldogma/common/PathPatternBuilderTest.java index 7070047621..224b451e94 100644 --- a/common/src/test/java/com/linecorp/centraldogma/common/PathPatternBuilderTest.java +++ b/common/src/test/java/com/linecorp/centraldogma/common/PathPatternBuilderTest.java @@ -1,3 +1,18 @@ +/* + * Copyright 2021 LINE Corporation + * + * LINE Corporation licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ package com.linecorp.centraldogma.common; import static org.assertj.core.api.Assertions.assertThat; From c7092861d791f6f80b22d7e3fd14663fc18805b1 Mon Sep 17 00:00:00 2001 From: noodlze Date: Sun, 26 Feb 2023 16:03:25 +0700 Subject: [PATCH 05/39] Update common/src/main/java/com/linecorp/centraldogma/common/PathPatternOptions.java Co-authored-by: Ikhun Um --- .../com/linecorp/centraldogma/common/PathPatternOptions.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/src/main/java/com/linecorp/centraldogma/common/PathPatternOptions.java b/common/src/main/java/com/linecorp/centraldogma/common/PathPatternOptions.java index 1c93bbd8e4..d648cc1d94 100644 --- a/common/src/main/java/com/linecorp/centraldogma/common/PathPatternOptions.java +++ b/common/src/main/java/com/linecorp/centraldogma/common/PathPatternOptions.java @@ -27,7 +27,7 @@ /** * A set of {@link PathPatternOption}s. */ -public final class PathPatternOptions { +final class PathPatternOptions { private static final Pattern FILE_EXTENSION_PATTERN = Pattern.compile("^.{0,1}[0-9a-z]+$"); From de9fe40f6f30f38d133cb0f17b92ed1996277246 Mon Sep 17 00:00:00 2001 From: noodlze Date: Sun, 26 Feb 2023 16:06:08 +0700 Subject: [PATCH 06/39] Update common/src/main/java/com/linecorp/centraldogma/common/PathPatternOption.java Co-authored-by: Ikhun Um --- .../com/linecorp/centraldogma/common/PathPatternOption.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/src/main/java/com/linecorp/centraldogma/common/PathPatternOption.java b/common/src/main/java/com/linecorp/centraldogma/common/PathPatternOption.java index ae95c0624c..7571fae76a 100644 --- a/common/src/main/java/com/linecorp/centraldogma/common/PathPatternOption.java +++ b/common/src/main/java/com/linecorp/centraldogma/common/PathPatternOption.java @@ -46,7 +46,7 @@ public class PathPatternOption { /** * Returns the option name. */ - public String getName() { + String name() { return name; } From 2ee53179d4076d8747692c17d551d4b830d79dbe Mon Sep 17 00:00:00 2001 From: Kate Pham Date: Sun, 26 Feb 2023 16:14:06 +0700 Subject: [PATCH 07/39] shorten options name in PathPatternOptions --- .../common/PathPatternBuilder.java | 24 ++++++++++--------- .../common/PathPatternOption.java | 2 +- .../common/PathPatternOptions.java | 8 +++---- 3 files changed, 18 insertions(+), 16 deletions(-) diff --git a/common/src/main/java/com/linecorp/centraldogma/common/PathPatternBuilder.java b/common/src/main/java/com/linecorp/centraldogma/common/PathPatternBuilder.java index 55fce9d8e7..9db336778b 100644 --- a/common/src/main/java/com/linecorp/centraldogma/common/PathPatternBuilder.java +++ b/common/src/main/java/com/linecorp/centraldogma/common/PathPatternBuilder.java @@ -16,6 +16,7 @@ package com.linecorp.centraldogma.common; import static com.google.common.base.Preconditions.checkArgument; +import static java.util.Objects.requireNonNull; import java.util.Comparator; import java.util.Iterator; @@ -47,34 +48,34 @@ public final class PathPatternBuilder { private final Map options = new LinkedHashMap<>(); /** - * Adds {@link PathPatternOptions#ENDS_WITH_OPTION}. + * Adds {@link PathPatternOptions#ENDS_WITH}. */ public PathPatternBuilder endsWith(String filename) { - put(PathPatternOptions.ENDS_WITH_OPTION, filename); + put(PathPatternOptions.ENDS_WITH, filename); return this; } /** - * Adds {@link PathPatternOptions#EXTENSION_OPTION}. + * Adds {@link PathPatternOptions#EXTENSION}. */ public PathPatternBuilder extension(String extension) { - put(PathPatternOptions.EXTENSION_OPTION, extension); + put(PathPatternOptions.EXTENSION, extension); return this; } /** - * Adds {@link PathPatternOptions#STARTS_WITH_OPTION}. + * Adds {@link PathPatternOptions#STARTS_WITH}. */ public PathPatternBuilder startsWith(String dirPath) { - put(PathPatternOptions.STARTS_WITH_OPTION, dirPath); + put(PathPatternOptions.STARTS_WITH, dirPath); return this; } /** - * Adds {@link PathPatternOptions#CONTAINS_OPTION}. + * Adds {@link PathPatternOptions#CONTAINS}. */ public PathPatternBuilder contains(String dirPath) { - put(PathPatternOptions.CONTAINS_OPTION, dirPath); + put(PathPatternOptions.CONTAINS, dirPath); return this; } @@ -129,9 +130,10 @@ public PathPattern build() { * Adds the specified {@link PathPatternOption}. */ private void put(PathPatternOptionFactory optionHelper, String pattern) { + requireNonNull(pattern, "patterns"); final PathPatternOption pathPatternOption = optionHelper.create(pattern); - checkArgument(!options.containsKey(pathPatternOption.getName()), " %s option exists", - pathPatternOption.getName()); - options.put(pathPatternOption.getName(), pathPatternOption); + checkArgument(!options.containsKey(pathPatternOption.name()), " %s option exists", + pathPatternOption.name()); + options.put(pathPatternOption.name(), pathPatternOption); } } diff --git a/common/src/main/java/com/linecorp/centraldogma/common/PathPatternOption.java b/common/src/main/java/com/linecorp/centraldogma/common/PathPatternOption.java index 7571fae76a..1681cbec6d 100644 --- a/common/src/main/java/com/linecorp/centraldogma/common/PathPatternOption.java +++ b/common/src/main/java/com/linecorp/centraldogma/common/PathPatternOption.java @@ -46,7 +46,7 @@ public class PathPatternOption { /** * Returns the option name. */ - String name() { + public String name() { return name; } diff --git a/common/src/main/java/com/linecorp/centraldogma/common/PathPatternOptions.java b/common/src/main/java/com/linecorp/centraldogma/common/PathPatternOptions.java index d648cc1d94..bda9b1f571 100644 --- a/common/src/main/java/com/linecorp/centraldogma/common/PathPatternOptions.java +++ b/common/src/main/java/com/linecorp/centraldogma/common/PathPatternOptions.java @@ -48,7 +48,7 @@ public interface PathPatternOptionFactory { * Appends "/**" to {@code dirPath}. * Returns the path pattern for matching all file(s) under {@code dirPath}. */ - public static final PathPatternOptionFactory STARTS_WITH_OPTION = pattern -> + public static final PathPatternOptionFactory STARTS_WITH = pattern -> new PathPatternOption(1, "startsWith", pattern, @@ -62,7 +62,7 @@ public interface PathPatternOptionFactory { * Prepends and appends "/**" to target {@code dirPath}. * Returns the path pattern for matching all file(s) containing {@code dirPath}. */ - public static final PathPatternOptionFactory CONTAINS_OPTION = pattern -> + public static final PathPatternOptionFactory CONTAINS = pattern -> new PathPatternOption(2, "contains", pattern, @@ -78,7 +78,7 @@ public interface PathPatternOptionFactory { * Prepends "/**/" to {@code filename}. * Returns the path pattern for matching file(s) ending in {@code filename}. */ - public static final PathPatternOptionFactory ENDS_WITH_OPTION = pattern -> + public static final PathPatternOptionFactory ENDS_WITH = pattern -> new PathPatternOption(3, "endsWith", pattern, @@ -91,7 +91,7 @@ public interface PathPatternOptionFactory { * Prepends "/**/*" to {@code extension}. * Returns the path pattern for matching file(s) ending in {@code extension}. */ - public static final PathPatternOptionFactory EXTENSION_OPTION = pattern -> + public static final PathPatternOptionFactory EXTENSION = pattern -> new PathPatternOption(3, "extension", pattern, From 316bb2a61c656fd25d7e774269192b04a5594ee6 Mon Sep 17 00:00:00 2001 From: Kate Pham Date: Sun, 26 Feb 2023 20:44:18 +0700 Subject: [PATCH 08/39] add new constructor in DefaultPathPattern that does not require path validation --- .../linecorp/centraldogma/common/DefaultPathPattern.java | 7 +++++++ .../java/com/linecorp/centraldogma/common/PathPattern.java | 5 +---- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/common/src/main/java/com/linecorp/centraldogma/common/DefaultPathPattern.java b/common/src/main/java/com/linecorp/centraldogma/common/DefaultPathPattern.java index c25ca2744e..de5b37ebf9 100644 --- a/common/src/main/java/com/linecorp/centraldogma/common/DefaultPathPattern.java +++ b/common/src/main/java/com/linecorp/centraldogma/common/DefaultPathPattern.java @@ -17,6 +17,7 @@ import static com.google.common.base.Preconditions.checkArgument; +import java.util.List; import java.util.Set; import java.util.regex.Pattern; import java.util.stream.Collectors; @@ -52,6 +53,12 @@ final class DefaultPathPattern implements PathPattern { }).collect(Collectors.joining(",")); } + DefaultPathPattern(List verifiedPatterns) { + patterns = verifiedPatterns.stream() + .map(PathPattern::patternString) + .collect(Collectors.joining(",")); + } + private DefaultPathPattern(String patterns, String encoded) { this.patterns = patterns; this.encoded = encoded; diff --git a/common/src/main/java/com/linecorp/centraldogma/common/PathPattern.java b/common/src/main/java/com/linecorp/centraldogma/common/PathPattern.java index 69c9175a3e..2e7a03799b 100644 --- a/common/src/main/java/com/linecorp/centraldogma/common/PathPattern.java +++ b/common/src/main/java/com/linecorp/centraldogma/common/PathPattern.java @@ -20,7 +20,6 @@ import static java.util.Objects.requireNonNull; import java.util.Arrays; -import java.util.stream.Collectors; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Streams; @@ -65,9 +64,7 @@ static PathPattern of(String... patterns) { */ static PathPattern of(PathPattern... pathPatterns) { requireNonNull(pathPatterns, "pathPatterns"); - return of(ImmutableSet.copyOf(Arrays.stream(pathPatterns) - .map(PathPattern::patternString) - .collect(Collectors.toList()))); + return new DefaultPathPattern(Arrays.asList(pathPatterns)); } /** From 0376f6d38f8bfd1ff14c7df35ff26db45e151190 Mon Sep 17 00:00:00 2001 From: Kate Pham Date: Sun, 26 Feb 2023 20:47:54 +0700 Subject: [PATCH 09/39] allow multiple contain options in PathPatternBuilder, move buildOrder logic from PathPatternOption to PathPatternBuilder --- .../common/PathPatternBuilder.java | 63 ++++++++----------- .../common/PathPatternOption.java | 28 +-------- .../common/PathPatternOptions.java | 36 +++-------- .../common/PathPatternBuilderTest.java | 20 +++--- 4 files changed, 47 insertions(+), 100 deletions(-) diff --git a/common/src/main/java/com/linecorp/centraldogma/common/PathPatternBuilder.java b/common/src/main/java/com/linecorp/centraldogma/common/PathPatternBuilder.java index 9db336778b..3b94002fda 100644 --- a/common/src/main/java/com/linecorp/centraldogma/common/PathPatternBuilder.java +++ b/common/src/main/java/com/linecorp/centraldogma/common/PathPatternBuilder.java @@ -16,19 +16,15 @@ package com.linecorp.centraldogma.common; import static com.google.common.base.Preconditions.checkArgument; -import static java.util.Objects.requireNonNull; -import java.util.Comparator; +import java.util.ArrayList; import java.util.Iterator; -import java.util.LinkedHashMap; import java.util.List; -import java.util.Map; -import java.util.function.Function; import java.util.stream.Collectors; -import com.google.common.collect.ImmutableSet; +import javax.annotation.Nullable; -import com.linecorp.centraldogma.common.PathPatternOptions.PathPatternOptionFactory; +import com.google.common.collect.ImmutableSet; /** * Builds a new {@link PathPattern}. @@ -44,14 +40,17 @@ * } */ public final class PathPatternBuilder { - - private final Map options = new LinkedHashMap<>(); + @Nullable + private PathPatternOption startPattern; + private final List innerPatterns = new ArrayList<>(); + @Nullable + private PathPatternOption endPattern; /** * Adds {@link PathPatternOptions#ENDS_WITH}. */ public PathPatternBuilder endsWith(String filename) { - put(PathPatternOptions.ENDS_WITH, filename); + endPattern = PathPatternOptions.ENDS_WITH.apply(filename); return this; } @@ -59,7 +58,7 @@ public PathPatternBuilder endsWith(String filename) { * Adds {@link PathPatternOptions#EXTENSION}. */ public PathPatternBuilder extension(String extension) { - put(PathPatternOptions.EXTENSION, extension); + endPattern = PathPatternOptions.EXTENSION.apply(extension); return this; } @@ -67,7 +66,7 @@ public PathPatternBuilder extension(String extension) { * Adds {@link PathPatternOptions#STARTS_WITH}. */ public PathPatternBuilder startsWith(String dirPath) { - put(PathPatternOptions.STARTS_WITH, dirPath); + startPattern = PathPatternOptions.STARTS_WITH.apply(dirPath); return this; } @@ -75,7 +74,7 @@ public PathPatternBuilder startsWith(String dirPath) { * Adds {@link PathPatternOptions#CONTAINS}. */ public PathPatternBuilder contains(String dirPath) { - put(PathPatternOptions.CONTAINS, dirPath); + innerPatterns.add(PathPatternOptions.CONTAINS.apply(dirPath)); return this; } @@ -104,36 +103,24 @@ private static String combine(Iterable patterns) { * Returns a newly-created {@link PathPattern} based on the options of this builder. */ public PathPattern build() { + final List options = new ArrayList<>(); + if (startPattern != null) { + options.add(startPattern); + } + options.addAll(innerPatterns); + if (endPattern != null) { + options.add(endPattern); + } + checkArgument(!options.isEmpty(), "Requires at least one pattern to build in PathPatternBuilder"); if (options.size() == 1) { - return options.entrySet().iterator().next().getValue().getPathPattern(); + return options.get(0).pathPattern(); } - // given the same precedence, option added after overrides previous one - final Map optionByPrecedence = options.values() - .stream() - .collect(Collectors.toMap( - PathPatternOption::getPrecedence, - Function.identity(), - (a, b) -> b)); - final List patterns = optionByPrecedence.values() - .stream() - .sorted(Comparator.comparing( - PathPatternOption::getPrecedence)) - .map(PathPatternOption::getPathPattern) - .collect(Collectors.toList()); + final List patterns = options.stream() + .map(PathPatternOption::pathPattern) + .collect(Collectors.toList()); return new DefaultPathPattern(ImmutableSet.of(combine(patterns))); } - - /** - * Adds the specified {@link PathPatternOption}. - */ - private void put(PathPatternOptionFactory optionHelper, String pattern) { - requireNonNull(pattern, "patterns"); - final PathPatternOption pathPatternOption = optionHelper.create(pattern); - checkArgument(!options.containsKey(pathPatternOption.name()), " %s option exists", - pathPatternOption.name()); - options.put(pathPatternOption.name(), pathPatternOption); - } } diff --git a/common/src/main/java/com/linecorp/centraldogma/common/PathPatternOption.java b/common/src/main/java/com/linecorp/centraldogma/common/PathPatternOption.java index 1681cbec6d..ae3b763c8f 100644 --- a/common/src/main/java/com/linecorp/centraldogma/common/PathPatternOption.java +++ b/common/src/main/java/com/linecorp/centraldogma/common/PathPatternOption.java @@ -21,46 +21,22 @@ * A {@link PathPatternBuilder} option. */ public class PathPatternOption { - private final String name; - /** - * Precedence is the priority of an option relative to others. - * Precedence level 1 is the highest precedence level, followed by level 2 v.v... - * In other words, n has a higher precedence than n+ 1. - */ - private final Integer precedence; - private final String pattern; /** * Create {@link PathPattern} from {@code pattern}. */ private final Function pathPatternCreator; - PathPatternOption(int precedence, String name, String pattern, + PathPatternOption(String pattern, Function pathPatternCreator) { - this.precedence = precedence; - this.name = name; this.pattern = pattern; this.pathPatternCreator = pathPatternCreator; } - /** - * Returns the option name. - */ - public String name() { - return name; - } - - /** - * Returns the precedence level of the option. - */ - public int getPrecedence() { - return precedence; - } - /** * Returns the {@link PathPattern} of the option. */ - public PathPattern getPathPattern() { + public PathPattern pathPattern() { return pathPatternCreator.apply(pattern); } } diff --git a/common/src/main/java/com/linecorp/centraldogma/common/PathPatternOptions.java b/common/src/main/java/com/linecorp/centraldogma/common/PathPatternOptions.java index bda9b1f571..e091622750 100644 --- a/common/src/main/java/com/linecorp/centraldogma/common/PathPatternOptions.java +++ b/common/src/main/java/com/linecorp/centraldogma/common/PathPatternOptions.java @@ -18,6 +18,7 @@ import static com.google.common.base.Preconditions.checkArgument; +import java.util.function.Function; import java.util.regex.Pattern; import com.google.common.collect.ImmutableSet; @@ -33,25 +34,12 @@ final class PathPatternOptions { private PathPatternOptions() {} - /** - * A factory to create an {@link PathPatternOption} instance. - */ - @FunctionalInterface - public interface PathPatternOptionFactory { - /** - * Creates a new {@link PathPatternOption} for {@code pattern}. - */ - PathPatternOption create(String pattern); - } - /** * Appends "/**" to {@code dirPath}. * Returns the path pattern for matching all file(s) under {@code dirPath}. */ - public static final PathPatternOptionFactory STARTS_WITH = pattern -> - new PathPatternOption(1, - "startsWith", - pattern, + public static final Function STARTS_WITH = pattern -> + new PathPatternOption(pattern, dirPath -> { checkArgument(Util.isValidDirPath(dirPath), "dir"); return new DefaultPathPattern(ImmutableSet.of( @@ -62,10 +50,8 @@ public interface PathPatternOptionFactory { * Prepends and appends "/**" to target {@code dirPath}. * Returns the path pattern for matching all file(s) containing {@code dirPath}. */ - public static final PathPatternOptionFactory CONTAINS = pattern -> - new PathPatternOption(2, - "contains", - pattern, + public static final Function CONTAINS = pattern -> + new PathPatternOption(pattern, dirPath -> { checkArgument(Util.isValidDirPath(dirPath), "dirPath"); return dirPath.endsWith("/") ? new DefaultPathPattern( @@ -78,10 +64,8 @@ public interface PathPatternOptionFactory { * Prepends "/**/" to {@code filename}. * Returns the path pattern for matching file(s) ending in {@code filename}. */ - public static final PathPatternOptionFactory ENDS_WITH = pattern -> - new PathPatternOption(3, - "endsWith", - pattern, + public static final Function ENDS_WITH = pattern -> + new PathPatternOption(pattern, filename -> { checkArgument(Util.isValidFileName(filename), "filename"); return new DefaultPathPattern(ImmutableSet.of(filename)); @@ -91,10 +75,8 @@ public interface PathPatternOptionFactory { * Prepends "/**/*" to {@code extension}. * Returns the path pattern for matching file(s) ending in {@code extension}. */ - public static final PathPatternOptionFactory EXTENSION = pattern -> - new PathPatternOption(3, - "extension", - pattern, + public static final Function EXTENSION = pattern -> + new PathPatternOption(pattern, extension -> { checkArgument(isValidFileExtension(extension), "extension"); if (extension.startsWith(".")) { diff --git a/common/src/test/java/com/linecorp/centraldogma/common/PathPatternBuilderTest.java b/common/src/test/java/com/linecorp/centraldogma/common/PathPatternBuilderTest.java index 224b451e94..58633e6869 100644 --- a/common/src/test/java/com/linecorp/centraldogma/common/PathPatternBuilderTest.java +++ b/common/src/test/java/com/linecorp/centraldogma/common/PathPatternBuilderTest.java @@ -60,15 +60,17 @@ void testPathPatternBuilder() { .endsWith("qux.json") .build() .patternString()).isEqualTo("/foo/**/qux.json"); - } - @Test - void testInvalidPathPatternBuilder() { - assertThatThrownBy(() -> PathPattern.builder() - .startsWith("/foo/bar") - .startsWith("/override") - .extension("json") - .build() - ).isInstanceOf(IllegalArgumentException.class); + assertThat(PathPattern.builder() + .contains("/foo") + .contains("/bar") + .build() + .patternString()).isEqualTo("/**/foo/**/bar/**"); + assertThat(PathPattern.builder() + .startsWith("/foo/bar") + .startsWith("/override") + .extension("json") + .build() + .patternString()).isEqualTo("/override/**/*.json"); } } From c799e632a446876f5092f993d9aa2b6676d6bd21 Mon Sep 17 00:00:00 2001 From: Kate Pham Date: Mon, 27 Feb 2023 06:31:51 +0700 Subject: [PATCH 10/39] remove unused import --- .../com/linecorp/centraldogma/common/PathPatternBuilderTest.java | 1 - 1 file changed, 1 deletion(-) diff --git a/common/src/test/java/com/linecorp/centraldogma/common/PathPatternBuilderTest.java b/common/src/test/java/com/linecorp/centraldogma/common/PathPatternBuilderTest.java index 58633e6869..9999d2c83c 100644 --- a/common/src/test/java/com/linecorp/centraldogma/common/PathPatternBuilderTest.java +++ b/common/src/test/java/com/linecorp/centraldogma/common/PathPatternBuilderTest.java @@ -16,7 +16,6 @@ package com.linecorp.centraldogma.common; import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; import org.junit.jupiter.api.Test; From f524a6dc86913dadf725cac369a5f34bbcff9ca8 Mon Sep 17 00:00:00 2001 From: noodlze Date: Thu, 2 Mar 2023 21:01:09 +0700 Subject: [PATCH 11/39] Update common/src/main/java/com/linecorp/centraldogma/common/PathPattern.java Co-authored-by: Ikhun Um --- .../main/java/com/linecorp/centraldogma/common/PathPattern.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/src/main/java/com/linecorp/centraldogma/common/PathPattern.java b/common/src/main/java/com/linecorp/centraldogma/common/PathPattern.java index 2e7a03799b..e92a4d3376 100644 --- a/common/src/main/java/com/linecorp/centraldogma/common/PathPattern.java +++ b/common/src/main/java/com/linecorp/centraldogma/common/PathPattern.java @@ -64,7 +64,7 @@ static PathPattern of(String... patterns) { */ static PathPattern of(PathPattern... pathPatterns) { requireNonNull(pathPatterns, "pathPatterns"); - return new DefaultPathPattern(Arrays.asList(pathPatterns)); + return new DefaultPathPattern(ImmutableList.copyOf(pathPatterns)); } /** From 5d610a0cffe9eac69a348ff8819739b656da0d77 Mon Sep 17 00:00:00 2001 From: noodlze Date: Thu, 2 Mar 2023 21:02:51 +0700 Subject: [PATCH 12/39] Update common/src/test/java/com/linecorp/centraldogma/common/PathPatternBuilderTest.java Co-authored-by: Ikhun Um --- .../linecorp/centraldogma/common/PathPatternBuilderTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/src/test/java/com/linecorp/centraldogma/common/PathPatternBuilderTest.java b/common/src/test/java/com/linecorp/centraldogma/common/PathPatternBuilderTest.java index 9999d2c83c..6718456744 100644 --- a/common/src/test/java/com/linecorp/centraldogma/common/PathPatternBuilderTest.java +++ b/common/src/test/java/com/linecorp/centraldogma/common/PathPatternBuilderTest.java @@ -19,7 +19,7 @@ import org.junit.jupiter.api.Test; -public class PathPatternBuilderTest { +class PathPatternBuilderTest { @Test void testSingleOption() { From 1fd3bcdf1b943144045e2db1d431493ddaa3f0b0 Mon Sep 17 00:00:00 2001 From: noodlze Date: Thu, 2 Mar 2023 21:03:50 +0700 Subject: [PATCH 13/39] Update common/src/test/java/com/linecorp/centraldogma/common/PathPatternBuilderTest.java Co-authored-by: Ikhun Um --- .../linecorp/centraldogma/common/PathPatternBuilderTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/common/src/test/java/com/linecorp/centraldogma/common/PathPatternBuilderTest.java b/common/src/test/java/com/linecorp/centraldogma/common/PathPatternBuilderTest.java index 6718456744..62c163f754 100644 --- a/common/src/test/java/com/linecorp/centraldogma/common/PathPatternBuilderTest.java +++ b/common/src/test/java/com/linecorp/centraldogma/common/PathPatternBuilderTest.java @@ -25,8 +25,8 @@ class PathPatternBuilderTest { void testSingleOption() { assertThat(PathPattern.builder().startsWith("/foo/bar").build() .patternString()).isEqualTo("/foo/bar/**"); - assertThat(PathPattern.builder().endsWith("json").build() - .patternString()).isEqualTo("/**/json"); + assertThat(PathPattern.builder().endsWith("foo.json").build() + .patternString()).isEqualTo("/**/foo.json"); assertThat(PathPattern.builder().contains("/bar").build() .patternString()).isEqualTo("/**/bar/**"); assertThat(PathPattern.builder().extension("json").build() From dc5fd40e0bb383ac575d7848a1e4037c1b0f9971 Mon Sep 17 00:00:00 2001 From: noodlze Date: Thu, 2 Mar 2023 21:04:48 +0700 Subject: [PATCH 14/39] Update common/src/main/java/com/linecorp/centraldogma/common/PathPatternBuilder.java Co-authored-by: Ikhun Um --- .../com/linecorp/centraldogma/common/PathPatternBuilder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/src/main/java/com/linecorp/centraldogma/common/PathPatternBuilder.java b/common/src/main/java/com/linecorp/centraldogma/common/PathPatternBuilder.java index 3b94002fda..39cc1c98ab 100644 --- a/common/src/main/java/com/linecorp/centraldogma/common/PathPatternBuilder.java +++ b/common/src/main/java/com/linecorp/centraldogma/common/PathPatternBuilder.java @@ -120,7 +120,7 @@ public PathPattern build() { final List patterns = options.stream() .map(PathPatternOption::pathPattern) - .collect(Collectors.toList()); + .collect(toImmutableList()); return new DefaultPathPattern(ImmutableSet.of(combine(patterns))); } } From da405670db4a5f2c00916a895f39be22cb2debb8 Mon Sep 17 00:00:00 2001 From: noodlze Date: Thu, 2 Mar 2023 21:07:43 +0700 Subject: [PATCH 15/39] Update common/src/main/java/com/linecorp/centraldogma/common/PathPatternOption.java Co-authored-by: Ikhun Um --- .../com/linecorp/centraldogma/common/PathPatternOption.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/src/main/java/com/linecorp/centraldogma/common/PathPatternOption.java b/common/src/main/java/com/linecorp/centraldogma/common/PathPatternOption.java index ae3b763c8f..360a1df191 100644 --- a/common/src/main/java/com/linecorp/centraldogma/common/PathPatternOption.java +++ b/common/src/main/java/com/linecorp/centraldogma/common/PathPatternOption.java @@ -20,7 +20,7 @@ /** * A {@link PathPatternBuilder} option. */ -public class PathPatternOption { +final class PathPatternOption { private final String pattern; /** * Create {@link PathPattern} from {@code pattern}. From a53edb2dd1b6f0b9928ed26c1ac21f62c538eda2 Mon Sep 17 00:00:00 2001 From: noodlze Date: Thu, 2 Mar 2023 21:08:17 +0700 Subject: [PATCH 16/39] Update common/src/main/java/com/linecorp/centraldogma/common/PathPatternOption.java Co-authored-by: Ikhun Um --- .../com/linecorp/centraldogma/common/PathPatternOption.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/src/main/java/com/linecorp/centraldogma/common/PathPatternOption.java b/common/src/main/java/com/linecorp/centraldogma/common/PathPatternOption.java index 360a1df191..7b423d4a81 100644 --- a/common/src/main/java/com/linecorp/centraldogma/common/PathPatternOption.java +++ b/common/src/main/java/com/linecorp/centraldogma/common/PathPatternOption.java @@ -36,7 +36,7 @@ final class PathPatternOption { /** * Returns the {@link PathPattern} of the option. */ - public PathPattern pathPattern() { + PathPattern pathPattern() { return pathPatternCreator.apply(pattern); } } From 06662c6c5ff2cb898ee87982a1537a59fea71ca1 Mon Sep 17 00:00:00 2001 From: noodlze Date: Thu, 2 Mar 2023 21:08:47 +0700 Subject: [PATCH 17/39] Update common/src/main/java/com/linecorp/centraldogma/common/PathPatternBuilder.java Co-authored-by: Ikhun Um --- .../com/linecorp/centraldogma/common/PathPatternBuilder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/src/main/java/com/linecorp/centraldogma/common/PathPatternBuilder.java b/common/src/main/java/com/linecorp/centraldogma/common/PathPatternBuilder.java index 39cc1c98ab..ae4d2ab9f7 100644 --- a/common/src/main/java/com/linecorp/centraldogma/common/PathPatternBuilder.java +++ b/common/src/main/java/com/linecorp/centraldogma/common/PathPatternBuilder.java @@ -45,7 +45,7 @@ public final class PathPatternBuilder { private final List innerPatterns = new ArrayList<>(); @Nullable private PathPatternOption endPattern; - + PathPatternBuilder() {} /** * Adds {@link PathPatternOptions#ENDS_WITH}. */ From 986df3a8c3aa8b80cdbd107c0ae8ae7fcb7ae1fa Mon Sep 17 00:00:00 2001 From: noodlze Date: Thu, 2 Mar 2023 21:09:05 +0700 Subject: [PATCH 18/39] Update common/src/main/java/com/linecorp/centraldogma/common/PathPatternBuilder.java Co-authored-by: Ikhun Um --- .../com/linecorp/centraldogma/common/PathPatternBuilder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/src/main/java/com/linecorp/centraldogma/common/PathPatternBuilder.java b/common/src/main/java/com/linecorp/centraldogma/common/PathPatternBuilder.java index ae4d2ab9f7..b7cbf8495c 100644 --- a/common/src/main/java/com/linecorp/centraldogma/common/PathPatternBuilder.java +++ b/common/src/main/java/com/linecorp/centraldogma/common/PathPatternBuilder.java @@ -90,7 +90,7 @@ private static String combine(String left, String right) { /** * Compose one pathPattern from a list of {@code patterns}. */ - private static String combine(Iterable patterns) { + private static String combine(List patterns) { final Iterator iter = patterns.iterator(); String combinedPattern = iter.next().patternString(); while (iter.hasNext()) { From b460bfe908e536f2fb8488bd87c3eb99d9089613 Mon Sep 17 00:00:00 2001 From: noodlze Date: Thu, 2 Mar 2023 21:13:36 +0700 Subject: [PATCH 19/39] Update common/src/main/java/com/linecorp/centraldogma/common/PathPatternBuilder.java Co-authored-by: Ikhun Um --- .../com/linecorp/centraldogma/common/PathPatternBuilder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/src/main/java/com/linecorp/centraldogma/common/PathPatternBuilder.java b/common/src/main/java/com/linecorp/centraldogma/common/PathPatternBuilder.java index b7cbf8495c..ef076224ea 100644 --- a/common/src/main/java/com/linecorp/centraldogma/common/PathPatternBuilder.java +++ b/common/src/main/java/com/linecorp/centraldogma/common/PathPatternBuilder.java @@ -31,7 +31,7 @@ * *

Example

*
{@code
- * final PathPattern factory =
+ * final PathPattern pathPattern =
  *         PathPattern.builder()
  *                    .startsWith("/foo/bar")
  *                    .contains("/ext")

From 0cf67c95803ff4dfe02b9a12855a6ef2a8b60c03 Mon Sep 17 00:00:00 2001
From: noodlze 
Date: Thu, 2 Mar 2023 21:17:08 +0700
Subject: [PATCH 20/39] Update
 common/src/main/java/com/linecorp/centraldogma/common/PathPatternOptions.java

Co-authored-by: Ikhun Um 
---
 .../com/linecorp/centraldogma/common/PathPatternOptions.java     | 1 +
 1 file changed, 1 insertion(+)

diff --git a/common/src/main/java/com/linecorp/centraldogma/common/PathPatternOptions.java b/common/src/main/java/com/linecorp/centraldogma/common/PathPatternOptions.java
index e091622750..567c2781b1 100644
--- a/common/src/main/java/com/linecorp/centraldogma/common/PathPatternOptions.java
+++ b/common/src/main/java/com/linecorp/centraldogma/common/PathPatternOptions.java
@@ -68,6 +68,7 @@ private PathPatternOptions() {}
             new PathPatternOption(pattern,
                                   filename -> {
                                       checkArgument(Util.isValidFileName(filename), "filename");
+                                      // `/**` is added by the constructor of `DefaultPathPattern`
                                       return new DefaultPathPattern(ImmutableSet.of(filename));
                                   });
 

From 9a2b815b90f124e510664c6d53a8c6bbf0b0f285 Mon Sep 17 00:00:00 2001
From: Kate Pham 
Date: Thu, 2 Mar 2023 21:23:30 +0700
Subject: [PATCH 21/39] fix missing imports, checkstyle violations

---
 .../com/linecorp/centraldogma/common/PathPatternBuilder.java  | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/common/src/main/java/com/linecorp/centraldogma/common/PathPatternBuilder.java b/common/src/main/java/com/linecorp/centraldogma/common/PathPatternBuilder.java
index ef076224ea..b88476bfa3 100644
--- a/common/src/main/java/com/linecorp/centraldogma/common/PathPatternBuilder.java
+++ b/common/src/main/java/com/linecorp/centraldogma/common/PathPatternBuilder.java
@@ -16,11 +16,11 @@
 package com.linecorp.centraldogma.common;
 
 import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.collect.ImmutableList.toImmutableList;
 
 import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
-import java.util.stream.Collectors;
 
 import javax.annotation.Nullable;
 
@@ -45,7 +45,9 @@ public final class PathPatternBuilder {
     private final List innerPatterns = new ArrayList<>();
     @Nullable
     private PathPatternOption endPattern;
+
     PathPatternBuilder() {}
+
     /**
      * Adds {@link PathPatternOptions#ENDS_WITH}.
      */

From 67bb12753e4c989fd30ccd577a2a2d6f096b369b Mon Sep 17 00:00:00 2001
From: Kate Pham 
Date: Thu, 2 Mar 2023 21:33:52 +0700
Subject: [PATCH 22/39] fix missing imports, address code style: prefer
 ImmutableList.Builder

---
 .../com/linecorp/centraldogma/common/PathPattern.java  |  3 +--
 .../centraldogma/common/PathPatternBuilder.java        | 10 ++++++----
 2 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/common/src/main/java/com/linecorp/centraldogma/common/PathPattern.java b/common/src/main/java/com/linecorp/centraldogma/common/PathPattern.java
index e92a4d3376..36c788ed88 100644
--- a/common/src/main/java/com/linecorp/centraldogma/common/PathPattern.java
+++ b/common/src/main/java/com/linecorp/centraldogma/common/PathPattern.java
@@ -19,8 +19,7 @@
 import static com.linecorp.centraldogma.common.DefaultPathPattern.allPattern;
 import static java.util.Objects.requireNonNull;
 
-import java.util.Arrays;
-
+import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Streams;
 
diff --git a/common/src/main/java/com/linecorp/centraldogma/common/PathPatternBuilder.java b/common/src/main/java/com/linecorp/centraldogma/common/PathPatternBuilder.java
index b88476bfa3..73d0363d7a 100644
--- a/common/src/main/java/com/linecorp/centraldogma/common/PathPatternBuilder.java
+++ b/common/src/main/java/com/linecorp/centraldogma/common/PathPatternBuilder.java
@@ -24,6 +24,7 @@
 
 import javax.annotation.Nullable;
 
+import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableSet;
 
 /**
@@ -105,14 +106,15 @@ private static String combine(List patterns) {
      * Returns a newly-created {@link PathPattern} based on the options of this builder.
      */
     public PathPattern build() {
-        final List options = new ArrayList<>();
+        final ImmutableList.Builder optionsBuilder = ImmutableList.builder();
         if (startPattern != null) {
-            options.add(startPattern);
+            optionsBuilder.add(startPattern);
         }
-        options.addAll(innerPatterns);
+        optionsBuilder.addAll(innerPatterns);
         if (endPattern != null) {
-            options.add(endPattern);
+            optionsBuilder.add(endPattern);
         }
+        final ImmutableList options = optionsBuilder.build();
 
         checkArgument(!options.isEmpty(), "Requires at least one pattern to build in PathPatternBuilder");
 

From dbb142c1c225cc53aa8a0290dad33b121a0e0c3e Mon Sep 17 00:00:00 2001
From: Kate Pham 
Date: Fri, 3 Mar 2023 06:55:35 +0700
Subject: [PATCH 23/39] use StringBuilder to combine for efficiency

---
 .../common/PathPatternBuilder.java            | 24 ++++++++-----------
 1 file changed, 10 insertions(+), 14 deletions(-)

diff --git a/common/src/main/java/com/linecorp/centraldogma/common/PathPatternBuilder.java b/common/src/main/java/com/linecorp/centraldogma/common/PathPatternBuilder.java
index 73d0363d7a..e4f0434c6c 100644
--- a/common/src/main/java/com/linecorp/centraldogma/common/PathPatternBuilder.java
+++ b/common/src/main/java/com/linecorp/centraldogma/common/PathPatternBuilder.java
@@ -81,25 +81,21 @@ public PathPatternBuilder contains(String dirPath) {
         return this;
     }
 
-    /**
-     * Combine 2 patterns into one.
-     */
-    private static String combine(String left, String right) {
-        checkArgument(left.endsWith("/**"), "left should end with \"/**\"");
-        checkArgument(right.startsWith("/**/"), "right should start with \"/**/\"");
-        return left + right.substring(3);
-    }
-
     /**
      * Compose one pathPattern from a list of {@code patterns}.
      */
     private static String combine(List patterns) {
-        final Iterator iter = patterns.iterator();
-        String combinedPattern = iter.next().patternString();
-        while (iter.hasNext()) {
-            combinedPattern = combine(combinedPattern, iter.next().patternString());
+        final StringBuilder sb = new StringBuilder();
+        for (final Iterator i = patterns.iterator(); i.hasNext();) {
+            if (sb.length() == 0) {
+                // left should end with "/**"
+                sb.append(i.next().patternString());
+            } else {
+                // right should start with "/**/"
+                sb.append(i.next().patternString().substring(3));
+            }
         }
-        return combinedPattern;
+        return sb.toString();
     }
 
     /**

From 3f5ab60dcadac31a9c53cf2523d58ee8e7215b7a Mon Sep 17 00:00:00 2001
From: Kate Pham 
Date: Fri, 3 Mar 2023 07:38:59 +0700
Subject: [PATCH 24/39] add new constructor in DefaultPathPattern for a single
 string

---
 .../common/DefaultPathPattern.java            | 20 ++++++++++-----
 .../common/PathPatternBuilder.java            |  3 +--
 .../common/PathPatternOptions.java            | 25 ++++++++-----------
 3 files changed, 26 insertions(+), 22 deletions(-)

diff --git a/common/src/main/java/com/linecorp/centraldogma/common/DefaultPathPattern.java b/common/src/main/java/com/linecorp/centraldogma/common/DefaultPathPattern.java
index de5b37ebf9..72edf6cbbb 100644
--- a/common/src/main/java/com/linecorp/centraldogma/common/DefaultPathPattern.java
+++ b/common/src/main/java/com/linecorp/centraldogma/common/DefaultPathPattern.java
@@ -45,12 +45,8 @@ final class DefaultPathPattern implements PathPattern {
         this.patterns = patterns.stream()
                                 .peek(DefaultPathPattern::validatePathPattern)
                                 .filter(pattern -> !pattern.isEmpty())
-                                .map(pattern -> {
-                                    if (pattern.charAt(0) != '/') {
-                                        return "/**/" + pattern;
-                                    }
-                                    return pattern;
-                                }).collect(Collectors.joining(","));
+                                .map(DefaultPathPattern::normalizePattern)
+                                .collect(Collectors.joining(","));
     }
 
     DefaultPathPattern(List verifiedPatterns) {
@@ -59,6 +55,11 @@ final class DefaultPathPattern implements PathPattern {
                                    .collect(Collectors.joining(","));
     }
 
+    DefaultPathPattern(String pattern) {
+        validatePathPattern(pattern);
+        patterns = normalizePattern(pattern);
+    }
+
     private DefaultPathPattern(String patterns, String encoded) {
         this.patterns = patterns;
         this.encoded = encoded;
@@ -107,6 +108,13 @@ private static String validatePathPattern(String pattern) {
         return pattern;
     }
 
+    private static String normalizePattern(String pattern) {
+        if (pattern.charAt(0) != '/') {
+            return "/**/" + pattern;
+        }
+        return pattern;
+    }
+
     @Override
     public String toString() {
         return MoreObjects.toStringHelper(this)
diff --git a/common/src/main/java/com/linecorp/centraldogma/common/PathPatternBuilder.java b/common/src/main/java/com/linecorp/centraldogma/common/PathPatternBuilder.java
index e4f0434c6c..76b8471e16 100644
--- a/common/src/main/java/com/linecorp/centraldogma/common/PathPatternBuilder.java
+++ b/common/src/main/java/com/linecorp/centraldogma/common/PathPatternBuilder.java
@@ -25,7 +25,6 @@
 import javax.annotation.Nullable;
 
 import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableSet;
 
 /**
  * Builds a new {@link PathPattern}.
@@ -121,6 +120,6 @@ public PathPattern build() {
         final List patterns = options.stream()
                                                   .map(PathPatternOption::pathPattern)
                                                   .collect(toImmutableList());
-        return new DefaultPathPattern(ImmutableSet.of(combine(patterns)));
+        return new DefaultPathPattern(combine(patterns));
     }
 }
diff --git a/common/src/main/java/com/linecorp/centraldogma/common/PathPatternOptions.java b/common/src/main/java/com/linecorp/centraldogma/common/PathPatternOptions.java
index 567c2781b1..d331a76699 100644
--- a/common/src/main/java/com/linecorp/centraldogma/common/PathPatternOptions.java
+++ b/common/src/main/java/com/linecorp/centraldogma/common/PathPatternOptions.java
@@ -21,8 +21,6 @@
 import java.util.function.Function;
 import java.util.regex.Pattern;
 
-import com.google.common.collect.ImmutableSet;
-
 import com.linecorp.centraldogma.internal.Util;
 
 /**
@@ -42,8 +40,8 @@ private PathPatternOptions() {}
             new PathPatternOption(pattern,
                                   dirPath -> {
                                       checkArgument(Util.isValidDirPath(dirPath), "dir");
-                                      return new DefaultPathPattern(ImmutableSet.of(
-                                              dirPath + (dirPath.endsWith("/") ? "" : "/") + "**"));
+                                      return new DefaultPathPattern(
+                                              dirPath + (dirPath.endsWith("/") ? "" : "/") + "**");
                                   });
 
     /**
@@ -54,10 +52,11 @@ private PathPatternOptions() {}
             new PathPatternOption(pattern,
                                   dirPath -> {
                                       checkArgument(Util.isValidDirPath(dirPath), "dirPath");
-                                      return dirPath.endsWith("/") ? new DefaultPathPattern(
-                                              ImmutableSet.of("/**" + dirPath + "**"))
-                                                                   : new DefaultPathPattern(
-                                              ImmutableSet.of("/**" + dirPath + "/**"));
+                                      if (dirPath.endsWith("/")) {
+                                          return new DefaultPathPattern("/**" + dirPath + "**");
+                                      } else { // add ending slash to dirPath
+                                          return new DefaultPathPattern("/**" + dirPath + "/**");
+                                      }
                                   });
 
     /**
@@ -69,7 +68,7 @@ private PathPatternOptions() {}
                                   filename -> {
                                       checkArgument(Util.isValidFileName(filename), "filename");
                                       // `/**` is added by the constructor of `DefaultPathPattern`
-                                      return new DefaultPathPattern(ImmutableSet.of(filename));
+                                      return new DefaultPathPattern(filename);
                                   });
 
     /**
@@ -81,11 +80,9 @@ private PathPatternOptions() {}
                                   extension -> {
                                       checkArgument(isValidFileExtension(extension), "extension");
                                       if (extension.startsWith(".")) {
-                                          return new DefaultPathPattern(
-                                                  ImmutableSet.of("/**/*" + extension));
-                                      } else { // need to add extension separator
-                                          return new DefaultPathPattern(
-                                                  ImmutableSet.of("/**/*." + extension));
+                                          return new DefaultPathPattern("/**/*" + extension);
+                                      } else { // add extension separator
+                                          return new DefaultPathPattern("/**/*." + extension);
                                       }
                                   });
 

From 33ccb30d50b0e975b786e04b58859e216a0a8ec9 Mon Sep 17 00:00:00 2001
From: noodlze 
Date: Fri, 3 Mar 2023 15:26:03 +0700
Subject: [PATCH 25/39] Update
 common/src/main/java/com/linecorp/centraldogma/common/PathPattern.java

Co-authored-by: Ikhun Um 
---
 .../main/java/com/linecorp/centraldogma/common/PathPattern.java | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/common/src/main/java/com/linecorp/centraldogma/common/PathPattern.java b/common/src/main/java/com/linecorp/centraldogma/common/PathPattern.java
index 36c788ed88..ed8c1fdbe7 100644
--- a/common/src/main/java/com/linecorp/centraldogma/common/PathPattern.java
+++ b/common/src/main/java/com/linecorp/centraldogma/common/PathPattern.java
@@ -38,7 +38,7 @@
 public interface PathPattern {
 
     /**
-     *Returns a newly created {@link PathPatternBuilder}.
+     * Returns a newly created {@link PathPatternBuilder}.
      */
     static PathPatternBuilder builder() {
         return new PathPatternBuilder();

From 96f14cee381120a69b23002c5d916aa7a3be5f82 Mon Sep 17 00:00:00 2001
From: noodlze 
Date: Fri, 3 Mar 2023 15:27:08 +0700
Subject: [PATCH 26/39] Update
 common/src/main/java/com/linecorp/centraldogma/common/PathPatternOptions.java

Co-authored-by: Ikhun Um 
---
 .../com/linecorp/centraldogma/common/PathPatternOptions.java    | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/common/src/main/java/com/linecorp/centraldogma/common/PathPatternOptions.java b/common/src/main/java/com/linecorp/centraldogma/common/PathPatternOptions.java
index d331a76699..d094e8b724 100644
--- a/common/src/main/java/com/linecorp/centraldogma/common/PathPatternOptions.java
+++ b/common/src/main/java/com/linecorp/centraldogma/common/PathPatternOptions.java
@@ -63,7 +63,7 @@ private PathPatternOptions() {}
      * Prepends "/**/" to {@code filename}.
      * Returns the path pattern for matching file(s) ending in {@code filename}.
      */
-    public static final Function ENDS_WITH = pattern ->
+    static final Function ENDS_WITH = pattern ->
             new PathPatternOption(pattern,
                                   filename -> {
                                       checkArgument(Util.isValidFileName(filename), "filename");

From 469020dcf3c5e94271ad844cb117b366bc956735 Mon Sep 17 00:00:00 2001
From: noodlze 
Date: Fri, 3 Mar 2023 15:27:38 +0700
Subject: [PATCH 27/39] Update
 common/src/main/java/com/linecorp/centraldogma/common/PathPatternOptions.java

Co-authored-by: Ikhun Um 
---
 .../com/linecorp/centraldogma/common/PathPatternOptions.java    | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/common/src/main/java/com/linecorp/centraldogma/common/PathPatternOptions.java b/common/src/main/java/com/linecorp/centraldogma/common/PathPatternOptions.java
index d094e8b724..aec5095bdb 100644
--- a/common/src/main/java/com/linecorp/centraldogma/common/PathPatternOptions.java
+++ b/common/src/main/java/com/linecorp/centraldogma/common/PathPatternOptions.java
@@ -48,7 +48,7 @@ private PathPatternOptions() {}
      * Prepends and appends "/**" to target {@code dirPath}.
      * Returns the path pattern for matching all file(s) containing {@code dirPath}.
      */
-    public static final Function CONTAINS = pattern ->
+    static final Function CONTAINS = pattern ->
             new PathPatternOption(pattern,
                                   dirPath -> {
                                       checkArgument(Util.isValidDirPath(dirPath), "dirPath");

From 1ff349c58ef23ad17ebb052916cd46912c9fb3ba Mon Sep 17 00:00:00 2001
From: noodlze 
Date: Fri, 3 Mar 2023 15:27:49 +0700
Subject: [PATCH 28/39] Update
 common/src/main/java/com/linecorp/centraldogma/common/PathPatternOptions.java

Co-authored-by: Ikhun Um 
---
 .../com/linecorp/centraldogma/common/PathPatternOptions.java    | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/common/src/main/java/com/linecorp/centraldogma/common/PathPatternOptions.java b/common/src/main/java/com/linecorp/centraldogma/common/PathPatternOptions.java
index aec5095bdb..b3562a5557 100644
--- a/common/src/main/java/com/linecorp/centraldogma/common/PathPatternOptions.java
+++ b/common/src/main/java/com/linecorp/centraldogma/common/PathPatternOptions.java
@@ -75,7 +75,7 @@ private PathPatternOptions() {}
      * Prepends "/**/*" to {@code extension}.
      * Returns the path pattern for matching file(s) ending in {@code extension}.
      */
-    public static final Function EXTENSION = pattern ->
+    static final Function EXTENSION = pattern ->
             new PathPatternOption(pattern,
                                   extension -> {
                                       checkArgument(isValidFileExtension(extension), "extension");

From fe03245497d3ee95d947446238c4fd34fdd12017 Mon Sep 17 00:00:00 2001
From: noodlze 
Date: Fri, 3 Mar 2023 15:27:59 +0700
Subject: [PATCH 29/39] Update
 common/src/main/java/com/linecorp/centraldogma/common/PathPatternBuilder.java

Co-authored-by: Ikhun Um 
---
 .../com/linecorp/centraldogma/common/PathPatternBuilder.java     | 1 +
 1 file changed, 1 insertion(+)

diff --git a/common/src/main/java/com/linecorp/centraldogma/common/PathPatternBuilder.java b/common/src/main/java/com/linecorp/centraldogma/common/PathPatternBuilder.java
index 76b8471e16..1b2e71d1d1 100644
--- a/common/src/main/java/com/linecorp/centraldogma/common/PathPatternBuilder.java
+++ b/common/src/main/java/com/linecorp/centraldogma/common/PathPatternBuilder.java
@@ -60,6 +60,7 @@ public PathPatternBuilder endsWith(String filename) {
      * Adds {@link PathPatternOptions#EXTENSION}.
      */
     public PathPatternBuilder extension(String extension) {
+        requireNonNull(extension, "extension");
         endPattern = PathPatternOptions.EXTENSION.apply(extension);
         return this;
     }

From 6e6736000215cb51b4bc6d4e2013d3443b31a930 Mon Sep 17 00:00:00 2001
From: noodlze 
Date: Fri, 3 Mar 2023 15:28:15 +0700
Subject: [PATCH 30/39] Update
 common/src/main/java/com/linecorp/centraldogma/common/PathPatternOptions.java

Co-authored-by: Ikhun Um 
---
 .../com/linecorp/centraldogma/common/PathPatternOptions.java    | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/common/src/main/java/com/linecorp/centraldogma/common/PathPatternOptions.java b/common/src/main/java/com/linecorp/centraldogma/common/PathPatternOptions.java
index b3562a5557..a1fe3fffee 100644
--- a/common/src/main/java/com/linecorp/centraldogma/common/PathPatternOptions.java
+++ b/common/src/main/java/com/linecorp/centraldogma/common/PathPatternOptions.java
@@ -36,7 +36,7 @@ private PathPatternOptions() {}
      * Appends "/**" to {@code dirPath}.
      * Returns the path pattern for matching all file(s) under {@code dirPath}.
      */
-    public static final Function STARTS_WITH = pattern ->
+    static final Function STARTS_WITH = pattern ->
             new PathPatternOption(pattern,
                                   dirPath -> {
                                       checkArgument(Util.isValidDirPath(dirPath), "dir");

From dac0a50215e573ccf1b3d9ace3b74564130a5d0f Mon Sep 17 00:00:00 2001
From: Kate Pham 
Date: Fri, 3 Mar 2023 15:42:07 +0700
Subject: [PATCH 31/39] improvements to PathPatternBuilder

---
 .../linecorp/centraldogma/common/PathPatternBuilder.java  | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/common/src/main/java/com/linecorp/centraldogma/common/PathPatternBuilder.java b/common/src/main/java/com/linecorp/centraldogma/common/PathPatternBuilder.java
index 1b2e71d1d1..7342049046 100644
--- a/common/src/main/java/com/linecorp/centraldogma/common/PathPatternBuilder.java
+++ b/common/src/main/java/com/linecorp/centraldogma/common/PathPatternBuilder.java
@@ -15,8 +15,9 @@
  */
 package com.linecorp.centraldogma.common;
 
-import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkState;
 import static com.google.common.collect.ImmutableList.toImmutableList;
+import static java.util.Objects.requireNonNull;
 
 import java.util.ArrayList;
 import java.util.Iterator;
@@ -52,6 +53,7 @@ public final class PathPatternBuilder {
      * Adds {@link PathPatternOptions#ENDS_WITH}.
      */
     public PathPatternBuilder endsWith(String filename) {
+        requireNonNull(filename, "filename");
         endPattern = PathPatternOptions.ENDS_WITH.apply(filename);
         return this;
     }
@@ -69,6 +71,7 @@ public PathPatternBuilder extension(String extension) {
      * Adds {@link PathPatternOptions#STARTS_WITH}.
      */
     public PathPatternBuilder startsWith(String dirPath) {
+        requireNonNull(dirPath, "dirPath");
         startPattern = PathPatternOptions.STARTS_WITH.apply(dirPath);
         return this;
     }
@@ -77,6 +80,7 @@ public PathPatternBuilder startsWith(String dirPath) {
      * Adds {@link PathPatternOptions#CONTAINS}.
      */
     public PathPatternBuilder contains(String dirPath) {
+        requireNonNull(dirPath, "dirPath");
         innerPatterns.add(PathPatternOptions.CONTAINS.apply(dirPath));
         return this;
     }
@@ -112,7 +116,7 @@ public PathPattern build() {
         }
         final ImmutableList options = optionsBuilder.build();
 
-        checkArgument(!options.isEmpty(), "Requires at least one pattern to build in PathPatternBuilder");
+        checkState(!options.isEmpty(), "Requires at least one pattern to build in PathPatternBuilder");
 
         if (options.size() == 1) {
             return options.get(0).pathPattern();

From fe145a02734f79a28a2cc3128b959fdb9062b572 Mon Sep 17 00:00:00 2001
From: Kate Pham 
Date: Mon, 6 Mar 2023 21:23:31 +0700
Subject: [PATCH 32/39] rename extension-> hasExtension, add javadoc to
 PathPatternBuilder options: endsWith, startsWith, contains and hasExtension

---
 .../centraldogma/common/PathPattern.java      |  2 +-
 .../common/PathPatternBuilder.java            | 35 +++++++++++++++----
 .../common/PathPatternBuilderTest.java        | 10 +++---
 3 files changed, 35 insertions(+), 12 deletions(-)

diff --git a/common/src/main/java/com/linecorp/centraldogma/common/PathPattern.java b/common/src/main/java/com/linecorp/centraldogma/common/PathPattern.java
index ed8c1fdbe7..0980fa7c92 100644
--- a/common/src/main/java/com/linecorp/centraldogma/common/PathPattern.java
+++ b/common/src/main/java/com/linecorp/centraldogma/common/PathPattern.java
@@ -103,7 +103,7 @@ static PathPattern contains(String dirPath) {
      * Returns the path pattern for file(s) with {@code extension}.
      */
     static PathPattern extension(String extension) {
-        return builder().extension(extension).build();
+        return builder().hasExtension(extension).build();
     }
 
     /**
diff --git a/common/src/main/java/com/linecorp/centraldogma/common/PathPatternBuilder.java b/common/src/main/java/com/linecorp/centraldogma/common/PathPatternBuilder.java
index 7342049046..b01f74542f 100644
--- a/common/src/main/java/com/linecorp/centraldogma/common/PathPatternBuilder.java
+++ b/common/src/main/java/com/linecorp/centraldogma/common/PathPatternBuilder.java
@@ -36,7 +36,7 @@
  *         PathPattern.builder()
  *                    .startsWith("/foo/bar")
  *                    .contains("/ext")
- *                    .extension("json")
+ *                    .hasExtension("json")
  *                    .build();
  * }
*/ @@ -50,7 +50,14 @@ public final class PathPatternBuilder { PathPatternBuilder() {} /** - * Adds {@link PathPatternOptions#ENDS_WITH}. + * Ensures the file name component matches the specified {@code filename}. + * For example, `endWith("foo.txt")` will match `/foo.txt`, `/alice/foo.txt` and + * `/alice/bob/foo.txt`, but not `/barfoo.txt`. + * + *

This option can only be specified once; multiple declarations will override one another. + * + *

Note: that this option and {@link PathPatternBuilder#hasExtension(String)} are mutually exclusive. + * When both are specified, the latter-most option will override the former. */ public PathPatternBuilder endsWith(String filename) { requireNonNull(filename, "filename"); @@ -59,16 +66,27 @@ public PathPatternBuilder endsWith(String filename) { } /** - * Adds {@link PathPatternOptions#EXTENSION}. + * Ensures the file extension component matches the specified {@code extension}. + * For example, `hasExtension("json")` will match `mux.json`, `/bar/mux.json` and + * `/alice/bar/mux.json` but not `/json.txt`. + * + *

This option can only be specified once; multiple declarations will override one another. + * + *

Note: that this option and {@link PathPatternBuilder#endsWith(String)} are mutually exclusive. + * When both are specified, the latter-most option will override the former. */ - public PathPatternBuilder extension(String extension) { + public PathPatternBuilder hasExtension(String extension) { requireNonNull(extension, "extension"); endPattern = PathPatternOptions.EXTENSION.apply(extension); return this; } /** - * Adds {@link PathPatternOptions#STARTS_WITH}. + * Ensures the directory path starts with the specified {@code dirPath}. + * For example, `startsWith("/foo")` will match `/foo/test.zip`, `/foo/bar/test.zip` + * but not `/nix/foo/test.zip`. + * + *

This option can only be specified once; multiple declarations will override one another. */ public PathPatternBuilder startsWith(String dirPath) { requireNonNull(dirPath, "dirPath"); @@ -77,7 +95,12 @@ public PathPatternBuilder startsWith(String dirPath) { } /** - * Adds {@link PathPatternOptions#CONTAINS}. + * Ensures the directory path contains the specified {@code dirPath}. + * For example, `contains("/bar")` will match `/nix/bar/test.zip`, `/nix/quix/bar/twee/test.zip` + * but not `/bar/foo/test.zip` or `/ren/bar.json`. + * + *

This option can be specified multiple times. For example, chaining `contains("/bar").contains("foo")` + * creates the glob-like pattern string `/**/bar/**/foo/**". */ public PathPatternBuilder contains(String dirPath) { requireNonNull(dirPath, "dirPath"); diff --git a/common/src/test/java/com/linecorp/centraldogma/common/PathPatternBuilderTest.java b/common/src/test/java/com/linecorp/centraldogma/common/PathPatternBuilderTest.java index 62c163f754..3f303244e6 100644 --- a/common/src/test/java/com/linecorp/centraldogma/common/PathPatternBuilderTest.java +++ b/common/src/test/java/com/linecorp/centraldogma/common/PathPatternBuilderTest.java @@ -29,7 +29,7 @@ void testSingleOption() { .patternString()).isEqualTo("/**/foo.json"); assertThat(PathPattern.builder().contains("/bar").build() .patternString()).isEqualTo("/**/bar/**"); - assertThat(PathPattern.builder().extension("json").build() + assertThat(PathPattern.builder().hasExtension("json").build() .patternString()).isEqualTo("/**/*.json"); } @@ -43,19 +43,19 @@ void testPathPatternBuilder() { assertThat(PathPattern.builder() .startsWith("/foo") .contains("/bar/") - .extension("json") + .hasExtension("json") .build() .patternString()).isEqualTo("/foo/**/bar/**/*.json"); assertThat(PathPattern.builder() .startsWith("/foo") .endsWith("qux.json") - .extension("json") + .hasExtension("json") .build() .patternString()).isEqualTo("/foo/**/*.json"); assertThat(PathPattern.builder() .startsWith("/foo") - .extension("json") + .hasExtension("json") .endsWith("qux.json") .build() .patternString()).isEqualTo("/foo/**/qux.json"); @@ -68,7 +68,7 @@ void testPathPatternBuilder() { assertThat(PathPattern.builder() .startsWith("/foo/bar") .startsWith("/override") - .extension("json") + .hasExtension("json") .build() .patternString()).isEqualTo("/override/**/*.json"); } From aff50dd493b7bc68697786d6b4501d0954b8552d Mon Sep 17 00:00:00 2001 From: Kate Pham Date: Mon, 6 Mar 2023 21:26:35 +0700 Subject: [PATCH 33/39] rename PathPattern#extension-> hasExtension --- .../main/java/com/linecorp/centraldogma/common/PathPattern.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/src/main/java/com/linecorp/centraldogma/common/PathPattern.java b/common/src/main/java/com/linecorp/centraldogma/common/PathPattern.java index 0980fa7c92..c89f314df9 100644 --- a/common/src/main/java/com/linecorp/centraldogma/common/PathPattern.java +++ b/common/src/main/java/com/linecorp/centraldogma/common/PathPattern.java @@ -102,7 +102,7 @@ static PathPattern contains(String dirPath) { /** * Returns the path pattern for file(s) with {@code extension}. */ - static PathPattern extension(String extension) { + static PathPattern hasExtension(String extension) { return builder().hasExtension(extension).build(); } From 43aaa0c4098a5c54623e61c86af77ef1dfda769d Mon Sep 17 00:00:00 2001 From: Kate Pham Date: Mon, 6 Mar 2023 21:47:18 +0700 Subject: [PATCH 34/39] fix file extension regex and add test for regex matcher --- .../centraldogma/common/PathPatternOptions.java | 2 +- .../centraldogma/common/PathPatternBuilderTest.java | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/common/src/main/java/com/linecorp/centraldogma/common/PathPatternOptions.java b/common/src/main/java/com/linecorp/centraldogma/common/PathPatternOptions.java index a1fe3fffee..d7280eb341 100644 --- a/common/src/main/java/com/linecorp/centraldogma/common/PathPatternOptions.java +++ b/common/src/main/java/com/linecorp/centraldogma/common/PathPatternOptions.java @@ -28,7 +28,7 @@ */ final class PathPatternOptions { - private static final Pattern FILE_EXTENSION_PATTERN = Pattern.compile("^.{0,1}[0-9a-z]+$"); + private static final Pattern FILE_EXTENSION_PATTERN = Pattern.compile("^\\.{0,1}[0-9a-zA-Z]+$"); private PathPatternOptions() {} diff --git a/common/src/test/java/com/linecorp/centraldogma/common/PathPatternBuilderTest.java b/common/src/test/java/com/linecorp/centraldogma/common/PathPatternBuilderTest.java index 3f303244e6..4ab5f82ee0 100644 --- a/common/src/test/java/com/linecorp/centraldogma/common/PathPatternBuilderTest.java +++ b/common/src/test/java/com/linecorp/centraldogma/common/PathPatternBuilderTest.java @@ -16,10 +16,22 @@ package com.linecorp.centraldogma.common; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.AssertionsForClassTypes.assertThatNoException; +import static org.assertj.core.api.AssertionsForClassTypes.assertThatThrownBy; import org.junit.jupiter.api.Test; class PathPatternBuilderTest { + @Test + void testExtensionPattern() { + assertThatNoException().isThrownBy(() -> PathPatternOptions.EXTENSION.apply(".JPG").pathPattern()); + assertThatNoException().isThrownBy(() -> PathPatternOptions.EXTENSION.apply(".7z").pathPattern()); + + assertThatThrownBy(() -> PathPatternOptions.EXTENSION.apply("가txt").pathPattern()) + .isInstanceOf(IllegalArgumentException.class); + assertThatThrownBy(() -> PathPatternOptions.EXTENSION.apply("..tx.t").pathPattern()) + .isInstanceOf(IllegalArgumentException.class); + } @Test void testSingleOption() { From 09a4e3a9413f7c7250034b943bb07a1d75f6874b Mon Sep 17 00:00:00 2001 From: Kate Pham Date: Mon, 6 Mar 2023 22:06:30 +0700 Subject: [PATCH 35/39] improve PathPattern#of that accepts pathPattern(s) --- .../java/com/linecorp/centraldogma/common/PathPattern.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/common/src/main/java/com/linecorp/centraldogma/common/PathPattern.java b/common/src/main/java/com/linecorp/centraldogma/common/PathPattern.java index c89f314df9..c48242b8b7 100644 --- a/common/src/main/java/com/linecorp/centraldogma/common/PathPattern.java +++ b/common/src/main/java/com/linecorp/centraldogma/common/PathPattern.java @@ -15,6 +15,7 @@ */ package com.linecorp.centraldogma.common; +import static com.google.common.base.Preconditions.checkArgument; import static com.linecorp.centraldogma.common.DefaultPathPattern.ALL; import static com.linecorp.centraldogma.common.DefaultPathPattern.allPattern; import static java.util.Objects.requireNonNull; @@ -62,7 +63,10 @@ static PathPattern of(String... patterns) { * Creates a path pattern with the {@code pathPatterns}. */ static PathPattern of(PathPattern... pathPatterns) { - requireNonNull(pathPatterns, "pathPatterns"); + checkArgument(pathPatterns.length > 0, "pathPatterns"); + if (pathPatterns.length == 1) { + return pathPatterns[0]; + } return new DefaultPathPattern(ImmutableList.copyOf(pathPatterns)); } From 7c875633d5347efe91023e9ac0470d2506e6aea2 Mon Sep 17 00:00:00 2001 From: Kate Pham Date: Tue, 7 Mar 2023 06:11:11 +0700 Subject: [PATCH 36/39] minor edits to javadoc of PathPatternBuilder options --- .../linecorp/centraldogma/common/PathPatternBuilder.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/common/src/main/java/com/linecorp/centraldogma/common/PathPatternBuilder.java b/common/src/main/java/com/linecorp/centraldogma/common/PathPatternBuilder.java index b01f74542f..b0801036d1 100644 --- a/common/src/main/java/com/linecorp/centraldogma/common/PathPatternBuilder.java +++ b/common/src/main/java/com/linecorp/centraldogma/common/PathPatternBuilder.java @@ -56,7 +56,7 @@ public final class PathPatternBuilder { * *

This option can only be specified once; multiple declarations will override one another. * - *

Note: that this option and {@link PathPatternBuilder#hasExtension(String)} are mutually exclusive. + *

Note: this option and {@link PathPatternBuilder#hasExtension(String)} are mutually exclusive. * When both are specified, the latter-most option will override the former. */ public PathPatternBuilder endsWith(String filename) { @@ -72,7 +72,7 @@ public PathPatternBuilder endsWith(String filename) { * *

This option can only be specified once; multiple declarations will override one another. * - *

Note: that this option and {@link PathPatternBuilder#endsWith(String)} are mutually exclusive. + *

Note: this option and {@link PathPatternBuilder#endsWith(String)} are mutually exclusive. * When both are specified, the latter-most option will override the former. */ public PathPatternBuilder hasExtension(String extension) { @@ -99,7 +99,8 @@ public PathPatternBuilder startsWith(String dirPath) { * For example, `contains("/bar")` will match `/nix/bar/test.zip`, `/nix/quix/bar/twee/test.zip` * but not `/bar/foo/test.zip` or `/ren/bar.json`. * - *

This option can be specified multiple times. For example, chaining `contains("/bar").contains("foo")` + *

This option can be specified multiple times; multiple declarations will be chained. + * For example, `contains("/bar").contains("foo")` * creates the glob-like pattern string `/**/bar/**/foo/**". */ public PathPatternBuilder contains(String dirPath) { From 49b5d3f9b25aad701387295be0dbaa7dedb43559 Mon Sep 17 00:00:00 2001 From: noodlze Date: Sun, 19 Mar 2023 19:13:08 +0700 Subject: [PATCH 37/39] Update common/src/main/java/com/linecorp/centraldogma/common/PathPattern.java Co-authored-by: Trustin Lee --- .../java/com/linecorp/centraldogma/common/PathPattern.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/common/src/main/java/com/linecorp/centraldogma/common/PathPattern.java b/common/src/main/java/com/linecorp/centraldogma/common/PathPattern.java index c48242b8b7..3b1786aa79 100644 --- a/common/src/main/java/com/linecorp/centraldogma/common/PathPattern.java +++ b/common/src/main/java/com/linecorp/centraldogma/common/PathPattern.java @@ -63,7 +63,8 @@ static PathPattern of(String... patterns) { * Creates a path pattern with the {@code pathPatterns}. */ static PathPattern of(PathPattern... pathPatterns) { - checkArgument(pathPatterns.length > 0, "pathPatterns"); + requireNonNull(pathPatterns, "pathPatterns"); + checkArgument(pathPatterns.length > 0, "pathPatterns is empty."); if (pathPatterns.length == 1) { return pathPatterns[0]; } From 0d85d789ca5e49806c1c421c7fa37f8865f2abb1 Mon Sep 17 00:00:00 2001 From: Kate Pham Date: Sun, 19 Mar 2023 21:53:00 +0700 Subject: [PATCH 38/39] improve DefaultPathPattern constructor accepting PathPattern(s) --- .../centraldogma/common/DefaultPathPattern.java | 12 +++++++----- .../linecorp/centraldogma/common/PathPattern.java | 3 +-- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/common/src/main/java/com/linecorp/centraldogma/common/DefaultPathPattern.java b/common/src/main/java/com/linecorp/centraldogma/common/DefaultPathPattern.java index 72edf6cbbb..f29a51f7b1 100644 --- a/common/src/main/java/com/linecorp/centraldogma/common/DefaultPathPattern.java +++ b/common/src/main/java/com/linecorp/centraldogma/common/DefaultPathPattern.java @@ -16,8 +16,9 @@ package com.linecorp.centraldogma.common; import static com.google.common.base.Preconditions.checkArgument; +import static java.util.Objects.requireNonNull; -import java.util.List; +import java.util.Arrays; import java.util.Set; import java.util.regex.Pattern; import java.util.stream.Collectors; @@ -49,10 +50,11 @@ final class DefaultPathPattern implements PathPattern { .collect(Collectors.joining(",")); } - DefaultPathPattern(List verifiedPatterns) { - patterns = verifiedPatterns.stream() - .map(PathPattern::patternString) - .collect(Collectors.joining(",")); + DefaultPathPattern(PathPattern... verifiedPatterns) { + requireNonNull(verifiedPatterns, "verifiedPatterns"); + patterns = Arrays.stream(verifiedPatterns) + .map(PathPattern::patternString) + .collect(Collectors.joining(",")); } DefaultPathPattern(String pattern) { diff --git a/common/src/main/java/com/linecorp/centraldogma/common/PathPattern.java b/common/src/main/java/com/linecorp/centraldogma/common/PathPattern.java index 3b1786aa79..2387e86aa0 100644 --- a/common/src/main/java/com/linecorp/centraldogma/common/PathPattern.java +++ b/common/src/main/java/com/linecorp/centraldogma/common/PathPattern.java @@ -20,7 +20,6 @@ import static com.linecorp.centraldogma.common.DefaultPathPattern.allPattern; import static java.util.Objects.requireNonNull; -import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Streams; @@ -68,7 +67,7 @@ static PathPattern of(PathPattern... pathPatterns) { if (pathPatterns.length == 1) { return pathPatterns[0]; } - return new DefaultPathPattern(ImmutableList.copyOf(pathPatterns)); + return new DefaultPathPattern(pathPatterns); } /** From 53ebe9f328c1ebb90c51a5d79a7a99287c38ed9d Mon Sep 17 00:00:00 2001 From: Kate Pham Date: Sun, 19 Mar 2023 22:11:33 +0700 Subject: [PATCH 39/39] dissolve PathPatternOptions and PathPatternOption, merge with PathPatternBuilder --- .../common/PathPatternBuilder.java | 55 +++++++---- .../common/PathPatternOption.java | 42 --------- .../common/PathPatternOptions.java | 93 ------------------- .../common/PathPatternBuilderTest.java | 8 +- 4 files changed, 40 insertions(+), 158 deletions(-) delete mode 100644 common/src/main/java/com/linecorp/centraldogma/common/PathPatternOption.java delete mode 100644 common/src/main/java/com/linecorp/centraldogma/common/PathPatternOptions.java diff --git a/common/src/main/java/com/linecorp/centraldogma/common/PathPatternBuilder.java b/common/src/main/java/com/linecorp/centraldogma/common/PathPatternBuilder.java index b0801036d1..371305a7f1 100644 --- a/common/src/main/java/com/linecorp/centraldogma/common/PathPatternBuilder.java +++ b/common/src/main/java/com/linecorp/centraldogma/common/PathPatternBuilder.java @@ -15,18 +15,21 @@ */ package com.linecorp.centraldogma.common; +import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkState; -import static com.google.common.collect.ImmutableList.toImmutableList; import static java.util.Objects.requireNonNull; import java.util.ArrayList; import java.util.Iterator; import java.util.List; +import java.util.regex.Pattern; import javax.annotation.Nullable; import com.google.common.collect.ImmutableList; +import com.linecorp.centraldogma.internal.Util; + /** * Builds a new {@link PathPattern}. * @@ -41,11 +44,14 @@ * } */ public final class PathPatternBuilder { + + private static final Pattern FILE_EXTENSION_PATTERN = Pattern.compile("^\\.{0,1}[0-9a-zA-Z]+$"); + @Nullable - private PathPatternOption startPattern; - private final List innerPatterns = new ArrayList<>(); + private PathPattern startPattern; + private final List innerPatterns = new ArrayList<>(); @Nullable - private PathPatternOption endPattern; + private PathPattern endPattern; PathPatternBuilder() {} @@ -60,8 +66,9 @@ public final class PathPatternBuilder { * When both are specified, the latter-most option will override the former. */ public PathPatternBuilder endsWith(String filename) { - requireNonNull(filename, "filename"); - endPattern = PathPatternOptions.ENDS_WITH.apply(filename); + checkArgument(Util.isValidFileName(filename), "filename"); + // "/**" is added by the constructor of `DefaultPathPattern` + endPattern = new DefaultPathPattern(filename); return this; } @@ -76,8 +83,12 @@ public PathPatternBuilder endsWith(String filename) { * When both are specified, the latter-most option will override the former. */ public PathPatternBuilder hasExtension(String extension) { - requireNonNull(extension, "extension"); - endPattern = PathPatternOptions.EXTENSION.apply(extension); + checkArgument(isValidFileExtension(extension), "invalid extension."); + if (extension.startsWith(".")) { + endPattern = new DefaultPathPattern("/**/*" + extension); + } else { // add extension separator + endPattern = new DefaultPathPattern("/**/*." + extension); + } return this; } @@ -89,8 +100,9 @@ public PathPatternBuilder hasExtension(String extension) { *

This option can only be specified once; multiple declarations will override one another. */ public PathPatternBuilder startsWith(String dirPath) { - requireNonNull(dirPath, "dirPath"); - startPattern = PathPatternOptions.STARTS_WITH.apply(dirPath); + checkArgument(Util.isValidDirPath(dirPath), "dir"); + // appends "/**" + startPattern = new DefaultPathPattern(dirPath + (dirPath.endsWith("/") ? "" : "/") + "**"); return this; } @@ -104,8 +116,11 @@ public PathPatternBuilder startsWith(String dirPath) { * creates the glob-like pattern string `/**/bar/**/foo/**". */ public PathPatternBuilder contains(String dirPath) { - requireNonNull(dirPath, "dirPath"); - innerPatterns.add(PathPatternOptions.CONTAINS.apply(dirPath)); + checkArgument(Util.isValidDirPath(dirPath), "dirPath"); + // Prepends and appends "/**" + final PathPattern contain = new DefaultPathPattern("/**" + dirPath + + (dirPath.endsWith("/") ? "" : "/") + "**"); + innerPatterns.add(contain); return this; } @@ -130,7 +145,7 @@ private static String combine(List patterns) { * Returns a newly-created {@link PathPattern} based on the options of this builder. */ public PathPattern build() { - final ImmutableList.Builder optionsBuilder = ImmutableList.builder(); + final ImmutableList.Builder optionsBuilder = ImmutableList.builder(); if (startPattern != null) { optionsBuilder.add(startPattern); } @@ -138,17 +153,19 @@ public PathPattern build() { if (endPattern != null) { optionsBuilder.add(endPattern); } - final ImmutableList options = optionsBuilder.build(); + final ImmutableList options = optionsBuilder.build(); checkState(!options.isEmpty(), "Requires at least one pattern to build in PathPatternBuilder"); if (options.size() == 1) { - return options.get(0).pathPattern(); + return options.get(0); } + return new DefaultPathPattern(combine(options)); + } - final List patterns = options.stream() - .map(PathPatternOption::pathPattern) - .collect(toImmutableList()); - return new DefaultPathPattern(combine(patterns)); + private static boolean isValidFileExtension(String extension) { + requireNonNull(extension, "extension"); + checkArgument(!extension.isEmpty(), "extension is empty."); + return FILE_EXTENSION_PATTERN.matcher(extension).matches(); } } diff --git a/common/src/main/java/com/linecorp/centraldogma/common/PathPatternOption.java b/common/src/main/java/com/linecorp/centraldogma/common/PathPatternOption.java deleted file mode 100644 index 7b423d4a81..0000000000 --- a/common/src/main/java/com/linecorp/centraldogma/common/PathPatternOption.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2021 LINE Corporation - * - * LINE Corporation licenses this file to you under the Apache License, - * version 2.0 (the "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at: - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - */ -package com.linecorp.centraldogma.common; - -import java.util.function.Function; - -/** - * A {@link PathPatternBuilder} option. - */ -final class PathPatternOption { - private final String pattern; - /** - * Create {@link PathPattern} from {@code pattern}. - */ - private final Function pathPatternCreator; - - PathPatternOption(String pattern, - Function pathPatternCreator) { - this.pattern = pattern; - this.pathPatternCreator = pathPatternCreator; - } - - /** - * Returns the {@link PathPattern} of the option. - */ - PathPattern pathPattern() { - return pathPatternCreator.apply(pattern); - } -} diff --git a/common/src/main/java/com/linecorp/centraldogma/common/PathPatternOptions.java b/common/src/main/java/com/linecorp/centraldogma/common/PathPatternOptions.java deleted file mode 100644 index d7280eb341..0000000000 --- a/common/src/main/java/com/linecorp/centraldogma/common/PathPatternOptions.java +++ /dev/null @@ -1,93 +0,0 @@ -package com.linecorp.centraldogma.common; - -/* - * Copyright 2023 LINE Corporation - * - * LINE Corporation licenses this file to you under the Apache License, - * version 2.0 (the "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at: - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - */ - -import static com.google.common.base.Preconditions.checkArgument; - -import java.util.function.Function; -import java.util.regex.Pattern; - -import com.linecorp.centraldogma.internal.Util; - -/** - * A set of {@link PathPatternOption}s. - */ -final class PathPatternOptions { - - private static final Pattern FILE_EXTENSION_PATTERN = Pattern.compile("^\\.{0,1}[0-9a-zA-Z]+$"); - - private PathPatternOptions() {} - - /** - * Appends "/**" to {@code dirPath}. - * Returns the path pattern for matching all file(s) under {@code dirPath}. - */ - static final Function STARTS_WITH = pattern -> - new PathPatternOption(pattern, - dirPath -> { - checkArgument(Util.isValidDirPath(dirPath), "dir"); - return new DefaultPathPattern( - dirPath + (dirPath.endsWith("/") ? "" : "/") + "**"); - }); - - /** - * Prepends and appends "/**" to target {@code dirPath}. - * Returns the path pattern for matching all file(s) containing {@code dirPath}. - */ - static final Function CONTAINS = pattern -> - new PathPatternOption(pattern, - dirPath -> { - checkArgument(Util.isValidDirPath(dirPath), "dirPath"); - if (dirPath.endsWith("/")) { - return new DefaultPathPattern("/**" + dirPath + "**"); - } else { // add ending slash to dirPath - return new DefaultPathPattern("/**" + dirPath + "/**"); - } - }); - - /** - * Prepends "/**/" to {@code filename}. - * Returns the path pattern for matching file(s) ending in {@code filename}. - */ - static final Function ENDS_WITH = pattern -> - new PathPatternOption(pattern, - filename -> { - checkArgument(Util.isValidFileName(filename), "filename"); - // `/**` is added by the constructor of `DefaultPathPattern` - return new DefaultPathPattern(filename); - }); - - /** - * Prepends "/**/*" to {@code extension}. - * Returns the path pattern for matching file(s) ending in {@code extension}. - */ - static final Function EXTENSION = pattern -> - new PathPatternOption(pattern, - extension -> { - checkArgument(isValidFileExtension(extension), "extension"); - if (extension.startsWith(".")) { - return new DefaultPathPattern("/**/*" + extension); - } else { // add extension separator - return new DefaultPathPattern("/**/*." + extension); - } - }); - - private static boolean isValidFileExtension(String extension) { - checkArgument(!extension.isEmpty(), "extension"); - return FILE_EXTENSION_PATTERN.matcher(extension).matches(); - } -} diff --git a/common/src/test/java/com/linecorp/centraldogma/common/PathPatternBuilderTest.java b/common/src/test/java/com/linecorp/centraldogma/common/PathPatternBuilderTest.java index 4ab5f82ee0..85456ef191 100644 --- a/common/src/test/java/com/linecorp/centraldogma/common/PathPatternBuilderTest.java +++ b/common/src/test/java/com/linecorp/centraldogma/common/PathPatternBuilderTest.java @@ -24,12 +24,12 @@ class PathPatternBuilderTest { @Test void testExtensionPattern() { - assertThatNoException().isThrownBy(() -> PathPatternOptions.EXTENSION.apply(".JPG").pathPattern()); - assertThatNoException().isThrownBy(() -> PathPatternOptions.EXTENSION.apply(".7z").pathPattern()); + assertThatNoException().isThrownBy(() -> PathPattern.builder().hasExtension(".JPG")); + assertThatNoException().isThrownBy(() -> PathPattern.builder().hasExtension(".7z")); - assertThatThrownBy(() -> PathPatternOptions.EXTENSION.apply("가txt").pathPattern()) + assertThatThrownBy(() -> PathPattern.builder().hasExtension("가txt")) .isInstanceOf(IllegalArgumentException.class); - assertThatThrownBy(() -> PathPatternOptions.EXTENSION.apply("..tx.t").pathPattern()) + assertThatThrownBy(() -> PathPattern.builder().hasExtension("..tx.t")) .isInstanceOf(IllegalArgumentException.class); }