(57)【要約】  既存のエンタープライズコンポーネントと一体化される簡単なウェブ状のプログラミングモデルと共に、精巧な移動ソルーションを開発し、配備しそしてマネージするためのフレームワークを提供する。移動アプリケーションは、データモデル定義と、ユーザインターフェイステンプレートと、アクションを定義するスクリプトを含むクライアント側コントローラと、そしてサーバー側では、データモデルとエンタープライズの間をいかに仲裁するか記述するコンジットの集合とで構成することができる。一実施形態では、時々接続されるアプリケーションサーバーは、移動アプリケーションによって使用されるデータが外部システムにより持続的に記憶されそしてマネージされると仮定する。時々接続されるデータモデルは、このデータについての移動アプリケーションの予想される使用のメタデータ記述であると共に、時々接続される装置と外部システムとの間でのこのデータの効率的なトラバース及び同期を可能にするように最適化できる。
2007524933.tif 000002
【特許請求の範囲】
【請求項１】
データノードをアプリケーションに関してクライアントと同期させるように構成された同期ユニットであって、前記アプリケーションが随時接続データモデルを含むような同期ユニットと、
外部システムからのデータと、前記随時接続データモデルにより定義されたデータノードとの間で変換を行うように構成されたコンジットマネージャーと、
を備えた随時接続アプリケーションサーバー。
【請求項２】
前記随時接続アプリケーションサーバーは、前記随時接続データモデルのメタデータにより指示されたキャッシュにデータノードをキャッシュ記憶するように構成された、請求項１に記載の随時接続アプリケーションサーバー。
【請求項３】
前記随時接続データモデルは、外部データについてのクライアントの予想使用を指示する、請求項１に記載の随時接続アプリケーションサーバー。
【請求項４】
前記コンジットマネージャーは、コンジットを使用するように構成され、前記コンジットは、前記随時接続データモデルにより定義されたデータと、特定のウェブサービスに対する要求及び応答との間の変換を定義する、請求項１に記載の随時接続アプリケーションサーバー。
【請求項５】
適応ユーザインターフェイスサーバーを更に備え、少なくとも１つのクライアントは、前記データノード及び前記随時接続データモデルを使用して前記適応ユーザインターフェイスサーバーにより構成された前記随時接続アプリケーションサーバーからのＨＴＭＬページを受け取る、請求項１に記載の随時接続アプリケーションサーバー。
【請求項６】
少なくとも１つのクライアントには、前記データノード及び前記随時接続データモデルが転送されて、クライアントに表示を発生する、請求項１に記載の随時接続アプリケーションサーバー。
【請求項７】
少なくとも１つのクライアントは、前記随時接続アプリケーションサーバーにコンタクトせずに、前記データノード及び前記随時接続データモデルを使用してアプリケーションを実行できる、請求項６に記載の随時接続アプリケーションサーバー。
【請求項８】
サーバーにおいて、データノードを、随時接続データモデルを含むアプリケーションに関してクライアントと同期させるステップと、
サーバーにおいて、外部システムからのデータと、前記随時接続データモデルにより定義されたデータノードとの間で変換を行うステップと、
を備えた方法。
【請求項９】
前記随時接続アプリケーションサーバーは、前記随時接続データモデルのメタデータにより指示されたキャッシュにデータノードをキャッシュ記憶する、請求項８に記載の方法。
【請求項１０】
前記随時接続データモデルは、外部データについてのクライアントの予想使用を指示する、請求項８に記載の方法。
【請求項１１】
前記変換はコンジットを使用し、これらコンジットは、前記随時接続データモデルにより定義されたデータと、特定のウェブサービスに対する要求及び応答との間の変換を定義する、請求項８に記載の方法。
【請求項１２】
前記クライアントには、前記データノード及び前記随時接続データモデルの両方が転送されて、クライアントに表示を発生する、請求項８に記載の方法。
【請求項１３】
随時接続アプリケーションサーバーにおいて、
随時接続データモデルを記憶するためのメモリと、
前記随時接続データモデルにより定義されるデータノードを記憶するためのキャッシュと、
を備え、前記随時接続データモデルのメタデータにより指示されたキャッシュにデータノードをキャッシュ記憶する随時接続アプリケーションサーバー。
【請求項１４】
前記随時接続アプリケーションサーバーは、外部システムと、前記随時接続データモデルにより定義されたデータノードとの間でデータを変換するように構成される、請求項１３に記載の随時接続アプリケーションサーバー。
【請求項１５】
前記データノードはＸＭＬを含む、請求項１３に記載の随時接続アプリケーションサーバー。
【請求項１６】
コンジットマネージャーを更に備え、このコンジットマネージャーは、コンジットを使用するように構成され、これらコンジットは、前記随時接続データモデルにより定義されたデータと、特定のウェブサービスに対する要求及び応答との間の変換を定義する、請求項１３に記載の随時接続アプリケーションサーバー。
【請求項１７】
適応ユーザインターフェイスサーバーを更に備え、少なくとも１つのクライアントは、前記データノード及び前記随時接続データモデルを使用して前記適応ユーザインターフェイスサーバーにより構成された前記随時接続アプリケーションサーバーからのＨＴＭＬページを受け取る、請求項１３に記載の随時接続アプリケーションサーバー。
【請求項１８】
少なくとも１つのクライアントには、前記データノード及び前記随時接続データモデルが転送されて、クライアントに表示を発生する、請求項１３に記載の随時接続アプリケーションサーバー。
【請求項１９】
前記クライアントは、前記随時接続アプリケーションサーバーにコンタクトせずに、前記データノード及び前記随時接続データモデルの両方を使用してアプリケーションを実行できる、請求項１８に記載の随時接続アプリケーションサーバー。
【請求項２０】
前記随時接続アプリケーションサーバーと前記クライアントとの間のデータノードの同期は、バックグランドにおいて行うことができる、請求項１９に記載の随時接続アプリケーションサーバー。
【請求項２１】
データノードをアプリケーションに関してクライアントと同期させるように構成された第１コンポーネントであって、前記アプリケーションが随時接続データモデルを含むような第１コンポーネントと、
外部システムからのデータと、前記随時接続データモデルにより定義されたデータノードとの間で変換を行うように構成された第２コンポーネントと、
を備えた随時接続アプリケーションサーバー。
【請求項２２】
クライアントにアプリケーションを与えるように構成された随時接続アプリケーションサーバーを備え、前記アプリケーションは、クライアントが、前記随時接続アプリケーションサーバーへの現在アクセスを要求せずに、アプリケーションデータを読み取り及び更新するのを許し、又、前記随時接続アプリケーションサーバーは、外部システムからアプリケーションデータを得て前記クライアントへ送信するよう適応され、更に、前記随時接続アプリケーションサーバーは、前記外部システムからのデータをデータノードへ変換するように適応されたシステム。
【請求項２３】
前記外部システムはサービスバスである、請求項２２に記載のシステム。
【請求項２４】
前記外部システムはウェブサービスである、請求項２２に記載のシステム。
【発明の詳細な説明】
【技術分野】
【０００１】
本発明は、一般に、移動（モバイル）アプリケーションアーキテクチャーに係り、より詳細には、随時接続移動装置のためのアプリケーションを開発し、配備し、そしてマネージするための移動アプリケーションアーキテクチャーに係る。
【０００２】
版権の警告：本特許文献の開示の一部分は、版権保護を受ける資料を含んでいる。版権所有者は、特許商標庁の特許ファイル又は記録に現われるように特許文献又は特許開示を誰かが複写再生することに異議を唱えるものではなく、全ての版権は何であれ保存されるものとする。
【０００３】
優先権の請求：２００４年５月２０日出願されたボスワース氏等の「MOBILEAPPLICATION SERVER」と題する米国プロビジョナル特許出願第６０／５７３，０７７号［代理人ドケットＮｏ．ＢＥＡＳ−０１５３７ＵＳ０］；及び
２００５年５月４日出願されたボスワース氏等の「OCCASIONALLY-CONNECTED APPLICATION SERVER」と題する米国特許出願第１１／１２２，２９４号［代理人ドケットＮｏ．ＢＥＡＳ−０１５３７ＵＳ１］
【背景技術】
【０００４】
コンピュータ及びコンピューティング装置は、より小型で、より高速で且つより効率的なものとなった。その結果、それらの機能が進歩し、それらがより多くの情報を記憶及び処理できるようになった。しかしながら、装置が何をローカルに記憶して処理できるかについては、依然、制約がある。
【０００５】
最近、移動接続システムの開発で、ポータブル装置のためのより多くの機能が可能となった。これらの装置は、ラップトップコンピュータ、ＰＤＡ、セルラー電話、ノートブックコンピュータ、ブラックベリー型装置、及び他の移動装置も含めて、強力な接続が存在するところであればどこでも、インターネットに接続することができる。これら装置のためのアプリケーションは、多数の形態で得られるが、ユーザは、アプリケーションの配備及びその後の変更が容易であることから、ウェブベースモデルを歴史的に好む。更に、ウェブベースページは、ユーザが使用するために非常に簡単で且つ直感的なものである。
【０００６】
移動装置のウェブブラウジングの最近の開発には多数の問題がある。ユーザがどこにいても接続を得ることが容易ではない。接続は、通常、標準的な電話接続を経て行われ、これは、セルラー電話の信号強度に依存する。現在、セルラー電話ネットワークには多数のデッドゾーンがあり、移動装置とウェブサーバーとの間の接続に休止時間を生じさせる。
【０００７】
これは、典型的なブラウザを通してウェブページコンテンツを与えるのに必要な対話について考えると、更に厄介なことになる。ユーザがウェブブラウザと対話するときに、ブラウザは、ユーザの入力に基づきサーバーからより多くの情報を要求する。これは、新たな情報を検索してユーザに与えるためにブラウザとウェブサーバーとの間にアクティブな接続を必要とする。従って、ユーザが移動装置のウェブブラウザと対話していて、信号強度の弱いエリア又はデッドゾーンに入ると、弱い接続（又は接続の欠如）のために、おそらく、移動装置により受け取られるコンテンツにエラーを生じさせる。従って、ユーザは、このようにウェブページと対話することがしばしばできなくなる。
【発明の開示】
【発明が解決しようとする課題】
【０００８】
そこで、直感的なユーザインターフェイスと、移動装置のユーザにコンテンツを与えるためのより信頼性のあるメカニズムとを与える移動アプリケーションアーキテクチャーフレームワークが要望される。又、このフレームワークは、既存のエンタープライズコンポーネントと一体化される簡単なウェブ状のプログラミングモデルを可能にしながら、精巧な移動ソルーション（解決策）を開発し、配備しそしてマネージもしなければならない。
【課題を解決するための手段】
【０００９】
一実施形態において、随時接続アプリケーションサーバープラットホームは、既存のエンタープライズコンポーネントと一体化される簡単なウェブ状のプログラミングモデルと共に、精巧な移動ソルーションを開発し、配備しそしてマネージするためのフレームワークを提供する。
【００１０】
随時接続アプリケーションは、データモデル定義と、ユーザインターフェイステンプレートと、アクションを定義するスクリプトを含むクライアント側コントローラと、そしてサーバー側では、データモデルとエンタープライズとの間をいかに仲裁するか記述できるコンジットの集合とで構成することができる。一実施形態では、随時接続アプリケーションサーバーは、随時接続アプリケーションにより使用される全てのデータがウェブサービスのような外部システムにより持続的に記憶されそしてマネージされると仮定する。データモデルは、このデータの接続−接続(connected-connected)アプリケーションの予想される使用のメタデータ記述であると共に、随時接続装置と外部システムとの間でのこのデータの効率的なトラバース及び同期を可能にするように最適化することができる。
【００１１】
随時接続データモデルは、持続的アプリケーションデータの構造（及び他のプロパティ）を記述することができる。随時接続データモデルそれ自体は、ブラウザと同期させることができ、従って、クライアントは、インテリジェントにデータをトラバースさせると共に、データをサーバーと同期させることができる。
【発明を実施するための最良の形態】
【００１２】
一実施形態において、随時接続アプリケーションサーバープラットホームは、既存のエンタープライズコンポーネントと一体化される簡単なウェブ状のプログラミングモデルと共に、精巧な移動ソルーションを開発し、配備しそしてマネージするためのフレームワークを提供する。
【００１３】
接続−接続アプリケーションは、データモデル定義と、ユーザインターフェイステンプレートと、アクションを定義するスクリプトを含むクライアント側コントローラと、そしてサーバー側では、データモデルとエンタープライズとの間をいかに仲裁するか記述するコンジットの集合とで構成することができる。一実施形態では、随時接続アプリケーションサーバーは、移動アプリケーションにより使用される全てのデータが外部システムにより持続的に記憶されそしてマネージされると仮定する。データモデルは、このデータの移動アプリケーションの予想される使用のメタデータ記述であると共に、随時接続装置と外部システムとの間でのこのデータの効率的なトラバース及び同期を可能にするように最適化することができる。
【００１４】
随時接続データモデルは、全ての持続的アプリケーションデータの構造（及び他のプロパティ）を記述することができる。モデルそれ自体は、移動ブラウザと同期させることができ、従って、クライアントは、インテリジェントにデータをトラバースさせると共に、データをサーバーと同期させることができる。
【００１５】
随時接続データモデルは、クライアントにおいてキャッシュ記憶及び同期されるデータ、及び任意であるが、サーバーにおいてキャッシュ記憶されるデータを記述することができる。多くのプログラミングモデルがメタデータにより記述され、これは、配備されたアプリケーションに勝る高レベルの制御をアドミニストレータ及びエンドユーザに与える。
【００１６】
一実施形態において、プログラミングモデルは、カリフォルニア州サンノセのＢＥＡシステムズのＷｅｂＬｏｇｉｃワークショップ内で完全にサポートすることができ、これは、ワークショップの視覚設計ツールを及びラウンドトリップ開発モデルを使用し、そしてデベロッパがＬｉｑｕｉｄＤａｔａ及びインテグレーションのような他のＷｅｂＬｏｇｉｃプラットホームコンポーネントをレバレッジできるようにする。
【００１７】
移動ソルーションの構築は、ワークショップウェブアプリケーションの構築と同程度に容易であり、特殊な移動チームを必要としない。この目標は、開発、配備、維持から、毎日の使用に至るまでの所有者の多大なトータルコストを伴う多大な移動経験である。
【００１８】
図１Ａ−Ｂは、一実施形態の全体的システムアーキテクチャー１００を示し、これは、移動ブラウザ１１０、随時接続アプリケーションサーバー１２０、及び外部ウェブサービス１４０を備えている。
【００１９】
随時接続アプリケーションサーバー１２０（ＯＣＡＳ）、例えば、移動アプリケーションサーバー（ＭＡＳ）は、移動ブラウザにおいて実行されるクライアントアプリケーションと、ウェブサーバーを経てアクセスされる外部システムとの間でのデータの交換を仲裁することができる。このメカニズムは、２つのステージをもつことができ、即ち第１に、ＯＣＡＳ１２０は、外部システムと、随時接続データモデルとの間のデータの変換を整合することができ、そして第２に、ＯＣＡＳ１２０は、クライアントキャッシュと外部ウェブサービスとの間の同期を整合することができる。
【００２０】
本発明の一実施形態は、移動クライアント１１１のための随時接続アプリケーションサーバー１２０である。この随時接続アプリケーションサーバー１２０は、随時接続データモデル１２７、例えば、移動データモデルを記憶するためのメモリと、この随時接続データモデル１２７により定義されるデータノードを記憶するためのキャッシュ１２８とを含むことができる。随時接続アプリケーションサーバー１２０は、随時接続データモデルのメタデータにより指示されるキャッシュ１２８にデータノードをキャッシュ記憶することができる。
【００２１】
随時接続アプリケーションサーバー１２０は、１つ以上のマシンで実行されるソフトウェアである。又、随時接続アプリケーションサーバー１２０は、アプリケーションサーバーの最上部で実行することもできるし又はその一部分であってもよい。随時接続クライアント１１１は、パーソナルデジタルアシスタント（ＰＤＡ）、電話、ノートブックコンピュータ、又は他の移動コンピューティング装置である。又、クライアントは、特にサーバーと間欠的にコンタクトする固定コンピュータを含むこともできる。
【００２２】
随時接続アプリケーションサーバー１２０は、ウェブサービス１４０のような外部システムと、随時接続データモデル１２７により定義されるデータノードとの間でデータを変換することができる。
【００２３】
本発明の一実施形態は、随時接続アプリケーションサーバー１２０を含むシステムである。随時接続アプリケーションサーバー１２０は、クライアントにアプリケーションを与えるように構成できる。アプリケーションは、クライアントが、随時接続アプリケーションサーバーへの現在アクセスを必要とせずに、アプリケーションデータを読み取って更新するのを許すことができる。随時接続アプリケーションサーバー１２０は、クライアントへ送信するために外部システムからアプリケーションデータを得るように適応され得る。又、随時接続アプリケーションサーバーは、外部システムからデータノードへデータを変換するように適用され得る。外部システムは、サービスバス、ウェブサービス、又は何らかの他のシステムである。
【００２４】
随時接続データモデル１２７は、外部データについての移動クライアントの予想される使用を指示し、そして移動クライアント１１１により外部データが要求される前にそれを得ることができる。
【００２５】
データノードは、ＸＭＬデータのようなデータの独立したチャンクである。移動データモデル１２７は、データノードに対して、ＸＭＬスキーマ又はＸＭＬ  ＤＴＤのようなＸＭＬ定義を含むことができる。
【００２６】
本発明の一実施形態は、随時接続アプリケーションサーバー１２０を含むシステムである。随時接続アプリケーションサーバー１２０は、クライアントにアプリケーションを与えるように構成できる。アプリケーションは、クライアントが、随時接続アプリケーションサーバーへの現在アクセスを必要とせずに、アプリケーションデータを読み取って更新するのを許すことができる。随時接続アプリケーションサーバー１２０は、クライアントへ送信するために外部システムからアプリケーションデータを得るように適応され得る。又、随時接続アプリケーションサーバーは、外部システムからデータノードへデータを変換するように適用され得る。外部システムは、サービスバス、ウェブサービス、又は何らかの他のシステムである。
【００２７】
移動クライアント１１１は、データノード及び随時接続データモデル１１５を転送して、移動クライアント１１１に表示を発生することができる。適応ユーザインターフェイスサーバー１２６は、クライアント１３０に対してキャッシュ１２８及び随時接続データモデル１２７におけるデータノードからＨＴＭＬページを構成することができる。クライアント１３０は、サーバー１２０への一貫したアクセスを有する慣習的なウェブブラウザを含むことができる。適応ＵＩサーバー１２６は、サーバーにおいてクライアントアプリケーションを実行して、シンクライアント（例えば、普通のウェブブラウザ、ＳＭＳ電話等）からアクセスできるようにするメカニズムを与えることができる。
【００２８】
移動クライアント１１１は、随時接続アプリケーションサーバー１２０にコンタクトせずに、データノード及び随時接続データモデル１１５を使用してアプリケーションを実行することができる。キャッシュ１１３及び随時接続データモデル１１５におけるデータノードは、移動ブラウザ１１０において同期クライアント１１２により使用されて、ＨＴＭＬビュー１１９のような表示を発生することができる。一実施形態では、テンプレートを使用して、移動ブラウザ１１０に表示を発生することができる。
【００２９】
データノード及び随時接続データモデルは、随時接続アプリケーションサーバー１２０と移動クライアント１１１との間で同期させることができる。この同期は、移動クライアント１１１と、随時接続アプリケーションサーバー１２０との間の接続が得られるので、バックグランドにおいて行うことができる。
【００３０】
本発明の一実施形態は、随時接続データモデルにより定義されたアプリケーションに対して、データノード、例えば、キャッシュ１２８のデータノードをクライアント１１１と同期させるための同期エンジンのような同期ユニット１３１と；外部システムからのデータと、随時接続データモデル１２７により定義されたデータノードとの間で変換を行うためのコンジットマネージャー１２４と、を備えた随時接続アプリケーションサーバー１２０である。
【００３１】
本発明の一実施形態は、随時接続アプリケーションサーバー１２０において、ノード及びノード間の関係を定義する随時接続データモデル１２７を記憶し、そして随時接続アプリケーションサーバー１２０において、随時接続データモデル１２７により定義されたデータノードをキャッシュ記憶することを含む方法である。随時接続アプリケーションサーバー１２０は、随時接続データモデル１２７のメタデータにより指示されるデータノードをキャッシュ記憶することができる。
【００３２】
本発明の一実施形態は、随時接続データモデル１２７を記憶するためのメモリと、随時接続データモデル１２７により定義されたデータノードを記憶するためのキャッシュ１２８とを備えた随時接続アプリケーションサーバー１２０である。データノードは、一次キー及び同期状態を含む。一次キーは、データモードを識別する。又、データノードは、少なくとも１つの二次キーを含むこともできる。同期状態を使用して、データノードを移動クライアントと同期させることができる。随時接続データモデル１２７は、データノードに対するＸＭＬスキーマを含むことができる。
【００３３】
本発明の一実施形態は、随時接続アプリケーションサーバー１２０である。この随時接続アプリケーションサーバー１２０は、随時接続データモデル１２７を記憶するためのメモリを含むことができ、この随時接続データモデル１２７は、ノード及びノード間の関係を定義することができ、そして更に、アプリケーションサーバー１２０は、外部システムからのデータと、随時接続データモデル１２７により定義されたデータノードとの間で変換を行うためのコンジットマネージャー１２４を含むことができる。
【００３４】
コンジットマネージャー１２４は、随時接続データモデル１２７により定義されたデータノードと、特定のウェブサービス１４０に対する要求及び応答のためのデータとの間の変換を定義するコンジット１３７を使用することができる。これら変換は、メタデータとして含むことができる。
【００３５】
要求変換は、出て行くメッセージ本体を生成するＸＱｕｅｒｙファンクションを含むことができる。応答変換は、到来する応答を処理すると共に、随時接続データモデル１２７により定義されたデータノードを生成するＸＱｕｅｒｙファンクションを含む。
【００３６】
本発明の一実施形態は、外部ウェブサービス１４０のオペレーションを呼び出すコンジットマネージャー１２４を備えた移動クライアント１１１のための随時接続アプリケーションサーバー１２０である。コンジットマネージャー１２４は、コンジット１３７を使用することができる。コンジットは、随時接続データモデルにより定義されたデータと、特定のウェブサービス１４０に対する要求及び応答との間の変換を定義することができる。
【００３７】
本発明の一実施形態は、随時接続アプリケーションサーバー１２０において、コンジット１３７を使用して、随時接続データモデル１２７のデータノードと、ウェブサービス１４０に対する要求及び応答との間で変換を行い、データノードはＸＭＬデータであり、そして随時接続アプリケーションサーバー１２０において、データノードを使用して、移動ブラウザ表示に対して移動クライアント１１１へデータを与えることを含む方法である。データノードは、表示のために移動クライアント１１１へ転送することができる。
【００３８】
本発明の一実施形態は、キャッシュ１１３に記憶することのできるデータノードを含む移動クライアント１１１である。データノードは、ＸＭＬフォーマットである。移動クライアントにおけるデータノードは、関連同期状態をもつことができる。この同期状態は、データノードがサーバー１２０と同期されたかどうか指示することができる。データノードは、バックグランドにおいて同期させることができる。というのは、サーバーへのアクセスが得られると共に、移動クライアント１１１における表示が、サーバー１２０への現在アクセスを必要とせずに、移動クライアント１１１においてデータモードを使用して行われるからである。
【００３９】
同期状態は、データノードがローカルで生成又は変更されたという指示と、データノードがローカルで生成又は変更されそしてサーバーと同期される準備ができたという指示と、データノードのサーバー同期が保留中であるという指示と、データノードがサーバーと同期されたという指示と、同期がサーバーにより拒絶されたという指示と、ローカル変更とサーバー更新との間に競合があるという指示とを含むことができる。これら及び他の同期状態は、移動クライアント１１１においてデータノードを更新するのに使用できる。
【００４０】
移動クライアント１１１には、サーバー１２０からデータノード及び随時接続データモデルが転送されて、移動クライアントに表示を発生することができる。移動クライアント１１１は、サーバーに現在コンタクトせずに、データノード及び随時接続データモデル１１５を使用してアプリケーションを実行することができる。サーバー１２０と移動クライアント１１１との間でのデータノードの同期は、バックグランドで行うことができる。
【００４１】
本発明の一実施形態は、ノードのタイプ及びノード間の関係、並びにデータノードを定義する随時接続データモデル１１５を含む随時接続アプリケーションサーバー１２０である。データノードは、ＸＭＬフォーマットである。随時接続アプリケーションサーバー１２０は、データノードのための同期状態を移動クライアント１１１とで前後に通過させて、データノードを同期させることができる。データノードは、バックグランドにおいて同期させることができる。というのは、サーバーへのアクセスが得られると共に、移動クライアント１１１における表示が、サーバー１２０への現在アクセスを必要とせずに、移動クライアント１１１においてデータモードを使用して行われるからである。
【００４２】
本発明の一実施形態は、移動装置において移動アプリケーションを同期させる方法である。この方法は、移動装置に第１ユーザインターフェイスを表示するステップであって、この第１ユーザインターフェイスが、移動装置に記憶されたテンプレートから導出されるようなステップと；移動装置のユーザから第１入力を受け取るステップと；移動装置において同期パラメータを更新するステップと；移動装置に第２ユーザインターフェイスを表示するステップであって、この第２ユーザインターフェイスが、移動装置に記憶されてユーザ入力に基づいて選択された第２テンプレートから導出されるようなステップと；アプリケーションサーバーからデータを検索するステップであって、このデータは、同期パラメータに基づいて選択された１つ以上のテンプレートを含むようなステップと、を備えている。
【００４３】
本発明の１つの態様は、ＸＭＬフォーマットのデータノードのローカルキャッシュ１１３と、ノードのタイプ及びノード間の関係を定義する随時接続データモデル１１５とを備えた移動ユニット１１１であって、データノード及び随時接続データモデルを使用して、この移動ユニットに表示されるアプリケーションを発生するような移動ユニット１１１である。
【００４４】
テンプレート１３５は、データノードのためのインターフェイスを移動ユニットに発生するのに使用できる。
本発明の一実施形態は、ＸＭＬフォーマットのデータノードのローカルキャッシュ１２８と、ノードのタイプ及びノード間の関係を定義する随時接続データモデル１１５と、データノードの変更を許すアクションとを含む移動ユニット１１０である。
【００４５】
本発明の一実施形態は、随時接続データモデル１１５を記憶するメモリと、この随時接続データモデル１１５により定義されたデータモードのローカルキャッシュ１１３とを備えた移動ユニット１１０である。データノードは、一次キー及び同期状態を含む。
【００４６】
一実施形態において、データモードの少なくとも１つは、少なくとも１つの二次キーを含む。同期状態を使用して、モードデータを随時接続アプリケーションサーバーと同期させることができる。随時接続データモデル１１５は、データノードのための少なくとも１つのＸＭＬスキーマを含むことができる。
【００４７】
本発明の一実施形態は、ウェブサービス１４０のような外部システムと、随時接続データモデル１２７との間で変換を行うためのコンジットマネージャーを含む移動クライアントのための随時接続アプリケーションサーバー１２０である。キャッシュ１２８を使用して、随時接続データモデル１２７により定義されたデータノードと、適応ユーザインターフェイスサーバー１２６とを記憶することができる。ある移動クライアント１１１には、データノード及び随時接続データモデルが転送されて、移動クライアント１１１に表示が発生されると共に、他のクライアントは、データノード及び随時接続データモデルを使用して適応ユーザインターフェイスサーバー１２６により構成されたＨＴＭＬページを、随時接続アプリケーションサーバー１２０から受信する。
【００４８】
適応ユーザインターフェイスサーバー１２６によりサービスされるクライアント１３０は、慣習的なブラウザをもつことができる。移動クライアント１１１は、データノード及び随時接続データモデルを使用して表示を発生する特殊なブラウザ１１０をもつことができる。
【００４９】
本発明の一実施形態は、サーバー１２０において、随時接続データモデル１２７により定義されたデータノードと、その随時接続データモデル１２７とを記憶するステップと；そのデータノード及び随時接続データモデルをあるクライアント１１１へ転送して、そのクライアントが表示を発生できるようにするステップと；そのデータノード及び随時接続データモデルからサーバーにおいて構成されたＨＴＭＬページを他のクライアント１３０へ転送するステップと、を備えた方法である。
【００５０】
本発明の一実施形態は、ノードの構造を記述するｎｏｄｅｔｙｐｅを含む随時接続データモデルである。ノードは、データとは論理的に独立したユニット、及びノード間の関係を記述するｋｅｙｒｅｆ宣言である。
【００５１】
ノードは、ルート（根）ノードを含むことができる。変数は、ルートノードを指すことができる。移動ブラウザ１１０は、データノード及び随時接続データモデル１１５を使用して、移動ユニット１１１に表示を発生することができる。随時接続データモデル１１５は、ノードグラフを含むことができる。ノードグラフは、どのデータモードをキャッシュ記憶すべきか指示することができる。
【００５２】
ｎｏｄｅｔｙｐｅは、複雑なタイプの定義であるＸＭＬスキーマのようなＸＭＬ定義を含むことができる。ｋｅｙｒｅｆ宣言は、キー及びキー参照を定義することができる。キーは、一次キーである。ｋｅｙｒｅｆは、一次キーを参照する外部(foreign)キー定義である。ｋｅｙｒｅｆ定義は、データグラフにおけるノードとノードとの間のリーガルトラバースを定義することができる。
【００５３】
本発明の一実施形態は、ノード構造のＸＭＬ定義であるｎｏｄｅｔｙｐｅと、ノード間の関係を記述するｋｅｙｒｅｆ定義のようなメタデータとを含む随時接続データモデルである。ノードは、データとは論理的に独立したユニットである。
【００５４】
本発明の一実施形態は、プロキシーを実施する方法であって、随時接続データモデルのようなプログラミングモデル内でデータへウェブサービスオペレーションをマップさせるステップと、データとの関連付けに関する要求を受信するステップと、対応するウェブサービスオペレーションへの呼び出しを開始するステップとを備えた方法である。
【００５５】
本発明の一実施形態は、ＸＭＬフォーマットであるアプリケーションデータノードのローカルキャッシュ１１３と、ノードのタイプ及びノード間の関係を定義する随時接続データモデル１１５と、データノードのためのインターフェイスを発生するテンプレート１３５とを備えた移動ユニット１１１である。
【００５６】
テンプレート１３５は、ＸＨＴＭＬテンプレートである。テンプレート１３５は、Ｓｐａｔｈ表現を使用することができる。
【００５７】
テンプレート１３５は、随時接続データモデル１１５において現在位置にアクセスすることができる。現在変数は、現在位置を指示することができる。一実施形態では、テンプレート１３５は、随時接続データモデルを変更しない。
【００５８】
一実施形態では、テンプレート１３５は、アクションを呼び出すことができる。アクションは、データノードを変更することができる。アクションは、サーバー１２０へ接続せずに、データノードの変更を許すことができる。
【００５９】
テンプレート１３５は、多数のアプリケーションに対して使用可能であり、各アプリケーションは、それ自身の随時接続データモデル及びデータノードを有する。テンプレート１３５は、ブラウザ１１０により検証することができる。
【００６０】
図１１Ａ−Ｂは、本発明の一実施形態の同期方法を示す。図１１Ａの実施例では、クライアント１１０２は、「データノードＡ」１１０４のクライアントバージョンを含む。「データノードＡ」１１０４のクライアントバージョンは、同期状態「ready for sync.(同期のための準備)」を有する。「データノードＡ」１１０４のクライアントバージョンは、クライアント１１０２において構成又は変更されるデータを含むことができる。図１１Ａの実施例では、クライアント１１０２とサーバー１１０８との間にアクティブな接続はない。「データノードＡ」１１０４のクライアントバージョンは、同期のための待機なしに、クライアントにおいてアプリケーションにより使用することができる。「データノードＡ」に対する変化は、接続が得られたときに送信されるメッセージ待ち行列１１０６のメッセージに含ませることができる。
【００６１】
サーバー１１０８は、クライアント１１０２へ送信されていない「データノードＢ」１１１０のサーバーバージョンを有する。「データノードＢ」１１１０のサーバーバージョンは、「ウェブサーバーＢ」１１１６から得たデータから構成することができる。コンジットマネージャーは、「コンジットＢ」１１１４を使用して、「ウェブサービスＢ」１１１６からの応答データを「データノードＢ」１１１０のサーバーバージョンへ変換することができる。「データノードＢ」は、接続が得られたときに送信されるべきメッセージ待ち行列１１１８のメッセージに含ませることができる。
【００６２】
図１１Ｂは、接続が得られたときの状態を示す。「データノードＡ」１１０４のクライアントバージョンは、サーバー１１０８へ送信することができ、そして「データノードＡ」１１０４のクライアントバージョンは、その同期状態を「awaiting sync.(同期待機)」にセットすることができる。サーバー１１０８は、「データノードＡ」１１１１のサーバーバージョンをキャッシュ記憶することができる。コンジットマネージャー１１１２は、「コンジットＡ」１１１５を使用して、「ウェブサービスＡ」１１１７へ送信するための要求データを構成することができる。クライアント１１０２は、サーバー１１０８から得た「データノードＢ」１１０５のクライアントバージョンを記憶することができる。
【００６３】
バックグランドにおいてサーバーと同期されるデータノードを使用することで、クライアントは、サーバーへ間欠的に接続されて、データノードのローカルバージョンでアプリケーションを実行し、そして導通が得られるときに更新することが許される。
【００６４】
１つの実施形態を以下に説明するが、これに限定されるものではない。以下の説明は、１つの実施形態であるが、当業者であれば、上述したコンセプトの他の実施形態も得られることが理解できよう。以下に述べる潜在的限定言語は、特定の非限定実施形態の文脈におけるものと解釈されるべきであり、一般的なコンセプトを限定するものではない。
【００６５】
本発明の一実施形態は、ブラウザ１１０を備えていて、随時接続アクセスメカニズムを与えるシステムである。ブラウザ１１０は、移動装置１１１において実施されて、ユーザへのユーザインターフェイスを与えるように構成できる。ユーザインターフェイスは、テンプレート１３５から導出することができる。アプリケーションサーバー１２０は、持続的なデータ記憶装置をなし、そしてブラウザとで情報を送信及び受信するように構成される。
【００６６】
一実施形態において、随時接続アプリケーションサーバー１２０（ＭＡＳ）は、ＢＥＡシステムズのＷｅｂＬｏｇｉｃサーバーのようなアプリケーションサーバーの最上部で実行されるか、又はその一部分である。随時接続アプリケーションサーバー１２０は、アプリケーションメタデータを記憶するための持続的データ記憶装置と、クライアント要求を最適化するためのデータキャッシュ１２８とを含む。
【００６７】
随時接続アプリケーションサーバー１２０は、ウェブベースの同期サービスの集合を経て移動ブラウザにアクセスすることができ、これは、ＳｙｎｃＭＬ規格を拡張することができる。これは、異なるタイプのクライアントがＭＡＳデータモデル及び同期能力をレバレッジできるようにする。
【００６８】
随時接続アプリケーションサーバー１２０は、クライアントの完全な状態を保持する必要がない。むしろ、随時接続アプリケーションサーバー１２０は、随時接続データモデル１２７におけるメタデータに基づいてデータをインテリジェントにキャッシュ記憶することができる。更に、随時接続アプリケーションサーバー１２０は、適応ＵＩサーバー１２６として知られている動的コンテンツ適応メカニズムを組み込むことができ、これは、移動アプリケーションファンクションをシンクライアント（例えば、ＨＴＭＬウェブサイト、ＷＡＰ、ＳＭＳ）に配送することができる。
【００６９】
一実施形態において、随時接続データモデルは、外部データについての移動アプリケーションの予想される使用のメタデータ記述であり、随時接続装置と外部システムとの間でこのデータの効率的なトラバース及び同期を可能にするように最適化することができる。
【００７０】
随時接続データモデルは、外部サービスに関連したデータのノード（又はエンティティ）及びそれらの間のトラバース（又は関係）を記述する関連モデルである。例えば、顧客関係マネージメント（ＣＲＭ）アプリケーションへのアクセスを与えるウェブサービスが与えられると、データモデルは、アカウント、コンタクト及び購入注文等に対するノードを、所与のノード（例えば、アカウント）から全ての関連ノード（例えば、コンタクト及び購入注文）へアプリケーションを「ナビゲート」させるトラバースと共にもつことができる。
【００７１】
随時接続データモデルは、デベロッパに対して、データモデルにおけるルートノードを指すマニフェスト変数＄ｒｏｏｔを伴う仮想ＸＭＬ文書として表面化させることができる。関連ノードへのナビゲーションは、ｋｅｙｒｅｆ宣言を経て仮想ＸＭＬ文書内で定義することができる。これは、ＸＭＬに対してＥＣＭＡＳｃｒｉｐｔに使用され且つ本書ではＳＰａｔｈとして知られているＸＰａｔｈ表示のサブセットを使用して、簡単なトラバースシンタックスを可能にする。更に、移動ブラウザは、常に、データモデル内の現在位置（例えば、特定の顧客又は注文のセット）をコンテクストとして有することができる。テンプレート及びスクリプトは、別のマニフェスト変数＄ｃｕｒｒｅｎｔを経てこの現在位置にアクセスすることができる。
【００７２】
一実施形態において、移動ブラウザ１１０は、随時接続ラップトップ及び他の装置が、接続状態となるかオフラインとなるかに関わらず、アプリケーションを実行できるようにするウェブブラウザの拡張であるか、又はそれを含む。ブラウザは、現在ウェブブラウザと同じＨＴＭＬレンダラーを組み込むことができるが、ユーザインターフェイステンプレート及びページフローメカニズム、インテリジェントな同期能力を伴うデータキャッシュ、及びデータキャッシュへのアクセスを与える拡張されたスクリプト言語も組み込むことができる。
【００７３】
移動ブラウザのユーザインターフェイスは、ページテンプレートで構成することができる。これらテンプレートは、ＳＰａｔｈ表現を使用してキャッシュ記憶データへの埋め込まれたバインディングを伴うＸＨＴＭＬページである。一実施形態において、テンプレートは、サーバー側の依存性をもたず、従って、ブラウザのネットワーク接続の状態（即ち、オンライン又はオフライン）に関わらず、それらをレンダリングすることができる。
【００７４】
これらテンプレートは、コントローラにより捕獲できるユーザインターフェイス事象を発生することができ、即ちコントローラは、クライアントキャッシュにおいてデータを変更してページフローを決定することのできるアクションスクリプトをコールすることができる。クライアント同期ユニットは、随時接続アプリケーションサーバー１２０とのデータアクセス及び変更を自動的に同期させることができる。
【００７５】
アプリケーションに関するクライアントユーザインターフェイス及び随時接続データモデルを実施するＸＭＬアプリケーションパッケージを参照するＵＲＬを指すことにより、移動ブラウザ１１０へアプリケーションを用意することができる。次いで、アプリケーションは、同期クライアント１１２に対して同期させることができる。更に、アプリケーションがいったん配備されると、アプリケーションの更新は、自動的で且つシームレスである。
【００７６】
一実施形態において、適応ＵＩサーバー１２４は、アクティブなユーザごとにクライアントアプリケーション（テンプレート、ページフロー、アクション等）を実行するプロキシーである。これは、ＨＴＭＬページ（又はＳＭＳ等）を発生することができ、これらページは、ブラウザ１３０へ送信され、そしてこれらのＨＴＭＬページは、適応サーバーが対応アクションコールへと解釈するところのＨＴＴＰ要求を発生する適当なハイパーリンクを含むことができる。適応サーバー１２６は、移動ブラウザ１１０と同じ同期メカニズムを使用することができる。
【００７７】
クライアントアプリケーションは、同期によりサーバーと通信することができる。同期プロセスは、新たな又はより最近のデータをフェッチするか、又は外部ウェブサービス１４０へのクライアント変更のポストバックを要求するためのコンジット要求をトリガーすることができる。コンジット３７は、ウェブサービス要求をいかにパッケージするか、及びそれらの応答をデータモデルの状況においていかに解釈するか記述するメタデータを含むことができる。
【００７８】
例えば、クライアントアプリケーションが、クライアントにキャッシュ記憶された特定のアカウントノード（レコード）に対するレーティングコードを変更し、即ち同期メカニズムが、サーバーへ送信される更新コマンドを発生できると仮定する。次いで、クライアントアプリケーションが、アカウントに関連したコンタクトを検索し、そして新たなコンタクトを追加する場合には、同期メカニズムは、対応するデータノードをフェッチしそして追加するためのコマンドを発生できる。コンジットは、これらオペレーションの各々を実施するのに必要な種々のウェブサービスオペレーションをいかに呼び出すか記述することができる。
【００７９】
このシステムは、標準的なウェブサービスを使用して、外部データリソース及びビジネスプロセスと情報を交換することができる。コンジットメカニズムは、随時接続アプリケーションサーバー１２０が、移動データキャッシュ１２８を更新するためのこれらオペレーションをコールできるようにする。これらオペレーションは、特定データタイプに対するゲッター及びセッターとして働くことができ、即ちアダプターとして働き得るコンジットによりオペレーションの集合をマネージすることができる。コンジットマネージャーは、ＯＣＡＳデータキャッシュからの同期要求とコンジットオペレーションを整合することができる。
【００８０】
コンジットは、ウェブサービスを、データモデルに関連した３つのタイプの要求されたアクションに関連付けるのに使用されるメタデータである。
−関連データへのナビゲーションで、例えば、アカウントに関連したコンタクトを得る。
−ＣＲＵＤオペレーション、即ちデータを生成し、読み取り、更新しそして削除する要求で、例えば、アカウントに関連したコンタクトを生成し、コンタクトの細部を更新し、又はコンタクトを削除することを要求する。
−あるデータに関連したエンタープライズにおいて行う必要があるが、データモデルに対して不透明なアクションである顧客オペレーションで、例えば、タスクをクローズすることを要求する。
【００８１】
コンジットメタデータは、ＯＣＡＳデータモデル及び同期コマンドを、対応するウェブサービスオペレーションに関連したＳＯＡＰメッセージへ及びそこからマップすることができる。コンジットメタデータは、ＸＭＬ問合せ又はＸＳｃｒｉｐｔを使用して定義することができる。
【００８２】
移動性に対する現在ウェブブラウザアーキテクチャーの主たる欠点は、同期（ブロッキング）要求−応答メッセージングプロトコル（即ち、ＨＴＴＰ）である。ＯＣＡＳにおいて、メッセージングは、非同期であってもよい。即ち、ユーザインターフェイスアクティビティ（例えば、ページをブラウジングしそしてデータを変更する）は、ネットワークの接続性に対して非同期で実行することができ、そして同期要求は、ブラウザに対して非同期で実行されてもよい。
【００８３】
図２は、移動ブラウザ２１０と、ＯＣＡＳ２２０と、外部ウェブサービス２３０との間の非同期の対話を例示する。このシステムは、ブラウザとＯＣＡＳとの間に信頼性のある順序付けされたメッセージ待ち行列を実施し、そしてＯＣＡＳとウェブサーバーとの間に耐久性のあるＪＭＳ待ち行列を使用してもよい（非同期のオペレーションコールに対して）。
【００８４】
ブラウザがオンラインである場合には、同期メッセージを待ち行列に入れて、後で、ＯＣＡＳへ送信することができる。さもなければ、同期ユニットは、これらの事象を追跡し、そして接続が確立されたときに同期メッセージを発生することができる。
【００８５】
サーバーにおいて、ＯＣＡＳは、クライアントの同期要求に関するデータをキャッシュ記憶した場合に、即座に応答することができる。キャッシュが適切なデータを保持しない（又はデータが古い）場合には、同期ユニットがコンジットマネージャーをコールすることができる。次いで、同期ユニットは、更新されたデータをブラウザへ配送することができる。特定の同期要求に対して多数のコンジットが呼び出されることがあるので、ＯＣＡＳは、多数の同期メッセージをブラウザへ配送することがある。
【００８６】
同期メッセージがブラウザにより受信されると、ローカルキャッシュを更新し、事象をコントローラへ送信することができる。現在表示されているデータが変更された（即ち、データが現在テンプレートにバインディングされた）場合には、コントローラは、現在ページをリフレッシュさせることができる。即ち、ページデータバインディングを再計算し、そしてページを増分的にブラウザに再表示することができ、現在ユーザ入力、脱字記号又は焦点をフリッカーさせたり失ったりすることはない。
【００８７】
ＯＣＡＳアプリケーションは、クライアント及びサーバーコンポーネントで構成することができる。図３は、例示的なＯＣＡＳアプリケーションに関するプログラミングモデル３００を示す。このプログラミングモデル３００は、移動クライアント３１０と、ＯＣＡＳ３２０と、外部システム３３０とを備えている。
【００８８】
一実施形態において、外部システム（即ち、エンタープライズ）への全ての通信は、ウェブサービス（即ち、ＳＯＡＰメッセージ）を経て達成することができる。サーバープログラミングモデルは、各アプリケーションに関するデータモデル定義３２２と、ウェブサービスオペレーションを記述する１組のコンジット定義３２４で構成することができる。データモデルは、データタイプ及び関係を記述する１組のＸＭＬスキーマ定義で構成される。コンジット定義は、到来する及び出て行くＳＯＡＰメッセージをデータモデルへとマップするＸＳｃｒｉｐｔ及びＸＭＬ問合せ（ＸＱｕｅｒｙ）ファンクションを含む。
【００８９】
クライアントプログラミングモデルは、データモデル３１１（これは、サーバーに定義されたモデルのコピーである）と、１組のＸＨＴＭＬテンプレート３１２と、ＸＰＦページフロー定義及びＸＳｃｒｉｐｔアクション及びファンクションを含むコントローラ定義３１３とで構成することができる。全アプリケーションのコンテンツは、クライアントへのアプリケーションコンポーネントを用意するためにフレームワークにより自動的に使用される単一のＸＭＬファイルにより記述することができる。
【００９０】
一実施形態において、各ＯＣＡＳアプリケーションは、それ自身の随時接続データモデルを有してもよい。この随時接続データモデルは、ウェブサービスを経て後端アプリケーションにより露出されたアプリケーションデータの論理的構造（及び他のプロパティ）を記述することができる。随時接続データモデルは、データモデルにおけるノード（又はエンティティ）を記述するｎｏｄｅｔｙｐｅと、それらｎｏｄｅｔｙｐｅ間の関係を定義するｋｅｙｒｅｆとで構成できる。随時接続データモデルは、他のＯＣＡＳコンポーネントにより使用されるリンガフランカ(lingua franca)として働いて、データを処理するか、又はデータを互いに交換することができる。
【００９１】
アプリケーションのデータモデルの実際の設計（これは、アプリケーションデザイナーにより行われる）は、データの予想される使用を考慮に入れて、サーバーと随時接続装置との間でクライアントアプリケーション及びデータ同期による両データアクセスを最適化することができる。
【００９２】
又、アプリケーションがデータ駆動（即ち自動的）ユーザインターフェイスを表示するのを容易にするように、付加的なメタデータを指定することもできる。一実施形態では、随時接続データモデルは、データを記述するだけであり、即ちＯＣＡＳは、全てのオペレーションデータが外部システムにより記憶されそしてマネージされる（所有される）と仮定し、即ちＯＣＡＳに永久的に存在するオペレーションデータはないと仮定する。
【００９３】
随時接続データモデルは、クライアント及びサーバーの両方にキャッシュ記憶され得るデータを記述するのに使用できると共に、本質的に、ウェブサービスを経てフェッチされるエンタープライズのデータの最上位における仮想キャッシュ記憶ビューである。一実施形態では、随時接続データモデル内に、全てのものが流れてくるところのｍａｓ：ｒｏｏｔ（プログラミングモデルにおいて＄ｒｏｏｔにより参照される）として知られたマジックスタートノードがある。
【００９４】
いずれかのノードから、トラバースを経て関連ノードにアクセスすることができる。ノードは、ＸＭＬスキーマ定義（／ｓｃｈｅｍａ／＊．ｘｓｄ）に適合することができる。又、トラバースは、ｋｅｙｒｅｆ宣言を使用して、スキーマ定義により定義することもできる。
【００９５】
自動同期メカニズムは、クライアントデータとサーバーデータとの間の変化を整合することができる。データは、コンジットとして知られたメカニズムを経て検索して外部システムと交換することができる。コンジットは、コンジットオペレーション、即ち外部ウェブサービスオペレーションから結果を呼び出して処理するＸＳｃｒｉｐｔ及びＸＱｕｅｒｙファンクション、を定義する１組のコンジットファイル（／ｃｏｎｄｕｉｔ／＊．ｊｓｘ）により構成することができる。
【００９６】
コンジットオペレーションは、所与のｋｅｙｒｅｆに関連した一対のＸＭＬ問合せファンクションで構成することができ、即ちその一方のファンクションは、適切なウェブサービスオペレーションへのアウトバウンド要求をフォーマットすることができ、そしてその他方は、インバウンド応答を処理することができる。又、コンジットオペレーションは、関連ＸＳｃｒｉｐｔファンクションにおける手順ロジックを定義することもできる。
【００９７】
随時接続データモデルは、リレーショナルデータベースにおけるエンティティ（即ちテーブル行）及び関係（即ち一次／外部キーフィールド）と同様のノード及びトラバースより成るデータグラフとして表わすことができる。ノードは、データとは論理的に独立したユニット（又はエンティティ、例えば、顧客、購入注文、又はコンタクトレコード）であり、そしてＸＭＬスキーマにより定義されたＸＭＬデータオブジェクトとして表わすことができる。データキャッシュの内部では、各ノードは、一次キーと、同期状態（例えば、シーケンスナンバーを含む）と、おそらく、他のノードを参照する多数の外部キーとを含むことができる。ｎｏｄｅｔｙｐｅは、ノードの特定タイプに関する情報を記述することができ、これは、データノードの構造を記述するＸＭＬスキーマ定義を含むことができる。トラバースは、２つのノード間の方向関係である。トラバースは、主として、１つのノードから１組の関係ノードへナビゲートするためのメカニズムである。例えば、アカウントは、１組のコンタクト及び１組のタスクに関連付けられてもよく、又、その各々は、コンタクトに関連付けられてもよい。ノード間の関係は、ｋｅｙｒｅｆ宣言により定義することができる。これは、ソース及びターゲットの両ｎｏｄｅｔｙｐｅを定義できると共に、カーディナリティ(cardinality)又はノードセット(nodeset)（例えば、丁度１、０又はそれより多く、１又はそれより多く、等）を決定するためのメタデータを含むことができる。コンジットマネージャーのメタデータは、ｋｅｙｒｅｆに関連付けることができ、そしてノードを生成できるか、更新できるか、リンクできるか又は除去できるか決定する。例えば、コンジットのメタデータは、アカウントに関するノート(Note)を挿入するか又はアカウントを更新するための既知のウェブサービスオペレーションがあるかどうか決定する。ｋｅｙｒｅｆにより定義されたノードの特定の集合をノードセットと称することができる。
【００９８】
データノード
データノードは、構造化データ（即ち、ＸＭＬ文書）を含むことができるが、トラバースに対して原子的であり、即ち一実施形態では、トラバースは、２つのノード間の特定の関係を表わすが、特定のノード内のデータを参照することも、別のノードを参照するノード内のデータを参照することもできない。
【００９９】
単一のエンタープライズ文書は、しばしば、多数のｎｏｄｅｔｙｐｅで作り上げることができる。例えば、購入注文は、一連のラインアイテム（各々製品参照をもつ）と、顧客参照とを含んでもよい。この場合に、購入注文、ラインアイテム、製品及び顧客は、全て、異なるｎｏｄｅｔｙｐｅで表わされてもよい。
【０１００】
これらの「複合」ノードの場合には、データモデル内のｋｅｙｒｅｆは、カーディナリティを定義することができ、例えば、ラインアイテムには、丁度１つの製品が関連付けられる。逆に、アプリケーションのニーズに基づいて、単一の購入注文ｎｏｄｅｔｙｐｅは、全ての前記情報を単一のスキーマに含むように定義されてもよい。判断は、アプリケーションデザイナーの手にあり、異なるトラバース、集合及びテンプレート要求に基づき異なるノードを独立してリンクするためのニーズに基づくものである。例えば、ラインアイテムが、購入注文以外でリンクも表示もされない場合には、購入注文−ラインアイテムの複合ｎｏｄｅｔｙｐｅを定義することが理解される。
【０１０１】
関係モデル
随時接続データモデルは、関係エンティティ及び関係（一次／外部キー）構造と同様のスキーマ及びｋｅｙｒｅｆ宣言で構成することができる。
【０１０２】
一次及び外部キー
一例のＣＲＭシステム（説明の目的で、本書全体にわたって参照される）は、リレーショナルデータベースを使用して実施される。図４に示すエンティティ関係ダイアグラム（ＥＲＤ）４００は、アカウント、コンタクト、事象、及びユーザエンティティを表わす。
【０１０３】
アカウント、コンタクト及びユーザエンティティは、次のＳＱＬにより定義される。
CREATE TABLE account (
pkey      INT NOT NULL PRIMARY KEY,
parentPkey        INT FOREIGN KEY REFERENCES account(pkey),
ownerPkey  INT FOREIGN KEY REFERENCES user(pkey),
name      VARCHAR,
type      CHAR
)
CREATE TABLE contact (
pkey      INT NOT NULL PRIMARY KEY,
accountPkey       INT NOT NULL FOREIGN KEY REFERENCES account(pkey),
ownerPkey  INT FOREIGN KEY REFERENCES user(pkey),
first             VARCHAR,
last              VARCHAR,
email             VARCHAR
)
CREATE TABLE user (
pkey              INT NOT NULL PRIMARY KEY,
login             VARCHAR
)
【０１０４】
両アカウント及びコンタクトエンティティは、ユーザ（所有者）への外部キー参照を含み、即ち各コンタクトエンティティは、アカウントへの外部キー参照を定義する。又、各アカウントは、親アカウントを参照する任意の外部キーを有する（即ち、アカウントがサブアカウントを有する）。
【０１０５】
サンプル問合せ
アカウントの一次キーｐａが与えられると、次のＳＱＬは、全てのコンタクトを選択する。
SELECT * FROM contact WHERE accountPkey = pa
【０１０６】
コンタクトの一次キーｐｃが与えられると、次のＳＱＬは、アカウントを選択する。
SELECT account.* FROM account, contact
WHERE account.pkey = contact.accountPkey
AND contact.pkey = pc
【０１０７】
しかしながら、全コンタクトレコードｃが与えられると、この簡単なＳＥＬＥＣＴ問合せがそれに対応するアカウントを選択する。
SELECT * FROM account WHERE account.pkey = c.accountPkey
【０１０８】
ジョインテーブル
事象が多数のアカウント及びコンタクト（例えば、存在する２つのアカウントを満足するセール）に属することができると仮定する。これは、例えば、ジョインテーブルを使用してモデリングされる。
CREATE TABLE event (
pkey                INT NOT NULL PRIMARY KEY,
title               VARCHAR,
details             VARCHAR
)
CREATE TABLE event_account (
eventPkey          INT FOREIGN KEY REFERENCES EVENT(pkey),
accountPkey        INT FOREIGN KEY REFERENCES ACCOUNT(pkey)
)
【０１０９】
ここで、ｅｖｅｎｔ＿ａｃｃｏｕｎｔジョインテーブルにより多対多の関係がモデリングされる。
アカウントの一次キーｐａが与えられると、次のＳＱＬ（ジョイン）は、全ての関係事象を選択する。
SELECT event.* FROM event, event_account
WHERE event_account.accountPkey = pa
AND event.pkey = event_account.eventPkey
【０１１０】
同様に、事象の一次キーｐｅが与えられると、次のＳＱＬは、全ての関係アカウントを選択する。
SELECT account.* FROM account, event_account
WHERE event_account.eventPkey = pe
AND account.pkey = event_account.accountPkey
【０１１１】
ＸＭＬスキーマ
ＸＭＬスキーマは、アプリケーションにより使用されるデータモデルにおいてｎｏｄｅｔｙｐｅを定義することができる。スキーマサブディレクトリーは、多数の．ｘｓｄファイルを含んでもよく、これらは全て始動時にフレームワークによりロードされる。
【０１１２】
スキーマタイプ定義は、２つの部分で構成でき、即ちタイプの構造を記述するｃｏｍｐｌｅｘＴｙｐｅ定義と、例えば、特定タイプに対するラベルをいかに構成するか定義するメタデータ定義（ｍａｓ  ｎａｍｅｓｐａｃｅを使用する）である。
【０１１３】
例えば、次のスキーマフラグメントは、コンタクトタイプを定義する。
<?xml version=”1.0”?>
<xsd:schema targetNamespace=”http://example.com/”
elementFormDefault=”qualified” attributeFormDefault=”unqualified”
xmlns:xsd=”http://www.w3.org/2001/XMLSchema”
xmlns:mas=”run:bea.com”
xmlns=”http://example.com/”>
...
<xsd:element name=”contact” type=”contactType”>
<xsd:annotation>
<xsd:appinfo>
<mas:nodeAnnotation>
<mas:label>$node.first + ” ” + $node.last</mas:label>
</mas:nodeAnnotation>
</xsd:appinfo>
</xsd:annotation>
</xsd:element>
<xsd:complexType name=”contactType”>
<xsd:sequence>
<xsd:element name=”salutation” type=”contactSalutationEnum”/>
<xsd:element name=”first” type=”xsd:string”/>
<xsd:element name=”last” type=”xsd:string”/>
<xsd:element name=”email” type=”xsd:string”/>
</xsd:sequence>
</xsd:complexType>
<xsd:simpleType name=”contactSalutationEnum”>
<xsd:restriction base=”xsd:string”>
<xsd:enumeration value=”Mr”/>
<xsd:enumeration value=”Mrs”/>
<xsd:enumeration value=”Ms”/>
<xsd:enumeration value=”Dr”/>
</xsd:restriction>
</xsd:simpleType>
...
</xsd:schema>
【０１１４】
次のＸＭＬは、コンタクトエレメントを表わす。
<contact>
<salutation>Mr</salutation>
<first>Roger</first>
<last>Reed</last>
<email>roger@acme.com</email>
</contact>
【０１１５】
ｋｅｙｒｅｆベーシック
随時接続データモデルは、全てのアプリケーションタイプに対して標準的なＸＭＬスキーマ定義で構成することができる。これらスキーマは、他のＸＭＬノードを参照するＸＭＬエレメント及び属性を含むノードを定義することができる。これら参照の定義は、ｋｅｙｒｅｆ宣言を使用して行うことができる。
【０１１６】
ｋｅｙｒｅｆ定義は、ｋｅｙ及びｋｅｙｒｅｆの２つの部分で構成できる。
キー定義は、一次キーを含む文書内の場所を定義することができる。例えば、次のキーは、ａｃｃｏｕｎｔＫｅｙが各＜ａｃｃｏｕｎｔ＞エレメントにおいてｉｄと称する属性として生じることを示している。
<xsd:key name=”accountKey”>
<xsd:selector xpath=”account”/>
<xsd:field xpath=”@id”/>
</xsd:key>
【０１１７】
一実施形態において、キーは、単一ノードを独特に識別することができる。キーは、ノード内の中継エレメントを識別するのには使用できない（例えば、ラインアイテムが購入注文に対するスキーマ内で定義される場合に、キー定義は、個々のラインアイテムを定義するのに使用できない）。
【０１１８】
ｋｅｙｒｅｆ定義は、外部キーを含む文書内の場所を定義することができ、即ち参照属性は、関連キー定義を参照する。例えば、次のｋｅｙｒｅｆは、各コンタクトが、ａｃｃｏｕｎｔＫｅｙ定義（上述した）を参照する外部キーであるアカウント属性を含むことを示す。
<xsd:keyref name=”contactAccountRef” refer=”accountKey”>
<xsd:selector xpath=”contact”/>
<xsd:field xpath=”@accountId”/>
</xsd:keyref>
【０１１９】
同じ（一次）キー定義を参照する多数のｋｅｙｒｅｆ（外部キー）定義が存在し得る。
タイプ及びインスタンス図
ＵＭＬを使用して、ｎｏｄｅｔｙｐｅ及びｋｅｙｒｅｆ図を説明する。
図５は、同じＣＲＭアプリケーションに関するＵＭＬエンティティ関係図（ＥＲＤ）５００である。この図において、各エンティティは、アプリケーションｎｏｄｅｔｙｐｅ（即ち、スキーマ）を表わす。ルートエンティティは、システムｎｏｄｅｔｙｐｅであることに注意されたい。
【０１２０】
アーク(arc)は、黒のダイアモンドがソースｎｏｄｅｔｙｐｅの外部キーのターゲットｎｏｄｅｔｙｐｅを表わすような関係（即ち、ｋｅｙｒｅｆ定義）を表わしている。スター(star)表示は、多対１の関係を表わす。各アークは、対応するｋｅｙｒｅｆのエイリアス名で表示される。図６は、ＣＲＭ使用の場合のノードインスタンス図である。
【０１２１】
ネームスペース
ネームスペースの実施形態について以下に説明する。サーバープログラミングモデルは、ネームスペースを使用して、フレームワークとアプリケーションＸＭＬエレメントとの間を区別することができる。ネームスペース定義は、ＸＭＬソースファイルの最上位レベルエレメント内の属性として含ませることができる。
【０１２２】
ｍａｓネームスペースを先頭にもつエレメントは、次のシステムエレメントを表わす。
xmlns:mas=”urn:bea.mas”
【０１２３】
規定により、ａｐｐネームスペースプレフィックスを先頭にもつエレメントは、次のアプリケーションを表わす。
xmlns:app=”http://example.com/”
【０１２４】
又、規定により（本書において）、ｗｓネームスペースプレフィックスは、例示的ウェブサービス定義（即ち、ＷＤＳＬファイル）により定義されたエレメントを指示するのに使用され、ｓｆｄｃプレフィックスは、ＳａｌｅｓＦｏｒｃｅウェブサービスを指示するのに使用される。
xmlns:ws=”http://www.openuri.org/”
xmlns:sfdc=”urn:partner.soap.sforce.com”
【０１２５】
スキーマデータタイプ
次のＸＭＬスキーマデータタイプをサポートすることができる。
2007524933.tif 000003
【０１２６】
スキーマ注釈
標準的なＸＳＤスキーマ定義は、＜ｘｓｄ：ａｐｐｉｎｆｏ＞エレメント内でｍａｓエレメントを宣言することにより拡張することができる。
<xsd:element name=”typeName” type=”type”>
<xsd:annotation>
<xsd:appinfo>
...
</xsd:appinfo>
<xsd:documentation>schema documentation</xsd:documentation>
</xsd:annotation>
</xsd:element>
【０１２７】
次のスキーマ注釈がサポートされる。
2007524933.tif 000004
【０１２８】
ラベル
ｍａｓ：ｌａｂｅｌエレメントは、ノードに対するデフォールトラベルを宣言し、即ちストリングを構成するのに使用されるＸＰａｔｈ表現を宣言する。この表現は、ＸＭＬノードオブジェクトの最上位レベルエレメントを参照する＄ｎｏｄｅ変数を任意に参照することができる。
シンタックス
<mas:label>spath-expression</mas:label>
【０１２９】
例
次のラベル定義は、コンタクトの最初と最後のネームからストリングを構成する。
<xsd:element name=”contact” type=”contactType”>
<xsd:annotation>
<xsd:appinfo>
<mas:label>$node.first + ” ” + $node.last</mas:label>
</xsd:appinfo>
</xsd:annotation>
</xsd:element>
【０１３０】
これは、次の表現と等価である。
<mas:label>first + ” ” + last</mas:label>
又、ラベル定義は、ＸＳｃｒｉｐｔファンクション及び演算子を含んでもよい。
($node.first) + ($node.first.length() > 0 ? ” ” : ””) + $node.last
【０１３１】
アプリケーションデータモデル定義の解剖
次のＸＭＬスキーマは、アカウント及びコンタクトｎｏｄｅｔｙｐｅを定義する簡単なアプリケーションデータモデルを記述する。
<xsd:schema ...>
<xsd:complexType name=”accountType”>
<xsd:all>
<xsd:element name=”name” type=”xsd:string”/>
<xsd:element name=”type” type=”xsd:string”/>
</xsd:all>
<xsd:attribute name=”id” type=”xsd:string” use=”required” mas:type=”pkey”/>
<xsd:attribute name=”ownerId” type=”xsd:string” use=”required”/>
<xsd:attribute name=”parentId” type=”xsd:string”/>
</xsd:complexType>
<xsd:complexType name=”contactType”>
<xsd:all>
<xsd:element name=”first” type=”xsd:string”/>
<xsd:element name=”last” type=”xsd:string”/>
<xsd:element name=”email” type=”xsd:string”/>
</xsd:all>
<xsd:attribute name=”id” type=”xsd:string” use=”required” mas:type=”pkey”/>
<xsd:attribute name=”ownerId” type=”xsd:string” use=”required”/>
<xsd:attribute name=”accountId” type=”xsd:string” use=”required”/>
</xsd:complexType>
<xsd:element name=”graph”>
<xsd:complexType>
<xsd:element name=”root” type=”mas:rootType”/>
<xsd:sequence>
<xsd:element name=”account” type=”accountType” maxOccurs=”unbounded”/>
<xsd:element name=”contact” type=”contactType” maxOccurs=”unbounded”/>
</xsd:sequence>
</xsd:complexType>
<xsd:key name=”accountKey”>
<xsd:selector xpath=”account”/>
<xsd:field xpath=”@id”/>
</xsd:key>
<xsd:keyref name=”contactAccountRef” refer=”accountKey” mas:alias=”account”
mas:inverseAlias=”contacts”>
<xsd:selector xpath=”contact”/>
<xsd:field xpath=”@accountId”/>
</xsd:keyref>
</xsd:element>
</xsd:schema>
【０１３２】
スキーマファイルは、３つの部分、即ちｎｏｄｅｔｙｐｅ（複雑なタイプの定義）と、キャッシュ「文書」の構造を定義するグラフ定義と、グラフ（即ち、文書）構造に対するものである１組のｋｅｙ／ｋｅｙｒｅｆ定義とで構成することができる。
【０１３３】
スキーマ定義
上述したように、データモデルは、ＸＭＬスキーマ定義で構成される。次のスキーマは、アカウント及びコンタクトｎｏｄｅｔｙｐｅを定義する。
<xsd:schema ...>
<xsd:complexType name=”accountType”>
<xsd:all>
<xsd:element name=”name” type=”xsd:string”/>
</xsd:all>
<xsd:attribute name=”id” type=”xsd:string” use=”required” mas:type=”pkey”/>
<xsd:attribute name=”ownerId” type=”xsd:string” use=”required”/>
<xsd:attribute name=”parentId” type=”xsd:string”/>
</xsd:complexType>
<xsd:complexType name=”contactType”>
<xsd:all>
<xsd:element name=”first” type=”xsd:string”/>
<xsd:element name=”last” type=”xsd:string”/>
<xsd:element name=”email” type=”xsd:string”/>
</xsd:all>
<xsd:attribute name=”id” type=”xsd:string” use=”required” mas:type=”pkey”/>        <xsd:attribute name=”ownerId” type=”xsd:string” use=”required”/>
<xsd:attribute name=”accountId” type=”xsd:string” use=”required”/>
</xsd:complexType>
【０１３４】
全てのタイプは、キーであると宣言された一次キーフィールド（又は属性）を定義することができる。
この実施例において、全てのタイプは、外部レコードの一次キーを表わす外部識別子ｉｄを定義することができ、又、ｃｏｎｔａｃｔタイプは、外部キーを表わす属性＠ａｃｃｏｕｎｔＩｄも定義する。
【０１３５】
上述したスキーマ定義は、次のインスタンスデータを許す。
<account id=”1.1”>
<name>Acme</name>
</account>
<contact id=”1.2” accountId=”1.1”>
<first>Bob</first>
<last>Harris</last>
<email>bob@acme.com</email>
</contact>
<contact id=”1.3” accountId=”1.1”>
<first>Maggie</first>
<last>Cheung</last>
<email>maggie@acme.com</email>
</contact>
【０１３６】
ここに示す識別子の値は、例示に過ぎず、又、この実施例は、フレームワークによりマネージされるものでプログラミングモデルには見えないｍａｓ属性を示すものでないことに注意されたい。
データグラフ定義
随時接続データモデルは、デベロッパに対して仮想ＸＭＬ文書又はデータグラフとして表面化することができる。アプリケーションは、スキーマ及びｋｅｙｒｅｆ宣言を指定することによりデータグラフの構造を定義する。
【０１３７】
しかしながら、キーのｋｅｙｒｅｆ宣言それ自体は、アプリケーションスキーマの＜ｇｒａｐｈ＞エレメントにより定義された固定文書構造に対するものであるＸＰａｔｈを含むことができる。
【０１３８】
グラフタイプは、ノード宣言の「フラット」シーケンスを定義することができる。
<xsd:complexType name=”rootType”/>
<xsd:element name=”root” type=”rootType”/>
<xsd:complexType name=”graphType”>
<xsd:sequence>
<xsd:element ref=”root”/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name=”graphType”>
<xsd:complexContent>
<xsd:extension base=”mas:graphType”>
<xsd:sequence minOccurs=”0” maxOccurs=”unbounded”>
<xsd:choice>
<xsd:element name=”nodeName” type=”nodeType”/>
</xsd:choice>
</xsd:sequence>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
<xsd:element name=”graph” type=”graphType”>
<key-definitions>
<keyref-definitions>
</xsd:element>
【０１３９】
例
<xsd:element name=”graph”>
<xsd:complexType>
<xsd:element name=”root” type=”rootType”/>
<xsd:sequence>
<xsd:element name=”account” type=”accountType” maxOccurs=”unbounded”/>
<xsd:element name=”contact” type=”contactType” maxOccurs=”unbounded”/>
</xsd:sequence>
</xsd:complexType>
【０１４０】
これは、ルートエレメントのタイプと、アプリケーションを作り上げる１組の全スキーマタイプとを定義する。
グラフ構造は、その大部分が実施細部であり、デベロッパは、ｋｅｙ／ｋｅｙｒｅｆ定義を使用してデータグラフをトラバースすることに注意されたい。ここに提案する１つのグラフ実施は、フラットであり、即ち全てのｎｏｄｅｔｙｐｅが、＜ｇｒａｐｈ＞エレメントの第１レベルの子である。
【０１４１】
上述した実施例は、次のインスタンスデータを許す。
<graph>
<account id=”1.1”>
<name>Acme</name>
</account>
<contact id=”1.2” accountId=”1.1”>
<first>Bob</first>
<last>Harris</last>
<email>bob@acme.com</email>
</contact>
<contact id=”1.3” accountId=”1.1”>
<first>Maggie</first>
<last>Cheung</last>
<email>maggie@acme.com</email>
</contact>
<graph>
【０１４２】
ｋｅｙ及びｋｅｙｒｅｆ定義
又、スキーマ定義ファイルは、データタイプとデータタイプとの間の一次キー及び外部キーの関係を宣言することのできるｋｅｙ及びｋｅｙｒｅｆ定義も含むことができる。
ｋｅｙ定義は、一次キーを定義することができる。キーは、多数のフィールド宣言（即ち、コンパウンドキーに対する）を含んでもよい。
【０１４３】
ｋｅｙｒｅｆ定義は、ｋｅｙ定義を参照する外部キーを定義する。
例えば、次のｋｅｙ及びｋｅｙｒｅｆ定義は、コンタクトノードからその関係アカウントノードへの多対１（ルックアップ）関係と、ルートからアカウントへの１対多の関係とを定義する。
<xsd:key name=”accountKey”>
<xsd:selector xpath=”account”/>
<xsd:field xpath=”@id”/>
</xsd:key>
<xsd:keyref name=”contactAccountRef” refer=”accountKey” mas:alias=”account”>
mas:inverseAlias=”contacts”>
<xsd:selector xpath=”contact”/>
<xsd:field xpath=”@accountId”/>
</xsd:keyref>
</xsd:graph>
</xsd:schema>
【０１４４】
ｋｅｙ及びｋｅｙｒｅｆ定義は、独特のネームを有していなければならない。ｋｅｙ及びｋｅｙｒｅｆに対するネーミング規定は、各々、次の通りである。
<xsd:key name=”<schema>Key” ...
<xsd:keyref name=”<sourceSchema><element|attribute>Ref” ...
【０１４５】
例えば、ｆｏｏＢａｒＲｅｆは、ｂａｒと命名されたエレメント又は属性により定義されたｆｏｏスキーマからのｋｅｙｒｅｆを意味する。即ち、（通常は）ｋｅｙｒｅｆのセレクタＸＰａｔｈは、「ｆｏｏ／ｂａｒ」又は「ｆｏｏ／＠ｂａｒ」である。
【０１４６】
一般に、ｋｅｙｒｅｆネームは、ｋｅｙｒｅｆセレクタ及びフィールドを連結しそしてｍａｓエレメントを剥離することにより構成された「ｃａｍｅｌＢａｃｋ」切り刻みネームである。例えば、
<xsd:keyref name=”contactAccountRef” refer=”accountKey”>
<xsd:selector xpath=”contact”/>
<xsd:field xpath=”@accountId”/>
</xsd:keyref>
<xsd:keyref name=”messageFromRef” refer=”contactEmailKey”>
<xsd:selector xpath=”message”/>
<xsd:field xpath=”from”/>
</xsd:keyref>
<xsd:keyref name=”messageToRef” refer=”contactEmailKey”>
<xsd:selector xpath=”message/to”/>
<xsd:field xpath=”.”/>
</xsd:keyref>
【０１４７】
タイプは、通常、ネームの最後の部分から推測できることに注意されたい。というのは、これは、ＸＭＬガイドラインに続いて、含まれたデータの目的を説明しなければならないエレメント又は属性ネームだからである。
フレームワークは、ｋｅｙｒｅｆネームが最上位レベルエレメント属性ネームと衝突しないことを保証できる。
【０１４８】
エイリアス
ｋｅｙｒｅｆ宣言は、データグラフ内のノードとノードとの間のリーガルトラバースを定義することができる。＠＠演算子は、グラフをトラバースするのに使用できると共に、デフォールトにより、ｋｅｙｒｅｆネームを使用する。しかしながら、エイリアスは、コードを読み易くするように定義されてもよい。
【０１４９】
ｍａｓ：ａｌｉａｓ属性は、任意に２つの部分を有するストリングを定義する。
mas:alias=”[XPath:]name”
ここで、ｎａｍｅは、エイリアスネームを表わし、そして任意のＸＰａｔｈプレフィックスは、＠＠演算子及びエイリアスネームの前に入らねばならないＳＰａｔｈ（グラフに対する）を表わす。即ち、
var refNode = srcNode.SPath.@@name
【０１５０】
コロンのデリミッターが存在しない場合には、エイリアスＸＰａｔｈプレフィックスがｋｅｙｒｅｆのセレクタＸＰａｔｈと同じである。エイリアスが定義されない場合には、ｋｅｙｒｅｆネームを使用しなければならない（ｋｅｙｒｅｆセレクタＸＰａｔｈに対して）。
【０１５１】
又、キー定義は、関連ｎｏｄｅｔｙｐｅを含むｎｏｄｅｓｅｔがルートノードからトラバースできることを指示するｍａｓ：ａｌｉａｓ属性を宣言してもよい。キー定義に対するエイリアスネームは、簡単なストリングであり、これも＠＠演算子により使用される。
ｍａｓｓ：ａｌｉａｓ＝‘ｎａｍｅ’
【０１５２】
例
次のＸＭＬは、アカウントノードのインスタンスを表わす。
<account id=”1.1” type=”Web” ownerId=”bob”>
<name>Acme</name>
<events>
<eventRef>1.2</eventRef>
<eventRef>1.3</eventRef>
</events>
<purchaseOrders>
<purchaseOrder>
<lineItem><prodId>ABC-1234</prodId></lineItem>
<lineItem><prodId>XYZ-4321</prodId></lineItem>
</purchaseOrder>
</purchaseOrders>
</account>
【０１５３】
アカウントノードに対するキー定義は、次の通りである。
<xsd:key name=”accountKey” mas:alias=”accounts”>
<xsd:selector xpath=”account ”/>
<xsd:field xpath=”@id”/>
</xsd:key>
【０１５４】
これは、次のナビゲーションシンタックスを許す。
var accounts = $root.@@accounts.*;
「製品」エイリアスは、次のように定義される。
<xsd:keyref name=”accountProductsRef” refer=”productKey” mas:alias=”product”>
<xsd:selector xpath=”account/purchaseOrders/purchaseOrder/lineItem”/>
<xsd:field xpath=”prodId”/>
</xsd:keyref>
【０１５５】
次の表現は、第１購入注文の第１ラインアイテムにより参照される製品へとトラバースする。
var product = account.purchaseOrders.*[0].lineItems.*[0].@@product;
「所有者」エイリアスは、次のように定義される。
<xsd:keyref name=”accountOwnerRef” refer=”UserKey” mas:alias=”owner”>
<xsd:selector xpath=”account”/>
<xsd:field xpath=”@ownerId”/>
</xsd:keyref>
【０１５６】
次の表現は、「所有者」エイリアスにより記述されるｋｅｙｒｅｆにより参照されるユーザノードへトラバースする。
var user = account.@@owner;
「事象」エイリアスは、次のように定義される。
<xsd:keyref name=”accountEventsRef” refer=”eventKey” mas:alias=”events”>
<xsd:selector xpath=”account/events/eventRef”/>
<xsd:field xpath=”.”/>
</xsd:keyref>
【０１５７】
次の表現は、「事象」エイリアスにより記述されたｋｅｙｒｅｆにより参照される全ての事象ノードへトラバースする。
var events = account.@@events.*;
「製品」エイリアスも、次のように定義できることに注意されたい。
<xsd:keyref name=”accountProductsRef” refer=”productKey”
mas:alias=”account:products”>
<xsd:selector xpath=”account/purchaseOrders/purchaseOrder/lineItem”/>
<xsd:field xpath=”prodId”/>
</xsd:keyref>
【０１５８】
次の表現は、全てのラインアイテムに対する全ての製品へトラバースする（全ての購入注文に対して）。
var products = account.@@products.*;
逆の関係
ｋｅｙｒｅｆ宣言は、逆方向のナビゲーションを可能にする逆ｋｅｙｒｅｆを任意に定義することができる。通常、多対１のｋｅｙｒｅｆは、逆の１対多のトラバーサルを可能にする逆ｋｅｙｒｅｆを宣言する。
<xsd:keyref name=”name” refer=”keyName” mas:alias=”alias”
mas:inverseAlias=”inverseAlias”>
【０１５９】
逆の属性は、次のように定義される。
2007524933.tif 000005
例えば、以下のｋｅｙｒｅｆ定義は、ｃｏｎｔａｃｔ→ａｃｃｏｕｎｔ及びａｃｃｏｕｎｔ→ｃｏｎｔａｃｔ関係を表わす。
<xsd:keyref name=”contactAccountRef” refer=”accountKey” mas:alias=”account”
mas:inverseAlias=”contacts”>
<xsd:selector xpath=”contact”/>
<xsd:field xpath=”@accountId”/>
</xsd:keyref>
【０１６０】
各コンタクトノードは、ａｃｃｏｕｎｔノードを参照する＠ａｃｃｏｕｎｔＩｄ属性（外部キー）を含む。即ち、
var account = contact.@@accountId;
逆の関係は、外部キーを使用してアカウントノードからコンタクトノードへトラバースできることを示す。即ち、
var contacts = account.@@contacts.*;
【０１６１】
一実施形態において、逆のエイリアス属性は、属性ネーム（上記ｋｅｙｒｅｆエイリアスを参照）しか含んではならず、そして常に、最上位レベルノードに対するものとなる。
多数のｋｅｙｒｅｆ定義は、同じｎｏｄｅｔｙｐｅに「戻るように指す」逆の関係を宣言してもよいことに注意されたい。これらの場合に、逆のエイリアスは、当然、ターゲットｎｏｄｅｔｙｐｅに対して独特のものでなければならない。例えば、ｂｕｇノードは、ｂｕｇｓ及びａｓｓｉｇｎｅｄＢｕｇｓの逆のエイリアスを各々定義するｏｗｎｅｒ及びａｓｓｉｇｎｅｄＴｏに対するｋｅｙｒｅｆを有してもよい。
【０１６２】
又、逆の関係は、両方向におけるナビゲーションがキャッシュ内で一貫したものとなるようにフレームワークが保証することも許す。
ルートｋｅｙｒｅｆ
外部キーの値に依存しないノード間の関係を定義することができる。例えば、現在ユーザ情報又は他の外部情報（例えば、日時、リアルタイムデータ、外部システム状態）を使用する問合せにより１組のノードを定義することができる。これらの場合に、ｎｏｄｅｓｅｔをデータモデル内の任意のｎｏｄｅｔｙｐｅにアタッチすることができる。しかしながら、通常、これらのｎｏｄｅｓｅｔは、ルートノードにアタッチされる。
【０１６３】
ＣＲＭ実施例では、特定のユーザにアクセスできるアカウントのセットを、システム変数＄ｕｓｅｒ／ｕｓｅｒｎａｍｅにより定義されたユーザログインネームで定義することができる。アプリケーションは、ルートノードからこのｎｏｄｅｓｅｔへのトラバースを定義することを望む。即ち、
var accounts = $root.@@accounts.*;
【０１６４】
ルートノードを参照する各アカウントノードに対して任意の人為的外部キー値が定義される。これは、次のｋｅｙｒｅｆ定義により達成される。
<xsd:keyref name=”accountRootRef” refer=”mas:rootKey”
mas:inverseAlias=”accounts”>
<xsd:selector xpath=”account”/>
<xsd:field xpath=”@rootId”/>
</xsd:keyref>
【０１６５】
又、アカウントスキーマは、検証されるべきｋｅｙｒｅｆに対して任意の＠ｍａｓ：ｒｏｏｔＩｄ属性も定義しなければならないことに注意されたい。
<xsd:complexType name=”accountType”>
<xsd:all>
<xsd:element name=”name” type=”xsd:string”/>
<xsd:element name=”type” type=”xsd:string”/>
</xsd:all>
<xsd:attribute name=”id” type=”xsd:string” use=”required” mas:type=”pkey”/>
<xsd:attribute name=”ownerId” type=”xsd:string”/>
<xsd:attribute name=”parentId” type=”xsd:string”/>
<xsd:attribute name=”rootId” type=”mas:rootId” use=”optional”/>
</xsd:complexType>
【０１６６】
＠ｍａｓ：ｒｏｏｔＩｄ属性は、フレームワークにより定義されたシステム定義を参照し、システムのスキーマ定義は、次のディレクティブによりアプリケーションのスキーマにインポートされる。
<xsd:import namespace=”urn:bea.mas” schemaLocation=”mas.xsd”/> 
【０１６７】
＠＠演算子
ナビゲーションは、ページフロー内であるページから次のページへ移動するアクションである。これは、＄ｃｏｎｔｅｘｔシステム変数を変化してもよいし、しなくてもよい。
トラバースは、データグラフ（キャッシュ）内を移動するアクションである。ＳＰａｔｈ表現は、例えば、＠＠演算子を使用してグラフを「トラバース」する。
foo.@@bar
但し、ｆｏｏは、ノード（又はノードの子エレメント）を表わし、そしてｂａｒは、ｋｅｙｒｅｆ定義（ネーム又はエイリアス）又はキーエイリアスにより外部キーであると定義された子エレメントのネームである。
【０１６８】
例えば、次のデータを有すると仮定する。
<account id=”1.1” type=”Web”>
<name>Acme</name>
<contacts>
<contactRef>1.2</contactRef>
<contactRef>1.3</contactRef>
</contacts>
<purchaseOrders>
<purchaseOrder>
<lineItem @prodId=”ABC-1234”/>
<lineItem @prodId=”XYZ-3000”/>
<lineItem @prodId=”EOW-2004”/>
</purchaseOrder>
<purchaseOrder>
<lineItem @prodId=”XYZ-3000”/>
</purchaseOrder>
</purchaseOrders>
</account>
<contact id=”1.2” accountId=”1.1”>
<email>bob@acme.com</email>
</contact
<product id=”ABC-1234”>
<price>1000.00</price>
</product>
次のｋｅｙｒｅｆ定義：
<xsd:keyref name=”accountContactsRef” refer=”contactPrimaryKey”
mas:alias=”.:contacts”>
<xsd:selector xpath=”account/contacts/contactRef”/>
<xsd:field xpath=”.”/>
</xsd:keyref>
<xsd:keyref name=”accountProductsRef” refer=”productKey”
mas:alias=”purchaseOrders/purchaseOrder/lineItem:product”>
<xsd:selector xpath=”account/purchaseOrders/purchaseOrder/lineItem”/>
<xsd:field xpath=”@prodId”/>
</xsd:keyref>
【０１６９】
エイリアスを使用しないと、次の表現が有効となる。
var contacts = account.contacts.*.@@contactRef;
var price = account.purchaseOrders.*[0].lineItems.*[0].@@(@prodId).price;
【０１７０】
サインエイリアスは、次の表現を許す。
var contacts = account.@@contacts.*;
var email = account.@@contacts[0].email;
var price = account.purchaseOrders.*.lineItems.*[0].@@product.price;
【０１７１】
キー及びシーケンスナンバー
データモデルにおいてノードとして表わすことのできる全ての外部レコードは、独特の一次キー（ｐｋｅｙ）を定義しなければならず、即ち一次キーは、ウェブサービスＳＯＡＰインターフェイスの一部分として露出されねばならない。一実施形態では、一次キーは、全てのユーザに対しオペレーション呼び出しにわたって一貫したものとなる。というのは、ある場合に、フレームワークが、１人のユーザにより得たデータを共有キャッシュに配置できるからである。
【０１７２】
外部システムのウェブサービスオペレーションは、任意であるが、特定ノードに関連したシーケンスナンバー（ｓｅｑ）を返送してもよく、これは、システムが更新されたレコードを検出できるようにする。通常、シーケンスナンバーは、データベースタイムスタンプに対応する。ウェブサービスがシーケンスナンバーを与えない場合には、フレームワークが、レコードのＸＭＬ値に基づいてＭＤ５ハッシュを計算する。
【０１７３】
スキーマ定義は、外部アプリケーション識別子と、任意であるが、シーケンスナンバー（又はタイムスタンプ）とを定義するエレメントを定義することができる。それに対応するスキーマエレメントは、システムプロパティ「ｐｋｅｙ」又は「ｓｅｑ」を示すｍａｓ：ｔｙｐｅ属性を定義する。
【０１７４】
例えば、次のスキーマは、アプリケーションコンタクトタイプを定義する。
<xsd:complexType name=”contactType”>
<xsd:all>
<xsd:element name=”first” type=”xsd:string”/>
<xsd:element name=”last” type=”xsd:string”/>
<xsd:element name=”email” type=”xsd:string”/>
</xsd:all>
<xsd:attribute name=”id” type=”xsd:string” use=”required” mas:type=”pkey”/>
<xsd:attribute name=”timestamp” type=”xsd:string” mas:type=”seq”/>
<xsd:attribute name=”ownerId” type=”xsd:string” use=”required”/>
<xsd:attribute name=”accountId” type=”xsd:string” use=”required”/>
</xsd:complexType>
【０１７５】
このスキーマは、一次キー及びシーケンスナンバーを各々表わす属性＠ｉｄ及び＠ｔｉｍｅｓｔａｍｐを定義する。例えば、次のＸＭＬは、コンジットにより返送されるコンタクトノードのインスタンスを表わす。
<app:contact id=”83FEB4C38AB36520” timestamp=”12388832”
accountId=”B3F234AD3342ABA6”>
<app:first>Bob</app:first>
<app:last>Harris</app:last>
<app:email>bob@harris.com</app:email>
</app:contact>
【０１７６】
又、スキーマは、適当なキー定義を含むことができ、例えば、次の通りである。
<xsd:key name=”contactPrimaryKey”>
<xsd:selector xpath=”contact”/>
<xsd:field xpath=”id”/>
</xsd:key>
<xsd:key name=”contactEmailKey”>
<xsd:selector xpath=”contact”/>
<xsd:field xpath=”email”/>
</xsd:key>
【０１７７】
ｍａｓ：ｔｙｐｅ＝「ｐｋｅｙ」スキーマエレメント宣言は、ノードに対する一次キーを識別するために必要とされることに注意されたい。
キーの値は長くてもよいので、デフォールトにより、これらの値は、クライアントにも送信されないし、クライアントプログラミングモデルによりアクセスされることもない。ｍａｓ：ｖｉｓｉｂｌｅ属性は、このデフォールト振舞いを抑制するように指定されてもよい。
【０１７８】
スキーマ修飾を以下に示す。
2007524933.tif 000006
【０１７９】
ｋｅｙ（ｋｅｙｒｅｆではなく）フィールドが可視としてマークされない場合には、クライアントのフィールドにアクセスする試みがナルとなる（不存在のフィールドがアクセスされたかのように）。たとえ可視であっても、キーフィールドは読み取りのみである。
var x = contact.id;          // returns null
var y = cont
【０１８０】
一次キー及びシーケンスナンバー値は、外部システムによりセットされる。キーであると定義されるフィールドと同様に、フィールドの値を変更する試みは、ランタイムエラーを発生する。新たなノードを生成するときに、これらフィールドが含まれてはならない。例えば、
var contact =
<contact>
<first>Maggie</first>
<last>Cheung</last>
<email>maggie@acme.com</email>
</contact>
【０１８１】
参照による外部キーの指定
外部キーの値は、指定によりセットすることができる。指定表現のＲＨＳがノードに対して評価する場合、これは、ノードの一次キーへと自動的に強制される。
以下に実施例では、コンタクトノードのアカウント外部キー（アカウントｋｅｙｒｅｆ定義によりアカウント属性となるように定義される）が、供給されたアカウントノードを参照するようにセットされる。
function setAccount(contact, account)
contact.@@accountId = account;
}
【０１８２】
値による外部キーの指定
ｋｅｙｒｅｆ定義により参照されるスキーマがｍａｓ：ｖｉｓｉｂｌｅ一次キーを宣言する場合に、それに対応する外部キー値は、文字通りの値（即ち、ノード参照ではない）によってセットされてもよい。
例えば、次のアカウントスキーマは、可視ｐｋｅｙ属性を定義する。
<xsd:complexType name=”accountType”>
<xsd:complexContent>
<xsd:all>
<xsd:element name=”name” type=”xsd:string”/>
</xsd:all>
<xsd:attribute name=”id” type=”xsd:string” use=”required”
mas:type=”pkey” mas:visible=”true”/> 
<xsd:attribute name=”ownerId” type=”xsd:string” use=”required”/>
<xsd:attribute name=”parentId” type=”xsd:string”/>
</xsd:complexContent>
</xsd:complexType>
【０１８３】
それ故、アプリケーションは、値に直接アクセスしてもよい。
var account = account.@@id;
又、値によりアカウントノードを参照する外部キーをセットしてもよく、例えば、
function setAccount(contact)
contact.@@account = ”A-1234”;
}
【０１８４】
外部キー値は、クライアントに現在キャッシュ記憶されているノードに分解されなくてよいことに注意されたい。更に、不良値がセットされた場合には、それに関連したコンジットオペレーションがフェイルするはずである。
関係
多対１（ルックアップ）
多対１の関係は、関係一次及び外部キーを並行して生じるｋｅｙ及びｋｅｙｒｅｆ定義を使用して実施することができる。
<xsd:key name=”accountKey”>
<xsd:selector xpath=”account”/>
<xsd:field xpath=”@id”/>
</xsd:key>
<xsd:keyref name=”contactAccountRef” refer=”accountKey”>
<xsd:selector xpath=”contact”/>
<xsd:field xpath=”@accountId”/>
</xsd:keyref>
【０１８５】
このキー定義は、ａｃｃｏｕｎｔＫｅｙ（一次キー）が各＜ａｃｃｏｕｎｔ＞ノードにおいてｉｄと称する属性として生じることを示す。ｋｅｙｒｅｆ定義は、ｃｏｎｔａｃｔＡｃｃｏｕｎｔＲｅｆ（外部キー）が＜ｃｏｎｔａｃｔ＞ノードのａｃｃｏｕｎｔ属性を参照することを示す。
例えば、次のインスタンスデータが与えられる。
<account id=”1.1”>
<name>Acme</name>
</account>
<contact id=”1.2” accountId=”1.1”>
<first>Bob</first>
<last>Harris</last>
<email>bob@acme.com</email>
</contact>
【０１８６】
次は、アカウントに対する一次キー（即ち、ａｃｃｏｕｎｔＫｅｙ）を定義する。
<account id=”1.1”>
次は、コンタクトから同じアカウントへの外部キー（即ち、ｃｏｎｔａｃｔＡｃｃｏｕｎｔＲｅｆ）を定義する。
<contact id=”1.2” accountId=”1.1”>
【０１８７】
時々、ノード内に含まれたデータを外部キー値として使用することを希望する。例えば、ＣＲＭ実施例を拡張して、コンタクトに関連したｅメールメッセージを含むようにする。以下のスキーマは、メッセージノードを記述するもので、これは、ｆｒｏｍ及びｔｏエレメントにより表わされた２つの「自然」外部キーを含む（各メッセージは、多数のｔｏエレメントを有してもよいことに注意されたい）。
<xsd:complexType name=”messageType”>
<xsd:sequence>
<xsd:element name=”from” type=”xsd:string” minOccurs=”1” maxOccurs=”1”/>
<xsd:element name=”to” type=”xsd:string” maxOccurs=”unbounded”/>
<xsd:element name=”subject” type=”xsd:string”/>
<xsd:element name=”body” type=”xsd:string”/>
</xsd:sequence>
</xsd:complexType>
【０１８８】
コンタクトエレメントがｅｍａｉｌエレメントを含むことは既に定義した。
<xsd:complexType name=”contactType”>
<xsd:all>
<xsd:element name=”first” type=”xsd:string”/>
<xsd:element name=”last” type=”xsd:string”/>
<xsd:element name=”email” type=”xsd:string”/>
</xsd:all>
<xsd:attribute name=”id” type=”xsd:string” use=”required” mas:type=”pkey”/>
<xsd:attribute name=”ownerId” type=”xsd:string” use=”required”/>
<xsd:attribute name=”accountId” type=”xsd:string” use=”required”/>
</xsd:complexType>
【０１８９】
コンタクトタイプは、一次キーを予め定義する。
<xsd:key name=”contactPrimaryKey”>
<xsd:selector xpath=”contact”/>
<xsd:field xpath=”@id”/>
</xsd:key>
【０１９０】
以下のキー定義は、コンタクトノード内のｅｍａｉｌエレメントがキーとして使用されてもよいことを定義する。
<xsd:key name=”contactEmailKey”>
<xsd:selector xpath=”contact”/>
<xsd:field xpath=”email”/>
</xsd:key>
【０１９１】
次のｋｅｙｒｅｆ定義は、メッセージノード内の２つの外部キーエレメントを定義する。
<xsd:keyref name=”messageFromRef” refer=”contactEmailKey”>
<xsd:selector xpath=”message”/>
<xsd:field xpath=”from”/>
</xsd:keyref>
<xsd:keyref name=”messageToRef” refer=”contactEmailKey”>
<xsd:selector xpath=”message/to”/>
<xsd:field xpath=”.”/>
</xsd:keyref>
【０１９２】
ｍｅｓｓａｇｅＦｒｏｍＲｅｆのｋｅｙｒｅｆは、次のように書くこともできる（が、フレームワークは、常に、上記形態を使用し、即ち、ｍｅｓｓａｇｅＴｏＲｅｆは、多数の＜ｔｏ＞エレメントが存在し得るので、上記形態で書かねばならない）ことに注意されたい。
<xsd:keyref name=”messageFromRef” refer=”contactEmailKey”>
<xsd:selector xpath=”message/from”/>
<xsd:field xpath=”.”/>
</xsd:keyref>
【０１９３】
１対多（集合）
１対多の関係は、逆ｋｅｙｒｅｆとして実施することもできるし、又はデータノード内に含まれたマニフェスト外部キー値として実施することもできる。
逆Ｋｅｙｒｅｆ
全ての多対１トラバースは、１対多のトラバースを定義する逆ｋｅｙｒｅｆを宣言してもよい。
【０１９４】
マニフェストＫｅｙｒｅｆ
あるｎｏｄｅｔｙｐｅのスキーマ宣言は、外部キー値を各々含むエレメントの中継シーケンスを含む複雑なＸＭＬ文書を定義してもよい。
例
以下のスキーマ定義は、購入注文エンティティを記述する。
<xsd:element name=”purchaseOrder” type=”purchaseOrderType”>
<xsd:complexType name=”purchaseOrderType”>
<xsd:sequence>
<xsd:element name=”price” type=”xsd:double”/>
...
<xsd:complexType name=”lineItems”>
<xsd:sequence maxOccurs=”unbounded”>
<xsd:complexType ref=”lineItem”>
<xsd:sequence>
<xsd:element name=”prodId” type=”xsd:string”/>
...
</xsd:sequence>
</xsd:complexType>
</xsd:sequence>
</xsd:complexType>
</xsd:sequence>
<xsd:attribute name=”id” type=”xsd:string” mas:type=”pkey”/>
</xsd:complexType>
【０１９５】
以下のキー宣言は、購入注文ｎｏｄｅｔｙｐｅに対して一次キーを定義する。
<xsd:key name=”purchaseOrderKey”>
<xsd:selector xpath=”purchaseOrder”/>
<xsd:field xpath=”id”/>
</xsd:key>
以下のｋｅｙｒｅｆ宣言は、製品を参照する外部キーである購入注文内のエレメントを識別する。
<xsd:keyref name=”purchaseOrderProductRef” refer=”productKey” 
mas:alias=”purchaseOrder:products”>
<xsd:selector xpath=”purchaseOrder/lineItems/lineItem”/>
<xsd:field xpath=”prodId”/>
</xsd:keyref>
【０１９６】
この関係は、図１２Ａにより説明することができる。例えば、次のＸＳｃｒｉｐｔ表現は、購入注文の第１ラインアイテムにより参照される製品を検索する。
var product = purchaseOrder.@@products.*;
多対多
多対多の関係は、１対多の関係の対として実施される。その一例が図１２Ｂに示されている。
即ち、アカウント及び事象は、次のスキーマを宣言する。
<xsd:complexType name=”accountType”>
<xsd:all>
<xsd:element name=”name” type=”xsd:string”/>
</xsd:all>
<xsd:attribute name=”id” type=”xsd:string” use=”required” mas:type=”pkey”/>
<xsd:attribute name=”ownerId” type=”xsd:string” use=”required”/>
<xsd:attribute name=”parentId” type=”xsd:string”/>
</xsd:complexType>o0
<xsd:complexType name=”eventType”>
<xsd:all>
<xsd:element name=”first” type=”xsd:string”/>
<xsd:element name=”last” type=”xsd:string”/>
</xsd:all>
<xsd:attribute name=”id” type=”xsd:string” use=”required” mas:type=”pkey”/>
</xsd:complexType>
【０１９７】
次のｋｅｙｒｅｆ定義を宣言する。
<xsd:keyref name=”accountEventRef” refer=”eventKey”>
<xsd:selector xpath=”account”/>
<xsd:field xpath=”events”/>
</xsd:key>
<xsd:keyref name=”eventAccountRef” refer=”accountKey”>
<xsd:selector xpath=”event”/>
<xsd:field xpath=”accounts”/>
</xsd:keyref>
【０１９８】
一実施形態において、多対多ｋｅｙｒｅｆは、逆ｋｅｙｒｅｆを宣言することができない。というのは、一般に、フレームワークが、一貫性を維持するに充分な情報をもたないからである。
１対１
一実施形態において、１対１の関係は、対にされた多対１の関係として実施される。
例
又、システムの各ユーザは、図１２Ｃに示すコンタクトレコードも有すると仮定する。
即ち、コンタクト及びユーザは、次のｋｅｙｒｅｆを定義する。
<xsd:keyref name=”userContactRef” refer=”contactKey” mas:alias=”contact”
mas:inverseAlias=”user”>
<xsd:selector xpath=”user”/>
<xsd:field xpath=”@contactId”/>
</xsd:key>
１対１のｋｅｙｒｅｆは、常に、逆ｋｅｙｒｅｆを宣言しなければならない。
var contact = user.@@contact;
contact.@@user == user;
【０１９９】
システムデータタイプ
ノードスキーマ定義
次のＸＭＬスキーマは、ノードの構造を定義する。
<?xml version=”1.0”?>
<xsd:schema targetNamespace=”urn:bea.mas”
elementFormDefault=”qualified” attributeFormDefault=”unqualified”
xmlns:xsd=”http://www.w3.org/2001/XMLSchema”
xmlns=”urn:bea.mas”>
<xsd:element name=”nodeType”>
<xsd:complexType>
<xsd:sequence>
<xsd:any minOccurs=”0” maxOccurs=”1”/>
</xsd:sequence>
<xsd:attribute name=”state” type=”mas:syncStateType”/>
</xsd:complexType>
</xsd:element>
【０２００】
ノード定義は、次の属性を含んでもよい。
2007524933.tif 000007
【０２０１】
ルートノード
一実施形態において、各アプリケーションに対して、ｎｏｄｅｔｙｐｅ  ｍａｓ：ｒｏｏｔをもつ特殊なルートノードがあり、このノードは、アプリケーションデータを含まず、そして変更されることがない。フレームワークは、＄ｒｏｏｔ変数を経て参照されるルートノードのインスタンスを自動的に生成する。ｋｅｙｒｅｆは、ｍａｓ：ｒｏｏｔをそれらのソースタイプとして参照してもよく、例えば、次の通りである。
<keyref name=”accounts” sourceType=”mas:root” targetType=”app:contact”/>
【０２０２】
一実施形態では、ノードは、クライアントプログラミングによりインスタンス生成されてもよいし又はサーバーコンジットによりインスタンス生成されてもよい。
ｎｏｄｅｓｅｔスキーマ定義
ルートノードはさておき、全てのノードは、ｋｅｙｒｅｆに対応するｎｏｄｅｓｅｔに属する。ｎｏｄｅｓｅｔは、次のＸＭＬスキーマにより定義される。
<?xml version=”1.0”?>
<xsd:schema targetNamespace=”run:bea.com”
elementFormDefault=”qualified” attributeFormDefault=”unqualified”
xmlns:xsd=”http://www.w3.org/2001/XMLSchema”
xmlns=”run:bea.com”>
<xsd:element name=”nodeSet”>
<xsd:complexType>
<xsd:sequence>
<xsd:element ref=”node” maxOccurs=”unbounded”/>
</xsd:sequence>
<xsd:attribute name=”keyref” type=”xsd:string”/>
</xsd:complexType>
</xsd:element>
【０２０３】
＜ｎｏｄｅｓｅｔ＞エレメントは、＜ｎｏｄｅ＞エレメントのアンバウンドシーケンスを含む。各ｎｏｄｅｓｅｔは、コンテインズ・ノードエレメント(the contains node elements)のｎｏｄｅｔｙｐｅを決定するｋｅｙｒｅｆ（ｋｅｙｒｅｆ属性により定義される）に対応する。
同期状態
全ての持続性アプリケーションデータは、サーバーで同期されるノードに記憶することができる。各データノードは、ｓｙｎｃＳｔａｔｅＴｙｐｅタイプにより定義される値を有する状態同期属性ｍａｓ：ｓｔａｔｅをもつことができる。
<xsd:simpleType name=”syncStateType”>
<xsd:restriction base=”xsd:string”>
<xsd:enumeration value=”dsync”/>
<xsd:enumeration value=”modified”/>
<xsd:enumeration value=”pending”/>
<xsd:enumeration value=”uptodate”/>
<xsd:enumeration value=”rejected”/>
<xsd:enumeration value=”conflict”/>
<xsd:enumeration value=”deleted”/>
</xsd:restriction>
</xsd:simpleType>
【０２０４】
状態変数は、同期を整合するためにクライアントとサーバーとの間に通すことができる。クライアントは、ノード状態を次の値の１つにセットする。
2007524933.tif 000008
一実施形態において、状態変数は、生成されたノードと変更されたノードとの間を区別しないことに注意されたい。というのは、これは、ゼロのグローバルシーケンスナンバーにより区別できるからである。
【０２０５】
同期プロセスは、対応するコンジットオペレーションをトリガーし、完了時に、サーバーは、各ノードに、次の値の１つを指定する。
2007524933.tif 000009
【０２０６】
例えば、次のテーブルは、ノードの考えられるライフサイクルを示す。
2007524933.tif 000010
【０２０７】
コンジット
一実施形態において、クライアントアプリケーションは、ウェブサービスオペレーションを直接コールせず、むしろ、コンジットメカニズムが、個々の（限定された）ウェブサービスオペレーションのセマンティックスを、クライアントの仮想ＸＭＬ文書に対してプログラミングモデルへマップする（例えば、ＣＲＵＤセマンティックス（生成、読み取り、更新、削除）、ナビゲーション、顧客オペレーション等）。クライアントデータモデルの変化は、サーバーに対して同期され、サーバーは、次いで、コンジットマネージャーをトリガーして、外部のウェブサービスオペレーションを呼び出す。
【０２０８】
一実施形態において、コンジットは、特定のｋｅｙｒｅｆに対して整合された１組のウェブサービスオペレーションを定義する。各ｋｅｙｒｅｆには、厳密に１つのコンジットを関連付けることができる。ウェブサービスは、データベース、ＬＤＡＰディレクトリー、ＥＲＰアプリケーション、及びウェブサイトのような既存のシステムへのインターフェイスでよい。又、それらは、手順ロジック（例えば、ＷＬＩ  ＪＰＤ）により整合された複雑な長時間実行の非同期プロセス（ワークフロー）を要約するラッパーでもよい。
【０２０９】
一実施形態において、システムにより利用されるウェブサービスは、幾つかの要件（例えば、各レコードは、独特の一次キー、及び理想的には、シーケンスナンバー又はタイムスタンプを含まねばならない）を有するが、随時接続データモデル特有の要件は課せられない。それ故、ＭＡＳは、これらリソースの多数の消費者の１つでよい。
【０２１０】
一実施形態において、コンジットは、ウェブサービスがデータモデルと共に記憶書き込みされたと仮定せず、即ち要求へ通されるタイプがデータモデルにおけるｎｏｄｅｔｙｐｅと同形でなく、そして応答も異なることがある。それ故、ウェブサービス要求及び応答により使用されるスキーマは、データモデルにおけるノードのスキーマと同じである必要はない。
【０２１１】
コンジットは、ウェブサービスオペレーション呼び出しに対してデータモデルから要求文書へマップすると共に、ウェブサービス応答からデータモデルへマップして戻すためのメタデータを含むことができる。これらメタデータは、変換として知られており、ＸＭＬ問合せ言語で表現することができる。実際に、変換モデルは、データモデルにおける多数の異なる関係ノードへとマップし且つデータモデルへ首尾良くマップして戻るような応答文書をウェブサービスが返送できるのに一般的に充分である。
【０２１２】
ＭＡＳキャッシュにとって重要なメタデータ（即ち、レコードタイプの一次キー及びシーケンスナンバー／タイムスタンプ）も、変換を使用してマップすることができる。
コンジットフローの概要
ｃｏｎｄｕｉｔｓサブディレクトリーは、多数の．ｊｓｘファイルを含むことができ、それらは全て始動時にフレームワークによりロードされ、これらのファイルは、コンジット定義を含む。コンジットファイルは、コンジットオペレーションを実施するＸＳｃｒｉｐｔ及びＸＱｕｅｒｙファンクションで構成することができ、又、これらファイルは、コメントブロックで定義されたメタデータも含むことができる。注釈モデルは、デベロッパが視覚ツール及びスクリプトエディタの両方を使用してコンジットファイルを構築できるようにする。
【０２１３】
各コンジットファイルは次のタグを宣言できるヘッダーコメントを含むことができる。
2007524933.tif 000011
例：
/**
* @mas:conversational shared=”false”
* @common:xmlns namespace=”http://schemas.xmlsoap.org/soap/envelope/” prefix=”soap”
* @common:xmlns namespace=”urn:partner.soap.sforce.com” prefix=”sfdc”
* @common:xmlns namespace=”http://example.com/” prefix=”app”
*/
【０２１４】
ｍａｓ：ｃｏｎｖｅｒｓａｔｉｏｎａｌ
ｍａｓ：ｃｏｎｖｅｒｓａｔｉｏｎａｌタグは、次の属性を有する。
2007524933.tif 000012
ｃｏｍｍｏｎ：ｘｍｌｎｓ
ｃｏｍｍｏｎ：ｘｍｌｎｓタグは、次の属性を有する。
2007524933.tif 000013
【０２１５】
ウェブサービスコントロール
又、コンジットファイルは、ウェブサービスコントロールを表わす（おそらく多数の）オブジェクト宣言も含む。コントロール定義は、対応する変数宣言の直前でヘッダーブロックに現われる。
例
/**
* @common:control
* @jc:location http-url=”http://enterprise.soap.sforce.com/”
*/
ws = new WebServiceControl();
次のタグが定義される。
2007524933.tif 000014
ｊｃ：ｌｏｃａｔｉｏｎ
ｊｃ：ｌｏｃａｔｉｏｎタグは、次の属性を有する。
2007524933.tif 000015
ＷｅｂＳｅｒｖｉｃｅＣｏｎｔｒｏｌオブジェクトは、ウェブサービスオペレーションの呼び出しをマネージする。
【０２１６】
ＷｅｂＳｅｒｖｉｃｅＣｏｎｔｒｏｌオブジェクトは、次のメソッドを実施する。
2007524933.tif 000016
メッセージオブジェクト
メッセージオブジェクトは、ウェブサービスコントロールのｉｎｖｏｋｅ（）ファンクションへ通され及びそこから返送される。
var. Response = control. Invoke (message);
メッセージオブジェクトは、次のプロパティを有する。
2007524933.tif 000017
【０２１７】
例えば、次のＳＯＡＰメッセージがウェブサービスから返送されると仮定する。
<soapenv:Envelope xmlns:SOAP-ENC=”http://schemas.xmlsoap.org/soap/encoding/”
xmlns:soapenv=”http://schemas.xmlsoap.org/soap/envelope/”
xmlns:xsd=”http://www.w3.org/2001/XMLSchema”
xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance”>
<soapenv:Header>
<SessionHeader xmlns=”urn:partner.soap.sforce.com”>
<sessionId>12345678</sessionId>
</SessionHeader>
</soapenv:Header>
<soapenv:Body>
<createResponse xmlns=”urn:partner.soap.sforce.com”>
<result>
<errors xsi:nil=”true”></errors>
<id>87654321</id>
<success>true</success>
</result>
</createResponse>
</soapenv:Body>
</soapenv:Envelope>
【０２１８】
次のファンクションは、最初に、メッセージヘッダーからのセッションエレメント及びメッセージ本体からの結果エレメントをプリントする前にｉｎｖｏｋｅ（）ファンクションによりエラーが発生されなかったことをチェックする。
function select($msg) {
var response = ws.invoke($msg);
if (! response.error) {
print(”Session: ” + response.header.SessoinHeader.sessionId);
print(”ID: ” + response.body.createResponse.result.id);
}
return response;
}
これは、次の出力をログする。
Session: 12345678
ID: 87654321
【０２１９】
オペレーションの定義
コンジットオペレーションは、ウェブサービスオペレーションへ直接マップすることができる。一実施形態では、各コンジットオペレーションは、次の３つのファンクションまで宣言する。
１．要求変換：出て行くメッセージ本体を生成するＸＱｕｅｒｙファンクション；
２．応答変換：到来する応答本体を処理し、コンジットマネージャーにより処理されたＭＡＳノードを生成するＸＱｕｅｒｙファンクション；
３．カスタムファンクション：カスタム手順ロジックを実行する（例えば、メッセージヘッダーを生成し、又はカスタムトランスポート又は他のコントロールを呼び出すために）ＸＳｃｒｉｐｔ（又はＪａｖａ（登録商標。以下同じ。））ファンクション。
【０２２０】
注釈
カスタムファンクションは、ファンクションプロートタイプの直前でヘッダーブロックに注釈も含む。例えば、
/**
* @mas:operation type=”operationType” keyref=”keyrefName” inverse=”true”
* @mas:transform type=”request” function=”foo_request”
* @mas:transform type=”response” function=”foo_response”
*/
function foo($msg, $source) {
return ws.invoke($msg);
}
【０２２１】
カスタムファンクションは、次のタグを宣言できる。
2007524933.tif 000018
【０２２２】
ｍａｓ：ｏｐｅｒａｔｉｏｎ
ｍａｓ：ｏｐｅｒａｔｉｏｎタグは、次の属性を有する。
2007524933.tif 000019
【０２２３】
これらオペレーションは、ｋｅｙｒｅｆ又はスキーマ（ノード）定義のいずれかを参照できる。
@mas:operation type=”operationType” keyref=”keyrefName”
@mas:operation type=”operationType” node=”nodeType”
ｉｎｖｅｒｓｅ属性は、オペレーションが逆のｋｅｙｒｅｆにおいてコールされることを指示する。
@mas:operation type=”operationType” keyref=”keyrefName” inverse=”true”
【０２２４】
例えば、次のｋｅｙｒｅｆ及びｋｅｙ定義が与えられると、
<xsd:keyref name=”contactAccountRef” refer=”accountKey”
mas:alias=”account” mas:inverseAlias=”contacts”>
<xsd:selector xpath=”contact”/>
<xsd:field xpath=”@account”/>
</xsd:keyref>
<xsd:key name=”accountKey”>
<xsd:selector xpath=”account”/>
<xsd:field xpath=”@id”/>
</xsd:key>
<xsd:key name=”contactKey”>
<xsd:selector xpath=”contact”/>
<xsd:field xpath=”@id”/>
</xsd:key>
【０２２５】
コンジットは、次のセレクトオペレーションを実施できる。
/** @mas:operation type=”select” keyref=”app:contactAccountRef” */
function selectAccount($msg, $source) {
return ws.invoke($msg);
}
/** @mas:operation type=”select” keyref=”app:contactAccountRef” inverse=”true” */
funciton selectContacts($msg, $source) {
return ws.invoke($msg);
}
【０２２６】
トラバースｃｏｎｔａｃｔ．＠＠ａｃｃｏｕｎｔは、ｓｅｌｅｃｔＡｃｃｏｕｎｔ（）をコールし、一方、ａｃｃｏｕｎｔ．＠＠ｃｏｎｔａｃｔｓ．＊は、ｓｅｌｅｃｔＣｏｎｔａｃｔｓ（）をコールする。
ｍａｓ：ｔｒａｎｓｆｏｒｍ
ｍａｓ：ｔｒａｎｓｆｏｒｍタグは、次の属性を有する。
2007524933.tif 000020
【０２２７】
フレームワークは、対応する＠ｍａｓ：ｔｒａｎｓｆｏｒｍタグが宣言された場合に、要求及び応答変換を自動的にコールすることができる。要求変換は、＄ｍｓｇ変数の本体を構成するのに使用されるＸＭＬオブジェクトを返送することができる。応答変換は、コンジットオペレーションの応答を処理することができる。
Ｊａｖａでは、要求及び応答の問合せ変換が、カスタムオペレーションのためのコメントブロック（自動的に発生される）内に含まれるか、又は注釈により参照される個別のファイルに含まれる。
【０２２８】
ｍａｓ：ｎａｍｅｓｐａｃｅ
ｍａｓ：ｎａｍｅｓｐａｃｅタグは、ファンクションのためのデフォールトｎａｍｅｓｐａｃｅを宣言し、そして次の属性を有する。
2007524933.tif 000021
【０２２９】
ｍａｓ：ｆｉｅｌｄ
ｍａｓ：ｆｉｅｌｄタグは、ファンクションをコールするのに必要なカスタムソースフィールドを宣言し、次の属性を有する。
2007524933.tif 000022
【０２３０】
発生されたファンクション
カスタムファンクションの本体は、ＷＬＷにより発生される。セレクトオペレーションに対するデフォールト本体は、次の通りである。
/**
* @mas:operation type=”select” keyref=”keyrefName”
*/
function operationTypeSourceType($msg, $source) {
return control.invoke($msg);
}
【０２３１】
＄ｍｓｇ変数は、ＸＭＬメッセージオブジェクトを参照し、マッチング要求変換が宣言された場合に（以下を参照）、メッセージオブジェクトの本体が、問合せにより返送されたＸＭＬオブジェクトから生成される。＄ｓｏｕｒｃｅ変数は、ソースコンテクストノード（例えば、ｎｏｄｅ．＠＠ｋｅｙｒｅｆＮａｍｅ．＊）を含むことができる。
【０２３２】
挿入、更新及び削除オペレーションに対して、デフォールト本体は、次の通りである。
/**
* @mas:operation type=”insert|update|delete” keyref=”keyrefName”
*/
function operationTypeSourceType($msg, $node) {
return ws.invoke($msg);
}
＄ｎｏｄｅ変数は、挿入／更新／削除されるべきノードを含む。
【０２３３】
カスタムオペレーションに対して、本体は、次の通りである。
/**
* @mas:operation type=”custom” node=”nodeName” name=”operationName”
*/
function operationTypeSourceType($msg, $source, $node) {
return ws.invoke($msg);
}
ここで、＄ｎｏｄｅ変数は、カスタムオペレーションをコールするクライアントにより生成された問合せオブジェクトを含む。
【０２３４】
変換
オペレーションは、任意であるが、ｍａｓ：ｔｒａｎｓｆｏｒｍ注釈を使用して要求及び応答変換ファンクションを定義することができる。
例えば、以下のオペレーションは、アカウント識別子（即ち、ｃｏｎｔａｃｔＡｃｃｏｕｎｔＲｅｆにより定義された逆ｋｅｙｒｅｆ）が与えられると、コンタクトを検索するセレクトオペレーションを実施する。
/**
* select contacts for an account: $account.@@contacts.*
* @mas:operation type=”select” keyref=”app:contactAccountRef” inverse=”true”
* @mas:transform type=”request” function=”selectContacts_request”
* @mas:transform type=”response” function=”selectContacts_response”
*/
function selectContacts($msg, $source) {
return ws.invoke($msg);
}
【０２３５】
要求変換は、コンジットオペレーションが呼び出される前にコールすることができ、アウトバウンドメッセージのＸＭＬ本体を返送し、これは、コンジットオペレーションへ通されるメッセージオブジェクト＄ｍｓｇに挿入される。
/**
* @mas:namespace target=”sfdc”
* @language:body type=”xquery”
*/
function selectContacts_request($source) {
<query>
<queryString>
SELECT * FROM Contact
WHERE AccountId = ”{string($source/@id)}”
</queryString>
</query>
}
【０２３６】
応答変換は、コンジットオペレーションが復帰した後にコールすることができる（オペレーションが＜ｅｒｒｏｒ＞オブジェクトを返送しない限り）。サービスコントロールのｉｎｖｏｋｅ（）ファンクションから返送されたＸＭＬメッセージ本体が通される。応答変換は、アプリケーションノードのリストをコンジットマネージャーに返送する。
/**
* @mas:namespace target=”app”
* @language:body type=”xquery”
*/
function selectContacts_response($response) {
for $i in $response/sfdc:queryResponse/sfdc:result/sfdc:records
return
<contact id=”{string($i/sfdc:Id)}” accountId=”{string($i/sfdc:AccountId)}”>
<modified>{string($i/sfdc:SystemModstamp)}</modified>
<fist>{string($i/sfdc:FistName)}</first>
<last>{string($i/sfdc:LastName)}</last>
<email>{string($i/sfdc:Email)}</email>
</contact>
}
【０２３７】
コンジットオペレーションは、応答変換によりサービス応答メッセージの本体が処理される前にそのヘッダー及び本体を操作できることに注意されたい。
コンジットオペレーション
コンジットオペレーションは、ウェブサービスオペレーションをフレームワークオペレーションへマップすることができ、このフレームワークオペレーションがアプリケーションプログラミングモデルへ露出される。
【０２３８】
各オペレーションは、関連ウェブサービスオペレーションから受け取られた及びそこに送信される到来する及び出て行く対応ＸＭＬメッセージをマップする一対の問合せを定義することができる。これらの変換は、（通常）外部システムデータフォーマットから、スキーマにより定義されたＭＡＳアプリケーションデータフォーマットへデータを変換するＸＱｕｅｒｙ表現で構成される。
【０２３９】
オペレーションタイプ
クライアントプログラミングモデルでは、ノード（＄ｒｏｏｔを含む）又はｋｅｙｒｅｆのいずれかにおいてオペレーションを呼び出すことができる。例えば、
$root.create(xml);                        // create node
node.@@keyref.create(xml);                // create and link node
node.@@keyref.*;                          // implicit select
node.@@keyref.select(spath);              // deep select
node.update();                            // update node
$root.foo(xml);                           // custom operation
【０２４０】
オペレーションタイプに基づいて、異なる入力パラメータをコンジットオペレーションへ通すことが要求される。
更新及び削除を除いて、他の全てのオペレーションにはオペレーションのコンテクスト（又はソース）を表わすノード（その一部分）が通される（ｍａｓ：ｆｉｅｌｄ宣言は、ソースノードのどれほど多くがサーバーに転送されるか決定する）。これは、＄ｓｏｕｒｃｅ変数を使用してコンジットファンクションにより参照される。
【０２４１】
更新オペレーション（即ち、挿入、更新及びカスタムオペレーション）の場合に、コンジットオペレーションを呼び出すのに使用されるデータノードが、＄ｎｏｄｅ変数を使用してＸＱｕｅｒｙ変換において参照される。更に、全てのオペレーションは、現在ユーザの情報を含む＄ｕｓｅｒシステム変数への暗示的アクセスを有する。
【０２４２】
コンジットオペレーションに対して以下の入力パラメータが定義される。
2007524933.tif 000023
【０２４３】
以下のテーブルは、特定のコンジットオペレーションに対して定義できる異なるタイプのオペレーションを示す。
2007524933.tif 000024
【０２４４】
変換
各コンジットオペレーションは、関連ウェブサービスオペレーションから受信され及びそれに送信される到来する及び出て行くＸＭＬメッセージに対応するＸＭＬオブジェクトを生成して処理する一対の問合せ（変換）を定義することができる。
【０２４５】
変換ファンクションは、対応するコンジットファンクションにおけるｍａｓ：ｔｒａｎｓｆｏｒｍ注釈を使用して宣言することができる。規定により、変換ファンクションのネームは、＿ｒｅｑｕｅｓｔ及び＿ｒｅｓｐｏｎｓｅサフィックスを伴いコンジットファンクションと同じネームを使用することができる。しかしながら、あるケースでは、応答変換は、多数のコンジットオペレーションにより再使用されてもよい。
変換は、ＸＱｕｅｒｙ（ＸＭＬ  Ｑｕｅｒｙ）ファンクションとして実施することができる。
【０２４６】
例
次のオペレーションは、アカウント識別子（即ち、ｃｏｎｔａｃｔＡｃｃｏｕｎｔＲｅｆにより定義された逆ｋｅｙｒｅｆ）が与えられると、コンタクトを検索するセレクトオペレーションを実施する。
/**
* select contacts for an account: $account.@@contacts.*
* @mas:operation type=”select” keyref=”app:contactAccountRef” inverse=”true”
* @mas:transform type=”request” function=”selectContacts_request”
* @mas:transform type=”response” function=”selectContacts_response”
*/
function selectContacts($msg, $source) {
return ws.invoke($msg);
}
/**
* @mas:namespace target=”sfdc”
* @language:body type=”xquery”
*/
function selectContacts_request($source) {
<query>
<queryString>
SELECT * FROM Contact
WHERE AccountId = ”{string($source/@id)}”
</queryString>
</query>
}
/**
* @mas:namespace target=”app”
* @language:body type=”xquery”
*/
function selectContacts_response($response) {
for $i in $response/sfdc:queryResponse/sfdc:result/sfdc:records
return
<contact id=”{string($i/sfdc:Id)}” accountId=”{string($i/sfdc:AccountId)}”>
<modified>{string($i/sfdc:SystemModstamp)}</modified>
<fist>{string($i/sfdc:FistName)}</first>
<last>{string($i/sfdc:LastName)}</last>
<email>{string($i/sfdc:Email)}</email>
</contact>
}
【０２４７】
要求変換は、ｑｕｅｒｙウェブサービスオペレーションを呼び出すＳＯＡＰメッセージの本体を構成することができる。応答変換は、ウェブサービスオペレーションの応答ＳＯＡＰメッセージの本体を処理し、そして１組の＜ｃｏｎｔａｃｔ＞ノードを構成する。
【０２４８】
要求変換
要求変換は、フレームワーク及びデータモデルエレメントから出て行くウェブサービスメッセージを生成することができる。オペレーションタイプに基づいて（上記のオペレーションテーブルを参照）、変換は、オペレーションに対するコンテクストを与える次のシステム変数を参照することができる。
2007524933.tif 000025
【０２４９】
上記ｓｅｌｅｃｔコンジットオペレーションメソッドは、ｑｕｅｒｙウェブサービスオペレーションを呼び出し、これは、以下のＸＭＬスキーマ定義に合致する本体を伴うＳＯＡＰメッセージを期待する。
...
<element name=”query”>
<complexType>
<sequence>
<element name=”queryString” type=”xsd:string”/>
</sequence>
</complexType>
</element>
...
【０２５０】
以下の変換は、問合せに必要なＡｃｃｏｕｎｔＩｄを指定するために、＄ｓｏｕｒｃｅシステム変数を参照する。
/**
* @mas:namespace target=”sfdc”
* @language:body type=”xquery”
* @mas:namespace target=”sfdc”
*/
function selectContacts_request($source) {
<query>
<queryString>
SELECT * FROM Contact
WHERE AccountId = ”{string($source/@id)}”
</queryString>
</query>
}
【０２５１】
例えば、これは、次のような、出て行くＳＯＡＰメッセージ本体を発生し得る。
<query xmlns=”urn:enterprise.soap.sforce.com”>
<queryString>SELECT * FROM Contact WHERE AccountId = 1000</queryString>
</query>
【０２５２】
応答変換
応答変換は、到来するウェブサービスメッセージを処理し、そしてコンジットマネージャーにより処理されるノード（又はｎｏｄｅｓｅｔ）を生成する。全ての応答変換は、次のシステム変数を参照することができる。
2007524933.tif 000026
【０２５３】
上記の例に続いて、ｑｕｅｒｙウェブサービスオペレーションは、次のＸＭＬスキーマに対応するＳＯＡＰメッセージを返送する。
...
<element name=”queryResponse”>
<complexType>
<sequence>
<element name=”result” type=”tns:QueryResult”/>
</sequence>
</complexType>
</element>
<complexType name=”QueryResult”>
<sequence>
<element name=”done” type=”xsd:boolean”/>
<element name=”queryLocator” type=”tns:QueryLocator” nillable=”true”/>
<element name=”records” minOccurs=”0” maxOccurs=”unbounded” 
type=”ens:sObject”/>
<element name=”size” type=”xsd:int”/>
</sequence>
</complexType>
...
【０２５４】
各＜ＱｕｅｒｙＲｅｓｕｌｔ＞エレメントは、一連の＜ｓＯｂｊｅｃｔ＞エレメントを含み、これは、＜Ｃｏｎｔａｃｔ＞スキーマタイプに対する基本タイプである。
<complexType name=”sObject” abstract=”true”>
<sequence>
<element name=”Id” minOccurs=”0” type=”tns:ID”/>
...
</sequence>
</complexType>
<complexType name=”Contact”>
<complexContent>
<extension base=”ens:sObject”>
<sequence>
<element name=”AccountId” minOccurs=”0” type=”tns:ID”/>
<element name=”Email” minOccurs=”0” type=”xsd:string”/>
<element name=”FirstName” minOccurs=”0” type=”xsd:string”/>
<element name=”LastName” minOccurs=”0” type=”xsd:string”/>
<element name=”SystemModstamp” minOccurs=”0” type=”xsd:dateTime”/>
...
</sequence>
</extension>
</complexContent>
</complexType>
<element name=”Contact” type=”ens:Contact”/>
【０２５５】
例えば、到来するＳＯＡＰメッセージ本体は、次の形態をとってもよい。
<sfdc:queryResponse xmlns:sfdc=”urn:enterprise.soap.sforce.com”> 
<sfdc:result>
<sfdc:records xsi:type=”urn:Contact”> 
<sfdc:Id>1234</sfdc:Id>
<sfdc:AccountId>1000</sfdc:AccountId>
<sfdc:Email>reoger@acme.com</sfdc:Email>
<sfdc:FirstName>Roger</sfdc:FirstName>
<sfdc:LastName>Reed</sfdc:LastName>
</sfdc:records> 
<sfdc:records xsi:type=”urn:Contact”> 
<sfdc:Id>5678</sfdc:Id>
<sfdc:AccountId>1000</sfdc:AccountId>
<sfdc:Email>sarah@acme.com</sfdc:Email>
<sfdc:FirstName>Sarah</sfdc:FirstName>
<sfdc:LastName>Smith</sfdc:LastName>
</sfdc:records> 
</sfdc:result>
</sfdc:queryResponse>
【０２５６】
＄ｒｅｓｐｏｎｓｅシステム変数は、最上位レベル＜ｑｕｅｒｙＲｅｓｐｏｎｓｅ＞エレメント（ＳＯＡＰメッセージ本体内）を指す。それ故、次のＸＰａｔｈ表現は、＜Ｃｏｎｔａｃｔ＞エレメントのアレーを参照するのに使用されねばならない。
$response/sfdc:queryResponse/sfdc:result/sfdc:records
【０２５７】
以下の変換は、到来するＳＯＡＰメッセージを処理し、そして＜ｃｏｎｔａｃｔ＞エレメントのリストを生成する。
/**
* @mas:namespace target=”app”
* @language:body type=”xquery”
*/
function selectContacts_response($response) {
for $i in $response/sfdc:queryResponse/sfdc:result/sfdc:records
return
<contact id=”{string($i/sfdc:Id)}” accountId=”{string($i/sfdc:AccountId)}”>
<modified>{string($i/sfdc:SystemModstamp)}</modified>
<fist>{string($i/sfdc:FistName)}</first>
<last>{string($i/sfdc:LastName)}</last>
<email>{string($i/sfdc:Email)}</email>
</contact>
}
【０２５８】
全ての要求変換は、サーバーによりキャッシュ記憶されると共にクライアントのデータモデルと同期されるノードを発生する。
許可
コンジットにより定義されるオペレーションは、クライアントの対応するｎｏｄｅｓｅｔにおいて呼び出すことのできるオペレーションを決定する。例えば、コンジットが挿入オペレーションを定義しない場合には、クライアントは、対応するｎｏｄｅｓｅｔに対するノードを生成及び挿入するように試みることができず、このように試みる場合には（例えば、カスタムアクションにおいて）、これがランタイムエラーをトリガーする。クライアント側のプログラミングモデルは、これらの制約を強いる。
【０２５９】
例えば、ａｃｃｏｕｎｔが特定のアカウントノードを指し、そしてアカウントノードがｏｒｄｅｒｓ  ｋｅｙｒｅｆに関連していると仮定する。この場合には、ｏｒｄｅｒｓ  ｋｅｙｒｅｆに関連したコンジット挿入オペレーションが定義されない限り、次のコードがエラーを招くことになる。
account.@quotes.create(
<quoteRequest>
<prodId>A1</prodId><qty>10</qty>
</quoteRequest>
);
【０２６０】
同様に、コンタクトｎｏｄｅｔｙｐｅに対して更新オペレーションが定義されない限り、次のコードもエラーを招くことになる。
contact.address.zip = ”11201”;
【０２６１】
一実施形態では、クライアントオペレーション（例えば、ｃｒｅａｔｅ（）ファンクション）の実施が、コンジットオペレーション（例えば、挿入）とマッチングされる。例えば、コンジットオペレーションの挿入は、ノードを挿入すると共に、ｋｅｙｒｅｆ関係を使用してそれを別のノードへトラバースし、それ故、クライアントにおけるノードの生成は、対応するｎｏｄｅｓｅｔへのトラバースオペレーションと自動的に対にされねばならない。
【０２６２】
実施されるコンジットオペレーションを記述するメタデータは、ユーザプログラミングモデルにアクセスできる（関連するｋｅｙｒｅｆを経て）。自動的ユーザインターフェイスは、この情報を使用して、基本的メニュー（挿入、更新等）を発生することができる。
【０２６３】
エラーハンドリング
コンジットメカニズムは、２種類のエラー、即ちシステムエラー（例えば、プロトコル及びトランスポートエラー）と、アプリケーションエラー（例えば、無効データ）との間を区別する。更に、アプリケーションエラーは、２つの異なる仕方で生じ、即ちＳＯＡＰ欠陥（即ち、プロトコルレベルエラー）として、及びＳＯＡＰ（又は平易ＸＭＬ）応答メッセージの一部分として生じ得る。
2007524933.tif 000027
【０２６４】
コンジットオペレーションは、ＳＯＡＰコールとして実施され、ＳＯＡＰ欠陥は、メッセージの処理にエラーが生じた場合に発生し、これは、インフラストラクチャー欠陥（例えば、トランスポート欠陥）によるか、プロトコル欠陥（例えば、不良に形成されたメッセージ）によるか、又はアプリケーション状態エラー（例えば、更新失敗）によるものである。出て行く又は到来するＳＯＡＰメッセージを生成又は処理するエラーがある場合に、システムエラーが生じる（例えば、ＸＱｕｅｒｙ変換エラー）。
【０２６５】
外部アプリケーションが、メッセージ本体の一部分として通された値に基づいてオペレーション要求を拒絶する場合にアプリケーションエラーが生じる（例えば、更新失敗）。ＳＯＡＰ欠陥は、ウェブサービスコントロールにおけるｉｎｖｏｋｅ（）ファンクションの呼び出し中にＳＯＡＰスタックにより生じる。
【０２６６】
通常、コンジットオペレーションにより返送されるＸＭＬオブジェクトの本体は、応答変換により処理される。しかしながら、オペレーションがシステム＜ｍａｓ：ｅｒｒｏｒ＞オブジェクトを返送する場合には、このオブジェクトがコンジットマネージャーへ直接通される。メインコンジットファンクション又は応答変換のいずれが＜ｍａｓ：ｅｒｒｏｒ＞オブジェクトを返送してもよいことに注意されたい。
【０２６７】
＜ｍａｓ：ｅｒｒｏｒ＞スキーマ定義を以下に示す。
<xsd:complexType name=”errorType”>
<xsd:sequence>
<xsd:element name=”pkey” type=”xsd:any” minOccurs=”0” maxOccurs=”1”/>
<xsd:element name=”system” type=”mas:systemErrorType” maxOccurs=”1”/>
<xsd:element name=”message” type=”xsd:string”/>
<xsd:element name=”field” type=”mas:errorFieldType” maxOccurs=”unbounded”/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name=”systemErrorType”>
<xsd:sequence>
<xsd:element name=”code” type=”xsd:any”/>
<xsd:element name=”message” type=”xsd:string”/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name=”errorFieldType”>
<xsd:sequence>
<xsd:element name=”code” type=”xsd:any”/>
<xsd:element name=”message” type=”xsd:string”/>
</xsd:sequence>
<xsd:attribute name=”xpath” type=”xsd:string”/>
</xsd:complexType>
【０２６８】
即ち、＜ｍａｓ：ｅｒｒｏｒ＞オブジェクトは、次の形態を有する。
<mas:error>
<mas:pkey>primary-key</mas:pkey>
<mas:system>
<mas:code>error-code</mas:code>
<mas:message>message-string</mas:message>
</mas:system>
<mas:message>message-string</mas:message>
<mas:field xpath=”spath-expression”>
<mas:code>error-code</mas:code>
<mas:message>message-string</mas:message>
</mas:field>
...
</mas:error>
【０２６９】
各エラーオブジェクトは、エラーにより影響されるノードの一次キーを含んでもよい。セレクトオペレーションについては、これは、ソースノードの一次キーとなり、更新及び削除オペレーションの場合には、これは、更新されたノードを参照する。
システムエラーは、サーバーによりログすることができる。他の全てのエラー値は、クライアントへ返送し、そしてそれに対応するコールバックファンクションへ通すことができる。
エラーオブジェクトは、アプリケーションのコールバックファンクションへ返送され、このオブジェクトは、上記スキーマに対応するプロパティを有する。
【０２７０】
例
次のオペレーションは、ｉｎｖｏｋｅ（）ファンクションの呼び出しがエラーを返送する場合にシステムエラーを返送する。
/**
* @mas:operation type=”select” keyref=”keyrefName”
*/
function operationTypeSourceType($msg, $source) {
var response = control.invoke($msg);
if (response.error) {
return
<mas:error>
<mas:system><mas:message>system-error</mas:message></mas:system>
</mas:error>;
}
return response;
}
【０２７１】
適当な場合に、失敗したｉｎｖｏｋｅ（）呼び出しを再試みするのは、コンジットオペレーションの責任である。この場合に、コンジットは、ウェブサービスオペレーションが等冪であるか、又はあるタイプの信頼し得るメッセージングを使用することを保証しなければならない。
次のオペレーションは、失敗時にｉｎｖｏｋｅ（）ファンクションを再試みした後にシステムエラーを返送する。
/**
* @mas:operation type=”select” keyref=”keyrefName”
*/
function operationTypeSourceType($msg, $source) {
for (i=0; i<3; i++) {
var response = control.invoke($msg);
if (!response.error) {
return response;      // OK
}
}
return
<mas:error>
<mas:system><mas:message>Retry failed</mas:message></mas:system>
</mas:error>;
}
【０２７２】
次のオペレーションは、先ず、ｉｎｖｏｋｅ（）ファンクションがエラーを返送する場合にシステムエラーをチェックし、さもなければ、一般的なアプリケーションエラーを返送する。ｉｎｖｏｋｅ（）は成功であるが、ウェブサービス応答がアプリケーションエラーを含む場合には、エラーメッセージをパーズするためのユーティリティファンクションをコールし、そして多数の＜ｆｉｅｌｄ＞エラーを含むことのあるコンパウンド＜ｅｒｒｏｒ＞オブジェクトを返送する。
/**
* @mas:operation type=”create” keyref=”keyrefName”
*/
function operationTypeSourceType($msg, $source) {
var response = control.invoke($msg);
if (response.error) {
if (response.error.code == 101) {
return 
<mas:error>          <mas:system>
<mas:code>{response.error.code}</mas:code>
<mas:message>system-error</mas:message>
</mas:system></mas:error>;
}
else {
return
<mas:error>
<mas:message>general-error</mas:message>
</mas:error>;
}
}
// check for application errors
if (response.body.createResponse.result.errors) {
return process_error(response.body.createResponse.result.errors);
}
return response;                    // OK
}
// utility function to process field errors
function process_error(errors) {
var fields;
for (i=0; i<errors.length i++) {
var path = match_path(errors[i].fields[0]);
fields +=
<mas:field xpath=”{path}”>
<code>{$i/statusCode}</code>
<mas:message>{$i/message}</mas:message>
</mas:field>
}
return <mas:error>{fields}</mas:error>;
}
【０２７３】
ＣＲＵＤオペレーション
ＣＲＵＤ（生成読み取り更新削除）オペレーションは、４つの基本的な関係データオペレーションを表わす。これらのオペレーションは、ＭＡＳデータモデル及びクライアントプログラミングモデルに直接マップすることができる。
ウェブサービスのコンタクトスキーマは、上記で定義されたアプリケーションのコンタクトスキーマとは異なる形状を有することに注意されたい。以下のセレクトオペレーションの例は、このマッピングをいかに行うか示す。
【０２７４】
セレクト
セレクトオペレーションは、特定のソースノードに対してｋｅｙｒｅｆにより定義されたノードをフレームワークが検索できるようにする。通常、全てのコンジットがセレクトオペレーションを定義する。というのは、これは、クライアントアプリケーションによりノードを検索するのに使用される基本的メカニズムだからである。
【０２７５】
それに続くセレクトオペレーション（異なるｋｅｙｒｅｆに対する）を呼び出して、データグラフを構成することができる。例えば、アカウントノードから購入注文ｋｅｙｒｅｆへのナビゲーションは、ＡｃｃｏｕｎｔＭａｎａｇｅｒウェブサービスのｇｅｔＰｕｒｃｈａｓｅＯｒｄｅｒｓオペレーションを呼び出し、次いで、購入注文ノードからラインアイテムｋｅｙｒｅｆへのナビゲーションは、ＯｒｄｅｒＭａｎａｇｅｒウェブサービスのｇｅｔＬｉｎｅＩｔｅｍｓオペレーションをコールする。
【０２７６】
セレクトオペレーションは、次の形態を有する。
/**
* @mas:operation type=”select” keyref=”keyrefName” [inverse=”true”]
* @mas:transform type=”request” function=”functionName_request”
* @mas:transform type=”response” function=”functionName_response”
*/
function functionName($msg, $source) {
return ws.invoke($msg);
}
【０２７７】
セレクトオペレーションは、特定のソースｎｏｄｅｔｙｐｅに対して定義されたｋｅｙｒｅｆＮａｍｅに対応するノードを検索するのに使用され、例えば、特定のコンタクトノードに対して外部キーにより参照されるアカウントを選択する。逆属性は、オペレーションが逆関係を実施することを定義し、例えば、外部キーを経ることにより特定のアカウントを参照する全てのコンタクトを選択する。
【０２７８】
ｋｅｙｒｅｆ定義は、次の形態をもつことができる。
<xsd:keyref name=”keyrefName” refer=”targetType”
mas:alias=”relationName” mas:inverseAlias=”inverseRelationName”>
<xsd:selector xpath=”sourceType”/>
<xsd:field xpath=”foreignKey”/>
</xsd:keyref>
【０２７９】
関連用語において、セレクトオペレーションは、次のＳＱＬ表現に対応する。
SELECT * FROM keyref.targetType WHERE primary_key = $source/foreign_key
逆ｋｅｙｒｅｆを実施するオペレーションは、次のＳＱＬ表現に対応する。
SELECT * FROM keyref.sourceType WHERE foreign_key = $source/primary_key
【０２８０】
セレクトオペレーションの要求変換は、ウェブサービスオペレーションに対するメッセージ本体を生成することができ、オペレーションに対するコンテクストを与える次のシステム変数を参照することができる。
2007524933.tif 000028
【０２８１】
セレクトオペレーションの応答変換は、応答メッセージ本体をノードのリストへマップすることができる。ノードエレメントは、ｋｅｙｒｅｆにより対応するｎｏｄｅｔｙｐｅ定義のためのアプリケーション定義スキーマに対応する。セレクトオペレーションの応答変換は、次のシステム変数を参照することができる。
2007524933.tif 000029
【０２８２】
外部キーによるセレクト（多対１）
関連外部キーは、多対１（又は「ルックアップ」）関係を実施する。
例えば、次のスキーマ及びｋｅｙｒｅｆ定義が与えられると、コンタクトノードのａｃｃｏｕｎｔＩｄ属性を、そのコンタクトが属するアカウントノードに対するポインタとして考えるのが自然である。
<xsd:complexType name=”contactType”>
<xsd:all>
<xsd:element name=”first” type=”xsd:string”/>
<xsd:element name=”last” type=”xsd:string”/>
<xsd:element name=”email” type=”xsd:string”/>
</xsd:all>
<xsd:attribute name=”id” type=”xsd:string” use=”required” mas:type=”pkey”/>
<xsd:attribute name=”ownerId” type=”xsd:string” use=”required”/>
<xsd:attribute name=”accountId” type=”xsd:string” use=”required”/>
</xsd:complexType>
<xsd:keyref name=”contactAccountRef” refer=”accountKey” mas:alias=”account”>
<xsd:selector xpath=”contact”/>
<xsd:field xpath=”@accountId”/>
</xsd:keyref>
【０２８３】
これは、次のクライアントトラバースを可能にする（＠＠演算子は、ｋｅｙｒｅｆ定義のエイリアスネームを参照することに注意されたい）。
var account = contact.@@account;
【０２８４】
次のコンジットオペレーションは、このｋｅｙｒｅｆ関係を実施する。
/**
* @mas:operation type=”select” keyref=”contactAccountRef”
* @mas:transform type=”request” function=”selectAccountByContact_request”
* @mas:transform type=”response” function=”selectAccountByContact_response”
*/
function selectAccountByContact($msg, $source) {
return ws.invoke($msg);
}
/**
* @language:body type=”xquery”
* @mas:namespace target=”sfdc”
* @mas:field xpath=”@accountId”
*/
function selectAccountByContact_request($source) {
<query>
<queryString>
SELECT * FROM Account
WHERE Id = {string($source/@accountId)}
</queryString>
</query>
}
/**
* @language:body type=”xquery”
* @mas:namespace target=”app”
*/
function selectAccountByContact_response($response) {
let $i := $response/sfdc:queryResponse/sfdc:result/sfdc:records
return
<account id=”{string($i/sfdc:Id)}”>
<modified>{string($i/sfdc:SystemModstamp)}</modified>
<name>{string($i/sfdc:Name)}</name>
<type>{string($i/sfdc:Type)}</type>
</account>
}
【０２８５】
このコンジットオペレーションファンクションは、プラットホームにより自動的に発生することができ、これは、ａｃｃｏｕｎｔＯｗｎｅｒＲｅｆのｋｅｙｒｅｆ定義を参照できると共に、要求及び応答変換ファンクションに対する宣言（ツールにより発生された）を有する。
/**
* @mas:operation type=”select” keyref=”contactAccountRef”
* @mas:transform type=”request” function=”selectAccountByContact_request”
* @mas:transform type=”response” function=”selectAccountByContact_response”
*/
function selectAccountByContact($msg, $source) {
return ws.invoke($msg);
}
【０２８６】
要求変換
要求変換は、アカウントノードを表わす＄ｓｏｕｒｃｅ変数を参照することができる。ファンクション注釈は、出て行くメッセージ文書の言語（ＸＱｕｅｒｙ）及びターゲットｎａｍｅｓｐａｃｅを宣言することができる（コンジットファイルのヘッダー注釈で宣言されたｎａｍｅｓｐａｃｅプレフィックスを参照する）。
【０２８７】
又、ファンクションは、コンタクトノードの＠ａｃｃｏｕｎｔＩｄ属性がファンクションにより要求されることを指示するフィールド注釈も宣言することができ、この宣言は、呼び出しているクライアントからサーバーへ外部キー値を同期要求の一部分として送信することを保証できる。
/**
* @language:body type=”xquery”
* @mas:namespace target=”sfdc”
* @mas:field xpath=”@accountId”
*/
function selectAccountByContact_request($source) {
<query>
<queryString>
SELECT * FROM Account
WHERE Id = {string($source/@accountId)}
</queryString>
</query>
}
【０２８８】
応答変換
応答変換は、ウェブサービスから返送されるメッセージのＸＭＬ本体を表わす＄ｒｅｓｐｏｎｓｅ変数を参照することができる。又、ファンクション注釈は、コンジットマネージャーへ返送されるＸＭＬオブジェクトの言語（ＸＱｕｅｒｙ）及びターゲットｎａｍｅｓｐａｃｅも宣言することができる。
【０２８９】
このファンクションは、単一レコードがウェブサービス＜ｑｕｅｒｙ＞要求により返送されると仮定することができる。このファンクションは、これを、スキーマ定義に合致する対応一次キー（ｉｄ）及びデータフィールド（シーケンスナンバーを表わす＜ｍｏｄｉｆｉｅｄ＞エレメントを含む）を伴う単一の＜ａｃｃｏｕｎｔ＞ノードへと変換することができる。
/**
* @language:body type=”xquery”
* @mas:namespace target=”app”
*/
function selectOwnerByAccount_response($response) {
let $i := $response/sfdc:queryResponse/sfdc:result/sfdc:records
return
<account id=”{string($i/sfdc:Id)}”>
<modified>{string($i/sfdc:SystemModstamp)}</modified>
<name>{string($i/sfdc:Name)}</name>
<type>{string($i/sfdc:Type)}</type>
</account>
}
【０２９０】
＜ａｃｃｏｕｎｔ＞ノードは、コンジットマネージャーへ返送できると共に、発呼アプリケーションへ戻るように同期させることができる。又、コンジットマネージャーは、ノードをサーバーのキャッシュへ入れるように選択してもよい。
逆のセレクト（１対多）
外部キーにより定義された多対１の関係は、もちろん、逆の方向に、１対多の関係として考えることができる。
【０２９１】
前記セクションの場合と同じスキーマ及びｋｅｙｒｅｆ定義が与えられると、個々のアカウントノードに属する１組のコンタクトノードを考えるのが自然である。
<xsd:complexType name=”contactType”>
<xsd:all>
<xsd:element name=”first” type=”xsd:string”/>
<xsd:element name=”last” type=”xsd:string”/>
<xsd:element name=”email” type=”xsd:string”/>
<xsd:element name=”modified” type=”xsd:string”/>
</xsd:all>
<xsd:attribute name=”id” type=”xsd:string” use=”required” mas:type=”pkey”/>
<xsd:attribute name=”ownerId” type=”xsd:string” use=”required”/>
<xsd:attribute name=”accountId” type=”xsd:string” use=”required”/>
</xsd:complexType>
<xsd:keyref name=”contactAccountRef” refer=”accountKey” mas:alias=”account” 
mas:inverseAlias=”contacts”>
<xsd:selector xpath=”contact”/>
<xsd:field xpath=”@accountId”/>
</xsd:keyref>
【０２９２】
しかしながら、このとき、ｋｅｙｒｅｆ定義のｍａｓ：ｉｎｖｅｒｓｅＡｌｉａｓ属性を使用して、ｋｅｙｒｅｆを逆方向にトラバースする。
var contacts = account.@@contacts.*;
次のコンジットオペレーションは、この逆のｋｅｙｒｅｆ関係を実施する。
/**
* @mas:operation type=”select” keyref=”contactAccountRef” inverse=”true”
* @mas:transform type=”request” function=”selectContactsByAccount_request”
* @mas:transform type=”response” function=”selectContactsByAccount_response”
*/
function selectContactsByAccount($msg, $source) {
return ws.invoke($msg);
}
/**
* @language:body type=”xquery”
* @mas:namespace target=”sfdc”
* @mas:field xpath=”@id”
*/
function selectContactsByAccount_request($source) {
<query>
<queryString>
SELECT * FROM Contact
WHERE accountId = {string($source/@id)}
</queryString>
</query>
}
/**
* @language:body type=”xquery”
* @mas:namespace target=”app”
*/
function selectContactsByAccount_response($response) {
for $i := $response/sfdc:queryResponse/sfdc:result/sfdc:records
return
<contact id=”{string($i/sfdc:Id)}” accountId=”{string($i/sfdc:AccountId)}”>
<modified>{string($i/sfdc:SystemModstamp)}</modified>
<fist>{string($i/sfdc:FistName)}</first>
<last>{string($i/sfdc:LastName)}</last>
<email>{string($i/sfdc:Email)}</email>
</contact>
}
【０２９３】
このコンジットオペレーションファンクションは、プラットホームにより自動的に発生することができ、これは、ａｃｃｏｕｎｔＯｗｎｅｒＲｅｆのｋｅｙｒｅｆ定義を参照しそして要求及び応答変換ファンクションに対する宣言（ツールにより発生される）を有する。又、このオペレーションは、それが逆のｋｅｙｒｅｆ関係を表わすことも宣言する。
/**
* @mas:operation type=”select” keyref=”contactAccountRef” inverse=”true”
* @mas:transform type=”request” function=”selectContactsByAccount_request”
* @mas:transform type=”response” function=”selectContactsByAccount_response”
*/
function selectContactsByAccount($msg, $source) {
return ws.invoke($msg);
}
【０２９４】
要求変換
要求変換は、コンタクトノードを表わす＄ｓｏｕｒｃｅ変数を参照することができる。ファンクション注釈は、出て行くメッセージ文書の言語（ＸＱｕｅｒｙ）及びターゲットｎａｍｅｓｐａｃｅを宣言する（コンジットファイルのヘッダー注釈で宣言されたｎａｍｅｓｐａｃｅプレフィックスを参照する）。
【０２９５】
又、ファンクションは、アカウントノードの＠ｉｄ属性がファンクションにより要求されることを指示するフィールド注釈も宣言することができ、この宣言は、呼び出しているクライアントからサーバーへ外部キー値を同期要求の一部分として送信することを保証できる。
/**
* @language:body type=”xquery”
* @mas:namespace target=”sfdc”
* @mas:field xpath=”@id”
*/
function selectContactsByAccount_request($source) {
<query>
<queryString>
SELECT * FROM Contact
WHERE accountId = {string($source/@id)}
</queryString>
</query>
}
【０２９６】
応答変換は、ウェブサービスから返送されたメッセージのＸＭＬ本体を表わす＄ｒｅｓｐｏｎｓｅ変数を参照することができる。又、ファンクション注釈は、コンジットマネージャーへ返送されるＸＭＬオブジェクトの言語（ＸＱｕｅｒｙ）及びターゲットｎａｍｅｓｐａｃｅも宣言することができる。
【０２９７】
このファンクションは、多数のレコードがウェブサービス＜ｑｕｅｒｙ＞要求により返送されると仮定することができる。ファンクションは、結果を通して繰り返し、そしてそれらを、１組の＜ｃｏｎｔａｃｔ＞ノードへと変換する。各ノードは、スキーマ定義に合致する対応一次キー（ｉｄ）及びデータフィールドを含むことができ、これは、アカウント外部キー（ａｃｃｏｕｎｔＩｄ属性）及びシーケンスナンバー（＜ｍｏｄｉｆｉｅｄ＞エレメント）を含む。
/**
* @language:body type=”xquery”
* @mas:namespace target=”app”
*/
function selectContactsByAccount_response($response) {
for $i := $response/sfdc:queryResponse/sfdc:result/sfdc:records
return
<contact id=”{string($i/sfdc:Id)}” accountId=”{string($i/sfdc:AccountId)}”>
<modified>{string($i/sfdc:SystemModstamp)}</modified>
<fist>{string($i/sfdc:FistName)}</first>
<last>{string($i/sfdc:LastName)}</last>
<email>{string($i/sfdc:Email)}</email>
</contact>
}
【０２９８】
＜ｃｏｎｔａｃｔ＞ノードは、コンジットマネージャーへ返送できると共に、発呼アプリケーションへ戻るように同期させることができる。又、コンジットマネージャーは、これらノードをサーバーのキャッシュへ入れるように選択してもよい。
【０２９９】
非関連（コンテクストフリー）セレクト
外部キー値に依存しないノードとノードとの間の関係を定義することができる。例えば、現在ユーザ情報又は他の外部情報（例えば、日時、リアルタイムデータ、外部システム状態）を使用する問合せにより１組のノードが定義されてもよい。これらの場合に、ｎｏｄｅｓｅｔは、データモデル内の任意のｎｏｄｅｔｙｐｅにアタッチされてもよい。しかしながら、通常、これらのｎｏｄｅｓｅｔは、ルートノードにアタッチされる。
【０３００】
コンジットセレクトオペレーションは、ｋｅｙｒｅｆ定義を参照することができ、コンテクストフリーのセレクトは、定義により、ソースノードのコンテクストを要求しないので、一実施形態では、それらが常に逆のｋｅｙｒｅｆにおいて実施される。
【０３０１】
次の例は、ＣＲＭ  ｄｅｍｏにおいて、現在ユーザに対する１組のアカウントがコンジットセレクトオペレーションによりいかに検索されるかを示す。アカウントｎｏｄｅｔｙｐｅは、次のキー定義を有する。
<xsd:key name=”accountKey” mas:alias=”accounts”>
<xsd:selector xpath=”account ”/>
<xsd:field xpath=”@id”/>
</xsd:key>
【０３０２】
ｍａｓ：ａｌｉａｓ属性は、アカウントのｎｏｄｅｓｅｔがルートノードからトラバースできることを指示し、即ち
var accounts = $root.@@accounts.*;
コンジットは、逆のｋｅｙｒｅｆセレクトオペレーション（上述した）と同様に実施することができる。
/**
* @mas:operation type=”select” key=”accountKey” inverse=”true”
* @mas:transform type=”request” function=”selectAccounts_request”
* @mas:transform type=”response” function=”selectAccounts_response”
*/
function selectAccounts($msg, $source) {
return ws.invoke($msg);
}
/**
* @language:body type=”xquery”
* @mas:namespace target=”sfdc”
*/
function selectAccounts_request($source) {
<query>
<queryString>
SELECT *.Account FROM Account, User
WHERE User.Alias = {string($user/username)}
AND User.Id = Account.OwnerId
</queryString>
</query>
}
/**
* @language:body type=”xquery”
* @mas:namespace target=”app”
*/
function selectAccounts_response($response) {
for $i := $response/sfdc:queryResponse/sfdc:result/sfdc:records
return
<account id=”{string($i/sfdc:Id)}”>
<modified>{string($i/sfdc:SystemModstamp)}</modified>
<name>{string($i/sfdc:Name)}</name>
<type>{string($i/sfdc:Type)}</type>
</account>
}
【０３０３】
要求変換
要求変換は、ウェブサービスへ送信される要求問合せを構成するのに使用される＄ｕｓｅｒシステム変数を参照することができる。
/**
* @language:body type=”xquery”
* @mas:namespace target=”sfdc”
*/
function selectAccounts_request($source) {
<query>
<queryString>
SELECT *.Account FROM Account, User
WHERE User.Alias = {string($user/username)}
AND User.Id = Account.OwnerId
</queryString>
</query>
}
【０３０４】
この場合に、サービスは、現在ユーザにより所有される（即ち、現在ユーザのＩＤにマッチするＯｗｎｅｒＩｄ外部キーを有する）全てのアカウントを選択するジョイン問合せを実施することができる。この変換は、＄ｓｏｕｒｃｅ変数を参照しないことに注意されたい。
【０３０５】
応答変換
応答変換は、先のセクションで定義された応答変換と同様に、ウェブサービスオペレーションにより返送される１組のアカウントを処理することができる。
/**
* @language:body type=”xquery”
* @mas:namespace target=”app”
*/
function selectAccounts_response($response) {
for $i := $response/sfdc:queryResponse/sfdc:result/sfdc:records
return
<account id=”{string($i/sfdc:Id)}”>
<modified>{string($i/sfdc:SystemModstamp)}</modified>
<name>{string($i/sfdc:Name)}</name>
<type>{string($i/sfdc:Type)}</type>
</account>
}
【０３０６】
＠ｍａｓ：ｒｏｏｔＩｄ属性は、１組の＜ａｃｃｏｕｎｔ＞ノードがそこに返送されたときにコンジットマネージャーにより自動的に計算できることに注意されたい。
挿入
挿入オペレーションは、クライアントアプリケーションが新たに形成されたノードをサーバーに同期させるときにコンジットマネージャーによりコールすることができる。
【０３０７】
クライアントにおいて、ノードは、２つの方法の１つで生成することができ、即ちｃｒｅａｔｅ（）ファンクションは、ｋｅｙｒｅｆ又はルートノードのいずれかにおいてコールすることができる。
var node = source.@@keyref.create(<xml>);          // contextual create
var node = $root.create(<xml>);                    // context free create
両方の場合に、ノードのＸＭＬオブジェクトだけを（即ちソースノードではなく）サーバーへ転送することができる。これは、コンテクスト生成オペレーションの場合に、ノードが、ソースノードを参照する外部キー値を含まねばならないからであり、この値は、ｋｅｙｒｅｆ定義に基づいてフレームワークにより自動的にセットされる。
【０３０８】
挿入オペレーションは、次の形態を有する。
/**
* @mas:operation type=”insert” node=”nodeName”
* @mas:transform type=”request” function=”functionName_request”
* @mas:transform type=”response” function=”functionName_response”
*/
function functionName($msg, $source) {
return ws.invoke($msg);
}
【０３０９】
挿入オペレーションは、ｎｏｄｅＮａｍｅ宣言により参照されるスキーマに対応するノードを生成するのに使用できる。
挿入オペレーションの要求変換は、ウェブサービスオペレーションに対するメッセージ本体を生成し、これは、オペレーションに対してコンテクストを与える次のシステム変数を参照することができる。
2007524933.tif 000030
【０３１０】
挿入オペレーションの応答変換は、応答メッセージ本体を、ウェブサービスにより生成されたレコードの一次キー（及び任意であるがシーケンスナンバー）を含む部分的に構成されたノードへとマップすることができる。挿入オペレーションの応答変換は、次のシステム変数を参照することができる。
2007524933.tif 000031
【０３１１】
ノードの一次キー（及び任意であるがシーケンスナンバー）は、コンジットマネージャーへ返送することができ、コンジットマネージャーは、この情報を再びクライアントに同期させる。ノードは、最初に、一時的な一次キーでクライアントにおいて生成され、この値は、外部システムの一次キーと置き換えねばならない。
【０３１２】
ノードは、通常、他のノードを参照する外部キー値を含む。互いに参照するクライアントにおいて多数のノードが生成される場合には、システムは、挿入コンジットオペレーションが適当な依存順序でコールされ且つウェブサービスから返送される一次キー値が保留ノードに対する一時的外部キー値との交換に使用されるよう保証しなければならない。
【０３１３】
非関連性挿入
一実施形態において、非関連性挿入オペレーションは、データモード内の他のｎｏｄｅｔｙｐｅを参照する外部キーをもたない。例えば、ユーザｎｏｄｅｔｙｐｅは、次のスキーマにより定義することができる。
<xsd:complexType name=”userType”>
<xsd:all>
<xsd:element name=”email” type=”xsd:string”/>
</xsd:all>
<xsd:attribute name=”id” type=”xsd:string”/>
</xsd:complexType>
アドミニストレーションアプリケーションがシステムに対する新たなユーザを生成できると仮定する。これを行うクライアントコードは、次の通りである。
$root.create(<user><email>bob@acme.com</email></user>);
【０３１４】
一実施形態において、これは、次の挿入コンジットオペレーションを要求する。
/**
* @mas:operation type=”insert” node=”app:user” 
* @mas:transform type=”request” function=”insertUser_request”
* @mas:transform type=”response” function=”insertUser_response”
*/
function insertUser($msg, $node) {
return ws.invoke($msg);
}
/**
* @language:body type=”xquery”
* @mas:namespace target=”sfdc”
*/
function insertUser_request($node) {
<create>
<sObjects xsi:type=”User”>
<Email>{string($node/app:email)}</Email>
</sObjects>
</create>
}
/**
* @language:body type=”xquery”
* @mas:namespace target=”app”
*/
function insertUser_response($response) {
<user id=”{string($response/sfdc:createResponse/sfdc:result/sfdc:Id)}”/>
}
【０３１５】
要求変換
要求変換は、アプリケーションにより生成されたユーザノードを表わす＄ｎｏｄｅ変数を参照することができる。ファンクションの注釈は、出て行くメッセージ文書の言語（ＸＱｕｅｒｙ）及びターゲットｎａｍｅｓｐａｃｅを宣言することができる（コンジットファイルのヘッダー注釈で宣言されたｎａｍｅｓｐａｃｅプレフィックスを参照する）。
/**
* @language:body type=”xquery”
* @mas:namespace target=”sfdc”
*/
function insertUser_request($node) {
<create>
<sObjects xsi:type=”User”>
<Email>{string($node/app:email)}</Email>
</sObjects>
</create>
}
【０３１６】
応答変換
応答変換は、ウェブサービスから返送されたメッセージのＸＭＬ本体を表わす＄ｒｅｓｐｏｎｓｅ変数を参照することができる。このファンクションの注釈は、コンジットマネージャーへ返送されるＸＭＬオブジェクトの言語（ＸＱｕｅｒｙ）及びターゲットｎａｍｅｓｐａｃｅも宣言することができる。
【０３１７】
成功時に、ウェブサービスは、次のスキーマ定義に合致するメッセージ本体を返送することができる。
<element name=”createResponse”>
<complexType>
<sequence>
<element name=”result” minOccurs=”1” type=”tns:SaveResult”/>
</sequence>
</complexType>
</element>
<complexType name=”SaveResult”>
<sequence>
<element name=”id” type=”tns:ID”/>
<element name=”success” type=”xsd:boolean”/>
<element name=”errors” minOccurs=”0” maxOccurs=”unbounded” type=”tns:Error”/>
</sequence>
</complexType>
【０３１８】
この変換は、アプリケーションのスキーマにより定義された一次キー属性（ｉｄ）を含む部分的に構成された＜ｕｓｅｒ＞ノードを生成することができる。
/**
* @language:body type=”xquery”
* @mas:namespace target=”app”
*/
function insertUser_response($response) {
<user id=”{string($response/sfdc:createResponse/sfdc:result/sfdc:id)}”/>
}
この一次キー値は、コンジットマネージャーにより処理できると共に、クライアントアプリケーションと同期させることができる。
【０３１９】
関連性挿入
関連性挿入は、キャッシュ内の他のノードを参照する外部キー値を含むノードを伴うことができる。
例えば、以下のコンタクトスキーマは、所有者ノード（＠ｏｗｎｅｒＩｄ）及びアカウントノード（＠ａｃｃｏｕｎｔＩｄ）に対する外部キーを定義する。
<xsd:complexType name=”contactType”>
<xsd:all>
<xsd:element name=”first” type=”xsd:string”/>
<xsd:element name=”last” type=”xsd:string”/>
<xsd:element name=”email” type=”xsd:string”/>
</xsd:all>
<xsd:attribute name=”id” type=”xsd:string” use=”required” mas:type=”pkey”/>
<xsd:attribute name=”ownerId” type=”xsd:string” use=”required”/>
<xsd:attribute name=”accountId” type=”xsd:string” use=”required”/>
</xsd:complexType>
【０３２０】
最初に、コンタクトＸＭＬオブジェクトは、ＸＳｃｒｉｐｔ指定により構成されてもよい。
var contact =
<contact>
<first>Sarah</first>
<last>Smith</last>
<email>sarah@acme.com</email>
</contact>;
【０３２１】
外部キーを含むノードは、多数のやり方で生成されてもよい。上述したコンタクトＸＭＬオブジェクトと、所有者及びコンタクトノードを表わす変数とが与えられると、次のファンクションは、ルートノードにおけるｃｒｅａｔｅ（）ファンクションをコールすることによりコンタクトノードを生成する。外部キーは、ｃｒｅａｔｅ（）がコールされる前にセットされねばならないことに注意されたい。
function createContact1(account, owner, contact) {
contact.@@account = account;
contact.@@owner = owner;
return $root.create(contact);
}
しかしながら、次のファンクションは、同じ目標を達成する。
function createContact2(account, owner, contact) {
contact.@@owner = owner;
return account.@@contacts.create(contact)
}
function createContact3(account, owner, contact) {
contact.@@account = account;
return owner.@@contact = contact;
}
【０３２２】
これら両方のケースにおいて、欠落した外部キーは、ノードがサーバーに対して同期される前にフレームワークにより供給されることに注意されたい。それ故、ノードがアプリケーションによりいかに生成されるかに関わらず、コンジットオペレーションは、ｎｏｄｅｔｙｐｅにバインディングするだけでよい。コンジットオペレーションは、先のセクションで定義したオペレーションと同じ仕方で実施することができる。
/**
* @mas:operation type=”insert” node=”app:contact” 
* @mas:transform type=”request” function=”insertContact_request”
* @mas:transform type=”response” function=”insertContact_response”
*/
function insertContact($msg, $node) {
return ws.invoke($msg);
}
/**
* @mas:namespace target=”sfdc”
* @language:body type=”xquery”
*/
function insertContact_request($node) {
<create>
<sObjects xsi:type=”Contact”>
<AccountId>{string($node/app:@accountId})</AccountId>
<OwnerId>{string($node/app:@ownerId})</OwnerId>
<FirstName>{string($node/app:first)}</FirstName>
<LastName>{string($node/app:last)}</LastName>
<Email>{string($node/app:email)}</Email>
</sObjects>
</create>
}
/**
* @mas:namespace target=”app”
* @language:body type=”xquery”
*/
function insertContact_response($response) {
<contact id=”{string($response/sfdc:createResponse/sfdc:result/sfdc:id)}”/>
}
【０３２３】
応答変換により返送されるこの一次キー値は、コンジットマネージャーにより処理できると共に、クライアントアプリケーションと同期させることができる。この値は、ノードが最初に生成されたときにアプリケーションにより指定された一時的な一次キーに置き換わる。
しかしながら、一実施形態では、互いに参照する多数のノードがアプリケーションにより生成される場合には、サーバーにより返送される一次キーの値を使用して、新たに挿入されたノードを参照するノードの外部キー値も更新しなければならない。
【０３２４】
例えば、次のファンクションは、最初に、所有者ノードを生成し、次いで、それを参照するコンタクトノードを生成する。
function createContact4(account) {
var owner = $root.create(<user><email>sarah@acme.com</email></user>);
var contact =
<contact>
<first>Sarah</first>
<last>Smith</last>
<email>sarah@acme.com</email>
</contact>;
contact.@@owner = owner;
return account.create(contact);
}
【０３２５】
ユーザノードに対するコンジット挿入オペレーションは、コンタクトノードに対するコンジット挿入オペレーションの前にコールされ、そしてそのコンタクトノードのｏｗｎｅｒＩｄ属性は、第１コンジットオペレーションから返送される適切な外部キー値を含む。
【０３２６】
シーケンスナンバー
ある場合に、ノードを生成するためにコールされるウェブサービスメソッドは、シーケンスナンバーを返送しないことがある。コンジットは、単一のコンジットオペレーション内で多数のウェブサービスコールを行って、この情報を検索することができる。
例えば、先のセクションで定義されたコンジットオペレーションは、次のように拡張される。
/**
* @mas:operation type=”insert” node=”app:contact” 
* @mas:transform type=”request” function=”insertContact_request”
* @mas:transform type=”response” function=”insertContact_response”
*/
function insertContact($msg, $source) {
var response = ws.invoke($msg);
var id = response.sfdc:createResponse.sfdc:result.sfdc:id;
// retrieve sequence number
var msg2 = createMessage(requestTimestamp(id));
var response2 = ws.invoke(msg2);
// return both responses
response.body += response2.body.sfdc:queryResponse;
return response;
}
/**
* @language:body type=”xquery”
* @mas:namespace target=”sfdc”
*/
function requestTimestamp($id) {
<query>
<queryString>
SELECT Id, SystemModstamp FROM Contact
WHERE Id = ”{$id}”
</queryString>
</query>
}
/**
* @language:body type=”xquery”
* @mas:namespace target=”sfdc”
*/
function insertContact_request($node) {
<create>
<sObjects xsi:type=”Contact”>
<AccountId>{string($node/app:@accountId})</AccountId>
<OwnerId>{string($node/app:@ownerId})</OwnerId>
<FirstName>{string($node/app:first)}</FirstName>
<LastName>{string($node/app:last)}</LastName>
<Email>{string($node/app:email)}</Email>
</sObjects>
</create>
}
/**
* @language:body type=”xquery”
* @mas:namespace target=”app”
*/
function insertContact_response($response) {
<contact id=”{string($response/sfdc:createResponse/sfdc:result/sfdc:id)}”>
<modified>
{string($response/sfdc:queryResponse/sfdc:records/sfdc:SystemModstamp)}
</modified>
</contact>
}
【０３２７】
要求変換
要求変換は、先のセクションで定義されたものと同じウェブサービスメッセージを生成することができる。
/**
* @language:body type=”xquery”
* @mas:namespace target=”sfdc”
*/
function insertContact_request($node) {
<create>
<sObjects xsi:type=”Contact”>
<AccountId>{string($node/app:@accountId})</AccountId>
<OwnerId>{string($node/app:@ownerId})</OwnerId>
<FirstName>{string($node/app:first)}</FirstName>
<LastName>{string($node/app:last)}</LastName>
<Email>{string($node/app:email)}</Email>
</sObjects>
</create>
}
【０３２８】
コンジットファンクション
しかしながら、この場合に、コンジットの自動的に発生されたＸＳｃｒｉｐｔファンクションは、２つのウェブサービスコールを呼び出すように変更することができる。第１に、要求変換から返送されるメッセージを使用して、ノードを挿入し、そして挿入されたノードの一次キーを検索することができる。
/**
* @mas:operation type=”insert” node=”app:contact” 
* @mas:transform type=”request” function=”insertContact_request”
* @mas:transform type=”response” function=”insertContact_response”
*/
function insertContact($msg, $source) {
var response = ws.invoke($msg);
var id = response.sfdc:createResponse.sfdc:result.sfdc:id;
【０３２９】
次いで、挿入されたノードの一次キーｉｄを、コンジットで定義されたヘルパーＸＱｕｅｒｙファンクションｒｅｑｕｅｓｔＴｉｍｅｓｔａｍｐ（）へ通すことにより、新たなメッセージオブジェクトが生成される。
// retrieve sequence number
var msg2 = createMessage(requestTimestamp(id));
var response2 = ws.invoke(msg2);
【０３３０】
ヘルパーファンクションは、変換と同じ言語及びｎａｍｅｓｐａｃｅ注釈を宣言するが、それらは、コンジットオペレーションの注釈により参照されない。このファンクションは、新たに生成されるノードに対するシーケンスナンバーを返送するコンジットオペレーションを呼び出すように適当なメッセージを構成する。
/**
* @language:body type=”xquery”
* @mas:namespace target=”sfdc”
*/
function requestTimestamp($id) {
<query>
<queryString>
SELECT Id, SystemModstamp FROM Contact
WHERE Id = ”{$id}”
</queryString>
</query>
}
【０３３１】
最終的に、両ウェブサービスオペレーションの結果は、両メッセージ本体で構成される単一のＸＭＬオブジェクトを生成することにより合成できる。
// return both responses
response.body += response2.body.sfdc:queryResponse;
return response;
}
【０３３２】
応答変換
応答変換は、コンジットファンクションにより生成されたＸＭＬオブジェクトを処理し、そして一次キーとノードのシーケンスナンバーの両方を含む単一の＜ｃｏｎｔａｃｔ＞ノードを返送することができる。
/**
* @language:body type=”xquery”
* @mas:namespace target=”app”
*/
function insertContact_response($response) {
<contact id=”{string($response/sfdc:createResponse/sfdc:result/sfdc:id)}”>
<modified>
{string($response/sfdc:queryResponse/sfdc:records/sfdc:SystemModstamp)}
</modified>
</contact>
}
【０３３３】
更新
更新オペレーションは、クライアントアプリケーションがノードを変更したときにコンジットマネージャーによりコールすることができる。
エンタープライズがデータの更新を要求されたときに、それを拒否するポリシー／プロセスがあるか、又は誰か他のものがデータを最初に変更したために、拒絶することが考えられる。第１の問題は、不可避であり、そして他の全てと同様に、更新オペレーションが失敗をハンドリングできることを要求する。フレームワークは、第２のケースに対する楽観的同時性モデルを実施することができる。
【０３３４】
更新要求は、それがウェブサービスオペレーションへ送信されるときに、変更された値を含むだけでなく、レコードが変更されたときにそれが最新のものであったかどうか決定するのに使用できるシーケンスナンバーも含むことができる。（コンジットマネージャーｃａｂは、セレクトオペレーションのウェブサービスがそれ自身のシーケンスナンバーを返送しない場合にノード値に基づいてＭＤ５ハッシュを計算する。）
【０３３５】
クライアントにおいて、ノードは、スクリプト表現によって変更され得るが、更新は、ｕｐｄａｔｅ（）ファンクションが特定ノードにおいてコールされるまでサーバーと同期されず、例えば、
function modify(contact, address) {
contact.email = address;
contact.update();
}
【０３３６】
一実施形態において、クライアントアプリケーションも、更新オペレーションも、キー値（即ち、キー定義により記述される任意のフィールド）を変更することがない。
更新オペレーションは、次の形態をもつことができる。
/**
* @mas:operation type=”update” node=”nodeName”
* @mas:transform type=”request” function=”functionName_request”
* @mas:transform type=”response” function=”functionName_response”
*/
function functionName($msg, $source) {
return ws.invoke($msg);
}
【０３３７】
オペレーション注釈は、アプリケーションスキーマに対応するｎｏｄｅｔｙｐｅ宣言する。
更新オペレーションの要求変換は、ウェブサービスオペレーションに対するメッセージ本体を生成することができ、これは、オペレーションのためのコンテクストを与える次のシステム変数を参照することができる。
2007524933.tif 000032
【０３３８】
更新オペレーションの応答変換は、応答メッセージ本体を、変更されたレコードのシーケンスナンバーを含む部分的に構成されたノードへとマップすることができる。更新オペレーションの応答変換は、次のシステム変数を参照することができる。
2007524933.tif 000033
【０３３９】
例
次のファンクションは、コンタクトノードに対する更新コンジットオペレーションを実施する。
/**
* @mas:operation type=”update” node=”app:contact” 
* @mas:transform type=”request” function=”updateContact_request”
* @mas:transform type=”response” function=”updateContact_response”
*/
function updateContact($msg, $source) {
ws.invoke($msg);
// retrieve sequence number
var msg2 = createMessage(requestTimestamp($source/@id));
var response2 = ws.invoke(msg2);
return response2;
}
/**
* @language:body type=”xquery”
* @mas:namespace target=”sfdc”
*/
function updateContact_request($node) {
<update>
<sObjects xsi:type=”Contact”>
<Id>{string($node/app:@id})</Id>
<LastModifiedDate>{string($node/app:modified})</LastModifiedDate>
<AccountId>{string($node/app:@accountId})</AccountId>
<OwnerId>{string($node/app:@ownerId})</OwnerId>
<FirstName>{string($node/app:first)}</FirstName>
<LastName>{string($node/app:last)}</LastName>
<Email>{string($node/app:email)}</Email>
</sObjects>
</update>
}
/**
* @language:body type=”xquery”
* @mas:namespace target=”app”
*/
function updateContact_response($response) {
let $i := $response/sfdc:queryResponse/sfdc:result/sfdc:records
return
<contact id=”{string($i/sfdc:Id)}”>
<modified>{string($i/sfdc:SystemModstamp)}</modified>
</contact>
}
【０３４０】
要求変換
要求変換は、更新オペレーションを呼び出すのに使用されるウェブサービスメッセージを生成することができる。
/**
* @language:body type=”xquery”
* @mas:namespace target=”sfdc”
*/
function updateContact_request($node) {
<update>
<sObjects xsi:type=”Contact”>
<Id>{string($node/app:@id})</Id>
<LastModifiedDate>{string($node/app:modified})</LastModifiedDate>
<AccountId>{string($node/app:@accountId})</AccountId>
<OwnerId>{string($node/app:@ownerId})</OwnerId>
<FirstName>{string($node/app:first)}</FirstName>
<LastName>{string($node/app:last)}</LastName>
<Email>{string($node/app:email)}</Email>
</sObjects>
</update>
}
【０３４１】
要求変換は、ノードの一次キーと、レコードがサービスから検索されたときにタイムスタンプを表わすエレメントＬａｓｔＭｏｄｉｆｉｅｄＤａｔｅとにおいて通過させることができる。これは、ウェブサービスオペレーションを楽観的同時性で実施できるようにし、即ちオペレーションへ送信されたタイムスタンプ値が現在システムタイムスタンプ値に一致しない場合に、オペレーションが失敗となる。
【０３４２】
コンジットファンクション
挿入オペレーションと同様に、コンジットの自動的に発生されたＸＳｃｒｉｐｔファンクションは、２つのウェブサービスコールを呼び出すように変更することができる。第１に、要求変換から返送されるメッセージを使用して、ノードを更新する。
/**
* @mas:operation type=”update” node=”app:contact”
* @mas:transform type=”request” function=”updateContact_request”
* @mas:transform type=”response” function=”updateContact_response”
*/
function updateContact($msg, $source) {
ws.invoke($msg);
【０３４３】
次いで、更新されたノードの一次キーｉｄを、コンジットで定義されたヘルパーＸＱｕｅｒｙファンクションｒｅｑｕｅｓｔＴｉｍｅｓｔａｍｐ（）（これは、上述した挿入オペレーションに対して定義された同じファンクションである）へ通すことにより、新たなメッセージオブジェクトを生成することができる。
// retrieve sequence number
var msg2 = createMessage(requestTimestamp(id));
var response2 = ws.invoke(msg2);
最後に、第２のウェブサービスオペレーションの結果を返送して、応答変換により処理することができる。
return response2;
}
【０３４４】
応答変換
応答変換は、コンジットファンクションにより生成されたＸＭＬオブジェクトを処理して、一次キー及びノードのシーケンスナンバーの両方を含む単一＜ｃｏｎｔａｃｔ＞ノードを返送することができる。
/**
* @language:body type=”xquery”
* @mas:namespace target=”app”
*/
function updateContact_response($response) {
let $i := $response/sfdc:queryResponse/sfdc:result/sfdc:records
return
<contact id=”{string($i/sfdc:Id)}”>
<modified>{string($i/sfdc:SystemModstamp)}</modified>
</contact>
}
【０３４５】
競合管理
クライアントが、外部システムにおいて既に更新された（別のクライアントによるか又は他の外因性変化プロセスにより）「古い」ノードを変更しそして同期しようと試みるときに、ノードの競合が生じ得る。古いノードとは、サーバーにより保持された現在シーケンスナンバーとは異なるシーケンスナンバーを有するものである。
【０３４６】
ＭＡＳは、クライアントが更新しようと試みるものより最近のバージョンのノードをキャッシュ記憶した場合に、更新されたノードで直接応答し（即ち、コンジットオペレーションを呼び出すことなく）、ｍａｓ：ｓｔａｔｅ属性を「ｃｏｎｆｌｉｃｔ（競合）」にセットすることがある。
【０３４７】
ノードが古いためにコンジットオペレーションが更新を拒絶する場合には、最新のノードを適当なｍａｓ：ｓｔａｔｅ属性と共に返送することができ、これは、最新のノードを選択するための別のラウンドトリップを伴うことがある。
【０３４８】
例
次の更新オペレーションファンクションは、ウェブサービスにより返送されるエラー値をチェックする。要求変換は、上記で定義されたものと同じである。
/**
* @mas:operation type=”update” node=”app:contact”
* @mas:transform type=”request” function=”updateContact_request”
* @mas:transform type=”response” function=”updateContact_response”
*/
function updateContact($msg, $source) {
var response = ws.invoke($msg);
// check for error
if (! response.body.sfdc:updateResponse.sfdc:result.sfdc:success) {
// retrieve server's record
msg = createMessage(selectContact_request($source/@id));
response = ws.invoke(msg);
// set state expando
var node = response.body.sfdc:queryResponse.sfdc:result.sfdc:records;
node.@state=”conflict”;
}
else {
// retrieve sequence number
msg = createMessage(requestTimestamp($source/@id));
response = ws.invoke(msg);
}
return response;
}
/**
* @language:body type=”xquery”
* @mas:namespace target=”app”
*/
function updateContact_response($response) {
let $i := $response/sfdc:queryResponse/sfdc:result/sfdc:records
if ($i.@!= null)
then
<contact id=”{string($i/sfdc:Id)}” accountId=”{string($i/sfdc:AccountId)}”
mas:state=”{$response.result.@state}”>
<modified>{string($i/sfdc:SystemModstamp)}</modified>
<fist>{string($i/sfdc:FistName)}</first>
<last>{string($i/sfdc:LastName)}</last>
<email>{string($i/sfdc:Email)}</email>
</contact>
else
<contact id=”{string($i/sfdc:Id)}”>
<modified>{string($i/sfdc:SystemModstamp)}</modified>
</contact>
}
【０３４９】
コンジットファンクション
コンジットファンクションは、第１に、ウェブサービスにより返送されるエラー値をチェックすることができる。
function updateContact($msg, $source) {
var response = ws.invoke($msg);
// check for error
if (! response.body.sfdc:updateResponse.sfdc:result.sfdc:success) {
【０３５０】
エラーが返送される場合には、このファンクションは、全ノードに対するウェブサービスに要求問合せを送信することができ、ここで、オペレーションは、コンテクストフリーセレクトオペレーションの要求変換を再使用する。
// retrieve server's record
msg = createMessage(selectContact_request($source/@id));
response = ws.invoke(msg);
【０３５１】
次いで、オペレーションは、ｅｘｐａｎｄｏ  ｓｔａｔｅ属性を生成し、競合レコードがサーバーから検索されたことを応答変換で検出できるようにする。
// set state expando
var node = response.body.sfdc:queryResponse.sfdc:result.sfdc:records;
node.@state=”conflict”;
【０３５２】
オリジナルのウェブサービスメソッドが成功であった場合には、ファンクションは、更新されたシーケンスナンバー（上述した）だけを要求するに過ぎない。
// retrieve sequence number
msg = createMessage(requestTimestamp($source/@id));
response = ws.invoke(msg);
【０３５３】
更新が成功したかどうかに関わらず、応答は、応答変換により処理される。
return response;
}
【０３５４】
応答変換
応答変換は、最初に、ｓｔａｔｅ  ｅｘｐａｎｄｏ属性がコンジットオペレーションにより生成されたかどうか調べるためのチェックを行うことができる。もしそうであれば、この変換は、完全なノードエレメントを構成することができ、さもなければ、上述したように、一次キー及びシーケンスナンバーのみを返送することができる。
function updateContact_response($response) {
let $i := $response/sfdc:queryResponse/sfdc:result/sfdc:records
if ($i.@state != null)
then
<contact id=”{string($i/sfdc:Id)}” accountId=”{string($i/sfdc:AccountId)}”
mas:state=”{$i.@state}”>
<modified>{string($i/sfdc:SystemModstamp)}</modified>
<fist>{string($i/sfdc:FistName)}</first>
<last>{string($i/sfdc:LastName)}</last>
<email>{string($i/sfdc:Email)}</email>
</contact>
else
<contact id=”{string($i/sfdc:Id)}”>
<modified>{string($i/sfdc:SystemModstamp)}</modified>
</contact>
}
【０３５５】
リンキング及びアンリンキング（外部キーの変更）
ノードは、ＸＳｃｒｉｐｔ表現により変更することができる。これは、外部キー値についても適用される。このセクションの例は、アカウント及びコンタクトｎｏｄｅｔｙｐｅを使用し、これらは、次のキー定義を宣言する。
<xsd:key name=”accountKey”>
<xsd:selector xpath=”account”/>
<xsd:field xpath=”@id”/>
</xsd:key>
<xsd:key name=”contactPrimaryKey”>
<xsd:selector xpath=”contact”/>
<xsd:field xpath=”@id”/>
</xsd:key>
<xsd:key name=”contactEmailKey”>
<xsd:selector xpath=”contact”/>
<xsd:field xpath=”email”/>
</xsd:key>
【０３５６】
次のファンクションは、ノードのキー値を変更する試みがなされるので、ランタイムエラーを発生することになる。
function foobar(contact) {
contact.first = $context.first;
contact.last = $context.last;
contact.email = $context.email;              // runtime error
}
【０３５７】
しかしながら、次のファンクションは、アカウント属性を首尾良く変化させ、これは、アカウントノードを参照する外部キー値を変化させる。
function foo(contact, account) {
contact.first = $context.first;
contact.last = $context.last;
contact.@@accountId = account;          // changes account foreign key
contact.update();
}
【０３５８】
ここで、外部キーは、次のｋｅｙｒｅｆ宣言により定義される。
<xsd:keyref name=”contactAccountRef” refer=”accountKey” mas:alias=”account”>
<xsd:selector xpath=”contact”/>
<xsd:field xpath=”@accountId”/>
</xsd:keyref>
【０３５９】
同様に、以下のファンクションは、＋＝演算子（ａ．ｋ．ａ．ｌｉｎｋ（）ファンクション）を使用して、コンタクトノードを、アカウントに対する１組のコンタクトに追加する。
function bar(account, contact) {
account.@@contacts += contact;
}
【０３６０】
この１対多の関係は、逆の関係を含む次のｋｅｙｒｅｆ宣言により定義される。
<xsd:keyref name=”contactAccountRef” refer=”accountKey”
mas:alias=”account” mas:inverseAlias=”contacts”>
<xsd:selector xpath=”contact”/>
<xsd:field xpath=”@accountId”/>
</xsd:keyref>
【０３６１】
実際に（即ち、外部データベースでは）、このオペレーションは、コンタクトエンティティ（行）のａｃｃｏｕｎｔ外部キーをアカウントの一次キーにセットすることにより実施できる。ソースノードにおいて外部キー値をセットすると（例えば、ｃｏｎｔａｃｔ．＠＠ａｃｃｏｕｎｔＩｄ）、当然、ターゲットノードからソースノードへの逆のトラバース（例えば、ａｃｃｏｕｎｔ．＠＠ｃｏｎｔａｃｔｓ．＊）が可能になるはずであり、そしてそれとは逆のことも言える。
【０３６２】
上記定義が与えられると、次のファンクションが同等である。
function foo1(contact, account) {
contact.first = $context.first;
contact.last = $context.last;
contact.@@accountId = account;
update(contact);
}
function foo2(contact, account) {
contact.first = $context.first;
contact.last = $context.last;
account.@@contacts += contact;
update(contact);
}
【０３６３】
一実施形態では、スキーマの外部キーエレメント（又は属性）宣言は、外部システムの制約（又はウェブサービスオペレーションのセマンティックにより課せられたもの）に一致する。特に、ＮＯＴ  ＮＵＬＬ外部キー値（例えば、データベーステーブルフィールドにおいて宣言された）は、属性の場合にはｘｓｄ：ｕｓｅ”ｒｅｑｕｉｒｅｄ”そしてエレメントの場合にはｍｉｎＯｃｃｕｒｓ＝”１”ｍａｘＯｃｃｕｒｓ＝”１”により鏡像とならねばならない。
【０３６４】
例えば、上記定義が与えられると、次のファンクションは、ランタイムエラーを発生することになる。
function foo(contact) {
contact.first = $context.first;
contact.last = $context.last;
contact.@@accountId = null;
update(contact);
}
【０３６５】
カスタム問合せ
データは、２つのｎｏｄｅｔｙｐｅ間の定義されたｋｅｙｒｅｆ関係に関連するセレクトコンジットオペレーションを実施することにより検索することができ、即ち１つのノード内に含まれた外部キー値は、関連ノードの一次キーを識別する。これらのセレクトオペレーションの出力は、フレームワークによりローカルキャッシュへと収納されるノードである。
【０３６６】
カスタム問合せは、クライアントプログラミングモデルにとって不透明で、即ち一次キー及び外部キー関係に排他的に基づいてデータを明確に選択（又は変更）しないコンジット問合せ（又は他の手順ロジック）である。例えば、サーチオペレーションが、自然言語表現に一致する１組のＸＭＬオブジェクトを返送してもよい。
【０３６７】
図８のマトリクスにより異なる種類のオペレーションが特徴付けられる。これらのオペレーションは、一時的データ又は永久的データとして分類される入力及び出力を有する。一実施形態では、一時的データは、アプリケーションのノードグラフの一部分ではなく、即ちスキーマ、ｋｅｙ又はｋｅｙｒｅｆ宣言により定義されず、そしてフレームワークによりローカルキャッシュへ自動的に収納されない。一時的データは、持続すると仮定されないが、クライアントアプリケーションフレームワークにより決定されたライフサイクルを有するシステム＄ｃｏｎｔｅｘｔ又は＄ｓｅｓｓｉｏｎ変数により参照されてもよい。永久的データは、スキーマにより定義されたアプリケーションデータノードで全体的に構成することができる。
【０３６８】
一実施形態において、カスタム問合せを実施するための２つのメカニズムがある。
１．カスタムオペレーションは、クライアントが、不透明な一時的ＸＭＬオブジェクト（文書）を特定のコンジットオペレーションへ通過させるのを許すことができる。このオペレーションは、一時的なＸＭＬ文書をクライアントコールバックへ非同期で返送することができる。
例えば、次のカスタムオペレーションｍｙＱｕｅｒｙは、ＸＭＬオブジェクト＜ｍｙＲｅｑｕｅｓｔ＞を入力として取り出し、そしてＸＭＬオブジェクトｍｙＣａｌｌｂａｃｋ（）ファンクションを返送する。
$root.myQuery(<myRequest>product mobile application</myRequest>, myCallback);
function myCallback(myOutput) {
...
}
【０３６９】
２．カスタムオブジェクトは、グラフの一部分となる非永続的モデル（スキーマにより定義された）の生成を伴うことができる。このオペレーションは、クライアントがそれに対応するｋｅｙｒｅｆを「通してトラバース」するときに呼び出すことができ、この場合、カスタムオブジェクトは、＄ｓｏｕｒｃｅノードとしてそれに対応するセレクトコンジットオペレーションへ通過される。
例えば、次のカスタムオブジェクト＜ｔａｋｅＱｕｅｒｙ＞が、タスクノードをｔａｓｋＱｕｅｒｙノードに関連付けるｋｅｙｒｅｆとして定義されたセレクトコンジットオペレーションへ送信される。
var query = $root.@@taskQueries.create(<taskQuery priority=”1”/>);
var tasks = query.@@tasks.*;
【０３７０】
カスタムオペレーション
カスタムオペレーションは、カスタムコンジットオペレーション（ファンクション）をコールするためのメカニズムである。ファンクション入力及び出力は、両方とも、ＸＭＬ文書リテラル（スキーマにより定義されない）である。一実施形態では、フレームワークは、結果をローカルキャッシュへ直接収納しない。
【０３７１】
例えば、ｅメールの受信から手を引いていないコンタクト（特定アカウントに対して）のための１組のｅメールアドレスの検索を希望すると仮定する。
次のコードクライアントコードは、ＸＭＬオブジェクト＜ｑｕｅｒｙ＞が通されたカスタムオペレーションｇｅｔＬｉｓｔをコールする。
function bar() {
account.getList(<query optedOut=”false”/>, callback);
}
function callback(result) {
for (i = 0; i < result.length; i++) {
addAddress(result[i].email);
}
}
【０３７２】
コールバックは、ＭＡＳから結果が返送されたときにそれを処理する。
以下のＸＱｕｅｒｙファンクションは、カスタム要求を実施する。
/**
* @mas:namespace target=”sfdc”
* @mas:field xpath=”@id”
* @language:body type=”xquery”
*/
function foo_request($source, $query) {
<query>
<queryString>
SELECT Id, Email FROM Contact
WHERE AccountId = ”{string($source/@id)}”
AND HasOptedOutOfEmail = {boolean($query/@optedOut)}
</queryString>
</query>
}
【０３７３】
ウェブサービスからの応答は、次のファンクションにより処理できる。結果が、単一のＸＭＬ文書としてクライアントコールバックへ返送され、即ちこれは、ローカルキャッシュへ収納されるノードとして解釈されない。
/**
* @mas:namespace target=”app”
* @language:body type=”xquery”
*/
function foo_response($response) {
for $i in $response/sfdc:queryResponse/sfdc:result/sfdc:records
return
<contact id=”{string($i/sfdc:Id)}”>
<email>{string($i/sfdc:Email)}</email>
</contact>
}
【０３７４】
カスタムオペレーション定義は、クライアントファンクションネームと、オペレーションに対するコンテクストとを宣言できる。
/**
* custom operatoin on contact: account.getList(<query optedOut=”false”/>);
* @mas:operation type=”custom” node=”app:account” name=”getList”
* @mas:transform type=”request” function=”foo_request”
* @mas:transform type=”response” function=”foo_response”
*/
function foo($msg, $source, $query) {
$msg.header += createHeader();
return ws.invoke($msg);
}
【０３７５】
カスタムオブジェクト
カスタムオブジェクトは、グラフの一部分となる非永続的ノード（スキーマにより定義される）の生成を伴うことができる。このオペレーションは、クライアントがそれに対応するｋｅｙｒｅｆを「通してトラバース」するときに呼び出すことができ、この場合、カスタムオブジェクトは、＄ｓｏｕｒｃｅノードとしてそれに対応するセレクトコンジットオペレーションへ通すことができる。
【０３７６】
実際に、カスタムオブジェクトは、そのカスタムオブジェクトにバインディングされるノードを返送するコンジットオペレーションのための入力データを含むことができる。これは、その後のクライアントテンプレート及びアクションによって参照されるノードと、結果を最新状態に保つために返送されるべきオペレーションとに対して、結果がクライアントキャッシュの一部分となるようにすることができる。
【０３７７】
例えば、次のスキーマ宣言は、ｐｒｉｏｒｉｔｙ属性の値に基づいてｔａｓｋノードの副組を選択するのに使用されるカスタムオブジェクトｔａｓｋＱｕｅｒｙを定義することができる。
<xsd:complexType name=”taskQuery”>
<xsd:attribute name=”priority” type=”xsd:string”/>
</xsd:complexType>
【０３７８】
次のキー定義は、各ｔａｓｋＱｕｅｒｙオブジェクトが独特であることを保証する。
<xsd:keyref name=”taskQueryKey”>
<xsd:selector xpath=”taskQuery”/>
<xsd:field xpath=”@priority”/>
</xsd:keyref>
【０３７９】
次のｋｅｙｒｅｆ定義は、ｔａｓｋＱｕｅｒｙノードをルートノードにバインディングするのに使用され、これは、ルートノードを参照するダミーの外部キー属性ｍａｓ：ｒｏｏｔを宣言し、ｉｎｖｅｒｓｅＡｌｉａｓ属性は、ルートノードから１組のｔａｓｋＱｕｅｒｙノードへのトラバース、即ち＄root.@@taskQueries.*を宣言する。
<xsd:keyref name=”taskQueryRootRef” refer=”mas:rootKey” 
mas:inverseAlias=”taskQueries”>
<xsd:selector xpath=”taskQuery”/>
<xsd:field xpath=”@mas:rootId”/>
</xsd:keyref>
【０３８０】
次のｋｅｙｒｅｆは、ｔａｓｋＱｕｅｒｙノードと、コンジット問合せオペレーションにより返送されるｔａｓｋノードとの間の関係を定義する。各ｔａｓｋノードは、それを選択した対応する問合せを識別するダミーのｔａｓｋＱｕｅｒｙ外部キー属性を宣言し、ｉｎｖｅｒｓｅＡｌｉａｓ属性は、ｔａｓｋＱｕｅｒｙノードから１組のタスクノードへのトラバース、即ちquery.@@tasks.*を宣言する。
<xsd:keyref name=”taskTaskQueryRef” refer=”TaskQueryKey”
mas:inverseAlias=”tasks”>
<xsd:selector xpath=”task”/>
<xsd:field xpath=”@taskQuery”/>
</xsd:keyref>
【０３８１】
これらのｋｅｙｒｅｆ定義は、ルートノードと、図１２Ｄに示したｔａｓｋＱｕｅｒｙ及びｔａｓｋノードとの間の次の関係を定義する。
ｔａｓｋＱｕｅｒｙノードは、標準的なｃｒｅａｔｅ（）ファンクションを使用してクライアントスクリプトにより生成されてもよい。
function init() {
var f = $root.@@taskQueries.create(<taskQuery priority=”1”/>);
}
【０３８２】
一実施形態において、ｔａｓｋＱｕｅｒｙＲｏｏｔＲｅｆのｋｅｙｒｅｆに対して定義されたコンジット挿入オペレーションは存在せず、従って、このクライアントスクリプトは、いずれのサーバーアクティビティもトリガーしない。
次のテンプレートは、逆ｔａｓｋＴａｓｋＱｕｅｒｙＲｅｆのｋｅｙｒｅｆ定義をトラバースする。
<netui:repeater id=”$s” 
source=”$root.@@taskQueries.where(priority=='1').@@tasks.*”>
<p>{$s}</p>
</netui:repeater>
【０３８３】
これは、関連コンジットオペレーションにおいて暗示的セレクトを生じさせ、リピータのソース属性は、上述したように生成されたｔａｓｋＮｏｄｅを参照し、そしてこれは、トラバースのためのソースコンテクストとして使用され、即ちノード＜ｔａｓｋＱｕｅｒｙｐｒｉｏｒｉｔｙ＝‘１’／＞が、＄ｓｏｕｒｃｅ変数としてオペレーションへ通される。
【０３８４】
それに対応するコンジットセレクトオペレーションは、次のファンクションにより定義される。
/**
* @mas:operation type=”select” keyref=”app:taskTaskQueryRef” inverse=”true”
* @mas:transform type=”request” function=”selectTasks_request”
* @mas:transform type=”response” function=”selectTasks_response”
*/
function selectTasks($msg, $source) {
return ws.invoke($msg);
}
/**
* @mas:namespace target=”sfdc”
* @mas:field xpath=”@priority”
* @language:body type=”xquery”
*/
function selectTasks_request($source) {
<query>
<queryString>
SELECT Id, Priority, Subject FROM Task
WHERE Priority = ”{string($source/@priority})”
</queryString>
</query>
}
/**
* @mas:namespace target=”app”
* @language:body type=”xquery”
*/
function selectTasks_response($response) {
for $i in $response/sfdc:queryResponse/sfdc:result/sfdc:records
return
<task id=”{string($i/sfdc:Id)}”
priority=”{string($i/sfdc:Priority)}”>
<subject>{string($i/sfdc:Subject)}</subject>
</task>
}
【０３８５】
又、アプリケーションは、「プリキャンド(pre-canned)」問合せを表わすカスタムオブジェクトを「シード(seed)」するためのコンジットセレクトオペレーションも定義することができる。例えば、次のオペレーションは、クライアントが$root.@@taskQueries.*をトラバースするときに（一定）組のｔａｓｋＱｕｅｒｙオブジェクトを返送するセレクトオペレーションを実施する。
/**
* @mas:operation type=”select” keyref=”app:taskQueryRootRef” inverse=”true”
*/
function selectTasks($msg, $source) {
return   <taskQuery priority='1'/><taskQuery priority='2'/>;
}
【０３８６】
この問合せは、例えば、次のテンプレートにより参照することができる。
<td>
<netui:repeater id=”s1” source=”$root.@@taskQueries.*”>
<a href=”s1.select(s1.iterator)”>Priority {s1}</a>
</netui:repeater>
</td>
<td>
<netui:repeater id=”s2” source=”s1.selected.@@tasks.*”>
<p>{s2}</p>
</netui:repeater>
</td>
【０３８７】
第１リピータｓ１は、１組のｔａｓｋＱｕｅｒｙオブジェクトを表示し、第２リピータｓ２は、第１リピータにより選択されたｔａｓｋＱｕｅｒｙから検索される得られたタスクを表示する。
2007524933.tif 000034
【０３８８】
もちろん、これら問合せオブジェクトを持続させ、実際には、それらをデータモデル内の普通のノードとして処理するウェブサービスを実施することにより、カスタムオブジェクトを挿入し、更新し、そして削除するコンジットオペレーションを定義することもできる。
【０３８９】
カスタムオブジェクトノードが、クライアントアプリケーションにより直接変更されるか、又は同期セレクトオペレーションにより間接的に変更されるときには、全ての対応する関係ノードをカスタムオブジェクトから自動的にアンリンクすることができ、即ち外部キー値を経てオブジェクトを参照するノードが、この外部キーをナルにセットする。これは、カスタムオブジェクトを経てトラバースされるノードがカスタムオブジェクトの状態を正確に反映することを保証する。
【０３９０】
進歩型セレクトオペレーション
セレクトオペレーションは、フレームワークが特定ｋｅｙｒｅｆに対するノードを検索できるようにする。コンジットは、セレクトオペレーションを定義することができる。というのは、これは、クライアントアプリケーションによりノードを検索するのに使用される基本的メカニズムだからである。
【０３９１】
通常のセレクトオペレーションは、クライアントアプリケーションにより、それらがデータモデルをナビゲーションするときに、自動的にトリガーすることができる。例えば、次のクライアントＳＰａｔｈ表現は、ａｃｃｏｕｎｔ  ｋｅｙｒｅｆのセレクトオペレーションを呼び出させる。
$account.@@contacts.*
コンジットセレクトオペレーションには、対応するアカウントオブジェクトの一次キーを通過させることができる。このセクションは、他の形態のセレクトオペレーションを詳述する。
【０３９２】
キャッシュ記憶及び最適化
クライアント及びＭＡＳは、両方とも、コンジットマネージャーにより返送されるデータをキャッシュ記憶することができる。それ故、各々のデータグラフトラバースがセレクト要求を発生しなくてよいことはない。クライアント及びサーバーの両キャッシュは、新たなセレクト要求が発生されるまでに、対応する１組のデータに、どれほど長時間、最新のものとして依存できるか決定するメタデータを、各ノード及びｎｏｄｅｓｅｔに対して維持することができる。
【０３９３】
セレクトオペレーションに続いて転送する必要のあるデータの量は、しばしば、かなり多量である。それ故、適当なウェブサービスオペレーションの利用性が与えられると、フレームワークによりある最適化を実施することができる。
【０３９４】
ｓｅｌｅｃｔ＿ｐｋｅｙオペレーションは、ｓｅｌｅｃｔオペレーションと全く同様に呼び出されるが、一次キー値の組しか返送しない。例えば、上述したコンタクトｋｅｙｒｅｆにおける対応するセレクトオペレーションに対するｓｅｌｅｃｔ＿ｐｋｅｙは、次の応答変換を実施する。
/**
* @language:body type=”xquery”
* @mas:namespace target=”app”
*/
function selectContactsByAccount_response($response) {
for $i := $response/sfdc:queryResponse/sfdc:result/sfdc:records
return
<contact id=”{string($i/sfdc:Id)}”>
<modified>{string($i/sfdc:SystemModstamp)}</modified>
</contact>
}
【０３９５】
次いで、ＭＡＳは、ノードエレメントのどれが（もしあれば）、キャッシュに現在存在するか決定することができる。
キャッシュ内に含まれないノードについては、フレームワークがｓｅｌｅｃｔ＿ｓｅｔオペレーションをコールすることができ、これは、通常のセレクトオペレーションと同様に、要求された１組のｐｋｅｙ値に対して完全なノードを返送する。例えば、上述したｓｅｌｅｃｔ＿ｓｅｔオペレーションは、次の要求変換を実施する。
/**
* @language:body type=”xquery”
* @mas:namespace target=”sfdc”
*/
function selectContacts_request($keyset) {
<query>
<queryString>
SELECT * FROM Contact
WHERE Id IN (
{
for $x in $keyset
return
{$x},
}
)
</queryString>
</query>
}
【０３９６】
応答変換は、通常のセレクトオペレーションに対するものと同じでよい。
複雑なスキーマの選択
セレクトオペレーションは、中継されるエレメントを含む複雑な文書として定義されたノードを返送することができる。ｎｏｄｅｔｙｐｅのスキーマ定義の複雑さについては制約が課せられない。しかしながら、ノードレコードのサイズについては実際上の制限が生じ得る。次のセクションは、複雑な文書を多数のノードに分割できるときのケースを詳述する。
例
以下のスキーマは、多数のｌｉｎｅＩｔｅｍエレメントを含むｐｕｒｃｈａｓｅＯｒｄｅｒ  ｎｏｄｅｔｙｐｅを示す。
<xsd:element name=”purchaseOrder” type=”purchaseOrderType”>
<xsd:complexType name=”purchaseOrderType”>
<xsd:sequence>
<xsd:element name=”price” type=”xsd:double”/>
...
<xsd:complexType name=”lineItems”>
<xsd:sequence maxOccurs=”unbounded”>
<xsd:complexType ref=”lineItem”>
<xsd:sequence>
<xsd:element name=”prodId” type=”xsd:string”/>
...
</xsd:sequence>
</xsd:complexType>
</xsd:sequence>
</xsd:complexType>
</xsd:sequence>
</xsd:complexType>
【０３９７】
例えば、次のＸＭＬ文書は、購入注文スキーマを示す。
<purchaseOrder>
<price>1000.00</price>
...
<lineItems>
<lineItem>
<prodId>Widget-X</prodId>
...
</lineItem>
<lineItem>
<prodId>Widget-Y</prodId>
...
</lineItem>
...
</lineItems>
</purchaseOrder>
【０３９８】
次のコンジットファンクションは、ネスト状の１組のラインアイテムを各々もつ１組の購入注文を発生するネスト状ループを含む。
/**
* @mas:operation type=”select” keyref=”purchaseOrderAccountRef” inverse=”true”
* @mas:transform type=”request” function=”selectPurchaseOrders_request”
* @mas:transform type=”response” function=”selectPurchaseOrders_response”
*/
function selectPurchaseOrders($msg, $source) {
var response = ws.invoke($msg);
var pos = response.sfdc:queryResponse.sfdc:result.sfdc:records;
// retrieve line items for each purchase order
for (i = 0; i < pos.length-1; i++) {
var msg2 = createMessage(requestLineItems(pos[i].sfdc:Id));
var response2 = ws.invoke(msg2);
pos[i] += response2.body.sfdc:queryResponse.sfdc:result.sfdc:records;
}
return response;
}
/**
* @language:body type=”xquery”
* @mas:namespace target=”sfdc”
* @mas:field xpath=”@id”
*/
function selectPurchaseOrders_request($source) {
<query>
<queryString>
SELECT * FROM PurchaseOrder
WHERE PurchaseOrder.AccountId = {string($source/@id)}
</queryString>
</query>
}
/**
* @language:body type=”xquery”
* @mas:namespace target=”sfdc”
*/
function selectLineItems($id) {
<query>
<queryString>
SELECT * FROM LineItem
WHERE LineItem.PurchaseOrderId = $id
</queryString>
</query>
}
/**
* @language:body type=”xquery”
* @mas:namespace target=”app”
*/
function selectPurchaseOrders_response($response) {
for $po := $response/sfdc:queryResponse/sfdc:result/sfdc:records
return
<purchaseOrder id=”{string($po/ws:Id)}”>
<price>{string($po/ws:Price)}</price>
...
<lineItems>
{
for $li in $po/ws:records
return
<lineItem>
<prodId>{string($li/ws:ProdId)}</prodId>
...
</lineItem>
}
</lineItems>
</purchaseOrder>
}
【０３９９】
ノードツリーの選択
セレクトオペレーションは、中継されるエレメントを含む複雑な文書として定義されたノードを返送することができる。ｎｏｄｅｔｙｐｅのスキーマ定義の複雑さには制約が課せられない。
【０４００】
あるケースでは、複雑な文書の部分を、ｋｅｙｒｅｆ関係によりバインディングされた独立したノードに分割することが望まれる。これらのノードは、クライアントへ再び同期されてキャッシュ記憶のデータグラフへ組み込まれるツリーを形成する。
【０４０１】
コンパウンド文書を多数のノードへ分割する効果は、単一のオペレーションで多数のレベルのｋｅｙｒｅｆを検索することによる性能改善である（例えば、特定アカウントに対する全てのコンタクト及び全ての関連タスクを選択する）。
【０４０２】
例
次のスキーマ定義において、ｐｕｒｃｈａｓｅＯｒｄｅｒＴｙｐｅ及びｌｉｎｅＩｔｅｍＴｙｐｅは、両方とも、次のスキーマ定義を伴うｎｏｄｅｔｙｐｅとして宣言される。
<xsd:complexType name=”purchaseOrderType”>
<xsd:complexType>
<xsd:sequence>
<xsd:element name=”price” type=”xsd:double”/>
...
<xsd:sequence>
</xsd:complexType>
<xsd:complexType>
<xsd:element name=”lineItemType”>
<xsd:complexType>
<xsd:sequence>
<xsd:element name=”prodId” type=”xsd:string”/>
...
</xsd:sequence>
</xsd:complexType>
</xsd:element>
【０４０３】
又、このスキーマは、次のｋｅｙ及びｋｅｙｒｅｆ定義も宣言する。
<xsd:key name=”purchaseOrderKey”>
<xsd:selector xpath=”purchaseOrder”/>
<xsd:field xpath=”@id”/>
</xsd:key>
<xsd:key name=”lineItemKey”>
<xsd:selector xpath=”lineItem”/>
<xsd:field xpath=”@id”/>
</xsd:key>
<xsd:keyref name=”lineItemPurchaseOrderRef” refer=”purchaseOrderKey” 
mas:inverseAlias=”lineItems”>
<xsd:selector xpath=”lineItem”/>
<xsd:field xpath=”@purchaseOrderId”/>
</xsd:keyref>
【０４０４】
図１２Ｄは、対応するｋｅｙｒｅｆを表わしている。
コンパウンド文書が個々のノードへ分割されるときには、フレームワークは、成分ノード（例えば、ラインアイテム）におけるクライアントオペレーションがコンジットによりサポートされることを保証できる。例えば、クライアントアプリケーションは、ｌｉｎｅＩｔｅｍ  ｋｅｙｒｅｆに対して対応する挿入オペレーションがない限り、新たなラインアイテムオブジェクトを生成することが防止され得る。
【０４０５】
以下のコンジット定義は、前記例の変更バージョンである。ここでは、内部ループは、ｎｏｄｅｓｅｔエレメント内にノードエレメントを生成する。又、内部オブジェクトは、各々、一次キーを定義しなければならない。
/**
* @mas:operation type=”select” keyref=”purchaseOrderAccountRef” inverse=”true”
* @mas:transform type=”request” function=”selectPurchaseOrders_request”
* @mas:transform type=”response” function=”selectPurchaseOrders_response”
*/
function selectPurchaseOrders($msg, $source) {
var response = ws.invoke($msg);
var pos = response.sfdc:queryResponse.sfdc:result.sfdc:records;
// retrieve line items for each purchase order
for (i = 0; i < pos.length-1; i++) {
var msg2 = createMessage(requestLineItems(pos[i].sfdc:Id));
var response2 = ws.invoke(msg2);
pos[i] += response2.body.sfdc:queryResponse.sfdc:result.sfdc:records;
}
return response;
}
/**
* @language:body type=”xquery”
* @mas:namespace target=”sfdc”
* @mas:field xpath=”@id”
*/
function selectPurchaseOrders_request($source) {
<query>
<queryString>
SELECT * FROM PurchaseOrder
WHERE PurchaseOrder.AccountId = {string($source/@id)}
</queryString>
</query>
}
/**
* @language:body type=”xquery”
* @mas:namespace target=”app”
*/
function selectPurchaseOrders_response($response) {
for $po := $response/sfdc:queryResponse/sfdc:result/sfdc:records
return
<purchaseOrder id=”{string($po/ws:Id)}”>
<price>{string($po/ws:Price)}</price>
...
<mas:nodeset keyref=”lineItemPurchaseOrderRef”>
{
for $li in $po/ws:records
return
<lineItem id=”{string($li/ws:Id)}”>
<prodId>{string($li/ws:ProdId)}</prodId>
...
</lineItem>
}
</mas:nodeset>
</purchaseOrder>
}
【０４０６】
ディープセレクト
上述したように、アプリケーションは、ＳＰａｔｈ表現を使用してデータグラフをトラバースすることができ、これらトラバースは、フレームワークがバックグランドにおいて必要なデータを同期するようにさせ得る。一実施形態において、同期メカニズムは、非同期で呼び出されるので、ＳＰａｔｈ表現を、現在キャッシュ記憶されているデータグラフに対して完全に評価できないことがしばしば生じ勝ちとなる。
【０４０７】
例えば、次のＳＰａｔｈ表現は、ｋｅｙｒｅｆアカウント及びコンタクトが予め同期されそしてクライアントによりキャッシュ記憶されていない場合には、空のリストを返送する。
$root.@@accounts.*.@@contacts.*.@@tasks.*;
【０４０８】
一実施形態において、その後のｋｅｙｒｅｆトラバースは、先行するノードが現在キャッシュに存在しない限り、開始できない。一実施形態において、クライアントコードは、先ず、$root.@@accounts.*をトラバースしなければならず、次いで、同期表示を待機し、次いで、$root.@@accounts.*.@@contacts.*を選択し、別の同期表示を待機し、そして最終的に、この表現が、全てのアカウントに対する全てのコンタクトについて全てのタスクの同期を呼び出すことになる。
【０４０９】
ｓｅｌｅｃｔ（）ファンクションは、クライアントが、サーバーに、ＳＰａｔｈ表現をそれに代わって評価し、次いで、それにより生じるノードのグラフをクライアントへ同期させることを要求できる。例えば、
$root.select(@@accounts.*.@@contacts.*.@@tasks.*);
【０４１０】
ここでは、全ＳＰａｔｈ表現がサーバーへ通過され、サーバーは、次々のｋｅｙｒｅｆトラバースをコールし、そしてノードの同期をマネージする。サーバーは、グラフ全体を１つの同期メッセージにおいて又は多数のメッセージを経て返送してもよいことに注意されたい。
又、ＳＰａｔｈ表現は、ｗｈｅｒｅ（）ファンクションを使用して述語も含んでもよい。例えば、
$root.select(@@accounts.*.@@contacts.*.@@tasks.*.where(.priority == 1));
【０４１１】
述語の表現は、得られるノードがクライアントに対して同期される前に、サーバーにおいて分析することができる。
次の表現は、タイプ＝”直接”エレメントを有する全てのアカウントに対して全てのコンタクト及びノードを検索することができる。
$root.select(@@accounts.where(.type=”Direct”).keyref(”contacts”, ”notes”).*;
【０４１２】
セッションマネージメント
セッション状態は、コンジットカスタム手順コードによりマネージすることができる。
コンジットは、セッション識別子を記憶するための変数を定義することができる。これは、コンジットにより生成されてもよいし、又はこの場合と同様に、ウェブサービスにより返送されてもよい。
// session object returned from Web service
var sessionId = null;
【０４１３】
コンジットは、セッションを開始するためのメッセージを生成して送信するファンクションを定義することができ、このファンクションは、次いで、応答を処理して、サービスにより返送されたセッション関連情報を抽出することができる。
【０４１４】
以下のファンクションは、＜ｌｏｇｉｎ＞メッセージをウェブサービスへ送信し、そして応答本体からセッション識別子を抽出する。又、サービスにより返送されるウェブサービスコントロールのＵＲＬをセットする。
// create and send login message and process results 
function login() {
var body =
<login>
<username>{$user.username}</username>
<password>{$user.password}</password>
</login>;
var response = ws.invoke(body);
// set session id
sessionId = string(response.body.sfdc:result.sfdc:sessionId);
// set URL for subsequent calls (from this conduit)
ws.endPoint = string(response.body.sfdc:result.sfdc:serverUrl);
}
【０４１５】
＄ｕｓｅｒ  ＸＭＬ変数は、現在ユーザに関する情報を含み、これは、全てのファンクションにアクセスできるシステム変数である。
各会話メソッドは、セッション識別子を含むヘッダーを指定することができ、次の（通常の）コンジットファンクションは、最初に、会話がスタートしたかどうかチェックし（もしそうでなければ、ログインをコールする）、次いで、適当なヘッダーＸＭＬフラグメントを返送する。
// create conversational header
function createHeader() {
if (sessionId == null) {
login();
}
return
<SessionHeader>
<sessiondId>{sessionId}</sessiondId>
</SessionHeader>;
}
【０４１６】
例えば、次のＸＳｃｒｉｐｔファンクションは、ウェブサービスにより必要とされるカスタムセッションマネージメントを実施する。
/**
* @mas:operation type=”select” keyref=”app:contactAcoountRef” inverse=”true”
* @mas:transform type=”request” function=”selectContacts_request”
* @mas:transform type=”response” function=”selectContacts_response”
*/
function selectContacts($msg, $source) {
$msg.header += createHeader();
return ws.invoke($msg);
}
【０４１７】
このファンクションは、要求変換により生成された本体を含むメッセージオブジェクト＄ｍｓｇにおいて通される。
次いで、このファンクションは、必要なヘッダー情報を含むＸＭＬオブジェクトを得るためにｃｒｅａｔｅＨｅａｄｅｒ（）ファンクションをコールする。このファンクションは、セッションが現在スタートしていない場合にｌｏｇｉｎ（）ファンクション（上述した）をトリガーする。次いで、ヘッダオブジェクトがメッセージに追加される。
【０４１８】
ｉｎｖｏｋｅ（）ファンクションは、次いで、メッセージ（ヘッダーを含む）をウェブサービスへ送信し、これは、指定のコントロールにより与えられたトランスポートを使用する。
ユーザ情報
＄ｕｓｅｒ変数は、どのユーザに代わってコンジットオペレーションが呼び出されるかに関するデータを含む。
2007524933.tif 000035
【０４１９】
クライアントプログラミングモデル
ユーザは、ＭＡＳにおけるそのＵＲＬを参照することによりアプリケーションにアクセスすることができる。ユーザがクライアントマシンからそれを初めて行うときに、アプリケーションの全てのコンポーネントをサーバーから自動的に「ダウンロード」することができる。アプリケーションデベロッパがアプリケーションに関するデータモデルしか指定しない場合には、そのデータモデルに対するメタデータをダウンロードすることができる。メタデータは、アプリケーションに対して最小ユーザインターフェイスを与えるに充分な移動ブラウザのための情報を含むことができる。メタデータを使用して、移動ブラウザは、ルートノード及びそのｋｅｙｒｅｆを最初に表示することができる。ユーザは、これらのｋｅｙｒｅｆをクリックすることによりアプリケーションデータを通してナビゲーションすることができる。ユーザがｋｅｙｒｅｆを選択するときに、データ同期エンジンがそのｋｅｙｒｅｆに対するノードを非同期でフェッチし、そしてデータをそれが得られたときに自動的に表示する。例えば、ユーザは、アカウントリンクをトラバースして、アカウントノードをフェッチさせ、次いで、アカウントコンタクトｋｅｙｒｅｆをトラバースして、アカウントに対するそのコンタクトを見ることができる。このモデルは、機能的であるが、特に快適なものではなく、即ちデータが予めフェッチされないので、ＵＩは、ありのままのもので、且つ経験は「ぎくしゃくした」ものである。このセクションは、アプリケーションプログラマーがユーザインターフェイスをどのようにカスタマイズできるか説明する。
【０４２０】
クライアントアプリケーションをカスタマイズするためにプログラマーが使用する基本的な人為的手段は２つある。その第１は、１組のデータに対してカスタムユーザインターフェイスを与えるのに使用できる「テンプレート」である。プログラマーは、データモデルからデータにアクセスするためのＳＰａｔｈ表現が埋め込まれると共にｎｏｄｅｓｅｔを経て中継するためのエレメントが埋め込まれたＸＨＴＭＬテンプレートである「テンプレート」を使用してノード及びｎｏｄｅｓｅｔをレンダリングするカスタマイズされた仕方をアタッチすることができる。随時接続データモデルそれ自体は、マジック変数＄ｒｏｏｔにルーツのある大きな仮想ＸＭＬ文書として与えられる。一実施形態において、データモデルには「現在」位置があり（例えば、アカウント又はアカウントのためのコンタクト）、そしてこれは、別のマジック変数＄ｃｕｒｒｅｎｔを通してテンプレートに使用することができる。ＵＲＬは、別のテンプレート又はテンプレート内の新たな「現在」データへの分岐（例えば、そのコンタクトへのアカウントへ進む）を表現することができる。テンプレートは、ＸＨＴＭＬで表現できるが、ＸＨＴＭＬモデルそれ自体への重要な拡張、以下に述べる「選択」、を含むことができる。これは、ＨＴＭＬが通常与えるものよりリッチで、よりインタラクティブなＵＩを可能にするが、これは、クライアントがコントローラでもあるときに可能となる。
【０４２１】
第２の人為的手段は、プログラマーがオフラインの振舞いをページ内のボタン及びＵＲＬにアタッチするようにさせることである。各ＵＲＬは、クライアントディレクトリーにも配置されるページフローファイル（ｃｏｎｔｒｏｌｌｅｒ．ｘｐｆ）においてＸＭＬに対するＥＣＭＡＳｃｒｉｐｔ（ａ．ｋ．ａ．ＪａｖａＳｃｒｉｐｔ）で書かれた「アクション」を参照することができる。このファイルは、１組のスクリプト「アクション」を含む。アクションは、データモデルへ完全にアクセスすることができ、従って、それらは、値を計算し、クライアントのデータを変更し、ひいては、延期同期、明確なトリガー同期及びディープセレクトをトリガーし、カスタムオペレーションを呼び出し、又はカレンシー(currency)をデータモデルの別の部分にセットするためのナビゲーションを生じさせることができる。コントローラにおける各「アクション」は、データモデル内の新たなカレンシー（又はアクションがデータモデル内の「カレンシー」を実際に変更しない場合にはＣＯＮＴＩＮＵＥ（継続））と、通常、特定のテンプレートとの両方を、そのカレンシーのコンテクストにおいて使用するように返送することができる。例えば、関連コンタクトを見るためにコンタクトをリストするページにおけるアクションは、そのカレンシーを関連コンタクトにセットしそしてコンタクトリストテンプレートを使用してそれらに何か似ているものを表示するための単なる１つのライナーでよい。
function showContactsForAccount($account) {
$context.account = $account;
return [$account.@@contacts.*, ”ContactsTemplate.tmpl”];
}
【０４２２】
モデルビューコントローラ
ＭＡＳクライアントアプリケーションは、ページフローファイル（ｃｏｎｔｒｏｌｌｅｒ．ｘｐｆ）で構成することができ、このファイルは、ＸＳｃｒｉｐｔアクション及びファンクションと、１組のページテンプレート（．ｔｍｐｌ）とを含むことができる。
クライアントは、アプリケーションデータのローカルキャッシュを維持することができる。このデータは、随時接続データモデルにより記述され、そしてＳＰａｔｈを使用して参照及び操作される。
【０４２３】
テンプレートは、埋め込まれたＳＰａｔｈ表現を含むＸＨＴＭＬページである。これらの表現は、キャッシュにおけるデータと、システム変数及びファンクションとを参照することができる。テンプレートは、ローカルデータしか参照できないので、マシンのネットワーク接続状態に関わりなくレンダリングすることができる（即ち、ユーザがアプリケーションをオフラインで実行できるようにする）。
【０４２４】
システム変数＄ｃｕｒｒｅｎｔは、データに対してカーソルを作用させることができ、＄ｃｕｒｒｅｎｔは、単一ノード又はノードリストのいずれかを参照する。＄ｃｕｒｒｅｎｔの値は、システムファンクションを呼び出すアクション及びアンカーにより変更することができ、これは、ナビゲーションとして知られている。システム変数＄ｃｏｎｔｅｘｔは、アクション及びテンプレートが一時的変数を交換するためのメカニズムを与えることができる。例えば、テンプレートは、入力フィールドを、キャッシュ内のコンテクスト変数又はノードエレメントのいずれかにバインディングしてもよい。
【０４２５】
又、テンプレートは、データ又はデータモードの指定部分にわたって繰り返すリピータを含んでもよい。これらリピータは、テンプレートが複雑なリスト及びテーブルを自動的に構築できるようにすると共に、ユーザが個々のレコードを選択しそしてそれらに対するアクションを呼び出すことができるようにする。
【０４２６】
ページフローメカニズムは、ユーザインターフェイス及び外部事象に応答してアクションを呼び出す。ユーザインターフェイス事象は、テンプレート内の＜ａ＞アンカーによりトリガーすることができ、外部事象は、データに対する外部同期更新によりトリガーすることができる。アプリケーションが最初にスタートすると、ページフロー内のｂｅｇｉｎ（）アクションをコールすることができ、これは、表示されるべき第１テンプレートを決定する。
【０４２７】
アクションは、テンプレート及び外部事象により呼び出されるＸＳｃｒｉｐｔファンクションである。アクションは、データを変更できると共に、テンプレートにアクセスできる＄ｃｕｒｒｅｎｔ及び＄ｃｏｎｔｅｘｔ変数も変更できる。システム変数＄ｐａｇｅは、現在見えるページ文書を参照し、これは、これらアクションがページコントロールプロパティをアクセスできるようにする。
【０４２８】
ナビゲーションは、＄ｐａｇｅ又は＄ｃｕｒｒｅｎｔシステム変数がアクションにより変更されるときに行うことができる。クライアントは、＜＄ｐａｇｅ  ｘ  ＄ｃｕｒｒｅｎｔ  ｘ  ＄ｃｏｎｔｅｘｔ＞変数の経歴スタックを維持することができる。これは、ユーザが経歴を前後にナビゲーションできると共に、テンプレートがコンテクスト（及び例えば、入力エレメントのバインディングされた値）を維持できるようにする。
【０４２９】
ＸＳｃｒｉｐｔ
ＳＰａｔｈ表現
クライアントプログラミングモデルは、ＸＭＬに対するＥＣＭＡＳｃｒｉｐｔ（Ｅ４Ｘ、ＸＳｃｒｉｐｔ）を使用することができ、これは、本質的にＸＭＬに対するナビゲーションサポートを伴うＪａｖａＳｃｒｉｐｔであり、ＳＰａｔｈは、ＸＰａｔｈ同様の言語で、アプリケーションがＸＭＬデータグラフに問合せできるようにする。これは、「ドット」演算子を使用して、グラフ内のエレメントを「トラバース」する。エレメントは、普通のＸＭＬエレメントでもデータノードでもよい。
【０４３０】
ＸＭＬオペレーション
システム変数は、‘＄’記号をプレフィックス（接頭辞）として設け、非タイプ入力とすることができる。他の変数の使用は、ＸＳｃｒｉｐｔ仕様により定義される。
次の宣言は、変数ｆｏｏ及びｂａｒを生成する。
foo = 100;
var bar = ”Alchemy”;
ｖａｒキーワードは、現在ファンクションのローカル範囲内に変数を配置し、ｖａｒを宣言しない変数は、グローバルな範囲に配置される。
【０４３１】
次の宣言は、ｆｏｏの値を、新たに生成されたＸＭＬオブジェクトにセットする。
var foo = <foo>Alchemy</foo>;
コンパウンドＸＭＬオブジェクトも次のように生成及び参照することができる。
var foo = <foo><bar>Alchemy</bar></foo>;
var bar = foo.bar
bar == ”Alchemy”
又、ＸＭＬオブジェクトは、‘＠’演算子を使用して参照される属性を宣言してもよく、例えば、
var foo = <foo id=”100”><bar>Alchemy</bar></foo>;
var id = foo.@id;
属性は暗示的に追加することができる（即ち、ｅｘｐａｎｄｏ）。
foo.@ping = ”200”;
【０４３２】
次の例は、＜ｂａｒ＞エレメントのテキストノードの値を変化させる。
var foo = <foo><bar>Alchemy</bar></foo>;
foo.bar = ”MAS”;
foo == <foo><bar>MAS</bar></foo>
次の例は、全＜ｂａｒ＞エレメントに置き換わる。
var foo = <foo><bar>Alchemy</bar></foo>;
for.bar = <foobar>Mobilized</foobar>
foo == <foo><foobar>Mobilized</foobar></foo>
【０４３３】
＋＝演算子を使用して、新たなＸＭＬエレメントを既存の親エレメントに追加又は挿入し、例えば、
var foo = <foo><bar>Alchemy</bar></foo>;
for.bar += <bar>Mobilized</bar>
foo == <foo><bar>Alchemy</bar><foobar>Mobilized</foobar></foo>
逆に、ｄｅｌｅｔｅ演算子を使用して、エレメントを除去する。
var foo = <foo><bar>Alchemy</bar></foo>;
delete foo.bar
foo == <foo></foo>
【０４３４】
データグラフオペレーション
随時接続データモデルは、データモデルにおけるルートノードを指すマニフェスト変数＄ｒｏｏｔをもつ仮想ＸＭＬ文書としてデベロッパへと表面化することができる。関連ノードへのナビゲーションは、＠＠演算子を使用しそしてｋｅｙｒｅｆ定義を経ての仮想ＸＭＬ文書内のモデルである。
【０４３５】
ノード操作
本書において、ノードという語は、データモデルノードを示すのに使用される。例えば、次のサンプルは、ＸＭＬエレメントを生成する。
var account =
<account>
<name>Acme</name>
<type>Direct</type>
</account>
【０４３６】
一実施形態において、ＸＭＬエレメントは、データキャッシュに挿入されるときに（ｃｒｅａｔｅ（）ファンクションを現在使用して）、ノードと考えられる。
新たなノードは、ｋｅｙｒｅｆにおいてｃｒｅａｔｅ（）ファンクションをコールすることにより生成することができる。例えば、次の例は、新たなａｃｃｏｕｎｔノードを生成する。
$root.@@accounts.create(<account><name>Brooklyn Industries</name></account>);
【０４３７】
ノードエレメント内に含まれたデータは、通常のＳＰａｔｈ表現を使用して参照及び変更することができる。次の例は、＄ｃｏｎｔａｃｔノード内のエレメントのテキスト値を変化させる。
account.name = ”Acme Ltd”;
又、新たなＸＭＬエレメントは、指定によりノード内に生成されてもよく、例えば、
account.address = <address><street>335 
Madison</street><zip>11211</zip></address>
【０４３８】
データオペレーション
ｎｏｄｅｔｙｐｅ間の関係は、随時接続データモデルにおけるｋｅｙｒｅｆ定義により定義することができる。例えば、次の宣言は、ａｃｃｏｕｎｔ  ｋｅｙｒｅｆがルートノードから発生され、そしてタイプａｃｃｏｕｎｔ（これは、スキーマにより定義される）のノードを含むことを指定する。
<keyref name=”accounts” sourceType=”mas:root” targetType=”app:account”>
クライアントプログラミングモデルにおいて、ｋｅｙｒｅｆは、＠＠演算子を使用してトラバースすることができる。例えば、
$root.@@accounts
【０４３９】
又、ｋｅｙｒｅｆ（）ファンクションを使用して、命名されたｋｅｙｒｅｆを参照することもできる。次の例は、前記例と同等である。
$root.keyref(”accounts”)
ｋｅｙｒｅｆは、指定の親ノードに対してｋｅｙｒｅｆを参照するものとして考えることができる。次の例は、＄ｒｏｏｔノードのａｃｃｏｕｎｔ  ｋｅｙｒｅｆの全てのａｃｃｏｕｎｔノードを参照する。
$root.@@accounts.*
$root.keyref(”accounts”).*
この表現は、各ノードがタイプａｃｃｏｕｎｔであるようなｎｏｄｅｓｅｔを返送し、例えば、
<account>
<name>Acme</name>
</account>
<account>
<name>Bancroft</name>
</account>
【０４４０】
［］演算子は、ｎｏｄｅｓｅｔ内の特定ノードをアクセスするのに使用できる。次の表現は、ａｃｃｏｕｎｔ  ｎｏｄｅｓｅｔにおける第１ノードを返送する。
$root.@@accounts.*[0]
ｌｅｎｇｔｈ（）ファンクションは、ｎｏｄｅｓｅｔにおけるノード数を返送するのに使用できる。
$root.@@accounts.*.length()
【０４４１】
これは、値１（one）を返送する次の表現とはかなり異なる。
$root.@@accounts.length()
即ち、＄ｒｏｏｔ＠＠ａｃｃｏｕｎｔは、単一エレメント＜ａｃｃｏｕｎｔｓ＞を返送する。
データグラフは、ＳＰａｔｈ表現をアーギュメントとして取り上げるｗｈｅｒｅ（）ファンクションを使用してフィルタリングすることができる。例えば、次のステートメントは、指定のラストネームをもつａｃｃｏｕｎｔ  ｋｅｙｒｅｆにおける全てのｃｏｎｔａｃｔノードに一致し、そしてノードリストを返送する。
$root.@@accounts.*.where(.name == ”Acme”);
これは、次の表現と同等であることに注意されたい。
$root.@@accounts.*.(thisXML.name == ”Acme”);
ここで、クローズがノードリストに対して評価でき、そしてその後にＳＰａｔｈ表現が続いてもよい。例えば、次の表現は、”Ａｃｍｅ”と命名された全てのアカウントに対するコンタクトのノードリストを返送する。
$root.@@accounts.*.where(.name == ”Acme”).@@contacts.*;
【０４４２】
ラベル
各ｎｏｄｅｔｙｐｅ宣言は、ノードを参照するＳＰａｔｈ表現であるラベルを定義してもよい。ｌａｂｅｌ（）ファンクションは、計算されたストリングを返送する。
<p>{$context.account.label()}</p>
又、ｋｅｙｒｅｆは、ｌａｂｅｌ（）ファンクションにより返送されるラベルを定義してもよい。
<p>{$root.@@accounts.label()}</p>
ノードのラベルは、ｌａｂｅｌ（）ファンクションにより得られる。例えば、
ノード又はｋｅｙｒｅｆがそれ自身により参照されるときに、強制で自動的にｌａｂｅｌ（）ファンクションを呼び出す。次の例は、上記例と同等である。
<p>{$context.account}</p>
<p>{$root.@@accounts}</p>
【０４４３】
Ｎａｍｅｓｐａｃｅ
クライアントプログラミングモデルにおいて、全てのオペレーションは、アプリケーション自身のデフォールトｎａｍｅｓｐａｃｅにおいて実施することができる。
このデフォールトｎａｍｅｓｐａｃｅは、ｓｅｔＤｅｆａｕｌｔＮａｍｅｓｐａｃｅファンクションを使用してセットされる。
function begin() {
$pageFlow.setDefaultNamespace(”http://example.com/”);
...
}
【０４４４】
これは、自動的にデフォールトアプリケーションｎａｍｅｓｐａｃｅを全てのＸＭＬオペレーションに追加する。例えば、次の表現は、
var account = <account><name>Acme</name></account>;
次のＸＭＬを発生する。
<account xmlns=”http://example.com/”>
<name>Acme</name>
</account>
システム変数及びファンクションの参照
このセクションは、ＸＭＬ規格に対してＥＣＭＡＳｃｒｉｐｔを拡張できるシステム変数及びファンクションを説明する。
【０４４５】
システム変数
全てのシステム変数は、‘＄’記号のプレフィックスをもつことができ、ユーザ変数も、規定により‘＄’記号を使用してもよい。
フレームワークは、テンプレート及びアクションの両方から参照できる次のシステム変数を定義する。
2007524933.tif 000036
【０４４６】
クライアントデータモデルは、アプリケーションに関する持続性データを表わすことができる。しかしながら、アプリケーションは、ページ遷移にわたって維持されるがＭＡＳに対して同期されない情報を一時的に記憶する必要があり、これは、例えば、「クリップボード」、「ウィザード(wizards)」及び他のマルチページプロセスを実施するのに使用できる。デベロッパは、＄ｃｏｎｔｅｘｔ及び＄ｓｅｓｓｉｏｎオブジェクト内の新たな変数を生成することができる。
【０４４７】
＄ｃｏｎｔｅｘｔ
＄ｃｏｎｔｅｘｔ変数は、発呼側アクションがテンプレートへの通過を望むことのある付加的なデータを表わす。これは、ＪＰＦ又はＨＴＴＰ  ＧＥＴ属性におけるフォワードビーンと同様である。コンテクスト変数は、ヒストリーの一部分として保存することができる。
【０４４８】
＄ｓｅｓｓｉｏｎ
＄ｓｅｓｓｉｏｎ変数は、アプリケーションの「セッション」状態を表わし、これは、＄ｃｏｎｔｅｘｔオブジェクトとは異なり、経歴の一部分として記憶されない。これは、通常、全アプリケーションに関連した（即ち、特定のページではない）情報を記憶するのに使用される。これらの変数は、アプリケーションのライフタイム中に残存し、そしてアプリケーション（及びブラウザ）が停止し及び開始するときに持続されそしてデハイドレート(dehydrate)される。
例えば、次のファンクションは、ユーザ定義のカウント状態変数をセットするのに使用されてもよい。
function onExternalSync() {
$session.count = $root.@@messages.*.length();
}
【０４４９】
次いで、各ページは、次のＸＨＴＭＬセグメントを含むことができ、これは、バインディング状態変数が変化するときに自動的に更新される。
<p>You have {$session.count} messages.</p>
<p>Click
<a href=”$pageFlow.navigate($root.@@messages.*， 
‘showMessages.tmpl’)”>here</a>
to see them</p>
【０４５０】
＄ｃｕｒｒｅｎｔ
＄ｃｕｒｒｅｎｔ変数は、ノード（又はノードリスト）を表わすもので、通常、ＵＩエレメントをデータにバインディングするために相対的ＳＰａｔｈ表現を伴うテンプレートにより使用される。
＄ｕｓｅｒ
＄ｕｓｅｒ変数は、ユーザに代わってコンジットオペレーションが呼び出されるところのユーザに関するデータを含む。オブジェクトは、次のフィールドを含む。
2007524933.tif 000037
【０４５１】
＄ｈｉｓｔｏｒｙ
＄ｈｉｓｔｏｒｙ変数は、コントローラにより変更することができる。
＄ｈｉｓｔｏｒｙ変数は、次のファンクションを実施することができる。
2007524933.tif 000038
【０４５２】
＄ｐａｇｅｆｌｏｗ
＄ｐａｇｅｆｌｏｗオブジェクトは、次のファンクションをサポートする。
2007524933.tif 000039
【０４５３】
＄ｇｌｏｂａｌＡｐｐ
＄ｇｌｏｂａｌＡｐｐ変数は、次のファンクションを実施する。
2007524933.tif 000040
【０４５４】
データモデルファンクション
次のファンクションは、ノードにおいて定義される。
2007524933.tif 000041
【０４５５】
次のファンクションは、ｋｅｙｒｅｆにおいて定義される。
2007524933.tif 000042
【０４５６】
メタデータファンクション
クライアントプログラミングモデルは、デベロッパが、アプリケーションを記述するメタデータの一部分にアクセスするのを許すことができる。
ｍｅｔａ（）
データモデルメタデータは、ノード又はｋｅｙｒｅｆのいずれかにおいてｍｅｔａ（）ファンクションをコールすることによりアクセスでき、例えば、
$root.meta();
$root.keyref(”accounts”).meta();
【０４５７】
次のファンクションは、ｍｅｔａオブジェクトにおいて定義される。
2007524933.tif 000043
【０４５８】
次のファンクションは、ｓｃｈｅｍａオブジェクトにおいて定義される。
2007524933.tif 000044
【０４５９】
例えば、次のテンプレートサンプルは、ネスト状のリピータを使用して、ｋｅｙｒｅｆハイアラーキーを表わすテーブルを構成する。
<netui:repeater id=”s1” source=”$root.keyref(*')” iterator=”$i”>
<p>{$i}</p>
<ul>
<netui:repeater id=”s2” 
source=”$s1.selected.meta().schema().keyref(*')”
iterator=”$j”>
<li>{j}</li>
</netui:repeater>
</ul>
</netui:repeater>
次の出力は、ＣＲＭ使用の場合に発生される。
−ｏｗｎｅｒ
−ｓｕｂＡｃｃｏｕｎｔｓ
−ｑｕｏｔｅＲｅｑｕｅｓｔ
−ｃｏｎｔａｃｔｓ
−ｎｏｔｅｓ
−ｅｖｅｎｔｓ
−ｔａｓｋｓ
【０４６０】
随時接続データモデル
前記セクションで述べたデータモデルは、デベロッパに対し、ルートノードを指すマニフェスト変数＄ｒｏｏｔを伴う仮想ＸＭＬ文書として表面化することができる。一実施形態において、移動ブラウザは、常に、コンテクストとして、データモデル内の現在位置を有する（例えば、特定のアカウント又は１組のコンタクト）。テンプレート及びスクリプトは、別のマニフェスト変数＄ｃｕｒｒｅｎｔを通してこの現在位置にアクセスすることができる。
【０４６１】
図９は、ＣＲＭアプリケーションに関するスキーマダイアグラム９００を示し、このアプリケーションは、６つのｎｏｄｅｔｙｐｅ：Ａｃｃｏｕｎｔ、Ｃｏｎｔａｃｔ、Ｎｏｔｅ、Ｅｖｅｎｔ、Ｔａｓｋ、及びＱｕｏｔｅＲｅｑｕｅｓｔを定義する。フレームワークは、全アプリケーションデータモデルを記述するＸＭＬスキーマを発生する。これは、アプリケーションスキーマ及びｋｅｙｒｅｆ定義を使用して発生することができる。
例えば、ＣＲＭアプリケーションは、次のスキーマを有する。
<?xml version=”1.0”?>
<xsd:schema targetNamespace=”http://example.com/”
elementFormDefault=”qualified” attributeFormDefault=”unqualified”
xmlns:xsd=”http://www.w3.org/2001/XMLSchema”
xmlns:mas=”run:bea.com”
xmlns=”http://example.com/”>
<xsd:element name=”graph”>
<xsd:complexType>
<xsd:sequence>
<xsd:element ref=”root” minOccurs=”1” maxOccurs=”1”>
<xsd:element ref=”account” maxOccurs=”unbounded”>
<xsd:element ref=”contact” maxOccurs=”unbounded”>
<xsd:element ref=”note” maxOccurs=”unbounded”>
<xsd:element ref=”event” maxOccurs=”unbounded”>
<xsd:element ref=”task” maxOccurs=”unbounded”>
<xsd:element ref=”quoteRequest” maxOccurs=”unbounded”>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
...
</xsd:schema>
【０４６２】
＜ｇｒａｐｈ＞エレメントは、アプリケーションデータモデルの最上位レベルエレメントを表わすことができ；これは、厳密に１つの＜ｒｏｏｔ＞ノード宣言と、各アプリケーションスキーマ（ａｃｃｏｕｎｔ、ｃｏｎｔａｃｔ、ｎｏｔｅ、ｅｖｅｎｔ、ｔａｓｋ、及びｑｕｏｔｅＲｅｑｕｅｓｔ）の各ノードに対する非制限インスタンスとを含むことができる。
＜ｒｏｏｔ＞エレメントは、＄ｒｏｏｔシステム変数により参照することができる。ルートノードは、特殊なシステムタイプであるから、ルートノード内に含まれるユーザデータオブジェクトは存在しない。
【０４６３】
＄ｒｏｏｔ．＠＠ａｃｃｏｕｎｔｓ．＊；
随時接続データモデルは、アプリケーションｎｏｄｅｔｙｐｅｓを定義することができ、これらは、アプリケーションスキーマ及びｋｅｙｒｅｆ定義から構成することができる。例えば、次の例は、ａｃｃｏｕｎｔ  ｎｏｄｅｔｙｐｅを詳述するもので、これは、スキーマエレメント（ｎａｍｅ及びｔｙｐｅ）と、ｋｅｙｒｅｆ定義（ｏｗｎｅｒ、ｓｕｂＡｃｃｏｕｎｔｓ、ｃｏｎｔａｃｔｓ、ｎｏｔｅｓ、ｅｖｅｎｔｓ、ｔａｓｋｓ、及びｑｕｏｔｅｓ）とを含む。
<xsd:element name=”account”>
<xsd:complexType>
<xsd:sequence>
<xsd:element name=”name” type=”xsd:string”/>
<xsd:element name=”type” type=”accountType”/>
</xsd:sequence>
<xsd:attribute name=”ownerId”/>
<xsd:attribute name=”parentAccountId”/>
</xsd:complexType>
</xsd:element>
【０４６４】
アカウントノード定義は、サーバーにおいて定義された対応するスキーマにより記述されるエレメント（及びおそらくは属性）を定義する。上述したように、ｋｅｙｒｅｆ定義は、アカウントノードから考えられるトラバースを決定する。例えば、
var user = account.@@owner;
var contacts = $root.@@accounts.*.@@contacts.*;
【０４６５】
同様に、次の例は、コンタクトｎｏｄｅｔｙｐｅを定義する。
<xsd:element name=”contact”>
<xsd:complexType>
<xsd:sequence>
<xsd:element name=”salutation” type=”contactSalutationEnum”/>
<xsd:element name=”first” type=”xsd:string”/>
<xsd:element name=”last” type=”addressType”/>
<xsd:element name=”email” type=”xsd:string”/>
</xsd:sequence>
<xsd:attribute name=”accountId”/>
<xsd:attribute name=”ownerId”/>
</xsd:complexType>
</xsd:element>
【０４６６】
次のＸＭＬは、ユーザがこのデータにいかにアクセスするかのクライアントモデルを示すが、これに似た実際のＸＭＬファイルが存在するときはない。
<graph>
<root accounts=”a1 a2”/>
<account id=”a1” owner=”bob” contacts=”c1 c2” notes=”n1” events=”e1” tasks=”t1”>
<name>Acme</name>
<type>Direct</type>
</account>
<account id=”a2” owner=”bob” contacts=”c3”>
<name>Bancroft</name>
<type>Web</type>
</account>
<contact id=”c1” owner=”bob” events=”e2” tasks=”t2”>
<salutation>Mr</salutation>
<first>Roger</first>
<last>Reed</last>
<email>roger@acme.com</email>
</contact>
<contact id=”c2” owner=”bob” notes=”n2”>
<salutation>Ms</salutation>
<first>Sarah</first>
<last>Smith</last>
<email>sarah@acme.com</email>
</contact>
<contact id=”c2” owner=”bob” notes=”n2”>
<salutation>Ms</salutation>
<first>Sarah</first>
<last>Smith</last>
<email>sarah@acme.com</email>
</contact>
<note id=”n1”>
<title>ROI information</title>
<body>Attached document details ROI for product</body>
</note>
<note id=”n2”>
<title>Customer requirements</title>
<body>Attached document presents customer's current and anticipated needs</body>
</note>
<event id=”e1” assigned=”fred”>
<title>Sales meeting</title>
</event>
<event id=”e2” assigned=”fred”>
<title>Product demonstration</title>
</event>
<task id=”t1” assigned=”fred”>
<title>Prepare RFP for sales call</title>
<status>Not started</status>
</task>
<task id=”t2” assigned=”fred”>
<title>Send white paper to customer</title>
<status>Completed</status>
</task>
</graph>
【０４６７】
概要
一実施形態において、クライアントがデータグラフを変更する仕方は２つある。第１に、テンプレートの入力エレメントをデータノードへ直接バインディングすることができ、このメカニズムは、ユーザが、既存のノードに属するＸＭＬエレメントを変更できるようにし、そしてコードを必要としない。第２に（そして通常は）、テンプレートが、データを変更するアクションを呼び出す。
【０４６８】
一実施形態において、データに対するこれらの変更は、サーバーへ同期状態で送信されない。むしろ、バックグランドプロセスが、サーバーへの及びサーバーからの更新を同期させる。実際に、全ページフローメカニズムが、ネットワーク（サーバー）接続とは独立して実行できるので、通常、データに対して多数のオフライン変化があり、これは、接続が確立されたときにサーバーと同期され且つ調和される。
【０４６９】
又、プログラミングモデルは、更新又は挿入されたレコードの同期を延期させるメカニズムも実施できる。例えば、購入注文を表わすノードを生成できるが、ユーザは、全てのラインアイテムが追加され、次いで、「サブミット」ボタンをクリックするまで、これを同期することを望まないことがある。
【０４７０】
サーバーは、他のユーザとの楽観的同時性競合のために、又は外部アプリケーションエラーのために、同期要求を拒絶することがある。各ノードは、フレームワークによりマネージされる同期状態を有する。これは、どのレコードが同期保留中であり、最新であり、又はサーバーにより拒絶されたか指示するフラグをアプリケーションが表示できるようにする。
【０４７１】
スキーマの検証
ｃｒｅａｔｅ（）及びｕｐｄａｔｅ（）ファンクションが呼び出されたときに、フレームワークは、次のことを実行する。
Ａ）オブジェクトをアプリケーションスキーマに対して検証すると共に、要求された全ての外部キーを検証する；
Ｂ）逆方向にトラバースできる関係（即ち、逆の関係）に対してキャッシュが一貫したものであることを保証する。
いずれかの条件を満足しない場合には、ランタイムエラーが発生される。
又、ｌｉｎｋ（）又はｕｎｌｉｎｋ（）ファンクション（又、＋＝／−＝演算子）が呼び出されたときにはｋｅｙ／ｋｅｙｒｅｆが強制される。
【０４７２】
ノードの生成
次のアクションは、ｃｒｅａｔｅ（）ファンクションを使用してノードを生成することができる。
var po = <purchaseOrder><date>03/12/05</date></purchaseOrder>;
po.lineItems += <lineItem><prodId>ABC</prodId><qty>100</qty></lineItem>
po.lineItems += <lineItem><prodId>XYZ</prodId><qty>200</qty></lineItem>
po = $account.@@purchaseOrders.create(po);
ノードｐｏは、ＸＭＬ指定表現（第１ライン）により構成することができる。第２及び第３表現は、ＸＭＬノードを変更する。しかしながら、ノードは、ｃｒｅａｔｅ（）ファンクションが呼び出されるまで検証される必要がない。
【０４７３】
ノードの更新
同様に、アプリケーションは、ノードのデータに直接アクセスすることにより既存のノードを変更することができる。例えば、次のコードは、特定の購入注文を検索し、次いで、状態を変更しそして新たなラインアイテムを追加する。
po = $account.@@purchaseOrders.where(.date == ”03/12/05”).*[0];
po.status = ”getQuote”;
po.lineItems += <lineItem><prodId>DEF</prodId><qty>300</qty></lineItem>
$po.update();
ここでも、ノードを検証するためにｕｐｄａｔｅ（）ファンクションがコールされる。
【０４７４】
ノードの生成
クライアントに新たなノードを生成するためにｃｒｅａｔｅ（）ファンクションを使用することができる。
var node = sourceNode.@@keyref.create(<node>[, callback, id]);
このファンクションは、挿入コンジットオペレーションをサポートするｋｅｙｒｅｆにおいてコールすることができる。このファンクションはノードオブジェクトを返送する。
2007524933.tif 000045
【０４７５】
例
例えば、次のＸＳｃｒｉｐｔは、指定の＄ａｃｃｏｕｎｔオブジェクトに対するｃｏｎｔａｃｔｓ  ｋｅｙｒｅｆ内の新たなｃｏｎｔａｃｔノードを構成する。
var contact =
<contact>
<salutation>Mr</salutation>
<first>Sydney</first>
<last>James</last>
<email>sydney@james.com</email>
</contact>;
node = account.@@contacts.create(contact);
【０４７６】
ノードは、通常、３つの段階で生成され、即ち第１に、アクションがコンテクスト変数を生成し、次いで、テンプレートを表示させる。
function init() {
$context.contact = <contact><salutation/><first/><last/><email/></contact>;
return [”editContact.tmpl”];
}
次いで、テンプレートが入力コントロールを個々のコンテクストエレメントにバインディングする。
<input type=”text” netui:bind=”$context.email”/>
次いで、テンプレートは、第２のアクションを呼び出し、フレームワークは、アクションをコールする前に、ＨＴＭＬ入力値をコンテクスト変数へ自動的に転送して戻す。次いで、アクションは、新たなノードを生成する。
function create() {
$context.contact = $account.@@contacts.create($context.contact);
return [”showContact.tmpl”];
}
【０４７７】
上記例において、アクションは、現在コンテクスト変数（＄ｃｏｎｔｅｘｔ．ｃｏｎｔａｃｔ）を、ｃｒｅａｔｅ（）ファンクションにより構成されたノードと置き換え、これは、次のテンプレート（ｓｈｏｗＣｏｎｔａｃｔ．ｔｍｐｌ）が、生成されたノードを参照できるようにする。ｃｒｅａｔｅ（）ファンクションがコールされる前に、＄ｃｏｎｔｅｘｔ．ｃｏｎｔａｃｔは、充分形成されたＸＭＬエレメントのみを含み、その後、検証されたノード（例えば、種々のノードファンクションをサポートする）を指す。
一実施形態において、ｉｎｓｅｒｔコンジットオペレーションを定義するｋｅｙｒｅｆは、ノードを生成するのを許し、そして無効のｎｏｄｅｓｅｔにおけるノードを生成するように試みると、ランタイムエラーを生じさせる。
【０４７８】
コールバック
ｃｒｅａｔｅ（）ファンクションは、コールバックファンクションを指定することもでき、これは、同期メカニズムが、ノードが生成された（即ち、関連コンジットオペレーションが新たな一次キーの返送に成功した）確認をサーバーから受信するときに呼び出される。例えば、
function foo(account, quote) {
node = account.@@requests.create(quote, bar);
}
function bar(request) {
$context.lastRequest = request;
}
コールバックファンクションには、生成されたノードをパラメータとして通すことができる。
【０４７９】
ノードの更新
ｕｐｄａｔｅ（）ファンクションを使用して、クライアントにおいて変更されるノードを同期させることができる。
node.update([callback, id]);
このファンクションは、更新コンジットオペレーションをサポートするｋｅｙｒｅｆにおいてコールされる。
2007524933.tif 000046
【０４８０】
ノードは、普通のＸＳｃｒｉｐｔ表現を使用して変更することができる。生成されたノードと同様に、同期は、バックグランドプロセスとして実行される。しかしながら、変更されたノードは、ｕｐｄａｔｅ（）ファンクションがコールされない限り、同期に対してマークされない。
ｕｐｄａｔｅ（）ファンクションは、関連ノードのｓｙｎｃＳｔａｔｅ属性をＭＯＤＩＦＩＥＤ（変更済）へセットすることができる。このメカニズムは、ノードが同期される前に、多数の編集を単一ノードに対して行えるようにする。
【０４８１】
例
以下のコードにおいて、最初の２つの表現は、＄ｃｏｎｔａｃｔノードのｓｙｎｃＳｔａｔｅをＤＳＹＮＣにセットすることができ、そして最後の表現は、ｓｙｎｃＳｔａｔｅをＭＯＤＩＦＩＥＤにセットすることができる。
contact.first = ”Bob”;
contact.address = <address><zip>10017</zip></address>;
$contact.update();
【０４８２】
コールバック
ｕｐｄａｔｅ（）ファンクションは、同期メカニズムが、ノードが更新された（即ち、関連コンジットオペレーションが成功した）という確認をサーバーから受信したときに呼び出されるコールバックファンクションを指定することもできる。例えば、
function foo(account, quote) {
quote.update(bar);
}
function bar(request) {
$context.lastRequest = request;
}
コールバックファンクションには、生成されたノードをパラメータとして通すことができる。
【０４８３】
競合のマネージメント
一実施形態において、クライアントが、外部システムにおいて既に更新されている（別のクライアント又は他の外因性変化プロセスのいずれかにより）「古い」ノードを変更しそして同期しようと試みるときに、ノードの競合が生じる。古いノードとは、サーバーにより保持されている現在シーケンスナンバーとは異なるシーケンスナンバーを有するノードである。
ノードが古いためにサーバーが更新を拒絶する場合には、同期状態属性を「ｃｏｎｆｌｉｃｔ」にセットした状態で最新のノードを返送する。
【０４８４】
更新オペレーションは、ノードがサーバーから返送されたときに呼び出される（競合の有無に関わらず）コールバックをセットすることができる。コールバックがセットされない場合には、クライアントフレームワークは、クライアントの古いノードを、サーバーにより返送された最新のノードと自動的に置き換える。
コールバックファンクションは、最初に、ｓｙｎｃＳｔａｔｅ（）システムファンクションを使用して競合状態についてテストしなければならない。次いで、アプリケーションに対してグローバルな変数（即ち、＄ｓｅｓｓｉｏｎ）をセットしなければならない。例えば、
function updateCallback(node) {
if (node.syncState() == CONFLICT) {
$session.message = ”<a href='showConflict()'>edit conflicts</a>”;
$session.conflict = node;
}
}
【０４８５】
競合が生じたことをユーザに通知するために、各テンプレートは、このグローバルな変数を参照することを含む状態エリアを含んでもよく、例えば、
<netui:html>{$session.message}</netui:html>
ここで、グローバル変数は、競合エディタページを表示するアクションへとユーザをナビゲーションできるＨＴＭＬアンカーを含む。
function showConflict() {
$context.node = $session.conflict;
return [”showConflict.tmpl”];
}
以下のｓｈｏｗＣｏｎｆｌｉｃｔテンプレートは、古いノード及び最新のノードの値を横に並べて表示する。
【０４８６】
ＳＰａｔｈ表現は、データノードに対して定義されたｃｏｎｆｌｉｃｔ（）ファンクションをコールし、これは、最新のノードを返送する。競合ノードは、外部キー値を含んでもよいが、＠＠演算子は、競合ノードからトラバースできないことに注意されたい。
<p>Contact record conflicted with server.</p>
<form netui:action=”$pageFlow.updateConflict()”>
<table><tbody>
<tr>
<td>First</td>
<td>{$context.node.conflict().first}</td>
<td><input type=”text” netui:bind=”$context.node.first”/></td>
</tr>
<tr>
<td>Last</td>
<td>{$context.node.conflict().last}</td>
td><input type=”text” netui:bind=”$context.node.last”/></td>
</tr>
<tr>
<td>Email</td>
<td>{$context.node.conflict().email}</td>
<td><input type=”text” netui:bind=”$context.node.email”/></td>
</tr>
<tr colspan=”3”>
<td><input type=”submit” value=”Create”/></td>
</tr>
</tbody></table>
</form>
<a href=”copyValues($context.node)”>Copy server's record.</a>
【０４８７】
サブミットボタンを押した場合に、このフォームは、以下のｕｐｄａｔｅＣｏｎｆｌｉｃｔ（）アクションを呼び出す。
function updateConflict() {
$context.node.update();
$status.message = null;
$status.conflict = null;
return [”BACK”];
}
【０４８８】
これは、現在ノードにおいてｕｐｄａｔｅ（）ファンクションをコールし、これは、同期メカニズムの再試みをトリガーする。ここで、コントローラは、ユーザが状態エリアをクリックする前に表示されていた以前のページに直ちに戻る。
又、上述したテンプレートは、クリック時に以下のｃｏｐｙＶａｌｕｅｓ（）アクションをコールするアンカーも定義する。
function copyValues(node) {
node.copy(node.conflict());
return [”CONTINUE”];
}
このアクションは、最新のノード値を古いノードへコピーし、そしてｓｈｏｗＣｏｎｆｌｉｃｔページに戻る。
【０４８９】
ノードのリンキング及びアンリンキング
一実施形態において、ｌｉｎｋ（）ファンクションは、１対多の関係を表わすｋｅｙｒｅｆにノード（又はノードのリスト）を追加するのに使用される。
node.@@keyref.link(nodeList);
ｎｏｄｅＬｉｓｔパラメータは、既に生成されたノードを参照しなければならないことに注意されたい。
ｕｎｌｉｎｋ（）ファンクションは、１対多の関係を表わすｋｅｙｒｅｆからノード（又はノードのリスト）を除去するのに使用される。
node.@@keyref.unlink(nodeList);
【０４９０】
例
以下のファンクションは、現在（コンタクト）ノードの関連ｋｅｙｒｅｆから全ての「ウェブ」アカウントを除去する。これは、次いで、ファンクションへ通される単一のｎｅｗＡｃｃｏｕｎｔノードをリンクする。
function foo(newAccount) {
contact = $current.@@accounts.*.where(.type == ”Web”);
current.@@accounts.unlink($contact);
contact.@@account.link(newAccount);
}
【０４９１】
エラーハンドリング
エラーオブジェクトは、サーバーにより発生され、そしてコンジットオペレーションが失敗したときにクライアントへ返送される。
エラーオブジェクトは、アプリケーションのコールバックファンクションへ返送され、このオブジェクトは、上記スキーマに対応するプロパティを有する。
エラーオブジェクトは、アプリケーションのコールバックファンクションへ返送され、このオブジェクトは、上記スキーマに対応するプロパティを有する。
function updateNode(node) {
node.update(updateCallback, <token/>)
}
function updateCallback(id, error) {
var msg = error.message;
var node = error.node();
var fields = error.field.*;
}
【０４９２】
又、エラーオブジェクトは、ｆｉｅｌｄ（）ファンクションを実施することもでき、これは、個々のエラーフラグにアクセスするのに使用され、例えば、
var msg = error.field(spath).message;
カスタムオブジェクト
テンプレートもアクションも、外部ソース（例えば、ウェブサービス）に直接アクセスすることができない。むしろ、外部プロセスは、ＭＡＳフレームワークにより同期されるデータオブジェクトとしてモデリングされる。
【０４９３】
大部分のコンジットオペレーションは、ノードエンティティのＣＲＵＤオペレーション（即ち、セレクト、生成、更新、等）へとマップすることができ、これらオペレーションは、クライアントプログラミングモデルファンクション（ナビゲーション、生成、更新、等）に直接対応する。しかしながら、通常、全てのウェブサービスオペレーションをフレームワークの標準的なオペレーションにマップすることはできない。例えば、ウェブサービスオペレーションは、多数のノードエレメントから形成されるか又はユーザにより入力される一時的な値を含む１組のパラメータを要求することがある。これらの場合に、アプリケーションは、ウェブサービスオペレーションの入力及び出力パラメータを含むカスタムｎｏｄｅｔｙｐｅを定義する。このメカニズムは、カスタムオペレーションとして知られている。ｃｒｅａｔｅ（）ファンクションは、普通のノードが生成される同じ仕方で新たなカスタムオブジェクトを生成するのに使用できる。
var customNode = $sourceNode.@@keyref-A.create(<node>[, callback]);
【０４９４】
カスタムオブジェクトは、通常、対応ｋｅｙｒｅｆのための挿入コンジットオペレーションを実施しない。むしろ、カスタムオブジェクトは、セレクトコンジットオペレーションをトリガーするその後のトラバースのためのコンテクストとして使用される。例えば、
var resultNodes = customNode.@@keyref-B.*;
ｋｅｙｒｅｆ宣言は、次の図で示される。
2007524933.tif 000047
【０４９５】
例
次の例は、次のプロートタイプを有するウェブサービスオペレーションを仮定する。
xsd:double submitQuote(xsd:string prodId, xsd:integer qty);
このオペレーションは、ｐｒｏｄＩｄ及びｑｔｙ入力パラメータを取り上げ、そしてｐｒｉｃｅ値を返送する。
これは、ｐｒｏｄＩｄ及びｑｔｙ入力パラメータと、ｐｒｉｃｅ応答フィールドとを含むｎｏｄｅｔｙｐｅに対するカスタムＸＭＬスキーマ定義を要求する。
【０４９６】
カスタムノードは、普通のノードと同じものが生成される。例えば、次のＸＭＬは、充分に形成されたｑｕｏｔｅＲｅｑｕｅｓｔエレメントを表わす。
<quoteRequest><prodId/><qty>0</qty></quoteRequest>
通常、デフォールト値を含む充分に形成されたＸＭＬオブジェクトを指定することによりコンテクスト変数を生成するアクションが呼び出される。次の例は、ｑｕｏｔｅＲｅｑｕｅｓｔエレメントを生成し、そしてコントローラがｉｎｐｕｔＲｅｑｕｅｓｔテンプレートをナビゲーションするようにさせる。
function initiateRequest() {
$context.request = <quoteRequest><prodId/><qty>0</qty></quoteRequest>;
return [”inputRequest.tmpl”];
}
【０４９７】
＜ｉｎｐｕｔ＞エレメントを個々のフィールド値にバインディングするテンプレート。
<table><tbody>
<tr>
<td>Product ID</td>
<td><input netui:bind=”$context.quoteRequest.prodId”/></td>
</tr>
<tr>
<td>Quantity</td>
<td><input netui:bind=”$context.quoteRequest.qty”/></td>
</tr>
<tr>
<td colspan=”2”>
<input type=”submit” value=”Submit” onClick=”submitQuoteRequest()”/>
</td>
</tr>
</tbody></table>
【０４９８】
テンプレートは、ｓｕｂｍｉｔＲｅｑｕｅｓｔアクションを呼び出して、充分に形成されたｑｕｏｔｅＲｅｑｕｅｓｔエレメントからノードを生成するためのサブミットボタンを有する。
function submitQuoteRequest() {
$current.@@quotes.create($context.request);
return [”showRequests.tmpl”];
}
ｃｒｅａｔｅ（）ファンクションは、直ちに戻って、同期のための新たに生成されたノードをマークする。通常のノードを生成するのと同様に、同期は、バックグランドプロセスとして行われる。それ故、このアクションは、ナビゲータが現在の１組のクオテ(quote)要求を表示するようにさせる。
【０４９９】
ｓｈｏｗＲｅｑｕｅｓｔテンプレートは、テンプレートの入力及び出力値の両方を参照する。新たに生成される要求に対するｒｅｓｐｏｎｓｅ．ｐｒｉｃｅエレメントは、最初に、値を返送しそして空にする。
<netui:repeater id=”$quotes” source=”$current.@@quotes.*” iterator=”$i”>
<tr>
<td>{$i.prodId}</td>
<td>{$i.qty}</td>
<td>{$i.response.price}</td>
</tr>
</netui:repeater>
2007524933.tif 000048
【０５００】
あるポイントにおいて、同期メカニズムは、生成されたノードをサーバーへ送信することができ、これは、関連カスタムオペレーションを呼び出す。成功の場合には、これは、＜ｒｅｓｐｏｎｓｅ＞エレメントを生成し、そしてノードをサーバーに再び同期させる。
<quoteRequest>
<prodId>Widget-Z</prodId>
<qty>1000</qty>
<response>
<price>2000.00</price>
</response>
</quoteRequest>
ｓｈｏｗＲｅｑｕｅｓｔｓテンプレートが依然見える場合には、クライアントフレームワークは、テンプレートを再レンダリングさせ、これは、対応するテーブルの行を更新する。
2007524933.tif 000049
【０５０１】
ノードの選択
ｓｅｌｅｃｔ（）ファンクションは、ｋｅｙｒｅｆにおいてコールすることができ、直ちに値を返送しない。このファンクションは、テンプレート内からはコールできない。
node.@@keyref.select(spath, [callback, id]);
又、ｓｅｌｅｃｔ（）ファンクションは、ルートノードにおいてコールされてもよい。
$root.select(spath, [callback, id]);
このメカニズムは、クライアントがＳＰａｔｈ表現により記述された仮想ＸＭＬ文書の一部分の同期を要求できるようにする。
【０５０２】
例えば、次の表現は、現在キャッシュにある全てのアカウントに対する全てのコンタクトを要求する。
$root.@@accounts.*.select(@@contacts.*);
次の表現は、ルートノードからアクセスできる全てのアカウントに対する全てのコンタクトを要求する。
$root.select(@@accounts.*.@@contacts.*);
【０５０３】
一実施形態において、ＳＰａｔｈ表現は、ローカルファンクションを参照せず、そしてこの表現は、非スカラー値へ分析できないローカル変数を参照しない。この表現は、サーバーへ通され、サーバーは、その表現をそれに対応するＸＰａｔｈ表現に変換する。
述語での選択
あるｋｅｙｒｅｆは、大きなもので、クライアントと完全に同期させることが不可能なことがある。これらの場合には、クライアントは、ｗｈｅｒｅ（）ファンクションを使用してｋｅｙｒｅｆをフィルタすることができる。
【０５０４】
例えば、次のセレクト表現は、ｗｈｅｒｅ（）述語に一致するアカウントノードだけを同期させる。
$root.select(@@acounts.*.where(.type == ”Web”));
次の表現は、上述した一致するアカウントに対する全てのコンタクトを選択する。
$root.select(@@acounts.*.where(.type == ”Web”)).contacts.*;
次の表現は、一致するｅメールアドレスを有する全てのコンタクトを選択する（全てのアカウントから）。
$root.select(@@accounts.*.@@contact.*.where(.email == ”bob@acme.com”));
【０５０５】
又、述語セレクトメカニズムを使用して、ユーザが、同期されねばならないノードを予め選択するのを許すこともできる。例えば、チェックされたブールの属性をアカウントｎｏｄｅｔｙｐｅに追加し、そしてこれをテンプレート内のチェックボックスエレメントにバインディングすることもできる。
<netui:repeater id=”s1” source=”$root.@@accounts.*” iterator=”i”>
<tr>
<td><input type=”checkbox” netui:bind=”i.@@checked”></a></td>
<td>{i}</td>
</tr>
</netui:repeater>
次の表現（テンプレートにより呼び出されたアクション内に含まれた）は、同期メカニズムが、全てのチェックされたアカウントに対して全てのコンタクトを検索するようにさせる。
$root.select(@@acounts.*.where(.@@checked == true).@@contacts.*);
【０５０６】
コールバック
コールバックメカニズムは、ＳＰａｔｈに対する全同期が完了したときに、発呼者が、コールされるべきファンクションを指定できるようにする。例えば、
$root.select(@@accounts.*.@@contacts.*, $id, callbackFn);
この例は、同期スクリプトをサーバーに送信して全てのアカウントに対して全てのコンタクトを検索すると共に、同期が完了したときに、ファンクションｃａｌｌｂａｃｋＦｎを、クライアントフレームワークにより呼び出されるべきコールバックとして登録する。＄ｉｄ変数は、特定のセレクト呼び出しを識別するためにファンクションへ通される。
【０５０７】
例
例えば、このメカニズムの１つのアプリケーションは、特定のアプリケーションに関する全てのテンプレートが各ページの底部に「状態バー」エレメントを含み、これが一時的データ値（例えば、＄ｓｅｓｓｉｏｎ．ｍｅｓｓａｇｅ）にバインディングするようにしてもよい。
<p>Status: <span>{$session.message}</span></p>
コールバックでセレクトを開始するアクションが１つのテンプレートからコールされてもよい。
q1 = ”Q1”;
function beginSearch(email) {
$root.select(@@accounts.*.@@contact.*.where(.email == email), q1, onUpdate);
}
【０５０８】
この場合に、ｂｅｇｉｎＳｅａｒｃｈ（）ファンクションは、コンタクトのｅメールアドレスを表わすパラメータを取り上げ、そして一致するｅメールアドレスエレメントを有する全てのコンタクト（全てのアカウントに対する）を選択する。
ユーザ定義のコールバックファンクションｏｎＵｐｄａｔｅ（）は、同期要求が完了したときにコールされる。
function onUpdate(id) {
if (id == q1) {
$session.message =  + ” Received results.”;
}
...
}
【０５０９】
このファンクションは、ｉｄ入力変数を、前記ｓｅｌｅｃｔ（）ファンクションへ通された要求定数と一致させ、次いで、＄ｓｅｓｓｉｏｎ．ｍｅｓｓａｇｅ変数を変化させ、これは、この変数へのテンプレートバインディングをリフレッシュさせる。
同期
通常、同期は、バックグラウンドで実行される。一実施形態において、同期に作用するものについてユーザが有する唯一のコントロールは、セレクトオペレーションが完了したときにコールバックを登録することである。
【０５１０】
しかしながら、ノードを生成又は変更するときには、１組のオペレーションが論理的に完全なユニットとして実行されることを保証することが時々必要となる。これは、全トランザクションセマンティックを要求するよりも低いバーであることに注意されたい。
例えば、以下のファンクションは、コンタクトのファーストネーム及びラストネームを変更すると共に、アカウントノードを参照する外部キーも変更する。
function foo(contact, account) {
contact.first = $context.first;
contact.last = $context.last;
contact.@@accountId = account;
}
【０５１１】
一実施形態において、ノードが生成又は変更されるときに、それらの同期状態をＤＳＹＮＣ（ｄｅｆｅｒｒｅｄ  ｓｙｎｃ）にセットする。しかしながら、それらは、コントローラにより呼び出されたオリジナルアクションがエラーなしに復帰するまで同期についてスケジュールされない。この点において、ＤＳＹＮＣとマークされた全てのノードは、ＭＯＤＩＦＩＥＤへ促進される。
アクションが、その後のアクションを呼び出すことがあり、この場合には、最も外側のアクションがこの暗示的トランザクションの範囲を形成する。
【０５１２】
クライアントフレームワークは、単一スレッド（アプリケーション当たり）アクションモデルを実施する。これは、到来する同期メッセージにより呼び出されたアクションと、フレームワークによる同期メッセージの処理との両方を含む。それ故、到来する同期更新がアクション内で操作されるデータに「大打撃を与える(clobber)」ことはあり得ない。
ある場合には、キャッシュは、一連のテンプレート（例えば、「ウイザード(wizard)」を呼び出すページフローによって更新される。これらの場合には、前ページフローが首尾良く完了するまで同期を延期するために、アプリケーションは、関連データを生成するか又はコンテクスト変数へコピーしなければならない。次いで、最終的なページフローアクションがキャッシュを更新する。
【０５１３】
ユーザ遅延同期
時々、ユーザは、レコードをサブミットする容易ができるまで（例えば、サブミットファンクションをプレスすることにより）、見掛け上の同期を延期することを希望する。
例えば、次のテンプレートは、購入注文のリスト（アカウントに対する）及び各アイテムのチェックボックスを表示する。チェックボックスは、アイテムの状態を決定する属性へバインディングされる。
<netui:repeater id=”s1” source=”$account.@@purchaseOrders.*” iterator=”i”>
<tr>
<td><input type=”checkbox” netui:bind=”i.@@complete”></a></td>
<td>{i}</td>
</tr>
</netui:repeater>
<input type=”submit” onClick=”$pageFlow.submit()”/>
【０５１４】
サブミットボタンは、ｓｕｂｍｉｔ（）アクションをコールし、これは、完全なものとしてセットされた全ての購入注文に対してｕｐｄａｔｅ（）をコールする。
funciton submit() {
for (i = 0; i < $accounts.@@purchaseOrders.*.length(); i++) {
var po = $account.@@purchaseOrders.*[i];
if (po.syncState() == ”DSYNC” && po.@@complete == true) {
$po.update();
}
}
}
【０５１５】
この例は、外部システムが完全な属性の意味を解釈し、即ちレコードの処理を（持続性をマネージしながら）、ユーザにより適当な値がセットされるまで、延期することを要求する。
テンプレート
テンプレートは、アプリケーションのユーザインターフェイスを作り上げる充分に形成された（そして検証された）ＸＨＴＭＬページである。テンプレートは、通常、キャッシュ内のデータを参照し、又、アクションを呼び出すこともできる。一実施形態において、テンプレートは、データグラフを直接変更できるスクリプト表現を含まない。
【０５１６】
テンプレートは、カーソルとして働く＄ｃｕｒｒｅｎｔシステム変数を参照することができ、＄ｃｕｒｒｅｎｔは、単一ノード又はノードリストのいずれかを参照する。一実施形態において、＄ｃｕｒｒｅｎｔの値は、システムファンクションをコールするアクション及びアンカーでしか変更できず、これは、ナビゲーションとして知られている。
【０５１７】
又、テンプレートは、データ又はデータモデルの特定部分にわたって繰り返すリピータを含んでもよい。リピータは、テンプレートが複雑なリスト及びテーブルを自動的に構築できるようにすると共に、ユーザが個々のレコードを選択して、それに対するアクション又はナビゲーションを呼び出せるようにする。
【０５１８】
システム変数＄ｃｏｎｔｅｘｔは、アクション及びテンプレートが一時的変数を交換するためのメカニズムを与えることができる。例えば、テンプレートは、入力フィールドをコンテクスト変数又はデータノードエレメントのいずれかにバインディングすることができる。テンプレートがアクションを呼び出すときには、ページ入力の値が自動的にそれらのバインディングされた変数へコピーされる。
【０５１９】
テンプレートは、ユーザがクリックしたときにトリガーされるＨＴＭＬ＜ａ＞アンカーを定義することにより事象を発生することができる。一実施形態において、アンカーは、３つの異なる目的を有する。
【０５２０】
１）ナビゲーション
アンカーは、ＳＰａｔｈ表現（例えば、＄ｃｕｒｒｅｎｔ．＠＠ｏｒｄｅｒｓ．＊）を指定することができ、これは、コントローラが＄ｃｕｒｒｅｎｔ変数を変更して異なるノード又はｎｏｄｅｓｅｔを指すようにし、これは、ナビゲーションとして知られている。システムは、特定のテンプレートをあるｎｏｄｅｔｙｐｅ及びｋｅｙｒｅｆに関連付けできるメタデータを与えて、ブラウザが自動的に適当なテンプレートを選択できるようにする。
【０５２１】
２）システムファンクションの呼び出し
フレームワークは、アプリケーションの振舞いを変更する種々のシステムファンクションを実施することができる。例えば、ｎａｖｉｇａｔｅ（）ファンクションは、特定のテンプレートへナビゲーションし、そして＄ｃｕｒｒｅｎｔ変数をセットし、ｓｅｌｅｃｔ（）ファンクション（リピータ内でコールされる）は、リスト又はテーブルから特定ノードを選択するのに使用される。
【０５２２】
３）アクションの呼び出し
アクションは、手前のテンプレートにバインディングされたコンテクスト変数を処理しそして計算を実行し又はデータを変更することができる。次いで、アクションは、現在ページへ直接戻ることができ、この場合に、データバウンドフォームコントロールが更新され、そして表示がリフレッシュされる。又、アクションは、コントローラが＄ｃｕｒｒｅｎｔ及び＄ｐａｇｅ変数を変更するようにさせて、ナビゲーションを生じさせることもできる。
【０５２３】
同期は、バックグランドにおいて行うことができる。クライアントにより生成されそして変更されたノードは、種々の同期状態を通過し、これらは、システムファンクションを経てテンプレートへアクセスされ、そしてユーザに表示することもできる。又、サーバーからの同期更新は、関連ノードにバインディングするテンプレートを即座に更新させる。
【０５２４】
表現の評価
一実施形態において、テンプレートは、カーリーブレース(curly brace)内のＳＰａｔｈ表現を引用することにより、キャッシュからのデータをページへ直接合体することができる。評価された表現の結果は、普通のＸＨＴＭＬとして処理される。
例えば、次の表現は、現在ノードのラベルを表示する。
<p>{$current.label()}</p>
【０５２５】
一実施形態において、カーリーブレース内に含まれた表現は、ページがリフレッシュされるたびに評価される。ページは、コントロールがアクションから戻されるときにリフレッシュされる。それ故、カーリーブレース内に含まれた表現は、ＸＨＴＭＬタグのための動的な値を定義するのに使用できる。
例えば、次の表現は、変数＄ｃｏｎｔｅｘｔ．ａｄｄｒｅｓｓのコンテンツを評価し、そしてその結果をアンカータグのｈｒｅｆ属性に入れる。
<a href=”{$context.address}”>Click</a>
【０５２６】
あるアクションは、このコンテクスト変数の値を変化させる。
$context.address = ”mailto:alchemy@bea.com”;
これは、コントロールがページへ戻されたときに、次のＸＨＴＭＬ表現を発生させる。
<a href=”mailto:alchemy@bea.com”>Click</a>
【０５２７】
システム変数
このセクションは、一実施形態において経歴スタックに維持される３つのシステム変数（＄ｃｕｒｒｅｎｔ、＄ｃｏｎｔｅｘｔ、及び＄ｐａｇｅ）を詳述する。
＄ｃｕｒｒｅｎｔ
＄ｃｕｒｒｅｎｔ変数は、ノードリスト（１つ以上のノード）を参照する。これは、ノード又はｎｏｄｅｓｅｔ、或いはノードリストを生じる評価されたＳＰａｔｈ表現に対する明確な参照でよい。
【０５２８】
テンプレートは、単一ノード又はノードリストをハンドリングするように設計される。＄ｃｕｒｒｅｎｔ［０］は、単一ノードを指すように保証される。又、＄ｃｕｒｒｅｎｔ．ｌｅｎｇｔｈ（）表現は、ノードリスト内のノードの数を検出するのに使用できる。
例えば、ＣＲＭアプリケーションは、単一アカウントノードを指すことを＄ｃｕｒｒｅｎｔに期待するａｃｃｏｕｎｔＤｅｔａｉｌ．ｔｍｐｌページを実施してもよい。
<html>
<head>
<meta current=”node”/>
<title>Account Detail</title>
</head>
<body>
<p>Account: {$current}</p>
<a href=”$pageFlow.navigate($current.@@contacts.*, contacts.tmpl')”>Contacts</a>
...
</body>
</html>
【０５２９】
逆に、ｃｏｎｔａｃｔｓ．ｔｍｐｌページは、全てのアカウントに対してコンタクトの全組を含むことを＄ｃｕｒｒｅｎｔに期待する。
<html>
<head>
<meta current=”nodelist”/>
<title>Contacts</title>
</head>
<body>
<table><tbody><tr>
<netui:repeater id=”$contacts” source=”$current” iterator=”$i” focused=”true”>
<td>first</td><td>{$i.first}</td>
<td>last</td><td>{$i.last}</td>
<td>email</td><td>{$i.email}</td>
<td><a href=”$s.previous()”>Previous</a></td><td><a href=”$s.next()”>Next</a></td>
</netui:repeater>
</tr></tbody></table>
</body>
</html>
ここで、焦点の合わされたリピータは、ユーザが、コンタクトノードの集合を通して循環するのを許す。
【０５３０】
＄ｃｏｎｔｅｘｔ
コンテクスト変数は、多ページプロセスを整合するためにテンプレート及びアクションに対する「スクラッチパッド」を与え、それらは、概念的には、セッション変数と同様である。
コンテクスト変数は、アクション内で実行される指定オペレーションによって生成される。
$context.foo = 100;
$context.foo.bar = <bar>FooBar</bar>
テンプレートは、表現言語シンタックスを使用してコンテクスト変数を参照する。
<p>{$context.foo}</p>
<p>{$context.foo.bar}</p>
【０５３１】
アクションは、全ての現在コンテクスト変数を除去するために＄ｃｏｎｔｅｘｔオブジェクトにおけるｒｅｓｅｔ（）ファンクションをコールすることができる。
$context.reset();
＄ｐａｇｅ
＄ｐａｇｅ変数は、現在レンダリングされたテンプレートを含む。これは、現在レンダリングされたページ内のＨＴＭＬコントロールの状態をアクセスするためにアクションにより使用される。
【０５３２】
ＸＨＴＭＬタグ表現
このセクションは、クライアントフレームワークによりサポートされるＸＨＴＭＬへの拡張を詳述する。
一実施形態において、テンプレートは、充分に形成され及び検証されたＸＨＴＭＬを含まねばならない。このセクションに述べるＸＨＴＭＬ拡張は、ｎｅｔｕｉ  ｎａｍｅｓｐａｃｅ内に定義され、全ての例は、次のｎａｍｅｓｐａｃｅ宣言を必要とする。
<html xmlns=”http://www.w3.org/1999/xhtml”
xmlns:netui=”http://www.bea.com/netui”>
【０５３３】
アンカータグ
＜ａ＞（アンカー）タグは、ユーザがクリックして事象をトリガーさせることのできるハイパーリンクを生成する。アンカーは、ナビゲーションを行い、システムファンクション（アイテムの選択を含む）を呼び出し、そしてアクションを呼び出すのに使用される。
アンカーは、ＳＰａｔｈ表現（例えば、＄ｃｕｒｒｅｎｔ．＠＠ｏｒｄｅｒｓ．＊）を指定することができ、これは、コントローラが、＄ｃｕｒｒｅｎｔ変数の値を変更して、異なるノード又はｎｏｄｅｓｅｔを指すようにさせ、これは、ナビゲーションとして知られている。
【０５３４】
アンカーは、種々のシステムファンクションの１つを呼び出すことができる。例えば、ｎａｖｉｇａｔｅ（）ファンクションは、特定のテンプレートへナビゲーションし、そして＄ｃｕｒｒｅｎｔ変数をセットし、リピータ内でコールされるｓｅｌｅｃｔ（）ファンクションは、リスト又はテーブルから特定のノードを選択するのに使用される。
【０５３５】
アンカーは、テンプレートにボンディングされたコンテクスト変数を処理して計算を実行するか又はデータを変更し得るアクションを呼び出してもよい。このアクションは、次いで、現在ページへ直接戻ってもよく、この場合には、コントロールからバインディングされるデータが更新され、そして表示がシームレスにリフレッシュされる。又、アクションは、コントローラが＄ｃｕｒｒｅｎｔ及び＄ｐａｇｅ変数を変更させて、ナビゲーションを生じさせてもよい。
<a href=”url”/>
【０５３６】
アンカーは、次の属性を使用することができる。
2007524933.tif 000050
【０５３７】
ｕｒｌ属性は、次のフォームの１つをもつことができる。
2007524933.tif 000051
【０５３８】
アンカーは、通常、異なるページへナビゲーションするか、又はデータを選択するのに使用される。
ナビゲーション
ナビゲーションは、種々の手段によって達成することができ、以下の例では、ブラウザがルートノードへナビゲーションさせる。
<a href=”$root”>Example 1</a>
<a href=”$pageFlow.navigate($root, bar.tmpl')”>Example 2</a>
<a href=”$pageFlow.foo($root, bar.tmpl')”>Example 3</a>
function foo($s, $p) {
return [$s, $p];
}
<a href=”$globalApp.history.home()”>Example 4</a>
【０５３９】
例１は、ＳＰａｔｈ表現を宣言し、これは、コントローラにより直接評価され、そして＄ｃｕｒｒｅｎｔの値をセットするのに使用される。
例２は、システムｎａｖｉｇａｔｅ（）ファンクションをコールし、これは、＄ｃｕｒｒｅｎｔを、評価されたＳＰａｔｈ表現にセットし、そして任意の第２パラメータを使用して、テンプレートをセットする。
例３は、ユーザアクション（コントローラファイルで定義された）を呼び出し、これは、通過されたパラメータを使用して、フォワードオブジェクト（アレー）を生成し、これは、例２と同じ作用を有する。
【０５４０】
例４は、ｈｏｍｅ（）システムファンクションを呼び出し、これは、＄ｈｉｓｔｏｒｙオブジェクトにおいてコールされる。
【０５４１】
選択
次の例は、１組の注文をリストし、そしてそれらの１つをクリックすることにより「選択された注文」として「選択」することを示す。
<netui:repeater id=”foo” source=”$current.@@orders.*” iterator=”$thisorder”>
<a href=”$foo.select($thisorder)”>{$thisorder.label()}</a>
</netui:repeater>
【０５４２】
次の例は、一度に１つの注文を表示し、そしてそれらを通して前後にユーザを移動させる。
<netui:repeater id=”foo” source=”$current.@@orders.*” iterator=”$thisorder” focused=”true”>
<tr>
<td>OrderID: </td><td>{$thisorder.id}</td>
<td>OrderDate: </td><td>{$thisorder.date}</td>
<td>OrderAmount: </td><td>{$thisorder.amount}</td>
</tr>
<tr>
<td><a href=”$foo.previous()”>Previous</a></td>
<td><a href=”$foo.next()”>Next</a></td>
</tr>
</netui:repeater>
【０５４３】
フォーム
一実施形態において、データを表示するために、必要とされるものは、カーリーブレースにエンクローズされたＳＰａｔｈだけである。
例えば、＄ｃｕｒｒｅｎｔがコンタクトを参照する場合には、次のものがコンタクトのネーム及びアドレスを示す。
<tr>
<td>First:</td><td>{$current.name.first}</td>
<td>Last:</td><td>{$current.name.last}</td>
</tr>
しかし、これは、リードオンリモデルである。
【０５４４】
一実施形態において、変数へ書き込みするために、ＨＴＭＬフォームエレメントは、ｎｅｔｕｉ：ｂｉｎｄ属性を追加してユーザ入力をデータモデルへマップするようにしてサポートされる。
2007524933.tif 000052
【０５４５】
次のＨＴＭＬフォームエレメントは、読み取り／書き込み変数をバインディングするためにサポートされる。
2007524933.tif 000053
【０５４６】
これらのタグの各々は、ｎｅｔｕｉ：ｂｉｎｄ属性をサポートし、これは、ＳＰａｔｈ表現を使用して読み取り／書き込み変数を参照する。
<input type=”intputType” netui:bind=”SPath”/>
ＳＰａｔｈ表現は、通常、＄ｃｏｎｔｅｘｔ変数を参照する。例えば、
<input type=”text” netui:bind=”$context.address.name”/>
この変数は、ページがレンダリングされるときに入力フィールドの値をセットするのに使用される。
【０５４７】
バインディングされた値は、サブミットアクションが呼び出されたとき（以下の＜ｉｎｐｕｔ  ｔｙｐｅ＝”ｓｕｂｍｉｔ”タグを経て行うことを含む）、又はナビゲーションが行われるとき（上述したアンカーを参照）、変数へ書き戻される。
入力タグ
＜ｉｎｐｕｔ＞タグは、ｔｙｐｅ属性の値に基づいて種々の簡単なコントロールを実施する汎用の入力タグである。
<input type=”inputType” netui:bind=”spath-expr”/>
フレームワークは、ｎｅｔｕｉ：ｂｉｎｄ属性を、ＸＨＴＭＬでサポートされる標準的な属性に追加する。
【０５４８】
＜ｉｎｐｕｔ＞タグの次のタイプがサポートされる。
2007524933.tif 000054
【０５４９】
以下の例は、＜ｉｎｐｕｔ＞タグの種々のフォームを示す。
<input type=”text” netui:bind=”$context.contact.email”/>
<input type=”radio” netui:bind=”$context.contact.selected” value=”yes”/>
<input type=”radio” netui:bind=”$context.contact.selected” value=”no”/>
<input type=”checkbox” value=”chinese” netui:bind=”$context.contact.langsSpoken”/>
<input type=”password” netui:bind=”$context.login.password”/>
<input type=”hidden” netui:bind=”$context.contact.MailingCountry” value=”USA”/>
<input type=”button” value=”press this button”/>
【０５５０】
無線
無線タグは、単一の値だけを選択してもよいようにグループ分けすることができ、同じ論理的グループ内の各無線タグを同じＳＰａｔｈ表現にバインディングしなければならない。
<p>Selected: 
<input type=”radio” netui:bind=”$context.contact.selected” value=”yes”>Yes</input>
<input type=”radio” netui:bind=”$context.contact.selected” value=”no”>No</input>
</p>
【０５５１】
現在選択されたコントロールは、ｖａｌｕｅ属性により指定された値をＳＰａｔｈ表現にバインディングする。ｖａｌｕｅ属性が指定されない場合には、ブールの値ｔｒｕｅがセットされる。
サブミット
サブミットのタイプは、ｏｎＣｌｉｃｋ属性を定義し、これは、アンカー（上述した）と同様に振舞う。
<input type=”submit” onClick=”$pageFlow.submitContact()”/>
これは、クリックされると、バインディングされた全ての変数（ページ上の）を、現在入力タグ値と共に書き込ませる。
【０５５２】
ＴｅｘｔＡｒｅａタグ
＜ｔｅｘｔａｒｅａ＞タグは、ユーザがテキストの多数のラインを入力及び編集できるようにし、これは、スクロールバーの表示を伴ってもよい。
<textarea netui:bind=”spath-expr”/>
フレームワークは、ＸＨＴＭＬでサポートされた標準的属性にｎｅｔｕｉ：ｂｉｎｄ属性を追加する。
例えば、次のＸＨＴＭＬエレメントは、＜ｔｅｘｔａｒｅａ＞エレメントを生成し、これは、＄ｃｏｎｔｅｘｔ変数により参照されるノートノードのｃｏｍｍｅｎｔｓ子エレメントにバインディングされる。
<textarea netui:bind=”$current.note.comments”/>
【０５５３】
セレクトタグ
＜ｓｅｌｅｃｔ＞タグは、ユーザがドロップダウンコントロールから多数のアプリケーション定義値の１つを選択できるようにする。
<select netui:bind=”spath-expr”/>
フレームワークは、ＨＴＭＬでサポートされる標準的属性にｎｅｔｕｉ：ｂｉｎｄ属性を追加する。
ｃｏｎｔａｃｔＴｙｐｅスキーマ定義は、ｓａｌｕｔａｔｉｏｎエレメントを含み、これは、ｃｏｎｔａｃｔＳａｌｕｔａｔｉｏｎＥｎｕｍタイプを有するように定義される。
<xsd:complexType name=”contactType”>
<xsd:sequence>
<xsd:element name=”salutation” type=”contactSalutationEnum”/>
<xsd:element name=”first” type=”xsd:string”/>
<xsd:element name=”last” type=”xsd:string”/>
<xsd:element name=”email” type=”xsd:string”/>
</xsd:sequence>
</xsd:complexType>
<xsd:simpleType name=”contactSalutationEnum”>
<xsd:restriction base=”xsd:string”>
<xsd:enumeration value=”Mr”/>
<xsd:enumeration value=”Mrs”/>
<xsd:enumeration value=”Ms”/>
<xsd:enumeration value=”Dr”/>
</xsd:restriction>
</xsd:simpleType>
【０５５４】
次のＸＨＴＭＬは、＜ｓｅｌｅｃｔ＞エレメントを生成するのに使用される。
<select netui:bind=”$context.contact.salutation”>
任意の値を明確に宣言することができる。
<select netui:bind=”$context.contact.salutation”>
<option value=”Mr”>Mr</option>
<option value=”Ms”>Ms</option>
<option value=”Mrs”>Mrs</option>
<option value=”Dr”>Dr</option>
</select>
【０５５５】
或いは又、リピータを使用して任意の値を生成することもできる。
<select netui:bind=”$context.contact.salutation” iterator=”i”>
<netui:repeater source=”$globalApp.schema(contactSalutationEnum')”>
<option value=”{$i.@value}”>{$i.@value}</option>
</netui:repeater>
</select>
ｎｅｔｕｉ：ｂｉｎｄ表現に一致する値は、デフォールトオプションとして選択されることに注意されたい。バインディングされた値がナルである場合には、最初のオプションが選択される。
【０５５６】
例
次の例は、ｅｍａｉｌコンテクスト変数をテキスト入力フィールドにバインディングする。それに対応するアクションは、フォームのアクション属性を使用して呼び出すこともできるし、又はネスト状のアンカータグで呼び出すこともできる。
<form netui:action=”$pageFlow.inputEmailAddress()”>
<input type=”text” netui:bind=”$context.email”/>
<input type=”submit” value=”Submit”/>
</form>
典型的に、コンテクスト変数は、最初、テンプレートを表示させる先行アクションにおいてインスタンス生成される。次のアンカーは、ａｄｄＣｏｎｔａｃｔ（）アクションを呼び出す。
<a href=”$pageFlow.addContact()”/>Create New Contact</a>
【０５５７】
このアクションは、次いで、３つのコンテクスト変数を生成し、次いで、ａｄｄＣｏｎｔａｃｔテンプレートを表示するようにコントローラに指令する。このアクションは、最初、既存の全てのコンテクスト変数をリセットし、次いで、指定演算子を使用して新たな変数を生成する。
function addContact() {
$context.reset();
$context.account = $current;
$context.salutation = ””;
$context.first = ””;
$context.last = ””;
$context.email = ””;
return [”addContact.tmpl”];
}
【０５５８】
ａｄｄＣｏｎｔａｃｔテンプレートは、バインディングされた入力フィールドをもつフォームを表示する。
<form netui:action=”$pageFlow.createContact()”>
<table><tbody>
<tr>
<td>Title</td>
<td>
<select netui:bind=”$context.salutation”>
<option value=”Mr”>Mr</option>
<option value=”Ms”>Ms</option>
<option value=”Mrs”>Mrs</option>
<option value=”Dr”>Dr</option>
</select>
</td>
</tr>
<tr>
<td>First</td><td><input type=”text” netui:bind=”$context.first”/></td>
</tr>
<tr>
<td>Last</td><td><input type=”text” netui:bind=”$context.last”/></td>
</tr>
<tr>
<td>Email</td><td><input type=”text” netui:bind=”$context.email”/></td>
</tr>
<tr colspan=”2”>
<td><input type=”submit” value=”Create”/></td>
</tr>
</tbody></table>
</form>
【０５５９】
バインディングされた変数を含むテンプレートがアクションを呼び出すときに、それら変数は、現在ＸＨＴＭＬフォーム値でセットすることができる。これらの場合に、サブミット＜ｉｎｐｕｔ＞エレメントは、以下に示すフォームのｃｒｅａｔｅＣｏｎｔａｃｔアクションを呼び出す。
function createContact() {
$context.account.@@contacts.create(
<contact>
<salutation>{$context.salutation}</salutation>
<first>{$context.first}</first>
<last>{$context.last}</last>
<email>{$context.email}</email>
</contact>
);
return [”showContacts.tmpl”];
}
【０５６０】
条件タグ
＜ｎｅｔｕｉ：ｉｆ＞タグは、計算された条件に基づきＸＨＴＭＬセグメントを条件付きで含むように使用することができる。
<netui:if cond=”spath-expr”>...</netui:if>
ｃｏｎｄ属性は、ページがレンダリングされるときに評価されるＳＰａｔｈ表現を定義する。この表現が真と評価される場合には、＜ｎｅｔｕｉ：ｉｆ＞エレメント内に含まれたＸＨＴＭＬセグメントがＸＨＴＭＬページに挿入される。
【０５６１】
表現は、標準的ＸＳｃｒｉｐｔ強制を使用して、ブールの結果を評価する。次の表現は、全て、真と評価される。
{true}
{100}
{”some string”}
{<xml>}
{$root}
以下の例は、条件付きテンプレートを実施するために＜ｉｆ＞タグを含む。ここで、＄ｃｕｒｒｅｎｔ．ｅｍａｉｌテーブル列は、変数が非ナル（即ち、空又はゼロ長さのテキスト）の場合にのみ表示され、他の全ての値は、真に強制される。
<table><tbody>
<tr>
<td>{$current.salutation}</td>
<td>{$current.first}</td>
<td>{$current.last}</td>
<netui:if cond=”$current.email”>
<td>{$current.email}</td>
</netui:if>
</tr>
</tbody></table>
条件付きテンプレートは、テンプレート設計におけるプロパティシートとして表示できることに注意されたい。
【０５６２】
リピータタグ
テンプレートは、データグラフ及びシステム変数からの普通のＸＨＴＭＬエレメント及びデータを合体する。又、それらは、レンダリングされるときにＸＨＴＭＬを発生するエレメントを含んでもよい（ＪＳＰにおけるＴａｇｌｉｂｓと同様に）。
リピータは、エレメントリスト（例えば、アカウントのノードリスト）にわたって中継するＨＴＭＬジェネレータタグである。＜ｎｅｔｕｉ：ｒｅｐｅａｔｅｒ＞は、エレメントに対して同じＨＴＭＬを中継するのに使用されるタグであり、＜ｎｅｔｕｉ：ｒｅｐｅａｔｅｒ＞エレメントの全ての子エレメントは、評価されたＳＰａｔｈ表現の各エレメントに対して中継される。
【０５６３】
シンタックス
<netui:repeater
id=”tag-id”
source=”spath-expr”
[iterator=”variable-name”]
[selected=”spath-expr”]
[orderBy=”orderBy-expr”]/>
各＜ｎｅｔｕｉ：ｒｅｐｅａｔｅｒ＞エレメントは、それが繰り返さねばならないところの１組のノードを記述するｓｏｕｒｃｅ属性を有する。概念的には、テンプレート内部の全てのＸＨＴＭＬは、ｓｏｕｒｃｅ属性により記述される各ノードに対して中継される。中継されるＸＨＴＭＬセグメントは、ｉｔｅｒａｔｏｒ属性により参照される繰り返されるノードインスタンスにアクセスすることができる。
【０５６４】
リピータは、次の属性を定義する。
2007524933.tif 000055
【０５６５】
次のファンクションは、リピータオブジェクトにおいてコールすることができる。
2007524933.tif 000056
【０５６６】
セクションの中継
次のテンプレートセグメントは、アカウントｋｅｙｒｅｆにより定義されるノードのリストを表示するリピータを定義する。
<ul>
<netui:repeater id=”$repeater1” source=”$current.@@accounts.*” iterator=”$i”>
<li>{$i.label()}</li>
</netui:repeater>
</ul>
これは、次の出力を生成する。
2007524933.tif 000057
＜ｎｅｔｕｉ：ｒｅｐｅａｔｅｒ＞エレメント内に含まれた全てのＸＨＴＭＬエレメントは、ｓｏｕｒｃｅ属性により定義されたノードリスト内の各ノード（即ち、各アカウントノード）に対して中継される。
【０５６７】
ナビゲーション及び選択
中継されたセクションは、アクション又はシステムファンクションを呼び出すアンカーを含んでもよい。例えば、以下のリピータは、アカウントのリストを表示し、アンカー（ハイパーテキスト）を各アカウントのラベルと共に表示する。
<ul>
<netui:repeater id=”$repeater1” source=”$current.@@accounts.*” iterator=”$i”>
<li><a href=”$pageFlow.navigate($i, showDetail.tmpl')”>{$i.label()}</a></li>
</netui:repeater>
</ul>
【０５６８】
アンカーの１つをクリックすると、システムナビゲーションファンクションを呼び出させ、コントローラが、ｓｈｏｗＤｅｔａｉｌ．ｔｍｐｌテンプレートへナビゲーションするようにさせ、＄ｃｕｒｒｅｎｔは、対応する中継エレメントに対して＄ｉの値により参照されるノードを指すようにセットされる。
【０５６９】
リピータは、ユーザがリストから特定のエレメントを選択できるようにする内蔵ファンクションｓｅｌｅｃｔ（）を実施する。例えば、次のテンプレートセグメントは、上記ノードリストをＨＴＭＬアンカーのリストとして表わす。
<ul>
<netui:repeater id=”$repeater1” source=”$current.@@accounts.*” iterator=”$i”>
<li><a href=”$repeater1.select($i)”>{$i.label()}</a></li>
</netui:repeater>
</ul>
【０５７０】
特定のアンカーをクリックすると、リピータのｓｅｌｅｃｔｅｄ属性を＄ｉ変数の現在値にセットさせる。テンプレートの他の部分は、リピータの現在選択値を参照してもよい。
<ul>
<netui:repeater id=”$repeater1” source=”$current.@@accounts.*” iterator=”$i”>
<li>
<a href=”$repeater1.select($i) ”
style='{$repeater1.selected.contains($i) ? ”background-color:yellow”:””}>
{$i.label()}</a>
</li>
</netui:repeater>
</ul>
<p>Type: {$repeater1.selected.type}<p>
【０５７１】
これは、次の出力を生成する。
2007524933.tif 000058
上記＜ａ＞アンカーは、関連アイテムが選択された場合にエレメントのバックグランドカラーを変更するＳＰａｔｈ表現を含むスタイル属性を宣言する。
ｓｅｌｅｃｔｅｄ属性は、他のリピータ（チェーンとして知られている）及びその後に呼び出されるアクションによりアクセスすることができる。又、中継されるＨＴＭＬセクションは、ｓｅｌｅｃｔｅｄ属性を参照して、現在選択されたアイテムを視覚指示することもできる。
【０５７２】
チェーン型リピータ
リピータは、親リピータにおけるエレメントの選択が子リピータにおいて表示されるものに影響するように、一緒にチェーン接続することができる。例えば、次のリピータは、手前のリピータにおいて選択されたノード（Ｃｏｎｔａｃｔ）に関連したメッセージのリストを表示する。
<ul>
<netui:repeater id=”$repeater1” source=”$current.@@accounts.*” iterator=”$i”>
<li><a href=”$repeater1.select($i)”>{$i.label()}</a></li>
</netui:repeater>
</ul>
<br/>
<ul>
<netui:repeater id=”$repeater2” source=”$repeater1.selected.@@contacts.*” iterator=”$j”>
<li>$j.label()</li>
</netui:repeater>
</ul>
【０５７３】
次のテンプレートは、多列表示（以下に示す）を生成するネスト状リピータを示す。
<table><tbody>
<tr>
<td>App</td><td>Repeater 1</td><td>Repeater 2</td><td>Contacts</td>
</tr>
<tr>
<td>{$current}</td>
<td><ul>
<netui:repeater id=”$x” source=”$current.@@keyref('*')” iterator=”$i”>
<li><a href=”$x.select($i)”>{$i}</a></li>
</netui:repeater>
</ul></td>
<td><ul>
<netui:repeater id=”$y” source=”$x.selected.*” iterator=”$j”>
<li><a href=”$y.select($j)”>{$j}</a></li>
</netui:repeater>
</ul></td>
<td><ul>
<netui:repeater source=”$y.selected.@@contacts.*” iterator=”$k”>
<li>{$k}</li>
</netui:repeater>
</ul></td>
</tr>
</tbody></table>
【０５７４】
第１リピータは、ｋｅｙｒｅｆアンカーのリストを発生し、第２リピータは、そのｓｏｕｒｃｅ変数を以前のリピータの選択されたノードへバインディングし、そしてノードアンカーのリストを発生する。最終的なリピータは、ｃｏｎｔａｃｔノードのリストを発生する。このリピータのソース属性は、ｃｏｎｔａｃｔｓ  ｋｅｙｒｅｆへ特にトラバースし、自動化ｋｅｙｒｅｆ列をスキップする。
【０５７５】
リピータのｓｅｌｅｃｔ（）ファンクションが呼び出されると、テンプレートの再表示を自動的にトリガーし、従属するリピータのソースを変更すると共に、従属するリピータの選択された変数をナルへセットする。テンプレートは、リピータ間の円形依存性を回避しなければならない。セレクトメカニズムは、テンプレートの現在カーソルが変化しないので、ナビゲーションとみなされない。
【０５７６】
上記例は、次の表示を生じる。
2007524933.tif 000059
【０５７７】
上記テンプレートは、ＵＩのナビゲーション部分を表わし、エンドユーザが一連のｋｅｙｒｅｆをトラバースできるようにする。
ノードのテーブルを表わすようにＵＩを更に変更することができる。例えば、
<td>
<table><tbody>
<netui:repeater source=”$y.@@contacts.*” iterator=”$k”>
<tr>
<td>{$k.email}</td>
<td>{$k.label()}</td>
</tr>
</netui:repeater>
</tbody></table>
</td>
【０５７８】
これは、次の出力を生じる。
2007524933.tif 000060
【０５７９】
焦点型ピータ
又、リピータは、「焦点が当てられる」ように定義されてもよく、これは、ｓｏｕｒｃｅ属性により定義されたエレメントの全集合にわたって繰り返すのではなく、リピータが一度に１つのエレメントしか示さず、カーソルを維持することを意味する。
次の付加的なファンクションは、焦点型リピータオブジェクトにおいてコールされてもよい。
2007524933.tif 000061
【０５８０】
次の例において、焦点属性は、ｎｏｄｅｓｅｔからの単一ノードを表示すべきであることを宣言する。以下のアクションは、焦点型リピータを含むテンプレートを呼び出し、そして指定のアカウントのコンタクトｋｅｙｒｅｆに関するノードリストに＄ｃｕｒｒｅｎｔをセットする。
function selectContacts($account) {
$context.cursor = $account.*[0];
return [$account.*, ”focusedContacts.tmpl”];
}
【０５８１】
アンカーは、リピータのカーソルを移動するリピータのファンクションを呼び出す。
<netui:repeater id=”$s” source=”$current” iterator=”$i”>
<netui:if cond=”$s.position($context.cursor) == $i.count()”>
<td>first</td><td>{$i.first}</td>
<td>last</td><td>{$i.last}</td>
<td>email</td><td>{$i.email}</td>
</netui:if>
</netui:repeater>
<netui:if cond=”$s.position($context.cursor) > 0”>
<a href=”$context.cursor = $current[$s.position($context.cursor)-1]”>previous</a>
</netui:if>
<netui:if cond=”$s.position($context.cursor) < ($s.length()-1)”>
<a href=”$context.cursor = $current[$s.position($context.cursor)+1]”>next</a>
</netui:if>
【０５８２】
これは、次の出力を生成する。
2007524933.tif 000062
【０５８３】
デフォールトにより、焦点型リピータは、カーソルを、＄ｃｕｒｒｅｎｔノードリストにおいて最初のノードを指すようにセットする。ｓｅｌｅｃｔｅｄ属性が定義された場合には、これを使用して、カーソルを適当なノード（通常、手前のアクションによりセットされたコンテクスト変数により定義された）にセットする。
<netui:repeater id=”$s” source=”$current” iterator=”$i” selected=”$context.selected”>
<td>first</td><td>{$i.first}</td>
<td>last</td><td>{$i.last}</td>
<td>email</td><td>{$i.email}</td>
</netui:repeater>
【０５８４】
分類型リピータ
リピータは、ｏｒｄｅｒＢｙ属性を宣言することによりエレメントが列挙される順序を指定できる。ｏｒｄｅｒＢｙ属性は、ＸＱｕｅｒｙ状の表現を含むストリングである。
<netui:repeater id=”id” source=”source” iterator=”var” 
orderBy=”OrderByClause”>
ｏｒｄｅｒＢｙＣｌａｕｓｅが次のＢＮＦ文法に合致する場合（ＳＰａｔｈ表現は、特定のリピータアイテムに対するフィールド値を表わす）：
OrderByClause ::= OrderSpec (”,” OrderSpec)*
OrderSpec     ::= SPath OrderModifier
OrderModifier ::= (”ascending” | ”descending”) ?
((”empty” ”greatest”) | (”empty” ”least”)) ?
(”collation” StringLiteral)?
【０５８５】
この表現は、安定な順序（即ち、多数の呼び出しにわたって等しい値の順序を保持しなければならない）を仮定することに注意されたい。
例えば、次のリピータは、コンタクトのラストネーム（即ち、＄ｉ．ｌａｓｔ）の降下する値によりコンタクトをリストする。
<netui:repeater id=”$s” source=”$current.@@contacts.*” iterator=”$i”
orderBy=”$i.last descending”>
<td>last</td><td>{$i.last}</td>
<td>first</td><td>{$i.first}</td>
<td>email</td><td>{$i.email}</td>
</netui:repeater>
【０５８６】
次のリピータは、ラストネームにより上昇順に（即ち、デフォールト）、次いで、ファーストネームにより下降順に分類する。
<netui:repeater id=”$s” source=”$current.@@contacts.*” iterator=”$i”
orderBy=”$i.last empty least, $i.first descending”>
上記例では、空きのラストネーム値は、最下位とみなされることに注意されたい。
【０５８７】
メタデータリピータ
又、リピータは、データモデルにより定義されたメタデータにわたって繰り返すように使用することもできる。
例えば、ｎｏｄｅ．ｋｅｙｒｅｆ（‘＊’）ファンクションは、対応するｎｏｄｅｔｙｐｅからの考えられるナビゲーションを記述するｋｅｙｒｅｆエレメントのリストを返送する。これは、ｋｅｙｒｅｆのリストを表示するためにリピータのソースとして使用されてもよい。
<ul>
<netui:repeater id=”$repeater1” source=”$current.@@keyref(*')” iterator=”$i”>
<li>{$i.label()}</li>
</netui:repeater>
</ul>
【０５８８】
上記例は、＄ｃｕｒｒｅｎｔがａｃｃｏｕｎｔノードを指す場合に、次の出力を返送する。
−ｏｗｎｅｒ
−ｓｕｂＡｃｃｏｕｎｔ
−ｃｏｎｔａｃｔｓ
−ｎｏｔｅｓ
−ｅｖｅｎｔｓ
−ｑｕｔｏｔｅｓ
【０５８９】
ｎｏｄｅ．ｓｃｈｅｍａ（）ファンクションは、対応するｎｏｄｅｔｙｐｅのＸＭＬスキーマ定義を表わすＸＭＬ文書を返送する。これは、入力フォームを形成するためのリピータのソースとして使用されてもよい。
<netui:repeater id=”repeater1” source=”$current.meta().schema()”
showNull=”true” iterator=”$i”>
<tr>
<td>{$current.meta().schema().getFieldLabel($i)}</td>
<td>{$i)</td>
</tr>
</netui:repeater>
【０５９０】
上記例は、次の出力を発生する。
2007524933.tif 000063
映像タグ
標準的なＸＨＴＭＬ＜ｉｍｇ＞タグは、映像を表示するのに使用される。
<img
[src=”filename”]
[netui:content=”spath-expr”]
[netui:type=”content-type”]/>
映像タグは、次の属性を定義する。
2007524933.tif 000064
【０５９１】
標準的なＸＨＴＭＬ属性に加えて、フレームワークは、映像のバイナリーソースを含むエレメントを参照するＳＰａｔｈ表現を宣言するためにｎｅｔｕｉ：ｃｏｎｔｅｎｔ及びｎｅｔｕｉ：ｔｙｐｅ属性をサポートする。これは、ｎｏｄｅｔｙｐｅの１つがそのＸＭＬスキーマ定義内の適当なエレメントを定義することを要求する。
例えば、以下のコンタクトスキーマは、＜ｉｍａｇｅ＞データエレメントを合体するように拡張されている。
<xsd:complexType name=”contactType”>
<xsd:sequence>
<xsd:element name=”salutation” type=”contactSalutationEnum”/>
<xsd:element name=”first” type=”xsd:string”/>
<xsd:element name=”last” type=”xsd:string”/>
<xsd:element name=”email” type=”xsd:string”/>
<xsd:element name=”image” type=”xsd:base64Binary”/>
</xsd:sequence>
</xsd:complexType>
【０５９２】
これは、次のＸＨＴＭＬを使用して参照される。
<img netui:content=”$current.contact.image” netui:type=”bmp”/>
ｉｎｃｌｕｄｅタグ
標準的な＜ｎｅｔｕｉ：ｉｎｃｌｕｄｅ＞タグは、参照されたものを挿入するのに使用される。
<netui:include template=”templateFile” [$current=”spath-expr”]/>
ｉｎｃｌｕｄｅタグは、現在ページへ挿入されるべきテンプレートを命名するｔｅｍｐｌａｔｅ属性を定義する。任意のｃｕｒｒｅｎｔ属性は、＄ｃｕｒｒｅｎｔを、挿入されたテンプレートの範囲内にセットするのに使用される。
【０５９３】
例えば、次のＸＨＴＭＬセグメントは、例えば、チェーン型リピータを拡張し、そしてコンタクトのリストを表示する（特定アカウント＄ｙに対して）新たなリピータ（＄ｚ）を合体する。＜ｎｅｔｕｉ：ｉｎｃｌｕｄｅ＞タグは、ｄｅｔａｉｌ．ｔｍｐｌテンプレートを含み、そしてリピータの選択されたノード（即ち、コンタクトノード）となる＄ｃｕｒｒｅｎｔ変数を定義する。
<td><ul>
<netui:repeater id=”$z” source=”$y.@@contacts.*” iterator=”$k”>
<li><a href=”select($k)”>{$k}</a></li>
</netui:repeater>
</ul></td>
<td>
<netui:include current=”$z.selected” template=”detail.tmpl”/>
</td>
【０５９４】
ｄｅｔａｉｌ．ｔｍｐｌテンプレートは、次のように定義される。
<td>
<table><tbody>
<tr><td>Detail</td></tr>
<tr><td>{$current.label()}</td></tr>
<tr><td>{$current.email}</td></tr>
</tbody></table>
</td>
これは、次の出力を生じる。
2007524933.tif 000065
【０５９５】
ＨＴＭＬタグ
＜ｎｅｔｕｉ：ｈｔｍｌ＞タグは、生のＸＨＴＭＬを現在ページに挿入するのに使用される。
<netui:html>{spath-expr}</netui:html>
通常、ＳＰａｔｈ表現が評価され、そしてそれにより生じる値がストリングとして解釈され、ＨＴＭＬとして処理されない。しかしながら、オープニングとクロージングの＜ｎｅｔｕｉ：ｈｔｍｌ＞タグ間に含まれた全ての評価されたＳＰａｔｈ表現は、ブラウザにより処理されるべきＨＴＭＬとしてページに挿入される。
【０５９６】
例えば、次のアクションコードが与えられると、
$current.productDesc = ”<p>A <b>great</b> new product.</p>”;
次のテンプレートＨＴＭＬは、以下の出力を返送する。
<netui:html>{$current.productDesc}</netui:html>
優れた新規製品
ＨＴＭＬ及び表現は、＜ｎｅｔｕｉ：ｈｔｍｌ＞エレメント内に合成されてもよい。例えば、次のテンプレートＨＴＭＬは、以下の出力を返送する。
<netui:html>
<ul><li>{$current.productDesc}</li><li>{$current.productDetail}</li><ul>
</netui:html>
−優れた新規製品
−あなたにウェブロジックを運ぶ人々から
【０５９７】
コントローラ
コントローラは、外部同期メッセージに応答してユーザインターフェイス及びデータベースにより引き起こされた事象を処理する責任をもつことができる。コントローラは、アクションスクリプトを実行させ、且つテンプレートをブラウザによりインスタンス生成して表示させることができる。コントローラのデフォールト振舞いは、ＸＭＬに対してＥＣＭＡＳｃｒｉｐｔで書かれ且つ本質的にＪＰＦのＥＣＭＡＳｃｒｉｐｔバージョンであるｃｏｎｔｒｏｌｌｅｒ．ｘｐｆを実施することにより、拡張できる。
コントローラファイルは、アクション及び普通のＥＣＭＡＳｃｒｉｐｔファンクション、並びにグローバルな変数定義を含むことができる。
【０５９８】
ページフロー
ｃｏｎｔｒｏｌｌｅｒ．ｘｐｆファイルは、アプリケーションに関するページフローを定義することができる。アプリケーションのクライアント部分は、コントローラ定義、アクション、及び１組のテンプレートで構成される。
【０５９９】
コントローラファイルは、ＸＳｃｒｉｐｔファンクション及びアクション定義で構成することができる。アクションは、テンプレート（及び他のアクション）により呼び出され、そして同じ＄ｒｏｏｔ、＄ｃｕｒｒｅｎｔ及び＄ｃｏｎｔｅｘｔ変数にアクセスすることができ、それらは、＄ｃｕｒｒｅｎｔ変数を直接変更することができず、むしろ、フォワードアレーを返送し、これは、＄ｃｕｒｒｅｎｔ及び＄ｐａｇｅの値を決定するようにコントローラにより解釈される。アクションは、ページへ及びページから状態を通すのに使用される新たな＄ｃｏｎｔｅｘｔ変数を追加し及び変更することができる。このコンテクスト状態は、経歴スタックにも記憶される。
【０６００】
各アプリケーションは、開始ファンクション（又はアクション）の定義を最小限含まねばならないコントローラファイルを定義し、これは、アプリケーションが実行されるときにコールされる。最小限、開始ファンクションは、表示されるべき第１テンプレートのｆｉｌｅｎａｍｅを含むフォワードアレーを返送しなければならない。
function begin()
{
return [”home.tmpl”];
}
【０６０１】
フォワードアレー
フォワードアレーは、ＸＳｃｒｉｐｔオブジェクト（即ち、ストリング、変数、ＳＰａｔｈ表現）のアレーであり、これらは、表示すべき次のテンプレート（即ち、＄ｐａｇｅ変数）を決定しそして＄ｃｕｒｒｅｎｔシステム変数の値をセットするためにコントローラにより解釈される。
【０６０２】
フォワードオブジェクトの次のタイプが定義される。
2007524933.tif 000066
【０６０３】
フォワードアレーは、任意の順序のフォワードオブジェクトで構成できる。これは、多数のＳＰａｔｈ表現、多数のテンプレートｆｉｌｅｎａｍｅ、又はテンプレートｆｉｌｅｎａｍｅ及びナビゲーションストリング定数（例えば、”ＣＯＮＴＩＮＵＥ”）を含まなくてもよい。次のものは、全て、リーガルフォワードアレーである。
return [”BACK”]
return [”home.tmpl”];
return [”home.tmpl”, $root.@@accounts.*];
return [nextAction];
return [];
【０６０４】
何も返送しないか又は空のフォワードアレーを返送するアクションは、＄ｐａｇｅ及び＄ｃｕｒｒｅｎｔ変数を変更せず、これは、［”ＣＯＮＴＩＮＵＥ”］の返送と透過であることに注意されたい。
以下の例では、アクションは、コンテクスト変数を使用して計算を実行すると共に、それが成功すると、ｓｈｏｗＯｒｄｅｒテンプレートへナビゲーションする。アラーが生じると、アクションは、エラーコンテクスト変数をセットし、そして現在テンプレートに留まるようにコントローラに指令する。
function calulateTotal() {
if ($context.order.qty <= 0) {
$context.error = ”Error: Quantity not set.”;
return [”CONTINUE”];
}
$context.order.total = $context.order.price * $context.order.qty;
return [”showOrder.tmpl”];
}
【０６０５】
アクション
アクションは、アプリケーションがデータを変更し、現在テンプレートを変更し、又はナビゲーションに影響を及ぼすためのメカニズムを与えることができる。例えば、アクションは、データノードを生成又は更新し、特定のｎｏｄｅｓｅｔにおける合計を計算し、或いはブラウザをデータモデルの異なる部分へ向け直してもよい。一実施形態では、テンプレートは、ローカルデータキャッシュ（又は＄ｃｏｎｔｅｘｔ）に記憶されたデータしかアクセスできないので、アクションは、外部システムと対話する（オンターネットを経て）メカニズムを与える。
【０６０６】
アクションは、テンプレートアンカーにより呼び出される。アクションの呼び出しは、同じシンタックスを普通のＥＣＭＡＳｃｒｉｐｔファンクションとして使用するが、それらは、＄ｐａｇｅＦｌｏｗ（コントローラ）オブジェクトにおけるメソッドとして呼び出される。
$pageFlow.actionName([param1[, param2[, ...]]])
例
次のアンカー宣言は、ｆｏｏ（）アクションを呼び出し、ストリングパラメータにおいて通過させる。
<a href=”$pageFlow.foo(World')”>Foo</a>
The action definition (defined in controller.xpf) is show below.
function foo($p) {
$context.bar = <hello>{$p}</hello>;
return [”CONTINUE”];
}
この場合、アクションは、＄ｃｏｎｔｅｘｔ変数（入力パラメータを含むＸＭＬオブジェクト）をセットし、そしてコントロールを現在テンプレートへ戻す。
【０６０７】
次の例は、＄ｃｕｒｒｅｎｔ変数を、ａｃｃｏｕｎｔｓ  ｋｅｙｒｅｆにより含まれたｎｏｄｅｓｅｔにおけるポイントへ変化させるフォワードオブジェクトを返送する。
function example1($p) {
...
return [$root.@@accounts.*];
}
次の例は、＄ｃｕｒｒｅｎｔをルートノードにおけるポイントへ変化させ、そして現在テンプレートも変化させる。
function example2($p) {
...
return [$root, ”bar.tmpl”];
}
【０６０８】
タイマー
タイマーは、簡単な事象発生メカニズムを実施する。ａｄｄＴｉｍｅｒ（）ファンクションは、指定の遅延の後に、任意であるが規則的な間隔で呼び出されるコールバックファンクションを登録するのに使用される。
var timerId = $pageFlow.addTimer(callback, delay[, period]);
このファンクションは、＄ｐａｇｅｆｌｏｗオブジェクトにおいてコールされ、そしてタイマーインスタンスを独特に識別する識別子を返送する。
2007524933.tif 000067
【０６０９】
ｃａｎｃｅｌＴｉｍｅｒ（）ファンクションは、タイマーをキャンセルするのに使用される。
$pageFlow.addTimer(timerId);
このファンクションは、＄ｐａｇｅｆｌｏｗオブジェクトにおいてコールされ、そしてタイマーインスタンスを独特に識別する識別子を返送する。
2007524933.tif 000068
【０６１０】
例
次の例において、ファンクションｆｏｏ（）は、タイマーをセットし、該タイマーは、ｂａｒ（）ファンクションを直ちにスケジュールし、次いで、１秒間隔で繰り返しスケジュールする。
function foo() {
var timerId = $pageFlow.addTimer(bar, 0, 1000);
}
function bar(timerId, count) {
$root.select(@@accounts.*.@@contacts.*.@@tasks.*.where(.priority == 1));
if (count == 10) {
$pageFlow.cancelTimer(timerId);
}
}
【０６１１】
ここで、コールバックファンクションｂａｒ（）は、ＳＰａｔｈ表現により定義されたデータセットを更新するためにサーバーをポーリングするディープセレクトオペレーションを呼び出す。タイマーは、ｃａｎｃｅｌＴｉｍｅｒ（）システムファンクションをコールすることにより、１０番目の呼び出しでキャンセルされる。
ブラウザは、単一スレッドの実行モデルを実施し、それ故、コールバックファンクションは、少なくともコールファンクションが戻るまで実行されない。
【０６１２】
経歴
ナビゲーションが行われるたびに、＜＄ｃｕｒｒｅｎｔ  ｘ  ＄ｃｏｎｔｅｘｔ  ｘ  ＄ｐａｇｅ＞タプルが、＄ｈｉｓｔｏｒｙシステム変数によりアクセスできる経歴スタックに入れられる。
ｂａｃｋ（）システムアクションをコールすると、これらの値を以前の経歴状態へロールバックさせ、同様に、ｆｏｒｗａｒｄ（）は、これらの値を次の経歴状態へ移動させる。ユーザが後方に移動しそして異なるナビゲーションを生じさせる場合には（即ち、前方に移動するのではなく）、全フォワード経歴が裁断される。
【０６１３】
経歴スタックを通して前後に移動することで、全リピータの現在選択された値が保存され、又、全＄ｃｏｎｔｅｘｔ変数が経歴フレームの一部分であるから、フォーム値も保存される。
＄ｈｉｓｔｏｒｙオブジェクトについて定義されるファンクションは、前記で定義された。
【０６１４】
ページフローの例
図１０は、ＣＲＭアプリケーション１０００の一部分の簡単なページフローを示し、ダイアグラムａ）は、データモデルの一部分（スキーマ及びｋｅｙｒｅｆ）を表わし、そしてダイアグラムｂ）は、＄ｃｕｒｒｅｎｔ  ｎｏｄｅｔｙｐｅを指示する点線を各々もつ４つのテンプレートで構成されたページフローを表わす。このシナリオは、特定のアカウントに対するクオテ（quote）要求を開始するためにカスタムオペレーションを実施する。この例は、セレクトオペレーションのコンテクストとして使用されるカスタムオブジェクト（クオテ要求）を生成するプロセスを示す。
【０６１５】
Ｈｏｍｅテンプレートは、ユーザが、ＡｃｃｏｕｎｔＤｅｔａｉｌテンプレート（以下を参照）を呼び出す特定のアカウントへナビゲーションできるようにするリピータを含む。ＡｃｃｏｕｎｔＤｅｔａｉｌテンプレートは、以前の価格クオテのリストを示し、そしてユーザがｃｒｅａｔｅＱｕｏｔｅＲｅｑｕｅｓｔアクション（Ａ）を呼び出すことができるようにする。
<a href=”$pageFlow.createQuoteRequest()”>Create Quote Request</a>
【０６１６】
これは、次のアクションを呼び出すようにさせる。
function createQuoteRequest() {
$context.quoteRequest.prodId = ””;
$context.quoteRequest.qty = 0;
return [”createQuoteRequest.html”];
}
このアクションは、現在コンテクスト内の＜ｑｕｏｔｅＲｅｑｕｅｓｔ＞ＸＭＬオブジェクトを生成し、そしてｐｒｏｄＩｄ及びｑｔｙ子エレメントに対する値をセットする。これは、充分に形成された＜ｑｕｏｔｅＲｅｑｕｅｓｔ＞エレメントを生成し、次の表現と同等である。
$context.quoteRequest = <quoteRequest><prodId/></qty>0<qty></quoteRequest>;
【０６１７】
このアクションは、次いで、「テンプレート」フォワード経路を返送し、＄ｃｕｒｒｅｎｔ変数を変更せずにｃｒｅａｔｅｑｕｏｔｅＲｅｑｕｅｓｔテンプレートを呼び出す。このｃｒｅａｔｅｑｕｏｔｅＲｅｑｕｅｓｔテンプレートは、以下に示す。＄ｃｕｒｒｅｎｔは、依然、アカウントノードを指すことに注意されたい。
<p>Quote Request for {current.label()}</p>
<table><tbody>
<tr>
<td>Product ID</td>
<td><input netui:bind=”$context.quoteRequest.prodId”/></td>
</tr>
<tr>
<td>Quantity</td>
<td><input netui:bind=”$context.quoteRequest.qty”/></td>
</tr>
<tr>
<td colspan=”2”>
<input type=”submit” value=”Submit” onClick=”submitQuoteRequest()”/>
</td>
</tr>
</tbody></table>
2007524933.tif 000069
【０６１８】
このテンプレートは、ユーザが、以前のアクションにより生成された＜ｑｕｏｔｅＲｅｑｕｅｓｔ＞エレメントを編集できるようにする。フォームサブミットアクションは、現在フィー無値を、バインディングされた＄ｃｏｎｔｅｘｔ変数へコピーし、次いで、以下のｓｕｂｍｉｔｑｕｏｔｅＲｅｑｕｅｓｔアクション（Ｂ）を呼び出す。
function submitQuoteRequest() {
if ($context.quoteRequest.prodId != ”” || $context.quoteRequest.qty <= 0) {
return [”CONTINUE”];
}
else {
$current.@@quoteRequests.create($context.quoteRequest);
return [”BACK”];
}
}
【０６１９】
このアクションは、＜ｑｕｏｔｅＲｅｑｕｅｓｔ＞エレメントの値に関する検証を実行し、そしてエラーがない場合にテンプレート（ＣＯＮＴＩＮＵＥ）へ戻る。さもなければ、＜ｑｕｏｔｅＲｅｑｕｅｓｔ＞エレメントを、現在アカウントに対するｑｕｏｔｅＲｅｑｕｅｓｔ  ｋｅｙｒｅｆに追加する。＄ｃｏｎｔｅｘｔ．ｑｕｏｔｅＲｅｑｕｅｓｔ変数は、フォームからバインディングされた値を含む充分に形成された＜ｑｕｏｔｅＲｅｑｕｅｓｔ＞エレメントであることに注意されたい。例えば、
<quoteRequest>
<prodId>Widget-Z</prodId>
<qty>1000</qty>
</quoteRequest>
【０６２０】
成功すると、このアクションは、”ＢＡＣＫ”を、以前のＡｃｃｏｕｎｔＤｅｔａｉｌテンプレート（ＢＡＣＫ）へナビゲーションする。ＡｃｃｏｕｎｔＤｅｔａｉｌは、以下のように、同期されたｐｒｉｃｅＱｕｏｔｅｓのリストを表示する。
<p>Account: {$current}</p>
<td>Product ID</td><td>Quantity</td><td>Price</td>
<netui:repeater source=”$current.@@quoteRequests.*” iterator=”i”>
<td>{$i.prodId}</td>
<td>{$i.qty}</td>
<td>{$i.@@quote.price}</td>
</netui:repeater>
<a href=”$pageFlow.createQuoteRequest()}”>Create Quote Request</a>
【０６２１】
このテンプレートは、以下の表示を生成する。
2007524933.tif 000070
前記のｓｕｂｍｉｔｑｕｏｔｅＲｅｑｕｅｓｔアクションは、直ちに戻り、従って、新たなｑｕｏｔｅＲｅｑｕｅｓｔノードは、サーバーが同期されたｑｕｏｔｅノードで応答するまで、価格フィールドを表示しないことに注意されたい。
【０６２２】
プロートタイプの構築
プロートタイプを構築して実行するために、次のアプリケーションをインストールする必要がある：Ａｐａｃｈｅ  Ａｎｔ、Ｓｕｎ  ｊａｖａ  ＪＤＫ、Ｐｅｒｆｏｒｃｅ  ｃｌｉｅｎｔ、ＢＥＡ  Ｗｏｒｋｓｈｏｐ  ８．１。又、次の環境変数もセットしなければならない。
2007524933.tif 000071
【０６２３】
このチュートリアルは、パーフォース(Perforce)クライアントが、／／ａｌｃｈｅｍｙ／ｍａｓをｃ：＼ａｌｃｈｅｍｙ＼ｍａｓにマッピングするビューと共に設定されると仮定する。次のコマンドを使用して、最新のソースコードを同期させ、そしてフレームワークを再構築する。
C:\alchemy\mas> p4 sync
C:\alchemy\mas> ant rebuild
【０６２４】
アプリケーションの実行
プロートタイプブラウザは、ブラウザのａｎｔ構築ファイル（＼ａｌｃｈｅｍｙ＼ｍａｓ＼ｓｒｃ＼ｂｒｏｗｓｅｒ＼ｂｕｉｌｄ．ｘｍｌ）を経て呼び出すことができる。
次のランタイム変数が定義される。
2007524933.tif 000072
【０６２５】
例えば、次のコマンドは、指定のウインドウサイズをもつナビゲータアプリケーションを実行するブラウザを呼び出す。
ant f ..\..\src\browser\bulid.xml Dmas.appname=crm Dclient.geometry=400x200 
run
このコマンドを呼び出すためにバッチファイル（例えば、ｒｕｎ．ｂａｔ）を生成するのが便利である。
又、ブラウザは、次の環境変数を設定することにより構成できる。
2007524933.tif 000073
【０６２６】
プロパティ変数は、次の設定を含んでもよい。
2007524933.tif 000074
【０６２７】
例えば、次のコマンドは、ブラウザをクライアントモードにおいて実行し、そしてデータ持続性をターンオンする。
set MAS_PROPS=-Dmas.singleproc=false Dpersistent=true
サービス定義（コンジットメタファイル）において定義されたウェブサービスＵＲＬは、ウインドウズ（登録商標）ホストファイル（Ｃ：＼ＷＩＮＤＯＷＳ＼ＳＹＳＴＥＭ３２＼ＤＲＩＶＥＲＳ＼ＥＴＣ＼ｈｏｓｔ）において物理的ＩＰアドレスを宣言することにより物理的サーバーへマップすることができ、例えば、次のホストファイルは、上記ウェブサービスを、ａｌｃｈｅｍｙテストサーバーへマップする。
172.17.33.34  example.com
【０６２８】
デバッギング
全てのエラー及びトレース情報は、＼ａｌｃｈｅｍｙ＼ｍａｓ＼ａｌｃｈｅｍｙ．ｌｏｇファイルへ書き込まれる。
アプリケーションパッケージング
以下のテーブルは、個々のＭＡＳアプリケーションに対してファイル及びディレクトリー構造を表わす。
2007524933.tif 000075
【０６２９】
プロートタイプは、ｓｃｈｅｍａｓ及びｍｅｔａディレクトリー内に全てのファイルをロードする。
アプリケーションルートディレクトリー（／ａｐｐｓ）は、ｍａｓ．ａｐｐｒｏｏｔ及びｍａｓ．ｃｌｉａｎｔ．ａｐｐｒｏｏｔのランタイムプロパティ（上述した）に対応する。
【０６３０】
アプリケーションの配備及びマネージメント
アプリケーションは、ＭＡＳ（ワークショップ内で実行される）からクライアントへ配備することができる。
１．ワークショップは、アプリケーションマネージャーサーバーにおいて実行されねばならない（以下を参照）。
２．アプリケーションコンポーネント（上述したコントローラテンプレート、メタファイル、及びスキーマファイル）は、先ず、単一ファイルに（ａｐｐ．ｚｉｐ）にジップされねばならず、これを行うために、新たなジップファイルを生成し、全ａｐｐフォルダー（例えば、＼ｍａｓ＼ａｐｐｓ＼ｃｒｍ）をＷｉｎＺｉｐへドラグする（ＮＯＴチェック状態で「全経路ｉｎｆｏをセーブする」のを確保する）。
３．アプリケーションａｄｍｉｎページ：ｈｔｔｐ：／／ｗｗｗ．ｌｏｃａｌｈｏｓｔ．ｃｏｍ：７００１／ｍａｓを見る。これは、しばらくの間を要してもよいことに注意されたい。
ａ．”ブラウズ・・・”をクリックし、そしてジップファイルを選択する。
ｂ．”配備”をクリックし、アプリケーションをサーバーへアップロードする（上述したｍａｓｓ．ａｐｐｒｏｏｔプロパティにより定義された位置において）。
４．ａｄｍｉｎページは、各アプリケーションに対して配備ＵＲＬを表示する。
５．クライアントにアプリケーションを「インストール」するために、移動ブラウザを単一プロセスモードで実行する（ｍａｓ．ａｐｐプロパティを指定せずに；これは、ａｐｐセレクタダイアログを呼び出す）。
set MAS_PROPS=-Dmas.singleproc=false
ant f ..\..\src\browser\bulid.xml run
６．アプリケーションＵＲＬを適当な編集ボックスにエンターし、そしてＯＫをクリックする。
【０６３１】
アプリケーションマネージャーサーバーの実行
１．次のグローバル環境変数をセットする。
set JAVA_OPTIONS=-Dmas.approot=c:\alchemy\mas\apps
２．＼ａｌｃｈｅｍｙ＼ｍａｓ＼ｓｒｃ＼ｍａｓｊｗｓ．ｗｏｒｋをワークショップへロードする。
３．プロジェクトパンにおいてｃｏｎｔｒｏｌｌｅｒ．ｊｐｆファイルをダブルクリックする。
４．ライブラリーアップグレードについて促された場合には、イエスと言い、次いで、Ｉｎｓｔａｌｌをクリックする。赤い”could not be replaced”警報は、安全に無視できる。
５．サーバーをスタートする（ツール→ＷｅｂＬｏｇｉｃサーバー→スタートＷｅｂＬｏｇｉｃサーバー）。
６．サーバーがスタートした後、次のコマンドを実行する。（ＷｅｂＬｏｇｉｃ配備エラーは安全に無視できる）。
C:\alchemy\mas > ant deploy
【０６３２】
７．ワークショップから、ｃｏｎｔｒｏｌｌｅｒ．ｊｐｆファイルが選択された状態でランボタン（緑の三角形）をクリックする。最終的に（標準的なスローサーバーブートストラップスタフの後に）、インストールされたアプリケーション及びそれらのＵＲＬを、新たなアプリケーションをアップロードするための配備ボタンと共に列挙したウェブページを見なければならない。
８．クライアントアプリケーション配備についてｃ：＼ｔｅｍｐ＼ａｐｐを生成する。
９．次の環境変数をセットする。
set MAS_PROPS=-Dmas.client.approot=c:\temp\apps -Dmas.singleproc=false
１０．次のコマンドを実行する。
C:\alchemy\mas\src\browser > ant run
１１．ウェブページ（上述した）にリストされたＵＲＬをダイアログにペーストしそしてＩｎｓｔａｌｌをクリックする。最終的に、アプリケーションは、コンボボックスにいっぱいにリストされ、そしてログインが可能となる
【０６３３】
ＭＡＳスキーマ定義
アプリケーションスキーマ定義は、次のスキーマディレクティブを使用して、パブリックＭＡＳスキーマファイルをインポートしなければならない。
<xsd:import namespace=”urn:bea.mas” schemaLocation=”mas.xsd”/> 
ＭＡＳスキーマファイルは、全てのフレームワークＸＭＬタイプに対する定義を含む。
<?xml version=”1.0” encoding=”UTF-8”?>
<xsd:schema targetNamespace=”urn:bea.mas” xmlns=”urn:bea.mas” 
xmlns:xsd=”http://www.w3.org/2001/XMLSchema”
elementFormDefault=”qualified” attributeFormDefault=”unqualified”>
<xsd:simpleType name=”idType”>
<xsd:restriction base=”xsd:anySimpleType”/>
</xsd:simpleType>
<xsd:complexType name=”nodeSetType”>
<xsd:sequence>
<xsd:any minOccurs=”1” maxOccurs=”1”/>
</xsd:sequence>
<xsd:attribute name=”keyref” type=”xsd:string” use=”required”/>
</xsd:complexType>
<xsd:complexType name=”rootType”/>
<xsd:element name=”root” type=”rootType”/>
<xsd:complexType name=”graphType”>
<xsd:sequence>
<xsd:element ref=”root”/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name=”errorType”>
<xsd:sequence minOccurs=”0” maxOccurs=”unbounded”>
<xsd:choice>
<xsd:element name=”pkey” type=”idType”/>
<xsd:element name=”system” type=”systemErrorType”/>
<xsd:element name=”message” type=”xsd:string”/>
<xsd:element name=”field” type=”fieldErrorType”/>
</xsd:choice>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name=”systemErrorType”>
<xsd:sequence>
<xsd:element name=”code” type=”xsd:anySimpleType”/>
<xsd:element name=”message” type=”xsd:string”/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name=”fieldErrorType”>
<xsd:sequence>
<xsd:element name=”code” type=”xsd:anySimpleType”/>
<xsd:element name=”message” type=”xsd:string”/>
</xsd:sequence>
<xsd:attribute name=”xpath” type=”xsd:string”/>
</xsd:complexType>
</xsd:schema>
【０６３４】
自動ユーザインターフェイス
フレームワークは、ノードグラフをトラバースするのに使用できる自動ブラウザ（ナビゲータと称される）を合体する。以下の出力は、次のコマンドラインシンタックスを使用して、ＣＲＭ例から発生される。
ant f ..\..\src\browser\bulid.xml -Dmas.app=crm Dmas.client.app=navigator 
run
【０６３５】
ナビゲータは、最初に、ルートノードに関連した全てのｋｅｙｒｅｆ（即ち、アカウント）を示す。
2007524933.tif 000076
【０６３６】
ｋｅｙｒｅｆが選択されると、それに対応するノードが表示され、この場合には、ａｃｃｏｕｎｔ  ｋｅｙｒｅｆが選択され、そしてそれに対応するａｃｃｏｕｎｔノードが表示される。
2007524933.tif 000077
【０６３７】
次いで、ａｃｃｏｕｎｔノードが選択され、そしてａｃｃｏｕｎｔ  ｎｏｄｅｔｙｐｅに関連したｋｅｙｒｅｆ（即ち、ｓｏｕｒｃｅＴｙｐｅ＝”ａｃｃｏｕｎｔ”）が表示される。
2007524933.tif 000078
【０６３８】
ここで、ｃｏｎｔａｃｔ  ｋｅｙｒｅｆが選択されると、ｃｏｎｔａｃｔノードの対応リストが表示される。
2007524933.tif 000079
【０６３９】
このナビゲータは、上述した同じテンプレートリピータ及びナビゲーションメカニズムを使用する。それ故、カスタムテンプレート、アクション及びページフローと共にデフォールトナビゲーションを増分的に拡張することができる。
自動的なＵＩは、２つのテンプレートで構成され、即ち第１は、現在「焦点の合わされた」ノード（＄ｃｕｒｒｅｎｔ）と、ユーザがナビゲートできるｋｅｙｒｅｆのリストとを表示する「ナビゲータ」テンプレートであり、そして第２のテンプレートは、特定ノードの「詳細」フォームビューである。
【０６４０】
ナビゲーションテンプレートにおいて、ｋｅｙｒｅｆが選択されると、関連ｎｏｄｅｓｅｔのノードリストがリストとして表示される。
<table><tbody>
</tr>
<td><b>{$current}</b></td>
</tr>
<tr>
<netui:repeater id=”$x” source=”$current.keyref('*').*” iterator=”$i”>
<td><img src=”bullet.gif”></td>
<td><a href=”select($i)”>{$i}</a></td>
</netui:repeater>
</tr>
<tr>
<netui:repeater id=”$y” source=”$x.selected.*” iterator=”$j”>
<td><a href=”$pageFlow.navigate($j, 'navigator.tmpl')”>NAV</a></td>
<td><a href=”$pageFlow.navigate($j, 'detail.tmpl')”>{$j}</a></td>
</netui:repeater>
</tr>
</tbody></table>
【０６４１】
ノードリストにおけるノード当たり２つのアンカー（ハイパーリンク）が表示され、第１のアンカー”ＮＡＶ”は、ユーザが関連ノードへナビゲーションして、選択されたノード＄ｊを伴う現在ナビゲータを＄ｃｕｒｒｅｎｔとして再表示できるようにし、第２のアンカー（強制されたノード＄ｊのラベルを表示する）は、以下の詳細なテンプレートへナビゲーションする。
<table><tbody>
<tr colspan=”2”>
<td><b>{$current.label()}</b></td>
</tr>
<netui:repeater id=”$i1” source=”$current.*” iterator=”$i”>
<tr>
<td>{$current.name()}</td>
<td>{$i}</td>
</tr>
</netui:repeater>
</tbody></table>
【０６４２】
詳細なテンプレートは、現在ノードラベルを表示し、そしてノードのＸＭＬ文書を通して繰り返すリピータであって、エレメントタグネーム及びそれに対応する値を表示するリピータを含む。
ＣＲＭ例をナビゲーションする自動ブラウザの出力を以下に示す。
2007524933.tif 000080
【０６４３】
第１ページは、ルートノードに焦点を当てたナビゲータテンプレートを示し、即ちユーザは、アカウントｋｅｙｒｅｆを選択し、そして”Ａｃｍｅ”アカウントにドリルダウンする。これは、同じナビゲータテンプレートにナビゲーションして、”Ａｃｍｅ”アカウントノードを指すように＄ｃｕｒｒｅｎｔをセットする。次いで、ユーザは、コンタクトｋｅｙｒｅｆを選択し、そして”Ｓａｒａｈ  Ｓｍｉｔｈ”に対するコンタクトレコードをクリックし、このとき、ナビゲータは、コンタクトを表わすノードに＄ｃｕｒｒｅｎｔがセットされた詳細なテンプレートを表示する。
ブラウザのバックボタンは、ユーザが詳細なテンプレートからナビゲータテンプレートへナビゲーションして戻すことができるようにする。
【０６４４】
ＣＲＭ使用ケースデータモデル定義
このセクションは、サンプルＣＲＭアプリケーションの全てのアプリケーションコンポーネントを詳述する。
データモデル
上述したように、図５は、ＣＲＭアプリケーションに関するエンティティ関係ダイアグラム（ＥＲＤ）を示す。
【０６４５】
ルート及びユーザノードは、システムｎｏｄｅｔｙｐｅである。ルートノードは、個々のユーザがアクセスできるデータを表わす仮想ＸＭＬ文書のルートを表わす。ユーザノードは、システムの個々のユーザを表わし、そしてシステムにより自動的に発生される。
ルートノードは、アカウントノードを含み、そしてアカウントｋｅｙｒｅｆを定義する。各アカウントノードは、コンタクト、事象、ノート及びタスクノードを含んでもよく、そしてそれに対応するｋｅｙｒｅｆを定義する。同様に、各コンタクトノードは、事象、ノート及びタスクノードを含んでもよい。又、アカウントノードは、サブアカウントを含んでもよく、そしてｓｕｂＡｃｃｏｕｎｔ  ｋｅｙｒｅｆを定義する。
【０６４６】
アカウント及びコンタクトノードは、両方とも、システムユーザを参照する所有者ｋｅｙｒｅｆを含み、同様に、タスク及び事象ノードは、指定された（ユーザ）ｋｅｙｒｅｆを定義する。これらのｋｅｙｒｅｆは、全て、カーディナリティが１である。
スキーマ及びｋｅｙｒｅｆ定義
次のセクションは、５つのアプリケーションスキーマを詳述し、これらは、全て、／ｓｃｈｅｍａ／ｃｒｍ．ｘｓｄファイルにおいて定義される。
<?xml version=”1.0”?>
<xsd:schema targetNamespace=”http://example.com/”
elementFormDefault=”qualified” attributeFormDefault=”unqualified”
xmlns:xsd=”http://www.w3.org/2001/XMLSchema”
xmlns:mas=”urn:bea.com”
xmlns=”http://example.com/”>
【０６４７】
アカウントタイプ
ａｃｃｏｕｎｔ  ｎｏｄｅｔｙｐｅは、次のスキーマにより定義される。
<xsd:complexType name=”accountType”>
<xsd:all>
<xsd:element name=”name” type=”xsd:string”/>
<xsd:element name=”type” type=”accountTypeEnum”/>
</xsd:all>
<xsd:attribute name=”id” type=”xsd:string” mas:type=”pkey”/>
<xsd:attribute name=”timestamp” type=”xsd:string” mas:type=”seq”/>
<xsd:attribute name=”ownerId” type=”xsd:string”/>
<xsd:attribute name=”parentAccountId” type=”xsd:string”/>
</xsd:complexType>
<xsd:simpleType name=”accountTypeEnum”>
<xsd:restriction base=”xsd:string”>
<xsd:enumeration value=”Direct”/>
<xsd:enumeration value=”Web”/>
<xsd:enumeration value=”Channel”/>
<xsd:enumeration value=”Partner”/>
</xsd:restriction>
</xsd:simpleType>
【０６４８】
ａｃｃｏｕｎｔタイプは、ｎａｍｅエレメントで構成される簡単なラベル宣言を定義することに注意されたい。又、ｔｙｐｅフィールドは、ａｃｃｏｕｎｔＴｙｐｅの簡単なタイプ定義により定義された１組の制約された値を有する。
次のセクションは、第１の宣言されたｋｅｙｒｅｆを示す／ｃｏｎｄｕｉｔ／ｃｒｍ．ｊｓｘファイルの最上部を示す。アプリケーションは、ａｐｐ  ｎａｍｅｓｐａｃｅにおいて宣言されることに注意されたい。
<?xml version=”1.0”?>
<graphMeta xmlns=”run:bea.com”
xmlns:mas=”run:bea.com”
xmlns:app=”http://example.com/”>
<keyref name=”account” sourceType=”mas:root” targetType=”app:account”>
...
</keyref>
...
</graphMeta>
【０６４９】
ａｃｃｏｕｎｔ  ｋｅｙｒｅｆは、ユーザのｒｏｏｔノードを１組のａｃｃｏｕｎｔノードに関連付ける。ＣＲＭアプリケーションでは、これは、ｒｏｏｔノードにバインディングされた唯一のｋｅｙｒｅｆである。
<keyref name=”accounts” sourceType=”mas:root” targetType=”app:account”/>
次のｋｅｙｒｅｆ定義は、ａｃｃｏｕｎｔ  ｎｏｄｅｔｙｐｅに関連している（即ち、その全てがａｐｐ：ａｃｃｏｕｎｔをｓｏｕｒｃｅＴｙｐｅ属性として宣言している）。アカウントは、サブアカウント（ｓｕｂＡｃｃｏｕｎｔｓ）と、コンタクト、ノート、事象、タスク及びクオテ要求に対するノードの組とを含む。
<keyref name=”subAccounts” sourceType=”app:account” targetType=”app:account”/>
<keyref name=”contacts” sourceType=”app:account” targetType=”app:contact”/>
<keyref name=”notes” sourceType=”app:account” targetType=”app:note”/>
<keyref name=”events” sourceType=”app:account” targetType=”app:event”/>
<keyref name=”tasks” sourceType=”app:account” targetType=”app:task”/>
<keyref name=”quotes” sourceType=”app:account” targetType=”app:quoteRequest”/>
【０６５０】
又、ａｃｃｏｕｎｔ  ｎｏｄｅｔｙｐｅは、単一ユーザノードに対する参照（ルックアップ）も含み、これは、ノードの現在所有者を表わす。これは、カーディナリティ制約（厳密に１）を指定する次の宣言により表わされる。
<keyref name=”owner” sourceType=”app:account” targetType=”mas:user”
minOccurs=”1” maxOccurs=”1”/>
【０６５１】
コンタクトのタイプ
ｃｏｎｔａｃｔ  ｎｏｄｅｔｙｐｅは、次のスキーマにより定義される。
<xsd:element name=”contact” type=”contactType”>
<xsd:annotation>
<xsd:appinfo>
<mas:nodeAnnotation>
<mas:label>$node.first + ” ” + $node.last</mas:label>
</mas:nodeAnnotation>
</xsd:appinfo>
</xsd:annotation>
</xsd:element>
<xsd:complexType name=”contactType”>
<xsd:sequence>
<xsd:element name=”salutation” type=”contactSalutationEnum”/>
<xsd:element name=”first” type=”xsd:string”/>
<xsd:element name=”last” type=”xsd:string”/>
<xsd:element name=”email” type=”xsd:string”/>
</xsd:sequence>
</xsd:complexType>
<xsd:simpleType name=”contactSalutationEnum”>
<xsd:restriction base=”xsd:string”>
<xsd:enumeration value=”Mr”/>
<xsd:enumeration value=”Mrs”/>
<xsd:enumeration value=”Ms”/>
<xsd:enumeration value=”Dr”/>
</xsd:restriction>
</xsd:simpleType>
【０６５２】
ａｃｃｏｕｎｔ  ｎｏｄｅｔｙｐｅは、最初と最後のネームエレメントを構成するラベル宣言を定義することに注意されたい。又、ｓａｌｕｔａｔｉｏｎフィールドは、ｃｏｎｔａｃｔＳａｌｕｔａｔｉｏｎＥｎｕｍの簡単なタイプの定義により定義された１組の制約された値を有する。
次のｋｅｙｒｅｆ定義は、ｃｏｎｔａｃｔ  ｎｏｄｅｔｙｐｅに関連する（即ち、その全ては、ａｐｐ：ｃｏｎｔａｃｔをｓｏｕｒｃｅＴｙｐｅ属性として宣言している）。アカウントは、ノート、事象及びタスクに対するノードの組を含む。
<keyref name=”notes” sourceType=”app:contact” targetType=”app:note”/>
<keyref name=”events” sourceType=”app:contact” targetType=”app:event”/>
<keyref name=”tasks” sourceType=”app:contact” targetType=”app:task”/>
【０６５３】
又、ｃｏｎｔａｃｔ  ｎｏｄｅｔｙｐｅは、単一ユーザノードに対する参照（ルックアップ）も含み、これは、ノードの現在所有者を表わす。これは、カーディナリティ制約（厳密に１）を指定する次の宣言により表わされる。
<keyref name=”owner” sourceType=”app:contact” targetType=”mas:user”
minOccurs=”1” maxOccurs=”1”/>
【０６５４】
ノートタイプ
ｎｏｔｅ  ｎｏｄｅｔｙｐｅは、次のスキーマにより定義される。
<xsd:element name=”note” type=”noteType”>
<xsd:annotation>
<xsd:appinfo>
<mas:nodeAnnotation>
<mas:label>$node.title</mas:label>
</mas:nodeAnnotation>
</xsd:appinfo>
</xsd:annotation>
</xsd:element>
<xsd:complexType name=”noteType”>
<xsd:sequence>
<xsd:element name=”title” type=”xsd:string”/>
<xsd:element name=”body” type=”xsd:string”/>
</xsd:sequence>
</xsd:complexType>
ノートは、ｋｅｙｒｅｆ定義を含まない。
【０６５５】
事象のタイプ
ｅｖｅｎｔ  ｎｏｄｅｔｙｐｅは、次のスキーマにより定義される。
<xsd:element name=”event” type=”eventType”>
<xsd:annotation>
<xsd:appinfo>
<mas:nodeAnnotation>
<mas:label>$node.title</mas:label>
</mas:nodeAnnotation>
</xsd:appinfo>
</xsd:annotation>
</xsd:element>
<xsd:complexType name=”eventType”>
<xsd:sequence>
<xsd:element name=”title” type=”xsd:string”/>
</xsd:sequence>
</xsd:complexType>
【０６５６】
又、ｅｖｅｎｔ  ｎｏｄｅｔｙｐｅは、単一ユーザノードに対する参照（ルックアップ）も含み、これは、事象の現在指定されたユーザを表わす。これは、カーディナリティ制約（厳密に１）を指定する次の宣言により表わされる。
<keyref name=”assigned” sourceType=”app:event” targetType=”mas:user”
minOccurs=”1” maxOccurs=”1”/>
【０６５７】
タスクのタイプ
ｔａｓｋ  ｎｏｄｅｔｙｐｅは、次のスキーマにより定義される。
<xsd:element name=”task” type=”taskType”>
<xsd:annotation>
<xsd:appinfo>
<mas:nodeAnnotation>
<mas:label>$node.title</mas:label>
</mas:nodeAnnotation>
</xsd:appinfo>
</xsd:annotation>
</xsd:element>
<xsd:complexType name=”taskType”>
<xsd:sequence>
<xsd:element name=”title” type=”xsd:string”/>
<xsd:element name=”status” type=”taskStatusEnum”/>
</xsd:sequence>
</xsd:complexType>
<xsd:simpleType name=”taskStatusEnum”>
<xsd:restriction base=”xsd:string”>
<xsd:enumeration value=”Not started”/>
<xsd:enumeration value=”In progress”/>
<xsd:enumeration value=”Completed”/>
<xsd:enumeration value=”Deferred”/>
</xsd:restriction>
</xsd:simpleType>
【０６５８】
又、ｔａｓｋ  ｎｏｄｅｔｙｐｅは、単一ユーザノードに対する参照（ルックアップ）も含み、これは、事象の現在指定されたユーザを表わす。これは、カーディナリティ制約（厳密に１）を指定する次の宣言により表わされる。
<keyref name=”assigned” sourceType=”app:task” targetType=”mas:user”
minOccurs=”1” maxOccurs=”1”/>
【０６５９】
ＱｕｏｔｅＲｅｑｕｅｓｔのタイプ
ＱｕｏｔｅＲｅｑｕｅｓｔ  ｎｏｄｅｔｙｐｅは、次のスキーマにより定義される。
<?xml version=”1.0”?>
<xsd:schema targetNamespace=”http://example.com/”
elementFormDefault=”qualified” attributeFormDefault=”unqualified”
xmlns:xsd=”http://www.w3.org/2001/XMLSchema”
xmlns:mas=”run:bea.com”
xmlns=”http://example.com/”>
<xsd:element name=”quoteRequest” type=”quoteRequestType”/>
<xsd:complexType name=”quoteRequestType”>
<xsd:sequence>
<xsd:element name=”prodId” type=”xsd:string”/>
<xsd:element name=”qty” type=”xsd:integer”/>
<xsd:element name=”response” minOccurs=”0” type=”quoteRequestResponseType”/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name=”quoteRequestResponseType”>
<xsd:sequence>
<xsd:element name=”price” type=”xsd:double”/>
</xsd:sequence>
</xsd:complexType>
</xsd:schema>
【０６６０】
サンプルアプリケーションスキーマ
次のセクションは、クライアントプログラミングモデルによりアクセスされる仮想データグラフに対するアプリケーションデータを示す。
フレームワークは、アプリケーションデータについて次のＸＭＬスキーマ定義を発生する。
<?xml version=”1.0”?>
<xsd:schema targetNamespace=”http://example.com/”
elementFormDefault=”qualified” attributeFormDefault=”unqualified”
xmlns:xsd=”http://www.w3.org/2001/XMLSchema”
xmlns:mas=”run:bea.com”
xmlns=”http://example.com/”>
<xsd:element name=”graph”>
<xsd:complexType>
<xsd:sequence>
<xsd:element ref=”root” minOccurs=”1” maxOccurs=”1”>
<xsd:element ref=”account” maxOccurs=”unbounded”>
<xsd:element ref=”contact” maxOccurs=”unbounded”>
<xsd:element ref=”note” maxOccurs=”unbounded”>
<xsd:element ref=”event” maxOccurs=”unbounded”>
<xsd:element ref=”task” maxOccurs=”unbounded”>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
...
</xsd:schema>
【０６６１】
ｇｒａｐｈエレメントは、アプリケーションデータモデルの最上位レベルエレメントを表わし、これは、厳密に１つのｒｏｏｔノード宣言と、各アプリケーションスキーマ（アカウント、コンタクト、ノート、事象及びタスク）の各ノードに対する非制限宣言とを表わす。
次のタイプ定義は、アプリケーションスキーマ及びｋｅｙｒｅｆ定義から発生される。
<xsd:element name=”account”>
<xsd:complexType>
<xsd:sequence>
<xsd:element name=”name” type=”xsd:string”/>
<xsd:element name=”type” type=”accountType”/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name=”contact”>
<xsd:complexType>
<xsd:sequence>
<xsd:element name=”salutation” type=”contactSalutationEnum”/>
<xsd:element name=”first” type=”xsd:string”/>
<xsd:element name=”last” type=”addressType”/>
<xsd:element name=”email” type=”xsd:string”/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
...
<xsd:element name=”note”>
<xsd:complexType>
<xsd:sequence>
<xsd:element name=”title” type=”xsd:string”/>
<xsd:element name=”body” type=”xsd:string”/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name=”event”>
<xsd:complexType>
<xsd:sequence>
<xsd:element name=”title” type=”xsd:string”/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name=”task”>
<xsd:complexType>
<xsd:sequence>
<xsd:element name=”title” type=”xsd:string”/>
<xsd:element name=”status” type=”taskStatusEnum”/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
...
【０６６２】
サンプルアプリケーションデータ
システムは、３人のユーザ、”ａｌｅｘ”、”ｂｏｂ”及び”ｃａｒｏｌ”を有する（これらは、仮想グラフに示されないシステムオブジェクトである）。
<graph>
<root accounts=”a1 a2”/>
<account id=”a1” owner=”bob” contacts=”c1 c2” notes=”n1” events=”e1” tasks=”t1”>
<name>Acme</name>
<type>Direct</type>
</account>
<account id=”a2” owner=”bob” contacts=”c3”>
<name>Bancroft</name>
<type>Web</type>
</account>
<contact id=”c1” owner=”bob” events=”e2” tasks=”t2”>
<salutation>Mr</salutation>
<first>Roger</first>
<last>Reed</last>
<email>roger@acme.com</email>
</contact>
<contact id=”c2” owner=”bob” notes=”n2”>
<salutation>Ms</salutation>
<first>Sarah</first>
<last>Smith</last>
<email>sarah@acme.com</email>
</contact>
<contact id=”c2” owner=”bob” notes=”n2”>
<salutation>Ms</salutation>
<first>Sarah</first>
<last>Smith</last>
<email>sarah@acme.com</email>
</contact>
<note id=”n1”>
<title>ROI information</title>
<body>Attached document details ROI for product</body>
</note>
<note id=”n2”>
<title>Customer requirements</title>
<body>Attached document presents customer's current and anticipated needs</body>
</note>
<event id=”e1” assigned=”fred”>
<title>Sales meeting</title>
</event>
<event id=”e2” assigned=”fred”>
<title>Product demonstration</title>
</event>
<task id=”t1” assigned=”fred”>
<title>Prepare RFP for sales call</title>
<status>Not started</status>
</task>
<task id=”t2” assigned=”fred”>
<title>Send white paper to customer</title>
<status>Completed</status>
</task>
</graph>
【０６６３】
簡単なＳＰａｔｈ表現
次のセクションは、幾つかのＳＰａｔｈ表現と、上述したサンプルデータに基づいて予想される値とを示す。
次の表現は、ａｃｃｏｕｎｔ  ｋｅｙｒｅｆに対するｎｏｄｅｓｅｔ（ノードのリスト）を返送する。
$root.@@accounts.*
<account id=”a1” owner=”bob” contacts=”c1 c2” notes=”n1” events=”e1” tasks=”t1”>
<name>Acme</name>
<type>Direct</type>
</account>
<account id=”a2” owner=”bob” contacts=”c3”>
<name>Bancroft</name>
<type>Web</type>
</account>
【０６６４】
次の表現は、全ａｃｃｏｕｎｔノードに対する１組のネームエレメントを返送する。
$root.@@accounts.*.name
Acme
Bancroft
【０６６５】
次の表現は、全てのアカウント命名Ａｃｍｅに対する全てのコンタクトを返送する。
$root.@@accounts.*.where(name == ”Acme”).@@contacts.*
<contact id=”c1” owner=”bob” events=”e2” tasks=”t2”>
<salutation>Mr</salutation>
<first>Roger</first>
<last>Reed</last>
<email>roger@acme.com</email>
</contact>
<contact id=”c2” owner=”bob” notes=”n2”>
<salutation>Ms</salutation>
<first>Sarah</first>
<last>Smith</last>
<email>sarah@acme.com</email>
</contact>
【０６６６】
次の表現は、全てのコンタクト（全てのアカウントに対する）を指定のｅメールアドレスと共に返送する。
var $contactX = $root.@@accounts.*.@@contacts where(email == ”sarah@acme.com”)
<contact id=”c2” owner=”bob” events=”e2” tasks=”t2”>
<salutation>Ms</salutation>
<first>Sarah</first>
<last>Smith</last>
<email>sarah@acme.com</email>
</contact>
【０６６７】
次の表現は、＄ｃｏｎｔａｃｔＸノード内の＜ｓａｌｕｔａｔｉｏｎ＞エレメントに対する値をセットする。
$contactX.salutation = ”Mrs”
<contact id=”c2” owner=”bob” events=”e2” tasks=”t2”>
<salutation>Mrs</salutation>
<first>Sarah</first>
<last>Smith</last>
<email>sarah@acme.com</email>
</contact>
【０６６８】
次の表現は、指定のアカウントに対する新たなコンタクトを生成する。これは、システム変数を使用して、ｏｗｎｅｒ属性をセットすることに注意されたい。
$accountX.@@contacts.create(
<contact ownerId=”$globalApp.user”>
<salutation>Dr</salutation>
<first>David</first>
<last>Daniels</last>
<email>david@acme.com</email>
</contact>
);
【０６６９】
次の表現は、指定のコンタクトに対する新たなタスクを生成し、これは、次いで、ａｓｓｉｇｎｅｄ  ｋｅｙｒｅｆを変更する。
var $newTask = <task>
<title>Perpare RFP</title>
<status>Not started</status>
</task>
$contactX.@@tasks.create($newTask);
$newTask.@@assigned = $root.@@users.*.where(.username == ”fred”);
【０６７０】
ＣＲＭ使用ケースウェブサービス定義
このセクションは、例示的ＣＲＭウェブサービスに対するＷＳＤＬ（ワークショップにより発生された）の部分を示す。
<?xml version=”1.0” encoding=”utf-8”?>
<definitions xmlns=”http://schemas.xmlsoap.org/wsdl/” 
xmlns:conv=”http://www.openuri.org/2002/04/soap/conversation/” 
xmlns:cw=”http://www.openuri.org/2002/04/wsdl/conversation/” 
xmlns:http=”http://schemas.xmlsoap.org/wsdl/http/” 
xmlns:jms=”http://www.openuri.org/2002/04/wsdl/jms/” 
xmlns:mime=”http://schemas.xmlsoap.org/wsdl/mime/” 
xmlns:s=”http://www.w3.org/2001/XMLSchema”
xmlns:s0=”http://www.openuri.org/” 
xmlns:soap=”http://schemas.xmlsoap.org/wsdl/soap/” 
xmlns:soapenc=”http://schemas.xmlsoap.org/soap/encoding/” 
targetNamespace=”http://www.openuri.org/”>
...
【０６７１】
タイプの定義
ＷＳＤＬは、２種類のタイプ定義、即ちメッセージパラメータに対する入力及び出力タイプ定義と、フィールドタイプ定義（個々の複雑なタイプに対する）とを含む。
＜ｔｙｐｅｓ＞セクションは、オペレーション入力及び出力タイプと、オペレーションパラメータとして通された複雑なエレメントとに対するスキーマ定義を含む。
次のタイプ定義は、ｇｅｔＡｃｃｏｕｎｔｓＢｙＵｓｅｒウェブサービスオペレーションに対する入力（ｇｅｔＡｃｃｏｕｎｔｓＢｙＵｓｅｒ）及び出力（ｇｅｔＡｃｃｏｕｎｔｓＢｙＵｓｅｒＲｅｓｐｏｎｓｅ）メッセージタイプに関する。
<types>
<s:schema xmlns:s=”http://www.w3.org/2001/XMLSchema” 
mlns:ope=”http://www.openuri.org/” elementFormDefault=”qualified” 
trgetNamespace=”http://www.openuri.org/”>
<s:element name=”getAccountsByUser”>
<s:complexType>
<s:sequence> 
<s:element name=”userId” type=”s:string” minOccurs=”0”/> 
</s:sequence>
</s:complexType>
</s:element>
<s:element name=”getAccountsByUserResponse”>
<s:complexType>
<s:sequence>
<s:element name=”getAccountsByUserResult” type=”ope:ArrayOfAccount” 
minOccurs=”0”/> 
</s:sequence>
</s:complexType>
</s:element>
【０６７２】
次のタイプ定義は、上述した入力／出力オペレーションで参照されたパラメータに対する複雑なタイプを定義する。
<s:complexType name=”ArrayOfAccount”>
<s:sequence>
<s:element name=”Account” type=”ope:Account” nillable=”true”
minOccurs=”0” maxOccurs=”unbounded”/> 
</s:sequence>
</s:complexType>
<s:element name=”Account” nillable=”true” type=”ope:Account”/> 
<s:complexType name=”Account”>
<s:sequence>
<s:element name=”id” type=”s:string”/>
<s:element name=”timestamp” type=”s:string”/>
<s:element name=”name” type=”s:string” minOccurs=”0”/>
<s:element name=”type” type=”s:string” minOccurs=”0”/>
<s:element name=”ownerId” type=”s:string” minOccurs=”0”/>
</s:sequence>
</s:complexType>
</s:schema>
【０６７３】
次のタイプ定義は、全て、ｇｅｔＣｏｎｔａｃｔｓＢｙＡｃｃｏｕｎｔ及びａｄｄＣｏｎｔａｃｔＴｏＡｃｃｏｕｎｔウェブサービスオペレーションに関する。
<s:element name=”getContactsByAccount”>
<s:complexType>
<s:sequence> 
<s:element name=”accountId” type=”s:string” minOccurs=”0”/> 
</s:sequence>
</s:complexType>
</s:element>
<s:element name=”getContactsByAccountResponse”>
<s:complexType>
<s:sequence>
<s:element name=”getContactsByAccountResult” type=”ope:ArrayOfContact”
minOccurs=”0”/> 
</s:sequence>
</s:complexType>
</s:element>
<s:element name=”addContactToAccount”>
<s:complexType>
<s:sequence> 
<s:element name=”accountId” type=”s:string” minOccurs=”0”/> 
<s:element name=”contact” type=”ope:Contact” minOccurs=”0”/>
</s:sequence>
</s:complexType>
</s:element>
<s:element name=”addContactToAccountResponse”>
<s:complexType>
<s:sequence>
<s:element name=”addContactToAccountResult” type=”s:string”
minOccurs=”0”/> 
</s:sequence>
</s:complexType>
</s:element>
<s:complexType name=”ArrayOfContact”>
<s:sequence>
<s:element name=”Contact” type=”ope:Contact” nillable=”true”
minOccurs=”0” maxOccurs=”unbounded”/> 
</s:sequence>
</s:complexType>
<s:element name=”Contact” nillable=”true” type=”ope:Contact”/>
<s:complexType name=”Contact”>
<s:sequence>
<s:element name=”id” type=”s:string”/>
<s:element name=”timestamp” type=”s:string”/>
<s:element name=”first” type=”s:string” minOccurs=”0”/>
<s:element name=”last” type=”s:string” minOccurs=”0”/>
<s:element name=”email” type=”s:string” minOccurs=”0”/>
</s:sequence>
</s:complexType>
</s:schema>
</types>
【０６７４】
メッセージ定義
各ウェブサービスオペレーションは、入力及び出力のタイプを定義する一対のメッセージを定義する。
<message name=”getAccountsByUserSoapIn”>
<part name=”parameters” element=”s0:getAccountsByUser”/> 
</message>
<message name=”getAccountsByUserSoapOut”>
<part name=”parameters” element=”s0:getAccountsByUserResponse”/> 
</message>
【０６７５】
ＰｏｒｔＴｙｐｅ、バインディング及びサービス定義
コンジットは、ｐｏｒｔＴｙｐｅ定義と構造的に同様であり、ｐｏｒｔＴｙｐｅオペレーションは、コンジットオペレーションへマップされ、入力及び出力エレメントは、ｔｒａｎｓｆｏｒｍＯｕｔ及びｔｒａｎｓｆｏｒｍＩｎのＸＱｕｅｒｙ宣言に対応する。
<portType name=”CRMSoap”>
<operation name=”getAccountsByUser”>
<input message=”s0:getAccountsByUserSoapIn”/> 
<output message=”s0:getAccountsByUserSoapOut”/> 
</operation>
...
</portType>
<binding name=”CRMSoap” type=”s0:CRMSoap”>
<soap:binding transport=”http://schemas.xmlsoap.org/soap/http” style=”document”/>
<operation name=”getAccountsByUser”>
<soap:operation soapAction=”http://www.openuri.org/getAccountsByUser” 
style=”document”/> 
<input>
<soap:body use=”literal”/> 
</input>
<output>
<soap:body use=”literal”/> 
</output>
</operation>
...
</binding>
<service name=”CRM”>
<port name=”CRMSoap” binding=”s0:CRMSoap”>
<soap:address location=”http://BISHAMON:7001/CRMWeb/CRM.jws”/> 
</port>
</service>
【０６７６】
ＳａｌｅｓＦｏｒｃｅコンジット定義
次のコンジットファイルは、ＳａｌｅｓＦｏｒｃｅ．ｃｏｍウェブサービスと接続するコンジットの一部分を実施する。
/**
* @mas:stateful shared=”false”
* @common:xmlns namespace=”http://schemas.xmlsoap.org/soap/envelope/” prefix=”soap”
* @common:xmlns namespace=”urn:partner.soap.sforce.com” prefix=”sfdc”
* @common:xmlns namespace=”http://example.com/” prefix=”app”
*/
/**
* @common:control
* @jc:location http-url=”http://enterprise.soap.sforce.com/”
*/
ws = new WebServiceControl();
// session object returned from web service
var sessionId = null;
// create and send login message and process results 
function login() {
var body =
<login>
<username>{$user.username}</username>
<password>{$user.password}</password>
</login>;
var response = ws.invoke(body);
// set session id
sessionId = string(response.body.sfdc:result.sfdc:sessionId);
// set URL for subsequent calls (from this conduit)
ws.endPoint = string(response.body.sfdc:result.sfdc:serverUrl);
}
// create conversational header
function createHeader() {
if (sessionId == null) {
login();
}
return
<SessionHeader>
<sessiondId>{sessionId}</sessiondId>
</SessionHeader>;
}
/**
* select contacts for an account: $account.@@contacts.*
* @mas:operation type=”select” keyref=”app:contactAccountRef” inverse=”true”
* @mas:transform type=”request” function=”selectContacts_request”
* @mas:transform type=”response” function=”selectContacts_response”
*/
function selectContacts($msg, $source) {
$msg.header += createHeader();
return ws.invoke($msg);
}
/**
* @mas:namespace target=”sfdc”
* @mas:field xpath=”@id”
* @language:body type=”xquery”
*/
function selectContacts_request($source) {
<query>
<queryString>
SELECT * FROM Contact
WHERE AccountId = ”{string($source/@id)}”
</queryString>
</query>
}
/**
* @mas:namespace target=”app”
* @language:body type=”xquery”
*/
function selectContacts_response($response) {
for $i in $response/sfdc:queryResponse/sfdc:result/sfdc:records
return
<contact id=”{string($i/sfdc:Id)}” accountId=”{string($i/sfdc:AccountId)}”>
<modified>{string($i/sfdc:SystemModstamp)}</modified>
<fist>{string($i/sfdc:FistName)}</first>
<last>{string($i/sfdc:LastName)}</last>
<email>{string($i/sfdc:Email)}</email>
</contact>
}
/**
* insert contact: $root.create(<contact>...</contact>);
* @mas:operation type=”insert” node=”app:contact” 
* @mas:transform type=”request” function=”insertContact_request”
* @mas:transform type=”response” function=”insertContact_response”
*/
function insertContact($msg, $node) {
$msg.header += createHeader();
var response = ws.invoke($msg);
var id = response.sfdc:createResponse.sfdc:result.sfdc:Id;
// retrieve sequence number
var $msg2 = createMessage(
<query>
<queryString>
SELECT SystemModstamp FROM Contact
WHERE Id = ”{id}”
</queryString>
</query>
);
$msg2.header += createHeader();
var response2 = ws.invoke($msg2);
// return both responses
response.body += response2.body.sfdc:queryResponse;
return response;
}
/**
* @mas:namespace target=”sfdc”
* @language:body type=”xquery”
*/
function insertContact_request($node) {
<create>
<sObjects xsi:type=”Contact”>
<AccountId>{string($node/app:@accountId})</AccountId>
<FirstName>{string($node/app:first})</FistName>
<LastName>{string($node/app:last})</LastName>
<Email>{string($node/app:email)}</Email>
</sObjects>
</create>
}
/**
* @mas:namespace target=”app”
* @language:body type=”xquery”
*/
function insertContact_response($response) {
<contact id=”{string($response/sfdc:createResponse/sfdc:result/sfdc:Id)}”>
<modified>
{string($response/sfdc:queryResponse/sfdc:records/sfdc:SystemModstamp)}
</modified>
</contact>
}
【０６７７】
一実施形態において、随時接続アプリケーションサーバーは、サーバーバスと対話することができる。一実施形態において、サービスバスト(bust)は、ウェブサーバーのように作用する。
サービスバスは、多数の位置からの情報を得るプロキシーである。サービスバスは、
−エンベローププロトコル、トランスポートプロトコル、セキュリティ機構、ペイロードコンテンツ、一方向及び要求／応答パラダイム、同期及び非同期通信、並びにポイント対ポイント及びｐｕｂ／ｓｕｂのエリアにおいて送信者が送信しそして受信者が期待するメッセージ間のギャップを橋絡し、
−多行先パブリッシュ、コンテンツベースのルーティング、認証及び許可、並びに証明書マッピングのようなタスクを実行するために媒介物に付加的な計算能力を設け、
−メトリック収集及び表示、警告表示、追跡事象収集及び使用、メッセージアーカイブ及びＳＬＡマネージメントと共に媒介物にモニタリング能力を設ける。
【０６７８】
サービスバスは、媒介物である。サービスバスへのメッセージは、トランスポートを経て到来し、それをどこへルーティングするか決定するために処理し、そしてメッセージエンリッチメントのために変換する。次いで、再びトランスポートを経て退出する。応答は、逆の経路をたどることができる。メッセージが通過するときに１組の関心のあるリスナーへメッセージのコピーをパブリッシュすることができる。媒介物によるメッセージ処理は、コンソールを経て使用されるメタデータにより駆動することができる。
【０６７９】
サービスバスは、ＷｅｂＬｏｇｉｃマネージサービスのクラスター化をサポートすることができる。コンフィギュレーション及びメタデータは、高速ローカル検索のためにマネージサーバーへ自動的に伝播される。モニタリングメトリックは、コンソールに集計して表示するために全てのマネージサーバーから自動的に収集することができる。
媒介物（プロキシーサービス）及び媒介物により呼び出される外部サービスは、両方とも、サービスとしてモデリングすることができる。
【０６８０】
サービスは、次のものをもつことができる。
−トランスポートアドレス及び関連コンフィギュレーションを各々もつポーと称される（エンドポイントとも称される）１組の具体的なインターフェイス。１組のポートは、サービスに対する負荷バランス及びフェイルオーバー代替物を構成し、そして特性が同一である。
−単一の任意の抽象的インターフェイス（類似は、ｊａｖａインターフェイス）であって、オペレーション（類似は、パラメータを伴うｊａｖａインターフェイスのメソッド）によりおそらくブレークダウンされたインターフェイスにおいてメッセージ部分の構造を定義したもの。
−具体的なメッセージに対する抽象的インターフェイスのメッセージ部分のパッケージングを定義する単一のバインディング、及びトランスポートに対するそのメッセージのバインディング。
−ＷＳセキュリティ（ＷＳＳ）及びＷＳ信頼性メッセージング（ＷＳ−ＲＭ）に対するポリシー、許可ポリシー、及びバインディングレイヤー（ロギングのような）により透過的に実行する必要のあるアクション。
【０６８１】
ＨＴＴＰ（Ｓ）又はＪＭＳトランスポートに基づく標準的なＳＯＡＰウェブサービスの場合には、抽象的インターフェイス、具体的インターフェイス及びバインディングのＷＳＤＬ表示が可能である。ＷＳＤＬリソース又は退出サービスを使用して、新たなサービスのインターフェイスの定義をジャンプスタート(ｊｕｍｐｓｔａｒｔ)することができる。
【０６８２】
サービスバスは、ＪＭＳ（ＢＥＡ及び外部ＪＭＳプロバイダーのための）、ＨＴＴＰ（Ｓ）、ｅメール、ファイル、ＷＳ−ＲＭ及びＦＴＰをサービストランスポートとしてサポートすることができる。サービスバスは、ＨＴＴＰ及びＪＭＳ非同期トランスポートに対して要求／応答及び一方向パラダイムの両方をサポートすることができる。又、任意であるが、メッセージの順序付けされた配送も、基礎的なトランスポートがこれをサポートする場合には、サポートできる。サービスバスは、ＸＭＬ、非ＸＭＬ（ＭＦＬと共に記述される構造）、バイナリー、アタッチメント（ｅメール）を伴うＭＩＭＥ、並びにＳＯＡＰ１．１及び１．２（ＲＰＣスタイル及び文書スタイルの両方に対してアタッチメントを伴うか又は伴わない）パッケージングをサポートすることができる。
【０６８３】
サービスは、同じバインディングに対して多数のポートをもつことができる。これらのポートは、負荷バランス及びフェイルオーバー代替物として使用することができる。サービスは、そのポートに対して使用するための負荷バランスポリシーを定義することができる。サポートされるポリシーは、ラウンドロビン及びランダム（重み付けされたもの又はされないもの）である。ポートは、負荷バランス行先として働くだけでなく、フェイル時にはフェイルオーバー代替物としても働く。２つのコンセプトは、ＨＡ負荷バランス機構に対して一緒に結合される。
【０６８４】
又、サービスは、フェイル時の再試みポリシー及び（要求／応答に対する）時間切れポリシーを定義することもできる。
サービスは、そのインターフェイスにおいてメッセージに適用するセキュリティポリシーを定義することができる。これは、サービスレベル（全てのメッセージに適用する）において指定することもできるし、又はサービスのオペレーションに対して個々にメッセージにおいて指定することもできる。
【０６８５】
サービスは、カテゴリーに分けることができる。カテゴリー機構を定義することができる。カテゴリーは、本質的にキーネームであり、そしてカテゴリー値は、キーネームに対する値である。サービスは、多数のカテゴリーネームに対して多数の値をもつことができる。カテゴリーは、発見目的に非常に有用である。キーネームと、値の許容ハイアラーキーとを定義する多数の標準的な存在論（又はカテゴリー機構）がある。サービスバスは、サービスをカテゴリー分けするためにハイアラーキーにおいてリーフ（葉）値の使用しか許さない。
【０６８６】
サービスプロバイダーと称される組織又はアプリケーションにより１組のサービスを提供することができる。サービスのプロバイダーを定義することは任意であり、スタンドアローンサービスを得ることができる。これらは、エンタープライズにおける内部サブ組織でもよいし、外部パートナー組織でもよいし、又は個々のアプリケーションでもよい（セマンティックでは、ユーザまで）。又、サービスプロバイダーは、サーチのためのサービスのようにカテゴリー分けすることもできる。サービスプロバイダーは、証明書が関連付けられ、そしてユーザに結び付けることができ、従って、許可のための役割に属することができる。サービスプロバイダーは、メッセージを送信及び受信することができる。
【０６８７】
サービス消費者は、組織又はアプリケーションであって、メッセージを送信する（又は同期応答を受信する）ことしかできない。又、サービスプロバイダーは、サーチのためのサービスのようにカテゴリー分けできる。サービス消費者は、証明書が関連付けられ、そしてユーザに結び付けられ、従って、許可のための役割に属することができる。
【０６８８】
プロキシーサービスの実施は、パイプライン定義によって指定することができる。これは、要求パイプライン定義と、応答パイプライン定義とで構成される。パイプラインは、外部（又は別のプロキシー）サービスを呼び出す前にプロキシーサービスへの要求メッセージにおいてどんなアクションが実行されるか、及びプロキシーが応答を返送する前にプロキシーにより呼び出されたサービスからの応答においてどんな処理が実行されるか指定する。
【０６８９】
各パイプラインは、一連のステージである。パイプラインに供給されたメッセージは、パイプラインステージによりアクセス又は変更できる１組のメッセージコンテクスト変数（メッセージコンテクストを含む変数を含む）を付随することができる。
【０６９０】
パイプラインにおけるメインステージは、次の通りである。
−変換ステージは、構造をネスト状にすべき場合に、コンテクストに影響する実行されるべき変換を選択するのを許す。ウェブサービスコールアウト又はＤＢルックアップは、Ｘｑｕｅｒｙ又はＸＳＬＴ変換に対する代替物で、出力コンテクスト変数をセットするためのものである。
−ルーティングステージ（要求パイプラインにおいてのみ許された）は、構造及びケース構造を合成（及びネスト状に）すべき場合に、メッセージをルーティングする単一エンドポイント及びオペレーションを定義するのを許す。メッセージを各エンドポイントへパブリッシュする前に、コンテクスト変数に影響を及ぼす１組の変換を定義することができる。ウェブサービスコールアウト又はＤＢルックアップは、Ｘｑｕｅｒｙ又はＸＳＬＴ変換に対する代替物で、コンテクスト変数をセットすることができる。
【０６９１】
−パブリッシュステージは、構造及びケース構造を合成（及びネスト状に）すべき場合に、メッセージをパブリッシュする１組のエンドポイント及びオペレーションを定義するのを許す。メッセージを各エンドポイントへパブリッシュする前に、コンテクスト変数に影響を及ぼす１組の変換を定義することができる。ウェブサービスコールアウト又はＤＢルックアップは、Ｘｑｕｅｒｙ又はＸＳＬＴ変換に対する代替物で、コンテクスト変数をセットすることができる。コンテクストに対する変更は、パブリッシュされた各エンドポイントに対して分離され、パイプラインによるその後の処理に影響しない。
−ＷＳセキュリティ処理及び許可は、バインディングレイヤーにおいて透過的に実行される。
【０６９２】
−追跡ステージは、ユーザ定義情報と共に追跡レコードを書き込むのを許し、従って、追跡システムを使用して、ユーザ定義基準によるサーチを行うことができる。
−アーカイブステージは、経歴及び記録保持の目的でメッセージをアーカイブに書き込む。
−ロギングステージは、デバッギングの目的で選択されたコンテクストをシステムログへロギングするのを許す。
−検証ステージは、ＭＦＬスキーマのＸＭＬに対して文書を検証する。
−カスタムステージは、ユーザが、ステージＳＤＫを使用してステージを実施する状態でそれ自身のアクションを定義するのを許す。
【０６９３】
各パイプラインは、一連のステージで構成することができる。しかしながら、単一サービスレベル要求パイプラインは、任意であるが、オペレーションパイプラインへと分岐されてもよい（オペレーション当たりせいぜい１つ、そして任意であるが、デフォールトオペレーションパイプライン）。メッセージコンテンツからオペレーションを決定する標準的な方法はないので、オペレーションの決定は、ユーザ選択基準を通して行われる。応答処理は、当該オペレーションパイプラインでスタートし、このパイプラインは、次いで、単一サービスレベル応答パイプラインに参加する。
【０６９４】
コンテクストは、要求パイプライン及び応答パイプラインの両方にわたって共有することができ、そしてその値は、個々の要求／応答メッセージに関連付けされる。コンテクストは、１組の予め定義されたＸＭＬ変数である。新たな変数をコンテクストに動的に追加したり削除したりすることができる。予め定義されたコンテクスト変数は、メッセージに関する情報、トランスポートヘッダ、セキュリティプリンシパル、現在プロキシーサービスに対するメタデータ、並びにプロキシーサービスにより呼び出された一次ルーティング及びサブスクリプションサービスに対するメタデータを有する。コンテクストは、ステージによるＸｑｕｅｒｙ／Ｘｕｐｄａｔｅ表現により読み取り及び変更することができる。
【０６９５】
コンテクストのコアは、変数＄ｈｅａｄｅｒ、＄ｂｏｄｙ及び＄ａｔｔａｃｈｍｅｎｔｓである。これらは、ＳＯＡＰヘッダー、ＳＯＡＰ本体コンテンツ、及びＭＩＭＥアタッチメントを各々含むラッパー変数である。コンテクストは、全てのメッセージがＳＯＡＰメッセージであり且つ非ＳＯＡＰメッセージがこのパラダイムにマップされるという印象を与える。バイナリー又はＭＦＬデータの場合には、＄ａｔｔａｃｈｍｅｎｔ又は＄ｂｏｄｙにおける文書を表わすＸＭＬエレメントが独特の識別子内の実際の文書を参照する。ＳＯＡＰ  ＲＰＣの場合には、本体コンテンツは、それ自体、タイプされたＲＰＣパラメータを含むラッパーエレメントである。
【０６９６】
サービスバスは、設計時に望まれる場合に使用することのできる内蔵のタイプシステムを有することができる。設計時の条件又は変換においてＸｑｕｅｒｙ表現を生成するときには、Ｘｑｕｅｒｙを容易に生成する助けとしてエディタにおいて１つ以上のタイプについて変数を宣言することができる。タイプは、ＸＭＬスキーマ、ＭＦＬ又はＷＳＤＬリソースである。このタイプ宣言プロセスは、タイプされるべき変数の性質が分かる（タイプのエレメント又はタイプそれ自体に対するラッパーである）。又、これは、＄ｂｏｄｙにおいてＳＯＡＰ  ＲＰＣパラメータ又は文書に容易にアクセスするための助けも与える。
【０６９７】
各ステージは、そのステージにエラーが発生した場合に実行するための一連のステップを有することができる。この一連のステップは、そのステージに対するエラーパイプラインを構成する。更に、エラーパイプラインは、全パイプライン又は全プロキシーサービスに対して定義することもできる。存在する最も低い範囲のエラーパイプラインは、エラーの際に呼び出される。このエラーパイプラインは、メッセージをエンドポイントへパブリッシュするのを許し、プロキシーの呼び出し者へ返送されるべきエラー応答メッセージを作り上げ、メッセージをログし、コンテンツを変更した後に継続し、又は例外を生じさせる。例外を生じさせると、次に高い範囲のエラーパイプラインへコントロールが移管される。
【０６９８】
要求パイプラインの処理は、インバウンドトランスポート処理、インバウンドバインディングレイヤー、パイプライン実行、アウトバウンドバインディングレイヤー、及びアウトバウンドトランスポート処理ステップで構成することができる。バインディングレイヤーは、メッセージをコンテクスト変数へ／コンテクスト変数からマッピングし、メッセージをパッケージング及びアンパッケージングし、そしてＷＳＳセキュリティ及び許可を行うといった実行されるべき処理の幾つかを自動化する。一次ルーティング行先及びパブリッシュ行先の両方がこのパラダイムに続く。
【０６９９】
一次ルーティングエンドポイントが呼び出された後に、応答パイプライン処理は、同様のモデルをたどる。
あるステージからのウェブサービスコールアウトは、バインディングレイヤー及びそれに続くトランスポートレイヤーを通して進む。コールアウト応答は、逆の経路をたどる。
ユーザは、人間、組織又はアプリケーションのいずれでもよいセキュリティプリンシパルである。ユーザは、ＵＩインターフェイス（コンソールユーザ）、又はメッセージングインターフェイス（サービス消費者又はプロバイダーとしてモデリングされたユーザ）のいずれを呼び出すこともできる。
【０７００】
サービスバスリソースは、エンティティの再使用可能な共通の定義又は記述で、通常、そのエンティティに対するメタデータである。リソースは、多数のサービスにより使用することができ、そしてエンタープライズ又はデパートメントにわたって標準化された定義又は記述である。リソースは、例えば、カテゴリー機構、ＭＦＬスキーマ、ＸＳＤスキーマ、Ｘｑｕｅｒｙマップ、ＸＳＴＬマップ、ＷＳＤＬインターフェイス、及びＷＳポリシーファイルである。
【０７０１】
カテゴリー機構は、単一カテゴリーネームと、そのカテゴリーネームに対する値のハイアラーキーセットとを定義することができる。サービス、プロバイダー及び消費者は、登録された機構を使用してカテゴリー分けすることができる。それらは、カテゴリー機構に対する多数のリーフ値、又は多数のカテゴリー機構からのリーフ値でカテゴリー分けすることができる。
【０７０２】
スキーマは、プリミティブ又は構造化データに対するタイプを記述することができる。ＭＦＬスキーマは、非ＸＭＬデータに対するタイプを記述する。ＸＭＬスキーマは、ＸＭＬに対するタイプを記述する。ＸＭＬスキーマタイプは、他のスキーマファイルをインポートし又はそれを含むことができる。
【０７０３】
変換マップは、２つのタイプ間のマッピングを記述することができる。ＸＳＬＴマップは、ＸＳＬＴ規格を使用してＸＭＬデータに対するマッピングを記述する。Ｘｑｕｅｒｙマップは、Ｘｑｕｅｒｙ規格を使用してＸＭＬ及び非ＸＭＬ（ＭＦＬ）データに対するマッピングを記述する。
【０７０４】
ＷＳＤＬインターフェイスは、サービスインターフェイスに対するテンプレートであり、そのインターフェイスにおけるオペレーションを含むサービスの抽象的インターフェイスと、オペレーションシグネチャーにおけるメッセージ部分のタイプとを記述する。又、任意であるが、メッセージ（パッケージング）に対するメッセージ部分のバインディングと、トランスポートに対するメッセージのバインディングも記述する。又、任意であるが、サービスの具体的なインターフェイスも記述する。
【０７０５】
ＷＳポリシーは、セキュリティ及び信頼性のあるメッセージングポリシーを記述することができる。これは、どんなアルゴリズムを使用してメッセージに何をサインし又は暗号化すべきか記述することができる。又、受信時にメッセージに対してどんな認証メカニズムを使用すべきか記述することができる。
【０７０６】
一実施形態において、随時接続アプリケーションサーバープラットホームは、既存のエンタープライズコンポーネントと一体化される簡単なウェブ状のプログラミングモデルで、精巧な移動ソルーションを開発し、配備しそしてマネージするフレームワークを提供する。
【０７０７】
移動アプリケーションは、データモデル定義と、ユーザインターフェイステンプレートと、アクションを定義するスクリプトを含むクライアント側コントローラと、そしてサーバー側では、データモデルとエンタープライズとの間をいかに仲裁するか記述できるコンジットの集合とで構成することができる。随時接続アプリケーションサーバーは、移動アプリケーションにより使用される全てのデータが外部システムにより持続的に記憶されそしてマネージされると仮定できる。データモデルは、このデータについての移動アプリケーションの予想される使用のメタデータ記述であると共に、随時接続装置と外部システムとの間でのこのデータの効率的なトラバース及び同期を可能にするように最適化することができる。
【０７０８】
随時接続データモデルは、持続的アプリケーションデータの構造（及び他のプロパティ）を記述することができる。モデルそれ自体は、移動ブラウザと同期させることができ、従って、クライアントは、インテリジェントにデータをトラバースすると共に、データをサーバーと同期させることができる。
【０７０９】
本発明の他の特徴、態様及び目的は、添付図面及び特許請求の範囲から得ることができる。本発明の精神及び範囲内、そして特許請求の範囲内で、本発明の他の実施形態も開発できることを理解されたい。
【０７１０】
本発明の好ましい実施形態の以上の説明は、単なる例示に過ぎない。これは、本発明を余すところなく示すものでもないし、又、ここに開示した正確な形態に制限するものでもない。当業者であれば、多数の変更や修正が明らかであろう。これら実施形態は、本発明の原理及びその実際の応用を説明するために選ばれたものであり、従って、当業者であれば、本発明、種々の実施形態、並びに意図された特定の用途に適する種々の変更を理解することができよう。従って、本発明の範囲は、特許請求の範囲によって限定されるものとする。
【０７１１】
特別に設計された集積回路又は他の電子装置で構成される実施形態に加えて、本発明は、コンピュータ分野の当業者に明らかなように、本開示の教示に基づいてプログラムされた従来の汎用又は特殊なデジタルコンピュータ又はマイクロプロセッサを使用して便利に実施することができる。
【０７１２】
ソフトウェア分野の当業者に明らかなように、熟練したプログラマーであれば、本開示の教示に基づき適切なソフトウェアコードを容易に準備することができよう。又、本発明は、当業者に容易に明らかなように、特定用途向け集積回路を準備するか、又は従来のコンポーネント回路の適切なネットワークを相互接続することにより、実施されてもよい。
【０７１３】
本発明は、本発明のプロセスを実行するようにコンピュータをプログラムするのに使用できる命令が記憶された記憶媒体（メディア）であるコンピュータプログラム製品を包含する。記憶媒体は、フロッピー（登録商標）ディスク、光学的ディスク、ＤＶＤ、ＣＤ−ＲＯＭ、マイクロドライブ、磁気−光学ディスクを含む任意のタイプのディスク、ＲＯＭ、ＲＡＭ、ＥＰＲＯＭ、ＥＥＰＲＯＭ、ＤＲＡＭ、ＶＲＡＭ、フラッシュメモリデバイス、磁気又は光学カード、ナノシステム（分子メモリ、ＩＣを含む）、或いは命令及び／又はデータを記憶するのに適した任意の形式のメディア又はデバイスを包含し得るが、これらに限定されない。
【０７１４】
コンピュータ読み取り可能な媒体（メディア）のいずれか１つに記憶されるものであるが、本開示は、汎用／特殊なコンピュータ又はマイクロプロセッサのハードウェアを制御すると共に、コンピュータ又はマイクロプロセッサが本発明の結果を利用して人間のユーザ又は他のメカニズムと対話できるようにするためのソフトウェアも包含する。このようなソフトウェアは、装置ドライバ、オペレーティングシステム、及びユーザアプリケーションを含むが、これらに限定されない。
【０７１５】
汎用／特殊なコンピュータ又はマイクロプロセッサのプログラミング（ソフトウェア）には、本発明の教示を実施するためのソフトウェアモデルであって、随時接続アプリケーションサーバーのためのシステム及び方法を備えた（これに限定されないが）ソフトウェアモジュールが含まれる。
【図面の簡単な説明】
【０７１６】
【図１Ａ】本発明の一実施形態に基づくアーキテクチャーの概要を示す図である。
【図１Ｂ】本発明の一実施形態に基づくアーキテクチャーの概要を示す図である。
【図２】本発明の一実施形態に基づく同期対話図である。
【図３】本発明の一実施形態に基づくＭＡＳアプリケーションのためのプログラミングモデルを示す図である。
【図４】本発明の一実施形態に基づくエンティティ関係図である。
【図５】本発明の一実施形態に基づくＵＭＬエンティティ関係図である。
【図６】本発明の一実施形態に基づくノードインスタンス図である。
【図７】本発明の一実施形態に基づくセレクト動作を示す図である。
【図８】本発明の一実施形態に基づく入力出力マトリクスを示す図である。
【図９】本発明の一実施形態に基づくＣＲＭスキーマタイプの図である。
【図１０】本発明の一実施形態に基づくＣＲＭアプリケーションの一部分に対するページフローを示す図である。
【図１１Ａ】本発明の一実施形態の同期方法を示す図である。
【図１１Ｂ】本発明の一実施形態の同期方法を示す図である。
【図１２Ａ】本発明の一実施形態のｋｅｙｒｅｆ定義を例示する図である。
【図１２Ｂ】本発明の一実施形態のｋｅｙｒｅｆ定義を例示する図である。
【図１２Ｃ】本発明の一実施形態のｋｅｙｒｅｆ定義を例示する図である。
【図１２Ｄ】本発明の一実施形態のｋｅｙｒｅｆ定義を例示する図である。
【図１Ａ】
2007524933.tif 000081
【図１Ｂ】
2007524933.tif 000082
【図２】
2007524933.tif 000083
【図３】
2007524933.tif 000084
【図４】
2007524933.tif 000085
【図５】
2007524933.tif 000086
【図６】
2007524933.tif 000087
【図７】
2007524933.tif 000088
【図８】
2007524933.tif 000089
【図９】
2007524933.tif 000090
【図１０】
2007524933.tif 000091
【図１１Ａ】
2007524933.tif 000092
【図１１Ｂ】
2007524933.tif 000093
【図１２Ａ】
2007524933.tif 000094
【図１２Ｂ】
2007524933.tif 000095
【図１２Ｃ】
2007524933.tif 000096
【図１２Ｄ】
2007524933.tif 000097