1 29 30 package com.caucho.lifecycle; 31 32 import com.caucho.util.Alarm; 33 34 import java.lang.ref.WeakReference ; 35 import java.util.ArrayList ; 36 import java.util.logging.Level ; 37 import java.util.logging.Logger ; 38 39 42 public final class Lifecycle implements LifecycleState { 43 private final Logger _log; 44 private String _name; 45 private Level _level = Level.FINE; 46 47 private int _state; 48 49 private long _activeCount; 50 private long _failCount; 51 52 private long _lastFailTime; 53 private long _lastChangeTime; 54 55 private ArrayList <WeakReference <LifecycleListener>> _listeners; 56 57 60 public Lifecycle() 61 { 62 _log = null; 63 } 64 65 68 public Lifecycle(Logger log) 69 { 70 _log = log; 71 } 72 73 76 public Lifecycle(Logger log, String name) 77 { 78 _log = log; 79 _name = name; 80 } 81 82 85 public Lifecycle(Logger log, String name, Level level) 86 { 87 _log = log; 88 _name = name; 89 _level = level; 90 } 91 92 95 public String getName() 96 { 97 return _name; 98 } 99 100 103 public void setName(String name) 104 { 105 _name = name; 106 } 107 108 111 public Level getLevel() 112 { 113 return _level; 114 } 115 116 119 public void setLevel(Level level) 120 { 121 _level = level; 122 } 123 124 127 public void addListener(LifecycleListener listener) 128 { 129 synchronized (this) { 130 if (isDestroyed()) { 131 IllegalStateException e = new IllegalStateException ("attempted to add listener to a destroyed lifecyle " + this); 132 133 if (_log != null) 134 _log.log(Level.WARNING, e.toString(), e); 135 else 136 Logger.getLogger(Lifecycle.class.getName()).log(Level.WARNING, e.toString(), e); 137 138 return; 139 } 140 141 if (_listeners == null) 142 _listeners = new ArrayList <WeakReference <LifecycleListener>>(); 143 144 for (int i = _listeners.size() - 1; i >= 0; i--) { 145 LifecycleListener oldListener = _listeners.get(i).get(); 146 147 if (listener == oldListener) 148 return; 149 else if (oldListener == null) 150 _listeners.remove(i); 151 } 152 153 _listeners.add(new WeakReference <LifecycleListener>(listener)); 154 } 155 } 156 157 160 public void removeListener(LifecycleListener listener) 161 { 162 synchronized (this) { 163 164 if (_listeners == null) 165 return; 166 167 for (int i = _listeners.size() - 1; i >= 0; i--) { 168 LifecycleListener oldListener = _listeners.get(i).get(); 169 170 if (listener == oldListener) { 171 _listeners.remove(i); 172 173 return; 174 } 175 else if (oldListener == null) 176 _listeners.remove(i); 177 } 178 } 179 } 180 181 184 private void notifyListeners(int oldState, int newState) 185 { 186 synchronized (this) { 187 if (_listeners == null) { 188 return; 189 } 190 else { 191 for (int i = 0; i < _listeners.size(); i++) { 192 LifecycleListener listener = _listeners.get(i).get(); 193 194 if (listener != null) { 195 listener.lifecycleEvent(oldState, newState); 196 } 197 else { 198 _listeners.remove(i); 199 i--; 200 } 201 } 202 } 203 } 204 } 205 206 209 public int getState() 210 { 211 return _state; 212 } 213 214 217 public static String getStateName(int state) 218 { 219 switch (state) { 220 case IS_NEW: 221 return "new"; 222 case IS_INITIALIZING: 223 return "initializing"; 224 case IS_INIT: 225 return "init"; 226 case IS_STARTING: 227 return "starting"; 228 case IS_ACTIVE: 229 return "active"; 230 case IS_FAILED: 231 return "failed"; 232 case IS_STOPPING: 233 return "stopping"; 234 case IS_STOPPED: 235 return "stopped"; 236 case IS_DESTROYING: 237 return "destroying"; 238 case IS_DESTROYED: 239 return "destroyed"; 240 default: 241 return "unknown"; 242 } 243 } 244 245 248 public String getStateName() 249 { 250 return getStateName(_state); 251 } 252 253 256 public long getLastChangeTime() 257 { 258 return _lastChangeTime; 259 } 260 261 264 public long getLastFailTime() 265 { 266 return _lastFailTime; 267 } 268 269 272 public long getActiveCount() 273 { 274 return _activeCount; 275 } 276 277 280 public long getFailCount() 281 { 282 return _failCount; 283 } 284 285 288 public boolean isInitializing() 289 { 290 return _state == IS_INITIALIZING; 291 } 292 293 296 public boolean isInit() 297 { 298 return _state == IS_INIT; 299 } 300 301 304 public boolean isBeforeInit() 305 { 306 return _state < IS_INIT; 307 } 308 309 312 public boolean isAfterInit() 313 { 314 return _state >= IS_INIT; 315 } 316 317 320 public boolean isStarting() 321 { 322 return _state == IS_STARTING; 323 } 324 325 328 public boolean isWarmup() 329 { 330 return _state == IS_WARMUP; 331 } 332 333 336 public boolean isBeforeActive() 337 { 338 return _state < IS_ACTIVE; 339 } 340 341 344 public boolean isAfterActive() 345 { 346 return IS_ACTIVE < _state; 347 } 348 349 352 public boolean waitForActive(long timeout) 353 { 354 if (_state == IS_ACTIVE) 355 return true; 356 357 long waitEnd = Alarm.getCurrentTime() + timeout; 358 359 synchronized (this) { 360 while (Alarm.getCurrentTime() < waitEnd) { 361 if (_state == IS_ACTIVE) 362 return true; 363 else if (IS_ACTIVE < _state) 364 return false; 365 else if (Alarm.isTest()) 366 return false; 367 368 try { 369 wait(waitEnd - Alarm.getCurrentTime()); 370 } catch (InterruptedException e) { 371 } 372 } 373 } 374 375 return _state == IS_ACTIVE; 376 } 377 378 381 public boolean isActive() 382 { 383 return _state == IS_ACTIVE; 384 } 385 386 389 public boolean isRunnable() 390 { 391 return IS_WARMUP <= _state && _state <= IS_ACTIVE; 392 } 393 394 397 public boolean isError() 398 { 399 return isFailed(); 400 } 401 402 405 public boolean isFailed() 406 { 407 return _state == IS_FAILED; 408 } 409 410 413 public boolean isStopping() 414 { 415 return IS_STOPPING <= _state; 416 } 417 418 421 public boolean isStopped() 422 { 423 return IS_STOPPING <= _state; 424 } 425 426 429 public boolean isDestroying() 430 { 431 return IS_DESTROYING <= _state; 432 } 433 434 437 public boolean isDestroyed() 438 { 439 return IS_DESTROYED <= _state; 440 } 441 442 447 public synchronized boolean toInitializing() 448 { 449 if (IS_INITIALIZING <= _state) 450 return false; 451 452 int oldState = _state; 453 454 _state = IS_INITIALIZING; 455 _lastChangeTime = Alarm.getCurrentTime(); 456 457 if (_log != null && _log.isLoggable(Level.FINE)) 458 _log.fine(_name + " initializing"); 459 460 notifyListeners(oldState, _state); 461 462 return true; 463 } 464 465 470 public synchronized boolean toInit() 471 { 472 if (IS_INIT <= _state) 473 return false; 474 475 int oldState = _state; 476 477 _state = IS_INIT; 478 _lastChangeTime = Alarm.getCurrentTime(); 479 480 if (_log != null && _log.isLoggable(Level.FINE)) 481 _log.fine(_name + " initialized"); 482 483 notifyListeners(oldState, _state); 484 485 return true; 486 } 487 492 public synchronized boolean toPostInit() 493 { 494 if (IS_STOPPED == _state) { 495 int oldState = _state; 496 497 _state = IS_INIT; 498 _lastChangeTime = Alarm.getCurrentTime(); 499 500 notifyListeners(oldState, _state); 501 502 return true; 503 } 504 else if (IS_INIT == _state) { 505 return true; 506 } 507 508 return false; 509 } 510 511 516 public synchronized boolean toStarting() 517 { 518 if (_state < IS_STARTING || _state == IS_STOPPED) { 519 int oldState = _state; 520 521 _state = IS_STARTING; 522 _lastChangeTime = Alarm.getCurrentTime(); 523 524 if (_log != null && _log.isLoggable(_level)) 525 _log.log(_level, _name + " starting"); 526 527 notifyListeners(oldState, _state); 528 529 return true; 530 } 531 else 532 return false; 533 } 534 535 540 public synchronized boolean toActive() 541 { 542 if (_state < IS_ACTIVE || IS_FAILED <= _state && _state <= IS_STOPPED) { 543 int oldState = _state; 544 545 _state = IS_ACTIVE; 546 _lastChangeTime = Alarm.getCurrentTime(); 547 _activeCount++; 548 549 if (_log != null && _log.isLoggable(Level.FINE)) 550 _log.fine(_name + " active"); 551 552 notifyListeners(oldState, _state); 553 554 notifyAll(); 555 556 return true; 557 } 558 else 559 return false; 560 } 561 562 567 public boolean toError() 568 { 569 return toFail(); 570 } 571 572 577 public synchronized boolean toFail() 578 { 579 if (_state < IS_DESTROYING && _state != IS_FAILED) { 580 int oldState = _state; 581 582 _state = IS_FAILED; 583 _lastChangeTime = Alarm.getCurrentTime(); 584 _failCount++; 585 586 if (_log != null && _log.isLoggable(_level)) 587 _log.log(_level, _name + " error"); 588 589 notifyListeners(oldState, _state); 590 591 notifyAll(); 592 593 return true; 594 } 595 else 596 return false; 597 } 598 599 604 public synchronized boolean toStopping() 605 { 606 if (_state < IS_STOPPING && _state != IS_STARTING) { 607 int oldState = _state; 608 609 _state = IS_STOPPING; 610 _lastChangeTime = Alarm.getCurrentTime(); 611 612 if (_log != null && _log.isLoggable(_level)) 613 _log.log(_level, _name + " stopping"); 614 615 notifyListeners(oldState, _state); 616 617 return true; 618 } 619 else 620 return false; 621 } 622 623 628 public synchronized boolean toStop() 629 { 630 if (_state < IS_STOPPED) { 631 if (_log == null) { 632 } 633 else if (_state < IS_STOPPING && _log.isLoggable(_level)) 634 _log.log(_level, _name + " stopped"); 635 else if (_log.isLoggable(Level.FINE)) 636 _log.fine(_name + " stopped"); 637 638 int oldState = _state; 639 640 _state = IS_STOPPED; 641 _lastChangeTime = Alarm.getCurrentTime(); 642 643 notifyListeners(oldState, _state); 644 645 notifyAll(); 646 647 return true; 648 } 649 else 650 return false; 651 } 652 653 658 public synchronized boolean toDestroying() 659 { 660 if (_state < IS_DESTROYING) { 661 int oldState = _state; 662 663 _state = IS_DESTROYING; 664 _lastChangeTime = Alarm.getCurrentTime(); 665 666 if (_log != null && _log.isLoggable(Level.FINE)) 667 _log.fine(_name + " destroying"); 668 669 notifyListeners(oldState, _state); 670 671 return true; 672 } 673 else 674 return false; 675 } 676 677 682 public synchronized boolean toDestroy() 683 { 684 if (_state < IS_DESTROYED) { 685 int oldState = _state; 686 687 _state = IS_DESTROYED; 688 _lastChangeTime = Alarm.getCurrentTime(); 689 690 if (_log != null && _log.isLoggable(Level.FINE)) 691 _log.fine(_name + " destroyed"); 692 693 notifyListeners(oldState, _state); 694 695 notifyAll(); 696 697 return true; 698 } 699 else 700 return false; 701 } 702 703 708 public void copyState(Lifecycle source) 709 { 710 _state = source._state; 711 } 712 713 716 public String toString() 717 { 718 if (_name != null) 719 return "Lifecycle[" + _name + ", " + getStateName() + "]"; 720 else 721 return "Lifecycle[" + getStateName() + "]"; 722 } 723 } 724 | Popular Tags |