From e1bea0c0687c5f4551b3a6058ec37ce3705fa6cc Mon Sep 17 00:00:00 2001
From: Matthias Klose
+ * 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.
+ *
+ * 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.
+ *
+ * Provides metadata for a management element as a series
+ * of fields, formed from name-value pairs. Descriptors
+ * are usually attached to one of the
+ * 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
+ * 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}.
+ *
+ * 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.
+ * The predefined names are as follows:
+ * Some names are also defined as part of the Model MBeans package.
+ * See {@link javax.management.modelmbean.ModelMBeanInfo}.
+ * Returns true if this descriptor is equivalent to the
+ * supplied object. This is true if the following holds:
+ *
+ * Returns all the field name and value pairs, in the
+ * form If the descriptor is empty, an empty array is returned.
+ * 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,
+ * Returns true if the given class represents an {@link MXBean}
+ * interface. An interface is an {@link MXBean interface} if:
+ *
+ * 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.
+ *
+ * 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:
+ *
+ * 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)}.
+ *
+ * Calling this method is equivalent to calling
+ * {@link #newMBeanProxy(MBeanServerConnection, ObjectName, Class,
+ * boolean)}.
+ *
+ * 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.
+ *
+ * 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:
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * Calling this method is equivalent to calling
+ * {@link #newMXBeanProxy(MBeanServerConnection, ObjectName, Class,
+ * boolean)}.
+ *
+ * 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}.
+ *
+ * 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}.
+ *
+ * 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:
+ *
+ * Returns a proxy for the specified bean. A proxy object is created
+ * using
+ * Note: 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.
+ *
+ * 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:
+ * The following would not:
+ * 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
+ * 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)}.
+ *
+ * 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
+ * Prior to either process taking place, the listeners are filtered.
+ * Notifications are only delivered if the filter is either
+ *
+ * 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.
+ *
+ * Whether the state is stored or not depends on the
+ * If the policy is set to any of the following, the state
+ * should not be stored:
+ * 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:
+ *
+ * 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.
+ *
+ * The description is based upon the template
+ * As an example, the array type returned by
+ *
+ * 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}.
+ *
+ * This method caches its results, so that the same instance
+ * is returned from subsequent calls with the same parameters.
+ *
+ * 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.
+ *
+ * As an example, the array type returned by
+ *
+ * This method caches its results, so that the same instance
+ * is returned from subsequent calls with the same parameters.
+ * count
, it
+ * should send a notification with the
+ * attributeName
, "count"
,
+ * the attributeType
, "Integer"
+ * 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 Vectornull
+ * 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, null
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
+ {
+ Listnull
+ * 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
+ {
+ ListInfo
+ * classes, such as {@link MBeanAttributeInfo}.
+ * getType()
method of the associated
+ * Info
object. In the case of {@link MXBean}s,
+ * this should be the mapped type returned by the mapping rules.
+ * gnu.classpath.ImportantMetadata
.
+ *
+ *
+ *
+ * Name Type Used In Meaning
+ *
+ *
+ *
+ * defaultValue Object {@link MBeanAttributeInfo},
+ * {@link MBeanParameterInfo} Default value for an attribute
+ * or parameter.
+ *
+ *
+ * deprecated String Any 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.
+ *
+ *
+ * descriptionResourceBundleBaseName String Any
+ * The base name for the bundle in which the
+ * descriptionResourceKey
+ * can be found.
+ *
+ * descriptionResourceKey String Any
+ * The name of the resource key which contains a localized description of
+ * this element.
+ *
+ *
+ * enabled String {@link MBeanAttributeInfo},
+ * {@link MBeanNotificationInfo}, {@link MBeanOperationInfo}
+ * Specifies whether the annotated element is currently enabled or
+ * not, via a value of either "true"
or "false"
.
+ *
+ *
+ * immutableInfo String {@link MBeanInfo}
+ * If the value of this field is
+ * "true"
, this means that
+ * the annotated element will not change and thus may be cached.
+ *
+ * infoTimeout String or Long {@link MBeanInfo}
+ * 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.
+ *
+ *
+ * interfaceClassName String {@link MBeanInfo}
+ * The Java interface name associated with the bean, as returned
+ * by {@link Class#getName()}.
+ *
+ *
+ * legalValues Set> {@link MBeanAttributeInfo},
+ * {@link MBeanParameterInfo} Legal values for an attribute
+ * or parameter.
+ *
+ *
+ * maxValue Object {@link MBeanAttributeInfo},
+ * {@link MBeanParameterInfo} Maximum legal value for an attribute
+ * or parameter.
+ *
+ *
+ * metricType String {@link MBeanAttributeInfo},
+ * {@link MBeanOperationInfo} Specifies the type of metric represented
+ * by the annotated element. This will be either
+ * "counter"
+ * (an increasing value, which will only be reset and never decrease)
+ * or "gauge"
(an increasing and decreasing value).
+ *
+ * minValue Object {@link MBeanAttributeInfo},
+ * {@link MBeanParameterInfo} Minimum legal value for an attribute
+ * or parameter.
+ *
+ *
+ * mxbean String {@link MBeanInfo}
+ * Specifies whether the annotated element is an {@link MXBean} or
+ * not, via a value of either "true"
or "false"
.
+ *
+ * openType {@link javax.management.openmbean.OpenType}
+ * {@link MBeanAttributeInfo}, {@link MBeanOperationInfo} ,
+ * {@link MBeanNotificationInfo}, {@link MBeanParameterInfo}
+ * 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
+ * Open*Info
instances and for {@link MXBean}s.
+ *
+ * originalType String {@link MBeanAttributeInfo},
+ * {@link MBeanOperationInfo}, {@link MBeanParameterInfo}
+ * 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
+ *
+ * "java.lang.management.MemoryType"
to represent the
+ * earlier type of an element with the converted type.
+ *
+ * severity Integer or String
+ * {@link MBeanNotificationInfo} Represents the severity
+ * of the notification, ranging from 1 (most severe) to 6 (least
+ * severe), with 0 representing unknown severity.
+ *
+ *
+ * since String Any
+ * The version in which this field was introduced.
+ *
+ *
+ * units String {@link MBeanAttributeInfo},
+ * {@link MBeanOperationInfo}, {@link MBeanParameterInfo}
+ * The units used by the value of an attribute or parameter,
+ * or the return value of an operation, such as "bytes"
,
+ * "milliseconds"
or "kilogrammes"
.
+ *
+ *
*
* @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);
+ }
+
+ /**
+ *
+ *
+ *
+ * @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();
+
+ /**
+ * null
, the other must be.name=value
. The value is converted
+ * to a String as follows:
+ *
+ *
+ * null
, the printed
+ * value will be empty."(" + string + ")"
.null
+ * if no value is present for the given field name.
+ *
+ * @param name the field name.
+ * @return the value of the field, or null
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 null
leads to behaviour equivalent to
+ * {@link #getFields()}. Field values are obtained as specified
+ * in {@link #getFieldValue(String)}, with null
+ * being returned if the field is not present. This applies
+ * even if the given field name is null
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);
+
+ /**
+ * n
, computed
+ * using n.toLowerCase().hashCode()
, and the
+ * hashcode of the value, v
, computed
+ * using:
+ *
+ *
+ *
+ * @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 v
is null
, then the
+ * hash code is 0.v
is a primitive array, then the
+ * hash code is computed using the appropriate method
+ * from {@link java.util.Arrays}.v
is an {@link java.lang.Object}
+ * array, then the hash code is computed using the
+ * {@link java.util.Arrays#deepHashCode(Object[])} method.v.hashCode()
.
+ * null
+ * 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 null
.
+ * @param values the values to use. The array must not be
+ * null
. 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 null
, 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 null
,
+ * 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()
+ {
+ }
+
+ /**
+ *
+ *
+ *
+ * @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");
+ }
+
+ /**
+ *
+ * public interface SomethingMBean
+ * {
+ * String getName();
+ * void setName(String name);
+ * void doStuff();
+ * }
+ *
+ *
+ * public interface SomethingMXBean
+ * {
+ * String getName();
+ * void setName(String name);
+ * List
+ *
+ *
+ *
+ * @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,
+ * Classequals(Object)
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.hashCode()
returns the same value for
+ * equivalent proxies.toString()
returns a textual representation
+ * of the proxy.MBeanServerInvocationHandler(conn,
+ * name, false)
. 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,
+ * ClassProxy.newProxyInstance(iface.getClassLoader(),
+ * new Class[] { iface }, handler)
. The
+ * {@link javax.management.NotificationEmitter} class is included as the
+ * second element of the array if broadcaster
is true.
+ * handler
refers to the invocation handler which forwards
+ * calls to the connection, which is created by a call to
+ * new MBeanServerInvocationHandler(conn, name)
.
+ *
+ *
+ *
+ *
+ *
+ * @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;
+
+/**
+ * handleNotification
+ * 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.
+ * null
if this thread should
+ * handle dispatch itself.
+ */
+ private Executor executor;
+
+ /**
+ * An array containing information on each
+ * notification, or null
if an
+ * empty array should be returned by
+ * {@link #getNotificationInfo()}.
+ */
+ private MBeanNotificationInfo[] info;
+
+ /**
+ * The list of listeners registered with
+ * this broadcaster.
+ */
+ private final ListNotificationBroadcasterSupport(null, null)
.
+ */
+ 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
+ * NotificationBroadcasterSupport(executor, null)
.
+ *
+ * @param executor the executor to use for each call to
+ * handleNotification()
.
+ * @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 NotificationBroadcasterSupport(null, info)
.
+ *
+ * @param info an array of {@link MBeanNotificationInfo} objects
+ * describing the notifications delivered by this
+ * broadcaster. This may be null
, 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
+ * handleNotification()
.
+ * @param info an array of {@link MBeanNotificationInfo} objects
+ * describing the notifications delivered by this
+ * broadcaster. This may be null
, 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 null
+ * if no filtering is required.
+ * @param passback an object to be passed to the listener with
+ * each notification.
+ * @throws IllegalArgumentException if listener
is
+ * null
.
+ * @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
+ * listener.handleNotification(notif, passback)
.
+ *
+ * @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
+ {
+ Iteratornull
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.");
+ }
+ }
+
+ /**
+ * null
, however,
+ * this thread calls the method itself in order to perform a
+ * synchronous dispatch of the notification to all eligible
+ * listeners.
+ * null
or returns true from the
+ * {@link NotificationFilter#isNotificationEnabled(Notification)}
+ * method.
+ * type.*
will
+ * match only notifications with a type beginning with
+ * code>type.*, not type.
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 Vectorprefix
+ * is null
.
+ */
+ 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 VectorpersistPolicy
field of the MBean/attribute
+ * descriptor. The state should be stored if the policy
+ * is set to any of the following:
+ *
+ *
+ * always
onTimer
and now
is
+ * greater than or equal to lastPersistTime +
+ * persistPeriod
.noMoreOftenThan
and now
is
+ * greater than or equal to lastPersistTime +
+ * persistPeriod
.
+ *
+ *
+ * @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
+ * never
onUpdate
onTimer
and now
is
+ * less than lastPersistTime + persistPeriod
.
+ * attrib.matches("*" + string + "*")
.
+ * 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, v1
, lies between v2
+ * and v3
.
+ *
+ * @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 v1
against v2
+ * and v3
. It returns true if
+ * v2 <= v1 <= v3
. 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 v1
by v2
.
+ *
+ * @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 v1
to v2
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
+ * attrib.matches("*" + string)
.
+ * 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 v1
to v2
to see if
+ * v1
is greater than or equal to v2
.
+ *
+ * @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 v1
to v2
to see if
+ * v1
is greater than v2
.
+ *
+ * @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, v
, is a member of the
+ * list, vlist
.
+ *
+ * @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 v
against the list, vlist
.
+ * 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
+ * attrib.matches(string + "*")
.
+ * 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 ((StringValueExp)
+ * className.apply(objectName)).getValue()
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 v1
to v2
to see if
+ * v1
is less than or equal to v2
.
+ *
+ * @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 v1
to v2
to see if
+ * v1
is less than v2
.
+ *
+ * @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);
+ }
+
+ /**
+ *
+ *
+ *
+ * @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
+ *
+ * v2
from v1
.
+ *
+ * @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
+ * q
. 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 v1
to v2
.
+ *
+ * @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 v1
by v2
.
+ *
+ * @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 val
. 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 val
. 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 val
. 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 val
. 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 val
. 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 val
. 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 val
.
+ */
+ 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
+ * exp1
and exp2
.
+ *
+ * @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
+ * exp1
and exp2
.
+ *
+ * @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
+ * classNameValue
.
+ *
+ * @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 InheritableThreadLocalnull
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 ArrayTypedim
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());
+ }
+
+ /**
+ * 1-dimension array
+ * of e
, 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.
+ * new ArrayType(SimpleType.INTEGER, true)
has the following
+ * values:
+ *
+ *
+ *
+ * @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}.Attribute Value
+ *
+ * Class Name [I
+ *
+ * Type Name [I
+ *
+ * Description 1-dimension array of int
+ * Element Type Class Name java.lang.Integer
+ * getPrimitiveArrayType(Integer.TYPE)
has the
+ * following values:
+ *
+ *
+ * Attribute Value
+ *
+ * Class Name [I
+ *
+ * Type Name [I
+ *
+ * Description 1-dimension array of int
+ * Element Type Class Name java.lang.Integer
+ *
* 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; + } + + /** *
* 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; + +/** + *
+ * 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. + *
+ *+ * As an example, consider the following interface: + *
+ *+ * public interface Person + * { + * public String getName(); + * public Date getBirthday(); + * } + *+ *
+ * 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. + *
+ *+ * 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. + *
+ *+ * 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. + *
+ * + * @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 SortedMapnull
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 Setnull
).
@@ -72,17 +72,17 @@ public class OpenMBeanAttributeInfoSupport
/**
* The possible legal values of the attribute (may be null
).
*/
- private Set legalValues;
+ private Set> legalValues;
/**
* The minimum value of the attribute (may be null
).
*/
- private Comparable minValue;
+ private Comparable