All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.spongepowered.api.data.Key Maven / Gradle / Ivy

The newest version!
/*
 * This file is part of SpongeAPI, licensed under the MIT License (MIT).
 *
 * Copyright (c) SpongePowered 
 * Copyright (c) contributors
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
package org.spongepowered.api.data;

import io.leangen.geantyref.TypeToken;
import org.spongepowered.api.ResourceKey;
import org.spongepowered.api.ResourceKeyed;
import org.spongepowered.api.Sponge;
import org.spongepowered.api.data.value.ListValue;
import org.spongepowered.api.data.value.MapValue;
import org.spongepowered.api.data.value.SetValue;
import org.spongepowered.api.data.value.Value;
import org.spongepowered.api.data.value.ValueContainer;
import org.spongepowered.api.data.value.WeightedCollectionValue;
import org.spongepowered.api.event.EventListener;
import org.spongepowered.api.event.data.ChangeDataHolderEvent;
import org.spongepowered.api.event.lifecycle.RegisterRegistryValueEvent;
import org.spongepowered.api.util.ResourceKeyedBuilder;
import org.spongepowered.api.util.annotation.CatalogedBy;
import org.spongepowered.api.util.weighted.WeightedTable;
import org.spongepowered.plugin.PluginContainer;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Collection;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.function.BiPredicate;

/**
 * Represents a key to an underlying {@link Value} such that the underlying
 * value can be retrieved from a {@link ValueContainer}. For the key to be used
 * through retrieval of {@link DataHolder}s, it's required to use a
 * {@link DataRegistration} if the data is needed to be serialized, or dynamically
 * provided for through external mechanisms, through {@link DataProvider}s.
 *
 * 

If dynamic or persistent retention of the {@link Value Values} by * {@link Key keys} is not desired, a registration with {@link DataRegistration} * is optional. This would mean that any submitted {@link Value}s of a * {@link Key} without an associated {@link DataRegistration} will be only * stored on a * {@link org.spongepowered.api.data.DataHolder.Mutable mutable DataHolder} for * the duration that that holder exists. The value would not persist between * reloads, restarts, etc.

* * @param The type of {@link Value} */ @CatalogedBy(Keys.class) public interface Key> extends ResourceKeyed { /** * Creates a {@link Key.Builder} which allows creation of a {@link Key} * to later be registered for accessing values from * a {@link ValueContainer}. It is the default policy that a * custom created {@link Key} is NOT PERSISTENT by * Sponge. If custom keys for {@link DataHolder}s is desired to be * persisted, a {@link DataRegistration} is required. * * @see DataRegistration * @return The key builder */ @SuppressWarnings("unchecked") static Builder builder() { return Sponge.game().builderProvider().provide(Builder.class); } static Key> from(final PluginContainer plugin, final String value, final Class type) { return Key.from(ResourceKey.of(Objects.requireNonNull(plugin, "plugin"), value), type); } static Key> from(final ResourceKey resourceKey, final Class type) { return Key.builder() .key(Objects.requireNonNull(resourceKey, "resourceKey")) .elementType(Objects.requireNonNull(type, "type")) .build(); } static Key> fromList(final PluginContainer plugin, final String value, final Class type) { return Key.fromList(ResourceKey.of(Objects.requireNonNull(plugin, "plugin"), value), type); } static Key> fromList(final ResourceKey resourceKey, final Class type) { return Key.builder() .key(Objects.requireNonNull(resourceKey, "resourceKey")) .listElementType(Objects.requireNonNull(type, "type")) .build(); } static Key> fromSet(final PluginContainer plugin, final String value, final Class type) { return Key.fromSet(ResourceKey.of(Objects.requireNonNull(plugin, "plugin"), value), type); } static Key> fromSet(final ResourceKey resourceKey, final Class type) { return Key.builder() .key(Objects.requireNonNull(resourceKey, "resourceKey")) .setElementType(Objects.requireNonNull(type, "type")) .build(); } static Key> fromMap(final PluginContainer plugin, final String value, final Class keyType, final Class valueType) { return Key.fromMap(ResourceKey.of(Objects.requireNonNull(plugin, "plugin"), value), keyType, valueType); } static Key> fromMap(final ResourceKey resourceKey, final Class keyType, final Class valueType) { return Key.builder() .key(Objects.requireNonNull(resourceKey, "resourceKey")) .mapElementType(Objects.requireNonNull(keyType, "keyType"), Objects.requireNonNull(valueType, "valueType")) .build(); } /** * Gets the type of the {@link Value} this {@link Key} is representing. * * @return The value generic type */ Type valueType(); /** * Gets the type of the element of the {@link Value} this {@link Key} * is representing. On occasion, if the element is a {@link Collection} type, * one can use {@link ParameterizedType#getActualTypeArguments()} to access * type parameters, such as the element type parameter for {@link List} or * {@link Map} values. * * @return The element generic type */ Type elementType(); /** * Gets the {@link Comparator} to * compare values of this key. * * @return The value comparator */ Comparator elementComparator(); /** * Gets the includes tester {@link BiPredicate}. This predicate should * return {@code true} when the second parameter (the key value) * is included in the first one (the matcher value). * *

The default tester will always return {@code false}.

* * @return The includes tester bi predicate * @see KeyValueMatcher.Operator#INCLUDES * @see KeyValueMatcher.Operator#EXCLUDES */ BiPredicate elementIncludesTester(); /** * Register an event listener which listens to the value the key accesses * changing. * * @param holderFilter The data holder to filter with * @param listener The event listener * @param The class type of the data holder */ void registerEvent(PluginContainer plugin, Class holderFilter, EventListener listener); interface Builder> extends ResourceKeyedBuilder, Builder> { /** * Starter method for the builder, to be used immediately after * {@link Key#builder()} is called. This defines the generics for the * builder itself to provide the properly generified {@link Key}. * *

For common cases, element types can be specified using one of the * {@code *elementType(Class)} methods. If a new {@link TypeToken} is to * be created, it is recommended to create an anonymous class instance * of a token, as described in the GeAnTyRef documentation *

* * @param token The type token * @param The element type of the Key * @param The base value type of the key * @return This builder, generified */ > Builder type(TypeToken token); /** * Starter method for the builder, to be used immediately after * {@link Key#builder()} is called. This defines the generics for the * builder itself to provide the properly generified {@link Key}. * *

This overload is provided for simple cases where a plain * {@link Value} is used.

* * @param type The element type * @param The element type of the Key * @return This builder, generified */ Builder> elementType(Class type); /** * Starter method for the builder, to be used immediately after * {@link Key#builder()} is called. This defines the generics for the * builder itself to provide the properly generified {@link Key}. * *

This overload is provided for simple cases where a plain * {@link Value} is used.

* * @param type The element type * @param The element type of the Key * @return This builder, generified */ Builder> elementType(TypeToken type); /** * Starter method for the builder, to be used immediately after * {@link Key#builder()} is called. This defines the generics for the * builder itself to provide the properly generified {@link Key}. * *

This overload is provided for simple cases where a plain * {@link ListValue} is used.

* * @param type The element type * @param The element type of the Key * @return This builder, generified */ Builder, ListValue> listElementType(Class type); /** * Starter method for the builder, to be used immediately after * {@link Key#builder()} is called. This defines the generics for the * builder itself to provide the properly generified {@link Key}. * *

This overload is provided for simple cases where a plain * {@link ListValue} is used.

* * @param type The element type * @param The element type of the Key * @return This builder, generified */ Builder, ListValue> listElementType(TypeToken type); /** * Starter method for the builder, to be used immediately after * {@link Key#builder()} is called. This defines the generics for the * builder itself to provide the properly generified {@link Key}. * *

This overload is provided for simple cases where a plain * {@link SetValue} is used.

* * @param type The element type * @param The element type of the Key * @return This builder, generified */ Builder, SetValue> setElementType(Class type); /** * Starter method for the builder, to be used immediately after * {@link Key#builder()} is called. This defines the generics for the * builder itself to provide the properly generified {@link Key}. * *

This overload is provided for simple cases where a plain * {@link SetValue} is used.

* * @param type The element type * @param The element type of the Key * @return This builder, generified */ Builder, SetValue> setElementType(TypeToken type); /** * Starter method for the builder, to be used immediately after * {@link Key#builder()} is called. This defines the generics for the * builder itself to provide the properly generified {@link Key}. * *

This overload is provided for simple cases where a plain * {@link MapValue} is used.

* * @param keyType the key type * @param valueType the value type * @param The element type of the Key's key type * @param The element type of the Key's value type * @return This builder, generified */ Builder, MapValue> mapElementType(Class keyType, Class valueType); /** * Starter method for the builder, to be used immediately after * {@link Key#builder()} is called. This defines the generics for the * builder itself to provide the properly generified {@link Key}. * *

This overload is provided for simple cases where a plain * {@link MapValue} is used.

* * @param keyType the key type * @param valueType the value type * @param The element type of the Key's key type * @param The element type of the Key's value type * @return This builder, generified */ Builder, MapValue> mapElementType(TypeToken keyType, TypeToken valueType); /** * Starter method for the builder, to be used immediately after * {@link Key#builder()} is called. This defines the generics for the * builder itself to provide the properly generified {@link Key}. * *

This overload is provided for simple cases where a plain * {@link WeightedCollectionValue} is used.

* * @param type The element type * @param The element type of the Key * @return This builder, generified */ Builder, WeightedCollectionValue> weightedCollectionElementType(Class type); /** * Starter method for the builder, to be used immediately after * {@link Key#builder()} is called. This defines the generics for the * builder itself to provide the properly generified {@link Key}. * *

This overload is provided for simple cases where a plain * {@link WeightedCollectionValue} is used.

* * @param type The element type * @param The element type of the Key * @return This builder, generified */ Builder, WeightedCollectionValue> weightedCollectionElementType(TypeToken type); /** * Sets the {@link Comparator} that can be used to compare * the elements. * *

Setting the comparator is a requirement * if the element type isn't {@link Comparable}.

* * @param comparator The comparator * @return This builder, for chaining */ Builder comparator(Comparator comparator); /** * Sets the includes tester {@link BiPredicate}. This predicate should * return {@code true} when the second parameter is included in the first one. * *

The default tester will always return {@code false}.

* * @param predicate The tester bi predicate * @return This builder, for chaining * @see KeyValueMatcher.Operator#INCLUDES * @see KeyValueMatcher.Operator#EXCLUDES */ Builder includesTester(BiPredicate predicate); /** * Builds the {@link Key}. * * @return The built key * @throws IllegalStateException If not all required options were specified; * {@link #type(TypeToken)}. */ @Override Key build(); } }