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