04c9eb4b51322980ffa8363aa949d837ce3128bf
[taxeditor.git] / eu.etaxonomy.taxeditor.store / src / main / java / eu / etaxonomy / taxeditor / datasource / wizard / CdmDataSourceCredentialsWizardPage.java
1 // $Id$
2 /**
3 * Copyright (C) 2007 EDIT
4 * European Distributed Institute of Taxonomy
5 * http://www.e-taxonomy.eu
6 *
7 * The contents of this file are subject to the Mozilla Public License Version 1.1
8 * See LICENSE.TXT at the top of this package for the full license terms.
9 */
10
11 package eu.etaxonomy.taxeditor.datasource.wizard;
12
13 import java.sql.SQLException;
14
15 import org.eclipse.jface.dialogs.MessageDialog;
16 import org.eclipse.jface.wizard.IWizardPage;
17 import org.eclipse.jface.wizard.WizardPage;
18 import org.eclipse.swt.SWT;
19 import org.eclipse.swt.events.ModifyEvent;
20 import org.eclipse.swt.events.ModifyListener;
21 import org.eclipse.swt.events.SelectionAdapter;
22 import org.eclipse.swt.events.SelectionEvent;
23 import org.eclipse.swt.layout.GridData;
24 import org.eclipse.swt.layout.GridLayout;
25 import org.eclipse.swt.widgets.Button;
26 import org.eclipse.swt.widgets.Composite;
27 import org.eclipse.swt.widgets.Group;
28 import org.eclipse.swt.widgets.Label;
29 import org.eclipse.swt.widgets.Text;
30
31 import eu.etaxonomy.cdm.database.CdmDataSource;
32 import eu.etaxonomy.cdm.database.CdmPersistentDataSource;
33 import eu.etaxonomy.cdm.database.ICdmDataSource;
34 import eu.etaxonomy.cdm.model.name.NomenclaturalCode;
35 import eu.etaxonomy.taxeditor.datasource.CdmDataSourceRepository;
36 import eu.etaxonomy.taxeditor.model.NomenclaturalCodeHelper;
37 import eu.etaxonomy.taxeditor.preference.PreferencesUtil;
38
39
40 /**
41 * <p>Abstract CdmDataSourceCredentialsWizardPage class.</p>
42 *
43 * @author n.hoffmann
44 * @created 19.05.2009
45 * @version 1.0
46 */
47 public abstract class CdmDataSourceCredentialsWizardPage extends WizardPage implements ModifyListener {
48 private ICdmDataSource dataSource;
49
50 protected Text text_password;
51 protected Text text_databaseName;
52 protected Text text_dataSourceName;
53 protected Text text_username;
54
55 protected Group authenticationGroup;
56 protected Group locationGroup;
57 protected Group nomenclaturalCodeGroup;
58
59 protected Composite composite;
60
61 protected Composite parent;
62
63 protected String name;
64 protected String database;
65 protected String username;
66 protected String password;
67
68 protected NomenclaturalCode nomenclaturalCode;
69
70 CdmDataSourceWizard.Mode mode;
71
72 /**
73 * <p>Constructor for CdmDataSourceCredentialsWizardPage.</p>
74 *
75 * @param pageName a {@link java.lang.String} object.
76 */
77 protected CdmDataSourceCredentialsWizardPage(String pageName, ICdmDataSource dataSource) {
78 super(pageName);
79 this.setPageComplete(false);
80 setDataSource(dataSource);
81 mode = CdmDataSourceWizard.Mode.CREATE;
82 }
83
84 /**
85 * <p>Constructor for CdmDataSourceCredentialsWizardPage.</p>
86 *
87 * @param pageName a {@link java.lang.String} object.
88 */
89 protected CdmDataSourceCredentialsWizardPage(String pageName, ICdmDataSource dataSource, CdmDataSourceWizard.Mode mode) {
90 super(pageName);
91 this.setPageComplete(false);
92
93 this.mode = mode;
94 if(mode == CdmDataSourceWizard.Mode.CLONE) {
95 setDataSource(CdmDataSource.NewInstance(dataSource));
96 } else {
97 setDataSource(dataSource);
98 }
99 }
100
101 /* (non-Javadoc)
102 * @see org.eclipse.jface.dialogs.IDialogPage#createControl(org.eclipse.swt.widgets.Composite)
103 */
104 /** {@inheritDoc} */
105 @Override
106 public void createControl(Composite parent) {
107 this.parent = parent;
108
109 // Create top-level composite
110 parent.setLayout(new GridLayout());
111 composite = new Composite(parent, SWT.NONE);
112 composite.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false,2,5));
113 GridLayout formLayout = new GridLayout();
114 formLayout.numColumns = 2;
115 composite.setLayout(formLayout);
116
117
118
119 // Create composite for data source name
120 Composite editDatasourceComposite = new Composite(composite, SWT.NONE);
121 GridData datasourceGridData = new GridData(SWT.FILL, SWT.TOP, true, true,2,1);
122 editDatasourceComposite.setLayoutData(datasourceGridData);
123 GridLayout datasourceLayout = new GridLayout();
124 datasourceLayout.numColumns = 2;
125 editDatasourceComposite.setLayout(datasourceLayout);
126
127 // Create label and input for dataSource name
128 Label datasourceNameLabel = new Label(editDatasourceComposite, SWT.NONE);
129 datasourceNameLabel.setText("Datasource Name:");
130 text_dataSourceName = new Text(editDatasourceComposite, SWT.BORDER);
131 text_dataSourceName.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
132
133 if(getDataSource() == null) {
134 editDatasourceComposite.setVisible(false);
135 }
136
137 // create a database specific form
138 createDatabaseForm();
139
140 // create the authentication input fields
141 createAuthenticationForm();
142
143 // create nomenclatural code combo
144 createNomenclaturalCodeForm();
145
146 // Create composite for buttons
147 Composite buttonComposite = new Composite(composite, SWT.NONE);
148 buttonComposite.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, true, false));
149 GridLayout buttonLayout = new GridLayout();
150 buttonLayout.numColumns = 1;
151 buttonComposite.setLayout(buttonLayout);
152
153 // Create test connection button
154 Button testButton = new Button(buttonComposite, SWT.NONE);
155 testButton.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false));
156 testButton.setText("Test connection");
157
158 // Test connection when button is pressed
159 testButton.addSelectionListener(new SelectionAdapter() {
160 /* (non-Javadoc)
161 * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)
162 */
163 @Override
164 public void widgetSelected(SelectionEvent e) {
165 testDbConfiguration();
166 }
167 });
168
169 setControl(composite);
170
171 init();
172
173 }
174
175 /**
176 * <p>createAuthenticationForm</p>
177 */
178 protected void createAuthenticationForm(){
179 // Create group composite for authentication data
180 authenticationGroup = new Group(composite, SWT.NONE);
181 authenticationGroup.setText("Authentication");
182 authenticationGroup.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 3));
183 GridLayout authenticationLayout = new GridLayout();
184 authenticationLayout.numColumns = 2;
185 authenticationGroup.setLayout(authenticationLayout);
186
187 // Create database name label
188 Label databaseNameLabel = new Label(authenticationGroup, SWT.NONE);
189 databaseNameLabel.setText("Database Name:");
190
191 // Create database name input
192 text_databaseName = new Text(authenticationGroup, SWT.BORDER);
193 text_databaseName.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
194
195
196 // Create username label
197 Label usernameLabel = new Label(authenticationGroup, SWT.NONE);
198 usernameLabel.setText("User Name:");
199
200 // Create username input
201 text_username = new Text(authenticationGroup, SWT.BORDER);
202 text_username.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
203
204
205 // Create password label
206 Label passwordLabel = new Label(authenticationGroup, SWT.NONE);
207 passwordLabel.setText("Password:");
208
209 // Create password input
210 text_password = new Text(authenticationGroup, SWT.BORDER | SWT.PASSWORD);
211 text_password.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
212
213 }
214
215 /**
216 * Initialize text fields
217 */
218 public void init() {
219 removeListeners();
220 if(getDataSource() != null){
221 text_dataSourceName.setText(getDataSource().getName());
222 text_databaseName.setText(getDataSource().getDatabase());
223 text_username.setText(getDataSource().getUsername());
224 text_password.setText(getDataSource().getPassword());
225 }
226 // add listeners after setting text to avoid the modify event being called
227 // for the initial value
228 addListeners();
229
230 // in the case of cloning we use the same datasource info
231 // except for the name
232 if(mode == CdmDataSourceWizard.Mode.CLONE) {
233 getDataSource().setName("");
234 text_dataSourceName.setText("");
235 } else {
236 name = text_dataSourceName.getText();
237 }
238
239 }
240
241 private void addListeners() {
242 text_dataSourceName.addModifyListener(this);
243 text_databaseName.addModifyListener(this);
244 text_username.addModifyListener(this);
245 text_password.addModifyListener(this);
246 }
247
248 private void removeListeners() {
249 text_dataSourceName.removeModifyListener(this);
250 text_databaseName.removeModifyListener(this);
251 text_username.removeModifyListener(this);
252 text_password.removeModifyListener(this);
253 }
254 /**
255 * Create a radio button group to select a nomenclatural code from
256 */
257 private void createNomenclaturalCodeForm() {
258 nomenclaturalCodeGroup = new Group(composite , SWT.NONE);
259 nomenclaturalCodeGroup.setLayout(new GridLayout());
260
261 nomenclaturalCode = dataSource != null ? dataSource.getNomenclaturalCode() : PreferencesUtil.getPreferredNomenclaturalCode();
262
263 for (final NomenclaturalCode code : NomenclaturalCodeHelper.getSupportedCodes()) {
264 Button button = new Button(nomenclaturalCodeGroup, SWT.RADIO);
265 button.setText(NomenclaturalCodeHelper.getDescription(code));
266 button.setData(code);
267 if (nomenclaturalCode != null) {
268 button.setSelection(nomenclaturalCode.equals(code));
269 }
270 button.addSelectionListener(new SelectionAdapter() {
271 @Override
272 public void widgetSelected(SelectionEvent e) {
273 nomenclaturalCode = (NomenclaturalCode) e.widget.getData();
274 modifyText(null);
275 }
276 });
277 }
278 }
279
280 public void testDbConfiguration(){
281 testDbConfiguration(false);
282 }
283
284 /**
285 * Tries to open a connection to the given dataSource. Generates a message on either
286 * failure or success
287 */
288 public void testDbConfiguration(boolean ignoreSuccess){
289 try{
290 updateAndCheck();
291 updateDataSource();
292 getDataSource().testConnection();
293 if(!ignoreSuccess) {
294 MessageDialog.openConfirm(parent.getShell(), "Connection Test successful", "Test successful!");
295 }
296 } catch(SQLException e){
297 MessageDialog.openWarning(parent.getShell(), "Connection Test unsuccessful", "Reason: " + e.getMessage()
298 + System.getProperty("line.separator") //we may use System.lineSeparator when migrated to Java 1.7
299 + System.getProperty("line.separator")
300 + "Please double check the connection fields");
301 } catch (ClassNotFoundException e) {
302 MessageDialog.openWarning(parent.getShell(), "Connection Test unsuccessful", "Reason: " + e.getMessage()
303 + System.getProperty("line.separator") //we may use System.lineSeparator when migrated to Java 1.7
304 + System.getProperty("line.separator")
305 + "Please double check the connection fields");
306 }
307 }
308
309 /**
310 * Form implementation for the specific database
311 */
312 public abstract void createDatabaseForm();
313
314 /**
315 * <p>updateLocation</p>
316 */
317 public abstract void updateLocation();
318
319 /**
320 * <p>updateDataSource</p>
321 */
322 public abstract void updateDataSource();
323
324 /**
325 * <p>checkPageComplete</p>
326 */
327 public void checkPageComplete(){
328 boolean complete = false;
329 if(mode == CdmDataSourceWizard.Mode.CREATE) {
330 complete = database.length() != 0;
331 } else {
332 complete = name.length() != 0 && database.length() != 0;
333 }
334 this.setPageComplete(complete);
335 }
336
337
338
339 /**
340 * updates the current datasource with form values
341 */
342 public void updateAuthentication(){
343 database = text_databaseName.getText();
344 username = text_username.getText();
345 password = text_password.getText();
346 }
347
348 /* (non-Javadoc)
349 * @see org.eclipse.jface.wizard.WizardPage#getNextPage()
350 */
351 /** {@inheritDoc} */
352 @Override
353 public IWizardPage getNextPage() {
354 return null;
355 }
356
357 /**
358 * <p>Setter for the field <code>dataSource</code>.</p>
359 *
360 * @param dataSource the dataSource to set
361 */
362 public void setDataSource(ICdmDataSource dataSource) {
363 this.dataSource = dataSource;
364 }
365
366 /**
367 * <p>Getter for the field <code>dataSource</code>.</p>
368 *
369 * @return the dataSource
370 */
371 public ICdmDataSource getUpdatedDataSource() {
372 updateDataSource();
373 return dataSource;
374 }
375
376 protected ICdmDataSource getDataSource() {
377 return dataSource;
378 }
379
380 /**
381 * <p>getDataSourceName</p>
382 *
383 * @return a {@link java.lang.String} object.
384 */
385 public String getDataSourceName() {
386 return name;
387 }
388
389 /* (non-Javadoc)
390 * @see org.eclipse.swto.events.ModifyListener#modifyText(org.eclipse.swt.events.ModifyEvent)
391 */
392 /** {@inheritDoc} */
393 @Override
394 public void modifyText(ModifyEvent e) {
395
396 name = text_dataSourceName.getText();
397 database = text_databaseName.getText();
398
399 switch(mode) {
400 case EDIT:
401 if(name.length() == 0){
402 name = "";
403 setErrorMessage("DataSource name must not be empty.");
404 this.setPageComplete(false);
405 return;
406 } else if ((!dataSource.getName().equals(name)) && (CdmDataSourceRepository.getDataSource(name) != null)) {
407 name = "";
408 setErrorMessage("DataSource with the same name already exists");
409 this.setPageComplete(false);
410 return;
411 }
412 break;
413 case CLONE:
414 if(name.length() == 0){
415 name = "";
416 setErrorMessage("DataSource name must not be empty.");
417 this.setPageComplete(false);
418 return;
419 } else if (CdmDataSourceRepository.getDataSource(name) != null) {
420 name = "";
421 setErrorMessage("DataSource with the same name already exists");
422 this.setPageComplete(false);
423 return;
424 }
425 break;
426 default:
427 break;
428 }
429
430 if(database.length() == 0){
431 setErrorMessage("Database name must not be empty.");
432 this.setPageComplete(false);
433 } else {
434 updateAndCheck();
435 setErrorMessage(null);
436 }
437 }
438
439
440 private void updateAndCheck() {
441 updateLocation();
442 updateAuthentication();
443 checkPageComplete();
444 }
445 /**
446 * <p>modifyTextWithoutTriggeringListeners</p>
447 *
448 * @param text a {@link org.eclipse.swt.widgets.Text} object.
449 * @param listener a {@link org.eclipse.swt.events.ModifyListener} object.
450 * @param string a {@link java.lang.String} object.
451 */
452 protected void modifyTextWithoutTriggeringListeners(Text text, ModifyListener listener, String string){
453 text.removeModifyListener(listener);
454 text.setText(string);
455 text.addModifyListener(listener);
456 }
457 }