シーケンス図のモデルの操作の概要
エクステンションではAPIでシーケンス図の各要素へアクセスすることが可能です。
シーケンス図の要素
No. | 要素名 | 説明 |
---|---|---|
1 | ライフラ イン | オブジェクトの生存期間を表すライフラインです。 |
2 | メッセージ | オブジェクト間のメッセージを表します。 |
3 | 実行仕様 | オブジェクトが活性化する区間を表します。 |
4 | 複合フラグメント | 条件によってメッセージのシーケンスを制御する区間を表します。 |
5 | 相互作用の利用 | メッセージのシーケンスの詳細を別のシーケンス図に分割する区間を表します。 |
6 | ノート | コメントを表します。 |
Next Designのシーケンス図は、他のエディタと同様に表現方法を表すシェイプと表現内容を表すモデルで構成しています。したがって、他のエディタ要素と同様に、シーケンス図の各要素のModel
プロパティでモデル情報にアクセスすることができます。ただし、モデルの変更へのビューの 追従はサポートしていませんのでご注意ください。シーケンス図のモデル情報でシーケンス図の構成に関わるフィールド値を変更した場合、シーケンス図が開けなくなります。
ライフラインを取得する
ライフラインを取得するにはISequenceDiagram
オブジェクトのLifelines
プロパティを用います。
public void GetLifelines(ICommandContext c, ICommandParams p)
{
ISequenceDiagram sequenceDiagram = c.App.Workspace.CurrentEditor as ISequenceDiagram;
if (sequenceDiagram == null) return;
// ライフラインを取得します
ILifelineShapeCollection lifelines = sequenceDiagram.Lifelines;
var no = 1;
foreach (ILifelineShape lifeline in lifelines)
{
c.App.Output.WriteLine("sample", $"{no}つ目のライフライン : {lifeline.Text}");
no++;
}
}
実行仕様を取得する
ライフラインが持つ実行仕様を取得するにはILifelineShape
オブジェクトのExecutionSpecifications
プロパティを用います。
public void GetExecutionSpecifications(ICommandContext c, ICommandParams p)
{
ISequenceDiagram sequenceDiagram = c.App.Workspace.CurrentEditor as ISequenceDiagram;
if (sequenceDiagram == null) return;
// 選択されたライフラインが持つ実行仕様を取得します
ILifelineShape lifeline = sequenceDiagram.GetSelectedShapes().FirstOrDefault() as ILifelineShape;
IExecutionSpecificationShapeCollection executionSpecifications = lifeline.ExecutionSpecifications;
c.App.Output.WriteLine("sample", $"ライフライン : {lifeline.Text} が持つ実行仕様は{executionSpecifications.Count()}つ");
}
ISequenceDiagram
オブジェクトのExecutionSpecifications
プロパティを用いることで、シーケンス図上のすべての実行仕様を取得することもできます。
public void GetAllExecutionSpecifications(ICommandContext c, ICommandParams p)
{
ISequenceDiagram sequenceDiagram = c.App.Workspace.CurrentEditor as ISequenceDiagram;
if (sequenceDiagram == null) return;
// 実行仕様を取得します
IExecutionSpecificationShapeCollection executionSpecifications = sequenceDiagram.ExecutionSpecifications;
foreach (IExecutionSpecificationShape executionSpecification in executionSpecifications)
{
// Lifelineプロパティで実行仕様を保持するライフラインにアクセスできます。
ILifelineShape lifeline = executionSpecification.Lifeline;
// Activatorプロパティで実行仕様を活性化するメッセージにアクセスできます。
IMessageShape activator = executionSpecification.Activator;
c.App.Output.WriteLine("sample", $"{lifeline.Text}は{activator.Text}により活性化します。");
}
}
メッセージを取得する
ライフラインからの送信・受信メッセージを取得するにはILifelineShape
オブジェクトのExecutionSpecifications
プロパティにアクセスし、実行仕様を取得します。さらに、IExecutionSpecificationShape
オブジェクトのSendMessages
、ReceiveMessages
プロパティを用いてメッセージを取得します。
public void GetMessages(ICommandContext c, ICommandParams p)
{
ISequenceDiagram sequenceDiagram = c.App.Workspace.CurrentEditor as ISequenceDiagram;
if (sequenceDiagram == null) return;
// 選択されたライフラインが持つ実行仕様から送信・受信メッセージを取得します
ILifelineShape lifeline = sequenceDiagram.GetSelectedShapes().FirstOrDefault() as ILifelineShape;
var sendMessages = lifeline.ExecutionSpecifications.SelectMany(ec => ec.SendMessages);
var receiveMessages = lifeline.ExecutionSpecifications.SelectMany(ec => ec.ReceiveMessages);
c.App.Output.WriteLine("sample", $"ライフライン : {lifeline.Text} の送信メッセージは{sendMessages.Count()}つ");
c.App.Output.WriteLine("sample", $"ライフライン : {lifeline.Text} の受信メッセージは{receiveMessages.Count()}つ");
}
ISequenceDiagram
オブジェクトのMessages
プロパティを用いることで、シーケンス図上のすべてのメッセージを取得することもできます。
public void GetAllMessages(ICommandContext c, ICommandParams p)
{
ISequenceDiagram sequenceDiagram = c.App.Workspace.CurrentEditor as ISequenceDiagram;
if (sequenceDiagram == null) return;
// メッセージを取得します
IMessageShapeCollection messages = sequenceDiagram.Messages;
foreach (IMessageShape message in messages)
{
// Senderプロパティ、Receiverプロパティで、それぞれ送信元、受信先のライフラインにアクセスできます。
// これらのプロパティは、送信元、受信先がライフラインでない場合は null を返します。
ILifelineShape sender = message.Sender;
ILifelineShape receiver = message.Receiver;
var senderName = sender != null ? sender.Text : "不明";
var receiverName = receiver != null ? receiver.Text : "不明";
c.App.Output.WriteLine("sample", $"{message.Text}は、{senderName}から{receiverName}のメッセージです。");
}
}
IMessageShape
オブジェクトからメッセージのモデルにアクセスすることでメッセージの種類や前後関係を調べることができます。メッセージのモデルは、IMessageShape
オブジェクトのModel
プロパティをIMessage
型にキャストします。
メッセージの種類を調べる
IMessage
オブジェクトのKind
プロパティでメッセージの種類を識別できます。
Kindプロパティの値 | 種類 |
---|---|
sync | 同期メッセージ |
async | 非同期メッセージ |
create | 生成メッセージ |
destroy | 破棄メッセージ |
reply | 応答メッセージ |
メッセージの前後関係を調べる
IMessage
オブジェクトのBefore
プロパティで、先行メッセージ(メッセージと送信元が同じ直前に送信されるメッセージ)を取得できます。また、IMessage
オブジェクトのAfter
プロパティで、後行メッセージ(メッセージと送信元が同じ直後に送信されるメッセージ)を取得できます。
先行メッセージ、および後行メッセージには応答メッセージは含まれません。また評価対象のメッセージが応答メッセージであった場合は、先行メッセージ、後行メッセージともに null となります。
同一のライフラインから送信するメッセージであっても、実行仕様が異なる送信メッセージは先行メッセージ、後行メッセージとはなりません。
public void GetMessageInfo(ICommandContext c, ICommandParams p)
{
ISequenceDiagram sequenceDiagram = c.App.Workspace.CurrentEditor as ISequenceDiagram;
if (sequenceDiagram == null) return;
// 選択されたメッセージを取得します
IMessageShape messageShape = sequenceDiagram.GetSelectedShapes().FirstOrDefault() as IMessageShape;
IMessage message = (IMessage)messageShape.Model;
c.App.Output.WriteLine("sample", $"{messageShape.Text}の種類は{message.Kind}です。");
// 先行メッセージ、後行メッセージのシェイプを取得します
IMessageShape beforeMessageShape = GetMessageShape(sequenceDiagram, message.Before);
IMessageShape afterMessageShape = GetMessageShape(sequenceDiagram, message.After);
if (beforeMessageShape != null)
{
c.App.Output.WriteLine("sample", $"{messageShape.Text}の先行メッセージは{beforeMessageShape.Text}です。");
}
if (afterMessageShape != null)
{
c.App.Output.WriteLine("sample", $"{messageShape.Text}の後行メッセージは{afterMessageShape.Text}です。");
}
}
private IMessageShape GetMessageShape(ISequenceDiagram sequenceDiagram, IMessage message)
{
if (message == null) return null;
return sequenceDiagram.Messages.FirstOrDefault(m => m.Model.Equals(message));
}
複合フラグメントを取得する
複合フラグメントを取得するにはISequenceDiagram
オブジェクトのFragments
プロパティを用います。
public void GetFragments(ICommandContext c, ICommandParams p)
{
ISequenceDiagram sequenceDiagram = c.App.Workspace.CurrentEditor as ISequenceDiagram;
if (sequenceDiagram == null) return;
// 複合フラグメントを取得します
IFragmentShapeCollection fragments = sequenceDiagram.Fragments;
var no = 1;
foreach (IFragmentShape fragment in fragments)
{
c.App.Output.WriteLine("sample", $"{no}つ目の複合フラグメント : {fragment.Text}");
no++;
}
}
IFragmentShape
オブジェクトのOperands
プロパティを用いて、オペランドにアクセスすることもできます。オペランドでは、ガード条件やオペランドの区画内に含まれるメッセージを確認することができます。
public void GetFragmentInfo(ICommandContext c, ICommandParams p)
{
ISequenceDiagram sequenceDiagram = c.App.Workspace.CurrentEditor as ISequenceDiagram;
if (sequenceDiagram == null) return;
// 選択された複合フラグメントを取得します
IFragmentShape fragment = sequenceDiagram.GetSelectedShapes().FirstOrDefault() as IFragmentShape;
var no = 1;
foreach (IOperandShape operand in fragment.Operands)
{
c.App.Output.WriteLine("sample", $"オペランド[{no}]:{operand.Guard}");
// オペランドの区画内に含まれるメッセージを取得
foreach (IMessageShape message in operand.Messages)
{
c.App.Output.WriteLine("sample", $"-- {message.Text}");
}
no++;
}
}
相互作用の利用を取得する
相互作用の利用を取得するにはISequenceDiagram
オブジェクトのInteractionUses
プロパティを用います。
public void GetInteractionUses(ICommandContext c, ICommandParams p)
{
ISequenceDiagram sequenceDiagram = c.App.Workspace.CurrentEditor as ISequenceDiagram;
if (sequenceDiagram == null) return;
// 相互作用の利用を取得します
IInteractionUseShapeCollection interactionUses = sequenceDiagram.InteractionUses;
var no = 1;
foreach (IInteractionUseShape interactionUse in interactionUses)
{
c.App.Output.WriteLine("sample", $"{no}つ目の相互作用の利用 : {interactionUse.Text}");
no++;
}
}