Skip to content

Commit

Permalink
Add options to the StructurizrDslParser to be able to inject some par…
Browse files Browse the repository at this point in the history
…sing behaviors.

The only option is to force unique constant declaration, in order to prevent constants override inside a workspace.
  • Loading branch information
GuillaumeTaffin committed Feb 25, 2024
1 parent d32faa9 commit e9e15f8
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 1 deletion.
1 change: 1 addition & 0 deletions structurizr-dsl/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ dependencies {

testImplementation 'org.junit.jupiter:junit-jupiter-engine:5.9.2'
testImplementation 'org.junit.jupiter:junit-jupiter-params:5.9.2'
testImplementation 'org.assertj:assertj-core:3.24.2'
}

description = 'Structurizr DSL'
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ public final class StructurizrDslParser extends StructurizrDslTokens {
private final Set<String> parsedTokens = new HashSet<>();
private final IdentifiersRegister identifiersRegister;
private final Map<String, Constant> constants;
private final StructurizrDslParserOptions parserOptions;

private final List<String> dslSourceLines = new ArrayList<>();
private Workspace workspace;
Expand All @@ -54,9 +55,14 @@ public final class StructurizrDslParser extends StructurizrDslTokens {
* Creates a new instance of the parser.
*/
public StructurizrDslParser() {
this(new StructurizrDslParserOptions(false));
}

public StructurizrDslParser(StructurizrDslParserOptions options) {
contextStack = new Stack<>();
identifiersRegister = new IdentifiersRegister();
constants = new HashMap<>();
parserOptions = options;
}

/**
Expand Down Expand Up @@ -874,7 +880,11 @@ void parse(List<String> lines, File dslFile, boolean include) throws Structurizr
} else if (CONSTANT_TOKEN.equalsIgnoreCase(firstToken)) {
Constant constant = new ConstantParser().parse(getContext(), tokens);
if (constants.containsKey(constant.getName())) {
log.warn("A constant named " + constant.getName() + " already exists");
String message = "A constant named " + constant.getName() + " already exists";
if(parserOptions.uniqueConstantsDeclaration()) {
throw new StructurizrDslParserException(message);
}
log.warn(message);
}
constants.put(constant.getName(), constant);

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.structurizr.dsl;

/**
* @param uniqueConstantsDeclaration If set to true, then constants declared with the !constant keyword cannot be overridden.
*/
public record StructurizrDslParserOptions(
boolean uniqueConstantsDeclaration
) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.structurizr.dsl;

import org.junit.jupiter.api.Test;

import static org.assertj.core.api.Assertions.assertThatCode;

public class UniqueConstantsConfigurationTests {

@Test
void shouldFailOnConstantDuplication() {
String dsl = """
workspace {
!constant NAME toto
!constant NAME titi
}
""";

StructurizrDslParser parser = new StructurizrDslParser(
new StructurizrDslParserOptions(true)
);

assertThatCode(() -> parser.parse(dsl))
.isInstanceOf(StructurizrDslParserException.class)
.hasMessageStartingWith("A constant named NAME already exists");
}
}

0 comments on commit e9e15f8

Please sign in to comment.