diff options
Diffstat (limited to 'libjava/classpath/javax/management')
101 files changed, 24476 insertions, 0 deletions
diff --git a/libjava/classpath/javax/management/Attribute.java b/libjava/classpath/javax/management/Attribute.java new file mode 100644 index 000000000..48f5db99d --- /dev/null +++ b/libjava/classpath/javax/management/Attribute.java @@ -0,0 +1,143 @@ +/* Attribute.java -- + Copyright (C) 2006 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 an MBean attribute, having the name and the assigned value. The + * MBean objects use this class to get and set attributes values. + * + * @since 1.5 + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class Attribute + implements Serializable +{ + /** + * Compatible with JDK 1.5 + */ + private static final long serialVersionUID = 2484220110589082382L; + + /** + * The attribute name. + */ + final String m_name; + + /** + * The attribute value. + */ + final Object m_value; + + /** + * Create the attribute with the given name and value. + * + * @param name the attribute name + * @param value the attribute value + */ + public Attribute(String name, Object value) + { + m_name = name; + m_value = value; + } + + /** + * Compares the attribute with another attribute. + * + * @param other the other object to compare with + * + * @return true if both value and object are equal, false otherwise. + */ + public boolean equals(Object other) + { + if (other instanceof Attribute) + { + Attribute oa = (Attribute) other; + boolean n, v; + if (oa.m_name == null || m_name == null) + n = oa.m_name == m_name; + else + n = oa.m_name.equals(m_name); + + if (oa.m_value == null || m_value == null) + v = oa.m_value == m_value; + else + v = oa.m_value.equals(m_value); + + return n && v; + + } + else + return false; + } + + /** + * Returns the attribute name. + * + * @return the attribute name + */ + public String getName() + { + return m_name; + } + + /** + * Returns the attribute value. + * + * @return the attribute value. + */ + public Object getValue() + { + return m_value; + } + + /** + * Need to override as {@link #equals} is overridden. + * + * @return the expression, dependent of the object and name hashcodes. + */ + public int hashCode() + { + int n = m_name == null ? 0 : m_name.hashCode(); + int v = m_value == null ? 0 : m_value.hashCode(); + + return n ^ v; + } + +} diff --git a/libjava/classpath/javax/management/AttributeChangeNotification.java b/libjava/classpath/javax/management/AttributeChangeNotification.java new file mode 100644 index 000000000..16dbf8647 --- /dev/null +++ b/libjava/classpath/javax/management/AttributeChangeNotification.java @@ -0,0 +1,164 @@ +/* AttributeChangeNotification.java -- Notification for attribute changes + Copyright (C) 2007 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package javax.management; + +/** + * Defines the notification used to let listeners know of + * an attribute change. The bean itself is responsible + * for creating and transmitting the notification when the + * attribute changes, by implementing + * {@link NotificationBroadcaster}. For example, if a + * bean increments the integer, <code>count</code>, it + * should send a notification with the + * <code>attributeName</code>, <code>"count"</code>, + * the <code>attributeType</code>, <code>"Integer"</code> + * and the old and new values of the attribute. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public class AttributeChangeNotification + extends Notification +{ + + /** + * Compatible with JDK 1.5 + */ + private static final long serialVersionUID = 535176054565814134L; + + /** + * The attribute type for attribute change + * notifications. + */ + public static final String ATTRIBUTE_CHANGE = "jmx.attribute.change"; + + /** + * The name of the attribute that changed. + */ + private String attributeName; + + /** + * The type of the attribute that changed. + */ + private String attributeType; + + /** + * The old value of the attribute. + */ + private Object oldValue; + + /** + * The new value of the attribute. + */ + private Object newValue; + + /** + * Constructs a new {@link AttributeChangeNotification} + * with the specified source, sequence number, timestamp, + * message, and the attribute name, type, old value and + * new value. + * + * @param source the producer of the notification, which + * is usually the bean that changed the + * attribute. + * @param sequenceNumber the sequence number of the + * notification. + * @param timeStamp the date and time of the notification. + * @param msg the message content of the notification. + * @param name the name of the attribute. + * @param type the type of the attribute. + * @param oldVal the old value of the attribute. + * @param newVal the new value of the attribute. + */ + public AttributeChangeNotification(Object source, + long sequenceNumber, + long timeStamp, + String msg, String name, + String type, Object oldVal, + Object newVal) + { + super(ATTRIBUTE_CHANGE, source, sequenceNumber, + timeStamp, msg); + attributeName = name; + attributeType = type; + oldValue = oldVal; + newValue = newVal; + } + + /** + * Returns the name of the attribute that changed. + * + * @return the name of the attribute. + */ + public String getAttributeName() + { + return attributeName; + } + + /** + * Returns the type of the attribute that changed. + * + * @return the type of the attribute. + */ + public String getAttributeType() + { + return attributeType; + } + + /** + * Returns the old value of the attribute. + * + * @return the old value. + */ + public Object getOldValue() + { + return oldValue; + } + + /** + * Returns the new value of the attribute. + * + * @return the new value. + */ + public Object getNewValue() + { + return newValue; + } + +} diff --git a/libjava/classpath/javax/management/AttributeChangeNotificationFilter.java b/libjava/classpath/javax/management/AttributeChangeNotificationFilter.java new file mode 100644 index 000000000..ef3af0d5a --- /dev/null +++ b/libjava/classpath/javax/management/AttributeChangeNotificationFilter.java @@ -0,0 +1,137 @@ +/* AttributeChangeNotificationFilter.java -- Filter on attribute name + Copyright (C) 2007 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package javax.management; + +import java.io.Serializable; + +import java.util.Vector; + +/** + * Performs filtering of {@link AttributeChangeNotification}s + * based on a list of attribute names. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public class AttributeChangeNotificationFilter + implements NotificationFilter, Serializable +{ + + /** + * Compatible with JDK 1.5 + */ + private static final long serialVersionUID = -6347317584796410029L; + + /** + * Lists the names of the attributes that may pass + * through the filter. + */ + private final Vector<String> enabledAttributes = new Vector<String>(); + + /** + * Blocks all {@link AttributeChangeNotification}s + * by emptying the list of enabled attributes. + */ + public void disableAllAttributes() + { + enabledAttributes.clear(); + } + + /** + * Removes the specified attribute name from the list + * of enabled attributes, thus preventing + * {@link AttributeChangeNotification}s for this attribute + * from passing through the filter. If the attribute is + * not enabled, this has no effect. + * + * @param name the name of the attribute to disable. + */ + public void disableAttribute(String name) + { + enabledAttributes.remove(name); + } + + /** + * Adds the specified attribute name to the list + * of enabled attributes, thus allowing + * {@link AttributeChangeNotification}s for this attribute + * to pass through the filter. If the attribute is + * enabled, this has no effect. + * + * @param name the name of the attribute to enable. + */ + public void enableAttribute(String name) + { + if (!enabledAttributes.contains(name)) + enabledAttributes.add(name); + } + + /** + * Returns the list of enabled attributes for this + * filter. + * + * @return the list of enabled attributes. + */ + public Vector<String> getEnabledAttributes() + { + return enabledAttributes; + } + + /** + * Returns true if the specified notification is an + * {@link AttributeChangeNotification} and the name of the + * attribute concerned is in the list of enabled attributes + * for this filter. + * + * @param notif the notification being filtered. + * @return true if the notification is an + * {@link AttributeChangeNotification} for an + * enabled attribute. + */ + public boolean isNotificationEnabled(Notification notif) + { + if (notif instanceof AttributeChangeNotification) + { + AttributeChangeNotification n = + (AttributeChangeNotification) notif; + return enabledAttributes.contains(n.getAttributeName()); + } + return false; + } + +} diff --git a/libjava/classpath/javax/management/AttributeList.java b/libjava/classpath/javax/management/AttributeList.java new file mode 100644 index 000000000..3d240b73b --- /dev/null +++ b/libjava/classpath/javax/management/AttributeList.java @@ -0,0 +1,220 @@ +/* AttributeList.java -- A list of MBean attributes. + Copyright (C) 2006 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.ArrayList; + +/** + * Represents a list of MBean {@link Attribute}s, with their + * names and values. This is implemented as an + * {@link java.util.ArrayList} extension, with additional + * methods typed to only allow the addition of {@link Attribute}s. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public class AttributeList + extends ArrayList<Object> +{ + + /** + * Compatible with JDK 1.5 + */ + private static final long serialVersionUID = -4077085769279709076L; + + /** + * Constructs an empty list with an initial capacity of ten. + * + * @see java.util.ArrayList#ArrayList() + */ + public AttributeList() + { + super(); + } + + /** + * Constructs an {@link AttributeList} using the contents + * of an existing list. The initial capacity is 110% of the + * size of the specified list. + * + * @param list the list to use to fill this list. + * @see java.util.ArrayList#ArrayList(java.util.Collection) + */ + public AttributeList(AttributeList list) + { + super(list); + } + + /** + * Constructs an empty list with the specified initial capacity. + * + * @param capacity the initial capacity of the list. + * @see java.util.ArrayList#ArrayList(int) + */ + public AttributeList(int capacity) + { + super(capacity); + } + + /** + * Adds the specified {@link Attribute} to the end of the list. + * + * @param attribute the attribute to add. + * @see java.util.Arraylist#add(Object) + */ + public void add(Attribute attribute) + { + super.add(attribute); + } + + /** + * <p> + * Adds the specified {@link Attribute} at the supplied index. + * Any attribute already at that index is moved up one place + * in the list to the position <code>(index + 1)</code>. + * Likewise, the attribute at <code>(index + 1)</code> is + * also moved up one place, continuing until the final + * attribute in the list moves to a new position, increasing + * the size of the list. + * </p> + * <p> + * If the index is invalid (i.e. it is smaller than zero, or + * greater than the current size of the list), a + * @link{RuntimeOperationsException} is thrown, which wraps + * the @link{IndexOutOfBoundsException} from the underlying + * array list. + * </p> + * + * @param index the index at which to place the new attribute. + * @param attribute the new attribute to add. + * @throws RuntimeOperationsException if <code>index < 0</code> + * or <code>index > size()</code> + * @see java.util.ArrayList#add(int, Object) + */ + public void add(int index, Attribute attribute) + { + try + { + super.add(index, attribute); + } + catch (IndexOutOfBoundsException e) + { + throw new RuntimeOperationsException(e, "Invalid index."); + } + } + + /** + * Adds all the {@link Attribute}s from the supplied list + * to the end of this list, in the order they are returned + * by the list's {@link java.util.Iterator}. + * + * @param list the list of attributes to add. + * @return true if the list changed. + * @see java.util.ArrayList#addAll(Collection) + */ + public boolean addAll(AttributeList list) + { + return super.addAll(list); + } + + /** + * <p> + * Adds all the {@link Attribute}s from the supplied list + * to this list, at the specified index. The attributes + * are added in the order they are returned by the + * list's {@link java.util.Iterator}. Any attribute already + * at that index is moved up one place in the list to the + * position <code>(index + list.size())</code>. + * Likewise, the attribute at <code>(index + list.size())</code> + * is also moved up one place, continuing until the final + * attribute in the original list. + * </p> + * <p> + * If the index is invalid (i.e. it is smaller than zero, or + * greater than the current size of the list), a + * @link{RuntimeOperationsException} is thrown, which wraps + * the @link{IndexOutOfBoundsException} from the underlying + * array list. + * </p> + * + * @param index the index at which to place the new attribute. + * @param list the list of attributes to add. + * @return true if the list changed. + * @throws RuntimeOperationsException if <code>index < 0</code> + * or <code>index > size()</code> + * @see java.util.ArrayList#addAll(int, Collection) + */ + public boolean addAll(int index, AttributeList list) + { + try + { + return super.addAll(index, list); + } + catch (IndexOutOfBoundsException e) + { + throw new RuntimeOperationsException(e, "Invalid index."); + } + } + + /** + * Replaces the attribute at the specified index with the one + * supplied. If the index is invalid (i.e. it is smaller than + * zero, or greater than the current size of the list), a + * @link{RuntimeOperationsException} is thrown, which wraps + * the @link{IndexOutOfBoundsException} from the underlying + * array list. + * + * @param index the index at which to place the new attribute. + * @param attribute the new attribute to add. + * @throws RuntimeOperationsException if <code>index < 0</code> + * or <code>index > size()</code> + * @see java.util.ArrayList#set(int, Object) + */ + public void set(int index, Attribute attribute) + { + try + { + super.set(index, attribute); + } + catch (IndexOutOfBoundsException e) + { + throw new RuntimeOperationsException(e, "Invalid index."); + } + } + +} diff --git a/libjava/classpath/javax/management/AttributeNotFoundException.java b/libjava/classpath/javax/management/AttributeNotFoundException.java new file mode 100644 index 000000000..4b1f4e690 --- /dev/null +++ b/libjava/classpath/javax/management/AttributeNotFoundException.java @@ -0,0 +1,70 @@ +/* AttributeNotFoundException.java -- Thrown by unknown attributes. + Copyright (C) 2006 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; + +/** + * Thrown when a attribute is requested but can not be + * found. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public class AttributeNotFoundException + extends OperationsException +{ + + /** + * Constructs a new <code>AttributeNotFoundException</code>. + */ + public AttributeNotFoundException() + { + super(); + } + + /** + * Constructs a new <code>AttributeNotFoundException</code> + * with the specified message. + * + * @param message the error message to give to the user. + */ + public AttributeNotFoundException(String message) + { + super(message); + } + +} diff --git a/libjava/classpath/javax/management/AttributeValueExp.java b/libjava/classpath/javax/management/AttributeValueExp.java new file mode 100644 index 000000000..6e8f5fbd2 --- /dev/null +++ b/libjava/classpath/javax/management/AttributeValueExp.java @@ -0,0 +1,181 @@ +/* AttributeValueExp.java -- Represents attributes to be passed to queries. + Copyright (C) 2007 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package javax.management; + +/** + * Represents an attribute value being used as an argument + * to a relational constraint. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public class AttributeValueExp + implements ValueExp +{ + + /** + * Compatible with JDK 1.5 + */ + private static final long serialVersionUID = -7768025046539163385L; + + /** + * The name of the attribute. + */ + private String attr; + + /** + * Constructs a new {@link AttributeValueExp}. + * + * @deprecated An instance created with a <code>null</code> + * attribute name can not be used in a query. + */ + @Deprecated public AttributeValueExp() + { + } + + /** + * Constructs a new {@link AttributeValueExp} using the + * specified attribute. + * + * @param attr the name of the attribute whose value + * will be used for this expression. + */ + public AttributeValueExp(String attr) + { + this.attr = attr; + } + + /** + * Applies the {@link AttributeValueExp} to the specified + * management bean by obtaining the attribute value from + * the {@link MBeanServer} and using it to create a + * {@link StringValueExp}. + * + * @param name the {@link ObjectName} of the bean to obtain + * the value from. + * @return a {@link StringValueExp} containing the result. + * @throws BadStringOperationException if an invalid string + * operation is used by + * the value expression. + * @throws BadBinaryOpValueExpException if an invalid expression + * is used by the value expression. + * @throws BadAttributeValueExpException if an invalid attribute + * is used by the value expression. + * @throws InvalidApplicationException if the value expression is applied + * to the wrong type of bean. + */ + public ValueExp apply(ObjectName name) + throws BadStringOperationException, BadBinaryOpValueExpException, + BadAttributeValueExpException, InvalidApplicationException + { + Object val = getAttribute(name); + if (val == null || !(val instanceof String)) + throw new BadAttributeValueExpException(val); + return new StringValueExp((String) val); + } + + /** + * Returns the value of the attribute by calling the + * {@link MBeanServer#getAttribute(ObjectName)} method of + * the server returned by {@link QueryEval#getMBeanServer()}. + * If an exception occurs, <code>null</code> is returned. + * + * @param name the {@link ObjectName} of the bean to obtain + * the value from. + * @return a {@link StringValueExp} containing the result. + */ + protected Object getAttribute(ObjectName name) + { + try + { + return QueryEval.getMBeanServer().getAttribute(name, attr); + } + catch (NullPointerException e) + { + return null; + } + catch (MBeanException e) + { + return null; + } + catch (AttributeNotFoundException e) + { + return null; + } + catch (InstanceNotFoundException e) + { + return null; + } + catch (ReflectionException e) + { + return null; + } + } + + /** + * Returns the attribute name. + * + * @return the attribute name. + */ + public String getAttributeName() + { + return attr; + } + + /** + * Sets the {@link MBeanServer} on which the query + * will be performed. + * + * @param server the new server. + */ + public void setMBeanServer(MBeanServer server) + { + /* This seems to do nothing any more */ + } + + /** + * Returns the attribute name, quoted. + * + * @return the quoted attribute name. + */ + public String toString() + { + return "'" + attr + "'"; + } + +} diff --git a/libjava/classpath/javax/management/BadAttributeValueExpException.java b/libjava/classpath/javax/management/BadAttributeValueExpException.java new file mode 100644 index 000000000..207a786de --- /dev/null +++ b/libjava/classpath/javax/management/BadAttributeValueExpException.java @@ -0,0 +1,90 @@ +/* BadAttributeValueExpException.java -- Thrown by invalid query attributes. + Copyright (C) 2006 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; + +/** + * Thrown when the value of an a attribute passed to a query proves to + * be invalid. This exception is only used internally by the Java + * management API and is not exposed to user code. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public class BadAttributeValueExpException + extends Exception +{ + + /** + * Compatible with JDK 1.5 + */ + private static final long serialVersionUID = -3105272988410493376L; + + /** + * The attribute value that caused the exception. + */ + private Object val; + + /** + * Constructs a new <code>BadAttributeValueExpException</code> + * using the specified object to represent the invalid value. + * + * @param val the inappropriate value. + */ + public BadAttributeValueExpException(Object val) + { + super(); + this.val = val; + } + + /** + * Returns a textual representation of this instance. This + * is constructed using the class name + * (<code>javax.management.BadAttributeValueExpException</code>) + * and the invalid value. + * + * @return a @link{java.lang.String} instance representing + * the instance in textual form. + */ + public String toString() + { + return getClass().getName() + + "[val=" + val + + "]"; + } + +} diff --git a/libjava/classpath/javax/management/BadBinaryOpValueExpException.java b/libjava/classpath/javax/management/BadBinaryOpValueExpException.java new file mode 100644 index 000000000..082b4a7db --- /dev/null +++ b/libjava/classpath/javax/management/BadBinaryOpValueExpException.java @@ -0,0 +1,101 @@ +/* BadBinaryOpValueExpException.java -- Thrown by invalid query expressions. + Copyright (C) 2006 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; + +/** + * Thrown when the expression passed to a method for constructing a + * query proves to be invalid. This exception is only used internally + * by the Java management API and is not exposed to user code. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public class BadBinaryOpValueExpException + extends Exception +{ + + /** + * Compatible with JDK 1.5 + */ + private static final long serialVersionUID = 5068475589449021227L; + + /** + * The value expression that caused the exception. + */ + private ValueExp exp; + + /** + * Constructs a new <code>BadBinaryOpValueExpException</code> + * using the specified expression to represent the invalid one. + * + * @param exp the inappropriate value expression. + */ + public BadBinaryOpValueExpException(ValueExp exp) + { + super(); + this.exp = exp; + } + + /** + * Returns the inappropriate value expression associated + * with this exception. + * + * @return the value expression. + */ + public ValueExp getExp() + { + return exp; + } + + /** + * Returns a textual representation of this instance. This + * is constructed using the class name + * (<code>javax.management.BadBinaryOpValueExpException</code>) + * and the invalid value expression. + * + * @return a @link{java.lang.String} instance representing + * the instance in textual form. + */ + public String toString() + { + return getClass().getName() + + "[exp=" + exp + + "]"; + } + +} diff --git a/libjava/classpath/javax/management/BadStringOperationException.java b/libjava/classpath/javax/management/BadStringOperationException.java new file mode 100644 index 000000000..261b352cb --- /dev/null +++ b/libjava/classpath/javax/management/BadStringOperationException.java @@ -0,0 +1,91 @@ +/* BadStringOperationException.java -- Thrown by invalid query attributes. + Copyright (C) 2006 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; + +/** + * Thrown when a string-based operation passed to a query proves to + * be invalid. This exception is only used internally by the Java + * management API and is not exposed to user code. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public class BadStringOperationException + extends Exception +{ + + /** + * Compatible with JDK 1.5 + */ + private static final long serialVersionUID = 7802201238441662100L; + + /** + * The operation that caused the exception. + */ + private String op; + + /** + * Constructs a new <code>BadStringOperationException</code> + * using the specified object to represent the invalid string + * operation. + * + * @param op the inappropriate string operation. + */ + public BadStringOperationException(String op) + { + super(); + this.op = op; + } + + /** + * Returns a textual representation of this instance. This + * is constructed using the class name + * (<code>javax.management.BadStringOperationException</code>) + * and the invalid string operation. + * + * @return a @link{java.lang.String} instance representing + * the instance in textual form. + */ + public String toString() + { + return getClass().getName() + + "[op=" + op + + "]"; + } + +} diff --git a/libjava/classpath/javax/management/DefaultLoaderRepository.java b/libjava/classpath/javax/management/DefaultLoaderRepository.java new file mode 100644 index 000000000..d331552a0 --- /dev/null +++ b/libjava/classpath/javax/management/DefaultLoaderRepository.java @@ -0,0 +1,152 @@ +/* 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. + */ + // API issue with lack of <?> on Class + @SuppressWarnings("unchecked") + public static Class loadClass(String name) + throws ClassNotFoundException + { + List<MBeanServer> servers = MBeanServerFactory.findMBeanServer(null); + for (MBeanServer server : servers) + { + try + { + return server.getClassLoaderRepository().loadClass(name); + } + catch (ClassNotFoundException e) + { + /* Ignored; try the next server. */ + } + } + throw new ClassNotFoundException("The class loaders of all registered " + + "servers failed to load the class, " + + name); + } + + /** + * <p> + * Attempts to load the given class using class loaders + * supplied by the repository of each {@link MBeanServer}. + * The {@link ClassLoader#loadClass(String)} + * method of each class loader is called. If the method + * returns successfully, then the returned {@link Class} instance + * is returned. If a {@link ClassNotFoundException} is thrown, + * then the next loader is tried. Any other exception thrown + * by the method is passed back to the caller. This method + * throws a {@link ClassNotFoundException} itself if all the + * class loaders listed prove fruitless. + * </p> + * <p> + * Note that this method may deadlock if called simultaneously + * by two class loaders in the list. + * {@link loadClassBefore(ClassLoader, String)} should be used + * in preference to this method to avoid this. + * </p> + * + * @param exclude the class loader to exclude, or <code>null</code> + * to obtain the same behaviour as {@link #loadClass(String)}. + * @param name the name of the class to load. + * @return the loaded class. + * @throws ClassNotFoundException if all the class loaders fail + * to load the class. + */ + // API issue with lack of <?> on Class + @SuppressWarnings("unchecked") + public static Class loadClassWithout(ClassLoader exclude, String name) + throws ClassNotFoundException + { + List<MBeanServer> servers = MBeanServerFactory.findMBeanServer(null); + for (MBeanServer server : servers) + { + try + { + return server.getClassLoaderRepository().loadClassWithout(exclude, + name); + } + catch (ClassNotFoundException e) + { + /* Ignored; try the next server. */ + } + } + throw new ClassNotFoundException("The class loaders of all registered " + + "servers failed to load the class, " + + name); + } + +} diff --git a/libjava/classpath/javax/management/Descriptor.java b/libjava/classpath/javax/management/Descriptor.java new file mode 100644 index 000000000..9a50b9e4e --- /dev/null +++ b/libjava/classpath/javax/management/Descriptor.java @@ -0,0 +1,392 @@ +/* Descriptor.java -- Metadata container. + Copyright (C) 2007 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package javax.management; + +import java.io.Serializable; + +/** + * <p> + * Provides metadata for a management element as a series + * of fields, formed from name-value pairs. Descriptors + * are usually attached to one of the <code>Info</code> + * classes, such as {@link MBeanAttributeInfo}. + * </p> + * <p> + * Field names are not case-sensitive, but are case-preserving + * (in that the same use of case will be returned by + * {@link #getFields()} and {@link #getFieldNames()}). + * The type of the value should match the type returned + * by the <code>getType()</code> method of the associated + * <code>Info</code> object. In the case of {@link MXBean}s, + * this should be the mapped type returned by the mapping rules. + * </p> + * <p> + * The contents of a descriptor may be immutable, in which + * case, attempts to change the contents of the descriptor + * will cause an exception to be thrown. Immutable descriptors + * are usually instances or subclasses of {@link ImmutableDescriptor}, + * while mutable descriptors are usually instances or subclasses + * of {@link javax.management.modelmbean.DescriptorSupport}. + * </p> + * <p> + * A series of field names are predefined, but additional + * ones can be added as needed. Predefined names never include + * a period ('.'), and so additional names may safely avoid + * conflicts by including this character. It is recommended that + * additional names make use of the same syntax as Java package + * names e.g. <code>gnu.classpath.ImportantMetadata</code>. + * </p> + * <p> + * The predefined names are as follows: + * </p> + * <table> + * <th> + * <td>Name</td><td>Type</td><td>Used In</td><td>Meaning</td> + * </th> + * <tr> + * <td>defaultValue</td><td>Object</td><td>{@link MBeanAttributeInfo}, + * {@link MBeanParameterInfo}</td><td>Default value for an attribute + * or parameter.</td> + * </tr> + * <tr> + * <td>deprecated</td><td>String</td><td>Any</td><td>The annotated element + * has been deprecated. Conventially, the field's value takes the form + * of the version in which the element was deprecated, followed by an + * explaination.</td> + * </tr> + * <tr> + * <td>descriptionResourceBundleBaseName</td><td>String</td><td>Any</td> + * <td>The base name for the bundle in which the <code>descriptionResourceKey</code> + * can be found.</td> + * </tr> + * <tr> + * <td>descriptionResourceKey</td><td>String</td><td>Any</td> + * <td>The name of the resource key which contains a localized description of + * this element.</td> + * </tr> + * <tr> + * <td>enabled</td><td>String</td><td>{@link MBeanAttributeInfo}, + * {@link MBeanNotificationInfo}, {@link MBeanOperationInfo}</td> + * <td>Specifies whether the annotated element is currently enabled or + * not, via a value of either <code>"true"</code> or <code>"false"</code>. + * </tr> + * <tr> + * <td>immutableInfo</td><td>String</td><td>{@link MBeanInfo}</td> + * <td>If the value of this field is <code>"true"</code>, this means that + * the annotated element will not change and thus may be cached.</td> + * </tr> + * <tr> + * <td>infoTimeout</td><td>String or Long</td><td>{@link MBeanInfo}</td> + * <td>If this field is present, and non-zero, it will contain a value + * in milliseconds for which the value of the annotated element will + * remain unchanged, allowing it to be safely cached for that period.</td> + * </tr> + * <tr> + * <td>interfaceClassName</td><td>String</td><td>{@link MBeanInfo}</td> + * <td>The Java interface name associated with the bean, as returned + * by {@link Class#getName()}.</td> + * </tr> + * <tr> + * <td>legalValues</td><td>Set<?></td><td>{@link MBeanAttributeInfo}, + * {@link MBeanParameterInfo}</td><td>Legal values for an attribute + * or parameter.</td> + * </tr> + * <tr> + * <td>maxValue</td><td>Object</td><td><td>{@link MBeanAttributeInfo}, + * {@link MBeanParameterInfo}</td><td>Maximum legal value for an attribute + * or parameter.</td> + * </tr> + * <tr> + * <td>metricType</td><td>String</td><td>{@link MBeanAttributeInfo}, + * {@link MBeanOperationInfo}</td><td>Specifies the type of metric represented + * by the annotated element. This will be either <code>"counter"</code> + * (an increasing value, which will only be reset and never decrease) + * or <code>"gauge"</code> (an increasing and decreasing value).</td> + * </tr> + * <tr> + * <td>minValue</td><td>Object</td><td>{@link MBeanAttributeInfo}, + * {@link MBeanParameterInfo}</td><td>Minimum legal value for an attribute + * or parameter.</td> + * </tr> + * <tr> + * <td>mxbean</td><td>String</td><td>{@link MBeanInfo}</td> + * <td>Specifies whether the annotated element is an {@link MXBean} or + * not, via a value of either <code>"true"</code> or <code>"false"</code>. + * </tr> + * <tr> + * <td>openType</td><td>{@link javax.management.openmbean.OpenType}</td> + * <td>{@link MBeanAttributeInfo}, {@link MBeanOperationInfo}</td>, + * {@link MBeanNotificationInfo}, {@link MBeanParameterInfo}</td> + * <td>Specifies the open type of the attribute or parameter, the return + * value of the operation or the user data of the notification respectively. + * This is present on <code>Open*Info</code> instances and for {@link MXBean}s.</td> + * <tr> + * <td>originalType</td><td>String</td><td>{@link MBeanAttributeInfo}, + * {@link MBeanOperationInfo}, {@link MBeanParameterInfo}</td> + * <td>The original Java type of an element which has been converted + * to another type according to the {@link MXBean} typing rules. + * For example, {@link java.lang.management.MemoryType} becomes a + * String after conversion. This field would contain + * <code>"java.lang.management.MemoryType"</code> to represent the + * earlier type of an element with the converted type.</td> + * </tr> + * <tr> + * <td>severity</td><td>Integer or String</td> + * <td>{@link MBeanNotificationInfo}</td><td>Represents the severity + * of the notification, ranging from 1 (most severe) to 6 (least + * severe), with 0 representing unknown severity.</td> + * </tr> + * <tr> + * <td>since</td><td>String</td><td>Any</td> + * <td>The version in which this field was introduced.</td> + * </tr> + * <tr> + * <td>units</td><td>String</td><td>{@link MBeanAttributeInfo}, + * {@link MBeanOperationInfo}, {@link MBeanParameterInfo}</td> + * <td>The units used by the value of an attribute or parameter, + * or the return value of an operation, such as <code>"bytes"</code>, + * <code>"milliseconds"</code> or <code>"kilogrammes"</code>. + * </tr> + * </table> + * <p>Some names are also defined as part of the Model MBeans package. + * See {@link javax.management.modelmbean.ModelMBeanInfo}.</p> + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public interface Descriptor + extends Serializable, Cloneable +{ + + /** + * Returns a clone of this descriptor, which can then be modified + * independently of this descriptor. If the descriptor is + * immutable, it is sufficient to return this instance. + * + * @return a clone of this descriptor. + * @throws RuntimeOperationsException if creation of the new + * descriptor fails for any + * reason. + */ + Object clone() + throws RuntimeOperationsException; + + /** + * <p> + * Returns true if this descriptor is equivalent to the + * supplied object. This is true if the following holds: + * </p> + * <ul> + * <li>The given object is also a {@link Descriptor}.</li> + * <li>Has the same field names, independent of case.</li> + * <li>Has the same values, based on the following: + * <ul> + * <li>If one value is <code>null</code>, the other must be.</li> + * <li>If one value is a primitive array, the other must be a + * primitive array of the same type with the same elements.</li> + * <li>If one value is an {@link Object} array, the other + * must be and {@link java.util.Arrays#deepEquals(Object[],Object[])} + * must return true.</li> + * <li>Otherwise, {@link Object#equals(Object)} must return true.</li> + * </ul> + * + * @param obj the object to compare according to the above. + * @return true if the above holds. + * @see Object#equals(Object) + * @see Object#hashCode() + * @since 1.6 + */ + boolean equals(Object obj); + + /** + * Returns the field names of the descriptor. If the + * descriptor is empty, an empty array is returned. + * + * @return the field names as an array of Strings. + */ + String[] getFieldNames(); + + /** + * <p> + * Returns all the field name and value pairs, in the + * form <code>name=value</code>. The value is converted + * to a String as follows: + * </p> + * <ul> + * <li>If the value is a String, it is used as is.</li> + * <li>If the value is <code>null</code>, the printed + * value will be empty.</li> + * <li>Otherwise, the value will be converted to a + * String using its {@link Object#toString()} method, + * and included as <code>"(" + string + ")"</code>.</li> + * </ul> + * <p>If the descriptor is empty, an empty array is returned.</p> + * + * @return the field names and values as an array of Strings. + * @see #setFields(String[],Object[]) + */ + String[] getFields(); + + /** + * Returns the value of the specified field, or <code>null</code> + * if no value is present for the given field name. + * + * @param name the field name. + * @return the value of the field, or <code>null</code> if there + * is no value present. + * @throws RuntimeOperationsException if the field name is illegal. + */ + Object getFieldValue(String name); + + /** + * Returns the values corresponding to the fields named in + * the specified array, in the same order. If an empty + * array is supplied, an empty array is returned. A value + * of <code>null</code> leads to behaviour equivalent to + * {@link #getFields()}. Field values are obtained as specified + * in {@link #getFieldValue(String)}, with <code>null</code> + * being returned if the field is not present. This applies + * even if the given field name is <code>null</code> or + * the empty string. + * + * @param names an array of field names whose values should + * be returned. + * @return the values of the specified fields. + * @see #getFields() + * @see #getFieldValue(String) + */ + Object[] getFieldValues(String... names); + + /** + * <p> + * Returns the hash code of the descriptor. The hashcode + * is computed as the sum of the hashcodes for each field, + * which in turn is calculated as the sum of + * the hashcode of the name, <code>n</code>, computed + * using <code>n.toLowerCase().hashCode()</code>, and the + * hashcode of the value, <code>v</code>, computed + * using: + * </p> + * <ul> + * <li>If <code>v</code> is <code>null</code>, then the + * hash code is 0.</li> + * <li>If <code>v</code> is a primitive array, then the + * hash code is computed using the appropriate method + * from {@link java.util.Arrays}.</li> + * <li>If <code>v</code> is an {@link java.lang.Object} + * array, then the hash code is computed using the + * {@link java.util.Arrays#deepHashCode(Object[])} method.</li> + * <li>Otherwise, the hashcode is equal to + * <code>v.hashCode()</code>. + * </ul> + * + * @return a hashcode for this descriptor. + * @since 1.6 + * @see Object#equals(Object) + * @see Object#hashCode() + */ + int hashCode(); + + /** + * Returns true if all the fields have legal values, given + * their names. Validity is determined by the implementation. + * + * @return true if the values are legal. + * @throws RuntimeOperationsException if the validity check + * fails for some reason. + */ + boolean isValid() + throws RuntimeOperationsException; + + /** + * Removes a field from the descriptor. If the field name + * is illegal or not found, this method fails silently. + * + * @param name the name of the field to remove. + * @throws RuntimeOperationsException if the field exists + * and the descriptor is + * immutable. This wraps + * an {@link UnsupportedOperationException}. + */ + void removeField(String name); + + /** + * Attempts to set the specified field to the supplied + * value. If the field does not exist, it will be created. + * If the field value given is invalid, then an exception will + * be thrown. Validity is determined by the implementation + * of the descriptor. + * + * @param name the field to set. Can not be <code>null</code> + * or empty. + * @param value the value to use, the validity of which is + * determined by the implementation. + * @throws RuntimeOperationsException if the name or value is + * illegal (wrapping a + * {@link IllegalArgumentException}) + * or if the descriptor is + * immutable (wrapping a + * {@link UnsupportedOperationException}. + */ + void setField(String name, Object value) + throws RuntimeOperationsException; + + /** + * Sets the field named in the first array to the corresponding + * value specified in the second. The array sizes must match. + * Empty arrays have no effect. An invalid value will cause + * an exception to be thrown. + * + * @param names the names of the fields to change. Neither + * the array or its elements may be <code>null</code>. + * @param values the values to use. The array must not be + * <code>null</code>. The value of the elements + * depends on the validity constraints of the + * implementation. + * @throws RuntimeOperationsException if the arrays differ in + * length, or a name or value is + * illegal (wrapping a + * {@link IllegalArgumentException}) + * or if the descriptor is + * immutable (wrapping a + * {@link UnsupportedOperationException}. + * @see #setField(String,Object) + */ + void setFields(String[] names, Object[] values); + +} diff --git a/libjava/classpath/javax/management/DescriptorAccess.java b/libjava/classpath/javax/management/DescriptorAccess.java new file mode 100644 index 000000000..189b34a22 --- /dev/null +++ b/libjava/classpath/javax/management/DescriptorAccess.java @@ -0,0 +1,65 @@ +/* DescriptorAccess.java -- Allows a descriptor to be changed. + Copyright (C) 2007 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package javax.management; + +/** + * Allows the descriptor of a management element + * to be changed. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public interface DescriptorAccess + extends DescriptorRead +{ + + /** + * Replaces the descriptor of this management element + * with the one specified. If the specified descriptor + * is <code>null</code>, the descriptor of the element + * will be returned to its default, which must at least + * contain a name and type. If the specified descriptor + * is invalid for this management element, an exception + * is thrown. + * + * @param descriptor the new descriptor to use. + * @see DescriptorRead#getDescriptor() + */ + void setDescriptor(Descriptor descriptor); + +} diff --git a/libjava/classpath/javax/management/DescriptorRead.java b/libjava/classpath/javax/management/DescriptorRead.java new file mode 100644 index 000000000..95e383afc --- /dev/null +++ b/libjava/classpath/javax/management/DescriptorRead.java @@ -0,0 +1,59 @@ +/* DescriptorRead.java -- Allows a descriptor to be read. + Copyright (C) 2007 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package javax.management; + +/** + * Provides read access to the descriptor of + * a management element. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.6 + */ +public interface DescriptorRead +{ + + /** + * Returns a copy of the descriptor for this management + * element. The return value is never <code>null</code>, + * but the returned descriptor may be empty. + * + * @return the descriptor for this management element. + */ + Descriptor getDescriptor(); + +} diff --git a/libjava/classpath/javax/management/DynamicMBean.java b/libjava/classpath/javax/management/DynamicMBean.java new file mode 100644 index 000000000..ceb47dcdc --- /dev/null +++ b/libjava/classpath/javax/management/DynamicMBean.java @@ -0,0 +1,162 @@ +/* DynamicMBean.java -- A management bean with a dynamic interface. + Copyright (C) 2006 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 management bean that provides a + * dynamic interface. Users of a {@link DynamicMBean} + * may retrieve information about its attributes at + * runtime and use this information to dynamically + * obtain the corresponding values of these attributes. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public interface DynamicMBean +{ + + /** + * Obtains the value of the specified attribute of the + * management bean. The management bean should perform + * a lookup for the named attribute, and return its value + * by calling the appropriate getter method, if possible. + * + * @param name the name of the attribute to retrieve. + * @return the value of the specified attribute. + * @throws AttributeNotFoundException if the name does not + * correspond to an attribute + * of the bean. + * @throws MBeanException if retrieving the attribute causes + * the bean to throw an exception (which + * becomes the cause of this exception). + * @throws ReflectionException if an exception occurred in trying + * to use the reflection interface + * to lookup the attribute. The + * thrown exception is the cause of + * this exception. + * @see #setAttribute(String) + */ + Object getAttribute(String name) + throws AttributeNotFoundException, MBeanException, + ReflectionException; + + /** + * Obtains the values of each of the specified attributes + * of the management bean. The returned list includes + * those attributes that were retrieved and their + * corresponding values. + * + * @param names the names of the attributes to retrieve. + * @return a list of the retrieved attributes. + * @see #setAttributes(AttributeList) + */ + AttributeList getAttributes(String[] names); + + /** + * Returns an information object which lists the attributes + * and actions associated with the management bean. + * + * @return a description of the management bean, including + * all exposed attributes and actions. + */ + MBeanInfo getMBeanInfo(); + + /** + * Invokes the specified action on the management bean using + * the supplied parameters. The signature of the action is + * specified by a {@link String} array, which lists the classes + * corresponding to each parameter. The class loader used to + * load these classes is the same as that used for loading the + * management bean itself. + * + * @param name the name of the action to invoke. + * @param params the parameters used to call the action. + * @param signature the signature of the action. + * @return the return value of the action. + * @throws MBeanException if the action throws an exception. The + * thrown exception is the cause of this + * exception. + * @throws ReflectionException if an exception occurred in trying + * to use the reflection interface + * to invoke the action. The + * thrown exception is the cause of + * this exception. + */ + Object invoke(String name, Object[] params, String[] signature) + throws MBeanException, ReflectionException; + + /** + * Sets the value of the specified attribute of the + * management bean. The management bean should perform + * a lookup for the named attribute, and sets its value + * using the associated setter method, if possible. + * + * @param attribute the attribute to set. + * @throws AttributeNotFoundException if the attribute does not + * correspond to an attribute + * of the bean. + * @throws InvalidAttributeValueException if the value is invalid + * for this particular + * attribute of the bean. + * @throws MBeanException if setting the attribute causes + * the bean to throw an exception (which + * becomes the cause of this exception). + * @throws ReflectionException if an exception occurred in trying + * to use the reflection interface + * to lookup the attribute. The + * thrown exception is the cause of + * this exception. + * @see #getAttribute(String) + */ + void setAttribute(Attribute attribute) + throws AttributeNotFoundException, InvalidAttributeValueException, + MBeanException, ReflectionException; + + /** + * Sets the value of each of the specified attributes + * to that supplied by the {@link Attribute} object. + * The returned list contains the attributes that were + * set and their new values. + * + * @param attributes the attributes to set. + * @return a list of the changed attributes. + * @see #getAttributes(AttributeList) + */ + AttributeList setAttributes(AttributeList attributes); + +} diff --git a/libjava/classpath/javax/management/InstanceAlreadyExistsException.java b/libjava/classpath/javax/management/InstanceAlreadyExistsException.java new file mode 100644 index 000000000..954df52c6 --- /dev/null +++ b/libjava/classpath/javax/management/InstanceAlreadyExistsException.java @@ -0,0 +1,75 @@ +/* InstanceAlreadyExistsException.java -- Thrown by invalid values. + Copyright (C) 2006 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; + +/** + * Thrown when an attempt to register a bean is made, and + * the bean is already registered. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public class InstanceAlreadyExistsException + extends OperationsException +{ + + /** + * Compatible with JDK 1.5 + */ + private static final long serialVersionUID = 8893743928912733931L; + + /** + * Constructs a new <code>InstanceAlreadyExistsException</code>. + */ + public InstanceAlreadyExistsException() + { + super(); + } + + /** + * Constructs a new <code>InstanceAlreadyExistsException</code> + * with the specified message. + * + * @param message the error message to give to the user. + */ + public InstanceAlreadyExistsException(String message) + { + super(message); + } + +} diff --git a/libjava/classpath/javax/management/InstanceNotFoundException.java b/libjava/classpath/javax/management/InstanceNotFoundException.java new file mode 100644 index 000000000..22eee35fa --- /dev/null +++ b/libjava/classpath/javax/management/InstanceNotFoundException.java @@ -0,0 +1,75 @@ +/* InstanceNotFoundException.java -- Thrown by invalid values. + Copyright (C) 2006 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; + +/** + * Thrown when an attempt to locate a bean is made, and + * the bean does not exist in the repository. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public class InstanceNotFoundException + extends OperationsException +{ + + /** + * Compatible with JDK 1.5 + */ + private static final long serialVersionUID = -882579438394773049L; + + /** + * Constructs a new <code>InstanceNotFoundException</code>. + */ + public InstanceNotFoundException() + { + super(); + } + + /** + * Constructs a new <code>InstanceNotFoundException</code> + * with the specified message. + * + * @param message the error message to give to the user. + */ + public InstanceNotFoundException(String message) + { + super(message); + } + +} diff --git a/libjava/classpath/javax/management/IntrospectionException.java b/libjava/classpath/javax/management/IntrospectionException.java new file mode 100644 index 000000000..dfca93b08 --- /dev/null +++ b/libjava/classpath/javax/management/IntrospectionException.java @@ -0,0 +1,77 @@ +/* IntrospectionException.java -- Thrown by bean introspection methods. + Copyright (C) 2006 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; + +/** + * A general for all exceptions thrown during introspection + * operations on management beans. For example, such an + * exception may be thrown while constructing one of + * the <code>MBeanXXXInfo</code> classes. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public class IntrospectionException + extends OperationsException +{ + + /** + * Compatible with JDK 1.5 + */ + private static final long serialVersionUID = 1054516935875481725L; + + /** + * Constructs a new <code>IntrospectionException</code>. + */ + public IntrospectionException() + { + super(); + } + + /** + * Constructs a new <code>IntrospectionException</code> + * with the specified message. + * + * @param message the error message to give to the user. + */ + public IntrospectionException(String message) + { + super(message); + } + +} diff --git a/libjava/classpath/javax/management/InvalidApplicationException.java b/libjava/classpath/javax/management/InvalidApplicationException.java new file mode 100644 index 000000000..b7a7e3cc6 --- /dev/null +++ b/libjava/classpath/javax/management/InvalidApplicationException.java @@ -0,0 +1,91 @@ +/* InvalidApplicationException.java -- Thrown by invalid query attributes. + Copyright (C) 2006 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; + +/** + * Thrown when a query or attribute is applied to a management bean + * which is of the wrong class. This exception is only used + * internally by the Java management API and is not exposed to user + * code. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public class InvalidApplicationException + extends Exception +{ + + /** + * Compatible with JDK 1.5 + */ + private static final long serialVersionUID = -3048022274675537269L; + + /** + * The attribute value that caused the exception. + */ + private Object val; + + /** + * Constructs a new <code>InvalidApplicationException</code> + * using the specified object to represent the invalid value. + * + * @param val the inappropriate expression. + */ + public InvalidApplicationException(Object val) + { + super(); + this.val = val; + } + + /** + * Returns a textual representation of this instance. This + * is constructed using the class name + * (<code>javax.management.InvalidApplicationException</code>) + * and the invalid expression. + * + * @return a @link{java.lang.String} instance representing + * the instance in textual form. + */ + public String toString() + { + return getClass().getName() + + "[val=" + val + + "]"; + } + +} diff --git a/libjava/classpath/javax/management/InvalidAttributeValueException.java b/libjava/classpath/javax/management/InvalidAttributeValueException.java new file mode 100644 index 000000000..1ec9fad60 --- /dev/null +++ b/libjava/classpath/javax/management/InvalidAttributeValueException.java @@ -0,0 +1,70 @@ +/* InvalidAttributeValueException.java -- Thrown by invalid values. + Copyright (C) 2006 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; + +/** + * Thrown when a value is given for an attribute which + * is invalid. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public class InvalidAttributeValueException + extends OperationsException +{ + + /** + * Constructs a new <code>InvalidAttributeValueException</code>. + */ + public InvalidAttributeValueException() + { + super(); + } + + /** + * Constructs a new <code>InvalidAttributeValueException</code> + * with the specified message. + * + * @param message the error message to give to the user. + */ + public InvalidAttributeValueException(String message) + { + super(message); + } + +} diff --git a/libjava/classpath/javax/management/JMException.java b/libjava/classpath/javax/management/JMException.java new file mode 100644 index 000000000..a46ac54c9 --- /dev/null +++ b/libjava/classpath/javax/management/JMException.java @@ -0,0 +1,70 @@ +/* JMException.java -- Thrown by the management classes. + Copyright (C) 2006 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; + +/** + * A general superclass for all non-runtime management + * exceptions. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public class JMException + extends Exception +{ + + /** + * Constructs a new <code>JMException</code>. + */ + public JMException() + { + super(); + } + + /** + * Constructs a new <code>JMException</code> + * with the specified message. + * + * @param message the error message to give to the user. + */ + public JMException(String message) + { + super(message); + } + +} diff --git a/libjava/classpath/javax/management/JMRuntimeException.java b/libjava/classpath/javax/management/JMRuntimeException.java new file mode 100644 index 000000000..d8eda330e --- /dev/null +++ b/libjava/classpath/javax/management/JMRuntimeException.java @@ -0,0 +1,70 @@ +/* JMRuntimeException.java -- Thrown by the management classes. + Copyright (C) 2006 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; + +/** + * A general superclass for all runtime management + * exceptions. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public class JMRuntimeException + extends RuntimeException +{ + + /** + * Constructs a new <code>JMRuntimeException</code>. + */ + public JMRuntimeException() + { + super(); + } + + /** + * Constructs a new <code>JMRuntimeException</code> + * with the specified message. + * + * @param message the error message to give to the user. + */ + public JMRuntimeException(String message) + { + super(message); + } + +} diff --git a/libjava/classpath/javax/management/JMX.java b/libjava/classpath/javax/management/JMX.java new file mode 100644 index 000000000..4a4958ace --- /dev/null +++ b/libjava/classpath/javax/management/JMX.java @@ -0,0 +1,344 @@ +/* JMX.java -- Static methods pertaining to the management API. + Copyright (C) 2007 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package javax.management; + +import java.lang.reflect.Proxy; + +/** + * Common static methods pertaining to the management + * API. There are no instances of this class. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.6 + */ +public class JMX +{ + + /** + * The name of the defaultValue field. + */ + public static final String DEFAULT_VALUE_FIELD = "defaultValue"; + + /** + * The name of the immutableInfo field. + */ + public static final String IMMUTABLE_INFO_FIELD = "immutableInfo"; + + /** + * The name of the interfaceClassName field. + */ + public static final String INTERFACE_CLASS_NAME_FIELD = "interfaceClassName"; + + /** + * The name of the legalValues field. + */ + public static final String LEGAL_VALUES_FIELD = "legalValues"; + + /** + * The name of the maxValue field. + */ + public static final String MAX_VALUE_FIELD = "maxValue"; + + /** + * The name of the minValue field. + */ + public static final String MIN_VALUE_FIELD = "minValue"; + + /** + * The name of the mxbean field. + */ + public static final String MXBEAN_FIELD = "mxbean"; + + /** + * The name of the openType field. + */ + public static final String OPEN_TYPE_FIELD = "openType"; + + /** + * The name of the originalType field. + */ + public static final String ORIGINAL_TYPE_FIELD = "originalType"; + + /** + * Prevent instance creation. + */ + private JMX() + { + } + + /** + * <p> + * Returns true if the given class represents an {@link MXBean} + * interface. An interface is an {@link MXBean interface} if: + * </p> + * <ul> + * <li>It is annotated with {@code @MXBean} or + * {@code @MXBean(true)}</li>. + * <li>Its name ends in {@code "MXBean"} and it does not + * have an {@link MXBean} annotation.</li> + * </ul> + * + * @param iface the interface class that is to be checked + * for {@link MXBean} status. + * @return true if the interface represents an {@link MXBean}. + * @throws NullPointerException if {@code iface} is {@code null}. + */ + public static boolean isMXBeanInterface(Class<?> iface) + { + MXBean annotation = iface.getAnnotation(MXBean.class); + if (annotation != null) + return annotation.value(); + return iface.getName().endsWith("MXBean"); + } + + /** + * <p> + * Returns a proxy for a standard management bean, using + * the specified connection to access the named implementation. + * To create a proxy for the bean, {@code SomethingMBean}, a call to + * {@code JMX.newMBeanProxy(server, name, SomethingMBean.class)} + * is made, where {@code server} is a local or remote management + * server, and {@code name} is the registered {@link ObjectName} + * of the implementation of {@code SomethingMBean} to use. + * </p> + * <p> + * The proxy redirects calls to the methods of the interface, + * {@link SomethingMBean}, to the appropriate methods of the + * management server. If {@link SomethingMBean} is specified + * as follows: + * </p> + * <pre> + * public interface SomethingMBean + * { + * String getName(); + * void setName(String name); + * void doStuff(); + * } + * </pre> + * <p> + * The proxy created above will provide these three methods + * using an instance of {@link MBeanServerInvocationHandler}. + * The two methods, {@code getName} and {@code setName} define + * an attribute, {@code Name}, so a call to {@code getName()} + * will return the value of {@code server.getAttribute(name, + * "Name")}, while {@code setName(newName)} will result in a + * call to {@code server.setAttribute(name, new Attribute("Name", + * newName))}. Finally, {@code doStuff()}, as an operation, + * will cause the proxy to call {@link MBeanServer#invoke(ObjectName, + * String, Object[], String[])} as + * {@code server.invoke(name, "doStuff", null, null)}. + * </p> + * <p> + * Calling this method is equivalent to calling + * {@link #newMBeanProxy(MBeanServerConnection, ObjectName, Class, + * boolean)}. + * </p> + * + * @param conn the server connection over which to forward calls to + * the bean. + * @param name the registered name of the bean to use to implement + * the given interface. + * @param iface the interface to provide a proxy for. + * @return a proxy implementing the specified interface using calls + * to the methods of the bean registered with the supplied + * server using the given name. + * @see #newMBeanProxy(MBeanServerConnection, ObjectName, Class, + * boolean) + */ + public static <T> T newMBeanProxy(MBeanServerConnection conn, + ObjectName name, Class<T> iface) + { + return newMBeanProxy(conn, name, iface, false); + } + + /** + * Returns a proxy for a standard management bean, using + * the specified connection to access the named implementation, + * as with {@link #newMBeanProxy(MBeanServerConnection, ObjectName, + * Class)}. In addition, the proxy returned by this method will + * also implement {@link NotificationEmitter} if {@code bcast} is + * true, under the assumption that the implementation referenced by + * {@code name} implements this interface. Calls to the methods of + * {@link NotificationEmitter} will be forwarded to the bean + * implementation via the appropriate server methods. + * + * @param conn the server connection over which to forward calls to + * the bean. + * @param name the registered name of the bean to use to implement + * the given interface. + * @param iface the interface to provide a proxy for. + * @param bcast true if the proxy should implement + * {@link NotificationEmitter}. + * @return a proxy implementing the specified interface using calls + * to the methods of the bean registered with the supplied + * server using the given name. + * @see #newMBeanProxy(MBeanServerConnection, ObjectName, Class) + */ + public static <T> T newMBeanProxy(MBeanServerConnection conn, + ObjectName name, Class<T> iface, + boolean bcast) + { + return MBeanServerInvocationHandler.newProxyInstance(conn, name, + iface, bcast); + } + + /** + * <p> + * Returns a proxy for a {@link MXBean}, using the specified + * connection to access the named implementation. + * To create a proxy for the bean, {@code SomethingMXBean}, a call to + * {@code JMX.newMXBeanProxy(server, name, SomethingMXBean.class)} + * is made, where {@code server} is a local or remote management + * server, and {@code name} is the registered {@link ObjectName} + * of the implementation of {@code SomethingMBean} to use. + * </p> + * <p> + * The proxy redirects calls to the methods of the interface, + * {@link SomethingMXBean}, to the appropriate methods of the + * management server with appropriate conversion between + * Java and open types, according to the MXBean rules. If + * {@link SomethingMXBean} is specified as follows: + * </p> + * <pre> + * public interface SomethingMXBean + * { + * String getName(); + * void setName(String name); + * List<Double> getStatistics(); + * void setStatistics(List<Double> statistics); + * List<Double> getNamedStatistics(String, Map<String,Integer>); + * } + * </pre> + * <p> + * The proxy created above will provide these five methods + * using an instance of {@link MBeanServerInvocationHandler}. + * The two methods, {@code getName} and {@code setName} define + * an attribute, {@code Name}, so a call to {@code getName()} + * will return the value of {@code server.getAttribute(name, + * "Name")}, while {@code setName(newName)} will result in a + * call to {@code server.setAttribute(name, new Attribute("Name", + * newName))}. As this uses a simple type, {@link String}, no + * conversion is necessary. + * </p> + * <p> + * The two methods, {@code getStatistics} and {@code setStatistics} + * similarly define another attribute, {@code Statistics}. Calling + * {@code getStatistics()} will cause a call to the server to be + * made as before, {@code server.getAttribute(name, "Statistics")}. + * However, the type of the return value from this call will be + * an array of {@link Double} objects, as per the {@link MXBean} + * rules. The proxy converts this back in to a {@link java.util.List} + * of {@link Double} objects before returning it. + * </p> + * <p> + * The same process is applied in reverse for + * {@code setStatistics(newStats)}. The list is converted into + * an appropriate array before the call to + * {@link MBeanServerConnection#setAttribute(ObjectName, Attribute)} + * is made. Finally, a call to {@code getNamedStatistics} will require + * both a Java to open type conversion on the arguments, and then + * an open type to Java conversion of the return value. Thus, a proxy + * enables an {@link MXBean} to be used in cases where the appropriate + * Java types are available and the user wishes to access the bean + * using the types directly defined in its interface, just as with + * standard management beans. + * </p> + * <p> + * Calling this method is equivalent to calling + * {@link #newMXBeanProxy(MBeanServerConnection, ObjectName, Class, + * boolean)}. + * </p> + * + * @param conn the server connection over which to forward calls to + * the bean. + * @param name the registered name of the bean to use to implement + * the given interface. + * @param iface the interface to provide a proxy for. + * @return a proxy implementing the specified interface using calls + * to the methods of the bean registered with the supplied + * server using the given name. + * @see #newMXBeanProxy(MBeanServerConnection, ObjectName, Class, + * boolean) + */ + public static <T> T newMXBeanProxy(MBeanServerConnection conn, + ObjectName name, Class<T> iface) + { + return newMXBeanProxy(conn, name, iface, false); + } + + /** + * Returns a proxy for a {@link MXBean}, using + * the specified connection to access the named implementation, + * as with {@link #newMXBeanProxy(MBeanServerConnection, ObjectName, + * Class)}. In addition, the proxy returned by this method will + * also implement {@link NotificationEmitter} if {@code bcast} is + * true, under the assumption that the implementation referenced by + * {@code name} implements this interface. Calls to the methods of + * {@link NotificationEmitter} will be forwarded to the bean + * implementation via the appropriate server methods. + * + * @param conn the server connection over which to forward calls to + * the bean. + * @param name the registered name of the bean to use to implement + * the given interface. + * @param iface the interface to provide a proxy for. + * @param bcast true if the proxy should implement + * {@link NotificationEmitter}. + * @return a proxy implementing the specified interface using calls + * to the methods of the bean registered with the supplied + * server using the given name. + * @see #newMXBeanProxy(MBeanServerConnection, ObjectName, Class) + */ + // Suppress warnings as we know an instance of T will be returned. + @SuppressWarnings("unchecked") + public static <T> T newMXBeanProxy(MBeanServerConnection conn, + ObjectName name, Class<T> iface, + boolean bcast) + { + if (bcast) + return (T) Proxy.newProxyInstance(iface.getClassLoader(), + new Class[] { iface, + NotificationEmitter.class }, + new MBeanServerInvocationHandler(conn,name,true)); + else + return (T) Proxy.newProxyInstance(iface.getClassLoader(), + new Class[] { iface }, + new MBeanServerInvocationHandler(conn,name,true)); + } + +} diff --git a/libjava/classpath/javax/management/ListenerNotFoundException.java b/libjava/classpath/javax/management/ListenerNotFoundException.java new file mode 100644 index 000000000..6fd6a1609 --- /dev/null +++ b/libjava/classpath/javax/management/ListenerNotFoundException.java @@ -0,0 +1,74 @@ +/* ListenerNotFoundException.java -- Thrown when a listener does not exist. + Copyright (C) 2006 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; + +/** + * Thrown when a requested listener does not exist. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public class ListenerNotFoundException + extends OperationsException +{ + + /** + * Compatible with JDK 1.5 + */ + private static final long serialVersionUID = -7242605822448519061L; + + /** + * Constructs a new <code>ListenerNotFoundException</code>. + */ + public ListenerNotFoundException() + { + super(); + } + + /** + * Constructs a new <code>ListenerNotFoundException</code> + * with the specified message. + * + * @param message the error message to give to the user. + */ + public ListenerNotFoundException(String message) + { + super(message); + } + +} diff --git a/libjava/classpath/javax/management/MBeanAttributeInfo.java b/libjava/classpath/javax/management/MBeanAttributeInfo.java new file mode 100644 index 000000000..950e06303 --- /dev/null +++ b/libjava/classpath/javax/management/MBeanAttributeInfo.java @@ -0,0 +1,315 @@ +/* MBeanAttributeInfo.java -- Information about an attribute of a bean. + Copyright (C) 2006 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.Method; +import java.lang.reflect.Type; + +/** + * Describes the attributes of a management bean. + * The information in this class is immutable as standard. + * Of course, subclasses may change this, but this + * behaviour is not recommended. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public class MBeanAttributeInfo + extends MBeanFeatureInfo + implements Cloneable +{ + + /** + * Compatible with JDK 1.6 + */ + private static final long serialVersionUID = 8644704819898565848L; + + /** + * The type of the attribute. + * + * @serial the attribute type. + */ + private String attributeType; + + /** + * True if the attribute's value can be changed. + * + * @serial true if the value can be changed. + */ + private boolean isWrite; + + /** + * True if the attribute's value can be read. + * + * @serial true if the value can be read. + */ + private boolean isRead; + + /** + * True if the attribute is a boolean and thus + * has a isXXX accessor rather than a getXXX accessor. + * + * @serial true if the attribute has an isXXX accessor. + */ + private boolean is; + + /** + * Constructs a new {@link MBeanAttributeInfo} using the specified + * name and description, with the given accessor and mutator + * methods. A <code>null</code> value for the accessor method + * indicates that the value can not be read. A <code>null</code> + * value for the mutator method indicates that the value can not be + * changed. + * + * @param name the name of the attribute. + * @param desc a description of the attribute. + * @param getter the accessor method, or <code>null</code> if the value + * can not be read. + * @param setter the mutator method, or <code>null</code> if the value + * can not be changed. + * @throws IntrospectionException if both the accessor and mutator method + * are <code>null</code>. + */ + public MBeanAttributeInfo(String name, String desc, + Method getter, Method setter) + throws IntrospectionException + { + super(name, desc); + if (getter == null && setter == null) + throw new IntrospectionException("Both the getter and setter methods can " + + "not be null."); + if (getter == null) + { + Type t = setter.getGenericParameterTypes()[0]; + if (t instanceof Class) + attributeType = ((Class<?>) t).getName(); + else + attributeType = t.toString(); + isRead = false; + is = false; + } + else + { + Type t = getter.getGenericReturnType(); + if (t instanceof Class) + attributeType = ((Class<?>) t).getName(); + else + attributeType = t.toString(); + isRead = true; + is = getter.getName().startsWith("is"); + } + if (setter != null) + isWrite = true; + } + + /** + * Constructs a new {@link MBeanAttributeInfo} using the specified + * name, description and type with the given settings for the accessor + * and mutator methods. + * + * @param name the name of the attribute. + * @param type the type of the attribute, in the form of its class name. + * @param desc a description of the attribute. + * @param isReadable true if the attribute's value can be read. + * @param isWritable true if the attribute's value can be changed. + * @param isIs true if the attribute uses an accessor of the form isXXX. + * @throws IllegalArgumentException if the attribute is both unreadable + * and unwritable. + */ + public MBeanAttributeInfo(String name, String type, String desc, + boolean isReadable, boolean isWritable, + boolean isIs) + { + super(name, desc); + if (!isReadable && !isWritable) + throw new IllegalArgumentException("The attribute can not be both " + + "unreadable and unwritable."); + attributeType = type; + isRead = isReadable; + isWrite = isWritable; + is = isIs; + } + + /** + * Returns a clone of this instance. The clone is created + * using just the method provided by {@link java.lang.Object}. + * Thus, the clone is just a shallow clone as returned by + * that method, and does not contain any deeper cloning based + * on the subject of this class. + * + * @return a clone of this instance. + * @see java.lang.Cloneable + */ + public Object clone() + { + try + { + return super.clone(); + } + catch (CloneNotSupportedException e) + { + /* This shouldn't happen; we implement Cloneable */ + throw new IllegalStateException("clone() called on " + + "non-cloneable object."); + } + } + + /** + * Compares this feature with the supplied object. This + * returns true iff the object is an instance of + * {@link MBeanAttributeInfo}, {@link Object#equals()} + * returns true for a comparison of both the name and + * description of this attribute with that of the specified + * object (performed by the superclass), and the type and + * boolean flags of the two instances are equal. + * + * @param obj the object to compare. + * @return true if the object is a {@link MBeanAttributeInfo} + * instance, + * <code>name.equals(object.getName())</code>, + * <code>description.equals(object.getDescription())</code>, + * <code>attributeType.equals(object.getType())</code>, + * <code>isRead == object.isReadable()</code>, + * <code>isWrite == object.isWritable()</code>, + * <code>is == object.isIs()</code> + */ + public boolean equals(Object obj) + { + if (!(obj instanceof MBeanAttributeInfo)) + return false; + if (!(super.equals(obj))) + return false; + MBeanAttributeInfo o = (MBeanAttributeInfo) obj; + return (attributeType.equals(o.getType()) && + isRead == o.isReadable() && + isWrite == o.isWritable() && + is == o.isIs()); + } + + /** + * Returns the type of this attribute, in the form of its class name. + * + * @return the type of this attribute. + */ + public String getType() + { + return attributeType; + } + + /** + * Returns the hashcode of the attribute information as the sum of + * the hashcode of the superclass, the hashcode of the type, + * the hashcode of {@link #isReadable()}, twice the hashcode + * of {@link #isWritable()} and four times the hashcode + * of {@link #isIs()}. + * + * @return the hashcode of the attribute information. + */ + public int hashCode() + { + return super.hashCode() + attributeType.hashCode() + + Boolean.valueOf(isRead).hashCode() + + (2 * Boolean.valueOf(isWrite).hashCode()) + + (4 * Boolean.valueOf(is).hashCode()); + } + + /** + * Returns true if the accessor method of this attribute + * is of the form <code>isXXX</code>. + * + * @return true if the accessor takes the form <code>isXXX</code>. + */ + public boolean isIs() + { + return is; + } + + /** + * Returns true if value of this attribute can be read. + * + * @return true if the value of the attribute can be read. + */ + public boolean isReadable() + { + return isRead; + } + + /** + * Returns true if the value of this attribute can be changed. + * + * @return true if the value of the attribute can be changed. + */ + public boolean isWritable() + { + return isWrite; + } + + /** + * <p> + * Returns a textual representation of this instance. This + * is constructed using the class name + * (<code>javax.management.MBeanAttributeInfo</code>), + * the name, description and type of the attribute and the + * current settings of the {@link #isReadable()}, + * {@link #isWritable()} and {@link #isIs()} properties. + * </p> + * <p> + * As instances of this class are immutable, the return value + * is computed just once for each instance and reused + * throughout its life. + * </p> + * + * @return a @link{java.lang.String} instance representing + * the instance in textual form. + */ + public String toString() + { + if (string == null) + { + super.toString(); + string = string.substring(0, string.length() - 1) + + ",type=" + attributeType + + ",isReadable=" + (isRead ? "yes" : "no") + + ",isWritable=" + (isWrite ? "yes" : "no") + + ",isIs=" + (is ? "yes" : "no") + + "]"; + } + return string; + } + +} diff --git a/libjava/classpath/javax/management/MBeanConstructorInfo.java b/libjava/classpath/javax/management/MBeanConstructorInfo.java new file mode 100644 index 000000000..509483f25 --- /dev/null +++ b/libjava/classpath/javax/management/MBeanConstructorInfo.java @@ -0,0 +1,241 @@ +/* MBeanConstructorInfo.java -- Information about a bean's constructor. + Copyright (C) 2006 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.Constructor; +import java.lang.reflect.Type; + +import java.util.Arrays; + +/** + * Describes the constructors of a management bean. + * The information in this class is immutable as standard. + * Of course, subclasses may change this, but this + * behaviour is not recommended. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public class MBeanConstructorInfo + extends MBeanFeatureInfo + implements Cloneable +{ + + /** + * Compatible with JDK 1.5 + */ + private static final long serialVersionUID = 4433990064191844427L; + + /** + * The signature of the constructor i.e. the argument types. + */ + private MBeanParameterInfo[] signature; + + /** + * Constructs a @link{MBeanConstructorInfo} with the specified + * description using the given constructor. Each parameter is + * described merely by its type; the name and description are + * <code>null</code>. + * + * @param desc a description of the attribute. + * @param cons the constructor. + */ + // API issue with lack of <?> on Constructor + @SuppressWarnings("unchecked") + public MBeanConstructorInfo(String desc, Constructor cons) + { + super(cons.getName(), desc); + Type[] paramTypes = cons.getGenericParameterTypes(); + signature = new MBeanParameterInfo[paramTypes.length]; + for (int a = 0; a < paramTypes.length; ++a) + { + Type t = paramTypes[a]; + if (t instanceof Class) + signature[a] = new MBeanParameterInfo(null, + ((Class<?>) t).getName(), + null); + else + signature[a] = new MBeanParameterInfo(null, t.toString(), null); + } + } + + /** + * Constructs a @link{MBeanConstructorInfo} with the specified + * name, description and parameter information. A <code>null</code> + * value for the parameter information is the same as passing in + * an empty array. A copy of the parameter array is taken, so + * later changes have no effect. + * + * @param name the name of the constructor. + * @param desc a description of the constructor. + * @param sig the signature of the constructor, as a series + * of {@link MBeanParameterInfo} objects, one for + * each parameter. + */ + public MBeanConstructorInfo(String name, String desc, + MBeanParameterInfo[] sig) + { + super(name, desc); + if (sig == null) + signature = new MBeanParameterInfo[0]; + else + { + signature = new MBeanParameterInfo[sig.length]; + System.arraycopy(sig, 0, signature, 0, sig.length); + } + } + + /** + * Returns a clone of this instance. The clone is created + * using just the method provided by {@link java.lang.Object}. + * Thus, the clone is just a shallow clone as returned by + * that method, and does not contain any deeper cloning based + * on the subject of this class. + * + * @return a clone of this instance. + * @see java.lang.Cloneable + */ + public Object clone() + { + try + { + return super.clone(); + } + catch (CloneNotSupportedException e) + { + /* This shouldn't happen; we implement Cloneable */ + throw new IllegalStateException("clone() called on " + + "non-cloneable object."); + } + } + + /** + * Compares this feature with the supplied object. This returns + * true iff the object is an instance of {@link + * MBeanConstructorInfo}, {@link Object#equals()} returns true for a + * comparison of both the name and description of this notification + * with that of the specified object (performed by the superclass), + * and the two signature arrays contain the same elements in the + * same order (but one may be longer than the other). + * + * @param obj the object to compare. + * @return true if the object is a {@link MBeanConstructorInfo} + * instance, + * <code>name.equals(object.getName())</code>, + * <code>description.equals(object.getDescription())</code> + * and the corresponding elements of the signature arrays are + * equal. + */ + public boolean equals(Object obj) + { + if (!(obj instanceof MBeanConstructorInfo)) + return false; + if (!(super.equals(obj))) + return false; + MBeanConstructorInfo o = (MBeanConstructorInfo) obj; + MBeanParameterInfo[] sig = o.getSignature(); + for (int a = 0; a < signature.length; ++a) + { + if (a == sig.length) + return true; + if (!(signature[a].equals(sig[a]))) + return false; + } + return true; + } + + /** + * Returns the constructor's signature, in the form of + * information on each parameter. Each parameter is + * described by an instance of {@link MBeanParameterInfo}. + * The returned array is a shallow copy of the array used + * by this instance, so changing which elements are stored + * in the array won't affect the array used by this, but + * changing the actual elements will affect the ones used + * here. + * + * @return an array of {@link MBeanParameterInfo} objects, + * describing the constructor parameters. + */ + public MBeanParameterInfo[] getSignature() + { + return (MBeanParameterInfo[]) signature.clone(); + } + + /** + * Returns the hashcode of the constructor information as the sum + * of the hashcode of the superclass and the hashcode of the parameter + * array. + * + * @return the hashcode of the constructor information. + */ + public int hashCode() + { + return super.hashCode() + Arrays.hashCode(signature); + } + + /** + * <p> + * Returns a textual representation of this instance. This + * is constructed using the class name + * (<code>javax.management.MBeanConstructorInfo</code>), + * the name and description of the constructor and the + * contents of the array of parameters. + * </p> + * <p> + * As instances of this class are immutable, the return value + * is computed just once for each instance and reused + * throughout its life. + * </p> + * + * @return a @link{java.lang.String} instance representing + * the instance in textual form. + */ + public String toString() + { + if (string == null) + { + super.toString(); + string = string.substring(0, string.length() - 1) + + ",signature=" + Arrays.toString(signature) + + "]"; + } + return string; + } + +} diff --git a/libjava/classpath/javax/management/MBeanException.java b/libjava/classpath/javax/management/MBeanException.java new file mode 100644 index 000000000..7ce81dedb --- /dev/null +++ b/libjava/classpath/javax/management/MBeanException.java @@ -0,0 +1,117 @@ +/* MBeanException.java -- A user-defined management exception. + Copyright (C) 2006 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package javax.management; + +/** + * Represents an arbitrary exception thrown by a management + * bean. When a management bean executes code that causes + * an exception to be thrown, the resulting exception is + * wrapped inside an {@link MBeanException}. Calling + * {@link getTargetException()} will return the wrapped + * exception. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public class MBeanException + extends JMException +{ + + /** + * Compatible with JDK 1.5 + */ + private static final long serialVersionUID = 4066342430588744142L; + + /* Sun re-implemented causality -- don't know why, but + serialization demands we do too... */ + + /** + * The target exception. + * + * @serial the target exception. + */ + private Exception exception; + + /** + * Constructs a new <code>MBeanException</code> wrapping + * the specified exception. + * + * @param e the exception to be wrapped. + */ + public MBeanException(Exception e) + { + super(); + exception = e; + } + + /** + * Constructs a new <code>MBeanException</code> wrapping + * the specified exception and using the supplied message. + * + * @param e the exception to be wrapped. + * @param message the error message to give to the user. + */ + public MBeanException(Exception e, String message) + { + super(message); + exception = e; + } + + /** + * Returns the true cause of this exception, the wrapped + * exception. + * + * @return the wrapped exception. + */ + public Throwable getCause() + { + return exception; + } + + /** + * Returns the true cause of this exception, the wrapped + * exception. + * + * @return the wrapped exception. + */ + public Exception getTargetException() + { + return exception; + } + +} diff --git a/libjava/classpath/javax/management/MBeanFeatureInfo.java b/libjava/classpath/javax/management/MBeanFeatureInfo.java new file mode 100644 index 000000000..a459ae946 --- /dev/null +++ b/libjava/classpath/javax/management/MBeanFeatureInfo.java @@ -0,0 +1,201 @@ +/* MBeanFeatureInfo.java -- Information about a bean feature. + Copyright (C) 2006 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.IOException; +import java.io.ObjectOutputStream; +import java.io.Serializable; + +/** + * A general superclass for the description of features + * of management beans. This allows the user to access + * the feature dynamically, without knowing the details + * beforehand. The information is immutable as standard. + * Of course, subclasses may change this, but this + * behaviour is not recommended. + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public class MBeanFeatureInfo + implements Serializable +{ + + /** + * Compatible with JDK 1.5 + */ + private static final long serialVersionUID = 3952882688968447265L; + + /** + * A description of the feature in human-readable form. + * Subclasses should access this via the {@link #getDescription()} + * function rather than using the value directly. + * + * @serial a description of the feature. + */ + protected String description; + + /** + * The name of the feature. Subclasses should access this + * via the {@link #getName()} function rather than using the + * value directly. + * + * @serial the name of the feature. + */ + protected String name; + + /** + * The <code>toString()</code> result of this instance. + */ + transient String string; + + /** + * Constructs a new {@link MBeanFeatureInfo} with the specified + * name and description. + * + * @param name the name of the management bean feature. + * @param description the description of the feature. + */ + public MBeanFeatureInfo(String name, String description) + { + this.name = name; + this.description = description; + } + + /** + * Compares this feature with the supplied object. This + * returns true iff the object is an instance of + * {@link MBeanFeatureInfo} and {@link Object#equals()} + * returns true for a comparison of both the name and + * description of this feature with that of the specified + * object. + * + * @param obj the object to compare. + * @return true if the object is a {@link MBeanFeatureInfo} + * instance, + * <code>name.equals(object.getName())</code> and + * <code>description.equals(object.getDescription</code>. + */ + public boolean equals(Object obj) + { + if (obj instanceof MBeanFeatureInfo) + { + MBeanFeatureInfo o = (MBeanFeatureInfo) obj; + return ((name == null ? + o.getName() == null : + name.equals(o.getName())) && + (description == null ? + o.getDescription() == null : + description.equals(o.getDescription()))); + } + else + return false; + } + + /** + * Returns a description of this feature. + * + * @return a human-readable description. + */ + public String getDescription() + { + return description; + } + + /** + * Returns the name of this feature. + * + * @return the name of the feature. + */ + public String getName() + { + return name; + } + + /** + * Returns the hashcode of the feature as + * the sum of the hashcodes of its name + * and description. + * + * @return the hashcode of this feature. + */ + public int hashCode() + { + return (name == null ? -1 : name.hashCode()) + + (description == null ? -1 : description.hashCode()); + } + + /** + * <p> + * Returns a textual representation of this instance. This + * is constructed using the class name + * (<code>javax.management.MBeanFeatureInfo</code>) and + * the name and description of the feature. + * </p> + * <p> + * As instances of this class are immutable, the return value + * is computed just once for each instance and reused + * throughout its life. + * </p> + * + * @return a @link{java.lang.String} instance representing + * the instance in textual form. + */ + public String toString() + { + if (string == null) + string = getClass().getName() + + "[name=" + name + + ",desc=" + description + + "]"; + return string; + } + + /** + * Serialize the {@link MBeanFeatureInfo}. + * + * @param out the output stream to write to. + * @throws IOException if an I/O error occurs. + */ + private void writeObject(ObjectOutputStream out) + throws IOException + { + out.defaultWriteObject(); + /* FIXME: Handle extra 1.6 descriptor stuff */ + } + +} diff --git a/libjava/classpath/javax/management/MBeanInfo.java b/libjava/classpath/javax/management/MBeanInfo.java new file mode 100644 index 000000000..bf07f9ad0 --- /dev/null +++ b/libjava/classpath/javax/management/MBeanInfo.java @@ -0,0 +1,402 @@ +/* MBeanInfo.java -- Information about a management bean. + Copyright (C) 2006 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.Arrays; + +/** + * <p> + * Describes the interface of a management bean. This allows + * the user to access the bean dynamically, without knowing + * the details of any of its attributes, operations, + * constructors or notifications beforehand. The information + * is immutable as standard. Of course, subclasses may change + * this, but this behaviour is not recommended. + * </p> + * <p> + * The contents of this class, for standard management beans, + * are dynamically compiled using reflection. + * {@link #getClassName()} and {@link #getConstructors()} + * return the name of the class and its constructors, respectively. + * This is much the same as could be obtained by reflection on the + * bean. {@link #getAttributes()} and {@link #getOperations()}, + * however, do something more in splitting the methods of the + * class into two sets. Those of the form, <code>getXXX</code>, + * <code>setXXX</code> and <code>isXXX</code> are taken to be + * the accessors and mutators of a series of attributes, with + * <code>XXX</code> being the attribute name. These are returned + * by {@link getAttributes()} and the {@link Attribute} class can + * be used to manipulate them. The remaining methods are classified + * as operations and returned by {@link getOperations()}. + * </p> + * <p> + * Beans can also broadcast notifications. If the bean provides this + * facility, by implementing the {@link NotificationBroadcaster} + * interface, then an array of {@link MBeanNotificationInfo} objects + * may be obtained from {@link #getNotifications()}, which describe + * the notifications emitted. + * </p> + * <p> + * Model management beans and open management beans also supply an + * instance of this class, as part of implementing the + * {@link DynamicMBean#getMBeanInfo()} method of {@link DynamicMBean}. + * </p> + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public class MBeanInfo + implements Cloneable, Serializable +{ + + /** + * Compatible with JDK 1.5 + */ + private static final long serialVersionUID = -6451021435135161911L; + + /** + * A description of the bean. + * + * @serial The bean's description. + */ + private String description; + + /** + * The class name of the management bean. + * + * @serial The bean's class name. + */ + private String className; + + /** + * Descriptions of the attributes provided by the bean. + */ + private MBeanAttributeInfo[] attributes; + + /** + * Descriptions of the operations provided by the bean. + */ + private MBeanOperationInfo[] operations; + + /** + * Descriptions of the bean's constructors. + */ + private MBeanConstructorInfo[] constructors; + + /** + * Descriptions of the notifications emitted by the bean. + * + * @serial The bean's notifications. + */ + private MBeanNotificationInfo[] notifications; + + /** + * The <code>toString()</code> result of this instance. + */ + private transient String string; + + /** + * Constructs a new {@link MBeanInfo} using the supplied + * class name and description with the given attributes, + * operations, constructors and notifications. The class + * name does not have to actually specify a valid class that + * can be loaded by the MBean server or class loader; it merely + * has to be a syntactically correct class name. Any of the + * arrays may be <code>null</code>; this will be treated as if + * an empty array was supplied. A copy of the arrays is + * taken, so later changes have no effect. + * + * @param name the name of the class this instance describes. + * @param desc a description of the bean. + * @param attribs the attribute descriptions for the bean, + * or <code>null</code>. + * @param cons the constructor descriptions for the bean, + * or <code>null</code>. + * @param ops the operation descriptions for the bean, + * or <code>null</code>. + * @param notifs the notification descriptions for the bean, + * or <code>null</code>. + */ + public MBeanInfo(String name, String desc, MBeanAttributeInfo[] attribs, + MBeanConstructorInfo[] cons, MBeanOperationInfo[] ops, + MBeanNotificationInfo[] notifs) + { + className = name; + description = desc; + + if (attribs == null) + attributes = new MBeanAttributeInfo[0]; + else + attributes = (MBeanAttributeInfo[]) attribs.clone(); + + if (cons == null) + constructors = new MBeanConstructorInfo[0]; + else + constructors = (MBeanConstructorInfo[]) cons.clone(); + + if (ops == null) + operations = new MBeanOperationInfo[0]; + else + operations = (MBeanOperationInfo[]) ops.clone(); + + if (notifs == null) + notifications = new MBeanNotificationInfo[0]; + else + notifications = (MBeanNotificationInfo[]) notifs.clone(); + } + + /** + * Returns a shallow clone of the information. This is + * simply a new copy of each string and a clone + * of each array, which still references the same objects, + * as obtained by the {@link Object} implementation of + * {@link Object#clone()}. As the fields can not be + * changed, this method is only really of interest to + * subclasses which may add new mutable fields or make + * the existing ones mutable. + * + * @return a shallow clone of this {@link MBeanInfo}. + */ + public Object clone() + { + MBeanInfo clone = null; + try + { + clone = (MBeanInfo) super.clone(); + } + catch (CloneNotSupportedException e) + { + /* This won't happen as we implement Cloneable */ + } + return clone; + } + + /** + * Compares this feature with the supplied object. This returns + * true iff the object is an instance of {@link MBeanInfo} and + * {@link Object#equals()} returns true for a comparison of the + * class name and description, and the arrays each contain the same + * elements in the same order (but one may be longer than the + * other). + * + * @param obj the object to compare. + * @return true if the object is a {@link MBeanInfo} + * instance, + * <code>className.equals(object.getClassName())</code>, + * <code>description.equals(object.getDescription())</code> + * and the corresponding elements of the arrays are + * equal. + */ + public boolean equals(Object obj) + { + if (!(obj instanceof MBeanInfo)) + return false; + if (!(super.equals(obj))) + return false; + MBeanInfo o = (MBeanInfo) obj; + MBeanAttributeInfo[] attr = o.getAttributes(); + for (int a = 0; a < attributes.length; ++a) + { + if (a == attr.length) + return true; + if (!(attributes[a].equals(attr[a]))) + return false; + } + MBeanConstructorInfo[] cons = o.getConstructors(); + for (int a = 0; a < constructors.length; ++a) + { + if (a == cons.length) + return true; + if (!(constructors[a].equals(cons[a]))) + return false; + } + MBeanOperationInfo[] ops = o.getOperations(); + for (int a = 0; a < operations.length; ++a) + { + if (a == ops.length) + return true; + if (!(operations[a].equals(ops[a]))) + return false; + } + MBeanNotificationInfo[] notifs = o.getNotifications(); + for (int a = 0; a < notifications.length; ++a) + { + if (a == notifs.length) + return true; + if (!(notifications[a].equals(notifs[a]))) + return false; + } + return (className.equals(o.getClassName()) && + description.equals(o.getDescription())); + } + + /** + * Returns descriptions of each of the attributes provided + * by this management bean. The returned value is a shallow + * copy of the attribute array maintained by this instance. + * Hence, changing the elements of the returned array will not + * affect the attribute array, and the elements (instances + * of the {@link MBeanAttributeInfo} class) are immutable. + * + * @return an array of {@link MBeanAttributeInfo} objects, + * representing the attributes emitted by this + * management bean. + */ + public MBeanAttributeInfo[] getAttributes() + { + return (MBeanAttributeInfo[]) attributes.clone(); + } + + /** + * Returns the class name of the management bean. + * + * @return the bean's class name. + */ + public String getClassName() + { + return className; + } + + /** + * Returns descriptions of each of the constructors provided + * by this management bean. The returned value is a shallow + * copy of the constructor array maintained by this instance. + * Hence, changing the elements of the returned array will not + * affect the constructor array, and the elements (instances + * of the {@link MBeanConstructorInfo} class) are immutable. + * + * @return an array of {@link MBeanConstructorInfo} objects, + * representing the constructors emitted by this + * management bean. + */ + public MBeanConstructorInfo[] getConstructors() + { + return (MBeanConstructorInfo[]) constructors.clone(); + } + + /** + * Returns a description of the management bean. + * + * @return the bean's description. + */ + public String getDescription() + { + return description; + } + + /** + * Returns descriptions of each of the notifications emitted + * by this management bean. The returned value is a shallow + * copy of the notification array maintained by this instance. + * Hence, changing the elements of the returned array will not + * affect the notification array, and the elements (instances + * of the {@link MBeanNotificationInfo} class) are immutable. + * + * @return an array of {@link MBeanNotificationInfo} objects, + * representing the notifications emitted by this + * management bean. + */ + public MBeanNotificationInfo[] getNotifications() + { + return (MBeanNotificationInfo[]) notifications.clone(); + } + + /** + * Returns descriptions of each of the operations provided + * by this management bean. The returned value is a shallow + * copy of the operation array maintained by this instance. + * Hence, changing the elements of the returned array will not + * affect the operation array, and the elements (instances + * of the {@link MBeanOperationInfo} class) are immutable. + * + * @return an array of {@link MBeanOperationInfo} objects, + * representing the operations emitted by this + * management bean. + */ + public MBeanOperationInfo[] getOperations() + { + return (MBeanOperationInfo[]) operations.clone(); + } + + /** + * Returns the hashcode of the information as the sum of the + * hashcode of the classname, description and each array. + * + * @return the hashcode of the information. + */ + public int hashCode() + { + return className.hashCode() + description.hashCode() + + Arrays.hashCode(attributes) + Arrays.hashCode(constructors) + + Arrays.hashCode(operations) + Arrays.hashCode(notifications); + } + + /** + * <p> + * Returns a textual representation of this instance. This + * is constructed using the class name + * (<code>javax.management.MBeanInfo</code>), + * the name and description of the bean and the contents + * of the four arrays. + * </p> + * <p> + * As instances of this class are immutable, the return value + * is computed just once for each instance and reused + * throughout its life. + * </p> + * + * @return a @link{java.lang.String} instance representing + * the instance in textual form. + */ + public String toString() + { + if (string == null) + string = getClass().getName() + + "[name=" + className + + ",desc=" + description + + ",attributes=" + Arrays.toString(attributes) + + ",constructors=" + Arrays.toString(constructors) + + ",operations=" + Arrays.toString(operations) + + ",notifications=" + Arrays.toString(notifications) + + "]"; + return string; + } + +} diff --git a/libjava/classpath/javax/management/MBeanNotificationInfo.java b/libjava/classpath/javax/management/MBeanNotificationInfo.java new file mode 100644 index 000000000..10dd956b0 --- /dev/null +++ b/libjava/classpath/javax/management/MBeanNotificationInfo.java @@ -0,0 +1,227 @@ +/* MBeanNotificationInfo.java -- Information about a bean's notification. + Copyright (C) 2006 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.Arrays; + +/** + * <p> + * Describes the notifications emitted by a management bean. + * An instance of this class is specific to notifications + * involving a particular type of object. A new instance + * should be created for each Java class used for notifications, + * and the Java class name forms the name of the instance. + * Each instance lists a number of notification types; these + * are not types in the sense of different Java classes, but + * instead form the names of notifications following the same + * syntax as Java property and package names. + * </p> + * <p> + * For instance, a management bean may emit two notifications + * containing {@link java.lang.String} objects. Both would be described + * using one instance of this class, with a member of the array + * returned by {@link #getNotifTypes()} for each one. If another + * notification containing a {@link java.util.Date} object were to + * be added, this would require a new instance of this class. + * </p> + * <p> + * The information in this class is immutable as standard. + * Of course, subclasses may change this, but this + * behaviour is not recommended. + * </p> + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public class MBeanNotificationInfo + extends MBeanFeatureInfo + implements Cloneable +{ + + /** + * Compatible with JDK 1.5 + */ + private static final long serialVersionUID = -3888371564530107064L; + + /** + * The types of notification described by this instance. + * + * @serial the types of notification. + */ + private String[] types; + + /** + * Constructs a new {@link MBeanNotificationInfo} with the + * specified name, description and notification types. The + * notification types array may be <code>null</code> or of + * zero length, in order to indicate the absence of any types. + * + * @param types an array of {@link java.lang.String} objects, + * containing the names of the notifications emitted + * of this Java type. The names use the dot notation + * familiar from Java property and package names. + * @param name the name of the Java class the notifications described + * by this object are instances of. + * @param description a description of the data. + * @throws IllegalArgumentException for some reason... + */ + public MBeanNotificationInfo(String[] types, String name, + String description) + { + super(name, description); + this.types = types; + } + + /** + * Returns a clone of this instance. The clone is created + * using just the method provided by {@link java.lang.Object}. + * Thus, the clone is just a shallow clone as returned by + * that method, and does not contain any deeper cloning based + * on the subject of this class. + * + * @return a clone of this instance. + * @see java.lang.Cloneable + */ + public Object clone() + { + try + { + return super.clone(); + } + catch (CloneNotSupportedException e) + { + /* This shouldn't happen; we implement Cloneable */ + throw new IllegalStateException("clone() called on " + + "non-cloneable object."); + } + } + + /** + * Compares this feature with the supplied object. This returns + * true iff the object is an instance of {@link + * MBeanNotificationInfo}, {@link Object#equals()} returns true for + * a comparison of both the name and description of this + * notification with that of the specified object, and the two + * notification type arrays contain the same elements in the same + * order (but one may be longer than the other). + * + * @param obj the object to compare. + * @return true if the object is a {@link MBeanNotificationInfo} + * instance, + * <code>name.equals(object.getName())</code>, + * <code>description.equals(object.getDescription())</code> + * and the corresponding elements of the type arrays are + * equal. + */ + public boolean equals(Object obj) + { + if (obj instanceof MBeanNotificationInfo) + { + if (!(super.equals(obj))) + return false; + MBeanNotificationInfo o = (MBeanNotificationInfo) obj; + String[] oTypes = o.getNotifTypes(); + for (int a = 0; a < types.length; ++a) + { + if (a == oTypes.length) + return true; + if (!(types[a].equals(oTypes[a]))) + return false; + } + return true; + } + else + return false; + } + + /** + * Returns the notification types that the management bean may emit. + * The notification types are strings using the dot notation + * familiar from Java property and package names. Changing the + * returned array does not affect the values retained by this + * instance. + * + * @return the notification types. + */ + public String[] getNotifTypes() + { + return types; + } + + /** + * Returns the hashcode of the notification information as the sum + * of the hashcode of the superclass and the hashcode of the types + * array. + * + * @return the hashcode of the notification information. + */ + public int hashCode() + { + return super.hashCode() + Arrays.hashCode(types); + } + + /** + * <p> + * Returns a textual representation of this instance. This + * is constructed using the class name + * (<code>javax.management.MBeanNotificationInfo</code>), + * the name and description of the notification and the + * contents of the array of types. + * </p> + * <p> + * As instances of this class are immutable, the return value + * is computed just once for each instance and reused + * throughout its life. + * </p> + * + * @return a @link{java.lang.String} instance representing + * the instance in textual form. + */ + public String toString() + { + if (string == null) + { + super.toString(); + string = string.substring(0, string.length() - 1) + + ",types=" + Arrays.toString(types) + + "]"; + } + return string; + } + +} diff --git a/libjava/classpath/javax/management/MBeanOperationInfo.java b/libjava/classpath/javax/management/MBeanOperationInfo.java new file mode 100644 index 000000000..0adc0e6bc --- /dev/null +++ b/libjava/classpath/javax/management/MBeanOperationInfo.java @@ -0,0 +1,359 @@ +/* MBeanOperationInfo.java -- Information about a bean's operations. + Copyright (C) 2006 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.Method; +import java.lang.reflect.Type; + +import java.util.Arrays; + +/** + * Describes the operations of a management bean. + * The information in this class is immutable as standard. + * Of course, subclasses may change this, but this + * behaviour is not recommended. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public class MBeanOperationInfo + extends MBeanFeatureInfo + implements Cloneable +{ + + /** + * Compatible with JDK 1.5 + */ + private static final long serialVersionUID = -6178860474881375330L; + + /** + * Used to signify that the operation merely provides information + * (akin to an accessor). + */ + public static final int INFO = 0; + + /** + * Used to signify that the operation makes some change to the + * state of the bean (akin to a mutator). + */ + public static final int ACTION = 1; + + /** + * Used to signify that the operation makes some state change + * to the bean and also returns information. + */ + public static final int ACTION_INFO = 2; + + /** + * Used to signify that the behaviour of the operation is + * unknown. + */ + public static final int UNKNOWN = 3; + + /** + * The return type of the method, in the form of its class name. + */ + private String type; + + /** + * The signature of the constructor i.e. the argument types. + */ + private MBeanParameterInfo[] signature; + + /** + * The impact of the method, as one of {@link #INFO}, {@link #ACTION}, + * {@link #ACTION_INFO} and {@link #UNKNOWN}. + */ + private int impact; + + /** + * Constructs a @link{MBeanOperationInfo} with the specified + * description using the given method. Each parameter is + * described merely by its type; the name and description are + * <code>null</code>. The return type and impact of the + * method are determined from the {@link Method} instance. + * + * @param desc a description of the attribute. + * @param method the method. + */ + public MBeanOperationInfo(String desc, Method method) + { + super(method.getName(), desc); + Type[] paramTypes = method.getGenericParameterTypes(); + signature = new MBeanParameterInfo[paramTypes.length]; + for (int a = 0; a < paramTypes.length; ++a) + { + Type t = paramTypes[a]; + if (t instanceof Class) + signature[a] = new MBeanParameterInfo(null, + ((Class<?>) t).getName(), + null); + else + signature[a] = new MBeanParameterInfo(null, t.toString(), null); + } + Type retType = method.getGenericReturnType(); + if (retType instanceof Class) + type = ((Class<?>) retType).getName(); + else + type = retType.toString(); + if (method.getReturnType() == Void.TYPE) + { + if (paramTypes.length == 0) + impact = UNKNOWN; + else + impact = ACTION; + } + else + { + if (paramTypes.length == 0) + impact = INFO; + else + impact = ACTION_INFO; + } + } + + /** + * Constructs a @link{MBeanOperationInfo} with the specified name, + * description, parameter information, return type and impact. A + * <code>null</code> value for the parameter information is the same + * as passing in an empty array. A copy of the parameter array is + * taken, so later changes have no effect. + * + * @param name the name of the constructor. + * @param desc a description of the attribute. + * @param sig the signature of the method, as a series + * of {@link MBeanParameterInfo} objects, one for + * each parameter. + * @param type the return type of the method, as the class name. + * @param impact the impact of performing the operation. + */ + public MBeanOperationInfo(String name, String desc, + MBeanParameterInfo[] sig, String type, + int impact) + { + super(name, desc); + if (sig == null) + signature = new MBeanParameterInfo[0]; + else + { + signature = new MBeanParameterInfo[sig.length]; + System.arraycopy(sig, 0, signature, 0, sig.length); + } + this.type = type; + this.impact = impact; + } + + /** + * Returns a clone of this instance. The clone is created + * using just the method provided by {@link java.lang.Object}. + * Thus, the clone is just a shallow clone as returned by + * that method, and does not contain any deeper cloning based + * on the subject of this class. + * + * @return a clone of this instance. + * @see java.lang.Cloneable + */ + public Object clone() + { + try + { + return super.clone(); + } + catch (CloneNotSupportedException e) + { + /* This shouldn't happen; we implement Cloneable */ + throw new IllegalStateException("clone() called on " + + "non-cloneable object."); + } + } + + /** + * Compares this feature with the supplied object. This returns + * true iff the object is an instance of {@link + * MBeanConstructorInfo}, {@link Object#equals()} returns true for a + * comparison of both the name and description of this notification + * with that of the specified object (performed by the superclass), + * the return type and impact are equal and the two signature arrays + * contain the same elements in the same order (but one may be + * longer than the other). + * + * @param obj the object to compare. + * @return true if the object is a {@link MBeanOperationInfo} + * instance, + * <code>name.equals(object.getName())</code>, + * <code>description.equals(object.getDescription())</code>, + * <code>type.equals(object.getReturnType())</code>, + * <code>impact == object.getImpact()</code>, + * and the corresponding elements of the signature arrays are + * equal. + */ + public boolean equals(Object obj) + { + if (!(obj instanceof MBeanOperationInfo)) + return false; + if (!(super.equals(obj))) + return false; + MBeanOperationInfo o = (MBeanOperationInfo) obj; + MBeanParameterInfo[] sig = o.getSignature(); + for (int a = 0; a < signature.length; ++a) + { + if (a == sig.length) + return true; + if (!(signature[a].equals(sig[a]))) + return false; + } + return (type.equals(o.getReturnType()) && + impact == o.getImpact()); + } + + /** + * <p> + * Returns the impact of performing this operation. + * The value is equal to one of the following: + * </p> + * <ol> + * <li>{@link #INFO} — the method just returns + * information (akin to an accessor).</li> + * <li>{@link #ACTION} — the method just alters + * the state of the bean, without returning a value + * (akin to a mutator).</li> + * <li>{@link #ACTION_INFO} — the method both makes + * state changes and returns a value.</li> + * <li>{@link #UNKNOWN} — the behaviour of the operation + * is unknown.</li> + * </ol> + * + * @return the impact of performing the operation. + */ + public int getImpact() + { + return impact; + } + + /** + * Returns the return type of the operation, as the class + * name. + * + * @return the return type. + */ + public String getReturnType() + { + return type; + } + + /** + * Returns the operation's signature, in the form of + * information on each parameter. Each parameter is + * described by an instance of {@link MBeanParameterInfo}. + * The returned array is a shallow copy of the array used + * by this instance, so changing which elements are stored + * in the array won't affect the array used by this, but + * changing the actual elements will affect the ones used + * here. + * + * @return an array of {@link MBeanParameterInfo} objects, + * describing the operation parameters. + */ + public MBeanParameterInfo[] getSignature() + { + return (MBeanParameterInfo[]) signature.clone(); + } + + /** + * Returns the hashcode of the operation information as the sum of + * the hashcode of the superclass, the parameter array, the return + * type and the impact factor. + * + * @return the hashcode of the operation information. + */ + public int hashCode() + { + return super.hashCode() + Arrays.hashCode(signature) + + type.hashCode() + Integer.valueOf(impact).hashCode(); + } + + /** + * <p> + * Returns a textual representation of this instance. This + * is constructed using the class name + * (<code>javax.management.MBeanOperationInfo</code>), + * the name, description, return type and impact of the + * operation and the contents of the array of parameters. + * </p> + * <p> + * As instances of this class are immutable, the return value + * is computed just once for each instance and reused + * throughout its life. + * </p> + * + * @return a @link{java.lang.String} instance representing + * the instance in textual form. + */ + public String toString() + { + if (string == null) + { + String impactString; + switch (impact) + { + case INFO: + impactString = "INFO"; + break; + case ACTION: + impactString = "ACTION"; + break; + case ACTION_INFO: + impactString = "ACTION_INFO"; + break; + case UNKNOWN: + impactString = "UNKNOWN"; + break; + default: + impactString = "ERRONEOUS VALUE"; + } + super.toString(); + string = string.substring(0, string.length() - 1) + + ",returnType=" + type + + ",impact=" + impactString + + ",signature=" + Arrays.toString(signature) + + "]"; + } + return string; + } + +} diff --git a/libjava/classpath/javax/management/MBeanParameterInfo.java b/libjava/classpath/javax/management/MBeanParameterInfo.java new file mode 100644 index 000000000..9307de46d --- /dev/null +++ b/libjava/classpath/javax/management/MBeanParameterInfo.java @@ -0,0 +1,176 @@ +/* MBeanParameterInfo.java -- Information about an operation's parameters. + Copyright (C) 2006 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; + +/** + * Describes the parameters of a constructor or operation associated + * with a management bean. The information in this class is immutable + * as standard. Of course, subclasses may change this, but this + * behaviour is not recommended. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public class MBeanParameterInfo + extends MBeanFeatureInfo + implements Cloneable +{ + + /** + * Compatible with JDK 1.5 + */ + private static final long serialVersionUID = 7432616882776782338L; + + /** + * The type of the parameter, represented by the class name. + */ + private String type; + + /** + * Constructs a new {@link MBeanParameterInfo} using the specified + * name, description and type. + * + * @param name the name of the attribute. + * @param type the type of the attribute, in the form of its class name. + * @param desc a description of the attribute. + */ + public MBeanParameterInfo(String name, String type, String desc) + { + super(name, desc); + this.type = type; + } + + /** + * Returns a clone of this instance. The clone is created + * using just the method provided by {@link java.lang.Object}. + * Thus, the clone is just a shallow clone as returned by + * that method, and does not contain any deeper cloning based + * on the subject of this class. + * + * @return a clone of this instance. + * @see java.lang.Cloneable + */ + public Object clone() + { + try + { + return super.clone(); + } + catch (CloneNotSupportedException e) + { + /* This shouldn't happen; we implement Cloneable */ + throw new IllegalStateException("clone() called on " + + "non-cloneable object."); + } + } + + /** + * Compares this feature with the supplied object. This returns + * true iff the object is an instance of {@link MBeanParameterInfo}, + * {@link Object#equals()} returns true for a comparison of both the + * name and description of this parameter with that of the specified + * object (performed by the superclass), and the type of the two + * instances is equal. + * + * @param obj the object to compare. + * @return true if the object is a {@link MBeanParameterInfo} + * instance, + * <code>name.equals(object.getName())</code>, + * <code>description.equals(object.getDescription())</code>, + * and <code>type.equals(object.getType())</code>. + */ + public boolean equals(Object obj) + { + if (!(obj instanceof MBeanParameterInfo)) + return false; + if (!(super.equals(obj))) + return false; + MBeanParameterInfo o = (MBeanParameterInfo) obj; + return type.equals(o.getType()); + } + + /** + * Returns the type of this attribute, in the form of its class name. + * + * @return the type of this attribute. + */ + public String getType() + { + return type; + } + + /** + * Returns the hashcode of the parameter information as the sum of + * the hashcode of the superclass and the hashcode of the type. + * + * @return the hashcode of the parameter information. + */ + public int hashCode() + { + return super.hashCode() + type.hashCode(); + } + + /** + * <p> + * Returns a textual representation of this instance. This + * is constructed using the class name + * (<code>javax.management.MBeanParameterInfo</code>) along + * with the name, description and type of the parameter. + * </p> + * <p> + * As instances of this class are immutable, the return value + * is computed just once for each instance and reused + * throughout its life. + * </p> + * + * @return a @link{java.lang.String} instance representing + * the instance in textual form. + */ + public String toString() + { + if (string == null) + { + super.toString(); + string = string.substring(0, string.length() - 1) + + ",type=" + type + + "]"; + } + return string; + } + +} diff --git a/libjava/classpath/javax/management/MBeanPermission.java b/libjava/classpath/javax/management/MBeanPermission.java new file mode 100644 index 000000000..10813e4e6 --- /dev/null +++ b/libjava/classpath/javax/management/MBeanPermission.java @@ -0,0 +1,549 @@ +/* MBeanPermission.java -- Permissions controlling server access. + Copyright (C) 2006 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.java.lang.CPStringBuilder; + +import java.security.Permission; + +import java.io.IOException; +import java.io.ObjectInputStream; + +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; +import java.util.TreeSet; + +/** + * <p> + * Represents the permissions required to perform + * operations using the {@link MBeanServer}. As with + * all {@link java.security.Permission} objects, an + * instance of this class either represents a permission + * already held or one that is required to access a + * particular service. In the case of {@link MBeanPermission}s, + * implication checks are made using an instance of this class + * when a user requests an operation from the server, and a + * {@link SecurityManager} is in place. + * </p> + * <p> + * An {@link MBeanPermission} consists of four elements, + * which all have to match for the permission to be implied. + * These are as follows: + * </p> + * <ol> + * <li><strong>The action</strong>. For a required permission, + * this is a single value. For a permission held by the user, + * this is a list of comma-separated actions (with spaces allowed), + * or <code>*</code> (representing all actions). {@link #getActions()} + * returns this value.</li> + * <li><strong>The class name</strong>. For a required permission, + * this is the class name of the bean being accessed, if any. If + * a bean isn't involved in this action, the value is <code>null</code>. + * For a permission held by the user, it has one of three values: + * <ol> + * <li>The empty string, implying any class.</li> + * <li><code>*</code>, also implying any class.</li> + * <li>A class name pattern, which may specify a single class + * (e.g. <code>java.lang.Object</code>) or a series of classes + * using the wildcard character <code>*</code> (e.g. + * <code>javax.swing.*</code>.)</li> + * </ol></li> + * <li><strong>The member</strong>. For a required permission, + * this is the member of the bean being accessed (an attribute + * or operation), if any. If a member of the bean isn't involved + * in this action, the value is <code>null</code>. + * For a permission held by the user, it has one of three values: + * <ol> + * <li>The empty string, implying any member.</li> + * <li><code>*</code>, also implying any member.</li> + * <li>The name of a member.</li> + * </ol></li> + * <li>The object name</strong>. For a required permission, + * this is the {@link ObjectName} of the bean being accessed, if + * any. If a bean isn't involved in this action, the value is + * <code>null</code>. The name may not be a pattern. + * For a permission held by the user, it may be the empty + * string (allowing everything) or an {@link ObjectName} + * pattern. + * </li></ol> + * {@link #getName()} returns the latter three of these as a + * single string: + * </p> + * <p><code>className#member[objectName]</code></p> + * <p> + * where <code>""</code> is disallowed, as, although any of + * the elements may be omitted, not all of them should be + * left out simultaneously. <code>"-"</code> is used to + * represent <code>null</code>. When this occurs in a + * required permission, anything may match it. When this + * forms part of a permission held by the user, it only + * matches another <code>null</code> value. + * </p> + * <p>The list of valid actions is as follows:</p> + * <ul> + * <li>addNotificationListener</li> + * <li>getAttribute</li> + * <li>getClassLoader</li> + * <li>getClassLoaderFor</li> + * <li>getClassLoaderRepository</li> + * <li>getDomains</li> + * <li>getMBeanInfo</li> + * <li>getObjectInstance</li> + * <li>instantiate</li> + * <li>invoke</li> + * <li>isInstanceOf</li> + * <li>queryMBeans</li> + * <li>queryNames</li> + * <li>registerMBean</li> + * <li>removeNotificationListener</li> + * <li>setAttribute</li> + * <li>unregisterMBean</li> + * </ul> + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public class MBeanPermission + extends Permission +{ + + /** + * Compatible with JDK 1.5 + */ + private static final long serialVersionUID = -2416928705275160661L; + + /** + * The list of actions associated with this permission. + */ + private String actions; + + /** + * The list of actions as an ordered set. + */ + private transient Set<String> actionSet; + + /** + * The set of valid actions. + */ + private static final Set<String> validSet; + + /** + * Initialise the set of valid actions. + */ + static + { + validSet = new HashSet<String>(); + validSet.add("addNotificationListener"); + validSet.add("getAttribute"); + validSet.add("getClassLoader"); + validSet.add("getClassLoaderFor"); + validSet.add("getClassLoaderRepository"); + validSet.add("getDomains"); + validSet.add("getMBeanInfo"); + validSet.add("getObjectInstance"); + validSet.add("instantiate"); + validSet.add("invoke"); + validSet.add("isInstanceOf"); + validSet.add("queryMBeans"); + validSet.add("queryNames"); + validSet.add("registerMBean"); + validSet.add("removeNotificationListener"); + validSet.add("setAttribute"); + validSet.add("unregisterMBean"); + } + + /** + * Constructs a new {@link MBeanPermission} with the specified name + * and actions. The name is of the form <code>className#member[objectName]</code>, + * where each element is optional, but a completely empty or <code>null</code> + * name is disallowed. Actions are specified as a comma-separated list + * and may also not be empty or <code>null</code>. + * + * @param name the name of the permission. + * @param actions the actions associated with this permission. + * @throws IllegalArgumentException if the name or actions are invalid. + */ + public MBeanPermission(String name, String actions) + { + super(name); + if (name == null || name.length() == 0) + throw new IllegalArgumentException("The supplied name was null or empty."); + if (actions == null || actions.length() == 0) + throw new IllegalArgumentException("The supplied action list was null or empty."); + this.actions = actions; + updateActionSet(); + } + + /** + * Constructs a new {@link MBeanPermission} with the specified class name, + * member, object name and actions. The name of the permission is created + * using the form <code>className#member[objectName]</code>, + * where each element is optional, but an empty or <code>null</code> + * name is disallowed. Actions are specified as a comma-separated list + * and may also not be empty or <code>null</code>. + * + * @param className the name of the class to which this permission applies, + * or either <code>null</code> or <code>"-"</code> for a + * value which may be implied by any class name, but not + * imply any class name itself. + * @param member the member of the class to which this permission applies, + * or either <code>null</code> or <code>"-"</code> for a + * value which may be implied by any member, but not + * imply any member itself. + * @param name the {@link ObjectName} to which this permission applies, + * or <code>null</code> for a value which may be implied by + * any object name, but not imply any object name itself. + * @param actions the actions associated with this permission. + */ + public MBeanPermission(String className, String member, + ObjectName name, String actions) + { + this((className == null ? "-" : className) + "#" + + (member == null ? "-" : member) + "[" + + (name == null ? "-" : name.toString()) + "]", actions); + } + + /** + * Returns true if the given object is also an {@link MBeanPermission} + * with the same name and actions. + * + * @param obj the object to test. + * @return true if the object is an {@link MBeanPermission} with + * the same name and actions. + */ + public boolean equals(Object obj) + { + if (obj instanceof MBeanPermission) + { + MBeanPermission p = (MBeanPermission) obj; + return (p.getName().equals(getName()) && + p.getActions().equals(actions)); + } + return false; + } + + /** + * Returns the list of actions in alphabetical order. + * + * @return the list of actions. + */ + public String getActions() + { + Iterator<String> it = actionSet.iterator(); + CPStringBuilder builder = new CPStringBuilder(); + while (it.hasNext()) + { + builder.append(it.next()); + if (it.hasNext()) + builder.append(","); + } + return builder.toString(); + } + + /** + * Returns the hashcode of the permission as the sum + * of the hashcodes of the name and actions. + * + * @return the hashcode of the permission. + */ + public int hashCode() + { + return getName().hashCode() + actions.hashCode(); + } + + /** + * <p> + * Returns true if this permission implies the supplied permission. + * This happens if the following holds: + * </p> + * <ul> + * <li>The supplied permission is an {@link MBeanPermission}</li> + * <li>The supplied permission has either a <code>null</code> classname + * or its classname matches the classname of this permission. A + * classname of <code>"*"</code> for this permission always matches + * the classname of the supplied permission. Generally, <code>'*'</code> + * acts as a wildcard, so <code>".*"</code> matches <code>'.'</code> + * followed by anything.</li> + * <li>The supplied permission has either a <code>null</code> member + * or its member matches the member of this permission. A member of + * <code>"*"</code> for this permission always matches the member + * of the supplied permission.</li> + * <li>The supplied permission has either a <code>null</code> object name + * or its object name matches the object name of this permission. If the + * object name of this permission is a pattern, {@link ObjectName#apply(ObjectName)} + * may be used as well.</li> + * <li>The supplied permission's actions are a subset of the actions + * of this permission. If the <code>queryMBeans</code> action is presented, + * the <code>queryNames</code> action is implied.</li> + * </ul> + * + * @param p the permission to check that this permission implies. + * @return true if this permission implies <code>p</code>. + */ + public boolean implies(Permission p) + { + if (p instanceof MBeanPermission) + { + MBeanPermission mp = (MBeanPermission) p; + NameHolder pName = new NameHolder(mp.getName()); + NameHolder name = new NameHolder(getName()); + if (!(name.equals(pName))) + return false; + for (String nextAction : mp.actionSet) + { + boolean found = actions.contains(nextAction); + if (!found) + if (nextAction.equals("queryNames")) + found = actions.contains("queryMBeans"); + if (!found) + return false; + } + return true; + } + return false; + } + + /** + * Small helper class to handle deconstruction of the name. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + */ + private class NameHolder + { + + /** + * The class name. + */ + private String className; + + /** + * The member. + */ + private String member; + + /** + * The object name. + */ + private ObjectName objectName; + + /** + * Constructs a broken-down name from a given name. + * + * @param name the name to break down. + */ + public NameHolder(String name) + { + String objectName = null; + int memberIndex = name.indexOf("#"); + int onIndex = name.indexOf("["); + if (onIndex == -1) + { + if (memberIndex == -1) + className = name; + else + { + className = name.substring(0, memberIndex); + member = name.substring(memberIndex + 1); + } + } + else + { + if (memberIndex == -1) + { + className = name.substring(0, onIndex); + objectName = name.substring(onIndex + 1, + name.length() - 1); + } + else + { + className = name.substring(0, memberIndex); + member = name.substring(memberIndex + 1, onIndex); + objectName = name.substring(onIndex + 1, + name.length() - 1); + } + } + if (className.equals("-")) + className = null; + if (member.equals("-")) + member = null; + if (objectName == null || objectName.equals("-")) + this.objectName = null; + else + try + { + this.objectName = new ObjectName(objectName); + } + catch (MalformedObjectNameException e) + { + throw (Error) + (new InternalError("Invalid object name.").initCause(e)); + } + } + + /** + * <p> + * Returns true if the supplied object is also a + * {@link NameHolder} and the following holds: + * </p> + * <ul> + * <li>The supplied classname is <code>null</code> or the two match. A + * classname of <code>"*"</code> for this holder always matches + * the classname of the supplied holder. Generally, <code>'*'</code> + * acts as a wildcard, so <code>".*"</code> matches <code>'.'</code> + * followed by anything.</li> + * <li>The supplied name holder has either a <code>null</code> member + * or its member matches the member of this name holder. A member of + * <code>"*"</code> for this name holder always matches the member + * of the supplied name holder.</li> + * <li>The supplied name holder has either a <code>null</code> object name + * or its object name matches the object name of this name holder. If the + * object name of this name holder is a pattern, + * {@link ObjectName#apply(ObjectName)} may be used as well.</li> + * </ul> + * + * @param obj the object to compare with this. + * @return true if the above holds. + */ + public boolean equals(Object obj) + { + if (obj instanceof NameHolder) + { + NameHolder nh = (NameHolder) obj; + boolean cn = false; + String ocn = nh.getClassName(); + if (ocn == null || className.equals("*")) + cn = true; + else + { + int wcIndex = className.indexOf("*"); + if (wcIndex != -1) + cn = ocn.startsWith(className.substring(0, wcIndex)); + else + cn = ocn.equals(className); + } + boolean m = false; + String om = nh.getMember(); + if (om == null || member.equals("*")) + m = true; + else + m = om.equals(member); + boolean on = false; + ObjectName oon = nh.getObjectName(); + if (oon == null) + on = true; + else if (objectName.isPattern()) + on = objectName.apply(oon); + else + on = oon.equals(objectName); + return (cn && m && on); + } + return false; + } + + /** + * Returns the class name. + */ + public String getClassName() + { + return className; + } + + /** + * Returns the member. + */ + public String getMember() + { + return member; + } + + /** + * Returns the object name. + */ + public ObjectName getObjectName() + { + return objectName; + } + } + + /** + * Updates the action set from the current value of + * the actions string. + */ + private void updateActionSet() + { + String[] actionsArray = actions.split(","); + actionSet = new TreeSet<String>(); + for (int a = 0; a < actionsArray.length; ++a) + actionSet.add(actionsArray[a].trim()); + } + + /** + * Reads the object from a stream and ensures the incoming + * data is valid. + * + * @param in the input stream. + * @throws IOException if an I/O error occurs. + * @throws ClassNotFoundException if a class used by the object + * can not be found. + */ + private void readObject(ObjectInputStream in) + throws IOException, ClassNotFoundException + { + in.defaultReadObject(); + updateActionSet(); + checkActions(); + } + + /** + * Checks that the actions used in this permission + * are from the valid set. + * + * @throws IllegalArgumentException if the name or actions are invalid. + */ + private void checkActions() + { + for (String action : actionSet) + { + if (!(validSet.contains(action))) + throw new IllegalArgumentException("Invalid action " + + action + " found."); + } + } + +} diff --git a/libjava/classpath/javax/management/MBeanRegistration.java b/libjava/classpath/javax/management/MBeanRegistration.java new file mode 100644 index 000000000..5a181ca49 --- /dev/null +++ b/libjava/classpath/javax/management/MBeanRegistration.java @@ -0,0 +1,95 @@ +/* MBeanRegistration.java -- Interface for beans to hook into registration. + Copyright (C) 2006 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package javax.management; + +/** + * Beans may implement this interface in order to perform + * operations immediately prior to or after their registration + * or deregistration. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public interface MBeanRegistration +{ + + /** + * This method is called following deregistration of the bean + * by the server. + */ + void postDeregister(); + + /** + * This method is called following both successful and unsuccessful + * attempts to register the bean. The supplied boolean value indicates + * the result of the attempt relative to this call. + * + * @param successful true if the registration was successful. + */ + void postRegister(Boolean successful); + + /** + * This method is called prior to de-registration, and may throw + * an exception. + * + * @throws Exception if something goes wrong during the bean's pre-deregistration + * operation. The server will re-throw this exception + * as an {@link MBeanRegistrationException}. + */ + void preDeregister() + throws Exception; + + /** + * This method is called prior to registration, with a reference to the + * server and {@link ObjectName} supplied to the server for registration. + * This method may be used to replace this name by one chosen by the bean. + * Such behaviour is expected if the supplied name is <code>null</code>, + * but may occur in all cases. The method may throw an exception, which + * will cause registration to be aborted. + * + * @param server the server with which the bean is being registered. + * @param name the name the server was supplied with for registration, + * which may be <code>null</code>. + * @throws Exception if something goes wrong during the bean's pre-registration + * operation. The server will re-throw this exception + * as an {@link MBeanRegistrationException}. + */ + ObjectName preRegister(MBeanServer server, ObjectName name) + throws Exception; + +} diff --git a/libjava/classpath/javax/management/MBeanRegistrationException.java b/libjava/classpath/javax/management/MBeanRegistrationException.java new file mode 100644 index 000000000..18ed44a36 --- /dev/null +++ b/libjava/classpath/javax/management/MBeanRegistrationException.java @@ -0,0 +1,83 @@ +/* MBeanRegistrationException.java -- A bean registration exception. + Copyright (C) 2006 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package javax.management; + +/** + * Represents an arbitrary exception thrown during registration of a + * management bean. When registering a bean causes an exception to be + * thrown, the resulting exception is wrapped inside an {@link + * MBeanRegistrationException}. Calling {@link getTargetException()} + * will return the wrapped exception. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public class MBeanRegistrationException + extends MBeanException +{ + + /** + * Compatible with JDK 1.5 + */ + private static final long serialVersionUID = 4482382455277067805L; + + /** + * Constructs a new <code>MBeanRegistrationException</code> wrapping + * the specified exception. + * + * @param e the exception to be wrapped. + */ + public MBeanRegistrationException(Exception e) + { + super(e); + } + + /** + * Constructs a new <code>MBeanRegistrationException</code> wrapping + * the specified exception and using the supplied message. + * + * @param e the exception to be wrapped. + * @param message the error message to give to the user. + */ + public MBeanRegistrationException(Exception e, String message) + { + super(e, message); + } + + +} diff --git a/libjava/classpath/javax/management/MBeanServer.java b/libjava/classpath/javax/management/MBeanServer.java new file mode 100644 index 000000000..4b5721570 --- /dev/null +++ b/libjava/classpath/javax/management/MBeanServer.java @@ -0,0 +1,1199 @@ +/* MBeanServer.java -- Represents a management server. + Copyright (C) 2006 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.ObjectInputStream; + +import java.util.Set; + +import javax.management.loading.ClassLoaderRepository; + +/** + * <p> + * This interface represents a server for management beans, + * providing facilities for the creation, registration and + * removal of such beans. This interface is central to the + * Java management architecture. Users do not usually implement + * this class. Instead, implementations of this class + * may be obtained using an {@link MBeanServerFactory}. + * </p> + * <p> + * Registering a bean with the server makes its attributes and + * operations accessible via the server. Only JMX compliant + * beans may be registered with the server. When a bean + * is registered or unregistered, an {@link MBeanServerNotification} + * is emitted by the server's {@link MBeanServerDelegate}. + * Listeners may be registered with this bean in order to + * obtain such notifications. It has the {@link ObjectName} + * <code>JMImplementation:type=MBeanServerDelegate</code>. + * </p> + * <p> + * Security checks are applied on the methods of the server, + * as detailed below, if it is obtained using the + * {@link MBeanServerFactory#createMBeanServer()} or + * {@link MBeanServerFactory#newMBeanServer()} methods and + * {@link System.getSecurityManager()} returns a non-<code>null</code> + * value. If a check fails, a {@link SecurityException} + * is thrown. Note than the class name used in the exception + * is that of the bean, and thus, as a result, an + * {@link InstanceNotFoundException} + * precludes these security checks, due to the class name + * that would be used in the exception being unavailable. + * </p> + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public interface MBeanServer + extends MBeanServerConnection +{ + + /** + * Registers the supplied listener with the specified management + * bean. Notifications emitted by the management bean are forwarded + * to the listener via the server, which will convert any MBean + * references in the source to portable {@link ObjectName} + * instances. The notification is otherwise unchanged. + * + * @param name the name of the management bean with which the listener + * should be registered. + * @param listener the listener which will handle notifications from + * the bean. + * @param filter the filter to apply to incoming notifications, or + * <code>null</code> if no filtering should be applied. + * @param passback an object to be passed to the listener when a + * notification is emitted. + * @throws InstanceNotFoundException if the name of the management bean + * could not be resolved. + * @throws SecurityException if a security manager exists and the + * caller's permissions don't imply {@link + * MBeanPermission(String,String,ObjectName,String) + * <code>MBeanPermission(className, null, name, + * "addNotificationListener")</code>}. + * @see #removeNotificationListener(ObjectName, NotificationListener) + * @see #removeNotificationListener(ObjectName, NotificationListener, + * NotificationFilter, Object) + * @see NotificationBroadcaster#addNotificationListener(NotificationListener, + * NotificationFilter, + * Object) + */ + void addNotificationListener(ObjectName name, NotificationListener listener, + NotificationFilter filter, Object passback) + throws InstanceNotFoundException; + + /** + * <p> + * Registers the supplied listener with the specified management + * bean. Notifications emitted by the management bean are forwarded + * to the listener via the server, which will convert any MBean + * references in the source to portable {@link ObjectName} + * instances. The notification is otherwise unchanged. + * </p> + * <p> + * The listener that receives notifications will be the one that is + * registered with the given name at the time this method is called. + * Even if it later unregisters and ceases to use that name, it will + * still receive notifications. + * </p> + * + * @param name the name of the management bean with which the listener + * should be registered. + * @param listener the name of the listener which will handle + * notifications from the bean. + * @param filter the filter to apply to incoming notifications, or + * <code>null</code> if no filtering should be applied. + * @param passback an object to be passed to the listener when a + * notification is emitted. + * @throws InstanceNotFoundException if the name of the management bean + * could not be resolved. + * @throws RuntimeOperationsException if the bean associated with the given + * object name is not a + * {@link NotificationListener}. This + * exception wraps an + * {@link IllegalArgumentException}. + * @throws SecurityException if a security manager exists and the + * caller's permissions don't imply {@link + * MBeanPermission(String,String,ObjectName,String) + * <code>MBeanPermission(className, null, name, + * "addNotificationListener")</code>}. + * @see #removeNotificationListener(ObjectName, NotificationListener) + * @see #removeNotificationListener(ObjectName, NotificationListener, + * NotificationFilter, Object) + * @see NotificationBroadcaster#addNotificationListener(NotificationListener, + * NotificationFilter, + * Object) + */ + void addNotificationListener(ObjectName name, ObjectName listener, + NotificationFilter filter, Object passback) + throws InstanceNotFoundException; + + /** + * <p> + * Instantiates a new instance of the specified management bean + * using the default constructor and registers it with the server + * under the supplied name. The class is loaded using the + * {@link javax.management.loading.ClassLoaderRepository default + * loader repository} of the server. + * </p> + * <p> + * If the name supplied is <code>null</code>, then the bean is + * expected to implement the {@link MBeanRegistration} interface. + * The {@link MBeanRegistration#preRegister preRegister} method + * of this interface will be used to obtain the name in this case. + * </p> + * <p> + * This method is equivalent to calling {@link + * #createMBean(String, ObjectName, Object[], String[]) + * <code>createMBean(className, name, (Object[]) null, + * (String[]) null)</code>} with <code>null</code> parameters + * and signature. + * </p> + * + * @param className the class of the management bean, of which + * an instance should be created. + * @param name the name to register the new bean with. + * @return an {@link ObjectInstance} containing the {@link ObjectName} + * and Java class name of the created instance. + * @throws ReflectionException if an exception occurs in creating + * an instance of the bean. + * @throws InstanceAlreadyExistsException if a matching instance + * already exists. + * @throws MBeanRegistrationException if an exception occurs in + * calling the preRegister + * method. + * @throws MBeanException if the bean's constructor throws an exception. + * @throws NotCompliantMBeanException if the created bean is not + * compliant with the JMX specification. + * @throws RuntimeOperationsException if an {@link IllegalArgumentException} + * is thrown by the server due to a + * <code>null</code> class name or object + * name or if the object name is a pattern. + * @throws SecurityException if a security manager exists and the + * caller's permissions don't imply the + * use of the <code>instantiate</code> + * and <code>registerMBean</code> methods. + * @see #createMBean(String, ObjectName, Object[], String[]) + */ + ObjectInstance createMBean(String className, ObjectName name) + throws ReflectionException, InstanceAlreadyExistsException, + MBeanRegistrationException, MBeanException, + NotCompliantMBeanException; + + /** + * <p> + * Instantiates a new instance of the specified management bean + * using the given constructor and registers it with the server + * under the supplied name. The class is loaded using the + * {@link javax.management.loading.ClassLoaderRepository default + * loader repository} of the server. + * </p> + * <p> + * If the name supplied is <code>null</code>, then the bean is + * expected to implement the {@link MBeanRegistration} interface. + * The {@link MBeanRegistration#preRegister preRegister} method + * of this interface will be used to obtain the name in this case. + * </p> + * + * @param className the class of the management bean, of which + * an instance should be created. + * @param name the name to register the new bean with. + * @param params the parameters for the bean's constructor. + * @param sig the signature of the constructor to use. + * @return an {@link ObjectInstance} containing the {@link ObjectName} + * and Java class name of the created instance. + * @throws ReflectionException if an exception occurs in creating + * an instance of the bean. + * @throws InstanceAlreadyExistsException if a matching instance + * already exists. + * @throws MBeanRegistrationException if an exception occurs in + * calling the preRegister + * method. + * @throws MBeanException if the bean's constructor throws an exception. + * @throws NotCompliantMBeanException if the created bean is not + * compliant with the JMX specification. + * @throws RuntimeOperationsException if an {@link IllegalArgumentException} + * is thrown by the server due to a + * <code>null</code> class name or object + * name or if the object name is a pattern. + * @throws SecurityException if a security manager exists and the + * caller's permissions don't imply the + * use of the <code>instantiate</code> + * and <code>registerMBean</code> methods. + */ + ObjectInstance createMBean(String className, ObjectName name, + Object[] params, String[] sig) + throws ReflectionException, InstanceAlreadyExistsException, + MBeanRegistrationException, MBeanException, + NotCompliantMBeanException; + + /** + * <p> + * Instantiates a new instance of the specified management bean + * using the default constructor and registers it with the server + * under the supplied name. The class is loaded using the + * given class loader. If this argument is <code>null</code>, + * then the same class loader as was used to load the server + * is used. + * </p> + * <p> + * If the name supplied is <code>null</code>, then the bean is + * expected to implement the {@link MBeanRegistration} interface. + * The {@link MBeanRegistration#preRegister preRegister} method + * of this interface will be used to obtain the name in this case. + * </p> + * <p> + * This method is equivalent to calling {@link + * #createMBean(String, ObjectName, ObjectName, Object[], String) + * <code>createMBean(className, name, loaderName, (Object[]) null, + * (String) null)</code>} with <code>null</code> parameters + * and signature. + * </p> + * + * @param className the class of the management bean, of which + * an instance should be created. + * @param name the name to register the new bean with. + * @param loaderName the name of the class loader. + * @return an {@link ObjectInstance} containing the {@link ObjectName} + * and Java class name of the created instance. + * @throws ReflectionException if an exception occurs in creating + * an instance of the bean. + * @throws InstanceAlreadyExistsException if a matching instance + * already exists. + * @throws MBeanRegistrationException if an exception occurs in + * calling the preRegister + * method. + * @throws MBeanException if the bean's constructor throws an exception. + * @throws NotCompliantMBeanException if the created bean is not + * compliant with the JMX specification. + * @throws InstanceNotFoundException if the specified class loader is not + * registered with the server. + * @throws RuntimeOperationsException if an {@link IllegalArgumentException} + * is thrown by the server due to a + * <code>null</code> class name or object + * name or if the object name is a pattern. + * @throws SecurityException if a security manager exists and the + * caller's permissions don't imply the + * use of the <code>instantiate</code> + * and <code>registerMBean</code> methods. + * @see #createMBean(String, ObjectName, ObjectName, Object[], String[]) + */ + ObjectInstance createMBean(String className, ObjectName name, + ObjectName loaderName) + throws ReflectionException, InstanceAlreadyExistsException, + MBeanRegistrationException, MBeanException, + NotCompliantMBeanException, InstanceNotFoundException; + + /** + * <p> + * Instantiates a new instance of the specified management bean + * using the given constructor and registers it with the server + * under the supplied name. The class is loaded using the + * given class loader. If this argument is <code>null</code>, + * then the same class loader as was used to load the server + * is used. + * </p> + * <p> + * If the name supplied is <code>null</code>, then the bean is + * expected to implement the {@link MBeanRegistration} interface. + * The {@link MBeanRegistration#preRegister preRegister} method + * of this interface will be used to obtain the name in this case. + * </p> + * + * @param className the class of the management bean, of which + * an instance should be created. + * @param name the name to register the new bean with. + * @param loaderName the name of the class loader. + * @param params the parameters for the bean's constructor. + * @param sig the signature of the constructor to use. + * @return an {@link ObjectInstance} containing the {@link ObjectName} + * and Java class name of the created instance. + * @throws ReflectionException if an exception occurs in creating + * an instance of the bean. + * @throws InstanceAlreadyExistsException if a matching instance + * already exists. + * @throws MBeanRegistrationException if an exception occurs in + * calling the preRegister + * method. + * @throws MBeanException if the bean's constructor throws an exception. + * @throws NotCompliantMBeanException if the created bean is not + * compliant with the JMX specification. + * @throws InstanceNotFoundException if the specified class loader is not + * registered with the server. + * @throws RuntimeOperationsException if an {@link IllegalArgumentException} + * is thrown by the server due to a + * <code>null</code> class name or object + * name or if the object name is a pattern. + * @throws SecurityException if a security manager exists and the + * caller's permissions don't imply the + * use of the <code>instantiate</code> + * and <code>registerMBean</code> methods. + */ + ObjectInstance createMBean(String className, ObjectName name, + ObjectName loaderName, Object[] params, + String[] sig) + throws ReflectionException, InstanceAlreadyExistsException, + MBeanRegistrationException, MBeanException, + NotCompliantMBeanException, InstanceNotFoundException; + + /** + * Deserializes a byte array using the class loader of the specified + * management bean as its context. + * + * @param name the name of the bean whose class loader should be used. + * @param data the byte array to be deserialized. + * @return the deserialized object stream. + * @deprecated {@link #getClassLoaderFor(ObjectName)} should be used + * to obtain the class loader of the bean, which can then + * be used to perform deserialization in the user's code. + * @throws InstanceNotFoundException if the specified bean is not + * registered with the server. + * @throws OperationsException if any I/O error is thrown by the + * deserialization process. + * @throws SecurityException if a security manager exists and the + * caller's permissions don't imply {@link + * MBeanPermission(String,String,ObjectName,String) + * <code>MBeanPermission(className, null, name, + * "getClassLoaderFor")</code> + */ + ObjectInputStream deserialize(ObjectName name, byte[] data) + throws InstanceNotFoundException, OperationsException; + + /** + * Deserializes a byte array using the same class loader for its context + * as was used to load the given class. This class loader is obtained by + * loading the specified class using the {@link + * javax.management.loading.ClassLoaderRepository Class Loader Repository} + * and then using the class loader of the resulting {@link Class} instance. + * + * @param name the name of the class which should be loaded to obtain the + * class loader. + * @param data the byte array to be deserialized. + * @return the deserialized object stream. + * @deprecated {@link #getClassLoaderRepository} should be used + * to obtain the class loading repository, which can then + * be used to obtain the {@link Class} instance and deserialize + * the array using its class loader. + * @throws OperationsException if any I/O error is thrown by the + * deserialization process. + * @throws ReflectionException if an error occurs in obtaining the + * {@link Class} instance. + * @throws SecurityException if a security manager exists and the + * caller's permissions don't imply {@link + * MBeanPermission(String,String,ObjectName,String) + * <code>MBeanPermission(null, null, null, + * "getClassLoaderRepository")</code> + */ + ObjectInputStream deserialize(String name, byte[] data) + throws OperationsException, ReflectionException; + + /** + * Deserializes a byte array using the same class loader for its context + * as was used to load the given class. The name of the class loader to + * be used is supplied, and may be <code>null</code> if the server's + * class loader should be used instead. + * + * @param name the name of the class which should be loaded to obtain the + * class loader. + * @param loader the name of the class loader to use, or <code>null</code> + * if the class loader of the server should be used. + * @param data the byte array to be deserialized. + * @return the deserialized object stream. + * @deprecated {@link #getClassLoader(ObjectName} can be used to obtain + * the named class loader and deserialize the array. + * @throws InstanceNotFoundException if the specified class loader is not + * registered with the server. + * @throws OperationsException if any I/O error is thrown by the + * deserialization process. + * @throws ReflectionException if an error occurs in obtaining the + * {@link Class} instance. + * @throws SecurityException if a security manager exists and the + * caller's permissions don't imply {@link + * MBeanPermission(String,String,ObjectName,String) + * <code>MBeanPermission(className, null, loader, + * "getClassLoader")</code> + */ + ObjectInputStream deserialize(String name, ObjectName loader, byte[] data) + throws InstanceNotFoundException, ReflectionException, + OperationsException; + + /** + * Returns the value of the supplied attribute from the specified + * management bean. + * + * @param bean the bean to retrieve the value from. + * @param name the name of the attribute to retrieve. + * @return the value of the attribute. + * @throws AttributeNotFoundException if the attribute could not be + * accessed from the bean. + * @throws MBeanException if the management bean's accessor throws + * an exception. + * @throws InstanceNotFoundException if the bean can not be found. + * @throws ReflectionException if an exception was thrown in trying + * to invoke the bean's accessor. + * @throws RuntimeOperationsException if an {@link IllegalArgumentException} + * is thrown by the server due to a + * <code>null</code> bean or attribute + * name. + * @throws SecurityException if a security manager exists and the + * caller's permissions don't imply {@link + * MBeanPermission(String,String,ObjectName,String) + * <code>MBeanPermission(className, name, bean, + * "getAttribute")</code>}. + * @see DynamicMBean#getAttribute(String) + */ + Object getAttribute(ObjectName bean, String name) + throws MBeanException, AttributeNotFoundException, + InstanceNotFoundException, ReflectionException; + + /** + * Returns the values of the named attributes from the specified + * management bean. + * + * @param bean the bean to retrieve the value from. + * @param names the names of the attributes to retrieve. + * @return the values of the attributes. + * @throws InstanceNotFoundException if the bean can not be found. + * @throws ReflectionException if an exception was thrown in trying + * to invoke the bean's accessor. + * @throws RuntimeOperationsException if an {@link IllegalArgumentException} + * is thrown by the server due to a + * <code>null</code> bean or attribute + * name. + * @throws SecurityException if a security manager exists and the + * caller's permissions don't imply {@link + * MBeanPermission(String,String,ObjectName,String) + * <code>MBeanPermission(className, null, bean, + * "getAttribute")</code>}. Additionally, + * for an attribute name, <code>n</code>, the + * caller's permission must imply {@link + * MBeanPermission(String,String,ObjectName,String) + * <code>MBeanPermission(className, n, bean, + * "getAttribute")</code>} or that attribute will + * not be included. + * + * @see DynamicMBean#getAttributes(String[]) + */ + AttributeList getAttributes(ObjectName bean, String[] names) + throws InstanceNotFoundException, ReflectionException; + + /** + * Returns the specified class loader. If the specified value is + * <code>null</code>, then the class loader of the server will be + * returned. If <code>l</code> is the requested class loader, + * and <code>r</code> is the actual class loader returned, then + * either <code>l</code> and <code>r</code> will be identical, + * or they will at least return the same class from + * {@link ClassLoader#loadClass(String)} for any given string. + * They may not be identical due to one or the other + * being wrapped in another class loader (e.g. for security). + * + * @param name the name of the class loader to return. + * @return the class loader. + * @throws InstanceNotFoundException if the class loader can not + * be found. + * @throws SecurityException if a security manager exists and the + * caller's permissions don't imply {@link + * MBeanPermission(String,String,ObjectName,String) + * <code>MBeanPermission(className, null, name, + * "getClassLoader")</code> + */ + ClassLoader getClassLoader(ObjectName name) + throws InstanceNotFoundException; + + /** + * Returns the class loader of the specified management bean. If + * <code>l</code> is the requested class loader, and <code>r</code> + * is the actual class loader returned, then either <code>l</code> + * and <code>r</code> will be identical, or they will at least + * return the same class from {@link ClassLoader#loadClass(String)} + * for any given string. They may not be identical due to one or + * the other being wrapped in another class loader (e.g. for + * security). + * + * @param name the name of the bean whose class loader should be + * returned. + * @return the class loader. + * @throws InstanceNotFoundException if the bean is not registered + * with the server. + * @throws SecurityException if a security manager exists and the + * caller's permissions don't imply {@link + * MBeanPermission(String,String,ObjectName,String) + * <code>MBeanPermission(className, null, name, + * "getClassLoaderFor")</code> + */ + ClassLoader getClassLoaderFor(ObjectName name) + throws InstanceNotFoundException; + + /** + * Returns the class loader repository used by this server. + * + * @return the class loader repository. + * @throws SecurityException if a security manager exists and the + * caller's permissions don't imply {@link + * MBeanPermission(String,String,ObjectName,String) + * <code>MBeanPermission(null, null, null, + * "getClassLoaderRepository")</code> + */ + ClassLoaderRepository getClassLoaderRepository(); + + /** + * Returns the default domain this server applies to beans that have + * no specified domain. + * + * @return the default domain. + */ + String getDefaultDomain(); + + /** + * Returns an array containing all the domains used by beans registered + * with this server. The ordering of the array is undefined. + * + * @return the list of domains. + * @throws SecurityException if a security manager exists and the + * caller's permissions don't imply {@link + * MBeanPermission(String,String,ObjectName,String) + * <code>MBeanPermission(null, null, name, + * "getDomains")</code>}. Additionally, + * for an domain, <code>d</code>, the + * caller's permission must imply {@link + * MBeanPermission(String,String,ObjectName,String) + * <code>MBeanPermission(null, null, + * new ObjectName("d:x=x"), "getDomains")</code>} + * or that domain will not be included. Note + * that "x=x" is an arbitrary key-value pair + * provided to satisfy the constructor. + * @see ObjectName#getDomain() + */ + String[] getDomains(); + + /** + * Returns the number of management beans registered with this server. + * This may be less than the real number if the caller's access is + * restricted. + * + * @return the number of registered beans. + */ + Integer getMBeanCount(); + + /** + * Returns information on the given management bean. + * + * @param name the name of the management bean. + * @return an instance of {@link MBeanInfo} for the bean. + * @throws IntrospectionException if an exception occurs in examining + * the bean. + * @throws InstanceNotFoundException if the bean can not be found. + * @throws ReflectionException if an exception occurs when trying + * to invoke {@link DynamicMBean#getMBeanInfo()} + * on the bean. + * @throws SecurityException if a security manager exists and the + * caller's permissions don't imply {@link + * MBeanPermission(String,String,ObjectName,String) + * <code>MBeanPermission(className, null, name, + * "getMBeanInfo")</code>}. + * @see DynamicMBean#getMBeanInfo() + */ + MBeanInfo getMBeanInfo(ObjectName name) + throws InstanceNotFoundException, IntrospectionException, + ReflectionException; + + /** + * Returns the {@link ObjectInstance} created for the specified + * management bean on registration. + * + * @param name the name of the bean. + * @return the corresponding {@link ObjectInstance} instance. + * @throws InstanceNotFoundException if the bean can not be found. + * @throws SecurityException if a security manager exists and the + * caller's permissions don't imply {@link + * MBeanPermission(String,String,ObjectName,String) + * <code>MBeanPermission(className, null, name, + * "getObjectInstance")</code> + * @see #createMBean(String, ObjectName) + */ + ObjectInstance getObjectInstance(ObjectName name) + throws InstanceNotFoundException; + + /** + * <p> + * Creates an instance of the specified class using the list of + * class loaders from the {@link + * javax.management.loading.ClassLoaderRepository Class Loader + * Repository}. The class should have a public constructor + * with no arguments. A reference to the new instance is returned, + * but the instance is not yet registered with the server. + * </p> + * <p> + * This method is equivalent to calling {@link + * #instantiate(String, Object[], String[]) + * <code>instantiate(name, (Object[]) null, (String[]) null)</code>} + * with <code>null</code> parameters and signature. + * </p> + * + * @param name the name of the class of bean to be instantiated. + * @return an instance of the given class. + * @throws ReflectionException if an exception is thrown during + * loading the class or calling the + * constructor. + * @throws MBeanException if the constructor throws an exception. + * @throws RuntimeOperationsException if an {@link IllegalArgumentException} + * is thrown by the server due to a + * <code>null</code> name. + * @throws SecurityException if a security manager exists and the + * caller's permissions don't imply {@link + * MBeanPermission(String,String,ObjectName,String) + * <code>MBeanPermission(className, null, null, + * "instantiate")</code>}. + * @see #instantiate(String, Object[], String[]) + */ + Object instantiate(String name) + throws ReflectionException, MBeanException; + + /** + * Creates an instance of the specified class using the list of + * class loaders from the {@link + * javax.management.loading.ClassLoaderRepository Class Loader + * Repository}. The class should have a public constructor + * matching the supplied signature. A reference to the new + * instance is returned, but the instance is not yet + * registered with the server. + * + * @param name the name of the class of bean to be instantiated. + * @param params the parameters for the constructor. + * @param sig the signature of the constructor. + * @return an instance of the given class. + * @throws ReflectionException if an exception is thrown during + * loading the class or calling the + * constructor. + * @throws MBeanException if the constructor throws an exception. + * @throws RuntimeOperationsException if an {@link IllegalArgumentException} + * is thrown by the server due to a + * <code>null</code> name. + * @throws SecurityException if a security manager exists and the + * caller's permissions don't imply {@link + * MBeanPermission(String,String,ObjectName,String) + * <code>MBeanPermission(className, null, null, + * "instantiate")</code>}. + */ + Object instantiate(String name, Object[] params, String[] sig) + throws ReflectionException, MBeanException; + + /** + * <p> + * Creates an instance of the specified class using the supplied + * class loader. If the class loader given is <code>null</code>, + * then the class loader of the server will be used. The class + * should have a public constructor with no arguments. A reference + * to the new instance is returned, but the instance is not yet + * registered with the server. + * </p> + * <p> + * This method is equivalent to calling {@link + * #instantiate(String, ObjectName, Object[], String[]) + * <code>instantiate(name, loaderName, (Object[]) null, + * (String[]) null)</code>} with <code>null</code> parameters + * and signature. + * </p> + * + * @param name the name of the class of bean to be instantiated. + * @param loaderName the name of the class loader to use. + * @return an instance of the given class. + * @throws InstanceNotFoundException if the class loader is not + * registered with the server. + * @throws ReflectionException if an exception is thrown during + * loading the class or calling the + * constructor. + * @throws MBeanException if the constructor throws an exception. + * @throws RuntimeOperationsException if an {@link IllegalArgumentException} + * is thrown by the server due to a + * <code>null</code> name. + * @throws SecurityException if a security manager exists and the + * caller's permissions don't imply {@link + * MBeanPermission(String,String,ObjectName,String) + * <code>MBeanPermission(className, null, null, + * "instantiate")</code>}. + * @see #instantiate(String, Object[], String[]) + */ + Object instantiate(String name, ObjectName loaderName) + throws InstanceNotFoundException, ReflectionException, + MBeanException; + + /** + * Creates an instance of the specified class using the supplied + * class loader. If the class loader given is <code>null</code>, + * then the class loader of the server will be used. The class + * should have a public constructor matching the supplied + * signature. A reference to the new instance is returned, + * but the instance is not yet registered with the server. + * + * @param name the name of the class of bean to be instantiated. + * @param loaderName the name of the class loader to use. + * @param params the parameters for the constructor. + * @param sig the signature of the constructor. + * @return an instance of the given class. + * @throws InstanceNotFoundException if the class loader is not + * registered with the server. + * @throws ReflectionException if an exception is thrown during + * loading the class or calling the + * constructor. + * @throws MBeanException if the constructor throws an exception. + * @throws RuntimeOperationsException if an {@link IllegalArgumentException} + * is thrown by the server due to a + * <code>null</code> name. + * @throws SecurityException if a security manager exists and the + * caller's permissions don't imply {@link + * MBeanPermission(String,String,ObjectName,String) + * <code>MBeanPermission(className, null, null, + * "instantiate")</code>}. + */ + Object instantiate(String name, ObjectName loaderName, + Object[] params, String[] sig) + throws InstanceNotFoundException, ReflectionException, + MBeanException; + + /** + * Invokes the supplied operation on the specified management + * bean. The class objects specified in the signature are loaded + * using the same class loader as was used for the management bean. + * + * @param bean the management bean whose operation should be invoked. + * @param name the name of the operation to invoke. + * @param params the parameters of the operation. + * @param sig the signature of the operation. + * @return the return value of the method. + * @throws InstanceNotFoundException if the bean can not be found. + * @throws MBeanException if the method invoked throws an exception. + * @throws ReflectionException if an exception is thrown in invoking the + * method. + * @throws SecurityException if a security manager exists and the + * caller's permissions don't imply {@link + * MBeanPermission(String,String,ObjectName,String) + * <code>MBeanPermission(className, name, bean, + * "invoke")</code>}. + * @see DynamicMBean#invoke(String, Object[], String[]) + */ + Object invoke(ObjectName bean, String name, Object[] params, String[] sig) + throws InstanceNotFoundException, MBeanException, + ReflectionException; + + /** + * <p> + * Returns true if the specified management bean is an instance + * of the supplied class. + * </p> + * <p> + * A bean, B, is an instance of a class, C, if either of the following + * conditions holds: + * </p> + * <ul> + * <li>The class name in B's {@link MBeanInfo} is equal to the supplied + * name.</li> + * <li>Both the class of B and C were loaded by the same class loader, + * and B is assignable to C.</li> + * </ul> + * + * @param name the name of the management bean. + * @param className the name of the class to test if <code>name</code> is + * an instance of. + * @return true if either B is directly an instance of the named class, + * or B is assignable to the class, given that both it and B's + * current class were loaded using the same class loader. + * @throws InstanceNotFoundException if the bean can not be found. + * @throws SecurityException if a security manager exists and the + * caller's permissions don't imply {@link + * MBeanPermission(String,String,ObjectName,String) + * <code>MBeanPermission(className, null, name, + * "isInstanceOf")</code> + */ + boolean isInstanceOf(ObjectName name, String className) + throws InstanceNotFoundException; + + /** + * Returns true if the specified management bean is registered with + * the server. + * + * @param name the name of the management bean. + * @return true if the bean is registered. + * @throws RuntimeOperationsException if an {@link IllegalArgumentException} + * is thrown by the server due to a + * <code>null</code> bean name. + */ + boolean isRegistered(ObjectName name); + + /** + * <p> + * Returns a set of {@link ObjectInstance}s matching the specified + * criteria. The full set of beans registered with the server + * are passed through two filters: + * </p> + * <ol> + * <li>Pattern matching is performed using the supplied + * {@link ObjectName}.</li> + * <li>The supplied query expression is applied.</li> + * </ol> + * <p> + * If both the object name and the query expression are <code>null</code>, + * or the object name has no domain and no key properties, + * no filtering will be performed and all beans are returned. + * </p> + * + * @param name an {@link ObjectName} to use as a filter. + * @param query a query expression to apply to each of the beans that match + * the given object name. + * @return a set of {@link ObjectInstance}s matching the filtered beans. + * @throws SecurityException if a security manager exists and the + * caller's permissions don't imply {@link + * MBeanPermission(String,String,ObjectName,String) + * <code>MBeanPermission(null, null, name, + * "queryMBeans")</code>}. Additionally, + * for an bean, <code>b</code>, the + * caller's permission must imply {@link + * MBeanPermission(String,String,ObjectName,String) + * <code>MBeanPermission(className, b, name, + * "queryMBeans")</code>} or that bean will + * not be included. Such an exception may also + * arise from the execution of the query, in which + * case that particular bean will again be excluded. + */ + Set<ObjectInstance> queryMBeans(ObjectName name, QueryExp query); + + /** + * <p> + * Returns a set of {@link ObjectName}s matching the specified + * criteria. The full set of beans registered with the server + * are passed through two filters: + * </p> + * <ol> + * <li>Pattern matching is performed using the supplied + * {@link ObjectName}.</li> + * <li>The supplied query expression is applied.</li> + * </ol> + * <p> + * If both the object name and the query expression are <code>null</code>, + * or the object name has no domain and no key properties, + * no filtering will be performed and all beans are returned. + * </p> + * + * @param name an {@link ObjectName} to use as a filter. + * @param query a query expression to apply to each of the beans that match + * the given object name. + * @return a set of {@link ObjectName}s matching the filtered beans. + * @throws SecurityException if a security manager exists and the + * caller's permissions don't imply {@link + * MBeanPermission(String,String,ObjectName,String) + * <code>MBeanPermission(null, null, name, + * "queryNames")</code>}. Additionally, + * for an name, <code>n</code>, the + * caller's permission must imply {@link + * MBeanPermission(String,String,ObjectName,String) + * <code>MBeanPermission(className, n, name, + * "queryNames")</code>} or that name will + * not be included. Such an exception may also + * arise from the execution of the query, in which + * case that particular bean will again be excluded. + * Note that these permissions are implied if the + * <code>queryMBeans</code> permissions are available. + */ + Set<ObjectName> queryNames(ObjectName name, QueryExp query); + + /** + * Registers the supplied instance with the server, using the specified + * {@link ObjectName}. If the name given is <code>null</code>, then + * the bean supplied is expected to implement the {@link MBeanRegistration} + * interface and provide the name via the + * {@link MBeanRegistration#preRegister preRegister} method + * of this interface. + * + * @param obj the object to register with the server. + * @param name the name under which to register the object, + * or <code>null</code> if the {@link MBeanRegistration} + * interface should be used. + * @throws InstanceAlreadyExistsException if a matching instance + * already exists. + * @throws MBeanRegistrationException if an exception occurs in + * calling the preRegister + * method. + * @throws NotCompliantMBeanException if the created bean is not + * compliant with the JMX specification. + * @throws RuntimeOperationsException if an {@link IllegalArgumentException} + * is thrown by the server due to a + * <code>null</code> object. + * @throws SecurityException if a security manager exists and the + * caller's permissions don't imply {@link + * MBeanPermission(String,String,ObjectName,String) + * <code>MBeanPermission(className, null, name, + * "registerMBean")</code>}. <code>className</code> + * here corresponds to the result of + * {@link MBeanInfo#getClassName()} for objects of + * this class. If this check succeeds, a check + * is also made on its + * {@link java.security.ProtectionDomain} to ensure + * it implies {@link MBeanTrustPermission(String) + * <code>MBeanTrustPermission("register")</code>}. + * The use of the {@link MBeanRegistration} interface + * results in another {@link MBeanPermission} check + * being made on the returned {@link ObjectName}. + */ + ObjectInstance registerMBean(Object obj, ObjectName name) + throws InstanceAlreadyExistsException, MBeanRegistrationException, + NotCompliantMBeanException; + + /** + * Removes the specified listener from the list of recipients + * of notifications from the supplied bean. This includes all + * combinations of filters and passback objects registered for + * this listener. For more specific removal of listeners, see + * {@link #removeNotificationListener(ObjectName, + * NotificationListener,NotificationFilter,Object)} + * + * @param name the name of the management bean from which the + * listener should be removed. + * @param listener the listener to remove. + * @throws InstanceNotFoundException if the bean can not be found. + * @throws ListenerNotFoundException if the specified listener + * is not registered with the bean. + * @throws SecurityException if a security manager exists and the + * caller's permissions don't imply {@link + * MBeanPermission(String,String,ObjectName,String) + * <code>MBeanPermission(className, null, name, + * "removeNotificationListener")</code>}. + * @see #addNotificationListener(NotificationListener, NotificationFilter, + * java.lang.Object) + * @see NotificationBroadcaster#removeNotificationListener(NotificationListener) + */ + void removeNotificationListener(ObjectName name, + NotificationListener listener) + throws InstanceNotFoundException, ListenerNotFoundException; + + /** + * Removes the specified listener from the list of recipients + * of notifications from the supplied bean. Only the first instance with + * the supplied filter and passback object is removed. + * <code>null</code> is used as a valid value for these parameters, + * rather than as a way to remove all registration instances for + * the specified listener; for this behaviour instead, see + * {@link #removeNotificationListener(ObjectName, NotificationListener)}. + * + * @param name the name of the management bean from which the + * listener should be removed. + * @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 InstanceNotFoundException if the bean can not be found. + * @throws ListenerNotFoundException if the specified listener + * is not registered with the bean. + * @throws SecurityException if a security manager exists and the + * caller's permissions don't imply {@link + * MBeanPermission(String,String,ObjectName,String) + * <code>MBeanPermission(className, null, name, + * "removeNotificationListener")</code>}. + * @see #addNotificationListener(ObjectName, NotificationListener, + * NotificationFilter, Object) + * @see NotificationEmitter#removeNotificationListener(NotificationListener, + * NotificationFilter, + * Object) + */ + void removeNotificationListener(ObjectName name, + NotificationListener listener, + NotificationFilter filter, + Object passback) + throws InstanceNotFoundException, ListenerNotFoundException; + + /** + * Removes the specified listener from the list of recipients + * of notifications from the supplied bean. This includes all + * combinations of filters and passback objects registered for + * this listener. For more specific removal of listeners, see + * {@link #removeNotificationListener(ObjectName, + * ObjectName,NotificationFilter,Object)} + * + * @param name the name of the management bean from which the + * listener should be removed. + * @param listener the name of the listener to remove. + * @throws InstanceNotFoundException if a name doesn't match a registered + * bean. + * @throws ListenerNotFoundException if the specified listener + * is not registered with the bean. + * @throws SecurityException if a security manager exists and the + * caller's permissions don't imply {@link + * MBeanPermission(String,String,ObjectName,String) + * <code>MBeanPermission(className, null, name, + * "removeNotificationListener")</code>}. + * @see #addNotificationListener(NotificationListener, NotificationFilter, + * java.lang.Object) + * @see NotificationBroadcaster#removeNotificationListener(NotificationListener) + */ + void removeNotificationListener(ObjectName name, ObjectName listener) + throws InstanceNotFoundException, ListenerNotFoundException; + + /** + * Removes the specified listener from the list of recipients + * of notifications from the supplied bean. Only the first instance with + * the supplied filter and passback object is removed. + * <code>null</code> is used as a valid value for these parameters, + * rather than as a way to remove all registration instances for + * the specified listener; for this behaviour instead, see + * {@link #removeNotificationListener(ObjectName, ObjectName)}. + * + * @param name the name of the management bean from which the + * listener should be removed. + * @param listener the name of the listener to remove. + * @param filter the filter of the listener to remove. + * @param passback the passback object of the listener to remove. + * @throws InstanceNotFoundException if a name doesn't match a registered + * bean. + * @throws ListenerNotFoundException if the specified listener + * is not registered with the bean. + * @throws SecurityException if a security manager exists and the + * caller's permissions don't imply {@link + * MBeanPermission(String,String,ObjectName,String) + * <code>MBeanPermission(className, null, name, + * "removeNotificationListener")</code>}. + * @see #addNotificationListener(ObjectName, NotificationListener, + * NotificationFilter, Object) + * @see NotificationEmitter#removeNotificationListener(NotificationListener, + * NotificationFilter, + * Object) + */ + void removeNotificationListener(ObjectName name, + ObjectName listener, + NotificationFilter filter, + Object passback) + throws InstanceNotFoundException, ListenerNotFoundException; + + /** + * Sets the value of the specified attribute of the supplied + * management bean. + * + * @param name the name of the management bean. + * @param attribute the attribute to set. + * @throws InstanceNotFoundException if the bean can not be found. + * @throws AttributeNotFoundException if the attribute does not + * correspond to an attribute + * of the bean. + * @throws InvalidAttributeValueException if the value is invalid + * for this particular + * attribute of the bean. + * @throws MBeanException if setting the attribute causes + * the bean to throw an exception (which + * becomes the cause of this exception). + * @throws ReflectionException if an exception occurred in trying + * to use the reflection interface + * to lookup the attribute. The + * thrown exception is the cause of + * this exception. + * @throws RuntimeOperationsException if an {@link IllegalArgumentException} + * is thrown by the server due to a + * <code>null</code> bean or attribute + * name. + * @throws SecurityException if a security manager exists and the + * caller's permissions don't imply {@link + * MBeanPermission(String,String,ObjectName,String) + * <code>MBeanPermission(className, name, bean, + * "setAttribute")</code>}. + * @see #getAttribute(ObjectName, String) + * @see DynamicMBean#setAttribute(Attribute) + */ + void setAttribute(ObjectName name, Attribute attribute) + throws InstanceNotFoundException, AttributeNotFoundException, + InvalidAttributeValueException, MBeanException, + ReflectionException; + + /** + * Sets the value of each of the specified attributes + * of the supplied management bean to that specified by + * the {@link Attribute} object. The returned list contains + * the attributes that were set and their new values. + * + * @param name the name of the management bean. + * @param attributes the attributes to set. + * @return a list of the changed attributes. + * @throws InstanceNotFoundException if the bean can not be found. + * @throws ReflectionException if an exception occurred in trying + * to use the reflection interface + * to lookup the attribute. The + * thrown exception is the cause of + * this exception. + * @throws RuntimeOperationsException if an {@link IllegalArgumentException} + * is thrown by the server due to a + * <code>null</code> bean or attribute + * list. + * @throws SecurityException if a security manager exists and the + * caller's permissions don't imply {@link + * MBeanPermission(String,String,ObjectName,String) + * <code>MBeanPermission(className, null, bean, + * "setAttribute")</code>}. Additionally, + * for an attribute name, <code>n</code>, the + * caller's permission must imply {@link + * MBeanPermission(String,String,ObjectName,String) + * <code>MBeanPermission(className, n, bean, + * "setAttribute")</code>} or that attribute will + * not be included. + * @see #getAttributes(ObjectName, String[]) + * @see DynamicMBean#setAttributes(AttributeList) + */ + AttributeList setAttributes(ObjectName name, AttributeList attributes) + throws InstanceNotFoundException, ReflectionException; + + /** + * Unregisters the specified management bean. Following this operation, + * the bean instance is no longer accessible from the server via this + * name. Prior to unregistering the bean, the + * {@link MBeanRegistration#preDeregister()} method will be called if + * the bean implements the {@link MBeanRegistration} interface. + * + * @param name the name of the management bean. + * @throws InstanceNotFoundException if the bean can not be found. + * @throws MBeanRegistrationException if an exception occurs in + * calling the preDeregister + * method. + * @throws RuntimeOperationsException if an {@link IllegalArgumentException} + * is thrown by the server due to a + * <code>null</code> bean name or a + * request being made to unregister the + * {@link MBeanServerDelegate} bean. + * @throws SecurityException if a security manager exists and the + * caller's permissions don't imply {@link + * MBeanPermission(String,String,ObjectName,String) + * <code>MBeanPermission(className, null, name, + * "unregisterMBean")</code>}. + */ + void unregisterMBean(ObjectName name) + throws InstanceNotFoundException, MBeanRegistrationException; + +} diff --git a/libjava/classpath/javax/management/MBeanServerBuilder.java b/libjava/classpath/javax/management/MBeanServerBuilder.java new file mode 100644 index 000000000..ce45915d7 --- /dev/null +++ b/libjava/classpath/javax/management/MBeanServerBuilder.java @@ -0,0 +1,102 @@ +/* MBeanServerBuilder.java -- Creates a default management server. + Copyright (C) 2006 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.Server; + +/** + * Constructs a default implementation of an {@link MBeanServer}. + * The {@link MBeanServerFactory} allows custom implementations of + * {@link MBeanServer} to be used by providing subclasses of this. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public class MBeanServerBuilder +{ + + /** + * Constructs a new {@link MBeanServerBuilder}. + */ + public MBeanServerBuilder() + { + } + + /** + * <p> + * Creates a new {@link MBeanServer} implementation with the specified + * default domain, delegate and outer server. The latter is the server + * passed to the {@link MBeanRegistration} interface of management beans, + * allowing an {@link MBeanServer} implementation to wrap another in order + * to provide additional checks, etc. If this value is <code>null</code>, + * <code>this</code> is passed to beans instead. + * </p> + * <p> + * The {@link MBeanServerFactory} calls this method after having first + * created a delegate using the {@link #newMBeanServerDelegate()} method. + * However, the delegate used in the call to this method may not be the + * same as that returned by {@link #newMBeanServerDelegate()} as the factory + * can optionally wrap the delegate before calling this method. + * </p> + * + * @param defaultDomain the default domain used by the new server. + * @param outer the {@link MBeanServer} passed to the {@link MBeanRegistration} + * interface of management beans. + * @param delegate the delegate bean associated with the server, which must + * be registered as a management bean by the server. + * @return a new instance of a server implementation. + */ + public MBeanServer newMBeanServer(String defaultDomain, MBeanServer outer, + MBeanServerDelegate delegate) + { + return new Server(defaultDomain, outer, delegate); + } + + /** + * Creates a new {@link MBeanServerDelegate}, which will be used by + * a management server. The returned delegate may either be used directly + * by the server, or may be further wrapped to add additional checks. + * + * @return a new instance of {@link MBeanServerDelegate}. + */ + public MBeanServerDelegate newMBeanServerDelegate() + { + return new MBeanServerDelegate(); + } + +} diff --git a/libjava/classpath/javax/management/MBeanServerConnection.java b/libjava/classpath/javax/management/MBeanServerConnection.java new file mode 100644 index 000000000..9e44b8fce --- /dev/null +++ b/libjava/classpath/javax/management/MBeanServerConnection.java @@ -0,0 +1,768 @@ +/* MBeanServerConnection.java -- Represents a connection to a management server. + Copyright (C) 2006 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.IOException; + +import java.util.Set; + +/** + * This interface represents a communication mechanism which may + * be used to access an MBean server, whether this be local or + * remote. The {@link MBeanServer} interface extends this with + * additional methods that apply only to local servers. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public interface MBeanServerConnection +{ + + /** + * Registers the supplied listener with the specified management + * bean. Notifications emitted by the management bean are forwarded + * to the listener via the server, which will convert any MBean + * references in the source to portable {@link ObjectName} + * instances. The notification is otherwise unchanged. + * + * @param name the name of the management bean with which the listener + * should be registered. + * @param listener the listener which will handle notifications from + * the bean. + * @param filter the filter to apply to incoming notifications, or + * <code>null</code> if no filtering should be applied. + * @param passback an object to be passed to the listener when a + * notification is emitted. + * @throws InstanceNotFoundException if the name of the management bean + * could not be resolved. + * @throws IOException if an I/O error occurred in communicating with + * the bean server. + * @see #removeNotificationListener(ObjectName, NotificationListener) + * @see #removeNotificationListener(ObjectName, NotificationListener, + * NotificationFilter, Object) + * @see NotificationBroadcaster#addNotificationListener(NotificationListener, + * NotificationFilter, + * Object) + */ + void addNotificationListener(ObjectName name, NotificationListener listener, + NotificationFilter filter, Object passback) + throws InstanceNotFoundException, IOException; + + /** + * <p> + * Registers the supplied listener with the specified management + * bean. Notifications emitted by the management bean are forwarded + * to the listener via the server, which will convert any MBean + * references in the source to portable {@link ObjectName} + * instances. The notification is otherwise unchanged. + * </p> + * <p> + * The listener that receives notifications will be the one that is + * registered with the given name at the time this method is called. + * Even if it later unregisters and ceases to use that name, it will + * still receive notifications. + * </p> + * + * @param name the name of the management bean with which the listener + * should be registered. + * @param listener the name of the listener which will handle + * notifications from the bean. + * @param filter the filter to apply to incoming notifications, or + * <code>null</code> if no filtering should be applied. + * @param passback an object to be passed to the listener when a + * notification is emitted. + * @throws InstanceNotFoundException if the name of the management bean + * could not be resolved. + * @throws RuntimeOperationsException if the bean associated with the given + * object name is not a + * {@link NotificationListener}. This + * exception wraps an + * {@link IllegalArgumentException}. + * @throws IOException if an I/O error occurred in communicating with + * the bean server. + * @see #removeNotificationListener(ObjectName, NotificationListener) + * @see #removeNotificationListener(ObjectName, NotificationListener, + * NotificationFilter, Object) + * @see NotificationBroadcaster#addNotificationListener(NotificationListener, + * NotificationFilter, + * Object) + */ + void addNotificationListener(ObjectName name, ObjectName listener, + NotificationFilter filter, Object passback) + throws InstanceNotFoundException, RuntimeOperationsException, IOException; + + /** + * <p> + * Instantiates a new instance of the specified management bean + * using the default constructor and registers it with the server + * under the supplied name. The class is loaded using the + * {@link javax.management.loading.ClassLoaderRepository default + * loader repository} of the server. + * </p> + * <p> + * If the name supplied is <code>null</code>, then the bean is + * expected to implement the {@link MBeanRegistration} interface. + * The {@link MBeanRegistration#preRegister preRegister} method + * of this interface will be used to obtain the name in this case. + * </p> + * <p> + * This method is equivalent to calling {@link + * #createMBean(String, ObjectName, Object[], String[]) + * <code>createMBean(className, name, (Object[]) null, + * (String[]) null)</code>} with <code>null</code> parameters + * and signature. + * </p> + * + * @param className the class of the management bean, of which + * an instance should be created. + * @param name the name to register the new bean with. + * @return an {@link ObjectInstance} containing the {@link ObjectName} + * and Java class name of the created instance. + * @throws ReflectionException if an exception occurs in creating + * an instance of the bean. + * @throws InstanceAlreadyExistsException if a matching instance + * already exists. + * @throws MBeanRegistrationException if an exception occurs in + * calling the preRegister + * method. + * @throws MBeanException if the bean's constructor throws an exception. + * @throws NotCompliantMBeanException if the created bean is not + * compliant with the JMX specification. + * @throws RuntimeOperationsException if an {@link IllegalArgumentException} + * is thrown by the server due to a + * <code>null</code> class name or object + * name or if the object name is a pattern. + * @throws IOException if an I/O error occurred in communicating with + * the bean server. + * @see #createMBean(String, ObjectName, Object[], String[]) + */ + ObjectInstance createMBean(String className, ObjectName name) + throws ReflectionException, InstanceAlreadyExistsException, + MBeanRegistrationException, MBeanException, + NotCompliantMBeanException, IOException; + + /** + * <p> + * Instantiates a new instance of the specified management bean + * using the given constructor and registers it with the server + * under the supplied name. The class is loaded using the + * {@link javax.management.loading.ClassLoaderRepository default + * loader repository} of the server. + * </p> + * <p> + * If the name supplied is <code>null</code>, then the bean is + * expected to implement the {@link MBeanRegistration} interface. + * The {@link MBeanRegistration#preRegister preRegister} method + * of this interface will be used to obtain the name in this case. + * </p> + * + * @param className the class of the management bean, of which + * an instance should be created. + * @param name the name to register the new bean with. + * @param params the parameters for the bean's constructor. + * @param sig the signature of the constructor to use. + * @return an {@link ObjectInstance} containing the {@link ObjectName} + * and Java class name of the created instance. + * @throws ReflectionException if an exception occurs in creating + * an instance of the bean. + * @throws InstanceAlreadyExistsException if a matching instance + * already exists. + * @throws MBeanRegistrationException if an exception occurs in + * calling the preRegister + * method. + * @throws MBeanException if the bean's constructor throws an exception. + * @throws NotCompliantMBeanException if the created bean is not + * compliant with the JMX specification. + * @throws RuntimeOperationsException if an {@link IllegalArgumentException} + * is thrown by the server due to a + * <code>null</code> class name or object + * name or if the object name is a pattern. + * @throws IOException if an I/O error occurred in communicating with + * the bean server. + */ + ObjectInstance createMBean(String className, ObjectName name, + Object[] params, String[] sig) + throws ReflectionException, InstanceAlreadyExistsException, + MBeanRegistrationException, MBeanException, + NotCompliantMBeanException, IOException; + + /** + * <p> + * Instantiates a new instance of the specified management bean + * using the default constructor and registers it with the server + * under the supplied name. The class is loaded using the + * given class loader. If this argument is <code>null</code>, + * then the same class loader as was used to load the server + * is used. + * </p> + * <p> + * If the name supplied is <code>null</code>, then the bean is + * expected to implement the {@link MBeanRegistration} interface. + * The {@link MBeanRegistration#preRegister preRegister} method + * of this interface will be used to obtain the name in this case. + * </p> + * <p> + * This method is equivalent to calling {@link + * #createMBean(String, ObjectName, ObjectName, Object[], String) + * <code>createMBean(className, name, loaderName, (Object[]) null, + * (String) null)</code>} with <code>null</code> parameters + * and signature. + * </p> + * + * @param className the class of the management bean, of which + * an instance should be created. + * @param name the name to register the new bean with. + * @param loaderName the name of the class loader. + * @return an {@link ObjectInstance} containing the {@link ObjectName} + * and Java class name of the created instance. + * @throws ReflectionException if an exception occurs in creating + * an instance of the bean. + * @throws InstanceAlreadyExistsException if a matching instance + * already exists. + * @throws MBeanRegistrationException if an exception occurs in + * calling the preRegister + * method. + * @throws MBeanException if the bean's constructor throws an exception. + * @throws NotCompliantMBeanException if the created bean is not + * compliant with the JMX specification. + * @throws InstanceNotFoundException if the specified class loader is not + * registered with the server. + * @throws RuntimeOperationsException if an {@link IllegalArgumentException} + * is thrown by the server due to a + * <code>null</code> class name or object + * name or if the object name is a pattern. + * @throws IOException if an I/O error occurred in communicating with + * the bean server. + * @see #createMBean(String, ObjectName, ObjectName, Object[], String[]) + */ + ObjectInstance createMBean(String className, ObjectName name, + ObjectName loaderName) + throws ReflectionException, InstanceAlreadyExistsException, + MBeanRegistrationException, MBeanException, + NotCompliantMBeanException, InstanceNotFoundException, + IOException; + + /** + * <p> + * Instantiates a new instance of the specified management bean + * using the given constructor and registers it with the server + * under the supplied name. The class is loaded using the + * given class loader. If this argument is <code>null</code>, + * then the same class loader as was used to load the server + * is used. + * </p> + * <p> + * If the name supplied is <code>null</code>, then the bean is + * expected to implement the {@link MBeanRegistration} interface. + * The {@link MBeanRegistration#preRegister preRegister} method + * of this interface will be used to obtain the name in this case. + * </p> + * + * @param className the class of the management bean, of which + * an instance should be created. + * @param name the name to register the new bean with. + * @param loaderName the name of the class loader. + * @param params the parameters for the bean's constructor. + * @param sig the signature of the constructor to use. + * @return an {@link ObjectInstance} containing the {@link ObjectName} + * and Java class name of the created instance. + * @throws ReflectionException if an exception occurs in creating + * an instance of the bean. + * @throws InstanceAlreadyExistsException if a matching instance + * already exists. + * @throws MBeanRegistrationException if an exception occurs in + * calling the preRegister + * method. + * @throws MBeanException if the bean's constructor throws an exception. + * @throws NotCompliantMBeanException if the created bean is not + * compliant with the JMX specification. + * @throws InstanceNotFoundException if the specified class loader is not + * registered with the server. + * @throws RuntimeOperationsException if an {@link IllegalArgumentException} + * is thrown by the server due to a + * <code>null</code> class name or object + * name or if the object name is a pattern. + * @throws IOException if an I/O error occurred in communicating with + * the bean server. + */ + ObjectInstance createMBean(String className, ObjectName name, + ObjectName loaderName, Object[] params, + String[] sig) + throws ReflectionException, InstanceAlreadyExistsException, + MBeanRegistrationException, MBeanException, + NotCompliantMBeanException, InstanceNotFoundException, + IOException; + + /** + * Returns the value of the supplied attribute from the specified + * management bean. + * + * @param bean the bean to retrieve the value from. + * @param name the name of the attribute to retrieve. + * @return the value of the attribute. + * @throws AttributeNotFoundException if the attribute could not be + * accessed from the bean. + * @throws MBeanException if the management bean's accessor throws + * an exception. + * @throws InstanceNotFoundException if the bean can not be found. + * @throws ReflectionException if an exception was thrown in trying + * to invoke the bean's accessor. + * @throws RuntimeOperationsException if an {@link IllegalArgumentException} + * is thrown by the server due to a + * <code>null</code> bean or attribute + * name. + * @throws IOException if an I/O error occurred in communicating with + * the bean server. + * @see DynamicMBean#getAttribute(String) + */ + Object getAttribute(ObjectName bean, String name) + throws MBeanException, AttributeNotFoundException, + InstanceNotFoundException, ReflectionException, + IOException; + + /** + * Returns the values of the named attributes from the specified + * management bean. + * + * @param bean the bean to retrieve the value from. + * @param names the names of the attributes to retrieve. + * @return the values of the attributes. + * @throws InstanceNotFoundException if the bean can not be found. + * @throws ReflectionException if an exception was thrown in trying + * to invoke the bean's accessor. + * @throws RuntimeOperationsException if an {@link IllegalArgumentException} + * is thrown by the server due to a + * <code>null</code> bean or attribute + * name. + * @throws IOException if an I/O error occurred in communicating with + * the bean server. + * @see DynamicMBean#getAttributes(String[]) + */ + AttributeList getAttributes(ObjectName bean, String[] names) + throws InstanceNotFoundException, ReflectionException, + IOException; + + /** + * Returns the default domain this server applies to beans that have + * no specified domain. + * + * @return the default domain. + * @throws IOException if an I/O error occurred in communicating with + * the bean server. + */ + String getDefaultDomain() + throws IOException; + + /** + * Returns an array containing all the domains used by beans registered + * with this server. The ordering of the array is undefined. + * + * @return the list of domains. + * @throws IOException if an I/O error occurred in communicating with + * the bean server. + * @see ObjectName#getDomain() + */ + String[] getDomains() + throws IOException; + + /** + * Returns the number of management beans registered with this server. + * + * @return the number of registered beans. + * @throws IOException if an I/O error occurred in communicating with + * the bean server. + */ + Integer getMBeanCount() + throws IOException; + + /** + * Returns information on the given management bean. + * + * @param name the name of the management bean. + * @return an instance of {@link MBeanInfo} for the bean. + * @throws IntrospectionException if an exception occurs in examining + * the bean. + * @throws InstanceNotFoundException if the bean can not be found. + * @throws ReflectionException if an exception occurs when trying + * to invoke {@link DynamicMBean#getMBeanInfo()} + * on the bean. + * @throws IOException if an I/O error occurred in communicating with + * the bean server. + * @see DynamicMBean#getMBeanInfo() + */ + MBeanInfo getMBeanInfo(ObjectName name) + throws InstanceNotFoundException, IntrospectionException, + ReflectionException, IOException; + + /** + * Returns the {@link ObjectInstance} created for the specified + * management bean on registration. + * + * @param name the name of the bean. + * @return the corresponding {@link ObjectInstance} instance. + * @throws InstanceNotFoundException if the bean can not be found. + * @throws IOException if an I/O error occurred in communicating with + * the bean server. + * @see #createMBean(String, ObjectName) + */ + ObjectInstance getObjectInstance(ObjectName name) + throws InstanceNotFoundException, IOException; + + /** + * Invokes the supplied operation on the specified management + * bean. The class objects specified in the signature are loaded + * using the same class loader as was used for the management bean. + * + * @param bean the management bean whose operation should be invoked. + * @param name the name of the operation to invoke. + * @param params the parameters of the operation. + * @param sig the signature of the operation. + * @return the return value of the method. + * @throws InstanceNotFoundException if the bean can not be found. + * @throws MBeanException if the method invoked throws an exception. + * @throws ReflectionException if an exception is thrown in invoking the + * method. + * @throws IOException if an I/O error occurred in communicating with + * the bean server. + * @see DynamicMBean#invoke(String, Object[], String[]) + */ + Object invoke(ObjectName bean, String name, Object[] params, String[] sig) + throws InstanceNotFoundException, MBeanException, + ReflectionException, IOException; + + /** + * <p> + * Returns true if the specified management bean is an instance + * of the supplied class. + * </p> + * <p> + * A bean, B, is an instance of a class, C, if either of the following + * conditions holds: + * </p> + * <ul> + * <li>The class name in B's {@link MBeanInfo} is equal to the supplied + * name.</li> + * <li>Both the class of B and C were loaded by the same class loader, + * and B is assignable to C.</li> + * </ul> + * + * @param name the name of the management bean. + * @param className the name of the class to test if <code>name</code> is + * an instance of. + * @return true if either B is directly an instance of the named class, + * or B is assignable to the class, given that both it and B's + * current class were loaded using the same class loader. + * @throws InstanceNotFoundException if the bean can not be found. + * @throws IOException if an I/O error occurred in communicating with + * the bean server. + */ + boolean isInstanceOf(ObjectName name, String className) + throws InstanceNotFoundException, IOException; + + /** + * Returns true if the specified management bean is registered with + * the server. + * + * @param name the name of the management bean. + * @return true if the bean is registered. + * @throws RuntimeOperationsException if an {@link IllegalArgumentException} + * is thrown by the server due to a + * <code>null</code> bean name. + * @throws IOException if an I/O error occurred in communicating with + * the bean server. + */ + boolean isRegistered(ObjectName name) + throws IOException; + + /** + * <p> + * Returns a set of {@link ObjectInstance}s matching the specified + * criteria. The full set of beans registered with the server + * are passed through two filters: + * </p> + * <ol> + * <li>Pattern matching is performed using the supplied + * {@link ObjectName}.</li> + * <li>The supplied query expression is applied.</li> + * </ol> + * <p> + * If both the object name and the query expression are <code>null</code>, + * or the object name has no domain and no key properties, + * no filtering will be performed and all beans are returned. + * </p> + * + * @param name an {@link ObjectName} to use as a filter. + * @param query a query expression to apply to each of the beans that match + * the given object name. + * @return a set of {@link ObjectInstance}s matching the filtered beans. + * @throws IOException if an I/O error occurred in communicating with + * the bean server. + */ + Set<ObjectInstance> queryMBeans(ObjectName name, QueryExp query) + throws IOException; + + /** + * <p> + * Returns a set of {@link ObjectName}s matching the specified + * criteria. The full set of beans registered with the server + * are passed through two filters: + * </p> + * <ol> + * <li>Pattern matching is performed using the supplied + * {@link ObjectName}.</li> + * <li>The supplied query expression is applied.</li> + * </ol> + * <p> + * If both the object name and the query expression are <code>null</code>, + * or the object name has no domain and no key properties, + * no filtering will be performed and all beans are returned. + * </p> + * + * @param name an {@link ObjectName} to use as a filter. + * @param query a query expression to apply to each of the beans that match + * the given object name. + * @return a set of {@link ObjectName}s matching the filtered beans. + * @throws IOException if an I/O error occurred in communicating with + * the bean server. + */ + Set<ObjectName> queryNames(ObjectName name, QueryExp query) + throws IOException; + + /** + * Removes the specified listener from the list of recipients + * of notifications from the supplied bean. This includes all + * combinations of filters and passback objects registered for + * this listener. For more specific removal of listeners, see + * {@link #removeNotificationListener(ObjectName, + * NotificationListener,NotificationFilter,Object)} + * + * @param name the name of the management bean from which the + * listener should be removed. + * @param listener the listener to remove. + * @throws InstanceNotFoundException if the bean can not be found. + * @throws ListenerNotFoundException if the specified listener + * is not registered with the bean. + * @throws IOException if an I/O error occurred in communicating with + * the bean server. + * @see #addNotificationListener(NotificationListener, NotificationFilter, + * java.lang.Object) + * @see NotificationBroadcaster#removeNotificationListener(NotificationListener) + */ + void removeNotificationListener(ObjectName name, + NotificationListener listener) + throws InstanceNotFoundException, ListenerNotFoundException, + IOException; + + /** + * Removes the specified listener from the list of recipients + * of notifications from the supplied bean. Only the first instance with + * the supplied filter and passback object is removed. + * <code>null</code> is used as a valid value for these parameters, + * rather than as a way to remove all registration instances for + * the specified listener; for this behaviour instead, see + * {@link #removeNotificationListener(ObjectName, NotificationListener)}. + * + * @param name the name of the management bean from which the + * listener should be removed. + * @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 InstanceNotFoundException if the bean can not be found. + * @throws ListenerNotFoundException if the specified listener + * is not registered with the bean. + * @throws IOException if an I/O error occurred in communicating with + * the bean server. + * @see #addNotificationListener(ObjectName, NotificationListener, + * NotificationFilter, Object) + * @see NotificationEmitter#removeNotificationListener(NotificationListener, + * NotificationFilter, + * Object) + */ + void removeNotificationListener(ObjectName name, + NotificationListener listener, + NotificationFilter filter, + Object passback) + throws InstanceNotFoundException, ListenerNotFoundException, + IOException; + + /** + * Removes the specified listener from the list of recipients + * of notifications from the supplied bean. This includes all + * combinations of filters and passback objects registered for + * this listener. For more specific removal of listeners, see + * {@link #removeNotificationListener(ObjectName, + * ObjectName,NotificationFilter,Object)} + * + * @param name the name of the management bean from which the + * listener should be removed. + * @param listener the name of the listener to remove. + * @throws InstanceNotFoundException if a name doesn't match a registered + * bean. + * @throws ListenerNotFoundException if the specified listener + * is not registered with the bean. + * @throws IOException if an I/O error occurred in communicating with + * the bean server. + * @see #addNotificationListener(NotificationListener, NotificationFilter, + * java.lang.Object) + * @see NotificationBroadcaster#removeNotificationListener(NotificationListener) + */ + void removeNotificationListener(ObjectName name, ObjectName listener) + throws InstanceNotFoundException, ListenerNotFoundException, + IOException; + + /** + * Removes the specified listener from the list of recipients + * of notifications from the supplied bean. Only the first instance with + * the supplied filter and passback object is removed. + * <code>null</code> is used as a valid value for these parameters, + * rather than as a way to remove all registration instances for + * the specified listener; for this behaviour instead, see + * {@link #removeNotificationListener(ObjectName, ObjectName)}. + * + * @param name the name of the management bean from which the + * listener should be removed. + * @param listener the name of the listener to remove. + * @param filter the filter of the listener to remove. + * @param passback the passback object of the listener to remove. + * @throws InstanceNotFoundException if a name doesn't match a registered + * bean. + * @throws ListenerNotFoundException if the specified listener + * is not registered with the bean. + * @throws IOException if an I/O error occurred in communicating with + * the bean server. + * @see #addNotificationListener(ObjectName, NotificationListener, + * NotificationFilter, Object) + * @see NotificationEmitter#removeNotificationListener(NotificationListener, + * NotificationFilter, + * Object) + */ + void removeNotificationListener(ObjectName name, + ObjectName listener, + NotificationFilter filter, + Object passback) + throws InstanceNotFoundException, ListenerNotFoundException, + IOException; + + /** + * Sets the value of the specified attribute of the supplied + * management bean. + * + * @param name the name of the management bean. + * @param attribute the attribute to set. + * @throws InstanceNotFoundException if the bean can not be found. + * @throws AttributeNotFoundException if the attribute does not + * correspond to an attribute + * of the bean. + * @throws InvalidAttributeValueException if the value is invalid + * for this particular + * attribute of the bean. + * @throws MBeanException if setting the attribute causes + * the bean to throw an exception (which + * becomes the cause of this exception). + * @throws ReflectionException if an exception occurred in trying + * to use the reflection interface + * to lookup the attribute. The + * thrown exception is the cause of + * this exception. + * @throws RuntimeOperationsException if an {@link IllegalArgumentException} + * is thrown by the server due to a + * <code>null</code> bean or attribute + * name. + * @throws IOException if an I/O error occurred in communicating with + * the bean server. + * @see #getAttribute(ObjectName, String) + * @see DynamicMBean#setAttribute(Attribute) + */ + void setAttribute(ObjectName name, Attribute attribute) + throws InstanceNotFoundException, AttributeNotFoundException, + InvalidAttributeValueException, MBeanException, + ReflectionException, IOException; + + /** + * Sets the value of each of the specified attributes + * of the supplied management bean to that specified by + * the {@link Attribute} object. The returned list contains + * the attributes that were set and their new values. + * + * @param name the name of the management bean. + * @param attributes the attributes to set. + * @return a list of the changed attributes. + * @throws InstanceNotFoundException if the bean can not be found. + * @throws ReflectionException if an exception occurred in trying + * to use the reflection interface + * to lookup the attribute. The + * thrown exception is the cause of + * this exception. + * @throws RuntimeOperationsException if an {@link IllegalArgumentException} + * is thrown by the server due to a + * <code>null</code> bean or attribute + * list. + * @throws IOException if an I/O error occurred in communicating with + * the bean server. + * @see #getAttributes(ObjectName, String[]) + * @see DynamicMBean#setAttributes(AttributeList) + */ + AttributeList setAttributes(ObjectName name, AttributeList attributes) + throws InstanceNotFoundException, ReflectionException, + IOException; + + /** + * Unregisters the specified management bean. Following this operation, + * the bean instance is no longer accessible from the server via this + * name. Prior to unregistering the bean, the + * {@link MBeanRegistration#preDeregister()} method will be called if + * the bean implements the {@link MBeanRegistration} interface. + * + * @param name the name of the management bean. + * @throws InstanceNotFoundException if the bean can not be found. + * @throws MBeanRegistrationException if an exception occurs in + * calling the preDeregister + * method. + * @throws RuntimeOperationsException if an {@link IllegalArgumentException} + * is thrown by the server due to a + * <code>null</code> bean name or a + * request being made to unregister the + * {@link MBeanServerDelegate} bean. + * @throws IOException if an I/O error occurred in communicating with + * the bean server. + */ + void unregisterMBean(ObjectName name) + throws InstanceNotFoundException, MBeanRegistrationException, + IOException; + +} diff --git a/libjava/classpath/javax/management/MBeanServerDelegate.java b/libjava/classpath/javax/management/MBeanServerDelegate.java new file mode 100644 index 000000000..5addb9932 --- /dev/null +++ b/libjava/classpath/javax/management/MBeanServerDelegate.java @@ -0,0 +1,304 @@ +/* MBeanServerDelegate.java -- The management server delegate. + Copyright (C) 2006 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 gnu.classpath.SystemProperties; + +import java.net.InetAddress; +import java.net.UnknownHostException; + +import java.util.ArrayList; +import java.util.Date; +import java.util.Iterator; +import java.util.List; + +/** + * Provides an implementation of a delegate bean, which is associated + * with a management server. The delegate bean is responsible + * for providing metadata about the server and handling the + * registration and deregistration notifications. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public class MBeanServerDelegate + implements MBeanServerDelegateMBean, NotificationEmitter +{ + + /** + * The identifier of the server associated with this delegate. + */ + private String id; + + /** + * The listeners registered with the delegate. + */ + private final List<ListenerData> listeners = + new ArrayList<ListenerData>(); + + /** + * The sequence identifier used by the delegate. + */ + private long seqNo; + + /** + * Default constructor which generates the id. + */ + public MBeanServerDelegate() + { + String hostName; + try + { + hostName = InetAddress.getLocalHost().getHostName(); + } + catch (UnknownHostException e) + { + hostName = "Unknown host"; + } + id = hostName + "_" + new Date().getTime(); + } + + /** + * Registers the specified listener as a new recipient of + * notifications from the delegate. If non-null, the filter + * argument will be used to select which notifications are + * delivered. The supplied object will also be passed to + * the recipient with each notification. This should not + * be modified by the broadcaster, but instead should be + * passed unmodified to the listener. + * + * @param listener the new listener, who will receive + * notifications from this broadcasting bean. + * @param filter a filter to determine which notifications are + * delivered to the listener, or <code>null</code> + * if no filtering is required. + * @param passback an object to be passed to the listener with + * each notification. + * @throws IllegalArgumentException if <code>listener</code> is + * <code>null</code>. + * @see #removeNotificationListener(NotificationListener) + */ + public void addNotificationListener(NotificationListener listener, + NotificationFilter filter, + Object passback) + throws IllegalArgumentException + { + if (listener == null) + throw new IllegalArgumentException("A null listener was supplied."); + listeners.add(new ListenerData(listener, filter, passback)); + } + + /** + * Returns the name of this Java Management eXtensions (JMX) implementation. + * + * @return the implementation name. + */ + public String getImplementationName() + { + return "GNU JMX"; + } + + /** + * Returns the vendor of this Java Management eXtensions (JMX) implementation. + * + * @return the implementation vendor. + */ + public String getImplementationVendor() + { + return "The GNU Classpath Project"; + } + + /** + * Returns the version of this Java Management eXtensions (JMX) implementation. + * + * @return the implementation version. + */ + public String getImplementationVersion() + { + return SystemProperties.getProperty("gnu.classpath.version"); + } + + /** + * Returns the unique identifier for this management server. + * + * @return the unique id of the server. + */ + public String getMBeanServerId() + { + return id; + } + + /** + * 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() + { + return new MBeanNotificationInfo[] + { + new MBeanNotificationInfo(new String[] + { + MBeanServerNotification.REGISTRATION_NOTIFICATION, + MBeanServerNotification.UNREGISTRATION_NOTIFICATION, + }, + MBeanServerNotification.class.getName(), + "Server registration notifications") + }; + } + + /** + * Returns the name of this Java Management eXtensions (JMX) specification. + * + * @return the specification name. + */ + public String getSpecificationName() + { + return "JMX"; + } + + + /** + * Returns the vendor of this Java Management eXtensions (JMX) specification. + * + * @return the specification vendor. + */ + public String getSpecificationVendor() + { + return "Sun Microsystems"; + } + + /** + * Returns the version of this Java Management eXtensions (JMX) specification. + * + * @return the specification version. + */ + public String getSpecificationVersion() + { + return "1.2"; + } + + /** + * 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 + * {@link #removeNotificationListener(NotificationListener, + * NotificationFilter, java.lang.Object)} + * + * @param listener the listener to remove. + * @throws ListenerNotFoundException if the specified listener + * is not registered with this bean. + * @see #addNotificationListener(NotificationListener, NotificationFilter, + * java.lang.Object) + */ + public void removeNotificationListener(NotificationListener listener) + throws ListenerNotFoundException + { + Iterator<ListenerData> it = listeners.iterator(); + boolean foundOne = false; + while (it.hasNext()) + { + if (it.next().getListener() == listener) + { + it.remove(); + foundOne = true; + } + } + if (!foundOne) + throw new ListenerNotFoundException("The specified listener, " + listener + + "is not registered with this bean."); + } + + /** + * Removes the specified listener from the list of recipients + * of notifications from this delegate. Only the first instance with + * the supplied filter and passback object is removed. + * <code>null</code> is used as a valid value for these parameters, + * rather than as a way to remove all registration instances for + * the specified listener; for this behaviour instead, see + * {@link #removeNotificationListener(NotificationListener)}. + * + * @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) + * @see #removeNotificationListener(NotificationListener) + */ + 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."); + } + } + + /** + * Allows the server to use the delegate to send a notification. + * If the supplied notification has a sequence number <= 0, then + * it is replaced with the delegate's own sequence number. + * + * @param notification the notification to send. + */ + public void sendNotification(Notification notification) + { + if (notification.getSequenceNumber() <= 0) + notification.setSequenceNumber(++seqNo); + for (ListenerData ldata : listeners) + { + NotificationFilter filter = ldata.getFilter(); + if (filter == null || filter.isNotificationEnabled(notification)) + ldata.getListener().handleNotification(notification, ldata.getPassback()); + } + } + +} diff --git a/libjava/classpath/javax/management/MBeanServerDelegateMBean.java b/libjava/classpath/javax/management/MBeanServerDelegateMBean.java new file mode 100644 index 000000000..aa7b27300 --- /dev/null +++ b/libjava/classpath/javax/management/MBeanServerDelegateMBean.java @@ -0,0 +1,101 @@ +/* MBeanServerDelegateMBean.java -- The interface of a management server delegate. + Copyright (C) 2006 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package javax.management; + +/** + * Defines the interface for the delegate bean associated + * with a management server. The delegate bean is responsible + * for providing metadata about the server and handling the + * registration and deregistration notifications. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public interface MBeanServerDelegateMBean +{ + + /** + * Returns the name of this Java Management eXtensions (JMX) implementation. + * + * @return the implementation name. + */ + String getImplementationName(); + + /** + * Returns the vendor of this Java Management eXtensions (JMX) implementation. + * + * @return the implementation vendor. + */ + String getImplementationVendor(); + + /** + * Returns the version of this Java Management eXtensions (JMX) implementation. + * + * @return the implementation version. + */ + String getImplementationVersion(); + + /** + * Returns the unique identifier for this management server. + * + * @return the unique id of the server. + */ + String getMBeanServerId(); + + /** + * Returns the name of this Java Management eXtensions (JMX) specification. + * + * @return the specification name. + */ + String getSpecificationName(); + + /** + * Returns the vendor of this Java Management eXtensions (JMX) specification. + * + * @return the specification vendor. + */ + String getSpecificationVendor(); + + /** + * Returns the version of this Java Management eXtensions (JMX) specification. + * + * @return the specification version. + */ + String getSpecificationVersion(); + +} diff --git a/libjava/classpath/javax/management/MBeanServerFactory.java b/libjava/classpath/javax/management/MBeanServerFactory.java new file mode 100644 index 000000000..f9bd4566f --- /dev/null +++ b/libjava/classpath/javax/management/MBeanServerFactory.java @@ -0,0 +1,413 @@ +/* MBeanServerFactory.java -- Manages server instances. + Copyright (C) 2006 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.classpath.SystemProperties; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +import javax.management.loading.ClassLoaderRepository; + +/** + * <p> + * Creates and maintains a set of {@link MBeanServer} instances. + * Server instances, as of JMX 1.2, are created using a subclass + * of {@link MBeanServerBuilder}. The exact class used is controlled + * by the property <code>javax.management.builder.initial</code>, + * and allows the instances created by {@link MBeanServerBuilder} + * to be wrapped, thus providing additional functionality. + * </p> + * <p> + * The property is used as follows: + * </p> + * <ol> + * <li>If the property has no value, then an instance of + * {@link MBeanServerBuilder} is used.</li> + * <li>If a value is given, then: + * <ol> + * <li>The class is loaded using + * <code>Thread.currentThread().getContextClassLoader()</code>, or, + * if this is <code>null</code>, by <code>Class.forName()</code>.</li> + * <li><code>Class.newInstance()</code> is used to create an instance + * of the class. The class must be public and have a public empty + * constructor. If an exception is thrown, it is propogated as + * a {@link JMRuntimeException} and no new server instances may be + * created until the property is set to a valid value.</li> + * </ol></li> + * <li>The value is checked on each successive request for a server. + * If it differs from the class of the existing instance of + * {@link MBeanServerBuilder}, then the value is used to create + * a new instance.</li> + * </ol> + */ +public class MBeanServerFactory +{ + + /** + * The last builder instance. + */ + private static MBeanServerBuilder builder; + + /** + * The map of registered servers (identifiers to servers). + */ + private static final Map<Object,MBeanServer> servers = + new HashMap<Object,MBeanServer>(); + + /** + * Private constructor to prevent instance creation. + */ + private MBeanServerFactory() {} + + /** + * Returns a server implementation using the default domain name + * of <code>"DefaultDomain"</code>. The default domain name is + * used when the domain name specified by the user is <code>null</code. + * A reference to the created server is retained, so that it can + * be retrieved at a later date using {@link #findMBeanServer}. + * Calling this method is equivalent to calling + * {@link createMBeanServer(String)} with a <code>null</code> value. + * + * @return a new {@link MBeanServer} instance. + * @throws SecurityException if a security manager exists and the + * caller's permissions don't imply {@link + * MBeanServerPermission(String)}("createMBeanServer") + * @throws JMRuntimeException if the property + * <code>javax.management.builder.initial</code> + * exists but names a class which either can not be + * instantiated or provides an implementation that returns + * <code>null</code> from either + * {@link MBeanServerBuilder#newMBeanServerDelegate()} + * or {@link MBeanServerBuilder#newMBeanServer()} + * @throws ClassCastException if the property + * <code>javax.management.builder.initial</code> + * exists but names a class which is not a subclass + * of {@link MBeanServerBuilder}. + * @see #createMBeanServer(String) + */ + public static MBeanServer createMBeanServer() + { + return createMBeanServer(null); + } + + /** + * Returns a server implementation using the default domain name + * given, or <code>"DefaultDomain"</code> if this is <code>null</code>. + * The default domain name is used when the domain name specified by + * the user is <code>null</code. A reference to the created server is + * retained, so that it can be retrieved at a later date using + * {@link #findMBeanServer}. + * + * @param domain the default domain name of the server. + * @return a new {@link MBeanServer} instance. + * @throws SecurityException if a security manager exists and the + * caller's permissions don't imply {@link + * MBeanServerPermission(String)}("createMBeanServer") + * @throws JMRuntimeException if the property + * <code>javax.management.builder.initial</code> + * exists but names a class which either can not be + * instantiated or provides an implementation that returns + * <code>null</code> from either + * {@link MBeanServerBuilder#newMBeanServerDelegate()} + * or {@link MBeanServerBuilder#newMBeanServer()} + * @throws ClassCastException if the property + * <code>javax.management.builder.initial</code> + * exists but names a class which is not a subclass + * of {@link MBeanServerBuilder}. + */ + public static MBeanServer createMBeanServer(String domain) + { + SecurityManager sm = System.getSecurityManager(); + if (sm != null) + sm.checkPermission(new MBeanServerPermission("createMBeanServer")); + MBeanServer server = createServer(domain); + try + { + ObjectName dn = new + ObjectName("JMImplementation:type=MBeanServerDelegate"); + servers.put(server.getAttribute(dn, "MBeanServerId"), server); + } + catch (MalformedObjectNameException e) + { + throw (Error) + (new InternalError("Malformed delegate bean name.").initCause(e)); + } + catch (MBeanException e) + { + throw (Error) + (new InternalError("Exception in getMBeanServerId().").initCause(e)); + } + catch (AttributeNotFoundException e) + { + throw (Error) + (new InternalError("Could not find MBeanServerId attribute.").initCause(e)); + } + catch (InstanceNotFoundException e) + { + throw (Error) + (new InternalError("Could not find the delegate bean.").initCause(e)); + } + catch (ReflectionException e) + { + throw (Error) + (new InternalError("Could not call getMBeanServerId().").initCause(e)); + } + return server; + } + + /** + * Returns the specified server, or, if <code>id</code> is <code>null</code>, + * a list of all registered servers. A registered server is one that + * was created using {@link #createMBeanServer()} or + * {@link #createMBeanServer(String)} and has not yet been released + * using {@link releaseMBeanServer(MBeanServer)}. + * + * @param id the id of the server to retrieve, or <code>null</code> + * to return all servers. + * @return a list of {@link MBeanServer}s. + * @throws SecurityException if a security manager exists and the + * caller's permissions don't imply {@link + * MBeanServerPermission(String)}("findMBeanServer") + */ + public static ArrayList<MBeanServer> findMBeanServer(String id) + { + SecurityManager sm = System.getSecurityManager(); + if (sm != null) + sm.checkPermission(new MBeanServerPermission("findMBeanServer")); + if (id == null) + return new ArrayList<MBeanServer>(servers.values()); + ArrayList<MBeanServer> list = new ArrayList<MBeanServer>(); + MBeanServer server = servers.get(id); + if (server != null) + list.add(servers.get(id)); + return list; + } + + /** + * Returns the class loader repository used by the specified server. + * This is equivalent to calling {@link MBeanServer#getClassLoaderRepository()} + * on the given server. + * + * @param server the server whose class loader repository should be + * retrieved. + * @throws NullPointerException if <code>server</code> is <code>null</code>. + * @throws SecurityException if a security manager exists and the + * caller's permissions don't imply {@link + * MBeanPermission(String,String,ObjectName,String) + * <code>MBeanPermission(null, null, null, + * "getClassLoaderRepository")</code> + */ + public static ClassLoaderRepository getClassLoaderRepository(MBeanServer server) + { + return server.getClassLoaderRepository(); + } + + /** + * Returns a server implementation using the default domain name + * of <code>"DefaultDomain"</code>. The default domain name is + * used when the domain name specified by the user is <code>null</code. + * No reference to the created server is retained, so the server is + * garbage collected when it is no longer used, but it can not be + * retrieved at a later date using {@link #findMBeanServer}. + * Calling this method is equivalent to calling + * {@link newMBeanServer(String)} with a <code>null</code> value. + * + * @return a new {@link MBeanServer} instance. + * @throws SecurityException if a security manager exists and the + * caller's permissions don't imply {@link + * MBeanServerPermission(String)}("newMBeanServer") + * @throws JMRuntimeException if the property + * <code>javax.management.builder.initial</code> + * exists but names a class which either can not be + * instantiated or provides an implementation that returns + * <code>null</code> from either + * {@link MBeanServerBuilder#newMBeanServerDelegate()} + * or {@link MBeanServerBuilder#newMBeanServer()} + * @throws ClassCastException if the property + * <code>javax.management.builder.initial</code> + * exists but names a class which is not a subclass + * of {@link MBeanServerBuilder}. + * @see #newMBeanServer(String) + */ + public static MBeanServer newMBeanServer() + { + return newMBeanServer(null); + } + + /** + * Returns a server implementation using the default domain name + * given, or <code>"DefaultDomain"</code> if this is <code>null</code>. + * The default domain name is used when the domain name specified by + * the user is <code>null</code. No reference to the created server is + * retained, so the server is garbage collected when it is no longer + * used, but it can not be retrieved at a later date using + * {@link #findMBeanServer}. + * + * @param domain the default domain name of the server. + * @return a new {@link MBeanServer} instance. + * @throws SecurityException if a security manager exists and the + * caller's permissions don't imply {@link + * MBeanServerPermission(String)}("newMBeanServer") + * @throws JMRuntimeException if the property + * <code>javax.management.builder.initial</code> + * exists but names a class which either can not be + * instantiated or provides an implementation that returns + * <code>null</code> from either + * {@link MBeanServerBuilder#newMBeanServerDelegate()} + * or {@link MBeanServerBuilder#newMBeanServer()} + * @throws ClassCastException if the property + * <code>javax.management.builder.initial</code> + * exists but names a class which is not a subclass + * of {@link MBeanServerBuilder}. + */ + public static MBeanServer newMBeanServer(String domain) + { + SecurityManager sm = System.getSecurityManager(); + if (sm != null) + sm.checkPermission(new MBeanServerPermission("newMBeanServer")); + return createServer(domain); + } + + /** + * Common method to create a server for the {@link #createMBeanServer(String)} + * and {@link #newMBeanServer(String)} methods above. + * + * @param domain the default domain name of the server. + * @throws JMRuntimeException if the property + * <code>javax.management.builder.initial</code> + * exists but names a class which either can not be + * instantiated or provides an implementation that returns + * <code>null</code> from either + * {@link MBeanServerBuilder#newMBeanServerDelegate()} + * or {@link MBeanServerBuilder#newMBeanServer()} + * @throws ClassCastException if the property + * <code>javax.management.builder.initial</code> + * exists but names a class which is not a subclass + * of {@link MBeanServerBuilder}. + */ + private static MBeanServer createServer(String domain) + { + if (domain == null) + domain = "DefaultDomain"; + String builderClass = + SystemProperties.getProperty("javax.management.builder.initial"); + if (builderClass == null) + { + if (builder == null || + builder.getClass() != MBeanServerBuilder.class) + builder = new MBeanServerBuilder(); + } + else if (!(builder != null && + builderClass.equals(builder.getClass().getName()))) + { + ClassLoader cl = Thread.currentThread().getContextClassLoader(); + if (cl == null) + cl = MBeanServerFactory.class.getClassLoader(); + try + { + Class<?> bClass = Class.forName(builderClass, true, cl); + builder = (MBeanServerBuilder) bClass.newInstance(); + } + catch (ClassNotFoundException e) + { + throw (JMRuntimeException) (new JMRuntimeException("The builder class, " + + builderClass + + ", could not be found.")) + .initCause(e); + } + catch (InstantiationException e) + { + throw (JMRuntimeException) (new JMRuntimeException("The builder class, " + + builderClass + + ", could not be instantiated.")) + .initCause(e); + } + catch (IllegalAccessException e) + { + throw (JMRuntimeException) (new JMRuntimeException("The builder class, " + + builderClass + + ", could not be accessed.")) + .initCause(e); + } + } + MBeanServerDelegate delegate = builder.newMBeanServerDelegate(); + if (delegate == null) + throw new JMRuntimeException("A delegate could not be created."); + MBeanServer server = builder.newMBeanServer(domain, null, delegate); + if (server == null) + throw new JMRuntimeException("A server could not be created."); + return server; + } + + /** + * Removes the reference to the specified server, thus allowing it to + * be garbage collected. + * + * @param server the server to remove. + * @throws IllegalArgumentException if a reference to the server is not + * held (i.e. it wasn't created by + * {@link #createMBeanServer(String)} + * or this method has already been called + * on it. + * @throws SecurityException if a security manager exists and the + * caller's permissions don't imply {@link + * MBeanServerPermission(String)}("releaseMBeanServer") + */ + public static void releaseMBeanServer(MBeanServer server) + { + SecurityManager sm = System.getSecurityManager(); + if (sm != null) + sm.checkPermission(new MBeanServerPermission("releaseMBeanServer")); + Iterator<MBeanServer> i = servers.values().iterator(); + while (i.hasNext()) + { + MBeanServer s = i.next(); + if (server == s) + { + i.remove(); + return; + } + } + throw new IllegalArgumentException("The server given is not referenced."); + } + + +} diff --git a/libjava/classpath/javax/management/MBeanServerInvocationHandler.java b/libjava/classpath/javax/management/MBeanServerInvocationHandler.java new file mode 100644 index 000000000..093e88278 --- /dev/null +++ b/libjava/classpath/javax/management/MBeanServerInvocationHandler.java @@ -0,0 +1,401 @@ +/* MBeanServerInvocationHandler.java -- Provides a proxy for a bean. + Copyright (C) 2007 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package javax.management; + +import gnu.javax.management.Translator; + +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; + +/** + * <p> + * Provides a proxy for a management bean. The methods + * of the given interface are fulfilled by redirecting the + * calls over an {@link MBeanServerConnection} to the bean + * specified by the supplied {@link ObjectName}. + * </p> + * <p> + * The {@link java.lang.reflect.InvocationHandler} also makes + * provision for {@link MXBean}s by providing type conversion + * according to the rules defined for these beans. The input + * parameters are converted to their equivalent open type before + * calling the method, and then the return value is converted + * back from its open type to the appropriate Java type. For + * example, a method that takes an {@link Enum} as input and + * returns a {@link java.util.List} will have the input value + * converted from an {@link Enum} to a {@link String}, while + * the return value will be converted from its return type + * (an appropriately typed array) to a {@link java.util.List}. + * </p> + * <p> + * The proxy has special cases for the {@link Object#equals(Object)}, + * {@link Object#hashCode()} and {@link Object#toString()} methods. + * Unless they are specified explictly by the interface, the + * following behaviour is provided for these methods by the proxy: + * </p> + * <ul> + * <li><code>equals(Object)</code> returns true if the other object + * is an {@link MBeanServerInvocationHandler} with the same + * {@link MBeanServerConnection} and {@link ObjectName}. If an + * interface class was specified on construction for one of the + * proxies, then the same class must have also been specified + * for the other.</li> + * <li><code>hashCode()</code> returns the same value for + * equivalent proxies.</li> + * <li><code>toString()</code> returns a textual representation + * of the proxy.</li> + * </ul> + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public class MBeanServerInvocationHandler + implements InvocationHandler +{ + + /** + * The connection used to make the calls. + */ + private MBeanServerConnection conn; + + /** + * The name of the bean to perform operations on. + */ + private ObjectName name; + + /** + * True if this proxy is for an {@link MXBean}. + */ + private boolean mxBean; + + /** + * The interface class associated with the bean. + */ + private Class<?> iface; + + /** + * Constructs a new {@link MBeanServerInvocationHandler} + * which forwards methods to the supplied bean via the + * given {@link MBeanServerConnection}. This constructor + * is used in preference to + * {@link JMX#newMBeanProxy(MBeanServerConnection, ObjectName, + * Class<T>)} if you wish to make your own call to + * {@link java.lang.reflect.Proxy#newInstance(ClassLoader, + * Class[], java.lang.reflect.InvocationHandler)} with + * a different {@link ClassLoader}. Calling this constructor + * is equivalent to <code>MBeanServerInvocationHandler(conn, + * name, false)</code>. The other constructor should be used + * instead if the bean being proxied is an {@link MXBean}. + * + * @param conn the connection through which methods will + * be forwarded to the bean. + * @param name the name of the bean to use to provide the + * actual calls. + */ + public MBeanServerInvocationHandler(MBeanServerConnection conn, + ObjectName name) + { + this(conn, name, false); + } + + /** + * Constructs a new {@link MBeanServerInvocationHandler} + * which forwards methods to the supplied bean via the + * given {@link MBeanServerConnection}. This constructor + * is used in preference to + * {@link JMX#newMBeanProxy(MBeanServerConnection, ObjectName, + * Class<T>)} if you wish to make your own call to + * {@link java.lang.reflect.Proxy#newInstance(ClassLoader, + * Class[], java.lang.reflect.InvocationHandler)} with + * a different {@link ClassLoader}. + * + * @param conn the connection through which methods will + * be forwarded to the bean. + * @param name the name of the bean to use to provide the + * actual calls. + * @param mxBean true if the bean being proxied is an + * {@link MXBean}. + * @since 1.6 + */ + public MBeanServerInvocationHandler(MBeanServerConnection conn, + ObjectName name, boolean mxBean) + { + this.conn = conn; + this.name = name; + this.mxBean = mxBean; + } + + /** + * Returns the connection through which the calls to the bean + * will be made. + * + * @return the connection being used to forward the calls to + * the bean. + * @since 1.6 + */ + public MBeanServerConnection getMBeanServerConnection() + { + return conn; + } + + /** + * Returns the name of the bean to which method calls are made. + * + * @return the bean which provides the actual method calls. + * @since 1.6 + */ + public ObjectName getObjectName() + { + return name; + } + + /** + * Called by the proxy class whenever a method is called. The method + * is emulated by retrieving an attribute from, setting an attribute on + * or invoking a method on the server connection as required. Translation + * between the Java data types supplied as arguments to the open types used + * by the bean is provided, as well as translation of the return value back + * in to the appropriate Java type if the bean is an {@link MXBean}. + * + * @param proxy the proxy on which the method was called. + * @param method the method which was called. + * @param args the arguments supplied to the method. + * @return the return value from the method. + * @throws Throwable if an exception is thrown in performing the + * method emulation. + */ + public Object invoke(Object proxy, Method method, Object[] args) + throws Throwable + { + String mName = method.getName(); + Class<?> proxyClass = proxy.getClass(); + if (mName.equals("toString")) + { + if (inInterface(mName, proxyClass)) + return conn.invoke(name,mName,null,null); + else + return proxyClass.getName() + "[name=" + name + + ", conn=" + conn + "]"; + } + if (mName.equals("hashCode")) + { + if (inInterface(mName, proxyClass)) + return conn.invoke(name,mName,null,null); + else + return conn.hashCode() + name.hashCode() + + (iface == null ? 0 : iface.hashCode()); + } + if (mName.equals("equals")) + { + if (inInterface(mName, proxyClass, Object.class)) + return conn.invoke(name,mName,new Object[]{args[0]}, + new String[]{"java.lang.Object"}); + else + { + if (args[0].getClass() != proxy.getClass()) + return false; + InvocationHandler ih = Proxy.getInvocationHandler(args[0]); + if (ih instanceof MBeanServerInvocationHandler) + { + MBeanServerInvocationHandler h = + (MBeanServerInvocationHandler) ih; + return conn.equals(h.getMBeanServerConnection()) + && name.equals(h.getObjectName()) + && (iface == null ? h.iface == null + : iface.equals(h.iface)); + } + return false; + } + } + if (NotificationEmitter.class.isAssignableFrom(proxyClass)) + { + if (mName.equals("addNotificationListener")) + { + conn.addNotificationListener(name, + (NotificationListener) args[0], + (NotificationFilter) args[1], + args[2]); + return null; + } + if (mName.equals("getNotificationInfo")) + return conn.getMBeanInfo(name).getNotifications(); + if (mName.equals("removeNotificationListener")) + { + if (args.length == 1) + conn.removeNotificationListener(name, + (NotificationListener) + args[0]); + else + conn.removeNotificationListener(name, + (NotificationListener) + args[0], + (NotificationFilter) + args[1], args[2]); + return null; + } + } + String[] sigs; + if (args == null) + sigs = null; + else + { + sigs = new String[args.length]; + for (int a = 0; a < args.length; ++a) + sigs[a] = args[a].getClass().getName(); + } + String attrib = null; + if (mName.startsWith("get")) + attrib = mName.substring(3); + else if (mName.startsWith("is")) + attrib = mName.substring(2); + if (attrib != null) + { + Object val = conn.getAttribute(name, attrib); + if (mxBean) + return Translator.toJava(val, method); + else + return val; + } + else if (mName.startsWith("set")) + { + Object arg; + if (mxBean) + arg = Translator.fromJava(args, method)[0]; + else + arg = args[0]; + conn.setAttribute(name, new Attribute(mName.substring(3), arg)); + return null; + } + if (mxBean) + return Translator.toJava(conn.invoke(name, mName, + Translator.fromJava(args,method), + sigs), method); + else + return conn.invoke(name, mName, args, sigs); + } + + /** + * Returns true if this is a proxy for an {@link MXBean} + * and conversions must be applied to input parameters + * and return types, according to the rules for such beans. + * + * @return true if this is a proxy for an {@link MXBean}. + * @since 1.6 + */ + public boolean isMXBean() + { + return mxBean; + } + + /** + * <p> + * Returns a proxy for the specified bean. A proxy object is created + * using <code>Proxy.newProxyInstance(iface.getClassLoader(), + * new Class[] { iface }, handler)</code>. The + * {@link javax.management.NotificationEmitter} class is included as the + * second element of the array if <code>broadcaster</code> is true. + * <code>handler</code> refers to the invocation handler which forwards + * calls to the connection, which is created by a call to + * <code>new MBeanServerInvocationHandler(conn, name)</code>. + * </p> + * <p> + * <strong>Note</strong>: use of the proxy may result in + * {@link java.io.IOException}s from the underlying + * {@link MBeanServerConnection}. + * As of 1.6, the use of {@link JMX#newMBeanProxy(MBeanServerConnection, + * ObjectName,Class)} and {@link JMX#newMBeanProxy(MBeanServerConnection, + * ObjectName,Class,boolean)} is preferred. + * </p> + * + * @param conn the server connection to use to access the bean. + * @param name the {@link javax.management.ObjectName} of the + * bean to provide a proxy for. + * @param iface the interface for the bean being proxied. + * @param broadcaster true if the proxy should implement + * {@link NotificationEmitter}. + * @return a proxy for the specified bean. + * @see JMX#newMBeanProxy(MBeanServerConnection,ObjectName,Class) + */ + // Suppress warnings as we know an instance of T will be returned. + @SuppressWarnings("unchecked") + public static <T> T newProxyInstance(MBeanServerConnection conn, + ObjectName name, Class<T> iface, + boolean broadcaster) + { + if (broadcaster) + return (T) Proxy.newProxyInstance(iface.getClassLoader(), + new Class[] { iface, + NotificationEmitter.class }, + new MBeanServerInvocationHandler(conn,name)); + else + return (T) Proxy.newProxyInstance(iface.getClassLoader(), + new Class[] { iface }, + new MBeanServerInvocationHandler(conn,name)); + } + + /** + * Returns true if the specified method is specified + * by one of the proxy's interfaces. + * + * @param name the name of the method to search for. + * @param proxyClass the class of the proxy. + * @param args the arguments to the method. + * @return true if one of the interfaces specifies the + * given method. + */ + private boolean inInterface(String name, Class<?> proxyClass, + Class<?>... args) + { + for (Class<?> iface : proxyClass.getInterfaces()) + { + try + { + iface.getMethod(name, args); + return true; + } + catch (NoSuchMethodException e) + { + /* Ignored; this interface doesn't specify + the method. */ + } + } + return false; + } + +} diff --git a/libjava/classpath/javax/management/MBeanServerNotification.java b/libjava/classpath/javax/management/MBeanServerNotification.java new file mode 100644 index 000000000..e225a2939 --- /dev/null +++ b/libjava/classpath/javax/management/MBeanServerNotification.java @@ -0,0 +1,103 @@ +/* MBeanServerNotification.java -- The registration notification. + Copyright (C) 2006 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; + +/** + * The notification emitted by a management server on a registration + * or de-registration event. Events are emitted via the delegate + * management bean of the server. Other objects can listen for + * such events by registering their interest with the delegate + * bean. The bean can be obtained via the {@link ObjectName} + * <code>JMImplementation:type=MBeanServerDelegate</code>. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public class MBeanServerNotification + extends Notification +{ + + /** + * Compatible with JDK 1.5 + */ + private static final long serialVersionUID = 2876477500475969677L; + + /** + * Notification type for the registration event. + */ + public static final String REGISTRATION_NOTIFICATION = "JMX.mbean.registered"; + + /** + * Notification type for the de-registration event. + */ + public static final String UNREGISTRATION_NOTIFICATION = "JMX.mbean.unregistered"; + + /** + * The name of the bean which forms the subject of this notification. + */ + private ObjectName objectName; + + /** + * Constructs a new {@link MBeanServerNotification} of the specified + * type for an event relating to the supplied bean, with the given + * source and sequence number. + * + * @param type the type of notification (registration or de-registration). + * @param source the source of the notification. + * @param seqNo the sequence number of this notification, used to order + * multiple such notifications. + * @param name the name of the bean concerned by this event. + */ + public MBeanServerNotification(String type, Object source, long seqNo, + ObjectName name) + { + super(type, source, seqNo); + objectName = name; + } + + /** + * Returns the name of the bean this notification concerns. + * + * @return the name of the bean. + */ + public ObjectName getMBeanName() + { + return objectName; + } + +} diff --git a/libjava/classpath/javax/management/MBeanServerPermission.java b/libjava/classpath/javax/management/MBeanServerPermission.java new file mode 100644 index 000000000..fea4ea210 --- /dev/null +++ b/libjava/classpath/javax/management/MBeanServerPermission.java @@ -0,0 +1,470 @@ +/* MBeanServerPermission.java -- Permissions controlling server creation. + Copyright (C) 2006 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.security.BasicPermission; +import java.security.Permission; +import java.security.PermissionCollection; + +import java.util.Enumeration; +import java.util.NoSuchElementException; + +/** + * <p> + * Represents the permissions required to perform + * operations provided by the {@link MBeanServerFactory}. + * As with all {@link java.security.Permission} objects, an + * instance of this class either represents a permission + * already held or one that is required to access a + * particular service. In the case of {@link MBeanServerPermission}s, + * implication checks are made using an instance of this class + * when a user requests an operation from the factory, and a + * {@link SecurityManager} is in place. + * </p> + * <p> + * The permission is defined by its name, which may be + * either a <code>'*'</code> (to allow all) or one or + * more of the following, separated by a <code>','</code>: + * </p> + * <ul> + * <li><code>createMBeanServer</code> -- allows a registered + * instance of a server to be obtained from the factory.</li> + * <li><code>findMBeanServer</code> -- allows all or one + * particular server instance to be retrieved from the factory.</li> + * <li><code>newMBeanServer</code> -- allows an unregistered + * instance of a server to be obtained from the factory.</li> + * <li><code>releaseMBeanServer</code> -- allows a reference to + * a server instance to be removed from the factory.</li> + * </ul> + * <p> + * The names may be surrounded by arbitrary amounts of whitespace. + * <code>createMBeanServer</code> implies <code>newMBeanServer</code>. + * </p> + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public class MBeanServerPermission + extends BasicPermission +{ + + /** + * Compatible with JDK 1.5 + */ + private static final long serialVersionUID = -5661980843569388590L; + + /** + * <p> + * Constructs a new {@link MBeanServerPermission} with + * the given name. The name must not be <code>null</code> + * and must be equal to either <code>"*"</code> or a + * comma-separated list of valid permissions. The four + * valid constraints are: + * </p> + * <ol> + * <li><code>createMBeanServer</code></li> + * <li><code>findMBeanServer</code></li> + * <li><code>newMBeanServer</code></li> + * <li><code>releaseMBeanServer</code></li> + * </ol> + * <p> + * Calling this constructor is equivalent to calling + * <code>MBeanPermission(name, null)</code>. + * </p> + * + * @param name the name of this permission. + * @throws NullPointerException if <code>name</code> + * is <code>null</code>. + * @throws IllegalArgumentException if <code>name</code> + * is not either equal to + * <code>"*"</code> or forms + * a comma-separated list of + * valid constraints. + * @see #MBeanServerPermission(String,String) + */ + public MBeanServerPermission(String name) + { + this(name, null); + } + + /** + * <p> + * Constructs a new {@link MBeanServerPermission} with + * the given name and actions. The actions are unused, + * and must be either <code>null</code> or the empty + * string. The name must not be <code>null</code> + * and must be equal to either <code>"*"</code> or a + * comma-separated list of valid permissions. The four + * valid constraints are: + * </p> + * <ol> + * <li><code>createMBeanServer</code></li> + * <li><code>findMBeanServer</code></li> + * <li><code>newMBeanServer</code></li> + * <li><code>releaseMBeanServer</code></li> + * </ol> + * <p> + * Calling this constructor is equivalent to calling + * <code>MBeanPermission(name, null)</code>. + * </p> + * + * @param name the name of this permission. + * @throws NullPointerException if <code>name</code> + * is <code>null</code>. + * @throws IllegalArgumentException if <code>name</code> + * is not either equal to + * <code>"*"</code> or forms + * a comma-separated list of + * valid constraints, or if + * <code>actions</code> is not + * <code>null</code> or the + * empty string. + * @see #MBeanServerPermission(String,String) + */ + public MBeanServerPermission(String name, String actions) + { + super(checkName(name), actions); + if (actions != null && actions.length() > 0) + throw new IllegalArgumentException("The supplied action list " + + "was not equal to null or the " + + "empty string."); + } + + /** + * Returns true if the given object is also an {@link MBeanServerPermission} + * with the same name. + * + * @param obj the object to compare with this one. + * @return true if the object is an {@link MBeanPermission} + * with the same name. + */ + public boolean equals(Object obj) + { + if (obj instanceof MBeanServerPermission) + { + MBeanServerPermission o = (MBeanServerPermission) obj; + return o.getName().equals(getName()); + } + return false; + } + + /** + * Returns a unique hash code for this permission. + * This is simply the hashcode of {@link BasicPermission#getName()}. + * + * @return the hashcode of this permission. + */ + public int hashCode() + { + return getName().hashCode(); + } + + /** + * Returns true if this {@link MBeanServerPermission} implies + * the given permission. This occurs if the given permission + * is also an {@link MBeanServerPermission} and its target names + * are a subset of the target names of this permission. Note that + * the name <code>createMBeanServer</code> implies + * <code>newMBeanServer</code>. + * + * @param p the permission to check for implication. + * @return true if this permission implies <code>p</code>. + */ + public boolean implies(Permission p) + { + if (p instanceof MBeanServerPermission) + { + if (getName().equals("*")) + return true; + MBeanServerPermission msp = (MBeanServerPermission) p; + String[] thisCaps = getName().split(","); + String[] mspCaps = msp.getName().split(","); + for (int a = 0; a < mspCaps.length; ++a) + { + boolean found = false; + String mc = mspCaps[a].trim(); + for (int b = 0; b < thisCaps.length; ++b) + { + String tc = thisCaps[b].trim(); + if (tc.equals(mc)) + found = true; + if (tc.equals("createMBeanServer") && + mc.equals("newMBeanServer")) + found = true; + } + if (!found) + return false; + } + return true; + } + return false; + } + + /** + * Returns a {@link PermissionCollection} which stores + * a series of {@link MBeanServerPermission}s as the union + * of their capabilities. + * + * @return a collection for {@link MBeanServerPermission}s. + */ + public PermissionCollection newPermissionCollection() + { + return new MBeanServerPermissionCollection(); + } + + /** + * A collection of {@link MBeanServerPermission}s, stored + * as a single permission with the union of the capabilities + * as its capabilities. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ + private class MBeanServerPermissionCollection + extends PermissionCollection + { + + /** + * Compatible with JDK 1.5 + */ + private static final long serialVersionUID = -5661980843569388590L; + + /** + * The collected permission. This is <code>null</code> or + * the union of the permissions held by all the collected + * permissions. + */ + private MBeanServerPermission collectionPermission; + + /** + * Adds a new permission by unifying it with the existing + * collection permission. + * + * @param p the permission to add. + * @throws SecurityException if the collection is read only. + * @see #isReadOnly() + * @see #setReadOnly(boolean) + */ + @Override + public void add(Permission p) + { + if (isReadOnly()) + throw new SecurityException("This collection is read only."); + if (p instanceof MBeanServerPermission) + { + MBeanServerPermission msp = (MBeanServerPermission) p; + if (collectionPermission == null) + collectionPermission = msp; + else + { + String finalString = collectionPermission.getName(); + String[] cp = finalString.split(","); + String[] np = msp.getName().split(","); + int createms = finalString.indexOf("createMBeanServer"); + int newms = finalString.indexOf("newMBeanServer"); + for (int a = 0; a < np.length; ++a) + { + boolean found = false; + String nps = np[a].trim(); + for (int b = 0; b < cp.length; ++b) + { + String cps = cp[b].trim(); + if (cps.equals(nps)) + found = true; + if (nps.equals("newMBeanServer") + && createms != -1) + found = true; + if (nps.equals("createMBeanServer") + && newms != -1) + finalString = + finalString.replace("newMBeanServer", + "createMBeanServer"); + } + if (!found) + finalString += "," + nps; + } + collectionPermission = + new MBeanServerPermission(finalString); + } + } + } + + /** + * Returns an enumeration over the single permission. + * + * @return an enumeration over the collection permission. + */ + @Override + public Enumeration<Permission> elements() + { + return new + MBeanServerPermissionEnumeration(collectionPermission); + } + + /** + * Provides an enumeration over a comma-separated list + * of capabilities. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ + private class MBeanServerPermissionEnumeration + implements Enumeration<Permission> + { + + /** + * The collected permission. + */ + private MBeanServerPermission p; + + /** + * True if we have returned the permission. + */ + private boolean done; + + /** + * Constructs a new {@link MBeanServerPermissionEnumeration} + * using the given collected permission. + * + * @param p the collected permission. + */ + public MBeanServerPermissionEnumeration(MBeanServerPermission p) + { + this.p = p; + done = false; + } + + /** + * Returns true if there are more capabilities to return. + * + * @return true if there are more capabilities available. + */ + public boolean hasMoreElements() + { + return !done; + } + + /** + * Returns the next capability. + * + * @return the next capability. + */ + public Permission nextElement() + { + if (hasMoreElements()) + { + done = true; + return p; + } + else + throw new NoSuchElementException("No more elements are available."); + } + + } + + /** + * Returns true if the collected {@link MBeanServerPermission} + * implies the given permission. This occurs if the given permission + * is also an {@link MBeanServerPermission} and its target names + * are a subset of the target names of this permission. Note that + * the name <code>createMBeanServer</code> implies + * <code>newMBeanServer</code>. + * + * @param p the permission to check for implication. + * @return true if this permission implies <code>p</code>. + */ + @Override + public boolean implies(Permission p) + { + return collectionPermission.implies(p); + } + } + + /** + * Checks the name is valid, including removing + * the <code>newMBeanServer</code> permission when + * <code>createMBeanServer</code> is present. + * + * @param name the name to check. + * @throws NullPointerException if <code>name</code> + * is <code>null</code>. + * @throws IllegalArgumentException if <code>name</code> + * is not either equal to + * <code>"*"</code> or forms + * a comma-separated list of + * valid constraints. + */ + private static String checkName(String name) + { + if (!(name.equals("*"))) + { + String[] constraints = name.split(","); + name = ""; + boolean seenCreate = false; + boolean seenNew = false; + boolean start = true; + for (int a = 0; a < constraints.length; ++a) + { + String next = constraints[a].trim(); + if (!(next.equals("createMBeanServer") || + next.equals("findMBeanServer") || + next.equals("newMBeanServer") || + next.equals("releaseMBeanServer"))) + throw new IllegalArgumentException("An invalid constraint, " + + next + ", was specified."); + if (next.equals("newMBeanServer")) + seenNew = true; + else if (next.equals("createMBeanServer")) + seenCreate = true; + else + { + if (!start) + name += ","; + name += next; + start = false; + } + } + if (seenNew && !seenCreate) + name += (start ? "" : ",") + "newMBeanServer"; + else if (seenCreate) + name += (start ? "" : ",") + "createMBeanServer"; + } + return name; + } + +} diff --git a/libjava/classpath/javax/management/MBeanTrustPermission.java b/libjava/classpath/javax/management/MBeanTrustPermission.java new file mode 100644 index 000000000..371e1295e --- /dev/null +++ b/libjava/classpath/javax/management/MBeanTrustPermission.java @@ -0,0 +1,105 @@ +/* MBeanTrustPermission.java -- Represents a trusted bean source. + Copyright (C) 2006 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.security.BasicPermission; + +/** + * Represents the permission held by a trusted source of + * management beans. For a bean to be added to a management + * server, the source of that bean must hold this permission. + * It has a target, but no actions. Valid values for the target + * are <code>"register"</code> and <code>"*"</code>, the latter + * representing both the existing <code>"register"</code> target + * and any future targets. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public class MBeanTrustPermission + extends BasicPermission +{ + + /** + * Compatible with JDK 1.5 + */ + private static final long serialVersionUID = -2952178077029018140L; + + /** + * Constructs a {@link MBeanTrustPermission} with the given target. + * The target must be either <code>"register"</code> or <code>"*"</code>. + * The actions of the permission default to <code>null</code>, + * so this is equivalent to calling + * <code>MBeanTrustPermission(target, null)</code>. + * + * @param target the target of this permission. + * @throws NullPointerException if <code>target</code> is null. + * @throws IllegalArgumentException if the target is other than + * <code>"register"</code> or <code>"*"</code>. + * @see #MBeanTrustPermission(String, String) + */ + public MBeanTrustPermission(String target) + { + this(target, null); + } + + /** + * Constructs a {@link MBeanTrustPermission} with the given target + * and actions. The target must be either <code>"register"</code> + * or <code>"*"</code>. The actions must be either <code>null</code> + * or the empty string, <code>""</code>. + * + * @param target the target of this permission. + * @param actions the actions for this permission. + * @throws NullPointerException if <code>target</code> is null. + * @throws IllegalArgumentException if the target is other than + * <code>"register"</code> or <code>"*"</code> + * or actions is other than + * <code>null</code> or <code>""</code>. + */ + public MBeanTrustPermission(String target, String actions) + { + super(target, actions); + if ((!(target.equals("register"))) && + (!(target.equals("*")))) + throw new IllegalArgumentException("The target must be 'register' or '*'"); + if (actions != null && !(actions.length() == 0)) + throw new IllegalArgumentException("The actions must be null or ''"); + } + +} diff --git a/libjava/classpath/javax/management/MXBean.java b/libjava/classpath/javax/management/MXBean.java new file mode 100644 index 000000000..7b3af541c --- /dev/null +++ b/libjava/classpath/javax/management/MXBean.java @@ -0,0 +1,82 @@ +/* MXBean.java - Marks a management bean interface as an MXBean. + Copyright (C) 2007 Free Software Foundation + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package javax.management; + +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import static java.lang.annotation.RetentionPolicy.RUNTIME; +import static java.lang.annotation.ElementType.TYPE; + +/** + * <p> + * An annotation used to explictly mark an interface + * as defining (or not defining) an {@link MXBean}. By + * default, such beans are taken to be those whose interface + * has the suffix {@code "MXBean"}. The presence of this + * annotation overrides this intuition. The following + * interfaces would be classed as {@link MXBean}s: + * </p> + * <ul> + * <li>{@code public interface SomethingMXBean{}}</li> + * <li>{@code @MXBean public interface Someat{}}</li> + * <li>{@code @MXBean(true) public interface SomeatElse{}}</li> + * </ul> + * <p>The following would not:</p> + * <ul> + * <li>{@code public interface RandomInterface{}}</li> + * <li>{@code @MXBean(false) public interface SomethingMXBean{}}</li> + * </ul> + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.6 + */ +@Documented @Retention(RUNTIME) @Target(TYPE) +public @interface MXBean +{ + + /** + * Returns true if the annotated interface + * is an {@link MXBean}. + * + * @return true if the interface is an {@link MXBean}. + */ + boolean value(); + +} diff --git a/libjava/classpath/javax/management/MalformedObjectNameException.java b/libjava/classpath/javax/management/MalformedObjectNameException.java new file mode 100644 index 000000000..9a9899193 --- /dev/null +++ b/libjava/classpath/javax/management/MalformedObjectNameException.java @@ -0,0 +1,75 @@ +/* MalformedObjectNameException.java -- Thrown by invalid values. + Copyright (C) 2006 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; + +/** + * Thrown when a string used as an {@link ObjectName} + * is invalid. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public class MalformedObjectNameException + extends OperationsException +{ + + /** + * Compatible with JDK 1.5 + */ + private static final long serialVersionUID = -572689714442915824L; + + /** + * Constructs a new <code>MalformedObjectNameException</code>. + */ + public MalformedObjectNameException() + { + super(); + } + + /** + * Constructs a new <code>MalformedObjectNameException</code> + * with the specified message. + * + * @param message the error message to give to the user. + */ + public MalformedObjectNameException(String message) + { + super(message); + } + +} diff --git a/libjava/classpath/javax/management/NotCompliantMBeanException.java b/libjava/classpath/javax/management/NotCompliantMBeanException.java new file mode 100644 index 000000000..a8fa7a852 --- /dev/null +++ b/libjava/classpath/javax/management/NotCompliantMBeanException.java @@ -0,0 +1,77 @@ +/* NotCompliantMBeanException.java -- Thrown due to a non-compliant bean. + Copyright (C) 2006 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; + +/** + * Thrown when a management bean is passed to a method + * (e.g. to an MBean server to be registered) and it + * fails to comply with the specifications for such + * a bean. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public class NotCompliantMBeanException + extends OperationsException +{ + + /** + * Compatible with JDK 1.5 + */ + private static final long serialVersionUID = 5175579583207963577L; + + /** + * Constructs a new <code>NotCompliantMBeanException</code>. + */ + public NotCompliantMBeanException() + { + super(); + } + + /** + * Constructs a new <code>NotCompliantMBeanException</code> + * with the specified message. + * + * @param message the error message to give to the user. + */ + public NotCompliantMBeanException(String message) + { + super(message); + } + +} diff --git a/libjava/classpath/javax/management/Notification.java b/libjava/classpath/javax/management/Notification.java new file mode 100644 index 000000000..0831c297c --- /dev/null +++ b/libjava/classpath/javax/management/Notification.java @@ -0,0 +1,334 @@ +/* Notification.java -- A notification emitted by a bean. + Copyright (C) 2006 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.IOException; +import java.io.ObjectOutputStream; + +import java.util.Date; +import java.util.EventObject; + +/** + * <p> + * A notification message that may be emitted by a bean. + * Notifications have both a message and a type, so individual + * notifications can be grouped by type. They also incorporate + * sequencing, so that the recipient can order the delivered + * messages correctly (there is no guarantee that they will + * be delivered in order). + * </p> + * <p> + * Notifications also include a reference to the source of + * the notification. The source bean is represented either + * by an {@link ObjectName} or by a direct reference to the + * bean. The former is preferable, and notifications emitted + * via a {@link MBeanServer} will automatically have the source + * transformed into an {@link ObjectName}. + * </p> + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public class Notification + extends EventObject +{ + + /** + * Compatible with JDK 1.6 + */ + private static final long serialVersionUID = -7516092053498031989L; + + /** + * The notification message. + * + * @serial the notification message. + */ + private String message; + + /** + * The notification's sequence number, relative to the notifications + * emitted by the bean. + * + * @serial the notification sequence number. + */ + private long sequenceNumber; + + /** + * The source of the notification. This is redeclared in order to + * replace the <code>source</code> variable in {@link java.util.EventObject} + * with a non-transient version. + * + * @serial the notification source. + */ + protected Object source; + + /** + * The time the notification was generated. + * + * @serial the notification timestamp. + */ + private long timeStamp; + + /** + * The type of notification sent. This utilises the same style + * as Java property and package names. For example, + * <code>gnu.gcj.compiler</code> may be one type of notifications. + * + * @serial the notification type. + */ + private String type; + + /** + * The user data associated with the notification. This includes + * any additional data which should be transmitted with the notification, + * but can't be achieved using the {@link java.lang.String} format + * of the <code>message</code>. + * + * @serial the notification user data. + */ + private Object userData; + + /** + * Creates a new {@link Notification} object with the specified type, + * source and sequence number. The timestamp is created using the + * current date and time. + * + * @param type the type of the notification. + * @param source the source of the notification. + * @param sequenceNumber the sequence number of the notifcation. + */ + public Notification(String type, Object source, long sequenceNumber) + { + this(type, source, sequenceNumber, new Date().getTime()); + } + + /** + * Creates a new {@link Notification} object with the specified type, + * source, sequence number and timestamp. + * + * @param type the type of the notification. + * @param source the source of the notification. + * @param sequenceNumber the sequence number of the notifcation. + * @param timeStamp the time the notification was emitted. + */ + public Notification(String type, Object source, long sequenceNumber, + long timeStamp) + { + this(type, source, sequenceNumber, timeStamp, ""); + } + + /** + * Creates a new {@link Notification} object with the specified type, + * source, sequence number, timestamp and message. + * + * @param type the type of the notification. + * @param source the source of the notification. + * @param sequenceNumber the sequence number of the notifcation. + * @param timeStamp the time the notification was emitted. + * @param message the message contained in the notification. + */ + public Notification(String type, Object source, long sequenceNumber, + long timeStamp, String message) + { + super(source); + this.type = type; + this.source = source; + this.sequenceNumber = sequenceNumber; + this.timeStamp = timeStamp; + this.message = message; + } + + /** + * Creates a new {@link Notification} object with the specified type, + * source, sequence number and message. The timestamp is created using + * the current date and time. + * + * @param type the type of the notification. + * @param source the source of the notification. + * @param sequenceNumber the sequence number of the notifcation. + * @param message the message contained in the notification. + */ + public Notification(String type, Object source, long sequenceNumber, + String message) + { + this(type, source, sequenceNumber, new Date().getTime(), message); + } + + /** + * Returns the message contained in this notification. The message + * is in {@link java.lang.String} form, and is thus intended for + * display to the end-user. Data transferred as part of the notification + * which shouldn't be displayed is included in the <code>userData</code> + * field. + * + * @return the notification message. + * @see #getUserData() + * @see #setUserData(java.lang.Object) + */ + public String getMessage() + { + return message; + } + + /** + * Returns the sequence number of this notification. This + * can be used to determine the order in which notifications + * were emitted by the broadcasting bean. + * + * @return the sequence number. + * @see #setSequenceNumber(long) + */ + public long getSequenceNumber() + { + return sequenceNumber; + } + + /** + * Returns the date and time at which this notification was + * emitted. + * + * @return the notification timestamp. + * @see #setTimeStamp(long) + */ + public long getTimeStamp() + { + return timeStamp; + } + + /** + * Returns the type of this notification. Types take the same + * form as Java package and property names. + * + * @return the type of the notification. + */ + public String getType() + { + return type; + } + + /** + * Returns the additional user data associated with the notification. + * This is used to attach additional non-textual information to the + * notification. + * + * @return the user data associated with the notification. + * @see #setUserData(java.lang.Object) + */ + public Object getUserData() + { + return userData; + } + + /** + * Sets the sequence number to the value specified. + * + * @param sequenceNumber the new sequence number. + * @see #getSequenceNumber() + */ + public void setSequenceNumber(long sequenceNumber) + { + this.sequenceNumber = sequenceNumber; + } + + /** + * Sets the source of this notification to the value + * specified. + * + * @param source the new source of the notification. + * @see java.util.EventSource#getSource() + */ + public void setSource(Object source) + { + this.source = source; + } + + /** + * Sets the date and time at which this notification + * was emitted. + * + * @param timeStamp the new time stamp of the notification. + * @see #getTimeStamp() + */ + public void setTimeStamp(long timeStamp) + { + this.timeStamp = timeStamp; + } + + /** + * Sets the additional user data associated with the notification + * to the specified value. This is used to attach additional + * non-textual information to the notification. + * + * @param userData the new user data associated with the notification. + * @see #getUserData() + */ + public void setUserData(Object userData) + { + this.userData = userData; + } + + /** + * A textual representation of the notification. + * + * @return the notification in {@link java.lang.String} form. + */ + public String toString() + { + return getClass().getName() + + "[message=" + message + + ", sequenceNumber=" + sequenceNumber + + ", source=" + source + + ", timeStamp=" + timeStamp + + ", type=" + type + + ", userData=" + userData + + "]"; + } + + /** + * 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/NotificationBroadcaster.java b/libjava/classpath/javax/management/NotificationBroadcaster.java new file mode 100644 index 000000000..2196e980f --- /dev/null +++ b/libjava/classpath/javax/management/NotificationBroadcaster.java @@ -0,0 +1,111 @@ +/* NotificationBroadcaster.java -- Interface for broadcasters. + Copyright (C) 2006 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; + +/** + * <p> + * Represents a bean that can emit notifications when + * events occur. Other beans can use this interface + * to add themselves to the list of recipients of such + * notifications. + * </p> + * <p> + * <strong>Note</strong>: New classes should use + * {@link NotificationEmitter}, a subinterface of this, + * in preference to using this interface directly. + * </p> + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public interface NotificationBroadcaster +{ + + /** + * Registers the specified listener as a new recipient of + * notifications from this bean. If non-null, the filter + * argument will be used to select which notifications are + * delivered. The supplied object will also be passed to + * the recipient with each notification. This should not + * be modified by the broadcaster, but instead should be + * passed unmodified to the listener. + * + * @param listener the new listener, who will receive + * notifications from this broadcasting bean. + * @param filter a filter to determine which notifications are + * delivered to the listener, or <code>null</code> + * if no filtering is required. + * @param passback an object to be passed to the listener with + * each notification. + * @throws IllegalArgumentException if <code>listener</code> is + * <code>null</code>. + * @see #removeNotificationListener(NotificationListener) + */ + void addNotificationListener(NotificationListener listener, + NotificationFilter filter, + Object passback) + throws IllegalArgumentException; + + /** + * 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. + */ + MBeanNotificationInfo[] getNotificationInfo(); + + /** + * 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) + */ + void removeNotificationListener(NotificationListener listener) + throws ListenerNotFoundException; + +} diff --git a/libjava/classpath/javax/management/NotificationBroadcasterSupport.java b/libjava/classpath/javax/management/NotificationBroadcasterSupport.java new file mode 100644 index 000000000..28b8148c1 --- /dev/null +++ b/libjava/classpath/javax/management/NotificationBroadcasterSupport.java @@ -0,0 +1,389 @@ +/* NotificationBroadcasterSupport.java -- Supporting implementation. + Copyright (C) 2007 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package javax.management; + +import gnu.javax.management.ListenerData; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import java.util.concurrent.Executor; + +/** + * <p> + * Provides an implementation of the {@link NotificationEmitter} + * interface, which beans may utilise by extension. By default, + * a synchronous dispatch system is provided, whereby the + * {@link #handleNotification(NotificationListener, Notification, + * Object)} is called once per listener by + * {*@link #sendNotification(Notification)} before returning. + * Thus, unless the listener is remote, it will have received + * the notification before the method returns. + * This may be changed by overriding the <code>handleNotification</code> + * method, or by providing an {@link java.util.concurrent.Executor} to + * use. With the latter, the dispatch of a notification to a particular + * listener will form one task performed by the executor. + * </p> + * <p> + * Any exceptions thrown by the dispatch process will be caught, allowing + * other listeners to still receive the notification. However, any + * {@link Error}s that are thrown will be propogated to the caller of + * {@link #sendNotification(Notification)}. + * </p> + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public class NotificationBroadcasterSupport + implements NotificationEmitter +{ + + /** + * The executor for dispatch, or + * <code>null</code> if this thread should + * handle dispatch itself. + */ + private Executor executor; + + /** + * An array containing information on each + * notification, or <code>null</code> if an + * empty array should be returned by + * {@link #getNotificationInfo()}. + */ + private MBeanNotificationInfo[] info; + + /** + * The list of listeners registered with + * this broadcaster. + */ + private final List<ListenerData> listeners = + new ArrayList<ListenerData>(); + + /** + * Constructs a {@link NotificationBroadcasterSupport} using + * the default synchronous dispatch model, where a single + * thread sends the notification to all listeners. This + * is equivalent to calling + * <code>NotificationBroadcasterSupport(null, null)</code>. + */ + public NotificationBroadcasterSupport() + { + this(null, (MBeanNotificationInfo[]) null); + } + + /** + * Constructs a {@link NotificationBroadcasterSupport} where + * the specified (@link java.util.concurrent.Executor} is used + * to perform each invocation of the + * {@link #handleNotification(NotificationListener, Notification, + * Object)} method. Filtering is performed beforehand, by this + * thread; only calls which have successfully passed through the + * filter are sent to the executor. This is equivalent to calling + * <code>NotificationBroadcasterSupport(executor, null)</code>. + * + * @param executor the executor to use for each call to + * <code>handleNotification()</code>. + * @since 1.6 + */ + public NotificationBroadcasterSupport(Executor executor) + { + this(executor, (MBeanNotificationInfo) null); + } + + /** + * Constructs a {@link NotificationBroadcasterSupport} using + * the default synchronous dispatch model, where a single + * thread sends the notification to all listeners. The specified + * {@link MBeanNotificationInfo} array is used to provide + * information about the notifications on calls to + * {@link #getNotificationInfo()}, where a clone will be + * returned if the array is non-empty. This is equivalent to + * calling <code>NotificationBroadcasterSupport(null, info)</code>. + * + * @param info an array of {@link MBeanNotificationInfo} objects + * describing the notifications delivered by this + * broadcaster. This may be <code>null</code>, which + * is taken as being equivalent to an empty array. + */ + public NotificationBroadcasterSupport(MBeanNotificationInfo... info) + { + this(null, info); + } + + /** + * Constructs a {@link NotificationBroadcasterSupport} where + * the specified (@link java.util.concurrent.Executor} is used + * to perform each invocation of the + * {@link #handleNotification(NotificationListener, Notification, + * Object)} method. Filtering is performed beforehand, by this + * thread; only calls which have successfully passed through the + * filter are sent to the executor. The specified + * {@link MBeanNotificationInfo} array is used to provide + * information about the notifications on calls to + * {@link #getNotificationInfo()}, where a clone will be + * returned if the array is non-empty. + * + * @param executor the executor to use for each call to + * <code>handleNotification()</code>. + * @param info an array of {@link MBeanNotificationInfo} objects + * describing the notifications delivered by this + * broadcaster. This may be <code>null</code>, which + * is taken as being equivalent to an empty array. + * @since 1.6 + */ + public NotificationBroadcasterSupport(Executor executor, + MBeanNotificationInfo... info) + { + this.executor = executor; + this.info = info; + } + + /** + * Registers the specified listener as a new recipient of + * notifications from this bean. If non-null, the filter + * argument will be used to select which notifications are + * delivered. The supplied object will also be passed to + * the recipient with each notification. This should not + * be modified by the broadcaster, but instead should be + * passed unmodified to the listener. + * + * @param listener the new listener, who will receive + * notifications from this broadcasting bean. + * @param filter a filter to determine which notifications are + * delivered to the listener, or <code>null</code> + * if no filtering is required. + * @param passback an object to be passed to the listener with + * each notification. + * @throws IllegalArgumentException if <code>listener</code> is + * <code>null</code>. + * @see #removeNotificationListener(NotificationListener) + */ + public void addNotificationListener(NotificationListener listener, + NotificationFilter filter, + Object passback) + throws IllegalArgumentException + { + if (listener == null) + throw new IllegalArgumentException("Null listener added to bean."); + listeners.add(new ListenerData(listener, filter, passback)); + } + + /** + * Returns an array describing the notifications this + * bean may send to its registered listeners. Ideally, this + * array should be complete, but in some cases, this may + * not be possible. However, be aware that some listeners + * may expect this to be so. + * + * @return the array of possible notifications. + */ + public MBeanNotificationInfo[] getNotificationInfo() + { + if (info == null || info.length == 0) + return new MBeanNotificationInfo[0]; + return (MBeanNotificationInfo[]) info.clone(); + } + + /** + * This method is called on a per-listener basis, either + * from this thread or the supplied executor, and may be + * overridden by subclasses which wish to change how + * notifications are delivered. The default + * implementation simply calls + * <code>listener.handleNotification(notif, passback)</code>. + * + * @param listener the listener to send the notification to. + * @param notif the notification to dispatch. + * @param passback the passback object of the listener. + */ + protected void handleNotification(NotificationListener listener, + Notification notif, + Object passback) + { + listener.handleNotification(notif, passback); + } + + /** + * Removes the specified listener from the list of recipients + * of notifications from this bean. This includes all combinations + * of filters and passback objects registered for this listener. + * For more specific removal of listeners, see the subinterface + * {@link NotificationEmitter}. + * + * @param listener the listener to remove. + * @throws ListenerNotFoundException if the specified listener + * is not registered with this bean. + * @see #addNotificationListener(NotificationListener, NotificationFilter, + * java.lang.Object) + */ + public void removeNotificationListener(NotificationListener listener) + throws ListenerNotFoundException + { + Iterator<ListenerData> it = listeners.iterator(); + boolean foundOne = false; + while (it.hasNext()) + { + if (it.next().getListener() == listener) + { + it.remove(); + foundOne = true; + } + } + if (!foundOne) + throw new ListenerNotFoundException("The specified listener, " + listener + + "is not registered with this bean."); + } + + /** + * Removes the specified listener from the list of recipients + * of notifications from this bean. Only the first instance with + * the supplied filter and passback object is removed. + * <code>null</code> is used as a valid value for these parameters, + * rather than as a way to remove all registration instances for + * the specified listener; for this behaviour instead, see the details + * of the same method in {@link NotificationBroadcaster}. + * + * @param listener the listener to remove. + * @param filter the filter of the listener to remove. + * @param passback the passback object of the listener to remove. + * @throws ListenerNotFoundException if the specified listener + * is not registered with this bean. + * @see #addNotificationListener(NotificationListener, NotificationFilter, + * java.lang.Object) + */ + public void removeNotificationListener(NotificationListener listener, + NotificationFilter filter, + Object passback) + throws ListenerNotFoundException + { + if (!(listeners.remove(new ListenerData(listener, filter, passback)))) + { + throw new ListenerNotFoundException("The specified listener, " + listener + + " with filter " + filter + + "and passback " + passback + + ", is not registered with this bean."); + } + } + + /** + * <p> + * Performs delivery of the notification. If an executor + * was specified on construction, this will be used to call + * {@link #handleNotification(NotificationListener, Notification, + * Object)}. If the executor is <code>null</code>, however, + * this thread calls the method itself in order to perform a + * synchronous dispatch of the notification to all eligible + * listeners. + * </p> + * <p> + * Prior to either process taking place, the listeners are filtered. + * Notifications are only delivered if the filter is either + * <code>null</code> or returns true from the + * {@link NotificationFilter#isNotificationEnabled(Notification)} + * method. + * </p> + * + * @param notif the notification to send. + */ + public void sendNotification(Notification notif) + { + for (ListenerData ldata : listeners) + { + NotificationFilter filter = ldata.getFilter(); + if (filter == null || filter.isNotificationEnabled(notif)) + { + if (executor == null) + try + { + handleNotification(ldata.getListener(), notif, + ldata.getPassback()); + } + catch (Exception e) { /* Ignore */ } + else + executor.execute(new DispatchTask(ldata, notif)); + } + } + } + + /** + * The dispatch task to be performed by an executor. + */ + private final class DispatchTask + implements Runnable + { + + /** + * The data on the listener being called. + */ + private ListenerData ldata; + + /** + * The notification to send. + */ + private Notification notif; + + /** + * Construct a new {@link DispatchTask}. + * + * @param ldata the listener data. + * @param notif the notification to send. + */ + public DispatchTask(ListenerData ldata, + Notification notif) + { + this.ldata = ldata; + this.notif = notif; + } + + /** + * Dispatch the notification. + */ + public void run() + { + try + { + handleNotification(ldata.getListener(), notif, + ldata.getPassback()); + } + catch (Exception e) { /* Ignore */ } + } + } + +} diff --git a/libjava/classpath/javax/management/NotificationEmitter.java b/libjava/classpath/javax/management/NotificationEmitter.java new file mode 100644 index 000000000..7187d8cdf --- /dev/null +++ b/libjava/classpath/javax/management/NotificationEmitter.java @@ -0,0 +1,75 @@ +/* NotificationEmitter.java -- Refined interface for broadcasters. + Copyright (C) 2006 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 bean that can emit notifications when + * events occur. Other beans can use this interface + * to add themselves to the list of recipients of such + * notifications. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public interface NotificationEmitter + extends NotificationBroadcaster +{ + + /** + * Removes the specified listener from the list of recipients + * of notifications from this bean. Only the first instance with + * the supplied filter and passback object is removed. + * <code>null</code> is used as a valid value for these parameters, + * rather than as a way to remove all registration instances for + * the specified listener; for this behaviour instead, see the details + * of the same method in {@link NotificationBroadcaster}. + * + * @param listener the listener to remove. + * @param filter the filter of the listener to remove. + * @param passback the passback object of the listener to remove. + * @throws ListenerNotFoundException if the specified listener + * is not registered with this bean. + * @see #addNotificationListener(NotificationListener, NotificationFilter, + * java.lang.Object) + */ + void removeNotificationListener(NotificationListener listener, + NotificationFilter filter, + Object passback) + throws ListenerNotFoundException; + +} diff --git a/libjava/classpath/javax/management/NotificationFilter.java b/libjava/classpath/javax/management/NotificationFilter.java new file mode 100644 index 000000000..db39aad7f --- /dev/null +++ b/libjava/classpath/javax/management/NotificationFilter.java @@ -0,0 +1,65 @@ +/* NotificationFilter.java -- Interface for notification filters. + Copyright (C) 2006 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 a object that acts as a filter for notifications. + * Implementations of this class are used to determine which + * notifications should be passed to a receiving bean, and which + * should not. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public interface NotificationFilter + extends Serializable +{ + + /** + * Returns true if the specified notification should be passed + * on to the listener. + * + * @param notification the notification being delivered. + * @return true if the notification should be passed to the + * listener, false otherwise. + */ + boolean isNotificationEnabled(Notification notification); + +} diff --git a/libjava/classpath/javax/management/NotificationFilterSupport.java b/libjava/classpath/javax/management/NotificationFilterSupport.java new file mode 100644 index 000000000..a71f5c717 --- /dev/null +++ b/libjava/classpath/javax/management/NotificationFilterSupport.java @@ -0,0 +1,139 @@ +/* NotificationFilterSupport.java -- Filter on notification type. + Copyright (C) 2007 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package javax.management; + +import java.util.Vector; + +/** + * Performs filtering of {@link Notification}s + * based on a list of type prefixes. The type of a notification + * is compared with each member of the list using + * {@link String#startsWith(String)} and, if one matches, + * the notification is allowed to pass through the filter. + * Matching on the beginning of the string is used in + * preference to wildcards, so <code>type.*</code> will + * match only notifications with a type beginning with + * code>type.*</code>, not <code>type.</code> as + * expected. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public class NotificationFilterSupport + implements NotificationFilter +{ + + /** + * Compatible with JDK 1.5 + */ + private static final long serialVersionUID = 6579080007561786969L; + + /** + * Lists the types that may pass through the filter. + */ + private final Vector<String> enabledTypes = new Vector<String>(); + + /** + * Blocks all types by emptying the list of enabled attributes. + */ + public void disableAllTypes() + { + enabledTypes.clear(); + } + + /** + * Removes the specified type prefix from the list + * of enabled types, thus preventing matching types + * from passing through the filter. If the specified + * type prefix is not enabled, this operation has no + * effect. + * + * @param prefix the prefix to disable. + */ + public void disableType(String prefix) + { + enabledTypes.remove(prefix); + } + + /** + * Adds the specified type prefix to the list + * of enabled types, thus allowing + * types starting with this string to pass through + * the filter. If the type prefix is already + * enabled, this has no effect. + * + * @param prefix the prefix to enable. + * @throws IllegalArgumentException if <code>prefix</code> + * is <code>null</code>. + */ + public void enableType(String prefix) + { + if (prefix == null) + throw new IllegalArgumentException("A null prefix was supplied."); + if (!enabledTypes.contains(prefix)) + enabledTypes.add(prefix); + } + + /** + * Returns the list of enabled types for this + * filter. + * + * @return the list of enabled types. + */ + public Vector<String> getEnabledTypes() + { + return enabledTypes; + } + + /** + * Returns true if the type of the specified notification + * begins with one of the enabled type prefixes. + * + * @param notif the notification being filtered. + * @return true if the notification's type is enabled. + */ + public boolean isNotificationEnabled(Notification notif) + { + String nType = notif.getType(); + for (String type : enabledTypes) + if (nType.startsWith(type)) + return true; + return false; + } + +} diff --git a/libjava/classpath/javax/management/NotificationListener.java b/libjava/classpath/javax/management/NotificationListener.java new file mode 100644 index 000000000..4810e9187 --- /dev/null +++ b/libjava/classpath/javax/management/NotificationListener.java @@ -0,0 +1,69 @@ +/* NotificationListener.java -- Interface for receivers of notifications. + Copyright (C) 2006 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.EventListener; + +/** + * Represents a object that can receive notifications from + * a bean. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public interface NotificationListener + extends EventListener +{ + + /** + * Invoked by the notifying bean when a notification is to + * be delivered to the recipient. As the transmission of + * notifications takes place sequentially, implementors of + * this method should avoid performing lengthy operations, + * as the notifying bean will stall until the method is + * complete. + * + * @param notification the notification from the bean. + * @param passback the object that was passed to the notifying + * bean as part of the registration process. + * @see NotificationBroadcaster#addListener(NotificationListener, + * NotificationFilter, Object) + */ + void handleNotification(Notification notification, Object passback); + +} diff --git a/libjava/classpath/javax/management/ObjectInstance.java b/libjava/classpath/javax/management/ObjectInstance.java new file mode 100644 index 000000000..1328db0e2 --- /dev/null +++ b/libjava/classpath/javax/management/ObjectInstance.java @@ -0,0 +1,147 @@ +/* ObjectInstance.java -- Represent the bean instance used by a server. + Copyright (C) 2006 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; + +/** + * A simple class used to link a bean instance to its class name. + * If the bean is a {@link DynamicMBean}, the class name may be + * obtained using {@link MBeanInfo#getClassName()}. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public class ObjectInstance + implements Serializable +{ + + /** + * Compatible with JDK 1.5 + */ + private static final long serialVersionUID = -4099952623687795850L; + + /** + * The name of the bean. + */ + private ObjectName name; + + /** + * The class name of the bean. + */ + private String className; + + /** + * Constructs a new {@link ObjectInstance} for the specified bean + * with the supplied class name. The class name should include + * the full package name. + * + * @param name the name of the bean. + * @param className the class name of the bean. + */ + public ObjectInstance(ObjectName name, String className) + { + this.name = name; + this.className = className; + } + + /** + * Constructs a new {@link ObjectInstance} for the specified bean + * with the supplied class name. The class name should include + * the full package name. + * + * @param name the name of the bean. + * @param className the class name of the bean. + * @throws MalformedObjectNameException if the name of the bean + * does not match the syntax + * of an {@link ObjectName}. + */ + public ObjectInstance(String name, String className) + throws MalformedObjectNameException + { + this(new ObjectName(name), className); + } + + /** + * Returns true if the supplied object is also an {@link ObjectInstance} + * with the same bean and class name. + * + * @param obj the object to compare. + * @return true if the the supplied object is equal to <code>this</code>. + */ + public boolean equals(Object obj) + { + if (!(obj instanceof ObjectInstance)) + return false; + ObjectInstance i = (ObjectInstance) obj; + return (i.getClassName().equals(className) && + i.getObjectName().equals(name)); + } + + /** + * Returns the class name of the bean. + * + * @return the class name. + */ + public String getClassName() + { + return className; + } + + /** + * Returns the name of the bean. + * + * @return the name of the bean. + */ + public ObjectName getObjectName() + { + return name; + } + + /** + * Returns a hash code for this instance. This is calculated as + * the sum of the hashcodes for the bean's name and the class name. + * + * @return the hash code of this instance. + */ + public int hashCode() + { + return name.hashCode() + className.hashCode(); + } + +} diff --git a/libjava/classpath/javax/management/ObjectName.java b/libjava/classpath/javax/management/ObjectName.java new file mode 100644 index 000000000..856d03f03 --- /dev/null +++ b/libjava/classpath/javax/management/ObjectName.java @@ -0,0 +1,944 @@ +/* ObjectName.java -- Represent the name of a bean, or a pattern for a name. + Copyright (C) 2006, 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.java.lang.CPStringBuilder; + +import java.io.Serializable; + +import java.util.Hashtable; +import java.util.Iterator; +import java.util.Map; +import java.util.TreeMap; + +import java.io.IOException; +import java.io.InvalidObjectException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; + +/** + * <p> + * An {@link ObjectName} instance represents the name of a management + * bean, or a pattern which may match the name of one or more + * management beans. Patterns are distinguished from names by the + * presence of the '?' and '*' characters (which match a single + * character and a series of zero or more characters, respectively). + * </p> + * <p> + * Each name begins with a domain element, which is terminated by + * a ':' character. The domain may be empty. If so, it will be + * replaced by the default domain of the bean server in certain + * contexts. The domain is a pattern, if it contains either '?' + * or '*'. To avoid collisions, it is usual to use reverse + * DNS names for the domain, as in Java package and property names. + * </p> + * <p> + * Following the ':' character is a series of properties. The list + * is separated by commas, and largely consists of unordered key-value + * pairs, separated by an equals sign ('='). At most one element may + * be an asterisk ('*'), which turns the {@link ObjectName} instance + * into a <emph>property list pattern</emph>. In this situation, the pattern + * matches a name if the name contains at least those key-value pairs + * given and has the same domain. + * </p> + * <p> + * A <emph>key</emph> is a string of characters which doesn't include + * any of those used as delimiters or in patterns (':', '=', ',', '?' + * and '*'). Keys must be unique. + * </p> + * <p> + * A value may be <emph>quoted</emph> or <emph>unquoted</emph>. Unquoted + * values obey the same rules as given for keys above. Quoted values are + * surrounded by quotation marks ("), and use a backslash ('\') character + * to include quotes ('\"'), backslashes ('\\'), newlines ('\n'), and + * the pattern characters ('\?' and '\*'). The quotes and backslashes + * (after expansion) are considered part of the value. + * </p> + * <p> + * Both quoted and unquoted values may contain the wildcard characters + * '?' and '*'. A name with at least one value containing a wildcard + * character is known as a <emph>property value pattern</emph>. A + * name is generally a <emph>property pattern</emph> if it is either + * a <emph>property list pattern</emph> or <emph>property value pattern</emph>. + * </p> + * <p> + * Spaces are maintained within the different parts of the name. Thus, + * '<code>domain: key1 = value1 </code>' has a key ' key1 ' with value + * ' value1 '. Newlines are disallowed, except where escaped in quoted + * values. + * </p> + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public class ObjectName + implements Serializable, QueryExp +{ + + private static final long serialVersionUID = 1081892073854801359L; + + /** + * The wildcard {@link ObjectName} {@code "*:*"} + * + * @since 1.6 + */ + public static final ObjectName WILDCARD; + + /** + * The domain of the name. + */ + private transient String domain; + + /** + * The properties, as key-value pairs. + */ + private transient TreeMap<String,String> properties; + + /** + * The properties as a string (stored for ordering). + */ + private transient String propertyListString; + + /** + * True if this object name is a property list pattern. + */ + private transient boolean propertyListPattern; + + /** + * True if this object name is a property value pattern. + */ + private transient boolean propertyValuePattern; + + /** + * The management server associated with this object name. + */ + private transient MBeanServer server; + + /** + * Static initializer to set up the wildcard. + */ + static + { + try + { + WILDCARD = new ObjectName(""); + } + catch (MalformedObjectNameException e) + { + throw (InternalError) (new InternalError("A problem occurred " + + "initializing the ObjectName " + + "wildcard.").initCause(e)); + } + } + + /** + * Constructs an {@link ObjectName} instance from the given string, + * which should be of the form + * <domain>:<properties><wild>. <domain> + * represents the domain section of the name. <properties> + * represents the key-value pairs, as returned by {@link + * #getKeyPropertyListString()}. <wild> is the optional + * asterisk present in the property list. If the string doesn't + * represent a property pattern, it will be empty. If it does, + * it will be either ',*' or '*', depending on whether other + * properties are present or not, respectively. + * + * @param name the string to use to construct this instance. + * @throws MalformedObjectNameException if the string is of the + * wrong format. + * @throws NullPointerException if <code>name</code> is + * <code>null</code>. + */ + public ObjectName(String name) + throws MalformedObjectNameException + { + if (name.length() == 0) + name = "*:*"; + parse(name); + } + + /** + * Parse the name in the same form as the constructor. Used by + * readObject(). + */ + private void parse(String name) + throws MalformedObjectNameException + { + int domainSep = name.indexOf(':'); + if (domainSep == -1) + throw new MalformedObjectNameException("No domain separator was found."); + domain = name.substring(0, domainSep); + String rest = name.substring(domainSep + 1); + properties = new TreeMap<String,String>(); + String[] pairs = rest.split(","); + if (pairs.length == 0 && !isPattern()) + throw new MalformedObjectNameException("A name that is not a " + + "pattern must contain at " + + "least one key-value pair."); + propertyListString = ""; + for (int a = 0; a < pairs.length; ++a) + { + if (pairs[a].equals("*")) + { + if (propertyListPattern) + throw new MalformedObjectNameException("Multiple wildcards " + + "in properties."); + propertyListPattern = true; + continue; + } + int sep = pairs[a].indexOf('='); + if (sep == -1) + throw new MalformedObjectNameException("A key must be " + + "followed by a value."); + String key = pairs[a].substring(0, sep); + if (properties.containsKey(key)) + throw new MalformedObjectNameException("The same key occurs " + + "more than once."); + String value = pairs[a].substring(sep+1); + properties.put(key, value); + propertyListString += key + "=" + value + ","; + } + if (propertyListString.length() > 0) + propertyListString = + propertyListString.substring(0, propertyListString.length() - 1); + checkComponents(); + } + + /** + * Constructs an {@link ObjectName} instance using the given + * domain and the one specified property. + * + * @param domain the domain part of the object name. + * @param key the key of the property. + * @param value the value of the property. + * @throws MalformedObjectNameException the domain, key or value + * contains an illegal + * character or the value + * does not follow the quoting + * specifications. + * @throws NullPointerException if one of the parameters is + * <code>null</code>. + */ + public ObjectName(String domain, String key, String value) + throws MalformedObjectNameException + { + this.domain = domain; + properties = new TreeMap<String,String>(); + properties.put(key, value); + checkComponents(); + } + + /** + * Constructs an {@link ObjectName} instance using the given + * domain and properties. + * + * @param domain the domain part of the object name. + * @param properties the key-value property pairs. + * @throws MalformedObjectNameException the domain, a key or a value + * contains an illegal + * character or a value + * does not follow the quoting + * specifications. + * @throws NullPointerException if one of the parameters is + * <code>null</code>. + */ + public ObjectName(String domain, Hashtable<String,String> properties) + throws MalformedObjectNameException + { + this.domain = domain; + this.properties = new TreeMap<String,String>(); + this.properties.putAll(properties); + checkComponents(); + } + + /** + * Checks the legality of the domain and the properties. + * + * @throws MalformedObjectNameException the domain, a key or a value + * contains an illegal + * character or a value + * does not follow the quoting + * specifications. + */ + private void checkComponents() + throws MalformedObjectNameException + { + if (domain.indexOf(':') != -1) + throw new MalformedObjectNameException("The domain includes a ':' " + + "character."); + if (domain.indexOf('\n') != -1) + throw new MalformedObjectNameException("The domain includes a newline " + + "character."); + char[] keychars = new char[] { '\n', ':', ',', '*', '?', '=' }; + char[] valchars = new char[] { '\n', ':', ',', '=' }; + for (Map.Entry<String,String> entry : properties.entrySet()) + { + for (int a = 0; a < keychars.length; ++a) + if (entry.getKey().indexOf(keychars[a]) != -1) + throw new MalformedObjectNameException("A key contains a '" + + keychars[a] + "' " + + "character."); + String value = entry.getValue(); + int quote = value.indexOf('"'); + if (quote == 0) + { + try + { + unquote(value); + } + catch (IllegalArgumentException e) + { + throw (MalformedObjectNameException) + new MalformedObjectNameException("The quoted value is " + + "invalid.").initCause(e); + } + } + else if (quote != -1) + throw new MalformedObjectNameException("A value contains " + + "a '\"' character."); + else + { + for (int a = 0; a < valchars.length; ++a) + if (value.indexOf(valchars[a]) != -1) + throw new MalformedObjectNameException("A value contains " + + "a '" + valchars[a] + "' " + + "character."); + + } + if (value.indexOf('*') != -1 || value.indexOf('?') != -1) + propertyValuePattern = true; + } + } + + /** + * <p> + * Attempts to find a match between this name and the one supplied. + * The following criteria are used: + * </p> + * <ul> + * <li>If the supplied name is a pattern, <code>false</code> is + * returned.</li> + * <li>If this name is a pattern, this method returns <code>true</code> + * if the supplied name matches the pattern.</li> + * <li>If this name is not a pattern, the result of + * <code>equals(name)</code> is returned. + * </ul> + * + * @param name the name to find a match with. + * @return true if the name either matches this pattern or is + * equivalent to this name under the criteria of + * {@link #equals(java.lang.Object)} + * @throws NullPointerException if <code>name</code> is <code>null</code>. + */ + public boolean apply(ObjectName name) + { + if (name.isPattern()) + return false; + + if (!isPattern()) + return equals(name); + + if (isDomainPattern()) + { + if (!domainMatches(domain, 0, name.getDomain(), 0)) + return false; + } + else + { + if (!domain.equals(name.getDomain())) + return false; + } + + if (isPropertyPattern()) + { + Hashtable<String,String> oProps = name.getKeyPropertyList(); + for (Map.Entry<String,String> entry : properties.entrySet()) + { + String key = entry.getKey(); + if (!(oProps.containsKey(key))) + return false; + String val = entry.getValue(); + if (!(val.equals(oProps.get(key)))) + return false; + } + } + else + { + if (!getCanonicalKeyPropertyListString().equals + (name.getCanonicalKeyPropertyListString())) + return false; + } + return true; + } + + /** + * Returns true if the domain matches the pattern. + * + * @param pattern the pattern to match against. + * @param patternindex the index into the pattern to start matching. + * @param domain the domain to match. + * @param domainindex the index into the domain to start matching. + * @return true if the domain matches the pattern. + */ + private static boolean domainMatches(String pattern, int patternindex, + String domain, int domainindex) + { + while (patternindex < pattern.length()) + { + char c = pattern.charAt(patternindex++); + + if (c == '*') + { + for (int i = domain.length(); i >= domainindex; i--) + { + if (domainMatches(pattern, patternindex, domain, i)) + return true; + } + return false; + } + + if (domainindex >= domain.length()) + return false; + + if (c != '?' && c != domain.charAt(domainindex)) + return false; + + domainindex++; + } + return true; + } + + /** + * Compares the specified object with this one. The two + * are judged to be equivalent if the given object is an + * instance of {@link ObjectName} and has an equal canonical + * form (as returned by {@link #getCanonicalName()}). + * + * @param obj the object to compare with this. + * @return true if the object is also an {@link ObjectName} + * with an equivalent canonical form. + */ + public boolean equals(Object obj) + { + if (obj instanceof ObjectName) + { + ObjectName o = (ObjectName) obj; + return getCanonicalName().equals(o.getCanonicalName()); + } + return false; + } + + /** + * Returns the property list in canonical form. The keys + * are ordered using the lexicographic ordering used by + * {@link java.lang.String#compareTo(java.lang.Object)}. + * + * @return the property list, with the keys in lexicographic + * order. + */ + public String getCanonicalKeyPropertyListString() + { + CPStringBuilder builder = new CPStringBuilder(); + Iterator<Map.Entry<String,String>> i = properties.entrySet().iterator(); + while (i.hasNext()) + { + Map.Entry<String,String> entry = i.next(); + builder.append(entry.getKey() + "=" + entry.getValue()); + if (i.hasNext()) + builder.append(","); + } + return builder.toString(); + } + + /** + * <p> + * Returns the name as a string in canonical form. More precisely, + * this returns a string of the format + * <domain>:<properties><wild>. <properties> + * is the same value as returned by + * {@link #getCanonicalKeyPropertyListString()}. <wild> + * is: + * </p> + * <ul> + * <li>an empty string, if the object name is not a property pattern.</li> + * <li>'*' if <properties> is empty.</li> + * <li>',*' if there is at least one key-value pair.</li> + * </ul> + * + * @return the canonical string form of the object name, as specified + * above. + */ + public String getCanonicalName() + { + return domain + ":" + + getCanonicalKeyPropertyListString() + + (isPropertyPattern() ? (properties.isEmpty() ? "*" : ",*") : ""); + } + + /** + * Returns the domain part of the object name. + * + * @return the domain. + */ + public String getDomain() + { + return domain; + } + + /** + * Returns an {@link ObjectName} instance that is substitutable for the + * one given. The instance returned may be a subclass of {@link ObjectName}, + * but is not guaranteed to be of the same type as the given name, if that + * should also turn out to be a subclass. The returned instance may or may + * not be equivalent to the one given. The purpose of this method is to provide + * an instance of {@link ObjectName} with a well-defined semantics, such as may + * be used in cases where the given name is not trustworthy. + * + * @param name the {@link ObjectName} to provide a substitute for. + * @return a substitute for the given name, which may or may not be a subclass + * of {@link ObjectName}. In either case, the returned object is + * guaranteed to have the semantics defined here. + * @throws NullPointerException if <code>name</code> is <code>null</code>. + */ + public static ObjectName getInstance(ObjectName name) + { + try + { + return new ObjectName(name.getCanonicalName()); + } + catch (MalformedObjectNameException e) + { + throw (InternalError) + (new InternalError("The canonical name of " + + "the given name is invalid.").initCause(e)); + } + } + + /** + * Returns an {@link ObjectName} instance for the specified name, represented + * as a {@link java.lang.String}. The instance returned may be a subclass of + * {@link ObjectName} and may or may not be equivalent to earlier instances + * returned by this method for the same string. + * + * @param name the {@link ObjectName} to provide an instance of. + * @return a instance for the given name, which may or may not be a subclass + * of {@link ObjectName}. + * @throws MalformedObjectNameException the domain, a key or a value + * contains an illegal + * character or a value + * does not follow the quoting + * specifications. + * @throws NullPointerException if <code>name</code> is <code>null</code>. + */ + public static ObjectName getInstance(String name) + throws MalformedObjectNameException + { + return new ObjectName(name); + } + + /** + * Returns an {@link ObjectName} instance for the specified name, represented + * as a series of {@link java.lang.String} objects for the domain and a single + * property, as a key-value pair. The instance returned may be a subclass of + * {@link ObjectName} and may or may not be equivalent to earlier instances + * returned by this method for the same parameters. + * + * @param domain the domain part of the object name. + * @param key the key of the property. + * @param value the value of the property. + * @return a instance for the given name, which may or may not be a subclass + * of {@link ObjectName}. + * @throws MalformedObjectNameException the domain, a key or a value + * contains an illegal + * character or a value + * does not follow the quoting + * specifications. + * @throws NullPointerException if <code>name</code> is <code>null</code>. + */ + public static ObjectName getInstance(String domain, String key, String value) + throws MalformedObjectNameException + { + return new ObjectName(domain, key, value); + } + + /** + * Returns an {@link ObjectName} instance for the specified name, represented + * as a domain {@link java.lang.String} and a table of properties. The + * instance returned may be a subclass of {@link ObjectName} and may or may + * not be equivalent to earlier instances returned by this method for the + * same string. + * + * @param domain the domain part of the object name. + * @param properties the key-value property pairs. + * @return a instance for the given name, which may or may not be a subclass + * of {@link ObjectName}. + * @throws MalformedObjectNameException the domain, a key or a value + * contains an illegal + * character or a value + * does not follow the quoting + * specifications. + * @throws NullPointerException if <code>name</code> is <code>null</code>. + */ + public static ObjectName getInstance(String domain, + Hashtable<String,String> properties) + throws MalformedObjectNameException + { + return new ObjectName(domain, properties); + } + + /** + * Returns the property value corresponding to the given key. + * + * @param key the key of the property to be obtained. + * @return the value of the specified property. + * @throws NullPointerException if <code>key</code> is <code>null</code>. + */ + public String getKeyProperty(String key) + { + if (key == null) + throw new NullPointerException("Null key given in request for a value."); + return (String) properties.get(key); + } + + /** + * Returns the properties in a {@link java.util.Hashtable}. The table + * contains each of the properties as keys mapped to their value. The + * returned table is not unmodifiable, but changes made to it will not + * be reflected in the object name. + * + * @return a {@link java.util.Hashtable}, containing each of the object + * name's properties. + */ + public Hashtable<String,String> getKeyPropertyList() + { + return new Hashtable<String,String>(properties); + } + + /** + * Returns a {@link java.lang.String} representation of the property + * list. If the object name was created using {@link + * ObjectName(String)}, then this string will contain the properties + * in the same order they were given in at creation. + * + * @return the property list. + */ + public String getKeyPropertyListString() + { + if (propertyListString != null) + return propertyListString; + return getCanonicalKeyPropertyListString(); + } + + /** + * Returns a hash code for this object name. This is calculated as the + * summation of the hash codes of the domain and the properties. + * + * @return a hash code for this object name. + */ + public int hashCode() + { + return domain.hashCode() + properties.hashCode(); + } + + /** + * Returns true if the domain of this object name is a pattern. + * This is the case if it contains one or more wildcard characters + * ('*' or '?'). + * + * @return true if the domain is a pattern. + */ + public boolean isDomainPattern() + { + return domain.contains("?") || domain.contains("*"); + } + + /** + * Returns true if this is an object name pattern. An object + * name pattern has a domain containing a wildcard character + * ('*' or '?') and/or a '*' in the list of properties. + * This method will return true if either {@link #isDomainPattern()} + * or {@link #isPropertyPattern()} does. + * + * @return true if this is an object name pattern. + */ + public boolean isPattern() + { + return isDomainPattern() || isPropertyPattern(); + } + + /** + * Returns true if this object name is a property list + * pattern, a property value pattern or both. + * + * @return true if the properties of this name contain a pattern. + * @see #isPropertyListPattern + * @see #isPropertyValuePattern + */ + public boolean isPropertyPattern() + { + return propertyListPattern || propertyValuePattern; + } + + /** + * Returns true if this object name is a property list pattern. This is + * the case if the list of properties contains an '*'. + * + * @return true if this is a property list pattern. + * @since 1.6 + */ + public boolean isPropertyListPattern() + { + return propertyListPattern; + } + + /** + * Returns true if this object name is a property value pattern. This is + * the case if one of the values contains a wildcard character, + * '?' or '*'. + * + * @return true if this is a property value pattern. + * @since 1.6 + */ + public boolean isPropertyValuePattern() + { + return propertyValuePattern; + } + + /** + * Returns true if the value of the given key is a pattern. This is + * the case if the value contains a wildcard character, '?' or '*'. + * + * @param key the key whose value should be checked. + * @return true if the value of the given key is a pattern. + * @since 1.6 + * @throws NullPointerException if {@code key} is {@code null}. + * @throws IllegalArgumentException if {@code key} is not a valid + * property. + */ + public boolean isPropertyValuePattern(String key) + { + String value = getKeyProperty(key); + if (value == null) + throw new IllegalArgumentException(key + " is not a valid property."); + return value.indexOf('?') != -1 || value.indexOf('*') != -1; + } + + /** + * <p> + * Returns a quoted version of the supplied string. The string may + * contain any character. The resulting quoted version is guaranteed + * to be usable as the value of a property, so this method provides + * a good way of ensuring that a value is legal. + * </p> + * <p> + * The string is transformed as follows: + * </p> + * <ul> + * <li>The string is prefixed with an opening quote character, '"'. + * <li>For each character, s: + * <ul> + * <li>If s is a quote ('"'), it is replaced by a backslash + * followed by a quote.</li> + * <li>If s is a star ('*'), it is replaced by a backslash followed + * by a star.</li> + * <li>If s is a question mark ('?'), it is replaced by a backslash + * followed by a question mark.</li> + * <li>If s is a backslash ('\'), it is replaced by two backslashes.</li> + * <li>If s is a newline character, it is replaced by a backslash followed by + * a '\n'.</li> + * <li>Otherwise, s is used verbatim. + * </ul></li> + * <li>The string is terminated with a closing quote character, '"'.</li> + * </ul> + * + * @param string the string to quote. + * @return a quoted version of the supplied string. + * @throws NullPointerException if <code>string</code> is <code>null</code>. + */ + public static String quote(String string) + { + CPStringBuilder builder = new CPStringBuilder(); + builder.append('"'); + for (int a = 0; a < string.length(); ++a) + { + char s = string.charAt(a); + switch (s) + { + case '"': + builder.append("\\\""); + break; + case '*': + builder.append("\\*"); + break; + case '?': + builder.append("\\?"); + break; + case '\\': + builder.append("\\\\"); + break; + case '\n': + builder.append("\\\n"); + break; + default: + builder.append(s); + } + } + builder.append('"'); + return builder.toString(); + } + + /** + * Changes the {@link MBeanServer} on which this query is performed. + * + * @param server the new server to use. + */ + public void setMBeanServer(MBeanServer server) + { + this.server = server; + } + + /** + * Returns a textual representation of the object name. + * + * <p>The format is unspecified beyond that equivalent object + * names will return the same string from this method, but note + * that Tomcat depends on the string returned by this method + * being a valid textual representation of the object name and + * will fail to start if it is not. + * + * @return a textual representation of the object name. + */ + public String toString() + { + return getCanonicalName(); + } + + + /** + * Serialize this {@link ObjectName}. The serialized + * form is the same as the string parsed by the constructor. + * + * @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(); + CPStringBuilder buffer = new CPStringBuilder(getDomain()); + buffer.append(':'); + String properties = getKeyPropertyListString(); + buffer.append(properties); + if (isPropertyPattern()) + { + if (properties.length() == 0) + buffer.append("*"); + else + buffer.append(",*"); + } + out.writeObject(buffer.toString()); + } + + /** + * Reads the serialized form, which is that used + * by the constructor. + * + * @param in the input stream to read from. + * @throws IOException if an I/O error occurs. + */ + private void readObject(ObjectInputStream in) + throws IOException, ClassNotFoundException + { + in.defaultReadObject(); + String objectName = (String)in.readObject(); + try + { + parse(objectName); + } + catch (MalformedObjectNameException x) + { + throw new InvalidObjectException(x.toString()); + } + } + + + /** + * Unquotes the supplied string. The quotation marks are removed as + * are the backslashes preceding the escaped characters ('"', '?', + * '*', '\n', '\\'). A one-to-one mapping exists between quoted and + * unquoted values. As a result, a string <code>s</code> should be + * equal to <code>unquote(quote(s))</code>. + * + * @param q the quoted string to unquote. + * @return the unquoted string. + * @throws NullPointerException if <code>q</code> is <code>null</code>. + * @throws IllegalArgumentException if the string is not a valid + * quoted string i.e. it is not + * surrounded by quotation marks + * and/or characters are not properly + * escaped. + */ + public static String unquote(String q) + { + if (q.charAt(0) != '"') + throw new IllegalArgumentException("The string does " + + "not start with a quote."); + if (q.charAt(q.length() - 1) != '"') + throw new IllegalArgumentException("The string does " + + "not end with a quote."); + CPStringBuilder builder = new CPStringBuilder(); + for (int a = 1; a < (q.length() - 1); ++a) + { + char n = q.charAt(a); + if (n == '\\') + { + n = q.charAt(++a); + if (n != '"' && n != '?' && n != '*' && + n != 'n' && n != '\\') + throw new IllegalArgumentException("Illegal escaped character: " + + n); + } + else if (n == '"' || n == '\n') + throw new IllegalArgumentException("Illegal character: " + n); + builder.append(n); + } + + return builder.toString(); + } + +} diff --git a/libjava/classpath/javax/management/OperationsException.java b/libjava/classpath/javax/management/OperationsException.java new file mode 100644 index 000000000..b0e434de4 --- /dev/null +++ b/libjava/classpath/javax/management/OperationsException.java @@ -0,0 +1,75 @@ +/* OperationsException.java -- Thrown by management operations. + Copyright (C) 2006 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; + +/** + * A general superclass for all exceptions thrown by + * operations on management beans. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public class OperationsException + extends JMException +{ + + /** + * Compatible with JDK 1.5 + */ + private static final long serialVersionUID = -4967597595580536216L; + + /** + * Constructs a new <code>OperationsException</code>. + */ + public OperationsException() + { + super(); + } + + /** + * Constructs a new <code>OperationsException</code> + * with the specified message. + * + * @param message the error message to give to the user. + */ + public OperationsException(String message) + { + super(message); + } + +} diff --git a/libjava/classpath/javax/management/PersistentMBean.java b/libjava/classpath/javax/management/PersistentMBean.java new file mode 100644 index 000000000..51ee4604b --- /dev/null +++ b/libjava/classpath/javax/management/PersistentMBean.java @@ -0,0 +1,126 @@ +/* PersistentMBean.java -- Interface for beans that should persist. + Copyright (C) 2007 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package javax.management; + +/** + * Beans may implement this interface in order to become + * persistent. The {@link #load()} method should be + * called on construction in order to reload the stored + * state. The {@link #store()} method should be called + * sometime during the bean's lifetime in order to create + * a persistent copy of the bean's instance data. This + * method may also be called by the {@link MBeanServer} + * as a result of the {@link Descriptor} of an + * {@link javax.management.modelmbean.ModelMBean}. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public interface PersistentMBean +{ + + /** + * Instantiates the bean with the data previously stored + * using a call to {@link #store()}. The data stored can + * include values held by attributes as well as those returned + * by operations. This method should be called during + * construction or initialisation of the bean, before + * it becomes registered with an {@link MBeanServer}. + * + * @throws MBeanException if persistence is not supported, + * or another exception is thrown + * (which this then wraps). + * @throws RuntimeOperationsException if the persistence + * mechanism throws an + * exception. + * @throws InstanceNotFoundException if the bean can not + * be found in the + * persistent store. + */ + void load() + throws MBeanException, RuntimeOperationsException, + InstanceNotFoundException; + + /** + * <p> + * Captures the current state of the bean and stores it + * for future retrieval by the {@link #load()} method. + * The data stored can include values held by attributes + * as well as those returned by operations. + * </p> + * <p> + * Whether the state is stored or not depends on the + * <code>persistPolicy</code> field of the MBean/attribute + * descriptor. The state should be stored if the policy + * is set to any of the following: + * </p> + * <ul> + * <li><code>always</code></li> + * <li><code>onTimer</code> and <code>now</code> is + * greater than or equal to <code>lastPersistTime + + * persistPeriod</code>.</li> + * <li><code>noMoreOftenThan</code> and <code>now</code> is + * greater than or equal to <code>lastPersistTime + + * persistPeriod</code>.</li> + * <li>onUnregister</li> + * </ul> + * <p>If the policy is set to any of the following, the state + * should not be stored:</p> + * <ul> + * <li><code>never</code></li> + * <li><code>onUpdate</code></li> + * <li><code>onTimer</code> and <code>now</code> is + * less than <code>lastPersistTime + persistPeriod</code>. + * </li> + * </ul> + * + * @throws MBeanException if persistence is not supported, + * or another exception is thrown + * (which this then wraps). + * @throws RuntimeOperationsException if the persistence + * mechanism throws an + * exception. + * @throws InstanceNotFoundException if the persistent + * store can not be found + * or accessed. + */ + void store() + throws MBeanException, RuntimeOperationsException, + InstanceNotFoundException; + +} diff --git a/libjava/classpath/javax/management/Query.java b/libjava/classpath/javax/management/Query.java new file mode 100644 index 000000000..7cd02704b --- /dev/null +++ b/libjava/classpath/javax/management/Query.java @@ -0,0 +1,1900 @@ +/* Query.java -- Static methods for query construction. + Copyright (C) 2007 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package javax.management; + +/** + * Provides static methods for constructing queries. Queries + * may be used to list and enumerate management beans, via + * the {@link MBeanServer}. By using the methods in this class, + * complex queries can be created from their more basic + * components. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public class Query +{ + + /** + * A code representing the {@link #plus(ValueExp, ValueExp) + * query to be used in serialization. + */ + public static final int PLUS = 0; + + /** + * A code representing the {@link #minus(ValueExp, ValueExp) + * query to be used in serialization. + */ + public static final int MINUS = 1; + + /** + * A code representing the {@link #times(ValueExp, ValueExp) + * query to be used in serialization. + */ + public static final int TIMES = 2; + + /** + * A code representing the {@link #div(ValueExp, ValueExp) + * query to be used in serialization. + */ + public static final int DIV = 3; + + /** + * A code representing the {@link #gt(ValueExp, ValueExp) + * query to be used in serialization. + */ + public static final int GT = 0; + + /** + * A code representing the {@link #lt(ValueExp, ValueExp) + * query to be used in serialization. + */ + public static final int LT = 1; + + /** + * A code representing the {@link #ge(ValueExp, ValueExp) + * query to be used in serialization. + */ + public static final int GE = 2; + + /** + * A code representing the {@link #le(ValueExp, ValueExp) + * query to be used in serialization. + */ + public static final int LE = 3; + + /** + * A code representing the {@link #eq(ValueExp, ValueExp) + * query to be used in serialization. + */ + public static final int EQ = 4; + + /** + * Returns a query expression formed from the conjunction + * of the two supplied query expressions. + * + * @param q1 the first query expression. + * @param q2 the second query expression. + * @return a query expression representing q1 && q2. This + * will be serialized as the non-public class + * {@link AndQueryExp}. + */ + public static QueryExp and(QueryExp q1, QueryExp q2) + { + return new AndQueryExp(q1, q2); + } + + /** + * Returns a query expression which checks that an + * attribute value held by the specified + * {@link AttributeValueExp} contains the string + * specified by the given {@link StringValueExp}. + * + * @param attrib the attribute to match. + * @param string the substring to find. + * @return a query expression representing + * <code>attrib.matches("*" + string + "*")</code>. + * This will be serialized as the non-public class + * {@link MatchQueryExp}. + */ + public static QueryExp anySubString(AttributeValueExp attrib, + StringValueExp string) + { + return new MatchQueryExp(attrib, "*" + string.getValue() + "*"); + } + + /** + * Returns a value expression for the value of the + * named attribute. Evaluating this using an + * {@link ObjectName} involves an underlying call + * to {@link MBeanServer#getAttribute(ObjectName,String)}. + * + * @param name the name of the attribute. + * @return a value expression which returns the value + * of the named attribute when applied. + */ + public static AttributeValueExp attr(String name) + { + return new AttributeValueExp(name); + } + + /** + * Returns a value expression for the value of the + * named attribute from the specified class. Evaluating + * this using an {@link ObjectName} involves an underlying call + * to both {@link MBeanServer#getObjectInstance(ObjectName)} and + * {@link MBeanServer#getAttribute(ObjectName,String)}. + * + * @param className the class containing the attribute. + * @param name the name of the attribute. + * @return a value expression which returns the value + * of the named attribute when applied. + * This will be serialized as the non-public class + * {@link QualifiedAttributeValueExp}. + */ + public static AttributeValueExp attr(String className, + String name) + { + return new QualifiedAttributeValueExp(className, name); + } + + /** + * Returns a query expression representing the constraint + * that the value, <code>v1</code>, lies between <code>v2</code> + * and <code>v3</code>. + * + * @param v1 the value to compare against the boundaries. + * @param v2 the lower boundary. + * @param v3 the upper boundary. + * @return a query expression representing a comparison + * of <code>v1</code> against <code>v2</code> + * and <code>v3</code>. It returns true if + * <code>v2 <= v1 <= v3</code>. This + * will be serialized as the non-public class + * {@link BetweenQueryExp}. + */ + public static QueryExp between(ValueExp v1, ValueExp v2, + ValueExp v3) + { + return new BetweenQueryExp(v1, v2, v3); + } + + /** + * Returns a value expression which evaluates to the name of + * the class of the bean when applied. Associating the expression + * with an {@link ObjectName} involves an underlying call + * to both {@link MBeanServer#getObjectInstance(ObjectName)} + * to obtain this information. + * + * @return a value expression which returns the class name + * of the bean to which it is applied. + * This will be serialized as the non-public class + * {@link ClassAttributeValueExp}. + */ + public static AttributeValueExp classattr() + { + return new ClassAttributeValueExp(); + } + + /** + * Returns a value expression which evaluates to the result of + * dividing <code>v1</code> by <code>v2</code>. + * + * @param v1 the left-hand operand. + * @param v2 the right-hand operand. + * @return a value expression which returns the result of + * the division when applied. This will be serialized + * as the non-public class {@link BinaryOpValueExp} + * with an operation of {@link #DIV}. + */ + public static ValueExp div(ValueExp v1, ValueExp v2) + { + return new BinaryOpValueExp(DIV, v1, v2); + } + + /** + * Returns a query expression which evaluates to the result of + * comparing <code>v1</code> to <code>v2</code> for equality. + * + * @param v1 the left-hand operand. + * @param v2 the right-hand operand. + * @return a value expression which returns the result of + * the comparison when applied. This will be serialized + * as the non-public class {@link BinaryRelQueryExp} + * with an operation of {@link #EQ}. + */ + public static QueryExp eq(ValueExp v1, ValueExp v2) + { + return new BinaryRelQueryExp(EQ, v1, v2); + } + + /** + * Returns a query expression which checks that an + * attribute value held by the specified + * {@link AttributeValueExp} ends with the string + * specified by the given {@link StringValueExp}. + * + * @param attrib the attribute to match. + * @param string the substring to find. + * @return a query expression representing + * <code>attrib.matches("*" + string)</code>. + * This will be serialized as the non-public class + * {@link MatchQueryExp}. + */ + public static QueryExp finalSubString(AttributeValueExp attrib, + StringValueExp string) + { + return new MatchQueryExp(attrib, "*" + string.getValue()); + } + + /** + * Returns a query expression which evaluates to the result of + * comparing <code>v1</code> to <code>v2</code> to see if + * <code>v1</code> is greater than or equal to <code>v2</code>. + * + * @param v1 the left-hand operand. + * @param v2 the right-hand operand. + * @return a value expression which returns the result of + * the comparison when applied. This will be serialized + * as the non-public class {@link BinaryRelQueryExp} + * with an operation of {@link #GE}. + */ + public static QueryExp geq(ValueExp v1, ValueExp v2) + { + return new BinaryRelQueryExp(GE, v1, v2); + } + + /** + * Returns a query expression which evaluates to the result of + * comparing <code>v1</code> to <code>v2</code> to see if + * <code>v1</code> is greater than <code>v2</code>. + * + * @param v1 the left-hand operand. + * @param v2 the right-hand operand. + * @return a value expression which returns the result of + * the comparison when applied. This will be serialized + * as the non-public class {@link BinaryRelQueryExp} + * with an operation of {@link #GT}. + */ + public static QueryExp gt(ValueExp v1, ValueExp v2) + { + return new BinaryRelQueryExp(GT, v1, v2); + } + + /** + * Returns a query expression representing the constraint + * that the value, <code>v</code>, is a member of the + * list, <code>vlist</code>. + * + * @param v the value to look for in the list. + * @param vlist the list of allowed values. + * @return a query expression representing a membership check + * of <code>v</code> against the list, <code>vlist</code>. + * This will be serialized as the non-public class + * {@link InQueryExp}. + */ + public static QueryExp in(ValueExp v, ValueExp[] vlist) + { + return new InQueryExp(v, vlist); + } + + /** + * Returns a query expression which checks that an + * attribute value held by the specified + * {@link AttributeValueExp} starts with the string + * specified by the given {@link StringValueExp}. + * + * @param attrib the attribute to match. + * @param string the substring to find. + * @return a query expression representing + * <code>attrib.matches(string + "*")</code>. + * This will be serialized as the non-public class + * {@link MatchQueryExp}. + */ + public static QueryExp initialSubString(AttributeValueExp attrib, + StringValueExp string) + { + return new MatchQueryExp(attrib, string.getValue() + "*"); + } + + /** + * Returns a query expression which checks that a + * bean is an instance of the class specified + * by the given {@link StringValueExp}. Associating the + * expression with an {@link ObjectName} involves an underlying + * call to {@link MBeanServer#isInstanceOf(ObjectName, String)} + * using the value of <code>((StringValueExp) + * className.apply(objectName)).getValue()</code> as the + * class name. + * + * @param className the name of the class which the bean + * should be an instance of. + * @return a query expression representing + * the inheritance check. This will be serialized + * as the non-public class {@link InstanceOfQueryExp}. + * @since 1.6 + */ + public static QueryExp isInstanceOf(StringValueExp className) + { + return new InstanceOfQueryExp(className); + } + + /** + * Returns a query expression which evaluates to the result of + * comparing <code>v1</code> to <code>v2</code> to see if + * <code>v1</code> is less than or equal to <code>v2</code>. + * + * @param v1 the left-hand operand. + * @param v2 the right-hand operand. + * @return a value expression which returns the result of + * the comparison when applied. This will be serialized + * as the non-public class {@link BinaryRelQueryExp} + * with an operation of {@link #LE}. + */ + public static QueryExp leq(ValueExp v1, ValueExp v2) + { + return new BinaryRelQueryExp(LE, v1, v2); + } + + /** + * Returns a query expression which evaluates to the result of + * comparing <code>v1</code> to <code>v2</code> to see if + * <code>v1</code> is less than <code>v2</code>. + * + * @param v1 the left-hand operand. + * @param v2 the right-hand operand. + * @return a value expression which returns the result of + * the comparison when applied. This will be serialized + * as the non-public class {@link BinaryRelQueryExp} + * with an operation of {@link #LT}. + */ + public static QueryExp lt(ValueExp v1, ValueExp v2) + { + return new BinaryRelQueryExp(LT, v1, v2); + } + + /** + * <p> + * Returns a query expression which checks that an + * attribute value matches the pattern + * specified by the given {@link StringValueExp}. + * The pattern uses file-globbing syntax: + * </p> + * <ul> + * <li>'*' stands for any number of arbitrary characters.</li> + * <li>'?' stands for a single arbitrary characters.</li> + * <li>An expression within '[' and ']' specify a character + * class.</li> + * <ul> + * <li>A range of characters can be specified by separating + * the start and end character with '-'.</li> + * <li>The complement of the class can be obtained by using + * '!' as the first character of the class.</li> + * <li>'?', '*' and '[' can occur freely within the class. '-' + * may occur as the first or last character. '!' may occur + * normally in any position other than the first. ']' may occur + * as the first element of the class.</li> + * </ul> + * <li>'?', '*' and '[' may be escaped using a backslash + * character, '\'.</li> + * </ul> + * + * @param attrib the attribute to match. + * @param string the substring to find. + * @return a query expression representing the result of + * matching the pattern against the evaluated + * value of the attribute. This will be serialized + * as the non-public class {@link MatchQueryExp}. + */ + public static QueryExp match(AttributeValueExp attrib, + StringValueExp string) + { + return new MatchQueryExp(attrib, string.getValue()); + } + + /** + * Returns a value expression which evaluates to the result of + * subtracting <code>v2</code> from <code>v1</code>. + * + * @param v1 the left-hand operand. + * @param v2 the right-hand operand. + * @return a value expression which returns the result of + * the subtraction when applied. This will be serialized + * as the non-public class {@link BinaryOpValueExp} + * with an operation of {@link #MINUS}. + */ + public static ValueExp minus(ValueExp v1, ValueExp v2) + { + return new BinaryOpValueExp(MINUS, v1, v2); + } + + /** + * Returns a query expression representing the negation + * of the specified query expression. + * + * @param q the query to negate. + * @return a query expression representing the negation of + * <code>q</code>. This will be serialized as the + * non-public class {@link NotQueryExp}. + */ + public static QueryExp not(QueryExp q) + { + return new NotQueryExp(q); + } + + /** + * Returns a query expression formed from the disjunction + * of the two supplied query expressions. + * + * @param q1 the first query expression. + * @param q2 the second query expression. + * @return a query expression representing q1 || q2. This + * will be serialized as the non-public class + * {@link OrQueryExp}. + */ + public static QueryExp or(QueryExp q1, QueryExp q2) + { + return new OrQueryExp(q1, q2); + } + + /** + * Returns a value expression which evaluates to the result of + * adding <code>v1</code> to <code>v2</code>. + * + * @param v1 the left-hand operand. + * @param v2 the right-hand operand. + * @return a value expression which returns the result of + * the addition when applied. This will be serialized + * as the non-public class {@link BinaryOpValueExp} + * with an operation of {@link #PLUS}. + */ + public static ValueExp plus(ValueExp v1, ValueExp v2) + { + return new BinaryOpValueExp(PLUS, v1, v2); + } + + /** + * Returns a value expression which evaluates to the result of + * multiplying <code>v1</code> by <code>v2</code>. + * + * @param v1 the left-hand operand. + * @param v2 the right-hand operand. + * @return a value expression which returns the result of + * the multiplication when applied. This will be serialized + * as the non-public class {@link BinaryOpValueExp} + * with an operation of {@link #TIMES}. + */ + public static ValueExp times(ValueExp v1, ValueExp v2) + { + return new BinaryOpValueExp(TIMES, v1, v2); + } + + /** + * Returns a value expression wrapping the specified value. + * + * @param val the boolean value to wrap. + * @return a value expression wrapping <code>val</code>. This + * will be serialized as the non-public class + * {@link BooleanValueExp}. + */ + public static ValueExp value(boolean val) + { + return new BooleanValueExp(val); + } + + /** + * Returns a value expression wrapping the specified value. + * + * @param val the double value to wrap. + * @return a value expression wrapping <code>val</code>. This + * will be serialized as the non-public class + * {@link NumericValueExp}. + */ + public static ValueExp value(double val) + { + return new NumericValueExp(val); + } + + /** + * Returns a value expression wrapping the specified value. + * + * @param val the float value to wrap. + * @return a value expression wrapping <code>val</code>. This + * will be serialized as the non-public class + * {@link NumericValueExp}. + */ + public static ValueExp value(float val) + { + return new NumericValueExp(val); + } + + /** + * Returns a value expression wrapping the specified value. + * + * @param val the integer value to wrap. + * @return a value expression wrapping <code>val</code>. This + * will be serialized as the non-public class + * {@link NumericValueExp}. + */ + public static ValueExp value(int val) + { + return new NumericValueExp(val); + } + + /** + * Returns a value expression wrapping the specified value. + * + * @param val the long value to wrap. + * @return a value expression wrapping <code>val</code>. This + * will be serialized as the non-public class + * {@link NumericValueExp}. + */ + public static ValueExp value(long val) + { + return new NumericValueExp(val); + } + + /** + * Returns a value expression wrapping the specified value. + * + * @param val the {@link Number} value to wrap. + * @return a value expression wrapping <code>val</code>. This + * will be serialized as the non-public class + * {@link NumericValueExp}. + */ + public static ValueExp value(Number val) + { + return new NumericValueExp(val); + } + + /** + * Returns a value expression wrapping the specified string. + * + * @param val the {@link String} to wrap. + * @return a {@link StringValueExp} wrapping <code>val</code>. + */ + public static StringValueExp value(String val) + { + return new StringValueExp(val); + } + + /** + * Representation of the conjunction formed using + * {@link #and(QueryExp, QueryExp). + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ + private static final class AndQueryExp + extends QueryEval + implements QueryExp + { + + /** + * Compatible with JDK 1.6 + */ + private static final long serialVersionUID = -1081892073854801359L; + + /** + * The first operand. + */ + private QueryExp exp1; + + /** + * The second operand. + */ + private QueryExp exp2; + + /** + * Constructs a new {@link AndQueryExp} using + * the two specified operands. + * + * @param exp1 the first query expression. + * @param exp2 the second query expression. + */ + public AndQueryExp(QueryExp exp1, QueryExp exp2) + { + this.exp1 = exp1; + this.exp2 = exp2; + } + + /** + * Returns the conjunction of the two query + * expressions. + * + * @param name the {@link ObjectName} to apply + * the query to. + * @return the conjunction of applying the name + * to both operands. + * @throws BadStringOperationException if an invalid string + * operation is used by + * the query. + * @throws BadBinaryOpValueExpException if an invalid expression + * is used by the query. + * @throws BadAttributeValueExpException if an invalid attribute + * is used by the query. + * @throws InvalidApplicationException if the query is applied + * to the wrong type of bean. + */ + public boolean apply(ObjectName name) + throws BadStringOperationException, BadBinaryOpValueExpException, + BadAttributeValueExpException, InvalidApplicationException + { + return exp1.apply(name) && exp2.apply(name); + } + + } + + /** + * Representation of a query that matches an + * attribute's value against a given pattern. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ + private static final class MatchQueryExp + extends QueryEval + implements QueryExp + { + + /** + * Compatible with JDK 1.6 + */ + private static final long serialVersionUID = -7156603696948215014L; + + /** + * The attribute to match against. + */ + private AttributeValueExp exp; + + /** + * The pattern to be matched. + */ + private String pattern; + + /** + * Constructs a new {@link MatchQueryExp} using + * the specified attribute value and pattern. + * + * @param exp the attribute value expression. + * @param pattern the pattern. + */ + public MatchQueryExp(AttributeValueExp exp, + String pattern) + { + this.exp = exp; + this.pattern = pattern; + } + + /** + * Returns the result of matching the attribute + * value against the pattern. + * + * @param name the {@link ObjectName} to apply + * the query to. + * @return the result of the match. + * @throws BadStringOperationException if an invalid string + * operation is used by + * the query. + * @throws BadBinaryOpValueExpException if an invalid expression + * is used by the query. + * @throws BadAttributeValueExpException if an invalid attribute + * is used by the query. + * @throws InvalidApplicationException if the query is applied + * to the wrong type of bean. + */ + public boolean apply(ObjectName name) + throws BadStringOperationException, BadBinaryOpValueExpException, + BadAttributeValueExpException, InvalidApplicationException + { + String val = ((StringValueExp) exp.apply(name)).getValue(); + int valPos = 0; + int fallback = -1; + int fallbackP = -1; + boolean backslash = false; + for (int a = 0; a < pattern.length(); ++a) + { + boolean matched = false; + int next = pattern.codePointAt(a); + if (!backslash) + { + if (next == '?' && valPos < val.length()) + { + ++valPos; + matched = true; + } + else if (next == '*') + { + fallback = valPos; + fallbackP = a; + matched = true; + } + else if (next == '[' && valPos < val.length()) + { + boolean negated = false; + int b = a + 1; + int classChar = pattern.codePointAt(b); + do + { + if (classChar == '!' && b == a + 1) + negated = true; + else if (pattern.codePointAt(b + 1) == '-' && + pattern.codePointAt(b + 2) != ']') + { + if (classChar > pattern.codePointAt(b + 2)) + throw new BadStringOperationException("Invalid range: " + + classChar + " to " + + pattern.codePointAt(b+2)); + for (int c = classChar; c <= pattern.codePointAt(b+2); ++c) + if (val.codePointAt(valPos) == c) + matched = true; + b = b + 2; + } + else if (val.codePointAt(valPos) == classChar) + matched = true; + ++b; + classChar = pattern.codePointAt(b); + } while (classChar != ']'); + if (negated) + matched = !matched; + ++valPos; + a = b; + } + else if (next == '\\') + backslash = true; + else if (valPos < val.length() && next == val.codePointAt(valPos)) + { + matched = true; + ++valPos; + } + } + else + { + backslash = false; + if (valPos < val.length() && next == val.codePointAt(valPos)) + { + matched = true; + ++valPos; + } + } + if (!matched) + if (fallback != -1) + { + ++fallback; + valPos = fallback; + a = fallbackP; + if (valPos == val.length()) + return false; + continue; + } + else + return false; + } + return true; + } + } + + /** + * Representation of the retrieval of an attribute + * value from a certain class for {@link #attr(String,String)}. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ + private static final class QualifiedAttributeValueExp + extends AttributeValueExp + { + + /** + * Compatible with JDK 1.6 + */ + private static final long serialVersionUID = 8832517277410933254L; + + /** + * The name of the class from which the attribute is taken. + */ + private String className; + + /** + * Constructs a new {@link QualifiedAttributeValueExp} using + * the specified class name and attribute name. + * + * @param className the class name. + * @param name the attribute name. + */ + public QualifiedAttributeValueExp(String className, String name) + { + super(name); + this.className = className; + } + + /** + * Applies the {@link AttributeValueExp} to the specified + * management bean by checking that the attribute will be + * obtained from the correct class (by a class to + * {@link MBeanServer#getObjectInstance(ObjectName)} and + * then obtaining the attribute value from the + * {@link MBeanServer}, using it to create a + * {@link StringValueExp}. + * + * @param name the {@link ObjectName} of the bean to obtain + * the value from. + * @return a {@link StringValueExp} containing the result. + * @throws BadStringOperationException if an invalid string + * operation is used by + * the value expression. + * @throws BadBinaryOpValueExpException if an invalid expression + * is used by the value expression. + * @throws BadAttributeValueExpException if an invalid attribute + * is used by the value expression. + * @throws InvalidApplicationException if the value expression is applied + * to the wrong type of bean. + */ + public ValueExp apply(ObjectName name) + throws BadStringOperationException, BadBinaryOpValueExpException, + BadAttributeValueExpException, InvalidApplicationException + { + try + { + if (!(QueryEval.getMBeanServer().getObjectInstance(name).getClassName().equals(className))) + throw new BadAttributeValueExpException("The value is not from " + + "the correct class."); + } + catch (InstanceNotFoundException e) + { + throw (BadAttributeValueExpException) + new BadAttributeValueExpException("The named bean is not registered.").initCause(e); + } + return super.apply(name); + } + + } + + /** + * Representation of the comparison of a value with + * a pair of bounds formed using + * {@link #between(ValueExp, ValueExp, ValueExp). + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ + private static final class BetweenQueryExp + extends QueryEval + implements QueryExp + { + + /** + * Compatible with JDK 1.6 + */ + private static final long serialVersionUID = -2933597532866307444L; + + /** + * The value to compare. + */ + private ValueExp exp1; + + /** + * The lower boundary. + */ + private ValueExp exp2; + + /** + * The upper boundary. + */ + private ValueExp exp3; + + /** + * Constructs a new {@link BetweenQueryExp} using + * the specified comparison value and the given + * bounds. + * + * @param exp1 the value to compare. + * @param exp2 the lower bound. + * @param exp3 the upper bound. + */ + public BetweenQueryExp(ValueExp exp1, ValueExp exp2, + ValueExp exp3) + { + this.exp1 = exp1; + this.exp2 = exp2; + this.exp3 = exp3; + } + + /** + * Returns the result of the comparison between + * the value and the two bounds. + * + * @param name the {@link ObjectName} to apply + * the query to. + * @return the result of the comparison. + * @throws BadStringOperationException if an invalid string + * operation is used by + * the query. + * @throws BadBinaryOpValueExpException if an invalid expression + * is used by the query. + * @throws BadAttributeValueExpException if an invalid attribute + * is used by the query. + * @throws InvalidApplicationException if the query is applied + * to the wrong type of bean. + */ + public boolean apply(ObjectName name) + throws BadStringOperationException, BadBinaryOpValueExpException, + BadAttributeValueExpException, InvalidApplicationException + { + String v1 = exp1.apply(name).toString(); + String v2 = exp2.apply(name).toString(); + String v3 = exp3.apply(name).toString(); + return v1.compareTo(v2) >= 0 && v1.compareTo(v3) <= 0; + } + + } + + /** + * Representation of the retrieval of the name of + * a bean's class for {@link #classattr()}. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ + private static final class ClassAttributeValueExp + extends AttributeValueExp + { + + /** + * Compatible with JDK 1.6 + */ + private static final long serialVersionUID = -1081892073854801359L; + + /** + * Obtains the name of the specified bean's class using a call + * to {@link MBeanServer#getObjectInstance(ObjectName)}. + * + * @param name the {@link ObjectName} of the bean to obtain + * the class name from. + * @return a {@link StringValueExp} containing the result. + * @throws BadStringOperationException if an invalid string + * operation is used by + * the value expression. + * @throws BadBinaryOpValueExpException if an invalid expression + * is used by the value expression. + * @throws BadAttributeValueExpException if an invalid attribute + * is used by the value expression. + * @throws InvalidApplicationException if the value expression is applied + * to the wrong type of bean. + */ + public ValueExp apply(ObjectName name) + throws BadStringOperationException, BadBinaryOpValueExpException, + BadAttributeValueExpException, InvalidApplicationException + { + try + { + return new StringValueExp(QueryEval.getMBeanServer().getObjectInstance(name).getClassName()); + } + catch (InstanceNotFoundException e) + { + throw (BadAttributeValueExpException) + new BadAttributeValueExpException("The named bean is not registered.").initCause(e); + } + } + + } + + /** + * Representation of a binary operation formed using + * {@link #div(ValueExp, ValueExp), {@link #plus(ValueExp,ValueExp)}, + * {@link #minus(ValueExp, ValueExp) or + * {@link #times(ValueExp, ValueExp)}. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ + private static final class BinaryOpValueExp + extends QueryEval + implements ValueExp + { + + /** + * Compatible with JDK 1.6 + */ + private static final long serialVersionUID = 1216286847881456786L; + + /** + * The operation to perform. + */ + private int op; + + /** + * The left-hand operand. + */ + private ValueExp exp1; + + /** + * The right-hand operand. + */ + private ValueExp exp2; + + /** + * Constructs a new {@link BinaryOpValueExp} using + * the specified operation and the two values supplied. + * + * @param op the operation to perform. + * @param exp1 the left-hand operand. + * @param exp2 the right-hand operand. + */ + public BinaryOpValueExp(int op, ValueExp exp1, ValueExp exp2) + { + this.op = op; + this.exp1 = exp1; + this.exp2 = exp2; + } + + /** + * Returns the result of performing the operation on + * <code>exp1</code> and <code>exp2</code>. + * + * @param name the {@link ObjectName} to apply + * the query to. + * @return the result of the operation. + * @throws BadStringOperationException if an invalid string + * operation is used by + * the query. + * @throws BadBinaryOpValueExpException if an invalid expression + * is used by the query. + * @throws BadAttributeValueExpException if an invalid attribute + * is used by the query. + * @throws InvalidApplicationException if the query is applied + * to the wrong type of bean. + */ + public ValueExp apply(ObjectName name) + throws BadStringOperationException, BadBinaryOpValueExpException, + BadAttributeValueExpException, InvalidApplicationException + { + NumericValueExp v1 = (NumericValueExp) exp1.apply(name); + NumericValueExp v2 = (NumericValueExp) exp2.apply(name); + switch (op) + { + case PLUS: + return v1.plus(v2); + case MINUS: + return v1.minus(v2); + case TIMES: + return v1.times(v2); + case DIV: + return v1.div(v2); + default: + throw new BadBinaryOpValueExpException(this); + } + } + + /** + * Returns a textual representation of the operation. + * + * @return a textual version of the operation. + */ + public String toString() + { + String opS; + switch (op) + { + case PLUS: + opS = "+"; + break; + case MINUS: + opS = "-"; + break; + case TIMES: + opS = "x"; + break; + case DIV: + opS = "/"; + break; + default: + opS = "?"; + } + return exp1 + " " + opS + " " + exp2; + } + } + + /** + * Representation of a binary operation formed using + * {@link #eq(ValueExp, ValueExp), {@link #geq(ValueExp, ValueExp)}, + * {@link #leq(ValueExp, ValueExp), {@link #gt(ValueExp, ValueExp)} + * or {@link #lt(ValueExp, ValueExp)}. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ + private static final class BinaryRelQueryExp + extends QueryEval + implements QueryExp + { + + /** + * Compatible with JDK 1.6 + */ + private static final long serialVersionUID = -5690656271650491000L; + + /** + * The operation to perform. + */ + private int relOp; + + /** + * The left-hand operand. + */ + private ValueExp exp1; + + /** + * The right-hand operand. + */ + private ValueExp exp2; + + /** + * Constructs a new {@link BinaryRelQueryExp} using + * the specified operation and the two values supplied. + * + * @param relOp the operation to perform. + * @param exp1 the left-hand operand. + * @param exp2 the right-hand operand. + */ + public BinaryRelQueryExp(int relOp, ValueExp exp1, ValueExp exp2) + { + this.relOp = relOp; + this.exp1 = exp1; + this.exp2 = exp2; + } + + /** + * Returns the result of performing the operation on + * <code>exp1</code> and <code>exp2</code>. + * + * @param name the {@link ObjectName} to apply + * the query to. + * @return the result of the comparison. + * @throws BadStringOperationException if an invalid string + * operation is used by + * the query. + * @throws BadBinaryOpValueExpException if an invalid expression + * is used by the query. + * @throws BadAttributeValueExpException if an invalid attribute + * is used by the query. + * @throws InvalidApplicationException if the query is applied + * to the wrong type of bean. + */ + public boolean apply(ObjectName name) + throws BadStringOperationException, BadBinaryOpValueExpException, + BadAttributeValueExpException, InvalidApplicationException + { + String v1 = exp1.apply(name).toString(); + String v2 = exp2.apply(name).toString(); + switch (relOp) + { + case EQ: + return v1.equals(v2); + case GT: + return v1.compareTo(v2) > 0; + case GE: + return v1.compareTo(v2) >= 0; + case LE: + return v1.compareTo(v2) <= 0; + case LT: + return v1.compareTo(v2) < 0; + default: + throw new BadStringOperationException("Invalid operator: " + relOp); + } + } + + /** + * Returns a textual representation of the operation. + * + * @return a textual version of the operation. + */ + public String toString() + { + String op; + switch (relOp) + { + case EQ: + op = "="; + break; + case GT: + op = ">"; + break; + case GE: + op = ">="; + break; + case LE: + op = "<="; + break; + case LT: + op = "<"; + break; + default: + op = "?"; + } + return exp1 + " " + op + " " + exp2; + } + } + + /** + * Representation of the comparison of a value with + * the members of a list formed using + * {@link #in(ValueExp, ValueExp[]). + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ + private static final class InQueryExp + extends QueryEval + implements QueryExp + { + + /** + * Compatible with JDK 1.6 + */ + private static final long serialVersionUID = -5801329450358952434L; + + /** + * The value to look for. + */ + private ValueExp val; + + /** + * The array to search. + */ + private ValueExp[] valueList; + + /** + * Constructs a new {@link InQueryExp} using + * the specified comparison value and the given + * list. + * + * @param val the value to compare. + * @param valueList the list of values. + */ + public InQueryExp(ValueExp val, ValueExp[] valueList) + { + this.val = val; + this.valueList = valueList; + } + + /** + * Returns the result of the comparison between + * the value and the list of allowed values. + * + * @param name the {@link ObjectName} to apply + * the query to. + * @return the result of the comparison. + * @throws BadStringOperationException if an invalid string + * operation is used by + * the query. + * @throws BadBinaryOpValueExpException if an invalid expression + * is used by the query. + * @throws BadAttributeValueExpException if an invalid attribute + * is used by the query. + * @throws InvalidApplicationException if the query is applied + * to the wrong type of bean. + */ + public boolean apply(ObjectName name) + throws BadStringOperationException, BadBinaryOpValueExpException, + BadAttributeValueExpException, InvalidApplicationException + { + String v = val.apply(name).toString(); + for (ValueExp vl : valueList) + if (v.equals(vl.apply(name).toString())) + return true; + return false; + } + + } + + /** + * Representation of the inheritance check on a + * bean for {@link #isInstanceOf(StringValueExp)}. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.6 + */ + private static final class InstanceOfQueryExp + extends QueryEval + implements QueryExp + { + + /** + * Compatible with JDK 1.6 + */ + private static final long serialVersionUID = -1081892073854801359L; + + /** + * The name of the class from which the attribute is taken. + */ + private StringValueExp classNameValue; + + /** + * Constructs a new {@link InstanceOfQueryExp} using + * the specified class name. + * + * @param classNameValue the class name. + */ + public InstanceOfQueryExp(StringValueExp classNameValue) + { + this.classNameValue = classNameValue; + } + + /** + * Checks that the bean specified by the supplied + * {@link ObjectName} is of the correct class + * using {@link MBeanServer#isInstanceOf(ObjectName,String)}. + * where the string is obtained by evaluating + * <code>classNameValue</code>. + * + * @param name the {@link ObjectName} of the bean to obtain + * the value from. + * @return true if the bean is an instance of the class. + * @throws BadStringOperationException if an invalid string + * operation is used by + * the value expression. + * @throws BadBinaryOpValueExpException if an invalid expression + * is used by the value expression. + * @throws BadAttributeValueExpException if an invalid attribute + * is used by the value expression. + * @throws InvalidApplicationException if the value expression is applied + * to the wrong type of bean. + */ + public boolean apply(ObjectName name) + throws BadStringOperationException, BadBinaryOpValueExpException, + BadAttributeValueExpException, InvalidApplicationException + { + try + { + String className = ((StringValueExp) + classNameValue.apply(name)).getValue(); + return QueryEval.getMBeanServer().isInstanceOf(name, className); + } + catch (InstanceNotFoundException e) + { + throw (BadAttributeValueExpException) + new BadAttributeValueExpException("The named bean is not registered.").initCause(e); + } + } + + } + + /** + * Representation of the negation of a query formed using + * {@link #not(QueryExp). + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ + private static final class NotQueryExp + extends QueryEval + implements QueryExp + { + + /** + * Compatible with JDK 1.6 + */ + private static final long serialVersionUID = 5269643775896723397L; + + /** + * The expression to negate. + */ + private QueryExp exp; + + /** + * Constructs a new {@link NotQueryExp} using + * the specified query expression. + * + * @param exp the expression to negate. + */ + public NotQueryExp(QueryExp exp) + { + this.exp = exp; + } + + /** + * Returns the result of the negation. + * + * @param name the {@link ObjectName} to apply + * the query to. + * @return the result of the negation. + * @throws BadStringOperationException if an invalid string + * operation is used by + * the query. + * @throws BadBinaryOpValueExpException if an invalid expression + * is used by the query. + * @throws BadAttributeValueExpException if an invalid attribute + * is used by the query. + * @throws InvalidApplicationException if the query is applied + * to the wrong type of bean. + */ + public boolean apply(ObjectName name) + throws BadStringOperationException, BadBinaryOpValueExpException, + BadAttributeValueExpException, InvalidApplicationException + { + return !(exp.apply(name)); + } + + } + + /** + * Representation of the disjunction formed using + * {@link #or(QueryExp, QueryExp). + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ + private static final class OrQueryExp + extends QueryEval + implements QueryExp + { + + /** + * Compatible with JDK 1.6 + */ + private static final long serialVersionUID = 2962973084421716523L; + + /** + * The first operand. + */ + private QueryExp exp1; + + /** + * The second operand. + */ + private QueryExp exp2; + + /** + * Constructs a new {@link OrQueryExp} using + * the two specified operands. + * + * @param exp1 the first query expression. + * @param exp2 the second query expression. + */ + public OrQueryExp(QueryExp exp1, QueryExp exp2) + { + this.exp1 = exp1; + this.exp2 = exp2; + } + + /** + * Returns the disjunction of the two query + * expressions. + * + * @param name the {@link ObjectName} to apply + * the query to. + * @return the disjunction of applying the name + * to both operands. + * @throws BadStringOperationException if an invalid string + * operation is used by + * the query. + * @throws BadBinaryOpValueExpException if an invalid expression + * is used by the query. + * @throws BadAttributeValueExpException if an invalid attribute + * is used by the query. + * @throws InvalidApplicationException if the query is applied + * to the wrong type of bean. + */ + public boolean apply(ObjectName name) + throws BadStringOperationException, BadBinaryOpValueExpException, + BadAttributeValueExpException, InvalidApplicationException + { + return exp1.apply(name) || exp2.apply(name); + } + + } + + /** + * Representation of a boolean being used as an argument + * to a relational constraint, formed using + * {@link #value(boolean)}. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ + private static final class BooleanValueExp + extends QueryEval + implements ValueExp + { + + /** + * Compatible with JDK 1.6 + */ + private static final long serialVersionUID = 7754922052666594581L; + + /** + * The boolean value. + */ + private boolean val; + + /** + * Constructs a new {@link BooleanValueExp} using the + * specified value. + * + * @param val the boolean value used for this expression. + */ + public BooleanValueExp(boolean val) + { + this.val = val; + } + + /** + * Applies the {@link BooleanValueExp} to the specified + * management bean by simply returning the value. + * + * @param name the {@link ObjectName} of the bean. + * @return the {@link BooleanValueExp} itself. + * @throws BadStringOperationException if an invalid string + * operation is used by + * the value expression. + * @throws BadBinaryOpValueExpException if an invalid expression + * is used by the value expression. + * @throws BadAttributeValueExpException if an invalid attribute + * is used by the value expression. + * @throws InvalidApplicationException if the value expression is applied + * to the wrong type of bean. + */ + public ValueExp apply(ObjectName name) + throws BadStringOperationException, BadBinaryOpValueExpException, + BadAttributeValueExpException, InvalidApplicationException + { + return this; + } + + /** + * Returns the value as a string. + * + * @return the value in textual form. + */ + public String toString() + { + return Boolean.toString(val); + } + + } + + /** + * Representation of a number being used as an argument + * to a relational constraint, formed using + * {@link #value(double)}, {@link #value(float)}, + * {@link #value(int)}, {@link #value(long)} or + * {@link #value(Number)}. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ + private static final class NumericValueExp + extends QueryEval + implements ValueExp + { + + /** + * Compatible with JDK 1.6 + */ + private static final long serialVersionUID = -4679739485102359104L; + + /** + * The numeric value. + */ + private Number val; + + /** + * Constructs a new {@link NumericValueExp} using the + * specified value. + * + * @param val the numeric value used for this expression. + */ + public NumericValueExp(Number val) + { + this.val = val; + } + + /** + * Applies the {@link NumericValueExp} to the specified + * management bean by simply returning the value. + * + * @param name the {@link ObjectName} of the bean. + * @return the {@link NumericValueExp} itself. + * @throws BadStringOperationException if an invalid string + * operation is used by + * the value expression. + * @throws BadBinaryOpValueExpException if an invalid expression + * is used by the value expression. + * @throws BadAttributeValueExpException if an invalid attribute + * is used by the value expression. + * @throws InvalidApplicationException if the value expression is applied + * to the wrong type of bean. + */ + public ValueExp apply(ObjectName name) + throws BadStringOperationException, BadBinaryOpValueExpException, + BadAttributeValueExpException, InvalidApplicationException + { + return this; + } + + /** + * Returns the value. + */ + public Number getValue() + { + return val; + } + + /** + * Returns the value as a string. + * + * @return the value in textual form. + */ + public String toString() + { + return val.toString(); + } + + /** + * Return the result of adding the specified + * {@link NumericValueExp} to this one. + * + * @param o the value to add. + * @return the result of the addition. + */ + public NumericValueExp plus(NumericValueExp o) + { + Number v = o.getValue(); + if (val instanceof Double) + { + double d = val.doubleValue(); + if (v instanceof Double) + return new NumericValueExp(d + v.doubleValue()); + else if (v instanceof Float) + return new NumericValueExp(d + v.floatValue()); + else if (v instanceof Long) + return new NumericValueExp(d + v.longValue()); + else + return new NumericValueExp(d + v.intValue()); + } + else if (val instanceof Float) + { + float f = val.floatValue(); + if (v instanceof Double) + return new NumericValueExp(f + v.doubleValue()); + else if (v instanceof Float) + return new NumericValueExp(f + v.floatValue()); + else if (v instanceof Long) + return new NumericValueExp(f + v.longValue()); + else + return new NumericValueExp(f + v.intValue()); + } + else if (val instanceof Long) + { + long l = val.longValue(); + if (v instanceof Double) + return new NumericValueExp(l + v.doubleValue()); + else if (v instanceof Float) + return new NumericValueExp(l + v.floatValue()); + else if (v instanceof Long) + return new NumericValueExp(l + v.longValue()); + else + return new NumericValueExp(l + v.intValue()); + } + int i = val.intValue(); + if (v instanceof Double) + return new NumericValueExp(i + v.doubleValue()); + else if (v instanceof Float) + return new NumericValueExp(i + v.floatValue()); + else if (v instanceof Long) + return new NumericValueExp(i + v.longValue()); + else + return new NumericValueExp(i + v.intValue()); + } + + /** + * Return New NumericValueExp(the result of subtracting the specified + * {@link NumericValueExp} from this one. + * + * @param o the value to subtract. + * @return new NumericValueExp(the result of the subtraction. + */ + public NumericValueExp minus(NumericValueExp o) + { + Number v = o.getValue(); + if (val instanceof Double) + { + double d = val.doubleValue(); + if (v instanceof Double) + return new NumericValueExp(d - v.doubleValue()); + else if (v instanceof Float) + return new NumericValueExp(d - v.floatValue()); + else if (v instanceof Long) + return new NumericValueExp(d - v.longValue()); + else + return new NumericValueExp(d - v.intValue()); + } + else if (val instanceof Float) + { + float f = val.floatValue(); + if (v instanceof Double) + return new NumericValueExp(f - v.doubleValue()); + else if (v instanceof Float) + return new NumericValueExp(f - v.floatValue()); + else if (v instanceof Long) + return new NumericValueExp(f - v.longValue()); + else + return new NumericValueExp(f - v.intValue()); + } + else if (val instanceof Long) + { + long l = val.longValue(); + if (v instanceof Double) + return new NumericValueExp(l - v.doubleValue()); + else if (v instanceof Float) + return new NumericValueExp(l - v.floatValue()); + else if (v instanceof Long) + return new NumericValueExp(l - v.longValue()); + else + return new NumericValueExp(l - v.intValue()); + } + int i = val.intValue(); + if (v instanceof Double) + return new NumericValueExp(i - v.doubleValue()); + else if (v instanceof Float) + return new NumericValueExp(i - v.floatValue()); + else if (v instanceof Long) + return new NumericValueExp(i - v.longValue()); + else + return new NumericValueExp(i - v.intValue()); + } + + /** + * Return New NumericValueExp(the result of multiplying the specified + * {@link NumericValueExp} to this one. + * + * @param o the value to multiply by. + * @return new NumericValueExp(the result of the multiplication. + */ + public NumericValueExp times(NumericValueExp o) + { + Number v = o.getValue(); + if (val instanceof Double) + { + double d = val.doubleValue(); + if (v instanceof Double) + return new NumericValueExp(d * v.doubleValue()); + else if (v instanceof Float) + return new NumericValueExp(d * v.floatValue()); + else if (v instanceof Long) + return new NumericValueExp(d * v.longValue()); + else + return new NumericValueExp(d * v.intValue()); + } + else if (val instanceof Float) + { + float f = val.floatValue(); + if (v instanceof Double) + return new NumericValueExp(f * v.doubleValue()); + else if (v instanceof Float) + return new NumericValueExp(f * v.floatValue()); + else if (v instanceof Long) + return new NumericValueExp(f * v.longValue()); + else + return new NumericValueExp(f * v.intValue()); + } + else if (val instanceof Long) + { + long l = val.longValue(); + if (v instanceof Double) + return new NumericValueExp(l * v.doubleValue()); + else if (v instanceof Float) + return new NumericValueExp(l * v.floatValue()); + else if (v instanceof Long) + return new NumericValueExp(l * v.longValue()); + else + return new NumericValueExp(l * v.intValue()); + } + int i = val.intValue(); + if (v instanceof Double) + return new NumericValueExp(i * v.doubleValue()); + else if (v instanceof Float) + return new NumericValueExp(i * v.floatValue()); + else if (v instanceof Long) + return new NumericValueExp(i * v.longValue()); + else + return new NumericValueExp(i * v.intValue()); + } + + /** + * Return New NumericValueExp(the result of dividing this + * number by value of the specified + * {@link NumericValueExp}. + * + * @param o the value to divide by. + * @return new NumericValueExp(the result of the division. + */ + public NumericValueExp div(NumericValueExp o) + { + Number v = o.getValue(); + if (val instanceof Double) + { + double d = val.doubleValue(); + if (v instanceof Double) + return new NumericValueExp(d / v.doubleValue()); + else if (v instanceof Float) + return new NumericValueExp(d / v.floatValue()); + else if (v instanceof Long) + return new NumericValueExp(d / v.longValue()); + else + return new NumericValueExp(d / v.intValue()); + } + else if (val instanceof Float) + { + float f = val.floatValue(); + if (v instanceof Double) + return new NumericValueExp(f / v.doubleValue()); + else if (v instanceof Float) + return new NumericValueExp(f / v.floatValue()); + else if (v instanceof Long) + return new NumericValueExp(f / v.longValue()); + else + return new NumericValueExp(f / v.intValue()); + } + else if (val instanceof Long) + { + long l = val.longValue(); + if (v instanceof Double) + return new NumericValueExp(l / v.doubleValue()); + else if (v instanceof Float) + return new NumericValueExp(l / v.floatValue()); + else if (v instanceof Long) + return new NumericValueExp(l / v.longValue()); + else + return new NumericValueExp(l / v.intValue()); + } + int i = val.intValue(); + if (v instanceof Double) + return new NumericValueExp(i / v.doubleValue()); + else if (v instanceof Float) + return new NumericValueExp(i / v.floatValue()); + else if (v instanceof Long) + return new NumericValueExp(i / v.longValue()); + else + return new NumericValueExp(i / v.intValue()); + } + + } + +} diff --git a/libjava/classpath/javax/management/QueryEval.java b/libjava/classpath/javax/management/QueryEval.java new file mode 100644 index 000000000..0b9df6155 --- /dev/null +++ b/libjava/classpath/javax/management/QueryEval.java @@ -0,0 +1,95 @@ +/* QueryEval.java -- An evaluation context for a MBean server query. + Copyright (C) 2007 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package javax.management; + +import java.io.Serializable; + +/** + * Represents the evaluation context of a {@link MBeanServer} + * query by retaining the server used on a thread-by-thread + * basis. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public class QueryEval + implements Serializable +{ + + /** + * Compatible with JDK 1.5 + */ + private static final long serialVersionUID = 2675899265640874796L; + + /** + * Stores the server used, on a + * thread-by-thread basis. + */ + private static InheritableThreadLocal<MBeanServer> server = + new InheritableThreadLocal<MBeanServer>(); + + /** + * Returns the {@link MBeanServer} last supplied to the + * {@link #setMBeanServer(MBeanServer)} method. If this method + * has not been called for this thread, then the value will be + * inherited from any parent thread on which the method has + * been called. If the method has never been called, then + * <code>null</code> is returned. + * + * @return the server. + * @see #setMBeanServer(MBeanServer) + */ + public static MBeanServer getMBeanServer() + { + return server.get(); + } + + /** + * Sets the {@link MBeanServer} on which the query will be + * performed. This value is inherited automatically by + * child threads. This method is only non-static for historical + * reasons; it makes no use of instance-related values. + * + * @param svr the server to use. + */ + public void setMBeanServer(MBeanServer svr) + { + server.set(svr); + } + +} diff --git a/libjava/classpath/javax/management/QueryExp.java b/libjava/classpath/javax/management/QueryExp.java new file mode 100644 index 000000000..778e28f5e --- /dev/null +++ b/libjava/classpath/javax/management/QueryExp.java @@ -0,0 +1,86 @@ +/* QueryExp.java -- Represents a query expression. + Copyright (C) 2006 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; + +/** + * Applies the type of relational constraints seen in the + * <code>where</code> clauses of databases to an + * {@link ObjectName}. Instances of this class are usually + * returned by the static methods of the {@link Query} classes. + * If a custom implementation is required, it is better to + * extend the {@link QueryEval} class, rather than simply + * implementing this interface, in order to ensure that + * the {@link #setMBeanServer(MBeanServer)} method functions + * correctly. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public interface QueryExp + extends Serializable +{ + + /** + * Applies the query to the specified management bean. + * + * @param name the name of the management bean. + * @return true if the query was applied successfully. + * @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. + */ + boolean apply(ObjectName name) + throws BadStringOperationException, BadBinaryOpValueExpException, + BadAttributeValueExpException, InvalidApplicationException; + + /** + * Changes the {@link MBeanServer} on which this query is performed. + * + * @param server the new server to use. + */ + void setMBeanServer(MBeanServer server); + +} diff --git a/libjava/classpath/javax/management/ReflectionException.java b/libjava/classpath/javax/management/ReflectionException.java new file mode 100644 index 000000000..96b4ea526 --- /dev/null +++ b/libjava/classpath/javax/management/ReflectionException.java @@ -0,0 +1,117 @@ +/* ReflectionException.java -- A reflection-based management exception. + Copyright (C) 2006 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 one of the reflection exceptions thrown by a + * management bean. When a management bean tries to perform + * a lookup using the reflection API and encounters an exception, + * it gets wrapped inside an {@link ReflectionException}. + * Calling {@link getTargetException()} will return the wrapped + * exception. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public class ReflectionException + extends JMException +{ + + /** + * Compatible with JDK 1.5 + */ + private static final long serialVersionUID = 9170809325636915553L; + + /* Sun re-implemented causality -- don't know why, but + serialization demands we do too... */ + + /** + * The target exception. + * + * @serial the target exception. + */ + private Exception exception; + + /** + * Constructs a new <code>ReflectionException</code> wrapping + * the specified exception. + * + * @param e the exception to be wrapped. + */ + public ReflectionException(Exception e) + { + super(); + exception = e; + } + + /** + * Constructs a new <code>ReflectionException</code> wrapping + * the specified exception and using the supplied message. + * + * @param e the exception to be wrapped. + * @param message the error message to give to the user. + */ + public ReflectionException(Exception e, String message) + { + super(message); + exception = e; + } + + /** + * Returns the true cause of this exception, the wrapped + * exception. + * + * @return the wrapped exception. + */ + public Throwable getCause() + { + return exception; + } + + /** + * Returns the true cause of this exception, the wrapped + * exception. + * + * @return the wrapped exception. + */ + public Exception getTargetException() + { + return exception; + } + +} diff --git a/libjava/classpath/javax/management/RuntimeErrorException.java b/libjava/classpath/javax/management/RuntimeErrorException.java new file mode 100644 index 000000000..f361a2c1c --- /dev/null +++ b/libjava/classpath/javax/management/RuntimeErrorException.java @@ -0,0 +1,114 @@ +/* RuntimeErrorException.java -- A user-defined management error. + Copyright (C) 2006 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package javax.management; + +/** + * Represents an arbitrary error thrown by a management + * bean. When a management bean executes code that causes + * an error to be thrown, the resulting error is + * wrapped inside an {@link RuntimeErrorException}. Calling + * {@link getTargetError()} will return the wrapped + * exception. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public class RuntimeErrorException + extends JMRuntimeException +{ + + /** + * Compatible with JDK 1.5 + */ + private static final long serialVersionUID = 704338937753949796L; + + /** + * The target error. + * + * @serial the target error. + */ + private Error error; + + /** + * Constructs a new <code>RuntimeErrorException</code> wrapping + * the specified error. + * + * @param e the error to be wrapped. + */ + public RuntimeErrorException(Error e) + { + super(); + error = e; + } + + /** + * Constructs a new <code>RuntimeErrorException</code> wrapping + * the specified error and using the supplied message. + * + * @param e the error to be wrapped. + * @param message the error message to give to the user. + */ + public RuntimeErrorException(Error e, String message) + { + super(message); + error = e; + } + + /** + * Returns the true cause of this error, the wrapped + * error. + * + * @return the wrapped error. + */ + public Throwable getCause() + { + return error; + } + + /** + * Returns the true cause of this error, the wrapped + * error. + * + * @return the wrapped error. + */ + public Error getTargetError() + { + return error; + } + +} diff --git a/libjava/classpath/javax/management/RuntimeMBeanException.java b/libjava/classpath/javax/management/RuntimeMBeanException.java new file mode 100644 index 000000000..1c8b242b5 --- /dev/null +++ b/libjava/classpath/javax/management/RuntimeMBeanException.java @@ -0,0 +1,113 @@ +/* RuntimeMBeanException.java -- A user-defined management exception. + Copyright (C) 2006 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package javax.management; + +/** + * Represents an arbitrary runtime exception thrown by a management + * bean. When a management bean executes code that causes a runtime + * exception to be thrown, the resulting exception is wrapped inside a + * {@link RuntimeMBeanException}. Calling {@link + * getTargetException()} will return the wrapped exception. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public class RuntimeMBeanException + extends JMRuntimeException +{ + + /** + * Compatible with JDK 1.5 + */ + private static final long serialVersionUID = 5274912751982730171L; + + /** + * The target exception. + * + * @serial the target exception. + */ + private RuntimeException runtimeException; + + /** + * Constructs a new <code>RuntimeMBeanException</code> wrapping + * the specified exception. + * + * @param e the exception to be wrapped. + */ + public RuntimeMBeanException(RuntimeException e) + { + super(); + runtimeException = e; + } + + /** + * Constructs a new <code>RuntimeMBeanException</code> wrapping + * the specified exception and using the supplied message. + * + * @param e the exception to be wrapped. + * @param message the error message to give to the user. + */ + public RuntimeMBeanException(RuntimeException e, String message) + { + super(message); + runtimeException = e; + } + + /** + * Returns the true cause of this exception, the wrapped runtime + * exception. + * + * @return the wrapped exception. + */ + public Throwable getCause() + { + return runtimeException; + } + + /** + * Returns the true cause of this exception, the wrapped runtime + * exception. + * + * @return the wrapped exception. + */ + public RuntimeException getTargetException() + { + return runtimeException; + } + +} diff --git a/libjava/classpath/javax/management/RuntimeOperationsException.java b/libjava/classpath/javax/management/RuntimeOperationsException.java new file mode 100644 index 000000000..8c134f07e --- /dev/null +++ b/libjava/classpath/javax/management/RuntimeOperationsException.java @@ -0,0 +1,120 @@ +/* RuntimeOperationsException.java -- A wrapped run-time exception. + Copyright (C) 2006 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 runtime exception thrown by a management + * bean operation. When a management bean executes code + * that causes a runtime exception to be thrown, the + * resulting exception is wrapped inside an + * {@link RuntimeOperationsException}. Calling + * {@link getTargetException()} will return the wrapped + * exception. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public class RuntimeOperationsException + extends JMRuntimeException +{ + + /** + * Compatible with JDK 1.5 + */ + private static final long serialVersionUID = -8408923047489133588L; + + /* Sun re-implemented causality -- don't know why, but + serialization demands we do too... */ + + /** + * The target exception. + * + * @serial the target exception. + */ + private RuntimeException runtimeException; + + /** + * Constructs a new <code>RuntimeOperationsException</code> + * wrapping the specified exception. + * + * @param e the exception to be wrapped. + */ + public RuntimeOperationsException(RuntimeException e) + { + super(); + runtimeException = e; + } + + /** + * Constructs a new <code>RuntimeOperationsException</code> + * wrapping the specified exception and using the supplied + * message. + * + * @param e the exception to be wrapped. + * @param message the error message to give to the user. + */ + public RuntimeOperationsException(RuntimeException e, + String message) + { + super(message); + runtimeException = e; + } + + /** + * Returns the true cause of this exception, the wrapped + * exception. + * + * @return the wrapped exception. + */ + public Throwable getCause() + { + return runtimeException; + } + + /** + * Returns the true cause of this exception, the wrapped + * exception. + * + * @return the wrapped exception. + */ + public RuntimeException getTargetException() + { + return runtimeException; + } + +} diff --git a/libjava/classpath/javax/management/ServiceNotFoundException.java b/libjava/classpath/javax/management/ServiceNotFoundException.java new file mode 100644 index 000000000..1c0d74286 --- /dev/null +++ b/libjava/classpath/javax/management/ServiceNotFoundException.java @@ -0,0 +1,74 @@ +/* ServiceNotFoundException.java -- Thrown by invalid values. + Copyright (C) 2006 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; + +/** + * Thrown when a requested service is unsupported. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public class ServiceNotFoundException + extends OperationsException +{ + + /** + * Compatible with JDK 1.5 + */ + private static final long serialVersionUID = -3990675661956646827L; + + /** + * Constructs a new <code>ServiceNotFoundException</code>. + */ + public ServiceNotFoundException() + { + super(); + } + + /** + * Constructs a new <code>ServiceNotFoundException</code> + * with the specified message. + * + * @param message the error message to give to the user. + */ + public ServiceNotFoundException(String message) + { + super(message); + } + +} diff --git a/libjava/classpath/javax/management/StandardMBean.java b/libjava/classpath/javax/management/StandardMBean.java new file mode 100644 index 000000000..8e30fc58b --- /dev/null +++ b/libjava/classpath/javax/management/StandardMBean.java @@ -0,0 +1,1083 @@ +/* StandardMBean.java -- A standard reflection-based management bean. + Copyright (C) 2006 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.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +/** + * Provides a dynamic management bean by using reflection on an + * interface and an implementing class. By default, a bean instance + * is paired up with its interface based on specific naming + * conventions (if the implementation is called X, the interface must + * be XMBean). Using this class removes the need to use a specific + * naming system to match up the two. Instead, an instance of this + * bean is created either via explicit construction or subclassing, + * and this provides access to the attributes, constructors and + * operations of the implementation via reflection. Various hooks are + * provided in order to allow customization of this process. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public class StandardMBean + implements DynamicMBean +{ + + /** + * The interface for this bean. + */ + private Class<?> iface; + + /** + * The implementation of the interface. + */ + private Object impl; + + /** + * Cached bean information. + */ + private MBeanInfo info; + + /** + * Constructs a new {@link StandardMBean} using the specified + * interface and <code>this</code> as the instance. This should + * be used to create an instance via subclassing. + * + * @param iface the interface this bean implements, or <code>null</code> + * if the interface should be determined using the naming + * convention (class X has interface XMBean). + * @throws NotCompliantMBeanException if this class doesn't implement + * the interface or a method appears + * in the interface that doesn't comply + * with the naming conventions. + */ + protected StandardMBean(Class<?> iface) + throws NotCompliantMBeanException + { + if (iface == null) + { + String className = getClass().getName(); + try + { + iface = Class.forName(className + "MBean"); + } + catch (ClassNotFoundException 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))) + throw new NotCompliantMBeanException("The instance, " + impl + + ", is not an instance of " + iface); + impl = this; + this.iface = iface; + } + + /** + * Constructs a new {@link StandardMBean} using the specified + * interface and the supplied instance as the implementation. + * + * @param impl the implementation. + * @param iface the interface the bean implements, or <code>null</code> + * if the interface should be determined using the naming + * convention (class X has interface XMBean). + * @throws IllegalArgumentException if <code>impl</code> is <code>null</code>. + * @throws NotCompliantMBeanException if <code>impl</code> doesn't implement + * the interface or a method appears + * in the interface that doesn't comply + * with the naming conventions. + */ + public <T> StandardMBean(T impl, Class<T> iface) + throws NotCompliantMBeanException + { + if (impl == null) + throw new IllegalArgumentException("The specified implementation is null."); + if (iface == null) + { + Class<?> implClass = impl.getClass(); + String className = implClass.getName(); + try + { + this.iface = Class.forName(className + "MBean", true, + implClass.getClassLoader()); + } + catch (ClassNotFoundException 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 + this.iface = iface; + if (!(this.iface.isInstance(impl))) + throw new NotCompliantMBeanException("The instance, " + impl + + ", is not an instance of " + iface); + this.impl = impl; + } + + /** + * Caches the {@link MBeanInfo} instance for this object. This is a + * customization hook, so that subclasses can choose the caching policy + * used. The default implementation caches the value in the instance + * itself. Subclasses may override this so as to not cache the data + * at all, or so as to use a cache shared between multiple beans. + * + * @param info the {@link MBeanInfo} instance to cache, or <code>null</code> + * if there is no new value to cache. When the value is not + * <code>null</code>, the cache should replace the current value + * with the value supplied here. + * @see #getCachedMBeanInfo() + */ + protected void cacheMBeanInfo(MBeanInfo info) + { + if (info != null) + this.info = info; + } + + /** + * Obtains the value of the specified attribute of the + * management bean. The management bean should perform + * a lookup for the named attribute, and return its value + * by calling the appropriate getter method, if possible. + * + * @param name the name of the attribute to retrieve. + * @return the value of the specified attribute. + * @throws AttributeNotFoundException if the name does not + * correspond to an attribute + * of the bean. + * @throws MBeanException if retrieving the attribute causes + * the bean to throw an exception (which + * becomes the cause of this exception). + * @throws ReflectionException if an exception occurred in trying + * to use the reflection interface + * to lookup the attribute. The + * thrown exception is the cause of + * this exception. + * @see #setAttribute(String) + */ + public Object getAttribute(String name) + throws AttributeNotFoundException, MBeanException, + ReflectionException + { + Method getter; + try + { + getter = iface.getMethod("get" + name); + } + catch (NoSuchMethodException e) + { + try + { + getter = iface.getMethod("is" + name); + } + catch (NoSuchMethodException ex) + { + throw ((AttributeNotFoundException) + new AttributeNotFoundException("The attribute, " + name + + ", was not found.").initCause(ex)); + } + } + Object result; + try + { + result = getter.invoke(impl); + } + catch (IllegalAccessException e) + { + throw new ReflectionException(e, "Failed to retrieve " + name); + } + catch (IllegalArgumentException e) + { + throw new ReflectionException(e, "Failed to retrieve " + name); + } + catch (InvocationTargetException e) + { + throw new MBeanException((Exception) e.getCause(), + "The getter of " + name + + " threw an exception"); + } + return result; + } + + /** + * Obtains the values of each of the specified attributes + * of the management bean. The returned list includes + * those attributes that were retrieved and their + * corresponding values. + * + * @param names the names of the attributes to retrieve. + * @return a list of the retrieved attributes. + * @see #setAttributes(AttributeList) + */ + public AttributeList getAttributes(String[] names) + { + AttributeList list = new AttributeList(names.length); + for (int a = 0; a < names.length; ++a) + { + try + { + Object value = getAttribute(names[a]); + list.add(new Attribute(names[a], value)); + } + catch (AttributeNotFoundException e) + { + /* Ignored */ + } + catch (ReflectionException e) + { + /* Ignored */ + } + catch (MBeanException e) + { + /* Ignored */ + } + } + return list; + } + + /** + * Returns the cached {@link MBeanInfo} instance for this object. This is a + * customization hook, so that subclasses can choose the caching policy + * used. The default implementation caches the value in the instance + * itself, and returns this value on calls to this method. + * + * @return the cached {@link MBeanInfo} instance, or <code>null</code> + * if no value is cached. + * @see #cacheMBeanInfo(javax.management.MBeanInfo) + */ + protected MBeanInfo getCachedMBeanInfo() + { + return info; + } + + /** + * Returns the class name that will be used in the {@link MBeanInfo} + * instance. This is a customization hook, so that subclasses can + * provide a custom class name. By default, this returns the class + * name from the supplied {@link MBeanInfo} instance. + * + * @param info the {@link MBeanInfo} instance constructed via + * reflection. + * @return the class name to use in the instance. + */ + protected String getClassName(MBeanInfo info) + { + return info.getClassName(); + } + + /** + * Returns information on the constructors that will be used in + * the {@link MBeanInfo} instance. This is a customization hook, + * so that subclasses can provide their own information on the + * bean's constructors, if necessary. By default, this method + * returns <code>null</code> unless the implementation supplied + * is either <code>null</code> or <code>this</code>. This default + * implementation prevents the use of + * {@link MBeanServer#createMBean} in cases where the bean is + * not created as a subclass of {@link StandardMBean}. + * + * @param constructors the constructor information created via + * reflection. + * @param impl the implementation, or <code>null</code> if this + * should be ignored. + * @return the constructor information to use. + */ + protected MBeanConstructorInfo[] getConstructors(MBeanConstructorInfo[] + constructors, Object impl) + { + if (impl == null || impl == this) + return constructors; + return null; + } + + /** + * Returns the description of the attribute that will be used in + * the supplied {@link MBeanAttributeInfo} instance. This is a + * customization hook, so that subclasses can provide a custom + * description. By default, this calls + * {@link #getDescription(MBeanFeatureInfo)} with the supplied + * {@link MBeanAttributeInfo} instance. + * + * @param info the {@link MBeanAttributeInfo} instance constructed + * via reflection. + * @return the description to use in the instance. + */ + protected String getDescription(MBeanAttributeInfo info) + { + return getDescription((MBeanFeatureInfo) info); + } + + /** + * Returns the description of the constructor that will be used in + * the supplied {@link MBeanConstructorInfo} instance. This is a + * customization hook, so that subclasses can provide a custom + * description. By default, this calls + * {@link #getDescription(MBeanFeatureInfo)} with the supplied + * {@link MBeanConstructorInfo} instance. + * + * @param info the {@link MBeanConstructorInfo} instance constructed + * via reflection. + * @return the description to use in the instance. + */ + protected String getDescription(MBeanConstructorInfo info) + { + return getDescription((MBeanFeatureInfo) info); + } + + /** + * Returns the description of the nth parameter of the constructor + * that will be used in the supplied {@link MBeanParameterInfo} + * instance. This is a customization hook, so that subclasses + * can provide a custom description. By default, this calls + * <code>param.getDescription()</code>. + * + * @param info the {@link MBeanConstructorInfo} instance constructed + * via reflection. + * @param param the {@link MBeanParameterInfo} instance constructed + * via reflection. + * @param n the number of the parameter, in order to link it to the + * information on the constructor. + * @return the description to use in the instance. + */ + protected String getDescription(MBeanConstructorInfo info, + MBeanParameterInfo param, int n) + { + return param.getDescription(); + } + + /** + * Returns the description of the supplied feature that + * will be used in the supplied {@link MBeanFeatureInfo} + * instance. This is a customization hook, so that subclasses + * can provide a custom description. By default, this calls + * <code>info.getDescription()</code>. This method is also called + * by default for the more specific description methods for attributes, + * constructors and operations. + * + * @param info the {@link MBeanFeatureInfo} instance constructed + * via reflection. + * @return the description to use in the instance. + */ + protected String getDescription(MBeanFeatureInfo info) + { + return info.getDescription(); + } + + /** + * Returns the description of the bean that will be used in the + * supplied {@link MBeanInfo} instance. This is a customization + * hook, so that subclasses can provide a custom description. By + * default, this calls <code>info.getDescription()</code>. + * + * @param info the {@link MBeanInfo} instance constructed + * via reflection. + * @return the description to use in the instance. + */ + protected String getDescription(MBeanInfo info) + { + return info.getDescription(); + } + + /** + * Returns the description of the operation that will be used in + * the supplied {@link MBeanOperationInfo} instance. This is a + * customization hook, so that subclasses can provide a custom + * description. By default, this calls + * {@link #getDescription(MBeanFeatureInfo)} with the supplied + * {@link MBeanOperationInfo} instance. + * + * @param info the {@link MBeanOperationInfo} instance constructed + * via reflection. + * @return the description to use in the instance. + */ + protected String getDescription(MBeanOperationInfo info) + { + return getDescription((MBeanFeatureInfo) info); + } + + /** + * Returns the description of the nth parameter of the operation + * that will be used in the supplied {@link MBeanParameterInfo} + * instance. This is a customization hook, so that subclasses + * can provide a custom description. By default, this calls + * <code>param.getDescription()</code>. + * + * @param info the {@link MBeanOperationInfo} instance constructed + * via reflection. + * @param param the {@link MBeanParameterInfo} instance constructed + * via reflection. + * @param n the number of the parameter, in order to link it to the + * information on the operation. + * @return the description to use in the instance. + */ + protected String getDescription(MBeanOperationInfo info, + MBeanParameterInfo param, int n) + { + return param.getDescription(); + } + + /** + * Returns the impact of the operation that will be used in the + * supplied {@link MBeanOperationInfo} instance. This is a + * customization hook, so that subclasses can provide a custom + * impact flag. By default, this returns + * <code>info.getImpact()</code>. + * + * @param info the {@link MBeanOperationInfo} instance constructed + * via reflection. + * @return the impact flag to use in the instance. + */ + protected int getImpact(MBeanOperationInfo info) + { + return info.getImpact(); + } + + /** + * Returns the instance that implements this bean. + * + * @return the implementation. + */ + public Object getImplementation() + { + return impl; + } + + /** + * Returns the class of the instance that implements this bean. + * + * @return the implementation class. + */ + public Class<?> getImplementationClass() + { + return impl.getClass(); + } + + /** + * <p> + * Returns an information object which lists the attributes + * and actions associated with the management bean. This + * implementation proceeds as follows: + * </p> + * <ol> + * <li>{@link #getCachedMBeanInfo()} is called to obtain + * the cached instance. If this returns a non-null value, + * this value is returned.</li> + * <li>If there is no cached value, then the method proceeds + * to create one. During this process, the customization hooks + * detailed in this class are called to allow the values used + * to be overrided: + * <ul> + * <li>For each attribute, + * {@link #getDescription(MBeanAttributeInfo)} is called.</li> + * <li>For each constructor, + * {@link #getDescription(MBeanConstructorInfo)} is called, + * along with {@link #getDescription(MBeanConstructorInfo, + * MBeanParameterInfo, int)} and + * {@link #getParameterName(MBeanConstructorInfo, + * MBeanParameterInfo, int)} for each parameter.</li> + * <li>The constructors may be replaced as a whole by + * a call to + * {@link #getConstructors(MBeanConstructorInfo[], Object)}.</li> + * <li>For each operation, + * {@link #getDescription(MBeanOperationInfo)} and + * {@link #getImpact(MBeanOperationInfo)} are called, + * along with {@link #getDescription(MBeanOperationInfo, + * MBeanParameterInfo, int)} and + * {@link #getParameterName(MBeanOperationInfo, + * MBeanParameterInfo, int)} for each parameter.</li> + * <li>{@link #getClassName(MBeanInfo)} and + * {@link #getDescription(MBeanInfo)} are called to customise + * the basic information about the class.</li> + * </ul> + * </li> + * <li>Finally, {@link #cacheMBeanInfo(MBeanInfo)} is called + * with the created instance before it is returned.</li> + * </ol> + * + * @return a description of the management bean, including + * all exposed attributes and actions. + */ + public MBeanInfo getMBeanInfo() + { + MBeanInfo info = getCachedMBeanInfo(); + if (info != null) + return info; + Method[] methods = iface.getMethods(); + Map<String,Method[]> attributes = new HashMap<String,Method[]>(); + List<MBeanOperationInfo> operations = new ArrayList<MBeanOperationInfo>(); + for (int a = 0; a < methods.length; ++a) + { + String name = methods[a].getName(); + if (((name.startsWith("get") && + methods[a].getReturnType() != Void.TYPE) || + (name.startsWith("is") && + methods[a].getReturnType() == Boolean.TYPE)) && + methods[a].getParameterTypes().length == 0) + { + Method[] amethods; + String attrib; + if (name.startsWith("is")) + attrib = name.substring(2); + else + attrib = name.substring(3); + if (attributes.containsKey(attrib)) + amethods = (Method[]) attributes.get(attrib); + else + { + amethods = new Method[2]; + attributes.put(attrib, amethods); + } + amethods[0] = methods[a]; + } + else if (name.startsWith("set") && + methods[a].getReturnType() == Void.TYPE && + methods[a].getParameterTypes().length == 1) + { + Method[] amethods; + String attrib = name.substring(3); + if (attributes.containsKey(attrib)) + amethods = (Method[]) attributes.get(attrib); + else + { + amethods = new Method[2]; + attributes.put(attrib, amethods); + } + amethods[1] = methods[a]; + } + else + operations.add(new MBeanOperationInfo(methods[a].getName(), + methods[a])); + } + List<MBeanAttributeInfo> attribs = new ArrayList<MBeanAttributeInfo>(attributes.size()); + for (Map.Entry<String,Method[]> entry : attributes.entrySet()) + { + Method[] amethods = entry.getValue(); + try + { + attribs.add(new MBeanAttributeInfo(entry.getKey(), + entry.getKey(), + amethods[0], amethods[1])); + } + catch (IntrospectionException e) + { + /* Shouldn't happen; both shouldn't be null */ + throw new IllegalStateException("The two methods passed to " + + "the MBeanAttributeInfo " + + "constructor for " + entry + + "were null.", e); + } + } + MBeanAttributeInfo[] ainfo = new MBeanAttributeInfo[attribs.size()]; + for (int a = 0; a < ainfo.length; ++a) + { + MBeanAttributeInfo oldInfo = (MBeanAttributeInfo) attribs.get(a); + String desc = getDescription(oldInfo); + ainfo[a] = new MBeanAttributeInfo(oldInfo.getName(), + oldInfo.getType(), desc, + oldInfo.isReadable(), + oldInfo.isWritable(), + oldInfo.isIs()); + } + Constructor<?>[] cons = impl.getClass().getConstructors(); + MBeanConstructorInfo[] cinfo = new MBeanConstructorInfo[cons.length]; + for (int a = 0; a < cinfo.length; ++a) + { + MBeanConstructorInfo oldInfo = new MBeanConstructorInfo(cons[a].getName(), + cons[a]); + String desc = getDescription(oldInfo); + MBeanParameterInfo[] params = oldInfo.getSignature(); + MBeanParameterInfo[] pinfo = new MBeanParameterInfo[params.length]; + for (int b = 0; b < pinfo.length; ++b) + { + String pdesc = getDescription(oldInfo, params[b], b); + String pname = getParameterName(oldInfo, params[b], b); + pinfo[b] = new MBeanParameterInfo(pname, params[b].getType(), + pdesc); + } + cinfo[a] = new MBeanConstructorInfo(oldInfo.getName(), desc, + pinfo); + } + cinfo = getConstructors(cinfo, impl); + MBeanOperationInfo[] oinfo = new MBeanOperationInfo[operations.size()]; + for (int a = 0; a < oinfo.length; ++a) + { + MBeanOperationInfo oldInfo = (MBeanOperationInfo) operations.get(a); + String desc = getDescription(oldInfo); + int impact = getImpact(oldInfo); + MBeanParameterInfo[] params = oldInfo.getSignature(); + MBeanParameterInfo[] pinfo = new MBeanParameterInfo[params.length]; + for (int b = 0; b < pinfo.length; ++b) + { + String pdesc = getDescription(oldInfo, params[b], b); + String pname = getParameterName(oldInfo, params[b], b); + pinfo[b] = new MBeanParameterInfo(pname, params[b].getType(), + pdesc); + } + oinfo[a] = new MBeanOperationInfo(oldInfo.getName(), desc, pinfo, + oldInfo.getReturnType(), impact); + } + info = new MBeanInfo(impl.getClass().getName(), impl.getClass().getName(), + ainfo, cinfo, oinfo, null); + String cname = getClassName(info); + String desc = getDescription(info); + MBeanNotificationInfo[] ninfo = null; + if (impl instanceof NotificationBroadcaster) + ninfo = ((NotificationBroadcaster) impl).getNotificationInfo(); + info = new MBeanInfo(cname, desc, ainfo, cinfo, oinfo, ninfo); + cacheMBeanInfo(info); + return info; + } + + /** + * Returns the interface for this management bean. + * + * @return the management interface. + */ + public final Class<?> getMBeanInterface() + { + return iface; + } + + /** + * Returns the name of the nth parameter of the constructor + * that will be used in the supplied {@link MBeanParameterInfo} + * instance. This is a customization hook, so that subclasses + * can provide a custom name. By default, this calls + * <code>param.getName()</code>. + * + * @param info the {@link MBeanConstructorInfo} instance constructed + * via reflection. + * @param param the {@link MBeanParameterInfo} instance constructed + * via reflection. + * @param n the number of the parameter, in order to link it to the + * information on the constructor. + * @return the name to use in the instance. + */ + protected String getParameterName(MBeanConstructorInfo info, + MBeanParameterInfo param, int n) + { + return param.getName(); + } + + /** + * Returns the name of the nth parameter of the operation + * that will be used in the supplied {@link MBeanParameterInfo} + * instance. This is a customization hook, so that subclasses + * can provide a custom name. By default, this calls + * <code>param.getName()</code>. + * + * @param info the {@link MBeanOperationInfo} instance constructed + * via reflection. + * @param param the {@link MBeanParameterInfo} instance constructed + * via reflection. + * @param n the number of the parameter, in order to link it to the + * information on the operation. + * @return the name to use in the instance. + */ + protected String getParameterName(MBeanOperationInfo info, + MBeanParameterInfo param, int n) + { + return param.getName(); + } + + /** + * Invokes the specified action on the management bean using + * the supplied parameters. The signature of the action is + * specified by a {@link String} array, which lists the classes + * corresponding to each parameter. The class loader used to + * load these classes is the same as that used for loading the + * management bean itself. + * + * @param name the name of the action to invoke. + * @param params the parameters used to call the action. + * @param signature the signature of the action. + * @return the return value of the action. + * @throws MBeanException if the action throws an exception. The + * thrown exception is the cause of this + * exception. + * @throws ReflectionException if an exception occurred in trying + * to use the reflection interface + * to invoke the action. The + * thrown exception is the cause of + * this exception. + */ + public Object invoke(String name, Object[] params, String[] signature) + throws MBeanException, ReflectionException + { + 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(); + 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 + { + method = iface.getMethod(name, sigTypes); + } + catch (NoSuchMethodException e) + { + throw new ReflectionException(e, "The method, " + name + + ", could not be found."); + } + Object result; + try + { + result = method.invoke(impl, params); + } + catch (IllegalAccessException e) + { + throw new ReflectionException(e, "Failed to call " + name); + } + catch (IllegalArgumentException e) + { + throw new ReflectionException(e, "Failed to call " + name); + } + catch (InvocationTargetException e) + { + throw new MBeanException((Exception) e.getCause(), "The method " + + name + " threw an exception"); + } + return result; + } + + /** + * Sets the value of the specified attribute of the + * management bean. The management bean should perform + * a lookup for the named attribute, and sets its value + * using the associated setter method, if possible. + * + * @param attribute the attribute to set. + * @throws AttributeNotFoundException if the attribute does not + * correspond to an attribute + * of the bean. + * @throws InvalidAttributeValueException if the value is invalid + * for this particular + * attribute of the bean. + * @throws MBeanException if setting the attribute causes + * the bean to throw an exception (which + * becomes the cause of this exception). + * @throws ReflectionException if an exception occurred in trying + * to use the reflection interface + * to lookup the attribute. The + * thrown exception is the cause of + * this exception. + * @see #getAttribute(String) + */ + public void setAttribute(Attribute attribute) + throws AttributeNotFoundException, InvalidAttributeValueException, + MBeanException, ReflectionException + { + String name = attribute.getName(); + String attName = name.substring(0, 1).toUpperCase() + name.substring(1); + Object val = attribute.getValue(); + try + { + getMutator(attName, val.getClass()).invoke(impl, new Object[] { val }); + } + catch (IllegalAccessException e) + { + throw new ReflectionException(e, "Failed to set " + name); + } + catch (IllegalArgumentException e) + { + throw ((InvalidAttributeValueException) + new InvalidAttributeValueException(attribute.getValue() + + " is an invalid value for " + + name).initCause(e)); + } + catch (InvocationTargetException e) + { + throw new MBeanException(e, "The getter of " + name + + " threw an exception"); + } + } + + /** + * Sets the value of each of the specified attributes + * to that supplied by the {@link Attribute} object. + * The returned list contains the attributes that were + * set and their new values. + * + * @param attributes the attributes to set. + * @return a list of the changed attributes. + * @see #getAttributes(AttributeList) + */ + public AttributeList setAttributes(AttributeList attributes) + { + AttributeList list = new AttributeList(attributes.size()); + Iterator<Object> it = attributes.iterator(); + while (it.hasNext()) + { + try + { + Attribute attrib = (Attribute) it.next(); + setAttribute(attrib); + list.add(attrib); + } + catch (AttributeNotFoundException e) + { + /* Ignored */ + } + catch (InvalidAttributeValueException e) + { + /* Ignored */ + } + catch (ReflectionException e) + { + /* Ignored */ + } + catch (MBeanException e) + { + /* Ignored */ + } + } + return list; + } + + /** + * Replaces the implementation of the interface used by this + * instance with the one specified. The new implementation + * must be non-null and implement the interface specified on + * construction of this instance. + * + * @throws IllegalArgumentException if <code>impl</code> is <code>null</code>. + * @throws NotCompliantMBeanException if <code>impl</code> doesn't implement + * the interface or a method appears + * in the interface that doesn't comply + * with the naming conventions. + */ + public void setImplementation(Object impl) + throws NotCompliantMBeanException + { + if (impl == null) + throw new IllegalArgumentException("The specified implementation is null."); + if (!(iface.isInstance(impl))) + throw new NotCompliantMBeanException("The instance, " + impl + + ", is not an instance of " + iface); + 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 000000000..0ecd06597 --- /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/ValueExp.java b/libjava/classpath/javax/management/ValueExp.java new file mode 100644 index 000000000..f98927672 --- /dev/null +++ b/libjava/classpath/javax/management/ValueExp.java @@ -0,0 +1,85 @@ +/* ValueExp.java -- Represents values that can be passed to queries. + Copyright (C) 2006 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 values that may be passed as arguments to + * {@link QueryExp}s. Strings, numbers and bean attributes + * are all valid argument types for query expressions, and + * so should be represented as implementations of this + * interface. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public interface ValueExp + extends Serializable +{ + + /** + * Applies the value expression to the specified management bean. + * + * @param name the name of the management bean. + * @return the value expression. + * @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. + */ + ValueExp apply(ObjectName name) + throws BadStringOperationException, BadBinaryOpValueExpException, + BadAttributeValueExpException, InvalidApplicationException; + + /** + * Changes the {@link MBeanServer} on which this query is performed. + * + * @param server the new server to use. + * @deprecated This method is superfluous, as the {@link ValueExp} + * can access the server using + * {@link QueryEval#getMBeanServer()}. + */ + void setMBeanServer(MBeanServer server); + +} diff --git a/libjava/classpath/javax/management/loading/ClassLoaderRepository.java b/libjava/classpath/javax/management/loading/ClassLoaderRepository.java new file mode 100644 index 000000000..cfd031e62 --- /dev/null +++ b/libjava/classpath/javax/management/loading/ClassLoaderRepository.java @@ -0,0 +1,138 @@ +/* ClassLoaderRepository.java -- Represents a collection of class loadersx. + Copyright (C) 2006 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.loading; + +/** + * Implementations of this interface maintain a list of + * {@link ClassLoader}s for use by the management servers, + * allowing classes to be loaded by the first {@link ClassLoader} + * that will do so. A class loader is added to the list + * whenever a {@link ClassLoader} instance is registered with + * the management server, and it does not implement the + * {@link PrivateClassLoader} interface. They are removed when + * unregistered. The first class loader in the list is always + * the one which was used to load the management server itself. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + * @see MBeanServerFactory + */ +public interface ClassLoaderRepository +{ + + /** + * Attempts to load the given class using class loaders + * supplied by the list. 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. + */ + Class<?> loadClass(String name) + throws ClassNotFoundException; + + /** + * <p> + * Attempts to load the given class using class loaders + * supplied by the list, stopping when the specified + * loader is reached. The {@link ClassLoader#loadClass(String)} + * method of each class loader is called. If the method + * returns successfully, then the returned {@link Class} instance + * is returned. If a {@link ClassNotFoundException} is thrown, + * then the next loader is tried. Any other exception thrown + * by the method is passed back to the caller. This method + * throws a {@link ClassNotFoundException} itself if all the + * class loaders listed prove fruitless. + * </p> + * <p> + * This method is usually used by the class loader specified + * by the <code>stop</code> argument to load classes using the + * loaders that appear before it in the list. By stopping when + * the loader is reached, the deadlock that occurs when the loader + * is merely skipped is avoided. + * </p> + * + * @param stop the class loader at which to stop, or <code>null</code> + * to obtain the same behaviour as {@link #loadClass(String)}. + * @param name the name of the class to load. + * @return the loaded class. + * @throws ClassNotFoundException if all the class loaders fail + * to load the class. + */ + Class<?> loadClassBefore(ClassLoader stop, String name) + throws ClassNotFoundException; + + /** + * <p> + * Attempts to load the given class using class loaders + * supplied by the list, excluding the one specified. + * The {@link ClassLoader#loadClass(String)} + * method of each class loader is called. If the method + * returns successfully, then the returned {@link Class} instance + * is returned. If a {@link ClassNotFoundException} is thrown, + * then the next loader is tried. Any other exception thrown + * by the method is passed back to the caller. This method + * throws a {@link ClassNotFoundException} itself if all the + * class loaders listed prove fruitless. + * </p> + * <p> + * Note that this method may deadlock if called simultaneously + * by two class loaders in the list. + * {@link loadClassBefore(ClassLoader, String)} should be used + * in preference to this method to avoid this. + * </p> + * + * @param exclude the class loader to exclude, or <code>null</code> + * to obtain the same behaviour as {@link #loadClass(String)}. + * @param name the name of the class to load. + * @return the loaded class. + * @throws ClassNotFoundException if all the class loaders fail + * to load the class. + */ + 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 new file mode 100644 index 000000000..fc1887014 --- /dev/null +++ b/libjava/classpath/javax/management/openmbean/ArrayType.java @@ -0,0 +1,672 @@ +/* ArrayType.java -- Open type descriptor for an array. + Copyright (C) 2006, 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.openmbean; + +import java.lang.reflect.Array; + +import java.util.HashMap; +import java.util.Map; + +/** + * The open type descriptor for arrays of open data values. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public class ArrayType<T> + extends OpenType<T> +{ + + /** + * Compatible with JDK 1.5 + */ + private static final long serialVersionUID = 720504429830309770L; + + /** + * The number of dimensions arrays of this type has. + */ + private int dimension; + + /** + * The element type of arrays of this type. + */ + private OpenType<?> elementType; + + /** + * True if this type represents a primitive array. + */ + private boolean primitiveArray; + + /** + * The hash code of this instance. + */ + private transient Integer hashCode; + + /** + * The <code>toString()</code> result of this instance. + */ + private transient String string; + + /** + * A cache of {@link ArrayType} instances created + * by {@link #getArrayType(OpenType)}. + */ + private static final Map<OpenType<?>,ArrayType<?>> cache = + new HashMap<OpenType<?>,ArrayType<?>>(); + + /** + * A cache of {@link ArrayType} instances created + * by {@link #getPrimitiveArrayType(Class)}. + */ + private static final Map<Class<?>,ArrayType<?>> primCache = + new HashMap<Class<?>,ArrayType<?>>(); + + /** + * Returns the class name of the array, given the element + * class name and its dimensions. + * + * @param elementType the type of the array's elements. + * @param dim the dimensions of the array. + * @param primitive true if this should be a primitive array. + * @return the array's class name. + * @throws OpenDataException if the class name does not reference + * a loadable class. + */ + private static final String getArrayClassName(OpenType<?> elementType, + int dim, + boolean primitive) + throws OpenDataException + { + Class<?> type; + if (primitive) + type = getPrimitiveTypeClass((SimpleType<?>) elementType); + else + { + String className = elementType.getClassName(); + try + { + type = Class.forName(className); + } + catch (ClassNotFoundException e) + { + throw new OpenDataException("The class name, " + className + + ", is unavailable."); + } + } + while (type.isArray()) + type = type.getComponentType(); + return + Array.newInstance(type, + new int[getDimensions(elementType, dim)]).getClass().getName(); + } + + /** + * Returns the dimensions of the new {@link ArrayType}, + * based on whether the given element type is already an + * {@link ArrayType} or not. + * + * @param elementType the type of the array. + * @param dim the proposed dimensions. + * @return the resultant dimensions. + * @throws IllegalArgumentException if <code>dim</code> is less than 1. + */ + private static final int getDimensions(OpenType<?> elementType, + int dim) + { + if (dim < 1) + throw new IllegalArgumentException("Dimensions must be greater " + + "than or equal to 1."); + if (elementType instanceof ArrayType) + return dim + ((ArrayType<?>) elementType).getDimension(); + return dim; + } + + /** + * Returns the appropriate primitive type name, given the + * corresponding wrapper class. + * + * @param type the type to convert. + * @return the corresponding primitive type. + * @throws OpenDataException if {@code type} is not a valid + * {@link Class} for a primitive type. + * + */ + private static final SimpleType<?> getPrimitiveType(Class<?> type) + throws OpenDataException + { + if (type.equals(Boolean.TYPE)) + return SimpleType.BOOLEAN; + if (type.equals(Byte.TYPE)) + return SimpleType.BYTE; + if (type.equals(Character.TYPE)) + return SimpleType.CHARACTER; + if (type.equals(Double.TYPE)) + return SimpleType.DOUBLE; + if (type.equals(Float.TYPE)) + return SimpleType.FLOAT; + if (type.equals(Integer.TYPE)) + return SimpleType.INTEGER; + if (type.equals(Long.TYPE)) + return SimpleType.LONG; + if (type.equals(Short.TYPE)) + return SimpleType.SHORT; + if (type.equals(Void.TYPE)) + return SimpleType.VOID; + throw new OpenDataException(type + " is not a primitive type."); + } + + /** + * Returns the appropriate primitive type name, given the + * corresponding wrapper class. + * + * @param type the type to convert. + * @return the corresponding primitive type. + * @throws OpenDataException if {@code type} is not a valid + * {@link SimpleType} for a primitive type. + * + */ + private static final Class<?> getPrimitiveTypeClass(SimpleType<?> type) + throws OpenDataException + { + if (type.equals(SimpleType.BOOLEAN)) + return Boolean.TYPE; + if (type.equals(SimpleType.BYTE)) + return Byte.TYPE; + if (type.equals(SimpleType.CHARACTER)) + return Character.TYPE; + if (type.equals(SimpleType.DOUBLE)) + return Double.TYPE; + if (type.equals(SimpleType.FLOAT)) + return Float.TYPE; + if (type.equals(SimpleType.INTEGER)) + return Integer.TYPE; + if (type.equals(SimpleType.LONG)) + return Long.TYPE; + if (type.equals(SimpleType.SHORT)) + return Short.TYPE; + if (type.equals(SimpleType.VOID)) + return Void.TYPE; + throw new OpenDataException(type + " is not a primitive type."); + } + + /** + * Returns the element type that will actually be used, if the + * specified element type is passed to a constructor. This is + * necessary to ensure that a non-array type is still returned when + * an {@link ArrayType} is constructed from an {@link ArrayType}. + * + * @param elemType the element type that was supplied. + * @return the element type that will be used. + */ + private static final OpenType<?> getElementType(OpenType<?> elemType) + { + if (elemType instanceof ArrayType) + return ((ArrayType<?>) elemType).getElementOpenType(); + return elemType; + } + + /** + * Returns the element type name that will actually be used, if the + * specified element type is passed to a constructor. This is + * necessary to ensure that a non-array type is still returned when + * an {@link ArrayType} is constructed from an {@link ArrayType}, + * and that primitive arrays are described correctly. + * + * @param elemType the element type that was supplied. + * @return the element type name that will be used. + * @throws OpenDataException if the element type is not a valid + * {@link SimpleType} for a primitive type. + */ + private static final String getElementTypeName(OpenType<?> elemType) + throws OpenDataException + { + OpenType<?> trueElemType = getElementType(elemType); + if (elemType instanceof ArrayType && + ((ArrayType<?>) elemType).isPrimitiveArray()) + return getPrimitiveTypeClass((SimpleType<?>) trueElemType).getName(); + return trueElemType.getClassName(); + } + + /** + * <p> + * Constructs a new {@link ArrayType} instance for an array of the + * specified type with the supplied number of dimensions. 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 (i.e. the element type, preceded by n instances of + * '[' and an 'L', where n is the number of dimensions the array has). + * The description is based upon the template <code>n-dimension array + * of e</code>, where n is the number of dimensions of the array, and + * e is the element type. The class name of the actual elements is + * obtainable by calling {@link OpenType#getClassName()} on the result + * of {@link #getElementOpenType()}. + * </p> + * <p> + * As an example, the array type returned by + * <code>new ArrayType(6, SimpleType.INTEGER)</code> has the following + * values: + * </p> + * <table> + * <th><td>Attribute</td><td>Value</td></th> + * <tr><td>Class Name</td><td><code>[[[[[[Ljava.lang.Integer;</code> + * </td></tr> + * <tr><td>Type Name</td><td><code>[[[[[[Ljava.lang.Integer;</code> + * </td></tr> + * <tr><td>Description</td><td><code>6-dimension array of + * java.lang.Integer</code></td></tr> + * <tr><td>Element Type Class Name</td><td><code>java.lang.Integer</code> + * </td></tr> + * </table> + * <p> + * The dimensions of the array must be equal to or greater than 1. The + * element type must be an instance of {@link SimpleType}, + * {@link CompositeType} or {@link TabularType}. + * </p> + * + * @param dim the dimensions of the array. + * @param elementType the type of the elements of the array. + * @throws IllegalArgumentException if <code>dim</code> is less than 1. + * @throws OpenDataException if the element type is not an instance of either + * {@link SimpleType}, {@link CompositeType} + * or {@link TabularType}. + */ + public ArrayType(int dim, OpenType<?> elementType) + throws OpenDataException + { + 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 ArrayType)) + throw new OpenDataException("The element type must be a simple " + + "type, an array type, a composite type " + + "or a tabular type."); + dimension = getDimensions(elementType, dim); + this.elementType = getElementType(elementType); + primitiveArray = (elementType instanceof ArrayType && + ((ArrayType<?>) elementType).isPrimitiveArray()); + } + + /** + * <p> + * Constructs a new {@link ArrayType} instance for a unidimensional + * array of the specified {@link SimpleType}. The attributes + * used by the superclass, {@link OpenType}, are automatically defined, + * based on these values. Both the class name and type name are set + * to the value returned by the {@link java.lang.Class#getName()} of + * the array's class. If the array is of a primitive type (indicated + * by giving {@code primitiveArray} the value {@code true}), the + * name will be '[' followed by the appropriate letter for the + * primitive type (see {@link java.lang.Class#getName()}). If the + * array is not of a primitive type, then the name is formed from + * the element type, preceded by '[' and an 'L', in the same way + * as when the multi-dimensional constructor is used. + * </p> + * <p> + * The description is based upon the template <code>1-dimension array + * of e</code>, where e is either the primitive type or a class name, + * depending on whether the array itself is of a primitive type or not. + * The class name of the actual elements is obtainable by calling + * {@link OpenType#getClassName()} on the result of + * {@link #getElementOpenType()}. This will be the appropriate wrapper + * class for a primitive type. + * </p> + * <p> + * As an example, the array type returned by + * <code>new ArrayType(SimpleType.INTEGER, true)</code> has the following + * values: + * </p> + * <table> + * <th><td>Attribute</td><td>Value</td></th> + * <tr><td>Class Name</td><td><code>[I</code> + * </td></tr> + * <tr><td>Type Name</td><td><code>[I</code> + * </td></tr> + * <tr><td>Description</td><td><code>1-dimension array of int</code></td></tr> + * <tr><td>Element Type Class Name</td><td><code>java.lang.Integer</code> + * </td></tr> + * </table> + * + * @param elementType the type of the elements of the array. + * @param primitiveArray true if the array should be of a primitive type. + * @throws OpenDataException if {@code primitiveArray} is {@code true}, + * and {@link elementType} is not a valid + * {@link SimpleType} for a primitive type. + * @since 1.6 + */ + public ArrayType(SimpleType<?> elementType, boolean primitiveArray) + throws OpenDataException + { + super(getArrayClassName(elementType, 1, primitiveArray), + getArrayClassName(elementType, 1, primitiveArray), + "1-dimension array of " + + (primitiveArray ? getPrimitiveTypeClass(elementType).getName() + : elementType.getClassName())); + dimension = 1; + this.elementType = elementType; + this.primitiveArray = primitiveArray; + } + + /** + * <p> + * Compares this array type with another object + * for equality. The objects are judged to be equal if: + * </p> + * <ul> + * <li><code>obj</code> is not null.</li> + * <li><code>obj</code> is an instance of + * {@link ArrayType}.</li> + * <li>The dimensions are equal.</li> + * <li>The element types are equal.</li> + * <li>The primitive array flag is set the same in both + * instances.</li> + * </ul> + * + * @param obj the object to compare with. + * @return true if the conditions above hold. + */ + public boolean equals(Object obj) + { + if (!(obj instanceof ArrayType)) + return false; + ArrayType<?> atype = (ArrayType<?>) obj; + return (atype.getDimension() == dimension && + atype.getElementOpenType().equals(elementType) && + atype.isPrimitiveArray() == primitiveArray); + } + + /** + * <p> + * Returns a new {@link ArrayType} instance in a type-safe + * manner, by ensuring that the type of the given {@link OpenType} + * matches the component type used in the type of the + * returned instance. If the given {@link OpenType} is a + * {@link SimpleType}, {@link CompositeType} or + * {@link TabularType}, then a 1-dimensional array of that + * type is returned. Otherwise, if the type is + * an {@link ArrayType} of n dimensions, the returned + * type is also an {@link ArrayType} but of n+1 dimensions. + * For example, + * {@code ArrayType.getArrayType(ArrayType.getArrayType(SimpleType.STRING))} + * returns a 2-dimensional array of {@link SimpleType#String}. + * </p> + * <p> + * This method caches its results, so that the same instance + * is returned from subsequent calls with the same parameters. + * </p> + * + * @param elementType the element type of the new array type. + * @throws OpenDataException if the class name of {@code elementType} + * is not in {@link OpenType#ALLOWED_CLASSNAMES_LIST}. + * @since 1.6 + */ + @SuppressWarnings("unchecked") + public static <E> ArrayType<E[]> getArrayType(OpenType<E> elementType) + throws OpenDataException + { + ArrayType<E[]> arr = (ArrayType<E[]>) cache.get(elementType); + if (arr != null) + return arr; + arr = new ArrayType<E[]>(1, elementType); + cache.put(elementType, arr); + return arr; + } + + /** + * <p> + * Returns a new {@link ArrayType} instance for the given + * primitive type in a type-safe* manner, by ensuring that + * the type of the given {@link OpenType} matches the type + * used in the returned instance. If the type is + * an array of n dimensions, the returned + * type is also an {@link ArrayType} of n dimensions. + * </p> + * <p> + * As an example, the array type returned by + * <code>getPrimitiveArrayType(Integer.TYPE)</code> has the + * following values: + * </p> + * <table> + * <th><td>Attribute</td><td>Value</td></th> + * <tr><td>Class Name</td><td><code>[I</code> + * </td></tr> + * <tr><td>Type Name</td><td><code>[I</code> + * </td></tr> + * <tr><td>Description</td><td><code>1-dimension array of int</code></td></tr> + * <tr><td>Element Type Class Name</td><td><code>java.lang.Integer</code> + * </td></tr> + * </table> + * <p> + * This method caches its results, so that the same instance + * is returned from subsequent calls with the same parameters. + * </p> + * + * @param type the type of the new {@link ArrayType}. + * @throws IllegalArgumentException if the type is not a primitive + * array. + * @since 1.6 + */ + @SuppressWarnings("unchecked") + public static <T> ArrayType<T> getPrimitiveArrayType(Class<T> type) + { + ArrayType<T> arr = (ArrayType<T>) primCache.get(type); + if (arr != null) + return arr; + Class<?> comType = type; + int dim = 0; + do + { + comType = comType.getComponentType(); + ++dim; + if (comType == null) + throw new IllegalArgumentException("The given class is " + + "not an array."); + } while (comType.isArray()); + try + { + arr = new ArrayType<T>(getPrimitiveType(comType), true); + } + catch (OpenDataException e) + { + throw new IllegalArgumentException("The array is not of a primitive " + + "type", e); + } + while (dim > 1) + try + { + arr = new ArrayType<T>(1, arr); + --dim; + } + catch (OpenDataException e) + { + throw (Error) + new InternalError("Couldn't generate extra dimensions").initCause(e); + } + primCache.put(type, arr); + return arr; + } + + /** + * Returns the number of dimensions used by arrays + * of this type. + * + * @return the number of dimensions. + */ + public int getDimension() + { + return dimension; + } + + /** + * Returns the open type descriptor which describes + * the type of the elements of this array type. + * + * @return the type of the elements. + */ + public OpenType<?> getElementOpenType() + { + return elementType; + } + + /** + * <p> + * Returns the hash code of the array type. + * This is computed as the sum of the hash code of the + * element type together with the number of dimensions + * the array has and the primitive array flag. These + * are the same elements of the type that are compared as + * part of the {@link #equals(java.lang.Object)} method, + * thus ensuring that the hashcode is compatible with the + * equality test. + * </p> + * <p> + * As instances of this class are immutable, the hash code + * is computed just once for each instance and reused + * throughout its life. + * </p> + * + * @return the hash code of this instance. + */ + public int hashCode() + { + if (hashCode == null) + hashCode = Integer.valueOf(dimension + + elementType.hashCode() + + Boolean.valueOf(primitiveArray).hashCode()); + return hashCode.intValue(); + } + + /** + * Returns true if this instance represents an array of + * a primitive type. + * + * @return true if the array is of a primitive type. + */ + public boolean isPrimitiveArray() + { + return primitiveArray; + } + + /** + * <p> + * Returns true if the specified object is a member of this + * array type. The object is judged to be so if it is + * non-null, an array and one of the following two conditions + * holds: + * </p> + * <ul> + * <li>This {@link ArrayType} instance has a {@link SimpleType} + * as its element type. Thus, the object must have the same + * class name as that returned by {@link SimpleType#getClassName()} + * for this class.</li> + * <li>This {@link ArrayType} instance has a {@link CompositeType} + * or a {@link TabularType} as its element type. Thus, the object + * must be assignable to such an array, and have elements which + * are either null or valid values for the element type.</li> + * </ul> + * + * @param obj the object to test for membership. + * @return true if the object is a member of this type. + */ + public boolean isValue(Object obj) + { + if (obj == null) + return false; + Class<?> objClass = obj.getClass(); + if (!(objClass.isArray())) + return false; + if (elementType instanceof SimpleType) + return getClassName().equals(objClass.getName()); + Class<?> elementClass = null; + try + { + elementClass = Class.forName(getClassName()); + } + catch (ClassNotFoundException e) + { + throw new IllegalStateException("The array type's element " + + "class could not be found.", e); + } + if (!(elementClass.isAssignableFrom(objClass))) + return false; + for (int a = 0; a < Array.getLength(obj); ++a) + { + Object elem = Array.get(obj, a); + if (elem != null && + (!(elementType.isValue(elem)))) + return false; + } + return true; + } + + /** + * <p> + * Returns a textual representation of this instance. This + * is constructed using the class name + * (<code>javax.management.openmbean.ArrayType</code>) + * and each element of the instance which is relevant to + * the definition of {@link equals(java.lang.Object)} and + * {@link hashCode()} (i.e. the type name, the number of + * dimensions and the element type). + * </p> + * <p> + * As instances of this class are immutable, the return value + * is computed just once for each instance and reused + * throughout its life. + * </p> + * + * @return a @link{java.lang.String} instance representing + * the instance in textual form. + */ + public String toString() + { + if (string == null) + string = getClass().getName() + + "[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 new file mode 100644 index 000000000..c3d2b2d9d --- /dev/null +++ b/libjava/classpath/javax/management/openmbean/CompositeData.java @@ -0,0 +1,153 @@ +/* CompositeData.java -- A composite data structure. + Copyright (C) 2006, 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.openmbean; + +import java.util.Collection; + +/** + * Provides an interface to a composite data structure, + * in order to aid interoperability. The composite data + * structure is represented by mapping field names to + * values. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public interface CompositeData +{ + + /** + * Returns true if this {@link CompositeData} instance contains + * the specified key. This method always returns false for + * an input key equal to <code>null</code> or the empty string. + * + * @param key the key to find in the structure. + * @return true if the key exists. + */ + boolean containsKey(String key); + + /** + * Returns true if this {@link CompositeData} instance has + * a value equal to that supplied. + * + * @param value the value to look for. + * @return true if the value exists. + */ + boolean containsValue(Object value); + + /** + * Compares the specified object with this object for equality. + * The object is judged equivalent if it is non-null, and also + * an instance of {@link CompositeData} with the same name-value + * mappings and types. The two compared instances may be + * equivalent even if they represent different implementations of + * {@link CompositeData}. + * + * @param obj the object to compare for equality. + * @return true if <code>obj</code> is equal to <code>this</code>. + */ + boolean equals(Object obj); + + /** + * Retrieves the value for the specified key. + * + * @param key the key whose value should be returned. + * @return the matching value. + * @throws IllegalArgumentException if the key is <code>null</code> + * or the empty string. + * @throws InvalidKeyException if the key does not exist. + */ + Object get(String key); + + /** + * Returns the appropriate value for each key in the given array, + * using the same ordering. + * + * @param keys the keys whose values should be returned. + * @return the matching values. + * @throws IllegalArgumentException if one of the keys is + * <code>null</code> or the + * empty string. + * @throws InvalidKeyException if one of the keys does not exist. + */ + Object[] getAll(String[] keys); + + /** + * Returns the composite type which corresponds to this instance + * of {@link CompositeData}. + * + * @return the composite type for this instance. + */ + CompositeType getCompositeType(); + + /** + * Returns the hash code of this instance. The hash code is + * computed as the sum of the hash codes of all the values plus + * the hash code of the composite type. As equality comparisons + * take place using this same information, this ensures that + * the property, <code>e1.equals(e2)</code> implies + * <code>e1.hashCode() == e2.hashCode(), holds for any pair + * of instances, <code>e1</code> and <code>e2</code>. + * + * @return the hash code of this {@link CompositeData}. + * @see Object#equals(Object) + */ + int hashCode(); + + /** + * Returns a textual representation of this instance. The + * exact format is left up to the implementation, but it + * should contain the name of the implementing class, + * the name of the type and a mapping of the form + * <code>key=value</code> for each pair of key and value. + * + * @return a {@link java.lang.String} representation of the + * object. + */ + String toString(); + + /** + * Returns a read-only collection of the values associated with + * this instance. The values are sorted using the lexicographic + * ordering of the corresponding keys. + * + * @return the values of this instance. + */ + 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 000000000..4f10f6ea2 --- /dev/null +++ b/libjava/classpath/javax/management/openmbean/CompositeDataInvocationHandler.java @@ -0,0 +1,190 @@ +/* CompositeDataInvocationHandler.java - Pseudo-accessors for CompositeData. + Copyright (C) 2007 Free Software Foundation + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package javax.management.openmbean; + +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; + +/** + * <p> + * Provides an {@link java.lang.reflect.InvocationHandler} which + * implements a series of accessor methods (those beginning with + * {@code "get"} or {@code "is"}) using the content of a + * {@link CompositeData} object. An instance of {@link CompositeData} + * consists of a series of key-value mappings. This handler assumes + * these keys to be the names of attributes, and thus provides + * accessor methods by returning the associated value. + * </p> + * <p> + * As an example, consider the following interface: + * </p> + * <pre> + * public interface Person + * { + * public String getName(); + * public Date getBirthday(); + * } + * </pre> + * <p> + * This specifies two accessor methods for retrieving the attributes, + * {@code name} and {@code birthday}. An implementation of this interface + * can be provided by creating an instance of this class, using a + * {@link CompositeData} object with appropriate key-value mappings + * (e.g. "name" => "Fred", "birthday" => 30/06/1974), and then passing + * that to {@link java.lang.reflect.Proxy#newProxyInstance} along with + * the interface itself. The invocation handler implements the methods + * by calling {@link CompositeData#get(String)} with the appropriate key. + * </p> + * <p> + * The attribute name is derived by taking the remainder of the method + * name following {@code "get"}. If the first letter of this substring + * is uppercase, then two attempts are made to retrieve the attribute + * from the {@link CompositeData} instance: one using the original substring, + * and one with the first letter changed to its lower-case equivalent. + * If the first letter is lowercase, only the exact substring is used. + * </p> + * <p> + * An {@link Object#equals(Object)} implementation is provided. This returns + * true if the argument is a proxy with a {@link CompositeDataInvocationHandler} + * using an equivalent {@link CompositeData} instance. {@link Object#hashCode()} + * is also defined so as to match this implementation and give equivalent instances + * the same hashcode. + * </p> + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.6 + */ +public class CompositeDataInvocationHandler + implements InvocationHandler +{ + + /** + * The {@link CompositeData} providing the key-value mappings. + */ + private CompositeData data; + + /** + * Constructs a new {@link CompositeDataInvocationHandler} + * with the specified {@link CompositeData} instance. + * + * @param data the {@link CompositeData} instance to use. + * @throws IllegalArgumentException if {@code data} is {@code null}. + */ + public CompositeDataInvocationHandler(CompositeData data) + { + if (data == null) + throw new IllegalArgumentException("The CompositeData instance " + + "must be non-null."); + this.data = data; + } + + /** + * Returns the {@link CompositeData} instance which provides + * the key-value mappings for this instance. This is never + * {@code null}. + * + * @return the {@link CompositeData} instance. + */ + public CompositeData getCompositeData() + { + return data; + } + + /** + * Called by the proxy class whenever a method is called. The + * handler only deals with accessor methods (beginning with + * {@code "get"} or {@code "is"}), {@code equals}, and + * {@code "hashCode"}. Accessor methods are implemented by + * returning the appropriate value from the {@link CompositeData} + * instance, while {@code equals} and {@code hashCode} allow + * two proxies with a {@link CompositeDataInvocationHandler} using + * the same {@link CompositeData} instance to be classified + * as equivalent. + * + * @param proxy the proxy on which the method was called. + * @param method the method which was called. + * @param args the arguments supplied to the method. + * @return the return value from the method. + * @throws Throwable if an exception is thrown in the process. + */ + public Object invoke(Object proxy, Method method, Object[] args) + throws Throwable + { + String mName = method.getName(); + if (mName.equals("equals")) + { + if (args[0] instanceof Proxy) + { + InvocationHandler h = Proxy.getInvocationHandler(args[0]); + if (h instanceof CompositeDataInvocationHandler) + return data.equals(((CompositeDataInvocationHandler) + h).getCompositeData()); + } + return false; + } + if (mName.equals("hashCode")) + { + return data.hashCode(); + } + String attrib = null; + if (mName.startsWith("get")) + attrib = mName.substring(3); + else if (mName.startsWith("is")) + attrib = mName.substring(2); + if (attrib == null) + throw new NoSuchMethodException(mName + " is not an accessor."); + if (!data.containsKey(attrib)) + { + if (Character.isLowerCase(attrib.charAt(0))) + throw new NoSuchMethodException("The attribute " + + attrib + " is not available " + + "in the given CompositeData " + + "object"); + attrib = Character.toLowerCase(attrib.charAt(0)) + + attrib.substring(1); + if (!data.containsKey(attrib)) + throw new NoSuchMethodException("The attribute " + + attrib + " is not available " + + "in the given CompositeData " + + "object"); + } + return data.get(attrib); + } + +} diff --git a/libjava/classpath/javax/management/openmbean/CompositeDataSupport.java b/libjava/classpath/javax/management/openmbean/CompositeDataSupport.java new file mode 100644 index 000000000..2cc6f4049 --- /dev/null +++ b/libjava/classpath/javax/management/openmbean/CompositeDataSupport.java @@ -0,0 +1,345 @@ +/* CompositeData.java -- A composite data structure implementation. + Copyright (C) 2006, 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.openmbean; + +import java.io.Serializable; + +import java.util.Collection; +import java.util.Collections; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; +import java.util.SortedMap; +import java.util.TreeMap; + +/** + * Provides an implementation of the {@link CompositeData} + * interface. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public class CompositeDataSupport + implements CompositeData, Serializable +{ + + /** + * Compatible with JDK 1.5 + */ + private static final long serialVersionUID = 8003518976613702244L; + + /** + * Mapping of field names to values. + * + * @serial the map of field names to values. + */ + private SortedMap<String, Object> contents; + + /** + * The composite type which represents this composite data instance. + * + * @serial the type information for this instance. + */ + private CompositeType compositeType; + + /** + * Constructs a new {@link CompositeDataSupport} instance with the + * specified type using field names and values from the supplied map. + * The keys of the map become the field names, while the values + * become the values of each respective field. This constructor simply + * calls the other constructor, with the two arrays formed using the + * keys and values of this map, respectively. Thus, the input parameters + * given should conform to the same requirements given there (i.e. no + * null values or empty strings). + * + * @param type the composite type of this composite data structure. + * @param items a mapping of field names to values. This should match + * the mappings given by the type (i.e. for each mapping + * in the type, there should be a corresponding field name + * with a value of the correct type). + * @throws IllegalArgumentException if the type, the map or any of the keys + * or values in the map are <code>null</code>, + * or if any key from the map is an empty + * string. + * @throws OpenDataException if a mismatch occurs between the map and the + * field name/type specification given by the + * {@link CompositeType} instance. This may be + * due to the two having a different size, a + * mismatch between keys or an incorrectly typed + * value. + * @throws ArrayStoreException if one of the keys is not a + * {@link java.lang.String} (thus calling a failure + * in converting the keys to an array of strings). + */ + public CompositeDataSupport(CompositeType type, Map<String, ?> items) + throws OpenDataException + { + this(type, + items.keySet().toArray(new String[items.size()]), + items.values().toArray()); + } + + /** + * Constructs a new {@link CompositeDataSupport} instance with the + * specified type using the supplied arrays of field names and + * values. Neither the type, the two arrays or any elements of the + * arrays may be <code>null</code>. The {@link java.lang.String}s + * within the <code>names</code> array must be non-empty. The + * arrays must match in size and order, as each element of the + * <code>names</code> array is matched against the corresponding + * value in the <code>values</code> array. Internally, the two are + * stored in a map, lexographically ordered using the field names. + * The data given should also conform to the description of the + * instance given by the {@link CompositeType} instance supplied. + * + * @param type the composite type of this composite data structure. + * @param names the field names. + * @param values the corresponding values of the fields. + * @throws IllegalArgumentException if the type, the arrays or any of the keys + * or values in the arrays are <code>null</code>, + * or if any key from <code>names</code> is + * an empty string. This also occurs if the + * arrays differ in length. + * @throws OpenDataException if a mismatch occurs between the arrays and the + * field name/type specification given by the + * {@link CompositeType} instance. This may be + * due to a differing number of field names, a + * mismatch between names or an incorrectly typed + * value. + */ + public CompositeDataSupport(CompositeType type, String[] names, Object[] values) + throws OpenDataException + { + if (type == null) + throw new IllegalArgumentException("The given composite type is null."); + compositeType = type; + if (names == null) + throw new IllegalArgumentException("The names array is null."); + if (values == null) + throw new IllegalArgumentException("The values array is null."); + if (names.length != values.length) + throw new IllegalArgumentException("The sizes of the arrays differ."); + Set<String> typeKeys = type.keySet(); + if (typeKeys.size() != names.length) + throw new OpenDataException("The number of field names does not match " + + "the type description."); + contents = new TreeMap<String, Object>(); + for (int a = 0; a < names.length; ++a) + { + if (names[a] == null) + throw new IllegalArgumentException("Element " + a + " of the names " + + "array is null."); + if (names[a].length() == 0) + throw new IllegalArgumentException("Element " + a + " of the names " + + "array is an empty string."); + if (values[a] == null) + throw new IllegalArgumentException("Element " + a + " of the values " + + "array is null."); + if (!(typeKeys.contains(names[a]))) + throw new OpenDataException("The name, " + names[a] + ", is not a " + + "field in the given type description."); + if (!(type.getType(names[a]).isValue(values[a]))) + throw new OpenDataException("The value, " + values[a] + ", is not a " + + "valid value for the " + names[a] + " field."); + contents.put(names[a], values[a]); + } + } + + /** + * Returns true if this {@link CompositeData} instance contains + * the specified key. This method always returns false for + * an input key equal to <code>null</code> or the empty string. + * + * @param key the key to find in the structure. + * @return true if the key exists. + */ + public boolean containsKey(String key) + { + if (key == null || key.length() == 0) + return false; + else + return contents.containsKey(key); + } + + /** + * Returns true if this {@link CompositeData} instance has + * a value equal to that supplied. + * + * @param value the value to look for. + * @return true if the value exists. + */ + public boolean containsValue(Object value) + { + return contents.containsValue(value); + } + + + /** + * Compares the specified object with this object for equality. + * The object is judged equivalent if it is non-null, and also + * an instance of {@link CompositeData} with the same name-value + * mappings and types. The two compared instances may be + * equivalent even if they represent different implementations of + * {@link CompositeData}. + * + * @param obj the object to compare for equality. + * @return true if <code>obj</code> is equal to <code>this</code>. + */ + public boolean equals(Object obj) + { + if (!(obj instanceof CompositeData)) + return false; + CompositeData data = (CompositeData) obj; + if (!(data.getCompositeType().equals(compositeType))) + return false; + for (String key : contents.keySet()) + { + if (!(data.containsKey(key))) + return false; + if (!(data.get(key).equals(contents.get(key)))) + return false; + } + return true; + } + + /** + * Retrieves the value for the specified key. + * + * @param key the key whose value should be returned. + * @return the matching value. + * @throws IllegalArgumentException if the key is <code>null</code> + * or the empty string. + * @throws InvalidKeyException if the key does not exist. + */ + public Object get(String key) + { + if (key == null) + throw new IllegalArgumentException("The supplied key is null."); + if (key.length() == 0) + throw new IllegalArgumentException("The supplied key is the empty string."); + if (!(contents.containsKey(key))) + throw new InvalidKeyException("The supplied key does not exist."); + return contents.get(key); + } + + /** + * Returns the appropriate value for each key in the given array, + * using the same ordering. + * + * @param keys the keys whose values should be returned. + * @return the matching values. + * @throws IllegalArgumentException if one of the keys is + * <code>null</code> or the + * empty string. + * @throws InvalidKeyException if one of the keys does not exist. + */ + public Object[] getAll(String[] keys) + { + Object[] values = new Object[keys.length]; + for (int a = 0; a < keys.length; ++a) + values[a] = get(keys[a]); + return values; + } + + + /** + * Returns the composite type which corresponds to this instance + * of {@link CompositeData}. + * + * @return the composite type for this instance. + */ + public CompositeType getCompositeType() + { + return compositeType; + } + + /** + * Returns the hash code of this instance. The hash code is + * computed as the sum of the hash codes of all the values plus + * the hash code of the composite type. As equality comparisons + * take place using this same information, this should ensure that + * the property, <code>e1.equals(e2)</code> implies + * <code>e1.hashCode() == e2.hashCode(), holds for any pair + * of instances, <code>e1</code> and <code>e2</code>. However, + * this relies on the other instance implementing the + * <code>hashCode</code> method correctly, if it is not an + * instance of {@link CompositeDataSupport}. + * + * @return the hash code of this {@link CompositeData}. + * @see Object#equals(Object) + */ + public int hashCode() + { + int code = compositeType.hashCode(); + for (Object o : contents.values()) + code += o.hashCode(); + return code; + } + + + /** + * Returns a textual representation of this instance. The + * exact format is left up to the implementation, but it + * should contain the name of the implementing class, + * the name of the type and a mapping of the form + * <code>key=value</code> for each pair of key and value. + * + * @return a {@link java.lang.String} representation of the + * object. + */ + public String toString() + { + return getClass().getName() + + "[compositeType=" + compositeType + + ",contents=" + contents + + "]"; + } + + /** + * Returns a read-only collection of the values associated with + * this instance. The values are sorted using the lexicographic + * ordering of the corresponding keys. + * + * @return the values of this instance. + */ + public Collection<?> values() + { + return Collections.unmodifiableCollection(contents.values()); + } + +} diff --git a/libjava/classpath/javax/management/openmbean/CompositeType.java b/libjava/classpath/javax/management/openmbean/CompositeType.java new file mode 100644 index 000000000..e36fed151 --- /dev/null +++ b/libjava/classpath/javax/management/openmbean/CompositeType.java @@ -0,0 +1,320 @@ +/* CompositeType.java -- Type descriptor for CompositeData instances. + Copyright (C) 2006, 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.openmbean; + +import java.util.Collections; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; +import java.util.TreeMap; + +/** + * The open type descriptor for instances of the + * {@link CompositeData} class. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public class CompositeType + extends OpenType<CompositeData> +{ + + /** + * Compatible with JDK 1.5 + */ + private static final long serialVersionUID = -5366242454346948798L; + + /** + * A map of item names to their descriptions. + */ + private TreeMap<String,String> nameToDescription; + + /** + * A map of item names to their types. + */ + private TreeMap<String,OpenType<?>> nameToType; + + /** + * The hash code of this instance. + */ + private transient Integer hashCode; + + /** + * The <code>toString()</code> result of this instance. + */ + private transient String string; + + /** + * <p> + * Constructs a new {@link CompositeType} instance for the given + * type name with the specified field names, descriptions and types. + * All parameters, and the elements of the array parameters, must be + * non-null and {@link java.lang.String} values must be something other + * than the empty string. The arrays must be non-empty, and be of + * equal size. + * </p> + * <p> + * The result of <code>CompositeData.class.getName()</code> is adopted + * as the class name (see {@link OpenType}) and changes to the array + * elements following construction of the {@link CompositeType} instance + * will <strong>not</strong> affect the values used by the instance. + * The field names are sorted in to ascending alphanumeric order internally, + * and so ordering can not be used to differentiate between two instances. + * </p> + * + * @param name the name of this composite type. + * @param desc a description of this composite type. + * @param names the names of each field within the composite type. + * @param descs the descriptions of each field within the composite type. + * @param types the types of each field within the composite type. + * @throws IllegalArgumentException if any validity constraint listed above + * is broken. + * @throws OpenDataException if duplicate item names are provided. Item names + * are case-sensitive, but whitespace is removed + * before comparison. + */ + public CompositeType(String name, String desc, String[] names, + String[] descs, OpenType<?>[] types) + throws OpenDataException + { + super(CompositeData.class.getName(), name, desc); + if (names.length == 0 + || names.length != descs.length + || names.length != types.length) + throw new IllegalArgumentException("Arrays must be non-empty " + + "and of equal size."); + nameToDescription = new TreeMap<String,String>(); + for (int a = 0; a < names.length; ++a) + { + if (names[a] == null) + throw new IllegalArgumentException("Name " + a + " is null."); + if (descs[a] == null) + throw new IllegalArgumentException("Description " + a + + " is null."); + String fieldName = names[a].trim(); + if (fieldName.length() == 0) + throw new IllegalArgumentException("Name " + a + " is " + + "the empty string."); + if (descs[a].length() == 0) + throw new IllegalArgumentException("Description " + a + " is " + + "the empty string."); + if (nameToDescription.containsKey(fieldName)) + throw new OpenDataException(fieldName + " appears more " + + "than once."); + nameToDescription.put(fieldName, descs[a]); + } + nameToType = new TreeMap<String,OpenType<?>>(); + for (int a = 0; a < names.length; ++a) + nameToType.put(names[a].trim(), types[a]); + } + + /** + * Returns true if this composite data type has a field + * with the given name. + * + * @param name the name of the field to check for. + * @return true if a field of that name exists. + */ + public boolean containsKey(String name) + { + return nameToDescription.containsKey(name); + } + + /** + * <p> + * Compares this composite data type with another object + * for equality. The objects are judged to be equal if: + * </p> + * <ul> + * <li><code>obj</code> is not null.</li> + * <li><code>obj</code> is an instance of + * {@link CompositeType}.</li> + * <li>The type names are equal.</li> + * <li>The fields and their types match.</li> + * </ul> + * + * @param obj the object to compare with. + * @return true if the conditions above hold. + */ + public boolean equals(Object obj) + { + if (!(obj instanceof CompositeType)) + return false; + CompositeType ctype = (CompositeType) obj; + if (!(ctype.getTypeName().equals(getTypeName()))) + return false; + Set<String> keys = keySet(); + if (!(ctype.keySet().equals(keys))) + return false; + for (String key : keys) + { + if (!(ctype.getType(key).equals(getType(key)))) + return false; + } + return true; + } + + /** + * Returns the description for the given field name, + * or <code>null</code> if the field name does not + * exist within this composite data type. + * + * @param name the name of the field whose description + * should be returned. + * @return the description, or <code>null</code> if the + * field doesn't exist. + */ + public String getDescription(String name) + { + return nameToDescription.get(name); + } + + /** + * Returns the type for the given field name, + * or <code>null</code> if the field name does not + * exist within this composite data type. + * + * @param name the name of the field whose type + * should be returned. + * @return the type, or <code>null</code> if the + * field doesn't exist. + */ + public OpenType<?> getType(String name) + { + return nameToType.get(name); + } + + /** + * <p> + * Returns the hash code of the composite data type. + * This is computed as the sum of the hash codes of + * each field name and its type, together with the hash + * code of the type name. These are the same elements + * of the type that are compared as part of the + * {@link #equals(java.lang.Object)} method, thus ensuring + * that the hashcode is compatible with the equality + * test. + * </p> + * <p> + * As instances of this class are immutable, the hash code + * is computed just once for each instance and reused + * throughout its life. + * </p> + * + * @return the hash code of this instance. + */ + public int hashCode() + { + if (hashCode == null) + { + int elementTotal = 0; + for (Map.Entry<String,OpenType<?>> entry : nameToType.entrySet()) + { + elementTotal += (entry.getKey().hashCode() + + entry.getValue().hashCode()); + } + hashCode = Integer.valueOf(elementTotal + + getTypeName().hashCode()); + } + return hashCode.intValue(); + } + + /** + * Returns true if the specified object is a member of this + * composite type. The object is judged to be so if it is + * an instance of {@link CompositeData} with an equivalent + * type, according to the definition of + * {@link #equals(java.lang.Object)} for {@link CompositeType}. + * + * @param obj the object to test for membership. + * @return true if the object is a member of this type. + */ + public boolean isValue(Object obj) + { + if (obj instanceof CompositeData) + { + CompositeData data = (CompositeData) obj; + return equals(data.getCompositeType()); + } + return false; + } + + /** + * Returns an unmodifiable {@link java.util.Set}-based + * view of the field names that form part of this + * {@link CompositeType} instance. The names are stored + * in ascending alphanumeric order. + * + * @return a unmodifiable set containing the field + * name {@link java.lang.String}s. + */ + public Set<String> keySet() + { + return Collections.unmodifiableSet(nameToDescription.keySet()); + } + + /** + * <p> + * Returns a textual representation of this instance. This + * is constructed using the class name + * (<code>javax.management.openmbean.CompositeType</code>) + * and each element of the instance which is relevant to + * the definition of {@link equals(java.lang.Object)} and + * {@link hashCode()} (i.e. the type name, and the name + * and type of each field). + * </p> + * <p> + * As instances of this class are immutable, the return value + * is computed just once for each instance and reused + * throughout its life. + * </p> + * + * @return a @link{java.lang.String} instance representing + * the instance in textual form. + */ + public String toString() + { + if (string == null) + string = getClass().getName() + + "[name=" + getTypeName() + + ", fields=" + nameToType + + "]"; + return string; + } + +} diff --git a/libjava/classpath/javax/management/openmbean/InvalidKeyException.java b/libjava/classpath/javax/management/openmbean/InvalidKeyException.java new file mode 100644 index 000000000..e9458ba91 --- /dev/null +++ b/libjava/classpath/javax/management/openmbean/InvalidKeyException.java @@ -0,0 +1,76 @@ +/* InvalidKeyException.java -- Thrown by an invalid composite/tabular key. + Copyright (C) 2006 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.openmbean; + +/** + * Thrown when an invalid key (a field name or row index) is + * passed to a method of the {@link CompositeData} or + * {@link TabularData} classes. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public class InvalidKeyException + extends IllegalArgumentException +{ + + /** + * Compatible with JDK 1.5 + */ + private static final long serialVersionUID = 4224269443946322062L; + + /** + * Constructs a new <code>InvalidKeyException</code>. + */ + public InvalidKeyException() + { + super(); + } + + /** + * Constructs a new <code>InvalidKeyException</code> + * with the specified message. + * + * @param message the error message to give to the user. + */ + public InvalidKeyException(String message) + { + super(message); + } + +} diff --git a/libjava/classpath/javax/management/openmbean/InvalidOpenTypeException.java b/libjava/classpath/javax/management/openmbean/InvalidOpenTypeException.java new file mode 100644 index 000000000..b4f49ba13 --- /dev/null +++ b/libjava/classpath/javax/management/openmbean/InvalidOpenTypeException.java @@ -0,0 +1,75 @@ +/* InvalidOpenTypeException.java -- Thrown by an invalid open type. + Copyright (C) 2006 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.openmbean; + +/** + * Thrown when a open data value has an erroneous open + * type. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public class InvalidOpenTypeException + extends IllegalArgumentException +{ + + /** + * Compatible with JDK 1.5 + */ + private static final long serialVersionUID = -2837312755412327534L; + + /** + * Constructs a new <code>InvalidOpenTypeException</code>. + */ + public InvalidOpenTypeException() + { + super(); + } + + /** + * Constructs a new <code>InvalidOpenTypeException</code> + * with the specified message. + * + * @param message the error message to give to the user. + */ + public InvalidOpenTypeException(String message) + { + super(message); + } + +} diff --git a/libjava/classpath/javax/management/openmbean/KeyAlreadyExistsException.java b/libjava/classpath/javax/management/openmbean/KeyAlreadyExistsException.java new file mode 100644 index 000000000..69b22c433 --- /dev/null +++ b/libjava/classpath/javax/management/openmbean/KeyAlreadyExistsException.java @@ -0,0 +1,76 @@ +/* KeyAlreadyExistsException.java -- Thrown when a key clashes with another. + Copyright (C) 2006 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.openmbean; + +/** + * Thrown when a key (a field name or row index) is passed to a method + * of the {@link CompositeData} or {@link TabularData} classes and it + * is found to already be in use. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public class KeyAlreadyExistsException + extends IllegalArgumentException +{ + + /** + * Compatible with JDK 1.5 + */ + private static final long serialVersionUID = 1845183636745282866L; + + /** + * Constructs a new <code>KeyAlreadyExistsException</code>. + */ + public KeyAlreadyExistsException() + { + super(); + } + + /** + * Constructs a new <code>KeyAlreadyExistsException</code> + * with the specified message. + * + * @param message the error message to give to the user. + */ + public KeyAlreadyExistsException(String message) + { + super(message); + } + +} diff --git a/libjava/classpath/javax/management/openmbean/OpenDataException.java b/libjava/classpath/javax/management/openmbean/OpenDataException.java new file mode 100644 index 000000000..5e2a0b746 --- /dev/null +++ b/libjava/classpath/javax/management/openmbean/OpenDataException.java @@ -0,0 +1,78 @@ +/* OpenDataException.java -- Thrown by invalid open bean data. + Copyright (C) 2006 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.openmbean; + +import javax.management.JMException; + +/** + * Thrown when an instance of one of the open types, open + * data objects or open metadata information objects could + * not be created due to invalid construction parameters. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public class OpenDataException + extends JMException +{ + + /** + * Compatible with JDK 1.5 + */ + private static final long serialVersionUID = 8346311255433349870L; + + /** + * Constructs a new <code>OpenDataException</code>. + */ + public OpenDataException() + { + super(); + } + + /** + * Constructs a new <code>OpenDataException</code> + * with the specified message. + * + * @param message the error message to give to the user. + */ + public OpenDataException(String message) + { + super(message); + } + +} diff --git a/libjava/classpath/javax/management/openmbean/OpenMBeanAttributeInfo.java b/libjava/classpath/javax/management/openmbean/OpenMBeanAttributeInfo.java new file mode 100644 index 000000000..d52130600 --- /dev/null +++ b/libjava/classpath/javax/management/openmbean/OpenMBeanAttributeInfo.java @@ -0,0 +1,120 @@ +/* OpenMBeanAttributeInfo.java -- Open typed info about an attribute. + Copyright (C) 2006 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.openmbean; + +/** + * Describes an attribute associated with an open management bean. + * This interface includes those methods specified by {@link + * javax.management.MBeanAttributeInfo}, so implementations should + * extend this class. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public interface OpenMBeanAttributeInfo + extends OpenMBeanParameterInfo +{ + + /** + * Compares this attribute with the supplied object. This returns + * true iff the object is an instance of {@link OpenMBeanAttributeInfo} + * with an equal name and open type, the same default, minimum, + * maximum and legal values and the same access properties + * ({@link #isIs()}, {@link #isReadable()}, {@link #isWritable()}). + * + * @param obj the object to compare. + * @return true if the object is a {@link OpenMBeanParameterInfo} + * instance, + * <code>name.equals(object.getName())</code>, + * <code>openType.equals(object.getOpenType())</code>, + * <code>defaultValue.equals(object.getDefaultValue())</code>, + * <code>minValue.equals(object.getMinValue())</code>, + * <code>maxValue.equals(object.getMaxValue())</code>, + * <code>legalValues.equals(object.getLegalValues())</code>, + * <code>is == object.isIs()</code>, + * <code>isRead == object.isReadable()</code>, + * and <code>isWrite == object.isWritable()</code>. + */ + boolean equals(Object obj); + + /** + * Returns the hashcode of the attribute information as the sum of + * the hashcodes of the name, open type, default value, maximum + * value, minimum value, the set of legal values and the access + * properties. + * + * @return the hashcode of the attribute information. + */ + int hashCode(); + + /** + * Returns true if the accessor method of this attribute + * is of the form <code>isXXX</code>. + * + * @return true if the accessor takes the form <code>isXXX</code>. + */ + boolean isIs(); + + /** + * Returns true if value of this attribute can be read. + * + * @return true if the value of the attribute can be read. + */ + boolean isReadable(); + + /** + * Returns true if the value of this attribute can be changed. + * + * @return true if the value of the attribute can be changed. + */ + boolean isWritable(); + + /** + * Returns a textual representation of this instance. This + * is constructed using the class name + * (<code>javax.management.openmbean.OpenMBeanAttributeInfo</code>) + * along with the name, open type, default, minimum, maximum + * and legal values of the parameter and the access permissions + * ({@link #isIs()}, {@link #isReadable()}, {@link #isWritable()}). + * + * @return a @link{java.lang.String} instance representing + * the instance in textual form. + */ + String toString(); + +} diff --git a/libjava/classpath/javax/management/openmbean/OpenMBeanAttributeInfoSupport.java b/libjava/classpath/javax/management/openmbean/OpenMBeanAttributeInfoSupport.java new file mode 100644 index 000000000..098f72e71 --- /dev/null +++ b/libjava/classpath/javax/management/openmbean/OpenMBeanAttributeInfoSupport.java @@ -0,0 +1,547 @@ +/* OpenMBeanAttributeInfoSupport.java -- Open typed info about an attribute. + Copyright (C) 2006, 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.openmbean; + +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + +import javax.management.MBeanAttributeInfo; + +/** + * Describes an attribute of an open management bean. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public class OpenMBeanAttributeInfoSupport + extends MBeanAttributeInfo + implements OpenMBeanAttributeInfo +{ + + /** + * Compatible with JDK 1.5 + */ + private static final long serialVersionUID = -4867215622149721849L; + + /** + * The open type of the attribute. + */ + private OpenType<?> openType; + + /** + * The default value of the attribute (may be <code>null</code>). + */ + private Object defaultValue; + + /** + * The possible legal values of the attribute (may be <code>null</code>). + */ + private Set<?> legalValues; + + /** + * The minimum value of the attribute (may be <code>null</code>). + */ + private Comparable<?> minValue; + + /** + * The maximum value of the attribute (may be <code>null</code>). + */ + private Comparable<?> maxValue; + + /** + * The hash code of this instance. + */ + private transient Integer hashCode; + + /** + * The <code>toString()</code> result of this instance. + */ + private transient String string; + + /** + * Constructs a new {@link OpenMBeanAttributeInfo} using the + * specified name, description, open type and access properties. + * The name, description and open type may not be <code>null</code> + * and the name and description may not be equal to the empty + * string. + * + * @param name the name of the attribute. + * @param desc a description of the attribute. + * @param type the open type of the attribute. + * @param isReadable true if the attribute's value can be read. + * @param isWritable true if the attribute's value can be changed. + * @param isIs true if the attribute uses an accessor of the form isXXX. + * @throws IllegalArgumentException if the name, description or + * open type are <code>null</code> + * or the name or description are + * the empty string. + */ + public OpenMBeanAttributeInfoSupport(String name, String desc, OpenType<?> type, + boolean isReadable, boolean isWritable, + boolean isIs) + { + super(name, type == null ? null : type.getClassName(), desc, isReadable, + isWritable, isIs); + if (name == null) + throw new IllegalArgumentException("The name may not be null."); + if (desc == null) + throw new IllegalArgumentException("The description may not be null."); + if (type == null) + throw new IllegalArgumentException("The type may not be null."); + if (name.length() == 0) + throw new IllegalArgumentException("The name may not be the empty string."); + if (desc.length() == 0) + throw new IllegalArgumentException("The description may not be the " + + "empty string."); + } + + /** + * Constructs a new {@link OpenMBeanAttributeInfo} using the + * specified name, description, open type and default value. The + * name, description and open type cannot be <code>null</code> and + * the name and description may not be equal to the empty string. + * The default value may be <code>null</code>. If non-null, it must + * be a valid value of the given open type. Default values are not + * applicable to the open types, {@link ArrayType} and {@link + * TabularType}. + * + * @param name the name of the attribute. + * @param desc a description of the attribute. + * @param type the open type of the attribute. + * @param isReadable true if the attribute's value can be read. + * @param isWritable true if the attribute's value can be changed. + * @param isIs true if the attribute uses an accessor of the form isXXX. + * @param defaultValue the default value of the attribute. + * @throws IllegalArgumentException if the name, description or + * open type are <code>null</code> + * or the name or description are + * the empty string. + * @throws OpenDataException if <code>defaultValue<code> is non-null + * and is either not a value of the given + * open type or the open type is an instance + * of {@link ArrayType} or {@link TabularType}. + */ + public <T> OpenMBeanAttributeInfoSupport(String name, String desc, OpenType<T> type, + boolean isReadable, boolean isWritable, + boolean isIs, T defaultValue) + throws OpenDataException + { + this(name, desc, type, isReadable, isWritable, isIs, defaultValue, null); + } + + /** + * <p> + * Constructs a new {@link OpenMBeanAttributeInfo} using the + * specified name, description, open type, access properties, + * default, maximum and minimum values. The name, description + * and open type cannot be <code>null</code> and the name and + * description may not be equal to the empty string. The + * default, maximum and minimum values may be <code>null</code>. + * The following conditions apply when the attributes mentioned + * are non-null: + * </p> + * <ul> + * <li>The values must be valid values for the given open type.</li> + * <li>Default values are not applicable to the open types, {@link + * ArrayType} and {@link TabularType}.</li> + * <li>The minimum value must be smaller than or equal to the maximum value + * (literally, <code>minValue.compareTo(maxValue) <= 0</code>.</li> + * <li>The minimum value must be smaller than or equal to the default value + * (literally, <code>minValue.compareTo(defaultValue) <= 0</code>.</li> + * <li>The default value must be smaller than or equal to the maximum value + * (literally, <code>defaultValue.compareTo(maxValue) <= 0</code>.</li> + * </ul> + * + * @param name the name of the attribute. + * @param desc a description of the attribute. + * @param type the open type of the attribute. + * @param isReadable true if the attribute's value can be read. + * @param isWritable true if the attribute's value can be changed. + * @param isIs true if the attribute uses an accessor of the form isXXX. + * @param defaultValue the default value of the attribute, or <code>null</code>. + * @param minimumValue the minimum value of the attribute, or <code>null</code>. + * @param maximumValue the maximum value of the attribute, or <code>null</code>. + * @throws IllegalArgumentException if the name, description or + * open type are <code>null</code> + * or the name or description are + * the empty string. + * @throws OpenDataException if any condition in the list above is broken. + */ + @SuppressWarnings("unchecked") + public <T> OpenMBeanAttributeInfoSupport(String name, String desc, OpenType<T> type, + boolean isReadable, boolean isWritable, + boolean isIs, T defaultValue, + Comparable<T> minimumValue, + Comparable<T> maximumValue) + throws OpenDataException + { + this(name, desc, type, isReadable, isWritable, isIs); + if (defaultValue != null && !(type.isValue(defaultValue))) + throw new OpenDataException("The default value is not a member of the " + + "open type given."); + if (minimumValue != null && !(type.isValue(minimumValue))) + throw new OpenDataException("The minimum value is not a member of the " + + "open type given."); + if (maximumValue != null && !(type.isValue(maximumValue))) + throw new OpenDataException("The maximum value is not a member of the " + + "open type given."); + if (defaultValue != null && (type instanceof ArrayType || + type instanceof TabularType)) + throw new OpenDataException("Default values are not applicable for " + + "array or tabular types."); + if (minimumValue != null && maximumValue != null + && minimumValue.compareTo((T) maximumValue) > 0) + throw new OpenDataException("The minimum value is greater than the " + + "maximum."); + if (minimumValue != null && defaultValue != null + && minimumValue.compareTo(defaultValue) > 0) + throw new OpenDataException("The minimum value is greater than the " + + "default."); + if (defaultValue != null && maximumValue != null + && maximumValue.compareTo(defaultValue) < 0) + throw new OpenDataException("The default value is greater than the " + + "maximum."); + + openType = type; + this.defaultValue = defaultValue; + minValue = minimumValue; + maxValue = maximumValue; + } + + /** + * <p> + * Constructs a new {@link OpenMBeanAttributeInfo} using the + * specified name, description, open type, access properties, default + * value and set of legal values. The name, description and open type + * cannot be <code>null</code> and the name and description may not be + * equal to the empty string. The default, maximum and minimum values + * may be <code>null</code>. The following conditions apply when the + * attributes mentioned are non-null: + * </p> + * <ul> + * <li>The default value and each of the legal values must be a valid + * value for the given open type.</li> + * <li>Default and legal values are not applicable to the open types, {@link + * ArrayType} and {@link TabularType}.</li> + * <li>The default value is not in the set of legal values.</li> + * </ul> + * <p> + * The legal values are copied from the array into a unmodifiable set, + * so future modifications to the array have no effect. + * </p> + * + * @param name the name of the attribute. + * @param desc a description of the attribute. + * @param type the open type of the attribute. + * @param isReadable true if the attribute's value can be read. + * @param isWritable true if the attribute's value can be changed. + * @param isIs true if the attribute uses an accessor of the form isXXX. + * @param defaultValue the default value of the attribute, or <code>null</code>. + * @param legalValues the legal values of the attribute. May be + * <code>null</code> or an empty array. + * @throws IllegalArgumentException if the name, description or + * open type are <code>null</code> + * or the name or description are + * the empty string. + * @throws OpenDataException if any condition in the list above is broken. + */ + public <T> OpenMBeanAttributeInfoSupport(String name, String desc, OpenType<T> type, + boolean isReadable, boolean isWritable, + boolean isIs, T defaultValue, + T[] legalValues) + throws OpenDataException + { + this(name, desc, type, isReadable, isWritable, isIs); + if (defaultValue != null && !(type.isValue(defaultValue))) + throw new OpenDataException("The default value is not a member of the " + + "open type given."); + if (defaultValue != null && (type instanceof ArrayType || + type instanceof TabularType)) + throw new OpenDataException("Default values are not applicable for " + + "array or tabular types."); + if (legalValues != null && (type instanceof ArrayType || + type instanceof TabularType)) + throw new OpenDataException("Legal values are not applicable for " + + "array or tabular types."); + if (legalValues != null && legalValues.length > 0) + { + Set<T> lv = new HashSet<T>(legalValues.length); + for (int a = 0; a < legalValues.length; ++a) + { + if (legalValues[a] != null && + !(type.isValue(legalValues[a]))) + throw new OpenDataException("The legal value, " + + legalValues[a] + + "is not a member of the " + + "open type given."); + lv.add(legalValues[a]); + } + if (defaultValue != null && !(lv.contains(defaultValue))) + throw new OpenDataException("The default value is not in the set " + + "of legal values."); + this.legalValues = Collections.unmodifiableSet(lv); + } + openType = type; + this.defaultValue = defaultValue; + } + + /** + * Compares this attribute with the supplied object. This returns + * true iff the object is an instance of {@link OpenMBeanAttributeInfo} + * with an equal name and open type and the same default, minimum, + * maximum and legal values and the same access properties. + * + * @param obj the object to compare. + * @return true if the object is a {@link OpenMBeanAttributeInfo} + * instance, + * <code>name.equals(object.getName())</code>, + * <code>openType.equals(object.getOpenType())</code>, + * <code>isRead == object.isReadable()</code>, + * <code>isWrite == object.isWritable()</code>, + * <code>isIs == object.isIs()</code>, + * <code>defaultValue.equals(object.getDefaultValue())</code>, + * <code>minValue.equals(object.getMinValue())</code>, + * <code>maxValue.equals(object.getMaxValue())</code>, + * and <code>legalValues.equals(object.getLegalValues())</code>. + */ + public boolean equals(Object obj) + { + if (!(obj instanceof OpenMBeanAttributeInfo)) + return false; + OpenMBeanAttributeInfo o = (OpenMBeanAttributeInfo) obj; + return getName().equals(o.getName()) && + openType.equals(o.getOpenType()) && + isReadable() == o.isReadable() && + isWritable() == o.isWritable() && + isIs() == o.isIs() && + (defaultValue == null ? o.getDefaultValue() == null : + defaultValue.equals(o.getDefaultValue())) && + (minValue == null ? o.getMinValue() == null : + minValue.equals(o.getMinValue())) && + (maxValue == null ? o.getMaxValue() == null : + maxValue.equals(o.getMaxValue())) && + (legalValues == null ? o.getLegalValues() == null : + legalValues.equals(o.getLegalValues())); + } + + /** + * Returns the default value of this attribute, or <code>null</code> + * if there is no default value. + * + * @return the default value of the attribute, or <code>null</code> + * if there is no default. + */ + public Object getDefaultValue() + { + return defaultValue; + } + + /** + * Returns a {@link java.util.Set} enumerating the legal values + * of this attribute, or <code>null</code> if no such limited + * set exists for this attribute. + * + * @return a set of legal values, or <code>null</code> if no such + * set exists. + */ + public Set<?> getLegalValues() + { + return legalValues; + } + + /** + * Returns the maximum value of this attribute, or <code>null</code> + * if there is no maximum. + * + * @return the maximum value, or <code>null</code> if none exists. + */ + public Comparable<?> getMaxValue() + { + return maxValue; + } + + /** + * Returns the minimum value of this attribute, or <code>null</code> + * if there is no minimum. + * + * @return the minimum value, or <code>null</code> if none exists. + */ + public Comparable<?> getMinValue() + { + return minValue; + } + + /** + * Returns the open type instance which represents the type of this + * attribute. + * + * @return the open type of this attribute. + */ + public OpenType<?> getOpenType() + { + return openType; + } + + /** + * Returns true if this attribute has a default value + * (i.e. the value is non-null). + * + * @return true if this attribute has a default. + */ + public boolean hasDefaultValue() + { + return defaultValue != null; + } + + /** + * <p> + * Returns the hashcode of the attribute information as the sum of + * the hashcodes of the name, open type, default value, maximum + * value, minimum value and the set of legal values. + * </p> + * <p> + * As instances of this class are immutable, the hash code + * is computed just once for each instance and reused + * throughout its life. + * </p> + * + * @return the hashcode of the attribute information. + */ + public int hashCode() + { + if (hashCode == null) + hashCode = Integer.valueOf(getName().hashCode() + + openType.hashCode() + + Boolean.valueOf(isReadable()).hashCode() + + (2 * + Boolean.valueOf(isWritable()).hashCode()) + + (4 * Boolean.valueOf(isIs()).hashCode()) + + (defaultValue == null ? 0 : + defaultValue.hashCode()) + + (minValue == null ? 0 : + minValue.hashCode()) + + (maxValue == null ? 0 : + maxValue.hashCode()) + + (legalValues == null ? 0 : + legalValues.hashCode())); + return hashCode.intValue(); + } + + /** + * Returns true if there is a set of legal values for this + * attribute (i.e. the value is non-null). + * + * @return true if a set of legal values exists for this + * attribute. + */ + public boolean hasLegalValues() + { + return legalValues != null; + } + + /** + * Returns true if there is a maximum value for this attribute + * (i.e. the value is non-null). + * + * @return true if a maximum value exists for this attribute. + */ + public boolean hasMaxValue() + { + return maxValue != null; + } + + /** + * Returns true if there is a minimum value for this attribute. + * (i.e. the value is non-null). + * + * @return true if a minimum value exists for this attribute. + */ + public boolean hasMinValue() + { + return minValue != null; + } + + /** + * Returns true if the specified object is a valid value for + * this attribute. + * + * @param obj the object to test. + * @return true if <code>obj</code> is a valid value for this + * attribute. + */ + public boolean isValue(Object obj) + { + return openType.isValue(obj); + } + + /** + * <p> + * Returns a textual representation of this instance. This + * is constructed using the class name + * (<code>javax.management.openmbean.OpenMBeanAttributeInfo</code>) + * along with the name, open type, access properties, default, + * minimum, maximum and legal values of the attribute. + * </p> + * <p> + * As instances of this class are immutable, the return value + * is computed just once for each instance and reused + * throughout its life. + * </p> + * + * @return a @link{java.lang.String} instance representing + * the instance in textual form. + */ + public String toString() + { + if (string == null) + string = getClass().getName() + + "[name=" + getName() + + ",openType=" + openType + + ",isReadable=" + isReadable() + + ",isWritable=" + isWritable() + + ",isIs=" + isIs() + + ",defaultValue=" + defaultValue + + ",minValue=" + minValue + + ",maxValue=" + maxValue + + ",legalValues=" + legalValues + + "]"; + return string; + } + +} diff --git a/libjava/classpath/javax/management/openmbean/OpenMBeanConstructorInfo.java b/libjava/classpath/javax/management/openmbean/OpenMBeanConstructorInfo.java new file mode 100644 index 000000000..5bccdb639 --- /dev/null +++ b/libjava/classpath/javax/management/openmbean/OpenMBeanConstructorInfo.java @@ -0,0 +1,112 @@ +/* OpenMBeanConstructorInfo.java -- Open typed info about a constructor. + Copyright (C) 2006 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.openmbean; + +import javax.management.MBeanParameterInfo; + +/** + * Describes a constructor for an open management bean. + * This interface includes those methods specified by {@link + * javax.management.MBeanConstructorInfo}, so implementations should + * extend this class. The {@link #getSignature()} method should + * return an array containing instances of {@link OpenMBeanParameterInfo}. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public interface OpenMBeanConstructorInfo +{ + + /** + * Compares this attribute with the supplied object. This returns + * true iff the object is an instance of {@link OpenMBeanConstructorInfo} + * with an equal name and signature. + * + * @param obj the object to compare. + * @return true if the object is a {@link OpenMBeanParameterInfo} + * instance, + * <code>name.equals(object.getName())</code>, + * and <code>signature.equals(object.getSignature())</code>. + */ + boolean equals(Object obj); + + /** + * Returns a description of this constructor. + * + * @return a human-readable description. + */ + String getDescription(); + + /** + * Returns the name of this constructor. + * + * @return the name of the constructor. + */ + String getName(); + + /** + * Returns the constructor's signature, in the form of + * information on each parameter. Each parameter is + * described by an instance of {@link OpenMBeanParameterInfo}. + * + * @return an array of {@link OpenMBeanParameterInfo} objects, + * describing the constructor parameters. + */ + MBeanParameterInfo[] getSignature(); + + /** + * Returns the hashcode of the constructor information as the sum of + * the hashcodes of the name and signature (calculated by + * <code>java.util.Arrays.asList(signature).hashCode()</code>). + * + * @return the hashcode of the constructor information. + */ + int hashCode(); + + /** + * Returns a textual representation of this instance. This + * is constructed using the class name + * (<code>javax.management.openmbean.OpenMBeanConstructorInfo</code>) + * along with the name and signature. + * + * @return a @link{java.lang.String} instance representing + * the instance in textual form. + */ + String toString(); + +} diff --git a/libjava/classpath/javax/management/openmbean/OpenMBeanConstructorInfoSupport.java b/libjava/classpath/javax/management/openmbean/OpenMBeanConstructorInfoSupport.java new file mode 100644 index 000000000..c187d5d13 --- /dev/null +++ b/libjava/classpath/javax/management/openmbean/OpenMBeanConstructorInfoSupport.java @@ -0,0 +1,174 @@ +/* OpenMBeanConstructorInfoSupport.java -- Open typed info about an constructor. + Copyright (C) 2006 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.openmbean; + +import java.util.Arrays; + +import javax.management.MBeanConstructorInfo; +import javax.management.MBeanParameterInfo; + +/** + * Describes a constructor for an open management bean. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public class OpenMBeanConstructorInfoSupport + extends MBeanConstructorInfo + implements OpenMBeanConstructorInfo +{ + + /** + * Compatible with JDK 1.5 + */ + private static final long serialVersionUID = -4400441579007477003L; + + /** + * The hash code of this instance. + */ + private transient Integer hashCode; + + /** + * The <code>toString()</code> result of this instance. + */ + private transient String string; + + /** + * Constructs a @link{OpenMBeanConstructorInfo} with the specified + * name, description and parameter information. A <code>null</code> + * value for the parameter information is the same as passing in + * an empty array. Neither the name nor the description may be + * null or equal to the empty string. A copy of the parameter array + * is taken, so later changes have no effect. + * + * @param name the name of the constructor. + * @param desc a description of the constructor. + * @param sig the signature of the constructor, as a series + * of {@link MBeanParameterInfo} objects, one for + * each parameter. + * @throws IllegalArgumentException if the name or description is + * either <code>null</code> + * or the empty string. + * @throws ArrayStoreException if the members of the signature array + * are not assignable to + * {@link javax.management.MBeanParameterInfo} + */ + public OpenMBeanConstructorInfoSupport(String name, String desc, + OpenMBeanParameterInfo[] sig) + { + super(name, desc, (MBeanParameterInfo[]) sig); + if (name == null) + throw new IllegalArgumentException("The name may not be null."); + if (desc == null) + throw new IllegalArgumentException("The description may not be null."); + if (name.length() == 0) + throw new IllegalArgumentException("The name may not be the empty string."); + if (desc.length() == 0) + throw new IllegalArgumentException("The description may not be the " + + "empty string."); + } + + /** + * Compares this attribute with the supplied object. This returns + * true iff the object is an instance of {@link OpenMBeanConstructorInfo} + * with an equal name and signature. + * + * @param obj the object to compare. + * @return true if the object is a {@link OpenMBeanParameterInfo} + * instance, + * <code>name.equals(object.getName())</code>, + * and <code>signature.equals(object.getSignature())</code>. + */ + public boolean equals(Object obj) + { + if (!(obj instanceof OpenMBeanConstructorInfo)) + return false; + OpenMBeanConstructorInfo o = (OpenMBeanConstructorInfo) obj; + return getName().equals(o.getName()) && + getSignature().equals(o.getSignature()); + } + + /** + * <p> + * Returns the hashcode of the constructor information as the sum of + * the hashcodes of the name and signature (calculated by + * <code>java.util.Arrays.asList(signature).hashCode()</code>). + * </p> + * <p> + * As instances of this class are immutable, the return value + * is computed just once for each instance and reused + * throughout its life. + * </p> + * + * @return the hashcode of the constructor information. + */ + public int hashCode() + { + if (hashCode == null) + hashCode = Integer.valueOf(getName().hashCode() + + Arrays.asList(getSignature()).hashCode()); + return hashCode.intValue(); + } + + /** + * <p> + * Returns a textual representation of this instance. This + * is constructed using the class name + * (<code>javax.management.openmbean.OpenMBeanConstructorInfo</code>) + * along with the name and signature. + * </p> + * <p> + * As instances of this class are immutable, the return value + * is computed just once for each instance and reused + * throughout its life. + * </p> + * + * @return a @link{java.lang.String} instance representing + * the instance in textual form. + */ + public String toString() + { + if (string == null) + string = getClass().getName() + + "[name=" + getName() + + ",signature=" + Arrays.toString(getSignature()) + + "]"; + return string; + } + +} diff --git a/libjava/classpath/javax/management/openmbean/OpenMBeanInfo.java b/libjava/classpath/javax/management/openmbean/OpenMBeanInfo.java new file mode 100644 index 000000000..98da260e7 --- /dev/null +++ b/libjava/classpath/javax/management/openmbean/OpenMBeanInfo.java @@ -0,0 +1,154 @@ +/* OpenMBeanInfo.java -- Open typed info about a management bean. + Copyright (C) 2006 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.openmbean; + +import javax.management.MBeanAttributeInfo; +import javax.management.MBeanConstructorInfo; +import javax.management.MBeanNotificationInfo; +import javax.management.MBeanOperationInfo; + +/** + * Describes an open management bean. Open management beans are + * management beans where {@link + * javax.management.DynamicMBean#getMBeanInfo()} returns an + * implementation of this interface. This interface includes those + * methods specified by {@link javax.management.MBeanInfo}, + * so implementations should extend this class. Each method + * which returns an array of one of the <code>MBeanXXXInfo</code> + * classes should return an array containing instances + * of the equivalent open version (<code>OpenMBeanXXXInfo</code>). + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public interface OpenMBeanInfo +{ + + /** + * Compares this attribute with the supplied object. This returns + * true iff the object is an instance of {@link OpenMBeanInfo} + * with the same class name and equal instances of the info classes. + * + * @param obj the object to compare. + * @return true if the object is a {@link OpenMBeanInfo} + * instance, + * <code>className.equals(object.getClassName())</code> + * and each info class has an equal in the other object. + */ + boolean equals(Object obj); + + /** + * Returns descriptions of each of the attributes provided by this + * management bean. The elements should be implementations of the + * {@link OpenMBeanAttributeInfo} class. + * + * @return an array of {@link OpenMBeanAttributeInfo} objects, + * representing the attributes emitted by this + * management bean. + */ + MBeanAttributeInfo[] getAttributes(); + + /** + * Returns the class name of the management bean. + * + * @return the bean's class name. + */ + String getClassName(); + + /** + * Returns descriptions of each of the constructors provided by this + * management bean. The elements should be implementations of the + * {@link OpenMBeanConstructorInfo} class. + * + * @return an array of {@link OpenMBeanConstructorInfo} objects, + * representing the constructors emitted by this + * management bean. + */ + MBeanConstructorInfo[] getConstructors(); + + /** + * Returns a description of this operation. + * + * @return a human-readable description. + */ + String getDescription(); + + /** + * Returns descriptions of each of the notifications provided by this + * management bean. The elements should be implementations of the + * {@link OpenMBeanNotificationInfo} class. + * + * @return an array of {@link OpenMBeanNotificationInfo} objects, + * representing the notifications emitted by this + * management bean. + */ + MBeanNotificationInfo[] getNotifications(); + + /** + * Returns descriptions of each of the operations provided by this + * management bean. The elements should be implementations of the + * {@link OpenMBeanOperationInfo} class. + * + * @return an array of {@link OpenMBeanOperationInfo} objects, + * representing the operations emitted by this + * management bean. + */ + MBeanOperationInfo[] getOperations(); + + /** + * Returns the hashcode of the bean information as the sum of the + * hashcodes of the class name and each array (calculated using + * java.util.HashSet(<code>java.util.Arrays.asList(signature)).hashCode()</code>). + * + * @return the hashcode of the bean information. + */ + int hashCode(); + + /** + * Returns a textual representation of this instance. This + * is constructed using the class name + * (<code>javax.management.openmbean.OpenMBeanInfo</code>) + * along with the class name and textual representations + * of each array. + * + * @return a @link{java.lang.String} instance representing + * the instance in textual form. + */ + String toString(); + +} diff --git a/libjava/classpath/javax/management/openmbean/OpenMBeanInfoSupport.java b/libjava/classpath/javax/management/openmbean/OpenMBeanInfoSupport.java new file mode 100644 index 000000000..c335d7512 --- /dev/null +++ b/libjava/classpath/javax/management/openmbean/OpenMBeanInfoSupport.java @@ -0,0 +1,191 @@ +/* OpenMBeanInfoSupport.java -- Open typed info about a bean. + Copyright (C) 2006 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.openmbean; + +import java.util.Arrays; +import java.util.HashSet; + +import javax.management.MBeanInfo; +import javax.management.MBeanAttributeInfo; +import javax.management.MBeanConstructorInfo; +import javax.management.MBeanNotificationInfo; +import javax.management.MBeanOperationInfo; + +/** + * Describes an open management bean. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public class OpenMBeanInfoSupport + extends MBeanInfo + implements OpenMBeanInfo +{ + + /** + * Compatible with JDK 1.5 + */ + private static final long serialVersionUID = 4349395935420511492L; + + /** + * The hash code of this instance. + */ + private transient Integer hashCode; + + /** + * The <code>toString()</code> result of this instance. + */ + private transient String string; + + /** + * Constructs a new {@link OpenMBeanInfo} using the supplied + * class name and description with the given attributes, + * operations, constructors and notifications. The class + * name does not have to actually specify a valid class that + * can be loaded by the MBean server or class loader; it merely + * has to be a syntactically correct class name. Any of the + * arrays may be <code>null</code>; this will be treated as if + * an empty array was supplied. A copy of the arrays is + * taken, so later changes have no effect. + * + * @param name the name of the class this instance describes. + * @param desc a description of the bean. + * @param attribs the attribute descriptions for the bean, + * or <code>null</code>. + * @param cons the constructor descriptions for the bean, + * or <code>null</code>. + * @param ops the operation descriptions for the bean, + * or <code>null</code>. + * @param notifs the notification descriptions for the bean, + * or <code>null</code>. + * @throws ArrayStoreException if a members of an array + * is not assignable to the equivalent + * <code>MBeanXXXInfo</code> class. + */ + public OpenMBeanInfoSupport(String name, String desc, + OpenMBeanAttributeInfo[] attribs, + OpenMBeanConstructorInfo[] cons, + OpenMBeanOperationInfo[] ops, + MBeanNotificationInfo[] notifs) + { + super(name, desc, (MBeanAttributeInfo[]) attribs, + (MBeanConstructorInfo[]) cons, + (MBeanOperationInfo[]) ops, + notifs); + } + + /** + * Compares this attribute with the supplied object. This returns + * true iff the object is an instance of {@link OpenMBeanInfo} + * with the same class name and equal instances of the info classes. + * + * @param obj the object to compare. + * @return true if the object is a {@link OpenMBeanInfo} + * instance, + * <code>className.equals(object.getClassName())</code> + * and each info class has an equal in the other object. + */ + public boolean equals(Object obj) + { + if (!(obj instanceof OpenMBeanInfo)) + return false; + OpenMBeanInfo o = (OpenMBeanInfo) obj; + return getClassName().equals(o.getClassName()) && + getAttributes().equals(o.getAttributes()) && + getConstructors().equals(o.getConstructors()) && + getNotifications().equals(o.getNotifications()) && + getOperations().equals(o.getOperations()); + } + + /** + * <p> + * Returns the hashcode of the bean information as the sum of the + * hashcodes of the class name and each array (calculated using + * java.util.HashSet(<code>java.util.Arrays.asList(signature)).hashCode()</code>). + * </p> + * <p> + * As instances of this class are immutable, the return value + * is computed just once for each instance and reused + * throughout its life. + * </p> + * + * @return the hashcode of the bean information. + */ + public int hashCode() + { + if (hashCode == null) + hashCode = + Integer.valueOf(getClassName().hashCode() + + new HashSet<MBeanAttributeInfo>(Arrays.asList(getAttributes())).hashCode() + + new HashSet<MBeanConstructorInfo>(Arrays.asList(getConstructors())).hashCode() + + new HashSet<MBeanNotificationInfo>(Arrays.asList(getNotifications())).hashCode() + + new HashSet<MBeanOperationInfo>(Arrays.asList(getOperations())).hashCode()); + return hashCode.intValue(); + } + + /** + * <p> + * Returns a textual representation of this instance. This + * is constructed using the class name + * (<code>javax.management.openmbean.OpenMBeanInfo</code>) + * along with the class name and textual representations + * of each array. + * </p> + * <p> + * As instances of this class are immutable, the return value + * is computed just once for each instance and reused + * throughout its life. + * </p> + * + * @return a @link{java.lang.String} instance representing + * the instance in textual form. + */ + public String toString() + { + if (string == null) + string = getClass().getName() + + "[className=" + getClassName() + + ",attributes=" + Arrays.toString(getAttributes()) + + ",constructors=" + Arrays.toString(getConstructors()) + + ",notifications=" + Arrays.toString(getNotifications()) + + ",operations=" + Arrays.toString(getOperations()) + + "]"; + return string; + } + +} diff --git a/libjava/classpath/javax/management/openmbean/OpenMBeanOperationInfo.java b/libjava/classpath/javax/management/openmbean/OpenMBeanOperationInfo.java new file mode 100644 index 000000000..3b5bf9260 --- /dev/null +++ b/libjava/classpath/javax/management/openmbean/OpenMBeanOperationInfo.java @@ -0,0 +1,154 @@ +/* OpenMBeanOperationInfo.java -- Open typed info about a operation. + Copyright (C) 2006 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.openmbean; + +import javax.management.MBeanParameterInfo; + +/** + * Describes a operation for an open management bean. + * This interface includes those methods specified by {@link + * javax.management.MBeanOperationInfo}, so implementations should + * extend this class. The {@link #getSignature()} method should + * return an array containing instances of {@link OpenMBeanParameterInfo}. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public interface OpenMBeanOperationInfo +{ + + /** + * Compares this attribute with the supplied object. This returns + * true iff the object is an instance of {@link OpenMBeanOperationInfo} + * with an equal name, signature, open return type and impact. + * + * @param obj the object to compare. + * @return true if the object is a {@link OpenMBeanParameterInfo} + * instance, + * <code>name.equals(object.getName())</code>, + * <code>signature.equals(object.getSignature())</code>, + * <code>returnOpenType.equals(object.getReturnOpenType())</code>, + * and <code>impact == object.getImpact()</code>. + */ + boolean equals(Object obj); + + /** + * Returns a description of this operation. + * + * @return a human-readable description. + */ + String getDescription(); + + /** + * <p> + * Returns the impact of performing this operation. + * The value is equal to one of the following: + * </p> + * <ol> + * <li>{@link javax.management.MBeanOperationInfo#INFO} + * — the method just returns + * information (akin to an accessor).</li> + * <li>{@link javax.management.MBeanOperationInfo#ACTION} + * the method just alters the state of the bean, without + * returning a value (akin to a mutator).</li> + * <li>{@link javax.management.MBeanOperationInfo#ACTION_INFO} + * the method both makes state changes and returns a value.</li> + * <li>{@link javax.management.MBeanOperationInfo#UNKNOWN} + * the behaviour of the operation is unknown.</li> + * </ol> + * + * @return the impact of performing the operation. + */ + int getImpact(); + + /** + * Returns the name of this operation. + * + * @return the name of the operation. + */ + String getName(); + + /** + * Returns the open type instance which represents the type of the + * return value. + * + * @return the open type of the return value. + */ + OpenType<?> getReturnOpenType(); + + /** + * Returns the return type of the operation, as the class + * name. This should be identical to + * <code>getReturnOpenType.getClassName()</code>. + * + * @return the return type. + */ + String getReturnType(); + + /** + * Returns the operation's signature, in the form of + * information on each parameter. Each parameter is + * described by an instance of {@link OpenMBeanParameterInfo}. + * + * @return an array of {@link OpenMBeanParameterInfo} objects, + * describing the operation parameters. + */ + MBeanParameterInfo[] getSignature(); + + /** + * Returns the hashcode of the operation information as the sum of + * the hashcodes of the name, open return type, impact and signature + * (calculated by + * <code>java.util.Arrays.asList(signature).hashCode()</code>). + * + * @return the hashcode of the operation information. + */ + int hashCode(); + + /** + * Returns a textual representation of this instance. This + * is constructed using the class name + * (<code>javax.management.openmbean.OpenMBeanOperationInfo</code>) + * along with the name, signature, open return type and impact. + * + * @return a @link{java.lang.String} instance representing + * the instance in textual form. + */ + String toString(); + +} diff --git a/libjava/classpath/javax/management/openmbean/OpenMBeanOperationInfoSupport.java b/libjava/classpath/javax/management/openmbean/OpenMBeanOperationInfoSupport.java new file mode 100644 index 000000000..992df344a --- /dev/null +++ b/libjava/classpath/javax/management/openmbean/OpenMBeanOperationInfoSupport.java @@ -0,0 +1,240 @@ +/* OpenMBeanOperationInfoSupport.java -- Open typed info about an operation. + Copyright (C) 2006, 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.openmbean; + +import java.util.Arrays; + +import javax.management.MBeanOperationInfo; +import javax.management.MBeanParameterInfo; + +/** + * Describes a operation for an open management bean. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public class OpenMBeanOperationInfoSupport + extends MBeanOperationInfo + implements OpenMBeanOperationInfo +{ + + /** + * Compatible with JDK 1.5 + */ + private static final long serialVersionUID = 4996859732565369366L; + + /** + * The open type representing the return value. + */ + private OpenType<?> returnOpenType; + + /** + * The hash code of this instance. + */ + private transient Integer hashCode; + + /** + * The <code>toString()</code> result of this instance. + */ + private transient String string; + + /** + * Constructs a @link{OpenMBeanOperationInfo} with the specified name, + * description, parameter information, open return type and impact. A + * <code>null</code> value for the parameter information is the same + * as passing in an empty array. A copy of the parameter array is + * taken, so later changes have no effect. The name and the + * description may not be equal to the empty string, and neither + * the name, description nor the open return type may be + * <code>null</code>. The value of <code>impact</code> must be + * one of the four valid values + * ({@link javax.management.MBeanOperationInfo#INFO}, + * {@link javax.management.MBeanOperationInfo#ACTION}, + * {@link javax.management.MBeanOperationInfo#ACTION_INFO} and + * {@link javax.management.MBeanOperationInfo#UNKNOWN}). + * + * + * @param name the name of the constructor. + * @param desc a description of the attribute. + * @param sig the signature of the method, as a series + * of {@link MBeanParameterInfo} objects, one for + * each parameter. + * @param type the open return type of the method. + * @param impact the impact of performing the operation. + * @throws IllegalArgumentException if the name, description or + * open return type is <code>null</code>, + * the name or description are equal to + * the empty string, or the impact factor + * is not one of the values enumerated + * above. + * @throws ArrayStoreException if the members of the signature array + * are not assignable to + * {@link javax.management.MBeanParameterInfo} + */ + public OpenMBeanOperationInfoSupport(String name, String desc, + OpenMBeanParameterInfo[] sig, + OpenType<?> type, int impact) + { + super(name, desc, (MBeanParameterInfo[]) sig, + type == null ? null : type.getClassName(), impact); + if (name == null) + throw new IllegalArgumentException("The name may not be null."); + if (desc == null) + throw new IllegalArgumentException("The description may not be null."); + if (type == null) + throw new IllegalArgumentException("The type may not be null."); + if (name.length() == 0) + throw new IllegalArgumentException("The name may not be the empty string."); + if (desc.length() == 0) + throw new IllegalArgumentException("The description may not be the " + + "empty string."); + if (impact != ACTION && impact != INFO && + impact != ACTION_INFO && impact != UNKNOWN) + throw new IllegalArgumentException("The impact factor is an invalid value."); + returnOpenType = type; + } + + /** + * Compares this attribute with the supplied object. This returns + * true iff the object is an instance of {@link OpenMBeanOperationInfo} + * with an equal name, signature, open return type and impact. + * + * @param obj the object to compare. + * @return true if the object is a {@link OpenMBeanParameterInfo} + * instance, + * <code>name.equals(object.getName())</code>, + * <code>signature.equals(object.getSignature())</code>, + * <code>returnOpenType.equals(object.getReturnOpenType())</code>, + * and <code>impact == object.getImpact()</code>. + */ + public boolean equals(Object obj) + { + if (!(obj instanceof OpenMBeanOperationInfo)) + return false; + OpenMBeanOperationInfo o = (OpenMBeanOperationInfo) obj; + return getName().equals(o.getName()) && + getSignature().equals(o.getSignature()) && + returnOpenType.equals(o.getReturnOpenType()) && + getImpact() == o.getImpact(); + } + + /** + * Returns the open type instance which represents the type of the + * return value. + * + * @return the open type of the return value. + */ + public OpenType<?> getReturnOpenType() + { + return returnOpenType; + } + + /** + * <p> + * Returns the hashcode of the operation information as the sum of + * the hashcodes of the name, open return type, impact and signature + * (calculated by + * <code>java.util.Arrays.asList(signature).hashCode()</code>). + * </p> + * <p> + * As instances of this class are immutable, the return value + * is computed just once for each instance and reused + * throughout its life. + * </p> + * + * @return the hashcode of the operation information. + */ + public int hashCode() + { + if (hashCode == null) + hashCode = Integer.valueOf(getName().hashCode() + + returnOpenType.hashCode() + + Integer.valueOf(getImpact()).hashCode() + + Arrays.asList(getSignature()).hashCode()); + return hashCode.intValue(); + } + + /** + * <p> + * Returns a textual representation of this instance. This + * is constructed using the class name + * (<code>javax.management.openmbean.OpenMBeanOperationInfo</code>) + * along with the name, signature, open return type and impact. + * </p> + * <p> + * As instances of this class are immutable, the return value + * is computed just once for each instance and reused + * throughout its life. + * </p> + * + * @return a @link{java.lang.String} instance representing + * the instance in textual form. + */ + public String toString() + { + if (string == null) + { + String impactString; + switch (getImpact()) + { + case INFO: + impactString = "INFO"; + break; + case ACTION: + impactString = "ACTION"; + break; + case ACTION_INFO: + impactString = "ACTION_INFO"; + break; + case UNKNOWN: + impactString = "UNKNOWN"; + break; + default: + impactString = "ERRONEOUS VALUE"; + } + string = getClass().getName() + + "[name=" + getName() + + ",signature=" + Arrays.toString(getSignature()) + + ",returnOpenType=" + returnOpenType + + ",impact=" + impactString + + "]"; + } + return string; + } + +} diff --git a/libjava/classpath/javax/management/openmbean/OpenMBeanParameterInfo.java b/libjava/classpath/javax/management/openmbean/OpenMBeanParameterInfo.java new file mode 100644 index 000000000..0869a686f --- /dev/null +++ b/libjava/classpath/javax/management/openmbean/OpenMBeanParameterInfo.java @@ -0,0 +1,190 @@ +/* OpenMBeanParameterInfo.java -- Open typed info about a parameter. + Copyright (C) 2006 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.openmbean; + +import java.util.Set; + +/** + * Describes the parameters of a constructor or operation associated + * with an open management bean. This interface includes those methods + * specified by {@link javax.management.MBeanParameterInfo}, so + * implementations should extend this class. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public interface OpenMBeanParameterInfo +{ + + /** + * Compares this parameter with the supplied object. This returns + * true iff the object is an instance of {@link OpenMBeanParameterInfo} + * with an equal name and open type and the same default, minimum, + * maximum and legal values. + * + * @param obj the object to compare. + * @return true if the object is a {@link OpenMBeanParameterInfo} + * instance, + * <code>name.equals(object.getName())</code>, + * <code>openType.equals(object.getOpenType())</code>, + * <code>defaultValue.equals(object.getDefaultValue())</code>, + * <code>minValue.equals(object.getMinValue())</code>, + * <code>maxValue.equals(object.getMaxValue())</code>, + * and <code>legalValues.equals(object.getLegalValues())</code>. + */ + boolean equals(Object obj); + + /** + * Returns the default value of this parameter, or <code>null</code> + * if there is no default value. + * + * @return the default value of the parameter, or <code>null</code> + * if there is no default. + */ + Object getDefaultValue(); + + /** + * Returns a description of this parameter. + * + * @return a human-readable description. + */ + String getDescription(); + + /** + * Returns a {@link java.util.Set} enumerating the legal values + * of this parameter, or <code>null</code> if no such limited + * set exists for this parameter. + * + * @return a set of legal values, or <code>null</code> if no such + * set exists. + */ + Set<?> getLegalValues(); + + /** + * Returns the maximum value of this parameter, or <code>null</code> + * if there is no maximum. + * + * @return the maximum value, or <code>null</code> if none exists. + */ + Comparable<?> getMaxValue(); + + /** + * Returns the minimum value of this parameter, or <code>null</code> + * if there is no minimum. + * + * @return the minimum value, or <code>null</code> if none exists. + */ + Comparable<?> getMinValue(); + + /** + * Returns the name of this parameter. + * + * @return the name of the parameter. + */ + String getName(); + + /** + * Returns the open type instance which represents the type of this + * parameter. + * + * @return the open type of this parameter. + */ + OpenType<?> getOpenType(); + + /** + * Returns true if this parameter has a default value. + * + * @return true if this parameter has a default. + */ + boolean hasDefaultValue(); + + /** + * Returns the hashcode of the parameter information as the sum of + * the hashcodes of the name, open type, default value, maximum + * value, minimum value and the set of legal values. + * + * @return the hashcode of the parameter information. + */ + int hashCode(); + + /** + * Returns true if there is a set of legal values for this + * parameter. + * + * @return true if a set of legal values exists for this + * parameter. + */ + boolean hasLegalValues(); + + /** + * Returns true if there is a maximum value for this parameter. + * + * @return true if a maximum value exists for this parameter. + */ + boolean hasMaxValue(); + + /** + * Returns true if there is a minimum value for this parameter. + * + * @return true if a minimum value exists for this parameter. + */ + boolean hasMinValue(); + + /** + * Returns true if the specified object is a valid value for + * this parameter. + * + * @param obj the object to test. + * @return true if <code>obj</code> is a valid value for this + * parameter. + */ + boolean isValue(Object obj); + + /** + * Returns a textual representation of this instance. This + * is constructed using the class name + * (<code>javax.management.openmbean.OpenMBeanParameterInfo</code>) + * along with the name, open type, default, minimum, maximum + * and legal values of the parameter. + * + * @return a @link{java.lang.String} instance representing + * the instance in textual form. + */ + String toString(); + +} diff --git a/libjava/classpath/javax/management/openmbean/OpenMBeanParameterInfoSupport.java b/libjava/classpath/javax/management/openmbean/OpenMBeanParameterInfoSupport.java new file mode 100644 index 000000000..78ad1c5a0 --- /dev/null +++ b/libjava/classpath/javax/management/openmbean/OpenMBeanParameterInfoSupport.java @@ -0,0 +1,512 @@ +/* OpenMBeanParameterInfoSupport.java -- Open typed info about a parameter. + Copyright (C) 2006, 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.openmbean; + +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + +import javax.management.MBeanParameterInfo; + +/** + * Describes the parameters of a constructor or operation associated + * with an open management bean. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public class OpenMBeanParameterInfoSupport + extends MBeanParameterInfo + implements OpenMBeanParameterInfo +{ + + /** + * Compatible with JDK 1.5 + */ + private static final long serialVersionUID = -7235016873758443122L; + + /** + * The open type of the parameter. + */ + private OpenType<?> openType; + + /** + * The default value of the parameter (may be <code>null</code>). + */ + private Object defaultValue; + + /** + * The possible legal values of the parameter (may be <code>null</code>). + */ + private Set<?> legalValues; + + /** + * The minimum value of the parameter (may be <code>null</code>). + */ + private Comparable<?> minValue; + + /** + * The maximum value of the parameter (may be <code>null</code>). + */ + private Comparable<?> maxValue; + + /** + * The hash code of this instance. + */ + private transient Integer hashCode; + + /** + * The <code>toString()</code> result of this instance. + */ + private transient String string; + + /** + * Constructs a new {@link OpenMBeanParameterInfo} using the specified + * name, description and open type. None of these values may be + * <code>null</code> and the name and description may not be equal + * to the empty string. + * + * @param name the name of the parameter. + * @param desc a description of the parameter. + * @param type the open type of the parameter. + * @throws IllegalArgumentException if the name, description or + * open type are <code>null</code> + * or the name or description are + * the empty string. + */ + public OpenMBeanParameterInfoSupport(String name, String desc, OpenType<?> type) + { + super(name, type == null ? null : type.getClassName(), desc); + if (name == null) + throw new IllegalArgumentException("The name may not be null."); + if (desc == null) + throw new IllegalArgumentException("The description may not be null."); + if (type == null) + throw new IllegalArgumentException("The type may not be null."); + if (name.length() == 0) + throw new IllegalArgumentException("The name may not be the empty string."); + if (desc.length() == 0) + throw new IllegalArgumentException("The description may not be the " + + "empty string."); + openType = type; + } + + /** + * Constructs a new {@link OpenMBeanParameterInfo} using the + * specified name, description, open type and default value. The + * name, description and open type cannot be <code>null</code> and + * the name and description may not be equal to the empty string. + * The default value may be <code>null</code>. If non-null, it must + * be a valid value of the given open type. Default values are not + * applicable to the open types, {@link ArrayType} and {@link + * TabularType}. + * + * @param name the name of the parameter. + * @param desc a description of the parameter. + * @param type the open type of the parameter. + * @param defaultValue the default value of the parameter. + * @throws IllegalArgumentException if the name, description or + * open type are <code>null</code> + * or the name or description are + * the empty string. + * @throws OpenDataException if <code>defaultValue<code> is non-null + * and is either not a value of the given + * open type or the open type is an instance + * of {@link ArrayType} or {@link TabularType}. + */ + public <T> OpenMBeanParameterInfoSupport(String name, String desc, OpenType<T> type, + T defaultValue) + throws OpenDataException + { + this(name, desc, type, defaultValue, null); + } + + /** + * <p> + * Constructs a new {@link OpenMBeanParameterInfo} using the + * specified name, description, open type, default, maximum and + * minimum values. The name, description and open type cannot be + * <code>null</code> and the name and description may not be equal + * to the empty string. The default, maximum and minimum values may + * be <code>null</code>. The following conditions apply when the + * parameters mentioned are non-null: + * </p> + * <ul> + * <li>The values must be valid values for the given open type.</li> + * <li>Default values are not applicable to the open types, {@link + * ArrayType} and {@link TabularType}.</li> + * <li>The minimum value must be smaller than or equal to the maximum value + * (literally, <code>minValue.compareTo(maxValue) <= 0</code>.</li> + * <li>The minimum value must be smaller than or equal to the default value + * (literally, <code>minValue.compareTo(defaultValue) <= 0</code>.</li> + * <li>The default value must be smaller than or equal to the maximum value + * (literally, <code>defaultValue.compareTo(maxValue) <= 0</code>.</li> + * </ul> + * + * @param name the name of the parameter. + * @param desc a description of the parameter. + * @param type the open type of the parameter. + * @param defaultValue the default value of the parameter, or <code>null</code>. + * @param minimumValue the minimum value of the parameter, or <code>null</code>. + * @param maximumValue the maximum value of the parameter, or <code>null</code>. + * @throws IllegalArgumentException if the name, description or + * open type are <code>null</code> + * or the name or description are + * the empty string. + * @throws OpenDataException if any condition in the list above is broken. + */ + @SuppressWarnings("unchecked") + public <T> OpenMBeanParameterInfoSupport(String name, String desc, OpenType<T> type, + T defaultValue, Comparable<T> minimumValue, + Comparable<T> maximumValue) + throws OpenDataException + { + this(name, desc, type); + if (defaultValue != null && !(type.isValue(defaultValue))) + throw new OpenDataException("The default value is not a member of the " + + "open type given."); + if (minimumValue != null && !(type.isValue(minimumValue))) + throw new OpenDataException("The minimum value is not a member of the " + + "open type given."); + if (maximumValue != null && !(type.isValue(maximumValue))) + throw new OpenDataException("The maximum value is not a member of the " + + "open type given."); + if (defaultValue != null && (type instanceof ArrayType || + type instanceof TabularType)) + throw new OpenDataException("Default values are not applicable for " + + "array or tabular types."); + if (minimumValue != null && maximumValue != null + && minimumValue.compareTo((T) maximumValue) > 0) + throw new OpenDataException("The minimum value is greater than the " + + "maximum."); + if (minimumValue != null && defaultValue != null + && minimumValue.compareTo(defaultValue) > 0) + throw new OpenDataException("The minimum value is greater than the " + + "default."); + if (defaultValue != null && maximumValue != null + && maximumValue.compareTo(defaultValue) < 0) + throw new OpenDataException("The default value is greater than the " + + "maximum."); + + this.defaultValue = defaultValue; + minValue = minimumValue; + maxValue = maximumValue; + } + + /** + * <p> + * Constructs a new {@link OpenMBeanParameterInfo} using the + * specified name, description, open type, default value and + * set of legal values. The name, description and open type cannot be + * <code>null</code> and the name and description may not be equal + * to the empty string. The default, maximum and minimum values may + * be <code>null</code>. The following conditions apply when the + * parameters mentioned are non-null: + * </p> + * <ul> + * <li>The default value and each of the legal values must be a valid + * value for the given open type.</li> + * <li>Default and legal values are not applicable to the open types, {@link + * ArrayType} and {@link TabularType}.</li> + * <li>The default value is not in the set of legal values.</li> + * </ul> + * <p> + * The legal values are copied from the array into a unmodifiable set, + * so future modifications to the array have no effect. + * </p> + * + * @param name the name of the parameter. + * @param desc a description of the parameter. + * @param type the open type of the parameter. + * @param defaultValue the default value of the parameter, or <code>null</code>. + * @param legalValues the legal values of the parameter. May be + * <code>null</code> or an empty array. + * @throws IllegalArgumentException if the name, description or + * open type are <code>null</code> + * or the name or description are + * the empty string. + * @throws OpenDataException if any condition in the list above is broken. + */ + public <T> OpenMBeanParameterInfoSupport(String name, String desc, OpenType<T> type, + T defaultValue, T[] legalValues) + throws OpenDataException + { + this(name, desc, type); + if (defaultValue != null && !(type.isValue(defaultValue))) + throw new OpenDataException("The default value is not a member of the " + + "open type given."); + if (defaultValue != null && (type instanceof ArrayType || + type instanceof TabularType)) + throw new OpenDataException("Default values are not applicable for " + + "array or tabular types."); + if (legalValues != null && (type instanceof ArrayType || + type instanceof TabularType)) + throw new OpenDataException("Legal values are not applicable for " + + "array or tabular types."); + if (legalValues != null && legalValues.length > 0) + { + Set<T> lv = new HashSet<T>(legalValues.length); + for (int a = 0; a < legalValues.length; ++a) + { + if (legalValues[a] != null && + !(type.isValue(legalValues[a]))) + throw new OpenDataException("The legal value, " + + legalValues[a] + + "is not a member of the " + + "open type given."); + lv.add(legalValues[a]); + } + if (defaultValue != null && !(lv.contains(defaultValue))) + throw new OpenDataException("The default value is not in the set " + + "of legal values."); + this.legalValues = Collections.unmodifiableSet(lv); + } + this.defaultValue = defaultValue; + } + + /** + * Compares this parameter with the supplied object. This returns + * true iff the object is an instance of {@link OpenMBeanParameterInfo} + * with an equal name and open type and the same default, minimum, + * maximum and legal values. + * + * @param obj the object to compare. + * @return true if the object is a {@link OpenMBeanParameterInfo} + * instance, + * <code>name.equals(object.getName())</code>, + * <code>openType.equals(object.getOpenType())</code>, + * <code>defaultValue.equals(object.getDefaultValue())</code>, + * <code>minValue.equals(object.getMinValue())</code>, + * <code>maxValue.equals(object.getMaxValue())</code>, + * and <code>legalValues.equals(object.getLegalValues())</code>. + */ + public boolean equals(Object obj) + { + if (!(obj instanceof OpenMBeanParameterInfo)) + return false; + OpenMBeanParameterInfo o = (OpenMBeanParameterInfo) obj; + return getName().equals(o.getName()) && + openType.equals(o.getOpenType()) && + (defaultValue == null ? o.getDefaultValue() == null : + defaultValue.equals(o.getDefaultValue())) && + (minValue == null ? o.getMinValue() == null : + minValue.equals(o.getMinValue())) && + (maxValue == null ? o.getMaxValue() == null : + maxValue.equals(o.getMaxValue())) && + (legalValues == null ? o.getLegalValues() == null : + legalValues.equals(o.getLegalValues())); + } + + /** + * Returns the default value of this parameter, or <code>null</code> + * if there is no default value. + * + * @return the default value of the parameter, or <code>null</code> + * if there is no default. + */ + public Object getDefaultValue() + { + return defaultValue; + } + + /** + * Returns a {@link java.util.Set} enumerating the legal values + * of this parameter, or <code>null</code> if no such limited + * set exists for this parameter. + * + * @return a set of legal values, or <code>null</code> if no such + * set exists. + */ + public Set<?> getLegalValues() + { + return legalValues; + } + + /** + * Returns the maximum value of this parameter, or <code>null</code> + * if there is no maximum. + * + * @return the maximum value, or <code>null</code> if none exists. + */ + public Comparable<?> getMaxValue() + { + return maxValue; + } + + /** + * Returns the minimum value of this parameter, or <code>null</code> + * if there is no minimum. + * + * @return the minimum value, or <code>null</code> if none exists. + */ + public Comparable<?> getMinValue() + { + return minValue; + } + + /** + * Returns the open type instance which represents the type of this + * parameter. + * + * @return the open type of this parameter. + */ + public OpenType<?> getOpenType() + { + return openType; + } + + /** + * Returns true if this parameter has a default value + * (i.e. the value is non-null). + * + * @return true if this parameter has a default. + */ + public boolean hasDefaultValue() + { + return defaultValue != null; + } + + /** + * <p> + * Returns the hashcode of the parameter information as the sum of + * the hashcodes of the name, open type, default value, maximum + * value, minimum value and the set of legal values. + * </p> + * <p> + * As instances of this class are immutable, the hash code + * is computed just once for each instance and reused + * throughout its life. + * </p> + * + * @return the hashcode of the parameter information. + */ + public int hashCode() + { + if (hashCode == null) + hashCode = Integer.valueOf(getName().hashCode() + + openType.hashCode() + + (defaultValue == null ? 0 : + defaultValue.hashCode()) + + (minValue == null ? 0 : + minValue.hashCode()) + + (maxValue == null ? 0 : + maxValue.hashCode()) + + (legalValues == null ? 0 : + legalValues.hashCode())); + return hashCode.intValue(); + } + + /** + * Returns true if there is a set of legal values for this + * parameter (i.e. the value is non-null). + * + * @return true if a set of legal values exists for this + * parameter. + */ + public boolean hasLegalValues() + { + return legalValues != null; + } + + /** + * Returns true if there is a maximum value for this parameter + * (i.e. the value is non-null). + * + * @return true if a maximum value exists for this parameter. + */ + public boolean hasMaxValue() + { + return maxValue != null; + } + + /** + * Returns true if there is a minimum value for this parameter. + * (i.e. the value is non-null). + * + * @return true if a minimum value exists for this parameter. + */ + public boolean hasMinValue() + { + return minValue != null; + } + + /** + * Returns true if the specified object is a valid value for + * this parameter. + * + * @param obj the object to test. + * @return true if <code>obj</code> is a valid value for this + * parameter. + */ + public boolean isValue(Object obj) + { + return openType.isValue(obj); + } + + /** + * <p> + * Returns a textual representation of this instance. This + * is constructed using the class name + * (<code>javax.management.openmbean.OpenMBeanParameterInfo</code>) + * along with the name, open type, default, minimum, maximum + * and legal values of the parameter. + * </p> + * <p> + * As instances of this class are immutable, the return value + * is computed just once for each instance and reused + * throughout its life. + * </p> + * + * @return a @link{java.lang.String} instance representing + * the instance in textual form. + */ + public String toString() + { + if (string == null) + string = getClass().getName() + + "[name=" + getName() + + ",openType=" + openType + + ",defaultValue=" + defaultValue + + ",minValue=" + minValue + + ",maxValue=" + maxValue + + ",legalValues=" + legalValues + + "]"; + return string; + } + +} diff --git a/libjava/classpath/javax/management/openmbean/OpenType.java b/libjava/classpath/javax/management/openmbean/OpenType.java new file mode 100644 index 000000000..d8abc7cf0 --- /dev/null +++ b/libjava/classpath/javax/management/openmbean/OpenType.java @@ -0,0 +1,247 @@ +/* OpenType.java -- Superclass of all open types. + Copyright (C) 2006, 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.openmbean; + +import java.io.Serializable; + +import java.util.Arrays; +import java.util.List; + +/** + * The superclass of all open types, which describe the + * applicable data values for open MBeans. An open type + * is defined by its name and description, and the name + * of the Java class it maps to. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public abstract class OpenType<T> + implements Serializable +{ + + /** + * Compatible with JDK 1.5 + */ + private static final long serialVersionUID = -9195195325186646468L; + + /** + * The name of the Java class this type represents. + */ + private String className; + + /** + * The name of this type. + */ + private String typeName; + + /** + * A description of this type. + */ + private String description; + + /** + * An array which defines the set of Java types which can be + * used as open types. Note that each type is also available + * in array form, possibly with multiple dimensions. + * + * @deprecated Use {@link ALLOWED_CLASSNAMES_LIST} instead. + */ + @Deprecated + public static final String[] ALLOWED_CLASSNAMES = { + "java.lang.Void", + "java.lang.Boolean", + "java.lang.Character", + "java.lang.Byte", + "java.lang.Short", + "java.lang.Integer", + "java.lang.Long", + "java.lang.Float", + "java.lang.Double", + "java.lang.String", + "java.math.BigDecimal", + "java.math.BigInteger", + "java.util.Date", + "javax.management.ObjectName", + CompositeData.class.getName(), + TabularData.class.getName() + }; + + /** + * A list which defines the set of Java types that may be + * used as open types. Note that each type is also available + * in array form, possibly with multiple dimensions. + */ + public static final List<String> ALLOWED_CLASSNAMES_LIST = + Arrays.asList(ALLOWED_CLASSNAMES); + + /** + * Constructs a new {@link OpenType} for the specified class + * with the given name and description. The name of the class + * must be taken from the list of {@link ALLOWED_CLASSNAMES}. + * Arrays are implictly included in this, and follow the usual + * syntax of {@link java.lang.Class#getName()} with the name + * preceded by n instances of '[' (where n is the number of + * dimensions) and an L. The name and description can not be + * <code>null</code> or the empty string. + * + * @param className the name of the Java class this type + * represents. + * @param name the name of the type. + * @param desc the description of the type. + * @throws IllegalArgumentException if either of <code>name</code> + * or <code>desc</code> are + * <code>null</code> or the empty + * string. + * @throws OpenDataException if the class name does not reference + * a listed class (from @{link ALLOWED_CLASSNAMES}) + */ + protected OpenType(String className, String name, String desc) + throws OpenDataException + { + if (name == null || name.equals("")) + throw new IllegalArgumentException("The name can not be null " + + "or the empty string."); + if (desc == null || desc.equals("")) + throw new IllegalArgumentException("The description can not " + + "be null or the empty string."); + Class<?> type; + try + { + type = Class.forName(className); + } + catch (ClassNotFoundException e) + { + throw (OpenDataException) new OpenDataException("The class name, " + className + + ", is unavailable.").initCause(e); + } + while (type.isArray()) + type = type.getComponentType(); + if (!(type.isPrimitive() || ALLOWED_CLASSNAMES_LIST.contains(type.getName()))) + throw new OpenDataException("The class name, " + className + + ", does not specify a valid open type."); + this.className = className; + typeName = name; + description = desc; + } + + /** + * Performs an equality test on this object and the one specified. + * + * @param obj the object to test against this one. + * @return true if the two objects are equivalent. + * @see java.lang.Object#hashCode() + */ + public abstract boolean equals(Object obj); + + /** + * Returns the name of the Java class this type represents. This must + * be one of the {@link ALLOWED_CLASSNAMES} or an array of one of them. + * The specification of arrays follows the standard set by + * {@link java.lang.Class#getName()} i.e. the name is the class name + * preceded by n instances of '[' and an 'L', where n is number of + * dimensions used by the array. + * + * @return the class name. + */ + public String getClassName() + { + return className; + } + + /** + * Returns a description of this open type. + * + * @return the description. + */ + public String getDescription() + { + return description; + } + + /** + * Returns the name of this open type. + * + * @return the type name. + */ + public String getTypeName() + { + return typeName; + } + + /** + * Returns a hash code for this open type. The hash code + * should be consistent with the {@link equals()} method. + * Thus, it should continue to return the same value while + * the values used by the {@link equals()} method remain + * the same, and should return different hash codes for + * objects which are judged to be different using the + * {@link equals()} method. + * + * @return the hash code of this instance. + */ + public abstract int hashCode(); + + /** + * Returns true if this open type represents an array type. + * + * @return true if this open type represents an array type. + */ + public boolean isArray() + { + return className.startsWith("["); + } + + /** + * Returns true if the specified object is a member of this + * type. + * + * @param obj the object to test for membership. + * @return true if the object is a member of this type. + */ + public abstract boolean isValue(Object obj); + + /** + * Returns a textual representation of this type. + * + * @return a {@link java.lang.String} representation of this + * type. + */ + public abstract String toString(); + +} diff --git a/libjava/classpath/javax/management/openmbean/SimpleType.java b/libjava/classpath/javax/management/openmbean/SimpleType.java new file mode 100644 index 000000000..81b991bdf --- /dev/null +++ b/libjava/classpath/javax/management/openmbean/SimpleType.java @@ -0,0 +1,350 @@ +/* SimpleType.java -- Open type descriptor for the base types. + Copyright (C) 2006, 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.openmbean; + +import java.io.InvalidObjectException; +import java.io.ObjectStreamException; + +import java.math.BigDecimal; +import java.math.BigInteger; + +import java.util.Date; + +import javax.management.ObjectName; + +/** + * The open type descriptor for data values that are members + * of one of the simple types (such as an integer or a string). + * The other open types ({@link ArrayType}, {@link CompositeType}, + * {@link TabularType}) are constructed from one or more of these + * types. The simple types are formed from a small subset of + * basic Java types. As a result, the valid instances of this + * class are predefined, and no constructor is given for creating + * new instances. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public final class SimpleType<T> + extends OpenType<T> +{ + + /** + * The {@link SimpleType} representation of + * <code>java.math.BigDecimal</code>. + */ + public static final SimpleType<BigDecimal> BIGDECIMAL; + + /** + * The {@link SimpleType} representation of + * <code>java.math.BigInteger</code>. + */ + public static final SimpleType<BigInteger> BIGINTEGER; + + /** + * The {@link SimpleType} representation of + * <code>java.lang.Boolean</code>. + */ + public static final SimpleType<Boolean> BOOLEAN; + + /** + * The {@link SimpleType} representation of + * <code>java.lang.Byte</code>. + */ + public static final SimpleType<Byte> BYTE; + + /** + * The {@link SimpleType} representation of + * <code>java.lang.Character</code>. + */ + public static final SimpleType<Character> CHARACTER; + + /** + * The {@link SimpleType} representation of + * <code>java.util.Date</code>. + */ + public static final SimpleType<Date> DATE; + + /** + * The {@link SimpleType} representation of + * <code>java.lang.Double</code>. + */ + public static final SimpleType<Double> DOUBLE; + + /** + * The {@link SimpleType} representation of + * <code>java.lang.Float</code>. + */ + public static final SimpleType<Float> FLOAT; + + /** + * The {@link SimpleType} representation of + * <code>java.lang.Integer</code>. + */ + public static final SimpleType<Integer> INTEGER; + + /** + * The {@link SimpleType} representation of + * <code>java.lang.Long</code>. + */ + public static final SimpleType<Long> LONG; + + /** + * The {@link SimpleType} representation of + * <code>javax.management.ObjectName</code>. + */ + public static final SimpleType<ObjectName> OBJECTNAME; + + + /** + * The {@link SimpleType} representation of + * <code>java.lang.Short</code>. + */ + public static final SimpleType<Short> SHORT; + + /** + * The {@link SimpleType} representation of + * <code>java.lang.String</code>. + */ + public static final SimpleType<String> STRING; + + /** + * The {@link SimpleType} representation of + * <code>java.lang.Void</code>. + */ + public static final SimpleType<Void> VOID; + + /** + * Compatible with JDK 1.5 + */ + private static final long serialVersionUID = 2215577471957694503L; + + /** + * The hash code of this instance. + */ + private transient Integer hashCode; + + /** + * The <code>toString()</code> result of this instance. + */ + private transient String string; + + /** + * Static construction of the {@link SimpleType} instances. + */ + static + { + try + { + BIGDECIMAL = new SimpleType<BigDecimal>("java.math.BigDecimal"); + BIGINTEGER = new SimpleType<BigInteger>("java.math.BigInteger"); + BOOLEAN = new SimpleType<Boolean>("java.lang.Boolean"); + BYTE = new SimpleType<Byte>("java.lang.Byte"); + CHARACTER = new SimpleType<Character>("java.lang.Character"); + DATE = new SimpleType<Date>("java.util.Date"); + DOUBLE = new SimpleType<Double>("java.lang.Double"); + FLOAT = new SimpleType<Float>("java.lang.Float"); + INTEGER = new SimpleType<Integer>("java.lang.Integer"); + LONG = new SimpleType<Long>("java.lang.Long"); + OBJECTNAME = + new SimpleType<ObjectName>("javax.management.ObjectName"); + SHORT = new SimpleType<Short>("java.lang.Short"); + STRING = new SimpleType<String>("java.lang.String"); + VOID = new SimpleType<Void>("java.lang.Void"); + } + catch (OpenDataException e) + { + /* In normal circumstances, this shouldn't be possible. */ + throw new IllegalStateException("A invalid class name " + + "was passed to the SimpleType " + + "constructor.", e); + } + } + + /** + * Constructs a new {@link SimpleType} instance for the given + * class name. The class name is also used as the type name + * and description of the {@link OpenType} instance. + * + * @param name the name of the class this instance should + * represent. + * @throws OpenDataException if somehow the constructor of the + * superclass is passed an invalid + * class name. + */ + private SimpleType(String name) + throws OpenDataException + { + super(name, name, name); + } + + /** + * <p> + * Compares this simple data type with another object + * for equality. The objects are judged to be equal if: + * </p> + * <ul> + * <li><code>obj</code> is not null.</li> + * <li><code>obj</code> is an instance of + * {@link SimpleType}.</li> + * <li>The class names are equal.</li> + * </ul> + * + * @param obj the object to compare with. + * @return true if the conditions above hold. + */ + public boolean equals(Object obj) + { + if (!(obj instanceof SimpleType)) + return false; + SimpleType<?> sType = (SimpleType<?>) obj; + return sType.getClassName().equals(getClassName()); + } + + /** + * <p> + * Returns the hash code of the simple data type. + * This is simply the hash code of the class name, + * which is the same element of the type compared + * as part of the + * {@link #equals(java.lang.Object)} method, thus ensuring + * that the hashcode is compatible with the equality + * test. + * </p> + * <p> + * As instances of this class are immutable, the hash code + * is computed just once for each instance and reused + * throughout its life. + * </p> + * + * @return the hash code of this instance. + */ + public int hashCode() + { + if (hashCode == null) + hashCode = Integer.valueOf(getClassName().hashCode()); + return hashCode.intValue(); + } + + /** + * Returns true if the specified object is a member of this + * simple type. The object is judged to be so if it is + * non-null and its class name is the same as that returned + * by {@link SimpleType#getClassName()}. + * + * @param obj the object to test for membership. + * @return true if the object is a member of this type. + */ + public boolean isValue(Object obj) + { + if (obj == null) + return false; + return obj.getClass().getName().equals(getClassName()); + } + + /** + * Replaces instances of this class read from an + * {@link java.io.ObjectInputStream} with one of the predefined + * values. This ensures that each existing instance of + * this class is one of these unique instances. + * + * @return the replacement object. + * @throws ObjectStreamException if the object can not be + * resolved. + */ + public Object readResolve() + throws ObjectStreamException + { + if (equals(BIGDECIMAL)) + return BIGDECIMAL; + if (equals(BIGINTEGER)) + return BIGINTEGER; + if (equals(BOOLEAN)) + return BOOLEAN; + if (equals(BYTE)) + return BYTE; + if (equals(CHARACTER)) + return CHARACTER; + if (equals(DATE)) + return DATE; + if (equals(DOUBLE)) + return DOUBLE; + if (equals(FLOAT)) + return FLOAT; + if (equals(INTEGER)) + return INTEGER; + if (equals(LONG)) + return LONG; + if (equals(OBJECTNAME)) + return OBJECTNAME; + if (equals(SHORT)) + return SHORT; + if (equals(STRING)) + return STRING; + if (equals(VOID)) + return VOID; + throw new InvalidObjectException("Invalid simple type instance " + + "deserialized."); + } + + /** + * <p> + * Returns a textual representation of this instance. This + * is constructed using the class name + * (<code>javax.management.openmbean.SimpleType</code>) + * and the name of the class the type represents. + * </p> + * <p> + * As instances of this class are immutable, the return value + * is computed just once for each instance and reused + * throughout its life. + * </p> + * + * @return a @link{java.lang.String} instance representing + * the instance in textual form. + */ + public String toString() + { + if (string == null) + string = getClass().getName() + + "[name=" + getClassName() + + "]"; + return string; + } + +} diff --git a/libjava/classpath/javax/management/openmbean/TabularData.java b/libjava/classpath/javax/management/openmbean/TabularData.java new file mode 100644 index 000000000..8bceae85e --- /dev/null +++ b/libjava/classpath/javax/management/openmbean/TabularData.java @@ -0,0 +1,258 @@ +/* TabularData.java -- Tables of composite data structures. + Copyright (C) 2006, 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.openmbean; + +import java.util.Collection; +import java.util.Set; + +/** + * Provides an interface to a specific type of composite + * data structure, where keys (the columns) map to the + * {@link CompositeData} objects that form the rows of + * the table. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public interface TabularData +{ + + /** + * Calculates the index the specified {@link CompositeData} value + * would have, if it was to be added to this {@link TabularData} + * instance. This method includes a check that the type of the + * given value is the same as the row type of this instance, but not + * a check for existing instances of the given value. The value + * must also not be <code>null</code>. Possible indices are + * returned by the {@link TabularType#getIndexNames()} method of + * this instance's tabular type. The returned indices are the + * values of the fields in the supplied {@link CompositeData} + * instance that match the names given in the {@link TabularType}. + * + * @param val the {@link CompositeData} value whose index should + * be calculated. + * @return the index the value would take on, if it were to be added. + * @throws NullPointerException if the value is <code>null</code>. + * @throws InvalidOpenTypeException if the value does not match the + * row type of this instance. + */ + Object[] calculateIndex(CompositeData val); + + /** + * Removes all {@link CompositeData} values from the table. + */ + void clear(); + + /** + * Returns true iff this instance of the {@link TabularData} class + * contains a {@link CompositeData} value at the specified index. + * In any other circumstance, including if the given key + * is <code>null</code> or of the incorrect type, according to + * the {@link TabularType} of this instance, this method returns + * false. + * + * @param key the key to test for. + * @return true if the key maps to a {@link CompositeData} value. + */ + boolean containsKey(Object[] key); + + /** + * Returns true iff this instance of the {@link TabularData} class + * contains the specified {@link CompositeData} value. + * In any other circumstance, including if the given value + * is <code>null</code> or of the incorrect type, according to + * the {@link TabularType} of this instance, this method returns + * false. + * + * @param val the value to test for. + * @return true if the value exists. + */ + boolean containsValue(CompositeData val); + + /** + * Compares the specified object with this object for equality. + * The object is judged equivalent if it is non-null, and also + * an instance of {@link TabularData} with the same row type, + * and {@link CompositeData} values. The two compared instances may + * be equivalent even if they represent different implementations + * of {@link TabularData}. + * + * @param obj the object to compare for equality. + * @return true if <code>obj</code> is equal to <code>this</code>. + */ + boolean equals(Object obj); + + /** + * Retrieves the {@link CompositeData} value for the specified + * key, or <code>null</code> if no such mapping exists. + * + * @param key the key whose value should be returned. + * @return the matching {@link CompositeData} value, or + * <code>null</code> if one does not exist. + * @throws NullPointerException if the key is <code>null</code>. + * @throws InvalidKeyException if the key does not match + * the {@link TabularType} of this + * instance. + */ + CompositeData get(Object[] key); + + /** + * Returns the tabular type which corresponds to this instance + * of {@link TabularData}. + * + * @return the tabular type for this instance. + */ + TabularType getTabularType(); + + /** + * Returns the hash code of the composite data type. This is + * computed as the sum of the hash codes of each value, together + * with the hash code of the tabular type. These are the same + * elements of the type that are compared as part of the {@link + * #equals(java.lang.Object)} method, thus ensuring that the + * hashcode is compatible with the equality test. + * + * @return the hash code of this instance. + */ + int hashCode(); + + /** + * Returns true if this {@link TabularData} instance + * contains no {@link CompositeData} values. + * + * @return true if the instance is devoid of rows. + */ + boolean isEmpty(); + + /** + * Returns a {@link java.util.Set} view of the keys or + * indices of this {@link TabularData} instance. + * + * @return a set containing the keys of this instance. + */ + Set<?> keySet(); + + /** + * Adds the specified {@link CompositeData} value to the + * table. The value must be non-null, of the same type + * as the row type of this instance, and must not have + * the same index as an existing value. The index is + * calculated using the index names of the + * {@link TabularType} for this instance. + * + * @param val the {@link CompositeData} value to add. + * @throws NullPointerException if <code>val</code> is + * <code>null</code>. + * @throws InvalidOpenTypeException if the type of the + * given value does not + * match the row type. + * @throws KeyAlreadyExistsException if the value has the + * same calculated index + * as an existing value. + */ + void put(CompositeData val); + + /** + * Adds each of the specified {@link CompositeData} values + * to the table. Each element of the array must meet the + * conditions given for the {@link #put(CompositeData)} + * method. In addition, the index of each value in the + * array must be distinct from the index of the other + * values in the array, as well as from the existing values + * in the table. The operation should be atomic; if one + * value can not be added, then none of the values should + * be. If the array is <code>null</code> or empty, the + * method simply returns. + * + * @param vals the {@link CompositeData} values to add. + * @throws NullPointerException if a value from the array is + * <code>null</code>. + * @throws InvalidOpenTypeException if the type of a + * given value does not + * match the row type. + * @throws KeyAlreadyExistsException if a value has the + * same calculated index + * as an existing value or + * of one of the other + * specified values. + */ + void putAll(CompositeData[] vals); + + /** + * Removes the {@link CompositeData} value located at the + * specified index. <code>null</code> is returned if the + * value does not exist. Otherwise, the removed value is + * returned. + * + * @param key the key of the value to remove. + * @return the removed value, or <code>null</code> if + * there is no value for the given key. + * @throws NullPointerException if the key is <code>null</code>. + * @throws InvalidOpenTypeException if the key does not match + * the {@link TabularType} of this + * instance. + */ + CompositeData remove(Object[] key); + + /** + * Returns the number of {@link CompositeData} values or rows + * in the table. + * + * @return the number of rows in the table. + */ + int size(); + + /** + * Returns a textual representation of this instance. The + * exact format is left up to the implementation, but it + * should contain the name of the implementing class and + * the tabular type. + * + * @return a {@link java.lang.String} representation of the + * object. + */ + String toString(); + + /** + * Returns the values associated with this instance. + * + * @return the values of this instance. + */ + Collection<?> values(); + +} diff --git a/libjava/classpath/javax/management/openmbean/TabularDataSupport.java b/libjava/classpath/javax/management/openmbean/TabularDataSupport.java new file mode 100644 index 000000000..e2da1b42d --- /dev/null +++ b/libjava/classpath/javax/management/openmbean/TabularDataSupport.java @@ -0,0 +1,648 @@ +/* TabularDataSupport.java -- Tables of composite data structures. + Copyright (C) 2006, 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.openmbean; + +import java.io.Serializable; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * Provides an implementation of the {@link TabularData} + * interface using a {@link java.util.HashMap}. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public class TabularDataSupport + implements TabularData, Serializable, Cloneable, Map<Object,Object> +{ + + /** + * Compatible with JDK 1.5 + */ + private static final long serialVersionUID = 5720150593236309827L; + + /** + * Mapping of rows to column values. + * + * @serial the map of rows to column values. + */ + private HashMap<Object,Object> dataMap; + + /** + * The tabular type which represents this tabular data instance. + * + * @serial the type information for this instance. + */ + private TabularType tabularType; + + /** + * Constructs a new empty {@link TabularDataSupport} with the + * specified type. The type may not be null. This constructor + * simply calls the other, with the default initial capacity of + * <code>101</code> and default load factor of <code>0.75</code>. + * + * @param type the tabular type of this tabular data instance. + * @throws IllegalArgumentException if <code>type</code> is + * <code>null</code>. + */ + public TabularDataSupport(TabularType type) + { + this(type, 101, 0.75f); + } + + /** + * Constructs a new empty {@link TabularDataSupport} with the + * specified type and the supplied initial capacity and load factor + * being used for the underlying {@link java.util.HashMap}. The + * type may not be null and the initial capacity and load factor + * must be positive. + * + * @param type the tabular type of this tabular data instance. + * @param cap the initial capacity of the underlying map. + * @param lf the load factor of the underlying map. + * @throws IllegalArgumentException if <code>type</code> is + * <code>null</code>, or + * <code>cap</code> or + * <code>lf</code> are + * negative. + */ + public TabularDataSupport(TabularType type, int cap, float lf) + { + if (type == null) + throw new IllegalArgumentException("The type may not be null."); + tabularType = type; + dataMap = new HashMap<Object,Object>(cap, lf); + } + + /** + * Calculates the index the specified {@link CompositeData} value + * would have, if it was to be added to this {@link TabularData} + * instance. This method includes a check that the type of the + * given value is the same as the row type of this instance, but not + * a check for existing instances of the given value. The value + * must also not be <code>null</code>. Possible indices are + * selected by the {@link TabularType#getIndexNames()} method of + * this instance's tabular type. The returned indices are the + * values of the fields in the supplied {@link CompositeData} + * instance that match the names given in the {@link TabularType}. + * + * @param val the {@link CompositeData} value whose index should + * be calculated. + * @return the index the value would take on, if it were to be added. + * @throws NullPointerException if the value is <code>null</code>. + * @throws InvalidOpenTypeException if the value does not match the + * row type of this instance. + */ + public Object[] calculateIndex(CompositeData val) + { + if (!(val.getCompositeType().equals(tabularType.getRowType()))) + throw new InvalidOpenTypeException("The type of the given value " + + "does not match the row type " + + "of this instance."); + List<String> indexNames = tabularType.getIndexNames(); + List<String> matchingIndicies = new ArrayList<String>(indexNames.size()); + for (String name : indexNames) + matchingIndicies.add(val.get(name).toString()); + return matchingIndicies.toArray(); + } + + /** + * Removes all {@link CompositeData} values from the table. + */ + public void clear() + { + dataMap.clear(); + } + + /** + * Returns a shallow clone of the information, as obtained by the + * {@link Object} implementation of {@link Object#clone()}. The map + * is also cloned, but it still references the same objects. + * + * @return a shallow clone of this {@link TabularDataSupport}. + */ + @SuppressWarnings("unchecked") + public Object clone() + { + TabularDataSupport clone = null; + try + { + clone = (TabularDataSupport) super.clone(); + clone.setMap((HashMap<Object,Object>) dataMap.clone()); + } + catch (CloneNotSupportedException e) + { + /* This won't happen as we implement Cloneable */ + } + return clone; + } + + /** + * Returns true iff this instance of the {@link TabularData} class + * contains a {@link CompositeData} value at the specified index. + * The method returns <code>false</code> if the given key can + * not be cast to an {@link java.lang.Object} array; otherwise + * it returns the result of {@link #containsKey(java.lang.Object[])}. + * + * + * @param key the key to test for. + * @return true if the key maps to a {@link CompositeData} value. + */ + public boolean containsKey(Object key) + { + if (key instanceof Object[]) + return containsKey((Object[]) key); + else + return false; + } + + /** + * Returns true iff this instance of the {@link TabularData} class + * contains a {@link CompositeData} value at the specified index. + * In any other circumstance, including if the given key + * is <code>null</code> or of the incorrect type, according to + * the {@link TabularType} of this instance, this method returns + * false. + * + * @param key the key to test for. + * @return true if the key maps to a {@link CompositeData} value. + */ + public boolean containsKey(Object[] key) + { + if (key == null) + return false; + if (!(isKeyValid(key))) + return false; + return dataMap.containsKey(key); + } + + /** + * Returns true iff this instance of the {@link TabularData} class + * contains the specified {@link CompositeData} value. If the given + * value is not an instance of {@link CompositeData}, this method + * simply returns false. + * + * @param val the value to test for. + * @return true if the value exists. + */ + public boolean containsValue(Object val) + { + if (val instanceof CompositeData) + return containsValue((CompositeData) val); + else + return false; + } + + /** + * Returns true iff this instance of the {@link TabularData} class + * contains the specified {@link CompositeData} value. + * In any other circumstance, including if the given value + * is <code>null</code> or of the incorrect type, according to + * the {@link TabularType} of this instance, this method returns + * false. + * + * @param val the value to test for. + * @return true if the value exists. + */ + public boolean containsValue(CompositeData val) + { + if (val == null) + return false; + if (!(val.getCompositeType().equals(tabularType.getRowType()))) + return false; + return dataMap.containsValue(val); + } + + /** + * <p> + * Returns a set view of the mappings in this Map. Each element in the + * set is a Map.Entry. The set is backed by the map, so that changes in + * one show up in the other. Modifications made while an iterator is + * in progress cause undefined behavior. If the set supports removal, + * these methods remove the underlying mapping from the map: + * <code>Iterator.remove</code>, <code>Set.remove</code>, + * <code>removeAll</code>, <code>retainAll</code>, and <code>clear</code>. + * Element addition, via <code>add</code> or <code>addAll</code>, is + * not supported via this set. + * </p> + * <p> + * <strong>Note</strong>: using the + * {@link java.util.Map.Entry#setValue(Object) will cause corruption of + * the index to row mappings. + * </p> + * + * @return the set view of all mapping entries + * @see java.util.Map.Entry + */ + public Set<Map.Entry<Object,Object>> entrySet() + { + return dataMap.entrySet(); + } + + /** + * Compares the specified object with this object for equality. + * The object is judged equivalent if it is non-null, and also + * an instance of {@link TabularData} with the same row type, + * and {@link CompositeData} values. The two compared instances may + * be equivalent even if they represent different implementations + * of {@link TabularData}. + * + * @param obj the object to compare for equality. + * @return true if <code>obj</code> is equal to <code>this</code>. + */ + public boolean equals(Object obj) + { + if (!(obj instanceof TabularData)) + return false; + TabularData data = (TabularData) obj; + return tabularType.equals(data.getTabularType()) && + dataMap.values().equals(data.values()); + } + + /** + * Retrieves the value for the specified key by simply + * calling <code>get((Object[]) key)</code>. + * + * @param key the key whose value should be returned. + * @return the matching {@link CompositeData} value, or + * <code>null</code> if one does not exist. + * @throws NullPointerException if the key is <code>null</code>. + * @throws ClassCastException if the key is not an instance + * of <code>Object[]</code>. + * @throws InvalidKeyException if the key does not match + * the {@link TabularType} of this + * instance. + */ + public Object get(Object key) + { + return get((Object[]) key); + } + + /** + * Retrieves the {@link CompositeData} value for the specified + * key, or <code>null</code> if no such mapping exists. + * + * @param key the key whose value should be returned. + * @return the matching {@link CompositeData} value, or + * <code>null</code> if one does not exist. + * @throws NullPointerException if the key is <code>null</code>. + * @throws InvalidKeyException if the key does not match + * the {@link TabularType} of this + * instance. + */ + public CompositeData get(Object[] key) + { + if (!(isKeyValid(key))) + throw new InvalidKeyException("The key does not match the " + + "tabular type of this instance."); + return (CompositeData) dataMap.get(key); + } + + /** + * Returns the tabular type which corresponds to this instance + * of {@link TabularData}. + * + * @return the tabular type for this instance. + */ + public TabularType getTabularType() + { + return tabularType; + } + + /** + * Returns the hash code of the composite data type. This is + * computed as the sum of the hash codes of each value, together + * with the hash code of the tabular type. These are the same + * elements of the type that are compared as part of the {@link + * #equals(java.lang.Object)} method, thus ensuring that the + * hashcode is compatible with the equality test. + * + * @return the hash code of this instance. + */ + public int hashCode() + { + return tabularType.hashCode() + dataMap.values().hashCode(); + } + + /** + * Returns true if this {@link TabularData} instance + * contains no {@link CompositeData} values. + * + * @return true if the instance is devoid of rows. + */ + public boolean isEmpty() + { + return dataMap.isEmpty(); + } + + /** + * Returns true if the given key is valid for the + * @link{TabularType} of this instance. + * + * @return true if the key is valid. + * @throws NullPointerException if <code>key</code> + * is null. + */ + private boolean isKeyValid(Object[] key) + { + Iterator<String> it = tabularType.getIndexNames().iterator(); + CompositeType rowType = tabularType.getRowType(); + for (int a = 0; it.hasNext(); ++a) + { + OpenType<?> type = rowType.getType(it.next()); + if (!(type.isValue(key[a]))) + return false; + } + return true; + } + + /** + * Returns a set view of the keys in this Map. The set is backed by the + * map, so that changes in one show up in the other. Modifications made + * while an iterator is in progress cause undefined behavior. If the set + * supports removal, these methods remove the underlying mapping from + * the map: <code>Iterator.remove</code>, <code>Set.remove</code>, + * <code>removeAll</code>, <code>retainAll</code>, and <code>clear</code>. + * Element addition, via <code>add</code> or <code>addAll</code>, is + * not supported via this set. + * + * @return the set view of all keys + */ + public Set<Object> keySet() + { + return dataMap.keySet(); + } + + /** + * Adds the specified {@link CompositeData} value to the + * table. The value must be non-null, of the same type + * as the row type of this instance, and must not have + * the same index as an existing value. The index is + * calculated using the index names of the + * {@link TabularType} for this instance. + * + * @param val the {@link CompositeData} value to add. + * @throws NullPointerException if <code>val</code> is + * <code>null</code>. + * @throws InvalidOpenTypeException if the type of the + * given value does not + * match the row type. + * @throws KeyAlreadyExistsException if the value has the + * same calculated index + * as an existing value. + */ + public void put(CompositeData val) + { + Object[] key = calculateIndex(val); + if (dataMap.containsKey(key)) + throw new KeyAlreadyExistsException("A value with this index " + + "already exists."); + dataMap.put(key, val); + } + + /** + * Adds the specified {@link CompositeData} value to the + * table, ignoring the supplied key, by simply calling + * <code>put((CompositeData) val)</code>. + * + * @param key ignored. + * @param val the {@link CompositeData} value to add. + * @return the {@link CompositeData} value. + * @throws NullPointerException if <code>val</code> is + * <code>null</code>. + * @throws InvalidOpenTypeException if the type of the + * given value does not + * match the row type. + * @throws KeyAlreadyExistsException if the value has the + * same calculated index + * as an existing value. + */ + public Object put(Object key, Object val) + { + put((CompositeData) val); + return val; + } + + /** + * Adds each of the specified {@link CompositeData} values + * to the table. Each element of the array must meet the + * conditions given for the {@link #put(CompositeData)} + * method. In addition, the index of each value in the + * array must be distinct from the index of the other + * values in the array, as well as from the existing values + * in the table. The operation should be atomic; if one + * value can not be added, then none of the values should + * be. If the array is <code>null</code> or empty, the + * method simply returns. + * + * @param vals the {@link CompositeData} values to add. + * @throws NullPointerException if a value from the array is + * <code>null</code>. + * @throws InvalidOpenTypeException if the type of a + * given value does not + * match the row type. + * @throws KeyAlreadyExistsException if a value has the + * same calculated index + * as an existing value or + * of one of the other + * specified values. + */ + public void putAll(CompositeData[] vals) + { + if (vals == null || vals.length == 0) + return; + Map<Object,Object> mapToAdd = new HashMap<Object,Object>(vals.length); + for (int a = 0; a < vals.length; ++a) + { + Object[] key = calculateIndex(vals[a]); + if (dataMap.containsKey(key)) + throw new KeyAlreadyExistsException("Element " + a + ": A " + + "value with this index " + + "already exists."); + mapToAdd.put(key, vals[a]); + } + dataMap.putAll(mapToAdd); + } + + /** + * Converts each value from the specified map to a member of an + * array of {@link CompositeData} values and adds them using {@link + * #put(CompositeData[])}, if possible. As in {@link + * #put(Object,Object)}, the keys are simply ignored. This method + * is useful for adding the {@link CompositeData} values from a + * different {@link TabularData} instance, which uses the same + * {@link TabularType} but a different selection of index names, to + * this one. If the map is <code>null</code> or empty, the method + * simply returns. + * + * @param m the map to add. Only the values are used and must + * all be instances of {@link CompositeData}. + * @throws NullPointerException if a value from the map is + * <code>null</code>. + * @throws ClassCastException if a value from the map is not + * an instance of {@link CompositeData}. + * @throws InvalidOpenTypeException if the type of the + * given value does not + * match the row type. + * @throws KeyAlreadyExistsException if the value has the + * same calculated index + * as an existing value or + * of one of the other + * specified values. + */ + public void putAll(Map<?,?> m) + { + if (m == null || m.size() == 0) + return; + Collection<?> vals = m.values(); + CompositeData[] data = new CompositeData[vals.size()]; + Iterator<?> it = vals.iterator(); + for (int a = 0; it.hasNext(); ++a) + { + data[a] = (CompositeData) it.next(); + } + putAll(data); + } + + /** + * Removes the value for the specified key by simply + * calling <code>remove((Object[]) key)</code>. + * + * @param key the key whose value should be removed. + * @return the removed value, or <code>null</code> if + * there is no value for the given key. + * @throws NullPointerException if the key is <code>null</code>. + * @throws ClassCastException if the key is not an instance + * of <code>Object[]</code>. + * @throws InvalidOpenTypeException if the key does not match + * the {@link TabularType} of this + * instance. + */ + public Object remove(Object key) + { + return remove((Object[]) key); + } + + /** + * Removes the {@link CompositeData} value located at the + * specified index. <code>null</code> is returned if the + * value does not exist. Otherwise, the removed value is + * returned. + * + * @param key the key of the value to remove. + * @return the removed value, or <code>null</code> if + * there is no value for the given key. + * @throws NullPointerException if the key is <code>null</code>. + * @throws InvalidOpenTypeException if the key does not match + * the {@link TabularType} of this + * instance. + */ + public CompositeData remove(Object[] key) + { + if (!(isKeyValid(key))) + throw new InvalidKeyException("The key does not match the " + + "tabular type of this instance."); + return (CompositeData) dataMap.remove(key); + } + + /** + * Private method to set the internal {@link java.util.Map} + * instance (used in cloning). + * + * @param map the new map used. + */ + private void setMap(HashMap<Object,Object> map) + { + dataMap = map; + } + + /** + * Returns the number of {@link CompositeData} values or rows + * in the table. + * + * @return the number of rows in the table. + */ + public int size() + { + return dataMap.size(); + } + + /** + * Returns a textual representation of this instance. This + * is constructed using the class name + * (<code>javax.management.openmbean.TabularDataSupport</code>) + * and the result of calling <code>toString()</code> on the + * tabular type and underlying hash map instance. + * + * @return a {@link java.lang.String} representation of the + * object. + */ + public String toString() + { + return getClass().getName() + + "[tabularType=" + tabularType + + ",dataMap=" + dataMap + + "]"; + } + + /** + * Returns a collection (or bag) view of the values in this Map. The + * collection is backed by the map, so that changes in one show up in + * the other. Modifications made while an iterator is in progress cause + * undefined behavior. If the collection supports removal, these methods + * remove the underlying mapping from the map: <code>Iterator.remove</code>, + * <code>Collection.remove</code>, <code>removeAll</code>, + * <code>retainAll</code>, and <code>clear</code>. Element addition, via + * <code>add</code> or <code>addAll</code>, is not supported via this + * collection. + * + * @return the collection view of all values + */ + public Collection<Object> values() + { + return dataMap.values(); + } + +} diff --git a/libjava/classpath/javax/management/openmbean/TabularType.java b/libjava/classpath/javax/management/openmbean/TabularType.java new file mode 100644 index 000000000..5ea220701 --- /dev/null +++ b/libjava/classpath/javax/management/openmbean/TabularType.java @@ -0,0 +1,268 @@ +/* TabularType.java -- Type descriptor for TabularData instances. + Copyright (C) 2006, 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.openmbean; + +import java.util.Arrays; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; + +/** + * The open type descriptor for instances of the + * {@link TabularData} class. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public class TabularType + extends OpenType<TabularData> +{ + + /** + * Compatible with JDK 1.5 + */ + private static final long serialVersionUID = 6554071860220659261L; + + /** + * The composite type used by the rows of the table. + */ + private CompositeType rowType; + + /** + * The list of index names, which form the columns of the table. + * They are retained in the order given by the user, and is + * unmodifiable. + */ + private List<String> indexNames; + + /** + * The hash code of this instance. + */ + private transient Integer hashCode; + + /** + * The <code>toString()</code> result of this instance. + */ + private transient String string; + + /** + * <p> + * Constructs a new {@link TabularType} instance for the given + * type name, description, row type and index names. All parameters + * (including the individual elements of the array of index names) + * must be non-null and those that are of type {@link java.lang.String} + * must be non-empty. The array of index names must also be non-empty. + * </p> + * <p> + * The result of <code>TabularData.class.getName()</code> is adopted + * as the class name (see {@link OpenType}). The ordering of the array + * elements is relevant in determining the indicies of the values in the + * table, and thus in the use of the + * {@link TabularData#get(java.lang.Object[])} and + * {@link TabularData#remove(java.lang.Object[])} methods of the + * {@link TabularData} class. + * </p> + * + * @param name the name of this tabular type. + * @param desc a description of this tabular type. + * @param rowType the type of the rows of the table. + * @param indexNames the names used to index the rows within the table. + * @throws IllegalArgumentException if any validity constraint listed above + * is broken. + * @throws OpenDataException if an index name does not match a corresponding + * name in the given row type. + */ + public TabularType(String name, String desc, CompositeType rowType, + String[] indexNames) + throws OpenDataException + { + super(TabularData.class.getName(), name, desc); + if (rowType == null) + throw new IllegalArgumentException("A null row type was given."); + for (int a = 0; a < indexNames.length; ++a) + { + if (indexNames[a] == null) + throw new IllegalArgumentException("Name " + a + + " is null."); + if (indexNames[a].length() == 0) + throw new IllegalArgumentException("Name " + a + + " is the empty string."); + if (!(rowType.containsKey(indexNames[a]))) + throw new OpenDataException("No matching key for " + + indexNames[a] + " was found in " + + "the supplied row type."); + } + this.rowType = rowType; + this.indexNames = Collections.unmodifiableList(Arrays.asList(indexNames)); + } + + /** + * <p> + * Compares this tabular data type with another object + * for equality. The objects are judged to be equal if: + * </p> + * <ul> + * <li><code>obj</code> is not null.</li> + * <li><code>obj</code> is an instance of + * {@link TabularType}.</li> + * <li>The type names are equal.</li> + * <li>The row types are equal.</li> + * <li>The index names are equal and in the same order.</li> + * </ul> + * + * @param obj the object to compare with. + * @return true if the conditions above hold. + */ + public boolean equals(Object obj) + { + if (!(obj instanceof TabularType)) + return false; + TabularType ttype = (TabularType) obj; + return (ttype.getTypeName().equals(getTypeName()) + && (ttype.getRowType().equals(getRowType())) + && (ttype.getIndexNames().equals(getIndexNames()))); + } + + /** + * Returns an unmodifiable list containing the index names. + * The ordering of these names is used to determine the indicies + * of the {@link CompositeData} values, and is retained from that + * used in the call to this object's constructor. + * + * @return an unmodifiable list of the index names used by this + * tabular data structure. + */ + public List<String> getIndexNames() + { + return indexNames; + } + + /** + * Returns the type of the rows used by this tabular data structure. + * + * @return the row type. + */ + public CompositeType getRowType() + { + return rowType; + } + + /** + * <p> + * Returns the hash code of the tabular data type. + * This is computed as the sum of the hash codes of the + * index names together with the hash code of the type + * name and row type. These are the same elements + * of the type that are compared as part of the + * {@link #equals(java.lang.Object)} method, thus ensuring + * that the hashcode is compatible with the equality + * test. + * </p> + * <p> + * As instances of this class are immutable, the hash code + * is computed just once for each instance and reused + * throughout its life. + * </p> + * + * @return the hash code of this instance. + */ + public int hashCode() + { + if (hashCode == null) + { + int elementTotal = 0; + for (String s : indexNames) + elementTotal += s.hashCode(); + hashCode = Integer.valueOf(elementTotal + + getTypeName().hashCode() + + rowType.hashCode()); + } + return hashCode.intValue(); + } + + /** + * Returns true if the specified object is a member of this + * tabular type. The object is judged to be so if it is + * an instance of {@link TabularData} with an equivalent + * type, according to the definition of + * {@link #equals(java.lang.Object)} for {@link TabularType}. + * + * @param obj the object to test for membership. + * @return true if the object is a member of this type. + */ + public boolean isValue(Object obj) + { + if (obj instanceof TabularData) + { + TabularData data = (TabularData) obj; + return equals(data.getTabularType()); + } + return false; + } + + /** + * <p> + * Returns a textual representation of this instance. This + * is constructed using the class name + * (<code>javax.management.openmbean.TabularType</code>) + * and each element of the instance which is relevant to + * the definition of {@link equals(java.lang.Object)} and + * {@link hashCode()} (i.e. the type name, the row type + * and the index names). + * </p> + * <p> + * As instances of this class are immutable, the return value + * is computed just once for each instance and reused + * throughout its life. + * </p> + * + * @return a @link{java.lang.String} instance representing + * the instance in textual form. + */ + public String toString() + { + if (string == null) + string = getClass().getName() + + "[name=" + getTypeName() + + ", rowType=" + rowType + + ", indexNames=" + indexNames + + "]"; + return string; + } + +} diff --git a/libjava/classpath/javax/management/openmbean/package.html b/libjava/classpath/javax/management/openmbean/package.html new file mode 100644 index 000000000..d915007d4 --- /dev/null +++ b/libjava/classpath/javax/management/openmbean/package.html @@ -0,0 +1,64 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> +<!-- package.html - describes classes in java.lang.management package. + Copyright (C) 2006 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. --> + +<html> +<head><title>GNU Classpath - javax.management.openmbean</title></head> + +<body> + +<p> +Provides the data types and descriptor classes for the +<emph>Open MBean</emph>s. Open MBeans are provided in +order to aid interoperability with non-Java management +systems. Unlike normal MBeans, which make use of any +Java data type, Open MBeans use a restricted set of types +which can then be mapped over remote connections, including +to non-Java systems. +</p> +<p> +Normal MBeans are described using an instance of +{@link javax.management.MBeanInfo} with appropriate representations +of the attributes, constructors and operators associated with +the bean. Open MBeans are described in the same way, but by +using subtypes of these entities, which type the bean data using +instances of {@link javax.management.openmbean.OpenType}. Open +types differ from Java types, and are explicitly specified in order +to obtain interoperability with other systems. +</p> +</body> +</html> diff --git a/libjava/classpath/javax/management/package.html b/libjava/classpath/javax/management/package.html new file mode 100644 index 000000000..3543eec90 --- /dev/null +++ b/libjava/classpath/javax/management/package.html @@ -0,0 +1,197 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> +<!-- package.html - describes classes in javax.management package. + 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. --> + +<html> +<head><title>GNU Classpath - javax.management</title></head> + +<body> + +<p> +Provides the core classes for the Java Management Extensions (JMX). This API +builds on the notion of Java beans by providing a layer of abstraction between +the beans themselves and the method of accessing them. Instead of being accessed +directly, management beans or <strong>MBeans</strong> are usually accessed via +a management server (an implementation of the @see MBeanServer interface). Thus, +the bean itself may be a simple Java object or it may be something +more complicated (for example, the server may map from Java to SNMP). The server may +also retrieve the bean from some remote location rather than using a local object. +</p> +<p> +Management beans are usually used for monitoring and/or configuration +of a particular entity. For example, the platform management beans +found in the @see java.lang.management package allow the user +to obtain information about the operating system, current memory usage, etc. +as well as turning on and off certain additional facilities. To this end, +an MBean consists of: +</p> +<ul> +<li><emph>attributes</emph> that may be read and/or written to.</li> +<li><emph>operations</emph> which may be performed.</li> +<li><emph>notifications</emph> that may emitted by the bean and listened for by users.</li> +</ul> +<p> +The most common type of management bean is the @see StandardMBean, A standard MBean +relies on the naming patterns established by the JavaBeans framework; the value of an +attribute <code>name</code> is retrieved by an accessor method named <code>getName</code> +and changed by a mutator method called <code>setName</code>. If the mutator is absent, +the attribute is read only. Naming is also used to associate the implementation of a +bean with its interface; an bean <code>Person</code> is assumed to be an implementation +of the interface <code>PersonMBean</code> (and vice versa). To avoid these naming constraints, +the @see StandardMBean class may be used. +</p> +<p> +<h2>Types of Beans</h2> +<p> +The @see StandardMBean class is one example of a @see DynamicMBean where the attributes and +operations of the bean are provided dynamically via the methods provided. With the +@see StandardMBean class, this simply means that the class uses reflection to access the +appropriate methods of the bean implementation. In a more complex scenario, the bean's +data could be supplied from a file or over the network. +</p> +<p> +Once we start talking about accessing beans over network and platform boundaries, we run +in to the issue of how to deal with the types utilised by these beans. Simple types, such +as numbers and strings, are usually fine but more complex types need special treatment. +An <emph>Open MBean</emph> is one that only uses a specific set of types defined in the +@see javax.management.openmbean package, allowing both sides of a remote connection to provide +this subset of types and thus interact. An @see MXBean goes a stage further, and defines +a method whereby a normal Java MBean may become an Open MBean by performing a defined mapping +on the types of the bean. For example, a @see java.util.List or @see java.util.Set of a +particular type becomes an array of the same type. +</p> +<h2>Accessing Beans</h2> +<p> +Although beans can be accessed like normal objects, the normal way of accessing them is +via an @see MBeanServer. This provides the abstraction from the bean's implementation to +a set of attributes, operations and notifications. The server identifies each bean via +an @see ObjectName. This name is unique to a particular bean and is used to identify the +bean when retrieving the value of an attribute or invoking an operation. Essentially, most +methods provided by the server are the same as those provided by the @see DynamicMBean +interface, except that each takes this additional @link ObjectName parameter to identify the +bean being accessed. +</p> +<p> +The @see MBeanServerFactory keeps track of the current MBean servers in use and allows new +ones to be created. A special @see MBeanServer instance, called the <emph>platform MBean +server</emph>, is created when the Java virtual machine is started and a reference to this +may be obtained from the @see ManagementFactory using +@see ManagementFactory#getPlatformMBeanServer(). This primarily exists for the purpose of +creating and registering the platform MBeans, described in @see java.lang.management, which +provide access to information about the underlying operating system, memory usage, the behaviour +of the garbage collector, etc. but is equally suitable for creating and registering your own +beans. Alternatively, a server instance may be obtained from the @see MBeanServerFactory. +</p> +<p> +A bean obtains an @link ObjectName by registering with the server. This operation can be +performed either by passing an existing instance to the @see MBeanServer#registerMBean method +or by using the @see MBeanServer#createMBean method to simultaneously create the bean and +register it with the server. During the registration process, the bean may perform some +arbitrary behaviour if it implements the @link MBeanRegistration interface. The same is +true when unregistering a bean. +</p> +<p> +To actually access the attributes and operations of a bean via the server, we use code +like the following: +</p> +<pre> +// First we obtain the platform MBean server which has the platform MBeans registered +MBeanServer server = ManagementFactory.getPlatformMBeanServer(); +// We also need the object name of the memory bean so we can address it +ObjectName name = new ObjectName(ManagementFactory.MEMORY_MXBEAN_NAME); +// Next we obtain the value of the 'verbose' attribute +// What actually happens here is that the server invokes the 'isVerbose' method of +// the MemoryMXBean +boolean verbose = server.getAttribute(name, "verbose"); +// We can also set the value of verbose. Again the server is actually performing +// a setVerbose(val) on the bean but we don't need to know this. +Attribute attrib = new Attribute("verbose", true); +server.setAttribute(name, attrib); +// We can also invoke the 'gc' operation which calls the garbage collector. +server.invoke(name, "gc", new Object[]{}, new String[]{}); +</pre> +<p> +As noted above, the server is simply making basic method calls on the object using +reflection. However, the server provides a layer of abstraction which means that something +more complicated could actually be going on. The lines above are equally applicable, for +example, if <code>server</code> is instead an @see MBeanServerConnection connecting us +to a distant computer. +</p> +<p> +This rather hideous code can be simplified back into simple method calls on an object, +so that we get the best of both worlds. This is achieved using a <emph>MBean proxy</emph>: +<pre> +MBeanServer server = ManagementFactory.getPlatformMBeanServer(); +ObjectName name = new ObjectName(ManagementFactory.MEMORY_MXBEAN_NAME); +MemoryMXBean bean = JMX.newMBeanProxy(server, name, MemoryMXBean.class); +boolean verbose = bean.isVerbose(); +bean.setVerbose(true); +bean.gc(); +</pre> +<p> +See how much simpler the operations are? The proxy handles the task of translating the method +calls into appropriate invocations of methods on the server, simplifying the code for the user. +</p> +<p> +Finally, we have assumed in the code above that the @see ObjectName of the bean is known. +If this is not the case, then the server's database can be searched. The @see Query class +provides appropriate operators (e.g. boolean (and,or), value comparison (>, <)) for +building up relatively complex queries. Once constructed, a query may be passed to either +the @see MBeanServer#queryNames or @see MBeanServer#queryMBeans to obtain an appropriate +set of @see ObjectName or MBean instances. +</p> +<h2>Notifications</h2> +<p> +MBeans also have the capability to emit events. Beans which do so implement either the +@see NotificationBroadcaster or @see NotificationEmitter interface (the difference between +the two is simply the existence of a better removal method in the newer +@see NotificationEmitter interface, which otherwise extends @see NotificationBroadcaster), +usually by extending the @see NotificationBroadcasterSupport class. As is usual with event +handling, other classes may <emph>signup</emph> to receive events via the +@see NotificationListener interface. The signup process can include registering a filter +(an implementation of @see NotificationFilter) so that only certain events reach the +listener and others are discarded. +</p> +<h2>Remote Access</h2> +<p> +The subpackage @see javax.management.remote provides facilities to access remote MBean +servers. This consists of a <emph>connector</emph> framework which abstracts the method +of accessing remote servers from the actual implementation, so that the same method is +used to connect to a remote server, regardless of how it is accessed. +</p> +</body> +</html> diff --git a/libjava/classpath/javax/management/remote/NotificationResult.java b/libjava/classpath/javax/management/remote/NotificationResult.java new file mode 100644 index 000000000..09945f06e --- /dev/null +++ b/libjava/classpath/javax/management/remote/NotificationResult.java @@ -0,0 +1,166 @@ +/* NotificationResult.java -- Wrapper for a series of buffered notifications. + Copyright (C) 2008 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.remote; + +import java.io.Serializable; + +/** + * <p> + * Wraps the result of a query for buffered notifications. In a remote + * scenario, it may be more practical for the server to buffer individual + * notifications from its beans and then return them in bulk on request. + * This class contains the notifications returned by such a request. + * </p> + * <p> + * It consists of a series of {@link Notification} and identifier pairs, + * wrapped in a {@link TargetedNotification} object. The identifiers + * serve to pair up the notification with the listener that requested + * it. Two positive numbers are also included: the first sequence number + * used by the returned notifications, and the sequence number of the + * notification which will be returned by the next query. The first + * sequence number may be greater than the next sequence number if some + * notifications have been lost. + * </p> + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public class NotificationResult + implements Serializable +{ + + /** + * Compatible with JDK 1.6 + */ + private static final long serialVersionUID = 1191800228721395279L; + + /** + * The sequence number of the first notification. + */ + private long earliestSequenceNumber; + + /** + * The sequence number of the next notification to be + * returned by a future query. + */ + private long nextSequenceNumber; + + /** + * The pairs of notifications and identifiers returned + * by the query. + */ + private TargetedNotification[] targetedNotifications; + + /** + * Constructs a new {@link NotificationResult} using the specified + * sequence numbers and the supplied array of notification pairs. + * + * @param startSeqNumber the sequence number of the first notification + * being returned. + * @param nextSeqNumber the sequence numbr of the next notification + * that will be returned from a future query. + * @param notifications the notification and identifier pairs. This + * may be empty. + * @throws IllegalArgumentException if a sequence number is negative + * or <code>notifications</code> is + * <code>null</code>. + */ + public NotificationResult(long startSeqNumber, long nextSeqNumber, + TargetedNotification[] notifications) + { + if (startSeqNumber < 0) + throw new IllegalArgumentException("Starting sequence number is " + + "less than 0."); + if (nextSeqNumber < 0) + throw new IllegalArgumentException("Next sequence number is " + + "less than 0."); + if (notifications == null) + throw new IllegalArgumentException("The array of notifications is null."); + earliestSequenceNumber = startSeqNumber; + nextSequenceNumber = nextSeqNumber; + targetedNotifications = notifications; + } + + /** + * Returns the sequence number of the earliest notification + * in the buffer. + * + * @return the sequence number of the earliest notification. + */ + public long getEarliestSequenceNumber() + { + return earliestSequenceNumber; + } + + /** + * Returns the sequence number of the next notification to + * be returned by a future query. + * + * @return the sequence number of the next notification. + */ + public long getNextSequenceNumber() + { + return nextSequenceNumber; + } + + /** + * Returns the notification and identifier pairs returned + * by the query. + * + * @return the notification and identifier pairs. + */ + public TargetedNotification[] getTargetedNotifications() + { + return targetedNotifications; + } + + /** + * Returns a textual representation of the object. + * + * @return a textual representation. + */ + public String toString() + { + return getClass().getName() + + "[earliestSequenceNumber=" + earliestSequenceNumber + + ",nextSequenceNumber=" + nextSequenceNumber + + ",targetedNotifications=" + targetedNotifications + + "]"; + } + +} diff --git a/libjava/classpath/javax/management/remote/TargetedNotification.java b/libjava/classpath/javax/management/remote/TargetedNotification.java new file mode 100644 index 000000000..07246189f --- /dev/null +++ b/libjava/classpath/javax/management/remote/TargetedNotification.java @@ -0,0 +1,126 @@ +/* TargetedNotificaton.java -- Wrapper for a notification and identifier pair. + Copyright (C) 2008 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.remote; + +import java.io.Serializable; + +import javax.management.Notification; + +/** + * Wraps a notification with an identifier that specifies + * the listener which received it. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public class TargetedNotification + implements Serializable +{ + + /** + * Compatible with JDK 1.6 + */ + private static final long serialVersionUID = 7676132089779300926L; + + /** + * The notification that was recieved by the listener. + */ + private Notification notif; + + /** + * The identifier for the listener that received the notification; + */ + private Integer id; + + /** + * Constructs a new {@link TargetedNotification} which connects + * the supplied notification with the specified identifier. The + * identifier matches one of those returned by a previous call + * to add a new notification listener. + * + * @param notif the notification. + * @param id the identifier of the listener that received the + * notification. + * @throws IllegalArgumentException if either argument is + * <code>null</code>. + */ + public TargetedNotification(Notification notif, Integer id) + { + if (notif == null) + throw new IllegalArgumentException("The notification is null."); + if (id == null) + throw new IllegalArgumentException("The identifier is null."); + this.notif = notif; + this.id = id; + } + + /** + * Returns the notification. + * + * @return the notification. + */ + public Notification getNotification() + { + return notif; + } + + /** + * Returns the identifier for the listener + * which received the notification. + * + * @return the identifier. + */ + public Integer getListenerID() + { + return id; + } + + /** + * Returns a textual representation of the object. + * + * @return a textual representation. + */ + public String toString() + { + return getClass().getName() + + "[notif=" + notif + + ",id=" + id + + "]"; + } + +} diff --git a/libjava/classpath/javax/management/remote/package.html b/libjava/classpath/javax/management/remote/package.html new file mode 100644 index 000000000..f1d469f3a --- /dev/null +++ b/libjava/classpath/javax/management/remote/package.html @@ -0,0 +1,53 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> +<!-- package.html - describes classes in javax.management.remote package. + Copyright (C) 2006 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. --> + +<html> +<head><title>GNU Classpath - javax.management.remote</title></head> + +<body> + +<p> +Provides a framework for accessing remote MBean servers. The JMX +remote API introduces the notion of a <emph>connector</emph>. On +the server side, the connector wraps the MBean server, processing +calls from remote clients. The client sends its requests via +a connector which is responsible for transmitting the request +to the server. +</p> +</body> +</html> diff --git a/libjava/classpath/javax/management/remote/rmi/RMIConnection.java b/libjava/classpath/javax/management/remote/rmi/RMIConnection.java new file mode 100644 index 000000000..434051d58 --- /dev/null +++ b/libjava/classpath/javax/management/remote/rmi/RMIConnection.java @@ -0,0 +1,1161 @@ +/* RMIConnection.java -- RMI object representing a MBean server connection. + Copyright (C) 2007, 2008 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.remote.rmi; + +import java.io.Closeable; +import java.io.IOException; + +import java.rmi.MarshalledObject; +import java.rmi.Remote; + +import java.util.Set; + +import javax.management.AttributeList; +import javax.management.AttributeNotFoundException; +import javax.management.InstanceAlreadyExistsException; +import javax.management.InstanceNotFoundException; +import javax.management.IntrospectionException; +import javax.management.InvalidAttributeValueException; +import javax.management.ListenerNotFoundException; +import javax.management.MBeanInfo; +import javax.management.MBeanException; +import javax.management.MBeanRegistrationException; +import javax.management.NotCompliantMBeanException; +import javax.management.ObjectInstance; +import javax.management.ObjectName; +import javax.management.ReflectionException; + +import javax.management.remote.NotificationResult; + +import javax.security.auth.Subject; + +/** + * <p> + * RMI interface for forwarding requests to a remote + * {@link javax.management.MBeanServer}. This interface + * parallels the {@link javax.management.MBeanServerConnection} + * interface, providing a way of invoking those methods using + * the RMI protocol. When a client wishes to call a method + * of an MBean server using RMI, the method is called on the stub + * on the client side, which serializes the object parameters + * and sends them to the server where they are deserialized and + * an implementation of this interface forwards them to the + * appropriate MBean server. Return values follow the same + * process, only in reverse. Each client obtains its own + * implementation of this interface from an {@link RMIServer} + * instance. + * </p> + * <p> + * Implementations of this interface do more than simply + * forward requests directly to the server. The arguments + * of the server methods are wrapped in {@link MarshalledObject} + * instances, so that the correct classloader can be used to + * deserialize the arguments. When a method is called, the + * implementation must first retrieve the appropriate classloader + * and then use it to deserialize the marshalled object. Unless + * explicitly specified in the documentation for the method, + * a parameter of the type {@link MarshalledObject} or an array + * of that type should not be {@code null}. + * </p> + * <p> + * Security is also handled by this interface, as the methods + * use an additional {@link javax.security.auth.Subject} parameter + * for role delegation. + * </p> + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public interface RMIConnection + extends Closeable, Remote +{ + + /** + * Handles {@link + * MBeanServerConnection#addNotificationListener(ObjectName, + * ObjectName, NotificationFilter, Object)} by + * registering the supplied listener with the specified management + * bean. Notifications emitted by the management bean are forwarded + * to the listener via the server, which will convert any MBean + * references in the source to portable {@link ObjectName} + * instances. The notification is otherwise unchanged. The filter + * and handback object are wrapped in a {@link MarshalledObject} + * so that they are deserialised using the bean's classloader. + * + * @param name the name of the management bean with which the listener + * should be registered. + * @param listener the listener which will handle notifications from + * the bean. + * @param filter a wrapper containing a filter to apply to incoming + * notifications, or <code>null</code> if no filtering + * should be applied. + * @param passback a wrapper containing an object to be passed to the + * listener when a notification is emitted. + * @param delegationSubject a {@link javax.security.auth.Subject} instance + * containing the delegation principles or + * {@code null} if authentication is used. + * @throws InstanceNotFoundException if the name of the management bean + * could not be resolved. + * @throws RuntimeOperationsException if the bean associated with the given + * object name is not a + * {@link NotificationListener}. This + * exception wraps an + * {@link IllegalArgumentException}. + * @throws SecurityException if the client or delegated subject (if any) + * does not have permission to invoke this operation. + * @throws IOException if an I/O error occurred in communicating with + * the bean server. + * @see #removeNotificationListener(ObjectName, ObjectName, + * javax.security.auth.Subject) + * @see #removeNotificationListener(ObjectName, ObjectName, + * java.rmi.MarshalledObject, + * java.rmi.MarshalledObject, + * javax.security.auth.Subject) + * @see #removeNotificationListeners(ObjectName, Integer[], + * javax.security.auth.Subject) + * @see NotificationBroadcaster#addNotificationListener(NotificationListener, + * NotificationFilter, + * Object) + */ + @SuppressWarnings("unchecked") + void addNotificationListener(ObjectName name, ObjectName listener, + MarshalledObject filter, MarshalledObject passback, + Subject delegationSubject) + throws InstanceNotFoundException, IOException; + + /** + * Handles {@link + * MBeanServerConnection#addNotificationListener(ObjectName, + * NotificationListener, NotificationFilter, Object)} by + * registering for notifications from the specified management + * beans. The array of filters is assumed to be aligned with + * the array of bean names, so that the notifications from each + * bean are matched against the appropriate filter (or left as + * is if the filter is {@code null}. Notifications emitted by + * the management beans are forwarded to a local listener created + * by this method, via the server, which converts any MBean + * references in the source to portable {@link ObjectName} + * instances. The notification is otherwise unchanged. + * </p> + * <p> + * This local listener buffers the notifications for retrieval by + * {@link #fetchNotifications(long,int,long). This method returns + * an array of listener identifiers which aligns with the supplied + * array of beans so that the appropriate listener can be identified + * by the client, which retains its own listener and handback object. + * The filters are wrapped in {@link MarshalledObject}s so that they are + * deserialised using the bean's classloader. + * </p> + * + * @param names the names of the management bean whose notifications + * should be recorded. + * @param filters an array of wrappers containing filters to apply to + * incoming notifications. An element may be <code>null</code> + * if no filtering should be applied to a bean's notifications. + * @param delegationSubjects an array of {@link javax.security.auth.Subject} + * instances containing the delegation principles for + * each listener. An element may be {@code null} if + * authentication is used instead, or the entire + * argument itself may be {@code null}. In the latter + * case, this is treated as an array of {@code null} + * values. + * @return an array of integers which act as listener identifiers, so that + * notifications retrieved from {@link #fetchNotifications(long,int,long) + * can be matched to the beans they were emitted from. The array is + * aligned against the array of beans supplied to this methods, so that + * the identifier in position 0 represents the bean in position 0 of the + * input array. + * @throws IllegalArgumentException if the {@code names} or {@code filters} array + * is {@code null}, the {@code names} array contains + * a {@code null} value or the three arrays are not + * of the same size. + * @throws ClassCastException if an element of the {@code filters} array unmarshalls + * as a non-null object that is not a {@link NotificationFilter}. + * @throws InstanceNotFoundException if the name of one of the management beans + * could not be resolved. + * @throws SecurityException if, for one of the beans, the client or delegated subject + * (if any) does not have permission to invoke this operation. + * @throws IOException if an I/O error occurred in communicating with + * the bean server. + * @see #removeNotificationListener(ObjectName, ObjectName, + * javax.security.auth.Subject) + * @see #removeNotificationListener(ObjectName, ObjectName, + * java.rmi.MarshalledObject, + * java.rmi.MarshalledObject, + * javax.security.auth.Subject) + * @see #removeNotificationListeners(ObjectName, Integer[], + * javax.security.auth.Subject) + * @see NotificationBroadcaster#addNotificationListener(NotificationListener, + * NotificationFilter, + * Object) + */ + @SuppressWarnings("unchecked") + Integer[] addNotificationListeners(ObjectName[] names, MarshalledObject[] filters, + Subject[] delegationSubjects) + throws InstanceNotFoundException, IOException; + + /** + * Closes the connection and unexports the RMI object implementing this + * interface. Following this call, future method calls to this instance + * will fail. + * + * @throws IOException if there is an I/O error in transmitting the close + * request via RMI, closing the connection, or unexporting + * the RMI object. + */ + void close() + throws IOException; + + /** + * <p> + * Handles {@link + * MBeanServerConnection#createMBean(String, ObjectName, + * Object[], String[])}. The array of parameters is wrapped in + * a {@link MarshalledObject} so that it is deserialised using the + * bean's classloader. + * </p> + * <p> + * Instantiates a new instance of the specified management bean + * using the given constructor and registers it with the server + * under the supplied name. The class is loaded using the + * {@link javax.management.loading.ClassLoaderRepository default + * loader repository} of the server. + * </p> + * <p> + * If the name supplied is <code>null</code>, then the bean is + * expected to implement the {@link MBeanRegistration} interface. + * The {@link MBeanRegistration#preRegister preRegister} method + * of this interface will be used to obtain the name in this case. + * </p> + * + * @param className the class of the management bean, of which + * an instance should be created. + * @param name the name to register the new bean with. This may + * be <code>null</code>. + * @param params the parameters for the bean's constructor, encapsulated + * in a {@link MarshalledObject}. If this parameter is + * <code>null</code>, it will be judged equivalent to an + * empty array. + * @param sig the signature of the constructor to use. If this parameter + * is <code>null</code>, it will be judged equivalent to an + * empty array. + * @param delegationSubject an instance of {@link javax.security.auth.Subject} + * containing the delegation principles. This may be + * {@code null} is authentication is used instead. + * @return an {@link ObjectInstance} containing the {@link ObjectName} + * and Java class name of the created instance. + * @throws ReflectionException if an exception occurs in creating + * an instance of the bean. + * @throws InstanceAlreadyExistsException if a matching instance + * already exists. + * @throws MBeanRegistrationException if an exception occurs in + * calling the preRegister + * method. + * @throws MBeanException if the bean's constructor throws an exception. + * @throws NotCompliantMBeanException if the created bean is not + * compliant with the JMX specification. + * @throws RuntimeOperationsException if an {@link IllegalArgumentException} + * is thrown by the server due to a + * <code>null</code> class name or object + * name or if the object name is a pattern. + * @throws SecurityException if the client or delegated subject (if any) does + * not have permission to invoke this operation. + * @throws IOException if an I/O error occurred in communicating with + * the bean server. + */ + @SuppressWarnings("unchecked") + ObjectInstance createMBean(String className, ObjectName name, + MarshalledObject params, String[] sig, + Subject delegationSubject) + throws ReflectionException, InstanceAlreadyExistsException, + MBeanRegistrationException, MBeanException, + NotCompliantMBeanException, IOException; + + /** + * <p> + * Handles {@link + * MBeanServerConnection#createMBean(String, ObjectName, + * ObjectName, Object[], String[])}. The array of parameters is + * wrapped in a {@link MarshalledObject} so that it is deserialised + * using the bean's classloader. + * </p> + * <p> + * Instantiates a new instance of the specified management bean + * using the given constructor and registers it with the server + * under the supplied name. The class is loaded using the + * given class loader. If this argument is <code>null</code>, + * then the same class loader as was used to load the server + * is used. + * </p> + * <p> + * If the name supplied is <code>null</code>, then the bean is + * expected to implement the {@link MBeanRegistration} interface. + * The {@link MBeanRegistration#preRegister preRegister} method + * of this interface will be used to obtain the name in this case. + * </p> + * + * @param className the class of the management bean, of which + * an instance should be created. + * @param name the name to register the new bean with. This may + * be <code>null</code>. + * @param loaderName the name of the class loader. + * @param params the parameters for the bean's constructor, encapsulated + * in a {@link MarshalledObject}. If this parameter is + * <code>null</code>, it will be judged equivalent to an + * empty array. + * @param sig the signature of the constructor to use. If this parameter + * is <code>null</code>, it will be judged equivalent to an + * empty array. + * @param delegationSubject an instance of {@link javax.security.auth.Subject} + * containing the delegation principles. This may be + * {@code null} is authentication is used instead. + * @return an {@link ObjectInstance} containing the {@link ObjectName} + * and Java class name of the created instance. + * @throws ReflectionException if an exception occurs in creating + * an instance of the bean. + * @throws InstanceAlreadyExistsException if a matching instance + * already exists. + * @throws MBeanRegistrationException if an exception occurs in + * calling the preRegister + * method. + * @throws MBeanException if the bean's constructor throws an exception. + * @throws NotCompliantMBeanException if the created bean is not + * compliant with the JMX specification. + * @throws InstanceNotFoundException if the specified class loader is not + * registered with the server. + * @throws RuntimeOperationsException if an {@link IllegalArgumentException} + * is thrown by the server due to a + * <code>null</code> class name or object + * name or if the object name is a pattern. + * @throws SecurityException if the client or delegated subject (if any) does + * not have permission to invoke this operation. + * @throws IOException if an I/O error occurred in communicating with + * the bean server. + */ + @SuppressWarnings("unchecked") + ObjectInstance createMBean(String className, ObjectName name, + ObjectName loaderName, MarshalledObject params, + String[] sig, Subject delegationSubject) + throws ReflectionException, InstanceAlreadyExistsException, + MBeanRegistrationException, MBeanException, + NotCompliantMBeanException, InstanceNotFoundException, + IOException; + + /** + * <p> + * Handles {@link + * MBeanServerConnection#createMBean(String, ObjectName, + * ObjectName)} by instantiating a new instance of the specified + * management bean using the default constructor and registering + * it with the server under the supplied name. The class is loaded + * using the given class loader. If this argument is <code>null</code>, + * then the same class loader as was used to load the server + * is used. + * </p> + * <p> + * If the name supplied is <code>null</code>, then the bean is + * expected to implement the {@link MBeanRegistration} interface. + * The {@link MBeanRegistration#preRegister preRegister} method + * of this interface will be used to obtain the name in this case. + * </p> + * <p> + * This method is equivalent to calling {@link + * #createMBean(String, ObjectName, ObjectName, Object[], String) + * <code>createMBean(className, name, loaderName, (Object[]) null, + * (String) null)</code>} with <code>null</code> parameters + * and signature. + * </p> + * + * @param className the class of the management bean, of which + * an instance should be created. + * @param name the name to register the new bean with. This may + * be <code>null</code>. + * @param loaderName the name of the class loader. + * @param delegationSubject an instance of {@link javax.security.auth.Subject} + * containing the delegation principles. This may be + * {@code null} is authentication is used instead. + * @return an {@link ObjectInstance} containing the {@link ObjectName} + * and Java class name of the created instance. + * @throws ReflectionException if an exception occurs in creating + * an instance of the bean. + * @throws InstanceAlreadyExistsException if a matching instance + * already exists. + * @throws MBeanRegistrationException if an exception occurs in + * calling the preRegister + * method. + * @throws MBeanException if the bean's constructor throws an exception. + * @throws NotCompliantMBeanException if the created bean is not + * compliant with the JMX specification. + * @throws InstanceNotFoundException if the specified class loader is not + * registered with the server. + * @throws RuntimeOperationsException if an {@link IllegalArgumentException} + * is thrown by the server due to a + * <code>null</code> class name or object + * name or if the object name is a pattern. + * @throws SecurityException if the client or delegated subject (if any) does + * not have permission to invoke this operation. + * @throws IOException if an I/O error occurred in communicating with + * the bean server. + * @see #createMBean(String, ObjectName, ObjectName, MarshalledObject, + * String[], Subject) + */ + ObjectInstance createMBean(String className, ObjectName name, + ObjectName loaderName, Subject delegationSubject) + throws ReflectionException, InstanceAlreadyExistsException, + MBeanRegistrationException, MBeanException, + NotCompliantMBeanException, InstanceNotFoundException, + IOException; + + /** + * <p> + * Handles {@link + * MBeanServerConnection#createMBean(String, ObjectName)} by + * instantiating a new instance of the specified management bean + * using the default constructor and registering it with the server + * under the supplied name. The class is loaded using the + * {@link javax.management.loading.ClassLoaderRepository default + * loader repository} of the server. + * </p> + * <p> + * If the name supplied is <code>null</code>, then the bean is + * expected to implement the {@link MBeanRegistration} interface. + * The {@link MBeanRegistration#preRegister preRegister} method + * of this interface will be used to obtain the name in this case. + * </p> + * <p> + * This method is equivalent to calling {@link + * #createMBean(String, ObjectName, Object[], String[]) + * <code>createMBean(className, name, (Object[]) null, + * (String[]) null)</code>} with <code>null</code> parameters + * and signature. + * </p> + * + * @param className the class of the management bean, of which + * an instance should be created. + * @param name the name to register the new bean with. This may + * be <code>null</code>. + * @param delegationSubject an instance of {@link javax.security.auth.Subject} + * containing the delegation principles. This may be + * {@code null} is authentication is used instead. + * @return an {@link ObjectInstance} containing the {@link ObjectName} + * and Java class name of the created instance. + * @throws ReflectionException if an exception occurs in creating + * an instance of the bean. + * @throws InstanceAlreadyExistsException if a matching instance + * already exists. + * @throws MBeanRegistrationException if an exception occurs in + * calling the preRegister + * method. + * @throws MBeanException if the bean's constructor throws an exception. + * @throws NotCompliantMBeanException if the created bean is not + * compliant with the JMX specification. + * @throws RuntimeOperationsException if an {@link IllegalArgumentException} + * is thrown by the server due to a + * <code>null</code> class name or object + * name or if the object name is a pattern. + * @throws SecurityException if the client or delegated subject (if any) does + * not have permission to invoke this operation. + * @throws IOException if an I/O error occurred in communicating with + * the bean server. + * @see #createMBean(String, ObjectName, MarshalledObject, String[], Subject) + */ + ObjectInstance createMBean(String className, ObjectName name, + Subject delegationSubject) + throws ReflectionException, InstanceAlreadyExistsException, + MBeanRegistrationException, MBeanException, + NotCompliantMBeanException, IOException; + + /** + * <p> + * Retrieves any waiting notifications from the server. When notifications + * are requested using the {@link #addNotificationListeners(ObjectName[], + * MarshalledObject[], Subject[])} method, the server sets up an internal + * listener to receive notifications from the bean and buffer them. When + * this method is called, these buffered notifications can be retrieved. + * </p> + * <p> + * The blocking behaviour of this method depends on the timeout value specified. + * If there are no waiting notifications in the buffer, a value of 0 will cause + * the method to return immediately. Conversely, if the value is + * {@link Long#MAX_VALUE}, then it will wait indefinitely until a notification + * arrives. For any other value, it waits until a notification arrives or the + * number of milliseconds specified by the timeout value is exceeded. The + * behaviour for a negative timeout value is undefined. + * </p> + * <p> + * For a notification to be returned, the following criteria must be fulfilled: + * </p> + * <ul> + * <li>the client must have previously requested notifications from at least + * one bean</li> + * <li>a bean from which notifications have been requested must have emitted + * a notification since the last call to this method</li> + * <li>the emitted notification must pass through any filters established + * when notifications were requested</li> + * <li>the sequence number of the notification must be greater than or equal + * to the specified sequence number (if non-negative)</li> + * </ul> + * + * @param sequenceNumber the sequence number of each notification returned + * must be greater than or equal to this value. If + * the number is negative, this is interpreted as + * meaning the sequence number of the next notification + * and so all notifications are allowed through. + * @param maxNotifications the maximum number of notifications to return. + * This does not include any duplicates so the + * number of actual notifications returned may + * be larger. + * @param timeout the number of milliseconds to wait for a notification + * if the buffer is empty. <code>0</code> causes the + * method to return immediately even if there are no + * notifications available (non-blocking behaviour) while + * a value of {@link Long#MAX_VALUE} causes it to wait + * indefinitely (blocking behaviour). The response to + * a negative value is undefined. + * @return a {@link NotificationResult} object containing the buffered + * notifications. + * @throws IOException if an I/O error occurs. + */ + NotificationResult fetchNotifications(long sequenceNumber, + int maxNotifications, + long timeout) + throws IOException; + + /** + * Handles {@link + * MBeanServerConnection#getAttribute(ObjectName, String)}, + * returning the value of the supplied attribute from the specified + * management bean. + * + * @param bean the bean to retrieve the value from. + * @param name the name of the attribute to retrieve. + * @param delegationSubject an instance of {@link javax.security.auth.Subject} + * containing the delegation principles. This may be + * {@code null} is authentication is used instead. + * @return the value of the attribute. + * @throws AttributeNotFoundException if the attribute could not be + * accessed from the bean. + * @throws MBeanException if the management bean's accessor throws + * an exception. + * @throws InstanceNotFoundException if the bean can not be found. + * @throws ReflectionException if an exception was thrown in trying + * to invoke the bean's accessor. + * @throws RuntimeOperationsException if an {@link IllegalArgumentException} + * is thrown by the server due to a + * <code>null</code> bean or attribute + * name. + * @throws SecurityException if the client or delegated subject (if any) does + * not have permission to invoke this operation. + * @throws IOException if an I/O error occurred in communicating with + * the bean server. + * @see DynamicMBean#getAttribute(String) + */ + Object getAttribute(ObjectName bean, String name, Subject delegationSubject) + throws MBeanException, AttributeNotFoundException, + InstanceNotFoundException, ReflectionException, + IOException; + + /** + * Handles {@link + * MBeanServerConnection#getAttribute(ObjectName, String)}, + * returning the values of the named attributes from the specified + * management bean. + * + * @param bean the bean to retrieve the value from. + * @param names the names of the attributes to retrieve. + * @param delegationSubject an instance of {@link javax.security.auth.Subject} + * containing the delegation principles. This may be + * {@code null} is authentication is used instead. + * @return the values of the attributes. + * @throws InstanceNotFoundException if the bean can not be found. + * @throws ReflectionException if an exception was thrown in trying + * to invoke the bean's accessor. + * @throws RuntimeOperationsException if an {@link IllegalArgumentException} + * is thrown by the server due to a + * <code>null</code> bean or attribute + * name. + * @throws SecurityException if the client or delegated subject (if any) does + * not have permission to invoke this operation. + * @throws IOException if an I/O error occurred in communicating with + * the bean server. + * @see DynamicMBean#getAttributes(String[]) + */ + AttributeList getAttributes(ObjectName bean, String[] names, + Subject delegationSubject) + throws InstanceNotFoundException, ReflectionException, + IOException; + + /** + * Returns the unique identifier for this connection to the RMI + * server. + * + * @return the connection ID. + * @throws IOException if an I/O error occurred. + */ + String getConnectionId() + throws IOException; + + /** + * Handles {@link + * MBeanServerConnection#getDefaultDomain()} by returning the default + * domain this server applies to beans that have no specified domain. + * + * @param delegationSubject an instance of {@link javax.security.auth.Subject} + * containing the delegation principles. This may be + * {@code null} is authentication is used instead. + * @return the default domain. + * @throws SecurityException if the client or delegated subject (if any) does + * not have permission to invoke this operation. + * @throws IOException if an I/O error occurred in communicating with + * the bean server. + */ + String getDefaultDomain(Subject delegationSubject) + throws IOException; + + /** + * Handles {@link + * MBeanServerConnection#getDomains()} by returning an array + * containing all the domains used by beans registered with + * this server. The ordering of the array is undefined. + * + * @param delegationSubject an instance of {@link javax.security.auth.Subject} + * containing the delegation principles. This may be + * {@code null} is authentication is used instead. + * @return the list of domains. + * @throws SecurityException if the client or delegated subject (if any) does + * not have permission to invoke this operation. + * @throws IOException if an I/O error occurred in communicating with + * the bean server. + * @see ObjectName#getDomain() + */ + String[] getDomains(Subject delegationSubject) + throws IOException; + + /** + * Handles {@link + * MBeanServerConnection#getMBeanCount()} by returning the number of + * management beans registered with this server. + * + * @param delegationSubject an instance of {@link javax.security.auth.Subject} + * containing the delegation principles. This may be + * {@code null} is authentication is used instead. + * @return the number of registered beans. + * @throws SecurityException if the client or delegated subject (if any) does + * not have permission to invoke this operation. + * @throws IOException if an I/O error occurred in communicating with + * the bean server. + */ + Integer getMBeanCount(Subject delegationSubject) + throws IOException; + + /** + * Handles {@link + * MBeanServerConnection#getMBeanInfo(ObjectName)} by returning + * information on the given management bean. + * + * @param name the name of the management bean. + * @param delegationSubject an instance of {@link javax.security.auth.Subject} + * containing the delegation principles. This may be + * {@code null} is authentication is used instead. + * @return an instance of {@link MBeanInfo} for the bean. + * @throws IntrospectionException if an exception occurs in examining + * the bean. + * @throws InstanceNotFoundException if the bean can not be found. + * @throws ReflectionException if an exception occurs when trying + * to invoke {@link DynamicMBean#getMBeanInfo()} + * on the bean. + * @throws SecurityException if the client or delegated subject (if any) does + * not have permission to invoke this operation. + * @throws IOException if an I/O error occurred in communicating with + * the bean server. + * @see DynamicMBean#getMBeanInfo() + */ + MBeanInfo getMBeanInfo(ObjectName name, Subject delegationSubject) + throws InstanceNotFoundException, IntrospectionException, + ReflectionException, IOException; + + /** + * Handles {@link + * MBeanServerConnection#getObjectInstance(ObjectName)} by returning + * the {@link ObjectInstance} created for the specified management + * bean on registration. + * + * @param name the name of the bean. + * @param delegationSubject an instance of {@link javax.security.auth.Subject} + * containing the delegation principles. This may be + * {@code null} is authentication is used instead. + * @return the corresponding {@link ObjectInstance} instance. + * @throws InstanceNotFoundException if the bean can not be found. + * @throws SecurityException if the client or delegated subject (if any) does + * not have permission to invoke this operation. + * @throws IOException if an I/O error occurred in communicating with + * the bean server. + * @see #createMBean(String, ObjectName, Subject) + */ + ObjectInstance getObjectInstance(ObjectName name, Subject delegationSubject) + throws InstanceNotFoundException, IOException; + + /** + * <p> + * Handles {@link + * MBeanServerConnection#invoke(ObjectName, String, Object[], + * String[])}. The array of parameters is wrapped in a + * {@link MarshalledObject} so that it is deserialised + * using the bean's classloader. + * </p> + * <p> + * Invokes the supplied operation on the specified management + * bean. The class objects specified in the signature are loaded + * using the same class loader as was used for the management bean. + * + * @param bean the management bean whose operation should be invoked. + * @param name the name of the operation to invoke. + * @param params the parameters for the bean's constructor, encapsulated + * in a {@link MarshalledObject}. If this parameter is + * <code>null</code>, it will be judged equivalent to an + * empty array. + * @param sig the signature of the constructor to use. If this parameter + * is <code>null</code>, it will be judged equivalent to an + * empty array. The class objects will be loaded using the + * bean's classloader. + * @param delegationSubject an instance of {@link javax.security.auth.Subject} + * containing the delegation principles. This may be + * {@code null} is authentication is used instead. + * @return the return value of the method. + * @throws InstanceNotFoundException if the bean can not be found. + * @throws MBeanException if the method invoked throws an exception. + * @throws ReflectionException if an exception is thrown in invoking the + * method. + * @throws SecurityException if the client or delegated subject (if any) does + * not have permission to invoke this operation. + * @throws IOException if an I/O error occurred in communicating with + * the bean server. + * @see DynamicMBean#invoke(String, Object[], String[]) + */ + @SuppressWarnings("unchecked") + Object invoke(ObjectName bean, String name, MarshalledObject params, + String[] sig, Subject delegationSubject) + throws InstanceNotFoundException, MBeanException, + ReflectionException, IOException; + + /** + * <p> + * Handles {@link + * MBeanServerConnection#isInstanceOf(ObjectName, String) by + * returning true if the specified management bean is an instance + * of the supplied class. + * </p> + * <p> + * A bean, B, is an instance of a class, C, if either of the following + * conditions holds: + * </p> + * <ul> + * <li>The class name in B's {@link MBeanInfo} is equal to the supplied + * name.</li> + * <li>Both the class of B and C were loaded by the same class loader, + * and B is assignable to C.</li> + * </ul> + * + * @param name the name of the management bean. + * @param className the name of the class to test if <code>name</code> is + * an instance of. + * @param delegationSubject an instance of {@link javax.security.auth.Subject} + * containing the delegation principles. This may be + * {@code null} is authentication is used instead. + * @return true if either B is directly an instance of the named class, + * or B is assignable to the class, given that both it and B's + * current class were loaded using the same class loader. + * @throws InstanceNotFoundException if the bean can not be found. + * @throws SecurityException if the client or delegated subject (if any) does + * not have permission to invoke this operation. + * @throws IOException if an I/O error occurred in communicating with + * the bean server. + */ + boolean isInstanceOf(ObjectName name, String className, + Subject delegationSubject) + throws InstanceNotFoundException, IOException; + + /** + * Handles {@link + * MBeanServerConnection#isRegistered(ObjectName) by returning + * true if the specified management bean is registered with + * the server. + * + * @param name the name of the management bean. + * @param delegationSubject an instance of {@link javax.security.auth.Subject} + * containing the delegation principles. This may be + * {@code null} is authentication is used instead. + * @return true if the bean is registered. + * @throws RuntimeOperationsException if an {@link IllegalArgumentException} + * is thrown by the server due to a + * <code>null</code> bean name. + * @throws SecurityException if the client or delegated subject (if any) does + * not have permission to invoke this operation. + * @throws IOException if an I/O error occurred in communicating with + * the bean server. + */ + boolean isRegistered(ObjectName name, Subject delegationSubject) + throws IOException; + + /** + * <p> + * Handles {@link + * MBeanServerConnection#queryMBeans(ObjectName, QueryExp)}. + * The query expression is wrapped in a {@link MarshalledObject} + * so that it is deserialised using the bean's classloader. + * </p> + * <p> + * Returns a set of {@link ObjectInstance}s matching the specified + * criteria. The full set of beans registered with the server + * are passed through two filters: + * </p> + * <ol> + * <li>Pattern matching is performed using the supplied + * {@link ObjectName}.</li> + * <li>The supplied query expression is applied.</li> + * </ol> + * <p> + * If both the object name and the query expression are <code>null</code>, + * or the object name has no domain and no key properties, + * no filtering will be performed and all beans are returned. + * </p> + * + * @param name an {@link ObjectName} to use as a filter. + * @param query a query expression to apply to each of the beans that match + * the given object name, encapsulated in a + * {@link MarshalledObject}. If a <code>null</code> value is + * encapsulated, then the beans will only be filtered using + * pattern matching on the supplied {@link ObjectName}. + * @param delegationSubject an instance of {@link javax.security.auth.Subject} + * containing the delegation principles. This may be + * {@code null} is authentication is used instead. + * @return a set of {@link ObjectInstance}s matching the filtered beans. + * This is empty if no beans survived the filters. + * @throws IOException if an I/O error occurred in communicating with + * the bean server. + * @throws SecurityException if the client or delegated subject (if any) does + * not have permission to invoke this operation. + */ + @SuppressWarnings("unchecked") + Set<ObjectInstance> queryMBeans(ObjectName name, MarshalledObject query, + Subject delegationSubject) + throws IOException; + + /** + * <p> + * Handles {@link + * MBeanServerConnection#queryNames(ObjectName, QueryExp)}. + * The query expression is wrapped in a {@link MarshalledObject} + * so that it is deserialised using the bean's classloader. + * </p> + * <p> + * Returns a set of {@link ObjectName}s matching the specified + * criteria. The full set of beans registered with the server + * are passed through two filters: + * </p> + * <ol> + * <li>Pattern matching is performed using the supplied + * {@link ObjectName}.</li> + * <li>The supplied query expression is applied.</li> + * </ol> + * <p> + * If both the object name and the query expression are <code>null</code>, + * or the object name has no domain and no key properties, + * no filtering will be performed and all beans are returned. + * </p> + * + * @param name an {@link ObjectName} to use as a filter. + * @param query a query expression to apply to each of the beans that match + * the given object name, encapsulated in a + * {@link MarshalledObject}. If a <code>null</code> value is + * encapsulated, then the beans will only be filtered using + * pattern matching on the supplied {@link ObjectName}. + * @param delegationSubject an instance of {@link javax.security.auth.Subject} + * containing the delegation principles. This may be + * {@code null} is authentication is used instead. + * @return a set of {@link ObjectName}s matching the filtered beans. + * @throws SecurityException if the client or delegated subject (if any) does + * not have permission to invoke this operation. + * @throws IOException if an I/O error occurred in communicating with + * the bean server. + */ + @SuppressWarnings("unchecked") + Set<ObjectName> queryNames(ObjectName name, MarshalledObject query, + Subject delegationSubject) + throws IOException; + + /** + * <p> + * Handles {@link + * MBeanServerConnection#removeNotificationListener(ObjectName, + * ObjectName, NotificationFilter, Object)}. Both the filter and + * the handback object are wrapped in a {@link MarshalledObject} + * so that they are deserialised using the bean's classloader. + * </p> + * <p> + * Removes the specified listener from the list of recipients + * of notifications from the supplied bean. Only the first instance with + * the supplied filter and passback object is removed. + * <code>null</code> is used as a valid value for these parameters, + * rather than as a way to remove all registration instances for + * the specified listener; for this behaviour instead, see + * {@link #removeNotificationListener(ObjectName, NotificationListener)}. + * </p> + * + * @param name the name of the management bean from which the + * listener should be removed. + * @param listener the listener to remove. + * @param filter a wrapper containing the filter of the listener + * to remove. + * @param passback a wrapper containing the handback object of the + * listener to remove. + * @param delegationSubject a {@link javax.security.auth.Subject} instance + * containing the delegation principles or + * {@code null} if authentication is used. + * @throws InstanceNotFoundException if the bean can not be found. + * @throws ListenerNotFoundException if the specified listener + * is not registered with the bean. + * @throws SecurityException if the client or delegated subject (if any) does + * not have permission to invoke this operation. + * @throws IOException if an I/O error occurred in communicating with + * the bean server. + * @see #addNotificationListener(ObjectName, NotificationListener, + * MarshalledObject, MarshalledObject, Subject) + * @see NotificationEmitter#removeNotificationListener(NotificationListener, + * NotificationFilter, + * Object) + */ + @SuppressWarnings("unchecked") + void removeNotificationListener(ObjectName name, + ObjectName listener, + MarshalledObject filter, + MarshalledObject passback, + Subject delegationSubject) + throws InstanceNotFoundException, ListenerNotFoundException, + IOException; + + /** + * Handles {@link + * MBeanServerConnection#removeNotificationListener(ObjectName, + * ObjectName)} by removing the specified listener from the list + * of recipients of notifications from the supplied bean. This + * includes all combinations of filters and passback objects + * registered for this listener. For more specific removal of + * listeners, see {@link #removeNotificationListener(ObjectName, + * ObjectName,MarshalledObject,MarshalledObject,Subject)} + * + * @param name the name of the management bean from which the + * listener should be removed. + * @param listener the name of the listener to remove. + * @param delegationSubject a {@link javax.security.auth.Subject} instance + * containing the delegation principles or + * {@code null} if authentication is used. + * @throws InstanceNotFoundException if a name doesn't match a registered + * bean. + * @throws ListenerNotFoundException if the specified listener + * is not registered with the bean. + * @throws SecurityException if the client or delegated subject (if any) does + * not have permission to invoke this operation. + * @throws IOException if an I/O error occurred in communicating with + * the bean server. + * @see #addNotificationListener(ObjectName, NotificationListener, + * MarshalledObject, MarshalledObject, Subject) + * @see NotificationBroadcaster#removeNotificationListener(NotificationListener) + */ + void removeNotificationListener(ObjectName name, ObjectName listener, + Subject delegationSubject) + throws InstanceNotFoundException, ListenerNotFoundException, + IOException; + + /** + * Removes one or more {@link NotificationListener}s from the specified + * management bean. This method corresponds to + * {@link #addNotificationListeners(ObjectName[], MarshalledObject[], + * Subject)} and provides a different way of handling + * MBeanServerConnection#removeNotificationListener(ObjectName, + * ObjectName)} and + * {@link MBeanServerConnection#removeNotificationListener(ObjectName, + * ObjectName, NotificationFilter, Object)} by using the integer + * identifiers provided by the + * {@link #addNotificationListeners(ObjectName[], MarshalledObject[], + * Subject)} method to select the listeners to remove. + * + * @param name the name of the management bean from which the + * listeners should be removed. + * @param listenerIds the identifiers of the listeners to remove. + * @param delegationSubject a {@link javax.security.auth.Subject} instance + * containing the delegation principles or + * {@code null} if authentication is used. + * @throws InstanceNotFoundException if a name doesn't match a registered + * bean. + * @throws ListenerNotFoundException if the specified listener + * is not registered with the bean. + * @throws SecurityException if the client or delegated subject (if any) does + * not have permission to invoke this operation. + * @throws IOException if an I/O error occurred in communicating with + * the bean server. + * @throws IllegalArgumentException if either <code>name</code>, + * <code>listenerIds</code> or an element + * of <code>listenerIds</code> + * is <code>null</code>. + * @see #addNotificationListeners(ObjectName[], MarshalledObject[], Subject) + */ + void removeNotificationListeners(ObjectName name, Integer[] listenerIds, + Subject delegationSubject) + throws InstanceNotFoundException, ListenerNotFoundException, + IOException; + + /** + * Handles {@link + * MBeanServerConnection#setAttribute(ObjectName, Attribute)} + * by setting the value of the specified attribute of the supplied + * management bean. The attribute is wrapped in a + * {@link MarshalledObject} so that it is deserialised using the + * bean's classloader. + * + * @param name the name of the management bean. + * @param attribute the attribute to set, encapsulated in a + * {@link MarshalledObject}. + * @param delegationSubject a {@link javax.security.auth.Subject} instance + * containing the delegation principles or + * {@code null} if authentication is used. + * @throws InstanceNotFoundException if the bean can not be found. + * @throws AttributeNotFoundException if the attribute does not + * correspond to an attribute + * of the bean. + * @throws InvalidAttributeValueException if the value is invalid + * for this particular + * attribute of the bean. + * @throws MBeanException if setting the attribute causes + * the bean to throw an exception (which + * becomes the cause of this exception). + * @throws ReflectionException if an exception occurred in trying + * to use the reflection interface + * to lookup the attribute. The + * thrown exception is the cause of + * this exception. + * @throws RuntimeOperationsException if an {@link IllegalArgumentException} + * is thrown by the server due to a + * <code>null</code> bean or attribute + * name. + * @throws SecurityException if the client or delegated subject (if any) does + * not have permission to invoke this operation. + * @throws IOException if an I/O error occurred in communicating with + * the bean server. + * @see #getAttribute(ObjectName, String, Subject) + * @see javax.management.DynamicMBean#setAttribute(Attribute) + */ + @SuppressWarnings("unchecked") + void setAttribute(ObjectName name, MarshalledObject attribute, + Subject delegationSubject) + throws InstanceNotFoundException, AttributeNotFoundException, + InvalidAttributeValueException, MBeanException, + ReflectionException, IOException; + + /** + * Handles {@link + * MBeanServerConnection#setAttributes(ObjectName, AttributeList)} + * by setting the value of each of the specified attributes + * of the supplied management bean to that specified by + * the {@link Attribute} object. The returned list contains + * the attributes that were set and their new values. + * The attribute list is wrapped in a {@link MarshalledObject} so + * that it is deserialised using the bean's classloader. + * + * @param name the name of the management bean. + * @param attributes the attributes to set, encapsulated in a + * {@link MarshalledObject}. + * @param delegationSubject a {@link javax.security.auth.Subject} instance + * containing the delegation principles or + * {@code null} if authentication is used. + * @return a list of the changed attributes. + * @throws InstanceNotFoundException if the bean can not be found. + * @throws ReflectionException if an exception occurred in trying + * to use the reflection interface + * to lookup the attribute. The + * thrown exception is the cause of + * this exception. + * @throws RuntimeOperationsException if an {@link IllegalArgumentException} + * is thrown by the server due to a + * <code>null</code> bean or attribute + * list. + * @throws SecurityException if the client or delegated subject (if any) does + * not have permission to invoke this operation. + * @throws IOException if an I/O error occurred in communicating with + * the bean server. + * @see #getAttributes(ObjectName, String[]) + * @see DynamicMBean#setAttributes(AttributeList) + */ + @SuppressWarnings("unchecked") + AttributeList setAttributes(ObjectName name, MarshalledObject attributes, + Subject delegationSubject) + throws InstanceNotFoundException, ReflectionException, + IOException; + + /** + * Handles {@link + * MBeanServerConnection#unregisterMBean(ObjectName)} by unregistering + * the specified management bean. Following this operation, + * the bean instance is no longer accessible from the server via this + * name. Prior to unregistering the bean, the + * {@link MBeanRegistration#preDeregister()} method will be called if + * the bean implements the {@link MBeanRegistration} interface. + * + * @param name the name of the management bean. + * @param delegationSubject a {@link javax.security.auth.Subject} instance + * containing the delegation principles or + * {@code null} if authentication is used. + * @throws InstanceNotFoundException if the bean can not be found. + * @throws MBeanRegistrationException if an exception occurs in + * calling the preDeregister + * method. + * @throws RuntimeOperationsException if an {@link IllegalArgumentException} + * is thrown by the server due to a + * <code>null</code> bean name or a + * request being made to unregister the + * {@link MBeanServerDelegate} bean. + * @throws SecurityException if the client or delegated subject (if any) does + * not have permission to invoke this operation. + * @throws IOException if an I/O error occurred in communicating with + * the bean server. + */ + void unregisterMBean(ObjectName name, Subject delegationSubject) + throws InstanceNotFoundException, MBeanRegistrationException, + IOException; + +} diff --git a/libjava/classpath/javax/management/remote/rmi/RMIServer.java b/libjava/classpath/javax/management/remote/rmi/RMIServer.java new file mode 100644 index 000000000..d862372ac --- /dev/null +++ b/libjava/classpath/javax/management/remote/rmi/RMIServer.java @@ -0,0 +1,89 @@ +/* RMIServer.java -- RMI object for connecting to an RMI JMX connector. + 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.remote.rmi; + +import java.io.IOException; + +import java.rmi.Remote; +import java.rmi.RemoteException; + +/** + * RMI interface for obtaining an instance of an + * {@link RMIConnection}. An implementation of this + * interface exists for each RMI connector. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public interface RMIServer + extends Remote +{ + + /** + * Returns the version of the RMI connection protocol used + * by this server. The returned string takes the form of + * <emph>protocol-version implementation-name</emph> where + * <emph>protocol-version</emph> is a series of two or more + * non-negative integers, separated by a decimal point (.) + * (currently {@code 1.0}) and <emph>implementation-name</emph> + * is the string {@code "GNU Classpath"} followed by the version + * of GNU Classpath in use. + * + * @return the string specified above. + * @throws RemoteException if there is a problem with the transfer + * of the string via RMI. + */ + String getVersion() + throws RemoteException; + + /** + * Constructs and returns a new RMI connection using the specified + * authentication credentials. Each client calls this method to + * obtain a connection to the server. + * + * @param credentials a user-defined object passed to the server + * to authenticate the client. May be {@code null}. + * @return the new connection. + * @throws IOException if the new connection can not be created or + * exported, or an error occurs in the RMI transmission. + * @throws SecurityException if the client could not be authenticated + * correctly using the supplied credientials. + */ + RMIConnection newClient(Object credentials) + throws IOException; +} |