Bukkit-API  1.7.9-R0.2
The inofficial Bukkit-API
MetadataStoreBase.java
1 package org.bukkit.metadata;
2 
3 import org.apache.commons.lang.Validate;
4 import org.bukkit.plugin.Plugin;
5 
6 import java.util.*;
7 
8 public abstract class MetadataStoreBase<T> {
9  private Map<String, Map<Plugin, MetadataValue>> metadataMap = new HashMap<String, Map<Plugin, MetadataValue>>();
10 
11  /**
12  * Adds a metadata value to an object. Each metadata value is owned by a
13  * specific {@link Plugin}. If a plugin has already added a metadata value
14  * to an object, that value will be replaced with the value of {@code
15  * newMetadataValue}. Multiple plugins can set independent values for the
16  * same {@code metadataKey} without conflict.
17  * <p>
18  * Implementation note: I considered using a {@link
19  * java.util.concurrent.locks.ReadWriteLock} for controlling access to
20  * {@code metadataMap}, but decided that the added overhead wasn't worth
21  * the finer grained access control.
22  * <p>
23  * Bukkit is almost entirely single threaded so locking overhead shouldn't
24  * pose a problem.
25  *
26  * @param subject The object receiving the metadata.
27  * @param metadataKey A unique key to identify this metadata.
28  * @param newMetadataValue The metadata value to apply.
29  * @see MetadataStore#setMetadata(Object, String, MetadataValue)
30  * @throws IllegalArgumentException If value is null, or the owning plugin
31  * is null
32  */
33  public synchronized void setMetadata(T subject, String metadataKey, MetadataValue newMetadataValue) {
34  Validate.notNull(newMetadataValue, "Value cannot be null");
35  Plugin owningPlugin = newMetadataValue.getOwningPlugin();
36  Validate.notNull(owningPlugin, "Plugin cannot be null");
37  String key = disambiguate(subject, metadataKey);
38  Map<Plugin, MetadataValue> entry = metadataMap.get(key);
39  if (entry == null) {
40  entry = new WeakHashMap<Plugin, MetadataValue>(1);
41  metadataMap.put(key, entry);
42  }
43  entry.put(owningPlugin, newMetadataValue);
44  }
45 
46  /**
47  * Returns all metadata values attached to an object. If multiple
48  * have attached metadata, each will value will be included.
49  *
50  * @param subject the object being interrogated.
51  * @param metadataKey the unique metadata key being sought.
52  * @return A list of values, one for each plugin that has set the
53  * requested value.
54  * @see MetadataStore#getMetadata(Object, String)
55  */
56  public synchronized List<MetadataValue> getMetadata(T subject, String metadataKey) {
57  String key = disambiguate(subject, metadataKey);
58  if (metadataMap.containsKey(key)) {
59  Collection<MetadataValue> values = metadataMap.get(key).values();
60  return Collections.unmodifiableList(new ArrayList<MetadataValue>(values));
61  } else {
62  return Collections.emptyList();
63  }
64  }
65 
66  /**
67  * Tests to see if a metadata attribute has been set on an object.
68  *
69  * @param subject the object upon which the has-metadata test is
70  * performed.
71  * @param metadataKey the unique metadata key being queried.
72  * @return the existence of the metadataKey within subject.
73  */
74  public synchronized boolean hasMetadata(T subject, String metadataKey) {
75  String key = disambiguate(subject, metadataKey);
76  return metadataMap.containsKey(key);
77  }
78 
79  /**
80  * Removes a metadata item owned by a plugin from a subject.
81  *
82  * @param subject the object to remove the metadata from.
83  * @param metadataKey the unique metadata key identifying the metadata to
84  * remove.
85  * @param owningPlugin the plugin attempting to remove a metadata item.
86  * @see MetadataStore#removeMetadata(Object, String,
87  * org.bukkit.plugin.Plugin)
88  * @throws IllegalArgumentException If plugin is null
89  */
90  public synchronized void removeMetadata(T subject, String metadataKey, Plugin owningPlugin) {
91  Validate.notNull(owningPlugin, "Plugin cannot be null");
92  String key = disambiguate(subject, metadataKey);
93  Map<Plugin, MetadataValue> entry = metadataMap.get(key);
94  if (entry == null) {
95  return;
96  }
97 
98  entry.remove(owningPlugin);
99  if (entry.isEmpty()) {
100  metadataMap.remove(key);
101  }
102  }
103 
104  /**
105  * Invalidates all metadata in the metadata store that originates from the
106  * given plugin. Doing this will force each invalidated metadata item to
107  * be recalculated the next time it is accessed.
108  *
109  * @param owningPlugin the plugin requesting the invalidation.
110  * @see MetadataStore#invalidateAll(org.bukkit.plugin.Plugin)
111  * @throws IllegalArgumentException If plugin is null
112  */
113  public synchronized void invalidateAll(Plugin owningPlugin) {
114  Validate.notNull(owningPlugin, "Plugin cannot be null");
115  for (Map<Plugin, MetadataValue> values : metadataMap.values()) {
116  if (values.containsKey(owningPlugin)) {
117  values.get(owningPlugin).invalidate();
118  }
119  }
120  }
121 
122  /**
123  * Creates a unique name for the object receiving metadata by combining
124  * unique data from the subject with a metadataKey.
125  * <p>
126  * The name created must be globally unique for the given object and any
127  * two equivalent objects must generate the same unique name. For example,
128  * two Player objects must generate the same string if they represent the
129  * same player, even if the objects would fail a reference equality test.
130  *
131  * @param subject The object for which this key is being generated.
132  * @param metadataKey The name identifying the metadata value.
133  * @return a unique metadata key for the given subject.
134  */
135  protected abstract String disambiguate(T subject, String metadataKey);
136 }
abstract String disambiguate(T subject, String metadataKey)
synchronized void invalidateAll(Plugin owningPlugin)
synchronized void removeMetadata(T subject, String metadataKey, Plugin owningPlugin)
synchronized List< MetadataValue > getMetadata(T subject, String metadataKey)
synchronized boolean hasMetadata(T subject, String metadataKey)
synchronized void setMetadata(T subject, String metadataKey, MetadataValue newMetadataValue)