1 /*
   2  * Copyright (c) 1999, 2006, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package javax.management;
  27 
  28 import java.util.Arrays;
  29 
  30 /**
  31  * <p>The <CODE>MBeanNotificationInfo</CODE> class is used to describe the
  32  * characteristics of the different notification instances
  33  * emitted by an MBean, for a given Java class of notification.
  34  * If an MBean emits notifications that can be instances of different Java classes,
  35  * then the metadata for that MBean should provide an <CODE>MBeanNotificationInfo</CODE>
  36  * object for each of these notification Java classes.</p>
  37  *
  38  * <p>Instances of this class are immutable.  Subclasses may be
  39  * mutable but this is not recommended.</p>
  40  *
  41  * <p>This class extends <CODE>javax.management.MBeanFeatureInfo</CODE>
  42  * and thus provides <CODE>name</CODE> and <CODE>description</CODE> fields.
  43  * The <CODE>name</CODE> field should be the fully qualified Java class name of
  44  * the notification objects described by this class.</p>
  45  *
  46  * <p>The <CODE>getNotifTypes</CODE> method returns an array of
  47  * strings containing the notification types that the MBean may
  48  * emit. The notification type is a dot-notation string which
  49  * describes what the emitted notification is about, not the Java
  50  * class of the notification.  A single generic notification class can
  51  * be used to send notifications of several types.  All of these types
  52  * are returned in the string array result of the
  53  * <CODE>getNotifTypes</CODE> method.
  54  *
  55  * @since 1.5
  56  */
  57 public class MBeanNotificationInfo extends MBeanFeatureInfo implements Cloneable {
  58 
  59     /* Serial version */
  60     static final long serialVersionUID = -3888371564530107064L;
  61 
  62     private static final String[] NO_TYPES = new String[0];
  63 
  64     static final MBeanNotificationInfo[] NO_NOTIFICATIONS =
  65         new MBeanNotificationInfo[0];
  66 
  67     /**
  68      * @serial The different types of the notification.
  69      */
  70     private final String[] types;
  71 
  72     /** @see MBeanInfo#arrayGettersSafe */
  73     private final transient boolean arrayGettersSafe;
  74 
  75     /**
  76      * Constructs an <CODE>MBeanNotificationInfo</CODE> object.
  77      *
  78      * @param notifTypes The array of strings (in dot notation)
  79      * containing the notification types that the MBean may emit.
  80      * This may be null with the same effect as a zero-length array.
  81      * @param name The fully qualified Java class name of the
  82      * described notifications.
  83      * @param description A human readable description of the data.
  84      */
  85     public MBeanNotificationInfo(String[] notifTypes,
  86                                  String name,
  87                                  String description) {
  88         this(notifTypes, name, description, null);
  89     }
  90 
  91     /**
  92      * Constructs an <CODE>MBeanNotificationInfo</CODE> object.
  93      *
  94      * @param notifTypes The array of strings (in dot notation)
  95      * containing the notification types that the MBean may emit.
  96      * This may be null with the same effect as a zero-length array.
  97      * @param name The fully qualified Java class name of the
  98      * described notifications.
  99      * @param description A human readable description of the data.
 100      * @param descriptor The descriptor for the notifications.  This may be null
 101      * which is equivalent to an empty descriptor.
 102      *
 103      * @since 1.6
 104      */
 105     public MBeanNotificationInfo(String[] notifTypes,
 106                                  String name,
 107                                  String description,
 108                                  Descriptor descriptor) {
 109         super(name, description, descriptor);
 110 
 111         /* We do not validate the notifTypes, since the spec just says
 112            they are dot-separated, not that they must look like Java
 113            classes.  E.g. the spec doesn't forbid "sun.prob.25" as a
 114            notifType, though it doesn't explicitly allow it
 115            either.  */
 116 
 117         if (notifTypes == null)
 118             notifTypes = NO_TYPES;
 119         this.types = notifTypes;
 120         this.arrayGettersSafe =
 121             MBeanInfo.arrayGettersSafe(this.getClass(),
 122                                        MBeanNotificationInfo.class);
 123     }
 124 
 125 
 126     /**
 127      * Returns a shallow clone of this instance.
 128      * The clone is obtained by simply calling <tt>super.clone()</tt>,
 129      * thus calling the default native shallow cloning mechanism
 130      * implemented by <tt>Object.clone()</tt>.
 131      * No deeper cloning of any internal field is made.
 132      */
 133      public Object clone () {
 134          try {
 135              return super.clone() ;
 136          } catch (CloneNotSupportedException e) {
 137              // should not happen as this class is cloneable
 138              return null;
 139          }
 140      }
 141 
 142 
 143     /**
 144      * Returns the array of strings (in dot notation) containing the
 145      * notification types that the MBean may emit.
 146      *
 147      * @return the array of strings.  Changing the returned array has no
 148      * effect on this MBeanNotificationInfo.
 149      */
 150     public String[] getNotifTypes() {
 151         if (types.length == 0)
 152             return NO_TYPES;
 153         else
 154             return types.clone();
 155     }
 156 
 157     private String[] fastGetNotifTypes() {
 158         if (arrayGettersSafe)
 159             return types;
 160         else
 161             return getNotifTypes();
 162     }
 163 
 164     public String toString() {
 165         return
 166             getClass().getName() + "[" +
 167             "description=" + getDescription() + ", " +
 168             "name=" + getName() + ", " +
 169             "notifTypes=" + Arrays.asList(fastGetNotifTypes()) + ", " +
 170             "descriptor=" + getDescriptor() +
 171             "]";
 172     }
 173 
 174     /**
 175      * Compare this MBeanNotificationInfo to another.
 176      *
 177      * @param o the object to compare to.
 178      *
 179      * @return true if and only if <code>o</code> is an MBeanNotificationInfo
 180      * such that its {@link #getName()}, {@link #getDescription()},
 181      * {@link #getDescriptor()},
 182      * and {@link #getNotifTypes()} values are equal (not necessarily
 183      * identical) to those of this MBeanNotificationInfo.  Two
 184      * notification type arrays are equal if their corresponding
 185      * elements are equal.  They are not equal if they have the same
 186      * elements but in a different order.
 187      */
 188     public boolean equals(Object o) {
 189         if (o == this)
 190             return true;
 191         if (!(o instanceof MBeanNotificationInfo))
 192             return false;
 193         MBeanNotificationInfo p = (MBeanNotificationInfo) o;
 194         return (p.getName().equals(getName()) &&
 195                 p.getDescription().equals(getDescription()) &&
 196                 p.getDescriptor().equals(getDescriptor()) &&
 197                 Arrays.equals(p.fastGetNotifTypes(), fastGetNotifTypes()));
 198     }
 199 
 200     public int hashCode() {
 201         int hash = getName().hashCode();
 202         for (int i = 0; i < types.length; i++)
 203             hash ^= types[i].hashCode();
 204         return hash;
 205     }
 206 }