/*
* 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. 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.,
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
package org.aitools.programd.util;
import java.io.IOException;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;
import org.aitools.programd.Core;
import org.aitools.util.resource.URLTools;
import org.apache.log4j.Logger;
/**
* Watches a set of AIML files. Any file changes will be loaded automatically.
*
* @author Jon Baer
* @author <a href="mailto:noel@aitools.org">Noel Bush</a>
*/
public class AIMLWatcher {
/**
* A {@link java.util.TimerTask TimerTask} for checking changed AIML files.
*/
private class CheckAIMLTask extends TimerTask {
/**
* Creates a new CheckAIMLTask.
*/
public CheckAIMLTask() {
super();
}
/**
* @see java.util.TimerTask#run()
*/
@SuppressWarnings("boxing")
@Override
public void run() {
synchronized (AIMLWatcher.this) {
for (URL path : AIMLWatcher.this.watchMap.keySet()) {
long previousTime = AIMLWatcher.this.watchMap.get(path);
if (previousTime != 0) {
long lastModified = URLTools.getLastModified(path);
if (lastModified > previousTime) {
AIMLWatcher.this.watchMap.put(path, lastModified);
AIMLWatcher.this.reload(path);
}
}
}
}
}
}
/** The Timer that handles watching AIML files. */
private Timer timer;
private Core _core;
/** Used for storing information about file changes. */
protected Map<URL, Long> watchMap = new HashMap<URL, Long>();
protected Logger logger = Logger.getLogger("programd");
/**
* Creates a new AIMLWatcher using the given Graphmaster
*
* @param core the Core to use
*/
public AIMLWatcher(Core core) {
this._core = core;
this.logger = this._core.getLogger();
}
/**
* Adds a file to the watchlist.
*
* @param path the path to the file
*/
@SuppressWarnings("boxing")
public void addWatchFile(URL path) {
/*
* if (this.logger.isDebugEnabled()) { this.logger.debug(String.format("Adding watch file \"%s\".", path)); }
*/
synchronized (this) {
if (URLTools.seemsToExist(path)) {
if (this.watchMap.containsKey(path)) {
this.watchMap.put(path, URLTools.getLastModified(path));
}
}
else {
this.logger.warn(String.format("AIMLWatcher cannot read path \"%s\"", URLTools.unescape(path)),
new IOException());
}
}
}
/**
* Reloads AIML from a given path.
*
* @param path the path to reload
*/
protected void reload(URL path) {
this.logger.info(String.format("AIMLWatcher reloading \"%s\".", URLTools.unescape(path)));
this._core.reload(path);
}
/**
* Starts the AIMLWatcher.
*/
public void start() {
this.timer = new Timer(true);
this.timer.schedule(new CheckAIMLTask(), 0, this._core.getSettings().getAIMLWatcherTimer());
}
/**
* Stops the AIMLWatcher.
*/
public void stop() {
if (this.timer != null) {
this.timer.cancel();
}
}
}