package org.reldb.dbrowser;
import java.io.File;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.LinkedList;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CTabFolder;
import org.eclipse.swt.custom.CTabItem;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.DirectoryDialog;
import org.eclipse.swt.widgets.Shell;
import org.reldb.dbrowser.hooks.OpenDocumentEventProcessor;
import org.reldb.dbrowser.ui.DbTab;
import org.reldb.dbrowser.ui.MainPanel;
import org.reldb.dbrowser.ui.ManageRecentlyUsedDialog;
import org.reldb.dbrowser.ui.RemoteDatabaseDialog;
import org.reldb.dbrowser.ui.RemoteDatabaseDialog.RemoteDatabaseDialogResponse;
import org.reldb.dbrowser.ui.preferences.PreferencePageGeneral;
import org.reldb.dbrowser.ui.preferences.Preferences;
/** Root of RelUI. */
public class DBrowser {
private final static String recentlyUsedDatabaseListPreference = "recentlyUsedDatabaseList";
private static MainPanel mainPanel;
private static DirectoryDialog openDatabaseDialog;
private static DirectoryDialog newDatabaseDialog;
private static RemoteDatabaseDialog remoteDatabaseDialog;
private static OpenDocumentEventProcessor openDocProcessor = new OpenDocumentEventProcessor();
private static boolean noLocalRel = true;
private static String defaultDatabasePath = Paths.get(System.getProperty("user.home"), "DefaultRelDb").toString();
public static Shell getShell() {
return mainPanel.getShell();
}
public static boolean isNoLocalRel() {
return noLocalRel;
}
public static void run(Composite parent) {
parent.getDisplay().addListener(SWT.OpenDocument, openDocProcessor);
mainPanel = new MainPanel(parent, SWT.None);
initialise();
}
public static void setStatus(String s) {
mainPanel.setStatus(s);
}
private static void initialise() {
openDatabaseDialog = new DirectoryDialog(getShell());
openDatabaseDialog.setText("Open Database");
openDatabaseDialog.setMessage("Select a folder that contains a database.");
openDatabaseDialog.setFilterPath(System.getProperty("user.home"));
newDatabaseDialog = new DirectoryDialog(getShell());
newDatabaseDialog.setText("Create Database");
newDatabaseDialog.setMessage("Select a folder to hold a new database. If a database already exists there, it will be opened.");
newDatabaseDialog.setFilterPath(System.getProperty("user.home"));
remoteDatabaseDialog = new RemoteDatabaseDialog(getShell());
Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
private int failureCount = 0;
public void uncaughtException(Thread t, Throwable e) {
if (failureCount > 1) {
System.err.println("SYSTEM ERROR! It's gotten even worse. This is a last-ditch attempt to escape.");
failureCount++;
Thread.setDefaultUncaughtExceptionHandler(null);
System.exit(1);
return;
} if (failureCount > 0) {
System.err.println("SYSTEM ERROR! Things have gone so horribly wrong that we can't recover or even pop up a message. I hope someone sees this...\nShutting down now, if we can.");
failureCount++;
System.exit(1);
return;
}
failureCount++;
if (e instanceof OutOfMemoryError) {
System.err.println("Out of memory!");
e.printStackTrace();
mainPanel.dispose();
MessageDialog.openError(getShell(), "OUT OF MEMORY", "Out of memory! Shutting down NOW!");
} else {
System.err.println("Unknown error: " + t);
e.printStackTrace();
mainPanel.dispose();
MessageDialog.openError(getShell(), "Unexpected Error", e.toString());
}
System.exit(1);
}
});
try {
Class.forName("org.reldb.rel.Rel");
noLocalRel = false;
} catch (ClassNotFoundException cnfe) {
noLocalRel = true;
}
DbTab dbTab = new DbTab();
if (!Preferences.getPreferenceBoolean(PreferencePageGeneral.SKIP_DEFAULT_DB_LOAD))
dbTab.openDefaultDatabase(defaultDatabasePath);
openDocProcessor.addFilesToOpen(Activator.getApplicationArguments());
String[] filesToOpen = openDocProcessor.retrieveFilesToOpen();
for (String fname: filesToOpen)
openFile(fname);
DBrowser.setSelection(0);
}
public static CTabFolder getTabFolder() {
return mainPanel.getTabFolder();
}
public static DbTab getCurrentDbTab() {
return (DbTab)mainPanel.getTabFolder().getSelection();
}
public static void setSelection(int i) {
mainPanel.getTabFolder().setSelection(i);
}
public static void newDatabase() {
String result = newDatabaseDialog.open();
if (result != null)
getCurrentDbTab().newDatabase(result.toString());
}
public static void openLocalDatabase() {
String result = openDatabaseDialog.open();
if (result != null)
getCurrentDbTab().openLocalDatabase(result.toString());
}
public static void openRemoteDatabase() {
RemoteDatabaseDialogResponse result = remoteDatabaseDialog.open();
if (result != null)
getCurrentDbTab().openRemoteDatabase(result.toString());
}
public static void createNewTabIfNeeded() {
CTabItem[] tabs = mainPanel.getTabFolder().getItems();
if (tabs.length == 0 || ((DbTab)tabs[tabs.length - 1]).isOpenOnADatabase())
new DbTab();
}
public static DbTab selectEmptyTab() {
CTabItem[] tabs = mainPanel.getTabFolder().getItems();
DbTab lastTab = (DbTab)tabs[tabs.length - 1];
DBrowser.setSelection(tabs.length - 1);
return lastTab;
}
public static void openFile(String fname) {
final String clickToOpenName = "ClickToOpen.rdb";
if (fname.toLowerCase().endsWith(".rel")) {
System.out.println("Request received to open " + fname);
DbTab dbTab = selectEmptyTab();
if (dbTab.openDefaultDatabase(defaultDatabasePath))
dbTab.openFile(fname);
} else {
int fnamePos = fname.toLowerCase().indexOf(clickToOpenName.toLowerCase());
if (fnamePos >= 0) {
System.out.println("Request received to open " + fname);
selectEmptyTab().openLocalDatabase(fname.substring(0, fnamePos));
} else {
String fnameWithRdb = fname + File.separator + clickToOpenName;
if (new File(fnameWithRdb).exists()) {
System.out.println("Request received to open database at " + fname);
selectEmptyTab().openLocalDatabase(fname);
}
}
}
}
public static void openDatabase(String dbURI) {
getCurrentDbTab().openDatabaseAtURI(dbURI, false);
}
// Add this to the recently-used list if it's not there; move it up if it is
public static void updateRecentlyUsedDatabaseList(String dbURL) {
LinkedList<String> recentlyUsed = new LinkedList<String>();
recentlyUsed.addAll(Arrays.asList(Preferences.getPreferenceStringArray(recentlyUsedDatabaseListPreference)));
int indexOfDBURL = recentlyUsed.indexOf(dbURL);
if (indexOfDBURL >= 0)
recentlyUsed.remove(dbURL);
recentlyUsed.addFirst(dbURL);
if (recentlyUsed.size() > 15) // arbitrary maximum 15 items in the recently used database list
recentlyUsed.removeLast();
Preferences.setPreference(recentlyUsedDatabaseListPreference, recentlyUsed.toArray(new String[0]));
}
public static void clearRecentlyUsedDatabaseList() {
if (MessageDialog.openConfirm(getShell(), "Clear list of recently-opened databases?",
"Are you sure you wish to clear the list of recently-opened databases?"))
Preferences.setPreference(recentlyUsedDatabaseListPreference, new String[0]);
}
public static void manageRecentlyUsedDatabaseList() {
ManageRecentlyUsedDialog dialog = new ManageRecentlyUsedDialog(getShell());
dialog.open();
}
public static String[] getRecentlyUsedDatabaseList() {
return Preferences.getPreferenceStringArray(recentlyUsedDatabaseListPreference);
}
public static void setRecentlyUsedDatabaseList(String[] usedList) {
Preferences.setPreference(recentlyUsedDatabaseListPreference, usedList);
}
}