Project

General

Profile

Download (15 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.Authentication;
25
import org.springframework.security.core.context.SecurityContext;
26
import org.springframework.security.core.context.SecurityContextHolder;
27

    
28
import eu.etaxonomy.cdm.api.application.ICdmApplicationConfiguration;
29
import eu.etaxonomy.cdm.api.conversation.ConversationHolder;
30
import eu.etaxonomy.cdm.api.service.ICommonService;
31
import eu.etaxonomy.cdm.api.service.IService;
32
import eu.etaxonomy.cdm.config.ICdmSource;
33
import eu.etaxonomy.cdm.database.DbSchemaValidation;
34
import eu.etaxonomy.cdm.ext.geo.IEditGeoService;
35
import eu.etaxonomy.cdm.model.common.CdmBase;
36
import eu.etaxonomy.cdm.model.common.Language;
37
import eu.etaxonomy.cdm.persistence.hibernate.permission.CRUD;
38
import eu.etaxonomy.cdm.persistence.hibernate.permission.ICdmPermissionEvaluator;
39
import eu.etaxonomy.cdm.persistence.hibernate.permission.Role;
40
import eu.etaxonomy.cdm.remote.CdmRemoteSourceException;
41
import eu.etaxonomy.taxeditor.datasource.CdmDataSourceRepository;
42
import eu.etaxonomy.taxeditor.io.ExportManager;
43
import eu.etaxonomy.taxeditor.io.ImportManager;
44
import eu.etaxonomy.taxeditor.model.AbstractUtility;
45
import eu.etaxonomy.taxeditor.model.MessagingUtils;
46
import eu.etaxonomy.taxeditor.preference.PreferencesUtil;
47
import eu.etaxonomy.taxeditor.store.internal.TaxeditorStorePlugin;
48
import eu.etaxonomy.taxeditor.view.datasource.CdmDataSourceViewPart;
49

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

    
64
	private static final Resource DEFAULT_APPLICATION_CONTEXT = new ClassPathResource(
65
			"/eu/etaxonomy/cdm/editorApplicationContext.xml",
66
			TaxeditorStorePlugin.class);
67
	private static final DbSchemaValidation DEFAULT_DB_SCHEMA_VALIDATION = DbSchemaValidation.VALIDATE;
68

    
69
	private static CdmStore instance;
70

    
71
	private final ICdmApplicationConfiguration applicationConfiguration;
72

    
73
	private static ContextManager contextManager = new ContextManager();
74

    
75
	private static LoginManager loginManager = new LoginManager();
76

    
77
	private static TermManager termManager = new TermManager();
78

    
79
	private static SearchManager searchManager = new SearchManager();
80

    
81
	private static EditorManager editorManager = new EditorManager();
82

    
83
	private static CdmStoreConnector job;
84

    
85
	private Language language;
86

    
87
	private ICdmSource cdmSource;
88

    
89
	private boolean isConnected;
90

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

    
103
			MessagingUtils.noDataSourceWarningDialog(instance);
104

    
105
			AbstractUtility.showView(CdmDataSourceViewPart.ID);
106
			return null;
107
		}
108
	}
109

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

    
115
		ICdmSource cdmSource;
116
		try {
117
			cdmSource = CdmDataSourceRepository.getCurrentCdmSource();
118
			connect(cdmSource);
119
		} catch (CdmRemoteSourceException e) {
120
			MessagingUtils.messageDialog("Connection to CDM Source Failed", CdmStore.class, "Could not connect to target CDM Source", e);
121
		}
122

    
123

    
124
	}
125

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

    
137
	/**
138
	 * Initialize and provide
139
	 *
140
	 * @param datasource
141
	 * @param dbSchemaValidation
142
	 * @param applicationContextBean
143
	 */
144
	private static void connect(final ICdmSource cdmSource,
145
			final DbSchemaValidation dbSchemaValidation,
146
			final Resource applicationContextBean) {
147
		MessagingUtils.info("Connecting to datasource: " + cdmSource);
148

    
149
		job = new CdmStoreConnector(Display.getDefault(), cdmSource,
150
				dbSchemaValidation, applicationContextBean);
151
		job.setUser(true);
152
		job.setPriority(Job.BUILD);
153
		job.schedule();
154

    
155
	}
156

    
157
	public static boolean isConnecting() {
158
		return job != null && job.getState() == Job.RUNNING;
159
	}
160

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

    
185
	private void close() {
186
		isConnected = false;
187
		cdmSource = null;
188
	}
189

    
190
	static void setInstance(ICdmApplicationConfiguration applicationController,
191
			ICdmSource cdmSource) {
192
		instance = new CdmStore(applicationController, cdmSource);
193
	}
194

    
195
	private CdmStore(ICdmApplicationConfiguration applicationController,
196
			ICdmSource cdmSource) {
197
		this.applicationConfiguration = applicationController;
198
		this.cdmSource = cdmSource;
199
		isConnected = true;
200
	}
201

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

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

    
232
	/*
233
	 * CONVERSATIONS
234
	 */
235

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

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

    
266
		Method[] methods = ICdmApplicationConfiguration.class.getDeclaredMethods();
267

    
268
		T service = null;
269

    
270
		for (Method method : methods) {
271
			Type type = method.getGenericReturnType();
272

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

    
287
		return service;
288
	}
289
	
290
	/**
291
	 * Generic method that will scan the getters of {@link ICdmApplicationConfiguration} for the given service
292
	 * interface. If a matching getter is found the according service implementation is returned by
293
	 * invoking the getter otherwise the method returns <code>null</code>.
294
	 *
295
	 * @param <T>
296
	 * @param serviceClass
297
	 * @return the configured implementation of <code>serviceClass</code> or <code>null</code>
298
	 */
299
	public static ICommonService getCommonService() {
300
		ICdmApplicationConfiguration configuration = getCurrentApplicationConfiguration();
301

    
302
		return configuration.getCommonService();
303

    
304
	}
305

    
306
	/**
307
	 * <p>
308
	 * getAuthenticationManager
309
	 * </p>
310
	 *
311
	 * @return a
312
	 *         {@link org.springframework.security.authentication.ProviderManager}
313
	 *         object.
314
	 */
315
	public static ProviderManager getAuthenticationManager() {
316
		return getCurrentApplicationConfiguration().getAuthenticationManager();
317
	}
318

    
319
	/**
320
	 * <p>
321
	 * getAuthenticationManager
322
	 * </p>
323
	 *
324
	 * @return a
325
	 *         {@link ICdmPermissionEvaluator} object.
326
	 */
327
	public static ICdmPermissionEvaluator getPermissionEvaluator() {
328
		return getCurrentApplicationConfiguration().getPermissionEvaluator();
329
	}
330

    
331
	/**
332
	 * <p>
333
	 * getGeoService
334
	 * </p>
335
	 *
336
	 * @return a {@link eu.etaxonomy.cdm.ext.geo.IEditGeoService} object.
337
	 */
338
	public static IEditGeoService getGeoService() {
339
		return (IEditGeoService) getCurrentApplicationConfiguration().getBean(
340
				"editGeoService");
341
	}
342

    
343
	/*
344
	 * SECURITY RELATED CONVENIENCE METHODS
345
	 */
346

    
347
	/**
348
	 * @see org.springframework.security.access.PermissionEvaluator#hasPermission(org.springframework.security.core.Authentication, java.lang.Object, java.lang.Object)
349
     *
350
	 * @param targetDomainObject
351
	 * @param permission
352
	 * @return
353
	 */
354
	public static boolean currentAuthentiationHasPermission(CdmBase targetDomainObject, EnumSet<CRUD> permission){
355
		//TODO use getCurrentApplicationConfiguration().currentAuthentiationHasPermission(CdmBase targetDomainObject, Operation permission) instead
356
		SecurityContext context = SecurityContextHolder.getContext();
357
		PermissionEvaluator pe = getPermissionEvaluator();
358
		boolean hasPermission = false;
359
		try {
360
            hasPermission = getPermissionEvaluator().hasPermission(context.getAuthentication(), targetDomainObject,
361
                    permission);
362
        } catch (org.springframework.security.access.AccessDeniedException e) {
363
            /* IGNORE */
364
        }
365
        return hasPermission;
366
	}
367

    
368
	/**
369
	 * @see org.springframework.security.access.PermissionEvaluator#hasPermission(org.springframework.security.core.Authentication, java.lang.Object, java.lang.Object)
370
     *
371
	 * @param targetDomainObject
372
	 * @param permission
373
	 * @return
374
	 */
375
	public static boolean currentAuthentiationHasPermission(Class<? extends CdmBase> targetType, EnumSet<CRUD> permission){
376
	    boolean hasPermission = false;
377
        try {
378
            hasPermission = getPermissionEvaluator().hasPermission(getCurrentAuthentiation(), null, targetType.getName(), permission);
379
        } catch (org.springframework.security.access.AccessDeniedException e) {
380
            /* IGNORE */
381
        }
382
        return hasPermission;
383
	}
384

    
385
	public static boolean currentAuthentiationHasOneOfRoles(Role ... roles){
386
	    boolean hasPermission = false;
387
        try {
388
            hasPermission =  getPermissionEvaluator().hasOneOfRoles(getCurrentAuthentiation(), roles);
389
        } catch (org.springframework.security.access.AccessDeniedException e) {
390
            /* IGNORE */
391
        }
392
        return hasPermission;
393
	}
394

    
395
	public static Authentication getCurrentAuthentiation() {
396
		SecurityContext context = SecurityContextHolder.getContext();
397
		return context.getAuthentication();
398
	}
399

    
400
	/*
401
	 * LANGUAGE
402
	 */
403

    
404
	/**
405
	 * Provides access to the global default language set in the application preferences.
406
	 *
407
	 * @return a {@link eu.etaxonomy.cdm.model.common.Language} object.
408
	 */
409
	public static Language getDefaultLanguage() {
410
		if (getDefault().getLanguage() == null) {
411
			getDefault().setLanguage(PreferencesUtil.getGlobalLanguage());
412
		}
413
		return getDefault().getLanguage();
414
	}
415

    
416
	/**
417
	 * <p>
418
	 * setDefaultLanguage
419
	 * </p>
420
	 *
421
	 * @param language
422
	 *            a {@link eu.etaxonomy.cdm.model.common.Language} object.
423
	 */
424
	public static void setDefaultLanguage(Language language) {
425
		getDefault().setLanguage(language);
426
	}
427

    
428
	/**
429
	 * @return the language
430
	 */
431
	private Language getLanguage() {
432
		return language;
433
	}
434

    
435
	/**
436
	 * @param language
437
	 *            the language to set
438
	 */
439
	private void setLanguage(Language language) {
440
		this.language = language;
441
	}
442

    
443
	/*
444
	 * LOGIN
445
	 */
446

    
447
	/**
448
	 * <p>
449
	 * Getter for the field <code>loginManager</code>.
450
	 * </p>
451
	 *
452
	 * @return a {@link eu.etaxonomy.taxeditor.store.LoginManager} object.
453
	 */
454
	public static LoginManager getLoginManager() {
455
		return loginManager;
456
	}
457

    
458
	/**
459
	 * <p>
460
	 * Getter for the field <code>contextManager</code>.
461
	 * </p>
462
	 *
463
	 * @return a {@link eu.etaxonomy.taxeditor.store.ContextManager} object.
464
	 */
465
	public static ContextManager getContextManager() {
466
		return contextManager;
467
	}
468

    
469
	public static TermManager getTermManager() {
470
		return termManager;
471
	}
472

    
473
	public static SearchManager getSearchManager() {
474
		return searchManager;
475
	}
476

    
477
	public static EditorManager getEditorManager() {
478
		return editorManager;
479
	}
480

    
481
	/*
482
	 * IMPORT/EXPORT FACTORIES
483
	 */
484

    
485
	/**
486
	 * <p>
487
	 * Getter for the field <code>importHandler</code>.
488
	 * </p>
489
	 *
490
	 * @return a {@link eu.etaxonomy.taxeditor.io.ImportManager} object.
491
	 */
492
	public static ImportManager getImportManager() {
493
		return ImportManager.NewInstance(getCurrentApplicationConfiguration());
494
	}
495

    
496
	/**
497
	 * <p>
498
	 * Getter for the field <code>exportHandler</code>.
499
	 * </p>
500
	 *
501
	 * @return a {@link eu.etaxonomy.taxeditor.io.ExportManager} object.
502
	 */
503
	public static ExportManager getExportManager() {
504
		return ExportManager.NewInstance(getCurrentApplicationConfiguration());
505
	}
506

    
507
	/**
508
	 * Whether this CdmStore is currently connected to a datasource
509
	 *
510
	 * @return a boolean.
511
	 */
512
	public static boolean isActive() {
513
		return instance != null && instance.isConnected;
514
	}
515

    
516
	public static ICdmSource getActiveCdmSource() {
517
		if (isActive()) {
518
			return instance.getCdmSource();
519
		}
520
		return null;
521
	}
522

    
523
	/**
524
	 * <p>
525
	 * getDataSource
526
	 * </p>
527
	 *
528
	 * @return a {@link eu.etaxonomy.cdm.database.ICdmDataSource} object.
529
	 * @deprecated currently retained for backward compatibility - use {@link getActiveCdmSource()} instead
530
	 */
531
//	public static ICdmDataSource getDataSource() {
532
//		if (isActive()) {
533
//			return (ICdmDataSource)instance.getCdmSource();
534
//		}
535
//		return null;
536
//	}
537

    
538
	/**
539
	 * @return
540
	 */
541
	private ICdmSource getCdmSource() {
542
		return cdmSource;
543
	}
544

    
545
}
(1-1/9)