Bukkit  1.4.7-R1.0
 All Classes Namespaces Files Functions Variables Enumerator Pages
MetadataStoreBase.java
Go to the documentation of this file.
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, List<MetadataValue>> metadataMap = new HashMap<String, List<MetadataValue>>();
10  private WeakHashMap<T, Map<String, String>> disambiguationCache = new WeakHashMap<T, Map<String, String>>();
11 
28  public synchronized void setMetadata(T subject, String metadataKey, MetadataValue newMetadataValue) {
29  Validate.notNull(newMetadataValue, "Value cannot be null");
30  Validate.notNull(newMetadataValue.getOwningPlugin(), "Plugin cannot be null");
31  String key = cachedDisambiguate(subject, metadataKey);
32  if (!metadataMap.containsKey(key)) {
33  metadataMap.put(key, new ArrayList<MetadataValue>());
34  }
35  // we now have a list of subject's metadata for the given metadata key. If newMetadataValue's owningPlugin
36  // is found in this list, replace the value rather than add a new one.
37  List<MetadataValue> metadataList = metadataMap.get(key);
38  for (int i = 0; i < metadataList.size(); i++) {
39  if (metadataList.get(i).getOwningPlugin().equals(newMetadataValue.getOwningPlugin())) {
40  metadataList.set(i, newMetadataValue);
41  return;
42  }
43  }
44  // we didn't find a duplicate...add the new metadata value
45  metadataList.add(newMetadataValue);
46  }
47 
57  public synchronized List<MetadataValue> getMetadata(T subject, String metadataKey) {
58  String key = cachedDisambiguate(subject, metadataKey);
59  if (metadataMap.containsKey(key)) {
60  return Collections.unmodifiableList(metadataMap.get(key));
61  } else {
62  return Collections.emptyList();
63  }
64  }
65 
73  public synchronized boolean hasMetadata(T subject, String metadataKey) {
74  String key = cachedDisambiguate(subject, metadataKey);
75  return metadataMap.containsKey(key);
76  }
77 
87  public synchronized void removeMetadata(T subject, String metadataKey, Plugin owningPlugin) {
88  Validate.notNull(owningPlugin, "Plugin cannot be null");
89  String key = cachedDisambiguate(subject, metadataKey);
90  List<MetadataValue> metadataList = metadataMap.get(key);
91  if (metadataList == null) return;
92  for (int i = 0; i < metadataList.size(); i++) {
93  if (metadataList.get(i).getOwningPlugin().equals(owningPlugin)) {
94  metadataList.remove(i);
95  if (metadataList.isEmpty()) {
96  metadataMap.remove(key);
97  }
98  }
99  }
100  }
101 
110  public synchronized void invalidateAll(Plugin owningPlugin) {
111  Validate.notNull(owningPlugin, "Plugin cannot be null");
112  for (List<MetadataValue> values : metadataMap.values()) {
113  for (MetadataValue value : values) {
114  if (value.getOwningPlugin().equals(owningPlugin)) {
115  value.invalidate();
116  }
117  }
118  }
119  }
120 
131  private String cachedDisambiguate(T subject, String metadataKey) {
132  if (disambiguationCache.containsKey(subject) && disambiguationCache.get(subject).containsKey(metadataKey)) {
133  return disambiguationCache.get(subject).get(metadataKey);
134  } else {
135  if (!disambiguationCache.containsKey(subject)) {
136  disambiguationCache.put(subject, new HashMap<String, String>());
137  }
138  String disambiguation = disambiguate(subject, metadataKey);
139  disambiguationCache.get(subject).put(metadataKey, disambiguation);
140  return disambiguation;
141  }
142  }
143 
154  protected abstract String disambiguate(T subject, String metadataKey);
155 }