001 /* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 018 019 package org.apache.commons.modeler; 020 021 022 import java.util.ArrayList; 023 import java.util.Iterator; 024 import java.util.List; 025 026 import javax.management.Descriptor; 027 import javax.management.InstanceNotFoundException; 028 import javax.management.MBeanException; 029 import javax.management.RuntimeOperationsException; 030 import javax.management.modelmbean.InvalidTargetObjectTypeException; 031 import javax.management.modelmbean.ModelMBean; 032 import javax.management.modelmbean.ModelMBeanAttributeInfo; 033 import javax.management.modelmbean.ModelMBeanConstructorInfo; 034 import javax.management.modelmbean.ModelMBeanInfo; 035 import javax.management.modelmbean.ModelMBeanInfoSupport; 036 import javax.management.modelmbean.ModelMBeanNotificationInfo; 037 import javax.management.modelmbean.ModelMBeanOperationInfo; 038 039 040 /** 041 * <p>Internal configuration information for a managed bean (MBean) 042 * descriptor.</p> 043 * 044 * @author Craig R. McClanahan 045 * @version $Revision: 480402 $ $Date: 2006-11-29 05:43:23 +0100 (Wed, 29 Nov 2006) $ 046 */ 047 048 public class ManagedBean implements java.io.Serializable 049 { 050 // ----------------------------------------------------- Instance Variables 051 052 053 /** 054 * The <code>ModelMBeanInfo</code> object that corresponds 055 * to this <code>ManagedBean</code> instance. 056 */ 057 transient ModelMBeanInfo info = null; 058 protected AttributeInfo attributes[] = new AttributeInfo[0]; 059 protected String className = 060 "org.apache.commons.modeler.BaseModelMBean"; 061 protected ConstructorInfo constructors[] = new ConstructorInfo[0]; 062 protected String description = null; 063 protected String domain = null; 064 protected String group = null; 065 protected String name = null; 066 067 protected List fields = new ArrayList(); 068 protected NotificationInfo notifications[] = new NotificationInfo[0]; 069 protected OperationInfo operations[] = new OperationInfo[0]; 070 protected String type = null; 071 072 /** Constructor. Will add default attributes. 073 * 074 */ 075 public ManagedBean() { 076 AttributeInfo ai=new AttributeInfo(); 077 ai.setName("modelerType"); 078 ai.setDescription("Type of the modeled resource. Can be set only once"); 079 ai.setType("java.lang.String"); 080 ai.setWriteable(false); 081 addAttribute(ai); 082 } 083 084 // ------------------------------------------------------------- Properties 085 086 087 /** 088 * The collection of attributes for this MBean. 089 */ 090 public AttributeInfo[] getAttributes() { 091 return (this.attributes); 092 } 093 094 095 /** 096 * The fully qualified name of the Java class of the MBean 097 * described by this descriptor. If not specified, the standard JMX 098 * class (<code>javax.management.modelmbean.RequiredModeLMBean</code>) 099 * will be utilized. 100 */ 101 public String getClassName() { 102 return (this.className); 103 } 104 105 public void setClassName(String className) { 106 this.className = className; 107 this.info = null; 108 } 109 110 111 /** 112 * The collection of constructors for this MBean. 113 */ 114 public ConstructorInfo[] getConstructors() { 115 return (this.constructors); 116 } 117 118 119 /** 120 * The human-readable description of this MBean. 121 */ 122 public String getDescription() { 123 return (this.description); 124 } 125 126 public void setDescription(String description) { 127 this.description = description; 128 this.info = null; 129 } 130 131 132 /** 133 * The (optional) <code>ObjectName</code> domain in which this MBean 134 * should be registered in the MBeanServer. 135 */ 136 public String getDomain() { 137 return (this.domain); 138 } 139 140 public void setDomain(String domain) { 141 this.domain = domain; 142 } 143 144 145 /** 146 * <p>Return a <code>List</code> of the {@link FieldInfo} objects for 147 * the name/value pairs that should be 148 * added to the Descriptor created from this metadata.</p> 149 */ 150 public List getFields() { 151 return (this.fields); 152 } 153 154 155 /** 156 * The (optional) group to which this MBean belongs. 157 */ 158 public String getGroup() { 159 return (this.group); 160 } 161 162 public void setGroup(String group) { 163 this.group = group; 164 } 165 166 167 /** 168 * The name of this managed bean, which must be unique among all 169 * MBeans managed by a particular MBeans server. 170 */ 171 public String getName() { 172 return (this.name); 173 } 174 175 public void setName(String name) { 176 this.name = name; 177 this.info = null; 178 } 179 180 181 /** 182 * The collection of notifications for this MBean. 183 */ 184 public NotificationInfo[] getNotifications() { 185 return (this.notifications); 186 } 187 188 189 /** 190 * The collection of operations for this MBean. 191 */ 192 public OperationInfo[] getOperations() { 193 return (this.operations); 194 } 195 196 197 /** 198 * The fully qualified name of the Java class of the resource 199 * implementation class described by the managed bean described 200 * by this descriptor. 201 */ 202 public String getType() { 203 return (this.type); 204 } 205 206 public void setType(String type) { 207 this.type = type; 208 this.info = null; 209 } 210 211 212 // --------------------------------------------------------- Public Methods 213 214 215 /** 216 * Add a new attribute to the set of attributes for this MBean. 217 * 218 * @param attribute The new attribute descriptor 219 */ 220 public void addAttribute(AttributeInfo attribute) { 221 222 synchronized (attributes) { 223 AttributeInfo results[] = 224 new AttributeInfo[attributes.length + 1]; 225 System.arraycopy(attributes, 0, results, 0, attributes.length); 226 results[attributes.length] = attribute; 227 attributes = results; 228 this.info = null; 229 } 230 231 } 232 233 234 /** 235 * Add a new constructor to the set of constructors for this MBean. 236 * 237 * @param constructor The new constructor descriptor 238 */ 239 public void addConstructor(ConstructorInfo constructor) { 240 241 synchronized (constructors) { 242 ConstructorInfo results[] = 243 new ConstructorInfo[constructors.length + 1]; 244 System.arraycopy(constructors, 0, results, 0, constructors.length); 245 results[constructors.length] = constructor; 246 constructors = results; 247 this.info = null; 248 } 249 250 } 251 252 253 /** 254 * <p>Add a new field to the fields associated with the 255 * Descriptor that will be created from this metadata.</p> 256 * 257 * @param field The field to be added 258 */ 259 public void addField(FieldInfo field) { 260 fields.add(field); 261 } 262 263 264 /** 265 * Add a new notification to the set of notifications for this MBean. 266 * 267 * @param notification The new notification descriptor 268 */ 269 public void addNotification(NotificationInfo notification) { 270 271 synchronized (notifications) { 272 NotificationInfo results[] = 273 new NotificationInfo[notifications.length + 1]; 274 System.arraycopy(notifications, 0, results, 0, 275 notifications.length); 276 results[notifications.length] = notification; 277 notifications = results; 278 this.info = null; 279 } 280 281 } 282 283 284 /** 285 * Add a new operation to the set of operations for this MBean. 286 * 287 * @param operation The new operation descriptor 288 */ 289 public void addOperation(OperationInfo operation) { 290 synchronized (operations) { 291 OperationInfo results[] = 292 new OperationInfo[operations.length + 1]; 293 System.arraycopy(operations, 0, results, 0, operations.length); 294 results[operations.length] = operation; 295 operations = results; 296 this.info = null; 297 } 298 299 } 300 301 302 /** 303 * Create and return a <code>ModelMBean</code> that has been 304 * preconfigured with the <code>ModelMBeanInfo</code> information 305 * for this managed bean, but is not associated with any particular 306 * managed resource. The returned <code>ModelMBean</code> will 307 * <strong>NOT</strong> have been registered with our 308 * <code>MBeanServer</code>. 309 * 310 * @exception InstanceNotFoundException if the managed resource 311 * object cannot be found 312 * @exception InvalidTargetObjectTypeException if our MBean cannot 313 * handle object references (should never happen) 314 * @exception MBeanException if a problem occurs instantiating the 315 * <code>ModelMBean</code> instance 316 * @exception RuntimeOperationsException if a JMX runtime error occurs 317 */ 318 public ModelMBean createMBean() 319 throws InstanceNotFoundException, 320 InvalidTargetObjectTypeException, 321 MBeanException, RuntimeOperationsException { 322 323 return (createMBean(null)); 324 325 } 326 327 328 /** 329 * Create and return a <code>ModelMBean</code> that has been 330 * preconfigured with the <code>ModelMBeanInfo</code> information 331 * for this managed bean, and is associated with the specified 332 * managed object instance. The returned <code>ModelMBean</code> 333 * will <strong>NOT</strong> have been registered with our 334 * <code>MBeanServer</code>. 335 * 336 * @param instance Instanced of the managed object, or <code>null</code> 337 * for no associated instance 338 * 339 * @exception InstanceNotFoundException if the managed resource 340 * object cannot be found 341 * @exception InvalidTargetObjectTypeException if our MBean cannot 342 * handle object references (should never happen) 343 * @exception MBeanException if a problem occurs instantiating the 344 * <code>ModelMBean</code> instance 345 * @exception RuntimeOperationsException if a JMX runtime error occurs 346 */ 347 public ModelMBean createMBean(Object instance) 348 throws InstanceNotFoundException, 349 InvalidTargetObjectTypeException, 350 MBeanException, RuntimeOperationsException { 351 352 // Load the ModelMBean implementation class 353 Class clazz = null; 354 Exception ex = null; 355 try { 356 clazz = Class.forName(getClassName()); 357 } catch (Exception e) { 358 } 359 360 if( clazz==null ) { 361 try { 362 ClassLoader cl= Thread.currentThread().getContextClassLoader(); 363 if ( cl != null) 364 clazz= cl.loadClass(getClassName()); 365 } catch (Exception e) { 366 ex=e; 367 } 368 } 369 370 if( clazz==null) { 371 throw new MBeanException 372 (ex, "Cannot load ModelMBean class " + getClassName()); 373 } 374 375 // Create a new ModelMBean instance 376 ModelMBean mbean = null; 377 try { 378 mbean = (ModelMBean) clazz.newInstance(); 379 mbean.setModelMBeanInfo(createMBeanInfo()); 380 } catch (MBeanException e) { 381 throw e; 382 } catch (RuntimeOperationsException e) { 383 throw e; 384 } catch (Exception e) { 385 throw new MBeanException 386 (e, "Cannot instantiate ModelMBean of class " + 387 getClassName()); 388 } 389 390 // Set the managed resource (if any) 391 try { 392 if (instance != null) 393 mbean.setManagedResource(instance, "ObjectReference"); 394 } catch (InstanceNotFoundException e) { 395 throw e; 396 } catch (InvalidTargetObjectTypeException e) { 397 throw e; 398 } 399 return (mbean); 400 401 } 402 403 404 /** 405 * Create and return a <code>ModelMBeanInfo</code> object that 406 * describes this entire managed bean. 407 */ 408 public ModelMBeanInfo createMBeanInfo() { 409 410 // Return our cached information (if any) 411 if (info != null) 412 return (info); 413 414 // Create subordinate information descriptors as required 415 AttributeInfo attrs[] = getAttributes(); 416 ModelMBeanAttributeInfo attributes[] = 417 new ModelMBeanAttributeInfo[attrs.length]; 418 for (int i = 0; i < attrs.length; i++) 419 attributes[i] = attrs[i].createAttributeInfo(); 420 421 ConstructorInfo consts[] = getConstructors(); 422 ModelMBeanConstructorInfo constructors[] = 423 new ModelMBeanConstructorInfo[consts.length]; 424 for (int i = 0; i < consts.length; i++) 425 constructors[i] = consts[i].createConstructorInfo(); 426 NotificationInfo notifs[] = getNotifications(); 427 ModelMBeanNotificationInfo notifications[] = 428 new ModelMBeanNotificationInfo[notifs.length]; 429 for (int i = 0; i < notifs.length; i++) 430 notifications[i] = notifs[i].createNotificationInfo(); 431 OperationInfo opers[] = getOperations(); 432 ModelMBeanOperationInfo operations[] = 433 new ModelMBeanOperationInfo[opers.length]; 434 for (int i = 0; i < opers.length; i++) 435 operations[i] = opers[i].createOperationInfo(); 436 437 /* 438 // Add operations for attribute getters and setters as needed 439 ArrayList list = new ArrayList(); 440 for (int i = 0; i < operations.length; i++) 441 list.add(operations[i]); 442 for (int i = 0; i < attributes.length; i++) { 443 Descriptor descriptor = attributes[i].getDescriptor(); 444 String getMethod = (String) descriptor.getFieldValue("getMethod"); 445 if (getMethod != null) { 446 OperationInfo oper = 447 new OperationInfo(getMethod, true, 448 attributes[i].getType()); 449 list.add(oper.createOperationInfo()); 450 } 451 String setMethod = (String) descriptor.getFieldValue("setMethod"); 452 if (setMethod != null) { 453 OperationInfo oper = 454 new OperationInfo(setMethod, false, 455 attributes[i].getType()); 456 list.add(oper.createOperationInfo()); 457 } 458 } 459 if (list.size() > operations.length) 460 operations = 461 (ModelMBeanOperationInfo[]) list.toArray(operations); 462 */ 463 464 // Construct and return a new ModelMBeanInfo object 465 info = new ModelMBeanInfoSupport 466 (getClassName(), getDescription(), 467 attributes, constructors, operations, notifications); 468 try { 469 Descriptor descriptor = info.getMBeanDescriptor(); 470 Iterator fields = getFields().iterator(); 471 while (fields.hasNext()) { 472 FieldInfo field = (FieldInfo) fields.next(); 473 descriptor.setField(field.getName(), field.getValue()); 474 } 475 info.setMBeanDescriptor(descriptor); 476 } catch (MBeanException e) { 477 ; 478 } 479 480 return (info); 481 482 } 483 484 485 /** 486 * Return a string representation of this managed bean. 487 */ 488 public String toString() { 489 490 StringBuffer sb = new StringBuffer("ManagedBean["); 491 sb.append("name="); 492 sb.append(name); 493 sb.append(", className="); 494 sb.append(className); 495 sb.append(", description="); 496 sb.append(description); 497 if (group != null) { 498 sb.append(", group="); 499 sb.append(group); 500 } 501 sb.append(", type="); 502 sb.append(type); 503 sb.append("]"); 504 return (sb.toString()); 505 506 } 507 508 509 }