13
0
geforkt von Mirrors/Paper

Added new Configuration classes

By: Dinnerbone <dinnerbone@dinnerbone.com>
Dieser Commit ist enthalten in:
Bukkit/Spigot 2011-09-19 20:36:44 +01:00
Ursprung e99e39ee62
Commit 6c7412d365
31 geänderte Dateien mit 3454 neuen und 9 gelöschten Zeilen

Datei anzeigen

@ -107,5 +107,11 @@
<type>jar</type>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.9</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>

Datei anzeigen

@ -1,9 +1,10 @@
package org.bukkit;
import org.bukkit.configuration.serialization.ConfigurationSerializable;
import org.bukkit.entity.AnimalTamer;
import org.bukkit.permissions.ServerOperator;
public interface OfflinePlayer extends ServerOperator, AnimalTamer {
public interface OfflinePlayer extends ServerOperator, AnimalTamer, ConfigurationSerializable {
/**
* Checks if this player is currently online
*

Datei anzeigen

@ -0,0 +1,82 @@
package org.bukkit.configuration;
import java.util.Map;
/**
* Represents a source of configurable options and settings
*/
public interface Configuration extends ConfigurationSection {
/**
* Sets the default value of the given path as provided.
* <p>
* If no source {@link Configuration} was provided as a default collection,
* then a new {@link MemoryConfiguration} will be created to hold the new default
* value.
* <p>
* If value is null, the value will be removed from the default Configuration source.
*
* @param path Path of the value to set.
* @param value Value to set the default to.
* @throws IllegalArgumentException Thrown if path is null.
*/
public void addDefault(String path, Object value);
/**
* Sets the default values of the given paths as provided.
* <p>
* If no source {@link Configuration} was provided as a default collection,
* then a new {@link MemoryConfiguration} will be created to hold the new default
* values.
*
* @param defaults A map of Path->Values to add to defaults.
* @throws IllegalArgumentException Thrown if defaults is null.
*/
public void addDefaults(Map<String, Object> defaults);
/**
* Sets the default values of the given paths as provided.
* <p>
* If no source {@link Configuration} was provided as a default collection,
* then a new {@link MemoryConfiguration} will be created to hold the new default
* value.
* <p>
* This method will not hold a reference to the specified Configuration, nor will it
* automatically update if that Configuration ever changes. If you require this,
* you should set the default source with {@link #setDefaults(org.bukkit.configuration.Configuration)}.
*
* @param defaults A configuration holding a list of defaults to copy.
* @throws IllegalArgumentException Thrown if defaults is null or this.
*/
public void addDefaults(Configuration defaults);
/**
* Sets the source of all default values for this {@link Configuration}.
* <p>
* If a previous source was set, or previous default values were defined, then they will
* not be copied to the new source.
*
* @param defaults New source of default values for this configuration.
* @throws IllegalArgumentException Thrown if defaults is null or this.
*/
public void setDefaults(Configuration defaults);
/**
* Gets the source {@link Configuration} for this configuration.
* <p>
* If no configuration source was set, but default values were added, then a
* {@link MemoryConfiguration} will be returned. If no source was set and no
* defaults were set, then this method will return null.
*
* @return Configuration source for default values, or null if none exist.
*/
public Configuration getDefaults();
/**
* Gets the {@link ConfigurationOptions} for this {@link Configuration}.
* <p>
* All setters through this method are chainable.
*
* @return Options for this configuration
*/
public ConfigurationOptions options();
}

Datei anzeigen

@ -0,0 +1,81 @@
package org.bukkit.configuration;
/**
* Various settings for controlling the input and output of a {@link Configuration}
*/
public class ConfigurationOptions {
private char pathSeparator = '.';
private boolean copyDefaults = false;
private final Configuration configuration;
protected ConfigurationOptions(Configuration configuration) {
this.configuration = configuration;
}
/**
* Returns the {@link Configuration} that this object is responsible for.
*
* @return Parent configuration
*/
public Configuration configuration() {
return configuration;
}
/**
* Gets the char that will be used to separate {@link ConfigurationSection}s
* <p>
* This value does not affect how the {@link Configuration} is stored, only in
* how you access the data. The default value is '.'.
*
* @return Path separator
*/
public char pathSeparator() {
return pathSeparator;
}
/**
* Sets the char that will be used to separate {@link ConfigurationSection}s
* <p>
* This value does not affect how the {@link Configuration} is stored, only in
* how you access the data. The default value is '.'.
*
* @param value Path separator
* @return This object, for chaining
*/
public ConfigurationOptions pathSeparator(char value) {
this.pathSeparator = value;
return this;
}
/**
* Checks if the {@link Configuration} should copy values from its default {@link Configuration} directly.
* <p>
* If this is true, all values in the default Configuration will be directly copied,
* making it impossible to distinguish between values that were set and values that
* are provided by default. As a result, {@link ConfigurationSection#contains(java.lang.String)} will always
* return the same value as {@link ConfigurationSection#isSet(java.lang.String)}.
* The default value is false.
*
* @return Whether or not defaults are directly copied
*/
public boolean copyDefaults() {
return copyDefaults;
}
/**
* Sets if the {@link Configuration} should copy values from its default {@link Configuration} directly.
* <p>
* If this is true, all values in the default Configuration will be directly copied,
* making it impossible to distinguish between values that were set and values that
* are provided by default. As a result, {@link ConfigurationSection#contains(java.lang.String)} will always
* return the same value as {@link ConfigurationSection#isSet(java.lang.String)}.
* The default value is false.
*
* @param value Whether or not defaults are directly copied
* @return This object, for chaining
*/
public ConfigurationOptions copyDefaults(boolean value) {
this.copyDefaults = value;
return this;
}
}

Datei anzeigen

@ -0,0 +1,560 @@
package org.bukkit.configuration;
import java.util.Map;
import java.util.Set;
import java.util.List;
import org.bukkit.OfflinePlayer;
import org.bukkit.util.Vector;
import org.bukkit.inventory.ItemStack;
/**
* Represents a section of a {@link Configuration}
*/
public interface ConfigurationSection {
/**
* Gets a set containing all keys in this section.
* <p>
* If deep is set to true, then this will contain all the keys within any child
* {@link ConfigurationSection}s (and their children, etc). These will be in a
* valid path notation for you to use.
* <p>
* 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 a deep list, as opposed to a shallow list.
* @return Set of keys contained within this ConfigurationSection.
*/
public Set<String> getKeys(boolean deep);
/**
* Gets a Map containing all keys and their values for this section.
* <p>
* If deep is set to true, then this will contain all the keys and values within
* any child {@link ConfigurationSection}s (and their children, etc). These
* keys will be in a valid path notation for you to use.
* <p>
* 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, as opposed to a shallow list.
* @return Map of keys and values of this section.
*/
public Map<String, Object> getValues(boolean deep);
/**
* Checks if this {@link ConfigurationSection} contains the given path.
* <p>
* If the value for the requested path does not exist but a default value has
* been specified, this will return true.
*
* @param path Path to check for existence.
* @return True if this section contains the requested path, either via default or being set.
* @throws IllegalArgumentException Thrown when path is null.
*/
public boolean contains(String path);
/**
* Checks if this {@link ConfigurationSection} has a value set for the given path.
* <p>
* If the value for the requested path does not exist but a default value has
* been specified, this will still return false.
*
* @param path Path to check for existence.
* @return True if this section contains the requested path, regardless of having a default.
* @throws IllegalArgumentException Thrown when path is null.
*/
public boolean isSet(String path);
/**
* Gets the path of this {@link ConfigurationSection} from its root {@link Configuration}
* <p>
* For any {@link Configuration} themselves, this will return an empty string.
* <p>
* If the section is no longer contained within its root for any reason, such as
* being replaced with a different value, this may return null.
* <p>
* To retrieve the single name of this section, that is, the final part of the path
* returned by this method, you may use {@link #getName()}.
*
* @return Path of this section relative to its root
*/
public String getCurrentPath();
/**
* Gets the name of this individual {@link ConfigurationSection}, in the path.
* <p>
* This will always be the final part of {@link #getCurrentPath()}, unless the
* section is orphaned.
*
* @return Name of this section
*/
public String getName();
/**
* Gets the root {@link Configuration} that contains this {@link ConfigurationSection}
* <p>
* For any {@link Configuration} themselves, this will return its own object.
* <p>
* If the section is no longer contained within its root for any reason, such as
* being replaced with a different value, this may return null.
*
* @return Root configuration containing this section.
*/
public Configuration getRoot();
/**
* Gets the parent {@link ConfigurationSection} that directly contains this
* {@link ConfigurationSection}.
* <p>
* For any {@link Configuration} themselves, this will return null.
* <p>
* If the section is no longer contained within its parent for any reason, such as
* being replaced with a different value, this may return null.
*
* @return Parent section containing this section.
*/
public ConfigurationSection getParent();
/**
* Gets the requested Object by path.
* <p>
* If the Object does not exist but a default value has been specified, this
* will return the default value. If the Object does not exist and no default
* value was specified, this will return null.
*
* @param path Path of the Object to get.
* @return Requested Object.
*/
public Object get(String path);
/**
* Gets the requested Object by path, returning a default value if not found.
* <p>
* If the Object does not exist then the specified default value will returned
* regardless of if a default has been identified in the root {@link Configuration}.
*
* @param path Path of the Object to get.
* @return Requested Object.
*/
public Object get(String path, Object def);
/**
* Sets the specified path to the given value.
* <p>
* If value is null, the entry will be removed. Any existing entry will be
* replaced, regardless of what the new value is.
* <p>
* Some implementations may have limitations on what you may store. See their
* individual javadocs for details. No implementations should allow you to store
* {@link Configuration}s or {@link ConfigurationSection}s, please use
* {@link #createSection(java.lang.String)} for that.
*
* @param path Path of the object to set.
* @param value New value to set the path to.
*/
public void set(String path, Object value);
/**
* Creates an empty {@link ConfigurationSection} at the specified path.
* <p>
* Any value that was previously set at this path will be overwritten. If the
* previous value was itself a {@link ConfigurationSection}, it will be orphaned.
*
* @param path Path to create the section at.
* @return Newly created section
*/
public ConfigurationSection createSection(String path);
// Primitives
/**
* Gets the requested String by path.
* <p>
* If the String does not exist but a default value has been specified, this
* will return the default value. If the String does not exist and no default
* value was specified, this will return null.
*
* @param path Path of the String to get.
* @return Requested String.
*/
public String getString(String path);
/**
* Gets the requested String by path, returning a default value if not found.
* <p>
* If the String does not exist then the specified default value will returned
* regardless of if a default has been identified in the root {@link Configuration}.
*
* @param path Path of the String to get.
* @return Requested String.
*/
public String getString(String path, String def);
/**
* Checks if the specified path is a String.
* <p>
* If the path exists but is not a String, this will return false. If the path does not
* exist, this will return false. If the path does not exist but a default value
* has been specified, this will check if that default value is a String and return
* appropriately.
*
* @param path Path of the String to check.
* @return Whether or not the specified path is a String.
*/
public boolean isString(String path);
/**
* Gets the requested int by path.
* <p>
* If the int does not exist but a default value has been specified, this
* will return the default value. If the int does not exist and no default
* value was specified, this will return null.
*
* @param path Path of the int to get.
* @return Requested int.
*/
public int getInt(String path);
/**
* Gets the requested int by path, returning a default value if not found.
* <p>
* If the int does not exist then the specified default value will returned
* regardless of if a default has been identified in the root {@link Configuration}.
*
* @param path Path of the int to get.
* @return Requested int.
*/
public int getInt(String path, int def);
/**
* Checks if the specified path is an int.
* <p>
* If the path exists but is not a int, this will return false. If the path does not
* exist, this will return false. If the path does not exist but a default value
* has been specified, this will check if that default value is a int and return
* appropriately.
*
* @param path Path of the int to check.
* @return Whether or not the specified path is an int.
*/
public boolean isInt(String path);
/**
* Gets the requested boolean by path.
* <p>
* If the boolean does not exist but a default value has been specified, this
* will return the default value. If the boolean does not exist and no default
* value was specified, this will return false.
*
* @param path Path of the boolean to get.
* @return Requested boolean.
*/
public boolean getBoolean(String path);
/**
* Gets the requested boolean by path, returning a default value if not found.
* <p>
* If the boolean does not exist then the specified default value will returned
* regardless of if a default has been identified in the root {@link Configuration}.
*
* @param path Path of the boolean to get.
* @return Requested boolean.
*/
public boolean getBoolean(String path, boolean def);
/**
* Checks if the specified path is a boolean.
* <p>
* If the path exists but is not a boolean, this will return false. If the path does not
* exist, this will return false. If the path does not exist but a default value
* has been specified, this will check if that default value is a boolean and return
* appropriately.
*
* @param path Path of the boolean to check.
* @return Whether or not the specified path is a boolean.
*/
public boolean isBoolean(String path);
/**
* Gets the requested double by path.
* <p>
* If the double does not exist but a default value has been specified, this
* will return the default value. If the double does not exist and no default
* value was specified, this will return null.
*
* @param path Path of the double to get.
* @return Requested double.
*/
public double getDouble(String path);
/**
* Gets the requested double by path, returning a default value if not found.
* <p>
* If the double does not exist then the specified default value will returned
* regardless of if a default has been identified in the root {@link Configuration}.
*
* @param path Path of the double to get.
* @return Requested double.
*/
public double getDouble(String path, double def);
/**
* Checks if the specified path is a double.
* <p>
* If the path exists but is not a double, this will return false. If the path does not
* exist, this will return false. If the path does not exist but a default value
* has been specified, this will check if that default value is a double and return
* appropriately.
*
* @param path Path of the double to check.
* @return Whether or not the specified path is a double.
*/
public boolean isDouble(String path);
/**
* Gets the requested long by path.
* <p>
* If the long does not exist but a default value has been specified, this
* will return the default value. If the long does not exist and no default
* value was specified, this will return null.
*
* @param path Path of the long to get.
* @return Requested long.
*/
public long getLong(String path);
/**
* Gets the requested long by path, returning a default value if not found.
* <p>
* If the long does not exist then the specified default value will returned
* regardless of if a default has been identified in the root {@link Configuration}.
*
* @param path Path of the long to get.
* @return Requested long.
*/
public long getLong(String path, long def);
/**
* Checks if the specified path is a long.
* <p>
* If the path exists but is not a long, this will return false. If the path does not
* exist, this will return false. If the path does not exist but a default value
* has been specified, this will check if that default value is a long and return
* appropriately.
*
* @param path Path of the long to check.
* @return Whether or not the specified path is a long.
*/
public boolean isLong(String path);
// Java
/**
* Gets the requested List by path.
* <p>
* If the List does not exist but a default value has been specified, this
* will return the default value. If the List does not exist and no default
* value was specified, this will return null.
*
* @param path Path of the List to get.
* @return Requested List.
*/
public List getList(String path);
/**
* Gets the requested List by path, returning a default value if not found.
* <p>
* If the List does not exist then the specified default value will returned
* regardless of if a default has been identified in the root {@link Configuration}.
*
* @param path Path of the List to get.
* @return Requested List.
*/
public List getList(String path, List def);
/**
* Checks if the specified path is a List.
* <p>
* If the path exists but is not a List, this will return false. If the path does not
* exist, this will return false. If the path does not exist but a default value
* has been specified, this will check if that default value is a List and return
* appropriately.
*
* @param path Path of the List to check.
* @return Whether or not the specified path is a List.
*/
public boolean isList(String path);
// Bukkit
/**
* Gets the requested Vector by path.
* <p>
* If the Vector does not exist but a default value has been specified, this
* will return the default value. If the Vector does not exist and no default
* value was specified, this will return null.
*
* @param path Path of the Vector to get.
* @return Requested Vector.
*/
public Vector getVector(String path);
/**
* Gets the requested Vector by path, returning a default value if not found.
* <p>
* If the Vector does not exist then the specified default value will returned
* regardless of if a default has been identified in the root {@link Configuration}.
*
* @param path Path of the Vector to get.
* @return Requested Vector.
*/
public Vector getVector(String path, Vector def);
/**
* Checks if the specified path is a Vector.
* <p>
* If the path exists but is not a Vector, this will return false. If the path does not
* exist, this will return false. If the path does not exist but a default value
* has been specified, this will check if that default value is a Vector and return
* appropriately.
*
* @param path Path of the Vector to check.
* @return Whether or not the specified path is a Vector.
*/
public boolean isVector(String path);
/**
* Gets the requested OfflinePlayer by path.
* <p>
* If the OfflinePlayer does not exist but a default value has been specified, this
* will return the default value. If the OfflinePlayer does not exist and no default
* value was specified, this will return null.
*
* @param path Path of the OfflinePlayer to get.
* @return Requested OfflinePlayer.
*/
public OfflinePlayer getOfflinePlayer(String path);
/**
* Gets the requested OfflinePlayer by path, returning a default value if not found.
* <p>
* If the OfflinePlayer does not exist then the specified default value will returned
* regardless of if a default has been identified in the root {@link Configuration}.
*
* @param path Path of the OfflinePlayer to get.
* @return Requested OfflinePlayer.
*/
public OfflinePlayer getOfflinePlayer(String path, OfflinePlayer def);
/**
* Checks if the specified path is an OfflinePlayer.
* <p>
* If the path exists but is not a OfflinePlayer, this will return false. If the path does not
* exist, this will return false. If the path does not exist but a default value
* has been specified, this will check if that default value is a OfflinePlayer and return
* appropriately.
*
* @param path Path of the OfflinePlayer to check.
* @return Whether or not the specified path is an OfflinePlayer.
*/
public boolean isOfflinePlayer(String path);
/**
* Gets the requested ItemStack by path.
* <p>
* If the ItemStack does not exist but a default value has been specified, this
* will return the default value. If the ItemStack does not exist and no default
* value was specified, this will return null.
*
* @param path Path of the ItemStack to get.
* @return Requested ItemStack.
*/
public ItemStack getItemStack(String path);
/**
* Gets the requested ItemStack by path, returning a default value if not found.
* <p>
* If the ItemStack does not exist then the specified default value will returned
* regardless of if a default has been identified in the root {@link Configuration}.
*
* @param path Path of the ItemStack to get.
* @return Requested ItemStack.
*/
public ItemStack getItemStack(String path, ItemStack def);
/**
* Checks if the specified path is an ItemStack.
* <p>
* If the path exists but is not a ItemStack, this will return false. If the path does not
* exist, this will return false. If the path does not exist but a default value
* has been specified, this will check if that default value is a ItemStack and return
* appropriately.
*
* @param path Path of the ItemStack to check.
* @return Whether or not the specified path is an ItemStack.
*/
public boolean isItemStack(String path);
/**
* Gets the requested ConfigurationSection by path.
* <p>
* If the ConfigurationSection does not exist but a default value has been specified, this
* will return the default value. If the ConfigurationSection does not exist and no default
* value was specified, this will return null.
*
* @param path Path of the ConfigurationSection to get.
* @return Requested ConfigurationSection.
*/
public ConfigurationSection getConfigurationSection(String path);
/**
* Checks if the specified path is a ConfigurationSection.
* <p>
* If the path exists but is not a ConfigurationSection, this will return false. If the path does not
* exist, this will return false. If the path does not exist but a default value
* has been specified, this will check if that default value is a ConfigurationSection and return
* appropriately.
*
* @param path Path of the ConfigurationSection to check.
* @return Whether or not the specified path is a ConfigurationSection.
*/
public boolean isConfigurationSection(String path);
/**
* Gets the equivalent {@link ConfigurationSection} from the default {@link Configuration} defined in {@link #getRoot()}.
* <p>
* If the root contains no defaults, or the defaults doesn't contain a value
* for this path, or the value at this path is not a {@link ConfigurationSection} then
* this will return null.
*
* @return Equivalent section in root configuration
*/
public ConfigurationSection getDefaultSection();
/**
* Sets the default value in the root at the given path as provided.
* <p>
* If no source {@link Configuration} was provided as a default collection,
* then a new {@link MemoryConfiguration} will be created to hold the new default
* value.
* <p>
* If value is null, the value will be removed from the default Configuration source.
* <p>
* If the value as returned by {@link #getDefaultSection()} is null,
* then this will create a new section at the path, replacing anything that
* may have existed there previously.
*
* @param path Path of the value to set.
* @param value Value to set the default to.
* @throws IllegalArgumentException Thrown if path is null.
*/
public void addDefault(String path, Object value);
}

Datei anzeigen

@ -0,0 +1,39 @@
package org.bukkit.configuration;
/**
* Exception thrown when attempting to load an invalid {@link Configuration}
*/
public class InvalidConfigurationException extends Exception {
/**
* Creates a new instance of InvalidConfigurationException without a message or cause.
*/
public InvalidConfigurationException() {}
/**
* Constructs an instance of InvalidConfigurationException with the specified message.
*
* @param msg The details of the exception.
*/
public InvalidConfigurationException(String msg) {
super(msg);
}
/**
* Constructs an instance of InvalidConfigurationException with the specified cause.
*
* @param cause The cause of the exception.
*/
public InvalidConfigurationException(Throwable cause) {
super(cause);
}
/**
* Constructs an instance of InvalidConfigurationException with the specified message and cause.
*
* @param cause The cause of the exception.
* @param msg The details of the exception.
*/
public InvalidConfigurationException(String msg, Throwable cause) {
super(msg, cause);
}
}

Datei anzeigen

@ -0,0 +1,85 @@
package org.bukkit.configuration;
import java.util.Map;
/**
* This is a {@link Configuration} implementation that does not save or load
* from any source, and stores all values in memory only.
* This is useful for temporary Configurations for providing defaults.
*/
public class MemoryConfiguration extends MemorySection implements Configuration {
protected Configuration defaults;
protected MemoryConfigurationOptions options;
/**
* Creates an empty {@link MemoryConfiguration} with no default values.
*/
public MemoryConfiguration() {}
/**
* Creates an empty {@link MemoryConfiguration} using the specified {@link Configuration}
* as a source for all default values.
*
* @param defaults Default value provider
* @throws IllegalArgumentException Thrown if defaults is null
*/
public MemoryConfiguration(Configuration defaults) {
this.defaults = defaults;
}
@Override
public void addDefault(String path, Object value) {
if (path == null) {
throw new IllegalArgumentException("Path may not be null");
}
if (defaults == null) {
defaults = new MemoryConfiguration();
}
defaults.set(path, value);
}
public void addDefaults(Map<String, Object> defaults) {
if (defaults == null) {
throw new IllegalArgumentException("Defaults may not be null");
}
for (Map.Entry<String, Object> entry : defaults.entrySet()) {
addDefault(entry.getKey(), entry.getValue());
}
}
public void addDefaults(Configuration defaults) {
if (defaults == null) {
throw new IllegalArgumentException("Defaults may not be null");
}
addDefaults(defaults.getValues(true));
}
public void setDefaults(Configuration defaults) {
if (defaults == null) {
throw new IllegalArgumentException("Defaults may not be null");
}
this.defaults = defaults;
}
public Configuration getDefaults() {
return defaults;
}
@Override
public ConfigurationSection getParent() {
return null;
}
public MemoryConfigurationOptions options() {
if (options == null) {
options = new MemoryConfigurationOptions(this);
}
return options;
}
}

Datei anzeigen

@ -0,0 +1,27 @@
package org.bukkit.configuration;
/**
* Various settings for controlling the input and output of a {@link MemoryConfiguration}
*/
public class MemoryConfigurationOptions extends ConfigurationOptions {
protected MemoryConfigurationOptions(MemoryConfiguration configuration) {
super(configuration);
}
@Override
public MemoryConfiguration configuration() {
return (MemoryConfiguration)super.configuration();
}
@Override
public MemoryConfigurationOptions copyDefaults(boolean value) {
super.copyDefaults(value);
return this;
}
@Override
public MemoryConfigurationOptions pathSeparator(char value) {
super.pathSeparator(value);
return this;
}
}

Datei anzeigen

@ -0,0 +1,667 @@
package org.bukkit.configuration;
import org.bukkit.configuration.serialization.ConfigurationSerializable;
import java.io.File;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Pattern;
import org.bukkit.Location;
import org.bukkit.OfflinePlayer;
import org.bukkit.World;
import org.bukkit.inventory.ItemStack;
import org.bukkit.material.MaterialData;
import org.bukkit.util.Vector;
/**
* A type of {@link ConfigurationSection} that is stored in memory.
*/
public class MemorySection implements ConfigurationSection {
protected final Map<String, Object> map = new LinkedHashMap<String, Object>();
private final Configuration root;
private final ConfigurationSection parent;
private final String path;
private final String fullPath;
/**
* Creates an empty MemorySection for use as a root {@link Configuration} section.
* <p>
* Note that calling this without being yourself a {@link Configuration} will throw an
* exception!
*
* @throws IllegalStateException Thrown if this is not a {@link Configuration} root.
*/
protected MemorySection() {
if (!(this instanceof Configuration)) {
throw new IllegalStateException("Cannot contruct a root MemorySection when not a Configuration");
}
this.path = "";
this.fullPath = "";
this.parent = null;
this.root = (Configuration)this;
}
/**
* Creates an empty MemorySection with the specified parent and path.
*
* @param parent Parent section that contains this own section.
* @param path Path that you may access this section from via the root {@link Configuration}.
* @throws IllegalArgumentException Thrown is parent or path is null, or if parent contains no root Configuration.
*/
protected MemorySection(ConfigurationSection parent, String path) {
if (parent == null) {
throw new IllegalArgumentException("Parent cannot be null");
}
if (path == null) {
throw new IllegalArgumentException("Path cannot be null");
}
this.path = path;
this.parent = parent;
this.root = parent.getRoot();
if (root == null) {
throw new IllegalArgumentException("Path cannot be orphaned");
}
this.fullPath = createPath(parent, path);
}
public Set<String> getKeys(boolean deep) {
Set<String> result = new LinkedHashSet<String>();
if (getRoot().options().copyDefaults()) {
ConfigurationSection defaults = getDefaultSection();
if (defaults != null) {
result.addAll(defaults.getKeys(deep));
}
}
mapChildrenKeys(result, this, deep);
return result;
}
public Map<String, Object> getValues(boolean deep) {
Map<String, Object> result = new LinkedHashMap<String, Object>();
if (getRoot().options().copyDefaults()) {
ConfigurationSection defaults = getDefaultSection();
if (defaults != null) {
result.putAll(defaults.getValues(deep));
}
}
mapChildrenValues(result, this, deep);
return result;
}
public boolean contains(String path) {
if (path == null) {
throw new IllegalArgumentException("Path cannot be null");
}
return get(path) != null;
}
public boolean isSet(String path) {
if (path == null) {
throw new IllegalArgumentException("Path cannot be null");
}
if (getRoot().options().copyDefaults()) {
return contains(path);
} else {
return get(path, null) != null;
}
}
public String getCurrentPath() {
return fullPath;
}
public String getName() {
return path;
}
public Configuration getRoot() {
return root;
}
public ConfigurationSection getParent() {
return parent;
}
public void addDefault(String path, Object value) {
if (path == null) {
throw new IllegalArgumentException("Path cannot be null");
}
if (root == null) {
throw new IllegalStateException("Cannot set default on orphaned section");
} else {
root.addDefault(createPath(this, path), value);
}
}
public ConfigurationSection getDefaultSection() {
if (getRoot() == null) {
return null;
}
Configuration defaults = getRoot().getDefaults();
if (defaults != null) {
if (defaults.isConfigurationSection(getCurrentPath())) {
return defaults.getConfigurationSection(getCurrentPath());
}
}
return null;
}
public void set(String path, Object value) {
String[] split = path.split(Pattern.quote(Character.toString(getRoot().options().pathSeparator())));
ConfigurationSection section = this;
if (path == null) {
throw new IllegalArgumentException("Path cannot be null");
} else if (path.length() == 0) {
throw new IllegalArgumentException("Cannot set to an empty path");
}
for (int i = 0; i < split.length - 1; i++) {
ConfigurationSection last = section;
section = last.getConfigurationSection(split[i]);
if (section == null) {
section = last.createSection(split[i]);
}
}
String key = split[split.length - 1];
if (section == this) {
map.put(key, prepForStorage(value));
} else {
section.set(key, value);
}
}
public Object get(String path) {
if (path == null) {
throw new IllegalArgumentException("Path cannot be null");
}
return get(path, getDefault(path));
}
public Object get(String path, Object def) {
Object result = null;
String[] split = path.split(Pattern.quote(Character.toString(getRoot().options().pathSeparator())));
ConfigurationSection section = this;
if (path == null) {
throw new IllegalArgumentException("Path cannot be null");
} else if (path.length() == 0) {
return this;
}
for (int i = 0; (i < split.length - 1) && (section != null); i++) {
section = getConfigurationSection(split[i]);
}
String key = split[split.length - 1];
if (section == this) {
result = map.get(key);
} else if (section != null) {
result = section.get(key);
}
return (result == null) ? def : result;
}
public ConfigurationSection createSection(String path) {
if (path == null) {
throw new IllegalArgumentException("Path cannot be null");
} else if (path.length() == 0) {
throw new IllegalArgumentException("Cannot create section at empty path");
}
String[] split = path.split(Pattern.quote(Character.toString(getRoot().options().pathSeparator())));
ConfigurationSection section = this;
for (int i = 0; i < split.length - 1; i++) {
ConfigurationSection last = section;
section = getConfigurationSection(split[i]);
if (section == null) {
section = last.createSection(split[i]);
}
}
String key = split[split.length - 1];
if (section == this) {
ConfigurationSection result = new MemorySection(this, key);
map.put(key, result);
return result;
} else {
return section.createSection(key);
}
}
// Primitives
public String getString(String path) {
if (path == null) {
throw new IllegalArgumentException("Path cannot be null");
}
Object def = getDefault(path);
return getString(path, (def instanceof String) ? (String)def : null);
}
public String getString(String path, String def) {
if (path == null) {
throw new IllegalArgumentException("Path cannot be null");
}
Object val = get(path, def);
return (val instanceof String) ? (String)val : def;
}
public boolean isString(String path) {
if (path == null) {
throw new IllegalArgumentException("Path cannot be null");
}
Object val = get(path);
return val instanceof String;
}
public int getInt(String path) {
if (path == null) {
throw new IllegalArgumentException("Path cannot be null");
}
Object def = getDefault(path);
return getInt(path, (def instanceof Integer) ? (Integer)def : 0);
}
public int getInt(String path, int def) {
if (path == null) {
throw new IllegalArgumentException("Path cannot be null");
}
Object val = get(path, def);
return (val instanceof Integer) ? (Integer)val : def;
}
public boolean isInt(String path) {
if (path == null) {
throw new IllegalArgumentException("Path cannot be null");
}
Object val = get(path);
return val instanceof Integer;
}
public boolean getBoolean(String path) {
if (path == null) {
throw new IllegalArgumentException("Path cannot be null");
}
Object def = getDefault(path);
return getBoolean(path, (def instanceof Boolean) ? (Boolean)def : false);
}
public boolean getBoolean(String path, boolean def) {
if (path == null) {
throw new IllegalArgumentException("Path cannot be null");
}
Object val = get(path, def);
return (val instanceof Boolean) ? (Boolean)val : def;
}
public boolean isBoolean(String path) {
if (path == null) {
throw new IllegalArgumentException("Path cannot be null");
}
Object val = get(path);
return val instanceof Boolean;
}
public double getDouble(String path) {
if (path == null) {
throw new IllegalArgumentException("Path cannot be null");
}
Object def = getDefault(path);
return getDouble(path, (def instanceof Double) ? (Double)def : 0);
}
public double getDouble(String path, double def) {
if (path == null) {
throw new IllegalArgumentException("Path cannot be null");
}
Object val = get(path, def);
return (val instanceof Double) ? (Double)val : def;
}
public boolean isDouble(String path) {
if (path == null) {
throw new IllegalArgumentException("Path cannot be null");
}
Object val = get(path);
return val instanceof Double;
}
public long getLong(String path) {
if (path == null) {
throw new IllegalArgumentException("Path cannot be null");
}
Object def = getDefault(path);
return getLong(path, (def instanceof Long) ? (Long)def : 0);
}
public long getLong(String path, long def) {
if (path == null) {
throw new IllegalArgumentException("Path cannot be null");
}
Object val = get(path, def);
return (val instanceof Long) ? (Long)val : def;
}
public boolean isLong(String path) {
if (path == null) {
throw new IllegalArgumentException("Path cannot be null");
}
Object val = get(path);
return val instanceof Long;
}
// Java
public List getList(String path) {
if (path == null) {
throw new IllegalArgumentException("Path cannot be null");
}
Object def = getDefault(path);
return getList(path, (def instanceof List) ? (List)def : null);
}
public List getList(String path, List def) {
if (path == null) {
throw new IllegalArgumentException("Path cannot be null");
}
Object val = get(path, def);
return (val instanceof List) ? (List)val : def;
}
public boolean isList(String path) {
if (path == null) {
throw new IllegalArgumentException("Path cannot be null");
}
Object val = get(path);
return val instanceof List;
}
// Bukkit
public Vector getVector(String path) {
if (path == null) {
throw new IllegalArgumentException("Path cannot be null");
}
Object def = getDefault(path);
return getVector(path, (def instanceof Vector) ? (Vector)def : null);
}
public Vector getVector(String path, Vector def) {
if (path == null) {
throw new IllegalArgumentException("Path cannot be null");
}
Object val = get(path, def);
return (val instanceof Vector) ? (Vector)val : def;
}
public boolean isVector(String path) {
if (path == null) {
throw new IllegalArgumentException("Path cannot be null");
}
Object val = get(path);
return val instanceof Vector;
}
public OfflinePlayer getOfflinePlayer(String path) {
if (path == null) {
throw new IllegalArgumentException("Path cannot be null");
}
Object def = getDefault(path);
return getOfflinePlayer(path, (def instanceof OfflinePlayer) ? (OfflinePlayer)def : null);
}
public OfflinePlayer getOfflinePlayer(String path, OfflinePlayer def) {
if (path == null) {
throw new IllegalArgumentException("Path cannot be null");
}
Object val = get(path, def);
return (val instanceof OfflinePlayer) ? (OfflinePlayer)val : def;
}
public boolean isOfflinePlayer(String path) {
if (path == null) {
throw new IllegalArgumentException("Path cannot be null");
}
Object val = get(path);
return val instanceof OfflinePlayer;
}
public ItemStack getItemStack(String path) {
if (path == null) {
throw new IllegalArgumentException("Path cannot be null");
}
Object def = getDefault(path);
return getItemStack(path, (def instanceof ItemStack) ? (ItemStack)def : null);
}
public ItemStack getItemStack(String path, ItemStack def) {
if (path == null) {
throw new IllegalArgumentException("Path cannot be null");
}
Object val = get(path, def);
return (val instanceof ItemStack) ? (ItemStack)val : def;
}
public boolean isItemStack(String path) {
if (path == null) {
throw new IllegalArgumentException("Path cannot be null");
}
Object val = get(path);
return val instanceof ItemStack;
}
public ConfigurationSection getConfigurationSection(String path) {
if (path == null) {
throw new IllegalArgumentException("Path cannot be null");
}
Object val = get(path, getDefault(path));
return (val instanceof ConfigurationSection) ? (ConfigurationSection)val : null;
}
public boolean isConfigurationSection(String path) {
if (path == null) {
throw new IllegalArgumentException("Path cannot be null");
}
Object val = get(path);
return val instanceof ConfigurationSection;
}
protected Object prepForStorage(Object input) {
if (input == null) {
throw new IllegalArgumentException("Cannot store null");
}
if (isPrimitiveWrapper(input) || isNaturallyStorable(input)) {
return input;
} else if (input instanceof ConfigurationSerializable) {
return input;
}
throw new IllegalArgumentException("Cannot store " + input + " into " + this + ", unsupported class");
}
protected boolean isPrimitiveWrapper(Object input) {
return input instanceof Integer || input instanceof Boolean ||
input instanceof Character || input instanceof Byte ||
input instanceof Short || input instanceof Double ||
input instanceof Long || input instanceof Float;
}
protected boolean isNaturallyStorable(Object input) {
return input instanceof List || input instanceof Iterable ||
input instanceof String || input instanceof File ||
input instanceof Enum;
}
protected Object getDefault(String path) {
if (path == null) {
throw new IllegalArgumentException("Path cannot be null");
}
Configuration defaults = root.getDefaults();
return (defaults == null) ? null : defaults.get(createPath(this, path));
}
protected void mapChildrenKeys(Set<String> output, ConfigurationSection section, boolean deep) {
if (section instanceof MemorySection) {
MemorySection sec = (MemorySection)section;
for (Map.Entry<String, Object> entry : sec.map.entrySet()) {
output.add(createPath(section, entry.getKey(), this));
if ((deep) && (entry.getValue() instanceof ConfigurationSection)) {
ConfigurationSection subsection = (ConfigurationSection)entry.getValue();
mapChildrenKeys(output, subsection, deep);
}
}
} else {
Set<String> keys = section.getKeys(deep);
for (String key : keys) {
output.add(createPath(section, key, this));
}
}
}
protected void mapChildrenValues(Map<String, Object> output, ConfigurationSection section, boolean deep) {
if (section instanceof MemorySection) {
MemorySection sec = (MemorySection)section;
for (Map.Entry<String, Object> entry : sec.map.entrySet()) {
output.put(createPath(section, entry.getKey(), this), entry.getValue());
if (entry.getValue() instanceof ConfigurationSection) {
if (deep) {
mapChildrenValues(output, (ConfigurationSection)entry.getValue(), deep);
}
}
}
} else {
Map<String, Object> values = section.getValues(deep);
for (Map.Entry<String, Object> entry : values.entrySet()) {
output.put(createPath(section, entry.getKey(), this), entry.getValue());
}
}
}
/**
* Creates a full path to the given {@link ConfigurationSection} from its root {@link Configuration}.
* <p>
* You may use this method for any given {@link ConfigurationSection}, not only {@link MemorySection}.
*
* @param section Section to create a path for.
* @param key Name of the specified section.
* @return Full path of the section from its root.
*/
public static String createPath(ConfigurationSection section, String key) {
return createPath(section, key, (section == null) ? null : section.getRoot());
}
/**
* Creates a relative path to the given {@link ConfigurationSection} from the given relative section.
* <p>
* You may use this method for any given {@link ConfigurationSection}, not only {@link MemorySection}.
*
* @param section Section to create a path for.
* @param key Name of the specified section.
* @param relativeTo Section to create the path relative to.
* @return Full path of the section from its root.
*/
public static String createPath(ConfigurationSection section, String key, ConfigurationSection relativeTo) {
StringBuilder builder = new StringBuilder();
if (section != null) {
for (ConfigurationSection parent = section; (parent != null) && (parent != relativeTo); parent = parent.getParent()) {
if (builder.length() > 0) {
builder.insert(0, section.getRoot().options().pathSeparator());
}
builder.insert(0, parent.getName());
}
}
if ((key != null) && (key.length() > 0)) {
if (builder.length() > 0) {
builder.append(section.getRoot().options().pathSeparator());
}
builder.append(key);
}
return builder.toString();
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append(getClass().getSimpleName());
builder.append("[path='");
builder.append(getCurrentPath());
builder.append("', root='");
builder.append(root.getClass().getSimpleName());
builder.append("']");
return builder.toString();
}
}

Datei anzeigen

@ -0,0 +1,191 @@
package org.bukkit.configuration.file;
import com.google.common.io.Files;
import org.bukkit.configuration.InvalidConfigurationException;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import org.bukkit.configuration.Configuration;
import org.bukkit.configuration.MemoryConfiguration;
/**
* This is a base class for all File based implementations of {@link Configuration}
*/
public abstract class FileConfiguration extends MemoryConfiguration {
/**
* Creates an empty {@link FileConfiguration} with no default values.
*/
public FileConfiguration() {
super();
}
/**
* Creates an empty {@link FileConfiguration} using the specified {@link Configuration}
* as a source for all default values.
*
* @param defaults Default value provider
*/
public FileConfiguration(Configuration defaults) {
super(defaults);
}
/**
* Saves this {@link FileConfiguration} to the specified location.
* <p>
* If the file does not exist, it will be created. If already exists, it will
* be overwritten. If it cannot be overwritten or created, an exception will be thrown.
*
* @param file File to save to.
* @throws IOException Thrown when the given file cannot be written to for any reason.
* @throws IllegalArgumentException Thrown when file is null.
*/
public void save(File file) throws IOException {
if (file == null) {
throw new IllegalArgumentException("File cannot be null");
}
Files.createParentDirs(file);
String data = saveToString();
FileWriter writer = new FileWriter(file);
try {
writer.write(data);
} finally {
writer.close();
}
}
/**
* Saves this {@link FileConfiguration} to the specified location.
* <p>
* If the file does not exist, it will be created. If already exists, it will
* be overwritten. If it cannot be overwritten or created, an exception will be thrown.
*
* @param file File to save to.
* @throws IOException Thrown when the given file cannot be written to for any reason.
* @throws IllegalArgumentException Thrown when file is null.
*/
public void save(String file) throws IOException {
if (file == null) {
throw new IllegalArgumentException("File cannot be null");
}
save(new File(file));
}
/**
* Saves this {@link FileConfiguration} to a string, and returns it.
*
* @return String containing this configuration.
*/
public abstract String saveToString();
/**
* Loads this {@link FileConfiguration} from the specified location.
* <p>
* All the values contained within this configuration will be removed, leaving
* only settings and defaults, and the new values will be loaded from the given file.
* <p>
* If the file cannot be loaded for any reason, an exception will be thrown.
*
* @param file File to load from.
* @throws FileNotFoundException Thrown when the given file cannot be opened.
* @throws IOException Thrown when the given file cannot be read.
* @throws InvalidConfigurationException Thrown when the given file is not a valid Configuration.
* @throws IllegalArgumentException Thrown when file is null.
*/
public void load(File file) throws FileNotFoundException, IOException, InvalidConfigurationException {
if (file == null) {
throw new IllegalArgumentException("File cannot be null");
}
load(new FileInputStream(file));
}
/**
* Loads this {@link FileConfiguration} from the specified stream.
* <p>
* All the values contained within this configuration will be removed, leaving
* only settings and defaults, and the new values will be loaded from the given stream.
*
* @param stream Stream to load from
* @throws IOException Thrown when the given file cannot be read.
* @throws InvalidConfigurationException Thrown when the given file is not a valid Configuration.
* @throws IllegalArgumentException Thrown when stream is null.
*/
public void load(InputStream stream) throws IOException, InvalidConfigurationException {
if (stream == null) {
throw new IllegalArgumentException("Stream cannot be null");
}
InputStreamReader reader = new InputStreamReader(stream);
StringBuilder builder = new StringBuilder();
BufferedReader input = new BufferedReader(reader);
try {
String line;
while ((line = input.readLine()) != null) {
builder.append(line);
builder.append('\n');
}
} finally {
input.close();
}
loadFromString(builder.toString());
}
/**
* Loads this {@link FileConfiguration} from the specified location.
* <p>
* All the values contained within this configuration will be removed, leaving
* only settings and defaults, and the new values will be loaded from the given file.
* <p>
* If the file cannot be loaded for any reason, an exception will be thrown.
*
* @param file File to load from.
* @throws FileNotFoundException Thrown when the given file cannot be opened.
* @throws IOException Thrown when the given file cannot be read.
* @throws InvalidConfigurationException Thrown when the given file is not a valid Configuration.
* @throws IllegalArgumentException Thrown when file is null.
*/
public void load(String file) throws FileNotFoundException, IOException, InvalidConfigurationException {
if (file == null) {
throw new IllegalArgumentException("File cannot be null");
}
load(new File(file));
}
/**
* Loads this {@link FileConfiguration} from the specified string, as opposed to from file.
* <p>
* All the values contained within this configuration will be removed, leaving
* only settings and defaults, and the new values will be loaded from the given string.
* <p>
* If the string is invalid in any way, an exception will be thrown.
*
* @param contents Contents of a Configuration to load.
* @throws InvalidConfigurationException Thrown if the specified string is invalid.
* @throws IllegalArgumentException Thrown if contents is null.
*/
public abstract void loadFromString(String contents) throws InvalidConfigurationException;
@Override
public FileConfigurationOptions options() {
if (options == null) {
options = new FileConfigurationOptions(this);
}
return (FileConfigurationOptions)options;
}
}

Datei anzeigen

@ -0,0 +1,67 @@
package org.bukkit.configuration.file;
import org.bukkit.configuration.*;
/**
* Various settings for controlling the input and output of a {@link FileConfiguration}
*/
public class FileConfigurationOptions extends MemoryConfigurationOptions {
private String header = null;
protected FileConfigurationOptions(MemoryConfiguration configuration) {
super(configuration);
}
@Override
public FileConfiguration configuration() {
return (FileConfiguration)super.configuration();
}
@Override
public FileConfigurationOptions copyDefaults(boolean value) {
super.copyDefaults(value);
return this;
}
@Override
public FileConfigurationOptions pathSeparator(char value) {
super.pathSeparator(value);
return this;
}
/**
* Gets the header that will be applied to the top of the saved output.
* <p>
* This header will be commented out and applied directly at the top of the
* generated output of the {@link FileConfiguration}. It is not required to
* include a newline at the end of the header as it will automatically be applied,
* but you may include one if you wish for extra spacing.
* <p>
* Null is a valid value which will indicate that no header is to be applied.
* The default value is null.
*
* @return Header
*/
public String header() {
return header;
}
/**
* Sets the header that will be applied to the top of the saved output.
* <p>
* This header will be commented out and applied directly at the top of the
* generated output of the {@link FileConfiguration}. It is not required to
* include a newline at the end of the header as it will automatically be applied,
* but you may include one if you wish for extra spacing.
* <p>
* Null is a valid value which will indicate that no header is to be applied.
* The default value is null.
*
* @param value New header
* @return This object, for chaining
*/
public FileConfigurationOptions header(String value) {
this.header = value;
return this;
}
}

Datei anzeigen

@ -0,0 +1,228 @@
package org.bukkit.configuration.file;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.logging.Level;
import org.bukkit.Bukkit;
import org.bukkit.configuration.InvalidConfigurationException;
import org.bukkit.configuration.Configuration;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.serialization.ConfigurationSerializable;
import org.bukkit.configuration.serialization.ConfigurationSerialization;
import org.yaml.snakeyaml.DumperOptions;
import org.yaml.snakeyaml.Yaml;
import org.yaml.snakeyaml.constructor.SafeConstructor;
import org.yaml.snakeyaml.error.YAMLException;
import org.yaml.snakeyaml.representer.Representer;
/**
* An implementation of {@link Configuration} which saves all files in Yaml.
*/
public class YamlConfiguration extends FileConfiguration {
protected static final String COMMENT_PREFIX = "# ";
protected static final String BLANK_CONFIG = "{}\n";
private final DumperOptions yamlOptions = new DumperOptions();
private final Representer yamlRepresenter = new Representer();
private final Yaml yaml = new Yaml(new SafeConstructor(), yamlRepresenter, yamlOptions);
@Override
public String saveToString() {
Map<String, Object> output = new LinkedHashMap<String, Object>();
yamlOptions.setIndent(options().indent());
yamlOptions.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
yamlRepresenter.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
serializeValues(output, getValues(false));
String dump = yaml.dump(output);
if (dump.equals(BLANK_CONFIG)) {
dump = "";
}
return buildHeader() + dump;
}
@Override
public void loadFromString(String contents) throws InvalidConfigurationException {
if (contents == null) {
throw new IllegalArgumentException("Contents cannot be null");
}
Map<String, Object> input;
try {
input = (Map<String, Object>)yaml.load(contents);
} catch (Throwable ex) {
throw new InvalidConfigurationException("Specified contents is not a valid Configuration", ex);
}
deserializeValues(input, this);
}
protected void deserializeValues(Map<String, Object> input, ConfigurationSection section) throws InvalidConfigurationException {
if (input == null) {
return;
}
for (Map.Entry<String, Object> entry : input.entrySet()) {
Object value = entry.getValue();
if (value instanceof Map) {
Map<String, Object> subvalues;
try {
subvalues = (Map<String, Object>) value;
} catch (ClassCastException ex) {
throw new InvalidConfigurationException("Map found where type is not <String, Object>", ex);
}
if (subvalues.containsKey(ConfigurationSerialization.SERIALIZED_TYPE_KEY)) {
try {
ConfigurationSerializable serializable = ConfigurationSerialization.deserializeObject(subvalues);
section.set(entry.getKey(), serializable);
} catch (IllegalArgumentException ex) {
throw new InvalidConfigurationException("Could not deserialize object", ex);
}
} else {
ConfigurationSection subsection = section.createSection(entry.getKey());
deserializeValues(subvalues, subsection);
}
} else {
section.set(entry.getKey(), entry.getValue());
}
}
}
protected void serializeValues(Map<String, Object> output, Map<String, Object> input) {
if (input == null) {
return;
}
for (Map.Entry<String, Object> entry : input.entrySet()) {
Object value = entry.getValue();
if (value instanceof ConfigurationSection) {
ConfigurationSection subsection = (ConfigurationSection)entry.getValue();
Map<String, Object> subvalues = new LinkedHashMap<String, Object>();
serializeValues(subvalues, subsection.getValues(false));
value = subvalues;
} else if (value instanceof ConfigurationSerializable) {
ConfigurationSerializable serializable = (ConfigurationSerializable)value;
Map<String, Object> subvalues = new LinkedHashMap<String, Object>();
subvalues.put(ConfigurationSerialization.SERIALIZED_TYPE_KEY, ConfigurationSerialization.getAlias(serializable.getClass()));
serializeValues(subvalues, serializable.serialize());
value = subvalues;
} else if ((!isPrimitiveWrapper(value)) && (!isNaturallyStorable(value))) {
throw new IllegalStateException("Configuration contains non-serializable values, cannot process");
}
if (value != null) {
output.put(entry.getKey(), value);
}
}
}
protected String buildHeader() {
String header = options().header();
if (header == null) {
return "";
}
StringBuilder builder = new StringBuilder();
String[] lines = header.split("\r?\n");
for (int i = 0; i < lines.length; i++) {
builder.append(COMMENT_PREFIX);
builder.append(lines[i]);
builder.append("\n");
}
return builder.toString();
}
@Override
public YamlConfigurationOptions options() {
if (options == null) {
options = new YamlConfigurationOptions(this);
}
return (YamlConfigurationOptions)options;
}
/**
* Creates a new {@link YamlConfiguration}, loading from the given file.
* <p>
* Any errors loading the Configuration will be logged and then ignored.
* If the specified input is not a valid config, a blank config will be returned.
*
* @param file Input file
* @return Resulting configuration
* @throws IllegalArgumentException Thrown is file is null
*/
public static YamlConfiguration loadConfiguration(File file) {
if (file == null) {
throw new IllegalArgumentException("File cannot be null");
}
YamlConfiguration config = new YamlConfiguration();
try {
config.load(file);
} catch (FileNotFoundException ex) {
} catch (IOException ex) {
Bukkit.getLogger().log(Level.SEVERE, "Cannot load " + file, ex);
} catch (InvalidConfigurationException ex) {
if (ex.getCause() instanceof YAMLException) {
Bukkit.getLogger().severe("Config file " + file + " isn't valid! " + ex.getCause());
} else if ((ex.getCause() == null) || (ex.getCause() instanceof ClassCastException)) {
Bukkit.getLogger().severe("Config file " + file + " isn't valid!");
} else {
Bukkit.getLogger().log(Level.SEVERE, "Cannot load " + file + ": " + ex.getCause().getClass(), ex);
}
}
return config;
}
/**
* Creates a new {@link YamlConfiguration}, loading from the given stream.
* <p>
* Any errors loading the Configuration will be logged and then ignored.
* If the specified input is not a valid config, a blank config will be returned.
*
* @param stream Input stream
* @return Resulting configuration
* @throws IllegalArgumentException Thrown is stream is null
*/
public static YamlConfiguration loadConfiguration(InputStream stream) {
if (stream == null) {
throw new IllegalArgumentException("Stream cannot be null");
}
YamlConfiguration config = new YamlConfiguration();
try {
config.load(stream);
} catch (IOException ex) {
Bukkit.getLogger().log(Level.SEVERE, "Cannot load configuration", ex);
} catch (InvalidConfigurationException ex) {
if (ex.getCause() instanceof YAMLException) {
Bukkit.getLogger().severe("Config file isn't valid! " + ex.getCause());
} else if ((ex.getCause() == null) || (ex.getCause() instanceof ClassCastException)) {
Bukkit.getLogger().severe("Config file isn't valid!");
} else {
Bukkit.getLogger().log(Level.SEVERE, "Cannot load configuration: " + ex.getCause().getClass(), ex);
}
}
return config;
}
}

Datei anzeigen

@ -0,0 +1,63 @@
package org.bukkit.configuration.file;
/**
* Various settings for controlling the input and output of a {@link YamlConfiguration}
*/
public class YamlConfigurationOptions extends FileConfigurationOptions {
private int indent = 2;
protected YamlConfigurationOptions(YamlConfiguration configuration) {
super(configuration);
}
@Override
public YamlConfiguration configuration() {
return (YamlConfiguration)super.configuration();
}
@Override
public YamlConfigurationOptions copyDefaults(boolean value) {
super.copyDefaults(value);
return this;
}
@Override
public YamlConfigurationOptions pathSeparator(char value) {
super.pathSeparator(value);
return this;
}
@Override
public YamlConfigurationOptions header(String value) {
super.header(value);
return this;
}
/**
* Gets how much spaces should be used to indent each line.
* <p>
* The minimum value this may be is 2, and the maximum is 9.
*
* @return How much to indent by
*/
public int indent() {
return indent;
}
/**
* Sets how much spaces should be used to indent each line.
* <p>
* The minimum value this may be is 2, and the maximum is 9.
*
* @param value New indent
* @return This object, for chaining
*/
public YamlConfigurationOptions indent(int value) {
if ((indent < 2) || (value > 9)) {
throw new IllegalArgumentException("Indent must be between 1 and 10 characters");
}
this.indent = value;
return this;
}
}

Datei anzeigen

@ -0,0 +1,24 @@
package org.bukkit.configuration.serialization;
import java.util.Map;
/**
* Represents an object that may be serialized.
* <p>
* These objects MUST implement one of the following, in addition to the methods
* as defined by this interface:
* - A static method "deserialize" that accepts a single {@link Map<String, Object>} and returns the class.
* - A static method "valueOf" that accepts a single {@link Map<String, Object>} and returns the class.
* - A constructor that accepts a single {@link Map<String, Object>}.
*/
public interface ConfigurationSerializable {
/**
* Creates a Map representation of this class.
* <p>
* This class must provide a method to restore this class, as defined in the
* {@link ConfigurationSerializable} interface javadocs.
*
* @return Map containing the current state of this class
*/
public Map<String, Object> serialize();
}

Datei anzeigen

@ -0,0 +1,251 @@
package org.bukkit.configuration.serialization;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.bukkit.util.BlockVector;
import org.bukkit.util.Vector;
/**
* Utility class for storing and retrieving classes for {@link Configuration}.
*/
public class ConfigurationSerialization {
public static final String SERIALIZED_TYPE_KEY = "==";
private final Class<? extends ConfigurationSerializable> clazz;
private static Map<String, Class<? extends ConfigurationSerializable>> aliases = new HashMap<String, Class<? extends ConfigurationSerializable>>();
static {
registerClass(Vector.class);
registerClass(BlockVector.class);
}
protected ConfigurationSerialization(Class<? extends ConfigurationSerializable> clazz) {
this.clazz = clazz;
}
protected Method getMethod(String name, boolean isStatic) {
try {
Method method = clazz.getDeclaredMethod(name, Map.class);
if (!ConfigurationSerializable.class.isAssignableFrom(method.getReturnType())) {
return null;
}
if (Modifier.isStatic(method.getModifiers()) != isStatic) {
return null;
}
return method;
} catch (NoSuchMethodException ex) {
return null;
} catch (SecurityException ex) {
return null;
}
}
protected Constructor<? extends ConfigurationSerializable> getConstructor() {
try {
return clazz.getConstructor(Map.class);
} catch (NoSuchMethodException ex) {
return null;
} catch (SecurityException ex) {
return null;
}
}
protected ConfigurationSerializable deserializeViaMethod(Method method, Map<String, Object> args) {
try {
ConfigurationSerializable result = (ConfigurationSerializable)method.invoke(null, args);
if (result == null) {
Logger.getLogger(ConfigurationSerialization.class.getName()).log(Level.SEVERE, "Could not call method '" + method.toString() + "' of " + clazz + " for deserialization: method returned null");
} else {
return result;
}
} catch (Throwable ex) {
Logger.getLogger(ConfigurationSerialization.class.getName()).log(Level.SEVERE, "Could not call method '" + method.toString() + "' of " + clazz + " for deserialization", ex);
}
return null;
}
protected ConfigurationSerializable deserializeViaCtor(Constructor<? extends ConfigurationSerializable> ctor, Map<String, Object> args) {
try {
return ctor.newInstance(args);
} catch (Throwable ex) {
Logger.getLogger(ConfigurationSerialization.class.getName()).log(Level.SEVERE, "Could not call constructor '" + ctor.toString() + "' of " + clazz + " for deserialization", ex);
}
return null;
}
public ConfigurationSerializable deserialize(Map<String, Object> args) {
if (args == null) {
throw new IllegalArgumentException("Args must not be null");
}
ConfigurationSerializable result = null;
Method method = null;
if (result == null) {
method = getMethod("deserialize", true);
if (method != null) {
result = deserializeViaMethod(method, args);
}
}
if (result == null) {
method = getMethod("valueOf", true);
if (method != null) {
result = deserializeViaMethod(method, args);
}
}
if (result == null) {
Constructor<? extends ConfigurationSerializable> constructor = getConstructor();
if (constructor != null) {
result = deserializeViaCtor(constructor, args);
}
}
return result;
}
/**
* Attempts to deserialize the given arguments into a new instance of the given class.
* <p>
* The class must implement {@link ConfigurationSerializable}, including the extra methods
* as specified in the javadoc of ConfigurationSerializable.
* <p>
* If a new instance could not be made, an example being the class not fully implementing
* the interface, null will be returned.
*
* @param args Arguments for deserialization
* @param clazz Class to deserialize into
* @return New instance of the specified class
*/
public static ConfigurationSerializable deserializeObject(Map<String, Object> args, Class<? extends ConfigurationSerializable> clazz) {
return new ConfigurationSerialization(clazz).deserialize(args);
}
/**
* Attempts to deserialize the given arguments into a new instance of the given class.
* <p>
* The class must implement {@link ConfigurationSerializable}, including the extra methods
* as specified in the javadoc of ConfigurationSerializable.
* <p>
* If a new instance could not be made, an example being the class not fully implementing
* the interface, null will be returned.
*
* @param args Arguments for deserialization
* @return New instance of the specified class
*/
public static ConfigurationSerializable deserializeObject(Map<String, Object> args) {
Class<? extends ConfigurationSerializable> clazz = null;
if (args.containsKey(SERIALIZED_TYPE_KEY)) {
try {
String alias = (String)args.get(SERIALIZED_TYPE_KEY);
if (alias == null) {
throw new IllegalArgumentException("Specified class does not exist ('" + alias + ")'");
} else {
clazz = getClassByAlias(alias);
}
} catch (ClassCastException ex) {
ex.fillInStackTrace();
throw ex;
}
} else {
throw new IllegalArgumentException("Args doesn't contain type key ('" + SERIALIZED_TYPE_KEY + "')");
}
return new ConfigurationSerialization(clazz).deserialize(args);
}
/**
* Registers the given {@link ConfigurationSerializable} class by its alias
*
* @param clazz Class to register
*/
public static void registerClass(Class<? extends ConfigurationSerializable> clazz) {
DelegateDeserialization delegate = clazz.getAnnotation(DelegateDeserialization.class);
if (delegate == null ) {
registerClass(clazz, getAlias(clazz));
registerClass(clazz, clazz.getName());
}
}
/**
* Registers the given alias to the specified {@link ConfigurationSerializable} class
*
* @param clazz Class to register
* @param alias Alias to register as
*/
public static void registerClass(Class<? extends ConfigurationSerializable> clazz, String alias) {
aliases.put(alias, clazz);
}
/**
* Unregisters the specified alias to a {@link ConfigurationSerializable}
*
* @param alias Alias to unregister
*/
public static void unregisterClass(String alias) {
aliases.remove(alias);
}
/**
* Unregisters any aliases for the specified {@link ConfigurationSerializable} class
*
* @param clazz Class to unregister
*/
public static void unregisterClass(Class<? extends ConfigurationSerializable> clazz) {
while (aliases.values().remove(clazz));
}
/**
* Attempts to get a registered {@link ConfigurationSerializable} class by its alias
*
* @param alias Alias of the serializable
* @return Registered class, or null if not found
*/
public static Class<? extends ConfigurationSerializable> getClassByAlias(String alias) {
return aliases.get(alias);
}
/**
* Gets the correct alias for the given {@link ConfigurationSerializable} class
*
* @param clazz Class to get alias for
* @return Alias to use for the class
*/
public static String getAlias(Class<? extends ConfigurationSerializable> clazz) {
DelegateDeserialization delegate = clazz.getAnnotation(DelegateDeserialization.class);
if (delegate != null) {
if ((delegate.value() == null) || (delegate.value() == clazz)) {
delegate = null;
} else {
return getAlias(delegate.value());
}
}
if (delegate == null) {
SerializableAs alias = clazz.getAnnotation(SerializableAs.class);
if ((alias != null) && (alias.value() != null)) {
return alias.value();
}
}
return clazz.getName();
}
}

Datei anzeigen

@ -0,0 +1,21 @@
package org.bukkit.configuration.serialization;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Represents a {@link ConfigurationSerializable} that will delegate all deserialization to another
* {@link ConfigurationSerializable}
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface DelegateDeserialization {
/**
* Which class should be used as a delegate for this classes deserialization
*
* @return Delegate class
*/
public Class<? extends ConfigurationSerializable> value();
}

Datei anzeigen

@ -0,0 +1,28 @@
package org.bukkit.configuration.serialization;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Represents an "alias" that a {@link ConfigurationSerializable} may be stored as.
* If this is not present on a {@link ConfigurationSerializable} class, it will use the
* fully qualified name of the class.
* <p>
* Using this annotation on any other class than a {@link ConfigurationSerializable} will
* have no effect.
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface SerializableAs {
/**
* This is the name your class will be stored and retrieved as.
* <p>
* This name MUST be unique. We recommend using names such as "MyPluginThing" instead of
* "Thing".
*
* @return Name to serialize the class as.
*/
public String value();
}

Datei anzeigen

@ -1,12 +1,16 @@
package org.bukkit.inventory;
import java.io.Serializable;
import java.util.LinkedHashMap;
import java.util.Map;
import org.bukkit.Material;
import org.bukkit.configuration.serialization.ConfigurationSerializable;
import org.bukkit.material.MaterialData;
/**
* Represents a stack of items
*/
public class ItemStack {
public class ItemStack implements Serializable, ConfigurationSerializable {
private int type;
private int amount = 0;
private MaterialData data = null;
@ -208,4 +212,36 @@ public class ItemStack {
hash = hash * 7 + 23 * getAmount(); // too bad these are mutable values... Q_Q
return hash;
}
public Map<String, Object> serialize() {
Map<String, Object> result = new LinkedHashMap<String, Object>();
result.put("type", getType());
if (durability != 0) {
result.put("damage", durability);
}
if (amount != 1) {
result.put("amount", amount);
}
return result;
}
public static ItemStack deserialize(Map<String, Object> args) {
Material type = Material.getMaterial((String)args.get("type"));
short damage = 0;
int amount = 1;
if (args.containsKey("damage")) {
damage = (Short)args.get("damage");
}
if (args.containsKey("amount")) {
amount = (Integer)args.get("amount");
}
return new ItemStack(type, amount, damage);
}
}

Datei anzeigen

@ -2,8 +2,10 @@ package org.bukkit.plugin;
import com.avaje.ebean.EbeanServer;
import java.io.File;
import java.io.InputStream;
import org.bukkit.Server;
import org.bukkit.command.CommandExecutor;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.generator.ChunkGenerator;
import org.bukkit.util.config.Configuration;
@ -33,6 +35,29 @@ public interface Plugin extends CommandExecutor {
* @return The configuration
*/
public Configuration getConfiguration();
/**
* Gets a {@link FileConfiguration} for this plugin, read through "config.yml"
* <p>
* If there is a default config.yml embedded in this plugin, it will be provided
* as a default for this Configuration.
*
* @return Plugin configuration
*/
public FileConfiguration getConfig();
/**
* Gets an embedded resource in this plugin
*
* @param filename Filename of the resource
* @return File if found, otherwise null
*/
public InputStream getResource(String filename);
/**
* Saves the {@link FileConfiguration} retrievable by {@link #getConfig()}.
*/
public void saveConfig();
/**
* Gets the associated PluginLoader responsible for this plugin

Datei anzeigen

@ -7,17 +7,27 @@ import com.avaje.ebean.config.ServerConfig;
import com.avaje.ebeaninternal.api.SpiEbeanServer;
import com.avaje.ebeaninternal.server.ddl.DdlGenerator;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.bukkit.Bukkit;
import org.bukkit.Server;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.command.PluginCommand;
import org.bukkit.configuration.InvalidConfigurationException;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.generator.ChunkGenerator;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.PluginDescriptionFile;
import org.bukkit.plugin.PluginLoader;
import org.bukkit.util.config.Configuration;
import org.yaml.snakeyaml.error.YAMLException;
/**
* Represents a Java plugin
@ -34,6 +44,8 @@ public abstract class JavaPlugin implements Plugin {
private Configuration config = null;
private boolean naggable = true;
private EbeanServer ebean = null;
private FileConfiguration newConfig = null;
private File configFile = null;
public JavaPlugin() {}
@ -99,10 +111,32 @@ public abstract class JavaPlugin implements Plugin {
* the configuration file will have no values.
*
* @return The configuration.
* @deprecated See the new
*/
@Deprecated
public Configuration getConfiguration() {
return config;
}
public FileConfiguration getConfig() {
return newConfig;
}
public void saveConfig() {
try {
newConfig.save(configFile);
} catch (IOException ex) {
Logger.getLogger(JavaPlugin.class.getName()).log(Level.SEVERE, "Could not save config to " + configFile, ex);
}
}
public InputStream getResource(String filename) {
if (filename == null) {
throw new IllegalArgumentException("Filename cannot be null");
}
return getClassLoader().getResourceAsStream(filename);
}
/**
* Returns the ClassLoader which holds this plugin
@ -153,8 +187,17 @@ public abstract class JavaPlugin implements Plugin {
this.description = description;
this.dataFolder = dataFolder;
this.classLoader = classLoader;
this.config = new Configuration(new File(dataFolder, "config.yml"));
this.configFile = new File(dataFolder, "config.yml");
this.config = new Configuration(configFile);
this.config.load();
this.newConfig = YamlConfiguration.loadConfiguration(configFile);
InputStream defConfigStream = getResource("config.yml");
if (defConfigStream != null) {
YamlConfiguration defConfig = YamlConfiguration.loadConfiguration(defConfigStream);
newConfig.setDefaults(defConfig);
}
if (description.isDatabaseEnabled()) {
ServerConfig db = new ServerConfig();

Datei anzeigen

@ -15,6 +15,9 @@ import java.util.jar.JarFile;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.bukkit.Server;
import org.bukkit.configuration.serialization.ConfigurationSerializable;
import org.bukkit.configuration.serialization.ConfigurationSerialization;
import org.bukkit.configuration.serialization.SerializableAs;
import org.bukkit.event.CustomEventListener;
import org.bukkit.event.Event;
import org.bukkit.event.Listener;
@ -229,6 +232,20 @@ public class JavaPluginLoader implements PluginLoader {
public void setClass(final String name, final Class<?> clazz) {
if (!classes.containsKey(name)) {
classes.put(name, clazz);
if (ConfigurationSerializable.class.isAssignableFrom(clazz)) {
Class<? extends ConfigurationSerializable> serializable = (Class<? extends ConfigurationSerializable>)clazz;
ConfigurationSerialization.registerClass(serializable);
}
}
}
public void removeClass(String name) {
Class<?> clazz = classes.remove(name);
if (ConfigurationSerializable.class.isAssignableFrom(clazz)) {
Class<? extends ConfigurationSerializable> serializable = (Class<? extends ConfigurationSerializable>)clazz;
ConfigurationSerialization.unregisterClass(serializable);
}
}
@ -973,7 +990,7 @@ public class JavaPluginLoader implements PluginLoader {
Set<String> names = loader.getClasses();
for (String name : names) {
classes.remove(name);
removeClass(name);
}
}
}

Datei anzeigen

@ -1,13 +1,15 @@
package org.bukkit.util;
import java.util.Map;
import org.bukkit.configuration.serialization.SerializableAs;
/**
* A vector with a hash function that floors the X, Y, Z components, a la
* BlockVector in WorldEdit. BlockVectors can be used in hash sets and
* hash maps. Be aware that BlockVectors are mutable, but it is important
* that BlockVectors are never changed once put into a hash set or hash map.
*
* @author sk89q
*/
@SerializableAs("BlockVector")
public class BlockVector extends Vector {
/**
@ -109,4 +111,22 @@ public class BlockVector extends Vector {
v.z = z;
return v;
}
public static BlockVector deserialize(Map<String, Object> args) {
double x = 0;
double y = 0;
double z = 0;
if (args.containsKey("x")) {
x = (Double)args.get("x");
}
if (args.containsKey("y")) {
y = (Double)args.get("y");
}
if (args.containsKey("z")) {
z = (Double)args.get("z");
}
return new BlockVector(x, y, z);
}
}

Datei anzeigen

@ -1,18 +1,21 @@
package org.bukkit.util;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Random;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.configuration.serialization.ConfigurationSerializable;
import org.bukkit.configuration.serialization.SerializableAs;
/**
* Represents a mutable vector. Because the components of Vectors are mutable,
* storing Vectors long term may be dangerous if passing code modifies the
* Vector later. If you want to keep around a Vector, it may be wise to call
* <code>clone()</code> in order to get a copy.
*
* @author sk89q
*/
public class Vector implements Cloneable {
@SerializableAs("Vector")
public class Vector implements Cloneable, ConfigurationSerializable {
private static final long serialVersionUID = -2657651106777219169L;
private static Random random = new Random();
@ -635,4 +638,32 @@ public class Vector implements Cloneable {
public static Vector getRandom() {
return new Vector(random.nextDouble(), random.nextDouble(), random.nextDouble());
}
public Map<String, Object> serialize() {
Map<String, Object> result = new LinkedHashMap<String, Object>();
result.put("x", getX());
result.put("y", getY());
result.put("z", getZ());
return result;
}
public static Vector deserialize(Map<String, Object> args) {
double x = 0;
double y = 0;
double z = 0;
if (args.containsKey("x")) {
x = (Double)args.get("x");
}
if (args.containsKey("y")) {
y = (Double)args.get("y");
}
if (args.containsKey("z")) {
z = (Double)args.get("z");
}
return new Vector(x, y, z);
}
}

Datei anzeigen

@ -7,6 +7,7 @@ import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.HashMap;
import java.util.Map;
import org.bukkit.configuration.file.YamlConfiguration;
import org.yaml.snakeyaml.DumperOptions;
import org.yaml.snakeyaml.Yaml;
import org.yaml.snakeyaml.constructor.SafeConstructor;
@ -52,12 +53,18 @@ import org.yaml.snakeyaml.representer.Representer;
* <p>This class is currently incomplete. It is not yet possible to get a node.
* </p>
*
* @deprecated See {@link YamlConfiguration}
*/
@Deprecated
public class Configuration extends ConfigurationNode {
private Yaml yaml;
private File file;
private String header = null;
/**
* @deprecated See {@link YamlConfiguration}
*/
@Deprecated
public Configuration(File file) {
super(new HashMap<String, Object>());

Datei anzeigen

@ -0,0 +1,504 @@
package org.bukkit.configuration;
import org.bukkit.Material;
import java.io.File;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import org.bukkit.inventory.ItemStack;
import org.bukkit.util.Vector;
import org.junit.Test;
import static org.junit.Assert.*;
public abstract class ConfigurationSectionTest {
public abstract ConfigurationSection getConfigurationSection();
@Test
public void testGetKeys() {
ConfigurationSection section = getConfigurationSection();
section.set("key", true);
section.set("subsection.subkey", true);
section.set("subsection.subkey2", true);
section.set("subsection.subsubsection.key", true);
section.set("key2", true);
assertArrayEquals(new String[] {"key", "subsection", "key2"}, section.getKeys(false).toArray());
assertArrayEquals(new String[] {"key", "subsection", "subsection.subkey", "subsection.subkey2", "subsection.subsubsection", "subsection.subsubsection.key", "key2"}, section.getKeys(true).toArray());
assertArrayEquals(new String[] {"subkey", "subkey2", "subsubsection", "subsubsection.key"}, section.getConfigurationSection("subsection").getKeys(true).toArray());
}
@Test
public void testGetKeysWithDefaults() {
ConfigurationSection section = getConfigurationSection();
section.getRoot().options().copyDefaults(true);
section.set("key", true);
section.addDefault("subsection.subkey", true);
section.addDefault("subsection.subkey2", true);
section.addDefault("subsection.subsubsection.key", true);
section.addDefault("key2", true);
assertArrayEquals(new String[] {"subsection", "key2", "key"}, section.getKeys(false).toArray());
assertArrayEquals(new String[] {"subsection", "subsection.subkey", "subsection.subkey2", "subsection.subsubsection", "subsection.subsubsection.key", "key2", "key"}, section.getKeys(true).toArray());
assertArrayEquals(new String[] {"subkey", "subkey2", "subsubsection", "subsubsection.key"}, section.getConfigurationSection("subsection").getKeys(true).toArray());
}
@Test
public void testGetValues() {
ConfigurationSection section = getConfigurationSection();
section.set("bool", true);
section.set("subsection.string", "test");
section.set("subsection.long", Long.MAX_VALUE);
section.set("int", 42);
Map<String, Object> shallowValues = section.getValues(false);
assertArrayEquals(new String[] {"bool", "subsection", "int"}, shallowValues.keySet().toArray());
assertArrayEquals(new Object[] {true, section.getConfigurationSection("subsection"), 42}, shallowValues.values().toArray());
Map<String, Object> deepValues = section.getValues(true);
assertArrayEquals(new String[] {"bool", "subsection", "subsection.string", "subsection.long", "int"}, deepValues.keySet().toArray());
assertArrayEquals(new Object[] {true, section.getConfigurationSection("subsection"), "test", Long.MAX_VALUE, 42}, deepValues.values().toArray());
}
@Test
public void testGetValuesWithDefaults() {
ConfigurationSection section = getConfigurationSection();
section.getRoot().options().copyDefaults(true);
section.set("bool", true);
section.set("subsection.string", "test");
section.addDefault("subsection.long", Long.MAX_VALUE);
section.addDefault("int", 42);
Map<String, Object> shallowValues = section.getValues(false);
assertArrayEquals(new String[] {"subsection", "int", "bool"}, shallowValues.keySet().toArray());
assertArrayEquals(new Object[] {section.getConfigurationSection("subsection"), 42, true}, shallowValues.values().toArray());
Map<String, Object> deepValues = section.getValues(true);
assertArrayEquals(new String[] {"subsection", "subsection.long", "int", "bool", "subsection.string"}, deepValues.keySet().toArray());
assertArrayEquals(new Object[] {section.getConfigurationSection("subsection"), Long.MAX_VALUE, 42, true, "test"}, deepValues.values().toArray());
}
@Test
public void testContains() {
ConfigurationSection section = getConfigurationSection();
section.set("exists", true);
assertTrue(section.contains("exists"));
assertFalse(section.contains("doesnt-exist"));
}
@Test
public void testIsSet() {
ConfigurationSection section = getConfigurationSection();
section.set("notDefault", true);
section.getRoot().addDefault("default", true);
section.getRoot().addDefault("defaultAndSet", true);
section.set("defaultAndSet", true);
assertTrue(section.isSet("notDefault"));
assertFalse(section.isSet("default"));
assertTrue(section.isSet("defaultAndSet"));
}
@Test
public void testGetCurrentPath() {
ConfigurationSection section = getConfigurationSection();
assertEquals(section.getName(), section.getCurrentPath());
}
@Test
public void testGetName() {
ConfigurationSection section = getConfigurationSection().createSection("subsection");
assertEquals("subsection", section.getName());
assertEquals("", section.getRoot().getName());
}
@Test
public void testGetRoot() {
ConfigurationSection section = getConfigurationSection();
assertNotNull(section.getRoot());
assertTrue(section.getRoot().contains(section.getCurrentPath()));
}
@Test
public void testGetParent() {
ConfigurationSection section = getConfigurationSection();
ConfigurationSection subsection = section.createSection("subsection");
assertEquals(section.getRoot(), section.getParent());
assertEquals(section, subsection.getParent());
}
@Test
public void testGet_String() {
ConfigurationSection section = getConfigurationSection();
section.set("exists", "hello world");
assertEquals("hello world", section.getString("exists"));
assertNull(section.getString("doesntExist"));
}
@Test
public void testGet_String_Object() {
ConfigurationSection section = getConfigurationSection();
section.set("exists", "Set Value");
assertEquals("Set Value", section.get("exists", "Default Value"));
assertEquals("Default Value", section.get("doesntExist", "Default Value"));
}
@Test
public void testSet() {
ConfigurationSection section = getConfigurationSection();
section.set("exists", "hello world");
assertEquals("hello world", section.get("exists"));
}
@Test
public void testCreateSection() {
ConfigurationSection section = getConfigurationSection();
ConfigurationSection subsection = section.createSection("subsection");
assertEquals("subsection", subsection.getName());
}
@Test
public void testGetString_String() {
ConfigurationSection section = getConfigurationSection();
String key = "exists";
String value = "Hello World";
section.set(key, value);
assertEquals(value, section.getString(key));
assertNull(section.getString("doesntExist"));
}
@Test
public void testGetString_String_String() {
ConfigurationSection section = getConfigurationSection();
String key = "exists";
String value = "Hello World";
String def = "Default Value";
section.set(key, value);
assertEquals(value, section.getString(key, def));
assertEquals(def, section.getString("doesntExist", def));
}
@Test
public void testIsString() {
ConfigurationSection section = getConfigurationSection();
String key = "exists";
String value = "Hello World";
section.set(key, value);
assertTrue(section.isString(key));
assertFalse(section.isString("doesntExist"));
}
@Test
public void testGetInt_String() {
ConfigurationSection section = getConfigurationSection();
String key = "exists";
int value = Integer.MAX_VALUE;
section.set(key, value);
assertEquals(value, section.getInt(key));
assertNull(section.getString("doesntExist"));
}
@Test
public void testGetInt_String_Int() {
ConfigurationSection section = getConfigurationSection();
String key = "exists";
int value = Integer.MAX_VALUE;
int def = Integer.MIN_VALUE;
section.set(key, value);
assertEquals(value, section.getInt(key, def));
assertEquals(def, section.getInt("doesntExist", def));
}
@Test
public void testIsInt() {
ConfigurationSection section = getConfigurationSection();
String key = "exists";
int value = Integer.MAX_VALUE;
section.set(key, value);
assertTrue(section.isInt(key));
assertFalse(section.isInt("doesntExist"));
}
@Test
public void testGetBoolean_String() {
ConfigurationSection section = getConfigurationSection();
String key = "exists";
boolean value = true;
section.set(key, value);
assertEquals(value, section.getBoolean(key));
assertNull(section.getString("doesntExist"));
}
@Test
public void testGetBoolean_String_Boolean() {
ConfigurationSection section = getConfigurationSection();
String key = "exists";
boolean value = true;
boolean def = false;
section.set(key, value);
assertEquals(value, section.getBoolean(key, def));
assertEquals(def, section.getBoolean("doesntExist", def));
}
@Test
public void testIsBoolean() {
ConfigurationSection section = getConfigurationSection();
String key = "exists";
boolean value = true;
section.set(key, value);
assertTrue(section.isBoolean(key));
assertFalse(section.isBoolean("doesntExist"));
}
@Test
public void testGetDouble_String() {
ConfigurationSection section = getConfigurationSection();
String key = "exists";
double value = Double.MAX_VALUE;
section.set(key, value);
assertEquals(value, section.getDouble(key), 1);
assertNull(section.getString("doesntExist"));
}
@Test
public void testGetDouble_String_Double() {
ConfigurationSection section = getConfigurationSection();
String key = "exists";
double value = Double.MAX_VALUE;
double def = Double.MIN_VALUE;
section.set(key, value);
assertEquals(value, section.getDouble(key, def), 1);
assertEquals(def, section.getDouble("doesntExist", def), 1);
}
@Test
public void testIsDouble() {
ConfigurationSection section = getConfigurationSection();
String key = "exists";
double value = Double.MAX_VALUE;
section.set(key, value);
assertTrue(section.isDouble(key));
assertFalse(section.isDouble("doesntExist"));
}
@Test
public void testGetLong_String() {
ConfigurationSection section = getConfigurationSection();
String key = "exists";
long value = Long.MAX_VALUE;
section.set(key, value);
assertEquals(value, section.getLong(key));
assertNull(section.getString("doesntExist"));
}
@Test
public void testGetLong_String_Long() {
ConfigurationSection section = getConfigurationSection();
String key = "exists";
long value = Long.MAX_VALUE;
long def = Long.MIN_VALUE;
section.set(key, value);
assertEquals(value, section.getLong(key, def));
assertEquals(def, section.getLong("doesntExist", def));
}
@Test
public void testIsLong() {
ConfigurationSection section = getConfigurationSection();
String key = "exists";
long value = Long.MAX_VALUE;
section.set(key, value);
assertTrue(section.isLong(key));
assertFalse(section.isLong("doesntExist"));
}
@Test
public void testGetList_String() {
ConfigurationSection section = getConfigurationSection();
String key = "exists";
List value = Arrays.asList("One", "Two", "Three");
section.set(key, value);
assertEquals(value, section.getList(key));
assertNull(section.getString("doesntExist"));
}
@Test
public void testGetList_String_List() {
ConfigurationSection section = getConfigurationSection();
String key = "exists";
List value = Arrays.asList("One", "Two", "Three");
List def = Arrays.asList("A", "B", "C");
section.set(key, value);
assertEquals(value, section.getList(key, def));
assertEquals(def, section.getList("doesntExist", def));
}
@Test
public void testIsList() {
ConfigurationSection section = getConfigurationSection();
String key = "exists";
List value = Arrays.asList("One", "Two", "Three");
section.set(key, value);
assertTrue(section.isList(key));
assertFalse(section.isList("doesntExist"));
}
@Test
public void testGetVector_String() {
ConfigurationSection section = getConfigurationSection();
String key = "exists";
Vector value = new Vector(Double.MIN_VALUE, Double.MAX_VALUE, 5);
section.set(key, value);
assertEquals(value, section.getVector(key));
assertNull(section.getString("doesntExist"));
}
@Test
public void testGetVector_String_Vector() {
ConfigurationSection section = getConfigurationSection();
String key = "exists";
Vector value = new Vector(Double.MIN_VALUE, Double.MAX_VALUE, 5);
Vector def = new Vector(100, Double.MIN_VALUE, Double.MAX_VALUE);
section.set(key, value);
assertEquals(value, section.getVector(key, def));
assertEquals(def, section.getVector("doesntExist", def));
}
@Test
public void testIsVector() {
ConfigurationSection section = getConfigurationSection();
String key = "exists";
Vector value = new Vector(Double.MIN_VALUE, Double.MAX_VALUE, 5);
section.set(key, value);
assertTrue(section.isVector(key));
assertFalse(section.isVector("doesntExist"));
}
@Test
public void testGetItemStack_String() {
ConfigurationSection section = getConfigurationSection();
String key = "exists";
ItemStack value = new ItemStack(Material.WOOD, 50, (short)2);
section.set(key, value);
assertEquals(value, section.getItemStack(key));
assertNull(section.getString("doesntExist"));
}
@Test
public void testGetItemStack_String_ItemStack() {
ConfigurationSection section = getConfigurationSection();
String key = "exists";
ItemStack value = new ItemStack(Material.WOOD, 50, (short)2);
ItemStack def = new ItemStack(Material.STONE, 1);
section.set(key, value);
assertEquals(value, section.getItemStack(key, def));
assertEquals(def, section.getItemStack("doesntExist", def));
}
@Test
public void testIsItemStack() {
ConfigurationSection section = getConfigurationSection();
String key = "exists";
ItemStack value = new ItemStack(Material.WOOD, 50, (short)2);
section.set(key, value);
assertTrue(section.isItemStack(key));
assertFalse(section.isItemStack("doesntExist"));
}
@Test
public void testGetConfigurationSection() {
ConfigurationSection section = getConfigurationSection();
String key = "exists";
ConfigurationSection subsection = section.createSection(key);
assertEquals(subsection, section.getConfigurationSection(key));
}
@Test
public void testIsConfigurationSection() {
ConfigurationSection section = getConfigurationSection();
String key = "exists";
ConfigurationSection subsection = section.createSection(key);
assertTrue(section.isConfigurationSection(key));
assertFalse(section.isConfigurationSection("doesntExist"));
}
public enum TestEnum {
HELLO,
WORLD,
BANANAS
}
}

Datei anzeigen

@ -0,0 +1,135 @@
package org.bukkit.configuration;
import java.util.LinkedHashMap;
import java.io.File;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import org.bukkit.util.Vector;
import org.junit.Test;
import static org.junit.Assert.*;
public abstract class ConfigurationTest {
public abstract Configuration getConfig();
public Map<String, Object> getTestValues() {
HashMap<String, Object> result = new LinkedHashMap<String, Object>();
result.put("integer", Integer.MIN_VALUE);
result.put("string", "String Value");
result.put("long", Long.MAX_VALUE);
result.put("true-boolean", true);
result.put("false-boolean", false);
result.put("vector", new Vector(12345.67, 64, -12345.6789));
result.put("list", Arrays.asList(1, 2, 3, 4, 5));
return result;
}
/**
* Test of addDefault method, of class Configuration.
*/
@Test
public void testAddDefault() {
Configuration config = getConfig();
Map<String, Object> values = getTestValues();
for (Map.Entry<String, Object> entry : values.entrySet()) {
String path = entry.getKey();
Object object = entry.getValue();
config.addDefault(path, object);
assertEquals(object, config.get(path));
assertTrue(config.contains(path));
assertFalse(config.isSet(path));
assertTrue(config.getDefaults().isSet(path));
}
}
/**
* Test of addDefaults method, of class Configuration.
*/
@Test
public void testAddDefaults_Map() {
Configuration config = getConfig();
Map<String, Object> values = getTestValues();
config.addDefaults(values);
for (Map.Entry<String, Object> entry : values.entrySet()) {
String path = entry.getKey();
Object object = entry.getValue();
assertEquals(object, config.get(path));
assertTrue(config.contains(path));
assertFalse(config.isSet(path));
assertTrue(config.getDefaults().isSet(path));
}
}
/**
* Test of addDefaults method, of class Configuration.
*/
@Test
public void testAddDefaults_Configuration() {
Configuration config = getConfig();
Map<String, Object> values = getTestValues();
Configuration defaults = getConfig();
for (Map.Entry<String, Object> entry : values.entrySet()) {
defaults.set(entry.getKey(), entry.getValue());
}
config.addDefaults(defaults);
for (Map.Entry<String, Object> entry : values.entrySet()) {
String path = entry.getKey();
Object object = entry.getValue();
assertEquals(object, config.get(path));
assertTrue(config.contains(path));
assertFalse(config.isSet(path));
assertTrue(config.getDefaults().isSet(path));
}
}
/**
* Test of setDefaults method, of class Configuration.
*/
@Test
public void testSetDefaults() {
Configuration config = getConfig();
Map<String, Object> values = getTestValues();
Configuration defaults = getConfig();
for (Map.Entry<String, Object> entry : values.entrySet()) {
defaults.set(entry.getKey(), entry.getValue());
}
config.setDefaults(defaults);
for (Map.Entry<String, Object> entry : values.entrySet()) {
String path = entry.getKey();
Object object = entry.getValue();
assertEquals(object, config.get(path));
assertTrue(config.contains(path));
assertFalse(config.isSet(path));
assertTrue(config.getDefaults().isSet(path));
}
}
/**
* Test of getDefaults method, of class Configuration.
*/
@Test
public void testGetDefaults() {
Configuration config = getConfig();
Configuration defaults = getConfig();
config.setDefaults(defaults);
assertEquals(defaults, config.getDefaults());
}
}

Datei anzeigen

@ -0,0 +1,8 @@
package org.bukkit.configuration;
public class MemoryConfigurationTest extends ConfigurationTest {
@Override
public Configuration getConfig() {
return new MemoryConfiguration();
}
}

Datei anzeigen

@ -0,0 +1,8 @@
package org.bukkit.configuration;
public class MemorySectionTest extends ConfigurationSectionTest {
@Override
public ConfigurationSection getConfigurationSection() {
return new MemoryConfiguration().createSection("section");
}
}

Datei anzeigen

@ -0,0 +1 @@
package org.bukkit.configuration;

Datei anzeigen

@ -0,0 +1,127 @@
package org.bukkit.configuration.file;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.util.Map;
import java.util.Scanner;
import org.bukkit.configuration.MemoryConfigurationTest;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import static org.junit.Assert.*;
public abstract class FileConfigurationTest extends MemoryConfigurationTest {
@Rule
public TemporaryFolder testFolder = new TemporaryFolder();
@Override
public abstract FileConfiguration getConfig();
public abstract String getTestValuesString();
@Test
public void testSave_File() throws Exception {
FileConfiguration config = getConfig();
File file = testFolder.newFile("test.config");
for (Map.Entry<String, Object> entry : getTestValues().entrySet()) {
config.set(entry.getKey(), entry.getValue());
}
config.save(file);
assertTrue(file.isFile());
}
@Test
public void testSave_String() throws Exception {
FileConfiguration config = getConfig();
File file = testFolder.newFile("test.config");
for (Map.Entry<String, Object> entry : getTestValues().entrySet()) {
config.set(entry.getKey(), entry.getValue());
}
config.save(file.getAbsolutePath());
assertTrue(file.isFile());
}
@Test
public void testSaveToString() {
FileConfiguration config = getConfig();
for (Map.Entry<String, Object> entry : getTestValues().entrySet()) {
config.set(entry.getKey(), entry.getValue());
}
String result = config.saveToString();
String expected = getTestValuesString();
assertEquals(expected, result);
}
@Test
public void testLoad_File() throws Exception {
FileConfiguration config = getConfig();
File file = testFolder.newFile("test.config");
BufferedWriter writer = new BufferedWriter(new FileWriter(file));
String saved = getTestValuesString();
Map<String, Object> values = getTestValues();
try {
writer.write(saved);
} finally {
writer.close();
}
config.load(file);
for (Map.Entry<String, Object> entry : values.entrySet()) {
assertEquals(entry.getValue(), config.get(entry.getKey()));
}
assertEquals(values.keySet(), config.getKeys(true));
}
@Test
public void testLoad_String() throws Exception {
FileConfiguration config = getConfig();
File file = testFolder.newFile("test.config");
BufferedWriter writer = new BufferedWriter(new FileWriter(file));
String saved = getTestValuesString();
Map<String, Object> values = getTestValues();
try {
writer.write(saved);
} finally {
writer.close();
}
config.load(file.getAbsolutePath());
for (Map.Entry<String, Object> entry : values.entrySet()) {
assertEquals(entry.getValue(), config.get(entry.getKey()));
}
assertEquals(values.keySet(), config.getKeys(true));
}
@Test
public void testLoadFromString() throws Exception {
FileConfiguration config = getConfig();
Map<String, Object> values = getTestValues();
String saved = getTestValuesString();
config.loadFromString(saved);
for (Map.Entry<String, Object> entry : values.entrySet()) {
assertEquals(entry.getValue(), config.get(entry.getKey()));
}
assertEquals(values.keySet(), config.getKeys(true));
}
}

Datei anzeigen

@ -0,0 +1,62 @@
package org.bukkit.configuration.file;
import java.util.Map;
import org.junit.Test;
import static org.junit.Assert.*;
public class YamlConfigurationTest extends FileConfigurationTest {
@Override
public YamlConfiguration getConfig() {
return new YamlConfiguration();
}
@Override
public String getTestValuesString() {
return "integer: -2147483648\n" +
"string: String Value\n" +
"long: 9223372036854775807\n" +
"true-boolean: true\n" +
"false-boolean: false\n" +
"vector:\n" +
" ==: Vector\n" +
" x: 12345.67\n" +
" y: 64.0\n" +
" z: -12345.6789\n" +
"list:\n" +
"- 1\n" +
"- 2\n" +
"- 3\n" +
"- 4\n" +
"- 5\n";
}
@Test
public void testSaveToStringWithheader() {
YamlConfiguration config = getConfig();
config.options().header("This is a sample\nheader.");
for (Map.Entry<String, Object> entry : getTestValues().entrySet()) {
config.set(entry.getKey(), entry.getValue());
}
String result = config.saveToString();
String expected = "# This is a sample\n# header.\n" + getTestValuesString();
assertEquals(expected, result);
}
@Test
public void testSaveToStringWithIndent() {
YamlConfiguration config = getConfig();
config.options().indent(9);
config.set("section.key", 1);
String result = config.saveToString();
String expected = "section:\n key: 1\n";
System.out.println(result);
assertEquals(expected, result);
}
}