|
1 /* |
|
2 * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved. |
|
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
|
4 * |
|
5 * This code is free software; you can redistribute it and/or modify it |
|
6 * under the terms of the GNU General Public License version 2 only, as |
|
7 * published by the Free Software Foundation. Sun designates this |
|
8 * particular file as subject to the "Classpath" exception as provided |
|
9 * by Sun in the LICENSE file that accompanied this code. |
|
10 * |
|
11 * This code is distributed in the hope that it will be useful, but WITHOUT |
|
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
|
14 * version 2 for more details (a copy is included in the LICENSE file that |
|
15 * accompanied this code). |
|
16 * |
|
17 * You should have received a copy of the GNU General Public License version |
|
18 * 2 along with this work; if not, write to the Free Software Foundation, |
|
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
|
20 * |
|
21 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, |
|
22 * CA 95054 USA or visit www.sun.com if you need additional information or |
|
23 * have any questions. |
|
24 */ |
|
25 |
|
26 package com.sun.jmx.namespace; |
|
27 |
|
28 import com.sun.jmx.defaults.JmxProperties; |
|
29 import com.sun.jmx.mbeanserver.Util; |
|
30 import java.io.IOException; |
|
31 import java.lang.reflect.UndeclaredThrowableException; |
|
32 import java.util.Set; |
|
33 import java.util.logging.Level; |
|
34 import java.util.logging.Logger; |
|
35 |
|
36 import javax.management.Attribute; |
|
37 import javax.management.AttributeList; |
|
38 import javax.management.AttributeNotFoundException; |
|
39 import javax.management.InstanceAlreadyExistsException; |
|
40 import javax.management.InstanceNotFoundException; |
|
41 import javax.management.IntrospectionException; |
|
42 import javax.management.InvalidAttributeValueException; |
|
43 import javax.management.JMRuntimeException; |
|
44 import javax.management.ListenerNotFoundException; |
|
45 import javax.management.MBeanException; |
|
46 import javax.management.MBeanInfo; |
|
47 import javax.management.MBeanRegistrationException; |
|
48 import javax.management.MBeanServerConnection; |
|
49 import javax.management.MalformedObjectNameException; |
|
50 import javax.management.NotCompliantMBeanException; |
|
51 import javax.management.NotificationFilter; |
|
52 import javax.management.NotificationListener; |
|
53 import javax.management.ObjectInstance; |
|
54 import javax.management.ObjectName; |
|
55 import javax.management.QueryExp; |
|
56 import javax.management.ReflectionException; |
|
57 import javax.management.RuntimeMBeanException; |
|
58 import javax.management.RuntimeOperationsException; |
|
59 |
|
60 /** |
|
61 * A RoutingMBeanServerConnection wraps a MBeanServerConnection, defining |
|
62 * abstract methods that can be implemented by subclasses to rewrite |
|
63 * routing ObjectNames. It is used to implement |
|
64 * HandlerInterceptors (wrapping JMXNamespace instances) and routing |
|
65 * proxies (used to implement cd operations). |
|
66 * <p><b> |
|
67 * This API is a Sun internal API and is subject to changes without notice. |
|
68 * </b></p> |
|
69 * @since 1.7 |
|
70 */ |
|
71 public abstract class RoutingMBeanServerConnection<T extends MBeanServerConnection> |
|
72 implements MBeanServerConnection { |
|
73 |
|
74 /** |
|
75 * A logger for this class. |
|
76 **/ |
|
77 private static final Logger LOG = JmxProperties.NAMESPACE_LOGGER; |
|
78 |
|
79 /** |
|
80 * Creates a new instance of RoutingMBeanServerConnection |
|
81 */ |
|
82 public RoutingMBeanServerConnection() { |
|
83 } |
|
84 |
|
85 /** |
|
86 * Returns the wrapped source connection. |
|
87 **/ |
|
88 protected abstract T source() throws IOException; |
|
89 |
|
90 /** |
|
91 * Converts a target ObjectName to a source ObjectName. |
|
92 **/ |
|
93 protected abstract ObjectName toSource(ObjectName targetName) |
|
94 throws MalformedObjectNameException; |
|
95 |
|
96 /** |
|
97 * Converts a source ObjectName to a target ObjectName. |
|
98 **/ |
|
99 protected abstract ObjectName toTarget(ObjectName sourceName) |
|
100 throws MalformedObjectNameException; |
|
101 |
|
102 /** |
|
103 * Can be overridden by subclasses to check the validity of a new |
|
104 * ObjectName used in createMBean or registerMBean. |
|
105 * This method is typically used by subclasses which might require |
|
106 * special handling for "null"; |
|
107 **/ |
|
108 protected ObjectName newSourceMBeanName(ObjectName targetName) |
|
109 throws MBeanRegistrationException { |
|
110 try { |
|
111 return toSource(targetName); |
|
112 } catch (Exception x) { |
|
113 throw new MBeanRegistrationException(x,"Illegal MBean Name"); |
|
114 } |
|
115 } |
|
116 |
|
117 // Calls toSource(), Wraps MalformedObjectNameException. |
|
118 ObjectName toSourceOrRuntime(ObjectName targetName) |
|
119 throws RuntimeOperationsException { |
|
120 try { |
|
121 return toSource(targetName); |
|
122 } catch (MalformedObjectNameException x) { |
|
123 final IllegalArgumentException x2 = |
|
124 new IllegalArgumentException(String.valueOf(targetName),x); |
|
125 final RuntimeOperationsException x3 = |
|
126 new RuntimeOperationsException(x2); |
|
127 throw x3; |
|
128 } |
|
129 } |
|
130 |
|
131 |
|
132 // Wraps given exception if needed. |
|
133 RuntimeException makeCompliantRuntimeException(Exception x) { |
|
134 if (x instanceof SecurityException) return (SecurityException)x; |
|
135 if (x instanceof JMRuntimeException) return (JMRuntimeException)x; |
|
136 if (x instanceof RuntimeException) |
|
137 return new RuntimeOperationsException((RuntimeException)x); |
|
138 if (x instanceof IOException) |
|
139 return Util.newRuntimeIOException((IOException)x); |
|
140 // shouldn't come here... |
|
141 final RuntimeException x2 = new UndeclaredThrowableException(x); |
|
142 return new RuntimeOperationsException(x2); |
|
143 } |
|
144 |
|
145 /** |
|
146 * This method is a hook to implement permission checking in subclasses. |
|
147 * By default, this method does nothing and simply returns |
|
148 * {@code attribute}. |
|
149 * |
|
150 * @param routingName The name of the MBean in the enclosing context. |
|
151 * This is of the form {@code <namespace>//<ObjectName>}. |
|
152 * @param attributes The list of attributes to check permission for. |
|
153 * @param action one of "getAttribute" or "setAttribute" |
|
154 * @return The list of attributes for which the callers has the |
|
155 * appropriate {@link |
|
156 * javax.management.namespace.JMXNamespacePermission}. |
|
157 */ |
|
158 String[] checkAttributes(ObjectName routingName, |
|
159 String[] attributes, String action) { |
|
160 check(routingName,null,action); |
|
161 return attributes; |
|
162 } |
|
163 |
|
164 /** |
|
165 * This method is a hook to implement permission checking in subclasses. |
|
166 * By default, this method does nothing and simply returns |
|
167 * {@code attribute}. |
|
168 * |
|
169 * @param routingName The name of the MBean in the enclosing context. |
|
170 * This is of the form {@code <namespace>//<ObjectName>}. |
|
171 * @param attributes The list of attributes to check permission for. |
|
172 * @param action one of "getAttribute" or "setAttribute" |
|
173 * @return The list of attributes for which the callers has the |
|
174 * appropriate {@link |
|
175 * javax.management.namespace.JMXNamespacePermission}. |
|
176 */ |
|
177 AttributeList checkAttributes(ObjectName routingName, |
|
178 AttributeList attributes, String action) { |
|
179 check(routingName,null,action); |
|
180 return attributes; |
|
181 } |
|
182 |
|
183 // from MBeanServerConnection |
|
184 public AttributeList getAttributes(ObjectName name, String[] attributes) |
|
185 throws InstanceNotFoundException, ReflectionException, IOException { |
|
186 final ObjectName sourceName = toSourceOrRuntime(name); |
|
187 try { |
|
188 final String[] authorized = |
|
189 checkAttributes(name,attributes,"getAttribute"); |
|
190 final AttributeList attrList = |
|
191 source().getAttributes(sourceName,authorized); |
|
192 return attrList; |
|
193 } catch (RuntimeException ex) { |
|
194 throw makeCompliantRuntimeException(ex); |
|
195 } |
|
196 } |
|
197 |
|
198 /** |
|
199 * This method is a hook to implement permission checking in subclasses. |
|
200 * By default, this method does nothing. |
|
201 * A subclass may override this method and throw a {@link |
|
202 * SecurityException} if the permission is denied. |
|
203 * |
|
204 * @param routingName The name of the MBean in the enclosing context. |
|
205 * This is of the form {@code <namespace>//<ObjectName>}. |
|
206 * @param member The {@link |
|
207 * javax.management.namespace.JMXNamespacePermission#getMember member} |
|
208 * name. |
|
209 * @param action The {@link |
|
210 * javax.management.namespace.JMXNamespacePermission#getActions action} |
|
211 * name. |
|
212 */ |
|
213 void check(ObjectName routingName, |
|
214 String member, String action) { |
|
215 } |
|
216 |
|
217 void checkPattern(ObjectName routingPattern, |
|
218 String member, String action) { |
|
219 // pattern is checked only at posteriori by checkQuery. |
|
220 // checking it a priori usually doesn't work, because ObjectName.apply |
|
221 // does not work between two patterns. |
|
222 check(null,null,action); |
|
223 } |
|
224 |
|
225 void checkCreate(ObjectName routingName, String className, |
|
226 String action) { |
|
227 } |
|
228 |
|
229 // from MBeanServerConnection |
|
230 public Object invoke(ObjectName name, String operationName, Object[] params, |
|
231 String[] signature) |
|
232 throws InstanceNotFoundException, MBeanException, ReflectionException, |
|
233 IOException { |
|
234 final ObjectName sourceName = toSourceOrRuntime(name); |
|
235 try { |
|
236 check(name, operationName, "invoke"); |
|
237 final Object result = |
|
238 source().invoke(sourceName,operationName,params, |
|
239 signature); |
|
240 return result; |
|
241 } catch (RuntimeException ex) { |
|
242 throw makeCompliantRuntimeException(ex); |
|
243 } |
|
244 } |
|
245 |
|
246 // from MBeanServerConnection |
|
247 public void unregisterMBean(ObjectName name) |
|
248 throws InstanceNotFoundException, MBeanRegistrationException, |
|
249 IOException { |
|
250 final ObjectName sourceName = toSourceOrRuntime(name); |
|
251 try { |
|
252 check(name, null, "unregisterMBean"); |
|
253 source().unregisterMBean(sourceName); |
|
254 } catch (RuntimeException ex) { |
|
255 throw makeCompliantRuntimeException(ex); |
|
256 } |
|
257 } |
|
258 |
|
259 // from MBeanServerConnection |
|
260 public MBeanInfo getMBeanInfo(ObjectName name) |
|
261 throws InstanceNotFoundException, IntrospectionException, |
|
262 ReflectionException, IOException { |
|
263 final ObjectName sourceName = toSourceOrRuntime(name); |
|
264 try { |
|
265 check(name, null, "getMBeanInfo"); |
|
266 return source().getMBeanInfo(sourceName); |
|
267 } catch (RuntimeException ex) { |
|
268 throw makeCompliantRuntimeException(ex); |
|
269 } |
|
270 } |
|
271 |
|
272 // from MBeanServerConnection |
|
273 public ObjectInstance getObjectInstance(ObjectName name) |
|
274 throws InstanceNotFoundException, IOException { |
|
275 final ObjectName sourceName = toSourceOrRuntime(name); |
|
276 try { |
|
277 check(name, null, "getObjectInstance"); |
|
278 return processOutputInstance( |
|
279 source().getObjectInstance(sourceName)); |
|
280 } catch (RuntimeException ex) { |
|
281 throw makeCompliantRuntimeException(ex); |
|
282 } |
|
283 } |
|
284 |
|
285 // from MBeanServerConnection |
|
286 public boolean isRegistered(ObjectName name) throws IOException { |
|
287 final ObjectName sourceName = toSourceOrRuntime(name); |
|
288 try { |
|
289 return source().isRegistered(sourceName); |
|
290 } catch (RuntimeMBeanException x) { |
|
291 throw new RuntimeOperationsException(x.getTargetException()); |
|
292 } catch (RuntimeException x) { |
|
293 throw makeCompliantRuntimeException(x); |
|
294 } |
|
295 } |
|
296 |
|
297 // from MBeanServerConnection |
|
298 public void setAttribute(ObjectName name, Attribute attribute) |
|
299 throws InstanceNotFoundException, AttributeNotFoundException, |
|
300 InvalidAttributeValueException, MBeanException, |
|
301 ReflectionException, IOException { |
|
302 final ObjectName sourceName = toSourceOrRuntime(name); |
|
303 try { |
|
304 check(name, |
|
305 (attribute==null?null:attribute.getName()), |
|
306 "setAttribute"); |
|
307 source().setAttribute(sourceName,attribute); |
|
308 } catch (RuntimeException ex) { |
|
309 throw makeCompliantRuntimeException(ex); |
|
310 } |
|
311 } |
|
312 |
|
313 // from MBeanServerConnection |
|
314 public ObjectInstance createMBean(String className, |
|
315 ObjectName name, ObjectName loaderName, |
|
316 Object[] params, String[] signature) |
|
317 throws ReflectionException, InstanceAlreadyExistsException, |
|
318 MBeanRegistrationException, MBeanException, |
|
319 NotCompliantMBeanException, InstanceNotFoundException, IOException { |
|
320 final ObjectName sourceName = newSourceMBeanName(name); |
|
321 // Loader Name is already a sourceLoaderName. |
|
322 final ObjectName sourceLoaderName = loaderName; |
|
323 try { |
|
324 checkCreate(name, className, "instantiate"); |
|
325 checkCreate(name, className, "registerMBean"); |
|
326 final ObjectInstance instance = |
|
327 source().createMBean(className,sourceName, |
|
328 sourceLoaderName, |
|
329 params,signature); |
|
330 return processOutputInstance(instance); |
|
331 } catch (RuntimeException ex) { |
|
332 throw makeCompliantRuntimeException(ex); |
|
333 } |
|
334 } |
|
335 |
|
336 // from MBeanServerConnection |
|
337 public ObjectInstance createMBean(String className, ObjectName name, |
|
338 Object[] params, String[] signature) |
|
339 throws ReflectionException, InstanceAlreadyExistsException, |
|
340 MBeanRegistrationException, MBeanException, |
|
341 NotCompliantMBeanException, IOException { |
|
342 final ObjectName sourceName = newSourceMBeanName(name); |
|
343 try { |
|
344 checkCreate(name, className, "instantiate"); |
|
345 checkCreate(name, className, "registerMBean"); |
|
346 return processOutputInstance(source().createMBean(className, |
|
347 sourceName,params,signature)); |
|
348 } catch (RuntimeException ex) { |
|
349 throw makeCompliantRuntimeException(ex); |
|
350 } |
|
351 } |
|
352 |
|
353 // from MBeanServerConnection |
|
354 public ObjectInstance createMBean(String className, ObjectName name, |
|
355 ObjectName loaderName) |
|
356 throws ReflectionException, InstanceAlreadyExistsException, |
|
357 MBeanRegistrationException, MBeanException, |
|
358 NotCompliantMBeanException, InstanceNotFoundException, IOException { |
|
359 final ObjectName sourceName = newSourceMBeanName(name); |
|
360 // Loader Name is already a source Loader Name. |
|
361 final ObjectName sourceLoaderName = loaderName; |
|
362 try { |
|
363 checkCreate(name, className, "instantiate"); |
|
364 checkCreate(name, className, "registerMBean"); |
|
365 return processOutputInstance(source().createMBean(className, |
|
366 sourceName,sourceLoaderName)); |
|
367 } catch (RuntimeException ex) { |
|
368 throw makeCompliantRuntimeException(ex); |
|
369 } |
|
370 } |
|
371 |
|
372 // from MBeanServerConnection |
|
373 public ObjectInstance createMBean(String className, ObjectName name) |
|
374 throws ReflectionException, InstanceAlreadyExistsException, |
|
375 MBeanRegistrationException, MBeanException, |
|
376 NotCompliantMBeanException, IOException { |
|
377 final ObjectName sourceName = newSourceMBeanName(name); |
|
378 try { |
|
379 checkCreate(name, className, "instantiate"); |
|
380 checkCreate(name, className, "registerMBean"); |
|
381 return processOutputInstance(source(). |
|
382 createMBean(className,sourceName)); |
|
383 } catch (RuntimeException ex) { |
|
384 throw makeCompliantRuntimeException(ex); |
|
385 } |
|
386 } |
|
387 |
|
388 // from MBeanServerConnection |
|
389 public Object getAttribute(ObjectName name, String attribute) |
|
390 throws MBeanException, AttributeNotFoundException, |
|
391 InstanceNotFoundException, ReflectionException, IOException { |
|
392 final ObjectName sourceName = toSourceOrRuntime(name); |
|
393 try { |
|
394 check(name, attribute, "getAttribute"); |
|
395 return source().getAttribute(sourceName,attribute); |
|
396 } catch (RuntimeException ex) { |
|
397 throw makeCompliantRuntimeException(ex); |
|
398 } |
|
399 } |
|
400 |
|
401 // from MBeanServerConnection |
|
402 public boolean isInstanceOf(ObjectName name, String className) |
|
403 throws InstanceNotFoundException, IOException { |
|
404 final ObjectName sourceName = toSourceOrRuntime(name); |
|
405 try { |
|
406 check(name, null, "isInstanceOf"); |
|
407 return source().isInstanceOf(sourceName,className); |
|
408 } catch (RuntimeException ex) { |
|
409 throw makeCompliantRuntimeException(ex); |
|
410 } |
|
411 } |
|
412 |
|
413 // from MBeanServerConnection |
|
414 public AttributeList setAttributes(ObjectName name, AttributeList attributes) |
|
415 throws InstanceNotFoundException, ReflectionException, IOException { |
|
416 final ObjectName sourceName = toSourceOrRuntime(name); |
|
417 try { |
|
418 final AttributeList authorized = |
|
419 checkAttributes(name, attributes, "setAttribute"); |
|
420 return source(). |
|
421 setAttributes(sourceName,authorized); |
|
422 } catch (RuntimeException ex) { |
|
423 throw makeCompliantRuntimeException(ex); |
|
424 } |
|
425 } |
|
426 |
|
427 // Return names in the target's context. |
|
428 Set<ObjectInstance> processOutputInstances(Set<ObjectInstance> sources) { |
|
429 |
|
430 final Set<ObjectInstance> result = Util.equivalentEmptySet(sources); |
|
431 for (ObjectInstance i : sources) { |
|
432 try { |
|
433 final ObjectInstance target = processOutputInstance(i); |
|
434 if (!checkQuery(target.getObjectName(), "queryMBeans")) |
|
435 continue; |
|
436 result.add(target); |
|
437 } catch (Exception x) { |
|
438 if (LOG.isLoggable(Level.FINE)) { |
|
439 LOG.fine("Skiping returned item: " + |
|
440 "Unexpected exception while processing " + |
|
441 "ObjectInstance: " + x); |
|
442 } |
|
443 continue; |
|
444 } |
|
445 } |
|
446 return result; |
|
447 } |
|
448 |
|
449 /** |
|
450 * This is a hook to implement permission checking in subclasses. |
|
451 * |
|
452 * Checks that the caller has sufficient permission for returning |
|
453 * information about {@code sourceName} in {@code action}. |
|
454 * |
|
455 * By default always return true. Subclass may override this method |
|
456 * and return false if the caller doesn't have sufficient permissions. |
|
457 * |
|
458 * @param routingName The name of the MBean to include or exclude from |
|
459 * the query, expressed in the enclosing context. |
|
460 * This is of the form {@code <namespace>//<ObjectName>}. |
|
461 * @param action one of "queryNames" or "queryMBeans" |
|
462 * @return true if {@code sourceName} can be returned. |
|
463 */ |
|
464 boolean checkQuery(ObjectName routingName, String action) { |
|
465 return true; |
|
466 } |
|
467 |
|
468 // Return names in the target's context. |
|
469 ObjectInstance processOutputInstance(ObjectInstance source) { |
|
470 if (source == null) return null; |
|
471 final ObjectName sourceName = source.getObjectName(); |
|
472 try { |
|
473 final ObjectName targetName = toTarget(sourceName); |
|
474 return new ObjectInstance(targetName,source.getClassName()); |
|
475 } catch (MalformedObjectNameException x) { |
|
476 final IllegalArgumentException x2 = |
|
477 new IllegalArgumentException(String.valueOf(sourceName),x); |
|
478 final RuntimeOperationsException x3 = |
|
479 new RuntimeOperationsException(x2); |
|
480 throw x3; |
|
481 } |
|
482 } |
|
483 |
|
484 // Returns names in the target's context. |
|
485 Set<ObjectName> processOutputNames(Set<ObjectName> sourceNames) { |
|
486 |
|
487 final Set<ObjectName> names = Util.equivalentEmptySet(sourceNames); |
|
488 for (ObjectName n : sourceNames) { |
|
489 try { |
|
490 final ObjectName targetName = toTarget(n); |
|
491 if (!checkQuery(targetName, "queryNames")) continue; |
|
492 names.add(targetName); |
|
493 } catch (Exception x) { |
|
494 if (LOG.isLoggable(Level.FINE)) { |
|
495 LOG.fine("Skiping returned item: " + |
|
496 "Unexpected exception while processing " + |
|
497 "ObjectInstance: " + x); |
|
498 } |
|
499 continue; |
|
500 } |
|
501 } |
|
502 return names; |
|
503 } |
|
504 |
|
505 // from MBeanServerConnection |
|
506 public Set<ObjectInstance> queryMBeans(ObjectName name, |
|
507 QueryExp query) throws IOException { |
|
508 if (name == null) name=ObjectName.WILDCARD; |
|
509 final ObjectName sourceName = toSourceOrRuntime(name); |
|
510 try { |
|
511 checkPattern(name,null,"queryMBeans"); |
|
512 return processOutputInstances( |
|
513 source().queryMBeans(sourceName,query)); |
|
514 } catch (RuntimeException ex) { |
|
515 throw makeCompliantRuntimeException(ex); |
|
516 } |
|
517 } |
|
518 |
|
519 // from MBeanServerConnection |
|
520 |
|
521 public Set<ObjectName> queryNames(ObjectName name, QueryExp query) |
|
522 throws IOException { |
|
523 if (name == null) name=ObjectName.WILDCARD; |
|
524 final ObjectName sourceName = toSourceOrRuntime(name); |
|
525 try { |
|
526 checkPattern(name,null,"queryNames"); |
|
527 final Set<ObjectName> tmp = source().queryNames(sourceName,query); |
|
528 final Set<ObjectName> out = processOutputNames(tmp); |
|
529 //System.err.println("queryNames: out: "+out); |
|
530 return out; |
|
531 } catch (RuntimeException ex) { |
|
532 throw makeCompliantRuntimeException(ex); |
|
533 } |
|
534 } |
|
535 |
|
536 // from MBeanServerConnection |
|
537 public void removeNotificationListener(ObjectName name, |
|
538 NotificationListener listener) |
|
539 throws InstanceNotFoundException, |
|
540 ListenerNotFoundException, IOException { |
|
541 final ObjectName sourceName = toSourceOrRuntime(name); |
|
542 try { |
|
543 check(name,null,"removeNotificationListener"); |
|
544 source().removeNotificationListener(sourceName,listener); |
|
545 } catch (RuntimeException ex) { |
|
546 throw makeCompliantRuntimeException(ex); |
|
547 } |
|
548 } |
|
549 |
|
550 // from MBeanServerConnection |
|
551 public void addNotificationListener(ObjectName name, ObjectName listener, |
|
552 NotificationFilter filter, Object handback) |
|
553 throws InstanceNotFoundException, IOException { |
|
554 final ObjectName sourceName = toSourceOrRuntime(name); |
|
555 // Listener name is already a source listener name. |
|
556 try { |
|
557 check(name,null,"addNotificationListener"); |
|
558 source().addNotificationListener(sourceName,listener, |
|
559 filter,handback); |
|
560 } catch (RuntimeException ex) { |
|
561 throw makeCompliantRuntimeException(ex); |
|
562 } |
|
563 } |
|
564 |
|
565 // from MBeanServerConnection |
|
566 public void addNotificationListener(ObjectName name, |
|
567 NotificationListener listener, NotificationFilter filter, |
|
568 Object handback) throws InstanceNotFoundException, IOException { |
|
569 final ObjectName sourceName = toSourceOrRuntime(name); |
|
570 try { |
|
571 check(name,null,"addNotificationListener"); |
|
572 source().addNotificationListener(sourceName, listener, filter, |
|
573 handback); |
|
574 } catch (RuntimeException ex) { |
|
575 throw makeCompliantRuntimeException(ex); |
|
576 } |
|
577 } |
|
578 |
|
579 |
|
580 // from MBeanServerConnection |
|
581 public void removeNotificationListener(ObjectName name, |
|
582 NotificationListener listener, NotificationFilter filter, |
|
583 Object handback) |
|
584 throws InstanceNotFoundException, ListenerNotFoundException, |
|
585 IOException { |
|
586 final ObjectName sourceName = toSourceOrRuntime(name); |
|
587 try { |
|
588 check(name,null,"removeNotificationListener"); |
|
589 source().removeNotificationListener(sourceName,listener,filter, |
|
590 handback); |
|
591 } catch (RuntimeException ex) { |
|
592 throw makeCompliantRuntimeException(ex); |
|
593 } |
|
594 } |
|
595 |
|
596 // from MBeanServerConnection |
|
597 public void removeNotificationListener(ObjectName name, ObjectName listener, |
|
598 NotificationFilter filter, Object handback) |
|
599 throws InstanceNotFoundException, ListenerNotFoundException, |
|
600 IOException { |
|
601 final ObjectName sourceName = toSourceOrRuntime(name); |
|
602 try { |
|
603 check(name,null,"removeNotificationListener"); |
|
604 source().removeNotificationListener(sourceName,listener, |
|
605 filter,handback); |
|
606 } catch (RuntimeException ex) { |
|
607 throw makeCompliantRuntimeException(ex); |
|
608 } |
|
609 } |
|
610 |
|
611 // from MBeanServerConnection |
|
612 public void removeNotificationListener(ObjectName name, ObjectName listener) |
|
613 throws InstanceNotFoundException, ListenerNotFoundException, |
|
614 IOException { |
|
615 final ObjectName sourceName = toSourceOrRuntime(name); |
|
616 // listener name is already a source name... |
|
617 final ObjectName sourceListener = listener; |
|
618 try { |
|
619 check(name,null,"removeNotificationListener"); |
|
620 source().removeNotificationListener(sourceName,sourceListener); |
|
621 } catch (RuntimeException ex) { |
|
622 throw makeCompliantRuntimeException(ex); |
|
623 } |
|
624 } |
|
625 |
|
626 // from MBeanServerConnection |
|
627 public Integer getMBeanCount() throws IOException { |
|
628 try { |
|
629 return source().getMBeanCount(); |
|
630 } catch (RuntimeException ex) { |
|
631 throw makeCompliantRuntimeException(ex); |
|
632 } |
|
633 } |
|
634 |
|
635 // from MBeanServerConnection |
|
636 public String[] getDomains() throws IOException { |
|
637 try { |
|
638 check(null,null,"getDomains"); |
|
639 final String[] domains = source().getDomains(); |
|
640 return checkDomains(domains,"getDomains"); |
|
641 } catch (RuntimeException ex) { |
|
642 throw makeCompliantRuntimeException(ex); |
|
643 } |
|
644 } |
|
645 |
|
646 /** |
|
647 * This method is a hook to implement permission checking in subclasses. |
|
648 * Checks that the caller as the necessary permissions to view the |
|
649 * given domain. If not remove the domains for which the caller doesn't |
|
650 * have permission from the list. |
|
651 * <p> |
|
652 * By default, this method always returns {@code domains} |
|
653 * |
|
654 * @param domains The domains to return. |
|
655 * @param action "getDomains" |
|
656 * @return a filtered list of domains. |
|
657 */ |
|
658 String[] checkDomains(String[] domains, String action) { |
|
659 return domains; |
|
660 } |
|
661 |
|
662 // from MBeanServerConnection |
|
663 public String getDefaultDomain() throws IOException { |
|
664 try { |
|
665 return source().getDefaultDomain(); |
|
666 } catch (RuntimeException ex) { |
|
667 throw makeCompliantRuntimeException(ex); |
|
668 } |
|
669 } |
|
670 |
|
671 } |