state machine exporter

This commit is contained in:
2025-07-13 21:06:23 +02:00
parent 8aa286385e
commit a387016587
3 changed files with 133 additions and 2 deletions

2
.gitignore vendored
View File

@@ -42,4 +42,4 @@ out/
*.png
*.dot
*.scxml.xml
./Combined.java
Combined.java

View File

@@ -1 +1 @@
rootProject.name = 'statemachinedemo'
rootProject.name = 'state machine exporter'

View File

@@ -0,0 +1,131 @@
package click.kamil.filecombine;
import click.kamil.springstatemachineexporter.ast.common.FileUtils;
import org.eclipse.jdt.core.dom.*;
import org.eclipse.jdt.core.dom.rewrite.ASTRewrite;
import org.eclipse.jface.text.Document;
import org.eclipse.text.edits.TextEdit;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.*;
public class JavaConcatenator {
public static void main(String[] args) throws IOException {
Path sourceDir = Path.of("./src/main/java/click/kamil/springstatemachineexporter/ast");
Path outputFile = Path.of("./Combined.java");
String targetPackage = "click.kamil";
List<Path> javaFiles = FileUtils.findFilesWithExtension(sourceDir, ".java");
Set<String> uniqueImports = new TreeSet<>();
List<String> classBodies = new ArrayList<>();
for (Path javaFile : javaFiles) {
String source = Files.readString(javaFile);
FileParseResult result = parseAndTransform(source);
uniqueImports.addAll(result.imports);
classBodies.add(result.classBody);
}
StringBuilder combinedSource = new StringBuilder();
// Add package declaration
combinedSource.append("package ").append(targetPackage).append(";\n\n");
// Filter and append imports excluding any from com.example.*
for (String imp : uniqueImports) {
String normalizedImport = imp.replaceFirst("^import\\s+static\\s+", "")
.replaceFirst("^import\\s+", "")
.replaceFirst(";$", "");
if (!normalizedImport.startsWith(targetPackage)) {
combinedSource.append(imp).append("\n");
}
}
combinedSource.append("\n");
// Append all class bodies
for (String body : classBodies) {
combinedSource.append(body).append("\n");
}
Files.writeString(outputFile, combinedSource.toString());
System.out.println("Combined Java source written to: " + outputFile);
}
private static FileParseResult parseAndTransform(String source) {
ASTParser parser = ASTParser.newParser(AST.JLS17);
parser.setSource(source.toCharArray());
parser.setKind(ASTParser.K_COMPILATION_UNIT);
parser.setResolveBindings(false);
CompilationUnit cu = (CompilationUnit) parser.createAST(null);
AST ast = cu.getAST();
ASTRewrite rewrite = ASTRewrite.create(ast);
// Collect imports as strings
List<String> imports = new ArrayList<>();
for (Object obj : cu.imports()) {
ImportDeclaration imp = (ImportDeclaration) obj;
imports.add(imp.toString().trim());
rewrite.remove(imp, null); // Remove from AST
}
// Remove package declaration
if (cu.getPackage() != null) {
rewrite.remove(cu.getPackage(), null);
}
// Remove 'public' from type declarations
cu.accept(new ASTVisitor() {
@Override
public boolean visit(TypeDeclaration node) {
removePublicModifier(node.modifiers(), rewrite);
return true;
}
@Override
public boolean visit(EnumDeclaration node) {
removePublicModifier(node.modifiers(), rewrite);
return true;
}
private void removePublicModifier(List<IExtendedModifier> modifiers, ASTRewrite rewrite) {
for (IExtendedModifier mod : new ArrayList<>(modifiers)) {
if (mod.isModifier()) {
Modifier m = (Modifier) mod;
if (m.isPublic()) {
rewrite.remove(m, null);
}
}
}
}
});
try {
Document document = new Document(source);
TextEdit edits = rewrite.rewriteAST(document, null);
edits.apply(document);
String transformedSource = document.get();
return new FileParseResult(imports, transformedSource);
} catch (Exception e) {
throw new RuntimeException("Failed to apply AST edits", e);
}
}
private static class FileParseResult {
List<String> imports;
String classBody;
public FileParseResult(List<String> imports, String classBody) {
this.imports = imports;
this.classBody = classBody;
}
}
}