diff options
Diffstat (limited to 'args4j/args4j-tools/src/org/kohsuke/args4j/apt/Main.java')
-rw-r--r-- | args4j/args4j-tools/src/org/kohsuke/args4j/apt/Main.java | 108 |
1 files changed, 108 insertions, 0 deletions
diff --git a/args4j/args4j-tools/src/org/kohsuke/args4j/apt/Main.java b/args4j/args4j-tools/src/org/kohsuke/args4j/apt/Main.java new file mode 100644 index 0000000..3839447 --- /dev/null +++ b/args4j/args4j-tools/src/org/kohsuke/args4j/apt/Main.java @@ -0,0 +1,108 @@ +package org.kohsuke.args4j.apt; + +import org.kohsuke.args4j.Argument; +import org.kohsuke.args4j.CmdLineException; +import org.kohsuke.args4j.CmdLineParser; +import org.kohsuke.args4j.Option; + +import java.io.File; +import java.lang.reflect.Method; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLClassLoader; +import java.util.ArrayList; +import java.util.List; + +/** + * Entry point that invokes APT. + * @author Kohsuke Kawaguchi + */ +public class Main { + + @Option(name="-o",usage="output directory to place generated HTML/XML") + private File outDir = new File("."); + + @Option(name="-mode",usage="output format. 'XML' 'TXT' or 'HTML'") + private Mode mode = Mode.HTML; + + @Option(name="-res",usage="resource file name to obtain usage strings from.\n"+ + "Using this option will cause Option.usage() to be used as a key to this resource") + private String resourceName = null; + + @Option(name="-r") + private boolean hidden = false; // for testing + + @Argument + private List<String> aptArgs = new ArrayList<String>(); + + public static void main(String[] args) throws Exception { + System.exit(new Main().run(args)); + } + + public int run(String[] args) throws Exception { + CmdLineParser parser = new CmdLineParser(this); + try { + parser.parseArgument(args); + } catch (CmdLineException e) { + System.err.println(e.getMessage()); + printUsage(parser); + return -1; + } + + if(aptArgs.isEmpty()) { + printUsage(parser); + return 0; + } + + // we'll use a separate class loader to reload our classes, + // so parameters need to be set as system properties. Ouch! + System.setProperty("args4j.outdir",outDir.getPath()); + System.setProperty("args4j.format",mode.name()); + if(resourceName==null) resourceName = ""; // can't have null in properties + System.setProperty("args4j.resource",resourceName); + + aptArgs.add(0,"-nocompile"); + + // locate tools.jar + ClassLoader cl = loadToolsJar(); + Class<?> apt = cl.loadClass("com.sun.tools.apt.Main"); + Method main = getProcessMethod(apt); + return (Integer)main.invoke(null,new Object[]{ + cl.loadClass("org.kohsuke.args4j.apt.AnnotationProcessorFactoryImpl").newInstance(), + aptArgs.toArray(new String[0])}); + } + + private void printUsage(CmdLineParser parser) { + System.err.println("argsj-tools [options...] sourcefiles..."); + System.err.println(" Generates the list of options in XML/HTML"); + parser.printUsage(System.err); + } + + private Method getProcessMethod(Class<?> apt) { + for(Method m : apt.getDeclaredMethods()) { + if(!m.getName().equals("process")) + continue; + + Class<?>[] p = m.getParameterTypes(); + if(p.length!=2) continue; + + if(p[1]!=String[].class) continue; + if(!p[0].getName().endsWith("AnnotationProcessorFactory")) continue; + + return m; + } + throw new Error("Unable to find the entry point to APT. Please use the latest version of JDK 5.0"); + } + + public ClassLoader loadToolsJar() { + File jreHome = new File(System.getProperty("java.home")); + File toolsJar = new File(jreHome.getParent(), "lib/tools.jar" ); + + try { + return new ReloadingClassLoader(new URLClassLoader( + new URL[]{ toolsJar.toURL() }, new IsolatingClassLoader(Main.class.getClassLoader())) ); + } catch (MalformedURLException e) { + throw new Error(e); + } + } +} |