-
Notifications
You must be signed in to change notification settings - Fork 528
/
Copy pathsequencediagram.go
110 lines (98 loc) · 2.31 KB
/
sequencediagram.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
package d2graph
import (
"oss.terrastruct.com/d2/d2target"
)
func (obj *Object) IsSequenceDiagram() bool {
return obj != nil && obj.Shape.Value == d2target.ShapeSequenceDiagram
}
func (obj *Object) OuterSequenceDiagram() *Object {
for obj != nil {
obj = obj.Parent
if obj.IsSequenceDiagram() {
return obj
}
}
return nil
}
// groups are objects in sequence diagrams that have no messages connected
// and does not have a note as a child (a note can appear within a group, but it's a child of an actor)
func (obj *Object) IsSequenceDiagramGroup() bool {
if obj.OuterSequenceDiagram() == nil {
return false
}
for _, e := range obj.Graph.Edges {
if e.Src == obj || e.Dst == obj {
return false
}
}
for _, ch := range obj.ChildrenArray {
// if the child contains a message, it's a span, not a note
if !ch.ContainsAnyEdge(obj.Graph.Edges) {
return false
}
}
return obj.ContainsAnyObject(obj.Graph.Objects) || obj.ContainsAnyEdge(obj.Graph.Edges)
}
// notes are descendant of actors with no edges and no children
func (obj *Object) IsSequenceDiagramNote() bool {
if obj.OuterSequenceDiagram() == nil {
return false
}
return !obj.hasEdgeRef() && !obj.ContainsAnyEdge(obj.Graph.Edges) && len(obj.ChildrenArray) == 0 && !obj.ContainsAnyObject(obj.Graph.Objects)
}
func (obj *Object) hasEdgeRef() bool {
for _, ref := range obj.References {
if ref.MapKey != nil && len(ref.MapKey.Edges) > 0 {
return true
}
}
return false
}
func (obj *Object) ContainsAnyObject(objects []*Object) bool {
for _, o := range objects {
if o.ContainedBy(obj) {
return true
}
}
return false
}
func (o *Object) ContainedBy(obj *Object) bool {
for _, ref := range o.References {
curr := ref.ScopeObj
for curr != nil {
if curr == obj {
return true
}
curr = curr.Parent
}
}
return false
}
func (obj *Object) ContainsAnyEdge(edges []*Edge) bool {
for _, e := range edges {
if e.ContainedBy(obj) {
return true
}
}
return false
}
func (e *Edge) ContainedBy(obj *Object) bool {
for _, ref := range e.References {
curr := ref.ScopeObj
for curr != nil {
if curr == obj {
return true
}
curr = curr.Parent
}
}
return false
}
func (e *Edge) GetGroup() *Object {
for _, ref := range e.References {
if ref.ScopeObj.IsSequenceDiagramGroup() {
return ref.ScopeObj
}
}
return nil
}