b0492bf8453503fb106d28521f83a29f4fe8e181
[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 CdmApplicationController applicationController;
60
61 private static LoginManager loginManager = new LoginManager();
62
63 private static ContextManager contextManager = new ContextManager();;
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 if (instance.getApplicationController() != null) {
170 instance.getApplicationController().close();
171 }
172 instance.close();
173 }
174 }
175 });
176 }
177
178 private void close() {
179 isConnected = false;
180 cdmDatasource = null;
181 }
182
183 static void setInstance(CdmApplicationController applicationController,
184 ICdmDataSource dataSource) {
185 instance = new CdmStore(applicationController, dataSource);
186 }
187
188 private CdmStore(CdmApplicationController applicationController,
189 ICdmDataSource dataSource) {
190 this.applicationController = applicationController;
191 this.cdmDatasource = dataSource;
192 isConnected = true;
193 }
194
195 /**
196 * All calls to the datastore require
197 *
198 * @return
199 */
200 private CdmApplicationController getApplicationController() {
201 try {
202 return applicationController;
203 } catch (Exception e) {
204 StoreUtil.error(CdmStore.class, e);
205 }
206 return null;
207 }
208
209 /**
210 * <p>
211 * getCurrentApplicationController
212 * </p>
213 *
214 * @return a
215 * {@link eu.etaxonomy.cdm.api.application.CdmApplicationController}
216 * object.
217 */
218 public static CdmApplicationController getCurrentApplicationController() {
219 if (getDefault() != null) {
220 return getDefault().getApplicationController();
221 }
222 return null;
223 }
224
225 /*
226 * CONVERSATIONS
227 */
228
229 /**
230 * Creates a new conversation, binds resources to the conversation and start
231 * a transaction for this conversation.
232 *
233 * @return a {@link eu.etaxonomy.cdm.api.conversation.ConversationHolder}
234 * object.
235 */
236 public static ConversationHolder createConversation() {
237 ConversationHolder conversation = getCurrentApplicationController()
238 .NewConversation();
239
240 conversation.startTransaction();
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 = getCurrentApplicationController();
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 getCurrentApplicationController().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) getCurrentApplicationController().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(getCurrentApplicationController());
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(getCurrentApplicationController());
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 }