merging in latest changes from trunk
[taxeditor.git] / eu.etaxonomy.taxeditor.store / src / main / java / eu / etaxonomy / taxeditor / store / CdmStore.java
1 /**
2 * Copyright (C) 2007 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
5 *
6 * The contents of this file are subject to the Mozilla Public License Version 1.1
7 * See LICENSE.TXT at the top of this package for the full license terms.
8 */
9
10 package eu.etaxonomy.taxeditor.store;
11
12 import java.lang.reflect.InvocationTargetException;
13 import java.lang.reflect.Method;
14 import java.lang.reflect.Type;
15
16 import org.eclipse.core.runtime.IProgressMonitor;
17 import org.eclipse.core.runtime.jobs.Job;
18 import org.eclipse.swt.widgets.Display;
19 import org.springframework.core.io.ClassPathResource;
20 import org.springframework.core.io.Resource;
21 import org.springframework.security.authentication.ProviderManager;
22
23 import eu.etaxonomy.cdm.api.application.CdmApplicationController;
24 import eu.etaxonomy.cdm.api.application.ICdmApplicationConfiguration;
25 import eu.etaxonomy.cdm.api.conversation.ConversationHolder;
26 import eu.etaxonomy.cdm.api.service.IService;
27 import eu.etaxonomy.cdm.database.DbSchemaValidation;
28 import eu.etaxonomy.cdm.database.ICdmDataSource;
29 import eu.etaxonomy.cdm.ext.geo.IEditGeoService;
30 import eu.etaxonomy.cdm.model.common.Language;
31 import eu.etaxonomy.taxeditor.datasource.CdmDataSourceRepository;
32 import eu.etaxonomy.taxeditor.io.ExportManager;
33 import eu.etaxonomy.taxeditor.io.ImportManager;
34 import eu.etaxonomy.taxeditor.preference.PreferencesUtil;
35 import eu.etaxonomy.taxeditor.store.internal.TaxeditorStorePlugin;
36 import eu.etaxonomy.taxeditor.view.datasource.CdmDataSourceViewPart;
37
38 /**
39 * This implementation of ICdmDataRepository depends on hibernate sessions to
40 * store the data correctly for the current session. No state is held in this
41 * class.
42 *
43 * Only methods that either get or manipulate data are exposed here. So this
44 * class acts as a facade for the methods in cdmlib-service.
45 *
46 * @author n.hoffmann
47 * @created 17.03.2009
48 * @version 1.0
49 */
50 public class CdmStore {
51
52 private static final Resource DEFAULT_APPLICATION_CONTEXT = new ClassPathResource(
53 "/eu/etaxonomy/cdm/editorApplicationContext.xml",
54 TaxeditorStorePlugin.class);
55 private static final DbSchemaValidation DEFAULT_DB_SCHEMA_VALIDATION = DbSchemaValidation.VALIDATE;
56
57 private static CdmStore instance;
58
59 private final ICdmApplicationConfiguration applicationConfiguration;
60
61 private static ContextManager contextManager = new ContextManager();
62
63 private static LoginManager loginManager = new LoginManager();
64
65 private static TermManager termManager = new TermManager();
66
67 private static SearchManager searchManager = new SearchManager();
68
69 private static EditorManager editorManager = new EditorManager();
70
71 private static CdmStoreConnector job;
72
73 private Language language;
74
75 private ICdmDataSource cdmDatasource;
76
77 private boolean isConnected;
78
79 /**
80 * <p>
81 * getDefault
82 * </p>
83 *
84 * @return a {@link eu.etaxonomy.taxeditor.store.CdmStore} object.
85 */
86 protected static CdmStore getDefault() {
87 if (instance != null && instance.isConnected) {
88 return instance;
89 } else if (instance == null || !instance.isConnected) {
90
91 StoreUtil
92 .warningDialog(
93 "Application is not connected to a datastore",
94 instance,
95 "The requested operation is only available when "
96 + "connected to a datasource. You may choose a datasource to connect to or create a new one in the datasource view.");
97
98 StoreUtil.showView(CdmDataSourceViewPart.ID);
99
100 }
101
102 throw new RuntimeException();
103 }
104
105 /**
106 * Initialize the with the last edited datasource
107 */
108 public static void connect() {
109
110 ICdmDataSource datasource = CdmDataSourceRepository
111 .getCurrentDataSource();
112
113 connect(datasource);
114 }
115
116 /**
117 * Initialize with a specific datasource
118 *
119 * @param datasource
120 * a {@link eu.etaxonomy.cdm.database.ICdmDataSource} object.
121 */
122 public static void connect(ICdmDataSource datasource) {
123 connect(datasource, DEFAULT_DB_SCHEMA_VALIDATION,
124 DEFAULT_APPLICATION_CONTEXT);
125 }
126
127 /**
128 * Initialize and provide
129 *
130 * @param datasource
131 * @param dbSchemaValidation
132 * @param applicationContextBean
133 */
134 private static void connect(final ICdmDataSource datasource,
135 final DbSchemaValidation dbSchemaValidation,
136 final Resource applicationContextBean) {
137 StoreUtil.info("Connecting to datasource: " + datasource);
138
139 job = new CdmStoreConnector(Display.getDefault(), datasource,
140 dbSchemaValidation, applicationContextBean);
141 job.setUser(true);
142 job.setPriority(Job.BUILD);
143 job.schedule();
144
145 }
146
147 public static boolean isConnecting() {
148 return job != null && job.getState() == Job.RUNNING;
149 }
150
151 /**
152 * Closes the current application context
153 *
154 * @param monitor
155 * a {@link org.eclipse.core.runtime.IProgressMonitor} object.
156 */
157 public static void close(final IProgressMonitor monitor) {
158 Display.getDefault().asyncExec(new Runnable() {
159 /*
160 * (non-Javadoc)
161 *
162 * @see java.lang.Runnable#run()
163 */
164 @Override
165 public void run() {
166 getContextManager().notifyContextAboutToStop(monitor);
167 if ((monitor == null || (!monitor.isCanceled()) && isActive())) {
168 getContextManager().notifyContextStop(monitor);
169 instance.close();
170 }
171 }
172 });
173 }
174
175 private void close() {
176 isConnected = false;
177 cdmDatasource = null;
178 }
179
180 static void setInstance(CdmApplicationController applicationController,
181 ICdmDataSource dataSource) {
182 instance = new CdmStore(applicationController, dataSource);
183 }
184
185 private CdmStore(CdmApplicationController applicationController,
186 ICdmDataSource dataSource) {
187 this.applicationConfiguration = applicationController;
188 this.cdmDatasource = dataSource;
189 isConnected = true;
190 }
191
192 /**
193 * All calls to the datastore require
194 *
195 * @return
196 */
197 private ICdmApplicationConfiguration getApplicationConfiguration() {
198 try {
199 return applicationConfiguration;
200 } catch (Exception e) {
201 StoreUtil.error(CdmStore.class, e);
202 }
203 return null;
204 }
205
206 /**
207 * <p>
208 * getCurrentApplicationController
209 * </p>
210 *
211 * @return a
212 * {@link eu.etaxonomy.cdm.api.application.CdmApplicationController}
213 * object.
214 */
215 public static ICdmApplicationConfiguration getCurrentApplicationConfiguration() {
216 if (getDefault() != null) {
217 return getDefault().getApplicationConfiguration();
218 }
219 return null;
220 }
221
222 /*
223 * CONVERSATIONS
224 */
225
226 /**
227 * Creates a new conversation, binds resources to the conversation and start
228 * a transaction for this conversation.
229 *
230 * @return a {@link eu.etaxonomy.cdm.api.conversation.ConversationHolder}
231 * object.
232 */
233 public static ConversationHolder createConversation() {
234 ConversationHolder conversation = getCurrentApplicationConfiguration()
235 .NewConversation();
236 try{
237 conversation.startTransaction();
238 }catch(Exception e){
239 StoreUtil.errorDialog("No database connection", CdmStore.class, "No database connection available", e);
240 }
241 return conversation;
242 }
243
244 /**
245 * Generic method that will return an implementation of the given service
246 * interface or <code>null</code> if the
247 *
248 * @param <T>
249 * @param serviceClass
250 * @return
251 */
252 public static <T extends IService> T getService(Class<T> serviceClass) {
253 ICdmApplicationConfiguration configuration = getCurrentApplicationConfiguration();
254
255 Method[] methods = ICdmApplicationConfiguration.class
256 .getDeclaredMethods();
257
258 T service = null;
259
260 for (Method method : methods) {
261 Type type = method.getGenericReturnType();
262
263 if (type.equals(serviceClass)) {
264 try {
265 service = (T) method.invoke(configuration, null);
266 break;
267 } catch (IllegalArgumentException e) {
268 StoreUtil.error(CdmStore.class, e);
269 } catch (IllegalAccessException e) {
270 StoreUtil.error(CdmStore.class, e);
271 } catch (InvocationTargetException e) {
272 StoreUtil.error(CdmStore.class, e);
273 }
274 }
275 }
276
277 return service;
278 }
279
280 /**
281 * <p>
282 * getAuthenticationManager
283 * </p>
284 *
285 * @return a
286 * {@link org.springframework.security.authentication.ProviderManager}
287 * object.
288 */
289 public static ProviderManager getAuthenticationManager() {
290 return getCurrentApplicationConfiguration().getAuthenticationManager();
291 }
292
293 /**
294 * <p>
295 * getGeoService
296 * </p>
297 *
298 * @return a {@link eu.etaxonomy.cdm.ext.geo.IEditGeoService} object.
299 */
300 public static IEditGeoService getGeoService() {
301 return (IEditGeoService) getCurrentApplicationConfiguration().getBean(
302 "editGeoService");
303 }
304
305 /*
306 * LANGUAGE
307 */
308
309 /**
310 * <p>
311 * getDefaultLanguage
312 * </p>
313 *
314 * @return a {@link eu.etaxonomy.cdm.model.common.Language} object.
315 */
316 public static Language getDefaultLanguage() {
317 if (getDefault().getLanguage() == null) {
318 getDefault().setLanguage(PreferencesUtil.getGlobalLanguage());
319 }
320 return getDefault().getLanguage();
321 }
322
323 /**
324 * <p>
325 * setDefaultLanguage
326 * </p>
327 *
328 * @param language
329 * a {@link eu.etaxonomy.cdm.model.common.Language} object.
330 */
331 public static void setDefaultLanguage(Language language) {
332 getDefault().setLanguage(language);
333 }
334
335 /**
336 * @return the language
337 */
338 private Language getLanguage() {
339 return language;
340 }
341
342 /**
343 * @param language
344 * the language to set
345 */
346 private void setLanguage(Language language) {
347 this.language = language;
348 }
349
350 /*
351 * LOGIN
352 */
353
354 /**
355 * <p>
356 * Getter for the field <code>loginManager</code>.
357 * </p>
358 *
359 * @return a {@link eu.etaxonomy.taxeditor.store.LoginManager} object.
360 */
361 public static LoginManager getLoginManager() {
362 return loginManager;
363 }
364
365 /**
366 * <p>
367 * Getter for the field <code>contextManager</code>.
368 * </p>
369 *
370 * @return a {@link eu.etaxonomy.taxeditor.store.ContextManager} object.
371 */
372 public static ContextManager getContextManager() {
373 return contextManager;
374 }
375
376 public static TermManager getTermManager() {
377 return termManager;
378 }
379
380 public static SearchManager getSearchManager() {
381 return searchManager;
382 }
383
384 public static EditorManager getEditorManager() {
385 return editorManager;
386 }
387
388 /*
389 * IMPORT/EXPORT FACTORIES
390 */
391
392 /**
393 * <p>
394 * Getter for the field <code>importHandler</code>.
395 * </p>
396 *
397 * @return a {@link eu.etaxonomy.taxeditor.io.ImportManager} object.
398 */
399 public static ImportManager getImportManager() {
400 return ImportManager.NewInstance(getCurrentApplicationConfiguration());
401 }
402
403 /**
404 * <p>
405 * Getter for the field <code>exportHandler</code>.
406 * </p>
407 *
408 * @return a {@link eu.etaxonomy.taxeditor.io.ExportManager} object.
409 */
410 public static ExportManager getExportManager() {
411 return ExportManager.NewInstance(getCurrentApplicationConfiguration());
412 }
413
414 /**
415 * Whether this CdmStore is currently connected to a datasource
416 *
417 * @return a boolean.
418 */
419 public static boolean isActive() {
420 return instance != null && instance.isConnected;
421 }
422
423 /**
424 * <p>
425 * getDataSource
426 * </p>
427 *
428 * @return a {@link eu.etaxonomy.cdm.database.ICdmDataSource} object.
429 */
430 public static ICdmDataSource getDataSource() {
431 if (isActive()) {
432 return instance.getDatasource();
433 }
434 return null;
435 }
436
437 /**
438 * @return
439 */
440 private ICdmDataSource getDatasource() {
441 return cdmDatasource;
442 }
443
444 }