Skip to content

Commit

Permalink
Merge pull request #507 from bci-oss/487-wrong-encoding-in-diagrams
Browse files Browse the repository at this point in the history
Generate UTF-8 encoded diagrams regardless of platform encoding
  • Loading branch information
atextor authored Jan 19, 2024
2 parents 2c2bd83 + 13b8f5b commit 679fdd2
Show file tree
Hide file tree
Showing 8 changed files with 240 additions and 232 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -142,15 +142,20 @@ private String base64EncodeInputStream( final InputStream in ) throws IOExceptio
}
}

public void generateSvg( final Locale language, final OutputStream out )
throws IOException {
/**
* Generates an SVG diagram for the Aspect in the given target language and write it to the given output stream.
* Note that the document will always be encoded in UTF-8, regardless of the platform's encoding.
* @param language the language
* @param out the output stream
* @throws IOException if writing to the output stream fails
*/
public void generateSvg( final Locale language, final OutputStream out ) throws IOException {
final DiagramVisitor diagramVisitor = new DiagramVisitor( language );
final AbstractDiagram diagram = aspectContext.aspect().accept( diagramVisitor, Optional.empty() );
final Diagram diagram = aspectContext.aspect().accept( diagramVisitor, Optional.empty() );
final Graphviz graphviz = render( diagram );

try ( final InputStream fontStream = getInputStream( FONT_FILE ) ) {
final String svgDocument = new String( graphviz.toSvgStr().getBytes( System.getProperty( "file.encoding" ) ),
StandardCharsets.UTF_8 )
final String svgDocument = graphviz.toSvgStr()
.replace( "<?xml version=\"1.0\" encoding=\"UTF-8\"?>", "" )
.replace( "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">", "" );

Expand All @@ -174,6 +179,7 @@ public void generateSvg( final Locale language, final OutputStream out )

/**
* Generates a diagram for the Aspect in the given output format and target language.
* Note that SVG documents will always be encoded in UTF-8, regardless of the platform's encoding.
*
* @param outputFormat One of SVG or PNG
* @param language The language for which the diagram should be generated
Expand All @@ -200,6 +206,7 @@ public void generateDiagram( final Format outputFormat, final Locale language, f
* The callback function will be called with the name of the diagram, which follows the format
* ASPECTNAME_XX.EXT where ASPECTNAME is the samm:name of the Aspect, XX is the language tag
* and EXT is the file extension for the respective output format.
* Note that SVG documents will always be encoded in UTF-8, regardless of the platform's encoding.
*
* @param outputFormat One of SVG or PNG
* @param nameMapper The callback function that maps diagram artifact names to OutputStreams
Expand All @@ -220,6 +227,7 @@ public void generateDiagrams( final Format outputFormat, final Function<String,
* The callback function will be called with the name of the diagram, which follows the format
* ASPECTNAME_XX.EXT where ASPECTNAME is the samm:name of the Aspect, XX is the language tag
* and EXT is the file extension for the respective output format.
* Note that SVG documents will always be encoded in UTF-8, regardless of the platform's encoding.
*
* @param targetFormats The set of formats in which diagrams should be generated
* @param language The language for which the diagram should be generated
Expand Down Expand Up @@ -248,6 +256,7 @@ public void generateDiagrams( final Set<Format> targetFormats, final Locale lang
* The callback function will be called with the name of the diagram, which follows the format
* ASPECTNAME_XX.EXT where ASPECTNAME is the samm:name of the Aspect, XX is the language tag
* and EXT is the file extension for the respective output format.
* Note that SVG documents will always be encoded in UTF-8, regardless of the platform's encoding.
*
* @param targetFormats The set of formats in which diagrams should be generated
* @param nameMapper The callback function that maps diagram artifact names to OutputStreams
Expand All @@ -259,16 +268,16 @@ public void generateDiagrams( final Set<Format> targetFormats, final Function<St
}
}

private Graphviz render( final AbstractDiagram diagram ) {
private Graphviz render( final Diagram diagram ) {
final Color bgColor = Color.ofRGB( "#cfdbed" );
final String fontName = "Roboto Condensed";
final Map<Box, Node> nodes = new HashMap<>();
final Map<Diagram.Box, Node> nodes = new HashMap<>();

final Graphviz.GraphvizBuilder graphvizBuilder = Graphviz.digraph()
.fontSize( 12f )
.tempNode( Node.builder().shape( NodeShapeEnum.PLAIN ).build() );

final Map<Box, Node> boxMap = diagram.getBoxes()
final Map<Diagram.Box, Node> boxMap = diagram.getBoxes()
.stream()
.map( box -> {
final Html.Table table = table()
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,15 @@
package org.eclipse.esmf.aspectmodel.generator.diagram;

record Context(
Box parent,
Diagram.Box parent,
String prototype,
String edgeLabel
) {
Context( final Box parent ) {
Context( final Diagram.Box parent ) {
this( parent, "", "" );
}

Context( final Box parent, final String prototype ) {
Context( final Diagram.Box parent, final String prototype ) {
this( parent, prototype, "" );
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,26 +13,31 @@

package org.eclipse.esmf.aspectmodel.generator.diagram;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

class AbstractDiagram {
/**
* An abstract representation of a diagram consisting of {@link Box}es and {@link Edge}s between them
*/
public class Diagram {
private final Box focusBox;
private final Set<Box> boxes;
private final Set<Edge> edges;

// Used for the special case where a value element is rendered as a string (as part of a parent's attribute)
private String scalarValue = null;

public AbstractDiagram( final Box focusBox ) {
public Diagram( final Box focusBox ) {
this.focusBox = focusBox;
boxes = new HashSet<>();
addBox( focusBox );
edges = new HashSet<>();
}

static final AbstractDiagram EMPTY = new AbstractDiagram( null );
static final Diagram EMPTY = new Diagram( null );

public void addBox( final Box box ) {
if ( box != null ) {
Expand All @@ -54,9 +59,9 @@ public void addEdges( final Collection<Edge> edges ) {
this.edges.addAll( edges );
}

public void add( final AbstractDiagram abstractDiagram ) {
addBoxes( abstractDiagram.getBoxes() );
addEdges( abstractDiagram.getEdges() );
public void add( final Diagram diagram ) {
addBoxes( diagram.getBoxes() );
addEdges( diagram.getEdges() );
}

public void setScalarValue( final String value ) {
Expand All @@ -78,4 +83,47 @@ public Box getFocusBox() {
public String getScalarValue() {
return scalarValue;
}

/**
* A box in the diagram with a prototype, title and a list of entries
*/
public static class Box {
private String prototype;
private final String title;
private final List<String> entries = new ArrayList<>();

public Box( final String prototype, final String title ) {
this.prototype = prototype;
this.title = title;
}

public void addEntry( final List<String> entry ) {
entries.addAll( entry );
}

public void setPrototype( final String prototype ) {
this.prototype = prototype;
}

public String getPrototype() {
return prototype;
}

public String getTitle() {
return title;
}

public List<String> getEntries() {
return entries;
}
}

/**
* An edge between two {@link Box}es
* @param from the source box
* @param to the target box
* @param label the label on the edge
*/
public record Edge( Box from, Box to, String label ) {
}
}
Loading

0 comments on commit 679fdd2

Please sign in to comment.