組み込みのモデリングツールとして一般的なEnterprise Architectのファイルは、zipファイルとして解凍すると、テキストベースのXMLとして、モデルデータの各種解析や編集が可能になるのが一部で知られています。
一方で同じく組み込み一般的なAstah*の方は、zipファイルとして解凍は可能なものの、中身はバイナリファイルでEAのような解析編集が難しくなっています。ただAPIが提供されていて、その活用で柔軟な処理を行えます。今回はそのAPIの使い方について触れたいと思います。
概要
astah* APIはJavaのAPIです。最新版だと無料のCommunity版でもモデルの解析や編集が可能になっています。
http://astah.change-vision.com/ja/astah-api.html などに情報がまとまっています。
astah* APIライブラリの追加
astah* APIを使用する際は、Community版の場合、astah-communityとastah-apiの2つが必要です。Mac環境のIntelliJだと、ProjectSettingのLibrariesに以下を追加します。
/Applications/astah community/astah community.app/Contents/Java/astah-community.jar /Applications/astah community/astah community.app/Contents/Java/astah-api.jar
実装
ProjectAccessorを使ってastahのファイルを操作します。細かな仕様は以下などで情報が提供されています。
http://astah.change-vision.com/ja/astah-api.html
http://members.change-vision.com/javadoc/astah-api/7_1_0/api/ja/doc/index.html
実装として、テスト設計の補助を想定して、astah*の状態遷移図のトリガイベントを網羅的にピックアップするコードを書いてみました。
//TARGET_FILE内で作成されている、TARGET_SMDの名前のステートマシン図のトリガイベントをすべて表示 import com.change_vision.jude.api.inf.model.*; import com.change_vision.jude.api.inf.project.ProjectAccessor; import com.change_vision.jude.api.inf.AstahAPI; public class PrintStateTransitions { private static final String TARGET_FILE = "/Users/ih/Desktop/sample.asta"; private static final String TARGET_SMD = "sampleStateMachine"; public static void main(String[] args) { ProjectAccessor prjAccessor = null; try { prjAccessor = AstahAPI.getAstahAPI().getProjectAccessor(); prjAccessor.open(TARGET_FILE, true, false, true); checkStateTransitions(prjAccessor.getProject()); } catch (Exception e) { e.printStackTrace(); } finally { if (prjAccessor != null) { prjAccessor.close(); } } } private static void checkStateTransitions(IPackage iPackage) { INamedElement[] ine = iPackage.getOwnedElements(); for (int ip = 0; ip < ine.length; ip++) { INamedElement[] idg = ine[ip].getDiagrams(); for (int id = 0; id < idg.length; id++) { if (idg[id] instanceof IStateMachineDiagram && idg[id].getName().equals(TARGET_SMD)) { printAllStateTransitions((IStateMachineDiagram)idg[id]); } } if (ine[ip] instanceof IPackage) { // 入れ子のパッケージ構造を再帰処理 System.out.println(); IPackage iChildPackage = (IPackage)ine[ip]; checkStateTransitions(iChildPackage); } } } private static void printAllStateTransitions(IStateMachineDiagram ismd) { ITransition[] it = ismd.getStateMachine().getTransitions(); System.out.print(ismd.getName() + ":"); for (int i = 0; i < it.length; i++) { System.out.println(" " + it[i].getName()); } } }