Context set values should be lowercase'd too

This commit is contained in:
Luck 2018-04-26 19:51:05 +01:00
parent 316e177c1d
commit fef6ebf793
No known key found for this signature in database
GPG Key ID: EFA9B3EC5FD90F8B
5 changed files with 15 additions and 108 deletions

View File

@ -68,27 +68,6 @@ abstract class AbstractContextSet implements ContextSet {
return backing().containsEntry(sanitizeKey(key), sanitizeValue(value)); return backing().containsEntry(sanitizeKey(key), sanitizeValue(value));
} }
@Override
public boolean hasIgnoreCase(@Nonnull String key, @Nonnull String value) {
String v = sanitizeValue(value);
Collection<String> values = backing().asMap().get(sanitizeKey(key));
if (values == null || values.isEmpty()) {
return false;
}
if (values.contains(v)) {
return true;
}
for (String val : values) {
if (val.equalsIgnoreCase(v)) {
return true;
}
}
return false;
}
@Override @Override
public boolean isEmpty() { public boolean isEmpty() {
return backing().isEmpty(); return backing().isEmpty();
@ -134,7 +113,7 @@ abstract class AbstractContextSet implements ContextSet {
if (stringIsEmpty(value)) { if (stringIsEmpty(value)) {
throw new IllegalArgumentException("value is (effectively) empty"); throw new IllegalArgumentException("value is (effectively) empty");
} }
return value; return value.toLowerCase();
} }
private static boolean stringIsEmpty(String s) { private static boolean stringIsEmpty(String s) {

View File

@ -47,9 +47,8 @@ import javax.annotation.Nonnull;
* <p>Contexts can be combined with each other to form so called * <p>Contexts can be combined with each other to form so called
* "context sets" - simply a collection of context pairs.</p> * "context sets" - simply a collection of context pairs.</p>
* *
* <p>Context keys are case-insensitive, and will be converted to * <p>Context keys and values are case-insensitive, and will be converted to
* {@link String#toLowerCase() lowercase} by all implementations. * {@link String#toLowerCase() lowercase} by all implementations.</p>
* Values however are case-sensitive.</p>
* *
* <p>Context keys and values may not be null or empty. A key/value will be * <p>Context keys and values may not be null or empty. A key/value will be
* deemed empty if it's length is zero, or if it consists of only space * deemed empty if it's length is zero, or if it consists of only space
@ -272,33 +271,16 @@ public interface ContextSet {
/** /**
* Returns if the {@link ContextSet} contains a given context pairing. * Returns if the {@link ContextSet} contains a given context pairing.
* *
* <p>This lookup is case-sensitive on the value.</p>
*
* @param key the key to look for * @param key the key to look for
* @param value the value to look for (case sensitive) * @param value the value to look for
* @return true if the set contains the context pair * @return true if the set contains the context pair
* @throws NullPointerException if the key or value is null * @throws NullPointerException if the key or value is null
*/ */
boolean has(@Nonnull String key, @Nonnull String value); boolean has(@Nonnull String key, @Nonnull String value);
/**
* Returns if the {@link ContextSet} contains a given context pairing,
* ignoring the case of values.
*
* <p>This lookup is case-insensitive on the value.</p>
*
* @param key the key to look for
* @param value the value to look for
* @return true if the set contains the context pair
* @throws NullPointerException if the key or value is null
*/
boolean hasIgnoreCase(@Nonnull String key, @Nonnull String value);
/** /**
* Returns if the {@link ContextSet} contains a given context pairing. * Returns if the {@link ContextSet} contains a given context pairing.
* *
* <p>This lookup is case-sensitive on the value.</p>
*
* @param entry the entry to look for * @param entry the entry to look for
* @return true if the set contains the context pair * @return true if the set contains the context pair
* @throws NullPointerException if the key or value is null * @throws NullPointerException if the key or value is null
@ -308,21 +290,6 @@ public interface ContextSet {
return has(entry.getKey(), entry.getValue()); return has(entry.getKey(), entry.getValue());
} }
/**
* Returns if the {@link ContextSet} contains a given context pairing,
* ignoring the case of values.
*
* <p>This lookup is case-insensitive on the value.</p>
*
* @param entry the entry to look for
* @return true if the set contains the context pair
* @throws NullPointerException if the key or value is null
*/
default boolean hasIgnoreCase(@Nonnull Map.Entry<String, String> entry) {
Objects.requireNonNull(entry, "entry");
return hasIgnoreCase(entry.getKey(), entry.getValue());
}
/** /**
* Returns if this {@link ContextSet} is fully "satisfied" by another set. * Returns if this {@link ContextSet} is fully "satisfied" by another set.
* *
@ -331,31 +298,11 @@ public interface ContextSet {
* *
* <p>Mathematically, this method returns true if this set is a <b>subset</b> of the other.</p> * <p>Mathematically, this method returns true if this set is a <b>subset</b> of the other.</p>
* *
* <p>This check is case-sensitive. For a case-insensitive check,
* use {@link #isSatisfiedBy(ContextSet, boolean)}.</p>
*
* @param other the other set to check * @param other the other set to check
* @return true if all entries in this set are also in the other set * @return true if all entries in this set are also in the other set
* @since 3.1 * @since 3.1
*/ */
default boolean isSatisfiedBy(@Nonnull ContextSet other) { default boolean isSatisfiedBy(@Nonnull ContextSet other) {
return isSatisfiedBy(other, true);
}
/**
* Returns if this {@link ContextSet} is fully "satisfied" by another set.
*
* <p>For a context set to "satisfy" another, it must itself contain all of
* the context pairings in the other set.</p>
*
* <p>Mathematically, this method returns true if this set is a <b>subset</b> of the other.</p>
*
* @param other the other set to check
* @param caseSensitive if the check should be case sensitive
* @return true if all entries in this set are also in the other set
* @since 3.4
*/
default boolean isSatisfiedBy(@Nonnull ContextSet other, boolean caseSensitive) {
if (this == other) { if (this == other) {
return true; return true;
} }
@ -373,15 +320,9 @@ public interface ContextSet {
} else { } else {
// neither are empty, we need to compare the individual entries // neither are empty, we need to compare the individual entries
for (Map.Entry<String, String> context : toSet()) { for (Map.Entry<String, String> context : toSet()) {
if (caseSensitive) {
if (!other.has(context)) { if (!other.has(context)) {
return false; return false;
} }
} else {
if (!other.hasIgnoreCase(context)) {
return false;
}
}
} }
return true; return true;
} }

View File

@ -32,7 +32,6 @@ import com.google.common.collect.Multimap;
import com.google.common.collect.Multimaps; import com.google.common.collect.Multimaps;
import com.google.common.collect.SetMultimap; import com.google.common.collect.SetMultimap;
import java.util.Collection;
import java.util.Map; import java.util.Map;
import java.util.Objects; import java.util.Objects;
import java.util.Set; import java.util.Set;
@ -282,28 +281,13 @@ public final class MutableContextSet extends AbstractContextSet implements Conte
* Removes a context from this set. * Removes a context from this set.
* *
* @param key the key to remove * @param key the key to remove
* @param value the value to remove (case sensitive) * @param value the value to remove
* @throws NullPointerException if the key or value is null * @throws NullPointerException if the key or value is null
*/ */
public void remove(@Nonnull String key, @Nonnull String value) { public void remove(@Nonnull String key, @Nonnull String value) {
this.map.remove(sanitizeKey(key), sanitizeValue(value)); this.map.remove(sanitizeKey(key), sanitizeValue(value));
} }
/**
* Removes a context from this set. (case-insensitive)
*
* @param key the key to remove
* @param value the value to remove
* @throws NullPointerException if the key or value is null
*/
public void removeIgnoreCase(@Nonnull String key, @Nonnull String value) {
String v = sanitizeValue(value);
Collection<String> strings = this.map.asMap().get(sanitizeKey(key));
if (strings != null) {
strings.removeIf(e -> e.equalsIgnoreCase(v));
}
}
/** /**
* Removes all contexts from this set with the given key. * Removes all contexts from this set with the given key.
* *

View File

@ -321,7 +321,7 @@ public final class ImmutableNode implements Node {
@Override @Override
public boolean shouldApplyWithContext(@Nonnull ContextSet contextSet) { public boolean shouldApplyWithContext(@Nonnull ContextSet contextSet) {
return getFullContexts().isSatisfiedBy(contextSet, false); return getFullContexts().isSatisfiedBy(contextSet);
} }
@Nonnull @Nonnull

View File

@ -25,10 +25,11 @@
package me.lucko.luckperms.common.storage.dao.file; package me.lucko.luckperms.common.storage.dao.file;
import com.google.gson.Gson;
import com.google.gson.JsonArray; import com.google.gson.JsonArray;
import com.google.gson.JsonElement; import com.google.gson.JsonElement;
import com.google.gson.JsonObject; import com.google.gson.JsonObject;
import com.google.gson.internal.Streams; import com.google.gson.JsonParser;
import com.google.gson.stream.JsonReader; import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonWriter; import com.google.gson.stream.JsonWriter;
@ -49,6 +50,8 @@ import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.locks.ReentrantLock; import java.util.concurrent.locks.ReentrantLock;
public class FileActionLogger { public class FileActionLogger {
private static final JsonParser JSON_PARSER = new JsonParser();
private static final Gson GSON = new Gson();
/** /**
* The path to save logger content to * The path to save logger content to
@ -94,7 +97,7 @@ public class FileActionLogger {
if (Files.exists(this.contentFile)) { if (Files.exists(this.contentFile)) {
try (JsonReader reader = new JsonReader(Files.newBufferedReader(this.contentFile, StandardCharsets.UTF_8))) { try (JsonReader reader = new JsonReader(Files.newBufferedReader(this.contentFile, StandardCharsets.UTF_8))) {
array = Streams.parse(reader).getAsJsonArray(); array = JSON_PARSER.parse(reader).getAsJsonArray();
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
array = new JsonArray(); array = new JsonArray();
@ -123,7 +126,7 @@ public class FileActionLogger {
// write the full content back to the file // write the full content back to the file
try (JsonWriter writer = new JsonWriter(Files.newBufferedWriter(this.contentFile, StandardCharsets.UTF_8))) { try (JsonWriter writer = new JsonWriter(Files.newBufferedWriter(this.contentFile, StandardCharsets.UTF_8))) {
writer.setIndent(" "); writer.setIndent(" ");
Streams.write(array, writer); GSON.toJson(array, writer);
} }
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
@ -136,7 +139,7 @@ public class FileActionLogger {
public Log getLog() throws IOException { public Log getLog() throws IOException {
Log.Builder log = Log.builder(); Log.Builder log = Log.builder();
try (JsonReader reader = new JsonReader(Files.newBufferedReader(this.contentFile, StandardCharsets.UTF_8))) { try (JsonReader reader = new JsonReader(Files.newBufferedReader(this.contentFile, StandardCharsets.UTF_8))) {
JsonArray array = Streams.parse(reader).getAsJsonArray(); JsonArray array = JSON_PARSER.parse(reader).getAsJsonArray();
for (JsonElement element : array) { for (JsonElement element : array) {
JsonObject object = element.getAsJsonObject(); JsonObject object = element.getAsJsonObject();