Location>code7788 >text

Step-by-step export of PlantUML class diagrams to a customized format XMI file

Popularity:521 ℃/2024-09-08 01:02:01

Step-by-step export of PlantUML class diagrams to a customized format XMI file

Description:

  • First published: 2024-09-08
  • PlantUML official website:/zh/
  • PlantUML command line documentation:/zh/command-line#6a26f548831e6a8c
  • PlantUML XMI documentation./zh/xmi
  • Further use: generating code from exported XMI files

Getting class diagrams in PlantUML (Java) and how plantuml xmi code traverses entities and gets attributes

The following is from/questions/76599075/parse-uml-class-diagram-with-plantuml-java-api of the code:

String source = "@startuml\n" +
            PUT YOUR CLASS DIAGRAM HERE
            "@enduml";

SourceStringReader r = new SourceStringReader(source);
FileOutputStream file = new FileOutputStream("");
ClassDiagram cd = (ClassDiagram) ().get(0).getDiagram();
Collection<Quark<Entity>> classes = 
().root().getChildren();
().forEach(c-> (c));

Know how to get ClassDiagram from

ferret out centerXmiClassDiagramStandardDefinition of:

public class XmiClassDiagramStandard extends XmiClassDiagramAbstract implements XmlDiagramTransformer {
    public XmiClassDiagramStandard(ClassDiagram classDiagram) throws ParserConfigurationException {
        super(classDiagram);
        Iterator var2 = ().leafs().iterator();

        while(()) {
            Entity ent = (Entity)();
            Element cla = (ent);
            if (cla != null) {
                (cla);
                (ent);
            }
        }

    }
}

From this, we know how to traverse the entity

ferret out hit the nail on the headcreateEntityNodeMethods:

    protected final Element createEntityNode(Entity entity) {
        Element cla = ("UML:Class");
        if (() == ) {
            return null;
        } else {
            ("", ());
            ("name", ().get(0).toString());
            Stereotype stereotype = ();
            if (stereotype != null) {
                Element stereo = ("UML:");
                Iterator var5 = ().iterator();

                while(()) {
                    String s = (String)();
                    Element name = ("UML:Stereotype");
                    ("name", s);
                    (name);
                }

                (stereo);
            }

            LeafType type = ();
            if (type == LeafType.ABSTRACT_CLASS) {
                ("isAbstract", "true");
            } else if (type == ) {
                ("isInterface", "true");
            }

            if (()) {
                ("isStatic", "true");
            }

            if (() == VisibilityModifier.PRIVATE_FIELD || () == VisibilityModifier.PRIVATE_METHOD) {
                ("visibility", ().getXmiVisibility());
            }

            Element feature = ("UML:");
            (feature);

            Member m;
            Element operation;
            VisibilityModifier visibility;
            ListIterator var13;
            CharSequence cs;
            for(var13 = ().getFieldsToDisplay().iterator(); (); (operation)) {
                cs = (CharSequence)();
                m = (Member)cs;
                operation = ("UML:Attribute");
                ("", "att" + ());
                ("name", (false));
                visibility = ();
                if (visibility != null) {
                    ("visibility", ());
                }

                if (()) {
                    ("isStatic", "true");
                }
            }

            for(var13 = ().getMethodsToDisplay().iterator(); (); (operation)) {
                cs = (CharSequence)();
                m = (Member)cs;
                operation = ("UML:Operation");
                ("", "att" + ());
                ("name", (false));
                visibility = ();
                if (visibility != null) {
                    ("visibility", ());
                }

                if (()) {
                    ("isStatic", "true");
                }
            }

            return cla;
        }
    }

As you can see from this:

  • ().getFieldsToDisplay().iterator() is an iterator that gets the entity's attribute.
  • ().getMethodsToDisplay().iterator() is an iterator that gets the entity's operation.
  • nameisAbstractisInterface cap (a poem)isStatic How these attributes are obtained

there are/plantuml/plantuml/pull/1298/files It's a PR from February 2023 (not yet Merge at the time of writing this article) that can be used as a reference (to be read).

Exporting PlantUML Class Diagrams to XMI Using JAVA Code

By calling the exportDiagram method

import ;  
import ;  
import ;

import ;

public class Main {  
    public static void main(String[] args) throws IOException {
        OutputStream output = new FileOutputStream("");
        
        FileFormatOption fileFormatOption = new FileFormatOption(FileFormat.XMI_ARGO);

        String content = new String((("")));
        SourceStringReader reader = new SourceStringReader(content);

        ().get(0).getDiagram().exportDiagram(output, 0, fileFormatOption);
    }
}

included among theseFileFormatis an enumeration that defines theXMI_STANDARDXMI_STARcap (a poem)XMI_ARGOiso-format

Analyzing the call chain of getDiagram

getDiagramMethods fromofferedexportDiagraminterface method, its implementation:

    public final ImageData exportDiagram(OutputStream os, int index, FileFormatOption fileFormatOption) throws IOException {
        long now = ();

        ImageData var6;
        try {
            var6 = (os, index, fileFormatOption);
        } finally {
            if (().isEnableStats()) {
                (() - now, (), ());
            }

        }

        return var6;
    }

which is mainly a call to thehit the nail on the headexportDiagramNowinterface method. And its interface methods in theThe implementation in is as follows:

    protected final ImageData exportDiagramNow(OutputStream os, int index, FileFormatOption fileFormatOption) throws IOException {
        fileFormatOption = (().getTikzFontDistortion());
        if (() == ) {
            return (os, index);
        } else {
            try {
                ImageData imageData = (os, index, fileFormatOption);
                 = new XDimension2D((double)(), (double)());
                return imageData;
            } catch (NoStyleAvailableException var5) {
                (os, var5, fileFormatOption, (String)null);
                return (var5);
            } catch (UnparsableGraphvizException var6) {
                (var6);
                (os, (), fileFormatOption, ());
                return (var6);
            } catch (Throwable var7) {
                (os, var7, fileFormatOption, (String)null);
                return (var7);
            }
        }
    }

It can be seen that it mainly calls theinterface method, since the current class isClassDiagramIt will call thepracticalexportDiagramInternalMethods:

    protected final ImageData exportDiagramInternal(OutputStream os, int index, FileFormatOption fileFormatOption) throws IOException {
        return  != 0 ? (os, index, fileFormatOption) : (os, index, fileFormatOption);
    }

included among thesepredecessorpredecessorpredecessor

(indicates contrast)The part of the method that deals with XMI is as follows:

                (os, fileFormat);
                return ();

It calls themethod, which is defined below:

    private void createFilesXmi(OutputStream suggestedFile, FileFormat fileFormat) throws IOException {
        CucaDiagramXmiMaker maker = new CucaDiagramXmiMaker(this, fileFormat);
        (suggestedFile);
    }

which calls the(used form a nominal expression)createFilesmethod, which is defined below:

    public void createFiles(OutputStream fos) throws IOException {
        try {
            Object xmi;
            if ( instanceof StateDiagram) {
                xmi = new XmiStateDiagram((StateDiagram));
            } else if ( instanceof DescriptionDiagram) {
                xmi = ();
            } else {
                if (!( instanceof ClassDiagram)) {
                    throw new UnsupportedOperationException("Diagram type " + () + " is not supported in XMI");
                }

                xmi = ();
            }

            ((XmlDiagramTransformer)xmi).transformerXml(fos);
        } catch (ParserConfigurationException var3) {
            (());
            (var3);
            throw new IOException(());
        } catch (TransformerException var4) {
            (());
            (var4);
            throw new IOException(());
        }
    }

You can see the key 2 behaviors involved in creating an xmi file:

xmi = ();
((XmlDiagramTransformer)xmi).transformerXml(fos);

(indicates contrast)createClassDiagramThe definitions are as follows:

    private XmlDiagramTransformer createClassDiagram() throws ParserConfigurationException {
        if ( == FileFormat.XMI_STANDARD) {
            return new XmiClassDiagramStandard((ClassDiagram));
        } else if ( == FileFormat.XMI_ARGO) {
            return new XmiClassDiagramArgo((ClassDiagram));
        } else if ( == FileFormat.XMI_SCRIPT) {
            return new XmiClassDiagramScript((ClassDiagram));
        } else if ( == FileFormat.XMI_STAR) {
            return new XmiClassDiagramStar((ClassDiagram));
        } else {
            throw new UnsupportedOperationException();
        }
    }

After analyzing the getDiagram method, call the internal API to export the XMI

import ;  
import ;  
import ;
import ;

import ;
import ;

import ;

public class Main {  
    public static void main(String[] args) throws IOException, ParserConfigurationException, TransformerException {
        OutputStream fos = new FileOutputStream("");
        
        FileFormatOption fileFormatOption = new FileFormatOption(FileFormat.XMI_ARGO);

        String content = new String((("")));
        SourceStringReader reader = new SourceStringReader(content);
        ClassDiagram classDiagram = (ClassDiagram) ().get(0).getDiagram();

        Object xmi = new XmiClassDiagramArgo(classDiagram);
        ((XmlDiagramTransformer)xmi).transformerXml(fos);
    }
}

Reads an uml file and prints its properties.

Now that you know a bit more, use the following Java code to view the information in the UML file

package ;

import ;
import ;
import ;
import ;
import ;
import ;
import ;

import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;

import ;


public class Main {
    public static void main(String[] args) throws IOException, ParserConfigurationException, TransformerException {
        OutputStream output = new FileOutputStream("");
//        String source = "@startuml\n";
//        source += "Bob -> Alice : hello\n";
//        source += "@enduml\n";
        String content = new String((("")));

        SourceStringReader reader = new SourceStringReader(content);
        ClassDiagram classDiagram = (ClassDiagram) ().get(0).getDiagram();

        String titleName = ().get(0).toString();
        ("title: " + titleName);
        Iterator var2 = ().leafs().iterator();

        while(()) {
            Entity entity = (Entity)();

            ("----------------------------------");
            ("uid: " + ());
            if (() == ) {
//                ();
//                ("Entity type: " + ());
            } else {

                Iterator var1 = ().iterator();
                while(()) {
                    Link link = (Link)();
                    if ((entity)) {
                        Entity other = (entity);
                        if (() == ) {
                            ("Note: "  + ().get(0).toString());
                        }
                    }
                }

                ("Entity type: " + ());

                String entityName = ().get(0).toString();
                ("Entity name: " + entityName);
                ("Package: " + ().getParent().toString());

                LeafType type = ();

                if (type == LeafType.ABSTRACT_CLASS) {
                    ("isAbstract");
                } else if (type == ) {
                    ("isInterface");
                }

                if (()) {
                    (("isStatic"));
                }

                if (() == VisibilityModifier.PRIVATE_FIELD || () == VisibilityModifier.PRIVATE_METHOD) {
                    ("visibility: " + ().getXmiVisibility());
                }

                Member m;
                VisibilityModifier visibility;
                ListIterator var13;
                CharSequence cs;
                for (var13 = ().getFieldsToDisplay().iterator(); ();) {
                    cs = (CharSequence)();
                    m = (Member) cs;
                    ("field name: " + (false));
                    visibility = ();
                    if (visibility != null) {
                        ("visibility: " + ());
                    }

                    if (()) {
                        ("isStatic");
                    }
                }

                for (var13 = ().getMethodsToDisplay().iterator(); ();) {
                    cs = (CharSequence)();
                    m = (Member) cs;
                    ("operation name: " + (false));

                    visibility = ();
                    if (visibility != null) {
                        ("visibility: " + ());
                    }

                    if (()) {
                        ("isStatic");
                    }
                }
            }

        }

// Write the first image to "png"
//        String desc = (output).getDescription();
// Return a null string if no generation
    }
}

Creating a JAVA project and packaging it as a JAR package: Exporting PlantUML to a custom formatted XMI file

Create a project

Create a maven project using IDEA and open the plantuml maven repository page:/artifact//plantuml/1.2024.6 Copy the dependency tag into the

Add classes for customizing the XMI format

Since it is not possible to quote theXmiClassDiagramAbstract(draw attention to sth. is not public in ''. Cannot be accessed from outside package),thus insrc/main/javaCreate a new package under

Then add the classXmiClassDiagramCustom(extends XmiClassDiagramAbstract):

package ;

import ;
import ;
import ;

import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import org.;

public class XmiClassDiagramCustom extends XmiClassDiagramAbstract implements XmlDiagramTransformer {
    public XmiClassDiagramCustom(ClassDiagram classDiagram) throws ParserConfigurationException {
        super(classDiagram);
        Iterator var2 = ().leafs().iterator();

        Element titleElement = ("UML:Title");
        ("name", ().get(0).toString());
        (titleElement);

        while(()) {
            Entity ent = (Entity)();
            Element cla = (ent, classDiagram);
            if (cla != null) {
                (cla);
                (ent);
            }
        }

        var2 = ().iterator();

        while(()) {
            Link link = (Link)();
            (link);
        }

    }

    protected final Element createEntityNodeCustom(Entity entity, ClassDiagram classDiagram) {
        Element cla = ("UML:Class");
        if (() == ) {
            return null;
        } else {
            ("", ());
            ("name", ().get(0).toString());

            // Get Note:
            Iterator var1 = ().iterator();
            while(()) {
                Link link = (Link)();
                if ((entity)) {
                    Entity other = (entity);
                    if (() == ) {
                        ("note", ().get(0).toString());
//                        ("Note: "  + ().get(0).toString());
                    }
                }
            }

            ("package", ().getParent().toString());

            Stereotype stereotype = ();
            if (stereotype != null) {
                Element stereo = ("UML:");
                Iterator var5 = ().iterator();

                while(()) {
                    String s = (String)();
                    Element name = ("UML:Stereotype");
                    ("name", s);
                    (name);
                }

                (stereo);
            }

            LeafType type = ();
            if (type == LeafType.ABSTRACT_CLASS) {
                ("isAbstract", "true");
            } else if (type == ) {
                ("isInterface", "true");
            }

            if (()) {
                ("isStatic", "true");
            }

            if (() == VisibilityModifier.PRIVATE_FIELD || () == VisibilityModifier.PRIVATE_METHOD) {
                ("visibility", ().getXmiVisibility());
            }

            Element feature = ("UML:");
            (feature);

            Member m;
            Element operation;
            VisibilityModifier visibility;
            ListIterator var13;
            CharSequence cs;
            for(var13 = ().getFieldsToDisplay().iterator(); (); (operation)) {
                cs = (CharSequence)();
                m = (Member)cs;
                operation = ("UML:Attribute");
                ("", "att" + ());
                ("name", (false));
                visibility = ();
                if (visibility != null) {
                    ("visibility", ());
                }

                if (()) {
                    ("isStatic", "true");
                }
            }

            for(var13 = ().getMethodsToDisplay().iterator(); (); (operation)) {
                cs = (CharSequence)();
                m = (Member)cs;
                operation = ("UML:Operation");
                ("", "att" + ());
                ("name", (false));
                visibility = ();
                if (visibility != null) {
                    ("visibility", ());
                }

                if (()) {
                    ("isStatic", "true");
                }
            }

            return cla;
        }
    }

    // copy from XmiClassDiagramStar
    private void addLink(Link link) {
        if (!() && !()) {
            String assId = "ass" + ();
            if (().getDecor1() !=  && ().getDecor2() != ) {
                Element association = ("UML:Association");
                ("", assId);
                ("namespace", ());
                if (!(())) {
                    ("name", (()));
                }

                Element connection = ("UML:");
                Element end1 = ("UML:AssociationEnd");
                ("", "end" + ());
                ("association", assId);
                ("type", link.getEntity1().getUid());
                if (link.getQuantifier1() != null) {
                    ("name", (link.getQuantifier1()));
                }

                Element endparticipant1 = ("UML:");
                if (().getDecor2() == ) {
                    ("aggregation", "composite");
                }

                if (().getDecor2() == ) {
                    ("aggregation", "aggregate");
                }

                (endparticipant1);
                (end1);
                Element end2 = ("UML:AssociationEnd");
                ("", "end" + ());
                ("association", assId);
                ("type", link.getEntity2().getUid());
                if (link.getQuantifier2() != null) {
                    ("name", (link.getQuantifier2()));
                }

                Element endparticipant2 = ("UML:");
                if (().getDecor1() == ) {
                    ("aggregation", "composite");
                }

                if (().getDecor1() == ) {
                    ("aggregation", "aggregate");
                }

                (endparticipant2);
                (end2);
                (connection);
                (association);
            } else {
                (link, assId);
            }
        }
    }

    // copy from XmiClassDiagramStar
    private void addExtension(Link link, String assId) {
        Element association = ("UML:Generalization");
        ("", assId);
        ("namespace", ());
        if (() != null) {
            ("name", (()));
        }

        if (().getDecor1() == ) {
            ("child", link.getEntity1().getUid());
            ("parent", link.getEntity2().getUid());
        } else {
            if (().getDecor2() != ) {
                throw new IllegalStateException();
            }

            ("child", link.getEntity2().getUid());
            ("parent", link.getEntity1().getUid());
        }

        (association);
    }
}

Add export class (portal)

Adding a packageand add classesUML2XMIExporter

package ;

import ;
import ;

import ;
import ;
import ;
import ;
import ;
import ;


import ;
import ;

public class UML2XMIExporter {
    public static void main(String[] args) throws IOException, ParserConfigurationException, TransformerException {

        String content = new String(((args[0])));
        OutputStream outputCustom = ((args[1]));

        SourceStringReader reader = new SourceStringReader(content);
        ClassDiagram classDiagram = (ClassDiagram) ().get(0).getDiagram();

        // deriveXMI
        XmlDiagramTransformer xmi = new XmiClassDiagramCustom(classDiagram);
        (outputCustom);

    }
}

ask for a doggy bag (at a restaurant)

Next, refer to/weixin_41229430/article/details/138963215 Packaged as a jar package

Create a file: src/main/assembly/ with the following contents:

<assembly>
    <id>assembly</id>
    <formats>
        <format>zip</format>
        <format>jar</format>
        <format></format>
    </formats>
    <includeBaseDirectory>false</includeBaseDirectory>
    <fileSets>
        <!--   -->
        <fileSet>
            <directory>src/main/resources</directory>
            <outputDirectory>conf</outputDirectory>
            <includes>
                <include>*.xml</include>
                <include>*.properties</include>
                <include>**/*.xml</include>
                <include>**/*.properties</include>
            </includes>
            <fileMode>0644</fileMode>
        </fileSet>
        <fileSet>
            <directory>assembly/bin</directory>
            <outputDirectory>bin</outputDirectory>
            <fileMode>0755</fileMode>
        </fileSet>
    </fileSets>
    <dependencySets>
        <dependencySet>
            <outputDirectory>lib</outputDirectory>
        </dependencySet>
    </dependencySets>
</assembly>

Then add the

    <build>
        <plugins>
            <!--Primarily for use in placing Maven Packaging of projects into executable programs or distribution packages -->
            <plugin>
                <groupId></groupId>
                <artifactId>maven-assembly-plugin</artifactId>
                <version>3.3.0</version>
                <executions>
                    <execution>
                        <id>make-assembly2</id><!--Any name -->
                        <phase>package</phase><!-- Bind topackagelife cycle stage -->
                        <goals>
                            <goal>single</goal><!-- Run only once -->
                        </goals>
                        <configuration>
                            <descriptors>
                                <descriptor>${basedir}/src/main/assembly/</descriptor>
                            </descriptors>
                            <archive>
                                <manifest>
                                    <mainClass>.UML2XMIExporter</mainClass>
                                    <addClasspath>true</addClasspath>
                                    <classpathPrefix>lib/</classpathPrefix>
                                    <useUniqueVersions>false</useUniqueVersions>
                                </manifest>
                            </archive>
                            <descriptorRefs>
                                <descriptorRef>jar-with-dependencies</descriptorRef>
                            </descriptorRefs>
                        </configuration>
                    </execution>
                </executions>
            </plugin>

            <plugin>
                <groupId></groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
        </plugins>
    </build>

Click on the m icon (maven) on the right side of IDEA and double click on package under Lifecycle. then you can see in the target directory that the jar package has been generated.

Open comman prompt command line (do not use powershell) and run it:

java -=UTF-8 -jar custom-plantuml-xmi-export-1.