STAMP/STPA

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

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

public IFacet getSTAMPFacet(ProjectAccessor projectAccessor) throws ProjectNotFoundException {
    return projectAccessor.getFacet(IStampFacet.FACET_SYMBOLIC_NAME);
}

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

モデルの参照

コンポーネントのコントロールアクションを取得する

astah*上で下図のようなコントロールストラクチャー図があり、Component0から各コントロールアクションを取得するとします。

common_view_diagram_editor

この場合、astah*のプロジェクト内のモデルは下図のようになります。
コンポーネントから直接取得することができないため、コントロールアクションを保持するコントロールリンクを取得してから関連するコンポーネントを判断する必要があることがわかります。

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

common_diagram_showing_class_structure

または、インスタンスは下図のようになります。 common_instance_diagram

StpaAnalysisからコントロールリンク(IStpaAnalysis#getLinks()で取得できます。
コントロールリンクからコントロールアクションはIControlLink#getActions()で取得できます。

public List<IControlAction> getControlActions(IComponent component) throws ClassNotFoundException {
    List<IControlAction> controlActions = new ArrayList<>();
    IFacet facet =  AstahAPI.getAstahAPI().getProjectAccessor().getFacet(IStampFacet.FACET_SYMBOLIC_NAME);
    IStpaAnalysis analysis = facet.getRootElement(IStpaAnalysis.class);
    List<ILink> links = analysis.getLinks();
    for (ILink link : links) {
        if (link instanceof IControlLink
                && (link.getSource() == component || link.getTarget() == component)) {
            controlActions.addAll(((IControlLink) link).getActions());
        }
    }
    return controlActions;
}

UCAのコントロールアクションの提供条件を取得する

IUnsafeControlAction.getControlActionからUCAのコントロールアクションを取得できます。IControlActionISignalを継承しており、ISignal.getProvidingConditionから提供条件を取得できます。

public String getProvidingCondition(IUnsafeControlAction uca) {
    return uca.getControlAction().getProvidingCondition();
}

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

コントロールストラクチャー図を取得する

public List<IControlStructureDiagram> getControlStructureDiagrams(IFacet facet) {
    IStpaAnalysis analysis = facet.getRootElement(IStpaAnalysis.class);
    List<IControlStructureDiagram> controlStructureDiagrams = new ArrayList<>();
    for (IDiagram diagram : analysis.getDiagrams()) {
        if (diagram instanceof IControlStructureDiagram) {
            controlStructureDiagrams.add((IControlStructureDiagram) diagram);
        }
    }
    return controlStructureDiagrams;
}

コントロールストラクチャー図に同期するUCA表を取得する

StampDiagramEditorからコントロールストラクチャー図に同期するUCA表を取得し、存在しない場合は作成できます。

public IUCATable createOrGetUCATable(IControlStructureDiagram controlStructureDiagram, String ucaTableName) 
throws ClassNotFoundException, InvalidUsingException, InvalidEditingException {
    IDiagramEditorFactory diagramEditorFactory = AstahAPI.getAstahAPI().getProjectAccessor().getDiagramEditorFactory();
    StampDiagramEditor stampDiagramEditor = diagramEditorFactory.getDiagramEditor(StampDiagramEditor.class);
    return stampDiagramEditor.createOrGetUCATable(controlStructureDiagram, ucaTableName);
}

図上で選択しているコンポーネントにネストするコンポーネントプレゼンテーションを取得する

astah*上で下図のようなコントロールストラクチャー図があり、parent componentからネストコンポーネントのプレゼンテーションを取得するとします。 common_view_diagram_editor

INodePresentation.getChildrenからコンポーネントプレゼンテーションにネストするコンポーネントプレゼンテーションを取得できます。

public INodePresentation[] getChildrenComponentPresentation(
        IControlStructureDiagram controlStructureDiagram) throws InvalidUsingException {
    for (IPresentation presentation : controlStructureDiagram.getPresentations()) {
        IElement model = presentation.getModel();
        if (presentation instanceof INodePresentation && model instanceof IComponent
                && "parent component".equals(((IComponent) model).getName())) {
            return ((INodePresentation) presentation).getChildren();
        }
    }
    return new INodePresentation[0];
}

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

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

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

モデルの編集

モデルエディタ

STAMP/STPA関連モデルの編集はモデルエディタ(StampModelEditor)を使用して行います。 例えば、コントロールアクションやアクシデントの作成はStampModelEditorから作成できます。 モデルとプレゼンテーションが1:nで対応するモデルはモデルエディタから作成できます。

モデルエディタの取得

モデルエディタの種類 作成可能要素
StampModelEditor コンポーネント、コントロールアクション、コントロールリンク、フィードバックリンク、フィードバック、プロセスモデル、プロセス変数、プロセスバリュー、前提条件、アクシデント、ハザード、安全制約、UCA、非UCA、HazardCausalFactor、ハザードシナリオ

アクシデントに安全制約を持つハザードを追加する

// 要トランザクション処理
public IHazard createHazard(IAccident accident, String hazardDescription) throws InvalidEditingException {
    IModelEditorFactory modelEditorFactory =  projectAccessor.getModelEditorFactory();
    StampModelEditor stampModelEditor = modelEditorFactory.getModelEditor(StampModelEditor.class);
    IFacet facet = projectAccessor.getFacet(IStampFacet.FACET_SYMBOLIC_NAME);
    IStpaAnalysis analysis = facet.getRootElement(IStpaAnalysis.class);

    IHazard hazard = stampModelEditor.createHazard(analysis,
            Collections.singletonList(accident), hazardDescription);
    ISafetyConstraint safetyConstraint1 = stampModelEditor.createSafetyConstraint(analysis,
            Collections.singletonList(hazard), "safetyConstraint1");
    ISafetyConstraint safetyConstraint2 = stampModelEditor.createSafetyConstraint(analysis,
            Collections.singletonList(hazard), "safetyConstraint2");
    return hazard;
}

コントロールアクションにUCAを追加する

astah*上で下図のようなUCA表があり、コントロールストラクチャー図上のコントロールアクション(ControlAction)とNot Providing(ガイドワード)で指定したセルにUCA1を追加するとします。

common_view_diagram_editor

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

// 要トランザクション処理
    public IUnsafeControlAction createUCA(IStpaAnalysis analysis) throws ClassNotFoundException, InvalidEditingException {
        final ITransactionManager transactionManager = projectAccessor.getTransactionManager();
        IUnsafeControlAction uca = null;
        try {
            // コントロールストラクチャー図を作成
            transactionManager.beginTransaction();
            IModelEditorFactory modelEditorFactory =  AstahAPI.getAstahAPI().getProjectAccessor().getModelEditorFactory();
            StampDiagramEditor stampDiagramEditor = modelEditorFactory.getModelEditor(StampDiagramEditor.class);
            IControlStructureDiagram controlStructureDiagram = stampDiagramEditor.createControlStructureDiagram(analysis, "controlStructureDiagram");
    
            StampModelEditor stampModelEditor = modelEditorFactory.getModelEditor(StampModelEditor.class);
            IComponent component1 = stampModelEditor.createComponent(analysis, "component1");
            IComponent component2 = stampModelEditor.createComponent(analysis, "component2");
            IControlLink controlLink = stampModelEditor.createControlLink(component1, component2);
            IControlAction controlAction = stampModelEditor.createControlAction(controlLink, "controlAction");
            INodePresentation component1Presentation = stampDiagramEditor.createNodePresentation(component1, createPoint2D(100.0, 100.0));
            INodePresentation component2Presentation = stampDiagramEditor.createNodePresentation(component2, createPoint2D(250.0, 250.0));
            ILinkPresentation controlLinkPresentation = stampDiagramEditor.createLinkPresentation(controlLink, component1Presentation, component2Presentation);
            transactionManager.endTransaction();

            // UCA表を作成
            transactionManager.beginTransaction();
            IUCATable ucaTable = stampDiagramEditor.createOrGetUCATable(controlStructureDiagram, "ucaTable");
            INamedElement guideword0 = analysis.getUCAGuideWords().get(0);
            uca = stampModelEditor.createUnsafeControlAction(controlAction, guideword0, "UCA1");
            uca.setIdentifier("UCA1-N-1");
            transactionManager.endTransaction();

            // UCA表のセルの設定
            transactionManager.beginTransaction();
            ucaTable.setCell(controlAction, guideword0, Collections.singletonList(uca));
            transactionManager.endTransaction();
        } catch (BadTransactionException e) {
            transactionManager.abortTransaction();
        }
        return uca;
    }

private Point2D createPoint2D(double x, double y) {
    Point2D location = new Point2D.Double();
     location.setLocation(x, y);
     return location;
}

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

ダイアグラムエディタ

図、表、プレゼンテーションの作成や削除はStampDiagramEditorを使用して行います。
StampDiagramEditorを以下のように取得できます。

    ProjectAccessor projectAccessor = AstahAPI.getAstahAPI().getProjectAccessor();
    IDiagramEditorFactory diagramEditorFactory = projectAccessor.getDiagramEditorFactory();
    StampDiagramEditor diagramEditor = diagramEditorFactory.getDiagramEditor(StampDiagramEditor.class);

コントロールループ図を作成する

// 要トランザクション処理
public IControlLoopDiagram createControlLoopDiagram(ILinkPresentation controlLinkPresentation)
throws ClassNotFoundException, InvalidUsingException, InvalidEditingException {
    ProjectAccessor projectAccessor = AstahAPI.getAstahAPI().getProjectAccessor();
    IDiagramEditorFactory diagramEditorFactory = projectAccessor.getDiagramEditorFactory();
    StampDiagramEditor diagramEditor = diagramEditorFactory.getDiagramEditor(StampDiagramEditor.class);
    IControlLoopDiagram diagram = diagramEditor.createControlLoopDiagram(controlLinkPresentation, "test");
    return diagram;
}

ネストのコンポーネントプレゼンテーションを作成する

// 要トランザクション処理
public INodePresentation createNestedNodePresentation(StampDiagramEditor editor, IComponent parent, IComponent child,
            Point2D location) throws InvalidEditingException {
    INodePresentation parentNodePresentation = createNodePresentation(editor, parent, location);
    return editor.createNodePresentation(child, parentNodePresentation,  location);
}

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

ロスシナリオ表を作成する

// 要トランザクション処理
public ILossScenarioTable createLossScenarioTable(IUnsafeControlAction uca)
        throws ClassNotFoundException, InvalidUsingException, InvalidEditingException {
    ProjectAccessor projectAccessor = AstahAPI.getAstahAPI().getProjectAccessor();
    IDiagramEditorFactory diagramEditorFactory = projectAccessor.getDiagramEditorFactory();
    StampDiagramEditor diagramEditor = diagramEditorFactory.getDiagramEditor(StampDiagramEditor.class);
    ILossScenarioTable table = diagramEditor.createOrGetLossScenarioTable(uca, "lossScenarioTable");
    return table;
}

表を削除する

// 要トランザクション処理
public void deleteUCATable(IUnsafeControlAction uca, IControlStructureDiagram controlStructureDiagram)
        throws ClassNotFoundException, InvalidUsingException, InvalidEditingException {
    ProjectAccessor projectAccessor = AstahAPI.getAstahAPI().getProjectAccessor();
    IDiagramEditorFactory diagramEditorFactory = projectAccessor.getDiagramEditorFactory();
    StampDiagramEditor diagramEditor = diagramEditorFactory.getDiagramEditor(StampDiagramEditor.class);
    IUCATable ucatable = diagramEditor.createOrGetUCATable(controlStructureDiagram, "ucaTable0");
    if (ucatable != null) {
        diagramEditor.delete(ucatable);
    }
}

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

構造の詳細については、JavadocSTAMP/STPA Overviewをご覧ください。

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

STAMP/STPA各図のモデルに対する対応の概要です。
モデルへの参照・編集の可否についてはStampModelEditorをご覧ください。 各図の作成についてはStampDiagramEditorをご覧ください。

関連モデル構造 各モデルの参照 各モデルの編集
コントロールループ図 IControlLoopDiagram コントロールループ図
コントロールストラクチャー図 IControlStructureDiagram コントロールストラクチャー図
前提条件表 IPreconditionTable 前提条件表
アクシデントハザード安全制約表 IAccidentHazardSafetyConstraintTable アクシデントハザード安全制約表
UCA表 IUCATable UCA表
ロスシナリオ表 ILossScenarioTable ロスシナリオ表
対策表 ICountermeasureTable 対策表

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

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

DiagramEditor INodePresentation ILinkPresentation
コントロールループ図 IControlLoopDiagram StampDiagramEditor
コントロールストラクチャー図 IControlStructureDiagram StampDiagramEditor