1 50 package org.apache.excalibur.instrument.manager; 51 52 import java.util.Arrays ; 53 import java.util.Comparator ; 54 import java.util.HashMap ; 55 56 import org.apache.avalon.framework.configuration.Configurable; 57 import org.apache.avalon.framework.configuration.Configuration; 58 import org.apache.avalon.framework.configuration.ConfigurationException; 59 import org.apache.avalon.framework.configuration.DefaultConfiguration; 60 import org.apache.avalon.framework.logger.AbstractLogEnabled; 61 import org.apache.avalon.framework.logger.Logger; 62 import org.apache.excalibur.instrument.manager.interfaces.InstrumentManagerClient; 63 import org.apache.excalibur.instrument.manager.interfaces.InstrumentSampleUtils; 64 65 79 public class InstrumentProxy 80 extends AbstractLogEnabled 81 implements org.apache.excalibur.instrument.InstrumentProxy, Configurable 82 { 83 84 private InstrumentableProxy m_instrumentableProxy; 85 86 87 private boolean m_configured; 88 89 90 private boolean m_registered; 91 92 93 private String m_name; 94 95 96 private String m_description; 97 98 99 private InstrumentDescriptorLocal m_descriptor; 100 101 102 private int m_type; 103 104 105 private InstrumentListener[] m_listeners; 106 107 108 private HashMap m_samples = new HashMap (); 109 110 111 private InstrumentSample[] m_sampleArray; 112 113 114 private InstrumentSampleDescriptorLocal[] m_sampleDescriptorArray; 115 116 117 private Logger m_valueLogger; 118 119 120 private int m_lastValue; 121 122 123 private int m_stateVersion; 124 125 128 136 InstrumentProxy( InstrumentableProxy instrumentableProxy, 137 String name, 138 String description ) 139 { 140 m_instrumentableProxy = instrumentableProxy; 141 m_name = name; 142 m_description = description; 143 144 m_descriptor = new InstrumentDescriptorLocalImpl( this ); 146 } 147 148 151 public void enableLogging( Logger logger ) 152 { 153 super.enableLogging( logger ); 154 155 m_valueLogger = logger.getChildLogger( "values" ); 158 } 159 160 163 173 public void configure( Configuration configuration ) 174 throws ConfigurationException 175 { 176 synchronized(this) 177 { 178 m_description = configuration.getAttribute( "description", m_description ); 180 181 if ( getLogger().isDebugEnabled() ) 182 { 183 getLogger().debug( "Configuring Instrument: " + m_name + " as \"" + 184 m_description + "\"" ); 185 } 186 187 m_configured = true; 188 189 Configuration[] sampleConfs = configuration.getChildren( "sample" ); 191 for ( int i = 0; i < sampleConfs.length; i++ ) 192 { 193 Configuration sampleConf = sampleConfs[i]; 194 195 int sampleType = InstrumentSampleUtils.resolveInstrumentSampleType( 196 sampleConf.getAttribute( "type" ) ); 197 long sampleInterval = sampleConf.getAttributeAsLong( "interval" ); 198 int sampleSize = sampleConf.getAttributeAsInteger( "size", 1 ); 199 200 String sampleName = InstrumentSampleUtils.generateFullInstrumentSampleName( 203 m_name, sampleType, sampleInterval, sampleSize ); 204 205 String defaultDescription = InstrumentSampleUtils.generateInstrumentSampleName( 206 sampleType, sampleInterval, sampleSize ); 207 String sampleDescription = 208 sampleConf.getAttribute( "description", defaultDescription ); 209 210 if ( getLogger().isDebugEnabled() ) 211 { 212 getLogger().debug( "Configuring InstrumentSample: " + sampleName + 213 " as \"" + sampleDescription + "\"" ); 214 } 215 216 AbstractInstrumentSample instrumentSample = 217 (AbstractInstrumentSample)InstrumentSampleFactory.getInstrumentSample( this, 218 sampleType, sampleName, sampleInterval, sampleSize, sampleDescription, 0 ); 219 instrumentSample.enableLogging( getLogger() ); 220 instrumentSample.setConfigured(); 221 222 addInstrumentSample( instrumentSample ); 223 } 224 } 225 } 226 227 230 236 public boolean isActive() { 237 return m_listeners != null; 238 } 239 240 247 public void increment( int count ) 248 { 249 if ( m_type != InstrumentManagerClient.INSTRUMENT_TYPE_COUNTER ) 250 { 251 throw new IllegalStateException ( 253 "The proxy is not configured to handle CounterInstruments." ); 254 } 255 256 InstrumentListener[] listeners = m_listeners; 258 if ( listeners != null ) 259 { 260 if ( m_valueLogger.isDebugEnabled() ) 261 { 262 m_valueLogger.debug( "increment() called for Instrument, " + m_name ); 263 } 264 265 long time = System.currentTimeMillis(); 266 for ( int i = 0; i < listeners.length; i++ ) 267 { 268 CounterInstrumentListener listener = 269 (CounterInstrumentListener)listeners[i]; 270 listener.increment( getName(), count, time ); 271 } 272 } 273 } 274 275 282 public void setValue( int value ) 283 { 284 if ( m_type != InstrumentManagerClient.INSTRUMENT_TYPE_VALUE ) 285 { 286 throw new IllegalStateException ( 288 "The proxy is not configured to handle ValueInstruments." ); 289 } 290 291 m_lastValue = value; 295 296 InstrumentListener[] listeners = m_listeners; 298 if ( listeners != null ) 299 { 300 if ( m_valueLogger.isDebugEnabled() ) 301 { 302 m_valueLogger.debug( "setValue( " + value + " ) called for Instrument, " + m_name ); 303 } 304 305 long time = System.currentTimeMillis(); 306 for ( int i = 0; i < listeners.length; i++ ) 307 { 308 ValueInstrumentListener listener = 309 (ValueInstrumentListener)listeners[i]; 310 listener.setValue( getName(), value, time ); 311 } 312 } 313 } 314 315 318 323 InstrumentableProxy getInstrumentableProxy() 324 { 325 return m_instrumentableProxy; 326 } 327 328 334 boolean isConfigured() 335 { 336 return m_configured; 337 } 338 339 345 boolean isRegistered() 346 { 347 return m_registered; 348 } 349 350 354 void setRegistered() 355 { 356 m_registered = true; 357 } 358 359 367 String getName() 368 { 369 return m_name; 370 } 371 372 379 void setDescription( String description ) 380 { 381 m_description = description; 382 } 383 384 389 String getDescription() 390 { 391 return m_description; 392 } 393 394 399 InstrumentDescriptorLocal getDescriptor() 400 { 401 return m_descriptor; 402 } 403 404 409 void setType( int type ) 410 { 411 synchronized(this) 412 { 413 if ( m_type != InstrumentManagerClient.INSTRUMENT_TYPE_NONE ) 414 { 415 throw new IllegalStateException ( "Type already set." ); 416 } 417 switch ( type ) 418 { 419 case InstrumentManagerClient.INSTRUMENT_TYPE_COUNTER: 420 case InstrumentManagerClient.INSTRUMENT_TYPE_VALUE: 421 m_type = type; 422 break; 423 default: 424 throw new IllegalStateException ( type + " is not a valid type." ); 425 } 426 } 427 } 428 429 434 int getType() 435 { 436 return m_type; 437 } 438 439 449 void addCounterInstrumentListener( CounterInstrumentListener listener ) 450 { 451 if ( m_type != InstrumentManagerClient.INSTRUMENT_TYPE_COUNTER ) 452 { 453 throw new IllegalStateException ( 455 "The proxy is not configured to handle CounterInstruments." ); 456 } 457 458 if ( getLogger().isDebugEnabled() ) 459 { 460 getLogger().debug( "A CounterInstrumentListener was added to Instrument, " + 461 m_name + " : " + listener.getClass().getName() ); 462 } 463 464 addInstrumentListener( listener ); 465 } 466 467 477 void removeCounterInstrumentListener( CounterInstrumentListener listener ) 478 { 479 if ( m_type != InstrumentManagerClient.INSTRUMENT_TYPE_COUNTER ) 480 { 481 throw new IllegalStateException ( 483 "The proxy is not configured to handle CounterInstruments." ); 484 } 485 486 if ( getLogger().isDebugEnabled() ) 487 { 488 getLogger().debug( "A CounterInstrumentListener was removed from Instrument, " + 489 m_name + " : " + listener.getClass().getName() ); 490 } 491 492 removeInstrumentListener( listener ); 493 } 494 495 505 void addValueInstrumentListener( ValueInstrumentListener listener ) 506 { 507 if ( m_type != InstrumentManagerClient.INSTRUMENT_TYPE_VALUE ) 508 { 509 throw new IllegalStateException ( 511 "The proxy is not configured to handle ValueInstruments." ); 512 } 513 514 if ( getLogger().isDebugEnabled() ) 515 { 516 getLogger().debug( "A ValueInstrumentListener was added to Instrument, " + m_name + 517 " : " + listener.getClass().getName() ); 518 } 519 520 addInstrumentListener( listener ); 521 522 long time = System.currentTimeMillis(); 524 listener.setValue( getName(), m_lastValue, time ); 525 } 526 527 537 void removeValueInstrumentListener( ValueInstrumentListener listener ) 538 { 539 if ( m_type != InstrumentManagerClient.INSTRUMENT_TYPE_VALUE ) 540 { 541 throw new IllegalStateException ( 543 "The proxy is not configured to handle ValueInstruments." ); 544 } 545 546 if ( getLogger().isDebugEnabled() ) 547 { 548 getLogger().debug( "A ValueInstrumentListener was removed from Instrument, " + m_name + 549 " : " + listener.getClass().getName() ); 550 } 551 552 removeInstrumentListener( listener ); 553 } 554 555 560 private void addInstrumentSample( InstrumentSample instrumentSample ) 561 { 562 synchronized(this) 563 { 564 if ( m_type == InstrumentManagerClient.INSTRUMENT_TYPE_NONE ) 567 { 568 setType( instrumentSample.getInstrumentType() ); 569 } 570 else if ( m_type != instrumentSample.getInstrumentType() ) 571 { 572 throw new IllegalStateException ( "The sample '" + instrumentSample.getName() + 574 "' had its type set to " + getTypeName( m_type ) + 575 " by another sample. This sample has a type of " + 576 getTypeName( instrumentSample.getInstrumentType() ) + " and is not compatible." ); 577 } 578 579 String sampleName = instrumentSample.getName(); 581 if ( m_samples.get( sampleName ) != null ) 582 { 583 throw new IllegalStateException ( "More than one sample with the same name, '" + 584 sampleName + "', can not be configured." ); 585 } 586 587 m_samples.put( sampleName, instrumentSample ); 589 590 m_sampleArray = null; 592 m_sampleDescriptorArray = null; 593 594 switch ( m_type ) 596 { 597 case InstrumentManagerClient.INSTRUMENT_TYPE_COUNTER: 598 addCounterInstrumentListener( (CounterInstrumentSample)instrumentSample ); 599 break; 600 601 case InstrumentManagerClient.INSTRUMENT_TYPE_VALUE: 602 addValueInstrumentListener( (AbstractValueInstrumentSample)instrumentSample ); 603 break; 604 605 default: 606 throw new IllegalStateException ( 607 "Don't know how to deal with the type: " + m_type ); 608 } 609 } 610 611 stateChanged(); 612 } 613 614 619 void removeInstrumentSample( InstrumentSample instrumentSample ) 620 { 621 synchronized(this) 622 { 623 switch ( m_type ) 625 { 626 case InstrumentManagerClient.INSTRUMENT_TYPE_COUNTER: 627 removeCounterInstrumentListener( (CounterInstrumentSample)instrumentSample ); 628 break; 629 630 case InstrumentManagerClient.INSTRUMENT_TYPE_VALUE: 631 removeValueInstrumentListener( (AbstractValueInstrumentSample)instrumentSample ); 632 break; 633 634 default: 635 throw new IllegalStateException ( 636 "Don't know how to deal with the type: " + m_type ); 637 } 638 639 m_samples.remove( instrumentSample.getName() ); 641 642 m_sampleArray = null; 644 m_sampleDescriptorArray = null; 645 } 646 647 stateChanged(); 648 } 649 650 657 InstrumentSample getInstrumentSample( String InstrumentSampleName ) 658 { 659 synchronized(this) 660 { 661 return (InstrumentSample)m_samples.get( InstrumentSampleName ); 662 } 663 } 664 665 670 InstrumentSample[] getInstrumentSamples() 671 { 672 InstrumentSample[] samples = m_sampleArray; 673 if ( samples == null ) 674 { 675 samples = updateInstrumentSampleArray(); 676 } 677 return samples; 678 } 679 680 702 InstrumentSample createInstrumentSample( String sampleDescription, 703 long sampleInterval, 704 int sampleSize, 705 long sampleLease, 706 int sampleType ) 707 { 708 getLogger().debug("Create new sample for " + m_name + ": interval=" + sampleInterval + 709 ", size=" + sampleSize + ", lease=" + sampleLease + ", type=" + 710 InstrumentSampleUtils.getInstrumentSampleTypeName( sampleType ) ); 711 712 long now = System.currentTimeMillis(); 714 715 String sampleName = InstrumentSampleUtils.generateFullInstrumentSampleName( 717 m_name, sampleType, sampleInterval, sampleSize ); 718 719 InstrumentSample instrumentSample; 720 synchronized( this ) 721 { 722 instrumentSample = getInstrumentSample( sampleName ); 724 if ( instrumentSample != null ) 725 { 726 instrumentSample.extendLease( sampleLease ); 728 } 729 else 730 { 731 instrumentSample = InstrumentSampleFactory.getInstrumentSample( 733 this, sampleType, sampleName, sampleInterval, sampleSize, 734 sampleDescription, sampleLease ); 735 instrumentSample.enableLogging( getLogger() ); 736 737 addInstrumentSample( instrumentSample ); 738 739 getInstrumentableProxy().getInstrumentManager(). 741 registerLeasedInstrumentSample( instrumentSample ); 742 } 743 } 744 745 return instrumentSample; 746 } 747 748 755 InstrumentSampleDescriptorLocal[] getInstrumentSampleDescriptors() 756 { 757 InstrumentSampleDescriptorLocal[] descriptors = m_sampleDescriptorArray; 758 if ( descriptors == null ) 759 { 760 descriptors = updateInstrumentSampleDescriptorArray(); 761 } 762 return descriptors; 763 } 764 765 774 int getStateVersion() 775 { 776 return m_stateVersion; 777 } 778 779 786 private void addInstrumentListener( InstrumentListener listener ) 787 { 788 synchronized(this) 789 { 790 InstrumentListener[] oldListeners = m_listeners; 795 InstrumentListener[] newListeners; 796 if ( oldListeners == null ) 797 { 798 newListeners = new InstrumentListener[] { listener }; 799 } 800 else 801 { 802 newListeners = new InstrumentListener[ oldListeners.length + 1 ]; 803 System.arraycopy( oldListeners, 0, newListeners, 0, oldListeners.length ); 804 newListeners[ oldListeners.length ] = listener; 805 } 806 807 m_listeners = newListeners; 809 } 810 } 811 812 819 private void removeInstrumentListener( InstrumentListener listener ) 820 { 821 synchronized(this) 822 { 823 InstrumentListener[] oldListeners = m_listeners; 828 InstrumentListener[] newListeners; 829 if ( oldListeners == null ) 830 { 831 newListeners = null; 834 } 835 else if ( oldListeners.length == 1 ) 836 { 837 if ( oldListeners[0] == listener ) 838 { 839 newListeners = null; 840 } 841 else 842 { 843 newListeners = oldListeners; 845 } 846 } 847 else 848 { 849 int pos = -1; 851 for ( int i = 0; i < oldListeners.length; i++ ) 852 { 853 if ( oldListeners[i] == listener ) 854 { 855 pos = i; 856 break; 857 } 858 } 859 860 if ( pos < 0 ) 861 { 862 newListeners = oldListeners; 864 } 865 else 866 { 867 newListeners = new InstrumentListener[ oldListeners.length - 1 ]; 868 if ( pos > 0 ) 869 { 870 System.arraycopy( oldListeners, 0, newListeners, 0, pos ); 872 } 873 if ( pos < oldListeners.length - 1 ) 874 { 875 System.arraycopy( oldListeners, pos + 1, 877 newListeners, pos, oldListeners.length - 1 - pos ); 878 } 879 } 880 } 881 882 m_listeners = newListeners; 884 } 885 } 886 887 893 private InstrumentSample[] updateInstrumentSampleArray() 894 { 895 synchronized(this) 896 { 897 m_sampleArray = new InstrumentSample[ m_samples.size() ]; 898 m_samples.values().toArray( m_sampleArray ); 899 900 Arrays.sort( m_sampleArray, new Comparator () 904 { 905 public int compare( Object o1, Object o2 ) 906 { 907 return ((InstrumentSample)o1).getDescription(). 908 compareTo( ((InstrumentSample)o2).getDescription() ); 909 } 910 911 public boolean equals( Object obj ) 912 { 913 return false; 914 } 915 } ); 916 917 return m_sampleArray; 918 } 919 } 920 921 927 private InstrumentSampleDescriptorLocal[] updateInstrumentSampleDescriptorArray() 928 { 929 synchronized(this) 930 { 931 if ( m_sampleArray == null ) 932 { 933 updateInstrumentSampleArray(); 934 } 935 936 m_sampleDescriptorArray = 937 new InstrumentSampleDescriptorLocal[ m_sampleArray.length ]; 938 for ( int i = 0; i < m_sampleArray.length; i++ ) 939 { 940 m_sampleDescriptorArray[i] = m_sampleArray[i].getDescriptor(); 941 } 942 943 return m_sampleDescriptorArray; 944 } 945 } 946 947 953 Configuration saveState() 954 { 955 boolean empty = true; 956 DefaultConfiguration state = new DefaultConfiguration( "instrument", "-" ); 957 state.setAttribute( "name", m_name ); 958 959 InstrumentSample[] samples = getInstrumentSamples(); 960 for ( int i = 0; i < samples.length; i++ ) 961 { 962 Configuration childState = samples[i].saveState(); 963 if ( childState != null ) 964 { 965 state.addChild( childState ); 966 empty = false; 967 } 968 } 969 970 if ( empty ) 972 { 973 state = null; 974 } 975 return state; 976 } 977 978 986 void loadState( Configuration state ) throws ConfigurationException 987 { 988 synchronized( this ) 989 { 990 Configuration[] instrumentSampleConfs = state.getChildren( "sample" ); 991 for ( int i = 0; i < instrumentSampleConfs.length; i++ ) 992 { 993 Configuration instrumentSampleConf = instrumentSampleConfs[i]; 994 995 int sampleType = InstrumentSampleUtils.resolveInstrumentSampleType( 996 instrumentSampleConf.getAttribute( "type" ) ); 997 long sampleInterval = instrumentSampleConf.getAttributeAsLong( "interval" ); 998 int sampleSize = instrumentSampleConf.getAttributeAsInteger( "size", 1 ); 999 1000 String fullSampleName = InstrumentSampleUtils.generateFullInstrumentSampleName( 1003 m_name, sampleType, sampleInterval, sampleSize ); 1004 InstrumentSample sample = getInstrumentSample( fullSampleName ); 1005 if ( sample == null ) 1006 { 1007 long leaseExpirationTime = 1009 instrumentSampleConf.getAttributeAsLong( "lease-expiration", 0 ); 1010 if ( leaseExpirationTime > 0 ) 1011 { 1012 1013 String sampleName = InstrumentSampleUtils.generateInstrumentSampleName( 1014 sampleType, sampleInterval, sampleSize ); 1015 String sampleDescription = 1016 instrumentSampleConf.getAttribute( "description", sampleName ); 1017 1018 AbstractInstrumentSample instrumentSample = 1019 (AbstractInstrumentSample)InstrumentSampleFactory.getInstrumentSample( 1020 this, sampleType, fullSampleName, sampleInterval, sampleSize, 1021 sampleDescription, 0 ); 1022 instrumentSample.enableLogging( getLogger() ); 1023 instrumentSample.loadState( instrumentSampleConf ); 1024 addInstrumentSample( instrumentSample ); 1025 } 1026 else 1027 { 1028 getLogger().warn( "InstrumentSample entry ignored while loading state " + 1029 "because the sample does not exist: " + fullSampleName ); 1030 } 1031 } 1032 else 1033 { 1034 sample.loadState( instrumentSampleConf ); 1035 } 1036 } 1037 } 1038 1039 stateChanged(); 1040 } 1041 1042 1045 protected void stateChanged() 1046 { 1047 m_stateVersion++; 1048 1049 m_instrumentableProxy.stateChanged(); 1051 } 1052 1053 1060 public static String getTypeName( int type ) 1061 { 1062 switch ( type ) 1063 { 1064 case InstrumentManagerClient.INSTRUMENT_TYPE_NONE: 1065 return "none"; 1066 case InstrumentManagerClient.INSTRUMENT_TYPE_COUNTER: 1067 return "counter"; 1068 case InstrumentManagerClient.INSTRUMENT_TYPE_VALUE: 1069 return "value"; 1070 default: 1071 throw new IllegalArgumentException ( type + " is not a known Instrument type." ); 1072 } 1073 } 1074} 1075 | Popular Tags |