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

org.eclipse.jetty.start.ModuleGraphWriter Maven / Gradle / Ivy

There is a newer version: 12.0.13
Show newest version
//
//  ========================================================================
//  Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd.
//  ------------------------------------------------------------------------
//  All rights reserved. This program and the accompanying materials
//  are made available under the terms of the Eclipse Public License v1.0
//  and Apache License v2.0 which accompanies this distribution.
//
//      The Eclipse Public License is available at
//      http://www.eclipse.org/legal/epl-v10.html
//
//      The Apache License v2.0 is available at
//      http://www.opensource.org/licenses/apache2.0.php
//
//  You may elect to redistribute this code under either of these licenses.
//  ========================================================================
//

package org.eclipse.jetty.start;

import java.io.BufferedWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
import java.util.Collection;
import java.util.List;

import org.eclipse.jetty.start.graph.Graph;
import org.eclipse.jetty.start.graph.Node;
import org.eclipse.jetty.start.graph.Selection;

/**
 * Generate a graphviz dot graph of the modules found
 */
public class ModuleGraphWriter
{
    private String colorModuleBg;
    private String colorEnabledBg;
    private String colorTransitiveBg;
    private String colorCellBg;
    private String colorHeaderBg;
    private String colorModuleFont;

    public ModuleGraphWriter()
    {
        colorModuleBg = "#B8FFB8";
        colorEnabledBg = "#66FFCC";
        colorTransitiveBg = "#66CC66";
        colorCellBg = "#FFFFFF80";
        colorHeaderBg = "#00000020";
        colorModuleFont = "#888888";
    }

    public void config(Props props)
    {
        String prefix = "jetty.graph.";
        colorModuleBg = getProperty(props,prefix + "color.module.bg",colorModuleBg);
        colorEnabledBg = getProperty(props,prefix + "color.enabled.bg",colorEnabledBg);
        colorTransitiveBg = getProperty(props,prefix + "color.transitive.bg",colorTransitiveBg);
        colorCellBg = getProperty(props,prefix + "color.cell.bg",colorCellBg);
        colorHeaderBg = getProperty(props,prefix + "color.header.bg",colorHeaderBg);
        colorModuleFont = getProperty(props,prefix + "color.font",colorModuleFont);
    }

    private String getProperty(Props props, String key, String defVal)
    {
        String val = props.getString(key,defVal);
        if (val == null)
        {
            return defVal;
        }
        val = val.trim();
        if (val.length() <= 0)
        {
            return defVal;
        }
        return val;
    }

    public void write(Modules modules, Path outputFile) throws IOException
    {
        try (BufferedWriter writer = Files.newBufferedWriter(outputFile,StandardCharsets.UTF_8,StandardOpenOption.CREATE_NEW,StandardOpenOption.WRITE); 
             PrintWriter out = new PrintWriter(writer);)
        {
            writeHeaderMessage(out,outputFile);

            out.println();
            out.println("digraph modules {");

            // Node Style
            out.println("  node [color=gray, style=filled, shape=rectangle];");
            out.println("  node [fontname=\"Verdana\", size=\"20,20\"];");
            // Graph Style
            out.println("  graph [");
            out.println("    concentrate=false,");
            out.println("    fontname=\"Verdana\",");
            out.println("    fontsize = 20,");
            out.println("    rankdir = LR,");
            out.println("    ranksep = 1.5,");
            out.println("    nodesep = .5,");
            out.println("    style = bold,");
            out.println("    labeljust = l,");
            out.println("    label = \"Jetty Modules\",");
            out.println("    ssize = \"20,40\"");
            out.println("  ];");

            List enabled = modules.getSelected();

            // Module Nodes
            writeModules(out,modules,enabled);

            // Module Relationships
            writeRelationships(out,modules,enabled);

            out.println("}");
            out.println();
        }
    }

    private void writeHeaderMessage(PrintWriter out, Path outputFile)
    {
        out.println("/*");
        out.println(" * GraphViz Graph of Jetty Modules");
        out.println(" * ");
        out.println(" * Jetty: http://eclipse.org/jetty/");
        out.println(" * GraphViz: http://graphviz.org/");
        out.println(" * ");
        out.println(" * To Generate Graph image using graphviz:");
        String filename = outputFile.getFileName().toString();
        String basename = filename.substring(0,filename.indexOf('.'));
        out.printf(" *   $ dot -Tpng -Goverlap=false -o %s.png %s%n",basename,filename);
        out.println(" */");
    }

    private void writeModuleDetailHeader(PrintWriter out, String header)
    {
        writeModuleDetailHeader(out,header,1);
    }

    private void writeModuleDetailHeader(PrintWriter out, String header, int count)
    {
        out.printf("  ");
        out.printf("",colorHeaderBg);
        out.printf("%s%s",header,count > 1?"s":"");
        out.println("");
    }

    private void writeModuleDetailLine(PrintWriter out, String line)
    {
        out.printf("  ");
        StringBuilder escape = new StringBuilder();
        for(char c: line.toCharArray()) {
            switch(c) {
                case '<': escape.append("<"); break;
                case '>': escape.append(">"); break;
                default:
                    escape.append(c);
                    break;
            }
        }
        
        out.printf("%s%n",colorCellBg,escape.toString());
    }

    private void writeModuleNode(PrintWriter out, Module module, boolean resolved)
    {
        String color = colorModuleBg;
        if (module.isSelected())
        {
            // specifically enabled by config
            color = colorEnabledBg;
        }
        else if (resolved)
        {
            // enabled by transitive reasons
            color = colorTransitiveBg;
        }

        out.printf("  \"%s\" [ color=\"%s\" label=<",module.getName(),color);
        out.printf("%n");
        out.printf("  %n",module.getName());

        if (module.isSelected())
        {
            writeModuleDetailHeader(out,"ENABLED");
            for (Selection selection : module.getSelections())
            {
                writeModuleDetailLine(out,"via: " + selection);
            }
        }
        else if (resolved)
        {
            writeModuleDetailHeader(out,"TRANSITIVE");
        }

        if (!module.getXmls().isEmpty())
        {
            List xmls = module.getXmls();
            writeModuleDetailHeader(out,"XML",xmls.size());
            for (String xml : xmls)
            {
                writeModuleDetailLine(out,xml);
            }
        }

        if (!module.getLibs().isEmpty())
        {
            List libs = module.getLibs();
            writeModuleDetailHeader(out,"LIB",libs.size());
            for (String lib : libs)
            {
                writeModuleDetailLine(out,lib);
            }
        }

        if (!module.getIniTemplate().isEmpty())
        {
            List inis = module.getIniTemplate();
            writeModuleDetailHeader(out,"INI Template",inis.size());
        }

        out.printf("
%s
>];%n"); } private void writeModules(PrintWriter out, Modules allmodules, List enabled) { out.println(); out.println(" /* Modules */"); out.println(); out.println(" node [ labeljust = l ];"); for (int depth = 0; depth <= allmodules.getMaxDepth(); depth++) { out.println(); Collection depthModules = allmodules.getModulesAtDepth(depth); if (depthModules.size() > 0) { out.printf(" /* Level %d */%n",depth); out.println(" { rank = same;"); for (Module module : depthModules) { boolean resolved = enabled.contains(module); writeModuleNode(out,module,resolved); } out.println(" }"); } } } private void writeRelationships(PrintWriter out, Graph modules, List enabled) { for (Module module : modules) { for (Node parent : module.getParentEdges()) { out.printf(" \"%s\" -> \"%s\";%n",module.getName(),parent.getName()); } } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy