Skip to content

Commit d9a6f1c

Browse files
structurizr-dsl: Adds a reluctant version of include * (include *?) for system context, container, and component views.
1 parent e814937 commit d9a6f1c

File tree

13 files changed

+292
-11
lines changed

13 files changed

+292
-11
lines changed

changelog.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
- structurizr-dsl: Fixes https://github.com/structurizr/java/issues/374 (!identifiers hierarchical isn't propagated when extending a workspace).
66
- structurizr-dsl: Adds the ability to use the `group` keyword inside a component definition, to set the group name of that component.
77
- structurizr-dsl: Adds the ability to use the `group` keyword inside the component finder strategy `forEach` block.
8+
- structurizr-dsl: Adds a reluctant version of `include *` (`include *?`) for system context views that only adds relationships to/from the scoped software system.
9+
- structurizr-dsl: Adds a reluctant version of `include *` (`include *?`) for container views that only adds relationships to/from the containers in the scoped software system.
10+
- structurizr-dsl: Adds a reluctant version of `include *` (`include *?`) for component views that only adds relationships to/from the components in the scoped container.
811

912
## 3.2.1 (10th December 2024)
1013

structurizr-core/src/main/java/com/structurizr/view/ComponentView.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,15 @@ public String getName() {
156156
*/
157157
@Override
158158
public void addDefaultElements() {
159+
addDefaultElements(true);
160+
}
161+
162+
/**
163+
* Adds the default set of elements and relationships to this view.
164+
*
165+
* @param greedy true (add all relationships) or false (adds relationships to/from the components in the scoped container only)
166+
*/
167+
public void addDefaultElements(boolean greedy) {
159168
for (Component component : getContainer().getComponents()) {
160169
add(component);
161170

@@ -169,6 +178,10 @@ public void addDefaultElements() {
169178
addNearestNeighbours(component, Person.class);
170179
addNearestNeighbours(component, SoftwareSystem.class);
171180
}
181+
182+
if (!greedy) {
183+
removeRelationshipsNotConnectedToElements(getContainer().getComponents());
184+
}
172185
}
173186

174187
/**

structurizr-core/src/main/java/com/structurizr/view/ContainerView.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,12 +85,25 @@ public String getName() {
8585
*/
8686
@Override
8787
public void addDefaultElements() {
88+
addDefaultElements(true);
89+
}
90+
91+
/**
92+
* Adds the default set of elements and relationships to this view.
93+
*
94+
* @param greedy true (add all relationships) or false (adds relationships to/from the containers in the scoped software system only)
95+
*/
96+
public void addDefaultElements(boolean greedy) {
8897
for (Container container : getSoftwareSystem().getContainers()) {
8998
add(container);
9099
addNearestNeighbours(container, CustomElement.class);
91100
addNearestNeighbours(container, Person.class);
92101
addNearestNeighbours(container, SoftwareSystem.class);
93102
}
103+
104+
if (!greedy) {
105+
removeRelationshipsNotConnectedToElements(getSoftwareSystem().getContainers());
106+
}
94107
}
95108

96109
/**

structurizr-core/src/main/java/com/structurizr/view/ModelView.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,20 @@ public void removeRelationshipsNotConnectedToElement(Element element) {
302302
}
303303
}
304304

305+
/**
306+
* Removes relationships that are not connected to the specified elements.
307+
*
308+
* @param elements the Set of Element objects to test against
309+
*/
310+
public void removeRelationshipsNotConnectedToElements(Set<? extends Element> elements) {
311+
if (elements != null) {
312+
getRelationships().stream()
313+
.map(RelationshipView::getRelationship)
314+
.filter(r -> !elements.contains(r.getSource()) && !elements.contains(r.getDestination()))
315+
.forEach(this::remove);
316+
}
317+
}
318+
305319
/**
306320
* Gets the set of elements in this view.
307321
*

structurizr-core/src/main/java/com/structurizr/view/StaticView.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,17 @@ public abstract class StaticView extends ModelView implements AnimatedView {
2525
}
2626

2727
/**
28-
* Adds the default set of elements to this view.
28+
* Adds the default set of elements and relationships to this view.
2929
*/
3030
public abstract void addDefaultElements();
3131

32+
/**
33+
* Adds the default set of elements and relationships to this view.
34+
*
35+
* @param greedy true (add all relationships) or false (depends on view type)
36+
*/
37+
public abstract void addDefaultElements(boolean greedy);
38+
3239
/**
3340
* Adds all software systems in the model to this view.
3441
*/

structurizr-core/src/main/java/com/structurizr/view/SystemContextView.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,22 @@ public String getName() {
3939
*/
4040
@Override
4141
public void addDefaultElements() {
42+
addDefaultElements(true);
43+
}
44+
45+
/**
46+
* Adds the default set of elements and relationships to this view.
47+
*
48+
* @param greedy true (add all relationships) or false (adds relationships to/from the scoped software system only)
49+
*/
50+
public void addDefaultElements(boolean greedy) {
4251
addNearestNeighbours(getSoftwareSystem(), CustomElement.class);
4352
addNearestNeighbours(getSoftwareSystem(), Person.class);
4453
addNearestNeighbours(getSoftwareSystem(), SoftwareSystem.class);
54+
55+
if (!greedy) {
56+
removeRelationshipsNotConnectedToElement(getSoftwareSystem());
57+
}
4558
}
4659

4760
/**

structurizr-core/src/main/java/com/structurizr/view/SystemLandscapeView.java

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,15 +54,24 @@ void setModel(Model model) {
5454
*/
5555
@Override
5656
public void addDefaultElements() {
57+
addDefaultElements(true);
58+
}
59+
60+
/**
61+
* Adds the default set of elements and relationships to this view.
62+
*
63+
* @param greedy true (add all relationships) or false (add all relationships)
64+
*/
65+
public void addDefaultElements(boolean greedy) {
5766
addAllSoftwareSystems();
5867
addAllPeople();
5968

6069
getElements().stream().map(ElementView::getElement).forEach(e -> addNearestNeighbours(e, CustomElement.class));
6170
}
6271

6372
/**
64-
* Adds all software systems and all people to this view.
65-
*/
73+
* Adds all software systems and all people to this view.
74+
*/
6675
@Override
6776
public void addAllElements() {
6877
addAllSoftwareSystems();

structurizr-core/src/test/java/com/structurizr/view/ComponentViewTests.java

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -614,6 +614,70 @@ void addDefaultElements() {
614614
assertFalse(view.getElements().contains(new ElementView(component2)));
615615
}
616616

617+
@Test
618+
void addDefaultElements_WhenGreedyIsTrue() {
619+
model.setImpliedRelationshipsStrategy(new CreateImpliedRelationshipsUnlessAnyRelationshipExistsStrategy());
620+
621+
SoftwareSystem a = model.addSoftwareSystem("A");
622+
Container a1 = a.addContainer("A1", "", "");
623+
Component aa1 = a1.addComponent("AA1", "", "");
624+
Component aa2 = a1.addComponent("AA2", "", "");
625+
SoftwareSystem b = model.addSoftwareSystem("B");
626+
SoftwareSystem c = model.addSoftwareSystem("C");
627+
628+
aa1.uses(aa2, "Uses");
629+
aa1.uses(b, "Uses");
630+
aa2.uses(c, "Uses");
631+
b.uses(c, "Uses");
632+
633+
view = new ComponentView(a1, "components", "Description");
634+
view.addDefaultElements(true);
635+
636+
assertEquals(4, view.getElements().size());
637+
assertTrue(view.getElements().contains(new ElementView(aa1)));
638+
assertTrue(view.getElements().contains(new ElementView(aa2)));
639+
assertTrue(view.getElements().contains(new ElementView(b)));
640+
assertTrue(view.getElements().contains(new ElementView(c)));
641+
642+
assertEquals(4, view.getRelationships().size());
643+
assertNotNull(view.getRelationshipView(aa1.getEfferentRelationshipWith(aa2)));
644+
assertNotNull(view.getRelationshipView(aa1.getEfferentRelationshipWith(b)));
645+
assertNotNull(view.getRelationshipView(aa2.getEfferentRelationshipWith(c)));
646+
assertNotNull(view.getRelationshipView(b.getEfferentRelationshipWith(c)));
647+
}
648+
649+
@Test
650+
void addDefaultElements_WhenGreedyIsFalse() {
651+
model.setImpliedRelationshipsStrategy(new CreateImpliedRelationshipsUnlessAnyRelationshipExistsStrategy());
652+
653+
SoftwareSystem a = model.addSoftwareSystem("A");
654+
Container a1 = a.addContainer("A1", "", "");
655+
Component aa1 = a1.addComponent("AA1", "", "");
656+
Component aa2 = a1.addComponent("AA2", "", "");
657+
SoftwareSystem b = model.addSoftwareSystem("B");
658+
SoftwareSystem c = model.addSoftwareSystem("C");
659+
660+
aa1.uses(aa2, "Uses");
661+
aa1.uses(b, "Uses");
662+
aa2.uses(c, "Uses");
663+
b.uses(c, "Uses");
664+
665+
view = new ComponentView(a1, "components", "Description");
666+
view.addDefaultElements(false);
667+
668+
assertEquals(4, view.getElements().size());
669+
assertTrue(view.getElements().contains(new ElementView(aa1)));
670+
assertTrue(view.getElements().contains(new ElementView(aa2)));
671+
assertTrue(view.getElements().contains(new ElementView(b)));
672+
assertTrue(view.getElements().contains(new ElementView(c)));
673+
674+
assertEquals(3, view.getRelationships().size());
675+
assertNotNull(view.getRelationshipView(aa1.getEfferentRelationshipWith(aa2)));
676+
assertNotNull(view.getRelationshipView(aa1.getEfferentRelationshipWith(b)));
677+
assertNotNull(view.getRelationshipView(aa2.getEfferentRelationshipWith(c)));
678+
assertNull(view.getRelationshipView(b.getEfferentRelationshipWith(c)));
679+
}
680+
617681
@Test
618682
void addSoftwareSystem_ThrowsAnException_WhenTheSoftwareSystemIsTheScopeOfTheView() {
619683
SoftwareSystem softwareSystem = model.addSoftwareSystem("Software System");

structurizr-core/src/test/java/com/structurizr/view/ContainerViewTests.java

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,68 @@ void addDefaultElements() {
306306
assertFalse(view.getElements().contains(new ElementView(container2)));
307307
}
308308

309+
@Test
310+
void addDefaultElements_WhenGreedyIsTrue() {
311+
model.setImpliedRelationshipsStrategy(new CreateImpliedRelationshipsUnlessAnyRelationshipExistsStrategy());
312+
313+
SoftwareSystem a = model.addSoftwareSystem("A");
314+
Container a1 = a.addContainer("A1");
315+
Container a2 = a.addContainer("A2");
316+
SoftwareSystem b = model.addSoftwareSystem("B");
317+
SoftwareSystem c = model.addSoftwareSystem("C");
318+
319+
a1.uses(a2, "Uses");
320+
a1.uses(b, "Uses");
321+
a2.uses(c, "Uses");
322+
b.uses(c, "Uses");
323+
324+
view = new ContainerView(a, "containers", "Description");
325+
view.addDefaultElements(true);
326+
327+
assertEquals(4, view.getElements().size());
328+
assertTrue(view.getElements().contains(new ElementView(a1)));
329+
assertTrue(view.getElements().contains(new ElementView(a2)));
330+
assertTrue(view.getElements().contains(new ElementView(b)));
331+
assertTrue(view.getElements().contains(new ElementView(c)));
332+
333+
assertEquals(4, view.getRelationships().size());
334+
assertNotNull(view.getRelationshipView(a1.getEfferentRelationshipWith(a2)));
335+
assertNotNull(view.getRelationshipView(a1.getEfferentRelationshipWith(b)));
336+
assertNotNull(view.getRelationshipView(a2.getEfferentRelationshipWith(c)));
337+
assertNotNull(view.getRelationshipView(b.getEfferentRelationshipWith(c)));
338+
}
339+
340+
@Test
341+
void addDefaultElements_WhenGreedyIsFalse() {
342+
model.setImpliedRelationshipsStrategy(new CreateImpliedRelationshipsUnlessAnyRelationshipExistsStrategy());
343+
344+
SoftwareSystem a = model.addSoftwareSystem("A");
345+
Container a1 = a.addContainer("A1");
346+
Container a2 = a.addContainer("A2");
347+
SoftwareSystem b = model.addSoftwareSystem("B");
348+
SoftwareSystem c = model.addSoftwareSystem("C");
349+
350+
a1.uses(a2, "Uses");
351+
a1.uses(b, "Uses");
352+
a2.uses(c, "Uses");
353+
b.uses(c, "Uses");
354+
355+
view = new ContainerView(a, "containers", "Description");
356+
view.addDefaultElements(false);
357+
358+
assertEquals(4, view.getElements().size());
359+
assertTrue(view.getElements().contains(new ElementView(a1)));
360+
assertTrue(view.getElements().contains(new ElementView(a2)));
361+
assertTrue(view.getElements().contains(new ElementView(b)));
362+
assertTrue(view.getElements().contains(new ElementView(c)));
363+
364+
assertEquals(3, view.getRelationships().size());
365+
assertNotNull(view.getRelationshipView(a1.getEfferentRelationshipWith(a2)));
366+
assertNotNull(view.getRelationshipView(a1.getEfferentRelationshipWith(b)));
367+
assertNotNull(view.getRelationshipView(a2.getEfferentRelationshipWith(c)));
368+
assertNull(view.getRelationshipView(b.getEfferentRelationshipWith(c)));
369+
}
370+
309371
@Test
310372
void addSoftwareSystem_ThrowsAnException_WhenTheSoftwareSystemIsTheScopeOfTheView() {
311373
SoftwareSystem softwareSystem = model.addSoftwareSystem("Software System");

structurizr-core/src/test/java/com/structurizr/view/SystemContextViewTests.java

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -305,4 +305,42 @@ void addDefaultElements() {
305305
assertTrue(view.getElements().contains(new ElementView(softwareSystem2)));
306306
}
307307

308+
@Test
309+
void addDefaultElements_WhenGreedyIsTrue() {
310+
SoftwareSystem a = model.addSoftwareSystem("A");
311+
SoftwareSystem b = model.addSoftwareSystem("B");
312+
SoftwareSystem c = model.addSoftwareSystem("C");
313+
314+
Relationship ab = a.uses(b, "Uses");
315+
Relationship ac = a.uses(c, "Uses");
316+
Relationship bc = b.uses(c, "Uses");
317+
318+
view = views.createSystemContextView(a, "key", "description");
319+
view.addDefaultElements(true);
320+
321+
assertEquals(3, view.getElements().size());
322+
assertNotNull(view.getRelationshipView(ab));
323+
assertNotNull(view.getRelationshipView(ac));
324+
assertNotNull(view.getRelationshipView(bc));
325+
}
326+
327+
@Test
328+
void addDefaultElements_WhenGreedyIsFalse() {
329+
SoftwareSystem a = model.addSoftwareSystem("A");
330+
SoftwareSystem b = model.addSoftwareSystem("B");
331+
SoftwareSystem c = model.addSoftwareSystem("C");
332+
333+
Relationship ab = a.uses(b, "Uses");
334+
Relationship ac = a.uses(c, "Uses");
335+
Relationship bc = b.uses(c, "Uses");
336+
337+
view = views.createSystemContextView(a, "key", "description");
338+
view.addDefaultElements(false);
339+
340+
assertEquals(3, view.getElements().size());
341+
assertNotNull(view.getRelationshipView(ab));
342+
assertNotNull(view.getRelationshipView(ac));
343+
assertNull(view.getRelationshipView(bc));
344+
}
345+
308346
}

0 commit comments

Comments
 (0)