Project

General

Profile

Download (16.5 KB) Statistics
| Branch: | Tag: | Revision:
1
// $Id$
2
/**
3
 * Copyright (C) 2007 EDIT
4
 * European Distributed Institute of Taxonomy 
5
 * http://www.e-taxonomy.eu
6
 * 
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.
9
 */
10

    
11

    
12
package eu.etaxonomy.cdm.api.application;
13

    
14
import java.util.List;
15
import java.util.UUID;
16

    
17
import org.apache.log4j.Logger;
18
import org.hibernate.SessionFactory;
19
import org.springframework.beans.factory.config.BeanDefinition;
20
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
21
import org.springframework.context.support.AbstractApplicationContext;
22
import org.springframework.context.support.GenericApplicationContext;
23
import org.springframework.core.io.ClassPathResource;
24
import org.springframework.core.io.Resource;
25
import org.springframework.security.authentication.ProviderManager;
26
import org.springframework.transaction.PlatformTransactionManager;
27
import org.springframework.transaction.TransactionDefinition;
28
import org.springframework.transaction.TransactionStatus;
29
import org.springframework.transaction.support.DefaultTransactionDefinition;
30

    
31
import eu.etaxonomy.cdm.api.conversation.ConversationHolder;
32
import eu.etaxonomy.cdm.api.service.IAgentService;
33
import eu.etaxonomy.cdm.api.service.ICollectionService;
34
import eu.etaxonomy.cdm.api.service.ICommonService;
35
import eu.etaxonomy.cdm.api.service.IDatabaseService;
36
import eu.etaxonomy.cdm.api.service.IDescriptionService;
37
import eu.etaxonomy.cdm.api.service.IFeatureNodeService;
38
import eu.etaxonomy.cdm.api.service.IFeatureTreeService;
39
import eu.etaxonomy.cdm.api.service.ILocationService;
40
import eu.etaxonomy.cdm.api.service.IMediaService;
41
import eu.etaxonomy.cdm.api.service.INameService;
42
import eu.etaxonomy.cdm.api.service.IOccurrenceService;
43
import eu.etaxonomy.cdm.api.service.IReferenceService;
44
import eu.etaxonomy.cdm.api.service.IService;
45
import eu.etaxonomy.cdm.api.service.ITaxonNodeService;
46
import eu.etaxonomy.cdm.api.service.ITaxonService;
47
import eu.etaxonomy.cdm.api.service.ITaxonTreeService;
48
import eu.etaxonomy.cdm.api.service.ITermService;
49
import eu.etaxonomy.cdm.api.service.IUserService;
50
import eu.etaxonomy.cdm.api.service.IVocabularyService;
51
import eu.etaxonomy.cdm.common.IProgressMonitor;
52
import eu.etaxonomy.cdm.common.NullProgressMonitor;
53
import eu.etaxonomy.cdm.database.CdmPersistentDataSource;
54
import eu.etaxonomy.cdm.database.DbSchemaValidation;
55
import eu.etaxonomy.cdm.database.ICdmDataSource;
56
import eu.etaxonomy.cdm.model.common.CdmBase;
57
import eu.etaxonomy.cdm.model.common.CdmMetaData;
58
import eu.etaxonomy.cdm.model.common.DefinedTermBase;
59
import eu.etaxonomy.cdm.model.common.User;
60

    
61

    
62
/**
63
 * @author a.mueller
64
 *
65
 */
66
public class CdmApplicationController implements ICdmApplicationConfiguration{
67
	private static final Logger logger = Logger.getLogger(CdmApplicationController.class);
68
	
69
	public static final String DEFAULT_APPLICATION_CONTEXT_RESOURCE = "/eu/etaxonomy/cdm/defaultApplicationContext.xml";
70
	
71
	public AbstractApplicationContext applicationContext;
72
	private ICdmApplicationConfiguration configuration; 
73
	private Resource applicationContextResource;
74

    
75
	private IProgressMonitor progressMonitor;
76
	
77
	final static DbSchemaValidation defaultDbSchemaValidation = DbSchemaValidation.VALIDATE;
78
	
79
	
80
	
81
	/**
82
	 * Constructor, opens a spring ApplicationContext by using the default data source
83
	 */
84
	public static CdmApplicationController NewInstance() {
85
		logger.info("Start CdmApplicationController with default data source");
86
		CdmPersistentDataSource dataSource = CdmPersistentDataSource.NewDefaultInstance();
87
		DbSchemaValidation dbSchemaValidation = defaultDbSchemaValidation;
88
		return CdmApplicationController.NewInstance(null, dataSource, dbSchemaValidation, false);
89
	}
90
	
91
	/**
92
	 * Constructor, opens a spring ApplicationContext by using the default data source
93
	 * @param dbSchemaValidation validation type for database schema
94
	 */
95
	public static CdmApplicationController NewInstance(DbSchemaValidation dbSchemaValidation) {
96
		logger.info("Start CdmApplicationController with default data source");
97
		CdmPersistentDataSource dataSource = CdmPersistentDataSource.NewDefaultInstance();
98
		return CdmApplicationController.NewInstance(null, dataSource, dbSchemaValidation, false);
99
	}
100

    
101
	
102
	/**
103
	 * Constructor, opens an spring ApplicationContext by using the according data source and the
104
	 * default database schema validation type
105
	 * @param dataSource
106
	 */
107
	public static CdmApplicationController NewInstance(ICdmDataSource dataSource) {
108
		return CdmApplicationController.NewInstance(null, dataSource, defaultDbSchemaValidation, false);
109
	}
110
	
111
	public static CdmApplicationController NewInstance(ICdmDataSource dataSource, DbSchemaValidation dbSchemaValidation) {
112
		return CdmApplicationController.NewInstance(null, dataSource, dbSchemaValidation, false);
113
	}
114

    
115
	public static CdmApplicationController NewInstance(ICdmDataSource dataSource, DbSchemaValidation dbSchemaValidation, boolean omitTermLoading) {
116
		return CdmApplicationController.NewInstance(null, dataSource, dbSchemaValidation, omitTermLoading);
117
	}
118
	
119
	public static CdmApplicationController NewInstance(Resource applicationContextResource, ICdmDataSource dataSource, DbSchemaValidation dbSchemaValidation, boolean omitTermLoading) {
120
		return CdmApplicationController.NewInstance(applicationContextResource, dataSource, dbSchemaValidation, omitTermLoading, null);
121
	}
122
	
123
	public static CdmApplicationController NewInstance(Resource applicationContextResource, ICdmDataSource dataSource, DbSchemaValidation dbSchemaValidation, boolean omitTermLoading, IProgressMonitor progressMonitor) {
124
		return new CdmApplicationController(applicationContextResource, dataSource, dbSchemaValidation, omitTermLoading, progressMonitor);
125
	}
126

    
127
	/**
128
	 * Constructor, opens an spring 2.5 ApplicationContext by using the according data source
129
	 * @param dataSource
130
	 * @param dbSchemaValidation
131
	 * @param omitTermLoading
132
	 */
133
	private CdmApplicationController(Resource applicationContextResource, ICdmDataSource dataSource, DbSchemaValidation dbSchemaValidation, boolean omitTermLoading, IProgressMonitor progressMonitor){
134
		logger.info("Start CdmApplicationController with datasource: " + dataSource.getName());
135
		
136
		if (dbSchemaValidation == null){
137
			dbSchemaValidation = defaultDbSchemaValidation;
138
		}
139
		
140
		this.applicationContextResource = applicationContextResource != null ? applicationContextResource : new ClassPathResource(DEFAULT_APPLICATION_CONTEXT_RESOURCE);
141
		this.progressMonitor = progressMonitor != null ? progressMonitor : new NullProgressMonitor();
142
		
143
		setNewDataSource(dataSource, dbSchemaValidation, omitTermLoading);
144
	}
145
		
146
	
147
	/**
148
	 * Sets the application context to a new spring ApplicationContext by using the according data source and initializes the Controller.
149
	 * @param dataSource
150
	 */
151
	private boolean setNewDataSource(ICdmDataSource dataSource, DbSchemaValidation dbSchemaValidation, boolean omitTermLoading){
152
		if (dbSchemaValidation == null){
153
			dbSchemaValidation = defaultDbSchemaValidation;
154
		}
155
		logger.info("Connecting to '" + dataSource.getName() + "'");
156
		progressMonitor.beginTask("Connecting to '" + dataSource.getName() + "'", 6);
157
		progressMonitor.worked(1);
158

    
159
		GenericApplicationContext applicationContext =  new GenericApplicationContext();
160
		
161
		BeanDefinition datasourceBean = dataSource.getDatasourceBean();
162
		datasourceBean.setAttribute("isLazy", false);
163
		progressMonitor.subTask("Registering datasource.");
164
		progressMonitor.worked(1);
165
		applicationContext.registerBeanDefinition("dataSource", datasourceBean);
166
		
167
		BeanDefinition hibernatePropBean= dataSource.getHibernatePropertiesBean(dbSchemaValidation);
168
		applicationContext.registerBeanDefinition("hibernateProperties", hibernatePropBean);
169
		
170
		XmlBeanDefinitionReader xmlReader = new XmlBeanDefinitionReader(applicationContext);
171
		progressMonitor.subTask("Registering resources.");
172
		progressMonitor.worked(1);
173
		xmlReader.loadBeanDefinitions(applicationContextResource);		 
174
		
175
		//omitTerms
176
		/*String initializerName = "persistentTermInitializer";
177
		BeanDefinition beanDef = applicationContext.getBeanDefinition(initializerName);
178
		MutablePropertyValues values = beanDef.getPropertyValues();
179
		values.addPropertyValue("omit", omitTermLoading);*/
180
		
181
		progressMonitor.subTask("Connecting. This might take a while ...");
182
		progressMonitor.worked(1);
183
		applicationContext.refresh();
184
		applicationContext.start();
185
		
186
		progressMonitor.subTask("Cleaning up.");
187
		progressMonitor.worked(1);
188
		setApplicationContext(applicationContext);
189
		
190
		//initialize user and metaData for new databases
191
		int userCount = getUserService().count(User.class);
192
		if (userCount == 0 ){
193
			progressMonitor.subTask("Creating Admin User");
194
			progressMonitor.worked(1);
195
			createAdminUser();
196
		}
197
		int metaDataCount = getCommonService().getCdmMetaData().size();
198
		if (metaDataCount == 0){
199
			progressMonitor.subTask("Creating Meta Data");
200
			progressMonitor.worked(1);
201
			createMetadata();
202
		}
203
		progressMonitor.done();
204
		return true;
205
	}
206

    
207
	private void createAdminUser(){
208
		User firstUser = User.NewInstance("admin", "0000");
209
		getUserService().save(firstUser);
210
		logger.info("Admin user created.");
211
	}
212
	
213
	private void createMetadata(){
214
		List<CdmMetaData> metaData = CdmMetaData.defaultMetaData();
215
		getCommonService().saveAllMetaData(metaData);
216
		logger.info("Metadata created.");
217
	}
218
	
219
	
220
	/**
221
	 * Tests if some DefinedTermsAreMissing.
222
	 * @return true, if at least one is missing, else false
223
	 */
224
	public boolean testDefinedTermsAreMissing(){
225
		UUID englishUuid = UUID.fromString("e9f8cdb7-6819-44e8-95d3-e2d0690c3523");
226
		DefinedTermBase<?> english = this.getTermService().getByUri(englishUuid.toString());
227
		if ( english == null || ! english.getUuid().equals(englishUuid)){
228
			return true;
229
		}else{
230
			return false;
231
		}
232
	}
233
	
234

    
235
	/**
236
	 * Changes the ApplicationContext to the new dataSource
237
	 * @param dataSource
238
	 */
239
	public boolean changeDataSource(ICdmDataSource dataSource){
240
		//logger.info("Change datasource to : " + dataSource);
241
		return setNewDataSource(dataSource, DbSchemaValidation.VALIDATE, false);
242
	}
243
	
244
	/**
245
	 * Changes the ApplicationContext to the new dataSource
246
	 * @param dataSource
247
	 * @param dbSchemaValidation
248
	 */
249
	public boolean changeDataSource(ICdmDataSource dataSource, DbSchemaValidation dbSchemaValidation){
250
		//logger.info("Change datasource to : " + dataSource);
251
		return setNewDataSource(dataSource, dbSchemaValidation, false);
252
	}
253
	
254
	/**
255
	 * Changes the ApplicationContext to the new dataSource
256
	 * @param dataSource
257
	 * @param dbSchemaValidation
258
	 * @param omitTermLoading
259
	 */
260
	public boolean changeDataSource(ICdmDataSource dataSource, DbSchemaValidation dbSchemaValidation, boolean omitTermLoading){
261
		logger.info("Change datasource to : " + dataSource);
262
		return setNewDataSource(dataSource, dbSchemaValidation, omitTermLoading);
263
	}
264
	
265
	/**
266
	 * Sets a new application Context.
267
	 * @param ac
268
	 */
269
	public void setApplicationContext(AbstractApplicationContext ac){
270
		closeApplicationContext(); //closes old application context if necessary
271
		applicationContext = ac;
272
		applicationContext.registerShutdownHook();
273
		init();
274
	}
275
	
276
	/* (non-Javadoc)
277
	 * @see java.lang.Object#finalize()
278
	 */
279
	public void finalize(){
280
		close();
281
	}
282
	
283
	/**
284
	 * closes the application
285
	 */
286
	public void close(){
287
		closeApplicationContext();
288
	}
289
	
290
	/**
291
	 * closes the application context
292
	 */
293
	private void closeApplicationContext(){
294
		if (applicationContext != null){
295
			logger.info("Close ApplicationContext");
296
			applicationContext.close();
297
		}
298
	}
299
	
300
	private void init(){
301
		logger.debug("Init " +  this.getClass().getName() + " ... ");
302
		if (logger.isDebugEnabled()){for (String beanName : applicationContext.getBeanDefinitionNames()){ logger.debug(beanName);}}
303
		//TODO delete next row (was just for testing)
304
		if (logger.isInfoEnabled()){
305
			logger.info("Registered Beans: ");
306
			progressMonitor.subTask("Registered Beans: ");
307
			String[] beanNames = applicationContext.getBeanDefinitionNames();
308
			for (String beanName : beanNames){
309
				logger.info(beanName);
310
				progressMonitor.subTask(beanName);
311
			}
312
		}
313
		configuration = (ICdmApplicationConfiguration)applicationContext.getBean("cdmApplicationDefaultConfiguration");
314
		getDatabaseService().setApplicationController(this);
315
	}
316
	
317

    
318
	
319
	/* ******  Services *********/
320
	public final INameService getNameService(){
321
		return configuration.getNameService();
322
	}
323

    
324
	public final ITaxonService getTaxonService(){
325
		return configuration.getTaxonService();
326
	}
327
	
328
	public final ITaxonTreeService getTaxonTreeService(){
329
		return configuration.getTaxonTreeService();
330
	}
331
	
332
	public final ITaxonNodeService getTaxonNodeService(){
333
		return configuration.getTaxonNodeService();
334
	}
335

    
336
	public final IReferenceService getReferenceService(){
337
		return configuration.getReferenceService();
338
	}
339
	
340
	public final IAgentService getAgentService(){
341
		return configuration.getAgentService();
342
	}
343
	
344
	public final IDatabaseService getDatabaseService(){
345
		return configuration.getDatabaseService();
346
	}
347
	
348
	public final ITermService getTermService(){
349
		return configuration.getTermService();
350
	}
351

    
352
	public final IDescriptionService getDescriptionService(){
353
		return configuration.getDescriptionService();
354
	}
355
	
356
	public final IOccurrenceService getOccurrenceService(){
357
		return configuration.getOccurrenceService();
358
	}
359

    
360
	public final IMediaService getMediaService(){
361
		return configuration.getMediaService();
362
	}
363

    
364
	public final ICommonService getCommonService(){
365
		return configuration.getCommonService();
366
	}
367
	
368
	public final ILocationService getLocationService(){
369
		return configuration.getLocationService();
370
	}
371
	
372
	public final IUserService getUserService(){
373
		return configuration.getUserService();
374
	}
375
	
376
	public final ICollectionService getCollectionService(){
377
		return configuration.getCollectionService();
378
	}
379
	
380
	public final IFeatureTreeService getFeatureTreeService(){
381
		return configuration.getFeatureTreeService();
382
	}
383
	
384
	public final IFeatureNodeService getFeatureNodeService(){
385
		return configuration.getFeatureNodeService();
386
	}
387
	
388
	public final IVocabularyService getVocabularyService(){
389
		return configuration.getVocabularyService();
390
	}	
391
	
392
	public final IService<CdmBase> getMainService(){
393
		return configuration.getMainService();
394
	}
395
	
396
	public final ConversationHolder NewConversation(){
397
		//return (ConversationHolder)applicationContext.getBean("conversationHolder");
398
		return configuration.NewConversation();
399
	}
400
	
401
	
402
	public final ProviderManager getAuthenticationManager(){
403
		return configuration.getAuthenticationManager();
404
	}
405
	
406

    
407
	@Override
408
	public final PlatformTransactionManager getTransactionManager() {
409
		return configuration.getTransactionManager();
410
	}
411
	
412
	public final Object getBean(String name){
413
		return this.applicationContext.getBean(name);
414
	}
415
	
416
	/*
417
	 * OLD TRANSACTION STUFF 
418
	 */
419
	
420
	/* **** flush ***********/
421
	public void flush() {
422
		SessionFactory sf = (SessionFactory)applicationContext.getBean("sessionFactory");
423
		sf.getCurrentSession().flush();
424
	}
425
	
426
	public SessionFactory getSessionFactory(){
427
		return (SessionFactory)applicationContext.getBean("sessionFactory");
428
	}
429
	
430
	public TransactionStatus startTransaction() {
431
		
432
		return startTransaction(false);
433
	}
434
	
435
	public TransactionStatus startTransaction(Boolean readOnly) {
436
		
437
		PlatformTransactionManager txManager = configuration.getTransactionManager();
438
		
439
		DefaultTransactionDefinition defaultTxDef = new DefaultTransactionDefinition();
440
		defaultTxDef.setReadOnly(readOnly);
441
		TransactionDefinition txDef = defaultTxDef;
442

    
443
		// Log some transaction-related debug information.
444
		if (logger.isDebugEnabled()) {
445
			logger.debug("Transaction name = " + txDef.getName());
446
			logger.debug("Transaction facets:");
447
			logger.debug("Propagation behavior = " + txDef.getPropagationBehavior());
448
			logger.debug("Isolation level = " + txDef.getIsolationLevel());
449
			logger.debug("Timeout = " + txDef.getTimeout());
450
			logger.debug("Read Only = " + txDef.isReadOnly());
451
			// org.springframework.orm.hibernate3.HibernateTransactionManager
452
			// provides more transaction/session-related debug information.
453
		}
454
		
455
		TransactionStatus txStatus = txManager.getTransaction(txDef);
456
		return txStatus;
457
	}
458

    
459
	public void commitTransaction(TransactionStatus txStatus){
460
		PlatformTransactionManager txManager = configuration.getTransactionManager();
461
		txManager.commit(txStatus);
462
		return;
463
	}
464

    
465
}
(1-1/3)