Project

General

Profile

Download (14.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.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.IService;
31
import eu.etaxonomy.cdm.config.ICdmSource;
32
import eu.etaxonomy.cdm.database.DbSchemaValidation;
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.ICdmPermissionEvaluator;
38
import eu.etaxonomy.cdm.persistence.hibernate.permission.Role;
39
import eu.etaxonomy.cdm.remote.CdmRemoteSourceException;
40
import eu.etaxonomy.taxeditor.datasource.CdmDataSourceRepository;
41
import eu.etaxonomy.taxeditor.io.ExportManager;
42
import eu.etaxonomy.taxeditor.io.ImportManager;
43
import eu.etaxonomy.taxeditor.model.AbstractUtility;
44
import eu.etaxonomy.taxeditor.model.MessagingUtils;
45
import eu.etaxonomy.taxeditor.preference.PreferencesUtil;
46
import eu.etaxonomy.taxeditor.store.internal.TaxeditorStorePlugin;
47
import eu.etaxonomy.taxeditor.view.datasource.CdmDataSourceViewPart;
48

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

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

    
68
	private static CdmStore instance;
69

    
70
	private final ICdmApplicationConfiguration applicationConfiguration;
71

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

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

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

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

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

    
82
	private static CdmStoreConnector job;
83

    
84
	private Language language;
85

    
86
	private ICdmSource cdmSource;
87

    
88
	private boolean isConnected;
89

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

    
102
			MessagingUtils.noDataSourceWarningDialog(instance);
103

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

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

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

    
122

    
123
	}
124

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

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

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

    
154
	}
155

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

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

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

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

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

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

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

    
231
	/*
232
	 * CONVERSATIONS
233
	 */
234

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

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

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

    
267
		T service = null;
268

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

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

    
286
		return service;
287
	}
288

    
289
	/**
290
	 * <p>
291
	 * getAuthenticationManager
292
	 * </p>
293
	 *
294
	 * @return a
295
	 *         {@link org.springframework.security.authentication.ProviderManager}
296
	 *         object.
297
	 */
298
	public static ProviderManager getAuthenticationManager() {
299
		return getCurrentApplicationConfiguration().getAuthenticationManager();
300
	}
301

    
302
	/**
303
	 * <p>
304
	 * getAuthenticationManager
305
	 * </p>
306
	 *
307
	 * @return a
308
	 *         {@link ICdmPermissionEvaluator} object.
309
	 */
310
	public static ICdmPermissionEvaluator getPermissionEvaluator() {
311
		return getCurrentApplicationConfiguration().getPermissionEvaluator();
312
	}
313

    
314
	/**
315
	 * <p>
316
	 * getGeoService
317
	 * </p>
318
	 *
319
	 * @return a {@link eu.etaxonomy.cdm.ext.geo.IEditGeoService} object.
320
	 */
321
	public static IEditGeoService getGeoService() {
322
		return (IEditGeoService) getCurrentApplicationConfiguration().getBean(
323
				"editGeoService");
324
	}
325

    
326
	/*
327
	 * SECURITY RELATED CONVENIENCE METHODS
328
	 */
329

    
330
	/**
331
	 * @see org.springframework.security.access.PermissionEvaluator#hasPermission(org.springframework.security.core.Authentication, java.lang.Object, java.lang.Object)
332
     *
333
	 * @param targetDomainObject
334
	 * @param permission
335
	 * @return
336
	 */
337
	public static boolean currentAuthentiationHasPermission(CdmBase targetDomainObject, EnumSet<CRUD> permission){
338
		//TODO use getCurrentApplicationConfiguration().currentAuthentiationHasPermission(CdmBase targetDomainObject, Operation permission) instead
339
		SecurityContext context = SecurityContextHolder.getContext();
340
		PermissionEvaluator pe = getPermissionEvaluator();
341
		boolean hasPermission = false;
342
		try {
343
            hasPermission = getPermissionEvaluator().hasPermission(context.getAuthentication(), targetDomainObject,
344
                    permission);
345
        } catch (org.springframework.security.access.AccessDeniedException e) {
346
            /* IGNORE */
347
        }
348
        return hasPermission;
349
	}
350

    
351
	/**
352
	 * @see org.springframework.security.access.PermissionEvaluator#hasPermission(org.springframework.security.core.Authentication, java.lang.Object, java.lang.Object)
353
     *
354
	 * @param targetDomainObject
355
	 * @param permission
356
	 * @return
357
	 */
358
	public static boolean currentAuthentiationHasPermission(Class<? extends CdmBase> targetType, EnumSet<CRUD> permission){
359
	    boolean hasPermission = false;
360
        try {
361
            hasPermission = getPermissionEvaluator().hasPermission(getCurrentAuthentiation(), null, targetType.getName(), permission);
362
        } catch (org.springframework.security.access.AccessDeniedException e) {
363
            /* IGNORE */
364
        }
365
        return hasPermission;
366
	}
367

    
368
	public static boolean currentAuthentiationHasOneOfRoles(Role ... roles){
369
	    boolean hasPermission = false;
370
        try {
371
            hasPermission =  getPermissionEvaluator().hasOneOfRoles(getCurrentAuthentiation(), roles);
372
        } catch (org.springframework.security.access.AccessDeniedException e) {
373
            /* IGNORE */
374
        }
375
        return hasPermission;
376
	}
377

    
378
	public static Authentication getCurrentAuthentiation() {
379
		SecurityContext context = SecurityContextHolder.getContext();
380
		return context.getAuthentication();
381
	}
382

    
383
	/*
384
	 * LANGUAGE
385
	 */
386

    
387
	/**
388
	 * Provides access to the global default language set in the application preferences.
389
	 *
390
	 * @return a {@link eu.etaxonomy.cdm.model.common.Language} object.
391
	 */
392
	public static Language getDefaultLanguage() {
393
		if (getDefault().getLanguage() == null) {
394
			getDefault().setLanguage(PreferencesUtil.getGlobalLanguage());
395
		}
396
		return getDefault().getLanguage();
397
	}
398

    
399
	/**
400
	 * <p>
401
	 * setDefaultLanguage
402
	 * </p>
403
	 *
404
	 * @param language
405
	 *            a {@link eu.etaxonomy.cdm.model.common.Language} object.
406
	 */
407
	public static void setDefaultLanguage(Language language) {
408
		getDefault().setLanguage(language);
409
	}
410

    
411
	/**
412
	 * @return the language
413
	 */
414
	private Language getLanguage() {
415
		return language;
416
	}
417

    
418
	/**
419
	 * @param language
420
	 *            the language to set
421
	 */
422
	private void setLanguage(Language language) {
423
		this.language = language;
424
	}
425

    
426
	/*
427
	 * LOGIN
428
	 */
429

    
430
	/**
431
	 * <p>
432
	 * Getter for the field <code>loginManager</code>.
433
	 * </p>
434
	 *
435
	 * @return a {@link eu.etaxonomy.taxeditor.store.LoginManager} object.
436
	 */
437
	public static LoginManager getLoginManager() {
438
		return loginManager;
439
	}
440

    
441
	/**
442
	 * <p>
443
	 * Getter for the field <code>contextManager</code>.
444
	 * </p>
445
	 *
446
	 * @return a {@link eu.etaxonomy.taxeditor.store.ContextManager} object.
447
	 */
448
	public static ContextManager getContextManager() {
449
		return contextManager;
450
	}
451

    
452
	public static TermManager getTermManager() {
453
		return termManager;
454
	}
455

    
456
	public static SearchManager getSearchManager() {
457
		return searchManager;
458
	}
459

    
460
	public static EditorManager getEditorManager() {
461
		return editorManager;
462
	}
463

    
464
	/*
465
	 * IMPORT/EXPORT FACTORIES
466
	 */
467

    
468
	/**
469
	 * <p>
470
	 * Getter for the field <code>importHandler</code>.
471
	 * </p>
472
	 *
473
	 * @return a {@link eu.etaxonomy.taxeditor.io.ImportManager} object.
474
	 */
475
	public static ImportManager getImportManager() {
476
		return ImportManager.NewInstance(getCurrentApplicationConfiguration());
477
	}
478

    
479
	/**
480
	 * <p>
481
	 * Getter for the field <code>exportHandler</code>.
482
	 * </p>
483
	 *
484
	 * @return a {@link eu.etaxonomy.taxeditor.io.ExportManager} object.
485
	 */
486
	public static ExportManager getExportManager() {
487
		return ExportManager.NewInstance(getCurrentApplicationConfiguration());
488
	}
489

    
490
	/**
491
	 * Whether this CdmStore is currently connected to a datasource
492
	 *
493
	 * @return a boolean.
494
	 */
495
	public static boolean isActive() {
496
		return instance != null && instance.isConnected;
497
	}
498

    
499
	public static ICdmSource getActiveCdmSource() {
500
		if (isActive()) {
501
			return instance.getCdmSource();
502
		}
503
		return null;
504
	}
505

    
506
	/**
507
	 * <p>
508
	 * getDataSource
509
	 * </p>
510
	 *
511
	 * @return a {@link eu.etaxonomy.cdm.database.ICdmDataSource} object.
512
	 * @deprecated currently retained for backward compatibility - use {@link getActiveCdmSource()} instead
513
	 */
514
//	public static ICdmDataSource getDataSource() {
515
//		if (isActive()) {
516
//			return (ICdmDataSource)instance.getCdmSource();
517
//		}
518
//		return null;
519
//	}
520

    
521
	/**
522
	 * @return
523
	 */
524
	private ICdmSource getCdmSource() {
525
		return cdmSource;
526
	}
527

    
528
}
(1-1/9)