|
From: <ls...@us...> - 2007-01-07 12:53:05
|
Revision: 3022
http://jnode.svn.sourceforge.net/jnode/?rev=3022&view=rev
Author: lsantha
Date: 2007-01-07 04:53:02 -0800 (Sun, 07 Jan 2007)
Log Message:
-----------
Classpath patches.
Modified Paths:
--------------
trunk/core/src/classpath/java/java/lang/Character.java
trunk/core/src/classpath/java/java/lang/Enum.java
trunk/core/src/classpath/java/java/lang/System.java
trunk/core/src/classpath/java/java/lang/management/ManagementFactory.java
trunk/core/src/classpath/java/java/lang/management/MemoryPoolMXBean.java
trunk/core/src/classpath/java/java/lang/management/MemoryUsage.java
trunk/core/src/classpath/java/java/lang/management/OperatingSystemMXBean.java
trunk/core/src/classpath/java/java/lang/management/RuntimeMXBean.java
trunk/core/src/classpath/java/java/lang/management/ThreadInfo.java
trunk/core/src/classpath/java/java/lang/management/ThreadMXBean.java
Added Paths:
-----------
trunk/core/src/classpath/java/java/lang/ProcessBuilder.java
trunk/core/src/classpath/java/java/lang/management/LockInfo.java
trunk/core/src/classpath/java/java/lang/management/MemoryType.java
trunk/core/src/classpath/java/java/lang/management/MonitorInfo.java
Modified: trunk/core/src/classpath/java/java/lang/Character.java
===================================================================
--- trunk/core/src/classpath/java/java/lang/Character.java 2007-01-07 12:51:25 UTC (rev 3021)
+++ trunk/core/src/classpath/java/java/lang/Character.java 2007-01-07 12:53:02 UTC (rev 3022)
@@ -156,7 +156,7 @@
private final String canonicalName;
/** Enumeration for the <code>forName()</code> method */
- private enum NameType { CANONICAL, NO_SPACES, CONSTANT; };
+ private enum NameType { CANONICAL, NO_SPACES, CONSTANT; }
/**
* Constructor for strictly defined blocks.
Modified: trunk/core/src/classpath/java/java/lang/Enum.java
===================================================================
--- trunk/core/src/classpath/java/java/lang/Enum.java 2007-01-07 12:51:25 UTC (rev 3021)
+++ trunk/core/src/classpath/java/java/lang/Enum.java 2007-01-07 12:53:02 UTC (rev 3022)
@@ -60,13 +60,13 @@
/**
* The name of this enum constant.
*/
- String name;
+ final String name;
/**
* The number of this enum constant. Each constant is given a number
* which matches the order in which it was declared, starting with zero.
*/
- int ordinal;
+ final int ordinal;
/**
* This constructor is used by the compiler to create enumeration constants.
@@ -220,4 +220,14 @@
k = k.getSuperclass();
return k;
}
+
+ /**
+ * Enumerations can not have finalization methods.
+ *
+ * @since 1.6
+ */
+ protected final void finalize()
+ {
+ }
+
}
Added: trunk/core/src/classpath/java/java/lang/ProcessBuilder.java
===================================================================
--- trunk/core/src/classpath/java/java/lang/ProcessBuilder.java (rev 0)
+++ trunk/core/src/classpath/java/java/lang/ProcessBuilder.java 2007-01-07 12:53:02 UTC (rev 3022)
@@ -0,0 +1,337 @@
+/* ProcessBuilder.java - Represent spawned system process
+ Copyright (C) 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.lang;
+
+import java.io.File;
+import java.io.IOException;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * <p>
+ * This class is used to construct new operating system processes.
+ * A <code>ProcessBuilder</code> instance basically represent a
+ * template for a new process. Actual processes are generated from
+ * this template via use of the <code>start()</code> method, which
+ * may be invoked multiple times, with each invocation spawning a
+ * new process with the current attributes of the
+ * <code>ProcessBuilder</code> object. Each spawned process is
+ * independent of the <code>ProcessBuilder</code> object, and is
+ * unaffected by changes in its attributes.
+ * </p>
+ * <p>
+ * The following attributes define a process:
+ * </p>
+ * <ul>
+ * <li>The <emphasis>working directory</emphasis>; the activities of a
+ * process begin with the current directory set to this. By default,
+ * this is the working directory of the current process, as defined
+ * by the <code>user.dir</code> property.</li>
+ * <li>The <emphasis>command</emphasis> which invokes the process. This
+ * usually consists of the name of the program binary followed by an
+ * arbitrary number of arguments. For example, <code>find -type f</code>
+ * invokes the <code>find</code> binary with the arguments "-type" and "f".
+ * The command is provided a list, the elements of which are defined in a
+ * system dependent manner; the layout is affected by expected operating
+ * system conventions. A common method is to split the command on each
+ * space within the string. Thus, <code>find -type f</code> forms a
+ * three element list. However, in some cases, the expectation is that
+ * this split is performed by the program itself; thus, the list consists
+ * of only two elements (the program name and its arguments).</li>
+ * <li>The <emphasis>environment map</emphasis>, which links environment
+ * variables to their corresponding values. The initial contents of the map
+ * are the current environment values i.e. it contains the contents of the
+ * map returned by <code>System.getenv()</code>.</li>
+ * <li>The <emphasis>redirection flag</emphasis>, which specifies whether
+ * or not the contents of the error stream should be redirected to standard
+ * output. By default, this is false, and there are two output streams, one
+ * for normal data ({@link Process#getOutputStream()}) and one for error data
+ * ({@link Process#getErrorStream()}). When set to true, the two are merged,
+ * which simplifies the interleaving of the two streams. Data is read using
+ * the stream returned by {@link Process#getOutputStream()}, and the
+ * stream returned by {@link Process#getErrorStream()} throws an immediate
+ * end-of-file exception.</li>
+ * </ul>
+ * <p>
+ * All checks on attribute validity are delayed until <code>start()</code>
+ * is called. <code>ProcessBuilder</code> objects are <strong>not
+ * synchronized</strong>; the user must provide external synchronization
+ * where multiple threads may interact with the same
+ * <code>ProcessBuilder</code> object.
+ * </p>
+ *
+ * @author Tom Tromey (tr...@re...)
+ * @author Andrew John Hughes (gnu...@me...)
+ * @see Process
+ * @see System#getenv()
+ * @since 1.5
+ */
+public final class ProcessBuilder
+{
+
+ /**
+ * The working directory of the process.
+ */
+ private File directory = new File(System.getProperty("user.dir"));
+
+ /**
+ * The command line syntax for invoking the process.
+ */
+ private List<String> command;
+
+ /**
+ * The mapping of environment variables to values.
+ */
+ private Map<String, String> environment =
+ new System.EnvironmentMap(System.getenv());
+
+ /**
+ * A flag indicating whether to redirect the error stream to standard
+ * output.
+ */
+ private boolean redirect = false;
+
+ /**
+ * Constructs a new <code>ProcessBuilder</code> with the specified
+ * command being used to invoke the process. The list is used directly;
+ * external changes are reflected in the <code>ProcessBuilder</code>.
+ *
+ * @param command the name of the program followed by its arguments.
+ */
+ public ProcessBuilder(List<String> command)
+ {
+ this.command = command;
+ }
+
+ /**
+ * Constructs a new <code>ProcessBuilder</code> with the specified
+ * command being used to invoke the process. This constructor
+ * simplifies creating a new <code>ProcessBuilder</code> by
+ * converting the provided series of constructor arguments into a
+ * list of command-line arguments.
+ *
+ * @param command the name of the program followed by its arguments.
+ */
+ public ProcessBuilder(String... command)
+ {
+ this.command = Arrays.asList(command);
+ }
+
+ /**
+ * Returns the current command line, used to invoke the process.
+ * The return value is simply a reference to the list of command
+ * line arguments used by the <code>ProcessBuilder</code> object;
+ * any changes made to it will be reflected in the operation of
+ * the <code>ProcessBuilder</code>.
+ *
+ * @return the list of command-line arguments.
+ */
+ public List<String> command()
+ {
+ return command;
+ }
+
+ /**
+ * Sets the command-line arguments to those specified. The list is
+ * used directly; external changes are reflected in the
+ * <code>ProcessBuilder</code>.
+ *
+ * @param command the name of the program followed by its arguments.
+ * @return a reference to this process builder.
+ */
+ public ProcessBuilder command(List<String> command)
+ {
+ this.command = command;
+ return this;
+ }
+
+ /**
+ * Sets the command-line arguments to those specified.
+ * This simplifies modifying the arguments by converting
+ * the provided series of constructor arguments into a
+ * list of command-line arguments.
+ *
+ * @param command the name of the program followed by its arguments.
+ * @return a reference to this process builder.
+ */
+ public ProcessBuilder command(String... command)
+ {
+ this.command = Arrays.asList(command);
+ return this;
+ }
+
+ /**
+ * Returns the working directory of the process. The
+ * returned value may be <code>null</code>; this
+ * indicates that the default behaviour of using the
+ * working directory of the current process should
+ * be adopted.
+ *
+ * @return the working directory.
+ */
+ public File directory()
+ {
+ return directory;
+ }
+
+ /**
+ * Sets the working directory to that specified.
+ * The supplied argument may be <code>null</code>,
+ * which indicates the default value should be used.
+ * The default is the working directory of the current
+ * process.
+ *
+ * @param directory the new working directory.
+ * @return a reference to this process builder.
+ */
+ public ProcessBuilder directory(File directory)
+ {
+ this.directory = directory;
+ return this;
+ }
+
+ /**
+ * <p>
+ * Returns the system environment variables of the process.
+ * If the underlying system does not support environment variables,
+ * an empty map is returned.
+ * </p>
+ * <p>
+ * The returned map does not accept queries using
+ * null keys or values, or those of a type other than
+ * <code>String</code>. Attempts to pass in a null value will
+ * throw a <code>NullPointerException</code>. Types other than
+ * <code>String</code> throw a <code>ClassCastException</code>.
+ * </p>
+ * <p>
+ * As the returned map is generated using data from the underlying
+ * platform, it may not comply with the <code>equals()</code>
+ * and <code>hashCode()</code> contracts. It is also likely that
+ * the keys of this map will be case-sensitive.
+ * </p>
+ * <p>
+ * Modification of the map is reliant on the underlying platform;
+ * some may not allow any changes to the environment variables or
+ * may prevent certain values being used. Attempts to do so will
+ * throw an <code>UnsupportedOperationException</code> or
+ * <code>IllegalArgumentException</code>, respectively.
+ * </p>
+ * <p>
+ * Use of this method may require a security check for the
+ * RuntimePermission "getenv.*".
+ * </p>
+ *
+ * @return a map of the system environment variables for the process.
+ * @throws SecurityException if the checkPermission method of
+ * an installed security manager prevents access to
+ * the system environment variables.
+ * @since 1.5
+ */
+ public Map<String, String> environment()
+ {
+ return environment;
+ }
+
+ /**
+ * Returns true if the output stream and error stream of the
+ * process will be merged to form one composite stream. The
+ * default return value is <code>false</code>.
+ *
+ * @return true if the output stream and error stream are to
+ * be merged.
+ */
+ public boolean redirectErrorStream()
+ {
+ return redirect;
+ }
+
+ /**
+ * Sets the error stream redirection flag. If set, the output
+ * and error streams are merged to form one composite stream.
+ *
+ * @param redirect the new value of the redirection flag.
+ * @return a reference to this process builder.
+ */
+ public ProcessBuilder redirectErrorStream(boolean redirect)
+ {
+ this.redirect = redirect;
+ return this;
+ }
+
+ /**
+ * <p>
+ * Starts execution of a new process, based on the attributes of
+ * this <code>ProcessBuilder</code> object. This is the point
+ * at which the command-line arguments are checked. The list
+ * must be non-empty and contain only non-null string objects.
+ * The other attributes have default values which are used in
+ * cases where their values are not explicitly specified.
+ * </p>
+ * <p>
+ * If a security manager is in place, then the
+ * {@link SecurityManager#checkExec()} method is called to
+ * ensure that permission is given to execute the process.
+ * </p>
+ * <p>
+ * The execution of the process is system-dependent. Various
+ * exceptions may result, due to problems at the operating system
+ * level. These are all returned as a form of {@link IOException}.
+ * </p>
+ *
+ * @return a <code>Process</code> object, representing the spawned
+ * subprocess.
+ * @throws IOException if a problem occurs with executing the process
+ * at the operating system level.
+ * @throws IndexOutOfBoundsException if the command to execute is
+ * actually an empty list.
+ * @throws NullPointerException if the command to execute is null
+ * or the list contains null elements.
+ * @throws SecurityException if a security manager exists and prevents
+ * execution of the subprocess.
+ */
+ public Process start() throws IOException
+ {
+ SecurityManager sm = SecurityManager.current; // Be thread-safe!
+ if (sm != null)
+ sm.checkExec(command.get(0));
+ return VMProcess.exec(command, environment, directory, redirect);
+ }
+}
Modified: trunk/core/src/classpath/java/java/lang/System.java
===================================================================
--- trunk/core/src/classpath/java/java/lang/System.java 2007-01-07 12:51:25 UTC (rev 3021)
+++ trunk/core/src/classpath/java/java/lang/System.java 2007-01-07 12:53:02 UTC (rev 3022)
@@ -149,7 +149,6 @@
SecurityManager sm = SecurityManager.current; // Be thread-safe.
if (sm != null)
sm.checkPermission(new RuntimePermission("setIO"));
-
VMSystem.setOut(out);
}
@@ -263,9 +262,7 @@
*/
public static long nanoTime()
{
- //todo
- throw new RuntimeException("Implement it");
- //return VMSystem.nanoTime();
+ return VMSystem.nanoTime();
}
/**
@@ -464,6 +461,29 @@
}
/**
+ * Remove a single system property by name. A security check may be
+ * performed, <code>checkPropertyAccess(key, "write")</code>.
+ *
+ * @param key the name of the system property to remove
+ * @return the previous value, or null
+ * @throws SecurityException if permission is denied
+ * @throws NullPointerException if key is null
+ * @throws IllegalArgumentException if key is ""
+ * @since 1.5
+ */
+ public static String clearProperty(String key)
+ {
+ SecurityManager sm = SecurityManager.current; // Be thread-safe.
+ if (sm != null)
+ sm.checkPermission(new PropertyPermission(key, "write"));
+ // This handles both the null pointer exception and the illegal
+ // argument exception.
+ if (key.length() == 0)
+ throw new IllegalArgumentException("key can't be empty");
+ return SystemProperties.remove(key);
+ }
+
+ /**
* Gets the value of an environment variable.
*
* @param name the name of the environment variable
@@ -486,6 +506,60 @@
}
/**
+ * <p>
+ * Returns an unmodifiable view of the system environment variables.
+ * If the underlying system does not support environment variables,
+ * an empty map is returned.
+ * </p>
+ * <p>
+ * The returned map is read-only and does not accept queries using
+ * null keys or values, or those of a type other than <code>String</code>.
+ * Attempts to modify the map will throw an
+ * <code>UnsupportedOperationException</code>, while attempts
+ * to pass in a null value will throw a
+ * <code>NullPointerException</code>. Types other than <code>String</code>
+ * throw a <code>ClassCastException</code>.
+ * </p>
+ * <p>
+ * As the returned map is generated using data from the underlying
+ * platform, it may not comply with the <code>equals()</code>
+ * and <code>hashCode()</code> contracts. It is also likely that
+ * the keys of this map will be case-sensitive.
+ * </p>
+ * <p>
+ * Use of this method may require a security check for the
+ * RuntimePermission "getenv.*".
+ * </p>
+ *
+ * @return a map of the system environment variables.
+ * @throws SecurityException if the checkPermission method of
+ * an installed security manager prevents access to
+ * the system environment variables.
+ * @since 1.5
+ */
+ public static Map<String, String> getenv()
+ {
+ SecurityManager sm = SecurityManager.current; // Be thread-safe.
+ if (sm != null)
+ sm.checkPermission(new RuntimePermission("getenv.*"));
+ if (environmentMap == null)
+ {
+ List<String> environ = (List<String>)VMSystem.environ();
+ Map<String,String> variables = new EnvironmentMap();
+ for (String pair : environ)
+ {
+ String[] parts = pair.split("=");
+ if (parts.length == 2)
+ variables.put(parts[0], parts[1]);
+ else
+ variables.put(parts[0], "");
+ }
+ environmentMap = Collections.unmodifiableMap(variables);
+ }
+ return environmentMap;
+ }
+
+ /**
* Terminate the Virtual Machine. This just calls
* <code>Runtime.getRuntime().exit(status)</code>, and never returns.
* Obviously, a security check is in order, <code>checkExit</code>.
@@ -597,4 +671,419 @@
return VMRuntime.mapLibraryName(libname);
}
+
+ /**
+ * This is a specialised <code>Collection</code>, providing
+ * the necessary provisions for the collections used by the
+ * environment variable map. Namely, it prevents
+ * querying anything but <code>String</code>s.
+ *
+ * @author Andrew John Hughes (gnu...@me...)
+ */
+ private static class EnvironmentCollection
+ extends AbstractCollection<String>
+ {
+
+ /**
+ * The wrapped collection.
+ */
+ protected Collection<String> c;
+
+ /**
+ * Constructs a new environment collection, which
+ * wraps the elements of the supplied collection.
+ *
+ * @param coll the collection to use as a base for
+ * this collection.
+ */
+ public EnvironmentCollection(Collection<String> coll)
+ {
+ c = coll;
+ }
+
+ /**
+ * Blocks queries containing a null object or an object which
+ * isn't of type <code>String</code>. All other queries
+ * are forwarded to the underlying collection.
+ *
+ * @param obj the object to look for.
+ * @return true if the object exists in the collection.
+ * @throws NullPointerException if the specified object is null.
+ * @throws ClassCastException if the specified object is not a String.
+ */
+ public boolean contains(Object obj)
+ {
+ if (obj == null)
+ throw new
+ NullPointerException("This collection does not support " +
+ "null values.");
+ if (!(obj instanceof String))
+ throw new
+ ClassCastException("This collection only supports Strings.");
+ return c.contains(obj);
+ }
+
+ /**
+ * Blocks queries where the collection contains a null object or
+ * an object which isn't of type <code>String</code>. All other
+ * queries are forwarded to the underlying collection.
+ *
+ * @param coll the collection of objects to look for.
+ * @return true if the collection contains all elements in the collection.
+ * @throws NullPointerException if the collection is null.
+ * @throws NullPointerException if any collection entry is null.
+ * @throws ClassCastException if any collection entry is not a String.
+ */
+ public boolean containsAll(Collection<?> coll)
+ {
+ for (Object o: coll)
+ {
+ if (o == null)
+ throw new
+ NullPointerException("This collection does not support " +
+ "null values.");
+ if (!(o instanceof String))
+ throw new
+ ClassCastException("This collection only supports Strings.");
+ }
+ return c.containsAll(coll);
+ }
+
+ /**
+ * This returns an iterator over the map elements, with the
+ * same provisions as for the collection and underlying map.
+ *
+ * @return an iterator over the map elements.
+ */
+ public Iterator<String> iterator()
+ {
+ return c.iterator();
+ }
+
+ /**
+ * Blocks the removal of elements from the collection.
+ *
+ * @return true if the removal was sucessful.
+ * @throws NullPointerException if the collection is null.
+ * @throws NullPointerException if any collection entry is null.
+ * @throws ClassCastException if any collection entry is not a String.
+ */
+ public boolean remove(Object key)
+ {
+ if (key == null)
+ throw new
+ NullPointerException("This collection does not support " +
+ "null values.");
+ if (!(key instanceof String))
+ throw new
+ ClassCastException("This collection only supports Strings.");
+ return c.contains(key);
+ }
+
+ /**
+ * Blocks the removal of all elements in the specified
+ * collection from the collection.
+ *
+ * @param coll the collection of elements to remove.
+ * @return true if the elements were removed.
+ * @throws NullPointerException if the collection is null.
+ * @throws NullPointerException if any collection entry is null.
+ * @throws ClassCastException if any collection entry is not a String.
+ */
+ public boolean removeAll(Collection<?> coll)
+ {
+ for (Object o: coll)
+ {
+ if (o == null)
+ throw new
+ NullPointerException("This collection does not support " +
+ "null values.");
+ if (!(o instanceof String))
+ throw new
+ ClassCastException("This collection only supports Strings.");
+ }
+ return c.removeAll(coll);
+ }
+
+ /**
+ * Blocks the retention of all elements in the specified
+ * collection from the collection.
+ *
+ * @param c the collection of elements to retain.
+ * @return true if the other elements were removed.
+ * @throws NullPointerException if the collection is null.
+ * @throws NullPointerException if any collection entry is null.
+ * @throws ClassCastException if any collection entry is not a String.
+ */
+ public boolean retainAll(Collection<?> coll)
+ {
+ for (Object o: coll)
+ {
+ if (o == null)
+ throw new
+ NullPointerException("This collection does not support " +
+ "null values.");
+ if (!(o instanceof String))
+ throw new
+ ClassCastException("This collection only supports Strings.");
+ }
+ return c.containsAll(coll);
+ }
+
+ /**
+ * This simply calls the same method on the wrapped
+ * collection.
+ *
+ * @return the size of the underlying collection.
+ */
+ public int size()
+ {
+ return c.size();
+ }
+
+ } // class EnvironmentCollection<String>
+
+ /**
+ * This is a specialised <code>HashMap</code>, which
+ * prevents the addition or querying of anything other than
+ * <code>String</code> objects.
+ *
+ * @author Andrew John Hughes (gnu...@me...)
+ */
+ static class EnvironmentMap
+ extends HashMap<String,String>
+ {
+
+ /**
+ * Cache the entry set.
+ */
+ private transient Set<Map.Entry<String,String>> entries;
+
+ /**
+ * Cache the key set.
+ */
+ private transient Set<String> keys;
+
+ /**
+ * Cache the value collection.
+ */
+ private transient Collection<String> values;
+
+ /**
+ * Constructs a new empty <code>EnvironmentMap</code>.
+ */
+ EnvironmentMap()
+ {
+ super();
+ }
+
+ /**
+ * Constructs a new <code>EnvironmentMap</code> containing
+ * the contents of the specified map.
+ *
+ * @param m the map to be added to this.
+ * @throws NullPointerException if a key or value is null.
+ * @throws ClassCastException if a key or value is not a String.
+ */
+ EnvironmentMap(Map<String,String> m)
+ {
+ super(m);
+ }
+
+ /**
+ * Blocks queries containing a null key or one which is not
+ * of type <code>String</code>. All other queries
+ * are forwarded to the superclass.
+ *
+ * @param key the key to look for in the map.
+ * @return true if the key exists in the map.
+ * @throws NullPointerException if the specified key is null.
+ */
+ public boolean containsKey(Object key)
+ {
+ if (key == null)
+ throw new
+ NullPointerException("This map does not support null keys.");
+ if (!(key instanceof String))
+ throw new
+ ClassCastException("This map only allows queries using Strings.");
+ return super.containsKey(key);
+ }
+
+ /**
+ * Blocks queries using a null or non-<code>String</code> value.
+ * All other queries are forwarded to the superclass.
+ *
+ * @param value the value to look for in the map.
+ * @return true if the value exists in the map.
+ * @throws NullPointerException if the specified value is null.
+ */
+ public boolean containsValue(Object value)
+ {
+ if (value == null)
+ throw new
+ NullPointerException("This map does not support null values.");
+ if (!(value instanceof String))
+ throw new
+ ClassCastException("This map only allows queries using Strings.");
+ return super.containsValue(value);
+ }
+
+ /**
+ * Returns a set view of the map entries, with the same
+ * provisions as for the underlying map.
+ *
+ * @return a set containing the map entries.
+ */
+ public Set<Map.Entry<String,String>> entrySet()
+ {
+ if (entries == null)
+ entries = super.entrySet();
+ return entries;
+ }
+
+ /**
+ * Blocks queries containing a null or non-<code>String</code> key.
+ * All other queries are passed on to the superclass.
+ *
+ * @param key the key to retrieve the value for.
+ * @return the value associated with the given key.
+ * @throws NullPointerException if the specified key is null.
+ * @throws ClassCastException if the specified key is not a String.
+ */
+ public String get(Object key)
+ {
+ if (key == null)
+ throw new
+ NullPointerException("This map does not support null keys.");
+ if (!(key instanceof String))
+ throw new
+ ClassCastException("This map only allows queries using Strings.");
+ return super.get(key);
+ }
+
+ /**
+ * Returns a set view of the keys, with the same
+ * provisions as for the underlying map.
+ *
+ * @return a set containing the keys.
+ */
+ public Set<String> keySet()
+ {
+ if (keys == null)
+ keys = new EnvironmentSet(super.keySet());
+ return keys;
+ }
+
+ /**
+ * Associates the given key to the given value. If the
+ * map already contains the key, its value is replaced.
+ * The map does not accept null keys or values, or keys
+ * and values not of type {@link String}.
+ *
+ * @param key the key to map.
+ * @param value the value to be mapped.
+ * @return the previous value of the key, or null if there was no mapping
+ * @throws NullPointerException if a key or value is null.
+ * @throws ClassCastException if a key or value is not a String.
+ */
+ public String put(String key, String value)
+ {
+ if (key == null)
+ throw new NullPointerException("A new key is null.");
+ if (value == null)
+ throw new NullPointerException("A new value is null.");
+ if (!(key instanceof String))
+ throw new ClassCastException("A new key is not a String.");
+ if (!(value instanceof String))
+ throw new ClassCastException("A new value is not a String.");
+ return super.put(key, value);
+ }
+
+ /**
+ * Removes a key-value pair from the map. The queried key may not
+ * be null or of a type other than a <code>String</code>.
+ *
+ * @param key the key of the entry to remove.
+ * @return the removed value.
+ * @throws NullPointerException if the specified key is null.
+ * @throws ClassCastException if the specified key is not a String.
+ */
+ public String remove(Object key)
+ {
+ if (key == null)
+ throw new
+ NullPointerException("This map does not support null keys.");
+ if (!(key instanceof String))
+ throw new
+ ClassCastException("This map only allows queries using Strings.");
+ return super.remove(key);
+ }
+
+ /**
+ * Returns a collection view of the values, with the same
+ * provisions as for the underlying map.
+ *
+ * @return a collection containing the values.
+ */
+ public Collection<String> values()
+ {
+ if (values == null)
+ values = new EnvironmentCollection(super.values());
+ return values;
+ }
+
+ }
+
+ /**
+ * This is a specialised <code>Set</code>, providing
+ * the necessary provisions for the collections used by the
+ * environment variable map. Namely, it prevents
+ * modifications and the use of queries with null
+ * or non-<code>String</code> values.
+ *
+ * @author Andrew John Hughes (gnu...@me...)
+ */
+ private static class EnvironmentSet
+ extends EnvironmentCollection
+ implements Set<String>
+ {
+
+ /**
+ * Constructs a new environment set, which
+ * wraps the elements of the supplied set.
+ *
+ * @param set the set to use as a base for
+ * this set.
+ */
+ public EnvironmentSet(Set<String> set)
+ {
+ super(set);
+ }
+
+ /**
+ * This simply calls the same method on the wrapped
+ * collection.
+ *
+ * @param obj the object to compare with.
+ * @return true if the two objects are equal.
+ */
+ public boolean equals(Object obj)
+ {
+ return c.equals(obj);
+ }
+
+ /**
+ * This simply calls the same method on the wrapped
+ * collection.
+ *
+ * @return the hashcode of the collection.
+ */
+ public int hashCode()
+ {
+ return c.hashCode();
+ }
+
+ } // class EnvironmentSet<String>
+
} // class System
Added: trunk/core/src/classpath/java/java/lang/management/LockInfo.java
===================================================================
--- trunk/core/src/classpath/java/java/lang/management/LockInfo.java (rev 0)
+++ trunk/core/src/classpath/java/java/lang/management/LockInfo.java 2007-01-07 12:53:02 UTC (rev 3022)
@@ -0,0 +1,114 @@
+/* LockInfo.java - Information on a lock.
+ Copyright (C) 2006 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.lang.management;
+
+import java.beans.ConstructorProperties;
+
+/**
+ * Provides information on a lock held by a thread.
+ * A lock can be either a built-in monitor, an
+ * <emph>ownable synchronizer</emph> (i.e. a subclass
+ * of {@link java.util.concurrent.locks.AbstractOwnableSynchronizer}),
+ * or a {@link java.util.concurrent.locks.Condition}
+ * object.
+ *
+ * @author Andrew John Hughes (gnu...@me...)
+ * @since 1.6
+ */
+public class LockInfo
+{
+
+ /**
+ * The class name of the lock object.
+ */
+ private String className;
+
+ /**
+ * The identity hash code of the lock object.
+ */
+ private int identityHashCode;
+
+ /**
+ * Constructs a new {@link LockInfo} object with the
+ * specified class name and identity hash code.
+ *
+ * @param className the name of the class of the lock object.
+ * @param identityHashCode the identity hash code of the
+ * lock object.
+ */
+ @ConstructorProperties({"className","identityHashCode"})
+ public LockInfo(String className, int identityHashCode)
+ {
+ this.className = className;
+ this.identityHashCode = identityHashCode;
+ }
+
+ /**
+ * Returns the class name of the lock object.
+ *
+ * @return the class name of the lock object.
+ */
+ public String getClassName()
+ {
+ return className;
+ }
+
+ /**
+ * Returns the identity hash code of the lock object.
+ *
+ * @return the identity hash code of the lock object.
+ */
+ public int getIdentityHashCode()
+ {
+ return identityHashCode;
+ }
+
+ /**
+ * Returns a textual representation of the lock,
+ * constructed by concatenating the class name,
+ * <code>'@'</code> and the identity hash code
+ * in unsigned hexadecimal form.
+ *
+ * @return a textual representation of the lock.
+ */
+ public String toString()
+ {
+ return className + '@' + Integer.toHexString(identityHashCode);
+ }
+
+}
Modified: trunk/core/src/classpath/java/java/lang/management/ManagementFactory.java
===================================================================
--- trunk/core/src/classpath/java/java/lang/management/ManagementFactory.java 2007-01-07 12:51:25 UTC (rev 3021)
+++ trunk/core/src/classpath/java/java/lang/management/ManagementFactory.java 2007-01-07 12:53:02 UTC (rev 3022)
@@ -49,11 +49,36 @@
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
@@ -66,6 +91,11 @@
* <ol>
* <li>Calling the appropriate static method of this factory.
* </li>
+ * <li>Using the platform {@link javax.management.MBeanServer}
+ * to access the beans locally, or an
+ * {@link javax.management.MBeanServerConnection} for remote
+ * access. The attributes and operations use the limited
+ * range of data types specified below.</li>
* </ol>
* <h2>Open Data Types</h2>
* <p>
@@ -118,6 +148,60 @@
{
/**
+ * The object name for the class loading bean.
+ */
+ public static final String CLASS_LOADING_MXBEAN_NAME =
+ "java.lang:type=ClassLoading";
+
+ /**
+ * The object name for the compilation bean.
+ */
+ public static final String COMPILATION_MXBEAN_NAME =
+ "java.lang:type=Compilation";
+
+ /**
+ * The domain for the garbage collecting beans.
+ */
+ public static final String GARBAGE_COLLECTOR_MXBEAN_DOMAIN_TYPE =
+ "java.lang:type=GarbageCollector";
+
+ /**
+ * The domain for the memory manager beans.
+ */
+ public static final String MEMORY_MANAGER_MXBEAN_DOMAIN_TYPE =
+ "java.lang:type=MemoryManager";
+
+ /**
+ * The object name for the memory bean.
+ */
+ public static final String MEMORY_MXBEAN_NAME =
+ "java.lang:type=Memory";
+
+ /**
+ * The domain for the memory pool beans.
+ */
+ public static final String MEMORY_POOL_MXBEAN_DOMAIN_TYPE =
+ "java.lang:type=MemoryPool";
+
+ /**
+ * The object name for the operating system bean.
+ */
+ public static final String OPERATING_SYSTEM_MXBEAN_NAME =
+ "java.lang:type=OperatingSystem";
+
+ /**
+ * The object name for the runtime bean.
+ */
+ public static final String RUNTIME_MXBEAN_NAME =
+ "java.lang:type=Runtime";
+
+ /**
+ * The object name for the threading bean.
+ */
+ public static final String THREAD_MXBEAN_NAME =
+ "java.lang:type=Threading";
+
+ /**
* The operating system management bean.
*/
private static OperatingSystemMXBean osBean;
@@ -148,6 +232,11 @@
private static CompilationMXBean compilationBean;
/**
+ * The platform server.
+ */
+ private static MBeanServer platformServer;
+
+ /**
* Private constructor to prevent instance creation.
*/
private ManagementFactory() {}
@@ -301,9 +390,10 @@
*
* @return a list of memory pool beans, one for each pool.
*/
- public static List getMemoryPoolMXBeans()
+ public static List<MemoryPoolMXBean> getMemoryPoolMXBeans()
{
- List poolBeans = new ArrayList();
+ List<MemoryPoolMXBean> poolBeans =
+ new ArrayList<MemoryPoolMXBean>();
String[] names = VMManagementFactory.getMemoryPoolNames();
for (int a = 0; a < names.length; ++a)
try
@@ -326,9 +416,10 @@
*
* @return a list of memory manager beans, one for each manager.
*/
- public static List getMemoryManagerMXBeans()
+ public static List<MemoryManagerMXBean> getMemoryManagerMXBeans()
{
- List managerBeans = new ArrayList();
+ List<MemoryManagerMXBean> managerBeans =
+ new ArrayList<MemoryManagerMXBean>();
String[] names = VMManagementFactory.getMemoryManagerNames();
for (int a = 0; a < names.length; ++a)
try
@@ -352,9 +443,10 @@
*
* @return a list of garbage collector beans, one for each pool.
*/
- public static List getGarbageCollectorMXBeans()
+ public static List<GarbageCollectorMXBean> getGarbageCollectorMXBeans()
{
- List gcBeans = new ArrayList();
+ List<GarbageCollectorMXBean> gcBeans =
+ new ArrayList<GarbageCollectorMXBean>();
String[] names = VMManagementFactory.getGarbageCollectorNames();
for (int a = 0; a < names.length; ++a)
try
@@ -371,4 +463,355 @@
return gcBeans;
}
+ /**
+ * <p>
+ * Returns the platform {@link javax.management.MBeanServer}. On the
+ * first call to this method, a server instance is retrieved from
+ * the {@link javax.management.MBeanServerFactory} and each of the
+ * beans are registered with it. Subsequent calls return the existing
+ * instance. If the property <code>javax.management.builder.initial</code>
+ * is set, its value will be used as the name of the class which is used
+ * to provide the server instance.
+ * </p>
+ * <p>
+ * It is recommended that the platform server is used for other beans as
+ * well, in order to simplify their discovery and publication. Name conflicts
+ * should be avoided.
+ * </p>
+ *
+ * @return the platform {@link javax.management.MBeanServer}
+ * @throws SecurityException if a security manager exists and the
+ * caller's permissions don't imply {@link
+ * MBeanServerPermission(String)}("createMBeanServer")
+ * @see javax.management.MBeanServerFactory
+ * @see javax.management.MBeanServerFactory#createMBeanServer()
+ */
+ public static MBeanServer getPlatformMBeanServer()
+ {
+ if (platformServer == null)
+ {
+ platformServer = MBeanServerFactory.createMBeanServer();
+ try
+ {
+ platformServer.registerMBean(getOperatingSystemMXBean(),
+ new ObjectName(OPERATING_SYSTEM_MXBEAN_NAME));
+ platformServer.registerMBean(getRuntimeMXBean(),
+ new ObjectName(RUNTIME_MXBEAN_NAME));
+ platformServer.registerMBean(getClassLoadingMXBean(),
+ new ObjectName(CLASS_LOADING_MXBEAN_NAME));
+ platformServer.registerMBean(getThreadMXBean(),
+ new ObjectName(THREAD_MXBEAN_NAME));
+ platformServer.registerMBean(getMemoryMXBean(),
+ new ObjectName(MEMORY_MXBEAN_NAME));
+ CompilationMXBean compBean = getCompilationMXBean();
+ if (compBean != null)
+ platformServer.registerMBean(compBean,
+ new ObjectName(COMPILATION_MXBEAN_NAME));
+ Iterator beans = getMemoryPoolMXBeans().iterator();
+ while (beans.hasNext())
+ {
+ MemoryPoolMXBean bean = (MemoryPoolMXBean) beans.next();
+ platformServer.registerMBean(bean,
+ new ObjectName(MEMORY_POOL_MXBEAN_DOMAIN_TYPE +
+ ",name=" +
+ bean.getName()));
+ }
+ beans = getMemoryManagerMXBeans().iterator();
+ while (beans.hasNext())
+ {
+ MemoryManagerMXBean bean = (MemoryManagerMXBean) beans.next();
+ platformServer.registerMBean(bean,
+ new ObjectName(MEMORY_MANAGER_MXBEAN_DOMAIN_TYPE +
+ ",name=" +
+ bean.getName()));
+ }
+ beans = getGarbageCollectorMXBeans().iterator();
+ while (beans.hasNext())
+ {
+ GarbageCollectorMXBean bean = (GarbageCollectorMXBean) beans.next();
+ platformServer.registerMBean(bean,
+ new ObjectName(GARBAGE_COLLECTOR_MXBEAN_DOMAIN_TYPE +
+ ",name=" +
+ bean.getName()));
+ }
+ platformServer.registerMBean(LogManager.getLoggingMXBean(),
+ new ObjectName(LogManager.LOGGING_MXBEAN_NAME));
+ }
+ catch (InstanceAlreadyExistsException e)
+ {
+ throw (Error)
+ (new InternalError("One of the management beans is " +
+ "already registered.").initCause(e));
+ }
+ catch (MBeanRegistrationException e)
+ {
+ throw (Error)
+ (new InternalError("One of the management beans' preRegister " +
+ "methods threw an exception.").initCause(e));
+ }
+ catch (NotCompliantMBeanException e)
+ {
+ throw (Error)
+ (new InternalError("One of the management beans is " +
+ "not compliant.").initCause(e));
+ }
+ catch (MalformedObjectNameException e)
+ {
+ throw (Error)
+ (new InternalError("The object name of a management bean is " +
+ "not compliant.").initCause(e));
+ }
+ }
+ 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...@me...)
+ * @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;
+ }
+
+ }
}
Modified: trunk/core/src/classpath/java/java/lang/management/MemoryPoolMXBean.java
===================================================================
--- trunk/core/src/classpath/java/java/lang/management/MemoryPoolMXBean.java 2007-01-07 12:51:25 UTC (rev 3021)
+++ trunk/core/src/classpath/java/java/lang/management/MemoryPoolMXBean.java 2007-01-07 12:53:02 UTC (rev 3022)
@@ -162,7 +162,7 @@
*
* @return the type of this pool.
*/
- String getType();
+ MemoryType getType();
/**
* Returns memory usage statistics for the current memory usage
Added: trunk/core/src/classpath/java/java/lang/management/MemoryType.java
===================================================================
--- trunk/core/src/classpath/java/java/lang/management/MemoryType.java (rev 0)
+++ trunk/core/src/classpath/java/java/lang/management/MemoryType.java 2007-01-07 12:53:02 UTC (rev 3022)
@@ -0,0 +1,51 @@
+/* MemoryType.java - Enumeration of the types of memory pools.
+ Copyright (C) 2006 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.lang.management;
+
+/**
+ * Enumerates the possible types of memory pools. A value of this
+ * type is returned by {@link MemoryPoolMXBean#getMemoryType()}.
+ *
+ * @author Andrew John Hughes (gnu...@me...)
+ * @since 1.5
+ */
+public enum MemoryType
+{
+ HEAP, NON_HEAP;
+}
+
Modified: trunk/core/src/classpath/java/java/lang/management/MemoryUsage.java
===================================================================
--- trunk/core/src/classpath/java/java/lang/management/MemoryUsage.java 2007-01-07 12:51:25 UTC (rev 3021)
+++ trunk/core/src/classpath/java/java/lang/management/MemoryUsage.java 2007-01-07 12:53:02 UTC (rev 3022)
@@ -180,14 +180,14 @@
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")).longVa...
[truncated message content] |