1 /* 2 * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 /* 25 * @test 26 * @bug 6222961 27 * @summary Test that the counter/gauge/string monitors 28 * support attributes of arbitrary data types. 29 * @author Luis-Miguel Alventosa 30 * @run clean AttributeArbitraryDataTypeTest 31 * @run build AttributeArbitraryDataTypeTest 32 * @run main AttributeArbitraryDataTypeTest 33 */ 34 35 import java.beans.BeanInfo; 36 import java.beans.IntrospectionException; 37 import java.beans.PropertyDescriptor; 38 import java.beans.SimpleBeanInfo; 39 import java.lang.reflect.Array; 40 import java.lang.reflect.InvocationTargetException; 41 import javax.management.AttributeNotFoundException; 42 import javax.management.MBeanServer; 43 import javax.management.MBeanServerFactory; 44 import javax.management.Notification; 45 import javax.management.NotificationListener; 46 import javax.management.ObjectName; 47 import javax.management.monitor.CounterMonitor; 48 import javax.management.monitor.GaugeMonitor; 49 import javax.management.monitor.MonitorNotification; 50 import javax.management.monitor.StringMonitor; 51 import javax.management.openmbean.CompositeData; 52 import javax.management.openmbean.CompositeDataSupport; 53 import javax.management.openmbean.CompositeType; 54 import javax.management.openmbean.OpenDataException; 55 import javax.management.openmbean.OpenType; 56 import javax.management.openmbean.SimpleType; 57 58 public class AttributeArbitraryDataTypeTest implements NotificationListener { 59 60 // Flag to notify that a message has been received 61 private volatile boolean counterMessageReceived = false; 62 private volatile boolean gaugeMessageReceived = false; 63 private volatile boolean stringMessageReceived = false; 64 65 // Match enum 66 public enum Match { do_not_match_0, 67 do_not_match_1, 68 do_not_match_2, 69 do_match_now }; 70 71 // MatchBeanInfo class 72 public static class MatchBeanInfo extends SimpleBeanInfo { 73 public PropertyDescriptor[] getPropertyDescriptors() { 74 try { 75 return new PropertyDescriptor[] { 76 new PropertyDescriptor("name", Match.class, "name", null) }; 77 } catch (IntrospectionException e ) { 78 e.printStackTrace(); 79 return null; 80 } 81 } 82 } 83 84 // ComplexAttribute class 85 public class ComplexAttribute { 86 87 public Integer getIntegerAttribute() { 88 return i; 89 } 90 91 public void setIntegerAttribute(Integer i) { 92 this.i = i; 93 } 94 95 public Double getDoubleAttribute() { 96 return d; 97 } 98 99 public void setDoubleAttribute(Double d) { 100 this.d = d; 101 } 102 103 public String getStringAttribute() { 104 return s; 105 } 106 107 public void setStringAttribute(String s) { 108 this.s = s; 109 } 110 111 public Integer[] getArrayAttribute() { 112 return a; 113 } 114 115 public void setArrayAttribute(Integer[] a) { 116 this.a = a; 117 } 118 119 public Match getEnumAttribute() { 120 return e; 121 } 122 123 public void setEnumAttribute(Match e) { 124 this.e = e; 125 } 126 127 private Integer i; 128 private Double d; 129 private String s; 130 private Integer[] a; 131 private Match e; 132 } 133 134 // MBean class 135 public class ObservedObject implements ObservedObjectMBean { 136 137 // Simple type buried in complex getter 138 // 139 public ComplexAttribute getComplexAttribute() { 140 return ca; 141 } 142 143 public void setComplexAttribute(ComplexAttribute ca) { 144 this.ca = ca; 145 } 146 147 private ComplexAttribute ca = null; 148 149 // Simple type buried in CompositeData 150 // 151 public CompositeData getCompositeDataAttribute() 152 throws OpenDataException { 153 CompositeType ct = new CompositeType("CompositeDataAttribute", 154 "Composite Data Attribute", 155 itemNames, 156 itemDescriptions, 157 itemTypes); 158 Object itemValues[] = { ia, da, sa }; 159 return new CompositeDataSupport(ct, itemNames, itemValues); 160 } 161 162 public Integer ia; 163 public Double da; 164 public String sa; 165 166 private String itemNames[] = { "IntegerAttribute", 167 "DoubleAttribute", 168 "StringAttribute" }; 169 private String itemDescriptions[] = { "Integer Attribute", 170 "Double Attribute", 171 "String Attribute" }; 172 private OpenType itemTypes[] = { SimpleType.INTEGER, 173 SimpleType.DOUBLE, 174 SimpleType.STRING }; 175 } 176 177 // MBean interface 178 public interface ObservedObjectMBean { 179 public ComplexAttribute getComplexAttribute(); 180 public void setComplexAttribute(ComplexAttribute ca); 181 public CompositeData getCompositeDataAttribute() 182 throws OpenDataException; 183 } 184 185 // Notification handler 186 public void handleNotification(Notification notification, 187 Object handback) { 188 MonitorNotification n = (MonitorNotification) notification; 189 echo("\tInside handleNotification..."); 190 String type = n.getType(); 191 try { 192 if (type.equals(MonitorNotification. 193 THRESHOLD_VALUE_EXCEEDED)) { 194 echo("\t\t" + n.getObservedAttribute() + 195 " has reached or exceeded the threshold"); 196 echo("\t\tDerived Gauge = " + n.getDerivedGauge()); 197 echo("\t\tTrigger = " + n.getTrigger()); 198 199 synchronized (this) { 200 counterMessageReceived = true; 201 notifyAll(); 202 } 203 } else if (type.equals(MonitorNotification. 204 THRESHOLD_HIGH_VALUE_EXCEEDED)) { 205 echo("\t\t" + n.getObservedAttribute() + 206 " has reached or exceeded the high threshold"); 207 echo("\t\tDerived Gauge = " + n.getDerivedGauge()); 208 echo("\t\tTrigger = " + n.getTrigger()); 209 210 synchronized (this) { 211 gaugeMessageReceived = true; 212 notifyAll(); 213 } 214 } else if (type.equals(MonitorNotification. 215 STRING_TO_COMPARE_VALUE_MATCHED)) { 216 echo("\t\t" + n.getObservedAttribute() + 217 " matches the string-to-compare value"); 218 echo("\t\tDerived Gauge = " + n.getDerivedGauge()); 219 echo("\t\tTrigger = " + n.getTrigger()); 220 221 synchronized (this) { 222 stringMessageReceived = true; 223 notifyAll(); 224 } 225 } else { 226 echo("\t\tSkipping notification of type: " + type); 227 } 228 } catch (Exception e) { 229 echo("\tError in handleNotification!"); 230 e.printStackTrace(System.out); 231 } 232 } 233 234 /** 235 * Update the counter and check for notifications 236 */ 237 public int counterMonitorNotification(int testCase) 238 throws Exception { 239 240 counterMessageReceived = false; 241 CounterMonitor counterMonitor = null; 242 try { 243 MBeanServer server = MBeanServerFactory.newMBeanServer(); 244 245 String domain = server.getDefaultDomain(); 246 247 // Create a new CounterMonitor MBean and add it to the MBeanServer. 248 // 249 echo(">>> CREATE a new CounterMonitor MBean"); 250 ObjectName counterMonitorName = new ObjectName( 251 domain + ":type=" + CounterMonitor.class.getName()); 252 counterMonitor = new CounterMonitor(); 253 server.registerMBean(counterMonitor, counterMonitorName); 254 255 echo(">>> ADD a listener to the CounterMonitor"); 256 counterMonitor.addNotificationListener(this, null, null); 257 258 // 259 // MANAGEMENT OF A STANDARD MBEAN 260 // 261 262 echo(">>> CREATE a new ObservedObject MBean"); 263 264 ObjectName obsObjName = 265 ObjectName.getInstance(domain + ":type=ObservedObject"); 266 ObservedObject obsObj = new ObservedObject(); 267 ComplexAttribute ca = new ComplexAttribute(); 268 switch (testCase) { 269 case 1: 270 obsObj.ia = 0; 271 break; 272 case 2: 273 ca.setIntegerAttribute(0); 274 obsObj.setComplexAttribute(ca); 275 break; 276 case 3: 277 ca.setArrayAttribute(new Integer[0]); 278 obsObj.setComplexAttribute(ca); 279 break; 280 } 281 server.registerMBean(obsObj, obsObjName); 282 283 echo(">>> SET the attributes of the CounterMonitor:"); 284 285 counterMonitor.addObservedObject(obsObjName); 286 echo("\tATTRIBUTE \"ObservedObject\" = " + obsObjName); 287 288 switch (testCase) { 289 case 1: 290 counterMonitor.setObservedAttribute( 291 "CompositeDataAttribute.IntegerAttribute"); 292 echo("\tATTRIBUTE \"ObservedAttribute\" = " + 293 "CompositeDataAttribute.IntegerAttribute"); 294 break; 295 case 2: 296 counterMonitor.setObservedAttribute( 297 "ComplexAttribute.integerAttribute"); 298 echo("\tATTRIBUTE \"ObservedAttribute\" = " + 299 "ComplexAttribute.integerAttribute"); 300 break; 301 case 3: 302 counterMonitor.setObservedAttribute( 303 "ComplexAttribute.arrayAttribute.length"); 304 echo("\tATTRIBUTE \"ObservedAttribute\" = " + 305 "ComplexAttribute.arrayAttribute.length"); 306 break; 307 } 308 309 counterMonitor.setNotify(true); 310 echo("\tATTRIBUTE \"NotifyFlag\" = true"); 311 312 Integer threshold = 2; 313 counterMonitor.setInitThreshold(threshold); 314 echo("\tATTRIBUTE \"Threshold\" = " + threshold); 315 316 int granularityperiod = 500; 317 counterMonitor.setGranularityPeriod(granularityperiod); 318 echo("\tATTRIBUTE \"GranularityPeriod\" = " + granularityperiod); 319 320 echo(">>> START the CounterMonitor"); 321 counterMonitor.start(); 322 323 // Wait for granularity period (multiplied by 2 for sure) 324 // 325 Thread.sleep(granularityperiod * 2); 326 327 switch (testCase) { 328 case 1: 329 obsObj.ia = 1; 330 break; 331 case 2: 332 ca.setIntegerAttribute(1); 333 break; 334 case 3: 335 ca.setArrayAttribute(new Integer[1]); 336 break; 337 } 338 339 // Wait for granularity period (multiplied by 2 for sure) 340 // 341 Thread.sleep(granularityperiod * 2); 342 343 switch (testCase) { 344 case 1: 345 obsObj.ia = 2; 346 break; 347 case 2: 348 ca.setIntegerAttribute(2); 349 break; 350 case 3: 351 ca.setArrayAttribute(new Integer[2]); 352 break; 353 } 354 355 // Wait for granularity period (multiplied by 2 for sure) 356 // 357 Thread.sleep(granularityperiod * 2); 358 359 switch (testCase) { 360 case 1: 361 obsObj.ia = 3; 362 break; 363 case 2: 364 ca.setIntegerAttribute(3); 365 break; 366 case 3: 367 ca.setArrayAttribute(new Integer[3]); 368 break; 369 } 370 371 // Check if notification was received 372 // 373 synchronized (this) { 374 while (!counterMessageReceived) { 375 try { 376 wait(); 377 } catch (InterruptedException e) { 378 System.err.println("Got unexpected exception: " + e); 379 e.printStackTrace(); 380 break; 381 } 382 } 383 } 384 if (counterMessageReceived) { 385 echo("\tOK: CounterMonitor notification received"); 386 } else { 387 echo("\tKO: CounterMonitor notification missed or not emitted"); 388 return 1; 389 } 390 } finally { 391 if (counterMonitor != null) 392 counterMonitor.stop(); 393 } 394 395 return 0; 396 } 397 398 /** 399 * Update the gauge and check for notifications 400 */ 401 public int gaugeMonitorNotification(int testCase) 402 throws Exception { 403 404 gaugeMessageReceived = false; 405 GaugeMonitor gaugeMonitor = null; 406 try { 407 MBeanServer server = MBeanServerFactory.newMBeanServer(); 408 409 String domain = server.getDefaultDomain(); 410 411 // Create a new GaugeMonitor MBean and add it to the MBeanServer. 412 // 413 echo(">>> CREATE a new GaugeMonitor MBean"); 414 ObjectName gaugeMonitorName = new ObjectName( 415 domain + ":type=" + GaugeMonitor.class.getName()); 416 gaugeMonitor = new GaugeMonitor(); 417 server.registerMBean(gaugeMonitor, gaugeMonitorName); 418 419 echo(">>> ADD a listener to the GaugeMonitor"); 420 gaugeMonitor.addNotificationListener(this, null, null); 421 422 // 423 // MANAGEMENT OF A STANDARD MBEAN 424 // 425 426 echo(">>> CREATE a new ObservedObject MBean"); 427 428 ObjectName obsObjName = 429 ObjectName.getInstance(domain + ":type=ObservedObject"); 430 ObservedObject obsObj = new ObservedObject(); 431 ComplexAttribute ca = new ComplexAttribute(); 432 switch (testCase) { 433 case 1: 434 obsObj.da = 0.0; 435 break; 436 case 2: 437 ca.setDoubleAttribute(0.0); 438 obsObj.setComplexAttribute(ca); 439 break; 440 case 3: 441 ca.setArrayAttribute(new Integer[0]); 442 obsObj.setComplexAttribute(ca); 443 break; 444 } 445 server.registerMBean(obsObj, obsObjName); 446 447 echo(">>> SET the attributes of the GaugeMonitor:"); 448 449 gaugeMonitor.addObservedObject(obsObjName); 450 echo("\tATTRIBUTE \"ObservedObject\" = " + obsObjName); 451 452 switch (testCase) { 453 case 1: 454 gaugeMonitor.setObservedAttribute( 455 "CompositeDataAttribute.DoubleAttribute"); 456 echo("\tATTRIBUTE \"ObservedAttribute\" = " + 457 "CompositeDataAttribute.DoubleAttribute"); 458 break; 459 case 2: 460 gaugeMonitor.setObservedAttribute( 461 "ComplexAttribute.doubleAttribute"); 462 echo("\tATTRIBUTE \"ObservedAttribute\" = " + 463 "ComplexAttribute.doubleAttribute"); 464 break; 465 case 3: 466 gaugeMonitor.setObservedAttribute( 467 "ComplexAttribute.arrayAttribute.length"); 468 echo("\tATTRIBUTE \"ObservedAttribute\" = " + 469 "ComplexAttribute.arrayAttribute.length"); 470 break; 471 } 472 473 gaugeMonitor.setNotifyLow(false); 474 gaugeMonitor.setNotifyHigh(true); 475 echo("\tATTRIBUTE \"Notify Low Flag\" = false"); 476 echo("\tATTRIBUTE \"Notify High Flag\" = true"); 477 478 switch (testCase) { 479 case 1: 480 case 2: 481 Double highThresholdD = 3.0, lowThresholdD = 2.5; 482 gaugeMonitor.setThresholds(highThresholdD, lowThresholdD); 483 echo("\tATTRIBUTE \"Low Threshold\" = " + lowThresholdD); 484 echo("\tATTRIBUTE \"High Threshold\" = " + highThresholdD); 485 break; 486 case 3: 487 Integer highThreshold = 2, lowThreshold = 1; 488 gaugeMonitor.setThresholds(highThreshold, lowThreshold); 489 echo("\tATTRIBUTE \"Low Threshold\" = " + lowThreshold); 490 echo("\tATTRIBUTE \"High Threshold\" = " + highThreshold); 491 break; 492 } 493 494 int granularityperiod = 500; 495 gaugeMonitor.setGranularityPeriod(granularityperiod); 496 echo("\tATTRIBUTE \"GranularityPeriod\" = " + granularityperiod); 497 498 echo(">>> START the GaugeMonitor"); 499 gaugeMonitor.start(); 500 501 // Wait for granularity period (multiplied by 2 for sure) 502 // 503 Thread.sleep(granularityperiod * 2); 504 505 switch (testCase) { 506 case 1: 507 obsObj.da = 2.0; 508 break; 509 case 2: 510 ca.setDoubleAttribute(2.0); 511 break; 512 case 3: 513 ca.setArrayAttribute(new Integer[2]); 514 break; 515 } 516 517 // Wait for granularity period (multiplied by 2 for sure) 518 // 519 Thread.sleep(granularityperiod * 2); 520 521 switch (testCase) { 522 case 1: 523 obsObj.da = 4.0; 524 break; 525 case 2: 526 ca.setDoubleAttribute(4.0); 527 break; 528 case 3: 529 ca.setArrayAttribute(new Integer[4]); 530 break; 531 } 532 533 // Wait for granularity period (multiplied by 2 for sure) 534 // 535 Thread.sleep(granularityperiod * 2); 536 537 switch (testCase) { 538 case 1: 539 obsObj.da = 6.0; 540 break; 541 case 2: 542 ca.setDoubleAttribute(6.0); 543 break; 544 case 3: 545 ca.setArrayAttribute(new Integer[6]); 546 break; 547 } 548 549 // Check if notification was received 550 // 551 synchronized (this) { 552 while (!gaugeMessageReceived) { 553 try { 554 wait(); 555 } catch (InterruptedException e) { 556 System.err.println("Got unexpected exception: " + e); 557 e.printStackTrace(); 558 break; 559 } 560 } 561 } 562 if (gaugeMessageReceived) { 563 echo("\tOK: GaugeMonitor notification received"); 564 } else { 565 echo("\tKO: GaugeMonitor notification missed or not emitted"); 566 return 1; 567 } 568 } finally { 569 if (gaugeMonitor != null) 570 gaugeMonitor.stop(); 571 } 572 573 return 0; 574 } 575 576 /** 577 * Update the string and check for notifications 578 */ 579 public int stringMonitorNotification(int testCase) 580 throws Exception { 581 582 stringMessageReceived = false; 583 StringMonitor stringMonitor = null; 584 try { 585 MBeanServer server = MBeanServerFactory.newMBeanServer(); 586 587 String domain = server.getDefaultDomain(); 588 589 // Create a new StringMonitor MBean and add it to the MBeanServer. 590 // 591 echo(">>> CREATE a new StringMonitor MBean"); 592 ObjectName stringMonitorName = new ObjectName( 593 domain + ":type=" + StringMonitor.class.getName()); 594 stringMonitor = new StringMonitor(); 595 server.registerMBean(stringMonitor, stringMonitorName); 596 597 echo(">>> ADD a listener to the StringMonitor"); 598 stringMonitor.addNotificationListener(this, null, null); 599 600 // 601 // MANAGEMENT OF A STANDARD MBEAN 602 // 603 604 echo(">>> CREATE a new ObservedObject MBean"); 605 606 ObjectName obsObjName = 607 ObjectName.getInstance(domain + ":type=ObservedObject"); 608 ObservedObject obsObj = new ObservedObject(); 609 ComplexAttribute ca = new ComplexAttribute(); 610 switch (testCase) { 611 case 1: 612 obsObj.sa = "do_not_match_0"; 613 break; 614 case 2: 615 ca.setStringAttribute("do_not_match_0"); 616 obsObj.setComplexAttribute(ca); 617 break; 618 case 3: 619 ca.setEnumAttribute(Match.do_not_match_0); 620 obsObj.setComplexAttribute(ca); 621 break; 622 } 623 server.registerMBean(obsObj, obsObjName); 624 625 echo(">>> SET the attributes of the StringMonitor:"); 626 627 stringMonitor.addObservedObject(obsObjName); 628 echo("\tATTRIBUTE \"ObservedObject\" = " + obsObjName); 629 630 switch (testCase) { 631 case 1: 632 stringMonitor.setObservedAttribute( 633 "CompositeDataAttribute.StringAttribute"); 634 echo("\tATTRIBUTE \"ObservedAttribute\" = " + 635 "CompositeDataAttribute.StringAttribute"); 636 break; 637 case 2: 638 stringMonitor.setObservedAttribute( 639 "ComplexAttribute.stringAttribute"); 640 echo("\tATTRIBUTE \"ObservedAttribute\" = " + 641 "ComplexAttribute.stringAttribute"); 642 break; 643 case 3: 644 stringMonitor.setObservedAttribute( 645 "ComplexAttribute.enumAttribute.name"); 646 echo("\tATTRIBUTE \"ObservedAttribute\" = " + 647 "ComplexAttribute.enumAttribute.name"); 648 break; 649 } 650 651 stringMonitor.setNotifyMatch(true); 652 echo("\tATTRIBUTE \"NotifyMatch\" = true"); 653 654 stringMonitor.setNotifyDiffer(false); 655 echo("\tATTRIBUTE \"NotifyDiffer\" = false"); 656 657 stringMonitor.setStringToCompare("do_match_now"); 658 echo("\tATTRIBUTE \"StringToCompare\" = \"do_match_now\""); 659 660 int granularityperiod = 500; 661 stringMonitor.setGranularityPeriod(granularityperiod); 662 echo("\tATTRIBUTE \"GranularityPeriod\" = " + granularityperiod); 663 664 echo(">>> START the StringMonitor"); 665 stringMonitor.start(); 666 667 // Wait for granularity period (multiplied by 2 for sure) 668 // 669 Thread.sleep(granularityperiod * 2); 670 671 switch (testCase) { 672 case 1: 673 obsObj.sa = "do_not_match_1"; 674 break; 675 case 2: 676 ca.setStringAttribute("do_not_match_1"); 677 break; 678 case 3: 679 ca.setEnumAttribute(Match.do_not_match_1); 680 break; 681 } 682 683 // Wait for granularity period (multiplied by 2 for sure) 684 // 685 Thread.sleep(granularityperiod * 2); 686 687 switch (testCase) { 688 case 1: 689 obsObj.sa = "do_match_now"; 690 break; 691 case 2: 692 ca.setStringAttribute("do_match_now"); 693 break; 694 case 3: 695 ca.setEnumAttribute(Match.do_match_now); 696 break; 697 } 698 699 // Wait for granularity period (multiplied by 2 for sure) 700 // 701 Thread.sleep(granularityperiod * 2); 702 703 switch (testCase) { 704 case 1: 705 obsObj.sa = "do_not_match_2"; 706 break; 707 case 2: 708 ca.setStringAttribute("do_not_match_2"); 709 break; 710 case 3: 711 ca.setEnumAttribute(Match.do_not_match_2); 712 break; 713 } 714 715 // Check if notification was received 716 // 717 synchronized (this) { 718 while (!stringMessageReceived) { 719 try { 720 wait(); 721 } catch (InterruptedException e) { 722 System.err.println("Got unexpected exception: " + e); 723 e.printStackTrace(); 724 break; 725 } 726 } 727 } 728 if (stringMessageReceived) { 729 echo("\tOK: StringMonitor notification received"); 730 } else { 731 echo("\tKO: StringMonitor notification missed or not emitted"); 732 return 1; 733 } 734 } finally { 735 if (stringMonitor != null) 736 stringMonitor.stop(); 737 } 738 739 return 0; 740 } 741 742 /** 743 * Test the monitor notifications. 744 */ 745 public int monitorNotifications() throws Exception { 746 echo(">>> ----------------------------------------"); 747 int error = counterMonitorNotification(1); 748 echo(">>> ----------------------------------------"); 749 error += counterMonitorNotification(2); 750 echo(">>> ----------------------------------------"); 751 error += counterMonitorNotification(3); 752 echo(">>> ----------------------------------------"); 753 error += gaugeMonitorNotification(1); 754 echo(">>> ----------------------------------------"); 755 error += gaugeMonitorNotification(2); 756 echo(">>> ----------------------------------------"); 757 error += gaugeMonitorNotification(3); 758 echo(">>> ----------------------------------------"); 759 error += stringMonitorNotification(1); 760 echo(">>> ----------------------------------------"); 761 error += stringMonitorNotification(2); 762 echo(">>> ----------------------------------------"); 763 error += stringMonitorNotification(3); 764 echo(">>> ----------------------------------------"); 765 return error; 766 } 767 768 /* 769 * Print message 770 */ 771 private static void echo(String message) { 772 System.out.println(message); 773 } 774 775 public static Object elementFromComplex(Object complex, String element) 776 throws AttributeNotFoundException { 777 try { 778 if (complex.getClass().isArray() && element.equals("length")) { 779 return Array.getLength(complex); 780 } else if (complex instanceof CompositeData) { 781 return ((CompositeData) complex).get(element); 782 } else { 783 // Java Beans introspection 784 // 785 BeanInfo bi = java.beans.Introspector.getBeanInfo(complex.getClass()); 786 PropertyDescriptor[] pds = bi.getPropertyDescriptors(); 787 System.out.println("PDs: " + pds.length); 788 for (PropertyDescriptor pd : pds) { 789 System.out.println("Property: " + pd.getName()); 790 if (pd.getName().equals(element)) 791 return pd.getReadMethod().invoke(complex); 792 } 793 throw new AttributeNotFoundException( 794 "Could not find the getter method for the property " + 795 element + " using the Java Beans introspector"); 796 } 797 } catch (InvocationTargetException e) { 798 throw new IllegalArgumentException(e); 799 } catch (AttributeNotFoundException e) { 800 throw e; 801 } catch (Exception e) { 802 AttributeNotFoundException anfe = 803 new AttributeNotFoundException(e.getMessage()); 804 anfe.initCause(e); 805 throw anfe; 806 } 807 } 808 809 /* 810 * Standalone entry point. 811 * 812 * Run the test and report to stdout. 813 */ 814 public static void main (String args[]) throws Exception { 815 Match match = Match.do_match_now; 816 String name = (String) elementFromComplex(match, "name"); 817 System.out.println("name: " + name); 818 AttributeArbitraryDataTypeTest test = 819 new AttributeArbitraryDataTypeTest(); 820 int error = test.monitorNotifications(); 821 if (error > 0) { 822 echo(">>> Unhappy Bye, Bye!"); 823 throw new IllegalStateException("Test FAILED: Didn't get all " + 824 "the notifications that were " + 825 "expected by the test!"); 826 } else { 827 echo(">>> Happy Bye, Bye!"); 828 } 829 } 830 }