Skip to content

Commit e9e15f8

Browse files
Add options to the StructurizrDslParser to be able to inject some parsing behaviors.
The only option is to force unique constant declaration, in order to prevent constants override inside a workspace.
1 parent d32faa9 commit e9e15f8

File tree

4 files changed

+47
-1
lines changed

4 files changed

+47
-1
lines changed

structurizr-dsl/build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ dependencies {
99

1010
testImplementation 'org.junit.jupiter:junit-jupiter-engine:5.9.2'
1111
testImplementation 'org.junit.jupiter:junit-jupiter-params:5.9.2'
12+
testImplementation 'org.assertj:assertj-core:3.24.2'
1213
}
1314

1415
description = 'Structurizr DSL'

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

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ public final class StructurizrDslParser extends StructurizrDslTokens {
4343
private final Set<String> parsedTokens = new HashSet<>();
4444
private final IdentifiersRegister identifiersRegister;
4545
private final Map<String, Constant> constants;
46+
private final StructurizrDslParserOptions parserOptions;
4647

4748
private final List<String> dslSourceLines = new ArrayList<>();
4849
private Workspace workspace;
@@ -54,9 +55,14 @@ public final class StructurizrDslParser extends StructurizrDslTokens {
5455
* Creates a new instance of the parser.
5556
*/
5657
public StructurizrDslParser() {
58+
this(new StructurizrDslParserOptions(false));
59+
}
60+
61+
public StructurizrDslParser(StructurizrDslParserOptions options) {
5762
contextStack = new Stack<>();
5863
identifiersRegister = new IdentifiersRegister();
5964
constants = new HashMap<>();
65+
parserOptions = options;
6066
}
6167

6268
/**
@@ -874,7 +880,11 @@ void parse(List<String> lines, File dslFile, boolean include) throws Structurizr
874880
} else if (CONSTANT_TOKEN.equalsIgnoreCase(firstToken)) {
875881
Constant constant = new ConstantParser().parse(getContext(), tokens);
876882
if (constants.containsKey(constant.getName())) {
877-
log.warn("A constant named " + constant.getName() + " already exists");
883+
String message = "A constant named " + constant.getName() + " already exists";
884+
if(parserOptions.uniqueConstantsDeclaration()) {
885+
throw new StructurizrDslParserException(message);
886+
}
887+
log.warn(message);
878888
}
879889
constants.put(constant.getName(), constant);
880890

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package com.structurizr.dsl;
2+
3+
/**
4+
* @param uniqueConstantsDeclaration If set to true, then constants declared with the !constant keyword cannot be overridden.
5+
*/
6+
public record StructurizrDslParserOptions(
7+
boolean uniqueConstantsDeclaration
8+
) {
9+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package com.structurizr.dsl;
2+
3+
import org.junit.jupiter.api.Test;
4+
5+
import static org.assertj.core.api.Assertions.assertThatCode;
6+
7+
public class UniqueConstantsConfigurationTests {
8+
9+
@Test
10+
void shouldFailOnConstantDuplication() {
11+
String dsl = """
12+
workspace {
13+
!constant NAME toto
14+
!constant NAME titi
15+
}
16+
""";
17+
18+
StructurizrDslParser parser = new StructurizrDslParser(
19+
new StructurizrDslParserOptions(true)
20+
);
21+
22+
assertThatCode(() -> parser.parse(dsl))
23+
.isInstanceOf(StructurizrDslParserException.class)
24+
.hasMessageStartingWith("A constant named NAME already exists");
25+
}
26+
}

0 commit comments

Comments
 (0)