Project

General

Profile

Download (18.7 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.util.EnumSet;
13

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

    
25
import eu.etaxonomy.cdm.api.application.CdmApplicationException;
26
import eu.etaxonomy.cdm.api.application.CdmApplicationRemoteController;
27
import eu.etaxonomy.cdm.api.application.CdmApplicationState;
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.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.remoting.cache.CdmRemoteCacheManager;
47
import eu.etaxonomy.taxeditor.session.ICdmEntitySessionManager;
48
import eu.etaxonomy.taxeditor.session.mock.MockCdmEntitySessionManager;
49
import eu.etaxonomy.taxeditor.store.internal.TaxeditorStorePlugin;
50
import eu.etaxonomy.taxeditor.ui.dialog.RemotingLoginDialog;
51
import eu.etaxonomy.taxeditor.view.datasource.CdmDataSourceViewPart;
52

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

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

    
72
    private static CdmStore instance;
73

    
74
    //private final ICdmApplicationConfiguration applicationConfiguration;
75

    
76
    private static ContextManager contextManager = new ContextManager();
77

    
78
    private static LoginManager loginManager = new LoginManager();
79

    
80
    private static TermManager termManager = new TermManager();
81

    
82
    private static SearchManager searchManager = new SearchManager();
83

    
84
    private static EditorManager editorManager = new EditorManager();
85

    
86
    private static UseObjectStore useObjectInitializer = new UseObjectStore();
87

    
88
    private static CdmStoreConnector job;
89

    
90
    private Language language;
91

    
92
    private ICdmSource cdmSource;
93

    
94
    private boolean isConnected;
95

    
96

    
97

    
98
    /**
99
     * <p>
100
     * getDefault
101
     * </p>
102
     *
103
     * @return a {@link eu.etaxonomy.taxeditor.store.CdmStore} object.
104
     */
105
    protected static CdmStore getDefault() {
106
        if (instance != null && instance.isConnected) {
107
            return instance;
108
        } else{// if (instance == null || !instance.isConnected) {
109

    
110
            MessagingUtils.noDataSourceWarningDialog(instance);
111

    
112
            AbstractUtility.showView(CdmDataSourceViewPart.ID);
113
            return null;
114
        }
115
    }
116

    
117
    /**
118
     * Initialize the with the last edited datasource
119
     */
120
    public static void connect() {
121

    
122
        ICdmSource cdmSource;
123
        try {
124

    
125
            cdmSource = CdmDataSourceRepository.getCurrentCdmSource();
126
            connect(cdmSource);
127
        } catch (Exception e) {
128
            MessagingUtils.messageDialog("Connection to CDM Source Failed", CdmStore.class, "Could not connect to target CDM Source", e);
129
        }
130

    
131

    
132
    }
133

    
134
    /**
135
     * Initialize with a specific datasource
136
     *
137
     * @param datasource
138
     *            a {@link eu.etaxonomy.cdm.database.ICdmDataSource} object.
139
     */
140
    public static void connect(ICdmSource cdmSource) {
141
        connect(cdmSource, DEFAULT_DB_SCHEMA_VALIDATION,
142
                DEFAULT_APPLICATION_CONTEXT);
143
    }
144

    
145
    public static void connect(ICdmSource cdmSource, RemotingLoginDialog loginDialog) {
146
        connect(cdmSource,
147
                DEFAULT_DB_SCHEMA_VALIDATION,
148
                DEFAULT_APPLICATION_CONTEXT,
149
                loginDialog);
150
    }
151

    
152
    /**
153
     * Initialize and provide
154
     *
155
     * @param datasource
156
     * @param dbSchemaValidation
157
     * @param applicationContextBean
158
     */
159
    private static void connect(final ICdmSource cdmSource,
160
            final DbSchemaValidation dbSchemaValidation,
161
            final Resource applicationContextBean) {
162

    
163
        MessagingUtils.info("Connecting to datasource: " + cdmSource);
164

    
165
        job = new CdmStoreConnector(Display.getDefault(), cdmSource,
166
                dbSchemaValidation, applicationContextBean);
167
        job.setUser(true);
168
        job.setPriority(Job.BUILD);
169
        job.schedule();
170

    
171
    }
172

    
173
    private static void connect(final ICdmSource cdmSource,
174
            final DbSchemaValidation dbSchemaValidation,
175
            final Resource applicationContextBean,
176
            RemotingLoginDialog remotingLoginDialog) {
177
        RemotingLoginDialog loginDialog = remotingLoginDialog;
178

    
179
        MessagingUtils.info("Connecting to datasource: " + cdmSource);
180

    
181
        job = new CdmStoreConnector(Display.getDefault(),
182
                cdmSource,
183
                dbSchemaValidation,
184
                applicationContextBean);
185
        job.start(loginDialog);
186
        if(isActive()) {
187
            // before we connect we clear the entity caches and the sessions
188
            CdmRemoteCacheManager.removeEntityCaches();
189
            if(getCurrentSessionManager() != null) {
190
                getCurrentSessionManager().disposeAll();
191
            }
192
        }
193
    }
194

    
195
    public static boolean isConnecting() {
196
        return job != null && job.getState() == Job.RUNNING;
197
    }
198

    
199
    /**
200
     * Closes the current application context
201
     *
202
     * @param monitor
203
     *            a {@link org.eclipse.core.runtime.IProgressMonitor} object.
204
     */
205
    public static void close(final IProgressMonitor monitor) {
206
        Display.getDefault().asyncExec(new Runnable() {
207
            /*
208
             * (non-Javadoc)
209
             *
210
             * @see java.lang.Runnable#run()
211
             */
212
            @Override
213
            public void run() {
214
                getContextManager().notifyContextAboutToStop(monitor);
215
                if ((monitor == null || (!monitor.isCanceled()) && isActive())) {
216
                    getContextManager().notifyContextStop(monitor);
217
                    instance.close();
218
                }
219
            }
220
        });
221
    }
222

    
223
    public static void close(IProgressMonitor monitor, boolean async) {
224
        if(async) {
225
            close(monitor);
226
        } else {
227
            getContextManager().notifyContextAboutToStop(monitor);
228
            if ((monitor == null || (!monitor.isCanceled()) && isActive())) {
229
                getContextManager().notifyContextStop(monitor);
230
                instance.close();
231
            }
232
        }
233

    
234
    }
235
    private void close() {
236
        isConnected = false;
237
        cdmSource = null;
238
        CdmApplicationState.dispose();
239
    }
240

    
241
    static void setInstance(ICdmApplicationConfiguration applicationController,
242
            ICdmSource cdmSource) {
243
        instance = new CdmStore(applicationController, cdmSource);
244
    }
245

    
246
    private CdmStore(ICdmApplicationConfiguration applicationController,
247
            ICdmSource cdmSource) {
248
        CdmApplicationState.setCurrentAppConfig(applicationController);
249
        CdmApplicationState.setCurrentDataChangeService(new CdmUIDataChangeService());
250
        this.cdmSource = cdmSource;
251
        isConnected = true;
252
    }
253

    
254
    /**
255
     * All calls to the datastore require
256
     *
257
     * @return
258
     */
259
    private ICdmApplicationConfiguration getApplicationConfiguration() {
260
        try {
261
            return CdmApplicationState.getCurrentAppConfig();
262
        } catch (Exception e) {
263
            MessagingUtils.error(CdmStore.class, e);
264
        }
265
        return null;
266
    }
267

    
268
    /**
269
     * <p>
270
     * getCurrentApplicationController
271
     * </p>
272
     *
273
     * @return a
274
     *         {@link eu.etaxonomy.cdm.remote.api.application.CdmApplicationController}
275
     *         object.
276
     */
277
    public static ICdmApplicationConfiguration getCurrentApplicationConfiguration() {
278
        if (getDefault() != null) {
279
            return getDefault().getApplicationConfiguration();
280
        }
281
        return null;
282
    }
283

    
284
    /*
285
     * CONVERSATIONS
286
     */
287

    
288
    /**
289
     * Creates a new conversation, binds resources to the conversation and start
290
     * a transaction for this conversation.
291
     *
292
     * @return a {@link eu.etaxonomy.cdm.api.conversation.ConversationHolder}
293
     *         object.
294
     */
295
    public static ConversationHolder createConversation() {
296
        ConversationHolder conversation = getCurrentApplicationConfiguration()
297
                .NewConversation();
298
        try {
299
            conversation.startTransaction();
300
        }catch(Exception e){
301
            MessagingUtils.messageDialog("No database connection", CdmStore.class, "No database connection available", e);
302
        }
303
        return conversation;
304
    }
305

    
306
    //FIXME:Remoting should be removed after moving completely to remoting
307
    private MockCdmEntitySessionManager mockCdmEntitySessionManager;
308

    
309
    private ICdmEntitySessionManager getSessionManager() {
310
        //FIXME:Remoting we should only have CdmApplicationRemoteConfiguration after move to remoting
311
        //               bad hack which should be finally removed
312
        if(getCurrentApplicationConfiguration() instanceof CdmApplicationRemoteController) {
313
            return ((CdmApplicationRemoteController)getCurrentApplicationConfiguration()).getCdmEntitySessionManager();
314
        } else {
315
            if(mockCdmEntitySessionManager == null) {
316
                mockCdmEntitySessionManager = new MockCdmEntitySessionManager();
317
            }
318
            return mockCdmEntitySessionManager;
319
        }
320
    }
321

    
322
    public static  ICdmEntitySessionManager getCurrentSessionManager() {
323
        if (getDefault() != null) {
324
            return getDefault().getSessionManager();
325
        }
326
        return null;
327

    
328
    }
329

    
330
    /**
331
     * Generic method that will scan the getters of {@link ICdmApplicationConfiguration} for the given service
332
     * interface. If a matching getter is found the according service implementation is returned by
333
     * invoking the getter otherwise the method returns <code>null</code>.
334
     *
335
     * @param <T>
336
     * @param serviceClass
337
     * @return the configured implementation of <code>serviceClass</code> or <code>null</code>
338
     */
339
    public static <T extends IService> T getService(Class<T> serviceClass) {
340
        T service = null;
341
        try {
342
            service = CdmApplicationState.getService(serviceClass);
343
        } catch (CdmApplicationException cae) {
344
            MessagingUtils.error(CdmStore.class, cae);
345
        }
346

    
347
        return service;
348
    }
349

    
350
    /**
351
     * @see #getService(Class)
352
     * As ICommonService is not extending IService we need a specific request here
353
     */
354
    public static ICommonService getCommonService() {
355
        return CdmApplicationState.getCommonService();
356

    
357
    }
358

    
359
    /**
360
     * <p>
361
     * getAuthenticationManager
362
     * </p>
363
     *
364
     * @return a
365
     *         {@link org.springframework.security.authentication.ProviderManager}
366
     *         object.
367
     */
368
    public static AuthenticationManager getAuthenticationManager() {
369
        return getCurrentApplicationConfiguration().getAuthenticationManager();
370
    }
371

    
372
    /**
373
     * <p>
374
     * getAuthenticationManager
375
     * </p>
376
     *
377
     * @return a
378
     *         {@link ICdmPermissionEvaluator} object.
379
     */
380
    public static ICdmPermissionEvaluator getPermissionEvaluator() {
381
        return getCurrentApplicationConfiguration().getPermissionEvaluator();
382
    }
383

    
384
    /**
385
     * <p>
386
     * getGeoService
387
     * </p>
388
     *
389
     * @return a {@link eu.etaxonomy.cdm.ext.geo.IEditGeoService} object.
390
     */
391
    public static IEditGeoService getGeoService() {
392
        return (IEditGeoService) getCurrentApplicationConfiguration().getBean(
393
                "editGeoService");
394
    }
395

    
396
    /*
397
     * SECURITY RELATED CONVENIENCE METHODS
398
     */
399

    
400
    /**
401
     * @see org.springframework.security.access.PermissionEvaluator#hasPermission(org.springframework.security.core.Authentication, java.lang.Object, java.lang.Object)
402
     *
403
     * @param targetDomainObject
404
     * @param permission
405
     * @return
406
     */
407
    public static boolean currentAuthentiationHasPermission(CdmBase targetDomainObject, EnumSet<CRUD> permission){
408
        //TODO use getCurrentApplicationConfiguration().currentAuthentiationHasPermission(CdmBase targetDomainObject, Operation permission) instead
409
        SecurityContext context = SecurityContextHolder.getContext();
410
        PermissionEvaluator pe = getPermissionEvaluator();
411
        boolean hasPermission = false;
412
        try {
413
            hasPermission = getPermissionEvaluator().hasPermission(context.getAuthentication(), targetDomainObject,
414
                    permission);
415
        } catch (org.springframework.security.access.AccessDeniedException e) {
416
            /* IGNORE */
417
        }
418
        return hasPermission;
419
    }
420

    
421
    /**
422
     * @see org.springframework.security.access.PermissionEvaluator#hasPermission(org.springframework.security.core.Authentication, java.lang.Object, java.lang.Object)
423
     *
424
     * @param targetDomainObject
425
     * @param permission
426
     * @return
427
     */
428
    public static boolean currentAuthentiationHasPermission(Class<? extends CdmBase> targetType, EnumSet<CRUD> permission){
429
        boolean hasPermission = false;
430
        try {
431
            hasPermission = getPermissionEvaluator().hasPermission(getCurrentAuthentiation(), null, targetType.getName(), permission);
432
        } catch (org.springframework.security.access.AccessDeniedException e) {
433
            /* IGNORE */
434
        }
435
        return hasPermission;
436
    }
437

    
438
    public static boolean currentAuthentiationHasOneOfRoles(Role ... roles){
439
        boolean hasPermission = false;
440
        try {
441
            hasPermission =  getPermissionEvaluator().hasOneOfRoles(getCurrentAuthentiation(), roles);
442
        } catch (org.springframework.security.access.AccessDeniedException e) {
443
            /* IGNORE */
444
        }
445
        return hasPermission;
446
    }
447

    
448
    public static Authentication getCurrentAuthentiation() {
449
        SecurityContext context = SecurityContextHolder.getContext();
450
        return context.getAuthentication();
451
    }
452

    
453
    /*
454
     * LANGUAGE
455
     */
456

    
457
    /**
458
     * Provides access to the global default language set in the application preferences.
459
     *
460
     * @return a {@link eu.etaxonomy.cdm.model.common.Language} object.
461
     */
462
    public static Language getDefaultLanguage() {
463
        if (getDefault().getLanguage() == null) {
464
            getDefault().setLanguage(PreferencesUtil.getGlobalLanguage());
465
        }
466
        return getDefault().getLanguage();
467
    }
468

    
469
    /**
470
     * <p>
471
     * setDefaultLanguage
472
     * </p>
473
     *
474
     * @param language
475
     *            a {@link eu.etaxonomy.cdm.model.common.Language} object.
476
     */
477
    public static void setDefaultLanguage(Language language) {
478
        getDefault().setLanguage(language);
479
    }
480

    
481
    /**
482
     * @return the language
483
     */
484
    private Language getLanguage() {
485
        return language;
486
    }
487

    
488
    /**
489
     * @param language
490
     *            the language to set
491
     */
492
    private void setLanguage(Language language) {
493
        this.language = language;
494
    }
495

    
496
    /*
497
     * LOGIN
498
     */
499

    
500
    /**
501
     * <p>
502
     * Getter for the field <code>loginManager</code>.
503
     * </p>
504
     *
505
     * @return a {@link eu.etaxonomy.taxeditor.store.LoginManager} object.
506
     */
507
    public static LoginManager getLoginManager() {
508
        return loginManager;
509
    }
510

    
511
    /**
512
     * <p>
513
     * Getter for the field <code>contextManager</code>.
514
     * </p>
515
     *
516
     * @return a {@link eu.etaxonomy.taxeditor.store.ContextManager} object.
517
     */
518
    public static ContextManager getContextManager() {
519
        return contextManager;
520
    }
521

    
522
    public static TermManager getTermManager() {
523
        return termManager;
524
    }
525

    
526
    public static SearchManager getSearchManager() {
527
        return searchManager;
528
    }
529

    
530
    public static EditorManager getEditorManager() {
531
        return editorManager;
532
    }
533

    
534
    /*
535
     * IMPORT/EXPORT FACTORIES
536
     */
537

    
538
    /**
539
     * <p>
540
     * Getter for the field <code>importHandler</code>.
541
     * </p>
542
     *
543
     * @return a {@link eu.etaxonomy.taxeditor.io.ImportManager} object.
544
     */
545
    public static ImportManager getImportManager() {
546
        return ImportManager.NewInstance(getCurrentApplicationConfiguration());
547
    }
548

    
549
    /**
550
     * <p>
551
     * Getter for the field <code>exportHandler</code>.
552
     * </p>
553
     *
554
     * @return a {@link eu.etaxonomy.taxeditor.io.ExportManager} object.
555
     */
556
    public static ExportManager getExportManager() {
557
        return ExportManager.NewInstance(getCurrentApplicationConfiguration());
558
    }
559

    
560
    /**
561
     * Whether this CdmStore is currently connected to a datasource
562
     *
563
     * @return a boolean.
564
     */
565
    public static boolean isActive() {
566
        return instance != null && instance.isConnected;
567
    }
568

    
569
    public static ICdmSource getActiveCdmSource() {
570
        if (isActive()) {
571
            return instance.getCdmSource();
572
        }
573
        return null;
574
    }
575

    
576
    /**
577
     * <p>
578
     * getDataSource
579
     * </p>
580
     *
581
     * @return a {@link eu.etaxonomy.cdm.database.ICdmDataSource} object.
582
     * @deprecated currently retained for backward compatibility - use {@link getActiveCdmSource()} instead
583
     */
584
    //	public static ICdmDataSource getDataSource() {
585
    //		if (isActive()) {
586
    //			return (ICdmDataSource)instance.getCdmSource();
587
    //		}
588
    //		return null;
589
    //	}
590

    
591
    /**
592
     * @return
593
     */
594
    private ICdmSource getCdmSource() {
595
        return cdmSource;
596
    }
597

    
598
}
(2-2/13)