853dbe42c7044ea1acd929ee9e4b22fefb3306d0
[taxeditor.git] / eu.etaxonomy.taxeditor.store / src / main / java / eu / etaxonomy / taxeditor / store / CdmStoreConnector.java
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
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.swt.widgets.Display;
20 import org.springframework.core.io.Resource;
21
22 import eu.etaxonomy.cdm.api.application.CdmApplicationController;
23 import eu.etaxonomy.cdm.database.DatabaseTypeEnum;
24 import eu.etaxonomy.cdm.database.DbSchemaValidation;
25 import eu.etaxonomy.cdm.database.ICdmDataSource;
26 import eu.etaxonomy.cdm.model.common.CdmMetaData;
27 import eu.etaxonomy.cdm.model.common.CdmMetaData.MetaDataPropertyName;
28 import eu.etaxonomy.taxeditor.model.CdmProgressMonitorAdapter;
29 import eu.etaxonomy.taxeditor.ui.dialogs.LoginDialog;
30 import eu.etaxonomy.taxeditor.view.datasource.CdmDataSourceViewPart;
31
32 /**
33 * @author n.hoffmann
34 * @created Dec 8, 2010
35 * @version 1.0
36 */
37 class CdmStoreConnector extends Job{
38 private Display display;
39 private ICdmDataSource dataSource;
40 private DbSchemaValidation dbSchemaValidation;
41 private Resource applicationContextBean;
42
43 /**
44 * @param datasource
45 * @param dbSchemaValidation
46 * @param applicationContextBean
47 */
48 public CdmStoreConnector(Display display, ICdmDataSource datasource,
49 DbSchemaValidation dbSchemaValidation,
50 Resource applicationContextBean) {
51 super("Connecting to datasource: " + datasource);
52 this.display = display;
53 this.dataSource = datasource;
54 this.dbSchemaValidation = dbSchemaValidation;
55 this.applicationContextBean = applicationContextBean;
56 }
57
58
59 public IStatus run(final IProgressMonitor monitor) {
60
61 monitor.beginTask(getConnectionMessage(), 10);
62
63 // check if database is up and running
64 checkDatabaseReachable(monitor);
65
66 if(! monitor.isCanceled()){
67 // check if the datasource actually holds data
68 checkIsNonEmptyCdmDatabase(monitor);
69 }
70
71 if(dbSchemaValidation != DbSchemaValidation.CREATE && ! monitor.isCanceled()){
72 // if we do not create the datasource, we want to check if the datasource is compatible with this editor
73 checkDbSchemaVersionCompatibility(monitor);
74 }
75
76 // we are done with our low level checking and will free resources now
77 dataSource.closeOpenConnections();
78
79 if(! monitor.isCanceled()){
80 CdmStore.close(monitor);
81 }
82
83 CdmApplicationController applicationController = null;
84
85 if(! monitor.isCanceled()){
86 CdmProgressMonitorAdapter subprogressMonitor = CdmProgressMonitorAdapter.CreateSubMonitor(monitor, 5);
87 // This is where we instantiate the application controller
88 try{
89 applicationController = CdmApplicationController.NewInstance(applicationContextBean, dataSource, dbSchemaValidation, false, subprogressMonitor);
90 }catch(Exception e){
91 StoreUtil.error(this.getClass(), e.getMessage(), e);
92 }
93 }
94
95 monitor.done();
96
97 if(! monitor.isCanceled()){
98 CdmStore.setInstance(applicationController, dataSource);
99
100 display.asyncExec(new Runnable(){
101 /* (non-Javadoc)
102 * @see java.lang.Runnable#run()
103 */
104 @Override
105 public void run() {
106 authenticate();
107
108 startContext();
109 }
110 });
111
112 StoreUtil.info("Application context initialized.");
113 return Status.OK_STATUS;
114 }else{
115 // Show datasource view if not shown yet
116 display.asyncExec(new Runnable(){
117 /* (non-Javadoc)
118 * @see java.lang.Runnable#run()
119 */
120 @Override
121 public void run() {
122 StoreUtil.showView(CdmDataSourceViewPart.ID);
123 }
124 });
125 return Status.CANCEL_STATUS;
126 }
127
128
129 }
130
131 private void authenticate(){
132 LoginDialog loginDialog = new LoginDialog(StoreUtil.getShell());
133 loginDialog.open();
134 }
135
136 private void startContext(){
137 CdmStore.getContextManager().notifyContextStart();
138 }
139
140 /**
141 * @return
142 */
143 private String getConnectionMessage() {
144 String message = "";
145 if(dataSource.getDatabaseType().equals(DatabaseTypeEnum.H2)){
146 message = " local CDM Store ";
147 }else{
148 message = " CDM Community Store ";
149 }
150 message += "'" + dataSource.getName() + "'";
151
152 message = "Connecting to" + message + ".";
153
154 return message;
155 }
156
157 /**
158 * @return
159 * @throws SQLException
160 */
161 private void checkDbSchemaVersionCompatibility(IProgressMonitor monitor) {
162 monitor.subTask("Checking if datasource is compatible with this editor.");
163 String dbSchemaVersion;
164 boolean result = false;
165 try {
166 dbSchemaVersion = (String) dataSource.getSingleValue(MetaDataPropertyName.DB_SCHEMA_VERSION.getSqlQuery());
167 // we assume that empty dbSchemaVersion means an empty database and skip version checking
168 result = dbSchemaVersion == null ? true : CdmMetaData.isDbSchemaVersionCompatible(dbSchemaVersion);
169 monitor.worked(1);
170 } catch (SQLException e) {
171 //
172 }
173
174 if(!result){
175 // Show an error message
176 StoreUtil.errorDialog("DatabaseCompatibilityCheck failed", this, "The database schema for the chosen " +
177 "datasource '" + dataSource + "' \n is not valid for this version of the taxonomic editor. \n" +
178 "Please update the chosen datasource or choose a new data source to connect to in the Datasource View.", null);
179
180 monitor.setCanceled(true);
181 }
182
183 }
184
185 private void checkIsNonEmptyCdmDatabase(IProgressMonitor monitor) {
186 monitor.subTask("Checking if datasource is a non empty CDM database.");
187
188 try {
189 dataSource.getSingleValue(MetaDataPropertyName.DB_SCHEMA_VERSION.getSqlQuery());
190 } catch (SQLException e1) {
191 dbSchemaValidation = DbSchemaValidation.CREATE;
192 }
193 }
194
195 private void checkDatabaseReachable(IProgressMonitor monitor){
196 try {
197 monitor.subTask("Checking if datasource is reachable.");
198 dataSource.testConnection();
199 monitor.worked(1);
200 } catch (ClassNotFoundException e) {
201 StoreUtil.errorDialog("Could not connect to chosen datasource", this, "Reason: " + e.getMessage(), e);
202 monitor.setCanceled(true);
203 } catch (SQLException e) {
204 StoreUtil.errorDialog("Could not connect to chosen datasource", this, "Reason: " + e.getMessage(), e);
205 monitor.setCanceled(true);
206 }
207
208 }
209 }