0

I would like to know if exists such thing like java parser (like parser xml). I mean from a String like this

String javaToParse = "public class x{void foo(){...} void baar(){...}}"

I could for example get the body (in string format) from foo or the body of all methods etc..

I have some like that

public class Some {
    @PostConstruct
    public void init1() {
        //some to do
    }
    @PostConstruct
    public void init2() {
        //some to do2
    }
    @PostConstruct
    public void init3() {
        //some to do3
    }
//..more..
}

Here there are one or more @PostConstruct This class is autogenerated and I cannot modified it manually.

I would like to iterate all @PostConstruct methods and put all his bodies into only one @Postcontruct method and export to file and get this:

public class Some {
    @PostConstruct
    public void init() {
        //some to do
        //some to do2
        //some to do3
    }
}

I see that it's possible to do this getting that file as String and operate manually with fors and search manually but maybe there are librearies to do it. EDIT:

Resolved with JavaParser If somebody has similar problem here my solution:

public static void createUniquePostContruct(File InputFile,File outputFile) throws FileNotFoundException {
        //get class to modified
        FileInputStream in = new FileInputStream(ficheroEntradaJava);
        // parse the file
        CompilationUnit cu = JavaParser.parse(in);
        //store methods with @PostContruct
        List<MethodDeclaration> methodsPost = new ArrayList<>();
        //iterate over all class' methods
        cu.accept(new VoidVisitorAdapter<Void>() {
            @Override
            public void visit(MethodDeclaration method, Void arg) {
                //if this method has @PostConstruct
                if (method.getAnnotationByName("PostConstruct").isPresent()) {
                    methodsPost .add(method);
                }
            }
        }, null);
        //delete all methods with @PostConstruct
        methodsPost.forEach((method) -> method.remove());
        //add a unique @PostConstruct method using body of anothers @PostConstruct methods
        MethodDeclaration uniqueMethodPostConstruct = new MethodDeclaration(EnumSet.of(Modifier.PUBLIC), new VoidType(), "init");
        uniqueMethodPostConstruct.addAnnotation("PostConstruct");
        BlockStmt bodyUniqueMethodPostConstruct= new BlockStmt();
        metodosPost.forEach(method-> {
            method.getBody().get().getStatements().forEach(statement -> {
                bodyUniqueMethodPostConstruct.addStatement(statement);
            });
        });
        metodoUnicoPostConstruct.setBody(bodyUniqueMethodPostConstruct);
        //get main class and put our method
        Optional<ClassOrInterfaceDeclaration> clazz = cu.getClassByName(ficheroEntradaJava.getName().split("\\.")[0]);
        clazz.get().addMember(uniqueMethodPostConstruct);

        System.out.println(cu.toString());

        //write to file
        try (PrintWriter out = new PrintWriter(outputFile)) {
            out.println(cu.toString());
        } catch (FileNotFoundException ex) {
            Logger.getLogger(ParserMetodos.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
Lucke
  • 316
  • 6
  • 18
  • 2
    There IS a java parser, called the ['Java Parser'](https://javaparser.org/), but I think it will take some fiddling to get it to do what you are looking for here. – otoomey Jun 19 '18 at 22:43
  • I haven't looked into this but It seems like it should be possible to compile the class on the fly and then use reflection to see what's in it. After all, that's what happens to a JSP (compiled on the fly). – Jason Jun 19 '18 at 22:46
  • If you use the java parser to create a new class I'd recommend keeping the methods without the annotation and adding one method that calls them all. And then of course add the annotation to that one. – NielsNet Jun 19 '18 at 22:55

0 Answers0