Fork of Poseidon providing Bukkit #1060 to older Beta versions (b1.0-b1.7.3)
at develop 271 lines 8.9 kB view raw
1package org.bukkit.plugin; 2 3import java.util.*; 4 5/** 6 * A simple services manager. 7 * 8 * @author sk89q 9 */ 10public class SimpleServicesManager implements ServicesManager { 11 12 /** 13 * Map of providers. 14 */ 15 private final Map<Class<?>, List<RegisteredServiceProvider<?>>> providers = new HashMap<Class<?>, List<RegisteredServiceProvider<?>>>(); 16 17 /** 18 * Register a provider of a service. 19 * 20 * @param <T> Provider 21 * @param service service class 22 * @param provider provider to register 23 * @param plugin plugin with the provider 24 * @param priority priority of the provider 25 */ 26 public <T> void register(Class<T> service, T provider, Plugin plugin, ServicePriority priority) { 27 28 synchronized (providers) { 29 List<RegisteredServiceProvider<?>> registered = providers.get(service); 30 31 if (registered == null) { 32 registered = new ArrayList<RegisteredServiceProvider<?>>(); 33 providers.put(service, registered); 34 } 35 36 registered.add(new RegisteredServiceProvider<T>(service, provider, priority, plugin)); 37 38 // Make sure that providers are in the right order in order 39 // for priorities to work correctly 40 Collections.sort(registered); 41 } 42 } 43 44 /** 45 * Unregister all the providers registered by a particular plugin. 46 * 47 * @param plugin 48 */ 49 public void unregisterAll(Plugin plugin) { 50 synchronized (providers) { 51 Iterator<Map.Entry<Class<?>, List<RegisteredServiceProvider<?>>>> it = providers.entrySet().iterator(); 52 53 try { 54 while (it.hasNext()) { 55 Map.Entry<Class<?>, List<RegisteredServiceProvider<?>>> entry = it.next(); 56 Iterator<RegisteredServiceProvider<?>> it2 = entry.getValue().iterator(); 57 58 try { 59 // Removed entries that are from this plugin 60 61 while (it2.hasNext()) { 62 if (it2.next().getPlugin() == plugin) { 63 it2.remove(); 64 } 65 } 66 } catch (NoSuchElementException e) { // Why does Java suck 67 } 68 69 // Get rid of the empty list 70 if (entry.getValue().size() == 0) { 71 it.remove(); 72 } 73 } 74 } catch (NoSuchElementException e) { 75 } 76 } 77 } 78 79 /** 80 * Unregister a particular provider for a particular service. 81 * 82 * @param service 83 * @param provider 84 */ 85 public void unregister(Class<?> service, Object provider) { 86 synchronized (providers) { 87 Iterator<Map.Entry<Class<?>, List<RegisteredServiceProvider<?>>>> it = providers.entrySet().iterator(); 88 89 try { 90 while (it.hasNext()) { 91 Map.Entry<Class<?>, List<RegisteredServiceProvider<?>>> entry = it.next(); 92 93 // We want a particular service 94 if (entry.getKey() != service) { 95 continue; 96 } 97 98 Iterator<RegisteredServiceProvider<?>> it2 = entry.getValue().iterator(); 99 100 try { 101 // Removed entries that are from this plugin 102 103 while (it2.hasNext()) { 104 if (it2.next().getProvider() == provider) { 105 it2.remove(); 106 } 107 } 108 } catch (NoSuchElementException e) { // Why does Java suck 109 } 110 111 // Get rid of the empty list 112 if (entry.getValue().size() == 0) { 113 it.remove(); 114 } 115 } 116 } catch (NoSuchElementException e) { 117 } 118 } 119 } 120 121 /** 122 * Unregister a particular provider. 123 * 124 * @param provider 125 */ 126 public void unregister(Object provider) { 127 synchronized (providers) { 128 Iterator<Map.Entry<Class<?>, List<RegisteredServiceProvider<?>>>> it = providers.entrySet().iterator(); 129 130 try { 131 while (it.hasNext()) { 132 Map.Entry<Class<?>, List<RegisteredServiceProvider<?>>> entry = it.next(); 133 Iterator<RegisteredServiceProvider<?>> it2 = entry.getValue().iterator(); 134 135 try { 136 // Removed entries that are from this plugin 137 138 while (it2.hasNext()) { 139 if (it2.next().getProvider() == provider) { 140 it2.remove(); 141 } 142 } 143 } catch (NoSuchElementException e) { // Why does Java suck 144 } 145 146 // Get rid of the empty list 147 if (entry.getValue().size() == 0) { 148 it.remove(); 149 } 150 } 151 } catch (NoSuchElementException e) { 152 } 153 } 154 } 155 156 /** 157 * Queries for a provider. This may return if no provider has been 158 * registered for a service. The highest priority provider is returned. 159 * 160 * @param <T> 161 * @param service 162 * @return provider or null 163 */ 164 @SuppressWarnings("unchecked") 165 public <T> T load(Class<T> service) { 166 synchronized (providers) { 167 List<RegisteredServiceProvider<?>> registered = providers.get(service); 168 169 if (registered == null) { 170 return null; 171 } 172 173 // This should not be null! 174 return (T) registered.get(0).getProvider(); 175 } 176 } 177 178 /** 179 * Queries for a provider registration. This may return if no provider 180 * has been registered for a service. 181 * 182 * @param <T> 183 * @param service 184 * @return provider registration or null 185 */ 186 @SuppressWarnings("unchecked") 187 public <T> RegisteredServiceProvider<T> getRegistration(Class<T> service) { 188 synchronized (providers) { 189 List<RegisteredServiceProvider<?>> registered = providers.get(service); 190 191 if (registered == null) { 192 return null; 193 } 194 195 // This should not be null! 196 return (RegisteredServiceProvider<T>) registered.get(0); 197 } 198 } 199 200 /** 201 * Get registrations of providers for a plugin. 202 * 203 * @param plugin 204 * @return provider registration or null 205 */ 206 public List<RegisteredServiceProvider<?>> getRegistrations(Plugin plugin) { 207 synchronized (providers) { 208 List<RegisteredServiceProvider<?>> ret = new ArrayList<RegisteredServiceProvider<?>>(); 209 210 for (List<RegisteredServiceProvider<?>> registered : providers.values()) { 211 for (RegisteredServiceProvider<?> provider : registered) { 212 if (provider.getPlugin() == plugin) { 213 ret.add(provider); 214 } 215 } 216 } 217 218 return ret; 219 } 220 } 221 222 /** 223 * Get registrations of providers for a service. The returned list is 224 * unmodifiable. 225 * 226 * @param <T> 227 * @param service 228 * @return list of registrations 229 */ 230 @SuppressWarnings("unchecked") 231 public <T> Collection<RegisteredServiceProvider<T>> getRegistrations(Class<T> service) { 232 synchronized (providers) { 233 List<RegisteredServiceProvider<?>> registered = providers.get(service); 234 235 if (registered == null) { 236 return Collections.unmodifiableList(new ArrayList<RegisteredServiceProvider<T>>()); 237 } 238 239 List<RegisteredServiceProvider<T>> ret = new ArrayList<RegisteredServiceProvider<T>>(); 240 241 for (RegisteredServiceProvider<?> provider : registered) { 242 ret.add((RegisteredServiceProvider<T>) provider); 243 } 244 245 return Collections.unmodifiableList(ret); 246 } 247 } 248 249 /** 250 * Get a list of known services. A service is known if it has registered 251 * providers for it. 252 * 253 * @return list of known services 254 */ 255 public Collection<Class<?>> getKnownServices() { 256 return Collections.unmodifiableSet(providers.keySet()); 257 } 258 259 /** 260 * Returns whether a provider has been registered for a service. Do not 261 * check this first only to call <code>load(service)</code> later, as that 262 * would be a non-thread safe situation. 263 * 264 * @param <T> service 265 * @param service service to check 266 * @return whether there has been a registered provider 267 */ 268 public <T> boolean isProvidedFor(Class<T> service) { 269 return getRegistration(service) != null; 270 } 271}