コールバックに「インターネット」用スマートコードを選択すると、Sun WorkShop Visual は、デザインからクライアントアプリケーションを生成します。インターネット用スマートコードのプログ ラミングでは、WWW を介してパブリックサーバー上の既存の Web ページや CGI プログラムにアクセスします。スマートコードのコールバックは、(「callouts」というサブディレクトリ の) クライアントアプリケーションに生成されます。「インターネット」のコールバックを定義した場合に、Su n WorkShop Visual によって生成されるアプリケーションの構造を図 18-1 に示します。thin クライアント用スマートコードの場合とは異なり、このタイプのコールバックには、クライアントアプリケ ーションと通信コードだけが生成されます。
グループは、getter や setter とともに、あらゆるタイプのスマートコードの基本となります。したがって、インターネット (または thin クライアント) 用スマートコードを使用するには、グループと取得/設定用スマートコードの使い方を理解する必要があり ます。これらの内容については、以下の章を参照してください。
1. ウィジェットのグループ化については、第 15 章「グループ」を参照してください。
2. 第 16 章「取得/設定用スマートコード」では、デザイン内のウィジェットに対してツールキットに依存しな いラッパーを提供する、取得/設定用スマートコードについて説明しています。
「試行」機能により、Sun WorkShop Visual のダイナミックディスプレイをプロトタイプクライアントとして使用できます。これによって、インタフェ ースの開発時に、インタフェースを生データでテストできます。「インターネット用スマートコードの簡単な学習」では、きわめて簡単な例を通じて、この操作方法とアプリケーションの生成方法 を示します。
着信データの処理や操作のためには独自の受信ハンドラを記述する必要があるため 、インターネット用スマートコードのプロトタイプで「試行」を使用する際には制限があります。

インターネット用と thin クライアント用のスマートコードは次の点でよく似ています。
このため、Sun WorkShop Visual の内部では、ユーザーインタフェースのいくつかの部分が共有されています。インターネットを使用するに は、第 17 章の以下の節を参照してください。
インターネット用スマートコードで生成されたアプリケーションには、受信ハンド
ラが必要です。Sun WorkShop Visual
は返却データへのポインタを提供しますが、そのデータの処理はユーザーが行ないます。データハンドラは
「カスタマイズ」ダイアログの一部であり、「サーバー接続のカスタマイズ」に記述されています。返却されたデータを利用するために、
Sun WorkShop Visual
はライブラリを提供しています。このライブラリを使用すれば、入力ストリームの特定項目にインタレスト
(関心) を表明し、それらの項目が到着したら「選び出す」ことができます。これについては 「HTML
データから情報を抽出」を参照してください。
データをストリームとして処理したり、Sun WorkShop Visual が提供する InputData クラスやオブジェクトを使用して getData() や getSize() のメソッドを介してデータにアクセスすることができます。たとえば、gif や jpeg のイメージなど、表示ウィジェットに送信するデータをダウンロードしている場合には、これは特に便利で す。C コードの場合には、InputData オブジェクトはデータ構造体です。C++ と Java の場合には、これはクラスです。InputData の詳細をオンライン参照資料で調べるには、HTML ブラウザで次のファイルを開き、適切なリンクに従ってください。
$VISUROOT/lib/locale/<YourLocale>/sc/index.html
ここで、VISUROOT は Sun WorkShop Visual のインストールディレクトリであり、 <YourLocale> は使用しているロケールです。
着信データの処理方法に関する簡単な例として、「試行」トグルをオンにした状態 でインターネット用スマートコードのコールバックを設定した後、デザインからコードを生成します。この 場合には、受信ハンドラとして「@<ウィジェット名>」という短縮形表記を使用します。これは、「インターネット用スマートコードの簡単な学習」で行う操作とまったく同じです。
「インターネット」用スマートコードを選択した場合には、Sun WorkShop Visual はインターネット上のサイトからデータを取り出すものと想定するため、GET HTTP プロトコルを使用します。「カスタマイズ」ダイアログで関数名を指定して送信ハンドラを無効にした場合 には、Sun WorkShop Visual は POST プロトコルを使用します。
次の例では、インターネット用スマートコードについて簡単に紹介します。ここで は、実際の Web サイトに接続して、そこからデータをダウンロードします。その様子を見るには、Sun WorkShop Visual の「試行」を使用するか、生成したアプリケーションを実行してください。
インターネット用スマートコードの使い方に早く慣れていただくため、次の例では 返却データの解析を行いません。HTML の解析については、「HTML データから情報を抽出」を参照してください。
注 - この学習ではリモートサーバーへの接続方法を示します。したがって、リモートサ ーバーに接続できるよう構成されたコンピュータをご使用ください。
1. 図 18-2 に示すウィジェットを含んでいる階層を作成します。

2. 配置エディタで、スクロールテキストウィジェットをフォームの下端と右端に接続して、ウィンドウのサイ ズ変更に応じてこのウィジェットがサイズ変更できるようにします。
3. text1 (スクロールテキストウィジェットのテキスト領域) を選択します。ツールバーの「新規グループに追加」ボタンを押します。
このボタンを図 18-3 に示します。

4. 表示されたグループエディタで、図 18-4 に示すようにテキストウィジェットだけをグループのメンバーとして持つ Group0 というグループがあることを確認します。

何も変更する必要はありません。この学習では Sun WorkShop Visual によって作成されたグループを使用します。
6. button1 を選択し、「コールバック」ダイアログを表示します。
7. 左側のリストから「活性化」が選択されていることを確認し、コールバックの名前として goInternet を指定します。
スマートコードを定義する必要があるため、まだこのコールバックを追加しないで ください。
9. スマートコードの「スタイル」オプションメニューから「インターネット」を選択します。
10. このコールバックのグループとして Group0 を選択します。
そのためには、「グループ」ボタンを押し、グループエディタで Group0 が選択されていることを確認してから「適用」ボタンを押します。
13. ファイアウォールの保護下にある場合には、プロキシ・ホストとポートを設定します。
プロキシ設定の詳細については、「プロキシの詳細」を参照してください。
これらのフィールドでの「@」の使い方については、「試行」を参照してください。
完成した「カスタマイズ」ダイアログを図 18-5 に示します。
注 - この「カスタマイズ」ダイアログは、一例として架空のプロキシを示します。「プロキシの詳細」で説明するように、使用するネットワークに適切なプロキシを入力する必 要があります。

17. 「コールバック」ダイアログで、「試行」トグルをオンにします。
「試行」をオンにした場合には、コールバックを「更新」する必要はありません。 コールバックはその時点で試行可能になります。
18. ダイナミックディスプレイで、button1 を押します。
リモートサーバーとの接続が行われている間は一時停止状態になります。その後、 図 18-6 に示すように、返却データ (「カスタマイズ」ダイアログで指定した Web ページ) が text1 に表示されます。

この学習の最終段階では、生成されたアプリケーションでも同じものが表示されま す。
インターネット用スマートコードで開発したアプリケーションでは、Web ページを取り出し、それを解析し、その結果を表示できます。サーバーから返された HTML データを整理してそのプロセスを大幅に単純化し、さらに使いやすくできるように、Sun WorkShop Visual には HTML パーサーが付属しています。
WWW の概念として、Web サーバーから取り出されるデータの大部分は HTML 形式になります。パーサーは、SGML User Groupの基準 SGML パーサー資料1 をベースにしています。このパーサーは、汎用の SGML パーサーエンジンを生成するよう改造されたものです。SGML は、DTD (Document Type Definition: 文書タイプ定義) と連結して、マークアップ言語を定義します。HTML 用の DTD は、Sun WorkShop Visual に付属しています。
DTD を別途追加することにより、他の規格のマークアップ言語や社内用のマークアップ言語でもパーサーを使用 できます。また、HTML の将来のバージョンや XML に対しても、アプリケーションをアップグレードすることができます。
SGML パーサーには、簡単で便利なプログラミングインタフェースがあります。入力ストリーム (つまり、HTML タグ) の 1 つ以上の項目にインタレスト (関心) を登録すれば、パーサーがこれらの項目を検出するたびに、選択したルーチンが呼び出されます。これは、 ウィジェットのコールバック方式と似ています。ウィジェットは特定のアクションにインタレストを登録し ます。そのようなアクションが発生すると、所定のルーチンが呼び出されます。
注 - ここで使用される Web 技術についてよくご存じない (または頭字語の意味がわからない) 場合には、背景となる知識を得られるようお勧めします。推奨書籍の一覧については、「ネットワーキングとWWWに関する資料」を参照してください。
パーサーを使用して着信データから必要な情報を抽出したいことを Sun WorkShop Visual に通知するには、「カスタマイズ」ダイアログで「SGML/HTML パーサ」トグルをオンにします。受信ハンドラでは、必要条件に応じてパーサーを設定してから、データを パーサーに送信します。この操作 (およびその結果) の詳細を以下に説明します。
「カスタマイズ」ダイアログで「SGML/HTML パーサ」トグルをオンにして、SGML/HTML を処理したいことを Sun WorkShop Visual に通知した後は、以下の 4 つの手順が必要となります。各手順は、受信ハンドラの内部で行われます。
1. ルーチン scRegisterSGMLMimeType (または HTML scRegisterHTML のショートカット) を呼び出すことによって、MIME 型を登録します。
2. ルーチン scRegisterSGMLMimeErrorHandler を呼び出すことによって、エラーハンドラを登録します。この手順は省略可能です。
3. ルーチン scAddTagCallback と scAddAttrCallback を呼び出すことによって、入力ストリームの 1 つ以上の項目にインタレストを登録します。あるいは、この時点で従来の構文解析ツリーを要求することも できます。
パーサーへのインタフェースをプログラムする前に、次のヘッダーファイルをイン クルードしていることを確認してください。
#include <SGML.h>
このヘッダーファイルは Sun WorkShop Visual に付属しています。このヘッダーファイルのディレクトリは、自動的に Makefile に組み込まれます。
さらに、DTDDIR 環境変数には次の値を設定する必要があります。
$VISUROOT/src/sgml/dtds
SGML パーサーの位置と使用するファイルの詳細については、「パーサーを使用するための実用情報」参照してください。
パーサーを構成するには、最初に SGML オブジェクトを作成する必要があります。その後、このオブジェクトは、呼び出す必要のある他のルーチン に渡されます。SGML オブジェクトは、次に示す、データの MIME 型を登録するために呼び出すルーチンから返されます。
SGML_t *
scRegisterSGMLMimeType( mimetype, dtd)
char * mimetype;
char * dtd;
これを使用して、MIME 型と SGML DTD を関連付けます。最も一般的な方法を次に示します。
SGML_t * sgm = scRegisterSGMLMimeType("text/html", "HTML32.soc");
これは最もよく使用されるため、次のショートカットを使用することもできます。
SGML_t *
scRegisterHTML( mimetype)
char * mimetype;
この動作は上とまったく同じであり、「text/html」と HTML32 DTD を関連付けます。独自の DTD を追加するには、それを DTDDIR 環境変数によって参照されるディレクトリに置いてください。
次に、「SGML/HTML パーサ」トグルをオンにした状態で、「受信 (URL の内容)」フィールドに「processMyData」を指定した場合に生成されるものを示します。MIME 型を登録するために 1 つの行が追加されています。
int
processMyData ( data, idata)
sc_stdcs_t* data;
sc_idata* idata;
{
extern InputData * newInputData();
group0_t * group = (group0_t*)data->group;
InputStream * i = (*idata->getInputStream)( idata);
#if 0 /* example usage */
char * type = (*idata->getMimeType)(idata);
int len = (*idata->getContentLength)( idata);
InputData * id = newInputData( i);
char * d = (*id->getData)( id);
#endif
sgm = scRegisterHTML( type); /* この行が追加されました */
...
return 0;
}
デフォルトのエラーハンドラは、標準出力にエラーメッセージを出力します。これ を無効にするには、次のルーチンを使用して、独自のエラーハンドラを登録してください。
int
scRegisterSGMLErrorHandler( errorhandler)
void_f errorhandler;
void
errorhandler( s)
char * s;
解析されたデータを利用するため、入力の 1 つ以上の項目 (たとえば、HTML 内の特定のタグや属性) にインタレストを登録します。
入力項目へのインタレストの登録は、ウィジェットのコールバック方式によく似て
います。ウィジェットのコールバックの場合、ウィジェットは特定のアクションにインタレストを登録しま
す。そして、そのアクションが起こると、指定したルーチン
(コールバック)
が呼び出されます。ここでは、言語の項目にインタレストを登録します。パーサーは、これらの項目のどち
らかを検出すると、ユーザーのコールバックルーチンを呼び出します。
HTML には、タグと属性という 2 つの主要項目があります。以降の節で説明する 2 つのルーチンのどちらかを使用して、これらの項目にインタレストを登録できます。最初に、タグと属性を 簡単に説明しておきます。
タグは、以下のテキスト要素の書式を記述する HTML の項目です。タグは山括弧で囲まれて表示されます。たとえば、<menu> は中黒付きリストを示し、<code> はコードのリストを示します。次の例では、個々のリスト項目を含んだ「menu」ブロックを示します。
<menu>
<li>The first item in the list
<li>The second item in the list
</menu>
属性は HTML のもう 1 つの項目です。属性も山括弧で囲まれて表示されます。属性はタグの後に置かれ、参照を示すために使用さ れます。参照先としては、外部ファイル、イメージ、文書内の他の位置などがあります。属性は常に、予約 文字列である等号記号 (=) と参照から構成されています。次の例では 2 つの属性を示します。最初の属性「href」はリンクの宛先 (「bottom」という場所) を指定します。ブロック内の「Go to bottom of page」というテキストは、実際に「目に見える」部分です。2 番目の属性は「name」であり、場所を指定します (この場合は「bottom」)。したがって、ユーザーの側から見れば、「Go to bottom of page」を選択すると、指定された位置である「bottom」にある内容が表示されます。
<a href="#bottom"><b>Go to bottom of page</b></a>
...
<a name="bottom"></a>
特定の HTML 言語項目にインタレストを登録するために使用できる、2 つのルーチンがあります。これらは次のとおりです。
SGML パーサーは、HTML 入力のどの部分にユーザーが関心を持っているかを知る必要があります。また、選択した HTML ブロック内のどこでコールバックルーチンを呼び出すかも知る必要があります。
タグ要素にインタレストを登録するためのルーチンは次のとおりです。
int
scAddTagCallback( sgm, tagname, type, callback, data)
SGML_t * sgm;
char * tagname;
int type;
void (*callback)();
void * data;
このルーチンへの引数には、さらに説明が必要です。これについては以下の項を参 照してください。
これは、データの MIME 型を登録するルーチンである、 scRegisterSGMLMimeType から返される SGML オブジェクトです。 scRegisterSGMLMimeType については、「MIME 型の登録」を参照してください。
この引数は、選択されたタグ内でユーザーのコールバックルーチンをいつ呼び出す かをパーサーに通知します。さらに、HTML の選択したブロックの内部からコールバックルーチンにデータが渡されるかどうかは、選択した「型」によ って決まります。ユーザーのコールバックルーチンは、任意の数の異なるタグと型に同じルーチンを使用で きるよう、常にタグ名とタイプを受け取ります。しかし、「ON_ATTR」と「ON_DATA」の場合には、より多く の情報が返されます。
図 18-7 に示すように、タグブロック内のどこでコールバックルーチンを呼び出すかに応じて、4 つの定義済みの型を選択できます。4 つの型は次のとおりです。

これは、パーサーがユーザーの関心のあるタグを検出したときに呼び出すルーチン の名前です (コールバックルーチン)。これはユーザーが定義するルーチンです。このルーチンの形式については、「ユーザーのコールバックルーチン」を参照してください。
int
scAddAttrCallback( sgm, tagname, attrname, callback, data)
SGML_t * sgm;
char * tagname;
char * attrname;
void (*callback)();
void * data;
ユーザーのコールバックルーチンにはスタブファイルがありません。すべて自分で 記述する必要があります。ルーチンの名前は、 scAddAttrCallback または scAddTagCallback への 4 番目の引数 (つまり「callback」という引数) として指定された名前です。
パーサーは、インタレストの登録されたタグや属性を検出すると、ユーザーのコー ルバックルーチンを呼び出します。次の例では、ユーザーのコールバックの内容と渡される引数の一覧を示 します。
int
mycallback( tag, attribute, type, call_data, client_data)
char * tag;
char * attribute;
int type;
void * call_data;
void * client_data;
2.
char * attribute
パーサーが検出した属性です。タグだけに関心があった場合には、これはヌルです。
3.
int type
ルーチンの呼び出し型が「ON_ENTRY」、「ON_EXIT」、「ON_DATA」、「ON_ATTR」のいずれであるかを示し
ます。これらについては、「int
type」を参照してください。属性に関心がある場合には、この引数は関係ありません。
4.
void * call_data
属性に関心がある場合には、これは等号記号の後に記述される属性部分です。たとえば、「href」属性にイ
ンタレストを登録し、パーサーが次の行を検出した場合、この引数は「
#regmime
」となります。
<a href="#regmime">
インタレストのタグとして「ON_DATA」を指定した場合には、この引数はタグの後のデータです。実例については、図 18-7 を参照してください。
5.
void * client_data
これは登録ルーチンに渡される「データ」引数であり、ユーザー独自のデータをコールバックに渡すことが
できます。これは、「コールバック」ダイアログでの Xt
コールバック用のクライアントデータに似ています。
任意の数のタグや属性にインタレストを登録できるため、任意の数のコールバック ルーチンを持つことができます。しかし、タグと属性にそれぞれ 1 つのコールバックルーチンを持つことが、おそらく最も便利な組み合わせとなります。
MIME 型を指定し、エラーハンドラを登録し、特定の入力ストリーム項目にインタレストを登録して SGML オブジェクトを設定すると、パーサーを呼び出す準備ができたことになります。そのためのルーチンを次に 示します。
scProcessSGML( sgm, istream)
SGML_t * sgm; /* the parser handle scRegisterSGMLMimeType */
InputStream * istream; /* the input stream from the server */
この節では、SGML パーサーの使い方を説明します。「カスタマイズ」ダイアログで 「SGML/HTML パーサ」トグルをオンにした場合には、受信ハンドラの名前も与える必要があります。Sun WorkShop Visual によって生成されたハンドラのスタブを次に示します。
int
processMyData ( data, idata)
sc_stdcs_t* data;
sc_idata* idata;
{
extern InputData * newInputData();
group0_t * group = (group0_t*)data->group;
InputStream * i = (*idata->getInputStream)( idata);
#if 0 /* example usage */
char * type = (*idata->getMimeType)(idata);
int len = (*idata->getContentLength)( idata);
InputData * id = newInputData( i);
char * d = (*id->getData)( id);
#endif
return 0;
}
SGML パーサーを使用するには、SGML オブジェクトを作成するためにこのルーチンにいくつかのコードを追加し、SGML オブジェクトを設定してから、着信データをパーサーに送信する必要があります。着信 HTML を解析するためのコードを追加した受信ハンドラを次に示します。
int
processMyData ( data, idata)
sc_stdcs_t* data;
sc_idata* idata;
{
extern InputData * newInputData();
group0_t * group = (group0_t*)data->group;
InputStream * i = (*idata->getInputStream)( idata);
/* 「#if 0 /* example usage */」という行は削除されました */
char * type = (*idata->getMimeType)(idata);
int len = (*idata->getContentLength)( idata);
InputData * id = newInputData( i);
char * d = (*id->getData)( id);
/* 「#endif」という行は削除されました */
/* ここからは追加された行です */
SGML_t * sgm;
if ( strcmp( type, "text/html") != 0)
return -1;
sgm = scRegisterHTML( type); /* the parser object */
(void) scAddTagCallback(sgm, "A", ON_ENTRY, getanchor,
"a-call");
(void) scAddAttrCallback(sgm, "A", "HREF",
getlinkinfo, "href");
(void) scProcessSGML( sgm, i);
/* ここまでが追加された行です */
return 0;
}
このルーチンでは、パーサーがアンカータグ (<a>) を検出するたびに getanchor を呼び出し、「href」属性が検出されるたびに getlinkinfo を呼び出すことを指定しています。以下のルーチンは、ユーザーが記述してください。
int
getanchor( tag, attr, type, call_data, client_data)
char * tag;
char * attr;
int type;
void * call_data;
void * client_data;
{
printf("anchor-start(%s)\n", client_data);
}
int
getlinkinfo( tag, attr, type, call_data, client_data)
char * tag;
char * attr;
int type;
void * call_data;
void * client_data;
{
printf( "%s=%s\n", client_data, call_data);
}
注 - このパーサーを使用する、Sun WorkShop Visual 再現機能によるオンラインスクリプトを実行する方法については、「さらに進んだ学習」を参照してください。
SGML パーサーを使用するには、コンパイル済みのコードとリンクする必要があります。ソースの場所を次に示し ます。
$VISUROOT/src/sgml
ライセンス条項により、ユーザーはこれらのソースを自由に使用できます。
最初は Sun WorkShop Visual に付属のコンパイル済みバージョンを使用する方が簡単です。
SGML パーサーは、以下のファイルとディレクトリを使用します。
1.
$VISUROOT/lib
ここには、アーカイブと SGML ライブラリの共有バージョンが含まれています。Sun WorkShop Visual が
Makefile
に生成した構築ルールでは、
libsgml.so
を使用します。しかし、好みに応じて
libsgml.a
とリンクすることもできます。
2.
$VISUROOT/src/sgml/hdrs/SGML.h
これは、パーサーエンジンを使用するために必要なインクルードファイルです。スマートコードの「カスタ
マイズ」ダイアログで「SGML/HTML パーサ」トグルをオンにした場合には、
Makefile
では API が参照されます。
3.
$VISUROOT/src/sgml/dtds
これは、HTML 3.2 DTD
および他の関連するデータファイルを含んでいるディレクトリです。パーサーはこれを見つける必要がある
ため、DTDDIR 環境変数に次の値を設定する必要があります。
$VISUROOT/src/sgml/dtds