Transferはリモートホストにあるファイルを転送するためのユーティリティをAgletにより実現したものです。これは2つのAgletで構成されています。一方はTransferで移動しないエージェントです。他方はTransferSlaveといい移動しないエージェントです。TransferSlaveはTransferによりリモートホストに送り出され、そこでファイルの内容のコピーします。最後にTransferSlaveはTransfer へ戻り、ファイルの内容を渡します。
のちほど述べます
少なくとも2つのAgletサーバーをネットワーク上で実行させます(Agletサーバーの実行方法についてはここをご覧ください)。
Tahitiの"new aglet"パネルでクラス名を"ibm.aglets.samples.Transfer"と指定してTransfer Agletを生成します(Agletの生成に関してのより詳細な情報は Tahiti ユーザーガイドをご覧ください)。 Transfer Agletが生成されるとダイアログ・ウィンドウが開きます。
atp://aglets.trl.ibm.com
またAgletサーバーがデフォルトのポート番号(434)以外で動いているなら次のようになります。
atp://aglets.trl.ibm.com:500
ファイルが転送されると、その内容がダイアログ・ウィンドウの真中にある結果のパネルに表示されます。さらに"TRANSFERED (bytes): <数字> DISPLAYED (bytes):<数字>" というメッセージがメッセージパネル(ダイアログ・ウィンドウの下部にあります)に表示されます。パネルの大きさは決まっているので、大きなファイルの場合は内容は一部分しか表示されません。
Agletのサンプルのトラブルシューティングに関してはここ をお読み下さい。
このプログラムは以下のクラスで構成されています。
TransferクラスはSampleAglet抽象クラスを継承してステーショナリーなAgletとして作られます(SampleAglet 抽象クラスについてはここ)を参照してください)。Finger クラスのgoメソッドでスレーブAgletが作られます。
protected static final String SlaveClassName = "ibm.aglets.samples.TransferSlave"; protected void go(URL url, String filename) { super.go(url); try { Slave.create(null, SlaveClassName, getAgletContext(), this, new SeqItinerary(url), filename); } catch (IOException ae) { inError(ae.getMessage()); } catch (AgletException ae) { inError(ae.getMessage()); } }
WatcherNotifierは単一の目的地を示す旅行計画(destinationパラメータ)と転送したいファイル名(ilenameパラメータ)を与えられます。TransferステーショナリーAglet はスレーブのマスターと考えられます(Slave.create メソッドの中ではthisという引数で表わされています)。
Transfer Agletはマスターとしてスレーブの結果を受け取ります (callbackメソッドで処理は行われます)、またスレーブが仕事を果たせなかったときにはエラーメッセージを受け取ります(inErrorメソッドで処理されます)。
protected synchronized void callback(Object arg) { try { if (arg != null) { byte[] data = ((TransferInfo)arg).getByteArray(); byte[] chunk = new byte[10000]; ..... //-- display the file by chunks of 10000 bytes. while (not end of file) { chunk =_msw.appendResult(new String(chunk,255)); } setTheMessage("TRANSFERED(bytes): " + data.length + "DISPLAYED(bytes): " + _msw.getResultSize()); } } catch (Exception e) { ... } setTheMessage("Finished!!!"); }
callbackメソッドはオーバーライトされて次のような働きをします。ファイルの内容(TransferInfoオブジェクト)を受け取り、それを(appendResultメソッドを経由して)ウィンドウの中の結果を表示するパネルに収まるだけの大きさに分割します。ここでファイルの内容を分割しているのは理由があってのことです。その理由とは内容を貯えておく一時的な文字列変数のサイズは固定されていますが(appendResultメソッドを呼び出しているところでパラメータを見てください)、こうすればファイルのサイズはどのようなものでもいいからです。どんなサイズのファイルにでも対応できるように、ファイルの内容を分割するブロックのサイズは好きなように選べます。
最後に転送されたファイルのサイズと実際に表示されているバイト数を表わすメッセージが表示されます(2つの数字は内容を表示するパネルのサイズが限られているために相違することがあります)。
TransferSlaveクラスはスレーブクラスの中の抽象メソッドを実装しています。そのなかにinitializeJob()とdoJob()というメソッドがあります。
protected synchronized void doJob() throws Exception { String _filePath = (String)ARGUMENT; File file; //-- check file existence if ((file = new File(_filePath)) == null) { throw new AgletException("AgletException:" + "Null File object error"); } if (!file.exists()) throw new AgletException("Try to access non-existing file"); RESULT = new TransferInfo(readfile(file)); }
doJobメソッドの中では、スレーブが目的のファイルを見つけ、それを読み、その内容を新たなTransferInfoオブジェクトに移しています。このオブジェクトはスレーブが最終的にマスターに渡すことになるresultインスタンス変数になります。
Transfer Agletについてより詳細な情報をお望みならソースコードをお読み下さい。