import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.URI;
import java.util.Random;
/**
* Created with IntelliJ IDEA.
* User: tomk
* Date: 8/15/13
* Time: 12:40 AM
* To change this template use File | Settings | File Templates.
*/
public class H2OLauncher implements ActionListener {
// Stuff managed by the GUI builder BEGIN.
private JTextField xmxField;
private JButton hexdataButton;
private JButton startStopButton;
private JPanel panel;
// Stuff managed by the GUI builder END.
private static H2OLauncher h2oLauncher;
private static Thread procManagerThread;
private static Process proc;
private final static String XMX_COMMAND = "xmx";
private final static String START_COMMAND = "start";
private final static String STOP_COMMAND = "stop";
private enum H2oStatus {
RUNNING,
NOT_RUNNING
}
private static H2oStatus status;
public H2OLauncher() {
startStopButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent actionEvent) {
//To change body of implemented methods use File | Settings | File Templates.
if (status == H2oStatus.RUNNING) {
stopProcess();
}
else {
startProcess();
}
recalcInBackground();
}
});
xmxField.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent actionEvent) {
//To change body of implemented methods use File | Settings | File Templates.
String s = xmxField.getText();
String s2 = s.trim();
if (s2.matches("^[1-9][0-9]*$")) {
updateResult ("Xmx set successfully");
}
else {
xmxField.setText("1");
updateResult("Xmx must be of the form nnnm or nnng (e.g. 1024m, 2g)");
}
recalcInBackground();
}
});
hexdataButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent actionEvent) {
try {
URI uri = new URI("http://docs.0xdata.com");
Desktop.getDesktop().browse(uri);
} catch (Exception e) {
}
}
});
}
private boolean isPortTaken (int port) {
boolean portTaken = false;
ServerSocket socket = null;
try {
socket = new ServerSocket(port);
}
catch (IOException e) {
portTaken = true;
}
finally {
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
/* e.printStackTrace(); */
}
}
}
return portTaken;
}
private class ProcManagerThread extends Thread {
private H2OLauncher _launcher;
private Process _p;
ProcManagerThread (H2OLauncher launcher, Process p) {
_launcher = launcher;
_p = p;
}
public void run() {
BufferedReader r = new BufferedReader (new InputStreamReader(_p.getInputStream()));
while (true) {
try {
String s = r.readLine();
if (s == null) {
_p.waitFor();
_launcher.notifyProcessExit();
break;
}
notifyProcessOutput (s + "\n");
if (s.contains("Listening for HTTP and REST traffic")) {
String s2 = s.replaceFirst ("^.*http", "http");
_launcher.notifyHttp (s2);
}
}
catch (Exception e) {
_p.destroy();
_launcher.notifyProcessExit();
break;
}
}
}
}
private void recalcInBackground() {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
recalc();
}
});
}
public void notifyProcessOutput(final String s) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
// textArea.append(s);
}
});
}
public void notifyHttp(final String s) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
// browserField.setText(s);
if ((s != null) && (s.length() > 0)) {
try {
URI uri = new URI(s);
Desktop.getDesktop().browse(uri);
} catch (Exception e) {
}
}
}
});
}
public void notifyProcessExit() {
synchronized (this) {
procManagerThread = null;
proc = null;
status = H2oStatus.NOT_RUNNING;
}
notifyProcessOutput ("\nH2O PROCESS EXITED\n\n");
notifyHttp("");
recalcInBackground();
}
private void startProcess() {
synchronized (this) {
if (procManagerThread != null) {
updateResult ("Error: procManagerThread already exists");
return;
}
}
try {
String cloudName;
{
Random r = new Random();
Integer randValue = new Integer(r.nextInt());
if (randValue < 0) {
randValue = -randValue;
}
cloudName = "h2o_cluster_" + (randValue.toString());
}
File currentDirectory = new File(new File(".").getAbsolutePath());
String javaHome = System.getProperty("java.home");
String javaBinary = javaHome + File.separator + "bin" + File.separator + "java";
String h2oJar = currentDirectory.getAbsolutePath().toString() + File.separator + "h2o.jar";
// String h2oJar = "/Users/tomk/0xdata/ws/h2o/target/h2o.jar";
ProcessBuilder pb = new ProcessBuilder(
javaBinary,
"-Xmx" + xmxField.getText().trim() + "g",
"-jar", h2oJar,
"-name", cloudName,
"-ip", "127.0.0.1",
"-port", "54321"
);
pb.redirectErrorStream(true);
Process p = pb.start();
synchronized (this) {
proc = p;
ProcManagerThread t;
t = new ProcManagerThread (this, proc);
t.start();
procManagerThread = t;
status = H2oStatus.RUNNING;
}
updateResult("H2O started");
}
catch (Exception e) {
updateResult ("Failed to start H2O (process start failed)");
String s = e.getMessage() + "\n" + e.getStackTrace();
// textArea.setText(s);
}
}
private void stopProcess() {
synchronized (this) {
//if (procManagerThread == null) {
// updateResult ("Error: procManagerThread does not");
//}
if (proc == null) {
updateResult ("Error: proc does not exist, cleaning up as best as possible");
procManagerThread = null;
status = H2oStatus.NOT_RUNNING;
return;
}
proc.destroy();
updateResult("H2O stopped");
notifyHttp("");
}
}
// Called when this JVM is exiting.
public void destroyProcess() {
synchronized (this) {
if (proc == null) {
return;
}
proc.destroy();
}
}
private void updateResult (String s) {
// resultField.setText(s);
}
public void actionPerformed(ActionEvent evt) {
String actionCommand = evt.getActionCommand();
if (actionCommand.equals (XMX_COMMAND)) {
String s = xmxField.getText();
String s2 = s.trim();
if (s2.matches("^[1-9][0-9]*$")) {
updateResult ("Xmx set successfully");
}
else {
updateResult ("Xmx must be of the form nnnm or nnng (e.g. 1024m, 2g)");
}
}
else if (actionCommand.equals (START_COMMAND)) {
startProcess();
}
else if (actionCommand.equals (STOP_COMMAND)) {
stopProcess();
}
else {
System.err.println ("Unknown actionCommand");
}
recalcInBackground();
}
private void recalc() {
if (status == H2oStatus.RUNNING) {
// h2oStatusLabel.setText(H2O_STATUS_RUNNING);
startStopButton.setText("Stop H2O");
}
else if (status == H2oStatus.NOT_RUNNING) {
// h2oStatusLabel.setText(H2O_STATUS_NOT_RUNNING);
startStopButton.setText("Start H2O");
}
startStopButton.requestFocusInWindow();
}
public static void main(String[] args) {
JFrame frame = new JFrame("H2O");
h2oLauncher = new H2OLauncher();
frame.setContentPane(h2oLauncher.panel);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
status = H2oStatus.NOT_RUNNING;
h2oLauncher.recalcInBackground();
final Thread mainThread = Thread.currentThread();
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() {
try {
h2oLauncher.destroyProcess();
mainThread.join();
}
catch (Exception e) {
}
}
});
}
}