1 20 21 package com.jtheory.jdring; 22 23 import java.util.Calendar ; 24 import java.util.Date ; 25 import java.util.Arrays ; 26 27 33 public class AlarmEntry implements Comparable , java.io.Serializable { 34 private int[] minutes = {-1}; 35 private static int minMinute = 0; 36 private static int maxMinute = 59; 37 38 private int[] hours = {-1}; 39 private static int minHour = 0; 40 private static int maxHour = 23; 41 42 private int[] daysOfMonth = {-1}; 43 private static int minDayOfMonth = 1; 44 46 private int[] months = {-1}; 47 private static int minMonth = 0; 48 private static int maxMonth = 11; 49 50 private int[] daysOfWeek = {-1}; 51 private static int minDayOfWeek = 1; 52 private static int maxDayOfWeek = 7; 53 54 private int year = -1; 56 private String name; 57 private static int UNIQUE = 0; 59 private boolean ringInNewThread = false; 61 private boolean isRelative; 62 public boolean isRepeating; 63 public long alarmTime; 64 private long lastUpdateTime; 65 private transient AlarmListener listener; 66 private transient boolean debug = false; 67 68 private void debug(String s) { 69 if (debug) 70 System.out.println("[" + Thread.currentThread().getName() + "] AlarmEntry "+name+": " + s); 71 } 72 73 82 public AlarmEntry(String _name, Date _date, AlarmListener _listener) 83 throws PastDateException { 84 85 setName(_name); 86 listener = _listener; 87 Calendar alarm = Calendar.getInstance(); 88 alarm.setTime(_date); 89 minutes = new int[] { alarm.get(Calendar.MINUTE) }; 90 hours = new int[] { alarm.get(Calendar.HOUR_OF_DAY) }; 91 daysOfMonth = new int[] { alarm.get(Calendar.DAY_OF_MONTH) }; 92 months = new int[] { alarm.get(Calendar.MONTH) }; 93 year = alarm.get( Calendar.YEAR ); 94 95 isRepeating = false; 96 isRelative = false; 97 alarmTime = _date.getTime(); 98 checkAlarmTime(); 99 } 100 101 public AlarmEntry(Date _date, AlarmListener _listener) 102 throws PastDateException { 103 this(null, _date, _listener); 104 } 105 106 118 public AlarmEntry(String _name, int _delayMinutes, boolean _isRepeating, AlarmListener _listener) 119 throws PastDateException { 120 if (_delayMinutes < 1) { 121 throw new PastDateException(); 122 } 123 124 setName(_name); 125 minutes = new int[] { _delayMinutes }; 126 listener = _listener; 127 isRepeating = _isRepeating; 128 129 isRelative = true; 130 updateAlarmTime(); 131 } 132 133 public AlarmEntry(int _delayMinutes, boolean _isRepeating, AlarmListener _listener) 134 throws PastDateException { 135 this(null, _delayMinutes, _isRepeating, _listener); 136 } 137 138 139 168 public AlarmEntry(String _name, int _minute, int _hour, int _dayOfMonth, int _month, 169 int _dayOfWeek, int _year, AlarmListener _listener) 170 throws PastDateException { 171 this(_name, new int[]{_minute}, new int[]{_hour}, new int[]{_dayOfMonth}, new int[]{_month}, 172 new int[]{_dayOfWeek}, _year, _listener); 173 } 174 175 public AlarmEntry(int _minute, int _hour, int _dayOfMonth, int _month, 176 int _dayOfWeek, int _year, AlarmListener _listener) 177 throws PastDateException { 178 this(null, _minute, _hour, _dayOfMonth, _month, 179 _dayOfWeek, _year, _listener); 180 } 181 182 183 213 public AlarmEntry(String _name, int[] _minutes, int[] _hours, int[] _daysOfMonth, int[] _months, 214 int[] _daysOfWeek, int _year, AlarmListener _listener) 215 throws PastDateException { 216 217 setName(_name); 218 minutes = _minutes; 219 hours = _hours; 220 daysOfMonth = _daysOfMonth; 221 months = _months; 222 daysOfWeek = _daysOfWeek; 223 year = _year; 224 listener = _listener; 225 isRepeating = (_year == -1); 226 isRelative = false; 227 228 updateAlarmTime(); 229 checkAlarmTime(); 230 } 231 232 public AlarmEntry( int[] _minutes, int[] _hours, int[] _daysOfMonth, int[] _months, 233 int[] _daysOfWeek, int _year, AlarmListener _listener) 234 throws PastDateException { 235 this(null, _minutes, _hours, _daysOfMonth, _months, 236 _daysOfWeek, _year, _listener); 237 } 238 239 243 private void setName(String _name) 244 { 245 name = _name; 246 if( name == null ) 247 name = "alarm" + (UNIQUE++); 248 } 249 250 public String getName() { 251 return name; 252 } 253 254 261 public void setRingInNewThead() 262 { 263 ringInNewThread = true; 264 } 265 public boolean isRingInNewThread() 266 { 267 return ringInNewThread; 268 } 269 270 271 278 void checkAlarmTime() throws PastDateException { 279 long delay = alarmTime - System.currentTimeMillis(); 280 281 if (delay <= 1000) { 282 throw new PastDateException(); 283 } 284 } 285 286 287 290 public void ringAlarm() 291 { 292 listener.handleAlarm(this); 293 } 294 295 298 public void updateAlarmTime() { 299 Calendar now = Calendar.getInstance(); 300 301 if (isRelative) { 302 alarmTime = now.getTime().getTime() + (minutes[0] * 60000); 304 return; 305 } 306 307 Calendar alarm = (Calendar )now.clone(); 308 alarm.set( Calendar.SECOND, 0 ); 309 310 debug("now: " + now.getTime()); 311 312 318 int current = alarm.get( Calendar.MINUTE ); 320 int offset = 0; 321 offset = getOffsetToNext( current, minMinute, maxMinute, minutes ); 323 alarm.add( Calendar.MINUTE, offset ); 324 debug( "after min: " + alarm.getTime() ); 325 326 current = alarm.get( Calendar.HOUR_OF_DAY ); offset = getOffsetToNextOrEqual( current, minHour, maxHour, hours ); 329 alarm.add( Calendar.HOUR_OF_DAY, offset ); 330 debug( "after hour (current:"+current+"): " + alarm.getTime() ); 331 332 if( daysOfMonth[0] != -1 && daysOfWeek[0] != -1 ) 339 { 340 Calendar dayOfWeekAlarm = (Calendar )alarm.clone(); 342 updateDayOfWeekAndMonth( dayOfWeekAlarm ); 343 344 Calendar dayOfMonthAlarm = (Calendar )alarm.clone(); 345 updateDayOfMonthAndMonth( dayOfMonthAlarm ); 346 347 if( dayOfMonthAlarm.getTime().getTime() < dayOfWeekAlarm.getTime().getTime() ) 349 { 350 alarm = dayOfMonthAlarm; 351 debug( "after dayOfMonth CLOSER: " + alarm.getTime() ); 352 } 353 else 354 { 355 alarm = dayOfWeekAlarm; 356 debug( "after dayOfWeek CLOSER: " + alarm.getTime() ); 357 } 358 } 359 else if( daysOfWeek[0] != -1 ) { 361 updateDayOfWeekAndMonth( alarm ); 363 debug( "after dayOfWeek: " + alarm.getTime() ); 364 } 365 else if( daysOfMonth[0] != -1 ) { 367 updateDayOfMonthAndMonth( alarm ); 369 debug( "after dayOfMonth: " + alarm.getTime() ); 370 } 371 373 374 debug("alarm: " + alarm.getTime()); 375 376 alarmTime = alarm.getTime().getTime(); 377 lastUpdateTime = System.currentTimeMillis(); 378 } 379 380 386 void updateDayOfMonthAndMonth( Calendar alarm ) 387 { 388 int currentMonth = alarm.get( Calendar.MONTH ); 389 int currentDayOfMonth = alarm.get( Calendar.DAY_OF_MONTH ); 390 int offset = 0; 391 392 while( !isIn(currentMonth, months) || !isIn(currentDayOfMonth, daysOfMonth) ) 394 { 395 if( !isIn(currentMonth, months) ) 397 { 398 offset = getOffsetToNextOrEqual( currentMonth, minMonth, maxMonth, months ); 399 alarm.add( Calendar.MONTH, offset ); 400 alarm.set( Calendar.DAY_OF_MONTH, 1 ); 401 currentDayOfMonth = 1; 402 } 403 404 if( !isIn(currentDayOfMonth, daysOfMonth) ) 406 { 407 int maxDayOfMonth = alarm.getActualMaximum( Calendar.DAY_OF_MONTH ); 408 offset = getOffsetToNextOrEqual( currentDayOfMonth, minDayOfMonth, maxDayOfMonth, daysOfMonth ); 409 alarm.add( Calendar.DAY_OF_MONTH, offset ); 410 } 411 412 currentMonth = alarm.get( Calendar.MONTH ); 413 currentDayOfMonth = alarm.get( Calendar.DAY_OF_MONTH ); 414 } 415 } 416 417 418 void updateDayOfWeekAndMonth( Calendar alarm ) 419 { 420 int currentMonth = alarm.get( Calendar.MONTH ); 421 int currentDayOfWeek = alarm.get( Calendar.DAY_OF_WEEK ); 422 int offset = 0; 423 424 while( !isIn(currentMonth, months) || !isIn(currentDayOfWeek, daysOfWeek) ) 426 { 427 if( !isIn(currentMonth, months) ) 429 { 430 offset = getOffsetToNextOrEqual( currentMonth, minMonth, maxMonth, months ); 431 alarm.add( Calendar.MONTH, offset ); 432 alarm.set( Calendar.DAY_OF_MONTH, 1 ); 433 currentDayOfWeek = alarm.get( Calendar.DAY_OF_WEEK ); 434 } 435 436 if( !isIn(currentDayOfWeek, daysOfWeek) ) 438 { 439 offset = getOffsetToNextOrEqual( currentDayOfWeek, minDayOfWeek, maxDayOfWeek, daysOfWeek ); 440 alarm.add( Calendar.DAY_OF_YEAR, offset ); 441 } 442 443 currentDayOfWeek = alarm.get( Calendar.DAY_OF_WEEK ); 444 currentMonth = alarm.get( Calendar.MONTH ); 445 } 446 } 447 448 449 450 454 462 static int getOffsetToNext( int current, int min, int max, int[] values ) 463 { 464 int offset = 0; 465 466 468 if (values[0] == -1 ) 470 { 471 offset = 1; 472 } 473 else 474 { 475 if( current >= last(values) ) 477 { 478 int next = values[0]; 479 offset = (max-current+1) + (next-min); 480 } 481 else { 483 findvalue: 484 for( int i=0; i<values.length; i++ ) 485 { 486 if( current < values[i] ) 487 { 488 offset = values[i] - current; 489 break findvalue; 490 } 491 } 492 } } 494 495 return offset; 496 } 497 498 506 static int getOffsetToNextOrEqual( int current, int min, int max, int[] values ) 507 { 508 int offset = 0; 509 int[] safeValues = null; 510 511 513 if (values[0] == -1 || isIn(current, values) ) 515 { 516 offset = 0; 517 } 518 else 519 { 520 safeValues = discardValuesOverMax( values, max ); 521 522 if( current > last(safeValues) ) 524 { 525 int next = safeValues[0]; 526 offset = (max-current+1) + (next-min); 527 } 528 else { 530 findvalue: 531 for( int i=0; i<values.length; i++ ) 532 { 533 if( current < safeValues[i] ) 534 { 535 offset = safeValues[i] - current; 536 break findvalue; 537 } 538 } 539 } } 541 542 return offset; 543 } 544 545 549 static boolean isIn( int find, int[] values ) 550 { 551 if( values[0] == -1 ) 552 { 553 return true; 554 } 555 else 556 { 557 for( int i=0; i<values.length; i++ ) 558 { 559 if( find == values[i] ) 560 return true; 561 } 562 return false; 563 } 564 } 565 566 569 static int last( int[] intArray ) 570 { 571 return intArray[ intArray.length - 1 ]; 572 } 573 574 579 static int[] discardValuesOverMax( int[] values, int max ) 580 { 581 int[] safeValues = null; 582 for( int i=0; i<values.length; i++ ) 583 { 584 if( values[i] > max ) 585 { 586 safeValues = new int[i]; 587 System.arraycopy( values, 0, safeValues, 0, i ); 588 return safeValues; 589 } 590 } 591 return values; 592 } 593 594 595 private static String arrToString( int[] intArray ) 596 { 597 if( intArray == null ) 598 return "null"; 599 if( intArray.length == 0 ) 600 return "{}"; 601 602 String s = "{"; 603 for( int i=0; i<intArray.length-1; i++ ) 604 { 605 s += intArray[i] + ", "; 606 } 607 s += intArray[intArray.length-1] + "}"; 608 609 return s; 610 } 611 612 616 629 public int compareTo(Object obj) { 630 AlarmEntry other = (AlarmEntry)obj; 631 if (alarmTime < other.alarmTime) 632 return -1; 633 else if (alarmTime > other.alarmTime) 634 return 1; 635 else { 637 if( lastUpdateTime < other.lastUpdateTime ) 638 return -1; 639 else if( lastUpdateTime > other.lastUpdateTime) 640 return 1; 641 else 642 return 0; 643 } 644 } 645 646 647 658 public boolean equals(Object obj) { 659 AlarmEntry entry = null; 660 661 if( obj == null || !(obj instanceof AlarmEntry) ) 662 return false; 663 664 entry = (AlarmEntry)obj; 665 return ( name.equals(entry.name) 666 && alarmTime == entry.alarmTime 667 && isRelative == entry.isRelative 668 && isRepeating == entry.isRepeating 669 && Arrays.equals(minutes, entry.minutes) 670 && Arrays.equals(hours, entry.hours) 671 && Arrays.equals(daysOfMonth, entry.daysOfMonth) 672 && Arrays.equals(months, entry.months) 673 && Arrays.equals(daysOfWeek, entry.daysOfWeek) ); 674 } 675 676 677 678 681 public String toString() { 682 if (year != -1) { 683 return "Alarm ("+name+") at " + new Date (alarmTime); 684 } 685 StringBuffer sb = new StringBuffer ("Alarm ("+name+") params"); 686 sb.append(" minute="); sb.append( arrToString(minutes) ); 687 sb.append(" hour="); sb.append( arrToString(hours) ); 688 sb.append(" dayOfMonth="); sb.append( arrToString(daysOfMonth) ); 689 sb.append(" month="); sb.append( arrToString(months) ); 690 sb.append(" dayOfWeek="); sb.append( arrToString(daysOfWeek) ); 691 sb.append(" (next alarm date=" + new Date (alarmTime) + ")"); 692 return sb.toString(); 693 } 694 695 696 699 public static void main( String [] args ) { 700 701 System.out.println( "GETTING OFFSETS" ); 702 703 System.out.println( "getOffsetToNext(3, 0, 11, new int[]{3,5,7,9}) = " + 704 getOffsetToNext(3, 0, 11, new int[]{3,5,7,9}) ); 705 System.out.println( "getOffsetToNextOrEqual(3, 0, 11, new int[]{3,5,7,9}) = " + 706 getOffsetToNextOrEqual(3, 0, 11, new int[]{3,5,7,9}) ); 707 708 System.out.println(); 709 System.out.println( "getOffsetToNext(9, 0, 11, new int[]{3,5,7,9}) = " + 710 getOffsetToNext(9, 0, 11, new int[]{3,5,7,9}) ); 711 System.out.println( "getOffsetToNextOrEqual(9, 0, 11, new int[]{3,5,7,9}) = " + 712 getOffsetToNextOrEqual(9, 0, 11, new int[]{3,5,7,9}) ); 713 714 System.out.println(); 715 System.out.println( "getOffsetToNext(0, 0, 11, new int[]{0}) = " + 716 getOffsetToNext(0, 0, 11, new int[]{0}) ); 717 System.out.println( "getOffsetToNextOrEqual(0, 0, 11, new int[]{0}) = " + 718 getOffsetToNextOrEqual(0, 0, 11, new int[]{0}) ); 719 720 System.out.println(); 721 System.out.println( "getOffsetToNext(5, 0, 11, new int[]{5}) = " + 722 getOffsetToNext(5, 0, 11, new int[]{5}) ); 723 System.out.println( "getOffsetToNextOrEqual(5, 0, 11, new int[]{5}) = " + 724 getOffsetToNextOrEqual(5, 0, 11, new int[]{5}) ); 725 726 System.out.println(); 727 System.out.println( "getOffsetToNext(0, 0, 11, new int[]{-1}) = " + 728 getOffsetToNext(0, 0, 11, new int[]{-1}) ); 729 System.out.println( "getOffsetToNextOrEqual(0, 0, 11, new int[]{-1}) = " + 730 getOffsetToNextOrEqual(0, 0, 11, new int[]{-1}) ); 731 732 System.out.println(); 733 734 System.out.println(); 735 System.out.println( "discardValuesOverMax(new int[]{0,1,2,3,4,5,6}, 4)) = " + 736 arrToString(discardValuesOverMax(new int[]{0,1,2,3,4,5,6}, 4)) ); 737 System.out.println( "discardValuesOverMax(new int[]{0,1,2,3,4,5,6}, 6)) = " + 738 arrToString(discardValuesOverMax(new int[]{0,1,2,3,4,5,6}, 6)) ); 739 System.out.println( "discardValuesOverMax(new int[]{0,1,2,3,4,5,6}, 0)) = " + 740 arrToString(discardValuesOverMax(new int[]{0,1,2,3,4,5,6}, 0)) ); 741 System.out.println( "discardValuesOverMax(new int[]{0,1,2,3,4,5,6}, 7)) = " + 742 arrToString(discardValuesOverMax(new int[]{0,1,2,3,4,5,6}, 7)) ); 743 } 744 } 745 746 747 748 749 750 751 752 753 754 | Popular Tags |