3 * Copyright (C) 2007 EDIT
4 * European Distributed Institute of Taxonomy
5 * http://www.e-taxonomy.eu
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.
11 package eu
.etaxonomy
.taxeditor
.store
;
13 import java
.sql
.SQLException
;
14 import java
.util
.concurrent
.CancellationException
;
16 import org
.eclipse
.core
.runtime
.IProgressMonitor
;
17 import org
.eclipse
.core
.runtime
.IStatus
;
18 import org
.eclipse
.core
.runtime
.Status
;
19 import org
.eclipse
.core
.runtime
.jobs
.Job
;
20 import org
.eclipse
.swt
.widgets
.Display
;
21 import org
.springframework
.core
.io
.Resource
;
23 import eu
.etaxonomy
.cdm
.api
.application
.CdmApplicationDefaultController
;
24 import eu
.etaxonomy
.cdm
.api
.application
.ICdmApplicationConfiguration
;
25 import eu
.etaxonomy
.cdm
.database
.DatabaseTypeEnum
;
26 import eu
.etaxonomy
.cdm
.database
.DbSchemaValidation
;
27 import eu
.etaxonomy
.cdm
.database
.ICdmDataSource
;
28 import eu
.etaxonomy
.cdm
.model
.metadata
.CdmMetaData
;
29 import eu
.etaxonomy
.cdm
.model
.metadata
.CdmMetaData
.MetaDataPropertyName
;
30 import eu
.etaxonomy
.cdm
.api
.application
.CdmApplicationRemoteController
;
31 import eu
.etaxonomy
.taxeditor
.model
.CdmProgressMonitorAdapter
;
32 import eu
.etaxonomy
.taxeditor
.ui
.dialog
.LoginDialog
;
33 import eu
.etaxonomy
.taxeditor
.view
.datasource
.CdmDataSourceViewPart
;
37 * @created Dec 8, 2010
40 class CdmStoreConnector
extends Job
{
41 private final Display display
;
42 private final ICdmDataSource dataSource
;
43 private DbSchemaValidation dbSchemaValidation
;
44 private final Resource applicationContextBean
;
48 * @param dbSchemaValidation
49 * @param applicationContextBean
51 public CdmStoreConnector(Display display
, ICdmDataSource datasource
,
52 DbSchemaValidation dbSchemaValidation
,
53 Resource applicationContextBean
) {
54 super("Connecting to datasource: " + datasource
);
55 this.display
= display
;
56 this.dataSource
= datasource
;
57 this.dbSchemaValidation
= dbSchemaValidation
;
58 this.applicationContextBean
= applicationContextBean
;
62 public IStatus
run(final IProgressMonitor monitor
) {
64 monitor
.beginTask(getConnectionMessage(), 10);
66 // check if database is up and running
67 checkDatabaseReachable(monitor
);
69 if (!monitor
.isCanceled()) {
70 // check if the datasource actually holds data
71 checkIsNonEmptyCdmDatabase(monitor
);
74 if (dbSchemaValidation
!= DbSchemaValidation
.CREATE
75 && !monitor
.isCanceled()) {
76 // if we do not create the datasource, we want to check if the
77 // datasource is compatible with this editor
78 checkDbSchemaVersionCompatibility(monitor
);
81 // we are done with our low level checking and will free resources now
82 dataSource
.closeOpenConnections();
84 if (!monitor
.isCanceled()) {
85 CdmStore
.close(monitor
);
88 ICdmApplicationConfiguration applicationController
= null;
90 if (!monitor
.isCanceled()) {
91 CdmProgressMonitorAdapter subprogressMonitor
= CdmProgressMonitorAdapter
92 .CreateSubMonitor(monitor
, 7);
93 // This is where we instantiate the application controller
95 //FIXME:Remoting change this to toggle remoting
96 applicationController
=
97 CdmApplicationDefaultController
.NewInstance(applicationContextBean
,
102 //applicationController = CdmApplicationRemoteController.NewInstance();
103 } catch (Exception e
) {
104 if(! causeIsCancelationExceptionRecursive(e
)){
105 return new Status(IStatus
.ERROR
, "Could not connect to CDM Store", "An error occurred while trying to connect to datasource: " + dataSource
.getName(), e
);
114 if (!monitor
.isCanceled()) {
115 CdmStore
.setInstance(applicationController
, dataSource
);
117 display
.asyncExec(new Runnable() {
121 * @see java.lang.Runnable#run()
131 StoreUtil
.info("Application context initialized.");
132 return Status
.OK_STATUS
;
134 // Show datasource view if not shown yet
135 display
.asyncExec(new Runnable() {
139 * @see java.lang.Runnable#run()
143 StoreUtil
.showView(CdmDataSourceViewPart
.ID
);
146 return Status
.CANCEL_STATUS
;
151 private void authenticate() {
152 LoginDialog loginDialog
= new LoginDialog(StoreUtil
.getShell());
156 private void startContext() {
157 CdmStore
.getContextManager().notifyContextStart();
163 private String
getConnectionMessage() {
165 if (dataSource
.getDatabaseType().equals(DatabaseTypeEnum
.H2
)) {
166 message
= " local CDM Store ";
168 message
= " CDM Community Store ";
170 message
+= "'" + dataSource
.getName() + "'";
172 message
= "Connecting to" + message
+ ".";
179 * @throws SQLException
181 private void checkDbSchemaVersionCompatibility(IProgressMonitor monitor
) {
182 monitor
.subTask("Checking if datasource is compatible with this editor.");
183 String dbSchemaVersion
;
184 boolean result
= false;
186 dbSchemaVersion
= (String
) dataSource
187 .getSingleValue(MetaDataPropertyName
.DB_SCHEMA_VERSION
189 // we assume that empty dbSchemaVersion means an empty database and
190 // skip version checking
191 result
= dbSchemaVersion
== null ?
true : CdmMetaData
192 .isDbSchemaVersionCompatible(dbSchemaVersion
);
194 } catch (SQLException e
) {
199 // Show an error message
202 "DatabaseCompatibilityCheck failed",
204 "The database schema for the chosen "
207 + "' \n is not valid for this version of the taxonomic editor. \n"
208 + "Please update the chosen datasource or choose a new data source to connect to in the Datasource View.",
211 monitor
.setCanceled(true);
216 private void checkIsNonEmptyCdmDatabase(IProgressMonitor monitor
) {
217 monitor
.subTask("Checking if datasource is a non empty CDM database.");
220 dataSource
.getSingleValue(MetaDataPropertyName
.DB_SCHEMA_VERSION
222 } catch (SQLException e1
) {
223 dbSchemaValidation
= DbSchemaValidation
.CREATE
;
227 private boolean causeIsCancelationExceptionRecursive(Throwable throwable
){
228 if(throwable
== null){
230 }else if(throwable
instanceof CancellationException
){
233 return causeIsCancelationExceptionRecursive(throwable
.getCause());
237 private void checkDatabaseReachable(IProgressMonitor monitor
) {
239 monitor
.subTask("Checking if datasource is reachable.");
240 dataSource
.testConnection();
242 } catch (ClassNotFoundException e
) {
243 StoreUtil
.errorDialog("Could not connect to chosen datasource",
244 this, "Reason: " + e
.getMessage(), e
);
245 monitor
.setCanceled(true);
246 } catch (SQLException e
) {
247 StoreUtil
.errorDialog("Could not connect to chosen datasource",
248 this, "Reason: " + e
.getMessage(), e
);
249 monitor
.setCanceled(true);