Project

General

Profile

Download (14.5 KB) Statistics
| Branch: | 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.io.cyprus;
11

    
12
import java.util.ArrayList;
13
import java.util.HashMap;
14
import java.util.HashSet;
15
import java.util.Iterator;
16
import java.util.List;
17
import java.util.Map;
18
import java.util.Set;
19
import java.util.UUID;
20

    
21
import org.apache.commons.lang.StringUtils;
22
import org.apache.log4j.Logger;
23
import org.springframework.stereotype.Component;
24

    
25
import eu.etaxonomy.cdm.api.service.pager.Pager;
26
import eu.etaxonomy.cdm.common.CdmUtils;
27
import eu.etaxonomy.cdm.io.common.mapping.IInputTransformer;
28
import eu.etaxonomy.cdm.io.common.mapping.UndefinedTransformerMethodException;
29
import eu.etaxonomy.cdm.io.excel.common.ExcelImporterBase;
30
import eu.etaxonomy.cdm.model.common.CdmBase;
31
import eu.etaxonomy.cdm.model.common.OriginalSourceType;
32
import eu.etaxonomy.cdm.model.common.TermType;
33
import eu.etaxonomy.cdm.model.common.TermVocabulary;
34
import eu.etaxonomy.cdm.model.description.DescriptionBase;
35
import eu.etaxonomy.cdm.model.description.DescriptionElementBase;
36
import eu.etaxonomy.cdm.model.description.Distribution;
37
import eu.etaxonomy.cdm.model.description.PresenceAbsenceTerm;
38
import eu.etaxonomy.cdm.model.description.TaxonDescription;
39
import eu.etaxonomy.cdm.model.location.Country;
40
import eu.etaxonomy.cdm.model.location.NamedArea;
41
import eu.etaxonomy.cdm.model.location.NamedAreaLevel;
42
import eu.etaxonomy.cdm.model.location.NamedAreaType;
43
import eu.etaxonomy.cdm.model.name.BotanicalName;
44
import eu.etaxonomy.cdm.model.reference.Reference;
45
import eu.etaxonomy.cdm.model.reference.ReferenceFactory;
46
import eu.etaxonomy.cdm.model.taxon.Taxon;
47

    
48
/**
49
 * @author a.babadshanjan
50
 * @created 08.01.2009
51
 * @version 1.0
52
 */
53

    
54
@Component
55
public class CyprusDistributionImport extends ExcelImporterBase<CyprusImportState> {
56
	private static final Logger logger = Logger.getLogger(CyprusDistributionImport.class);
57

    
58
	@Override
59
	protected boolean doCheck(CyprusImportState state) {
60
		logger.warn("DoCheck not yet implemented for CyprusExcelImport");
61
		return true;
62
	}
63

    
64
//	protected static final String ID_COLUMN = "Id";
65
	protected static final String SPECIES_COLUMN = "Taxon";
66
	protected static final String DISTRIBUTION_COLUMN = "Distribution";
67
	protected static final String REFERENCE_COLUMN = "source";
68

    
69

    
70
	private Reference refMeikle1977 = ReferenceFactory.newGeneric();
71
	private Reference refMeikle1985 = ReferenceFactory.newGeneric();
72

    
73
	private final Map<String, Taxon> taxonWithAuthorStore = new HashMap<String, Taxon>();
74
	private final Map<String, Taxon> taxonNameOnlyStore = new HashMap<String, Taxon>();
75

    
76

    
77
	private boolean areasCreated = false;
78
	private final Map<String, NamedArea> divisions = new HashMap<String, NamedArea>();
79

    
80
	private void makeAreasAndReference(CyprusImportState state) {
81
		if (areasCreated == false){
82
			IInputTransformer transformer = state.getTransformer();
83
			try {
84
				//divisions
85
				makeNewDivisions(state, transformer);
86

    
87
				loadReferences();
88
				loadStatus();
89
				loadTaxa();
90

    
91
				areasCreated = true;
92
				return;
93
			} catch (Exception e) {
94
				e.printStackTrace();
95
				state.setUnsuccessfull();
96
				return;
97
			}
98
		}
99
	}
100

    
101
	/**
102
	 *  Stores taxa records in DB
103
	 */
104
	@Override
105
    protected void firstPass(CyprusImportState state) {
106

    
107
		makeAreasAndReference(state);
108

    
109
		CyprusDistributionRow taxonLight = state.getCyprusDistributionRow();
110
		//species name
111
		String taxonStr = taxonLight.getSpecies();
112
		if ("#entf�llt#".equalsIgnoreCase(taxonStr)){
113
			logger.warn("entf�llt");
114
			return;
115
		}
116
		Taxon taxon = getTaxon(state, taxonStr);
117
		Reference ref = getReference(taxonLight.getReference());
118
		if (taxon != null){
119
			makeDistribution(state, taxon, taxonLight.getDistribution(), ref);
120
			getTaxonService().save(taxon);
121
		}
122

    
123
		return;
124
    }
125

    
126

    
127
	protected static final boolean CREATE = true;
128
	protected static final boolean CREATE_NOT = false;
129
	protected static final boolean NO_IMAGE_GALLERY = false;
130
	protected static final boolean IMAGE_GALLERY = false;
131

    
132
	private void makeDistribution(CyprusImportState state, Taxon taxon, String distributionStr, Reference ref) {
133

    
134
//		TaxonDescription description = getTaxonDescription(taxon, NO_IMAGE_GALLERY, CREATE);
135
		TaxonDescription description = getNewDescription(state, taxon);
136
		PresenceAbsenceTerm status = getStatus(taxon);
137
		status = removeDoubtfulStatus(status);
138
		removeDistributions(taxon);
139

    
140
		for (int i = 1; i <= 8; i++){
141
			if (distributionStr.contains(String.valueOf(i))){
142
				NamedArea area = this.divisions.get(String.valueOf(i));
143
				Distribution distribution = Distribution.NewInstance(area, status);
144
				distribution.addSource(OriginalSourceType.PrimaryTaxonomicSource, null, null, ref, null);
145
				description.addElement(distribution);
146
			}
147
		}
148
	}
149

    
150
	private TaxonDescription getNewDescription(CyprusImportState state, Taxon taxon) {
151
		Reference excelRef = state.getConfig().getSourceReference();
152
		TaxonDescription desc = TaxonDescription.NewInstance(taxon, false);
153
		desc.setTitleCache(excelRef.getTitleCache() + " for " + taxon.getTitleCache(), true);
154
		desc.addSource(OriginalSourceType.Import, null, null, excelRef, null);
155
		return desc;
156
	}
157

    
158
	private PresenceAbsenceTerm indigenousStatus;
159
	private PresenceAbsenceTerm casualStatus;
160
	private PresenceAbsenceTerm nonInvasiveStatus;
161
	private PresenceAbsenceTerm invasiveStatus;
162
	private PresenceAbsenceTerm questionableStatus;
163

    
164
	private PresenceAbsenceTerm removeDoubtfulStatus(PresenceAbsenceTerm status) {
165
	    if (status == null){
166
			return null;
167
		}
168
		if (status.getUuid().equals(CyprusTransformer.indigenousDoubtfulUuid)){
169
			status = indigenousStatus;
170
		}else if (status.getUuid().equals(CyprusTransformer.casualDoubtfulUuid)){
171
			status = casualStatus;
172
		}else if (status.getUuid().equals(CyprusTransformer.nonInvasiveDoubtfulUuid)){
173
			status = nonInvasiveStatus;
174
		}else if (status.getUuid().equals(CyprusTransformer.invasiveDoubtfulUuid)){
175
			status = invasiveStatus;
176
		}else if (status.getUuid().equals(CyprusTransformer.questionableDoubtfulUuid)){
177
			status = questionableStatus;
178
		}else if (status.getUuid().equals(CyprusTransformer.cultivatedDoubtfulUuid)){
179
			status = PresenceAbsenceTerm.CULTIVATED();
180
		}
181

    
182
		return status;
183
	}
184

    
185
	private PresenceAbsenceTerm getStatus(Taxon taxon) {
186
		Set<PresenceAbsenceTerm> statusSet = new HashSet<PresenceAbsenceTerm>();
187
		Set<Distribution> existingDistributions = getExistingDistributions(taxon);
188
		if (existingDistributions.size() > 1){
189
			logger.warn("There is more than 1 distribution: " + taxon.getTitleCache());
190
		}
191
		for (Distribution distribution: existingDistributions){
192
			PresenceAbsenceTerm status = distribution.getStatus();
193
			statusSet.add(status);
194
		}
195

    
196
		if (statusSet.size() == 0){
197
			logger.warn("No status found for: " +  taxon.getTitleCache());
198
			return null;
199
		}else if (statusSet.size() == 1){
200
			return statusSet.iterator().next();
201
		}else{
202
			logger.warn("More than 1 status found. Return first: " +  taxon.getTitleCache());
203
			return statusSet.iterator().next();
204
		}
205
	}
206

    
207
	/**
208
	 * @param taxon
209
	 * @param statusSet
210
	 */
211
	private void removeDistributions(Taxon taxon) {
212
		Set<Distribution> toRemove = new HashSet<Distribution>();
213
		for (TaxonDescription desc : taxon.getDescriptions()){
214
			if (desc.isImageGallery() == NO_IMAGE_GALLERY ){
215
				Iterator<DescriptionElementBase> iterator = desc.getElements().iterator();
216
				while (iterator.hasNext()){
217
					DescriptionElementBase element = iterator.next();
218
					if (element.isInstanceOf(Distribution.class)){
219
						toRemove.add(CdmBase.deproxy(element, Distribution.class));
220
//						iterator.remove();
221
					}
222
				}
223
			}
224
		}
225
		for (Distribution distribution : toRemove){
226
			DescriptionBase<?> desc = distribution.getInDescription();
227
			desc.removeElement(distribution);
228
			getDescriptionService().saveOrUpdate(desc);
229
		}
230
		return;
231
	}
232

    
233
	/**
234
	 * @param taxon
235
	 * @param statusSet
236
	 */
237
	private Set<Distribution> getExistingDistributions(Taxon taxon) {
238
		Set<Distribution> result = new HashSet<Distribution>();
239
		for (TaxonDescription desc : taxon.getDescriptions()){
240
			if (desc.isImageGallery() == NO_IMAGE_GALLERY ){
241
				for (DescriptionElementBase element : desc.getElements()){
242
					if (element.isInstanceOf(Distribution.class)){
243
						Distribution distribution = CdmBase.deproxy(element, Distribution.class);
244
						result.add(distribution);
245
					}
246
				}
247
			}
248
		}
249
		return result;
250
	}
251

    
252
	private Reference getReference(String referenceStr) {
253
		Reference result;
254
		if ("Meikle 1977".equals(referenceStr)){
255
			result = refMeikle1977;
256
		}else if("Meikle 1985".equals(referenceStr)){
257
			result = refMeikle1985;
258
		}else{
259
			logger.warn("Reference not recognized: " + referenceStr);
260
			result = null;
261
		}
262
		return result;
263
	}
264

    
265
	private Taxon getTaxon(CyprusImportState state, String taxonStr) {
266
		Taxon result;
267

    
268
		if (taxonWithAuthorStore.get(taxonStr) != null){
269
			result = taxonWithAuthorStore.get(taxonStr);
270
		}else if(taxonNameOnlyStore.get(taxonStr) != null){
271
			result = taxonNameOnlyStore.get(taxonStr);
272
		}else {
273
//			result = getTaxonService().findBestMatchingTaxon(taxonStr);
274
//			TaxonNameBase name = BotanicalName.NewInstance(Rank.SPECIES());
275
//			name.setTitleCache(taxonStr, true);
276
//
277
//			result = Taxon.NewInstance(name, null);
278
//			if (result == null){
279
				logger.warn("Taxon not found: " +  taxonStr);
280
//			}else{
281
//				taxonStore.put(taxonStr, result);
282
//			}
283
			result = null;
284
		}
285
		return result;
286
	}
287

    
288

    
289

    
290
	/**
291
	 *
292
	 */
293
	private void loadTaxa() {
294
		List<String> propertyPaths = new ArrayList<String>();
295
		propertyPaths.add("*.name");
296
		List<Taxon> taxonList = getTaxonService().list(Taxon.class, null, null, null, propertyPaths);
297
		for (Taxon taxon: taxonList){
298
			if (taxon.getTaxonNodes().size() == 0){
299
				continue;
300
			}
301
			String nameTitle = taxon.getName().getTitleCache();
302
			String nameCache = CdmBase.deproxy(taxon.getName(), BotanicalName.class).getNameCache();
303
			Taxon returnValue = taxonWithAuthorStore.put(nameTitle, taxon);
304
			if (returnValue != null){
305
				logger.warn("Duplicate titleCache entry for taxon: " + nameTitle);
306
			}
307
			returnValue = taxonNameOnlyStore.put(nameCache, taxon);
308
			if (returnValue != null){
309
				logger.warn("Duplicate nameCache entry for taxon: " + nameCache);
310
			}
311
		}
312
	}
313

    
314
	/**
315
	 * @param meikle1977List
316
	 */
317
	private void loadReferences() {
318
		Pager<Reference> meikle1977List = getReferenceService().findByTitle(Reference.class, "R. D. Meikle, Flora of Cyprus 1. 1977", null, null, null, null, null, null);
319

    
320
		if (meikle1977List.getCount() != 1){
321
			logger.error("There is not exactly 1 Meikle 1977 reference");
322
		}else{
323
			refMeikle1977 = meikle1977List.getRecords().iterator().next();
324
		}
325

    
326
		Pager<Reference> meikle1985List = getReferenceService().findByTitle(Reference.class, "R. D. Meikle, Flora of Cyprus 2. 1985", null, null, null, null, null, null);
327
		if (meikle1985List.getCount() != 1){
328
			logger.error("There is not exactly 1 Meikle 1985 reference");
329
		}else{
330
			refMeikle1985 = meikle1977List.getRecords().iterator().next();
331
		}
332
	}
333

    
334
	/**
335
	 *
336
	 */
337
	private void loadStatus() {
338
		indigenousStatus = (PresenceAbsenceTerm)getTermService().find(CyprusTransformer.indigenousUuid);
339
		casualStatus = (PresenceAbsenceTerm)getTermService().find(CyprusTransformer.casualUuid);
340
		nonInvasiveStatus = (PresenceAbsenceTerm)getTermService().find(CyprusTransformer.nonInvasiveUuid);
341
		invasiveStatus = (PresenceAbsenceTerm)getTermService().find(CyprusTransformer.invasiveUuid);
342
		questionableStatus = (PresenceAbsenceTerm)getTermService().find(CyprusTransformer.questionableUuid);
343
	}
344

    
345
	/**
346
	 * @param state
347
	 * @param transformer
348
	 * @throws UndefinedTransformerMethodException
349
	 */
350
	private void makeNewDivisions(CyprusImportState state,
351
			IInputTransformer transformer)
352
			throws UndefinedTransformerMethodException {
353
		NamedAreaType areaType = NamedAreaType.NATURAL_AREA();
354
		NamedAreaLevel areaLevel = (NamedAreaLevel)getTermService().find(CyprusTransformer.uuidCyprusDivisionsAreaLevel);
355
		if (areaLevel == null){
356
			areaLevel = NamedAreaLevel.NewInstance("Cyprus Division", "Cyprus Division", null);
357
			getTermService().save(areaLevel);
358
		}
359

    
360
		TermVocabulary<NamedArea> areaVocabulary = getVocabulary(TermType.NamedArea, CyprusTransformer.uuidCyprusDivisionsVocabulary, "Cyprus devisions", "Cyprus divisions", null, null, true, NamedArea.NewInstance());
361
		NamedArea tdwg4Cyprus = (NamedArea)getTermService().find(UUID.fromString("9d447b51-e363-4dde-ae40-84c55679983c"));
362
		Country isoCountryCyprus = (Country)getTermService().find(UUID.fromString("4b13d6b8-7eca-4d42-8172-f2018051ca19"));
363

    
364
		for(int i = 1; i <= 8; i++){
365
			UUID divisionUuid = transformer.getNamedAreaUuid(String.valueOf(i));
366
			NamedArea division = this.getNamedArea(state, divisionUuid, "Division " + i, "Cyprus: Division " + i, String.valueOf(i), areaType, areaLevel, areaVocabulary, null);
367
			divisions.put(String.valueOf(i), division);
368
			tdwg4Cyprus.addIncludes(division);
369
			isoCountryCyprus.addIncludes(division);
370
			getTermService().save(division);
371
		}
372
	}
373

    
374

    
375
	@Override
376
    protected void analyzeRecord(HashMap<String, String> record, CyprusImportState state) {
377

    
378
    	Set<String> keys = record.keySet();
379
    	CyprusDistributionRow cyprusDistributionRow = new CyprusDistributionRow();
380
    	state.setCyprusDistributionRow(cyprusDistributionRow);
381

    
382
    	for (String originalKey: keys) {
383
    		String indexedKey = CdmUtils.removeDuplicateWhitespace(originalKey.trim()).toString();
384
    		String[] split = indexedKey.split("_");
385
    		String key = split[0];
386
    		if (split.length > 1){
387
    			String indexString = split[1];
388
    			try {
389
					Integer.valueOf(indexString);
390
				} catch (NumberFormatException e) {
391
					String message = "Index must be integer";
392
					logger.error(message);
393
					continue;
394
				}
395
    		}
396

    
397
    		String value = record.get(indexedKey);
398
    		if (! StringUtils.isBlank(value)) {
399
    			if (logger.isDebugEnabled()) { logger.debug(key + ": " + value); }
400
        		value = CdmUtils.removeDuplicateWhitespace(value.trim()).toString();
401
    		}else{
402
    			continue;
403
    		}
404

    
405

    
406
    		if (key.equalsIgnoreCase(SPECIES_COLUMN)) {
407
    			cyprusDistributionRow.setSpecies(value);
408

    
409
			} else if(key.equalsIgnoreCase(DISTRIBUTION_COLUMN)) {
410
				cyprusDistributionRow.setDistribution(value);
411

    
412
			} else if(key.equalsIgnoreCase(REFERENCE_COLUMN)) {
413
				cyprusDistributionRow.setReference(value);
414

    
415
			} else {
416
				state.setUnsuccessfull();
417
				logger.error("Unexpected column header " + key);
418
			}
419
    	}
420
    	return;
421
    }
422

    
423

    
424
	/**
425
	 *
426
	 */
427
	@Override
428
    protected void secondPass(CyprusImportState state) {
429
		//no second pass for this import
430
		return;
431
	}
432

    
433
	@Override
434
	protected boolean isIgnore(CyprusImportState state) {
435
		return ! state.getConfig().isDoDistribution();
436
	}
437

    
438
}
(1-1/8)