![]() ![]() ![]() ![]() ![]() ![]() | ![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
第4章
「アクション」は、プログラミングステートメントに類似しており、パラメータの形式で入力を受け付け、特定のタスクを実行します。『Composerユーザガイド』のアクションに関する章を参照してください。
Telnetコンポーネントエディタ内では、XMLドキュメントを処理したり、非XMLデータソースと通信したりするための一連の命令がアクションモデルの一部として作成されます。アクションモデルは、ホストとXMLドキュメント間のすべてのデータマッピング、データ変換、データ転送、およびコンポーネントおよびサービス内のデータ転送を実行します。
アクションモデルは、連係するアクションのリストから構成されています。たとえば、請求書のデータをディスクから読み取り、データをホストの在庫データベースから取得し、一時XMLドキュメントに結果をマップして変換し、変換されたデータを出力XMLドキュメントにマップするアクションモデルを構築できます。
このようにアクションモデルは、複数のアクションから構成されています。たとえば、次のようなアクションが含まれます。
Telnet Connectには、Telnet環境に固有な2つのアクション、画面の確認およびバッファの送信が含まれています。
これらのアクションの目的は、(展開されたサービスで実行されている) Telnetコンポーネントが、ランタイム時にTelnetセッションで発生する端末/ホストの通信を複製できるようにすることです。次に、これらのアクションの使用法と意味をさらに詳しく説明します。
Telnetセッションでは、待ち時間が生じたり、画面データの受信順序が、ホストとアプリケーション間で定義された順序で一定でない可能性があるため、コンポーネントで現在の画面データを操作する前には、特定の状態の端末画面に依存できることが不可欠となります。画面の確認アクションでは、コンポーネントとホストとの「同期」を保つことができます。正しい画面が適切なときに正常に動作するように、画面の確認アクションをアクションモデルのさまざまな場所に手動で作成します。
新しい画面の確認アクションを作成するには、次のいずれかの操作を実行できます。
注記: 記録モードでは、ほとんどの場合ツールバーボタンを使用します。
アクションリスト内でマウスを右クリックして、コンテキストメニューから[新規アクション]、[画面の確認]の順に選択します(または、前の説明のように、メインメニューバーで[アクション]メニューを使用します)。[画面の確認]ダイアログボックスが表示されます。
実行許可(画面の準備状態)条件を指定する方法に応じて、3つのラジオボタン([カーソルの位置]、[プロンプト]、または[式])のいずれかをオンにします(デフォルトは、[カーソルの位置]です)。次の説明を参照してください。
画面の確認アクションのダイアログボックスの目的は、次の2つです。
これらの点は、次に詳しく説明します。Telnetコンポーネントをはじめて作成する前には、次の節をよくお読みになり、内容を十分理解するようにしてください。
重要な点として、アクションモデルのアクションは、次の条件を満たすまで実行されません。
コンポーネントでは、現在の画面の準備が完了したことを何らかの方法で「認識」する必要があります。カーソルの位置、プロンプト名、またはECMAScript式に基づいて準備条件を指定できます。
準備条件として端末のカーソル位置を指定できます。カーソルの「プロンプト位置」の行番号とカラム番号を入力するだけです(ダイアログボックスの[行]フィールドと[カラム]フィールドに表示される値は、常にカーソルの現在の位置が自動的にデフォルトになります。通常、これらの数字を手動で入力する必要はありません)。
現在のプロンプト位置は、端末のエミュレーションウィンドウのカーソル位置の直前にある文字列に基づいて指定できます。たとえば、「Choose one: (A, B, C, D)」というプロンプトがあるとします。この場合、実行条件プロンプトとして「Choose one: (A, B, C, D)」または「(A, B, C, D)」、あるいは単純に「)」を指定できます(プロンプト文字列として表示されるデフォルト値は、現在画面上でカーソルが置かれた行の内容になります。デフォルト文字列には、プロンプト行でカーソルの前にある最初から最後の文字(スペースがある場合はスペースを含む)まで、すべての文字が含まれます)。
プロンプトの位置またはプロンプトのテキストは、ランタイムでダイナミックに変更することができます。実行条件を柔軟に決定するために、画面の確認アクションのダイアログボックスで[式]ラジオボタンをオンにして、関連するテキストフィールドにECMAScript式を入力できます。ランタイム時に式で「true」が返されると画面の準備が完了しているとみなされますが、逆の場合はあてはまりません。
タイムアウトの値(ミリ秒単位)は、画面データを受信してから、このデータがダイアログボックス上部で指定された準備条件を満たすまで、コンポーネントが待機する最長時間を表します。指定のミリ秒数が経過するまでに使用可能な画面データが準備条件を満たさない場合は、例外がスローされます。
注記: Telnetセッションにおける待ち時間は、アプリケーション、接続、または画面によっても大幅に異なるため、タイムアウトの値は慎重に決定する必要があります。「安全な」タイムアウトの値を決定するためには、設計時およびサーバ上で慎重にコンポーネントをテストする必要があります。
デフォルトのタイムアウトの値は、記録モードを使用しているか、または単純に手動でアクションを作成しているかによって異なります。記録モードでは、デフォルトのタイムアウト値は、最後に操作を実行してから新しい画面をロードするまでに経過した実際の時間に基づいて計算された値になります(ダイアログボックスに表示された値は、この「検出されたロード時間」を2倍して、最も近い秒数に切り上げた数値です)。(記録モードの代わりに)手動で画面の確認アクションを作成している場合、デフォルト値は、1500ミリ秒です。
最小待機時間(ミリ秒単位)は、画面バッファの初期確認前にコンポーネントが待機しなければならない時間を示します。たとえば、最小待機時間を500と指定した場合、コンポーネントは500ミリ秒間待機してから(指定した条件に基づいて)画面の準備状態を確認します。実行条件を満たしている場合、その100ミリ秒後に画面が再確認されます。2回目の確認時にも条件を満たしている場合のみ、コンポーネントの実行が続行されます。そうでない場合は、タイムアウト値(前を参照)に達するまで、画面が100ミリ秒間隔で再確認されます。その時点で、画面が条件を満たしていない場合は、例外がスローされます。
注記: すべての画面の確認アクションでは、画面が最低2回確認されます。2回連続して確認の結果が適切にならなければ、実行条件は満たされません。
最小待機時間のデフォルト値は、50ミリ秒です。ただし、最小待機時間の値に関わらず、タイムアウト時に最後の画面確認が行われるため、最小待機時間がタイムアウト値より大きい場合でも、画面は1度確認されることになります。
バッファの送信アクションでは、コンポーネントの実行時に1度の送信でホストに送信される「キー入力されたデータ」(データが実際にキー入力によって取得されたか、ドラッグアンドドロップのマップによるものか、または式ビルダで作成したECMAScript式によるものかは問わない)をカプセル化します。バッファの送信アクションを実行すると、バッファされたデータが、適切にエスケープされたANSIバイトストリームの形式でホストに送信されます。
記録モードでは、画面の確認アクションの作成後に、単純に入力していきます。キー入力は、新しいバッファの送信アクションに自動的にキャプチャされます。
アクションモデルの任意の場所を右クリックして、コンテキストメニューを表示します。[新規アクション]、[バッファの送信]の順に選択します。
メニューコマンドを使用してバッファの送信アクションを
作成する
アクションモデルの任意の場所を右クリックして、コンテキストメニューから[新規アクション]、[バッファの送信]の順に選択します(または、前に説明されたように、[アクション]メニューを使用します)。[バッファの送信]ダイアログボックスが表示されます。
DOM要素のコンテンツをバッファにマップするには、[XPath]ラジオボタンをオンにしてから、プルダウンリストでDOMを選択して、テキスト領域に適切なXPathノード名を入力します(または、右側の[式]アイコンをクリックして、式ビルダを使用してノード名を作成します)。
ECMAScriptを使用してバッファのコンテンツを指定するには、[式]ラジオボタンをオンにしてから、[式ビルダ]ダイアログボックスを使用して、文字列を返すECMAScript式を作成します。
(文字列をテキストフィールドに入力することによって)手動でバッファのコンテンツを指定するには、最初に[キー入力の許可]チェックボックスをオンにしてから入力していきます。[式]ラジオボタンが自動的にオンになり、押したキーすべてがテキスト領域の引用符で囲まれた文字列中に入力されます。コントロールキー(矢印キー、ファンクションキーなど)は、適切なエスケープシーケンスに自動的に変換されます(次の説明を参照)。
「キー入力の許可」モードの場合、キー入力はすべてエスケープ処理された文字列リテラル値としてダイアログボックスにキャプチャされるため、<Backspace>、切り取り/貼り付けなどを使用した通常のテキスト編集を行うことはできません。たとえば、<Backspace>キーを押すと、直前の文字を削除する代わりに、「\u0008」という値が文字列バッファに追加されます。ただし、これが意図した操作でない場合もあります。
(切り取り、貼り付け、<Backspace>などを使用して)バッファのコンテンツを直接編集するには、最初に[キー入力の許可]チェックボックスをオフにします。その後、テキストを編集します。キーキャプチャモードに戻るには、[キー入力の許可]チェックボックスをオンにします。これで追加のキー入力は、すべてエスケープシーケンスに変換され、既存のテキストに追加されます。
状況によっては、エスケープの値を手動で入力したい場合があります。[キー入力の許可]チェックボックスをオフにして、該当する値を現在のテキスト文字列の任意の場所に入力すると、この操作を実行できます。コントロールキーのエスケープシーケンスが不明な場合は、テキスト領域の右側にある[式]アイコンをクリックして([式ビルダ]ダイアログボックスが表示されます)、[式ビルダ]ダイアログボックス上部の選択リストで適切なコントロールキーをダブルクリックして指定することができます。
特定のエスケープシーケンスの意味を見るには、目的のエスケープシーケンスを選択(ハイライト)し、選択項目の上にマウスを合わせます。次の図を参照してください。
エスケープシーケンスを変換した文字がマウス移動ヘルプボックスが表示されます。たとえば、前の図ではエスケープシーケンス「\u0008」を選択して、選択項目の上にマウスを合わせています。マウス移動ヘルプボックスによって、「\u0008」という組み合わせが、Telnetで<Backspace (BS)>または<Cntl>-<H>に等しくなることが示されます。
エスケープシーケンスのグループを選択すると、角括弧で囲まれた文字に相当する内容がすべて(マウス移動ヘルプボックスで)表示されます。たとえば、シーケンス「\u001b[A\u000a\u000d]を選択すると、マウス移動ヘルプには次のように表示されます。
< Arrow Up > < LF = CTRL+J > < CR = CTRL+M >
特殊(非印字)キー、およびそれに対応するANSIのリストは、付録Bの「Telnetの対応キーボード」に記載されています。
記録モードでアクションモデルを作成する場合、[画面の確認]ボタンをクリックして入力を開始すると、新しいバッファの送信アクションが自動的に作成されます。この結果、[画面の確認]ボタンをクリックしてから入力し(または、要素を入力DOMから画面上のプロンプト領域にドラッグする)、ホストから次の画面を受信するまで待機してから、[画面の確認]をクリックして入力(またはドラッグ)する操作を繰り返すだけでよいため、簡単にアクションモデルを作成できます。このように、画面の確認アクションとバッファの送信アクションのシーケンスは、非常に簡単で自然に作成できます。
バッファの送信アクションが自動的に作成されると、次のいずれかの操作を実行するまで、その後のキー入力はすべてバッファにキャプチャされます。
バッファの送信アクションを作成すると、リアルタイムでキャプチャされるキー入力は、英数字の値、または(非印字文字の場合は)エスケープされた形式でアクションモデルに表示されます。たとえば、「上矢印」キーは\u001b[a
に変換されます。\u001bはANSI制御コードの2バイトの16進Unicode値を表し、[aは上矢印キーの残りのASCIIエスケープシーケンスを表します。<Backspace>キーおよび<Delete>キーの入力もエスケープシーケンスとして表されます。そのため、バッファの送信アクションで入力ミスを訂正する場合は、アクションモデルでアクションをダブルクリックして([バッファの送信]ダイアログボックスが表示されます)、バッファ文字列を手動で編集します。
Telnet用Connectでは、Telnet固有のECMAScript変数およびオブジェクト拡張が多数提供されており、式ビルダの選択リストに表示されています。Telnet固有の項目は、[Telnet]というラベルの付いたノードの下に表示され、[ログイン]、[画面メソッド]、および[キー]という3つのチャイルドノードがあります。次の図を参照してください。
Telnet接続リソースには、[式ビルダ]ダイアログボックスからアクセスできる「USERID」および「PASSWORD」という2つのグローバル変数があります。これらのプロパティ(選択ツリーの[ログイン]ノードで使用できます)では、接続時にホストシステムで要求される可能性があるユーザIDおよびパスワードの値を指定します。これらの変数は端末画面にマップできるため、ユーザはマップアクションで明示的にユーザ情報およびパスワード情報を入力する必要がなくなります。
注記: また、XPathソースが$PASSWORDとして定義されたバッファの送信アクションを作成することもできます。
Telnetコンポーネントで、マップアクションまたは関数アクションから[式ビルダ]ウィンドウにアクセスした場合、ウィンドウ上部の選択リストには、Telnet固有の特別なECMAScript拡張が表示されます。このECMAScript拡張は、Screenオブジェクト、および仮想端末キーボードで「特殊キー」に対応する事前定義されたエスケープシーケンスのメソッドから構成されています。
マウスを特定の選択ツリー項目の上に移動すると、マウス移動ヘルプを使用できます(図を参照)。
さらに、ダイアログボックスの左下隅にある[ヘルプ]をクリックするとさらに詳細なオンラインヘルプを取得できます。
Screenオブジェクトでは、次の名前、署名、および使用規則を持つメソッドが提供されています。
このメソッドは、nRow, nColumnによって指定された画面の位置にある文字の「表示属性」値を返します。使用できる表示属性値の一覧は、付録Cに記載されています。 このメソッドの使用例は次のとおりです。
if (Screen.getAttribute( 5, 20 ) == 1) // if character at 5, 20 is bold
// do something
このメソッドは、Telnetエミュレータ画面(ネイティブ環境ペイン)内でのカーソルの現在のカラム位置を返します。カラム位置は、ゼロではなく1を基準とします。つまり、24x80モードでは、このメソッドにより1から80までの値が返されます。
このメソッドは、Telnetエミュレータ画面(ネイティブ環境ペイン)内でのカーソルの現在の行位置を返します。行位置は、ゼロではなく1を基準とします。つまり、24x80モードでは、このメソッドにより1から24までの値が返されます。
このメソッドは、現在の画面本来のカラム幅のサイズを返します(ホストプログラムの実行中にモードが変更される可能性があるため、この値は画面によって変わる場合があります。コンポーネントを使用している間、この値が常に同じであるとは限りません)。プログラムが24x80モードの場合、このメソッドにより80が返されます。本来のサイズに関係なく、現在の画面で行15にあるすべてのコンテンツを取得するには、次のように入力できます。
var myRow = Screen.getTextAt( 15, 1, Screen.getMaxColumn() );
getPrompt()
メソッドは、カラムの行にあるカラム1からgetCursorColumn()
までのすべての文字(ただしgetCursorColumn()
は含まない)を表す文字列、つまり行頭からカーソル位置にあるすべての文字を返します(これは、[画面の確認]ダイアログボックスに表示されるデフォルトのプロンプト文字列と同じです)。例:
var thePrompt = Screen.getPrompt();
if (thePrompt().toLowerCase().indexOf("password") != -1)
Screen.setText(PASSWORD);
このメソッドは、現在の画面本来の縦のサイズを返します(ホストプログラムの実行中にモードが変更される可能性があるため、この値は画面によって変わる場合があります。コンポーネントを使用している間、この値が常に同じであるとは限りません)。プログラムが24x80モードの場合、このメソッドにより24が返されます。本来のサイズに関係なく画面の行をすべてループするには、次のように入力します。
for (var i = 1; i <= Screen.getMaxRow(); i++)
{
var myRow = Screen.getTextAt( i, 1, Screen.getMaxColumn() );
// do something with myRow
}
このメソッドは、nOffset
によって指定されたバイトオフセットで、Screenオブジェクトで生じる文字(長さnLength
)の文字列を返します。オフセットは、ゼロではなく、1を基準とします。そのため、ECMAScript文字列として24 x 80画面を「すべて」取得するには、次のようにします。
var wholeScreen = Screen.getText( 1, 24 * 80 );
画面バッファの限度を超えて文字データ取得しようとすると、例外が発生します。たとえば、次のような呼び出しは実行できません。
var wholeScreen = Screen.getText( 1, 1 + 24 * 80 ); // ERROR!
このメソッドは、現在の画面で指定した行とカラムの位置から始まる文字(長さnLength
)のシーケンスを表すECMAScript文字列を返します。nRow
およびnColumn
は、ゼロではなく1を基準とします。これらのパラメータの値がゼロの場合、いずれも例外が発生します。
24x80画面の行20を取得するには、次のようにします。
var myRow = Screen.getTextAt( 20, 1, 80 );
getTextAt()
メソッドは、後の「連続するデータの選択」で説明しているように作成された画面選択に関するマップョンのドラッグアンドドロップで内部的に使用されます。
このメソッドは、下位文字列(1行につき1つ)で構成された単一の文字列を返します。下位文字列は、パラメータとして指定された左上および右下の行/カラムの座標で定義された境界ボックス内にあるすべての文字から構成されます。たとえば、24x80モードでは、次のように実行すると、画面を4等分したうちの左上の部分を取得できます。
var topLeftQuadrant = Screen.getTextFromRectangle(1,1,12,40);
getTextFromRectangle()
メソッドは、<Shift>を使用した選択方法によって作成された、長方形画面の選択部分に関するドラッグアンドドロップを使用したマップアクションで、内部的に使用されます(次の「長方形領域の選択」を参照)。
このメソッドによって返された文字列には、下位文字列間に改行区切り記号(\u000a)が含まれます。つまり、各行でデータの最後には改行が含まれます。そのため、返された文字列の全体的な長さは、行数とカラム数を乗算して、行数を加算した値となります。たとえば、Screen.getTextFromRectangle(1,1,4,4).length
は、20になります。
setText()
メソッドでは、明示的にバッファの送信アクションを作成せずに、プログラムによって画面(および、ホストアプリケーション)にデータを送信できます。例:
var myPhone = "(203) 225-1800";
if (Screen.getPrompt().indexOf("Phone") != -1)
Screen.setText( myPhone + "\r" ); // send string + CR
[式ビルダ]ダイアログボックスにあるTelnet固有の選択ツリーの[キー]ノードには、[一般キー]、[NumPadキー]、[コントロールキー]、および[その他のキー]というラベルが付いたチャイルドノードがあります。これらのカテゴリで選択リスト項目をダブルクリックすると、ホストに送信しようとしている任意の非印字文字に対して、ANSIエスケープシーケンスを自動生成できます。選択リスト項目の詳細については、付録Bを参照してください。
設計時に、端末画面の外にデータをドラッグする目的で端末画面(ネイティブ環境ペイン内)でデータを選択するには、主に2つの方法があります。1つの方法では、ある画面バッファオフセットから別の画面バッファオフセットに連続するストリームでテキストを選択し、もう1つの方法では、任意の画面上で境界ボックスまたは境界部分でテキストを選択します。
<Shift>キーを押さずに複数行でデータをドラッグすると、次の図のように最初の画面オフセット(マウスを合わせた点)から最後の画面オフセット(マウスを離した点)までの文字列すべてが選択されます。(選択されたテキストは「黒くハイライト」されます。上から行の一部、3つの完全な行、行の一部という順に選択されます)。
コンポーネントエディタウィンドウのステータス行(左下)で示すように、前の例での選択内容は、実際に行5、カラム26で開始し、行9、カラム35で終了します。この選択内容をネイティブ環境ペインからDOM内にドラッグすると、次のようにマップアクションが生成されます。
getTextAt()
メソッドが使用されていることに注意してください。つまり、キャプチャされた画面文字によって、1つの文字列が形成され、Output/Inquiry/Response/Infoにマップされます。改行または他の特殊文字は、文字列に挿入されません(黒色で表示された画面領域は、文字列内の単なるスペースを表します)。
場合によっては、前で説明した選択は、使用したくない場合があります。特定の状況では、画面データは独自の境界を持ったゾーンに分類できます。たとえば、前の画面では、画面の上から3分の2の位置に、本が利用できるかどうかを示しているボックスがあります。画面上のこの長方形で囲まれた部分のデータのみを(画面外にドラッグする目的で)キャプチャできます。それには、最初に<Shift>キーを押してから、選択する画面部分でマウスを横にドラッグします。選択した領域がハイライトされ、適切な行/カラムの開始ポイントおよび終了ポイントが、コンポーネントエディタのウィンドウのステータス行に表示されます(次を参照)。
この例では、長方形内で選択された領域をネイティブ環境ペインからDOM内にドラッグすると、その結果マップアクションで、46ページで説明したgetTextFromRectangle()
メソッドが使用されます。アクションは、次のようになります。
getTextFromRectangle()
によって返された文字列は、長方形の右端でラップされるため、このメソッドは、getTextAt()
とは異なる方法で動作します。新しい行は、getTextFromRectangle()
のAPIで説明されているように、改行ポイントに挿入されます(前を参照)。
説明を目的として、次の例ではCONSULSプログラムが使用されています。このTelnetプログラムは、コネチカット州立大学の図書館システムによってオンラインで提供され、このプログラムのユーザは、タイトル、著者、および他の条件から本や定期刊行物を検索することができます。
Telnetコンポーネントは、大部分のアクションモデルが自動的に作成される点で、他のコンポーネントとは異なります。これは、有効なTelnetセッションの一部として、ネイティブ環境ペインでホストと通信する際に起こります。Composerでは、アクションモデルで自動生成された一連のアクションとして通信を記録します。通常、他のexteNd Composerコンポーネント(JDBCコンポーネントなど)では、アクションモデルでアクションを手動で作成してから、マップ、ログ、変換、通信、およびコンポーネントやサービスで必要とされるその他のタスクを実行する必要があります。これとは逆に、Telnetコンポーネントを作成する場合は、ホストへの要求およびホストからの応答を「記録」し、これが最終的にアクションモデルのアクションとして処理されます。さらに、他のコンポーネントと同様に、アクションモデルに標準のアクション(マップ、ログ、関数など)を追加できます。
注記: Telnetコンポーネントを正常に作成するためには、Telnetコマンド、およびXML統合プロジェクトで使用するアプリケーションの仕様を理解しておく必要があります。
Telnetコンポーネントを作成する際に必要な共通タスクは、次の例のとおりです。
次の例では、まず本のタイトルおよび著者を含む入力XMLドキュメントから操作を開始します。Webサービスの目的は、CONSULS Telnetアプリケーションを使用して、著者のオンライン検索を行い、指定したタイトルの本がライブラリシステムに存在するかどうかを確認することです。存在する場合、出力DOMでISBN (International Standard Book Number)コードを取得します。目的の本が見つかったかどうかに関わらず、出力DOMに適切なステータスメッセージを挿入します。
23ページの「新しいTelnetコンポーネントを作成する」の指示に従って、Telnetコンポーネントを作成します。
コンポーネントを作成すると、Telnetコンポーネントエディタウィンドウが開き、ネイティブ環境ペインの中央に「Telnet Terminal Emulation」という語句が表示され、ホストとの接続が確立されていないことが示されます。
[記録]ボタンをクリックします。自動的にコンポーネントの接続リソースで選択したホストに接続されます。ネイティブ環境ペインに入力画面が表示されます(次を参照)。
注記: この後の例では、州立大学図書館システムのオンライン書籍検索サービスからの画面を示します。同様のTelnetサービスがオンラインで数多く利用できますので、お好みのWeb検索エンジンを使用して、サービスのIPアドレスを取得してください。
ツールバーで[画面の確認アクションの作成]ボタンをクリックします。アクションリストに新しい画面の確認アクションが表示されます。「現在のカーソル位置」に基づいてデフォルトの実行条件(この画面上では常に21,56と想定していますが、このコンポーネントを実行するたびにこの数字は変わる可能性があります)が表示されます。CONSULSプログラムの応答時間は比較的短いため、この画面の確認アクションに対してデフォルトで1500ミリ秒となるタイムアウトを一時的に受け入れます(その場合でも、このタイムアウト値が安全であることを検証するため、コンポーネントを慎重にテストする必要があります)。
Telnet環境ペインの入力画面に文字A(著者: Author)を入力します。コンポーネントのアクションリストに新しいバッファの送信アクションが自動的に表示されます。入力した「A」は、すでにアクション内に含まれています。
注記: ほとんどの場合、Telnetコマンドでは大文字と小文字が区別され、通常はすべて大文字で入力する必要があります。
このホストアプリケーションのこの部分では、(<Enter>または<Return>を押さずに)文字を1つ入力するだけで、新しい画面が表示されます。つまり、入力した文字はすぐにホストで処理されます。これは、Telnetの一般的な慣用法です。<Return>または<Enter>を押さなくても新しい画面を表示できることがあります。
バッファの送信アクションを終了して、次に新しい画面を操作するため、この時点でツールバーで[画面の確認]ボタンをクリックして、コンポーネントが次のアクションと現在の画面を「同期」できるようにする必要があります。[画面の確認アクションの作成]ボタンをクリックします。アクションリストに新しい画面の確認アクションが表示されます。
注記: この時点で、(最初に新しい画面の確認アクションを作成しないで)次のコマンドを単純に入力していく場合は、コマンドはアクティブなバッファの送信アクションに追加されます。本質的には、「先読み入力」バッファを作成することになります。ランタイム時には、(連結された2セットの画面コマンドを含む)バッファがすべて一度に送信されます。先読み入力は、この特定のプログラムでは適切に動作しますが、この方法は他の実際のTelnetプログラムでは正常に動作しない場合があります。そのため、バッファの送信アクションを意図的にオーバーロードする際には注意が必要です。「最良の方法」は、セッション中に表示される新しい画面すべてに対して、新しい画面の確認アクションを作成することです。
[BOOKINQUIRY]、[AUTHOR]、[LASTNAME]の順に展開されたノードを、入力DOMからネイティブ環境ペインのカーソル位置にドラッグします。「Clancy」(「」は含まない)という文字がプロンプトゾーンに表示され、新しいバッファの送信アクションがアクションモデルに自動的に表示されます。
注記: このTelnetアプリケーションでは、姓、名の順序(姓と名の間にスペースあり)で著者名を指定するよう想定しています。そのため、最初に[LASTNAME]の要素をドラッグしました。
キーボードのスペースバーを押します。ネイティブ環境ペインで、「Clancy」にスペース文字が追加されます。また、スペース文字のみを含む新しいバッファの送信アクションが作成されます。
[BOOKINQUIRY]、[AUTHOR]、[FIRSTNAME]の順に展開されたノードの要素を、入力DOMからネイティブ環境ペインのカーソル位置にドラッグします。「Tom」(「」なし)が、プロンプトゾーンで「Clancy」の後に表示され、新しいバッファの送信アクションがアクションモデルに自動的に表示されます。
端末画面は<Return>または<Enter>キーが入力されるまで待機状態であるため、画面は変わりません(ホストはユーザの入力に反応していません)。<Return>または<Enter>を押して、クエリ文字列(著者名)が完了したことをホストに通知します。すると、\u000aを含む新しいバッファの送信アクションが表示され、クエリ結果を反映してネイティブ環境ペインが更新されます。
ツールバーで[画面の確認アクションの作成]ボタンをクリックします。新しい画面の確認アクションが表示され、行24、カラム38のカーソル位置に基づくデフォルトの実行条件が表示されます(行24は、一番下の行で、カラム38は、80カラムから成る画面の約半分の位置にあるカラムです。前のスクリーンショットを参照)。この場合、デフォルトの画面の確認アクションを変更する必要はありません。
ネイティブ環境ペインで、マウスをクリックしてからドラッグして、行2、カラム2からカラム18までの端末画面のテキストを選択します。
注記: テキストをクリックしてドラッグすると、選択した領域での画面上の行/カラムの座標が、コンポーネントエディタウィンドウのステータス行(左下隅)に表示されます。
マウスのボタンから指を放して、選択したテキストの上にマウスを合わせます。カーソルが指の形で表示されます。選択内容をクリックして、出力DOMの[InquiryResponse/Status]ノードにドラッグします。選択したテキストは、DOM内の目的の場所に挿入され、アクションモデルに新しいマップアクションが自動的に作成されます。
CONSULSの例(前を参照)での目的は、目的の本のISBN (International Standard Book Number)情報を検索して、出力DOMにマップすることです。そのため、CONSULSアプリケーションで著者の検索結果が表示されると、画面をスキャンして該当する本のタイトルを検索する必要があります。タイトルが存在する場合、次のアクションとして、対応する行数を送信し、CONSULSで本の詳細情報(ISBNを含む)を示す「新しい」画面が表示されるようにします。
単純に端末エミュレータ画面(前の図を参照)では、Tom Clancyの『Debt of Honor』が検索結果画面の行番号3として表示されていることを確認できます。ただし、これは、この特定の検索に対してのみ当てはまります。異なる著者/タイトルの組み合わせを検索すると、異なる行の位置でヒットが生じる場合があります(または、Tom Clancyがさらに多くの本を出版した場合、『Debt of Honor』のリストでの位置は変更される場合があります)。ランタイム時に本の行の位置を判断するには、端末画面の行4から行11を繰り返して、入力DOMで[BOOKINQUIRY]の[TITLE]ノードに保存されている文字列を検索する必要があります。前の例を踏まえて、この操作を行う方法は次の例のとおりです。
アクションモデルの一番下に、新しいRepeat Whileアクションを追加します(マウスを右クリックし、[新規アクション]、[繰り返し]、[Repeat While]の順に選択します)。 [Repeat While]ダイアログボックスが表示されます。
[While]テキスト入力ボックスで、このループに適用するループの終了条件を表す式を入力します。この場合、インデックス変数rowIndex
の確認が条件です。全部で画面データの8行をチェックします。
画面から単一の値(本1冊)を取得しているだけなので、ダイアログボックスでオプションの[ターゲット]部分を記入する必要はありません。そのため、単純に[OK]をクリックします。新しいRepeat Whileアクションがコンポーネントのアクションモデルに追加されます。
この例では、指定の行内で特定の文字列を検索しています。文字列が見つかった場合、複数のアクションを実行してからループを抜けます。決定アクション内で、行の解析および文字列の検索を実行します。マウスを右クリックして、コンテキストメニューから[新規アクション]>[決定]を選択して、決定アクションを作成します。[決定]ダイアログボックスが表示されます。
var myRow = Screen.getTextAt(rowIndex+4, 1, 80).toLowerCase();
var bookTitle = String(Input.XPath("BOOKINQUIRY/TITLE")).toLowerCase();
myRow.indexOf( bookTitle ) != -1
1番目の行では、ScreenオブジェクトのgetTextAt()
メソッド(46ページを参照)を使用して、rowIndex + 4
で80文字のデータ(つまり、24x80の端末画面での完全な1行)を取得します。画面データの検索は、行4で始まり、行11まで続く必要があるため、インデックス変数にオフセットを追加します(インデックス変数自体は、0から7までの値を持ちます。rowIndex
が8になると、ループが終了します)。
前のコードで2番目の行は、単純に小文字の文字列として入力DOMから本のタイトルを取得します (検索で大文字と小文字が区別されないようにするため、クエリ文字列およびターゲットオブジェクト文字列のいずれも、強制的に小文字にします)。
コードの最後の行は、実際の「条件チェック」です。これは、引数文字列がメソッドを呼び出す文字列の下位文字列でない場合に、-1を返すコアのECMAScript文字列メソッドindexOf()
に依存します。
決定アクションのTRUEブランチで、新しい「バッファの送信」アクションを作成します(マウスを右クリックしてから、コンテキストメニューで[新規アクション]>[バッファの送信]の順に選択します)。[バッファの送信]ダイアログボックスが表示されます。
[式]ラジオボタンをオンにしてから、テキスト編集領域にECMAScript式を入力します。ここでは、次のように入力します。
var item = Screen.getTextAt( rowIndex + 4, 1,10);
var regex = new RegExp("\\d+");
1番目の行は、getTextAt()
メソッドを使用して、「ヒット」の行でデータの最初の10文字を取得します。この文字列内では、本のCONSULS行数(例: 3)を表す数字の最初の下位文字列を取得する必要があります。この下位文字列を抽出する1つの方法として、ECMAScript文字列メソッドmatch()
を使用して、正規表現オブジェクトを引数として実行します。成功すると、このメソッドは、0番目の項目が一致したテキストとなるアレイを返します。正規表現は、円記号、d、プラス記号の順で構成され、「1行に1桁または複数桁の文字」を意味します。
注記: RegExpコンストラクタは、文字列引数をとり、「リテラル」円記号として表示される円記号は、「円記号でエスケープされる必要があります」。
これらのECMAScript行の最終的な結果は、ターゲット行(つまり、「3」)で本のタイトルの前にくる数字は、バッファの送信アクションを介してホストアプリケーションに送信されます。 数字「3」には改行を付ける必要はありません。ホストアプリケーションは、この数字を受信すると、ただちに指定された本に関する詳細情報を示した新しい画面を送信し直します(次を参照)。
マウスを右クリックして、コンテキストメニューから[新規アクション]>[画面の確認]の順に選択して、新しい画面の確認アクションを作成します。[画面の確認]ダイアログボックスが表示されます。
[式]ラジオボタンをオンにしてから、テキスト編集領域に「true」と入力します。[最小待機時間]の値を、(この場合は)経験上適切である100に設定します。
注記: 「true」および100の組み合わせは、100ミリ秒以内に送信された任意の画面データを「自動的に受け入れる」ことを意味します。
新しい関数アクションを作成します(マウスを右クリックします。そして、[新規アクション]>[関数]の順に選択します)。このアクションで、ページ上の最初のISBN番号(存在する場合)を取得し、ECMAScriptグローバル変数に保存します。
this.isbn = "Not found"; // set up global
var screen = Screen.getText( 1, 24 * 80 ); // fetch whole screen
if (screen.indexOf(\qISBN\q) != -1) // 「ISBN」なら取得する
this.isbn = lTrim( screen.split(\qISBN\q)[1] ).split(\q \q)[0];
前の式で、最初の行は、単純にECMAScriptグローバル変数を宣言して初期化します(ECMAScriptグローバル変数は、成功すると、有効なISBN値で上書きされます)。
コードの2番目の行は、画面バッファ全体を文字列として取得し、ローカル変数text
内に配置します(ここでは、24x80モードであると想定します)。
3番目の行は、画面バッファをチェックして、画面バッファ内に「ISBN」が生じるかどうか確認します。生じた場合、「ISBN」を区切り記号として使用して、バッファを下位文字列のアレイに分割します。インデックス1のアレイメンバーには、ISBN数字が含まれ、画面の一部の情報(行頭にスペースが含まれる場合もあります)が含まれます。スペースが区切り文字である場合、splitメソッドをもう一度使用して、文字列を下位文字列のアレイに分割し、さらにカスタムECMAScript関数lTrim()
を使用して、行頭のスペースを削除します。この最後のアレイで0番目の項目が、対象となるISBN文字列です。次の一連の図を参照してください。
該当する情報が見つかった場合、品目全体を繰り返す必要はありません。そのため、「ブレークアクション」を作成して、ループを抜けます(マウスを右クリックして[新規アクション]>[ブレーク]の順に選択します)。
this.isbn
を出力DOMの[InquiryResponse/ISBN]ノードにマップする「マップアクション」を作成します。
完全なアクションモデルは、次のとおりです。
以前に記録したアクションモデルを編集する必要が生じる場合があります。他のコンポーネントを使用する場合とは異なり、Telnetコンポーネントの編集には、特別な注意が必要です。Telnetコンポーネントを実行すると、コンポーネントが適切に動作するために、特定の画面およびデータが一定の時間帯に表示されるようなアクションのシーケンスが繰り返されます。そのため、コンポーネントを編集する際には、アクションモデルのシーケンスが以前に記録したホストプログラムの実行シーケンスと矛盾しないよう注意する必要があります。
アクションモデルで、[切り取り]、[コピー]、または[貼り付け]、あるいはこれらすべてを使用してアクションを削除、移動、または複製する際には、細心の注意を払います。「記録」セッション中に自動的に作成されるアクションでは、編集処理で見落としやすい従属データが頻繁に作成されます。
ドラッグアンドドロップを使用して、アクションモデルに新しいマップアクションを追加する必要がある場合は、アクションペインのツールバーで[アニメーションの開始]ボタンをクリックし、アクションモデルの目的の行に進んでから、アニメーションを一時停止して記録モードをオンにします。この時点では、安全に画面の内外にドラッグできます。この手順に従うと、アクションモデルでホストとの同期がずれたり、以前にマップしたDOMデータと矛盾が生じたりするのを防ぐことができます。
次の手順では、以前に記録したセッションで既存のアクションを変更する方法を説明します。
以前に記録したアクションモデルで、既存のアクションを変更する
編集するアクションモデルが含まれるコンポーネントを開きます。すると、Telnetコンポーネントエディタウィンドウにコンポーネントが表示されます。
[ブレークポイントの切り替え]ボタンをクリックします(または、<F2>を押します)。選択したアクションが赤色になります。
[アニメーションの開始]ボタンをクリックします。(アクションペインのツールバーで)アニメーションツールが有効になります。
[ブレークポイント/終了までのステップ]ボタンをクリックします。アクションモデルで、アクションモデルの最初から前の手順3で設定したブレークポイントまでのアクションがすべて実行されます。
次の手順では、以前に記録したセッションで新しいアクションを追加する方法を説明します。
アクションを追加するアクションモデルを含むコンポーネントを開きます。すると、Telnetコンポーネントエディタウィンドウにコンポーネントが表示されます。
[ブレークポイントの切り替え]ボタンをクリックします(または、<F2>を押します)。選択したアクションが赤色になります。
[アニメーション の開始]ボタンをクリックします。(アクションペインのツールバーで)アニメーションツールが有効になります。
[ブレークポイント/終了までのステップ]ボタンをクリックします。アクションモデルで、アクションモデルの最初から前の手順3で設定したブレークポイントまでのアクションがすべて実行されます。
Composerのドラッグアンドドロップ機能を使用して、画面と動作する新しいマップアクションを追加します。選択した行のすぐ下に新しいアクションが追加されます。
別名であるループにマップアクションを追加している場合、次の操作を実行します。
エイリアスアクションを以前に記録したアクションモデルに追加する
[アクション]メニューから、[新規アクション]、[マップ]の順に選択します。[マップ]ダイアログボックスが表示されます。
次の手順では、以前に記録したセッションでアクションを削除する方法を説明します。
削除するアクションの行を選択して、マウスを右クリックし、メニューから[削除]を選択します。行を選択して、キーボードの<Delete>ボタンを押すこともできます。
Composerには、コンポーネントを簡単にテストできるアニメーションツールが含まれています。Telnetコンポーネントエディタのツールバーには、[実行]ボタンがあり、このボタンを使用するとアクションモデル全体を実行して、コンポーネントが意図したとおりに動作するか検証できます。新規に作成したTelnetコンポーネントをテストして、すべての画面の確認アクションでのタイムアウト値が適切であり、バッファの送信アクションおよび他のアクションが意図したように動作するか確認することが大切です。
[実行]ボタンを選択します。アクションモデルのアクションが実行されます。コンポーネントが正常に実行された場合、次のようなメッセージが表示されます。
コンポーネントを実行した後は、DOMのコンテンツをもう一度確認し、意図したようにすべてのデータが適切にマップされたか確認する必要があります。すべてのデータ要素を表示するには、[表示]メニューで[ XMLドキュメントの展開]を選択します。これにより、DOMツリーのペアレント、チャイルド、データ要素などがすべて展開され、コンポーネントの実行結果を簡単に確認できます。
アクションモデルには、1つまたは複数のブレークポイントを設定して、アクションモデルの特定のセクションをテストできるアニメーションツールがあります。これらのツールを使用すると、適切に動作するアクションをすべて実行して、問題の生じたアクションで停止してから、問題のアクションを1つずつトラブルシューティングすることができます。
アニメーションツール機能の簡単な例は、次のとおりです。すべてのアニメーションツールおよびその機能の詳細については、『exteNd Composerユーザガイド』を参照してください。
アニメーションツールを使用してTelnetコンポーネントを実行する
1. Telnetコンポーネントを開きます。すると、Telnetコンポーネントエディタウィンドウにコンポーネントが表示されます。
注記: アニメーションモードと記録モードは、コンポーネントで「互いに排他的なモード」です。アニメーション中に記録を行うためには、アニメーションを一時停止または停止してから、記録モードをオンにする必要があります。
アクションモデルのツールバーで[アニメーションの開始]ボタンをクリックするか、キーボードの<F5>キーを押します。ツールバーのツールがすべてアクティブになり、ホストとの接続が確立され、ネイティブ環境ペインがアクティブになります。
[ステップイン]ボタンをもう一度クリックします。画面の確認アクション(前を参照)が実行され、次のアクションが選択されます。
希望に応じて他のボタン([ステップオーバー]、[ブレークポイントまで実行]、[一時停止]など)をクリックして、コンポーネントの実行を制御します。アクションの行でマウスをクリックして、<F2>を押すか、[ブレークポイントの設定]ボタンを使用すると、ブレークポイントを実行中いつでも設定できます。
次のヒントは、信頼性の高いTelnetコンポーネントを作成する上で役に立ちます。
画面の確認アクションでは、絶対カーソル位置が指定の画面に対して常に一定であることが明らかな場合に限り、(カーソル位置に基づく)デフォルトの実行条件を受け入れます。多くの場合、カスタム式を記述する方がより安全です。
記録中にプロンプトに基づく画面の確認アクションを作成する迅速で、正確な方法は、カーソル直前にある(カーソル位置まで、カーソル位置は含まない)該当する文字をハイライト(選択)してから、マウスを右クリックして[画面の確認]を選択することです。これにより、ハイライトしたプロンプトに基づき、画面の確認アクションが自動的に作成されます。
[プロンプト]([画面の確認]ダイアログボックス内)でカスタムプロンプト文字列を入力する場合は、プロンプト文字列内に表示される引用符を忘れずにエスケープしてください。
最小待機時間の設定を使用して、指定の時間待機する以外には何も実行されない画面の確認は、使用しないようにします。この方法は、適切に動作するように思われますが、重大なパフォーマンスのボトルネックが発生する場合があります。
画面の確認アクションで使用するデフォルトのタイムアウト値は、設計セッション中に実際の応答時間から計算されます。この結果、いくらかの影響が生じます。まず、デフォルトのタイムアウト値は、ロードに対応したアプリケーションに対して大きくしなければならない場合があります。次に、画面の確認アクションを削除すると、それ以降の実行で同期がタイムアウトになる可能性があります。慎重にテストを行うと、この種の問題が明らかになります。
再表示している際に画面の途中は同じでも、最初と最後の行が変更された場合など、不完全な実行条件が有効になると、2つの画面の確認アクションを作成してから、それらを式に基づく1つのアクションに結合する必要があります。
画面の確認アクションおよびバッファの送信アクションに加えて、すべての標準のComposerアクションも使用できます。Composerの基本的なアクションの一覧は、『Composerユーザガイド』の第7章に記載されています。第8章には、さらに高度なアクションの一覧が記載されています。
Telnetコンポーネントをテストする際には、画面の確認アクションまたはバッファの送信アクション、あるいはその両方に関するエラーが表示されることがあります。その結果、次のようなダイアログボックスが表示されます。
この節では、考えられるエラーの条件およびそれに対処する方法について説明します。
実行時に発生するエラーの大部分は、画面の確認アクションに関連します。次に説明する画面の確認エラーは、すべてタイムアウトエラーであることを認識しておくことが大切です。次に説明するエラーのいずれかが発生した場合、画面の確認設定ダイアログボックスで指定した実行条件が「タイムアウト時間内に満たされなかった」ことを意味します。そのため、ホストの応答の遅れが実際の問題であるかどうか最初に判断する必要があります(その場合の解決策は、問題の画面の確認アクションに対するタイムアウト値を大きくすることです)。タイムアウト値を大きくしてもエラーが引き続き発生する場合は、エラーの原因が画面の確認アクションでの不正または不適切な実行条件によるものであると考えられます。
次に、一般的なエラーメッセージおよびその意味について説明します。
このエラーメッセージは、タイムアウト時間が切れる際にカーソルが予期される位置になかったため、画面の確認が失敗したことを意味します。予期しない何らかの方法でホストアプリケーションが変更されたか、プロンプト行がダイナミックに変更された可能性があります。また、ホストの負荷が重い、または接続不良といった理由から、画面の確認アクションが単純に「タイムアウトになった」可能性もあります(前の説明を参照)。指定の画面の確認アクションに対して、タイムアウト値を大きくします。それでも解決しない場合(または、問題が不適切な実行条件の選択に関すると考えられる場合)は、固定したカーソルの座標以外の条件に基づいて、画面の確認の実行条件を再度記述するようにします。たとえば、プロンプト文字列を指定したり、式を使用して何らかの方法で画面のコンテンツを検証します。
このエラーメッセージは、タイムアウト時間が切れる前にプロンプトが指定の(予期される)プロンプト文字列と同じでなかったため、画面の確認が失敗したことを意味します。プロンプト行が、予期しない何らかの方法でダイナミックに変更されている可能性があります。または、負荷が重いあるいは他の要因によって、単にホストの応答時間が予想外に長くなった可能性もあります(前の説明を参照)。ホストの待ち時間が問題であると考えられる場合、画面の確認アクションのタイムアウト値を大きくします。それ以外の場合は、画面の確認実行条件を再度記述して、ハードコード化されたプロンプト値以外の条件を指定します。たとえば、何らかの方法でプロンプトを検証する式を指定します。
このエラーメッセージは、画面の確認実行条件がECMAScript式に基づき、実行時に式が「false」をを返した場合に発生します。ここでも、この種のエラーは、単純にホストの応答の遅れ(タイムアウト)によって、トリガされることを認識しておくことが大切です。ホストの応答が遅い場合、ECMAScript式が「タイムアウトの時点で画面バッファに存在する内容すべて」によって評価されます。データが受信されていない(またはデータが不十分である)場合、式が評価され、結果として「false」が返されます。
この種の問題を解決するためには、この画面の確認アクションのタイムアウト値を大きくするか(ホストの待ち時間が問題と考えられる場合)、ECMAScript式でロジックを変更します。
文字列「\u001b[?1;2c](または、これに類似した文字列)を含むアクションモデル上部に、自動生成されたバッファの送信アクションが表示された場合、Telnet接続リソースの設定ダイアログボックスの[端末タイプ]フィールドで端末タイプが指定されていない(または認識できない端末タイプを指定した)ことを意味します。
通常、バッファの送信エラーはほとんど発生しません。ただし、バッファの送信には複数画面に渡るコマンド(「先読み入力」バッファと呼ばれる)が含まれることに注意してください。そのようなアクションは、簡単に誤って作成されます。オーバーロードしたバッファの送信を使用したアクションモデルは、アニメーション時にアクションを処理する際には正常に動作することがありますが、コンポーネント全体の実行時には、画面での同期問題のため、失敗する場合があります。ここで問題を回避する方法は、バッファの送信アクションすべてに対して、常に対応する画面の確認アクションがあることを確認することです。
第6章で詳しく説明した接続プールが使用中で、不正なユーザIDまたはパスワードを使用してログオンしようとした場合、接続インスタンスは使用できなくなり、プールのメンバーは次の接続要求でスキップされます。「プール<プール名>のログオン接続がユーザID<ユーザID>に対して破棄されました」というエラーメッセージがサーバログに送信されます。運用前のテスト中またはパフォーマンスの問題が生じた場合、あるいはその両方で、この種のメッセージを確認する必要があります。
アクションモデルが大きい(数十、数百の画面の確認アクションおよびバッファの送信アクションを含む)場合、単純にエラーの原因となるアクションを検索することが困難になります。問題のアクションを検索する1つの方法は、次のとおりです。
エラーのダイアログボックスで、「Expected (予期した)」に続くテキストを選択して、コピーします(必要な場合[詳細]ボタンをクリックして、エラーの説明をすべて表示します。カーソルの座標などの、該当するテキストを選択します。<Ctrl>キーを押しながら<C>キーを押して、コピーします)。
同一の実行条件に基づく複数の画面の確認アクションがある場合、前の方法が必ずしも役に立つとは限りません。その場合、アクションモデルの中間点にブレークポイントを設定し、コンポーネントを実行します。エラーが発生しない場合は、元のブレークポイントとアクションリストの最後との間にブレークポイントを移動します(エラーが発生する場合は、アクションリストの最上部から下に4分の1の場所にブレークポイントを設定します)。コンポーネントをもう一度実行します。ブレークポイントの場所の変更を繰り返し、毎回最後のブレークポイントとアクションリストの最上部または最下部の距離が「半分」となる場所に適宜設定します。このようにすると、問題となるアクションの場所を迅速に絞り込むことができます。(この「バイナリ検索」方法を使用すると、128個のアクションを含むアクションモデルをわずか7回でデバッグできます)。
Copyright © 2004 Novell, Inc. All rights reserved. Copyright © 1997, 1998, 1999, 2000, 2001, 2002, 2003 SilverStream Software, LLC. All rights reserved. more ...