MPS 2019.1ヘルプ

オープンAPI - コードからモデルにアクセスする

言語レポジトリ、プロジェクトモジュール、言語、およびモデルは、Open APIを介してプログラム的に便利にアクセスできます。Open APIを使用すると、モデルへのアクセスを制御したり、持続性などのいくつかの側面について独自の実装を提供したりすることもできます。

これら2つの使用箇所の種類について個別に説明します。

注意:このドキュメントはOpen APIの哲学の一般的な概要を説明し、APIへの便利なリンクを提供することを目的としています: 使い方の技術的な詳細については相談してください .

Open APIを使用する

APIはorg.jetbrains.mps.openapiパッケージにあり、いくつかのサブパッケージに分かれています。

  • event - モデルへの変更のためのイベントクラスを含みます

  • language - コンパイルされた言語にアクセスし、それらの構造を調べるための一連のインターフェースを提供します。

  • model - モデルを調べて修正する方法を提供します (AST)

  • module - モデルを論理的に整理する手段としてリポジトリとモジュールを抽象化します

  • 永続性 - モデルの永続化メカニズムを拡張およびカスタマイズするために必要なインターフェースを保持します

  • repository - リポジトリ固有のイベントのリスナーを保持します

  • util - 長期的なアクションをUI進捗インジケータにフックするためのProgressMonitorなどのユーティリティクラスが含まれています

APIはこれらの論理要素を認識します。上の要素はリストの要素を含みます。

  • リポジトリー

  • モジュール

  • モデル

  • ノード

  • プロパティー、参照

Open APIは、上記の要素に直交するメタ構造も認識します。メタ構造は次の重要な要素で構成されています。

  • 言語

  • 概念、列挙

  • メンバー (プロパティー、リンク、列挙リテラルなど)

ノードには関連する概念があります。概念は言語に属します。言語は、言語ユーザーに言語を詳細に調査する方法を提供するために、それらが由来するソースモジュールへのポインタを保持することができます。

APIを使用すると、リポジトリ全体を参照して、そのモジュール、そのモデル、およびそれらのモデルの構築元となるノードを調査できます。さらに、APIには、リポジトリ内の場所に関係なく、要素の使用箇所を検索したり、名前で要素を検索したりする機能があります。これらの要素すべてを変更したり、変更を保存したり、永続的な記憶域から再ロードしたりすることもできます。APIは、メモリ内のモデルとその永続的記憶域に衝突する変更を検出します。

いくつかのAPIの詳細

メタモデルレベル

SAbstractConcept

  • SConceptSConceptInterfaceの両方に共通のスーパークラス

  • 概念の特性包含リンク、および参照リンク のアクセスを提供します

  • getProperties()getContainmentLinks()およびgetReferenceLinks()メソッドを使用して、それぞれ概念のプロパティー、包含および参照リンクを取得します。

SPROPERTY

  • プロパティーを表します

  • 概念間の包含(親子)関係を表します

  • 概念間の明示的な(参照)関係を表します

モデルレベル

スノード

  • モデル内の個々のノードを表します

SR基準

  • ノード間の参照を表します

SNodeReference

  • 永続化してリポジトリからノードを取得するために繰り返し使用できるノードへの一意のグローバル参照

オープンAPIの利用パターン

プロパティーを設定する

Iterable<SProperty> properties = concept/Shape/.getProperties();  list<SProperty> props = new arraylist<SProperty>(copy: properties);  currentNode/.setProperty(props.findFirst({~it => it.getName() :eq: "foo"; }), "value");

子供を追加する

Iterable<SContainmentLink> containmentLinks = concept/Shape/.getContainmentLinks();  list<SContainmentLink> containments = new arraylist<SContainmentLink>(copy: containmentLinks); currentNode/.addChild(containmentLinks.findFirst(...), childNode);

コマンドを使用する

Open APIはモデルを変更する手段も提供します。変更は、処理のためにリポジトリに渡されるコマンドとして実行する必要があります。典型的なモデル変更/編集アクションは未完了/再実行可能ですが、モジュール構造に大きな変更を加えるアクションはできません。変更には3種類あります。

  1. モデルとノードは、元に戻すことができるアクションによって変更できます。

  2. モジュール、そのプロパティー、および依存関係は、リポジトリコマンドを介して実行できます:

  3. そのようなVCSの更新または完全なプロジェクトのリロードなどのプロジェクトに根本的な変化が、外部の更新アクションを実行する必要がある-ないノード・レベルの通知は、このような場合には焼成されていない、唯一のモデルは、置換またはモジュールは、通知がトリガされる変化しました

タイプに応じたコマンドには、モデルの変更を開始する前に、必要なすべての読み取りまたは書き込み権限が自動的に割り当てられます。変更通知は、ノード、モデル、モジュール、またはリポジトリレベルの登録済みリスナーに発行されます。

同時アクセス

Open APIは同時アクセス用に設計されており、提供されている同期メカニズムが呼び出しコードによって正しく利用されていれば、Open APIを介してモデルに同時にアクセスする複数のスレッドを正しく処理します。Open APIは、不適切に同期された要求をすべて拒否し、それによってモデルの整合性を維持します。

より具体的には、操作を実行する前に読み取りまたは書き込みアクションを取得する必要があります。そうしないと、コードから例外が発生します。

リポジトリ(英語)を使用してください。getRepositoryAccess()(英語) .applyChanges()を使用して、変更内容をリポジトリリポジトリ(英語)全体に適用します。getModelAccess()(英語) .runXXXAction()で読み取り/書き込みアクションを実行し、リポジトリ(英語)を実行します。コマンドを実行するためのgetModelAccess()(英語) .executeCommand()。コマンドはすべての書き込み権限を自動的に取得するため、常にリポジトリへの排他アクセス権を取得します。どちらの方法でも、EDT内で提供されたアクションを非同期的に実行する非同期バリアントが提供されています。

モデルロックの例

リポジトリはモデルのロックを開始するのに適した場所です。EditorContextなどのコンテキストオブジェクトからリポジトリ参照を取得できます。あなたのコードはModelAccessを取得してロックを取得することができます。

(node, editorContext)->JComponent {  //get ModelAccess from the context final ModelAccess modelAccess = editorContext.getRepository().getModelAccess();    //read the model final boolean[] active = new boolean[]{false}; modelAccess.runReadAction(new Runnable() { public void run() { active[0] = node.showActive; } }); final JButton button = new JButton(active[0] ? "Show all" : "Show active"); button.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent p0) {  //update the model in an action, that can be undone modelAccess.executeCommand(new Runnable() { public void run() { node.showActive = !node.showActive; } }); } }); return button; }  

カスタム持続性

デフォルトでは、MPSはモデルをフラットファイルとしてXMLまたはバイナリ形式で保存します。モデルの保存方法をカスタマイズできるように、Open APIにはいくつかのオプションがあります。

代替ファイル形式

フラットファイルに格納されているモデルデータの形式を変更することは、モデルの永続性をカスタマイズする最も簡単な方法です。(PersistenceFacade(英語)を通して)選んだファイル拡張子で独自のModelFactory(英語)を単に登録すれば、そのファイル拡張子が発見されるときはいつでもMPSはあなたのカスタムSModel(英語)インプリメンテーションを具体化するためにそのファクトリーを使います。SModelIdFactory(英語)SNodeIdFactory(英語)の独自の実装を提供し登録する必要もあります。

代替保管

さらに冒険的で、たとえばデータベースや他の非ファイルストレージからあなたのモデルをロードしたいなら、カスタムModelRoot(英語)インスタンスを作成できるModelRootFactory(英語)をさらに提供する必要があります。これらのモデルルートは、モデルをロード/保存するために、選択したストレージのすべての詳細を処理します。通常、ユーザーがデータベースの場所、ユーザー名などのデータソースの詳細を構成できるようにするためのUIをバンドルする必要もあります。

カスタム検索の使い方とナビゲーションの参加者

FindUsagesParticipant(英語)のカスタム実装を提供すると、カスタム持続性を使用してモデル内のFindUsagesを最適化できます。同様に、ナビゲーション参加者(英語)のカスタム実装はルート/クラス/シンボルに移動アクションを最適化する機会があります。PersistenceFacade(英語)にカスタム参加者を提供することで、デフォルトで使用方法とナビゲーションの実装がすべてのモデルをメモリにロードして標準的な方法で処理するのではなく、永続ストレージに直接アクセスしてナビゲーションと同様に検索を高速化することができます。

最終更新日: 2019年6月7日