Project

General

Profile

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

    
11
package eu.etaxonomy.taxeditor.store;
12

    
13
import java.sql.SQLException;
14
import java.util.concurrent.CancellationException;
15

    
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;
22

    
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.common.CdmMetaData;
28
import eu.etaxonomy.cdm.model.common.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;
32

    
33
/**
34
 * @author n.hoffmann
35
 * @created Dec 8, 2010
36
 * @version 1.0
37
 */
38
class CdmStoreConnector extends Job {
39
	private final Display display;
40
	private final ICdmDataSource dataSource;
41
	private DbSchemaValidation dbSchemaValidation;
42
	private final Resource applicationContextBean;
43

    
44
	/**
45
	 * @param datasource
46
	 * @param dbSchemaValidation
47
	 * @param applicationContextBean
48
	 */
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;
57
	}
58

    
59
	@Override
60
	public IStatus run(final IProgressMonitor monitor) {
61

    
62
		monitor.beginTask(getConnectionMessage(), 10);
63

    
64
		// check if database is up and running
65
		checkDatabaseReachable(monitor);
66

    
67
		if (!monitor.isCanceled()) {
68
			// check if the datasource actually holds data
69
			checkIsNonEmptyCdmDatabase(monitor);
70
		}
71

    
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);
77
		}
78

    
79
		// we are done with our low level checking and will free resources now
80
		dataSource.closeOpenConnections();
81

    
82
		if (!monitor.isCanceled()) {
83
			CdmStore.close(monitor);
84
		}
85

    
86
		CdmApplicationController applicationController = null;
87

    
88
		if (!monitor.isCanceled()) {
89
			CdmProgressMonitorAdapter subprogressMonitor = CdmProgressMonitorAdapter
90
					.CreateSubMonitor(monitor, 7);
91
			// This is where we instantiate the application controller
92
			try {
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);
99
				}
100
			} finally {
101
				monitor.done();
102
			}
103
		}
104
		
105
		
106

    
107
		if (!monitor.isCanceled()) {
108
			CdmStore.setInstance(applicationController, dataSource);
109

    
110
			display.asyncExec(new Runnable() {
111
				/*
112
				 * (non-Javadoc)
113
				 * 
114
				 * @see java.lang.Runnable#run()
115
				 */
116
				@Override
117
				public void run() {
118
					authenticate();
119

    
120
					startContext();
121
				}
122
			});
123

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

    
142
	}
143

    
144
	private void authenticate() {
145
		LoginDialog loginDialog = new LoginDialog(StoreUtil.getShell());
146
		loginDialog.open();
147
	}
148

    
149
	private void startContext() {
150
		CdmStore.getContextManager().notifyContextStart();
151
	}
152

    
153
	/**
154
	 * @return
155
	 */
156
	private String getConnectionMessage() {
157
		String message = "";
158
		if (dataSource.getDatabaseType().equals(DatabaseTypeEnum.H2)) {
159
			message = " local CDM Store ";
160
		} else {
161
			message = " CDM Community Store ";
162
		}
163
		message += "'" + dataSource.getName() + "'";
164

    
165
		message = "Connecting to" + message + ".";
166

    
167
		return message;
168
	}
169

    
170
	/**
171
	 * @return
172
	 * @throws SQLException
173
	 */
174
	private void checkDbSchemaVersionCompatibility(IProgressMonitor monitor) {
175
		monitor.subTask("Checking if datasource is compatible with this editor.");
176
		String dbSchemaVersion;
177
		boolean result = false;
178
		try {
179
			dbSchemaVersion = (String) dataSource
180
					.getSingleValue(MetaDataPropertyName.DB_SCHEMA_VERSION
181
							.getSqlQuery());
182
			// we assume that empty dbSchemaVersion means an empty database and
183
			// skip version checking
184
			result = dbSchemaVersion == null ? true : CdmMetaData
185
					.isDbSchemaVersionCompatible(dbSchemaVersion);
186
			monitor.worked(1);
187
		} catch (SQLException e) {
188
			//
189
		}
190

    
191
		if (!result) {
192
			// Show an error message
193
			StoreUtil
194
					.errorDialog(
195
							"DatabaseCompatibilityCheck failed",
196
							this,
197
							"The database schema for the chosen "
198
									+ "datasource '"
199
									+ dataSource
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.",
202
							null);
203

    
204
			monitor.setCanceled(true);
205
		}
206

    
207
	}
208

    
209
	private void checkIsNonEmptyCdmDatabase(IProgressMonitor monitor) {
210
		monitor.subTask("Checking if datasource is a non empty CDM database.");
211

    
212
		try {
213
			dataSource.getSingleValue(MetaDataPropertyName.DB_SCHEMA_VERSION
214
					.getSqlQuery());
215
		} catch (SQLException e1) {
216
			dbSchemaValidation = DbSchemaValidation.CREATE;
217
		}
218
	}
219

    
220
	private boolean causeIsCancelationExceptionRecursive(Throwable throwable){
221
		if(throwable == null){
222
			return false;
223
		}else if(throwable instanceof CancellationException){
224
			return true;
225
		}else{
226
			return causeIsCancelationExceptionRecursive(throwable.getCause());
227
		}
228
	}
229
	
230
	private void checkDatabaseReachable(IProgressMonitor monitor) {
231
		try {
232
			monitor.subTask("Checking if datasource is reachable.");
233
			dataSource.testConnection();
234
			monitor.worked(1);
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);
243
		}
244

    
245
	}
246
}
(2-2/9)