package com.supaham.commons.placeholders; import static com.google.common.base.Preconditions.checkNotNull; import static com.supaham.commons.utils.StringUtils.checkNotNullOrEmpty; import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; import javax.annotation.Nonnull; /** * Represents a data class used for {@link Placeholder}'s {@link Placeholder#apply(PlaceholderData)}. * <br /> This class provides a Builder class; accessible through {@link #builder()}. <br /> This * class provides the ability to add local objects using a {@literal Map<Object, Object>}. This is * useful for adding any extra objects that you'd like {@link Placeholder} to have access to. * * @since 0.1 */ public class PlaceholderData { private final String original; private String string = ""; private String placeholder; private final Map<Object, Object> locals; /** * Creates a new {@link PlaceholderData} using only a {@link String}. This method would be * equivalent to calling {@code builder().input(myInput).build();} * * @param input input to pass to the {@link Builder}. * * @return newly constructed {@link PlaceholderData} * * @see #builder() */ public static PlaceholderData build(@Nonnull String input) { return builder().input(input).build(); } /** * Creates a new {@link Builder} for constructing a {@link PlaceholderData} instance. * * @return {@link Builder} instance */ public static Builder builder() { return new Builder(); } private PlaceholderData(@Nonnull String string) { this(string, new HashMap<>()); } private PlaceholderData(@Nonnull String string, @Nonnull Map<Object, Object> locals) { checkNotNullOrEmpty(string); this.original = string; this.locals = locals; } /** * Gets the original version of {@link #getString()}. * * @return full original string */ public String getOriginal() { return original; } /** * Gets the full {@link String} being replaced. * * @return full string */ public String getString() { return string; } protected final void setString(@Nonnull String string) { checkNotNullOrEmpty(string); this.string = string; } protected final void append(@Nonnull String string) { checkNotNullOrEmpty(string); this.string += string; } /** * Gets the current placeholder {@link String}. * * @return placeholder string */ public String getPlaceholder() { return placeholder; } protected final void setPlaceholder(@Nonnull String placeholder) { checkNotNullOrEmpty(placeholder, "placeholder"); this.placeholder = placeholder; } /** * @see Map#containsKey(Object) */ public boolean containsKey(Object key) { return locals.containsKey(key); } /** * @see Map#containsValue(Object) */ public boolean containsValue(Object value) { return locals.containsValue(value); } /** * @see Map#get(Object) */ public Object get(Object key) { return locals.get(key); } /** * This method simply casts the {@link #get(Object)} return to the class generic type passed in * this method. * * @param key class with generic type to cast the get() to * * @see #get(Object) */ @SuppressWarnings("unchecked") public <T> T get(Class<T> key) { return (T) locals.get(key); } /** * @see Map#put(Object, Object) */ public Object put(Object key, Object value) { return this.locals.put(key, value); } public static final class Builder { private String input; private final Map<Object, Object> locals = new HashMap<>(); public Builder input(@Nonnull String input) { checkNotNullOrEmpty(input); this.input = input; return this; } public Builder put(@Nonnull Object local) { put(local.getClass(), local); return this; } public Builder put(@Nonnull Map<Object, Object> map) { checkNotNull(map, "map cannot be null."); for (Entry<Object, Object> entry : map.entrySet()) { put(entry.getKey(), entry.getValue()); } return this; } public Builder put(@Nonnull Object key, @Nonnull Object value) { checkNotNull(key, "key cannot be null"); checkNotNull(value, key + "'s value cannot be null."); this.locals.put(key, value); return this; } public PlaceholderData build() { checkNotNullOrEmpty(this.input); for (Entry<Object, Object> entry : this.locals.entrySet()) { checkNotNull(entry.getValue(), entry.getKey() + "'s value cannot be null."); } return new PlaceholderData(this.input, this.locals); } } }