/**
* VMware Continuent Tungsten Replicator
* Copyright (C) 2015 VMware, Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Initial developer(s): Edward Archibald
* Contributor(s): Linas Virbalas
*/
package com.continuent.tungsten.common.jmx;
import java.io.Serializable;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;
import javax.management.MBeanInfo;
import javax.management.MBeanOperationInfo;
import javax.management.ObjectName;
/**
* Dynamic access to MBean enabled class.
*
* @author <a href="mailto:edward.archibald@continuent.com">Edward Archibald</a>
* @version 1.0
*/
public class DynamicMBeanHelper implements Serializable
{
private static final long serialVersionUID = 1L;
private ObjectName objName;
private String className = null;
private MBeanInfo info = null;
private Map<String, DynamicMBeanOperation> methods = new TreeMap<String, DynamicMBeanOperation>();
/**
* @param mbeanClass
* @param name
* @param info
*/
public DynamicMBeanHelper(Class<?> mbeanClass, ObjectName name,
MBeanInfo info)
{
this.objName = name;
this.className = mbeanClass.getName();
this.info = info;
setMethods(mbeanClass, info);
}
/**
* @param mbeanClass
* @param info
*/
private void setMethods(Class<?> mbeanClass, MBeanInfo info)
{
Map<String, Method> classMethods = getClassMethods(mbeanClass);
for (MBeanOperationInfo operation : info.getOperations())
{
Method classMethod = classMethods.get(operation.getName());
if (classMethod == null)
{
continue;
}
DynamicMBeanOperation method = new DynamicMBeanOperation(
classMethod, operation);
methods.put(
String.format("%s(%d)", method.getName(),
method.getSignature().length), method);
}
}
/**
* @param mbeanClass
*/
private Map<String, Method> getClassMethods(Class<?> mbeanClass)
{
Map<String, Method> classMethods = new HashMap<String, Method>();
for (Method method : mbeanClass.getMethods())
{
classMethods.put(method.getName(), method);
}
return classMethods;
}
/**
* Returns the name value.
*
* @return Returns the name.
*/
public ObjectName getName()
{
return objName;
}
/**
* Sets the name value.
*
* @param name The name to set.
*/
public void setName(ObjectName name)
{
this.objName = name;
}
/**
* Returns the info value.
*
* @return Returns the info.DynamicMBeanHelper
*/
public MBeanInfo getInfo()
{
return info;
}
/**
* Sets the info value.
*
* @param info The info to set.
*/
public void setInfo(MBeanInfo info)
{
this.info = info;
}
/**
* Returns the methods value.
*
* @return Returns the methods.
*/
public Map<String, DynamicMBeanOperation> getMethods()
{
return methods;
}
public DynamicMBeanOperation getMethod(String methodName, int paramCount)
{
return methods.get(String.format("%s(%d)", methodName, paramCount));
}
@Override
public String toString()
{
StringBuilder builder = new StringBuilder();
builder.append(String.format("ObjectName=%s\n%s\n", objName,
classNameOnly(className)));
return builder.toString();
}
public String usage()
{
StringBuilder builder = new StringBuilder();
builder.append(String.format("%s\n", classNameOnly(className)));
for (DynamicMBeanOperation method : methods.values())
{
builder.append(String.format("\t%s\n", method.getUsage()));
}
return builder.toString();
}
/**
* Returns the className value.
*
* @return Returns the className.
*/
public String getClassName()
{
return className;
}
/**
* Returns the className value.
*
* @return Returns the className.
*/
public String getShortName()
{
return classNameOnly(className);
}
/**
* Sets the className value.
*
* @param className The className to set.
*/
public void setClassName(String className)
{
this.className = className;
}
private String classNameOnly(String className)
{
return className.substring(className.lastIndexOf('.') + 1);
}
}