package com.netifera.platform.ui.updater; import java.util.concurrent.ScheduledFuture; /** * ScheduledTask implementation to use with TaskScheduler for the UI updater. It is generic * and does not have UI specific code so it could be probably be replaced for some standard * implementation. * * @author kevin * */ public class ScheduledTask implements Runnable { private long lastRunEnd; private volatile boolean scheduled; private volatile boolean cancelled; /* period and delay unit is milliseconds */ protected int period; protected int delay; protected long nextRunStart; protected long lastRunStart; protected final TaskScheduler taskScheduler = TaskScheduler.getInstance(); protected final Runnable task; private ScheduledFuture<?> future; public ScheduledTask(Runnable task) { this.task = task; } /** * @param task Runnable * @param delay milliseconds to wait before running the task again */ public ScheduledTask(Runnable task, int period, int delay) { this.task = task; this.delay = delay; this.period = period; } public void run() { if (cancelled) { return; } /* if the task is periodic it is always scheduled */ if (period == 0) { scheduled = false; } lastRunEnd = 0; nextRunStart = 0; lastRunStart = System.currentTimeMillis(); if (period >= 0) { nextRunStart = lastRunStart + period; } task.run(); lastRunEnd = System.currentTimeMillis(); if (delay >= 0) { nextRunStart = lastRunEnd + delay; } } public void schedule() { if (scheduled) { return; } /* double-checked locking broken in java 1.4 and earlier */ synchronized (this) { if (!scheduled) { scheduled = true; future = taskScheduler.submit(this); } } } private void reschedule() { taskScheduler.remove(this); scheduled = true; taskScheduler.submit(this); } public void cancel() { cancelled = true; taskScheduler.remove(this); } public int getNextRunDelay() { long nextDelay = nextRunStart - System.currentTimeMillis(); return nextDelay > 0 ? (int) nextDelay : 0; } public int getDelay() { return delay; } public void setDelay(int delay) { this.delay = delay; } public synchronized int getPeriod() { return period; } public synchronized void setPeriod(int period) { this.period = period; reschedule(); } public int hashCode() { return task.hashCode(); } public boolean equals(Object other) { if (other == this) { return true; } if (!(other instanceof ScheduledTask)) { return false; } return (((ScheduledTask) other).task == this.task); } public void setFuture(ScheduledFuture<?> future) { this.future = future; } public ScheduledFuture<?> getFuture() { return future; } }