Make PlotFlag more generic to allow generic flag creation

This commit is contained in:
Hannes Greule 2020-02-11 23:33:05 +01:00
parent b3db67ab76
commit 1c4c680e18
9 changed files with 77 additions and 70 deletions

View File

@ -11,7 +11,7 @@ import java.util.Map;
@EqualsAndHashCode(of = "flagMap") public class FlagContainer {
private final FlagContainer parentContainer;
private final Map<Class<?>, PlotFlag<?>> flagMap = new HashMap<>();
private final Map<Class<?>, PlotFlag<?, ?>> flagMap = new HashMap<>();
public FlagContainer(@Nullable final FlagContainer parentContainer) {
this.parentContainer = parentContainer;
@ -21,25 +21,25 @@ import java.util.Map;
return this.parentContainer;
}
protected Map<Class<?>, PlotFlag<?>> getInternalPlotFlagMap() {
protected Map<Class<?>, PlotFlag<?, ?>> getInternalPlotFlagMap() {
return this.flagMap;
}
public Map<Class<?>, PlotFlag<?>> getFlagMap() {
return ImmutableMap.<Class<?>, PlotFlag<?>>builder().putAll(this.flagMap).build();
public Map<Class<?>, PlotFlag<?, ?>> getFlagMap() {
return ImmutableMap.<Class<?>, PlotFlag<?, ?>>builder().putAll(this.flagMap).build();
}
public void addFlag(final PlotFlag<?> flag) {
public void addFlag(final PlotFlag<?, ? extends PlotFlag<?, ?>> flag) {
this.flagMap.put(flag.getClass(), flag);
}
public void addAll(final Collection<PlotFlag<?>> flags) {
for (final PlotFlag<?> flag : flags) {
public void addAll(final Collection<PlotFlag<?, ?>> flags) {
for (final PlotFlag<?, ?> flag : flags) {
this.addFlag(flag);
}
}
public Collection<PlotFlag<?>> getRecognizedPlotFlags() {
public Collection<PlotFlag<?, ?>> getRecognizedPlotFlags() {
return this.getHighestClassContainer().getFlagMap().values();
}
@ -50,8 +50,8 @@ import java.util.Map;
return this;
}
public PlotFlag<?> getFlagErased(Class<?> flagClass) {
final PlotFlag<?> flag = this.flagMap.get(flagClass);
public PlotFlag<?, ?> getFlagErased(Class<?> flagClass) {
final PlotFlag<?, ?> flag = this.flagMap.get(flagClass);
if (flag != null) {
return flag;
} else {
@ -62,10 +62,10 @@ import java.util.Map;
return null;
}
public <T> PlotFlag<T> getFlag(final Class<? extends PlotFlag<T>> flagClass) {
final PlotFlag<?> flag = this.flagMap.get(flagClass);
public <T> PlotFlag<T, ?> getFlag(final Class<? extends PlotFlag<T, ?>> flagClass) {
final PlotFlag<?, ?> flag = this.flagMap.get(flagClass);
if (flag != null) {
return (PlotFlag<T>) flag;
return (PlotFlag<T, ?>) flag;
} else {
if (getParentContainer() != null) {
return getParentContainer().getFlag(flagClass);

View File

@ -14,8 +14,8 @@ public final class GlobalFlagContainer extends FlagContainer {
private final Map<String, Class<?>> stringClassMap = new HashMap<>();
@Override public PlotFlag<?> getFlagErased(Class<?> flagClass) {
final PlotFlag<?> flag = super.getFlagErased(flagClass);
@Override public PlotFlag<?, ?> getFlagErased(Class<?> flagClass) {
final PlotFlag<?, ?> flag = super.getFlagErased(flagClass);
if (flag != null) {
return flag;
} else {
@ -24,10 +24,10 @@ public final class GlobalFlagContainer extends FlagContainer {
}
}
@Nonnull @Override public <T> PlotFlag<T> getFlag(Class<? extends PlotFlag<T>> flagClass) {
final PlotFlag<?> flag = super.getFlag(flagClass);
@Nonnull @Override public <T> PlotFlag<T, ?> getFlag(Class<? extends PlotFlag<T, ?>> flagClass) {
final PlotFlag<?, ?> flag = super.getFlag(flagClass);
if (flag != null) {
return (PlotFlag<T>) flag;
return (PlotFlag<T, ?>) flag;
} else {
throw new IllegalStateException(String.format("Unrecognized flag '%s'. All flag types"
+ " must be present in the global flag container.", flagClass.getSimpleName()));
@ -37,10 +37,10 @@ public final class GlobalFlagContainer extends FlagContainer {
private GlobalFlagContainer() {
super(null);
// Register all default flags here
this.addFlag(new ExplosionFlag());
this.addFlag(ExplosionFlag.EXPLOSION_FALSE);
}
@Override public void addFlag(PlotFlag<?> flag) {
@Override public void addFlag(PlotFlag<?, ?> flag) {
super.addFlag(flag);
this.stringClassMap.put(flag.getName().toLowerCase(Locale.ENGLISH), flag.getClass());
}
@ -49,7 +49,7 @@ public final class GlobalFlagContainer extends FlagContainer {
return this.stringClassMap.get(name.toLowerCase(Locale.ENGLISH));
}
public PlotFlag<?> getFlagFromString(final String name) {
public PlotFlag<?, ?> getFlagFromString(final String name) {
final Class<?> flagClass = this.getFlagClassFromString(name);
if (flagClass == null) {
return null;

View File

@ -14,9 +14,9 @@ import java.util.Locale;
*
* @param <T> Value contained in the flag.
*/
@EqualsAndHashCode(of = "value") public abstract class PlotFlag<T> {
@EqualsAndHashCode(of = "value") public abstract class PlotFlag<T, F extends PlotFlag<T, F>> {
private T value;
private final T value;
private final Captions flagCategory;
private final Captions flagDescription;
@ -42,33 +42,24 @@ import java.util.Locale;
}
/**
* Update the flag value.
*
* @param newValue New flag value.
*/
public T setFlagValue(@NotNull final T newValue) {
return (this.value = Preconditions.checkNotNull(newValue, "flag values may not be null"));
}
/**
* Parse a string into a flag value, and throw an exception in the case that the
* string does not represent a valid flag value. The flag value will be updated to
* the newly parsed value.
* Parse a string into a flag, and throw an exception in the case that the
* string does not represent a valid flag value. This instance won't change its
* state, but instead an instance holding the parsed flag value will be returned.
*
* @param input String to parse.
* @return Parsed value, if valid.
* @throws FlagParseException If the value could not be parsed.
*/
public abstract T parse(@NotNull final String input) throws FlagParseException;
public abstract F parse(@NotNull final String input) throws FlagParseException;
/**
* Merge two flag values into one and updates the flag value.
* Merge this flag's value with another value and return an instance
* holding the merged value.
*
* @param oldValue Existing flag value.
* @param newValue New flag value.
* @return Flag containing parsed flag value.
*/
public abstract T merge(@NotNull final T oldValue, @NotNull final T newValue);
public abstract F merge(@NotNull final T newValue);
/**
* Returns a string representation of the flag instance, that when
@ -93,4 +84,6 @@ import java.util.Locale;
public abstract String getExample();
protected abstract F flagOf(@NotNull T value);
}

View File

@ -2,15 +2,21 @@ package com.github.intellectualsites.plotsquared.plot.flags.implementations;
import com.github.intellectualsites.plotsquared.plot.config.Captions;
import com.github.intellectualsites.plotsquared.plot.flags.types.BooleanFlag;
import org.jetbrains.annotations.NotNull;
public class ExplosionFlag extends BooleanFlag {
public class ExplosionFlag extends BooleanFlag<ExplosionFlag> {
public static final ExplosionFlag EXPLOSION_TRUE = new ExplosionFlag(true);
public static final ExplosionFlag EXPLOSION_FALSE = new ExplosionFlag(false);
public ExplosionFlag() {
super(Captions.FLAG_DESCRIPTION_EXPLOSION);
private ExplosionFlag(boolean value) {
super(value, Captions.FLAG_DESCRIPTION_EXPLOSION);
}
@Override public String getExample() {
return "true";
}
@Override protected ExplosionFlag flagOf(@NotNull Boolean value) {
return value ? EXPLOSION_TRUE : EXPLOSION_FALSE;
}
}

View File

@ -10,17 +10,17 @@ import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
public class BlockTypeListFlag extends ListFlag<BlockType> {
public class BlockTypeListFlag extends ListFlag<BlockType, BlockTypeListFlag> {
public BlockTypeListFlag(Captions description) {
super(Captions.FLAG_CATEGORY_BLOCK_LIST, description);
public BlockTypeListFlag(List<BlockType> blockTypeList, Captions description) {
super(blockTypeList, Captions.FLAG_CATEGORY_BLOCK_LIST, description);
}
@Override public List<BlockType> parse(@NotNull String input) throws FlagParseException {
@Override public BlockTypeListFlag parse(@NotNull String input) throws FlagParseException {
final List<BlockType> parsedBlocks = new ArrayList<>();
final String[] split = input.split(",(?![^\\(\\[]*[\\]\\)])");
if (split.length == 0) {
return parsedBlocks;
return this.flagOf(parsedBlocks);
}
for (final String blockString : split) {
final BlockState blockState = BlockUtil.get(blockString);
@ -30,11 +30,15 @@ public class BlockTypeListFlag extends ListFlag<BlockType> {
parsedBlocks.add(blockState.getBlockType());
}
}
return parsedBlocks;
return this.flagOf(parsedBlocks);
}
@Override public String getExample() {
return "air,grass_block";
}
@Override protected BlockTypeListFlag flagOf(@NotNull List<BlockType> value) {
return new BlockTypeListFlag(value, getFlagDescription()); // copy the description
}
}

View File

@ -9,7 +9,7 @@ import java.util.Arrays;
import java.util.Collection;
import java.util.Locale;
public abstract class BooleanFlag extends PlotFlag<Boolean> {
public abstract class BooleanFlag<F extends PlotFlag<Boolean, F>> extends PlotFlag<Boolean, F> {
private static final Collection<String> positiveValues = Arrays.asList("1", "yes", "allow", "true");
private static final Collection<String> negativeValues = Arrays.asList("0", "no", "deny", "disallow", "false");
@ -34,18 +34,18 @@ public abstract class BooleanFlag extends PlotFlag<Boolean> {
this(false, description);
}
@Override public Boolean parse(@NotNull String input) throws FlagParseException {
@Override public F parse(@NotNull String input) throws FlagParseException {
if (positiveValues.contains(input.toLowerCase(Locale.ENGLISH))) {
return true;
return this.flagOf(true);
} else if (negativeValues.contains(input.toLowerCase(Locale.ENGLISH))) {
return false;
return this.flagOf(false);
} else {
throw new FlagParseException(this, input, Captions.FLAG_ERROR_BOOLEAN);
}
}
@Override public Boolean merge(@NotNull Boolean oldValue, @NotNull Boolean newValue) {
return this.setFlagValue(oldValue || newValue);
@Override public F merge(@NotNull Boolean newValue) {
return this.flagOf(getValue() || newValue);
}
@Override public String toString() {

View File

@ -5,26 +5,26 @@ import com.github.intellectualsites.plotsquared.plot.flags.FlagParseException;
import com.github.intellectualsites.plotsquared.plot.flags.PlotFlag;
import org.jetbrains.annotations.NotNull;
public class IntegerFlag extends PlotFlag<Integer> {
public class IntegerFlag extends PlotFlag<Integer, IntegerFlag> {
protected IntegerFlag(final int defaultValue, @NotNull Captions flagDescription) {
super(defaultValue, Captions.FLAG_CATEGORY_INTEGERS, flagDescription);
protected IntegerFlag(final int value, @NotNull Captions flagDescription) {
super(value, Captions.FLAG_CATEGORY_INTEGERS, flagDescription);
}
protected IntegerFlag(@NotNull Captions flagDescription) {
this(0, flagDescription);
}
@Override public Integer parse(@NotNull String input) throws FlagParseException {
@Override public IntegerFlag parse(@NotNull String input) throws FlagParseException {
try {
return Integer.parseInt(input);
return flagOf(Integer.parseInt(input));
} catch (final Throwable throwable) {
throw new FlagParseException(this, input, Captions.FLAG_ERROR_INTEGER);
}
}
@Override public Integer merge(@NotNull Integer oldValue, @NotNull Integer newValue) {
return oldValue + newValue;
@Override public IntegerFlag merge(@NotNull Integer newValue) {
return flagOf(getValue() + newValue);
}
@Override public String toString() {
@ -35,4 +35,8 @@ public class IntegerFlag extends PlotFlag<Integer> {
return "10";
}
@Override protected IntegerFlag flagOf(@NotNull Integer value) {
return new IntegerFlag(value, getFlagDescription());
}
}

View File

@ -8,17 +8,17 @@ import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
public abstract class ListFlag<V> extends PlotFlag<List<V>> {
public abstract class ListFlag<V, F extends PlotFlag<List<V>, F>> extends PlotFlag<List<V>, F> {
public ListFlag(final Captions category, final Captions description) {
super(new ArrayList<>(), category, description);
public ListFlag(final List<V> valueList, final Captions category, final Captions description) {
super(valueList, category, description);
}
@Override public List<V> merge(@NotNull List<V> oldValue, @NotNull List<V> newValue) {
@Override public F merge(@NotNull List<V> newValue) {
final List<V> mergedList = new ArrayList<>();
mergedList.addAll(oldValue);
mergedList.addAll(getValue());
mergedList.addAll(newValue);
return this.setFlagValue(mergedList);
return this.flagOf(mergedList);
}
@Override public String toString() {

View File

@ -213,7 +213,7 @@ public class Plot {
* @see Plot#getPlot(Location) for existing plots
*/
public Plot(@NotNull PlotId id, UUID owner, HashSet<UUID> trusted, HashSet<UUID> members,
HashSet<UUID> denied, String alias, BlockLoc position, Collection<PlotFlag<?>> flags,
HashSet<UUID> denied, String alias, BlockLoc position, Collection<PlotFlag<?, ?>> flags,
PlotArea area, boolean[] merged, long timestamp, int temp) {
this.id = id;
this.area = area;
@ -229,7 +229,7 @@ public class Plot {
this.temp = temp;
this.flagContainer = new FlagContainer(area.getFlagContainer());
if (flags != null) {
for (PlotFlag<?> flag : flags) {
for (PlotFlag<?, ?> flag : flags) {
this.flagContainer.addFlag(flag);
}
}
@ -3148,7 +3148,7 @@ public class Plot {
return getMerged(direction.getIndex());
}
public <T> T getFlag(final Class<? extends PlotFlag<T>> flagClass) {
public <T> T getFlag(final Class<? extends PlotFlag<T, ?>> flagClass) {
return this.flagContainer.getFlag(flagClass).getValue();
}