2 * Copyright (C) 2007 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
6 * The contents of this file are subject to the Mozilla Public License Version 1.1
7 * See LICENSE.TXT at the top of this package for the full license terms.
10 package eu
.etaxonomy
.taxeditor
.datasource
;
12 import java
.util
.ArrayList
;
14 import org
.apache
.log4j
.Logger
;
15 import org
.eclipse
.jface
.action
.MenuManager
;
16 import org
.eclipse
.jface
.dialogs
.Dialog
;
17 import org
.eclipse
.jface
.dialogs
.IDialogConstants
;
18 import org
.eclipse
.jface
.dialogs
.MessageDialog
;
19 import org
.eclipse
.jface
.viewers
.ArrayContentProvider
;
20 import org
.eclipse
.jface
.viewers
.DoubleClickEvent
;
21 import org
.eclipse
.jface
.viewers
.IDoubleClickListener
;
22 import org
.eclipse
.jface
.viewers
.IStructuredSelection
;
23 import org
.eclipse
.jface
.viewers
.LabelProvider
;
24 import org
.eclipse
.jface
.viewers
.TableViewer
;
25 import org
.eclipse
.swt
.SWT
;
26 import org
.eclipse
.swt
.custom
.CCombo
;
27 import org
.eclipse
.swt
.events
.ModifyEvent
;
28 import org
.eclipse
.swt
.events
.ModifyListener
;
29 import org
.eclipse
.swt
.events
.MouseAdapter
;
30 import org
.eclipse
.swt
.events
.MouseEvent
;
31 import org
.eclipse
.swt
.events
.SelectionAdapter
;
32 import org
.eclipse
.swt
.events
.SelectionEvent
;
33 import org
.eclipse
.swt
.graphics
.Point
;
34 import org
.eclipse
.swt
.layout
.GridData
;
35 import org
.eclipse
.swt
.layout
.GridLayout
;
36 import org
.eclipse
.swt
.widgets
.Button
;
37 import org
.eclipse
.swt
.widgets
.Composite
;
38 import org
.eclipse
.swt
.widgets
.Control
;
39 import org
.eclipse
.swt
.widgets
.Group
;
40 import org
.eclipse
.swt
.widgets
.Label
;
41 import org
.eclipse
.swt
.widgets
.Menu
;
42 import org
.eclipse
.swt
.widgets
.Shell
;
43 import org
.eclipse
.swt
.widgets
.Table
;
44 import org
.eclipse
.swt
.widgets
.Text
;
46 import eu
.etaxonomy
.cdm
.common
.CdmUtils
;
47 import eu
.etaxonomy
.cdm
.database
.CdmDataSource
;
48 import eu
.etaxonomy
.cdm
.database
.CdmPersistentDataSource
;
49 import eu
.etaxonomy
.cdm
.database
.DatabaseTypeEnum
;
50 import eu
.etaxonomy
.cdm
.database
.ICdmDataSource
;
51 import eu
.etaxonomy
.taxeditor
.controller
.GlobalController
;
53 * List of database types comes from {@link eu.etaxonomy.cdm.database.DatabaseTypeEnum}.
59 public class CdmDataSourceDialog
extends Dialog
{
60 private static final Logger logger
= Logger
.getLogger(CdmDataSourceDialog
.class);
62 private Text portText
;
63 private Text serverText
;
64 private Text passwordText
;
65 private Text databaseNameText
;
66 private Text datasourceNameText
;
67 private CCombo databaseTypeCombo
;
68 private Text usernameText
;
70 private Composite container
;
71 private Composite editDatasourceComposite
;
72 private Group authenticationGroup
;
73 private Group locationGroup
;
74 private Button saveButton
;
75 private Composite dbConfigComposite
;
77 private ArrayList
<DatabaseTypeEnum
> databaseTypes
;
78 private ICdmDataSource dataSource
= null;
80 private TableViewer dataSourceViewer
;
82 private Button btnEdit
;
84 private Button btnRemove
;
86 private ICdmDataSource selectedDataSource
;
88 private Shell parentShell
;
91 * Any time user modifies datasource properties, force a save or a cancel
93 ModifyListener modifyListener
= new ModifyListener() {
94 public void modifyText(ModifyEvent e
) {
95 forceUserToSave(true);
103 public CdmDataSourceDialog(Shell parentShell
) {
105 this.parentShell
= parentShell
;
108 protected void configureShell(Shell shell
) {
109 super.configureShell(shell
);
110 shell
.setText("Edit Data Sources");
114 * Create contents of the dialog
118 protected Control
createDialogArea(Composite parent
) {
120 // Create top-level composite
121 container
= (Composite
) super.createDialogArea(parent
);
122 GridLayout gridLayout
= new GridLayout();
123 gridLayout
.numColumns
= 5;
124 container
.setLayout(gridLayout
);
126 // Create buttons to edit list
127 btnEdit
= new Button(container
, SWT
.NONE
);
128 btnEdit
.setText("Edit ...");
129 btnEdit
.setEnabled(false);
130 btnEdit
.addSelectionListener(new SelectionAdapter() {
131 public void widgetSelected(SelectionEvent e
) {
132 // if (getSelectedTypeDesignation() != null) {
133 // createTypeDesignationWizard(getSelectedTypeDesignation());
135 if (getSelectedDataSource() != null) {
136 showDatasource(getSelectedDataSource());
141 btnRemove
= new Button(container
, SWT
.NONE
);
142 btnRemove
.setText("Remove");
143 btnRemove
.setEnabled(false);
144 btnRemove
.addSelectionListener(new SelectionAdapter() {
145 public void widgetSelected(SelectionEvent e
) {
146 if (getSelectedDataSource() != null) {
147 removeDataSource(getSelectedDataSource());
148 setSelectedDataSource(null);
153 final Button btnAdd
= new Button(container
, SWT
.NONE
);
154 final GridData gd_btnAdd
= new GridData(SWT
.RIGHT
, SWT
.CENTER
, true,
156 btnAdd
.setLayoutData(gd_btnAdd
);
157 btnAdd
.setText("Add ...");
158 btnAdd
.addSelectionListener(new SelectionAdapter() {
159 public void widgetSelected(SelectionEvent e
) {
164 // Create viewer for datasource list
165 dataSourceViewer
= new TableViewer(container
, SWT
.BORDER
);
166 GridData viewerLayout
= new GridData(SWT
.LEFT
, SWT
.FILL
, false, true, 3, 1);
167 viewerLayout
.widthHint
= 162;
168 dataSourceViewer
.getTable().setLayoutData(viewerLayout
);
170 // Set providers for datasource list
171 dataSourceViewer
.setContentProvider(new ArrayContentProvider());
172 dataSourceViewer
.setLabelProvider(new LabelProvider() {
173 public String
getText(Object element
) {
174 if (element
instanceof ICdmDataSource
) {
175 return ((ICdmDataSource
) element
).getName();
177 return super.getText(element
);
181 // Add data sources to viewer
182 refreshDataSourceViewer();
184 // Double-clicking on a dataSource in the viewer puts it in the editable area
185 dataSourceViewer
.addDoubleClickListener(new IDoubleClickListener() {
186 public void doubleClick(DoubleClickEvent event
) {
189 ((IStructuredSelection
) event
.getSelection()).
192 if (dataSource
instanceof ICdmDataSource
) {
194 // Existing datasource
195 showDatasource((ICdmDataSource
) dataSource
);
199 showDatasource(null);
204 // Create "remove datasource" rt-click menu
205 Table dataSourceControl
= dataSourceViewer
.getTable();
206 final MenuManager manager
= new MenuManager();
207 final Menu menu
= manager
.createContextMenu(dataSourceControl
);
208 dataSourceControl
.setMenu(menu
);
210 // Add right-click menu to delete datasources
211 dataSourceControl
.addSelectionListener(new SelectionAdapter() {
212 public void widgetSelected(SelectionEvent e
) {
214 setEnableTypeDesignationButtons(true);
216 // Get content of widget's data field
217 if (e
.item
.getData() instanceof ICdmDataSource
) {
218 setSelectedDataSource((ICdmDataSource
) e
.item
.getData());
223 // manager.removeAll();
225 // Only persistent data sources can be removed -
226 // H2 database and "New datasource" entry remain untouched
227 // if (data instanceof CdmPersistentDataSource) {
228 // manager.add(new RemoveDataSourceAction((CdmPersistentDataSource) data));
233 // Create editDatasourceComposite to display a dataSource's name and type
234 editDatasourceComposite
= new Composite(container
, SWT
.NONE
);
235 GridData datasourceGridData
= new GridData(SWT
.FILL
, SWT
.TOP
, true, true);
236 editDatasourceComposite
.setLayoutData(datasourceGridData
);
237 GridLayout datasourceLayout
= new GridLayout();
238 datasourceLayout
.numColumns
= 2;
239 editDatasourceComposite
.setLayout(datasourceLayout
);
241 // Create label and input for dataSource name
242 Label datasourceNameLabel
= new Label(editDatasourceComposite
, SWT
.NONE
);
243 datasourceNameLabel
.setText("Datasource Name:");
244 datasourceNameText
= new Text(editDatasourceComposite
, SWT
.BORDER
);
245 datasourceNameText
.setLayoutData(new GridData(SWT
.FILL
, SWT
.CENTER
, true, false));
247 // Create label and dropdown for database type
248 Label databaseTypeLabel
= new Label(editDatasourceComposite
, SWT
.NONE
);
249 databaseTypeLabel
.setText("Database Type:");
250 databaseTypeCombo
= new CCombo(editDatasourceComposite
, SWT
.BORDER
);
251 GridData comboLayout
= new GridData(SWT
.FILL
, SWT
.CENTER
, false, false);
252 databaseTypeCombo
.setLayoutData(comboLayout
);
253 populateComboBoxItems();
255 // Create listener to display database type-specific config options
256 databaseTypeCombo
.addSelectionListener(new SelectionAdapter() {
257 public void widgetSelected(SelectionEvent e
) {
259 // Get database type at the selected index
260 DatabaseTypeEnum type
= databaseTypes
.get(databaseTypeCombo
.getSelectionIndex());
262 // Display type-specific input fields
263 showDatabaseConfig(dataSource
, type
);
267 // Hide editable fields until a dataSource is chosen
268 editDatasourceComposite
.setVisible(false);
276 protected void showNewDatasource() {
277 showDatasource(null);
281 * @param selectedDataSource
283 protected void removeDataSource(ICdmDataSource dataSource
) {
285 if (dataSource
instanceof CdmPersistentDataSource
) {
287 // Delete from persistent data sources
288 CdmDataSourceRepository
.getDefault().delete((CdmPersistentDataSource
) dataSource
);
290 // Refresh list of data sources to reflect changes
291 refreshDataSourceViewer();
294 MessageDialog
.openInformation(parentShell
, "Data source not persistent",
295 "This data source cannot be removed. Only persistent data sources can be removed.");
302 protected ICdmDataSource
getSelectedDataSource() {
303 return selectedDataSource
;
309 protected void setSelectedDataSource(ICdmDataSource selectedDataSource
) {
310 this.selectedDataSource
= selectedDataSource
;
316 protected void setEnableTypeDesignationButtons(boolean enabled
) {
317 btnEdit
.setEnabled(enabled
);
318 btnRemove
.setEnabled(enabled
);
321 private void showDatasource(ICdmDataSource dataSource
) {
323 // Put dataSource in field
324 this.dataSource
= dataSource
;
326 // Make editable fields visible
327 editDatasourceComposite
.setVisible(true);
329 // Remove any existing db config data
330 removeDbConfigFields();
332 // Populate name and database type if this is a non-null dataSource
333 if (dataSource
!= null) {
334 datasourceNameText
.setText(dataSource
.getName());
335 datasourceNameText
.setEnabled(false);
336 selectDatabaseType(dataSource
.getDatabaseType());
337 databaseTypeCombo
.setEnabled(false);
339 datasourceNameText
.setText("");
340 datasourceNameText
.setEnabled(true);
341 databaseTypeCombo
.setText(""); // for some reason, .deselectAll and .clearSelection don't work as advertised
342 databaseTypeCombo
.setEnabled(true);
347 private void showDatabaseConfig(ICdmDataSource dataSource
, DatabaseTypeEnum type
) {
348 if (type
.equals(DatabaseTypeEnum
.MySQL
)) {
349 createMySqlForm(dataSource
);
351 // TODO Intrusive - change to text
352 MessageDialog
.openInformation(GlobalController
.getShell(), "Database not yet implemented",
353 "Creation or editing of datasources using a(n) '" + type
.getName() + "' database not yet implemented.");
357 private void selectDatabaseType(DatabaseTypeEnum type
) {
361 // Go through types list until match is found
362 for (DatabaseTypeEnum typeInList
: databaseTypes
) {
363 if (typeInList
.equals(type
)) {
365 // Set combo to the type
366 databaseTypeCombo
.select(i
);
372 // Display type-specific input fields
373 showDatabaseConfig(dataSource
, type
);
375 // // If we're this far, database type was not in the list
376 // MessageDialog.openInformation(UiUtil.getShell(), "Database not yet implemented",
377 // "This dataSource expects a database type '" + type.getName() +
378 // "', which is not in the Taxonomic Editor's list of expected databases.");
381 private void populateComboBoxItems() {
384 if (databaseTypes
== null) {
385 databaseTypes
= new ArrayList
<DatabaseTypeEnum
>();
388 // Add types to the type drop-down and to the types collection
389 for (DatabaseTypeEnum type
: DatabaseTypeEnum
.getAllTypes()) {
390 databaseTypeCombo
.add(type
.getName());
391 databaseTypes
.add(type
);
396 * Create contents of the button bar
400 protected void createButtonsForButtonBar(Composite parent
) {
401 createButton(parent
, IDialogConstants
.OK_ID
, IDialogConstants
.OK_LABEL
,
403 createButton(parent
, IDialogConstants
.CANCEL_ID
,
404 IDialogConstants
.CANCEL_LABEL
, false);
408 * Return the initial size of the dialog
411 protected Point
getInitialSize() {
412 return new Point(500, 375);
415 private void removeDbConfigFields() {
416 // Init db config area by removing all children
417 if (dbConfigComposite
!= null) {
418 for (Control child
: dbConfigComposite
.getChildren()) {
424 private void createH2Form() {
428 private void createMySqlForm(final ICdmDataSource dataSource
) {
430 // Create composite for db config as necessary
431 if (dbConfigComposite
== null) {
432 dbConfigComposite
= new Composite(editDatasourceComposite
, SWT
.NONE
);
433 dbConfigComposite
.setLayoutData(new GridData(SWT
.FILL
, SWT
.FILL
, true, true, 2, 1));
434 GridLayout formLayout
= new GridLayout();
435 formLayout
.numColumns
= 2;
436 dbConfigComposite
.setLayout(formLayout
);
439 // Create group composite for authentication data
440 authenticationGroup
= new Group(dbConfigComposite
, SWT
.NONE
);
441 authenticationGroup
.setText("Authentication");
442 authenticationGroup
.setLayoutData(new GridData(SWT
.FILL
, SWT
.CENTER
, true, false, 2, 1));
443 GridLayout authenticationLayout
= new GridLayout();
444 authenticationLayout
.numColumns
= 2;
445 authenticationGroup
.setLayout(authenticationLayout
);
447 // Create database name label
448 Label databaseNameLabel
= new Label(authenticationGroup
, SWT
.NONE
);
449 databaseNameLabel
.setText("Database Name:");
451 // Create database name input
452 databaseNameText
= new Text(authenticationGroup
, SWT
.BORDER
);
453 databaseNameText
.setLayoutData(new GridData(SWT
.FILL
, SWT
.CENTER
, true, false));
455 // Create username label
456 Label usernameLabel
= new Label(authenticationGroup
, SWT
.NONE
);
457 usernameLabel
.setText("User Name:");
459 // Create username input
460 usernameText
= new Text(authenticationGroup
, SWT
.BORDER
);
461 usernameText
.setLayoutData(new GridData(SWT
.FILL
, SWT
.CENTER
, true, false));
463 // Create password label
464 Label passwordLabel
= new Label(authenticationGroup
, SWT
.NONE
);
465 passwordLabel
.setText("Password:");
467 // Create password input
468 passwordText
= new Text(authenticationGroup
, SWT
.BORDER
);
469 passwordText
.setLayoutData(new GridData(SWT
.FILL
, SWT
.CENTER
, true, false));
471 // // Create save password label
472 // Label savePasswordLabel = new Label(authenticationGroup, SWT.NONE);
473 // savePasswordLabel.setText("Save password:");
475 // // Create save password checkbox
476 // Button button = new Button(authenticationGroup, SWT.CHECK);
478 // Create group composite for location data
479 locationGroup
= new Group(dbConfigComposite
, SWT
.NONE
);
480 locationGroup
.setText("Location");
481 locationGroup
.setLayoutData(new GridData(SWT
.FILL
, SWT
.CENTER
, true, false, 2, 1));
482 GridLayout locationLayout
= new GridLayout();
483 locationLayout
.numColumns
= 2;
484 locationGroup
.setLayout(locationLayout
);
487 Label serverLabel
= new Label(locationGroup
, SWT
.NONE
);
488 serverLabel
.setText("Host:");
491 serverText
= new Text(locationGroup
, SWT
.BORDER
);
492 serverText
.setLayoutData(new GridData(SWT
.FILL
, SWT
.CENTER
, true, false));
495 Label portLabel
= new Label(locationGroup
, SWT
.NONE
);
496 portLabel
.setText("Port:");
499 portText
= new Text(locationGroup
, SWT
.BORDER
);
500 portText
.setLayoutData(new GridData(SWT
.FILL
, SWT
.CENTER
, true, false));
502 // Create composite for buttons
503 Composite buttonComposite
= new Composite(dbConfigComposite
, SWT
.NONE
);
504 buttonComposite
.setLayoutData(new GridData(SWT
.RIGHT
, SWT
.CENTER
, true, false));
505 GridLayout buttonLayout
= new GridLayout();
506 buttonLayout
.numColumns
= 2;
507 buttonComposite
.setLayout(buttonLayout
);
509 // Create test connection button
510 Button testButton
= new Button(buttonComposite
, SWT
.NONE
);
511 testButton
.setLayoutData(new GridData(SWT
.RIGHT
, SWT
.CENTER
, false, false));
512 testButton
.setText("Test connection");
514 // Test connection when button is pressed
515 testButton
.addMouseListener(new MouseAdapter() {
516 public void mouseUp(MouseEvent e
) {
521 // Create save button
522 saveButton
= new Button(buttonComposite
, SWT
.NONE
);
523 GridData saveButtonLayout
= new GridData(SWT
.RIGHT
, SWT
.CENTER
, false, false);
524 saveButtonLayout
.widthHint
= 76;
525 saveButton
.setLayoutData(saveButtonLayout
);
526 saveButton
.setText("Save");
527 saveButton
.setEnabled(false);
529 // Save data to datasource on mouse click
530 saveButton
.addMouseListener(new MouseAdapter() {
531 public void mouseUp(MouseEvent e
) {
536 // Populate fields with datasource data
537 if (dataSource
!= null) {
538 databaseNameText
.setText(CdmUtils
.Nz(dataSource
.getDatabase()));
539 passwordText
.setText(CdmUtils
.Nz(dataSource
.getPassword()));
540 usernameText
.setText(CdmUtils
.Nz(dataSource
.getUsername()));
541 serverText
.setText(CdmUtils
.Nz(dataSource
.getServer()));
542 portText
.setText(String
.valueOf(dataSource
.getPort()));
545 // Listen for changes to any input fields in order to toggle Save / OK
546 databaseNameText
.addModifyListener(modifyListener
);
547 usernameText
.addModifyListener(modifyListener
);
548 passwordText
.addModifyListener(modifyListener
);
549 serverText
.addModifyListener(modifyListener
);
550 portText
.addModifyListener(modifyListener
);
551 forceUserToSave(false);
554 container
.layout(true, true);
560 private void forceUserToSave(boolean mustSave
) {
561 saveButton
.setEnabled(mustSave
);
562 getButton(IDialogConstants
.OK_ID
).setEnabled(!mustSave
);
565 private void testDbConfig() {
567 ICdmDataSource dataSource
= CdmDataSource
.NewMySqlInstance(
568 serverText
.getText(),
569 databaseNameText
.getText(),
571 usernameText
.getText(),
572 passwordText
.getText());
573 if (dataSource
.testConnection()) {
574 MessageDialog
.openConfirm(GlobalController
.getShell(), "Test successful", "Test successful");
576 MessageDialog
.openWarning(GlobalController
.getShell(), "Test unsuccessful", "Test unsuccessful");
583 private int getPort() {
585 return Integer
.valueOf(portText
.getText());
586 } catch (NumberFormatException e
) {
587 portText
.setText("");
592 private void saveDbConfig() {
595 DatabaseTypeEnum databaseType
= databaseTypes
.get(databaseTypeCombo
.getSelectionIndex());
596 String dataSourceName
= datasourceNameText
.getText();
597 String server
= serverText
.getText();
598 String database
= databaseNameText
.getText();
599 String username
= usernameText
.getText();
600 String password
= passwordText
.getText();
601 Integer port
= getPort(); // new Integer(portText.getText());
603 // Remove data source in case it already exists
604 if (dataSource
!= null) {
605 removeDataSource(dataSource
);
610 CdmDataSourceRepository
.getDefault().save (
620 CdmDataSourceRepository
.getDefault().save (
629 // Refresh list of data sources to reflect changes
630 refreshDataSourceViewer();
631 forceUserToSave(false);
634 private void refreshDataSourceViewer() {
636 // Populate the list with saved datasources and an entry for "new dataSource"
637 dataSourceViewer
.setInput(
638 CdmDataSourceRepository
.getDefault().getAll());
641 public boolean close() {
642 return super.close();