From a6631c40ad48114e442d29f15f2959bbe71d4386 Mon Sep 17 00:00:00 2001 From: Nathan Wolf Date: Tue, 13 May 2014 09:09:53 -0700 Subject: [PATCH 01/11] Add hasCustomData/getCustomData. Fixes BUKKIT-3221 --- .../org/bukkit/inventory/meta/ItemMeta.java | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/src/main/java/org/bukkit/inventory/meta/ItemMeta.java b/src/main/java/org/bukkit/inventory/meta/ItemMeta.java index 397ba11582..d3c43a2619 100644 --- a/src/main/java/org/bukkit/inventory/meta/ItemMeta.java +++ b/src/main/java/org/bukkit/inventory/meta/ItemMeta.java @@ -3,6 +3,7 @@ import java.util.List; import java.util.Map; +import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.serialization.ConfigurationSerializable; import org.bukkit.enchantments.Enchantment; @@ -63,6 +64,36 @@ public interface ItemMeta extends Cloneable, ConfigurationSerializable { */ void setLore(List lore); + /** + * Check to see if this Item has any custom or unknown data. + *

+ * This is normally data that has been put here by a Plugin. + * + * @return true if this Item has any custom data + */ + boolean hasCustomData(); + + /** + * Retrieve a read/write accessor fo this Item's custom data. + *

+ * Changes made to this object will affect the Item's custom + * data directly. + *

+ * These objects should not be retained, it is best to get a + * new reference each time you want to modify the item, since + * items may get copied as they move around or spawn and get + * picked up. + *

+ * If this item has no custom data, calling this will initialize + * custom data for the item. + *

+ * Use hasData for an efficient pre-check if you + * only getting data to look for a specific key or value. + * + * @return Access to the Item's custom data + */ + ConfigurationSection getCustomData(); + /** * Checks for the existence of any enchantments. * From 10b3367eed98b425be9a53add0e2ca931d244eb2 Mon Sep 17 00:00:00 2001 From: Nathan Wolf Date: Fri, 16 May 2014 10:22:08 -0700 Subject: [PATCH 02/11] ItemMeta extends Metadatable This replaces the ConfigurationSection-based getCustomData() method. The metadata store will only accept a new PersistentMetadataValue class, which encapsulates and hopefully clarifies the notion that only "persistable" data can be stored here. This includes Lists, Maps, most basic types, and ConfigurationSerializable objects. --- .../java/org/bukkit/inventory/ItemStack.java | 13 ++ .../org/bukkit/inventory/meta/ItemMeta.java | 36 +--- .../metadata/PersistentMetadataValue.java | 158 ++++++++++++++++++ 3 files changed, 180 insertions(+), 27 deletions(-) create mode 100644 src/main/java/org/bukkit/metadata/PersistentMetadataValue.java diff --git a/src/main/java/org/bukkit/inventory/ItemStack.java b/src/main/java/org/bukkit/inventory/ItemStack.java index 6137c994f8..3f9f5bf499 100644 --- a/src/main/java/org/bukkit/inventory/ItemStack.java +++ b/src/main/java/org/bukkit/inventory/ItemStack.java @@ -600,4 +600,17 @@ private boolean setItemMeta0(ItemMeta itemMeta, Material material) { return true; } + + /** + * An efficient quick check to see if this ItemStack has any Metadata in + * its ItemMeta store, without actually unpacking the ItemMeta object. + *

+ * Use this in place of getItemMeta().hasMetadata() for simple first-pass + * checks for data, if you don't necessarily need to unpack the data. + * + * @return True if getItemMeta().hasMetadata() + */ + public boolean hasMetadata() { + return false; + } } diff --git a/src/main/java/org/bukkit/inventory/meta/ItemMeta.java b/src/main/java/org/bukkit/inventory/meta/ItemMeta.java index d3c43a2619..d8ae772911 100644 --- a/src/main/java/org/bukkit/inventory/meta/ItemMeta.java +++ b/src/main/java/org/bukkit/inventory/meta/ItemMeta.java @@ -6,14 +6,18 @@ import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.serialization.ConfigurationSerializable; import org.bukkit.enchantments.Enchantment; +import org.bukkit.metadata.Metadatable; /** * This type represents the storage mechanism for auxiliary item data. *

* An implementation will handle the creation and application for ItemMeta. * This class should not be implemented by a plugin in a live environment. + *

+ * The implementing class should implement Metadatable as a persistent data store attached + * to each ItemStack, and only accept PersistentMetadataValue entries. */ -public interface ItemMeta extends Cloneable, ConfigurationSerializable { +public interface ItemMeta extends Cloneable, ConfigurationSerializable, Metadatable { /** * Checks for existence of a display name. @@ -65,34 +69,12 @@ public interface ItemMeta extends Cloneable, ConfigurationSerializable { void setLore(List lore); /** - * Check to see if this Item has any custom or unknown data. - *

- * This is normally data that has been put here by a Plugin. - * - * @return true if this Item has any custom data - */ - boolean hasCustomData(); - - /** - * Retrieve a read/write accessor fo this Item's custom data. - *

- * Changes made to this object will affect the Item's custom - * data directly. - *

- * These objects should not be retained, it is best to get a - * new reference each time you want to modify the item, since - * items may get copied as they move around or spawn and get - * picked up. - *

- * If this item has no custom data, calling this will initialize - * custom data for the item. - *

- * Use hasData for an efficient pre-check if you - * only getting data to look for a specific key or value. + * Check to see if the Metadatable store contains any data for any + * Plugin. * - * @return Access to the Item's custom data + * @return true if there is any custom data present */ - ConfigurationSection getCustomData(); + public boolean hasMetadata(); /** * Checks for the existence of any enchantments. diff --git a/src/main/java/org/bukkit/metadata/PersistentMetadataValue.java b/src/main/java/org/bukkit/metadata/PersistentMetadataValue.java new file mode 100644 index 0000000000..7701c99c6a --- /dev/null +++ b/src/main/java/org/bukkit/metadata/PersistentMetadataValue.java @@ -0,0 +1,158 @@ +package org.bukkit.metadata; + +import org.bukkit.configuration.serialization.ConfigurationSerializable; +import org.bukkit.plugin.Plugin; + +import java.util.List; +import java.util.Map; + +/** + * A PersistentMetadataValue is a special case metadata item that may + * only contain ConfigurationSerializeable Objects, Lists, Maps or + * basic Object types. + *

+ * This class extends FixedMetadataValue to do the work, and is + * primarily here to serve as a reminder that ItemMeta holds + * a slightly different form of Metadata. + */ +public class PersistentMetadataValue extends FixedMetadataValue { + /** + * Initializes a PersistentMetadataValue with a + * ConfigurationSerializable Object + * + * @param owningPlugin the {@link org.bukkit.plugin.Plugin} that created this metadata value + * @param value the value assigned to this metadata value + */ + public PersistentMetadataValue(Plugin owningPlugin, final ConfigurationSerializable value) { + super(owningPlugin, value); + } + + /** + * Initializes a PersistentMetadataValue with a String value. + * + * @param owningPlugin the {@link org.bukkit.plugin.Plugin} that created this metadata value + * @param value the value assigned to this metadata value + */ + public PersistentMetadataValue(Plugin owningPlugin, final String value) { + super(owningPlugin, value); + } + + /** + * Initializes a PersistentMetadataValue with an Integer value. + * + * @param owningPlugin the {@link org.bukkit.plugin.Plugin} that created this metadata value + * @param value the value assigned to this metadata value + */ + public PersistentMetadataValue(Plugin owningPlugin, final Integer value) { + super(owningPlugin, value); + } + + /** + * Initializes a PersistentMetadataValue with a Boolean value. + * + * @param owningPlugin the {@link org.bukkit.plugin.Plugin} that created this metadata value + * @param value the value assigned to this metadata value + */ + public PersistentMetadataValue(Plugin owningPlugin, final Boolean value) { + super(owningPlugin, value); + } + + /** + * Initializes a PersistentMetadataValue with a Long value. + * + * @param owningPlugin the {@link org.bukkit.plugin.Plugin} that created this metadata value + * @param value the value assigned to this metadata value + */ + public PersistentMetadataValue(Plugin owningPlugin, final Long value) { + super(owningPlugin, value); + } + + /** + * Initializes a PersistentMetadataValue with a Double value. + * + * @param owningPlugin the {@link org.bukkit.plugin.Plugin} that created this metadata value + * @param value the value assigned to this metadata value + */ + public PersistentMetadataValue(Plugin owningPlugin, final Double value) { + super(owningPlugin, value); + } + + /** + * Initializes a PersistentMetadataValue with a Short value. + * + * @param owningPlugin the {@link org.bukkit.plugin.Plugin} that created this metadata value + * @param value the value assigned to this metadata value + */ + public PersistentMetadataValue(Plugin owningPlugin, final Short value) { + super(owningPlugin, value); + } + + /** + * Initializes a PersistentMetadataValue with a Float value. + * + * @param owningPlugin the {@link org.bukkit.plugin.Plugin} that created this metadata value + * @param value the value assigned to this metadata value + */ + public PersistentMetadataValue(Plugin owningPlugin, final Float value) { + super(owningPlugin, value); + } + + /** + * Initializes a PersistentMetadataValue with a List value. + *

+ * Note that the contents of the List must also be persistable, + * otherwise an IllegalArgumentException may be generated when + * the metadata store persists. + * + * @param owningPlugin the {@link org.bukkit.plugin.Plugin} that created this metadata value + * @param value the value assigned to this metadata value + */ + public PersistentMetadataValue(Plugin owningPlugin, final List value) { + super(owningPlugin, value); + } + + /** + * Initializes a PersistentMetadataValue with a Map value. + *

+ * Note that the keys of the Map must be Strings, and the + * contents of the Map must be persistable, + * otherwise an IllegalArgumentException may be generated when + * the metadata store persists. + * + * @param owningPlugin the {@link org.bukkit.plugin.Plugin} that created this metadata value + * @param value the value assigned to this metadata value + */ + public PersistentMetadataValue(Plugin owningPlugin, final Map value) { + super(owningPlugin, value); + } + + /** + * Initializes a PersistentMetadataValue with an Object value. + *

+ * The Object must be one of the valid persistable object types. + * The other Constructor forms are preferred, this is here as a + * convenience method. + * + * @throws java.lang.IllegalArgumentException on non-persistable input + * @param owningPlugin the {@link org.bukkit.plugin.Plugin} that created this metadata value + * @param value the value assigned to this metadata value + */ + public PersistentMetadataValue(Plugin owningPlugin, final Object value) { + super(owningPlugin, value); + + if (!( + value instanceof ConfigurationSerializable + || value instanceof String + || value instanceof Integer + || value instanceof Double + || value instanceof Long + || value instanceof Boolean + || value instanceof Short + || value instanceof Float + || value instanceof Map + || value instanceof List + )) { + throw new IllegalArgumentException("Invalid Object type for PersistentMetadataValue: " + value.getClass()); + } + } +} From 9c68c5e5d8f60c1a22e26c6a81b4a324759dfa93 Mon Sep 17 00:00:00 2001 From: Nathan Wolf Date: Mon, 19 May 2014 09:33:37 -0700 Subject: [PATCH 03/11] Add ItemStack.hasMetadata(String key) This provides an efficient mechanism for the common use case of wanting to check for the presence of a specific metadata key without unpacking all of the metadata. --- src/main/java/org/bukkit/inventory/ItemStack.java | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/main/java/org/bukkit/inventory/ItemStack.java b/src/main/java/org/bukkit/inventory/ItemStack.java index 3f9f5bf499..cfb17d7318 100644 --- a/src/main/java/org/bukkit/inventory/ItemStack.java +++ b/src/main/java/org/bukkit/inventory/ItemStack.java @@ -613,4 +613,19 @@ private boolean setItemMeta0(ItemMeta itemMeta, Material material) { public boolean hasMetadata() { return false; } + + /** + * An efficient quick check to see if this ItemStack has a + * particular metadata key in its ItemMeta store, + * without actually unpacking the ItemMeta object. + *

+ * Use this in place of getItemMeta().hasMetadata("field") for simple first-pass + * checks for data, if you don't necessarily need to unpack the data. + * + * @param key The String key to check for + * @return True if getItemMeta().hasMetadata(key) + */ + public boolean hasMetadata(String key) { + return false; + } } From 8ec74fc9b0d72bf78e16a5f9f048671bb20c6af4 Mon Sep 17 00:00:00 2001 From: Nathan Wolf Date: Mon, 19 May 2014 16:05:03 -0700 Subject: [PATCH 04/11] Implement ItemStack.hasMetadata I have to admit I'm not sure what specific use cases will result in the base ItemStack methods getting called, but this is generally the correct thing to do, and let descending classes override for optimization purposes. --- src/main/java/org/bukkit/inventory/ItemStack.java | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/bukkit/inventory/ItemStack.java b/src/main/java/org/bukkit/inventory/ItemStack.java index cfb17d7318..e5a545122a 100644 --- a/src/main/java/org/bukkit/inventory/ItemStack.java +++ b/src/main/java/org/bukkit/inventory/ItemStack.java @@ -602,30 +602,35 @@ private boolean setItemMeta0(ItemMeta itemMeta, Material material) { } /** - * An efficient quick check to see if this ItemStack has any Metadata in + * This can be overridden to provide an efficient quick check to + * see if this ItemStack has any Metadata in * its ItemMeta store, without actually unpacking the ItemMeta object. *

* Use this in place of getItemMeta().hasMetadata() for simple first-pass * checks for data, if you don't necessarily need to unpack the data. + *

+ * The default implementation defers to ItemMeta. * * @return True if getItemMeta().hasMetadata() */ public boolean hasMetadata() { - return false; + return meta != null && meta.hasMetadata(); } /** - * An efficient quick check to see if this ItemStack has a - * particular metadata key in its ItemMeta store, + * This can be overridden to provide an efficient quick check to + * see if this ItemStack has any Metadata in its ItemMeta store, * without actually unpacking the ItemMeta object. *

* Use this in place of getItemMeta().hasMetadata("field") for simple first-pass * checks for data, if you don't necessarily need to unpack the data. + *

+ * The default implementation defers to ItemMeta. * * @param key The String key to check for * @return True if getItemMeta().hasMetadata(key) */ public boolean hasMetadata(String key) { - return false; + return meta != null && meta.hasMetadata(key); } } From 0f3caaae7bb1e078e4d817777bd84d9c68222fc7 Mon Sep 17 00:00:00 2001 From: Nathan Wolf Date: Mon, 19 May 2014 20:42:40 -0700 Subject: [PATCH 05/11] Add ItemStack.hasMetadata(String, Plugin) --- .../java/org/bukkit/inventory/ItemStack.java | 22 ++++++++++++++++++- .../org/bukkit/inventory/meta/ItemMeta.java | 12 ++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/bukkit/inventory/ItemStack.java b/src/main/java/org/bukkit/inventory/ItemStack.java index e5a545122a..2496ca4170 100644 --- a/src/main/java/org/bukkit/inventory/ItemStack.java +++ b/src/main/java/org/bukkit/inventory/ItemStack.java @@ -12,6 +12,7 @@ import org.bukkit.enchantments.Enchantment; import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.material.MaterialData; +import org.bukkit.plugin.Plugin; /** * Represents a stack of items @@ -619,7 +620,7 @@ public boolean hasMetadata() { /** * This can be overridden to provide an efficient quick check to - * see if this ItemStack has any Metadata in its ItemMeta store, + * see if this ItemStack has a specific key in its metadata store, * without actually unpacking the ItemMeta object. *

* Use this in place of getItemMeta().hasMetadata("field") for simple first-pass @@ -633,4 +634,23 @@ public boolean hasMetadata() { public boolean hasMetadata(String key) { return meta != null && meta.hasMetadata(key); } + + /** + * This can be overridden to provide an efficient quick check to + * see if this ItemStack has a specific key in its metadata store + * for a specific plugin, without actually unpacking the ItemMeta object. + *

+ * Use this in place of getItemMeta().hasMetadata("field", plugin) for + * simple first-pass checks for data, if you don't necessarily need to + * unpack the data. + *

+ * The default implementation defers to ItemMeta. + * + * @param key The String key to check for + * @param plugin The Plugin for which to check for data + * @return True if getItemMeta().hasMetadata(key) + */ + public boolean hasMetadata(String key, Plugin plugin) { + return meta != null && meta.hasMetadata(key, plugin); + } } diff --git a/src/main/java/org/bukkit/inventory/meta/ItemMeta.java b/src/main/java/org/bukkit/inventory/meta/ItemMeta.java index d8ae772911..db91757c3a 100644 --- a/src/main/java/org/bukkit/inventory/meta/ItemMeta.java +++ b/src/main/java/org/bukkit/inventory/meta/ItemMeta.java @@ -7,6 +7,7 @@ import org.bukkit.configuration.serialization.ConfigurationSerializable; import org.bukkit.enchantments.Enchantment; import org.bukkit.metadata.Metadatable; +import org.bukkit.plugin.Plugin; /** * This type represents the storage mechanism for auxiliary item data. @@ -76,6 +77,17 @@ public interface ItemMeta extends Cloneable, ConfigurationSerializable, Metadata */ public boolean hasMetadata(); + /** + * Check to see if the Metadatable store contains a specific key + * for a specific Plugin. + * + * @param key The String key to check for + * @param plugin The Plugin for which to check for data + * @return True if the specified key is registered in this store + * for the specified Plugin + */ + public boolean hasMetadata(String key, Plugin plugin); + /** * Checks for the existence of any enchantments. * From 5998742f9619133b42ec8e147dc20834b0d26e78 Mon Sep 17 00:00:00 2001 From: Nathan Wolf Date: Mon, 19 May 2014 21:04:28 -0700 Subject: [PATCH 06/11] Add ItemMeta.getMetadata(String, Plugin) I think this is a good fit here as an extension to Metadatable, the more common use case is for a Plugin to want to retrieve its own data. --- .../java/org/bukkit/inventory/meta/ItemMeta.java | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/bukkit/inventory/meta/ItemMeta.java b/src/main/java/org/bukkit/inventory/meta/ItemMeta.java index db91757c3a..67b37065ed 100644 --- a/src/main/java/org/bukkit/inventory/meta/ItemMeta.java +++ b/src/main/java/org/bukkit/inventory/meta/ItemMeta.java @@ -6,6 +6,7 @@ import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.serialization.ConfigurationSerializable; import org.bukkit.enchantments.Enchantment; +import org.bukkit.metadata.MetadataValue; import org.bukkit.metadata.Metadatable; import org.bukkit.plugin.Plugin; @@ -81,13 +82,22 @@ public interface ItemMeta extends Cloneable, ConfigurationSerializable, Metadata * Check to see if the Metadatable store contains a specific key * for a specific Plugin. * - * @param key The String key to check for - * @param plugin The Plugin for which to check for data - * @return True if the specified key is registered in this store + * @param key the String key to check for + * @param plugin the Plugin for which to check for data + * @return true if the specified key is registered in this store * for the specified Plugin */ public boolean hasMetadata(String key, Plugin plugin); + /** + * Return a single metadata value for a given key and Plugin. + * + * @param metadataKey the unique metadata key being sought + * @param owningPlugin the plugin that owns the data being sought + * @return the requested value, or null if not found + */ + public MetadataValue getMetadata(String metadataKey, Plugin owningPlugin); + /** * Checks for the existence of any enchantments. * From 9aeeb63ab83616142f441be9971121a084e5ff61 Mon Sep 17 00:00:00 2001 From: Nathan Wolf Date: Wed, 21 May 2014 20:08:18 -0700 Subject: [PATCH 07/11] Remove the ItemStack.hasMetadata method There is no longer an efficient way to perform this check, and I don't believe there was a valid use case for its existence in the API in the first place. If a Plugin wants to interrogate for data, it should be doing so with a specific key. --- .../java/org/bukkit/inventory/ItemStack.java | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/src/main/java/org/bukkit/inventory/ItemStack.java b/src/main/java/org/bukkit/inventory/ItemStack.java index 2496ca4170..dd990aa2b6 100644 --- a/src/main/java/org/bukkit/inventory/ItemStack.java +++ b/src/main/java/org/bukkit/inventory/ItemStack.java @@ -602,22 +602,6 @@ private boolean setItemMeta0(ItemMeta itemMeta, Material material) { return true; } - /** - * This can be overridden to provide an efficient quick check to - * see if this ItemStack has any Metadata in - * its ItemMeta store, without actually unpacking the ItemMeta object. - *

- * Use this in place of getItemMeta().hasMetadata() for simple first-pass - * checks for data, if you don't necessarily need to unpack the data. - *

- * The default implementation defers to ItemMeta. - * - * @return True if getItemMeta().hasMetadata() - */ - public boolean hasMetadata() { - return meta != null && meta.hasMetadata(); - } - /** * This can be overridden to provide an efficient quick check to * see if this ItemStack has a specific key in its metadata store, From 6efa7b2ab2a65734f7ff92193967559a26f4cad4 Mon Sep 17 00:00:00 2001 From: Nathan Wolf Date: Wed, 21 May 2014 21:39:45 -0700 Subject: [PATCH 08/11] Add ItemMeta.set/hasGlowEffect. Adds BUKKIT-4767 --- .../org/bukkit/inventory/meta/ItemMeta.java | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/main/java/org/bukkit/inventory/meta/ItemMeta.java b/src/main/java/org/bukkit/inventory/meta/ItemMeta.java index 67b37065ed..aa3cc8f7c8 100644 --- a/src/main/java/org/bukkit/inventory/meta/ItemMeta.java +++ b/src/main/java/org/bukkit/inventory/meta/ItemMeta.java @@ -159,6 +159,23 @@ public interface ItemMeta extends Cloneable, ConfigurationSerializable, Metadata */ boolean hasConflictingEnchant(Enchantment ench); + /** + * See if this item is glowing for any reason. + * This could be due to enchantments, or to having its gow effect set with setGlowEffect(true) + * + * @return true if this item is glowing + */ + boolean hasGlowEffect(); + + /** + * Force this item to glow, or remove an item's glow. + * + * Glow can only be removed this way if there are no enchantments on the item. + * + * @param glow if true, a visual glow effect will be added to the item, effect removed if false + */ + void setGlowEffect(boolean glow); + @SuppressWarnings("javadoc") ItemMeta clone(); } From a53497b67e3449951aa60d9b1802af7e533852c6 Mon Sep 17 00:00:00 2001 From: Nathan Wolf Date: Wed, 21 May 2014 21:41:25 -0700 Subject: [PATCH 09/11] Clean up PersistentMetadataValue Extend MetadataValueAdapter directly for performance, and remove all the variant constructor types. They were meant to serve as a compile-time suggestion for what types are ok, but in practice it feels cluttered. --- .../metadata/PersistentMetadataValue.java | 135 +++--------------- 1 file changed, 20 insertions(+), 115 deletions(-) diff --git a/src/main/java/org/bukkit/metadata/PersistentMetadataValue.java b/src/main/java/org/bukkit/metadata/PersistentMetadataValue.java index 7701c99c6a..eb872a2251 100644 --- a/src/main/java/org/bukkit/metadata/PersistentMetadataValue.java +++ b/src/main/java/org/bukkit/metadata/PersistentMetadataValue.java @@ -8,137 +8,32 @@ /** * A PersistentMetadataValue is a special case metadata item that may - * only contain ConfigurationSerializeable Objects, Lists, Maps or + * only contain ConfigurationSerializable Objects, Lists, Maps or * basic Object types. *

- * This class extends FixedMetadataValue to do the work, and is - * primarily here to serve as a reminder that ItemMeta holds - * a slightly different form of Metadata. + * This class is primarily here to serve as a reminder that + * a persistent data store must hold serializable data. */ -public class PersistentMetadataValue extends FixedMetadataValue { +public class PersistentMetadataValue extends MetadataValueAdapter implements MetadataValue { /** - * Initializes a PersistentMetadataValue with a - * ConfigurationSerializable Object - * - * @param owningPlugin the {@link org.bukkit.plugin.Plugin} that created this metadata value - * @param value the value assigned to this metadata value - */ - public PersistentMetadataValue(Plugin owningPlugin, final ConfigurationSerializable value) { - super(owningPlugin, value); - } - - /** - * Initializes a PersistentMetadataValue with a String value. - * - * @param owningPlugin the {@link org.bukkit.plugin.Plugin} that created this metadata value - * @param value the value assigned to this metadata value - */ - public PersistentMetadataValue(Plugin owningPlugin, final String value) { - super(owningPlugin, value); - } - - /** - * Initializes a PersistentMetadataValue with an Integer value. - * - * @param owningPlugin the {@link org.bukkit.plugin.Plugin} that created this metadata value - * @param value the value assigned to this metadata value - */ - public PersistentMetadataValue(Plugin owningPlugin, final Integer value) { - super(owningPlugin, value); - } - - /** - * Initializes a PersistentMetadataValue with a Boolean value. - * - * @param owningPlugin the {@link org.bukkit.plugin.Plugin} that created this metadata value - * @param value the value assigned to this metadata value - */ - public PersistentMetadataValue(Plugin owningPlugin, final Boolean value) { - super(owningPlugin, value); - } - - /** - * Initializes a PersistentMetadataValue with a Long value. - * - * @param owningPlugin the {@link org.bukkit.plugin.Plugin} that created this metadata value - * @param value the value assigned to this metadata value - */ - public PersistentMetadataValue(Plugin owningPlugin, final Long value) { - super(owningPlugin, value); - } - - /** - * Initializes a PersistentMetadataValue with a Double value. - * - * @param owningPlugin the {@link org.bukkit.plugin.Plugin} that created this metadata value - * @param value the value assigned to this metadata value - */ - public PersistentMetadataValue(Plugin owningPlugin, final Double value) { - super(owningPlugin, value); - } - - /** - * Initializes a PersistentMetadataValue with a Short value. - * - * @param owningPlugin the {@link org.bukkit.plugin.Plugin} that created this metadata value - * @param value the value assigned to this metadata value + * Store the internal value that is represented by this value. + * This is expected to be one of a set of a valid serializable types. */ - public PersistentMetadataValue(Plugin owningPlugin, final Short value) { - super(owningPlugin, value); - } - - /** - * Initializes a PersistentMetadataValue with a Float value. - * - * @param owningPlugin the {@link org.bukkit.plugin.Plugin} that created this metadata value - * @param value the value assigned to this metadata value - */ - public PersistentMetadataValue(Plugin owningPlugin, final Float value) { - super(owningPlugin, value); - } - - /** - * Initializes a PersistentMetadataValue with a List value. - *

- * Note that the contents of the List must also be persistable, - * otherwise an IllegalArgumentException may be generated when - * the metadata store persists. - * - * @param owningPlugin the {@link org.bukkit.plugin.Plugin} that created this metadata value - * @param value the value assigned to this metadata value - */ - public PersistentMetadataValue(Plugin owningPlugin, final List value) { - super(owningPlugin, value); - } - - /** - * Initializes a PersistentMetadataValue with a Map value. - *

- * Note that the keys of the Map must be Strings, and the - * contents of the Map must be persistable, - * otherwise an IllegalArgumentException may be generated when - * the metadata store persists. - * - * @param owningPlugin the {@link org.bukkit.plugin.Plugin} that created this metadata value - * @param value the value assigned to this metadata value - */ - public PersistentMetadataValue(Plugin owningPlugin, final Map value) { - super(owningPlugin, value); - } + private final Object internalValue; /** * Initializes a PersistentMetadataValue with an Object value. *

* The Object must be one of the valid persistable object types. - * The other Constructor forms are preferred, this is here as a - * convenience method. + * Otherwise, an IllegalArgumentException will be thrown. * * @throws java.lang.IllegalArgumentException on non-persistable input * @param owningPlugin the {@link org.bukkit.plugin.Plugin} that created this metadata value * @param value the value assigned to this metadata value */ public PersistentMetadataValue(Plugin owningPlugin, final Object value) { - super(owningPlugin, value); + super(owningPlugin); + this.internalValue = value; if (!( value instanceof ConfigurationSerializable @@ -155,4 +50,14 @@ public PersistentMetadataValue(Plugin owningPlugin, final Object value) { throw new IllegalArgumentException("Invalid Object type for PersistentMetadataValue: " + value.getClass()); } } + + @Override + public Object value() { + return internalValue; + } + + @Override + public void invalidate() { + + } } From b8ed542b84e058e6c772c41d7103bb1a33cd9283 Mon Sep 17 00:00:00 2001 From: Nathan Wolf Date: Sun, 25 May 2014 14:13:52 -0700 Subject: [PATCH 10/11] Restructure PersistentMetadataValue Restore type-specific constructors, and add asList and asMap accessors. I did not add array accessors. --- .../java/org/bukkit/inventory/ItemStack.java | 14 +- .../metadata/PersistentMetadataValue.java | 148 +++++++++++++++--- 2 files changed, 135 insertions(+), 27 deletions(-) diff --git a/src/main/java/org/bukkit/inventory/ItemStack.java b/src/main/java/org/bukkit/inventory/ItemStack.java index dd990aa2b6..69373e74d9 100644 --- a/src/main/java/org/bukkit/inventory/ItemStack.java +++ b/src/main/java/org/bukkit/inventory/ItemStack.java @@ -603,14 +603,12 @@ private boolean setItemMeta0(ItemMeta itemMeta, Material material) { } /** - * This can be overridden to provide an efficient quick check to - * see if this ItemStack has a specific key in its metadata store, + * This may provide a more efficient check to see if this ItemStack + * has a specific key in its metadata store, * without actually unpacking the ItemMeta object. *

* Use this in place of getItemMeta().hasMetadata("field") for simple first-pass * checks for data, if you don't necessarily need to unpack the data. - *

- * The default implementation defers to ItemMeta. * * @param key The String key to check for * @return True if getItemMeta().hasMetadata(key) @@ -620,15 +618,13 @@ public boolean hasMetadata(String key) { } /** - * This can be overridden to provide an efficient quick check to - * see if this ItemStack has a specific key in its metadata store - * for a specific plugin, without actually unpacking the ItemMeta object. + * This may provide a more efficient check to see if this ItemStack + * has a specific key in its metadata store for a specific plugin, + * without actually unpacking the ItemMeta object. *

* Use this in place of getItemMeta().hasMetadata("field", plugin) for * simple first-pass checks for data, if you don't necessarily need to * unpack the data. - *

- * The default implementation defers to ItemMeta. * * @param key The String key to check for * @param plugin The Plugin for which to check for data diff --git a/src/main/java/org/bukkit/metadata/PersistentMetadataValue.java b/src/main/java/org/bukkit/metadata/PersistentMetadataValue.java index eb872a2251..e5d9a6e3bf 100644 --- a/src/main/java/org/bukkit/metadata/PersistentMetadataValue.java +++ b/src/main/java/org/bukkit/metadata/PersistentMetadataValue.java @@ -3,6 +3,7 @@ import org.bukkit.configuration.serialization.ConfigurationSerializable; import org.bukkit.plugin.Plugin; +import java.util.Collections; import java.util.List; import java.util.Map; @@ -21,34 +22,137 @@ public class PersistentMetadataValue extends MetadataValueAdapter implements Met */ private final Object internalValue; + /** + * Initializes a PersistentMetadataValue with a + * ConfigurationSerializable Object + * + * @param owningPlugin the {@link org.bukkit.plugin.Plugin} that created this metadata value + * @param value the value assigned to this metadata value + */ + public PersistentMetadataValue(Plugin owningPlugin, final ConfigurationSerializable value) { + this(owningPlugin, (Object)value); + } + + /** + * Initializes a PersistentMetadataValue with a String value. + * + * @param owningPlugin the {@link org.bukkit.plugin.Plugin} that created this metadata value + * @param value the value assigned to this metadata value + */ + public PersistentMetadataValue(Plugin owningPlugin, final String value) { + this(owningPlugin, (Object)value); + } + + /** + * Initializes a PersistentMetadataValue with an Integer value. + * + * @param owningPlugin the {@link org.bukkit.plugin.Plugin} that created this metadata value + * @param value the value assigned to this metadata value + */ + public PersistentMetadataValue(Plugin owningPlugin, final Integer value) { + this(owningPlugin, (Object)value); + } + + /** + * Initializes a PersistentMetadataValue with a Boolean value. + * + * @param owningPlugin the {@link org.bukkit.plugin.Plugin} that created this metadata value + * @param value the value assigned to this metadata value + */ + public PersistentMetadataValue(Plugin owningPlugin, final Boolean value) { + this(owningPlugin, (Object)value); + } + + /** + * Initializes a PersistentMetadataValue with a Long value. + * + * @param owningPlugin the {@link org.bukkit.plugin.Plugin} that created this metadata value + * @param value the value assigned to this metadata value + */ + public PersistentMetadataValue(Plugin owningPlugin, final Long value) { + this(owningPlugin, (Object)value); + } + + /** + * Initializes a PersistentMetadataValue with a Double value. + * + * @param owningPlugin the {@link org.bukkit.plugin.Plugin} that created this metadata value + * @param value the value assigned to this metadata value + */ + public PersistentMetadataValue(Plugin owningPlugin, final Double value) { + this(owningPlugin, (Object)value); + } + + /** + * Initializes a PersistentMetadataValue with a Short value. + * + * @param owningPlugin the {@link org.bukkit.plugin.Plugin} that created this metadata value + * @param value the value assigned to this metadata value + */ + public PersistentMetadataValue(Plugin owningPlugin, final Short value) { + this(owningPlugin, (Object)value); + } + + /** + * Initializes a PersistentMetadataValue with a Byte value. + * + * @param owningPlugin the {@link org.bukkit.plugin.Plugin} that created this metadata value + * @param value the value assigned to this metadata value + */ + public PersistentMetadataValue(Plugin owningPlugin, final Byte value) { + this(owningPlugin, (Object)value); + } + + /** + * Initializes a PersistentMetadataValue with a Float value. + * + * @param owningPlugin the {@link org.bukkit.plugin.Plugin} that created this metadata value + * @param value the value assigned to this metadata value + */ + public PersistentMetadataValue(Plugin owningPlugin, final Float value) { + this(owningPlugin, (Object)value); + } + + /** + * Initializes a PersistentMetadataValue with a List value. + *

+ * Note that the contents of the List must also be persistable, + * otherwise an IllegalArgumentException may be generated when + * the metadata store persists. + * + * @param owningPlugin the {@link org.bukkit.plugin.Plugin} that created this metadata value + * @param value the value assigned to this metadata value + */ + public PersistentMetadataValue(Plugin owningPlugin, final List value) { + this(owningPlugin, (Object)value); + } + + /** + * Initializes a PersistentMetadataValue with a Map value. + *

+ * Note that the keys of the Map must be Strings, and the + * contents of the Map must be persistable, + * otherwise an IllegalArgumentException may be generated when + * the metadata store persists. + * + * @param owningPlugin the {@link org.bukkit.plugin.Plugin} that created this metadata value + * @param value the value assigned to this metadata value + */ + public PersistentMetadataValue(Plugin owningPlugin, final Map value) { + this(owningPlugin, (Object)value); + } + /** * Initializes a PersistentMetadataValue with an Object value. *

* The Object must be one of the valid persistable object types. - * Otherwise, an IllegalArgumentException will be thrown. * - * @throws java.lang.IllegalArgumentException on non-persistable input * @param owningPlugin the {@link org.bukkit.plugin.Plugin} that created this metadata value * @param value the value assigned to this metadata value */ - public PersistentMetadataValue(Plugin owningPlugin, final Object value) { + private PersistentMetadataValue(Plugin owningPlugin, final Object value) { super(owningPlugin); this.internalValue = value; - - if (!( - value instanceof ConfigurationSerializable - || value instanceof String - || value instanceof Integer - || value instanceof Double - || value instanceof Long - || value instanceof Boolean - || value instanceof Short - || value instanceof Float - || value instanceof Map - || value instanceof List - )) { - throw new IllegalArgumentException("Invalid Object type for PersistentMetadataValue: " + value.getClass()); - } } @Override @@ -60,4 +164,12 @@ public Object value() { public void invalidate() { } + + public List asList() { + return internalValue instanceof List ? (List)internalValue : Collections.emptyList(); + } + + public Map asMap() { + return internalValue instanceof Map ? (Map)internalValue : Collections.emptyMap(); + } } From 3f49f5daecb0c45a0e8003451e87f3c60a1abd30 Mon Sep 17 00:00:00 2001 From: Nathan Wolf Date: Fri, 15 Aug 2014 10:39:18 -0700 Subject: [PATCH 11/11] Add ItemMeta.setMetadata method --- src/main/java/org/bukkit/inventory/meta/ItemMeta.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/main/java/org/bukkit/inventory/meta/ItemMeta.java b/src/main/java/org/bukkit/inventory/meta/ItemMeta.java index aa3cc8f7c8..4b5b3a4a3b 100644 --- a/src/main/java/org/bukkit/inventory/meta/ItemMeta.java +++ b/src/main/java/org/bukkit/inventory/meta/ItemMeta.java @@ -98,6 +98,14 @@ public interface ItemMeta extends Cloneable, ConfigurationSerializable, Metadata */ public MetadataValue getMetadata(String metadataKey, Plugin owningPlugin); + /** + * Set a MetadataValue for a given key. + * + * @param metadataKey A unique key to identify this metadata. + * @param newMetadataValue The metadata value to apply. + */ + public void setMetadata(String metadataKey, MetadataValue newMetadataValue); + /** * Checks for the existence of any enchantments. *