geforkt von Mirrors/Paper
Added new Configuration classes
By: Dinnerbone <dinnerbone@dinnerbone.com>
Dieser Commit ist enthalten in:
Ursprung
e99e39ee62
Commit
6c7412d365
@ -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>
|
||||
|
@ -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
|
||||
*
|
||||
|
82
paper-api/src/main/java/org/bukkit/configuration/Configuration.java
Normale Datei
82
paper-api/src/main/java/org/bukkit/configuration/Configuration.java
Normale Datei
@ -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();
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
667
paper-api/src/main/java/org/bukkit/configuration/MemorySection.java
Normale Datei
667
paper-api/src/main/java/org/bukkit/configuration/MemorySection.java
Normale Datei
@ -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();
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
@ -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();
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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>());
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
}
|
135
paper-api/src/test/java/org/bukkit/configuration/ConfigurationTest.java
Normale Datei
135
paper-api/src/test/java/org/bukkit/configuration/ConfigurationTest.java
Normale Datei
@ -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());
|
||||
}
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
package org.bukkit.configuration;
|
||||
|
||||
public class MemoryConfigurationTest extends ConfigurationTest {
|
||||
@Override
|
||||
public Configuration getConfig() {
|
||||
return new MemoryConfiguration();
|
||||
}
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
package org.bukkit.configuration;
|
||||
|
||||
public class MemorySectionTest extends ConfigurationSectionTest {
|
||||
@Override
|
||||
public ConfigurationSection getConfigurationSection() {
|
||||
return new MemoryConfiguration().createSection("section");
|
||||
}
|
||||
}
|
1
paper-api/src/test/java/org/bukkit/configuration/TestEnum.java
Normale Datei
1
paper-api/src/test/java/org/bukkit/configuration/TestEnum.java
Normale Datei
@ -0,0 +1 @@
|
||||
package org.bukkit.configuration;
|
@ -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));
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren