-
Notifications
You must be signed in to change notification settings - Fork 130
Path pattern builder #809
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Path pattern builder #809
Changes from 24 commits
cb49cfa
dd52fb4
1e5be70
8a04af4
c709286
de9fe40
2ee5317
316bb2a
0376f6d
c799e63
f524a6d
5d610a0
1fd3bcd
dc5fd40
da40567
a53edb2
06662c6
986df3a
b460bfe
0cf67c9
9a2b815
67bb127
dbb142c
3f5ab60
33ccb30
96f14ce
469020d
1ff349c
fe03245
6e67360
dac0a50
fe145a0
aff50dd
43aaa0c
09a4e3a
7c87563
49b5d3f
0d85d78
53ebe9f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -19,6 +19,7 @@ | |||||
| 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; | ||||||
|
|
||||||
|
|
@@ -36,6 +37,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 +58,14 @@ 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"); | ||||||
noodlze marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
| return new DefaultPathPattern(ImmutableList.copyOf(pathPatterns)); | ||||||
|
||||||
| return new DefaultPathPattern(ImmutableList.copyOf(pathPatterns)); | |
| return new DefaultPathPattern(ImmutableSet.copyOf(pathPatterns)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Previously, a new constructor for DefaultPathPattern(List<PathPattern> verifiedPatterns) was introduced that would skip the validatePathPattern step.
I changed the argument type from List<PathPattern> -> varargs PathPattern... in commit 0d85d78.
noodlze marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,125 @@ | ||
| /* | ||
| * 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 com.google.common.collect.ImmutableList.toImmutableList; | ||
|
|
||
| import java.util.ArrayList; | ||
| import java.util.Iterator; | ||
| import java.util.List; | ||
|
|
||
| import javax.annotation.Nullable; | ||
|
|
||
| import com.google.common.collect.ImmutableList; | ||
|
|
||
| /** | ||
| * Builds a new {@link PathPattern}. | ||
| * | ||
| * <h2>Example</h2> | ||
| * <pre>{@code | ||
| * final PathPattern pathPattern = | ||
| * PathPattern.builder() | ||
| * .startsWith("/foo/bar") | ||
| * .contains("/ext") | ||
| * .extension("json") | ||
| * .build(); | ||
| * }</pre> | ||
| */ | ||
| public final class PathPatternBuilder { | ||
| @Nullable | ||
| private PathPatternOption startPattern; | ||
| private final List<PathPatternOption> innerPatterns = new ArrayList<>(); | ||
| @Nullable | ||
| private PathPatternOption endPattern; | ||
|
||
|
|
||
noodlze marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| PathPatternBuilder() {} | ||
|
|
||
| /** | ||
| * Adds {@link PathPatternOptions#ENDS_WITH}. | ||
noodlze marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| */ | ||
| public PathPatternBuilder endsWith(String filename) { | ||
| endPattern = PathPatternOptions.ENDS_WITH.apply(filename); | ||
| return this; | ||
| } | ||
|
|
||
| /** | ||
| * Adds {@link PathPatternOptions#EXTENSION}. | ||
| */ | ||
| public PathPatternBuilder extension(String extension) { | ||
noodlze marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| endPattern = PathPatternOptions.EXTENSION.apply(extension); | ||
noodlze marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| return this; | ||
| } | ||
|
|
||
| /** | ||
| * Adds {@link PathPatternOptions#STARTS_WITH}. | ||
| */ | ||
| public PathPatternBuilder startsWith(String dirPath) { | ||
| startPattern = PathPatternOptions.STARTS_WITH.apply(dirPath); | ||
| return this; | ||
| } | ||
|
|
||
| /** | ||
| * Adds {@link PathPatternOptions#CONTAINS}. | ||
| */ | ||
| public PathPatternBuilder contains(String dirPath) { | ||
| innerPatterns.add(PathPatternOptions.CONTAINS.apply(dirPath)); | ||
| return this; | ||
| } | ||
|
|
||
| /** | ||
| * Compose one pathPattern from a list of {@code patterns}. | ||
| */ | ||
| private static String combine(List<PathPattern> patterns) { | ||
| final StringBuilder sb = new StringBuilder(); | ||
| for (final Iterator<PathPattern> 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 sb.toString(); | ||
| } | ||
|
|
||
| /** | ||
| * Returns a newly-created {@link PathPattern} based on the options of this builder. | ||
| */ | ||
| public PathPattern build() { | ||
| final ImmutableList.Builder<PathPatternOption> optionsBuilder = ImmutableList.builder(); | ||
| if (startPattern != null) { | ||
| optionsBuilder.add(startPattern); | ||
| } | ||
| optionsBuilder.addAll(innerPatterns); | ||
| if (endPattern != null) { | ||
| optionsBuilder.add(endPattern); | ||
| } | ||
| final ImmutableList<PathPatternOption> options = optionsBuilder.build(); | ||
|
|
||
| checkArgument(!options.isEmpty(), "Requires at least one pattern to build in PathPatternBuilder"); | ||
noodlze marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| if (options.size() == 1) { | ||
| return options.get(0).pathPattern(); | ||
| } | ||
|
|
||
| final List<PathPattern> patterns = options.stream() | ||
| .map(PathPatternOption::pathPattern) | ||
| .collect(toImmutableList()); | ||
| return new DefaultPathPattern(combine(patterns)); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,42 @@ | ||
| /* | ||
| * 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<String, PathPattern> pathPatternCreator; | ||
|
|
||
| PathPatternOption(String pattern, | ||
| Function<String, PathPattern> pathPatternCreator) { | ||
| this.pattern = pattern; | ||
| this.pathPatternCreator = pathPatternCreator; | ||
| } | ||
|
|
||
| /** | ||
| * Returns the {@link PathPattern} of the option. | ||
| */ | ||
| PathPattern pathPattern() { | ||
| return pathPatternCreator.apply(pattern); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,93 @@ | ||
| 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-z]+$"); | ||
noodlze marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| private PathPatternOptions() {} | ||
|
|
||
| /** | ||
| * Appends "/**" to {@code dirPath}. | ||
| * Returns the path pattern for matching all file(s) under {@code dirPath}. | ||
| */ | ||
| public static final Function<String, PathPatternOption> STARTS_WITH = pattern -> | ||
noodlze marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| 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}. | ||
| */ | ||
| public static final Function<String, PathPatternOption> CONTAINS = pattern -> | ||
noodlze marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| 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}. | ||
| */ | ||
| public static final Function<String, PathPatternOption> ENDS_WITH = pattern -> | ||
noodlze marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| 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}. | ||
| */ | ||
| public static final Function<String, PathPatternOption> EXTENSION = pattern -> | ||
noodlze marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| 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(); | ||
| } | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.