Fixed a couple of bugs introduced during #464
[cdmlib.git] / cdmlib-model / src / main / java / eu / etaxonomy / cdm / model / common / init / TermLoader.java
1 package eu.etaxonomy.cdm.model.common.init;
2
3 import java.io.FileNotFoundException;
4 import java.io.InputStream;
5 import java.io.InputStreamReader;
6 import java.util.ArrayList;
7 import java.util.HashMap;
8 import java.util.List;
9 import java.util.Map;
10 import java.util.UUID;
11
12 import org.apache.log4j.Logger;
13 import org.springframework.beans.factory.annotation.Autowired;
14 import org.springframework.stereotype.Component;
15 import org.springframework.transaction.annotation.Transactional;
16
17 import au.com.bytecode.opencsv.CSVReader;
18 import eu.etaxonomy.cdm.common.CdmUtils;
19
20 import eu.etaxonomy.cdm.model.common.AnnotationType;
21 import eu.etaxonomy.cdm.model.common.DefinedTermBase;
22 import eu.etaxonomy.cdm.model.common.ILoadableTerm;
23 import eu.etaxonomy.cdm.model.common.Language;
24 import eu.etaxonomy.cdm.model.common.MarkerType;
25 import eu.etaxonomy.cdm.model.common.NoDefinedTermClassException;
26 import eu.etaxonomy.cdm.model.common.OrderedTermBase;
27 import eu.etaxonomy.cdm.model.common.OrderedTermVocabulary;
28 import eu.etaxonomy.cdm.model.common.TermVocabulary;
29 import eu.etaxonomy.cdm.model.description.AbsenceTerm;
30 import eu.etaxonomy.cdm.model.description.Feature;
31 import eu.etaxonomy.cdm.model.description.PresenceTerm;
32 import eu.etaxonomy.cdm.model.description.Sex;
33 import eu.etaxonomy.cdm.model.description.StatisticalMeasure;
34 import eu.etaxonomy.cdm.model.location.Continent;
35 import eu.etaxonomy.cdm.model.location.NamedArea;
36 import eu.etaxonomy.cdm.model.location.NamedAreaLevel;
37 import eu.etaxonomy.cdm.model.location.NamedAreaType;
38 import eu.etaxonomy.cdm.model.location.WaterbodyOrCountry;
39 import eu.etaxonomy.cdm.model.name.HybridRelationshipType;
40 import eu.etaxonomy.cdm.model.name.NameRelationshipType;
41 import eu.etaxonomy.cdm.model.name.NomenclaturalCode;
42 import eu.etaxonomy.cdm.model.name.NomenclaturalStatusType;
43 import eu.etaxonomy.cdm.model.name.Rank;
44 import eu.etaxonomy.cdm.model.name.TypeDesignationStatus;
45 import eu.etaxonomy.cdm.model.occurrence.DerivationEventType;
46 import eu.etaxonomy.cdm.model.occurrence.DeterminationModifier;
47 import eu.etaxonomy.cdm.model.occurrence.PreservationMethod;
48 import eu.etaxonomy.cdm.model.taxon.TaxonRelationshipType;
49 import eu.etaxonomy.cdm.model.taxon.SynonymRelationshipType;
50
51 @Component
52 @Transactional(readOnly = false)
53 public class TermLoader {
54 private static final Logger logger = Logger.getLogger(TermLoader.class);
55
56 @Autowired
57 private IVocabularyStore vocabularyStore;
58 // private VocabularyStoreImpl vocabularyStore;
59
60
61 //TODO private -but Autowiring for constructor arguments is needed then for classes that use this class autowired (e.g. CdmTermInitializer)
62 @Deprecated //because still public
63 public TermLoader(){
64 super();
65 }
66 public void setVocabularyStore(IVocabularyStore vocabularyStore){
67 this.vocabularyStore = vocabularyStore;
68 }
69
70
71
72 public TermLoader(IVocabularyStore vocabularyStore){
73 super();
74 this.vocabularyStore = vocabularyStore;
75 }
76
77
78 // load a list of defined terms from a simple text file
79 // if isEnumeration is true an Enumeration for the ordered term list will be returned
80 @Transactional(readOnly = false)
81 public TermVocabulary<DefinedTermBase> insertTerms(Class<ILoadableTerm> termClass, String filename, boolean isEnumeration, boolean isOrdered) throws NoDefinedTermClassException, FileNotFoundException {
82 DefinedTermBase.setVocabularyStore(vocabularyStore); //otherwise DefinedTermBase is not able to find DefaultLanguage
83 TermVocabulary.setVocabularyStore(vocabularyStore);
84 try {
85 String strResourceFileName = "terms" + CdmUtils.getFolderSeperator() + filename;
86 logger.debug("strResourceFileName is " + strResourceFileName);
87 InputStream inputStream = CdmUtils.getReadableResourceStream("terms" + CdmUtils.getFolderSeperator() + filename);
88 if (inputStream == null) {logger.info("inputStream is null");}
89 CSVReader reader = new CSVReader(new InputStreamReader(inputStream));
90
91 //vocabulary
92 TermVocabulary voc = null;
93 String labelAbbrev = null;
94 if (isOrdered){
95 voc = new OrderedTermVocabulary<OrderedTermBase>(termClass.getCanonicalName(), termClass.getSimpleName(), labelAbbrev, termClass.getCanonicalName());
96 }else{
97 voc = new TermVocabulary<DefinedTermBase>(termClass.getCanonicalName(), termClass.getSimpleName(), labelAbbrev, termClass.getCanonicalName());
98 }
99 String [] nextLine = reader.readNext();
100 if (nextLine != null){
101 voc.readCsvLine(arrayedLine(nextLine));
102 }
103 saveVocabulary(voc, termClass);
104 //terms
105 while ((nextLine = reader.readNext()) != null) {
106 // nextLine[] is an array of values from the line
107 if (nextLine.length == 0){
108 continue;
109 }
110 ILoadableTerm term = termClass.newInstance();
111 term = term.readCsvLine(arrayedLine(nextLine));
112 term.setVocabulary(voc);
113 vocabularyStore.saveOrUpdate(term);
114 // save enumeration and all terms to DB
115 }
116 return voc;
117 } catch (Exception e) {
118 logger.error(e.getMessage());
119 e.printStackTrace();
120 return null;
121 }
122 }
123
124 private List<String> arrayedLine(String [] nextLine){
125 ArrayList<String> csvTermAttributeList = new ArrayList<String>(10);
126 for (String col : nextLine){
127 csvTermAttributeList.add(col);
128 }
129 while (csvTermAttributeList.size()<10){
130 csvTermAttributeList.add("");
131 }
132 return csvTermAttributeList;
133 }
134
135
136 private void saveVocabulary(TermVocabulary voc, Class<ILoadableTerm> termClass){
137 if (vocabularyStore != null){
138 vocabularyStore.saveOrUpdate(voc);
139 }else{
140 //e.g. in tests when no database connection exists
141 if (logger.isDebugEnabled()) {logger.debug("No vocabularyStore exists. Vocabulary for class '" + termClass + "' could not be saved to database");}
142 }
143
144 }
145
146 public TermVocabulary<DefinedTermBase> insertDefaultTerms(Class termClass, boolean isOrdered) throws NoDefinedTermClassException, FileNotFoundException {
147 return insertDefaultTerms(termClass, termClass.getSimpleName()+".csv", isOrdered );
148 }
149
150 public TermVocabulary<DefinedTermBase> insertDefaultTerms(Class termClass, String csvName, boolean isOrdered) throws NoDefinedTermClassException, FileNotFoundException {
151 if (termClass != null){logger.info("load file " + csvName);}
152 return this.insertTerms(termClass, csvName, true, isOrdered );
153 }
154
155 public boolean insertDefaultTerms() throws FileNotFoundException, NoDefinedTermClassException{
156 final boolean ORDERED = true;
157 final boolean NOT_ORDERED = false;
158
159 logger.info("load terms");
160 insertDefaultTerms(Language.class, NOT_ORDERED);
161 insertDefaultTerms(Continent.class, NOT_ORDERED);
162 insertDefaultTerms(WaterbodyOrCountry.class, NOT_ORDERED);
163 insertDefaultTerms(Rank.class, ORDERED);
164 insertDefaultTerms(TypeDesignationStatus.class, ORDERED);
165 insertDefaultTerms(NomenclaturalStatusType.class, ORDERED);
166 insertDefaultTerms(SynonymRelationshipType.class, ORDERED);
167 insertDefaultTerms(HybridRelationshipType.class, ORDERED);
168 insertDefaultTerms(NameRelationshipType.class, ORDERED);
169 insertDefaultTerms(TaxonRelationshipType.class, ORDERED);
170 insertDefaultTerms(MarkerType.class, NOT_ORDERED);
171 insertDefaultTerms(AnnotationType.class, NOT_ORDERED);
172 insertDefaultTerms(NamedAreaType.class, NOT_ORDERED);
173 insertDefaultTerms(NamedAreaLevel.class, NOT_ORDERED);
174 insertDefaultTerms(NomenclaturalCode.class, NOT_ORDERED);
175 insertDefaultTerms(Feature.class, NOT_ORDERED);
176 insertDefaultTerms(NamedArea.class, "TdwgArea.csv", ORDERED);
177 insertDefaultTerms(PresenceTerm.class, ORDERED);
178 insertDefaultTerms(AbsenceTerm.class, ORDERED);
179 insertDefaultTerms(Sex.class, ORDERED);
180 insertDefaultTerms(DerivationEventType.class, NOT_ORDERED);
181 insertDefaultTerms(PreservationMethod.class, NOT_ORDERED);
182 insertDefaultTerms(DeterminationModifier.class, ORDERED);
183 insertDefaultTerms(StatisticalMeasure.class, NOT_ORDERED);
184 logger.debug("terms loaded");
185 return true;
186 }
187
188
189 public boolean makeDefaultTermsInserted() throws FileNotFoundException, NoDefinedTermClassException{
190 return makeDefaultTermsInserted(vocabularyStore);
191 }
192
193 public boolean makeDefaultTermsInserted(IVocabularyStore vocabularyStore) throws FileNotFoundException, NoDefinedTermClassException{
194 if (vocabularyStore == null){
195 vocabularyStore = this.vocabularyStore;
196 }
197 if (! checkBasicTermsExist(vocabularyStore)){
198 return insertDefaultTerms();
199 }
200 return true;
201 }
202
203 /**
204 * True, if some of the important basic terms are accessible by saver
205 * @param saver
206 * @return
207 */
208 private boolean checkBasicTermsExist(IVocabularyStore vocabularyStore){
209 if (vocabularyStore == null){
210 vocabularyStore = this.vocabularyStore;
211 }
212 if (vocabularyStore == null){
213 return false;
214 }
215 Map<String, UUID> allImportantUuid = new HashMap<String,UUID>();
216 allImportantUuid.put("English", UUID.fromString("e9f8cdb7-6819-44e8-95d3-e2d0690c3523"));
217 allImportantUuid.put("Rank", UUID.fromString("1b11c34c-48a8-4efa-98d5-84f7f66ef43a"));
218 for (UUID uuid: allImportantUuid.values()){
219 if (! checkTermExists(uuid, vocabularyStore)){
220 return false;
221 }
222 }
223 return true;
224 }
225
226 private boolean checkTermExists(UUID uuid, IVocabularyStore vocabularyStore){
227 if (vocabularyStore == null){
228 return false;
229 }
230 ILoadableTerm basicTerm = vocabularyStore.getTermByUuid(uuid);
231 if ( basicTerm == null || ! basicTerm.getUuid().equals(uuid)){
232 return false;
233 }else{
234 return true;
235 }
236
237 }
238
239 }