Project

General

Profile

Download (15.3 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
	/* (non-Javadoc)
59
	 * @see eu.etaxonomy.cdm.io.common.CdmIoBase#doCheck(eu.etaxonomy.cdm.io.common.IoStateBase)
60
	 */
61
	@Override
62
	protected boolean doCheck(CyprusImportState state) {
63
		logger.warn("DoCheck not yet implemented for CyprusExcelImport");
64
		return true;
65
	}
66

    
67
//	protected static final String ID_COLUMN = "Id";
68
	protected static final String SPECIES_COLUMN = "Taxon";
69
	protected static final String DISTRIBUTION_COLUMN = "Distribution";
70
	protected static final String REFERENCE_COLUMN = "source";
71
	
72

    
73
	private Reference<?> refMeikle1977 = ReferenceFactory.newGeneric();
74
	private Reference<?> refMeikle1985 = ReferenceFactory.newGeneric();
75
	
76
	private Map<String, Taxon> taxonWithAuthorStore = new HashMap<String, Taxon>(); 
77
	private Map<String, Taxon> taxonNameOnlyStore = new HashMap<String, Taxon>();
78

    
79

    
80
	private boolean areasCreated = false;
81
	private Map<String, NamedArea> divisions = new HashMap<String, NamedArea>();
82
	
83
	private void makeAreasAndReference(CyprusImportState state) {
84
		if (areasCreated == false){
85
			IInputTransformer transformer = state.getTransformer();
86
			try {
87
				//divisions
88
				makeNewDivisions(state, transformer);
89
				
90
				loadReferences();
91
				loadStatus();
92
				loadTaxa();
93
				
94
				areasCreated = true;
95
				return;
96
			} catch (Exception e) {
97
				e.printStackTrace();
98
				state.setUnsuccessfull();
99
				return;
100
			}
101
		}
102
	}
103

    
104
	/** 
105
	 *  Stores taxa records in DB
106
	 */
107
	@Override
108
    protected void firstPass(CyprusImportState state) {
109
		
110
		makeAreasAndReference(state);
111
		
112
		CyprusDistributionRow taxonLight = state.getCyprusDistributionRow();
113
		//species name
114
		String taxonStr = taxonLight.getSpecies();
115
		if ("#entf�llt#".equalsIgnoreCase(taxonStr)){
116
			logger.warn("entf�llt");
117
			return;
118
		}
119
		Taxon taxon = getTaxon(state, taxonStr);
120
		Reference<?> ref = getReference(taxonLight.getReference());
121
		if (taxon != null){
122
			makeDistribution(state, taxon, taxonLight.getDistribution(), ref);
123
			getTaxonService().save(taxon);
124
		}	
125
			
126
		return;
127
    }
128

    
129
	
130
	protected static final boolean CREATE = true;
131
	protected static final boolean CREATE_NOT = false;
132
	protected static final boolean NO_IMAGE_GALLERY = false;
133
	protected static final boolean IMAGE_GALLERY = false;
134
	
135
	private void makeDistribution(CyprusImportState state, Taxon taxon, String distributionStr, Reference<?> ref) {
136
		
137
//		TaxonDescription description = getTaxonDescription(taxon, NO_IMAGE_GALLERY, CREATE);
138
		TaxonDescription description = getNewDescription(state, taxon);
139
		PresenceAbsenceTerm status = getStatus(taxon);
140
		status = removeDoubtfulStatus(status);
141
		removeDistributions(taxon);
142
		
143
		for (int i = 1; i <= 8; i++){
144
			if (distributionStr.contains(String.valueOf(i))){
145
				NamedArea area = this.divisions.get(String.valueOf(i));
146
				Distribution distribution = Distribution.NewInstance(area, status);
147
				distribution.addSource(OriginalSourceType.PrimaryTaxonomicSource, null, null, ref, null);
148
				description.addElement(distribution);
149
			}
150
		}
151
	}
152
	
153
	private TaxonDescription getNewDescription(CyprusImportState state, Taxon taxon) {
154
		Reference<?> excelRef = state.getConfig().getSourceReference();
155
		TaxonDescription desc = TaxonDescription.NewInstance(taxon, false);
156
		desc.setTitleCache(excelRef.getTitleCache() + " for " + taxon.getTitleCache(), true);
157
		desc.addSource(OriginalSourceType.Import, null, null, excelRef, null);
158
		return desc;
159
	}
160

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

    
188
	private PresenceAbsenceTerm getStatus(Taxon taxon) {
189
		Set<PresenceAbsenceTerm> statusSet = new HashSet<PresenceAbsenceTerm>();
190
		Set<Distribution> existingDistributions = getExistingDistributions(taxon);
191
		if (existingDistributions.size() > 1){
192
			logger.warn("There is more than 1 distribution: " + taxon.getTitleCache());
193
		}
194
		for (Distribution distribution: existingDistributions){
195
			PresenceAbsenceTerm status = distribution.getStatus();
196
			statusSet.add(status);
197
		}
198
		
199
		if (statusSet.size() == 0){
200
			logger.warn("No status found for: " +  taxon.getTitleCache());
201
			return null;
202
		}else if (statusSet.size() == 1){
203
			return statusSet.iterator().next();
204
		}else{
205
			logger.warn("More than 1 status found. Return first: " +  taxon.getTitleCache());
206
			return statusSet.iterator().next();
207
		}
208
	}
209

    
210
	/**
211
	 * @param taxon
212
	 * @param statusSet
213
	 */
214
	private void removeDistributions(Taxon taxon) {
215
		Set<Distribution> toRemove = new HashSet<Distribution>();
216
		for (TaxonDescription desc : taxon.getDescriptions()){
217
			if (desc.isImageGallery() == NO_IMAGE_GALLERY ){
218
				Iterator<DescriptionElementBase> iterator = desc.getElements().iterator();
219
				while (iterator.hasNext()){
220
					DescriptionElementBase element = iterator.next();
221
					if (element.isInstanceOf(Distribution.class)){
222
						toRemove.add(CdmBase.deproxy(element, Distribution.class));
223
//						iterator.remove();
224
					}
225
				}
226
			}
227
		}
228
		for (Distribution distribution : toRemove){
229
			DescriptionBase<?> desc = distribution.getInDescription();
230
			desc.removeElement(distribution);
231
			getDescriptionService().saveOrUpdate(desc);
232
		}
233
		return;
234
	}
235
	
236
	/**
237
	 * @param taxon
238
	 * @param statusSet
239
	 */
240
	private Set<Distribution> getExistingDistributions(Taxon taxon) {
241
		Set<Distribution> result = new HashSet<Distribution>();
242
		for (TaxonDescription desc : taxon.getDescriptions()){
243
			if (desc.isImageGallery() == NO_IMAGE_GALLERY ){
244
				for (DescriptionElementBase element : desc.getElements()){
245
					if (element.isInstanceOf(Distribution.class)){
246
						Distribution distribution = CdmBase.deproxy(element, Distribution.class);
247
						result.add(distribution);
248
					}
249
				}
250
			}
251
		}
252
		return result;
253
	}
254
	
255
	private Reference<?> getReference(String referenceStr) {
256
		Reference<?> result;
257
		if ("Meikle 1977".equals(referenceStr)){
258
			result = refMeikle1977;
259
		}else if("Meikle 1985".equals(referenceStr)){
260
			result = refMeikle1985;
261
		}else{
262
			logger.warn("Reference not recognized: " + referenceStr);
263
			result = null;
264
		}
265
		return result;
266
	}
267

    
268
	private Taxon getTaxon(CyprusImportState state, String taxonStr) {
269
		Taxon result;
270

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

    
291
	
292

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

    
317
	/**
318
	 * @param meikle1977List
319
	 */
320
	private void loadReferences() {
321
		Pager<Reference> meikle1977List = getReferenceService().findByTitle(Reference.class, "R. D. Meikle, Flora of Cyprus 1. 1977", null, null, null, null, null, null);
322
		
323
		if (meikle1977List.getCount() != 1){
324
			logger.error("There is not exactly 1 Meikle 1977 reference");
325
		}else{
326
			refMeikle1977 = meikle1977List.getRecords().iterator().next();
327
		}
328
		
329
		Pager<Reference> meikle1985List = getReferenceService().findByTitle(Reference.class, "R. D. Meikle, Flora of Cyprus 2. 1985", null, null, null, null, null, null);
330
		if (meikle1985List.getCount() != 1){
331
			logger.error("There is not exactly 1 Meikle 1985 reference");
332
		}else{
333
			refMeikle1985 = meikle1977List.getRecords().iterator().next();
334
		}
335
	}
336

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

    
348
	/**
349
	 * @param state
350
	 * @param transformer
351
	 * @throws UndefinedTransformerMethodException
352
	 */
353
	private void makeNewDivisions(CyprusImportState state,
354
			IInputTransformer transformer)
355
			throws UndefinedTransformerMethodException {
356
		NamedAreaType areaType = NamedAreaType.NATURAL_AREA();
357
		NamedAreaLevel areaLevel = (NamedAreaLevel)getTermService().find(CyprusTransformer.uuidCyprusDivisionsAreaLevel);
358
		if (areaLevel == null){
359
			areaLevel = NamedAreaLevel.NewInstance("Cyprus Division", "Cyprus Division", null);
360
			getTermService().save(areaLevel);
361
		}
362
		
363
		TermVocabulary<NamedArea> areaVocabulary = getVocabulary(TermType.NamedArea, CyprusTransformer.uuidCyprusDivisionsVocabulary, "Cyprus devisions", "Cyprus divisions", null, null, true, NamedArea.NewInstance());
364
		NamedArea tdwg4Cyprus = (NamedArea)getTermService().find(UUID.fromString("9d447b51-e363-4dde-ae40-84c55679983c"));
365
		Country isoCountryCyprus = (Country)getTermService().find(UUID.fromString("4b13d6b8-7eca-4d42-8172-f2018051ca19"));
366
		
367
		for(int i = 1; i <= 8; i++){
368
			UUID divisionUuid = transformer.getNamedAreaUuid(String.valueOf(i));
369
			NamedArea division = this.getNamedArea(state, divisionUuid, "Division " + i, "Cyprus: Division " + i, String.valueOf(i), areaType, areaLevel, areaVocabulary, null);
370
			divisions.put(String.valueOf(i), division);
371
			tdwg4Cyprus.addIncludes(division);
372
			isoCountryCyprus.addIncludes(division);
373
			getTermService().save(division);
374
		}
375
	}
376

    
377
	
378
	/* (non-Javadoc)
379
	 * @see eu.etaxonomy.cdm.io.excel.common.ExcelImporterBase#analyzeRecord(java.util.HashMap, eu.etaxonomy.cdm.io.excel.common.ExcelImportState)
380
	 */
381
	@Override
382
    protected void analyzeRecord(HashMap<String, String> record, CyprusImportState state) {
383
		
384
    	Set<String> keys = record.keySet();
385
    	CyprusDistributionRow cyprusDistributionRow = new CyprusDistributionRow();
386
    	state.setCyprusDistributionRow(cyprusDistributionRow);
387
    	
388
    	for (String originalKey: keys) {
389
    		String indexedKey = CdmUtils.removeDuplicateWhitespace(originalKey.trim()).toString();
390
    		String[] split = indexedKey.split("_");
391
    		String key = split[0];
392
    		if (split.length > 1){
393
    			String indexString = split[1];
394
    			try {
395
					Integer.valueOf(indexString);
396
				} catch (NumberFormatException e) {
397
					String message = "Index must be integer";
398
					logger.error(message);
399
					continue;
400
				}
401
    		}
402
    		
403
    		String value = (String) record.get(indexedKey);
404
    		if (! StringUtils.isBlank(value)) {
405
    			if (logger.isDebugEnabled()) { logger.debug(key + ": " + value); }
406
        		value = CdmUtils.removeDuplicateWhitespace(value.trim()).toString();
407
    		}else{
408
    			continue;
409
    		}
410
    		
411
    		
412
    		if (key.equalsIgnoreCase(SPECIES_COLUMN)) {
413
    			cyprusDistributionRow.setSpecies(value);
414
    			
415
			} else if(key.equalsIgnoreCase(DISTRIBUTION_COLUMN)) {
416
				cyprusDistributionRow.setDistribution(value);
417
				
418
			} else if(key.equalsIgnoreCase(REFERENCE_COLUMN)) {
419
				cyprusDistributionRow.setReference(value);
420
    			
421
			} else {
422
				state.setUnsuccessfull();
423
				logger.error("Unexpected column header " + key);
424
			}
425
    	}
426
    	return;
427
    }
428
	
429
	
430
	/** 
431
	 *  
432
	 */
433
	@Override
434
    protected void secondPass(CyprusImportState state) {
435
		//no second pass for this import
436
		return;
437
	}
438
	
439
	@Override
440
	protected boolean isIgnore(CyprusImportState state) {
441
		return ! state.getConfig().isDoDistribution();
442
	}
443
	
444
}
(1-1/8)