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
.List
;
16 import java
.util
.UUID
;
18 import org
.apache
.log4j
.Logger
;
19 import org
.hibernate
.SessionFactory
;
20 import org
.springframework
.beans
.MutablePropertyValues
;
21 import org
.springframework
.beans
.factory
.config
.BeanDefinition
;
22 import org
.springframework
.beans
.factory
.xml
.XmlBeanDefinitionReader
;
23 import org
.springframework
.context
.ApplicationListener
;
24 import org
.springframework
.context
.support
.AbstractApplicationContext
;
25 import org
.springframework
.core
.io
.ClassPathResource
;
26 import org
.springframework
.core
.io
.Resource
;
27 import org
.springframework
.security
.access
.PermissionEvaluator
;
28 import org
.springframework
.security
.authentication
.ProviderManager
;
29 import org
.springframework
.security
.core
.context
.SecurityContext
;
30 import org
.springframework
.security
.core
.context
.SecurityContextHolder
;
31 import org
.springframework
.transaction
.PlatformTransactionManager
;
32 import org
.springframework
.transaction
.TransactionStatus
;
34 import eu
.etaxonomy
.cdm
.api
.conversation
.ConversationHolder
;
35 import eu
.etaxonomy
.cdm
.api
.service
.IAgentService
;
36 import eu
.etaxonomy
.cdm
.api
.service
.IClassificationService
;
37 import eu
.etaxonomy
.cdm
.api
.service
.ICollectionService
;
38 import eu
.etaxonomy
.cdm
.api
.service
.ICommonService
;
39 import eu
.etaxonomy
.cdm
.api
.service
.IDatabaseService
;
40 import eu
.etaxonomy
.cdm
.api
.service
.IDescriptionService
;
41 import eu
.etaxonomy
.cdm
.api
.service
.IFeatureNodeService
;
42 import eu
.etaxonomy
.cdm
.api
.service
.IFeatureTreeService
;
43 import eu
.etaxonomy
.cdm
.api
.service
.IGrantedAuthorityService
;
44 import eu
.etaxonomy
.cdm
.api
.service
.IGroupService
;
45 import eu
.etaxonomy
.cdm
.api
.service
.IIdentificationKeyService
;
46 import eu
.etaxonomy
.cdm
.api
.service
.ILocationService
;
47 import eu
.etaxonomy
.cdm
.api
.service
.IMediaService
;
48 import eu
.etaxonomy
.cdm
.api
.service
.INameService
;
49 import eu
.etaxonomy
.cdm
.api
.service
.IOccurrenceService
;
50 import eu
.etaxonomy
.cdm
.api
.service
.IPolytomousKeyNodeService
;
51 import eu
.etaxonomy
.cdm
.api
.service
.IPolytomousKeyService
;
52 import eu
.etaxonomy
.cdm
.api
.service
.IReferenceService
;
53 import eu
.etaxonomy
.cdm
.api
.service
.IService
;
54 import eu
.etaxonomy
.cdm
.api
.service
.ITaxonNodeService
;
55 import eu
.etaxonomy
.cdm
.api
.service
.ITaxonService
;
56 import eu
.etaxonomy
.cdm
.api
.service
.ITermService
;
57 import eu
.etaxonomy
.cdm
.api
.service
.IUserService
;
58 import eu
.etaxonomy
.cdm
.api
.service
.IVocabularyService
;
59 import eu
.etaxonomy
.cdm
.api
.service
.IWorkingSetService
;
60 import eu
.etaxonomy
.cdm
.common
.monitor
.IProgressMonitor
;
61 import eu
.etaxonomy
.cdm
.common
.monitor
.NullProgressMonitor
;
62 import eu
.etaxonomy
.cdm
.common
.monitor
.SubProgressMonitor
;
63 import eu
.etaxonomy
.cdm
.database
.CdmPersistentDataSource
;
64 import eu
.etaxonomy
.cdm
.database
.DataSourceNotFoundException
;
65 import eu
.etaxonomy
.cdm
.database
.DbSchemaValidation
;
66 import eu
.etaxonomy
.cdm
.database
.ICdmDataSource
;
67 import eu
.etaxonomy
.cdm
.model
.common
.CdmBase
;
68 import eu
.etaxonomy
.cdm
.model
.common
.CdmMetaData
;
69 import eu
.etaxonomy
.cdm
.model
.common
.DefinedTermBase
;
70 import eu
.etaxonomy
.cdm
.model
.common
.User
;
71 import eu
.etaxonomy
.cdm
.persistence
.hibernate
.permission
.CRUD
;
72 import eu
.etaxonomy
.cdm
.persistence
.hibernate
.permission
.Operation
;
79 public class CdmApplicationController
implements ICdmApplicationConfiguration
{
80 private static final Logger logger
= Logger
.getLogger(CdmApplicationController
.class);
82 public static final String DEFAULT_APPLICATION_CONTEXT_RESOURCE
= "/eu/etaxonomy/cdm/defaultApplicationContext.xml";
84 public AbstractApplicationContext applicationContext
;
85 private ICdmApplicationConfiguration configuration
;
86 private Resource applicationContextResource
;
88 private IProgressMonitor progressMonitor
;
90 final protected static DbSchemaValidation defaultDbSchemaValidation
= DbSchemaValidation
.VALIDATE
;
95 * Constructor, opens a spring ApplicationContext by using the default data source
96 * @throws DataSourceNotFoundException
98 public static CdmApplicationController
NewInstance() throws DataSourceNotFoundException
{
99 logger
.info("Start CdmApplicationController with default data source");
100 CdmPersistentDataSource dataSource
= getDefaultDatasource();
101 DbSchemaValidation dbSchemaValidation
= defaultDbSchemaValidation
;
102 return CdmApplicationController
.NewInstance(null, dataSource
, dbSchemaValidation
, false);
106 * Constructor, opens a spring ApplicationContext by using the default data source
107 * @param dbSchemaValidation validation type for database schema
108 * @throws DataSourceNotFoundException
110 public static CdmApplicationController
NewInstance(DbSchemaValidation dbSchemaValidation
) throws DataSourceNotFoundException
{
111 logger
.info("Start CdmApplicationController with default data source");
112 CdmPersistentDataSource dataSource
= getDefaultDatasource();
113 return CdmApplicationController
.NewInstance(null, dataSource
, dbSchemaValidation
, false);
118 * Constructor, opens an spring ApplicationContext by using the according data source and the
119 * default database schema validation type
122 public static CdmApplicationController
NewInstance(ICdmDataSource dataSource
) {
123 return CdmApplicationController
.NewInstance(null, dataSource
, defaultDbSchemaValidation
, false);
126 public static CdmApplicationController
NewInstance(ICdmDataSource dataSource
, DbSchemaValidation dbSchemaValidation
) {
127 return CdmApplicationController
.NewInstance(null, dataSource
, dbSchemaValidation
, false);
130 public static CdmApplicationController
NewInstance(ICdmDataSource dataSource
, DbSchemaValidation dbSchemaValidation
, boolean omitTermLoading
) {
131 return CdmApplicationController
.NewInstance(null, dataSource
, dbSchemaValidation
, omitTermLoading
);
134 public static CdmApplicationController
NewInstance(Resource applicationContextResource
, ICdmDataSource dataSource
, DbSchemaValidation dbSchemaValidation
, boolean omitTermLoading
) {
135 return CdmApplicationController
.NewInstance(applicationContextResource
, dataSource
, dbSchemaValidation
, omitTermLoading
, null);
138 public static CdmApplicationController
NewInstance(Resource applicationContextResource
, ICdmDataSource dataSource
, DbSchemaValidation dbSchemaValidation
, boolean omitTermLoading
, IProgressMonitor progressMonitor
) {
139 return new CdmApplicationController(applicationContextResource
, dataSource
, dbSchemaValidation
, omitTermLoading
, progressMonitor
, null);
142 //TODO discuss need for listeners before commit to trunk
143 // public static CdmApplicationController NewInstance(Resource applicationContextResource, ICdmDataSource dataSource, DbSchemaValidation dbSchemaValidation, boolean omitTermLoading, IProgressMonitor progressMonitor, List<ApplicationListener> listeners) {
144 // return new CdmApplicationController(applicationContextResource, dataSource, dbSchemaValidation, omitTermLoading, progressMonitor,listeners);
151 protected static ClassPathResource
getClasspathResource() {
152 return new ClassPathResource(DEFAULT_APPLICATION_CONTEXT_RESOURCE
);
157 * @throws DataSourceNotFoundException
159 protected static CdmPersistentDataSource
getDefaultDatasource() throws DataSourceNotFoundException
{
160 CdmPersistentDataSource dataSource
= CdmPersistentDataSource
.NewDefaultInstance();
166 * Constructor, opens an spring 2.5 ApplicationContext by using the according data source
168 * @param dbSchemaValidation
169 * @param omitTermLoading
171 protected CdmApplicationController(Resource applicationContextResource
, ICdmDataSource dataSource
, DbSchemaValidation dbSchemaValidation
, boolean omitTermLoading
, IProgressMonitor progressMonitor
, List
<ApplicationListener
> listeners
){
172 logger
.info("Start CdmApplicationController with datasource: " + dataSource
.getName());
174 if (dbSchemaValidation
== null){
175 dbSchemaValidation
= defaultDbSchemaValidation
;
177 this.applicationContextResource
= applicationContextResource
!= null ? applicationContextResource
: getClasspathResource();
178 this.progressMonitor
= progressMonitor
!= null ? progressMonitor
: new NullProgressMonitor();
180 setNewDataSource(dataSource
, dbSchemaValidation
, omitTermLoading
, listeners
);
185 * Sets the application context to a new spring ApplicationContext by using the according data source and initializes the Controller.
188 private boolean setNewDataSource(ICdmDataSource dataSource
, DbSchemaValidation dbSchemaValidation
, boolean omitTermLoading
, List
<ApplicationListener
> listeners
){
190 if (dbSchemaValidation
== null){
191 dbSchemaValidation
= defaultDbSchemaValidation
;
193 logger
.info("Connecting to '" + dataSource
.getName() + "'");
195 MonitoredGenericApplicationContext applicationContext
= new MonitoredGenericApplicationContext();
196 int refreshTasks
= 45;
197 int nTasks
= 5 + refreshTasks
;
198 // nTasks += applicationContext.countTasks();
199 progressMonitor
.beginTask("Connecting to '" + dataSource
.getName() + "'", nTasks
);
201 // progressMonitor.worked(1);
203 BeanDefinition datasourceBean
= dataSource
.getDatasourceBean();
204 datasourceBean
.setAttribute("isLazy", false);
205 progressMonitor
.subTask("Registering datasource.");
206 applicationContext
.registerBeanDefinition("dataSource", datasourceBean
);
207 progressMonitor
.worked(1);
209 BeanDefinition hibernatePropBean
= dataSource
.getHibernatePropertiesBean(dbSchemaValidation
);
210 applicationContext
.registerBeanDefinition("hibernateProperties", hibernatePropBean
);
212 XmlBeanDefinitionReader xmlReader
= new XmlBeanDefinitionReader(applicationContext
);
213 progressMonitor
.subTask("Registering resources.");
214 xmlReader
.loadBeanDefinitions(applicationContextResource
);
215 progressMonitor
.worked(1);
218 if (omitTermLoading
== true){
219 String initializerName
= "persistentTermInitializer";
220 BeanDefinition beanDef
= applicationContext
.getBeanDefinition(initializerName
);
221 MutablePropertyValues values
= beanDef
.getPropertyValues();
222 values
.addPropertyValue("omit", omitTermLoading
);
225 if (listeners
!= null){
226 for(ApplicationListener listener
: listeners
){
227 applicationContext
.addApplicationListener(listener
);
231 // String message = "Start application context. This might take a while ...";
232 //// progressMonitor.subTask(message);
233 // SubProgressMonitor subMonitor= new SubProgressMonitor(progressMonitor, 10);
234 // subMonitor.beginTask(message, 2);
235 // applicationContext.setProgressMonitor(subMonitor);
237 applicationContext
.refresh(new SubProgressMonitor(progressMonitor
, refreshTasks
));
238 applicationContext
.start();
239 // progressMonitor.worked(1);
241 progressMonitor
.subTask("Cleaning up.");
242 setApplicationContext(applicationContext
);
243 progressMonitor
.worked(1);
245 //initialize user and metaData for new databases
246 int userCount
= getUserService().count(User
.class);
247 if (userCount
== 0 ){
248 progressMonitor
.subTask("Creating Admin User");
251 progressMonitor
.worked(1);
254 int metaDataCount
= getCommonService().getCdmMetaData().size();
255 if (metaDataCount
== 0){
256 progressMonitor
.subTask("Creating Meta Data");
259 progressMonitor
.worked(1);
261 progressMonitor
.done();
265 protected void createAdminUser(){
266 User firstUser
= User
.NewInstance("admin", "00000");
267 getUserService().save(firstUser
);
268 logger
.info("Admin user created.");
271 protected void createMetadata(){
272 List
<CdmMetaData
> metaData
= CdmMetaData
.defaultMetaData();
273 getCommonService().saveAllMetaData(metaData
);
274 logger
.info("Metadata created.");
279 * Tests if some DefinedTermsAreMissing.
280 * @return true, if at least one is missing, else false
282 public boolean testDefinedTermsAreMissing(){
283 UUID englishUuid
= UUID
.fromString("e9f8cdb7-6819-44e8-95d3-e2d0690c3523");
284 DefinedTermBase
<?
> english
= this.getTermService().load(englishUuid
);
285 if ( english
== null || ! english
.getUuid().equals(englishUuid
)){
294 * Changes the ApplicationContext to the new dataSource
297 public boolean changeDataSource(ICdmDataSource dataSource
){
298 //logger.info("Change datasource to : " + dataSource);
299 return setNewDataSource(dataSource
, DbSchemaValidation
.VALIDATE
, false, null);
303 * Changes the ApplicationContext to the new dataSource
305 * @param dbSchemaValidation
307 public boolean changeDataSource(ICdmDataSource dataSource
, DbSchemaValidation dbSchemaValidation
){
308 //logger.info("Change datasource to : " + dataSource);
309 return setNewDataSource(dataSource
, dbSchemaValidation
, false, null);
313 * Changes the ApplicationContext to the new dataSource
315 * @param dbSchemaValidation
316 * @param omitTermLoading
318 public boolean changeDataSource(ICdmDataSource dataSource
, DbSchemaValidation dbSchemaValidation
, boolean omitTermLoading
){
319 logger
.info("Change datasource to : " + dataSource
);
320 return setNewDataSource(dataSource
, dbSchemaValidation
, omitTermLoading
, null);
324 * Changes the ApplicationContext to the new dataSource
326 * @param dbSchemaValidation
327 * @param omitTermLoading
329 public boolean changeDataSource(ICdmDataSource dataSource
, DbSchemaValidation dbSchemaValidation
, boolean omitTermLoading
, List
<ApplicationListener
> listeners
){
330 logger
.info("Change datasource to : " + dataSource
);
331 return setNewDataSource(dataSource
, dbSchemaValidation
, omitTermLoading
, listeners
);
335 * Sets a new application Context.
338 public void setApplicationContext(AbstractApplicationContext ac
){
339 closeApplicationContext(); //closes old application context if necessary
340 applicationContext
= ac
;
341 applicationContext
.registerShutdownHook();
346 * @see java.lang.Object#finalize()
348 public void finalize(){
353 * closes the application
356 closeApplicationContext();
360 * closes the application context
362 protected void closeApplicationContext(){
363 if (applicationContext
!= null){
364 logger
.info("Close ApplicationContext");
365 applicationContext
.close();
369 protected void init(){
370 logger
.debug("Init " + this.getClass().getName() + " ... ");
371 if (logger
.isDebugEnabled()){for (String beanName
: applicationContext
.getBeanDefinitionNames()){ logger
.debug(beanName
);}}
372 //TODO delete next row (was just for testing)
373 if (logger
.isInfoEnabled()){
374 logger
.info("Registered Beans: ");
375 String
[] beanNames
= applicationContext
.getBeanDefinitionNames();
376 for (String beanName
: beanNames
){
377 logger
.info(beanName
);
380 configuration
= (ICdmApplicationConfiguration
)applicationContext
.getBean("cdmApplicationDefaultConfiguration");
381 getDatabaseService().setApplicationController(this);
386 /* ****** Services *********/
387 public final INameService
getNameService(){
388 return configuration
.getNameService();
391 public final ITaxonService
getTaxonService(){
392 return configuration
.getTaxonService();
395 public final IClassificationService
getClassificationService(){
396 return configuration
.getClassificationService();
399 public final ITaxonNodeService
getTaxonNodeService(){
400 return configuration
.getTaxonNodeService();
403 public final IReferenceService
getReferenceService(){
404 return configuration
.getReferenceService();
407 public final IAgentService
getAgentService(){
408 return configuration
.getAgentService();
411 public final IDatabaseService
getDatabaseService(){
412 return configuration
.getDatabaseService();
415 public final ITermService
getTermService(){
416 return configuration
.getTermService();
419 public final IDescriptionService
getDescriptionService(){
420 return configuration
.getDescriptionService();
423 public final IOccurrenceService
getOccurrenceService(){
424 return configuration
.getOccurrenceService();
427 public final IMediaService
getMediaService(){
428 return configuration
.getMediaService();
431 public final ICommonService
getCommonService(){
432 return configuration
.getCommonService();
435 public final ILocationService
getLocationService(){
436 return configuration
.getLocationService();
439 public final IUserService
getUserService(){
440 return configuration
.getUserService();
443 public final IGrantedAuthorityService
getGrantedAuthorityService(){
444 return configuration
.getGrantedAuthorityService();
447 public IGroupService
getGroupService() {
448 return configuration
.getGroupService();
451 public final ICollectionService
getCollectionService(){
452 return configuration
.getCollectionService();
455 public final IFeatureTreeService
getFeatureTreeService(){
456 return configuration
.getFeatureTreeService();
459 public final IFeatureNodeService
getFeatureNodeService(){
460 return configuration
.getFeatureNodeService();
463 public final IVocabularyService
getVocabularyService(){
464 return configuration
.getVocabularyService();
467 public final IIdentificationKeyService
getIdentificationKeyService(){
468 return configuration
.getIdentificationKeyService();
471 public final IPolytomousKeyService
getPolytomousKeyService(){
472 return configuration
.getPolytomousKeyService();
475 public final IPolytomousKeyNodeService
getPolytomousKeyNodeService(){
476 return configuration
.getPolytomousKeyNodeService();
479 public final IService
<CdmBase
> getMainService(){
480 return configuration
.getMainService();
483 public final IWorkingSetService
getWorkingSetService(){
484 return configuration
.getWorkingSetService();
487 public final ConversationHolder
NewConversation(){
488 //return (ConversationHolder)applicationContext.getBean("conversationHolder");
489 return configuration
.NewConversation();
493 /* **** Security ***** */
496 * @see eu.etaxonomy.cdm.api.application.ICdmApplicationConfiguration#getAuthenticationManager()
498 public final ProviderManager
getAuthenticationManager(){
499 return configuration
.getAuthenticationManager();
503 public PermissionEvaluator
getPermissionEvaluator() {
504 return configuration
.getPermissionEvaluator();
508 * @see org.springframework.security.access.PermissionEvaluator#hasPermission(org.springframework.security.core.Authentication, java.lang.Object, java.lang.Object)
510 * @param targetDomainObject
514 public boolean currentAuthentiationHasPermissions(CdmBase targetDomainObject
, EnumSet
<CRUD
> permission
){
515 SecurityContext context
= SecurityContextHolder
.getContext();
516 return getPermissionEvaluator().hasPermission(context
.getAuthentication(), targetDomainObject
, permission
);
521 public final PlatformTransactionManager
getTransactionManager() {
522 return configuration
.getTransactionManager();
525 public final Object
getBean(String name
){
526 return this.applicationContext
.getBean(name
);
530 * OLD TRANSACTION STUFF
533 /* **** flush ***********/
534 public void flush() {
535 SessionFactory sf
= (SessionFactory
)applicationContext
.getBean("sessionFactory");
536 sf
.getCurrentSession().flush();
539 public SessionFactory
getSessionFactory(){
540 return (SessionFactory
)applicationContext
.getBean("sessionFactory");
543 public TransactionStatus
startTransaction() {
544 return startTransaction(false);
547 public TransactionStatus
startTransaction(Boolean readOnly
) {
548 return configuration
.startTransaction(readOnly
);
551 public void commitTransaction(TransactionStatus txStatus
){
552 PlatformTransactionManager txManager
= configuration
.getTransactionManager();
553 txManager
.commit(txStatus
);