Archive for the ‘sdo’ Category
Apache Tuscany’s SDO Java Release 1.0-incubating
TuscanyのSDOバージョン1.0-incubatingがリリースされました。
http://incubator.apache.org/tuscany/sdo-java-10-incubating.html
Apache Tuscany’s SDO Java Release 1.0-incubating is the first release with full coverage of the SDO 2.1 specification.
In addition to adding the few remaining SDO 2.1 features not included in the 1.0-incubating-beta1 release and fixing a number of bugs there are a number of new features relating to XML serialization, and new support for handling dynamic derivation from static classes. There has also been significant focus on making the SDO sample programs more accessible.
ChangeSummary
ようやくChangeSummaryです。謎のxmlの不具合でやたらと時間がかかってしまいましたが、さっそくDataObjectを編集してみましょう。SDOUtilを使って、xmlからDataGraphを生成します。
元のxml
<?xml version=”1.0″ encoding=”UTF-8″?>
<sdo:datagraph xmlns:fireworks=”fireworksDataGraph.xsd” xmlns:sdo=”commonj.sdo”>
<fireworks:fireworksEvent eventID=”1″ eventName=”全国新作花火競技会” location=”諏訪湖” date=”2007-09-01″>
<comments>雨天決行</comments>
<firework id=”1″ title=”Advanced Technologies” pyrotechnist=”松尾潤子” size=”3″ pattern=”型物” score=”0″/>
</fireworks:fireworksEvent>
</sdo:datagraph>
今年の全国新作花火競技会で、松尾潤子さんという花火師が”Advanced Technologies”というタイトルの花火を上げます。それを審査員が採点するプログラムとなっています。
前準備として、ChangeSummaryのloggingを開始。
ChangeSummary cs = dataGraph.getChangeSummary();
cs.beginLogging();
先ずはルートDataObject (dataObject)から、XPathを指定してfireworkデータオブジェクトのidプロパティの値が1のDataObjectを取得します。pathは操作対象となるDataObjectの構造を知らないと指定できませんが、データソースに関係なく統一的な手法でアクセスできるのはやはり便利です。
DataObject firework = dataObject.getDataObject(“firework[id = 1]“);
次に、scoreを編集。元のxmlで、scoreが要素なのか属性なのかを気にせずにアクセスできています。
firework.setInt(“score”, 99);
DataGraphをファイルに書き出すと、ChangeSummaryは次のようなxmlで表現されていました。
<?xml version=”1.0″ encoding=”UTF-8″?>
<sdo:datagraph xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance”
xmlns:fireworks=”fireworksDataGraph.xsd” xmlns:sdo=”commonj.sdo” xmlns:sdo_1=”http://www.apache.org/tuscany/2005/SDO”>
<changeSummary xmlns=”"
logging=”true”>
<objectChanges key=”#//@eRootObject/@firework.0″>
<value xsi:type=”sdo_1:ChangeSummarySetting” featureName=”score” dataValue=”0″/>
</objectChanges>
</changeSummary>
<fireworks:FireworksEventType eventID=”1″
eventName=”全国新作花火競技会” location=”諏訪湖” date=”2007-09-01″>
<comments>雨天決行</comments>
<firework id=”1″ title=”Advanced Technologies” pyrotechnist=”松尾潤子” size=”3″ pattern=”型物” score=”99″/>
</fireworks:FireworksEventType>
</sdo:datagraph>
undoも可能。
cs.undoChanges();
undoした場合、ChangeSummaryは残りません。但し、loggingを開始すると、変更しなくてもchangeSummary要素が追加されます。
<?xml version=”1.0″ encoding=”UTF-8″?>
<sdo:datagraph xmlns:fireworks=”fireworksDataGraph.xsd” xmlns:sdo=”commonj.sdo”>
<changeSummary xmlns=”"
logging=”true”/>
<fireworks:FireworksEventType eventID=”1″
eventName=”全国新作花火競技会” location=”諏訪湖” date=”2007-09-01″>
<comments>雨天決行</comments>
<firework id=”1″ title=”Advanced Technologies” pyrotechnist=”松尾潤子” size=”3″ pattern=”型物” score=”0″/>
</fireworks:FireworksEventType>
</sdo:datagraph>
PropertyのisContainment()とisMany()
DataGraphとDataObjectを実際にプログラムの中で扱ってみると、直感的にわからないことが多いのに気付きます。TypeとPropertyのメソッドも、何が取得できるのかわかりにくい。
とりあえず、サンプルのUsingTypeAndPropertyWithDataObjects.javaを参考に、DataGraphに格納されている値をSequenceを使わずに全て取り出してみました。余談ですが、SDOのサンプルプログラムはこのように、クラスが何をしているのかわかるようなとても長い名前が付けられています。
先ずは、 getRootObject()メソッドで、DataGraphからルートDataObjectを取得。
次に、getType().getProperties()メソッドで、ルートDataObjectからプロパティを取得。
ここから先が、直感的ではなくなってきます。プロパティがどんな状態なのかを調べなければなりません。
- 単一の値を保持している
- 複数の値を保持している -> PropertyのisMany()メソッド
- 包含関係が定義されている -> PropertyのisContainment()メソッド
包含関係が定義されているプロパティが複数という場合もあるでしょう。
/* (isContainment() == true) && (isMany() == false) という場合もあると思うのですが、TuscanyのSDOで試している限りでは、今のところ包含している要素を1つにしても isMany() == true が返ってきます。 */
isMany() == true の場合は、DataObjectのgetListメソッドでListを取得します。DataObjectのgetメソッドの戻り値は、many-valuedならList型になります。
isContainment() == true の場合は、ObjectをDataObjectにキャストして再帰的に値を取得する、という流れです。
SDOUtil.loadDataGraph()メソッドでxmlファイルからDataGraphを取得する
本来DataGraphはDASにリクエストして取得しますが、DASはSDOの仕様範囲外です。そこでTuscanyのDASをダウンロードしてみたところ...なんと、TuscanyのDASはRDB DASなのです。XML File DASは見当たらず、RDBを準備している時間もなく。
しかし、TuscanyのSDOは私を見捨てませんでした。
SDOUtil.loadDataGraph()メソッドで、xmlファイルからDataGraphを取得することができます。サンプルあり。このユーティリティはSDOの仕様外です。
明日はいよいよ、DataGraphとChangeSummaryに着手する予定。
[追記]
xmlは<sdo:datagraph xmlns:yournamespace=”yourschema.xsd” xmlns:sdo=”commonj.sdo”></sdo:datagraph>の中に記述します。
SDOの disconnected data architecture
エンドユーザーは通常、Data Access Service (DAS)を通してデータグラフにアクセスします。DASはデータの格納場所からデータグラフをロードし、データグラフを格納場所に保存するメソッドを提供するJavaのクラスです。例えば、XML File DASはXMLファイルを格納場所とするデータグラフを扱い、JDBC DASはRDBを格納場所とするデータグラフを扱います。(それぞれのDASの仕様はSDOの仕様の範囲外。)
DASは典型的なディスコネクテッド・データ・アーキテクチャを採用しています。クライアントは、データグラフを読み込む時と書き出す時のみDASにアクセスします。そのため、データグラフにアクセスする一般的なシナリオは、以下のようなイメージです。
- アプリケーションは、DASにデータグラフのロードをリクエストする。
- DASは、永続的なデータの格納場所に対してトランザクションを開始し、データグラフを作成してトランザクションを終了する。
- DASは、リクエストがあったアプリケーションにデータグラフを渡す。
- アプリケーションは、データグラフに対して何かしらの処理を行う。
- アプリケーションは、DASにデータグラフの更新をリクエストする。
- DASは、新しいトランザクションを開始し、データグラフの変更点を元に永続化されているデータを更新し、トランザクションを終了する。
DataGraph
全てのデータグラフは、単一のルートDataObjectを持ちます。ルートDataObjectは、データグラフに含まれている全てのDataObjectを直接的または間接的に含んでいます。
あるデータグラフに含まれる全てのDataObjectが同じデータグラフ内のDataObjectだけを参照している場合、そのデータグラフは「closedなデータグラフ」と呼ばれます。データグラフは通常、closedです。
データグラフの構成要素
- ルートDataObject
- ルートDataObjectからcontainment propertyとして再帰的に横断できる全てのDataObject
closedなデータグラフはtreeを形成します。
データグラフは含まれているDataObjectを描写している図式を覚えています。また、DataObjectの変更を表すChangeSummaryを管理しています。
“data graph” と DataGraph
ようやくDataGraphにたどり着きました。
DataGraphは関連している複数のDataObjectをまとめる封筒のようなものです。
仕様書では”data graph”と”DataGraph”という記述が見られます。”data graph”と書かれている場合は、任意のDataObjectのセットを意味します。”DataGraph”と書かれている場合は、ある特定のDataGraphオブジェクトを意味します。日本語では”data graph”を”データグラフ”とし、”DataGraph”はそのまま”DataGraph”と書くのが良さそうです。
Open Content
DataObjectは2種類のプロパティを持つことができます。
- Typeを特定したプロパティ
- Typeを特定しないプロパティ
2の、Typeを特定しないプロパティをOpen Contentと呼びます。
Typeが特定されたDataObjectのプロパティは、getType().getProperties()メソッドでリストを取得します。
DataObjectは次のような場合にTypeを特定しないプロパティも持つことができます。
- XMLのオープンコンテントモデルを扱う場合
- 動的に生成されたプロパティを扱う場合
オープンコンテントプロパティは、Type.openの値がtrueの場合に使用可能です。DataObjectのコンセプトでも触れていますが、オープンコンテントプロパティは、getType().getProperties()で取得されるプロパティのリストには含まれません。getInstanceProperties()メソッドで取得します。
TypeとProperty
TypeとPropertyは、DataObject内部のメタデータAPIです。DataObjectのモデル、及びデータ型のモデルを内観するためのもの。
PropertyがDataObjectの値を保持しているので、DataObjectが直接Propertyを持っている印象がありますが、Propertyを持っているのは実はType。なので、DataObjectが持っているプロパティの一覧を取得するには、 getType().getProperties()メソッドを呼びます。
SDOとプログラミング言語、データモデリング言語のマッピング
Java、C++、UML、EMOFのクラス
- クラスはType
- 各フィールドはProperty
XML Schema
- 単純型と複合型はType
- 要素と属性はProperty
C言語の構造体
- 構造体はType
- 構造体の各フィールドはProperty
リレーショナルデータベース
- テーブルはType
- カラムはProperty
Sequence
If a DataObject’s Type is sequenced then getSequence() returns that Sequence, otherwise getSequence() returns null.
いきなりこんなことを言われても、sequencedだったら、という意味がよくわかりませんね。とりあえずSequenceの特徴を見てみましょう。DataObjectのコンセプトには
プロパティ内部、複数のプロパティ間の順序が保持されているJavaBeanと言うことができます。XMLのDOMに相当します。
と書いてあります。 これも、わかるような、わからないような。
ひとつずつ整理してみます。
- DataObjectの値はPropertyに割り当てられる。
- ひとつのPropertyは複数の値を持つことができる。「プロパティ内部の順序」というのは、ひとつのPropertyが持っている値の順序。
- 「複数のプロパティ間の順序」というのは、複数の値を持つ、複数のProperty間の順序。int型のプロパティ”numbers”と、文字列型プロパティ”letters”を持つDataObjectがあるとします。それぞれのプロパティは、複数の値を持っています。このDataObjectのSequenceに対して以下の操作を行った場合にどうなるかを考えてみましょう。
- numbersプロパティに1という値を追加
- “annotation text”という文字列をSequenceに追加
- lettersプロパティに”A”という値を追加
- numbersプロパティに2という値を追加
- lettersプロパティに”B”という値を追加
この場合、Sequenceに格納されている値を順番に読むと
{<numbers, 1>, <null, ”annotation text”>, <letters, ”A”>,<numbers, 2>, <letters, ”B”>}
となります。
numbersプロパティには{1, 2}、 lettersプロパティには{“A”, “B”}という値が格納されていますが、numbersプロパティとlettersプロパティを横断した順序はSequenceインタフェースを通してアクセスした場合のみ取得可能です。


