summaryrefslogtreecommitdiffstats
path: root/args4j/args4j-tools/src/org/kohsuke/args4j/apt/Main.java
diff options
context:
space:
mode:
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.java108
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);
+ }
+ }
+}