All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.nuiton.eugene.plantuml.PlantumlTemplatesGenerator Maven / Gradle / Ivy

package org.nuiton.eugene.plantuml;

/*
 * #%L
 * EUGene :: PlantUML templates
 * %%
 * Copyright (C) 2013 - 2017 Code Lutin, Ultreia.io
 * %%
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as 
 * published by the Free Software Foundation, either version 3 of the 
 * License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Lesser Public License for more details.
 * 
 * You should have received a copy of the GNU General Lesser Public 
 * License along with this program.  If not, see
 * .
 * #L%
 */

import net.sourceforge.plantuml.GeneratedImage;
import net.sourceforge.plantuml.SourceFileReader;
import org.nuiton.eugene.models.object.ObjectModel;
import org.nuiton.eugene.models.object.ObjectModelAttribute;
import org.nuiton.eugene.models.object.ObjectModelClass;
import org.nuiton.eugene.models.object.ObjectModelClassifier;
import org.nuiton.eugene.models.object.ObjectModelEnumeration;
import org.nuiton.eugene.models.object.ObjectModelGenerator;
import org.nuiton.eugene.models.object.ObjectModelInterface;
import org.nuiton.eugene.models.object.ObjectModelOperation;
import org.nuiton.eugene.models.object.ObjectModelParameter;
import org.nuiton.eugene.models.object.reader.yaml.KeyWords;
import org.nuiton.eugene.models.object.reader.yaml.YamlUtil;

import java.io.File;
import java.io.IOException;
import java.io.Writer;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * @author agiraudet - [email protected]
 * @plexus.component role="org.nuiton.eugene.Template" role-hint="org.nuiton.eugene.plantuml.PlantumlTemplatesGenerator"
 * @since 2.6.4
 */

//TODO: utiliser systeme de template

public class PlantumlTemplatesGenerator extends ObjectModelGenerator implements KeyWords {

    @Override
    public void generateFromModel(Writer output, ObjectModel input) throws IOException {
        output.write("@startuml\n\n");

        String nameM = "", versionM = "", packageM = "";
        if (input.getName() != null) {
            nameM = input.getName();
        }
        if (input.getVersion() != null) {
            versionM = input.getVersion();
        }
        if (input.getTagValue(PACKAGE) != null) {
            packageM = input.getTagValue(PACKAGE) + " ";
        } else {
            packageM = findPackage(input) + " ";
        }
        output.write("note \"" + nameM + " " + versionM + "\" as N1\n\n");
        output.write("package " + packageM + "{\n\n");
        String indent = "  ";
        for (ObjectModelClass objectModelClass : input.getClasses()) {
            generateFromClass(output, objectModelClass, indent);
        }
        for (ObjectModelInterface objectModelInterface : input.getInterfaces()) {
            generateFromInterface(output, objectModelInterface, indent);
        }
        for (ObjectModelEnumeration objectModelEnumeration : input.getEnumerations()) {
            generateFromEnumeration(output, objectModelEnumeration, indent);
        }
        generateFromLinks(output, input, indent);
        output.write("\n");
        output.write("}\n");
        output.write("@enduml");
    }

    @Override
    public void applyTemplate(ObjectModel model, File destDir) throws IOException {
        super.applyTemplate(model, destDir);

        File plantuml = new File(destDir + File.separator + this.getFilenameForModel(model));
        SourceFileReader reader = new SourceFileReader(plantuml);
        List lst = reader.getGeneratedImages();
        new File(lst.get(0).getPngFile(), destDir + File.separator + model.getName() + ".png");
    }

    @Override
    public String getFilenameForModel(ObjectModel model) {
        return model.getName() + ".plantuml";
    }

    public void generateFromClass(Writer output, ObjectModelClass input, String indent) throws IOException {
        String name = "", stereotype = "", isAbstract = "";
        if (input.getName() != null) {
            name = input.getName() + " ";
        }
        if (input.getStereotypes() != null) {
            stereotype = getFromStereotypes(input.getStereotypes()) + " ";
        }
        if (input.isAbstract()) {
            isAbstract = "abstract ";
        }
        output.write(indent + isAbstract + "class " + name + stereotype + "{\n");
        if (input.getAttributes() != null && !input.getAttributes().isEmpty()) {
            generateFromAttributes(output, input.getAttributes(), indent + "  ");
        }
        output.write(indent + "  ..\n");
        if (input.getOperations() != null) {
            generateFromOperations(output, input.getOperations(), indent + "  ");
        }
        output.write(indent + "}\n");

        if (input.getSuperclasses() != null) {
            generateFromSuperClasses(output, input.getSuperclasses(), name, indent);
        }
        if (input.getInterfaces() != null) {
            generateFromSuperInterfaces(output, input.getInterfaces(), name, indent);
        }
        output.write("\n");
    }

    public void generateFromInterface(Writer output, ObjectModelInterface input, String indent) throws IOException {
        String name = "", stereotype = "";
        if (input.getName() != null) {
            name = input.getName() + " ";
        }
        if (input.getStereotypes() != null) {
            stereotype = getFromStereotypes(input.getStereotypes()) + " ";
        }
        output.write(indent + "class " + name + stereotype + "{\n");
        if (input.getAttributes() != null && !input.getAttributes().isEmpty()) {
            generateFromAttributes(output, input.getAttributes(), indent + "  ");
        }
        output.write(indent + "  ..\n");
        if (input.getOperations() != null) {
            generateFromOperations(output, input.getOperations(), indent + "  ");
        }
        output.write(indent + "}\n");

        if (input.getInterfaces() != null) {
            generateFromSuperInterfaces(output, input.getInterfaces(), name, indent);
        }
        output.write("\n");
    }

    public void generateFromEnumeration(Writer output, ObjectModelEnumeration input, String indent) throws IOException {
        String name = "", stereotype = "";
        if (input.getName() != null) {
            name = input.getName() + " ";
        }
        if (input.getStereotypes() != null) {
            stereotype = getFromStereotypes(input.getStereotypes()) + " ";
        }
        output.write(indent + "enum " + name + stereotype + "{\n");
        if (input.getLiterals() != null && !input.getAttributes().isEmpty()) {
            for (String literal : input.getLiterals()) {
                output.write(indent + "  " + literal.toUpperCase() + "\n");
            }
        }
        output.write(indent + "  ..\n");
        if (input.getOperations() != null) {
            generateFromOperations(output, input.getOperations(), indent + "  ");
        }
        output.write(indent + "}\n");

        output.write("\n");
    }

    public String getFromStereotypes(Set stereotypes) {
        StringBuilder stereotype = new StringBuilder("");
        if (stereotypes.size() > 0) {
            stereotype.append("<< ");
            boolean first = true;
            for (String str : stereotypes) {
                if (first) {
                    first = false;
                } else {
                    stereotype.append(", ");
                }
                stereotype.append(str);
            }
            stereotype.append(" >>");
        }
        return stereotype.toString();
    }

    public void generateFromAttributes(Writer output, Collection input, String indent) throws IOException {
        for (ObjectModelAttribute attribute : input) {
            if (!attribute.referenceClassifier()) {
                String visibility = "";
                if (attribute.getVisibility() != null) {
                    if (attribute.getVisibility().equals(PUBLIC)) {
                        visibility = "+ ";
                    } else if (attribute.getVisibility().equals(PROTECTED)) {
                        visibility = "# ";
                    } else if (attribute.getVisibility().equals(PRIVATE)) {
                        visibility = "- ";
                    }
                }
                String type = "", name = "";
                if (attribute.getType() != null) {
                    type = reduceType(attribute.getType()) + " ";
                }
                if (attribute.getName() != null) {
                    name = attribute.getName();
                }
                output.write(indent + visibility + type + name + "\n");
            }
        }
    }

    public void generateFromOperations(Writer output, Collection input, String indent) throws IOException {
        for (ObjectModelOperation operation : input) {
            String isAbstract = "", isStatic = "", parameters = "", name = "", returnParameter = "";
            if (operation.isAbstract()) {
                isAbstract = "{abstract} ";
            }
            if (operation.isStatic()) {
                isAbstract = "{static} ";
            }
            String visibility = "";
            if (operation.getVisibility() != null) {
                if (operation.getVisibility().equals(PUBLIC)) {
                    visibility = "+ ";
                } else if (operation.getVisibility().equals(PROTECTED)) {
                    visibility = "# ";
                } else if (operation.getVisibility().equals(PRIVATE)) {
                    visibility = "- ";
                }
            }
            if (operation.getParameters() != null) {
                StringBuilder tmp = new StringBuilder("");
                boolean first = true;
                for (ObjectModelParameter parameter : operation.getParameters()) {
                    if (first) {
                        first = false;
                    } else {
                        tmp.append(", ");
                    }
                    if (parameter.getType() != null) {
                        tmp.append(reduceType(parameter.getType())).append(" ");
                    }
                    if (parameter.getName() != null) {
                        tmp.append(parameter.getName());
                    }
                }
                parameters = tmp.toString();
            }
            if (operation.getReturnParameter() != null) {
                if (operation.getReturnParameter().getType() != null) {
                    returnParameter = reduceType(operation.getReturnParameter().getType()) + " ";
                }
            }
            if (operation.getName() != null) {
                name = operation.getName();
            }
            output.write(indent + isAbstract + isStatic + visibility + returnParameter + name + "(" + parameters + ")\n");
        }
    }

    public void generateFromSuperClasses(Writer output, Collection input, String name, String indent) throws IOException {
        for (ObjectModelClass superClass : input) {
            String superClassName = "";
            if (superClass.getName() != null) {
                superClassName = superClass.getName();
            }
            output.write(indent + superClassName + " <|-- " + name + "\n");
        }
    }

    public void generateFromSuperInterfaces(Writer output, Collection input, String name, String indent) throws IOException {
        for (ObjectModelInterface superInterface : input) {
            String superInterfaceName = "";
            if (superInterface.getName() != null) {
                superInterfaceName = superInterface.getName();
            }
            output.write(indent + superInterfaceName + " <|.. " + name + "\n");
        }
    }

    public void generateFromLinks(Writer output, ObjectModel input, String indent) throws IOException {
        Map attributesM = new LinkedHashMap<>();
        List bin = new LinkedList<>();//bin au sens poubelle

        for (ObjectModelClassifier classifier : input.getClassifiers()) {
            if (classifier.getAttributes() != null) {
                for (ObjectModelAttribute attribute : classifier.getAttributes()) {
                    if (attribute.referenceClassifier()) {
                        attributesM.put(attribute, classifier);
                    }
                }
            }
        }

        for (Map.Entry entry : attributesM.entrySet()) {
            ObjectModelAttribute attribute = entry.getKey();
            ObjectModelClassifier classifier = entry.getValue();
            if (attribute.isNavigable()) {
                String attributeName = "";
                if (attribute.getName() != null) {
                    attributeName = attribute.getName();
                }
                String associationType = "";
                if (attribute.isComposite()) {
                    associationType = "*";
                } else if (attribute.isAggregate()) {
                    associationType = "o";
                }
                String minMultiplicity = (attribute.getMinMultiplicity() == -1) ? "*" : String.valueOf(attribute.getMinMultiplicity());
                String maxMultiplicity = (attribute.getMaxMultiplicity() == -1) ? "*" : String.valueOf(attribute.getMaxMultiplicity());
                String multiplicity = (minMultiplicity.equals(maxMultiplicity)) ? minMultiplicity : minMultiplicity + ".." + maxMultiplicity;
                String type = YamlUtil.afterChar(attribute.getType(), '.');
                if (!bin.contains(attribute)) {
                    if (attribute.getReverseAttribute() != null) {
                        ObjectModelAttribute reverseAttribute = attribute.getReverseAttribute();
                        String reverseAttributeName = "";
                        if (reverseAttribute.getName() != null) {
                            reverseAttributeName = reverseAttribute.getName();
                        }
                        String reverseMinMultiplicity = (reverseAttribute.getMinMultiplicity() == -1) ? "*" : String.valueOf(reverseAttribute.getMinMultiplicity());
                        String reverseMaxMultiplicity = (reverseAttribute.getMaxMultiplicity() == -1) ? "*" : String.valueOf(reverseAttribute.getMaxMultiplicity());
                        String reverseMultiplicity = (reverseMinMultiplicity.equals(reverseMaxMultiplicity)) ? reverseMinMultiplicity : reverseMinMultiplicity + ".." + reverseMaxMultiplicity;
                        String reverseType = YamlUtil.afterChar(reverseAttribute.getType(), '.');
                        if (reverseAttribute.isNavigable())//lien bi-directionnel
                        {
                            //tenir compte du type d'association ?
                            output.write(indent + type + " \"" + multiplicity + " " + attributeName + "\" -- \"" + reverseMultiplicity + " " + reverseAttributeName + "\" " + reverseType + "\n");
                            if (attribute.getAssociationClass() != null && reverseAttribute.getAssociationClass() != null && attribute.getAssociationClass().equals(reverseAttribute.getAssociationClass())) {
                                String associationClassName = "";
                                if (attribute.getAssociationClass().getName() != null) {
                                    associationClassName = attribute.getAssociationClass().getName();
                                }
                                output.write(indent + "(" + type + ", " + reverseType + ") . " + associationClassName + "\n");
                            }
                            bin.add(reverseAttribute);
                        } else//lien uni-directionnel
                        {
                            /*if (multiplicity.equals("0..*") && reverseMultiplicity.equals("1")) {
                                output.write(indent + type + " \"" + multiplicity + " " + attributeName + "\" <--* \"" + reverseMultiplicity + " " + reverseAttributeName + "\" " + reverseType + "\n");
                            } else {
                                output.write(indent + type + " \"" + multiplicity + " " + attributeName + "\" <-- \"" + reverseMultiplicity + " " + reverseAttributeName + "\" " + reverseType + "\n");
                            }*/
                            output.write(indent + type + " \"" + multiplicity + " " + attributeName + "\" <--" + associationType + " \"" + reverseMultiplicity + " " + reverseAttributeName + "\" " + reverseType + "\n");

                        }
                    } else {
                        String reverseType = "";
                        if (attributesM.get(attribute).getName() != null) {
                            reverseType = attributesM.get(attribute).getName();
                        }
                        output.write(indent + type + " \"" + multiplicity + " " + attributeName + "\" <-- " + reverseType + "\n");
                    }
                }
            }
        }
    }

    public static String browseType(String type) {
        StringBuilder res = new StringBuilder();
        boolean first = true;
        for (String tmp : YamlUtil.charParseIgnore(type, ',', '<', '>')) {
            if (first) {
                first = false;
            } else {
                res.append(",");
            }
            if (tmp.contains("<") && tmp.contains(">")) {
                String ninja = YamlUtil.beforeChar(tmp, '<');
                res.append(YamlUtil.afterChar(ninja, '.'));
                res.append("<");
                res.append(browseType(YamlUtil.extract('<', '>', tmp)));
                res.append(">");
            } else {
                res.append(YamlUtil.afterChar(tmp, '.'));
            }
        }
        return res.toString();
    }

    public static String reduceType(String type) {
        List ignore = new LinkedList<>();
        ignore.add(' ');
        String typePARSE = YamlUtil.removeMultiChar(type, ignore);
        return browseType(typePARSE);
    }

    public String findPackage(ObjectModel input) {
        Map packages = new LinkedHashMap<>();
        for (ObjectModelClassifier classifier : input.getClassifiers()) {
            String packageTMP = classifier.getPackageName();
            if (packageTMP != null) {
                if (packages.containsKey(packageTMP)) {
                    packages.put(packageTMP, packages.get(packageTMP) + 1);
                } else {
                    packages.put(packageTMP, 1);
                }
            }
        }
        String packageL = "";
        int count = 0;
        for (Map.Entry entry : packages.entrySet()) {
            if (entry.getValue() > count) {
                count = entry.getValue();
                packageL = entry.getKey();
            }
        }
        return packageL;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy