Skip to content
This repository was archived by the owner on Mar 28, 2026. It is now read-only.

Commit b6fd8cd

Browse files
structurizr-dsl: description and technology now work inside !elements blocks.
1 parent d95879f commit b6fd8cd

5 files changed

Lines changed: 129 additions & 0 deletions

File tree

changelog.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
- structurizr-dsl: Adds support for `element!=` expressions.
66
- structurizr-dsl: `!elements` and `!relationships` now work inside deployment environment blocks.
7+
- structurizr-dsl: `description` and `technology` now work inside `!elements` blocks.
78

89
## 3.1.0 (4th November 2024)
910

structurizr-dsl/src/main/java/com/structurizr/dsl/ElementsDslContext.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ Set<ModelItem> getModelItems() {
2929
protected String[] getPermittedTokens() {
3030
return new String[] {
3131
StructurizrDslTokens.RELATIONSHIP_TOKEN,
32+
StructurizrDslTokens.DESCRIPTION_TOKEN,
33+
StructurizrDslTokens.TECHNOLOGY_TOKEN,
3234
StructurizrDslTokens.TAG_TOKEN,
3335
StructurizrDslTokens.TAGS_TOKEN,
3436
StructurizrDslTokens.URL_TOKEN,
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package com.structurizr.dsl;
2+
3+
import com.structurizr.model.*;
4+
5+
final class ElementsParser extends AbstractParser {
6+
7+
private final static int DESCRIPTION_INDEX = 1;
8+
private final static int TECHNOLOGY_INDEX = 1;
9+
10+
void parseDescription(ElementsDslContext context, Tokens tokens) {
11+
// description <description>
12+
if (tokens.hasMoreThan(DESCRIPTION_INDEX)) {
13+
throw new RuntimeException("Too many tokens, expected: description <description>");
14+
}
15+
16+
if (!tokens.includes(DESCRIPTION_INDEX)) {
17+
throw new RuntimeException("Expected: description <description>");
18+
}
19+
20+
String description = tokens.get(DESCRIPTION_INDEX);
21+
for (Element element : context.getElements()) {
22+
element.setDescription(description);
23+
}
24+
}
25+
26+
void parseTechnology(ElementsDslContext context, Tokens tokens) {
27+
// technology <technology>
28+
if (tokens.hasMoreThan(TECHNOLOGY_INDEX)) {
29+
throw new RuntimeException("Too many tokens, expected: technology <technology>");
30+
}
31+
32+
if (!tokens.includes(TECHNOLOGY_INDEX)) {
33+
throw new RuntimeException("Expected: technology <technology>");
34+
}
35+
36+
String technology = tokens.get(TECHNOLOGY_INDEX);
37+
for (Element element : context.getElements()) {
38+
if (element instanceof Container) {
39+
((Container)element).setTechnology(technology);
40+
} else if (element instanceof Component) {
41+
((Component)element).setTechnology(technology);
42+
} else if (element instanceof DeploymentNode) {
43+
((DeploymentNode)element).setTechnology(technology);
44+
} else if (element instanceof InfrastructureNode) {
45+
((InfrastructureNode)element).setTechnology(technology);
46+
}
47+
}
48+
}
49+
50+
}

structurizr-dsl/src/main/java/com/structurizr/dsl/StructurizrDslParser.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -537,6 +537,9 @@ void parse(List<String> lines, File dslFile, boolean fragment, boolean includeIn
537537
} else if (DESCRIPTION_TOKEN.equalsIgnoreCase(firstToken) && inContext(ElementDslContext.class) && !isGroup(getContext())) {
538538
new ModelItemParser().parseDescription(getContext(ElementDslContext.class), tokens);
539539

540+
} else if (DESCRIPTION_TOKEN.equalsIgnoreCase(firstToken) && inContext(ElementsDslContext.class)) {
541+
new ElementsParser().parseDescription(getContext(ElementsDslContext.class), tokens);
542+
540543
} else if (TECHNOLOGY_TOKEN.equalsIgnoreCase(firstToken) && inContext(ContainerDslContext.class) && !getContext(ContainerDslContext.class).hasGroup()) {
541544
new ContainerParser().parseTechnology(getContext(ContainerDslContext.class), tokens);
542545

@@ -549,6 +552,9 @@ void parse(List<String> lines, File dslFile, boolean fragment, boolean includeIn
549552
} else if (TECHNOLOGY_TOKEN.equalsIgnoreCase(firstToken) && inContext(InfrastructureNodeDslContext.class)) {
550553
new InfrastructureNodeParser().parseTechnology(getContext(InfrastructureNodeDslContext.class), tokens);
551554

555+
} else if (TECHNOLOGY_TOKEN.equalsIgnoreCase(firstToken) && inContext(ElementsDslContext.class)) {
556+
new ElementsParser().parseTechnology(getContext(ElementsDslContext.class), tokens);
557+
552558
} else if (INSTANCES_TOKEN.equalsIgnoreCase(firstToken) && inContext(DeploymentNodeDslContext.class)) {
553559
new DeploymentNodeParser().parseInstances(getContext(DeploymentNodeDslContext.class), tokens);
554560

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
package com.structurizr.dsl;
2+
3+
import com.structurizr.model.*;
4+
import org.junit.jupiter.api.Test;
5+
6+
import java.util.Set;
7+
8+
import static org.junit.jupiter.api.Assertions.assertEquals;
9+
import static org.junit.jupiter.api.Assertions.fail;
10+
11+
class ElementsParserTests extends AbstractTests {
12+
13+
private final ElementsParser parser = new ElementsParser();
14+
15+
@Test
16+
void test_parseTechnology_ThrowsAnException_WhenNoTechnologyIsSpecified() {
17+
try {
18+
parser.parseTechnology(null, tokens("technology"));
19+
fail();
20+
} catch (Exception e) {
21+
assertEquals("Expected: technology <technology>", e.getMessage());
22+
}
23+
}
24+
25+
@Test
26+
void test_parseTechnology() {
27+
SoftwareSystem softwareSystem = model.addSoftwareSystem("Software System");
28+
Container container = softwareSystem.addContainer("Container");
29+
Component component = container.addComponent("Component");
30+
DeploymentNode deploymentNode = model.addDeploymentNode("Deployment Node");
31+
InfrastructureNode infrastructureNode = deploymentNode.addInfrastructureNode("Infrastructure Node");
32+
33+
ElementsDslContext context = new ElementsDslContext(null, Set.of(softwareSystem, container, component, deploymentNode, infrastructureNode));
34+
35+
parser.parseTechnology(context, tokens("technology", "Technology"));
36+
assertEquals("Technology", container.getTechnology());
37+
assertEquals("Technology", component.getTechnology());
38+
assertEquals("Technology", deploymentNode.getTechnology());
39+
assertEquals("Technology", infrastructureNode.getTechnology());
40+
}
41+
42+
@Test
43+
void test_parseDescription_ThrowsAnException_WhenNoDescriptionIsSpecified() {
44+
try {
45+
parser.parseDescription(null, tokens("description"));
46+
fail();
47+
} catch (Exception e) {
48+
assertEquals("Expected: description <description>", e.getMessage());
49+
}
50+
}
51+
52+
@Test
53+
void test_parseDescription() {
54+
SoftwareSystem softwareSystem = model.addSoftwareSystem("Software System");
55+
Container container = softwareSystem.addContainer("Container");
56+
Component component = container.addComponent("Component");
57+
DeploymentNode deploymentNode = model.addDeploymentNode("Deployment Node");
58+
InfrastructureNode infrastructureNode = deploymentNode.addInfrastructureNode("Infrastructure Node");
59+
60+
ElementsDslContext context = new ElementsDslContext(null, Set.of(softwareSystem, container, component, deploymentNode, infrastructureNode));
61+
62+
parser.parseDescription(context, tokens("description", "Description"));
63+
assertEquals("Description", softwareSystem.getDescription());
64+
assertEquals("Description", container.getDescription());
65+
assertEquals("Description", component.getDescription());
66+
assertEquals("Description", deploymentNode.getDescription());
67+
assertEquals("Description", infrastructureNode.getDescription());
68+
}
69+
70+
}

0 commit comments

Comments
 (0)