mirror of
https://github.com/CarmJos/EasyConfiguration.git
synced 2026-06-04 18:48:20 +08:00
feat: Optimized ContentHandler with Replacer & Inserter.
This commit is contained in:
+89
-134
@@ -1,54 +1,27 @@
|
|||||||
package cc.carm.lib.configuration.value.text.function;
|
package cc.carm.lib.configuration.value.text.function;
|
||||||
|
|
||||||
import cc.carm.lib.configuration.value.text.data.TextContents;
|
import cc.carm.lib.configuration.value.text.data.TextContents;
|
||||||
import cc.carm.lib.configuration.value.text.function.modifier.ContentReplacer;
|
import cc.carm.lib.configuration.value.text.function.common.AppendLineInserter;
|
||||||
|
import cc.carm.lib.configuration.value.text.function.common.OptionalLineInserter;
|
||||||
|
import cc.carm.lib.configuration.value.text.function.common.ParamReplacer;
|
||||||
|
import cc.carm.lib.configuration.value.text.function.inserter.ContentInserter;
|
||||||
|
import cc.carm.lib.configuration.value.text.function.inserter.Insertable;
|
||||||
|
import cc.carm.lib.configuration.value.text.function.replacer.ContentReplacer;
|
||||||
|
import cc.carm.lib.configuration.value.text.function.replacer.Replaceable;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.function.BiFunction;
|
import java.util.function.BiFunction;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
import java.util.function.UnaryOperator;
|
import java.util.function.UnaryOperator;
|
||||||
import java.util.regex.Matcher;
|
|
||||||
import java.util.regex.Pattern;
|
|
||||||
import java.util.stream.IntStream;
|
|
||||||
|
|
||||||
public abstract class ContentHandler<RECEIVER, SELF extends ContentHandler<RECEIVER, SELF>> {
|
public abstract class ContentHandler<RECEIVER, SELF extends ContentHandler<RECEIVER, SELF>>
|
||||||
|
implements Replaceable<RECEIVER, SELF>, Insertable<RECEIVER, SELF> {
|
||||||
/**
|
|
||||||
* Used to match the message insertion.
|
|
||||||
* <p>
|
|
||||||
* format:
|
|
||||||
* <br>- to insert parsed line {prefix}#content-id#{offset-above,offset-down}
|
|
||||||
* <br>- to insert original line {prefix}@content-id@{offset-above,offset-down}
|
|
||||||
* <br> original lines will not be parsed
|
|
||||||
* <br> example:
|
|
||||||
* <ul>
|
|
||||||
* <li>{- }#content-id#{1,1}</li>
|
|
||||||
* <li>@content-id@{1,1}</li>
|
|
||||||
* </ul>
|
|
||||||
*/
|
|
||||||
public static final @NotNull Pattern INSERT_PATTERN = Pattern.compile(
|
|
||||||
"^(?:\\{(?<prefix>.*)})?(?<type>[#@])(?<id>.*)[#@](?:\\{(?<above>-?\\d+)(?:,(?<down>-?\\d+))?})?$"
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Used to match the message which can be inserted
|
|
||||||
* <p>
|
|
||||||
* format:
|
|
||||||
* <br>- ?[id]Message content
|
|
||||||
* <br> example:
|
|
||||||
* <ul>
|
|
||||||
* <li>?[click]Click to use this item!</li>
|
|
||||||
* </ul>
|
|
||||||
*/
|
|
||||||
public static final @NotNull Pattern ENABLE_PATTERN = Pattern.compile(
|
|
||||||
"^\\?\\[(?<id>.+)](?<content>.*)$"
|
|
||||||
);
|
|
||||||
|
|
||||||
public static final @NotNull Function<String, String>
|
|
||||||
public static final @NotNull UnaryOperator<String> DEFAULT_PARAM_BUILDER = s -> "%(" + s + ")";
|
|
||||||
|
|
||||||
protected BiFunction<RECEIVER, String, String> parser = (receiver, value) -> value;
|
protected BiFunction<RECEIVER, String, String> parser = (receiver, value) -> value;
|
||||||
protected String lineSeparator = System.lineSeparator();
|
protected String lineSeparator = System.lineSeparator();
|
||||||
@@ -56,19 +29,24 @@ public abstract class ContentHandler<RECEIVER, SELF extends ContentHandler<RECEI
|
|||||||
/**
|
/**
|
||||||
* Used to store the placeholders of the message
|
* Used to store the placeholders of the message
|
||||||
*/
|
*/
|
||||||
protected @NotNull Map<String, Object> placeholders = new HashMap<>();
|
protected @NotNull ParamReplacer<RECEIVER> paramReplacer = ParamReplacer.defaults();
|
||||||
protected @NotNull UnaryOperator<String> paramFormatter = DEFAULT_PARAM_BUILDER;
|
|
||||||
protected @NotNull String[] params;
|
protected @NotNull String[] params;
|
||||||
|
|
||||||
protected @NotNull List<ContentReplacer> replacers = new ArrayList<>();
|
protected @NotNull List<ContentReplacer<RECEIVER>> replacers = new ArrayList<>();
|
||||||
protected @NotNull List<ContentReplacer> inserters = new ArrayList<>();
|
protected @NotNull List<ContentInserter<RECEIVER>> inserters = new ArrayList<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used to store the insertion of the message
|
* Used to store the insertion of the message
|
||||||
*/
|
*/
|
||||||
protected @NotNull Map<String, @Nullable Function<RECEIVER, List<String>>> insertion = new HashMap<>();
|
protected final @NotNull Map<String, @Nullable Function<RECEIVER, List<String>>> insertion = new HashMap<>();
|
||||||
protected boolean disableInsertion = false;
|
protected boolean disableInsertion = false;
|
||||||
|
|
||||||
|
public ContentHandler() {
|
||||||
|
inserters.add(new AppendLineInserter<>(0));
|
||||||
|
inserters.add(new OptionalLineInserter<>(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public abstract SELF self();
|
public abstract SELF self();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -92,6 +70,11 @@ public abstract class ContentHandler<RECEIVER, SELF extends ContentHandler<RECEI
|
|||||||
return self();
|
return self();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean noneInsertion() {
|
||||||
|
return this.insertion.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the line separator for the text.
|
* Set the line separator for the text.
|
||||||
*
|
*
|
||||||
@@ -111,7 +94,7 @@ public abstract class ContentHandler<RECEIVER, SELF extends ContentHandler<RECEI
|
|||||||
* @return the current {@link ContentHandler} instance
|
* @return the current {@link ContentHandler} instance
|
||||||
*/
|
*/
|
||||||
public SELF placeholders(@NotNull Map<String, Object> placeholders) {
|
public SELF placeholders(@NotNull Map<String, Object> placeholders) {
|
||||||
this.placeholders = placeholders;
|
this.paramReplacer.set(placeholders);
|
||||||
return self();
|
return self();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -122,7 +105,7 @@ public abstract class ContentHandler<RECEIVER, SELF extends ContentHandler<RECEI
|
|||||||
* @return the current {@link ContentHandler} instance
|
* @return the current {@link ContentHandler} instance
|
||||||
*/
|
*/
|
||||||
public SELF placeholders(@NotNull Consumer<Map<String, Object>> consumer) {
|
public SELF placeholders(@NotNull Consumer<Map<String, Object>> consumer) {
|
||||||
consumer.accept(this.placeholders);
|
consumer.accept(this.paramReplacer.placeholders());
|
||||||
return self();
|
return self();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -133,7 +116,8 @@ public abstract class ContentHandler<RECEIVER, SELF extends ContentHandler<RECEI
|
|||||||
* @return the current {@link ContentHandler} instance
|
* @return the current {@link ContentHandler} instance
|
||||||
*/
|
*/
|
||||||
public SELF placeholders(@Nullable Object... values) {
|
public SELF placeholders(@Nullable Object... values) {
|
||||||
return placeholders(map -> map.putAll(buildParams(this.paramFormatter, this.params, values)));
|
this.paramReplacer.putAll(this.params, values);
|
||||||
|
return self();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -144,7 +128,7 @@ public abstract class ContentHandler<RECEIVER, SELF extends ContentHandler<RECEI
|
|||||||
* @return the current {@link ContentHandler} instance
|
* @return the current {@link ContentHandler} instance
|
||||||
*/
|
*/
|
||||||
public SELF placeholder(@NotNull String key, @Nullable Object value) {
|
public SELF placeholder(@NotNull String key, @Nullable Object value) {
|
||||||
this.placeholders.put(paramFormatter.apply(key), value);
|
this.paramReplacer.put(key, value);
|
||||||
return self();
|
return self();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -160,49 +144,52 @@ public abstract class ContentHandler<RECEIVER, SELF extends ContentHandler<RECEI
|
|||||||
return self();
|
return self();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* Insert the specific contents by the id.
|
public List<ContentReplacer<RECEIVER>> replacers() {
|
||||||
*
|
return this.replacers;
|
||||||
* @param id the id of the insertion text
|
}
|
||||||
* @return the current {@link ContentHandler} instance
|
|
||||||
*/
|
@Override
|
||||||
public SELF insert(@NotNull String id) {
|
public SELF replacer(@NotNull ContentReplacer<RECEIVER> replacer) {
|
||||||
this.insertion.put(id, null);
|
this.replacers.add(replacer);
|
||||||
|
this.replacers.sort(ContentReplacer::compareTo);
|
||||||
return self();
|
return self();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* Insert the specific contents by the id.
|
public List<ContentInserter<RECEIVER>> inserters() {
|
||||||
*
|
return this.inserters;
|
||||||
* @param id the id of the insertion text
|
}
|
||||||
* @param linesSupplier to supply the lines to insert
|
|
||||||
* @return the current {@link ContentHandler} instance
|
@Override
|
||||||
*/
|
public SELF inserter(@NotNull ContentInserter<RECEIVER> inserter) {
|
||||||
public SELF insert(@NotNull String id, @NotNull Function<RECEIVER, List<String>> linesSupplier) {
|
this.inserters.add(inserter);
|
||||||
this.insertion.put(id, linesSupplier);
|
this.inserters.sort(ContentInserter::compareTo);
|
||||||
return self();
|
return self();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* Insert the specific contents by the id.
|
public SELF insert(@NotNull String id, @Nullable Function<RECEIVER, List<String>> supplier) {
|
||||||
*
|
this.insertion.put(id, supplier);
|
||||||
* @param id the id of the insertion text
|
return self();
|
||||||
* @param lines the lines to insert
|
|
||||||
* @return the current {@link ContentHandler} instance
|
|
||||||
*/
|
|
||||||
public SELF insert(@NotNull String id, @NotNull String... lines) {
|
|
||||||
return insert(id, Arrays.asList(lines));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* Insert the specific contents by the id.
|
public boolean inserting(@NotNull String id) {
|
||||||
*
|
return this.insertion.keySet().stream().anyMatch(key -> key.equalsIgnoreCase(id));
|
||||||
* @param id the id of the insertion text
|
}
|
||||||
* @param lines the lines to insert
|
|
||||||
* @return the current {@link ContentHandler} instance
|
@Override
|
||||||
*/
|
public @Nullable List<String> getInsertion(@NotNull String id, @Nullable RECEIVER receiver) {
|
||||||
public SELF insert(@NotNull String id, @NotNull List<String> lines) {
|
Function<RECEIVER, List<String>> function = this.insertion.get(id);
|
||||||
return insert(id, receiver -> lines);
|
if (function == null) return null;
|
||||||
|
return function.apply(receiver);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SELF removeInsert(@NotNull String id) {
|
||||||
|
this.insertion.remove(id);
|
||||||
|
return self();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -224,73 +211,41 @@ public abstract class ContentHandler<RECEIVER, SELF extends ContentHandler<RECEI
|
|||||||
* @return the parsed text
|
* @return the parsed text
|
||||||
*/
|
*/
|
||||||
protected @Nullable String parse(@Nullable RECEIVER receiver, @NotNull String text) {
|
protected @Nullable String parse(@Nullable RECEIVER receiver, @NotNull String text) {
|
||||||
return this.parser.apply(receiver, setPlaceholders(text, this.placeholders));
|
text = applyReplacements(receiver, text); // First, apply the custom replacements
|
||||||
|
text = this.paramReplacer.replace(text, receiver); // Then, apply the static placeholders
|
||||||
|
return this.parser.apply(receiver, text); // Finally, parse the text
|
||||||
}
|
}
|
||||||
|
|
||||||
public void handle(@NotNull TextContents contents, @Nullable RECEIVER receiver,
|
public void handle(@NotNull TextContents contents, @Nullable RECEIVER receiver,
|
||||||
@NotNull Consumer<String> lineConsumer) {
|
@NotNull Consumer<String> lineConsumer) {
|
||||||
if (contents.isEmpty()) return; // Nothing to parse
|
if (contents.isEmpty()) return; // Nothing to parse
|
||||||
|
|
||||||
if (this.disableInsertion) {
|
if (this.disableInsertion || noneInsertion()) {
|
||||||
contents.lines().forEach(line -> lineConsumer.accept(parse(receiver, line)));
|
contents.lines().forEach(line -> lineConsumer.accept(parse(receiver, line)));
|
||||||
return; // Simple parsed
|
return; // Simple parsed
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set the default insertion of the text
|
||||||
|
for (Map.Entry<String, @Nullable Function<RECEIVER, List<String>>> entry : this.insertion.entrySet()) {
|
||||||
|
if (entry.getValue() != null) continue;
|
||||||
|
List<String> lines = contents.optionalLines().get(entry.getKey());
|
||||||
|
if (lines == null) continue;
|
||||||
|
entry.setValue(r -> lines);
|
||||||
|
}
|
||||||
|
|
||||||
|
lines:
|
||||||
for (String line : contents.lines()) {
|
for (String line : contents.lines()) {
|
||||||
Matcher insertMatcher = INSERT_PATTERN.matcher(line);
|
for (ContentInserter<RECEIVER> inserter : inserters) {
|
||||||
if (insertMatcher.matches()) {
|
List<String> inserted = inserter.handle(receiver, line, this);
|
||||||
doInsert(insertMatcher, receiver, lineConsumer);
|
if (inserted != null) { // Found the insertion
|
||||||
continue;
|
inserted.forEach(l -> lineConsumer.accept(parse(receiver, l)));
|
||||||
}
|
continue lines; // Go to the next line
|
||||||
|
|
||||||
Matcher enableMatcher = ENABLE_PATTERN.matcher(line);
|
|
||||||
if (enableMatcher.matches()) {
|
|
||||||
if (this.insertion.containsKey(enableMatcher.group("id"))) {
|
|
||||||
lineConsumer.accept(parse(receiver, enableMatcher.group("content")));
|
|
||||||
}
|
}
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
lineConsumer.accept(parse(receiver, line));
|
lineConsumer.accept(parse(receiver, line));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void doInsert(Matcher matcher, @Nullable RECEIVER receiver,
|
|
||||||
@NotNull Consumer<String> lineConsumer) {
|
|
||||||
String id = matcher.group("id");
|
|
||||||
List<String> values = Optional.ofNullable(this.insertion.get(id))
|
|
||||||
.map(f -> f.apply(receiver))
|
|
||||||
.orElse(null);
|
|
||||||
if (values == null || values.isEmpty()) return; // No values to insert
|
|
||||||
|
|
||||||
String prefix = matcher.group("prefix");
|
|
||||||
String type = matcher.group("type");
|
|
||||||
boolean original = type.equals("@");
|
|
||||||
int offsetAbove = Optional.ofNullable(matcher.group("above"))
|
|
||||||
.map(Integer::parseInt).orElse(0);
|
|
||||||
int offsetDown = Optional.ofNullable(matcher.group("down"))
|
|
||||||
.map(Integer::parseInt).orElse(offsetAbove); // If offsetDown is not set, use offsetAbove
|
|
||||||
|
|
||||||
IntStream.range(0, Math.max(0, offsetAbove)).mapToObj(i -> "").forEach(lineConsumer);
|
|
||||||
String prefixContent = Optional.ofNullable(prefix).map(p -> parse(receiver, p)).orElse("");
|
|
||||||
if (original) {
|
|
||||||
values.stream().map(value -> prefixContent + value).forEach(lineConsumer);
|
|
||||||
} else {
|
|
||||||
values.stream().map(value -> prefixContent + parse(receiver, value)).forEach(lineConsumer);
|
|
||||||
}
|
|
||||||
IntStream.range(0, Math.max(0, offsetDown)).mapToObj(i -> "").forEach(lineConsumer);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String setPlaceholders(@NotNull String messages,
|
|
||||||
@NotNull Map<String, Object> placeholders) {
|
|
||||||
if (messages.isEmpty()) return messages;
|
|
||||||
String parsed = messages;
|
|
||||||
for (Map.Entry<String, Object> entry : placeholders.entrySet()) {
|
|
||||||
parsed = parsed.replace(entry.getKey(), entry.getValue() == null ? "" : entry.getValue().toString());
|
|
||||||
}
|
|
||||||
return parsed;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Map<String, Object> buildParams(@NotNull UnaryOperator<String> paramBuilder,
|
public static Map<String, Object> buildParams(@NotNull UnaryOperator<String> paramBuilder,
|
||||||
@Nullable String[] params, @Nullable Object[] values) {
|
@Nullable String[] params, @Nullable Object[] values) {
|
||||||
Map<String, Object> map = new HashMap<>();
|
Map<String, Object> map = new HashMap<>();
|
||||||
|
|||||||
+67
@@ -0,0 +1,67 @@
|
|||||||
|
package cc.carm.lib.configuration.value.text.function.common;
|
||||||
|
|
||||||
|
import cc.carm.lib.configuration.value.text.function.inserter.ContentInserter;
|
||||||
|
import cc.carm.lib.configuration.value.text.function.inserter.Insertable;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
import java.util.stream.IntStream;
|
||||||
|
|
||||||
|
public class AppendLineInserter<RECEIVER> extends ContentInserter<RECEIVER> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to match the message insertion.
|
||||||
|
* <p>
|
||||||
|
* format:
|
||||||
|
* <br>- to insert parsed line {prefix}#content-id#{offset-above,offset-down}
|
||||||
|
* <br>- to insert original line {prefix}@content-id@{offset-above,offset-down}
|
||||||
|
* <br> original lines will not be parsed
|
||||||
|
* <br> example:
|
||||||
|
* <ul>
|
||||||
|
* <li>{- }#content-id#{1,1}</li>
|
||||||
|
* <li>@content-id@{1,1}</li>
|
||||||
|
* </ul>
|
||||||
|
*/
|
||||||
|
public static final @NotNull Pattern APPEND_PATTERN = Pattern.compile(
|
||||||
|
"^(?:\\{(?<prefix>.*)})?#(?<id>.*)#(?:\\{(?<above>-?\\d+)(?:,(?<down>-?\\d+))?})?$"
|
||||||
|
);
|
||||||
|
|
||||||
|
public AppendLineInserter(int priority) {
|
||||||
|
super(priority, APPEND_PATTERN);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected @Nullable String extractID(@NotNull Matcher matcher) {
|
||||||
|
return matcher.group("id");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected @NotNull List<String> get(@Nullable RECEIVER receiver, @NotNull Matcher matcher,
|
||||||
|
@NotNull Insertable<RECEIVER, ?> insertion) {
|
||||||
|
String id = extractID(matcher);
|
||||||
|
List<String> values = insertion.getInsertion(id, receiver);
|
||||||
|
if (values == null || values.isEmpty()) return Collections.emptyList(); // No values to insert
|
||||||
|
|
||||||
|
String prefix = Optional.ofNullable(matcher.group("prefix")).orElse("");
|
||||||
|
int offsetAbove = Optional.ofNullable(matcher.group("above"))
|
||||||
|
.map(Integer::parseInt).orElse(0);
|
||||||
|
int offsetDown = Optional.ofNullable(matcher.group("down"))
|
||||||
|
.map(Integer::parseInt).orElse(offsetAbove); // If offsetDown is not set, use offsetAbove
|
||||||
|
|
||||||
|
List<String> contents = new ArrayList<>();
|
||||||
|
|
||||||
|
IntStream.range(0, Math.max(0, offsetAbove)).mapToObj(i -> "").forEach(contents::add);
|
||||||
|
values.stream().map(value -> prefix + value).forEach(contents::add);
|
||||||
|
IntStream.range(0, Math.max(0, offsetDown)).mapToObj(i -> "").forEach(contents::add);
|
||||||
|
|
||||||
|
return contents;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
+46
@@ -0,0 +1,46 @@
|
|||||||
|
package cc.carm.lib.configuration.value.text.function.common;
|
||||||
|
|
||||||
|
import cc.carm.lib.configuration.value.text.function.inserter.ContentInserter;
|
||||||
|
import cc.carm.lib.configuration.value.text.function.inserter.Insertable;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
public class OptionalLineInserter<RECEIVER> extends ContentInserter<RECEIVER> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to match the message which can be inserted
|
||||||
|
* <p>
|
||||||
|
* format:
|
||||||
|
* <br>- ?[id]Message content
|
||||||
|
* <br> example:
|
||||||
|
* <ul>
|
||||||
|
* <li>?[click]Click to use this item!</li>
|
||||||
|
* </ul>
|
||||||
|
*/
|
||||||
|
public static final @NotNull Pattern OPTIONAL_PATTERN = Pattern.compile(
|
||||||
|
"^\\?\\[(?<id>.+)](?<content>.*)$"
|
||||||
|
);
|
||||||
|
|
||||||
|
public OptionalLineInserter(int priority) {
|
||||||
|
super(priority, OPTIONAL_PATTERN);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected @Nullable String extractID(@NotNull Matcher matcher) {
|
||||||
|
return matcher.group("id");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected @NotNull List<String> get(@Nullable RECEIVER receiver, @NotNull Matcher matcher,
|
||||||
|
@NotNull Insertable<RECEIVER, ?> insertion) {
|
||||||
|
String content = matcher.group("content");
|
||||||
|
if (content == null) return Collections.emptyList();
|
||||||
|
return Collections.singletonList(content);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+71
@@ -0,0 +1,71 @@
|
|||||||
|
package cc.carm.lib.configuration.value.text.function.common;
|
||||||
|
|
||||||
|
import cc.carm.lib.configuration.value.text.function.replacer.ContentReplacer;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.function.Function;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
public class ParamReplacer<RECEIVER> extends ContentReplacer<RECEIVER> {
|
||||||
|
|
||||||
|
public static final @NotNull Pattern DEFAULT_PARAM_PATTERN = Pattern.compile("%\\((?<id>[^)]+)\\)");
|
||||||
|
|
||||||
|
public static <R> ParamReplacer<R> defaults() {
|
||||||
|
return create(DEFAULT_PARAM_PATTERN, m -> m.group("id"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <R> ParamReplacer<R> create(@NotNull Pattern pattern, @NotNull Function<Matcher, String> extractor) {
|
||||||
|
return new ParamReplacer<>(0, pattern, extractor);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected final @NotNull Function<Matcher, @Nullable String> extractor;
|
||||||
|
protected @NotNull Map<String, Object> placeholders = new HashMap<>();
|
||||||
|
|
||||||
|
public ParamReplacer(int priority, @NotNull Pattern pattern, @NotNull Function<Matcher, String> extractor) {
|
||||||
|
super(priority, pattern);
|
||||||
|
this.extractor = extractor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public @NotNull Map<String, Object> placeholders() {
|
||||||
|
return placeholders;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected @Nullable String get(@NotNull RECEIVER receiver, @NotNull Matcher matcher) {
|
||||||
|
@Nullable String id = extractor.apply(matcher);
|
||||||
|
if (id == null) return null;
|
||||||
|
Object value = placeholders.get(id);
|
||||||
|
if (value == null) return null;
|
||||||
|
return value.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void set(@NotNull Map<String, Object> placeholders) {
|
||||||
|
this.placeholders = placeholders;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void put(@NotNull String id, @Nullable Object value) {
|
||||||
|
placeholders.put(id, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void remove(@NotNull String id) {
|
||||||
|
placeholders.remove(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void putAll(@NotNull Map<String, Object> placeholders) {
|
||||||
|
this.placeholders.putAll(placeholders);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void putAll(@NotNull String[] params, @NotNull Object[] values) {
|
||||||
|
for (int i = 0; i < params.length; i++) {
|
||||||
|
placeholders.put(params[i], (values != null && values.length > i) ? values[i] : "?");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clear() {
|
||||||
|
placeholders.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
+51
@@ -0,0 +1,51 @@
|
|||||||
|
package cc.carm.lib.configuration.value.text.function.inserter;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
public abstract class ContentInserter<RECEIVER> implements Comparable<ContentInserter<RECEIVER>> {
|
||||||
|
|
||||||
|
protected final int priority;
|
||||||
|
protected @NotNull Pattern pattern;
|
||||||
|
|
||||||
|
public ContentInserter(int priority, @NotNull Pattern pattern) {
|
||||||
|
this.priority = priority;
|
||||||
|
this.pattern = pattern;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int priority() {
|
||||||
|
return priority;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPattern(@NotNull Pattern pattern) {
|
||||||
|
this.pattern = pattern;
|
||||||
|
}
|
||||||
|
|
||||||
|
public @NotNull Matcher matcher(@NotNull String text) {
|
||||||
|
return pattern.matcher(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract @Nullable String extractID(@NotNull Matcher matcher);
|
||||||
|
|
||||||
|
protected abstract @NotNull List<String> get(@Nullable RECEIVER receiver, @NotNull Matcher matcher,
|
||||||
|
@NotNull Insertable<RECEIVER, ?> insertions);
|
||||||
|
|
||||||
|
public @Nullable List<String> handle(@Nullable RECEIVER receiver, @NotNull String line,
|
||||||
|
@NotNull Insertable<RECEIVER, ?> insertions) {
|
||||||
|
Matcher matcher = matcher(line);
|
||||||
|
if (!matcher.matches()) return null;
|
||||||
|
if (!insertions.inserting(extractID(matcher))) return Collections.emptyList();
|
||||||
|
return get(receiver, matcher, insertions);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compareTo(@NotNull ContentInserter<RECEIVER> o) {
|
||||||
|
return Integer.compare(o.priority, priority);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+66
@@ -0,0 +1,66 @@
|
|||||||
|
package cc.carm.lib.configuration.value.text.function.inserter;
|
||||||
|
|
||||||
|
import cc.carm.lib.configuration.value.text.function.ContentHandler;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
public interface Insertable<RECEIVER, SELF> {
|
||||||
|
|
||||||
|
List<ContentInserter<RECEIVER>> inserters();
|
||||||
|
|
||||||
|
SELF inserter(@NotNull ContentInserter<RECEIVER> inserter);
|
||||||
|
|
||||||
|
boolean noneInsertion();
|
||||||
|
|
||||||
|
boolean inserting(@NotNull String id);
|
||||||
|
|
||||||
|
@Nullable List<String> getInsertion(@NotNull String id, @Nullable RECEIVER receiver);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Insert the specific contents by the id.
|
||||||
|
*
|
||||||
|
* @param id the id of the insertion text
|
||||||
|
* @param supplier to supply the lines to insert
|
||||||
|
* @return the current {@link ContentHandler} instance
|
||||||
|
*/
|
||||||
|
SELF insert(@NotNull String id, @Nullable Function<RECEIVER, List<String>> supplier);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Insert the specific contents by the id.
|
||||||
|
*
|
||||||
|
* @param id the id of the insertion text
|
||||||
|
* @return the current {@link ContentHandler} instance
|
||||||
|
*/
|
||||||
|
default SELF insert(@NotNull String id) {
|
||||||
|
return insert(id, (Function<RECEIVER, List<String>>) null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Insert the specific contents by the id.
|
||||||
|
*
|
||||||
|
* @param id the id of the insertion text
|
||||||
|
* @param contents the lines to insert
|
||||||
|
* @return the current {@link ContentHandler} instance
|
||||||
|
*/
|
||||||
|
default SELF insert(@NotNull String id, @NotNull List<String> contents) {
|
||||||
|
return insert(id, receiver -> contents);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Insert the specific contents by the id.
|
||||||
|
*
|
||||||
|
* @param id the id of the insertion text
|
||||||
|
* @param contents the lines to insert
|
||||||
|
* @return the current {@link ContentHandler} instance
|
||||||
|
*/
|
||||||
|
default SELF insert(@NotNull String id, @NotNull String... contents) {
|
||||||
|
return insert(id, Arrays.asList(contents));
|
||||||
|
}
|
||||||
|
|
||||||
|
SELF removeInsert(@NotNull String id);
|
||||||
|
|
||||||
|
}
|
||||||
-82
@@ -1,82 +0,0 @@
|
|||||||
package cc.carm.lib.configuration.value.text.function.modifier;
|
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
import java.util.function.BiFunction;
|
|
||||||
import java.util.function.Function;
|
|
||||||
import java.util.function.Predicate;
|
|
||||||
import java.util.function.Supplier;
|
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
public class ContentReplacer<RECEIVER> {
|
|
||||||
|
|
||||||
public static <R> ContentReplacer.Builder<R> match(@NotNull Predicate<String> matcher) {
|
|
||||||
return new Builder<>(matcher);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static <R> ContentReplacer.Builder<R> match(@NotNull String id) {
|
|
||||||
return match(text -> text.equalsIgnoreCase(id));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static <R> ContentReplacer.Builder<R> match(@NotNull Pattern pattern) {
|
|
||||||
return match(text -> pattern.matcher(text).find());
|
|
||||||
}
|
|
||||||
|
|
||||||
protected final int priority;
|
|
||||||
protected final @NotNull Predicate<String> matcher;
|
|
||||||
protected final BiFunction<@NotNull RECEIVER, @NotNull String, @Nullable String> supplier;
|
|
||||||
|
|
||||||
public ContentReplacer(int priority,
|
|
||||||
@NotNull Predicate<String> matcher,
|
|
||||||
BiFunction<@NotNull RECEIVER, @NotNull String, @Nullable String> supplier) {
|
|
||||||
this.priority = priority;
|
|
||||||
this.matcher = matcher;
|
|
||||||
this.supplier = supplier;
|
|
||||||
}
|
|
||||||
|
|
||||||
public @NotNull Predicate<String> matcher() {
|
|
||||||
return this.matcher;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean check(@NotNull String param) {
|
|
||||||
return this.matcher.test(param);
|
|
||||||
}
|
|
||||||
|
|
||||||
public @Nullable String content(@NotNull RECEIVER receiver, @NotNull String matchedParam) {
|
|
||||||
return this.supplier == null ? null : this.supplier.apply(receiver, matchedParam);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class Builder<R> {
|
|
||||||
|
|
||||||
protected final @NotNull Predicate<String> matcher;
|
|
||||||
protected int priority = 0;
|
|
||||||
|
|
||||||
public Builder(@NotNull Predicate<String> matcher) {
|
|
||||||
this.matcher = matcher;
|
|
||||||
}
|
|
||||||
|
|
||||||
public @NotNull Builder<R> priority(int priority) {
|
|
||||||
this.priority = priority;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public @NotNull ContentReplacer<R> to(BiFunction<@NotNull R, @NotNull String, @Nullable String> supplier) {
|
|
||||||
return new ContentReplacer<>(this.priority, this.matcher, supplier);
|
|
||||||
}
|
|
||||||
|
|
||||||
public @NotNull ContentReplacer<R> to(Function<@NotNull R, @Nullable String> supplier) {
|
|
||||||
return to((receiver, matchedParam) -> supplier.apply(receiver));
|
|
||||||
}
|
|
||||||
|
|
||||||
public @NotNull ContentReplacer<R> to(Supplier<@Nullable String> supplier) {
|
|
||||||
return to((receiver, matchedParam) -> supplier.get());
|
|
||||||
}
|
|
||||||
|
|
||||||
public @NotNull ContentReplacer<R> to(@NotNull String content) {
|
|
||||||
return to(() -> content);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
-26
@@ -1,26 +0,0 @@
|
|||||||
package cc.carm.lib.configuration.value.text.function.modifier;
|
|
||||||
|
|
||||||
import java.util.function.Function;
|
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
public class ParamHandler {
|
|
||||||
|
|
||||||
// %(<ID>)
|
|
||||||
public static final Pattern DEFAULT_PARAM_PATTERN = Pattern.compile("%\\((?<id>[^)]+)\\)");
|
|
||||||
public static final ParamHandler DEFAULT_PARAM = new ParamHandler(
|
|
||||||
s -> {
|
|
||||||
},
|
|
||||||
s -> {
|
|
||||||
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
protected final Function<String, String> extractor;
|
|
||||||
protected final Function<String, String> replacer;
|
|
||||||
|
|
||||||
public ParamHandler(Function<String, String> extractor, Function<String, String> replacer) {
|
|
||||||
this.extractor = extractor;
|
|
||||||
this.replacer = replacer;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+105
@@ -0,0 +1,105 @@
|
|||||||
|
package cc.carm.lib.configuration.value.text.function.replacer;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.function.BiFunction;
|
||||||
|
import java.util.function.Function;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
public abstract class ContentReplacer<RECEIVER> implements Comparable<ContentReplacer<RECEIVER>> {
|
||||||
|
|
||||||
|
public static <R> ContentReplacer.Builder<R> match(@NotNull Pattern pattern) {
|
||||||
|
return new Builder<>(pattern);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <R> ContentReplacer.Builder<R> match(@NotNull String pattern) {
|
||||||
|
return match(Pattern.compile(pattern));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <R> ContentReplacer.Builder<R> replace(@NotNull String text) {
|
||||||
|
return match(Pattern.quote(text));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected final int priority;
|
||||||
|
protected @NotNull Pattern pattern;
|
||||||
|
|
||||||
|
public ContentReplacer(int priority, @NotNull Pattern pattern) {
|
||||||
|
this.priority = priority;
|
||||||
|
this.pattern = pattern;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int priority() {
|
||||||
|
return priority;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void pattern(@NotNull Pattern pattern) {
|
||||||
|
this.pattern = pattern;
|
||||||
|
}
|
||||||
|
|
||||||
|
public @NotNull Matcher matcher(@NotNull String text) {
|
||||||
|
return pattern.matcher(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String replace(@NotNull String text, @Nullable RECEIVER receiver) {
|
||||||
|
Matcher matcher = matcher(text);
|
||||||
|
StringBuffer sb = new StringBuffer();
|
||||||
|
while (matcher.find()) {
|
||||||
|
String replaced = get(receiver, matcher);
|
||||||
|
matcher.appendReplacement(sb, replaced == null ? "" : replaced);
|
||||||
|
}
|
||||||
|
matcher.appendTail(sb);
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract @Nullable String get(@Nullable RECEIVER receiver, @NotNull Matcher matcher);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compareTo(@NotNull ContentReplacer<RECEIVER> o) {
|
||||||
|
return Integer.compare(o.priority, this.priority);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Builder<R> {
|
||||||
|
|
||||||
|
protected final @NotNull Pattern pattern;
|
||||||
|
protected int priority = 0;
|
||||||
|
|
||||||
|
public Builder(@NotNull Pattern pattern) {
|
||||||
|
this.pattern = pattern;
|
||||||
|
}
|
||||||
|
|
||||||
|
public @NotNull Builder<R> priority(int priority) {
|
||||||
|
this.priority = priority;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public @NotNull ContentReplacer<R> to(BiFunction<@Nullable R, @NotNull Matcher, @Nullable String> supplier) {
|
||||||
|
return new ContentReplacer<R>(this.priority, this.pattern) {
|
||||||
|
@Override
|
||||||
|
protected @Nullable String get(@NotNull R receiver, @NotNull Matcher matcher) {
|
||||||
|
return supplier.apply(receiver, matcher);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public @NotNull ContentReplacer<R> to(Function<@Nullable R, @Nullable String> supplier) {
|
||||||
|
return to((receiver, matchedParam) -> supplier.apply(receiver));
|
||||||
|
}
|
||||||
|
|
||||||
|
public @NotNull ContentReplacer<R> to(Supplier<@Nullable String> supplier) {
|
||||||
|
return to((receiver, matchedParam) -> supplier.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
public @NotNull ContentReplacer<R> to(@NotNull String content) {
|
||||||
|
return to(() -> content);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@FunctionalInterface
|
||||||
|
public interface Constructor<R> extends Function<ContentReplacer.Builder<R>, ContentReplacer<R>> {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+63
@@ -0,0 +1,63 @@
|
|||||||
|
package cc.carm.lib.configuration.value.text.function.replacer;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.function.BiFunction;
|
||||||
|
import java.util.function.Function;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
public interface Replaceable<RECEIVER, SELF> {
|
||||||
|
|
||||||
|
List<ContentReplacer<RECEIVER>> replacers();
|
||||||
|
|
||||||
|
default String applyReplacements(@Nullable RECEIVER receiver, @NotNull String text) {
|
||||||
|
for (ContentReplacer<RECEIVER> replacer : replacers()) {
|
||||||
|
text = replacer.replace(text, receiver);
|
||||||
|
}
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
|
SELF replacer(@NotNull ContentReplacer<RECEIVER> replacer);
|
||||||
|
|
||||||
|
default SELF replacer(@NotNull Pattern pattern, @NotNull ContentReplacer.Constructor<RECEIVER> constructor) {
|
||||||
|
ContentReplacer.Builder<RECEIVER> builder = ContentReplacer.match(pattern);
|
||||||
|
return replacer(constructor.apply(builder));
|
||||||
|
}
|
||||||
|
|
||||||
|
default SELF replace(@NotNull Pattern pattern,
|
||||||
|
@NotNull BiFunction<@Nullable RECEIVER, @NotNull Matcher, @Nullable String> supplier) {
|
||||||
|
return replacer(pattern, builder -> builder.to(supplier));
|
||||||
|
}
|
||||||
|
|
||||||
|
default SELF replace(@NotNull Pattern pattern,
|
||||||
|
@NotNull Function<@Nullable RECEIVER, @Nullable String> supplier) {
|
||||||
|
return replacer(pattern, builder -> builder.to(supplier));
|
||||||
|
}
|
||||||
|
|
||||||
|
default SELF replace(@NotNull Pattern pattern,
|
||||||
|
@NotNull Supplier<@Nullable String> supplier) {
|
||||||
|
return replacer(pattern, builder -> builder.to(supplier));
|
||||||
|
}
|
||||||
|
|
||||||
|
default SELF replace(@NotNull Pattern pattern, @NotNull String replacement) {
|
||||||
|
return replacer(pattern, builder -> builder.to(replacement));
|
||||||
|
}
|
||||||
|
|
||||||
|
default SELF replace(@NotNull String text, @NotNull String replacement) {
|
||||||
|
return replacer(Pattern.compile(Pattern.quote(text)), builder -> builder.to(replacement));
|
||||||
|
}
|
||||||
|
|
||||||
|
default SELF replace(@NotNull String text, @NotNull Supplier<@Nullable String> supplier) {
|
||||||
|
return replacer(Pattern.compile(Pattern.quote(text)), builder -> builder.to(supplier));
|
||||||
|
}
|
||||||
|
|
||||||
|
default SELF replace(@NotNull String text,
|
||||||
|
@NotNull Function<@Nullable RECEIVER, @Nullable String> supplier) {
|
||||||
|
return replacer(Pattern.compile(Pattern.quote(text)), builder -> builder.to(supplier));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -11,14 +11,12 @@ import java.util.List;
|
|||||||
|
|
||||||
public class ConfigTest {
|
public class ConfigTest {
|
||||||
|
|
||||||
|
|
||||||
public static final String[] WEBSITES = new String[]{
|
public static final String[] WEBSITES = new String[]{
|
||||||
"https://carm.cc",
|
"https://carm.cc",
|
||||||
"https://www.baidu.com",
|
"https://www.baidu.com",
|
||||||
"https://www.google.com"
|
"https://www.google.com"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void test() {
|
public void test() {
|
||||||
|
|
||||||
|
|||||||
+9
-3
@@ -7,6 +7,7 @@ import org.junit.Test;
|
|||||||
import java.io.PrintStream;
|
import java.io.PrintStream;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
|
|
||||||
public class ParseTest {
|
public class ParseTest {
|
||||||
|
|
||||||
|
|
||||||
@@ -18,14 +19,15 @@ public class ParseTest {
|
|||||||
lines.add("#more-creating#{1}");
|
lines.add("#more-creating#{1}");
|
||||||
lines.add("This is a test message");
|
lines.add("This is a test message");
|
||||||
lines.add("#guidance#");
|
lines.add("#guidance#");
|
||||||
lines.add("{- }#websites#{0,1}");
|
lines.add("{ - }#websites#{0,1}");
|
||||||
lines.add("Thanks for your reading!");
|
lines.add("Thanks for your reading!");
|
||||||
|
lines.add("uuid: $UUID$");
|
||||||
lines.add("?[click]");
|
lines.add("?[click]");
|
||||||
lines.add("?[click]Click to see more!");
|
lines.add("?[click]Click to see more!");
|
||||||
lines.add("?[hidden]This entry should be hidden!");
|
lines.add("?[hidden]This entry should be hidden!");
|
||||||
|
|
||||||
Map<String, List<String>> optional = new HashMap<>();
|
Map<String, List<String>> optional = new HashMap<>();
|
||||||
optional.put("guidance", Arrays.asList("To get more information for %(name), see:"));
|
optional.put("guidance", Arrays.asList("To get more information for %(name),", " see:"));
|
||||||
optional.put("websites", Arrays.asList("https://www.baidu.com", "https://www.google.com"));
|
optional.put("websites", Arrays.asList("https://www.baidu.com", "https://www.google.com"));
|
||||||
|
|
||||||
TextContents textContents = new TextContents(lines, optional);
|
TextContents textContents = new TextContents(lines, optional);
|
||||||
@@ -33,13 +35,17 @@ public class ParseTest {
|
|||||||
PreparedText<String, PrintStream> msg = new PreparedText<String, PrintStream>(textContents)
|
PreparedText<String, PrintStream> msg = new PreparedText<String, PrintStream>(textContents)
|
||||||
.dispatcher((p, s) -> s.forEach(p::println))
|
.dispatcher((p, s) -> s.forEach(p::println))
|
||||||
.parser((p, s) -> s)
|
.parser((p, s) -> s)
|
||||||
.compiler((p, s) -> s);
|
.compiler((p, s) -> s)
|
||||||
|
.replace( // Custom replacer, replace $UUID$ with Random UUID
|
||||||
|
"$UUID$", () -> UUID.randomUUID().toString()
|
||||||
|
);
|
||||||
|
|
||||||
msg.placeholder("name", "Carm")
|
msg.placeholder("name", "Carm")
|
||||||
.insert("guidance")
|
.insert("guidance")
|
||||||
.insert("click")
|
.insert("click")
|
||||||
.insert("websites", "Baidu", "Bilibili", "Google");
|
.insert("websites", "Baidu", "Bilibili", "Google");
|
||||||
|
|
||||||
|
|
||||||
System.out.println("----------------------------");
|
System.out.println("----------------------------");
|
||||||
msg.to(System.out);
|
msg.to(System.out);
|
||||||
System.out.println("----------------------------");
|
System.out.println("----------------------------");
|
||||||
|
|||||||
Reference in New Issue
Block a user