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