1 package cz.cuni.amis.pogamut.base.utils.jmx;
2
3 import java.io.ObjectInputStream;
4 import java.util.HashSet;
5 import java.util.Iterator;
6 import java.util.Set;
7
8 import javax.management.Attribute;
9 import javax.management.AttributeList;
10 import javax.management.AttributeNotFoundException;
11 import javax.management.InstanceAlreadyExistsException;
12 import javax.management.InstanceNotFoundException;
13 import javax.management.IntrospectionException;
14 import javax.management.InvalidAttributeValueException;
15 import javax.management.ListenerNotFoundException;
16 import javax.management.MBeanException;
17 import javax.management.MBeanInfo;
18 import javax.management.MBeanRegistrationException;
19 import javax.management.MBeanServer;
20 import javax.management.MBeanServerFactory;
21 import javax.management.NotCompliantMBeanException;
22 import javax.management.NotificationFilter;
23 import javax.management.NotificationListener;
24 import javax.management.ObjectInstance;
25 import javax.management.ObjectName;
26 import javax.management.OperationsException;
27 import javax.management.QueryExp;
28 import javax.management.ReflectionException;
29 import javax.management.loading.ClassLoaderRepository;
30
31 import cz.cuni.amis.utils.HashCode;
32 import cz.cuni.amis.utils.NullCheck;
33 import cz.cuni.amis.utils.SafeEquals;
34
35
36
37
38
39
40
41
42
43 public class PogamutMBeanServer implements MBeanServer {
44
45 private static interface RegisteredListener {
46 public void register() throws InstanceNotFoundException;
47 public void unregister();
48 }
49
50 private static interface RegisteredMBean {
51 public void register() throws InstanceNotFoundException, InstanceAlreadyExistsException, MBeanRegistrationException, NotCompliantMBeanException;
52 public void unregister();
53 }
54
55 private class Listener1 implements RegisteredListener {
56
57 private ObjectName name;
58 private ObjectName listener;
59 private NotificationFilter filter;
60 private Object handback;
61
62 private int hashCode;
63
64 public Listener1(ObjectName name,
65 ObjectName listener, NotificationFilter filter, Object handback) {
66 this.name = name;
67 this.listener = listener;
68 this.filter = filter;
69 this.handback = handback;
70 HashCode hc = new HashCode();
71 hc.add(name);
72 hc.add(listener);
73 hc.add(filter);
74 hc.add(handback);
75 this.hashCode = hc.getHash();
76 }
77
78 @Override
79 public int hashCode() {
80 return hashCode;
81 }
82
83 public boolean equals(Object o) {
84 if (o == null) return false;
85 if (!(o instanceof Listener1)) return false;
86 Listener1 l = (Listener1)o;
87 return SafeEquals.equals(name, l.name) && SafeEquals.equals(listener, l.listener) && SafeEquals.equals(filter, l.filter) && SafeEquals.equals(handback, l.handback);
88 }
89
90 @Override
91 public void unregister() {
92 try {
93 innerRemoveNotificationListener(name, listener, filter, handback);
94 } catch (Exception e) {
95 }
96 }
97
98 public void register() throws InstanceNotFoundException {
99 innerAddNotificationListener(name, listener, filter, handback);
100 }
101
102 @Override
103 public String toString() {
104 return "Listener1[name=" + name + ", listener=" + listener + "]";
105 }
106
107 }
108
109 private class Listener2 implements RegisteredListener {
110
111 private ObjectName name;
112 private NotificationListener listener;
113 private NotificationFilter filter;
114 private Object handback;
115
116 private int hashCode;
117
118 public Listener2(ObjectName name, NotificationListener listener, NotificationFilter filter, Object handback) {
119 this.name = name;
120 this.listener = listener;
121 this.filter = filter;
122 this.handback = handback;
123 HashCode hc = new HashCode();
124 hc.add(name);
125 hc.add(listener);
126 hc.add(filter);
127 hc.add(handback);
128 this.hashCode = hc.getHash();
129 }
130
131 @Override
132 public int hashCode() {
133 return hashCode;
134 }
135
136 public boolean equals(Object o) {
137 if (o == null) return false;
138 if (!(o instanceof Listener2)) return false;
139 Listener2 l = (Listener2)o;
140 return SafeEquals.equals(name, l.name) && SafeEquals.equals(listener, l.listener) && SafeEquals.equals(filter, l.filter) && SafeEquals.equals(handback, l.handback);
141 }
142
143 @Override
144 public void unregister() {
145 try {
146 innerRemoveNotificationListener(name, listener, filter, handback);
147 } catch (Exception e) {
148 }
149 }
150
151 public void register() throws InstanceNotFoundException {
152 innerAddNotificationListener(name, listener, filter, handback);
153 }
154
155 @Override
156 public String toString() {
157 return "Listener2[name=" + name + ", listener=" + listener + "]";
158 }
159
160 }
161
162 private class MBean1 implements RegisteredMBean {
163
164 private ObjectName name;
165 private Object mBean;
166 private int hashCode;
167
168 public MBean1(ObjectName name, Object bean) {
169 this.name = name;
170 this.mBean = bean;
171 HashCode hc = new HashCode();
172 hc.add(name);
173 this.hashCode = hc.getHash();
174 }
175
176 @Override
177 public int hashCode() {
178 return hashCode;
179 }
180
181 @Override
182 public boolean equals(Object obj) {
183 if (obj == null) return false;
184 if (!(obj instanceof MBean1)) return false;
185 MBean1 mBean = (MBean1)obj;
186 return SafeEquals.equals(name, mBean.name);
187 }
188
189 @Override
190 public void register() throws InstanceNotFoundException, InstanceAlreadyExistsException, MBeanRegistrationException, NotCompliantMBeanException {
191 innerRegisterMBean(mBean, name);
192 }
193
194 @Override
195 public void unregister() {
196 try {
197 innerUnregisterMBean(name);
198 } catch (Exception e) {
199 }
200 }
201
202 @Override
203 public String toString() {
204 return "MBean1[name=" + name + ", object=" + mBean + "]";
205 }
206
207
208 }
209
210 private MBeanServer mbs;
211
212 private Set<RegisteredMBean> unregisteredMBeans = new HashSet<RegisteredMBean>();
213
214 private Set<RegisteredMBean> mBeans = new HashSet<RegisteredMBean>();
215
216 private Set<RegisteredListener> unregisteredListeners = new HashSet<RegisteredListener>();
217
218 private Set<RegisteredListener> listeners = new HashSet<RegisteredListener>();
219
220 private Set<Listener1> listeners1 = new HashSet<Listener1>();
221
222 private Set<Listener2> listeners2 = new HashSet<Listener2>();
223
224 public PogamutMBeanServer() {
225 this(MBeanServerFactory.createMBeanServer());
226 }
227
228 public PogamutMBeanServer(MBeanServer mBeanServer) {
229 this.mbs = mBeanServer;
230 NullCheck.check(this.mbs, "mBeanServer");
231 }
232
233 public synchronized void clearSaved() {
234 unregisteredMBeans.clear();
235 unregisteredListeners.clear();
236 }
237
238
239
240
241 public synchronized void unregisterAll() {
242 Iterator<RegisteredListener> iter1 = listeners.iterator();
243 while (iter1.hasNext()) {
244 RegisteredListener listener = iter1.next();
245 listener.unregister();
246 iter1.remove();
247 unregisteredListeners.add(listener);
248 }
249 Iterator<RegisteredMBean> iter2 = mBeans.iterator();
250 while (iter2.hasNext()) {
251 RegisteredMBean mBean = iter2.next();
252 mBean.unregister();
253 unregisteredMBeans.add(mBean);
254 iter2.remove();
255 }
256 }
257
258 public synchronized void registerAll() throws InstanceNotFoundException, InstanceAlreadyExistsException, MBeanRegistrationException, NotCompliantMBeanException {
259 Iterator<RegisteredMBean> iter1 = unregisteredMBeans.iterator();
260 while (iter1.hasNext()) {
261 RegisteredMBean mBean = iter1.next();
262 mBean.register();
263 iter1.remove();
264 mBeans.add(mBean);
265 }
266 Iterator<RegisteredListener> iter2 = unregisteredListeners.iterator();
267 while (iter2.hasNext()) {
268 RegisteredListener listener = iter2.next();
269 listener.register();
270 iter2.remove();
271 if (listener instanceof Listener1) {
272 listeners1.add((Listener1) listener);
273 } else {
274 listeners2.add((Listener2) listener);
275 }
276 }
277 }
278
279 @Override
280 public synchronized void addNotificationListener(ObjectName name, NotificationListener listener, NotificationFilter filter,
281 Object handback) throws InstanceNotFoundException {
282 mbs.addNotificationListener(name, listener, filter, handback);
283 Listener2 l = new Listener2(name, listener, filter, handback);
284 listeners.add(l);
285 listeners2.add(l);
286 }
287
288 private synchronized void innerAddNotificationListener(ObjectName name, NotificationListener listener, NotificationFilter filter,
289 Object handback) throws InstanceNotFoundException {
290 mbs.addNotificationListener(name, listener, filter, handback);
291 }
292
293 @Override
294 public synchronized void addNotificationListener(ObjectName name, ObjectName listener,
295 NotificationFilter filter, Object handback)
296 throws InstanceNotFoundException {
297 mbs.addNotificationListener(name, listener, filter, handback);
298 Listener1 l = new Listener1(name, listener, filter, handback);
299 listeners.add(l);
300 listeners1.add(l);
301 }
302
303 private synchronized void innerAddNotificationListener(ObjectName name, ObjectName listener,
304 NotificationFilter filter, Object handback)
305 throws InstanceNotFoundException {
306 mbs.addNotificationListener(name, listener, filter, handback);
307 }
308
309 @Override
310 public synchronized ObjectInstance createMBean(String className, ObjectName name)
311 throws ReflectionException, InstanceAlreadyExistsException,
312 MBeanRegistrationException, MBeanException,
313 NotCompliantMBeanException {
314 throw new UnsupportedOperationException("Not supported by PogamutMBeanServer yet...");
315 }
316
317 @Override
318 public synchronized ObjectInstance createMBean(String className, ObjectName name,
319 ObjectName loaderName) throws ReflectionException,
320 InstanceAlreadyExistsException, MBeanRegistrationException,
321 MBeanException, NotCompliantMBeanException,
322 InstanceNotFoundException {
323 throw new UnsupportedOperationException("Not supported by PogamutMBeanServer yet...");
324 }
325
326 @Override
327 public synchronized ObjectInstance createMBean(String className, ObjectName name,
328 Object[] params, String[] signature) throws ReflectionException,
329 InstanceAlreadyExistsException, MBeanRegistrationException,
330 MBeanException, NotCompliantMBeanException {
331 throw new UnsupportedOperationException("Not supported by PogamutMBeanServer yet...");
332 }
333
334 @Override
335 public synchronized ObjectInstance createMBean(String className, ObjectName name,
336 ObjectName loaderName, Object[] params, String[] signature)
337 throws ReflectionException, InstanceAlreadyExistsException,
338 MBeanRegistrationException, MBeanException,
339 NotCompliantMBeanException, InstanceNotFoundException {
340 throw new UnsupportedOperationException("Not supported by PogamutMBeanServer yet...");
341 }
342
343 @Deprecated
344 @Override
345 public ObjectInputStream deserialize(ObjectName name, byte[] data)
346 throws InstanceNotFoundException, OperationsException {
347 return mbs.deserialize(name, data);
348 }
349
350 @Deprecated
351 @Override
352 public ObjectInputStream deserialize(String className, byte[] data)
353 throws OperationsException, ReflectionException {
354 return mbs.deserialize(className, data);
355 }
356
357 @Deprecated
358 @Override
359 public ObjectInputStream deserialize(String className,
360 ObjectName loaderName, byte[] data)
361 throws InstanceNotFoundException, OperationsException,
362 ReflectionException {
363 return mbs.deserialize(className, loaderName, data);
364 }
365
366 @Override
367 public Object getAttribute(ObjectName name, String attribute)
368 throws MBeanException, AttributeNotFoundException,
369 InstanceNotFoundException, ReflectionException {
370 return mbs.getAttribute(name, attribute);
371 }
372
373 @Override
374 public AttributeList getAttributes(ObjectName name, String[] attributes)
375 throws InstanceNotFoundException, ReflectionException {
376 return mbs.getAttributes(name, attributes);
377 }
378
379 @Override
380 public ClassLoader getClassLoader(ObjectName loaderName)
381 throws InstanceNotFoundException {
382 return mbs.getClassLoader(loaderName);
383 }
384
385 @Override
386 public ClassLoader getClassLoaderFor(ObjectName mbeanName)
387 throws InstanceNotFoundException {
388 return mbs.getClassLoaderFor(mbeanName);
389 }
390
391 @Override
392 public ClassLoaderRepository getClassLoaderRepository() {
393 return mbs.getClassLoaderRepository();
394 }
395
396 @Override
397 public String getDefaultDomain() {
398 return mbs.getDefaultDomain();
399 }
400
401 @Override
402 public String[] getDomains() {
403 return mbs.getDomains();
404 }
405
406 @Override
407 public Integer getMBeanCount() {
408 return mbs.getMBeanCount();
409 }
410
411 @Override
412 public MBeanInfo getMBeanInfo(ObjectName name)
413 throws InstanceNotFoundException, IntrospectionException,
414 ReflectionException {
415 return mbs.getMBeanInfo(name);
416 }
417
418 @Override
419 public ObjectInstance getObjectInstance(ObjectName name)
420 throws InstanceNotFoundException {
421 return mbs.getObjectInstance(name);
422 }
423
424 @Override
425 public Object instantiate(String className) throws ReflectionException,
426 MBeanException {
427 return mbs.instantiate(className);
428 }
429
430 @Override
431 public Object instantiate(String className, ObjectName loaderName)
432 throws ReflectionException, MBeanException,
433 InstanceNotFoundException {
434 return mbs.instantiate(className, loaderName);
435 }
436
437 @Override
438 public Object instantiate(String className, Object[] params,
439 String[] signature) throws ReflectionException, MBeanException {
440 return mbs.instantiate(className, params, signature);
441 }
442
443 @Override
444 public Object instantiate(String className, ObjectName loaderName,
445 Object[] params, String[] signature) throws ReflectionException,
446 MBeanException, InstanceNotFoundException {
447 return mbs.instantiate(className, loaderName, params, signature);
448 }
449
450 @Override
451 public Object invoke(ObjectName name, String operationName,
452 Object[] params, String[] signature)
453 throws InstanceNotFoundException, MBeanException,
454 ReflectionException {
455 return mbs.invoke(name, operationName, params, signature);
456 }
457
458 @Override
459 public boolean isInstanceOf(ObjectName name, String className)
460 throws InstanceNotFoundException {
461 return mbs.isInstanceOf(name, className);
462 }
463
464 @Override
465 public boolean isRegistered(ObjectName name) {
466 return mbs.isRegistered(name);
467 }
468
469 @Override
470 public Set<ObjectInstance> queryMBeans(ObjectName name, QueryExp query) {
471 return mbs.queryMBeans(name, query);
472 }
473
474 @Override
475 public Set<ObjectName> queryNames(ObjectName name, QueryExp query) {
476 return mbs.queryNames(name, query);
477 }
478
479 @Override
480 public synchronized ObjectInstance registerMBean(Object object, ObjectName name)
481 throws InstanceAlreadyExistsException, MBeanRegistrationException,
482 NotCompliantMBeanException {
483 ObjectInstance obj = mbs.registerMBean(object, name);
484 mBeans.add(new MBean1(name, object));
485 unregisteredMBeans.remove(new MBean1(name, object));
486 return obj;
487 }
488
489 private synchronized ObjectInstance innerRegisterMBean(Object object, ObjectName name)
490 throws InstanceAlreadyExistsException, MBeanRegistrationException,
491 NotCompliantMBeanException {
492 return mbs.registerMBean(object, name);
493 }
494
495 @Override
496 public synchronized void removeNotificationListener(ObjectName name, ObjectName listener)
497 throws InstanceNotFoundException, ListenerNotFoundException {
498 mbs.removeNotificationListener(name, listener);
499
500
501 Iterator<Listener1> iter = listeners1.iterator();
502 while(iter.hasNext()) {
503 Listener1 l = iter.next();
504 if (SafeEquals.equals(name, l.name) && SafeEquals.equals(listener, l.listener)) {
505 listeners.remove(l);
506 unregisteredListeners.remove(l);
507 iter.remove();
508 }
509 }
510 }
511
512 @Override
513 public synchronized void removeNotificationListener(ObjectName name,
514 NotificationListener listener) throws InstanceNotFoundException,
515 ListenerNotFoundException {
516 mbs.removeNotificationListener(name, listener);
517
518
519 Iterator<Listener2> iter = listeners2.iterator();
520 while(iter.hasNext()) {
521 Listener2 l = iter.next();
522 if (SafeEquals.equals(name, l.name) && SafeEquals.equals(listener, l.listener)) {
523 listeners.remove(l);
524 unregisteredListeners.remove(l);
525 iter.remove();
526 }
527 }
528 }
529
530 @Override
531 public synchronized void removeNotificationListener(ObjectName name, ObjectName listener, NotificationFilter filter, Object handback)
532 throws InstanceNotFoundException, ListenerNotFoundException {
533 mbs.removeNotificationListener(name, listener, filter, handback);
534 Listener1 l = new Listener1(name, listener, filter, handback);
535 listeners.remove(l);
536 listeners1.remove(l);
537 unregisteredListeners.remove(l);
538 }
539
540 private synchronized void innerRemoveNotificationListener(ObjectName name, ObjectName listener, NotificationFilter filter, Object handback)
541 throws InstanceNotFoundException, ListenerNotFoundException {
542 mbs.removeNotificationListener(name, listener, filter, handback);
543 }
544
545 @Override
546 public synchronized void removeNotificationListener(ObjectName name, NotificationListener listener, NotificationFilter filter, Object handback) throws InstanceNotFoundException,
547 ListenerNotFoundException {
548 mbs.removeNotificationListener(name, listener, filter, handback);
549 Listener2 l = new Listener2(name, listener, filter, handback);
550 listeners.remove(l);
551 listeners2.remove(l);
552 unregisteredListeners.remove(l);
553 }
554
555 private synchronized void innerRemoveNotificationListener(ObjectName name, NotificationListener listener, NotificationFilter filter, Object handback) throws InstanceNotFoundException,
556 ListenerNotFoundException {
557 mbs.removeNotificationListener(name, listener, filter, handback);
558 }
559
560 @Override
561 public void setAttribute(ObjectName name, Attribute attribute)
562 throws InstanceNotFoundException, AttributeNotFoundException,
563 InvalidAttributeValueException, MBeanException, ReflectionException {
564 mbs.setAttribute(name, attribute);
565 }
566
567 @Override
568 public AttributeList setAttributes(ObjectName name, AttributeList attributes)
569 throws InstanceNotFoundException, ReflectionException {
570 return mbs.setAttributes(name, attributes);
571 }
572
573 @Override
574 public synchronized void unregisterMBean(ObjectName name)
575 throws InstanceNotFoundException, MBeanRegistrationException {
576 mbs.unregisterMBean(name);
577 mBeans.remove(new MBean1(name, null));
578 unregisteredMBeans.remove(new MBean1(name, null));
579 }
580
581 private synchronized void innerUnregisterMBean(ObjectName name)
582 throws InstanceNotFoundException, MBeanRegistrationException {
583 mbs.unregisterMBean(name);
584 }
585
586 }