38
38
import java .util .stream .Collectors ;
39
39
import java .util .stream .Stream ;
40
40
41
+ import org .eclipse .esmf .aspectmodel .generator .AspectGenerator ;
41
42
import org .eclipse .esmf .aspectmodel .generator .DocumentGenerationException ;
42
43
import org .eclipse .esmf .aspectmodel .generator .LanguageCollector ;
43
44
import org .eclipse .esmf .metamodel .Aspect ;
59
60
/**
60
61
* Generate SVG and PNG diagrams from Aspect Models
61
62
*/
62
- public class AspectModelDiagramGenerator {
63
+ public class AspectModelDiagramGenerator extends AspectGenerator <String , byte [], DiagramGenerationConfig , DiagramArtifact > {
64
+ public static final DiagramGenerationConfig DEFAULT_CONFIG = DiagramGenerationConfigBuilder .builder ().build ();
65
+ private static final String FONT_NAME = "Roboto Condensed" ;
66
+ private static final String FONT_FILE = "diagram/RobotoCondensed-Regular.ttf" ;
67
+
68
+ /**
69
+ * @deprecated Replaced by {@link DiagramGenerationConfig.Format}
70
+ */
71
+ @ Deprecated ( forRemoval = true )
63
72
public enum Format {
64
73
PNG ,
65
74
SVG ;
66
75
76
+ @ Deprecated ( forRemoval = true )
67
77
public String getArtifactFilename ( final String aspectName , final Locale language ) {
68
78
return String .format ( "%s_%s.%s" , aspectName , language .toLanguageTag (), toString ().toLowerCase () );
69
79
}
@@ -76,47 +86,33 @@ public String toString() {
76
86
};
77
87
}
78
88
89
+ @ Deprecated ( forRemoval = true )
79
90
public static String allValues () {
80
91
return String .join ( ", " , Stream .of ( values () ).map ( Format ::toString ).toList () );
81
92
}
82
93
}
83
94
84
- private static final String FONT_NAME = "Roboto Condensed" ;
85
- private static final String FONT_FILE = "diagram/RobotoCondensed-Regular.ttf" ;
86
-
87
- private final Aspect aspect ;
88
-
89
95
public AspectModelDiagramGenerator ( final Aspect aspect ) {
90
- this . aspect = aspect ;
96
+ this ( aspect , DEFAULT_CONFIG ) ;
91
97
}
92
98
93
- InputStream getInputStream ( final String resource ) {
94
- return getClass (). getClassLoader (). getResourceAsStream ( resource );
99
+ public AspectModelDiagramGenerator ( final Aspect aspect , final DiagramGenerationConfig config ) {
100
+ super ( aspect , config );
95
101
}
96
102
97
- private void generatePng ( final String svgInput , final OutputStream output ) {
98
- // To make the font available during PNG generation, it needs to be registered
99
- // in Java Runtime's graphics environment
100
- try {
101
- final File tmpFontFile = generateTmpFontFile ();
102
- final Font f = Font .createFont ( Font .TRUETYPE_FONT , tmpFontFile );
103
- final GraphicsEnvironment ge = GraphicsEnvironment .getLocalGraphicsEnvironment ();
104
- ge .registerFont ( f );
105
-
106
- final String input = svgInput .replaceAll (
107
- "<!DOCTYPE svg PUBLIC \" -//W3C//DTD SVG 1.1//EN\" \" http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\" >" , "" );
103
+ @ Override
104
+ public Stream <DiagramArtifact > generate () {
105
+ final String artifactName = "%s_%s.%s" .formatted ( aspect ().getName (), config .language ().toLanguageTag (),
106
+ config .format ().toString ().toLowerCase () );
107
+ final String svg = generateSvg ();
108
+ final byte [] content = config .format () == DiagramGenerationConfig .Format .SVG
109
+ ? svg .getBytes ( StandardCharsets .UTF_8 )
110
+ : generatePng ( svg );
111
+ return Stream .of ( new DiagramArtifact ( artifactName , content ) );
112
+ }
108
113
109
- final TranscoderInput inputSvgImage = new TranscoderInput ( new StringReader ( input ) );
110
- final TranscoderOutput outputPngImage = new TranscoderOutput ( output );
111
- final PNGTranscoder pngTranscoder = new PNGTranscoder ();
112
- pngTranscoder .transcode ( inputSvgImage , outputPngImage );
113
- output .flush ();
114
- output .close ();
115
- } catch ( final FontFormatException exception ) {
116
- // Will only happen if the loaded .ttf file is invalid
117
- } catch ( final IOException | TranscoderException exception ) {
118
- throw new DocumentGenerationException ( exception );
119
- }
114
+ private InputStream getInputStream ( final String resource ) {
115
+ return getClass ().getClassLoader ().getResourceAsStream ( resource );
120
116
}
121
117
122
118
private File generateTmpFontFile () throws IOException {
@@ -141,17 +137,9 @@ private String base64EncodeInputStream( final InputStream in ) throws IOExceptio
141
137
}
142
138
}
143
139
144
- /**
145
- * Generates an SVG diagram for the Aspect in the given target language and write it to the given output stream.
146
- * Note that the document will always be encoded in UTF-8, regardless of the platform's encoding.
147
- *
148
- * @param language the language
149
- * @param out the output stream
150
- * @throws IOException if writing to the output stream fails
151
- */
152
- public void generateSvg ( final Locale language , final OutputStream out ) throws IOException {
153
- final DiagramVisitor diagramVisitor = new DiagramVisitor ( language );
154
- final Diagram diagram = aspect .accept ( diagramVisitor , Optional .empty () );
140
+ private String generateSvg () {
141
+ final DiagramVisitor diagramVisitor = new DiagramVisitor ( config .language () );
142
+ final Diagram diagram = aspect ().accept ( diagramVisitor , Optional .empty () );
155
143
final Graphviz graphviz = render ( diagram );
156
144
157
145
try ( final InputStream fontStream = getInputStream ( FONT_FILE ) ) {
@@ -169,14 +157,56 @@ public void generateSvg( final Locale language, final OutputStream out ) throws
169
157
+ "\" );\n "
170
158
+ "}\n "
171
159
+ "</style>" ;
172
- final String result = svgDocument
173
- .replaceFirst ( ">" , ">" + css );
174
- out .write ( result .getBytes ( StandardCharsets .UTF_8 ) );
175
- } catch ( final ExecuteException exception ) {
160
+ return svgDocument .replaceFirst ( ">" , ">" + css );
161
+ } catch ( final ExecuteException | IOException exception ) {
176
162
throw new DocumentGenerationException ( exception );
177
163
}
178
164
}
179
165
166
+ private byte [] generatePng ( final String svg ) {
167
+ // To make the font available during PNG generation, it needs to be registered
168
+ // in Java Runtime's graphics environment
169
+ try {
170
+ final File tmpFontFile = generateTmpFontFile ();
171
+ final Font f = Font .createFont ( Font .TRUETYPE_FONT , tmpFontFile );
172
+ final GraphicsEnvironment ge = GraphicsEnvironment .getLocalGraphicsEnvironment ();
173
+ ge .registerFont ( f );
174
+
175
+ final String input = svg .replaceAll (
176
+ "<!DOCTYPE svg PUBLIC \" -//W3C//DTD SVG 1.1//EN\" \" http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\" >" , "" );
177
+
178
+ final TranscoderInput inputSvgImage = new TranscoderInput ( new StringReader ( input ) );
179
+ final ByteArrayOutputStream output = new ByteArrayOutputStream ();
180
+ final TranscoderOutput outputPngImage = new TranscoderOutput ( output );
181
+ final PNGTranscoder pngTranscoder = new PNGTranscoder ();
182
+ pngTranscoder .transcode ( inputSvgImage , outputPngImage );
183
+ output .flush ();
184
+ output .close ();
185
+ return output .toByteArray ();
186
+ } catch ( final FontFormatException exception ) {
187
+ // Will only happen if the loaded .ttf file is invalid
188
+ throw new DocumentGenerationException ( exception );
189
+ } catch ( final IOException | TranscoderException exception ) {
190
+ throw new DocumentGenerationException ( exception );
191
+ }
192
+ }
193
+
194
+ /**
195
+ * Generates an SVG diagram for the Aspect in the given target language and write it to the given output stream.
196
+ * Note that the document will always be encoded in UTF-8, regardless of the platform's encoding.
197
+ *
198
+ * @param language the language
199
+ * @param out the output stream
200
+ * @throws IOException if writing to the output stream fails
201
+ * @deprecated Use {@link #AspectModelDiagramGenerator(Aspect, DiagramGenerationConfig)} and {@link #generate()} instead
202
+ */
203
+ @ Deprecated ( forRemoval = true )
204
+ public void generateSvg ( final Locale language , final OutputStream out ) throws IOException {
205
+ final DiagramGenerationConfig config = DiagramGenerationConfigBuilder .builder ().language ( language ).build ();
206
+ final byte [] content = new AspectModelDiagramGenerator ( aspect (), config ).getContent ();
207
+ IOUtils .copy ( new ByteArrayInputStream ( content ), out );
208
+ }
209
+
180
210
/**
181
211
* Generates a diagram for the Aspect in the given output format and target language.
182
212
* Note that SVG documents will always be encoded in UTF-8, regardless of the platform's encoding.
@@ -185,17 +215,17 @@ public void generateSvg( final Locale language, final OutputStream out ) throws
185
215
* @param language The language for which the diagram should be generated
186
216
* @param out The output stream the diagram is written to
187
217
* @throws DocumentGenerationException if diagram generation fails
218
+ * @deprecated Use {@link #AspectModelDiagramGenerator(Aspect, DiagramGenerationConfig)} and {@link #generate()} instead
188
219
*/
220
+ @ Deprecated ( forRemoval = true )
189
221
public void generateDiagram ( final Format outputFormat , final Locale language , final OutputStream out ) {
190
- final ByteArrayOutputStream buffer = new ByteArrayOutputStream ();
222
+ final DiagramGenerationConfig config = DiagramGenerationConfigBuilder .builder ()
223
+ .language ( language )
224
+ .format ( outputFormat == Format .PNG ? DiagramGenerationConfig .Format .PNG : DiagramGenerationConfig .Format .SVG )
225
+ .build ();
226
+ final byte [] content = new AspectModelDiagramGenerator ( aspect (), config ).getContent ();
191
227
try {
192
- generateSvg ( language , buffer );
193
- final String svgResult = buffer .toString ( StandardCharsets .UTF_8 );
194
-
195
- switch ( outputFormat ) {
196
- case PNG -> generatePng ( svgResult , out );
197
- default -> IOUtils .copy ( new ByteArrayInputStream ( svgResult .getBytes ( StandardCharsets .UTF_8 ) ), out );
198
- }
228
+ IOUtils .copy ( new ByteArrayInputStream ( content ), out );
199
229
} catch ( final IOException exception ) {
200
230
throw new DocumentGenerationException ( exception );
201
231
}
@@ -211,14 +241,18 @@ public void generateDiagram( final Format outputFormat, final Locale language, f
211
241
* @param outputFormat One of SVG or PNG
212
242
* @param nameMapper The callback function that maps diagram artifact names to OutputStreams
213
243
* @throws IOException if a write error occurs
244
+ * @deprecated Use {@link #AspectModelDiagramGenerator(Aspect, DiagramGenerationConfig)} and {@link #generate(Function)} instead
214
245
*/
246
+ @ Deprecated ( forRemoval = true )
215
247
public void generateDiagrams ( final Format outputFormat , final Function <String , OutputStream > nameMapper )
216
248
throws IOException {
217
- for ( final Locale language : LanguageCollector .collectUsedLanguages ( aspect ) ) {
218
- try ( final OutputStream outputStream = nameMapper
219
- .apply ( outputFormat .getArtifactFilename ( aspect .getName (), language ) ) ) {
220
- generateDiagram ( outputFormat , language , outputStream );
221
- }
249
+ for ( final Locale language : LanguageCollector .collectUsedLanguages ( aspect () ) ) {
250
+ final DiagramGenerationConfig config = DiagramGenerationConfigBuilder .builder ()
251
+ .language ( language )
252
+ .format ( outputFormat == Format .PNG ? DiagramGenerationConfig .Format .PNG : DiagramGenerationConfig .Format .SVG )
253
+ .build ();
254
+ final DiagramArtifact diagramArtifact = new AspectModelDiagramGenerator ( aspect (), config ).singleResult ();
255
+ IOUtils .copy ( new ByteArrayInputStream ( diagramArtifact .getContent () ), nameMapper .apply ( diagramArtifact .getId () ) );
222
256
}
223
257
}
224
258
@@ -233,21 +267,18 @@ public void generateDiagrams( final Format outputFormat, final Function<String,
233
267
* @param language The language for which the diagram should be generated
234
268
* @param nameMapper The callback function that maps diagram artifact names to OutputStreams
235
269
* @throws IOException if a write error occurs
270
+ * @deprecated Use {@link #AspectModelDiagramGenerator(Aspect, DiagramGenerationConfig)} and {@link #generate(Function)} instead
236
271
*/
272
+ @ Deprecated ( forRemoval = true )
237
273
public void generateDiagrams ( final Set <Format > targetFormats , final Locale language ,
238
274
final Function <String , OutputStream > nameMapper ) throws IOException {
239
- final ByteArrayOutputStream buffer = new ByteArrayOutputStream ();
240
- generateSvg ( language , buffer );
241
- final String svgDocument = buffer .toString ( StandardCharsets .UTF_8 );
242
- final String aspectName = aspect .getName ();
243
-
244
- for ( final Format format : targetFormats ) {
245
- try ( final OutputStream outputStream = nameMapper .apply ( format .getArtifactFilename ( aspectName , language ) ) ) {
246
- switch ( format ) {
247
- case PNG -> generatePng ( svgDocument , outputStream );
248
- default -> outputStream .write ( svgDocument .getBytes ( StandardCharsets .UTF_8 ) );
249
- }
250
- }
275
+ for ( final Format outputFormat : targetFormats ) {
276
+ final DiagramGenerationConfig config = DiagramGenerationConfigBuilder .builder ()
277
+ .language ( language )
278
+ .format ( outputFormat == Format .PNG ? DiagramGenerationConfig .Format .PNG : DiagramGenerationConfig .Format .SVG )
279
+ .build ();
280
+ final DiagramArtifact diagramArtifact = new AspectModelDiagramGenerator ( aspect (), config ).singleResult ();
281
+ IOUtils .copy ( new ByteArrayInputStream ( diagramArtifact .getContent () ), nameMapper .apply ( diagramArtifact .getId () ) );
251
282
}
252
283
}
253
284
@@ -261,9 +292,11 @@ public void generateDiagrams( final Set<Format> targetFormats, final Locale lang
261
292
* @param targetFormats The set of formats in which diagrams should be generated
262
293
* @param nameMapper The callback function that maps diagram artifact names to OutputStreams
263
294
* @throws IOException if a write error occurs
295
+ * @deprecated Use {@link #AspectModelDiagramGenerator(Aspect, DiagramGenerationConfig)} and {@link #generate(Function)} instead
264
296
*/
297
+ @ Deprecated ( forRemoval = true )
265
298
public void generateDiagrams ( final Set <Format > targetFormats , final Function <String , OutputStream > nameMapper ) throws IOException {
266
- for ( final Locale language : LanguageCollector .collectUsedLanguages ( aspect ) ) {
299
+ for ( final Locale language : LanguageCollector .collectUsedLanguages ( aspect () ) ) {
267
300
generateDiagrams ( targetFormats , language , nameMapper );
268
301
}
269
302
}
0 commit comments