Project

General

Profile

Download (12.4 KB) Statistics
| Branch: | Tag: | Revision:
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
import java.util.EnumSet;
16

    
17
import org.eclipse.core.runtime.IProgressMonitor;
18
import org.eclipse.core.runtime.jobs.Job;
19
import org.eclipse.swt.widgets.Display;
20
import org.springframework.core.io.ClassPathResource;
21
import org.springframework.core.io.Resource;
22
import org.springframework.security.access.PermissionEvaluator;
23
import org.springframework.security.authentication.ProviderManager;
24
import org.springframework.security.core.context.SecurityContext;
25
import org.springframework.security.core.context.SecurityContextHolder;
26

    
27
import eu.etaxonomy.cdm.api.application.CdmApplicationController;
28
import eu.etaxonomy.cdm.api.application.ICdmApplicationConfiguration;
29
import eu.etaxonomy.cdm.api.conversation.ConversationHolder;
30
import eu.etaxonomy.cdm.api.service.IService;
31
import eu.etaxonomy.cdm.database.DbSchemaValidation;
32
import eu.etaxonomy.cdm.database.ICdmDataSource;
33
import eu.etaxonomy.cdm.ext.geo.IEditGeoService;
34
import eu.etaxonomy.cdm.model.common.CdmBase;
35
import eu.etaxonomy.cdm.model.common.Language;
36
import eu.etaxonomy.cdm.persistence.hibernate.permission.CRUD;
37
import eu.etaxonomy.cdm.persistence.hibernate.permission.Operation;
38
import eu.etaxonomy.taxeditor.datasource.CdmDataSourceRepository;
39
import eu.etaxonomy.taxeditor.io.ExportManager;
40
import eu.etaxonomy.taxeditor.io.ImportManager;
41
import eu.etaxonomy.taxeditor.preference.PreferencesUtil;
42
import eu.etaxonomy.taxeditor.store.internal.TaxeditorStorePlugin;
43
import eu.etaxonomy.taxeditor.view.datasource.CdmDataSourceViewPart;
44

    
45
/**
46
 * This implementation of ICdmDataRepository depends on hibernate sessions to
47
 * store the data correctly for the current session. No state is held in this
48
 * class.
49
 * 
50
 * Only methods that either get or manipulate data are exposed here. So this
51
 * class acts as a facade for the methods in cdmlib-service.
52
 * 
53
 * @author n.hoffmann
54
 * @created 17.03.2009
55
 * @version 1.0
56
 */
57
public class CdmStore {
58

    
59
	private static final Resource DEFAULT_APPLICATION_CONTEXT = new ClassPathResource(
60
			"/eu/etaxonomy/cdm/editorApplicationContext.xml",
61
			TaxeditorStorePlugin.class);
62
	private static final DbSchemaValidation DEFAULT_DB_SCHEMA_VALIDATION = DbSchemaValidation.VALIDATE;
63

    
64
	private static CdmStore instance;
65

    
66
	private final ICdmApplicationConfiguration applicationConfiguration;
67

    
68
	private static ContextManager contextManager = new ContextManager();
69

    
70
	private static LoginManager loginManager = new LoginManager();
71

    
72
	private static TermManager termManager = new TermManager();
73

    
74
	private static SearchManager searchManager = new SearchManager();
75

    
76
	private static EditorManager editorManager = new EditorManager();
77

    
78
	private static CdmStoreConnector job;
79

    
80
	private Language language;
81

    
82
	private ICdmDataSource cdmDatasource;
83

    
84
	private boolean isConnected;
85

    
86
	/**
87
	 * <p>
88
	 * getDefault
89
	 * </p>
90
	 * 
91
	 * @return a {@link eu.etaxonomy.taxeditor.store.CdmStore} object.
92
	 */
93
	protected static CdmStore getDefault() {
94
		if (instance != null && instance.isConnected) {
95
			return instance;
96
		} else if (instance == null || !instance.isConnected) {
97

    
98
			StoreUtil
99
					.warningDialog(
100
							"Application is not connected to a datastore",
101
							instance,
102
							"The requested operation is only available when "
103
									+ "connected to a datasource. You may choose a datasource to connect to or create a new one in the datasource view.");
104

    
105
			StoreUtil.showView(CdmDataSourceViewPart.ID);
106

    
107
		}
108

    
109
		throw new RuntimeException();
110
	}
111

    
112
	/**
113
	 * Initialize the with the last edited datasource
114
	 */
115
	public static void connect() {
116

    
117
		ICdmDataSource datasource = CdmDataSourceRepository
118
				.getCurrentDataSource();
119

    
120
		connect(datasource);
121
	}
122

    
123
	/**
124
	 * Initialize with a specific datasource
125
	 * 
126
	 * @param datasource
127
	 *            a {@link eu.etaxonomy.cdm.database.ICdmDataSource} object.
128
	 */
129
	public static void connect(ICdmDataSource datasource) {
130
		connect(datasource, DEFAULT_DB_SCHEMA_VALIDATION,
131
				DEFAULT_APPLICATION_CONTEXT);
132
	}
133

    
134
	/**
135
	 * Initialize and provide
136
	 * 
137
	 * @param datasource
138
	 * @param dbSchemaValidation
139
	 * @param applicationContextBean
140
	 */
141
	private static void connect(final ICdmDataSource datasource,
142
			final DbSchemaValidation dbSchemaValidation,
143
			final Resource applicationContextBean) {
144
		StoreUtil.info("Connecting to datasource: " + datasource);
145

    
146
		job = new CdmStoreConnector(Display.getDefault(), datasource,
147
				dbSchemaValidation, applicationContextBean);
148
		job.setUser(true);
149
		job.setPriority(Job.BUILD);
150
		job.schedule();
151

    
152
	}
153

    
154
	public static boolean isConnecting() {
155
		return job != null && job.getState() == Job.RUNNING;
156
	}
157

    
158
	/**
159
	 * Closes the current application context
160
	 * 
161
	 * @param monitor
162
	 *            a {@link org.eclipse.core.runtime.IProgressMonitor} object.
163
	 */
164
	public static void close(final IProgressMonitor monitor) {
165
		Display.getDefault().asyncExec(new Runnable() {
166
			/*
167
			 * (non-Javadoc)
168
			 * 
169
			 * @see java.lang.Runnable#run()
170
			 */
171
			@Override
172
			public void run() {
173
				getContextManager().notifyContextAboutToStop(monitor);
174
				if ((monitor == null || (!monitor.isCanceled()) && isActive())) {
175
					getContextManager().notifyContextStop(monitor);
176
					instance.close();
177
				}
178
			}
179
		});
180
	}
181

    
182
	private void close() {
183
		isConnected = false;
184
		cdmDatasource = null;
185
	}
186

    
187
	static void setInstance(CdmApplicationController applicationController,
188
			ICdmDataSource dataSource) {
189
		instance = new CdmStore(applicationController, dataSource);
190
	}
191

    
192
	private CdmStore(CdmApplicationController applicationController,
193
			ICdmDataSource dataSource) {
194
		this.applicationConfiguration = applicationController;
195
		this.cdmDatasource = dataSource;
196
		isConnected = true;
197
	}
198

    
199
	/**
200
	 * All calls to the datastore require
201
	 * 
202
	 * @return
203
	 */
204
	private ICdmApplicationConfiguration getApplicationConfiguration() {
205
		try {
206
			return applicationConfiguration;
207
		} catch (Exception e) {
208
			StoreUtil.error(CdmStore.class, e);
209
		}
210
		return null;
211
	}
212

    
213
	/**
214
	 * <p>
215
	 * getCurrentApplicationController
216
	 * </p>
217
	 * 
218
	 * @return a
219
	 *         {@link eu.etaxonomy.cdm.api.application.CdmApplicationController}
220
	 *         object.
221
	 */
222
	public static ICdmApplicationConfiguration getCurrentApplicationConfiguration() {
223
		if (getDefault() != null) {
224
			return getDefault().getApplicationConfiguration();
225
		}
226
		return null;
227
	}
228

    
229
	/*
230
	 * CONVERSATIONS
231
	 */
232

    
233
	/**
234
	 * Creates a new conversation, binds resources to the conversation and start
235
	 * a transaction for this conversation.
236
	 * 
237
	 * @return a {@link eu.etaxonomy.cdm.api.conversation.ConversationHolder}
238
	 *         object.
239
	 */
240
	public static ConversationHolder createConversation() {
241
		ConversationHolder conversation = getCurrentApplicationConfiguration()
242
				.NewConversation();
243
		try{
244
			conversation.startTransaction();
245
		}catch(Exception e){
246
			StoreUtil.errorDialog("No database connection", CdmStore.class, "No database connection available", e);
247
		}
248
		return conversation;
249
	}
250

    
251
	/**
252
	 * Generic method that will scan the getters of {@link ICdmApplicationConfiguration} for the given service
253
	 * interface. If a matching getter is found the according service implementation is returned by 
254
	 * invoking the getter otherwise the method returns <code>null</code>. 
255
	 * 
256
	 * @param <T>
257
	 * @param serviceClass
258
	 * @return the configured implementation of <code>serviceClass</code> or <code>null</code>
259
	 */
260
	public static <T extends IService> T getService(Class<T> serviceClass) {
261
		ICdmApplicationConfiguration configuration = getCurrentApplicationConfiguration();
262

    
263
		Method[] methods = ICdmApplicationConfiguration.class.getDeclaredMethods();
264

    
265
		T service = null;
266

    
267
		for (Method method : methods) {
268
			Type type = method.getGenericReturnType();
269

    
270
			if (type.equals(serviceClass)) {
271
				try {
272
					service = (T) method.invoke(configuration, null);
273
					break;
274
				} catch (IllegalArgumentException e) {
275
					StoreUtil.error(CdmStore.class, e);
276
				} catch (IllegalAccessException e) {
277
					StoreUtil.error(CdmStore.class, e);
278
				} catch (InvocationTargetException e) {
279
					StoreUtil.error(CdmStore.class, e);
280
				}
281
			}
282
		}
283

    
284
		return service;
285
	}
286

    
287
	/**
288
	 * <p>
289
	 * getAuthenticationManager
290
	 * </p>
291
	 * 
292
	 * @return a
293
	 *         {@link org.springframework.security.authentication.ProviderManager}
294
	 *         object.
295
	 */
296
	public static ProviderManager getAuthenticationManager() {
297
		return getCurrentApplicationConfiguration().getAuthenticationManager();
298
	}
299
	
300
	/**
301
	 * <p>
302
	 * getAuthenticationManager
303
	 * </p>
304
	 * 
305
	 * @return a
306
	 *         {@link PermissionEvaluator} object.
307
	 */
308
	public static PermissionEvaluator getPermissionEvaluator() {
309
		return getCurrentApplicationConfiguration().getPermissionEvaluator();
310
	}
311

    
312
	/**
313
	 * <p>
314
	 * getGeoService
315
	 * </p>
316
	 * 
317
	 * @return a {@link eu.etaxonomy.cdm.ext.geo.IEditGeoService} object.
318
	 */
319
	public static IEditGeoService getGeoService() {
320
		return (IEditGeoService) getCurrentApplicationConfiguration().getBean(
321
				"editGeoService");
322
	}
323
	
324
	/*
325
	 * SECURITY RELATED CONVENIENCE METHODS
326
	 */
327
	
328
	/**
329
	 * @see org.springframework.security.access.PermissionEvaluator#hasPermission(org.springframework.security.core.Authentication, java.lang.Object, java.lang.Object)
330
     *
331
	 * @param targetDomainObject
332
	 * @param permission 
333
	 * @return
334
	 */
335
	public static boolean currentAuthentiationHasPermission(CdmBase targetDomainObject, EnumSet<CRUD> permission){
336
		//TODO use getCurrentApplicationConfiguration().currentAuthentiationHasPermission(CdmBase targetDomainObject, Operation permission) instead
337
		SecurityContext context = SecurityContextHolder.getContext();
338
		return getPermissionEvaluator().hasPermission(context.getAuthentication(), targetDomainObject, permission);
339
	}
340

    
341
	/*
342
	 * LANGUAGE
343
	 */
344

    
345
	/**
346
	 * <p>
347
	 * getDefaultLanguage
348
	 * </p>
349
	 * 
350
	 * @return a {@link eu.etaxonomy.cdm.model.common.Language} object.
351
	 */
352
	public static Language getDefaultLanguage() {
353
		if (getDefault().getLanguage() == null) {
354
			getDefault().setLanguage(PreferencesUtil.getGlobalLanguage());
355
		}
356
		return getDefault().getLanguage();
357
	}
358

    
359
	/**
360
	 * <p>
361
	 * setDefaultLanguage
362
	 * </p>
363
	 * 
364
	 * @param language
365
	 *            a {@link eu.etaxonomy.cdm.model.common.Language} object.
366
	 */
367
	public static void setDefaultLanguage(Language language) {
368
		getDefault().setLanguage(language);
369
	}
370

    
371
	/**
372
	 * @return the language
373
	 */
374
	private Language getLanguage() {
375
		return language;
376
	}
377

    
378
	/**
379
	 * @param language
380
	 *            the language to set
381
	 */
382
	private void setLanguage(Language language) {
383
		this.language = language;
384
	}
385

    
386
	/*
387
	 * LOGIN
388
	 */
389

    
390
	/**
391
	 * <p>
392
	 * Getter for the field <code>loginManager</code>.
393
	 * </p>
394
	 * 
395
	 * @return a {@link eu.etaxonomy.taxeditor.store.LoginManager} object.
396
	 */
397
	public static LoginManager getLoginManager() {
398
		return loginManager;
399
	}
400

    
401
	/**
402
	 * <p>
403
	 * Getter for the field <code>contextManager</code>.
404
	 * </p>
405
	 * 
406
	 * @return a {@link eu.etaxonomy.taxeditor.store.ContextManager} object.
407
	 */
408
	public static ContextManager getContextManager() {
409
		return contextManager;
410
	}
411

    
412
	public static TermManager getTermManager() {
413
		return termManager;
414
	}
415

    
416
	public static SearchManager getSearchManager() {
417
		return searchManager;
418
	}
419

    
420
	public static EditorManager getEditorManager() {
421
		return editorManager;
422
	}
423

    
424
	/*
425
	 * IMPORT/EXPORT FACTORIES
426
	 */
427

    
428
	/**
429
	 * <p>
430
	 * Getter for the field <code>importHandler</code>.
431
	 * </p>
432
	 * 
433
	 * @return a {@link eu.etaxonomy.taxeditor.io.ImportManager} object.
434
	 */
435
	public static ImportManager getImportManager() {
436
		return ImportManager.NewInstance(getCurrentApplicationConfiguration());
437
	}
438

    
439
	/**
440
	 * <p>
441
	 * Getter for the field <code>exportHandler</code>.
442
	 * </p>
443
	 * 
444
	 * @return a {@link eu.etaxonomy.taxeditor.io.ExportManager} object.
445
	 */
446
	public static ExportManager getExportManager() {
447
		return ExportManager.NewInstance(getCurrentApplicationConfiguration());
448
	}
449

    
450
	/**
451
	 * Whether this CdmStore is currently connected to a datasource
452
	 * 
453
	 * @return a boolean.
454
	 */
455
	public static boolean isActive() {
456
		return instance != null && instance.isConnected;
457
	}
458

    
459
	/**
460
	 * <p>
461
	 * getDataSource
462
	 * </p>
463
	 * 
464
	 * @return a {@link eu.etaxonomy.cdm.database.ICdmDataSource} object.
465
	 */
466
	public static ICdmDataSource getDataSource() {
467
		if (isActive()) {
468
			return instance.getDatasource();
469
		}
470
		return null;
471
	}
472

    
473
	/**
474
	 * @return
475
	 */
476
	private ICdmDataSource getDatasource() {
477
		return cdmDatasource;
478
	}
479

    
480
}
(1-1/9)