001: package org.kohsuke.args4j;
002:
003: import java.lang.annotation.Annotation;
004: import java.lang.reflect.Field;
005: import java.lang.reflect.InvocationTargetException;
006: import java.lang.reflect.Method;
007:
008: /**
009: * Starter class which uses reflection to instantiate the business
010: * class, parse the command line parameters, sets the fields of the
011: * business class and doing the help message handling.
012: *
013: * @author Jan Materne
014: */
015: public class Starter {
016:
017: /**
018: * The name of the JavaVM property which stores the class name of
019: * the business class.
020: * {@value}
021: */
022: public static final String PARAMETER_NAME = "mainclass";
023:
024: public static void main(String[] args) {
025: String classname = System.getProperty(PARAMETER_NAME);
026: CmdLineParser parser = null;
027: boolean classHasArgument = false;
028: boolean classHasOptions = false;
029:
030: // Check the requirement: must specify the class to start
031: if (classname == null || "".equals(classname)) {
032: System.err.println("The system property '" + PARAMETER_NAME
033: + "' must contain the classname to start.");
034: System.exit(-1);
035: }
036:
037: try {
038: Class clazz = Class.forName(classname);
039: Object bean = clazz.newInstance();
040: parser = new CmdLineParser(bean);
041:
042: // for help output
043: classHasArgument = hasAnnotation(clazz, Argument.class);
044: classHasOptions = hasAnnotation(clazz, Option.class);
045:
046: parser.parseArgument(args);
047:
048: // try starting run()
049: Method m;
050: boolean couldInvoke = false;
051: try {
052: m = clazz.getMethod("run", (Class[]) null);
053: m.invoke(bean, (Object[]) null);
054: couldInvoke = true;
055: } catch (SecurityException e) {
056: } catch (IllegalArgumentException e) {
057: } catch (NoSuchMethodException e) {
058: } catch (IllegalAccessException e) {
059: } catch (InvocationTargetException e) {
060: }
061:
062: // try starting run(String[])
063: if (!couldInvoke)
064: try {
065: m = clazz.getMethod("run", String[].class);
066: m.invoke(bean, new Object[] { args });
067: couldInvoke = true;
068: } catch (SecurityException e) {
069: } catch (IllegalArgumentException e) {
070: e.printStackTrace();
071: } catch (NoSuchMethodException e) {
072: } catch (IllegalAccessException e) {
073: } catch (InvocationTargetException e) {
074: }
075: } catch (ClassNotFoundException e) {
076: // wrong classpath setting
077: System.err.println("Cant find the class '" + classname
078: + "' as specified in the system property '"
079: + PARAMETER_NAME + "'.");
080: } catch (CmdLineException e) {
081: // wrong argument enteres, so print the usage message as
082: // supplied by args4j
083: System.err.println(e.getMessage());
084: System.err.print(classname);
085: if (classHasOptions)
086: System.err.print(" [options]");
087: if (classHasArgument)
088: System.err.print(" arguments");
089: System.err.println();
090: if (parser != null)
091: parser.printUsage(System.err);
092: } catch (Exception e) {
093: // Must be an unhandled business exception, so we can only
094: // print stacktraces.
095: e.printStackTrace();
096: }
097: }
098:
099: public static boolean hasAnnotation(Class clazz,
100: Class<? extends Annotation> annotation) {
101: if (clazz.getAnnotation(annotation) != null)
102: return true;
103: for (Field f : clazz.getFields()) {
104: if (f.getAnnotation(annotation) != null)
105: return true;
106: }
107: for (Method m : clazz.getMethods()) {
108: if (m.getAnnotation(annotation) != null)
109: return true;
110: }
111: return false;
112: }
113:
114: }
|