Remove GenBankAccession class, Spatium for EN_DASH and some minor stuff for v3.3
[cdmlib.git] / cdmlib-persistence / src / main / java / eu / etaxonomy / cdm / database / PersistentTermInitializer.java
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.List;
14 import java.util.Map;
15 import java.util.UUID;
16
17 import javax.annotation.PostConstruct;
18
19 import org.apache.log4j.Logger;
20 import org.hibernate.Hibernate;
21 import org.springframework.beans.factory.annotation.Autowired;
22 import org.springframework.stereotype.Component;
23 import org.springframework.transaction.PlatformTransactionManager;
24 import org.springframework.transaction.TransactionDefinition;
25 import org.springframework.transaction.TransactionStatus;
26 import org.springframework.transaction.support.DefaultTransactionDefinition;
27
28 import eu.etaxonomy.cdm.model.common.DefaultTermInitializer;
29 import eu.etaxonomy.cdm.model.common.DefinedTermBase;
30 import eu.etaxonomy.cdm.model.common.Representation;
31 import eu.etaxonomy.cdm.model.common.TermVocabulary;
32 import eu.etaxonomy.cdm.model.common.VocabularyEnum;
33 import eu.etaxonomy.cdm.model.common.init.TermLoader;
34 import eu.etaxonomy.cdm.persistence.dao.common.ITermVocabularyDao;
35
36 /**
37 * Spring bean class to initialize the {@link IVocabularyStore IVocabularyStore}.
38 * To initialize the store the {@link TermLoader TermLoader} and the {@link IVocabularyStore IVocabularyStore}
39 * are injected via spring and the initializeTerms method is called as an init-method (@PostConstruct).
40
41 * @author a.mueller
42 */
43
44 @Component
45 public class PersistentTermInitializer extends DefaultTermInitializer {
46 private static final Logger logger = Logger.getLogger(PersistentTermInitializer.class);
47
48 private boolean omit = false;
49 protected ITermVocabularyDao vocabularyDao;
50
51 protected PlatformTransactionManager transactionManager;
52 protected DefaultTransactionDefinition txDefinition = new DefaultTransactionDefinition();
53
54 public PersistentTermInitializer() {
55 txDefinition.setName("PersistentTermInitializer.initialize()");
56 txDefinition.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
57 }
58
59 public void setOmit(boolean omit) {
60 this.omit = omit;
61 }
62
63 public boolean isOmit() {
64 return omit;
65 }
66
67
68 @Autowired
69 public void setVocabularyDao(ITermVocabularyDao vocabularyDao) {
70 this.vocabularyDao = vocabularyDao;
71 }
72
73 @Autowired
74 public void setTransactionManager(PlatformTransactionManager transactionManager) {
75 this.transactionManager = transactionManager;
76 }
77
78 /*
79 * After a bit of head-scratching I found section 3.5.1.3. in the current spring
80 * reference manual - @PostConstruct / afterPropertiesSet() is called
81 * immediatly after the bean is constructed, prior to any AOP interceptors being
82 * wrapped round the bean. Thus, we have to use programmatic transactions, not
83 * annotations or pointcuts.
84 */
85 @PostConstruct
86 @Override
87 public void initialize() {
88 super.initialize();
89 }
90
91
92 @Override
93 public void doInitialize(){
94 logger.info("PersistentTermInitializer initialize start ...");
95
96 // //only for testing - remove
97 // TransactionStatus txStatus2 = transactionManager.getTransaction(txDefinition);
98 // int i = vocabularyDao.count();
99 // List<TermVocabulary> list = vocabularyDao.list(null, null);
100 // for (TermVocabulary voc : list){
101 // System.out.println(voc.getUuid());
102 // }
103 // transactionManager.commit(txStatus2);
104 // // end testing
105
106 if (omit){
107 logger.info("PersistentTermInitializer.omit == true, returning without initializing terms");
108 return;
109 } else {
110 Map<UUID,DefinedTermBase> terms = new HashMap<UUID,DefinedTermBase>();
111 logger.info("PersistentTermInitializer.omit == false, initializing " + VocabularyEnum.values().length + " term classes");
112
113 TransactionStatus txStatus = transactionManager.getTransaction(txDefinition);
114 for(VocabularyEnum vocabularyType : VocabularyEnum.values()) {
115 //Class<? extends DefinedTermBase<?>> clazz = vocabularyType.getClazz();
116 UUID vocabularyUuid = firstPass(vocabularyType,terms);
117 secondPass(vocabularyType.getClazz(),vocabularyUuid,terms);
118 }
119 transactionManager.commit(txStatus);
120 }
121 logger.info("PersistentTermInitializer initialize end ...");
122 }
123
124 /**
125 * Initializes the static fields of the <code>TermVocabulary</code> classes.
126 *
127 * @param clazz the <code>Class</code> of the vocabulary
128 * @param vocabularyUuid the <code>UUID</code> of the vocabulary
129 * @param terms a <code>Map</code> containing all already
130 * loaded terms with their <code>UUID</code> as key
131 */
132 protected void secondPass(Class clazz, UUID vocabularyUuid, Map<UUID,DefinedTermBase> terms) {
133 logger.debug("Initializing vocabulary for class " + clazz.getSimpleName() + " with uuid " + vocabularyUuid );
134
135 TermVocabulary<?> persistedVocabulary = vocabularyDao.findByUuid(vocabularyUuid);
136
137 if (persistedVocabulary != null){
138 for(Object object : persistedVocabulary.getTerms()) {
139 DefinedTermBase<?> definedTermBase = (DefinedTermBase) object;
140 Hibernate.initialize(definedTermBase.getRepresentations());
141 for(Representation r : definedTermBase.getRepresentations()) {
142 Hibernate.initialize(r.getLanguage());
143 }
144 terms.put(definedTermBase.getUuid(), definedTermBase);
145 }
146 }else{
147 logger.error("Persisted Vocabulary does not exist in database: " + vocabularyUuid);
148 throw new NullPointerException("Persisted Vocabulary does not exist in database: " + vocabularyUuid);
149 }
150 logger.debug("Setting defined Terms for class " + clazz.getSimpleName() + ", " + persistedVocabulary.getTerms().size() + " in vocabulary");
151 super.setDefinedTerms(clazz, persistedVocabulary);
152 }
153
154 /**
155 * This method loads the vocabularies from CSV files and compares them to the vocabularies
156 * already in database. Non-existing vocabularies will be created and vocabularies with missing
157 * terms will be updated.
158 *
159 * @param clazz the <code>Class</code> of the vocabulary
160 * @param persistedTerms a <code>Map</code> containing all already
161 * loaded terms with their <code>UUID</code> as key
162 * @return the <code>UUID</code> of the loaded vocabulary as found in CSV file
163 */
164 public UUID firstPass(VocabularyEnum vocabularyType, Map<UUID, DefinedTermBase> persistedTerms) {
165 logger.info("Loading terms for '" + vocabularyType.name() + "': " + vocabularyType.getClazz().getName());
166 Map<UUID,DefinedTermBase> terms = new HashMap<UUID,DefinedTermBase>();
167
168 for(DefinedTermBase d : persistedTerms.values()) {
169 terms.put(d.getUuid(), d);
170 }
171
172 TermVocabulary<?> loadedVocabulary = termLoader.loadTerms(vocabularyType, terms);
173
174 UUID vocabularyUuid = loadedVocabulary.getUuid();
175
176
177 logger.debug("loading vocabulary " + vocabularyUuid);
178 TermVocabulary<DefinedTermBase> persistedVocabulary = vocabularyDao.findByUuid(vocabularyUuid);
179 if(persistedVocabulary == null) { // i.e. there is no persisted vocabulary
180 logger.debug("vocabulary " + vocabularyUuid + " does not exist - saving");
181 saveVocabulary(loadedVocabulary);
182 }else {
183 logger.debug("vocabulary " + vocabularyUuid + " does exist and already has " + persistedVocabulary.size() + " terms");
184 boolean persistedVocabularyHasMissingTerms = false;
185 for(Object t : loadedVocabulary.getTerms()) {
186 if(!persistedVocabulary.getTerms().contains(t)) {
187 persistedVocabularyHasMissingTerms = true;
188 persistedVocabulary.addTerm((DefinedTermBase)t);
189 }
190 }
191 if(persistedVocabularyHasMissingTerms) {
192 logger.debug("vocabulary " + vocabularyUuid + " exists but does not have all the required terms - updating");
193 updateVocabulary(persistedVocabulary);
194 }
195 }
196 return vocabularyUuid;
197 }
198
199 private void updateVocabulary(TermVocabulary vocabulary) {
200 TransactionStatus txStatus = transactionManager.getTransaction(txDefinition);
201 vocabularyDao.update(vocabulary);
202 transactionManager.commit(txStatus);
203 }
204
205 private void saveVocabulary(TermVocabulary vocabulary) {
206 TransactionStatus txStatus = transactionManager.getTransaction(txDefinition);
207 vocabularyDao.save(vocabulary);
208 transactionManager.commit(txStatus);
209 }
210 }