Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get Class Annotations from Java Source File

I'm parsing Java Source Files to collect various informations about my classes. Therefore I'm using the JavaParser, since I could not find a good alternative (good suggestions have the chance to become "answers") to parse Source Files.

I already managed to get Annotations of all methods from my class. The code looks like this:

package de.mackaz;

import japa.parser.JavaParser;
import japa.parser.ParseException;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import japa.parser.ast.CompilationUnit;
import japa.parser.ast.body.MethodDeclaration;
import japa.parser.ast.expr.AnnotationExpr;
import japa.parser.ast.expr.MarkerAnnotationExpr;
import japa.parser.ast.expr.MemberValuePair;
import japa.parser.ast.expr.NormalAnnotationExpr;
import japa.parser.ast.visitor.VoidVisitorAdapter;
import java.io.FileInputStream;

public class JavaSourceUtils {

    public static void main(String[] args) throws Exception {
        File f = new File("/home/mackaz/SourceFile.java");
        inspectJavaFile(f);
    }

    public static void inspectJavaFile(File pFile) 
    throws FileNotFoundException, ParseException, IOException {
        CompilationUnit cu;
        FileInputStream in = new FileInputStream(pFile);
        try {
            cu = JavaParser.parse(in);
        } finally {
            in.close();
        }
        new MethodVisitor().visit(cu, null);
    }

    /**
     * Simple visitor implementation for visiting MethodDeclaration nodes.
     */
    private static class MethodVisitor extends VoidVisitorAdapter {

        @Override
        public void visit(MethodDeclaration n, Object arg) {
            System.out.println(n.getName());
            if (n.getAnnotations() != null) {
                for (AnnotationExpr annotation : n.getAnnotations()) {
                    System.out.println(annotation.getClass());
                    // MarkerAnnotations, for example @Test
                    if (annotation.getClass().equals(MarkerAnnotationExpr.class)) {
                        System.out.println("MarkerAnnotation:" + ((MarkerAnnotationExpr)annotation).getName());
                    }
                    if (annotation.getClass().equals(NormalAnnotationExpr.class)) {
                        for (MemberValuePair pair : ((NormalAnnotationExpr)annotation).getPairs()) {
                            if (pair.getName().equals("groups"))
                                System.out.println("Group:\"" + pair.getValue() + "\"");
                        }
                    }
                }
            }
        }
    }
}

Now how can I get the Annotations of the class itself?

like image 709
Wolkenarchitekt Avatar asked Mar 23 '11 18:03

Wolkenarchitekt


People also ask

Are class annotations inherited Java?

Because there is no multiple inheritance in Java, annotations on interfaces cannot be inherited. Even when the annotation is inherited, the application code that retrieves the annotation of a certain element can distinguish between the annotations that are inherited and those that are declared on the entity itself.

Which of the following is a meta annotation?

JUnit. As of JUnit 5, JUnit annotations can be used as meta-annotations.

Which annotation tells the compiler to suppress specific warnings that it would otherwise generate?

@SuppressWarnings @SuppressWarnings annotation tells the compiler to suppress specific warnings that it would otherwise generate.

When source code containing an annotation definition is compiled what is the extension of the file generated?

class file and a source code file, the annotation file must redundantly specify the annotation's bytecode offset and source code index. This can be done in a single . jaif file or two separate . jaif files.


2 Answers

You are overriding public void visit(MethodDeclaration n, Object arg), which visits methods. You can also override public void visit(ClassOrInterfaceDeclaration n, A arg) or public void visit(ClassOrInterfaceType n, A arg), which should give you access to the information you are looking for.

like image 83
Sean Adkinson Avatar answered Oct 06 '22 02:10

Sean Adkinson


This is how I solved it in the end - I added another Visitor "ClassVisitor":

private static class ClassVisitor extends VoidVisitorAdapter {
    @Override
    public void visit(ClassOrInterfaceDeclaration n, Object arg) {
        for (AnnotationExpr ann: n.getAnnotations()) {
            System.out.println(ann.toString());
        }
    }
}
like image 33
Wolkenarchitekt Avatar answered Oct 06 '22 02:10

Wolkenarchitekt