SysML

SysMLファセットへアクセスする

SysMLの全モデル、プレゼンテーションは、SysMLファセットを表すモデル(以下、ファセットモデル)の下に存在します。
SysMLファセットモデルは、ProjectAccessorからgetFacet(String symbolicName)を用いて取得します。

public IFacet getProjectSysMLFacet(ProjectAccessor projectAccessor) throws ProjectNotFoundException {
    return projectAccessor.getFacet(ISysmlFacet.FACET_SYMBOLIC_NAME);
}

モデル / プレゼンテーションの参照

モデルの参照

ブロックから関連を取得する

astah*上で下図のようなブロック定義図があり、Block0から関連を取得するとします。

common_view_diagram_editor

この場合、astah*のプロジェクト内のモデルは下図のようになります。
ブロックから直接取得することができないため、関連端を取得してから関連のモデルを取得する必要があることがわかります。

common_instance_diagram

また、対応するastah* APIの構造は下図のようになります。

common_diagram_showing_class_structure

ブロックから関連端はIBlock#getReferences()で取得できます。
関連端から関連はIAttribute#getAssociation()で取得できます(属性からIAttribute#getAssociation()した場合はnullが返ります)。

public List<IAssociation> getAssociations(IBlock block) {
    List<IAssociation> associations = new ArrayList<>();
    IAttribute[] attributes = block.getReferences();
    for (IAttribute attribute : attributes) {
        IAssociation association = attribute.getAssociation();
        if (association == null) {
            continue;
        }
        associations.add(association);
    }
    return associations;
}

ブロックから依存を取得する

astah*上で下図のようなブロック定義図があり、Block0から依存を取得するとします。

common_view_diagram_editor

この場合、astah*のプロジェクト内のモデルは下図のようになります。

common_instance_diagram

また、対応するastah* APIの構造は下図のようになります。
INamedElementIBlockの親クラスです。

common_diagram_showing_class_structure

Block0から依存は、INamedElement#getClientDependencies()を用いることで取得することができます。
Block1からはINamedElement#getSupplierDependencies()で取得できます。

パッケージ配下のパッケージを再帰的に取得する

パッケージ(IPackage)を継承するモデルとパッケージに含めます。

public List<IPackage> getPackages(IPackage pkg, List<IPackage> packages) {
    INamedElement[] namedElements = pkg.getOwnedElements();
    for (INamedElement namedElement : namedElements) {
       if (namedElement instanceof IPackage) {
           packages.add((IPackage)namedElement);
           getPackages((IPackage)namedElement, packages);
       }
     }
     return packages;
}

パッケージ配下のブロックを取得する

パッケージ(IPackage)配下にある全モデル要素を取得し、クラスを抽出します。

public List<IBlock> getIBlocks(IPackage pkg) {
    List<IBlock> blocks = new ArrayList<>();
    INamedElement[] namedElements = pkg.getOwnedElements();
    for (INamedElement namedElement : namedElements) {
       if (namedElement instanceof IBlock) {
           blocks.add((IBlock)namedElement);
       }
    }
    return blocks;
}

ブロックのネームスペースを取得する

ブロック(IBlock)等INamedElementのサブクラスの場合、メソッドgetFullName(String)を用いることでその限定名を取得できます。

public String getFullName(IBlock block) {
    return block.getFullName("::");
}

INamedElementのサブクラスの場合、メソッドgetName()と自らを所有するモデル要素を取得するメソッドgetOwner()を使用することによって、 プロジェクトモデルからのネームスペースを再帰的に取得もできます。

public String getFullName(IBlock block) {
    IElement owner = block.getOwner();
    StringJoiner sj = new StringJoiner("::");
    while (owner != null && owner instanceof INamedElement && owner.getOwner() != null) {
        sj.add(((INamedElement) owner).getName());
        owner = owner.getOwner();
    }
    sj.add(block.getName());
    return sj.toString();
}

アクティビティ図のモデルを取得する

アクティビティ図のモデル構造を示します。下記を参考にしてモデルを取得して下さい。

astah*上で下図のようなアクティビティ図がある場合、

common_view_diagram_editor

astah*プロジェクト内のモデルは下図のようになります。
上図には表示されていませんが、Partition0のsuperPartitionにディメンジョンが存在することに注意して下さい。

common_instance_diagram

また、対応するastah* APIの構造は下図のようになります。

common_diagram_showing_class_structure

シーケンス図のモデルを取得する

シーケンス図のモデル構造を示します。下記を参考にしてモデルを取得して下さい。

astah*上で下図のようなシーケンス図がある場合、

common_view_diagram_editor

astah*のプロジェクト内のモデルは下図のようになります。

common_instance_diagram

また、対応するastah* APIの構造は下図のようになります。

common_diagram_showing_class_structure

ステートマシン図のモデルを取得する

ステートマシン図のモデル構造を示します。下記を参考にしてモデルを取得して下さい。

astah*上で下図のようなステートマシン図がある場合、

common_view_diagram_editor

astah*のプロジェクト内のモデルは下図のようになります。

common_instance_diagram

また、対応するastah* APIの構造は下図のようになります。

common_diagram_showing_class_structure

state0から領域にかかわらず全子要素を取得するにはIState#getSubvertexes()、state0の各領域から子要素を取得するにはIState#getSubvertexes(int regionIndex)を用います。

図 / プレゼンテーションの参照

内部ブロック図を取得する

public List<IInternalBlockDiagram> getInternalBlockDiagrams(IBlock block) {
    List<IInternalBlockDiagram> internalBlockDiagrams = new ArrayList<>();
    IDiagram[] diagrams = block.getDiagrams();
    for (IDiagram diagram : diagrams) {
        if (diagram instanceof IInternalBlockDiagram) {
            internalBlockDiagrams.add((IInternalBlockDiagram) diagram);
        }
    }
    return internalBlockDiagrams;
}

内部ブロック図上のパートプロパティを取得する

public List<INodePresentation> getPartProperty(IDiagram diagram) throws InvalidUsingException {
    List<INodePresentation> partPropertyPresentations = new ArrayList<>();
    if (diagram instanceof IInternalBlockDiagram) {
        INodePresentation[] childrenPresentations = ((IInternalBlockDiagram) diagram)
                .getStructuredBlockPresentation().getChildren();
        for (INodePresentation nodePresentation : childrenPresentations) {
            IElement model = nodePresentation.getModel();
            if (model instanceof IAttribute && ((IAttribute) model).isComposite()) {
                partPropertyPresentations.add(nodePresentation);
            }
        }
    }
    return partPropertyPresentations;
}

モデル / プレゼンテーションの編集

編集を行う場合は必ずトランザクション処理が必要となります。
なお、下記条件を満たしていない場合は例外が発生します。

  • プロジェクトアクセサにプロジェクトを登録していること
  • 編集APIが対応しているエディションであること
  • 対象が編集可能であること

モデルの編集

モデルエディタ

SysML関連モデルの編集はモデルエディタ(SysmlModelEditor)を使用して行います。 例えば、要求モデルの作成はSysmlModelEditorから作成できます。 モデルとプレゼンテーションが1:nで対応するモデルは各種モデルエディタから作成できます。

モデルエディタの取得

モデルエディタの種類 作成可能要素
SysMLModelEditor ブロック、インターフェースブロック、制約ブロック、制約パラメータ、バリュータイプ、ユニット、量単位、フロープロパティなどの各種プロパティ、アイテムフロー、各種ポート、要求、テストケース、パート、バイディングコネクタ、関連

ブロックにフロープロパティを作成する

// 要トランザクション処理
public IFlowProperty createFlowProperty(ProjectAccessor projectAccessor)
        throws InvalidEditingException, ProjectNotFoundException {
    IModelEditorFactory modelEditorFactory = projectAccessor.getModelEditorFactory();
    SysmlModelEditor sysmlModelEditor = modelEditorFactory.getSysmlModelEditor();
    IModel projectModel = projectAccessor.getProject();
    IBlock parent = sysmlModelEditor.createBlock(projectModel, "parentBlock");
    IBlock type = sysmlModelEditor.createBlock(projectModel, "typeBlock");
    return sysmlModelEditor.createFlowProperty(parent, "Flow Property", type);
}

要求を作成する

// 要トランザクション処理
public IRequirement createRequirement(ProjectAccessor projectAccessor)
        throws InvalidEditingException, ProjectNotFoundException {
    IModelEditorFactory modelEditorFactory = projectAccessor.getModelEditorFactory();
    SysmlModelEditor sysmlModelEditor = modelEditorFactory.getSysmlModelEditor();
    IModel model = projectAccessor.getProject();
    IRequirement requirement = sysmlModelEditor.createRequirement(model, "requirement");
    requirement.setRequirementID("id");
    return requirement;
}

プレゼンテーションの編集

ダイアグラムエディタ

図およびプレゼンテーションの作成や削除はダイアグラムエディタを使用して行います。

ダイアグラムエディタの種類 編集可能図
BlockDefinitionDiagramEditor ブロック定義図
InternalBlockDiagramEditor 内部ブロック図
ParametricDiagramEditor パラメトリック図
UseCaseDiagramEditor ユースケース図
StateMachineDiagramEditor ステートマシン図
ActivityDiagramEditor アクティビティ図
SequenceDiagramEditor シーケンス図
RequirementDiagramEditor 要求図
MindmapEditor マインドマップ

要求図を作成する

// 要トランザクション処理
public IRequirementDiagram createRequirementDiagram(RequirementDiagramEditor editor, INamedElement owner,
        String name) throws InvalidEditingException {
    return editor.createRequirementDiagram(owner, name);
}

要求プレゼンテーションを作成する

// 要トランザクション処理
public INodePresentation createRequirementPresentation(RequirementDiagramEditor editor, IRequirement model,
        Point2D location) throws InvalidEditingException {
    return createNodePresentation(editor, model, location);
}

// 要トランザクション処理
public INodePresentation createNodePresentation(RequirementDiagramEditor editor, IElement model,
        Point2D location) throws InvalidEditingException {
    return editor.createNodePresentation(model, location);
}

アクティビティ図のアクションを作成する

アクティビティ図のアクション等、モデルとプレゼンテーションの対応が1:1となる場合、プレゼンテーションを作成するとモデルも一緒に作成されます。

// 要トランザクション処理
public INodePresentation createActionPresentation(ActivityDiagramEditor editor, String name,
        Point2D location) throws InvalidEditingException {
    return editor.createAction(name, location);
}

対応モデル / プレゼンテーション一覧

astah* APIのクラス構造は、SysMLメタモデルの継承構造から実際にモデル要素としてインスタンス化されることのない抽象的なモデル要素の一部を省き、簡素化した構造になっています。SysMLメタモデルの構造とは異なる部分があることにご留意下さい。
構造についての詳細については、JavadocSysML Overviewをご覧ください。

モデル対応の概要 (図単位)

SysML各図のモデルに対する対応の概要です。
モデルへの参照・編集の可否についてはSysMLModelEditorをご覧ください。 各図の作成についてはBlockDefinitionDiagramEditorなど、各図のDiagramEditorsをご覧ください。

関連モデル構造 各モデルの参照 各モデルの編集
ブロック定義図 IBlockDefinitionDiagram ブロック定義図
内部ブロック図 IInternalBlockDiagram 内部ブロック図
パラメトリック図 IParametricDiagram パラメトリック図
要求図と要求表 IRequirementDiagram,IRequirementTable 要求図と要求表
ユースケース図 IUseCaseDiagram ユースケース図
アクティビティ図 IActivityDiagram アクティビティ図
シーケンス図 ISequenceDiagram シーケンス図
ステートマシン図 IStateMachineDiagram ステートマシン図

対応プレゼンテーションの概要 (図単位)

SysML各図のモデルに対応するプレゼンテーションの概要です。
プレゼンテーションへの参照・編集の可否についてはBlockDefinitionDiagramEditorなど、各図のDiagramEditorsをご覧ください。

DiagramEditor INodePresentation ILinkPresentation
ブロック定義図 BlockDefinitionDiagram BlockDefinitionDiagramEditor
内部ブロック図 IInternalBlockDiagram InternalBlockDiagramEditor
パラメトリック図 IParametricDiagram ParametricDiagramEditor
要求図と要求表 IRequirementDiagram,IRequirementTable RequirementDiagramEditor
ユースケース図 IUseCaseDiagram UseCaseDiagramEditor
アクティビティ図 IActivityDiagram ActivityDiagramEditor
シーケンス図 ISequenceDiagram SequenceDiagramEditor
ステートマシン図 IStateMachineDiagram StateMachineDiagramEditor

サンプル

実際に API を使用したサンプルコードです。

astah-sysml-api-sample