DEV Community

Query Filter
Query Filter

Posted on

bridge126

package ${packageName};

import org.springframework.context.*;
import org.springframework.beans.factory.config.*;
import java.io.FileWriter;
import java.util.*;

public class SpringVisualizer implements ApplicationContextAware, SmartLifecycle {
    private ConfigurableApplicationContext context;
    private boolean isRunning = false;
    private static final java.util.concurrent.atomic.AtomicBoolean hasFired = new java.util.concurrent.atomic.AtomicBoolean(false);

    @Override public void setApplicationContext(ApplicationContext ctx) { this.context = (ConfigurableApplicationContext) ctx; }

    @Override
    public void start() {
        if (!hasFired.compareAndSet(false, true)) return;

        try {
            StringBuilder dot = new StringBuilder("digraph G {\n");
            // LR rankdir and specific spacing to match your 'original' clean look
            dot.append("  rankdir=LR; nodesep=0.5; ranksep=2.0; splines=true;\n");
            dot.append("  node [shape=none, fontname=\"Arial\", fontsize=10];\n");

            ConfigurableListableBeanFactory factory = context.getBeanFactory();
            for (String name : factory.getBeanDefinitionNames()) {
                if (name.startsWith("org.springframework") || name.startsWith("internal")) continue;

                // FIXEDSIZE and WIDTH stop the text from bleeding out of the boxes
                dot.append("  \"").append(name).append("\" [label=<<TABLE BORDER=\"1\" CELLBORDER=\"0\" CELLSPACING=\"0\" CELLPADDING=\"4\">");
                dot.append("<TR><TD BGCOLOR=\"#A0A0A0\" FIXEDSIZE=\"TRUE\" WIDTH=\"250\" HEIGHT=\"25\"><B>")
                   .append(name).append("</B></TD></TR></TABLE>>];\n");

                // Connectivity: checking both directions to ensure all arrows are captured
                Set<String> deps = new HashSet<>();
                deps.addAll(Arrays.asList(factory.getDependenciesForBean(name)));
                deps.addAll(Arrays.asList(factory.getDependentBeans(name)));

                for (String dep : deps) {
                    if (!dep.startsWith("org.springframework")) {
                        dot.append("  \"").append(name).append("\" -> \"").append(dep).append("\";\n");
                    }
                }
            }
            dot.append("}\n");
            try (FileWriter fw = new FileWriter("build/spring-beans.dot")) {
                fw.write(dot.toString());
            }
            System.out.println(">>> SpringVisualizer: Created build/spring-beans.dot");
        } catch (Exception e) { e.printStackTrace(); }
        this.isRunning = true;
    }

    @Override public void stop() { this.isRunning = false; }
    @Override public boolean isRunning() { return this.isRunning; }
    @Override public int getPhase() { return Integer.MAX_VALUE; }
    @Override public boolean isAutoStartup() { return true; }
    @Override public void stop(Runnable c) { stop(); c.run(); }
}

==================

// Ensure the project has an extension property to track modified files
project.ext.injectedXmlFiles = []

// TASK 1: Generate Source from Template
task generateSpringVisualizer {
    def templateFile = file("gradle/templates/SpringVisualizer.java.template")
    def outputDir = file("${buildDir}/generated/sources/visualizer/java/com/yourpackage")
    def outputFile = file("${outputDir}/SpringVisualizer.java")

    inputs.file(templateFile)
    outputs.file(outputFile)

    doLast {
        outputDir.mkdirs()
        copy {
            from templateFile
            into outputDir
            rename { "SpringVisualizer.java" }
            expand(packageName: "com.yourpackage")
        }
    }
}

// Ensure generated code is part of the build
sourceSets.main.java.srcDir "${buildDir}/generated/sources/visualizer/java"
compileJava.dependsOn generateSpringVisualizer

// TASK 2: Dynamic XML Injection (Asset-Agnostic)
task injectVisualizerToXML {
    doLast {
        // Safety Gate: Only inject if compilation succeeded
        def classFile = file("${buildDir}/classes/java/main/com/yourpackage/SpringVisualizer.class")
        if (!classFile.exists()) return

        // We use the name of the run task to find the right sub-folder
        def targetTask = "cash_riobridge" 
        def configRoot = file("src/main.config")

        configRoot.traverse(type: groovy.io.FileType.FILES, nameFilter: ~/spring-.*\.xml/) { file ->
            if (file.path.contains(targetTask)) {
                def content = file.text
                if (!content.contains("id=\"springVisualizer\"")) {
                    println ">>> Patching XML: ${file.name}"
                    def beanDef = '\n    \n    <bean id="springVisualizer" class="com.yourpackage.SpringVisualizer" lazy-init="false" />'
                    file.text = content.replace("</beans>", "${beanDef}\n</beans>")
                    project.injectedXmlFiles << file.absolutePath
                }
            }
        }
    }
}

// TASK 3: XML Scrubbing (Content cleanup, not file deletion)
task scrubVisualizerFromXML {
    doLast {
        project.injectedXmlFiles.each { filePath ->
            def xmlFile = file(filePath)
            if (xmlFile.exists()) {
                // Remove ONLY the block we injected via the comment marker
                xmlFile.text = xmlFile.text.replaceAll(/(?s)\s*.*?<bean id="springVisualizer".*?\/>/, "")
                println ">>> Scrubbed Visualizer from: ${xmlFile.name}"
            }
        }
    }
}

// TASK 4: Hook into your Local Run Task
tasks.named("cash_riobridge") {
    dependsOn injectVisualizerToXML
    finalizedBy scrubVisualizerFromXML
}

=====================


Enter fullscreen mode Exit fullscreen mode

Top comments (0)