2010年3月31日水曜日

EMF Transactionについてまとめてみました

EMFTransaction
EMF Transactionについて

EMFのデータモデルをトランザクションを用いて、複数スレッドからのアクセスコントロールやデータの整合性(atomic)を守る仕組み。 EditingDomainを用いてやり取りを行います。

簡単な説明はざっくり飛ばします。参考サイトを読んでください。


予備知識:EditingDomain

editingDomainは相関のあるEMFモデルを含んでいるのとコマンドを管理するものです。モデルはリソースセットの形式で保持されていています。
コマンドとモデルの編集はドメインを経由して、コマンドスタックを使って行います。
EditingDomainの補足機能として、基本的なコマンドのオーバーライドが使えます(OverrideableCommand. を参照)
ドメインはgetParent,getChildrenメソッドの結果でモデルへ階層的に役割を課す。
これはネストしたオブジェクトの削除などに使うRemoveCommandなどの実装に便利である。
また、ネストしたコピーなどに使うCopyCommandも便利である。

クラス図的にはこんな感じ

Transactional Commands API




Transactional Commands API


EditingDomain取得方法

EMFTransactionはEditingDomainを利用して、データのやり取りを行うため、EditingDomainを取得する必要があります。取得方法としてはTransactionUtilのユーティリティクラスのgetEditingDomainメソッドを利用します。
引数はEObject,Resource,ResourceSetのいずれかを入れてやれば取得が行えます。

データアクセス方法
データ取得

データの取得に関してはデータの変更が行われないため、取得方法はどのようにしても構いません。リソースからモデルを取得して任意のデータを取得することが可能です。

データ更新

コマンドを用いてデータ更新は行います。リソースから直接取得してデータ更新を行うとExceptionが投げられます。


public void setModuleDet(String moduleName, boolean detInfo) {
EObject owner = null;
EAttribute feature = null;


try{
Command cmd = editingDomain.createCommand(
SetCommand.class,
new CommandParameter(
owner,
feature,
detInfo
));

editingDomain.getCommandStack().execute(cmd);
} catch (Exception e) {
logger.warn(e.getMessage());
}
}



ロールバック

トランザクション環境で、データ整合性が失われた場合ロールバックするために、R/Wのトランザクションが発生する。しかし、基本的なコマンドスタックAPIはコマンドを失敗することはないので、
ロールバックしたときのフィードバックはない。
もし、トランザクションが始まっていなく、トランザクションがロールバックや、割り込み例外が発生したとき、トランザクションコマンドスタックはロールバック例外を投げることができる。


Library richmond = getLibrary("Richmond Branch"); // this would use a read-only transaction
TransactionalEditingDomain domain = getEditingDomain();

TransactionalCommandStack tstack = (TransactionalCommandStack) domain.getCommandStack();

Command cmd = domain.createCommand(
SetCommand.class,
new CommandParameter(richmond, EXTLibraryPackage.Literals.LIBRARY__ADDRESS, "5600 Perth St."));

try {
tstack.execute(cmd, Collections.EMPTY_MAP);
} catch (InterruptedException e) {
MessageDialog.openError(shell, "Command Failed",
"Interrupted while waiting for a read/write transaction.");
} catch (RollbackException e) {
ErrorDialog.openError(shell, "Command Failed", "Transaction rolled back",
e.getStatus());
}



コマンドオプション

コマンド実行に対して、色々オプションを付けて実行が行える。

Transaction Options




* OPTION_NO_NOTIFICATIONS:  リスナに変更通知を送らない。
* OPTION_NO_TRIGGERS: トリガーを使わない。
* OPTION_NO_VALIDATION: 変更に整合性チェックを行わない。
* OPTION_NO_UNDO: UNDO/REDOやロールバックのための変更記録を行わない。
* OPTION_UNPROTECTED: OPTION_NO_UNDO, OPTION_NO_VALIDATION, and OPTION_NO_TRIGGERSの複合ケース



TransactionalCommandStack stack;
Library library;

// don't tell the UI that we are changing the library name
stack.execute(
SetCommand.create(domain, library,
EXTLibraryPackage.Literals.LIBRARY__NAME, "Secret Name"),
Collections.singletonMap(
Transaction.OPTION_NO_NOTIFICATIONS, Boolean.TRUE));



トリガー
トリガーの実装も可能である。
Trigger API






// trigger ensuring that all libraries have names
class MyListener extends ResourceSetListenerImpl {
MyListener() { // only interested in changes to Library objects
super(NotificationFilter.createNotifierTypeFilter(
EXTLibraryPackage.Literals.LIBRARY));
}

public Command transactionAboutToCommit(ResourceSetChangeEvent event)
throws RollbackException {

List commands = new ArrayList();
Iterator iter = event.getNotifications().iterator();

while (iter.hasNext()) {
Notification next = (Notification) iter.next();
Library library = (Library) next.getNotifier();
if (library.getName() == null)
commands.add(SetCommand.create(
event.getEditingDomain(), library,
EXTLibraryPackage.Literals.LIBRARY__NAME, "A library"));
}

return commands.isEmpty()? null : new CompoundCommand(commands);
}
}



class MyTriggerListener extends TriggerListener {
MyListener() { // only interested in changes to Library objects
super(NotificationFilter.createNotifierTypeFilter(
EXTLibraryPackage.Literals.LIBRARY));
}

protected Command trigger(TransactionalEditingDomain domain,
Notification notification) throws RollbackException {

Library library = (Library) next.getNotifier();
if (library.getName() == null) {
return SetCommand.create(domain, library,
EXTLibraryPackage.Literals.LIBRARY__NAME, "A library");
}

return null;
}

}



参考サイト

2010年3月29日月曜日

WindowTester Pro 5.0リリース

WindowTester Pro 5.0のリリースだそうなので色々調べてみました。

InfoQにWindowTester Pro 5.0がリリースというニュースを見たので、
ちょっと気になったため調べてみました。
GUI作成ツールを調査しているときにRCP DeveloperやWindowBuilderが
引っかかりWindowTesterも知っていました。
WindowTesterのデモを見るとわかるとは思いますが、SWTBotの動作を
より実運用的にしたイメージです。
・http://www.instantiations.com/flash/wt_demo/record_playback_eclipse_test.html
・http://www.instantiations.com/flash/wt_demo/record_playback_rcp_test.html

SWTBotのレコード機能とgroovyをうまく使いこなせばある程度近いものは作れないかなぁ?
とは思ってみたりするんだけど、そんな時間がない。。。。。
SWTBotのレコード機能をちょっと調査してみたいです。


http://www.instantiations.com/mktg/windowtester-demo.html

2010年3月21日日曜日

eclipse 3.6(Helios)をインストールしてみた

eclipseのHelios(Modeling Tools)をインストールしてみました。
現在2010/03/20のバージョンはM6(03/12/2010)でAPI Freeze状態です。
GW前にはFeature Freezeになるそうです。

・GalileoとはCompatibilityがある。
・InternationalizationはLatin-1,DBCSロケールデフォルトサポート。ドイツ語、日本語は現在テスト中のこと。
・EMF QueryがM5で入っていないというMLで流れていたが、すでにM6では入っている。QVTは問題なく使えそう。OCLも入っている。
・subcripseも普通にインストールできた。
・GMFはデフォルトで入っていないため、インストールが必要(しかし更新サイトからのインストールが固まる)

とりあえず以下のパッケージがデフォルトで入っているようです。

org.eclipse.amalgam.discovery
org.eclipse.cvs 1.1.0
org.eclipse.emf.cdo.epp
org.eclipse.emf.compare.sdk
org.eclipse.emf.mint.sdk
org.eclipse.emf.query.sdk
org.eclipse.emf.sdk
org.eclipse.emf.transaction.sdk
org.eclipse.emf.validation.sdk
org.eclipse.epp.usagedata.feature
org.eclipse.equinox.p2.user.ui 1.1.0
org.eclipse.gef.sdk
org.eclipse.help 1.1.0
org.eclipse.jdt 3.6.0
org.eclipse.mylyn.bugzilla_feature
org.eclipse.mylyn.context_feature
org.eclipse.mylyn.ide_feature
org.eclipse.mylyn.java_feature
org.eclipse.mylyn.pde_feature
org.eclipse.mylyn.wikitext_feature
org.eclipse.mylyn_feature
org.eclipse.ocl.all.sdk
org.eclipse.pde 3.6.0
org.eclipse.rcp 3.6.0
org.eclipse.sdk 3.6.0
org.eclipse.uml2.sdk
org.eclipse.xsd.sdk

2010年3月16日火曜日

EMF Transaction

またまた新しい知識を得なければならなくなりました。
その名もEMF Transaction。

http://help.eclipse.org/ganymede/index.jsp?topic=/org.eclipse.emf.doc/references/overview/EMF.html

概要を説明すると、EditingDomainをマルチスレッドアクセスでも整合性を保つようにDBのような
トランザクションの仕組みをEMFに取り込んだものである。
基本的にはトランザクションはコマンドをトランザクションとして処理を行う。



ざっくりな和訳


The transaction framework provides the capability of managing access to an editing domain
by multiple reading and writing threads. It also provides a facility to register and
share an editing domain amongst different clients and listeners. Resource set listeners
are defined in the transaction layer and are provided with notifications in batches.
The resource set listener has the option to append changes before the transaction is
committed (pre-commit) or receive only the notifications of transactions that were
validated and not rolled-back (post-commit). The following are the main extension
points and classes to be used with the transaction framework:


トランザクションフレームワークはマルチスレッドによるEditingDomainのR/Wのアクセス管理を可能にする。
異なるクライアント間でeditingDomainとリスナの共有と登録で実現できている。
リソースセットリスナはトランザクション層で定義されていて、
バッチの通知で提供されている。
リソースセットリスナは変更を追加するオプションを持っている。
トランザクションがコミットされる前やvalidateされたトランザクションや
ロールバックされていないトランザクションの通知を受け取る前に
次の拡張ポイントとクラスでトランザクションフレームワークが利用されている。

2010年2月16日火曜日

Groovyのテストケース作成ウィザード

Groovyでテストケース作成した場合正しくコード生成が行えないことがわかった。
doSample(),doString()メソッドがあるクラスのテストクラスを自動生成したが
testDoSample(),testDoStrin()メソッドがクラスの外部に生成されている。
そのため、エラーが発生する。

package sample.test;

import static org.junit.Assert.*;

import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;

class hoge {

@BeforeClass
public static void setUpBeforeClass() throws Exception {
}

@AfterClass
public static void tearDownAfterClass() throws Exception {
}

@Before
public void setUp() throws Exception {
}

@After
public void tearDown() throws Exception {
}

@Test
public final void testDoStringObject() {
fail("Not yet implemented"); // TODO
}
}

@Test
public final void testDoSample(){
fail("Not yet implemented"); // TODO
}

@Test
public final void testDoString(){
fail("Not yet implemented"); // TODO
}

2010年2月12日金曜日

antを勉強する

プロジェクトで開発を行うためには自動化が重要ということでantをマスターせねばということでantの本を買いました。
ant

開発に必要なプロジェクトをsubversionで更新を行う&リフレッシュをするという仕組みを作る。
以下こんな感じでやるのがよいかもしれません。



 
 




 
















2010年2月8日月曜日

EMFValidationの翻訳

使えるかと思うので翻訳をしてみました。
あとでちゃんと直します。


The validation framework provides support for constraint providers for any EMF meta-model (batch and live constraints), customizable model traversal algorithms, constraint parsing for languages, configurable constraint bindings to application contexts and validation listeners. The following are the main extension points and classes to be used with the validation framework.

ValidationFrameworkは以下のような制約プロバイダのサポートを提供する。
EMFメタモデル、モデルトラバーサルアルゴリズム、言語の制約パース、アプリケーションコンテキスト、validation リスナのバインディング制約などである。
次のようなvalidationFrameworkを使ったクラスや拡張ポイントがある。


1.The extension point org.eclipse.emf.validation.constraintProviders is used to provide constraints. Static constraint providers declare constraints in the plugin.xml. Constraints are grouped into hierarchically structured categories. Constraint providers target one or more EPackages by namespace URI. A group of constraints declares categories in which they are members. Each constraint has a variety of meta-data associated with it (Language, ID, severity, mode, name, message, triggers, etc.). Dynamic constraint providers address situations where constraints cannot be declared statically. e.g., where constraints are defined in models or other resources. Dynamic providers declare a class implementing the IModelConstraintProvider interface. This class is responsible for making constraints available on the appropriate triggers, organizing them into categories, etc.

拡張ポイントorg.eclipse.emf.validation.constraintProvidersで制約を与えることができる。
静的な制約はplugin.xmlで宣言をすることができる。
制約は構造化されたカテゴリに階層的にグループ化することができる。
制約プロバイダは1つのターゲットや名前空間URIのEPackageをターゲットにすることができる。
制約グループはメンバーのカテゴリを宣言する。
各々の制約はそれに関連するメタデータに種類を持つ。
(言語、ID,severity,mode,name,message,triggers)
次に動的な制約は静的に制約が定義できない場合に使われる。
制約はモデルや他のリソースで定義される。
動的な制約プロバイダはIModelConstraintProviderインタフェースを実装したクラスで
定義できる。
このクラスは適当なトリガや、カテゴリに組み込む制約を有用化する責任をおう。

2.The extension point org.eclipse.emf.validation.traversal is used to provide customizable model traversal algorithms. Batch validation traverses a subset of the model starting from the user's selections. No traversal is performed in live validation. Some meta-models require custom strategies for traversal. The default strategy simply iterates the content tree via eAllContents() API. Some meta-models do not use EMF containment relationships extensively, or implement logical models on multiple distinct resources, making containment-based traversal impractical.

拡張ポイントorg.eclipse.emf.validation.traversalはモデルトラバーサルなアルゴリズムで使用する。
バッチvalidationはユーザの選択したモデルのサブセットを横断する。
live validationはモデルの横断はできない。
トラバーサルには独自ロジックが必要となる。
デフォルトのロジックはeAllContents() APIを通してコンテンツツリーを走査する。
メタモデルはEMF Containment関係を使わない。
または、または多重の区別するリソースについてモデルや実用的なコンテナベースの横断を
持ったモデルを実装する。


3.The extension point org.eclipse.emf.validation.constraintParsers is used to provide constraint parsing for languages. The validation framework provides support for two languages: Java and OCL. Clients can provide support for other constraint languages via constraint parsers. The Language ID: used in the lang attribute of constraint elements in the constraint XML. The Class: identifies an implementation of the IXmlConstraintParser interface, which constructs a constraint from the XML configuration data. Constraint parsers are responsible for parsing the content of a constraint element in the plugin.xml to produce IModelConstraint objects.

拡張ポイントorg.eclipse.emf.validation.constraintParsersは言語の制約パースに対して使われる。
validation frameworkは2つの言語(Java OCL)で利用される。
クライアントは制約パーサを通して他の制約言語に対するサポートを提供できる。
言語ID:制約XMLの中の制約の要素の属性で使われる。
クラス:IXmlConstraintParserインタフェースで実装された識別
XMLの設定ファイルからの制約で作成された。
制約パーサはIModelConstraintを作るためのplugin.xmlに記述された
制約要素のコンテンツをパースするのに使われる。


4.The extension point org.eclipse.emf.validation.constraintBindings allows clients of the EMF Validation framework to define "client contexts" that describe the objects that they are interested in validating, and to bind them to constraints that they are interested in enforcing on these objects. A client context can declare an enablement expression that matches model elements that are included in the context. Where that is not sufficient, an alternative is to define a selector class using a selector element. Client contexts can be bound to constraints, individually, or to constraint categories (to bind all of the constraints in the category). Binding to constraint categories has the advantage of allowing new constraint contributions in a category to automatically be bound to the appropriate client context, even if the constraint is defined in a plug-in that is unaware of that context or its binding to the category. Category bindings are inherited by sub-categories from their ancestors.

拡張ポイントorg.eclipse.emf.validation.constraintBindingは
EMFValidationフレームワークのクライアントが"クライアントコンテキスト"を定義できる。
クライアントコンテキストはvalidationで興味があるオブジェクトを記述する。
オブジェクトに対して実施することに興味がある制約に対してバインドする。
クライアントコンテキストはコンテキストの中にあるモデル要素にマッチした可能な表現
で定義する。
十分でない場合、オルタネイティブはセレクタ要素を使ってセレクタクラスを定義すべきである。
クライアントコンテキストは制約や制約カテゴリ(カテゴリのすべての制約)に対してここに
バインディングできる。
制約カテゴリのバインディングはクライアントコンテキストを自動的にバインディングするため
カテゴリへの新しい制約の寄与の利点を持つ。
たとえ制約がコンテキストを意識せずにプラグインやカテゴリへのバインディングを定義できたとしても、
カテゴリバインディングは親からのサブカテゴリによって受け継がれる

5.The extension point org.eclipse.emf.validation.validationListeners is used to define validation listeners for the validation service (org.eclipse.emf.validation.service.ModelValidationService). The validation service will inform this listener whenever validation has occurred, loading it if necessary in order to do so. This is most useful for cases where client plug-ins need to find out about validation events even before they are loaded. Otherwise, it is usually simpler just to programmatically add a listener to the validation service. The value of the listener element class attribute must be the fully qualified name of a class that implements the IValidationListener interface. Listeners can also be registered in code, at run-time, using the ModelValidationService.addValidationListener() method.

拡張ポイント.org.eclipse.emf.validation.validationListenersは
validationサービスに対してvalidationリスナを定義するために利用する。
validationサービスはリスナにvalidationが起きたという情報を伝える。
もしそのようなことをするためには必要ならば、リスナをロードする。
これはクライアントプラグインがロードする前にvalidationイベントについて
理解する必要があるケースに使われる。
普通validationサービスに対してリスナをプログラム的に追加するのは簡単。
リスナ要素のクラス属性の値がLValidationListenerインタフェースを実装したクラス名を
制限されなければならない。
実行時はMdelValidationService.addValidationListerner()を使ってリスナは登録される。

6.The ModelValidationService singleton coordinates the invocation of validation. It defines a single factory method for creation of IValidator for the batch and live evaluation modes. Validators validate one or more objects at a time; the kind of object accepted as input depends on the evaluation mode. They can be configured to report constraint passes as well as failures, for verbose results. Results are reported as IValidationStatus. Validators can be reused by a client for any number of validation operations. The ILiveValidator validates EMF Notifications. The IBatchValidator validates EObjects and, due to its support for model traversal, supports progress monitors. Registered traversal strategies can be overridden by the client.

ModelValidationServiceはシングルトンでvalidationの実行を行う。
これはbatchモードliveモードに対してIValidatorを生成するファクトリメソッドを
定義する。
Validatorsは1つやそれ以上のオブジェクトをvalidateする。
評価モードに依存する入力として受けられたオブジェクトの種類。
それらは詳細な結果に対して制約の通過同様失敗のレポートすることを設定される。
結果はIValidationStatusとしてレポートされる。
Validatorはvalidation operationの数に対してクライアントは再利用する。
ILiveValidatorはEMF通知をvalidateする。
IBatchValidatorはEObjectをvalidateし、モデルトラバーサル、プログレスモニタ
をサポートする。
登録されたトラバーサルストラテジはクライアントでオーバーライドする。

7.Clients can create an EValidator implementation that delegates to the validation framework.

クライアントはvalidation frameworkを委譲したEValidator実装で作成される。


8.The framework provides implementation of an XML constraint parser (org.eclipse.emf.validation.xml.IXmlConstraintParser) API that supports definition of XML constraints in OCL. The class OclConstraintParser is the constraint parser implementation that creates instances of the OclModelConstraint class, the OCL-language constraint implementation, from XML constraint descriptors. It uses the Query class to test model elements against an OCL constraint expression.

frameworkはXML制約パーサAPIの実装を提供する。
(org.eclipse.emf.validation.xml.IXmlConstraintParser)
APIはOCLのXML制約を定義できる。
クラスOclCOntraintParserは制約パーサである。
OclModelConstraintクラスでインスタンス化された制約パース実装である。
OCL言語は制約を、実装する。
OCL制約表現に対してモデル要素のテストするためにクエリクラスを使う。