001 /* 002 * CDDL HEADER START 003 * 004 * The contents of this file are subject to the terms of the 005 * Common Development and Distribution License, Version 1.0 only 006 * (the "License"). You may not use this file except in compliance 007 * with the License. 008 * 009 * You can obtain a copy of the license at 010 * trunk/opends/resource/legal-notices/OpenDS.LICENSE 011 * or https://OpenDS.dev.java.net/OpenDS.LICENSE. 012 * See the License for the specific language governing permissions 013 * and limitations under the License. 014 * 015 * When distributing Covered Code, include this CDDL HEADER in each 016 * file and include the License file at 017 * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable, 018 * add the following below this CDDL HEADER, with the fields enclosed 019 * by brackets "[]" replaced with your own identifying information: 020 * Portions Copyright [yyyy] [name of copyright owner] 021 * 022 * CDDL HEADER END 023 * 024 * 025 * Copyright 2006-2008 Sun Microsystems, Inc. 026 */ 027 package org.opends.server.types; 028 029 030 031 import javax.management.Attribute; 032 import javax.management.MBeanException; 033 import javax.management.MBeanOperationInfo; 034 import javax.management.MBeanParameterInfo; 035 036 import org.opends.server.api.InvokableComponent; 037 import org.opends.server.config.ConfigAttribute; 038 039 import static org.opends.server.loggers.debug.DebugLogger.*; 040 import org.opends.server.loggers.debug.DebugTracer; 041 042 043 044 /** 045 * This class defines a data structure that holds information about a 046 * method that may be invoked for an invokable component. 047 */ 048 @org.opends.server.types.PublicAPI( 049 stability=org.opends.server.types.StabilityLevel.VOLATILE, 050 mayInstantiate=false, 051 mayExtend=false, 052 mayInvoke=true) 053 public class InvokableMethod 054 { 055 /** 056 * The tracer object for the debug logger. 057 */ 058 private static final DebugTracer TRACER = getTracer(); 059 060 061 062 063 // Indicates whether this method retrieves information about the 064 // associated component. 065 private boolean retrievesComponentInfo; 066 067 // Indicates whether this method updates information about the 068 // associated component. 069 private boolean updatesComponentInfo; 070 071 // The set of arguments for this method. 072 private ConfigAttribute[] arguments; 073 074 // The description for this method. 075 private String description; 076 077 // The name for this method. 078 private String name; 079 080 // The return type for this method. 081 private String returnType; 082 083 084 085 /** 086 * Creates a new invokable method with the provided information. 087 * 088 * @param name The name for this invokable 089 * method. 090 * @param description The description for this 091 * invokable method. 092 * @param arguments The object types for this 093 * method's arguments. 094 * @param returnType The object type for this method's 095 * return value. 096 * @param retrievesComponentInfo Indicates whether this method 097 * retrieves information about the 098 * associated component. 099 * @param updatesComponentInfo Indicates whether this method 100 * updates information about the 101 * associated component. 102 */ 103 public InvokableMethod(String name, String description, 104 ConfigAttribute[] arguments, 105 String returnType, 106 boolean retrievesComponentInfo, 107 boolean updatesComponentInfo) 108 { 109 this.name = name; 110 this.description = description; 111 this.returnType = returnType; 112 this.retrievesComponentInfo = retrievesComponentInfo; 113 this.updatesComponentInfo = updatesComponentInfo; 114 115 if (arguments == null) 116 { 117 this.arguments = new ConfigAttribute[0]; 118 } 119 else 120 { 121 this.arguments = arguments; 122 } 123 } 124 125 126 127 /** 128 * Retrieves the name of this invokable method. 129 * 130 * @return The name of this invokable method. 131 */ 132 public String getName() 133 { 134 return name; 135 } 136 137 138 139 /** 140 * Retrieves a description of this invokable method. 141 * 142 * @return A description of this invokable method. 143 */ 144 public String getDescription() 145 { 146 return description; 147 } 148 149 150 151 /** 152 * Retrieves the set of arguments for this invokable method. 153 * 154 * @return The set of arguments for this invokable method. 155 */ 156 public ConfigAttribute[] getArguments() 157 { 158 return arguments; 159 } 160 161 162 163 /** 164 * Retrieves the return type for this invokable method. 165 * 166 * @return The return type for this invokable method. 167 */ 168 public String getReturnType() 169 { 170 return returnType; 171 } 172 173 174 175 /** 176 * Indicates whether this method retrieves information about the 177 * associated component. 178 * 179 * @return <CODE>true</CODE> if this method retrieves information 180 * about the associated component, or <CODE>false</CODE> if 181 * it does not. 182 */ 183 public boolean retrievesComponentInfo() 184 { 185 return retrievesComponentInfo; 186 } 187 188 189 190 /** 191 * Indicates whether this method updates information about the 192 * associated component. 193 * 194 * @return <CODE>true</CODE> if this method updates information 195 * about the associated component, or <CODE>false</CODE> if 196 * it does not. 197 */ 198 public boolean updatesComponentInfo() 199 { 200 return updatesComponentInfo; 201 } 202 203 204 205 /** 206 * Retrieves an <CODE>MBeanOperationInfo</CODE> object that 207 * encapsulates the information in this invokable method. 208 * 209 * @return An <CODE>MBeanOperationInfo</CODE> object that 210 * encapsulates the information in this invokable method. 211 */ 212 public MBeanOperationInfo toOperationInfo() 213 { 214 MBeanParameterInfo[] signature = 215 new MBeanParameterInfo[arguments.length]; 216 for (int i=0; i < arguments.length; i++) 217 { 218 signature[i] = arguments[i].toJMXParameterInfo(); 219 } 220 221 222 int impact; 223 if (retrievesComponentInfo) 224 { 225 if (updatesComponentInfo) 226 { 227 impact = MBeanOperationInfo.ACTION_INFO; 228 } 229 else 230 { 231 impact = MBeanOperationInfo.INFO; 232 } 233 } 234 else if (updatesComponentInfo) 235 { 236 impact = MBeanOperationInfo.ACTION; 237 } 238 else 239 { 240 impact = MBeanOperationInfo.UNKNOWN; 241 } 242 243 244 return new MBeanOperationInfo(name, description, signature, 245 returnType, impact); 246 247 } 248 249 250 251 /** 252 * Indicates whether this invokable method has the provided 253 * signature. 254 * 255 * @param methodName The method name to use in the 256 * determination. 257 * @param argumentTypes The argument object types to use in the 258 * determination. 259 * 260 * @return <CODE>true</CODE> if this invokable method has the 261 * provided signature, or <CODE>false</CODE> if not. 262 */ 263 public boolean hasSignature(String methodName, 264 String[] argumentTypes) 265 { 266 if (! methodName.equals(name)) 267 { 268 return false; 269 } 270 271 if (argumentTypes.length != arguments.length) 272 { 273 return false; 274 } 275 276 for (int i=0; i < arguments.length; i++) 277 { 278 MBeanParameterInfo paramInfo = 279 arguments[i].toJMXParameterInfo(); 280 if (! argumentTypes[i].equals(paramInfo.getType())) 281 { 282 return false; 283 } 284 } 285 286 return true; 287 } 288 289 290 291 /** 292 * Calls upon the provided component to invoke this method using the 293 * given parameters. 294 * 295 * @param component The component to use to invoke this 296 * method. 297 * @param parameters The set of method arguments to use when 298 * invoking this method. 299 * 300 * @return The return value resulting from invoking the method, or 301 * <CODE>null</CODE> if it did not return a value. 302 * 303 * @throws MBeanException If a problem occurred while invoking the 304 * method. 305 */ 306 public Object invoke(InvokableComponent component, 307 Object[] parameters) 308 throws MBeanException 309 { 310 try 311 { 312 ConfigAttribute[] methodArguments = 313 new ConfigAttribute[arguments.length]; 314 for (int i=0; i < arguments.length; i++) 315 { 316 Attribute jmxAttr = new Attribute(arguments[i].getName(), 317 parameters[i]); 318 319 methodArguments[i] = arguments[i].duplicate(); 320 methodArguments[i].setValue(jmxAttr); 321 } 322 323 return component.invokeMethod(name, methodArguments); 324 } 325 catch (DirectoryException de) 326 { 327 if (debugEnabled()) 328 { 329 TRACER.debugCaught(DebugLogLevel.ERROR, de); 330 } 331 332 throw new MBeanException(de, de.getMessage()); 333 } 334 catch (Exception e) 335 { 336 if (debugEnabled()) 337 { 338 TRACER.debugCaught(DebugLogLevel.ERROR, e); 339 } 340 341 throw new MBeanException(e); 342 } 343 } 344 345 346 347 /** 348 * Retrieves a string representation of this invokable method. It 349 * will be in the form of a method signature, like "returnType 350 * name(arguments)". 351 * 352 * @return a string representation of this invokable method. 353 */ 354 public String toString() 355 { 356 StringBuilder buffer = new StringBuilder(); 357 358 if (returnType == null) 359 { 360 buffer.append("void "); 361 } 362 else 363 { 364 buffer.append(returnType); 365 } 366 367 buffer.append(name); 368 buffer.append('('); 369 370 if ((arguments != null) && (arguments.length > 0)) 371 { 372 buffer.append(arguments[0].getDataType()); 373 buffer.append(' '); 374 buffer.append(arguments[0].getName()); 375 376 for (int i=1; i < arguments.length; i++) 377 { 378 buffer.append(", "); 379 buffer.append(arguments[i].getDataType()); 380 buffer.append(' '); 381 buffer.append(arguments[i].getName()); 382 } 383 } 384 385 buffer.append(')'); 386 387 return buffer.toString(); 388 } 389 } 390