org.spongepowered.api.data.value.ValueContainer Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of spongeapi Show documentation
Show all versions of spongeapi Show documentation
A plugin API for Minecraft: Java Edition
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.value;
import com.google.common.collect.ImmutableSet;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.spongepowered.api.data.DataHolder;
import org.spongepowered.api.data.DataManipulator;
import org.spongepowered.api.data.Key;
import java.util.NoSuchElementException;
import java.util.Objects;
import java.util.Optional;
import java.util.OptionalDouble;
import java.util.OptionalInt;
import java.util.OptionalLong;
import java.util.Set;
/**
* A value holder is a holder of a particular set of {@link Value}s. While
* there exists a {@link DataHolder} and {@link DataManipulator},
* the emphasis of {@link ValueContainer} is that it only contains "data". It
* is not known whether a {@code ValueHolder} is mutable or immutable.
*
* Being that a {@code ValueHolder} is literally a container of
* {@link Value}s, it itself does not contain the underlying values of
* data. A {@link ValueContainer} may not always be parented by another
* {@link ValueContainer}, such as the case for {@link DataManipulator}s and
* {@link org.spongepowered.api.data.DataHolder.Mutable}s, it is recommended to knowingly understand the
* fundamental differences between them.
*/
public interface ValueContainer {
/**
* Attempts to get the underlying value backed by a {@link Value}
* linked to the provided {@link Key}. If the {@link Key} is not
* supported, {@link Optional#empty()} is returned. It is important
* to check for support of a {@link Key} by either calling
* {@link #supports(Value)} or {@link #supports(Key)}.
*
* @param key The key to retrieve the value for
* @param The type of value
* @return The value, if available
*/
Optional get(Key extends Value> key);
/**
* Attempts to get the underlying int value backed by a {@link Value}
* linked to the provided {@link Key}. If the {@link Key} is not
* supported, {@link Optional#empty()} is returned. It is important
* to check for support of a {@link Key} by either calling
* {@link #supports(Value)} or {@link #supports(Key)}.
*
* @param key The key to retrieve the value for
* @return The value, if available
*/
default OptionalInt getInt(final Key extends Value> key) {
return this.get(key).map(OptionalInt::of).orElseGet(OptionalInt::empty);
}
/**
* Attempts to get the underlying double value backed by a {@link Value}
* linked to the provided {@link Key}. If the {@link Key} is not
* supported, {@link Optional#empty()} is returned. It is important
* to check for support of a {@link Key} by either calling
* {@link #supports(Value)} or {@link #supports(Key)}.
*
* @param key The key to retrieve the value for
* @return The value, if available
*/
default OptionalDouble getDouble(final Key extends Value> key) {
return this.get(key).map(OptionalDouble::of).orElseGet(OptionalDouble::empty);
}
/**
* Attempts to get the underlying long value backed by a {@link Value}
* linked to the provided {@link Key}. If the {@link Key} is not
* supported, {@link Optional#empty()} is returned. It is important
* to check for support of a {@link Key} by either calling
* {@link #supports(Value)} or {@link #supports(Key)}.
*
* @param key The key to retrieve the value for
* @return The value, if available
*/
default OptionalLong getLong(final Key extends Value> key) {
return this.get(key).map(OptionalLong::of).orElseGet(OptionalLong::empty);
}
/**
* Attempts to get the underlying value backed by a {@link Value}
* linked to the provided {@link Key}.
*
* If the {@link Key} is not supported or
* available, {@link NoSuchElementException} will be thrown.
*
* @param key The key
* @param The type of value
* @return The value
* @throws NoSuchElementException If the value is not supported or present
*/
default E require(final Key extends Value> key) {
return this.get(key).orElseThrow(() -> new NoSuchElementException(String.format(
"Could not retrieve value for key '%s'", key.toString())));
}
/**
* Attempts to get the underlying value if available and supported. If the
* {@link Value} is not supported whatsoever by this
* {@link ValueContainer}, an exception is thrown.
*
* @param key The {@link Key} backing the {@link Value}
* @param The type of value
* @return The value, or null if not set
*/
default @Nullable E getOrNull(final Key extends Value> key) {
final Optional value = this.get(key);
if (value.isPresent()) {
return value.get();
}
if (!this.supports(key)) {
throw new UnsupportedOperationException("Key not supported. Key: " + key);
}
return null;
}
/**
* Attempts to get the underlying value if available. If the value is not
* set, the given {@code defaultValue} is returned, if the
* {@link Value} is even supported.
*
* @param key The key backing the {@link Value}
* @param defaultValue The value to default to if not set
* @param The type of value
* @return The value, or default if not set
*/
default E getOrElse(final Key extends Value> key, E defaultValue) {
return this.get(key).orElse(Objects.requireNonNull(defaultValue, "defaultValue"));
}
/**
* Gets the {@link Value} for the given {@link Key}.
*
* @param key The key linked to the {@link Value}
* @param The type of the return type
* @param The type of value
* @return The value, if available
*/
> Optional getValue(Key key);
/**
* Attempts to get the underlying value backed by a {@link Value}
* linked to the provided {@link Key}.
*
* If the {@link Key} is not supported or
* available, {@link NoSuchElementException} will be thrown.
*
* @param key The key
* @param The type of element wrapped by the value
* @param The type of value
* @return The value
* @throws NoSuchElementException If the value is not supported or present
*/
default > V requireValue(final Key key) {
return this.getValue(key).orElseThrow(() -> new NoSuchElementException(String.format(
"Could not retrieve value for key '%s'", key.toString())));
}
/**
* Checks if the given {@link Key} is supported by this
* {@link ValueContainer}.
*
* @param key The key to check
* @return True if the key and value backed by the key is supported
*/
boolean supports(Key> key);
/**
* Checks if the provided {@link Value} is supported.
*
* @param value The base value to check
* @return True if the base value is supported
*/
default boolean supports(final Value> value) {
return this.supports(value.key());
}
/**
* Gets all applicable {@link Key}s for this {@link ValueContainer}.
* Changes can not be made to the set to alter the {@link ValueContainer},
* nor can the {@link Value}s be changed with the provided
* {@link ImmutableSet}.
*
* @return An immutable set of known {@link Key}s
*/
Set> getKeys();
/**
* Gets all applicable {@link Value}s associated with this
* {@link ValueContainer}. As the data backed by the values are copied,
* any modifications to the {@link Value}s will not be reflected onto
* this {@link ValueContainer}.
*
* @return An immutable set of copied values
*/
Set> getValues();
}