エージェントコンテキストクラスはエージェントとランタイムシステムとのインターフェースを提供するクラスであり、ランタイムシステム・コンピュータの情報、他のエージェントに関する情報、エージェント間通信、エージェント自身による移動、永続化、複製要求の受け付けなどのサービスをランタイムシステムに代わり提供します。
エージェントは、エージェントコンテキストを通してコンピュータのホストアドレス、他のエージェントの識別子などの実行に必要な情報を得ることができます。 また、エージェント間通信のプリミティブもエージェントコンテキスに用意されます。 エージェントコンテキストはAgentContextのクラスから生成されたインスタンスであり、 以下の APIによってそのインスタンスを得ることができます。
AgentContext getAgentContext();
ただし、エージェントコンテキストはエージェントが移動または保存した際には有効ではなくなり、到着または復活した際に再び作られます。このため、到着または復活したときは、getAgentContext()を通じて再び習得するようにして下さい。
public class Hello extends Agent { .... public void create() { AgentContext ac = getAgentContext(); .... } .... }
エージェントコンテキストを取得するときは、エージェントコンテキストが必要となる直前に上記のAPIを実行し、また、エージェントコンテキストを保持するときは、メソッド変数に 保持してください(インスタンス変数やクラス変数には保持しないこと)。次にAgentContextのメソッドを示します。
エージェントコンテキストのAPIは「各種情報の取得」、「エージェント間通信」、「状態変更」の3種類に大別されます。
メソッド名 |
引数の数 |
引数の型 |
メソッド返値の型 |
getIdentifier() |
0 |
| |
getAgents() |
0 |
|
AgentIdentifier の Enumeration リスト |
getAgents() |
1 |
String |
AgentIdentifier の Enumeration リスト |
getAgentName() |
1 |
String | |
getAgentName() |
0 |
|
String |
setAgentName() |
1 |
String |
void |
getCurrentHost() |
0 |
|
URL |
getPreviousHost() |
|
|
URL |
AgentIdentifier getIdentifier()
これを実行したエージェント、つまり自分自身のエージェント識別子を返します。エージェント識別子はエージェントに付けられた番号であり、同じ識別子が2つ以上のエージェントに着けられることはありません。エージェント間で通信をするときは通信相手の識別子を指定して通信を行います。
Enumeration getAgents()
これを実行したエージェントが存在するランタイムシステム上のエージェントすべての識別子のリストをEnumeration インタフェースとして返します(AgentIdentifierにキャストして下さい)。このメッソドの利用方法は java のapplet で用いる AppletContext の getApplets() メソッドと同様であるといえますが、返値はエージェント自体のリストではなく、エージェントの識別子のリストを返すことに注意して下さい。例えば、以下の例では、エージェントは生成時に同じエージェントランタイム上のすべてのエージェントの識別子を画面上に表示します。
public class Hello extends Agent { public Hello(){} public void create() { AgentContext ac = getAgentContext(); for (Enumeration e = ac.getAgents() ; e.hasMoreElements ; ) { System.out.println("ID = "+(AgentIdentifier)e.nextElement()); } } }
特定のエージェントの識別子を得る場合には以下のAPIを利用して下さい。
Enumeration getAgents(Sting name)
これを実行したエージェントが存在するランタイムシステム上のエージェントのうち、名前(後述)が name をとなるエージェント識別子のリストを返します。
エージェントは識別子の他に名前をもっています。名前とはエージェントにつけられた文字列のことです。識別子と違い一意に付けられるとは限りません。このため、同じ名前のエージェントが複数存在するとことがあります。名前は明示的に与えることができますが、それ以外ではブートクラスの名前がそのエージェントの名前になります。
void setAgentName(String name)
これを実行したエージェントの名前を name にします。
String getAgentName()
これを実行したエージェントの名前を得ることもできます。エージェントの識別子からそのエージェントの名前を得ることもできます。
String getAgentName(AgentIdentifier aid)
識別子 aid をもつエージェントの名前を返します。
エージェントはエージェントコンテキストのメッソドを通じて、そのエージェント自身の状態を変更することができます。なお、これらのメソッドはエージェントランタイムへのメッセージのマクロとして定義されています。詳細はエージェントランタイムへのメッセージを参照して下さい。また、このメソッドがその名前を変更する可能性があり、エージェントランタイムへのメッセージを利用したプログラムを推奨します。
メッソド名 |
引数の数 |
引数の型 |
返値の型 |
dispatch() |
1 |
String |
void |
dispatch() (未実装) |
1 |
URL |
void |
suspend() |
1 |
String |
void |
duplicate() |
0 |
|
AgentIdentifier |
create() |
1 |
String |
AgentIdentifier |
load() |
1 |
String |
AgentIdentifier |
エージェントに対して上記のメッソドを実行した場合には以下のような制限があります。
メッソド名 |
エージェント自身 |
子エージェント |
それ以外のエージェント |
dispatch() |
○ |
○ |
× |
destroy() |
○ |
○ |
× |
duplicate() |
○ |
○ |
× |
create() |
× |
× |
○ |
suspend() |
○ |
○ |
× |
load() |
× |
○ |
× |
上記の×に対応するエージェントに対してメソッドを実行した場合はアクセス権を守らなかった場合はセキュリティー例外が発生します。
引数としてアドレスにエージェントを移動します。詳細は dispatch メッセージを参照して下さい。
void dispatch(String address)
void dispatch(AgentIdentifier aid, String address) (未実装)
このメソッドはsend()(後述)を利用してエージェントランタイムにメッセージ "dispatch" として送信されます。このため、メッセージキューに入った後に処理されます。例を示します。
AgentContext ac = getAgentContext(); ac.dispatch("133.65.66.198");
エージェントを終了させます。詳細は destroy メッセージを参照して下さい。
void destroy()
void destroy(AgentIdentifier aid) (未実装)
このメソッドは send()(後述)を利用してエージェントランタイムにメッセージ "destroy" として送信されます。このため、メッセージキューに入った後に処理されます。例を示します。
AgentContext ac = getAgentContext(); ac.destroy();
エージェントを永続化させます。詳細はsuspend メッセージを参照して下さい。
byte[] suspend(AgentIdentifier aid)
void suspend(AgentIdentifier aid, String filename)
void suspend(String filename)
このメソッドは引数により機能が異なります。引数がaidのときはエージェント識別子がaidのエージェントを永続化し、その永続化されたデータを返します。また、aid以外にfilenameが付くときは、aidをエージェント識別子としてもつエージェントを永続化して、そのデータを名前がfilenameのファイルにセーブします。また、filenameだけのときはこのメソッドを実行したエージェント、つまり自分自身を永続化した結果をファイルfilenameにセーブします。なお、このメソッドは send()(後述)を利用してエージェントランタイムにメッセージ "suspend" として送信されます。このため、メッセージキューに入った後に処理されます。例を示します。これはエージェントをファイル new.agent として保存します。
AgentContext ac = getAgentContext(); ac.suspend("new.agent");
エージェントの複製をつくります。
AgentIdentifier duplicate()
void duplicate(AgentIdentifier aid) (未実装)
これを実行したエージェント、つまり自分自身をその状態を含めて複製した別のエージェントを生成します。返値は生成されたエージェントの識別子となります。UNIXのforkシステムコールと同様の働きをするメソッドです。なお、このAPIを実行後に、このAPIを実行したエージェントのparent()コールバックメソッドが呼び出されます。一方、生成した新しいエージェントのchild()コールバックメソッドが呼び出されます。以下に例を示します。これは自分自身を複製し、子エージェントにメッセージ "hello" を送信するものです。
AgentContext ac = getAgentContext(); AgentIdentifier aid = ac.duplicate(); ac.send(aid, "hello");
引数 agentFileName というファイルのエージェントを生成・復活します。詳細は create メッセージを参照して下さい。
AgentIdentifier create(String agentFileName)
AgentIdentifier create(byte[] data)
これはファイル agentFileName またはバイトデータ(byte[] data)に保存されているエージェントを実行可能(生成または復活)にします。返値は実行可能になったエージェントの識別子となります。なお、将来のバージョンでは引数は URL に変更される予定です。以下に例を示します。これはファイル "some.agent" のエージェントを生成し、それにメッセージ "hello" を送信するものです。
AgentContext ac = getAgentContext(); AgentIdentifier aid = ac.create("some.agent"); ac.send(aid, "hello");
このほか、suspend()によりバイトデータに永続化したエージェントを復活させることもできます。ここで、永続化したデータはエージェント中のインスタンス変数に保持すれば、移動前に永続化したエージェントを移動後に復活させることもできます。
class A extends Agent { byte[] data = null; public A() {} create() { AgentContext ac = getAgentContext(); AgentIdentifier aid = ac.create("some.agent"); data = ac.suspend(aid); } arrive() { AgentIdentifier aid = ac.create(data); ac.send(aid, "hello"); } }
なお、create()は名前がload()に変更される予定です。
create() メソッドと同じ。ただし、まだ実装されていない。
AgentContext クラスにはMessengerインスタンスに関する以下のメソッドが用意されている。
Messenger getMessenger();
メッセンジャーオブジェクトを返します。エージェント間通信をする際に実行します。
Messenger getMessenger(AgentIdentifier aid)
エージェント識別子 aid のメッセンジャーオブジェクトを返します。以下のエージェントは create() メソッドでエージェントコンテキストを取得しています。
JAR版のAgentSpaceは、gifファイルなどのリソースファイルをエージェントのJARファイルにいれることより、エージェントからアクセスすることができます。
public void setResource(String name, byte[] data) throws AlreadyBoundException;
バイト列 data を名前 name としてリソースリポジトリに登録。すでに 同じ名前のリソースが存在するときは例外AlreadyBoundExceptionを発生。永続化されたエージェントにはnameを名前とするファイルとして保存されます。このため、JARコマンドにより追加したリソースも取り出すことが出来ます。
public byte[] getResource(String name);
名前 name としてリソースリポジトリに登録されているリソースを返す。名前はJARコマンドで圧縮したときのリソースの名前(相対パス名)となります。
public String getResourceType(String name);
名前 name としてリソースリポジトリに登録されているリソースの種別 をMIMEタイプとして返す
public InputStream getResourceAsStream(String name);
名前 name としてリソースリポジトリに登録されているリソースをストリーム 形式で返す。