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