0N/A/*
2362N/A * Copyright (c) 2000, 2008, Oracle and/or its affiliates. All rights reserved.
0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0N/A *
0N/A * This code is free software; you can redistribute it and/or modify it
0N/A * under the terms of the GNU General Public License version 2 only, as
2362N/A * published by the Free Software Foundation. Oracle designates this
0N/A * particular file as subject to the "Classpath" exception as provided
2362N/A * by Oracle in the LICENSE file that accompanied this code.
0N/A *
0N/A * This code is distributed in the hope that it will be useful, but WITHOUT
0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0N/A * version 2 for more details (a copy is included in the LICENSE file that
0N/A * accompanied this code).
0N/A *
0N/A * You should have received a copy of the GNU General Public License version
0N/A * 2 along with this work; if not, write to the Free Software Foundation,
0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0N/A *
2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2362N/A * or visit www.oracle.com if you need additional information or have any
2362N/A * questions.
0N/A */
0N/A/*
0N/A * @author IBM Corp.
0N/A *
0N/A * Copyright IBM Corp. 1999-2000. All rights reserved.
0N/A */
0N/A
0N/Apackage javax.management.modelmbean;
0N/A
0N/Aimport static com.sun.jmx.defaults.JmxProperties.MODELMBEAN_LOGGER;
0N/Aimport com.sun.jmx.mbeanserver.GetPropertyAction;
0N/A
0N/Aimport java.io.IOException;
0N/Aimport java.io.ObjectInputStream;
0N/Aimport java.io.ObjectOutputStream;
0N/Aimport java.io.ObjectStreamField;
0N/Aimport java.security.AccessController;
0N/Aimport java.util.logging.Level;
0N/A
0N/Aimport javax.management.Descriptor;
0N/Aimport javax.management.DescriptorAccess;
0N/Aimport javax.management.MBeanNotificationInfo;
0N/Aimport javax.management.RuntimeOperationsException;
0N/A
0N/A/**
689N/A * <p>The ModelMBeanNotificationInfo object describes a notification emitted
0N/A * by a ModelMBean.
0N/A * It is a subclass of MBeanNotificationInfo with the addition of an
689N/A * associated Descriptor and an implementation of the Descriptor interface.</p>
689N/A *
689N/A * <P id="descriptor">
689N/A * The fields in the descriptor are defined, but not limited to, the following.
689N/A * Note that when the Type in this table is Number, a String that is the decimal
689N/A * representation of a Long can also be used.</P>
689N/A *
689N/A * <table border="1" cellpadding="5">
689N/A * <tr><th>Name</th><th>Type</th><th>Meaning</th></tr>
689N/A * <tr><td>name</td><td>String</td>
689N/A * <td>Notification name.</td></tr>
689N/A * <tr><td>descriptorType</td><td>String</td>
689N/A * <td>Must be "notification".</td></tr>
689N/A * <tr><td>severity</td><td>Number</td>
689N/A * <td>0-6 where 0: unknown; 1: non-recoverable;
689N/A * 2: critical, failure; 3: major, severe;
689N/A * 4: minor, marginal, error; 5: warning;
689N/A * 6: normal, cleared, informative</td></tr>
689N/A * <tr><td>messageID</td><td>String</td>
689N/A * <td>Unique key for message text (to allow translation, analysis).</td></tr>
689N/A * <tr><td>messageText</td><td>String</td>
689N/A * <td>Text of notification.</td></tr>
689N/A * <tr><td>log</td><td>String</td>
689N/A * <td>T - log message, F - do not log message.</td></tr>
689N/A * <tr><td>logfile</td><td>String</td>
689N/A * <td>fully qualified file name appropriate for operating system.</td></tr>
689N/A * <tr><td>visibility</td><td>Number</td>
689N/A * <td>1-4 where 1: always visible 4: rarely visible.</td></tr>
689N/A * <tr><td>presentationString</td><td>String</td>
689N/A * <td>XML formatted string to allow presentation of data.</td></tr>
689N/A * </table>
689N/A *
689N/A * <p>The default descriptor contains the name, descriptorType,
0N/A * displayName and severity(=6) fields. The default value of the name
0N/A * and displayName fields is the name of the Notification class (as
0N/A * specified by the <code>name</code> parameter of the
689N/A * ModelMBeanNotificationInfo constructor).</p>
0N/A *
0N/A * <p>The <b>serialVersionUID</b> of this class is <code>-7445681389570207141L</code>.
0N/A *
0N/A * @since 1.5
0N/A */
0N/A
0N/A@SuppressWarnings("serial") // serialVersionUID is not constant
0N/Apublic class ModelMBeanNotificationInfo
0N/A extends MBeanNotificationInfo
0N/A implements DescriptorAccess {
0N/A
0N/A // Serialization compatibility stuff:
0N/A // Two serial forms are supported in this class. The selected form
0N/A // depends on system property "jmx.serial.form":
0N/A // - "1.0" for JMX 1.0
0N/A // - any other value for JMX 1.1 and higher
0N/A //
0N/A // Serial version for old serial form
0N/A private static final long oldSerialVersionUID = -5211564525059047097L;
0N/A //
0N/A // Serial version for new serial form
0N/A private static final long newSerialVersionUID = -7445681389570207141L;
0N/A //
0N/A // Serializable fields in old serial form
0N/A private static final ObjectStreamField[] oldSerialPersistentFields =
0N/A {
0N/A new ObjectStreamField("notificationDescriptor", Descriptor.class),
0N/A new ObjectStreamField("currClass", String.class)
0N/A };
0N/A //
0N/A // Serializable fields in new serial form
0N/A private static final ObjectStreamField[] newSerialPersistentFields =
0N/A {
0N/A new ObjectStreamField("notificationDescriptor", Descriptor.class)
0N/A };
0N/A //
0N/A // Actual serial version and serial form
0N/A private static final long serialVersionUID;
0N/A /**
0N/A * @serialField notificationDescriptor Descriptor The descriptor
0N/A * containing the appropriate metadata for this instance
0N/A */
0N/A private static final ObjectStreamField[] serialPersistentFields;
0N/A private static boolean compat = false;
0N/A static {
0N/A try {
0N/A GetPropertyAction act = new GetPropertyAction("jmx.serial.form");
0N/A String form = AccessController.doPrivileged(act);
0N/A compat = (form != null && form.equals("1.0"));
0N/A } catch (Exception e) {
0N/A // OK: No compat with 1.0
0N/A }
0N/A if (compat) {
0N/A serialPersistentFields = oldSerialPersistentFields;
0N/A serialVersionUID = oldSerialVersionUID;
0N/A } else {
0N/A serialPersistentFields = newSerialPersistentFields;
0N/A serialVersionUID = newSerialVersionUID;
0N/A }
0N/A }
0N/A //
0N/A // END Serialization compatibility stuff
0N/A
0N/A /**
0N/A * @serial The descriptor containing the appropriate metadata for
0N/A * this instance
0N/A */
0N/A private Descriptor notificationDescriptor;
0N/A
0N/A private static final String currClass = "ModelMBeanNotificationInfo";
0N/A
0N/A /**
0N/A * Constructs a ModelMBeanNotificationInfo object with a default
0N/A * descriptor.
0N/A *
0N/A * @param notifTypes The array of strings (in dot notation) containing
0N/A * the notification types that may be emitted.
0N/A * @param name The name of the Notification class.
0N/A * @param description A human readable description of the
0N/A * Notification. Optional.
0N/A **/
0N/A public ModelMBeanNotificationInfo(String[] notifTypes,
0N/A String name,
0N/A String description) {
0N/A this(notifTypes,name,description,null);
0N/A }
0N/A
0N/A /**
0N/A * Constructs a ModelMBeanNotificationInfo object.
0N/A *
0N/A * @param notifTypes The array of strings (in dot notation)
0N/A * containing the notification types that may be emitted.
0N/A * @param name The name of the Notification class.
0N/A * @param description A human readable description of the Notification.
0N/A * Optional.
0N/A * @param descriptor An instance of Descriptor containing the
0N/A * appropriate metadata for this instance of the
0N/A * MBeanNotificationInfo. If it is null a default descriptor
1790N/A * will be created. If the descriptor does not contain the
1790N/A * fields "displayName" or "severity",
0N/A * the missing ones are added with their default values.
0N/A *
0N/A * @exception RuntimeOperationsException Wraps an
0N/A * {@link IllegalArgumentException}. The descriptor is invalid, or
1790N/A * descriptor field "name" is not equal to parameter name, or
1790N/A * descriptor field "descriptorType" is not equal to "notification".
0N/A *
0N/A **/
0N/A public ModelMBeanNotificationInfo(String[] notifTypes,
0N/A String name,
0N/A String description,
0N/A Descriptor descriptor) {
0N/A super(notifTypes, name, description);
0N/A if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
0N/A MODELMBEAN_LOGGER.logp(Level.FINER,
0N/A ModelMBeanNotificationInfo.class.getName(),
0N/A "ModelMBeanNotificationInfo", "Entry");
0N/A }
0N/A notificationDescriptor = validDescriptor(descriptor);
0N/A }
0N/A
0N/A /**
0N/A * Constructs a new ModelMBeanNotificationInfo object from this
0N/A * ModelMBeanNotfication Object.
0N/A *
0N/A * @param inInfo the ModelMBeanNotificationInfo to be duplicated
0N/A *
0N/A **/
0N/A public ModelMBeanNotificationInfo(ModelMBeanNotificationInfo inInfo) {
0N/A this(inInfo.getNotifTypes(),
0N/A inInfo.getName(),
0N/A inInfo.getDescription(),inInfo.getDescriptor());
0N/A }
0N/A
0N/A /**
0N/A * Creates and returns a new ModelMBeanNotificationInfo which is a
0N/A * duplicate of this ModelMBeanNotificationInfo.
0N/A **/
0N/A public Object clone () {
0N/A if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
0N/A MODELMBEAN_LOGGER.logp(Level.FINER,
0N/A ModelMBeanNotificationInfo.class.getName(),
0N/A "clone()", "Entry");
0N/A }
0N/A return(new ModelMBeanNotificationInfo(this));
0N/A }
0N/A
0N/A /**
0N/A * Returns a copy of the associated Descriptor for the
0N/A * ModelMBeanNotificationInfo.
0N/A *
0N/A * @return Descriptor associated with the
0N/A * ModelMBeanNotificationInfo object.
0N/A *
0N/A * @see #setDescriptor
0N/A **/
0N/A public Descriptor getDescriptor() {
0N/A if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
0N/A MODELMBEAN_LOGGER.logp(Level.FINER,
0N/A ModelMBeanNotificationInfo.class.getName(),
0N/A "getDescriptor()", "Entry");
0N/A }
0N/A
0N/A if (notificationDescriptor == null) {
0N/A // Dead code. Should never happen.
0N/A if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
0N/A MODELMBEAN_LOGGER.logp(Level.FINER,
0N/A ModelMBeanNotificationInfo.class.getName(),
0N/A "getDescriptor()", "Descriptor value is null, " +
0N/A "setting descriptor to default values");
0N/A }
0N/A notificationDescriptor = validDescriptor(null);
0N/A }
0N/A
0N/A return((Descriptor)notificationDescriptor.clone());
0N/A }
0N/A
0N/A /**
0N/A * Sets associated Descriptor (full replace) for the
0N/A * ModelMBeanNotificationInfo If the new Descriptor is null,
0N/A * then the associated Descriptor reverts to a default
0N/A * descriptor. The Descriptor is validated before it is
0N/A * assigned. If the new Descriptor is invalid, then a
0N/A * RuntimeOperationsException wrapping an
0N/A * IllegalArgumentException is thrown.
0N/A *
0N/A * @param inDescriptor replaces the Descriptor associated with the
0N/A * ModelMBeanNotification interface
0N/A *
0N/A * @exception RuntimeOperationsException Wraps an
0N/A * {@link IllegalArgumentException} for invalid Descriptor.
0N/A *
0N/A * @see #getDescriptor
0N/A **/
0N/A public void setDescriptor(Descriptor inDescriptor) {
0N/A if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
0N/A MODELMBEAN_LOGGER.logp(Level.FINER,
0N/A ModelMBeanNotificationInfo.class.getName(),
0N/A "setDescriptor(Descriptor)", "Entry");
0N/A }
0N/A notificationDescriptor = validDescriptor(inDescriptor);
0N/A }
0N/A
0N/A /**
0N/A * Returns a human readable string containing
0N/A * ModelMBeanNotificationInfo.
0N/A *
0N/A * @return a string describing this object.
0N/A **/
0N/A public String toString() {
0N/A if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
0N/A MODELMBEAN_LOGGER.logp(Level.FINER,
0N/A ModelMBeanNotificationInfo.class.getName(),
0N/A "toString()", "Entry");
0N/A }
0N/A
0N/A final StringBuilder retStr = new StringBuilder();
0N/A
0N/A retStr.append("ModelMBeanNotificationInfo: ")
0N/A .append(this.getName());
0N/A
0N/A retStr.append(" ; Description: ")
0N/A .append(this.getDescription());
0N/A
0N/A retStr.append(" ; Descriptor: ")
0N/A .append(this.getDescriptor());
0N/A
0N/A retStr.append(" ; Types: ");
0N/A String[] nTypes = this.getNotifTypes();
0N/A for (int i=0; i < nTypes.length; i++) {
0N/A if (i > 0) retStr.append(", ");
0N/A retStr.append(nTypes[i]);
0N/A }
0N/A return retStr.toString();
0N/A }
0N/A
0N/A
0N/A /**
0N/A * Clones the passed in Descriptor, sets default values, and checks for validity.
0N/A * If the Descriptor is invalid (for instance by having the wrong "name"),
0N/A * this indicates programming error and a RuntimeOperationsException will be thrown.
0N/A *
0N/A * The following fields will be defaulted if they are not already set:
0N/A * descriptorType="notification",displayName=this.getName(),
0N/A * name=this.getName(),severity="6"
0N/A *
0N/A *
0N/A * @param in Descriptor to be checked, or null which is equivalent to an
0N/A * empty Descriptor.
0N/A * @exception RuntimeOperationsException if Descriptor is invalid
0N/A */
0N/A private Descriptor validDescriptor(final Descriptor in) throws RuntimeOperationsException {
277N/A Descriptor clone;
1790N/A boolean defaulted = (in == null);
1790N/A if (defaulted) {
0N/A clone = new DescriptorSupport();
0N/A MODELMBEAN_LOGGER.finer("Null Descriptor, creating new.");
0N/A } else {
0N/A clone = (Descriptor) in.clone();
0N/A }
0N/A
0N/A //Setting defaults.
1790N/A if (defaulted && clone.getFieldValue("name")==null) {
0N/A clone.setField("name", this.getName());
0N/A MODELMBEAN_LOGGER.finer("Defaulting Descriptor name to " + this.getName());
0N/A }
1790N/A if (defaulted && clone.getFieldValue("descriptorType")==null) {
0N/A clone.setField("descriptorType", "notification");
0N/A MODELMBEAN_LOGGER.finer("Defaulting descriptorType to \"notification\"");
0N/A }
0N/A if (clone.getFieldValue("displayName") == null) {
0N/A clone.setField("displayName",this.getName());
0N/A MODELMBEAN_LOGGER.finer("Defaulting Descriptor displayName to " + this.getName());
0N/A }
0N/A if (clone.getFieldValue("severity") == null) {
0N/A clone.setField("severity", "6");
0N/A MODELMBEAN_LOGGER.finer("Defaulting Descriptor severity field to 6");
0N/A }
0N/A
0N/A //Checking validity
0N/A if (!clone.isValid()) {
0N/A throw new RuntimeOperationsException(new IllegalArgumentException("Invalid Descriptor argument"),
0N/A "The isValid() method of the Descriptor object itself returned false,"+
0N/A "one or more required fields are invalid. Descriptor:" + clone.toString());
0N/A }
1790N/A if (!getName().equalsIgnoreCase((String) clone.getFieldValue("name"))) {
0N/A throw new RuntimeOperationsException(new IllegalArgumentException("Invalid Descriptor argument"),
0N/A "The Descriptor \"name\" field does not match the object described. " +
0N/A " Expected: "+ this.getName() + " , was: " + clone.getFieldValue("name"));
0N/A }
1790N/A if (!"notification".equalsIgnoreCase((String) clone.getFieldValue("descriptorType"))) {
0N/A throw new RuntimeOperationsException(new IllegalArgumentException("Invalid Descriptor argument"),
0N/A "The Descriptor \"descriptorType\" field does not match the object described. " +
0N/A " Expected: \"notification\" ," + " was: " + clone.getFieldValue("descriptorType"));
0N/A }
0N/A
0N/A return clone;
0N/A }
0N/A
0N/A
0N/A /**
0N/A * Deserializes a {@link ModelMBeanNotificationInfo} from an
0N/A * {@link ObjectInputStream}.
0N/A **/
0N/A private void readObject(ObjectInputStream in)
0N/A throws IOException, ClassNotFoundException {
0N/A // New serial form ignores extra field "currClass"
0N/A in.defaultReadObject();
0N/A }
0N/A
0N/A
0N/A /**
0N/A * Serializes a {@link ModelMBeanNotificationInfo} to an
0N/A * {@link ObjectOutputStream}.
0N/A **/
0N/A private void writeObject(ObjectOutputStream out)
0N/A throws IOException {
0N/A if (compat) {
0N/A // Serializes this instance in the old serial form
0N/A //
0N/A ObjectOutputStream.PutField fields = out.putFields();
0N/A fields.put("notificationDescriptor", notificationDescriptor);
0N/A fields.put("currClass", currClass);
0N/A out.writeFields();
0N/A } else {
0N/A // Serializes this instance in the new serial form
0N/A //
0N/A out.defaultWriteObject();
0N/A }
0N/A }
0N/A
0N/A}