// Path: src/main/java/com/kendelong/util/monitoring/webservice/ExternalNameElementComputer.java
// public class ExternalNameElementComputer
// {
// 	private final Logger logger = LoggerFactory.getLogger(this.getClass());
// 
// 	public String computeExternalNameElement(Class<?> clazz)
// 	{
// 		Class<?> correctClazz = findOriginalClass(clazz);
// 		String nameElement = null;
// 		if(correctClazz.isAnnotationPresent(WebServiceClient.class))
// 		{
// 			nameElement = "client";
// 		}
// 		if(correctClazz.isAnnotationPresent(WebServiceEndpoint.class))
// 		{
// 			nameElement = "endpoint";
// 		}
// 				
// 		return nameElement;
// 	}
// 	
// 	private Class<?> findOriginalClass(Class<?> clazz)
// 	{
// 		String className = clazz.getName();
// 		String newClassName = cleanClassName(className);
// 		if(newClassName.equals(className))
// 		{
// 			return clazz;
// 		}
// 		else
// 		{
// 			try
// 			{
// 				return clazz.getClassLoader().loadClass(newClassName);
// 			}
// 			catch(ClassNotFoundException e)
// 			{
// 				logger.warn("Class not found: [" + newClassName + "]");
// 				return clazz;
// 			}
// 		}
// 	}
// 
// 	String cleanClassName(String cn)
// 	{
// 		int index = cn.indexOf("$$EnhancerBySpring");
// 		if(index < 0)
// 		{
// 			return cn;
// 		}
// 		else
// 		{
// 			return cn.substring(0, index);
// 		}
// 	}
// }


import java.util.Map;
import javax.management.ObjectName;
import org.aopalliance.aop.Advice;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.aop.Advisor;
import org.springframework.aop.aspectj.AbstractAspectJAdvice;
import org.springframework.aop.framework.Advised;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.jmx.export.MBeanExportException;
import org.springframework.jmx.export.MBeanExporter;
import com.kendelong.util.monitoring.webservice.ExternalNameElementComputer;
package com.kendelong.util.spring;





/**
 * This bean can export AspectJ-style aspects to JMX when registered.  For example:
 * 
 * <pre>
 * {@code
	<bean class="com.kendelong.util.circuitbreaker.CircuitBreakerAspect" scope="prototype"/>
			
	<bean class="com.kendelong.util.spring.JmxExportingAspectPostProcessor" lazy-init="false">
		<property name="mbeanExporter" ref="mbeanExporter"/>
		<property name="annotationToServiceNames">
			<map>
				<entry key="com.kendelong.util.circuitbreaker.CircuitBreakerAspect" value="circuitbreaker"/>
			</map>
		</property>
		<property name="jmxDomain" value="app.mystuff"/>
	</bean>  
   }
	</pre>
 * 
 * Important properties to set are the jmxDomain to use for the ONames of the MBeans,
 * and the value of the map which will be also used for the OName.  OName structure is 
 *      jmxDomain:service=[map value],bean=[original advised bean name]
 * 
 * @author Ken DeLong
 *
 */
public class JmxExportingAspectPostProcessor implements BeanPostProcessor
{
	private MBeanExporter mbeanExporter;
	
	private Map<Class<?>, String> annotationToServiceNames;
	
	private String jmxDomain;
	
	private final Logger logger = LoggerFactory.getLogger(this.getClass());
	
// Path: src/main/java/com/kendelong/util/monitoring/webservice/ExternalNameElementComputer.java
// public class ExternalNameElementComputer
// {
// 	private final Logger logger = LoggerFactory.getLogger(this.getClass());
// 
// 	public String computeExternalNameElement(Class<?> clazz)
// 	{
// 		Class<?> correctClazz = findOriginalClass(clazz);
// 		String nameElement = null;
// 		if(correctClazz.isAnnotationPresent(WebServiceClient.class))
// 		{
// 			nameElement = "client";
// 		}
// 		if(correctClazz.isAnnotationPresent(WebServiceEndpoint.class))
// 		{
// 			nameElement = "endpoint";
// 		}
// 				
// 		return nameElement;
// 	}
// 	
// 	private Class<?> findOriginalClass(Class<?> clazz)
// 	{
// 		String className = clazz.getName();
// 		String newClassName = cleanClassName(className);
// 		if(newClassName.equals(className))
// 		{
// 			return clazz;
// 		}
// 		else
// 		{
// 			try
// 			{
// 				return clazz.getClassLoader().loadClass(newClassName);
// 			}
// 			catch(ClassNotFoundException e)
// 			{
// 				logger.warn("Class not found: [" + newClassName + "]");
// 				return clazz;
// 			}
// 		}
// 	}
// 
// 	String cleanClassName(String cn)
// 	{
// 		int index = cn.indexOf("$$EnhancerBySpring");
// 		if(index < 0)
// 		{
// 			return cn;
// 		}
// 		else
// 		{
// 			return cn.substring(0, index);
// 		}
// 	}
// }


// Path: src/main/java/com/kendelong/util/spring/JmxExportingAspectPostProcessor.java
import java.util.Map;
import javax.management.ObjectName;
import org.aopalliance.aop.Advice;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.aop.Advisor;
import org.springframework.aop.aspectj.AbstractAspectJAdvice;
import org.springframework.aop.framework.Advised;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.jmx.export.MBeanExportException;
import org.springframework.jmx.export.MBeanExporter;
import com.kendelong.util.monitoring.webservice.ExternalNameElementComputer;

package com.kendelong.util.spring;





/**
 * This bean can export AspectJ-style aspects to JMX when registered.  For example:
 * 
 * <pre>
 * {@code
	<bean class="com.kendelong.util.circuitbreaker.CircuitBreakerAspect" scope="prototype"/>
			
	<bean class="com.kendelong.util.spring.JmxExportingAspectPostProcessor" lazy-init="false">
		<property name="mbeanExporter" ref="mbeanExporter"/>
		<property name="annotationToServiceNames">
			<map>
				<entry key="com.kendelong.util.circuitbreaker.CircuitBreakerAspect" value="circuitbreaker"/>
			</map>
		</property>
		<property name="jmxDomain" value="app.mystuff"/>
	</bean>  
   }
	</pre>
 * 
 * Important properties to set are the jmxDomain to use for the ONames of the MBeans,
 * and the value of the map which will be also used for the OName.  OName structure is 
 *      jmxDomain:service=[map value],bean=[original advised bean name]
 * 
 * @author Ken DeLong
 *
 */
public class JmxExportingAspectPostProcessor implements BeanPostProcessor
{
	private MBeanExporter mbeanExporter;
	
	private Map<Class<?>, String> annotationToServiceNames;
	
	private String jmxDomain;
	
	private final Logger logger = LoggerFactory.getLogger(this.getClass());
	
	private final ExternalNameElementComputer nameElementComputer = new ExternalNameElementComputer();