org.vxwo.springboot.experience.web.matcher.GroupPathRuleMatcher Maven / Gradle / Ivy
package org.vxwo.springboot.experience.web.matcher;
import java.util.*;
import java.util.stream.Collectors;
import org.springframework.util.ObjectUtils;
import org.vxwo.springboot.experience.web.config.GroupPathRule;
import org.vxwo.springboot.experience.web.util.SplitUtil;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* @author vxwo-team
*/
public class GroupPathRuleMatcher implements PathRuleMatcher {
@Getter
@AllArgsConstructor
public static class ExcludesAndOptionals {
private List excludes;
private List optionals;
public boolean isExclude(String path) {
for (PathTester s : excludes) {
if (s.test(path)) {
return true;
}
}
return false;
}
public boolean isOptional(String path) {
for (PathTester s : optionals) {
if (s.test(path)) {
return true;
}
}
return false;
}
}
private final List> acceptPathTesters;
@SuppressWarnings("PMD.AvoidComplexConditionRule")
public GroupPathRuleMatcher(String configName, List pathRules) {
acceptPathTesters = new ArrayList<>();
if (ObjectUtils.isEmpty(pathRules)) {
throw new RuntimeException(String.format("Configuration: {%s} empty", configName));
}
Set excludeOrOptionalPathSet = new HashSet<>();
for (int i = 0; i < pathRules.size(); ++i) {
GroupPathRule pathRule = pathRules.get(i);
String configPathName = String.format("%s.[%d]", configName, i);
String path = pathRule.getPath();
if (ObjectUtils.isEmpty(path)) {
throw new RuntimeException(
String.format("Configuration: {%s.path} empty", configPathName));
}
if (PathTester.isPattern(path)) {
throw new RuntimeException(String
.format("Configuration: {%s.path} has pattern character", configPathName));
}
boolean existExcludes = !ObjectUtils.isEmpty(pathRule.getExcludes());
boolean existOptionals = !ObjectUtils.isEmpty(pathRule.getOptionals());
if ((existExcludes || existOptionals) && !path.endsWith("/")) {
throw new RuntimeException(String
.format("Configuration: {%s.path} not ends with '/'", configPathName));
}
List excludePathTesters = new ArrayList<>();
if (existExcludes) {
for (String exclude : SplitUtil.shrinkList(pathRule.getExcludes())) {
if (exclude.startsWith("/")) {
throw new RuntimeException(String.format(
"Configuration: {%s.excludes} starts with '/'", configPathName));
}
if (PathTester.isPattern(exclude)) {
throw new RuntimeException(
String.format("Configuration: {%s.excludes} has pattern character",
configPathName));
}
String excludePath = path + exclude;
PathTester matcher = new PathTester(excludePath);
if (!excludeOrOptionalPathSet.contains(excludePath)) {
excludePathTesters.add(matcher);
excludeOrOptionalPathSet.add(excludePath);
}
}
}
List optionalPathTesters = new ArrayList<>();
if (existOptionals) {
for (String optional : SplitUtil.shrinkList(pathRule.getOptionals())) {
if (optional.startsWith("/")) {
throw new RuntimeException(String.format(
"Configuration: {%s.optionals} starts with '/'", configPathName));
}
if (PathTester.isPattern(optional)) {
throw new RuntimeException(
String.format("Configuration: {%s.optionals} has pattern character",
configPathName));
}
String optionalPath = path + optional;
PathTester matcher = new PathTester(optionalPath);
if (!excludeOrOptionalPathSet.contains(optionalPath)) {
optionalPathTesters.add(matcher);
excludeOrOptionalPathSet.add(optionalPath);
}
}
}
acceptPathTesters.add(new TagPathTester<>(pathRule.getTag(), path,
new ExcludesAndOptionals(Collections.unmodifiableList(excludePathTesters),
Collections.unmodifiableList(optionalPathTesters))));
}
}
public TagPathTester findMatchTester(String path) {
for (TagPathTester tester : acceptPathTesters) {
if (tester.test(path)) {
return tester;
}
}
return null;
}
@Override
public String toString() {
StringBuffer sb = new StringBuffer();
sb.append(acceptPathTesters.size() + " paths");
for (TagPathTester tester : acceptPathTesters) {
sb.append("\n tag: " + tester.getTag() + ", path: " + tester.toPathMatch());
if (!ObjectUtils.isEmpty(tester.getExtra().getExcludes())) {
sb.append("\n excludes:\n" + String.join("\n", tester.getExtra().getExcludes()
.stream().map(o -> " " + o.toPathMatch()).collect(Collectors.toList())));
}
if (!ObjectUtils.isEmpty(tester.getExtra().getOptionals())) {
sb.append("\n optionals:\n" + String.join("\n", tester.getExtra().getOptionals()
.stream().map(o -> " " + o.toPathMatch()).collect(Collectors.toList())));
}
}
return sb.toString();
}
@Override
public List getPathMatchs(String tag) {
return acceptPathTesters.stream().filter(o -> o.getTag().equals(tag))
.map(o -> o.toPathMatch()).collect(Collectors.toList());
}
@Override
public List getExcludePathMatchs(String tag) {
List pathMatches = new ArrayList<>();
acceptPathTesters.stream().filter(o -> o.getTag().equals(tag)).forEach(o -> {
o.getExtra().getExcludes().stream().forEach(x -> pathMatches.add(x.toPathMatch()));
o.getExtra().getOptionals().stream().forEach(x -> pathMatches.add(x.toPathMatch()));
});
return pathMatches;
}
}