2 * Copyright (C) 2007 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
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.
10 package eu
.etaxonomy
.cdm
.database
;
12 import java
.util
.HashMap
;
14 import java
.util
.UUID
;
16 import javax
.annotation
.PostConstruct
;
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
;
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
;
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).
44 public class PersistentTermInitializer
extends DefaultTermInitializer
{
45 private static final Logger logger
= Logger
.getLogger(PersistentTermInitializer
.class);
47 private boolean omit
= false;
48 protected ITermVocabularyDao vocabularyDao
;
50 protected PlatformTransactionManager transactionManager
;
51 protected DefaultTransactionDefinition txDefinition
= new DefaultTransactionDefinition();
53 public PersistentTermInitializer() {
54 txDefinition
.setName("PersistentTermInitializer.initialize()");
55 txDefinition
.setPropagationBehavior(TransactionDefinition
.PROPAGATION_REQUIRED
);
58 public void setOmit(boolean omit
) {
63 public void setVocabularyDao(ITermVocabularyDao vocabularyDao
) {
64 this.vocabularyDao
= vocabularyDao
;
68 public void setTransactionManager(PlatformTransactionManager transactionManager
) {
69 this.transactionManager
= transactionManager
;
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.
81 public void doInitialize(){
82 logger
.debug("PersistentTermInitializer initialize start ...");
84 logger
.info("PersistentTermInitializer.omit == true, returning without initializing terms");
87 Map
<UUID
,DefinedTermBase
> terms
= new HashMap
<UUID
,DefinedTermBase
>();
88 logger
.info("PersistentTermInitializer.omit == false, initializing " + VocabularyEnum
.values().length
+ " term classes");
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
);
96 transactionManager
.commit(txStatus
);
98 logger
.debug("PersistentTermInitializer initialize end ...");
102 * Initializes the static fields of the <code>TermVocabulary</code> classes.
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
109 protected void secondPass(Class clazz
, UUID vocabularyUuid
, Map
<UUID
,DefinedTermBase
> terms
) {
110 logger
.debug("Initializing vocabulary for class " + clazz
.getSimpleName() + " with uuid " + vocabularyUuid
);
112 TermVocabulary persistedVocabulary
= vocabularyDao
.findByUuid(vocabularyUuid
);
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());
121 terms
.put(definedTermBase
.getUuid(), definedTermBase
);
124 logger
.error("Persisted Vocabulary does not exist in database: " + vocabularyUuid
);
125 throw new NullPointerException("Persisted Vocabulary does not exist in database: " + vocabularyUuid
);
127 logger
.debug("Setting defined Terms for class " + clazz
.getSimpleName());
128 super.setDefinedTerms(clazz
, persistedVocabulary
);
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.
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
141 public UUID
firstPass(VocabularyEnum vocabularyType
, Map
<UUID
, DefinedTermBase
> persistedTerms
) {
142 logger
.debug("loading terms for " + vocabularyType
.getClazz().getSimpleName());
143 Map
<UUID
,DefinedTermBase
> terms
= new HashMap
<UUID
,DefinedTermBase
>();
145 for(DefinedTermBase d
: persistedTerms
.values()) {
146 terms
.put(d
.getUuid(), d
);
149 TermVocabulary loadedVocabulary
= termLoader
.loadTerms(vocabularyType
, terms
);
151 UUID vocabularyUuid
= loadedVocabulary
.getUuid();
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
);
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
);
168 if(persistedVocabularyHasMissingTerms
) {
169 logger
.debug("vocabulary " + vocabularyUuid
+ " exists but does not have all the required terms - updating");
170 updateVocabulary(persistedVocabulary
);
173 return vocabularyUuid
;
176 private void updateVocabulary(TermVocabulary vocabulary
) {
177 TransactionStatus txStatus
= transactionManager
.getTransaction(txDefinition
);
178 vocabularyDao
.update(vocabulary
);
179 transactionManager
.commit(txStatus
);
182 private void saveVocabulary(TermVocabulary vocabulary
) {
183 TransactionStatus txStatus
= transactionManager
.getTransaction(txDefinition
);
184 vocabularyDao
.save(vocabulary
);
185 transactionManager
.commit(txStatus
);