Watcher is an aglet-based implementation of a utility for watching a file update status. It consists of two aglets, one stationary (Watcher) and one mobile(WatcherNotifier). The latter is dispatched by Watcher to a remote location where it stays and keeps watching of a file being updated. WatcherNotifier usually sleeps and periodically gets up and checks if the file was updated or not. Whenever the file is updated, the WatcherNotifier notifies the Watcher.
To be written.
Run at least two aglet servers in your network (read here how to run an aglet server).
Use the "new aglet" panel of Tahiti to create your Watcher aglet by specifying its class name: "ibm.aglets.samples.Watcher"(read Tahiti User's Guide for more information about aglet creation). When the Watcher aglet is created, its dialog window is displayed:
Specify the URL of a remote aglet server in the "Adress" field (or choose one from the AddressBook). This URL should consists of "atp://" followed by the host and domain names. You may specify an additional port number. An example of a URL is:
atp://aglets.trl.ibm.com
or, if your aglet server is running on a port other than the default one (434):
atp://aglets.trl.ibm.com:500
In order to update the AddressBook, click once to display its panel. Then, either select an address and remove it (via the delete button) or add the current address in the "Address" field (via the add button). Click on the close button to hide the AddressBook panel.
Read here about troubleshooting for the sample aglets.
This program is composed of the following classes:
The Watcher class inherits the SampleAglet abstract class for a stationary aglet (see a description of the SampleAglet abstract class here). Its go method creates the WatcherNotifier aglet.
protected void go(URL destination, double interval, double duration, boolean stay, String path) { super.go(destination); try { Notifier.create(null, NotifierClassName, getAgletContext(), this, new SeqItinerary(destination), interval, duration, stay, path); } catch (IOException ae) { ...... } } }
The WatcherNotifier is given an itinerary of a single destination (the destination parameter) and the name of the local file to be watched (the path parameter). The rest of the parameters specify the time interval between checks, the time duration for watching the file and whether to keep notifying after the next first detected change. All times are given in hour units. The Watcher aglet is considered the notifier's master (specified by the this parameter to the Notifier.create method).
The default handleMessage of the SampleAglet is completely overwritten to reject all kind of messages except the notification ones.
public boolean handleMessage(Message msg) { if ("notification".equals(msg.kind)) message((Arguments)(msg.getArg())); else super.handleMessage(msg); return true; }
The notification messages are handled in the message private method. These messages either indicate (via the type argument of the message) that the file has been updated, the duration time has been expired or an unexpected error has been occured.
private synchronized void message(Arguments message) { int type = ((Integer)message.getArgument("type")).intValue(); if (type == Notifier.NOTIFICATION) { _msw.appendResult( "UPDATE: " + (String)(message.getArgument("message")) + ", AT: " + message.getArgument("date").toString()); } else { setTheMessage((String)(message.getArgument("message"))); } }
The WatcherNotifier class implements the abstract methods of the Notifier class. These are initializeCheck() and doCheck(). In InitializeCheck(), the notifier tries to locate the file and to save the time of the last update (the lastModified variable)
protected void initializeCheck() throws AgletException { _filePath = (String)ARGUMENT; setText("checking update of " + _filePath); if ((f = new File(_filePath)) == null) { throw new AgletException("Null File object error"); } if (f.exists()) { _lastModified = f.lastModified(); MESSAGE = _filePath; return; } else { throw new AgletException("Access Non-Existing File"); } }
In doCheck(), the time of the last update is compared against the previous one (the lastModified variable) to detect a change. If a change is detected, the filename is save in the MESSAGE variable which is finally sent as the content of a notification message.
protected boolean doCheck() throws AgletException { long time; if (f != null) { // get the timestamp of the target file time = f.lastModified(); if (_lastModified != time) { MESSAGE = _filePath ; // update _lastModefied timestamp _lastModified = time; // file has changed on time "Date(time)" return true; } } else throw new AgletException("Null File object error"); // no change on the target file return false; }
You can further study the Watcher aglet in more detail by directly traversing the source code.