JP4551899B2 - 随時接続アプリケーションサーバー - Google Patents

随時接続アプリケーションサーバー Download PDF

Info

Publication number
JP4551899B2
JP4551899B2 JP2006542905A JP2006542905A JP4551899B2 JP 4551899 B2 JP4551899 B2 JP 4551899B2 JP 2006542905 A JP2006542905 A JP 2006542905A JP 2006542905 A JP2006542905 A JP 2006542905A JP 4551899 B2 JP4551899 B2 JP 4551899B2
Authority
JP
Japan
Prior art keywords
data
xsd
node
server
mas
Prior art date
Legal status (The legal status is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the status listed.)
Active
Application number
JP2006542905A
Other languages
English (en)
Other versions
JP2007524933A (ja
Inventor
アダム ボズワース
リチャード バードン
アレックス ケーシン
アレックス ロイド
ファロック エイチ エスカフィー
ケン オン
テリー ルーカス
アレクサンダー ボズワース
Current Assignee (The listed assignees may be inaccurate. Google has not performed a legal analysis and makes no representation or warranty as to the accuracy of the list.)
BEA Systems Inc
Original Assignee
BEA Systems Inc
Priority date (The priority date is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the date listed.)
Filing date
Publication date
Application filed by BEA Systems Inc filed Critical BEA Systems Inc
Publication of JP2007524933A publication Critical patent/JP2007524933A/ja
Application granted granted Critical
Publication of JP4551899B2 publication Critical patent/JP4551899B2/ja
Active legal-status Critical Current
Anticipated expiration legal-status Critical

Links

Images

Classifications

    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F16/00Information retrieval; Database structures therefor; File system structures therefor
    • G06F16/20Information retrieval; Database structures therefor; File system structures therefor of structured data, e.g. relational data
    • G06F16/27Replication, distribution or synchronisation of data between databases or within a distributed database system; Distributed database system architectures therefor
    • G06F16/273Asynchronous replication or reconciliation
    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F16/00Information retrieval; Database structures therefor; File system structures therefor
    • G06F16/20Information retrieval; Database structures therefor; File system structures therefor of structured data, e.g. relational data
    • G06F16/27Replication, distribution or synchronisation of data between databases or within a distributed database system; Distributed database system architectures therefor

Description

本発明は、一般に、移動(モバイル)アプリケーションアーキテクチャーに係り、より詳細には、随時接続移動装置のためのアプリケーションを開発し、配備し、そしてマネージするための移動アプリケーションアーキテクチャーに係る。
版権の警告:本特許文献の開示の一部分は、版権保護を受ける資料を含んでいる。版権所有者は、特許商標庁の特許ファイル又は記録に現われるように特許文献又は特許開示を誰かが複写再生することに異議を唱えるものではなく、全ての版権は何であれ保存されるものとする。
優先権の請求:2004年5月20日出願されたボスワース氏等の「MOBILEAPPLICATION SERVER」と題する米国プロビジョナル特許出願第60/573,077号[代理人ドケットNo.BEAS−01537US0];及び
2005年5月4日出願されたボスワース氏等の「OCCASIONALLY-CONNECTED APPLICATION SERVER」と題する米国特許出願第11/122,294号[代理人ドケットNo.BEAS−01537US1]
コンピュータ及びコンピューティング装置は、より小型で、より高速で且つより効率的なものとなった。その結果、それらの機能が進歩し、それらがより多くの情報を記憶及び処理できるようになった。しかしながら、装置が何をローカルに記憶して処理できるかについては、依然、制約がある。
最近、移動接続システムの開発で、ポータブル装置のためのより多くの機能が可能となった。これらの装置は、ラップトップコンピュータ、PDA、セルラー電話、ノートブックコンピュータ、ブラックベリー型装置、及び他の移動装置も含めて、強力な接続が存在するところであればどこでも、インターネットに接続することができる。これら装置のためのアプリケーションは、多数の形態で得られるが、ユーザは、アプリケーションの配備及びその後の変更が容易であることから、ウェブベースモデルを歴史的に好む。更に、ウェブベースページは、ユーザが使用するために非常に簡単で且つ直感的なものである。
移動装置のウェブブラウジングの最近の開発には多数の問題がある。ユーザがどこにいても接続を得ることが容易ではない。接続は、通常、標準的な電話接続を経て行われ、これは、セルラー電話の信号強度に依存する。現在、セルラー電話ネットワークには多数のデッドゾーンがあり、移動装置とウェブサーバーとの間の接続に休止時間を生じさせる。
これは、典型的なブラウザを通してウェブページコンテンツを与えるのに必要な対話について考えると、更に厄介なことになる。ユーザがウェブブラウザと対話するときに、ブラウザは、ユーザの入力に基づきサーバーからより多くの情報を要求する。これは、新たな情報を検索してユーザに与えるためにブラウザとウェブサーバーとの間にアクティブな接続を必要とする。従って、ユーザが移動装置のウェブブラウザと対話していて、信号強度の弱いエリア又はデッドゾーンに入ると、弱い接続(又は接続の欠如)のために、おそらく、移動装置により受け取られるコンテンツにエラーを生じさせる。従って、ユーザは、このようにウェブページと対話することがしばしばできなくなる。
そこで、直感的なユーザインターフェイスと、移動装置のユーザにコンテンツを与えるためのより信頼性のあるメカニズムとを与える移動アプリケーションアーキテクチャーフレームワークが要望される。又、このフレームワークは、既存のエンタープライズコンポーネントと一体化される簡単なウェブ状のプログラミングモデルを可能にしながら、精巧な移動ソルーション(解決策)を開発し、配備しそしてマネージもしなければならない。
一実施形態において、随時接続アプリケーションサーバープラットホームは、既存のエンタープライズコンポーネントと一体化される簡単なウェブ状のプログラミングモデルと共に、精巧な移動ソルーションを開発し、配備しそしてマネージするためのフレームワークを提供する。
随時接続アプリケーションは、データモデル定義と、ユーザインターフェイステンプレートと、アクションを定義するスクリプトを含むクライアント側コントローラと、そしてサーバー側では、データモデルとエンタープライズとの間をいかに仲裁するか記述できるコンジットの集合とで構成することができる。一実施形態では、随時接続アプリケーションサーバーは、随時接続アプリケーションにより使用される全てのデータがウェブサービスのような外部システムにより持続的に記憶されそしてマネージされると仮定する。データモデルは、このデータの接続−接続(connected-connected)アプリケーションの予想される使用のメタデータ記述であると共に、随時接続装置と外部システムとの間でのこのデータの効率的なトラバース及び同期を可能にするように最適化することができる。
随時接続データモデルは、持続的アプリケーションデータの構造(及び他のプロパティ)を記述することができる。随時接続データモデルそれ自体は、ブラウザと同期させることができ、従って、クライアントは、インテリジェントにデータをトラバースさせると共に、データをサーバーと同期させることができる。
一実施形態において、随時接続アプリケーションサーバープラットホームは、既存のエンタープライズコンポーネントと一体化される簡単なウェブ状のプログラミングモデルと共に、精巧な移動ソルーションを開発し、配備しそしてマネージするためのフレームワークを提供する。
接続−接続アプリケーションは、データモデル定義と、ユーザインターフェイステンプレートと、アクションを定義するスクリプトを含むクライアント側コントローラと、そしてサーバー側では、データモデルとエンタープライズとの間をいかに仲裁するか記述するコンジットの集合とで構成することができる。一実施形態では、随時接続アプリケーションサーバーは、移動アプリケーションにより使用される全てのデータが外部システムにより持続的に記憶されそしてマネージされると仮定する。データモデルは、このデータの移動アプリケーションの予想される使用のメタデータ記述であると共に、随時接続装置と外部システムとの間でのこのデータの効率的なトラバース及び同期を可能にするように最適化することができる。
随時接続データモデルは、全ての持続的アプリケーションデータの構造(及び他のプロパティ)を記述することができる。モデルそれ自体は、移動ブラウザと同期させることができ、従って、クライアントは、インテリジェントにデータをトラバースさせると共に、データをサーバーと同期させることができる。
随時接続データモデルは、クライアントにおいてキャッシュ記憶及び同期されるデータ、及び任意であるが、サーバーにおいてキャッシュ記憶されるデータを記述することができる。多くのプログラミングモデルがメタデータにより記述され、これは、配備されたアプリケーションに勝る高レベルの制御をアドミニストレータ及びエンドユーザに与える。
一実施形態において、プログラミングモデルは、カリフォルニア州サンノセのBEAシステムズのWebLogicワークショップ内で完全にサポートすることができ、これは、ワークショップの視覚設計ツールを及びラウンドトリップ開発モデルを使用し、そしてデベロッパがLiquidData及びインテグレーションのような他のWebLogicプラットホームコンポーネントをレバレッジできるようにする。
移動ソルーションの構築は、ワークショップウェブアプリケーションの構築と同程度に容易であり、特殊な移動チームを必要としない。この目標は、開発、配備、維持から、毎日の使用に至るまでの所有者の多大なトータルコストを伴う多大な移動経験である。
図1A−Bは、一実施形態の全体的システムアーキテクチャー100を示し、これは、移動ブラウザ110、随時接続アプリケーションサーバー120、及び外部ウェブサービス140を備えている。
随時接続アプリケーションサーバー120(OCAS)、例えば、移動アプリケーションサーバー(MAS)は、移動ブラウザにおいて実行されるクライアントアプリケーションと、ウェブサーバーを経てアクセスされる外部システムとの間でのデータの交換を仲裁することができる。このメカニズムは、2つのステージをもつことができ、即ち第1に、OCAS120は、外部システムと、随時接続データモデルとの間のデータの変換を整合することができ、そして第2に、OCAS120は、クライアントキャッシュと外部ウェブサービスとの間の同期を整合することができる。
本発明の一実施形態は、移動クライアント111のための随時接続アプリケーションサーバー120である。この随時接続アプリケーションサーバー120は、随時接続データモデル127、例えば、移動データモデルを記憶するためのメモリと、この随時接続データモデル127により定義されるデータノードを記憶するためのキャッシュ128とを含むことができる。随時接続アプリケーションサーバー120は、随時接続データモデルのメタデータにより指示されるキャッシュ128にデータノードをキャッシュ記憶することができる。
随時接続アプリケーションサーバー120は、1つ以上のマシンで実行されるソフトウェアである。又、随時接続アプリケーションサーバー120は、アプリケーションサーバーの最上部で実行することもできるし又はその一部分であってもよい。随時接続クライアント111は、パーソナルデジタルアシスタント(PDA)、電話、ノートブックコンピュータ、又は他の移動コンピューティング装置である。又、クライアントは、特にサーバーと間欠的にコンタクトする固定コンピュータを含むこともできる。
随時接続アプリケーションサーバー120は、ウェブサービス140のような外部システムと、随時接続データモデル127により定義されるデータノードとの間でデータを変換することができる。
本発明の一実施形態は、随時接続アプリケーションサーバー120を含むシステムである。随時接続アプリケーションサーバー120は、クライアントにアプリケーションを与えるように構成できる。アプリケーションは、クライアントが、随時接続アプリケーションサーバーへの現在アクセスを必要とせずに、アプリケーションデータを読み取って更新するのを許すことができる。随時接続アプリケーションサーバー120は、クライアントへ送信するために外部システムからアプリケーションデータを得るように適応され得る。又、随時接続アプリケーションサーバーは、外部システムからデータノードへデータを変換するように適用され得る。外部システムは、サービスバス、ウェブサービス、又は何らかの他のシステムである。
随時接続データモデル127は、外部データについての移動クライアントの予想される使用を指示し、そして移動クライアント111により外部データが要求される前にそれを得ることができる。
データノードは、XMLデータのようなデータの独立したチャンクである。移動データモデル127は、データノードに対して、XMLスキーマ又はXML DTDのようなXML定義を含むことができる。
本発明の一実施形態は、随時接続アプリケーションサーバー120を含むシステムである。随時接続アプリケーションサーバー120は、クライアントにアプリケーションを与えるように構成できる。アプリケーションは、クライアントが、随時接続アプリケーションサーバーへの現在アクセスを必要とせずに、アプリケーションデータを読み取って更新するのを許すことができる。随時接続アプリケーションサーバー120は、クライアントへ送信するために外部システムからアプリケーションデータを得るように適応され得る。又、随時接続アプリケーションサーバーは、外部システムからデータノードへデータを変換するように適用され得る。外部システムは、サービスバス、ウェブサービス、又は何らかの他のシステムである。
移動クライアント111は、データノード及び随時接続データモデル115を転送して、移動クライアント111に表示を発生することができる。適応ユーザインターフェイスサーバー126は、クライアント130に対してキャッシュ128及び随時接続データモデル127におけるデータノードからHTMLページを構成することができる。クライアント130は、サーバー120への一貫したアクセスを有する慣習的なウェブブラウザを含むことができる。適応UIサーバー126は、サーバーにおいてクライアントアプリケーションを実行して、シンクライアント(例えば、普通のウェブブラウザ、SMS電話等)からアクセスできるようにするメカニズムを与えることができる。
移動クライアント111は、随時接続アプリケーションサーバー120にコンタクトせずに、データノード及び随時接続データモデル115を使用してアプリケーションを実行することができる。キャッシュ113及び随時接続データモデル115におけるデータノードは、移動ブラウザ110において同期クライアント112により使用されて、HTMLビュー119のような表示を発生することができる。一実施形態では、テンプレートを使用して、移動ブラウザ110に表示を発生することができる。
データノード及び随時接続データモデルは、随時接続アプリケーションサーバー120と移動クライアント111との間で同期させることができる。この同期は、移動クライアント111と、随時接続アプリケーションサーバー120との間の接続が得られるので、バックグランドにおいて行うことができる。
本発明の一実施形態は、随時接続データモデルにより定義されたアプリケーションに対して、データノード、例えば、キャッシュ128のデータノードをクライアント111と同期させるための同期エンジンのような同期ユニット131と;外部システムからのデータと、随時接続データモデル127により定義されたデータノードとの間で変換を行うためのコンジットマネージャー124と、を備えた随時接続アプリケーションサーバー120である。
本発明の一実施形態は、随時接続アプリケーションサーバー120において、ノード及びノード間の関係を定義する随時接続データモデル127を記憶し、そして随時接続アプリケーションサーバー120において、随時接続データモデル127により定義されたデータノードをキャッシュ記憶することを含む方法である。随時接続アプリケーションサーバー120は、随時接続データモデル127のメタデータにより指示されるデータノードをキャッシュ記憶することができる。
本発明の一実施形態は、随時接続データモデル127を記憶するためのメモリと、随時接続データモデル127により定義されたデータノードを記憶するためのキャッシュ128とを備えた随時接続アプリケーションサーバー120である。データノードは、一次キー及び同期状態を含む。一次キーは、データモードを識別する。又、データノードは、少なくとも1つの二次キーを含むこともできる。同期状態を使用して、データノードを移動クライアントと同期させることができる。随時接続データモデル127は、データノードに対するXMLスキーマを含むことができる。
本発明の一実施形態は、随時接続アプリケーションサーバー120である。この随時接続アプリケーションサーバー120は、随時接続データモデル127を記憶するためのメモリを含むことができ、この随時接続データモデル127は、ノード及びノード間の関係を定義することができ、そして更に、アプリケーションサーバー120は、外部システムからのデータと、随時接続データモデル127により定義されたデータノードとの間で変換を行うためのコンジットマネージャー124を含むことができる。
コンジットマネージャー124は、随時接続データモデル127により定義されたデータノードと、特定のウェブサービス140に対する要求及び応答のためのデータとの間の変換を定義するコンジット137を使用することができる。これら変換は、メタデータとして含むことができる。
要求変換は、出て行くメッセージ本体を生成するXQueryファンクションを含むことができる。応答変換は、到来する応答を処理すると共に、随時接続データモデル127により定義されたデータノードを生成するXQueryファンクションを含む。
本発明の一実施形態は、外部ウェブサービス140のオペレーションを呼び出すコンジットマネージャー124を備えた移動クライアント111のための随時接続アプリケーションサーバー120である。コンジットマネージャー124は、コンジット137を使用することができる。コンジットは、随時接続データモデルにより定義されたデータと、特定のウェブサービス140に対する要求及び応答との間の変換を定義することができる。
本発明の一実施形態は、随時接続アプリケーションサーバー120において、コンジット137を使用して、随時接続データモデル127のデータノードと、ウェブサービス140に対する要求及び応答との間で変換を行い、データノードはXMLデータであり、そして随時接続アプリケーションサーバー120において、データノードを使用して、移動ブラウザ表示に対して移動クライアント111へデータを与えることを含む方法である。データノードは、表示のために移動クライアント111へ転送することができる。
本発明の一実施形態は、キャッシュ113に記憶することのできるデータノードを含む移動クライアント111である。データノードは、XMLフォーマットである。移動クライアントにおけるデータノードは、関連同期状態をもつことができる。この同期状態は、データノードがサーバー120と同期されたかどうか指示することができる。データノードは、バックグランドにおいて同期させることができる。というのは、サーバーへのアクセスが得られると共に、移動クライアント111における表示が、サーバー120への現在アクセスを必要とせずに、移動クライアント111においてデータモードを使用して行われるからである。
同期状態は、データノードがローカルで生成又は変更されたという指示と、データノードがローカルで生成又は変更されそしてサーバーと同期される準備ができたという指示と、データノードのサーバー同期が保留中であるという指示と、データノードがサーバーと同期されたという指示と、同期がサーバーにより拒絶されたという指示と、ローカル変更とサーバー更新との間に競合があるという指示とを含むことができる。これら及び他の同期状態は、移動クライアント111においてデータノードを更新するのに使用できる。
移動クライアント111には、サーバー120からデータノード及び随時接続データモデルが転送されて、移動クライアントに表示を発生することができる。移動クライアント111は、サーバーに現在コンタクトせずに、データノード及び随時接続データモデル115を使用してアプリケーションを実行することができる。サーバー120と移動クライアント111との間でのデータノードの同期は、バックグランドで行うことができる。
本発明の一実施形態は、ノードのタイプ及びノード間の関係、並びにデータノードを定義する随時接続データモデル115を含む随時接続アプリケーションサーバー120である。データノードは、XMLフォーマットである。随時接続アプリケーションサーバー120は、データノードのための同期状態を移動クライアント111とで前後に通過させて、データノードを同期させることができる。データノードは、バックグランドにおいて同期させることができる。というのは、サーバーへのアクセスが得られると共に、移動クライアント111における表示が、サーバー120への現在アクセスを必要とせずに、移動クライアント111においてデータモードを使用して行われるからである。
本発明の一実施形態は、移動装置において移動アプリケーションを同期させる方法である。この方法は、移動装置に第1ユーザインターフェイスを表示するステップであって、この第1ユーザインターフェイスが、移動装置に記憶されたテンプレートから導出されるようなステップと;移動装置のユーザから第1入力を受け取るステップと;移動装置において同期パラメータを更新するステップと;移動装置に第2ユーザインターフェイスを表示するステップであって、この第2ユーザインターフェイスが、移動装置に記憶されてユーザ入力に基づいて選択された第2テンプレートから導出されるようなステップと;アプリケーションサーバーからデータを検索するステップであって、このデータは、同期パラメータに基づいて選択された1つ以上のテンプレートを含むようなステップと、を備えている。
本発明の1つの態様は、XMLフォーマットのデータノードのローカルキャッシュ113と、ノードのタイプ及びノード間の関係を定義する随時接続データモデル115とを備えた移動ユニット111であって、データノード及び随時接続データモデルを使用して、この移動ユニットに表示されるアプリケーションを発生するような移動ユニット111である。
テンプレート135は、データノードのためのインターフェイスを移動ユニットに発生するのに使用できる。
本発明の一実施形態は、XMLフォーマットのデータノードのローカルキャッシュ128と、ノードのタイプ及びノード間の関係を定義する随時接続データモデル115と、データノードの変更を許すアクションとを含む移動ユニット110である。
本発明の一実施形態は、随時接続データモデル115を記憶するメモリと、この随時接続データモデル115により定義されたデータモードのローカルキャッシュ113とを備えた移動ユニット110である。データノードは、一次キー及び同期状態を含む。
一実施形態において、データモードの少なくとも1つは、少なくとも1つの二次キーを含む。同期状態を使用して、モードデータを随時接続アプリケーションサーバーと同期させることができる。随時接続データモデル115は、データノードのための少なくとも1つのXMLスキーマを含むことができる。
本発明の一実施形態は、ウェブサービス140のような外部システムと、随時接続データモデル127との間で変換を行うためのコンジットマネージャーを含む移動クライアントのための随時接続アプリケーションサーバー120である。キャッシュ128を使用して、随時接続データモデル127により定義されたデータノードと、適応ユーザインターフェイスサーバー126とを記憶することができる。ある移動クライアント111には、データノード及び随時接続データモデルが転送されて、移動クライアント111に表示が発生されると共に、他のクライアントは、データノード及び随時接続データモデルを使用して適応ユーザインターフェイスサーバー126により構成されたHTMLページを、随時接続アプリケーションサーバー120から受信する。
適応ユーザインターフェイスサーバー126によりサービスされるクライアント130は、慣習的なブラウザをもつことができる。移動クライアント111は、データノード及び随時接続データモデルを使用して表示を発生する特殊なブラウザ110をもつことができる。
本発明の一実施形態は、サーバー120において、随時接続データモデル127により定義されたデータノードと、その随時接続データモデル127とを記憶するステップと;そのデータノード及び随時接続データモデルをあるクライアント111へ転送して、そのクライアントが表示を発生できるようにするステップと;そのデータノード及び随時接続データモデルからサーバーにおいて構成されたHTMLページを他のクライアント130へ転送するステップと、を備えた方法である。
本発明の一実施形態は、ノードの構造を記述するnodetypeを含む随時接続データモデルである。ノードは、データとは論理的に独立したユニット、及びノード間の関係を記述するkeyref宣言である。
ノードは、ルート(根)ノードを含むことができる。変数は、ルートノードを指すことができる。移動ブラウザ110は、データノード及び随時接続データモデル115を使用して、移動ユニット111に表示を発生することができる。随時接続データモデル115は、ノードグラフを含むことができる。ノードグラフは、どのデータモードをキャッシュ記憶すべきか指示することができる。
nodetypeは、複雑なタイプの定義であるXMLスキーマのようなXML定義を含むことができる。keyref宣言は、キー及びキー参照を定義することができる。キーは、一次キーである。keyrefは、一次キーを参照する外部(foreign)キー定義である。keyref定義は、データグラフにおけるノードとノードとの間のリーガルトラバースを定義することができる。
本発明の一実施形態は、ノード構造のXML定義であるnodetypeと、ノード間の関係を記述するkeyref定義のようなメタデータとを含む随時接続データモデルである。ノードは、データとは論理的に独立したユニットである。
本発明の一実施形態は、プロキシーを実施する方法であって、随時接続データモデルのようなプログラミングモデル内でデータへウェブサービスオペレーションをマップさせるステップと、データとの関連付けに関する要求を受信するステップと、対応するウェブサービスオペレーションへの呼び出しを開始するステップとを備えた方法である。
本発明の一実施形態は、XMLフォーマットであるアプリケーションデータノードのローカルキャッシュ113と、ノードのタイプ及びノード間の関係を定義する随時接続データモデル115と、データノードのためのインターフェイスを発生するテンプレート135とを備えた移動ユニット111である。
テンプレート135は、XHTMLテンプレートである。テンプレート135は、Spath表現を使用することができる。
テンプレート135は、随時接続データモデル115において現在位置にアクセスすることができる。現在変数は、現在位置を指示することができる。一実施形態では、テンプレート135は、随時接続データモデルを変更しない。
一実施形態では、テンプレート135は、アクションを呼び出すことができる。アクションは、データノードを変更することができる。アクションは、サーバー120へ接続せずに、データノードの変更を許すことができる。
テンプレート135は、多数のアプリケーションに対して使用可能であり、各アプリケーションは、それ自身の随時接続データモデル及びデータノードを有する。テンプレート135は、ブラウザ110により検証することができる。
図11A−Bは、本発明の一実施形態の同期方法を示す。図11Aの実施例では、クライアント1102は、「データノードA」1104のクライアントバージョンを含む。「データノードA」1104のクライアントバージョンは、同期状態「ready for sync.(同期のための準備)」を有する。「データノードA」1104のクライアントバージョンは、クライアント1102において構成又は変更されるデータを含むことができる。図11Aの実施例では、クライアント1102とサーバー1108との間にアクティブな接続はない。「データノードA」1104のクライアントバージョンは、同期のための待機なしに、クライアントにおいてアプリケーションにより使用することができる。「データノードA」に対する変化は、接続が得られたときに送信されるメッセージ待ち行列1106のメッセージに含ませることができる。
サーバー1108は、クライアント1102へ送信されていない「データノードB」1110のサーバーバージョンを有する。「データノードB」1110のサーバーバージョンは、「ウェブサーバーB」1116から得たデータから構成することができる。コンジットマネージャーは、「コンジットB」1114を使用して、「ウェブサービスB」1116からの応答データを「データノードB」1110のサーバーバージョンへ変換することができる。「データノードB」は、接続が得られたときに送信されるべきメッセージ待ち行列1118のメッセージに含ませることができる。
図11Bは、接続が得られたときの状態を示す。「データノードA」1104のクライアントバージョンは、サーバー1108へ送信することができ、そして「データノードA」1104のクライアントバージョンは、その同期状態を「awaiting sync.(同期待機)」にセットすることができる。サーバー1108は、「データノードA」1111のサーバーバージョンをキャッシュ記憶することができる。コンジットマネージャー1112は、「コンジットA」1115を使用して、「ウェブサービスA」1117へ送信するための要求データを構成することができる。クライアント1102は、サーバー1108から得た「データノードB」1105のクライアントバージョンを記憶することができる。
バックグランドにおいてサーバーと同期されるデータノードを使用することで、クライアントは、サーバーへ間欠的に接続されて、データノードのローカルバージョンでアプリケーションを実行し、そして導通が得られるときに更新することが許される。
1つの実施形態を以下に説明するが、これに限定されるものではない。以下の説明は、1つの実施形態であるが、当業者であれば、上述したコンセプトの他の実施形態も得られることが理解できよう。以下に述べる潜在的限定言語は、特定の非限定実施形態の文脈におけるものと解釈されるべきであり、一般的なコンセプトを限定するものではない。
本発明の一実施形態は、ブラウザ110を備えていて、随時接続アクセスメカニズムを与えるシステムである。ブラウザ110は、移動装置111において実施されて、ユーザへのユーザインターフェイスを与えるように構成できる。ユーザインターフェイスは、テンプレート135から導出することができる。アプリケーションサーバー120は、持続的なデータ記憶装置をなし、そしてブラウザとで情報を送信及び受信するように構成される。
一実施形態において、随時接続アプリケーションサーバー120(MAS)は、BEAシステムズのWebLogicサーバーのようなアプリケーションサーバーの最上部で実行されるか、又はその一部分である。随時接続アプリケーションサーバー120は、アプリケーションメタデータを記憶するための持続的データ記憶装置と、クライアント要求を最適化するためのデータキャッシュ128とを含む。
随時接続アプリケーションサーバー120は、ウェブベースの同期サービスの集合を経て移動ブラウザにアクセスすることができ、これは、SyncML規格を拡張することができる。これは、異なるタイプのクライアントがMASデータモデル及び同期能力をレバレッジできるようにする。
随時接続アプリケーションサーバー120は、クライアントの完全な状態を保持する必要がない。むしろ、随時接続アプリケーションサーバー120は、随時接続データモデル127におけるメタデータに基づいてデータをインテリジェントにキャッシュ記憶することができる。更に、随時接続アプリケーションサーバー120は、適応UIサーバー126として知られている動的コンテンツ適応メカニズムを組み込むことができ、これは、移動アプリケーションファンクションをシンクライアント(例えば、HTMLウェブサイト、WAP、SMS)に配送することができる。
一実施形態において、随時接続データモデルは、外部データについての移動アプリケーションの予想される使用のメタデータ記述であり、随時接続装置と外部システムとの間でこのデータの効率的なトラバース及び同期を可能にするように最適化することができる。
随時接続データモデルは、外部サービスに関連したデータのノード(又はエンティティ)及びそれらの間のトラバース(又は関係)を記述する関連モデルである。例えば、顧客関係マネージメント(CRM)アプリケーションへのアクセスを与えるウェブサービスが与えられると、データモデルは、アカウント、コンタクト及び購入注文等に対するノードを、所与のノード(例えば、アカウント)から全ての関連ノード(例えば、コンタクト及び購入注文)へアプリケーションを「ナビゲート」させるトラバースと共にもつことができる。
随時接続データモデルは、デベロッパに対して、データモデルにおけるルートノードを指すマニフェスト変数$rootを伴う仮想XML文書として表面化させることができる。関連ノードへのナビゲーションは、keyref宣言を経て仮想XML文書内で定義することができる。これは、XMLに対してECMAScriptに使用され且つ本書ではSPathとして知られているXPath表示のサブセットを使用して、簡単なトラバースシンタックスを可能にする。更に、移動ブラウザは、常に、データモデル内の現在位置(例えば、特定の顧客又は注文のセット)をコンテクストとして有することができる。テンプレート及びスクリプトは、別のマニフェスト変数$currentを経てこの現在位置にアクセスすることができる。
一実施形態において、移動ブラウザ110は、随時接続ラップトップ及び他の装置が、接続状態となるかオフラインとなるかに関わらず、アプリケーションを実行できるようにするウェブブラウザの拡張であるか、又はそれを含む。ブラウザは、現在ウェブブラウザと同じHTMLレンダラーを組み込むことができるが、ユーザインターフェイステンプレート及びページフローメカニズム、インテリジェントな同期能力を伴うデータキャッシュ、及びデータキャッシュへのアクセスを与える拡張されたスクリプト言語も組み込むことができる。
移動ブラウザのユーザインターフェイスは、ページテンプレートで構成することができる。これらテンプレートは、SPath表現を使用してキャッシュ記憶データへの埋め込まれたバインディングを伴うXHTMLページである。一実施形態において、テンプレートは、サーバー側の依存性をもたず、従って、ブラウザのネットワーク接続の状態(即ち、オンライン又はオフライン)に関わらず、それらをレンダリングすることができる。
これらテンプレートは、コントローラにより捕獲できるユーザインターフェイス事象を発生することができ、即ちコントローラは、クライアントキャッシュにおいてデータを変更してページフローを決定することのできるアクションスクリプトをコールすることができる。クライアント同期ユニットは、随時接続アプリケーションサーバー120とのデータアクセス及び変更を自動的に同期させることができる。
アプリケーションに関するクライアントユーザインターフェイス及び随時接続データモデルを実施するXMLアプリケーションパッケージを参照するURLを指すことにより、移動ブラウザ110へアプリケーションを用意することができる。次いで、アプリケーションは、同期クライアント112に対して同期させることができる。更に、アプリケーションがいったん配備されると、アプリケーションの更新は、自動的で且つシームレスである。
一実施形態において、適応UIサーバー124は、アクティブなユーザごとにクライアントアプリケーション(テンプレート、ページフロー、アクション等)を実行するプロキシーである。これは、HTMLページ(又はSMS等)を発生することができ、これらページは、ブラウザ130へ送信され、そしてこれらのHTMLページは、適応サーバーが対応アクションコールへと解釈するところのHTTP要求を発生する適当なハイパーリンクを含むことができる。適応サーバー126は、移動ブラウザ110と同じ同期メカニズムを使用することができる。
クライアントアプリケーションは、同期によりサーバーと通信することができる。同期プロセスは、新たな又はより最近のデータをフェッチするか、又は外部ウェブサービス140へのクライアント変更のポストバックを要求するためのコンジット要求をトリガーすることができる。コンジット37は、ウェブサービス要求をいかにパッケージするか、及びそれらの応答をデータモデルの状況においていかに解釈するか記述するメタデータを含むことができる。
例えば、クライアントアプリケーションが、クライアントにキャッシュ記憶された特定のアカウントノード(レコード)に対するレーティングコードを変更し、即ち同期メカニズムが、サーバーへ送信される更新コマンドを発生できると仮定する。次いで、クライアントアプリケーションが、アカウントに関連したコンタクトを検索し、そして新たなコンタクトを追加する場合には、同期メカニズムは、対応するデータノードをフェッチしそして追加するためのコマンドを発生できる。コンジットは、これらオペレーションの各々を実施するのに必要な種々のウェブサービスオペレーションをいかに呼び出すか記述することができる。
このシステムは、標準的なウェブサービスを使用して、外部データリソース及びビジネスプロセスと情報を交換することができる。コンジットメカニズムは、随時接続アプリケーションサーバー120が、移動データキャッシュ128を更新するためのこれらオペレーションをコールできるようにする。これらオペレーションは、特定データタイプに対するゲッター及びセッターとして働くことができ、即ちアダプターとして働き得るコンジットによりオペレーションの集合をマネージすることができる。コンジットマネージャーは、OCASデータキャッシュからの同期要求とコンジットオペレーションを整合することができる。
コンジットは、ウェブサービスを、データモデルに関連した3つのタイプの要求されたアクションに関連付けるのに使用されるメタデータである。
−関連データへのナビゲーションで、例えば、アカウントに関連したコンタクトを得る。
−CRUDオペレーション、即ちデータを生成し、読み取り、更新しそして削除する要求で、例えば、アカウントに関連したコンタクトを生成し、コンタクトの細部を更新し、又はコンタクトを削除することを要求する。
−あるデータに関連したエンタープライズにおいて行う必要があるが、データモデルに対して不透明なアクションである顧客オペレーションで、例えば、タスクをクローズすることを要求する。
コンジットメタデータは、OCASデータモデル及び同期コマンドを、対応するウェブサービスオペレーションに関連したSOAPメッセージへ及びそこからマップすることができる。コンジットメタデータは、XML問合せ又はXScriptを使用して定義することができる。
移動性に対する現在ウェブブラウザアーキテクチャーの主たる欠点は、同期(ブロッキング)要求−応答メッセージングプロトコル(即ち、HTTP)である。OCASにおいて、メッセージングは、非同期であってもよい。即ち、ユーザインターフェイスアクティビティ(例えば、ページをブラウジングしそしてデータを変更する)は、ネットワークの接続性に対して非同期で実行することができ、そして同期要求は、ブラウザに対して非同期で実行されてもよい。
図2は、移動ブラウザ210と、OCAS220と、外部ウェブサービス230との間の非同期の対話を例示する。このシステムは、ブラウザとOCASとの間に信頼性のある順序付けされたメッセージ待ち行列を実施し、そしてOCASとウェブサーバーとの間に耐久性のあるJMS待ち行列を使用してもよい(非同期のオペレーションコールに対して)。
ブラウザがオンラインである場合には、同期メッセージを待ち行列に入れて、後で、OCASへ送信することができる。さもなければ、同期ユニットは、これらの事象を追跡し、そして接続が確立されたときに同期メッセージを発生することができる。
サーバーにおいて、OCASは、クライアントの同期要求に関するデータをキャッシュ記憶した場合に、即座に応答することができる。キャッシュが適切なデータを保持しない(又はデータが古い)場合には、同期ユニットがコンジットマネージャーをコールすることができる。次いで、同期ユニットは、更新されたデータをブラウザへ配送することができる。特定の同期要求に対して多数のコンジットが呼び出されることがあるので、OCASは、多数の同期メッセージをブラウザへ配送することがある。
同期メッセージがブラウザにより受信されると、ローカルキャッシュを更新し、事象をコントローラへ送信することができる。現在表示されているデータが変更された(即ち、データが現在テンプレートにバインディングされた)場合には、コントローラは、現在ページをリフレッシュさせることができる。即ち、ページデータバインディングを再計算し、そしてページを増分的にブラウザに再表示することができ、現在ユーザ入力、脱字記号又は焦点をフリッカーさせたり失ったりすることはない。
OCASアプリケーションは、クライアント及びサーバーコンポーネントで構成することができる。図3は、例示的なOCASアプリケーションに関するプログラミングモデル300を示す。このプログラミングモデル300は、移動クライアント310と、OCAS320と、外部システム330とを備えている。
一実施形態において、外部システム(即ち、エンタープライズ)への全ての通信は、ウェブサービス(即ち、SOAPメッセージ)を経て達成することができる。サーバープログラミングモデルは、各アプリケーションに関するデータモデル定義322と、ウェブサービスオペレーションを記述する1組のコンジット定義324で構成することができる。データモデルは、データタイプ及び関係を記述する1組のXMLスキーマ定義で構成される。コンジット定義は、到来する及び出て行くSOAPメッセージをデータモデルへとマップするXScript及びXML問合せ(XQuery)ファンクションを含む。
クライアントプログラミングモデルは、データモデル311(これは、サーバーに定義されたモデルのコピーである)と、1組のXHTMLテンプレート312と、XPFページフロー定義及びXScriptアクション及びファンクションを含むコントローラ定義313とで構成することができる。全アプリケーションのコンテンツは、クライアントへのアプリケーションコンポーネントを用意するためにフレームワークにより自動的に使用される単一のXMLファイルにより記述することができる。
一実施形態において、各OCASアプリケーションは、それ自身の随時接続データモデルを有してもよい。この随時接続データモデルは、ウェブサービスを経て後端アプリケーションにより露出されたアプリケーションデータの論理的構造(及び他のプロパティ)を記述することができる。随時接続データモデルは、データモデルにおけるノード(又はエンティティ)を記述するnodetypeと、それらnodetype間の関係を定義するkeyrefとで構成できる。随時接続データモデルは、他のOCASコンポーネントにより使用されるリンガフランカ(lingua franca)として働いて、データを処理するか、又はデータを互いに交換することができる。
アプリケーションのデータモデルの実際の設計(これは、アプリケーションデザイナーにより行われる)は、データの予想される使用を考慮に入れて、サーバーと随時接続装置との間でクライアントアプリケーション及びデータ同期による両データアクセスを最適化することができる。
又、アプリケーションがデータ駆動(即ち自動的)ユーザインターフェイスを表示するのを容易にするように、付加的なメタデータを指定することもできる。一実施形態では、随時接続データモデルは、データを記述するだけであり、即ちOCASは、全てのオペレーションデータが外部システムにより記憶されそしてマネージされる(所有される)と仮定し、即ちOCASに永久的に存在するオペレーションデータはないと仮定する。
随時接続データモデルは、クライアント及びサーバーの両方にキャッシュ記憶され得るデータを記述するのに使用できると共に、本質的に、ウェブサービスを経てフェッチされるエンタープライズのデータの最上位における仮想キャッシュ記憶ビューである。一実施形態では、随時接続データモデル内に、全てのものが流れてくるところのmas:root(プログラミングモデルにおいて$rootにより参照される)として知られたマジックスタートノードがある。
いずれかのノードから、トラバースを経て関連ノードにアクセスすることができる。ノードは、XMLスキーマ定義(/schema/*.xsd)に適合することができる。又、トラバースは、keyref宣言を使用して、スキーマ定義により定義することもできる。
自動同期メカニズムは、クライアントデータとサーバーデータとの間の変化を整合することができる。データは、コンジットとして知られたメカニズムを経て検索して外部システムと交換することができる。コンジットは、コンジットオペレーション、即ち外部ウェブサービスオペレーションから結果を呼び出して処理するXScript及びXQueryファンクション、を定義する1組のコンジットファイル(/conduit/*.jsx)により構成することができる。
コンジットオペレーションは、所与のkeyrefに関連した一対のXML問合せファンクションで構成することができ、即ちその一方のファンクションは、適切なウェブサービスオペレーションへのアウトバウンド要求をフォーマットすることができ、そしてその他方は、インバウンド応答を処理することができる。又、コンジットオペレーションは、関連XScriptファンクションにおける手順ロジックを定義することもできる。
随時接続データモデルは、リレーショナルデータベースにおけるエンティティ(即ちテーブル行)及び関係(即ち一次/外部キーフィールド)と同様のノード及びトラバースより成るデータグラフとして表わすことができる。ノードは、データとは論理的に独立したユニット(又はエンティティ、例えば、顧客、購入注文、又はコンタクトレコード)であり、そしてXMLスキーマにより定義されたXMLデータオブジェクトとして表わすことができる。データキャッシュの内部では、各ノードは、一次キーと、同期状態(例えば、シーケンスナンバーを含む)と、おそらく、他のノードを参照する多数の外部キーとを含むことができる。nodetypeは、ノードの特定タイプに関する情報を記述することができ、これは、データノードの構造を記述するXMLスキーマ定義を含むことができる。トラバースは、2つのノード間の方向関係である。トラバースは、主として、1つのノードから1組の関係ノードへナビゲートするためのメカニズムである。例えば、アカウントは、1組のコンタクト及び1組のタスクに関連付けられてもよく、又、その各々は、コンタクトに関連付けられてもよい。ノード間の関係は、keyref宣言により定義することができる。これは、ソース及びターゲットの両nodetypeを定義できると共に、カーディナリティ(cardinality)又はノードセット(nodeset)(例えば、丁度1、0又はそれより多く、1又はそれより多く、等)を決定するためのメタデータを含むことができる。コンジットマネージャーのメタデータは、keyrefに関連付けることができ、そしてノードを生成できるか、更新できるか、リンクできるか又は除去できるか決定する。例えば、コンジットのメタデータは、アカウントに関するノート(Note)を挿入するか又はアカウントを更新するための既知のウェブサービスオペレーションがあるかどうか決定する。keyrefにより定義されたノードの特定の集合をノードセットと称することができる。
データノード
データノードは、構造化データ(即ち、XML文書)を含むことができるが、トラバースに対して原子的であり、即ち一実施形態では、トラバースは、2つのノード間の特定の関係を表わすが、特定のノード内のデータを参照することも、別のノードを参照するノード内のデータを参照することもできない。
単一のエンタープライズ文書は、しばしば、多数のnodetypeで作り上げることができる。例えば、購入注文は、一連のラインアイテム(各々製品参照をもつ)と、顧客参照とを含んでもよい。この場合に、購入注文、ラインアイテム、製品及び顧客は、全て、異なるnodetypeで表わされてもよい。
これらの「複合」ノードの場合には、データモデル内のkeyrefは、カーディナリティを定義することができ、例えば、ラインアイテムには、丁度1つの製品が関連付けられる。逆に、アプリケーションのニーズに基づいて、単一の購入注文nodetypeは、全ての前記情報を単一のスキーマに含むように定義されてもよい。判断は、アプリケーションデザイナーの手にあり、異なるトラバース、集合及びテンプレート要求に基づき異なるノードを独立してリンクするためのニーズに基づくものである。例えば、ラインアイテムが、購入注文以外でリンクも表示もされない場合には、購入注文−ラインアイテムの複合nodetypeを定義することが理解される。
関係モデル
随時接続データモデルは、関係エンティティ及び関係(一次/外部キー)構造と同様のスキーマ及びkeyref宣言で構成することができる。
一次及び外部キー
一例のCRMシステム(説明の目的で、本書全体にわたって参照される)は、リレーショナルデータベースを使用して実施される。図4に示すエンティティ関係ダイアグラム(ERD)400は、アカウント、コンタクト、事象、及びユーザエンティティを表わす。
アカウント、コンタクト及びユーザエンティティは、次のSQLにより定義される。
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
)
両アカウント及びコンタクトエンティティは、ユーザ(所有者)への外部キー参照を含み、即ち各コンタクトエンティティは、アカウントへの外部キー参照を定義する。又、各アカウントは、親アカウントを参照する任意の外部キーを有する(即ち、アカウントがサブアカウントを有する)。
サンプル問合せ
アカウントの一次キーpaが与えられると、次のSQLは、全てのコンタクトを選択する。
SELECT * FROM contact WHERE accountPkey = pa
コンタクトの一次キーpcが与えられると、次のSQLは、アカウントを選択する。
SELECT account.* FROM account, contact
WHERE account.pkey = contact.accountPkey
AND contact.pkey = pc
しかしながら、全コンタクトレコードcが与えられると、この簡単なSELECT問合せがそれに対応するアカウントを選択する。
SELECT * FROM account WHERE account.pkey = c.accountPkey
ジョインテーブル
事象が多数のアカウント及びコンタクト(例えば、存在する2つのアカウントを満足するセール)に属することができると仮定する。これは、例えば、ジョインテーブルを使用してモデリングされる。
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)
)
ここで、event_accountジョインテーブルにより多対多の関係がモデリングされる。
アカウントの一次キーpaが与えられると、次のSQL(ジョイン)は、全ての関係事象を選択する。
SELECT event.* FROM event, event_account
WHERE event_account.accountPkey = pa
AND event.pkey = event_account.eventPkey
同様に、事象の一次キーpeが与えられると、次のSQLは、全ての関係アカウントを選択する。
SELECT account.* FROM account, event_account
WHERE event_account.eventPkey = pe
AND account.pkey = event_account.accountPkey
XMLスキーマ
XMLスキーマは、アプリケーションにより使用されるデータモデルにおいてnodetypeを定義することができる。スキーマサブディレクトリーは、多数の.xsdファイルを含んでもよく、これらは全て始動時にフレームワークによりロードされる。
スキーマタイプ定義は、2つの部分で構成でき、即ちタイプの構造を記述するcomplexType定義と、例えば、特定タイプに対するラベルをいかに構成するか定義するメタデータ定義(mas namespaceを使用する)である。
例えば、次のスキーマフラグメントは、コンタクトタイプを定義する。
<?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>
次のXMLは、コンタクトエレメントを表わす。
<contact>
<salutation>Mr</salutation>
<first>Roger</first>
<last>Reed</last>
<email>roger@acme.com</email>
</contact>
keyrefベーシック
随時接続データモデルは、全てのアプリケーションタイプに対して標準的なXMLスキーマ定義で構成することができる。これらスキーマは、他のXMLノードを参照するXMLエレメント及び属性を含むノードを定義することができる。これら参照の定義は、keyref宣言を使用して行うことができる。
keyref定義は、key及びkeyrefの2つの部分で構成できる。
キー定義は、一次キーを含む文書内の場所を定義することができる。例えば、次のキーは、accountKeyが各<account>エレメントにおいてidと称する属性として生じることを示している。
<xsd:key name=”accountKey”>
<xsd:selector xpath=”account”/>
<xsd:field xpath=”@id”/>
</xsd:key>
一実施形態において、キーは、単一ノードを独特に識別することができる。キーは、ノード内の中継エレメントを識別するのには使用できない(例えば、ラインアイテムが購入注文に対するスキーマ内で定義される場合に、キー定義は、個々のラインアイテムを定義するのに使用できない)。
keyref定義は、外部キーを含む文書内の場所を定義することができ、即ち参照属性は、関連キー定義を参照する。例えば、次のkeyrefは、各コンタクトが、accountKey定義(上述した)を参照する外部キーであるアカウント属性を含むことを示す。
<xsd:keyref name=”contactAccountRef” refer=”accountKey”>
<xsd:selector xpath=”contact”/>
<xsd:field xpath=”@accountId”/>
</xsd:keyref>
同じ(一次)キー定義を参照する多数のkeyref(外部キー)定義が存在し得る。
タイプ及びインスタンス図
UMLを使用して、nodetype及びkeyref図を説明する。
図5は、同じCRMアプリケーションに関するUMLエンティティ関係図(ERD)500である。この図において、各エンティティは、アプリケーションnodetype(即ち、スキーマ)を表わす。ルートエンティティは、システムnodetypeであることに注意されたい。
アーク(arc)は、黒のダイアモンドがソースnodetypeの外部キーのターゲットnodetypeを表わすような関係(即ち、keyref定義)を表わしている。スター(star)表示は、多対1の関係を表わす。各アークは、対応するkeyrefのエイリアス名で表示される。図6は、CRM使用の場合のノードインスタンス図である。
ネームスペース
ネームスペースの実施形態について以下に説明する。サーバープログラミングモデルは、ネームスペースを使用して、フレームワークとアプリケーションXMLエレメントとの間を区別することができる。ネームスペース定義は、XMLソースファイルの最上位レベルエレメント内の属性として含ませることができる。
masネームスペースを先頭にもつエレメントは、次のシステムエレメントを表わす。
xmlns:mas=”urn:bea.mas”
規定により、appネームスペースプレフィックスを先頭にもつエレメントは、次のアプリケーションを表わす。
xmlns:app=”http://example.com/”
又、規定により(本書において)、wsネームスペースプレフィックスは、例示的ウェブサービス定義(即ち、WDSLファイル)により定義されたエレメントを指示するのに使用され、sfdcプレフィックスは、SalesForceウェブサービスを指示するのに使用される。
xmlns:ws=”http://www.openuri.org/”
xmlns:sfdc=”urn:partner.soap.sforce.com”
スキーマデータタイプ
次のXMLスキーマデータタイプをサポートすることができる。
Figure 0004551899
スキーマ注釈
標準的なXSDスキーマ定義は、<xsd:appinfo>エレメント内でmasエレメントを宣言することにより拡張することができる。
<xsd:element name=”typeName” type=”type”>
<xsd:annotation>
<xsd:appinfo>
...
</xsd:appinfo>
<xsd:documentation>schema documentation</xsd:documentation>
</xsd:annotation>
</xsd:element>
次のスキーマ注釈がサポートされる。
Figure 0004551899
ラベル
mas:labelエレメントは、ノードに対するデフォールトラベルを宣言し、即ちストリングを構成するのに使用されるXPath表現を宣言する。この表現は、XMLノードオブジェクトの最上位レベルエレメントを参照する$node変数を任意に参照することができる。
シンタックス
<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>
又、ラベル定義は、XScriptファンクション及び演算子を含んでもよい。
($node.first) + ($node.first.length() > 0 ? ” ” : ””) + $node.last
アプリケーションデータモデル定義の解剖
次のXMLスキーマは、アカウント及びコンタクトnodetypeを定義する簡単なアプリケーションデータモデルを記述する。
<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>
スキーマファイルは、3つの部分、即ちnodetype(複雑なタイプの定義)と、キャッシュ「文書」の構造を定義するグラフ定義と、グラフ(即ち、文書)構造に対するものである1組のkey/keyref定義とで構成することができる。
スキーマ定義
上述したように、データモデルは、XMLスキーマ定義で構成される。次のスキーマは、アカウント及びコンタクトnodetypeを定義する。
<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>
全てのタイプは、キーであると宣言された一次キーフィールド(又は属性)を定義することができる。
この実施例において、全てのタイプは、外部レコードの一次キーを表わす外部識別子idを定義することができ、又、contactタイプは、外部キーを表わす属性@accountIdも定義する。
上述したスキーマ定義は、次のインスタンスデータを許す。
<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>
ここに示す識別子の値は、例示に過ぎず、又、この実施例は、フレームワークによりマネージされるものでプログラミングモデルには見えないmas属性を示すものでないことに注意されたい。
データグラフ定義
随時接続データモデルは、デベロッパに対して仮想XML文書又はデータグラフとして表面化することができる。アプリケーションは、スキーマ及びkeyref宣言を指定することによりデータグラフの構造を定義する。
しかしながら、キーのkeyref宣言それ自体は、アプリケーションスキーマの<graph>エレメントにより定義された固定文書構造に対するものであるXPathを含むことができる。
グラフタイプは、ノード宣言の「フラット」シーケンスを定義することができる。
<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>
これは、ルートエレメントのタイプと、アプリケーションを作り上げる1組の全スキーマタイプとを定義する。
グラフ構造は、その大部分が実施細部であり、デベロッパは、key/keyref定義を使用してデータグラフをトラバースすることに注意されたい。ここに提案する1つのグラフ実施は、フラットであり、即ち全てのnodetypeが、<graph>エレメントの第1レベルの子である。
上述した実施例は、次のインスタンスデータを許す。
<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>
key及びkeyref定義
又、スキーマ定義ファイルは、データタイプとデータタイプとの間の一次キー及び外部キーの関係を宣言することのできるkey及びkeyref定義も含むことができる。
key定義は、一次キーを定義することができる。キーは、多数のフィールド宣言(即ち、コンパウンドキーに対する)を含んでもよい。
keyref定義は、key定義を参照する外部キーを定義する。
例えば、次のkey及びkeyref定義は、コンタクトノードからその関係アカウントノードへの多対1(ルックアップ)関係と、ルートからアカウントへの1対多の関係とを定義する。
<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>
key及びkeyref定義は、独特のネームを有していなければならない。key及びkeyrefに対するネーミング規定は、各々、次の通りである。
<xsd:key name=”<schema>Key” ...
<xsd:keyref name=”<sourceSchema><element|attribute>Ref” ...
例えば、fooBarRefは、barと命名されたエレメント又は属性により定義されたfooスキーマからのkeyrefを意味する。即ち、(通常は)keyrefのセレクタXPathは、「foo/bar」又は「foo/@bar」である。
一般に、keyrefネームは、keyrefセレクタ及びフィールドを連結しそしてmasエレメントを剥離することにより構成された「camelBack」切り刻みネームである。例えば、
<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>
タイプは、通常、ネームの最後の部分から推測できることに注意されたい。というのは、これは、XMLガイドラインに続いて、含まれたデータの目的を説明しなければならないエレメント又は属性ネームだからである。
フレームワークは、keyrefネームが最上位レベルエレメント属性ネームと衝突しないことを保証できる。
エイリアス
keyref宣言は、データグラフ内のノードとノードとの間のリーガルトラバースを定義することができる。@@演算子は、グラフをトラバースするのに使用できると共に、デフォールトにより、keyrefネームを使用する。しかしながら、エイリアスは、コードを読み易くするように定義されてもよい。
mas:alias属性は、任意に2つの部分を有するストリングを定義する。
mas:alias=”[XPath:]name”
ここで、nameは、エイリアスネームを表わし、そして任意のXPathプレフィックスは、@@演算子及びエイリアスネームの前に入らねばならないSPath(グラフに対する)を表わす。即ち、
var refNode = srcNode.SPath.@@name
コロンのデリミッターが存在しない場合には、エイリアスXPathプレフィックスがkeyrefのセレクタXPathと同じである。エイリアスが定義されない場合には、keyrefネームを使用しなければならない(keyrefセレクタXPathに対して)。
又、キー定義は、関連nodetypeを含むnodesetがルートノードからトラバースできることを指示するmas:alias属性を宣言してもよい。キー定義に対するエイリアスネームは、簡単なストリングであり、これも@@演算子により使用される。
mass:alias=‘name’

次のXMLは、アカウントノードのインスタンスを表わす。
<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>
次の表現は、第1購入注文の第1ラインアイテムにより参照される製品へとトラバースする。
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>
次の表現は、「所有者」エイリアスにより記述される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>
次の表現は、「事象」エイリアスにより記述された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.*;
逆の関係
keyref宣言は、逆方向のナビゲーションを可能にする逆keyrefを任意に定義することができる。通常、多対1のkeyrefは、逆の1対多のトラバーサルを可能にする逆keyrefを宣言する。
<xsd:keyref name=”name” refer=”keyName” mas:alias=”alias”
mas:inverseAlias=”inverseAlias”>
逆の属性は、次のように定義される。
Figure 0004551899
例えば、以下のkeyref定義は、contact→account及びaccount→contact関係を表わす。
<xsd:keyref name=”contactAccountRef” refer=”accountKey” mas:alias=”account”
mas:inverseAlias=”contacts”>
<xsd:selector xpath=”contact”/>
<xsd:field xpath=”@accountId”/>
</xsd:keyref>
各コンタクトノードは、accountノードを参照する@accountId属性(外部キー)を含む。即ち、
var account = contact.@@accountId;
逆の関係は、外部キーを使用してアカウントノードからコンタクトノードへトラバースできることを示す。即ち、
var contacts = account.@@contacts.*;
一実施形態において、逆のエイリアス属性は、属性ネーム(上記keyrefエイリアスを参照)しか含んではならず、そして常に、最上位レベルノードに対するものとなる。
多数のkeyref定義は、同じnodetypeに「戻るように指す」逆の関係を宣言してもよいことに注意されたい。これらの場合に、逆のエイリアスは、当然、ターゲットnodetypeに対して独特のものでなければならない。例えば、bugノードは、bugs及びassignedBugsの逆のエイリアスを各々定義するowner及びassignedToに対するkeyrefを有してもよい。
又、逆の関係は、両方向におけるナビゲーションがキャッシュ内で一貫したものとなるようにフレームワークが保証することも許す。
ルートkeyref
外部キーの値に依存しないノード間の関係を定義することができる。例えば、現在ユーザ情報又は他の外部情報(例えば、日時、リアルタイムデータ、外部システム状態)を使用する問合せにより1組のノードを定義することができる。これらの場合に、nodesetをデータモデル内の任意のnodetypeにアタッチすることができる。しかしながら、通常、これらのnodesetは、ルートノードにアタッチされる。
CRM実施例では、特定のユーザにアクセスできるアカウントのセットを、システム変数$user/usernameにより定義されたユーザログインネームで定義することができる。アプリケーションは、ルートノードからこのnodesetへのトラバースを定義することを望む。即ち、
var accounts = $root.@@accounts.*;
ルートノードを参照する各アカウントノードに対して任意の人為的外部キー値が定義される。これは、次のkeyref定義により達成される。
<xsd:keyref name=”accountRootRef” refer=”mas:rootKey”
mas:inverseAlias=”accounts”>
<xsd:selector xpath=”account”/>
<xsd:field xpath=”@rootId”/>
</xsd:keyref>
又、アカウントスキーマは、検証されるべきkeyrefに対して任意の@mas:rootId属性も定義しなければならないことに注意されたい。
<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>
@mas:rootId属性は、フレームワークにより定義されたシステム定義を参照し、システムのスキーマ定義は、次のディレクティブによりアプリケーションのスキーマにインポートされる。
<xsd:import namespace=”urn:bea.mas” schemaLocation=”mas.xsd”/>
@@演算子
ナビゲーションは、ページフロー内であるページから次のページへ移動するアクションである。これは、$contextシステム変数を変化してもよいし、しなくてもよい。
トラバースは、データグラフ(キャッシュ)内を移動するアクションである。SPath表現は、例えば、@@演算子を使用してグラフを「トラバース」する。
foo.@@bar
但し、fooは、ノード(又はノードの子エレメント)を表わし、そしてbarは、keyref定義(ネーム又はエイリアス)又はキーエイリアスにより外部キーであると定義された子エレメントのネームである。
例えば、次のデータを有すると仮定する。
<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>
次のkeyref定義:
<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;
キー及びシーケンスナンバー
データモデルにおいてノードとして表わすことのできる全ての外部レコードは、独特の一次キー(pkey)を定義しなければならず、即ち一次キーは、ウェブサービスSOAPインターフェイスの一部分として露出されねばならない。一実施形態では、一次キーは、全てのユーザに対しオペレーション呼び出しにわたって一貫したものとなる。というのは、ある場合に、フレームワークが、1人のユーザにより得たデータを共有キャッシュに配置できるからである。
外部システムのウェブサービスオペレーションは、任意であるが、特定ノードに関連したシーケンスナンバー(seq)を返送してもよく、これは、システムが更新されたレコードを検出できるようにする。通常、シーケンスナンバーは、データベースタイムスタンプに対応する。ウェブサービスがシーケンスナンバーを与えない場合には、フレームワークが、レコードのXML値に基づいてMD5ハッシュを計算する。
スキーマ定義は、外部アプリケーション識別子と、任意であるが、シーケンスナンバー(又はタイムスタンプ)とを定義するエレメントを定義することができる。それに対応するスキーマエレメントは、システムプロパティ「pkey」又は「seq」を示すmas:type属性を定義する。
例えば、次のスキーマは、アプリケーションコンタクトタイプを定義する。
<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>
このスキーマは、一次キー及びシーケンスナンバーを各々表わす属性@id及び@timestampを定義する。例えば、次のXMLは、コンジットにより返送されるコンタクトノードのインスタンスを表わす。
<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>
mas:type=「pkey」スキーマエレメント宣言は、ノードに対する一次キーを識別するために必要とされることに注意されたい。
キーの値は長くてもよいので、デフォールトにより、これらの値は、クライアントにも送信されないし、クライアントプログラミングモデルによりアクセスされることもない。mas:visible属性は、このデフォールト振舞いを抑制するように指定されてもよい。
スキーマ修飾を以下に示す。
Figure 0004551899
key(keyrefではなく)フィールドが可視としてマークされない場合には、クライアントのフィールドにアクセスする試みがナルとなる(不存在のフィールドがアクセスされたかのように)。たとえ可視であっても、キーフィールドは読み取りのみである。
var x = contact.id; // returns null
var y = cont
一次キー及びシーケンスナンバー値は、外部システムによりセットされる。キーであると定義されるフィールドと同様に、フィールドの値を変更する試みは、ランタイムエラーを発生する。新たなノードを生成するときに、これらフィールドが含まれてはならない。例えば、
var contact =
<contact>
<first>Maggie</first>
<last>Cheung</last>
<email>maggie@acme.com</email>
</contact>
参照による外部キーの指定
外部キーの値は、指定によりセットすることができる。指定表現のRHSがノードに対して評価する場合、これは、ノードの一次キーへと自動的に強制される。
以下に実施例では、コンタクトノードのアカウント外部キー(アカウントkeyref定義によりアカウント属性となるように定義される)が、供給されたアカウントノードを参照するようにセットされる。
function setAccount(contact, account)
contact.@@accountId = account;
}
値による外部キーの指定
keyref定義により参照されるスキーマがmas:visible一次キーを宣言する場合に、それに対応する外部キー値は、文字通りの値(即ち、ノード参照ではない)によってセットされてもよい。
例えば、次のアカウントスキーマは、可視pkey属性を定義する。
<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”;
}
外部キー値は、クライアントに現在キャッシュ記憶されているノードに分解されなくてよいことに注意されたい。更に、不良値がセットされた場合には、それに関連したコンジットオペレーションがフェイルするはずである。
関係
多対1(ルックアップ)
多対1の関係は、関係一次及び外部キーを並行して生じるkey及びkeyref定義を使用して実施することができる。
<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>
このキー定義は、accountKey(一次キー)が各<account>ノードにおいてidと称する属性として生じることを示す。keyref定義は、contactAccountRef(外部キー)が<contact>ノードのaccount属性を参照することを示す。
例えば、次のインスタンスデータが与えられる。
<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>
次は、アカウントに対する一次キー(即ち、accountKey)を定義する。
<account id=”1.1”>
次は、コンタクトから同じアカウントへの外部キー(即ち、contactAccountRef)を定義する。
<contact id=”1.2” accountId=”1.1”>
時々、ノード内に含まれたデータを外部キー値として使用することを希望する。例えば、CRM実施例を拡張して、コンタクトに関連したeメールメッセージを含むようにする。以下のスキーマは、メッセージノードを記述するもので、これは、from及びtoエレメントにより表わされた2つの「自然」外部キーを含む(各メッセージは、多数のtoエレメントを有してもよいことに注意されたい)。
<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>
コンタクトエレメントがemailエレメントを含むことは既に定義した。
<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>
以下のキー定義は、コンタクトノード内のemailエレメントがキーとして使用されてもよいことを定義する。
<xsd:key name=”contactEmailKey”>
<xsd:selector xpath=”contact”/>
<xsd:field xpath=”email”/>
</xsd:key>
次のkeyref定義は、メッセージノード内の2つの外部キーエレメントを定義する。
<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>
messageFromRefのkeyrefは、次のように書くこともできる(が、フレームワークは、常に、上記形態を使用し、即ち、messageToRefは、多数の<to>エレメントが存在し得るので、上記形態で書かねばならない)ことに注意されたい。
<xsd:keyref name=”messageFromRef” refer=”contactEmailKey”>
<xsd:selector xpath=”message/from”/>
<xsd:field xpath=”.”/>
</xsd:keyref>
1対多(集合)
1対多の関係は、逆keyrefとして実施することもできるし、又はデータノード内に含まれたマニフェスト外部キー値として実施することもできる。
逆Keyref
全ての多対1トラバースは、1対多のトラバースを定義する逆keyrefを宣言してもよい。
マニフェストKeyref
あるnodetypeのスキーマ宣言は、外部キー値を各々含むエレメントの中継シーケンスを含む複雑なXML文書を定義してもよい。

以下のスキーマ定義は、購入注文エンティティを記述する。
<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>
以下のキー宣言は、購入注文nodetypeに対して一次キーを定義する。
<xsd:key name=”purchaseOrderKey”>
<xsd:selector xpath=”purchaseOrder”/>
<xsd:field xpath=”id”/>
</xsd:key>
以下のkeyref宣言は、製品を参照する外部キーである購入注文内のエレメントを識別する。
<xsd:keyref name=”purchaseOrderProductRef” refer=”productKey”
mas:alias=”purchaseOrder:products”>
<xsd:selector xpath=”purchaseOrder/lineItems/lineItem”/>
<xsd:field xpath=”prodId”/>
</xsd:keyref>
この関係は、図12Aにより説明することができる。例えば、次のXScript表現は、購入注文の第1ラインアイテムにより参照される製品を検索する。
var product = purchaseOrder.@@products.*;
多対多
多対多の関係は、1対多の関係の対として実施される。その一例が図12Bに示されている。
即ち、アカウント及び事象は、次のスキーマを宣言する。
<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>
次のkeyref定義を宣言する。
<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>
一実施形態において、多対多keyrefは、逆keyrefを宣言することができない。というのは、一般に、フレームワークが、一貫性を維持するに充分な情報をもたないからである。
1対1
一実施形態において、1対1の関係は、対にされた多対1の関係として実施される。

又、システムの各ユーザは、図12Cに示すコンタクトレコードも有すると仮定する。
即ち、コンタクト及びユーザは、次のkeyrefを定義する。
<xsd:keyref name=”userContactRef” refer=”contactKey” mas:alias=”contact”
mas:inverseAlias=”user”>
<xsd:selector xpath=”user”/>
<xsd:field xpath=”@contactId”/>
</xsd:key>
1対1のkeyrefは、常に、逆keyrefを宣言しなければならない。
var contact = user.@@contact;
contact.@@user == user;
システムデータタイプ
ノードスキーマ定義
次のXMLスキーマは、ノードの構造を定義する。
<?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>
ノード定義は、次の属性を含んでもよい。
Figure 0004551899
ルートノード
一実施形態において、各アプリケーションに対して、nodetype mas:rootをもつ特殊なルートノードがあり、このノードは、アプリケーションデータを含まず、そして変更されることがない。フレームワークは、$root変数を経て参照されるルートノードのインスタンスを自動的に生成する。keyrefは、mas:rootをそれらのソースタイプとして参照してもよく、例えば、次の通りである。
<keyref name=”accounts” sourceType=”mas:root” targetType=”app:contact”/>
一実施形態では、ノードは、クライアントプログラミングによりインスタンス生成されてもよいし又はサーバーコンジットによりインスタンス生成されてもよい。
nodesetスキーマ定義
ルートノードはさておき、全てのノードは、keyrefに対応するnodesetに属する。nodesetは、次のXMLスキーマにより定義される。
<?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>
<nodeset>エレメントは、<node>エレメントのアンバウンドシーケンスを含む。各nodesetは、コンテインズ・ノードエレメント(the contains node elements)のnodetypeを決定するkeyref(keyref属性により定義される)に対応する。
同期状態
全ての持続性アプリケーションデータは、サーバーで同期されるノードに記憶することができる。各データノードは、syncStateTypeタイプにより定義される値を有する状態同期属性mas:stateをもつことができる。
<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>
状態変数は、同期を整合するためにクライアントとサーバーとの間に通すことができる。クライアントは、ノード状態を次の値の1つにセットする。
Figure 0004551899
一実施形態において、状態変数は、生成されたノードと変更されたノードとの間を区別しないことに注意されたい。というのは、これは、ゼロのグローバルシーケンスナンバーにより区別できるからである。
同期プロセスは、対応するコンジットオペレーションをトリガーし、完了時に、サーバーは、各ノードに、次の値の1つを指定する。
Figure 0004551899
例えば、次のテーブルは、ノードの考えられるライフサイクルを示す。
Figure 0004551899
コンジット
一実施形態において、クライアントアプリケーションは、ウェブサービスオペレーションを直接コールせず、むしろ、コンジットメカニズムが、個々の(限定された)ウェブサービスオペレーションのセマンティックスを、クライアントの仮想XML文書に対してプログラミングモデルへマップする(例えば、CRUDセマンティックス(生成、読み取り、更新、削除)、ナビゲーション、顧客オペレーション等)。クライアントデータモデルの変化は、サーバーに対して同期され、サーバーは、次いで、コンジットマネージャーをトリガーして、外部のウェブサービスオペレーションを呼び出す。
一実施形態において、コンジットは、特定のkeyrefに対して整合された1組のウェブサービスオペレーションを定義する。各keyrefには、厳密に1つのコンジットを関連付けることができる。ウェブサービスは、データベース、LDAPディレクトリー、ERPアプリケーション、及びウェブサイトのような既存のシステムへのインターフェイスでよい。又、それらは、手順ロジック(例えば、WLI JPD)により整合された複雑な長時間実行の非同期プロセス(ワークフロー)を要約するラッパーでもよい。
一実施形態において、システムにより利用されるウェブサービスは、幾つかの要件(例えば、各レコードは、独特の一次キー、及び理想的には、シーケンスナンバー又はタイムスタンプを含まねばならない)を有するが、随時接続データモデル特有の要件は課せられない。それ故、MASは、これらリソースの多数の消費者の1つでよい。
一実施形態において、コンジットは、ウェブサービスがデータモデルと共に記憶書き込みされたと仮定せず、即ち要求へ通されるタイプがデータモデルにおけるnodetypeと同形でなく、そして応答も異なることがある。それ故、ウェブサービス要求及び応答により使用されるスキーマは、データモデルにおけるノードのスキーマと同じである必要はない。
コンジットは、ウェブサービスオペレーション呼び出しに対してデータモデルから要求文書へマップすると共に、ウェブサービス応答からデータモデルへマップして戻すためのメタデータを含むことができる。これらメタデータは、変換として知られており、XML問合せ言語で表現することができる。実際に、変換モデルは、データモデルにおける多数の異なる関係ノードへとマップし且つデータモデルへ首尾良くマップして戻るような応答文書をウェブサービスが返送できるのに一般的に充分である。
MASキャッシュにとって重要なメタデータ(即ち、レコードタイプの一次キー及びシーケンスナンバー/タイムスタンプ)も、変換を使用してマップすることができる。
コンジットフローの概要
conduitsサブディレクトリーは、多数の.jsxファイルを含むことができ、それらは全て始動時にフレームワークによりロードされ、これらのファイルは、コンジット定義を含む。コンジットファイルは、コンジットオペレーションを実施するXScript及びXQueryファンクションで構成することができ、又、これらファイルは、コメントブロックで定義されたメタデータも含むことができる。注釈モデルは、デベロッパが視覚ツール及びスクリプトエディタの両方を使用してコンジットファイルを構築できるようにする。
各コンジットファイルは次のタグを宣言できるヘッダーコメントを含むことができる。
Figure 0004551899
例:
/**
* @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”
*/
mas:conversational
mas:conversationalタグは、次の属性を有する。
Figure 0004551899
common:xmlns
common:xmlnsタグは、次の属性を有する。
Figure 0004551899
ウェブサービスコントロール
又、コンジットファイルは、ウェブサービスコントロールを表わす(おそらく多数の)オブジェクト宣言も含む。コントロール定義は、対応する変数宣言の直前でヘッダーブロックに現われる。

/**
* @common:control
* @jc:location http-url=”http://enterprise.soap.sforce.com/”
*/
ws = new WebServiceControl();
次のタグが定義される。
Figure 0004551899
jc:location
jc:locationタグは、次の属性を有する。
Figure 0004551899
WebServiceControlオブジェクトは、ウェブサービスオペレーションの呼び出しをマネージする。
WebServiceControlオブジェクトは、次のメソッドを実施する。
Figure 0004551899
メッセージオブジェクト
メッセージオブジェクトは、ウェブサービスコントロールのinvoke()ファンクションへ通され及びそこから返送される。
var. Response = control. Invoke (message);
メッセージオブジェクトは、次のプロパティを有する。
Figure 0004551899
例えば、次のSOAPメッセージがウェブサービスから返送されると仮定する。
<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>
次のファンクションは、最初に、メッセージヘッダーからのセッションエレメント及びメッセージ本体からの結果エレメントをプリントする前にinvoke()ファンクションによりエラーが発生されなかったことをチェックする。
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
オペレーションの定義
コンジットオペレーションは、ウェブサービスオペレーションへ直接マップすることができる。一実施形態では、各コンジットオペレーションは、次の3つのファンクションまで宣言する。
1.要求変換:出て行くメッセージ本体を生成するXQueryファンクション;
2.応答変換:到来する応答本体を処理し、コンジットマネージャーにより処理されたMASノードを生成するXQueryファンクション;
3.カスタムファンクション:カスタム手順ロジックを実行する(例えば、メッセージヘッダーを生成し、又はカスタムトランスポート又は他のコントロールを呼び出すために)XScript(又はJava(登録商標。以下同じ。))ファンクション。
注釈
カスタムファンクションは、ファンクションプロートタイプの直前でヘッダーブロックに注釈も含む。例えば、
/**
* @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);
}
カスタムファンクションは、次のタグを宣言できる。
Figure 0004551899
mas:operation
mas:operationタグは、次の属性を有する。
Figure 0004551899
これらオペレーションは、keyref又はスキーマ(ノード)定義のいずれかを参照できる。
@mas:operation type=”operationType” keyref=”keyrefName”
@mas:operation type=”operationType” node=”nodeType”
inverse属性は、オペレーションが逆のkeyrefにおいてコールされることを指示する。
@mas:operation type=”operationType” keyref=”keyrefName” inverse=”true”
例えば、次のkeyref及びkey定義が与えられると、
<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);
}
トラバースcontact.@@accountは、selectAccount()をコールし、一方、account.@@contacts.*は、selectContacts()をコールする。
mas:transform
mas:transformタグは、次の属性を有する。
Figure 0004551899
フレームワークは、対応する@mas:transformタグが宣言された場合に、要求及び応答変換を自動的にコールすることができる。要求変換は、$msg変数の本体を構成するのに使用されるXMLオブジェクトを返送することができる。応答変換は、コンジットオペレーションの応答を処理することができる。
Javaでは、要求及び応答の問合せ変換が、カスタムオペレーションのためのコメントブロック(自動的に発生される)内に含まれるか、又は注釈により参照される個別のファイルに含まれる。
mas:namespace
mas:namespaceタグは、ファンクションのためのデフォールトnamespaceを宣言し、そして次の属性を有する。
Figure 0004551899
mas:field
mas:fieldタグは、ファンクションをコールするのに必要なカスタムソースフィールドを宣言し、次の属性を有する。
Figure 0004551899
発生されたファンクション
カスタムファンクションの本体は、WLWにより発生される。セレクトオペレーションに対するデフォールト本体は、次の通りである。
/**
* @mas:operation type=”select” keyref=”keyrefName”
*/
function operationTypeSourceType($msg, $source) {
return control.invoke($msg);
}
$msg変数は、XMLメッセージオブジェクトを参照し、マッチング要求変換が宣言された場合に(以下を参照)、メッセージオブジェクトの本体が、問合せにより返送されたXMLオブジェクトから生成される。$source変数は、ソースコンテクストノード(例えば、node.@@keyrefName.*)を含むことができる。
挿入、更新及び削除オペレーションに対して、デフォールト本体は、次の通りである。
/**
* @mas:operation type=”insert|update|delete” keyref=”keyrefName”
*/
function operationTypeSourceType($msg, $node) {
return ws.invoke($msg);
}
$node変数は、挿入/更新/削除されるべきノードを含む。
カスタムオペレーションに対して、本体は、次の通りである。
/**
* @mas:operation type=”custom” node=”nodeName” name=”operationName”
*/
function operationTypeSourceType($msg, $source, $node) {
return ws.invoke($msg);
}
ここで、$node変数は、カスタムオペレーションをコールするクライアントにより生成された問合せオブジェクトを含む。
変換
オペレーションは、任意であるが、mas:transform注釈を使用して要求及び応答変換ファンクションを定義することができる。
例えば、以下のオペレーションは、アカウント識別子(即ち、contactAccountRefにより定義された逆keyref)が与えられると、コンタクトを検索するセレクトオペレーションを実施する。
/**
* 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);
}
要求変換は、コンジットオペレーションが呼び出される前にコールすることができ、アウトバウンドメッセージのXML本体を返送し、これは、コンジットオペレーションへ通されるメッセージオブジェクト$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>
}
応答変換は、コンジットオペレーションが復帰した後にコールすることができる(オペレーションが<error>オブジェクトを返送しない限り)。サービスコントロールのinvoke()ファンクションから返送されたXMLメッセージ本体が通される。応答変換は、アプリケーションノードのリストをコンジットマネージャーに返送する。
/**
* @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>
}
コンジットオペレーションは、応答変換によりサービス応答メッセージの本体が処理される前にそのヘッダー及び本体を操作できることに注意されたい。
コンジットオペレーション
コンジットオペレーションは、ウェブサービスオペレーションをフレームワークオペレーションへマップすることができ、このフレームワークオペレーションがアプリケーションプログラミングモデルへ露出される。
各オペレーションは、関連ウェブサービスオペレーションから受け取られた及びそこに送信される到来する及び出て行く対応XMLメッセージをマップする一対の問合せを定義することができる。これらの変換は、(通常)外部システムデータフォーマットから、スキーマにより定義されたMASアプリケーションデータフォーマットへデータを変換するXQuery表現で構成される。
オペレーションタイプ
クライアントプログラミングモデルでは、ノード($rootを含む)又はkeyrefのいずれかにおいてオペレーションを呼び出すことができる。例えば、
$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
オペレーションタイプに基づいて、異なる入力パラメータをコンジットオペレーションへ通すことが要求される。
更新及び削除を除いて、他の全てのオペレーションにはオペレーションのコンテクスト(又はソース)を表わすノード(その一部分)が通される(mas:field宣言は、ソースノードのどれほど多くがサーバーに転送されるか決定する)。これは、$source変数を使用してコンジットファンクションにより参照される。
更新オペレーション(即ち、挿入、更新及びカスタムオペレーション)の場合に、コンジットオペレーションを呼び出すのに使用されるデータノードが、$node変数を使用してXQuery変換において参照される。更に、全てのオペレーションは、現在ユーザの情報を含む$userシステム変数への暗示的アクセスを有する。
コンジットオペレーションに対して以下の入力パラメータが定義される。
Figure 0004551899
以下のテーブルは、特定のコンジットオペレーションに対して定義できる異なるタイプのオペレーションを示す。
Figure 0004551899
変換
各コンジットオペレーションは、関連ウェブサービスオペレーションから受信され及びそれに送信される到来する及び出て行くXMLメッセージに対応するXMLオブジェクトを生成して処理する一対の問合せ(変換)を定義することができる。
変換ファンクションは、対応するコンジットファンクションにおけるmas:transform注釈を使用して宣言することができる。規定により、変換ファンクションのネームは、_request及び_responseサフィックスを伴いコンジットファンクションと同じネームを使用することができる。しかしながら、あるケースでは、応答変換は、多数のコンジットオペレーションにより再使用されてもよい。
変換は、XQuery(XML Query)ファンクションとして実施することができる。

次のオペレーションは、アカウント識別子(即ち、contactAccountRefにより定義された逆keyref)が与えられると、コンタクトを検索するセレクトオペレーションを実施する。
/**
* 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>
}
要求変換は、queryウェブサービスオペレーションを呼び出すSOAPメッセージの本体を構成することができる。応答変換は、ウェブサービスオペレーションの応答SOAPメッセージの本体を処理し、そして1組の<contact>ノードを構成する。
要求変換
要求変換は、フレームワーク及びデータモデルエレメントから出て行くウェブサービスメッセージを生成することができる。オペレーションタイプに基づいて(上記のオペレーションテーブルを参照)、変換は、オペレーションに対するコンテクストを与える次のシステム変数を参照することができる。
Figure 0004551899
上記selectコンジットオペレーションメソッドは、queryウェブサービスオペレーションを呼び出し、これは、以下のXMLスキーマ定義に合致する本体を伴うSOAPメッセージを期待する。
...
<element name=”query”>
<complexType>
<sequence>
<element name=”queryString” type=”xsd:string”/>
</sequence>
</complexType>
</element>
...
以下の変換は、問合せに必要なAccountIdを指定するために、$sourceシステム変数を参照する。
/**
* @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>
}
例えば、これは、次のような、出て行くSOAPメッセージ本体を発生し得る。
<query xmlns=”urn:enterprise.soap.sforce.com”>
<queryString>SELECT * FROM Contact WHERE AccountId = 1000</queryString>
</query>
応答変換
応答変換は、到来するウェブサービスメッセージを処理し、そしてコンジットマネージャーにより処理されるノード(又はnodeset)を生成する。全ての応答変換は、次のシステム変数を参照することができる。
Figure 0004551899
上記の例に続いて、queryウェブサービスオペレーションは、次のXMLスキーマに対応するSOAPメッセージを返送する。
...
<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>
...
各<QueryResult>エレメントは、一連の<sObject>エレメントを含み、これは、<Contact>スキーマタイプに対する基本タイプである。
<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”/>
例えば、到来するSOAPメッセージ本体は、次の形態をとってもよい。
<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システム変数は、最上位レベル<queryResponse>エレメント(SOAPメッセージ本体内)を指す。それ故、次のXPath表現は、<Contact>エレメントのアレーを参照するのに使用されねばならない。
$response/sfdc:queryResponse/sfdc:result/sfdc:records
以下の変換は、到来するSOAPメッセージを処理し、そして<contact>エレメントのリストを生成する。
/**
* @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>
}
全ての要求変換は、サーバーによりキャッシュ記憶されると共にクライアントのデータモデルと同期されるノードを発生する。
許可
コンジットにより定義されるオペレーションは、クライアントの対応するnodesetにおいて呼び出すことのできるオペレーションを決定する。例えば、コンジットが挿入オペレーションを定義しない場合には、クライアントは、対応するnodesetに対するノードを生成及び挿入するように試みることができず、このように試みる場合には(例えば、カスタムアクションにおいて)、これがランタイムエラーをトリガーする。クライアント側のプログラミングモデルは、これらの制約を強いる。
例えば、accountが特定のアカウントノードを指し、そしてアカウントノードがorders keyrefに関連していると仮定する。この場合には、orders keyrefに関連したコンジット挿入オペレーションが定義されない限り、次のコードがエラーを招くことになる。
account.@quotes.create(
<quoteRequest>
<prodId>A1</prodId><qty>10</qty>
</quoteRequest>
);
同様に、コンタクトnodetypeに対して更新オペレーションが定義されない限り、次のコードもエラーを招くことになる。
contact.address.zip = ”11201”;
一実施形態では、クライアントオペレーション(例えば、create()ファンクション)の実施が、コンジットオペレーション(例えば、挿入)とマッチングされる。例えば、コンジットオペレーションの挿入は、ノードを挿入すると共に、keyref関係を使用してそれを別のノードへトラバースし、それ故、クライアントにおけるノードの生成は、対応するnodesetへのトラバースオペレーションと自動的に対にされねばならない。
実施されるコンジットオペレーションを記述するメタデータは、ユーザプログラミングモデルにアクセスできる(関連するkeyrefを経て)。自動的ユーザインターフェイスは、この情報を使用して、基本的メニュー(挿入、更新等)を発生することができる。
エラーハンドリング
コンジットメカニズムは、2種類のエラー、即ちシステムエラー(例えば、プロトコル及びトランスポートエラー)と、アプリケーションエラー(例えば、無効データ)との間を区別する。更に、アプリケーションエラーは、2つの異なる仕方で生じ、即ちSOAP欠陥(即ち、プロトコルレベルエラー)として、及びSOAP(又は平易XML)応答メッセージの一部分として生じ得る。
Figure 0004551899
コンジットオペレーションは、SOAPコールとして実施され、SOAP欠陥は、メッセージの処理にエラーが生じた場合に発生し、これは、インフラストラクチャー欠陥(例えば、トランスポート欠陥)によるか、プロトコル欠陥(例えば、不良に形成されたメッセージ)によるか、又はアプリケーション状態エラー(例えば、更新失敗)によるものである。出て行く又は到来するSOAPメッセージを生成又は処理するエラーがある場合に、システムエラーが生じる(例えば、XQuery変換エラー)。
外部アプリケーションが、メッセージ本体の一部分として通された値に基づいてオペレーション要求を拒絶する場合にアプリケーションエラーが生じる(例えば、更新失敗)。SOAP欠陥は、ウェブサービスコントロールにおけるinvoke()ファンクションの呼び出し中にSOAPスタックにより生じる。
通常、コンジットオペレーションにより返送されるXMLオブジェクトの本体は、応答変換により処理される。しかしながら、オペレーションがシステム<mas:error>オブジェクトを返送する場合には、このオブジェクトがコンジットマネージャーへ直接通される。メインコンジットファンクション又は応答変換のいずれが<mas:error>オブジェクトを返送してもよいことに注意されたい。
<mas:error>スキーマ定義を以下に示す。
<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: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>
各エラーオブジェクトは、エラーにより影響されるノードの一次キーを含んでもよい。セレクトオペレーションについては、これは、ソースノードの一次キーとなり、更新及び削除オペレーションの場合には、これは、更新されたノードを参照する。
システムエラーは、サーバーによりログすることができる。他の全てのエラー値は、クライアントへ返送し、そしてそれに対応するコールバックファンクションへ通すことができる。
エラーオブジェクトは、アプリケーションのコールバックファンクションへ返送され、このオブジェクトは、上記スキーマに対応するプロパティを有する。

次のオペレーションは、invoke()ファンクションの呼び出しがエラーを返送する場合にシステムエラーを返送する。
/**
* @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;
}
適当な場合に、失敗したinvoke()呼び出しを再試みするのは、コンジットオペレーションの責任である。この場合に、コンジットは、ウェブサービスオペレーションが等冪であるか、又はあるタイプの信頼し得るメッセージングを使用することを保証しなければならない。
次のオペレーションは、失敗時にinvoke()ファンクションを再試みした後にシステムエラーを返送する。
/**
* @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>;
}
次のオペレーションは、先ず、invoke()ファンクションがエラーを返送する場合にシステムエラーをチェックし、さもなければ、一般的なアプリケーションエラーを返送する。invoke()は成功であるが、ウェブサービス応答がアプリケーションエラーを含む場合には、エラーメッセージをパーズするためのユーティリティファンクションをコールし、そして多数の<field>エラーを含むことのあるコンパウンド<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>;
}
CRUDオペレーション
CRUD(生成読み取り更新削除)オペレーションは、4つの基本的な関係データオペレーションを表わす。これらのオペレーションは、MASデータモデル及びクライアントプログラミングモデルに直接マップすることができる。
ウェブサービスのコンタクトスキーマは、上記で定義されたアプリケーションのコンタクトスキーマとは異なる形状を有することに注意されたい。以下のセレクトオペレーションの例は、このマッピングをいかに行うか示す。
セレクト
セレクトオペレーションは、特定のソースノードに対してkeyrefにより定義されたノードをフレームワークが検索できるようにする。通常、全てのコンジットがセレクトオペレーションを定義する。というのは、これは、クライアントアプリケーションによりノードを検索するのに使用される基本的メカニズムだからである。
それに続くセレクトオペレーション(異なるkeyrefに対する)を呼び出して、データグラフを構成することができる。例えば、アカウントノードから購入注文keyrefへのナビゲーションは、AccountManagerウェブサービスのgetPurchaseOrdersオペレーションを呼び出し、次いで、購入注文ノードからラインアイテムkeyrefへのナビゲーションは、OrderManagerウェブサービスのgetLineItemsオペレーションをコールする。
セレクトオペレーションは、次の形態を有する。
/**
* @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);
}
セレクトオペレーションは、特定のソースnodetypeに対して定義されたkeyrefNameに対応するノードを検索するのに使用され、例えば、特定のコンタクトノードに対して外部キーにより参照されるアカウントを選択する。逆属性は、オペレーションが逆関係を実施することを定義し、例えば、外部キーを経ることにより特定のアカウントを参照する全てのコンタクトを選択する。
keyref定義は、次の形態をもつことができる。
<xsd:keyref name=”keyrefName” refer=”targetType”
mas:alias=”relationName” mas:inverseAlias=”inverseRelationName”>
<xsd:selector xpath=”sourceType”/>
<xsd:field xpath=”foreignKey”/>
</xsd:keyref>
関連用語において、セレクトオペレーションは、次のSQL表現に対応する。
SELECT * FROM keyref.targetType WHERE primary_key = $source/foreign_key
逆keyrefを実施するオペレーションは、次のSQL表現に対応する。
SELECT * FROM keyref.sourceType WHERE foreign_key = $source/primary_key
セレクトオペレーションの要求変換は、ウェブサービスオペレーションに対するメッセージ本体を生成することができ、オペレーションに対するコンテクストを与える次のシステム変数を参照することができる。
Figure 0004551899
セレクトオペレーションの応答変換は、応答メッセージ本体をノードのリストへマップすることができる。ノードエレメントは、keyrefにより対応するnodetype定義のためのアプリケーション定義スキーマに対応する。セレクトオペレーションの応答変換は、次のシステム変数を参照することができる。
Figure 0004551899
外部キーによるセレクト(多対1)
関連外部キーは、多対1(又は「ルックアップ」)関係を実施する。
例えば、次のスキーマ及びkeyref定義が与えられると、コンタクトノードのaccountId属性を、そのコンタクトが属するアカウントノードに対するポインタとして考えるのが自然である。
<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>
これは、次のクライアントトラバースを可能にする(@@演算子は、keyref定義のエイリアスネームを参照することに注意されたい)。
var account = contact.@@account;
次のコンジットオペレーションは、このkeyref関係を実施する。
/**
* @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>
}
このコンジットオペレーションファンクションは、プラットホームにより自動的に発生することができ、これは、accountOwnerRefのkeyref定義を参照できると共に、要求及び応答変換ファンクションに対する宣言(ツールにより発生された)を有する。
/**
* @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);
}
要求変換
要求変換は、アカウントノードを表わす$source変数を参照することができる。ファンクション注釈は、出て行くメッセージ文書の言語(XQuery)及びターゲットnamespaceを宣言することができる(コンジットファイルのヘッダー注釈で宣言されたnamespaceプレフィックスを参照する)。
又、ファンクションは、コンタクトノードの@accountId属性がファンクションにより要求されることを指示するフィールド注釈も宣言することができ、この宣言は、呼び出しているクライアントからサーバーへ外部キー値を同期要求の一部分として送信することを保証できる。
/**
* @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>
}
応答変換
応答変換は、ウェブサービスから返送されるメッセージのXML本体を表わす$response変数を参照することができる。又、ファンクション注釈は、コンジットマネージャーへ返送されるXMLオブジェクトの言語(XQuery)及びターゲットnamespaceも宣言することができる。
このファンクションは、単一レコードがウェブサービス<query>要求により返送されると仮定することができる。このファンクションは、これを、スキーマ定義に合致する対応一次キー(id)及びデータフィールド(シーケンスナンバーを表わす<modified>エレメントを含む)を伴う単一の<account>ノードへと変換することができる。
/**
* @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>
}
<account>ノードは、コンジットマネージャーへ返送できると共に、発呼アプリケーションへ戻るように同期させることができる。又、コンジットマネージャーは、ノードをサーバーのキャッシュへ入れるように選択してもよい。
逆のセレクト(1対多)
外部キーにより定義された多対1の関係は、もちろん、逆の方向に、1対多の関係として考えることができる。
前記セクションの場合と同じスキーマ及びkeyref定義が与えられると、個々のアカウントノードに属する1組のコンタクトノードを考えるのが自然である。
<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>
しかしながら、このとき、keyref定義のmas:inverseAlias属性を使用して、keyrefを逆方向にトラバースする。
var contacts = account.@@contacts.*;
次のコンジットオペレーションは、この逆のkeyref関係を実施する。
/**
* @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>
}
このコンジットオペレーションファンクションは、プラットホームにより自動的に発生することができ、これは、accountOwnerRefのkeyref定義を参照しそして要求及び応答変換ファンクションに対する宣言(ツールにより発生される)を有する。又、このオペレーションは、それが逆のkeyref関係を表わすことも宣言する。
/**
* @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);
}
要求変換
要求変換は、コンタクトノードを表わす$source変数を参照することができる。ファンクション注釈は、出て行くメッセージ文書の言語(XQuery)及びターゲットnamespaceを宣言する(コンジットファイルのヘッダー注釈で宣言されたnamespaceプレフィックスを参照する)。
又、ファンクションは、アカウントノードの@id属性がファンクションにより要求されることを指示するフィールド注釈も宣言することができ、この宣言は、呼び出しているクライアントからサーバーへ外部キー値を同期要求の一部分として送信することを保証できる。
/**
* @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>
}
応答変換は、ウェブサービスから返送されたメッセージのXML本体を表わす$response変数を参照することができる。又、ファンクション注釈は、コンジットマネージャーへ返送されるXMLオブジェクトの言語(XQuery)及びターゲットnamespaceも宣言することができる。
このファンクションは、多数のレコードがウェブサービス<query>要求により返送されると仮定することができる。ファンクションは、結果を通して繰り返し、そしてそれらを、1組の<contact>ノードへと変換する。各ノードは、スキーマ定義に合致する対応一次キー(id)及びデータフィールドを含むことができ、これは、アカウント外部キー(accountId属性)及びシーケンスナンバー(<modified>エレメント)を含む。
/**
* @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>
}
<contact>ノードは、コンジットマネージャーへ返送できると共に、発呼アプリケーションへ戻るように同期させることができる。又、コンジットマネージャーは、これらノードをサーバーのキャッシュへ入れるように選択してもよい。
非関連(コンテクストフリー)セレクト
外部キー値に依存しないノードとノードとの間の関係を定義することができる。例えば、現在ユーザ情報又は他の外部情報(例えば、日時、リアルタイムデータ、外部システム状態)を使用する問合せにより1組のノードが定義されてもよい。これらの場合に、nodesetは、データモデル内の任意のnodetypeにアタッチされてもよい。しかしながら、通常、これらのnodesetは、ルートノードにアタッチされる。
コンジットセレクトオペレーションは、keyref定義を参照することができ、コンテクストフリーのセレクトは、定義により、ソースノードのコンテクストを要求しないので、一実施形態では、それらが常に逆のkeyrefにおいて実施される。
次の例は、CRM demoにおいて、現在ユーザに対する1組のアカウントがコンジットセレクトオペレーションによりいかに検索されるかを示す。アカウントnodetypeは、次のキー定義を有する。
<xsd:key name=”accountKey” mas:alias=”accounts”>
<xsd:selector xpath=”account ”/>
<xsd:field xpath=”@id”/>
</xsd:key>
mas:alias属性は、アカウントのnodesetがルートノードからトラバースできることを指示し、即ち
var accounts = $root.@@accounts.*;
コンジットは、逆のkeyrefセレクトオペレーション(上述した)と同様に実施することができる。
/**
* @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>
}
要求変換
要求変換は、ウェブサービスへ送信される要求問合せを構成するのに使用される$userシステム変数を参照することができる。
/**
* @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>
}
この場合に、サービスは、現在ユーザにより所有される(即ち、現在ユーザのIDにマッチするOwnerId外部キーを有する)全てのアカウントを選択するジョイン問合せを実施することができる。この変換は、$source変数を参照しないことに注意されたい。
応答変換
応答変換は、先のセクションで定義された応答変換と同様に、ウェブサービスオペレーションにより返送される1組のアカウントを処理することができる。
/**
* @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>
}
@mas:rootId属性は、1組の<account>ノードがそこに返送されたときにコンジットマネージャーにより自動的に計算できることに注意されたい。
挿入
挿入オペレーションは、クライアントアプリケーションが新たに形成されたノードをサーバーに同期させるときにコンジットマネージャーによりコールすることができる。
クライアントにおいて、ノードは、2つの方法の1つで生成することができ、即ちcreate()ファンクションは、keyref又はルートノードのいずれかにおいてコールすることができる。
var node = source.@@keyref.create(<xml>); // contextual create
var node = $root.create(<xml>); // context free create
両方の場合に、ノードのXMLオブジェクトだけを(即ちソースノードではなく)サーバーへ転送することができる。これは、コンテクスト生成オペレーションの場合に、ノードが、ソースノードを参照する外部キー値を含まねばならないからであり、この値は、keyref定義に基づいてフレームワークにより自動的にセットされる。
挿入オペレーションは、次の形態を有する。
/**
* @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);
}
挿入オペレーションは、nodeName宣言により参照されるスキーマに対応するノードを生成するのに使用できる。
挿入オペレーションの要求変換は、ウェブサービスオペレーションに対するメッセージ本体を生成し、これは、オペレーションに対してコンテクストを与える次のシステム変数を参照することができる。
Figure 0004551899
挿入オペレーションの応答変換は、応答メッセージ本体を、ウェブサービスにより生成されたレコードの一次キー(及び任意であるがシーケンスナンバー)を含む部分的に構成されたノードへとマップすることができる。挿入オペレーションの応答変換は、次のシステム変数を参照することができる。
Figure 0004551899
ノードの一次キー(及び任意であるがシーケンスナンバー)は、コンジットマネージャーへ返送することができ、コンジットマネージャーは、この情報を再びクライアントに同期させる。ノードは、最初に、一時的な一次キーでクライアントにおいて生成され、この値は、外部システムの一次キーと置き換えねばならない。
ノードは、通常、他のノードを参照する外部キー値を含む。互いに参照するクライアントにおいて多数のノードが生成される場合には、システムは、挿入コンジットオペレーションが適当な依存順序でコールされ且つウェブサービスから返送される一次キー値が保留ノードに対する一時的外部キー値との交換に使用されるよう保証しなければならない。
非関連性挿入
一実施形態において、非関連性挿入オペレーションは、データモード内の他のnodetypeを参照する外部キーをもたない。例えば、ユーザnodetypeは、次のスキーマにより定義することができる。
<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)}”/>
}
要求変換
要求変換は、アプリケーションにより生成されたユーザノードを表わす$node変数を参照することができる。ファンクションの注釈は、出て行くメッセージ文書の言語(XQuery)及びターゲットnamespaceを宣言することができる(コンジットファイルのヘッダー注釈で宣言されたnamespaceプレフィックスを参照する)。
/**
* @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>
}
応答変換
応答変換は、ウェブサービスから返送されたメッセージのXML本体を表わす$response変数を参照することができる。このファンクションの注釈は、コンジットマネージャーへ返送されるXMLオブジェクトの言語(XQuery)及びターゲットnamespaceも宣言することができる。
成功時に、ウェブサービスは、次のスキーマ定義に合致するメッセージ本体を返送することができる。
<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>
この変換は、アプリケーションのスキーマにより定義された一次キー属性(id)を含む部分的に構成された<user>ノードを生成することができる。
/**
* @language:body type=”xquery”
* @mas:namespace target=”app”
*/
function insertUser_response($response) {
<user id=”{string($response/sfdc:createResponse/sfdc:result/sfdc:id)}”/>
}
この一次キー値は、コンジットマネージャーにより処理できると共に、クライアントアプリケーションと同期させることができる。
関連性挿入
関連性挿入は、キャッシュ内の他のノードを参照する外部キー値を含むノードを伴うことができる。
例えば、以下のコンタクトスキーマは、所有者ノード(@ownerId)及びアカウントノード(@accountId)に対する外部キーを定義する。
<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>
最初に、コンタクトXMLオブジェクトは、XScript指定により構成されてもよい。
var contact =
<contact>
<first>Sarah</first>
<last>Smith</last>
<email>sarah@acme.com</email>
</contact>;
外部キーを含むノードは、多数のやり方で生成されてもよい。上述したコンタクトXMLオブジェクトと、所有者及びコンタクトノードを表わす変数とが与えられると、次のファンクションは、ルートノードにおけるcreate()ファンクションをコールすることによりコンタクトノードを生成する。外部キーは、create()がコールされる前にセットされねばならないことに注意されたい。
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;
}
これら両方のケースにおいて、欠落した外部キーは、ノードがサーバーに対して同期される前にフレームワークにより供給されることに注意されたい。それ故、ノードがアプリケーションによりいかに生成されるかに関わらず、コンジットオペレーションは、nodetypeにバインディングするだけでよい。コンジットオペレーションは、先のセクションで定義したオペレーションと同じ仕方で実施することができる。
/**
* @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);
}
ユーザノードに対するコンジット挿入オペレーションは、コンタクトノードに対するコンジット挿入オペレーションの前にコールされ、そしてそのコンタクトノードのownerId属性は、第1コンジットオペレーションから返送される適切な外部キー値を含む。
シーケンスナンバー
ある場合に、ノードを生成するためにコールされるウェブサービスメソッドは、シーケンスナンバーを返送しないことがある。コンジットは、単一のコンジットオペレーション内で多数のウェブサービスコールを行って、この情報を検索することができる。
例えば、先のセクションで定義されたコンジットオペレーションは、次のように拡張される。
/**
* @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>
}
コンジットファンクション
しかしながら、この場合に、コンジットの自動的に発生されたXScriptファンクションは、2つのウェブサービスコールを呼び出すように変更することができる。第1に、要求変換から返送されるメッセージを使用して、ノードを挿入し、そして挿入されたノードの一次キーを検索することができる。
/**
* @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;
次いで、挿入されたノードの一次キーidを、コンジットで定義されたヘルパーXQueryファンクションrequestTimestamp()へ通すことにより、新たなメッセージオブジェクトが生成される。
// retrieve sequence number
var msg2 = createMessage(requestTimestamp(id));
var response2 = ws.invoke(msg2);
ヘルパーファンクションは、変換と同じ言語及びnamespace注釈を宣言するが、それらは、コンジットオペレーションの注釈により参照されない。このファンクションは、新たに生成されるノードに対するシーケンスナンバーを返送するコンジットオペレーションを呼び出すように適当なメッセージを構成する。
/**
* @language:body type=”xquery”
* @mas:namespace target=”sfdc”
*/
function requestTimestamp($id) {
<query>
<queryString>
SELECT Id, SystemModstamp FROM Contact
WHERE Id = ”{$id}”
</queryString>
</query>
}
最終的に、両ウェブサービスオペレーションの結果は、両メッセージ本体で構成される単一のXMLオブジェクトを生成することにより合成できる。
// return both responses
response.body += response2.body.sfdc:queryResponse;
return response;
}
応答変換
応答変換は、コンジットファンクションにより生成されたXMLオブジェクトを処理し、そして一次キーとノードのシーケンスナンバーの両方を含む単一の<contact>ノードを返送することができる。
/**
* @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>
}
更新
更新オペレーションは、クライアントアプリケーションがノードを変更したときにコンジットマネージャーによりコールすることができる。
エンタープライズがデータの更新を要求されたときに、それを拒否するポリシー/プロセスがあるか、又は誰か他のものがデータを最初に変更したために、拒絶することが考えられる。第1の問題は、不可避であり、そして他の全てと同様に、更新オペレーションが失敗をハンドリングできることを要求する。フレームワークは、第2のケースに対する楽観的同時性モデルを実施することができる。
更新要求は、それがウェブサービスオペレーションへ送信されるときに、変更された値を含むだけでなく、レコードが変更されたときにそれが最新のものであったかどうか決定するのに使用できるシーケンスナンバーも含むことができる。(コンジットマネージャーcabは、セレクトオペレーションのウェブサービスがそれ自身のシーケンスナンバーを返送しない場合にノード値に基づいてMD5ハッシュを計算する。)
クライアントにおいて、ノードは、スクリプト表現によって変更され得るが、更新は、update()ファンクションが特定ノードにおいてコールされるまでサーバーと同期されず、例えば、
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);
}
オペレーション注釈は、アプリケーションスキーマに対応するnodetype宣言する。
更新オペレーションの要求変換は、ウェブサービスオペレーションに対するメッセージ本体を生成することができ、これは、オペレーションのためのコンテクストを与える次のシステム変数を参照することができる。
Figure 0004551899
更新オペレーションの応答変換は、応答メッセージ本体を、変更されたレコードのシーケンスナンバーを含む部分的に構成されたノードへとマップすることができる。更新オペレーションの応答変換は、次のシステム変数を参照することができる。
Figure 0004551899

次のファンクションは、コンタクトノードに対する更新コンジットオペレーションを実施する。
/**
* @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>
}
要求変換は、ノードの一次キーと、レコードがサービスから検索されたときにタイムスタンプを表わすエレメントLastModifiedDateとにおいて通過させることができる。これは、ウェブサービスオペレーションを楽観的同時性で実施できるようにし、即ちオペレーションへ送信されたタイムスタンプ値が現在システムタイムスタンプ値に一致しない場合に、オペレーションが失敗となる。
コンジットファンクション
挿入オペレーションと同様に、コンジットの自動的に発生されたXScriptファンクションは、2つのウェブサービスコールを呼び出すように変更することができる。第1に、要求変換から返送されるメッセージを使用して、ノードを更新する。
/**
* @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);
次いで、更新されたノードの一次キーidを、コンジットで定義されたヘルパーXQueryファンクションrequestTimestamp()(これは、上述した挿入オペレーションに対して定義された同じファンクションである)へ通すことにより、新たなメッセージオブジェクトを生成することができる。
// retrieve sequence number
var msg2 = createMessage(requestTimestamp(id));
var response2 = ws.invoke(msg2);
最後に、第2のウェブサービスオペレーションの結果を返送して、応答変換により処理することができる。
return response2;
}
応答変換
応答変換は、コンジットファンクションにより生成されたXMLオブジェクトを処理して、一次キー及びノードのシーケンスナンバーの両方を含む単一<contact>ノードを返送することができる。
/**
* @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は、クライアントが更新しようと試みるものより最近のバージョンのノードをキャッシュ記憶した場合に、更新されたノードで直接応答し(即ち、コンジットオペレーションを呼び出すことなく)、mas:state属性を「conflict(競合)」にセットすることがある。
ノードが古いためにコンジットオペレーションが更新を拒絶する場合には、最新のノードを適当なmas:state属性と共に返送することができ、これは、最新のノードを選択するための別のラウンドトリップを伴うことがある。

次の更新オペレーションファンクションは、ウェブサービスにより返送されるエラー値をチェックする。要求変換は、上記で定義されたものと同じである。
/**
* @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>
}
コンジットファンクション
コンジットファンクションは、第1に、ウェブサービスにより返送されるエラー値をチェックすることができる。
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);
次いで、オペレーションは、expando state属性を生成し、競合レコードがサーバーから検索されたことを応答変換で検出できるようにする。
// 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;
}
応答変換
応答変換は、最初に、state expando属性がコンジットオペレーションにより生成されたかどうか調べるためのチェックを行うことができる。もしそうであれば、この変換は、完全なノードエレメントを構成することができ、さもなければ、上述したように、一次キー及びシーケンスナンバーのみを返送することができる。
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>
}
リンキング及びアンリンキング(外部キーの変更)
ノードは、XScript表現により変更することができる。これは、外部キー値についても適用される。このセクションの例は、アカウント及びコンタクトnodetypeを使用し、これらは、次のキー定義を宣言する。
<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();
}
ここで、外部キーは、次のkeyref宣言により定義される。
<xsd:keyref name=”contactAccountRef” refer=”accountKey” mas:alias=”account”>
<xsd:selector xpath=”contact”/>
<xsd:field xpath=”@accountId”/>
</xsd:keyref>
同様に、以下のファンクションは、+=演算子(a.k.a.link()ファンクション)を使用して、コンタクトノードを、アカウントに対する1組のコンタクトに追加する。
function bar(account, contact) {
account.@@contacts += contact;
}
この1対多の関係は、逆の関係を含む次のkeyref宣言により定義される。
<xsd:keyref name=”contactAccountRef” refer=”accountKey”
mas:alias=”account” mas:inverseAlias=”contacts”>
<xsd:selector xpath=”contact”/>
<xsd:field xpath=”@accountId”/>
</xsd:keyref>
実際に(即ち、外部データベースでは)、このオペレーションは、コンタクトエンティティ(行)のaccount外部キーをアカウントの一次キーにセットすることにより実施できる。ソースノードにおいて外部キー値をセットすると(例えば、contact.@@accountId)、当然、ターゲットノードからソースノードへの逆のトラバース(例えば、account.@@contacts.*)が可能になるはずであり、そしてそれとは逆のことも言える。
上記定義が与えられると、次のファンクションが同等である。
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);
}
一実施形態では、スキーマの外部キーエレメント(又は属性)宣言は、外部システムの制約(又はウェブサービスオペレーションのセマンティックにより課せられたもの)に一致する。特に、NOT NULL外部キー値(例えば、データベーステーブルフィールドにおいて宣言された)は、属性の場合にはxsd:use”required”そしてエレメントの場合にはminOccurs=”1”maxOccurs=”1”により鏡像とならねばならない。
例えば、上記定義が与えられると、次のファンクションは、ランタイムエラーを発生することになる。
function foo(contact) {
contact.first = $context.first;
contact.last = $context.last;

contact.@@accountId = null;

update(contact);
}
カスタム問合せ
データは、2つのnodetype間の定義されたkeyref関係に関連するセレクトコンジットオペレーションを実施することにより検索することができ、即ち1つのノード内に含まれた外部キー値は、関連ノードの一次キーを識別する。これらのセレクトオペレーションの出力は、フレームワークによりローカルキャッシュへと収納されるノードである。
カスタム問合せは、クライアントプログラミングモデルにとって不透明で、即ち一次キー及び外部キー関係に排他的に基づいてデータを明確に選択(又は変更)しないコンジット問合せ(又は他の手順ロジック)である。例えば、サーチオペレーションが、自然言語表現に一致する1組のXMLオブジェクトを返送してもよい。
図8のマトリクスにより異なる種類のオペレーションが特徴付けられる。これらのオペレーションは、一時的データ又は永久的データとして分類される入力及び出力を有する。一実施形態では、一時的データは、アプリケーションのノードグラフの一部分ではなく、即ちスキーマ、key又はkeyref宣言により定義されず、そしてフレームワークによりローカルキャッシュへ自動的に収納されない。一時的データは、持続すると仮定されないが、クライアントアプリケーションフレームワークにより決定されたライフサイクルを有するシステム$context又は$session変数により参照されてもよい。永久的データは、スキーマにより定義されたアプリケーションデータノードで全体的に構成することができる。
一実施形態において、カスタム問合せを実施するための2つのメカニズムがある。
1.カスタムオペレーションは、クライアントが、不透明な一時的XMLオブジェクト(文書)を特定のコンジットオペレーションへ通過させるのを許すことができる。このオペレーションは、一時的なXML文書をクライアントコールバックへ非同期で返送することができる。
例えば、次のカスタムオペレーションmyQueryは、XMLオブジェクト<myRequest>を入力として取り出し、そしてXMLオブジェクトmyCallback()ファンクションを返送する。
$root.myQuery(<myRequest>product mobile application</myRequest>, myCallback);

function myCallback(myOutput) {
...
}
2.カスタムオブジェクトは、グラフの一部分となる非永続的モデル(スキーマにより定義された)の生成を伴うことができる。このオペレーションは、クライアントがそれに対応するkeyrefを「通してトラバース」するときに呼び出すことができ、この場合、カスタムオブジェクトは、$sourceノードとしてそれに対応するセレクトコンジットオペレーションへ通過される。
例えば、次のカスタムオブジェクト<takeQuery>が、タスクノードをtaskQueryノードに関連付けるkeyrefとして定義されたセレクトコンジットオペレーションへ送信される。
var query = $root.@@taskQueries.create(<taskQuery priority=”1”/>);

var tasks = query.@@tasks.*;
カスタムオペレーション
カスタムオペレーションは、カスタムコンジットオペレーション(ファンクション)をコールするためのメカニズムである。ファンクション入力及び出力は、両方とも、XML文書リテラル(スキーマにより定義されない)である。一実施形態では、フレームワークは、結果をローカルキャッシュへ直接収納しない。
例えば、eメールの受信から手を引いていないコンタクト(特定アカウントに対して)のための1組のeメールアドレスの検索を希望すると仮定する。
次のコードクライアントコードは、XMLオブジェクト<query>が通されたカスタムオペレーションgetListをコールする。
function bar() {
account.getList(<query optedOut=”false”/>, callback);
}

function callback(result) {
for (i = 0; i < result.length; i++) {
addAddress(result[i].email);
}
}
コールバックは、MASから結果が返送されたときにそれを処理する。
以下のXQueryファンクションは、カスタム要求を実施する。
/**
* @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>
}
ウェブサービスからの応答は、次のファンクションにより処理できる。結果が、単一のXML文書としてクライアントコールバックへ返送され、即ちこれは、ローカルキャッシュへ収納されるノードとして解釈されない。
/**
* @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);
}
カスタムオブジェクト
カスタムオブジェクトは、グラフの一部分となる非永続的ノード(スキーマにより定義される)の生成を伴うことができる。このオペレーションは、クライアントがそれに対応するkeyrefを「通してトラバース」するときに呼び出すことができ、この場合、カスタムオブジェクトは、$sourceノードとしてそれに対応するセレクトコンジットオペレーションへ通すことができる。
実際に、カスタムオブジェクトは、そのカスタムオブジェクトにバインディングされるノードを返送するコンジットオペレーションのための入力データを含むことができる。これは、その後のクライアントテンプレート及びアクションによって参照されるノードと、結果を最新状態に保つために返送されるべきオペレーションとに対して、結果がクライアントキャッシュの一部分となるようにすることができる。
例えば、次のスキーマ宣言は、priority属性の値に基づいてtaskノードの副組を選択するのに使用されるカスタムオブジェクトtaskQueryを定義することができる。
<xsd:complexType name=”taskQuery”>
<xsd:attribute name=”priority” type=”xsd:string”/>
</xsd:complexType>
次のキー定義は、各taskQueryオブジェクトが独特であることを保証する。
<xsd:keyref name=”taskQueryKey”>
<xsd:selector xpath=”taskQuery”/>
<xsd:field xpath=”@priority”/>
</xsd:keyref>
次のkeyref定義は、taskQueryノードをルートノードにバインディングするのに使用され、これは、ルートノードを参照するダミーの外部キー属性mas:rootを宣言し、inverseAlias属性は、ルートノードから1組のtaskQueryノードへのトラバース、即ち$root.@@taskQueries.*を宣言する。
<xsd:keyref name=”taskQueryRootRef” refer=”mas:rootKey”
mas:inverseAlias=”taskQueries”>
<xsd:selector xpath=”taskQuery”/>
<xsd:field xpath=”@mas:rootId”/>
</xsd:keyref>
次のkeyrefは、taskQueryノードと、コンジット問合せオペレーションにより返送されるtaskノードとの間の関係を定義する。各taskノードは、それを選択した対応する問合せを識別するダミーのtaskQuery外部キー属性を宣言し、inverseAlias属性は、taskQueryノードから1組のタスクノードへのトラバース、即ちquery.@@tasks.*を宣言する。
<xsd:keyref name=”taskTaskQueryRef” refer=”TaskQueryKey”
mas:inverseAlias=”tasks”>
<xsd:selector xpath=”task”/>
<xsd:field xpath=”@taskQuery”/>
</xsd:keyref>
これらのkeyref定義は、ルートノードと、図12Dに示したtaskQuery及びtaskノードとの間の次の関係を定義する。
taskQueryノードは、標準的なcreate()ファンクションを使用してクライアントスクリプトにより生成されてもよい。
function init() {
var f = $root.@@taskQueries.create(<taskQuery priority=”1”/>);
}
一実施形態において、taskQueryRootRefのkeyrefに対して定義されたコンジット挿入オペレーションは存在せず、従って、このクライアントスクリプトは、いずれのサーバーアクティビティもトリガーしない。
次のテンプレートは、逆taskTaskQueryRefのkeyref定義をトラバースする。
<netui:repeater id=”$s”
source=”$root.@@taskQueries.where(priority=='1').@@tasks.*”>
<p>{$s}</p>
</netui:repeater>
これは、関連コンジットオペレーションにおいて暗示的セレクトを生じさせ、リピータのソース属性は、上述したように生成されたtaskNodeを参照し、そしてこれは、トラバースのためのソースコンテクストとして使用され、即ちノード<taskQuerypriority=‘1’/>が、$source変数としてオペレーションへ通される。
それに対応するコンジットセレクトオペレーションは、次のファンクションにより定義される。
/**
* @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.*をトラバースするときに(一定)組のtaskQueryオブジェクトを返送するセレクトオペレーションを実施する。
/**
* @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>
第1リピータs1は、1組のtaskQueryオブジェクトを表示し、第2リピータs2は、第1リピータにより選択されたtaskQueryから検索される得られたタスクを表示する。
Figure 0004551899
もちろん、これら問合せオブジェクトを持続させ、実際には、それらをデータモデル内の普通のノードとして処理するウェブサービスを実施することにより、カスタムオブジェクトを挿入し、更新し、そして削除するコンジットオペレーションを定義することもできる。
カスタムオブジェクトノードが、クライアントアプリケーションにより直接変更されるか、又は同期セレクトオペレーションにより間接的に変更されるときには、全ての対応する関係ノードをカスタムオブジェクトから自動的にアンリンクすることができ、即ち外部キー値を経てオブジェクトを参照するノードが、この外部キーをナルにセットする。これは、カスタムオブジェクトを経てトラバースされるノードがカスタムオブジェクトの状態を正確に反映することを保証する。
進歩型セレクトオペレーション
セレクトオペレーションは、フレームワークが特定keyrefに対するノードを検索できるようにする。コンジットは、セレクトオペレーションを定義することができる。というのは、これは、クライアントアプリケーションによりノードを検索するのに使用される基本的メカニズムだからである。
通常のセレクトオペレーションは、クライアントアプリケーションにより、それらがデータモデルをナビゲーションするときに、自動的にトリガーすることができる。例えば、次のクライアントSPath表現は、account keyrefのセレクトオペレーションを呼び出させる。
$account.@@contacts.*
コンジットセレクトオペレーションには、対応するアカウントオブジェクトの一次キーを通過させることができる。このセクションは、他の形態のセレクトオペレーションを詳述する。
キャッシュ記憶及び最適化
クライアント及びMASは、両方とも、コンジットマネージャーにより返送されるデータをキャッシュ記憶することができる。それ故、各々のデータグラフトラバースがセレクト要求を発生しなくてよいことはない。クライアント及びサーバーの両キャッシュは、新たなセレクト要求が発生されるまでに、対応する1組のデータに、どれほど長時間、最新のものとして依存できるか決定するメタデータを、各ノード及びnodesetに対して維持することができる。
セレクトオペレーションに続いて転送する必要のあるデータの量は、しばしば、かなり多量である。それ故、適当なウェブサービスオペレーションの利用性が与えられると、フレームワークによりある最適化を実施することができる。
select_pkeyオペレーションは、selectオペレーションと全く同様に呼び出されるが、一次キー値の組しか返送しない。例えば、上述したコンタクトkeyrefにおける対応するセレクトオペレーションに対するselect_pkeyは、次の応答変換を実施する。
/**
* @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>
}
次いで、MASは、ノードエレメントのどれが(もしあれば)、キャッシュに現在存在するか決定することができる。
キャッシュ内に含まれないノードについては、フレームワークがselect_setオペレーションをコールすることができ、これは、通常のセレクトオペレーションと同様に、要求された1組のpkey値に対して完全なノードを返送する。例えば、上述したselect_setオペレーションは、次の要求変換を実施する。
/**
* @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>
}
応答変換は、通常のセレクトオペレーションに対するものと同じでよい。
複雑なスキーマの選択
セレクトオペレーションは、中継されるエレメントを含む複雑な文書として定義されたノードを返送することができる。nodetypeのスキーマ定義の複雑さについては制約が課せられない。しかしながら、ノードレコードのサイズについては実際上の制限が生じ得る。次のセクションは、複雑な文書を多数のノードに分割できるときのケースを詳述する。

以下のスキーマは、多数のlineItemエレメントを含むpurchaseOrder nodetypeを示す。
<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>
例えば、次のXML文書は、購入注文スキーマを示す。
<purchaseOrder>
<price>1000.00</price>
...
<lineItems>
<lineItem>
<prodId>Widget-X</prodId>
...
</lineItem>
<lineItem>
<prodId>Widget-Y</prodId>
...
</lineItem>
...
</lineItems>
</purchaseOrder>
次のコンジットファンクションは、ネスト状の1組のラインアイテムを各々もつ1組の購入注文を発生するネスト状ループを含む。
/**
* @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>
}
ノードツリーの選択
セレクトオペレーションは、中継されるエレメントを含む複雑な文書として定義されたノードを返送することができる。nodetypeのスキーマ定義の複雑さには制約が課せられない。
あるケースでは、複雑な文書の部分を、keyref関係によりバインディングされた独立したノードに分割することが望まれる。これらのノードは、クライアントへ再び同期されてキャッシュ記憶のデータグラフへ組み込まれるツリーを形成する。
コンパウンド文書を多数のノードへ分割する効果は、単一のオペレーションで多数のレベルのkeyrefを検索することによる性能改善である(例えば、特定アカウントに対する全てのコンタクト及び全ての関連タスクを選択する)。

次のスキーマ定義において、purchaseOrderType及びlineItemTypeは、両方とも、次のスキーマ定義を伴うnodetypeとして宣言される。
<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>
又、このスキーマは、次のkey及びkeyref定義も宣言する。
<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>
図12Dは、対応するkeyrefを表わしている。
コンパウンド文書が個々のノードへ分割されるときには、フレームワークは、成分ノード(例えば、ラインアイテム)におけるクライアントオペレーションがコンジットによりサポートされることを保証できる。例えば、クライアントアプリケーションは、lineItem keyrefに対して対応する挿入オペレーションがない限り、新たなラインアイテムオブジェクトを生成することが防止され得る。
以下のコンジット定義は、前記例の変更バージョンである。ここでは、内部ループは、nodesetエレメント内にノードエレメントを生成する。又、内部オブジェクトは、各々、一次キーを定義しなければならない。
/**
* @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>
}
ディープセレクト
上述したように、アプリケーションは、SPath表現を使用してデータグラフをトラバースすることができ、これらトラバースは、フレームワークがバックグランドにおいて必要なデータを同期するようにさせ得る。一実施形態において、同期メカニズムは、非同期で呼び出されるので、SPath表現を、現在キャッシュ記憶されているデータグラフに対して完全に評価できないことがしばしば生じ勝ちとなる。
例えば、次のSPath表現は、keyrefアカウント及びコンタクトが予め同期されそしてクライアントによりキャッシュ記憶されていない場合には、空のリストを返送する。
$root.@@accounts.*.@@contacts.*.@@tasks.*;
一実施形態において、その後のkeyrefトラバースは、先行するノードが現在キャッシュに存在しない限り、開始できない。一実施形態において、クライアントコードは、先ず、$root.@@accounts.*をトラバースしなければならず、次いで、同期表示を待機し、次いで、$root.@@accounts.*.@@contacts.*を選択し、別の同期表示を待機し、そして最終的に、この表現が、全てのアカウントに対する全てのコンタクトについて全てのタスクの同期を呼び出すことになる。
select()ファンクションは、クライアントが、サーバーに、SPath表現をそれに代わって評価し、次いで、それにより生じるノードのグラフをクライアントへ同期させることを要求できる。例えば、
$root.select(@@accounts.*.@@contacts.*.@@tasks.*);
ここでは、全SPath表現がサーバーへ通過され、サーバーは、次々のkeyrefトラバースをコールし、そしてノードの同期をマネージする。サーバーは、グラフ全体を1つの同期メッセージにおいて又は多数のメッセージを経て返送してもよいことに注意されたい。
又、SPath表現は、where()ファンクションを使用して述語も含んでもよい。例えば、
$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;
コンジットは、セッションを開始するためのメッセージを生成して送信するファンクションを定義することができ、このファンクションは、次いで、応答を処理して、サービスにより返送されたセッション関連情報を抽出することができる。
以下のファンクションは、<login>メッセージをウェブサービスへ送信し、そして応答本体からセッション識別子を抽出する。又、サービスにより返送されるウェブサービスコントロールのURLをセットする。
// 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);
}
$user XML変数は、現在ユーザに関する情報を含み、これは、全てのファンクションにアクセスできるシステム変数である。
各会話メソッドは、セッション識別子を含むヘッダーを指定することができ、次の(通常の)コンジットファンクションは、最初に、会話がスタートしたかどうかチェックし(もしそうでなければ、ログインをコールする)、次いで、適当なヘッダーXMLフラグメントを返送する。
// create conversational header
function createHeader() {
if (sessionId == null) {
login();
}
return
<SessionHeader>
<sessiondId>{sessionId}</sessiondId>
</SessionHeader>;
}
例えば、次のXScriptファンクションは、ウェブサービスにより必要とされるカスタムセッションマネージメントを実施する。
/**
* @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);
}
このファンクションは、要求変換により生成された本体を含むメッセージオブジェクト$msgにおいて通される。
次いで、このファンクションは、必要なヘッダー情報を含むXMLオブジェクトを得るためにcreateHeader()ファンクションをコールする。このファンクションは、セッションが現在スタートしていない場合にlogin()ファンクション(上述した)をトリガーする。次いで、ヘッダオブジェクトがメッセージに追加される。
invoke()ファンクションは、次いで、メッセージ(ヘッダーを含む)をウェブサービスへ送信し、これは、指定のコントロールにより与えられたトランスポートを使用する。
ユーザ情報
$user変数は、どのユーザに代わってコンジットオペレーションが呼び出されるかに関するデータを含む。
Figure 0004551899
クライアントプログラミングモデル
ユーザは、MASにおけるそのURLを参照することによりアプリケーションにアクセスすることができる。ユーザがクライアントマシンからそれを初めて行うときに、アプリケーションの全てのコンポーネントをサーバーから自動的に「ダウンロード」することができる。アプリケーションデベロッパがアプリケーションに関するデータモデルしか指定しない場合には、そのデータモデルに対するメタデータをダウンロードすることができる。メタデータは、アプリケーションに対して最小ユーザインターフェイスを与えるに充分な移動ブラウザのための情報を含むことができる。メタデータを使用して、移動ブラウザは、ルートノード及びそのkeyrefを最初に表示することができる。ユーザは、これらのkeyrefをクリックすることによりアプリケーションデータを通してナビゲーションすることができる。ユーザがkeyrefを選択するときに、データ同期エンジンがそのkeyrefに対するノードを非同期でフェッチし、そしてデータをそれが得られたときに自動的に表示する。例えば、ユーザは、アカウントリンクをトラバースして、アカウントノードをフェッチさせ、次いで、アカウントコンタクトkeyrefをトラバースして、アカウントに対するそのコンタクトを見ることができる。このモデルは、機能的であるが、特に快適なものではなく、即ちデータが予めフェッチされないので、UIは、ありのままのもので、且つ経験は「ぎくしゃくした」ものである。このセクションは、アプリケーションプログラマーがユーザインターフェイスをどのようにカスタマイズできるか説明する。
クライアントアプリケーションをカスタマイズするためにプログラマーが使用する基本的な人為的手段は2つある。その第1は、1組のデータに対してカスタムユーザインターフェイスを与えるのに使用できる「テンプレート」である。プログラマーは、データモデルからデータにアクセスするためのSPath表現が埋め込まれると共にnodesetを経て中継するためのエレメントが埋め込まれたXHTMLテンプレートである「テンプレート」を使用してノード及びnodesetをレンダリングするカスタマイズされた仕方をアタッチすることができる。随時接続データモデルそれ自体は、マジック変数$rootにルーツのある大きな仮想XML文書として与えられる。一実施形態において、データモデルには「現在」位置があり(例えば、アカウント又はアカウントのためのコンタクト)、そしてこれは、別のマジック変数$currentを通してテンプレートに使用することができる。URLは、別のテンプレート又はテンプレート内の新たな「現在」データへの分岐(例えば、そのコンタクトへのアカウントへ進む)を表現することができる。テンプレートは、XHTMLで表現できるが、XHTMLモデルそれ自体への重要な拡張、以下に述べる「選択」、を含むことができる。これは、HTMLが通常与えるものよりリッチで、よりインタラクティブなUIを可能にするが、これは、クライアントがコントローラでもあるときに可能となる。
第2の人為的手段は、プログラマーがオフラインの振舞いをページ内のボタン及びURLにアタッチするようにさせることである。各URLは、クライアントディレクトリーにも配置されるページフローファイル(controller.xpf)においてXMLに対するECMAScript(a.k.a.JavaScript)で書かれた「アクション」を参照することができる。このファイルは、1組のスクリプト「アクション」を含む。アクションは、データモデルへ完全にアクセスすることができ、従って、それらは、値を計算し、クライアントのデータを変更し、ひいては、延期同期、明確なトリガー同期及びディープセレクトをトリガーし、カスタムオペレーションを呼び出し、又はカレンシー(currency)をデータモデルの別の部分にセットするためのナビゲーションを生じさせることができる。コントローラにおける各「アクション」は、データモデル内の新たなカレンシー(又はアクションがデータモデル内の「カレンシー」を実際に変更しない場合にはCONTINUE(継続))と、通常、特定のテンプレートとの両方を、そのカレンシーのコンテクストにおいて使用するように返送することができる。例えば、関連コンタクトを見るためにコンタクトをリストするページにおけるアクションは、そのカレンシーを関連コンタクトにセットしそしてコンタクトリストテンプレートを使用してそれらに何か似ているものを表示するための単なる1つのライナーでよい。
function showContactsForAccount($account) {
$context.account = $account;
return [$account.@@contacts.*, ”ContactsTemplate.tmpl”];
}
モデルビューコントローラ
MASクライアントアプリケーションは、ページフローファイル(controller.xpf)で構成することができ、このファイルは、XScriptアクション及びファンクションと、1組のページテンプレート(.tmpl)とを含むことができる。
クライアントは、アプリケーションデータのローカルキャッシュを維持することができる。このデータは、随時接続データモデルにより記述され、そしてSPathを使用して参照及び操作される。
テンプレートは、埋め込まれたSPath表現を含むXHTMLページである。これらの表現は、キャッシュにおけるデータと、システム変数及びファンクションとを参照することができる。テンプレートは、ローカルデータしか参照できないので、マシンのネットワーク接続状態に関わりなくレンダリングすることができる(即ち、ユーザがアプリケーションをオフラインで実行できるようにする)。
システム変数$currentは、データに対してカーソルを作用させることができ、$currentは、単一ノード又はノードリストのいずれかを参照する。$currentの値は、システムファンクションを呼び出すアクション及びアンカーにより変更することができ、これは、ナビゲーションとして知られている。システム変数$contextは、アクション及びテンプレートが一時的変数を交換するためのメカニズムを与えることができる。例えば、テンプレートは、入力フィールドを、キャッシュ内のコンテクスト変数又はノードエレメントのいずれかにバインディングしてもよい。
又、テンプレートは、データ又はデータモードの指定部分にわたって繰り返すリピータを含んでもよい。これらリピータは、テンプレートが複雑なリスト及びテーブルを自動的に構築できるようにすると共に、ユーザが個々のレコードを選択しそしてそれらに対するアクションを呼び出すことができるようにする。
ページフローメカニズムは、ユーザインターフェイス及び外部事象に応答してアクションを呼び出す。ユーザインターフェイス事象は、テンプレート内の<a>アンカーによりトリガーすることができ、外部事象は、データに対する外部同期更新によりトリガーすることができる。アプリケーションが最初にスタートすると、ページフロー内のbegin()アクションをコールすることができ、これは、表示されるべき第1テンプレートを決定する。
アクションは、テンプレート及び外部事象により呼び出されるXScriptファンクションである。アクションは、データを変更できると共に、テンプレートにアクセスできる$current及び$context変数も変更できる。システム変数$pageは、現在見えるページ文書を参照し、これは、これらアクションがページコントロールプロパティをアクセスできるようにする。
ナビゲーションは、$page又は$currentシステム変数がアクションにより変更されるときに行うことができる。クライアントは、<$page x $current x $context>変数の経歴スタックを維持することができる。これは、ユーザが経歴を前後にナビゲーションできると共に、テンプレートがコンテクスト(及び例えば、入力エレメントのバインディングされた値)を維持できるようにする。
XScript
SPath表現
クライアントプログラミングモデルは、XMLに対するECMAScript(E4X、XScript)を使用することができ、これは、本質的にXMLに対するナビゲーションサポートを伴うJavaScriptであり、SPathは、XPath同様の言語で、アプリケーションがXMLデータグラフに問合せできるようにする。これは、「ドット」演算子を使用して、グラフ内のエレメントを「トラバース」する。エレメントは、普通のXMLエレメントでもデータノードでもよい。
XMLオペレーション
システム変数は、‘$’記号をプレフィックス(接頭辞)として設け、非タイプ入力とすることができる。他の変数の使用は、XScript仕様により定義される。
次の宣言は、変数foo及びbarを生成する。
foo = 100;
var bar = ”Alchemy”;
varキーワードは、現在ファンクションのローカル範囲内に変数を配置し、varを宣言しない変数は、グローバルな範囲に配置される。
次の宣言は、fooの値を、新たに生成されたXMLオブジェクトにセットする。
var foo = <foo>Alchemy</foo>;
コンパウンドXMLオブジェクトも次のように生成及び参照することができる。
var foo = <foo><bar>Alchemy</bar></foo>;
var bar = foo.bar

bar == ”Alchemy”
又、XMLオブジェクトは、‘@’演算子を使用して参照される属性を宣言してもよく、例えば、
var foo = <foo id=”100”><bar>Alchemy</bar></foo>;
var id = foo.@id;
属性は暗示的に追加することができる(即ち、expando)。
foo.@ping = ”200”;
次の例は、<bar>エレメントのテキストノードの値を変化させる。
var foo = <foo><bar>Alchemy</bar></foo>;
foo.bar = ”MAS”;

foo == <foo><bar>MAS</bar></foo>
次の例は、全<bar>エレメントに置き換わる。
var foo = <foo><bar>Alchemy</bar></foo>;
for.bar = <foobar>Mobilized</foobar>

foo == <foo><foobar>Mobilized</foobar></foo>
+=演算子を使用して、新たなXMLエレメントを既存の親エレメントに追加又は挿入し、例えば、
var foo = <foo><bar>Alchemy</bar></foo>;
for.bar += <bar>Mobilized</bar>

foo == <foo><bar>Alchemy</bar><foobar>Mobilized</foobar></foo>
逆に、delete演算子を使用して、エレメントを除去する。
var foo = <foo><bar>Alchemy</bar></foo>;
delete foo.bar

foo == <foo></foo>
データグラフオペレーション
随時接続データモデルは、データモデルにおけるルートノードを指すマニフェスト変数$rootをもつ仮想XML文書としてデベロッパへと表面化することができる。関連ノードへのナビゲーションは、@@演算子を使用しそしてkeyref定義を経ての仮想XML文書内のモデルである。
ノード操作
本書において、ノードという語は、データモデルノードを示すのに使用される。例えば、次のサンプルは、XMLエレメントを生成する。
var account =
<account>
<name>Acme</name>
<type>Direct</type>
</account>
一実施形態において、XMLエレメントは、データキャッシュに挿入されるときに(create()ファンクションを現在使用して)、ノードと考えられる。
新たなノードは、keyrefにおいてcreate()ファンクションをコールすることにより生成することができる。例えば、次の例は、新たなaccountノードを生成する。
$root.@@accounts.create(<account><name>Brooklyn Industries</name></account>);
ノードエレメント内に含まれたデータは、通常のSPath表現を使用して参照及び変更することができる。次の例は、$contactノード内のエレメントのテキスト値を変化させる。
account.name = ”Acme Ltd”;
又、新たなXMLエレメントは、指定によりノード内に生成されてもよく、例えば、
account.address = <address><street>335
Madison</street><zip>11211</zip></address>
データオペレーション
nodetype間の関係は、随時接続データモデルにおけるkeyref定義により定義することができる。例えば、次の宣言は、account keyrefがルートノードから発生され、そしてタイプaccount(これは、スキーマにより定義される)のノードを含むことを指定する。
<keyref name=”accounts” sourceType=”mas:root” targetType=”app:account”>
クライアントプログラミングモデルにおいて、keyrefは、@@演算子を使用してトラバースすることができる。例えば、
$root.@@accounts
又、keyref()ファンクションを使用して、命名されたkeyrefを参照することもできる。次の例は、前記例と同等である。
$root.keyref(”accounts”)
keyrefは、指定の親ノードに対してkeyrefを参照するものとして考えることができる。次の例は、$rootノードのaccount keyrefの全てのaccountノードを参照する。
$root.@@accounts.*
$root.keyref(”accounts”).*
この表現は、各ノードがタイプaccountであるようなnodesetを返送し、例えば、
<account>
<name>Acme</name>
</account>
<account>
<name>Bancroft</name>
</account>
[]演算子は、nodeset内の特定ノードをアクセスするのに使用できる。次の表現は、account nodesetにおける第1ノードを返送する。
$root.@@accounts.*[0]
length()ファンクションは、nodesetにおけるノード数を返送するのに使用できる。
$root.@@accounts.*.length()
これは、値1(one)を返送する次の表現とはかなり異なる。
$root.@@accounts.length()
即ち、$root@@accountは、単一エレメント<accounts>を返送する。
データグラフは、SPath表現をアーギュメントとして取り上げるwhere()ファンクションを使用してフィルタリングすることができる。例えば、次のステートメントは、指定のラストネームをもつaccount keyrefにおける全てのcontactノードに一致し、そしてノードリストを返送する。
$root.@@accounts.*.where(.name == ”Acme”);
これは、次の表現と同等であることに注意されたい。
$root.@@accounts.*.(thisXML.name == ”Acme”);
ここで、クローズがノードリストに対して評価でき、そしてその後にSPath表現が続いてもよい。例えば、次の表現は、”Acme”と命名された全てのアカウントに対するコンタクトのノードリストを返送する。
$root.@@accounts.*.where(.name == ”Acme”).@@contacts.*;
ラベル
各nodetype宣言は、ノードを参照するSPath表現であるラベルを定義してもよい。label()ファンクションは、計算されたストリングを返送する。
<p>{$context.account.label()}</p>
又、keyrefは、label()ファンクションにより返送されるラベルを定義してもよい。
<p>{$root.@@accounts.label()}</p>
ノードのラベルは、label()ファンクションにより得られる。例えば、
ノード又はkeyrefがそれ自身により参照されるときに、強制で自動的にlabel()ファンクションを呼び出す。次の例は、上記例と同等である。
<p>{$context.account}</p>
<p>{$root.@@accounts}</p>
Namespace
クライアントプログラミングモデルにおいて、全てのオペレーションは、アプリケーション自身のデフォールトnamespaceにおいて実施することができる。
このデフォールトnamespaceは、setDefaultNamespaceファンクションを使用してセットされる。
function begin() {
$pageFlow.setDefaultNamespace(”http://example.com/”);
...
}
これは、自動的にデフォールトアプリケーションnamespaceを全てのXMLオペレーションに追加する。例えば、次の表現は、
var account = <account><name>Acme</name></account>;
次のXMLを発生する。
<account xmlns=”http://example.com/”>
<name>Acme</name>
</account>
システム変数及びファンクションの参照
このセクションは、XML規格に対してECMAScriptを拡張できるシステム変数及びファンクションを説明する。
システム変数
全てのシステム変数は、‘$’記号のプレフィックスをもつことができ、ユーザ変数も、規定により‘$’記号を使用してもよい。
フレームワークは、テンプレート及びアクションの両方から参照できる次のシステム変数を定義する。
Figure 0004551899
クライアントデータモデルは、アプリケーションに関する持続性データを表わすことができる。しかしながら、アプリケーションは、ページ遷移にわたって維持されるがMASに対して同期されない情報を一時的に記憶する必要があり、これは、例えば、「クリップボード」、「ウィザード(wizards)」及び他のマルチページプロセスを実施するのに使用できる。デベロッパは、$context及び$sessionオブジェクト内の新たな変数を生成することができる。
$context
$context変数は、発呼側アクションがテンプレートへの通過を望むことのある付加的なデータを表わす。これは、JPF又はHTTP GET属性におけるフォワードビーンと同様である。コンテクスト変数は、ヒストリーの一部分として保存することができる。
$session
$session変数は、アプリケーションの「セッション」状態を表わし、これは、$contextオブジェクトとは異なり、経歴の一部分として記憶されない。これは、通常、全アプリケーションに関連した(即ち、特定のページではない)情報を記憶するのに使用される。これらの変数は、アプリケーションのライフタイム中に残存し、そしてアプリケーション(及びブラウザ)が停止し及び開始するときに持続されそしてデハイドレート(dehydrate)される。
例えば、次のファンクションは、ユーザ定義のカウント状態変数をセットするのに使用されてもよい。
function onExternalSync() {
$session.count = $root.@@messages.*.length();
}
次いで、各ページは、次のXHTMLセグメントを含むことができ、これは、バインディング状態変数が変化するときに自動的に更新される。
<p>You have {$session.count} messages.</p>
<p>Click
<a href=”$pageFlow.navigate($root.@@messages.*,
‘showMessages.tmpl’)”>here</a>
to see them</p>
$current
$current変数は、ノード(又はノードリスト)を表わすもので、通常、UIエレメントをデータにバインディングするために相対的SPath表現を伴うテンプレートにより使用される。
$user
$user変数は、ユーザに代わってコンジットオペレーションが呼び出されるところのユーザに関するデータを含む。オブジェクトは、次のフィールドを含む。
Figure 0004551899
$history
$history変数は、コントローラにより変更することができる。
$history変数は、次のファンクションを実施することができる。
Figure 0004551899
$pageflow
$pageflowオブジェクトは、次のファンクションをサポートする。
Figure 0004551899
$globalApp
$globalApp変数は、次のファンクションを実施する。
Figure 0004551899
データモデルファンクション
次のファンクションは、ノードにおいて定義される。
Figure 0004551899
次のファンクションは、keyrefにおいて定義される。
Figure 0004551899
メタデータファンクション
クライアントプログラミングモデルは、デベロッパが、アプリケーションを記述するメタデータの一部分にアクセスするのを許すことができる。
meta()
データモデルメタデータは、ノード又はkeyrefのいずれかにおいてmeta()ファンクションをコールすることによりアクセスでき、例えば、
$root.meta();
$root.keyref(”accounts”).meta();
次のファンクションは、metaオブジェクトにおいて定義される。
Figure 0004551899
次のファンクションは、schemaオブジェクトにおいて定義される。
Figure 0004551899
例えば、次のテンプレートサンプルは、ネスト状のリピータを使用して、keyrefハイアラーキーを表わすテーブルを構成する。
<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>
次の出力は、CRM使用の場合に発生される。
−owner
−subAccounts
−quoteRequest
−contacts
−notes
−events
−tasks
随時接続データモデル
前記セクションで述べたデータモデルは、デベロッパに対し、ルートノードを指すマニフェスト変数$rootを伴う仮想XML文書として表面化することができる。一実施形態において、移動ブラウザは、常に、コンテクストとして、データモデル内の現在位置を有する(例えば、特定のアカウント又は1組のコンタクト)。テンプレート及びスクリプトは、別のマニフェスト変数$currentを通してこの現在位置にアクセスすることができる。
図9は、CRMアプリケーションに関するスキーマダイアグラム900を示し、このアプリケーションは、6つのnodetype:Account、Contact、Note、Event、Task、及びQuoteRequestを定義する。フレームワークは、全アプリケーションデータモデルを記述するXMLスキーマを発生する。これは、アプリケーションスキーマ及びkeyref定義を使用して発生することができる。
例えば、CRMアプリケーションは、次のスキーマを有する。
<?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>
<graph>エレメントは、アプリケーションデータモデルの最上位レベルエレメントを表わすことができ;これは、厳密に1つの<root>ノード宣言と、各アプリケーションスキーマ(account、contact、note、event、task、及びquoteRequest)の各ノードに対する非制限インスタンスとを含むことができる。
<root>エレメントは、$rootシステム変数により参照することができる。ルートノードは、特殊なシステムタイプであるから、ルートノード内に含まれるユーザデータオブジェクトは存在しない。
$root.@@accounts.*;
随時接続データモデルは、アプリケーションnodetypesを定義することができ、これらは、アプリケーションスキーマ及びkeyref定義から構成することができる。例えば、次の例は、account nodetypeを詳述するもので、これは、スキーマエレメント(name及びtype)と、keyref定義(owner、subAccounts、contacts、notes、events、tasks、及びquotes)とを含む。
<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>
アカウントノード定義は、サーバーにおいて定義された対応するスキーマにより記述されるエレメント(及びおそらくは属性)を定義する。上述したように、keyref定義は、アカウントノードから考えられるトラバースを決定する。例えば、
var user = account.@@owner;
var contacts = $root.@@accounts.*.@@contacts.*;
同様に、次の例は、コンタクトnodetypeを定義する。
<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>
次のXMLは、ユーザがこのデータにいかにアクセスするかのクライアントモデルを示すが、これに似た実際のXMLファイルが存在するときはない。
<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>
概要
一実施形態において、クライアントがデータグラフを変更する仕方は2つある。第1に、テンプレートの入力エレメントをデータノードへ直接バインディングすることができ、このメカニズムは、ユーザが、既存のノードに属するXMLエレメントを変更できるようにし、そしてコードを必要としない。第2に(そして通常は)、テンプレートが、データを変更するアクションを呼び出す。
一実施形態において、データに対するこれらの変更は、サーバーへ同期状態で送信されない。むしろ、バックグランドプロセスが、サーバーへの及びサーバーからの更新を同期させる。実際に、全ページフローメカニズムが、ネットワーク(サーバー)接続とは独立して実行できるので、通常、データに対して多数のオフライン変化があり、これは、接続が確立されたときにサーバーと同期され且つ調和される。
又、プログラミングモデルは、更新又は挿入されたレコードの同期を延期させるメカニズムも実施できる。例えば、購入注文を表わすノードを生成できるが、ユーザは、全てのラインアイテムが追加され、次いで、「サブミット」ボタンをクリックするまで、これを同期することを望まないことがある。
サーバーは、他のユーザとの楽観的同時性競合のために、又は外部アプリケーションエラーのために、同期要求を拒絶することがある。各ノードは、フレームワークによりマネージされる同期状態を有する。これは、どのレコードが同期保留中であり、最新であり、又はサーバーにより拒絶されたか指示するフラグをアプリケーションが表示できるようにする。
スキーマの検証
create()及びupdate()ファンクションが呼び出されたときに、フレームワークは、次のことを実行する。
A)オブジェクトをアプリケーションスキーマに対して検証すると共に、要求された全ての外部キーを検証する;
B)逆方向にトラバースできる関係(即ち、逆の関係)に対してキャッシュが一貫したものであることを保証する。
いずれかの条件を満足しない場合には、ランタイムエラーが発生される。
又、link()又はunlink()ファンクション(又、+=/−=演算子)が呼び出されたときにはkey/keyrefが強制される。
ノードの生成
次のアクションは、create()ファンクションを使用してノードを生成することができる。
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は、XML指定表現(第1ライン)により構成することができる。第2及び第3表現は、XMLノードを変更する。しかしながら、ノードは、create()ファンクションが呼び出されるまで検証される必要がない。
ノードの更新
同様に、アプリケーションは、ノードのデータに直接アクセスすることにより既存のノードを変更することができる。例えば、次のコードは、特定の購入注文を検索し、次いで、状態を変更しそして新たなラインアイテムを追加する。
po = $account.@@purchaseOrders.where(.date == ”03/12/05”).*[0];

po.status = ”getQuote”;
po.lineItems += <lineItem><prodId>DEF</prodId><qty>300</qty></lineItem>

$po.update();
ここでも、ノードを検証するためにupdate()ファンクションがコールされる。
ノードの生成
クライアントに新たなノードを生成するためにcreate()ファンクションを使用することができる。
var node = sourceNode.@@keyref.create(<node>[, callback, id]);
このファンクションは、挿入コンジットオペレーションをサポートするkeyrefにおいてコールすることができる。このファンクションはノードオブジェクトを返送する。
Figure 0004551899

例えば、次のXScriptは、指定の$accountオブジェクトに対するcontacts keyref内の新たなcontactノードを構成する。
var contact =
<contact>
<salutation>Mr</salutation>
<first>Sydney</first>
<last>James</last>
<email>sydney@james.com</email>
</contact>;

node = account.@@contacts.create(contact);
ノードは、通常、3つの段階で生成され、即ち第1に、アクションがコンテクスト変数を生成し、次いで、テンプレートを表示させる。
function init() {
$context.contact = <contact><salutation/><first/><last/><email/></contact>;

return [”editContact.tmpl”];
}
次いで、テンプレートが入力コントロールを個々のコンテクストエレメントにバインディングする。
<input type=”text” netui:bind=”$context.email”/>
次いで、テンプレートは、第2のアクションを呼び出し、フレームワークは、アクションをコールする前に、HTML入力値をコンテクスト変数へ自動的に転送して戻す。次いで、アクションは、新たなノードを生成する。
function create() {
$context.contact = $account.@@contacts.create($context.contact);

return [”showContact.tmpl”];
}
上記例において、アクションは、現在コンテクスト変数($context.contact)を、create()ファンクションにより構成されたノードと置き換え、これは、次のテンプレート(showContact.tmpl)が、生成されたノードを参照できるようにする。create()ファンクションがコールされる前に、$context.contactは、充分形成されたXMLエレメントのみを含み、その後、検証されたノード(例えば、種々のノードファンクションをサポートする)を指す。
一実施形態において、insertコンジットオペレーションを定義するkeyrefは、ノードを生成するのを許し、そして無効のnodesetにおけるノードを生成するように試みると、ランタイムエラーを生じさせる。
コールバック
create()ファンクションは、コールバックファンクションを指定することもでき、これは、同期メカニズムが、ノードが生成された(即ち、関連コンジットオペレーションが新たな一次キーの返送に成功した)確認をサーバーから受信するときに呼び出される。例えば、
function foo(account, quote) {
node = account.@@requests.create(quote, bar);
}

function bar(request) {
$context.lastRequest = request;
}
コールバックファンクションには、生成されたノードをパラメータとして通すことができる。
ノードの更新
update()ファンクションを使用して、クライアントにおいて変更されるノードを同期させることができる。
node.update([callback, id]);
このファンクションは、更新コンジットオペレーションをサポートするkeyrefにおいてコールされる。
Figure 0004551899
ノードは、普通のXScript表現を使用して変更することができる。生成されたノードと同様に、同期は、バックグランドプロセスとして実行される。しかしながら、変更されたノードは、update()ファンクションがコールされない限り、同期に対してマークされない。
update()ファンクションは、関連ノードのsyncState属性をMODIFIED(変更済)へセットすることができる。このメカニズムは、ノードが同期される前に、多数の編集を単一ノードに対して行えるようにする。

以下のコードにおいて、最初の2つの表現は、$contactノードのsyncStateをDSYNCにセットすることができ、そして最後の表現は、syncStateをMODIFIEDにセットすることができる。
contact.first = ”Bob”;
contact.address = <address><zip>10017</zip></address>;

$contact.update();
コールバック
update()ファンクションは、同期メカニズムが、ノードが更新された(即ち、関連コンジットオペレーションが成功した)という確認をサーバーから受信したときに呼び出されるコールバックファンクションを指定することもできる。例えば、
function foo(account, quote) {
quote.update(bar);
}

function bar(request) {
$context.lastRequest = request;
}
コールバックファンクションには、生成されたノードをパラメータとして通すことができる。
競合のマネージメント
一実施形態において、クライアントが、外部システムにおいて既に更新されている(別のクライアント又は他の外因性変化プロセスのいずれかにより)「古い」ノードを変更しそして同期しようと試みるときに、ノードの競合が生じる。古いノードとは、サーバーにより保持されている現在シーケンスナンバーとは異なるシーケンスナンバーを有するノードである。
ノードが古いためにサーバーが更新を拒絶する場合には、同期状態属性を「conflict」にセットした状態で最新のノードを返送する。
更新オペレーションは、ノードがサーバーから返送されたときに呼び出される(競合の有無に関わらず)コールバックをセットすることができる。コールバックがセットされない場合には、クライアントフレームワークは、クライアントの古いノードを、サーバーにより返送された最新のノードと自動的に置き換える。
コールバックファンクションは、最初に、syncState()システムファンクションを使用して競合状態についてテストしなければならない。次いで、アプリケーションに対してグローバルな変数(即ち、$session)をセットしなければならない。例えば、
function updateCallback(node) {
if (node.syncState() == CONFLICT) {
$session.message = ”<a href='showConflict()'>edit conflicts</a>”;
$session.conflict = node;
}
}
競合が生じたことをユーザに通知するために、各テンプレートは、このグローバルな変数を参照することを含む状態エリアを含んでもよく、例えば、
<netui:html>{$session.message}</netui:html>
ここで、グローバル変数は、競合エディタページを表示するアクションへとユーザをナビゲーションできるHTMLアンカーを含む。
function showConflict() {
$context.node = $session.conflict;
return [”showConflict.tmpl”];
}
以下のshowConflictテンプレートは、古いノード及び最新のノードの値を横に並べて表示する。
SPath表現は、データノードに対して定義されたconflict()ファンクションをコールし、これは、最新のノードを返送する。競合ノードは、外部キー値を含んでもよいが、@@演算子は、競合ノードからトラバースできないことに注意されたい。
<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>
サブミットボタンを押した場合に、このフォームは、以下のupdateConflict()アクションを呼び出す。
function updateConflict() {
$context.node.update();

$status.message = null;
$status.conflict = null;
return [”BACK”];
}
これは、現在ノードにおいてupdate()ファンクションをコールし、これは、同期メカニズムの再試みをトリガーする。ここで、コントローラは、ユーザが状態エリアをクリックする前に表示されていた以前のページに直ちに戻る。
又、上述したテンプレートは、クリック時に以下のcopyValues()アクションをコールするアンカーも定義する。
function copyValues(node) {
node.copy(node.conflict());
return [”CONTINUE”];
}
このアクションは、最新のノード値を古いノードへコピーし、そしてshowConflictページに戻る。
ノードのリンキング及びアンリンキング
一実施形態において、link()ファンクションは、1対多の関係を表わすkeyrefにノード(又はノードのリスト)を追加するのに使用される。
node.@@keyref.link(nodeList);
nodeListパラメータは、既に生成されたノードを参照しなければならないことに注意されたい。
unlink()ファンクションは、1対多の関係を表わすkeyrefからノード(又はノードのリスト)を除去するのに使用される。
node.@@keyref.unlink(nodeList);

以下のファンクションは、現在(コンタクト)ノードの関連keyrefから全ての「ウェブ」アカウントを除去する。これは、次いで、ファンクションへ通される単一のnewAccountノードをリンクする。
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.*;
}
又、エラーオブジェクトは、field()ファンクションを実施することもでき、これは、個々のエラーフラグにアクセスするのに使用され、例えば、
var msg = error.field(spath).message;
カスタムオブジェクト
テンプレートもアクションも、外部ソース(例えば、ウェブサービス)に直接アクセスすることができない。むしろ、外部プロセスは、MASフレームワークにより同期されるデータオブジェクトとしてモデリングされる。
大部分のコンジットオペレーションは、ノードエンティティのCRUDオペレーション(即ち、セレクト、生成、更新、等)へとマップすることができ、これらオペレーションは、クライアントプログラミングモデルファンクション(ナビゲーション、生成、更新、等)に直接対応する。しかしながら、通常、全てのウェブサービスオペレーションをフレームワークの標準的なオペレーションにマップすることはできない。例えば、ウェブサービスオペレーションは、多数のノードエレメントから形成されるか又はユーザにより入力される一時的な値を含む1組のパラメータを要求することがある。これらの場合に、アプリケーションは、ウェブサービスオペレーションの入力及び出力パラメータを含むカスタムnodetypeを定義する。このメカニズムは、カスタムオペレーションとして知られている。create()ファンクションは、普通のノードが生成される同じ仕方で新たなカスタムオブジェクトを生成するのに使用できる。
var customNode = $sourceNode.@@keyref-A.create(<node>[, callback]);
カスタムオブジェクトは、通常、対応keyrefのための挿入コンジットオペレーションを実施しない。むしろ、カスタムオブジェクトは、セレクトコンジットオペレーションをトリガーするその後のトラバースのためのコンテクストとして使用される。例えば、
var resultNodes = customNode.@@keyref-B.*;
keyref宣言は、次の図で示される。
Figure 0004551899

次の例は、次のプロートタイプを有するウェブサービスオペレーションを仮定する。
xsd:double submitQuote(xsd:string prodId, xsd:integer qty);
このオペレーションは、prodId及びqty入力パラメータを取り上げ、そしてprice値を返送する。
これは、prodId及びqty入力パラメータと、price応答フィールドとを含むnodetypeに対するカスタムXMLスキーマ定義を要求する。
カスタムノードは、普通のノードと同じものが生成される。例えば、次のXMLは、充分に形成されたquoteRequestエレメントを表わす。
<quoteRequest><prodId/><qty>0</qty></quoteRequest>
通常、デフォールト値を含む充分に形成されたXMLオブジェクトを指定することによりコンテクスト変数を生成するアクションが呼び出される。次の例は、quoteRequestエレメントを生成し、そしてコントローラがinputRequestテンプレートをナビゲーションするようにさせる。
function initiateRequest() {
$context.request = <quoteRequest><prodId/><qty>0</qty></quoteRequest>;

return [”inputRequest.tmpl”];
}
<input>エレメントを個々のフィールド値にバインディングするテンプレート。
<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>
テンプレートは、submitRequestアクションを呼び出して、充分に形成されたquoteRequestエレメントからノードを生成するためのサブミットボタンを有する。
function submitQuoteRequest() {
$current.@@quotes.create($context.request);

return [”showRequests.tmpl”];
}
create()ファンクションは、直ちに戻って、同期のための新たに生成されたノードをマークする。通常のノードを生成するのと同様に、同期は、バックグランドプロセスとして行われる。それ故、このアクションは、ナビゲータが現在の1組のクオテ(quote)要求を表示するようにさせる。
showRequestテンプレートは、テンプレートの入力及び出力値の両方を参照する。新たに生成される要求に対するresponse.priceエレメントは、最初に、値を返送しそして空にする。
<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>
Figure 0004551899
あるポイントにおいて、同期メカニズムは、生成されたノードをサーバーへ送信することができ、これは、関連カスタムオペレーションを呼び出す。成功の場合には、これは、<response>エレメントを生成し、そしてノードをサーバーに再び同期させる。
<quoteRequest>
<prodId>Widget-Z</prodId>
<qty>1000</qty>
<response>
<price>2000.00</price>
</response>
</quoteRequest>
showRequestsテンプレートが依然見える場合には、クライアントフレームワークは、テンプレートを再レンダリングさせ、これは、対応するテーブルの行を更新する。
Figure 0004551899
ノードの選択
select()ファンクションは、keyrefにおいてコールすることができ、直ちに値を返送しない。このファンクションは、テンプレート内からはコールできない。
node.@@keyref.select(spath, [callback, id]);
又、select()ファンクションは、ルートノードにおいてコールされてもよい。
$root.select(spath, [callback, id]);
このメカニズムは、クライアントがSPath表現により記述された仮想XML文書の一部分の同期を要求できるようにする。
例えば、次の表現は、現在キャッシュにある全てのアカウントに対する全てのコンタクトを要求する。
$root.@@accounts.*.select(@@contacts.*);
次の表現は、ルートノードからアクセスできる全てのアカウントに対する全てのコンタクトを要求する。
$root.select(@@accounts.*.@@contacts.*);
一実施形態において、SPath表現は、ローカルファンクションを参照せず、そしてこの表現は、非スカラー値へ分析できないローカル変数を参照しない。この表現は、サーバーへ通され、サーバーは、その表現をそれに対応するXPath表現に変換する。
述語での選択
あるkeyrefは、大きなもので、クライアントと完全に同期させることが不可能なことがある。これらの場合には、クライアントは、where()ファンクションを使用してkeyrefをフィルタすることができる。
例えば、次のセレクト表現は、where()述語に一致するアカウントノードだけを同期させる。
$root.select(@@acounts.*.where(.type == ”Web”));
次の表現は、上述した一致するアカウントに対する全てのコンタクトを選択する。
$root.select(@@acounts.*.where(.type == ”Web”)).contacts.*;
次の表現は、一致するeメールアドレスを有する全てのコンタクトを選択する(全てのアカウントから)。
$root.select(@@accounts.*.@@contact.*.where(.email == ”bob@acme.com”));
又、述語セレクトメカニズムを使用して、ユーザが、同期されねばならないノードを予め選択するのを許すこともできる。例えば、チェックされたブールの属性をアカウントnodetypeに追加し、そしてこれをテンプレート内のチェックボックスエレメントにバインディングすることもできる。
<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.*);
コールバック
コールバックメカニズムは、SPathに対する全同期が完了したときに、発呼者が、コールされるべきファンクションを指定できるようにする。例えば、
$root.select(@@accounts.*.@@contacts.*, $id, callbackFn);
この例は、同期スクリプトをサーバーに送信して全てのアカウントに対して全てのコンタクトを検索すると共に、同期が完了したときに、ファンクションcallbackFnを、クライアントフレームワークにより呼び出されるべきコールバックとして登録する。$id変数は、特定のセレクト呼び出しを識別するためにファンクションへ通される。

例えば、このメカニズムの1つのアプリケーションは、特定のアプリケーションに関する全てのテンプレートが各ページの底部に「状態バー」エレメントを含み、これが一時的データ値(例えば、$session.message)にバインディングするようにしてもよい。
<p>Status: <span>{$session.message}</span></p>
コールバックでセレクトを開始するアクションが1つのテンプレートからコールされてもよい。
q1 = ”Q1”;

function beginSearch(email) {
$root.select(@@accounts.*.@@contact.*.where(.email == email), q1, onUpdate);
}
この場合に、beginSearch()ファンクションは、コンタクトのeメールアドレスを表わすパラメータを取り上げ、そして一致するeメールアドレスエレメントを有する全てのコンタクト(全てのアカウントに対する)を選択する。
ユーザ定義のコールバックファンクションonUpdate()は、同期要求が完了したときにコールされる。
function onUpdate(id) {
if (id == q1) {
$session.message = + ” Received results.”;
}
...
}
このファンクションは、id入力変数を、前記select()ファンクションへ通された要求定数と一致させ、次いで、$session.message変数を変化させ、これは、この変数へのテンプレートバインディングをリフレッシュさせる。
同期
通常、同期は、バックグラウンドで実行される。一実施形態において、同期に作用するものについてユーザが有する唯一のコントロールは、セレクトオペレーションが完了したときにコールバックを登録することである。
しかしながら、ノードを生成又は変更するときには、1組のオペレーションが論理的に完全なユニットとして実行されることを保証することが時々必要となる。これは、全トランザクションセマンティックを要求するよりも低いバーであることに注意されたい。
例えば、以下のファンクションは、コンタクトのファーストネーム及びラストネームを変更すると共に、アカウントノードを参照する外部キーも変更する。
function foo(contact, account) {
contact.first = $context.first;
contact.last = $context.last;

contact.@@accountId = account;
}
一実施形態において、ノードが生成又は変更されるときに、それらの同期状態をDSYNC(deferred sync)にセットする。しかしながら、それらは、コントローラにより呼び出されたオリジナルアクションがエラーなしに復帰するまで同期についてスケジュールされない。この点において、DSYNCとマークされた全てのノードは、MODIFIEDへ促進される。
アクションが、その後のアクションを呼び出すことがあり、この場合には、最も外側のアクションがこの暗示的トランザクションの範囲を形成する。
クライアントフレームワークは、単一スレッド(アプリケーション当たり)アクションモデルを実施する。これは、到来する同期メッセージにより呼び出されたアクションと、フレームワークによる同期メッセージの処理との両方を含む。それ故、到来する同期更新がアクション内で操作されるデータに「大打撃を与える(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()”/>
サブミットボタンは、submit()アクションをコールし、これは、完全なものとしてセットされた全ての購入注文に対してupdate()をコールする。
funciton submit() {
for (i = 0; i < $accounts.@@purchaseOrders.*.length(); i++) {
var po = $account.@@purchaseOrders.*[i];
if (po.syncState() == ”DSYNC” && po.@@complete == true) {
$po.update();
}
}
}
この例は、外部システムが完全な属性の意味を解釈し、即ちレコードの処理を(持続性をマネージしながら)、ユーザにより適当な値がセットされるまで、延期することを要求する。
テンプレート
テンプレートは、アプリケーションのユーザインターフェイスを作り上げる充分に形成された(そして検証された)XHTMLページである。テンプレートは、通常、キャッシュ内のデータを参照し、又、アクションを呼び出すこともできる。一実施形態において、テンプレートは、データグラフを直接変更できるスクリプト表現を含まない。
テンプレートは、カーソルとして働く$currentシステム変数を参照することができ、$currentは、単一ノード又はノードリストのいずれかを参照する。一実施形態において、$currentの値は、システムファンクションをコールするアクション及びアンカーでしか変更できず、これは、ナビゲーションとして知られている。
又、テンプレートは、データ又はデータモデルの特定部分にわたって繰り返すリピータを含んでもよい。リピータは、テンプレートが複雑なリスト及びテーブルを自動的に構築できるようにすると共に、ユーザが個々のレコードを選択して、それに対するアクション又はナビゲーションを呼び出せるようにする。
システム変数$contextは、アクション及びテンプレートが一時的変数を交換するためのメカニズムを与えることができる。例えば、テンプレートは、入力フィールドをコンテクスト変数又はデータノードエレメントのいずれかにバインディングすることができる。テンプレートがアクションを呼び出すときには、ページ入力の値が自動的にそれらのバインディングされた変数へコピーされる。
テンプレートは、ユーザがクリックしたときにトリガーされるHTML<a>アンカーを定義することにより事象を発生することができる。一実施形態において、アンカーは、3つの異なる目的を有する。
1)ナビゲーション
アンカーは、SPath表現(例えば、$current.@@orders.*)を指定することができ、これは、コントローラが$current変数を変更して異なるノード又はnodesetを指すようにし、これは、ナビゲーションとして知られている。システムは、特定のテンプレートをあるnodetype及びkeyrefに関連付けできるメタデータを与えて、ブラウザが自動的に適当なテンプレートを選択できるようにする。
2)システムファンクションの呼び出し
フレームワークは、アプリケーションの振舞いを変更する種々のシステムファンクションを実施することができる。例えば、navigate()ファンクションは、特定のテンプレートへナビゲーションし、そして$current変数をセットし、select()ファンクション(リピータ内でコールされる)は、リスト又はテーブルから特定ノードを選択するのに使用される。
3)アクションの呼び出し
アクションは、手前のテンプレートにバインディングされたコンテクスト変数を処理しそして計算を実行し又はデータを変更することができる。次いで、アクションは、現在ページへ直接戻ることができ、この場合に、データバウンドフォームコントロールが更新され、そして表示がリフレッシュされる。又、アクションは、コントローラが$current及び$page変数を変更するようにさせて、ナビゲーションを生じさせることもできる。
同期は、バックグランドにおいて行うことができる。クライアントにより生成されそして変更されたノードは、種々の同期状態を通過し、これらは、システムファンクションを経てテンプレートへアクセスされ、そしてユーザに表示することもできる。又、サーバーからの同期更新は、関連ノードにバインディングするテンプレートを即座に更新させる。
表現の評価
一実施形態において、テンプレートは、カーリーブレース(curly brace)内のSPath表現を引用することにより、キャッシュからのデータをページへ直接合体することができる。評価された表現の結果は、普通のXHTMLとして処理される。
例えば、次の表現は、現在ノードのラベルを表示する。
<p>{$current.label()}</p>
一実施形態において、カーリーブレース内に含まれた表現は、ページがリフレッシュされるたびに評価される。ページは、コントロールがアクションから戻されるときにリフレッシュされる。それ故、カーリーブレース内に含まれた表現は、XHTMLタグのための動的な値を定義するのに使用できる。
例えば、次の表現は、変数$context.addressのコンテンツを評価し、そしてその結果をアンカータグのhref属性に入れる。
<a href=”{$context.address}”>Click</a>
あるアクションは、このコンテクスト変数の値を変化させる。
$context.address = ”mailto:alchemy@bea.com”;
これは、コントロールがページへ戻されたときに、次のXHTML表現を発生させる。
<a href=”mailto:alchemy@bea.com”>Click</a>
システム変数
このセクションは、一実施形態において経歴スタックに維持される3つのシステム変数($current、$context、及び$page)を詳述する。
$current
$current変数は、ノードリスト(1つ以上のノード)を参照する。これは、ノード又はnodeset、或いはノードリストを生じる評価されたSPath表現に対する明確な参照でよい。
テンプレートは、単一ノード又はノードリストをハンドリングするように設計される。$current[0]は、単一ノードを指すように保証される。又、$current.length()表現は、ノードリスト内のノードの数を検出するのに使用できる。
例えば、CRMアプリケーションは、単一アカウントノードを指すことを$currentに期待するaccountDetail.tmplページを実施してもよい。
<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>
逆に、contacts.tmplページは、全てのアカウントに対してコンタクトの全組を含むことを$currentに期待する。
<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
コンテクスト変数は、多ページプロセスを整合するためにテンプレート及びアクションに対する「スクラッチパッド」を与え、それらは、概念的には、セッション変数と同様である。
コンテクスト変数は、アクション内で実行される指定オペレーションによって生成される。
$context.foo = 100;
$context.foo.bar = <bar>FooBar</bar>
テンプレートは、表現言語シンタックスを使用してコンテクスト変数を参照する。
<p>{$context.foo}</p>
<p>{$context.foo.bar}</p>
アクションは、全ての現在コンテクスト変数を除去するために$contextオブジェクトにおけるreset()ファンクションをコールすることができる。
$context.reset();
$page
$page変数は、現在レンダリングされたテンプレートを含む。これは、現在レンダリングされたページ内のHTMLコントロールの状態をアクセスするためにアクションにより使用される。
XHTMLタグ表現
このセクションは、クライアントフレームワークによりサポートされるXHTMLへの拡張を詳述する。
一実施形態において、テンプレートは、充分に形成され及び検証されたXHTMLを含まねばならない。このセクションに述べるXHTML拡張は、netui namespace内に定義され、全ての例は、次のnamespace宣言を必要とする。
<html xmlns=”http://www.w3.org/1999/xhtml”
xmlns:netui=”http://www.bea.com/netui”>
アンカータグ
<a>(アンカー)タグは、ユーザがクリックして事象をトリガーさせることのできるハイパーリンクを生成する。アンカーは、ナビゲーションを行い、システムファンクション(アイテムの選択を含む)を呼び出し、そしてアクションを呼び出すのに使用される。
アンカーは、SPath表現(例えば、$current.@@orders.*)を指定することができ、これは、コントローラが、$current変数の値を変更して、異なるノード又はnodesetを指すようにさせ、これは、ナビゲーションとして知られている。
アンカーは、種々のシステムファンクションの1つを呼び出すことができる。例えば、navigate()ファンクションは、特定のテンプレートへナビゲーションし、そして$current変数をセットし、リピータ内でコールされるselect()ファンクションは、リスト又はテーブルから特定のノードを選択するのに使用される。
アンカーは、テンプレートにボンディングされたコンテクスト変数を処理して計算を実行するか又はデータを変更し得るアクションを呼び出してもよい。このアクションは、次いで、現在ページへ直接戻ってもよく、この場合には、コントロールからバインディングされるデータが更新され、そして表示がシームレスにリフレッシュされる。又、アクションは、コントローラが$current及び$page変数を変更させて、ナビゲーションを生じさせてもよい。
<a href=”url”/>
アンカーは、次の属性を使用することができる。
Figure 0004551899
url属性は、次のフォームの1つをもつことができる。
Figure 0004551899
アンカーは、通常、異なるページへナビゲーションするか、又はデータを選択するのに使用される。
ナビゲーション
ナビゲーションは、種々の手段によって達成することができ、以下の例では、ブラウザがルートノードへナビゲーションさせる。
<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>
例1は、SPath表現を宣言し、これは、コントローラにより直接評価され、そして$currentの値をセットするのに使用される。
例2は、システムnavigate()ファンクションをコールし、これは、$currentを、評価されたSPath表現にセットし、そして任意の第2パラメータを使用して、テンプレートをセットする。
例3は、ユーザアクション(コントローラファイルで定義された)を呼び出し、これは、通過されたパラメータを使用して、フォワードオブジェクト(アレー)を生成し、これは、例2と同じ作用を有する。
例4は、home()システムファンクションを呼び出し、これは、$historyオブジェクトにおいてコールされる。
選択
次の例は、1組の注文をリストし、そしてそれらの1つをクリックすることにより「選択された注文」として「選択」することを示す。
<netui:repeater id=”foo” source=”$current.@@orders.*” iterator=”$thisorder”>
<a href=”$foo.select($thisorder)”>{$thisorder.label()}</a>
</netui:repeater>
次の例は、一度に1つの注文を表示し、そしてそれらを通して前後にユーザを移動させる。
<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>
フォーム
一実施形態において、データを表示するために、必要とされるものは、カーリーブレースにエンクローズされたSPathだけである。
例えば、$currentがコンタクトを参照する場合には、次のものがコンタクトのネーム及びアドレスを示す。
<tr>
<td>First:</td><td>{$current.name.first}</td>
<td>Last:</td><td>{$current.name.last}</td>
</tr>
しかし、これは、リードオンリモデルである。
一実施形態において、変数へ書き込みするために、HTMLフォームエレメントは、netui:bind属性を追加してユーザ入力をデータモデルへマップするようにしてサポートされる。

Figure 0004551899
次のHTMLフォームエレメントは、読み取り/書き込み変数をバインディングするためにサポートされる。
Figure 0004551899
これらのタグの各々は、netui:bind属性をサポートし、これは、SPath表現を使用して読み取り/書き込み変数を参照する。
<input type=”intputType” netui:bind=”SPath”/>
SPath表現は、通常、$context変数を参照する。例えば、
<input type=”text” netui:bind=”$context.address.name”/>
この変数は、ページがレンダリングされるときに入力フィールドの値をセットするのに使用される。
バインディングされた値は、サブミットアクションが呼び出されたとき(以下の<input type=”submit”タグを経て行うことを含む)、又はナビゲーションが行われるとき(上述したアンカーを参照)、変数へ書き戻される。
入力タグ
<input>タグは、type属性の値に基づいて種々の簡単なコントロールを実施する汎用の入力タグである。
<input type=”inputType” netui:bind=”spath-expr”/>
フレームワークは、netui:bind属性を、XHTMLでサポートされる標準的な属性に追加する。
<input>タグの次のタイプがサポートされる。
Figure 0004551899
以下の例は、<input>タグの種々のフォームを示す。
<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”/>
無線
無線タグは、単一の値だけを選択してもよいようにグループ分けすることができ、同じ論理的グループ内の各無線タグを同じSPath表現にバインディングしなければならない。
<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>
現在選択されたコントロールは、value属性により指定された値をSPath表現にバインディングする。value属性が指定されない場合には、ブールの値trueがセットされる。
サブミット
サブミットのタイプは、onClick属性を定義し、これは、アンカー(上述した)と同様に振舞う。
<input type=”submit” onClick=”$pageFlow.submitContact()”/>
これは、クリックされると、バインディングされた全ての変数(ページ上の)を、現在入力タグ値と共に書き込ませる。
TextAreaタグ
<textarea>タグは、ユーザがテキストの多数のラインを入力及び編集できるようにし、これは、スクロールバーの表示を伴ってもよい。
<textarea netui:bind=”spath-expr”/>
フレームワークは、XHTMLでサポートされた標準的属性にnetui:bind属性を追加する。
例えば、次のXHTMLエレメントは、<textarea>エレメントを生成し、これは、$context変数により参照されるノートノードのcomments子エレメントにバインディングされる。
<textarea netui:bind=”$current.note.comments”/>
セレクトタグ
<select>タグは、ユーザがドロップダウンコントロールから多数のアプリケーション定義値の1つを選択できるようにする。
<select netui:bind=”spath-expr”/>
フレームワークは、HTMLでサポートされる標準的属性にnetui:bind属性を追加する。
contactTypeスキーマ定義は、salutationエレメントを含み、これは、contactSalutationEnumタイプを有するように定義される。
<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>
次のXHTMLは、<select>エレメントを生成するのに使用される。
<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>
netui:bind表現に一致する値は、デフォールトオプションとして選択されることに注意されたい。バインディングされた値がナルである場合には、最初のオプションが選択される。

次の例は、emailコンテクスト変数をテキスト入力フィールドにバインディングする。それに対応するアクションは、フォームのアクション属性を使用して呼び出すこともできるし、又はネスト状のアンカータグで呼び出すこともできる。
<form netui:action=”$pageFlow.inputEmailAddress()”>
<input type=”text” netui:bind=”$context.email”/>
<input type=”submit” value=”Submit”/>
</form>
典型的に、コンテクスト変数は、最初、テンプレートを表示させる先行アクションにおいてインスタンス生成される。次のアンカーは、addContact()アクションを呼び出す。
<a href=”$pageFlow.addContact()”/>Create New Contact</a>
このアクションは、次いで、3つのコンテクスト変数を生成し、次いで、addContactテンプレートを表示するようにコントローラに指令する。このアクションは、最初、既存の全てのコンテクスト変数をリセットし、次いで、指定演算子を使用して新たな変数を生成する。
function addContact() {
$context.reset();

$context.account = $current;
$context.salutation = ””;
$context.first = ””;
$context.last = ””;
$context.email = ””;

return [”addContact.tmpl”];
}
addContactテンプレートは、バインディングされた入力フィールドをもつフォームを表示する。
<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>
バインディングされた変数を含むテンプレートがアクションを呼び出すときに、それら変数は、現在XHTMLフォーム値でセットすることができる。これらの場合に、サブミット<input>エレメントは、以下に示すフォームのcreateContactアクションを呼び出す。
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>タグは、計算された条件に基づきXHTMLセグメントを条件付きで含むように使用することができる。
<netui:if cond=”spath-expr”>...</netui:if>
cond属性は、ページがレンダリングされるときに評価されるSPath表現を定義する。この表現が真と評価される場合には、<netui:if>エレメント内に含まれたXHTMLセグメントがXHTMLページに挿入される。
表現は、標準的XScript強制を使用して、ブールの結果を評価する。次の表現は、全て、真と評価される。
{true}
{100}
{”some string”}
{<xml>}
{$root}
以下の例は、条件付きテンプレートを実施するために<if>タグを含む。ここで、$current.emailテーブル列は、変数が非ナル(即ち、空又はゼロ長さのテキスト)の場合にのみ表示され、他の全ての値は、真に強制される。
<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>
条件付きテンプレートは、テンプレート設計におけるプロパティシートとして表示できることに注意されたい。
リピータタグ
テンプレートは、データグラフ及びシステム変数からの普通のXHTMLエレメント及びデータを合体する。又、それらは、レンダリングされるときにXHTMLを発生するエレメントを含んでもよい(JSPにおけるTaglibsと同様に)。
リピータは、エレメントリスト(例えば、アカウントのノードリスト)にわたって中継するHTMLジェネレータタグである。<netui:repeater>は、エレメントに対して同じHTMLを中継するのに使用されるタグであり、<netui:repeater>エレメントの全ての子エレメントは、評価されたSPath表現の各エレメントに対して中継される。
シンタックス
<netui:repeater
id=”tag-id”
source=”spath-expr”
[iterator=”variable-name”]
[selected=”spath-expr”]
[orderBy=”orderBy-expr”]/>
各<netui:repeater>エレメントは、それが繰り返さねばならないところの1組のノードを記述するsource属性を有する。概念的には、テンプレート内部の全てのXHTMLは、source属性により記述される各ノードに対して中継される。中継されるXHTMLセグメントは、iterator属性により参照される繰り返されるノードインスタンスにアクセスすることができる。
リピータは、次の属性を定義する。
Figure 0004551899
次のファンクションは、リピータオブジェクトにおいてコールすることができる。
Figure 0004551899
セクションの中継
次のテンプレートセグメントは、アカウントkeyrefにより定義されるノードのリストを表示するリピータを定義する。
<ul>
<netui:repeater id=”$repeater1” source=”$current.@@accounts.*” iterator=”$i”>
<li>{$i.label()}</li>
</netui:repeater>
</ul>
これは、次の出力を生成する。
Figure 0004551899
<netui:repeater>エレメント内に含まれた全てのXHTMLエレメントは、source属性により定義されたノードリスト内の各ノード(即ち、各アカウントノード)に対して中継される。
ナビゲーション及び選択
中継されたセクションは、アクション又はシステムファンクションを呼び出すアンカーを含んでもよい。例えば、以下のリピータは、アカウントのリストを表示し、アンカー(ハイパーテキスト)を各アカウントのラベルと共に表示する。
<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>
アンカーの1つをクリックすると、システムナビゲーションファンクションを呼び出させ、コントローラが、showDetail.tmplテンプレートへナビゲーションするようにさせ、$currentは、対応する中継エレメントに対して$iの値により参照されるノードを指すようにセットされる。
リピータは、ユーザがリストから特定のエレメントを選択できるようにする内蔵ファンクションselect()を実施する。例えば、次のテンプレートセグメントは、上記ノードリストをHTMLアンカーのリストとして表わす。
<ul>
<netui:repeater id=”$repeater1” source=”$current.@@accounts.*” iterator=”$i”>
<li><a href=”$repeater1.select($i)”>{$i.label()}</a></li>
</netui:repeater>
</ul>
特定のアンカーをクリックすると、リピータのselected属性を$i変数の現在値にセットさせる。テンプレートの他の部分は、リピータの現在選択値を参照してもよい。
<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>
これは、次の出力を生成する。
Figure 0004551899
上記<a>アンカーは、関連アイテムが選択された場合にエレメントのバックグランドカラーを変更するSPath表現を含むスタイル属性を宣言する。
selected属性は、他のリピータ(チェーンとして知られている)及びその後に呼び出されるアクションによりアクセスすることができる。又、中継されるHTMLセクションは、selected属性を参照して、現在選択されたアイテムを視覚指示することもできる。
チェーン型リピータ
リピータは、親リピータにおけるエレメントの選択が子リピータにおいて表示されるものに影響するように、一緒にチェーン接続することができる。例えば、次のリピータは、手前のリピータにおいて選択されたノード(Contact)に関連したメッセージのリストを表示する。
<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>
第1リピータは、keyrefアンカーのリストを発生し、第2リピータは、そのsource変数を以前のリピータの選択されたノードへバインディングし、そしてノードアンカーのリストを発生する。最終的なリピータは、contactノードのリストを発生する。このリピータのソース属性は、contacts keyrefへ特にトラバースし、自動化keyref列をスキップする。
リピータのselect()ファンクションが呼び出されると、テンプレートの再表示を自動的にトリガーし、従属するリピータのソースを変更すると共に、従属するリピータの選択された変数をナルへセットする。テンプレートは、リピータ間の円形依存性を回避しなければならない。セレクトメカニズムは、テンプレートの現在カーソルが変化しないので、ナビゲーションとみなされない。
上記例は、次の表示を生じる。
Figure 0004551899
上記テンプレートは、UIのナビゲーション部分を表わし、エンドユーザが一連のkeyrefをトラバースできるようにする。
ノードのテーブルを表わすようにUIを更に変更することができる。例えば、
<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>
これは、次の出力を生じる。
Figure 0004551899
焦点型ピータ
又、リピータは、「焦点が当てられる」ように定義されてもよく、これは、source属性により定義されたエレメントの全集合にわたって繰り返すのではなく、リピータが一度に1つのエレメントしか示さず、カーソルを維持することを意味する。
次の付加的なファンクションは、焦点型リピータオブジェクトにおいてコールされてもよい。
Figure 0004551899
次の例において、焦点属性は、nodesetからの単一ノードを表示すべきであることを宣言する。以下のアクションは、焦点型リピータを含むテンプレートを呼び出し、そして指定のアカウントのコンタクトkeyrefに関するノードリストに$currentをセットする。
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>
これは、次の出力を生成する。
Figure 0004551899
デフォールトにより、焦点型リピータは、カーソルを、$currentノードリストにおいて最初のノードを指すようにセットする。selected属性が定義された場合には、これを使用して、カーソルを適当なノード(通常、手前のアクションによりセットされたコンテクスト変数により定義された)にセットする。
<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>
分類型リピータ
リピータは、orderBy属性を宣言することによりエレメントが列挙される順序を指定できる。orderBy属性は、XQuery状の表現を含むストリングである。
<netui:repeater id=”id” source=”source” iterator=”var”
orderBy=”OrderByClause”>
orderByClauseが次のBNF文法に合致する場合(SPath表現は、特定のリピータアイテムに対するフィールド値を表わす):
OrderByClause ::= OrderSpec (”,” OrderSpec)*
OrderSpec ::= SPath OrderModifier
OrderModifier ::= (”ascending” | ”descending”) ?
((”empty” ”greatest”) | (”empty” ”least”)) ?
(”collation” StringLiteral)?
この表現は、安定な順序(即ち、多数の呼び出しにわたって等しい値の順序を保持しなければならない)を仮定することに注意されたい。
例えば、次のリピータは、コンタクトのラストネーム(即ち、$i.last)の降下する値によりコンタクトをリストする。
<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”>
上記例では、空きのラストネーム値は、最下位とみなされることに注意されたい。
メタデータリピータ
又、リピータは、データモデルにより定義されたメタデータにわたって繰り返すように使用することもできる。
例えば、node.keyref(‘*’)ファンクションは、対応するnodetypeからの考えられるナビゲーションを記述するkeyrefエレメントのリストを返送する。これは、keyrefのリストを表示するためにリピータのソースとして使用されてもよい。
<ul>
<netui:repeater id=”$repeater1” source=”$current.@@keyref(*')” iterator=”$i”>
<li>{$i.label()}</li>
</netui:repeater>
</ul>
上記例は、$currentがaccountノードを指す場合に、次の出力を返送する。
−owner
−subAccount
−contacts
−notes
−events
−qutotes
node.schema()ファンクションは、対応するnodetypeのXMLスキーマ定義を表わすXML文書を返送する。これは、入力フォームを形成するためのリピータのソースとして使用されてもよい。
<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>
上記例は、次の出力を発生する。
Figure 0004551899
映像タグ
標準的なXHTML<img>タグは、映像を表示するのに使用される。
<img
[src=”filename”]
[netui:content=”spath-expr”]
[netui:type=”content-type”]/>
映像タグは、次の属性を定義する。
Figure 0004551899
標準的なXHTML属性に加えて、フレームワークは、映像のバイナリーソースを含むエレメントを参照するSPath表現を宣言するためにnetui:content及びnetui:type属性をサポートする。これは、nodetypeの1つがそのXMLスキーマ定義内の適当なエレメントを定義することを要求する。
例えば、以下のコンタクトスキーマは、<image>データエレメントを合体するように拡張されている。
<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>
これは、次のXHTMLを使用して参照される。
<img netui:content=”$current.contact.image” netui:type=”bmp”/>
includeタグ
標準的な<netui:include>タグは、参照されたものを挿入するのに使用される。
<netui:include template=”templateFile” [$current=”spath-expr”]/>
includeタグは、現在ページへ挿入されるべきテンプレートを命名するtemplate属性を定義する。任意のcurrent属性は、$currentを、挿入されたテンプレートの範囲内にセットするのに使用される。
例えば、次のXHTMLセグメントは、例えば、チェーン型リピータを拡張し、そしてコンタクトのリストを表示する(特定アカウント$yに対して)新たなリピータ($z)を合体する。<netui:include>タグは、detail.tmplテンプレートを含み、そしてリピータの選択されたノード(即ち、コンタクトノード)となる$current変数を定義する。
<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>
detail.tmplテンプレートは、次のように定義される。
<td>
<table><tbody>
<tr><td>Detail</td></tr>
<tr><td>{$current.label()}</td></tr>
<tr><td>{$current.email}</td></tr>
</tbody></table>
</td>
これは、次の出力を生じる。
Figure 0004551899
HTMLタグ
<netui:html>タグは、生のXHTMLを現在ページに挿入するのに使用される。
<netui:html>{spath-expr}</netui:html>
通常、SPath表現が評価され、そしてそれにより生じる値がストリングとして解釈され、HTMLとして処理されない。しかしながら、オープニングとクロージングの<netui:html>タグ間に含まれた全ての評価されたSPath表現は、ブラウザにより処理されるべきHTMLとしてページに挿入される。
例えば、次のアクションコードが与えられると、
$current.productDesc = ”<p>A <b>great</b> new product.</p>”;
次のテンプレートHTMLは、以下の出力を返送する。
<netui:html>{$current.productDesc}</netui:html>
優れた新規製品
HTML及び表現は、<netui:html>エレメント内に合成されてもよい。例えば、次のテンプレートHTMLは、以下の出力を返送する。
<netui:html>
<ul><li>{$current.productDesc}</li><li>{$current.productDetail}</li><ul>
</netui:html>
−優れた新規製品
−あなたにウェブロジックを運ぶ人々から
コントローラ
コントローラは、外部同期メッセージに応答してユーザインターフェイス及びデータベースにより引き起こされた事象を処理する責任をもつことができる。コントローラは、アクションスクリプトを実行させ、且つテンプレートをブラウザによりインスタンス生成して表示させることができる。コントローラのデフォールト振舞いは、XMLに対してECMAScriptで書かれ且つ本質的にJPFのECMAScriptバージョンであるcontroller.xpfを実施することにより、拡張できる。
コントローラファイルは、アクション及び普通のECMAScriptファンクション、並びにグローバルな変数定義を含むことができる。
ページフロー
controller.xpfファイルは、アプリケーションに関するページフローを定義することができる。アプリケーションのクライアント部分は、コントローラ定義、アクション、及び1組のテンプレートで構成される。
コントローラファイルは、XScriptファンクション及びアクション定義で構成することができる。アクションは、テンプレート(及び他のアクション)により呼び出され、そして同じ$root、$current及び$context変数にアクセスすることができ、それらは、$current変数を直接変更することができず、むしろ、フォワードアレーを返送し、これは、$current及び$pageの値を決定するようにコントローラにより解釈される。アクションは、ページへ及びページから状態を通すのに使用される新たな$context変数を追加し及び変更することができる。このコンテクスト状態は、経歴スタックにも記憶される。
各アプリケーションは、開始ファンクション(又はアクション)の定義を最小限含まねばならないコントローラファイルを定義し、これは、アプリケーションが実行されるときにコールされる。最小限、開始ファンクションは、表示されるべき第1テンプレートのfilenameを含むフォワードアレーを返送しなければならない。
function begin()
{
return [”home.tmpl”];
}
フォワードアレー
フォワードアレーは、XScriptオブジェクト(即ち、ストリング、変数、SPath表現)のアレーであり、これらは、表示すべき次のテンプレート(即ち、$page変数)を決定しそして$currentシステム変数の値をセットするためにコントローラにより解釈される。
フォワードオブジェクトの次のタイプが定義される。
Figure 0004551899
フォワードアレーは、任意の順序のフォワードオブジェクトで構成できる。これは、多数のSPath表現、多数のテンプレートfilename、又はテンプレートfilename及びナビゲーションストリング定数(例えば、”CONTINUE”)を含まなくてもよい。次のものは、全て、リーガルフォワードアレーである。
return [”BACK”]
return [”home.tmpl”];
return [”home.tmpl”, $root.@@accounts.*];
return [nextAction];
return [];
何も返送しないか又は空のフォワードアレーを返送するアクションは、$page及び$current変数を変更せず、これは、[”CONTINUE”]の返送と透過であることに注意されたい。
以下の例では、アクションは、コンテクスト変数を使用して計算を実行すると共に、それが成功すると、showOrderテンプレートへナビゲーションする。アラーが生じると、アクションは、エラーコンテクスト変数をセットし、そして現在テンプレートに留まるようにコントローラに指令する。
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”];
}
アクション
アクションは、アプリケーションがデータを変更し、現在テンプレートを変更し、又はナビゲーションに影響を及ぼすためのメカニズムを与えることができる。例えば、アクションは、データノードを生成又は更新し、特定のnodesetにおける合計を計算し、或いはブラウザをデータモデルの異なる部分へ向け直してもよい。一実施形態では、テンプレートは、ローカルデータキャッシュ(又は$context)に記憶されたデータしかアクセスできないので、アクションは、外部システムと対話する(オンターネットを経て)メカニズムを与える。
アクションは、テンプレートアンカーにより呼び出される。アクションの呼び出しは、同じシンタックスを普通のECMAScriptファンクションとして使用するが、それらは、$pageFlow(コントローラ)オブジェクトにおけるメソッドとして呼び出される。
$pageFlow.actionName([param1[, param2[, ...]]])

次のアンカー宣言は、foo()アクションを呼び出し、ストリングパラメータにおいて通過させる。
<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”];
}
この場合、アクションは、$context変数(入力パラメータを含むXMLオブジェクト)をセットし、そしてコントロールを現在テンプレートへ戻す。
次の例は、$current変数を、accounts keyrefにより含まれたnodesetにおけるポイントへ変化させるフォワードオブジェクトを返送する。
function example1($p) {
...
return [$root.@@accounts.*];
}
次の例は、$currentをルートノードにおけるポイントへ変化させ、そして現在テンプレートも変化させる。
function example2($p) {
...
return [$root, ”bar.tmpl”];
}
タイマー
タイマーは、簡単な事象発生メカニズムを実施する。addTimer()ファンクションは、指定の遅延の後に、任意であるが規則的な間隔で呼び出されるコールバックファンクションを登録するのに使用される。
var timerId = $pageFlow.addTimer(callback, delay[, period]);
このファンクションは、$pageflowオブジェクトにおいてコールされ、そしてタイマーインスタンスを独特に識別する識別子を返送する。
Figure 0004551899
cancelTimer()ファンクションは、タイマーをキャンセルするのに使用される。
$pageFlow.addTimer(timerId);
このファンクションは、$pageflowオブジェクトにおいてコールされ、そしてタイマーインスタンスを独特に識別する識別子を返送する。
Figure 0004551899

次の例において、ファンクションfoo()は、タイマーをセットし、該タイマーは、bar()ファンクションを直ちにスケジュールし、次いで、1秒間隔で繰り返しスケジュールする。
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);
}
}
ここで、コールバックファンクションbar()は、SPath表現により定義されたデータセットを更新するためにサーバーをポーリングするディープセレクトオペレーションを呼び出す。タイマーは、cancelTimer()システムファンクションをコールすることにより、10番目の呼び出しでキャンセルされる。
ブラウザは、単一スレッドの実行モデルを実施し、それ故、コールバックファンクションは、少なくともコールファンクションが戻るまで実行されない。
経歴
ナビゲーションが行われるたびに、<$current x $context x $page>タプルが、$historyシステム変数によりアクセスできる経歴スタックに入れられる。
back()システムアクションをコールすると、これらの値を以前の経歴状態へロールバックさせ、同様に、forward()は、これらの値を次の経歴状態へ移動させる。ユーザが後方に移動しそして異なるナビゲーションを生じさせる場合には(即ち、前方に移動するのではなく)、全フォワード経歴が裁断される。
経歴スタックを通して前後に移動することで、全リピータの現在選択された値が保存され、又、全$context変数が経歴フレームの一部分であるから、フォーム値も保存される。
$historyオブジェクトについて定義されるファンクションは、前記で定義された。
ページフローの例
図10は、CRMアプリケーション1000の一部分の簡単なページフローを示し、ダイアグラムa)は、データモデルの一部分(スキーマ及びkeyref)を表わし、そしてダイアグラムb)は、$current nodetypeを指示する点線を各々もつ4つのテンプレートで構成されたページフローを表わす。このシナリオは、特定のアカウントに対するクオテ(quote)要求を開始するためにカスタムオペレーションを実施する。この例は、セレクトオペレーションのコンテクストとして使用されるカスタムオブジェクト(クオテ要求)を生成するプロセスを示す。
Homeテンプレートは、ユーザが、AccountDetailテンプレート(以下を参照)を呼び出す特定のアカウントへナビゲーションできるようにするリピータを含む。AccountDetailテンプレートは、以前の価格クオテのリストを示し、そしてユーザがcreateQuoteRequestアクション(A)を呼び出すことができるようにする。
<a href=”$pageFlow.createQuoteRequest()”>Create Quote Request</a>
これは、次のアクションを呼び出すようにさせる。
function createQuoteRequest() {
$context.quoteRequest.prodId = ””;
$context.quoteRequest.qty = 0;

return [”createQuoteRequest.html”];
}
このアクションは、現在コンテクスト内の<quoteRequest>XMLオブジェクトを生成し、そしてprodId及びqty子エレメントに対する値をセットする。これは、充分に形成された<quoteRequest>エレメントを生成し、次の表現と同等である。
$context.quoteRequest = <quoteRequest><prodId/></qty>0<qty></quoteRequest>;
このアクションは、次いで、「テンプレート」フォワード経路を返送し、$current変数を変更せずにcreatequoteRequestテンプレートを呼び出す。このcreatequoteRequestテンプレートは、以下に示す。$currentは、依然、アカウントノードを指すことに注意されたい。
<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>

Figure 0004551899
このテンプレートは、ユーザが、以前のアクションにより生成された<quoteRequest>エレメントを編集できるようにする。フォームサブミットアクションは、現在フィー無値を、バインディングされた$context変数へコピーし、次いで、以下のsubmitquoteRequestアクション(B)を呼び出す。
function submitQuoteRequest() {
if ($context.quoteRequest.prodId != ”” || $context.quoteRequest.qty <= 0) {
return [”CONTINUE”];
}
else {
$current.@@quoteRequests.create($context.quoteRequest);
return [”BACK”];
}
}
このアクションは、<quoteRequest>エレメントの値に関する検証を実行し、そしてエラーがない場合にテンプレート(CONTINUE)へ戻る。さもなければ、<quoteRequest>エレメントを、現在アカウントに対するquoteRequest keyrefに追加する。$context.quoteRequest変数は、フォームからバインディングされた値を含む充分に形成された<quoteRequest>エレメントであることに注意されたい。例えば、
<quoteRequest>
<prodId>Widget-Z</prodId>
<qty>1000</qty>
</quoteRequest>
成功すると、このアクションは、”BACK”を、以前のAccountDetailテンプレート(BACK)へナビゲーションする。AccountDetailは、以下のように、同期されたpriceQuotesのリストを表示する。
<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>
このテンプレートは、以下の表示を生成する。
Figure 0004551899
前記のsubmitquoteRequestアクションは、直ちに戻り、従って、新たなquoteRequestノードは、サーバーが同期されたquoteノードで応答するまで、価格フィールドを表示しないことに注意されたい。
プロートタイプの構築
プロートタイプを構築して実行するために、次のアプリケーションをインストールする必要がある:Apache Ant、Sun java JDK、Perforce client、BEA Workshop 8.1。又、次の環境変数もセットしなければならない。
Figure 0004551899
このチュートリアルは、パーフォース(Perforce)クライアントが、//alchemy/masをc:\alchemy\masにマッピングするビューと共に設定されると仮定する。次のコマンドを使用して、最新のソースコードを同期させ、そしてフレームワークを再構築する。
C:\alchemy\mas> p4 sync
C:\alchemy\mas> ant rebuild
アプリケーションの実行
プロートタイプブラウザは、ブラウザのant構築ファイル(\alchemy\mas\src\browser\build.xml)を経て呼び出すことができる。
次のランタイム変数が定義される。
Figure 0004551899
例えば、次のコマンドは、指定のウインドウサイズをもつナビゲータアプリケーションを実行するブラウザを呼び出す。
ant f ..\..\src\browser\bulid.xml Dmas.appname=crm Dclient.geometry=400x200
run
このコマンドを呼び出すためにバッチファイル(例えば、run.bat)を生成するのが便利である。
又、ブラウザは、次の環境変数を設定することにより構成できる。
Figure 0004551899
プロパティ変数は、次の設定を含んでもよい。
Figure 0004551899
例えば、次のコマンドは、ブラウザをクライアントモードにおいて実行し、そしてデータ持続性をターンオンする。
set MAS_PROPS=-Dmas.singleproc=false Dpersistent=true
サービス定義(コンジットメタファイル)において定義されたウェブサービスURLは、ウインドウズ(登録商標)ホストファイル(C:\WINDOWS\SYSTEM32\DRIVERS\ETC\host)において物理的IPアドレスを宣言することにより物理的サーバーへマップすることができ、例えば、次のホストファイルは、上記ウェブサービスを、alchemyテストサーバーへマップする。
172.17.33.34 example.com
デバッギング
全てのエラー及びトレース情報は、\alchemy\mas\alchemy.logファイルへ書き込まれる。
アプリケーションパッケージング
以下のテーブルは、個々のMASアプリケーションに対してファイル及びディレクトリー構造を表わす。
Figure 0004551899
プロートタイプは、schemas及びmetaディレクトリー内に全てのファイルをロードする。
アプリケーションルートディレクトリー(/apps)は、mas.approot及びmas.cliant.approotのランタイムプロパティ(上述した)に対応する。
アプリケーションの配備及びマネージメント
アプリケーションは、MAS(ワークショップ内で実行される)からクライアントへ配備することができる。
1.ワークショップは、アプリケーションマネージャーサーバーにおいて実行されねばならない(以下を参照)。
2.アプリケーションコンポーネント(上述したコントローラテンプレート、メタファイル、及びスキーマファイル)は、先ず、単一ファイルに(app.zip)にジップされねばならず、これを行うために、新たなジップファイルを生成し、全appフォルダー(例えば、\mas\apps\crm)をWinZipへドラグする(NOTチェック状態で「全経路infoをセーブする」のを確保する)。
3.アプリケーションadminページ:http://www.localhost.com:7001/masを見る。これは、しばらくの間を要してもよいことに注意されたい。
a.”ブラウズ・・・”をクリックし、そしてジップファイルを選択する。
b.”配備”をクリックし、アプリケーションをサーバーへアップロードする(上述したmass.approotプロパティにより定義された位置において)。
4.adminページは、各アプリケーションに対して配備URLを表示する。
5.クライアントにアプリケーションを「インストール」するために、移動ブラウザを単一プロセスモードで実行する(mas.appプロパティを指定せずに;これは、appセレクタダイアログを呼び出す)。
set MAS_PROPS=-Dmas.singleproc=false
ant f ..\..\src\browser\bulid.xml run
6.アプリケーションURLを適当な編集ボックスにエンターし、そしてOKをクリックする。
アプリケーションマネージャーサーバーの実行
1.次のグローバル環境変数をセットする。
set JAVA_OPTIONS=-Dmas.approot=c:\alchemy\mas\apps
2.\alchemy\mas\src\masjws.workをワークショップへロードする。
3.プロジェクトパンにおいてcontroller.jpfファイルをダブルクリックする。
4.ライブラリーアップグレードについて促された場合には、イエスと言い、次いで、Installをクリックする。赤い”could not be replaced”警報は、安全に無視できる。
5.サーバーをスタートする(ツール→WebLogicサーバー→スタートWebLogicサーバー)。
6.サーバーがスタートした後、次のコマンドを実行する。(WebLogic配備エラーは安全に無視できる)。
C:\alchemy\mas > ant deploy
7.ワークショップから、controller.jpfファイルが選択された状態でランボタン(緑の三角形)をクリックする。最終的に(標準的なスローサーバーブートストラップスタフの後に)、インストールされたアプリケーション及びそれらのURLを、新たなアプリケーションをアップロードするための配備ボタンと共に列挙したウェブページを見なければならない。
8.クライアントアプリケーション配備についてc:\temp\appを生成する。
9.次の環境変数をセットする。
set MAS_PROPS=-Dmas.client.approot=c:\temp\apps -Dmas.singleproc=false
10.次のコマンドを実行する。
C:\alchemy\mas\src\browser > ant run
11.ウェブページ(上述した)にリストされたURLをダイアログにペーストしそしてInstallをクリックする。最終的に、アプリケーションは、コンボボックスにいっぱいにリストされ、そしてログインが可能となる
MASスキーマ定義
アプリケーションスキーマ定義は、次のスキーマディレクティブを使用して、パブリックMASスキーマファイルをインポートしなければならない。
<xsd:import namespace=”urn:bea.mas” schemaLocation=”mas.xsd”/>
MASスキーマファイルは、全てのフレームワークXMLタイプに対する定義を含む。
<?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>
自動ユーザインターフェイス
フレームワークは、ノードグラフをトラバースするのに使用できる自動ブラウザ(ナビゲータと称される)を合体する。以下の出力は、次のコマンドラインシンタックスを使用して、CRM例から発生される。
ant f ..\..\src\browser\bulid.xml -Dmas.app=crm Dmas.client.app=navigator
run
ナビゲータは、最初に、ルートノードに関連した全てのkeyref(即ち、アカウント)を示す。
Figure 0004551899
keyrefが選択されると、それに対応するノードが表示され、この場合には、account keyrefが選択され、そしてそれに対応するaccountノードが表示される。
Figure 0004551899
次いで、accountノードが選択され、そしてaccount nodetypeに関連したkeyref(即ち、sourceType=”account”)が表示される。
Figure 0004551899
ここで、contact keyrefが選択されると、contactノードの対応リストが表示される。
Figure 0004551899
このナビゲータは、上述した同じテンプレートリピータ及びナビゲーションメカニズムを使用する。それ故、カスタムテンプレート、アクション及びページフローと共にデフォールトナビゲーションを増分的に拡張することができる。
自動的なUIは、2つのテンプレートで構成され、即ち第1は、現在「焦点の合わされた」ノード($current)と、ユーザがナビゲートできるkeyrefのリストとを表示する「ナビゲータ」テンプレートであり、そして第2のテンプレートは、特定ノードの「詳細」フォームビューである。
ナビゲーションテンプレートにおいて、keyrefが選択されると、関連nodesetのノードリストがリストとして表示される。
<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>
ノードリストにおけるノード当たり2つのアンカー(ハイパーリンク)が表示され、第1のアンカー”NAV”は、ユーザが関連ノードへナビゲーションして、選択されたノード$jを伴う現在ナビゲータを$currentとして再表示できるようにし、第2のアンカー(強制されたノード$jのラベルを表示する)は、以下の詳細なテンプレートへナビゲーションする。
<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>
詳細なテンプレートは、現在ノードラベルを表示し、そしてノードのXML文書を通して繰り返すリピータであって、エレメントタグネーム及びそれに対応する値を表示するリピータを含む。
CRM例をナビゲーションする自動ブラウザの出力を以下に示す。
Figure 0004551899
第1ページは、ルートノードに焦点を当てたナビゲータテンプレートを示し、即ちユーザは、アカウントkeyrefを選択し、そして”Acme”アカウントにドリルダウンする。これは、同じナビゲータテンプレートにナビゲーションして、”Acme”アカウントノードを指すように$currentをセットする。次いで、ユーザは、コンタクトkeyrefを選択し、そして”Sarah Smith”に対するコンタクトレコードをクリックし、このとき、ナビゲータは、コンタクトを表わすノードに$currentがセットされた詳細なテンプレートを表示する。
ブラウザのバックボタンは、ユーザが詳細なテンプレートからナビゲータテンプレートへナビゲーションして戻すことができるようにする。
CRM使用ケースデータモデル定義
このセクションは、サンプルCRMアプリケーションの全てのアプリケーションコンポーネントを詳述する。
データモデル
上述したように、図5は、CRMアプリケーションに関するエンティティ関係ダイアグラム(ERD)を示す。
ルート及びユーザノードは、システムnodetypeである。ルートノードは、個々のユーザがアクセスできるデータを表わす仮想XML文書のルートを表わす。ユーザノードは、システムの個々のユーザを表わし、そしてシステムにより自動的に発生される。
ルートノードは、アカウントノードを含み、そしてアカウントkeyrefを定義する。各アカウントノードは、コンタクト、事象、ノート及びタスクノードを含んでもよく、そしてそれに対応するkeyrefを定義する。同様に、各コンタクトノードは、事象、ノート及びタスクノードを含んでもよい。又、アカウントノードは、サブアカウントを含んでもよく、そしてsubAccount keyrefを定義する。
アカウント及びコンタクトノードは、両方とも、システムユーザを参照する所有者keyrefを含み、同様に、タスク及び事象ノードは、指定された(ユーザ)keyrefを定義する。これらのkeyrefは、全て、カーディナリティが1である。
スキーマ及びkeyref定義
次のセクションは、5つのアプリケーションスキーマを詳述し、これらは、全て、/schema/crm.xsdファイルにおいて定義される。
<?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/”>
アカウントタイプ
account nodetypeは、次のスキーマにより定義される。
<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>
accountタイプは、nameエレメントで構成される簡単なラベル宣言を定義することに注意されたい。又、typeフィールドは、accountTypeの簡単なタイプ定義により定義された1組の制約された値を有する。
次のセクションは、第1の宣言されたkeyrefを示す/conduit/crm.jsxファイルの最上部を示す。アプリケーションは、app namespaceにおいて宣言されることに注意されたい。
<?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>
account keyrefは、ユーザのrootノードを1組のaccountノードに関連付ける。CRMアプリケーションでは、これは、rootノードにバインディングされた唯一のkeyrefである。
<keyref name=”accounts” sourceType=”mas:root” targetType=”app:account”/>
次のkeyref定義は、account nodetypeに関連している(即ち、その全てがapp:accountをsourceType属性として宣言している)。アカウントは、サブアカウント(subAccounts)と、コンタクト、ノート、事象、タスク及びクオテ要求に対するノードの組とを含む。
<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”/>
又、account nodetypeは、単一ユーザノードに対する参照(ルックアップ)も含み、これは、ノードの現在所有者を表わす。これは、カーディナリティ制約(厳密に1)を指定する次の宣言により表わされる。
<keyref name=”owner” sourceType=”app:account” targetType=”mas:user”
minOccurs=”1” maxOccurs=”1”/>
コンタクトのタイプ
contact nodetypeは、次のスキーマにより定義される。
<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>
account nodetypeは、最初と最後のネームエレメントを構成するラベル宣言を定義することに注意されたい。又、salutationフィールドは、contactSalutationEnumの簡単なタイプの定義により定義された1組の制約された値を有する。
次のkeyref定義は、contact nodetypeに関連する(即ち、その全ては、app:contactをsourceType属性として宣言している)。アカウントは、ノート、事象及びタスクに対するノードの組を含む。
<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”/>
又、contact nodetypeは、単一ユーザノードに対する参照(ルックアップ)も含み、これは、ノードの現在所有者を表わす。これは、カーディナリティ制約(厳密に1)を指定する次の宣言により表わされる。
<keyref name=”owner” sourceType=”app:contact” targetType=”mas:user”
minOccurs=”1” maxOccurs=”1”/>
ノートタイプ
note nodetypeは、次のスキーマにより定義される。
<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>
ノートは、keyref定義を含まない。
事象のタイプ
event nodetypeは、次のスキーマにより定義される。
<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>
又、event nodetypeは、単一ユーザノードに対する参照(ルックアップ)も含み、これは、事象の現在指定されたユーザを表わす。これは、カーディナリティ制約(厳密に1)を指定する次の宣言により表わされる。
<keyref name=”assigned” sourceType=”app:event” targetType=”mas:user”
minOccurs=”1” maxOccurs=”1”/>
タスクのタイプ
task nodetypeは、次のスキーマにより定義される。
<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>
又、task nodetypeは、単一ユーザノードに対する参照(ルックアップ)も含み、これは、事象の現在指定されたユーザを表わす。これは、カーディナリティ制約(厳密に1)を指定する次の宣言により表わされる。
<keyref name=”assigned” sourceType=”app:task” targetType=”mas:user”
minOccurs=”1” maxOccurs=”1”/>
QuoteRequestのタイプ
QuoteRequest nodetypeは、次のスキーマにより定義される。
<?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スキーマ定義を発生する。
<?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>
graphエレメントは、アプリケーションデータモデルの最上位レベルエレメントを表わし、これは、厳密に1つのrootノード宣言と、各アプリケーションスキーマ(アカウント、コンタクト、ノート、事象及びタスク)の各ノードに対する非制限宣言とを表わす。
次のタイプ定義は、アプリケーションスキーマ及びkeyref定義から発生される。
<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>
...
サンプルアプリケーションデータ
システムは、3人のユーザ、”alex”、”bob”及び”carol”を有する(これらは、仮想グラフに示されないシステムオブジェクトである)。

<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>
簡単なSPath表現
次のセクションは、幾つかのSPath表現と、上述したサンプルデータに基づいて予想される値とを示す。
次の表現は、account keyrefに対するnodeset(ノードのリスト)を返送する。
$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>
次の表現は、全accountノードに対する1組のネームエレメントを返送する。
$root.@@accounts.*.name

Acme
Bancroft
次の表現は、全てのアカウント命名Acmeに対する全てのコンタクトを返送する。
$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>
次の表現は、全てのコンタクト(全てのアカウントに対する)を指定のeメールアドレスと共に返送する。
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>エレメントに対する値をセットする。
$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>
次の表現は、指定のアカウントに対する新たなコンタクトを生成する。これは、システム変数を使用して、owner属性をセットすることに注意されたい。
$accountX.@@contacts.create(
<contact ownerId=”$globalApp.user”>
<salutation>Dr</salutation>
<first>David</first>
<last>Daniels</last>
<email>david@acme.com</email>
</contact>
);
次の表現は、指定のコンタクトに対する新たなタスクを生成し、これは、次いで、assigned keyrefを変更する。
var $newTask = <task>
<title>Perpare RFP</title>
<status>Not started</status>
</task>

$contactX.@@tasks.create($newTask);

$newTask.@@assigned = $root.@@users.*.where(.username == ”fred”);
CRM使用ケースウェブサービス定義
このセクションは、例示的CRMウェブサービスに対するWSDL(ワークショップにより発生された)の部分を示す。
<?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/”>
...
タイプの定義
WSDLは、2種類のタイプ定義、即ちメッセージパラメータに対する入力及び出力タイプ定義と、フィールドタイプ定義(個々の複雑なタイプに対する)とを含む。
<types>セクションは、オペレーション入力及び出力タイプと、オペレーションパラメータとして通された複雑なエレメントとに対するスキーマ定義を含む。
次のタイプ定義は、getAccountsByUserウェブサービスオペレーションに対する入力(getAccountsByUser)及び出力(getAccountsByUserResponse)メッセージタイプに関する。
<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>
次のタイプ定義は、全て、getContactsByAccount及びaddContactToAccountウェブサービスオペレーションに関する。
<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、バインディング及びサービス定義
コンジットは、portType定義と構造的に同様であり、portTypeオペレーションは、コンジットオペレーションへマップされ、入力及び出力エレメントは、transformOut及びtransformInのXQuery宣言に対応する。
<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>
SalesForceコンジット定義
次のコンジットファイルは、SalesForce.comウェブサービスと接続するコンジットの一部分を実施する。
/**
* @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)は、ウェブサーバーのように作用する。
サービスバスは、多数の位置からの情報を得るプロキシーである。サービスバスは、
−エンベローププロトコル、トランスポートプロトコル、セキュリティ機構、ペイロードコンテンツ、一方向及び要求/応答パラダイム、同期及び非同期通信、並びにポイント対ポイント及びpub/subのエリアにおいて送信者が送信しそして受信者が期待するメッセージ間のギャップを橋絡し、
−多行先パブリッシュ、コンテンツベースのルーティング、認証及び許可、並びに証明書マッピングのようなタスクを実行するために媒介物に付加的な計算能力を設け、
−メトリック収集及び表示、警告表示、追跡事象収集及び使用、メッセージアーカイブ及びSLAマネージメントと共に媒介物にモニタリング能力を設ける。
サービスバスは、媒介物である。サービスバスへのメッセージは、トランスポートを経て到来し、それをどこへルーティングするか決定するために処理し、そしてメッセージエンリッチメントのために変換する。次いで、再びトランスポートを経て退出する。応答は、逆の経路をたどることができる。メッセージが通過するときに1組の関心のあるリスナーへメッセージのコピーをパブリッシュすることができる。媒介物によるメッセージ処理は、コンソールを経て使用されるメタデータにより駆動することができる。
サービスバスは、WebLogicマネージサービスのクラスター化をサポートすることができる。コンフィギュレーション及びメタデータは、高速ローカル検索のためにマネージサーバーへ自動的に伝播される。モニタリングメトリックは、コンソールに集計して表示するために全てのマネージサーバーから自動的に収集することができる。
媒介物(プロキシーサービス)及び媒介物により呼び出される外部サービスは、両方とも、サービスとしてモデリングすることができる。
サービスは、次のものをもつことができる。
−トランスポートアドレス及び関連コンフィギュレーションを各々もつポーと称される(エンドポイントとも称される)1組の具体的なインターフェイス。1組のポートは、サービスに対する負荷バランス及びフェイルオーバー代替物を構成し、そして特性が同一である。
−単一の任意の抽象的インターフェイス(類似は、javaインターフェイス)であって、オペレーション(類似は、パラメータを伴うjavaインターフェイスのメソッド)によりおそらくブレークダウンされたインターフェイスにおいてメッセージ部分の構造を定義したもの。
−具体的なメッセージに対する抽象的インターフェイスのメッセージ部分のパッケージングを定義する単一のバインディング、及びトランスポートに対するそのメッセージのバインディング。
−WSセキュリティ(WSS)及びWS信頼性メッセージング(WS−RM)に対するポリシー、許可ポリシー、及びバインディングレイヤー(ロギングのような)により透過的に実行する必要のあるアクション。
HTTP(S)又はJMSトランスポートに基づく標準的なSOAPウェブサービスの場合には、抽象的インターフェイス、具体的インターフェイス及びバインディングのWSDL表示が可能である。WSDLリソース又は退出サービスを使用して、新たなサービスのインターフェイスの定義をジャンプスタート(jumpstart)することができる。
サービスバスは、JMS(BEA及び外部JMSプロバイダーのための)、HTTP(S)、eメール、ファイル、WS−RM及びFTPをサービストランスポートとしてサポートすることができる。サービスバスは、HTTP及びJMS非同期トランスポートに対して要求/応答及び一方向パラダイムの両方をサポートすることができる。又、任意であるが、メッセージの順序付けされた配送も、基礎的なトランスポートがこれをサポートする場合には、サポートできる。サービスバスは、XML、非XML(MFLと共に記述される構造)、バイナリー、アタッチメント(eメール)を伴うMIME、並びにSOAP1.1及び1.2(RPCスタイル及び文書スタイルの両方に対してアタッチメントを伴うか又は伴わない)パッケージングをサポートすることができる。
サービスは、同じバインディングに対して多数のポートをもつことができる。これらのポートは、負荷バランス及びフェイルオーバー代替物として使用することができる。サービスは、そのポートに対して使用するための負荷バランスポリシーを定義することができる。サポートされるポリシーは、ラウンドロビン及びランダム(重み付けされたもの又はされないもの)である。ポートは、負荷バランス行先として働くだけでなく、フェイル時にはフェイルオーバー代替物としても働く。2つのコンセプトは、HA負荷バランス機構に対して一緒に結合される。
又、サービスは、フェイル時の再試みポリシー及び(要求/応答に対する)時間切れポリシーを定義することもできる。
サービスは、そのインターフェイスにおいてメッセージに適用するセキュリティポリシーを定義することができる。これは、サービスレベル(全てのメッセージに適用する)において指定することもできるし、又はサービスのオペレーションに対して個々にメッセージにおいて指定することもできる。
サービスは、カテゴリーに分けることができる。カテゴリー機構を定義することができる。カテゴリーは、本質的にキーネームであり、そしてカテゴリー値は、キーネームに対する値である。サービスは、多数のカテゴリーネームに対して多数の値をもつことができる。カテゴリーは、発見目的に非常に有用である。キーネームと、値の許容ハイアラーキーとを定義する多数の標準的な存在論(又はカテゴリー機構)がある。サービスバスは、サービスをカテゴリー分けするためにハイアラーキーにおいてリーフ(葉)値の使用しか許さない。
サービスプロバイダーと称される組織又はアプリケーションにより1組のサービスを提供することができる。サービスのプロバイダーを定義することは任意であり、スタンドアローンサービスを得ることができる。これらは、エンタープライズにおける内部サブ組織でもよいし、外部パートナー組織でもよいし、又は個々のアプリケーションでもよい(セマンティックでは、ユーザまで)。又、サービスプロバイダーは、サーチのためのサービスのようにカテゴリー分けすることもできる。サービスプロバイダーは、証明書が関連付けられ、そしてユーザに結び付けることができ、従って、許可のための役割に属することができる。サービスプロバイダーは、メッセージを送信及び受信することができる。
サービス消費者は、組織又はアプリケーションであって、メッセージを送信する(又は同期応答を受信する)ことしかできない。又、サービスプロバイダーは、サーチのためのサービスのようにカテゴリー分けできる。サービス消費者は、証明書が関連付けられ、そしてユーザに結び付けられ、従って、許可のための役割に属することができる。
プロキシーサービスの実施は、パイプライン定義によって指定することができる。これは、要求パイプライン定義と、応答パイプライン定義とで構成される。パイプラインは、外部(又は別のプロキシー)サービスを呼び出す前にプロキシーサービスへの要求メッセージにおいてどんなアクションが実行されるか、及びプロキシーが応答を返送する前にプロキシーにより呼び出されたサービスからの応答においてどんな処理が実行されるか指定する。
各パイプラインは、一連のステージである。パイプラインに供給されたメッセージは、パイプラインステージによりアクセス又は変更できる1組のメッセージコンテクスト変数(メッセージコンテクストを含む変数を含む)を付随することができる。
パイプラインにおけるメインステージは、次の通りである。
−変換ステージは、構造をネスト状にすべき場合に、コンテクストに影響する実行されるべき変換を選択するのを許す。ウェブサービスコールアウト又はDBルックアップは、Xquery又はXSLT変換に対する代替物で、出力コンテクスト変数をセットするためのものである。
−ルーティングステージ(要求パイプラインにおいてのみ許された)は、構造及びケース構造を合成(及びネスト状に)すべき場合に、メッセージをルーティングする単一エンドポイント及びオペレーションを定義するのを許す。メッセージを各エンドポイントへパブリッシュする前に、コンテクスト変数に影響を及ぼす1組の変換を定義することができる。ウェブサービスコールアウト又はDBルックアップは、Xquery又はXSLT変換に対する代替物で、コンテクスト変数をセットすることができる。
−パブリッシュステージは、構造及びケース構造を合成(及びネスト状に)すべき場合に、メッセージをパブリッシュする1組のエンドポイント及びオペレーションを定義するのを許す。メッセージを各エンドポイントへパブリッシュする前に、コンテクスト変数に影響を及ぼす1組の変換を定義することができる。ウェブサービスコールアウト又はDBルックアップは、Xquery又はXSLT変換に対する代替物で、コンテクスト変数をセットすることができる。コンテクストに対する変更は、パブリッシュされた各エンドポイントに対して分離され、パイプラインによるその後の処理に影響しない。
−WSセキュリティ処理及び許可は、バインディングレイヤーにおいて透過的に実行される。
−追跡ステージは、ユーザ定義情報と共に追跡レコードを書き込むのを許し、従って、追跡システムを使用して、ユーザ定義基準によるサーチを行うことができる。
−アーカイブステージは、経歴及び記録保持の目的でメッセージをアーカイブに書き込む。
−ロギングステージは、デバッギングの目的で選択されたコンテクストをシステムログへロギングするのを許す。
−検証ステージは、MFLスキーマのXMLに対して文書を検証する。
−カスタムステージは、ユーザが、ステージSDKを使用してステージを実施する状態でそれ自身のアクションを定義するのを許す。
各パイプラインは、一連のステージで構成することができる。しかしながら、単一サービスレベル要求パイプラインは、任意であるが、オペレーションパイプラインへと分岐されてもよい(オペレーション当たりせいぜい1つ、そして任意であるが、デフォールトオペレーションパイプライン)。メッセージコンテンツからオペレーションを決定する標準的な方法はないので、オペレーションの決定は、ユーザ選択基準を通して行われる。応答処理は、当該オペレーションパイプラインでスタートし、このパイプラインは、次いで、単一サービスレベル応答パイプラインに参加する。
コンテクストは、要求パイプライン及び応答パイプラインの両方にわたって共有することができ、そしてその値は、個々の要求/応答メッセージに関連付けされる。コンテクストは、1組の予め定義されたXML変数である。新たな変数をコンテクストに動的に追加したり削除したりすることができる。予め定義されたコンテクスト変数は、メッセージに関する情報、トランスポートヘッダ、セキュリティプリンシパル、現在プロキシーサービスに対するメタデータ、並びにプロキシーサービスにより呼び出された一次ルーティング及びサブスクリプションサービスに対するメタデータを有する。コンテクストは、ステージによるXquery/Xupdate表現により読み取り及び変更することができる。
コンテクストのコアは、変数$header、$body及び$attachmentsである。これらは、SOAPヘッダー、SOAP本体コンテンツ、及びMIMEアタッチメントを各々含むラッパー変数である。コンテクストは、全てのメッセージがSOAPメッセージであり且つ非SOAPメッセージがこのパラダイムにマップされるという印象を与える。バイナリー又はMFLデータの場合には、$attachment又は$bodyにおける文書を表わすXMLエレメントが独特の識別子内の実際の文書を参照する。SOAP RPCの場合には、本体コンテンツは、それ自体、タイプされたRPCパラメータを含むラッパーエレメントである。
サービスバスは、設計時に望まれる場合に使用することのできる内蔵のタイプシステムを有することができる。設計時の条件又は変換においてXquery表現を生成するときには、Xqueryを容易に生成する助けとしてエディタにおいて1つ以上のタイプについて変数を宣言することができる。タイプは、XMLスキーマ、MFL又はWSDLリソースである。このタイプ宣言プロセスは、タイプされるべき変数の性質が分かる(タイプのエレメント又はタイプそれ自体に対するラッパーである)。又、これは、$bodyにおいてSOAP RPCパラメータ又は文書に容易にアクセスするための助けも与える。
各ステージは、そのステージにエラーが発生した場合に実行するための一連のステップを有することができる。この一連のステップは、そのステージに対するエラーパイプラインを構成する。更に、エラーパイプラインは、全パイプライン又は全プロキシーサービスに対して定義することもできる。存在する最も低い範囲のエラーパイプラインは、エラーの際に呼び出される。このエラーパイプラインは、メッセージをエンドポイントへパブリッシュするのを許し、プロキシーの呼び出し者へ返送されるべきエラー応答メッセージを作り上げ、メッセージをログし、コンテンツを変更した後に継続し、又は例外を生じさせる。例外を生じさせると、次に高い範囲のエラーパイプラインへコントロールが移管される。
要求パイプラインの処理は、インバウンドトランスポート処理、インバウンドバインディングレイヤー、パイプライン実行、アウトバウンドバインディングレイヤー、及びアウトバウンドトランスポート処理ステップで構成することができる。バインディングレイヤーは、メッセージをコンテクスト変数へ/コンテクスト変数からマッピングし、メッセージをパッケージング及びアンパッケージングし、そしてWSSセキュリティ及び許可を行うといった実行されるべき処理の幾つかを自動化する。一次ルーティング行先及びパブリッシュ行先の両方がこのパラダイムに続く。
一次ルーティングエンドポイントが呼び出された後に、応答パイプライン処理は、同様のモデルをたどる。
あるステージからのウェブサービスコールアウトは、バインディングレイヤー及びそれに続くトランスポートレイヤーを通して進む。コールアウト応答は、逆の経路をたどる。
ユーザは、人間、組織又はアプリケーションのいずれでもよいセキュリティプリンシパルである。ユーザは、UIインターフェイス(コンソールユーザ)、又はメッセージングインターフェイス(サービス消費者又はプロバイダーとしてモデリングされたユーザ)のいずれを呼び出すこともできる。
サービスバスリソースは、エンティティの再使用可能な共通の定義又は記述で、通常、そのエンティティに対するメタデータである。リソースは、多数のサービスにより使用することができ、そしてエンタープライズ又はデパートメントにわたって標準化された定義又は記述である。リソースは、例えば、カテゴリー機構、MFLスキーマ、XSDスキーマ、Xqueryマップ、XSTLマップ、WSDLインターフェイス、及びWSポリシーファイルである。
カテゴリー機構は、単一カテゴリーネームと、そのカテゴリーネームに対する値のハイアラーキーセットとを定義することができる。サービス、プロバイダー及び消費者は、登録された機構を使用してカテゴリー分けすることができる。それらは、カテゴリー機構に対する多数のリーフ値、又は多数のカテゴリー機構からのリーフ値でカテゴリー分けすることができる。
スキーマは、プリミティブ又は構造化データに対するタイプを記述することができる。MFLスキーマは、非XMLデータに対するタイプを記述する。XMLスキーマは、XMLに対するタイプを記述する。XMLスキーマタイプは、他のスキーマファイルをインポートし又はそれを含むことができる。
変換マップは、2つのタイプ間のマッピングを記述することができる。XSLTマップは、XSLT規格を使用してXMLデータに対するマッピングを記述する。Xqueryマップは、Xquery規格を使用してXML及び非XML(MFL)データに対するマッピングを記述する。
WSDLインターフェイスは、サービスインターフェイスに対するテンプレートであり、そのインターフェイスにおけるオペレーションを含むサービスの抽象的インターフェイスと、オペレーションシグネチャーにおけるメッセージ部分のタイプとを記述する。又、任意であるが、メッセージ(パッケージング)に対するメッセージ部分のバインディングと、トランスポートに対するメッセージのバインディングも記述する。又、任意であるが、サービスの具体的なインターフェイスも記述する。
WSポリシーは、セキュリティ及び信頼性のあるメッセージングポリシーを記述することができる。これは、どんなアルゴリズムを使用してメッセージに何をサインし又は暗号化すべきか記述することができる。又、受信時にメッセージに対してどんな認証メカニズムを使用すべきか記述することができる。
一実施形態において、随時接続アプリケーションサーバープラットホームは、既存のエンタープライズコンポーネントと一体化される簡単なウェブ状のプログラミングモデルで、精巧な移動ソルーションを開発し、配備しそしてマネージするフレームワークを提供する。
移動アプリケーションは、データモデル定義と、ユーザインターフェイステンプレートと、アクションを定義するスクリプトを含むクライアント側コントローラと、そしてサーバー側では、データモデルとエンタープライズとの間をいかに仲裁するか記述できるコンジットの集合とで構成することができる。随時接続アプリケーションサーバーは、移動アプリケーションにより使用される全てのデータが外部システムにより持続的に記憶されそしてマネージされると仮定できる。データモデルは、このデータについての移動アプリケーションの予想される使用のメタデータ記述であると共に、随時接続装置と外部システムとの間でのこのデータの効率的なトラバース及び同期を可能にするように最適化することができる。
随時接続データモデルは、持続的アプリケーションデータの構造(及び他のプロパティ)を記述することができる。モデルそれ自体は、移動ブラウザと同期させることができ、従って、クライアントは、インテリジェントにデータをトラバースすると共に、データをサーバーと同期させることができる。
本発明の他の特徴、態様及び目的は、添付図面及び特許請求の範囲から得ることができる。本発明の精神及び範囲内、そして特許請求の範囲内で、本発明の他の実施形態も開発できることを理解されたい。
本発明の好ましい実施形態の以上の説明は、単なる例示に過ぎない。これは、本発明を余すところなく示すものでもないし、又、ここに開示した正確な形態に制限するものでもない。当業者であれば、多数の変更や修正が明らかであろう。これら実施形態は、本発明の原理及びその実際の応用を説明するために選ばれたものであり、従って、当業者であれば、本発明、種々の実施形態、並びに意図された特定の用途に適する種々の変更を理解することができよう。従って、本発明の範囲は、特許請求の範囲によって限定されるものとする。
特別に設計された集積回路又は他の電子装置で構成される実施形態に加えて、本発明は、コンピュータ分野の当業者に明らかなように、本開示の教示に基づいてプログラムされた従来の汎用又は特殊なデジタルコンピュータ又はマイクロプロセッサを使用して便利に実施することができる。
ソフトウェア分野の当業者に明らかなように、熟練したプログラマーであれば、本開示の教示に基づき適切なソフトウェアコードを容易に準備することができよう。又、本発明は、当業者に容易に明らかなように、特定用途向け集積回路を準備するか、又は従来のコンポーネント回路の適切なネットワークを相互接続することにより、実施されてもよい。
本発明は、本発明のプロセスを実行するようにコンピュータをプログラムするのに使用できる命令が記憶された記憶媒体(メディア)であるコンピュータプログラム製品を包含する。記憶媒体は、フロッピー(登録商標)ディスク、光学的ディスク、DVD、CD−ROM、マイクロドライブ、磁気−光学ディスクを含む任意のタイプのディスク、ROM、RAM、EPROM、EEPROM、DRAM、VRAM、フラッシュメモリデバイス、磁気又は光学カード、ナノシステム(分子メモリ、ICを含む)、或いは命令及び/又はデータを記憶するのに適した任意の形式のメディア又はデバイスを包含し得るが、これらに限定されない。
コンピュータ読み取り可能な媒体(メディア)のいずれか1つに記憶されるものであるが、本開示は、汎用/特殊なコンピュータ又はマイクロプロセッサのハードウェアを制御すると共に、コンピュータ又はマイクロプロセッサが本発明の結果を利用して人間のユーザ又は他のメカニズムと対話できるようにするためのソフトウェアも包含する。このようなソフトウェアは、装置ドライバ、オペレーティングシステム、及びユーザアプリケーションを含むが、これらに限定されない。
汎用/特殊なコンピュータ又はマイクロプロセッサのプログラミング(ソフトウェア)には、本発明の教示を実施するためのソフトウェアモデルであって、随時接続アプリケーションサーバーのためのシステム及び方法を備えた(これに限定されないが)ソフトウェアモジュールが含まれる。
本発明の一実施形態に基づくアーキテクチャーの概要を示す図である。 本発明の一実施形態に基づくアーキテクチャーの概要を示す図である。 本発明の一実施形態に基づく同期対話図である。 本発明の一実施形態に基づくMASアプリケーションのためのプログラミングモデルを示す図である。 本発明の一実施形態に基づくエンティティ関係図である。 本発明の一実施形態に基づくUMLエンティティ関係図である。 本発明の一実施形態に基づくノードインスタンス図である。 本発明の一実施形態に基づくセレクト動作を示す図である。 本発明の一実施形態に基づく入力出力マトリクスを示す図である。 本発明の一実施形態に基づくCRMスキーマタイプの図である。 本発明の一実施形態に基づくCRMアプリケーションの一部分に対するページフローを示す図である。 本発明の一実施形態の同期方法を示す図である。 本発明の一実施形態の同期方法を示す図である。 本発明の一実施形態のkeyref定義を例示する図である。 本発明の一実施形態のkeyref定義を例示する図である。 本発明の一実施形態のkeyref定義を例示する図である。 本発明の一実施形態のkeyref定義を例示する図である。

Claims (21)

  1. 随時接続サーバーデバイスであって、
    前記随時接続サーバーデバイス上に記憶されている一組のデータノードを、前記サーバーデバイスによって提供されたアプリケーションに関してモバイルクライアントデバイス上に記憶されたデータノードと同期させる同期ユニットであって、前記アプリケーションが、前記データノードが前記モバイルクライアントデバイスによって要求される前に、前記モバイルクライアントデバイスによる前記データノードの予想使用を指示する随時接続データモデルを使用するような同期ユニットと、
    前記随時接続データモデルにより定義されたデータノードと、前記サーバーデバイス及び前記モバイルクライアントデバイスに対する外部システムからのデータとの間で変換を行うために使用される、前記データノードに関連する一組のコンジットを含むコンジットマネージャーと、
    を備え、
    前記データノードは、それぞれのデータノードが前記サーバーデバイスと同期したかどうかを示す同期状態に関連し、前記同期状態は、前記サーバーデバイス上の前記データノードを前記モバイルクライアントデバイス上の前記データノードに同期させるために、前記サーバーデバイスと前記モバイルクライアントデバイスとの間をバックグラウンドプロセスによって伝送され、それによって、前記モバイルクライアントデバイスが前記サーバーから切断されている期間の間、前記データノード上で実行され更新動作が、前記データノードに関連する前記同期状態を使用することによって接続が再確立されたときに、前記サーバーデバイス上に反映されるものであり、
    前記コンジットマネージャーは、前記サーバーデバイス上のデータノードと前記外部システムに含まれるデータとの間の同期の際に、データ変換を行ってデータを整合させるために、同期状態の前記伝送の間に少なくとも1つのコンジットを呼び出す、ことを特徴とする随時接続サーバーデバイス。
  2. 前記随時接続サーバーデバイスは、前記随時接続データモデルのメタデータにより指示されたキャッシュにデータノードをキャッシュ記憶する、請求項1に記載の随時接続サーバーデバイス。
  3. 前記コンジットマネージャーは、前記随時接続データモデルにより定義されたデータと、特定のウェブサービスに対する要求及び応答との間の変換を定義するコンジットを使用する、請求項1に記載の随時接続サーバーデバイス。
  4. 適応ユーザインターフェイスサーバーを更に備え、前記モバイルクライアントデバイスは、前記データノード及び前記随時接続データモデルを使用して前記適応ユーザインターフェイスサーバーにより構成された前記随時接続サーバーデバイスからのHTMLページを受け取る、請求項1に記載の随時接続サーバーデバイス。
  5. 前記モバイルクライアントデバイスには、前記データノード及び前記随時接続データモデルが転送されて、クライアントに表示を発生する、請求項1に記載の随時接続サーバーデバイス。
  6. 前記モバイルクライアントデバイスは、前記随時接続サーバーデバイスにコンタクトせずに、前記データノード及び前記随時接続データモデルを使用してアプリケーションを実行できる、請求項に記載の随時接続ーバーデバイス
  7. サーバー上にキャッシュ記憶されたデータノードを、随時接続データモデルを使用するアプリケーションに関してモバイルクライアント上に記憶されたデータノードと同期させるステップであって、前記随時接続データモデルは、前記データノードが前記モバイルクライアントデバイスによって要求される前に、前記データノードの予想使用を指示するステップと、
    外部システムからのデータと、前記随時接続データモデルにより定義されたデータノードとの間で、前記データノードに関連する一組のコンジットを使用することによって変換を行うステップと、を備え、前記データノードは、それぞれのデータノードが前記サーバーと同期したかどうかを示す同期状態に関連し、前記同期状態は、前記サーバー上の前記データノードを前記モバイルクライアント上の前記データノードに同期させるために、前記サーバーと前記モバイルクライアントとの間をバックグラウンドプロセスによって伝送され、それによって、前記モバイルクライアントが前記サーバーから切断されている期間の間、前記データノード上で実行され更新動作が、前記データノードに関連する前記同期状態を使用することによって接続が再確立されたときに、前記サーバー上に反映されるものであり、
    少なくとも一つの前記コンジットは、前記サーバー上のデータノード前記外部システムに含まれるデータとの間の同期の際に、データ変換を行ってデータを整合させるために、同期状態の前記伝送の間に呼び出される、ことを特徴とする方法。
  8. 前記サーバーは、前記随時接続データモデルのメタデータにより指示されたキャッシュに前記データノードをキャッシュ記憶する、請求項7に記載の方法。
  9. 前記変換は、前記随時接続データモデルにより定義されたデータと、特定のウェブサービスに対する要求及び応答との間の変換を定義するコンジットを使用する、請求項7に記載の方法。
  10. 前記クライアントには、前記データノード及び前記随時接続データモデルの両方が転送されて、クライアントに表示を発生する、請求項7に記載の方法。
  11. 随時接続データモデルを記憶するためのメモリと、
    前記随時接続データモデルにより定義されるデータノードを記憶するためのキャッシュであって、サーバーが、前記随時接続データモデルのメタデータにより指示されたキャッシュにデータノードをキャッシュ記憶し、前記随時接続データモデルは、サーバー上に記憶されている前記データノードを、前記サーバーによって提供されたアプリケーションに関してモバイルクライアント上に記憶されたデータノードと同期させるために使用され、前記アプリケーションは前記随時接続データモデルを使用し、前記随時接続データモデルは、前記データノードが前記モバイルクライアントによって要求される前に、前記モバイルクライアントによる前記データノードの予想使用を指示するキャッシュと、
    前記随時接続データモデルによって定義される前記データノード前記外部システムに含まれるデータとの間の同期の際に、データ変換を行ってデータを整合させる、前記データノードに関連する一組のコンジットを記憶するメモリーと、を含み、
    前記データノードは、それぞれのデータノードが前記サーバーと同期したかどうかを示す同期状態に関連し、前記同期状態は、前記サーバー上の前記データノードを前記モバイルクライアント上の前記データノードに同期させるために、前記サーバーと前記モバイルクライアントとの間をバックグラウンドプロセスによって伝送され、それによって、前記モバイルクライアントが前記サーバーから切断されている期間の間、前記データノード上で実行され更新動作が、前記データノードに関連する前記同期状態を使用することによって接続が再確立されたときに、前記サーバー上に反映されるものであり、
    少なくとも一つの前記コンジットは、前記サーバー上のデータノード前記外部システムに含まれるデータとの間の同期の際に、データ変換を行ってデータを整合させるために、同期状態の前記伝送の間に呼び出される、ことを特徴とするシステム。
  12. 前記外部システムと、前記随時接続データモデルにより定義された前記データノードとの間でデータを変換するように構成される、請求項11に記載のシステム。
  13. 前記データノードはXMLを含む、請求項11に記載のシステム。
  14. 前記随時接続データモデルにより定義されたデータと、特定のウェブサービスに対する要求及び応答との間の変換を定義するコンジットを使用するように構成されたコンジットマネージャーを更に備えた、請求項11に記載のシステム。
  15. 適応ユーザインターフェイスサーバーを更に備え、少なくとも1つの前記モバイルクライアントは、前記データノード及び前記随時接続データモデルを使用して前記適応ユーザインターフェイスサーバーにより構成された前記サーバーからのHTMLページを受け取る、請求項11に記載のシステム。
  16. 前記モバイルクライアントには、前記データノード及び前記随時接続データモデルが転送されて、前記モバイルクライアントに表示を発生する、請求項11に記載のシステム。
  17. 前記モバイルクライアントは、前記サーバーにコンタクトせずに、前記データノード及び前記随時接続データモデルの両方を使用してアプリケーションを実行できる、請求項16に記載のシステム。
  18. 前記サーバと前記モバイルクライアントとの間で通過させられる前記同期状態は、
    前記データノードがローカルで生成又は変更されたかという指示、
    前記データノードがローカルで生成又は変更されそしてサーバーとの同期の準備ができたかという指示、
    前記データノードが保留中のサーバー同期を有するかという指示
    前記データノードが前記サーバーと同期させられたかという指示、
    同期が前記サーバーによって拒絶されたかという指示、及び
    ローカルの変更とサーバーの更新との間に競合があるかという指示、
    という指示から構成される、請求項1に記載の随時接続サーバーデバイス。
  19. 同期の要求が前記モバイルクライアントデバイスによって受信され、前記モバイルクライアントデバイス上のページ上に現在表示されているデータが、ページデータバインディングを再計算することによってリフレッシュされて、前記ページが、現在ユーザ入力、脱字記号又は焦点を維持したまま増分的に再表示される、請求項1に記載のサーバーデバイス。
  20. 前記サーバーデバイスは、前記モバイルクライアントデバイスから同期要求を受信し、前記サーバーが前記要求に関連する前記データをキャッシュ記憶していた場合は前記サーバーデバイスは直ちに応答し、そうではなく、前記サーバー上にキャッシュ記憶された前記データが古い場合は前記コンジットマネージャーは更新されたデータを配送するために1つ以上の前記コンジットを呼び出す、請求項1に記載のサーバーデバイス。
  21. 前記モバイルクライアントデバイス上のユーザーインターフェース動作は、前記モバイルクライアントデバイスと前記サーバーデバイスの間の接続性に関して非同期で実行され、前記同期状態を通過する同期要求が前記モバイルクライアントデバイス上のブラウザに関して非同期で実行される、請求項1に記載のサーバーデバイス。
JP2006542905A 2004-05-20 2005-05-20 随時接続アプリケーションサーバー Active JP4551899B2 (ja)

Applications Claiming Priority (3)

Application Number Priority Date Filing Date Title
US57307704P 2004-05-20 2004-05-20
US11/122,294 US7650432B2 (en) 2004-05-20 2005-05-04 Occasionally-connected application server
PCT/US2005/017822 WO2005114489A2 (en) 2004-05-20 2005-05-20 Occasionally-connected application server

Publications (2)

Publication Number Publication Date
JP2007524933A JP2007524933A (ja) 2007-08-30
JP4551899B2 true JP4551899B2 (ja) 2010-09-29

Family

ID=35429049

Family Applications (1)

Application Number Title Priority Date Filing Date
JP2006542905A Active JP4551899B2 (ja) 2004-05-20 2005-05-20 随時接続アプリケーションサーバー

Country Status (5)

Country Link
US (1) US7650432B2 (ja)
EP (1) EP1754175A4 (ja)
JP (1) JP4551899B2 (ja)
AU (1) AU2005246392B2 (ja)
WO (1) WO2005114489A2 (ja)

Families Citing this family (134)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
WO2002059773A1 (en) * 2000-12-04 2002-08-01 Thinkshare Corp. Modular distributed mobile data applications
WO2003058483A1 (en) 2002-01-08 2003-07-17 Seven Networks, Inc. Connection architecture for a mobile network
US7606881B2 (en) * 2002-04-25 2009-10-20 Oracle International Corporation System and method for synchronization of version annotated objects
US7076567B1 (en) * 2002-04-25 2006-07-11 Oracle International Corporation Simplified application object data synchronization for optimized data storage
US7787489B2 (en) * 2002-10-07 2010-08-31 Oracle International Corporation Mobile data distribution
US7908286B2 (en) * 2004-12-08 2011-03-15 Oracle International Corporation Techniques for providing XQuery access using web services
US8438633B1 (en) * 2005-04-21 2013-05-07 Seven Networks, Inc. Flexible real-time inbox access
US8464317B2 (en) * 2005-05-06 2013-06-11 International Business Machines Corporation Method and system for creating a protected object namespace from a WSDL resource description
CN1869932A (zh) * 2005-05-24 2006-11-29 中国银联股份有限公司 实现数据升级的计算机处理系统以及数据升级方法
US7970386B2 (en) 2005-06-03 2011-06-28 Good Technology, Inc. System and method for monitoring and maintaining a wireless device
WO2006136660A1 (en) 2005-06-21 2006-12-28 Seven Networks International Oy Maintaining an ip connection in a mobile network
US7877420B2 (en) * 2005-06-24 2011-01-25 Microsoft Corporation Methods and systems for incorporating meta-data in document content
US8171394B2 (en) * 2005-06-24 2012-05-01 Microsoft Corporation Methods and systems for providing a customized user interface for viewing and editing meta-data
US20070016577A1 (en) * 2005-07-13 2007-01-18 Rivergy, Inc. System for building a website
US7912871B2 (en) * 2005-07-27 2011-03-22 Technion Research And Development Foundation Ltd. Incremental validation of key and keyref constraints
US7668836B2 (en) * 2005-09-02 2010-02-23 International Business Machines Corporation IMS SOAP gateway deployment utility
US8972423B2 (en) * 2006-09-26 2015-03-03 Siemens Product Lifecycle Management Software Inc. Opaque mechanism for web service interoperability
US20070112791A1 (en) * 2005-11-09 2007-05-17 Harvey Richard H Method and system for providing enhanced read performance for a supplemental directory
US8321486B2 (en) * 2005-11-09 2012-11-27 Ca, Inc. Method and system for configuring a supplemental directory
US8326899B2 (en) * 2005-11-09 2012-12-04 Ca, Inc. Method and system for improving write performance in a supplemental directory
US8458176B2 (en) * 2005-11-09 2013-06-04 Ca, Inc. Method and system for providing a directory overlay
US20070112812A1 (en) * 2005-11-09 2007-05-17 Harvey Richard H System and method for writing data to a directory
US20070171923A1 (en) 2005-12-01 2007-07-26 Firestar Software, Inc. System and method for exchanging information among exchange applications
US7788223B2 (en) * 2005-12-05 2010-08-31 Microsoft Corporation Resource freshness and replication
KR100717520B1 (ko) 2005-12-06 2007-05-11 주식회사 인프라웨어 무선인터넷 서비스를 제공하는 이동 단말기 및 그 사용자인터페이스 방법
US7631017B2 (en) * 2005-12-08 2009-12-08 Motorola, Inc. Method and system for maintaining current data for wireless devices
US20070168535A1 (en) * 2005-12-22 2007-07-19 Ilmo Ikonen System and method for data communication between devices
WO2007083954A1 (en) * 2006-01-23 2007-07-26 Lg Electronics Inc. Method for scheduling device management and terminal thereof
US8086756B2 (en) * 2006-01-25 2011-12-27 Cisco Technology, Inc. Methods and apparatus for web content transformation and delivery
US7676786B2 (en) 2006-02-02 2010-03-09 Research In Motion Limited System and method and apparatus for using UML tools for defining web service bound component applications
US9152928B2 (en) * 2006-06-30 2015-10-06 Triplay, Inc. Context parameters and identifiers for communication
US20090210631A1 (en) * 2006-09-22 2009-08-20 Bea Systems, Inc. Mobile application cache system
US8239522B1 (en) * 2006-11-16 2012-08-07 Adobe Systems Incorporated Dynamic variables for tracking wireless device website usage
US8499044B2 (en) * 2006-12-07 2013-07-30 Microsoft Corporation Formatted message processing utilizing a message map
US7983249B2 (en) * 2007-01-23 2011-07-19 Oracle America, Inc. Enterprise web service data to mobile device synchronization
US7899917B2 (en) * 2007-02-01 2011-03-01 Microsoft Corporation Synchronization framework for occasionally connected applications
US20080234987A1 (en) * 2007-02-23 2008-09-25 Autodesk, Inc. Amalgamation of data models across multiple applications
US10387130B1 (en) * 2007-02-23 2019-08-20 Sugarcrm Inc. Metadata driven distributed application behavior system and method
US20080215664A1 (en) * 2007-03-01 2008-09-04 Microsoft Corporation Occasionally connected edge application architecture
US8453136B1 (en) * 2007-03-06 2013-05-28 Cadence Design Systems, Inc. Change tracking and incremental synchronization of EDA design and technology data
US9729843B1 (en) 2007-03-16 2017-08-08 The Mathworks, Inc. Enriched video for a technical computing environment
US8005812B1 (en) * 2007-03-16 2011-08-23 The Mathworks, Inc. Collaborative modeling environment
US20080235258A1 (en) * 2007-03-23 2008-09-25 Hyen Vui Chung Method and Apparatus for Processing Extensible Markup Language Security Messages Using Delta Parsing Technology
US7853669B2 (en) 2007-05-04 2010-12-14 Microsoft Corporation Mesh-managing data across a distributed set of devices
US8805425B2 (en) * 2007-06-01 2014-08-12 Seven Networks, Inc. Integrated messaging
US8819080B2 (en) * 2007-06-13 2014-08-26 The Boeing Company System and method for collection, retrieval, and distribution of data
KR100916244B1 (ko) * 2007-09-03 2009-09-10 전자부품연구원 Soap 오퍼레이션을 이용한 질의된 컨텐츠 서비스방법
US8112460B2 (en) * 2007-09-28 2012-02-07 Xcerion Aktiebolag Framework for applying rules
US8886779B2 (en) * 2007-10-19 2014-11-11 Oracle America, Inc. Performance modeling for SOA security appliance
US9002828B2 (en) * 2007-12-13 2015-04-07 Seven Networks, Inc. Predictive content delivery
EP2250791B1 (en) * 2008-01-11 2016-08-10 Telefonaktiebolaget LM Ericsson (publ) Securing contact information
US8862657B2 (en) 2008-01-25 2014-10-14 Seven Networks, Inc. Policy based content service
US20090193338A1 (en) * 2008-01-28 2009-07-30 Trevor Fiatal Reducing network and battery consumption during content delivery and playback
US8875306B2 (en) * 2008-02-12 2014-10-28 Oracle International Corporation Customization restrictions for multi-layer XML customization
US8788542B2 (en) * 2008-02-12 2014-07-22 Oracle International Corporation Customization syntax for multi-layer XML customization
US8966465B2 (en) * 2008-02-12 2015-02-24 Oracle International Corporation Customization creation and update for multi-layer XML customization
US7996444B2 (en) * 2008-02-18 2011-08-09 International Business Machines Corporation Creation of pre-filters for more efficient X-path processing
US7831608B2 (en) * 2008-02-28 2010-11-09 International Business Machines Corporation Service identification in legacy source code using structured and unstructured analyses
US20090228542A1 (en) * 2008-03-06 2009-09-10 Microsoft Corporation Occasionally-connected support through off-line service-supplied proxies
US9753712B2 (en) 2008-03-20 2017-09-05 Microsoft Technology Licensing, Llc Application management within deployable object hierarchy
US9298747B2 (en) * 2008-03-20 2016-03-29 Microsoft Technology Licensing, Llc Deployable, consistent, and extensible computing environment platform
US8572033B2 (en) 2008-03-20 2013-10-29 Microsoft Corporation Computing environment configuration
US8484174B2 (en) * 2008-03-20 2013-07-09 Microsoft Corporation Computing environment representation
US20090248737A1 (en) * 2008-03-27 2009-10-01 Microsoft Corporation Computing environment representation
US20090254822A1 (en) * 2008-04-04 2009-10-08 International Business Machines Corporation Hi-efficiency wizard framework system and method
US8799319B2 (en) * 2008-09-19 2014-08-05 Oracle International Corporation System and method for meta-data driven, semi-automated generation of web services based on existing applications
US8996658B2 (en) * 2008-09-03 2015-03-31 Oracle International Corporation System and method for integration of browser-based thin client applications within desktop rich client architecture
US8112470B2 (en) 2008-09-09 2012-02-07 Microsoft Corporation Virtual javascript object notation
US9122520B2 (en) * 2008-09-17 2015-09-01 Oracle International Corporation Generic wait service: pausing a BPEL process
US8909759B2 (en) 2008-10-10 2014-12-09 Seven Networks, Inc. Bandwidth measurement
US8490052B2 (en) * 2008-10-14 2013-07-16 Microsoft Corporation Declarative programming model for authoring and execution control and data flow for resource oriented system
US8438295B2 (en) * 2008-10-14 2013-05-07 Microsoft Corporation Declarative programming model for modeling and execution of triggers for resource oriented system
US8533666B2 (en) * 2008-10-17 2013-09-10 Microsoft Corporation Interactive design environments to visually model, debug and execute resource oriented programs
TWI384378B (zh) * 2008-12-29 2013-02-01 Ind Tech Res Inst 網頁應用程式執行方法
US20100268784A1 (en) * 2009-04-17 2010-10-21 Marc Henness Data synchronization system and method
US8028070B2 (en) * 2009-05-18 2011-09-27 Microsoft Corporation Synchronizing tasks between servers
US9438448B2 (en) * 2009-08-18 2016-09-06 Microsoft Technology Licensing, Llc Maintaining communication connections during temporary network disruptions
US8768913B2 (en) * 2009-10-21 2014-07-01 Kana Software, Inc. Multi-source searching in a data driven application
US20110149086A1 (en) 2009-12-23 2011-06-23 Winbush Iii Amos Camera user content synchronization with central web-based records and information sharing system
US9244965B2 (en) 2010-02-22 2016-01-26 Thoughtwire Holdings Corp. Method and system for sharing data between software systems
US8595382B2 (en) * 2010-06-07 2013-11-26 Salesforce.Com, Inc. System, method and computer program product for performing a synchronization of data
JP5620578B2 (ja) 2010-07-26 2014-11-05 セブン ネットワークス インコーポレイテッド 複数のアプリケーションにわたるモバイルネットワークトラフィック調整
US8838783B2 (en) 2010-07-26 2014-09-16 Seven Networks, Inc. Distributed caching for resource and mobile network traffic management
CN102457499B (zh) * 2010-10-26 2015-09-16 腾讯科技(深圳)有限公司 客户端的离线工作方法和离线工作客户端
US8843153B2 (en) 2010-11-01 2014-09-23 Seven Networks, Inc. Mobile traffic categorization and policy for network use optimization while preserving user experience
WO2012060995A2 (en) 2010-11-01 2012-05-10 Michael Luna Distributed caching in a wireless network of content delivered for a mobile application over a long-held request
EP2636268B1 (en) 2010-11-22 2019-02-27 Seven Networks, LLC Optimization of resource polling intervals to satisfy mobile device requests
US9189566B2 (en) * 2010-12-07 2015-11-17 Sap Se Facilitating extraction and discovery of enterprise services
WO2012094675A2 (en) 2011-01-07 2012-07-12 Seven Networks, Inc. System and method for reduction of mobile network traffic used for domain name system (dns) queries
KR101755421B1 (ko) * 2011-01-10 2017-07-10 삼성전자주식회사 클라이언트 장치를 이용한 호스트 장치의 파일 정보 시스템 편집 방법 및 시스템
CA2769775A1 (en) 2011-03-01 2012-09-01 Weever Apps Inc. System, method and computer program product for generating browser-executable software program to present web page as mobile application
US9084105B2 (en) 2011-04-19 2015-07-14 Seven Networks, Inc. Device resources sharing for network resource conservation
US8438474B1 (en) * 2011-04-27 2013-05-07 Google Inc. Speculative rendering during cache revalidation
WO2012149434A2 (en) 2011-04-27 2012-11-01 Seven Networks, Inc. Detecting and preserving state for satisfying application requests in a distributed proxy and cache system
EP2702827A4 (en) 2011-04-27 2014-10-22 Seven Networks Inc MOBILE DEVICE DISCHARGING REQUESTS MOBILE APPLICATION TO REMOTE ENTITY TO KEEP MOBILE DEVICE RESOURCES AND NETWORK RESOURCES AND RELATED METHODS
FR2976379B1 (fr) * 2011-06-08 2019-04-26 Schneider Electric Industries Sas Systeme et procede de partage de donnees stockees dans une base de donnees
US9578114B2 (en) 2011-09-27 2017-02-21 Microsoft Technology Licensing, Llc External service application discovery method
US8954942B2 (en) * 2011-09-30 2015-02-10 Oracle International Corporation Optimizations using a BPEL compiler
US9069844B2 (en) 2011-11-02 2015-06-30 Sap Se Facilitating extraction and discovery of enterprise services
US8934414B2 (en) 2011-12-06 2015-01-13 Seven Networks, Inc. Cellular or WiFi mobile traffic optimization based on public or private network destination
US8977755B2 (en) 2011-12-06 2015-03-10 Seven Networks, Inc. Mobile device and method to utilize the failover mechanism for fault tolerance provided for mobile traffic management and network/device resource conservation
EP2788889A4 (en) 2011-12-07 2015-08-12 Seven Networks Inc FLEXIBLE AND DYNAMIC INTEGRATION SCHEMES OF A TRAFFIC MANAGEMENT SYSTEM WITH VARIOUS NETWORK OPERATORS TO REDUCE NETWORK TRAFFIC
WO2013086447A1 (en) 2011-12-07 2013-06-13 Seven Networks, Inc. Radio-awareness of mobile device for sending server-side control signals using a wireless network optimized transport protocol
WO2013090212A1 (en) 2011-12-14 2013-06-20 Seven Networks, Inc. Mobile network reporting and usage analytics system and method using aggregation of data in a distributed traffic optimization system
US11216454B1 (en) * 2011-12-19 2022-01-04 Actian Sub Iii, Inc. User defined functions for database query languages based on call-back functions
RU2605047C2 (ru) * 2012-02-09 2016-12-20 Общество с ограниченной ответственностью "Колловэар" Способ синхронизации объектов персонального информационного менеджера и внешнего сервера
US8812695B2 (en) 2012-04-09 2014-08-19 Seven Networks, Inc. Method and system for management of a virtual network connection without heartbeat messages
US9177289B2 (en) 2012-05-03 2015-11-03 Sap Se Enhancing enterprise service design knowledge using ontology-based clustering
US8874682B2 (en) * 2012-05-23 2014-10-28 Sybase, Inc. Composite graph cache management
US8775631B2 (en) 2012-07-13 2014-07-08 Seven Networks, Inc. Dynamic bandwidth adjustment for browsing or streaming activity in a wireless network based on prediction of user behavior when interacting with mobile applications
US20140082586A1 (en) * 2012-08-09 2014-03-20 FatFractal, Inc. Application development system and method for object models and datagraphs in client-side and server-side applications
US9298391B2 (en) 2012-12-19 2016-03-29 Dropbox, Inc. Application programming interfaces for data synchronization with online storage systems
US9398090B2 (en) 2013-01-07 2016-07-19 Dropbox, Inc. Synchronized content library
US8874761B2 (en) 2013-01-25 2014-10-28 Seven Networks, Inc. Signaling optimization in a wireless network for traffic utilizing proprietary and non-proprietary protocols
KR101772781B1 (ko) * 2013-01-30 2017-08-29 세이코 엡슨 가부시키가이샤 Pos 제어 시스템, pos 제어 시스템의 제어 방법, 및, 제어 장치
JP6149416B2 (ja) * 2013-02-07 2017-06-21 日本電気株式会社 サービスバス装置、サービスバス装置の制御方法、メッセージ送受信システム、及びプログラム
US9326185B2 (en) 2013-03-11 2016-04-26 Seven Networks, Llc Mobile network congestion recognition for optimization of mobile traffic
US9742843B2 (en) 2013-03-14 2017-08-22 Thoughtwire Holdings Corp. Method and system for enabling data sharing between software systems
US9614932B2 (en) 2013-03-14 2017-04-04 Microsoft Technology Licensing, Llc Managing and implementing web application data snapshots
US10372442B2 (en) 2013-03-14 2019-08-06 Thoughtwire Holdings Corp. Method and system for generating a view incorporating semantically resolved data values
US10313433B2 (en) 2013-03-14 2019-06-04 Thoughtwire Holdings Corp. Method and system for registering software systems and data-sharing sessions
KR20140128737A (ko) * 2013-04-29 2014-11-06 삼성전자주식회사 어플리케이션 결함을 관리하기 위한 장치 및 방법
US9065765B2 (en) 2013-07-22 2015-06-23 Seven Networks, Inc. Proxy server associated with a mobile carrier for enhancing mobile traffic management in a mobile network
JP6382819B2 (ja) 2013-08-21 2018-08-29 株式会社東芝 データベースシステム、ノード、管理装置、プログラムおよびデータ処理方法
US10762276B2 (en) * 2013-08-27 2020-09-01 Paper Software LLC Cross-references within a hierarchically structured document
WO2015029139A1 (ja) 2013-08-27 2015-03-05 株式会社東芝 データベースシステム、プログラムおよびデータ処理方法
US10769143B1 (en) 2014-07-31 2020-09-08 Open Text Corporation Composite index on hierarchical nodes in the hierarchical data model within case model
US10515124B1 (en) * 2014-07-31 2019-12-24 Open Text Corporation Placeholder case nodes and child case nodes in a case model
US10599718B2 (en) * 2015-10-09 2020-03-24 Software Ag Systems and/or methods for graph based declarative mapping
US10929174B2 (en) * 2016-12-15 2021-02-23 Ecole Polytechnique Federale De Lausanne (Epfl) Atomic object reads for in-memory rack-scale computing
US11714811B2 (en) 2017-09-27 2023-08-01 Salesforce, Inc. Run-time querying of multi-tenant non-relational platform objects
US10579692B2 (en) * 2017-09-27 2020-03-03 Salesforce.Com, Inc. Composite keys for multi-tenant non-relational platform objects
US10579691B2 (en) 2017-09-27 2020-03-03 Salesforce.Com, Inc. Application programming interface representation of multi-tenant non-relational platform objects
US10579722B1 (en) * 2018-07-25 2020-03-03 Sprint Communications Company, L.P. Structured metadata for dynamic data encapsulation

Family Cites Families (123)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
US5159592A (en) * 1990-10-29 1992-10-27 International Business Machines Corporation Network address management for a wired network supporting wireless communication to a plurality of mobile users
US5250789A (en) * 1991-10-31 1993-10-05 Johnsen Edward L Shopping cart
US5566225A (en) * 1994-11-21 1996-10-15 Lucent Technologies Inc. Wireless data communications system for detecting a disabled condition and simulating a functioning mode in response to detection
US5758257A (en) * 1994-11-29 1998-05-26 Herz; Frederick System and method for scheduling broadcast of and access to video programs and other data using customer profiles
US6571279B1 (en) * 1997-12-05 2003-05-27 Pinpoint Incorporated Location enhanced information delivery system
US5664110A (en) * 1994-12-08 1997-09-02 Highpoint Systems, Inc. Remote ordering system
US5812819A (en) * 1995-06-05 1998-09-22 Shiva Corporation Remote access apparatus and method which allow dynamic internet protocol (IP) address management
US5727159A (en) * 1996-04-10 1998-03-10 Kikinis; Dan System in which a Proxy-Server translates information received from the Internet into a form/format readily usable by low power portable computers
US6314406B1 (en) * 1996-06-26 2001-11-06 Telxon Corporation Customer information network
US5828832A (en) * 1996-07-30 1998-10-27 Itt Industries, Inc. Mixed enclave operation in a computer network with multi-level network security
US5931917A (en) * 1996-09-26 1999-08-03 Verifone, Inc. System, method and article of manufacture for a gateway system architecture with system administration information accessible from a browser
US6096096A (en) * 1996-12-13 2000-08-01 Silicon Graphics, Inc. Web-site delivery
US6477527B2 (en) * 1997-05-09 2002-11-05 International Business Machines Corporation System, method, and program for object building in queries over object views
US6314408B1 (en) * 1997-07-15 2001-11-06 Eroom Technology, Inc. Method and apparatus for controlling access to a product
US6112212A (en) * 1997-09-15 2000-08-29 The Pangea Project Llc Systems and methods for organizing and analyzing information stored on a computer network
US6236768B1 (en) * 1997-10-14 2001-05-22 Massachusetts Institute Of Technology Method and apparatus for automated, context-dependent retrieval of information
US6009410A (en) * 1997-10-16 1999-12-28 At&T Corporation Method and system for presenting customized advertising to a user on the world wide web
US6128661A (en) * 1997-10-24 2000-10-03 Microsoft Corporation Integrated communications architecture on a mobile device
US6594682B2 (en) * 1997-10-28 2003-07-15 Microsoft Corporation Client-side system for scheduling delivery of web content and locally managing the web content
US6065120A (en) * 1997-12-09 2000-05-16 Phone.Com, Inc. Method and system for self-provisioning a rendezvous to ensure secure access to information in a database from multiple devices
US6058391A (en) * 1997-12-17 2000-05-02 Mci Communications Corporation Enhanced user view/update capability for managing data from relational tables
US6801916B2 (en) * 1998-04-01 2004-10-05 Cyberpulse, L.L.C. Method and system for generation of medical reports from data in a hierarchically-organized database
US6101483A (en) * 1998-05-29 2000-08-08 Symbol Technologies, Inc. Personal shopping system portable terminal
US6151675A (en) * 1998-07-23 2000-11-21 Tumbleweed Software Corporation Method and apparatus for effecting secure document format conversion
US6925595B1 (en) * 1998-08-05 2005-08-02 Spyglass, Inc. Method and system for content conversion of hypertext data using data mining
US7778260B2 (en) 1998-10-09 2010-08-17 Netmotion Wireless, Inc. Method and apparatus for providing mobile and other intermittent connectivity in a computing environment
ATE260490T1 (de) * 1998-11-30 2004-03-15 Index Systems Inc Intelligenter agent basierend auf gewohnheit, statistische inferenz und psychodemografische profilierung
AU1838200A (en) * 1998-11-30 2000-06-19 Siebel Systems, Inc. Client server system with thin client architecture
US6177905B1 (en) * 1998-12-08 2001-01-23 Avaya Technology Corp. Location-triggered reminder for mobile user devices
US6212640B1 (en) * 1999-03-25 2001-04-03 Sun Microsystems, Inc. Resources sharing on the internet via the HTTP
US6226752B1 (en) * 1999-05-11 2001-05-01 Sun Microsystems, Inc. Method and apparatus for authenticating users
US6681220B1 (en) * 1999-05-28 2004-01-20 International Business Machines Corporation Reduction and optimization of information processing systems
US20030191832A1 (en) * 1999-06-01 2003-10-09 Ramakrishna Satyavolu Method and apparatus for controlled establishment of a turnkey system providing a centralized data aggregation and summary capability to third party entities
US6425022B1 (en) * 1999-06-11 2002-07-23 Oak Technology, Inc. System for reading blocks of different sizes by maintaining buffer page pointer when word count is not greater than guardband, and reset word count thereafter
US6477373B1 (en) * 1999-08-10 2002-11-05 Research Foundation Of State University Of New York Method and apparatus to maintain connectivity for mobile terminals in wireless and cellular communications systems
US6760758B1 (en) * 1999-08-31 2004-07-06 Qwest Communications International, Inc. System and method for coordinating network access
US7392308B2 (en) * 1999-09-10 2008-06-24 Ianywhere Solutions, Inc. System, method, and computer program product for placement of channels on a mobile device
US6725022B1 (en) * 1999-09-22 2004-04-20 Motorola, Inc. Method and apparatus for enabling the selection of content on a wireless communication device
US7020697B1 (en) 1999-10-01 2006-03-28 Accenture Llp Architectures for netcentric computing systems
US6578054B1 (en) 1999-10-04 2003-06-10 Microsoft Corporation Method and system for supporting off-line mode of operation and synchronization using resource state information
US6430624B1 (en) * 1999-10-21 2002-08-06 Air2Web, Inc. Intelligent harvesting and navigation system and method
US6353398B1 (en) * 1999-10-22 2002-03-05 Himanshu S. Amin System for dynamically pushing information to a user utilizing global positioning system
US6647001B1 (en) * 1999-12-06 2003-11-11 At&T Corp. Persistent communication with changing environment
US7047305B1 (en) * 1999-12-09 2006-05-16 Vidiator Enterprises Inc. Personal broadcasting system for audio and video data using a wide area network
WO2001067309A2 (en) * 2000-03-03 2001-09-13 Radiant Logic, Inc. System and method for providing access to databases via directories and other hierarchical structures and interfaces
GB2360173B (en) * 2000-03-07 2004-04-07 Hewlett Packard Co Distributed telemetry method and system
US6618737B2 (en) * 2000-03-09 2003-09-09 International Business Machines Corporation Speculative caching of individual fields in a distributed object system
US6845091B2 (en) * 2000-03-16 2005-01-18 Sri International Mobile ad hoc extensions for the internet
US6701522B1 (en) * 2000-04-07 2004-03-02 Danger, Inc. Apparatus and method for portal device authentication
WO2001080133A2 (en) * 2000-04-17 2001-10-25 Emtera Corporation System and method for wireless purchases of goods and services
AU2001251643A1 (en) * 2000-04-17 2001-10-30 Circadence Corporation System and method for providing distributed database services
WO2001086882A2 (en) * 2000-05-05 2001-11-15 @ Hand Corporation System and method for extending an enterprise network to mobile devices
GB0011426D0 (en) * 2000-05-11 2000-06-28 Charteris Limited A method for transforming documents written in different XML-based languages
US6922685B2 (en) 2000-05-22 2005-07-26 Mci, Inc. Method and system for managing partitioned data resources
US6438575B1 (en) * 2000-06-07 2002-08-20 Clickmarks, Inc. System, method, and article of manufacture for wireless enablement of the world wide web using a wireless gateway
US6990513B2 (en) * 2000-06-22 2006-01-24 Microsoft Corporation Distributed computing services platform
US6615216B1 (en) * 2000-06-29 2003-09-02 Microsoft Corporation Lock free data structure maintenance
US7099926B1 (en) * 2000-07-06 2006-08-29 International Business Machines Corporation Object caching and update queuing technique to improve performance and resource utilization
KR100425494B1 (ko) 2000-08-21 2004-03-30 엘지전자 주식회사 웹 기반 전송장비의 관리 데이터 동기 방법
EP1366435A2 (en) 2000-08-22 2003-12-03 Symbian Limited Database for use with a wireless information device
US20020059345A1 (en) * 2000-09-12 2002-05-16 Wang Wayne W. Method for generating transform rules for web-based markup languages
US20020069263A1 (en) * 2000-10-13 2002-06-06 Mark Sears Wireless java technology
US6542740B1 (en) * 2000-10-24 2003-04-01 Litepoint, Corp. System, method and article of manufacture for utilizing a wireless link in an interface roaming network framework
US6865680B1 (en) * 2000-10-31 2005-03-08 Yodlee.Com, Inc. Method and apparatus enabling automatic login for wireless internet-capable devices
US7600014B2 (en) * 2000-11-16 2009-10-06 Symantec Corporation Method and system for monitoring the performance of a distributed application
US20020099829A1 (en) * 2000-11-27 2002-07-25 Richards Kenneth W. Filter proxy system and method
US7877518B2 (en) * 2000-11-30 2011-01-25 Access Systems Americas, Inc. Method and apparatus for updating applications on a mobile device via device synchronization
US7546298B2 (en) * 2001-01-09 2009-06-09 Nextair Corporation Software, devices and methods facilitating execution of server-side applications at mobile devices
JP3768406B2 (ja) 2001-01-15 2006-04-19 株式会社エヌ・ティ・ティ・ドコモ 移動通信網における情報配信制御方法及びシステム、及び移動通信網における通信ノードでの情報蓄積方法
US7017175B2 (en) 2001-02-02 2006-03-21 Opentv, Inc. Digital television application protocol for interactive television
US6714791B2 (en) * 2001-02-23 2004-03-30 Danger, Inc. System, apparatus and method for location-based instant messaging
US6668177B2 (en) * 2001-04-26 2003-12-23 Nokia Corporation Method and apparatus for displaying prioritized icons in a mobile terminal
US20030177175A1 (en) * 2001-04-26 2003-09-18 Worley Dale R. Method and system for display of web pages
US7190956B2 (en) * 2001-05-15 2007-03-13 Motorola Inc. Instant message proxy for circuit switched mobile environment
US7152090B2 (en) * 2001-06-01 2006-12-19 Sun Microsystems, Inc. Metadata-aware enterprise application integration framework for application server environment
US7003566B2 (en) 2001-06-29 2006-02-21 International Business Machines Corporation Method and system for predictive directional data caching
US6813641B2 (en) * 2001-07-05 2004-11-02 Sun Microsystems, Inc. Teamware server working over HTTP/HTTPS connections
US7117225B2 (en) * 2001-08-13 2006-10-03 Jasmin Cosic Universal data management interface
US7149813B2 (en) * 2001-08-14 2006-12-12 Microsoft Corporation Method and system for synchronizing mobile devices
GB2379296B (en) * 2001-09-01 2005-05-25 Ibm A data storage system having a unified container layer for an active data store
US7761535B2 (en) * 2001-09-28 2010-07-20 Siebel Systems, Inc. Method and system for server synchronization with a computing device
US7257649B2 (en) 2001-09-28 2007-08-14 Siebel Systems, Inc. Method and system for transferring information during server synchronization with a computing device
US7032033B1 (en) 2001-11-30 2006-04-18 Microsoft Corporation Handling collisions during synchronization of data between client and server computers
US7062756B2 (en) * 2001-11-30 2006-06-13 Sun Microsystems, Inc. Dynamic object usage pattern learning and efficient caching
US7640491B2 (en) * 2001-12-05 2009-12-29 Microsoft Corporation Outputting dynamic local content on mobile devices
US20030135556A1 (en) * 2001-12-14 2003-07-17 International Business Machines Corporation Selection of communication strategies for message brokers or publish/subscribe communications
US6826568B2 (en) * 2001-12-20 2004-11-30 Microsoft Corporation Methods and system for model matching
US7062515B1 (en) 2001-12-28 2006-06-13 Vignette Corporation System and method for the synchronization of a file in a cache
US7275105B2 (en) * 2002-01-16 2007-09-25 Laszlo Systems, Inc. Enabling online and offline operation
US7159174B2 (en) * 2002-01-16 2007-01-02 Microsoft Corporation Data preparation for media browsing
JP3967141B2 (ja) * 2002-01-28 2007-08-29 富士通株式会社 フレーム中継システムおよびフレーム中継装置
US9087319B2 (en) * 2002-03-11 2015-07-21 Oracle America, Inc. System and method for designing, developing and implementing internet service provider architectures
US20040006586A1 (en) * 2002-04-23 2004-01-08 Secure Resolutions, Inc. Distributed server software distribution
US7457810B2 (en) 2002-05-10 2008-11-25 International Business Machines Corporation Querying markup language data sources using a relational query processor
US8255548B2 (en) 2002-06-13 2012-08-28 Salesforce.Com, Inc. Offline web services API to mirror online web services API
US20040001476A1 (en) * 2002-06-24 2004-01-01 Nayeem Islam Mobile application environment
US6941310B2 (en) * 2002-07-17 2005-09-06 Oracle International Corp. System and method for caching data for a mobile application
US7076508B2 (en) 2002-08-12 2006-07-11 International Business Machines Corporation Method, system, and program for merging log entries from multiple recovery log files
TWI231669B (en) * 2002-11-02 2005-04-21 Ibm System and method for using portals by mobile devices in a disconnected mode
US20040098463A1 (en) * 2002-11-19 2004-05-20 Bo Shen Transcoding-enabled caching proxy and method thereof
US6973460B1 (en) 2002-11-26 2005-12-06 Microsoft Corporation Framework for applying operations to nodes of an object model
AU2003298797A1 (en) * 2002-12-04 2004-06-23 Entriq Inc. Multiple content provider user interface
US6964053B2 (en) * 2002-12-04 2005-11-08 International Business Machines Corporation Type descriptor language (TDLanguage) metamodel
WO2004055659A1 (en) * 2002-12-13 2004-07-01 Bea Systems, Inc. System and method for mobile communication
US7644361B2 (en) * 2002-12-23 2010-01-05 Canon Kabushiki Kaisha Method of using recommendations to visually create new views of data across heterogeneous sources
US20040128345A1 (en) * 2002-12-27 2004-07-01 Robinson Scott H. Dynamic service registry
US7366460B2 (en) * 2003-01-23 2008-04-29 Dexterra, Inc. System and method for mobile data update
US7966418B2 (en) * 2003-02-21 2011-06-21 Axeda Corporation Establishing a virtual tunnel between two computer programs
US7516157B2 (en) * 2003-05-08 2009-04-07 Microsoft Corporation Relational directory
US7242925B2 (en) 2003-05-08 2007-07-10 Bellsouth Intellectual Property Corporation Wireless market place for multiple access internet portal
GB0311564D0 (en) * 2003-05-20 2003-06-25 Ibm Monitoring operational data in data processing systems
US20050033767A1 (en) * 2003-08-04 2005-02-10 Kamentz Joel D. Computer-implemented system and method for resource caching and execution
US20050234969A1 (en) 2003-08-27 2005-10-20 Ascential Software Corporation Services oriented architecture for handling metadata in a data integration platform
US20050050142A1 (en) * 2003-08-28 2005-03-03 Aligo Inc. Method and framework for transaction synchronization
US7290034B2 (en) * 2003-09-18 2007-10-30 Vulcan Portals Inc. Method and system for polling a server for new emails, downloading the new emails in a background process, and caching the downloaded emails for access by an email application of an electronic device, such as a portable computer
US20050138143A1 (en) * 2003-12-23 2005-06-23 Thompson Blake A. Pre-fetching linked content
US8751926B2 (en) 2004-02-12 2014-06-10 Mobileframe, Llc Intelligent rendering on a mobile computing device
US7467389B2 (en) * 2004-11-23 2008-12-16 Sybase, Inc. System and methodology providing service invocation for occasionally connected computing devices
US20060155759A1 (en) 2004-12-29 2006-07-13 Yahoo! Inc. Scalable cache layer for accessing blog content
US8175233B2 (en) 2005-02-07 2012-05-08 Avaya Inc. Distributed cache system
US7702318B2 (en) 2005-09-14 2010-04-20 Jumptap, Inc. Presentation of sponsored content based on mobile transaction event
US7548915B2 (en) 2005-09-14 2009-06-16 Jorey Ramer Contextual mobile content placement on a mobile communication facility
US7899917B2 (en) * 2007-02-01 2011-03-01 Microsoft Corporation Synchronization framework for occasionally connected applications

Also Published As

Publication number Publication date
AU2005246392B2 (en) 2008-10-16
AU2005246392A1 (en) 2005-12-01
JP2007524933A (ja) 2007-08-30
WO2005114489A3 (en) 2009-04-09
EP1754175A2 (en) 2007-02-21
WO2005114489A2 (en) 2005-12-01
EP1754175A4 (en) 2013-11-06
US7650432B2 (en) 2010-01-19
US20060117073A1 (en) 2006-06-01

Similar Documents

Publication Publication Date Title
JP4551899B2 (ja) 随時接続アプリケーションサーバー
US9398077B2 (en) Mobile applications
CN101421726B (zh) 偶尔连接的应用服务器
US7827565B2 (en) Integration architecture for non-integrated tools
JP4473128B2 (ja) ウェブ・ポータルの関連するポートレットが、同期されたコンテンツ表示のために協働することを可能にする方法および装置
JP4456485B2 (ja) ポータル・サーバにおいてポートレットの集合を管理する方法および装置
US7089295B2 (en) Customizing content provided by a service
AU2001291300B2 (en) Providing content from multiple services
JP4218759B2 (ja) ポータル・サーバからセッション情報を中継する方法および装置
AU2001293254B2 (en) Accessing data stored at an intermediary from a service
AU2001295024B2 (en) Developing applications online
JP4406609B2 (ja) 単一のインターフェイスからのデータの多重階層を管理するための手法
US20070220089A1 (en) Modular distributed mobile data applications
JP2006501558A (ja) ウェブ・アプリケーション用のウェブ・ページのセッションをユーザに表示する装置と方法
US20050262119A1 (en) Data processing systems and methods
AU2001293254A1 (en) Accessing data stored at an intermediary from a service
CN102346685A (zh) 集成适配器管理系统和方法
US20030188034A1 (en) Method and apparatus for enabling retargetable application architectures
Team Microservice Application Design
Gomez et al. Second International Workshop on Adaptation and Evolution in Web Systems Engineering (AEWSE’07)

Legal Events

Date Code Title Description
A131 Notification of reasons for refusal

Free format text: JAPANESE INTERMEDIATE CODE: A131

Effective date: 20090601

A601 Written request for extension of time

Free format text: JAPANESE INTERMEDIATE CODE: A601

Effective date: 20090901

A602 Written permission of extension of time

Free format text: JAPANESE INTERMEDIATE CODE: A602

Effective date: 20090908

A521 Request for written amendment filed

Free format text: JAPANESE INTERMEDIATE CODE: A523

Effective date: 20091001

A131 Notification of reasons for refusal

Free format text: JAPANESE INTERMEDIATE CODE: A131

Effective date: 20100315

A521 Request for written amendment filed

Free format text: JAPANESE INTERMEDIATE CODE: A523

Effective date: 20100615

TRDD Decision of grant or rejection written
A01 Written decision to grant a patent or to grant a registration (utility model)

Free format text: JAPANESE INTERMEDIATE CODE: A01

Effective date: 20100705

A01 Written decision to grant a patent or to grant a registration (utility model)

Free format text: JAPANESE INTERMEDIATE CODE: A01

A61 First payment of annual fees (during grant procedure)

Free format text: JAPANESE INTERMEDIATE CODE: A61

Effective date: 20100712

R150 Certificate of patent or registration of utility model

Ref document number: 4551899

Country of ref document: JP

Free format text: JAPANESE INTERMEDIATE CODE: R150

Free format text: JAPANESE INTERMEDIATE CODE: R150

FPAY Renewal fee payment (event date is renewal date of database)

Free format text: PAYMENT UNTIL: 20130716

Year of fee payment: 3

S111 Request for change of ownership or part of ownership

Free format text: JAPANESE INTERMEDIATE CODE: R313113

S531 Written request for registration of change of domicile

Free format text: JAPANESE INTERMEDIATE CODE: R313531

FPAY Renewal fee payment (event date is renewal date of database)

Free format text: PAYMENT UNTIL: 20130716

Year of fee payment: 3

R350 Written notification of registration of transfer

Free format text: JAPANESE INTERMEDIATE CODE: R350

R250 Receipt of annual fees

Free format text: JAPANESE INTERMEDIATE CODE: R250

R250 Receipt of annual fees

Free format text: JAPANESE INTERMEDIATE CODE: R250

R250 Receipt of annual fees

Free format text: JAPANESE INTERMEDIATE CODE: R250

R250 Receipt of annual fees

Free format text: JAPANESE INTERMEDIATE CODE: R250

R250 Receipt of annual fees

Free format text: JAPANESE INTERMEDIATE CODE: R250

R250 Receipt of annual fees

Free format text: JAPANESE INTERMEDIATE CODE: R250

R250 Receipt of annual fees

Free format text: JAPANESE INTERMEDIATE CODE: R250

R250 Receipt of annual fees

Free format text: JAPANESE INTERMEDIATE CODE: R250

R250 Receipt of annual fees

Free format text: JAPANESE INTERMEDIATE CODE: R250

R250 Receipt of annual fees

Free format text: JAPANESE INTERMEDIATE CODE: R250

R250 Receipt of annual fees

Free format text: JAPANESE INTERMEDIATE CODE: R250