1 17 package org.apache.servicemix.jbi.management; 18 19 import edu.emory.mathcs.backport.java.util.concurrent.ExecutorService; 20 21 import org.apache.commons.beanutils.MethodUtils; 22 import org.apache.commons.beanutils.PropertyUtilsBean; 23 import org.apache.commons.logging.Log; 24 import org.apache.commons.logging.LogFactory; 25 26 import javax.management.Attribute ; 27 import javax.management.AttributeChangeNotification ; 28 import javax.management.AttributeChangeNotificationFilter ; 29 import javax.management.AttributeList ; 30 import javax.management.AttributeNotFoundException ; 31 import javax.management.Descriptor ; 32 import javax.management.InvalidAttributeValueException ; 33 import javax.management.ListenerNotFoundException ; 34 import javax.management.MBeanAttributeInfo ; 35 import javax.management.MBeanException ; 36 import javax.management.MBeanInfo ; 37 import javax.management.MBeanNotificationInfo ; 38 import javax.management.MBeanOperationInfo ; 39 import javax.management.MBeanRegistration ; 40 import javax.management.MBeanServer ; 41 import javax.management.NotCompliantMBeanException ; 42 import javax.management.Notification ; 43 import javax.management.NotificationBroadcasterSupport ; 44 import javax.management.NotificationFilter ; 45 import javax.management.NotificationListener ; 46 import javax.management.ObjectName ; 47 import javax.management.ReflectionException ; 48 import javax.management.RuntimeOperationsException ; 49 import javax.management.StandardMBean ; 50 import javax.management.modelmbean.DescriptorSupport ; 51 import javax.management.modelmbean.ModelMBeanNotificationBroadcaster ; 52 import javax.management.modelmbean.ModelMBeanNotificationInfo ; 53 54 import java.beans.PropertyChangeEvent ; 55 import java.beans.PropertyChangeListener ; 56 import java.beans.PropertyDescriptor ; 57 import java.lang.reflect.InvocationTargetException ; 58 import java.util.Date ; 59 import java.util.Hashtable ; 60 import java.util.Iterator ; 61 import java.util.LinkedHashMap ; 62 import java.util.Map ; 63 64 69 public class BaseStandardMBean extends StandardMBean 70 implements 71 ModelMBeanNotificationBroadcaster , 72 MBeanRegistration , 73 PropertyChangeListener { 74 private final static Log log = LogFactory.getLog(BaseStandardMBean.class); 75 private Map cachedAttributes = new LinkedHashMap (); private PropertyUtilsBean beanUtil = new PropertyUtilsBean(); 77 private NotificationBroadcasterSupport broadcasterSupport = new NotificationBroadcasterSupport (); 78 protected ExecutorService executorService; 79 private MBeanAttributeInfo [] attributeInfos; 80 private MBeanInfo beanInfo; 81 private ObjectName objectName; 83 private MBeanServer beanServer; 84 85 97 public BaseStandardMBean(Object object, Class interfaceMBean, String description, MBeanAttributeInfo [] attrs, 98 MBeanOperationInfo [] ops, ExecutorService executorService) throws ReflectionException , NotCompliantMBeanException { 99 super(object, interfaceMBean); 100 this.attributeInfos = attrs; 101 buildAttributes(object, this.attributeInfos); 102 this.beanInfo = new MBeanInfo (object.getClass().getName(), description, attrs, null, ops, getNotificationInfo()); 103 this.executorService = executorService; 104 } 105 106 109 public MBeanInfo getMBeanInfo() { 110 return beanInfo; 111 } 112 113 118 public ObjectName getObjectName() { 119 return objectName; 120 } 121 122 127 public MBeanServer getBeanServer() { 128 return beanServer; 129 } 130 131 140 public Object getAttribute(String name) throws AttributeNotFoundException , MBeanException , ReflectionException { 141 Object result = null; 142 CachedAttribute ca = (CachedAttribute) cachedAttributes.get(name); 143 if (ca == null) { 144 for (Iterator i = cachedAttributes.entrySet().iterator();i.hasNext();) { 147 Map.Entry entry = (Map.Entry ) i.next(); 148 String key = entry.getKey().toString(); 149 if (key.equalsIgnoreCase(name)) { 150 ca = (CachedAttribute) entry.getValue(); 151 break; 152 } 153 } 154 } 155 if (ca != null) { 156 result = getCurrentValue(ca); 157 } 158 else { 159 throw new AttributeNotFoundException ("Could not locate " + name); 160 } 161 return result; 162 } 163 164 173 public void setAttribute(Attribute attr) throws AttributeNotFoundException , InvalidAttributeValueException , 174 MBeanException , ReflectionException { 175 String name = attr.getName(); 176 CachedAttribute ca = (CachedAttribute) cachedAttributes.get(name); 177 if (ca != null) { 178 Attribute old = ca.getAttribute(); 179 try { 180 ca.updateAttribute(beanUtil, attr); 181 sendAttributeChangeNotification(old, attr); 182 } 183 catch (NoSuchMethodException e) { 184 throw new ReflectionException (e); 185 } 186 catch (IllegalAccessException e) { 187 throw new ReflectionException (e); 188 } 189 catch (InvocationTargetException e) { 190 Throwable t = e.getTargetException(); 191 if (t instanceof Exception ) { 192 throw new MBeanException (e); 193 } 194 throw new MBeanException (e); 195 } 196 } 197 else { 198 throw new AttributeNotFoundException ("Could not locate " + name); 199 } 200 } 201 202 208 public void updateAttribute(String name, Object value) { 209 CachedAttribute ca = (CachedAttribute) cachedAttributes.get(name); 210 if (ca != null) { 211 Attribute old = ca.getAttribute(); 212 ca.updateAttributeValue(value); 213 try { 214 sendAttributeChangeNotification(old, ca.getAttribute()); 215 } 216 catch (RuntimeOperationsException e) { 217 log.error("Failed to update attribute: " + name + " to new value: " + value, e); 218 } 219 catch (MBeanException e) { 220 log.error("Failed to update attribute: " + name + " to new value: " + value, e); 221 } 222 } 223 } 224 225 230 public void propertyChange(PropertyChangeEvent event) { 231 updateAttribute(event.getPropertyName(), event.getNewValue()); 232 } 233 234 238 public AttributeList getAttributes(String [] attributes) { 239 AttributeList result = null; 240 try { 241 if (attributes != null) { 242 result = new AttributeList (); 243 for (int i = 0;i < attributes.length;i++) { 244 CachedAttribute ca = (CachedAttribute) cachedAttributes.get(attributes[i]); 245 ca.updateValue(beanUtil); 246 result.add(ca.getAttribute()); 247 } 248 } 249 else { 250 for (Iterator i = cachedAttributes.entrySet().iterator();i.hasNext();) { 252 Map.Entry entry = (Map.Entry ) i.next(); 253 CachedAttribute ca = (CachedAttribute) entry.getValue(); 254 ca.updateValue(beanUtil); 255 result.add(ca.getAttribute()); 256 } 257 } 258 } 259 catch (MBeanException e) { 260 log.error("Caught excdeption building attributes", e); 261 } 262 return result; 263 } 264 265 271 public AttributeList setAttributes(AttributeList attributes) { 272 AttributeList result = new AttributeList (); 273 if (attributes != null) { 274 for (int i = 0;i < attributes.size();i++) { 275 Attribute attribute = (Attribute ) attributes.get(i); 276 try { 277 setAttribute(attribute); 278 } 279 catch (AttributeNotFoundException e) { 280 log.warn("Failed to setAttribute(" + attribute + ")", e); 281 } 282 catch (InvalidAttributeValueException e) { 283 log.warn("Failed to setAttribute(" + attribute + ")", e); 284 } 285 catch (MBeanException e) { 286 log.warn("Failed to setAttribute(" + attribute + ")", e); 287 } 288 catch (ReflectionException e) { 289 log.warn("Failed to setAttribute(" + attribute + ")", e); 290 } 291 result.add(attribute); 292 } 293 } 294 return result; 295 } 296 297 307 public Object invoke(String name, Object [] params, String [] signature) throws MBeanException , ReflectionException { 308 try { 309 Class [] parameterTypes = new Class [signature.length]; 310 for (int i = 0; i < parameterTypes.length; i++) { 311 parameterTypes[i] = (Class ) primitiveClasses.get(signature[i]); 312 if (parameterTypes[i] == null) { 313 parameterTypes[i] = Class.forName(signature[i]); 314 } 315 } 316 return MethodUtils.invokeMethod(getImplementation(), name, params, parameterTypes); 317 } 318 catch (ClassNotFoundException e) { 319 throw new ReflectionException (e); 320 } 321 catch (NoSuchMethodException e) { 322 throw new ReflectionException (e); 323 } 324 catch (IllegalAccessException e) { 325 throw new ReflectionException (e); 326 } 327 catch (InvocationTargetException e) { 328 Throwable t = e.getTargetException(); 329 if (t instanceof Exception ) { 330 throw new MBeanException ((Exception )t); 331 } else { 332 throw new MBeanException (e); 333 } 334 } 335 } 336 337 private final static Hashtable primitiveClasses = new Hashtable (8); 338 { 339 primitiveClasses.put(Boolean.TYPE.toString(), Boolean.TYPE); 340 primitiveClasses.put(Character.TYPE.toString(), Character.TYPE); 341 primitiveClasses.put(Byte.TYPE.toString(), Byte.TYPE); 342 primitiveClasses.put(Short.TYPE.toString(), Short.TYPE); 343 primitiveClasses.put(Integer.TYPE.toString(), Integer.TYPE); 344 primitiveClasses.put(Long.TYPE.toString(), Long.TYPE); 345 primitiveClasses.put(Float.TYPE.toString(), Float.TYPE); 346 primitiveClasses.put(Double.TYPE.toString(), Double.TYPE); 347 } 348 349 357 public ObjectName preRegister(MBeanServer mbs,ObjectName on) throws Exception { 358 if(mbs != null){ 359 this.beanServer = mbs; 360 } 361 if(on != null){ 362 this.objectName = on; 363 } 364 return on; 365 } 366 367 372 public void postRegister(Boolean done) { 373 } 374 375 380 public void preDeregister() throws Exception { 381 } 382 383 386 public void postDeregister() { 387 } 388 389 394 public void sendNotification(final Notification notification) throws MBeanException , RuntimeOperationsException { 395 if (notification != null) { 396 if (!executorService.isShutdown()) { 397 executorService.execute(new Runnable () { 398 public void run() { 399 broadcasterSupport.sendNotification(notification); 400 } 401 }); 402 } 403 } 404 } 405 406 411 public void sendNotification(String text) throws MBeanException , RuntimeOperationsException { 412 if (text != null) { 413 Notification myNtfyObj = new Notification ("jmx.modelmbean.generic", this, 1, text); 414 sendNotification(myNtfyObj); 415 } 416 } 417 418 426 public void addAttributeChangeNotificationListener(NotificationListener l, String attrName, Object handback) 427 throws MBeanException , RuntimeOperationsException , IllegalArgumentException { 428 AttributeChangeNotificationFilter currFilter = new AttributeChangeNotificationFilter (); 429 currFilter.enableAttribute(attrName); 430 broadcasterSupport.addNotificationListener(l, currFilter, handback); 431 } 432 433 440 public void removeAttributeChangeNotificationListener(NotificationListener l, String attrName) 441 throws MBeanException , RuntimeOperationsException , ListenerNotFoundException { 442 broadcasterSupport.removeNotificationListener(l); 443 } 444 445 450 public void sendAttributeChangeNotification(AttributeChangeNotification notification) throws MBeanException , 451 RuntimeOperationsException { 452 sendNotification(notification); 453 } 454 455 461 public void sendAttributeChangeNotification(Attribute oldAttr, Attribute newAttr) throws MBeanException , 462 RuntimeOperationsException { 463 if (!oldAttr.equals(newAttr)) { 464 AttributeChangeNotification notification = new AttributeChangeNotification (objectName, 1, ((new Date ()) 465 .getTime()), "AttributeChange", oldAttr.getName(), (((newAttr.getValue()).getClass()).toString()), 466 oldAttr.getValue(), newAttr.getValue()); 467 sendAttributeChangeNotification(notification); 468 } 469 } 470 471 474 public MBeanNotificationInfo [] getNotificationInfo() { 475 MBeanNotificationInfo [] result = new MBeanNotificationInfo [2]; 476 Descriptor genericDescriptor = new DescriptorSupport (new String []{"name=GENERIC", 477 "descriptorType=notification", "log=T", "severity=5", "displayName=jmx.modelmbean.generic"}); 478 result[0] = new ModelMBeanNotificationInfo (new String []{"jmx.modelmbean.generic"}, "GENERIC", 479 "A text notification has been issued by the managed resource", genericDescriptor); 480 Descriptor attributeDescriptor = new DescriptorSupport (new String []{"name=ATTRIBUTE_CHANGE", 481 "descriptorType=notification", "log=T", "severity=5", "displayName=jmx.attribute.change"}); 482 result[1] = new ModelMBeanNotificationInfo (new String []{"jmx.attribute.change"}, "ATTRIBUTE_CHANGE", 483 "Signifies that an observed MBean attribute value has changed", attributeDescriptor); 484 return result; 485 } 486 487 493 public void addNotificationListener(NotificationListener l, NotificationFilter filter, Object handle) 494 throws IllegalArgumentException { 495 broadcasterSupport.addNotificationListener(l, filter, handle); 496 } 497 498 502 public void removeNotificationListener(NotificationListener l) throws ListenerNotFoundException { 503 broadcasterSupport.removeNotificationListener(l); 504 } 505 506 private Object getCurrentValue(CachedAttribute ca) throws MBeanException { 507 Object result = null; 508 if (ca != null) { 509 try { 510 result = beanUtil.getProperty(ca.getBean(), ca.getName()); 511 } 512 catch (IllegalAccessException e) { 513 throw new MBeanException (e); 514 } 515 catch (InvocationTargetException e) { 516 throw new MBeanException (e); 517 } 518 catch (NoSuchMethodException e) { 519 throw new MBeanException (e); 520 } 521 } 522 return result; 523 } 524 525 532 private void buildAttributes(Object obj, MBeanAttributeInfo [] attrs) throws ReflectionException { 533 if (attrs != null) { 534 for (int i = 0;i < attrs.length;i++) { 535 try { 536 String name = attrs[i].getName(); 537 PropertyDescriptor pd = beanUtil.getPropertyDescriptor(obj, name); 538 Object value = beanUtil.getProperty(obj, name); 539 Attribute attribute = new Attribute (name, value); 540 CachedAttribute ca = new CachedAttribute(attribute); 541 ca.setBean(obj); 542 ca.setPropertyDescriptor(pd); 543 cachedAttributes.put(name, ca); 544 } 545 catch (NoSuchMethodException e) { 546 throw new ReflectionException (e); 547 } 548 catch (IllegalAccessException e) { 549 throw new ReflectionException (e); 550 } 551 catch (InvocationTargetException e) { 552 throw new ReflectionException (e); 553 } 554 } 555 } 556 } 557 } | Popular Tags |