All the sample applications are implemented by stationary aglets which (1) interact with the the user and (2) creates/dispatch other "worker" aglets to do some "work" at remote hosts. Interaction with the user is done via user interface defined by the SampleWindow abstract class. The user interface enables to create/dispatch a new "worker" aglet to several remote hosts and to display both the messages the "worker" sends (see ahead) and the result of its "work".
Throughout the rest of this page, the terms "samples" and "sample aglets" are used interchangeability, while the term "sample classes" refers to the specialized subclasses of the SimpleAglet class of these samples. The SampleAglet abstracts class encapsulates shared data, code and default behavior of the sample aglets. The reader should refer to the descriptions of the sample aglets in order to fully understand their implementation.
The only instance variable is the interaction window object, defined as follows:
protected SampleWindow _msw = null;
A sample aglet is defined as a stationary one (i.e. one which can not be dispatched to remote hosts) by overwriting its onDispatching() to throw an exception upon every attempt to dispatch it.
public synchronized void onDispatching(URL url) { // I will shout if you try to move me! throw new SecurityException("Don't ever try to move me!"); }
Before a sample aglet is disposed, the onDisposing() is called to dispose the interactive window.
public synchronized void onDisposing() { // Removes any windows if disposed. if (_msw != null) _msw.dispose(); }
Message handling is defined by the handleMessage(). Three basic kind of messages are accepted: error, result and updateWindow. The result message carries the results of the task done by a "worker" aglet. The error message is notifies of an irrecoverable error, detected by a "worker" aglet. The updateWindow is called to update the sample's interactive window (see ahead). They are handled by the corresponding callback,inError and updateWindow methods, respectively.
public boolean handleMessage(Message msg) { try { if ("updateWindow".equals(msg.kind)) updateWindow(); else if ("result".equals(msg.kind)) callback(msg.getArg()); else if ("error".equals(msg.kind)) inError((String)(msg.getArg())); else return false; return false; } catch (Exception e) { // -- not yet handled } return false; }
The go method is called by an interaction window object, whenever its go button is pressed, in order to create an new "worker " aglet. It computes the target URL, reset the interaction window (via the resetTheWindow method, ahead), displays a message, "Going to....", on the interaction window (via the setTheMessage method, ahead) and update context properties (see ahead). It is called by more specialized go methods of the sample classes, where the specific "worker" aglets are created.
protected void go(URL url) { String _target = url.toString(); if (url.getHost().equals("")) // in case the URL address _target="localhost"; // does not start with "atp://" resetTheWindow(); setTheMessage("going to: " + _target); try { getAgletContext().setProperty("location", (String)_msw.getLocation()); getAgletContext().setProperty("filename",(String)_msw.getFilename()); getAgletContext().multicastMessage(new Message("updateWindow")); } catch (AgletException ae) { inError(ae.getMessage()); } }
The run method (called automatically after an aglet is created) writes an initial message ("starting..") on the Tahiti interaction window. It is called by more specialized run methods of the sample classes.
public void run() { setText("Starting..."); }
Multiple samples, running simultaneously, share the same values of the destination address and filename fields of their interactive windows. Try to change the values of these fields in one interaction window, press its go button and notice that changes in the corresponding fields in the other interactive windows. Sharing of these values is done via access of context properties and a message multi-casting mechanism.
public void onCreation(Object o) { try { subscribeMessage("updateWindow"); } catch (Exception e) { //-- not yet handled } }
protected synchronized void updateWindow () throws Exception { AgletContext ctx = getAgletContext(); _msw.setLocation((String)ctx.getProperty("location",_msw.getLocation())); _msw.setFilename((String)ctx.getProperty("filename",_msw.getFilename())); }
The complete source code of the SampleAglet class is found here.