/** * Helios, OpenSource Monitoring * Brought to you by the Helios Development Group * * Copyright 2007, Helios Development Group and individual contributors * as indicated by the @author tags. See the copyright.txt file in the * distribution for a full listing of individual contributors. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. * */ package org.helios.apmrouter.spring.ctx; import java.io.IOException; import java.lang.annotation.Annotation; import java.net.URL; import java.net.URLClassLoader; import java.util.Collection; import java.util.HashSet; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Set; import java.util.concurrent.atomic.AtomicLong; import javax.management.MBeanServerInvocationHandler; import javax.management.ObjectName; import org.apache.log4j.Logger; import org.helios.apmrouter.deployer.HotDeployerClassLoader; import org.helios.apmrouter.jmx.JMXHelper; import org.springframework.beans.BeansException; import org.springframework.beans.factory.BeanDefinitionStoreException; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.NoSuchBeanDefinitionException; import org.springframework.beans.factory.config.AutowireCapableBeanFactory; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.config.BeanFactoryPostProcessor; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.beans.factory.support.DefaultListableBeanFactory; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationEvent; import org.springframework.context.ApplicationListener; import org.springframework.context.MessageSourceResolvable; import org.springframework.context.NoSuchMessageException; import org.springframework.context.support.GenericApplicationContext; import org.springframework.core.env.Environment; import org.springframework.core.io.Resource; import org.springframework.core.io.ResourceLoader; /** * <p>Title: ApplicationContextService</p> * <p>Description: Exposes an application context as a JMX MBean.</p> * <p>Company: Helios Development Group LLC</p> * @author Whitehead (nwhitehead AT heliosdev DOT org) * <p><code>org.helios.apmrouter.spring.ctx.ApplicationContextService</code></p> */ public class ApplicationContextService implements ApplicationContextServiceMBean { /** The wrapped app context */ protected final GenericApplicationContext delegate; /** The app context service JMX ObjectName */ protected final ObjectName objectName; /** The unique identifier of the app context used to add a key prop to the object name */ protected final String id; /** The instance logger */ protected final Logger log; /** Serial number factory for providing IDs for app ctxs with empty display names */ protected static final AtomicLong serial = new AtomicLong(0L); /** * Creates a new ApplicationContextService * @param delegate The wrapped app context * @return the created ApplicationContextService */ public static ApplicationContextService register(GenericApplicationContext delegate) { return new ApplicationContextService(delegate); } /** * Creates a new ApplicationContextService * @param on The provided objectname for this service * @param delegate The wrapped app context * @return the created ApplicationContextService */ public static ApplicationContextService register(ObjectName on, GenericApplicationContext delegate) { return new ApplicationContextService(on, delegate); } /** * Creates a new ApplicationContextService * @param delegate The wrapped app context */ public ApplicationContextService(GenericApplicationContext delegate) { this(null, delegate); } /** * Creates a new ApplicationContextService * @param on The provided objectname for this service * @param delegate The wrapped app context */ public ApplicationContextService(ObjectName on, GenericApplicationContext delegate) { this.delegate = delegate; id = getId(this.delegate); log = Logger.getLogger(getClass().getName() + "." + id); objectName = on!=null ? on : JMXHelper.objectName(OBJECT_NAME_PREF + id); try { if(JMXHelper.getHeliosMBeanServer().isRegistered(objectName)) { JMXHelper.getHeliosMBeanServer().unregisterMBean(objectName); } JMXHelper.getHeliosMBeanServer().registerMBean(this, objectName); } catch (Exception ex) { if(log.isDebugEnabled()) { log.warn("Failed to register management interface. Continuing without.", ex); } else { log.warn("Failed to register management interface [" + ex + "]. Continuing without."); } } } /** * Determines the unique ID assigned to the passed application context * @param appCtx application context to assign an ID for * @return the ID for the passed application context */ protected static String getId(ApplicationContext appCtx) { String dn = appCtx.getDisplayName().trim(); if(dn.isEmpty()) { return "#" + serial.incrementAndGet(); } return dn; } /** * Returns a proxy to the root app context * @return a proxy to the root app context */ public static ApplicationContext getRootInstance() { return MBeanServerInvocationHandler.newProxyInstance(JMXHelper.getHeliosMBeanServer(), ROOT_APP_CTX_ON, ApplicationContext.class, false); } /** * Returns the wrapped {@link GenericApplicationContext} instance * @return the wrapped {@link GenericApplicationContext} instance */ public GenericApplicationContext getInstance() { return this.delegate; } /** * Lists any entries in the classpath of this application context * @return a set of strings representing classpath entries */ public Set<String> getClassPath() { Set<String> cp = new HashSet<String>(); ClassLoader cl = getClassLoader(); if(cl instanceof URLClassLoader) { if(cl instanceof HotDeployerClassLoader) { cl = cl.getParent(); } if(cl!=null) { for(URL url: ((URLClassLoader)cl).getURLs()) { cp.add(url.toString()); } } } return cp; } /** * Lists any entries in the extended classpath of this application context * @return a set of strings representing classpath entries */ public Set<String> getExtendedClassPath() { Set<String> cp = new HashSet<String>(); ClassLoader cl = getClassLoader(); if(cl instanceof HotDeployerClassLoader) { cp.addAll(((HotDeployerClassLoader)cl).getClassPathEntries()); } return cp; } /** * @return int * @see java.lang.Object#hashCode() */ @Override public int hashCode() { return delegate.hashCode(); } /** * @param classLoader * @see org.springframework.core.io.DefaultResourceLoader#setClassLoader(java.lang.ClassLoader) */ public void setClassLoader(ClassLoader classLoader) { delegate.setClassLoader(classLoader); } /** * @return ClassLoader * @see org.springframework.core.io.DefaultResourceLoader#getClassLoader() */ public ClassLoader getClassLoader() { return delegate.getClassLoader(); } /** * @param obj * @return boolean * @see java.lang.Object#equals(java.lang.Object) */ @Override public boolean equals(Object obj) { return delegate.equals(obj); } /** * @param parent * @see org.springframework.context.support.GenericApplicationContext#setParent(org.springframework.context.ApplicationContext) */ public void setParent(ApplicationContext parent) { delegate.setParent(parent); } /** * @param id * @see org.springframework.context.support.GenericApplicationContext#setId(java.lang.String) */ public void setId(String id) { delegate.setId(id); } /** * @param allowBeanDefinitionOverriding * @see org.springframework.context.support.GenericApplicationContext#setAllowBeanDefinitionOverriding(boolean) */ public void setAllowBeanDefinitionOverriding( boolean allowBeanDefinitionOverriding) { delegate.setAllowBeanDefinitionOverriding(allowBeanDefinitionOverriding); } /** * @param allowCircularReferences * @see org.springframework.context.support.GenericApplicationContext#setAllowCircularReferences(boolean) */ public void setAllowCircularReferences(boolean allowCircularReferences) { delegate.setAllowCircularReferences(allowCircularReferences); } /** * @param resourceLoader * @see org.springframework.context.support.GenericApplicationContext#setResourceLoader(org.springframework.core.io.ResourceLoader) */ public void setResourceLoader(ResourceLoader resourceLoader) { delegate.setResourceLoader(resourceLoader); } /** * @param location * @return Resource * @see org.springframework.context.support.GenericApplicationContext#getResource(java.lang.String) */ public Resource getResource(String location) { return delegate.getResource(location); } /** * @param locationPattern * @return Resource[] * @throws IOException * @see org.springframework.context.support.GenericApplicationContext#getResources(java.lang.String) */ public Resource[] getResources(String locationPattern) throws IOException { return delegate.getResources(locationPattern); } /** * @return String * @see org.springframework.context.support.AbstractApplicationContext#getId() */ public String getId() { return delegate.getId(); } /** * @param displayName * @see org.springframework.context.support.AbstractApplicationContext#setDisplayName(java.lang.String) */ public void setDisplayName(String displayName) { delegate.setDisplayName(displayName); } /** * @return ConfigurableListableBeanFactory * @see org.springframework.context.support.GenericApplicationContext#getBeanFactory() */ public final ConfigurableListableBeanFactory getBeanFactory() { return delegate.getBeanFactory(); } /** * @return DefaultListableBeanFactory * @see org.springframework.context.support.GenericApplicationContext#getDefaultListableBeanFactory() */ public final DefaultListableBeanFactory getDefaultListableBeanFactory() { return delegate.getDefaultListableBeanFactory(); } /** * @return String * @see org.springframework.context.support.AbstractApplicationContext#getDisplayName() */ public String getDisplayName() { return delegate.getDisplayName(); } /** * @return ApplicationContext * @see org.springframework.context.support.AbstractApplicationContext#getParent() */ public ApplicationContext getParent() { return delegate.getParent(); } /** * @return AutowireCapableBeanFactory * @throws IllegalStateException * @see org.springframework.context.support.AbstractApplicationContext#getAutowireCapableBeanFactory() */ public AutowireCapableBeanFactory getAutowireCapableBeanFactory() throws IllegalStateException { return delegate.getAutowireCapableBeanFactory(); } /** * @param beanName * @param beanDefinition * @throws BeanDefinitionStoreException * @see org.springframework.context.support.GenericApplicationContext#registerBeanDefinition(java.lang.String, org.springframework.beans.factory.config.BeanDefinition) */ public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws BeanDefinitionStoreException { delegate.registerBeanDefinition(beanName, beanDefinition); } /** * @return long * @see org.springframework.context.support.AbstractApplicationContext#getStartupDate() */ public long getStartupDate() { return delegate.getStartupDate(); } /** * @param event * @see org.springframework.context.support.AbstractApplicationContext#publishEvent(org.springframework.context.ApplicationEvent) */ public void publishEvent(ApplicationEvent event) { delegate.publishEvent(event); } /** * @param beanName * @throws NoSuchBeanDefinitionException * @see org.springframework.context.support.GenericApplicationContext#removeBeanDefinition(java.lang.String) */ public void removeBeanDefinition(String beanName) throws NoSuchBeanDefinitionException { delegate.removeBeanDefinition(beanName); } /** * @param beanName * @return BeanDefinition * @throws NoSuchBeanDefinitionException * @see org.springframework.context.support.GenericApplicationContext#getBeanDefinition(java.lang.String) */ public BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException { return delegate.getBeanDefinition(beanName); } /** * @param beanName * @return boolean * @see org.springframework.context.support.GenericApplicationContext#isBeanNameInUse(java.lang.String) */ public boolean isBeanNameInUse(String beanName) { return delegate.isBeanNameInUse(beanName); } /** * @param beanName * @param alias * @see org.springframework.context.support.GenericApplicationContext#registerAlias(java.lang.String, java.lang.String) */ public void registerAlias(String beanName, String alias) { delegate.registerAlias(beanName, alias); } /** * @param alias * @see org.springframework.context.support.GenericApplicationContext#removeAlias(java.lang.String) */ public void removeAlias(String alias) { delegate.removeAlias(alias); } /** * @param beanName * @return boolean * @see org.springframework.context.support.GenericApplicationContext#isAlias(java.lang.String) */ public boolean isAlias(String beanName) { return delegate.isAlias(beanName); } /** * @param beanFactoryPostProcessor * @see org.springframework.context.support.AbstractApplicationContext#addBeanFactoryPostProcessor(org.springframework.beans.factory.config.BeanFactoryPostProcessor) */ public void addBeanFactoryPostProcessor( BeanFactoryPostProcessor beanFactoryPostProcessor) { delegate.addBeanFactoryPostProcessor(beanFactoryPostProcessor); } /** * @return List<BeanFactoryPostProcessor> * @see org.springframework.context.support.AbstractApplicationContext#getBeanFactoryPostProcessors() */ public List<BeanFactoryPostProcessor> getBeanFactoryPostProcessors() { return delegate.getBeanFactoryPostProcessors(); } /** * @param listener * @see org.springframework.context.support.AbstractApplicationContext#addApplicationListener(org.springframework.context.ApplicationListener) */ public void addApplicationListener(ApplicationListener listener) { delegate.addApplicationListener(listener); } /** * @return Collection<ApplicationListener<?>> * @see org.springframework.context.support.AbstractApplicationContext#getApplicationListeners() */ public Collection<ApplicationListener<?>> getApplicationListeners() { return delegate.getApplicationListeners(); } /** * @throws BeansException * @throws IllegalStateException * @see org.springframework.context.support.AbstractApplicationContext#refresh() */ public void refresh() throws BeansException, IllegalStateException { delegate.refresh(); } /** * * @see org.springframework.context.support.AbstractApplicationContext#registerShutdownHook() */ public void registerShutdownHook() { delegate.registerShutdownHook(); } /** * * @see org.springframework.context.support.AbstractApplicationContext#destroy() */ public void destroy() { delegate.destroy(); } /** * * @see org.springframework.context.support.AbstractApplicationContext#close() */ public void close() { delegate.close(); } /** * @return boolean * @see org.springframework.context.support.AbstractApplicationContext#isActive() */ public boolean isActive() { return delegate.isActive(); } /** * @param name * @return Object * @throws BeansException * @see org.springframework.context.support.AbstractApplicationContext#getBean(java.lang.String) */ public Object getBean(String name) throws BeansException { return delegate.getBean(name); } /** * @param name * @param requiredType * @return <T> T * @throws BeansException * @see org.springframework.context.support.AbstractApplicationContext#getBean(java.lang.String, java.lang.Class) */ public <T> T getBean(String name, Class<T> requiredType) throws BeansException { return delegate.getBean(name, requiredType); } /** * @param requiredType * @return <T> T * @throws BeansException * @see org.springframework.context.support.AbstractApplicationContext#getBean(java.lang.Class) */ public <T> T getBean(Class<T> requiredType) throws BeansException { return delegate.getBean(requiredType); } /** * @param name * @param args * @return Object * @throws BeansException * @see org.springframework.context.support.AbstractApplicationContext#getBean(java.lang.String, java.lang.Object[]) */ public Object getBean(String name, Object... args) throws BeansException { return delegate.getBean(name, args); } /** * @param name * @return boolean * @see org.springframework.context.support.AbstractApplicationContext#containsBean(java.lang.String) */ public boolean containsBean(String name) { return delegate.containsBean(name); } /** * @param name * @return boolean * @throws NoSuchBeanDefinitionException * @see org.springframework.context.support.AbstractApplicationContext#isSingleton(java.lang.String) */ public boolean isSingleton(String name) throws NoSuchBeanDefinitionException { return delegate.isSingleton(name); } /** * @param name * @return boolean * @throws NoSuchBeanDefinitionException * @see org.springframework.context.support.AbstractApplicationContext#isPrototype(java.lang.String) */ public boolean isPrototype(String name) throws NoSuchBeanDefinitionException { return delegate.isPrototype(name); } /** * @param name * @return Class<?> * @throws NoSuchBeanDefinitionException * @see org.springframework.context.support.AbstractApplicationContext#getType(java.lang.String) */ public Class<?> getType(String name) throws NoSuchBeanDefinitionException { return delegate.getType(name); } /** * @param name * @return String[] * @see org.springframework.context.support.AbstractApplicationContext#getAliases(java.lang.String) */ public String[] getAliases(String name) { return delegate.getAliases(name); } /** * @param beanName * @return boolean * @see org.springframework.context.support.AbstractApplicationContext#containsBeanDefinition(java.lang.String) */ public boolean containsBeanDefinition(String beanName) { return delegate.containsBeanDefinition(beanName); } /** * @return int * @see org.springframework.context.support.AbstractApplicationContext#getBeanDefinitionCount() */ public int getBeanDefinitionCount() { return delegate.getBeanDefinitionCount(); } /** * @return String[] * @see org.springframework.context.support.AbstractApplicationContext#getBeanDefinitionNames() */ public String[] getBeanDefinitionNames() { return delegate.getBeanDefinitionNames(); } /** * @param type * @return <T> Map<String, T> * @throws BeansException * @see org.springframework.context.support.AbstractApplicationContext#getBeansOfType(java.lang.Class) */ public <T> Map<String, T> getBeansOfType(Class<T> type) throws BeansException { return delegate.getBeansOfType(type); } /** * @param type * @param includeNonSingletons * @param allowEagerInit * @return <T> Map<String, T> * @throws BeansException * @see org.springframework.context.support.AbstractApplicationContext#getBeansOfType(java.lang.Class, boolean, boolean) */ public <T> Map<String, T> getBeansOfType(Class<T> type, boolean includeNonSingletons, boolean allowEagerInit) throws BeansException { return delegate.getBeansOfType(type, includeNonSingletons, allowEagerInit); } /** * @param annotationType * @return Map<String, Object> * @throws BeansException * @see org.springframework.context.support.AbstractApplicationContext#getBeansWithAnnotation(java.lang.Class) */ public Map<String, Object> getBeansWithAnnotation( Class<? extends Annotation> annotationType) throws BeansException { return delegate.getBeansWithAnnotation(annotationType); } /** * @param beanName * @param annotationType * @return <A extends Annotation> A * @see org.springframework.context.support.AbstractApplicationContext#findAnnotationOnBean(java.lang.String, java.lang.Class) */ public <A extends Annotation> A findAnnotationOnBean(String beanName, Class<A> annotationType) { return delegate.findAnnotationOnBean(beanName, annotationType); } /** * @return BeanFactory * @see org.springframework.context.support.AbstractApplicationContext#getParentBeanFactory() */ public BeanFactory getParentBeanFactory() { return delegate.getParentBeanFactory(); } /** * @param name * @return boolean * @see org.springframework.context.support.AbstractApplicationContext#containsLocalBean(java.lang.String) */ public boolean containsLocalBean(String name) { return delegate.containsLocalBean(name); } /** * @param code * @param args * @param defaultMessage * @param locale * @return String * @see org.springframework.context.support.AbstractApplicationContext#getMessage(java.lang.String, java.lang.Object[], java.lang.String, java.util.Locale) */ public String getMessage(String code, Object[] args, String defaultMessage, Locale locale) { return delegate.getMessage(code, args, defaultMessage, locale); } /** * @param code * @param args * @param locale * @return String * @throws NoSuchMessageException * @see org.springframework.context.support.AbstractApplicationContext#getMessage(java.lang.String, java.lang.Object[], java.util.Locale) */ public String getMessage(String code, Object[] args, Locale locale) throws NoSuchMessageException { return delegate.getMessage(code, args, locale); } /** * @param resolvable * @param locale * @return String * @throws NoSuchMessageException * @see org.springframework.context.support.AbstractApplicationContext#getMessage(org.springframework.context.MessageSourceResolvable, java.util.Locale) */ public String getMessage(MessageSourceResolvable resolvable, Locale locale) throws NoSuchMessageException { return delegate.getMessage(resolvable, locale); } /** * * @see org.springframework.context.support.AbstractApplicationContext#start() */ public void start() { delegate.start(); } /** * * @see org.springframework.context.support.AbstractApplicationContext#stop() */ public void stop() { delegate.stop(); } /** * @return boolean * @see org.springframework.context.support.AbstractApplicationContext#isRunning() */ public boolean isRunning() { return delegate.isRunning(); } /** * @return String * @see org.springframework.context.support.AbstractApplicationContext#toString() */ @Override public String toString() { return delegate.toString(); } /** * Returns the JMX ObjectName of this service * @return the JMX ObjectName of this service */ public ObjectName getObjectName() { return objectName; } /** * {@inheritDoc} * @see org.springframework.context.ApplicationContext#getApplicationName() */ @Override public String getApplicationName() { return delegate.getApplicationName(); } /** * {@inheritDoc} * @see org.springframework.core.env.EnvironmentCapable#getEnvironment() */ @Override public Environment getEnvironment() { return delegate.getEnvironment(); } /** * {@inheritDoc} * @see org.springframework.beans.factory.ListableBeanFactory#getBeanNamesForType(java.lang.Class) */ @Override public String[] getBeanNamesForType(Class<?> type) { return delegate.getBeanNamesForType(type); } /** * {@inheritDoc} * @see org.springframework.beans.factory.ListableBeanFactory#getBeanNamesForType(java.lang.Class, boolean, boolean) */ @Override public String[] getBeanNamesForType(Class<?> type, boolean includeNonSingletons, boolean allowEagerInit) { return delegate.getBeanNamesForType(type, includeNonSingletons, allowEagerInit); } /** * {@inheritDoc} * @see org.springframework.beans.factory.BeanFactory#isTypeMatch(java.lang.String, java.lang.Class) */ @Override public boolean isTypeMatch(String name, Class<?> targetType) throws NoSuchBeanDefinitionException { return delegate.isTypeMatch(name, targetType); } }