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

Commit 69b7d39

Browse files
structurizr-dsl: Adds support for element!= expressions.
1 parent 0351c2d commit 69b7d39

5 files changed

Lines changed: 82 additions & 15 deletions

File tree

build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ subprojects { proj ->
88

99
description = 'Structurizr'
1010
group = 'com.structurizr'
11-
version = '3.1.0'
11+
version = '3.2.0'
1212

1313
repositories {
1414
mavenCentral()

changelog.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Changelog
22

3+
## 3.2.0 (unreleased)
4+
5+
- structurizr-dsl: Adds support for `element!=` expressions.
6+
37
## 3.1.0 (4th November 2024)
48

59
- structurizr-client: Workspace archive file now includes the branch name in the filename.

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

Lines changed: 33 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -18,21 +18,22 @@ static boolean isExpression(String token) {
1818
token = token.toLowerCase();
1919

2020
return
21+
token.startsWith(ELEMENT_EQUALS_EXPRESSION.toLowerCase()) ||
22+
token.startsWith(ELEMENT_NOT_EQUALS_EXPRESSION.toLowerCase()) ||
2123
token.startsWith(ELEMENT_TYPE_EQUALS_EXPRESSION.toLowerCase()) ||
22-
token.startsWith(ELEMENT_TAG_EQUALS_EXPRESSION.toLowerCase()) ||
23-
token.startsWith(ELEMENT_TAG_NOT_EQUALS_EXPRESSION.toLowerCase()) ||
24-
token.startsWith(ELEMENT_TECHNOLOGY_EQUALS_EXPRESSION.toLowerCase()) ||
25-
token.startsWith(ELEMENT_TECHNOLOGY_NOT_EQUALS_EXPRESSION.toLowerCase()) ||
26-
token.matches(ELEMENT_PROPERTY_EQUALS_EXPRESSION) ||
27-
token.startsWith(ELEMENT_PARENT_EQUALS_EXPRESSION.toLowerCase()) ||
28-
token.startsWith(RELATIONSHIP) || token.endsWith(RELATIONSHIP) || token.contains(RELATIONSHIP) ||
29-
token.startsWith(ELEMENT_EQUALS_EXPRESSION) ||
30-
token.startsWith(RELATIONSHIP_TAG_EQUALS_EXPRESSION.toLowerCase()) ||
31-
token.startsWith(RELATIONSHIP_TAG_NOT_EQUALS_EXPRESSION.toLowerCase()) ||
32-
token.matches(RELATIONSHIP_PROPERTY_EQUALS_EXPRESSION) ||
33-
token.startsWith(RELATIONSHIP_SOURCE_EQUALS_EXPRESSION.toLowerCase()) ||
34-
token.startsWith(RELATIONSHIP_DESTINATION_EQUALS_EXPRESSION.toLowerCase()) ||
35-
token.startsWith(RELATIONSHIP_EQUALS_EXPRESSION);
24+
token.startsWith(ELEMENT_TAG_EQUALS_EXPRESSION.toLowerCase()) ||
25+
token.startsWith(ELEMENT_TAG_NOT_EQUALS_EXPRESSION.toLowerCase()) ||
26+
token.startsWith(ELEMENT_TECHNOLOGY_EQUALS_EXPRESSION.toLowerCase()) ||
27+
token.startsWith(ELEMENT_TECHNOLOGY_NOT_EQUALS_EXPRESSION.toLowerCase()) ||
28+
token.matches(ELEMENT_PROPERTY_EQUALS_EXPRESSION) ||
29+
token.startsWith(ELEMENT_PARENT_EQUALS_EXPRESSION.toLowerCase()) ||
30+
token.startsWith(RELATIONSHIP) || token.endsWith(RELATIONSHIP) || token.contains(RELATIONSHIP) ||
31+
token.startsWith(RELATIONSHIP_TAG_EQUALS_EXPRESSION.toLowerCase()) ||
32+
token.startsWith(RELATIONSHIP_TAG_NOT_EQUALS_EXPRESSION.toLowerCase()) ||
33+
token.matches(RELATIONSHIP_PROPERTY_EQUALS_EXPRESSION) ||
34+
token.startsWith(RELATIONSHIP_SOURCE_EQUALS_EXPRESSION.toLowerCase()) ||
35+
token.startsWith(RELATIONSHIP_DESTINATION_EQUALS_EXPRESSION.toLowerCase()) ||
36+
token.startsWith(RELATIONSHIP_EQUALS_EXPRESSION);
3637
}
3738

3839

@@ -71,6 +72,24 @@ private Set<ModelItem> evaluateExpression(String expr, DslContext context) {
7172
} else {
7273
modelItems.addAll(parseIdentifier(expr, context));
7374
}
75+
} else if (expr.startsWith(ELEMENT_NOT_EQUALS_EXPRESSION)) {
76+
expr = expr.substring(ELEMENT_NOT_EQUALS_EXPRESSION.length());
77+
78+
if (isExpression(expr)) {
79+
Set<ModelItem> mi = evaluateExpression(expr, context);
80+
context.getWorkspace().getModel().getElements().forEach(element -> {
81+
if (!mi.contains(element)) {
82+
modelItems.add(element);
83+
}
84+
});
85+
} else {
86+
Set<ModelItem> mi = parseIdentifier(expr, context);
87+
context.getWorkspace().getModel().getElements().forEach(element -> {
88+
if (!mi.contains(element)) {
89+
modelItems.add(element);
90+
}
91+
});
92+
}
7493
} else if (expr.startsWith(RELATIONSHIP_EQUALS_EXPRESSION)) {
7594
expr = expr.substring(RELATIONSHIP_EQUALS_EXPRESSION.length());
7695

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ class StructurizrDslExpressions {
1010
static final String ELEMENT_PROPERTY_EQUALS_EXPRESSION = "element\\.properties\\[.*]==.*";
1111

1212
static final String ELEMENT_EQUALS_EXPRESSION = "element==";
13+
static final String ELEMENT_NOT_EQUALS_EXPRESSION = "element!=";
1314
static final String ELEMENT_PARENT_EQUALS_EXPRESSION = "element.parent==";
1415

1516
static final String RELATIONSHIP_TAG_EQUALS_EXPRESSION = "relationship.tag==";

structurizr-dsl/src/test/java/com/structurizr/dsl/ExpressionParserTests.java

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -541,4 +541,47 @@ void test_parseExpression_ReturnsRelationshipsAndImpliedRelationships_WhenUsingA
541541
assertTrue(relationships.contains(impliedRelationship));
542542
}
543543

544+
@Test
545+
void test_parseExpression_ReturnsElements_WhenUsingElementNotEqualsIdentifier() {
546+
SoftwareSystem a = model.addSoftwareSystem("A");
547+
SoftwareSystem b = model.addSoftwareSystem("B");
548+
SoftwareSystem c = model.addSoftwareSystem("C");
549+
550+
SystemLandscapeViewDslContext context = new SystemLandscapeViewDslContext(null);
551+
context.setWorkspace(workspace);
552+
553+
IdentifiersRegister map = new IdentifiersRegister();
554+
map.register("a", a);
555+
map.register("b", b);
556+
map.register("c", c);
557+
context.setIdentifierRegister(map);
558+
559+
Set<ModelItem> elements = parser.parseExpression("element!=c", context);
560+
assertEquals(2, elements.size());
561+
assertTrue(elements.contains(a));
562+
assertTrue(elements.contains(b));
563+
}
564+
565+
@Test
566+
void test_parseExpression_ReturnsElements_WhenUsingElementNotEqualsExpression() {
567+
SoftwareSystem a = model.addSoftwareSystem("A");
568+
SoftwareSystem b = model.addSoftwareSystem("B");
569+
SoftwareSystem c = model.addSoftwareSystem("C");
570+
Relationship aToB = a.uses(b, "Uses");
571+
Relationship bToC = b.uses(c, "Uses");
572+
573+
SystemLandscapeViewDslContext context = new SystemLandscapeViewDslContext(null);
574+
context.setWorkspace(workspace);
575+
576+
IdentifiersRegister map = new IdentifiersRegister();
577+
map.register("a", a);
578+
map.register("b", b);
579+
map.register("c", c);
580+
context.setIdentifierRegister(map);
581+
582+
Set<ModelItem> elements = parser.parseExpression("element!=->b", context);
583+
assertEquals(1, elements.size());
584+
assertTrue(elements.contains(c));
585+
}
586+
544587
}

0 commit comments

Comments
 (0)