Refactor Patterns to PatternCache

This commit is contained in:
Luck 2017-05-07 13:56:42 +01:00
parent 65af3d0f54
commit cedc5108fc
No known key found for this signature in database
GPG Key ID: EFA9B3EC5FD90F8B
14 changed files with 72 additions and 66 deletions

View File

@ -30,7 +30,6 @@ import com.google.common.base.Splitter;
import me.lucko.luckperms.common.commands.CommandManager;
import me.lucko.luckperms.common.commands.utils.Util;
import me.lucko.luckperms.common.constants.Patterns;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
@ -53,7 +52,7 @@ public class BukkitCommand extends CommandManager implements CommandExecutor, Ta
onCommand(
plugin.getSenderFactory().wrap(sender),
label,
Util.stripQuotes(Splitter.on(Patterns.COMMAND_SEPARATOR).omitEmptyStrings().splitToList(Joiner.on(' ').join(args)))
Util.stripQuotes(Splitter.on(COMMAND_SEPARATOR_PATTERN).omitEmptyStrings().splitToList(Joiner.on(' ').join(args)))
);
return true;
}

View File

@ -30,7 +30,6 @@ import com.google.common.base.Splitter;
import me.lucko.luckperms.common.commands.CommandManager;
import me.lucko.luckperms.common.commands.utils.Util;
import me.lucko.luckperms.common.constants.Patterns;
import net.md_5.bungee.api.CommandSender;
import net.md_5.bungee.api.plugin.Command;
@ -53,7 +52,7 @@ class BungeeCommand extends Command implements TabExecutor {
manager.onCommand(
plugin.getSenderFactory().wrap(sender),
"lpb",
Util.stripQuotes(Splitter.on(Patterns.COMMAND_SEPARATOR).omitEmptyStrings().splitToList(Joiner.on(' ').join(args)))
Util.stripQuotes(Splitter.on(CommandManager.COMMAND_SEPARATOR_PATTERN).omitEmptyStrings().splitToList(Joiner.on(' ').join(args)))
);
}

View File

@ -27,24 +27,19 @@ package me.lucko.luckperms.common.calculators.processors;
import me.lucko.luckperms.api.Tristate;
import me.lucko.luckperms.common.calculators.PermissionProcessor;
import me.lucko.luckperms.common.constants.Patterns;
import me.lucko.luckperms.common.utils.PatternCache;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.regex.Pattern;
public class RegexProcessor implements PermissionProcessor {
private Map<String, Boolean> regexPermissions = new ConcurrentHashMap<>();
private Map<Pattern, Boolean> regexPermissions = new ConcurrentHashMap<>();
@Override
public Tristate hasPermission(String permission) {
for (Map.Entry<String, Boolean> e : regexPermissions.entrySet()) {
Pattern p = Patterns.compile(e.getKey());
if (p == null) {
continue;
}
if (p.matcher(permission).matches()) {
for (Map.Entry<Pattern, Boolean> e : regexPermissions.entrySet()) {
if (e.getKey().matcher(permission).matches()) {
return Tristate.fromBoolean(e.getValue());
}
}
@ -61,9 +56,13 @@ public class RegexProcessor implements PermissionProcessor {
}
String pattern = e.getKey().substring(2);
Patterns.compile(pattern); // Cache the lookup for later.
Pattern p = PatternCache.compile(pattern);
regexPermissions.put(pattern, e.getValue());
if (p == null) {
continue;
}
regexPermissions.put(p, e.getValue());
}
}
}

View File

@ -69,9 +69,11 @@ import java.util.Optional;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
public class CommandManager {
public static final Pattern COMMAND_SEPARATOR_PATTERN = Pattern.compile(" (?=([^\\\"]*\\\"[^\\\"]*\\\")*[^\\\"]*$)");
@Getter
private final LuckPermsPlugin plugin;

View File

@ -32,8 +32,8 @@ import me.lucko.luckperms.common.commands.CommandResult;
import me.lucko.luckperms.common.commands.abstraction.SubCommand;
import me.lucko.luckperms.common.commands.sender.Sender;
import me.lucko.luckperms.common.commands.utils.Util;
import me.lucko.luckperms.common.constants.DataConstraints;
import me.lucko.luckperms.common.constants.Message;
import me.lucko.luckperms.common.constants.Patterns;
import me.lucko.luckperms.common.constants.Permission;
import me.lucko.luckperms.common.data.Log;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
@ -105,7 +105,7 @@ public class LogRecent extends SubCommand<Log> {
u = Util.parseUuid(s);
if (u == null) {
if (s.length() <= 16) {
if (Patterns.NON_USERNAME.matcher(s).find()) {
if (!DataConstraints.PLAYER_USERNAME_TEST.test(s)) {
Message.USER_INVALID_ENTRY.send(sender, s);
return CommandResult.INVALID_ARGS;
}

View File

@ -32,8 +32,8 @@ import me.lucko.luckperms.common.commands.CommandResult;
import me.lucko.luckperms.common.commands.abstraction.SubCommand;
import me.lucko.luckperms.common.commands.sender.Sender;
import me.lucko.luckperms.common.commands.utils.Util;
import me.lucko.luckperms.common.constants.DataConstraints;
import me.lucko.luckperms.common.constants.Message;
import me.lucko.luckperms.common.constants.Patterns;
import me.lucko.luckperms.common.constants.Permission;
import me.lucko.luckperms.common.data.Log;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
@ -103,7 +103,7 @@ public class LogUserHistory extends SubCommand<Log> {
}
if (user.length() <= 16) {
if (Patterns.NON_USERNAME.matcher(user).find()) {
if (!DataConstraints.PLAYER_USERNAME_TEST.test(user)) {
Message.USER_INVALID_ENTRY.send(sender, user);
return CommandResult.INVALID_ARGS;
}

View File

@ -36,8 +36,8 @@ import me.lucko.luckperms.common.commands.impl.generic.parent.CommandParent;
import me.lucko.luckperms.common.commands.impl.generic.permission.CommandPermission;
import me.lucko.luckperms.common.commands.sender.Sender;
import me.lucko.luckperms.common.commands.utils.Util;
import me.lucko.luckperms.common.constants.DataConstraints;
import me.lucko.luckperms.common.constants.Message;
import me.lucko.luckperms.common.constants.Patterns;
import me.lucko.luckperms.common.core.model.User;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
@ -65,7 +65,7 @@ public class UserMainCommand extends MainCommand<User> {
UUID u = Util.parseUuid(target);
if (u == null) {
if (target.length() <= 16) {
if (Patterns.NON_USERNAME.matcher(target).find()) {
if (!DataConstraints.PLAYER_USERNAME_TEST.test(target)) {
Message.USER_INVALID_ENTRY.send(sender, target);
return null;
}

View File

@ -34,7 +34,6 @@ import me.lucko.luckperms.api.Tristate;
import me.lucko.luckperms.api.context.ContextSet;
import me.lucko.luckperms.common.commands.sender.Sender;
import me.lucko.luckperms.common.constants.Message;
import me.lucko.luckperms.common.constants.Patterns;
import io.github.mkremins.fanciful.FancyMessage;
@ -45,9 +44,11 @@ import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.UUID;
import java.util.regex.Pattern;
@UtilityClass
public class Util {
private static final Pattern STRIP_COLOR_PATTERN = Pattern.compile("(?i)" + String.valueOf('§') + "[0-9A-FK-OR]");
/**
* Sends a message to the sender, formatted with the plugin prefix and color scheme
@ -111,7 +112,7 @@ public class Util {
* @return the message without color
*/
public static String stripColor(String s) {
return s == null ? null : Patterns.STRIP_COLOR_PATTERN.matcher(s).replaceAll("");
return s == null ? null : STRIP_COLOR_PATTERN.matcher(s).replaceAll("");
}
public static <T> List<List<T>> divideList(Iterable<T> source, int size) {

View File

@ -34,18 +34,21 @@ import com.google.common.base.Splitter;
import me.lucko.luckperms.api.Node;
import me.lucko.luckperms.api.context.ContextSet;
import me.lucko.luckperms.api.context.MutableContextSet;
import me.lucko.luckperms.common.constants.Patterns;
import me.lucko.luckperms.common.core.model.ImmutableNode;
import me.lucko.luckperms.common.utils.PatternCache;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Pattern;
/**
* Builds Nodes
*/
@RequiredArgsConstructor(access = AccessLevel.PACKAGE)
class NodeBuilder implements Node.Builder {
private static final Pattern NODE_CONTEXTS_PATTERN = Pattern.compile("\\(.+\\).*");
private final String permission;
private final MutableContextSet extraContexts = MutableContextSet.create();
private Boolean value = true;
@ -58,15 +61,15 @@ class NodeBuilder implements Node.Builder {
if (!shouldConvertContexts) {
this.permission = permission;
} else {
if (!Patterns.NODE_CONTEXTS.matcher(permission).matches()) {
if (!NODE_CONTEXTS_PATTERN.matcher(permission).matches()) {
this.permission = permission;
} else {
List<String> contextParts = Splitter.on(Patterns.compileDelimitedMatcher(")", "\\")).limit(2).splitToList(permission.substring(1));
List<String> contextParts = Splitter.on(PatternCache.compileDelimitedMatcher(")", "\\")).limit(2).splitToList(permission.substring(1));
// 0 = context, 1 = node
this.permission = contextParts.get(1);
try {
Map<String, String> map = Splitter.on(Patterns.compileDelimitedMatcher(",", "\\")).withKeyValueSeparator(Splitter.on(Patterns.compileDelimitedMatcher("=", "\\"))).split(contextParts.get(0));
Map<String, String> map = Splitter.on(PatternCache.compileDelimitedMatcher(",", "\\")).withKeyValueSeparator(Splitter.on(PatternCache.compileDelimitedMatcher("=", "\\"))).split(contextParts.get(0));
for (Map.Entry<String, String> e : map.entrySet()) {
this.withExtraContext(NodeFactory.unescapeDelimiters(e.getKey(), "=", "(", ")", ","), NodeFactory.unescapeDelimiters(e.getValue(), "=", "(", ")", ","));
}

View File

@ -34,8 +34,8 @@ import com.google.common.base.Splitter;
import me.lucko.luckperms.api.MetaUtils;
import me.lucko.luckperms.api.Node;
import me.lucko.luckperms.api.context.ContextSet;
import me.lucko.luckperms.common.constants.Patterns;
import me.lucko.luckperms.common.core.model.Group;
import me.lucko.luckperms.common.utils.PatternCache;
import java.util.List;
import java.util.Map;
@ -65,18 +65,18 @@ public class NodeFactory {
public static Node.Builder builderFromSerializedNode(String s, Boolean b) {
// if contains /
if (Patterns.compileDelimitedMatcher("/", "\\").matcher(s).find()) {
List<String> parts = Splitter.on(Patterns.compileDelimitedMatcher("/", "\\")).limit(2).splitToList(s);
if (PatternCache.compileDelimitedMatcher("/", "\\").matcher(s).find()) {
List<String> parts = Splitter.on(PatternCache.compileDelimitedMatcher("/", "\\")).limit(2).splitToList(s);
// 0=server(+world) 1=node
// WORLD SPECIFIC
// if parts[0] contains -
if (Patterns.compileDelimitedMatcher("-", "\\").matcher(parts.get(0)).find()) {
List<String> serverParts = Splitter.on(Patterns.compileDelimitedMatcher("-", "\\")).limit(2).splitToList(parts.get(0));
if (PatternCache.compileDelimitedMatcher("-", "\\").matcher(parts.get(0)).find()) {
List<String> serverParts = Splitter.on(PatternCache.compileDelimitedMatcher("-", "\\")).limit(2).splitToList(parts.get(0));
// 0=server 1=world
// if parts[1] contains $
if (Patterns.compileDelimitedMatcher("$", "\\").matcher(parts.get(1)).find()) {
if (PatternCache.compileDelimitedMatcher("$", "\\").matcher(parts.get(1)).find()) {
List<String> tempParts = Splitter.on('$').limit(2).splitToList(parts.get(1));
return new NodeBuilder(tempParts.get(0), true).setServer(serverParts.get(0)).setWorld(serverParts.get(1))
.setExpiry(Long.parseLong(tempParts.get(1))).setValue(b);
@ -87,8 +87,8 @@ public class NodeFactory {
// SERVER BUT NOT WORLD SPECIFIC
// if parts[1] contains $
if (Patterns.compileDelimitedMatcher("$", "\\").matcher(parts.get(1)).find()) {
List<String> tempParts = Splitter.on(Patterns.compileDelimitedMatcher("$", "\\")).limit(2).splitToList(parts.get(1));
if (PatternCache.compileDelimitedMatcher("$", "\\").matcher(parts.get(1)).find()) {
List<String> tempParts = Splitter.on(PatternCache.compileDelimitedMatcher("$", "\\")).limit(2).splitToList(parts.get(1));
return new NodeBuilder(tempParts.get(0), true).setServer(parts.get(0)).setExpiry(Long.parseLong(tempParts.get(1))).setValue(b);
} else {
return new NodeBuilder(parts.get(1), true).setServer(parts.get(0)).setValue(b);
@ -98,8 +98,8 @@ public class NodeFactory {
// NOT SERVER SPECIFIC
// if s contains $
if (Patterns.compileDelimitedMatcher("$", "\\").matcher(s).find()) {
List<String> tempParts = Splitter.on(Patterns.compileDelimitedMatcher("$", "\\")).limit(2).splitToList(s);
if (PatternCache.compileDelimitedMatcher("$", "\\").matcher(s).find()) {
List<String> tempParts = Splitter.on(PatternCache.compileDelimitedMatcher("$", "\\")).limit(2).splitToList(s);
return new NodeBuilder(tempParts.get(0), true).setExpiry(Long.parseLong(tempParts.get(1))).setValue(b);
} else {
return new NodeBuilder(s, true).setValue(b);
@ -214,7 +214,7 @@ public class NodeFactory {
return false;
}
String parts = s.substring("meta.".length());
return Patterns.compileDelimitedMatcher(".", "\\").matcher(parts).find();
return PatternCache.compileDelimitedMatcher(".", "\\").matcher(parts).find();
}
private static boolean isChatMetaNode(String type, String s) {
@ -223,11 +223,11 @@ public class NodeFactory {
}
String parts = s.substring((type + ".").length());
if (!Patterns.compileDelimitedMatcher(".", "\\").matcher(parts).find()) {
if (!PatternCache.compileDelimitedMatcher(".", "\\").matcher(parts).find()) {
return false;
}
List<String> metaParts = Splitter.on(Patterns.compileDelimitedMatcher(".", "\\")).limit(2).splitToList(parts);
List<String> metaParts = Splitter.on(PatternCache.compileDelimitedMatcher(".", "\\")).limit(2).splitToList(parts);
String priority = metaParts.get(0);
try {
Integer.parseInt(priority);

View File

@ -40,8 +40,8 @@ import me.lucko.luckperms.api.Tristate;
import me.lucko.luckperms.api.context.ContextSet;
import me.lucko.luckperms.api.context.ImmutableContextSet;
import me.lucko.luckperms.api.context.MutableContextSet;
import me.lucko.luckperms.common.constants.Patterns;
import me.lucko.luckperms.common.core.NodeFactory;
import me.lucko.luckperms.common.utils.PatternCache;
import me.lucko.luckperms.common.utils.ShorthandParser;
import java.util.Collections;
@ -70,7 +70,7 @@ public final class ImmutableNode implements Node {
Set<String> expandedThisStr = ShorthandParser.parseShorthand(thisStr, false);
if (str.toLowerCase().startsWith("r=") && applyRegex) {
Pattern p = Patterns.compile(str.substring(2));
Pattern p = PatternCache.compile(str.substring(2));
if (p == null) {
return false;
}
@ -84,7 +84,7 @@ public final class ImmutableNode implements Node {
}
if (thisStr.toLowerCase().startsWith("r=") && applyRegex) {
Pattern p = Patterns.compile(thisStr.substring(2));
Pattern p = PatternCache.compile(thisStr.substring(2));
if (p == null) {
return false;
}
@ -231,20 +231,20 @@ public final class ImmutableNode implements Node {
isMeta = NodeFactory.isMetaNode(this.permission);
if (isMeta) {
List<String> metaPart = Splitter.on(Patterns.compileDelimitedMatcher(".", "\\")).limit(2).splitToList(getPermission().substring("meta.".length()));
List<String> metaPart = Splitter.on(PatternCache.compileDelimitedMatcher(".", "\\")).limit(2).splitToList(getPermission().substring("meta.".length()));
meta = Maps.immutableEntry(MetaUtils.unescapeCharacters(metaPart.get(0)), MetaUtils.unescapeCharacters(metaPart.get(1)));
}
isPrefix = NodeFactory.isPrefixNode(this.permission);
if (isPrefix) {
List<String> prefixPart = Splitter.on(Patterns.compileDelimitedMatcher(".", "\\")).limit(2).splitToList(getPermission().substring("prefix.".length()));
List<String> prefixPart = Splitter.on(PatternCache.compileDelimitedMatcher(".", "\\")).limit(2).splitToList(getPermission().substring("prefix.".length()));
Integer i = Integer.parseInt(prefixPart.get(0));
prefix = Maps.immutableEntry(i, MetaUtils.unescapeCharacters(prefixPart.get(1)));
}
isSuffix = NodeFactory.isSuffixNode(this.permission);
if (isSuffix) {
List<String> suffixPart = Splitter.on(Patterns.compileDelimitedMatcher(".", "\\")).limit(2).splitToList(getPermission().substring("suffix.".length()));
List<String> suffixPart = Splitter.on(PatternCache.compileDelimitedMatcher(".", "\\")).limit(2).splitToList(getPermission().substring("suffix.".length()));
Integer i = Integer.parseInt(suffixPart.get(0));
suffix = Maps.immutableEntry(i, MetaUtils.unescapeCharacters(suffixPart.get(1)));
}

View File

@ -38,7 +38,6 @@ import me.lucko.luckperms.common.commands.sender.Sender;
import me.lucko.luckperms.common.commands.utils.Util;
import me.lucko.luckperms.common.constants.Constants;
import me.lucko.luckperms.common.constants.Message;
import me.lucko.luckperms.common.constants.Patterns;
import me.lucko.luckperms.common.constants.Permission;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
@ -109,7 +108,7 @@ public class Importer implements Runnable {
CommandResult result = commandManager.onCommand(
fake,
"lp",
Util.stripQuotes(Splitter.on(Patterns.COMMAND_SEPARATOR).omitEmptyStrings().splitToList(command))
Util.stripQuotes(Splitter.on(CommandManager.COMMAND_SEPARATOR_PATTERN).omitEmptyStrings().splitToList(command))
).get();
getResult(index, command).setResult(result);

View File

@ -23,8 +23,9 @@
* SOFTWARE.
*/
package me.lucko.luckperms.common.constants;
package me.lucko.luckperms.common.utils;
import lombok.AllArgsConstructor;
import lombok.experimental.UtilityClass;
import com.github.benmanes.caffeine.cache.Caffeine;
@ -33,30 +34,29 @@ import com.google.common.collect.Maps;
import java.util.Map;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
@UtilityClass
public class Patterns {
private static final LoadingCache<String, Pattern> CACHE = Caffeine.newBuilder().build(Pattern::compile);
public class PatternCache {
private static final NullablePattern NULL_PATTERN = new NullablePattern(null);
private static final LoadingCache<String, NullablePattern> CACHE = Caffeine.newBuilder().build(s -> {
try {
return new NullablePattern(Pattern.compile(s));
} catch (PatternSyntaxException e) {
return NULL_PATTERN;
}
});
private static final LoadingCache<Map.Entry<String, String>, String> DELIMITER_CACHE = Caffeine.newBuilder()
.build(e -> {
// note the reversed order
return "(?<!" + Pattern.quote(e.getValue()) + ")" + Pattern.quote(e.getKey());
});
public static final Pattern COMMAND_SEPARATOR = Pattern.compile(" (?=([^\\\"]*\\\"[^\\\"]*\\\")*[^\\\"]*$)");
public static final Pattern NON_ALPHA_NUMERIC = Pattern.compile("[\\/\\$\\. ]");
public static final Pattern NON_ALPHA_NUMERIC_SPACE = Pattern.compile("[\\/\\$\\.]");
public static final Pattern NON_USERNAME = Pattern.compile("[^A-Za-z0-9_ ]");
public static final Pattern STRIP_COLOR_PATTERN = Pattern.compile("(?i)" + String.valueOf('§') + "[0-9A-FK-OR]");
public static final Pattern NODE_CONTEXTS = Pattern.compile("\\(.+\\).*");
public static Pattern compile(String regex) {
try {
return CACHE.get(regex);
} catch (Exception e) {
e.printStackTrace();
return null;
}
return CACHE.get(regex).pattern;
}
public static String buildDelimitedMatcher(String delim, String esc) {
@ -67,4 +67,9 @@ public class Patterns {
return compile(buildDelimitedMatcher(delim, esc));
}
@AllArgsConstructor
private static final class NullablePattern {
private final Pattern pattern;
}
}

View File

@ -29,7 +29,6 @@ import com.google.common.base.Splitter;
import me.lucko.luckperms.common.commands.CommandManager;
import me.lucko.luckperms.common.commands.utils.Util;
import me.lucko.luckperms.common.constants.Patterns;
import me.lucko.luckperms.sponge.timings.LPTiming;
import org.spongepowered.api.command.CommandCallable;
@ -62,7 +61,7 @@ class SpongeCommand extends CommandManager implements CommandCallable {
onCommand(
plugin.getSenderFactory().wrap(source),
"lp",
Util.stripQuotes(Splitter.on(Patterns.COMMAND_SEPARATOR).omitEmptyStrings().splitToList(s))
Util.stripQuotes(Splitter.on(COMMAND_SEPARATOR_PATTERN).omitEmptyStrings().splitToList(s))
);
return CommandResult.success();
}