OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libjava/] [classpath/] [gnu/] [javax/] [management/] [Server.java] - Blame information for rev 769

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 769 jeremybenn
/* Server.java -- A GNU Classpath management server.
2
   Copyright (C) 2006 Free Software Foundation, Inc.
3
 
4
This file is part of GNU Classpath.
5
 
6
GNU Classpath is free software; you can redistribute it and/or modify
7
it under the terms of the GNU General Public License as published by
8
the Free Software Foundation; either version 2, or (at your option)
9
any later version.
10
 
11
GNU Classpath is distributed in the hope that it will be useful, but
12
WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
General Public License for more details.
15
 
16
You should have received a copy of the GNU General Public License
17
along with GNU Classpath; see the file COPYING.  If not, write to the
18
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19
02110-1301 USA.
20
 
21
Linking this library statically or dynamically with other modules is
22
making a combined work based on this library.  Thus, the terms and
23
conditions of the GNU General Public License cover the whole
24
combination.
25
 
26
As a special exception, the copyright holders of this library give you
27
permission to link this library with independent modules to produce an
28
executable, regardless of the license terms of these independent
29
modules, and to copy and distribute the resulting executable under
30
terms of your choice, provided that you also meet, for each linked
31
independent module, the terms and conditions of the license of that
32
module.  An independent module is a module which is not derived from
33
or based on this library.  If you modify this library, you may extend
34
this exception to your version of the library, but you are not
35
obligated to do so.  If you do not wish to do so, delete this
36
exception statement from your version. */
37
 
38
package gnu.javax.management;
39
 
40
import java.io.ByteArrayInputStream;
41
import java.io.InputStream;
42
import java.io.IOException;
43
import java.io.ObjectInputStream;
44
import java.io.ObjectStreamClass;
45
import java.io.StreamCorruptedException;
46
 
47
import java.lang.reflect.Constructor;
48
import java.lang.reflect.InvocationTargetException;
49
import java.lang.reflect.Method;
50
 
51
import java.util.HashSet;
52
import java.util.Iterator;
53
import java.util.Map;
54
import java.util.Set;
55
 
56
import java.util.concurrent.atomic.AtomicLong;
57
import java.util.concurrent.ConcurrentHashMap;
58
 
59
import javax.management.Attribute;
60
import javax.management.AttributeList;
61
import javax.management.AttributeNotFoundException;
62
import javax.management.BadAttributeValueExpException;
63
import javax.management.BadBinaryOpValueExpException;
64
import javax.management.BadStringOperationException;
65
import javax.management.DynamicMBean;
66
import javax.management.InstanceAlreadyExistsException;
67
import javax.management.InstanceNotFoundException;
68
import javax.management.IntrospectionException;
69
import javax.management.InvalidApplicationException;
70
import javax.management.InvalidAttributeValueException;
71
import javax.management.ListenerNotFoundException;
72
import javax.management.MalformedObjectNameException;
73
import javax.management.MBeanException;
74
import javax.management.MBeanInfo;
75
import javax.management.MBeanPermission;
76
import javax.management.MBeanRegistration;
77
import javax.management.MBeanRegistrationException;
78
import javax.management.MBeanServer;
79
import javax.management.MBeanServerDelegate;
80
import javax.management.MBeanServerNotification;
81
import javax.management.MBeanTrustPermission;
82
import javax.management.NotCompliantMBeanException;
83
import javax.management.Notification;
84
import javax.management.NotificationBroadcaster;
85
import javax.management.NotificationEmitter;
86
import javax.management.NotificationFilter;
87
import javax.management.NotificationListener;
88
import javax.management.ObjectInstance;
89
import javax.management.ObjectName;
90
import javax.management.OperationsException;
91
import javax.management.QueryExp;
92
import javax.management.ReflectionException;
93
import javax.management.RuntimeOperationsException;
94
import javax.management.StandardMBean;
95
 
96
import javax.management.loading.ClassLoaderRepository;
97
 
98
/**
99
 * This class provides an {@link javax.management.MBeanServer}
100
 * implementation for GNU Classpath.
101
 *
102
 * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
103
 * @since 1.5
104
 */
105
public class Server
106
  implements MBeanServer
107
{
108
 
109
  /**
110
   * The name of the delegate bean.
111
   */
112
  private static final ObjectName DELEGATE_NAME;
113
 
114
  /**
115
   * The registered beans, represented as a map of
116
   * {@link javax.management.ObjectName}s to
117
   * {@link gnu.javax.management.Server.ServerInfo}s.
118
   */
119
  private final ConcurrentHashMap<ObjectName,ServerInfo> beans =
120
    new ConcurrentHashMap<ObjectName,ServerInfo>();
121
 
122
  /**
123
   * The default domain.
124
   */
125
  private final String defaultDomain;
126
 
127
  /**
128
   * The outer server.
129
   */
130
  private final MBeanServer outer;
131
 
132
  /**
133
   * The class loader repository.
134
   */
135
  private ClassLoaderRepository repository;
136
 
137
  /**
138
   * The map of listener delegates to the true
139
   * listener.  We wrap this in an inner class
140
   * to delay initialisation until a listener
141
   * is actually added.
142
   */
143
  private static class LazyListenersHolder
144
  {
145
    private static final Map<NotificationListener,NotificationListener> listeners =
146
      new ConcurrentHashMap<NotificationListener,NotificationListener>();
147
  }
148
 
149
  /**
150
   * An MBean that emits notifications when an MBean is registered and
151
   * unregistered with this server.
152
   *
153
   */
154
  private final MBeanServerDelegate delegate;
155
 
156
  /**
157
   * Provides sequencing for notifications about registrations.
158
   */
159
  private static final AtomicLong sequenceNumber = new AtomicLong(1);
160
 
161
  /**
162
   * Initialise the delegate name.
163
   */
164
  static
165
  {
166
    try
167
      {
168
        DELEGATE_NAME =
169
          new ObjectName("JMImplementation:type=MBeanServerDelegate");
170
      }
171
    catch (MalformedObjectNameException e)
172
      {
173
        throw (Error)
174
          (new InternalError("Failed to construct " +
175
                             "the delegate's object name.").initCause(e));
176
      }
177
  }
178
 
179
  /**
180
   * Constructs a new management server using the specified
181
   * default domain, delegate bean and outer server.
182
   *
183
   * @param defaultDomain the default domain to use for beans constructed
184
   *               with no specified domain.
185
   * @param outer an {@link javax.management.MBeanServer} to pass
186
   *              to beans implementing the {@link MBeanRegistration}
187
   *              interface, or <code>null</code> if <code>this</code>
188
   *              should be passed.
189
   * @param delegate the delegate bean for this server.
190
   */
191
  public Server(String defaultDomain, MBeanServer outer,
192
                MBeanServerDelegate delegate)
193
  {
194
    this.defaultDomain = defaultDomain;
195
    this.outer = outer;
196
    this.delegate = delegate;
197
    try
198
      {
199
        registerMBean(delegate, DELEGATE_NAME);
200
      }
201
    catch (InstanceAlreadyExistsException e)
202
      {
203
        throw (Error)
204
          (new InternalError("The delegate bean is " +
205
                             "already registered.").initCause(e));
206
      }
207
    catch (MBeanRegistrationException e)
208
      {
209
        throw (Error)
210
          (new InternalError("The delegate bean's preRegister " +
211
                             "methods threw an exception.").initCause(e));
212
      }
213
    catch (NotCompliantMBeanException e)
214
      {
215
        throw (Error)
216
          (new InternalError("The delegate bean is " +
217
                             "not compliant.").initCause(e));
218
      }
219
  }
220
 
221
  /**
222
   * Checks for the necessary security privileges to perform an
223
   * operation.
224
   *
225
   * @param name the name of the bean being accessed.
226
   * @param member the name of the operation or attribute being
227
   *               accessed, or <code>null</code> if one is not
228
   *               involved.
229
   * @param action the action being performed.
230
   * @throws SecurityException if the action is denied.
231
   */
232
  private void checkSecurity(ObjectName name, String member,
233
                             String action)
234
  {
235
    SecurityManager sm = System.getSecurityManager();
236
    if (sm != null)
237
      try
238
        {
239
          MBeanInfo info = null;
240
          if (name != null)
241
            {
242
              Object bean = getBean(name);
243
              Method method = bean.getClass().getMethod("getMBeanInfo");
244
              info = (MBeanInfo) method.invoke(bean);
245
            }
246
          sm.checkPermission(new MBeanPermission((info == null) ?
247
                                                 null : info.getClassName(),
248
                                                 member, name, action));
249
        }
250
      catch (InstanceNotFoundException e)
251
        {
252
          throw (Error)
253
            (new InternalError("Failed to get bean.").initCause(e));
254
        }
255
      catch (NoSuchMethodException e)
256
        {
257
          throw (Error)
258
            (new InternalError("Failed to get bean info.").initCause(e));
259
        }
260
      catch (IllegalAccessException e)
261
        {
262
          throw (Error)
263
            (new InternalError("Failed to get bean info.").initCause(e));
264
        }
265
      catch (IllegalArgumentException e)
266
        {
267
          throw (Error)
268
            (new InternalError("Failed to get bean info.").initCause(e));
269
        }
270
      catch (InvocationTargetException e)
271
        {
272
          throw (Error)
273
            (new InternalError("Failed to get bean info.").initCause(e));
274
        }
275
  }
276
 
277
  /**
278
   * Retrieves the specified bean.
279
   *
280
   * @param name the name of the bean.
281
   * @return the bean.
282
   * @throws InstanceNotFoundException if the name of the management bean
283
   *                                   could not be resolved.
284
   */
285
  private Object getBean(ObjectName name)
286
    throws InstanceNotFoundException
287
  {
288
    ServerInfo bean = beans.get(name);
289
    if (bean == null)
290
      throw new InstanceNotFoundException("The bean, " + name +
291
                                          ", was not found.");
292
    return bean.getObject();
293
  }
294
 
295
  /**
296
   * Registers the supplied listener with the specified management
297
   * bean.  Notifications emitted by the management bean are forwarded
298
   * to the listener via the server, which will convert an MBean
299
   * references in the source to a portable {@link ObjectName}
300
   * instance.  The notification is otherwise unchanged.
301
   *
302
   * @param name the name of the management bean with which the listener
303
   *             should be registered.
304
   * @param listener the listener which will handle notifications from
305
   *                 the bean.
306
   * @param filter the filter to apply to incoming notifications, or
307
   *               <code>null</code> if no filtering should be applied.
308
   * @param passback an object to be passed to the listener when a
309
   *                 notification is emitted.
310
   * @throws InstanceNotFoundException if the name of the management bean
311
   *                                   could not be resolved.
312
   * @throws SecurityException if a security manager exists and the
313
   *                           caller's permissions don't imply {@link
314
   *                           MBeanPermission(String,String,ObjectName,String)
315
   *                           <code>MBeanPermission(className, null, name,
316
   *                           "addNotificationListener")</code>}.
317
   * @see #removeNotificationListener(ObjectName, NotificationListener)
318
   * @see #removeNotificationListener(ObjectName, NotificationListener,
319
   *                                  NotificationFilter, Object)
320
   * @see NotificationBroadcaster#addNotificationListener(NotificationListener,
321
   *                                                      NotificationFilter,
322
   *                                                      Object)
323
   */
324
  public void addNotificationListener(ObjectName name, NotificationListener listener,
325
                                      NotificationFilter filter, Object passback)
326
    throws InstanceNotFoundException
327
  {
328
    Object bean = getBean(name);
329
    checkSecurity(name, null, "addNotificationListener");
330
    if (bean instanceof NotificationBroadcaster)
331
      {
332
        NotificationBroadcaster bbean = (NotificationBroadcaster) bean;
333
        NotificationListener indirection = new ServerNotificationListener(bean, name,
334
                                                                          listener);
335
        bbean.addNotificationListener(indirection, filter, passback);
336
        LazyListenersHolder.listeners.put(listener, indirection);
337
      }
338
  }
339
 
340
  /**
341
   * <p>
342
   * Registers the supplied listener with the specified management
343
   * bean.  Notifications emitted by the management bean are forwarded
344
   * to the listener via the server, which will convert any MBean
345
   * references in the source to portable {@link ObjectName}
346
   * instances.  The notification is otherwise unchanged.
347
   * </p>
348
   * <p>
349
   * The listener that receives notifications will be the one that is
350
   * registered with the given name at the time this method is called.
351
   * Even if it later unregisters and ceases to use that name, it will
352
   * still receive notifications.
353
   * </p>
354
   *
355
   * @param name the name of the management bean with which the listener
356
   *             should be registered.
357
   * @param listener the name of the listener which will handle
358
   *                 notifications from the bean.
359
   * @param filter the filter to apply to incoming notifications, or
360
   *               <code>null</code> if no filtering should be applied.
361
   * @param passback an object to be passed to the listener when a
362
   *                 notification is emitted.
363
   * @throws InstanceNotFoundException if the name of the management bean
364
   *                                   could not be resolved.
365
   * @throws RuntimeOperationsException if the bean associated with the given
366
   *                                    object name is not a
367
   *                                    {@link NotificationListener}.  This
368
   *                                    exception wraps an
369
   *                                    {@link IllegalArgumentException}.
370
   * @throws SecurityException if a security manager exists and the
371
   *                           caller's permissions don't imply {@link
372
   *                           MBeanPermission(String,String,ObjectName,String)
373
   *                           <code>MBeanPermission(className, null, name,
374
   *                           "addNotificationListener")</code>}.
375
   * @see #removeNotificationListener(ObjectName, NotificationListener)
376
   * @see #removeNotificationListener(ObjectName, NotificationListener,
377
   *                                  NotificationFilter, Object)
378
   * @see NotificationBroadcaster#addNotificationListener(NotificationListener,
379
   *                                                      NotificationFilter,
380
   *                                                      Object)
381
   */
382
  public void addNotificationListener(ObjectName name, ObjectName listener,
383
                                      NotificationFilter filter, Object passback)
384
    throws InstanceNotFoundException
385
  {
386
    Object lbean = getBean(listener);
387
    if (!(lbean instanceof NotificationListener))
388
      {
389
        RuntimeException e =
390
          new IllegalArgumentException("The supplied listener name does not " +
391
                                       "correspond to a notification listener.");
392
        throw new RuntimeOperationsException(e);
393
      }
394
    addNotificationListener(name, ((NotificationListener) lbean), filter, passback);
395
  }
396
 
397
  /**
398
   * <p>
399
   * Instantiates a new instance of the specified management bean
400
   * using the default constructor and registers it with the server
401
   * under the supplied name.  The class is loaded using the
402
   * {@link javax.management.loading.ClassLoaderRepository default
403
   * loader repository} of the server.
404
   * </p>
405
   * <p>
406
   * If the name supplied is <code>null</code>, then the bean is
407
   * expected to implement the {@link MBeanRegistration} interface.
408
   * The {@link MBeanRegistration#preRegister preRegister} method
409
   * of this interface will be used to obtain the name in this case.
410
   * </p>
411
   * <p>
412
   * This method is equivalent to calling {@link
413
   * #createMBean(String, ObjectName, Object[], String[])
414
   * <code>createMBean(className, name, (Object[]) null,
415
   * (String[]) null)</code>} with <code>null</code> parameters
416
   * and signature.
417
   * </p>
418
   *
419
   * @param className the class of the management bean, of which
420
   *                  an instance should be created.
421
   * @param name the name to register the new bean with.
422
   * @return an {@link ObjectInstance} containing the {@link ObjectName}
423
   *         and Java class name of the created instance.
424
   * @throws ReflectionException if an exception occurs in creating
425
   *                             an instance of the bean.
426
   * @throws InstanceAlreadyExistsException if a matching instance
427
   *                                        already exists.
428
   * @throws MBeanRegistrationException if an exception occurs in
429
   *                                    calling the preRegister
430
   *                                    method.
431
   * @throws MBeanException if the bean's constructor throws an exception.
432
   * @throws NotCompliantMBeanException if the created bean is not
433
   *                                    compliant with the JMX specification.
434
   * @throws RuntimeOperationsException if an {@link IllegalArgumentException}
435
   *                                    is thrown by the server due to a
436
   *                                    <code>null</code> class name or object
437
   *                                    name or if the object name is a pattern.
438
   * @throws SecurityException if a security manager exists and the
439
   *                           caller's permissions don't imply the
440
   *                           use of the <code>instantiate</code>
441
   *                           and <code>registerMBean</code> methods.
442
   * @see #createMBean(String, ObjectName, Object[], String[])
443
   */
444
  public ObjectInstance createMBean(String className, ObjectName name)
445
    throws ReflectionException, InstanceAlreadyExistsException,
446
           MBeanRegistrationException, MBeanException,
447
           NotCompliantMBeanException
448
  {
449
    return createMBean(className, name, (Object[]) null, (String[]) null);
450
  }
451
 
452
  /**
453
   * <p>
454
   * Instantiates a new instance of the specified management bean
455
   * using the given constructor and registers it with the server
456
   * under the supplied name.  The class is loaded using the
457
   * {@link javax.management.loading.ClassLoaderRepository default
458
   * loader repository} of the server.
459
   * </p>
460
   * <p>
461
   * If the name supplied is <code>null</code>, then the bean is
462
   * expected to implement the {@link MBeanRegistration} interface.
463
   * The {@link MBeanRegistration#preRegister preRegister} method
464
   * of this interface will be used to obtain the name in this case.
465
   * </p>
466
   *
467
   * @param className the class of the management bean, of which
468
   *                  an instance should be created.
469
   * @param name the name to register the new bean with.
470
   * @param params the parameters for the bean's constructor.
471
   * @param sig the signature of the constructor to use.
472
   * @return an {@link ObjectInstance} containing the {@link ObjectName}
473
   *         and Java class name of the created instance.
474
   * @throws ReflectionException if an exception occurs in creating
475
   *                             an instance of the bean.
476
   * @throws InstanceAlreadyExistsException if a matching instance
477
   *                                        already exists.
478
   * @throws MBeanRegistrationException if an exception occurs in
479
   *                                    calling the preRegister
480
   *                                    method.
481
   * @throws MBeanException if the bean's constructor throws an exception.
482
   * @throws NotCompliantMBeanException if the created bean is not
483
   *                                    compliant with the JMX specification.
484
   * @throws RuntimeOperationsException if an {@link IllegalArgumentException}
485
   *                                    is thrown by the server due to a
486
   *                                    <code>null</code> class name or object
487
   *                                    name or if the object name is a pattern.
488
   * @throws SecurityException if a security manager exists and the
489
   *                           caller's permissions don't imply the
490
   *                           use of the <code>instantiate</code>
491
   *                           and <code>registerMBean</code> methods.
492
   */
493
  public ObjectInstance createMBean(String className, ObjectName name,
494
                                    Object[] params, String[] sig)
495
    throws ReflectionException, InstanceAlreadyExistsException,
496
           MBeanRegistrationException, MBeanException,
497
           NotCompliantMBeanException
498
  {
499
    return registerMBean(instantiate(className, params, sig), name);
500
  }
501
 
502
  /**
503
   * <p>
504
   * Instantiates a new instance of the specified management bean
505
   * using the default constructor and registers it with the server
506
   * under the supplied name.  The class is loaded using the
507
   * given class loader.  If this argument is <code>null</code>,
508
   * then the same class loader as was used to load the server
509
   * is used.
510
   * </p>
511
   * <p>
512
   * If the name supplied is <code>null</code>, then the bean is
513
   * expected to implement the {@link MBeanRegistration} interface.
514
   * The {@link MBeanRegistration#preRegister preRegister} method
515
   * of this interface will be used to obtain the name in this case.
516
   * </p>
517
   * <p>
518
   * This method is equivalent to calling {@link
519
   * #createMBean(String, ObjectName, ObjectName, Object[], String)
520
   * <code>createMBean(className, name, loaderName, (Object[]) null,
521
   * (String) null)</code>} with <code>null</code> parameters
522
   * and signature.
523
   * </p>
524
   *
525
   * @param className the class of the management bean, of which
526
   *                  an instance should be created.
527
   * @param name the name to register the new bean with.
528
   * @param loaderName the name of the class loader.
529
   * @return an {@link ObjectInstance} containing the {@link ObjectName}
530
   *         and Java class name of the created instance.
531
   * @throws ReflectionException if an exception occurs in creating
532
   *                             an instance of the bean.
533
   * @throws InstanceAlreadyExistsException if a matching instance
534
   *                                        already exists.
535
   * @throws MBeanRegistrationException if an exception occurs in
536
   *                                    calling the preRegister
537
   *                                    method.
538
   * @throws MBeanException if the bean's constructor throws an exception.
539
   * @throws NotCompliantMBeanException if the created bean is not
540
   *                                    compliant with the JMX specification.
541
   * @throws InstanceNotFoundException if the specified class loader is not
542
   *                                   registered with the server.
543
   * @throws RuntimeOperationsException if an {@link IllegalArgumentException}
544
   *                                    is thrown by the server due to a
545
   *                                    <code>null</code> class name or object
546
   *                                    name or if the object name is a pattern.
547
   * @throws SecurityException if a security manager exists and the
548
   *                           caller's permissions don't imply the
549
   *                           use of the <code>instantiate</code>
550
   *                           and <code>registerMBean</code> methods.
551
   * @see #createMBean(String, ObjectName, ObjectName, Object[], String[])
552
   */
553
  public ObjectInstance createMBean(String className, ObjectName name,
554
                                    ObjectName loaderName)
555
    throws ReflectionException, InstanceAlreadyExistsException,
556
           MBeanRegistrationException, MBeanException,
557
           NotCompliantMBeanException, InstanceNotFoundException
558
  {
559
    return createMBean(className, name, loaderName, (Object[]) null,
560
                       (String[]) null);
561
  }
562
 
563
  /**
564
   * <p>
565
   * Instantiates a new instance of the specified management bean
566
   * using the given constructor and registers it with the server
567
   * under the supplied name.  The class is loaded using the
568
   * given class loader.  If this argument is <code>null</code>,
569
   * then the same class loader as was used to load the server
570
   * is used.
571
   * </p>
572
   * <p>
573
   * If the name supplied is <code>null</code>, then the bean is
574
   * expected to implement the {@link MBeanRegistration} interface.
575
   * The {@link MBeanRegistration#preRegister preRegister} method
576
   * of this interface will be used to obtain the name in this case.
577
   * </p>
578
   *
579
   * @param className the class of the management bean, of which
580
   *                  an instance should be created.
581
   * @param name the name to register the new bean with.
582
   * @param loaderName the name of the class loader.
583
   * @param params the parameters for the bean's constructor.
584
   * @param sig the signature of the constructor to use.
585
   * @return an {@link ObjectInstance} containing the {@link ObjectName}
586
   *         and Java class name of the created instance.
587
   * @throws ReflectionException if an exception occurs in creating
588
   *                             an instance of the bean.
589
   * @throws InstanceAlreadyExistsException if a matching instance
590
   *                                        already exists.
591
   * @throws MBeanRegistrationException if an exception occurs in
592
   *                                    calling the preRegister
593
   *                                    method.
594
   * @throws MBeanException if the bean's constructor throws an exception.
595
   * @throws NotCompliantMBeanException if the created bean is not
596
   *                                    compliant with the JMX specification.
597
   * @throws InstanceNotFoundException if the specified class loader is not
598
   *                                   registered with the server.
599
   * @throws RuntimeOperationsException if an {@link IllegalArgumentException}
600
   *                                    is thrown by the server due to a
601
   *                                    <code>null</code> class name or object
602
   *                                    name or if the object name is a pattern.
603
   * @throws SecurityException if a security manager exists and the
604
   *                           caller's permissions don't imply the
605
   *                           use of the <code>instantiate</code>
606
   *                           and <code>registerMBean</code> methods.
607
   */
608
  public ObjectInstance createMBean(String className, ObjectName name,
609
                                    ObjectName loaderName, Object[] params,
610
                                    String[] sig)
611
    throws ReflectionException, InstanceAlreadyExistsException,
612
           MBeanRegistrationException, MBeanException,
613
           NotCompliantMBeanException, InstanceNotFoundException
614
  {
615
    return registerMBean(instantiate(className, loaderName, params, sig),
616
                         name);
617
  }
618
 
619
  /**
620
   * Deserializes a byte array using the class loader of the specified
621
   * management bean as its context.
622
   *
623
   * @param name the name of the bean whose class loader should be used.
624
   * @param data the byte array to be deserialized.
625
   * @return the deserialized object stream.
626
   * @deprecated {@link #getClassLoaderFor(ObjectName)} should be used
627
   *             to obtain the class loader of the bean, which can then
628
   *             be used to perform deserialization in the user's code.
629
   * @throws InstanceNotFoundException if the specified bean is not
630
   *                                   registered with the server.
631
   * @throws OperationsException if any I/O error is thrown by the
632
   *                             deserialization process.
633
   * @throws SecurityException if a security manager exists and the
634
   *                           caller's permissions don't imply {@link
635
   *                           MBeanPermission(String,String,ObjectName,String)
636
   *                           <code>MBeanPermission(className, null, name,
637
   *                           "getClassLoaderFor")</code>
638
   */
639
  public ObjectInputStream deserialize(ObjectName name, byte[] data)
640
    throws InstanceNotFoundException, OperationsException
641
  {
642
    try
643
      {
644
        return new ServerInputStream(new ByteArrayInputStream(data),
645
                                     getClassLoaderFor(name));
646
      }
647
    catch (IOException e)
648
      {
649
        throw new OperationsException("An I/O error occurred: " + e);
650
      }
651
  }
652
 
653
  /**
654
   * Deserializes a byte array using the same class loader for its context
655
   * as was used to load the given class.  This class loader is obtained by
656
   * loading the specified class using the {@link
657
   * javax.management.loading.ClassLoaderRepository Class Loader Repository}
658
   * and then using the class loader of the resulting {@link Class} instance.
659
   *
660
   * @param name the name of the class which should be loaded to obtain the
661
   *             class loader.
662
   * @param data the byte array to be deserialized.
663
   * @return the deserialized object stream.
664
   * @deprecated {@link #getClassLoaderRepository} should be used
665
   *             to obtain the class loading repository, which can then
666
   *             be used to obtain the {@link Class} instance and deserialize
667
   *             the array using its class loader.
668
   * @throws OperationsException if any I/O error is thrown by the
669
   *                             deserialization process.
670
   * @throws ReflectionException if an error occurs in obtaining the
671
   *                             {@link Class} instance.
672
   * @throws SecurityException if a security manager exists and the
673
   *                           caller's permissions don't imply {@link
674
   *                           MBeanPermission(String,String,ObjectName,String)
675
   *                           <code>MBeanPermission(null, null, null,
676
   *                           "getClassLoaderRepository")</code>
677
   */
678
  public ObjectInputStream deserialize(String name, byte[] data)
679
    throws OperationsException, ReflectionException
680
  {
681
    try
682
      {
683
        Class<?> c = getClassLoaderRepository().loadClass(name);
684
        return new ServerInputStream(new ByteArrayInputStream(data),
685
                                           c.getClassLoader());
686
      }
687
    catch (IOException e)
688
      {
689
        throw new OperationsException("An I/O error occurred: " + e);
690
      }
691
    catch (ClassNotFoundException e)
692
      {
693
        throw new ReflectionException(e, "The class could not be found.");
694
      }
695
  }
696
 
697
  /**
698
   * Deserializes a byte array using the same class loader for its context
699
   * as was used to load the given class.  The name of the class loader to
700
   * be used is supplied, and may be <code>null</code> if the server's
701
   * class loader should be used instead.
702
   *
703
   * @param name the name of the class which should be loaded to obtain the
704
   *             class loader.
705
   * @param loader the name of the class loader to use, or <code>null</code>
706
   *               if the class loader of the server should be used.
707
   * @param data the byte array to be deserialized.
708
   * @return the deserialized object stream.
709
   * @deprecated {@link #getClassLoader(ObjectName} can be used to obtain
710
   *              the named class loader and deserialize the array.
711
   * @throws InstanceNotFoundException if the specified class loader is not
712
   *                                   registered with the server.
713
   * @throws OperationsException if any I/O error is thrown by the
714
   *                             deserialization process.
715
   * @throws ReflectionException if an error occurs in obtaining the
716
   *                             {@link Class} instance.
717
   * @throws SecurityException if a security manager exists and the
718
   *                           caller's permissions don't imply {@link
719
   *                           MBeanPermission(String,String,ObjectName,String)
720
   *                           <code>MBeanPermission(className, null, loader,
721
   *                           "getClassLoader")</code>
722
   */
723
  public ObjectInputStream deserialize(String name, ObjectName loader, byte[] data)
724
    throws InstanceNotFoundException, ReflectionException,
725
           OperationsException
726
  {
727
    try
728
      {
729
        Class<?> c = getClassLoader(loader).loadClass(name);
730
        return new ServerInputStream(new ByteArrayInputStream(data),
731
                                           c.getClassLoader());
732
      }
733
    catch (IOException e)
734
      {
735
        throw new OperationsException("An I/O error occurred: " + e);
736
      }
737
    catch (ClassNotFoundException e)
738
      {
739
        throw new ReflectionException(e, "The class could not be found.");
740
      }
741
  }
742
 
743
  /**
744
   * Returns the value of the supplied attribute from the specified
745
   * management bean.
746
   *
747
   * @param bean the bean to retrieve the value from.
748
   * @param name the name of the attribute to retrieve.
749
   * @return the value of the attribute.
750
   * @throws AttributeNotFoundException if the attribute could not be
751
   *                                    accessed from the bean.
752
   * @throws MBeanException if the management bean's accessor throws
753
   *                        an exception.
754
   * @throws InstanceNotFoundException if the bean can not be found.
755
   * @throws ReflectionException if an exception was thrown in trying
756
   *                             to invoke the bean's accessor.
757
   * @throws RuntimeOperationsException if an {@link IllegalArgumentException}
758
   *                                    is thrown by the server due to a
759
   *                                    <code>null</code> bean or attribute
760
   *                                    name.
761
   * @throws SecurityException if a security manager exists and the
762
   *                           caller's permissions don't imply {@link
763
   *                           MBeanPermission(String,String,ObjectName,String)
764
   *                           <code>MBeanPermission(className, name, bean,
765
   *                           "getAttribute")</code>}.
766
   * @see DynamicMBean#getAttribute(String)
767
   */
768
  public Object getAttribute(ObjectName bean, String name)
769
    throws MBeanException, AttributeNotFoundException,
770
           InstanceNotFoundException, ReflectionException
771
  {
772
    if (bean == null || name == null)
773
      {
774
        RuntimeException e =
775
          new IllegalArgumentException("One of the supplied arguments was null.");
776
        throw new RuntimeOperationsException(e);
777
      }
778
    Object abean = getBean(bean);
779
    checkSecurity(bean, name, "getAttribute");
780
    if (abean instanceof DynamicMBean)
781
      return ((DynamicMBean) abean).getAttribute(name);
782
    else
783
      try
784
        {
785
          return new StandardMBean(abean, null).getAttribute(name);
786
        }
787
      catch (NotCompliantMBeanException e)
788
        {
789
          throw (Error)
790
            (new InternalError("Failed to create dynamic bean.").initCause(e));
791
        }
792
  }
793
 
794
 
795
  /**
796
   * Returns the values of the named attributes from the specified
797
   * management bean.
798
   *
799
   * @param bean the bean to retrieve the value from.
800
   * @param names the names of the attributes to retrieve.
801
   * @return the values of the attributes.
802
   * @throws InstanceNotFoundException if the bean can not be found.
803
   * @throws ReflectionException if an exception was thrown in trying
804
   *                             to invoke the bean's accessor.
805
   * @throws RuntimeOperationsException if an {@link IllegalArgumentException}
806
   *                                    is thrown by the server due to a
807
   *                                    <code>null</code> bean or attribute
808
   *                                    name.
809
   * @throws SecurityException if a security manager exists and the
810
   *                           caller's permissions don't imply {@link
811
   *                           MBeanPermission(String,String,ObjectName,String)
812
   *                           <code>MBeanPermission(className, null, bean,
813
   *                           "getAttribute")</code>}.  Additionally,
814
   *                           for an attribute name, <code>n</code>, the
815
   *                           caller's permission must imply {@link
816
   *                           MBeanPermission(String,String,ObjectName,String)
817
   *                           <code>MBeanPermission(className, n, bean,
818
   *                           "getAttribute")</code>} or that attribute will
819
   *                           not be included.
820
   *
821
   * @see DynamicMBean#getAttributes(String[])
822
   */
823
  public AttributeList getAttributes(ObjectName bean, String[] names)
824
    throws InstanceNotFoundException, ReflectionException
825
  {
826
    if (bean == null || names == null)
827
      {
828
        RuntimeException e =
829
          new IllegalArgumentException("One of the supplied arguments was null.");
830
        throw new RuntimeOperationsException(e);
831
      }
832
    Object abean = getBean(bean);
833
    checkSecurity(bean, null, "getAttribute");
834
    AttributeList list = new AttributeList(names.length);
835
    for (int a = 0; a < names.length; ++a)
836
      {
837
        if (names[a] == null)
838
          {
839
            RuntimeException e =
840
              new IllegalArgumentException("Argument " + a + " was null.");
841
            throw new RuntimeOperationsException(e);
842
          }
843
        checkSecurity(bean, names[a], "getAttribute");
844
        try
845
          {
846
            Object value;
847
            if (abean instanceof DynamicMBean)
848
              value = ((DynamicMBean) abean).getAttribute(names[a]);
849
            else
850
              try
851
                {
852
                  value = new StandardMBean(abean, null).getAttribute(names[a]);
853
                }
854
              catch (NotCompliantMBeanException e)
855
                {
856
                  throw (Error)
857
                    (new InternalError("Failed to create dynamic bean.").initCause(e));
858
                }
859
            list.add(new Attribute(names[a], value));
860
          }
861
        catch (AttributeNotFoundException e)
862
          {
863
            /* Ignored */
864
          }
865
        catch (MBeanException e)
866
          {
867
            /* Ignored */
868
          }
869
      }
870
    return list;
871
  }
872
 
873
 
874
  /**
875
   * Returns the specified class loader.  If the specified value is
876
   * <code>null</code>, then the class loader of the server will be
877
   * returned.  If <code>l</code> is the requested class loader,
878
   * and <code>r</code> is the actual class loader returned, then
879
   * either <code>l</code> and <code>r</code> will be identical,
880
   * or they will at least return the same class from
881
   * {@link ClassLoader#loadClass(String)} for any given string.
882
   * They may not be identical due to one or the other
883
   * being wrapped in another class loader (e.g. for security).
884
   *
885
   * @param name the name of the class loader to return.
886
   * @return the class loader.
887
   * @throws InstanceNotFoundException if the class loader can not
888
   *                                   be found.
889
   * @throws SecurityException if a security manager exists and the
890
   *                           caller's permissions don't imply {@link
891
   *                           MBeanPermission(String,String,ObjectName,String)
892
   *                           <code>MBeanPermission(className, null, name,
893
   *                           "getClassLoader")</code>
894
   */
895
  public ClassLoader getClassLoader(ObjectName name)
896
    throws InstanceNotFoundException
897
  {
898
    if (name == null)
899
      {
900
        checkSecurity(null, null, "getClassLoader");
901
        return getClass().getClassLoader();
902
      }
903
    Object bean = getBean(name);
904
    checkSecurity(name, null, "getClassLoader");
905
    return (ClassLoader) bean;
906
  }
907
 
908
  /**
909
   * Returns the class loader of the specified management bean.  If
910
   * <code>l</code> is the requested class loader, and <code>r</code>
911
   * is the actual class loader returned, then either <code>l</code>
912
   * and <code>r</code> will be identical, or they will at least
913
   * return the same class from {@link ClassLoader#loadClass(String)}
914
   * for any given string.  They may not be identical due to one or
915
   * the other being wrapped in another class loader (e.g. for
916
   * security).
917
   *
918
   * @param name the name of the bean whose class loader should be
919
   *             returned.
920
   * @return the class loader.
921
   * @throws InstanceNotFoundException if the bean is not registered
922
   *                                   with the server.
923
   * @throws SecurityException if a security manager exists and the
924
   *                           caller's permissions don't imply {@link
925
   *                           MBeanPermission(String,String,ObjectName,String)
926
   *                           <code>MBeanPermission(className, null, name,
927
   *                           "getClassLoaderFor")</code>
928
   */
929
  public ClassLoader getClassLoaderFor(ObjectName name)
930
    throws InstanceNotFoundException
931
  {
932
    Object bean = getBean(name);
933
    checkSecurity(name, null, "getClassLoaderFor");
934
    return bean.getClass().getClassLoader();
935
  }
936
 
937
  /**
938
   * Returns the class loader repository used by this server.
939
   *
940
   * @return the class loader repository.
941
   * @throws SecurityException if a security manager exists and the
942
   *                           caller's permissions don't imply {@link
943
   *                           MBeanPermission(String,String,ObjectName,String)
944
   *                           <code>MBeanPermission(null, null, null,
945
   *                           "getClassLoaderRepository")</code>
946
   */
947
  public ClassLoaderRepository getClassLoaderRepository()
948
  {
949
    return repository;
950
  }
951
 
952
  /**
953
   * Returns the default domain this server applies to beans that have
954
   * no specified domain.
955
   *
956
   * @return the default domain.
957
   */
958
  public String getDefaultDomain()
959
  {
960
    return defaultDomain;
961
  }
962
 
963
  /**
964
   * Returns an array containing all the domains used by beans registered
965
   * with this server.  The ordering of the array is undefined.
966
   *
967
   * @return the list of domains.
968
   * @throws SecurityException if a security manager exists and the
969
   *                           caller's permissions don't imply {@link
970
   *                           MBeanPermission(String,String,ObjectName,String)
971
   *                           <code>MBeanPermission(null, null, name,
972
   *                           "getDomains")</code>}.  Additionally,
973
   *                           for an domain, <code>d</code>, the
974
   *                           caller's permission must imply {@link
975
   *                           MBeanPermission(String,String,ObjectName,String)
976
   *                           <code>MBeanPermission(null, null,
977
   *                           new ObjectName("d:x=x"), "getDomains")</code>}
978
   *                           or that domain will not be included.  Note
979
   *                           that "x=x" is an arbitrary key-value pair
980
   *                           provided to satisfy the constructor.
981
   * @see ObjectName#getDomain()
982
   */
983
  public String[] getDomains()
984
  {
985
    checkSecurity(null, null, "getDomains");
986
    Set<String> domains = new HashSet<String>();
987
    Iterator<ObjectName> iterator = beans.keySet().iterator();
988
    while (iterator.hasNext())
989
      {
990
        String d = iterator.next().getDomain();
991
        try
992
          {
993
            checkSecurity(new ObjectName(d + ":x=x"), null, "getDomains");
994
            domains.add(d);
995
          }
996
        catch (MalformedObjectNameException e)
997
          {
998
            /* Ignored */
999
          }
1000
      }
1001
    return domains.toArray(new String[domains.size()]);
1002
  }
1003
 
1004
  /**
1005
   * Returns the number of management beans registered with this server.
1006
   * This may be less than the real number if the caller's access is
1007
   * restricted.
1008
   *
1009
   * @return the number of registered beans.
1010
   */
1011
  public Integer getMBeanCount()
1012
  {
1013
    return Integer.valueOf(beans.size());
1014
  }
1015
 
1016
  /**
1017
   * Returns information on the given management bean.
1018
   *
1019
   * @param name the name of the management bean.
1020
   * @return an instance of {@link MBeanInfo} for the bean.
1021
   * @throws IntrospectionException if an exception occurs in examining
1022
   *                                the bean.
1023
   * @throws InstanceNotFoundException if the bean can not be found.
1024
   * @throws ReflectionException if an exception occurs when trying
1025
   *                             to invoke {@link DynamicMBean#getMBeanInfo()}
1026
   *                             on the bean.
1027
   * @throws SecurityException if a security manager exists and the
1028
   *                           caller's permissions don't imply {@link
1029
   *                           MBeanPermission(String,String,ObjectName,String)
1030
   *                           <code>MBeanPermission(className, null, name,
1031
   *                           "getMBeanInfo")</code>}.
1032
   * @see DynamicMBean#getMBeanInfo()
1033
   */
1034
  public MBeanInfo getMBeanInfo(ObjectName name)
1035
    throws InstanceNotFoundException, IntrospectionException,
1036
           ReflectionException
1037
  {
1038
    Object bean = getBean(name);
1039
    checkSecurity(name, null, "getMBeanInfo");
1040
    try
1041
      {
1042
        Method method = bean.getClass().getMethod("getMBeanInfo");
1043
        return (MBeanInfo) method.invoke(bean);
1044
      }
1045
    catch (NoSuchMethodException e)
1046
      {
1047
        try
1048
          {
1049
            return new StandardMBean(bean, null).getMBeanInfo();
1050
          }
1051
        catch (NotCompliantMBeanException ex)
1052
          {
1053
            throw new IntrospectionException("An error occurred in executing " +
1054
                                             "getMBeanInfo on the bean: " + ex + ".");
1055
          }
1056
      }
1057
    catch (IllegalAccessException e)
1058
      {
1059
        throw new ReflectionException(e, "Failed to call getMBeanInfo");
1060
      }
1061
    catch (IllegalArgumentException e)
1062
      {
1063
        throw new ReflectionException(e, "Failed to call getMBeanInfo");
1064
      }
1065
    catch (InvocationTargetException e)
1066
      {
1067
        throw new ReflectionException(e, "The method threw an exception");
1068
      }
1069
  }
1070
 
1071
  /**
1072
   * Returns the {@link ObjectInstance} created for the specified
1073
   * management bean on registration.
1074
   *
1075
   * @param name the name of the bean.
1076
   * @return the corresponding {@link ObjectInstance} instance.
1077
   * @throws InstanceNotFoundException if the bean can not be found.
1078
   * @throws SecurityException if a security manager exists and the
1079
   *                           caller's permissions don't imply {@link
1080
   *                           MBeanPermission(String,String,ObjectName,String)
1081
   *                           <code>MBeanPermission(className, null, name,
1082
   *                           "getObjectInstance")</code>
1083
   * @see #createMBean(String, ObjectName)
1084
   */
1085
  public ObjectInstance getObjectInstance(ObjectName name)
1086
    throws InstanceNotFoundException
1087
  {
1088
    ServerInfo bean = beans.get(name);
1089
    if (bean == null)
1090
      throw new InstanceNotFoundException("The bean, " + name +
1091
                                          ", was not found.");
1092
    return bean.getInstance();
1093
  }
1094
 
1095
  /**
1096
   * <p>
1097
   * Creates an instance of the specified class using the list of
1098
   * class loaders from the {@link
1099
   * javax.management.loading.ClassLoaderRepository Class Loader
1100
   * Repository}.  The class should have a public constructor
1101
   * with no arguments.  A reference to the new instance is returned,
1102
   * but the instance is not yet registered with the server.
1103
   * </p>
1104
   * <p>
1105
   * This method is equivalent to calling {@link
1106
   * #instantiate(String, Object[], String[])
1107
   * <code>instantiate(name, (Object[]) null, (String[]) null)</code>}
1108
   * with <code>null</code> parameters and signature.
1109
   * </p>
1110
   *
1111
   * @param name the name of the class of bean to be instantiated.
1112
   * @return an instance of the given class.
1113
   * @throws ReflectionException if an exception is thrown during
1114
   *                             loading the class or calling the
1115
   *                             constructor.
1116
   * @throws MBeanException if the constructor throws an exception.
1117
   * @throws RuntimeOperationsException if an {@link IllegalArgumentException}
1118
   *                                    is thrown by the server due to a
1119
   *                                    <code>null</code> name.
1120
   * @throws SecurityException if a security manager exists and the
1121
   *                           caller's permissions don't imply {@link
1122
   *                           MBeanPermission(String,String,ObjectName,String)
1123
   *                           <code>MBeanPermission(className, null, null,
1124
   *                           "instantiate")</code>}.
1125
   * @see #instantiate(String, Object[], String[])
1126
   */
1127
  public Object instantiate(String name)
1128
    throws ReflectionException, MBeanException
1129
  {
1130
    return instantiate(name, (Object[]) null, (String[]) null);
1131
  }
1132
 
1133
  /**
1134
   * Creates an instance of the specified class using the list of
1135
   * class loaders from the {@link
1136
   * javax.management.loading.ClassLoaderRepository Class Loader
1137
   * Repository}.  The class should have a public constructor
1138
   * matching the supplied signature.  A reference to the new
1139
   * instance is returned, but the instance is not yet
1140
   * registered with the server.
1141
   *
1142
   * @param name the name of the class of bean to be instantiated.
1143
   * @param params the parameters for the constructor.
1144
   * @param sig the signature of the constructor.
1145
   * @return an instance of the given class.
1146
   * @throws ReflectionException if an exception is thrown during
1147
   *                             loading the class or calling the
1148
   *                             constructor.
1149
   * @throws MBeanException if the constructor throws an exception.
1150
   * @throws RuntimeOperationsException if an {@link IllegalArgumentException}
1151
   *                                    is thrown by the server due to a
1152
   *                                    <code>null</code> name.
1153
   * @throws SecurityException if a security manager exists and the
1154
   *                           caller's permissions don't imply {@link
1155
   *                           MBeanPermission(String,String,ObjectName,String)
1156
   *                           <code>MBeanPermission(className, null, null,
1157
   *                           "instantiate")</code>}.
1158
   */
1159
  public Object instantiate(String name, Object[] params, String[] sig)
1160
    throws ReflectionException, MBeanException
1161
  {
1162
    checkSecurity(null, null, "instantiate");
1163
    if (name == null)
1164
      {
1165
        RuntimeException e =
1166
          new IllegalArgumentException("The name was null.");
1167
        throw new RuntimeOperationsException(e);
1168
      }
1169
    Class<?>[] sigTypes = new Class[sig.length];
1170
    for (int a = 0; a < sigTypes.length; ++a)
1171
      {
1172
        try
1173
          {
1174
            sigTypes[a] = repository.loadClass(sig[a]);
1175
          }
1176
        catch (ClassNotFoundException e)
1177
          {
1178
            throw new ReflectionException(e, "The class, " + sigTypes[a] +
1179
                                          ", in the method signature " +
1180
                                          "could not be loaded.");
1181
          }
1182
      }
1183
    try
1184
      {
1185
        Constructor<?> cons =
1186
          repository.loadClass(name).getConstructor(sigTypes);
1187
        return cons.newInstance(params);
1188
      }
1189
    catch (ClassNotFoundException e)
1190
      {
1191
        throw new ReflectionException(e, "The class, " + name +
1192
                                      ", of the constructor " +
1193
                                      "could not be loaded.");
1194
      }
1195
    catch (NoSuchMethodException e)
1196
      {
1197
        throw new ReflectionException(e, "The method, " + name +
1198
                                      ", could not be found.");
1199
      }
1200
    catch (IllegalAccessException e)
1201
      {
1202
        throw new ReflectionException(e, "Failed to instantiate the object");
1203
      }
1204
    catch (InstantiationException e)
1205
      {
1206
        throw new ReflectionException(e, "Failed to instantiate the object");
1207
      }
1208
    catch (InvocationTargetException e)
1209
      {
1210
        throw new MBeanException((Exception) e.getCause(), "The constructor "
1211
                                 + name + " threw an exception");
1212
      }
1213
  }
1214
 
1215
  /**
1216
   * <p>
1217
   * Creates an instance of the specified class using the supplied
1218
   * class loader.  If the class loader given is <code>null</code>,
1219
   * then the class loader of the server will be used.  The class
1220
   * should have a public constructor with no arguments.  A reference
1221
   * to the new instance is returned, but the instance is not yet
1222
   * registered with the server.
1223
   * </p>
1224
   * <p>
1225
   * This method is equivalent to calling {@link
1226
   * #instantiate(String, ObjectName, Object[], String[])
1227
   * <code>instantiate(name, loaderName, (Object[]) null,
1228
   * (String[]) null)</code>} with <code>null</code> parameters
1229
   * and signature.
1230
   * </p>
1231
   *
1232
   * @param name the name of the class of bean to be instantiated.
1233
   * @param loaderName the name of the class loader to use.
1234
   * @return an instance of the given class.
1235
   * @throws InstanceNotFoundException if the class loader is not
1236
   *                                   registered with the server.
1237
   * @throws ReflectionException if an exception is thrown during
1238
   *                             loading the class or calling the
1239
   *                             constructor.
1240
   * @throws MBeanException if the constructor throws an exception.
1241
   * @throws RuntimeOperationsException if an {@link IllegalArgumentException}
1242
   *                                    is thrown by the server due to a
1243
   *                                    <code>null</code> name.
1244
   * @throws SecurityException if a security manager exists and the
1245
   *                           caller's permissions don't imply {@link
1246
   *                           MBeanPermission(String,String,ObjectName,String)
1247
   *                           <code>MBeanPermission(className, null, null,
1248
   *                           "instantiate")</code>}.
1249
   * @see #instantiate(String, Object[], String[])
1250
   */
1251
  public Object instantiate(String name, ObjectName loaderName)
1252
    throws InstanceNotFoundException, ReflectionException,
1253
           MBeanException
1254
  {
1255
    return instantiate(name, loaderName);
1256
  }
1257
 
1258
  /**
1259
   * Creates an instance of the specified class using the supplied
1260
   * class loader.  If the class loader given is <code>null</code>,
1261
   * then the class loader of the server will be used.  The class
1262
   * should have a public constructor matching the supplied
1263
   * signature.  A reference to the new instance is returned,
1264
   * but the instance is not yet registered with the server.
1265
   *
1266
   * @param name the name of the class of bean to be instantiated.
1267
   * @param loaderName the name of the class loader to use.
1268
   * @param params the parameters for the constructor.
1269
   * @param sig the signature of the constructor.
1270
   * @return an instance of the given class.
1271
   * @throws InstanceNotFoundException if the class loader is not
1272
   *                                   registered with the server.
1273
   * @throws ReflectionException if an exception is thrown during
1274
   *                             loading the class or calling the
1275
   *                             constructor.
1276
   * @throws MBeanException if the constructor throws an exception.
1277
   * @throws RuntimeOperationsException if an {@link IllegalArgumentException}
1278
   *                                    is thrown by the server due to a
1279
   *                                    <code>null</code> name.
1280
   * @throws SecurityException if a security manager exists and the
1281
   *                           caller's permissions don't imply {@link
1282
   *                           MBeanPermission(String,String,ObjectName,String)
1283
   *                           <code>MBeanPermission(className, null, null,
1284
   *                           "instantiate")</code>}.
1285
   */
1286
  public Object instantiate(String name, ObjectName loaderName,
1287
                            Object[] params, String[] sig)
1288
    throws InstanceNotFoundException, ReflectionException,
1289
           MBeanException
1290
  {
1291
    checkSecurity(null, null, "instantiate");
1292
    if (name == null)
1293
      {
1294
        RuntimeException e =
1295
          new IllegalArgumentException("The name was null.");
1296
        throw new RuntimeOperationsException(e);
1297
      }
1298
    ClassLoader loader = getClassLoader(loaderName);
1299
    Class<?>[] sigTypes = new Class[sig.length];
1300
    for (int a = 0; a < sig.length; ++a)
1301
      {
1302
        try
1303
          {
1304
            sigTypes[a] = Class.forName(sig[a], true, loader);
1305
          }
1306
        catch (ClassNotFoundException e)
1307
          {
1308
            throw new ReflectionException(e, "The class, " + sig[a] +
1309
                                          ", in the method signature " +
1310
                                          "could not be loaded.");
1311
          }
1312
      }
1313
    try
1314
      {
1315
        Constructor<?> cons =
1316
          Class.forName(name, true, loader).getConstructor(sigTypes);
1317
        return cons.newInstance(params);
1318
      }
1319
    catch (ClassNotFoundException e)
1320
      {
1321
        throw new ReflectionException(e, "The class, " + name +
1322
                                      ", of the constructor " +
1323
                                      "could not be loaded.");
1324
      }
1325
    catch (NoSuchMethodException e)
1326
      {
1327
        throw new ReflectionException(e, "The method, " + name +
1328
                                      ", could not be found.");
1329
      }
1330
    catch (IllegalAccessException e)
1331
      {
1332
        throw new ReflectionException(e, "Failed to instantiate the object");
1333
      }
1334
    catch (InstantiationException e)
1335
      {
1336
        throw new ReflectionException(e, "Failed to instantiate the object");
1337
      }
1338
    catch (InvocationTargetException e)
1339
      {
1340
        throw new MBeanException((Exception) e.getCause(), "The constructor "
1341
                                 + name + " threw an exception");
1342
      }
1343
  }
1344
 
1345
  /**
1346
   * Invokes the supplied operation on the specified management
1347
   * bean.  The class objects specified in the signature are loaded
1348
   * using the same class loader as was used for the management bean.
1349
   *
1350
   * @param bean the management bean whose operation should be invoked.
1351
   * @param name the name of the operation to invoke.
1352
   * @param params the parameters of the operation.
1353
   * @param sig the signature of the operation.
1354
   * @return the return value of the method.
1355
   * @throws InstanceNotFoundException if the bean can not be found.
1356
   * @throws MBeanException if the method invoked throws an exception.
1357
   * @throws RuntimeOperationsException if an {@link IllegalArgumentException}
1358
   *                                    is thrown by the server due to a
1359
   *                                    <code>null</code> name.
1360
   * @throws ReflectionException if an exception is thrown in invoking the
1361
   *                             method.
1362
   * @throws SecurityException if a security manager exists and the
1363
   *                           caller's permissions don't imply {@link
1364
   *                           MBeanPermission(String,String,ObjectName,String)
1365
   *                           <code>MBeanPermission(className, name, bean,
1366
   *                           "invoke")</code>}.
1367
   * @see DynamicMBean#invoke(String, Object[], String[])
1368
   */
1369
  public Object invoke(ObjectName bean, String name, Object[] params, String[] sig)
1370
    throws InstanceNotFoundException, MBeanException,
1371
           ReflectionException
1372
  {
1373
    if (bean == null)
1374
      {
1375
        RuntimeException e =
1376
          new IllegalArgumentException("The bean was null.");
1377
        throw new RuntimeOperationsException(e);
1378
      }
1379
    Object abean = getBean(bean);
1380
    checkSecurity(bean, name, "invoke");
1381
    if (abean instanceof DynamicMBean)
1382
      return ((DynamicMBean) abean).invoke(name, params, sig);
1383
    else
1384
      try
1385
        {
1386
          return new StandardMBean(abean, null).invoke(name, params, sig);
1387
        }
1388
      catch (NotCompliantMBeanException e)
1389
        {
1390
          throw (Error)
1391
            (new InternalError("Failed to create dynamic bean.").initCause(e));
1392
        }
1393
  }
1394
 
1395
  /**
1396
   * <p>
1397
   * Returns true if the specified management bean is an instance
1398
   * of the supplied class.
1399
   * </p>
1400
   * <p>
1401
   * A bean, B, is an instance of a class, C, if either of the following
1402
   * conditions holds:
1403
   * </p>
1404
   * <ul>
1405
   * <li>The class name in B's {@link MBeanInfo} is equal to the supplied
1406
   * name.</li>
1407
   * <li>Both the class of B and C were loaded by the same class loader,
1408
   * and B is assignable to C.</li>
1409
   * </ul>
1410
   *
1411
   * @param name the name of the management bean.
1412
   * @param className the name of the class to test if <code>name</code> is
1413
   *                  an instance of.
1414
   * @return true if either B is directly an instance of the named class,
1415
   *         or B is assignable to the class, given that both it and B's
1416
   *         current class were loaded using the same class loader.
1417
   * @throws InstanceNotFoundException if the bean can not be found.
1418
   * @throws SecurityException if a security manager exists and the
1419
   *                           caller's permissions don't imply {@link
1420
   *                           MBeanPermission(String,String,ObjectName,String)
1421
   *                           <code>MBeanPermission(className, null, name,
1422
   *                           "isInstanceOf")</code>
1423
   */
1424
  public boolean isInstanceOf(ObjectName name, String className)
1425
    throws InstanceNotFoundException
1426
  {
1427
    Object bean = getBean(name);
1428
    checkSecurity(name, null, "isInstanceOf");
1429
    MBeanInfo info;
1430
    if (bean instanceof DynamicMBean)
1431
      info = ((DynamicMBean) bean).getMBeanInfo();
1432
    else
1433
      try
1434
        {
1435
          info = new StandardMBean(bean, null).getMBeanInfo();
1436
        }
1437
      catch (NotCompliantMBeanException e)
1438
        {
1439
          throw (Error)
1440
            (new InternalError("Failed to create dynamic bean.").initCause(e));
1441
        }
1442
    if (info.getClassName().equals(className))
1443
      return true;
1444
    Class<?> bclass = bean.getClass();
1445
    try
1446
      {
1447
        Class<?> oclass = Class.forName(className);
1448
        return (bclass.getClassLoader().equals(oclass.getClassLoader()) &&
1449
                oclass.isAssignableFrom(bclass));
1450
      }
1451
    catch (ClassNotFoundException e)
1452
      {
1453
        return false;
1454
      }
1455
  }
1456
 
1457
  /**
1458
   * Returns true if the specified management bean is registered with
1459
   * the server.
1460
   *
1461
   * @param name the name of the management bean.
1462
   * @return true if the bean is registered.
1463
   * @throws RuntimeOperationsException if an {@link IllegalArgumentException}
1464
   *                                    is thrown by the server due to a
1465
   *                                    <code>null</code> bean name.
1466
   */
1467
  public boolean isRegistered(ObjectName name)
1468
  {
1469
    if (name == null)
1470
      {
1471
        RuntimeException e =
1472
          new IllegalArgumentException("The name was null.");
1473
        throw new RuntimeOperationsException(e);
1474
      }
1475
    return beans.containsKey(name);
1476
  }
1477
 
1478
  /**
1479
   * <p>
1480
   * Returns a set of {@link ObjectInstance}s matching the specified
1481
   * criteria.  The full set of beans registered with the server
1482
   * are passed through two filters:
1483
   * </p>
1484
   * <ol>
1485
   * <li>Pattern matching is performed using the supplied
1486
   * {@link ObjectName}.</li>
1487
   * <li>The supplied query expression is applied.</li>
1488
   * </ol>
1489
   * <p>
1490
   * If both the object name and the query expression are <code>null</code>,
1491
   * or the object name has no domain and no key properties,
1492
   * no filtering will be performed and all beans are returned.
1493
   * </p>
1494
   *
1495
   * @param name an {@link ObjectName} to use as a filter.
1496
   * @param query a query expression to apply to each of the beans that match
1497
   *              the given object name.
1498
   * @return a set of {@link ObjectInstance}s matching the filtered beans.
1499
   * @throws SecurityException if a security manager exists and the
1500
   *                           caller's permissions don't imply {@link
1501
   *                           MBeanPermission(String,String,ObjectName,String)
1502
   *                           <code>MBeanPermission(null, null, name,
1503
   *                           "queryMBeans")</code>}.  Additionally,
1504
   *                           for an bean, <code>b</code>, the
1505
   *                           caller's permission must imply {@link
1506
   *                           MBeanPermission(String,String,ObjectName,String)
1507
   *                           <code>MBeanPermission(className, b, name,
1508
   *                           "queryMBeans")</code>} or that bean will
1509
   *                           not be included.  Such an exception may also
1510
   *                           arise from the execution of the query, in which
1511
   *                           case that particular bean will again be excluded.
1512
   */
1513
  public Set<ObjectInstance> queryMBeans(ObjectName name, QueryExp query)
1514
  {
1515
    checkSecurity(name, null, "queryMBeans");
1516
    Set<ObjectInstance> results = new HashSet<ObjectInstance>();
1517
    for (Map.Entry<ObjectName,ServerInfo> entry : beans.entrySet())
1518
      {
1519
        ObjectName nextName = entry.getKey();
1520
        checkSecurity(name, nextName.toString(), "queryMBeans");
1521
        try
1522
          {
1523
            if ((name == null || name.apply(nextName)) &&
1524
                (query == null || query.apply(nextName)))
1525
              results.add(entry.getValue().getInstance());
1526
          }
1527
        catch (BadStringOperationException e)
1528
          {
1529
            /* Ignored -- assume false result */
1530
          }
1531
        catch (BadBinaryOpValueExpException e)
1532
          {
1533
            /* Ignored -- assume false result */
1534
          }
1535
        catch (BadAttributeValueExpException e)
1536
          {
1537
            /* Ignored -- assume false result */
1538
          }
1539
        catch (InvalidApplicationException e)
1540
          {
1541
            /* Ignored -- assume false result */
1542
          }
1543
      }
1544
    return results;
1545
  }
1546
 
1547
  /**
1548
   * <p>
1549
   * Returns a set of {@link ObjectName}s matching the specified
1550
   * criteria.  The full set of beans registered with the server
1551
   * are passed through two filters:
1552
   * </p>
1553
   * <ol>
1554
   * <li>Pattern matching is performed using the supplied
1555
   * {@link ObjectName}.</li>
1556
   * <li>The supplied query expression is applied.</li>
1557
   * </ol>
1558
   * <p>
1559
   * If both the object name and the query expression are <code>null</code>,
1560
   * or the object name has no domain and no key properties,
1561
   * no filtering will be performed and all beans are returned.
1562
   * </p>
1563
   *
1564
   * @param name an {@link ObjectName} to use as a filter.
1565
   * @param query a query expression to apply to each of the beans that match
1566
   *              the given object name.
1567
   * @return a set of {@link ObjectName}s matching the filtered beans.
1568
   * @throws SecurityException if a security manager exists and the
1569
   *                           caller's permissions don't imply {@link
1570
   *                           MBeanPermission(String,String,ObjectName,String)
1571
   *                           <code>MBeanPermission(null, null, name,
1572
   *                           "queryNames")</code>}.  Additionally,
1573
   *                           for an name, <code>n</code>, the
1574
   *                           caller's permission must imply {@link
1575
   *                           MBeanPermission(String,String,ObjectName,String)
1576
   *                           <code>MBeanPermission(className, n, name,
1577
   *                           "queryNames")</code>} or that name will
1578
   *                           not be included.  Such an exception may also
1579
   *                           arise from the execution of the query, in which
1580
   *                           case that particular bean will again be excluded.
1581
   *                           Note that these permissions are implied if the
1582
   *                           <code>queryMBeans</code> permissions are available.
1583
   */
1584
  public Set<ObjectName> queryNames(ObjectName name, QueryExp query)
1585
  {
1586
    checkSecurity(name, null, "queryNames");
1587
    Set<ObjectName> results = new HashSet<ObjectName>();
1588
    for (ObjectName nextName : beans.keySet())
1589
      {
1590
        checkSecurity(name, nextName.toString(), "queryNames");
1591
        try
1592
          {
1593
            if ((name == null || name.apply(nextName)) &&
1594
                (query == null || query.apply(nextName)))
1595
              results.add(nextName);
1596
          }
1597
        catch (BadStringOperationException e)
1598
          {
1599
            /* Ignored -- assume false result */
1600
          }
1601
        catch (BadBinaryOpValueExpException e)
1602
          {
1603
            /* Ignored -- assume false result */
1604
          }
1605
        catch (BadAttributeValueExpException e)
1606
          {
1607
            /* Ignored -- assume false result */
1608
          }
1609
        catch (InvalidApplicationException e)
1610
          {
1611
            /* Ignored -- assume false result */
1612
          }
1613
      }
1614
    return results;
1615
  }
1616
 
1617
  /**
1618
   * Registers the supplied instance with the server, using the specified
1619
   * {@link ObjectName}.  If the name given is <code>null</code>, then
1620
   * the bean supplied is expected to implement the {@link MBeanRegistration}
1621
   * interface and provide the name via the
1622
   * {@link MBeanRegistration#preRegister preRegister} method
1623
   * of this interface.
1624
   *
1625
   * @param obj the object to register with the server.
1626
   * @param name the name under which to register the object,
1627
   *             or <code>null</code> if the {@link MBeanRegistration}
1628
   *             interface should be used.
1629
   * @return an {@link ObjectInstance} containing the supplied
1630
   *         {@link ObjectName} along with the name of the bean's class.
1631
   * @throws InstanceAlreadyExistsException if a matching instance
1632
   *                                        already exists.
1633
   * @throws MBeanRegistrationException if an exception occurs in
1634
   *                                    calling the preRegister
1635
   *                                    method.
1636
   * @throws NotCompliantMBeanException if the created bean is not
1637
   *                                    compliant with the JMX specification.
1638
   * @throws RuntimeOperationsException if an {@link IllegalArgumentException}
1639
   *                                    is thrown by the server due to a
1640
   *                                    <code>null</code> object.
1641
   * @throws SecurityException if a security manager exists and the
1642
   *                           caller's permissions don't imply {@link
1643
   *                           MBeanPermission(String,String,ObjectName,String)
1644
   *                           <code>MBeanPermission(className, null, name,
1645
   *                           "registerMBean")</code>}.  <code>className</code>
1646
   *                           here corresponds to the result of
1647
   *                           {@link MBeanInfo#getClassName()} for objects of
1648
   *                           this class.  If this check succeeds, a check
1649
   *                           is also made on its
1650
   *                           {@link java.security.ProtectionDomain} to ensure
1651
   *                           it implies {@link MBeanTrustPermission(String)
1652
   *                           <code>MBeanTrustPermission("register")</code>}.
1653
   *                           The use of the {@link MBeanRegistration} interface
1654
   *                           results in another {@link MBeanPermission} check
1655
   *                           being made on the returned {@link ObjectName}.
1656
   */
1657
  public ObjectInstance registerMBean(Object obj, ObjectName name)
1658
    throws InstanceAlreadyExistsException, MBeanRegistrationException,
1659
           NotCompliantMBeanException
1660
  {
1661
    SecurityManager sm = System.getSecurityManager();
1662
    Class<?> cl = obj.getClass();
1663
    String className = cl.getName();
1664
    if (sm != null)
1665
      {
1666
        sm.checkPermission(new MBeanPermission(className, null, name,
1667
                                               "registerMBean"));
1668
        if (!(cl.getProtectionDomain().implies(new MBeanTrustPermission("register"))))
1669
          throw new SecurityException("The protection domain of the object's class" +
1670
                                      "does not imply the trust permission," +
1671
                                      "register");
1672
      }
1673
    if (obj == null)
1674
      {
1675
        RuntimeException e =
1676
          new IllegalArgumentException("The object was null.");
1677
        throw new RuntimeOperationsException(e);
1678
      }
1679
    MBeanRegistration register = null;
1680
    if (obj instanceof MBeanRegistration)
1681
      register = (MBeanRegistration) obj;
1682
    if (name == null && register == null)
1683
      {
1684
        RuntimeException e =
1685
          new IllegalArgumentException("The name was null and " +
1686
                                       "the bean does not implement " +
1687
                                       "MBeanRegistration.");
1688
        throw new RuntimeOperationsException(e);
1689
      }
1690
    if (register != null)
1691
      {
1692
        try
1693
          {
1694
            name = register.preRegister(this, name);
1695
            if (name == null)
1696
              {
1697
                RuntimeException e =
1698
                  new NullPointerException("The name returned by " +
1699
                                           "MBeanRegistration.preRegister() " +
1700
                                           "was null");
1701
                throw e;
1702
              }
1703
            if (sm != null)
1704
              sm.checkPermission(new MBeanPermission(className, null, name,
1705
                                                     "registerMBean"));
1706
          }
1707
        catch (SecurityException e)
1708
          {
1709
            register.postRegister(Boolean.FALSE);
1710
            throw e;
1711
          }
1712
        catch (Exception e)
1713
          {
1714
            register.postRegister(Boolean.FALSE);
1715
            throw new MBeanRegistrationException(e, "Pre-registration failed.");
1716
          }
1717
      }
1718
    ObjectInstance obji = new ObjectInstance(name, className);
1719
    if (beans.putIfAbsent(name, new ServerInfo(obji, obj)) != null)
1720
      {
1721
        if (register != null)
1722
          register.postRegister(Boolean.FALSE);
1723
        throw new InstanceAlreadyExistsException(name + "is already registered.");
1724
      }
1725
    if (register != null)
1726
      register.postRegister(Boolean.TRUE);
1727
    notify(name, MBeanServerNotification.REGISTRATION_NOTIFICATION);
1728
    return obji;
1729
  }
1730
 
1731
  /**
1732
   * Removes the specified listener from the list of recipients
1733
   * of notifications from the supplied bean.  This includes all
1734
   * combinations of filters and passback objects registered for
1735
   * this listener.  For more specific removal of listeners, see
1736
   * {@link #removeNotificationListener(ObjectName,
1737
   * NotificationListener,NotificationFilter,Object)}
1738
   *
1739
   * @param name the name of the management bean from which the
1740
   *             listener should be removed.
1741
   * @param listener the listener to remove.
1742
   * @throws InstanceNotFoundException if the bean can not be found.
1743
   * @throws ListenerNotFoundException if the specified listener
1744
   *                                   is not registered with the bean.
1745
   * @throws SecurityException if a security manager exists and the
1746
   *                           caller's permissions don't imply {@link
1747
   *                           MBeanPermission(String,String,ObjectName,String)
1748
   *                           <code>MBeanPermission(className, null, name,
1749
   *                           "removeNotificationListener")</code>}.
1750
   * @see #addNotificationListener(NotificationListener, NotificationFilter,
1751
   *                               java.lang.Object)
1752
   * @see NotificationBroadcaster#removeNotificationListener(NotificationListener)
1753
   */
1754
  public void removeNotificationListener(ObjectName name,
1755
                                         NotificationListener listener)
1756
    throws InstanceNotFoundException, ListenerNotFoundException
1757
  {
1758
    Object bean = getBean(name);
1759
    checkSecurity(name, null, "removeNotificationListener");
1760
    if (bean instanceof NotificationBroadcaster)
1761
      {
1762
        NotificationBroadcaster bbean = (NotificationBroadcaster) bean;
1763
        bbean.removeNotificationListener(listener);
1764
        LazyListenersHolder.listeners.remove(listener);
1765
      }
1766
  }
1767
 
1768
  /**
1769
   * Removes the specified listener from the list of recipients
1770
   * of notifications from the supplied bean.  Only the first instance with
1771
   * the supplied filter and passback object is removed.
1772
   * <code>null</code> is used as a valid value for these parameters,
1773
   * rather than as a way to remove all registration instances for
1774
   * the specified listener; for this behaviour instead, see
1775
   * {@link #removeNotificationListener(ObjectName, NotificationListener)}.
1776
   *
1777
   * @param name the name of the management bean from which the
1778
   *             listener should be removed.
1779
   * @param listener the listener to remove.
1780
   * @param filter the filter of the listener to remove.
1781
   * @param passback the passback object of the listener to remove.
1782
   * @throws InstanceNotFoundException if the bean can not be found.
1783
   * @throws ListenerNotFoundException if the specified listener
1784
   *                                   is not registered with the bean.
1785
   * @throws SecurityException if a security manager exists and the
1786
   *                           caller's permissions don't imply {@link
1787
   *                           MBeanPermission(String,String,ObjectName,String)
1788
   *                           <code>MBeanPermission(className, null, name,
1789
   *                           "removeNotificationListener")</code>}.
1790
   * @see #addNotificationListener(ObjectName, NotificationListener,
1791
   *                               NotificationFilter, Object)
1792
   * @see NotificationEmitter#removeNotificationListener(NotificationListener,
1793
   *                                                     NotificationFilter,
1794
   *                                                     Object)
1795
   */
1796
  public void removeNotificationListener(ObjectName name,
1797
                                         NotificationListener listener,
1798
                                         NotificationFilter filter,
1799
                                         Object passback)
1800
    throws InstanceNotFoundException, ListenerNotFoundException
1801
  {
1802
    Object bean = getBean(name);
1803
    checkSecurity(name, null, "removeNotificationListener");
1804
    if (bean instanceof NotificationEmitter)
1805
      {
1806
        NotificationEmitter bbean = (NotificationEmitter) bean;
1807
        bbean.removeNotificationListener(listener, filter, passback);
1808
        LazyListenersHolder.listeners.remove(listener);
1809
      }
1810
  }
1811
 
1812
  /**
1813
   * Removes the specified listener from the list of recipients
1814
   * of notifications from the supplied bean.  This includes all
1815
   * combinations of filters and passback objects registered for
1816
   * this listener.  For more specific removal of listeners, see
1817
   * {@link #removeNotificationListener(ObjectName,
1818
   * ObjectName,NotificationFilter,Object)}
1819
   *
1820
   * @param name the name of the management bean from which the
1821
   *             listener should be removed.
1822
   * @param listener the name of the listener to remove.
1823
   * @throws InstanceNotFoundException if a name doesn't match a registered
1824
   *                                   bean.
1825
   * @throws ListenerNotFoundException if the specified listener
1826
   *                                   is not registered with the bean.
1827
   * @throws SecurityException if a security manager exists and the
1828
   *                           caller's permissions don't imply {@link
1829
   *                           MBeanPermission(String,String,ObjectName,String)
1830
   *                           <code>MBeanPermission(className, null, name,
1831
   *                           "removeNotificationListener")</code>}.
1832
   * @see #addNotificationListener(NotificationListener, NotificationFilter,
1833
   *                               java.lang.Object)
1834
   * @see NotificationBroadcaster#removeNotificationListener(NotificationListener)
1835
   */
1836
  public void removeNotificationListener(ObjectName name, ObjectName listener)
1837
    throws InstanceNotFoundException, ListenerNotFoundException
1838
  {
1839
    Object lbean = getBean(listener);
1840
    if (!(lbean instanceof NotificationListener))
1841
      {
1842
        RuntimeException e =
1843
          new IllegalArgumentException("The supplied listener name does not " +
1844
                                       "correspond to a notification listener.");
1845
        throw new RuntimeOperationsException(e);
1846
      }
1847
    removeNotificationListener(name, ((NotificationListener) lbean));
1848
  }
1849
 
1850
  /**
1851
   * Removes the specified listener from the list of recipients
1852
   * of notifications from the supplied bean.  Only the first instance with
1853
   * the supplied filter and passback object is removed.
1854
   * <code>null</code> is used as a valid value for these parameters,
1855
   * rather than as a way to remove all registration instances for
1856
   * the specified listener; for this behaviour instead, see
1857
   * {@link #removeNotificationListener(ObjectName, ObjectName)}.
1858
   *
1859
   * @param name the name of the management bean from which the
1860
   *             listener should be removed.
1861
   * @param listener the name of the listener to remove.
1862
   * @param filter the filter of the listener to remove.
1863
   * @param passback the passback object of the listener to remove.
1864
   * @throws InstanceNotFoundException if a name doesn't match a registered
1865
   *                                   bean.
1866
   * @throws ListenerNotFoundException if the specified listener
1867
   *                                   is not registered with the bean.
1868
   * @throws SecurityException if a security manager exists and the
1869
   *                           caller's permissions don't imply {@link
1870
   *                           MBeanPermission(String,String,ObjectName,String)
1871
   *                           <code>MBeanPermission(className, null, name,
1872
   *                           "removeNotificationListener")</code>}.
1873
   * @see #addNotificationListener(ObjectName, NotificationListener,
1874
   *                               NotificationFilter, Object)
1875
   * @see NotificationEmitter#removeNotificationListener(NotificationListener,
1876
   *                                                     NotificationFilter,
1877
   *                                                     Object)
1878
   */
1879
  public void removeNotificationListener(ObjectName name,
1880
                                  ObjectName listener,
1881
                                  NotificationFilter filter,
1882
                                  Object passback)
1883
    throws InstanceNotFoundException, ListenerNotFoundException
1884
  {
1885
    Object lbean = getBean(listener);
1886
    if (!(lbean instanceof NotificationListener))
1887
      {
1888
        RuntimeException e =
1889
          new IllegalArgumentException("The supplied listener name does not " +
1890
                                       "correspond to a notification listener.");
1891
        throw new RuntimeOperationsException(e);
1892
      }
1893
    removeNotificationListener(name, ((NotificationListener) lbean), filter,
1894
                               passback);
1895
  }
1896
 
1897
  /**
1898
   * Sets the value of the specified attribute of the supplied
1899
   * management bean.
1900
   *
1901
   * @param name the name of the management bean.
1902
   * @param attribute the attribute to set.
1903
   * @throws InstanceNotFoundException if the bean can not be found.
1904
   * @throws AttributeNotFoundException if the attribute does not
1905
   *                                    correspond to an attribute
1906
   *                                    of the bean.
1907
   * @throws InvalidAttributeValueException if the value is invalid
1908
   *                                        for this particular
1909
   *                                        attribute of the bean.
1910
   * @throws MBeanException if setting the attribute causes
1911
   *                        the bean to throw an exception (which
1912
   *                        becomes the cause of this exception).
1913
   * @throws ReflectionException if an exception occurred in trying
1914
   *                             to use the reflection interface
1915
   *                             to lookup the attribute.  The
1916
   *                             thrown exception is the cause of
1917
   *                             this exception.
1918
   * @throws RuntimeOperationsException if an {@link IllegalArgumentException}
1919
   *                                    is thrown by the server due to a
1920
   *                                    <code>null</code> bean or attribute
1921
   *                                    name.
1922
   * @throws SecurityException if a security manager exists and the
1923
   *                           caller's permissions don't imply {@link
1924
   *                           MBeanPermission(String,String,ObjectName,String)
1925
   *                           <code>MBeanPermission(className, name, bean,
1926
   *                           "setAttribute")</code>}.
1927
   * @see #getAttribute(ObjectName, String)
1928
   * @see DynamicMBean#setAttribute(Attribute)
1929
   */
1930
  public void setAttribute(ObjectName name, Attribute attribute)
1931
    throws InstanceNotFoundException, AttributeNotFoundException,
1932
           InvalidAttributeValueException, MBeanException,
1933
           ReflectionException
1934
  {
1935
    if (attribute == null || name == null)
1936
      {
1937
        RuntimeException e =
1938
          new IllegalArgumentException("One of the supplied arguments was null.");
1939
        throw new RuntimeOperationsException(e);
1940
      }
1941
    Object bean = getBean(name);
1942
    checkSecurity(name, attribute.getName(), "setAttribute");
1943
    if (bean instanceof DynamicMBean)
1944
      ((DynamicMBean) bean).setAttribute(attribute);
1945
    else
1946
      try
1947
        {
1948
          new StandardMBean(bean, null).setAttribute(attribute);
1949
        }
1950
      catch (NotCompliantMBeanException e)
1951
        {
1952
          throw (Error)
1953
            (new InternalError("Failed to create dynamic bean.").initCause(e));
1954
        }
1955
  }
1956
 
1957
  /**
1958
   * Sets the value of each of the specified attributes
1959
   * of the supplied management bean to that specified by
1960
   * the {@link Attribute} object.  The returned list contains
1961
   * the attributes that were set and their new values.
1962
   *
1963
   * @param name the name of the management bean.
1964
   * @param attributes the attributes to set.
1965
   * @return a list of the changed attributes.
1966
   * @throws InstanceNotFoundException if the bean can not be found.
1967
   * @throws ReflectionException if an exception occurred in trying
1968
   *                             to use the reflection interface
1969
   *                             to lookup the attribute.  The
1970
   *                             thrown exception is the cause of
1971
   *                             this exception.
1972
   * @throws RuntimeOperationsException if an {@link IllegalArgumentException}
1973
   *                                    is thrown by the server due to a
1974
   *                                    <code>null</code> bean or attribute
1975
   *                                    list.
1976
   * @throws SecurityException if a security manager exists and the
1977
   *                           caller's permissions don't imply {@link
1978
   *                           MBeanPermission(String,String,ObjectName,String)
1979
   *                           <code>MBeanPermission(className, null, bean,
1980
   *                           "setAttribute")</code>}.  Additionally,
1981
   *                           for an attribute name, <code>n</code>, the
1982
   *                           caller's permission must imply {@link
1983
   *                           MBeanPermission(String,String,ObjectName,String)
1984
   *                           <code>MBeanPermission(className, n, bean,
1985
   *                           "setAttribute")</code>} or that attribute will
1986
   *                           not be included.
1987
   * @see #getAttributes(ObjectName, String[])
1988
   * @see DynamicMBean#setAttributes(AttributeList)
1989
   */
1990
  public AttributeList setAttributes(ObjectName name, AttributeList attributes)
1991
    throws InstanceNotFoundException, ReflectionException
1992
  {
1993
    if (name == null || attributes == null)
1994
      {
1995
        RuntimeException e =
1996
          new IllegalArgumentException("One of the supplied arguments was null.");
1997
        throw new RuntimeOperationsException(e);
1998
      }
1999
    Object abean = getBean(name);
2000
    checkSecurity(name, null, "setAttribute");
2001
    AttributeList list = new AttributeList(attributes.size());
2002
    Iterator<Object> it = attributes.iterator();
2003
    while (it.hasNext())
2004
      {
2005
        try
2006
          {
2007
            Attribute attrib = (Attribute) it.next();
2008
            if (attrib == null)
2009
              {
2010
                RuntimeException e =
2011
                  new IllegalArgumentException("An attribute was null.");
2012
                throw new RuntimeOperationsException(e);
2013
              }
2014
            checkSecurity(name, attrib.getName(), "setAttribute");
2015
            if (abean instanceof DynamicMBean)
2016
              ((DynamicMBean) abean).setAttribute(attrib);
2017
            else
2018
              try
2019
                {
2020
                  new StandardMBean(abean, null).setAttribute(attrib);
2021
                }
2022
              catch (NotCompliantMBeanException e)
2023
                {
2024
                  throw (Error)
2025
                    (new InternalError("Failed to create dynamic bean.").initCause(e));
2026
                }
2027
            list.add(attrib);
2028
          }
2029
        catch (AttributeNotFoundException e)
2030
          {
2031
            /* Ignored */
2032
          }
2033
        catch (InvalidAttributeValueException e)
2034
          {
2035
            /* Ignored */
2036
          }
2037
        catch (MBeanException e)
2038
          {
2039
            /* Ignored */
2040
          }
2041
      }
2042
    return list;
2043
  }
2044
 
2045
  /**
2046
   * Unregisters the specified management bean.  Following this operation,
2047
   * the bean instance is no longer accessible from the server via this
2048
   * name.  Prior to unregistering the bean, the
2049
   * {@link MBeanRegistration#preDeregister()} method will be called if
2050
   * the bean implements the {@link MBeanRegistration} interface.
2051
   *
2052
   * @param name the name of the management bean.
2053
   * @throws InstanceNotFoundException if the bean can not be found.
2054
   * @throws MBeanRegistrationException if an exception occurs in
2055
   *                                    calling the preDeregister
2056
   *                                    method.
2057
   * @throws RuntimeOperationsException if an {@link IllegalArgumentException}
2058
   *                                    is thrown by the server due to a
2059
   *                                    <code>null</code> bean name or a
2060
   *                                    request being made to unregister the
2061
   *                                    {@link MBeanServerDelegate} bean.
2062
   * @throws SecurityException if a security manager exists and the
2063
   *                           caller's permissions don't imply {@link
2064
   *                           MBeanPermission(String,String,ObjectName,String)
2065
   *                           <code>MBeanPermission(className, null, name,
2066
   *                           "unregisterMBean")</code>}.
2067
   */
2068
  public void unregisterMBean(ObjectName name)
2069
    throws InstanceNotFoundException, MBeanRegistrationException
2070
  {
2071
    if (name == null)
2072
      {
2073
        RuntimeException e =
2074
          new IllegalArgumentException("The name was null.");
2075
        throw new RuntimeOperationsException(e);
2076
      }
2077
    if (name.equals(DELEGATE_NAME))
2078
      {
2079
        RuntimeException e =
2080
          new IllegalArgumentException("The delegate can not be unregistered.");
2081
        throw new RuntimeOperationsException(e);
2082
      }
2083
    Object bean = getBean(name);
2084
    checkSecurity(name, null, "unregisterMBean");
2085
    MBeanRegistration register = null;
2086
    if (bean instanceof MBeanRegistration)
2087
      {
2088
        register = (MBeanRegistration) bean;
2089
        try
2090
          {
2091
            register.preDeregister();
2092
          }
2093
        catch (Exception e)
2094
          {
2095
            throw new MBeanRegistrationException(e, "Pre-deregistration failed.");
2096
          }
2097
      }
2098
    beans.remove(name);
2099
    notify(name, MBeanServerNotification.UNREGISTRATION_NOTIFICATION);
2100
    if (register != null)
2101
      register.postDeregister();
2102
  }
2103
 
2104
  /**
2105
   * Notifies the delegate of beans being registered
2106
   * and unregistered.
2107
   *
2108
   * @param name the bean being registered.
2109
   * @param type the type of notification;
2110
   * {@code REGISTRATION_NOTIFICATION} or
2111
   * {@code UNREGISTRATION_NOTIFICATION}.
2112
   */
2113
   private void notify(ObjectName name, String type)
2114
   {
2115
      delegate.sendNotification
2116
        (new MBeanServerNotification
2117
         (type, DELEGATE_NAME, sequenceNumber.getAndIncrement(), name));
2118
   }
2119
 
2120
  /**
2121
   * Input stream which deserializes using the given classloader.
2122
   */
2123
  private class ServerInputStream
2124
    extends ObjectInputStream
2125
  {
2126
 
2127
    private ClassLoader cl;
2128
 
2129
    public ServerInputStream(InputStream is, ClassLoader cl)
2130
      throws IOException, StreamCorruptedException
2131
    {
2132
      super(is);
2133
      this.cl = cl;
2134
    }
2135
 
2136
    protected Class<?> resolveClass(ObjectStreamClass osc)
2137
      throws ClassNotFoundException, IOException
2138
    {
2139
      try
2140
        {
2141
          return Class.forName(osc.getName(), true, cl);
2142
        }
2143
      catch (ClassNotFoundException e)
2144
        {
2145
          return super.resolveClass(osc);
2146
        }
2147
    }
2148
 
2149
  }
2150
 
2151
  /**
2152
   * Holder for information on registered beans.
2153
   */
2154
  private class ServerInfo
2155
  {
2156
    private ObjectInstance instance;
2157
 
2158
    private Object object;
2159
 
2160
    public ServerInfo(ObjectInstance instance, Object object)
2161
    {
2162
      this.instance = instance;
2163
      this.object = object;
2164
    }
2165
 
2166
    public Object getObject()
2167
    {
2168
      return object;
2169
    }
2170
 
2171
    public ObjectInstance getInstance()
2172
    {
2173
      return instance;
2174
    }
2175
  }
2176
 
2177
  /**
2178
   * Notification listener which removes direct references
2179
   * to beans.
2180
   */
2181
  private class ServerNotificationListener
2182
    implements NotificationListener
2183
  {
2184
 
2185
    /**
2186
     * The bean from which notifications are emitted.
2187
     */
2188
    Object bean;
2189
 
2190
    /**
2191
     * The {@link ObjectName} of the emitting bean.
2192
     */
2193
    ObjectName name;
2194
 
2195
    /**
2196
     * The real {@link NotificationListener}.
2197
     */
2198
    NotificationListener listener;
2199
 
2200
    /**
2201
     * Constructs a new {@link ServerNotificationListener} replacing
2202
     * occurrences of <code>bean</code> with its name.
2203
     *
2204
     * @param bean the bean emitting notifications.
2205
     * @param name the object name of the emitting bean.
2206
     * @param listener the listener events eventually reach.
2207
     */
2208
    public ServerNotificationListener(Object bean, ObjectName name,
2209
                                      NotificationListener listener)
2210
    {
2211
      this.bean = bean;
2212
      this.name = name;
2213
      this.listener = listener;
2214
    }
2215
 
2216
    /**
2217
     * Replace a direct reference to <code>bean</code> with its
2218
     * object reference, if necessary, before calling the listener.
2219
     *
2220
     * @param notif the notification being emitted.
2221
     * @param handback an object that will be returned to the notification
2222
     *                 listener when an event occurs.
2223
     */
2224
    public void handleNotification(Notification notif, Object handback)
2225
    {
2226
      if (notif.getSource() == bean)
2227
        notif.setSource(name);
2228
      listener.handleNotification(notif, handback);
2229
    }
2230
 
2231
  }
2232
 
2233
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.