1 17 package org.apache.avalon.excalibur.testcase; 18 19 import org.apache.avalon.framework.activity.Disposable; 20 import org.apache.avalon.framework.activity.Initializable; 21 import org.apache.avalon.framework.activity.Startable; 22 import org.apache.avalon.framework.activity.Suspendable; 23 import org.apache.avalon.framework.component.Composable; 24 import org.apache.avalon.framework.component.Recomposable; 25 import org.apache.avalon.framework.configuration.Configurable; 26 import org.apache.avalon.framework.configuration.Reconfigurable; 27 import org.apache.avalon.framework.context.Contextualizable; 28 import org.apache.avalon.framework.context.Recontextualizable; 29 import org.apache.avalon.framework.logger.LogEnabled; 30 import org.apache.avalon.framework.logger.Loggable; 31 import org.apache.avalon.framework.parameters.Parameterizable; 32 import org.apache.avalon.framework.service.Serviceable; 33 34 45 public final class ComponentStateValidator 46 { 47 private static final String WRITE_FAIL = "Value is already bound"; 48 49 private static final long LOG_ENABLED = 0x00000001; 51 private static final long LOGGABLE = 0x00000002; 52 private static final long CONTEXTUALIZABLE = 0x00000004; 53 private static final long COMPOSABLE = 0x00000008; 54 private static final long SERVICEABLE = 0x00000010; 55 private static final long CONFIGURABLE = 0x00000020; 56 private static final long PARAMETERIZABLE = 0x00000040; 57 private static final long INITIALIZABLE = 0x00000080; 58 private static final long STARTABLE = 0x00000100; 59 private static final long SUSPENDABLE = 0x00001000; 60 private static final long RECONTEXTUALIZABLE = 0x00002000; 61 private static final long RECOMPOSABLE = 0x00004000; 62 private static final long RECONFIGURABLE = 0x00008000; 63 private static final long DISPOSABLE = 0x00100000; 64 65 private static final long ENABLE_LOGGING = 0x00000001; 67 private static final long SET_LOGGER = 0x00000002; 68 private static final long CONTEXTUALIZE = 0x00000004; 69 private static final long SERVICE = 0x00000008; 70 private static final long COMPOSE = 0x00000010; 71 private static final long CONFIGURE = 0x00000020; 72 private static final long PARAMETERIZE = 0x00000040; 73 private static final long INITIALIZE = 0x00000080; 74 private static final long START = 0x00000100; 75 private static final long INIT_COMPLETE = 0x00000400; 76 77 private static final long SUSPEND = 0x00001000; 79 private static final long RECONTEXTUALIZE = 0x00002000; 80 private static final long RECOMPOSE = 0x00004000; 81 private static final long RECONFIGURE = 0x00008000; 82 private static final long RESUME = 0x00010000; 83 84 private static final long STOP = 0x00100000; 86 private static final long DISPOSE = 0x00200000; 87 88 private static final long INIT_MASK = ENABLE_LOGGING | SET_LOGGER | 90 CONTEXTUALIZE | COMPOSE | SERVICE | CONFIGURE | PARAMETERIZE | INITIALIZE | 91 START; 92 93 private final long m_interfaces; 94 private final long m_methods; 95 private long m_state; 96 private boolean m_active; 97 private final Object m_object; 98 99 103 public ComponentStateValidator( final Object object ) 104 { 105 m_object = object; 106 107 long methods = 0; 108 long interfaces = 0; 109 110 if( object instanceof LogEnabled ) 111 { 112 interfaces |= LOG_ENABLED; 113 methods |= ENABLE_LOGGING; 114 } 115 116 if( object instanceof Loggable ) 117 { 118 interfaces |= LOGGABLE; 119 methods |= SET_LOGGER; 120 } 121 122 if( object instanceof Contextualizable ) 123 { 124 interfaces |= CONTEXTUALIZABLE; 125 methods |= CONTEXTUALIZE; 126 } 127 128 if( object instanceof Serviceable ) 129 { 130 interfaces |= SERVICEABLE; 131 methods |= SERVICE; 132 } 133 134 if( object instanceof Composable ) 135 { 136 if( ( interfaces & SERVICEABLE ) > 0 ) 137 { 138 throw new IllegalStateException ( "Cannot implement Composable and Serviceable together" ); 139 } 140 141 interfaces |= COMPOSABLE; 142 methods |= COMPOSE; 143 } 144 145 if( object instanceof Configurable ) 146 { 147 interfaces |= CONFIGURABLE; 148 methods |= CONFIGURE; 149 } 150 151 if( object instanceof Parameterizable ) 152 { 153 interfaces |= PARAMETERIZABLE; 154 methods |= PARAMETERIZE; 155 } 156 157 if( object instanceof Initializable ) 158 { 159 interfaces |= INITIALIZABLE; 160 methods |= INITIALIZE; 161 } 162 163 if( object instanceof Startable ) 164 { 165 interfaces |= STARTABLE; 166 methods |= START | STOP; 167 } 168 169 if( object instanceof Suspendable ) 170 { 171 interfaces |= SUSPENDABLE; 172 methods |= SUSPEND | RESUME; 173 } 174 175 if( object instanceof Recontextualizable ) 176 { 177 interfaces |= RECONTEXTUALIZABLE; 178 methods |= RECONTEXTUALIZE; 179 } 180 181 if( object instanceof Recomposable ) 182 { 183 interfaces |= RECOMPOSABLE; 184 methods |= RECOMPOSE; 185 } 186 187 if( object instanceof Reconfigurable ) 188 { 189 interfaces |= RECONFIGURABLE; 190 methods |= RECONFIGURE; 191 } 192 193 if( object instanceof Disposable ) 194 { 195 interfaces |= DISPOSABLE; 196 methods |= DISPOSE; 197 } 198 199 m_methods = methods; 200 m_interfaces = interfaces; 201 202 generalCheckInitComplete(); 203 } 204 205 private String getInterfaceName( long interfaceId ) 206 { 207 if( interfaceId == LOG_ENABLED ) 208 { 209 return LogEnabled.class.getName(); 210 } 211 else if( interfaceId == LOGGABLE ) 212 { 213 return Loggable.class.getName(); 214 } 215 else if( interfaceId == CONTEXTUALIZABLE ) 216 { 217 return Contextualizable.class.getName(); 218 } 219 else if( interfaceId == SERVICEABLE ) 220 { 221 return Serviceable.class.getName(); 222 } 223 else if( interfaceId == COMPOSABLE ) 224 { 225 return Composable.class.getName(); 226 } 227 else if( interfaceId == CONFIGURABLE ) 228 { 229 return Configurable.class.getName(); 230 } 231 else if( interfaceId == PARAMETERIZABLE ) 232 { 233 return Parameterizable.class.getName(); 234 } 235 else if( interfaceId == INITIALIZABLE ) 236 { 237 return Initializable.class.getName(); 238 } 239 else if( interfaceId == STARTABLE ) 240 { 241 return Startable.class.getName(); 242 } 243 else if( interfaceId == SUSPENDABLE ) 244 { 245 return Suspendable.class.getName(); 246 } 247 else if( interfaceId == RECONTEXTUALIZABLE ) 248 { 249 return Recontextualizable.class.getName(); 250 } 251 else if( interfaceId == RECOMPOSABLE ) 252 { 253 return Recomposable.class.getName(); 254 } 255 else if( interfaceId == RECONFIGURABLE ) 256 { 257 return Reconfigurable.class.getName(); 258 } 259 else if( interfaceId == DISPOSABLE ) 260 { 261 return Disposable.class.getName(); 262 } 263 else 264 { 265 throw new IllegalStateException ( "Unknown Interface Id " + interfaceId ); 266 } 267 } 268 269 private String getMethodName( long methodId ) 270 { 271 if( methodId == ENABLE_LOGGING ) 272 { 273 return "enableLogging()"; 274 } 275 else if( methodId == SET_LOGGER ) 276 { 277 return "setLogger()"; 278 } 279 else if( methodId == CONTEXTUALIZE ) 280 { 281 return "contextualize()"; 282 } 283 else if( methodId == SERVICE ) 284 { 285 return "service()"; 286 } 287 else if( methodId == COMPOSE ) 288 { 289 return "compose()"; 290 } 291 else if( methodId == CONFIGURE ) 292 { 293 return "configure()"; 294 } 295 else if( methodId == PARAMETERIZE ) 296 { 297 return "parameterize()"; 298 } 299 else if( methodId == INITIALIZE ) 300 { 301 return "initialize()"; 302 } 303 else if( methodId == START ) 304 { 305 return "start()"; 306 } 307 else if( methodId == SUSPEND ) 308 { 309 return "suspend()"; 310 } 311 else if( methodId == RECONTEXTUALIZE ) 312 { 313 return "recontextualize()"; 314 } 315 else if( methodId == RECOMPOSE ) 316 { 317 return "recompose()"; 318 } 319 else if( methodId == RECONFIGURE ) 320 { 321 return "reconfigure()"; 322 } 323 else if( methodId == RESUME ) 324 { 325 return "resume()"; 326 } 327 else if( methodId == STOP ) 328 { 329 return "stop()"; 330 } 331 else if( methodId == DISPOSE ) 332 { 333 return "dispose()"; 334 } 335 else 336 { 337 throw new IllegalStateException ( "Unknown Method Id " + methodId ); 338 } 339 } 340 341 private String getLastMethod( long state ) 342 { 343 for( int i = 31; i >= 0; i-- ) 344 { 345 long methodId = 0x1 << i; 346 if( ( state & methodId ) != 0 ) 347 { 348 return getMethodName( methodId ); 349 } 350 } 351 throw new IllegalStateException ( "No last state method found for state " + state ); 352 } 353 354 357 private void generalCheckInitComplete() 358 { 359 if( m_state == ( m_methods & INIT_MASK ) ) 360 { 361 m_active = true; 363 } 364 } 365 366 371 private void generalCheckInit( final String message, final long interfaceId, final long methodId ) 372 { 373 if( ( m_interfaces & interfaceId ) == 0 ) 374 { 375 if( message == null ) 377 { 378 throw new IllegalStateException ( m_object.getClass().getName() + 379 " does not implement " + getInterfaceName( interfaceId ) + "." ); 380 } 381 else 382 { 383 throw new IllegalStateException ( message ); 384 } 385 } 386 else if( ( m_state & methodId ) > 0 ) 387 { 388 if( message == null ) 390 { 391 throw new IllegalStateException ( getMethodName( methodId ) + " already called." ); 392 } 393 else 394 { 395 throw new IllegalStateException ( message ); 396 } 397 } 398 else if( m_state > methodId ) 399 { 400 if( message == null ) 402 { 403 throw new IllegalStateException ( getMethodName( methodId ) + 404 " can not be called after " + getLastMethod( m_state ) + "." ); 405 } 406 else 407 { 408 throw new IllegalStateException ( message ); 409 } 410 } 411 else if( ( m_state & ( methodId - 1 ) ) != ( m_methods & ( methodId - 1 ) ) ) 412 { 413 if( message == null ) 416 { 417 throw new IllegalStateException ( getMethodName( methodId ) + 418 " called out of order. " + getLastMethod( m_methods & ( methodId - 1 ) ) + 419 " must be called first." ); 420 } 421 else 422 { 423 throw new IllegalStateException ( message ); 424 } 425 } 426 427 m_state |= methodId; 429 430 generalCheckInitComplete(); 432 } 433 434 443 private void generalCheckActive( final String message, final long interfaceId, final long methodId ) 444 { 445 if( ( m_interfaces & interfaceId ) == 0 ) 446 { 447 if( message == null ) 449 { 450 throw new IllegalStateException ( m_object.getClass().getName() + 451 " does not implement " + getInterfaceName( interfaceId ) + "." ); 452 } 453 else 454 { 455 throw new IllegalStateException ( message ); 456 } 457 } 458 else if( !m_active ) 459 { 460 if( m_state < INIT_COMPLETE ) 462 { 463 if( message == null ) 465 { 466 throw new IllegalStateException ( getMethodName( methodId ) + 467 " called before component was made active. " + 468 getLastMethod( m_methods & ( INIT_COMPLETE - 1 ) ) + 469 " must be called first." ); 470 } 471 else 472 { 473 throw new IllegalStateException ( message ); 474 } 475 } 476 else 477 { 478 if( message == null ) 480 { 481 throw new IllegalStateException ( getMethodName( methodId ) + 482 " called after component was made inactive. Cannot call after " + 483 getLastMethod( m_state ) + "." ); 484 } 485 else 486 { 487 throw new IllegalStateException ( message ); 488 } 489 } 490 } 491 } 492 493 498 private void generalCheckDest( final String message, final long interfaceId, final long methodId ) 499 { 500 if( ( m_interfaces & interfaceId ) == 0 ) 501 { 502 if( message == null ) 504 { 505 throw new IllegalStateException ( m_object.getClass().getName() + 506 " does not implement " + getInterfaceName( interfaceId ) + "." ); 507 } 508 else 509 { 510 throw new IllegalStateException ( message ); 511 } 512 } 513 else if( m_state > methodId ) 514 { 515 if( message == null ) 517 { 518 throw new IllegalStateException ( getMethodName( methodId ) + 519 " can not be called after " + getLastMethod( m_state ) + "." ); 520 } 521 else 522 { 523 throw new IllegalStateException ( message ); 524 } 525 } 526 527 m_state |= methodId; 529 530 m_active = false; 532 } 533 534 541 public void checkLogEnabled() 542 { 543 checkLogEnabled( null ); 544 } 545 546 554 public void checkLogEnabled( final String message ) 555 { 556 generalCheckInit( message, LOG_ENABLED, ENABLE_LOGGING ); 557 } 558 559 566 public void checkLoggable() 567 { 568 checkLogEnabled( null ); 569 } 570 571 579 public void checkLoggable( final String message ) 580 { 581 generalCheckInit( message, LOGGABLE, SET_LOGGER ); 582 } 583 584 591 public void checkContextualized() 592 { 593 checkContextualized( null ); 594 } 595 596 604 public void checkContextualized( final String message ) 605 { 606 generalCheckInit( message, CONTEXTUALIZABLE, CONTEXTUALIZE ); 607 } 608 609 616 public void checkServiced() 617 { 618 checkServiced( null ); 619 } 620 621 629 public void checkServiced( final String message ) 630 { 631 generalCheckInit( message, SERVICEABLE, SERVICE ); 632 } 633 634 641 public void checkComposed() 642 { 643 checkComposed( null ); 644 } 645 646 654 public void checkComposed( final String message ) 655 { 656 generalCheckInit( message, COMPOSABLE, COMPOSE ); 657 } 658 659 666 public void checkConfigured() 667 { 668 checkConfigured( null ); 669 } 670 671 679 public void checkConfigured( final String message ) 680 { 681 generalCheckInit( message, CONFIGURABLE, CONFIGURE ); 682 } 683 684 691 public void checkParameterized() 692 { 693 checkParameterized( null ); 694 } 695 696 704 public void checkParameterized( final String message ) 705 { 706 generalCheckInit( message, PARAMETERIZABLE, PARAMETERIZE ); 707 } 708 709 716 public void checkInitialized() 717 { 718 checkInitialized( null ); 719 } 720 721 729 public void checkInitialized( final String message ) 730 { 731 generalCheckInit( message, INITIALIZABLE, INITIALIZE ); 732 } 733 734 741 public void checkStarted() 742 { 743 checkStarted( null ); 744 } 745 746 754 public void checkStarted( final String message ) 755 { 756 generalCheckInit( message, STARTABLE, START ); 757 } 758 759 766 public void checkSuspended() 767 { 768 checkSuspended( null ); 769 } 770 771 779 public void checkSuspended( final String message ) 780 { 781 generalCheckActive( message, SUSPENDABLE, SUSPEND ); 782 } 783 784 791 public void checkResumed() 792 { 793 checkResumed( null ); 794 } 795 796 804 public void checkResumed( final String message ) 805 { 806 generalCheckActive( message, SUSPENDABLE, RESUME ); 807 } 808 809 816 public void checkStopped() 817 { 818 checkStopped( null ); 819 } 820 821 829 public void checkStopped( final String message ) 830 { 831 generalCheckDest( message, STARTABLE, STOP ); 832 } 833 834 841 public void checkDisposed() 842 { 843 checkDisposed( null ); 844 } 845 846 854 public void checkDisposed( final String message ) 855 { 856 generalCheckDest( message, DISPOSABLE, DISPOSE ); 857 } 858 859 864 public void checkActive() 865 { 866 checkActive( null ); 867 } 868 869 875 public void checkActive( final String message ) 876 { 877 if( isActive() ) 878 { 879 return; 880 } 881 882 if( m_state < INIT_COMPLETE ) 884 { 885 if( message == null ) 887 { 888 throw new IllegalStateException ( "Component not in the active state. " + 889 getLastMethod( m_methods & ( INIT_COMPLETE - 1 ) ) + 890 " was not called." ); 891 } 892 else 893 { 894 throw new IllegalStateException ( message ); 895 } 896 } 897 else 898 { 899 if( message == null ) 901 { 902 throw new IllegalStateException ( "Component not in the active state because " + 903 getLastMethod( m_state ) + " was called." ); 904 } 905 else 906 { 907 throw new IllegalStateException ( message ); 908 } 909 } 910 } 911 912 917 public boolean isActive() 918 { 919 return m_active; 920 } 921 922 928 public void checkNotAssigned( final Object object ) 929 { 930 checkNotAssigned( object, WRITE_FAIL ); 931 } 932 933 940 public void checkNotAssigned( final Object object, final String message ) 941 { 942 if( null != object ) 943 { 944 throw new IllegalStateException ( message ); 945 } 946 } 947 } 948 949 | Popular Tags |