1 5 package com.tc.management; 6 7 import EDU.oswego.cs.dl.util.concurrent.CopyOnWriteArrayList; 8 9 import com.tc.exception.TCRuntimeException; 10 import com.tc.logging.TCLogger; 11 import com.tc.logging.TCLogging; 12 import com.tc.properties.TCPropertiesImpl; 13 14 import java.util.Iterator ; 15 import java.util.List ; 16 import java.util.Locale ; 17 import java.util.MissingResourceException ; 18 import java.util.ResourceBundle ; 19 20 import javax.management.ListenerNotFoundException ; 21 import javax.management.MBeanFeatureInfo ; 22 import javax.management.MBeanNotificationInfo ; 23 import javax.management.NotCompliantMBeanException ; 24 import javax.management.Notification ; 25 import javax.management.NotificationEmitter ; 26 import javax.management.NotificationFilter ; 27 import javax.management.NotificationListener ; 28 import javax.management.StandardMBean ; 29 30 public abstract class AbstractTerracottaMBean extends StandardMBean implements NotificationEmitter , TerracottaMBean { 31 32 private static final ResourceBundle DEFAULT_BUNDLE = getBundleForMBean(TerracottaMBean.class, TCLogging 33 .getLogger(TerracottaMBean.class)); 34 35 private static final boolean ENABLED = TCPropertiesImpl.getProperties().getBoolean( 36 "tc.management.mbeans.enabled"); 37 38 private final TCLogger logger; 39 private final ResourceBundle beanBundle; 40 private final boolean isNotificationBroadcaster; 41 42 private final List notificationListeners = new CopyOnWriteArrayList(); 45 private boolean isActive; 46 47 protected AbstractTerracottaMBean(final Class mBeanInterface, final boolean isNotificationBroadcaster) 48 throws NotCompliantMBeanException { 49 this(mBeanInterface, isNotificationBroadcaster, ENABLED); 50 } 51 52 protected AbstractTerracottaMBean(final Class mBeanInterface, final boolean isNotificationBroadcaster, 53 final boolean isActive) throws NotCompliantMBeanException { 54 super(mBeanInterface); 55 this.logger = TCLogging.getLogger(mBeanInterface); 56 this.beanBundle = getBundleForMBean(mBeanInterface, logger); 57 this.isNotificationBroadcaster = isNotificationBroadcaster; 58 this.isActive = isActive; 59 } 60 61 public final String getInterfaceClassName() { 62 return getMBeanInterface().getName(); 63 } 64 65 public final void addNotificationListener(final NotificationListener listener, final NotificationFilter filter, 66 final Object obj) { 67 notificationListeners.add(new Listener (listener, filter, obj)); 68 } 69 70 public MBeanNotificationInfo [] getNotificationInfo() { 71 if (isNotificationBroadcaster()) { 72 final RuntimeException re = new TCRuntimeException("MBean error: this MBean[" + getClass().getName() 73 + "] must override getNotificationInfo() since" + " it broadcasts notifications"); 74 throw re; 75 } 76 return new MBeanNotificationInfo [0]; 77 } 78 79 public final void removeNotificationListener(final NotificationListener listener, final NotificationFilter filter, 80 final Object obj) throws ListenerNotFoundException { 81 boolean removed = false; 82 83 for (Iterator i = notificationListeners.iterator(); i.hasNext();) { 84 Listener lsnr = (Listener ) i.next(); 85 if (lsnr.listener == listener && lsnr.filter == filter && lsnr.handback == obj) { 86 removed = true; 87 i.remove(); 88 } 89 } 90 91 if (!removed) { throw new ListenerNotFoundException (); } 92 } 93 94 public final void removeNotificationListener(final NotificationListener listener) throws ListenerNotFoundException { 95 boolean removed = false; 96 97 for (Iterator i = notificationListeners.iterator(); i.hasNext();) { 98 Listener lsnr = (Listener ) i.next(); 99 if (lsnr.listener == listener) { 100 removed = true; 101 i.remove(); 102 } 103 } 104 105 if (!removed) { throw new ListenerNotFoundException (); } 106 } 107 108 public final void sendNotification(final Notification notification) { 109 if (isEnabled()) { 110 for (Iterator i = notificationListeners.iterator(); i.hasNext();) { 111 Listener lsnr = (Listener ) i.next(); 112 113 if (lsnr.filter == null || lsnr.filter.isNotificationEnabled(notification)) { 114 lsnr.listener.handleNotification(notification, lsnr.handback); 115 } 116 } 117 } 118 } 119 120 public final boolean isNotificationBroadcaster() { 121 return isNotificationBroadcaster; 122 } 123 124 public final void enable() { 125 setState(true); 126 } 127 128 public final void disable() { 129 setState(false); 130 } 131 132 private synchronized void setState(final boolean isActive) { 133 if (this.isActive && !isActive) { 134 reset(); 135 } 136 this.isActive = isActive; 137 } 138 139 public final synchronized boolean isEnabled() { 140 return isActive; 141 } 142 143 149 protected String getDescription(final MBeanFeatureInfo featureInfo) { 150 final String name = featureInfo.getName(); 151 String bundleDescription = null; 152 if (beanBundle != null) { 153 try { 154 bundleDescription = beanBundle.getString(name); 155 } catch (MissingResourceException mre) { 156 if (DEFAULT_BUNDLE != null) { 157 try { 158 bundleDescription = DEFAULT_BUNDLE.getString(name); 159 } catch (MissingResourceException defaultMre) { 160 } 162 } 163 } catch (Throwable t) { 164 logger.warn("Unexpected error while trying to retrieve feature description[" + name + "]", t); 166 } finally { 167 if (bundleDescription == null) { 168 bundleDescription = super.getDescription(featureInfo); 169 } 170 } 171 } 172 return bundleDescription; 173 } 174 175 private static ResourceBundle getBundleForMBean(final Class mBeanInterface, final TCLogger logger) { 176 ResourceBundle bundle = null; 177 try { 178 bundle = ResourceBundle.getBundle(mBeanInterface.getName(), Locale.getDefault(), AbstractTerracottaMBean.class 179 .getClassLoader()); 180 } catch (MissingResourceException mre) { 181 logger.info("No resource bundle exists for MBean " + mBeanInterface.getName()); 182 } catch (Throwable t) { 183 logger.warn("Unexpected error loading resource bundle for MBean " + mBeanInterface.getName(), t); 184 } 185 return bundle; 186 } 187 188 private static class Listener { 189 private final NotificationListener listener; 190 private final NotificationFilter filter; 191 private final Object handback; 192 193 Listener(NotificationListener listener, NotificationFilter filter, Object obj) { 194 this.listener = listener; 195 this.filter = filter; 196 this.handback = obj; 197 } 198 199 } 200 201 } 202 | Popular Tags |