Project

General

Profile

Download (7.6 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.Representation;
30
import eu.etaxonomy.cdm.model.common.TermVocabulary;
31
import eu.etaxonomy.cdm.model.common.VocabularyEnum;
32
import eu.etaxonomy.cdm.model.common.init.TermLoader;
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 doInitialize(){
82
		logger.info("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 " + VocabularyEnum.values().length + " term classes");
89
			
90
			TransactionStatus txStatus = transactionManager.getTransaction(txDefinition);
91
			for(VocabularyEnum vocabularyType : VocabularyEnum.values()) {
92
				//Class<? extends DefinedTermBase<?>> clazz = vocabularyType.getClazz();
93
				UUID vocabularyUuid = firstPass(vocabularyType,terms);
94
				secondPass(vocabularyType.getClazz(),vocabularyUuid,terms);
95
			}
96
			transactionManager.commit(txStatus);
97
		}
98
		logger.info("PersistentTermInitializer initialize end ...");
99
	}	
100
	
101
	/**
102
	 * Initializes the static fields of the <code>TermVocabulary</code> classes.
103
	 * 
104
	 * @param clazz the <code>Class</code> of the vocabulary
105
	 * @param vocabularyUuid the <code>UUID</code> of the vocabulary
106
	 * @param terms a <code>Map</code> containing all already 
107
	 * 						 loaded terms with their <code>UUID</code> as key
108
	 */
109
	protected void secondPass(Class clazz, UUID vocabularyUuid, Map<UUID,DefinedTermBase> terms) {
110
		logger.debug("Initializing vocabulary for class " + clazz.getSimpleName() + " with uuid " + vocabularyUuid );
111
		
112
		TermVocabulary persistedVocabulary = vocabularyDao.findByUuid(vocabularyUuid);
113
		
114
		if (persistedVocabulary != null){
115
			for(Object object : persistedVocabulary.getTerms()) {
116
				DefinedTermBase definedTermBase = (DefinedTermBase) object;
117
				Hibernate.initialize(definedTermBase.getRepresentations());
118
				for(Representation r : definedTermBase.getRepresentations()) {
119
					Hibernate.initialize(r.getLanguage());
120
				}
121
				terms.put(definedTermBase.getUuid(), definedTermBase);			
122
			}
123
		}else{
124
			logger.error("Persisted Vocabulary does not exist in database: " + vocabularyUuid);
125
			throw new NullPointerException("Persisted Vocabulary does not exist in database: " + vocabularyUuid);
126
		}
127
		logger.debug("Setting defined Terms for class " + clazz.getSimpleName());
128
		super.setDefinedTerms(clazz, persistedVocabulary);
129
	}
130
 
131
	/**
132
	 * This method loads the vocabularies from CSV files and compares them to the vocabularies
133
	 * already in database. Non-existing vocabularies will be created and vocabularies with missing 
134
	 * terms will be updated.
135
	 * 
136
	 * @param clazz the <code>Class</code> of the vocabulary
137
	 * @param persistedTerms a <code>Map</code> containing all already 
138
	 * 						 loaded terms with their <code>UUID</code> as key
139
	 * @return the <code>UUID</code> of the loaded vocabulary as found in CSV file
140
	 */
141
	public UUID firstPass(VocabularyEnum vocabularyType, Map<UUID, DefinedTermBase> persistedTerms) {
142
		logger.info("Loading terms for " + vocabularyType.getClazz().getSimpleName());
143
		Map<UUID,DefinedTermBase> terms = new HashMap<UUID,DefinedTermBase>();
144
		
145
		for(DefinedTermBase d : persistedTerms.values()) {
146
			terms.put(d.getUuid(), d);
147
		}
148

    
149
		TermVocabulary loadedVocabulary  = termLoader.loadTerms(vocabularyType, terms);
150

    
151
		UUID vocabularyUuid = loadedVocabulary.getUuid();
152
		
153
		
154
		logger.debug("loading vocabulary " + vocabularyUuid);
155
		TermVocabulary persistedVocabulary = vocabularyDao.findByUuid(vocabularyUuid);
156
		if(persistedVocabulary == null) { // i.e. there is no persisted vocabulary
157
			logger.debug("vocabulary " + vocabularyUuid + " does not exist - saving");
158
			saveVocabulary(loadedVocabulary);
159
		}else {
160
			logger.debug("vocabulary " + vocabularyUuid + " does exist and already has " + persistedVocabulary.size() + " terms");
161
		    boolean persistedVocabularyHasMissingTerms = false;
162
		    for(Object t : loadedVocabulary.getTerms()) {				
163
		    	if(!persistedVocabulary.getTerms().contains(t)) {
164
		    		persistedVocabularyHasMissingTerms = true;
165
		    		persistedVocabulary.addTerm((DefinedTermBase)t);
166
		    	}
167
		    }				    
168
		    if(persistedVocabularyHasMissingTerms) {
169
		    	logger.debug("vocabulary " + vocabularyUuid + " exists but does not have all the required terms - updating");
170
		    	updateVocabulary(persistedVocabulary);
171
		    }
172
		}
173
		return vocabularyUuid;
174
	}
175

    
176
	private void updateVocabulary(TermVocabulary vocabulary) {
177
		TransactionStatus txStatus = transactionManager.getTransaction(txDefinition);
178
		vocabularyDao.update(vocabulary);
179
		transactionManager.commit(txStatus);		
180
	}
181

    
182
	private void saveVocabulary(TermVocabulary vocabulary) {
183
		TransactionStatus txStatus = transactionManager.getTransaction(txDefinition);
184
		vocabularyDao.save(vocabulary);
185
		transactionManager.commit(txStatus);
186
	}
187
}
(17-17/18)