Project

General

Profile

Download (6.29 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.cdm.database;
11

    
12
import java.util.HashMap;
13
import java.util.Map;
14
import java.util.UUID;
15

    
16
import javax.annotation.PostConstruct;
17

    
18
import org.apache.log4j.Logger;
19
import org.hibernate.Hibernate;
20
import org.springframework.beans.factory.annotation.Autowired;
21
import org.springframework.stereotype.Component;
22
import org.springframework.transaction.PlatformTransactionManager;
23
import org.springframework.transaction.TransactionDefinition;
24
import org.springframework.transaction.TransactionStatus;
25
import org.springframework.transaction.support.DefaultTransactionDefinition;
26

    
27
import eu.etaxonomy.cdm.model.common.DefaultTermInitializer;
28
import eu.etaxonomy.cdm.model.common.DefinedTermBase;
29
import eu.etaxonomy.cdm.model.common.TermVocabulary;
30
import eu.etaxonomy.cdm.model.common.init.IVocabularyStore;
31
import eu.etaxonomy.cdm.model.common.init.TermLoader;
32
import eu.etaxonomy.cdm.persistence.dao.common.IDefinedTermDao;
33
import eu.etaxonomy.cdm.persistence.dao.common.ITermVocabularyDao;
34

    
35
/**
36
 * Spring bean class to initialize the {@link IVocabularyStore IVocabularyStore}.
37
 * To initialize the store the {@link TermLoader TermLoader} and the {@link IVocabularyStore IVocabularyStore}
38
 * are injected via spring and the initializeTerms method is called as an init-method (@PostConstruct). 
39

    
40
 * @author a.mueller
41
 */
42

    
43
@Component
44
public class PersistentTermInitializer extends DefaultTermInitializer {
45
	private static final Logger logger = Logger.getLogger(PersistentTermInitializer.class);
46
	
47
	private boolean omit = false;
48
	protected ITermVocabularyDao vocabularyDao;
49

    
50
	protected PlatformTransactionManager transactionManager;
51
	protected DefaultTransactionDefinition txDefinition = new DefaultTransactionDefinition();
52
	
53
	public PersistentTermInitializer() {
54
		txDefinition.setName("PersistentTermInitializer.initialize()");
55
		txDefinition.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
56
	}
57
	
58
	public void setOmit(boolean omit) {
59
		this.omit = omit;
60
	}
61
	
62
	@Autowired
63
	public void setVocabularyDao(ITermVocabularyDao vocabularyDao) {
64
		this.vocabularyDao = vocabularyDao;
65
	}
66
	
67
	@Autowired
68
	public void setTransactionManager(PlatformTransactionManager transactionManager) {
69
		this.transactionManager = transactionManager;
70
	}
71
	
72
	/*
73
	 * After a bit of head-scratching I found section 3.5.1.3. in the current spring 
74
	 * reference manual - @PostConstruct / afterPropertiesSet() is called 
75
	 * immediatly after the bean is constructed, prior to any AOP interceptors being 
76
	 * wrapped round the bean. Thus, we have to use programmatic transactions, not 
77
	 * annotations or pointcuts.
78
	 */
79
	@PostConstruct
80
	@Override
81
	public void initialize(){
82
		logger.debug("PersistentTermInitializer initialize start ...");
83
		if (omit){
84
			logger.info("PersistentTermInitializer.omit == true, returning without initializing terms");
85
			return;
86
		} else {
87
			Map<UUID,DefinedTermBase> terms = new HashMap<UUID,DefinedTermBase>();
88
			logger.info("PersistentTermInitializer.omit == false, initializing " + terms.size() + " term classes");
89
			for(Class clazz : classesToInitialize) {
90
				UUID vocabularyUuid = firstPass(clazz,terms);
91
				secondPass(clazz,vocabularyUuid,terms);
92
			}
93
			
94
		}
95
		logger.debug("PersistentTermInitializer initialize end ...");
96
	}	
97
	
98
	protected void secondPass(Class clazz, UUID vocabularyUuid,Map<UUID,DefinedTermBase> terms) {
99
		TransactionStatus txStatus = transactionManager.getTransaction(txDefinition);
100
		
101
		TermVocabulary persistedVocabulary = vocabularyDao.findByUuid(vocabularyUuid);
102
		
103
		for(Object obj : persistedVocabulary.getTerms()) {
104
			DefinedTermBase d = (DefinedTermBase)obj;
105
			Hibernate.initialize(d.getRepresentations());
106
			terms.put(d.getUuid(), d);			
107
		}
108
		
109
		logger.debug("Setting defined Terms for class " + clazz.getSimpleName());
110
		super.setDefinedTerms(clazz, persistedVocabulary);
111

    
112
		transactionManager.commit(txStatus);
113
	}
114
 
115
	/**
116
	 * T
117
	 * @param clazz
118
	 * @param persistedTerms
119
	 * @return
120
	 */
121
	public UUID firstPass(Class clazz, Map<UUID, DefinedTermBase> persistedTerms) {
122
		TransactionStatus txStatus = transactionManager.getTransaction(txDefinition);
123
		logger.debug("loading terms for " + clazz.getSimpleName());
124
		Map<UUID,DefinedTermBase> terms = new HashMap<UUID,DefinedTermBase>();
125
		
126
		for(DefinedTermBase d : persistedTerms.values()) {
127
			terms.put(d.getUuid(), d);
128
		}
129

    
130
		TermVocabulary loadedVocabulary  = termLoader.loadTerms((Class<? extends DefinedTermBase>)clazz, terms);
131
		
132
		UUID vocabularyUuid = loadedVocabulary.getUuid();
133
		
134
		logger.debug("loading vocabulary " + vocabularyUuid);
135
		TermVocabulary persistedVocabulary = vocabularyDao.findByUuid(vocabularyUuid);
136
		if(persistedVocabulary == null) { // i.e. there is no persisted vocabulary
137
			logger.debug("vocabulary " + vocabularyUuid + " does not exist - saving");
138
			saveVocabulary(loadedVocabulary);
139
		} else {
140
			logger.debug("vocabulary " + vocabularyUuid + " does exist and already has " + persistedVocabulary.size() + " terms");
141
		    boolean persistedVocabularyHasMissingTerms = false;
142
		    for(Object t : loadedVocabulary.getTerms()) {				
143
		    	if(!persistedVocabulary.getTerms().contains(t)) {
144
		    		persistedVocabularyHasMissingTerms = true;
145
		    		persistedVocabulary.addTerm((DefinedTermBase)t);
146
		    	}
147
		    }				    
148
		    if(persistedVocabularyHasMissingTerms) {
149
		    	logger.debug("vocabulary " + vocabularyUuid + " exists but does not have all the required terms - updating");
150
		    	updateVocabulary(persistedVocabulary);
151
		    }
152
		}
153
		transactionManager.commit(txStatus);
154
		return vocabularyUuid;
155
	}
156

    
157
	private void updateVocabulary(TermVocabulary vocabulary) {
158
		TransactionStatus txStatus = transactionManager.getTransaction(txDefinition);
159
		vocabularyDao.update(vocabulary);
160
		transactionManager.commit(txStatus);		
161
	}
162

    
163
	private void saveVocabulary(TermVocabulary vocabulary) {
164
		TransactionStatus txStatus = transactionManager.getTransaction(txDefinition);
165
		vocabularyDao.save(vocabulary);
166
		transactionManager.commit(txStatus);
167
	}
168
}
(13-13/14)