Searcher is an aglet-based implementation of a utility for files that contains an specified string in its file name. It consists of two aglets, one stationary (Searcher) and one mobile (SearcherSlave). The latter is dispatched by Searcher to visit (sequentially) multiple remote locations, looking for files whose file name contains a specific string. Having gathered all the file names, the SearcherSlave finally returns to the Searcher and displays these file names.
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 Searcher aglet by specifying its class name: "ibm.aglets.samples.Searcher"(read Tahiti User's Guide for more information about aglet creation). When the Searcher aglet is created, its dialog window is displayed:
The panel bellow the "File Name Substring" field shows the itinerary of the SearcherSlave (the URLs of the remote aglet servers to visit). Next, is the result panel where the file names are displayed..
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
Specify, in the "File Name Substring" field, the string which will be matched against file names. An empty field (see the example above) means an empty string which is always matched against any file name. Regular expressions are not supported.
Press the Go button. A new WriterSlave aglet will be created and dispatched to the first aglet server. If errors occurs, corresponding error messages will be displayed in the bottom panel (the message panel) of the dialog window.
Note: The SearcherSlave aglet searches those files that are allowed to access in "Security Configuration" dialog of every remote Tahiti.
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.
The SearcherSlave notifies the Slave of successful completion of the local search in every remote aglet server. These messages will be displayed on the message panel (see the example above).
The file name will be displayed on the result panel, in the form of <hostname>::<file name>. You can watch only the files of a specific remote aglet server by selecting its URL in the itinerary panel and pressing the show button.
Read here about troubleshooting for the sample aglets.
This program is composed of the following classes:
The Searcher class inherits the SampleAglet abstract class for a stationary aglet (see a description of the SampleAglet abstract class here). Its go method creates the slave aglet.
private final static String SlaveClassName = "ibm.aglets.samples.SearcherSlave"; void go(Vector destinations, String str) { super.go((URL)(destinations.firstElement())); try { Slave.create(null, SlaveClassName, getAgletContext(), this, new SeqItinerary(destinations), str); } catch (IOException ae) { ..... } }
The slave is given an itinerary of several remote aglet servers (specified by destination parameter which is a vector of URLs) and a string to be matched against file names (the str parameter) . The Searcher aglet is considered the slave's master (specified by the this parameter to the Slave.create method).
In every remote aglet server, the slave creates a new SearcherInfo object which includes the name of the host and a vector with the names of the matched files. These objects are accumulated and finally become the result of the slave (see ahead).
The Searcher aglet, as a master, receives the slave's result (handled by the callback method) and error messages which are sent by the slave whenever its fails to perform a local search (handled by the inError method). The callback method is overwritten to receive the slave's result (a vector of SearcherInfo objects) and to display (via the addResultList method) the names of all the matched files on the result panel of the dialog window.
protected synchronized void callback(Object arg) { String ni; // Slave is back... setTheMessage("Searcher has returned"); _fileList = (Vector)arg; for (int i = 0; i < _fileList.size(); i++) { SearcherInfo si= (SearcherInfo)(_fileList.elementAt(i)); Vector v = si.getFileList(); String URLString = si.getURLString(); for (int j=0; j < v.size(); j++) { ((SearcherWindow)_msw).addResultList( SearcherInfo.getFullPathName(URLString, (String)(v.elementAt(j)))); } } }
The handleMessage of the SampleAglet class is overwritten to accept a "status report" kind of messages which are sent by the SearcherSlave to indicate successful completion of local searches. The handling of these messages is done in the private statusReport method.
public boolean handleMessage(Message msg) { if ("status report".equals(msg.kind)) { statusReport((String)(msg.getArg())); return false; } else return super.handleMessage(msg); }
The SearcherSlave class implements the abstract methods of the Slave class. These are initializeJob() and doJob(). In initializeJob(), the result instance variable of the slave class (used to save the final result of the task of the slave) is initialized to an empty vector which will accumulate all the local information (SearcherInfo objects) gathered in every remote aglet server.
protected synchronized void initializeJob () { RESULT = new Vector(); }
protected synchronized void doJob() throws AgletException { String filename, readPath; filename = (String)ARGUMENT; _fileList = new Vector(); //-- a slave is always untrusted readPath = getAgletContext().getProperty("aglets.tahiti.untrusted.read", ""); //-- match the file names and collect into the _fileList variable if (!readPath.equals("")) { find(filename.toLowerCase(), //-- case insensitive readPath.toLowerCase()); } ((Vector)RESULT).addElement( new SearcherInfo( getAgletContext().getHostingURL(), _fileList)); //-- send "status report" message to the master reportMaster("Completed search"); }
In doJob(), the slave retrieves the local directories (files) which are allowed to be accessed (read) and recursively traverse them to search all the files whose names includes the given string. The matched file names and the host name are saved in a new SearcherInfo object which is added to the result instance variable.
You can further study the Searcher aglet in more detail by directly traversing the source code.