/**\r
* Copyright (C) 2007 EDIT\r
-* European Distributed Institute of Taxonomy \r
+* European Distributed Institute of Taxonomy\r
* http://www.e-taxonomy.eu\r
-* \r
+*\r
* The contents of this file are subject to the Mozilla Public License Version 1.1\r
* See LICENSE.TXT at the top of this package for the full license terms.\r
*/\r
package eu.etaxonomy.cdm.database;\r
\r
import java.util.HashMap;\r
+import java.util.List;\r
import java.util.Map;\r
import java.util.UUID;\r
\r
import javax.annotation.PostConstruct;\r
\r
import org.apache.log4j.Logger;\r
+import org.hibernate.Hibernate;\r
import org.springframework.beans.factory.annotation.Autowired;\r
import org.springframework.stereotype.Component;\r
import org.springframework.transaction.PlatformTransactionManager;\r
import org.springframework.transaction.TransactionStatus;\r
import org.springframework.transaction.support.DefaultTransactionDefinition;\r
\r
-import eu.etaxonomy.cdm.model.common.AnnotationType;\r
import eu.etaxonomy.cdm.model.common.DefaultTermInitializer;\r
import eu.etaxonomy.cdm.model.common.DefinedTermBase;\r
-import eu.etaxonomy.cdm.model.common.Language;\r
-import eu.etaxonomy.cdm.model.common.MarkerType;\r
+import eu.etaxonomy.cdm.model.common.Representation;\r
import eu.etaxonomy.cdm.model.common.TermVocabulary;\r
-import eu.etaxonomy.cdm.model.common.WrongTermTypeException;\r
+import eu.etaxonomy.cdm.model.common.VocabularyEnum;\r
import eu.etaxonomy.cdm.model.common.init.TermLoader;\r
-import eu.etaxonomy.cdm.model.description.AbsenceTerm;\r
-import eu.etaxonomy.cdm.model.description.Feature;\r
-import eu.etaxonomy.cdm.model.description.PresenceTerm;\r
-import eu.etaxonomy.cdm.model.description.Sex;\r
-import eu.etaxonomy.cdm.model.description.StatisticalMeasure;\r
-import eu.etaxonomy.cdm.model.location.Continent;\r
-import eu.etaxonomy.cdm.model.location.NamedArea;\r
-import eu.etaxonomy.cdm.model.location.NamedAreaLevel;\r
-import eu.etaxonomy.cdm.model.location.NamedAreaType;\r
-import eu.etaxonomy.cdm.model.location.WaterbodyOrCountry;\r
-import eu.etaxonomy.cdm.model.media.RightsTerm;\r
-import eu.etaxonomy.cdm.model.name.HybridRelationshipType;\r
-import eu.etaxonomy.cdm.model.name.NameRelationshipType;\r
-import eu.etaxonomy.cdm.model.name.NomenclaturalCode;\r
-import eu.etaxonomy.cdm.model.name.NomenclaturalStatusType;\r
-import eu.etaxonomy.cdm.model.name.Rank;\r
-import eu.etaxonomy.cdm.model.name.TypeDesignationStatus;\r
-import eu.etaxonomy.cdm.model.occurrence.DerivationEventType;\r
-import eu.etaxonomy.cdm.model.occurrence.DeterminationModifier;\r
-import eu.etaxonomy.cdm.model.occurrence.PreservationMethod;\r
-import eu.etaxonomy.cdm.model.taxon.SynonymRelationshipType;\r
-import eu.etaxonomy.cdm.model.taxon.TaxonRelationshipType;\r
-import eu.etaxonomy.cdm.persistence.dao.common.IDefinedTermDao;\r
import eu.etaxonomy.cdm.persistence.dao.common.ITermVocabularyDao;\r
\r
/**\r
* Spring bean class to initialize the {@link IVocabularyStore IVocabularyStore}.\r
* To initialize the store the {@link TermLoader TermLoader} and the {@link IVocabularyStore IVocabularyStore}\r
- * are injected via spring and the initializeTerms method is called as an init-method (@PostConstruct). \r
+ * are injected via spring and the initializeTerms method is called as an init-method (@PostConstruct).\r
+\r
* @author a.mueller\r
*/\r
+\r
@Component\r
public class PersistentTermInitializer extends DefaultTermInitializer {\r
- private static final Logger logger = Logger.getLogger(PersistentTermInitializer.class);\r
- \r
- private boolean omit = false;\r
- private ITermVocabularyDao vocabularyDao;\r
- private IDefinedTermDao termDao;\r
- /**\r
- * After a bit of head-scratching I found section 3.5.1.3. in the current spring \r
- * reference manual - @PostConstruct / afterPropertiesSet() is called \r
- * immediatly after the bean is constructed, prior to any AOP interceptors being \r
- * wrapped round the bean. Thus, we have to use programmatic transactions, not \r
- * annotations or pointcuts.\r
- */\r
- private PlatformTransactionManager transactionManager;\r
- private DefaultTransactionDefinition txDefinition = new DefaultTransactionDefinition();\r
- \r
- public PersistentTermInitializer() {\r
- txDefinition.setName("PersistentTermInitializer.initialize()");\r
- txDefinition.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);\r
- }\r
- \r
- public void setOmit(boolean omit) {\r
- this.omit = omit;\r
- }\r
- \r
- @Autowired\r
- public void setVocabularyDao(ITermVocabularyDao vocabularyDao) {\r
- this.vocabularyDao = vocabularyDao;\r
- }\r
- \r
- @Autowired\r
- public void setTermDao(IDefinedTermDao termDao){\r
- this.termDao = termDao;\r
- }\r
- \r
- @Autowired\r
- public void setTransactionManager(PlatformTransactionManager transactionManager) {\r
- this.transactionManager = transactionManager;\r
- }\r
- \r
- @PostConstruct\r
- @Override\r
- public void initialize(){\r
- logger.debug("PersistentTermInitializer initialize()");\r
- if (omit){\r
- logger.info("PersistentTermInitializer.omit == true, returning without initializing terms");\r
- return;\r
- } else {\r
- Map<UUID,DefinedTermBase> terms = new HashMap<UUID,DefinedTermBase>();\r
- classesToInitialize = new Class[]{Language.class,Continent.class,WaterbodyOrCountry.class,\r
- Rank.class,TypeDesignationStatus.class,\r
- NomenclaturalStatusType.class,\r
- SynonymRelationshipType.class,\r
- HybridRelationshipType.class,\r
- NameRelationshipType.class,TaxonRelationshipType.class,\r
- MarkerType.class,\r
- AnnotationType.class,NamedAreaType.class,NamedAreaLevel.class,\r
- NomenclaturalCode.class,Feature.class,NamedArea.class,PresenceTerm.class,AbsenceTerm.class,Sex.class,\r
- DerivationEventType.class,PreservationMethod.class,DeterminationModifier.class,StatisticalMeasure.class,RightsTerm.class\r
- };\r
- logger.info("PersistentTermInitializer.omit == false, initializing " + terms.size() + " term classes");\r
- for(Class clazz : classesToInitialize) {\r
- UUID vocabularyUuid = firstPass(clazz,terms);\r
- secondPass(clazz,vocabularyUuid,terms);\r
- }\r
- \r
- }\r
- } \r
- \r
- private void secondPass(Class clazz, UUID vocabularyUuid,Map<UUID,DefinedTermBase> terms) {\r
- TransactionStatus txStatus = transactionManager.getTransaction(txDefinition);\r
- \r
- TermVocabulary persistedVocabulary = vocabularyDao.findByUuid(vocabularyUuid);\r
- for(Object obj : persistedVocabulary.getTerms()) {\r
- DefinedTermBase d = (DefinedTermBase)obj;\r
- terms.put(d.getUuid(), d);\r
- logger.debug("Setting defined Terms for class " + clazz.getSimpleName());\r
- super.setDefinedTerms(clazz, persistedVocabulary);\r
- }\r
-\r
- transactionManager.commit(txStatus);\r
- }\r
- \r
- /**\r
- * T\r
- * @param clazz\r
- * @param persistedTerms\r
- * @return\r
- */\r
- private UUID firstPass(Class clazz, Map<UUID, DefinedTermBase> persistedTerms) {\r
- TransactionStatus txStatus = transactionManager.getTransaction(txDefinition);\r
- logger.debug("loading terms for " + clazz.getSimpleName());\r
- Map<UUID,DefinedTermBase> terms = new HashMap<UUID,DefinedTermBase>();\r
- \r
- for(DefinedTermBase d : persistedTerms.values()) {\r
- terms.put(d.getUuid(), d);\r
- }\r
-\r
- TermVocabulary loadedVocabulary = termLoader.loadTerms((Class<? extends DefinedTermBase>)clazz, terms);\r
- UUID vocabularyUuid = loadedVocabulary.getUuid();\r
- \r
- logger.debug("loading vocabulary " + vocabularyUuid);\r
- TermVocabulary persistedVocabulary = vocabularyDao.findByUuid(vocabularyUuid);\r
- \r
- if(persistedVocabulary == null) { // i.e. there is no persisted vocabulary\r
- logger.debug("vocabulary " + vocabularyUuid + " does not exist - saving");\r
- saveVocabulary(loadedVocabulary);\r
- } else {\r
- logger.debug("vocabulary " + vocabularyUuid + " does exists and already has " + persistedVocabulary.size() + " terms");\r
- boolean persistedVocabularyHasMissingTerms = false;\r
- for(Object t : loadedVocabulary.getTerms()) { \r
- if(!persistedVocabulary.getTerms().contains(t)) {\r
- persistedVocabularyHasMissingTerms = true;\r
- persistedVocabulary.addTerm((DefinedTermBase)t);\r
- }\r
- } \r
- if(persistedVocabularyHasMissingTerms) {\r
- logger.debug("vocabulary " + vocabularyUuid + " exists but does not have all the required terms - updating");\r
- updateVocabulary(persistedVocabulary);\r
- }\r
- }\r
- transactionManager.commit(txStatus);\r
- return vocabularyUuid;\r
- }\r
-\r
- private void updateVocabulary(TermVocabulary vocabulary) {\r
- TransactionStatus txStatus = transactionManager.getTransaction(txDefinition);\r
- vocabularyDao.update(vocabulary); \r
- transactionManager.commit(txStatus); \r
- }\r
-\r
- private void saveVocabulary(TermVocabulary vocabulary) {\r
- TransactionStatus txStatus = transactionManager.getTransaction(txDefinition);\r
- vocabularyDao.save(vocabulary);\r
- transactionManager.commit(txStatus);\r
- }\r
+ private static final Logger logger = Logger.getLogger(PersistentTermInitializer.class);\r
+\r
+ private boolean omit = false;\r
+ protected ITermVocabularyDao vocabularyDao;\r
+\r
+ protected PlatformTransactionManager transactionManager;\r
+ protected DefaultTransactionDefinition txDefinition = new DefaultTransactionDefinition();\r
+\r
+ public PersistentTermInitializer() {\r
+ txDefinition.setName("PersistentTermInitializer.initialize()");\r
+ txDefinition.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);\r
+ }\r
+\r
+ public void setOmit(boolean omit) {\r
+ this.omit = omit;\r
+ }\r
+\r
+ public boolean isOmit() {\r
+ return omit;\r
+ }\r
+\r
+\r
+ @Autowired\r
+ public void setVocabularyDao(ITermVocabularyDao vocabularyDao) {\r
+ this.vocabularyDao = vocabularyDao;\r
+ }\r
+\r
+ @Autowired\r
+ public void setTransactionManager(PlatformTransactionManager transactionManager) {\r
+ this.transactionManager = transactionManager;\r
+ }\r
+\r
+ /*\r
+ * After a bit of head-scratching I found section 3.5.1.3. in the current spring\r
+ * reference manual - @PostConstruct / afterPropertiesSet() is called\r
+ * immediatly after the bean is constructed, prior to any AOP interceptors being\r
+ * wrapped round the bean. Thus, we have to use programmatic transactions, not\r
+ * annotations or pointcuts.\r
+ */\r
+ @PostConstruct\r
+ @Override\r
+ public void initialize() {\r
+ super.initialize();\r
+ }\r
+\r
+\r
+ @Override\r
+ public void doInitialize(){\r
+ logger.info("PersistentTermInitializer initialize start ...");\r
+ \r
+// //only for testing - remove\r
+// TransactionStatus txStatus2 = transactionManager.getTransaction(txDefinition);\r
+// int i = vocabularyDao.count();\r
+// List<TermVocabulary> list = vocabularyDao.list(null, null);\r
+// for (TermVocabulary voc : list){\r
+// System.out.println(voc.getUuid());\r
+// }\r
+// transactionManager.commit(txStatus2);\r
+// // end testing\r
+ \r
+ if (omit){\r
+ logger.info("PersistentTermInitializer.omit == true, returning without initializing terms");\r
+ return;\r
+ } else {\r
+ Map<UUID,DefinedTermBase> terms = new HashMap<UUID,DefinedTermBase>();\r
+ logger.info("PersistentTermInitializer.omit == false, initializing " + VocabularyEnum.values().length + " term classes");\r
+\r
+ TransactionStatus txStatus = transactionManager.getTransaction(txDefinition);\r
+ for(VocabularyEnum vocabularyType : VocabularyEnum.values()) {\r
+ //Class<? extends DefinedTermBase<?>> clazz = vocabularyType.getClazz();\r
+ UUID vocabularyUuid = firstPass(vocabularyType,terms);\r
+ secondPass(vocabularyType.getClazz(),vocabularyUuid,terms);\r
+ }\r
+ transactionManager.commit(txStatus);\r
+ }\r
+ logger.info("PersistentTermInitializer initialize end ...");\r
+ }\r
+\r
+ /**\r
+ * Initializes the static fields of the <code>TermVocabulary</code> classes.\r
+ *\r
+ * @param clazz the <code>Class</code> of the vocabulary\r
+ * @param vocabularyUuid the <code>UUID</code> of the vocabulary\r
+ * @param terms a <code>Map</code> containing all already\r
+ * loaded terms with their <code>UUID</code> as key\r
+ */\r
+ protected void secondPass(Class clazz, UUID vocabularyUuid, Map<UUID,DefinedTermBase> terms) {\r
+ logger.debug("Initializing vocabulary for class " + clazz.getSimpleName() + " with uuid " + vocabularyUuid );\r
+\r
+ TermVocabulary<?> persistedVocabulary = vocabularyDao.findByUuid(vocabularyUuid);\r
+\r
+ if (persistedVocabulary != null){\r
+ for(Object object : persistedVocabulary.getTerms()) {\r
+ DefinedTermBase<?> definedTermBase = (DefinedTermBase) object;\r
+ Hibernate.initialize(definedTermBase.getRepresentations());\r
+ for(Representation r : definedTermBase.getRepresentations()) {\r
+ Hibernate.initialize(r.getLanguage());\r
+ }\r
+ terms.put(definedTermBase.getUuid(), definedTermBase);\r
+ }\r
+ }else{\r
+ logger.error("Persisted Vocabulary does not exist in database: " + vocabularyUuid);\r
+ throw new NullPointerException("Persisted Vocabulary does not exist in database: " + vocabularyUuid);\r
+ }\r
+ logger.debug("Setting defined Terms for class " + clazz.getSimpleName() + ", " + persistedVocabulary.getTerms().size() + " in vocabulary");\r
+ super.setDefinedTerms(clazz, persistedVocabulary);\r
+ }\r
+\r
+ /**\r
+ * This method loads the vocabularies from CSV files and compares them to the vocabularies\r
+ * already in database. Non-existing vocabularies will be created and vocabularies with missing\r
+ * terms will be updated.\r
+ *\r
+ * @param clazz the <code>Class</code> of the vocabulary\r
+ * @param persistedTerms a <code>Map</code> containing all already\r
+ * loaded terms with their <code>UUID</code> as key\r
+ * @return the <code>UUID</code> of the loaded vocabulary as found in CSV file\r
+ */\r
+ public UUID firstPass(VocabularyEnum vocabularyType, Map<UUID, DefinedTermBase> persistedTerms) {\r
+ logger.info("Loading terms for '" + vocabularyType.name() + "': " + vocabularyType.getClazz().getName());\r
+ Map<UUID,DefinedTermBase> terms = new HashMap<UUID,DefinedTermBase>();\r
+\r
+ for(DefinedTermBase d : persistedTerms.values()) {\r
+ terms.put(d.getUuid(), d);\r
+ }\r
+\r
+ TermVocabulary<?> loadedVocabulary = termLoader.loadTerms(vocabularyType, terms);\r
+\r
+ UUID vocabularyUuid = loadedVocabulary.getUuid();\r
+\r
+\r
+ logger.debug("loading vocabulary " + vocabularyUuid);\r
+ TermVocabulary<DefinedTermBase> persistedVocabulary = vocabularyDao.findByUuid(vocabularyUuid);\r
+ if(persistedVocabulary == null) { // i.e. there is no persisted vocabulary\r
+ logger.debug("vocabulary " + vocabularyUuid + " does not exist - saving");\r
+ saveVocabulary(loadedVocabulary);\r
+ }else {\r
+ logger.debug("vocabulary " + vocabularyUuid + " does exist and already has " + persistedVocabulary.size() + " terms");\r
+ boolean persistedVocabularyHasMissingTerms = false;\r
+ for(Object t : loadedVocabulary.getTerms()) {\r
+ if(!persistedVocabulary.getTerms().contains(t)) {\r
+ persistedVocabularyHasMissingTerms = true;\r
+ persistedVocabulary.addTerm((DefinedTermBase)t);\r
+ }\r
+ }\r
+ if(persistedVocabularyHasMissingTerms) {\r
+ logger.debug("vocabulary " + vocabularyUuid + " exists but does not have all the required terms - updating");\r
+ updateVocabulary(persistedVocabulary);\r
+ }\r
+ }\r
+ return vocabularyUuid;\r
+ }\r
+\r
+ private void updateVocabulary(TermVocabulary vocabulary) {\r
+ TransactionStatus txStatus = transactionManager.getTransaction(txDefinition);\r
+ vocabularyDao.update(vocabulary);\r
+ transactionManager.commit(txStatus);\r
+ }\r
+\r
+ private void saveVocabulary(TermVocabulary vocabulary) {\r
+ TransactionStatus txStatus = transactionManager.getTransaction(txDefinition);\r
+ vocabularyDao.save(vocabulary);\r
+ transactionManager.commit(txStatus);\r
+ }\r
}\r