3 * Copyright (C) 2007 EDIT
4 * European Distributed Institute of Taxonomy
5 * http://www.e-taxonomy.eu
7 * The contents of this file are subject to the Mozilla Public License Version 1.1
8 * See LICENSE.TXT at the top of this package for the full license terms.
12 package eu
.etaxonomy
.cdm
.api
.application
;
14 import java
.util
.EnumSet
;
15 import java
.util
.HashSet
;
16 import java
.util
.List
;
18 import java
.util
.UUID
;
20 import org
.apache
.log4j
.Logger
;
21 import org
.hibernate
.SessionFactory
;
22 import org
.springframework
.beans
.MutablePropertyValues
;
23 import org
.springframework
.beans
.factory
.config
.BeanDefinition
;
24 import org
.springframework
.beans
.factory
.xml
.XmlBeanDefinitionReader
;
25 import org
.springframework
.context
.ApplicationListener
;
26 import org
.springframework
.context
.support
.AbstractApplicationContext
;
27 import org
.springframework
.core
.io
.ClassPathResource
;
28 import org
.springframework
.core
.io
.Resource
;
29 import org
.springframework
.security
.access
.PermissionEvaluator
;
30 import org
.springframework
.security
.authentication
.ProviderManager
;
31 import org
.springframework
.security
.core
.GrantedAuthority
;
32 import org
.springframework
.security
.core
.context
.SecurityContext
;
33 import org
.springframework
.security
.core
.context
.SecurityContextHolder
;
34 import org
.springframework
.transaction
.PlatformTransactionManager
;
35 import org
.springframework
.transaction
.TransactionStatus
;
37 import eu
.etaxonomy
.cdm
.api
.conversation
.ConversationHolder
;
38 import eu
.etaxonomy
.cdm
.api
.service
.IAgentService
;
39 import eu
.etaxonomy
.cdm
.api
.service
.IClassificationService
;
40 import eu
.etaxonomy
.cdm
.api
.service
.ICollectionService
;
41 import eu
.etaxonomy
.cdm
.api
.service
.ICommonService
;
42 import eu
.etaxonomy
.cdm
.api
.service
.IDatabaseService
;
43 import eu
.etaxonomy
.cdm
.api
.service
.IDescriptionService
;
44 import eu
.etaxonomy
.cdm
.api
.service
.IFeatureNodeService
;
45 import eu
.etaxonomy
.cdm
.api
.service
.IFeatureTreeService
;
46 import eu
.etaxonomy
.cdm
.api
.service
.IGrantedAuthorityService
;
47 import eu
.etaxonomy
.cdm
.api
.service
.IGroupService
;
48 import eu
.etaxonomy
.cdm
.api
.service
.IIdentificationKeyService
;
49 import eu
.etaxonomy
.cdm
.api
.service
.ILocationService
;
50 import eu
.etaxonomy
.cdm
.api
.service
.IMediaService
;
51 import eu
.etaxonomy
.cdm
.api
.service
.INameService
;
52 import eu
.etaxonomy
.cdm
.api
.service
.IOccurrenceService
;
53 import eu
.etaxonomy
.cdm
.api
.service
.IPolytomousKeyNodeService
;
54 import eu
.etaxonomy
.cdm
.api
.service
.IPolytomousKeyService
;
55 import eu
.etaxonomy
.cdm
.api
.service
.IReferenceService
;
56 import eu
.etaxonomy
.cdm
.api
.service
.IService
;
57 import eu
.etaxonomy
.cdm
.api
.service
.ITaxonNodeService
;
58 import eu
.etaxonomy
.cdm
.api
.service
.ITaxonService
;
59 import eu
.etaxonomy
.cdm
.api
.service
.ITermService
;
60 import eu
.etaxonomy
.cdm
.api
.service
.IUserService
;
61 import eu
.etaxonomy
.cdm
.api
.service
.IVocabularyService
;
62 import eu
.etaxonomy
.cdm
.api
.service
.IWorkingSetService
;
63 import eu
.etaxonomy
.cdm
.common
.monitor
.IProgressMonitor
;
64 import eu
.etaxonomy
.cdm
.common
.monitor
.NullProgressMonitor
;
65 import eu
.etaxonomy
.cdm
.common
.monitor
.SubProgressMonitor
;
66 import eu
.etaxonomy
.cdm
.database
.CdmPersistentDataSource
;
67 import eu
.etaxonomy
.cdm
.database
.DataSourceNotFoundException
;
68 import eu
.etaxonomy
.cdm
.database
.DbSchemaValidation
;
69 import eu
.etaxonomy
.cdm
.database
.ICdmDataSource
;
70 import eu
.etaxonomy
.cdm
.model
.common
.CdmBase
;
71 import eu
.etaxonomy
.cdm
.model
.common
.CdmMetaData
;
72 import eu
.etaxonomy
.cdm
.model
.common
.DefinedTermBase
;
73 import eu
.etaxonomy
.cdm
.model
.common
.GrantedAuthorityImpl
;
74 import eu
.etaxonomy
.cdm
.model
.common
.User
;
75 import eu
.etaxonomy
.cdm
.persistence
.hibernate
.permission
.CRUD
;
76 import eu
.etaxonomy
.cdm
.persistence
.hibernate
.permission
.Operation
;
77 import eu
.etaxonomy
.cdm
.persistence
.hibernate
.permission
.Role
;
84 public class CdmApplicationController
implements ICdmApplicationConfiguration
{
85 private static final Logger logger
= Logger
.getLogger(CdmApplicationController
.class);
87 public static final String DEFAULT_APPLICATION_CONTEXT_RESOURCE
= "/eu/etaxonomy/cdm/defaultApplicationContext.xml";
89 public AbstractApplicationContext applicationContext
;
90 private ICdmApplicationConfiguration configuration
;
91 private Resource applicationContextResource
;
93 private IProgressMonitor progressMonitor
;
95 final protected static DbSchemaValidation defaultDbSchemaValidation
= DbSchemaValidation
.VALIDATE
;
100 * Constructor, opens a spring ApplicationContext by using the default data source
101 * @throws DataSourceNotFoundException
103 public static CdmApplicationController
NewInstance() throws DataSourceNotFoundException
{
104 logger
.info("Start CdmApplicationController with default data source");
105 CdmPersistentDataSource dataSource
= getDefaultDatasource();
106 DbSchemaValidation dbSchemaValidation
= defaultDbSchemaValidation
;
107 return CdmApplicationController
.NewInstance(null, dataSource
, dbSchemaValidation
, false);
111 * Constructor, opens a spring ApplicationContext by using the default data source
112 * @param dbSchemaValidation validation type for database schema
113 * @throws DataSourceNotFoundException
115 public static CdmApplicationController
NewInstance(DbSchemaValidation dbSchemaValidation
) throws DataSourceNotFoundException
{
116 logger
.info("Start CdmApplicationController with default data source");
117 CdmPersistentDataSource dataSource
= getDefaultDatasource();
118 return CdmApplicationController
.NewInstance(null, dataSource
, dbSchemaValidation
, false);
123 * Constructor, opens an spring ApplicationContext by using the according data source and the
124 * default database schema validation type
127 public static CdmApplicationController
NewInstance(ICdmDataSource dataSource
) {
128 return CdmApplicationController
.NewInstance(null, dataSource
, defaultDbSchemaValidation
, false);
131 public static CdmApplicationController
NewInstance(ICdmDataSource dataSource
, DbSchemaValidation dbSchemaValidation
) {
132 return CdmApplicationController
.NewInstance(null, dataSource
, dbSchemaValidation
, false);
135 public static CdmApplicationController
NewInstance(ICdmDataSource dataSource
, DbSchemaValidation dbSchemaValidation
, boolean omitTermLoading
) {
136 return CdmApplicationController
.NewInstance(null, dataSource
, dbSchemaValidation
, omitTermLoading
);
139 public static CdmApplicationController
NewInstance(Resource applicationContextResource
, ICdmDataSource dataSource
, DbSchemaValidation dbSchemaValidation
, boolean omitTermLoading
) {
140 return CdmApplicationController
.NewInstance(applicationContextResource
, dataSource
, dbSchemaValidation
, omitTermLoading
, null);
143 public static CdmApplicationController
NewInstance(Resource applicationContextResource
, ICdmDataSource dataSource
, DbSchemaValidation dbSchemaValidation
, boolean omitTermLoading
, IProgressMonitor progressMonitor
) {
144 return new CdmApplicationController(applicationContextResource
, dataSource
, dbSchemaValidation
, omitTermLoading
, progressMonitor
, null);
147 //TODO discuss need for listeners before commit to trunk
148 // public static CdmApplicationController NewInstance(Resource applicationContextResource, ICdmDataSource dataSource, DbSchemaValidation dbSchemaValidation, boolean omitTermLoading, IProgressMonitor progressMonitor, List<ApplicationListener> listeners) {
149 // return new CdmApplicationController(applicationContextResource, dataSource, dbSchemaValidation, omitTermLoading, progressMonitor,listeners);
156 protected static ClassPathResource
getClasspathResource() {
157 return new ClassPathResource(DEFAULT_APPLICATION_CONTEXT_RESOURCE
);
162 * @throws DataSourceNotFoundException
164 protected static CdmPersistentDataSource
getDefaultDatasource() throws DataSourceNotFoundException
{
165 CdmPersistentDataSource dataSource
= CdmPersistentDataSource
.NewDefaultInstance();
171 * Constructor, opens an spring 2.5 ApplicationContext by using the according data source
173 * @param dbSchemaValidation
174 * @param omitTermLoading
176 protected CdmApplicationController(Resource applicationContextResource
, ICdmDataSource dataSource
, DbSchemaValidation dbSchemaValidation
, boolean omitTermLoading
, IProgressMonitor progressMonitor
, List
<ApplicationListener
> listeners
){
177 logger
.info("Start CdmApplicationController with datasource: " + dataSource
.getName());
179 if (dbSchemaValidation
== null){
180 dbSchemaValidation
= defaultDbSchemaValidation
;
182 this.applicationContextResource
= applicationContextResource
!= null ? applicationContextResource
: getClasspathResource();
183 this.progressMonitor
= progressMonitor
!= null ? progressMonitor
: new NullProgressMonitor();
185 setNewDataSource(dataSource
, dbSchemaValidation
, omitTermLoading
, listeners
);
190 * Sets the application context to a new spring ApplicationContext by using the according data source and initializes the Controller.
193 private boolean setNewDataSource(ICdmDataSource dataSource
, DbSchemaValidation dbSchemaValidation
, boolean omitTermLoading
, List
<ApplicationListener
> listeners
){
195 if (dbSchemaValidation
== null){
196 dbSchemaValidation
= defaultDbSchemaValidation
;
198 logger
.info("Connecting to '" + dataSource
.getName() + "'");
200 MonitoredGenericApplicationContext applicationContext
= new MonitoredGenericApplicationContext();
201 int refreshTasks
= 45;
202 int nTasks
= 5 + refreshTasks
;
203 // nTasks += applicationContext.countTasks();
204 progressMonitor
.beginTask("Connecting to '" + dataSource
.getName() + "'", nTasks
);
206 // progressMonitor.worked(1);
208 BeanDefinition datasourceBean
= dataSource
.getDatasourceBean();
209 datasourceBean
.setAttribute("isLazy", false);
210 progressMonitor
.subTask("Registering datasource.");
211 applicationContext
.registerBeanDefinition("dataSource", datasourceBean
);
212 progressMonitor
.worked(1);
214 BeanDefinition hibernatePropBean
= dataSource
.getHibernatePropertiesBean(dbSchemaValidation
);
215 applicationContext
.registerBeanDefinition("hibernateProperties", hibernatePropBean
);
217 XmlBeanDefinitionReader xmlReader
= new XmlBeanDefinitionReader(applicationContext
);
218 progressMonitor
.subTask("Registering resources.");
219 xmlReader
.loadBeanDefinitions(applicationContextResource
);
220 progressMonitor
.worked(1);
223 if (omitTermLoading
== true){
224 String initializerName
= "persistentTermInitializer";
225 BeanDefinition beanDef
= applicationContext
.getBeanDefinition(initializerName
);
226 MutablePropertyValues values
= beanDef
.getPropertyValues();
227 values
.addPropertyValue("omit", omitTermLoading
);
230 if (listeners
!= null){
231 for(ApplicationListener listener
: listeners
){
232 applicationContext
.addApplicationListener(listener
);
236 // String message = "Start application context. This might take a while ...";
237 //// progressMonitor.subTask(message);
238 // SubProgressMonitor subMonitor= new SubProgressMonitor(progressMonitor, 10);
239 // subMonitor.beginTask(message, 2);
240 // applicationContext.setProgressMonitor(subMonitor);
242 applicationContext
.refresh(new SubProgressMonitor(progressMonitor
, refreshTasks
));
243 applicationContext
.start();
244 // progressMonitor.worked(1);
246 progressMonitor
.subTask("Cleaning up.");
247 setApplicationContext(applicationContext
);
248 progressMonitor
.worked(1);
250 progressMonitor
.done();
259 * Tests if some DefinedTermsAreMissing.
260 * @return true, if at least one is missing, else false
262 public boolean testDefinedTermsAreMissing(){
263 UUID englishUuid
= UUID
.fromString("e9f8cdb7-6819-44e8-95d3-e2d0690c3523");
264 DefinedTermBase
<?
> english
= this.getTermService().load(englishUuid
);
265 if ( english
== null || ! english
.getUuid().equals(englishUuid
)){
274 * Changes the ApplicationContext to the new dataSource
277 public boolean changeDataSource(ICdmDataSource dataSource
){
278 //logger.info("Change datasource to : " + dataSource);
279 return setNewDataSource(dataSource
, DbSchemaValidation
.VALIDATE
, false, null);
283 * Changes the ApplicationContext to the new dataSource
285 * @param dbSchemaValidation
287 public boolean changeDataSource(ICdmDataSource dataSource
, DbSchemaValidation dbSchemaValidation
){
288 //logger.info("Change datasource to : " + dataSource);
289 return setNewDataSource(dataSource
, dbSchemaValidation
, false, null);
293 * Changes the ApplicationContext to the new dataSource
295 * @param dbSchemaValidation
296 * @param omitTermLoading
298 public boolean changeDataSource(ICdmDataSource dataSource
, DbSchemaValidation dbSchemaValidation
, boolean omitTermLoading
){
299 logger
.info("Change datasource to : " + dataSource
);
300 return setNewDataSource(dataSource
, dbSchemaValidation
, omitTermLoading
, null);
304 * Changes the ApplicationContext to the new dataSource
306 * @param dbSchemaValidation
307 * @param omitTermLoading
309 public boolean changeDataSource(ICdmDataSource dataSource
, DbSchemaValidation dbSchemaValidation
, boolean omitTermLoading
, List
<ApplicationListener
> listeners
){
310 logger
.info("Change datasource to : " + dataSource
);
311 return setNewDataSource(dataSource
, dbSchemaValidation
, omitTermLoading
, listeners
);
315 * Sets a new application Context.
318 public void setApplicationContext(AbstractApplicationContext ac
){
319 closeApplicationContext(); //closes old application context if necessary
320 applicationContext
= ac
;
321 applicationContext
.registerShutdownHook();
326 * @see java.lang.Object#finalize()
328 public void finalize(){
333 * closes the application
336 closeApplicationContext();
340 * closes the application context
342 protected void closeApplicationContext(){
343 if (applicationContext
!= null){
344 logger
.info("Close ApplicationContext");
345 applicationContext
.close();
349 protected void init(){
350 logger
.debug("Init " + this.getClass().getName() + " ... ");
351 if (logger
.isDebugEnabled()){for (String beanName
: applicationContext
.getBeanDefinitionNames()){ logger
.debug(beanName
);}}
352 //TODO delete next row (was just for testing)
353 if (logger
.isInfoEnabled()){
354 logger
.info("Registered Beans: ");
355 String
[] beanNames
= applicationContext
.getBeanDefinitionNames();
356 for (String beanName
: beanNames
){
357 logger
.info(beanName
);
360 configuration
= (ICdmApplicationConfiguration
)applicationContext
.getBean("cdmApplicationDefaultConfiguration");
361 getDatabaseService().setApplicationController(this);
366 /* ****** Services *********/
367 public final INameService
getNameService(){
368 return configuration
.getNameService();
371 public final ITaxonService
getTaxonService(){
372 return configuration
.getTaxonService();
375 public final IClassificationService
getClassificationService(){
376 return configuration
.getClassificationService();
379 public final ITaxonNodeService
getTaxonNodeService(){
380 return configuration
.getTaxonNodeService();
383 public final IReferenceService
getReferenceService(){
384 return configuration
.getReferenceService();
387 public final IAgentService
getAgentService(){
388 return configuration
.getAgentService();
391 public final IDatabaseService
getDatabaseService(){
392 return configuration
.getDatabaseService();
395 public final ITermService
getTermService(){
396 return configuration
.getTermService();
399 public final IDescriptionService
getDescriptionService(){
400 return configuration
.getDescriptionService();
403 public final IOccurrenceService
getOccurrenceService(){
404 return configuration
.getOccurrenceService();
407 public final IMediaService
getMediaService(){
408 return configuration
.getMediaService();
411 public final ICommonService
getCommonService(){
412 return configuration
.getCommonService();
415 public final ILocationService
getLocationService(){
416 return configuration
.getLocationService();
419 public final IUserService
getUserService(){
420 return configuration
.getUserService();
423 public final IGrantedAuthorityService
getGrantedAuthorityService(){
424 return configuration
.getGrantedAuthorityService();
427 public IGroupService
getGroupService() {
428 return configuration
.getGroupService();
431 public final ICollectionService
getCollectionService(){
432 return configuration
.getCollectionService();
435 public final IFeatureTreeService
getFeatureTreeService(){
436 return configuration
.getFeatureTreeService();
439 public final IFeatureNodeService
getFeatureNodeService(){
440 return configuration
.getFeatureNodeService();
443 public final IVocabularyService
getVocabularyService(){
444 return configuration
.getVocabularyService();
447 public final IIdentificationKeyService
getIdentificationKeyService(){
448 return configuration
.getIdentificationKeyService();
451 public final IPolytomousKeyService
getPolytomousKeyService(){
452 return configuration
.getPolytomousKeyService();
455 public final IPolytomousKeyNodeService
getPolytomousKeyNodeService(){
456 return configuration
.getPolytomousKeyNodeService();
459 public final IService
<CdmBase
> getMainService(){
460 return configuration
.getMainService();
463 public final IWorkingSetService
getWorkingSetService(){
464 return configuration
.getWorkingSetService();
467 public final ConversationHolder
NewConversation(){
468 //return (ConversationHolder)applicationContext.getBean("conversationHolder");
469 return configuration
.NewConversation();
473 /* **** Security ***** */
476 * @see eu.etaxonomy.cdm.api.application.ICdmApplicationConfiguration#getAuthenticationManager()
478 public final ProviderManager
getAuthenticationManager(){
479 return configuration
.getAuthenticationManager();
483 public PermissionEvaluator
getPermissionEvaluator() {
484 return configuration
.getPermissionEvaluator();
488 * @see org.springframework.security.access.PermissionEvaluator#hasPermission(org.springframework.security.core.Authentication, java.lang.Object, java.lang.Object)
490 * @param targetDomainObject
494 public boolean currentAuthentiationHasPermissions(CdmBase targetDomainObject
, EnumSet
<CRUD
> permission
){
495 SecurityContext context
= SecurityContextHolder
.getContext();
496 return getPermissionEvaluator().hasPermission(context
.getAuthentication(), targetDomainObject
, permission
);
501 public final PlatformTransactionManager
getTransactionManager() {
502 return configuration
.getTransactionManager();
505 public final Object
getBean(String name
){
506 return this.applicationContext
.getBean(name
);
510 * OLD TRANSACTION STUFF
513 /* **** flush ***********/
514 public void flush() {
515 SessionFactory sf
= (SessionFactory
)applicationContext
.getBean("sessionFactory");
516 sf
.getCurrentSession().flush();
519 public SessionFactory
getSessionFactory(){
520 return (SessionFactory
)applicationContext
.getBean("sessionFactory");
523 public TransactionStatus
startTransaction() {
524 return startTransaction(false);
527 public TransactionStatus
startTransaction(Boolean readOnly
) {
528 return configuration
.startTransaction(readOnly
);
531 public void commitTransaction(TransactionStatus txStatus
){
532 PlatformTransactionManager txManager
= configuration
.getTransactionManager();
533 txManager
.commit(txStatus
);