Project

General

Profile

Download (7.11 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.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;
34

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

    
46
	/**
47
	 * @param datasource
48
	 * @param dbSchemaValidation
49
	 * @param applicationContextBean
50
	 */
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;
59
	}
60

    
61
	@Override
62
	public IStatus run(final IProgressMonitor monitor) {
63

    
64
		monitor.beginTask(getConnectionMessage(), 10);
65

    
66
		// check if database is up and running
67
		checkDatabaseReachable(monitor);
68

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

    
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);
79
		}
80

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

    
84
		if (!monitor.isCanceled()) {
85
			CdmStore.close(monitor);
86
		}
87

    
88
		ICdmApplicationConfiguration applicationController = null;
89

    
90
		if (!monitor.isCanceled()) {
91
			CdmProgressMonitorAdapter subprogressMonitor = CdmProgressMonitorAdapter
92
					.CreateSubMonitor(monitor, 7);
93
			// This is where we instantiate the application controller
94
			try {
95
				//FIXME:Remoting change this to toggle remoting
96
				applicationController = 
97
						CdmApplicationDefaultController.NewInstance(applicationContextBean, 
98
								dataSource, 
99
								dbSchemaValidation,
100
								false, 
101
								subprogressMonitor);
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);
106
				}
107
			} finally {
108
				monitor.done();
109
			}
110
		}
111
		
112
		
113

    
114
		if (!monitor.isCanceled()) {
115
			CdmStore.setInstance(applicationController, dataSource);
116

    
117
			display.asyncExec(new Runnable() {
118
				/*
119
				 * (non-Javadoc)
120
				 * 
121
				 * @see java.lang.Runnable#run()
122
				 */
123
				@Override
124
				public void run() {
125
					authenticate();
126

    
127
					startContext();
128
				}
129
			});
130

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

    
149
	}
150

    
151
	private void authenticate() {
152
		LoginDialog loginDialog = new LoginDialog(StoreUtil.getShell());
153
		loginDialog.open();
154
	}
155

    
156
	private void startContext() {
157
		CdmStore.getContextManager().notifyContextStart();
158
	}
159

    
160
	/**
161
	 * @return
162
	 */
163
	private String getConnectionMessage() {
164
		String message = "";
165
		if (dataSource.getDatabaseType().equals(DatabaseTypeEnum.H2)) {
166
			message = " local CDM Store ";
167
		} else {
168
			message = " CDM Community Store ";
169
		}
170
		message += "'" + dataSource.getName() + "'";
171

    
172
		message = "Connecting to" + message + ".";
173

    
174
		return message;
175
	}
176

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

    
198
		if (!result) {
199
			// Show an error message
200
			StoreUtil
201
					.errorDialog(
202
							"DatabaseCompatibilityCheck failed",
203
							this,
204
							"The database schema for the chosen "
205
									+ "datasource '"
206
									+ dataSource
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.",
209
							null);
210

    
211
			monitor.setCanceled(true);
212
		}
213

    
214
	}
215

    
216
	private void checkIsNonEmptyCdmDatabase(IProgressMonitor monitor) {
217
		monitor.subTask("Checking if datasource is a non empty CDM database.");
218

    
219
		try {
220
			dataSource.getSingleValue(MetaDataPropertyName.DB_SCHEMA_VERSION
221
					.getSqlQuery());
222
		} catch (SQLException e1) {
223
			dbSchemaValidation = DbSchemaValidation.CREATE;
224
		}
225
	}
226

    
227
	private boolean causeIsCancelationExceptionRecursive(Throwable throwable){
228
		if(throwable == null){
229
			return false;
230
		}else if(throwable instanceof CancellationException){
231
			return true;
232
		}else{
233
			return causeIsCancelationExceptionRecursive(throwable.getCause());
234
		}
235
	}
236
	
237
	private void checkDatabaseReachable(IProgressMonitor monitor) {
238
		try {
239
			monitor.subTask("Checking if datasource is reachable.");
240
			dataSource.testConnection();
241
			monitor.worked(1);
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);
250
		}
251

    
252
	}
253
}
(2-2/9)