Project

General

Profile

Download (14.7 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.ExcelImportBase;
30
import eu.etaxonomy.cdm.io.excel.common.ExcelRowBase;
31
import eu.etaxonomy.cdm.model.common.CdmBase;
32
import eu.etaxonomy.cdm.model.common.OriginalSourceType;
33
import eu.etaxonomy.cdm.model.common.TermType;
34
import eu.etaxonomy.cdm.model.common.TermVocabulary;
35
import eu.etaxonomy.cdm.model.description.DescriptionBase;
36
import eu.etaxonomy.cdm.model.description.DescriptionElementBase;
37
import eu.etaxonomy.cdm.model.description.Distribution;
38
import eu.etaxonomy.cdm.model.description.PresenceAbsenceTerm;
39
import eu.etaxonomy.cdm.model.description.TaxonDescription;
40
import eu.etaxonomy.cdm.model.location.Country;
41
import eu.etaxonomy.cdm.model.location.NamedArea;
42
import eu.etaxonomy.cdm.model.location.NamedAreaLevel;
43
import eu.etaxonomy.cdm.model.location.NamedAreaType;
44
import eu.etaxonomy.cdm.model.name.TaxonName;
45
import eu.etaxonomy.cdm.model.reference.Reference;
46
import eu.etaxonomy.cdm.model.reference.ReferenceFactory;
47
import eu.etaxonomy.cdm.model.taxon.Taxon;
48

    
49
/**
50
 * @author a.babadshanjan
51
 * @since 08.01.2009
52
 */
53

    
54
@Component
55
public class CyprusDistributionImport
56
       extends ExcelImportBase<CyprusImportState, CyprusImportConfigurator, ExcelRowBase> {
57
    private static final long serialVersionUID = -8527569026580975181L;
58
    private static final Logger logger = Logger.getLogger(CyprusDistributionImport.class);
59

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

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

    
71

    
72
	private Reference refMeikle1977 = ReferenceFactory.newGeneric();
73
	private Reference refMeikle1985 = ReferenceFactory.newGeneric();
74

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

    
78

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

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

    
89
				loadReferences();
90
				loadStatus();
91
				loadTaxa();
92

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

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

    
109
		makeAreasAndReference(state);
110

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

    
125
		return;
126
    }
127

    
128

    
129
	protected static final boolean CREATE = true;
130
	protected static final boolean CREATE_NOT = false;
131
	protected static final boolean NO_IMAGE_GALLERY = false;
132
	protected static final boolean IMAGE_GALLERY = false;
133

    
134
	private void makeDistribution(CyprusImportState state, Taxon taxon, String distributionStr, Reference ref) {
135

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

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

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

    
160
	private PresenceAbsenceTerm indigenousStatus;
161
	private PresenceAbsenceTerm casualStatus;
162
	private PresenceAbsenceTerm nonInvasiveStatus;
163
	private PresenceAbsenceTerm invasiveStatus;
164
	private PresenceAbsenceTerm questionableStatus;
165

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

    
184
		return status;
185
	}
186

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

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

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

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

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

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

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

    
290

    
291

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

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

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

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

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

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

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

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

    
376

    
377
	@Override
378
    protected void analyzeRecord(Map<String, String> record, CyprusImportState state) {
379

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

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

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

    
407

    
408
    		if (key.equalsIgnoreCase(SPECIES_COLUMN)) {
409
    			cyprusDistributionRow.setSpecies(value);
410

    
411
			} else if(key.equalsIgnoreCase(DISTRIBUTION_COLUMN)) {
412
				cyprusDistributionRow.setDistribution(value);
413

    
414
			} else if(key.equalsIgnoreCase(REFERENCE_COLUMN)) {
415
				cyprusDistributionRow.setReference(value);
416

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

    
425

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

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

    
440
}
(1-1/7)