cn.nukkit.blockproperty.ArrayBlockProperty Maven / Gradle / Ivy
package cn.nukkit.blockproperty;
import cn.nukkit.api.PowerNukkitOnly;
import cn.nukkit.api.Since;
import cn.nukkit.blockproperty.exception.InvalidBlockPropertyMetaException;
import cn.nukkit.blockproperty.exception.InvalidBlockPropertyPersistenceValueException;
import cn.nukkit.blockproperty.exception.InvalidBlockPropertyValueException;
import cn.nukkit.math.NukkitMath;
import com.google.common.base.Preconditions;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.annotation.ParametersAreNonnullByDefault;
import java.io.Serializable;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
@PowerNukkitOnly
@Since("1.4.0.0-PN")
@ParametersAreNonnullByDefault
public final class ArrayBlockProperty extends BlockProperty {
private static final long serialVersionUID = 507174531989068430L;
@Nonnull
private final E[] universe;
/**
* Nullable when {@link #ordinal} is {@code true.
*/
private final String[] persistenceNames;
private final Class eClass;
private final boolean ordinal;
private static E[] checkUniverseLength(E[] universe) {
Preconditions.checkNotNull(universe, "universe can't be null");
Preconditions.checkArgument(universe.length > 0, "The universe can't be empty");
return universe;
}
@PowerNukkitOnly
@Since("1.4.0.0-PN")
public ArrayBlockProperty(String name, boolean exportedToItem, E[] universe, int bitSize, String persistenceName) {
this(name, exportedToItem, universe, bitSize, persistenceName, false);
}
@PowerNukkitOnly
@Since("1.4.0.0-PN")
public ArrayBlockProperty(String name, boolean exportedToItem, E[] universe, int bitSize, String persistenceName, boolean ordinal) {
this(name, exportedToItem, universe, bitSize, persistenceName,ordinal, ordinal? null :
Arrays.stream(universe).map(Objects::toString).map(String::toLowerCase).toArray(String[]::new));
}
@PowerNukkitOnly
@Since("1.4.0.0-PN")
public ArrayBlockProperty(String name, boolean exportedToItem, E[] universe, int bitSize, String persistenceName, boolean ordinal, @Nullable String[] persistenceNames) {
super(name, exportedToItem, bitSize, persistenceName);
checkUniverseLength(universe);
if (!ordinal) {
Preconditions.checkArgument(persistenceNames != null, "persistenceNames can't be null when ordinal is false");
Preconditions.checkArgument(persistenceNames.length == universe.length, "persistenceNames and universe must have the same length when ordinal is false");
this.persistenceNames = persistenceNames.clone();
} else {
this.persistenceNames = null;
}
this.ordinal = ordinal;
this.universe = universe.clone();
//noinspection unchecked
this.eClass = (Class) universe.getClass().getComponentType();
Set elements = new HashSet<>();
Set persistenceNamesCheck = new HashSet<>();
for (int i = 0; i < this.universe.length; i++) {
E element = this.universe[i];
Preconditions.checkNotNull(element, "The universe can not contain null values");
Preconditions.checkArgument(elements.add(element), "The universe can not have duplicated elements");
if (!ordinal) {
String elementName = this.persistenceNames[i];
Preconditions.checkNotNull(elementName, "The persistenceNames can not contain null values");
Preconditions.checkArgument(persistenceNamesCheck.add(elementName), "The persistenceNames can not have duplicated elements");
}
}
}
@PowerNukkitOnly
@Since("1.4.0.0-PN")
public ArrayBlockProperty(String name, boolean exportedToItem, E[] universe, int bitSize) {
this(name, exportedToItem, universe, bitSize, name);
}
@PowerNukkitOnly
@Since("1.4.0.0-PN")
public ArrayBlockProperty(String name, boolean exportedToItem, E[] universe) {
this(name, exportedToItem, checkUniverseLength(universe), NukkitMath.bitLength(universe.length - 1));
}
@PowerNukkitOnly
@Since("1.4.0.0-PN")
public ArrayBlockProperty(String name, boolean exportedToItem, Class enumClass) {
this(name, exportedToItem, enumClass.getEnumConstants());
}
@Since("1.4.0.0-PN")
@PowerNukkitOnly
@Override
public ArrayBlockProperty copy() {
return new ArrayBlockProperty<>(getName(), isExportedToItem(), universe, getBitSize(), getPersistenceName(), isOrdinal(), persistenceNames);
}
@Since("1.4.0.0-PN")
@PowerNukkitOnly
@Override
public ArrayBlockProperty exportingToItems(boolean exportedToItem) {
return new ArrayBlockProperty<>(getName(), exportedToItem, universe, getBitSize(), getPersistenceName(), isOrdinal(), persistenceNames);
}
@Since("1.4.0.0-PN")
@PowerNukkitOnly
public ArrayBlockProperty ordinal(boolean ordinal) {
if (ordinal == this.ordinal) {
return this;
}
return new ArrayBlockProperty<>(getName(), isExportedToItem(), universe, getBitSize(), getPersistenceName(), ordinal);
}
@PowerNukkitOnly
@Override
public int getMetaForValue(@Nullable E value) {
if (value == null) {
return 0;
}
for (int i = 0; i < universe.length; i++) {
if (universe[i].equals(value)) {
return i;
}
}
throw new InvalidBlockPropertyValueException(this, null, value, "Element is not part of this property");
}
@Nonnull
@PowerNukkitOnly
@Override
public E getValueForMeta(int meta) {
return universe[meta];
}
@PowerNukkitOnly
@Override
public int getIntValueForMeta(int meta) {
try {
validateMetaDirectly(meta);
} catch (IllegalArgumentException e) {
throw new InvalidBlockPropertyMetaException(this, meta, meta, e);
}
return meta;
}
@Nonnull
@PowerNukkitOnly
@Override
public String getPersistenceValueForMeta(int meta) {
try {
validateMetaDirectly(meta);
} catch (IllegalArgumentException e) {
throw new InvalidBlockPropertyMetaException(this, meta, meta, e);
}
if (isOrdinal()) {
return Integer.toString(meta);
}
return persistenceNames[meta];
}
@Since("1.4.0.0-PN")
@PowerNukkitOnly
@Override
public int getMetaForPersistenceValue(String persistenceValue) {
int meta;
if (isOrdinal()) {
try {
meta = Integer.parseInt(persistenceValue);
validateMetaDirectly(meta);
} catch (IndexOutOfBoundsException|IllegalArgumentException e) {
throw new InvalidBlockPropertyPersistenceValueException(this, null, persistenceValue,
"Expected a number from 0 to " + (universe.length - 1), e);
}
return meta;
}
for (int index = 0; index < persistenceNames.length; index++) {
if (persistenceNames[index].equals(persistenceValue)) {
return index;
}
}
throw new InvalidBlockPropertyPersistenceValueException(
this, null, persistenceValue,
"The value does not exists in this property."
);
}
@PowerNukkitOnly
@Override
protected void validateDirectly(@Nullable E value) {
for (E object : universe) {
if (object == value) {
return;
}
}
throw new IllegalArgumentException(value+" is not valid for this property");
}
@PowerNukkitOnly
@Override
protected void validateMetaDirectly(int meta) {
Preconditions.checkElementIndex(meta, universe.length);
}
@PowerNukkitOnly
@Nonnull
@Override
public Class getValueClass() {
return eClass;
}
@PowerNukkitOnly
@Nonnull
public E[] getUniverse() {
return universe.clone();
}
@PowerNukkitOnly
@Since("1.4.0.0-PN")
public boolean isOrdinal() {
return ordinal;
}
@Since("1.4.0.0-PN")
@PowerNukkitOnly
@Nonnull
@Override
public E getDefaultValue() {
return universe[0];
}
@Since("1.4.0.0-PN")
@PowerNukkitOnly
@Override
public boolean isDefaultValue(@Nullable E value) {
return value == null || universe[0].equals(value);
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy