mirror of
https://github.com/filoghost/HolographicDisplays.git
synced 2025-02-01 04:31:21 +01:00
Simplify placeholder replacement
This commit is contained in:
parent
e161dd18f9
commit
2d99a0c36a
@ -22,7 +22,7 @@ public class PlaceholderAPIHook {
|
|||||||
enabled = true;
|
enabled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean containsPlaceholders(String text) {
|
public static boolean containsPlaceholderPattern(String text) {
|
||||||
if (Strings.isEmpty(text)) {
|
if (Strings.isEmpty(text)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -20,35 +20,43 @@ class DisplayText {
|
|||||||
private final PlaceholderTracker placeholderTracker;
|
private final PlaceholderTracker placeholderTracker;
|
||||||
private @NotNull StringWithPlaceholders textWithoutReplacements;
|
private @NotNull StringWithPlaceholders textWithoutReplacements;
|
||||||
private @NotNull StringWithPlaceholders textWithGlobalReplacements;
|
private @NotNull StringWithPlaceholders textWithGlobalReplacements;
|
||||||
|
private boolean containsPlaceholderAPIPattern;
|
||||||
|
|
||||||
DisplayText(PlaceholderTracker placeholderTracker) {
|
DisplayText(PlaceholderTracker placeholderTracker) {
|
||||||
this.placeholderTracker = placeholderTracker;
|
this.placeholderTracker = placeholderTracker;
|
||||||
this.textWithoutReplacements = StringWithPlaceholders.of(null);
|
this.textWithoutReplacements = StringWithPlaceholders.of(null);
|
||||||
this.textWithGlobalReplacements = StringWithPlaceholders.of(null);
|
this.textWithGlobalReplacements = textWithoutReplacements;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setWithoutReplacements(@Nullable String textString) {
|
void setWithoutReplacements(@Nullable String textString) {
|
||||||
textWithoutReplacements = StringWithPlaceholders.of(textString);
|
textWithoutReplacements = StringWithPlaceholders.of(textString);
|
||||||
textWithGlobalReplacements = textWithoutReplacements;
|
textWithGlobalReplacements = textWithoutReplacements;
|
||||||
|
containsPlaceholderAPIPattern = textWithoutReplacements.anyLiteralPartMatch(PlaceholderAPIHook::containsPlaceholderPattern);
|
||||||
}
|
}
|
||||||
|
|
||||||
String getWithoutReplacements() {
|
String getWithoutReplacements() {
|
||||||
return textWithoutReplacements.getUnreplacedString();
|
return textWithoutReplacements.getString();
|
||||||
}
|
}
|
||||||
|
|
||||||
String getWithGlobalReplacements() {
|
String getWithGlobalReplacements() {
|
||||||
return textWithGlobalReplacements.getUnreplacedString();
|
return textWithGlobalReplacements.getString();
|
||||||
}
|
}
|
||||||
|
|
||||||
String getWithIndividualReplacements(Player player) {
|
String getWithIndividualReplacements(Player player) {
|
||||||
String textWithIndividualReplacements = textWithGlobalReplacements.replacePlaceholders((PlaceholderOccurrence occurrence) ->
|
return textWithGlobalReplacements.replaceParts(
|
||||||
placeholderTracker.updateAndGetIndividualReplacement(occurrence, player));
|
(PlaceholderOccurrence placeholderOccurrence) -> {
|
||||||
|
return placeholderTracker.updateAndGetIndividualReplacement(placeholderOccurrence, player);
|
||||||
if (PlaceholderAPIHook.isEnabled() && PlaceholderAPIHook.containsPlaceholders(textWithIndividualReplacements)) {
|
},
|
||||||
textWithIndividualReplacements = PlaceholderAPIHook.replacePlaceholders(player, textWithIndividualReplacements);
|
(String literalPart) -> {
|
||||||
|
if (containsPlaceholderAPIPattern
|
||||||
|
&& PlaceholderAPIHook.isEnabled()
|
||||||
|
&& PlaceholderAPIHook.containsPlaceholderPattern(literalPart)) {
|
||||||
|
return PlaceholderAPIHook.replacePlaceholders(player, literalPart);
|
||||||
|
} else {
|
||||||
|
return literalPart;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return textWithIndividualReplacements;
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean updateGlobalReplacements() {
|
boolean updateGlobalReplacements() {
|
||||||
@ -68,8 +76,7 @@ class DisplayText {
|
|||||||
}
|
}
|
||||||
|
|
||||||
boolean containsIndividualPlaceholders() {
|
boolean containsIndividualPlaceholders() {
|
||||||
return placeholderTracker.containsIndividualPlaceholders(textWithoutReplacements)
|
return containsPlaceholderAPIPattern || placeholderTracker.containsIndividualPlaceholders(textWithoutReplacements);
|
||||||
|| PlaceholderAPIHook.containsPlaceholders(textWithoutReplacements.getUnreplacedString());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -5,9 +5,13 @@
|
|||||||
*/
|
*/
|
||||||
package me.filoghost.holographicdisplays.plugin.placeholder.parsing;
|
package me.filoghost.holographicdisplays.plugin.placeholder.parsing;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
@FunctionalInterface
|
@FunctionalInterface
|
||||||
public interface PlaceholderReplaceFunction {
|
public interface PlaceholderReplaceFunction {
|
||||||
|
|
||||||
String getReplacement(PlaceholderOccurrence placeholderOccurrence);
|
PlaceholderReplaceFunction NO_REPLACEMENTS = placeholderOccurrence -> null;
|
||||||
|
|
||||||
|
@Nullable String getReplacement(PlaceholderOccurrence placeholderOccurrence);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -11,8 +11,8 @@ import org.jetbrains.annotations.Nullable;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.function.Function;
|
|
||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
|
import java.util.function.UnaryOperator;
|
||||||
|
|
||||||
public final class StringWithPlaceholders {
|
public final class StringWithPlaceholders {
|
||||||
|
|
||||||
@ -36,23 +36,39 @@ public final class StringWithPlaceholders {
|
|||||||
this.stringParts = stringParts;
|
this.stringParts = stringParts;
|
||||||
}
|
}
|
||||||
|
|
||||||
public @Nullable String getUnreplacedString() {
|
public @Nullable String getString() {
|
||||||
return string;
|
return string;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean containsPlaceholders() {
|
public boolean containsPlaceholders() {
|
||||||
return stringParts != null;
|
return string != null && stringParts != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean anyMatch(Predicate<PlaceholderOccurrence> filter) {
|
public boolean anyPlaceholderMatch(Predicate<PlaceholderOccurrence> filter) {
|
||||||
if (!containsPlaceholders()) {
|
if (!containsPlaceholders()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (StringPart stringPart : stringParts) {
|
for (StringPart stringPart : stringParts) {
|
||||||
if (stringPart instanceof PlaceholderStringPart) {
|
if (stringPart instanceof PlaceholderPart) {
|
||||||
PlaceholderStringPart placeholderStringPart = (PlaceholderStringPart) stringPart;
|
PlaceholderPart placeholderPart = (PlaceholderPart) stringPart;
|
||||||
if (filter.test(placeholderStringPart.placeholderOccurrence)) {
|
if (filter.test(placeholderPart.getPlaceholderOccurrence())) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean anyLiteralPartMatch(Predicate<String> filter) {
|
||||||
|
if (!containsPlaceholders()) {
|
||||||
|
return filter.test(string);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (StringPart stringPart : stringParts) {
|
||||||
|
if (stringPart instanceof LiteralPart) {
|
||||||
|
if (filter.test(stringPart.getRawValue())) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -66,77 +82,51 @@ public final class StringWithPlaceholders {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
StringBuilder output = new StringBuilder();
|
List<StringPart> newStringParts = new ArrayList<>(stringParts.size());
|
||||||
StringBuilder fullOutput = new StringBuilder();
|
|
||||||
List<StringPart> newStringParts = null; // Lazy initialization
|
|
||||||
|
|
||||||
for (StringPart part : stringParts) {
|
for (StringPart part : stringParts) {
|
||||||
if (part instanceof PlaceholderStringPart) {
|
if (part instanceof PlaceholderPart) {
|
||||||
PlaceholderStringPart placeholderStringPart = (PlaceholderStringPart) part;
|
String replacement = replaceFunction.getReplacement(((PlaceholderPart) part).getPlaceholderOccurrence());
|
||||||
String replacement = replaceFunction.getReplacement(placeholderStringPart.placeholderOccurrence);
|
|
||||||
if (replacement != null) {
|
if (replacement != null) {
|
||||||
output.append(replacement);
|
// Do not use LiteralPart to avoid potentially replacing it again later
|
||||||
fullOutput.append(replacement);
|
newStringParts.add(new ReplacementPart(replacement));
|
||||||
} else {
|
} else {
|
||||||
// Placeholder was not replaced, may be replaced later
|
// Placeholder was not replaced, may be replaced later
|
||||||
if (newStringParts == null) {
|
newStringParts.add(part);
|
||||||
newStringParts = new ArrayList<>();
|
|
||||||
}
|
|
||||||
// Append leading literal string, if present
|
|
||||||
if (output.length() > 0) {
|
|
||||||
newStringParts.add(new LiteralStringPart(output.toString()));
|
|
||||||
output.setLength(0);
|
|
||||||
}
|
|
||||||
newStringParts.add(placeholderStringPart);
|
|
||||||
fullOutput.append(placeholderStringPart.unreplacedString);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
LiteralStringPart literalStringPart = (LiteralStringPart) part;
|
newStringParts.add(part);
|
||||||
output.append(literalStringPart.literalString);
|
|
||||||
fullOutput.append(literalStringPart.literalString);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (output.length() > 0 && newStringParts != null) {
|
return new StringWithPlaceholders(joinParts(newStringParts), newStringParts);
|
||||||
newStringParts.add(new LiteralStringPart(output.toString()));
|
|
||||||
}
|
|
||||||
|
|
||||||
return new StringWithPlaceholders(fullOutput.toString(), newStringParts);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public @Nullable String replacePlaceholders(PlaceholderReplaceFunction replaceFunction) {
|
public @Nullable String replacePlaceholders(PlaceholderReplaceFunction replaceFunction) {
|
||||||
if (!containsPlaceholders()) {
|
return replaceParts(replaceFunction, UnaryOperator.identity());
|
||||||
return string;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
StringBuilder output = new StringBuilder();
|
public String replaceLiteralParts(UnaryOperator<String> replaceFunction) {
|
||||||
|
return replaceParts(PlaceholderReplaceFunction.NO_REPLACEMENTS, replaceFunction);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String replaceParts(PlaceholderReplaceFunction placeholderReplaceFunction, UnaryOperator<String> literalPartReplaceFunction) {
|
||||||
|
if (!containsPlaceholders()) {
|
||||||
|
return literalPartReplaceFunction.apply(string);
|
||||||
|
}
|
||||||
|
|
||||||
|
StringBuilder output = new StringBuilder(string.length());
|
||||||
|
|
||||||
for (StringPart part : stringParts) {
|
for (StringPart part : stringParts) {
|
||||||
output.append(part.getValue(replaceFunction));
|
if (part instanceof LiteralPart) {
|
||||||
|
output.append(literalPartReplaceFunction.apply(part.getRawValue()));
|
||||||
|
} else {
|
||||||
|
output.append(part.getValue(placeholderReplaceFunction));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return output.toString();
|
return output.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public String replaceLiteralParts(Function<String, String> transformFunction) {
|
|
||||||
if (!containsPlaceholders() || string == null) {
|
|
||||||
return transformFunction.apply(string);
|
|
||||||
}
|
|
||||||
|
|
||||||
StringBuilder stringOutput = new StringBuilder(string.length());
|
|
||||||
|
|
||||||
for (StringPart part : stringParts) {
|
|
||||||
if (part instanceof LiteralStringPart) {
|
|
||||||
LiteralStringPart literalStringPart = (LiteralStringPart) part;
|
|
||||||
String transformedPart = transformFunction.apply(literalStringPart.literalString);
|
|
||||||
stringOutput.append(transformedPart);
|
|
||||||
} else {
|
|
||||||
stringOutput.append(((PlaceholderStringPart) part).unreplacedString);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return stringOutput.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static @Nullable List<StringPart> splitToParts(@NotNull String string) {
|
private static @Nullable List<StringPart> splitToParts(@NotNull String string) {
|
||||||
int placeholderStartIndex = -1;
|
int placeholderStartIndex = -1;
|
||||||
int lastAppendIndex = 0;
|
int lastAppendIndex = 0;
|
||||||
@ -163,11 +153,11 @@ public final class StringWithPlaceholders {
|
|||||||
|
|
||||||
// Append leading literal part (if any)
|
// Append leading literal part (if any)
|
||||||
if (placeholderStartIndex != lastAppendIndex) {
|
if (placeholderStartIndex != lastAppendIndex) {
|
||||||
stringParts.add(new LiteralStringPart(string.substring(lastAppendIndex, placeholderStartIndex)));
|
stringParts.add(new LiteralPart(string.substring(lastAppendIndex, placeholderStartIndex)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Append placeholder part
|
// Append placeholder part
|
||||||
stringParts.add(new PlaceholderStringPart(content, unparsedString));
|
stringParts.add(new PlaceholderPart(content, unparsedString));
|
||||||
lastAppendIndex = endIndex;
|
lastAppendIndex = endIndex;
|
||||||
placeholderStartIndex = -1;
|
placeholderStartIndex = -1;
|
||||||
|
|
||||||
@ -185,12 +175,20 @@ public final class StringWithPlaceholders {
|
|||||||
|
|
||||||
// Append trailing literal part (if any)
|
// Append trailing literal part (if any)
|
||||||
if (lastAppendIndex != string.length() && stringParts != null) {
|
if (lastAppendIndex != string.length() && stringParts != null) {
|
||||||
stringParts.add(new LiteralStringPart(string.substring(lastAppendIndex)));
|
stringParts.add(new LiteralPart(string.substring(lastAppendIndex)));
|
||||||
}
|
}
|
||||||
|
|
||||||
return stringParts;
|
return stringParts;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static String joinParts(@NotNull List<StringPart> stringParts) {
|
||||||
|
StringBuilder stringBuilder = new StringBuilder();
|
||||||
|
for (StringPart stringPart : stringParts) {
|
||||||
|
stringBuilder.append(stringPart.getRawValue());
|
||||||
|
}
|
||||||
|
return stringBuilder.toString();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object obj) {
|
public boolean equals(Object obj) {
|
||||||
if (this == obj) {
|
if (this == obj) {
|
||||||
@ -214,31 +212,59 @@ public final class StringWithPlaceholders {
|
|||||||
|
|
||||||
String getValue(PlaceholderReplaceFunction placeholderReplaceFunction);
|
String getValue(PlaceholderReplaceFunction placeholderReplaceFunction);
|
||||||
|
|
||||||
|
String getRawValue();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static class LiteralStringPart implements StringPart {
|
private static class LiteralPart implements StringPart {
|
||||||
|
|
||||||
private final String literalString;
|
private final String value;
|
||||||
|
|
||||||
LiteralStringPart(String literalString) {
|
LiteralPart(@NotNull String value) {
|
||||||
this.literalString = literalString;
|
this.value = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getValue(PlaceholderReplaceFunction placeholderReplaceFunction) {
|
public String getValue(PlaceholderReplaceFunction placeholderReplaceFunction) {
|
||||||
return literalString;
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getRawValue() {
|
||||||
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static class PlaceholderStringPart implements StringPart {
|
private static class ReplacementPart implements StringPart {
|
||||||
|
|
||||||
|
private final String replacement;
|
||||||
|
|
||||||
|
ReplacementPart(@NotNull String replacement) {
|
||||||
|
this.replacement = replacement;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getValue(PlaceholderReplaceFunction placeholderReplaceFunction) {
|
||||||
|
return replacement;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getRawValue() {
|
||||||
|
return replacement;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static class PlaceholderPart implements StringPart {
|
||||||
|
|
||||||
private final PlaceholderOccurrence placeholderOccurrence;
|
private final PlaceholderOccurrence placeholderOccurrence;
|
||||||
private final String unreplacedString;
|
private final String unreplacedString;
|
||||||
|
|
||||||
PlaceholderStringPart(PlaceholderOccurrence placeholderOccurrence, String unreplacedString) {
|
PlaceholderPart(@NotNull PlaceholderOccurrence placeholderOccurrence, @NotNull String unreplacedString) {
|
||||||
this.placeholderOccurrence = placeholderOccurrence;
|
this.placeholderOccurrence = placeholderOccurrence;
|
||||||
this.unreplacedString = unreplacedString;
|
this.unreplacedString = unreplacedString;
|
||||||
}
|
}
|
||||||
@ -249,11 +275,20 @@ public final class StringWithPlaceholders {
|
|||||||
if (replacement != null) {
|
if (replacement != null) {
|
||||||
return replacement;
|
return replacement;
|
||||||
} else {
|
} else {
|
||||||
// If no replacement is provided, leave the unreplaced placeholder string
|
// If no replacement is provided return the unreplaced placeholder string
|
||||||
return unreplacedString;
|
return unreplacedString;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getRawValue() {
|
||||||
|
return unreplacedString;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PlaceholderOccurrence getPlaceholderOccurrence() {
|
||||||
|
return placeholderOccurrence;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -102,7 +102,7 @@ public class PlaceholderTracker {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean containsIndividualPlaceholders(StringWithPlaceholders textWithPlaceholders) {
|
public boolean containsIndividualPlaceholders(StringWithPlaceholders textWithPlaceholders) {
|
||||||
return textWithPlaceholders.anyMatch(occurrence -> {
|
return textWithPlaceholders.anyPlaceholderMatch(occurrence -> {
|
||||||
PlaceholderExpansion placeholderExpansion = registry.find(occurrence);
|
PlaceholderExpansion placeholderExpansion = registry.find(occurrence);
|
||||||
return placeholderExpansion != null && placeholderExpansion.isIndividual();
|
return placeholderExpansion != null && placeholderExpansion.isIndividual();
|
||||||
});
|
});
|
||||||
|
@ -34,7 +34,7 @@ class StringWithPlaceholdersTest {
|
|||||||
boolean expectedContainsPlaceholders = expectedOutput.contains("#");
|
boolean expectedContainsPlaceholders = expectedOutput.contains("#");
|
||||||
StringWithPlaceholders s = StringWithPlaceholders.of(input);
|
StringWithPlaceholders s = StringWithPlaceholders.of(input);
|
||||||
|
|
||||||
assertThat(s.partiallyReplacePlaceholders(occurrence -> "#").getUnreplacedString()).isEqualTo(expectedOutput);
|
assertThat(s.partiallyReplacePlaceholders(occurrence -> "#").getString()).isEqualTo(expectedOutput);
|
||||||
assertThat(s.partiallyReplacePlaceholders(occurrence -> null).replacePlaceholders(occurrence -> "#")).isEqualTo(expectedOutput);
|
assertThat(s.partiallyReplacePlaceholders(occurrence -> null).replacePlaceholders(occurrence -> "#")).isEqualTo(expectedOutput);
|
||||||
assertThat(s.containsPlaceholders()).isEqualTo(expectedContainsPlaceholders);
|
assertThat(s.containsPlaceholders()).isEqualTo(expectedContainsPlaceholders);
|
||||||
}
|
}
|
||||||
@ -82,7 +82,7 @@ class StringWithPlaceholdersTest {
|
|||||||
|
|
||||||
List<PlaceholderOccurrence> placeholders = new ArrayList<>();
|
List<PlaceholderOccurrence> placeholders = new ArrayList<>();
|
||||||
s.replacePlaceholders(occurrence -> {
|
s.replacePlaceholders(occurrence -> {
|
||||||
placeholders.add(occurrence); // Just save occurrences
|
placeholders.add(occurrence); // Just collect occurrences
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
assertThat(placeholders).hasSize(1);
|
assertThat(placeholders).hasSize(1);
|
||||||
|
Loading…
Reference in New Issue
Block a user