KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > jmx > interceptor > DefaultMBeanServerInterceptor


1 /*
2  * @(#)DefaultMBeanServerInterceptor.java 1.64 04/03/18
3  *
4  * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7
8 package com.sun.jmx.interceptor;
9
10 // java import
11
import java.util.ArrayList JavaDoc;
12 import java.util.Iterator JavaDoc;
13 import java.util.Set JavaDoc;
14 import java.util.HashSet JavaDoc;
15 import java.util.WeakHashMap JavaDoc;
16 import java.lang.ref.WeakReference JavaDoc;
17 import java.lang.reflect.InvocationTargetException JavaDoc;
18 import java.lang.reflect.Method JavaDoc;
19 import java.lang.reflect.Constructor JavaDoc;
20 import java.io.OptionalDataException JavaDoc;
21 import java.io.ObjectInputStream JavaDoc;
22 import java.io.ObjectOutputStream JavaDoc;
23 import java.io.ByteArrayInputStream JavaDoc;
24 import java.io.ByteArrayOutputStream JavaDoc;
25 import java.io.PrintWriter JavaDoc;
26 import java.io.StringWriter JavaDoc;
27 import java.io.IOException JavaDoc;
28 import java.security.AccessControlContext JavaDoc;
29 import java.security.Permission JavaDoc;
30 import java.security.ProtectionDomain JavaDoc;
31 import java.security.AccessController JavaDoc;
32 import java.security.PrivilegedAction JavaDoc;
33
34 // JMX import
35
import javax.management.*;
36 import javax.management.loading.ClassLoaderRepository JavaDoc;
37
38 // JMX RI
39
import com.sun.jmx.mbeanserver.ModifiableClassLoaderRepository;
40 import com.sun.jmx.mbeanserver.MetaData;
41 import com.sun.jmx.mbeanserver.MetaDataImpl;
42 import com.sun.jmx.mbeanserver.MBeanInstantiator;
43 import com.sun.jmx.mbeanserver.Repository;
44 import com.sun.jmx.mbeanserver.RepositorySupport;
45 import com.sun.jmx.mbeanserver.NamedObject;
46 import com.sun.jmx.defaults.ServiceName;
47 import com.sun.jmx.trace.Trace;
48
49 /**
50  * This is the default class for MBean manipulation on the agent side. It
51  * contains the methods necessary for the creation, registration, and
52  * deletion of MBeans as well as the access methods for registered MBeans.
53  * This is the core component of the JMX infrastructure.
54  * <P>
55  * Every MBean which is added to the MBean server becomes manageable: its attributes and operations
56  * become remotely accessible through the connectors/adaptors connected to that MBean server.
57  * A Java object cannot be registered in the MBean server unless it is a JMX compliant MBean.
58  * <P>
59  * When an MBean is registered or unregistered in the MBean server an
60  * {@link javax.management.MBeanServerNotification MBeanServerNotification}
61  * Notification is emitted. To register an object as listener to MBeanServerNotifications
62  * you should call the MBean server method {@link #addNotificationListener addNotificationListener} with <CODE>ObjectName</CODE>
63  * the <CODE>ObjectName</CODE> of the {@link javax.management.MBeanServerDelegate MBeanServerDelegate}.
64  * This <CODE>ObjectName</CODE> is:
65  * <BR>
66  * <CODE>JMImplementation:type=MBeanServerDelegate</CODE>.
67  *
68  * @since 1.5
69  * @since.unbundled JMX RI 1.2
70  */

71 public class DefaultMBeanServerInterceptor implements MBeanServerInterceptor {
72
73     /** MBeanServerDelegate ObjectName shared ref */
74     private final static ObjectName _MBSDelegateObjectName;
75     static {
76     try {
77             _MBSDelegateObjectName = new ObjectName(ServiceName.DELEGATE);
78     } catch (MalformedObjectNameException e) {
79         throw new UnsupportedOperationException JavaDoc(e.getMessage());
80     }
81     }
82
83     /** The MBeanInstantiator object used by the
84      * DefaultMBeanServerInterceptor */

85     private final transient MBeanInstantiator instantiator;
86
87     /** The MBean server object that is associated to the
88      * DefaultMBeanServerInterceptor */

89     private transient MBeanServer server = null;
90
91     /** The MBean server object taht associated to the
92      * DefaultMBeanServerInterceptor */

93     private final transient MBeanServerDelegate delegate;
94
95     /** The Metadata object used by the DefaultMBeanServerInterceptor */
96     private final transient MetaData meta;
97
98     /** The Repository object used by the DefaultMBeanServerInterceptor */
99     private final transient Repository JavaDoc repository;
100
101     /** Wrappers for client listeners. */
102     /* See the comment before addNotificationListener below. */
103     private final transient WeakHashMap JavaDoc listenerWrappers = new WeakHashMap JavaDoc();
104
105     /** The default domain of the object names */
106     private final String JavaDoc domain;
107
108     /** True if the repository perform queries, false otherwise */
109     private boolean queryByRepo;
110
111     /** The sequence number identifyng the notifications sent */
112     // Now sequence number is handled by MBeanServerDelegate.
113
// private int sequenceNumber=0;
114

115     /** The name of this class to be used for tracing */
116     private final static String JavaDoc dbgTag = "DefaultMBeanServerInterceptor";
117
118     /**
119      * Creates a DefaultMBeanServerInterceptor with the specified
120      * default domain name.
121      * The default domain name is used as the domain part in the ObjectName
122      * of MBeans if no domain is specified by the user.
123      * <p>Do not forget to call <code>initialize(outer,delegate)</code>
124      * before using this object.
125      * @param domain The default domain name used by this MBeanServer.
126      * @param outer A pointer to the MBeanServer object that must be
127      * passed to the MBeans when invoking their
128      * {@link javax.management.MBeanRegistration} interface.
129      * @param delegate A pointer to the MBeanServerDelegate associated
130      * with the new MBeanServer. The new MBeanServer must register
131      * this MBean in its MBean repository.
132      * @param instantiator The MBeanInstantiator that will be used to
133      * instantiate MBeans and take care of class loading issues.
134      */

135     public DefaultMBeanServerInterceptor(String JavaDoc domain,
136                      MBeanServer outer,
137                      MBeanServerDelegate delegate,
138                      MBeanInstantiator instantiator) {
139         this(outer, delegate, instantiator, null,
140          new RepositorySupport((domain==null?ServiceName.DOMAIN:domain)));
141     }
142
143     /**
144      * Creates a DefaultMBeanServerInterceptor with the specified
145      * repository instance.
146      * <p>Do not forget to call <code>initialize(outer,delegate)</code>
147      * before using this object.
148      * @param outer A pointer to the MBeanServer object that must be
149      * passed to the MBeans when invoking their
150      * {@link javax.management.MBeanRegistration} interface.
151      * @param delegate A pointer to the MBeanServerDelegate associated
152      * with the new MBeanServer. The new MBeanServer must register
153      * this MBean in its MBean repository.
154      * @param instantiator The MBeanInstantiator that will be used to
155      * instantiate MBeans and take care of class loading issues.
156      * @param metadata The MetaData object that will be used by the
157      * MBean server in order to invoke the MBean interface of
158      * the registered MBeans.
159      * @param repository The repository to use for this MBeanServer
160      */

161     public DefaultMBeanServerInterceptor(MBeanServer outer,
162                      MBeanServerDelegate delegate,
163                      MBeanInstantiator instantiator,
164                      MetaData metadata,
165                      Repository JavaDoc repository) {
166     if (outer == null) throw new
167         IllegalArgumentException JavaDoc("outer MBeanServer cannot be null");
168     if (delegate == null) throw new
169         IllegalArgumentException JavaDoc("MBeanServerDelegate cannot be null");
170     if (instantiator == null) throw new
171         IllegalArgumentException JavaDoc("MBeanInstantiator cannot be null");
172     if (metadata == null)
173         metadata = new MetaDataImpl(instantiator);
174     if (repository == null)
175         repository = new RepositorySupport(ServiceName.DOMAIN);
176
177     this.server = outer;
178     this.delegate = delegate;
179     this.instantiator = instantiator;
180     this.meta = metadata;
181     this.repository = repository;
182     this.domain = repository.getDefaultDomain();
183     }
184
185     public ObjectInstance createMBean(String JavaDoc className, ObjectName name)
186         throws ReflectionException, InstanceAlreadyExistsException,
187                MBeanRegistrationException, MBeanException,
188                NotCompliantMBeanException {
189
190     return createMBean(className, name, (Object JavaDoc[]) null, (String JavaDoc[]) null);
191
192     }
193
194     public ObjectInstance createMBean(String JavaDoc className, ObjectName name,
195                                       ObjectName loaderName)
196         throws ReflectionException, InstanceAlreadyExistsException,
197                MBeanRegistrationException, MBeanException,
198                NotCompliantMBeanException, InstanceNotFoundException {
199
200     return createMBean(className, name, loaderName, (Object JavaDoc[]) null,
201                (String JavaDoc[]) null);
202     }
203
204     public ObjectInstance createMBean(String JavaDoc className, ObjectName name,
205                       Object JavaDoc[] params, String JavaDoc[] signature)
206         throws ReflectionException, InstanceAlreadyExistsException,
207            MBeanRegistrationException, MBeanException,
208                NotCompliantMBeanException {
209
210     try {
211         return createMBean(className, name, null, true,
212                    params, signature);
213     } catch (InstanceNotFoundException e) {
214         /* Can only happen if loaderName doesn't exist, but we just
215            passed null, so we shouldn't get this exception. */

216         throw new IllegalArgumentException JavaDoc("Unexpected exception: " + e);
217     }
218     }
219
220     public ObjectInstance createMBean(String JavaDoc className, ObjectName name,
221                       ObjectName loaderName,
222                       Object JavaDoc[] params, String JavaDoc[] signature)
223         throws ReflectionException, InstanceAlreadyExistsException,
224            MBeanRegistrationException, MBeanException,
225                NotCompliantMBeanException, InstanceNotFoundException {
226
227     return createMBean(className, name, loaderName, false,
228                params, signature);
229     }
230
231     private ObjectInstance createMBean(String JavaDoc className, ObjectName name,
232                        ObjectName loaderName,
233                        boolean withDefaultLoaderRepository,
234                        Object JavaDoc[] params, String JavaDoc[] signature)
235         throws ReflectionException, InstanceAlreadyExistsException,
236            MBeanRegistrationException, MBeanException,
237                NotCompliantMBeanException, InstanceNotFoundException {
238
239         ObjectName logicalName = name;
240         Class JavaDoc theClass;
241
242     if (className == null) {
243         final RuntimeException JavaDoc wrapped =
244         new IllegalArgumentException JavaDoc("The class name cannot be null");
245         throw new RuntimeOperationsException(wrapped,
246                       "Exception occured during MBean creation");
247     }
248
249     if (name != null) {
250         if (name.isPattern()) {
251         final RuntimeException JavaDoc wrapped =
252             new IllegalArgumentException JavaDoc("Invalid name->" +
253                          name.toString());
254         final String JavaDoc msg = "Exception occurred during MBean creation";
255         throw new RuntimeOperationsException(wrapped, msg);
256         }
257
258         name = nonDefaultDomain(name);
259     }
260
261     /* Permission check */
262     checkMBeanPermission(className, null, null, "instantiate");
263     checkMBeanPermission(className, null, name, "registerMBean");
264
265     /* Load the appropriate class. */
266     if (withDefaultLoaderRepository) {
267         if (isTraceOn()) {
268         trace(dbgTag, "createMBean", "ClassName = " + className +
269               ",ObjectName = " + name);
270         }
271         theClass =
272         instantiator.findClassWithDefaultLoaderRepository(className);
273     } else if (loaderName == null) {
274         if (isTraceOn()) {
275         trace(dbgTag, "createMBean", "ClassName = " + className +
276               ",ObjectName = " + name + " Loader name = null");
277         }
278
279         theClass = instantiator.findClass(className,
280                   server.getClass().getClassLoader());
281     } else {
282         loaderName = nonDefaultDomain(loaderName);
283
284         if (isTraceOn()) {
285                 trace(dbgTag, "createMBean", "ClassName = " + className +
286               ",ObjectName = " + name + ",Loader name = "+
287               loaderName.toString());
288             }
289
290         theClass = instantiator.findClass(className, loaderName);
291     }
292
293     /* Permission check */
294     checkMBeanTrustPermission(theClass);
295
296     // Check that the MBean can be instantiated by the MBeanServer.
297
instantiator.testCreation(theClass);
298
299     // Check the JMX compliance of the class
300
meta.testCompliance(theClass);
301
302     Object JavaDoc moi= instantiator.instantiate(theClass, params, signature,
303                          server.getClass().getClassLoader());
304
305     final String JavaDoc infoClassName;
306     try {
307         infoClassName = meta.getMBeanClassName(moi);
308     } catch (IntrospectionException e) {
309         throw new NotCompliantMBeanException(e.getMessage());
310     }
311
312     return registerCreatedObject(infoClassName, moi, name);
313     }
314
315     public ObjectInstance registerMBean(Object JavaDoc object, ObjectName name)
316     throws InstanceAlreadyExistsException, MBeanRegistrationException,
317     NotCompliantMBeanException {
318
319     // ------------------------------
320
// ------------------------------
321
Class JavaDoc theClass = object.getClass();
322
323         // Check the JMX compliance of the class
324
meta.testCompliance(theClass);
325
326     /* Permission check */
327     final String JavaDoc infoClassName;
328     try {
329         infoClassName = meta.getMBeanClassName(object);
330     } catch (IntrospectionException e) {
331         throw new NotCompliantMBeanException(e.getMessage());
332     }
333
334     checkMBeanPermission(infoClassName, null, name, "registerMBean");
335     checkMBeanTrustPermission(theClass);
336
337     return registerObject(infoClassName, object, name);
338     }
339
340     public void unregisterMBean(ObjectName name)
341         throws InstanceNotFoundException, MBeanRegistrationException {
342         Object JavaDoc object;
343
344         if (name == null) {
345         final RuntimeException JavaDoc wrapped =
346         new IllegalArgumentException JavaDoc("Object name cannot be null");
347             throw new RuntimeOperationsException(wrapped,
348                       "Exception occured trying to unregister the MBean");
349         }
350
351     name = nonDefaultDomain(name);
352
353     /* Permission check */
354         Object JavaDoc instance = getMBean(name);
355     String JavaDoc classname = null;
356     try {
357         classname = meta.getMBeanClassName(instance);
358     } catch (IntrospectionException e) {
359         classname = null;
360     } catch (NotCompliantMBeanException e) {
361         classname = null;
362     }
363     checkMBeanPermission(classname, null, name, "unregisterMBean");
364
365     /* We synchronize here to be sure that the preDeregister
366        method will be invoked exactly once, even if more than one
367        thread unregisters the MBean at the same time. */

368         synchronized(this) {
369             object = repository.retrieve(name);
370             if (object==null) {
371                 if (isTraceOn()) {
372                     trace("unregisterMBean", name+": Found no object");
373                 }
374                 throw new InstanceNotFoundException(name.toString());
375             }
376             if (object instanceof MBeanRegistration) {
377                 meta.preDeregisterInvoker(object);
378             }
379             // Let the repository do the work.
380
try {
381         repository.remove(name);
382             }
383             catch (InstanceNotFoundException e) {
384                 throw e;
385             }
386
387         /**
388          * Checks if the unregistered MBean is a ClassLoader
389          * If so, it removes the MBean from the default loader repository.
390          */

391
392             if (object instanceof ClassLoader JavaDoc
393         && object != server.getClass().getClassLoader()) {
394         final ModifiableClassLoaderRepository clr =
395             instantiator.getClassLoaderRepository();
396         if (clr != null) clr.removeClassLoader(name);
397         }
398     }
399
400     // ---------------------
401
// Send deletion event
402
// ---------------------
403
if (isTraceOn()) {
404         trace("unregisterMBean", "Send delete notification of object "
405           + name.getCanonicalName());
406     }
407     sendNotification(MBeanServerNotification.UNREGISTRATION_NOTIFICATION,
408              name);
409
410     if (object instanceof MBeanRegistration) {
411         meta.postDeregisterInvoker(object);
412     }
413     }
414
415     public ObjectInstance getObjectInstance(ObjectName name)
416         throws InstanceNotFoundException {
417
418     name = nonDefaultDomain(name);
419         Object JavaDoc obj = getMBean(name);
420     final String JavaDoc className;
421     try {
422         className = meta.getMBeanClassName(obj);
423     } catch (IntrospectionException x) {
424         debugX("getObjectInstance",x);
425         throw new JMRuntimeException("Can't obtain class name for " +
426                      name + ": " + x);
427     } catch (NotCompliantMBeanException x) {
428         debugX("getObjectInstance",x);
429         throw new JMRuntimeException("Can't obtain class name for " +
430                      name + ": " + x);
431     }
432
433     /* Permission check */
434     checkMBeanPermission(className, null, name, "getObjectInstance");
435
436     return new ObjectInstance(name, className);
437     }
438
439     public Set JavaDoc queryMBeans(ObjectName name, QueryExp query) {
440     /* Permission check */
441     SecurityManager JavaDoc sm = System.getSecurityManager();
442     if (sm != null) {
443         // Check if the caller has the right to invoke 'queryMBeans'
444
//
445
checkMBeanPermission(null, null, null, "queryMBeans");
446
447         // Perform query without "query".
448
//
449
Set JavaDoc list = queryMBeansImpl(name, null);
450
451         // Check if the caller has the right to invoke 'queryMBeans'
452
// on each specific classname/objectname in the list.
453
//
454
Set JavaDoc allowedList = new HashSet JavaDoc(list.size());
455         for (Iterator JavaDoc i = list.iterator(); i.hasNext(); ) {
456         try {
457             ObjectInstance oi = (ObjectInstance) i.next();
458             checkMBeanPermission(oi.getClassName(), null,
459                      oi.getObjectName(), "queryMBeans");
460             allowedList.add(oi);
461         } catch (SecurityException JavaDoc e) {
462             // OK: Do not add this ObjectInstance to the list
463
}
464         }
465
466         // Apply query to allowed MBeans only.
467
//
468
return filterListOfObjectInstances(allowedList, query);
469     } else {
470         // Perform query.
471
//
472
return queryMBeansImpl(name, query);
473     }
474     }
475
476     private Set JavaDoc queryMBeansImpl(ObjectName name, QueryExp query) {
477     // Query the MBeans on the repository
478
//
479
Set JavaDoc list = null;
480         synchronized(this) {
481             list = repository.query(name, query);
482         }
483         // The repository performs the filtering
484
//
485
if (queryByRepo) {
486         return list;
487     } else {
488             // The filtering will be performed by the MBeanServer
489
//
490
return (filterListOfObjects(list, query));
491         }
492     }
493
494     public Set JavaDoc queryNames(ObjectName name, QueryExp query) {
495     /* Permission check */
496     SecurityManager JavaDoc sm = System.getSecurityManager();
497     if (sm != null) {
498         // Check if the caller has the right to invoke 'queryNames'
499
//
500
checkMBeanPermission(null, null, null, "queryNames");
501
502         // Perform query without "query".
503
//
504
Set JavaDoc list = queryMBeansImpl(name, null);
505
506         // Check if the caller has the right to invoke 'queryNames'
507
// on each specific classname/objectname in the list.
508
//
509
Set JavaDoc allowedList = new HashSet JavaDoc(list.size());
510         for (Iterator JavaDoc i = list.iterator(); i.hasNext(); ) {
511         try {
512             ObjectInstance oi = (ObjectInstance) i.next();
513             checkMBeanPermission(oi.getClassName(), null,
514                      oi.getObjectName(), "queryNames");
515             allowedList.add(oi);
516         } catch (SecurityException JavaDoc e) {
517             // OK: Do not add this ObjectInstance to the list
518
}
519         }
520
521         // Apply query to allowed MBeans only.
522
//
523
Set JavaDoc queryList = filterListOfObjectInstances(allowedList, query);
524         Set JavaDoc result = new HashSet JavaDoc(queryList.size());
525         for (Iterator JavaDoc i = queryList.iterator(); i.hasNext(); ) {
526         ObjectInstance oi = (ObjectInstance) i.next();
527         result.add(oi.getObjectName());
528         }
529         return result;
530     } else {
531         // Perform query.
532
//
533
Set JavaDoc queryList = queryMBeansImpl(name, query);
534         Set JavaDoc result = new HashSet JavaDoc(queryList.size());
535         for (Iterator JavaDoc i = queryList.iterator(); i.hasNext(); ) {
536         ObjectInstance oi = (ObjectInstance) i.next();
537         result.add(oi.getObjectName());
538         }
539         return result;
540     }
541     }
542
543     public boolean isRegistered(ObjectName name) {
544         if (name == null) {
545             throw new RuntimeOperationsException(
546              new IllegalArgumentException JavaDoc("Object name cannot be null"),
547              "Object name cannot be null");
548         }
549
550     name = nonDefaultDomain(name);
551
552 // /* Permission check */
553
// checkMBeanPermission(null, null, name, "isRegistered");
554

555         synchronized(this) {
556             return (repository.contains(name));
557         }
558     }
559
560     public String JavaDoc[] getDomains() {
561     /* Permission check */
562     SecurityManager JavaDoc sm = System.getSecurityManager();
563     if (sm != null) {
564         // Check if the caller has the right to invoke 'getDomains'
565
//
566
checkMBeanPermission(null, null, null, "getDomains");
567         
568         // Return domains
569
//
570
String JavaDoc[] domains = repository.getDomains();
571
572         // Check if the caller has the right to invoke 'getDomains'
573
// on each specific domain in the list.
574
//
575
ArrayList JavaDoc result = new ArrayList JavaDoc(domains.length);
576         for (int i = 0; i < domains.length; i++) {
577         try {
578             ObjectName domain = new ObjectName(domains[i] + ":x=x");
579             checkMBeanPermission(null, null, domain, "getDomains");
580             result.add(domains[i]);
581         } catch (MalformedObjectNameException e) {
582             // Should never occur... But let's log it just in case.
583
error("getDomains",
584               "Failed to check permission for domain=" +
585               domains[i] + ". Error is: " + e);
586             debugX("getDomains",e);
587         } catch (SecurityException JavaDoc e) {
588             // OK: Do not add this domain to the list
589
}
590         }
591
592         // Make an array from result.
593
//
594
return (String JavaDoc[]) result.toArray(new String JavaDoc[result.size()]);
595     } else {
596         return repository.getDomains();
597     }
598     }
599
600     public Integer JavaDoc getMBeanCount() {
601         return (repository.getCount());
602     }
603
604     public Object JavaDoc getAttribute(ObjectName name, String JavaDoc attribute)
605     throws MBeanException, AttributeNotFoundException,
606            InstanceNotFoundException, ReflectionException {
607
608         if (name == null) {
609             throw new RuntimeOperationsException(new
610         IllegalArgumentException JavaDoc("Object name cannot be null"),
611                 "Exception occured trying to invoke the getter on the MBean");
612         }
613         if (attribute == null) {
614             throw new RuntimeOperationsException(new
615         IllegalArgumentException JavaDoc("Attribute cannot be null"),
616                 "Exception occured trying to invoke the getter on the MBean");
617         }
618
619     name = nonDefaultDomain(name);
620     
621         if (isTraceOn()) {
622             trace("getAttribute", "Attribute= " + attribute +
623           ", obj= " + name);
624         }
625
626     /* Permission check */
627         Object JavaDoc instance = getMBean(name);
628     String JavaDoc classname = null;
629     try {
630         classname = meta.getMBeanClassName(instance);
631     } catch (IntrospectionException e) {
632         classname = null;
633     } catch (NotCompliantMBeanException e) {
634         classname = null;
635     }
636     checkMBeanPermission(classname, attribute, name, "getAttribute");
637
638         return meta.getAttribute(instance, attribute);
639     }
640
641     public AttributeList getAttributes(ObjectName name, String JavaDoc[] attributes)
642         throws InstanceNotFoundException, ReflectionException {
643
644         if (name == null) {
645             throw new RuntimeOperationsException(new
646         IllegalArgumentException JavaDoc("ObjectName name cannot be null"),
647                 "Exception occured trying to invoke the getter on the MBean");
648         }
649
650         if (attributes == null) {
651             throw new RuntimeOperationsException(new
652         IllegalArgumentException JavaDoc("Attributes cannot be null"),
653                 "Exception occured trying to invoke the getter on the MBean");
654         }
655
656     name = nonDefaultDomain(name);
657
658         if (isTraceOn()) {
659             trace("getAttributes", "Object= " + name);
660         }
661
662     Object JavaDoc instance = getMBean(name);
663     SecurityManager JavaDoc sm = System.getSecurityManager();
664     if (sm != null) {
665         /* Permission check */
666         String JavaDoc classname = null;
667         try {
668         classname = meta.getMBeanClassName(instance);
669         } catch (IntrospectionException e) {
670         classname = null;
671         } catch (NotCompliantMBeanException e) {
672         classname = null;
673         }
674
675         // Check if the caller has the right to invoke 'getAttribute'
676
//
677
checkMBeanPermission(classname, null, name, "getAttribute");
678
679         // Check if the caller has the right to invoke 'getAttribute'
680
// on each specific attribute
681
//
682
ArrayList JavaDoc allowedList = new ArrayList JavaDoc(attributes.length);
683         for (int i = 0; i < attributes.length; i++) {
684         try {
685             checkMBeanPermission(classname, attributes[i],
686                      name, "getAttribute");
687             allowedList.add(attributes[i]);
688         } catch (SecurityException JavaDoc e) {
689             // OK: Do not add this attribute to the list
690
}
691         }
692         String JavaDoc[] allowedAttributes =
693         (String JavaDoc[]) allowedList.toArray(new String JavaDoc[0]);
694         return meta.getAttributes(instance, allowedAttributes);
695     } else {
696         return meta.getAttributes(instance, attributes);
697     }
698     }
699
700     public void setAttribute(ObjectName name, Attribute attribute)
701     throws InstanceNotFoundException, AttributeNotFoundException,
702            InvalidAttributeValueException, MBeanException,
703            ReflectionException {
704
705         if (name == null) {
706             throw new RuntimeOperationsException(new
707         IllegalArgumentException JavaDoc("ObjectName name cannot be null"),
708                 "Exception occured trying to invoke the setter on the MBean");
709         }
710
711         if (attribute == null) {
712             throw new RuntimeOperationsException(new
713         IllegalArgumentException JavaDoc("Attribute cannot be null"),
714                 "Exception occured trying to invoke the setter on the MBean");
715         }
716
717     name = nonDefaultDomain(name);
718
719         if (isTraceOn()) {
720             trace("setAttribute", "Object= " + name + ", attribute=" +
721           attribute.getName());
722         }
723
724     /* Permission check */
725         Object JavaDoc instance = getMBean(name);
726     String JavaDoc classname = null;
727     try {
728         classname = meta.getMBeanClassName(instance);
729     } catch (IntrospectionException e) {
730         classname = null;
731     } catch (NotCompliantMBeanException e) {
732         classname = null;
733     }
734     checkMBeanPermission(classname, attribute.getName(),
735                  name, "setAttribute");
736
737         final Object JavaDoc o = meta.setAttribute(instance, attribute);
738     }
739
740     public AttributeList setAttributes(ObjectName name,
741                        AttributeList attributes)
742         throws InstanceNotFoundException, ReflectionException {
743
744         if (name == null) {
745             throw new RuntimeOperationsException(new
746         IllegalArgumentException JavaDoc("ObjectName name cannot be null"),
747         "Exception occured trying to invoke the setter on the MBean");
748         }
749
750         if (attributes == null) {
751             throw new RuntimeOperationsException(new
752             IllegalArgumentException JavaDoc("AttributeList cannot be null"),
753         "Exception occured trying to invoke the setter on the MBean");
754         }
755
756     name = nonDefaultDomain(name);
757
758     Object JavaDoc instance = getMBean(name);
759     SecurityManager JavaDoc sm = System.getSecurityManager();
760     if (sm != null) {
761         /* Permission check */
762         String JavaDoc classname = null;
763         try {
764         classname = meta.getMBeanClassName(instance);
765         } catch (IntrospectionException e) {
766         classname = null;
767         } catch (NotCompliantMBeanException e) {
768         classname = null;
769         }
770
771         // Check if the caller has the right to invoke 'setAttribute'
772
//
773
checkMBeanPermission(classname, null, name, "setAttribute");
774
775         // Check if the caller has the right to invoke 'setAttribute'
776
// on each specific attribute
777
//
778
AttributeList allowedAttributes =
779         new AttributeList(attributes.size());
780         for (Iterator JavaDoc i = attributes.iterator(); i.hasNext();) {
781         try {
782             Attribute attribute = (Attribute) i.next();
783             checkMBeanPermission(classname, attribute.getName(),
784                      name, "setAttribute");
785             allowedAttributes.add(attribute);
786         } catch (SecurityException JavaDoc e) {
787             // OK: Do not add this attribute to the list
788
}
789         }
790         return meta.setAttributes(instance, allowedAttributes);
791     } else {
792         return meta.setAttributes(instance, attributes);
793     }
794     }
795
796     public Object JavaDoc invoke(ObjectName name, String JavaDoc operationName,
797              Object JavaDoc params[], String JavaDoc signature[])
798         throws InstanceNotFoundException, MBeanException,
799            ReflectionException {
800
801     name = nonDefaultDomain(name);
802
803     /* Permission check */
804         Object JavaDoc instance = getMBean(name);
805     String JavaDoc classname = null;
806     try {
807         classname = meta.getMBeanClassName(instance);
808     } catch (IntrospectionException e) {
809         classname = null;
810     } catch (NotCompliantMBeanException e) {
811         classname = null;
812     }
813     checkMBeanPermission(classname, operationName, name, "invoke");
814
815         return meta.invoke(instance, operationName, params, signature);
816     }
817
818     /**
819      * Return the MetaData service object used by this interceptor.
820      *
821      **/

822     protected MetaData meta() {
823     return meta;
824     }
825
826     /**
827      * Builds an ObjectInstance.
828      * <ul>
829      * <li> If the given <code>object</code> implements DynamicMBean,
830      * then ask its MBeanInfo for the class name.</li>
831      * <li> Otherwise, uses the provided <code>className</code></li>
832      * </ul>
833      *
834      * @return A new ObjectInstance for the given <code>object</code>.
835      * @exception NotCompliantMBeanException if the <code>object</code>
836      * implements DynamicMBean but the class name can't be
837      * retrieved from its MBeanInfo.
838      **/

839     protected ObjectInstance makeObjectInstance(String JavaDoc className,
840                         Object JavaDoc object,
841                         ObjectName name)
842         throws NotCompliantMBeanException {
843
844     // if the MBean is a dynamic MBean ask its MBeanInfo for the
845
// class name
846
if (object instanceof DynamicMBean) {
847         try {
848         className = meta.getMBeanClassName(object);
849         } catch (SecurityException JavaDoc x) {
850         debugX("makeObjectInstance",x);
851         throw x;
852         } catch (IntrospectionException x) {
853         debugX("makeObjectInstance",x);
854         throw new NotCompliantMBeanException(
855                "Can't obtain class name for " + name + ": " + x);
856         } catch (JMRuntimeException x) {
857         debugX("makeObjectInstance",x);
858         throw new NotCompliantMBeanException(
859                "Can't obtain class name for " + name + ": " + x);
860         }
861     }
862
863     if (className == null) {
864         throw new NotCompliantMBeanException(
865                  "The class Name returned is null");
866     }
867
868         return(new ObjectInstance(nonDefaultDomain(name), className));
869     }
870
871     /**
872      * Register <code>object</code> in the repository, with the
873      * given <code>name</code>.
874      * This method is called by the various createMBean() flavours
875      * and by registerMBean() after all MBean compliance tests
876      * have been performed.
877      * <p>
878      * This method does not performed any kind of test compliance,
879      * and the caller should make sure that the given <code>object</object>
880      * is MBean compliant.
881      * <p>
882      * This methods performed all the basic steps needed for object
883      * registration:
884      * <ul>
885      * <li>If the <code>object</code> implements the MBeanRegistration
886      * interface, it invokes preRegister() on the object.</li>
887      * <li>Then the object is added to the repository with the given
888      * <code>name</code>.</li>
889      * <li>Finally, if the <code>object</code> implements the
890      * MBeanRegistration interface, it invokes postRegister()
891      * on the object.</li>
892      * </ul>
893      * @param object A reference to a MBean compliant object.
894      * @param name The ObjectName of the <code>object</code> MBean.
895      * @return the actual ObjectName with which the object was registered.
896      * @exception InstanceAlreadyExistsException if an object is already
897      * registered with that name.
898      * @exception MBeanRegistrationException if an exception occurs during
899      * registration.
900      **/

901     protected ObjectInstance registerObject(String JavaDoc classname,
902                         Object JavaDoc object, ObjectName name)
903     throws InstanceAlreadyExistsException,
904            MBeanRegistrationException,
905            NotCompliantMBeanException {
906       
907         if (object == null) {
908         final RuntimeException JavaDoc wrapped =
909         new IllegalArgumentException JavaDoc("Cannot add null object");
910             throw new RuntimeOperationsException(wrapped,
911                         "Exception occured trying to register the MBean");
912         }
913
914     name = nonDefaultDomain(name);
915
916         if (isTraceOn()) {
917             trace(dbgTag, "registerMBean", "ObjectName = " + name);
918         }
919     
920     ObjectName logicalName = name;
921
922         if (object instanceof MBeanRegistration) {
923             logicalName = meta.preRegisterInvoker(object, name, server);
924         if (logicalName != name && logicalName != null) {
925         logicalName =
926             ObjectName.getInstance(nonDefaultDomain(logicalName));
927         }
928         }
929
930     /* Permission check */
931     checkMBeanPermission(classname, null, logicalName, "registerMBean");
932
933     final ObjectInstance result;
934         if (logicalName!=null) {
935         result = makeObjectInstance(classname, object, logicalName);
936             internal_addObject(object, logicalName);
937         } else {
938             if (object instanceof MBeanRegistration ) {
939                 meta.postRegisterInvoker(object, false);
940             }
941         final RuntimeException JavaDoc wrapped =
942         new IllegalArgumentException JavaDoc("No object name specified");
943             throw new RuntimeOperationsException(wrapped,
944                         "Exception occured trying to register the MBean");
945         }
946
947         if (object instanceof MBeanRegistration)
948             meta.postRegisterInvoker(object, true);
949
950         /**
951          * Checks if the newly registered MBean is a ClassLoader
952      * If so, tell the ClassLoaderRepository (CLR) about it. We do
953      * this even if the object is a PrivateClassLoader. In that
954      * case, the CLR remembers the loader for use when it is
955      * explicitly named (e.g. as the loader in createMBean) but
956      * does not add it to the list that is consulted by
957      * ClassLoaderRepository.loadClass.
958          */

959         if (object instanceof ClassLoader JavaDoc) {
960         final ModifiableClassLoaderRepository clr =
961         instantiator.getClassLoaderRepository();
962         if (clr == null) {
963         final RuntimeException JavaDoc wrapped =
964             new IllegalArgumentException JavaDoc(
965              "Dynamic addition of class loaders is not supported");
966         throw new RuntimeOperationsException(wrapped,
967        "Exception occured trying to register the MBean as a class loader");
968         }
969         clr.addClassLoader(logicalName, (ClassLoader JavaDoc)object);
970         }
971
972     return result;
973     }
974
975     /**
976      * Register an object from within createMBean().
977      * This method wrapps registerObject() and is only called from within
978      * createMBean().
979      * It calls directly registerObject(). Its only purpose is to provide
980      * hooks for derived classes.
981      **/

982     protected ObjectInstance registerCreatedObject(String JavaDoc classname,
983                            Object JavaDoc object,
984                            ObjectName name)
985     throws InstanceAlreadyExistsException,
986            MBeanRegistrationException,
987            NotCompliantMBeanException {
988     return registerObject(classname,object,name);
989     }
990
991     /**
992      * Gets a specific MBean controlled by the DefaultMBeanServerInterceptor.
993      * The name must have a non-default domain.
994      */

995     private Object JavaDoc getMBean(ObjectName name)
996     throws InstanceNotFoundException {
997
998         if (name == null) {
999             throw new RuntimeOperationsException(new
1000        IllegalArgumentException JavaDoc("Object name cannot be null"),
1001                   "Exception occured trying to get an MBean");
1002        }
1003        Object JavaDoc obj = null;
1004        synchronized(this) {
1005            obj = repository.retrieve(name);
1006            if (obj == null) {
1007        if (isTraceOn()) {
1008            trace("getMBean", name+": Found no object");
1009        }
1010        throw new InstanceNotFoundException(name.toString());
1011            }
1012        }
1013        return obj;
1014    }
1015
1016    private ObjectName nonDefaultDomain(ObjectName name) {
1017    if (name == null || name.getDomain().length() > 0)
1018        return name;
1019
1020    /* The ObjectName looks like ":a=b", and that's what its
1021       toString() will return in this implementation. So
1022       we can just stick the default domain in front of it
1023       to get a non-default-domain name. We depend on the
1024       fact that toString() works like that and that it
1025       leaves wildcards in place (so we can detect an error
1026       if one is supplied where it shouldn't be). */

1027    final String JavaDoc completeName = domain + name;
1028
1029    try {
1030        return new ObjectName(completeName);
1031    } catch (MalformedObjectNameException e) {
1032        final String JavaDoc msg =
1033        "Unexpected default domain problem: " + completeName + ": " +
1034        e;
1035        throw new IllegalArgumentException JavaDoc(msg);
1036    }
1037    }
1038
1039    public String JavaDoc getDefaultDomain() {
1040        return domain;
1041    }
1042
1043    /*
1044     * Notification handling.
1045     *
1046     * This is not trivial, because the MBeanServer translates the
1047     * source of a received notification from a reference to an MBean
1048     * into the ObjectName of that MBean. While that does make
1049     * notification sending easier for MBean writers, it comes at a
1050     * considerable cost. We need to replace the source of a
1051     * notification, which is basically wrong if there are also
1052     * listeners registered directly with the MBean (without going
1053     * through the MBean server). We also need to wrap the listener
1054     * supplied by the client of the MBeanServer with a listener that
1055     * performs the substitution before forwarding. This is why we
1056     * strongly discourage people from putting MBean references in the
1057     * source of their notifications. Instead they should arrange to
1058     * put the ObjectName there themselves.
1059     *
1060     * However, existing code relies on the substitution, so we are
1061     * stuck with it.
1062     *
1063     * Here's how we handle it. When you add a listener, we make a
1064     * ListenerWrapper around it. We look that up in the
1065     * listenerWrappers map, and if there was already a wrapper for
1066     * that listener with the given ObjectName, we reuse it. This map
1067     * is a WeakHashMap, so a listener that is no longer registered
1068     * with any MBean can be garbage collected.
1069     *
1070     * We cannot use simpler solutions such as always creating a new
1071     * wrapper or always registering the same listener with the MBean
1072     * and using the handback to find the client's original listener.
1073     * The reason is that we need to support the removeListener
1074     * variant that removes all (listener,filter,handback) triples on
1075     * a broadcaster that have a given listener. And we do not have
1076     * any way to inspect a broadcaster's internal list of triples.
1077     * So the same client listener must always map to the same
1078     * listener registered with the broadcaster.
1079     *
1080     * Another possible solution would be to map from ObjectName to
1081     * list of listener wrappers (or IdentityHashMap of listener
1082     * wrappers), making this list the first time a listener is added
1083     * on a given MBean, and removing it when the MBean is removed.
1084     * This is probably more costly in memory, but could be useful if
1085     * some day we don't want to rely on weak references.
1086     */

1087    public void addNotificationListener(ObjectName name,
1088                    NotificationListener listener,
1089                    NotificationFilter filter,
1090                    Object JavaDoc handback)
1091        throws InstanceNotFoundException {
1092
1093    // ------------------------------
1094
// ------------------------------
1095
if (isTraceOn()) {
1096            trace("addNotificationListener", "obj= " + name);
1097        }
1098
1099    /* Permission check */
1100        Object JavaDoc instance = getMBean(name);
1101    String JavaDoc classname = null;
1102    try {
1103        classname = meta.getMBeanClassName(instance);
1104    } catch (IntrospectionException e) {
1105        classname = null;
1106    } catch (NotCompliantMBeanException e) {
1107        classname = null;
1108    }
1109    checkMBeanPermission(classname, null, name, "addNotificationListener");
1110
1111        NotificationBroadcaster broadcaster;
1112
1113    if (!(instance instanceof NotificationBroadcaster)) {
1114            throw new RuntimeOperationsException(new
1115        IllegalArgumentException JavaDoc(name.getCanonicalName() ),
1116                "The MBean " + name.getCanonicalName() +
1117                " does not implement the NotificationBroadcaster interface");
1118        }
1119    broadcaster = (NotificationBroadcaster) instance;
1120
1121        // ------------------
1122
// Check listener
1123
// ------------------
1124
if (listener == null) {
1125        throw new RuntimeOperationsException(new
1126        IllegalArgumentException JavaDoc("Null listener"),"Null listener");
1127    }
1128
1129    NotificationListener listenerWrapper =
1130        getListenerWrapper(listener, name, instance, true);
1131    broadcaster.addNotificationListener(listenerWrapper, filter, handback);
1132    }
1133
1134    public void addNotificationListener(ObjectName name,
1135                    ObjectName listener,
1136                    NotificationFilter filter,
1137                    Object JavaDoc handback)
1138        throws InstanceNotFoundException {
1139
1140    // ------------------------------
1141
// ------------------------------
1142

1143        // ----------------
1144
// Get listener object
1145
// ----------------
1146
Object JavaDoc instance = getMBean(listener);
1147        if (!(instance instanceof NotificationListener)) {
1148        throw new RuntimeOperationsException(new
1149        IllegalArgumentException JavaDoc(listener.getCanonicalName()),
1150        "The MBean " + listener.getCanonicalName() +
1151        "does not implement the NotificationListener interface") ;
1152        }
1153
1154        // ----------------
1155
// Add a listener on an MBean
1156
// ----------------
1157
if (isTraceOn()) {
1158            trace("addNotificationListener", "obj= " + name + " listener= " +
1159          listener);
1160        }
1161        server.addNotificationListener(name,(NotificationListener) instance,
1162                       filter, handback) ;
1163    }
1164
1165    public void removeNotificationListener(ObjectName name,
1166                       NotificationListener listener)
1167        throws InstanceNotFoundException, ListenerNotFoundException {
1168    removeNotificationListener(name, listener, null, null, true);
1169    }
1170
1171    public void removeNotificationListener(ObjectName name,
1172                       NotificationListener listener,
1173                       NotificationFilter filter,
1174                       Object JavaDoc handback)
1175        throws InstanceNotFoundException, ListenerNotFoundException {
1176    removeNotificationListener(name, listener, filter, handback, false);
1177    }
1178
1179    public void removeNotificationListener(ObjectName name,
1180                       ObjectName listener)
1181        throws InstanceNotFoundException, ListenerNotFoundException {
1182    NotificationListener instance = getListener(listener);
1183
1184        if (isTraceOn()) {
1185            trace("removeNotificationListener", "obj= " + name +
1186          " listener= " + listener);
1187        }
1188    server.removeNotificationListener(name, instance);
1189    }
1190
1191    public void removeNotificationListener(ObjectName name,
1192                       ObjectName listener,
1193                       NotificationFilter filter,
1194                       Object JavaDoc handback)
1195        throws InstanceNotFoundException, ListenerNotFoundException {
1196
1197    NotificationListener instance = getListener(listener);
1198
1199        if (isTraceOn()) {
1200            trace("removeNotificationListener", "obj= " + name +
1201          " listener= " + listener);
1202        }
1203    server.removeNotificationListener(name, instance, filter, handback);
1204    }
1205
1206    private NotificationListener getListener(ObjectName listener)
1207    throws ListenerNotFoundException {
1208        // ----------------
1209
// Get listener object
1210
// ----------------
1211
final Object JavaDoc instance;
1212        try {
1213        instance = getMBean(listener);
1214    } catch (InstanceNotFoundException e) {
1215        throw new ListenerNotFoundException(e.getMessage()) ;
1216    }
1217
1218        if (!(instance instanceof NotificationListener)) {
1219        final RuntimeException JavaDoc exc =
1220        new IllegalArgumentException JavaDoc(listener.getCanonicalName());
1221        final String JavaDoc msg =
1222        "MBean " + listener.getCanonicalName() + " does not " +
1223        "implement " + NotificationListener.class.getName();
1224            throw new RuntimeOperationsException(exc, msg);
1225        }
1226    return (NotificationListener) instance;
1227    }
1228
1229    private void removeNotificationListener(ObjectName name,
1230                        NotificationListener listener,
1231                        NotificationFilter filter,
1232                        Object JavaDoc handback,
1233                        boolean removeAll)
1234        throws InstanceNotFoundException, ListenerNotFoundException {
1235
1236        if (isTraceOn()) {
1237            trace("removeNotificationListener", "obj= " + name);
1238        }
1239
1240    /* Permission check */
1241        Object JavaDoc instance = getMBean(name);
1242    String JavaDoc classname = null;
1243    try {
1244        classname = meta.getMBeanClassName(instance);
1245    } catch (IntrospectionException e) {
1246        classname = null;
1247    } catch (NotCompliantMBeanException e) {
1248        classname = null;
1249    }
1250    checkMBeanPermission(classname, null, name,
1251                 "removeNotificationListener");
1252
1253    /* We could simplify the code by assigning broadcaster after
1254       assigning listenerWrapper, but that would change the error
1255       behaviour when both the broadcaster and the listener are
1256       erroneous. */

1257        NotificationBroadcaster broadcaster = null;
1258    NotificationEmitter emitter = null;
1259    if (removeAll) {
1260        if (!(instance instanceof NotificationBroadcaster)) {
1261        final RuntimeException JavaDoc exc =
1262            new IllegalArgumentException JavaDoc(name.getCanonicalName());
1263        final String JavaDoc msg =
1264            "MBean " + name.getCanonicalName() + " does not " +
1265            "implement " + NotificationBroadcaster.class.getName();
1266        throw new RuntimeOperationsException(exc, msg);
1267        }
1268        broadcaster = (NotificationBroadcaster) instance;
1269    } else {
1270        if (!(instance instanceof NotificationEmitter)) {
1271        final RuntimeException JavaDoc exc =
1272            new IllegalArgumentException JavaDoc(name.getCanonicalName());
1273        final String JavaDoc msg =
1274            "MBean " + name.getCanonicalName() + " does not " +
1275            "implement " + NotificationEmitter.class.getName();
1276        throw new RuntimeOperationsException(exc, msg);
1277        }
1278        emitter = (NotificationEmitter) instance;
1279    }
1280
1281    NotificationListener listenerWrapper =
1282        getListenerWrapper(listener, name, instance, false);
1283
1284        if (listenerWrapper == null)
1285            throw new ListenerNotFoundException("Unknown listener");
1286
1287    if (removeAll)
1288        broadcaster.removeNotificationListener(listenerWrapper);
1289    else {
1290        emitter.removeNotificationListener(listenerWrapper,
1291                           filter,
1292                           handback);
1293    }
1294    }
1295
1296    public MBeanInfo getMBeanInfo(ObjectName name)
1297    throws InstanceNotFoundException, IntrospectionException,
1298           ReflectionException {
1299
1300    // ------------------------------
1301
// ------------------------------
1302

1303        Object JavaDoc moi = getMBean(name);
1304    final MBeanInfo mbi = meta.getMBeanInfo(moi);
1305    if (mbi == null)
1306        throw new JMRuntimeException("MBean " + name +
1307                     "has no MBeanInfo");
1308
1309    /* Permission check */
1310    checkMBeanPermission(mbi.getClassName(), null, name, "getMBeanInfo");
1311
1312    return mbi;
1313    }
1314
1315    public boolean isInstanceOf(ObjectName name, String JavaDoc className)
1316    throws InstanceNotFoundException {
1317
1318    /* Permission check */
1319        Object JavaDoc instance = getMBean(name);
1320    String JavaDoc classname = null;
1321    try {
1322        classname = meta.getMBeanClassName(instance);
1323    } catch (IntrospectionException e) {
1324        classname = null;
1325    } catch (NotCompliantMBeanException e) {
1326        classname = null;
1327    }
1328    checkMBeanPermission(classname, null, name, "isInstanceOf");
1329
1330    try {
1331        return meta.isInstanceOf(instance, className);
1332    } catch (ReflectionException e) {
1333        debugX("isInstanceOf",e);
1334        return false;
1335    }
1336    }
1337
1338    /**
1339     * <p>Return the {@link java.lang.ClassLoader} that was used for
1340     * loading the class of the named MBean.
1341     * @param mbeanName The ObjectName of the MBean.
1342     * @return The ClassLoader used for that MBean.
1343     * @exception InstanceNotFoundException if the named MBean is not found.
1344     */

1345    public ClassLoader JavaDoc getClassLoaderFor(ObjectName mbeanName)
1346    throws InstanceNotFoundException {
1347
1348    /* Permission check */
1349        Object JavaDoc instance = getMBean(mbeanName);
1350    String JavaDoc classname = null;
1351    try {
1352        classname = meta.getMBeanClassName(instance);
1353    } catch (IntrospectionException e) {
1354        classname = null;
1355    } catch (NotCompliantMBeanException e) {
1356        classname = null;
1357    }
1358    checkMBeanPermission(classname, null, mbeanName, "getClassLoaderFor");
1359
1360    return instance.getClass().getClassLoader();
1361    }
1362   
1363    /**
1364     * <p>Return the named {@link java.lang.ClassLoader}.
1365     * @param loaderName The ObjectName of the ClassLoader.
1366     * @return The named ClassLoader.
1367     * @exception InstanceNotFoundException if the named ClassLoader
1368     * is not found.
1369     */

1370    public ClassLoader JavaDoc getClassLoader(ObjectName loaderName)
1371        throws InstanceNotFoundException {
1372
1373    if (loaderName == null) {
1374        checkMBeanPermission(null, null, null, "getClassLoader");
1375        return server.getClass().getClassLoader();
1376    }
1377
1378        Object JavaDoc instance = getMBean(loaderName);
1379    String JavaDoc classname = null;
1380    try {
1381        classname = meta.getMBeanClassName(instance);
1382    } catch (IntrospectionException e) {
1383        classname = null;
1384    } catch (NotCompliantMBeanException e) {
1385        classname = null;
1386    }
1387    checkMBeanPermission(classname, null, loaderName, "getClassLoader");
1388
1389    /* Check if the given MBean is a ClassLoader */
1390    if (!(instance instanceof ClassLoader JavaDoc))
1391        throw new InstanceNotFoundException(loaderName.toString() +
1392                                                " is not a classloader");
1393
1394    return (ClassLoader JavaDoc) instance;
1395    }
1396
1397    /**
1398     * Adds a MBean in the repository
1399     */

1400    private void internal_addObject(Object JavaDoc object, ObjectName logicalName)
1401    throws InstanceAlreadyExistsException {
1402
1403    // ------------------------------
1404
// ------------------------------
1405

1406        // Let the repository do the work.
1407

1408        synchronized(this) {
1409            try {
1410                repository.addMBean(object, logicalName);
1411            }
1412            catch (InstanceAlreadyExistsException e) {
1413                if (object instanceof MBeanRegistration ) {
1414                    meta.postRegisterInvoker(object,false);
1415                }
1416                throw e;
1417            }
1418        }
1419        // ---------------------
1420
// Send create event
1421
// ---------------------
1422
if (isTraceOn()) {
1423            trace("addObject", "Send create notification of object " +
1424          logicalName.getCanonicalName());
1425        }
1426
1427        sendNotification(MBeanServerNotification.REGISTRATION_NOTIFICATION,
1428             logicalName ) ;
1429    }
1430
1431    /**
1432     * Sends an MBeanServerNotifications with the specified type for the
1433     * MBean with the specified ObjectName
1434     */

1435    private void sendNotification(String JavaDoc NotifType, ObjectName name) {
1436
1437    // ------------------------------
1438
// ------------------------------
1439

1440        // ---------------------
1441
// Create notification
1442
// ---------------------
1443
MBeanServerNotification notif = new
1444        MBeanServerNotification(NotifType,_MBSDelegateObjectName,0,name);
1445
1446    if (isTraceOn()) {
1447        trace("sendNotification", NotifType + " " + name);
1448    }
1449
1450    delegate.sendNotification(notif);
1451    }
1452
1453    /**
1454     * Performs the necessary initializations for the MBeanServer.
1455     * Creates and registers the MetaData service and the MBeanServer
1456     * identification MBean
1457     */

1458    private void initialize(String JavaDoc domain,
1459                MBeanServer outer,
1460                MBeanServerDelegate delegate,
1461                MBeanInstantiator inst,
1462                MetaData meta,
1463                Repository JavaDoc repos) {
1464
1465    // ------------------------------
1466
// ------------------------------
1467

1468    if (!this.domain.equals(repository.getDefaultDomain()))
1469        throw new IllegalArgumentException JavaDoc("Domain Name Mismatch");
1470        try {
1471            queryByRepo = repository.isFiltering();
1472        } catch (SecurityException JavaDoc e) {
1473        throw e;
1474        } catch (Exception JavaDoc e) {
1475            queryByRepo = false;
1476        }
1477    }
1478
1479    /**
1480     * Applies the specified queries to the set of objects
1481     */

1482    private Set JavaDoc filterListOfObjects(Set JavaDoc list, QueryExp query) {
1483        Set JavaDoc result = new HashSet JavaDoc();
1484
1485        // No query ...
1486
if (query == null ) {
1487            for (final Iterator JavaDoc i = list.iterator(); i.hasNext(); ) {
1488                final NamedObject no = (NamedObject) i.next();
1489        final Object JavaDoc obj = no.getObject();
1490        String JavaDoc className = null;
1491
1492        try {
1493            className = meta.getMBeanClassName(obj);
1494        } catch (JMException x) {
1495            if (isDebugOn()) {
1496            debug("filterListOfObjects",
1497                  "Can't obtain class name for " +
1498                  no.getName() + ": " + x);
1499            debugX("filterListOfObjects",x);
1500            }
1501        }
1502
1503        result.add(new ObjectInstance(no.getName(), className));
1504            }
1505        } else {
1506            // Access the filter
1507
for (final Iterator JavaDoc i = list.iterator(); i.hasNext(); ) {
1508                final NamedObject no = (NamedObject) i.next();
1509                final Object JavaDoc obj = no.getObject();
1510                boolean res = false;
1511        MBeanServer oldServer = QueryEval.getMBeanServer();
1512        query.setMBeanServer(server);
1513                try {
1514                    res = query.apply(no.getName());
1515                } catch (Exception JavaDoc e) {
1516                    res = false;
1517                } finally {
1518            /*
1519             * query.setMBeanServer is probably
1520             * QueryEval.setMBeanServer so put back the old
1521             * value. Since that method uses a ThreadLocal
1522             * variable, this code is only needed for the
1523             * unusual case where the user creates a custom
1524             * QueryExp that calls a nested query on another
1525             * MBeanServer.
1526             */

1527            query.setMBeanServer(oldServer);
1528        }
1529                if (res) {
1530            // if the MBean is a dynamic MBean ask its MBeanInfo
1531
// for the class name
1532
String JavaDoc className = null;
1533            try {
1534            className = meta.getMBeanClassName(obj);
1535            } catch (JMException x) {
1536            if (isDebugOn()) {
1537                debug("filterListOfObjects",
1538                  "Can't obtain class name for " +
1539                  no.getName() + ": " + x);
1540                debugX("filterListOfObjects",x);
1541            }
1542            }
1543            result.add(new ObjectInstance(no.getName(), className));
1544                }
1545            }
1546        }
1547    return result;
1548    }
1549
1550    /**
1551     * Applies the specified queries to the set of ObjectInstances.
1552     */

1553    private Set JavaDoc filterListOfObjectInstances(Set JavaDoc list, QueryExp query) {
1554        // Null query.
1555
//
1556
if (query == null) {
1557        return list;
1558        } else {
1559        Set JavaDoc result = new HashSet JavaDoc();
1560            // Access the filter.
1561
//
1562
for (final Iterator JavaDoc i = list.iterator(); i.hasNext(); ) {
1563        final ObjectInstance oi = (ObjectInstance) i.next();
1564                boolean res = false;
1565        MBeanServer oldServer = QueryEval.getMBeanServer();
1566        query.setMBeanServer(server);
1567                try {
1568                    res = query.apply(oi.getObjectName());
1569                } catch (Exception JavaDoc e) {
1570                    res = false;
1571                } finally {
1572            /*
1573             * query.setMBeanServer is probably
1574             * QueryEval.setMBeanServer so put back the old
1575             * value. Since that method uses a ThreadLocal
1576             * variable, this code is only needed for the
1577             * unusual case where the user creates a custom
1578             * QueryExp that calls a nested query on another
1579             * MBeanServer.
1580             */

1581            query.setMBeanServer(oldServer);
1582        }
1583                if (res) {
1584            result.add(oi);
1585                }
1586            }
1587        return result;
1588        }
1589    }
1590
1591    /*
1592     * Get the existing wrapper for this listener, name, and mbean, if
1593     * there is one. Otherwise, if "create" is true, create and
1594     * return one. Otherwise, return null.
1595     *
1596     * We use a WeakHashMap so that if the only reference to a user
1597     * listener is in listenerWrappers, it can be garbage collected.
1598     * This requires a certain amount of care, because only the key in
1599     * a WeakHashMap is weak; the value is strong. We need to recover
1600     * the existing wrapper object (not just an object that is equal
1601     * to it), so we would like listenerWrappers to map any
1602     * ListenerWrapper to the canonical ListenerWrapper for that
1603     * (listener,name,mbean) set. But we do not want this canonical
1604     * wrapper to be referenced strongly. Therefore we put it inside
1605     * a WeakReference and that is the value in the WeakHashMap.
1606     */

1607    private NotificationListener getListenerWrapper(NotificationListener l,
1608                            ObjectName name,
1609                            Object JavaDoc mbean,
1610                            boolean create) {
1611    NotificationListener wrapper = new ListenerWrapper(l, name, mbean);
1612    synchronized (listenerWrappers) {
1613        WeakReference JavaDoc ref = (WeakReference JavaDoc) listenerWrappers.get(wrapper);
1614        if (ref != null) {
1615        NotificationListener existing =
1616            (NotificationListener) ref.get();
1617        if (existing != null)
1618            return existing;
1619        }
1620        if (create) {
1621        listenerWrappers.put(wrapper, new WeakReference JavaDoc(wrapper));
1622        return wrapper;
1623        } else
1624        return null;
1625    }
1626    }
1627
1628    private static class ListenerWrapper implements NotificationListener {
1629    ListenerWrapper(NotificationListener l, ObjectName name,
1630            Object JavaDoc mbean) {
1631        this.listener = l;
1632        this.name = name;
1633        this.mbean = mbean;
1634    }
1635
1636    public void handleNotification(Notification notification,
1637                       Object JavaDoc handback) {
1638        if (notification != null) {
1639        if (notification.getSource() == mbean)
1640            notification.setSource(name);
1641        }
1642
1643        /*
1644         * Listeners are not supposed to throw exceptions. If
1645         * this one does, we could remove it from the MBean. It
1646         * might indicate that a connector has stopped working,
1647         * for instance, and there is no point in sending future
1648         * notifications over that connection. However, this
1649         * seems rather drastic, so instead we propagate the
1650         * exception and let the broadcaster handle it.
1651         */

1652        listener.handleNotification(notification, handback);
1653    }
1654
1655    public boolean equals(Object JavaDoc o) {
1656        if (!(o instanceof ListenerWrapper))
1657        return false;
1658        ListenerWrapper w = (ListenerWrapper) o;
1659        return (w.listener == listener && w.mbean == mbean
1660            && w.name.equals(name));
1661        /*
1662         * We compare all three, in case the same MBean object
1663         * gets unregistered and then reregistered under a
1664         * different name, or the same name gets assigned to two
1665         * different MBean objects at different times. We do the
1666         * comparisons in this order to avoid the slow
1667         * ObjectName.equals when possible.
1668         */

1669    }
1670
1671    public int hashCode() {
1672        return (System.identityHashCode(listener) ^
1673            System.identityHashCode(mbean));
1674        /*
1675         * We do not include name.hashCode() in the hash because
1676         * computing it is slow and usually we will not have two
1677         * instances of ListenerWrapper with the same mbean but
1678         * different ObjectNames. That can happen if the MBean is
1679         * unregistered from one name and reregistered with
1680         * another, and there is no garbage collection between; or
1681         * if the same object is registered under two names (which
1682         * is not recommended because MBeanRegistration will
1683         * break). But even in these unusual cases the hash code
1684         * does not have to be unique.
1685         */

1686    }
1687
1688    private NotificationListener listener;
1689    private ObjectName name;
1690    private Object JavaDoc mbean;
1691    }
1692
1693    // SECURITY CHECKS
1694
//----------------
1695

1696    private static void checkMBeanPermission(String JavaDoc classname,
1697                         String JavaDoc member,
1698                         ObjectName objectName,
1699                         String JavaDoc actions)
1700    throws SecurityException JavaDoc {
1701    SecurityManager JavaDoc sm = System.getSecurityManager();
1702    if (sm != null) {
1703        Permission JavaDoc perm = new MBeanPermission(classname,
1704                          member,
1705                          objectName,
1706                          actions);
1707        sm.checkPermission(perm);
1708    }
1709    }
1710
1711    private static void checkMBeanTrustPermission(final Class JavaDoc theClass)
1712    throws SecurityException JavaDoc {
1713    SecurityManager JavaDoc sm = System.getSecurityManager();
1714    if (sm != null) {
1715        Permission JavaDoc perm = new MBeanTrustPermission("register");
1716        ProtectionDomain JavaDoc pd = (ProtectionDomain JavaDoc)
1717        AccessController.doPrivileged(new PrivilegedAction JavaDoc() {
1718            public Object JavaDoc run() {
1719            return theClass.getProtectionDomain();
1720            }
1721        });
1722        AccessControlContext JavaDoc acc =
1723        new AccessControlContext JavaDoc(new ProtectionDomain JavaDoc[] { pd });
1724        sm.checkPermission(perm, acc);
1725    }
1726    }
1727
1728    // TRACES & DEBUG
1729
//---------------
1730

1731    private static boolean isTraceOn() {
1732        return Trace.isSelected(Trace.LEVEL_TRACE, Trace.INFO_MBEANSERVER);
1733    }
1734
1735    private static void trace(String JavaDoc clz, String JavaDoc func, String JavaDoc info) {
1736        Trace.send(Trace.LEVEL_TRACE, Trace.INFO_MBEANSERVER, clz, func, info);
1737    }
1738
1739    private static void trace(String JavaDoc func, String JavaDoc info) {
1740        trace(dbgTag, func, info);
1741    }
1742
1743    private static void error(String JavaDoc func, String JavaDoc info) {
1744        Trace.send(Trace.LEVEL_ERROR,Trace.INFO_MBEANSERVER,dbgTag,func,info);
1745    }
1746
1747    private static boolean isDebugOn() {
1748        return Trace.isSelected(Trace.LEVEL_DEBUG, Trace.INFO_MBEANSERVER);
1749    }
1750
1751    private static void debug(String JavaDoc clz, String JavaDoc func, String JavaDoc info) {
1752        Trace.send(Trace.LEVEL_DEBUG, Trace.INFO_MBEANSERVER, clz, func, info);
1753    }
1754
1755    private static void debug(String JavaDoc func, String JavaDoc info) {
1756        debug(dbgTag, func, info);
1757    }
1758
1759    private static void debugX(String JavaDoc func,Throwable JavaDoc e) {
1760    if (isDebugOn()) {
1761        final StringWriter JavaDoc s = new StringWriter JavaDoc();
1762        e.printStackTrace(new PrintWriter JavaDoc(s));
1763        final String JavaDoc stack = s.toString();
1764
1765        debug(dbgTag,func,"Exception caught in "+ func+"(): "+e);
1766        debug(dbgTag,func,stack);
1767
1768        // java.lang.System.err.println("**** Exception caught in "+
1769
// func+"(): "+e);
1770
// java.lang.System.err.println(stack);
1771
}
1772    }
1773}
1774
Popular Tags