All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.gridkit.jvmtool.cli.CommandLauncher Maven / Gradle / Ivy
/**
* Copyright 2013 Alexey Ragozin
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.gridkit.jvmtool.cli;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import com.beust.jcommander.JCommander;
import com.beust.jcommander.Parameter;
/**
* Swiss Java Knife
*
* Command line tool for JVM troubleshooting
*
* @author Alexey Ragozin ([email protected] )
*/
public class CommandLauncher {
public interface CmdRef {
public String getCommandName();
public Runnable newCommand(CommandLauncher host);
}
@Parameter(names = "--help", help = true)
private boolean help = false;
@Parameter(names = {"-X", "--verbose"}, description = "Enable detailed diagnostics")
private boolean verbose = false;
@Parameter(names = "--commands", help = true)
private boolean listCommands = false;
private boolean suppressSystemExit;
private Map commands = new HashMap();
public boolean isVerbose() {
return verbose;
}
public Error fail(String... messages) {
throw new CommandAbortedError(false, messages);
}
public Error fail(String message, Exception e) {
throw new CommandAbortedError(false, new String[]{message}, e);
}
public Error failAndPrintUsage(String... messages) {
throw new CommandAbortedError(true, messages);
}
public void logError(String line) {
System.err.println(line);
}
public void logTrace(Throwable e) {
e.printStackTrace(System.err);
}
public void suppressSystemExit() {
suppressSystemExit = true;
}
public boolean start(String[] args) {
JCommander parser = null;
try {
parser = new JCommander(this);
addCommands(parser);
try {
parser.parse(args);
}
catch(Exception e) {
failAndPrintUsage(e.toString());
}
if (help) {
String cmd = parser.getParsedCommand();
if (cmd == null) {
parser.usage();
}
else {
parser.usage(cmd);
}
}
else if (listCommands) {
for(String cmd: commands.keySet()) {
System.out.println(String.format("%8s - %s", cmd, parser.getCommandDescription(cmd)));
}
}
else {
Runnable cmd = commands.get(parser.getParsedCommand());
if (cmd == null) {
failAndPrintUsage();
}
else {
cmd.run();
}
}
if (suppressSystemExit) {
return true;
}
else {
System.exit(0);
}
}
catch(CommandAbortedError error) {
for(String m: error.messages) {
logError(m);
}
if (verbose && error.getCause() != null) {
logTrace(error.getCause());
}
if (error.printUsage && parser != null) {
if (parser.getParsedCommand() != null) {
parser.usage(parser.getParsedCommand());
}
else {
parser.usage();
}
}
}
catch(Throwable e) {
e.printStackTrace();
}
// abnormal termination
if (suppressSystemExit) {
return false;
}
else {
System.exit(1);
return false;
}
}
protected List getCommandPackages() {
return Collections.singletonList(getClass().getPackage().getName() + ".cmd");
}
private void addCommands(JCommander parser) throws InstantiationException, IllegalAccessException {
for(String pack: getCommandPackages()) {
for(Class> c: findClasses(pack)) {
if (CmdRef.class.isAssignableFrom(c)) {
CmdRef cmd = (CmdRef) c.newInstance();
String cmdName = cmd.getCommandName();
Runnable cmdTask = cmd.newCommand(this);
if (commands.containsKey(cmdName)) {
fail("Ambiguous implementation for '" + cmdName + "'");
}
commands.put(cmdName, cmdTask);
parser.addCommand(cmdName, cmdTask);
}
}
}
}
private List> findClasses(String packageName) {
List> result = new ArrayList>();
try {
String path = packageName.replace('.', '/');
for(String f: findFiles(path)) {
if (f.endsWith(".class") && f.indexOf('$') < 0) {
f = f.substring(0, f.length() - ".class".length());
f = f.replace('/', '.');
result.add(Class.forName(f));
}
}
return result;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
static List findFiles(String path) throws IOException {
List result = new ArrayList();
ClassLoader cl = Thread.currentThread().getContextClassLoader();
Enumeration en = cl.getResources(path);
while(en.hasMoreElements()) {
URL u = en.nextElement();
listFiles(result, u, path);
}
return result;
}
static List listFiles(List results, URL packageURL, String path) throws IOException {
if(packageURL.getProtocol().equals("jar")){
String jarFileName;
JarFile jf ;
Enumeration jarEntries;
String entryName;
// build jar file name, then loop through zipped entries
jarFileName = URLDecoder.decode(packageURL.getFile(), "UTF-8");
jarFileName = jarFileName.substring(5,jarFileName.indexOf("!"));
jf = new JarFile(jarFileName);
jarEntries = jf.entries();
while(jarEntries.hasMoreElements()){
entryName = jarEntries.nextElement().getName();
if(entryName.startsWith(path)){
results.add(entryName);
}
}
// loop through files in classpath
}else{
File dir = new File(packageURL.getFile());
String cp = dir.getCanonicalPath();
File root = dir;
while(true) {
if (cp.equals(new File(root, path).getCanonicalPath())) {
break;
}
root = root.getParentFile();
}
listFiles(results, root, dir);
}
return results;
}
static void listFiles(List names, File root, File dir) {
String rootPath = root.getAbsolutePath();
if (dir.exists() && dir.isDirectory()) {
for(File file: dir.listFiles()) {
if (file.isDirectory()) {
listFiles(names, root, file);
}
else {
String name = file.getAbsolutePath().substring(rootPath.length() + 1);
name = name.replace('\\', '/');
names.add(name);
}
}
}
}
@SuppressWarnings("serial")
public static class CommandAbortedError extends Error {
public boolean printUsage;
public String[] messages;
public CommandAbortedError(boolean printUsage, String[] messages) {
super();
this.printUsage = printUsage;
this.messages = messages;
}
public CommandAbortedError(boolean printUsage, String[] messages, Exception e) {
super(e);
this.printUsage = printUsage;
this.messages = messages;
}
}
}