libjava/classpath/ChangeLog.gcj:
2007-05-31 Matthias Klose <doko@ubuntu.com> * javax/management/NotificationBroadcasterSupport.java (getNotificationInfo): Add cast. * native/jni/qt-peer/Makefile.am (AM_CXXFLAGS): Add libstdc++ include directories. * native/jni/qt-peer/Makefile.in: Regenerate. libjava/ChangeLog: 2007-06-03 Matthias Klose <doko@ubuntu.com> * java/io/natFileWin32.cc (setFilePermissions): New (stub only). _access: Handle EXEC query, stub only. 2007-06-03 Matthias Klose <doko@ubuntu.com> Merged from classpath: * gnu/java/nio/SelectorProviderImpl.java: Whitespace merge. * java/lang/System.java(inheritedChannel): New. * java/lang/Character.java: Remove stray`;'. * java/net/MulticastSocket.java: Merged. * java/text/DateFormatSymbols.java(getInstance): New, comment updates. * java/text/Collator.java(getInstance): Merged. * java/util/Calendar.java: New attributes ALL_STYLES, SHORT, LONG. getDisplayName, getDisplayNames: New. * java/util/logging/Logger.java: Merged. * Regenerate .class and .h files. 2007-06-03 Matthias Klose <doko@ubuntu.com> * java/io/File.java: Merge with classpath-0.95, new method setFilePermissions, new attribute EXEC. * java/io/natFilePosix.cc (setFilePermissions): New. _access: Handle EXEC query. * classpath/lib/java/io/File.class, java/io/File.h: Regenerate. 2007-06-03 Matthias Klose <doko@ubuntu.com> Imported GNU Classpath 0.95. * classpath/Makefile.in, classpath/native/jni/midi-dssi/Makefile.in, classpath/native/jni/classpath/Makefile.in, classpath/native/jni/Makefile.in, classpath/native/jni/gconf-peer/Makefile.in, classpath/native/jni/java-io/Makefile.in, classpath/native/jni/native-lib/Makefile.in, classpath/native/jni/java-util/Makefile.in, classpath/native/jni/midi-alsa/Makefile.in, classpath/native/jni/java-lang/Makefile.in, classpath/native/jni/java-nio/Makefile.in, classpath/native/jni/java-net/Makefile.in, classpath/native/jni/xmlj/Makefile.in, classpath/native/jni/qt-peer/Makefile.in, classpath/native/jni/gtk-peer/Makefile.in, classpath/native/Makefile.in, classpath/native/jawt/Makefile.in, classpath/native/fdlibm/Makefile.in, classpath/native/plugin/Makefile.in, classpath/resource/Makefile.in, classpath/scripts/Makefile.in, classpath/tools/Makefile.in, classpath/doc/Makefile.in, classpath/doc/api/Makefile.in, classpath/lib/Makefile.in, classpath/external/Makefile.in, classpath/external/jsr166/Makefile.in, classpath/external/sax/Makefile.in, classpath/external/w3c_dom/Makefile.in, classpath/external/relaxngDatatype/Makefile.in, classpath/include/Makefile.in, classpath/examples/Makefile.in: Regenerate. * classpath/config.guess, classpath/config.sub, classpath/ltmain.sh : Update. * classpath/configure, classpath/depcomp, classpath/missing, classpath/aclocal.m4, classpath/install-sh: Regenerate. * gnu/classpath/Configuration.java (CLASSPATH_VERSION): Now 0.95. * sources.am: Regenerate. * Makefile.in: Regenerate. * Update the .class files and generated CNI header files, add new .class and generated CNI header files. * Remove generated files for removed java source files: classpath/gnu/java/net/BASE64.java, classpath/gnu/java/security/util/Base64.java, classpath/gnu/java/awt/peer/gtk/GThreadMutex.java, classpath/gnu/java/awt/peer/gtk/GThreadNativeMethodRunner.java, classpath/gnu/java/awt/font/autofit/Scaler.java, classpath/gnu/classpath/jdwp/util/Value.java, classpath/gnu/javax/net/ssl/Base64.java. * Remove empty directories. * Makefile.am(nat_source_files): Add natVMOperatingSystemMXBeanImpl.cc. * java/lang/Class.java(setAccessible): Merge from classpath. * java/util/Locale.java: Remove. * gnu/java/lang/management/VMOperatingSystemMXBeanImpl.java, gnu/java/lang/management/natVMOperatingSystemMXBeanImpl.cc: New. * gcj/javaprims.h: Update class declarations. * scripts/classes.pl: Update usage. * HACKING: Mention to build all peers. From-SVN: r125302
This commit is contained in:
@@ -49,20 +49,36 @@ import gnu.java.lang.management.MemoryPoolMXBeanImpl;
|
||||
import gnu.java.lang.management.RuntimeMXBeanImpl;
|
||||
import gnu.java.lang.management.ThreadMXBeanImpl;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import java.lang.reflect.InvocationHandler;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Proxy;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import java.util.logging.LogManager;
|
||||
|
||||
import javax.management.Attribute;
|
||||
import javax.management.InstanceAlreadyExistsException;
|
||||
import javax.management.MBeanRegistrationException;
|
||||
import javax.management.MBeanServer;
|
||||
import javax.management.MBeanServerConnection;
|
||||
import javax.management.MBeanServerFactory;
|
||||
import javax.management.MalformedObjectNameException;
|
||||
import javax.management.NotCompliantMBeanException;
|
||||
import javax.management.NotificationEmitter;
|
||||
import javax.management.NotificationFilter;
|
||||
import javax.management.NotificationListener;
|
||||
import javax.management.ObjectName;
|
||||
|
||||
import javax.management.openmbean.CompositeData;
|
||||
import javax.management.openmbean.TabularData;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Provides access to the system's management beans via a series
|
||||
@@ -549,4 +565,253 @@ public class ManagementFactory
|
||||
return platformServer;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Returns a proxy for the specified platform bean. A proxy object is created
|
||||
* using <code>Proxy.newProxyInstance(mxbeanInterface.getClassLoader(),
|
||||
* new Class[] { mxbeanInterface }, handler)</code>. The
|
||||
* {@link javax.management.NotificationEmitter} class is also added to the
|
||||
* array if the bean provides notifications. <code>handler</code> refers
|
||||
* to the invocation handler which forwards calls to the connection, and
|
||||
* also provides translation between the Java data types used in the
|
||||
* bean interfaces and the open data types, as specified in the description
|
||||
* of this class. It is this translation that makes the
|
||||
* usual {@link javax.management.MBeanServerInvocationHandler} inappropriate
|
||||
* for providing such a proxy.
|
||||
* </p>
|
||||
* <p>
|
||||
* <strong>Note</strong>: use of the proxy may result in
|
||||
* {@link java.io.IOException}s from the underlying {@link MBeanServerConnection}
|
||||
* and a {@link java.io.InvalidObjectException} if enum constants
|
||||
* used on the client and the server don't match.
|
||||
* </p>
|
||||
*
|
||||
* @param connection the server connection to use to access the bean.
|
||||
* @param mxbeanName the {@link javax.management.ObjectName} of the
|
||||
* bean to provide a proxy for.
|
||||
* @param mxbeanInterface the interface for the bean being proxied.
|
||||
* @return a proxy for the specified bean.
|
||||
* @throws IllegalArgumentException if <code>mxbeanName</code> is not a valid
|
||||
* {@link javax.management.ObjectName},
|
||||
* the interface and name do not match the
|
||||
* same bean, the name does not refer to a
|
||||
* platform bean or the bean is not registered
|
||||
* with the server accessed by <code>connection</code>.
|
||||
* @throws IOException if the connection throws one.
|
||||
*/
|
||||
public static <T> T newPlatformMXBeanProxy(MBeanServerConnection connection,
|
||||
String mxbeanName,
|
||||
Class<T> mxbeanInterface)
|
||||
throws IOException
|
||||
{
|
||||
if (!(mxbeanName.equals(CLASS_LOADING_MXBEAN_NAME) ||
|
||||
mxbeanName.equals(COMPILATION_MXBEAN_NAME) ||
|
||||
mxbeanName.startsWith(GARBAGE_COLLECTOR_MXBEAN_DOMAIN_TYPE) ||
|
||||
mxbeanName.startsWith(MEMORY_MANAGER_MXBEAN_DOMAIN_TYPE) ||
|
||||
mxbeanName.equals(MEMORY_MXBEAN_NAME) ||
|
||||
mxbeanName.startsWith(MEMORY_POOL_MXBEAN_DOMAIN_TYPE) ||
|
||||
mxbeanName.equals(OPERATING_SYSTEM_MXBEAN_NAME) ||
|
||||
mxbeanName.equals(RUNTIME_MXBEAN_NAME) ||
|
||||
mxbeanName.equals(THREAD_MXBEAN_NAME)))
|
||||
{
|
||||
throw new IllegalArgumentException("The named bean, " + mxbeanName +
|
||||
", is not a platform name.");
|
||||
}
|
||||
if ((mxbeanName.equals(CLASS_LOADING_MXBEAN_NAME) &&
|
||||
mxbeanInterface != ClassLoadingMXBean.class) ||
|
||||
(mxbeanName.equals(COMPILATION_MXBEAN_NAME) &&
|
||||
mxbeanInterface != CompilationMXBean.class) ||
|
||||
(mxbeanName.startsWith(GARBAGE_COLLECTOR_MXBEAN_DOMAIN_TYPE) &&
|
||||
mxbeanInterface != GarbageCollectorMXBean.class) ||
|
||||
(mxbeanName.startsWith(MEMORY_MANAGER_MXBEAN_DOMAIN_TYPE) &&
|
||||
mxbeanInterface != MemoryManagerMXBean.class) ||
|
||||
(mxbeanName.equals(MEMORY_MXBEAN_NAME) &&
|
||||
mxbeanInterface != MemoryMXBean.class) ||
|
||||
(mxbeanName.startsWith(MEMORY_POOL_MXBEAN_DOMAIN_TYPE) &&
|
||||
mxbeanInterface != MemoryPoolMXBean.class) ||
|
||||
(mxbeanName.equals(OPERATING_SYSTEM_MXBEAN_NAME) &&
|
||||
mxbeanInterface != OperatingSystemMXBean.class) ||
|
||||
(mxbeanName.equals(RUNTIME_MXBEAN_NAME) &&
|
||||
mxbeanInterface != RuntimeMXBean.class) ||
|
||||
(mxbeanName.equals(THREAD_MXBEAN_NAME) &&
|
||||
mxbeanInterface != ThreadMXBean.class))
|
||||
throw new IllegalArgumentException("The interface, " + mxbeanInterface +
|
||||
", does not match the bean, " + mxbeanName);
|
||||
ObjectName bean;
|
||||
try
|
||||
{
|
||||
bean = new ObjectName(mxbeanName);
|
||||
}
|
||||
catch (MalformedObjectNameException e)
|
||||
{
|
||||
throw new IllegalArgumentException("The named bean is invalid.");
|
||||
}
|
||||
if (!(connection.isRegistered(bean)))
|
||||
throw new IllegalArgumentException("The bean is not registered on this connection.");
|
||||
Class[] interfaces;
|
||||
if (mxbeanName.equals(MEMORY_MXBEAN_NAME))
|
||||
interfaces = new Class[] { mxbeanInterface, NotificationEmitter.class };
|
||||
else
|
||||
interfaces = new Class[] { mxbeanInterface };
|
||||
return (T) Proxy.newProxyInstance(mxbeanInterface.getClassLoader(),
|
||||
interfaces,
|
||||
new ManagementInvocationHandler(connection, bean));
|
||||
}
|
||||
|
||||
/**
|
||||
* This invocation handler provides method calls for a platform bean
|
||||
* by forwarding them to a {@link MBeanServerConnection}. Translation from
|
||||
* Java data types to open data types is performed as specified above.
|
||||
*
|
||||
* @author Andrew John Hughes (gnu_andrew@member.fsf.org)
|
||||
* @since 1.5
|
||||
*/
|
||||
private static class ManagementInvocationHandler
|
||||
implements InvocationHandler
|
||||
{
|
||||
|
||||
/**
|
||||
* The encapsulated connection.
|
||||
*/
|
||||
private MBeanServerConnection conn;
|
||||
|
||||
/**
|
||||
* The bean being proxied.
|
||||
*/
|
||||
private ObjectName bean;
|
||||
|
||||
/**
|
||||
* Constructs a new {@link InvocationHandler} which proxies
|
||||
* for the specified bean using the supplied connection.
|
||||
*
|
||||
* @param conn the connection on which to forward method calls.
|
||||
* @param bean the bean to proxy.
|
||||
*/
|
||||
public ManagementInvocationHandler(MBeanServerConnection conn,
|
||||
ObjectName bean)
|
||||
throws IOException
|
||||
{
|
||||
this.conn = conn;
|
||||
this.bean = bean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by the proxy class whenever a method is called. The method
|
||||
* is emulated by retrieving an attribute from, setting an attribute on
|
||||
* or invoking a method on the server connection as required. Translation
|
||||
* between the Java data types supplied as arguments to the open types used
|
||||
* by the bean is provided, as well as translation of the return value back
|
||||
* in to the appropriate Java type.
|
||||
*
|
||||
* @param proxy the proxy on which the method was called.
|
||||
* @param method the method which was called.
|
||||
* @param args the arguments supplied to the method.
|
||||
* @return the return value from the method.
|
||||
* @throws Throwable if an exception is thrown in performing the
|
||||
* method emulation.
|
||||
*/
|
||||
public Object invoke(Object proxy, Method method, Object[] args)
|
||||
throws Throwable
|
||||
{
|
||||
String name = method.getName();
|
||||
if (name.equals("toString"))
|
||||
return "Proxy for " + bean + " using " + conn;
|
||||
if (name.equals("addNotificationListener"))
|
||||
{
|
||||
conn.addNotificationListener(bean,
|
||||
(NotificationListener) args[0],
|
||||
(NotificationFilter) args[1],
|
||||
args[2]);
|
||||
return null;
|
||||
}
|
||||
if (name.equals("getNotificationInfo"))
|
||||
return conn.getMBeanInfo(bean).getNotifications();
|
||||
if (name.equals("removeNotificationListener"))
|
||||
{
|
||||
if (args.length == 1)
|
||||
conn.removeNotificationListener(bean,
|
||||
(NotificationListener)
|
||||
args[0]);
|
||||
else
|
||||
conn.removeNotificationListener(bean,
|
||||
(NotificationListener)
|
||||
args[0],
|
||||
(NotificationFilter)
|
||||
args[1], args[2]);
|
||||
return null;
|
||||
}
|
||||
String attrib = null;
|
||||
if (name.startsWith("get"))
|
||||
attrib = name.substring(3);
|
||||
else if (name.startsWith("is"))
|
||||
attrib = name.substring(2);
|
||||
if (attrib != null)
|
||||
return translate(conn.getAttribute(bean, attrib), method);
|
||||
else if (name.startsWith("set"))
|
||||
{
|
||||
conn.setAttribute(bean, new Attribute(name.substring(3),
|
||||
args[0]));
|
||||
return null;
|
||||
}
|
||||
else
|
||||
return translate(conn.invoke(bean, name, args, null), method);
|
||||
}
|
||||
|
||||
/**
|
||||
* Translates the returned open data type to the value
|
||||
* required by the interface.
|
||||
*
|
||||
* @param otype the open type returned by the method call.
|
||||
* @param method the method that was called.
|
||||
* @return the equivalent return type required by the interface.
|
||||
* @throws Throwable if an exception is thrown in performing the
|
||||
* conversion.
|
||||
*/
|
||||
private final Object translate(Object otype, Method method)
|
||||
throws Throwable
|
||||
{
|
||||
Class<?> returnType = method.getReturnType();
|
||||
if (returnType.isEnum())
|
||||
{
|
||||
String ename = (String) otype;
|
||||
Enum[] constants = (Enum[]) returnType.getEnumConstants();
|
||||
for (Enum c : constants)
|
||||
if (c.name().equals(ename))
|
||||
return c;
|
||||
}
|
||||
if (List.class.isAssignableFrom(returnType))
|
||||
{
|
||||
Object[] elems = (Object[]) otype;
|
||||
List l = new ArrayList(elems.length);
|
||||
for (Object elem : elems)
|
||||
l.add(elem);
|
||||
return l;
|
||||
}
|
||||
if (Map.class.isAssignableFrom(returnType))
|
||||
{
|
||||
TabularData data = (TabularData) otype;
|
||||
Map m = new HashMap(data.size());
|
||||
for (Object val : data.values())
|
||||
{
|
||||
CompositeData vals = (CompositeData) val;
|
||||
m.put(vals.get("key"), vals.get("value"));
|
||||
}
|
||||
return m;
|
||||
}
|
||||
try
|
||||
{
|
||||
Method m = returnType.getMethod("from",
|
||||
new Class[]
|
||||
{ CompositeData.class });
|
||||
return m.invoke(null, (CompositeData) otype);
|
||||
}
|
||||
catch (NoSuchMethodException e)
|
||||
{
|
||||
/* Ignored; we expect this if this
|
||||
isn't a from(CompositeData) class */
|
||||
}
|
||||
return otype;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user