diff options
author | Matthias Klose <doko@gcc.gnu.org> | 2007-06-03 23:18:43 +0000 |
---|---|---|
committer | Matthias Klose <doko@gcc.gnu.org> | 2007-06-03 23:18:43 +0000 |
commit | e1bea0c0687c5f4551b3a6058ec37ce3705fa6cc (patch) | |
tree | a9c9e7d91c484d53fe154f9285fc57325572ce50 /libjava/classpath/javax/management | |
parent | af333b9a7f9e1cc1029bec56d48f2de63acdf686 (diff) | |
download | gcc-e1bea0c0687c5f4551b3a6058ec37ce3705fa6cc.zip gcc-e1bea0c0687c5f4551b3a6058ec37ce3705fa6cc.tar.gz gcc-e1bea0c0687c5f4551b3a6058ec37ce3705fa6cc.tar.bz2 |
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
Diffstat (limited to 'libjava/classpath/javax/management')
36 files changed, 5735 insertions, 209 deletions
diff --git a/libjava/classpath/javax/management/AttributeChangeNotification.java b/libjava/classpath/javax/management/AttributeChangeNotification.java new file mode 100644 index 0000000..e63671d --- /dev/null +++ b/libjava/classpath/javax/management/AttributeChangeNotification.java @@ -0,0 +1,166 @@ +/* AttributeChangeNotification.java -- Notification for attribute changes + Copyright (C) 2007 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 javax.management; + +/** + * Defines the notification used to let listeners know of + * an attribute change. The bean itself is responsible + * for creating and transmitting the notification when the + * attribute changes, by implementing + * {@link NotificationBroadcaster}. For example, if a + * bean increments the integer, <code>count</code>, it + * should send a notification with the + * <code>attributeName</code>, <code>"count"</code>, + * the <code>attributeType</code>, <code>"Integer"</code> + * and the old and new values of the attribute. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public class AttributeChangeNotification + extends Notification +{ + + /** + * Compatible with JDK 1.5 + */ + private static final long serialVersionUID = 535176054565814134L; + + /** + * The attribute type for attribute change + * notifications. + */ + public static final String ATTRIBUTE_CHANGE = "jmx.attribute.change"; + + /** + * The name of the attribute that changed. + */ + private String attributeName; + + /** + * The type of the attribute that changed. + */ + private String attributeType; + + /** + * The old value of the attribute. + */ + private Object oldValue; + + /** + * The new value of the attribute. + */ + private Object newValue; + + /** + * Constructs a new {@link AttributeChangeNotification} + * with the specified source, sequence number, timestamp, + * message, and the attribute name, type, old value and + * new value. + * + * @param source the producer of the notification, which + * is usually the bean that changed the + * attribute. + * @param sequenceNumber the sequence number of the + * notification. + * @param timeStamp the date and time of the notification. + * @param msg the message content of the notification. + * @param name the name of the attribute. + * @param type the type of the attribute. + * @param oldVal the old value of the attribute. + * @param newVal the new value of the attribute. + */ + public AttributeChangeNotification(Object source, + long sequenceNumber, + long timeStamp, + String msg, String name, + String type, Object oldVal, + Object newVal) + { + super(ATTRIBUTE_CHANGE, source, sequenceNumber, + timeStamp, msg); + attributeName = name; + attributeType = type; + oldValue = oldVal; + newValue = newVal; + } + + /** + * Returns the name of the attribute that changed. + * + * @return the name of the attribute. + */ + public String getAttributeName() + { + return attributeName; + } + + /** + * Returns the type of the attribute that changed. + * + * @return the type of the attribute. + */ + public String getAttributeType() + { + return attributeType; + } + + /** + * Returns the old value of the attribute. + * + * @return the old value. + */ + public Object getOldValue() + { + return oldValue; + } + + /** + * Returns the new value of the attribute. + * + * @return the new value. + */ + public Object getNewValue() + { + return newValue; + } + +} + + diff --git a/libjava/classpath/javax/management/AttributeChangeNotificationFilter.java b/libjava/classpath/javax/management/AttributeChangeNotificationFilter.java new file mode 100644 index 0000000..90d19a3 --- /dev/null +++ b/libjava/classpath/javax/management/AttributeChangeNotificationFilter.java @@ -0,0 +1,137 @@ +/* AttributeChangeNotificationFilter.java -- Filter on attribute name + Copyright (C) 2007 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 javax.management; + +import java.io.Serializable; + +import java.util.Vector; + +/** + * Performs filtering of {@link AttributeChangeNotification}s + * based on a list of attribute names. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public class AttributeChangeNotificationFilter + implements NotificationFilter, Serializable +{ + + /** + * Compatible with JDK 1.5 + */ + private static final long serialVersionUID = -6347317584796410029L; + + /** + * Lists the names of the attributes that may pass + * through the filter. + */ + private final Vector<String> enabledAttributes = new Vector<String>(); + + /** + * Blocks all {@link AttributeChangeNotification}s + * by emptying the list of enabled attributes. + */ + public void disableAllAttributes() + { + enabledAttributes.clear(); + } + + /** + * Removes the specified attribute name from the list + * of enabled attributes, thus preventing + * {@link AttributeChangeNotification}s for this attribute + * from passing through the filter. If the attribute is + * not enabled, this has no effect. + * + * @param name the name of the attribute to disable. + */ + public void disableAttribute(String name) + { + enabledAttributes.remove(name); + } + + /** + * Adds the specified attribute name to the list + * of enabled attributes, thus allowing + * {@link AttributeChangeNotification}s for this attribute + * to pass through the filter. If the attribute is + * enabled, this has no effect. + * + * @param name the name of the attribute to enable. + */ + public void enableAttribute(String name) + { + if (!enabledAttributes.contains(name)) + enabledAttributes.add(name); + } + + /** + * Returns the list of enabled attributes for this + * filter. + * + * @return the list of enabled attributes. + */ + public Vector<String> getEnabledAttributes() + { + return enabledAttributes; + } + + /** + * Returns true if the specified notification is an + * {@link AttributeChangeNotification} and the name of the + * attribute concerned is in the list of enabled attributes + * for this filter. + * + * @param notif the notification being filtered. + * @return true if the notification is an + * {@link AttributeChangeNotification} for an + * enabled attribute. + */ + public boolean isNotificationEnabled(Notification notif) + { + if (notif instanceof AttributeChangeNotification) + { + AttributeChangeNotification n = + (AttributeChangeNotification) notif; + return enabledAttributes.contains(n.getAttributeName()); + } + return false; + } + +} diff --git a/libjava/classpath/javax/management/AttributeValueExp.java b/libjava/classpath/javax/management/AttributeValueExp.java new file mode 100644 index 0000000..42e7161 --- /dev/null +++ b/libjava/classpath/javax/management/AttributeValueExp.java @@ -0,0 +1,181 @@ +/* AttributeValueExp.java -- Represents attributes to be passed to queries. + Copyright (C) 2007 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 javax.management; + +/** + * Represents an attribute value being used as an argument + * to a relational constraint. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public class AttributeValueExp + implements ValueExp +{ + + /** + * Compatible with JDK 1.5 + */ + private static final long serialVersionUID = -7768025046539163385L; + + /** + * The name of the attribute. + */ + private String attr; + + /** + * Constructs a new {@link AttributeValueExp}. + * + * @deprecated An instance created with a <code>null</code> + * attribute name can not be used in a query. + */ + @Deprecated public AttributeValueExp() + { + } + + /** + * Constructs a new {@link AttributeValueExp} using the + * specified attribute. + * + * @param attr the name of the attribute whose value + * will be used for this expression. + */ + public AttributeValueExp(String attr) + { + this.attr = attr; + } + + /** + * Applies the {@link AttributeValueExp} to the specified + * management bean by obtaining the attribute value from + * the {@link MBeanServer} and using it to create a + * {@link StringValueExp}. + * + * @param name the {@link ObjectName} of the bean to obtain + * the value from. + * @return a {@link StringValueExp} containing the result. + * @throws BadStringOperationException if an invalid string + * operation is used by + * the value expression. + * @throws BadBinaryOpValueExpException if an invalid expression + * is used by the value expression. + * @throws BadAttributeValueExpException if an invalid attribute + * is used by the value expression. + * @throws InvalidApplicationException if the value expression is applied + * to the wrong type of bean. + */ + public ValueExp apply(ObjectName name) + throws BadStringOperationException, BadBinaryOpValueExpException, + BadAttributeValueExpException, InvalidApplicationException + { + Object val = getAttribute(name); + if (val == null || !(val instanceof String)) + throw new BadAttributeValueExpException(val); + return new StringValueExp((String) val); + } + + /** + * Returns the value of the attribute by calling the + * {@link MBeanServer#getAttribute(ObjectName)} method of + * the server returned by {@link QueryEval#getMBeanServer()}. + * If an exception occurs, <code>null</code> is returned. + * + * @param name the {@link ObjectName} of the bean to obtain + * the value from. + * @return a {@link StringValueExp} containing the result. + */ + protected Object getAttribute(ObjectName name) + { + try + { + return QueryEval.getMBeanServer().getAttribute(name, attr); + } + catch (NullPointerException e) + { + return null; + } + catch (MBeanException e) + { + return null; + } + catch (AttributeNotFoundException e) + { + return null; + } + catch (InstanceNotFoundException e) + { + return null; + } + catch (ReflectionException e) + { + return null; + } + } + + /** + * Returns the attribute name. + * + * @return the attribute name. + */ + public String getAttributeName() + { + return attr; + } + + /** + * Sets the {@link MBeanServer} on which the query + * will be performed. + * + * @param server the new server. + */ + public void setMBeanServer(MBeanServer server) + { + /* This seems to do nothing any more */ + } + + /** + * Returns the attribute name, quoted. + * + * @return the quoted attribute name. + */ + public String toString() + { + return "'" + attr + "'"; + } + +} diff --git a/libjava/classpath/javax/management/DefaultLoaderRepository.java b/libjava/classpath/javax/management/DefaultLoaderRepository.java new file mode 100644 index 0000000..b905af2 --- /dev/null +++ b/libjava/classpath/javax/management/DefaultLoaderRepository.java @@ -0,0 +1,148 @@ +/* DefaultLoaderRepository.java -- Manages class loaders for the servers. + Copyright (C) 2007 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 javax.management; + +import java.util.List; + +/** + * Maintains a list of the {@link ClassLoader} instances + * registered with the management servers, allowing it + * to be used to load classes. In early versions of the + * JMX API, this class represented a shared repository for + * the classloaders of all management servers. The management + * of classloaders is now decentralised and this class is + * deprecated. The old behaviour is emulated by consulting + * the {@link MBeanServer#getClassLoaderRepository()} method + * of all the servers obtained from + * {@link MBeanServerFactory#findMBeanServer(String)}. Use of + * this class should be avoided in new code. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + * @deprecated Use {@link MBeanServer#getClassLoaderRepository()} + * instead. + */ +@Deprecated public class DefaultLoaderRepository +{ + + /** + * Attempts to load the given class using class loaders + * supplied by the repository of each {@link MBeanServer}. + * The {@link ClassLoader#loadClass(String)} + * method of each class loader is called. If the method + * returns successfully, then the returned {@link Class} instance + * is returned. If a {@link ClassNotFoundException} is thrown, + * then the next loader is tried. Any other exception thrown + * by the method is passed back to the caller. This method + * throws a {@link ClassNotFoundException} itself if all the + * class loaders listed prove fruitless. + * + * @param name the name of the class to load. + * @return the loaded class. + * @throws ClassNotFoundException if all the class loaders fail + * to load the class. + */ + public static Class loadClass(String name) + throws ClassNotFoundException + { + List<MBeanServer> servers = MBeanServerFactory.findMBeanServer(null); + for (MBeanServer server : servers) + { + try + { + return server.getClassLoaderRepository().loadClass(name); + } + catch (ClassNotFoundException e) + { + /* Ignored; try the next server. */ + } + } + throw new ClassNotFoundException("The class loaders of all registered " + + "servers failed to load the class, " + + name); + } + + /** + * <p> + * Attempts to load the given class using class loaders + * supplied by the repository of each {@link MBeanServer}. + * The {@link ClassLoader#loadClass(String)} + * method of each class loader is called. If the method + * returns successfully, then the returned {@link Class} instance + * is returned. If a {@link ClassNotFoundException} is thrown, + * then the next loader is tried. Any other exception thrown + * by the method is passed back to the caller. This method + * throws a {@link ClassNotFoundException} itself if all the + * class loaders listed prove fruitless. + * </p> + * <p> + * Note that this method may deadlock if called simultaneously + * by two class loaders in the list. + * {@link loadClassBefore(ClassLoader, String)} should be used + * in preference to this method to avoid this. + * </p> + * + * @param exclude the class loader to exclude, or <code>null</code> + * to obtain the same behaviour as {@link #loadClass(String)}. + * @param name the name of the class to load. + * @return the loaded class. + * @throws ClassNotFoundException if all the class loaders fail + * to load the class. + */ + public static Class loadClassWithout(ClassLoader exclude, String name) + throws ClassNotFoundException + { + List<MBeanServer> servers = MBeanServerFactory.findMBeanServer(null); + for (MBeanServer server : servers) + { + try + { + return server.getClassLoaderRepository().loadClassWithout(exclude, + name); + } + catch (ClassNotFoundException e) + { + /* Ignored; try the next server. */ + } + } + throw new ClassNotFoundException("The class loaders of all registered " + + "servers failed to load the class, " + + name); + } + +} diff --git a/libjava/classpath/javax/management/Descriptor.java b/libjava/classpath/javax/management/Descriptor.java new file mode 100644 index 0000000..07b8f1d --- /dev/null +++ b/libjava/classpath/javax/management/Descriptor.java @@ -0,0 +1,392 @@ +/* Descriptor.java -- Metadata container. + Copyright (C) 2007 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 javax.management; + +import java.io.Serializable; + +/** + * <p> + * Provides metadata for a management element as a series + * of fields, formed from name-value pairs. Descriptors + * are usually attached to one of the <code>Info</code> + * classes, such as {@link MBeanAttributeInfo}. + * </p> + * <p> + * Field names are not case-sensitive, but are case-preserving + * (in that the same use of case will be returned by + * {@link #getFields()} and {@link #getFieldNames()}). + * The type of the value should match the type returned + * by the <code>getType()</code> method of the associated + * <code>Info</code> object. In the case of {@link MXBean}s, + * this should be the mapped type returned by the mapping rules. + * </p> + * <p> + * The contents of a descriptor may be immutable, in which + * case, attempts to change the contents of the descriptor + * will cause an exception to be thrown. Immutable descriptors + * are usually instances or subclasses of {@link ImmutableDescriptor}, + * while mutable descriptors are usually instances or subclasses + * of {@link javax.management.modelmbean.DescriptorSupport}. + * </p> + * <p> + * A series of field names are predefined, but additional + * ones can be added as needed. Predefined names never include + * a period ('.'), and so additional names may safely avoid + * conflicts by including this character. It is recommended that + * additional names make use of the same syntax as Java package + * names e.g. <code>gnu.classpath.ImportantMetadata</code>. + * </p> + * <p> + * The predefined names are as follows: + * </p> + * <table> + * <th> + * <td>Name</td><td>Type</td><td>Used In</td><td>Meaning</td> + * </th> + * <tr> + * <td>defaultValue</td><td>Object</td><td>{@link MBeanAttributeInfo}, + * {@link MBeanParameterInfo}</td><td>Default value for an attribute + * or parameter.</td> + * </tr> + * <tr> + * <td>deprecated</td><td>String</td><td>Any</td><td>The annotated element + * has been deprecated. Conventially, the field's value takes the form + * of the version in which the element was deprecated, followed by an + * explaination.</td> + * </tr> + * <tr> + * <td>descriptionResourceBundleBaseName</td><td>String</td><td>Any</td> + * <td>The base name for the bundle in which the <code>descriptionResourceKey</code> + * can be found.</td> + * </tr> + * <tr> + * <td>descriptionResourceKey</td><td>String</td><td>Any</td> + * <td>The name of the resource key which contains a localized description of + * this element.</td> + * </tr> + * <tr> + * <td>enabled</td><td>String</td><td>{@link MBeanAttributeInfo}, + * {@link MBeanNotificationInfo}, {@link MBeanOperationInfo}</td> + * <td>Specifies whether the annotated element is currently enabled or + * not, via a value of either <code>"true"</code> or <code>"false"</code>. + * </tr> + * <tr> + * <td>immutableInfo</td><td>String</td><td>{@link MBeanInfo}</td> + * <td>If the value of this field is <code>"true"</code>, this means that + * the annotated element will not change and thus may be cached.</td> + * </tr> + * <tr> + * <td>infoTimeout</td><td>String or Long</td><td>{@link MBeanInfo}</td> + * <td>If this field is present, and non-zero, it will contain a value + * in milliseconds for which the value of the annotated element will + * remain unchanged, allowing it to be safely cached for that period.</td> + * </tr> + * <tr> + * <td>interfaceClassName</td><td>String</td><td>{@link MBeanInfo}</td> + * <td>The Java interface name associated with the bean, as returned + * by {@link Class#getName()}.</td> + * </tr> + * <tr> + * <td>legalValues</td><td>Set<?></td><td>{@link MBeanAttributeInfo}, + * {@link MBeanParameterInfo}</td><td>Legal values for an attribute + * or parameter.</td> + * </tr> + * <tr> + * <td>maxValue</td><td>Object</td><td><td>{@link MBeanAttributeInfo}, + * {@link MBeanParameterInfo}</td><td>Maximum legal value for an attribute + * or parameter.</td> + * </tr> + * <tr> + * <td>metricType</td><td>String</td><td>{@link MBeanAttributeInfo}, + * {@link MBeanOperationInfo}</td><td>Specifies the type of metric represented + * by the annotated element. This will be either <code>"counter"</code> + * (an increasing value, which will only be reset and never decrease) + * or <code>"gauge"</code> (an increasing and decreasing value).</td> + * </tr> + * <tr> + * <td>minValue</td><td>Object</td><td>{@link MBeanAttributeInfo}, + * {@link MBeanParameterInfo}</td><td>Minimum legal value for an attribute + * or parameter.</td> + * </tr> + * <tr> + * <td>mxbean</td><td>String</td><td>{@link MBeanInfo}</td> + * <td>Specifies whether the annotated element is an {@link MXBean} or + * not, via a value of either <code>"true"</code> or <code>"false"</code>. + * </tr> + * <tr> + * <td>openType</td><td>{@link javax.management.openmbean.OpenType}</td> + * <td>{@link MBeanAttributeInfo}, {@link MBeanOperationInfo}</td>, + * {@link MBeanNotificationInfo}, {@link MBeanParameterInfo}</td> + * <td>Specifies the open type of the attribute or parameter, the return + * value of the operation or the user data of the notification respectively. + * This is present on <code>Open*Info</code> instances and for {@link MXBean}s.</td> + * <tr> + * <td>originalType</td><td>String</td><td>{@link MBeanAttributeInfo}, + * {@link MBeanOperationInfo}, {@link MBeanParameterInfo}</td> + * <td>The original Java type of an element which has been converted + * to another type according to the {@link MXBean} typing rules. + * For example, {@link java.lang.management.MemoryType} becomes a + * String after conversion. This field would contain + * <code>"java.lang.management.MemoryType"</code> to represent the + * earlier type of an element with the converted type.</td> + * </tr> + * <tr> + * <td>severity</td><td>Integer or String</td> + * <td>{@link MBeanNotificationInfo}</td><td>Represents the severity + * of the notification, ranging from 1 (most severe) to 6 (least + * severe), with 0 representing unknown severity.</td> + * </tr> + * <tr> + * <td>since</td><td>String</td><td>Any</td> + * <td>The version in which this field was introduced.</td> + * </tr> + * <tr> + * <td>units</td><td>String</td><td>{@link MBeanAttributeInfo}, + * {@link MBeanOperationInfo}, {@link MBeanParameterInfo}</td> + * <td>The units used by the value of an attribute or parameter, + * or the return value of an operation, such as <code>"bytes"</code>, + * <code>"milliseconds"</code> or <code>"kilogrammes"</code>. + * </tr> + * </table> + * <p>Some names are also defined as part of the Model MBeans package. + * See {@link javax.management.modelmbean.ModelMBeanInfo}.</p> + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public interface Descriptor + extends Serializable, Cloneable +{ + + /** + * Returns a clone of this descriptor, which can then be modified + * independently of this descriptor. If the descriptor is + * immutable, it is sufficient to return this instance. + * + * @return a clone of this descriptor. + * @throws RuntimeOperationsException if creation of the new + * descriptor fails for any + * reason. + */ + Object clone() + throws RuntimeOperationsException; + + /** + * <p> + * Returns true if this descriptor is equivalent to the + * supplied object. This is true if the following holds: + * </p> + * <ul> + * <li>The given object is also a {@link Descriptor}.</li> + * <li>Has the same field names, independent of case.</li> + * <li>Has the same values, based on the following: + * <ul> + * <li>If one value is <code>null</code>, the other must be.</li> + * <li>If one value is a primitive array, the other must be a + * primitive array of the same type with the same elements.</li> + * <li>If one value is an {@link Object} array, the other + * must be and {@link java.util.Arrays#deepEquals(Object[],Object[])} + * must return true.</li> + * <li>Otherwise, {@link Object#equals(Object)} must return true.</li> + * </ul> + * + * @param obj the object to compare according to the above. + * @return true if the above holds. + * @see Object#equals(Object) + * @see Object#hashCode() + * @since 1.6 + */ + boolean equals(Object obj); + + /** + * Returns the field names of the descriptor. If the + * descriptor is empty, an empty array is returned. + * + * @return the field names as an array of Strings. + */ + String[] getFieldNames(); + + /** + * <p> + * Returns all the field name and value pairs, in the + * form <code>name=value</code>. The value is converted + * to a String as follows: + * </p> + * <ul> + * <li>If the value is a String, it is used as is.</li> + * <li>If the value is <code>null</code>, the printed + * value will be empty.</li> + * <li>Otherwise, the value will be converted to a + * String using its {@link Object#toString()} method, + * and included as <code>"(" + string + ")"</code>.</li> + * </ul> + * <p>If the descriptor is empty, an empty array is returned.</p> + * + * @return the field names and values as an array of Strings. + * @see #setFields(String[],Object[]) + */ + String[] getFields(); + + /** + * Returns the value of the specified field, or <code>null</code> + * if no value is present for the given field name. + * + * @param name the field name. + * @return the value of the field, or <code>null</code> if there + * is no value present. + * @throws RuntimeOperationsException if the field name is illegal. + */ + Object getFieldValue(String name); + + /** + * Returns the values corresponding to the fields named in + * the specified array, in the same order. If an empty + * array is supplied, an empty array is returned. A value + * of <code>null</code> leads to behaviour equivalent to + * {@link #getFields()}. Field values are obtained as specified + * in {@link #getFieldValue(String)}, with <code>null</code> + * being returned if the field is not present. This applies + * even if the given field name is <code>null</code> or + * the empty string. + * + * @param names an array of field names whose values should + * be returned. + * @return the values of the specified fields. + * @see #getFields() + * @see #getFieldValue(String) + */ + Object[] getFieldValues(String... names); + + /** + * <p> + * Returns the hash code of the descriptor. The hashcode + * is computed as the sum of the hashcodes for each field, + * which in turn is calculated as the sum of + * the hashcode of the name, <code>n</code>, computed + * using <code>n.toLowerCase().hashCode()</code>, and the + * hashcode of the value, <code>v</code>, computed + * using: + * </p> + * <ul> + * <li>If <code>v</code> is <code>null</code>, then the + * hash code is 0.</li> + * <li>If <code>v</code> is a primitive array, then the + * hash code is computed using the appropriate method + * from {@link java.util.Arrays}.</li> + * <li>If <code>v</code> is an {@link java.lang.Object} + * array, then the hash code is computed using the + * {@link java.util.Arrays#deepHashCode(Object[])} method.</li> + * <li>Otherwise, the hashcode is equal to + * <code>v.hashCode()</code>. + * </ul> + * + * @return a hashcode for this descriptor. + * @since 1.6 + * @see Object#equals(Object) + * @see Object#hashCode() + */ + int hashCode(); + + /** + * Returns true if all the fields have legal values, given + * their names. Validity is determined by the implementation. + * + * @return true if the values are legal. + * @throws RuntimeOperationsException if the validity check + * fails for some reason. + */ + boolean isValid() + throws RuntimeOperationsException; + + /** + * Removes a field from the descriptor. If the field name + * is illegal or not found, this method fails silently. + * + * @param name the name of the field to remove. + * @throws RuntimeOperationsException if the field exists + * and the descriptor is + * immutable. This wraps + * an {@link UnsupportedOperationException}. + */ + void removeField(String name); + + /** + * Attempts to set the specified field to the supplied + * value. If the field does not exist, it will be created. + * If the field value given is invalid, then an exception will + * be thrown. Validity is determined by the implementation + * of the descriptor. + * + * @param name the field to set. Can not be <code>null</code> + * or empty. + * @param value the value to use, the validity of which is + * determined by the implementation. + * @throws RuntimeOperationsException if the name or value is + * illegal (wrapping a + * {@link IllegalArgumentException}) + * or if the descriptor is + * immutable (wrapping a + * {@link UnsupportedOperationException}. + */ + void setField(String name, Object value) + throws RuntimeOperationsException; + + /** + * Sets the field named in the first array to the corresponding + * value specified in the second. The array sizes must match. + * Empty arrays have no effect. An invalid value will cause + * an exception to be thrown. + * + * @param names the names of the fields to change. Neither + * the array or its elements may be <code>null</code>. + * @param values the values to use. The array must not be + * <code>null</code>. The value of the elements + * depends on the validity constraints of the + * implementation. + * @throws RuntimeOperationsException if the arrays differ in + * length, or a name or value is + * illegal (wrapping a + * {@link IllegalArgumentException}) + * or if the descriptor is + * immutable (wrapping a + * {@link UnsupportedOperationException}. + * @see #setField(String,Object) + */ + void setFields(String[] names, Object[] values); + +} diff --git a/libjava/classpath/javax/management/DescriptorAccess.java b/libjava/classpath/javax/management/DescriptorAccess.java new file mode 100644 index 0000000..189b34a --- /dev/null +++ b/libjava/classpath/javax/management/DescriptorAccess.java @@ -0,0 +1,65 @@ +/* DescriptorAccess.java -- Allows a descriptor to be changed. + Copyright (C) 2007 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 javax.management; + +/** + * Allows the descriptor of a management element + * to be changed. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public interface DescriptorAccess + extends DescriptorRead +{ + + /** + * Replaces the descriptor of this management element + * with the one specified. If the specified descriptor + * is <code>null</code>, the descriptor of the element + * will be returned to its default, which must at least + * contain a name and type. If the specified descriptor + * is invalid for this management element, an exception + * is thrown. + * + * @param descriptor the new descriptor to use. + * @see DescriptorRead#getDescriptor() + */ + void setDescriptor(Descriptor descriptor); + +} diff --git a/libjava/classpath/javax/management/DescriptorRead.java b/libjava/classpath/javax/management/DescriptorRead.java new file mode 100644 index 0000000..95e383a --- /dev/null +++ b/libjava/classpath/javax/management/DescriptorRead.java @@ -0,0 +1,59 @@ +/* DescriptorRead.java -- Allows a descriptor to be read. + Copyright (C) 2007 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 javax.management; + +/** + * Provides read access to the descriptor of + * a management element. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.6 + */ +public interface DescriptorRead +{ + + /** + * Returns a copy of the descriptor for this management + * element. The return value is never <code>null</code>, + * but the returned descriptor may be empty. + * + * @return the descriptor for this management element. + */ + Descriptor getDescriptor(); + +} diff --git a/libjava/classpath/javax/management/JMX.java b/libjava/classpath/javax/management/JMX.java new file mode 100644 index 0000000..a435d3e --- /dev/null +++ b/libjava/classpath/javax/management/JMX.java @@ -0,0 +1,342 @@ +/* JMX.java -- Static methods pertaining to the management API. + Copyright (C) 2007 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 javax.management; + +import java.lang.reflect.Proxy; + +/** + * Common static methods pertaining to the management + * API. There are no instances of this class. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.6 + */ +public class JMX +{ + + /** + * The name of the defaultValue field. + */ + public static final String DEFAULT_VALUE_FIELD = "defaultValue"; + + /** + * The name of the immutableInfo field. + */ + public static final String IMMUTABLE_INFO_FIELD = "immutableInfo"; + + /** + * The name of the interfaceClassName field. + */ + public static final String INTERFACE_CLASS_NAME_FIELD = "interfaceClassName"; + + /** + * The name of the legalValues field. + */ + public static final String LEGAL_VALUES_FIELD = "legalValues"; + + /** + * The name of the maxValue field. + */ + public static final String MAX_VALUE_FIELD = "maxValue"; + + /** + * The name of the minValue field. + */ + public static final String MIN_VALUE_FIELD = "minValue"; + + /** + * The name of the mxbean field. + */ + public static final String MXBEAN_FIELD = "mxbean"; + + /** + * The name of the openType field. + */ + public static final String OPEN_TYPE_FIELD = "openType"; + + /** + * The name of the originalType field. + */ + public static final String ORIGINAL_TYPE_FIELD = "originalType"; + + /** + * Prevent instance creation. + */ + private JMX() + { + } + + /** + * <p> + * Returns true if the given class represents an {@link MXBean} + * interface. An interface is an {@link MXBean interface} if: + * </p> + * <ul> + * <li>It is annotated with {@code @MXBean} or + * {@code @MXBean(true)}</li>. + * <li>Its name ends in {@code "MXBean"} and it does not + * have an {@link MXBean} annotation.</li> + * </ul> + * + * @param iface the interface class that is to be checked + * for {@link MXBean} status. + * @return true if the interface represents an {@link MXBean}. + * @throws NullPointerException if {@code iface} is {@code null}. + */ + public static boolean isMXBeanInterface(Class<?> iface) + { + MXBean annotation = iface.getAnnotation(MXBean.class); + if (annotation != null) + return annotation.value(); + return iface.getName().endsWith("MXBean"); + } + + /** + * <p> + * Returns a proxy for a standard management bean, using + * the specified connection to access the named implementation. + * To create a proxy for the bean, {@code SomethingMBean}, a call to + * {@code JMX.newMBeanProxy(server, name, SomethingMBean.class)} + * is made, where {@code server} is a local or remote management + * server, and {@code name} is the registered {@link ObjectName} + * of the implementation of {@code SomethingMBean} to use. + * </p> + * <p> + * The proxy redirects calls to the methods of the interface, + * {@link SomethingMBean}, to the appropriate methods of the + * management server. If {@link SomethingMBean} is specified + * as follows: + * </p> + * <pre> + * public interface SomethingMBean + * { + * String getName(); + * void setName(String name); + * void doStuff(); + * } + * </pre> + * <p> + * The proxy created above will provide these three methods + * using an instance of {@link MBeanServerInvocationHandler}. + * The two methods, {@code getName} and {@code setName} define + * an attribute, {@code Name}, so a call to {@code getName()} + * will return the value of {@code server.getAttribute(name, + * "Name")}, while {@code setName(newName)} will result in a + * call to {@code server.setAttribute(name, new Attribute("Name", + * newName))}. Finally, {@code doStuff()}, as an operation, + * will cause the proxy to call {@link MBeanServer#invoke(ObjectName, + * String, Object[], String[])} as + * {@code server.invoke(name, "doStuff", null, null)}. + * </p> + * <p> + * Calling this method is equivalent to calling + * {@link #newMBeanProxy(MBeanServerConnection, ObjectName, Class, + * boolean)}. + * </p> + * + * @param conn the server connection over which to forward calls to + * the bean. + * @param name the registered name of the bean to use to implement + * the given interface. + * @param iface the interface to provide a proxy for. + * @return a proxy implementing the specified interface using calls + * to the methods of the bean registered with the supplied + * server using the given name. + * @see #newMBeanProxy(MBeanServerConnection, ObjectName, Class, + * boolean) + */ + public static <T> T newMBeanProxy(MBeanServerConnection conn, + ObjectName name, Class<T> iface) + { + return newMBeanProxy(conn, name, iface, false); + } + + /** + * Returns a proxy for a standard management bean, using + * the specified connection to access the named implementation, + * as with {@link #newMBeanProxy(MBeanServerConnection, ObjectName, + * Class)}. In addition, the proxy returned by this method will + * also implement {@link NotificationEmitter} if {@code bcast} is + * true, under the assumption that the implementation referenced by + * {@code name} implements this interface. Calls to the methods of + * {@link NotificationEmitter} will be forwarded to the bean + * implementation via the appropriate server methods. + * + * @param conn the server connection over which to forward calls to + * the bean. + * @param name the registered name of the bean to use to implement + * the given interface. + * @param iface the interface to provide a proxy for. + * @param bcast true if the proxy should implement + * {@link NotificationEmitter}. + * @return a proxy implementing the specified interface using calls + * to the methods of the bean registered with the supplied + * server using the given name. + * @see #newMBeanProxy(MBeanServerConnection, ObjectName, Class) + */ + public static <T> T newMBeanProxy(MBeanServerConnection conn, + ObjectName name, Class<T> iface, + boolean bcast) + { + return MBeanServerInvocationHandler.newProxyInstance(conn, name, + iface, bcast); + } + + /** + * <p> + * Returns a proxy for a {@link MXBean}, using the specified + * connection to access the named implementation. + * To create a proxy for the bean, {@code SomethingMXBean}, a call to + * {@code JMX.newMXBeanProxy(server, name, SomethingMXBean.class)} + * is made, where {@code server} is a local or remote management + * server, and {@code name} is the registered {@link ObjectName} + * of the implementation of {@code SomethingMBean} to use. + * </p> + * <p> + * The proxy redirects calls to the methods of the interface, + * {@link SomethingMXBean}, to the appropriate methods of the + * management server with appropriate conversion between + * Java and open types, according to the MXBean rules. If + * {@link SomethingMXBean} is specified as follows: + * </p> + * <pre> + * public interface SomethingMXBean + * { + * String getName(); + * void setName(String name); + * List<Double> getStatistics(); + * void setStatistics(List<Double> statistics); + * List<Double> getNamedStatistics(String, Map<String,Integer>); + * } + * </pre> + * <p> + * The proxy created above will provide these five methods + * using an instance of {@link MBeanServerInvocationHandler}. + * The two methods, {@code getName} and {@code setName} define + * an attribute, {@code Name}, so a call to {@code getName()} + * will return the value of {@code server.getAttribute(name, + * "Name")}, while {@code setName(newName)} will result in a + * call to {@code server.setAttribute(name, new Attribute("Name", + * newName))}. As this uses a simple type, {@link String}, no + * conversion is necessary. + * </p> + * <p> + * The two methods, {@code getStatistics} and {@code setStatistics} + * similarly define another attribute, {@code Statistics}. Calling + * {@code getStatistics()} will cause a call to the server to be + * made as before, {@code server.getAttribute(name, "Statistics")}. + * However, the type of the return value from this call will be + * an array of {@link Double} objects, as per the {@link MXBean} + * rules. The proxy converts this back in to a {@link java.util.List} + * of {@link Double} objects before returning it. + * </p> + * <p> + * The same process is applied in reverse for + * {@code setStatistics(newStats)}. The list is converted into + * an appropriate array before the call to + * {@link MBeanServerConnection#setAttribute(ObjectName, Attribute)} + * is made. Finally, a call to {@code getNamedStatistics} will require + * both a Java to open type conversion on the arguments, and then + * an open type to Java conversion of the return value. Thus, a proxy + * enables an {@link MXBean} to be used in cases where the appropriate + * Java types are available and the user wishes to access the bean + * using the types directly defined in its interface, just as with + * standard management beans. + * </p> + * <p> + * Calling this method is equivalent to calling + * {@link #newMXBeanProxy(MBeanServerConnection, ObjectName, Class, + * boolean)}. + * </p> + * + * @param conn the server connection over which to forward calls to + * the bean. + * @param name the registered name of the bean to use to implement + * the given interface. + * @param iface the interface to provide a proxy for. + * @return a proxy implementing the specified interface using calls + * to the methods of the bean registered with the supplied + * server using the given name. + * @see #newMXBeanProxy(MBeanServerConnection, ObjectName, Class, + * boolean) + */ + public static <T> T newMXBeanProxy(MBeanServerConnection conn, + ObjectName name, Class<T> iface) + { + return newMXBeanProxy(conn, name, iface, false); + } + + /** + * Returns a proxy for a {@link MXBean}, using + * the specified connection to access the named implementation, + * as with {@link #newMXBeanProxy(MBeanServerConnection, ObjectName, + * Class)}. In addition, the proxy returned by this method will + * also implement {@link NotificationEmitter} if {@code bcast} is + * true, under the assumption that the implementation referenced by + * {@code name} implements this interface. Calls to the methods of + * {@link NotificationEmitter} will be forwarded to the bean + * implementation via the appropriate server methods. + * + * @param conn the server connection over which to forward calls to + * the bean. + * @param name the registered name of the bean to use to implement + * the given interface. + * @param iface the interface to provide a proxy for. + * @param bcast true if the proxy should implement + * {@link NotificationEmitter}. + * @return a proxy implementing the specified interface using calls + * to the methods of the bean registered with the supplied + * server using the given name. + * @see #newMXBeanProxy(MBeanServerConnection, ObjectName, Class) + */ + public static <T> T newMXBeanProxy(MBeanServerConnection conn, + ObjectName name, Class<T> iface, + boolean bcast) + { + if (bcast) + return (T) Proxy.newProxyInstance(iface.getClassLoader(), + new Class[] { iface, + NotificationEmitter.class }, + new MBeanServerInvocationHandler(conn,name,true)); + else + return (T) Proxy.newProxyInstance(iface.getClassLoader(), + new Class[] { iface }, + new MBeanServerInvocationHandler(conn,name,true)); + } + +} diff --git a/libjava/classpath/javax/management/MBeanAttributeInfo.java b/libjava/classpath/javax/management/MBeanAttributeInfo.java index 2d7c100..2e8475e 100644 --- a/libjava/classpath/javax/management/MBeanAttributeInfo.java +++ b/libjava/classpath/javax/management/MBeanAttributeInfo.java @@ -55,6 +55,11 @@ public class MBeanAttributeInfo { /** + * Compatible with JDK 1.6 + */ + private static final long serialVersionUID = 8644704819898565848L; + + /** * The type of the attribute. * * @serial the attribute type. diff --git a/libjava/classpath/javax/management/MBeanFeatureInfo.java b/libjava/classpath/javax/management/MBeanFeatureInfo.java index 74a03038..b3d60d2 100644 --- a/libjava/classpath/javax/management/MBeanFeatureInfo.java +++ b/libjava/classpath/javax/management/MBeanFeatureInfo.java @@ -37,6 +37,8 @@ exception statement from your version. */ package javax.management; +import java.io.IOException; +import java.io.ObjectOutputStream; import java.io.Serializable; /** @@ -183,4 +185,17 @@ public class MBeanFeatureInfo return string; } + /** + * Serialize the {@link MBeanFeatureInfo}. + * + * @param out the output stream to write to. + * @throws IOException if an I/O error occurs. + */ + private void writeObject(ObjectOutputStream out) + throws IOException + { + out.defaultWriteObject(); + /* FIXME: Handle extra 1.6 descriptor stuff */ + } + } diff --git a/libjava/classpath/javax/management/MBeanServerInvocationHandler.java b/libjava/classpath/javax/management/MBeanServerInvocationHandler.java new file mode 100644 index 0000000..9489967 --- /dev/null +++ b/libjava/classpath/javax/management/MBeanServerInvocationHandler.java @@ -0,0 +1,400 @@ +/* MBeanServerInvocationHandler.java -- Provides a proxy for a bean. + Copyright (C) 2007 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 javax.management; + +import gnu.javax.management.Translator; + +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; + +/** + * <p> + * Provides a proxy for a management bean. The methods + * of the given interface are fulfilled by redirecting the + * calls over an {@link MBeanServerConnection} to the bean + * specified by the supplied {@link ObjectName}. + * </p> + * <p> + * The {@link java.lang.reflect.InvocationHandler} also makes + * provision for {@link MXBean}s by providing type conversion + * according to the rules defined for these beans. The input + * parameters are converted to their equivalent open type before + * calling the method, and then the return value is converted + * back from its open type to the appropriate Java type. For + * example, a method that takes an {@link Enum} as input and + * returns a {@link java.util.List} will have the input value + * converted from an {@link Enum} to a {@link String}, while + * the return value will be converted from its return type + * (an appropriately typed array) to a {@link java.util.List}. + * </p> + * <p> + * The proxy has special cases for the {@link Object#equals(Object)}, + * {@link Object#hashCode()} and {@link Object#toString()} methods. + * Unless they are specified explictly by the interface, the + * following behaviour is provided for these methods by the proxy: + * </p> + * <ul> + * <li><code>equals(Object)</code> returns true if the other object + * is an {@link MBeanServerInvocationHandler} with the same + * {@link MBeanServerConnection} and {@link ObjectName}. If an + * interface class was specified on construction for one of the + * proxies, then the same class must have also been specified + * for the other.</li> + * <li><code>hashCode()</code> returns the same value for + * equivalent proxies.</li> + * <li><code>toString()</code> returns a textual representation + * of the proxy.</li> + * </ul> + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public class MBeanServerInvocationHandler + implements InvocationHandler +{ + + /** + * The connection used to make the calls. + */ + private MBeanServerConnection conn; + + /** + * The name of the bean to perform operations on. + */ + private ObjectName name; + + /** + * True if this proxy is for an {@link MXBean}. + */ + private boolean mxBean; + + /** + * The interface class associated with the bean. + */ + private Class<?> iface; + + /** + * Constructs a new {@link MBeanServerInvocationHandler} + * which forwards methods to the supplied bean via the + * given {@link MBeanServerConnection}. This constructor + * is used in preference to + * {@link JMX#newMBeanProxy(MBeanServerConnection, ObjectName, + * Class<T>)} if you wish to make your own call to + * {@link java.lang.reflect.Proxy#newInstance(ClassLoader, + * Class[], java.lang.reflect.InvocationHandler)} with + * a different {@link ClassLoader}. Calling this constructor + * is equivalent to <code>MBeanServerInvocationHandler(conn, + * name, false)</code>. The other constructor should be used + * instead if the bean being proxied is an {@link MXBean}. + * + * @param conn the connection through which methods will + * be forwarded to the bean. + * @param name the name of the bean to use to provide the + * actual calls. + */ + public MBeanServerInvocationHandler(MBeanServerConnection conn, + ObjectName name) + { + this(conn, name, false); + } + + /** + * Constructs a new {@link MBeanServerInvocationHandler} + * which forwards methods to the supplied bean via the + * given {@link MBeanServerConnection}. This constructor + * is used in preference to + * {@link JMX#newMBeanProxy(MBeanServerConnection, ObjectName, + * Class<T>)} if you wish to make your own call to + * {@link java.lang.reflect.Proxy#newInstance(ClassLoader, + * Class[], java.lang.reflect.InvocationHandler)} with + * a different {@link ClassLoader}. + * + * @param conn the connection through which methods will + * be forwarded to the bean. + * @param name the name of the bean to use to provide the + * actual calls. + * @param mxBean true if the bean being proxied is an + * {@link MXBean}. + * @since 1.6 + */ + public MBeanServerInvocationHandler(MBeanServerConnection conn, + ObjectName name, boolean mxBean) + { + this.conn = conn; + this.name = name; + this.mxBean = mxBean; + } + + /** + * Returns the connection through which the calls to the bean + * will be made. + * + * @return the connection being used to forward the calls to + * the bean. + * @since 1.6 + */ + public MBeanServerConnection getMBeanServerConnection() + { + return conn; + } + + /** + * Returns the name of the bean to which method calls are made. + * + * @return the bean which provides the actual method calls. + * @since 1.6 + */ + public ObjectName getObjectName() + { + return name; + } + + /** + * 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 if the bean is an {@link MXBean}. + * + * @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 mName = method.getName(); + Class proxyClass = proxy.getClass(); + if (mName.equals("toString")) + { + if (inInterface(mName, proxyClass)) + return conn.invoke(name,mName,null,null); + else + return proxyClass.getName() + "[name=" + name + + ", conn=" + conn + "]"; + } + if (mName.equals("hashCode")) + { + if (inInterface(mName, proxyClass)) + return conn.invoke(name,mName,null,null); + else + return conn.hashCode() + name.hashCode() + + (iface == null ? 0 : iface.hashCode()); + } + if (mName.equals("equals")) + { + if (inInterface(mName, proxyClass, Object.class)) + return conn.invoke(name,mName,new Object[]{args[0]}, + new String[]{"java.lang.Object"}); + else + { + if (args[0].getClass() != proxy.getClass()) + return false; + InvocationHandler ih = Proxy.getInvocationHandler(args[0]); + if (ih instanceof MBeanServerInvocationHandler) + { + MBeanServerInvocationHandler h = + (MBeanServerInvocationHandler) ih; + return conn.equals(h.getMBeanServerConnection()) + && name.equals(h.getObjectName()) + && (iface == null ? h.iface == null + : iface.equals(h.iface)); + } + return false; + } + } + if (NotificationEmitter.class.isAssignableFrom(proxyClass)) + { + if (mName.equals("addNotificationListener")) + { + conn.addNotificationListener(name, + (NotificationListener) args[0], + (NotificationFilter) args[1], + args[2]); + return null; + } + if (mName.equals("getNotificationInfo")) + return conn.getMBeanInfo(name).getNotifications(); + if (mName.equals("removeNotificationListener")) + { + if (args.length == 1) + conn.removeNotificationListener(name, + (NotificationListener) + args[0]); + else + conn.removeNotificationListener(name, + (NotificationListener) + args[0], + (NotificationFilter) + args[1], args[2]); + return null; + } + } + String[] sigs; + if (args == null) + sigs = null; + else + { + sigs = new String[args.length]; + for (int a = 0; a < args.length; ++a) + sigs[a] = args[a].getClass().getName(); + } + String attrib = null; + if (mName.startsWith("get")) + attrib = mName.substring(3); + else if (mName.startsWith("is")) + attrib = mName.substring(2); + if (attrib != null) + { + Object val = conn.getAttribute(name, attrib); + if (mxBean) + return Translator.toJava(val, method); + else + return val; + } + else if (mName.startsWith("set")) + { + Object arg; + if (mxBean) + arg = Translator.fromJava(args, method)[0]; + else + arg = args[0]; + conn.setAttribute(name, new Attribute(mName.substring(3), arg)); + return null; + } + if (mxBean) + return Translator.toJava(conn.invoke(name, mName, + Translator.fromJava(args,method), + sigs), method); + else + return conn.invoke(name, mName, args, sigs); + } + + /** + * Returns true if this is a proxy for an {@link MXBean} + * and conversions must be applied to input parameters + * and return types, according to the rules for such beans. + * + * @return true if this is a proxy for an {@link MXBean}. + * @since 1.6 + */ + public boolean isMXBean() + { + return mxBean; + } + + /** + * <p> + * Returns a proxy for the specified bean. A proxy object is created + * using <code>Proxy.newProxyInstance(iface.getClassLoader(), + * new Class[] { iface }, handler)</code>. The + * {@link javax.management.NotificationEmitter} class is included as the + * second element of the array if <code>broadcaster</code> is true. + * <code>handler</code> refers to the invocation handler which forwards + * calls to the connection, which is created by a call to + * <code>new MBeanServerInvocationHandler(conn, name)</code>. + * </p> + * <p> + * <strong>Note</strong>: use of the proxy may result in + * {@link java.io.IOException}s from the underlying + * {@link MBeanServerConnection}. + * As of 1.6, the use of {@link JMX#newMBeanProxy(MBeanServerConnection, + * ObjectName,Class)} and {@link JMX#newMBeanProxy(MBeanServerConnection, + * ObjectName,Class,boolean)} is preferred. + * </p> + * + * @param conn the server connection to use to access the bean. + * @param name the {@link javax.management.ObjectName} of the + * bean to provide a proxy for. + * @param iface the interface for the bean being proxied. + * @param broadcaster true if the proxy should implement + * {@link NotificationEmitter}. + * @return a proxy for the specified bean. + * @see JMX#newMBeanProxy(MBeanServerConnection,ObjectName,Class) + */ + public static <T> T newProxyInstance(MBeanServerConnection conn, + ObjectName name, Class<T> iface, + boolean broadcaster) + { + if (broadcaster) + return (T) Proxy.newProxyInstance(iface.getClassLoader(), + new Class[] { iface, + NotificationEmitter.class }, + new MBeanServerInvocationHandler(conn,name)); + else + return (T) Proxy.newProxyInstance(iface.getClassLoader(), + new Class[] { iface }, + new MBeanServerInvocationHandler(conn,name)); + } + + /** + * Returns true if the specified method is specified + * by one of the proxy's interfaces. + * + * @param name the name of the method to search for. + * @param proxyClass the class of the proxy. + * @param args the arguments to the method. + * @return true if one of the interfaces specifies the + * given method. + */ + private boolean inInterface(String name, Class<?> proxyClass, + Class<?>... args) + { + for (Class<?> iface : proxyClass.getInterfaces()) + { + try + { + iface.getMethod(name, args); + return true; + } + catch (NoSuchMethodException e) + { + /* Ignored; this interface doesn't specify + the method. */ + } + } + return false; + } + +} + diff --git a/libjava/classpath/javax/management/MXBean.java b/libjava/classpath/javax/management/MXBean.java new file mode 100644 index 0000000..7b3af54 --- /dev/null +++ b/libjava/classpath/javax/management/MXBean.java @@ -0,0 +1,82 @@ +/* MXBean.java - Marks a management bean interface as an MXBean. + Copyright (C) 2007 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 javax.management; + +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import static java.lang.annotation.RetentionPolicy.RUNTIME; +import static java.lang.annotation.ElementType.TYPE; + +/** + * <p> + * An annotation used to explictly mark an interface + * as defining (or not defining) an {@link MXBean}. By + * default, such beans are taken to be those whose interface + * has the suffix {@code "MXBean"}. The presence of this + * annotation overrides this intuition. The following + * interfaces would be classed as {@link MXBean}s: + * </p> + * <ul> + * <li>{@code public interface SomethingMXBean{}}</li> + * <li>{@code @MXBean public interface Someat{}}</li> + * <li>{@code @MXBean(true) public interface SomeatElse{}}</li> + * </ul> + * <p>The following would not:</p> + * <ul> + * <li>{@code public interface RandomInterface{}}</li> + * <li>{@code @MXBean(false) public interface SomethingMXBean{}}</li> + * </ul> + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.6 + */ +@Documented @Retention(RUNTIME) @Target(TYPE) +public @interface MXBean +{ + + /** + * Returns true if the annotated interface + * is an {@link MXBean}. + * + * @return true if the interface is an {@link MXBean}. + */ + boolean value(); + +} diff --git a/libjava/classpath/javax/management/Notification.java b/libjava/classpath/javax/management/Notification.java index 52c11de..2bbc206 100644 --- a/libjava/classpath/javax/management/Notification.java +++ b/libjava/classpath/javax/management/Notification.java @@ -37,6 +37,9 @@ exception statement from your version. */ package javax.management; +import java.io.IOException; +import java.io.ObjectOutputStream; + import java.util.Date; import java.util.EventObject; @@ -66,6 +69,11 @@ public class Notification { /** + * Compatible with JDK 1.6 + */ + private static final long serialVersionUID = -7516092053498031989L; + + /** * The notification message. * * @serial the notification message. @@ -141,7 +149,7 @@ public class Notification public Notification(String type, Object source, long sequenceNumber, long timeStamp) { - this(type, source, sequenceNumber, timeStamp, null); + this(type, source, sequenceNumber, timeStamp, ""); } /** @@ -159,6 +167,7 @@ public class Notification { super(source); this.type = type; + this.source = source; this.sequenceNumber = sequenceNumber; this.timeStamp = timeStamp; this.message = message; @@ -310,5 +319,17 @@ public class Notification + "]"; } + /** + * Serialize the {@link Notification}. + * + * @param out the output stream to write to. + * @throws IOException if an I/O error occurs. + */ + private void writeObject(ObjectOutputStream out) + throws IOException + { + out.defaultWriteObject(); + } + } diff --git a/libjava/classpath/javax/management/NotificationBroadcasterSupport.java b/libjava/classpath/javax/management/NotificationBroadcasterSupport.java new file mode 100644 index 0000000..59d9ec2 --- /dev/null +++ b/libjava/classpath/javax/management/NotificationBroadcasterSupport.java @@ -0,0 +1,390 @@ +/* NotificationBroadcasterSupport.java -- Supporting implementation. + Copyright (C) 2007 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 javax.management; + +import gnu.javax.management.ListenerData; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import java.util.concurrent.Executor; + +/** + * <p> + * Provides an implementation of the {@link NotificationEmitter} + * interface, which beans may utilise by extension. By default, + * a synchronous dispatch system is provided, whereby the + * {@link #handleNotification(NotificationListener, Notification, + * Object)} is called once per listener by + * {*@link #sendNotification(Notification)} before returning. + * Thus, unless the listener is remote, it will have received + * the notification before the method returns. + * This may be changed by overriding the <code>handleNotification</code> + * method, or by providing an {@link java.util.concurrent.Executor} to + * use. With the latter, the dispatch of a notification to a particular + * listener will form one task performed by the executor. + * </p> + * <p> + * Any exceptions thrown by the dispatch process will be caught, allowing + * other listeners to still receive the notification. However, any + * {@link Error}s that are thrown will be propogated to the caller of + * {@link #sendNotification(Notification)}. + * </p> + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public class NotificationBroadcasterSupport + implements NotificationEmitter +{ + + /** + * The executor for dispatch, or + * <code>null</code> if this thread should + * handle dispatch itself. + */ + private Executor executor; + + /** + * An array containing information on each + * notification, or <code>null</code> if an + * empty array should be returned by + * {@link #getNotificationInfo()}. + */ + private MBeanNotificationInfo[] info; + + /** + * The list of listeners registered with + * this broadcaster. + */ + private final List<ListenerData> listeners = + new ArrayList<ListenerData>(); + + /** + * Constructs a {@link NotificationBroadcasterSupport} using + * the default synchronous dispatch model, where a single + * thread sends the notification to all listeners. This + * is equivalent to calling + * <code>NotificationBroadcasterSupport(null, null)</code>. + */ + public NotificationBroadcasterSupport() + { + this(null, null); + } + + /** + * Constructs a {@link NotificationBroadcasterSupport} where + * the specified (@link java.util.concurrent.Executor} is used + * to perform each invocation of the + * {@link #handleNotification(NotificationListener, Notification, + * Object)} method. Filtering is performed beforehand, by this + * thread; only calls which have successfully passed through the + * filter are sent to the executor. This is equivalent to calling + * <code>NotificationBroadcasterSupport(executor, null)</code>. + * + * @param executor the executor to use for each call to + * <code>handleNotification()</code>. + * @since 1.6 + */ + public NotificationBroadcasterSupport(Executor executor) + { + this(executor, null); + } + + /** + * Constructs a {@link NotificationBroadcasterSupport} using + * the default synchronous dispatch model, where a single + * thread sends the notification to all listeners. The specified + * {@link MBeanNotificationInfo} array is used to provide + * information about the notifications on calls to + * {@link #getNotificationInfo()}, where a clone will be + * returned if the array is non-empty. This is equivalent to + * calling <code>NotificationBroadcasterSupport(null, info)</code>. + * + * @param info an array of {@link MBeanNotificationInfo} objects + * describing the notifications delivered by this + * broadcaster. This may be <code>null</code>, which + * is taken as being equivalent to an empty array. + */ + public NotificationBroadcasterSupport(MBeanNotificationInfo... info) + { + this(null, info); + } + + /** + * Constructs a {@link NotificationBroadcasterSupport} where + * the specified (@link java.util.concurrent.Executor} is used + * to perform each invocation of the + * {@link #handleNotification(NotificationListener, Notification, + * Object)} method. Filtering is performed beforehand, by this + * thread; only calls which have successfully passed through the + * filter are sent to the executor. The specified + * {@link MBeanNotificationInfo} array is used to provide + * information about the notifications on calls to + * {@link #getNotificationInfo()}, where a clone will be + * returned if the array is non-empty. + * + * @param executor the executor to use for each call to + * <code>handleNotification()</code>. + * @param info an array of {@link MBeanNotificationInfo} objects + * describing the notifications delivered by this + * broadcaster. This may be <code>null</code>, which + * is taken as being equivalent to an empty array. + * @since 1.6 + */ + public NotificationBroadcasterSupport(Executor executor, + MBeanNotificationInfo... info) + { + this.executor = executor; + this.info = info; + } + + /** + * Registers the specified listener as a new recipient of + * notifications from this bean. If non-null, the filter + * argument will be used to select which notifications are + * delivered. The supplied object will also be passed to + * the recipient with each notification. This should not + * be modified by the broadcaster, but instead should be + * passed unmodified to the listener. + * + * @param listener the new listener, who will receive + * notifications from this broadcasting bean. + * @param filter a filter to determine which notifications are + * delivered to the listener, or <code>null</code> + * if no filtering is required. + * @param passback an object to be passed to the listener with + * each notification. + * @throws IllegalArgumentException if <code>listener</code> is + * <code>null</code>. + * @see #removeNotificationListener(NotificationListener) + */ + public void addNotificationListener(NotificationListener listener, + NotificationFilter filter, + Object passback) + throws IllegalArgumentException + { + if (listener == null) + throw new IllegalArgumentException("Null listener added to bean."); + listeners.add(new ListenerData(listener, filter, passback)); + } + + /** + * Returns an array describing the notifications this + * bean may send to its registered listeners. Ideally, this + * array should be complete, but in some cases, this may + * not be possible. However, be aware that some listeners + * may expect this to be so. + * + * @return the array of possible notifications. + */ + public MBeanNotificationInfo[] getNotificationInfo() + { + if (info == null || info.length == 0) + return new MBeanNotificationInfo[0]; + return (MBeanNotificationInfo[]) info.clone(); + } + + /** + * This method is called on a per-listener basis, either + * from this thread or the supplied executor, and may be + * overridden by subclasses which wish to change how + * notifications are delivered. The default + * implementation simply calls + * <code>listener.handleNotification(notif, passback)</code>. + * + * @param listener the listener to send the notification to. + * @param notif the notification to dispatch. + * @param passback the passback object of the listener. + */ + protected void handleNotification(NotificationListener listener, + Notification notif, + Object passback) + { + listener.handleNotification(notif, passback); + } + + /** + * Removes the specified listener from the list of recipients + * of notifications from this bean. This includes all combinations + * of filters and passback objects registered for this listener. + * For more specific removal of listeners, see the subinterface + * {@link NotificationEmitter}. + * + * @param listener the listener to remove. + * @throws ListenerNotFoundException if the specified listener + * is not registered with this bean. + * @see #addNotificationListener(NotificationListener, NotificationFilter, + * java.lang.Object) + */ + public void removeNotificationListener(NotificationListener listener) + throws ListenerNotFoundException + { + Iterator<ListenerData> it = listeners.iterator(); + boolean foundOne = false; + while (it.hasNext()) + { + if (it.next().getListener() == listener) + { + it.remove(); + foundOne = true; + } + } + if (!foundOne) + throw new ListenerNotFoundException("The specified listener, " + listener + + "is not registered with this bean."); + } + + /** + * Removes the specified listener from the list of recipients + * of notifications from this bean. Only the first instance with + * the supplied filter and passback object is removed. + * <code>null</code> is used as a valid value for these parameters, + * rather than as a way to remove all registration instances for + * the specified listener; for this behaviour instead, see the details + * of the same method in {@link NotificationBroadcaster}. + * + * @param listener the listener to remove. + * @param filter the filter of the listener to remove. + * @param passback the passback object of the listener to remove. + * @throws ListenerNotFoundException if the specified listener + * is not registered with this bean. + * @see #addNotificationListener(NotificationListener, NotificationFilter, + * java.lang.Object) + */ + public void removeNotificationListener(NotificationListener listener, + NotificationFilter filter, + Object passback) + throws ListenerNotFoundException + { + if (!(listeners.remove(new ListenerData(listener, filter, passback)))) + { + throw new ListenerNotFoundException("The specified listener, " + listener + + " with filter " + filter + + "and passback " + passback + + ", is not registered with this bean."); + } + } + + /** + * <p> + * Performs delivery of the notification. If an executor + * was specified on construction, this will be used to call + * {@link #handleNotification(NotificationListener, Notification, + * Object)}. If the executor is <code>null</code>, however, + * this thread calls the method itself in order to perform a + * synchronous dispatch of the notification to all eligible + * listeners. + * </p> + * <p> + * Prior to either process taking place, the listeners are filtered. + * Notifications are only delivered if the filter is either + * <code>null</code> or returns true from the + * {@link NotificationFilter#isNotificationEnabled(Notification)} + * method. + * </p> + * + * @param notif the notification to send. + */ + public void sendNotification(Notification notif) + { + for (ListenerData ldata : listeners) + { + NotificationFilter filter = ldata.getFilter(); + if (filter == null || filter.isNotificationEnabled(notif)) + { + if (executor == null) + try + { + handleNotification(ldata.getListener(), notif, + ldata.getPassback()); + } + catch (Exception e) { /* Ignore */ } + else + executor.execute(new DispatchTask(ldata, notif)); + } + } + } + + /** + * The dispatch task to be performed by an executor. + */ + private final class DispatchTask + implements Runnable + { + + /** + * The data on the listener being called. + */ + private ListenerData ldata; + + /** + * The notification to send. + */ + private Notification notif; + + /** + * Construct a new {@link DispatchTask}. + * + * @param ldata the listener data. + * @param notif the notification to send. + */ + public DispatchTask(ListenerData ldata, + Notification notif) + { + this.ldata = ldata; + this.notif = notif; + } + + /** + * Dispatch the notification. + */ + public void run() + { + try + { + handleNotification(ldata.getListener(), notif, + ldata.getPassback()); + } + catch (Exception e) { /* Ignore */ } + } + } + +} + diff --git a/libjava/classpath/javax/management/NotificationFilterSupport.java b/libjava/classpath/javax/management/NotificationFilterSupport.java new file mode 100644 index 0000000..28be871 --- /dev/null +++ b/libjava/classpath/javax/management/NotificationFilterSupport.java @@ -0,0 +1,139 @@ +/* NotificationFilterSupport.java -- Filter on notification type. + Copyright (C) 2007 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 javax.management; + +import java.util.Vector; + +/** + * Performs filtering of {@link Notification}s + * based on a list of type prefixes. The type of a notification + * is compared with each member of the list using + * {@link String#startsWith(String)} and, if one matches, + * the notification is allowed to pass through the filter. + * Matching on the beginning of the string is used in + * preference to wildcards, so <code>type.*</code> will + * match only notifications with a type beginning with + * code>type.*</code>, not <code>type.</code> as + * expected. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public class NotificationFilterSupport + implements NotificationFilter +{ + + /** + * Compatible with JDK 1.5 + */ + private static final long serialVersionUID = 6579080007561786969L; + + /** + * Lists the types that may pass through the filter. + */ + private final Vector<String> enabledTypes = new Vector<String>(); + + /** + * Blocks all types by emptying the list of enabled attributes. + */ + public void disableAllTypes() + { + enabledTypes.clear(); + } + + /** + * Removes the specified type prefix from the list + * of enabled types, thus preventing matching types + * from passing through the filter. If the specified + * type prefix is not enabled, this operation has no + * effect. + * + * @param prefix the prefix to disable. + */ + public void disableType(String prefix) + { + enabledTypes.remove(prefix); + } + + /** + * Adds the specified type prefix to the list + * of enabled types, thus allowing + * types starting with this string to pass through + * the filter. If the type prefix is already + * enabled, this has no effect. + * + * @param prefix the prefix to enable. + * @throws IllegalArgumentException if <code>prefix</code> + * is <code>null</code>. + */ + public void enableType(String prefix) + { + if (prefix == null) + throw new IllegalArgumentException("A null prefix was supplied."); + if (!enabledTypes.contains(prefix)) + enabledTypes.add(prefix); + } + + /** + * Returns the list of enabled types for this + * filter. + * + * @return the list of enabled types. + */ + public Vector<String> getEnabledTypes() + { + return enabledTypes; + } + + /** + * Returns true if the type of the specified notification + * begins with one of the enabled type prefixes. + * + * @param notif the notification being filtered. + * @return true if the notification's type is enabled. + */ + public boolean isNotificationEnabled(Notification notif) + { + String nType = notif.getType(); + for (String type : enabledTypes) + if (nType.startsWith(type)) + return true; + return false; + } + +} diff --git a/libjava/classpath/javax/management/PersistentMBean.java b/libjava/classpath/javax/management/PersistentMBean.java new file mode 100644 index 0000000..e47e2c5 --- /dev/null +++ b/libjava/classpath/javax/management/PersistentMBean.java @@ -0,0 +1,126 @@ +/* PersistentMBean.java -- Interface for beans that should persist. + Copyright (C) 2007 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 javax.management; + +/** + * Beans may implement this interface in order to become + * persistent. The {@link #load()} method should be + * called on construction in order to reload the stored + * state. The {@link #store()} method should be called + * sometime during the bean's lifetime in order to create + * a persistent copy of the bean's instance data. This + * method may also be called by the {@link MBeanServer} + * as a result of the {@link Descriptor} of an + * {@link javax.management.modelmbean.ModelMBean}. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public interface PersistentMBean +{ + + /** + * Instantiates the bean with the data previously stored + * using a call to {@link #store()}. The data stored can + * include values held by attributes as well as those returned + * by operations. This method should be called during + * construction or initialisation of the bean, before + * it becomes registered with an {@link MBeanServer}. + * + * @throws MBeanException if persistence is not supported, + * or another exception is thrown + * (which this then wraps). + * @throws RuntimeOperationsException if the persistence + * mechanism throws an + * exception. + * @throws InstanceNotFoundException if the bean can not + * be found in the + * persistent store. + */ + void load() + throws MBeanException, RuntimeOperationsException, + InstanceNotFoundException; + + /** + * <p> + * Captures the current state of the bean and stores it + * for future retrieval by the {@link #load()} method. + * The data stored can include values held by attributes + * as well as those returned by operations. + * </p> + * <p> + * Whether the state is stored or not depends on the + * <code>persistPolicy</code> field of the MBean/attribute + * descriptor. The state should be stored if the policy + * is set to any of the following: + * </p> + * <ul> + * <li><code>always</code></li> + * <li><code>onTimer</code> and <code>now</code> is + * greater than or equal to <code>lastPersistTime + + * persistPeriod</code>.</li> + * <li><code>noMoreOftenThan</code> and <code>now</code> is + * greater than or equal to <code>lastPersistTime + + * persistPeriod</code>.</li> + * <li>onUnregister</li> + * </ul> + * <p>If the policy is set to any of the following, the state + * should not be stored:</p> + * <ul> + * <li><code>never</code></li> + * <li><code>onUpdate</code></li> + * <li><code>onTimer</code> and <code>now</code> is + * less than <code>lastPersistTime + persistPeriod</code>. + * </li> + * </ul> + * + * @throws MBeanException if persistence is not supported, + * or another exception is thrown + * (which this then wraps). + * @throws RuntimeOperationsException if the persistence + * mechanism throws an + * exception. + * @throws InstanceNotFoundException if the persistent + * store can not be found + * or accessed. + */ + void store() + throws MBeanException, RuntimeOperationsException, + InstanceNotFoundException; + +} diff --git a/libjava/classpath/javax/management/Query.java b/libjava/classpath/javax/management/Query.java new file mode 100644 index 0000000..80b76b1 --- /dev/null +++ b/libjava/classpath/javax/management/Query.java @@ -0,0 +1,1901 @@ +/* Query.java -- Static methods for query construction. + Copyright (C) 2007 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 javax.management; + +/** + * Provides static methods for constructing queries. Queries + * may be used to list and enumerate management beans, via + * the {@link MBeanServer}. By using the methods in this class, + * complex queries can be created from their more basic + * components. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public class Query +{ + + /** + * A code representing the {@link #plus(ValueExp, ValueExp) + * query to be used in serialization. + */ + public static final int PLUS = 0; + + /** + * A code representing the {@link #minus(ValueExp, ValueExp) + * query to be used in serialization. + */ + public static final int MINUS = 1; + + /** + * A code representing the {@link #times(ValueExp, ValueExp) + * query to be used in serialization. + */ + public static final int TIMES = 2; + + /** + * A code representing the {@link #div(ValueExp, ValueExp) + * query to be used in serialization. + */ + public static final int DIV = 3; + + /** + * A code representing the {@link #gt(ValueExp, ValueExp) + * query to be used in serialization. + */ + public static final int GT = 0; + + /** + * A code representing the {@link #lt(ValueExp, ValueExp) + * query to be used in serialization. + */ + public static final int LT = 1; + + /** + * A code representing the {@link #ge(ValueExp, ValueExp) + * query to be used in serialization. + */ + public static final int GE = 2; + + /** + * A code representing the {@link #le(ValueExp, ValueExp) + * query to be used in serialization. + */ + public static final int LE = 3; + + /** + * A code representing the {@link #eq(ValueExp, ValueExp) + * query to be used in serialization. + */ + public static final int EQ = 4; + + /** + * Returns a query expression formed from the conjunction + * of the two supplied query expressions. + * + * @param q1 the first query expression. + * @param q2 the second query expression. + * @return a query expression representing q1 && q2. This + * will be serialized as the non-public class + * {@link AndQueryExp}. + */ + public static QueryExp and(QueryExp q1, QueryExp q2) + { + return new AndQueryExp(q1, q2); + } + + /** + * Returns a query expression which checks that an + * attribute value held by the specified + * {@link AttributeValueExp} contains the string + * specified by the given {@link StringValueExp}. + * + * @param attrib the attribute to match. + * @param string the substring to find. + * @return a query expression representing + * <code>attrib.matches("*" + string + "*")</code>. + * This will be serialized as the non-public class + * {@link MatchQueryExp}. + */ + public static QueryExp anySubString(AttributeValueExp attrib, + StringValueExp string) + { + return new MatchQueryExp(attrib, "*" + string.getValue() + "*"); + } + + /** + * Returns a value expression for the value of the + * named attribute. Evaluating this using an + * {@link ObjectName} involves an underlying call + * to {@link MBeanServer#getAttribute(ObjectName,String)}. + * + * @param name the name of the attribute. + * @return a value expression which returns the value + * of the named attribute when applied. + */ + public static AttributeValueExp attr(String name) + { + return new AttributeValueExp(name); + } + + /** + * Returns a value expression for the value of the + * named attribute from the specified class. Evaluating + * this using an {@link ObjectName} involves an underlying call + * to both {@link MBeanServer#getObjectInstance(ObjectName)} and + * {@link MBeanServer#getAttribute(ObjectName,String)}. + * + * @param className the class containing the attribute. + * @param name the name of the attribute. + * @return a value expression which returns the value + * of the named attribute when applied. + * This will be serialized as the non-public class + * {@link QualifiedAttributeValueExp}. + */ + public static AttributeValueExp attr(String className, + String name) + { + return new QualifiedAttributeValueExp(className, name); + } + + /** + * Returns a query expression representing the constraint + * that the value, <code>v1</code>, lies between <code>v2</code> + * and <code>v3</code>. + * + * @param v1 the value to compare against the boundaries. + * @param v2 the lower boundary. + * @param v3 the upper boundary. + * @return a query expression representing a comparison + * of <code>v1</code> against <code>v2</code> + * and <code>v3</code>. It returns true if + * <code>v2 <= v1 <= v3</code>. This + * will be serialized as the non-public class + * {@link BetweenQueryExp}. + */ + public static QueryExp between(ValueExp v1, ValueExp v2, + ValueExp v3) + { + return new BetweenQueryExp(v1, v2, v3); + } + + /** + * Returns a value expression which evaluates to the name of + * the class of the bean when applied. Associating the expression + * with an {@link ObjectName} involves an underlying call + * to both {@link MBeanServer#getObjectInstance(ObjectName)} + * to obtain this information. + * + * @return a value expression which returns the class name + * of the bean to which it is applied. + * This will be serialized as the non-public class + * {@link ClassAttributeValueExp}. + */ + public static AttributeValueExp classattr() + { + return new ClassAttributeValueExp(); + } + + /** + * Returns a value expression which evaluates to the result of + * dividing <code>v1</code> by <code>v2</code>. + * + * @param v1 the left-hand operand. + * @param v2 the right-hand operand. + * @return a value expression which returns the result of + * the division when applied. This will be serialized + * as the non-public class {@link BinaryOpValueExp} + * with an operation of {@link #DIV}. + */ + public static ValueExp div(ValueExp v1, ValueExp v2) + { + return new BinaryOpValueExp(DIV, v1, v2); + } + + /** + * Returns a query expression which evaluates to the result of + * comparing <code>v1</code> to <code>v2</code> for equality. + * + * @param v1 the left-hand operand. + * @param v2 the right-hand operand. + * @return a value expression which returns the result of + * the comparison when applied. This will be serialized + * as the non-public class {@link BinaryRelQueryExp} + * with an operation of {@link #EQ}. + */ + public static QueryExp eq(ValueExp v1, ValueExp v2) + { + return new BinaryRelQueryExp(EQ, v1, v2); + } + + /** + * Returns a query expression which checks that an + * attribute value held by the specified + * {@link AttributeValueExp} ends with the string + * specified by the given {@link StringValueExp}. + * + * @param attrib the attribute to match. + * @param string the substring to find. + * @return a query expression representing + * <code>attrib.matches("*" + string)</code>. + * This will be serialized as the non-public class + * {@link MatchQueryExp}. + */ + public static QueryExp finalSubString(AttributeValueExp attrib, + StringValueExp string) + { + return new MatchQueryExp(attrib, "*" + string.getValue()); + } + + /** + * Returns a query expression which evaluates to the result of + * comparing <code>v1</code> to <code>v2</code> to see if + * <code>v1</code> is greater than or equal to <code>v2</code>. + * + * @param v1 the left-hand operand. + * @param v2 the right-hand operand. + * @return a value expression which returns the result of + * the comparison when applied. This will be serialized + * as the non-public class {@link BinaryRelQueryExp} + * with an operation of {@link #GE}. + */ + public static QueryExp geq(ValueExp v1, ValueExp v2) + { + return new BinaryRelQueryExp(GE, v1, v2); + } + + /** + * Returns a query expression which evaluates to the result of + * comparing <code>v1</code> to <code>v2</code> to see if + * <code>v1</code> is greater than <code>v2</code>. + * + * @param v1 the left-hand operand. + * @param v2 the right-hand operand. + * @return a value expression which returns the result of + * the comparison when applied. This will be serialized + * as the non-public class {@link BinaryRelQueryExp} + * with an operation of {@link #GT}. + */ + public static QueryExp gt(ValueExp v1, ValueExp v2) + { + return new BinaryRelQueryExp(GT, v1, v2); + } + + /** + * Returns a query expression representing the constraint + * that the value, <code>v</code>, is a member of the + * list, <code>vlist</code>. + * + * @param v the value to look for in the list. + * @param vlist the list of allowed values. + * @return a query expression representing a membership check + * of <code>v</code> against the list, <code>vlist</code>. + * This will be serialized as the non-public class + * {@link InQueryExp}. + */ + public static QueryExp in(ValueExp v, ValueExp[] vlist) + { + return new InQueryExp(v, vlist); + } + + /** + * Returns a query expression which checks that an + * attribute value held by the specified + * {@link AttributeValueExp} starts with the string + * specified by the given {@link StringValueExp}. + * + * @param attrib the attribute to match. + * @param string the substring to find. + * @return a query expression representing + * <code>attrib.matches(string + "*")</code>. + * This will be serialized as the non-public class + * {@link MatchQueryExp}. + */ + public static QueryExp initialSubString(AttributeValueExp attrib, + StringValueExp string) + { + return new MatchQueryExp(attrib, string.getValue() + "*"); + } + + /** + * Returns a query expression which checks that a + * bean is an instance of the class specified + * by the given {@link StringValueExp}. Associating the + * expression with an {@link ObjectName} involves an underlying + * call to {@link MBeanServer#isInstanceOf(ObjectName, String)} + * using the value of <code>((StringValueExp) + * className.apply(objectName)).getValue()</code> as the + * class name. + * + * @param className the name of the class which the bean + * should be an instance of. + * @return a query expression representing + * the inheritance check. This will be serialized + * as the non-public class {@link InstanceOfQueryExp}. + * @since 1.6 + */ + public static QueryExp isInstanceOf(StringValueExp className) + { + return new InstanceOfQueryExp(className); + } + + /** + * Returns a query expression which evaluates to the result of + * comparing <code>v1</code> to <code>v2</code> to see if + * <code>v1</code> is less than or equal to <code>v2</code>. + * + * @param v1 the left-hand operand. + * @param v2 the right-hand operand. + * @return a value expression which returns the result of + * the comparison when applied. This will be serialized + * as the non-public class {@link BinaryRelQueryExp} + * with an operation of {@link #LE}. + */ + public static QueryExp leq(ValueExp v1, ValueExp v2) + { + return new BinaryRelQueryExp(LE, v1, v2); + } + + /** + * Returns a query expression which evaluates to the result of + * comparing <code>v1</code> to <code>v2</code> to see if + * <code>v1</code> is less than <code>v2</code>. + * + * @param v1 the left-hand operand. + * @param v2 the right-hand operand. + * @return a value expression which returns the result of + * the comparison when applied. This will be serialized + * as the non-public class {@link BinaryRelQueryExp} + * with an operation of {@link #LT}. + */ + public static QueryExp lt(ValueExp v1, ValueExp v2) + { + return new BinaryRelQueryExp(LT, v1, v2); + } + + /** + * <p> + * Returns a query expression which checks that an + * attribute value matches the pattern + * specified by the given {@link StringValueExp}. + * The pattern uses file-globbing syntax: + * </p> + * <ul> + * <li>'*' stands for any number of arbitrary characters.</li> + * <li>'?' stands for a single arbitrary characters.</li> + * <li>An expression within '[' and ']' specify a character + * class.</li> + * <ul> + * <li>A range of characters can be specified by separating + * the start and end character with '-'.</li> + * <li>The complement of the class can be obtained by using + * '!' as the first character of the class.</li> + * <li>'?', '*' and '[' can occur freely within the class. '-' + * may occur as the first or last character. '!' may occur + * normally in any position other than the first. ']' may occur + * as the first element of the class.</li> + * </ul> + * <li>'?', '*' and '[' may be escaped using a backslash + * character, '\'.</li> + * </ul> + * + * @param attrib the attribute to match. + * @param string the substring to find. + * @return a query expression representing the result of + * matching the pattern against the evaluated + * value of the attribute. This will be serialized + * as the non-public class {@link MatchQueryExp}. + */ + public static QueryExp match(AttributeValueExp attrib, + StringValueExp string) + { + return new MatchQueryExp(attrib, string.getValue()); + } + + /** + * Returns a value expression which evaluates to the result of + * subtracting <code>v2</code> from <code>v1</code>. + * + * @param v1 the left-hand operand. + * @param v2 the right-hand operand. + * @return a value expression which returns the result of + * the subtraction when applied. This will be serialized + * as the non-public class {@link BinaryOpValueExp} + * with an operation of {@link #MINUS}. + */ + public static ValueExp minus(ValueExp v1, ValueExp v2) + { + return new BinaryOpValueExp(MINUS, v1, v2); + } + + /** + * Returns a query expression representing the negation + * of the specified query expression. + * + * @param q the query to negate. + * @return a query expression representing the negation of + * <code>q</code>. This will be serialized as the + * non-public class {@link NotQueryExp}. + */ + public static QueryExp not(QueryExp q) + { + return new NotQueryExp(q); + } + + /** + * Returns a query expression formed from the disjunction + * of the two supplied query expressions. + * + * @param q1 the first query expression. + * @param q2 the second query expression. + * @return a query expression representing q1 || q2. This + * will be serialized as the non-public class + * {@link OrQueryExp}. + */ + public static QueryExp or(QueryExp q1, QueryExp q2) + { + return new OrQueryExp(q1, q2); + } + + /** + * Returns a value expression which evaluates to the result of + * adding <code>v1</code> to <code>v2</code>. + * + * @param v1 the left-hand operand. + * @param v2 the right-hand operand. + * @return a value expression which returns the result of + * the addition when applied. This will be serialized + * as the non-public class {@link BinaryOpValueExp} + * with an operation of {@link #PLUS}. + */ + public static ValueExp plus(ValueExp v1, ValueExp v2) + { + return new BinaryOpValueExp(PLUS, v1, v2); + } + + /** + * Returns a value expression which evaluates to the result of + * multiplying <code>v1</code> by <code>v2</code>. + * + * @param v1 the left-hand operand. + * @param v2 the right-hand operand. + * @return a value expression which returns the result of + * the multiplication when applied. This will be serialized + * as the non-public class {@link BinaryOpValueExp} + * with an operation of {@link #TIMES}. + */ + public static ValueExp times(ValueExp v1, ValueExp v2) + { + return new BinaryOpValueExp(TIMES, v1, v2); + } + + /** + * Returns a value expression wrapping the specified value. + * + * @param val the boolean value to wrap. + * @return a value expression wrapping <code>val</code>. This + * will be serialized as the non-public class + * {@link BooleanValueExp}. + */ + public static ValueExp value(boolean val) + { + return new BooleanValueExp(val); + } + + /** + * Returns a value expression wrapping the specified value. + * + * @param val the double value to wrap. + * @return a value expression wrapping <code>val</code>. This + * will be serialized as the non-public class + * {@link NumericValueExp}. + */ + public static ValueExp value(double val) + { + return new NumericValueExp(val); + } + + /** + * Returns a value expression wrapping the specified value. + * + * @param val the float value to wrap. + * @return a value expression wrapping <code>val</code>. This + * will be serialized as the non-public class + * {@link NumericValueExp}. + */ + public static ValueExp value(float val) + { + return new NumericValueExp(val); + } + + /** + * Returns a value expression wrapping the specified value. + * + * @param val the integer value to wrap. + * @return a value expression wrapping <code>val</code>. This + * will be serialized as the non-public class + * {@link NumericValueExp}. + */ + public static ValueExp value(int val) + { + return new NumericValueExp(val); + } + + /** + * Returns a value expression wrapping the specified value. + * + * @param val the long value to wrap. + * @return a value expression wrapping <code>val</code>. This + * will be serialized as the non-public class + * {@link NumericValueExp}. + */ + public static ValueExp value(long val) + { + return new NumericValueExp(val); + } + + /** + * Returns a value expression wrapping the specified value. + * + * @param val the {@link Number} value to wrap. + * @return a value expression wrapping <code>val</code>. This + * will be serialized as the non-public class + * {@link NumericValueExp}. + */ + public static ValueExp value(Number val) + { + return new NumericValueExp(val); + } + + /** + * Returns a value expression wrapping the specified string. + * + * @param val the {@link String} to wrap. + * @return a {@link StringValueExp} wrapping <code>val</code>. + */ + public static StringValueExp value(String val) + { + return new StringValueExp(val); + } + + /** + * Representation of the conjunction formed using + * {@link #and(QueryExp, QueryExp). + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ + private static final class AndQueryExp + extends QueryEval + implements QueryExp + { + + /** + * Compatible with JDK 1.6 + */ + private static final long serialVersionUID = -1081892073854801359L; + + /** + * The first operand. + */ + private QueryExp exp1; + + /** + * The second operand. + */ + private QueryExp exp2; + + /** + * Constructs a new {@link AndQueryExp} using + * the two specified operands. + * + * @param exp1 the first query expression. + * @param exp2 the second query expression. + */ + public AndQueryExp(QueryExp exp1, QueryExp exp2) + { + this.exp1 = exp1; + this.exp2 = exp2; + } + + /** + * Returns the conjunction of the two query + * expressions. + * + * @param name the {@link ObjectName} to apply + * the query to. + * @return the conjunction of applying the name + * to both operands. + * @throws BadStringOperationException if an invalid string + * operation is used by + * the query. + * @throws BadBinaryOpValueExpException if an invalid expression + * is used by the query. + * @throws BadAttributeValueExpException if an invalid attribute + * is used by the query. + * @throws InvalidApplicationException if the query is applied + * to the wrong type of bean. + */ + public boolean apply(ObjectName name) + throws BadStringOperationException, BadBinaryOpValueExpException, + BadAttributeValueExpException, InvalidApplicationException + { + return exp1.apply(name) && exp2.apply(name); + } + + } + + /** + * Representation of a query that matches an + * attribute's value against a given pattern. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ + private static final class MatchQueryExp + extends QueryEval + implements QueryExp + { + + /** + * Compatible with JDK 1.6 + */ + private static final long serialVersionUID = -7156603696948215014L; + + /** + * The attribute to match against. + */ + private AttributeValueExp exp; + + /** + * The pattern to be matched. + */ + private String pattern; + + /** + * Constructs a new {@link MatchQueryExp} using + * the specified attribute value and pattern. + * + * @param exp the attribute value expression. + * @param pattern the pattern. + */ + public MatchQueryExp(AttributeValueExp exp, + String pattern) + { + this.exp = exp; + this.pattern = pattern; + } + + /** + * Returns the result of matching the attribute + * value against the pattern. + * + * @param name the {@link ObjectName} to apply + * the query to. + * @return the result of the match. + * @throws BadStringOperationException if an invalid string + * operation is used by + * the query. + * @throws BadBinaryOpValueExpException if an invalid expression + * is used by the query. + * @throws BadAttributeValueExpException if an invalid attribute + * is used by the query. + * @throws InvalidApplicationException if the query is applied + * to the wrong type of bean. + */ + public boolean apply(ObjectName name) + throws BadStringOperationException, BadBinaryOpValueExpException, + BadAttributeValueExpException, InvalidApplicationException + { + String val = ((StringValueExp) exp.apply(name)).getValue(); + int valPos = 0; + int fallback = -1; + int fallbackP = -1; + boolean backslash = false; + for (int a = 0; a < pattern.length(); ++a) + { + boolean matched = false; + int next = pattern.codePointAt(a); + if (!backslash) + { + if (next == '?' && valPos < val.length()) + { + ++valPos; + matched = true; + } + else if (next == '*') + { + fallback = valPos; + fallbackP = a; + matched = true; + } + else if (next == '[' && valPos < val.length()) + { + boolean negated = false; + int b = a + 1; + int classChar = pattern.codePointAt(b); + do + { + if (classChar == '!' && b == a + 1) + negated = true; + else if (pattern.codePointAt(b + 1) == '-' && + pattern.codePointAt(b + 2) != ']') + { + if (classChar > pattern.codePointAt(b + 2)) + throw new BadStringOperationException("Invalid range: " + + classChar + " to " + + pattern.codePointAt(b+2)); + for (int c = classChar; c <= pattern.codePointAt(b+2); ++c) + if (val.codePointAt(valPos) == c) + matched = true; + b = b + 2; + } + else if (val.codePointAt(valPos) == classChar) + matched = true; + ++b; + classChar = pattern.codePointAt(b); + } while (classChar != ']'); + if (negated) + matched = !matched; + ++valPos; + a = b; + } + else if (next == '\\') + backslash = true; + else if (valPos < val.length() && next == val.codePointAt(valPos)) + { + matched = true; + ++valPos; + } + } + else + { + backslash = false; + if (valPos < val.length() && next == val.codePointAt(valPos)) + { + matched = true; + ++valPos; + } + } + if (!matched) + if (fallback != -1) + { + ++fallback; + valPos = fallback; + a = fallbackP; + if (valPos == val.length()) + return false; + continue; + } + else + return false; + } + return true; + } + } + + /** + * Representation of the retrieval of an attribute + * value from a certain class for {@link #attr(String,String)}. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ + private static final class QualifiedAttributeValueExp + extends AttributeValueExp + { + + /** + * Compatible with JDK 1.6 + */ + private static final long serialVersionUID = 8832517277410933254L; + + /** + * The name of the class from which the attribute is taken. + */ + private String className; + + /** + * Constructs a new {@link QualifiedAttributeValueExp} using + * the specified class name and attribute name. + * + * @param className the class name. + * @param name the attribute name. + */ + public QualifiedAttributeValueExp(String className, String name) + { + super(name); + this.className = className; + } + + /** + * Applies the {@link AttributeValueExp} to the specified + * management bean by checking that the attribute will be + * obtained from the correct class (by a class to + * {@link MBeanServer#getObjectInstance(ObjectName)} and + * then obtaining the attribute value from the + * {@link MBeanServer}, using it to create a + * {@link StringValueExp}. + * + * @param name the {@link ObjectName} of the bean to obtain + * the value from. + * @return a {@link StringValueExp} containing the result. + * @throws BadStringOperationException if an invalid string + * operation is used by + * the value expression. + * @throws BadBinaryOpValueExpException if an invalid expression + * is used by the value expression. + * @throws BadAttributeValueExpException if an invalid attribute + * is used by the value expression. + * @throws InvalidApplicationException if the value expression is applied + * to the wrong type of bean. + */ + public ValueExp apply(ObjectName name) + throws BadStringOperationException, BadBinaryOpValueExpException, + BadAttributeValueExpException, InvalidApplicationException + { + try + { + if (!(QueryEval.getMBeanServer().getObjectInstance(name).getClassName().equals(className))) + throw new BadAttributeValueExpException("The value is not from " + + "the correct class."); + } + catch (InstanceNotFoundException e) + { + throw (BadAttributeValueExpException) + new BadAttributeValueExpException("The named bean is not registered.").initCause(e); + } + return super.apply(name); + } + + } + + /** + * Representation of the comparison of a value with + * a pair of bounds formed using + * {@link #between(ValueExp, ValueExp, ValueExp). + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ + private static final class BetweenQueryExp + extends QueryEval + implements QueryExp + { + + /** + * Compatible with JDK 1.6 + */ + private static final long serialVersionUID = -2933597532866307444L; + + /** + * The value to compare. + */ + private ValueExp exp1; + + /** + * The lower boundary. + */ + private ValueExp exp2; + + /** + * The upper boundary. + */ + private ValueExp exp3; + + /** + * Constructs a new {@link BetweenQueryExp} using + * the specified comparison value and the given + * bounds. + * + * @param exp1 the value to compare. + * @param exp2 the lower bound. + * @param exp3 the upper bound. + */ + public BetweenQueryExp(ValueExp exp1, ValueExp exp2, + ValueExp exp3) + { + this.exp1 = exp1; + this.exp2 = exp2; + this.exp3 = exp3; + } + + /** + * Returns the result of the comparison between + * the value and the two bounds. + * + * @param name the {@link ObjectName} to apply + * the query to. + * @return the result of the comparison. + * @throws BadStringOperationException if an invalid string + * operation is used by + * the query. + * @throws BadBinaryOpValueExpException if an invalid expression + * is used by the query. + * @throws BadAttributeValueExpException if an invalid attribute + * is used by the query. + * @throws InvalidApplicationException if the query is applied + * to the wrong type of bean. + */ + public boolean apply(ObjectName name) + throws BadStringOperationException, BadBinaryOpValueExpException, + BadAttributeValueExpException, InvalidApplicationException + { + String v1 = exp1.apply(name).toString(); + String v2 = exp2.apply(name).toString(); + String v3 = exp3.apply(name).toString(); + return v1.compareTo(v2) >= 0 && v1.compareTo(v3) <= 0; + } + + } + + /** + * Representation of the retrieval of the name of + * a bean's class for {@link #classattr()}. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ + private static final class ClassAttributeValueExp + extends AttributeValueExp + { + + /** + * Compatible with JDK 1.6 + */ + private static final long serialVersionUID = -1081892073854801359L; + + /** + * Obtains the name of the specified bean's class using a call + * to {@link MBeanServer#getObjectInstance(ObjectName)}. + * + * @param name the {@link ObjectName} of the bean to obtain + * the class name from. + * @return a {@link StringValueExp} containing the result. + * @throws BadStringOperationException if an invalid string + * operation is used by + * the value expression. + * @throws BadBinaryOpValueExpException if an invalid expression + * is used by the value expression. + * @throws BadAttributeValueExpException if an invalid attribute + * is used by the value expression. + * @throws InvalidApplicationException if the value expression is applied + * to the wrong type of bean. + */ + public ValueExp apply(ObjectName name) + throws BadStringOperationException, BadBinaryOpValueExpException, + BadAttributeValueExpException, InvalidApplicationException + { + try + { + return new StringValueExp(QueryEval.getMBeanServer().getObjectInstance(name).getClassName()); + } + catch (InstanceNotFoundException e) + { + throw (BadAttributeValueExpException) + new BadAttributeValueExpException("The named bean is not registered.").initCause(e); + } + } + + } + + /** + * Representation of a binary operation formed using + * {@link #div(ValueExp, ValueExp), {@link #plus(ValueExp,ValueExp)}, + * {@link #minus(ValueExp, ValueExp) or + * {@link #times(ValueExp, ValueExp)}. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ + private static final class BinaryOpValueExp + extends QueryEval + implements ValueExp + { + + /** + * Compatible with JDK 1.6 + */ + private static final long serialVersionUID = 1216286847881456786L; + + /** + * The operation to perform. + */ + private int op; + + /** + * The left-hand operand. + */ + private ValueExp exp1; + + /** + * The right-hand operand. + */ + private ValueExp exp2; + + /** + * Constructs a new {@link BinaryOpValueExp} using + * the specified operation and the two values supplied. + * + * @param op the operation to perform. + * @param exp1 the left-hand operand. + * @param exp2 the right-hand operand. + */ + public BinaryOpValueExp(int op, ValueExp exp1, ValueExp exp2) + { + this.op = op; + this.exp1 = exp1; + this.exp2 = exp2; + } + + /** + * Returns the result of performing the operation on + * <code>exp1</code> and <code>exp2</code>. + * + * @param name the {@link ObjectName} to apply + * the query to. + * @return the result of the operation. + * @throws BadStringOperationException if an invalid string + * operation is used by + * the query. + * @throws BadBinaryOpValueExpException if an invalid expression + * is used by the query. + * @throws BadAttributeValueExpException if an invalid attribute + * is used by the query. + * @throws InvalidApplicationException if the query is applied + * to the wrong type of bean. + */ + public ValueExp apply(ObjectName name) + throws BadStringOperationException, BadBinaryOpValueExpException, + BadAttributeValueExpException, InvalidApplicationException + { + NumericValueExp v1 = (NumericValueExp) exp1.apply(name); + NumericValueExp v2 = (NumericValueExp) exp2.apply(name); + switch (op) + { + case PLUS: + return v1.plus(v2); + case MINUS: + return v1.minus(v2); + case TIMES: + return v1.times(v2); + case DIV: + return v1.div(v2); + default: + throw new BadBinaryOpValueExpException(this); + } + } + + /** + * Returns a textual representation of the operation. + * + * @return a textual version of the operation. + */ + public String toString() + { + String opS; + switch (op) + { + case PLUS: + opS = "+"; + break; + case MINUS: + opS = "-"; + break; + case TIMES: + opS = "x"; + break; + case DIV: + opS = "/"; + break; + default: + opS = "?"; + } + return exp1 + " " + opS + " " + exp2; + } + } + + /** + * Representation of a binary operation formed using + * {@link #eq(ValueExp, ValueExp), {@link #geq(ValueExp, ValueExp)}, + * {@link #leq(ValueExp, ValueExp), {@link #gt(ValueExp, ValueExp)} + * or {@link #lt(ValueExp, ValueExp)}. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ + private static final class BinaryRelQueryExp + extends QueryEval + implements QueryExp + { + + /** + * Compatible with JDK 1.6 + */ + private static final long serialVersionUID = -5690656271650491000L; + + /** + * The operation to perform. + */ + private int relOp; + + /** + * The left-hand operand. + */ + private ValueExp exp1; + + /** + * The right-hand operand. + */ + private ValueExp exp2; + + /** + * Constructs a new {@link BinaryRelQueryExp} using + * the specified operation and the two values supplied. + * + * @param relOp the operation to perform. + * @param exp1 the left-hand operand. + * @param exp2 the right-hand operand. + */ + public BinaryRelQueryExp(int relOp, ValueExp exp1, ValueExp exp2) + { + this.relOp = relOp; + this.exp1 = exp1; + this.exp2 = exp2; + } + + /** + * Returns the result of performing the operation on + * <code>exp1</code> and <code>exp2</code>. + * + * @param name the {@link ObjectName} to apply + * the query to. + * @return the result of the comparison. + * @throws BadStringOperationException if an invalid string + * operation is used by + * the query. + * @throws BadBinaryOpValueExpException if an invalid expression + * is used by the query. + * @throws BadAttributeValueExpException if an invalid attribute + * is used by the query. + * @throws InvalidApplicationException if the query is applied + * to the wrong type of bean. + */ + public boolean apply(ObjectName name) + throws BadStringOperationException, BadBinaryOpValueExpException, + BadAttributeValueExpException, InvalidApplicationException + { + String v1 = exp1.apply(name).toString(); + String v2 = exp2.apply(name).toString(); + switch (relOp) + { + case EQ: + return v1.equals(v2); + case GT: + return v1.compareTo(v2) > 0; + case GE: + return v1.compareTo(v2) >= 0; + case LE: + return v1.compareTo(v2) <= 0; + case LT: + return v1.compareTo(v2) < 0; + default: + throw new BadStringOperationException("Invalid operator: " + relOp); + } + } + + /** + * Returns a textual representation of the operation. + * + * @return a textual version of the operation. + */ + public String toString() + { + String op; + switch (relOp) + { + case EQ: + op = "="; + break; + case GT: + op = ">"; + break; + case GE: + op = ">="; + break; + case LE: + op = "<="; + break; + case LT: + op = "<"; + break; + default: + op = "?"; + } + return exp1 + " " + op + " " + exp2; + } + } + + /** + * Representation of the comparison of a value with + * the members of a list formed using + * {@link #in(ValueExp, ValueExp[]). + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ + private static final class InQueryExp + extends QueryEval + implements QueryExp + { + + /** + * Compatible with JDK 1.6 + */ + private static final long serialVersionUID = -5801329450358952434L; + + /** + * The value to look for. + */ + private ValueExp val; + + /** + * The array to search. + */ + private ValueExp[] valueList; + + /** + * Constructs a new {@link InQueryExp} using + * the specified comparison value and the given + * list. + * + * @param val the value to compare. + * @param valueList the list of values. + */ + public InQueryExp(ValueExp val, ValueExp[] valueList) + { + this.val = val; + this.valueList = valueList; + } + + /** + * Returns the result of the comparison between + * the value and the list of allowed values. + * + * @param name the {@link ObjectName} to apply + * the query to. + * @return the result of the comparison. + * @throws BadStringOperationException if an invalid string + * operation is used by + * the query. + * @throws BadBinaryOpValueExpException if an invalid expression + * is used by the query. + * @throws BadAttributeValueExpException if an invalid attribute + * is used by the query. + * @throws InvalidApplicationException if the query is applied + * to the wrong type of bean. + */ + public boolean apply(ObjectName name) + throws BadStringOperationException, BadBinaryOpValueExpException, + BadAttributeValueExpException, InvalidApplicationException + { + String v = val.apply(name).toString(); + for (ValueExp vl : valueList) + if (v.equals(vl.apply(name).toString())) + return true; + return false; + } + + } + + /** + * Representation of the inheritance check on a + * bean for {@link #isInstanceOf(StringValueExp)}. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.6 + */ + private static final class InstanceOfQueryExp + extends QueryEval + implements QueryExp + { + + /** + * Compatible with JDK 1.6 + */ + private static final long serialVersionUID = -1081892073854801359L; + + /** + * The name of the class from which the attribute is taken. + */ + private StringValueExp classNameValue; + + /** + * Constructs a new {@link InstanceOfQueryExp} using + * the specified class name. + * + * @param classNameValue the class name. + */ + public InstanceOfQueryExp(StringValueExp classNameValue) + { + this.classNameValue = classNameValue; + } + + /** + * Checks that the bean specified by the supplied + * {@link ObjectName} is of the correct class + * using {@link MBeanServer#isInstanceOf(ObjectName,String)}. + * where the string is obtained by evaluating + * <code>classNameValue</code>. + * + * @param name the {@link ObjectName} of the bean to obtain + * the value from. + * @return true if the bean is an instance of the class. + * @throws BadStringOperationException if an invalid string + * operation is used by + * the value expression. + * @throws BadBinaryOpValueExpException if an invalid expression + * is used by the value expression. + * @throws BadAttributeValueExpException if an invalid attribute + * is used by the value expression. + * @throws InvalidApplicationException if the value expression is applied + * to the wrong type of bean. + */ + public boolean apply(ObjectName name) + throws BadStringOperationException, BadBinaryOpValueExpException, + BadAttributeValueExpException, InvalidApplicationException + { + try + { + String className = ((StringValueExp) + classNameValue.apply(name)).getValue(); + return QueryEval.getMBeanServer().isInstanceOf(name, className); + } + catch (InstanceNotFoundException e) + { + throw (BadAttributeValueExpException) + new BadAttributeValueExpException("The named bean is not registered.").initCause(e); + } + } + + } + + /** + * Representation of the negation of a query formed using + * {@link #not(QueryExp). + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ + private static final class NotQueryExp + extends QueryEval + implements QueryExp + { + + /** + * Compatible with JDK 1.6 + */ + private static final long serialVersionUID = 5269643775896723397L; + + /** + * The expression to negate. + */ + private QueryExp exp; + + /** + * Constructs a new {@link NotQueryExp} using + * the specified query expression. + * + * @param exp the expression to negate. + */ + public NotQueryExp(QueryExp exp) + { + this.exp = exp; + } + + /** + * Returns the result of the negation. + * + * @param name the {@link ObjectName} to apply + * the query to. + * @return the result of the negation. + * @throws BadStringOperationException if an invalid string + * operation is used by + * the query. + * @throws BadBinaryOpValueExpException if an invalid expression + * is used by the query. + * @throws BadAttributeValueExpException if an invalid attribute + * is used by the query. + * @throws InvalidApplicationException if the query is applied + * to the wrong type of bean. + */ + public boolean apply(ObjectName name) + throws BadStringOperationException, BadBinaryOpValueExpException, + BadAttributeValueExpException, InvalidApplicationException + { + return !(exp.apply(name)); + } + + } + + /** + * Representation of the disjunction formed using + * {@link #or(QueryExp, QueryExp). + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ + private static final class OrQueryExp + extends QueryEval + implements QueryExp + { + + /** + * Compatible with JDK 1.6 + */ + private static final long serialVersionUID = 2962973084421716523L; + + /** + * The first operand. + */ + private QueryExp exp1; + + /** + * The second operand. + */ + private QueryExp exp2; + + /** + * Constructs a new {@link OrQueryExp} using + * the two specified operands. + * + * @param exp1 the first query expression. + * @param exp2 the second query expression. + */ + public OrQueryExp(QueryExp exp1, QueryExp exp2) + { + this.exp1 = exp1; + this.exp2 = exp2; + } + + /** + * Returns the disjunction of the two query + * expressions. + * + * @param name the {@link ObjectName} to apply + * the query to. + * @return the disjunction of applying the name + * to both operands. + * @throws BadStringOperationException if an invalid string + * operation is used by + * the query. + * @throws BadBinaryOpValueExpException if an invalid expression + * is used by the query. + * @throws BadAttributeValueExpException if an invalid attribute + * is used by the query. + * @throws InvalidApplicationException if the query is applied + * to the wrong type of bean. + */ + public boolean apply(ObjectName name) + throws BadStringOperationException, BadBinaryOpValueExpException, + BadAttributeValueExpException, InvalidApplicationException + { + return exp1.apply(name) || exp2.apply(name); + } + + } + + /** + * Representation of a boolean being used as an argument + * to a relational constraint, formed using + * {@link #value(boolean)}. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ + private static final class BooleanValueExp + extends QueryEval + implements ValueExp + { + + /** + * Compatible with JDK 1.6 + */ + private static final long serialVersionUID = 7754922052666594581L; + + /** + * The boolean value. + */ + private boolean val; + + /** + * Constructs a new {@link BooleanValueExp} using the + * specified value. + * + * @param val the boolean value used for this expression. + */ + public BooleanValueExp(boolean val) + { + this.val = val; + } + + /** + * Applies the {@link BooleanValueExp} to the specified + * management bean by simply returning the value. + * + * @param name the {@link ObjectName} of the bean. + * @return the {@link BooleanValueExp} itself. + * @throws BadStringOperationException if an invalid string + * operation is used by + * the value expression. + * @throws BadBinaryOpValueExpException if an invalid expression + * is used by the value expression. + * @throws BadAttributeValueExpException if an invalid attribute + * is used by the value expression. + * @throws InvalidApplicationException if the value expression is applied + * to the wrong type of bean. + */ + public ValueExp apply(ObjectName name) + throws BadStringOperationException, BadBinaryOpValueExpException, + BadAttributeValueExpException, InvalidApplicationException + { + return this; + } + + /** + * Returns the value as a string. + * + * @return the value in textual form. + */ + public String toString() + { + return Boolean.toString(val); + } + + } + + /** + * Representation of a number being used as an argument + * to a relational constraint, formed using + * {@link #value(double)}, {@link #value(float)}, + * {@link #value(int)}, {@link #value(long)} or + * {@link #value(Number)}. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ + private static final class NumericValueExp + extends QueryEval + implements ValueExp + { + + /** + * Compatible with JDK 1.6 + */ + private static final long serialVersionUID = -4679739485102359104L; + + /** + * The numeric value. + */ + private Number val; + + /** + * Constructs a new {@link NumericValueExp} using the + * specified value. + * + * @param val the numeric value used for this expression. + */ + public NumericValueExp(Number val) + { + this.val = val; + } + + /** + * Applies the {@link NumericValueExp} to the specified + * management bean by simply returning the value. + * + * @param name the {@link ObjectName} of the bean. + * @return the {@link NumericValueExp} itself. + * @throws BadStringOperationException if an invalid string + * operation is used by + * the value expression. + * @throws BadBinaryOpValueExpException if an invalid expression + * is used by the value expression. + * @throws BadAttributeValueExpException if an invalid attribute + * is used by the value expression. + * @throws InvalidApplicationException if the value expression is applied + * to the wrong type of bean. + */ + public ValueExp apply(ObjectName name) + throws BadStringOperationException, BadBinaryOpValueExpException, + BadAttributeValueExpException, InvalidApplicationException + { + return this; + } + + /** + * Returns the value. + */ + public Number getValue() + { + return val; + } + + /** + * Returns the value as a string. + * + * @return the value in textual form. + */ + public String toString() + { + return val.toString(); + } + + /** + * Return the result of adding the specified + * {@link NumericValueExp} to this one. + * + * @param o the value to add. + * @return the result of the addition. + */ + public NumericValueExp plus(NumericValueExp o) + { + Number v = o.getValue(); + if (val instanceof Double) + { + double d = val.doubleValue(); + if (v instanceof Double) + return new NumericValueExp(d + v.doubleValue()); + else if (v instanceof Float) + return new NumericValueExp(d + v.floatValue()); + else if (v instanceof Long) + return new NumericValueExp(d + v.longValue()); + else + return new NumericValueExp(d + v.intValue()); + } + else if (val instanceof Float) + { + float f = val.floatValue(); + if (v instanceof Double) + return new NumericValueExp(f + v.doubleValue()); + else if (v instanceof Float) + return new NumericValueExp(f + v.floatValue()); + else if (v instanceof Long) + return new NumericValueExp(f + v.longValue()); + else + return new NumericValueExp(f + v.intValue()); + } + else if (val instanceof Long) + { + long l = val.longValue(); + if (v instanceof Double) + return new NumericValueExp(l + v.doubleValue()); + else if (v instanceof Float) + return new NumericValueExp(l + v.floatValue()); + else if (v instanceof Long) + return new NumericValueExp(l + v.longValue()); + else + return new NumericValueExp(l + v.intValue()); + } + int i = val.intValue(); + if (v instanceof Double) + return new NumericValueExp(i + v.doubleValue()); + else if (v instanceof Float) + return new NumericValueExp(i + v.floatValue()); + else if (v instanceof Long) + return new NumericValueExp(i + v.longValue()); + else + return new NumericValueExp(i + v.intValue()); + } + + /** + * Return New NumericValueExp(the result of subtracting the specified + * {@link NumericValueExp} from this one. + * + * @param o the value to subtract. + * @return new NumericValueExp(the result of the subtraction. + */ + public NumericValueExp minus(NumericValueExp o) + { + Number v = o.getValue(); + if (val instanceof Double) + { + double d = val.doubleValue(); + if (v instanceof Double) + return new NumericValueExp(d - v.doubleValue()); + else if (v instanceof Float) + return new NumericValueExp(d - v.floatValue()); + else if (v instanceof Long) + return new NumericValueExp(d - v.longValue()); + else + return new NumericValueExp(d - v.intValue()); + } + else if (val instanceof Float) + { + float f = val.floatValue(); + if (v instanceof Double) + return new NumericValueExp(f - v.doubleValue()); + else if (v instanceof Float) + return new NumericValueExp(f - v.floatValue()); + else if (v instanceof Long) + return new NumericValueExp(f - v.longValue()); + else + return new NumericValueExp(f - v.intValue()); + } + else if (val instanceof Long) + { + long l = val.longValue(); + if (v instanceof Double) + return new NumericValueExp(l - v.doubleValue()); + else if (v instanceof Float) + return new NumericValueExp(l - v.floatValue()); + else if (v instanceof Long) + return new NumericValueExp(l - v.longValue()); + else + return new NumericValueExp(l - v.intValue()); + } + int i = val.intValue(); + if (v instanceof Double) + return new NumericValueExp(i - v.doubleValue()); + else if (v instanceof Float) + return new NumericValueExp(i - v.floatValue()); + else if (v instanceof Long) + return new NumericValueExp(i - v.longValue()); + else + return new NumericValueExp(i - v.intValue()); + } + + /** + * Return New NumericValueExp(the result of multiplying the specified + * {@link NumericValueExp} to this one. + * + * @param o the value to multiply by. + * @return new NumericValueExp(the result of the multiplication. + */ + public NumericValueExp times(NumericValueExp o) + { + Number v = o.getValue(); + if (val instanceof Double) + { + double d = val.doubleValue(); + if (v instanceof Double) + return new NumericValueExp(d * v.doubleValue()); + else if (v instanceof Float) + return new NumericValueExp(d * v.floatValue()); + else if (v instanceof Long) + return new NumericValueExp(d * v.longValue()); + else + return new NumericValueExp(d * v.intValue()); + } + else if (val instanceof Float) + { + float f = val.floatValue(); + if (v instanceof Double) + return new NumericValueExp(f * v.doubleValue()); + else if (v instanceof Float) + return new NumericValueExp(f * v.floatValue()); + else if (v instanceof Long) + return new NumericValueExp(f * v.longValue()); + else + return new NumericValueExp(f * v.intValue()); + } + else if (val instanceof Long) + { + long l = val.longValue(); + if (v instanceof Double) + return new NumericValueExp(l * v.doubleValue()); + else if (v instanceof Float) + return new NumericValueExp(l * v.floatValue()); + else if (v instanceof Long) + return new NumericValueExp(l * v.longValue()); + else + return new NumericValueExp(l * v.intValue()); + } + int i = val.intValue(); + if (v instanceof Double) + return new NumericValueExp(i * v.doubleValue()); + else if (v instanceof Float) + return new NumericValueExp(i * v.floatValue()); + else if (v instanceof Long) + return new NumericValueExp(i * v.longValue()); + else + return new NumericValueExp(i * v.intValue()); + } + + /** + * Return New NumericValueExp(the result of dividing this + * number by value of the specified + * {@link NumericValueExp}. + * + * @param o the value to divide by. + * @return new NumericValueExp(the result of the division. + */ + public NumericValueExp div(NumericValueExp o) + { + Number v = o.getValue(); + if (val instanceof Double) + { + double d = val.doubleValue(); + if (v instanceof Double) + return new NumericValueExp(d / v.doubleValue()); + else if (v instanceof Float) + return new NumericValueExp(d / v.floatValue()); + else if (v instanceof Long) + return new NumericValueExp(d / v.longValue()); + else + return new NumericValueExp(d / v.intValue()); + } + else if (val instanceof Float) + { + float f = val.floatValue(); + if (v instanceof Double) + return new NumericValueExp(f / v.doubleValue()); + else if (v instanceof Float) + return new NumericValueExp(f / v.floatValue()); + else if (v instanceof Long) + return new NumericValueExp(f / v.longValue()); + else + return new NumericValueExp(f / v.intValue()); + } + else if (val instanceof Long) + { + long l = val.longValue(); + if (v instanceof Double) + return new NumericValueExp(l / v.doubleValue()); + else if (v instanceof Float) + return new NumericValueExp(l / v.floatValue()); + else if (v instanceof Long) + return new NumericValueExp(l / v.longValue()); + else + return new NumericValueExp(l / v.intValue()); + } + int i = val.intValue(); + if (v instanceof Double) + return new NumericValueExp(i / v.doubleValue()); + else if (v instanceof Float) + return new NumericValueExp(i / v.floatValue()); + else if (v instanceof Long) + return new NumericValueExp(i / v.longValue()); + else + return new NumericValueExp(i / v.intValue()); + } + + } + +} + diff --git a/libjava/classpath/javax/management/QueryEval.java b/libjava/classpath/javax/management/QueryEval.java new file mode 100644 index 0000000..375270a --- /dev/null +++ b/libjava/classpath/javax/management/QueryEval.java @@ -0,0 +1,95 @@ +/* QueryEval.java -- An evaluation context for a MBean server query. + Copyright (C) 2007 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 javax.management; + +import java.io.Serializable; + +/** + * Represents the evaluation context of a {@link MBeanServer} + * query by retaining the server used on a thread-by-thread + * basis. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public class QueryEval + implements Serializable +{ + + /** + * Compatible with JDK 1.5 + */ + private static final long serialVersionUID = 2675899265640874796L; + + /** + * Stores the server used, on a + * thread-by-thread basis. + */ + private static InheritableThreadLocal<MBeanServer> server = + new InheritableThreadLocal<MBeanServer>(); + + /** + * Returns the {@link MBeanServer} last supplied to the + * {@link #setMBeanServer(MBeanServer)} method. If this method + * has not been called for this thread, then the value will be + * inherited from any parent thread on which the method has + * been called. If the method has never been called, then + * <code>null</code> is returned. + * + * @return the server. + * @see #setMBeanServer(MBeanServer) + */ + public static MBeanServer getMBeanServer() + { + return server.get(); + } + + /** + * Sets the {@link MBeanServer} on which the query will be + * performed. This value is inherited automatically by + * child threads. This method is only non-static for historical + * reasons; it makes no use of instance-related values. + * + * @param svr the server to use. + */ + public void setMBeanServer(MBeanServer svr) + { + server.set(svr); + } + +} diff --git a/libjava/classpath/javax/management/StandardMBean.java b/libjava/classpath/javax/management/StandardMBean.java index b31436c..3748384 100644 --- a/libjava/classpath/javax/management/StandardMBean.java +++ b/libjava/classpath/javax/management/StandardMBean.java @@ -106,10 +106,19 @@ public class StandardMBean } catch (ClassNotFoundException e) { - throw (NotCompliantMBeanException) - (new NotCompliantMBeanException("An interface, " + className + - "MBean, for the class " + className + - " was not found.").initCause(e)); + for (Class<?> nextIface : getClass().getInterfaces()) + { + if (JMX.isMXBeanInterface(nextIface)) + { + iface = nextIface; + break; + } + } + if (iface == null) + throw (NotCompliantMBeanException) + (new NotCompliantMBeanException("An interface for the class " + + className + + " was not found.").initCause(e)); } } if (!(iface.isInstance(this))) @@ -140,18 +149,28 @@ public class StandardMBean throw new IllegalArgumentException("The specified implementation is null."); if (iface == null) { - String className = impl.getClass().getName(); + Class<?> implClass = impl.getClass(); + String className = implClass.getName(); try { this.iface = Class.forName(className + "MBean", true, - impl.getClass().getClassLoader()); + implClass.getClassLoader()); } catch (ClassNotFoundException e) { - throw (NotCompliantMBeanException) - (new NotCompliantMBeanException("An interface, " + className + - "MBean, for the class " + className + - " was not found.").initCause(e)); + for (Class<?> nextIface : implClass.getInterfaces()) + { + if (JMX.isMXBeanInterface(nextIface)) + { + this.iface = nextIface; + break; + } + } + if (this.iface == null) + throw (NotCompliantMBeanException) + (new NotCompliantMBeanException("An interface for the class " + + className + + " was not found.").initCause(e)); } } else @@ -753,19 +772,30 @@ public class StandardMBean public Object invoke(String name, Object[] params, String[] signature) throws MBeanException, ReflectionException { - Class[] sigTypes = new Class[signature.length]; + if (name.startsWith("get") || name.startsWith("is") || + name.startsWith("set")) + throw new ReflectionException(new NoSuchMethodException(), + "Invocation of an attribute " + + "method is disallowed."); ClassLoader loader = getClass().getClassLoader(); - for (int a = 0; a < signature.length; ++a) - try - { - sigTypes[a] = Class.forName(signature[a], true, loader); - } - catch (ClassNotFoundException e) - { - throw new ReflectionException(e, "The class, " + signature[a] + - ", in the method signature " + - "could not be loaded."); - } + Class[] sigTypes; + if (signature != null) + { + sigTypes = new Class[signature.length]; + for (int a = 0; a < signature.length; ++a) + try + { + sigTypes[a] = Class.forName(signature[a], true, loader); + } + catch (ClassNotFoundException e) + { + throw new ReflectionException(e, "The class, " + signature[a] + + ", in the method signature " + + "could not be loaded."); + } + } + else + sigTypes = null; Method method; try { @@ -824,23 +854,12 @@ public class StandardMBean throws AttributeNotFoundException, InvalidAttributeValueException, MBeanException, ReflectionException { - Method setter; String name = attribute.getName(); - try - { - setter = iface.getMethod("set" + - name.substring(0, 1).toUpperCase() + - name.substring(1), null); - } - catch (NoSuchMethodException e) - { - throw ((AttributeNotFoundException) - new AttributeNotFoundException("The attribute, " + name + - ", was not found.").initCause(e)); - } + String attName = name.substring(0, 1).toUpperCase() + name.substring(1); + Object val = attribute.getValue(); try { - setter.invoke(impl, new Object[] { attribute.getValue() }); + getMutator(attName, val.getClass()).invoke(impl, new Object[] { val }); } catch (IllegalAccessException e) { @@ -855,8 +874,8 @@ public class StandardMBean } catch (InvocationTargetException e) { - throw new MBeanException((Exception) e.getCause(), "The getter of " - + name + " threw an exception"); + throw new MBeanException(e, "The getter of " + name + + " threw an exception"); } } @@ -925,4 +944,142 @@ public class StandardMBean this.impl = impl; } + /** + * Returns the mutator method for a particular attribute name + * with a parameter type matching that of the given value. + * + * @param name the name of the attribute. + * @param type the type of the parameter. + * @return the appropriate mutator method. + * @throws AttributeNotFoundException if a method can't be found. + */ + private Method getMutator(String name, Class<?> type) + throws AttributeNotFoundException + { + String mutator = "set" + name; + Exception ex = null; + try + { + return iface.getMethod(mutator, type); + } + catch (NoSuchMethodException e) + { + /* Ignored; we'll try harder instead */ + ex = e; + } + /* Special cases */ + if (type == Boolean.class) + try + { + return iface.getMethod(mutator, Boolean.TYPE); + } + catch (NoSuchMethodException e) + { + throw ((AttributeNotFoundException) + new AttributeNotFoundException("The attribute, " + name + + ", was not found.").initCause(e)); + } + if (type == Byte.class) + try + { + return iface.getMethod(mutator, Byte.TYPE); + } + catch (NoSuchMethodException e) + { + throw ((AttributeNotFoundException) + new AttributeNotFoundException("The attribute, " + name + + ", was not found.").initCause(e)); + } + if (type == Character.class) + try + { + return iface.getMethod(mutator, Character.TYPE); + } + catch (NoSuchMethodException e) + { + throw ((AttributeNotFoundException) + new AttributeNotFoundException("The attribute, " + name + + ", was not found.").initCause(e)); + } + if (type == Double.class) + try + { + return iface.getMethod(mutator, Double.TYPE); + } + catch (NoSuchMethodException e) + { + throw ((AttributeNotFoundException) + new AttributeNotFoundException("The attribute, " + name + + ", was not found.").initCause(e)); + } + if (type == Float.class) + try + { + return iface.getMethod(mutator, Float.TYPE); + } + catch (NoSuchMethodException e) + { + throw ((AttributeNotFoundException) + new AttributeNotFoundException("The attribute, " + name + + ", was not found.").initCause(e)); + } + if (type == Integer.class) + try + { + return iface.getMethod(mutator, Integer.TYPE); + } + catch (NoSuchMethodException e) + { + throw ((AttributeNotFoundException) + new AttributeNotFoundException("The attribute, " + name + + ", was not found.").initCause(e)); + } + if (type == Long.class) + try + { + return iface.getMethod(mutator, Long.TYPE); + } + catch (NoSuchMethodException e) + { + throw ((AttributeNotFoundException) + new AttributeNotFoundException("The attribute, " + name + + ", was not found.").initCause(e)); + } + if (type == Short.class) + try + { + return iface.getMethod(mutator, Short.TYPE); + } + catch (NoSuchMethodException e) + { + throw ((AttributeNotFoundException) + new AttributeNotFoundException("The attribute, " + name + + ", was not found.").initCause(e)); + } + /* Superclasses and interfaces */ + for (Class<?> i : type.getInterfaces()) + try + { + return getMutator(name, i); + } + catch (AttributeNotFoundException e) + { + ex = e; + } + Class<?> sclass = type.getSuperclass(); + if (sclass != null && sclass != Object.class) + try + { + return getMutator(name, sclass); + } + catch (AttributeNotFoundException e) + { + ex = e; + } + /* If we get this far, give up */ + throw ((AttributeNotFoundException) + new AttributeNotFoundException("The attribute, " + name + + ", was not found.").initCause(ex)); + } + } diff --git a/libjava/classpath/javax/management/StringValueExp.java b/libjava/classpath/javax/management/StringValueExp.java new file mode 100644 index 0000000..f3ce00b --- /dev/null +++ b/libjava/classpath/javax/management/StringValueExp.java @@ -0,0 +1,133 @@ +/* StringValueExp.java -- Represents strings to be passed to queries. + Copyright (C) 2007 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 javax.management; + +/** + * Represents a string being used as an argument + * to a relational constraint. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public class StringValueExp + implements ValueExp +{ + + /** + * Compatible with JDK 1.5 + */ + private static final long serialVersionUID = -3256390509806284044L; + + /** + * The string value. + */ + private String val; + + /** + * Constructs a new {@link StringValueExp}. + */ + public StringValueExp() + { + } + + /** + * Constructs a new {@link StringValueExp} using the + * specified value. + * + * @param val the string value used for this expression. + */ + public StringValueExp(String val) + { + this.val = val; + } + + /** + * Applies the {@link StringValueExp} to the specified + * management bean by simply returning the value. + * + * @param name the {@link ObjectName} of the bean. + * @return the {@link StringValueExp} itself. + * @throws BadStringOperationException if an invalid string + * operation is used by + * the value expression. + * @throws BadBinaryOpValueExpException if an invalid expression + * is used by the value expression. + * @throws BadAttributeValueExpException if an invalid attribute + * is used by the value expression. + * @throws InvalidApplicationException if the value expression is applied + * to the wrong type of bean. + */ + public ValueExp apply(ObjectName name) + throws BadStringOperationException, BadBinaryOpValueExpException, + BadAttributeValueExpException, InvalidApplicationException + { + return this; + } + + /** + * Returns the value. + * + * @return the value. + */ + public String getValue() + { + return val; + } + + /** + * Sets the {@link MBeanServer} on which the query + * will be performed. + * + * @param server the new server. + */ + public void setMBeanServer(MBeanServer server) + { + /* This seems to do nothing any more */ + } + + /** + * Returns the value in quotes. + * + * @return the value (quoted). + */ + public String toString() + { + return "'" + val + "'"; + } + +} diff --git a/libjava/classpath/javax/management/loading/ClassLoaderRepository.java b/libjava/classpath/javax/management/loading/ClassLoaderRepository.java index e2c8b7c..2526d52 100644 --- a/libjava/classpath/javax/management/loading/ClassLoaderRepository.java +++ b/libjava/classpath/javax/management/loading/ClassLoaderRepository.java @@ -71,7 +71,7 @@ public interface ClassLoaderRepository * @throws ClassNotFoundException if all the class loaders fail * to load the class. */ - Class loadClass(String name) + Class<?> loadClass(String name) throws ClassNotFoundException; /** @@ -102,7 +102,7 @@ public interface ClassLoaderRepository * @throws ClassNotFoundException if all the class loaders fail * to load the class. */ - Class loadClassBefore(ClassLoader stop, String name) + Class<?> loadClassBefore(ClassLoader stop, String name) throws ClassNotFoundException; /** @@ -132,7 +132,7 @@ public interface ClassLoaderRepository * @throws ClassNotFoundException if all the class loaders fail * to load the class. */ - Class loadClassWithout(ClassLoader exclude, String name) + Class<?> loadClassWithout(ClassLoader exclude, String name) throws ClassNotFoundException; } diff --git a/libjava/classpath/javax/management/openmbean/ArrayType.java b/libjava/classpath/javax/management/openmbean/ArrayType.java index d2fc398..42f8062 100644 --- a/libjava/classpath/javax/management/openmbean/ArrayType.java +++ b/libjava/classpath/javax/management/openmbean/ArrayType.java @@ -1,5 +1,5 @@ /* ArrayType.java -- Open type descriptor for an array. - Copyright (C) 2006 Free Software Foundation, Inc. + Copyright (C) 2006, 2007 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -40,6 +40,8 @@ package javax.management.openmbean; import java.lang.reflect.Array; import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; /** * The open type descriptor for arrays of open data values. @@ -47,8 +49,8 @@ import java.util.Arrays; * @author Andrew John Hughes (gnu_andrew@member.fsf.org) * @since 1.5 */ -public class ArrayType - extends OpenType +public class ArrayType<T> + extends OpenType<T> { /** @@ -64,7 +66,12 @@ public class ArrayType /** * The element type of arrays of this type. */ - private OpenType elementType; + private OpenType<?> elementType; + + /** + * True if this type represents a primitive array. + */ + private boolean primitiveArray; /** * The hash code of this instance. @@ -77,19 +84,183 @@ public class ArrayType private transient String string; /** + * A cache of {@link ArrayType} instances created + * by {@link #getArrayType(OpenType)}. + */ + private static final Map<OpenType<?>,ArrayType<?>> cache = + new HashMap<OpenType<?>,ArrayType<?>>(); + + /** + * A cache of {@link ArrayType} instances created + * by {@link #getPrimitiveArrayType(Class)}. + */ + private static final Map<Class<?>,ArrayType<?>> primCache = + new HashMap<Class<?>,ArrayType<?>>(); + + /** * Returns the class name of the array, given the element * class name and its dimensions. * - * @param className the name of the class used by the - * array's elements. + * @param elementType the type of the array's elements. * @param dim the dimensions of the array. + * @param primitive true if this should be a primitive array. * @return the array's class name. + * @throws OpenDataException if the class name does not reference + * a loadable class. */ - private static String getArrayClassName(String className, int dim) + private static final String getArrayClassName(OpenType<?> elementType, + int dim, + boolean primitive) + throws OpenDataException { - char[] brackets = new char[dim]; - Arrays.fill(brackets, '['); - return String.valueOf(brackets) + "L" + className; + Class<?> type; + if (primitive) + type = getPrimitiveTypeClass((SimpleType<?>) elementType); + else + { + String className = elementType.getClassName(); + try + { + type = Class.forName(className); + } + catch (ClassNotFoundException e) + { + throw new OpenDataException("The class name, " + className + + ", is unavailable."); + } + } + while (type.isArray()) + type = type.getComponentType(); + return + Array.newInstance(type, + new int[getDimensions(elementType, dim)]).getClass().getName(); + } + + /** + * Returns the dimensions of the new {@link ArrayType}, + * based on whether the given element type is already an + * {@link ArrayType} or not. + * + * @param elementType the type of the array. + * @param dim the proposed dimensions. + * @return the resultant dimensions. + * @throws IllegalArgumentException if <code>dim</code> is less than 1. + */ + private static final int getDimensions(OpenType<?> elementType, + int dim) + { + if (dim < 1) + throw new IllegalArgumentException("Dimensions must be greater " + + "than or equal to 1."); + if (elementType instanceof ArrayType) + return dim + ((ArrayType) elementType).getDimension(); + return dim; + } + + /** + * Returns the appropriate primitive type name, given the + * corresponding wrapper class. + * + * @param type the type to convert. + * @return the corresponding primitive type. + * @throws OpenDataException if {@code type} is not a valid + * {@link Class} for a primitive type. + * + */ + private static final SimpleType<?> getPrimitiveType(Class<?> type) + throws OpenDataException + { + if (type.equals(Boolean.TYPE)) + return SimpleType.BOOLEAN; + if (type.equals(Byte.TYPE)) + return SimpleType.BYTE; + if (type.equals(Character.TYPE)) + return SimpleType.CHARACTER; + if (type.equals(Double.TYPE)) + return SimpleType.DOUBLE; + if (type.equals(Float.TYPE)) + return SimpleType.FLOAT; + if (type.equals(Integer.TYPE)) + return SimpleType.INTEGER; + if (type.equals(Long.TYPE)) + return SimpleType.LONG; + if (type.equals(Short.TYPE)) + return SimpleType.SHORT; + if (type.equals(Void.TYPE)) + return SimpleType.VOID; + throw new OpenDataException(type + " is not a primitive type."); + } + + /** + * Returns the appropriate primitive type name, given the + * corresponding wrapper class. + * + * @param type the type to convert. + * @return the corresponding primitive type. + * @throws OpenDataException if {@code type} is not a valid + * {@link SimpleType} for a primitive type. + * + */ + private static final Class<?> getPrimitiveTypeClass(SimpleType<?> type) + throws OpenDataException + { + if (type.equals(SimpleType.BOOLEAN)) + return Boolean.TYPE; + if (type.equals(SimpleType.BYTE)) + return Byte.TYPE; + if (type.equals(SimpleType.CHARACTER)) + return Character.TYPE; + if (type.equals(SimpleType.DOUBLE)) + return Double.TYPE; + if (type.equals(SimpleType.FLOAT)) + return Float.TYPE; + if (type.equals(SimpleType.INTEGER)) + return Integer.TYPE; + if (type.equals(SimpleType.LONG)) + return Long.TYPE; + if (type.equals(SimpleType.SHORT)) + return Short.TYPE; + if (type.equals(SimpleType.VOID)) + return Void.TYPE; + throw new OpenDataException(type + " is not a primitive type."); + } + + /** + * Returns the element type that will actually be used, if the + * specified element type is passed to a constructor. This is + * necessary to ensure that a non-array type is still returned when + * an {@link ArrayType} is constructed from an {@link ArrayType}. + * + * @param elemType the element type that was supplied. + * @return the element type that will be used. + */ + private static final OpenType<?> getElementType(OpenType<?> elemType) + { + if (elemType instanceof ArrayType) + return ((ArrayType) elemType).getElementOpenType(); + return elemType; + } + + /** + * Returns the element type name that will actually be used, if the + * specified element type is passed to a constructor. This is + * necessary to ensure that a non-array type is still returned when + * an {@link ArrayType} is constructed from an {@link ArrayType}, + * and that primitive arrays are described correctly. + * + * @param elemType the element type that was supplied. + * @return the element type name that will be used. + * @throws OpenDataException if the element type is not a valid + * {@link SimpleType} for a primitive type. + */ + private static final String getElementTypeName(OpenType<?> elemType) + throws OpenDataException + { + OpenType<?> trueElemType = getElementType(elemType); + if (elemType instanceof ArrayType && + ((ArrayType) elemType).isPrimitiveArray()) + return getPrimitiveTypeClass((SimpleType<?>) trueElemType).getName(); + return trueElemType.getClassName(); } /** @@ -136,23 +307,84 @@ public class ArrayType * {@link SimpleType}, {@link CompositeType} * or {@link TabularType}. */ - public ArrayType(int dim, OpenType elementType) + public ArrayType(int dim, OpenType<?> elementType) throws OpenDataException { - super(getArrayClassName(elementType.getClassName(), dim), - getArrayClassName(elementType.getClassName(), dim), - dim + "-dimension array of " + elementType.getClassName()); - if (dim < 1) - throw new IllegalArgumentException("Dimensions must be greater " + - "than or equal to 1."); + super(getArrayClassName(elementType, dim, false), + getArrayClassName(elementType, dim, false), + getDimensions(elementType, dim) + "-dimension array of " + + getElementTypeName(elementType)); if (!(elementType instanceof SimpleType || elementType instanceof CompositeType || - elementType instanceof TabularType)) + elementType instanceof TabularType || + elementType instanceof ArrayType)) throw new OpenDataException("The element type must be a simple " + - "type, a composite type or a tabular " + - "type."); - dimension = dim; + "type, an array type, a composite type " + + "or a tabular type."); + dimension = getDimensions(elementType, dim); + this.elementType = getElementType(elementType); + primitiveArray = (elementType instanceof ArrayType && + ((ArrayType) elementType).isPrimitiveArray()); + } + + /** + * <p> + * Constructs a new {@link ArrayType} instance for a unidimensional + * array of the specified {@link SimpleType}. The attributes + * used by the superclass, {@link OpenType}, are automatically defined, + * based on these values. Both the class name and type name are set + * to the value returned by the {@link java.lang.Class#getName()} of + * the array's class. If the array is of a primitive type (indicated + * by giving {@code primitiveArray} the value {@code true}), the + * name will be '[' followed by the appropriate letter for the + * primitive type (see {@link java.lang.Class#getName()}). If the + * array is not of a primitive type, then the name is formed from + * the element type, preceded by '[' and an 'L', in the same way + * as when the multi-dimensional constructor is used. + * </p> + * <p> + * The description is based upon the template <code>1-dimension array + * of e</code>, where e is either the primitive type or a class name, + * depending on whether the array itself is of a primitive type or not. + * The class name of the actual elements is obtainable by calling + * {@link OpenType#getClassName()} on the result of + * {@link #getElementOpenType()}. This will be the appropriate wrapper + * class for a primitive type. + * </p> + * <p> + * As an example, the array type returned by + * <code>new ArrayType(SimpleType.INTEGER, true)</code> has the following + * values: + * </p> + * <table> + * <th><td>Attribute</td><td>Value</td></th> + * <tr><td>Class Name</td><td><code>[I</code> + * </td></tr> + * <tr><td>Type Name</td><td><code>[I</code> + * </td></tr> + * <tr><td>Description</td><td><code>1-dimension array of int</code></td></tr> + * <tr><td>Element Type Class Name</td><td><code>java.lang.Integer</code> + * </td></tr> + * </table> + * + * @param elementType the type of the elements of the array. + * @param primitiveArray true if the array should be of a primitive type. + * @throws OpenDataException if {@code primitiveArray} is {@code true}, + * and {@link elementType} is not a valid + * {@link SimpleType} for a primitive type. + * @since 1.6 + */ + public ArrayType(SimpleType<?> elementType, boolean primitiveArray) + throws OpenDataException + { + super(getArrayClassName(elementType, 1, primitiveArray), + getArrayClassName(elementType, 1, primitiveArray), + "1-dimension array of " + + (primitiveArray ? getPrimitiveTypeClass(elementType).getName() + : elementType.getClassName())); + dimension = 1; this.elementType = elementType; + this.primitiveArray = primitiveArray; } /** @@ -166,6 +398,8 @@ public class ArrayType * {@link ArrayType}.</li> * <li>The dimensions are equal.</li> * <li>The element types are equal.</li> + * <li>The primitive array flag is set the same in both + * instances.</li> * </ul> * * @param obj the object to compare with. @@ -177,7 +411,118 @@ public class ArrayType return false; ArrayType atype = (ArrayType) obj; return (atype.getDimension() == dimension && - atype.getElementOpenType().equals(elementType)); + atype.getElementOpenType().equals(elementType) && + atype.isPrimitiveArray() == primitiveArray); + } + + /** + * <p> + * Returns a new {@link ArrayType} instance in a type-safe + * manner, by ensuring that the type of the given {@link OpenType} + * matches the component type used in the type of the + * returned instance. If the given {@link OpenType} is a + * {@link SimpleType}, {@link CompositeType} or + * {@link TabularType}, then a 1-dimensional array of that + * type is returned. Otherwise, if the type is + * an {@link ArrayType} of n dimensions, the returned + * type is also an {@link ArrayType} but of n+1 dimensions. + * For example, + * {@code ArrayType.getArrayType(ArrayType.getArrayType(SimpleType.STRING))} + * returns a 2-dimensional array of {@link SimpleType#String}. + * </p> + * <p> + * This method caches its results, so that the same instance + * is returned from subsequent calls with the same parameters. + * </p> + * + * @param elementType the element type of the new array type. + * @throws OpenDataException if the class name of {@code elementType} + * is not in {@link OpenType#ALLOWED_CLASSNAMES_LIST}. + * @since 1.6 + */ + public static <E> ArrayType<E[]> getArrayType(OpenType<E> elementType) + throws OpenDataException + { + ArrayType<E[]> arr = (ArrayType<E[]>) cache.get(elementType); + if (arr != null) + return arr; + arr = new ArrayType(1, elementType); + cache.put(elementType, arr); + return arr; + } + + /** + * <p> + * Returns a new {@link ArrayType} instance for the given + * primitive type in a type-safe* manner, by ensuring that + * the type of the given {@link OpenType} matches the type + * used in the returned instance. If the type is + * an array of n dimensions, the returned + * type is also an {@link ArrayType} of n dimensions. + * </p> + * <p> + * As an example, the array type returned by + * <code>getPrimitiveArrayType(Integer.TYPE)</code> has the + * following values: + * </p> + * <table> + * <th><td>Attribute</td><td>Value</td></th> + * <tr><td>Class Name</td><td><code>[I</code> + * </td></tr> + * <tr><td>Type Name</td><td><code>[I</code> + * </td></tr> + * <tr><td>Description</td><td><code>1-dimension array of int</code></td></tr> + * <tr><td>Element Type Class Name</td><td><code>java.lang.Integer</code> + * </td></tr> + * </table> + * <p> + * This method caches its results, so that the same instance + * is returned from subsequent calls with the same parameters. + * </p> + * + * @param type the type of the new {@link ArrayType}. + * @throws IllegalArgumentException if the type is not a primitive + * array. + * @since 1.6 + */ + public static <T> ArrayType<T> getPrimitiveArrayType(Class<T> type) + { + ArrayType<T> arr = (ArrayType<T>) primCache.get(type); + if (arr != null) + return arr; + Class<?> comType = type; + int dim = 0; + do + { + comType = comType.getComponentType(); + ++dim; + if (comType == null) + throw new IllegalArgumentException("The given class is " + + "not an array."); + } while (comType.isArray()); + String className = type.getName(); + try + { + arr = new ArrayType(getPrimitiveType(comType), true); + } + catch (OpenDataException e) + { + throw new IllegalArgumentException("The array is not of a primitive " + + "type", e); + } + while (dim > 1) + try + { + arr = new ArrayType(1, arr); + --dim; + } + catch (OpenDataException e) + { + throw (Error) + new InternalError("Couldn't generate extra dimensions").initCause(e); + } + primCache.put(type, arr); + return arr; } /** @@ -197,7 +542,7 @@ public class ArrayType * * @return the type of the elements. */ - public OpenType getElementOpenType() + public OpenType<?> getElementOpenType() { return elementType; } @@ -207,11 +552,11 @@ public class ArrayType * Returns the hash code of the array type. * This is computed as the sum of the hash code of the * element type together with the number of dimensions - * the array has. These are the same elements - * of the type that are compared as part of the - * {@link #equals(java.lang.Object)} method, thus ensuring - * that the hashcode is compatible with the equality - * test. + * the array has and the primitive array flag. These + * are the same elements of the type that are compared as + * part of the {@link #equals(java.lang.Object)} method, + * thus ensuring that the hashcode is compatible with the + * equality test. * </p> * <p> * As instances of this class are immutable, the hash code @@ -224,11 +569,24 @@ public class ArrayType public int hashCode() { if (hashCode == null) - hashCode = Integer.valueOf(dimension + elementType.hashCode()); + hashCode = Integer.valueOf(dimension + + elementType.hashCode() + + Boolean.valueOf(primitiveArray).hashCode()); return hashCode.intValue(); } /** + * Returns true if this instance represents an array of + * a primitive type. + * + * @return true if the array is of a primitive type. + */ + public boolean isPrimitiveArray() + { + return primitiveArray; + } + + /** * <p> * Returns true if the specified object is a member of this * array type. The object is judged to be so if it is @@ -306,6 +664,7 @@ public class ArrayType + "[name=" + getTypeName() + ", dimension=" + dimension + ", elementType=" + elementType + + ", primitiveArray=" + primitiveArray + "]"; return string; } diff --git a/libjava/classpath/javax/management/openmbean/CompositeData.java b/libjava/classpath/javax/management/openmbean/CompositeData.java index 08f0dc2..3134bc4 100644 --- a/libjava/classpath/javax/management/openmbean/CompositeData.java +++ b/libjava/classpath/javax/management/openmbean/CompositeData.java @@ -1,5 +1,5 @@ /* CompositeData.java -- A composite data structure. - Copyright (C) 2006 Free Software Foundation, Inc. + Copyright (C) 2006, 2007 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -148,7 +148,7 @@ public interface CompositeData * * @return the values of this instance. */ - Collection values(); + Collection<?> values(); } diff --git a/libjava/classpath/javax/management/openmbean/CompositeDataInvocationHandler.java b/libjava/classpath/javax/management/openmbean/CompositeDataInvocationHandler.java new file mode 100644 index 0000000..170ec32 --- /dev/null +++ b/libjava/classpath/javax/management/openmbean/CompositeDataInvocationHandler.java @@ -0,0 +1,190 @@ +/* CompositeDataInvocationHandler.java - Pseudo-accessors for CompositeData. + Copyright (C) 2007 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 javax.management.openmbean; + +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; + +/** + * <p> + * Provides an {@link java.lang.reflect.InvocationHandler} which + * implements a series of accessor methods (those beginning with + * {@code "get"} or {@code "is"}) using the content of a + * {@link CompositeData} object. An instance of {@link CompositeData} + * consists of a series of key-value mappings. This handler assumes + * these keys to be the names of attributes, and thus provides + * accessor methods by returning the associated value. + * </p> + * <p> + * As an example, consider the following interface: + * </p> + * <pre> + * public interface Person + * { + * public String getName(); + * public Date getBirthday(); + * } + * </pre> + * <p> + * This specifies two accessor methods for retrieving the attributes, + * {@code name} and {@code birthday}. An implementation of this interface + * can be provided by creating an instance of this class, using a + * {@link CompositeData} object with appropriate key-value mappings + * (e.g. "name" => "Fred", "birthday" => 30/06/1974), and then passing + * that to {@link java.lang.reflect.Proxy#newProxyInstance} along with + * the interface itself. The invocation handler implements the methods + * by calling {@link CompositeData#get(String)} with the appropriate key. + * </p> + * <p> + * The attribute name is derived by taking the remainder of the method + * name following {@code "get"}. If the first letter of this substring + * is uppercase, then two attempts are made to retrieve the attribute + * from the {@link CompositeData} instance: one using the original substring, + * and one with the first letter changed to its lower-case equivalent. + * If the first letter is lowercase, only the exact substring is used. + * </p> + * <p> + * An {@link Object#equals(Object)} implementation is provided. This returns + * true if the argument is a proxy with a {@link CompositeDataInvocationHandler} + * using an equivalent {@link CompositeData} instance. {@link Object#hashCode()} + * is also defined so as to match this implementation and give equivalent instances + * the same hashcode. + * </p> + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.6 + */ +public class CompositeDataInvocationHandler + implements InvocationHandler +{ + + /** + * The {@link CompositeData} providing the key-value mappings. + */ + private CompositeData data; + + /** + * Constructs a new {@link CompositeDataInvocationHandler} + * with the specified {@link CompositeData} instance. + * + * @param data the {@link CompositeData} instance to use. + * @throws IllegalArgumentException if {@code data} is {@code null}. + */ + public CompositeDataInvocationHandler(CompositeData data) + { + if (data == null) + throw new IllegalArgumentException("The CompositeData instance " + + "must be non-null."); + this.data = data; + } + + /** + * Returns the {@link CompositeData} instance which provides + * the key-value mappings for this instance. This is never + * {@code null}. + * + * @return the {@link CompositeData} instance. + */ + public CompositeData getCompositeData() + { + return data; + } + + /** + * Called by the proxy class whenever a method is called. The + * handler only deals with accessor methods (beginning with + * {@code "get"} or {@code "is"}), {@code equals}, and + * {@code "hashCode"}. Accessor methods are implemented by + * returning the appropriate value from the {@link CompositeData} + * instance, while {@code equals} and {@code hashCode} allow + * two proxies with a {@link CompositeDataInvocationHandler} using + * the same {@link CompositeData} instance to be classified + * as equivalent. + * + * @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 the process. + */ + public Object invoke(Object proxy, Method method, Object[] args) + throws Throwable + { + String mName = method.getName(); + if (mName.equals("equals")) + { + if (args[0] instanceof Proxy) + { + InvocationHandler h = Proxy.getInvocationHandler(args[0]); + if (h instanceof CompositeDataInvocationHandler) + return data.equals(((CompositeDataInvocationHandler) + h).getCompositeData()); + } + return false; + } + if (mName.equals("hashCode")) + { + return data.hashCode(); + } + String attrib = null; + if (mName.startsWith("get")) + attrib = mName.substring(3); + else if (mName.startsWith("is")) + attrib = mName.substring(2); + if (attrib == null) + throw new NoSuchMethodException(mName + " is not an accessor."); + if (!data.containsKey(attrib)) + { + if (Character.isLowerCase(attrib.charAt(0))) + throw new NoSuchMethodException("The attribute " + + attrib + " is not available " + + "in the given CompositeData " + + "object"); + attrib = Character.toLowerCase(attrib.charAt(0)) + + attrib.substring(1); + if (!data.containsKey(attrib)) + throw new NoSuchMethodException("The attribute " + + attrib + " is not available " + + "in the given CompositeData " + + "object"); + } + return data.get(attrib); + } + +} diff --git a/libjava/classpath/javax/management/openmbean/CompositeDataSupport.java b/libjava/classpath/javax/management/openmbean/CompositeDataSupport.java index 5d5adb7..d4c9d45 100644 --- a/libjava/classpath/javax/management/openmbean/CompositeDataSupport.java +++ b/libjava/classpath/javax/management/openmbean/CompositeDataSupport.java @@ -1,5 +1,5 @@ /* CompositeData.java -- A composite data structure implementation. - Copyright (C) 2006 Free Software Foundation, Inc. + Copyright (C) 2006, 2007 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -68,7 +68,7 @@ public class CompositeDataSupport * * @serial the map of field names to values. */ - private SortedMap contents; + private SortedMap<String, Object> contents; /** * The composite type which represents this composite data instance. @@ -106,11 +106,11 @@ public class CompositeDataSupport * {@link java.lang.String} (thus calling a failure * in converting the keys to an array of strings). */ - public CompositeDataSupport(CompositeType type, Map items) + public CompositeDataSupport(CompositeType type, Map<String, ?> items) throws OpenDataException { this(type, - (String[]) items.keySet().toArray(new String[items.size()]), + items.keySet().toArray(new String[items.size()]), items.values().toArray()); } @@ -158,7 +158,7 @@ public class CompositeDataSupport if (typeKeys.size() != names.length) throw new OpenDataException("The number of field names does not match " + "the type description."); - contents = new TreeMap(); + contents = new TreeMap<String, Object>(); for (int a = 0; a < names.length; ++a) { if (names[a] == null) @@ -340,7 +340,7 @@ public class CompositeDataSupport * * @return the values of this instance. */ - public Collection values() + public Collection<?> values() { return Collections.unmodifiableCollection(contents.values()); } diff --git a/libjava/classpath/javax/management/openmbean/CompositeType.java b/libjava/classpath/javax/management/openmbean/CompositeType.java index 0ae5a4e..1a213f6 100644 --- a/libjava/classpath/javax/management/openmbean/CompositeType.java +++ b/libjava/classpath/javax/management/openmbean/CompositeType.java @@ -1,5 +1,5 @@ /* CompositeType.java -- Type descriptor for CompositeData instances. - Copyright (C) 2006 Free Software Foundation, Inc. + Copyright (C) 2006, 2007 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -51,7 +51,7 @@ import java.util.TreeMap; * @since 1.5 */ public class CompositeType - extends OpenType + extends OpenType<CompositeData> { /** @@ -62,12 +62,12 @@ public class CompositeType /** * A map of item names to their descriptions. */ - private TreeMap nameToDescription; + private TreeMap<String,String> nameToDescription; /** * A map of item names to their types. */ - private TreeMap nameToType; + private TreeMap<String,OpenType<?>> nameToType; /** * The hash code of this instance. @@ -109,7 +109,7 @@ public class CompositeType * before comparison. */ public CompositeType(String name, String desc, String[] names, - String[] descs, OpenType[] types) + String[] descs, OpenType<?>[] types) throws OpenDataException { super(CompositeData.class.getName(), name, desc); @@ -138,7 +138,7 @@ public class CompositeType "than once."); nameToDescription.put(fieldName, descs[a]); } - nameToType = new TreeMap(); + nameToType = new TreeMap<String,OpenType<?>>(); for (int a = 0; a < names.length; ++a) nameToType.put(names[a].trim(), types[a]); } @@ -178,16 +178,14 @@ public class CompositeType CompositeType ctype = (CompositeType) obj; if (!(ctype.getTypeName().equals(getTypeName()))) return false; - Set keys = keySet(); + Set<String> keys = keySet(); if (!(ctype.keySet().equals(keys))) return false; - Iterator it = keys.iterator(); - while (it.hasNext()) - { - String key = (String) it.next(); - if (!(ctype.getType(key).equals(getType(key)))) - return false; - } + for (String key : keys) + { + if (!(ctype.getType(key).equals(getType(key)))) + return false; + } return true; } @@ -203,7 +201,7 @@ public class CompositeType */ public String getDescription(String name) { - return (String) nameToDescription.get(name); + return nameToDescription.get(name); } /** @@ -216,9 +214,9 @@ public class CompositeType * @return the type, or <code>null</code> if the * field doesn't exist. */ - public OpenType getType(String name) + public OpenType<?> getType(String name) { - return (OpenType) nameToType.get(name); + return nameToType.get(name); } /** @@ -287,7 +285,7 @@ public class CompositeType * @return a unmodifiable set containing the field * name {@link java.lang.String}s. */ - public Set keySet() + public Set<String> keySet() { return Collections.unmodifiableSet(nameToDescription.keySet()); } diff --git a/libjava/classpath/javax/management/openmbean/OpenMBeanAttributeInfoSupport.java b/libjava/classpath/javax/management/openmbean/OpenMBeanAttributeInfoSupport.java index 83e0436..22667aa 100644 --- a/libjava/classpath/javax/management/openmbean/OpenMBeanAttributeInfoSupport.java +++ b/libjava/classpath/javax/management/openmbean/OpenMBeanAttributeInfoSupport.java @@ -1,5 +1,5 @@ /* OpenMBeanAttributeInfoSupport.java -- Open typed info about an attribute. - Copyright (C) 2006 Free Software Foundation, Inc. + Copyright (C) 2006, 2007 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -62,7 +62,7 @@ public class OpenMBeanAttributeInfoSupport /** * The open type of the attribute. */ - private OpenType openType; + private OpenType<?> openType; /** * The default value of the attribute (may be <code>null</code>). @@ -72,17 +72,17 @@ public class OpenMBeanAttributeInfoSupport /** * The possible legal values of the attribute (may be <code>null</code>). */ - private Set legalValues; + private Set<?> legalValues; /** * The minimum value of the attribute (may be <code>null</code>). */ - private Comparable minValue; + private Comparable<Object> minValue; /** * The maximum value of the attribute (may be <code>null</code>). */ - private Comparable maxValue; + private Comparable<Object> maxValue; /** * The hash code of this instance. @@ -112,7 +112,7 @@ public class OpenMBeanAttributeInfoSupport * or the name or description are * the empty string. */ - public OpenMBeanAttributeInfoSupport(String name, String desc, OpenType type, + public OpenMBeanAttributeInfoSupport(String name, String desc, OpenType<?> type, boolean isReadable, boolean isWritable, boolean isIs) { @@ -157,9 +157,9 @@ public class OpenMBeanAttributeInfoSupport * open type or the open type is an instance * of {@link ArrayType} or {@link TabularType}. */ - public OpenMBeanAttributeInfoSupport(String name, String desc, OpenType type, - boolean isReadable, boolean isWritable, - boolean isIs, Object defaultValue) + public <T> OpenMBeanAttributeInfoSupport(String name, String desc, OpenType<T> type, + boolean isReadable, boolean isWritable, + boolean isIs, T defaultValue) throws OpenDataException { this(name, desc, type, isReadable, isWritable, isIs, defaultValue, null); @@ -203,11 +203,11 @@ public class OpenMBeanAttributeInfoSupport * the empty string. * @throws OpenDataException if any condition in the list above is broken. */ - public OpenMBeanAttributeInfoSupport(String name, String desc, OpenType type, - boolean isReadable, boolean isWritable, - boolean isIs, Object defaultValue, - Comparable minimumValue, - Comparable maximumValue) + public <T> OpenMBeanAttributeInfoSupport(String name, String desc, OpenType<T> type, + boolean isReadable, boolean isWritable, + boolean isIs, T defaultValue, + Comparable<T> minimumValue, + Comparable<T> maximumValue) throws OpenDataException { this(name, desc, type, isReadable, isWritable, isIs); @@ -239,8 +239,8 @@ public class OpenMBeanAttributeInfoSupport openType = type; this.defaultValue = defaultValue; - minValue = minimumValue; - maxValue = maximumValue; + minValue = (Comparable<Object>) minimumValue; + maxValue = (Comparable<Object>) maximumValue; } /** @@ -280,10 +280,10 @@ public class OpenMBeanAttributeInfoSupport * the empty string. * @throws OpenDataException if any condition in the list above is broken. */ - public OpenMBeanAttributeInfoSupport(String name, String desc, OpenType type, - boolean isReadable, boolean isWritable, - boolean isIs, Object defaultValue, - Object[] legalValues) + public <T> OpenMBeanAttributeInfoSupport(String name, String desc, OpenType<T> type, + boolean isReadable, boolean isWritable, + boolean isIs, T defaultValue, + T[] legalValues) throws OpenDataException { this(name, desc, type, isReadable, isWritable, isIs); @@ -379,7 +379,7 @@ public class OpenMBeanAttributeInfoSupport * @return a set of legal values, or <code>null</code> if no such * set exists. */ - public Set getLegalValues() + public Set<?> getLegalValues() { return legalValues; } @@ -390,7 +390,7 @@ public class OpenMBeanAttributeInfoSupport * * @return the maximum value, or <code>null</code> if none exists. */ - public Comparable getMaxValue() + public Comparable<?> getMaxValue() { return maxValue; } @@ -401,7 +401,7 @@ public class OpenMBeanAttributeInfoSupport * * @return the minimum value, or <code>null</code> if none exists. */ - public Comparable getMinValue() + public Comparable<?> getMinValue() { return minValue; } @@ -412,7 +412,7 @@ public class OpenMBeanAttributeInfoSupport * * @return the open type of this attribute. */ - public OpenType getOpenType() + public OpenType<?> getOpenType() { return openType; } diff --git a/libjava/classpath/javax/management/openmbean/OpenMBeanOperationInfo.java b/libjava/classpath/javax/management/openmbean/OpenMBeanOperationInfo.java index 8b61329..e835b8d 100644 --- a/libjava/classpath/javax/management/openmbean/OpenMBeanOperationInfo.java +++ b/libjava/classpath/javax/management/openmbean/OpenMBeanOperationInfo.java @@ -109,7 +109,7 @@ public interface OpenMBeanOperationInfo * * @return the open type of the return value. */ - OpenType getReturnOpenType(); + OpenType<?> getReturnOpenType(); /** * Returns the return type of the operation, as the class diff --git a/libjava/classpath/javax/management/openmbean/OpenMBeanOperationInfoSupport.java b/libjava/classpath/javax/management/openmbean/OpenMBeanOperationInfoSupport.java index 0756489..c01433d 100644 --- a/libjava/classpath/javax/management/openmbean/OpenMBeanOperationInfoSupport.java +++ b/libjava/classpath/javax/management/openmbean/OpenMBeanOperationInfoSupport.java @@ -1,5 +1,5 @@ /* OpenMBeanOperationInfoSupport.java -- Open typed info about an operation. - Copyright (C) 2006 Free Software Foundation, Inc. + Copyright (C) 2006, 2007 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -61,7 +61,7 @@ public class OpenMBeanOperationInfoSupport /** * The open type representing the return value. */ - private OpenType returnOpenType; + private OpenType<?> returnOpenType; /** * The hash code of this instance. @@ -108,7 +108,7 @@ public class OpenMBeanOperationInfoSupport */ public OpenMBeanOperationInfoSupport(String name, String desc, OpenMBeanParameterInfo[] sig, - OpenType type, int impact) + OpenType<?> type, int impact) { super(name, desc, (MBeanParameterInfo[]) sig, type == null ? null : type.getClassName(), impact); @@ -159,7 +159,7 @@ public class OpenMBeanOperationInfoSupport * * @return the open type of the return value. */ - public OpenType getReturnOpenType() + public OpenType<?> getReturnOpenType() { return returnOpenType; } diff --git a/libjava/classpath/javax/management/openmbean/OpenMBeanParameterInfo.java b/libjava/classpath/javax/management/openmbean/OpenMBeanParameterInfo.java index 780e8ba..75d1baf 100644 --- a/libjava/classpath/javax/management/openmbean/OpenMBeanParameterInfo.java +++ b/libjava/classpath/javax/management/openmbean/OpenMBeanParameterInfo.java @@ -93,7 +93,7 @@ public interface OpenMBeanParameterInfo * @return a set of legal values, or <code>null</code> if no such * set exists. */ - Set getLegalValues(); + Set<?> getLegalValues(); /** * Returns the maximum value of this parameter, or <code>null</code> @@ -101,7 +101,7 @@ public interface OpenMBeanParameterInfo * * @return the maximum value, or <code>null</code> if none exists. */ - Comparable getMaxValue(); + Comparable<?> getMaxValue(); /** * Returns the minimum value of this parameter, or <code>null</code> @@ -109,7 +109,7 @@ public interface OpenMBeanParameterInfo * * @return the minimum value, or <code>null</code> if none exists. */ - Comparable getMinValue(); + Comparable<?> getMinValue(); /** * Returns the name of this parameter. @@ -124,7 +124,7 @@ public interface OpenMBeanParameterInfo * * @return the open type of this parameter. */ - OpenType getOpenType(); + OpenType<?> getOpenType(); /** * Returns true if this parameter has a default value. diff --git a/libjava/classpath/javax/management/openmbean/OpenMBeanParameterInfoSupport.java b/libjava/classpath/javax/management/openmbean/OpenMBeanParameterInfoSupport.java index af3bda6..7fad2a1 100644 --- a/libjava/classpath/javax/management/openmbean/OpenMBeanParameterInfoSupport.java +++ b/libjava/classpath/javax/management/openmbean/OpenMBeanParameterInfoSupport.java @@ -1,5 +1,5 @@ /* OpenMBeanParameterInfoSupport.java -- Open typed info about a parameter. - Copyright (C) 2006 Free Software Foundation, Inc. + Copyright (C) 2006, 2007 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -63,7 +63,7 @@ public class OpenMBeanParameterInfoSupport /** * The open type of the parameter. */ - private OpenType openType; + private OpenType<?> openType; /** * The default value of the parameter (may be <code>null</code>). @@ -73,17 +73,17 @@ public class OpenMBeanParameterInfoSupport /** * The possible legal values of the parameter (may be <code>null</code>). */ - private Set legalValues; + private Set<?> legalValues; /** * The minimum value of the parameter (may be <code>null</code>). */ - private Comparable minValue; + private Comparable<Object> minValue; /** * The maximum value of the parameter (may be <code>null</code>). */ - private Comparable maxValue; + private Comparable<Object> maxValue; /** * The hash code of this instance. @@ -109,7 +109,7 @@ public class OpenMBeanParameterInfoSupport * or the name or description are * the empty string. */ - public OpenMBeanParameterInfoSupport(String name, String desc, OpenType type) + public OpenMBeanParameterInfoSupport(String name, String desc, OpenType<?> type) { super(name, type == null ? null : type.getClassName(), desc); if (name == null) @@ -149,8 +149,8 @@ public class OpenMBeanParameterInfoSupport * open type or the open type is an instance * of {@link ArrayType} or {@link TabularType}. */ - public OpenMBeanParameterInfoSupport(String name, String desc, OpenType type, - Object defaultValue) + public <T> OpenMBeanParameterInfoSupport(String name, String desc, OpenType<T> type, + T defaultValue) throws OpenDataException { this(name, desc, type, defaultValue, null); @@ -190,9 +190,9 @@ public class OpenMBeanParameterInfoSupport * the empty string. * @throws OpenDataException if any condition in the list above is broken. */ - public OpenMBeanParameterInfoSupport(String name, String desc, OpenType type, - Object defaultValue, Comparable minimumValue, - Comparable maximumValue) + public <T> OpenMBeanParameterInfoSupport(String name, String desc, OpenType<T> type, + T defaultValue, Comparable<T> minimumValue, + Comparable<T> maximumValue) throws OpenDataException { this(name, desc, type); @@ -223,8 +223,8 @@ public class OpenMBeanParameterInfoSupport "maximum."); this.defaultValue = defaultValue; - minValue = minimumValue; - maxValue = maximumValue; + minValue = (Comparable<Object>) minimumValue; + maxValue = (Comparable<Object>) maximumValue; } /** @@ -261,8 +261,8 @@ public class OpenMBeanParameterInfoSupport * the empty string. * @throws OpenDataException if any condition in the list above is broken. */ - public OpenMBeanParameterInfoSupport(String name, String desc, OpenType type, - Object defaultValue, Object[] legalValues) + public <T> OpenMBeanParameterInfoSupport(String name, String desc, OpenType<T> type, + T defaultValue, T[] legalValues) throws OpenDataException { this(name, desc, type); @@ -351,7 +351,7 @@ public class OpenMBeanParameterInfoSupport * @return a set of legal values, or <code>null</code> if no such * set exists. */ - public Set getLegalValues() + public Set<?> getLegalValues() { return legalValues; } @@ -362,7 +362,7 @@ public class OpenMBeanParameterInfoSupport * * @return the maximum value, or <code>null</code> if none exists. */ - public Comparable getMaxValue() + public Comparable<?> getMaxValue() { return maxValue; } @@ -373,7 +373,7 @@ public class OpenMBeanParameterInfoSupport * * @return the minimum value, or <code>null</code> if none exists. */ - public Comparable getMinValue() + public Comparable<?> getMinValue() { return minValue; } @@ -384,7 +384,7 @@ public class OpenMBeanParameterInfoSupport * * @return the open type of this parameter. */ - public OpenType getOpenType() + public OpenType<?> getOpenType() { return openType; } diff --git a/libjava/classpath/javax/management/openmbean/OpenType.java b/libjava/classpath/javax/management/openmbean/OpenType.java index 13c9e8a..f3a97fe 100644 --- a/libjava/classpath/javax/management/openmbean/OpenType.java +++ b/libjava/classpath/javax/management/openmbean/OpenType.java @@ -1,5 +1,5 @@ /* OpenType.java -- Superclass of all open types. - Copyright (C) 2006 Free Software Foundation, Inc. + Copyright (C) 2006, 2007 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -39,6 +39,9 @@ package javax.management.openmbean; import java.io.Serializable; +import java.util.Arrays; +import java.util.List; + /** * The superclass of all open types, which describe the * applicable data values for open MBeans. An open type @@ -48,7 +51,7 @@ import java.io.Serializable; * @author Andrew John Hughes (gnu_andrew@member.fsf.org) * @since 1.5 */ -public abstract class OpenType +public abstract class OpenType<T> implements Serializable { @@ -76,7 +79,10 @@ public abstract class OpenType * An array which defines the set of Java types which can be * used as open types. Note that each type is also available * in array form, possibly with multiple dimensions. + * + * @deprecated Use {@link ALLOWED_CLASSNAMES_LIST} instead. */ + @Deprecated public static final String[] ALLOWED_CLASSNAMES = { "java.lang.Void", "java.lang.Boolean", @@ -97,6 +103,14 @@ public abstract class OpenType }; /** + * A list which defines the set of Java types that may be + * used as open types. Note that each type is also available + * in array form, possibly with multiple dimensions. + */ + public static final List<String> ALLOWED_CLASSNAMES_LIST = + Arrays.asList(ALLOWED_CLASSNAMES); + + /** * Constructs a new {@link OpenType} for the specified class * with the given name and description. The name of the class * must be taken from the list of {@link ALLOWED_CLASSNAMES}. @@ -126,17 +140,20 @@ public abstract class OpenType if (desc == null || desc.equals("")) throw new IllegalArgumentException("The description can not " + "be null or the empty string."); - String testString; - if (className.startsWith("[")) - testString = className.substring(className.indexOf("L") + 1); - else - testString = className; - boolean openTypeFound = false; - for (int a = 0; a < ALLOWED_CLASSNAMES.length; ++a) - if (ALLOWED_CLASSNAMES[a].equals(testString)) - openTypeFound = true; - if (!openTypeFound) - throw new OpenDataException("The class name, " + testString + + Class<?> type; + try + { + type = Class.forName(className); + } + catch (ClassNotFoundException e) + { + throw (OpenDataException) new OpenDataException("The class name, " + className + + ", is unavailable.").initCause(e); + } + while (type.isArray()) + type = type.getComponentType(); + if (!(type.isPrimitive() || ALLOWED_CLASSNAMES_LIST.contains(type.getName()))) + throw new OpenDataException("The class name, " + className + ", does not specify a valid open type."); this.className = className; typeName = name; diff --git a/libjava/classpath/javax/management/openmbean/SimpleType.java b/libjava/classpath/javax/management/openmbean/SimpleType.java index 39753f1..fb3b1bc 100644 --- a/libjava/classpath/javax/management/openmbean/SimpleType.java +++ b/libjava/classpath/javax/management/openmbean/SimpleType.java @@ -1,5 +1,5 @@ /* SimpleType.java -- Open type descriptor for the base types. - Copyright (C) 2006 Free Software Foundation, Inc. + Copyright (C) 2006, 2007 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -40,6 +40,13 @@ package javax.management.openmbean; import java.io.InvalidObjectException; import java.io.ObjectStreamException; +import java.math.BigDecimal; +import java.math.BigInteger; + +import java.util.Date; + +import javax.management.ObjectName; + /** * The open type descriptor for data values that are members * of one of the simple types (such as an integer or a string). @@ -53,94 +60,94 @@ import java.io.ObjectStreamException; * @author Andrew John Hughes (gnu_andrew@member.fsf.org) * @since 1.5 */ -public final class SimpleType - extends OpenType +public final class SimpleType<T> + extends OpenType<T> { /** * The {@link SimpleType} representation of * <code>java.math.BigDecimal</code>. */ - public static final SimpleType BIGDECIMAL; + public static final SimpleType<BigDecimal> BIGDECIMAL; /** * The {@link SimpleType} representation of * <code>java.math.BigInteger</code>. */ - public static final SimpleType BIGINTEGER; + public static final SimpleType<BigInteger> BIGINTEGER; /** * The {@link SimpleType} representation of * <code>java.lang.Boolean</code>. */ - public static final SimpleType BOOLEAN; + public static final SimpleType<Boolean> BOOLEAN; /** * The {@link SimpleType} representation of * <code>java.lang.Byte</code>. */ - public static final SimpleType BYTE; + public static final SimpleType<Byte> BYTE; /** * The {@link SimpleType} representation of * <code>java.lang.Character</code>. */ - public static final SimpleType CHARACTER; + public static final SimpleType<Character> CHARACTER; /** * The {@link SimpleType} representation of * <code>java.util.Date</code>. */ - public static final SimpleType DATE; + public static final SimpleType<Date> DATE; /** * The {@link SimpleType} representation of * <code>java.lang.Double</code>. */ - public static final SimpleType DOUBLE; + public static final SimpleType<Double> DOUBLE; /** * The {@link SimpleType} representation of * <code>java.lang.Float</code>. */ - public static final SimpleType FLOAT; + public static final SimpleType<Float> FLOAT; /** * The {@link SimpleType} representation of * <code>java.lang.Integer</code>. */ - public static final SimpleType INTEGER; + public static final SimpleType<Integer> INTEGER; /** * The {@link SimpleType} representation of * <code>java.lang.Long</code>. */ - public static final SimpleType LONG; + public static final SimpleType<Long> LONG; /** * The {@link SimpleType} representation of * <code>javax.management.ObjectName</code>. */ - public static final SimpleType OBJECTNAME; + public static final SimpleType<ObjectName> OBJECTNAME; /** * The {@link SimpleType} representation of * <code>java.lang.Short</code>. */ - public static final SimpleType SHORT; + public static final SimpleType<Short> SHORT; /** * The {@link SimpleType} representation of * <code>java.lang.String</code>. */ - public static final SimpleType STRING; + public static final SimpleType<String> STRING; /** * The {@link SimpleType} representation of * <code>java.lang.Void</code>. */ - public static final SimpleType VOID; + public static final SimpleType<Void> VOID; /** * Compatible with JDK 1.5 @@ -164,27 +171,28 @@ public final class SimpleType { try { - BIGDECIMAL = new SimpleType("java.math.BigDecimal"); - BIGINTEGER = new SimpleType("java.math.BigInteger"); - BOOLEAN = new SimpleType("java.lang.Boolean"); - BYTE = new SimpleType("java.lang.Byte"); - CHARACTER = new SimpleType("java.lang.Character"); - DATE = new SimpleType("java.util.Date"); - DOUBLE = new SimpleType("java.lang.Double"); - FLOAT = new SimpleType("java.lang.Float"); - INTEGER = new SimpleType("java.lang.Integer"); - LONG = new SimpleType("java.lang.Long"); - OBJECTNAME = new SimpleType("javax.management.ObjectName"); - SHORT = new SimpleType("java.lang.Short"); - STRING = new SimpleType("java.lang.String"); - VOID = new SimpleType("java.lang.Void"); + BIGDECIMAL = new SimpleType<BigDecimal>("java.math.BigDecimal"); + BIGINTEGER = new SimpleType<BigInteger>("java.math.BigInteger"); + BOOLEAN = new SimpleType<Boolean>("java.lang.Boolean"); + BYTE = new SimpleType<Byte>("java.lang.Byte"); + CHARACTER = new SimpleType<Character>("java.lang.Character"); + DATE = new SimpleType<Date>("java.util.Date"); + DOUBLE = new SimpleType<Double>("java.lang.Double"); + FLOAT = new SimpleType<Float>("java.lang.Float"); + INTEGER = new SimpleType<Integer>("java.lang.Integer"); + LONG = new SimpleType<Long>("java.lang.Long"); + OBJECTNAME = + new SimpleType<ObjectName>("javax.management.ObjectName"); + SHORT = new SimpleType<Short>("java.lang.Short"); + STRING = new SimpleType<String>("java.lang.String"); + VOID = new SimpleType<Void>("java.lang.Void"); } catch (OpenDataException e) { /* In normal circumstances, this shouldn't be possible. */ throw new IllegalStateException("A invalid class name " + "was passed to the SimpleType " + - "constructor."); + "constructor.", e); } } diff --git a/libjava/classpath/javax/management/openmbean/TabularData.java b/libjava/classpath/javax/management/openmbean/TabularData.java index 7e57e0f..75ab00b 100644 --- a/libjava/classpath/javax/management/openmbean/TabularData.java +++ b/libjava/classpath/javax/management/openmbean/TabularData.java @@ -1,5 +1,5 @@ /* TabularData.java -- Tables of composite data structures. - Copyright (C) 2006 Free Software Foundation, Inc. + Copyright (C) 2006, 2007 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -165,7 +165,7 @@ public interface TabularData * * @return a set containing the keys of this instance. */ - Set keySet(); + Set<?> keySet(); /** * Adds the specified {@link CompositeData} value to the @@ -253,7 +253,7 @@ public interface TabularData * * @return the values of this instance. */ - Collection values(); + Collection<?> values(); } diff --git a/libjava/classpath/javax/management/openmbean/TabularDataSupport.java b/libjava/classpath/javax/management/openmbean/TabularDataSupport.java index 9dc8a0e..1d340e8 100644 --- a/libjava/classpath/javax/management/openmbean/TabularDataSupport.java +++ b/libjava/classpath/javax/management/openmbean/TabularDataSupport.java @@ -1,5 +1,5 @@ /* TabularDataSupport.java -- Tables of composite data structures. - Copyright (C) 2006 Free Software Foundation, Inc. + Copyright (C) 2006, 2007 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -55,7 +55,7 @@ import java.util.Set; * @since 1.5 */ public class TabularDataSupport - implements TabularData, Serializable, Cloneable, Map + implements TabularData, Serializable, Cloneable, Map<Object,Object> { /** @@ -68,7 +68,7 @@ public class TabularDataSupport * * @serial the map of rows to column values. */ - private Map dataMap; + private Map<Object,Object> dataMap; /** * The tabular type which represents this tabular data instance. @@ -113,7 +113,7 @@ public class TabularDataSupport if (type == null) throw new IllegalArgumentException("The type may not be null."); tabularType = type; - dataMap = new HashMap(cap, lf); + dataMap = new HashMap<Object,Object>(cap, lf); } /** @@ -279,7 +279,7 @@ public class TabularDataSupport * @return the set view of all mapping entries * @see java.util.Map.Entry */ - public Set entrySet() + public Set<Map.Entry<Object,Object>> entrySet() { return dataMap.entrySet(); } @@ -413,7 +413,7 @@ public class TabularDataSupport * * @return the set view of all keys */ - public Set keySet() + public Set<Object> keySet() { return dataMap.keySet(); } @@ -535,7 +535,7 @@ public class TabularDataSupport * of one of the other * specified values. */ - public void putAll(Map m) + public void putAll(Map<?,?> m) { if (m == null || m.size() == 0) return; @@ -643,7 +643,7 @@ public class TabularDataSupport * * @return the collection view of all values */ - public Collection values() + public Collection<Object> values() { return dataMap.values(); } diff --git a/libjava/classpath/javax/management/openmbean/TabularType.java b/libjava/classpath/javax/management/openmbean/TabularType.java index c38f5ea..9a0881e 100644 --- a/libjava/classpath/javax/management/openmbean/TabularType.java +++ b/libjava/classpath/javax/management/openmbean/TabularType.java @@ -1,5 +1,5 @@ /* TabularType.java -- Type descriptor for TabularData instances. - Copyright (C) 2006 Free Software Foundation, Inc. + Copyright (C) 2006, 2007 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -50,7 +50,7 @@ import java.util.List; * @since 1.5 */ public class TabularType - extends OpenType + extends OpenType<TabularData> { /** @@ -68,7 +68,7 @@ public class TabularType * They are retained in the order given by the user, and is * unmodifiable. */ - private List indexNames; + private List<String> indexNames; /** * The hash code of this instance. @@ -167,7 +167,7 @@ public class TabularType * @return an unmodifiable list of the index names used by this * tabular data structure. */ - public List getIndexNames() + public List<String> getIndexNames() { return indexNames; } |