全てのサンプルアプリケーションはステーショナリーAgletを用いて実装されています。ステーショナリーAgletとは(1)ユーザーと対話し、(2)「仕事」をするためにリモートホストに対して"worker"agletsをつくって送り出します。ユーザーとの対話はSampleWindow抽象クラスで定義されたユーザーインターフェースを介して行われます。 このユーザーインターフェースにより、リモートホストに対して新しい"worker" agletをつくって送り出したり、"worker" agletの送るメッセージ(メッセージについてはこの先をご覧ください)や結果を表示することが出来ます。
このページの残りの部分では、サンプルという言葉とサンプルAgletという言葉は同じ意味で用いられます。一方、サンプルクラスという言葉はSampleAgletクラスの特定のサブクラスを指します。
抽象クラスSampleAgletはサンプルagletの共有データ、コード、デフォルトの振る舞いをカプセル化します。サンプルagletの実装をより深く理解するためにはサンプル agletについての解説をご覧ください。
ただ一つのインスタンス変数として対話ウィンドウオブジェクトがありそれは以下のように定義されています:
protected SampleWindow _msw = null;
サンプルagletをステーショナリーなエージェント(つまりリモートホストへと転送されることのないもの)として定義するために、onDispatchingメソッド(Agletクラスにおいて定義されています)はオーバーライトされてAgletをディスパッチしようとする全ての試みに対し例外を投げるようになっています。
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!"); }
サンプルagletが消去されるまえに、対話ウィンドウを消去するため、onDisposing()が呼ばれます。
public synchronized void onDisposing() { // Removes any windows if disposed. if (_msw != null) _msw.dispose(); }
メッセージの扱いはhandleMessage()で記述されています。三種類のメッセージ errorとresult、updateWindowが受け付けられます。resultメッセージは"worker"agletが行った作業の結果を運びます。errorメッセージは"worker" agletが遭遇した回復不可能なエラーを通知します。updateWindowはサンプルの対話ウィンドウを更新するために用います(後述)。これらのメッセージはおのおのcallback とinError、updateWindowで処理が行われます。
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; }
goメソッドは対話ウィンドウオブジェクトによって、新たな"worker" agletを生成するためにそのウィンドウ上でgoボタンが押されたときつねに呼び出されます。このメソッドでは行き先のURLに関する計算を行い, (resetTheWindowメソッドによって)対話ウィンドウをリセットし、 "Going to...."というメッセージを表示し、コンテキストの属性を更新します。これは、サンプルクラスのさらに特化したgoメソッドから呼び出されそこで"worker" agletsが生成されます。
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()); } }
agletが生成された後自動的に呼び出されるrunメソッドはTahitiの対話ウィンドウに初期メッセージを("starting..")表示します。これは、サンプルクラスのさらに特化したrunメソッドから呼び出されます。
public void run() { setText("Starting..."); }
複数のサンプルAgletを同時に実行し、対話ウィンドウに表示された行き先アドレスやファイル名などを共有するということが可能です。対話ウィンドウ上でこれらのフィールドの値を変更して、ためしにgoボタンを押して対話ウィンドウ上でのフィールドの値の変化が対応していることを確認して見てください。これらのデータの共有は、コンテキスト属性へのアクセスおよびメッセージのマルチキャスティング機構によって実現されています。
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())); }
SampleAgletクラスの完全なソースコードはここにあります。