adapting to new use new ICdmPermissionEvaluator
[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 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.CdmPermissionEvaluator;
38 import eu.etaxonomy.cdm.persistence.hibernate.permission.ICdmPermissionEvaluator;
39 import eu.etaxonomy.cdm.persistence.hibernate.permission.Role;
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.preference.PreferencesUtil;
44 import eu.etaxonomy.taxeditor.store.internal.TaxeditorStorePlugin;
45 import eu.etaxonomy.taxeditor.view.datasource.CdmDataSourceViewPart;
46
47 /**
48 * This implementation of ICdmDataRepository depends on hibernate sessions to
49 * store the data correctly for the current session. No state is held in this
50 * class.
51 *
52 * Only methods that either get or manipulate data are exposed here. So this
53 * class acts as a facade for the methods in cdmlib-service.
54 *
55 * @author n.hoffmann
56 * @created 17.03.2009
57 * @version 1.0
58 */
59 public class CdmStore {
60
61 private static final Resource DEFAULT_APPLICATION_CONTEXT = new ClassPathResource(
62 "/eu/etaxonomy/cdm/editorApplicationContext.xml",
63 TaxeditorStorePlugin.class);
64 private static final DbSchemaValidation DEFAULT_DB_SCHEMA_VALIDATION = DbSchemaValidation.VALIDATE;
65
66 private static CdmStore instance;
67
68 private final ICdmApplicationConfiguration applicationConfiguration;
69
70 private static ContextManager contextManager = new ContextManager();
71
72 private static LoginManager loginManager = new LoginManager();
73
74 private static TermManager termManager = new TermManager();
75
76 private static SearchManager searchManager = new SearchManager();
77
78 private static EditorManager editorManager = new EditorManager();
79
80 private static CdmStoreConnector job;
81
82 private Language language;
83
84 private ICdmDataSource cdmDatasource;
85
86 private boolean isConnected;
87
88 /**
89 * <p>
90 * getDefault
91 * </p>
92 *
93 * @return a {@link eu.etaxonomy.taxeditor.store.CdmStore} object.
94 */
95 protected static CdmStore getDefault() {
96 if (instance != null && instance.isConnected) {
97 return instance;
98 } else if (instance == null || !instance.isConnected) {
99
100 StoreUtil
101 .warningDialog(
102 "Application is not connected to a datastore",
103 instance,
104 "The requested operation is only available when "
105 + "connected to a datasource. You may choose a datasource to connect to or create a new one in the datasource view.");
106
107 StoreUtil.showView(CdmDataSourceViewPart.ID);
108
109 }
110
111 throw new RuntimeException();
112 }
113
114 /**
115 * Initialize the with the last edited datasource
116 */
117 public static void connect() {
118
119 ICdmDataSource datasource = CdmDataSourceRepository
120 .getCurrentDataSource();
121
122 connect(datasource);
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(ICdmDataSource datasource) {
132 connect(datasource, 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 ICdmDataSource datasource,
144 final DbSchemaValidation dbSchemaValidation,
145 final Resource applicationContextBean) {
146 StoreUtil.info("Connecting to datasource: " + datasource);
147
148 job = new CdmStoreConnector(Display.getDefault(), datasource,
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 cdmDatasource = null;
187 }
188
189 static void setInstance(CdmApplicationController applicationController,
190 ICdmDataSource dataSource) {
191 instance = new CdmStore(applicationController, dataSource);
192 }
193
194 private CdmStore(CdmApplicationController applicationController,
195 ICdmDataSource dataSource) {
196 this.applicationConfiguration = applicationController;
197 this.cdmDatasource = dataSource;
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 StoreUtil.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.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 StoreUtil.errorDialog("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 StoreUtil.error(CdmStore.class, e);
278 } catch (IllegalAccessException e) {
279 StoreUtil.error(CdmStore.class, e);
280 } catch (InvocationTargetException e) {
281 StoreUtil.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 return getPermissionEvaluator().hasPermission(context.getAuthentication(), targetDomainObject, permission);
341 }
342
343 /**
344 * @see org.springframework.security.access.PermissionEvaluator#hasPermission(org.springframework.security.core.Authentication, java.lang.Object, java.lang.Object)
345 *
346 * @param targetDomainObject
347 * @param permission
348 * @return
349 */
350 public static boolean currentAuthentiationHasPermission(Class<? extends CdmBase> targetType, EnumSet<CRUD> permission){
351 SecurityContext context = SecurityContextHolder.getContext();
352 return getPermissionEvaluator().hasPermission(context.getAuthentication(), null, targetType.getName(), permission);
353 }
354
355
356
357 /*
358 * LANGUAGE
359 */
360
361 /**
362 * <p>
363 * getDefaultLanguage
364 * </p>
365 *
366 * @return a {@link eu.etaxonomy.cdm.model.common.Language} object.
367 */
368 public static Language getDefaultLanguage() {
369 if (getDefault().getLanguage() == null) {
370 getDefault().setLanguage(PreferencesUtil.getGlobalLanguage());
371 }
372 return getDefault().getLanguage();
373 }
374
375 /**
376 * <p>
377 * setDefaultLanguage
378 * </p>
379 *
380 * @param language
381 * a {@link eu.etaxonomy.cdm.model.common.Language} object.
382 */
383 public static void setDefaultLanguage(Language language) {
384 getDefault().setLanguage(language);
385 }
386
387 /**
388 * @return the language
389 */
390 private Language getLanguage() {
391 return language;
392 }
393
394 /**
395 * @param language
396 * the language to set
397 */
398 private void setLanguage(Language language) {
399 this.language = language;
400 }
401
402 /*
403 * LOGIN
404 */
405
406 /**
407 * <p>
408 * Getter for the field <code>loginManager</code>.
409 * </p>
410 *
411 * @return a {@link eu.etaxonomy.taxeditor.store.LoginManager} object.
412 */
413 public static LoginManager getLoginManager() {
414 return loginManager;
415 }
416
417 /**
418 * <p>
419 * Getter for the field <code>contextManager</code>.
420 * </p>
421 *
422 * @return a {@link eu.etaxonomy.taxeditor.store.ContextManager} object.
423 */
424 public static ContextManager getContextManager() {
425 return contextManager;
426 }
427
428 public static TermManager getTermManager() {
429 return termManager;
430 }
431
432 public static SearchManager getSearchManager() {
433 return searchManager;
434 }
435
436 public static EditorManager getEditorManager() {
437 return editorManager;
438 }
439
440 /*
441 * IMPORT/EXPORT FACTORIES
442 */
443
444 /**
445 * <p>
446 * Getter for the field <code>importHandler</code>.
447 * </p>
448 *
449 * @return a {@link eu.etaxonomy.taxeditor.io.ImportManager} object.
450 */
451 public static ImportManager getImportManager() {
452 return ImportManager.NewInstance(getCurrentApplicationConfiguration());
453 }
454
455 /**
456 * <p>
457 * Getter for the field <code>exportHandler</code>.
458 * </p>
459 *
460 * @return a {@link eu.etaxonomy.taxeditor.io.ExportManager} object.
461 */
462 public static ExportManager getExportManager() {
463 return ExportManager.NewInstance(getCurrentApplicationConfiguration());
464 }
465
466 /**
467 * Whether this CdmStore is currently connected to a datasource
468 *
469 * @return a boolean.
470 */
471 public static boolean isActive() {
472 return instance != null && instance.isConnected;
473 }
474
475 /**
476 * <p>
477 * getDataSource
478 * </p>
479 *
480 * @return a {@link eu.etaxonomy.cdm.database.ICdmDataSource} object.
481 */
482 public static ICdmDataSource getDataSource() {
483 if (isActive()) {
484 return instance.getDatasource();
485 }
486 return null;
487 }
488
489 /**
490 * @return
491 */
492 private ICdmDataSource getDatasource() {
493 return cdmDatasource;
494 }
495
496 }