1 22 package org.jboss.mx.metadata; 23 24 import java.beans.IntrospectionException ; 25 import java.beans.PropertyEditor ; 26 import java.beans.PropertyEditorManager ; 27 import java.util.ArrayList ; 28 import java.util.Iterator ; 29 import java.util.List ; 30 import java.util.Map ; 31 32 import javax.management.Descriptor ; 33 import javax.management.MBeanInfo ; 34 import javax.management.MBeanOperationInfo ; 35 import javax.management.MBeanParameterInfo ; 36 import javax.management.NotCompliantMBeanException ; 37 import javax.management.modelmbean.DescriptorSupport ; 38 import javax.management.modelmbean.ModelMBeanAttributeInfo ; 39 import javax.management.modelmbean.ModelMBeanConstructorInfo ; 40 import javax.management.modelmbean.ModelMBeanInfo ; 41 import javax.management.modelmbean.ModelMBeanInfoSupport ; 42 import javax.management.modelmbean.ModelMBeanNotificationInfo ; 43 import javax.management.modelmbean.ModelMBeanOperationInfo ; 44 45 import org.dom4j.Attribute; 46 import org.dom4j.Element; 47 import org.jboss.logging.Logger; 48 import org.jboss.mx.modelmbean.XMBeanConstants; 49 import org.jboss.mx.util.JBossNotCompliantMBeanException; 50 import org.jboss.util.Classes; 51 import org.jboss.util.StringPropertyReplacer; 52 import org.jboss.util.propertyeditor.PropertyEditors; 53 import org.w3c.dom.Node ; 54 import org.w3c.dom.NodeList ; 55 56 64 public class JBossXMBean10 extends AbstractBuilder 65 implements XMBeanConstants 66 { 67 private static Logger log = Logger.getLogger(JBossXMBean10.class); 68 69 71 private Element element; 72 73 76 private String mmbClassName = null; 77 78 81 private String resourceClassName = null; 82 83 84 86 public JBossXMBean10(String mmbClassName, String resourceClassName, Element element, Map properties) 87 { 88 super(); 89 this.mmbClassName = mmbClassName; 90 this.resourceClassName = resourceClassName; 91 this.element = element; 92 setProperties(properties); 93 } 94 95 97 public MBeanInfo build() throws NotCompliantMBeanException 98 { 99 try 100 { 101 if (element == null) 102 { 103 throw new JBossNotCompliantMBeanException("No xml configuration supplied!"); 104 } 105 String description = element.elementTextTrim("description"); 106 107 if (resourceClassName == null) 108 { 109 resourceClassName = element.elementTextTrim("class"); 110 } 111 112 List constructors = element.elements("constructor"); 113 List operations = element.elements("operation"); 114 List attributes = element.elements("attribute"); 115 List notifications = element.elements("notification"); 116 117 Descriptor descr = getDescriptor(element, mmbClassName, MBEAN_DESCRIPTOR); 118 119 ModelMBeanInfo info = buildMBeanMetaData( 120 description, constructors, operations, 121 attributes, notifications, descr 122 ); 123 124 return (MBeanInfo ) info; 125 } 126 catch (Throwable t) 127 { 128 throw new JBossNotCompliantMBeanException("Error parsing the XML file: ", t); 129 } 130 } 131 132 133 135 protected Descriptor getDescriptor(final Element parent, final String infoName, final String type) 136 throws NotCompliantMBeanException 137 { 138 Descriptor descr = new DescriptorSupport (); 139 descr.setField(NAME, infoName); 140 descr.setField(DISPLAY_NAME, infoName); 141 descr.setField(DESCRIPTOR_TYPE, type); 142 143 Element descriptors = parent.element("descriptors"); 144 if (descriptors == null) 145 { 146 return descr; 147 } 148 149 for (Iterator i = descriptors.elementIterator(); i.hasNext();) 150 { 151 Element descriptor = (Element)i.next(); 152 String name = descriptor.getName(); 153 if (name.equals("persistence")) 154 { 155 String persistPolicy = descriptor.attributeValue(PERSIST_POLICY); 156 String persistPeriod = descriptor.attributeValue(PERSIST_PERIOD); 157 String persistLocation = descriptor.attributeValue(PERSIST_LOCATION); 158 String persistName = descriptor.attributeValue(PERSIST_NAME); 159 if (persistPolicy != null) 160 { 161 validate(persistPolicy, PERSIST_POLICIES); 162 descr.setField(PERSIST_POLICY, persistPolicy); 163 } 164 if (persistPeriod != null) 165 { 166 descr.setField(PERSIST_PERIOD, persistPeriod); 167 } 168 if (persistLocation != null) 169 { 170 descr.setField(PERSIST_LOCATION, persistLocation); 171 } 172 if (persistName != null) 173 { 174 descr.setField(PERSIST_NAME, persistName); 175 } 176 } 177 else if (name.equals(CURRENCY_TIME_LIMIT)) 178 { 179 descr.setField(CURRENCY_TIME_LIMIT, descriptor.attributeValue("value")); 180 } 181 else if (name.equals(DEFAULT)) 182 { 183 String value = descriptor.attributeValue("value"); 184 descr.setField(DEFAULT, value); 185 } 186 else if (name.equals("display-name")) { 188 String value = descriptor.attributeValue("value"); 189 descr.setField(DISPLAY_NAME, value); 190 } 191 else if (name.equals(CACHED_VALUE)) 192 { 193 String value = descriptor.attributeValue("value"); 194 descr.setField(CACHED_VALUE, value); 195 } 196 else if (name.equals(PERSISTENCE_MANAGER)) 197 { 198 descr.setField(PERSISTENCE_MANAGER, descriptor.attributeValue("value")); 199 } 200 else if (name.equals(DESCRIPTOR)) 201 { 202 descr.setField(descriptor.attributeValue("name"), descriptor.attributeValue("value")); 203 } 204 else if (name.equals("injection")) 205 { 206 descr.setField(descriptor.attributeValue("id"), descriptor.attributeValue("setMethod")); 207 } 208 else if(name.equals(INTERCEPTORS)) 209 { 210 Descriptor [] interceptorDescriptors = buildInterceptors(descriptor); 211 descr.setField(INTERCEPTORS, interceptorDescriptors); 212 } 213 } 215 return descr; 216 } 217 218 private void validate(String value, String [] valid) throws NotCompliantMBeanException 219 { 220 for (int i = 0; i< valid.length; i++) 221 { 222 if (valid[i].equalsIgnoreCase(value)) 223 { 224 return; 225 } } throw new JBossNotCompliantMBeanException("Unknown descriptor value: " + value); 228 } 229 230 231 233 protected ModelMBeanInfo buildMBeanMetaData(String description, 234 List constructors, List operations, List attributes, 235 List notifications, Descriptor descr) 236 throws NotCompliantMBeanException 237 { 238 239 ModelMBeanOperationInfo [] operInfo = 240 buildOperationInfo(operations); 241 ModelMBeanAttributeInfo [] attrInfo = 242 buildAttributeInfo(attributes); 243 ModelMBeanConstructorInfo [] constrInfo = 244 buildConstructorInfo(constructors); 245 ModelMBeanNotificationInfo [] notifInfo = 246 buildNotificationInfo(notifications); 247 248 ModelMBeanInfo info = new ModelMBeanInfoSupport ( 249 mmbClassName, description, attrInfo, constrInfo, 250 operInfo, notifInfo, descr 251 ); 252 253 return info; 254 } 255 256 257 protected ModelMBeanConstructorInfo [] buildConstructorInfo(List constructors) 258 throws NotCompliantMBeanException 259 { 260 261 List infos = new ArrayList (); 262 263 for (Iterator it = constructors.iterator(); it.hasNext();) 264 { 265 Element constr = (Element) it.next(); 266 String name = constr.elementTextTrim("name"); 267 String description = constr.elementTextTrim("description"); 268 List params = constr.elements("parameter"); 269 270 MBeanParameterInfo [] paramInfo = 271 buildParameterInfo(params); 272 273 Descriptor descr = getDescriptor(constr, name, OPERATION_DESCRIPTOR); 274 descr.setField(ROLE, ROLE_CONSTRUCTOR); 275 276 ModelMBeanConstructorInfo info = 277 new ModelMBeanConstructorInfo (name, description, paramInfo, descr); 278 279 infos.add(info); 280 } 281 282 return (ModelMBeanConstructorInfo []) infos.toArray( 283 new ModelMBeanConstructorInfo [0]); 284 } 285 286 protected ModelMBeanOperationInfo [] buildOperationInfo(List operations) 287 throws NotCompliantMBeanException 288 { 289 List infos = new ArrayList (); 290 291 for (Iterator it = operations.iterator(); it.hasNext(); ) 292 { 293 Element oper = (Element) it.next(); 294 String name = oper.elementTextTrim("name"); 295 String description = oper.elementTextTrim("description"); 296 String type = oper.elementTextTrim("return-type"); 297 String impact = oper.attributeValue("impact"); 298 List params = oper.elements("parameter"); 299 300 MBeanParameterInfo [] paramInfo = 301 buildParameterInfo(params); 302 303 Descriptor descr = getDescriptor(oper, name, OPERATION_DESCRIPTOR); 304 descr.setField(ROLE, ROLE_OPERATION); 305 306 int operImpact = MBeanOperationInfo.ACTION_INFO; 308 309 if (impact != null) 310 { 311 if (impact.equals(INFO)) 312 operImpact = MBeanOperationInfo.INFO; 313 else if (impact.equals(ACTION)) 314 operImpact = MBeanOperationInfo.ACTION; 315 else if (impact.equals(ACTION_INFO)) 316 operImpact = MBeanOperationInfo.ACTION_INFO; 317 } 318 319 if (type == null) 321 type = "void"; 322 323 ModelMBeanOperationInfo info = new ModelMBeanOperationInfo ( 324 name, description, paramInfo, type, operImpact, descr); 325 326 infos.add(info); 327 } 328 329 return (ModelMBeanOperationInfo []) infos.toArray( 330 new ModelMBeanOperationInfo [0]); 331 } 332 333 334 protected ModelMBeanNotificationInfo [] buildNotificationInfo(List notifications) 335 throws NotCompliantMBeanException 336 { 337 338 List infos = new ArrayList (); 339 340 for (Iterator it = notifications.iterator(); it.hasNext();) 341 { 342 Element notif = (Element) it.next(); 343 String name = notif.elementTextTrim("name"); 344 String description = notif.elementTextTrim("description"); 345 List notifTypes = notif.elements("notification-type"); 346 Descriptor descr = getDescriptor(notif, name, NOTIFICATION_DESCRIPTOR); 347 348 List types = new ArrayList (); 349 350 for (Iterator iterator = notifTypes.iterator(); iterator.hasNext();) 351 { 352 Element type = (Element) iterator.next(); 353 types.add(type.getTextTrim()); 354 } 355 356 ModelMBeanNotificationInfo info = new ModelMBeanNotificationInfo ( 357 (String []) types.toArray(new String [types.size()]), name, description, descr); 358 359 infos.add(info); 360 } 361 362 return (ModelMBeanNotificationInfo []) infos.toArray( 363 new ModelMBeanNotificationInfo [infos.size()] 364 ); 365 } 366 367 protected ModelMBeanAttributeInfo [] buildAttributeInfo(List attributes) 368 throws NotCompliantMBeanException 369 { 370 371 List infos = new ArrayList (); 372 373 for (Iterator it = attributes.iterator(); it.hasNext();) 374 { 375 Element attr = (Element) it.next(); 376 String name = attr.elementTextTrim("name"); 377 String description = attr.elementTextTrim("description"); 378 String type = attr.elementTextTrim("type"); 379 String access = attr.attributeValue("access"); 380 String getMethod = attr.attributeValue("getMethod"); 381 String setMethod = attr.attributeValue("setMethod"); 382 Descriptor descr = getDescriptor(attr, name, ATTRIBUTE_DESCRIPTOR); 383 String unconvertedValue = (String )descr.getFieldValue(CACHED_VALUE); 385 if (unconvertedValue != null && !"java.lang.String".equals(type)) 386 { 387 descr.setField(CACHED_VALUE, convertValue(unconvertedValue, type)); 388 } 389 else 390 { 391 Object value = getAttributeValue(attr, type, CACHED_VALUE); 395 if (value != null) 396 descr.setField(CACHED_VALUE, value); 397 } 398 String unconvertedDefault = (String )descr.getFieldValue(DEFAULT); 399 if (unconvertedDefault != null && !"java.lang.String".equals(type)) 400 { 401 descr.setField(DEFAULT, convertValue(unconvertedDefault, type)); 402 } 403 else 404 { 405 Object value = getAttributeValue(attr, type, DEFAULT); 409 if (value != null) 410 descr.setField(DEFAULT, value); 411 } 412 if (getMethod != null) 413 { 414 descr.setField(GET_METHOD, getMethod); 415 } 417 if (setMethod != null) 418 { 419 descr.setField(SET_METHOD, setMethod); 420 } 422 423 boolean isReadable = true; 425 boolean isWritable = true; 426 427 if (access.equalsIgnoreCase("read-only")) 428 isWritable = false; 429 430 else if (access.equalsIgnoreCase("write-only")) 431 isReadable = false; 432 433 434 ModelMBeanAttributeInfo info = new ModelMBeanAttributeInfo ( 435 name, type, description, isReadable, isWritable, false, descr 436 ); 437 438 439 infos.add(info); 440 } 441 442 return (ModelMBeanAttributeInfo []) infos.toArray( 443 new ModelMBeanAttributeInfo [0] 444 ); 445 } 446 447 451 protected Object getAttributeValue(Element attribute, String typeName, String which) 452 throws NotCompliantMBeanException 453 { 454 Object value = null; 455 456 Element descriptors = attribute.element("descriptors"); 457 if (descriptors != null) 458 { 459 for (Iterator i = descriptors.elementIterator(); i.hasNext();) 460 { 461 Element descriptor = (Element)i.next(); 463 String name = descriptor.getName(); 464 if (name.equals(which) && descriptor.hasContent()) 465 { 466 475 try 477 { 478 org.w3c.dom.Element element = toW3CElement(descriptor); 479 480 boolean replace = true; 481 boolean trim = true; 482 483 String replaceAttr = element.getAttribute("replace"); 484 if( replaceAttr.length() > 0 ) 485 replace = Boolean.valueOf(replaceAttr).booleanValue(); 486 String trimAttr = element.getAttribute("trim"); 487 if( trimAttr.length() > 0 ) 488 trim = Boolean.valueOf(trimAttr).booleanValue(); 489 490 ClassLoader cl = Thread.currentThread().getContextClassLoader(); 492 493 Class typeClass = Classes.getPrimitiveTypeForName(typeName); 495 if (typeClass == null) 496 { 497 try 499 { 500 typeClass = cl.loadClass(typeName); 501 } 502 catch (ClassNotFoundException e) 503 { 504 throw new JBossNotCompliantMBeanException 505 ("Class not found '" + typeName + "'", e); 506 } 507 } 508 509 512 if (typeClass.equals(org.w3c.dom.Element .class)) 513 { 514 NodeList nl = element.getChildNodes(); 516 for (int j=0; j < nl.getLength(); j++) 517 { 518 Node n = nl.item(j); 519 if (n.getNodeType() == Node.ELEMENT_NODE) 520 { 521 value = n; 522 break; 523 } 524 } 525 if( replace ) 527 { 528 PropertyEditor editor = PropertyEditorManager.findEditor(typeClass); 529 if( editor == null ) 530 { 531 log.warn("Cannot perform property replace on Element"); 532 } 533 else 534 { 535 editor.setValue(value); 536 String text = editor.getAsText(); 537 text = StringPropertyReplacer.replaceProperties(text); 538 editor.setAsText(text); 539 value = editor.getValue(); 540 } 541 } 542 } 543 544 if (value == null) 545 { 546 PropertyEditor editor = PropertyEditorManager.findEditor(typeClass); 547 if (editor == null) 548 { 549 throw new JBossNotCompliantMBeanException 550 ("No property editor for type '" + typeName + "'"); 551 } 552 String attributeText = getElementContent(element, trim, replace); 554 editor.setAsText(attributeText); 555 value = editor.getValue(); 556 } 557 } 558 catch (org.dom4j.DocumentException e) 559 { 560 throw new JBossNotCompliantMBeanException( 561 "cannot convert '" + which + "' descriptor to org.w3c.dom.Element", e); 562 } 563 564 break; 566 } 567 } 568 } 569 return value; 570 } 571 572 575 private org.w3c.dom.Element toW3CElement(org.dom4j.Element d4element) 576 throws org.dom4j.DocumentException 577 { 578 org.dom4j.Document d4doc = org.dom4j.DocumentFactory.getInstance().createDocument(); 580 org.dom4j.io.DOMWriter d4Writer = new org.dom4j.io.DOMWriter(); 581 d4doc.setRootElement(d4element.createCopy()); 583 org.w3c.dom.Document doc = d4Writer.write(d4doc); 585 return doc.getDocumentElement(); 587 } 588 589 592 private String getElementContent(org.w3c.dom.Element element, boolean trim, boolean replace) 593 { 594 NodeList nl = element.getChildNodes(); 595 String attributeText = ""; 596 for (int i = 0; i < nl.getLength(); i++) 597 { 598 Node n = nl.item(i); 599 if( n instanceof org.w3c.dom.Text ) 600 { 601 attributeText += ((org.w3c.dom.Text )n).getData(); 602 } 603 } if( trim ) 605 attributeText = attributeText.trim(); 606 if (replace) 607 attributeText = StringPropertyReplacer.replaceProperties(attributeText); 608 return attributeText; 609 } 610 611 620 protected Object convertValue(String unconverted, String typeName) 621 throws NotCompliantMBeanException 622 { 623 Object value = null; 624 try 625 { 626 value = PropertyEditors.convertValue(unconverted, typeName); 627 } 628 catch (ClassNotFoundException e) 629 { 630 log.debug("Failed to load type class", e); 631 throw new NotCompliantMBeanException 632 ("Class not found for type: " + typeName); 633 } 634 catch(IntrospectionException e) 635 { 636 throw new NotCompliantMBeanException 637 ("No property editor for type=" + typeName); 638 } 639 return value; 640 } 641 642 protected MBeanParameterInfo [] buildParameterInfo(List parameters) 643 { 644 Iterator it = parameters.iterator(); 645 List infos = new ArrayList (); 646 647 while (it.hasNext()) 648 { 649 Element param = (Element) it.next(); 650 String name = param.elementTextTrim("name"); 651 String type = param.elementTextTrim("type"); 652 String descr = param.elementTextTrim("description"); 653 654 MBeanParameterInfo info = new MBeanParameterInfo (name, type, descr); 655 656 infos.add(info); 657 } 658 659 return (MBeanParameterInfo []) infos.toArray(new MBeanParameterInfo [0]); 660 } 661 662 protected Descriptor [] buildInterceptors(Element descriptor) 663 { 664 List interceptors = descriptor.elements("interceptor"); 665 ArrayList tmp = new ArrayList (); 666 for(int i = 0; i < interceptors.size(); i ++) 667 { 668 Element interceptor = (Element) interceptors.get(i); 669 String code = interceptor.attributeValue("code"); 670 DescriptorSupport interceptorDescr = new DescriptorSupport (); 671 interceptorDescr.setField("code", code); 672 List attributes = interceptor.attributes(); 673 for(int a = 0; a < attributes.size(); a ++) 674 { 675 Attribute attr = (Attribute) attributes.get(a); 676 String name = attr.getName(); 677 String value = attr.getValue(); 678 value = StringPropertyReplacer.replaceProperties(value); 679 interceptorDescr.setField(name, value); 680 } 681 tmp.add(interceptorDescr); 682 } 683 Descriptor [] descriptors = new Descriptor [tmp.size()]; 684 tmp.toArray(descriptors); 685 return descriptors; 686 } 687 688 } 689 | Popular Tags |