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
.local
.server
;
12 import java
.lang
.reflect
.InvocationTargetException
;
13 import java
.util
.concurrent
.CancellationException
;
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
;
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
.CdmAuthenticationException
;
44 import eu
.etaxonomy
.taxeditor
.store
.CdmStore
;
45 import eu
.etaxonomy
.taxeditor
.store
.LoginManager
;
46 import eu
.etaxonomy
.taxeditor
.store
.internal
.TaxeditorStorePlugin
;
51 * @created Dec 8, 2010
53 public class CdmStoreConnectorLocal
extends Job
{
54 private final Display display
;
55 private final ICdmSource cdmSource
;
56 private DbSchemaValidation dbSchemaValidation
;
57 private final Resource applicationContextBean
;
59 public CdmStoreConnectorLocal(Display display
,
61 DbSchemaValidation dbSchemaValidation
,
62 Resource applicationContextBean
) {
63 super(String
.format(Messages
.CdmStoreConnector_CREATING_DATAMODEL
, cdmSource
));
64 this.display
= display
;
65 this.cdmSource
= cdmSource
;
66 this.dbSchemaValidation
= dbSchemaValidation
;
67 this.applicationContextBean
= applicationContextBean
;
71 public IStatus
run(final IProgressMonitor monitor
) {
73 monitor
.beginTask(getConnectionMessage(), 10);
75 // check if database is up and running
76 checkDatabaseReachable(monitor
);
78 if (!monitor
.isCanceled()) {
79 // check if the datasource actually holds data
80 checkIsNonEmptyCdmDatabase(monitor
);
83 if (dbSchemaValidation
!= DbSchemaValidation
.CREATE
84 && !monitor
.isCanceled()) {
85 // if we do not create the datasource, we want to check if the
86 // datasource is compatible with this editor
87 checkDbSchemaVersionCompatibility(monitor
);
90 // we are done with our low level checking and will free resources now
91 cdmSource
.closeOpenConnections();
93 if (!monitor
.isCanceled()) {
94 CdmStore
.close(monitor
);
97 ICdmRepository applicationController
= null;
99 if (!monitor
.isCanceled()) {
100 CdmProgressMonitorAdapter subprogressMonitor
= CdmProgressMonitorAdapter
101 .CreateSubMonitor(monitor
, 7);
102 // This is where we instantiate the application controller
103 int oldPriority
= Thread
.currentThread().getPriority();
105 Thread
.currentThread().setPriority(10);
106 applicationController
= getApplicationController(cdmSource
,subprogressMonitor
);
107 MessagingUtils
.informationDialog(Messages
.CdmStoreConnector_SUCCESS
, Messages
.CdmStoreConnector_DATA_MODEL_CREATION_SUCCESSFUL
);
108 //FIXME E4 migrate or delete because data source view is not used anymore
109 // CdmDataSourceViewPartE4 dataSourceView = (CdmDataSourceViewPartE4) WorkbenchUtility.getE4WrappedPart(AbstractUtility.getView("eu.etaxonomy.taxeditor.view.datasource", false));
110 // if(dataSourceView!=null){
111 // dataSourceView.refresh();
113 EventUtility
.postEvent(WorkbenchEventConstants
.REFRESH_DATASOURCE
, true);
114 return Status
.OK_STATUS
;
115 } catch (Exception e
) {
116 if(! causeIsCancelationExceptionRecursive(e
)){
117 MessagingUtils
.errorDialog(Messages
.CdmStoreConnector_COULD_NOT_CREATE_DATAMODEL
, CdmStoreConnectorLocal
.class,
118 String
.format(Messages
.CdmStoreConnector_ERROR_DURING_DATAMODEL_CREATION
, cdmSource
.getName()), TaxeditorStorePlugin
.PLUGIN_ID
, e
, true);
119 return Status
.CANCEL_STATUS
;
123 Thread
.currentThread().setPriority(oldPriority
);
126 return Status
.CANCEL_STATUS
;
129 public void start(final RemotingLoginDialogLocal loginDialog
) {
130 // hide login dialog and start connection dialog
131 loginDialog
.setMessage(null);
132 loginDialog
.hide(true);
134 ProgressMonitorDialog dialog
= new ProgressMonitorDialog(AbstractUtility
.getShell());
137 dialog
.run(true, true, new IRunnableWithProgress() {
139 public void run(final IProgressMonitor monitor
) {
141 monitor
.beginTask(getConnectionMessage(), 7);
143 // check if database is up and running
144 checkDatabaseReachable(monitor
);
146 // check if the datasource actually holds data
147 checkIsNonEmptyCdmDatabase(monitor
);
149 if (dbSchemaValidation
!= DbSchemaValidation
.CREATE
) {
150 // if we do not create the datasource, we want to check if the
151 // datasource is compatible with this editor
152 checkDbSchemaVersionCompatibility(monitor
);
155 // we are done with our low level checking and will free resources now
156 cdmSource
.closeOpenConnections();
158 display
.syncExec(new Runnable() {
161 // close the current context
162 CdmStore
.close(monitor
, false);
166 ICdmRepository applicationController
= null;
168 if (!monitor
.isCanceled()) {
169 CdmProgressMonitorAdapter subprogressMonitor
= CdmProgressMonitorAdapter
170 .CreateSubMonitor(monitor
, 3);
171 // genrerate new application controller
172 applicationController
= getApplicationController(cdmSource
,subprogressMonitor
);
175 if (!monitor
.isCanceled()) {
176 CdmStoreLocal
.setInstance(applicationController
, cdmSource
);
177 CdmStoreLocal
.getTermManager().reset();
178 monitor
.subTask(Messages
.CdmStoreConnector_AUTHENTICATING_USER
);
179 display
.syncExec(()-> {
181 // create new security context
182 CdmStore
.getLoginManager().doAuthenticate(loginDialog
.getUsername(), loginDialog
.getPassword());
183 //loginDialog.onComplete();
184 CdmStore
.getContextManager().notifyContextStart();
185 loginDialog
.onComplete();
186 //TODO AM: is this necessary to be done on display thread?
187 new TermLoader().unloadAllTerms();
188 Rank
.initDefaultTerms();
189 NomenclaturalStatusType
.initDefaultTerms();
190 Language
.getDefaultLanguage();
191 } catch(CdmAuthenticationException cae
) {
192 loginDialog
.hide(false);
193 loginDialog
.setMessage(LoginManager
.INCORRECT_CREDENTIALS_MESSAGE
);
197 throw new RuntimeException("Login cancelled");
204 } catch (InvocationTargetException e
) {
205 loginDialog
.hide(false);
206 loginDialog
.setMessage(e
.getMessage());
207 } catch (InterruptedException e
) {
208 loginDialog
.hide(false);
209 loginDialog
.setMessage(e
.getMessage());
213 private ICdmRepository
getApplicationController(ICdmSource cdmSource
, CdmProgressMonitorAdapter subprogressMonitor
) {
214 if(cdmSource
instanceof ICdmDataSource
) {
215 return CdmApplicationController
.NewInstance(applicationContextBean
,
216 (ICdmDataSource
)cdmSource
,
220 } else if(cdmSource
instanceof ICdmRemoteSource
) {
221 return CdmApplicationRemoteController
.NewInstance((ICdmRemoteSource
)cdmSource
,
225 throw new UnsupportedOperationException("Cannot create application controller for " + cdmSource
.getName());
229 private String
getConnectionMessage() {
230 return cdmSource
.getConnectionMessage();
233 private void checkDbSchemaVersionCompatibility(IProgressMonitor monitor
) {
234 monitor
.subTask(Messages
.CdmStoreConnector_CHECK_IF_EDITOR_IS_COMPATIBLE
);
235 String dbSchemaVersion
;
237 String message
= null;
239 dbSchemaVersion
= cdmSource
.getDbSchemaVersion();
240 // we assume that empty dbSchemaVersion means an empty database and
241 // skip version checking
243 if(dbSchemaVersion
!= null) {
244 int compareVersion
= CdmMetaData
.compareVersion(dbSchemaVersion
, CdmMetaData
.getDbSchemaVersion(), 3, null);
245 // if the datasource version is greater than the taxeditor compatible version then the taxeditor needs to
246 // be updated else the datasource needs to be updated
247 if(compareVersion
> 0) {
248 message
= Messages
.CdmStoreConnector_UPDATE_EDITOR_OR_CHOOSE_COMPATIBLE_DATASOURCE
;
249 } else if (compareVersion
< 0) {
250 message
= Messages
.CdmStoreConnector_UPDATE_DATASOUREC_OR_CHOOSE_NEW_DATASOURCE
;
254 } catch (CdmSourceException e
) {
258 if (message
!= null) {
259 // Show an error message
262 Messages
.CdmStoreConnector_COMPATIBILITY_CHECK_FAILED
,
264 String
.format(Messages
.CdmStoreConnector_SCHEME_NOT_COMPATIBLE
, cdmSource
, message
),
267 monitor
.setCanceled(true);
271 private void checkIsNonEmptyCdmDatabase(IProgressMonitor monitor
) {
272 monitor
.subTask(Messages
.CdmStoreConnector_CHECK_IF_NON_EMPTY
);
273 boolean isDbEmpty
= false;
275 isDbEmpty
= cdmSource
.isDbEmpty();
276 } catch (CdmSourceException e
) {
280 dbSchemaValidation
= DbSchemaValidation
.CREATE
;
284 private boolean causeIsCancelationExceptionRecursive(Throwable throwable
){
285 if(throwable
== null){
287 }else if(throwable
instanceof CancellationException
){
290 return causeIsCancelationExceptionRecursive(throwable
.getCause());
294 private void checkDatabaseReachable(IProgressMonitor monitor
) {
296 monitor
.subTask(Messages
.CdmStoreConnector_CHECK_IF_REACHABLE
);
297 cdmSource
.checkConnection();
299 } catch (CdmSourceException e
) {
300 MessagingUtils
.messageDialog(Messages
.CdmStoreConnector_COULD_NOT_CONNECT_TO_CHOSEN_DATASOURCE
,
301 this, Messages
.CdmStoreConnector_REASON
+ e
.getMessage(), e
);
302 monitor
.setCanceled(true);