This patch completes the implementation of a proxy
for the MXBean platform server.

Changelog:

2006-12-23  Andrew John Hughes  <[EMAIL PROTECTED]>

        * gnu/java/lang/management/BeanImpl.java:
        (translate(String)): Correct handling of
        CompositeData objects.
        * java/lang/management/ManagementFactory.java:
        (ManagementInvocationHandler.invoke(Object,
        Method,Object[])): Handle translation and notifications.
        (ManagementInvocationHandler.translate(Object,
        Method)): Implement type translation.
        * java/lang/management/MemoryUsage.java:
        (from(CompositeData)): Fix capitalisation.
        * java/lang/management/ThreadInfo.java:
        (from(CompositeData)): Likewise.
        * javax/management/StandardMBean.java:
        (getMBeanInfo()): Add notification handling.

-- 
Andrew :-)

Escape the Java Trap with GNU Classpath!
http://www.gnu.org/philosophy/java-trap.html
public class gcj extends Freedom implements Java { ... }
Index: gnu/java/lang/management/BeanImpl.java
===================================================================
RCS file: /cvsroot/classpath/classpath/gnu/java/lang/management/BeanImpl.java,v
retrieving revision 1.11
diff -u -3 -p -u -r1.11 BeanImpl.java
--- gnu/java/lang/management/BeanImpl.java      21 Dec 2006 13:02:51 -0000      
1.11
+++ gnu/java/lang/management/BeanImpl.java      23 Dec 2006 12:49:05 -0000
@@ -483,9 +483,9 @@ public class BeanImpl
     try
       {
        c.getMethod("from", new Class[] { CompositeData.class });
-       Method[] methods = c.getMethods();
-       List names = new ArrayList();
-       List types = new ArrayList();
+       Method[] methods = c.getDeclaredMethods();
+       List<String> names = new ArrayList<String>();
+       List<OpenType> types = new ArrayList<OpenType>();
        for (int a = 0; a < methods.length; ++a)
          {
            String name = methods[a].getName();
@@ -495,10 +495,10 @@ public class BeanImpl
                types.add(getTypeFromClass(methods[a].getReturnType()));
              }
          }
-       String[] fields = (String[]) names.toArray();
+       String[] fields = names.toArray(new String[names.size()]);
        CompositeType ctype = new CompositeType(c.getName(), c.getName(),
                                                fields, fields,
-                                               (OpenType[]) types.toArray());
+                                               types.toArray(new 
OpenType[types.size()]));
        return new OpenMBeanParameterInfoSupport("TransParam",
                                                 "Translated parameter",
                                                 ctype);
Index: java/lang/management/ManagementFactory.java
===================================================================
RCS file: 
/cvsroot/classpath/classpath/java/lang/management/ManagementFactory.java,v
retrieving revision 1.18
diff -u -3 -p -u -r1.18 ManagementFactory.java
--- java/lang/management/ManagementFactory.java 19 Dec 2006 00:33:44 -0000      
1.18
+++ java/lang/management/ManagementFactory.java 23 Dec 2006 12:49:06 -0000
@@ -56,8 +56,10 @@ 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;
 
@@ -70,8 +72,13 @@ import javax.management.MBeanServerFacto
 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
@@ -709,15 +716,37 @@ public class ManagementFactory
       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 conn.getAttribute(bean, attrib);
-       }
+       return translate(conn.getAttribute(bean, attrib), method);
       else if (name.startsWith("set"))
        {
          conn.setAttribute(bean, new Attribute(name.substring(3),
@@ -725,9 +754,64 @@ public class ManagementFactory
          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())
        {
-         return conn.invoke(bean, name, args, null);
-       }     
+         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;
     }
+
   }
 }
Index: java/lang/management/MemoryUsage.java
===================================================================
RCS file: /cvsroot/classpath/classpath/java/lang/management/MemoryUsage.java,v
retrieving revision 1.3
diff -u -3 -p -u -r1.3 MemoryUsage.java
--- java/lang/management/MemoryUsage.java       9 Jul 2006 20:02:03 -0000       
1.3
+++ java/lang/management/MemoryUsage.java       23 Dec 2006 12:49:06 -0000
@@ -180,14 +180,14 @@ public class MemoryUsage
     if (data == null)
       return null;
     CompositeType type = data.getCompositeType();
-    ThreadInfo.checkAttribute(type, "init", SimpleType.LONG);
-    ThreadInfo.checkAttribute(type, "used", SimpleType.LONG);
-    ThreadInfo.checkAttribute(type, "committed", SimpleType.LONG);
-    ThreadInfo.checkAttribute(type, "max", SimpleType.LONG);
-    return new MemoryUsage(((Long) data.get("init")).longValue(),
-                          ((Long) data.get("used")).longValue(),
-                          ((Long) data.get("committed")).longValue(),
-                          ((Long) data.get("max")).longValue());
+    ThreadInfo.checkAttribute(type, "Init", SimpleType.LONG);
+    ThreadInfo.checkAttribute(type, "Used", SimpleType.LONG);
+    ThreadInfo.checkAttribute(type, "Committed", SimpleType.LONG);
+    ThreadInfo.checkAttribute(type, "Max", SimpleType.LONG);
+    return new MemoryUsage(((Long) data.get("Init")).longValue(),
+                          ((Long) data.get("Used")).longValue(),
+                          ((Long) data.get("Committed")).longValue(),
+                          ((Long) data.get("Max")).longValue());
   }
 
   /**
Index: java/lang/management/ThreadInfo.java
===================================================================
RCS file: /cvsroot/classpath/classpath/java/lang/management/ThreadInfo.java,v
retrieving revision 1.6
diff -u -3 -p -u -r1.6 ThreadInfo.java
--- java/lang/management/ThreadInfo.java        10 Dec 2006 20:25:44 -0000      
1.6
+++ java/lang/management/ThreadInfo.java        23 Dec 2006 12:49:06 -0000
@@ -336,18 +336,18 @@ public class ThreadInfo
     if (data == null)
       return null;
     CompositeType type = data.getCompositeType();
-    checkAttribute(type, "threadId", SimpleType.LONG);
-    checkAttribute(type, "threadName", SimpleType.STRING);
-    checkAttribute(type, "threadState", SimpleType.STRING);
-    checkAttribute(type, "suspended", SimpleType.BOOLEAN);
-    checkAttribute(type, "inNative", SimpleType.BOOLEAN);
-    checkAttribute(type, "blockedCount", SimpleType.LONG);
-    checkAttribute(type, "blockedTime", SimpleType.LONG);
-    checkAttribute(type, "waitedCount", SimpleType.LONG);
-    checkAttribute(type, "waitedTime", SimpleType.LONG);
-    checkAttribute(type, "lockName", SimpleType.STRING);
-    checkAttribute(type, "lockOwnerId", SimpleType.LONG);
-    checkAttribute(type, "lockOwnerName", SimpleType.STRING);
+    checkAttribute(type, "ThreadId", SimpleType.LONG);
+    checkAttribute(type, "ThreadName", SimpleType.STRING);
+    checkAttribute(type, "ThreadState", SimpleType.STRING);
+    checkAttribute(type, "Suspended", SimpleType.BOOLEAN);
+    checkAttribute(type, "InNative", SimpleType.BOOLEAN);
+    checkAttribute(type, "BlockedCount", SimpleType.LONG);
+    checkAttribute(type, "BlockedTime", SimpleType.LONG);
+    checkAttribute(type, "WaitedCount", SimpleType.LONG);
+    checkAttribute(type, "WaitedTime", SimpleType.LONG);
+    checkAttribute(type, "LockName", SimpleType.STRING);
+    checkAttribute(type, "LockOwnerId", SimpleType.LONG);
+    checkAttribute(type, "LockOwnerName", SimpleType.STRING);
     try
       {
        CompositeType seType = 
@@ -368,7 +368,7 @@ public class ThreadInfo
                              SimpleType.STRING, SimpleType.INTEGER,
                              SimpleType.BOOLEAN 
                            });
-       checkAttribute(type, "stackTrace", new ArrayType(1, seType));
+       checkAttribute(type, "StackTrace", new ArrayType(1, seType));
       }
     catch (OpenDataException e)
       {
@@ -376,29 +376,29 @@ public class ThreadInfo
                                        "the composite data type for the " +
                                        "stack trace element.", e);
       }
-    CompositeData[] dTraces = (CompositeData[]) data.get("stackTrace");
+    CompositeData[] dTraces = (CompositeData[]) data.get("StackTrace");
     StackTraceElement[] traces = new StackTraceElement[dTraces.length];
     for (int a = 0; a < dTraces.length; ++a)
        /* FIXME: We can't use the boolean as there is no available
           constructor. */
       traces[a] = 
-       new StackTraceElement((String) dTraces[a].get("className"),
-                             (String) dTraces[a].get("methodName"),
-                             (String) dTraces[a].get("fileName"),
+       new StackTraceElement((String) dTraces[a].get("ClassName"),
+                             (String) dTraces[a].get("MethodName"),
+                             (String) dTraces[a].get("FileName"),
                              ((Integer) 
-                              dTraces[a].get("lineNumber")).intValue());
-    return new ThreadInfo(((Long) data.get("threadId")).longValue(),
-                         (String) data.get("threadName"),
-                         Thread.State.valueOf((String) 
data.get("threadState")),
-                         ((Long) data.get("blockedCount")).longValue(),
-                         ((Long) data.get("blockedTime")).longValue(),
-                         (String) data.get("lockName"),
-                         ((Long) data.get("lockOwnerId")).longValue(),
-                         (String) data.get("lockOwnerName"),  
-                         ((Long) data.get("waitedCount")).longValue(),
-                         ((Long) data.get("waitedTime")).longValue(),
-                         ((Boolean) data.get("inNative")).booleanValue(),
-                         ((Boolean) data.get("suspended")).booleanValue(),
+                              dTraces[a].get("LineNumber")).intValue());
+    return new ThreadInfo(((Long) data.get("ThreadId")).longValue(),
+                         (String) data.get("ThreadName"),
+                         Thread.State.valueOf((String) 
data.get("ThreadState")),
+                         ((Long) data.get("BlockedCount")).longValue(),
+                         ((Long) data.get("BlockedTime")).longValue(),
+                         (String) data.get("LockName"),
+                         ((Long) data.get("LockOwnerId")).longValue(),
+                         (String) data.get("LockOwnerName"),  
+                         ((Long) data.get("WaitedCount")).longValue(),
+                         ((Long) data.get("WaitedTime")).longValue(),
+                         ((Boolean) data.get("InNative")).booleanValue(),
+                         ((Boolean) data.get("Suspended")).booleanValue(),
                          traces);
   }
 
Index: javax/management/StandardMBean.java
===================================================================
RCS file: /cvsroot/classpath/classpath/javax/management/StandardMBean.java,v
retrieving revision 1.4
diff -u -3 -p -u -r1.4 StandardMBean.java
--- javax/management/StandardMBean.java 5 Aug 2006 18:08:28 -0000       1.4
+++ javax/management/StandardMBean.java 23 Dec 2006 12:49:07 -0000
@@ -665,7 +665,10 @@ public class StandardMBean
                         ainfo, cinfo, oinfo, null);
     String cname = getClassName(info);
     String desc = getDescription(info);
-    info = new MBeanInfo(cname, desc, ainfo, cinfo, oinfo, null);
+    MBeanNotificationInfo[] ninfo = null;
+    if (impl instanceof NotificationBroadcaster)
+      ninfo = ((NotificationBroadcaster) impl).getNotificationInfo();
+    info = new MBeanInfo(cname, desc, ainfo, cinfo, oinfo, ninfo);
     cacheMBeanInfo(info);
     return info;
   }

Attachment: signature.asc
Description: Digital signature

Reply via email to