ToolTalk ユーザーズガイド

第 12 章 オブジェクト

この章では、アプリケーションが作成および管理するオブジェクトの ToolTalk 仕様 (スペック) の作成方法について説明します。オブジェクトの型を識別できるようになる前に、otype を定義して、その otype を ToolTalk 型データベースに格納する必要があります。otype の詳細は、第 10 章「静的メッセージパターン」を参照してください。

ToolTalk サービスは、仕様と otype 情報を使用して、オブジェクト指向メッセージの受信側を決定します。


注 -

ToolTalk オブジェクト指向メッセージインタフェース用にコーディングされたプログラムは、ソースコードを変更しなければ CORBA 準拠のシステムに移植できません。


オブジェクト指向メッセージ方式

オブジェクト指向メッセージは、アプリケーションが管理するオブジェクトにアドレス指定されます。オブジェクト指向メッセージ方式を使用するには、プロセス指向メッセージ方式と ToolTalk のオブジェクトの概念について詳しく知る必要があります。

オブジェクトデータ

オブジェクトデータは、図 12-1 に示すように 2 つの部分に分けて格納されます。

図 12-1 ToolTalk オブジェクトデータ

Graphic

1 つの部分を「オブジェクト内容」と呼びます。オブジェクト内容は、そのオブジェクトを作成または管理するアプリケーションが管理する通常ファイルの一部または複数の部分です。たとえば、パラグラフ、ソースコード関数、スプレッドシートのセルの集まりなどです。

オブジェクトのもう 1 つの部分は、「オブジェクト仕様」(「スペック」) と呼びます。スペックには、オブジェクトの型、オブジェクト内容が入っているファイル名、オブジェクトの所有者などの標準プロパティが入っています。また、アプリケーションはそれ自体のプロパティ (たとえば、ファイル内のオブジェクト内容の場所) をスペックに追加することもできます。アプリケーションがスペックに追加情報を格納できるので、ファイルのフォーマットを変更せずに、既存のファイル内のデータをオブジェクトとして識別できます。また、読み取り専用ファイルの一部からオブジェクトを作成できます。アプリケーションはスペックを作成し、rpc.ttdbserverd が管理する ToolTalk データベースに書き込みます。


注 -

読み取り専用ファイルシステムに存在しているファイルの中には、オブジェクトを作成できません。ToolTalk サービスは、オブジェクトが入っているファイルシステム内にデータベースを作成できなければなりません。


「ToolTalk オブジェクト」は、ToolTalk スペックが作成されるアプリケーションデータの一部です。

オブジェクト仕様の作成

メッセージをオブジェクトに配信するよう ToolTalk サービスに指示するには、オブジェクトとその otype を識別する仕様を作成します。表 12-1 に、オブジェクト仕様の作成と書き込みに使用する ToolTalk 関数を示します。

表 12-1 作成用関数

ToolTalk 関数 

説明 

tt_spec_create(const char *filepath)

仕様を作成する。返される型は char *

tt_spec_prop_set(const char *objid, const char *propname, const char *value)

指定された文字列の値にプロパティを設定する。返される型は Tt_status

tt_spec_prop_add(const char *objid, const char *propname, const char *value)

文字列プロパティを追加する。返される型は Tt_status

tt_spec_bprop_add(const char *objid, const char *propname, const unsigned char *value, int length)

バイト配列プロパティを追加する。返される型は Tt_status

tt_spec_bprop_set(const char *objid, const char *propname, const unsigned char *value, int length)

指定されたバイト配列値にプロパティを設定する。返される型は Tt_status

tt_spec_type_set(const char *objid, const char *otid)

仕様のオブジェクト型を設定する。返される型は Tt_status

tt_spec_write(const char *objid)

データベースに仕様を書き込む。返される型は Tt_status

オブジェクト仕様をメモリーに作成し、そのオブジェクトの objid を取得するには、tt_spec_create を使用します。

otype の割り当て

オブジェクト仕様に otype を割り当てるには、tt_spec_type_set を使用します。仕様が最初に書き込まれる前に、その型を設定しなければなりません。この型は変更できません。


注 -

otype を割り当てないでオブジョクト仕様を作成する場合、または ToolTalk 型データベースにとって不明の otype を持つオブジェクト仕様を作成する場合、そのオブジェクトにアドレス指定されたメッセージは配信できません。(ToolTalk サービスは、ユーザーが指定した otype が ToolTalk 型データベースにとって既知であるかどうかは検査しません。)


オブジェクト仕様プロパティの決定

ユーザーは、オブジェクトに関連付けたい「プロパティ」を決定できます。つまり、関連付けたいプロパティを仕様に追加します。ToolTalk サービスでは、ユーザー専用の内部データに、たとえば通常の ASCII 形式テキストファイル内のオブジェクト用 objid のような情報をいつでも格納できるわけではありません。まず、仕様プロパティ内の objid の場所を格納して、さらにこの場所を利用すれば、ツールの内部データ構造のどこにオブジェクトがあるかを識別できます。

仕様プロパティは、ユーザーにとっても便利なものです。ユーザーは、コメントまたはオブジェクト名などのプロパティを後で見ることができるオブジェクトに関連付けたいことがあります。ユーザーのアプリケーションまたは別の ToolTalk を使ったツールが、ユーザーに代わってオブジェクトに関連付けたプロパティの検索と表示を行います。

仕様プロパティの格納

仕様内にプロパティを格納するには、tt_spec_prop_set を使用します。

プロパティへの値の追加

プロパティに関連する値のリストに追加するには、tt_spec_prop_add を使用します。

オブジェクト仕様の書き込み

otype を設定してオブジェクト仕様にプロパティを追加した後に tt_spec_write を使うと、そのプロパティは永続的な ToolTalk 項目となり、他のアプリケーションから見えるようになります。tt_spec_write を呼び出すと、ToolTalk サービスは ToolTalk データベースにその仕様を書き込みます。

オブジェクト仕様の更新

既存のオブジェクト仕様プロパティを更新するには、既存の仕様の objid を指定し、tt_spec_prop_settt_spec_prop_add を使用します。仕様プロパティが更新された場合は、tt_spec_write を使って ToolTalk データベースにその変更を書き込みます。

既存の仕様を更新中に、tt_spec_write を呼び出した時点で ToolTalk サービスが TT_WRN_STALE_OBJID を返した場合、ToolTalk データベース内のオブジェクトを指す転送ポインタが見つかったことになります。これは、オブジェクトが移動していることを示します。新しい objid を取得するには、古い objid が入ったオブジェクトメッセージを作成し、このメッセージを送信します。ToolTalk サービスは、同じ状態コードの TT_WRN_STALE_OBJID を返しますが、新しい objid を入れるためにメッセージの objid 属性を更新します。tt_message_object を使って、メッセージから新しい objid を検索し、新しい objid を内部データ構造に配置します。

オブジェクト仕様の管理

ToolTalk サービスでは、オブジェクト仕様の検査、比較、照会、および移動を行う関数を提供しています。表 12-2 に、オブジェクト仕様を管理するために使用する ToolTalk 関数を示します。

表 12-2 オブジェクト仕様を管理する関数

返される型 

ToolTalk 関数 

説明 

char *

tt_spec_file(const char *objid)

仕様があるファイル名 

char *

tt_spec_type(const char *objid)

仕様のオブジェクト型 

char *

tt_spec_prop(const char *objid, const char *propname, int i)

(ゼロから数えて)「i」番目のプロパティ値を文字列として検索する 

int

tt_spec_prop_count(const char *objid, const char *propname)

このプロパティ名での値の数 

Tt_status

tt_spec_bprop(const char *objid, const char *propname, int i, unsigned char **value, int *length)

このプロパティ名でのバイト配列の値の数 

char *

tt_spec_propname(const char *objid, int i)

「i 番目」のプロパティ名 

int

tt_spec_propnames_count(const char *objid)

この仕様のプロパティ数 

char *

tt_objid_objkey(const char *objid)

仕様 ID に固有のキー 

Tt_status

tt_file_objects_query(const char *filepath, Tt_filter_function filter, void *context, void *accumulator)

オブジェクト仕様用のデータベースを照会する 

int

tt_objid_equal(const char *objid1, const char *objid2)

2 つの仕様 ID が等しいかどうかを検査する 

char *

tt_spec_move(const char *objid, const char *newfilepath)

オブジェクト仕様を新しいファイルに移動する 

仕様情報の検査

指定された ToolTalk 関数によって、次の仕様情報を検査できます。

オブジェクト仕様の比較

2 つの objid を比較するには、tt_objid_equal を使用します。tt_objid_equal は、1 つの objid が他の objid に対する転送ポインタの場合でも 1 を返します。

ファイル内の特定の仕様の照会

ファイル内の特定の仕様を照会するためにフィルタ関数を作成し、対象とする仕様を取得します。

tt_file_objects_query を使って、指定されたファイル内のすべてのオブジェクトを見つけます。ToolTalk サービスは、各オブジェクトを見つけるとフィルタ関数を呼び出し、そのオブジェクトの objid とアプリケーションが与えた 2 つのポインタをそのフィルタ関数に渡します。フィルタ関数は演算をいくつか行い、Tt_filter_action の値 (TT_FILTER_CONTINUE または TT_FILTER_STOP) を返します。これは照会を続行するか、検出を終了してすぐに復帰するかを示します。

例 12-1 は、仕様リストの取得方法を示します。


例 12-1 仕様リストの取得

/*
 * Called to update the scrolling list of objects for a file. Uses
 * tt_file_objects_query to find all the ToolTalk objects.
 */
int
cntl_update_obj_panel()
{
       static int list_item = 0;
	char *file;
	int i;

	cntl_objid = (char *)0;

	for (i = list_item; i >= 0; i--) {
		xv_set(cntl_ui_olist, PANEL_LIST_DELETE, i, NULL);
	}

	list_item = 0;
	file = (char *)xv_get(cntl_ui_file_field, PANEL_VALUE);
	if (tt_file_objects_query(file,
                                     (Tt_filter_function)cntl_gather_specs,
                                   &list_item, NULL) != TT_OK) {
		xv_set(cntl_ui_base_window, FRAME_LEFT_FOOTER,
		       "Couldn't query objects for file", NULL);
		return 0;
	}

	return 1;
}


tt_file_objects_query 関数内では、アプリケーションは、オブジェクトをスクロールリストに挿入するフィルタ関数 cntl_gather_specs を呼び出します。例 12-2 に objid の挿入方法を示します。


例 12-2 objid の挿入

/*
 * Function to insert the objid given into the scrolling lists of objects
 * for a file. Used inside tt_file_objects_query as it iterates through
 * all the ToolTalk objects in a file.
 */
Tt_filter_action
cntl_gather_specs(objid, list_count, acc)
     char *objid;
     void *list_count;
     void *acc;
{
	int *i = (int *)list_count;

	xv_set(cntl_ui_olist, PANEL_LIST_INSERT, *i,
	       PANEL_LIST_STRING, *i, objid,
	       NULL);

	*i = (*i + 1);

	/* continue processing */
	return TT_FILTER_CONTINUE;
}


オブジェクト仕様の移動

objid には、仕様情報が格納された特定のファイルシステムを指すポインタが入っています。仕様によって記述されたオブジェクトと同じように仕様情報を利用できるようにするため、ToolTalk サービスは仕様情報をそのオブジェクトと同じファイルシステムに格納します。そのため、オブジェクトが移動すると、仕様も移動しなければなりません。

tt_spec_move を使用して、オブジェクトが 1 つのファイルから別のファイルにいつ移動したか (たとえば、カット&ペースト操作などで) を ToolTalk サービスに知らせます。

プロセスが古い objid にメッセージを送信する場合 (つまり、転送ポインタを持つ objid)、tt_message_send は特殊な状態コード TT_WRN_STALE_OBJID を返し、メッセージ内のオブジェクト属性を新しい場所の同じオブジェクトを指す新しい objid と置き換えます。


注 -

オブジェクトを参照する内部データ構造体は、すべて新しい objid に更新してください。


オブジェクト仕様の削除

tt_spec_destroy を使用して、オブジェクト仕様をすぐに削除します。

オブジェクトおよびファイル情報の管理


注意 - 注意 -

ToolTalk サービスと統合アプリケーションがあるにも関わらず、rmmv などの標準のオペレーティングシステムコマンドによるファイルの削除、移動、または名前の変更を行うことによって、オブジェクトの参照が削除されることがあります。参照が削除されると、メッセージが配信できなくなります。


オブジェクトデータが入ったファイルの管理

オブジェクトデータが入ったファイルが格納されているディスクパーティションのサービスを行う ToolTalk データベースを最新にしておくために、ファイルをコピー、移動、または削除する ToolTalk 関数を使用します。表 12-3 に、ユーザーがオブジェクトデータの入ったファイルの管理に使用する ToolTalk 関数を示します。

表 12-3 オブジェクデータファイルをコピー、移動、および削除する関数

ToolTalk 関数 

説明 

tt_file_move(const char *oldfilepath, const char *newfilepath)

ファイルと ToolTalk オブジェクトデータを移動する 

tt_file_copy(const char *oldfilepath, const char *newfilepath)

ファイルと ToolTalk オブジェクトデータをコピーする 

tt_file_destroy(const char *filepath)

ファイルと ToolTalk オフジェクトデータを削除する 

これらの関数から返される型は Tt_status です。

ToolTalk 情報が入ったファイルの管理

ToolTalk サービスは、ToolTalk オブジェクトとファイル情報をコピー、移動、および削除するための ToolTalk の拡張シェルコマンドを提供しています。アプリケーションのユーザーが、メッセージ内で参照されるファイルとオブジェクトの入ったファイルをコピー、移動、および削除するために使用する ToolTalk の拡張シェルコマンドを表 12-4 に示します。

表 12-4 ToolTalk の拡張シェルコマンド

コマンド 

説明 

ttcp

ファイルを新しい場所にコピーする。ToolTalk データベース内のファイルとオブジェクトの場所についての情報を更新する 

ttmv

ディレクトリ名またはファイル名を変更する。ToolTalk データベース内のファイルとオブジェクトの場所についての情報を更新する 

ttrm

指定されたファイルを削除する。ToolTalk データベース内のファイルとオブジェクトの情報を削除する 

ttrmdir

ToolTalk オブジェクト仕様を関連付ける空のディレクトリ (ファイルが入っていないディレクトリ) を削除する (ディレクトリ用にオブジェクト仕様を作成できる。オフジェクト仕様が作成されると、ファイルまたはディレクトリのパス名が与えられる) 

ToolTalk データベースからオブジェクト情報を削除する 

tttar

複数のファイルとオブジェクト情報を tarfile と呼ばれる単一のアーカイブに保存 (またはこのアーカイブから抽出) する。ToolTalk ファイルとオブジェクト情報を tarfile に保存 (または tarfile から抽出) するためにも使用できる 

オブジェクト指向メッセージの例

edit_demo というプログラムを実行すれば、ToolTalk のオブジェクト指向メッセージのデモを見ることができます。このデモプログラムは、cntledit という 2 つのプログラムで構成されています。cntl の方は ToolTalk サービスを使用して、指定されたファイルを編集する編集プロセスを起動します。edit を使用すれば、ToolTalk オブジェクトを作成し、その指定されたファイル中のテキストと関連付けることができます。オブジェクトを作成してテキストと関連付けると、cntl を使用してそのファイルにオブジェクトを照会し、そのオブジェクトにメッセージを送信できます。

例 12-3 は、C 言語形式のコメントを前後につけてユーザーのオブジェクトを作成します。2 つのコード例から成り立ちます。オブジェクト仕様を作成して otype を設定し、その仕様を ToolTalk データベースに書き込むことにより、ユーザーの選択をラップします。さらに、アプリケーションは ToolTalk_EditDemo_new_object 操作を使って新しいオブジェクトを作成し、メッセージを監視する他のアプリケーションを更新した後、手続きアドレス指定された通知も送信します。他のアプリケーションが、ToolTalk_EditDemo が管理するファイル内のオブジェクトのリストを表示している場合、この通知を受信した後にリストを更新します。


例 12-3 オブジェクトの作成 - 1

/*
 * Make a ToolTalk spec out of the selected text in this textpane. Once
 * the spec is successfully created and written to a database, wrap the
 * text with C-style comments in order to delimit the object and send out
 * a notification that an object has been created in this file.
 */
Menu_item
edit_ui_make_object(item, event)
   Panel_item		item;
   Event		*event;
{
         int               mark = tt_mark();
	char		*objid;
	char		*file;
	char		*sel;
	Textsw_index		first, last;
	char		obj_start_text[100];
	char		obj_end_text[100];
	Tt_message		msg;

	if (! get_selection(edit_ui_xserver, edit_ui_textpane,
			  &sel, &first, &last)) {
		xv_set(edit_ui_base_window, FRAME_LEFT_FOOTER,
		       "First select some text", NULL);
		tt_release(mark);
		return item;
	}
	file = tt_default_file();

	if (file == (char *)0) {
		xv_set(edit_ui_base_window, FRAME_LEFT_FOOTER,
		       "Not editing any file", NULL);
		tt_release(mark);
		return item;
	}



例 12-4 オブジェクトの作成 - 2

/*
	/* create a new spec */

	objid = tt_spec_create(tt_default_file());
	if (tt_pointer_error(objid) != TT_OK) {
		xv_set(edit_ui_base_window, FRAME_LEFT_FOOTER,
		       "Couldn't create object", NULL);
		tt_release(mark);
		return item;
	}

	/* set its otype */

	tt_spec_type_set(objid, "Sun_EditDemo_object");
	if (tt_spec_write(objid) != TT_OK) {
		xv_set(edit_ui_base_window, FRAME_LEFT_FOOTER,
		       "Couldn't write out object", NULL);
		tt_release(mark);
		return item;
	}

	/* wrap spec's contents (the selected text) with C-style */
	/* comments. */

	sprintf(obj_start_text," /* begin_object(%s) */", objid);
	sprintf(obj_end_text,"	/* end_object(%s) */", objid);
	(void)wrap_selection(edit_ui_xserver, edit_ui_textpane,
			   obj_start_text, obj_end_text);

	/* now send out a notification that we've added a new object */

	msg = tt_pnotice_create(TT_FILE_IN_SESSION,"Sun_EditDemo_new_object");
	tt_message_file_set(msg, file);
	tt_message_send(msg);

	tt_release(mark);
	return item;
}