Fork of Poseidon providing Bukkit #1060 to older Beta versions (b1.0-b1.7.3)
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}