PandaLib/pandalib-cli/src/main/java/fr/pandacube/lib/cli/CLIApplication.java

105 lines
2.6 KiB
Java

package fr.pandacube.lib.cli;
import fr.pandacube.lib.cli.commands.CommandAdmin;
import fr.pandacube.lib.cli.commands.CommandStop;
import fr.pandacube.lib.util.Log;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.logging.Logger;
/**
* Main class of a CLI application.
*/
public abstract class CLIApplication {
private static CLIApplication instance;
public static CLIApplication getInstance() {
return instance;
}
public final CLI cli;
protected CLIApplication() {
instance = this;
CLI tmpCLI = null;
try {
tmpCLI = new CLI();
Log.setLogger(tmpCLI.getLogger());
} catch (Throwable t) {
System.err.println("Unable to start application " + getName() + " version " + getClass().getPackage().getImplementationVersion());
t.printStackTrace();
System.exit(1);
}
cli = tmpCLI;
try {
Log.info("Starting " + getName() + " version " + getClass().getPackage().getImplementationVersion());
start();
new CommandAdmin();
new CommandStop();
Runtime.getRuntime().addShutdownHook(new Thread(this::end));
cli.start(); // actually starts the CLI thread
Log.info("Application started.");
} catch (Throwable t) {
Log.severe("Unable to start application " + getName() + " version " + getClass().getPackage().getImplementationVersion(), t);
}
}
public Logger getLogger() {
return cli.getLogger();
}
private final Object stopLock = new Object();
private final AtomicBoolean stopping = new AtomicBoolean(false);
@SuppressWarnings("finally")
public final void stop() {
synchronized (stopLock) {
synchronized (stopping) {
if (stopping.get())
return;
stopping.set(true);
}
Log.info("Stopping " + getName() + " version " + getClass().getPackage().getImplementationVersion());
try {
end();
} catch (Throwable t) {
Log.severe("Error stopping application " + getName() + " version " + getClass().getPackage().getImplementationVersion(), t);
} finally {
Log.info("Bye bye.");
System.exit(0);
}
}
}
public boolean isStopping() {
return stopping.get();
}
public abstract String getName();
protected abstract void start() throws Exception;
public abstract void reload();
protected abstract void end();
}