001/* MBeanOperationInfo.java -- Information about a bean's operations. 002 Copyright (C) 2006 Free Software Foundation, Inc. 003 004This file is part of GNU Classpath. 005 006GNU Classpath is free software; you can redistribute it and/or modify 007it under the terms of the GNU General Public License as published by 008the Free Software Foundation; either version 2, or (at your option) 009any later version. 010 011GNU Classpath is distributed in the hope that it will be useful, but 012WITHOUT ANY WARRANTY; without even the implied warranty of 013MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 014General Public License for more details. 015 016You should have received a copy of the GNU General Public License 017along with GNU Classpath; see the file COPYING. If not, write to the 018Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 01902110-1301 USA. 020 021Linking this library statically or dynamically with other modules is 022making a combined work based on this library. Thus, the terms and 023conditions of the GNU General Public License cover the whole 024combination. 025 026As a special exception, the copyright holders of this library give you 027permission to link this library with independent modules to produce an 028executable, regardless of the license terms of these independent 029modules, and to copy and distribute the resulting executable under 030terms of your choice, provided that you also meet, for each linked 031independent module, the terms and conditions of the license of that 032module. An independent module is a module which is not derived from 033or based on this library. If you modify this library, you may extend 034this exception to your version of the library, but you are not 035obligated to do so. If you do not wish to do so, delete this 036exception statement from your version. */ 037 038package javax.management; 039 040import java.lang.reflect.Method; 041import java.lang.reflect.Type; 042 043import java.util.Arrays; 044 045/** 046 * Describes the operations of a management bean. 047 * The information in this class is immutable as standard. 048 * Of course, subclasses may change this, but this 049 * behaviour is not recommended. 050 * 051 * @author Andrew John Hughes (gnu_andrew@member.fsf.org) 052 * @since 1.5 053 */ 054public class MBeanOperationInfo 055 extends MBeanFeatureInfo 056 implements Cloneable 057{ 058 059 /** 060 * Compatible with JDK 1.5 061 */ 062 private static final long serialVersionUID = -6178860474881375330L; 063 064 /** 065 * Used to signify that the operation merely provides information 066 * (akin to an accessor). 067 */ 068 public static final int INFO = 0; 069 070 /** 071 * Used to signify that the operation makes some change to the 072 * state of the bean (akin to a mutator). 073 */ 074 public static final int ACTION = 1; 075 076 /** 077 * Used to signify that the operation makes some state change 078 * to the bean and also returns information. 079 */ 080 public static final int ACTION_INFO = 2; 081 082 /** 083 * Used to signify that the behaviour of the operation is 084 * unknown. 085 */ 086 public static final int UNKNOWN = 3; 087 088 /** 089 * The return type of the method, in the form of its class name. 090 */ 091 private String type; 092 093 /** 094 * The signature of the constructor i.e. the argument types. 095 */ 096 private MBeanParameterInfo[] signature; 097 098 /** 099 * The impact of the method, as one of {@link #INFO}, {@link #ACTION}, 100 * {@link #ACTION_INFO} and {@link #UNKNOWN}. 101 */ 102 private int impact; 103 104 /** 105 * Constructs a @link{MBeanOperationInfo} with the specified 106 * description using the given method. Each parameter is 107 * described merely by its type; the name and description are 108 * <code>null</code>. The return type and impact of the 109 * method are determined from the {@link Method} instance. 110 * 111 * @param desc a description of the attribute. 112 * @param method the method. 113 */ 114 public MBeanOperationInfo(String desc, Method method) 115 { 116 super(method.getName(), desc); 117 Type[] paramTypes = method.getGenericParameterTypes(); 118 signature = new MBeanParameterInfo[paramTypes.length]; 119 for (int a = 0; a < paramTypes.length; ++a) 120 { 121 Type t = paramTypes[a]; 122 if (t instanceof Class) 123 signature[a] = new MBeanParameterInfo(null, 124 ((Class<?>) t).getName(), 125 null); 126 else 127 signature[a] = new MBeanParameterInfo(null, t.toString(), null); 128 } 129 Type retType = method.getGenericReturnType(); 130 if (retType instanceof Class) 131 type = ((Class<?>) retType).getName(); 132 else 133 type = retType.toString(); 134 if (method.getReturnType() == Void.TYPE) 135 { 136 if (paramTypes.length == 0) 137 impact = UNKNOWN; 138 else 139 impact = ACTION; 140 } 141 else 142 { 143 if (paramTypes.length == 0) 144 impact = INFO; 145 else 146 impact = ACTION_INFO; 147 } 148 } 149 150 /** 151 * Constructs a @link{MBeanOperationInfo} with the specified name, 152 * description, parameter information, return type and impact. A 153 * <code>null</code> value for the parameter information is the same 154 * as passing in an empty array. A copy of the parameter array is 155 * taken, so later changes have no effect. 156 * 157 * @param name the name of the constructor. 158 * @param desc a description of the attribute. 159 * @param sig the signature of the method, as a series 160 * of {@link MBeanParameterInfo} objects, one for 161 * each parameter. 162 * @param type the return type of the method, as the class name. 163 * @param impact the impact of performing the operation. 164 */ 165 public MBeanOperationInfo(String name, String desc, 166 MBeanParameterInfo[] sig, String type, 167 int impact) 168 { 169 super(name, desc); 170 if (sig == null) 171 signature = new MBeanParameterInfo[0]; 172 else 173 { 174 signature = new MBeanParameterInfo[sig.length]; 175 System.arraycopy(sig, 0, signature, 0, sig.length); 176 } 177 this.type = type; 178 this.impact = impact; 179 } 180 181 /** 182 * Returns a clone of this instance. The clone is created 183 * using just the method provided by {@link java.lang.Object}. 184 * Thus, the clone is just a shallow clone as returned by 185 * that method, and does not contain any deeper cloning based 186 * on the subject of this class. 187 * 188 * @return a clone of this instance. 189 * @see java.lang.Cloneable 190 */ 191 public Object clone() 192 { 193 try 194 { 195 return super.clone(); 196 } 197 catch (CloneNotSupportedException e) 198 { 199 /* This shouldn't happen; we implement Cloneable */ 200 throw new IllegalStateException("clone() called on " + 201 "non-cloneable object."); 202 } 203 } 204 205 /** 206 * Compares this feature with the supplied object. This returns 207 * true iff the object is an instance of {@link 208 * MBeanConstructorInfo}, {@link Object#equals()} returns true for a 209 * comparison of both the name and description of this notification 210 * with that of the specified object (performed by the superclass), 211 * the return type and impact are equal and the two signature arrays 212 * contain the same elements in the same order (but one may be 213 * longer than the other). 214 * 215 * @param obj the object to compare. 216 * @return true if the object is a {@link MBeanOperationInfo} 217 * instance, 218 * <code>name.equals(object.getName())</code>, 219 * <code>description.equals(object.getDescription())</code>, 220 * <code>type.equals(object.getReturnType())</code>, 221 * <code>impact == object.getImpact()</code>, 222 * and the corresponding elements of the signature arrays are 223 * equal. 224 */ 225 public boolean equals(Object obj) 226 { 227 if (!(obj instanceof MBeanOperationInfo)) 228 return false; 229 if (!(super.equals(obj))) 230 return false; 231 MBeanOperationInfo o = (MBeanOperationInfo) obj; 232 MBeanParameterInfo[] sig = o.getSignature(); 233 for (int a = 0; a < signature.length; ++a) 234 { 235 if (a == sig.length) 236 return true; 237 if (!(signature[a].equals(sig[a]))) 238 return false; 239 } 240 return (type.equals(o.getReturnType()) && 241 impact == o.getImpact()); 242 } 243 244 /** 245 * <p> 246 * Returns the impact of performing this operation. 247 * The value is equal to one of the following: 248 * </p> 249 * <ol> 250 * <li>{@link #INFO} — the method just returns 251 * information (akin to an accessor).</li> 252 * <li>{@link #ACTION} — the method just alters 253 * the state of the bean, without returning a value 254 * (akin to a mutator).</li> 255 * <li>{@link #ACTION_INFO} — the method both makes 256 * state changes and returns a value.</li> 257 * <li>{@link #UNKNOWN} — the behaviour of the operation 258 * is unknown.</li> 259 * </ol> 260 * 261 * @return the impact of performing the operation. 262 */ 263 public int getImpact() 264 { 265 return impact; 266 } 267 268 /** 269 * Returns the return type of the operation, as the class 270 * name. 271 * 272 * @return the return type. 273 */ 274 public String getReturnType() 275 { 276 return type; 277 } 278 279 /** 280 * Returns the operation's signature, in the form of 281 * information on each parameter. Each parameter is 282 * described by an instance of {@link MBeanParameterInfo}. 283 * The returned array is a shallow copy of the array used 284 * by this instance, so changing which elements are stored 285 * in the array won't affect the array used by this, but 286 * changing the actual elements will affect the ones used 287 * here. 288 * 289 * @return an array of {@link MBeanParameterInfo} objects, 290 * describing the operation parameters. 291 */ 292 public MBeanParameterInfo[] getSignature() 293 { 294 return (MBeanParameterInfo[]) signature.clone(); 295 } 296 297 /** 298 * Returns the hashcode of the operation information as the sum of 299 * the hashcode of the superclass, the parameter array, the return 300 * type and the impact factor. 301 * 302 * @return the hashcode of the operation information. 303 */ 304 public int hashCode() 305 { 306 return super.hashCode() + Arrays.hashCode(signature) 307 + type.hashCode() + Integer.valueOf(impact).hashCode(); 308 } 309 310 /** 311 * <p> 312 * Returns a textual representation of this instance. This 313 * is constructed using the class name 314 * (<code>javax.management.MBeanOperationInfo</code>), 315 * the name, description, return type and impact of the 316 * operation and the contents of the array of parameters. 317 * </p> 318 * <p> 319 * As instances of this class are immutable, the return value 320 * is computed just once for each instance and reused 321 * throughout its life. 322 * </p> 323 * 324 * @return a @link{java.lang.String} instance representing 325 * the instance in textual form. 326 */ 327 public String toString() 328 { 329 if (string == null) 330 { 331 String impactString; 332 switch (impact) 333 { 334 case INFO: 335 impactString = "INFO"; 336 break; 337 case ACTION: 338 impactString = "ACTION"; 339 break; 340 case ACTION_INFO: 341 impactString = "ACTION_INFO"; 342 break; 343 case UNKNOWN: 344 impactString = "UNKNOWN"; 345 break; 346 default: 347 impactString = "ERRONEOUS VALUE"; 348 } 349 super.toString(); 350 string = string.substring(0, string.length() - 1) 351 + ",returnType=" + type 352 + ",impact=" + impactString 353 + ",signature=" + Arrays.toString(signature) 354 + "]"; 355 } 356 return string; 357 } 358 359}