io.github.almightysatan.slams.PlaceholderResolver Maven / Gradle / Ivy
/*
* SLAMS - Simple Language And Message System
* Copyright (C) 2023 Almighty-Satan, LeStegii
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*/
package io.github.almightysatan.slams;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.*;
/**
* Resolves {@link Placeholder Placeholders}.
*/
@FunctionalInterface
public interface PlaceholderResolver {
PlaceholderResolver EMPTY = key -> null;
/**
* Searches for a {@link Placeholder} with the given key. SLAMS may cache the resulting {@link Placeholder} if
* possible.
*
* @param key the key
* @return the placeholder or {@code null}
*/
@Nullable Placeholder resolve(@NotNull String key);
/**
* Returns a {@link PlaceholderResolver} that always returns null (does not resolve any
* {@link Placeholder Placeholders}).
*
* @return a {@link PlaceholderResolver} that always returns null
*/
static @NotNull PlaceholderResolver empty() {
return EMPTY;
}
/**
* Returns a {@link PlaceholderResolver} that only resolves a single {@link Placeholder}.
*
* @param placeholder the {@link Placeholder}
* @return a new {@link PlaceholderResolver}
*/
static @NotNull PlaceholderResolver of(@NotNull Placeholder placeholder) {
Objects.requireNonNull(placeholder);
return key -> key.equals(placeholder.key()) ? placeholder : null;
}
/**
* Returns a {@link PlaceholderResolver} that can resolve all the given {@link Placeholder Placeholders}.
*
* @param placeholders an array of {@link Placeholder Placeholders}
* @return a new {@link PlaceholderResolver}
*/
static @NotNull PlaceholderResolver of(@NotNull Placeholder @NotNull ... placeholders) {
if (placeholders.length == 0)
return empty();
return builder().add(placeholders).build();
}
/**
* Returns a {@link PlaceholderResolver} that will use the given {@link PlaceholderResolver PlaceholderResolvers} to
* find a {@link Placeholder}. It can therefore resolve any {@link Placeholder} resolved by at least one of the
* given {@link PlaceholderResolver PlaceholderResolvers}.
*
* @param placeholderResolvers an array of {@link PlaceholderResolver PlaceholderResolvers}
* @return a new {@link PlaceholderResolver}
*/
static @NotNull PlaceholderResolver of(@NotNull PlaceholderResolver @NotNull ... placeholderResolvers) {
if (placeholderResolvers.length == 0)
return empty();
return key -> {
for (PlaceholderResolver placeholderResolver : placeholderResolvers) {
Placeholder placeholder = placeholderResolver.resolve(key);
if (placeholder != null)
return placeholder;
}
return null;
};
}
/**
* Returns a {@link PlaceholderResolver} that will use the given {@link PlaceholderResolver PlaceholderResolvers} to
* find a {@link Placeholder}. It can therefore resolve any {@link Placeholder} resolved by at least one of the
* given {@link PlaceholderResolver PlaceholderResolvers}.
*
* @param placeholderResolvers a list of {@link PlaceholderResolver PlaceholderResolvers}
* @return a new {@link PlaceholderResolver}
*/
static @NotNull PlaceholderResolver of(@NotNull List<@NotNull PlaceholderResolver> placeholderResolvers) {
return of(placeholderResolvers.toArray(new PlaceholderResolver[0]));
}
/**
* Returns a new {@link Builder Builder}.
*
* @return a new {@link Builder Builder}
*/
static @NotNull Builder builder() {
return new Builder() {
private final Map placeholderMap = new HashMap<>();
@Override
public @NotNull PlaceholderResolver build() {
return this.placeholderMap::get;
}
@Override
public @NotNull Builder add(@NotNull Placeholder placeholder) {
String key = Objects.requireNonNull(placeholder.key());
this.placeholderMap.put(key, placeholder);
return this;
}
};
}
/**
* Used to build a {@link PlaceholderResolver}.
*/
interface Builder {
@NotNull PlaceholderResolver build();
/**
* Adds a new {@link Placeholder}.
*
* @param placeholder the {@link Placeholder}
* @return this {@link Builder}
*/
@NotNull Builder add(@NotNull Placeholder placeholder);
/**
* Adds a new {@link Placeholder}.
*
* @param key the placeholder's key
* @param valueFunction a function that evaluates this placeholder's value
* @return this {@link Builder}
*/
default @NotNull Builder add(@NotNull String key, @NotNull Placeholder.ValueFunction valueFunction) {
return this.add(Placeholder.of(key, valueFunction));
}
/**
* Adds multiple {@link Placeholder Placeholders}.
*
* @param placeholders an array of {@link Placeholder Placeholders}
* @return this {@link Builder}
*/
default @NotNull Builder add(@NotNull Placeholder @NotNull ... placeholders) {
for (Placeholder placeholder : placeholders)
this.add(placeholder);
return this;
}
/**
* Adds multiple {@link Placeholder Placeholders}.
*
* @param placeholders a {@link Collection} of {@link Placeholder Placeholders}
* @return this {@link Builder}
*/
default @NotNull Builder add(@NotNull Collection<@NotNull Placeholder> placeholders) {
for (Placeholder placeholder : placeholders)
this.add(placeholder);
return this;
}
/**
* Adds a new placeholder. The {@link Context} is ignored when evaluating its value.
*
* @param key the placeholder's key
* @param valueFunction a function that evaluates this placeholder's value
* @return this {@link Builder}
*/
default @NotNull Builder withArgs(@NotNull String key, @NotNull Placeholder.ContextIndependentValueFunction valueFunction) {
return this.add(Placeholder.withArgs(key, valueFunction));
}
/**
* Adds a new placeholder. Arguments are ignored when evaluating its value.
*
* @param key the placeholder's key
* @param valueFunction a function that evaluates this placeholder's value
* @return this {@link Builder}
*/
default @NotNull Builder withContext(@NotNull String key, @NotNull Placeholder.ArgumentIndependentValueFunction valueFunction) {
return this.add(Placeholder.withContext(key, valueFunction));
}
/**
* Adds a new placeholder. Arguments and {@link Context} are ignored when evaluating its value.
*
* @param key the placeholder's key
* @param valueFunction a function that evaluates this placeholder's value
* @return this {@link Builder}
*/
default @NotNull Builder variable(@NotNull String key, @NotNull Placeholder.ArgumentAndContextIndependentValueFunction valueFunction) {
return this.add(Placeholder.variable(key, valueFunction));
}
/**
* Adds a new placeholder with a constant value.
*
* @param key the placeholder's key
* @param value the value
* @return this {@link Builder}
*/
default @NotNull Builder constant(@NotNull String key, @NotNull String value) {
return this.add(Placeholder.constant(key, value));
}
/**
* Adds a new {@link Placeholder}. If the {@link Context} is not {@code null} and of the given type,
* {@code contextValueFunction} will be used to evaluate the value. Otherwise {@code fallbackValueFunction} will be
* used.
*
* @param key the placeholder's key
* @param type class of the context type
* @param contextValueFunction a function that evaluates this placeholder's value
* @param fallbackValueFunction a function that evaluates this placeholder's value
* @param the context type
* @return this {@link Builder}
*/
default @NotNull Builder contextual(@NotNull String key, @NotNull Class type, @NotNull Placeholder.ContextualValueFunction contextValueFunction, @NotNull Placeholder.ValueFunction fallbackValueFunction) {
return this.add(Placeholder.contextual(key, type, contextValueFunction, fallbackValueFunction));
}
/**
* Adds a new {@link Placeholder}. If the {@link Context} is not {@code null} and of the given type,
* {@code contextValueFunction} will be used to evaluate the value. Otherwise {@code fallbackValue} will be used.
*
* @param key the placeholder's key
* @param type class of the context type
* @param contextValueFunction a function that evaluates this placeholder's value
* @param fallbackValue the fallback value
* @param the context type
* @return this {@link Builder}
*/
default @NotNull Builder contextual(@NotNull String key, @NotNull Class type, @NotNull Placeholder.ContextualValueFunction contextValueFunction, @NotNull String fallbackValue) {
return this.add(Placeholder.contextual(key, type, contextValueFunction, fallbackValue));
}
/**
* Adds a new {@link Placeholder}. If the {@link Context} is not {@code null} and of the given type,
* {@code contextValueFunction} will be used to evaluate the value.
*
* @param key the placeholder's key
* @param type class of the context type
* @param contextValueFunction a function that evaluates this placeholder's value
* @param the context type
* @return this {@link Builder}
*/
default @NotNull Builder contextual(@NotNull String key, @NotNull Class type, @NotNull Placeholder.ContextualValueFunction contextValueFunction) {
return this.add(Placeholder.contextual(key, type, contextValueFunction));
}
/**
* Adds a new {@link Placeholder}. If the {@link Context} is not {@code null} and of the given type,
* {@code contextValueFunction} will be used to evaluate the value. Otherwise {@code fallbackValueFunction} will be
* used. Possible arguments passed to the placeholder are ignored.
*
* @param key the placeholder's key
* @param type class of the context type
* @param contextValueFunction a function that evaluates this placeholder's value
* @param fallbackValueFunction a function that evaluates this placeholder's value
* @param the context type
* @return this {@link Builder}
*/
default @NotNull Builder contextual(@NotNull String key, @NotNull Class type, @NotNull Placeholder.ArgumentIndependentContextualValueFunction contextValueFunction, @NotNull Placeholder.ValueFunction fallbackValueFunction) {
return this.add(Placeholder.contextual(key, type, contextValueFunction, fallbackValueFunction));
}
/**
* Adds a new {@link Placeholder}. If the {@link Context} is not {@code null} and of the given type,
* {@code contextValueFunction} will be used to evaluate the value. Otherwise {@code fallbackValue} will be used.
* Possible arguments passed to the placeholder are ignored.
*
* @param key the placeholder's key
* @param type class of the context type
* @param contextValueFunction a function that evaluates this placeholder's value
* @param fallbackValue the fallback value
* @param the context type
* @return this {@link Builder}
*/
default @NotNull Builder contextual(@NotNull String key, @NotNull Class type, @NotNull Placeholder.ArgumentIndependentContextualValueFunction contextValueFunction, @NotNull String fallbackValue) {
return this.add(Placeholder.contextual(key, type, contextValueFunction, fallbackValue));
}
/**
* Adds a new {@link Placeholder}. If the {@link Context} is not {@code null} and of the given type,
* {@code contextValueFunction} will be used to evaluate the value. Possible arguments passed to the placeholder are
* ignored.
*
* @param key the placeholder's key
* @param type class of the context type
* @param contextValueFunction a function that evaluates this placeholder's value
* @param the context type
* @return this {@link Builder}
*/
default @NotNull Builder contextual(@NotNull String key, @NotNull Class type, @NotNull Placeholder.ArgumentIndependentContextualValueFunction contextValueFunction) {
return this.add(Placeholder.contextual(key, type, contextValueFunction));
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy