Skip to content

Instantly share code, notes, and snippets.

@crast
Last active December 15, 2015 07:29
Show Gist options
  • Save crast/5223292 to your computer and use it in GitHub Desktop.
Save crast/5223292 to your computer and use it in GitHub Desktop.
package org.bukkit.craftbukkit.metadata;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang.Validate;
import org.bukkit.metadata.MetadataProvider;
import org.bukkit.metadata.Metadatable;
import org.bukkit.plugin.Plugin;
/**
* Maintain a registry of classes to MetadataProviders.
* This is used as the place that metadata providers are registered and
* unregistered, and also where metadata stores get their provider data from.
*/
public class MetadataProviderMap {
/** Store the provider registry */
private static Map<Class<? extends Metadatable>, ProviderEntry<? extends Metadatable>> providers = new HashMap<Class<? extends Metadatable>, ProviderEntry<? extends Metadatable>>();
/**
* Get one of the entries in the map for a particular implementation class.
* @param clazz The class for which we want the entries.
* @return a mapping of keys to MetadataProviders.
*/
public static <T extends Metadatable> Collection<MetadataProvider<T>> getProviders(Class<T> clazz) {
return ensureEntry(clazz).getProviders();
}
/**
* Register a metadata provider.
* @param clazz The implementation class (scope) of this provider.
* @param plugin the plugin managing this.
* @param provider An appropriate generic provider.
*/
public static <T extends Metadatable> void register(Class<T> clazz, Plugin plugin, MetadataProvider<T> provider) {
Validate.notNull(clazz, "clazz cannot be null");
Validate.notNull(provider, "Provider cannot be null");
Validate.notNull(plugin, "Plugin cannot be null");
ensureEntry(clazz).register(plugin, provider);
}
/**
* Unregister a metadata provider.
* @param clazz The implementation class(scope).
* @param plugin the plugin unregistering this provider.
*/
public static <T extends Metadatable> void unregister(Class<T> clazz, Plugin plugin) {
Validate.notNull(clazz, "clazz cannot be null");
Validate.notNull(plugin, "Plugin cannot be null");
ensureEntry(clazz).unregister(plugin);
}
/**
* Clear all data belonging to a plugin.
* @param plugin the plugin whose data which we want to remove.
*/
public static void clearPluginData(Plugin plugin) {
for (ProviderEntry<?> entry : providers.values()) {
entry.unregister(plugin);
}
}
@SuppressWarnings("unchecked")
private static <T extends Metadatable> ProviderEntry<T> ensureEntry(Class<T> clazz) {
if (!providers.containsKey(clazz)) {
providers.put(clazz, new ProviderEntry<T>());
}
return (ProviderEntry<T>) providers.get(clazz);
}
}
class ProviderEntry<T extends Metadatable> {
private Map<Plugin, MetadataProvider<T>> entries = new HashMap<Plugin, MetadataProvider<T>>();
private List<MetadataProvider<T>> entryList = new ArrayList<MetadataProvider<T>>();
public void register(Plugin plugin, MetadataProvider<T> provider) {
entries.put(plugin, provider);
updateEntryList();
}
public void unregister(Plugin plugin) {
if (entries.remove(plugin) != null) {
updateEntryList();
}
}
private void updateEntryList() {
entryList.clear();
entryList.addAll(entries.values());
}
public Collection<MetadataProvider<T>> getProviders() {
return (Collection<MetadataProvider<T>>) entryList;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment