Project

General

Profile

Download (7.05 KB) Statistics
| Branch: | Tag: | Revision:
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.model.term.init;
11

    
12
import java.io.IOException;
13
import java.lang.reflect.Constructor;
14
import java.util.ArrayList;
15
import java.util.HashMap;
16
import java.util.HashSet;
17
import java.util.List;
18
import java.util.Map;
19
import java.util.Set;
20
import java.util.UUID;
21

    
22
import org.apache.log4j.Logger;
23
import org.springframework.stereotype.Component;
24

    
25
import au.com.bytecode.opencsv.CSVReader;
26
import eu.etaxonomy.cdm.common.CdmUtils;
27
import eu.etaxonomy.cdm.model.term.DefinedTermBase;
28
import eu.etaxonomy.cdm.model.term.OrderedTermBase;
29
import eu.etaxonomy.cdm.model.term.OrderedTermVocabulary;
30
import eu.etaxonomy.cdm.model.term.TermType;
31
import eu.etaxonomy.cdm.model.term.TermVocabulary;
32
import eu.etaxonomy.cdm.model.term.VocabularyEnum;
33

    
34
@Component
35
public class TermLoader implements ITermLoader {
36
	private static final Logger logger = Logger.getLogger(TermLoader.class);
37

    
38
	@Override
39
	public void unloadAllTerms(){
40
		for(VocabularyEnum vocabularyEnum : VocabularyEnum.values()) {
41
//			Class<? extends DefinedTermBase<?>> clazz = vocabularyEnum.getClazz();
42
			this.unloadVocabularyType(vocabularyEnum);
43
		}
44
	}
45

    
46
	private <T extends DefinedTermBase> void unloadVocabularyType(VocabularyEnum vocType){
47
		Class<? extends DefinedTermBase> termClass = vocType.getClazz();
48
		getInstance(termClass).resetTerms();
49
		return;
50
	}
51

    
52
	@Override
53
	public UUID loadUuids(VocabularyEnum vocType, Map<UUID, Set<UUID>> uuidMap) {
54

    
55
		try {
56
			CSVReader reader = getCsvReader(vocType);
57
			String[] nextLine = reader.readNext();
58
			UUID uuidVocabulary = UUID.fromString(nextLine[0]);
59
			Set<UUID> termSet = new HashSet<>();
60
			uuidMap.put(uuidVocabulary, termSet);
61

    
62
			while ( (nextLine = reader.readNext()) != null) {
63
				UUID uuidTerm = UUID.fromString(nextLine[0]);
64
				termSet.add(uuidTerm);
65
			}
66
			return uuidVocabulary;
67

    
68

    
69
		} catch (Exception e) {
70
			logger.error(e + " " + e.getCause() + " " + e.getMessage());
71
			for(StackTraceElement ste : e.getStackTrace()) {
72
				logger.error(ste);
73
			}
74
			throw new RuntimeException(e);
75
		}
76

    
77
	}
78

    
79
	@Override
80
	public <T extends DefinedTermBase> TermVocabulary<T> loadTerms(VocabularyEnum vocType, Map<UUID,DefinedTermBase> terms) {
81

    
82

    
83
		try {
84
			CSVReader reader = getCsvReader(vocType);
85

    
86
			String [] nextLine = reader.readNext();
87

    
88

    
89
			Class<? extends DefinedTermBase> termClass = vocType.getClazz();
90

    
91
			//vocabulary
92
			TermVocabulary<T> voc;
93
			TermType termType = TermType.Unknown;
94
			if (OrderedTermBase.class.isAssignableFrom(termClass)){
95
				voc = OrderedTermVocabulary.NewInstance(termType);
96
			}else{
97
				voc = TermVocabulary.NewInstance(termType);
98
			}
99

    
100
			if (nextLine != null){
101
				voc.readCsvLine(arrayedLine(nextLine));
102
			}
103
			termType = voc.getTermType();
104
			boolean abbrevAsId = (arrayedLine(nextLine).get(5).equals("1"));
105

    
106
			// Ugly, I know, but I don't think we can use a static method here . .
107

    
108
			T classDefiningTermInstance = getInstance(termClass);// ((Class<T>)termClass).newInstance();
109

    
110
			while ((nextLine = reader.readNext()) != null) {
111
				// nextLine[] is an array of values from the line
112
				if (nextLine.length == 0){
113
					continue;
114
				}
115

    
116
				handleSingleTerm(nextLine, terms, termClass, voc,
117
						abbrevAsId, classDefiningTermInstance);
118

    
119
			}
120
			return voc;
121
		} catch (Exception e) {
122
			logger.error(e + " " + e.getCause() + " " + e.getMessage());
123
			for(StackTraceElement ste : e.getStackTrace()) {
124
				logger.error(ste);
125
			}
126
			throw new RuntimeException(e);
127
		}
128

    
129
	}
130

    
131
	/**
132
	 * Handles a single csv line, creates the term and adds it to the vocabulary and to the terms map.
133
	 * @param csvLine csv line
134
	 * @param terms UUID-Term map this term should be added to
135
	 * @param termClass the class of the term to create
136
	 * @param voc the vocabulary the term should be added to
137
	 * @param abbrevAsId boolean value, if true the abbreviation should be taken as idInVocabulary
138
	 * @param classDefiningTermInstance instance for calling readCsvLine
139
	 * @return
140
	 */
141
	private <T extends DefinedTermBase> T handleSingleTerm(String[] csvLine, Map<UUID,DefinedTermBase> terms,
142
			Class<? extends DefinedTermBase> termClass,
143
			TermVocabulary<T> voc, boolean abbrevAsId,
144
			T classDefiningTermInstance) {
145
		T term = (T) classDefiningTermInstance.readCsvLine(termClass,arrayedLine(csvLine), voc.getTermType(), terms, abbrevAsId);
146
		voc.addTerm(term);
147
		terms.put(term.getUuid(), term);
148
		return term;
149
	}
150

    
151

    
152
	@Override
153
	public <T extends DefinedTermBase> Set<T> loadSingleTerms(VocabularyEnum vocType,
154
			TermVocabulary<T> voc, Set<UUID> missingTerms) {
155
		try {
156
			Class<? extends DefinedTermBase> termClass = vocType.getClazz();
157

    
158
			CSVReader reader = getCsvReader(vocType);
159
			String [] nextLine =  reader.readNext();
160

    
161
			if (! UUID.fromString(nextLine[0]).equals(voc.getUuid())){
162
				throw new IllegalStateException("Vocabularies in csv file and vocabulary must be equal");
163
			}
164

    
165

    
166

    
167
			boolean abbrevAsId = (arrayedLine(nextLine).get(5).equals("1"));
168
			T classDefiningTermInstance = getInstance(termClass);// ((Class<T>)termClass).newInstance();
169
			Map<UUID,DefinedTermBase> allVocTerms = new HashMap<UUID, DefinedTermBase>();
170
			for (T term:voc.getTerms()){
171
				allVocTerms.put(term.getUuid(), term);
172
			}
173

    
174
			while ((nextLine = reader.readNext()) != null) {
175
				if (nextLine.length == 0){
176
					continue;
177
				}
178
				UUID uuid = UUID.fromString(nextLine[0]);
179
				if (missingTerms.contains(uuid)){
180
					handleSingleTerm(nextLine, allVocTerms, termClass, voc, abbrevAsId, classDefiningTermInstance);
181
				}
182
			}
183

    
184
			return null;
185
		} catch (Exception e) {
186
			e.printStackTrace();
187
			throw new RuntimeException(e);
188
		}
189
	}
190

    
191
	/**
192
	 * Returns the {@link CSVReader} for the given {@link VocabularyEnum}.
193
	 * @param vocType
194
	 * @return
195
	 * @throws IOException
196
	 */
197
	private CSVReader getCsvReader(VocabularyEnum vocType) throws IOException {
198
		String filename = vocType.name()+".csv";
199
		String strResourceFileName = "terms" + CdmUtils.getFolderSeperator() + filename;
200
		if (logger.isDebugEnabled()){logger.debug("strResourceFileName is " + strResourceFileName);}
201
		CSVReader reader = new CSVReader(CdmUtils.getUtf8ResourceReader(strResourceFileName));
202
		return reader;
203
	}
204

    
205
	/**
206
	 * Returns a new instance for the given class by using the default constructor.
207
	 * The constructor must be declared but can be unaccessible (e.g. private)
208
	 * @param termClass
209
	 * @return
210
	 */
211
	private  <T extends DefinedTermBase> T getInstance(Class<? extends DefinedTermBase> termClass) {
212
		try {
213
			Constructor<T> c = ((Class<T>)termClass).getDeclaredConstructor();
214
			c.setAccessible(true);
215
			T termInstance = c.newInstance();
216
			return termInstance;
217
		} catch (Exception e) {
218
			throw new RuntimeException(e);
219
		}
220
	}
221

    
222
	private List<String> arrayedLine(String [] nextLine){
223
		ArrayList<String> csvTermAttributeList = new ArrayList<String>(15);
224
		for (String col : nextLine){
225
			csvTermAttributeList.add(col);
226
		}
227
		while (csvTermAttributeList.size()<15){
228
			csvTermAttributeList.add("");
229
		}
230
		return csvTermAttributeList;
231
	}
232

    
233
}
(3-3/4)