Bukkit-API  1.7.9-R0.2
The inofficial Bukkit-API
SimpleServicesManager.java
1 package org.bukkit.plugin;
2 
3 import org.bukkit.Bukkit;
6 
7 import com.google.common.collect.ImmutableList;
8 import com.google.common.collect.ImmutableSet;
9 
10 import java.util.ArrayList;
11 import java.util.Collections;
12 import java.util.HashMap;
13 import java.util.Iterator;
14 import java.util.Map;
15 import java.util.List;
16 import java.util.NoSuchElementException;
17 import java.util.Set;
18 
19 /**
20  * A simple services manager.
21  */
22 public class SimpleServicesManager implements ServicesManager {
23 
24  /**
25  * Map of providers.
26  */
27  private final Map<Class<?>, List<RegisteredServiceProvider<?>>> providers = new HashMap<Class<?>, List<RegisteredServiceProvider<?>>>();
28 
29  /**
30  * Register a provider of a service.
31  *
32  * @param <T> Provider
33  * @param service service class
34  * @param provider provider to register
35  * @param plugin plugin with the provider
36  * @param priority priority of the provider
37  */
38  public <T> void register(Class<T> service, T provider, Plugin plugin, ServicePriority priority) {
39  RegisteredServiceProvider<T> registeredProvider = null;
40  synchronized (providers) {
41  List<RegisteredServiceProvider<?>> registered = providers.get(service);
42  if (registered == null) {
43  registered = new ArrayList<RegisteredServiceProvider<?>>();
44  providers.put(service, registered);
45  }
46 
47  registeredProvider = new RegisteredServiceProvider<T>(service, provider, priority, plugin);
48 
49  // Insert the provider into the collection, much more efficient big O than sort
50  int position = Collections.binarySearch(registered, registeredProvider);
51  if (position < 0) {
52  registered.add(-(position + 1), registeredProvider);
53  } else {
54  registered.add(position, registeredProvider);
55  }
56 
57  }
58  Bukkit.getServer().getPluginManager().callEvent(new ServiceRegisterEvent(registeredProvider));
59  }
60 
61  /**
62  * Unregister all the providers registered by a particular plugin.
63  *
64  * @param plugin The plugin
65  */
66  public void unregisterAll(Plugin plugin) {
67  ArrayList<ServiceUnregisterEvent> unregisteredEvents = new ArrayList<ServiceUnregisterEvent>();
68  synchronized (providers) {
69  Iterator<Map.Entry<Class<?>, List<RegisteredServiceProvider<?>>>> it = providers.entrySet().iterator();
70 
71  try {
72  while (it.hasNext()) {
73  Map.Entry<Class<?>, List<RegisteredServiceProvider<?>>> entry = it.next();
74  Iterator<RegisteredServiceProvider<?>> it2 = entry.getValue().iterator();
75 
76  try {
77  // Removed entries that are from this plugin
78 
79  while (it2.hasNext()) {
80  RegisteredServiceProvider<?> registered = it2.next();
81 
82  if (registered.getPlugin().equals(plugin)) {
83  it2.remove();
84  unregisteredEvents.add(new ServiceUnregisterEvent(registered));
85  }
86  }
87  } catch (NoSuchElementException e) { // Why does Java suck
88  }
89 
90  // Get rid of the empty list
91  if (entry.getValue().size() == 0) {
92  it.remove();
93  }
94  }
95  } catch (NoSuchElementException e) {}
96  }
97  for (ServiceUnregisterEvent event : unregisteredEvents) {
99  }
100  }
101 
102  /**
103  * Unregister a particular provider for a particular service.
104  *
105  * @param service The service interface
106  * @param provider The service provider implementation
107  */
108  public void unregister(Class<?> service, Object provider) {
109  ArrayList<ServiceUnregisterEvent> unregisteredEvents = new ArrayList<ServiceUnregisterEvent>();
110  synchronized (providers) {
111  Iterator<Map.Entry<Class<?>, List<RegisteredServiceProvider<?>>>> it = providers.entrySet().iterator();
112 
113  try {
114  while (it.hasNext()) {
115  Map.Entry<Class<?>, List<RegisteredServiceProvider<?>>> entry = it.next();
116 
117  // We want a particular service
118  if (entry.getKey() != service) {
119  continue;
120  }
121 
122  Iterator<RegisteredServiceProvider<?>> it2 = entry.getValue().iterator();
123 
124  try {
125  // Removed entries that are from this plugin
126 
127  while (it2.hasNext()) {
128  RegisteredServiceProvider<?> registered = it2.next();
129 
130  if (registered.getProvider() == provider) {
131  it2.remove();
132  unregisteredEvents.add(new ServiceUnregisterEvent(registered));
133  }
134  }
135  } catch (NoSuchElementException e) { // Why does Java suck
136  }
137 
138  // Get rid of the empty list
139  if (entry.getValue().size() == 0) {
140  it.remove();
141  }
142  }
143  } catch (NoSuchElementException e) {}
144  }
145  for (ServiceUnregisterEvent event : unregisteredEvents) {
147  }
148  }
149 
150  /**
151  * Unregister a particular provider.
152  *
153  * @param provider The service provider implementation
154  */
155  public void unregister(Object provider) {
156  ArrayList<ServiceUnregisterEvent> unregisteredEvents = new ArrayList<ServiceUnregisterEvent>();
157  synchronized (providers) {
158  Iterator<Map.Entry<Class<?>, List<RegisteredServiceProvider<?>>>> it = providers.entrySet().iterator();
159 
160  try {
161  while (it.hasNext()) {
162  Map.Entry<Class<?>, List<RegisteredServiceProvider<?>>> entry = it.next();
163  Iterator<RegisteredServiceProvider<?>> it2 = entry.getValue().iterator();
164 
165  try {
166  // Removed entries that are from this plugin
167 
168  while (it2.hasNext()) {
169  RegisteredServiceProvider<?> registered = it2.next();
170 
171  if (registered.getProvider().equals(provider)) {
172  it2.remove();
173  unregisteredEvents.add(new ServiceUnregisterEvent(registered));
174  }
175  }
176  } catch (NoSuchElementException e) { // Why does Java suck
177  }
178 
179  // Get rid of the empty list
180  if (entry.getValue().size() == 0) {
181  it.remove();
182  }
183  }
184  } catch (NoSuchElementException e) {}
185  }
186  for (ServiceUnregisterEvent event : unregisteredEvents) {
188  }
189  }
190 
191  /**
192  * Queries for a provider. This may return if no provider has been
193  * registered for a service. The highest priority provider is returned.
194  *
195  * @param <T> The service interface
196  * @param service The service interface
197  * @return provider or null
198  */
199  public <T> T load(Class<T> service) {
200  synchronized (providers) {
201  List<RegisteredServiceProvider<?>> registered = providers.get(service);
202 
203  if (registered == null) {
204  return null;
205  }
206 
207  // This should not be null!
208  return service.cast(registered.get(0).getProvider());
209  }
210  }
211 
212  /**
213  * Queries for a provider registration. This may return if no provider
214  * has been registered for a service.
215  *
216  * @param <T> The service interface
217  * @param service The service interface
218  * @return provider registration or null
219  */
220  @SuppressWarnings("unchecked")
221  public <T> RegisteredServiceProvider<T> getRegistration(Class<T> service) {
222  synchronized (providers) {
223  List<RegisteredServiceProvider<?>> registered = providers.get(service);
224 
225  if (registered == null) {
226  return null;
227  }
228 
229  // This should not be null!
230  return (RegisteredServiceProvider<T>) registered.get(0);
231  }
232  }
233 
234  /**
235  * Get registrations of providers for a plugin.
236  *
237  * @param plugin The plugin
238  * @return provider registration or null
239  */
240  public List<RegisteredServiceProvider<?>> getRegistrations(Plugin plugin) {
241  ImmutableList.Builder<RegisteredServiceProvider<?>> ret = ImmutableList.<RegisteredServiceProvider<?>>builder();
242  synchronized (providers) {
243  for (List<RegisteredServiceProvider<?>> registered : providers.values()) {
244  for (RegisteredServiceProvider<?> provider : registered) {
245  if (provider.getPlugin().equals(plugin)) {
246  ret.add(provider);
247  }
248  }
249  }
250  }
251  return ret.build();
252  }
253 
254  /**
255  * Get registrations of providers for a service. The returned list is
256  * an unmodifiable copy.
257  *
258  * @param <T> The service interface
259  * @param service The service interface
260  * @return a copy of the list of registrations
261  */
262  @SuppressWarnings("unchecked")
263  public <T> List<RegisteredServiceProvider<T>> getRegistrations(Class<T> service) {
264  ImmutableList.Builder<RegisteredServiceProvider<T>> ret;
265  synchronized (providers) {
266  List<RegisteredServiceProvider<?>> registered = providers.get(service);
267 
268  if (registered == null) {
269  return ImmutableList.<RegisteredServiceProvider<T>>of();
270  }
271 
272  ret = ImmutableList.<RegisteredServiceProvider<T>>builder();
273 
274  for (RegisteredServiceProvider<?> provider : registered) {
275  ret.add((RegisteredServiceProvider<T>) provider);
276  }
277 
278  }
279  return ret.build();
280  }
281 
282  /**
283  * Get a list of known services. A service is known if it has registered
284  * providers for it.
285  *
286  * @return a copy of the set of known services
287  */
288  public Set<Class<?>> getKnownServices() {
289  synchronized (providers) {
290  return ImmutableSet.<Class<?>>copyOf(providers.keySet());
291  }
292  }
293 
294  /**
295  * Returns whether a provider has been registered for a service.
296  *
297  * @param <T> service
298  * @param service service to check
299  * @return true if and only if there are registered providers
300  */
301  public <T> boolean isProvidedFor(Class<T> service) {
302  synchronized (providers) {
303  return providers.containsKey(service);
304  }
305  }
306 }
PluginManager getPluginManager()
List< RegisteredServiceProvider<?> > getRegistrations(Plugin plugin)
static Server getServer()
Definition: Bukkit.java:50
void unregister(Class<?> service, Object provider)