package com.robonobo;
import static com.robonobo.common.util.TextUtil.*;
import java.awt.GraphicsEnvironment;
import java.io.*;
import javax.swing.SwingUtilities;
import com.robonobo.common.concurrent.CatchingRunnable;
import com.robonobo.common.exceptions.SeekInnerCalmException;
import com.robonobo.console.RobonoboConsole;
import com.robonobo.core.*;
import com.robonobo.eon.EONException;
import com.robonobo.gui.frames.EULAFrame;
import com.robonobo.gui.frames.RobonoboFrame;
/**
* Just a mainline - starts a RobonoboFrame or RobonoboConsole as appropriate
*
* @author macavity
*/
public class Robonobo {
private static final String HTML_EULA_PATH = "/eula.html";
private static final String TEXT_EULA_PATH = "/eula.txt";
public static void main(String[] args) throws Exception {
// 1st-stage arg checker
boolean consoleOnly = false;
for (int i = 0; i < args.length; i++) {
if (args[i].equalsIgnoreCase("-console"))
consoleOnly = true;
}
if (GraphicsEnvironment.isHeadless())
consoleOnly = true;
// Is there an instance already running?
RobonoboRuntime rt = new RobonoboRuntime(homeDir());
boolean handedOver;
try {
handedOver = rt.handoverIfRunning(argForRunningInstance(args));
} catch(EONException e) {
// TODO: there is a running instance, but it's wedged - ask the user to kill it...
throw new SeekInnerCalmException("Wedged rbnb instance");
}
if(handedOver) {
System.exit(0);
}
Platform.getPlatform().init();
if (!consoleOnly)
Platform.getPlatform().setLookAndFeel();
checkEulaAndStartup(args, consoleOnly);
}
public static File homeDir() {
if (System.getenv().containsKey("RBNB_HOME"))
return new File(System.getenv("RBNB_HOME"));
else
return Platform.getPlatform().getDefaultHomeDirectory();
}
public static String argForRunningInstance(String[] args) {
for (String arg : args) {
if(!"-console".equals(arg))
return arg;
}
return null;
}
public static void checkEulaAndStartup(final String[] args, boolean consoleOnly) throws Exception {
// Make sure they've agreed to the eula
final RobonoboController control = new RobonoboController(args);
if (control.getConfig().getAgreedToEula())
startup(control, args, consoleOnly);
else {
if (consoleOnly) {
boolean acceptedEula = showConsoleEula();
if (acceptedEula) {
control.getConfig().setAgreedToEula(true);
control.saveConfig();
startup(control, args, true);
} else {
System.exit(0);
}
} else {
CatchingRunnable onAccept = new CatchingRunnable() {
public void doRun() throws Exception {
control.getConfig().setAgreedToEula(true);
control.saveConfig();
startup(control, args, false);
}
};
CatchingRunnable onCancel = new CatchingRunnable() {
public void doRun() throws Exception {
System.exit(0);
}
};
EULAFrame eulaFrame = new EULAFrame(HTML_EULA_PATH, control.getExecutor(), onAccept, onCancel);
eulaFrame.setVisible(true);
}
}
}
private static boolean showConsoleEula() throws IOException {
// Copy the eula to a temporary file and ask them to read it
InputStream is = Robonobo.class.getResourceAsStream(TEXT_EULA_PATH);
File eulaFile = File.createTempFile("robonobo-eula-", ".txt");
OutputStream os = new FileOutputStream(eulaFile);
byte[] buf = new byte[1024];
int numRead;
while ((numRead = is.read(buf)) > 0) {
os.write(buf, 0, numRead);
}
is.close();
os.close();
String promptText = "The robonobo End-User License Agreement has been copied to the file "
+ eulaFile.getAbsolutePath()
+ " - please read this file carefully and then type 'accept' or 'cancel' below. By typing 'accept', you are agreeing to the terms of the agreement.\n";
PrintStream out = System.out;
out.println(promptText);
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
try {
while (true) {
out.print("> ");
String response = in.readLine();
if (response.equalsIgnoreCase("accept"))
return true;
if (response.equalsIgnoreCase("cancel"))
return false;
out.println("Please type either 'accept' or 'cancel'.");
}
} finally {
eulaFile.delete();
}
}
/**
* If this is a cold startup, argControl will be non-null as we need to create a controller to see if they've agreed
* to the eula. If it's a restart, argControl will be null, so we make a new controller
*/
public static void startup(RobonoboController argControl, final String[] args, boolean consoleOnly) throws Exception,
InterruptedException {
final RobonoboController control = (argControl == null) ? new RobonoboController(args) : argControl;
// Start the controller and the gui in parallel
Thread cThread = new Thread(new CatchingRunnable() {
public void doRun() throws Exception {
control.start();
}
});
cThread.start();
if (consoleOnly) {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
PrintWriter out = new PrintWriter(System.out);
RobonoboConsole console = new RobonoboConsole(control, in, out);
Thread consoleThread = new Thread(console);
consoleThread.start();
// If the user has login details entered, perform the login here (gui handles this in RobonoboFrame.setVisible() to show the login sheet)
if(isNonEmpty(control.getConfig().getMetadataUsername()))
control.login(control.getConfig().getMetadataUsername(), control.getConfig().getMetadataPassword());
} else {
SwingUtilities.invokeLater(new CatchingRunnable() {
public void doRun() throws Exception {
final RobonoboFrame frame = new RobonoboFrame(control, args);
Platform.getPlatform().initMainWindow(frame);
frame.setVisible(true);
}
});
}
}
}