jdk/src/share/classes/javax/management/MBeanOperationInfo.java
changeset 2 90ce3da70b43
child 833 bfa2bef7517c
equal deleted inserted replaced
0:fd16c54261b3 2:90ce3da70b43
       
     1 /*
       
     2  * Copyright 1999-2006 Sun Microsystems, Inc.  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.  Sun designates this
       
     8  * particular file as subject to the "Classpath" exception as provided
       
     9  * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
       
    22  * CA 95054 USA or visit www.sun.com if you need additional information or
       
    23  * have any questions.
       
    24  */
       
    25 
       
    26 package javax.management;
       
    27 
       
    28 import com.sun.jmx.mbeanserver.Introspector;
       
    29 import java.lang.annotation.Annotation;
       
    30 import java.lang.reflect.Method;
       
    31 import java.util.Arrays;
       
    32 
       
    33 /**
       
    34  * Describes a management operation exposed by an MBean.  Instances of
       
    35  * this class are immutable.  Subclasses may be mutable but this is
       
    36  * not recommended.
       
    37  *
       
    38  * @since 1.5
       
    39  */
       
    40 public class MBeanOperationInfo extends MBeanFeatureInfo implements Cloneable {
       
    41 
       
    42     /* Serial version */
       
    43     static final long serialVersionUID = -6178860474881375330L;
       
    44 
       
    45     static final MBeanOperationInfo[] NO_OPERATIONS =
       
    46         new MBeanOperationInfo[0];
       
    47 
       
    48     /**
       
    49      * Indicates that the operation is read-like,
       
    50      * it basically returns information.
       
    51      */
       
    52     public static final int INFO = 0;
       
    53 
       
    54     /**
       
    55      * Indicates that the operation is a write-like,
       
    56      * and would modify the MBean in some way, typically by writing some value
       
    57      * or changing a configuration.
       
    58      */
       
    59     public static final int ACTION = 1;
       
    60 
       
    61     /**
       
    62      * Indicates that the operation is both read-like and write-like.
       
    63      */
       
    64     public static final int ACTION_INFO = 2;
       
    65 
       
    66     /**
       
    67      * Indicates that the operation has an "unknown" nature.
       
    68      */
       
    69     public static final int UNKNOWN = 3;
       
    70 
       
    71     /**
       
    72      * @serial The method's return value.
       
    73      */
       
    74     private final String type;
       
    75 
       
    76     /**
       
    77      * @serial The signature of the method, that is, the class names
       
    78      * of the arguments.
       
    79      */
       
    80     private final MBeanParameterInfo[] signature;
       
    81 
       
    82     /**
       
    83      * @serial The impact of the method, one of
       
    84      *         <CODE>INFO</CODE>,
       
    85      *         <CODE>ACTION</CODE>,
       
    86      *         <CODE>ACTION_INFO</CODE>,
       
    87      *         <CODE>UNKNOWN</CODE>
       
    88      */
       
    89     private final int impact;
       
    90 
       
    91     /** @see MBeanInfo#arrayGettersSafe */
       
    92     private final transient boolean arrayGettersSafe;
       
    93 
       
    94 
       
    95     /**
       
    96      * Constructs an <CODE>MBeanOperationInfo</CODE> object.  The
       
    97      * {@link Descriptor} of the constructed object will include
       
    98      * fields contributed by any annotations on the {@code Method}
       
    99      * object that contain the {@link DescriptorKey} meta-annotation.
       
   100      *
       
   101      * @param method The <CODE>java.lang.reflect.Method</CODE> object
       
   102      * describing the MBean operation.
       
   103      * @param description A human readable description of the operation.
       
   104      */
       
   105     public MBeanOperationInfo(String description, Method method) {
       
   106         this(method.getName(),
       
   107              description,
       
   108              methodSignature(method),
       
   109              method.getReturnType().getName(),
       
   110              UNKNOWN,
       
   111              Introspector.descriptorForElement(method));
       
   112     }
       
   113 
       
   114     /**
       
   115      * Constructs an <CODE>MBeanOperationInfo</CODE> object.
       
   116      *
       
   117      * @param name The name of the method.
       
   118      * @param description A human readable description of the operation.
       
   119      * @param signature <CODE>MBeanParameterInfo</CODE> objects
       
   120      * describing the parameters(arguments) of the method.  This may be
       
   121      * null with the same effect as a zero-length array.
       
   122      * @param type The type of the method's return value.
       
   123      * @param impact The impact of the method, one of <CODE>INFO,
       
   124      * ACTION, ACTION_INFO, UNKNOWN</CODE>.
       
   125      */
       
   126     public MBeanOperationInfo(String name,
       
   127                               String description,
       
   128                               MBeanParameterInfo[] signature,
       
   129                               String type,
       
   130                               int impact) {
       
   131         this(name, description, signature, type, impact, (Descriptor) null);
       
   132     }
       
   133 
       
   134     /**
       
   135      * Constructs an <CODE>MBeanOperationInfo</CODE> object.
       
   136      *
       
   137      * @param name The name of the method.
       
   138      * @param description A human readable description of the operation.
       
   139      * @param signature <CODE>MBeanParameterInfo</CODE> objects
       
   140      * describing the parameters(arguments) of the method.  This may be
       
   141      * null with the same effect as a zero-length array.
       
   142      * @param type The type of the method's return value.
       
   143      * @param impact The impact of the method, one of <CODE>INFO,
       
   144      * ACTION, ACTION_INFO, UNKNOWN</CODE>.
       
   145      * @param descriptor The descriptor for the operation.  This may be null
       
   146      * which is equivalent to an empty descriptor.
       
   147      *
       
   148      * @since 1.6
       
   149      */
       
   150     public MBeanOperationInfo(String name,
       
   151                               String description,
       
   152                               MBeanParameterInfo[] signature,
       
   153                               String type,
       
   154                               int impact,
       
   155                               Descriptor descriptor) {
       
   156 
       
   157         super(name, description, descriptor);
       
   158 
       
   159         if (signature == null || signature.length == 0)
       
   160             signature = MBeanParameterInfo.NO_PARAMS;
       
   161         else
       
   162             signature = signature.clone();
       
   163         this.signature = signature;
       
   164         this.type = type;
       
   165         this.impact = impact;
       
   166         this.arrayGettersSafe =
       
   167             MBeanInfo.arrayGettersSafe(this.getClass(),
       
   168                                        MBeanOperationInfo.class);
       
   169     }
       
   170 
       
   171     /**
       
   172      * <p>Returns a shallow clone of this instance.
       
   173      * The clone is obtained by simply calling <tt>super.clone()</tt>,
       
   174      * thus calling the default native shallow cloning mechanism
       
   175      * implemented by <tt>Object.clone()</tt>.
       
   176      * No deeper cloning of any internal field is made.</p>
       
   177      *
       
   178      * <p>Since this class is immutable, cloning is chiefly of interest
       
   179      * to subclasses.</p>
       
   180      */
       
   181      public Object clone () {
       
   182          try {
       
   183              return super.clone() ;
       
   184          } catch (CloneNotSupportedException e) {
       
   185              // should not happen as this class is cloneable
       
   186              return null;
       
   187          }
       
   188      }
       
   189 
       
   190     /**
       
   191      * Returns the type of the method's return value.
       
   192      *
       
   193      * @return the return type.
       
   194      */
       
   195     public String getReturnType() {
       
   196         return type;
       
   197     }
       
   198 
       
   199     /**
       
   200      * <p>Returns the list of parameters for this operation.  Each
       
   201      * parameter is described by an <CODE>MBeanParameterInfo</CODE>
       
   202      * object.</p>
       
   203      *
       
   204      * <p>The returned array is a shallow copy of the internal array,
       
   205      * which means that it is a copy of the internal array of
       
   206      * references to the <CODE>MBeanParameterInfo</CODE> objects but
       
   207      * that each referenced <CODE>MBeanParameterInfo</CODE> object is
       
   208      * not copied.</p>
       
   209      *
       
   210      * @return  An array of <CODE>MBeanParameterInfo</CODE> objects.
       
   211      */
       
   212     public MBeanParameterInfo[] getSignature() {
       
   213         // If MBeanOperationInfo was created in our implementation,
       
   214         // signature cannot be null - because our constructors replace
       
   215         // null with MBeanParameterInfo.NO_PARAMS;
       
   216         //
       
   217         // However, signature could be null if an  MBeanOperationInfo is
       
   218         // deserialized from a byte array produced by another implementation.
       
   219         // This is not very likely but possible, since the serial form says
       
   220         // nothing against it. (see 6373150)
       
   221         //
       
   222         if (signature == null)
       
   223             // if signature is null simply return an empty array .
       
   224             //
       
   225             return MBeanParameterInfo.NO_PARAMS;
       
   226         else if (signature.length == 0)
       
   227             return signature;
       
   228         else
       
   229             return signature.clone();
       
   230     }
       
   231 
       
   232     private MBeanParameterInfo[] fastGetSignature() {
       
   233         if (arrayGettersSafe) {
       
   234             // if signature is null simply return an empty array .
       
   235             // see getSignature() above.
       
   236             //
       
   237             if (signature == null)
       
   238                 return MBeanParameterInfo.NO_PARAMS;
       
   239             else return signature;
       
   240         } else return getSignature();
       
   241     }
       
   242 
       
   243     /**
       
   244      * Returns the impact of the method, one of
       
   245      * <CODE>INFO</CODE>, <CODE>ACTION</CODE>, <CODE>ACTION_INFO</CODE>, <CODE>UNKNOWN</CODE>.
       
   246      *
       
   247      * @return the impact code.
       
   248      */
       
   249     public int getImpact() {
       
   250         return impact;
       
   251     }
       
   252 
       
   253     public String toString() {
       
   254         String impactString;
       
   255         switch (getImpact()) {
       
   256         case ACTION: impactString = "action"; break;
       
   257         case ACTION_INFO: impactString = "action/info"; break;
       
   258         case INFO: impactString = "info"; break;
       
   259         case UNKNOWN: impactString = "unknown"; break;
       
   260         default: impactString = "(" + getImpact() + ")";
       
   261         }
       
   262         return getClass().getName() + "[" +
       
   263             "description=" + getDescription() + ", " +
       
   264             "name=" + getName() + ", " +
       
   265             "returnType=" + getReturnType() + ", " +
       
   266             "signature=" + Arrays.asList(fastGetSignature()) + ", " +
       
   267             "impact=" + impactString + ", " +
       
   268             "descriptor=" + getDescriptor() +
       
   269             "]";
       
   270     }
       
   271 
       
   272     /**
       
   273      * Compare this MBeanOperationInfo to another.
       
   274      *
       
   275      * @param o the object to compare to.
       
   276      *
       
   277      * @return true if and only if <code>o</code> is an MBeanOperationInfo such
       
   278      * that its {@link #getName()}, {@link #getReturnType()}, {@link
       
   279      * #getDescription()}, {@link #getImpact()}, {@link #getDescriptor()}
       
   280      * and {@link #getSignature()} values are equal (not necessarily identical)
       
   281      * to those of this MBeanConstructorInfo.  Two signature arrays
       
   282      * are equal if their elements are pairwise equal.
       
   283      */
       
   284     public boolean equals(Object o) {
       
   285         if (o == this)
       
   286             return true;
       
   287         if (!(o instanceof MBeanOperationInfo))
       
   288             return false;
       
   289         MBeanOperationInfo p = (MBeanOperationInfo) o;
       
   290         return (p.getName().equals(getName()) &&
       
   291                 p.getReturnType().equals(getReturnType()) &&
       
   292                 p.getDescription().equals(getDescription()) &&
       
   293                 p.getImpact() == getImpact() &&
       
   294                 Arrays.equals(p.fastGetSignature(), fastGetSignature()) &&
       
   295                 p.getDescriptor().equals(getDescriptor()));
       
   296     }
       
   297 
       
   298     /* We do not include everything in the hashcode.  We assume that
       
   299        if two operations are different they'll probably have different
       
   300        names or types.  The penalty we pay when this assumption is
       
   301        wrong should be less than the penalty we would pay if it were
       
   302        right and we needlessly hashed in the description and the
       
   303        parameter array.  */
       
   304     public int hashCode() {
       
   305         return getName().hashCode() ^ getReturnType().hashCode();
       
   306     }
       
   307 
       
   308     private static MBeanParameterInfo[] methodSignature(Method method) {
       
   309         final Class[] classes = method.getParameterTypes();
       
   310         final Annotation[][] annots = method.getParameterAnnotations();
       
   311         return parameters(classes, annots);
       
   312     }
       
   313 
       
   314     static MBeanParameterInfo[] parameters(Class[] classes,
       
   315                                            Annotation[][] annots) {
       
   316         final MBeanParameterInfo[] params =
       
   317             new MBeanParameterInfo[classes.length];
       
   318         assert(classes.length == annots.length);
       
   319 
       
   320         for (int i = 0; i < classes.length; i++) {
       
   321             Descriptor d = Introspector.descriptorForAnnotations(annots[i]);
       
   322             final String pn = "p" + (i + 1);
       
   323             params[i] =
       
   324                 new MBeanParameterInfo(pn, classes[i].getName(), "", d);
       
   325         }
       
   326 
       
   327         return params;
       
   328     }
       
   329 }