| 1 16 17 18 package org.apache.commons.modeler; 19 20 21 import java.lang.reflect.InvocationTargetException ; 22 import java.lang.reflect.Method ; 23 import java.util.HashMap ; 24 import java.util.Hashtable ; 25 import java.util.Iterator ; 26 27 import javax.management.Attribute ; 28 import javax.management.AttributeChangeNotification ; 29 import javax.management.AttributeList ; 30 import javax.management.AttributeNotFoundException ; 31 import javax.management.Descriptor ; 32 import javax.management.DynamicMBean ; 33 import javax.management.InstanceNotFoundException ; 34 import javax.management.InvalidAttributeValueException ; 35 import javax.management.ListenerNotFoundException ; 36 import javax.management.MBeanException ; 37 import javax.management.MBeanInfo ; 38 import javax.management.MBeanNotificationInfo ; 39 import javax.management.MBeanRegistration ; 40 import javax.management.MBeanServer ; 41 import javax.management.Notification ; 42 import javax.management.NotificationFilter ; 43 import javax.management.NotificationListener ; 44 import javax.management.ObjectName ; 45 import javax.management.ReflectionException ; 46 import javax.management.RuntimeErrorException ; 47 import javax.management.RuntimeOperationsException ; 48 import javax.management.ServiceNotFoundException ; 49 import javax.management.modelmbean.DescriptorSupport ; 50 import javax.management.modelmbean.InvalidTargetObjectTypeException ; 51 import javax.management.modelmbean.ModelMBean ; 52 import javax.management.modelmbean.ModelMBeanAttributeInfo ; 53 import javax.management.modelmbean.ModelMBeanInfo ; 54 import javax.management.modelmbean.ModelMBeanInfoSupport ; 55 import javax.management.modelmbean.ModelMBeanNotificationInfo ; 56 import javax.management.modelmbean.ModelMBeanOperationInfo ; 57 58 import org.apache.commons.logging.Log; 59 import org.apache.commons.logging.LogFactory; 60 import org.apache.commons.modeler.modules.ModelerSource; 61 62 64 97 98 public class BaseModelMBean implements ModelMBean , MBeanRegistration { 99 private static Log log = LogFactory.getLog(BaseModelMBean.class); 100 101 103 112 public BaseModelMBean() throws MBeanException , RuntimeOperationsException { 113 114 super(); 115 if( log.isDebugEnabled()) log.debug("default constructor"); 116 setModelMBeanInfo(createDefaultModelMBeanInfo()); 117 } 118 119 120 131 public BaseModelMBean(ModelMBeanInfo info) 132 throws MBeanException , RuntimeOperationsException { 133 super(); 135 setModelMBeanInfo(info); 136 if( log.isDebugEnabled()) log.debug("ModelMBeanInfo constructor"); 137 } 138 139 151 public BaseModelMBean( String type ) 152 throws MBeanException , RuntimeOperationsException  153 { 154 try { 155 setModeledType(type); 158 } catch( Throwable ex ) { 159 log.error( "Error creating mbean ", ex); 160 } 161 } 162 163 public BaseModelMBean( String type, ModelerSource source ) 164 throws MBeanException , RuntimeOperationsException  165 { 166 try { 167 setModeledType(type); 168 } catch( Throwable ex ) { 169 log.error( "Error creating mbean ", ex); 170 } 171 this.source=source; 172 } 173 174 176 177 180 protected BaseNotificationBroadcaster attributeBroadcaster = null; 181 182 184 protected Registry registry=null; 185 186 189 protected BaseNotificationBroadcaster generalBroadcaster = null; 190 191 protected ObjectName oname=null; 192 193 196 protected ModelMBeanInfo info = null; 197 198 199 202 protected Object resource = null; 203 protected String resourceType = null; 204 205 208 protected ModelerSource source=null; 209 210 212 protected HashMap attributes=new HashMap (); 213 214 static final Object [] NO_ARGS_PARAM=new Object [0]; 216 static final Class [] NO_ARGS_PARAM_SIG=new Class [0]; 217 private Hashtable getAttMap=new Hashtable (); 219 220 private Hashtable setAttMap=new Hashtable (); 222 223 private Hashtable invokeAttMap=new Hashtable (); 225 226 238 public Object getAttribute(String name) 239 throws AttributeNotFoundException , MBeanException , 240 ReflectionException { 241 if (name == null) 243 throw new RuntimeOperationsException  244 (new IllegalArgumentException ("Attribute name is null"), 245 "Attribute name is null"); 246 247 if( (resource instanceof DynamicMBean ) && 248 ! ( resource instanceof BaseModelMBean )) { 249 return ((DynamicMBean )resource).getAttribute(name); 250 } 251 252 Method m=(Method )getAttMap.get( name ); 254 255 if( m==null ) { 256 ModelMBeanAttributeInfo attrInfo = info.getAttribute(name); 258 if (attrInfo == null) 259 throw new AttributeNotFoundException (" Cannot find attribute " + name); 260 Descriptor attrDesc = attrInfo.getDescriptor(); 261 if (attrDesc == null) 262 throw new AttributeNotFoundException ("Cannot find attribute " + name + " descriptor"); 263 String getMethod = (String ) attrDesc.getFieldValue("getMethod"); 264 265 if (getMethod == null) 266 throw new AttributeNotFoundException ("Cannot find attribute " + name + " get method name"); 267 268 Object object = null; 269 NoSuchMethodException exception = null; 270 try { 271 object = this; 272 m = object.getClass().getMethod(getMethod, NO_ARGS_PARAM_SIG); 273 } catch (NoSuchMethodException e) { 274 exception = e;; 275 } 276 if( m== null && resource != null ) { 277 try { 278 object = resource; 279 m = object.getClass().getMethod(getMethod, NO_ARGS_PARAM_SIG); 280 exception=null; 281 } catch (NoSuchMethodException e) { 282 exception = e; 283 } 284 } 285 if( exception != null ) 286 throw new ReflectionException (exception, 287 "Cannot find getter method " + getMethod); 288 getAttMap.put( name, m ); 289 } 290 291 Object result = null; 292 try { 293 Class declaring=m.getDeclaringClass(); 294 if( declaring.isAssignableFrom(this.getClass()) ) { 297 result = m.invoke(this, NO_ARGS_PARAM ); 298 } else { 299 result = m.invoke(resource, NO_ARGS_PARAM ); 300 } 301 } catch (InvocationTargetException e) { 302 Throwable t = e.getTargetException(); 303 if (t == null) 304 t = e; 305 if (t instanceof RuntimeException ) 306 throw new RuntimeOperationsException  307 ((RuntimeException ) t, "Exception invoking method " + name); 308 else if (t instanceof Error ) 309 throw new RuntimeErrorException  310 ((Error ) t, "Error invoking method " + name); 311 else 312 throw new MBeanException  313 (e, "Exception invoking method " + name); 314 } catch (Exception e) { 315 throw new MBeanException  316 (e, "Exception invoking method " + name); 317 } 318 319 return (result); 322 } 323 324 325 330 public AttributeList getAttributes(String names[]) { 331 332 if (names == null) 334 throw new RuntimeOperationsException  335 (new IllegalArgumentException ("Attribute names list is null"), 336 "Attribute names list is null"); 337 338 AttributeList response = new AttributeList (); 340 for (int i = 0; i < names.length; i++) { 341 try { 342 response.add(new Attribute (names[i],getAttribute(names[i]))); 343 } catch (Exception e) { 344 ; ; } 347 } 348 return (response); 349 350 } 351 352 353 356 public MBeanInfo getMBeanInfo() { 357 if( info== null ) return null; 359 return ((MBeanInfo ) info.clone()); 360 } 361 362 363 382 public Object invoke(String name, Object params[], String signature[]) 383 throws MBeanException , ReflectionException 384 { 385 if( (resource instanceof DynamicMBean ) && 386 ! ( resource instanceof BaseModelMBean )) { 387 return ((DynamicMBean )resource).invoke(name, params, signature); 388 } 389 390 if (name == null) 392 throw new RuntimeOperationsException  393 (new IllegalArgumentException ("Method name is null"), 394 "Method name is null"); 395 396 if( log.isDebugEnabled()) log.debug("Invoke " + name); 397 Method method=(Method )invokeAttMap.get(name); 398 if( method==null ) { 399 if (params == null) 400 params = new Object [0]; 401 if (signature == null) 402 signature = new String [0]; 403 if (params.length != signature.length) 404 throw new RuntimeOperationsException  405 (new IllegalArgumentException ("Inconsistent arguments and signature"), 406 "Inconsistent arguments and signature"); 407 408 ModelMBeanOperationInfo opInfo = info.getOperation(name); 411 if (opInfo == null) 412 throw new MBeanException  413 (new ServiceNotFoundException ("Cannot find operation " + name), 414 "Cannot find operation " + name); 415 416 Class types[] = new Class [signature.length]; 419 for (int i = 0; i < signature.length; i++) { 420 types[i]=getAttributeClass( signature[i] ); 421 } 422 423 Object object = null; 427 Exception exception = null; 428 try { 429 object = this; 430 method = object.getClass().getMethod(name, types); 431 } catch (NoSuchMethodException e) { 432 exception = e;; 433 } 434 try { 435 if ((method == null) && (resource != null)) { 436 object = resource; 437 method = object.getClass().getMethod(name, types); 438 } 439 } catch (NoSuchMethodException e) { 440 exception = e; 441 } 442 if (method == null) { 443 throw new ReflectionException (exception, 444 "Cannot find method " + name + 445 " with this signature"); 446 } 447 invokeAttMap.put( name, method ); 448 } 449 450 Object result = null; 452 try { 453 if( method.getDeclaringClass().isAssignableFrom( this.getClass()) ) { 454 result = method.invoke(this, params ); 455 } else { 456 result = method.invoke(resource, params); 457 } 458 } catch (InvocationTargetException e) { 459 Throwable t = e.getTargetException(); 460 log.error("Exception invoking method " + name , t ); 461 if (t == null) 462 t = e; 463 if (t instanceof RuntimeException ) 464 throw new RuntimeOperationsException  465 ((RuntimeException ) t, "Exception invoking method " + name); 466 else if (t instanceof Error ) 467 throw new RuntimeErrorException  468 ((Error ) t, "Error invoking method " + name); 469 else 470 throw new MBeanException  471 ((Exception )t, "Exception invoking method " + name); 472 } catch (Exception e) { 473 log.error("Exception invoking method " + name , e ); 474 throw new MBeanException  475 (e, "Exception invoking method " + name); 476 } 477 478 return (result); 481 482 } 483 484 private Class getAttributeClass(String signature) 485 throws ReflectionException  486 { 487 if (signature.equals(Boolean.TYPE.getName())) 488 return Boolean.TYPE; 489 else if (signature.equals(Byte.TYPE.getName())) 490 return Byte.TYPE; 491 else if (signature.equals(Character.TYPE.getName())) 492 return Character.TYPE; 493 else if (signature.equals(Double.TYPE.getName())) 494 return Double.TYPE; 495 else if (signature.equals(Float.TYPE.getName())) 496 return Float.TYPE; 497 else if (signature.equals(Integer.TYPE.getName())) 498 return Integer.TYPE; 499 else if (signature.equals(Long.TYPE.getName())) 500 return Long.TYPE; 501 else if (signature.equals(Short.TYPE.getName())) 502 return Short.TYPE; 503 else { 504 try { 505 ClassLoader cl=Thread.currentThread().getContextClassLoader(); 506 if( cl!=null ) 507 return cl.loadClass(signature); 508 } catch( ClassNotFoundException e ) { 509 } 510 try { 511 return Class.forName(signature); 512 } catch (ClassNotFoundException e) { 513 throw new ReflectionException  514 (e, "Cannot find Class for " + signature); 515 } 516 } 517 } 518 519 532 public void setAttribute(Attribute attribute) 533 throws AttributeNotFoundException , MBeanException , 534 ReflectionException  535 { 536 if( log.isDebugEnabled() ) 537 log.debug("Setting attribute " + this + " " + attribute ); 538 539 if( (resource instanceof DynamicMBean ) && 540 ! ( resource instanceof BaseModelMBean )) { 541 try { 542 ((DynamicMBean )resource).setAttribute(attribute); 543 } catch (InvalidAttributeValueException e) { 544 throw new MBeanException (e); 545 } 546 return; 547 } 548 549 if (attribute == null) 551 throw new RuntimeOperationsException  552 (new IllegalArgumentException ("Attribute is null"), 553 "Attribute is null"); 554 555 String name = attribute.getName(); 556 Object value = attribute.getValue(); 557 558 if (name == null) 559 throw new RuntimeOperationsException  560 (new IllegalArgumentException ("Attribute name is null"), 561 "Attribute name is null"); 562 563 ModelMBeanAttributeInfo attrInfo=info.getAttribute(name); 564 if (attrInfo == null) 565 throw new AttributeNotFoundException ("Cannot find attribute " + name); 566 567 Descriptor attrDesc=attrInfo.getDescriptor(); 568 if (attrDesc == null) 569 throw new AttributeNotFoundException ("Cannot find attribute " + name + " descriptor"); 570 571 try { 572 Object oldValue=null; 574 if( getAttMap.get(name) != null ) 575 oldValue=getAttribute( name ); 576 sendAttributeChangeNotification(new Attribute ( name, oldValue), 577 attribute); 578 } catch( Exception ex ) { 579 log.error( "Error sending notification " + name, ex ); 580 } 581 582 Method m=(Method )setAttMap.get( name ); 584 585 if( m==null ) { 586 String setMethod = (String ) attrDesc.getFieldValue("setMethod"); 588 if (setMethod == null) 589 throw new AttributeNotFoundException ("Cannot find attribute " + name + " set method name"); 590 591 String argType=attrInfo.getType(); 592 593 Class signature[] = new Class [] { getAttributeClass( argType ) }; 594 595 Object object = null; 596 NoSuchMethodException exception = null; 597 try { 598 object = this; 599 m = object.getClass().getMethod(setMethod, signature); 600 } catch (NoSuchMethodException e) { 601 exception = e;; 602 } 603 if( m== null && resource != null ) { 604 try { 605 object = resource; 606 m = object.getClass().getMethod(setMethod, signature); 607 exception=null; 608 } catch (NoSuchMethodException e) { 609 if( log.isDebugEnabled()) 610 log.debug("Method not found in resource " +resource); 611 exception = e; 612 } 613 } 614 if( exception != null ) 615 throw new ReflectionException (exception, 616 "Cannot find setter method " + setMethod + 617 " " + resource); 618 setAttMap.put( name, m ); 619 } 620 621 Object result = null; 622 try { 623 if( m.getDeclaringClass().isAssignableFrom( this.getClass()) ) { 624 result = m.invoke(this, new Object [] { value }); 625 } else { 626 result = m.invoke(resource, new Object [] { value }); 627 } 628 } catch (InvocationTargetException e) { 629 Throwable t = e.getTargetException(); 630 if (t == null) 631 t = e; 632 if (t instanceof RuntimeException ) 633 throw new RuntimeOperationsException  634 ((RuntimeException ) t, "Exception invoking method " + name); 635 else if (t instanceof Error ) 636 throw new RuntimeErrorException  637 ((Error ) t, "Error invoking method " + name); 638 else 639 throw new MBeanException  640 (e, "Exception invoking method " + name); 641 } catch (Exception e) { 642 log.error("Exception invoking method " + name , e ); 643 throw new MBeanException  644 (e, "Exception invoking method " + name); 645 } 646 647 attributes.put( name, value ); 648 if( source != null ) { 649 source.updateField(oname, name, value); 651 } 652 } 653 654 public String toString() { 655 if( resource==null ) 656 return "BaseModelMbean[" + resourceType + "]"; 657 return resource.toString();
|