/* * Created on Mar 14, 2005 * * The Open SLEE Project * * A SLEE for the People * * The source code contained in this file is in in the public domain. * It can be used in any project or product without prior permission, * license or royalty payments. There is no claim of correctness and * NO WARRANTY OF ANY KIND provided with this code. */ package org.mobicents.slee.container.deployment; import java.beans.Introspector; import java.util.HashSet; import java.util.Set; import javassist.CtClass; import javassist.CtConstructor; import javassist.CtMethod; import javassist.CtNewMethod; import javax.slee.management.ManagementException; import javax.slee.management.NotificationSource; import javax.slee.usage.UsageNotificationManagerMBean; import org.apache.log4j.Logger; import org.mobicents.slee.container.component.SleeComponentWithUsageParametersInterface; import org.mobicents.slee.container.component.deployment.ClassPool; import org.mobicents.slee.container.management.jmx.UsageNotificationManagerMBeanImpl; /** * Generator for the concrete usage usage parameter mbean. * @author F.Moggia * @author <a href="mailto:michele.laporta@gmail.com">Michele La Porta</a> * @author martins */ public class ConcreteUsageNotificationManagerMBeanGenerator { private static Logger logger= Logger.getLogger(ConcreteUsageNotificationManagerMBeanGenerator.class); private final SleeComponentWithUsageParametersInterface component; public ConcreteUsageNotificationManagerMBeanGenerator(SleeComponentWithUsageParametersInterface component) { this.component = component; } /** * Create a constructor. This method simply records the input parameters in * appropriately named fields. * * @param * @param classes */ private void createConstructor(CtClass concreteClass, CtClass usageMBeanInterface, CtClass notificationSource,CtClass usageComponent) throws Exception { CtConstructor ctCons = new CtConstructor(new CtClass[]{usageMBeanInterface,notificationSource,usageComponent}, concreteClass); ctCons.setBody("{ super($1,$2,$3); }"); concreteClass.addConstructor(ctCons); } public void generateConcreteUsageNotificationManagerMBean( ) throws Exception { Class<?> interfaceClass = component.getUsageParametersInterface(); if (interfaceClass == null) return; ClassPool classPool = component.getClassPool(); String usageParamInterfaceName = interfaceClass.getName(); CtClass usageParamInterface = classPool.get(usageParamInterfaceName); CtClass usageMBeanInterface = classPool.get(UsageNotificationManagerMBean.class .getName()); CtClass usageMBeanImplClass = classPool.get(UsageNotificationManagerMBeanImpl.class .getName()); // generate the mbean interface String concreteMBeanInterfaceName = usageParamInterfaceName + "NotificationManagerMBean"; CtClass ctInterface = classPool.makeInterface(concreteMBeanInterfaceName); ctInterface.addInterface(usageMBeanInterface); // generate the mbean class String concreteMBeanClassName = usageParamInterfaceName + "NotificationManagerMBeanImpl"; CtClass ctClass = classPool.makeClass(concreteMBeanClassName); ctClass.setSuperclass(usageMBeanImplClass); ConcreteClassGeneratorUtils.createInterfaceLinks(ctClass,new CtClass[]{ctInterface}); if (logger.isDebugEnabled()) { logger.debug("generating "+concreteMBeanInterfaceName+" and "+concreteMBeanClassName); } // create constructor this.createConstructor(ctClass, classPool.get(Class.class.getName()),classPool.get(NotificationSource.class .getName()),classPool.get(SleeComponentWithUsageParametersInterface.class .getName())); CtMethod[] methods = usageParamInterface.getMethods(); Set<String> userParams = new HashSet<String>(); for (CtMethod ctMethod : methods) { if (!ctMethod.getDeclaringClass().getName().equals(Object.class.getName())) { if (ctMethod.getName().startsWith("increment")) { userParams.add(ctMethod.getName().substring("increment".length())); } else if (ctMethod.getName().startsWith("sample")) { userParams.add(ctMethod.getName().substring("sample".length())); } else if (ctMethod.getName().startsWith("get")) { userParams.add(ctMethod.getName().substring("get".length())); } } } for(String userParam : userParams) { generateInterfaceMethod(ctInterface, userParam); generateConcreteMethod(ctClass, userParam); } String deploymentPathStr = component.getDeploymentDir().getAbsolutePath(); ctInterface.writeFile(deploymentPathStr); logger.debug("Writing file " + concreteMBeanInterfaceName); ctClass.writeFile(deploymentPathStr); logger.debug("Writing file " + concreteMBeanClassName); component.setUsageNotificationManagerMBeanConcreteInterface(Thread.currentThread().getContextClassLoader().loadClass(concreteMBeanInterfaceName)); component.setUsageNotificationManagerMBeanImplConcreteClass(Thread.currentThread().getContextClassLoader().loadClass(concreteMBeanClassName)); ctInterface.defrost(); ctClass.defrost(); } private void generateConcreteMethod(CtClass ctClass, String userParamName) throws Exception{ String userParamNameLowerCase = Introspector.decapitalize(userParamName); String getterBody = "public boolean get" + userParamName + "NotificationsEnabled" + "() throws " + ManagementException.class.getName() + " {" + "return getNotificationsEnabled(\""+userParamNameLowerCase+"\");" + "}"; if ( logger.isDebugEnabled()) logger.debug("getNotificationsEnabled method for user param "+userParamName+" :\n" + getterBody); CtMethod getterMethod = CtNewMethod.make(getterBody, ctClass); ctClass.addMethod(getterMethod); String setterBody = "public void set" + userParamName + "NotificationsEnabled" + "(boolean enabled) throws " + ManagementException.class.getName() + " {" + " setNotificationsEnabled(\""+userParamNameLowerCase+"\",enabled);" + "}"; if ( logger.isDebugEnabled()) logger.debug("setNotificationsEnabled method for user param "+userParamName+" :\n" + setterBody); CtMethod setterMethod = CtNewMethod.make(setterBody, ctClass); ctClass.addMethod(setterMethod); } private void generateInterfaceMethod(CtClass ctClass, String userParamName) throws Exception { ClassPool classPool = component.getClassPool(); CtClass managementExceptionClass = classPool.get(ManagementException.class.getName()); // add the getter method CtClass[] getterParameters = {}; CtClass[] getterExceptions = {managementExceptionClass}; CtMethod getterMethod = CtNewMethod.abstractMethod(CtClass.booleanType, "get" + userParamName + "NotificationsEnabled", getterParameters, getterExceptions, ctClass); ctClass.addMethod(getterMethod); // add the setter method CtClass[] setterParameters = {CtClass.booleanType}; CtClass[] setterExceptions = {managementExceptionClass}; CtMethod setterMethod = CtNewMethod.abstractMethod(CtClass.voidType, "set" + userParamName + "NotificationsEnabled", setterParameters, setterExceptions, ctClass); ctClass.addMethod(setterMethod); } }