How to create PlantUML diagram using Java API without using PlantUML diagram code?

Viewed 593

In my Java application I want to use PlantUML to create diagrams. I want to create diagrams in PlantUML using it's Java API without using PlantUML diagram code. Unfortunately there is a lack of examples or documentation of this on internet and the only documented API is the one that generates diagram from diagram code as string and that doesn't help me. What API in PlantUML can be used to create diagram in this way?

1 Answers

It doesn't look to me like PlantUML is designed to be used in this way: the API isn't documented. Having said that, it's an open source project, so you can download the sources and follow the execution for a given UML string, then recreate that execution with method calls avoiding the UML source, if that's what you need. If you have a debugger that can step through third party code, like IntelliJ, that will help a lot.

I had a little go at that. Here's a class which will generate the "Bob -> Alice : hello" diagram using the Java API without going via UML source string. I included the UML string version for comparison:

import net.sourceforge.plantuml.FileFormat;
import net.sourceforge.plantuml.FileFormatOption;
import net.sourceforge.plantuml.SourceStringReader;
import net.sourceforge.plantuml.core.ImageData;
import net.sourceforge.plantuml.cucadiagram.Display;
import net.sourceforge.plantuml.sequencediagram.Message;
import net.sourceforge.plantuml.sequencediagram.Participant;
import net.sourceforge.plantuml.sequencediagram.SequenceDiagram;
import net.sourceforge.plantuml.sequencediagram.SequenceDiagramFactory;
import net.sourceforge.plantuml.skin.ArrowConfiguration;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;

import static com.google.common.base.Preconditions.checkState;

public class PlantUMLDemoMain {
    public static void main(String[] args) throws Exception {
        generateFromStringSource(new File("from-string.png"));
        generateFromApi(new File("from-api.png"));
    }

    private static void generateFromApi(File file) throws IOException {
        // 1. setup:
        SequenceDiagramFactory f = new SequenceDiagramFactory();
        SequenceDiagram diagram = f.createEmptyDiagram();

        // 2. Build the diagram:
        // "Bob -> Alice : hello"
        // See net.sourceforge.plantuml.sequencediagram.command.CommandArrow#executeArg
        Display bobD = Display.getWithNewlines("Bob");
        Participant bobP = diagram.getOrCreateParticipant("Bob", bobD);

        Display aliceD = Display.getWithNewlines("Alice");
        Participant aliceP = diagram.getOrCreateParticipant("Alice", aliceD);

        Display label = Display.getWithNewlines("hello");
        ArrowConfiguration config = ArrowConfiguration.withDirectionNormal();

        Message msg = new Message(bobP, aliceP, label, config, diagram.getNextMessageNumber());

        checkState(null == diagram.addMessage(msg));

        // 3. Output the diagram
        // See net.sourceforge.plantuml.SourceStringReader#generateImage
        diagram.makeDiagramReady();
        checkState(1 == diagram.getNbImages());
        try (OutputStream os = new FileOutputStream(file)) {
            ImageData imageData = diagram.exportDiagram(os, 0, new FileFormatOption(FileFormat.PNG));
            System.out.println("generateFromApi: " + diagram.getDescription().getDescription());
        }
    }

    private static void generateFromStringSource(File file) throws IOException {
        String source = "@startuml\n";
        source += "Bob -> Alice : hello\n";
        source += "@enduml\n";

        SourceStringReader reader = new SourceStringReader(source);
        // Write the first image to "png"
        String desc = reader.generateImage(file);
        // Return a null string if no generation
        System.out.println("generateFromStringSource: " + desc);
    }
}

This will build with a build.sbt file like this:

libraryDependencies += "net.sourceforge.plantuml" % "plantuml" % "8059"
libraryDependencies += "com.google.guava" % "guava" % "31.0.1-jre"

The output of generateFromApi is identical to generateFromStringSource and looks like this:

from-api.png

Related