/* * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * For information about the authors of this project Have a look * at the AUTHORS file in the root of this project. */ package net.sourceforge.fullsync.schedule; import java.util.ArrayList; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class SchedulerImpl implements Scheduler, Runnable { private Logger logger = LoggerFactory.getLogger(Scheduler.class); private ScheduleTaskSource scheduleSource; private Thread worker; private boolean running; private boolean enabled; private ArrayList<SchedulerChangeListener> schedulerListeners; public SchedulerImpl() { this(null); } public SchedulerImpl(ScheduleTaskSource source) { scheduleSource = source; schedulerListeners = new ArrayList<SchedulerChangeListener>(); } @Override public void setSource(ScheduleTaskSource source) { scheduleSource = source; } @Override public ScheduleTaskSource getSource() { return scheduleSource; } @Override public void addSchedulerChangeListener(SchedulerChangeListener listener) { schedulerListeners.add(listener); } @Override public void removeSchedulerChangeListener(SchedulerChangeListener listener) { schedulerListeners.remove(listener); } protected void fireSchedulerChangedEvent() { for (SchedulerChangeListener listener : schedulerListeners) { listener.schedulerStatusChanged(enabled); } } @Override public boolean isRunning() { return running; } @Override public boolean isEnabled() { return enabled; } @Override public void start() { if (enabled) { return; } enabled = true; if ((worker == null) || !worker.isAlive()) { worker = new Thread(this, "Scheduler"); worker.setDaemon(true); worker.start(); } fireSchedulerChangedEvent(); } @Override public void stop() { if (enabled && (null != worker)) { enabled = false; if (running) { worker.interrupt(); } try { worker.join(); } catch (InterruptedException ex) { ex.printStackTrace(); } finally { worker = null; } fireSchedulerChangedEvent(); } } @Override public void refresh() { if (worker != null) { worker.interrupt(); } } @Override public void run() { running = true; while (enabled) { long now = System.currentTimeMillis(); if (logger.isDebugEnabled()) { logger.debug("searching for next task after " + now); } ScheduleTask task = scheduleSource.getNextScheduleTask(); if (task == null) { logger.info("could not find a scheduled task, aborting"); break; } if (logger.isDebugEnabled()) { logger.debug("found: " + task.toString() + " at " + task.getExecutionTime()); } long nextTime = task.getExecutionTime(); try { if (logger.isDebugEnabled()) { logger.debug("waiting for " + (nextTime - now) + " mseconds"); } if (nextTime >= now) { Thread.sleep(nextTime - now); } if (logger.isDebugEnabled()) { logger.debug("Running task " + task); } task.run(); } catch (InterruptedException ex) { ex.printStackTrace(); } } running = false; if (enabled) { enabled = false; fireSchedulerChangedEvent(); } } }