mirror of
https://github.com/IntellectualSites/PlotSquared.git
synced 2024-11-29 16:46:45 +01:00
configuration stuff
This commit is contained in:
parent
c659ec075f
commit
ac85eb6db8
@ -0,0 +1,84 @@
|
|||||||
|
package com.intellectualcrafters.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(com.intellectualcrafters.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,90 @@
|
|||||||
|
package com.intellectualcrafters.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,642 @@
|
|||||||
|
package com.intellectualcrafters.configuration;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
* @param def The default value to return if the path is not found.
|
||||||
|
* @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);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a {@link ConfigurationSection} at the specified path, with
|
||||||
|
* specified values.
|
||||||
|
* <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.
|
||||||
|
* @param map The values to used.
|
||||||
|
* @return Newly created section
|
||||||
|
*/
|
||||||
|
public ConfigurationSection createSection(String path, Map<?, ?> map);
|
||||||
|
|
||||||
|
// 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.
|
||||||
|
* @param def The default value to return if the path is not found or is
|
||||||
|
* not a String.
|
||||||
|
* @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 0.
|
||||||
|
*
|
||||||
|
* @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.
|
||||||
|
* @param def The default value to return if the path is not found or is
|
||||||
|
* not an int.
|
||||||
|
* @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.
|
||||||
|
* @param def The default value to return if the path is not found or is
|
||||||
|
* not a boolean.
|
||||||
|
* @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 0.
|
||||||
|
*
|
||||||
|
* @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.
|
||||||
|
* @param def The default value to return if the path is not found or is
|
||||||
|
* not a double.
|
||||||
|
* @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 0.
|
||||||
|
*
|
||||||
|
* @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.
|
||||||
|
* @param def The default value to return if the path is not found or is
|
||||||
|
* not a long.
|
||||||
|
* @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.
|
||||||
|
* @param def The default value to return if the path is not found or is
|
||||||
|
* not a List.
|
||||||
|
* @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);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the requested List of String 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 an empty List.
|
||||||
|
* <p>
|
||||||
|
* This method will attempt to cast any values into a String if possible,
|
||||||
|
* but may miss any values out if they are not compatible.
|
||||||
|
*
|
||||||
|
* @param path Path of the List to get.
|
||||||
|
* @return Requested List of String.
|
||||||
|
*/
|
||||||
|
public List<String> getStringList(String path);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the requested List of Integer 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 an empty List.
|
||||||
|
* <p>
|
||||||
|
* This method will attempt to cast any values into a Integer if possible,
|
||||||
|
* but may miss any values out if they are not compatible.
|
||||||
|
*
|
||||||
|
* @param path Path of the List to get.
|
||||||
|
* @return Requested List of Integer.
|
||||||
|
*/
|
||||||
|
public List<Integer> getIntegerList(String path);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the requested List of Boolean 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 an empty List.
|
||||||
|
* <p>
|
||||||
|
* This method will attempt to cast any values into a Boolean if possible,
|
||||||
|
* but may miss any values out if they are not compatible.
|
||||||
|
*
|
||||||
|
* @param path Path of the List to get.
|
||||||
|
* @return Requested List of Boolean.
|
||||||
|
*/
|
||||||
|
public List<Boolean> getBooleanList(String path);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the requested List of Double 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 an empty List.
|
||||||
|
* <p>
|
||||||
|
* This method will attempt to cast any values into a Double if possible,
|
||||||
|
* but may miss any values out if they are not compatible.
|
||||||
|
*
|
||||||
|
* @param path Path of the List to get.
|
||||||
|
* @return Requested List of Double.
|
||||||
|
*/
|
||||||
|
public List<Double> getDoubleList(String path);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the requested List of Float 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 an empty List.
|
||||||
|
* <p>
|
||||||
|
* This method will attempt to cast any values into a Float if possible,
|
||||||
|
* but may miss any values out if they are not compatible.
|
||||||
|
*
|
||||||
|
* @param path Path of the List to get.
|
||||||
|
* @return Requested List of Float.
|
||||||
|
*/
|
||||||
|
public List<Float> getFloatList(String path);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the requested List of Long 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 an empty List.
|
||||||
|
* <p>
|
||||||
|
* This method will attempt to cast any values into a Long if possible,
|
||||||
|
* but may miss any values out if they are not compatible.
|
||||||
|
*
|
||||||
|
* @param path Path of the List to get.
|
||||||
|
* @return Requested List of Long.
|
||||||
|
*/
|
||||||
|
public List<Long> getLongList(String path);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the requested List of Byte 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 an empty List.
|
||||||
|
* <p>
|
||||||
|
* This method will attempt to cast any values into a Byte if possible,
|
||||||
|
* but may miss any values out if they are not compatible.
|
||||||
|
*
|
||||||
|
* @param path Path of the List to get.
|
||||||
|
* @return Requested List of Byte.
|
||||||
|
*/
|
||||||
|
public List<Byte> getByteList(String path);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the requested List of Character 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 an empty List.
|
||||||
|
* <p>
|
||||||
|
* This method will attempt to cast any values into a Character if
|
||||||
|
* possible, but may miss any values out if they are not compatible.
|
||||||
|
*
|
||||||
|
* @param path Path of the List to get.
|
||||||
|
* @return Requested List of Character.
|
||||||
|
*/
|
||||||
|
public List<Character> getCharacterList(String path);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the requested List of Short 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 an empty List.
|
||||||
|
* <p>
|
||||||
|
* This method will attempt to cast any values into a Short if possible,
|
||||||
|
* but may miss any values out if they are not compatible.
|
||||||
|
*
|
||||||
|
* @param path Path of the List to get.
|
||||||
|
* @return Requested List of Short.
|
||||||
|
*/
|
||||||
|
public List<Short> getShortList(String path);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the requested List of Maps 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 an empty List.
|
||||||
|
* <p>
|
||||||
|
* This method will attempt to cast any values into a Map if possible, but
|
||||||
|
* may miss any values out if they are not compatible.
|
||||||
|
*
|
||||||
|
* @param path Path of the List to get.
|
||||||
|
* @return Requested List of Maps.
|
||||||
|
*/
|
||||||
|
public List<Map<?, ?>> getMapList(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,45 @@
|
|||||||
|
package com.intellectualcrafters.configuration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Exception thrown when attempting to load an invalid {@link Configuration}
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("serial")
|
||||||
|
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,76 @@
|
|||||||
|
package com.intellectualcrafters.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 NullPointerException("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 NullPointerException("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 NullPointerException("Defaults may not be null");
|
||||||
|
|
||||||
|
addDefaults(defaults.getValues(true));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDefaults(Configuration defaults) {
|
||||||
|
if (defaults == null) throw new NullPointerException("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,28 @@
|
|||||||
|
package com.intellectualcrafters.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,753 @@
|
|||||||
|
package com.intellectualcrafters.configuration;
|
||||||
|
|
||||||
|
import static org.bukkit.util.NumberConversions.*;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.LinkedHashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 construct 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 NullPointerException("Parent may not be null");
|
||||||
|
if (path == null) throw new NullPointerException("Path may not be null");
|
||||||
|
|
||||||
|
this.path = path;
|
||||||
|
this.parent = parent;
|
||||||
|
this.root = parent.getRoot();
|
||||||
|
|
||||||
|
if (root == null) throw new NullPointerException("Path may not be orphaned");
|
||||||
|
|
||||||
|
this.fullPath = createPath(parent, path);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<String> getKeys(boolean deep) {
|
||||||
|
Set<String> result = new LinkedHashSet<String>();
|
||||||
|
|
||||||
|
Configuration root = getRoot();
|
||||||
|
if (root != null && root.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>();
|
||||||
|
|
||||||
|
Configuration root = getRoot();
|
||||||
|
if (root != null && root.options().copyDefaults()) {
|
||||||
|
ConfigurationSection defaults = getDefaultSection();
|
||||||
|
|
||||||
|
if (defaults != null) {
|
||||||
|
result.putAll(defaults.getValues(deep));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mapChildrenValues(result, this, deep);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean contains(String path) {
|
||||||
|
return get(path) != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isSet(String path) {
|
||||||
|
Configuration root = getRoot();
|
||||||
|
if (root == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (root.options().copyDefaults()) {
|
||||||
|
return contains(path);
|
||||||
|
}
|
||||||
|
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 NullPointerException("Path cannot be null");
|
||||||
|
|
||||||
|
Configuration root = getRoot();
|
||||||
|
if (root == null) {
|
||||||
|
throw new IllegalStateException("Cannot add default without root");
|
||||||
|
}
|
||||||
|
if (root == this) {
|
||||||
|
throw new UnsupportedOperationException("Unsupported addDefault(String, Object) implementation");
|
||||||
|
}
|
||||||
|
root.addDefault(createPath(this, path), value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ConfigurationSection getDefaultSection() {
|
||||||
|
Configuration root = getRoot();
|
||||||
|
Configuration defaults = root == null ? null : root.getDefaults();
|
||||||
|
|
||||||
|
if (defaults != null) {
|
||||||
|
if (defaults.isConfigurationSection(getCurrentPath())) {
|
||||||
|
return defaults.getConfigurationSection(getCurrentPath());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void set(String path, Object value) {
|
||||||
|
if (path == null) throw new NullPointerException("Cannot set to an empty path");
|
||||||
|
|
||||||
|
Configuration root = getRoot();
|
||||||
|
if (root == null) {
|
||||||
|
throw new IllegalStateException("Cannot use section without a root");
|
||||||
|
}
|
||||||
|
|
||||||
|
final char separator = root.options().pathSeparator();
|
||||||
|
// i1 is the leading (higher) index
|
||||||
|
// i2 is the trailing (lower) index
|
||||||
|
int i1 = -1, i2;
|
||||||
|
ConfigurationSection section = this;
|
||||||
|
while ((i1 = path.indexOf(separator, i2 = i1 + 1)) != -1) {
|
||||||
|
String node = path.substring(i2, i1);
|
||||||
|
ConfigurationSection subSection = section.getConfigurationSection(node);
|
||||||
|
if (subSection == null) {
|
||||||
|
section = section.createSection(node);
|
||||||
|
} else {
|
||||||
|
section = subSection;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String key = path.substring(i2);
|
||||||
|
if (section == this) {
|
||||||
|
if (value == null) {
|
||||||
|
map.remove(key);
|
||||||
|
} else {
|
||||||
|
map.put(key, value);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
section.set(key, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object get(String path) {
|
||||||
|
return get(path, getDefault(path));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object get(String path, Object def) {
|
||||||
|
if (path == null) throw new NullPointerException("Path cannot be null");
|
||||||
|
|
||||||
|
if (path.length() == 0) {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Configuration root = getRoot();
|
||||||
|
if (root == null) {
|
||||||
|
throw new IllegalStateException("Cannot access section without a root");
|
||||||
|
}
|
||||||
|
|
||||||
|
final char separator = root.options().pathSeparator();
|
||||||
|
// i1 is the leading (higher) index
|
||||||
|
// i2 is the trailing (lower) index
|
||||||
|
int i1 = -1, i2;
|
||||||
|
ConfigurationSection section = this;
|
||||||
|
while ((i1 = path.indexOf(separator, i2 = i1 + 1)) != -1) {
|
||||||
|
section = section.getConfigurationSection(path.substring(i2, i1));
|
||||||
|
if (section == null) {
|
||||||
|
return def;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String key = path.substring(i2);
|
||||||
|
if (section == this) {
|
||||||
|
Object result = map.get(key);
|
||||||
|
return (result == null) ? def : result;
|
||||||
|
}
|
||||||
|
return section.get(key, def);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ConfigurationSection createSection(String path) {
|
||||||
|
if (path == null) throw new NullPointerException("Cannot create section at empty path");
|
||||||
|
Configuration root = getRoot();
|
||||||
|
if (root == null) {
|
||||||
|
throw new IllegalStateException("Cannot create section without a root");
|
||||||
|
}
|
||||||
|
|
||||||
|
final char separator = root.options().pathSeparator();
|
||||||
|
// i1 is the leading (higher) index
|
||||||
|
// i2 is the trailing (lower) index
|
||||||
|
int i1 = -1, i2;
|
||||||
|
ConfigurationSection section = this;
|
||||||
|
while ((i1 = path.indexOf(separator, i2 = i1 + 1)) != -1) {
|
||||||
|
String node = path.substring(i2, i1);
|
||||||
|
ConfigurationSection subSection = section.getConfigurationSection(node);
|
||||||
|
if (subSection == null) {
|
||||||
|
section = section.createSection(node);
|
||||||
|
} else {
|
||||||
|
section = subSection;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String key = path.substring(i2);
|
||||||
|
if (section == this) {
|
||||||
|
ConfigurationSection result = new MemorySection(this, key);
|
||||||
|
map.put(key, result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
return section.createSection(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ConfigurationSection createSection(String path, Map<?, ?> map) {
|
||||||
|
ConfigurationSection section = createSection(path);
|
||||||
|
|
||||||
|
for (Map.Entry<?, ?> entry : map.entrySet()) {
|
||||||
|
if (entry.getValue() instanceof Map) {
|
||||||
|
section.createSection(entry.getKey().toString(), (Map<?, ?>) entry.getValue());
|
||||||
|
} else {
|
||||||
|
section.set(entry.getKey().toString(), entry.getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return section;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Primitives
|
||||||
|
public String getString(String path) {
|
||||||
|
Object def = getDefault(path);
|
||||||
|
return getString(path, def != null ? def.toString() : null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getString(String path, String def) {
|
||||||
|
Object val = get(path, def);
|
||||||
|
return (val != null) ? val.toString() : def;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isString(String path) {
|
||||||
|
Object val = get(path);
|
||||||
|
return val instanceof String;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getInt(String path) {
|
||||||
|
Object def = getDefault(path);
|
||||||
|
return getInt(path, (def instanceof Number) ? toInt(def) : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getInt(String path, int def) {
|
||||||
|
Object val = get(path, def);
|
||||||
|
return (val instanceof Number) ? toInt(val) : def;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isInt(String path) {
|
||||||
|
Object val = get(path);
|
||||||
|
return val instanceof Integer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean getBoolean(String path) {
|
||||||
|
Object def = getDefault(path);
|
||||||
|
return getBoolean(path, (def instanceof Boolean) ? (Boolean) def : false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean getBoolean(String path, boolean def) {
|
||||||
|
Object val = get(path, def);
|
||||||
|
return (val instanceof Boolean) ? (Boolean) val : def;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isBoolean(String path) {
|
||||||
|
Object val = get(path);
|
||||||
|
return val instanceof Boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getDouble(String path) {
|
||||||
|
Object def = getDefault(path);
|
||||||
|
return getDouble(path, (def instanceof Number) ? toDouble(def) : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getDouble(String path, double def) {
|
||||||
|
Object val = get(path, def);
|
||||||
|
return (val instanceof Number) ? toDouble(val) : def;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isDouble(String path) {
|
||||||
|
Object val = get(path);
|
||||||
|
return val instanceof Double;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getLong(String path) {
|
||||||
|
Object def = getDefault(path);
|
||||||
|
return getLong(path, (def instanceof Number) ? toLong(def) : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getLong(String path, long def) {
|
||||||
|
Object val = get(path, def);
|
||||||
|
return (val instanceof Number) ? toLong(val) : def;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isLong(String path) {
|
||||||
|
Object val = get(path);
|
||||||
|
return val instanceof Long;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Java
|
||||||
|
public List<?> getList(String path) {
|
||||||
|
Object def = getDefault(path);
|
||||||
|
return getList(path, (def instanceof List) ? (List<?>) def : null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<?> getList(String path, List<?> def) {
|
||||||
|
Object val = get(path, def);
|
||||||
|
return (List<?>) ((val instanceof List) ? val : def);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isList(String path) {
|
||||||
|
Object val = get(path);
|
||||||
|
return val instanceof List;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getStringList(String path) {
|
||||||
|
List<?> list = getList(path);
|
||||||
|
|
||||||
|
if (list == null) {
|
||||||
|
return new ArrayList<String>(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<String> result = new ArrayList<String>();
|
||||||
|
|
||||||
|
for (Object object : list) {
|
||||||
|
if ((object instanceof String) || (isPrimitiveWrapper(object))) {
|
||||||
|
result.add(String.valueOf(object));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Integer> getIntegerList(String path) {
|
||||||
|
List<?> list = getList(path);
|
||||||
|
|
||||||
|
if (list == null) {
|
||||||
|
return new ArrayList<Integer>(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Integer> result = new ArrayList<Integer>();
|
||||||
|
|
||||||
|
for (Object object : list) {
|
||||||
|
if (object instanceof Integer) {
|
||||||
|
result.add((Integer) object);
|
||||||
|
} else if (object instanceof String) {
|
||||||
|
try {
|
||||||
|
result.add(Integer.valueOf((String) object));
|
||||||
|
} catch (Exception ex) {
|
||||||
|
}
|
||||||
|
} else if (object instanceof Character) {
|
||||||
|
result.add((int) ((Character) object).charValue());
|
||||||
|
} else if (object instanceof Number) {
|
||||||
|
result.add(((Number) object).intValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Boolean> getBooleanList(String path) {
|
||||||
|
List<?> list = getList(path);
|
||||||
|
|
||||||
|
if (list == null) {
|
||||||
|
return new ArrayList<Boolean>(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Boolean> result = new ArrayList<Boolean>();
|
||||||
|
|
||||||
|
for (Object object : list) {
|
||||||
|
if (object instanceof Boolean) {
|
||||||
|
result.add((Boolean) object);
|
||||||
|
} else if (object instanceof String) {
|
||||||
|
if (Boolean.TRUE.toString().equals(object)) {
|
||||||
|
result.add(true);
|
||||||
|
} else if (Boolean.FALSE.toString().equals(object)) {
|
||||||
|
result.add(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Double> getDoubleList(String path) {
|
||||||
|
List<?> list = getList(path);
|
||||||
|
|
||||||
|
if (list == null) {
|
||||||
|
return new ArrayList<Double>(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Double> result = new ArrayList<Double>();
|
||||||
|
|
||||||
|
for (Object object : list) {
|
||||||
|
if (object instanceof Double) {
|
||||||
|
result.add((Double) object);
|
||||||
|
} else if (object instanceof String) {
|
||||||
|
try {
|
||||||
|
result.add(Double.valueOf((String) object));
|
||||||
|
} catch (Exception ex) {
|
||||||
|
}
|
||||||
|
} else if (object instanceof Character) {
|
||||||
|
result.add((double) ((Character) object).charValue());
|
||||||
|
} else if (object instanceof Number) {
|
||||||
|
result.add(((Number) object).doubleValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Float> getFloatList(String path) {
|
||||||
|
List<?> list = getList(path);
|
||||||
|
|
||||||
|
if (list == null) {
|
||||||
|
return new ArrayList<Float>(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Float> result = new ArrayList<Float>();
|
||||||
|
|
||||||
|
for (Object object : list) {
|
||||||
|
if (object instanceof Float) {
|
||||||
|
result.add((Float) object);
|
||||||
|
} else if (object instanceof String) {
|
||||||
|
try {
|
||||||
|
result.add(Float.valueOf((String) object));
|
||||||
|
} catch (Exception ex) {
|
||||||
|
}
|
||||||
|
} else if (object instanceof Character) {
|
||||||
|
result.add((float) ((Character) object).charValue());
|
||||||
|
} else if (object instanceof Number) {
|
||||||
|
result.add(((Number) object).floatValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Long> getLongList(String path) {
|
||||||
|
List<?> list = getList(path);
|
||||||
|
|
||||||
|
if (list == null) {
|
||||||
|
return new ArrayList<Long>(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Long> result = new ArrayList<Long>();
|
||||||
|
|
||||||
|
for (Object object : list) {
|
||||||
|
if (object instanceof Long) {
|
||||||
|
result.add((Long) object);
|
||||||
|
} else if (object instanceof String) {
|
||||||
|
try {
|
||||||
|
result.add(Long.valueOf((String) object));
|
||||||
|
} catch (Exception ex) {
|
||||||
|
}
|
||||||
|
} else if (object instanceof Character) {
|
||||||
|
result.add((long) ((Character) object).charValue());
|
||||||
|
} else if (object instanceof Number) {
|
||||||
|
result.add(((Number) object).longValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Byte> getByteList(String path) {
|
||||||
|
List<?> list = getList(path);
|
||||||
|
|
||||||
|
if (list == null) {
|
||||||
|
return new ArrayList<Byte>(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Byte> result = new ArrayList<Byte>();
|
||||||
|
|
||||||
|
for (Object object : list) {
|
||||||
|
if (object instanceof Byte) {
|
||||||
|
result.add((Byte) object);
|
||||||
|
} else if (object instanceof String) {
|
||||||
|
try {
|
||||||
|
result.add(Byte.valueOf((String) object));
|
||||||
|
} catch (Exception ex) {
|
||||||
|
}
|
||||||
|
} else if (object instanceof Character) {
|
||||||
|
result.add((byte) ((Character) object).charValue());
|
||||||
|
} else if (object instanceof Number) {
|
||||||
|
result.add(((Number) object).byteValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Character> getCharacterList(String path) {
|
||||||
|
List<?> list = getList(path);
|
||||||
|
|
||||||
|
if (list == null) {
|
||||||
|
return new ArrayList<Character>(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Character> result = new ArrayList<Character>();
|
||||||
|
|
||||||
|
for (Object object : list) {
|
||||||
|
if (object instanceof Character) {
|
||||||
|
result.add((Character) object);
|
||||||
|
} else if (object instanceof String) {
|
||||||
|
String str = (String) object;
|
||||||
|
|
||||||
|
if (str.length() == 1) {
|
||||||
|
result.add(str.charAt(0));
|
||||||
|
}
|
||||||
|
} else if (object instanceof Number) {
|
||||||
|
result.add((char) ((Number) object).intValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Short> getShortList(String path) {
|
||||||
|
List<?> list = getList(path);
|
||||||
|
|
||||||
|
if (list == null) {
|
||||||
|
return new ArrayList<Short>(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Short> result = new ArrayList<Short>();
|
||||||
|
|
||||||
|
for (Object object : list) {
|
||||||
|
if (object instanceof Short) {
|
||||||
|
result.add((Short) object);
|
||||||
|
} else if (object instanceof String) {
|
||||||
|
try {
|
||||||
|
result.add(Short.valueOf((String) object));
|
||||||
|
} catch (Exception ex) {
|
||||||
|
}
|
||||||
|
} else if (object instanceof Character) {
|
||||||
|
result.add((short) ((Character) object).charValue());
|
||||||
|
} else if (object instanceof Number) {
|
||||||
|
result.add(((Number) object).shortValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Map<?, ?>> getMapList(String path) {
|
||||||
|
List<?> list = getList(path);
|
||||||
|
List<Map<?, ?>> result = new ArrayList<Map<?, ?>>();
|
||||||
|
|
||||||
|
if (list == null) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Object object : list) {
|
||||||
|
if (object instanceof Map) {
|
||||||
|
result.add((Map<?, ?>) object);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ConfigurationSection getConfigurationSection(String path) {
|
||||||
|
Object val = get(path, null);
|
||||||
|
if (val != null) {
|
||||||
|
return (val instanceof ConfigurationSection) ? (ConfigurationSection) val : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
val = get(path, getDefault(path));
|
||||||
|
return (val instanceof ConfigurationSection) ? createSection(path) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isConfigurationSection(String path) {
|
||||||
|
Object val = get(path);
|
||||||
|
return val instanceof ConfigurationSection;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 Object getDefault(String path) {
|
||||||
|
if (path == null) throw new NullPointerException("Path may not be null");
|
||||||
|
|
||||||
|
Configuration root = getRoot();
|
||||||
|
Configuration defaults = root == null ? null : 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) {
|
||||||
|
if (section == null) throw new NullPointerException("Cannot create path without a section");
|
||||||
|
Configuration root = section.getRoot();
|
||||||
|
if (root == null) {
|
||||||
|
throw new IllegalStateException("Cannot create path without a root");
|
||||||
|
}
|
||||||
|
char separator = root.options().pathSeparator();
|
||||||
|
|
||||||
|
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, separator);
|
||||||
|
}
|
||||||
|
|
||||||
|
builder.insert(0, parent.getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((key != null) && (key.length() > 0)) {
|
||||||
|
if (builder.length() > 0) {
|
||||||
|
builder.append(separator);
|
||||||
|
}
|
||||||
|
|
||||||
|
builder.append(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
return builder.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
Configuration root = getRoot();
|
||||||
|
return new StringBuilder()
|
||||||
|
.append(getClass().getSimpleName())
|
||||||
|
.append("[path='")
|
||||||
|
.append(getCurrentPath())
|
||||||
|
.append("', root='")
|
||||||
|
.append(root == null ? null : root.getClass().getSimpleName())
|
||||||
|
.append("']")
|
||||||
|
.toString();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,287 @@
|
|||||||
|
package com.intellectualcrafters.configuration.file;
|
||||||
|
|
||||||
|
import com.intellectualcrafters.configuration.InvalidConfigurationException;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.io.OutputStreamWriter;
|
||||||
|
import java.io.Reader;
|
||||||
|
import java.io.Writer;
|
||||||
|
import java.nio.charset.Charset;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
|
||||||
|
import com.intellectualcrafters.configuration.Configuration;
|
||||||
|
import com.intellectualcrafters.configuration.MemoryConfiguration;
|
||||||
|
|
||||||
|
import org.yaml.snakeyaml.external.biz.base64Coder.Base64Coder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is a base class for all File based implementations of {@link
|
||||||
|
* Configuration}
|
||||||
|
*/
|
||||||
|
public abstract class FileConfiguration extends MemoryConfiguration {
|
||||||
|
/**
|
||||||
|
* This value specified that the system default encoding should be
|
||||||
|
* completely ignored, as it cannot handle the ASCII character set, or it
|
||||||
|
* is a strict-subset of UTF8 already (plain ASCII).
|
||||||
|
*
|
||||||
|
* @deprecated temporary compatibility measure
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
public static final boolean UTF8_OVERRIDE;
|
||||||
|
/**
|
||||||
|
* This value specifies if the system default encoding is unicode, but
|
||||||
|
* cannot parse standard ASCII.
|
||||||
|
*
|
||||||
|
* @deprecated temporary compatibility measure
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
public static final boolean UTF_BIG;
|
||||||
|
/**
|
||||||
|
* This value specifies if the system supports unicode.
|
||||||
|
*
|
||||||
|
* @deprecated temporary compatibility measure
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
public static final boolean SYSTEM_UTF;
|
||||||
|
static {
|
||||||
|
final byte[] testBytes = Base64Coder.decode("ICEiIyQlJicoKSorLC0uLzAxMjM0NTY3ODk6Ozw9Pj9AQUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVpbXF1eX2BhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ent8fX4NCg==");
|
||||||
|
final String testString = " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\r\n";
|
||||||
|
final Charset defaultCharset = Charset.defaultCharset();
|
||||||
|
final String resultString = new String(testBytes, defaultCharset);
|
||||||
|
final boolean trueUTF = defaultCharset.name().contains("UTF");
|
||||||
|
UTF8_OVERRIDE = !testString.equals(resultString) || defaultCharset.equals(Charset.forName("US-ASCII"));
|
||||||
|
SYSTEM_UTF = trueUTF || UTF8_OVERRIDE;
|
||||||
|
UTF_BIG = trueUTF && UTF8_OVERRIDE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
* <p>
|
||||||
|
* This method will save using the system default encoding, or possibly
|
||||||
|
* using UTF8.
|
||||||
|
*
|
||||||
|
* @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 NullPointerException("File cannot be null");
|
||||||
|
file.getParentFile().mkdirs();
|
||||||
|
|
||||||
|
String data = saveToString();
|
||||||
|
|
||||||
|
Writer writer = new OutputStreamWriter(new FileOutputStream(file), UTF8_OVERRIDE && !UTF_BIG ? StandardCharsets.UTF_8 : Charset.defaultCharset());
|
||||||
|
|
||||||
|
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.
|
||||||
|
* <p>
|
||||||
|
* This method will save using the system default encoding, or possibly
|
||||||
|
* using UTF8.
|
||||||
|
*
|
||||||
|
* @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 NullPointerException("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.
|
||||||
|
* <p>
|
||||||
|
* This will attempt to use the {@link Charset#defaultCharset()} for
|
||||||
|
* files, unless {@link #UTF8_OVERRIDE} but not {@link #UTF_BIG} is
|
||||||
|
* specified.
|
||||||
|
*
|
||||||
|
* @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 NullPointerException("File cannot be null");
|
||||||
|
|
||||||
|
final FileInputStream stream = new FileInputStream(file);
|
||||||
|
|
||||||
|
load(new InputStreamReader(stream, UTF8_OVERRIDE && !UTF_BIG ? StandardCharsets.UTF_8 : Charset.defaultCharset()));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
* <p>
|
||||||
|
* This will attempt to use the {@link Charset#defaultCharset()}, unless
|
||||||
|
* {@link #UTF8_OVERRIDE} or {@link #UTF_BIG} is specified.
|
||||||
|
*
|
||||||
|
* @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.
|
||||||
|
* @deprecated This does not consider encoding
|
||||||
|
* @see #load(Reader)
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
public void load(InputStream stream) throws IOException, InvalidConfigurationException {
|
||||||
|
if (stream == null) throw new NullPointerException("Stream cannot be null");
|
||||||
|
|
||||||
|
load(new InputStreamReader(stream, UTF8_OVERRIDE ? StandardCharsets.UTF_8 : Charset.defaultCharset()));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads this {@link FileConfiguration} from the specified reader.
|
||||||
|
* <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 reader the reader to load from
|
||||||
|
* @throws IOException thrown when underlying reader throws an IOException
|
||||||
|
* @throws InvalidConfigurationException thrown when the reader does not
|
||||||
|
* represent a valid Configuration
|
||||||
|
* @throws IllegalArgumentException thrown when reader is null
|
||||||
|
*/
|
||||||
|
public void load(Reader reader) throws IOException, InvalidConfigurationException {
|
||||||
|
BufferedReader input = reader instanceof BufferedReader ? (BufferedReader) reader : new BufferedReader(reader);
|
||||||
|
|
||||||
|
StringBuilder builder = new StringBuilder();
|
||||||
|
|
||||||
|
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 NullPointerException("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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compiles the header for this {@link FileConfiguration} and returns the
|
||||||
|
* result.
|
||||||
|
* <p>
|
||||||
|
* This will use the header from {@link #options()} -> {@link
|
||||||
|
* FileConfigurationOptions#header()}, respecting the rules of {@link
|
||||||
|
* FileConfigurationOptions#copyHeader()} if set.
|
||||||
|
*
|
||||||
|
* @return Compiled header
|
||||||
|
*/
|
||||||
|
protected abstract String buildHeader();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FileConfigurationOptions options() {
|
||||||
|
if (options == null) {
|
||||||
|
options = new FileConfigurationOptions(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (FileConfigurationOptions) options;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,118 @@
|
|||||||
|
package com.intellectualcrafters.configuration.file;
|
||||||
|
|
||||||
|
import com.intellectualcrafters.configuration.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Various settings for controlling the input and output of a {@link
|
||||||
|
* FileConfiguration}
|
||||||
|
*/
|
||||||
|
public class FileConfigurationOptions extends MemoryConfigurationOptions {
|
||||||
|
private String header = null;
|
||||||
|
private boolean copyHeader = true;
|
||||||
|
|
||||||
|
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.
|
||||||
|
*
|
||||||
|
* @param value New header
|
||||||
|
* @return This object, for chaining
|
||||||
|
*/
|
||||||
|
public FileConfigurationOptions header(String value) {
|
||||||
|
this.header = value;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets whether or not the header should be copied from a default source.
|
||||||
|
* <p>
|
||||||
|
* If this is true, if a default {@link FileConfiguration} is passed to
|
||||||
|
* {@link
|
||||||
|
* FileConfiguration#setDefaults(com.intellectualcrafters.configuration.Configuration)}
|
||||||
|
* then upon saving it will use the header from that config, instead of
|
||||||
|
* the one provided here.
|
||||||
|
* <p>
|
||||||
|
* If no default is set on the configuration, or the default is not of
|
||||||
|
* type FileConfiguration, or that config has no header ({@link #header()}
|
||||||
|
* returns null) then the header specified in this configuration will be
|
||||||
|
* used.
|
||||||
|
* <p>
|
||||||
|
* Defaults to true.
|
||||||
|
*
|
||||||
|
* @return Whether or not to copy the header
|
||||||
|
*/
|
||||||
|
public boolean copyHeader() {
|
||||||
|
return copyHeader;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets whether or not the header should be copied from a default source.
|
||||||
|
* <p>
|
||||||
|
* If this is true, if a default {@link FileConfiguration} is passed to
|
||||||
|
* {@link
|
||||||
|
* FileConfiguration#setDefaults(com.intellectualcrafters.configuration.Configuration)}
|
||||||
|
* then upon saving it will use the header from that config, instead of
|
||||||
|
* the one provided here.
|
||||||
|
* <p>
|
||||||
|
* If no default is set on the configuration, or the default is not of
|
||||||
|
* type FileConfiguration, or that config has no header ({@link #header()}
|
||||||
|
* returns null) then the header specified in this configuration will be
|
||||||
|
* used.
|
||||||
|
* <p>
|
||||||
|
* Defaults to true.
|
||||||
|
*
|
||||||
|
* @param value Whether or not to copy the header
|
||||||
|
* @return This object, for chaining
|
||||||
|
*/
|
||||||
|
public FileConfigurationOptions copyHeader(boolean value) {
|
||||||
|
copyHeader = value;
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,254 @@
|
|||||||
|
package com.intellectualcrafters.configuration.file;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.Reader;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import com.intellectualcrafters.configuration.Configuration;
|
||||||
|
import com.intellectualcrafters.configuration.ConfigurationSection;
|
||||||
|
import com.intellectualcrafters.configuration.InvalidConfigurationException;
|
||||||
|
import com.intellectualcrafters.plot.PS;
|
||||||
|
|
||||||
|
import org.yaml.snakeyaml.DumperOptions;
|
||||||
|
import org.yaml.snakeyaml.Yaml;
|
||||||
|
import org.yaml.snakeyaml.error.YAMLException;
|
||||||
|
import org.yaml.snakeyaml.representer.Representer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An implementation of {@link Configuration} which saves all files in Yaml.
|
||||||
|
* Note that this implementation is not synchronized.
|
||||||
|
*/
|
||||||
|
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 YamlRepresenter();
|
||||||
|
private final Yaml yaml = new Yaml(new YamlConstructor(), yamlRepresenter, yamlOptions);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String saveToString() {
|
||||||
|
yamlOptions.setIndent(options().indent());
|
||||||
|
yamlOptions.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
|
||||||
|
yamlOptions.setAllowUnicode(SYSTEM_UTF);
|
||||||
|
yamlRepresenter.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
|
||||||
|
|
||||||
|
String header = buildHeader();
|
||||||
|
String dump = yaml.dump(getValues(false));
|
||||||
|
|
||||||
|
if (dump.equals(BLANK_CONFIG)) {
|
||||||
|
dump = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
return header + dump;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void loadFromString(String contents) throws InvalidConfigurationException {
|
||||||
|
if (contents == null) throw new NullPointerException("Contents cannot be null");
|
||||||
|
|
||||||
|
Map<?, ?> input;
|
||||||
|
try {
|
||||||
|
input = (Map<?, ?>) yaml.load(contents);
|
||||||
|
} catch (YAMLException e) {
|
||||||
|
throw new InvalidConfigurationException(e);
|
||||||
|
} catch (ClassCastException e) {
|
||||||
|
throw new InvalidConfigurationException("Top level is not a Map.");
|
||||||
|
}
|
||||||
|
|
||||||
|
String header = parseHeader(contents);
|
||||||
|
if (header.length() > 0) {
|
||||||
|
options().header(header);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (input != null) {
|
||||||
|
convertMapsToSections(input, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void convertMapsToSections(Map<?, ?> input, ConfigurationSection section) {
|
||||||
|
for (Map.Entry<?, ?> entry : input.entrySet()) {
|
||||||
|
String key = entry.getKey().toString();
|
||||||
|
Object value = entry.getValue();
|
||||||
|
|
||||||
|
if (value instanceof Map) {
|
||||||
|
convertMapsToSections((Map<?, ?>) value, section.createSection(key));
|
||||||
|
} else {
|
||||||
|
section.set(key, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected String parseHeader(String input) {
|
||||||
|
String[] lines = input.split("\r?\n", -1);
|
||||||
|
StringBuilder result = new StringBuilder();
|
||||||
|
boolean readingHeader = true;
|
||||||
|
boolean foundHeader = false;
|
||||||
|
|
||||||
|
for (int i = 0; (i < lines.length) && (readingHeader); i++) {
|
||||||
|
String line = lines[i];
|
||||||
|
|
||||||
|
if (line.startsWith(COMMENT_PREFIX)) {
|
||||||
|
if (i > 0) {
|
||||||
|
result.append("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (line.length() > COMMENT_PREFIX.length()) {
|
||||||
|
result.append(line.substring(COMMENT_PREFIX.length()));
|
||||||
|
}
|
||||||
|
|
||||||
|
foundHeader = true;
|
||||||
|
} else if ((foundHeader) && (line.length() == 0)) {
|
||||||
|
result.append("\n");
|
||||||
|
} else if (foundHeader) {
|
||||||
|
readingHeader = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String buildHeader() {
|
||||||
|
String header = options().header();
|
||||||
|
|
||||||
|
if (options().copyHeader()) {
|
||||||
|
Configuration def = getDefaults();
|
||||||
|
|
||||||
|
if ((def != null) && (def instanceof FileConfiguration)) {
|
||||||
|
FileConfiguration filedefaults = (FileConfiguration) def;
|
||||||
|
String defaultsHeader = filedefaults.buildHeader();
|
||||||
|
|
||||||
|
if ((defaultsHeader != null) && (defaultsHeader.length() > 0)) {
|
||||||
|
return defaultsHeader;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (header == null) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
StringBuilder builder = new StringBuilder();
|
||||||
|
String[] lines = header.split("\r?\n", -1);
|
||||||
|
boolean startedHeader = false;
|
||||||
|
|
||||||
|
for (int i = lines.length - 1; i >= 0; i--) {
|
||||||
|
builder.insert(0, "\n");
|
||||||
|
|
||||||
|
if ((startedHeader) || (lines[i].length() != 0)) {
|
||||||
|
builder.insert(0, lines[i]);
|
||||||
|
builder.insert(0, COMMENT_PREFIX);
|
||||||
|
startedHeader = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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.
|
||||||
|
* <p>
|
||||||
|
* The encoding used may follow the system dependent default.
|
||||||
|
*
|
||||||
|
* @param file Input file
|
||||||
|
* @return Resulting configuration
|
||||||
|
* @throws IllegalArgumentException Thrown if file is null
|
||||||
|
*/
|
||||||
|
public static YamlConfiguration loadConfiguration(File file) {
|
||||||
|
if (file == null) throw new NullPointerException("File cannot be null");
|
||||||
|
|
||||||
|
YamlConfiguration config = new YamlConfiguration();
|
||||||
|
|
||||||
|
try {
|
||||||
|
config.load(file);
|
||||||
|
} catch (FileNotFoundException ex) {
|
||||||
|
} catch (IOException ex) {
|
||||||
|
PS.log("Cannot load " + file);
|
||||||
|
ex.printStackTrace();
|
||||||
|
} catch (InvalidConfigurationException ex) {
|
||||||
|
PS.log("Cannot load " + file);
|
||||||
|
ex.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
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 if stream is null
|
||||||
|
* @deprecated does not properly consider encoding
|
||||||
|
* @see #load(InputStream)
|
||||||
|
* @see #loadConfiguration(Reader)
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
public static YamlConfiguration loadConfiguration(InputStream stream) {
|
||||||
|
if (stream == null) throw new NullPointerException("Stream cannot be null");
|
||||||
|
|
||||||
|
YamlConfiguration config = new YamlConfiguration();
|
||||||
|
|
||||||
|
try {
|
||||||
|
config.load(stream);
|
||||||
|
} catch (IOException ex) {
|
||||||
|
PS.log("Cannot load configuration from stream");
|
||||||
|
ex.printStackTrace();
|
||||||
|
} catch (InvalidConfigurationException ex) {
|
||||||
|
ex.printStackTrace();
|
||||||
|
PS.log("Cannot load configuration from stream");
|
||||||
|
}
|
||||||
|
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new {@link YamlConfiguration}, loading from the given reader.
|
||||||
|
* <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 reader input
|
||||||
|
* @return resulting configuration
|
||||||
|
* @throws IllegalArgumentException Thrown if stream is null
|
||||||
|
*/
|
||||||
|
public static YamlConfiguration loadConfiguration(Reader reader) {
|
||||||
|
if (reader == null) throw new NullPointerException("Reader cannot be null");
|
||||||
|
|
||||||
|
YamlConfiguration config = new YamlConfiguration();
|
||||||
|
|
||||||
|
try {
|
||||||
|
config.load(reader);
|
||||||
|
} catch (IOException ex) {
|
||||||
|
PS.log("Cannot load configuration from stream");
|
||||||
|
ex.printStackTrace();
|
||||||
|
} catch (InvalidConfigurationException ex) {
|
||||||
|
PS.log("Cannot load configuration from stream");
|
||||||
|
ex.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,69 @@
|
|||||||
|
package com.intellectualcrafters.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;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public YamlConfigurationOptions copyHeader(boolean value) {
|
||||||
|
super.copyHeader(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 (value < 2) throw new IllegalArgumentException("Indent must be at least 2 characters");
|
||||||
|
if (value > 9) throw new IllegalArgumentException("Indent cannot be greater than 9 characters");
|
||||||
|
|
||||||
|
this.indent = value;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,49 @@
|
|||||||
|
package com.intellectualcrafters.configuration.file;
|
||||||
|
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.yaml.snakeyaml.nodes.Node;
|
||||||
|
import org.yaml.snakeyaml.constructor.SafeConstructor;
|
||||||
|
import org.yaml.snakeyaml.error.YAMLException;
|
||||||
|
import org.yaml.snakeyaml.nodes.Tag;
|
||||||
|
|
||||||
|
import com.intellectualcrafters.configuration.serialization.ConfigurationSerialization;
|
||||||
|
|
||||||
|
public class YamlConstructor extends SafeConstructor {
|
||||||
|
|
||||||
|
public YamlConstructor() {
|
||||||
|
this.yamlConstructors.put(Tag.MAP, new ConstructCustomObject());
|
||||||
|
}
|
||||||
|
|
||||||
|
private class ConstructCustomObject extends ConstructYamlMap {
|
||||||
|
@Override
|
||||||
|
public Object construct(Node node) {
|
||||||
|
if (node.isTwoStepsConstruction()) {
|
||||||
|
throw new YAMLException("Unexpected referential mapping structure. Node: " + node);
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<?, ?> raw = (Map<?, ?>) super.construct(node);
|
||||||
|
|
||||||
|
if (raw.containsKey(ConfigurationSerialization.SERIALIZED_TYPE_KEY)) {
|
||||||
|
Map<String, Object> typed = new LinkedHashMap<String, Object>(raw.size());
|
||||||
|
for (Map.Entry<?, ?> entry : raw.entrySet()) {
|
||||||
|
typed.put(entry.getKey().toString(), entry.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
return ConfigurationSerialization.deserializeObject(typed);
|
||||||
|
} catch (IllegalArgumentException ex) {
|
||||||
|
throw new YAMLException("Could not deserialize object", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return raw;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void construct2ndStep(Node node, Object object) {
|
||||||
|
throw new YAMLException("Unexpected referential mapping structure. Node: " + node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,38 @@
|
|||||||
|
package com.intellectualcrafters.configuration.file;
|
||||||
|
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import com.intellectualcrafters.configuration.ConfigurationSection;
|
||||||
|
import com.intellectualcrafters.configuration.serialization.ConfigurationSerializable;
|
||||||
|
import com.intellectualcrafters.configuration.serialization.ConfigurationSerialization;
|
||||||
|
|
||||||
|
import org.yaml.snakeyaml.nodes.Node;
|
||||||
|
import org.yaml.snakeyaml.representer.Representer;
|
||||||
|
|
||||||
|
public class YamlRepresenter extends Representer {
|
||||||
|
|
||||||
|
public YamlRepresenter() {
|
||||||
|
this.multiRepresenters.put(ConfigurationSection.class, new RepresentConfigurationSection());
|
||||||
|
this.multiRepresenters.put(ConfigurationSerializable.class, new RepresentConfigurationSerializable());
|
||||||
|
}
|
||||||
|
|
||||||
|
private class RepresentConfigurationSection extends RepresentMap {
|
||||||
|
@Override
|
||||||
|
public Node representData(Object data) {
|
||||||
|
return super.representData(((ConfigurationSection) data).getValues(false));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class RepresentConfigurationSerializable extends RepresentMap {
|
||||||
|
@Override
|
||||||
|
public Node representData(Object data) {
|
||||||
|
ConfigurationSerializable serializable = (ConfigurationSerializable) data;
|
||||||
|
Map<String, Object> values = new LinkedHashMap<String, Object>();
|
||||||
|
values.put(ConfigurationSerialization.SERIALIZED_TYPE_KEY, ConfigurationSerialization.getAlias(serializable.getClass()));
|
||||||
|
values.putAll(serializable.serialize());
|
||||||
|
|
||||||
|
return super.representData(values);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,35 @@
|
|||||||
|
package com.intellectualcrafters.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:
|
||||||
|
* <ul>
|
||||||
|
* <li>A static method "deserialize" that accepts a single {@link Map}<
|
||||||
|
* {@link String}, {@link Object}> and returns the class.</li>
|
||||||
|
* <li>A static method "valueOf" that accepts a single {@link Map}<{@link
|
||||||
|
* String}, {@link Object}> and returns the class.</li>
|
||||||
|
* <li>A constructor that accepts a single {@link Map}<{@link String},
|
||||||
|
* {@link Object}>.</li>
|
||||||
|
* </ul>
|
||||||
|
* In addition to implementing this interface, you must register the class
|
||||||
|
* with {@link ConfigurationSerialization#registerClass(Class)}.
|
||||||
|
*
|
||||||
|
* @see DelegateDeserialization
|
||||||
|
* @see SerializableAs
|
||||||
|
*/
|
||||||
|
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,266 @@
|
|||||||
|
package com.intellectualcrafters.configuration.serialization;
|
||||||
|
|
||||||
|
import java.lang.reflect.Constructor;
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
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 com.intellectualcrafters.configuration.Configuration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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>>();
|
||||||
|
|
||||||
|
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, ?> 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 instanceof InvocationTargetException ? ex.getCause() : ex);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected ConfigurationSerializable deserializeViaCtor(Constructor<? extends ConfigurationSerializable> ctor, Map<String, ?> 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 instanceof InvocationTargetException ? ex.getCause() : ex);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ConfigurationSerializable deserialize(Map<String, ?> args) {
|
||||||
|
if (args == null) {
|
||||||
|
throw new NullPointerException("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, ?> 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, ?> 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("Cannot have null alias");
|
||||||
|
}
|
||||||
|
clazz = getClassByAlias(alias);
|
||||||
|
if (clazz == null) {
|
||||||
|
throw new IllegalArgumentException("Specified class does not exist ('" + 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
|
||||||
|
* @see SerializableAs
|
||||||
|
*/
|
||||||
|
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,22 @@
|
|||||||
|
package com.intellectualcrafters.configuration.serialization;
|
||||||
|
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Applies to 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,34 @@
|
|||||||
|
package com.intellectualcrafters.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>
|
||||||
|
* This value will be stored in the configuration so that the configuration
|
||||||
|
* deserialization can determine what type it is.
|
||||||
|
* <p>
|
||||||
|
* Using this annotation on any other class than a {@link
|
||||||
|
* ConfigurationSerializable} will have no effect.
|
||||||
|
*
|
||||||
|
* @see ConfigurationSerialization#registerClass(Class, String)
|
||||||
|
*/
|
||||||
|
@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();
|
||||||
|
}
|
@ -16,7 +16,7 @@ import com.intellectualcrafters.plot.util.Logger.LogLevel;
|
|||||||
import com.intellectualcrafters.plot.util.bukkit.UUIDHandler;
|
import com.intellectualcrafters.plot.util.bukkit.UUIDHandler;
|
||||||
import com.sk89q.worldedit.bukkit.WorldEditPlugin;
|
import com.sk89q.worldedit.bukkit.WorldEditPlugin;
|
||||||
|
|
||||||
import org.bukkit.configuration.file.YamlConfiguration;
|
import com.intellectualcrafters.configuration.file.YamlConfiguration;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
@ -1084,7 +1084,7 @@ public class PS {
|
|||||||
Settings.CONFIRM_UNLINK = config.getBoolean("confirmation.unlink");
|
Settings.CONFIRM_UNLINK = config.getBoolean("confirmation.unlink");
|
||||||
|
|
||||||
// Protection
|
// Protection
|
||||||
Settings.REDSTONE_DISABLER = config.getBoolean("protection.tnt-listener.enabled");
|
Settings.REDSTONE_DISABLER = config.getBoolean("protection.redstone.disable-offline");
|
||||||
Settings.TNT_LISTENER = config.getBoolean("protection.tnt-listener.enabled");
|
Settings.TNT_LISTENER = config.getBoolean("protection.tnt-listener.enabled");
|
||||||
Settings.PISTON_FALLING_BLOCK_CHECK = config.getBoolean("protection.piston.falling-blocks");
|
Settings.PISTON_FALLING_BLOCK_CHECK = config.getBoolean("protection.piston.falling-blocks");
|
||||||
|
|
||||||
|
@ -35,7 +35,7 @@ import com.intellectualcrafters.plot.util.bukkit.UUIDHandler;
|
|||||||
import com.intellectualcrafters.plot.uuid.UUIDWrapper;
|
import com.intellectualcrafters.plot.uuid.UUIDWrapper;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
import org.bukkit.configuration.file.YamlConfiguration;
|
import com.intellectualcrafters.configuration.file.YamlConfiguration;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.plugin.java.JavaPlugin;
|
import org.bukkit.plugin.java.JavaPlugin;
|
||||||
|
|
||||||
|
@ -32,6 +32,7 @@ import com.intellectualcrafters.plot.object.PlotItemStack;
|
|||||||
import com.intellectualcrafters.plot.object.PlotPlayer;
|
import com.intellectualcrafters.plot.object.PlotPlayer;
|
||||||
import com.intellectualcrafters.plot.util.BlockManager;
|
import com.intellectualcrafters.plot.util.BlockManager;
|
||||||
import com.intellectualcrafters.plot.util.MainUtil;
|
import com.intellectualcrafters.plot.util.MainUtil;
|
||||||
|
import com.intellectualcrafters.plot.util.TaskManager;
|
||||||
|
|
||||||
public class MusicSubcommand extends SubCommand {
|
public class MusicSubcommand extends SubCommand {
|
||||||
public MusicSubcommand() {
|
public MusicSubcommand() {
|
||||||
@ -52,8 +53,19 @@ public class MusicSubcommand extends SubCommand {
|
|||||||
PlotInventory inv = new PlotInventory(player, 2, "Plot Jukebox") {
|
PlotInventory inv = new PlotInventory(player, 2, "Plot Jukebox") {
|
||||||
public boolean onClick(int index) {
|
public boolean onClick(int index) {
|
||||||
PlotItemStack item = getItem(index);
|
PlotItemStack item = getItem(index);
|
||||||
FlagManager.addPlotFlag(plot, new Flag(FlagManager.getFlag("music"), item.id));
|
int id = item.id == 7 ? 0 : item.id;
|
||||||
|
if (id == 0) {
|
||||||
|
FlagManager.removePlotFlag(plot, "music");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
FlagManager.addPlotFlag(plot, new Flag(FlagManager.getFlag("music"), id));
|
||||||
|
}
|
||||||
|
TaskManager.runTaskLater(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
PlotListener.manager.plotEntry(player, plot);
|
PlotListener.manager.plotEntry(player, plot);
|
||||||
|
}
|
||||||
|
}, 1);
|
||||||
close();
|
close();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -66,6 +78,11 @@ public class MusicSubcommand extends SubCommand {
|
|||||||
inv.setItem(index, item);
|
inv.setItem(index, item);
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
|
if (player.getMeta("music") != null) {
|
||||||
|
String name = "&r&6Cancel music";
|
||||||
|
String[] lore = {"&r&cClick to cancel!"};
|
||||||
|
inv.setItem(index, new PlotItemStack(7, (short) 0, 1, name, lore));
|
||||||
|
}
|
||||||
inv.openInventory();
|
inv.openInventory();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -28,8 +28,8 @@ import com.intellectualcrafters.plot.util.BlockManager;
|
|||||||
import com.intellectualcrafters.plot.util.MainUtil;
|
import com.intellectualcrafters.plot.util.MainUtil;
|
||||||
import com.intellectualcrafters.plot.util.SetupUtils;
|
import com.intellectualcrafters.plot.util.SetupUtils;
|
||||||
import com.intellectualcrafters.plot.util.TaskManager;
|
import com.intellectualcrafters.plot.util.TaskManager;
|
||||||
import org.bukkit.configuration.ConfigurationSection;
|
import com.intellectualcrafters.configuration.ConfigurationSection;
|
||||||
import org.bukkit.configuration.file.YamlConfiguration;
|
import com.intellectualcrafters.configuration.file.YamlConfiguration;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
|
@ -127,12 +127,16 @@ public class Trim extends SubCommand {
|
|||||||
plots.remove(0);
|
plots.remove(0);
|
||||||
final Location pos1 = MainUtil.getPlotBottomLoc(world, plot.id);
|
final Location pos1 = MainUtil.getPlotBottomLoc(world, plot.id);
|
||||||
final Location pos2 = MainUtil.getPlotTopLoc(world, plot.id);
|
final Location pos2 = MainUtil.getPlotTopLoc(world, plot.id);
|
||||||
final Location pos3 = new Location(world, pos1.getX(), 64, pos2.getZ());
|
System.out.print(plot);
|
||||||
final Location pos4 = new Location(world, pos2.getX(), 64, pos1.getZ());
|
System.out.print(pos1);
|
||||||
chunks.remove(ChunkManager.getChunkChunk(pos1));
|
System.out.print(pos2);
|
||||||
chunks.remove(ChunkManager.getChunkChunk(pos2));
|
for (int x = pos1.getX(); x <= pos2.getX(); x += 512 ) {
|
||||||
chunks.remove(ChunkManager.getChunkChunk(pos3));
|
for (int z = pos1.getZ(); z <= pos2.getZ(); z += 512 ) {
|
||||||
chunks.remove(ChunkManager.getChunkChunk(pos4));
|
ChunkLoc chunk = ChunkManager.getChunkChunk(new Location(world, x, 0, z));
|
||||||
|
System.out.print(chunk.x + "," + chunk.z);
|
||||||
|
chunks.remove(chunk);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, 20);
|
}, 20);
|
||||||
|
@ -22,6 +22,7 @@ package com.intellectualcrafters.plot.config;
|
|||||||
|
|
||||||
import org.bukkit.ChatColor;
|
import org.bukkit.ChatColor;
|
||||||
|
|
||||||
|
import com.boydti.buildoff.config.BBC;
|
||||||
import com.intellectualsites.translation.TranslationFile;
|
import com.intellectualsites.translation.TranslationFile;
|
||||||
import com.intellectualsites.translation.TranslationLanguage;
|
import com.intellectualsites.translation.TranslationLanguage;
|
||||||
import com.intellectualsites.translation.TranslationManager;
|
import com.intellectualsites.translation.TranslationManager;
|
||||||
@ -546,6 +547,20 @@ public enum C {
|
|||||||
this(d, true, cat.toLowerCase());
|
this(d, true, cat.toLowerCase());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String format(C c, Object... args) {
|
||||||
|
String m = c.s;
|
||||||
|
for (int i = args.length - 1 ; i >= 0; i--) {
|
||||||
|
if (args[i] == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
m = m.replaceAll("%s" + i, args[i].toString());
|
||||||
|
}
|
||||||
|
if (args.length > 0) {
|
||||||
|
m = m.replaceAll("%s", args[0].toString());
|
||||||
|
}
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
public static void setupTranslations() {
|
public static void setupTranslations() {
|
||||||
manager = new TranslationManager();
|
manager = new TranslationManager();
|
||||||
defaultFile = new YamlTranslationFile(BukkitTranslation.getParent(), lang, "PlotSquared", manager, true).read();
|
defaultFile = new YamlTranslationFile(BukkitTranslation.getParent(), lang, "PlotSquared", manager, true).read();
|
||||||
|
@ -4,7 +4,7 @@ import java.sql.Connection;
|
|||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
|
||||||
import org.bukkit.configuration.file.FileConfiguration;
|
import com.intellectualcrafters.configuration.file.FileConfiguration;
|
||||||
|
|
||||||
import com.intellectualcrafters.plot.object.Plot;
|
import com.intellectualcrafters.plot.object.Plot;
|
||||||
import com.intellectualcrafters.plot.object.PlotId;
|
import com.intellectualcrafters.plot.object.PlotId;
|
||||||
|
@ -11,7 +11,7 @@ import com.intellectualcrafters.plot.util.MainUtil;
|
|||||||
import com.intellectualcrafters.plot.util.bukkit.UUIDHandler;
|
import com.intellectualcrafters.plot.util.bukkit.UUIDHandler;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
import org.bukkit.configuration.file.FileConfiguration;
|
import com.intellectualcrafters.configuration.file.FileConfiguration;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.sql.*;
|
import java.sql.*;
|
||||||
|
@ -30,8 +30,8 @@ import com.intellectualcrafters.plot.util.TaskManager;
|
|||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
import org.bukkit.WorldCreator;
|
import org.bukkit.WorldCreator;
|
||||||
import org.bukkit.configuration.file.FileConfiguration;
|
import com.intellectualcrafters.configuration.file.FileConfiguration;
|
||||||
import org.bukkit.configuration.file.YamlConfiguration;
|
import com.intellectualcrafters.configuration.file.YamlConfiguration;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package com.intellectualcrafters.plot.generator;
|
package com.intellectualcrafters.plot.generator;
|
||||||
|
|
||||||
import org.apache.commons.lang.StringUtils;
|
import org.apache.commons.lang.StringUtils;
|
||||||
import org.bukkit.configuration.ConfigurationSection;
|
import com.intellectualcrafters.configuration.ConfigurationSection;
|
||||||
|
|
||||||
import com.intellectualcrafters.plot.PS;
|
import com.intellectualcrafters.plot.PS;
|
||||||
import com.intellectualcrafters.plot.config.Configuration;
|
import com.intellectualcrafters.plot.config.Configuration;
|
||||||
|
@ -25,7 +25,7 @@ import java.util.HashSet;
|
|||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
import org.apache.commons.lang.StringUtils;
|
import org.apache.commons.lang.StringUtils;
|
||||||
import org.bukkit.configuration.ConfigurationSection;
|
import com.intellectualcrafters.configuration.ConfigurationSection;
|
||||||
|
|
||||||
import com.intellectualcrafters.plot.PS;
|
import com.intellectualcrafters.plot.PS;
|
||||||
import com.intellectualcrafters.plot.config.C;
|
import com.intellectualcrafters.plot.config.C;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
package com.intellectualcrafters.plot.generator;
|
package com.intellectualcrafters.plot.generator;
|
||||||
|
|
||||||
import org.bukkit.configuration.ConfigurationSection;
|
import com.intellectualcrafters.configuration.ConfigurationSection;
|
||||||
|
|
||||||
import com.intellectualcrafters.plot.PS;
|
import com.intellectualcrafters.plot.PS;
|
||||||
|
|
||||||
|
@ -34,8 +34,10 @@ import com.intellectualcrafters.plot.object.PlotPlayer;
|
|||||||
import com.intellectualcrafters.plot.object.comment.CommentManager;
|
import com.intellectualcrafters.plot.object.comment.CommentManager;
|
||||||
import com.intellectualcrafters.plot.titles.AbstractTitle;
|
import com.intellectualcrafters.plot.titles.AbstractTitle;
|
||||||
import com.intellectualcrafters.plot.util.MainUtil;
|
import com.intellectualcrafters.plot.util.MainUtil;
|
||||||
|
import com.intellectualcrafters.plot.util.TaskManager;
|
||||||
import com.intellectualcrafters.plot.util.bukkit.BukkitUtil;
|
import com.intellectualcrafters.plot.util.bukkit.BukkitUtil;
|
||||||
import com.intellectualcrafters.plot.util.bukkit.UUIDHandler;
|
import com.intellectualcrafters.plot.util.bukkit.UUIDHandler;
|
||||||
|
|
||||||
import org.bukkit.*;
|
import org.bukkit.*;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
@ -91,7 +93,7 @@ public class PlotListener extends APlotListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void plotEntry(final PlotPlayer pp, final Plot plot) {
|
public void plotEntry(final PlotPlayer pp, final Plot plot) {
|
||||||
Player player = ((BukkitPlayer) pp).player;
|
final Player player = ((BukkitPlayer) pp).player;
|
||||||
if (plot.hasOwner()) {
|
if (plot.hasOwner()) {
|
||||||
final Flag gamemodeFlag = FlagManager.getPlotFlag(plot, "gamemode");
|
final Flag gamemodeFlag = FlagManager.getPlotFlag(plot, "gamemode");
|
||||||
if (gamemodeFlag != null) {
|
if (gamemodeFlag != null) {
|
||||||
@ -137,18 +139,31 @@ public class PlotListener extends APlotListener {
|
|||||||
}
|
}
|
||||||
Flag musicFlag = FlagManager.getPlotFlag(plot, "music");
|
Flag musicFlag = FlagManager.getPlotFlag(plot, "music");
|
||||||
if (musicFlag != null) {
|
if (musicFlag != null) {
|
||||||
player.playEffect(player.getLocation(), Effect.RECORD_PLAY, 0);
|
final Integer id = (Integer) musicFlag.getValue();
|
||||||
Integer id = (Integer) musicFlag.getValue();
|
if ((id >= 2256 && id <= 2267) || id == 0) {
|
||||||
if (id >= 2256 && id <= 2267) {
|
final org.bukkit.Location loc = player.getLocation();
|
||||||
Location center = MainUtil.getPlotCenter(plot);
|
org.bukkit.Location lastLoc = (org.bukkit.Location) pp.getMeta("music");
|
||||||
org.bukkit.Location newLoc = BukkitUtil.getLocation(center);
|
if (lastLoc != null) {
|
||||||
newLoc.setY(Math.min((player.getLocation().getBlockY() / 16) * 16, 240));
|
player.playEffect(lastLoc, Effect.RECORD_PLAY, 0);
|
||||||
|
if (id == 0) {
|
||||||
|
pp.deleteMeta("music");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
player.playEffect(newLoc, Effect.RECORD_PLAY, Material.getMaterial(id));
|
pp.setMeta("music", loc);
|
||||||
|
player.playEffect(loc, Effect.RECORD_PLAY, Material.getMaterial(id));
|
||||||
}
|
}
|
||||||
catch (Exception e) {}
|
catch (Exception e) {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
org.bukkit.Location lastLoc = (org.bukkit.Location) pp.getMeta("music");
|
||||||
|
if (lastLoc != null) {
|
||||||
|
pp.deleteMeta("music");
|
||||||
|
player.playEffect(lastLoc, Effect.RECORD_PLAY, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
CommentManager.sendTitle(pp, plot);
|
CommentManager.sendTitle(pp, plot);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -169,13 +184,10 @@ public class PlotListener extends APlotListener {
|
|||||||
if (FlagManager.getPlotFlag(plot, "weather") != null) {
|
if (FlagManager.getPlotFlag(plot, "weather") != null) {
|
||||||
player.resetPlayerWeather();
|
player.resetPlayerWeather();
|
||||||
}
|
}
|
||||||
if (FlagManager.getPlotFlag(plot, "music") != null) {
|
org.bukkit.Location lastLoc = (org.bukkit.Location) pp.getMeta("music");
|
||||||
Location center = MainUtil.getPlotCenter(plot);
|
if (lastLoc != null) {
|
||||||
for (int i = 0; i < 256; i+= 16) {
|
pp.deleteMeta("music");
|
||||||
org.bukkit.Location newLoc = BukkitUtil.getLocation(center);
|
player.playEffect(lastLoc, Effect.RECORD_PLAY, 0);
|
||||||
newLoc.setY(i);
|
|
||||||
player.playEffect(newLoc, Effect.RECORD_PLAY, 0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -199,7 +199,6 @@ public class PlotPlusListener extends PlotListener implements Listener {
|
|||||||
@EventHandler
|
@EventHandler
|
||||||
public void onPlotLeave(final PlayerLeavePlotEvent event) {
|
public void onPlotLeave(final PlayerLeavePlotEvent event) {
|
||||||
final Player leaver = event.getPlayer();
|
final Player leaver = event.getPlayer();
|
||||||
leaver.playEffect(leaver.getLocation(), Effect.RECORD_PLAY, 0);
|
|
||||||
final Plot plot = event.getPlot();
|
final Plot plot = event.getPlot();
|
||||||
if (FlagManager.getPlotFlag(plot, "farewell") != null) {
|
if (FlagManager.getPlotFlag(plot, "farewell") != null) {
|
||||||
event.getPlayer().sendMessage(ChatColor.translateAlternateColorCodes('&', C.PREFIX_FAREWELL.s().replaceAll("%id%", plot.id + "") + FlagManager.getPlotFlag(plot, "farewell").getValueString()));
|
event.getPlayer().sendMessage(ChatColor.translateAlternateColorCodes('&', C.PREFIX_FAREWELL.s().replaceAll("%id%", plot.id + "") + FlagManager.getPlotFlag(plot, "farewell").getValueString()));
|
||||||
|
@ -28,7 +28,7 @@ import com.intellectualcrafters.plot.flag.Flag;
|
|||||||
import com.intellectualcrafters.plot.flag.FlagManager;
|
import com.intellectualcrafters.plot.flag.FlagManager;
|
||||||
import com.intellectualcrafters.plot.util.EconHandler;
|
import com.intellectualcrafters.plot.util.EconHandler;
|
||||||
import org.apache.commons.lang.StringUtils;
|
import org.apache.commons.lang.StringUtils;
|
||||||
import org.bukkit.configuration.ConfigurationSection;
|
import com.intellectualcrafters.configuration.ConfigurationSection;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
@ -42,8 +42,8 @@ import java.util.logging.Level;
|
|||||||
import java.util.zip.GZIPOutputStream;
|
import java.util.zip.GZIPOutputStream;
|
||||||
|
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.configuration.InvalidConfigurationException;
|
import com.intellectualcrafters.configuration.InvalidConfigurationException;
|
||||||
import org.bukkit.configuration.file.YamlConfiguration;
|
import com.intellectualcrafters.configuration.file.YamlConfiguration;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.plugin.Plugin;
|
import org.bukkit.plugin.Plugin;
|
||||||
import org.bukkit.plugin.PluginDescriptionFile;
|
import org.bukkit.plugin.PluginDescriptionFile;
|
||||||
|
@ -24,8 +24,8 @@ import org.bukkit.Material;
|
|||||||
import org.bukkit.Statistic;
|
import org.bukkit.Statistic;
|
||||||
import org.bukkit.Statistic.Type;
|
import org.bukkit.Statistic.Type;
|
||||||
import org.bukkit.command.CommandSender;
|
import org.bukkit.command.CommandSender;
|
||||||
import org.bukkit.configuration.serialization.ConfigurationSerializable;
|
import com.intellectualcrafters.configuration.serialization.ConfigurationSerializable;
|
||||||
import org.bukkit.configuration.serialization.ConfigurationSerialization;
|
import com.intellectualcrafters.configuration.serialization.ConfigurationSerialization;
|
||||||
import org.bukkit.entity.EntityType;
|
import org.bukkit.entity.EntityType;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
@ -4,7 +4,7 @@ import java.io.IOException;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.bukkit.configuration.serialization.ConfigurationSerializable;
|
import com.intellectualcrafters.configuration.serialization.ConfigurationSerializable;
|
||||||
|
|
||||||
import com.google.gson.stream.JsonWriter;
|
import com.google.gson.stream.JsonWriter;
|
||||||
|
|
||||||
|
@ -8,8 +8,8 @@ import java.util.logging.Level;
|
|||||||
|
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.ChatColor;
|
import org.bukkit.ChatColor;
|
||||||
import org.bukkit.configuration.serialization.ConfigurationSerializable;
|
import com.intellectualcrafters.configuration.serialization.ConfigurationSerializable;
|
||||||
import org.bukkit.configuration.serialization.ConfigurationSerialization;
|
import com.intellectualcrafters.configuration.serialization.ConfigurationSerialization;
|
||||||
|
|
||||||
import com.google.common.collect.BiMap;
|
import com.google.common.collect.BiMap;
|
||||||
import com.google.common.collect.ImmutableBiMap;
|
import com.google.common.collect.ImmutableBiMap;
|
||||||
|
@ -4,8 +4,8 @@ import java.io.IOException;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.bukkit.configuration.serialization.ConfigurationSerializable;
|
import com.intellectualcrafters.configuration.serialization.ConfigurationSerializable;
|
||||||
import org.bukkit.configuration.serialization.ConfigurationSerialization;
|
import com.intellectualcrafters.configuration.serialization.ConfigurationSerialization;
|
||||||
|
|
||||||
import com.google.common.base.Preconditions;
|
import com.google.common.base.Preconditions;
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
@ -9,7 +9,7 @@ import java.util.HashMap;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.bukkit.configuration.file.YamlConfiguration;
|
import com.intellectualcrafters.configuration.file.YamlConfiguration;
|
||||||
import org.yaml.snakeyaml.DumperOptions;
|
import org.yaml.snakeyaml.DumperOptions;
|
||||||
import org.yaml.snakeyaml.Yaml;
|
import org.yaml.snakeyaml.Yaml;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user