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

org.spongepowered.api.data.persistence.DataView Maven / Gradle / Ivy

There is a newer version: 9.0.0
Show 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.persistence;

import org.spongepowered.api.ResourceKey;
import org.spongepowered.api.Sponge;
import org.spongepowered.api.data.DataManager;
import org.spongepowered.api.data.Key;
import org.spongepowered.api.data.value.Value;
import org.spongepowered.api.registry.RegistryHolder;
import org.spongepowered.api.registry.RegistryType;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;

/**
 * Represents an object of data represented by a map.
 * 

DataViews always exist within a {@link DataContainer} and can be used * for serialization.

*/ public interface DataView { /** * Gets the parent container of this DataView. * *

Every DataView will always have a {@link DataContainer}.

* *

For any {@link DataContainer}, this will return itself.

* * @return The parent container */ DataContainer container(); /** * Gets the current path of this {@link DataView} from its root * {@link DataContainer}. * *

For any {@link DataContainer} itself, this will return an * empty string as it is the root of the path.

* *

The full path will always include this {@link DataView}s name * at the end of the path.

* * @return The path of this view originating from the root */ DataQuery currentPath(); /** * Gets the name of this individual {@link DataView} in the path. * *

This will always be the final substring of the full path * from {@link #currentPath()}.

* * @return The name of this DataView */ String name(); /** * Gets the parent {@link DataView} of this view. The parent directly * contains this view according to the {@link #currentPath()}. * *

For any {@link DataContainer}, this will return an absent parent.

* * @return The parent data view containing this view */ Optional parent(); /** * Gets a collection containing all keys in this {@link DataView}. * *

If deep is set to true, then this will contain all the keys * within any child {@link DataView}s (and their children, etc). * These will be in a valid path notation for you to use.

* *

If deep is set to false, then this will contain only the keys * of any direct children, and not their own children.

* * @param deep Whether or not to get all children keys * @return A set of current keys in this container */ Set keys(boolean deep); /** * Gets a Map containing all keys and their values for this {@link DataView}. * *

If deep is set to true, then this will contain all the keys and * values within any child {@link DataView}s (and their children, * etc). These keys will be in a valid path notation for you to use.

* *

If deep is set to false, then this will contain only the keys and * values of any direct children, and not their own children.

* * @param deep Whether or not to get a deep list of all children or not * @return Map of keys and values of this container */ Map values(boolean deep); /** * Returns whether this {@link DataView} contains the given path. * * @param path The path relative to this data view * @return True if the path exists */ boolean contains(DataQuery path); /** * Returns whether this {@link DataView} contains an entry for all * provided {@link DataQuery} objects. * * @param path The path relative to this data view * @param paths The additional paths to check * @return True if all paths exist */ boolean contains(DataQuery path, DataQuery... paths); /** * Gets an object from the desired path. If the path is not defined, * an absent Optional is returned. * * @param path The path to the Object * @return The Object, if available */ Optional get(DataQuery path); /** * Sets the given Object value according to the given path relative to * this {@link DataView}'s path. * * @param path The path of the object to set * @param value The value of the data * @return This view, for chaining */ DataView set(DataQuery path, Object value); /** * Removes the data associated to the given path relative to this * {@link DataView}'s path. *

Path can not be empty, to remove this {@link DataView}, call * the associated parent to remove this views name.

* * @param path The path of data to remove * @return This view, for chaining */ DataView remove(DataQuery path); /** * Creates a new {@link DataView} at the desired path. *

If any data existed at the given path, that data will be * overwritten with the newly constructed {@link DataView}.

* * @param path The path of the new view * @return The newly created view */ DataView createView(DataQuery path); /** * Creates a new {@link DataView} with the given data at the desired * path. * *

If any data existed at the given path, that data will be overwritten * with the newly constructed {@link DataView}.

* * @param path The path of the new view * @param map The data to store in the new view * @return The new view */ DataView createView(DataQuery path, Map map); /** * Gets the {@link DataView} by path, if available. * *

If a {@link DataView} does not exist, or the data residing at * the path is not an instance of a {@link DataView}, an absent is * returned.

* * @param path The path of the value to get * @return The data view, if available */ Optional getView(DataQuery path); /** * Gets the underlying {@link Map} by path, if available. * *

If a {@link Map} does not exist, or data residing at the path is not * an instance of a {@link Map}, an absent is returned.

* * @param path The path of the value to get * @return The map, if available */ Optional> getMap(DataQuery path); /** * Gets the {@link Boolean} by path, if available. * *

If a {@link Boolean} does not exist, or the data residing at * the path is not an instance of a {@link Boolean}, an absent is * returned.

* * @param path The path of the value to get * @return The boolean, if available */ Optional getBoolean(DataQuery path); /** * Gets the {@link Short} by path, if available. * *

If a {@link Short} does not exist, or the data residing at * the path is not an instance of a {@link Short}, an absent is * returned.

* * @param path The path of the value to get * @return The boolean, if available */ Optional getShort(DataQuery path); /** * Gets the {@link Byte} by path, if available. * *

If a {@link Byte} does not exist, or the data residing at * the path is not an instance of a {@link Byte}, an absent is * returned.

* * @param path The path of the value to get * @return The boolean, if available */ Optional getByte(DataQuery path); /** * Gets the {@link Integer} by path, if available. * *

If a {@link Integer} does not exist, or the data residing at * the path is not an instance of a {@link Integer}, an absent is * returned.

* * @param path The path of the value to get * @return The integer, if available */ Optional getInt(DataQuery path); /** * Gets the {@link Long} by path, if available. * *

If a {@link Long} does not exist, or the data residing at * the path is not an instance of a {@link Long}, an absent is * returned.

* * @param path The path of the value to get * @return The long, if available */ Optional getLong(DataQuery path); /** * Gets the {@link Float} by path, if available. * *

If a {@link Float} does not exist, or the data residing at * the path is not an instance of a {@link Float}, an absent is * returned.

* * @param path The path of the value to get * @return The boolean, if available */ Optional getFloat(DataQuery path); /** * Gets the {@link Double} by path, if available. * *

If a {@link Double} does not exist, or the data residing at * the path is not an instance of a {@link Double}, an absent is * returned.

* * @param path The path of the value to get * @return The double, if available */ Optional getDouble(DataQuery path); /** * Gets the {@link String} by path, if available. * *

If a {@link String} does not exist, or the data residing at * the path is not an instance of a {@link String}, an absent is * returned.

* * @param path The path of the value to get * @return The string, if available */ Optional getString(DataQuery path); /** * Gets the {@link ResourceKey key} by path, if available. * * @param path The path of the value to get * @return The key, if available */ default Optional getResourceKey(final DataQuery path) { Objects.requireNonNull(path, "path"); final Optional value = this.getString(path); if (!value.isPresent()) { return Optional.empty(); } try { return Optional.of(ResourceKey.resolve(value.get())); } catch (final Exception ignore) { return Optional.empty(); } } /** * Gets the {@link List} of {@link ResourceKey keys} by path, if available. * * @param path The path of the value to get * @return The list of keys, if available */ default Optional> getResourceKeyList(final DataQuery path) { Objects.requireNonNull(path, "path"); final Optional> strings = this.getStringList(path); if (!strings.isPresent()) { return Optional.empty(); } final List keys = new ArrayList<>(); for (final String s : strings.get()) { try { keys.add(ResourceKey.resolve(s)); } catch (final Exception ignored) { // skip invalid keys } } if (keys.isEmpty()) { return Optional.empty(); } return Optional.of(keys); } /** * Gets the {@link List} of something by path, if available. * *

If a {@link List} of something does not exist, or the data * residing at the path is not an instance of a {@link List} of something, * an absent is returned.

* * @param path The path of the value to get * @return The list, if available */ Optional> getList(DataQuery path); /** * Gets the {@link List} of {@link String} by path, if available. * *

If a {@link List} of {@link String} does not exist, or the data * residing at the path is not an instance of a {@link List} of * {@link String}, an absent is returned.

* * @param path The path of the value to get * @return The list of strings, if available */ Optional> getStringList(DataQuery path); /** * Gets the {@link List} of {@link Character} by path, if available. * *

If a {@link List} of {@link Character} does not exist, or the data * residing at the path is not an instance of a {@link List} of * {@link Character}, an absent is returned.

* * @param path The path of the value to get * @return The list of characters, if available */ Optional> getCharacterList(DataQuery path); /** * Gets the {@link List} of {@link Boolean} by path, if available. * *

If a {@link List} of {@link Boolean} does not exist, or the data * residing at the path is not an instance of a {@link List} of * {@link Boolean}, an absent is returned.

* * @param path The path of the value to get * @return The list of booleans, if available */ Optional> getBooleanList(DataQuery path); /** * Gets the {@link List} of {@link Byte} by path, if available. * *

If a {@link List} of {@link Byte} does not exist, or the data * residing at the path is not an instance of a {@link List} of * {@link Byte}, an absent is returned.

* * @param path The path of the value to get * @return The list of bytes, if available */ Optional> getByteList(DataQuery path); /** * Gets the {@link List} of {@link Short} by path, if available. * *

If a {@link List} of {@link Short} does not exist, or the data * residing at the path is not an instance of a {@link List} of * {@link Short}, an absent is returned.

* * @param path The path of the value to get * @return The list of shorts, if available */ Optional> getShortList(DataQuery path); /** * Gets the {@link List} of {@link Integer} by path, if available. * *

If a {@link List} of {@link Integer} does not exist, or the data * residing at the path is not an instance of a {@link List} of * {@link Integer}, an absent is returned.

* * @param path The path of the value to get * @return The list of integers, if available */ Optional> getIntegerList(DataQuery path); /** * Gets the {@link List} of {@link Long} by path, if available. * *

If a {@link List} of {@link Long} does not exist, or the data * residing at the path is not an instance of a {@link List} of * {@link Long}, an absent is returned.

* * @param path The path of the value to get * @return The list of longs, if available */ Optional> getLongList(DataQuery path); /** * Gets the {@link List} of {@link Float} by path, if available. * *

If a {@link List} of {@link Float} does not exist, or the data * residing at the path is not an instance of a {@link List} of * {@link Float}, an absent is returned.

* * @param path The path of the value to get * @return The list of floats, if available */ Optional> getFloatList(DataQuery path); /** * Gets the {@link List} of {@link Double} by path, if available. * *

If a {@link List} of {@link Double} does not exist, or the data * residing at the path is not an instance of a {@link List} of * {@link Double}, an absent is returned.

* * @param path The path of the value to get * @return The list of doubles, if available */ Optional> getDoubleList(DataQuery path); /** * Gets the {@link List} of {@link Map} by path, if available. * *

If a {@link List} of {@link Map} does not exist, or the data * residing at the path is not an instance of a {@link List} of * {@link Map}, an absent is returned.

* * @param path The path of the value to get * @return The list of maps, if available */ Optional>> getMapList(DataQuery path); /** * Gets the {@link List} of {@link DataView} by path, if available. * *

If a {@link List} of {@link DataView} does not exist, or the data * residing at the path is not an instance of a {@link List} of * {@link DataView}, an absent is returned.

* * @param path The path of the value to get * @return The list of data views, if available */ Optional> getViewList(DataQuery path); /** * Gets the {@link DataSerializable} object by path, if available. * *

If a {@link DataSerializable} exists, but is not the proper class * type, or there is no data at the path given, an absent is returned.

* *

It is important that the {@link DataManager} provided is * the same one that has registered many of the * {@link DataBuilder}s to ensure the {@link DataSerializable} * requested can be returned.

* * @param The type of {@link DataSerializable} object * @param path The path of the value to get * @param clazz The class of the {@link DataSerializable} * @return The deserialized object, if available */ Optional getSerializable(DataQuery path, Class clazz); /** * Gets the {@link List} of {@link DataSerializable} by path, if available. * *

If a {@link List} exists, but the contents of the list are not * considered {@link DataSerializable} or are not of the proper type of * {@link DataSerializable}, an absent is returned.

* *

It is important that the {@link DataManager} provided is * the same one that has registered many of the * {@link DataBuilder}s to ensure the {@link DataSerializable} * requested can be returned.

* * @param The type of {@link DataSerializable} object * @param path The path of the list value to get * @param clazz The class of the {@link DataSerializable} * @return The deserialized objects in a list, if available */ Optional> getSerializableList(DataQuery path, Class clazz); /** * Gets the {@link Object} object by path, if available. * *

If a {@link Object} exists, but is not the proper class * type, or there is no data at the path given, an absent is returned.

* *

It is important that the {@link DataManager} provided is * the same one that has registered many of the * {@link DataTranslator}s to ensure the {@link DataSerializable} * requested can be returned.

* * @param The type of {@link Object} object * @param path The path of the value to get * @param objectClass The class of the {@link Object} * @return The deserialized object, if available */ Optional getObject(DataQuery path, Class objectClass); /** * Gets the {@link List} of {@link DataSerializable} by path, if available. * *

If a {@link List} exists, but the contents of the list are not * considered {@link DataTranslator}"able" or are not of the proper type of * {@link DataTranslator}, an absent is returned.

* *

It is important that the {@link DataManager} provided is * the same one that has registered many of the * {@link DataTranslator}s to ensure the {@link Object} * requested can be returned.

* * @param The type of {@link Object} object * @param path The path of the value to get * @param objectClass The class of the {@link Object} * @return The deserialized objects in a list, if available */ Optional> getObjectList(DataQuery path, Class objectClass); /** * Gets the {@link T value} by path, if available, from the global registry. * * @param path The path of the value to get * @param registryType The class of the dummy type * @param The type of dummy * @return The dummy type, if available */ default Optional getRegistryValue(final DataQuery path, final RegistryType registryType) { return this.getRegistryValue(Objects.requireNonNull(path, "path"), Objects.requireNonNull(registryType, "registryType"), Sponge.game()); } /** * Gets the {@link List} of {@link T values} by path, if available, from the global registry. * * @param path The path of the list value to get * @param registryType The type of registry to search * @param The type of dummy type * @return The list of dummy types, if available */ default Optional> getRegistryValueList(final DataQuery path, final RegistryType registryType) { return this.getRegistryValueList(Objects.requireNonNull(path, "path"), Objects.requireNonNull(registryType, "registryType"), Sponge.game()); } /** * Gets the {@link T value} by path, if available. * * @param path The path of the value to get * @param registryType The class of the dummy type * @param holder The holder to get the registry from * @param The type of dummy * @return The dummy type, if available */ Optional getRegistryValue(DataQuery path, RegistryType registryType, RegistryHolder holder); /** * Gets the {@link List} of {@link T values} by path, if available. * * @param path The path of the list value to get * @param registryType The type of registry to search * @param holder the holder to get the registry from * @param The type of dummy type * @return The list of dummy types, if available */ Optional> getRegistryValueList(DataQuery path, RegistryType registryType, RegistryHolder holder); /** * Gets the {@link Key key} by path, if available. * * @param path The path of the value to get * @param The element type * @param The value type * @return The key, if available */ > Optional> getDataKey(DataQuery path); /** * Gets the {@link List} of {@link Key values} by path, if available. * * @param path The path of the value to get * @return The list of keys, if available */ Optional>>> getDataKeyList(DataQuery path); /** * Copies this {@link DataView} and all of it's contents into a new * {@link DataContainer}. * *

Note that the copy will not have the same path as this * {@link DataView} since it will be constructed with the top level path * being itself.

* * @return The newly constructed data view */ DataContainer copy(); /** * Copies this {@link DataView} and all of it's contents into a new * {@link DataContainer} with the given safety mode. * *

Note that the copy will not have the same path as this * {@link DataView} since it will be constructed with the top level path * being itself.

* * @param safety The safety mode of the copy * @return The newly constructed data view */ DataContainer copy(SafetyMode safety); /** * Gets if this view contains no data. * * @return True if no data */ boolean isEmpty(); /** * Gets the {@link DataView.SafetyMode} of this data view. * * @return The safety mode */ SafetyMode safetyMode(); /** * The safety mode of the container. */ enum SafetyMode { /** * All data added to the container will be cloned for safety. */ ALL_DATA_CLONED, /** * All data added to the container will be cloned for safety. */ CLONED_ON_SET, /** * No data added to the container will be cloned, useful for situations * with a large amount of data where the cloning would be too costly. */ NO_DATA_CLONED } }