package com.idega.util.timer; import java.util.Calendar; import java.util.Date; /** * This class represents the attributs of a timer. * * @author Olivier Dedieu, David Sims, Simon Bécot, Jim Lerner * @version 1.4, 01/02/2002 * @modified Eirikur Hrafnsson eiki@idega.is */ public class TimerEntry implements Comparable, java.io.Serializable { public int minute = -1; public int hour = -1; public int dayOfMonth = -1; public int month = -1; public int dayOfWeek = -1; public int year = -1; public boolean isRelative; public boolean isRepetitive; public long timerTime; public String timerName = ""; public transient TimerListener listener; public boolean canRun = true; /** * @return Returns the dayOfMonth. */ public int getDayOfMonth() { return this.dayOfMonth; } /** * @param dayOfMonth The dayOfMonth to set. */ public void setDayOfMonth(int dayOfMonth) { this.dayOfMonth = dayOfMonth; } /** * @return Returns the dayOfWeek. */ public int getDayOfWeek() { return this.dayOfWeek; } /** * @param dayOfWeek The dayOfWeek to set. */ public void setDayOfWeek(int dayOfWeek) { this.dayOfWeek = dayOfWeek; } /** * @return Returns the hour. */ public int getHour() { return this.hour; } /** * @param hour The hour to set. */ public void setHour(int hour) { this.hour = hour; } /** * @return Returns the if the handleTime method can be called. */ public boolean canRun() { return this.canRun; } /** * @param canRun */ public void setCanRun(boolean canRun) { this.canRun = canRun; } /** * @return Returns the isRelative. */ public boolean isRelative() { return this.isRelative; } /** * @param isRelative The isRelative to set. */ public void setRelative(boolean isRelative) { this.isRelative = isRelative; } /** * @return Returns the isRepetitive. */ public boolean isRepetitive() { return this.isRepetitive; } /** * @param isRepetitive The isRepetitive to set. */ public void setRepetitive(boolean isRepetitive) { this.isRepetitive = isRepetitive; } /** * @return Returns the minute. */ public int getMinute() { return this.minute; } /** * @param minute The minute to set. */ public void setMinute(int minute) { this.minute = minute; } /** * @return Returns the month. */ public int getMonth() { return this.month; } /** * @param month The month to set. */ public void setMonth(int month) { this.month = month; } /** * @return Returns the timerName. */ public String getTimerName() { return this.timerName; } /** * @param timerName The timerName to set. */ public void setTimerName(String timerName) { this.timerName = timerName; } /** * @return Returns the timerTime. */ public long getTimerTime() { return this.timerTime; } /** * @param timerTime The timerTime to set. */ public void setTimerTime(long timerTime) { this.timerTime = timerTime; } /** * @return Returns the year. */ public int getYear() { return this.year; } /** * @param year The year to set. */ public void setYear(int year) { this.year = year; } private transient boolean debug = false; private void debug(String s) { if (this.debug) { System.out.println("[" + Thread.currentThread().getName() + "] TimerEntry: " + s); } } /** * Creates a new TimerEntry. * * @param date the timer date to be added. * @param listener the timer listener. * @exception PastDateException if the timer date is in the past * (or less than 1 second closed to the current date). */ public TimerEntry(Date date, TimerListener listener) throws PastDateException { this.listener = listener; Calendar timer = Calendar.getInstance(); timer.setTime(date); this.minute = timer.get(Calendar.MINUTE); this.hour = timer.get(Calendar.HOUR_OF_DAY); this.dayOfMonth = timer.get(Calendar.DAY_OF_MONTH); this.month = timer.get(Calendar.MONTH); this.year = timer.get(Calendar.YEAR); this.isRepetitive = false; this.isRelative = false; this.timerTime = date.getTime(); checkTimerTime(); } /** * Creates a new TimerEntry. * * @param delay the timer delay in minute (relative to now). * @param isRepetitive <code>true</code> if the timer must be * reactivated, <code>false</code> otherwise. * @param listener the timer listener. * @exception PastDateException if the timer date is in the past * (or less than 1 second closed to the current date). */ public TimerEntry(int delay, boolean isRepetitive, TimerListener listener) throws PastDateException { if (delay < 1) { throw new PastDateException(); } this.minute = delay; this.listener = listener; this.isRepetitive = isRepetitive; if (this.minute < 1) { throw new IllegalArgumentException(); } this.isRelative = true; updateTimerTime(); } /** * Creates a new TimerEntry. * * @param minute minute of the timer. Allowed values 0-59. * @param hour hour of the timer. Allowed values 0-23. * @param dayOfMonth day of month of the timer (-1 if every * day). This attribute is exclusive with * <code>dayOfWeek</code>. Allowed values 1-31. * @param month month of the timer (-1 if every month). Allowed values * 0-11 (0 = January, 1 = February, ...). <code>java.util.Calendar</code> * constants can be used. * @param dayOfWeek day of week of the timer (-1 if every * day). This attribute is exclusive with * <code>dayOfMonth</code>. Allowed values 1-7 (1 = Sunday, 2 = * Monday, ...). <code>java.util.Calendar</code> constants can be used. * @param year year of the timer. When this field is not set * (i.e. -1) the timer is repetitive (i.e. it is rescheduled when * reached). * @param listener the timer listener. * @return the TimerEntry. * @exception PastDateException if the timer date is in the past * (or less than 1 second closed to the current date). */ public TimerEntry(int minute, int hour, int dayOfMonth, int month, int dayOfWeek, int year, TimerListener listener) throws PastDateException { this.minute = minute; this.hour = hour; this.dayOfMonth = dayOfMonth; this.month = month; this.dayOfWeek = dayOfWeek; this.year = year; this.listener = listener; this.isRepetitive = (year == -1); this.isRelative = false; updateTimerTime(); checkTimerTime(); } /** * @param timerName the timer name. * @return the TimerEntry. * @exception PastDateException if the timer date is in the past * (or less than 1 second closed to the current date). **/ public TimerEntry(int minute, int hour, int dayOfMonth, int month, int dayOfWeek, int year, TimerListener listener, String timerName)throws PastDateException { this(minute, hour, dayOfMonth, month, dayOfWeek, year, listener); this.timerName = timerName; } /** * Updates the timer time for repetitive timers. */ public void updateTimerTime() { if (this.isRelative) { this.timerTime = System.currentTimeMillis() + (this.minute * 60000); return; } Calendar now = Calendar.getInstance(); Calendar timer = (Calendar)now.clone(); debug("now: " + now.getTime()); if (this.year != -1) { timer.set(Calendar.YEAR, this.year); } if (this.month != -1) { timer.set(Calendar.MONTH, this.month); } if (this.hour != -1) { timer.set(Calendar.HOUR_OF_DAY, this.hour); } if (this.minute != -1) { timer.set(Calendar.MINUTE, this.minute); } timer.set(Calendar.SECOND, 0); // Increments minute if now >= timer (for every minute timers) if (this.minute == -1) { timer.add(Calendar.MINUTE, 1); } // Increments hour if now >= timer (for every hour timers) if (this.hour == -1 && this.minute != -1 && now.get(Calendar.MINUTE) >= this.minute) { timer.add(Calendar.HOUR_OF_DAY, 1); } // Incrementes dayOfYear if now >= timer (for everyday timers) if (this.dayOfMonth == -1 && this.dayOfWeek == -1 && this.hour != -1 && this.minute != -1 && (now.get(Calendar.HOUR_OF_DAY) > this.hour || (now.get(Calendar.HOUR_OF_DAY) == this.hour && now.get(Calendar.MINUTE) >= this.minute))) { timer.roll(Calendar.DAY_OF_YEAR, true); } // Incrementes year if now >= timer (for monthly or yearly timers) if (this.month != -1 && this.year == -1 && (now.get(Calendar.MONTH) > this.month || (now.get(Calendar.MONTH) == this.month && (now.get(Calendar.DAY_OF_MONTH) > this.dayOfMonth || (now.get(Calendar.DAY_OF_MONTH) == this.dayOfMonth && (now.get(Calendar.HOUR_OF_DAY) > this.hour || (now.get(Calendar.HOUR_OF_DAY) == this.hour && (now.get(Calendar.MINUTE) >= this.minute)))))))) { timer.add(Calendar.YEAR, 1); } // Weekly timers if (this.dayOfWeek != -1) { int deltaOfDay = (7 + (this.dayOfWeek - now.get(Calendar.DAY_OF_WEEK))) % 7; debug("deltaOfDay: " + deltaOfDay); if (deltaOfDay != 0) { timer.add(Calendar.DAY_OF_YEAR, deltaOfDay); } // Incrementes week if now >= timer else if (now.get(Calendar.HOUR_OF_DAY) > this.hour || (now.get(Calendar.HOUR_OF_DAY) == this.hour && now.get(Calendar.MINUTE) >= this.minute)) { timer.add(Calendar.WEEK_OF_YEAR, 1); } } // Monthly timers else if (this.dayOfMonth != -1) { timer.set(Calendar.DAY_OF_MONTH, this.dayOfMonth); // Incrementes month if now >= timer (for weekly timers) if (this.month == -1 && (now.get(Calendar.DAY_OF_MONTH) > this.dayOfMonth || (now.get(Calendar.DAY_OF_MONTH) == this.dayOfMonth && (now.get(Calendar.HOUR_OF_DAY) > this.hour || (now.get(Calendar.HOUR_OF_DAY) == this.hour && now.get(Calendar.MINUTE) >= this.minute))))) { timer.roll(Calendar.MONTH, true); } } debug("timer: " + timer.getTime()); this.timerTime = timer.getTime().getTime(); } /** * Checks that timer is not in the past (or less than 1 second * closed to the current date). * * @exception PastDateException if the timer date is in the past * (or less than 1 second closed to the current date). */ void checkTimerTime() throws PastDateException { long delay = this.timerTime - System.currentTimeMillis(); if (delay <= 1000) { throw new PastDateException(); } } /** * Returns a string representation of this timer. * * @return the string. */ public String toString() { if (this.year != -1) { return "Timer at " + new Date(this.timerTime); } StringBuffer sb = new StringBuffer("Timer params"); sb.append(" minute="); sb.append(this.minute); sb.append(" hour="); sb.append(this.hour); sb.append(" dayOfMonth="); sb.append(this.dayOfMonth); sb.append(" month="); sb.append(this.month); sb.append(" dayOfWeek="); sb.append(this.dayOfWeek); sb.append(" (next timer date=" + new Date(this.timerTime) + ")"); sb.append(" name="+ this.timerName); return sb.toString(); } // ---------------------------------------------------------------------- // Comparable interface // ---------------------------------------------------------------------- /** * Compares this TimerEntry with the specified TimerEntry for order. * * @param obj the TimerEntry with which to compare. * @return a negative integer, zero, or a positive integer as this * TimerEntry is less than, equal to, or greater than the given * TimerEntry. * @exception ClassCastException if the specified Object's type * prevents it from being compared to this TimerEntry. */ public int compareTo(Object obj) { TimerEntry entry = (TimerEntry)obj; if (this.timerTime < entry.timerTime) { return -1; } if (this.timerTime > entry.timerTime) { return 1; } return 0; } /** * Indicates whether some other TimerEntry is "equal to" this one. * * @param obj the TimerEntry with which to compare. * @return <code>true if this TimerEntry has the same * <code>timerTime</code> as the <code>timerTime</code> of the obj * argument; <code>false</code> otherwise. */ public boolean equals(Object obj) { TimerEntry entry = (TimerEntry)obj; if ( (this.timerTime == entry.timerTime) && (this.timerName.equals(entry.timerName)) ){ return true; } return false; } }