package org.bukkit.plugin; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.List; import java.util.NoSuchElementException; /** * A simple services manager. * * @author sk89q */ public class SimpleServicesManager implements ServicesManager { /** * Map of providers. */ private final Map, List>> providers = new HashMap, List>>(); /** * Register a provider of a service. * * @param Provider * @param service service class * @param provider provider to register * @param plugin plugin with the provider * @param priority priority of the provider */ public void register(Class service, T provider, Plugin plugin, ServicePriority priority) { synchronized (providers) { List> registered = providers.get(service); if (registered == null) { registered = new ArrayList>(); providers.put(service, registered); } registered.add(new RegisteredServiceProvider( service, provider, priority, plugin)); // Make sure that providers are in the right order in order // for priorities to work correctly Collections.sort(registered); } } /** * Unregister all the providers registered by a particular plugin. * * @param plugin */ public void unregisterAll(Plugin plugin) { synchronized (providers) { Iterator, List>>> it = providers.entrySet().iterator(); try { while (it.hasNext()) { Map.Entry, List>> entry = it.next(); Iterator> it2 = entry.getValue().iterator(); try { // Removed entries that are from this plugin while (it2.hasNext()) { if (it2.next().getPlugin() == plugin) { it2.remove(); } } } catch (NoSuchElementException e) { // Why does Java suck } // Get rid of the empty list if (entry.getValue().size() == 0) { it.remove(); } } } catch (NoSuchElementException e) { } } } /** * Unregister a particular provider for a particular service. * * @param service * @param provider */ public void unregister(Class service, Object provider) { synchronized (providers) { Iterator, List>>> it = providers.entrySet().iterator(); try { while (it.hasNext()) { Map.Entry, List>> entry = it.next(); // We want a particular service if (entry.getKey() != service) { continue; } Iterator> it2 = entry.getValue().iterator(); try { // Removed entries that are from this plugin while (it2.hasNext()) { if (it2.next().getProvider() == provider) { it2.remove(); } } } catch (NoSuchElementException e) { // Why does Java suck } // Get rid of the empty list if (entry.getValue().size() == 0) { it.remove(); } } } catch (NoSuchElementException e) { } } } /** * Unregister a particular provider. * * @param provider */ public void unregister(Object provider) { synchronized (providers) { Iterator, List>>> it = providers.entrySet().iterator(); try { while (it.hasNext()) { Map.Entry, List>> entry = it.next(); Iterator> it2 = entry.getValue().iterator(); try { // Removed entries that are from this plugin while (it2.hasNext()) { if (it2.next().getProvider() == provider) { it2.remove(); } } } catch (NoSuchElementException e) { // Why does Java suck } // Get rid of the empty list if (entry.getValue().size() == 0) { it.remove(); } } } catch (NoSuchElementException e) { } } } /** * Queries for a provider. This may return if no provider has been * registered for a service. The highest priority provider is returned. * * @param * @param service * @return provider or null */ @SuppressWarnings("unchecked") public T load(Class service) { synchronized (providers) { List> registered = providers.get(service); if (registered == null) { return null; } // This should not be null! return (T) registered.get(0).getProvider(); } } /** * Queries for a provider registration. This may return if no provider * has been registered for a service. * * @param * @param service * @return provider registration or null */ @SuppressWarnings("unchecked") public RegisteredServiceProvider getRegistration(Class service) { synchronized (providers) { List> registered = providers.get(service); if (registered == null) { return null; } // This should not be null! return (RegisteredServiceProvider) registered.get(0); } } /** * Get registrations of providers for a plugin. * * @param plugin * @return provider registration or null */ public List> getRegistrations(Plugin plugin) { synchronized (providers) { List> ret = new ArrayList>(); for (List> registered : providers.values()) { for (RegisteredServiceProvider provider : registered) { if (provider.getPlugin() == plugin) { ret.add(provider); } } } return ret; } } /** * Get registrations of providers for a service. The returned list is * unmodifiable. * * @param * @param service * @return list of registrations */ @SuppressWarnings("unchecked") public Collection> getRegistrations(Class service) { synchronized (providers) { List> registered = providers.get(service); if (registered == null) { return Collections.unmodifiableList( new ArrayList>()); } List> ret = new ArrayList>(); for (RegisteredServiceProvider provider : registered) { ret.add((RegisteredServiceProvider) provider); } return Collections.unmodifiableList(ret); } } /** * Get a list of known services. A service is known if it has registered * providers for it. * * @return list of known services */ public Collection> getKnownServices() { return Collections.unmodifiableSet(providers.keySet()); } /** * Returns whether a provider has been registered for a service. Do not * check this first only to call load(service) later, as that * would be a non-thread safe situation. * * @param service * @param service service to check * @return whether there has been a registered provider */ public boolean isProvidedFor(Class service) { return getRegistration(service) != null; } }