mirror of
https://github.com/PaperMC/Paper.git
synced 2025-08-07 23:52:11 -07:00
Added new Configuration classes
By: Dinnerbone <dinnerbone@dinnerbone.com>
This commit is contained in:
@@ -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
|
||||
*
|
||||
|
@@ -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;
|
||||
}
|
||||
}
|
@@ -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>());
|
||||
|
||||
|
Reference in New Issue
Block a user