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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libjava/] [classpath/] [java/] [lang/] [management/] [ManagementFactory.java] - Blame information for rev 791

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 771 jeremybenn
/* ManagementFactory.java - Factory for obtaining system beans.
2
   Copyright (C) 2006 Free Software Foundation
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 java.lang.management;
39
 
40
import gnu.classpath.SystemProperties;
41
 
42
import gnu.java.lang.management.ClassLoadingMXBeanImpl;
43
import gnu.java.lang.management.CompilationMXBeanImpl;
44
import gnu.java.lang.management.GarbageCollectorMXBeanImpl;
45
import gnu.java.lang.management.OperatingSystemMXBeanImpl;
46
import gnu.java.lang.management.MemoryMXBeanImpl;
47
import gnu.java.lang.management.MemoryManagerMXBeanImpl;
48
import gnu.java.lang.management.MemoryPoolMXBeanImpl;
49
import gnu.java.lang.management.RuntimeMXBeanImpl;
50
import gnu.java.lang.management.ThreadMXBeanImpl;
51
 
52
import java.io.IOException;
53
 
54
import java.lang.reflect.InvocationHandler;
55
import java.lang.reflect.Method;
56
import java.lang.reflect.Proxy;
57
 
58
import java.util.ArrayList;
59
import java.util.HashMap;
60
import java.util.Iterator;
61
import java.util.List;
62
import java.util.Map;
63
 
64
import java.util.logging.LogManager;
65
 
66
import javax.management.Attribute;
67
import javax.management.InstanceAlreadyExistsException;
68
import javax.management.MBeanRegistrationException;
69
import javax.management.MBeanServer;
70
import javax.management.MBeanServerConnection;
71
import javax.management.MBeanServerFactory;
72
import javax.management.MalformedObjectNameException;
73
import javax.management.NotCompliantMBeanException;
74
import javax.management.NotificationEmitter;
75
import javax.management.NotificationFilter;
76
import javax.management.NotificationListener;
77
import javax.management.ObjectName;
78
 
79
import javax.management.openmbean.CompositeData;
80
import javax.management.openmbean.TabularData;
81
 
82
/**
83
 * <p>
84
 * Provides access to the system's management beans via a series
85
 * of static methods.
86
 * </p>
87
 * <p>
88
 * An instance of a system management bean can be obtained by
89
 * using one of the following methods:
90
 * </p>
91
 * <ol>
92
 * <li>Calling the appropriate static method of this factory.
93
 * </li>
94
 * <li>Using the platform {@link javax.management.MBeanServer}
95
 * to access the beans locally, or an
96
 * {@link javax.management.MBeanServerConnection} for remote
97
 * access.  The attributes and operations use the limited
98
 * range of data types specified below.</li>
99
 * </ol>
100
 * <h2>Open Data Types</h2>
101
 * <p>
102
 * The data types used by the management beans are restricted
103
 * to <emph>open</emph> data types to aid interoperability.  This
104
 * allows the beans to be accessed remotely, including from non-Java
105
 * clients.  Below is a table which lists the types used by the beans
106
 * on the left, and the types they are converted to when returned via
107
 * a bean server on the right.  Type information is provided for each
108
 * bean by obtaining its instance of {@link javax.management.MBeanInfo}.
109
 * </p>
110
 * <table>
111
 * <th><td>Data Type Used</td><td>Data Type Returned</td></th>
112
 * <tr>
113
 * <td>Primitive types (<code>int</code>, <code>char</code>, etc.)</td>
114
 * <td>Same</td>
115
 * </tr><tr>
116
 * <td>Wrapper classes ({@link{java.lang.Integer},
117
 * @link{java.lang.Character}, etc.)</td>
118
 * <td>Same</td>
119
 * </tr><tr>
120
 * <td>An {@link java.lang.Enum}</td>
121
 * <td>The <code>name</code> of the enumeration constant</td>
122
 * </tr><tr>
123
 * <td>An array of type <code>E</code></td>
124
 * <td>An array of the same dimensions with this mapping applied
125
 * to <code>E</code>.</td>
126
 * </tr><tr>
127
 * <td>A class with `getter' methods and a
128
 * <code>from({@link javax.management.openmbean.CompositeData})</code>
129
 * method.</td>
130
 * <td>The equivalent {@link javax.management.openmbean.CompositeData}
131
 * instance, specified by the <code>from</code> method.</td>
132
 * </tr><tr>
133
 * <td>A map with keys of type <code>K</code> and values of
134
 * type <code>V</code>.</td>
135
 * <td>A {@link javax.management.openmbean.TabularData} instance,
136
 * with the row type containing two items, <code>"key"</code> and
137
 * <code>"value"</code> with the types <code>K</code> and <code>V</code>
138
 * respectively (with translation applied).</td>
139
 * </tr><tr>
140
 * <td>A list of type <code>E</code>.</td>
141
 * <td>An array with this mapping applied to <code>E</code>.</td>
142
 * </tr></table>
143
 *
144
 * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
145
 * @since 1.5
146
 */
147
public class ManagementFactory
148
{
149
 
150
  /**
151
   * The object name for the class loading bean.
152
   */
153
  public static final String CLASS_LOADING_MXBEAN_NAME =
154
    "java.lang:type=ClassLoading";
155
 
156
  /**
157
   * The object name for the compilation bean.
158
   */
159
  public static final String COMPILATION_MXBEAN_NAME =
160
    "java.lang:type=Compilation";
161
 
162
  /**
163
   * The domain for the garbage collecting beans.
164
   */
165
  public static final String GARBAGE_COLLECTOR_MXBEAN_DOMAIN_TYPE =
166
    "java.lang:type=GarbageCollector";
167
 
168
  /**
169
   * The domain for the memory manager beans.
170
   */
171
  public static final String MEMORY_MANAGER_MXBEAN_DOMAIN_TYPE =
172
    "java.lang:type=MemoryManager";
173
 
174
  /**
175
   * The object name for the memory bean.
176
   */
177
  public static final String MEMORY_MXBEAN_NAME =
178
    "java.lang:type=Memory";
179
 
180
  /**
181
   * The domain for the memory pool beans.
182
   */
183
  public static final String MEMORY_POOL_MXBEAN_DOMAIN_TYPE =
184
    "java.lang:type=MemoryPool";
185
 
186
  /**
187
   * The object name for the operating system bean.
188
   */
189
  public static final String OPERATING_SYSTEM_MXBEAN_NAME =
190
    "java.lang:type=OperatingSystem";
191
 
192
  /**
193
   * The object name for the runtime bean.
194
   */
195
  public static final String RUNTIME_MXBEAN_NAME =
196
    "java.lang:type=Runtime";
197
 
198
  /**
199
   * The object name for the threading bean.
200
   */
201
  public static final String THREAD_MXBEAN_NAME =
202
    "java.lang:type=Threading";
203
 
204
  /**
205
   * The operating system management bean.
206
   */
207
  private static OperatingSystemMXBean osBean;
208
 
209
  /**
210
   * The runtime management bean.
211
   */
212
  private static RuntimeMXBean runtimeBean;
213
 
214
  /**
215
   * The class loading management bean.
216
   */
217
  private static ClassLoadingMXBean classLoadingBean;
218
 
219
  /**
220
   * The thread bean.
221
   */
222
  private static ThreadMXBean threadBean;
223
 
224
  /**
225
   * The memory bean.
226
   */
227
  private static MemoryMXBean memoryBean;
228
 
229
  /**
230
   * The compilation bean (may remain null).
231
   */
232
  private static CompilationMXBean compilationBean;
233
 
234
  /**
235
   * The platform server.
236
   */
237
  private static MBeanServer platformServer;
238
 
239
  /**
240
   * Private constructor to prevent instance creation.
241
   */
242
  private ManagementFactory() {}
243
 
244
  /**
245
   * Returns the operating system management bean for the
246
   * operating system on which the virtual machine is running.
247
   *
248
   * @return an instance of {@link OperatingSystemMXBean} for
249
   *         the underlying operating system.
250
   */
251
  public static OperatingSystemMXBean getOperatingSystemMXBean()
252
  {
253
    if (osBean == null)
254
      try
255
        {
256
          osBean = new OperatingSystemMXBeanImpl();
257
        }
258
      catch (NotCompliantMBeanException e)
259
        {
260
          throw new InternalError("The GNU implementation of the " +
261
                                  "operating system bean is not a " +
262
                                  "compliant management bean.");
263
        }
264
    return osBean;
265
  }
266
 
267
  /**
268
   * Returns the runtime management bean for the
269
   * running virtual machine.
270
   *
271
   * @return an instance of {@link RuntimeMXBean} for
272
   *         this virtual machine.
273
   */
274
  public static RuntimeMXBean getRuntimeMXBean()
275
  {
276
    if (runtimeBean == null)
277
      try
278
        {
279
          runtimeBean = new RuntimeMXBeanImpl();
280
        }
281
      catch (NotCompliantMBeanException e)
282
        {
283
          throw new InternalError("The GNU implementation of the " +
284
                                  "runtime bean is not a compliant " +
285
                                  "management bean.");
286
        }
287
    return runtimeBean;
288
  }
289
 
290
  /**
291
   * Returns the class loading management bean for the
292
   * running virtual machine.
293
   *
294
   * @return an instance of {@link ClassLoadingMXBean} for
295
   *         this virtual machine.
296
   */
297
  public static ClassLoadingMXBean getClassLoadingMXBean()
298
  {
299
    if (classLoadingBean == null)
300
      try
301
        {
302
          classLoadingBean = new ClassLoadingMXBeanImpl();
303
        }
304
      catch (NotCompliantMBeanException e)
305
        {
306
          throw new InternalError("The GNU implementation of the " +
307
                                  "class loading bean is not a " +
308
                                  "compliant management bean.");
309
        }
310
    return classLoadingBean;
311
  }
312
 
313
  /**
314
   * Returns the thread management bean for the running
315
   * virtual machine.
316
   *
317
   * @return an instance of {@link ThreadMXBean} for
318
   *         this virtual machine.
319
   */
320
  public static ThreadMXBean getThreadMXBean()
321
  {
322
    if (threadBean == null)
323
      try
324
        {
325
          threadBean = new ThreadMXBeanImpl();
326
        }
327
      catch (NotCompliantMBeanException e)
328
        {
329
          throw new InternalError("The GNU implementation of the " +
330
                                  "thread bean is not a compliant " +
331
                                  "management bean.");
332
        }
333
    return threadBean;
334
  }
335
 
336
  /**
337
   * Returns the memory management bean for the running
338
   * virtual machine.
339
   *
340
   * @return an instance of {@link MemoryMXBean} for
341
   *         this virtual machine.
342
   */
343
  public static MemoryMXBean getMemoryMXBean()
344
  {
345
    if (memoryBean == null)
346
      try
347
        {
348
          memoryBean = new MemoryMXBeanImpl();
349
        }
350
      catch (NotCompliantMBeanException e)
351
        {
352
          throw new InternalError("The GNU implementation of the " +
353
                                  "memory bean is not a compliant " +
354
                                  "management bean.");
355
        }
356
    return memoryBean;
357
  }
358
 
359
  /**
360
   * Returns the compilation bean for the running
361
   * virtual machine, if supported.  Otherwise,
362
   * it returns <code>null</code>.
363
   *
364
   * @return an instance of {@link CompilationMXBean} for
365
   *         this virtual machine, or <code>null</code>
366
   *         if the virtual machine doesn't include
367
   *         a Just-In-Time (JIT) compiler.
368
   */
369
  public static CompilationMXBean getCompilationMXBean()
370
  {
371
    if (compilationBean == null &&
372
        SystemProperties.getProperty("gnu.java.compiler.name") != null)
373
      try
374
        {
375
          compilationBean = new CompilationMXBeanImpl();
376
        }
377
      catch (NotCompliantMBeanException e)
378
        {
379
          throw new InternalError("The GNU implementation of the " +
380
                                  "compilation bean is not a compliant " +
381
                                  "management bean.");
382
        }
383
    return compilationBean;
384
  }
385
 
386
  /**
387
   * Returns the memory pool beans for the running
388
   * virtual machine.  These may change during the course
389
   * of execution.
390
   *
391
   * @return a list of memory pool beans, one for each pool.
392
   */
393
  public static List<MemoryPoolMXBean> getMemoryPoolMXBeans()
394
  {
395
    List<MemoryPoolMXBean> poolBeans =
396
      new ArrayList<MemoryPoolMXBean>();
397
    String[] names = VMManagementFactory.getMemoryPoolNames();
398
    for (int a = 0; a < names.length; ++a)
399
      try
400
        {
401
          poolBeans.add(new MemoryPoolMXBeanImpl(names[a]));
402
        }
403
      catch (NotCompliantMBeanException e)
404
        {
405
          throw new InternalError("The GNU implementation of the " +
406
                                  "memory pool bean, " + a + ", is " +
407
                                  "not a compliant management bean.");
408
        }
409
    return poolBeans;
410
  }
411
 
412
  /**
413
   * Returns the memory manager beans for the running
414
   * virtual machine.  These may change during the course
415
   * of execution.
416
   *
417
   * @return a list of memory manager beans, one for each manager.
418
   */
419
  public static List<MemoryManagerMXBean> getMemoryManagerMXBeans()
420
  {
421
    List<MemoryManagerMXBean> managerBeans =
422
      new ArrayList<MemoryManagerMXBean>();
423
    String[] names = VMManagementFactory.getMemoryManagerNames();
424
    for (int a = 0; a < names.length; ++a)
425
      try
426
        {
427
          managerBeans.add(new MemoryManagerMXBeanImpl(names[a]));
428
        }
429
      catch (NotCompliantMBeanException e)
430
        {
431
          throw new InternalError("The GNU implementation of the " +
432
                                  "memory manager bean, " + a + ", is " +
433
                                  "not a compliant management bean.");
434
        }
435
    managerBeans.addAll(getGarbageCollectorMXBeans());
436
    return managerBeans;
437
  }
438
 
439
  /**
440
   * Returns the garbage collector beans for the running
441
   * virtual machine.  These may change during the course
442
   * of execution.
443
   *
444
   * @return a list of garbage collector beans, one for each pool.
445
   */
446
  public static List<GarbageCollectorMXBean> getGarbageCollectorMXBeans()
447
  {
448
    List<GarbageCollectorMXBean> gcBeans =
449
      new ArrayList<GarbageCollectorMXBean>();
450
    String[] names = VMManagementFactory.getGarbageCollectorNames();
451
    for (int a = 0; a < names.length; ++a)
452
      try
453
        {
454
          gcBeans.add(new GarbageCollectorMXBeanImpl(names[a]));
455
        }
456
      catch (NotCompliantMBeanException e)
457
        {
458
          throw new InternalError("The GNU implementation of the " +
459
                                  "garbage collector bean, " + a +
460
                                  ", is not a compliant management " +
461
                                  "bean.");
462
        }
463
    return gcBeans;
464
  }
465
 
466
  /**
467
   * <p>
468
   * Returns the platform {@link javax.management.MBeanServer}.  On the
469
   * first call to this method, a server instance is retrieved from
470
   * the {@link javax.management.MBeanServerFactory} and each of the
471
   * beans are registered with it.  Subsequent calls return the existing
472
   * instance.  If the property <code>javax.management.builder.initial</code>
473
   * is set, its value will be used as the name of the class which is used
474
   * to provide the server instance.
475
   * </p>
476
   * <p>
477
   * It is recommended that the platform server is used for other beans as
478
   * well, in order to simplify their discovery and publication.  Name conflicts
479
   * should be avoided.
480
   * </p>
481
   *
482
   * @return the platform {@link javax.management.MBeanServer}
483
   * @throws SecurityException if a security manager exists and the
484
   *                           caller's permissions don't imply {@link
485
   *                           MBeanServerPermission(String)}("createMBeanServer")
486
   * @see javax.management.MBeanServerFactory
487
   * @see javax.management.MBeanServerFactory#createMBeanServer()
488
   */
489
  public static MBeanServer getPlatformMBeanServer()
490
  {
491
    if (platformServer == null)
492
      {
493
        platformServer = MBeanServerFactory.createMBeanServer();
494
        try
495
          {
496
            platformServer.registerMBean(getOperatingSystemMXBean(),
497
                                         new ObjectName(OPERATING_SYSTEM_MXBEAN_NAME));
498
            platformServer.registerMBean(getRuntimeMXBean(),
499
                                         new ObjectName(RUNTIME_MXBEAN_NAME));
500
            platformServer.registerMBean(getClassLoadingMXBean(),
501
                                         new ObjectName(CLASS_LOADING_MXBEAN_NAME));
502
            platformServer.registerMBean(getThreadMXBean(),
503
                                         new ObjectName(THREAD_MXBEAN_NAME));
504
            platformServer.registerMBean(getMemoryMXBean(),
505
                                         new ObjectName(MEMORY_MXBEAN_NAME));
506
            CompilationMXBean compBean = getCompilationMXBean();
507
            if (compBean != null)
508
              platformServer.registerMBean(compBean,
509
                                           new ObjectName(COMPILATION_MXBEAN_NAME));
510
            Iterator beans = getMemoryPoolMXBeans().iterator();
511
            while (beans.hasNext())
512
              {
513
                MemoryPoolMXBean bean = (MemoryPoolMXBean) beans.next();
514
                platformServer.registerMBean(bean,
515
                                             new ObjectName(MEMORY_POOL_MXBEAN_DOMAIN_TYPE +
516
                                                            ",name=" +
517
                                                            bean.getName()));
518
              }
519
            beans = getMemoryManagerMXBeans().iterator();
520
            while (beans.hasNext())
521
              {
522
                MemoryManagerMXBean bean = (MemoryManagerMXBean) beans.next();
523
                platformServer.registerMBean(bean,
524
                                             new ObjectName(MEMORY_MANAGER_MXBEAN_DOMAIN_TYPE +
525
                                                            ",name=" +
526
                                                            bean.getName()));
527
              }
528
            beans = getGarbageCollectorMXBeans().iterator();
529
            while (beans.hasNext())
530
              {
531
                GarbageCollectorMXBean bean = (GarbageCollectorMXBean) beans.next();
532
                platformServer.registerMBean(bean,
533
                                             new ObjectName(GARBAGE_COLLECTOR_MXBEAN_DOMAIN_TYPE +
534
                                                            ",name=" +
535
                                                            bean.getName()));
536
              }
537
            platformServer.registerMBean(LogManager.getLoggingMXBean(),
538
                                         new ObjectName(LogManager.LOGGING_MXBEAN_NAME));
539
          }
540
        catch (InstanceAlreadyExistsException e)
541
          {
542
            throw (Error)
543
              (new InternalError("One of the management beans is " +
544
                                 "already registered.").initCause(e));
545
          }
546
        catch (MBeanRegistrationException e)
547
          {
548
            throw (Error)
549
              (new InternalError("One of the management beans' preRegister " +
550
                                 "methods threw an exception.").initCause(e));
551
          }
552
        catch (NotCompliantMBeanException e)
553
          {
554
            throw (Error)
555
              (new InternalError("One of the management beans is " +
556
                                 "not compliant.").initCause(e));
557
          }
558
        catch (MalformedObjectNameException e)
559
          {
560
            throw (Error)
561
              (new InternalError("The object name of a management bean is " +
562
                                 "not compliant.").initCause(e));
563
          }
564
      }
565
    return platformServer;
566
  }
567
 
568
  /**
569
   * <p>
570
   * Returns a proxy for the specified platform bean.  A proxy object is created
571
   * using <code>Proxy.newProxyInstance(mxbeanInterface.getClassLoader(),
572
   * new Class[] { mxbeanInterface }, handler)</code>.  The
573
   * {@link javax.management.NotificationEmitter} class is also added to the
574
   * array if the bean provides notifications.  <code>handler</code> refers
575
   * to the invocation handler which forwards calls to the connection, and
576
   * also provides translation between the Java data types used in the
577
   * bean interfaces and the open data types, as specified in the description
578
   * of this class.  It is this translation that makes the
579
   * usual {@link javax.management.MBeanServerInvocationHandler} inappropriate
580
   * for providing such a proxy.
581
   * </p>
582
   * <p>
583
   * <strong>Note</strong>: use of the proxy may result in
584
   * {@link java.io.IOException}s from the underlying {@link MBeanServerConnection}
585
   * and a {@link java.io.InvalidObjectException} if enum constants
586
   * used on the client and the server don't match.
587
   * </p>
588
   *
589
   * @param connection the server connection to use to access the bean.
590
   * @param mxbeanName the {@link javax.management.ObjectName} of the
591
   *                   bean to provide a proxy for.
592
   * @param mxbeanInterface the interface for the bean being proxied.
593
   * @return a proxy for the specified bean.
594
   * @throws IllegalArgumentException if <code>mxbeanName</code> is not a valid
595
   *                                  {@link javax.management.ObjectName},
596
   *                                  the interface and name do not match the
597
   *                                  same bean, the name does not refer to a
598
   *                                  platform bean or the bean is not registered
599
   *                                  with the server accessed by <code>connection</code>.
600
   * @throws IOException if the connection throws one.
601
   */
602
  public static <T> T newPlatformMXBeanProxy(MBeanServerConnection connection,
603
                                             String mxbeanName,
604
                                             Class<T> mxbeanInterface)
605
    throws IOException
606
  {
607
    if (!(mxbeanName.equals(CLASS_LOADING_MXBEAN_NAME) ||
608
          mxbeanName.equals(COMPILATION_MXBEAN_NAME) ||
609
          mxbeanName.startsWith(GARBAGE_COLLECTOR_MXBEAN_DOMAIN_TYPE) ||
610
          mxbeanName.startsWith(MEMORY_MANAGER_MXBEAN_DOMAIN_TYPE) ||
611
          mxbeanName.equals(MEMORY_MXBEAN_NAME) ||
612
          mxbeanName.startsWith(MEMORY_POOL_MXBEAN_DOMAIN_TYPE) ||
613
          mxbeanName.equals(OPERATING_SYSTEM_MXBEAN_NAME) ||
614
          mxbeanName.equals(RUNTIME_MXBEAN_NAME) ||
615
          mxbeanName.equals(THREAD_MXBEAN_NAME)))
616
      {
617
        throw new IllegalArgumentException("The named bean, " + mxbeanName +
618
                                           ", is not a platform name.");
619
      }
620
    if ((mxbeanName.equals(CLASS_LOADING_MXBEAN_NAME) &&
621
         mxbeanInterface != ClassLoadingMXBean.class) ||
622
        (mxbeanName.equals(COMPILATION_MXBEAN_NAME) &&
623
         mxbeanInterface != CompilationMXBean.class) ||
624
        (mxbeanName.startsWith(GARBAGE_COLLECTOR_MXBEAN_DOMAIN_TYPE) &&
625
         mxbeanInterface != GarbageCollectorMXBean.class) ||
626
        (mxbeanName.startsWith(MEMORY_MANAGER_MXBEAN_DOMAIN_TYPE) &&
627
         mxbeanInterface != MemoryManagerMXBean.class) ||
628
        (mxbeanName.equals(MEMORY_MXBEAN_NAME) &&
629
         mxbeanInterface != MemoryMXBean.class) ||
630
        (mxbeanName.startsWith(MEMORY_POOL_MXBEAN_DOMAIN_TYPE) &&
631
         mxbeanInterface != MemoryPoolMXBean.class) ||
632
        (mxbeanName.equals(OPERATING_SYSTEM_MXBEAN_NAME) &&
633
         mxbeanInterface != OperatingSystemMXBean.class) ||
634
        (mxbeanName.equals(RUNTIME_MXBEAN_NAME) &&
635
         mxbeanInterface != RuntimeMXBean.class) ||
636
        (mxbeanName.equals(THREAD_MXBEAN_NAME) &&
637
         mxbeanInterface != ThreadMXBean.class))
638
      throw new IllegalArgumentException("The interface, " + mxbeanInterface +
639
                                         ", does not match the bean, " + mxbeanName);
640
    ObjectName bean;
641
    try
642
      {
643
        bean = new ObjectName(mxbeanName);
644
      }
645
    catch (MalformedObjectNameException e)
646
      {
647
        throw new IllegalArgumentException("The named bean is invalid.");
648
      }
649
    if (!(connection.isRegistered(bean)))
650
      throw new IllegalArgumentException("The bean is not registered on this connection.");
651
    Class[] interfaces;
652
    if (mxbeanName.equals(MEMORY_MXBEAN_NAME))
653
      interfaces = new Class[] { mxbeanInterface, NotificationEmitter.class };
654
    else
655
      interfaces = new Class[] { mxbeanInterface };
656
    return (T) Proxy.newProxyInstance(mxbeanInterface.getClassLoader(),
657
                                      interfaces,
658
                                      new ManagementInvocationHandler(connection, bean));
659
  }
660
 
661
  /**
662
   * This invocation handler provides method calls for a platform bean
663
   * by forwarding them to a {@link MBeanServerConnection}.  Translation from
664
   * Java data types to open data types is performed as specified above.
665
   *
666
   * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
667
   * @since 1.5
668
   */
669
  private static class ManagementInvocationHandler
670
    implements InvocationHandler
671
  {
672
 
673
    /**
674
     * The encapsulated connection.
675
     */
676
    private MBeanServerConnection conn;
677
 
678
    /**
679
     * The bean being proxied.
680
     */
681
    private ObjectName bean;
682
 
683
    /**
684
     * Constructs a new {@link InvocationHandler} which proxies
685
     * for the specified bean using the supplied connection.
686
     *
687
     * @param conn the connection on which to forward method calls.
688
     * @param bean the bean to proxy.
689
     */
690
    public ManagementInvocationHandler(MBeanServerConnection conn,
691
                                       ObjectName bean)
692
      throws IOException
693
    {
694
      this.conn = conn;
695
      this.bean = bean;
696
    }
697
 
698
    /**
699
     * Called by the proxy class whenever a method is called.  The method
700
     * is emulated by retrieving an attribute from, setting an attribute on
701
     * or invoking a method on the server connection as required.  Translation
702
     * between the Java data types supplied as arguments to the open types used
703
     * by the bean is provided, as well as translation of the return value back
704
     * in to the appropriate Java type.
705
     *
706
     * @param proxy the proxy on which the method was called.
707
     * @param method the method which was called.
708
     * @param args the arguments supplied to the method.
709
     * @return the return value from the method.
710
     * @throws Throwable if an exception is thrown in performing the
711
     *                   method emulation.
712
     */
713
    public Object invoke(Object proxy, Method method, Object[] args)
714
      throws Throwable
715
    {
716
      String name = method.getName();
717
      if (name.equals("toString"))
718
        return "Proxy for " + bean + " using " + conn;
719
      if (name.equals("addNotificationListener"))
720
        {
721
          conn.addNotificationListener(bean,
722
                                       (NotificationListener) args[0],
723
                                       (NotificationFilter) args[1],
724
                                       args[2]);
725
          return null;
726
        }
727
      if (name.equals("getNotificationInfo"))
728
        return conn.getMBeanInfo(bean).getNotifications();
729
      if (name.equals("removeNotificationListener"))
730
        {
731
          if (args.length == 1)
732
            conn.removeNotificationListener(bean,
733
                                            (NotificationListener)
734
                                            args[0]);
735
          else
736
            conn.removeNotificationListener(bean,
737
                                            (NotificationListener)
738
                                            args[0],
739
                                            (NotificationFilter)
740
                                            args[1], args[2]);
741
          return null;
742
        }
743
      String attrib = null;
744
      if (name.startsWith("get"))
745
        attrib = name.substring(3);
746
      else if (name.startsWith("is"))
747
        attrib = name.substring(2);
748
      if (attrib != null)
749
        return translate(conn.getAttribute(bean, attrib), method);
750
      else if (name.startsWith("set"))
751
        {
752
          conn.setAttribute(bean, new Attribute(name.substring(3),
753
                                                args[0]));
754
          return null;
755
        }
756
      else
757
        return translate(conn.invoke(bean, name, args, null), method);
758
    }
759
 
760
    /**
761
     * Translates the returned open data type to the value
762
     * required by the interface.
763
     *
764
     * @param otype the open type returned by the method call.
765
     * @param method the method that was called.
766
     * @return the equivalent return type required by the interface.
767
     * @throws Throwable if an exception is thrown in performing the
768
     *                   conversion.
769
     */
770
    private final Object translate(Object otype, Method method)
771
      throws Throwable
772
    {
773
      Class<?> returnType = method.getReturnType();
774
      if (returnType.isEnum())
775
        {
776
          String ename = (String) otype;
777
          Enum[] constants = (Enum[]) returnType.getEnumConstants();
778
          for (Enum c : constants)
779
            if (c.name().equals(ename))
780
              return c;
781
        }
782
      if (List.class.isAssignableFrom(returnType))
783
        {
784
          Object[] elems = (Object[]) otype;
785
          List l = new ArrayList(elems.length);
786
          for (Object elem : elems)
787
            l.add(elem);
788
          return l;
789
        }
790
      if (Map.class.isAssignableFrom(returnType))
791
        {
792
          TabularData data = (TabularData) otype;
793
          Map m = new HashMap(data.size());
794
          for (Object val : data.values())
795
            {
796
              CompositeData vals = (CompositeData) val;
797
              m.put(vals.get("key"), vals.get("value"));
798
            }
799
          return m;
800
        }
801
      try
802
        {
803
          Method m = returnType.getMethod("from",
804
                                          new Class[]
805
            { CompositeData.class });
806
          return m.invoke(null, (CompositeData) otype);
807
        }
808
      catch (NoSuchMethodException e)
809
        {
810
          /* Ignored; we expect this if this
811
             isn't a from(CompositeData) class */
812
        }
813
      return otype;
814
    }
815
 
816
  }
817
}

powered by: WebSVN 2.1.0

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