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
.CdmApplicationController
;
24 import eu
.etaxonomy
.cdm
.database
.DatabaseTypeEnum
;
25 import eu
.etaxonomy
.cdm
.database
.DbSchemaValidation
;
26 import eu
.etaxonomy
.cdm
.database
.ICdmDataSource
;
27 import eu
.etaxonomy
.cdm
.model
.metadata
.CdmMetaData
;
28 import eu
.etaxonomy
.cdm
.model
.metadata
.CdmMetaData
.MetaDataPropertyName
;
29 import eu
.etaxonomy
.taxeditor
.model
.CdmProgressMonitorAdapter
;
30 import eu
.etaxonomy
.taxeditor
.ui
.dialog
.LoginDialog
;
31 import eu
.etaxonomy
.taxeditor
.view
.datasource
.CdmDataSourceViewPart
;
35 * @created Dec 8, 2010
38 class CdmStoreConnector
extends Job
{
39 private final Display display
;
40 private final ICdmDataSource dataSource
;
41 private DbSchemaValidation dbSchemaValidation
;
42 private final Resource applicationContextBean
;
46 * @param dbSchemaValidation
47 * @param applicationContextBean
49 public CdmStoreConnector(Display display
, ICdmDataSource datasource
,
50 DbSchemaValidation dbSchemaValidation
,
51 Resource applicationContextBean
) {
52 super("Connecting to datasource: " + datasource
);
53 this.display
= display
;
54 this.dataSource
= datasource
;
55 this.dbSchemaValidation
= dbSchemaValidation
;
56 this.applicationContextBean
= applicationContextBean
;
60 public IStatus
run(final IProgressMonitor monitor
) {
62 monitor
.beginTask(getConnectionMessage(), 10);
64 // check if database is up and running
65 checkDatabaseReachable(monitor
);
67 if (!monitor
.isCanceled()) {
68 // check if the datasource actually holds data
69 checkIsNonEmptyCdmDatabase(monitor
);
72 if (dbSchemaValidation
!= DbSchemaValidation
.CREATE
73 && !monitor
.isCanceled()) {
74 // if we do not create the datasource, we want to check if the
75 // datasource is compatible with this editor
76 checkDbSchemaVersionCompatibility(monitor
);
79 // we are done with our low level checking and will free resources now
80 dataSource
.closeOpenConnections();
82 if (!monitor
.isCanceled()) {
83 CdmStore
.close(monitor
);
86 CdmApplicationController applicationController
= null;
88 if (!monitor
.isCanceled()) {
89 CdmProgressMonitorAdapter subprogressMonitor
= CdmProgressMonitorAdapter
90 .CreateSubMonitor(monitor
, 7);
91 // This is where we instantiate the application controller
93 applicationController
= CdmApplicationController
.NewInstance(
94 applicationContextBean
, dataSource
, dbSchemaValidation
,
95 false, subprogressMonitor
);
96 } catch (Exception e
) {
97 if(! causeIsCancelationExceptionRecursive(e
)){
98 return new Status(IStatus
.ERROR
, "Could not connect to CDM Store", "An error occurred while trying to connect to datasource: " + dataSource
.getName(), e
);
107 if (!monitor
.isCanceled()) {
108 CdmStore
.setInstance(applicationController
, dataSource
);
110 display
.asyncExec(new Runnable() {
114 * @see java.lang.Runnable#run()
124 StoreUtil
.info("Application context initialized.");
125 return Status
.OK_STATUS
;
127 // Show datasource view if not shown yet
128 display
.asyncExec(new Runnable() {
132 * @see java.lang.Runnable#run()
136 StoreUtil
.showView(CdmDataSourceViewPart
.ID
);
139 return Status
.CANCEL_STATUS
;
144 private void authenticate() {
145 LoginDialog loginDialog
= new LoginDialog(StoreUtil
.getShell());
149 private void startContext() {
150 CdmStore
.getContextManager().notifyContextStart();
156 private String
getConnectionMessage() {
158 if (dataSource
.getDatabaseType().equals(DatabaseTypeEnum
.H2
)) {
159 message
= " local CDM Store ";
161 message
= " CDM Community Store ";
163 message
+= "'" + dataSource
.getName() + "'";
165 message
= "Connecting to" + message
+ ".";
172 * @throws SQLException
174 private void checkDbSchemaVersionCompatibility(IProgressMonitor monitor
) {
175 monitor
.subTask("Checking if datasource is compatible with this editor.");
176 String dbSchemaVersion
;
177 boolean result
= false;
179 dbSchemaVersion
= (String
) dataSource
180 .getSingleValue(MetaDataPropertyName
.DB_SCHEMA_VERSION
182 // we assume that empty dbSchemaVersion means an empty database and
183 // skip version checking
184 result
= dbSchemaVersion
== null ?
true : CdmMetaData
185 .isDbSchemaVersionCompatible(dbSchemaVersion
);
187 } catch (SQLException e
) {
192 // Show an error message
195 "DatabaseCompatibilityCheck failed",
197 "The database schema for the chosen "
200 + "' \n is not valid for this version of the taxonomic editor. \n"
201 + "Please update the chosen datasource or choose a new data source to connect to in the Datasource View.",
204 monitor
.setCanceled(true);
209 private void checkIsNonEmptyCdmDatabase(IProgressMonitor monitor
) {
210 monitor
.subTask("Checking if datasource is a non empty CDM database.");
213 dataSource
.getSingleValue(MetaDataPropertyName
.DB_SCHEMA_VERSION
215 } catch (SQLException e1
) {
216 dbSchemaValidation
= DbSchemaValidation
.CREATE
;
220 private boolean causeIsCancelationExceptionRecursive(Throwable throwable
){
221 if(throwable
== null){
223 }else if(throwable
instanceof CancellationException
){
226 return causeIsCancelationExceptionRecursive(throwable
.getCause());
230 private void checkDatabaseReachable(IProgressMonitor monitor
) {
232 monitor
.subTask("Checking if datasource is reachable.");
233 dataSource
.testConnection();
235 } catch (ClassNotFoundException e
) {
236 StoreUtil
.errorDialog("Could not connect to chosen datasource",
237 this, "Reason: " + e
.getMessage(), e
);
238 monitor
.setCanceled(true);
239 } catch (SQLException e
) {
240 StoreUtil
.errorDialog("Could not connect to chosen datasource",
241 this, "Reason: " + e
.getMessage(), e
);
242 monitor
.setCanceled(true);