use of hudson.cli.CLICommand in project hudson-2.x by hudson.
the class CLIRegisterer method discover.
private List<ExtensionComponent<CLICommand>> discover(final Hudson hudson) {
LOGGER.fine("Listing up @CLIMethod");
List<ExtensionComponent<CLICommand>> r = new ArrayList<ExtensionComponent<CLICommand>>();
try {
for (final Method m : Util.filter(Index.list(CLIMethod.class, hudson.getPluginManager().uberClassLoader), Method.class)) {
try {
// command name
final String name = m.getAnnotation(CLIMethod.class).name();
final ResourceBundleHolder res = loadMessageBundle(m);
// make sure we have the resource, to fail early
res.format("CLI." + name + ".shortDescription");
r.add(new ExtensionComponent<CLICommand>(new CloneableCLICommand() {
@Override
public String getName() {
return name;
}
public String getShortDescription() {
// format by using the right locale
return res.format("CLI." + name + ".shortDescription");
}
@Override
public int main(List<String> args, Locale locale, InputStream stdin, PrintStream stdout, PrintStream stderr) {
this.stdout = stdout;
this.stderr = stderr;
this.locale = locale;
this.channel = Channel.current();
registerOptionHandlers();
CmdLineParser parser = new CmdLineParser(null);
try {
SecurityContext sc = SecurityContextHolder.getContext();
Authentication old = sc.getAuthentication();
try {
// build up the call sequence
Stack<Method> chains = new Stack<Method>();
Method method = m;
while (true) {
chains.push(method);
if (Modifier.isStatic(method.getModifiers()))
// the chain is complete.
break;
// the method in question is an instance method, so we need to resolve the instance by using another resolver
Class<?> type = method.getDeclaringClass();
method = findResolver(type);
if (method == null) {
stderr.println("Unable to find the resolver method annotated with @CLIResolver for " + type);
return 1;
}
}
List<MethodBinder> binders = new ArrayList<MethodBinder>();
while (!chains.isEmpty()) binders.add(new MethodBinder(chains.pop(), parser));
// authentication
CliAuthenticator authenticator = Hudson.getInstance().getSecurityRealm().createCliAuthenticator(this);
new ClassParser().parse(authenticator, parser);
// fill up all the binders
parser.parseArgument(args);
Authentication auth = authenticator.authenticate();
if (auth == Hudson.ANONYMOUS)
auth = loadStoredAuthentication();
// run the CLI with the right credential
sc.setAuthentication(auth);
hudson.checkPermission(Hudson.READ);
// resolve them
Object instance = null;
for (MethodBinder binder : binders) instance = binder.call(instance);
if (instance instanceof Integer)
return (Integer) instance;
else
return 0;
} catch (InvocationTargetException e) {
Throwable t = e.getTargetException();
if (t instanceof Exception)
throw (Exception) t;
throw e;
} finally {
// restore
sc.setAuthentication(old);
}
} catch (CmdLineException e) {
stderr.println(e.getMessage());
printUsage(stderr, parser);
return 1;
} catch (Exception e) {
e.printStackTrace(stderr);
return 1;
}
}
protected int run() throws Exception {
throw new UnsupportedOperationException();
}
}));
} catch (ClassNotFoundException e) {
LOGGER.log(SEVERE, "Failed to process @CLIMethod: " + m, e);
}
}
} catch (IOException e) {
LOGGER.log(SEVERE, "Failed to discvoer @CLIMethod", e);
}
return r;
}
Aggregations