Project

General

Profile

Download (12.9 KB) Statistics
| Branch: | Tag: | Revision:
1
/**
2
 * Copyright (C) 2007 EDIT
3
 * European Distributed Institute of Taxonomy
4
 * http://www.e-taxonomy.eu
5
 *
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.
8
 */
9

    
10
package eu.etaxonomy.taxeditor.store;
11

    
12
import java.lang.reflect.InvocationTargetException;
13
import java.util.concurrent.CancellationException;
14

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

    
24
import eu.etaxonomy.cdm.api.application.CdmApplicationController;
25
import eu.etaxonomy.cdm.api.application.CdmApplicationRemoteController;
26
import eu.etaxonomy.cdm.api.application.ICdmRepository;
27
import eu.etaxonomy.cdm.config.CdmSourceException;
28
import eu.etaxonomy.cdm.config.ICdmSource;
29
import eu.etaxonomy.cdm.database.DbSchemaValidation;
30
import eu.etaxonomy.cdm.database.ICdmDataSource;
31
import eu.etaxonomy.cdm.model.common.Language;
32
import eu.etaxonomy.cdm.model.metadata.CdmMetaData;
33
import eu.etaxonomy.cdm.model.name.NomenclaturalStatusType;
34
import eu.etaxonomy.cdm.model.name.Rank;
35
import eu.etaxonomy.cdm.model.term.init.TermLoader;
36
import eu.etaxonomy.taxeditor.event.EventUtility;
37
import eu.etaxonomy.taxeditor.event.WorkbenchEventConstants;
38
import eu.etaxonomy.taxeditor.l10n.Messages;
39
import eu.etaxonomy.taxeditor.model.AbstractUtility;
40
import eu.etaxonomy.taxeditor.model.CdmProgressMonitorAdapter;
41
import eu.etaxonomy.taxeditor.model.MessagingUtils;
42
import eu.etaxonomy.taxeditor.remoting.source.ICdmRemoteSource;
43
import eu.etaxonomy.taxeditor.store.internal.TaxeditorStorePlugin;
44
import eu.etaxonomy.taxeditor.ui.dialog.RemotingLoginDialog;
45

    
46
/**
47
 * @author n.hoffmann
48
 * @created Dec 8, 2010
49
 */
50
class CdmStoreConnector extends Job {
51
    private final Display display;
52
    private final ICdmSource cdmSource;
53
    private DbSchemaValidation dbSchemaValidation;
54
    private final Resource applicationContextBean;
55

    
56
    public CdmStoreConnector(Display display,
57
            ICdmSource cdmSource,
58
            DbSchemaValidation dbSchemaValidation,
59
            Resource applicationContextBean) {
60
        super(String.format(Messages.CdmStoreConnector_CREATING_DATAMODEL, cdmSource));
61
        this.display = display;
62
        this.cdmSource = cdmSource;
63
        this.dbSchemaValidation = dbSchemaValidation;
64
        this.applicationContextBean = applicationContextBean;
65
    }
66

    
67
    @Override
68
    public IStatus run(final IProgressMonitor monitor) {
69

    
70
        monitor.beginTask(getConnectionMessage(), 10);
71

    
72
        // check if database is up and running
73
        checkDatabaseReachable(monitor);
74

    
75
        if (!monitor.isCanceled()) {
76
            // check if the datasource actually holds data
77
            checkIsNonEmptyCdmDatabase(monitor);
78
        }
79

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

    
87
        // we are done with our low level checking and will free resources now
88
        cdmSource.closeOpenConnections();
89

    
90
        if (!monitor.isCanceled()) {
91
            CdmStore.close(monitor);
92
        }
93

    
94
        ICdmRepository applicationController = null;
95

    
96
        if (!monitor.isCanceled()) {
97
            CdmProgressMonitorAdapter subprogressMonitor = CdmProgressMonitorAdapter
98
                    .CreateSubMonitor(monitor, 7);
99
            // This is where we instantiate the application controller
100
            int oldPriority = Thread.currentThread().getPriority();
101
            try {
102
                Thread.currentThread().setPriority(10);
103
                applicationController = getApplicationController(cdmSource,subprogressMonitor);
104
                MessagingUtils.informationDialog(Messages.CdmStoreConnector_SUCCESS, Messages.CdmStoreConnector_DATA_MODEL_CREATION_SUCCESSFUL);
105
                //FIXME E4 migrate or delete because data source view is not used anymore
106
//                CdmDataSourceViewPartE4 dataSourceView = (CdmDataSourceViewPartE4) WorkbenchUtility.getE4WrappedPart(AbstractUtility.getView("eu.etaxonomy.taxeditor.view.datasource", false));
107
//                if(dataSourceView!=null){
108
//                    dataSourceView.refresh();
109
//                }
110
                EventUtility.postEvent(WorkbenchEventConstants.REFRESH_DATASOURCE, true);
111
                return Status.OK_STATUS;
112
            } catch (Exception e) {
113
                if(! causeIsCancelationExceptionRecursive(e)){
114
                    MessagingUtils.errorDialog(Messages.CdmStoreConnector_COULD_NOT_CREATE_DATAMODEL, CdmStoreConnector.class,
115
                    		String.format(Messages.CdmStoreConnector_ERROR_DURING_DATAMODEL_CREATION, cdmSource.getName()), TaxeditorStorePlugin.PLUGIN_ID, e, true);
116
                    return Status.CANCEL_STATUS;
117
                }
118
            } finally {
119
                monitor.done();
120
                Thread.currentThread().setPriority(oldPriority);
121
            }
122
        }
123
        return Status.CANCEL_STATUS;
124
    }
125

    
126
    public void start(final RemotingLoginDialog loginDialog) {
127
        // hide login dialog and start connection dialog
128
        loginDialog.setMessage(null);
129
        loginDialog.hide(true);
130

    
131
        ProgressMonitorDialog dialog = new ProgressMonitorDialog(AbstractUtility.getShell());
132

    
133
        try {
134
            dialog.run(true, true, new IRunnableWithProgress() {
135
                @Override
136
                public void run(final IProgressMonitor monitor) {
137
                    try {
138
                        monitor.beginTask(getConnectionMessage(), 7);
139

    
140
                        // check if database is up and running
141
                        checkDatabaseReachable(monitor);
142

    
143
                        // check if the datasource actually holds data
144
                        checkIsNonEmptyCdmDatabase(monitor);
145

    
146
                        if (dbSchemaValidation != DbSchemaValidation.CREATE) {
147
                            // if we do not create the datasource, we want to check if the
148
                            // datasource is compatible with this editor
149
                            checkDbSchemaVersionCompatibility(monitor);
150
                        }
151

    
152
                        // we are done with our low level checking and will free resources now
153
                        cdmSource.closeOpenConnections();
154

    
155
                        display.syncExec(new Runnable() {
156
                            @Override
157
                            public void run() {
158
                                // close the current context
159
                                CdmStore.close(monitor, false);
160
                            }
161
                        });
162

    
163
                        ICdmRepository applicationController = null;
164

    
165
                        if (!monitor.isCanceled()) {
166
                            CdmProgressMonitorAdapter subprogressMonitor = CdmProgressMonitorAdapter
167
                                    .CreateSubMonitor(monitor, 3);
168
                            // genrerate new application controller
169
                            applicationController = getApplicationController(cdmSource,subprogressMonitor);
170
                        }
171

    
172
                        if (!monitor.isCanceled()) {
173
                            CdmStore.setInstance(applicationController, cdmSource);
174
                            monitor.subTask(Messages.CdmStoreConnector_AUTHENTICATING_USER);
175
                            display.syncExec(()-> {
176
                                try {
177
                                    // create new security context
178
                                    CdmStore.getLoginManager().doAuthenticate(loginDialog.getUsername(), loginDialog.getPassword());
179
                                    //loginDialog.onComplete();
180
                                    CdmStore.getContextManager().notifyContextStart();
181
                                    loginDialog.onComplete();
182
                                    new TermLoader().unloadAllTerms();
183
                                    Rank.initDefaultTerms();
184
                                    NomenclaturalStatusType.initDefaultTerms();
185
                                    Language.getDefaultLanguage();
186
                                } catch(CdmAuthenticationException cae) {
187
                                    loginDialog.hide(false);
188
                                    loginDialog.setMessage(LoginManager.INCORRECT_CREDENTIALS_MESSAGE);
189
                                }
190
                            });
191
                        } else {
192
                            throw new RuntimeException("Login cancelled");
193
                        }
194
                    } finally {
195
                        monitor.done();
196
                    }
197
                }
198
            });
199
        } catch (InvocationTargetException e) {
200
            loginDialog.hide(false);
201
            loginDialog.setMessage(e.getMessage());
202
        } catch (InterruptedException e) {
203
            loginDialog.hide(false);
204
            loginDialog.setMessage(e.getMessage());
205
        }
206
    }
207

    
208
    private ICdmRepository getApplicationController(ICdmSource cdmSource, CdmProgressMonitorAdapter subprogressMonitor) {
209
        if(cdmSource instanceof ICdmDataSource) {
210
            return  CdmApplicationController.NewInstance(applicationContextBean,
211
                    (ICdmDataSource)cdmSource,
212
                    dbSchemaValidation,
213
                    false,
214
                    subprogressMonitor);
215
        } else if(cdmSource instanceof ICdmRemoteSource) {
216
            return CdmApplicationRemoteController.NewInstance((ICdmRemoteSource)cdmSource,
217
                    subprogressMonitor,
218
                    null);
219
        } else {
220
            throw new UnsupportedOperationException("Cannot create application controller for " + cdmSource.getName());
221
        }
222
    }
223

    
224
    private String getConnectionMessage() {
225
        return cdmSource.getConnectionMessage();
226
    }
227

    
228
    private void checkDbSchemaVersionCompatibility(IProgressMonitor monitor) {
229
        monitor.subTask(Messages.CdmStoreConnector_CHECK_IF_EDITOR_IS_COMPATIBLE);
230
        String dbSchemaVersion;
231

    
232
        String message = null;
233
        try {
234
            dbSchemaVersion = cdmSource.getDbSchemaVersion();
235
            // we assume that empty dbSchemaVersion means an empty database and
236
            // skip version checking
237

    
238
            if(dbSchemaVersion != null) {
239
                int compareVersion = CdmMetaData.compareVersion(dbSchemaVersion, CdmMetaData.getDbSchemaVersion(), 3, null);
240
                // if the datasource version is greater than the taxeditor compatible version then the taxeditor needs to
241
                // be updated else the datasource needs to be updated
242
                if(compareVersion > 0) {
243
                    message = Messages.CdmStoreConnector_UPDATE_EDITOR_OR_CHOOSE_COMPATIBLE_DATASOURCE;
244
                } else if (compareVersion < 0) {
245
                    message = Messages.CdmStoreConnector_UPDATE_DATASOUREC_OR_CHOOSE_NEW_DATASOURCE;
246
                }
247
            }
248
            monitor.worked(1);
249
        } catch (CdmSourceException e) {
250
            //
251
        }
252

    
253
        if (message != null) {
254
            // Show an error message
255
            MessagingUtils
256
            .messageDialog(
257
                    Messages.CdmStoreConnector_COMPATIBILITY_CHECK_FAILED,
258
                    this,
259
                    String.format(Messages.CdmStoreConnector_SCHEME_NOT_COMPATIBLE, cdmSource, message),
260
                            null);
261

    
262
            monitor.setCanceled(true);
263
        }
264
    }
265

    
266
    private void checkIsNonEmptyCdmDatabase(IProgressMonitor monitor) {
267
        monitor.subTask(Messages.CdmStoreConnector_CHECK_IF_NON_EMPTY);
268
        boolean isDbEmpty = false;
269
        try {
270
            isDbEmpty = cdmSource.isDbEmpty();
271
        } catch (CdmSourceException e) {
272
            isDbEmpty = true;
273
        }
274
        if(isDbEmpty) {
275
            dbSchemaValidation = DbSchemaValidation.CREATE;
276
        }
277
    }
278

    
279
    private boolean causeIsCancelationExceptionRecursive(Throwable throwable){
280
        if(throwable == null){
281
            return false;
282
        }else if(throwable instanceof CancellationException){
283
            return true;
284
        }else{
285
            return causeIsCancelationExceptionRecursive(throwable.getCause());
286
        }
287
    }
288

    
289
    private void checkDatabaseReachable(IProgressMonitor monitor) {
290
        try {
291
            monitor.subTask(Messages.CdmStoreConnector_CHECK_IF_REACHABLE);
292
            cdmSource.checkConnection();
293
            monitor.worked(1);
294
        } catch (CdmSourceException e) {
295
            MessagingUtils.messageDialog(Messages.CdmStoreConnector_COULD_NOT_CONNECT_TO_CHOSEN_DATASOURCE,
296
                    this, Messages.CdmStoreConnector_REASON + e.getMessage(), e);
297
            monitor.setCanceled(true);
298
        }
299
    }
300
}
(4-4/13)