1 2 18 19 22 package org.quartz; 23 24 import java.util.Date ; 25 26 27 40 public class SimpleTrigger extends Trigger { 41 42 49 50 64 public static final int MISFIRE_INSTRUCTION_FIRE_NOW = 1; 65 66 89 public static final int MISFIRE_INSTRUCTION_RESCHEDULE_NOW_WITH_EXISTING_REPEAT_COUNT = 2; 90 91 115 public static final int MISFIRE_INSTRUCTION_RESCHEDULE_NOW_WITH_REMAINING_REPEAT_COUNT = 3; 116 117 131 public static final int MISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_REMAINING_COUNT = 4; 132 133 154 public static final int MISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_EXISTING_COUNT = 5; 155 156 163 public static int REPEAT_INDEFINITELY = -1; 164 165 172 173 private Date startTime = null; 174 175 private Date endTime = null; 176 177 private Date nextFireTime = null; 178 179 private Date previousFireTime = null; 180 181 private int repeatCount = 0; 182 183 private long repeatInterval = 0; 184 185 private int timesTriggered = 0; 186 187 private boolean complete = false; 188 189 196 197 202 public SimpleTrigger() { 203 super(); 204 } 205 206 212 public SimpleTrigger(String name, String group) { 213 this(name, group, new Date (), null, 0, 0); 214 } 215 216 222 public SimpleTrigger(String name, String group, int repeatCount, 223 long repeatInterval) { 224 this(name, group, new Date (), null, repeatCount, repeatInterval); 225 } 226 227 233 public SimpleTrigger(String name, String group, Date startTime) { 234 this(name, group, startTime, null, 0, 0); 235 } 236 237 256 public SimpleTrigger(String name, String group, Date startTime, 257 Date endTime, int repeatCount, long repeatInterval) { 258 super(name, group); 259 260 setStartTime(startTime); 261 setEndTime(endTime); 262 setRepeatCount(repeatCount); 263 setRepeatInterval(repeatInterval); 264 } 265 266 285 public SimpleTrigger(String name, String group, String jobName, 286 String jobGroup, Date startTime, Date endTime, int repeatCount, 287 long repeatInterval) { 288 super(name, group, jobName, jobGroup); 289 290 setStartTime(startTime); 291 setEndTime(endTime); 292 setRepeatCount(repeatCount); 293 setRepeatInterval(repeatInterval); 294 } 295 296 303 304 309 public Date getStartTime() { 310 return startTime; 311 } 312 313 321 public void setStartTime(Date startTime) { 322 if (startTime == null) { 323 throw new IllegalArgumentException ("Start time cannot be null"); 324 } 325 326 Date eTime = getEndTime(); 327 if (eTime != null && startTime != null && eTime.before(startTime)) { 328 throw new IllegalArgumentException ( 329 "End time cannot be before start time"); 330 } 331 332 this.startTime = startTime; 333 } 334 335 343 public Date getEndTime() { 344 return endTime; 345 } 346 347 356 public void setEndTime(Date endTime) { 357 Date sTime = getStartTime(); 358 if (sTime != null && endTime != null && sTime.after(endTime)) { 359 throw new IllegalArgumentException ( 360 "End time cannot be before start time"); 361 } 362 363 this.endTime = endTime; 364 } 365 366 374 public int getRepeatCount() { 375 return repeatCount; 376 } 377 378 388 public void setRepeatCount(int repeatCount) { 389 if (repeatCount < 0 && repeatCount != REPEAT_INDEFINITELY) { 390 throw new IllegalArgumentException ( 391 "Repeat count must be >= 0, use the " 392 + "constant REPEAT_INDEFINITELY for infinite."); 393 } 394 395 this.repeatCount = repeatCount; 396 } 397 398 404 public long getRepeatInterval() { 405 return repeatInterval; 406 } 407 408 417 public void setRepeatInterval(long repeatInterval) { 418 if (repeatInterval < 0) { 419 throw new IllegalArgumentException ( 420 "Repeat interval must be >= 0"); 421 } 422 423 this.repeatInterval = repeatInterval; 424 } 425 426 432 public int getTimesTriggered() { 433 return timesTriggered; 434 } 435 436 442 public void setTimesTriggered(int timesTriggered) { 443 this.timesTriggered = timesTriggered; 444 } 445 446 protected boolean validateMisfireInstruction(int misfireInstruction) { 447 if (misfireInstruction < MISFIRE_INSTRUCTION_SMART_POLICY) { 448 return false; 449 } 450 451 if (misfireInstruction > MISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_EXISTING_COUNT) { 452 return false; 453 } 454 455 return true; 456 } 457 458 483 public void updateAfterMisfire(Calendar cal) { 484 int instr = getMisfireInstruction(); 485 if (instr == Trigger.MISFIRE_INSTRUCTION_SMART_POLICY) { 486 if (getRepeatCount() == 0) { 487 instr = MISFIRE_INSTRUCTION_FIRE_NOW; 488 } else if (getRepeatCount() == REPEAT_INDEFINITELY) { 489 instr = MISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_REMAINING_COUNT; 490 } else { 491 instr = MISFIRE_INSTRUCTION_RESCHEDULE_NOW_WITH_EXISTING_REPEAT_COUNT; 493 } 494 } else if (instr == MISFIRE_INSTRUCTION_FIRE_NOW && getRepeatCount() != 0) { 495 instr = MISFIRE_INSTRUCTION_RESCHEDULE_NOW_WITH_REMAINING_REPEAT_COUNT; 496 } 497 498 if (instr == MISFIRE_INSTRUCTION_FIRE_NOW) { 499 setNextFireTime(new Date ()); 500 } else if (instr == MISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_EXISTING_COUNT) { 501 Date newFireTime = getFireTimeAfter(new Date ()); 502 while (newFireTime != null && cal != null 503 && !cal.isTimeIncluded(newFireTime.getTime())) { 504 newFireTime = getFireTimeAfter(newFireTime); 505 } 506 setNextFireTime(newFireTime); 507 } else if (instr == MISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_REMAINING_COUNT) { 508 Date newFireTime = getFireTimeAfter(new Date ()); 509 while (newFireTime != null && cal != null 510 && !cal.isTimeIncluded(newFireTime.getTime())) { 511 newFireTime = getFireTimeAfter(newFireTime); 512 } 513 if (newFireTime != null) { 514 int timesMissed = computeNumTimesFiredBetween(nextFireTime, 515 newFireTime); 516 setTimesTriggered(getTimesTriggered() + timesMissed); 517 } 518 519 setNextFireTime(newFireTime); 520 } else if (instr == MISFIRE_INSTRUCTION_RESCHEDULE_NOW_WITH_EXISTING_REPEAT_COUNT) { 521 Date newFireTime = new Date (); 522 if (repeatCount != 0 && repeatCount != REPEAT_INDEFINITELY) { 523 setRepeatCount(getRepeatCount() - getTimesTriggered()); 524 setTimesTriggered(0); 525 } 526 527 if (getEndTime() != null && getEndTime().before(newFireTime)) { 528 setNextFireTime(null); } else { 530 setStartTime(newFireTime); 531 setNextFireTime(newFireTime); 532 } 533 } else if (instr == MISFIRE_INSTRUCTION_RESCHEDULE_NOW_WITH_REMAINING_REPEAT_COUNT) { 534 Date newFireTime = new Date (); 535 536 int timesMissed = computeNumTimesFiredBetween(nextFireTime, 537 newFireTime); 538 539 if (repeatCount != 0 && repeatCount != REPEAT_INDEFINITELY) { 540 int remainingCount = getRepeatCount() 541 - (getTimesTriggered() + timesMissed); 542 if (remainingCount <= 0) { 543 remainingCount = 0; 544 } 545 setRepeatCount(remainingCount); 546 setTimesTriggered(0); 547 } 548 549 if (getEndTime() != null && getEndTime().before(newFireTime)) { 550 setNextFireTime(null); } else { 552 setStartTime(newFireTime); 553 setNextFireTime(newFireTime); 554 } 555 } 556 557 } 558 559 569 public void triggered(Calendar calendar) { 570 timesTriggered++; 571 previousFireTime = nextFireTime; 572 nextFireTime = getFireTimeAfter(nextFireTime); 573 574 while (nextFireTime != null && calendar != null 575 && !calendar.isTimeIncluded(nextFireTime.getTime())) { 576 nextFireTime = getFireTimeAfter(nextFireTime); 577 } 578 } 579 580 584 public void updateWithNewCalendar(Calendar calendar, long misfireThreshold) 585 { 586 nextFireTime = getFireTimeAfter(previousFireTime); 587 588 Date now = new Date (); 589 do { 590 while (nextFireTime != null && calendar != null 591 && !calendar.isTimeIncluded(nextFireTime.getTime())) { 592 nextFireTime = getFireTimeAfter(nextFireTime); 593 } 594 595 if(nextFireTime != null && nextFireTime.before(now)) { 596 long diff = now.getTime() - nextFireTime.getTime(); 597 if(diff >= misfireThreshold) { 598 nextFireTime = getFireTimeAfter(nextFireTime); 599 continue; 600 } 601 } 602 }while(false); 603 } 604 605 622 public Date computeFirstFireTime(Calendar calendar) { 623 nextFireTime = getStartTime(); 624 625 while (nextFireTime != null && calendar != null 626 && !calendar.isTimeIncluded(nextFireTime.getTime())) { 627 nextFireTime = getFireTimeAfter(nextFireTime); 628 } 629 630 return nextFireTime; 631 } 632 633 654 public int executionComplete(JobExecutionContext context, 655 JobExecutionException result) { 656 if (result != null && result.refireImmediately()) { 657 return INSTRUCTION_RE_EXECUTE_JOB; 658 } 659 660 if (result != null && result.unscheduleFiringTrigger()) { 661 return INSTRUCTION_SET_TRIGGER_COMPLETE; 662 } 663 664 if (result != null && result.unscheduleAllTriggers()) { 665 return INSTRUCTION_SET_ALL_JOB_TRIGGERS_COMPLETE; 666 } 667 668 if (!mayFireAgain()) { 669 return INSTRUCTION_DELETE_TRIGGER; 670 } 671 672 return INSTRUCTION_NOOP; 673 } 674 675 683 public Date getNextFireTime() { 684 return nextFireTime; 685 } 686 687 693 public Date getPreviousFireTime() { 694 return previousFireTime; 695 } 696 697 706 public void setNextFireTime(Date nextFireTime) { 707 this.nextFireTime = nextFireTime; 708 } 709 710 719 public void setPreviousFireTime(Date previousFireTime) { 720 this.previousFireTime = previousFireTime; 721 } 722 723 730 public Date getFireTimeAfter(Date afterTime) { 731 if (complete) { 732 return null; 733 } 734 735 if ((timesTriggered > repeatCount) 736 && (repeatCount != REPEAT_INDEFINITELY)) { 737 return null; 738 } 739 740 if (afterTime == null) { 741 afterTime = new Date (); 742 } 743 744 if (repeatCount == 0 && afterTime.compareTo(getStartTime()) >= 0) { 745 return null; 746 } 747 748 long startMillis = getStartTime().getTime(); 749 long afterMillis = afterTime.getTime(); 750 long endMillis = (getEndTime() == null) ? Long.MAX_VALUE : getEndTime() 751 .getTime(); 752 753 if (endMillis <= afterMillis) { 754 return null; 755 } 756 757 if (afterMillis < startMillis) { 758 return new Date (startMillis); 759 } 760 761 long numberOfTimesExecuted = ((afterMillis - startMillis) / repeatInterval) + 1; 762 763 if ((numberOfTimesExecuted > repeatCount) && 764 (repeatCount != REPEAT_INDEFINITELY)) { 765 return null; 766 } 767 768 Date time = new Date (startMillis + (numberOfTimesExecuted * repeatInterval)); 769 770 if (endMillis <= time.getTime()) { 771 return null; 772 } 773 774 return time; 775 } 776 777 784 public Date getFireTimeBefore(Date end) { 785 if (end.getTime() < getStartTime().getTime()) { 786 return null; 787 } 788 789 int numFires = computeNumTimesFiredBetween(getStartTime(), end); 790 791 return new Date (getStartTime().getTime() + (numFires * repeatInterval)); 792 } 793 794 public int computeNumTimesFiredBetween(Date start, Date end) { 795 796 if(repeatInterval < 1) { 797 return 0; 798 } 799 800 long time = end.getTime() - start.getTime(); 801 802 return (int) (time / repeatInterval); 803 } 804 805 815 public Date getFinalFireTime() { 816 if (repeatCount == 0) { 817 return startTime; 818 } 819 820 if (repeatCount == REPEAT_INDEFINITELY) { 821 return (getEndTime() == null) ? null : getFireTimeBefore(getEndTime()); 822 } 823 824 long lastTrigger = startTime.getTime() + (repeatCount * repeatInterval); 825 826 if ((getEndTime() == null) || (lastTrigger < getEndTime().getTime())) { 827 return new Date (lastTrigger); 828 } else { 829 return getFireTimeBefore(getEndTime()); 830 } 831 } 832 833 839 public boolean mayFireAgain() { 840 return (getNextFireTime() != null); 841 } 842 843 852 public void validate() throws SchedulerException { 853 super.validate(); 854 855 if (repeatCount != 0 && repeatInterval < 1) { 856 throw new SchedulerException("Repeat Interval cannot be zero.", 857 SchedulerException.ERR_CLIENT_ERROR); 858 } 859 } 860 861 public static void main(String [] args) throws Exception { 864 865 Date sdt = new Date (); 866 867 Date edt = new Date (sdt.getTime() + 55000L); 868 869 SimpleTrigger st = new SimpleTrigger("t", "g", "j", "g", sdt, edt, 10, 870 10000L); 871 872 System.err.println(); 873 874 st.computeFirstFireTime(null); 875 876 System.err.println("lastTime=" + st.getFinalFireTime()); 877 878 java.util.List times = TriggerUtils.computeFireTimes(st, null, 50); 879 880 for (int i = 0; i < times.size(); i++) { 881 System.err.println("firetime = " + times.get(i)); 882 } 883 } 884 885 } 886 | Popular Tags |