Project

General

Profile

« Previous | Next » 

Revision 19c39bf4

Added by Cherian Mathew over 8 years ago

#5029 Implement oneclick login for remoting

View differences:

eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/store/CdmStoreConnector.java
10 10

  
11 11
package eu.etaxonomy.taxeditor.store;
12 12

  
13
import java.lang.reflect.InvocationTargetException;
13 14
import java.sql.SQLException;
14 15
import java.util.concurrent.CancellationException;
15 16

  
......
17 18
import org.eclipse.core.runtime.IStatus;
18 19
import org.eclipse.core.runtime.Status;
19 20
import org.eclipse.core.runtime.jobs.Job;
21
import org.eclipse.jface.dialogs.ProgressMonitorDialog;
22
import org.eclipse.jface.operation.IRunnableWithProgress;
20 23
import org.eclipse.swt.widgets.Display;
21 24
import org.springframework.core.io.Resource;
22 25

  
......
32 35
import eu.etaxonomy.taxeditor.model.MessagingUtils;
33 36
import eu.etaxonomy.taxeditor.remoting.source.ICdmRemoteSource;
34 37
import eu.etaxonomy.taxeditor.ui.dialog.LoginDialog;
38
import eu.etaxonomy.taxeditor.ui.dialog.RemotingLoginDialog;
35 39
import eu.etaxonomy.taxeditor.view.datasource.CdmDataSourceViewPart;
36 40

  
41

  
37 42
/**
38 43
 * @author n.hoffmann
39 44
 * @created Dec 8, 2010
40 45
 * @version 1.0
41 46
 */
42 47
class CdmStoreConnector extends Job {
43
	private final Display display;
44
	private final ICdmSource cdmSource;
45
	private DbSchemaValidation dbSchemaValidation;
46
	private final Resource applicationContextBean;
47

  
48
	/**
49
	 * @param datasource
50
	 * @param dbSchemaValidation
51
	 * @param applicationContextBean
52
	 */
53
	public CdmStoreConnector(Display display, ICdmSource cdmSource,
54
			DbSchemaValidation dbSchemaValidation,
55
			Resource applicationContextBean) {
56
		super("Connecting to datasource: " + cdmSource);
57
		this.display = display;
58
		this.cdmSource = cdmSource;
59
		this.dbSchemaValidation = dbSchemaValidation;
60
		this.applicationContextBean = applicationContextBean;
61
	}
62

  
63
	@Override
64
	public IStatus run(final IProgressMonitor monitor) {
65

  
66
		monitor.beginTask(getConnectionMessage(), 10);
67

  
68
		// check if database is up and running
69
		checkDatabaseReachable(monitor);
70

  
71
		if (!monitor.isCanceled()) {
72
			// check if the datasource actually holds data
73
			checkIsNonEmptyCdmDatabase(monitor);
74
		}
75

  
76
		if (dbSchemaValidation != DbSchemaValidation.CREATE
77
				&& !monitor.isCanceled()) {
78
			// if we do not create the datasource, we want to check if the
79
			// datasource is compatible with this editor
80
			checkDbSchemaVersionCompatibility(monitor);
81
		}
82

  
83
		// we are done with our low level checking and will free resources now
84
		cdmSource.closeOpenConnections();
85

  
86
		if (!monitor.isCanceled()) {
87
			CdmStore.close(monitor);
88
		}
89

  
90
		ICdmApplicationConfiguration applicationController = null;
91

  
92
		if (!monitor.isCanceled()) {
93
			CdmProgressMonitorAdapter subprogressMonitor = CdmProgressMonitorAdapter
94
					.CreateSubMonitor(monitor, 7);
95
			// This is where we instantiate the application controller
96
			int oldPriority = Thread.currentThread().getPriority();
97
			try {
98
				Thread.currentThread().setPriority(10);
99
				applicationController = getApplicationController(cdmSource,subprogressMonitor);
100
			} catch (Exception e) {
101
				if(! causeIsCancelationExceptionRecursive(e)){
102
					return new Status(IStatus.ERROR, "Could not connect to CDM Store", "An error occurred while trying to connect to datasource: " + cdmSource.getName(), e);
103
				}
104
			} finally {
105
				monitor.done();
106
				Thread.currentThread().setPriority(oldPriority);
107
			}
108
		}
109

  
110

  
111

  
112
		if (!monitor.isCanceled()) {
113
			CdmStore.setInstance(applicationController, cdmSource);
114

  
115
			display.asyncExec(new Runnable() {
116
				/*
117
				 * (non-Javadoc)
118
				 *
119
				 * @see java.lang.Runnable#run()
120
				 */
121
				@Override
122
				public void run() {
123
					authenticate();
124

  
125
					startContext();
126
				}
127
			});
128

  
129
			MessagingUtils.info("Application context initialized.");
130
			return Status.OK_STATUS;
131
		} else {
132
			// Show datasource view if not shown yet
133
			display.asyncExec(new Runnable() {
134
				/*
135
				 * (non-Javadoc)
136
				 *
137
				 * @see java.lang.Runnable#run()
138
				 */
139
				@Override
140
				public void run() {
141
					StoreUtil.showView(CdmDataSourceViewPart.ID);
142
				}
143
			});
144
			return Status.CANCEL_STATUS;
145
		}
146

  
147
	}
148

  
149
	private ICdmApplicationConfiguration getApplicationController(ICdmSource cdmSource, CdmProgressMonitorAdapter subprogressMonitor) {
150
		if(cdmSource instanceof ICdmDataSource) {
151
			return  CdmApplicationController.NewInstance(applicationContextBean,
152
					(ICdmDataSource)cdmSource,
153
					dbSchemaValidation,
154
					false,
155
					subprogressMonitor);
156
		} else if(cdmSource instanceof ICdmRemoteSource) {
157
			return CdmApplicationRemoteController.NewInstance((ICdmRemoteSource)cdmSource,
158
							subprogressMonitor,
159
							null);
160
		} else {
161
			throw new UnsupportedOperationException("Cannot create application controller for " + cdmSource.getName());
162
		}
163
	}
164
	private void authenticate() {
165
		LoginDialog loginDialog = new LoginDialog(StoreUtil.getShell());
166
		loginDialog.open();
167
	}
168

  
169
	private void startContext() {
170
		CdmStore.getContextManager().notifyContextStart();
171
	}
172

  
173
	/**
174
	 * @return
175
	 */
176
	private String getConnectionMessage() {
177
		return cdmSource.getConnectionMessage();
178
	}
179

  
180
	/**
181
	 * @return
182
	 * @throws SQLException
183
	 */
184
	private void checkDbSchemaVersionCompatibility(IProgressMonitor monitor) {
185
		monitor.subTask("Checking if datasource is compatible with this editor.");
186
		String dbSchemaVersion;
187

  
188
		String message = null;
189
		try {
190
			dbSchemaVersion = cdmSource.getDbSchemaVersion();
191
			// we assume that empty dbSchemaVersion means an empty database and
192
			// skip version checking
193

  
194
			if(dbSchemaVersion != null) {
195
			    int compareVersion = CdmMetaData.compareVersion(dbSchemaVersion, CdmMetaData.getDbSchemaVersion(), 3, null);
196
			    // if the datasource version is greater than the taxeditor compatible version then the taxeditor needs to
197
			    // be updated else the datasource needs to be updated
198
			    if(compareVersion > 0) {
199
			        message = "Please update the Taxonomic Editor (Help->Check for Updates) or choose a compatible datasource";
200
			    } else if (compareVersion < 0) {
201
			        message = "Please update the chosen datasource or choose a new data source to connect to in the Datasource View.";
202
			    }
203
			}
204
			monitor.worked(1);
205
		} catch (CdmSourceException e) {
206
			//
207
		}
208

  
209
		if (message != null) {
210
			// Show an error message
211
			MessagingUtils
212
					.messageDialog(
213
							"Datasource Compatibility Check failed",
214
							this,
215
							"The database schema for the chosen "
216
									+ "datasource '"
217
									+ cdmSource
218
									+ "' \n is not compatible for this version of the taxonomic editor. \n\n"
219
									+ message,
220
							null);
221

  
222
			monitor.setCanceled(true);
223
		}
224

  
225
	}
226

  
227
	private void checkIsNonEmptyCdmDatabase(IProgressMonitor monitor) {
228
		monitor.subTask("Checking if datasource is a non empty CDM database.");
229
		boolean isDbEmpty = false;
230
		try {
231
			isDbEmpty = cdmSource.isDbEmpty();
232
		} catch (CdmSourceException e) {
233
			isDbEmpty = true;
234
		}
235
		if(isDbEmpty) {
236
			dbSchemaValidation = DbSchemaValidation.CREATE;
237
		}
238
	}
239

  
240
	private boolean causeIsCancelationExceptionRecursive(Throwable throwable){
241
		if(throwable == null){
242
			return false;
243
		}else if(throwable instanceof CancellationException){
244
			return true;
245
		}else{
246
			return causeIsCancelationExceptionRecursive(throwable.getCause());
247
		}
248
	}
249

  
250
	private void checkDatabaseReachable(IProgressMonitor monitor) {
251
		try {
252
			monitor.subTask("Checking if datasource is reachable.");
253
			cdmSource.checkConnection();
254
			monitor.worked(1);
255
		} catch (CdmSourceException e) {
256
			MessagingUtils.messageDialog("Could not connect to chosen datasource",
257
					this, "Reason: " + e.getMessage(), e);
258
			monitor.setCanceled(true);
259
		}
260
	}
48
    private final Display display;
49
    private final ICdmSource cdmSource;
50
    private DbSchemaValidation dbSchemaValidation;
51
    private final Resource applicationContextBean;
52

  
53

  
54
    /**
55
     * @param datasource
56
     * @param dbSchemaValidation
57
     * @param applicationContextBean
58
     */
59
    public CdmStoreConnector(Display display,
60
            ICdmSource cdmSource,
61
            DbSchemaValidation dbSchemaValidation,
62
            Resource applicationContextBean) {
63
        super("Connecting to datasource: " + cdmSource);
64
        this.display = display;
65
        this.cdmSource = cdmSource;
66
        this.dbSchemaValidation = dbSchemaValidation;
67
        this.applicationContextBean = applicationContextBean;
68
    }
69

  
70

  
71

  
72
    @Override
73
    public IStatus run(final IProgressMonitor monitor) {
74

  
75
        monitor.beginTask(getConnectionMessage(), 10);
76

  
77
        // check if database is up and running
78
        checkDatabaseReachable(monitor);
79

  
80
        if (!monitor.isCanceled()) {
81
            // check if the datasource actually holds data
82
            checkIsNonEmptyCdmDatabase(monitor);
83
        }
84

  
85
        if (dbSchemaValidation != DbSchemaValidation.CREATE
86
                && !monitor.isCanceled()) {
87
            // if we do not create the datasource, we want to check if the
88
            // datasource is compatible with this editor
89
            checkDbSchemaVersionCompatibility(monitor);
90
        }
91

  
92
        // we are done with our low level checking and will free resources now
93
        cdmSource.closeOpenConnections();
94

  
95
        if (!monitor.isCanceled()) {
96
            CdmStore.close(monitor);
97
        }
98

  
99
        ICdmApplicationConfiguration applicationController = null;
100

  
101
        if (!monitor.isCanceled()) {
102
            CdmProgressMonitorAdapter subprogressMonitor = CdmProgressMonitorAdapter
103
                    .CreateSubMonitor(monitor, 7);
104
            // This is where we instantiate the application controller
105
            int oldPriority = Thread.currentThread().getPriority();
106
            try {
107
                Thread.currentThread().setPriority(10);
108
                applicationController = getApplicationController(cdmSource,subprogressMonitor);
109
            } catch (Exception e) {
110
                if(! causeIsCancelationExceptionRecursive(e)){
111
                    return new Status(IStatus.ERROR, "Could not connect to CDM Store", "An error occurred while trying to connect to datasource: " + cdmSource.getName(), e);
112
                }
113
            } finally {
114
                monitor.done();
115
                Thread.currentThread().setPriority(oldPriority);
116
            }
117
        }
118

  
119

  
120

  
121
        if (!monitor.isCanceled()) {
122
            CdmStore.setInstance(applicationController, cdmSource);
123

  
124
            display.asyncExec(new Runnable() {
125
                /*
126
                 * (non-Javadoc)
127
                 *
128
                 * @see java.lang.Runnable#run()
129
                 */
130
                @Override
131
                public void run() {
132
                    authenticate();
133

  
134
                    startContext();
135
                }
136
            });
137

  
138
            MessagingUtils.info("Application context initialized.");
139
            return Status.OK_STATUS;
140
        } else {
141
            // Show datasource view if not shown yet
142
            display.asyncExec(new Runnable() {
143
                /*
144
                 * (non-Javadoc)
145
                 *
146
                 * @see java.lang.Runnable#run()
147
                 */
148
                @Override
149
                public void run() {
150
                    StoreUtil.showView(CdmDataSourceViewPart.ID);
151
                }
152
            });
153
            return Status.CANCEL_STATUS;
154
        }
155

  
156
    }
157

  
158
    public void start(final RemotingLoginDialog loginDialog) {
159
        // hide login dialog and start connection dialog
160
        loginDialog.setMessage(null);
161
        loginDialog.hide(true);
162

  
163

  
164
        ProgressMonitorDialog dialog = new ProgressMonitorDialog(StoreUtil.getShell());
165

  
166
        try {
167
            dialog.run(true, true, new IRunnableWithProgress() {
168
                @Override
169
                public void run(final IProgressMonitor monitor) {
170
                    try {
171
                        monitor.beginTask(getConnectionMessage(), 7);
172

  
173
                        // check if database is up and running
174
                        checkDatabaseReachable(monitor);
175

  
176
                        // check if the datasource actually holds data
177
                        checkIsNonEmptyCdmDatabase(monitor);
178

  
179
                        if (dbSchemaValidation != DbSchemaValidation.CREATE) {
180
                            // if we do not create the datasource, we want to check if the
181
                            // datasource is compatible with this editor
182
                            checkDbSchemaVersionCompatibility(monitor);
183
                        }
184

  
185
                        // we are done with our low level checking and will free resources now
186
                        cdmSource.closeOpenConnections();
187

  
188
                        display.syncExec(new Runnable() {
189
                            /*
190
                             * (non-Javadoc)
191
                             *
192
                             * @see java.lang.Runnable#run()
193
                             */
194
                            @Override
195
                            public void run() {
196
                                // close the current context
197
                                CdmStore.close(monitor, false);
198
                            }
199
                        });
200

  
201
                        ICdmApplicationConfiguration applicationController = null;
202

  
203
                        if (!monitor.isCanceled()) {
204
                            CdmProgressMonitorAdapter subprogressMonitor = CdmProgressMonitorAdapter
205
                                    .CreateSubMonitor(monitor, 3);
206
                            // genrerate new application controller
207
                            applicationController = getApplicationController(cdmSource,subprogressMonitor);
208
                        }
209

  
210

  
211
                        if (!monitor.isCanceled()) {
212
                            CdmStore.setInstance(applicationController, cdmSource);
213
                            monitor.subTask("Authenticating user and starting editor context...");
214
                            display.syncExec(new Runnable() {
215
                                /*
216
                                 * (non-Javadoc)
217
                                 *
218
                                 * @see java.lang.Runnable#run()
219
                                 */
220
                                @Override
221
                                public void run() {
222

  
223
                                    try {
224
                                        // create new security context
225
                                        CdmStore.getLoginManager().doAuthenticate(loginDialog.getUsername(), loginDialog.getPassword());
226
                                        loginDialog.dispose();
227
                                        // start editor context
228
                                        CdmStore.getContextManager().notifyContextStartWithoutDialog(monitor);
229

  
230
                                    } catch(CdmAuthenticationException cae) {
231
                                        loginDialog.hide(false);
232
                                        loginDialog.setMessage(cae.getMessage());
233
                                    }
234

  
235
                                }
236
                            });
237
                        } else {
238
                            throw new RuntimeException("Login cancelled");
239
                        }
240
                    } finally {
241
                        monitor.done();
242
                    }
243
                }
244
            });
245
        } catch (InvocationTargetException e) {
246
            loginDialog.hide(false);
247
            loginDialog.setMessage(e.getMessage());
248
        } catch (InterruptedException e) {
249
            loginDialog.hide(false);
250
            loginDialog.setMessage(e.getMessage());
251
        }
252
    }
253

  
254

  
255
    private ICdmApplicationConfiguration getApplicationController(ICdmSource cdmSource, CdmProgressMonitorAdapter subprogressMonitor) {
256
        if(cdmSource instanceof ICdmDataSource) {
257
            return  CdmApplicationController.NewInstance(applicationContextBean,
258
                    (ICdmDataSource)cdmSource,
259
                    dbSchemaValidation,
260
                    false,
261
                    subprogressMonitor);
262
        } else if(cdmSource instanceof ICdmRemoteSource) {
263
            return CdmApplicationRemoteController.NewInstance((ICdmRemoteSource)cdmSource,
264
                    subprogressMonitor,
265
                    null);
266
        } else {
267
            throw new UnsupportedOperationException("Cannot create application controller for " + cdmSource.getName());
268
        }
269
    }
270

  
271
    private void authenticate() {
272
        LoginDialog saloginDialog = new LoginDialog(StoreUtil.getShell());
273
        saloginDialog.open();
274
    }
275

  
276
    private void startContext() {
277
        CdmStore.getContextManager().notifyContextStart();
278
    }
279

  
280
    /**
281
     * @return
282
     */
283
    private String getConnectionMessage() {
284
        return cdmSource.getConnectionMessage();
285
    }
286

  
287
    /**
288
     * @return
289
     * @throws SQLException
290
     */
291
    private void checkDbSchemaVersionCompatibility(IProgressMonitor monitor) {
292
        monitor.subTask("Checking if datasource is compatible with this editor.");
293
        String dbSchemaVersion;
294

  
295
        String message = null;
296
        try {
297
            dbSchemaVersion = cdmSource.getDbSchemaVersion();
298
            // we assume that empty dbSchemaVersion means an empty database and
299
            // skip version checking
300

  
301
            if(dbSchemaVersion != null) {
302
                int compareVersion = CdmMetaData.compareVersion(dbSchemaVersion, CdmMetaData.getDbSchemaVersion(), 3, null);
303
                // if the datasource version is greater than the taxeditor compatible version then the taxeditor needs to
304
                // be updated else the datasource needs to be updated
305
                if(compareVersion > 0) {
306
                    message = "Please update the Taxonomic Editor (Help->Check for Updates) or choose a compatible datasource";
307
                } else if (compareVersion < 0) {
308
                    message = "Please update the chosen datasource or choose a new data source to connect to in the Datasource View.";
309
                }
310
            }
311
            monitor.worked(1);
312
        } catch (CdmSourceException e) {
313
            //
314
        }
315

  
316
        if (message != null) {
317
            // Show an error message
318
            MessagingUtils
319
            .messageDialog(
320
                    "Datasource Compatibility Check failed",
321
                    this,
322
                    "The database schema for the chosen "
323
                            + "datasource '"
324
                            + cdmSource
325
                            + "' \n is not compatible for this version of the taxonomic editor. \n\n"
326
                            + message,
327
                            null);
328

  
329
            monitor.setCanceled(true);
330
        }
331

  
332
    }
333

  
334
    private void checkIsNonEmptyCdmDatabase(IProgressMonitor monitor) {
335
        monitor.subTask("Checking if datasource is a non empty CDM database.");
336
        boolean isDbEmpty = false;
337
        try {
338
            isDbEmpty = cdmSource.isDbEmpty();
339
        } catch (CdmSourceException e) {
340
            isDbEmpty = true;
341
        }
342
        if(isDbEmpty) {
343
            dbSchemaValidation = DbSchemaValidation.CREATE;
344
        }
345
    }
346

  
347
    private boolean causeIsCancelationExceptionRecursive(Throwable throwable){
348
        if(throwable == null){
349
            return false;
350
        }else if(throwable instanceof CancellationException){
351
            return true;
352
        }else{
353
            return causeIsCancelationExceptionRecursive(throwable.getCause());
354
        }
355
    }
356

  
357
    private void checkDatabaseReachable(IProgressMonitor monitor) {
358
        try {
359
            monitor.subTask("Checking if datasource is reachable.");
360
            cdmSource.checkConnection();
361
            monitor.worked(1);
362
        } catch (CdmSourceException e) {
363
            MessagingUtils.messageDialog("Could not connect to chosen datasource",
364
                    this, "Reason: " + e.getMessage(), e);
365
            monitor.setCanceled(true);
366
        }
367
    }
368

  
369

  
261 370
}

Also available in: Unified diff