1 22 package com.scalagent.scheduler.event; 23 24 import java.util.Date ; 25 import java.util.Calendar ; 26 import java.util.TimeZone ; 27 import java.text.DateFormat ; 28 29 import fr.dyade.aaa.util.Strings; 30 31 40 public class PeriodicEvent implements DiaryEvent { 41 49 public static long getDate(long refDate, DiaryPeriod period) { 50 if ((refDate == -1) || 51 (period.value == 0)) 52 return -1; 53 PeriodicEvent pevt = new PeriodicEvent(refDate, period); 54 return pevt.getNextDate(refDate); 55 } 56 57 66 public static boolean checkField( 67 Calendar calendar, int field, int value) { 68 69 if (value >= 0) { 70 if (calendar.get(field) != value) 71 return false; 72 return true; 73 } 74 75 Calendar clone = (Calendar ) calendar.clone(); 77 switch (field) { 78 case Calendar.DAY_OF_MONTH: 79 clone.add(Calendar.DAY_OF_MONTH, -value); 80 if (clone.get(Calendar.DAY_OF_MONTH) != 1) 81 return false; 82 return true; 83 case Calendar.DAY_OF_WEEK_IN_MONTH: 84 clone.add(Calendar.DAY_OF_MONTH, -7 * value); 85 if (clone.get(Calendar.DAY_OF_MONTH) >= 7) 86 return false; 87 return true; 88 default: 89 break; 91 } 92 93 return false; 94 } 95 96 102 protected String timeZoneId = null; 103 104 111 protected long refDate = -1; 112 113 119 protected DiaryPeriod period = null; 120 121 133 protected int[] maskField = null; 134 135 144 protected int[] maskValue = null; 145 146 155 protected Calendar calendar; 156 157 172 public PeriodicEvent(String timeZoneId, long refDate, DiaryPeriod period, 173 int[] maskField, int[] maskValue) { 174 this.timeZoneId = timeZoneId; 175 this.refDate = refDate; 176 this.period = period; 177 this.maskField = maskField; 178 this.maskValue = maskValue; 179 180 if (timeZoneId == null) { 181 calendar = Calendar.getInstance(); 182 } else { 183 TimeZone tz = TimeZone.getTimeZone(timeZoneId); 184 if (tz == null) 185 calendar = Calendar.getInstance(); 186 else 187 calendar = Calendar.getInstance(tz); 188 } 189 190 if (refDate != -1) 191 calendar.setTime(new Date (refDate)); 192 } 193 194 201 public PeriodicEvent(String timeZoneId, long refDate, DiaryPeriod period) { 202 this(timeZoneId, refDate, period, null, null); 203 } 204 205 211 public PeriodicEvent(long refDate, DiaryPeriod period) { 212 this(null, refDate, period); 213 } 214 215 219 public PeriodicEvent() { 220 this(-1, null); 221 } 222 223 228 public void setTimeZoneId(String timeZoneId) { 229 this.timeZoneId = timeZoneId; 230 } 231 232 237 public String getTimeZoneId() { 238 return timeZoneId; 239 } 240 241 246 public void setRefDate(long refDate) { 247 this.refDate = refDate; 248 if (refDate != -1) 249 calendar.setTime(new Date (refDate)); 250 } 251 252 257 public long getRefDate() { 258 return refDate; 259 } 260 261 266 public void setPeriod(DiaryPeriod period) { 267 this.period = period; 268 } 269 270 275 public DiaryPeriod getPeriod() { 276 return period; 277 } 278 279 285 public void setMaskField(int[] maskField) { 286 if ((maskField != null) && (maskField.length == 0)) 287 this.maskField = null; 288 else 289 this.maskField = maskField; 290 } 291 292 297 public int[] getMaskField() { 298 return maskField; 299 } 300 301 307 public void setMaskValue(int[] maskValue) { 308 if ((maskValue != null) && (maskValue.length == 0)) 309 this.maskValue = null; 310 else 311 this.maskValue = maskValue; 312 } 313 314 319 public int[] getMaskValue() { 320 return maskValue; 321 } 322 323 344 public boolean validateMask() { 345 if ((maskField == null) || 346 (maskField.length == 0)) 347 return true; 348 349 if (period == null) { 350 return false; 352 } 353 354 boolean fillValue = false; 355 if (maskValue == null) { 356 fillValue = true; 357 maskValue = new int[maskField.length]; 358 } 359 360 if (refDate != -1) 362 calendar.setTime(new Date (refDate)); 363 364 if (maskField[0] == Calendar.YEAR) 365 return false; 366 int index = 0; 367 switch (period.unit) { 368 case Calendar.YEAR: 369 switch (maskField[index]) { 370 case Calendar.MONTH: 371 if (fillValue) { 372 if (refDate == -1) 373 return false; 374 maskValue[index] = calendar.get(Calendar.MONTH); 375 } else if (refDate != -1) { 376 if (! checkField(calendar, Calendar.MONTH, maskValue[index])) 377 return false; 378 } 379 index ++; 380 if (index >= maskField.length) 381 return false; 382 switch (maskField[index]) { 383 case Calendar.WEEK_OF_MONTH: 384 if (fillValue) { 385 if (refDate == -1) 386 return false; 387 maskValue[index] = calendar.get(Calendar.WEEK_OF_MONTH); 388 } else if (refDate != -1) { 389 if (! checkField(calendar, 390 Calendar.WEEK_OF_MONTH, 391 maskValue[index])) 392 return false; 393 } 394 index ++; 395 if (index < maskField.length) { 396 switch (maskField[index]) { 397 case Calendar.DAY_OF_WEEK: 398 if (fillValue) { 399 if (refDate == -1) 400 return false; 401 maskValue[index] = calendar.get(Calendar.DAY_OF_WEEK); 402 } else if (refDate != -1) { 403 if (! checkField(calendar, Calendar.DAY_OF_WEEK, maskValue[index])) 404 return false; 405 } 406 index ++; 407 if (index >= maskField.length) 408 return true; 409 return false; 410 default: 411 return false; 412 } 413 } else { 414 if (refDate == -1) 416 return false; 417 int mask[] = new int[index]; 418 System.arraycopy(maskField, 0, mask, 0, maskField.length); 419 maskField = mask; 420 maskField[index] = Calendar.DAY_OF_WEEK; 421 mask = new int[index]; 422 System.arraycopy(maskValue, 0, mask, 0, maskValue.length); 423 maskValue = mask; 424 maskValue[index] = calendar.get(Calendar.DAY_OF_WEEK); 425 return true; 426 } 427 case Calendar.DAY_OF_MONTH: 428 if (fillValue) { 429 if (refDate == -1) 430 return false; 431 maskValue[index] = calendar.get(Calendar.DAY_OF_MONTH); 432 } else if (refDate != -1) { 433 if (! checkField(calendar, Calendar.DAY_OF_MONTH, maskValue[index])) 434 return false; 435 } 436 index ++; 437 if (index >= maskField.length) 438 return true; 439 return false; 440 case Calendar.DAY_OF_WEEK_IN_MONTH: 441 if (fillValue) { 442 if (refDate == -1) 443 return false; 444 maskValue[index] = calendar.get(Calendar.DAY_OF_WEEK_IN_MONTH); 445 } else if (refDate != -1) { 446 if (! checkField(calendar, Calendar.DAY_OF_WEEK_IN_MONTH, maskValue[index])) 447 return false; 448 } 449 index ++; 450 if (index < maskField.length) { 451 switch (maskField[index]) { 452 case Calendar.DAY_OF_WEEK: 453 if (fillValue) { 454 if (refDate == -1) 455 return false; 456 maskValue[index] = calendar.get(Calendar.DAY_OF_WEEK); 457 } else if (refDate != -1) { 458 if (! checkField(calendar, Calendar.DAY_OF_WEEK, maskValue[index])) 459 return false; 460 } 461 index ++; 462 if (index >= maskField.length) 463 return true; 464 return false; 465 default: 466 return false; 467 } 468 } else { 469 if (refDate == -1) 471 return false; 472 int mask[] = new int[index]; 473 System.arraycopy(maskField, 0, mask, 0, maskField.length); 474 maskField = mask; 475 maskField[index] = Calendar.DAY_OF_WEEK; 476 mask = new int[index]; 477 System.arraycopy(maskValue, 0, mask, 0, maskValue.length); 478 maskValue = mask; 479 maskValue[index] = calendar.get(Calendar.DAY_OF_WEEK); 480 return true; 481 } 482 default: 483 return false; 484 } 485 case Calendar.WEEK_OF_YEAR: 486 if (fillValue) { 487 if (refDate == -1) 488 return false; 489 maskValue[index] = calendar.get(Calendar.WEEK_OF_YEAR); 490 } else if (refDate != -1) { 491 if (! checkField(calendar, Calendar.WEEK_OF_YEAR, maskValue[index])) 492 return false; 493 } 494 index ++; 495 if (index < maskField.length) { 496 switch (maskField[index]) { 497 case Calendar.DAY_OF_WEEK: 498 if (fillValue) { 499 if (refDate == -1) 500 return false; 501 maskValue[index] = calendar.get(Calendar.DAY_OF_WEEK); 502 } else if (refDate != -1) { 503 if (! checkField(calendar, Calendar.DAY_OF_WEEK, maskValue[index])) 504 return false; 505 } 506 index ++; 507 if (index >= maskField.length) 508 return true; 509 return false; 510 default: 511 return false; 512 } 513 } else { 514 if (refDate == -1) 516 return false; 517 int mask[] = new int[index]; 518 System.arraycopy(maskField, 0, mask, 0, maskField.length); 519 maskField = mask; 520 maskField[index] = Calendar.DAY_OF_WEEK; 521 mask = new int[index]; 522 System.arraycopy(maskValue, 0, mask, 0, maskValue.length); 523 maskValue = mask; 524 maskValue[index] = calendar.get(Calendar.DAY_OF_WEEK); 525 return true; 526 } 527 case Calendar.DAY_OF_YEAR: 528 if (fillValue) { 529 if (refDate == -1) 530 return false; 531 maskValue[index] = calendar.get(Calendar.DAY_OF_YEAR); 532 } else if (refDate != -1) { 533 if (! checkField(calendar, Calendar.DAY_OF_YEAR, maskValue[index])) 534 return false; 535 } 536 index ++; 537 if (index >= maskField.length) 538 return true; 539 return false; 540 } 541 break; 542 case Calendar.MONTH: 543 switch (maskField[index]) { 544 case Calendar.WEEK_OF_MONTH: 545 if (fillValue) { 546 if (refDate == -1) 547 return false; 548 maskValue[index] = calendar.get(Calendar.WEEK_OF_MONTH); 549 } else if (refDate != -1) { 550 if (! checkField(calendar, Calendar.WEEK_OF_MONTH, maskValue[index])) 551 return false; 552 } 553 index ++; 554 if (index < maskField.length) { 555 switch (maskField[index]) { 556 case Calendar.DAY_OF_WEEK: 557 if (fillValue) { 558 if (refDate == -1) 559 return false; 560 maskValue[index] = calendar.get(Calendar.DAY_OF_WEEK); 561 } else if (refDate != -1) { 562 if (! checkField(calendar, Calendar.DAY_OF_WEEK, maskValue[index])) 563 return false; 564 } 565 index ++; 566 if (index >= maskField.length) 567 return true; 568 return false; 569 default: 570 return false; 571 } 572 } else { 573 if (refDate == -1) 575 return false; 576 int mask[] = new int[index]; 577 System.arraycopy(maskField, 0, mask, 0, maskField.length); 578 maskField = mask; 579 maskField[index] = Calendar.DAY_OF_WEEK; 580 mask = new int[index]; 581 System.arraycopy(maskValue, 0, mask, 0, maskValue.length); 582 maskValue = mask; 583 maskValue[index] = calendar.get(Calendar.DAY_OF_WEEK); 584 return true; 585 } 586 case Calendar.DAY_OF_MONTH: 587 if (fillValue) { 588 if (refDate == -1) 589 return false; 590 maskValue[index] = calendar.get(Calendar.DAY_OF_MONTH); 591 } else if (refDate != -1) { 592 if (! checkField(calendar, Calendar.DAY_OF_MONTH, maskValue[index])) 593 return false; 594 } 595 index ++; 596 if (index >= maskField.length) 597 return true; 598 return false; 599 case Calendar.DAY_OF_WEEK_IN_MONTH: 600 if (fillValue) { 601 if (refDate == -1) 602 return false; 603 maskValue[index] = calendar.get(Calendar.DAY_OF_WEEK_IN_MONTH); 604 } else if (refDate != -1) { 605 if (! checkField(calendar, Calendar.DAY_OF_WEEK_IN_MONTH, maskValue[index])) 606 return false; 607 } 608 index ++; 609 if (index < maskField.length) { 610 switch (maskField[index]) { 611 case Calendar.DAY_OF_WEEK: 612 if (fillValue) { 613 if (refDate == -1) 614 return false; 615 maskValue[index] = calendar.get(Calendar.DAY_OF_WEEK); 616 } else if (refDate != -1) { 617 if (! checkField(calendar, Calendar.DAY_OF_WEEK, maskValue[index])) 618 return false; 619 } 620 index ++; 621 if (index >= maskField.length) 622 return true; 623 return false; 624 default: 625 return false; 626 } 627 } else { 628 if (refDate == -1) 630 return false; 631 int mask[] = new int[index]; 632 System.arraycopy(maskField, 0, mask, 0, maskField.length); 633 maskField = mask; 634 maskField[index] = Calendar.DAY_OF_WEEK; 635 mask = new int[index]; 636 System.arraycopy(maskValue, 0, mask, 0, maskValue.length); 637 maskValue = mask; 638 maskValue[index] = calendar.get(Calendar.DAY_OF_WEEK); 639 return true; 640 } 641 default: 642 return false; 643 } 644 default: 645 return false; 647 } 648 649 return false; 651 } 652 653 658 public String toString() { 659 StringBuffer output = new StringBuffer (); 660 output.append("("); 661 output.append(super.toString()); 662 output.append(",timeZoneId="); 663 Strings.toString(output, timeZoneId); 664 output.append(",refDate="); 665 output.append(refDate); 666 if (refDate > 0) { 667 output.append("("); 668 output.append(DateFormat.getDateTimeInstance().format( 669 new Date (refDate))); 670 output.append(")"); 671 } 672 output.append(",period="); 673 output.append(period); 674 output.append(",maskField="); 675 Strings.toStringArray(output, maskField); 676 output.append(",maskValue="); 677 Strings.toStringArray(output, maskValue); 678 output.append(")"); 679 return output.toString(); 680 } 681 682 685 protected void applyMask() { 686 if (maskField == null) 687 return; 688 689 int lastDayInMonth = 0; 690 691 for (int i = 0; i < maskField.length; i ++) { 692 if ((maskField[i] == Calendar.DAY_OF_MONTH) && 694 (maskValue[i] < 0)) { 695 lastDayInMonth = maskValue[i]; 696 calendar.set(Calendar.DAY_OF_MONTH, 33); 697 } else { 698 calendar.set(maskField[i], maskValue[i]); 699 } 700 } 701 702 if (lastDayInMonth != 0) { 703 calendar.get(Calendar.MONTH); 707 calendar.set(Calendar.DAY_OF_MONTH, lastDayInMonth + 1); 708 } 709 } 710 711 714 protected boolean checkMask() { 715 if (maskField == null) 716 return true; 717 718 for (int i = 0; i < maskField.length; i ++) { 719 if ((maskValue[i] > 0) && 720 (calendar.get(maskField[i]) != maskValue[i])) 721 return false; 722 } 723 724 return true; 725 } 726 727 739 public long getNextDate(long now, boolean inclusive) { 740 return getNextDate(now, 1, inclusive); 741 } 742 743 755 public long getNextDate(long now) { 756 return getNextDate(now, false); 757 } 758 759 771 public long getLastDate(long now, boolean inclusive) { 772 return getNextDate(now, -1, inclusive); 773 } 774 775 787 public long getLastDate(long now) { 788 return getLastDate(now, false); 789 } 790 791 805 private long getNextDate(long now, int dir, boolean inclusive) { 806 if (dir == 0) 807 return -1; 808 if (dir > 0) 809 dir = 1; 810 else 811 dir = -1; 812 813 if (refDate == -1) 814 return -1; 815 816 long date = calendar.getTime().getTime(); 819 if (inclusive && (date == now)) 820 return date; 821 822 if (period.value == 0) 823 return -1; 824 825 Calendar clone = (Calendar ) calendar.clone(); 826 827 long pnum = now - date; 829 int sign = 1; 830 if (pnum > 0) { 831 sign = dir; 832 } else { 833 pnum = -pnum; 834 sign = -dir; 835 } 836 switch (period.unit) { 837 case Calendar.YEAR: 838 pnum /= 12; 839 case Calendar.MONTH: 840 pnum /= 30; 841 case Calendar.DAY_OF_MONTH: 842 pnum /= 24; 843 case Calendar.HOUR_OF_DAY: 844 pnum /= 60; 845 case Calendar.MINUTE: 846 pnum /= 60; 847 case Calendar.SECOND: 848 pnum /= 1000; 849 } 850 pnum /= period.value; 851 852 pnum_loop: 854 while (pnum > 3) { 855 calendar.add(period.unit, (int) (pnum * period.value * dir * sign)); 856 857 applyMask(); 859 if (! checkMask()) { 860 calendar = clone; 862 clone = (Calendar ) calendar.clone(); 863 pnum --; 864 continue pnum_loop; 865 } 866 867 clone = (Calendar ) calendar.clone(); 869 break pnum_loop; 870 } 871 872 date = calendar.getTime().getTime(); 873 if (now == date) { 874 if (inclusive) 875 return date; 876 sign = 1; 877 } else if (now > date) { 878 sign = dir; 879 } else { 880 sign = -dir; 881 } 882 pnum = 1; 883 884 main_loop: 885 while (true) { 886 calendar.add(period.unit, (int) (pnum * period.value * dir * sign)); 887 888 applyMask(); 889 890 date = calendar.getTime().getTime(); 891 if ((sign == -1) && 892 ((((date - now) * dir) < 0) || 893 (!inclusive && (date == now)))) { 894 calendar = clone; 895 return calendar.getTime().getTime(); 896 } 897 898 if (! checkMask()) { 899 calendar = clone; 901 clone = (Calendar ) calendar.clone(); 902 pnum ++; 903 continue main_loop; 904 } 905 906 if ((sign == 1) && 908 ((((date - now) * dir) > 0) || 909 (inclusive && (date == now)))) { 910 return date; 911 } 912 913 clone = (Calendar ) calendar.clone(); 914 pnum = 1; 915 } 916 917 } 919 } 920
| Popular Tags
|