Skip to content

Commit c1c25fd

Browse files
authored
Merge pull request #174 from mswiderski/custom-template
allow to use custom workflow template for generatig diagrams
2 parents 5cf206b + 5be6e37 commit c1c25fd

File tree

6 files changed

+129
-3
lines changed

6 files changed

+129
-3
lines changed

README.md

+16
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,22 @@ String diagramSVG = workflowDiagram.getSvgDiagram();
267267
`diagramSVG` includes the diagram SVG source which you can then decide to save to a file,
268268
print, or process further.
269269

270+
In case default visualization of the workflow is not sufficient you can provide custom workflow template to be
271+
used while generating the SVG file. Easiest is to start off from the default template and customize it to your needs.
272+
273+
Custom template must be on the classpath in `templates/plantuml` directory and must use `.txt` extension. Next
274+
template is set on `WorkflowDiagram` instance as shown below.
275+
276+
``` java
277+
Workflow workflow = Workflow.fromSource(source);
278+
279+
WorkflowDiagram workflowDiagram = new WorkflowDiagramImpl();
280+
workflowDiagram.setWorkflow(workflow);
281+
workflowDiagram.setTemplate("custom-template");
282+
283+
String diagramSVG = workflowDiagram.getSvgDiagram();
284+
```
285+
270286
By default the diagram legend is now shown. If you want to enable it you can do:
271287

272288
``` java

api/src/main/java/io/serverlessworkflow/api/interfaces/WorkflowDiagram.java

+2
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ public interface WorkflowDiagram {
2222

2323
WorkflowDiagram setSource(String source);
2424

25+
WorkflowDiagram setTemplate(String template);
26+
2527
String getSvgDiagram() throws Exception;
2628

2729
WorkflowDiagram showLegend(boolean showLegend);

diagram/src/main/java/io/serverlessworkflow/diagram/WorkflowDiagramImpl.java

+12-1
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,14 @@
2626

2727
public class WorkflowDiagramImpl implements WorkflowDiagram {
2828

29+
public static final String DEFAULT_TEMPLATE = "workflow-template";
30+
2931
@SuppressWarnings("unused")
3032
private String source;
3133

34+
@SuppressWarnings("unused")
35+
private String template = DEFAULT_TEMPLATE;
36+
3237
private Workflow workflow;
3338
private boolean showLegend = false;
3439

@@ -46,12 +51,18 @@ public WorkflowDiagram setSource(String source) {
4651
return this;
4752
}
4853

54+
@Override
55+
public WorkflowDiagram setTemplate(String template) {
56+
this.template = template;
57+
return this;
58+
}
59+
4960
@Override
5061
public String getSvgDiagram() throws Exception {
5162
if (workflow == null) {
5263
throw new IllegalAccessException("Unable to get diagram - no workflow set.");
5364
}
54-
String diagramSource = WorkflowToPlantuml.convert(workflow, showLegend);
65+
String diagramSource = WorkflowToPlantuml.convert(template, workflow, showLegend);
5566
SourceStringReader reader = new SourceStringReader(diagramSource);
5667
final ByteArrayOutputStream os = new ByteArrayOutputStream();
5768
reader.generateImage(os, new FileFormatOption(FileFormat.SVG));

diagram/src/main/java/io/serverlessworkflow/diagram/utils/WorkflowToPlantuml.java

+3-2
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,12 @@
2222
import org.thymeleaf.context.Context;
2323

2424
public class WorkflowToPlantuml {
25-
public static String convert(Workflow workflow, boolean showLegend) {
25+
26+
public static String convert(String template, Workflow workflow, boolean showLegend) {
2627
TemplateEngine plantUmlTemplateEngine = ThymeleafConfig.templateEngine;
2728
Context context = new Context();
2829
context.setVariable("diagram", new WorkflowDiagramModel(workflow, showLegend));
2930

30-
return plantUmlTemplateEngine.process("workflow-template", context);
31+
return plantUmlTemplateEngine.process(template, context);
3132
}
3233
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/*
2+
* Copyright 2020-Present The Serverless Workflow Specification Authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package io.serverlessworkflow.diagram.test;
17+
18+
import static org.junit.jupiter.api.Assertions.assertNotNull;
19+
20+
import io.serverlessworkflow.api.Workflow;
21+
import io.serverlessworkflow.api.interfaces.WorkflowDiagram;
22+
import io.serverlessworkflow.diagram.WorkflowDiagramImpl;
23+
import io.serverlessworkflow.diagram.test.utils.DiagramTestUtils;
24+
import org.junit.jupiter.api.Assertions;
25+
import org.junit.jupiter.params.ParameterizedTest;
26+
import org.junit.jupiter.params.provider.ValueSource;
27+
28+
public class CustomTemplateWorkflowDiagramTest {
29+
30+
@ParameterizedTest
31+
@ValueSource(strings = {"/examples/applicantrequest.json", "/examples/applicantrequest.yml"})
32+
public void testSpecExamplesParsing(String workflowLocation) throws Exception {
33+
34+
Workflow workflow = Workflow.fromSource(DiagramTestUtils.readWorkflowFile(workflowLocation));
35+
36+
assertNotNull(workflow);
37+
assertNotNull(workflow.getId());
38+
assertNotNull(workflow.getName());
39+
assertNotNull(workflow.getStates());
40+
41+
WorkflowDiagram workflowDiagram =
42+
new WorkflowDiagramImpl().setWorkflow(workflow).setTemplate("custom-template");
43+
44+
String diagramSVG = workflowDiagram.getSvgDiagram();
45+
46+
Assertions.assertNotNull(diagramSVG);
47+
// custom template uses #0000FF as start node color
48+
Assertions.assertTrue(diagramSVG.contains("#0000FF"));
49+
}
50+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
@startuml
2+
skinparam backgroundColor White
3+
skinparam legendBackgroundColor White
4+
skinparam legendBorderColor White
5+
skinparam state {
6+
StartColor #0000FF
7+
EndColor Orange
8+
BackgroundColor GhostWhite
9+
BackgroundColor<< workflow >> White
10+
BorderColor Black
11+
ArrowColor Black
12+
13+
BorderColor<< event >> #7fe5f0
14+
BorderColor<< operation >> #bada55
15+
BorderColor<< switch >> #92a0f2
16+
BorderColor<< sleep >> #b83b5e
17+
BorderColor<< parallel >> #6a2c70
18+
BorderColor<< inject >> #1e5f74
19+
BorderColor<< foreach >> #931a25
20+
BorderColor<< callback >> #ffcb8e
21+
}
22+
state "[(${diagram.title})]" as workflow << workflow >> {
23+
24+
[# th:each="stateDef : ${diagram.modelStateDefs}" ]
25+
[(${stateDef.toString()})]
26+
[/]
27+
28+
[# th:each="state : ${diagram.modelStates}" ]
29+
[(${state.toString()})]
30+
[/]
31+
32+
[# th:each="connection : ${diagram.modelConnections}" ]
33+
[(${connection.toString()})]
34+
[/]
35+
36+
}
37+
38+
[# th:if="${diagram.showLegend}" ]
39+
legend center
40+
State Types and Border Colors:
41+
| Event | Operation | Switch | Sleep | Parallel | Inject | ForEach | CallBack |
42+
|<#7fe5f0>|<#bada55>|<#92a0f2>|<#b83b5e>|<#6a2c70>|<#1e5f74>|<#931a25>|<#ffcb8e>|
43+
endlegend
44+
[/]
45+
46+
@enduml

0 commit comments

Comments
 (0)