GH-989 - Allow registering skin parameters in generated PlantUML diagrams.

This commit is contained in:
Alexander Miller
2024-12-11 16:19:46 +01:00
committed by Oliver Drotbohm
parent dab378aaeb
commit eed4744b2f

View File

@@ -35,6 +35,7 @@ import java.util.function.Supplier;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import com.structurizr.export.plantuml.AbstractPlantUMLExporter;
import org.springframework.lang.Nullable;
import org.springframework.modulith.core.ApplicationModule;
import org.springframework.modulith.core.ApplicationModuleDependency;
@@ -565,6 +566,7 @@ public class Documenter {
case C4:
var c4PlantUmlExporter = new C4PlantUMLExporter();
addSkinParamsFromOptions(c4PlantUmlExporter, options);
var diagram = c4PlantUmlExporter.export(view);
return diagram.getDefinition();
@@ -573,12 +575,19 @@ public class Documenter {
default:
var plantUmlExporter = new CustomizedPlantUmlExporter();
addSkinParamsFromOptions(plantUmlExporter, options);
plantUmlExporter.addSkinParam("componentStyle", "uml1");
return plantUmlExporter.export(view).getDefinition();
}
}
private void addSkinParamsFromOptions(AbstractPlantUMLExporter exporter, DiagramOptions options) {
for (var skinParamEntry : options.skinParams.entrySet()) {
exporter.addSkinParam(skinParamEntry.getKey(), skinParamEntry.getValue());
}
}
private String createPlantUml(DiagramOptions options) {
ComponentView componentView = createComponentView(options);
@@ -692,6 +701,7 @@ public class Documenter {
private final Function<ApplicationModule, String> defaultDisplayName;
private final DiagramStyle style;
private final ElementsWithoutRelationships elementsWithoutRelationships;
private final Map<String, String> skinParams;
/**
* @param dependencyTypes must not be {@literal null}.
@@ -704,13 +714,15 @@ public class Documenter {
* @param defaultDisplayName must not be {@literal null}.
* @param style must not be {@literal null}.
* @param elementsWithoutRelationships must not be {@literal null}.
* @param skinParams must not be {@literal null}.
*/
DiagramOptions(Set<DependencyType> dependencyTypes, DependencyDepth dependencyDepth,
Predicate<ApplicationModule> exclusions, Predicate<Component> componentFilter,
Predicate<ApplicationModule> targetOnly, @Nullable String targetFileName,
Function<ApplicationModule, Optional<String>> colorSelector,
Function<ApplicationModule, String> defaultDisplayName, DiagramStyle style,
ElementsWithoutRelationships elementsWithoutRelationships) {
ElementsWithoutRelationships elementsWithoutRelationships,
Map<String, String> skinParams) {
Assert.notNull(dependencyTypes, "Dependency types must not be null!");
Assert.notNull(dependencyDepth, "Dependency depth must not be null!");
@@ -721,6 +733,7 @@ public class Documenter {
Assert.notNull(defaultDisplayName, "Default display name must not be null!");
Assert.notNull(style, "DiagramStyle must not be null!");
Assert.notNull(elementsWithoutRelationships, "ElementsWithoutRelationships must not be null!");
Assert.notNull(skinParams, "SkinParams must not be null!");
this.dependencyTypes = dependencyTypes;
this.dependencyDepth = dependencyDepth;
@@ -732,6 +745,7 @@ public class Documenter {
this.defaultDisplayName = defaultDisplayName;
this.style = style;
this.elementsWithoutRelationships = elementsWithoutRelationships;
this.skinParams = skinParams;
}
/**
@@ -739,7 +753,7 @@ public class Documenter {
*/
public DiagramOptions withDependencyDepth(DependencyDepth dependencyDepth) {
return new DiagramOptions(dependencyTypes, dependencyDepth, exclusions, componentFilter, targetOnly,
targetFileName, colorSelector, defaultDisplayName, style, elementsWithoutRelationships);
targetFileName, colorSelector, defaultDisplayName, style, elementsWithoutRelationships, skinParams);
}
/**
@@ -747,7 +761,7 @@ public class Documenter {
*/
public DiagramOptions withExclusions(Predicate<ApplicationModule> exclusions) {
return new DiagramOptions(dependencyTypes, dependencyDepth, exclusions, componentFilter, targetOnly,
targetFileName, colorSelector, defaultDisplayName, style, elementsWithoutRelationships);
targetFileName, colorSelector, defaultDisplayName, style, elementsWithoutRelationships, skinParams);
}
/**
@@ -755,7 +769,7 @@ public class Documenter {
*/
public DiagramOptions withComponentFilter(Predicate<Component> componentFilter) {
return new DiagramOptions(dependencyTypes, dependencyDepth, exclusions, componentFilter, targetOnly,
targetFileName, colorSelector, defaultDisplayName, style, elementsWithoutRelationships);
targetFileName, colorSelector, defaultDisplayName, style, elementsWithoutRelationships, skinParams);
}
/**
@@ -765,7 +779,7 @@ public class Documenter {
*/
public DiagramOptions withTargetOnly(Predicate<ApplicationModule> targetOnly) {
return new DiagramOptions(dependencyTypes, dependencyDepth, exclusions, componentFilter, targetOnly,
targetFileName, colorSelector, defaultDisplayName, style, elementsWithoutRelationships);
targetFileName, colorSelector, defaultDisplayName, style, elementsWithoutRelationships, skinParams);
}
/**
@@ -777,7 +791,7 @@ public class Documenter {
Assert.isTrue(targetFileName.contains("%s"), () -> INVALID_FILE_NAME_PATTERN.formatted(targetFileName));
return new DiagramOptions(dependencyTypes, dependencyDepth, exclusions, componentFilter, targetOnly,
targetFileName, colorSelector, defaultDisplayName, style, elementsWithoutRelationships);
targetFileName, colorSelector, defaultDisplayName, style, elementsWithoutRelationships, skinParams);
}
/**
@@ -785,7 +799,7 @@ public class Documenter {
*/
public DiagramOptions withColorSelector(Function<ApplicationModule, Optional<String>> colorSelector) {
return new DiagramOptions(dependencyTypes, dependencyDepth, exclusions, componentFilter, targetOnly,
targetFileName, colorSelector, defaultDisplayName, style, elementsWithoutRelationships);
targetFileName, colorSelector, defaultDisplayName, style, elementsWithoutRelationships, skinParams);
}
/**
@@ -794,7 +808,7 @@ public class Documenter {
*/
public DiagramOptions withDefaultDisplayName(Function<ApplicationModule, String> defaultDisplayName) {
return new DiagramOptions(dependencyTypes, dependencyDepth, exclusions, componentFilter, targetOnly,
targetFileName, colorSelector, defaultDisplayName, style, elementsWithoutRelationships);
targetFileName, colorSelector, defaultDisplayName, style, elementsWithoutRelationships, skinParams);
}
/**
@@ -802,7 +816,7 @@ public class Documenter {
*/
public DiagramOptions withStyle(DiagramStyle style) {
return new DiagramOptions(dependencyTypes, dependencyDepth, exclusions, componentFilter, targetOnly,
targetFileName, colorSelector, defaultDisplayName, style, elementsWithoutRelationships);
targetFileName, colorSelector, defaultDisplayName, style, elementsWithoutRelationships, skinParams);
}
/**
@@ -815,7 +829,18 @@ public class Documenter {
*/
public DiagramOptions withElementsWithoutRelationships(ElementsWithoutRelationships elementsWithoutRelationships) {
return new DiagramOptions(dependencyTypes, dependencyDepth, exclusions, componentFilter, targetOnly,
targetFileName, colorSelector, defaultDisplayName, style, elementsWithoutRelationships);
targetFileName, colorSelector, defaultDisplayName, style, elementsWithoutRelationships, skinParams);
}
/**
* Configuration setting to add arbitrary skin parameters to the created diagrams.
*
* Applies to both the UML and C4 {@link DiagramStyle styles}.
*/
public DiagramOptions withSkinParam(String name, String value) {
skinParams.put(name, value);
return new DiagramOptions(dependencyTypes, dependencyDepth, exclusions, componentFilter, targetOnly,
targetFileName, colorSelector, defaultDisplayName, style, elementsWithoutRelationships, skinParams);
}
/**
@@ -828,7 +853,7 @@ public class Documenter {
public static DiagramOptions defaults() {
return new DiagramOptions(ALL_TYPES, DependencyDepth.IMMEDIATE, it -> false, it -> true, it -> false, null,
__ -> Optional.empty(), it -> it.getDisplayName(), DiagramStyle.C4,
ElementsWithoutRelationships.HIDDEN);
ElementsWithoutRelationships.HIDDEN, new LinkedHashMap<>());
}
/**
@@ -845,7 +870,7 @@ public class Documenter {
return new DiagramOptions(dependencyTypes, dependencyDepth, exclusions, componentFilter, targetOnly,
targetFileName,
colorSelector, defaultDisplayName, style, elementsWithoutRelationships);
colorSelector, defaultDisplayName, style, elementsWithoutRelationships, skinParams);
}
private Optional<String> getTargetFileName() {