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

Subversion Repositories openrisc

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 772 jeremybenn
/* MBeanServerInvocationHandler.java -- Provides a proxy for a bean.
2
   Copyright (C) 2007 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 javax.management;
39
 
40
import gnu.javax.management.Translator;
41
 
42
import java.lang.reflect.InvocationHandler;
43
import java.lang.reflect.Method;
44
import java.lang.reflect.Proxy;
45
 
46
/**
47
 * <p>
48
 * Provides a proxy for a management bean.  The methods
49
 * of the given interface are fulfilled by redirecting the
50
 * calls over an {@link MBeanServerConnection} to the bean
51
 * specified by the supplied {@link ObjectName}.
52
 * </p>
53
 * <p>
54
 * The {@link java.lang.reflect.InvocationHandler} also makes
55
 * provision for {@link MXBean}s by providing type conversion
56
 * according to the rules defined for these beans.  The input
57
 * parameters are converted to their equivalent open type before
58
 * calling the method, and then the return value is converted
59
 * back from its open type to the appropriate Java type.  For
60
 * example, a method that takes an {@link Enum} as input and
61
 * returns a {@link java.util.List} will have the input value
62
 * converted from an {@link Enum} to a {@link String}, while
63
 * the return value will be converted from its return type
64
 * (an appropriately typed array) to a {@link java.util.List}.
65
 * </p>
66
 * <p>
67
 * The proxy has special cases for the {@link Object#equals(Object)},
68
 * {@link Object#hashCode()} and {@link Object#toString()} methods.
69
 * Unless they are specified explictly by the interface, the
70
 * following behaviour is provided for these methods by the proxy:
71
 * </p>
72
 * <ul>
73
 * <li><code>equals(Object)</code> returns true if the other object
74
 * is an {@link MBeanServerInvocationHandler} with the same
75
 * {@link MBeanServerConnection} and {@link ObjectName}.  If an
76
 * interface class was specified on construction for one of the
77
 * proxies, then the same class must have also been specified
78
 * for the other.</li>
79
 * <li><code>hashCode()</code> returns the same value for
80
 * equivalent proxies.</li>
81
 * <li><code>toString()</code> returns a textual representation
82
 * of the proxy.</li>
83
 * </ul>
84
 *
85
 * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
86
 * @since 1.5
87
 */
88
public class MBeanServerInvocationHandler
89
  implements InvocationHandler
90
{
91
 
92
  /**
93
   * The connection used to make the calls.
94
   */
95
  private MBeanServerConnection conn;
96
 
97
  /**
98
   * The name of the bean to perform operations on.
99
   */
100
  private ObjectName name;
101
 
102
  /**
103
   * True if this proxy is for an {@link MXBean}.
104
   */
105
  private boolean mxBean;
106
 
107
  /**
108
   * The interface class associated with the bean.
109
   */
110
  private Class<?> iface;
111
 
112
  /**
113
   * Constructs a new {@link MBeanServerInvocationHandler}
114
   * which forwards methods to the supplied bean via the
115
   * given {@link MBeanServerConnection}.  This constructor
116
   * is used in preference to
117
   * {@link JMX#newMBeanProxy(MBeanServerConnection, ObjectName,
118
   * Class<T>)} if you wish to make your own call to
119
   * {@link java.lang.reflect.Proxy#newInstance(ClassLoader,
120
   * Class[], java.lang.reflect.InvocationHandler)} with
121
   * a different {@link ClassLoader}.  Calling this constructor
122
   * is equivalent to <code>MBeanServerInvocationHandler(conn,
123
   * name, false)</code>.  The other constructor should be used
124
   * instead if the bean being proxied is an {@link MXBean}.
125
   *
126
   * @param conn the connection through which methods will
127
   *             be forwarded to the bean.
128
   * @param name the name of the bean to use to provide the
129
   *             actual calls.
130
   */
131
  public MBeanServerInvocationHandler(MBeanServerConnection conn,
132
                                      ObjectName name)
133
  {
134
    this(conn, name, false);
135
  }
136
 
137
  /**
138
   * Constructs a new {@link MBeanServerInvocationHandler}
139
   * which forwards methods to the supplied bean via the
140
   * given {@link MBeanServerConnection}.  This constructor
141
   * is used in preference to
142
   * {@link JMX#newMBeanProxy(MBeanServerConnection, ObjectName,
143
   * Class<T>)} if you wish to make your own call to
144
   * {@link java.lang.reflect.Proxy#newInstance(ClassLoader,
145
   * Class[], java.lang.reflect.InvocationHandler)} with
146
   * a different {@link ClassLoader}.
147
   *
148
   * @param conn the connection through which methods will
149
   *             be forwarded to the bean.
150
   * @param name the name of the bean to use to provide the
151
   *             actual calls.
152
   * @param mxBean true if the bean being proxied is an
153
   *               {@link MXBean}.
154
   * @since 1.6
155
   */
156
  public MBeanServerInvocationHandler(MBeanServerConnection conn,
157
                                      ObjectName name, boolean mxBean)
158
  {
159
    this.conn = conn;
160
    this.name = name;
161
    this.mxBean = mxBean;
162
  }
163
 
164
  /**
165
   * Returns the connection through which the calls to the bean
166
   * will be made.
167
   *
168
   * @return the connection being used to forward the calls to
169
   *         the bean.
170
   * @since 1.6
171
   */
172
  public MBeanServerConnection getMBeanServerConnection()
173
  {
174
    return conn;
175
  }
176
 
177
  /**
178
   * Returns the name of the bean to which method calls are made.
179
   *
180
   * @return the bean which provides the actual method calls.
181
   * @since 1.6
182
   */
183
  public ObjectName getObjectName()
184
  {
185
    return name;
186
  }
187
 
188
  /**
189
   * Called by the proxy class whenever a method is called.  The method
190
   * is emulated by retrieving an attribute from, setting an attribute on
191
   * or invoking a method on the server connection as required.  Translation
192
   * between the Java data types supplied as arguments to the open types used
193
   * by the bean is provided, as well as translation of the return value back
194
   * in to the appropriate Java type if the bean is an {@link MXBean}.
195
   *
196
   * @param proxy the proxy on which the method was called.
197
   * @param method the method which was called.
198
   * @param args the arguments supplied to the method.
199
   * @return the return value from the method.
200
   * @throws Throwable if an exception is thrown in performing the
201
   *                   method emulation.
202
   */
203
  public Object invoke(Object proxy, Method method, Object[] args)
204
    throws Throwable
205
  {
206
    String mName = method.getName();
207
    Class<?> proxyClass = proxy.getClass();
208
    if (mName.equals("toString"))
209
      {
210
        if (inInterface(mName, proxyClass))
211
          return conn.invoke(name,mName,null,null);
212
        else
213
          return proxyClass.getName() + "[name=" + name
214
            + ", conn=" + conn + "]";
215
      }
216
    if (mName.equals("hashCode"))
217
      {
218
        if (inInterface(mName, proxyClass))
219
          return conn.invoke(name,mName,null,null);
220
        else
221
          return conn.hashCode() + name.hashCode()
222
            + (iface == null ? 0 : iface.hashCode());
223
      }
224
    if (mName.equals("equals"))
225
      {
226
        if (inInterface(mName, proxyClass, Object.class))
227
          return conn.invoke(name,mName,new Object[]{args[0]},
228
                             new String[]{"java.lang.Object"});
229
        else
230
          {
231
            if (args[0].getClass() != proxy.getClass())
232
              return false;
233
            InvocationHandler ih = Proxy.getInvocationHandler(args[0]);
234
            if (ih instanceof MBeanServerInvocationHandler)
235
              {
236
                MBeanServerInvocationHandler h =
237
                  (MBeanServerInvocationHandler) ih;
238
                return conn.equals(h.getMBeanServerConnection())
239
                  && name.equals(h.getObjectName())
240
                  && (iface == null ? h.iface == null
241
                      : iface.equals(h.iface));
242
              }
243
            return false;
244
          }
245
      }
246
    if (NotificationEmitter.class.isAssignableFrom(proxyClass))
247
      {
248
        if (mName.equals("addNotificationListener"))
249
          {
250
            conn.addNotificationListener(name,
251
                                         (NotificationListener) args[0],
252
                                         (NotificationFilter) args[1],
253
                                         args[2]);
254
            return null;
255
          }
256
        if (mName.equals("getNotificationInfo"))
257
          return conn.getMBeanInfo(name).getNotifications();
258
        if (mName.equals("removeNotificationListener"))
259
          {
260
            if (args.length == 1)
261
              conn.removeNotificationListener(name,
262
                                              (NotificationListener)
263
                                              args[0]);
264
            else
265
              conn.removeNotificationListener(name,
266
                                              (NotificationListener)
267
                                              args[0],
268
                                              (NotificationFilter)
269
                                              args[1], args[2]);
270
            return null;
271
          }
272
      }
273
    String[] sigs;
274
    if (args == null)
275
      sigs = null;
276
    else
277
      {
278
        sigs = new String[args.length];
279
        for (int a = 0; a < args.length; ++a)
280
          sigs[a] = args[a].getClass().getName();
281
      }
282
    String attrib = null;
283
    if (mName.startsWith("get"))
284
      attrib = mName.substring(3);
285
    else if (mName.startsWith("is"))
286
      attrib = mName.substring(2);
287
    if (attrib != null)
288
      {
289
        Object val = conn.getAttribute(name, attrib);
290
        if (mxBean)
291
          return Translator.toJava(val, method);
292
        else
293
          return val;
294
      }
295
    else if (mName.startsWith("set"))
296
      {
297
        Object arg;
298
        if (mxBean)
299
          arg = Translator.fromJava(args, method)[0];
300
        else
301
          arg = args[0];
302
        conn.setAttribute(name, new Attribute(mName.substring(3), arg));
303
        return null;
304
      }
305
    if (mxBean)
306
      return Translator.toJava(conn.invoke(name, mName,
307
                                           Translator.fromJava(args,method),
308
                                           sigs), method);
309
    else
310
      return conn.invoke(name, mName, args, sigs);
311
  }
312
 
313
  /**
314
   * Returns true if this is a proxy for an {@link MXBean}
315
   * and conversions must be applied to input parameters
316
   * and return types, according to the rules for such beans.
317
   *
318
   * @return true if this is a proxy for an {@link MXBean}.
319
   * @since 1.6
320
   */
321
  public boolean isMXBean()
322
  {
323
    return mxBean;
324
  }
325
 
326
  /**
327
   * <p>
328
   * Returns a proxy for the specified bean.  A proxy object is created
329
   * using <code>Proxy.newProxyInstance(iface.getClassLoader(),
330
   * new Class[] { iface }, handler)</code>.  The
331
   * {@link javax.management.NotificationEmitter} class is included as the
332
   * second element of the array if <code>broadcaster</code> is true.
333
   * <code>handler</code> refers to the invocation handler which forwards
334
   * calls to the connection, which is created by a call to
335
   * <code>new MBeanServerInvocationHandler(conn, name)</code>.
336
   * </p>
337
   * <p>
338
   * <strong>Note</strong>: use of the proxy may result in
339
   * {@link java.io.IOException}s from the underlying
340
   * {@link MBeanServerConnection}.
341
   * As of 1.6, the use of {@link JMX#newMBeanProxy(MBeanServerConnection,
342
   * ObjectName,Class)} and {@link JMX#newMBeanProxy(MBeanServerConnection,
343
   * ObjectName,Class,boolean)} is preferred.
344
   * </p>
345
   *
346
   * @param conn the server connection to use to access the bean.
347
   * @param name the {@link javax.management.ObjectName} of the
348
   *             bean to provide a proxy for.
349
   * @param iface the interface for the bean being proxied.
350
   * @param broadcaster true if the proxy should implement
351
   *                    {@link NotificationEmitter}.
352
   * @return a proxy for the specified bean.
353
   * @see JMX#newMBeanProxy(MBeanServerConnection,ObjectName,Class)
354
   */
355
  // Suppress warnings as we know an instance of T will be returned.
356
  @SuppressWarnings("unchecked")
357
  public static <T> T newProxyInstance(MBeanServerConnection conn,
358
                                       ObjectName name, Class<T> iface,
359
                                       boolean broadcaster)
360
  {
361
    if (broadcaster)
362
      return (T) Proxy.newProxyInstance(iface.getClassLoader(),
363
                                        new Class[] { iface,
364
                                                      NotificationEmitter.class },
365
                                        new MBeanServerInvocationHandler(conn,name));
366
    else
367
      return (T) Proxy.newProxyInstance(iface.getClassLoader(),
368
                                        new Class[] { iface },
369
                                        new MBeanServerInvocationHandler(conn,name));
370
  }
371
 
372
  /**
373
   * Returns true if the specified method is specified
374
   * by one of the proxy's interfaces.
375
   *
376
   * @param name the name of the method to search for.
377
   * @param proxyClass the class of the proxy.
378
   * @param args the arguments to the method.
379
   * @return true if one of the interfaces specifies the
380
   *         given method.
381
   */
382
  private boolean inInterface(String name, Class<?> proxyClass,
383
                              Class<?>... args)
384
  {
385
    for (Class<?> iface : proxyClass.getInterfaces())
386
      {
387
        try
388
          {
389
            iface.getMethod(name, args);
390
            return true;
391
          }
392
        catch (NoSuchMethodException e)
393
          {
394
            /* Ignored; this interface doesn't specify
395
               the method. */
396
          }
397
      }
398
    return false;
399
  }
400
 
401
}

powered by: WebSVN 2.1.0

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