00001 package edu.rice.cs.hpc.traceviewer.ui;
00002
00003 import org.eclipse.jface.action.IStatusLineManager;
00004 import org.eclipse.jface.dialogs.Dialog;
00005 import org.eclipse.jface.dialogs.IDialogConstants;
00006 import org.eclipse.jface.dialogs.MessageDialog;
00007 import org.eclipse.jface.layout.GridDataFactory;
00008 import org.eclipse.jface.layout.GridLayoutFactory;
00009 import org.eclipse.swt.SWT;
00010 import org.eclipse.swt.events.ModifyEvent;
00011 import org.eclipse.swt.events.ModifyListener;
00012 import org.eclipse.swt.events.SelectionEvent;
00013 import org.eclipse.swt.events.SelectionListener;
00014 import org.eclipse.swt.layout.FillLayout;
00015 import org.eclipse.swt.widgets.Button;
00016 import org.eclipse.swt.widgets.Combo;
00017 import org.eclipse.swt.widgets.Composite;
00018 import org.eclipse.swt.widgets.Control;
00019 import org.eclipse.swt.widgets.DirectoryDialog;
00020 import org.eclipse.swt.widgets.Display;
00021 import org.eclipse.swt.widgets.Group;
00022 import org.eclipse.swt.widgets.Label;
00023 import org.eclipse.swt.widgets.Shell;
00024 import org.eclipse.swt.widgets.TabFolder;
00025 import org.eclipse.swt.widgets.TabItem;
00026 import org.eclipse.ui.preferences.ScopedPreferenceStore;
00027
00028 import edu.rice.cs.hpc.common.util.UserInputHistory;
00029 import edu.rice.cs.hpc.traceviewer.db.AbstractDBOpener;
00030 import edu.rice.cs.hpc.traceviewer.db.DatabaseAccessInfo;
00031 import edu.rice.cs.hpc.traceviewer.db.TraceDatabase;
00032 import edu.rice.cs.hpc.traceviewer.db.local.LocalDBOpener;
00033 import edu.rice.cs.hpc.traceviewer.db.remote.RemoteDBOpener;
00034 import edu.rice.cs.hpc.traceviewer.framework.Activator;
00035
00036
00037
00038
00039
00040
00041
00042
00043 public class OpenDatabaseDialog extends Dialog
00044 {
00045
00046
00047
00048
00049 private static final String SERVER_NAME_KEY = "server_name";
00050 private static final String SERVER_PORT_KEY = "server_port";
00051 private static final String SERVER_PATH_KEY = "server_path";
00052
00053 private static final String SERVER_LOGIN = "server_login";
00054 private static final String SERVER_TUNNEL = "server_tunnel";
00055
00056 private static final String DATABASE_PATH = "database_path";
00057
00058 private static final String PORT_KEY_DEFAULT = "21590";
00059 private static final String HISTORY_SELECTION = "traceviewer.data.select";
00060
00061 private static final int NUM_COMBO_FIELDS = 5;
00062
00063 private final Combo[] comboBoxes = new Combo[NUM_COMBO_FIELDS];
00064
00065
00066 final static int FieldServerName = 0, FieldPortKey = 1, FieldPathKey = 2, FieldServerLogin = 4;
00067 public final static int FieldDatabasePath = 3;
00068
00069
00070
00071
00072
00073
00074 private String[] args = null;
00075
00076 private final IStatusLineManager status;
00077 private Button okButton;
00078 private String errorMessage;
00079 private Button checkboxTunneling;
00080
00081 private UserInputHistory objHistoryName, objHistoryPort, objHistoryPath,
00082 objHistoryDb;
00083 private UserInputHistory objHistoryLoginHost, objHistoryTunnel;
00084
00085 private TabFolder tabFolder ;
00086
00087
00088 private boolean useLocalDatabase = true;
00089
00090
00091
00092
00093
00094
00095
00096
00097 public OpenDatabaseDialog(Shell parentShell, final IStatusLineManager inStatus) {
00098 super(parentShell);
00099 status=inStatus;
00100 errorMessage="";
00101 }
00102
00103
00104
00105
00106
00107
00108
00109
00110 public OpenDatabaseDialog(Shell parentShell, final IStatusLineManager inStatus, String _errorMessage){
00111 super(parentShell);
00112 status=inStatus;
00113 setErrorMessage(_errorMessage);
00114 }
00115
00116 public void setErrorMessage(String errorMessage)
00117 {
00118 this.errorMessage = errorMessage;
00119 }
00120
00121
00122
00132 public AbstractDBOpener getDBOpener() {
00133
00134 if (isLocalDatabase()) {
00135 return new LocalDBOpener(args[FieldDatabasePath]);
00136 } else {
00137 final DatabaseAccessInfo info = new DatabaseAccessInfo();
00138
00139 info.databasePath = args[FieldPathKey];
00140 info.serverName = args[FieldServerName];
00141 info.serverPort = args[FieldPortKey];
00142 info.sshTunnelHostname = getLoginHost();
00143 info.sshTunnelUsername = getLoginUser();
00144
00145 return (isLocalDatabase() ? new LocalDBOpener(args[FieldDatabasePath]) : new RemoteDBOpener(info));
00146 }
00147 }
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158 public DatabaseAccessInfo getDatabaseAccessInfo()
00159 {
00160
00161 if (args == null)
00162 return null;
00163
00164 DatabaseAccessInfo info = new DatabaseAccessInfo();
00165
00166 if (isLocalDatabase())
00167 {
00168 info.databasePath = args[FieldDatabasePath];
00169 } else
00170 {
00171 info.databasePath = args[FieldPathKey];
00172 info.serverName = args[FieldServerName];
00173 info.serverPort = args[FieldPortKey];
00174 info.sshTunnelHostname = getLoginHost();
00175 info.sshTunnelUsername = getLoginUser();
00176 }
00177
00178 return info;
00179 }
00180
00181
00182 @Override
00183 protected void createButtonsForButtonBar(Composite parent){
00184 super.createButtonsForButtonBar(parent);
00185 okButton=getButton(IDialogConstants.OK_ID);
00186 }
00187
00188 @Override
00189 protected Control createDialogArea(Composite parent) {
00190
00191 getShell().setText("Open a Database");
00192
00193 if (status != null)
00194 status.setMessage("Select a local or remote directory containing traces");
00195
00196 Composite outerComposite = (Composite) super.createDialogArea(parent);
00197
00198 GridLayoutFactory.fillDefaults().numColumns(1).applyTo(outerComposite);
00199 GridDataFactory.fillDefaults().grab(true, true).align(SWT.FILL, SWT.FILL).applyTo(outerComposite);
00200
00201 tabFolder = new TabFolder(outerComposite, SWT.TOP);
00202
00203
00204 tabFolder.addSelectionListener(new SelectionListener() {
00205 @Override
00206 public void widgetDefaultSelected(SelectionEvent e) {}
00207
00208 @Override
00209 public void widgetSelected(SelectionEvent e) {
00210 if (okButton != null)
00211 checkFields();
00212 }
00213 });
00214
00215
00216
00217
00218 TabItem tabLocalItem = new TabItem(tabFolder, SWT.NULL);
00219 tabLocalItem.setText("Local database");
00220
00221 Composite localComposite = new Composite(tabLocalItem.getParent(), SWT.BORDER_SOLID);
00222 GridLayoutFactory.fillDefaults().numColumns(2).applyTo(localComposite);
00223 GridDataFactory.fillDefaults().grab(true, true).align(SWT.FILL, SWT.FILL).applyTo(localComposite);
00224
00225 final Label lblBrowse = new Label(localComposite, SWT.LEFT | SWT.WRAP);
00226 lblBrowse.setText("Database:");
00227 GridDataFactory.swtDefaults().grab(false, false).align(SWT.BEGINNING, SWT.CENTER).applyTo(lblBrowse);
00228
00229 objHistoryDb = new UserInputHistory(DATABASE_PATH);
00230 comboBoxes[FieldDatabasePath] = new Combo(localComposite, SWT.DROP_DOWN | SWT.SINGLE);
00231 setComboWithHistory(comboBoxes[FieldDatabasePath], objHistoryDb, "", 400,
00232 "Enter the path to the folder containing the database");
00233
00234 GridDataFactory.fillDefaults().grab(true, false).hint(400, 40).
00235 align(SWT.FILL, SWT.CENTER).applyTo(comboBoxes[FieldDatabasePath]);
00236
00237
00238
00239 ModifyListener localModify = new ModifyListener() {
00240 @Override
00241 public void modifyText(ModifyEvent e) {
00242 checkFields();
00243 }
00244 };
00245 comboBoxes[FieldDatabasePath].addModifyListener(localModify);
00246
00247 final Button btnBrowse = new Button(localComposite, SWT.PUSH);
00248 btnBrowse.setText("Browse");
00249
00250
00251 btnBrowse.addSelectionListener(new SelectionListener() {
00252
00253 @Override
00254 public void widgetSelected(SelectionEvent e) {
00255 DirectoryDialog dialog;
00256
00257 dialog = new DirectoryDialog(getShell());
00258 dialog.setMessage("Please select a directory containing execution traces.");
00259 dialog.setText("Select Data Directory");
00260
00261 final String database = dialog.open();
00262
00263 if (database == null)
00264
00265 return;
00266 comboBoxes[FieldDatabasePath].setText(database);
00267
00268
00269 OpenDatabaseDialog.this.okPressed();
00270 }
00271
00272 @Override
00273 public void widgetDefaultSelected(SelectionEvent e) {}
00274 });
00275
00276 localComposite.pack();
00277
00278 tabLocalItem.setControl(localComposite);
00279
00280
00281
00282
00283 TabItem tabRemoteItem = new TabItem(tabFolder, SWT.NULL);
00284 tabRemoteItem.setText("Remote database");
00285
00286 Composite remoteComposite = new Composite(tabRemoteItem.getParent(), SWT.NULL);
00287 GridLayoutFactory.fillDefaults().numColumns(2).applyTo(remoteComposite);
00288 GridDataFactory.fillDefaults().grab(true, true).align(SWT.FILL, SWT.FILL).applyTo(remoteComposite);
00289
00290
00291 Label serverAddr = new Label(remoteComposite, SWT.LEAD);
00292 serverAddr.setText("Server's host:");
00293
00294 final Combo name = new Combo(remoteComposite, SWT.SINGLE);
00295 objHistoryName = new UserInputHistory( SERVER_NAME_KEY );
00296 setComboWithHistory(name, objHistoryName, "", 50,
00297 "Enter the domain name or IP address of the server to use");
00298
00299 GridDataFactory.fillDefaults().grab(true, false).applyTo(name);
00300
00301 comboBoxes[FieldServerName] = name;
00302
00303
00304 Label serverPort = new Label(remoteComposite, SWT.LEFT);
00305 serverPort.setText("Port:");
00306 Combo port = new Combo(remoteComposite, SWT.SINGLE);
00307 objHistoryPort = new UserInputHistory( SERVER_PORT_KEY );
00308
00309 setComboWithHistory(port, objHistoryPort, PORT_KEY_DEFAULT, 5,
00310 "Enter the port to use");
00311
00312 GridDataFactory.fillDefaults().grab(true, false).applyTo(port);
00313
00314 comboBoxes[FieldPortKey] = port;
00315
00316
00317
00318 Label serverPath = new Label(remoteComposite, SWT.LEAD);
00319 serverPath.setText("Path to database folder:");
00320
00321 Combo path = new Combo(remoteComposite, SWT.SINGLE);
00322 objHistoryPath = new UserInputHistory( SERVER_PATH_KEY );
00323 setComboWithHistory(path, objHistoryPath, "", 400,
00324 "Enter the path to the folder containing the database on the server");
00325
00326 GridDataFactory.fillDefaults().grab(true, false).applyTo(path);
00327
00328 comboBoxes[FieldPathKey] = path;
00329
00330
00331 ModifyListener remoteModify = new ModifyListener() {
00332 @Override
00333 public void modifyText(ModifyEvent e) {
00334 checkFields();
00335 }
00336 };
00337
00338
00339
00340 final Group grpTunnel = new Group(remoteComposite, SWT.None);
00341 grpTunnel.setText("SSH Tunneling");
00342 GridDataFactory.fillDefaults().grab(true, true).span(2, 1).applyTo(grpTunnel);
00343 GridLayoutFactory.fillDefaults().numColumns(2).applyTo(grpTunnel);
00344
00345 objHistoryTunnel = new UserInputHistory(SERVER_TUNNEL, 1);
00346
00347 checkboxTunneling = new Button(grpTunnel, SWT.CHECK);
00348 checkboxTunneling.setText("Use SSH tunnel (similar to ssh -L port:server_address:port login@hostname)");
00349 boolean check = false;
00350
00351 String []tunnels = objHistoryTunnel.getHistory();
00352 if (tunnels != null && tunnels.length > 0) {
00353 check = tunnels[0].equals(Boolean.TRUE.toString());
00354 }
00355 checkboxTunneling.setSelection(check);
00356
00357 GridDataFactory.fillDefaults().grab(true, false).span(2, 1).applyTo(checkboxTunneling);
00358
00359 final Label lblHost = new Label(grpTunnel, SWT.LEFT);
00360 lblHost.setText("login@hostname:");
00361
00362 objHistoryLoginHost = new UserInputHistory(SERVER_LOGIN);
00363 final Combo login = new Combo(grpTunnel, SWT.SINGLE);
00364 setComboWithHistory(login, objHistoryLoginHost, "login@hostname", 400,
00365 "Enter the login and the host for tunneling in format login@hostname");
00366
00367 GridDataFactory.fillDefaults().grab(true, false).applyTo(login);
00368 login.setEnabled(check);
00369 comboBoxes[FieldServerLogin] = login;
00370
00371 checkboxTunneling.addSelectionListener( new SelectionListener() {
00372
00373 @Override
00374 public void widgetSelected(SelectionEvent e) {
00375 login.setEnabled(checkboxTunneling.getSelection());
00376 }
00377
00378 @Override
00379 public void widgetDefaultSelected(SelectionEvent e) {}
00380
00381 });
00382
00383
00384
00385
00386 name.addModifyListener(remoteModify);
00387 port.addModifyListener(remoteModify);
00388 path.addModifyListener(remoteModify);
00389
00390 remoteComposite.pack();
00391
00392 tabRemoteItem.setControl(remoteComposite);
00393
00394
00395 final Label lblError = new Label(outerComposite, SWT.CENTER | SWT.WRAP);
00396 lblError.setForeground(getShell().getDisplay().getSystemColor(SWT.COLOR_RED));
00397
00398 if (errorMessage != null)
00399 {
00400 lblError.setText(errorMessage);
00401 }
00402 GridDataFactory.fillDefaults().grab(true, true).hint(SWT.DEFAULT, SWT.DEFAULT).align(SWT.FILL, SWT.CENTER).applyTo(lblError);
00403 getShell().layout(true,true);
00404
00405 outerComposite.pack();
00406
00407
00408 Activator activator = Activator.getDefault();
00409 if (activator != null) {
00410 ScopedPreferenceStore objPref = (ScopedPreferenceStore) activator.getPreferenceStore();
00411 int select = objPref.getInt(HISTORY_SELECTION);
00412 tabFolder.setSelection(select);
00413 }
00414
00415 return outerComposite;
00416 }
00417
00418
00419
00420
00421
00422
00423 private String getLoginUser()
00424 {
00425 if (args[FieldServerLogin] != null)
00426 {
00427 final String field = args[FieldServerLogin];
00428 final String user = field.substring(0, field.indexOf('@'));
00429 return user;
00430 }
00431 return null;
00432 }
00433
00434
00435
00436
00437
00438
00439 private String getLoginHost()
00440 {
00441 if (args[FieldServerLogin] != null)
00442 {
00443 final String field = args[FieldServerLogin];
00444 final String host = field.substring(field.indexOf('@')+1);
00445 return host;
00446 }
00447 return null;
00448 }
00449
00450
00451 private boolean isLocalDatabase()
00452 {
00453 return useLocalDatabase;
00454 }
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466 private void setComboWithHistory(Combo combo, UserInputHistory history, String defaultValue,
00467 int limit, String tooltipText)
00468 {
00469 final String []logs = history.getHistory();
00470 if (logs != null && logs.length > 0)
00471 {
00472 combo.setItems(logs);
00473 combo.select(0);
00474 }
00475 else
00476 {
00477 combo.setText(defaultValue);
00478 }
00479 combo.setTextLimit(limit);
00480 combo.setToolTipText(tooltipText);
00481 }
00482
00483
00484 @Override
00485
00486
00487
00488
00489 protected void okPressed() {
00490
00491 args = new String[NUM_COMBO_FIELDS];
00492 useLocalDatabase = tabFolder.getSelectionIndex() == 0;
00493
00494 if (useLocalDatabase)
00495 {
00496 final String filename = comboBoxes[FieldDatabasePath].getText();
00497 args[FieldDatabasePath] = filename;
00498 objHistoryDb.addLine(filename);
00499 } else
00500 {
00501
00502
00503
00504 final String login = comboBoxes[FieldServerLogin].getText();
00505 if (!login.isEmpty())
00506 {
00507 if (login.indexOf( '@' ) < 0) {
00508 MessageDialog.openError(getShell(), "Invalid input", "The SSH tunnel login input is invalid");
00509 return;
00510 }
00511 }
00512
00513 try{
00514 Integer portVal = (Integer.valueOf(comboBoxes[FieldPortKey].getText()));
00515 args[FieldPortKey] = portVal.toString().trim();
00516 }
00517 catch (NumberFormatException r)
00518 {
00519 comboBoxes[FieldPortKey].setText("");
00520 return;
00521 }
00522
00523 args[FieldServerName] = comboBoxes[FieldServerName].getText();
00524 args[FieldPathKey] = comboBoxes[FieldPathKey].getText();
00525
00526 if (checkboxTunneling.getSelection()) {
00527 args[FieldServerLogin] = comboBoxes[FieldServerLogin].getText();
00528 objHistoryLoginHost.addLine(args[FieldServerLogin]);
00529 } else {
00530 args[FieldServerLogin] = null;
00531 }
00532
00533
00534
00535
00536 objHistoryName.addLine(args[FieldServerName]);
00537 objHistoryPort.addLine(args[FieldPortKey]);
00538 objHistoryPath.addLine(args[FieldPathKey]);
00539 objHistoryTunnel.addLine(String.valueOf( checkboxTunneling.getSelection()) );
00540 }
00541
00542 Activator activator = Activator.getDefault();
00543 if (activator != null) {
00544 ScopedPreferenceStore objPref = (ScopedPreferenceStore) activator.getPreferenceStore();
00545 objPref.setValue(HISTORY_SELECTION, tabFolder.getSelectionIndex());
00546 }
00547
00548 super.okPressed();
00549 }
00550
00551
00552
00553
00554
00555 private void checkFields()
00556 {
00557
00558 if (comboBoxes[FieldDatabasePath] == null)
00559 return;
00560
00561 if (tabFolder.getSelectionIndex() == 0) {
00562 if (!comboBoxes[FieldDatabasePath].getText().equals("")) {
00563 okButton.setEnabled(true);
00564 } else {
00565 okButton.setEnabled(false);
00566 }
00567 } else {
00568 if (!(comboBoxes[0].getText().equals("")) && !(comboBoxes[1].getText().equals("")) && !(comboBoxes[2].getText().equals(""))) {
00569 okButton.setEnabled(true);
00570 } else {
00571 okButton.setEnabled(false);
00572 }
00573 }
00574 }
00575
00576
00577
00578
00579
00580
00581 public static void main(String []args)
00582 {
00583 Display display = new Display ();
00584 Shell shell = new Shell(display);
00585 shell.setLayout(new FillLayout());
00586
00587 shell.open();
00588 OpenDatabaseDialog dialog = new OpenDatabaseDialog(shell, null);
00589
00590 if (dialog.open() == Dialog.OK) {
00591 System.out.println("ok");
00592 final String []arguments = dialog.args;
00593 for (String arg:arguments)
00594 {
00595 System.out.println("-> " + arg);
00596 }
00597 }
00598 }
00599 }