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
.TermVocabulary
;
30 import eu
.etaxonomy
.cdm
.model
.common
.init
.TermLoader
;
31 import eu
.etaxonomy
.cdm
.persistence
.dao
.common
.IDefinedTermDao
;
32 import eu
.etaxonomy
.cdm
.persistence
.dao
.common
.ITermVocabularyDao
;
35 * Spring bean class to initialize the {@link IVocabularyStore IVocabularyStore}.
36 * To initialize the store the {@link TermLoader TermLoader} and the {@link IVocabularyStore IVocabularyStore}
37 * are injected via spring and the initializeTerms method is called as an init-method (@PostConstruct).
43 public class PersistentTermInitializer
extends DefaultTermInitializer
{
44 private static final Logger logger
= Logger
.getLogger(PersistentTermInitializer
.class);
46 private boolean omit
= false;
47 protected ITermVocabularyDao vocabularyDao
;
49 protected PlatformTransactionManager transactionManager
;
50 protected DefaultTransactionDefinition txDefinition
= new DefaultTransactionDefinition();
52 public PersistentTermInitializer() {
53 txDefinition
.setName("PersistentTermInitializer.initialize()");
54 txDefinition
.setPropagationBehavior(TransactionDefinition
.PROPAGATION_REQUIRED
);
57 public void setOmit(boolean omit
) {
62 public void setVocabularyDao(ITermVocabularyDao vocabularyDao
) {
63 this.vocabularyDao
= vocabularyDao
;
67 public void setTransactionManager(PlatformTransactionManager transactionManager
) {
68 this.transactionManager
= transactionManager
;
72 * After a bit of head-scratching I found section 3.5.1.3. in the current spring
73 * reference manual - @PostConstruct / afterPropertiesSet() is called
74 * immediatly after the bean is constructed, prior to any AOP interceptors being
75 * wrapped round the bean. Thus, we have to use programmatic transactions, not
76 * annotations or pointcuts.
80 public void initialize(){
81 logger
.debug("PersistentTermInitializer initialize start ...");
83 logger
.info("PersistentTermInitializer.omit == true, returning without initializing terms");
86 Map
<UUID
,DefinedTermBase
> terms
= new HashMap
<UUID
,DefinedTermBase
>();
87 logger
.info("PersistentTermInitializer.omit == false, initializing " + classesToInitialize
.length
+ " term classes");
88 for(Class clazz
: classesToInitialize
) {
89 UUID vocabularyUuid
= firstPass(clazz
,terms
);
90 secondPass(clazz
,vocabularyUuid
,terms
);
94 logger
.debug("PersistentTermInitializer initialize end ...");
97 protected void secondPass(Class clazz
, UUID vocabularyUuid
,Map
<UUID
,DefinedTermBase
> terms
) {
98 TransactionStatus txStatus
= transactionManager
.getTransaction(txDefinition
);
99 logger
.info("Loading vocabulary for class " + clazz
.getSimpleName() + " with uuid " + vocabularyUuid
);
101 TermVocabulary persistedVocabulary
= vocabularyDao
.findByUuid(vocabularyUuid
);
103 for(Object obj
: persistedVocabulary
.getTerms()) {
104 DefinedTermBase d
= (DefinedTermBase
)obj
;
105 Hibernate
.initialize(d
.getRepresentations());
106 terms
.put(d
.getUuid(), d
);
109 logger
.debug("Setting defined Terms for class " + clazz
.getSimpleName());
110 super.setDefinedTerms(clazz
, persistedVocabulary
);
112 transactionManager
.commit(txStatus
);
118 * @param persistedTerms
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
>();
126 for(DefinedTermBase d
: persistedTerms
.values()) {
127 terms
.put(d
.getUuid(), d
);
130 TermVocabulary loadedVocabulary
= termLoader
.loadTerms((Class
<?
extends DefinedTermBase
>)clazz
, terms
);
132 UUID vocabularyUuid
= loadedVocabulary
.getUuid();
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
);
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
);
148 if(persistedVocabularyHasMissingTerms
) {
149 logger
.debug("vocabulary " + vocabularyUuid
+ " exists but does not have all the required terms - updating");
150 updateVocabulary(persistedVocabulary
);
153 transactionManager
.commit(txStatus
);
154 return vocabularyUuid
;
157 private void updateVocabulary(TermVocabulary vocabulary
) {
158 TransactionStatus txStatus
= transactionManager
.getTransaction(txDefinition
);
159 vocabularyDao
.update(vocabulary
);
160 transactionManager
.commit(txStatus
);
163 private void saveVocabulary(TermVocabulary vocabulary
) {
164 TransactionStatus txStatus
= transactionManager
.getTransaction(txDefinition
);
165 vocabularyDao
.save(vocabulary
);
166 transactionManager
.commit(txStatus
);