Package org.kohsuke.args4j.apt

Source Code of org.kohsuke.args4j.apt.AnnotationProcessorFactoryImpl

package org.kohsuke.args4j.apt;

import com.sun.mirror.apt.AnnotationProcessor;
import com.sun.mirror.apt.AnnotationProcessorEnvironment;
import com.sun.mirror.apt.AnnotationProcessorFactory;
import com.sun.mirror.declaration.AnnotationTypeDeclaration;
import com.sun.mirror.declaration.ClassDeclaration;
import com.sun.mirror.declaration.Declaration;
import com.sun.mirror.declaration.FieldDeclaration;
import com.sun.mirror.declaration.MethodDeclaration;
import com.sun.mirror.declaration.TypeDeclaration;
import com.sun.mirror.declaration.MemberDeclaration;
import com.sun.mirror.type.ClassType;
import com.sun.mirror.util.SimpleDeclarationVisitor;
import org.kohsuke.args4j.Argument;
import org.kohsuke.args4j.Option;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.FileInputStream;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.Properties;

/**
* {@link AnnotationProcessorFactory} to be invoked by APT.
*
* This class receives options from the Main method through system properties (ouch!).
*
* @author Kohsuke Kawaguchi
*/
public class AnnotationProcessorFactoryImpl implements AnnotationProcessorFactory {

    private File outDir;
    private String format;
    private Properties resource = null;

    public AnnotationProcessorFactoryImpl() {
        outDir = new File(System.getProperty("args4j.outdir"));
        format = System.getProperty("args4j.format");

        String res = System.getProperty("args4j.resource");
        if(res!=null && res.length()>0) {
            try {
                resource = new Properties();
                resource.load(new FileInputStream(res));
            } catch (IOException e) {
                throw new Error(e);
            }
        }
    }

    public Collection<String> supportedOptions() {
        return Collections.emptyList();
    }

    public Collection<String> supportedAnnotationTypes() {
        return Arrays.asList(Option.class.getName(),Argument.class.getName());
    }

    public AnnotationProcessor getProcessorFor(final Set<AnnotationTypeDeclaration> annotationTypeDeclarations, final AnnotationProcessorEnvironment env) {
        return new AnnotationProcessor() {
            public void process() {
                Collection<Declaration> params = env.getDeclarationsAnnotatedWith((AnnotationTypeDeclaration)env.getTypeDeclaration(Option.class.getName()));

                final Set<TypeDeclaration> optionBeans = new HashSet<TypeDeclaration>();
                for (Declaration d : params) {
                    d.accept(new SimpleDeclarationVisitor() {
                        public void visitFieldDeclaration(FieldDeclaration f) {
                            TypeDeclaration dt = f.getDeclaringType();
                            optionBeans.add(dt);
                        }

                        public void visitMethodDeclaration(MethodDeclaration m) {
                            optionBeans.add(m.getDeclaringType());
                        }
                    });
                }

                // make sure that they are on classes
                for (TypeDeclaration t : optionBeans) {
                    if(t instanceof ClassDeclaration) {
                        ClassDeclaration cd = (ClassDeclaration)t;
                        try {
                            FileWriter out = new FileWriter(new File(outDir,cd.getQualifiedName()+"."+format.toLowerCase()));
                            AnnotationVisitor writer;
                            if(format.equals("XML"))
                                writer = new XmlWriter(out,cd);
                            else
                                writer = new HtmlWriter(out);
                            env.getMessager().printNotice("Processing "+cd.getQualifiedName());
                            scan(cd, writer);
                        } catch (IOException e) {
                            env.getMessager().printError(e.getMessage());
                        }
                    } else {
                        env.getMessager().printError(t.getPosition(),
                            "args4j annotations need to be placed on a class");
                    }
                }
            }
        };
    }

    private void scan(ClassDeclaration decl, AnnotationVisitor visitor) {
        while(decl!=null) {
            for( FieldDeclaration f : decl.getFields() )
                scan(f, visitor);

            for (MethodDeclaration m : decl.getMethods())
                scan(m, visitor);

            ClassType sc = decl.getSuperclass();
            if(sc==null)    break;

            decl = sc.getDeclaration();
        }

        visitor.done();
    }

    private void scan(MemberDeclaration f, AnnotationVisitor visitor) {
        Option o = f.getAnnotation(Option.class);
        if(o==null) return;

        String usage = getUsage(o);
        if(usage==null || usage.length()==0)    return;   // hidden
        visitor.onOption(o.name(),usage);
    }

    private String getUsage(Option o) {
        if(resource==null)
            return o.usage();
        else
            return resource.getProperty(o.usage());
    }

}
TOP

Related Classes of org.kohsuke.args4j.apt.AnnotationProcessorFactoryImpl

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.