Project

General

Profile

Download (19.6 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.cuba;
11

    
12
import java.util.Arrays;
13
import java.util.HashMap;
14
import java.util.List;
15
import java.util.Set;
16
import java.util.UUID;
17

    
18
import org.apache.commons.lang.StringUtils;
19
import org.apache.log4j.Logger;
20
import org.springframework.stereotype.Component;
21

    
22
import eu.etaxonomy.cdm.common.CdmUtils;
23
import eu.etaxonomy.cdm.io.common.mapping.UndefinedTransformerMethodException;
24
import eu.etaxonomy.cdm.io.cyprus.CyprusRow;
25
import eu.etaxonomy.cdm.io.excel.common.ExcelImporterBase;
26
import eu.etaxonomy.cdm.model.common.Annotation;
27
import eu.etaxonomy.cdm.model.common.AnnotationType;
28
import eu.etaxonomy.cdm.model.common.Language;
29
import eu.etaxonomy.cdm.model.description.Distribution;
30
import eu.etaxonomy.cdm.model.description.Feature;
31
import eu.etaxonomy.cdm.model.description.PresenceAbsenceTerm;
32
import eu.etaxonomy.cdm.model.description.TaxonDescription;
33
import eu.etaxonomy.cdm.model.description.TextData;
34
import eu.etaxonomy.cdm.model.location.NamedArea;
35
import eu.etaxonomy.cdm.model.name.BotanicalName;
36
import eu.etaxonomy.cdm.model.name.NomenclaturalCode;
37
import eu.etaxonomy.cdm.model.name.NonViralName;
38
import eu.etaxonomy.cdm.model.name.Rank;
39
import eu.etaxonomy.cdm.model.name.TaxonNameBase;
40
import eu.etaxonomy.cdm.model.reference.Reference;
41
import eu.etaxonomy.cdm.model.taxon.Classification;
42
import eu.etaxonomy.cdm.model.taxon.Synonym;
43
import eu.etaxonomy.cdm.model.taxon.SynonymRelationshipType;
44
import eu.etaxonomy.cdm.model.taxon.Taxon;
45
import eu.etaxonomy.cdm.model.taxon.TaxonBase;
46
import eu.etaxonomy.cdm.model.taxon.TaxonNode;
47
import eu.etaxonomy.cdm.strategy.parser.INonViralNameParser;
48
import eu.etaxonomy.cdm.strategy.parser.NonViralNameParserImpl;
49

    
50
/**
51
 * @author a.mueller
52
 * @created 05.01.2016
53
 */
54

    
55
@Component
56
public class CubaExcelImport extends ExcelImporterBase<CubaImportState> {
57
    private static final long serialVersionUID = -747486709409732371L;
58

    
59
    private static final Logger logger = Logger.getLogger(CubaExcelImport.class);
60

    
61
    private static INonViralNameParser<?> nameParser = NonViralNameParserImpl.NewInstance();
62
    private static NomenclaturalCode nc = NomenclaturalCode.ICNAFP;
63

    
64
    private  static List<String> expectedKeys= Arrays.asList(new String[]{"Fam.","(Fam.)","Taxón","(Notas)","Syn.","End","Ind","Ind? D","Nat","Dud P","Adv","Cult C","CuW","PR PR*","Art","Hab(*)","May","Mat","IJ","CuC","VC","Ci","SS","CA","Cam","LT","CuE","Gr","Ho","SC","Gu","Esp","Ja","PR","Men","Bah","Cay","AmN","AmC","AmS","VM"});
65

    
66
    private  static List<String> dummy= Arrays.asList(new String[]{
67
            "(Fam.)","Syn.","Ind? D","Nat","Dud P","Adv","Cult C",
68
            "CuW","PR PR*","Art","Hab(*)","May","Mat","IJ",
69
            "CuC","VC","Ci","SS","CA","Cam","LT",
70
            "CuE","Gr","Ho","SC","Gu",
71
            "Esp","Ja","PR","Men","Bah","Cay",
72
            "AmN","AmC","AmS","VM"});
73

    
74

    
75
	@Override
76
    protected void analyzeRecord(HashMap<String, String> record, CubaImportState state) {
77

    
78
		Set<String> keys = record.keySet();
79
        for (String key: keys) {
80
            if (! expectedKeys.contains(key)){
81
                logger.warn("Unexpected Key: " + key);
82
            }
83
        }
84

    
85
        //Fam.
86
        TaxonNode familyTaxon = getFamilyTaxon(record, state);
87
        if (familyTaxon == null){
88
            logger.warn("Family not recognized. Do not handle row");
89
            return;
90
        }
91

    
92
        //(Fam.)
93
        //TODO
94

    
95
        //Taxón
96
        Taxon taxon = makeTaxon(record, state, familyTaxon);
97

    
98
        //(Notas)
99
        makeNotes(record, state, taxon);
100

    
101
        //Syn.
102
        makeSynonyms(record, state, taxon);
103

    
104
        //End, Ind, Ind? D, Nat N, Dud P, Adv A, Cult C
105
        makeCubanDistribution(record, state, taxon);
106

    
107
    	return;
108
    }
109

    
110

    
111
    /**
112
     * @param record
113
     * @param state
114
     * @param taxon
115
     */
116
    private void makeCubanDistribution(HashMap<String, String> record, CubaImportState state, Taxon taxon) {
117
        try {
118
            NamedArea cuba = getNamedArea(state, state.getTransformer().getNamedAreaUuid("C"), null, null, null, null, null);
119
            TaxonDescription desc = getTaxonDescription(taxon, false, true);
120
            PresenceAbsenceTerm status =  makeCubanStatus(record, state);
121
            Distribution distribution = Distribution.NewInstance(cuba, status);
122
            desc.addElement(distribution);
123
        } catch (UndefinedTransformerMethodException e) {
124
            e.printStackTrace();
125
        }
126
    }
127

    
128

    
129
    /**
130
     * @param record
131
     * @param state
132
     * @return
133
     * @throws UndefinedTransformerMethodException
134
     */
135
    private PresenceAbsenceTerm makeCubanStatus(HashMap<String, String> record, CubaImportState state) throws UndefinedTransformerMethodException {
136
        boolean isAbsent = false;  //TODO
137

    
138
        String endemicStr = getValue(record, "End");
139
        String indigenousStr = getValue(record, "Ind");
140
        String indigenousDoubtStr = getValue(record, "Ind? D");
141
        String naturalisedStr = getValue(record, "Nat");
142
        String dudStr = getValue(record, "Dud P");
143
        String advStr = getValue(record, "Adv");
144
        String cultStr = getValue(record, "Cult C");
145

    
146
        if (endemicStr != null){
147
            boolean allNull = checkAllNull(indigenousStr, indigenousDoubtStr, naturalisedStr, dudStr, advStr, cultStr);
148
            if (!endemicStr.equals("+")){
149
                logger.warn("Endemic not recognized: " + endemicStr);
150
                return null;
151
            }else if (! allNull){
152
                logger.warn("Cuban state is endemic but others exist");
153
                return null;
154
            }else{
155
                return PresenceAbsenceTerm.ENDEMIC_FOR_THE_RELEVANT_AREA();
156
            }
157
        }else if (indigenousStr != null){
158
            boolean allNull = checkAllNull(indigenousDoubtStr, naturalisedStr, dudStr, advStr, cultStr);
159
            if (!checkPlusMinus(indigenousStr)){
160
                logger.warn("Indigenous not recognized: " + indigenousStr);
161
                return null;
162
            }else if (! allNull){
163
                //TODO may this exist?
164
                logger.warn("Cuban state is indigenous but others exist");
165
                return null;
166
            }else if(indigenousStr.equals("+")){
167
                UUID indigenousUuid = state.getTransformer().getPresenceTermUuid("Ind.");
168
                PresenceAbsenceTerm indigenousState = getPresenceTerm(state, indigenousUuid, null, null, null);
169
                return indigenousState;
170
            }else if(indigenousStr.equals("-") || indigenousStr.equals("–")){
171
                logger.warn("Indigenous status '-' not yet handled)");
172
                return PresenceAbsenceTerm.ABSENT();
173
            }else{
174
                logger.warn("Indigenous not recognized: " + indigenousStr);
175
                return null;
176
            }
177
        }else if(indigenousDoubtStr != null){
178

    
179
        }
180

    
181
        return null;
182
    }
183

    
184

    
185
    /**
186
     * @param indigenousStr
187
     * @return
188
     */
189
    private boolean checkPlusMinus(String str) {
190
        return str.equals("+") || str.equals("-") || str.equals("–");
191
    }
192

    
193

    
194
    /**
195
     * @param indigenousStr
196
     * @param indigenousDoubtStr
197
     * @param naturalisedStr
198
     * @param dudStr
199
     * @param advStr
200
     * @param cultStr
201
     */
202
    private boolean checkAllNull(String ... others) {
203
        for (String other : others){
204
            if (other != null){
205
                return false;
206
            }
207
        }
208
        return true;
209
    }
210

    
211

    
212
    /**
213
     * @param record
214
     * @param state
215
     * @param taxon
216
     */
217
    private void makeSynonyms(HashMap<String, String> record, CubaImportState state, Taxon taxon) {
218
        // TODO Auto-generated method stub
219

    
220
    }
221

    
222

    
223
    /**
224
     * @param record
225
     * @param state
226
     * @param taxon
227
     */
228
    private void makeNotes(HashMap<String, String> record, CubaImportState state, Taxon taxon) {
229
        String notesStr = getValue(record, "(Notas)");
230
        if (notesStr == null){
231
            return;
232
        }else{
233
            Annotation annotation = Annotation.NewDefaultLanguageInstance(notesStr);
234
            //TODO
235
            annotation.setAnnotationType(AnnotationType.EDITORIAL());
236
            taxon.addAnnotation(annotation);
237
        }
238
    }
239

    
240

    
241
    /**
242
     * @param record
243
     * @param state
244
     * @param familyTaxon
245
     * @return
246
     */
247
    private Taxon makeTaxon(HashMap<String, String> record, CubaImportState state, TaxonNode familyNode) {
248
        String taxonStr = getValue(record, "Taxón");
249
        if (taxonStr == null){
250
            return null;
251
        }
252
        boolean isAbsent = false;
253
        if (taxonStr.startsWith("[") && taxonStr.endsWith("]")){
254
            taxonStr = taxonStr.substring(1, taxonStr.length() - 1);
255
            isAbsent = true;
256
        }
257

    
258
        TaxonNameBase<?,?> botanicalName = nameParser.parseFullName(taxonStr, nc, Rank.SPECIES());
259
        if (botanicalName.isProtectedTitleCache()){
260
            logger.warn("Taxon could not be parsed: " + taxonStr);
261
        }
262
        Reference<?> sec = null;
263
        Taxon taxon = Taxon.NewInstance(botanicalName, sec);
264
        familyNode.addChildTaxon(taxon, null, null);
265

    
266
        return taxon;
267
    }
268

    
269

    
270
    /**
271
     * @param record
272
     * @param state
273
     * @return
274
     */
275
    private TaxonNode getFamilyTaxon(HashMap<String, String> record, CubaImportState state) {
276
        String familyStr = getValue(record, "Fam.");
277
        if (familyStr == null){
278
            return null;
279
        }
280
        Taxon family = state.getHigherTaxon(familyStr);
281
        TaxonNode familyNode;
282
        if (family != null){
283
            familyNode = family.getTaxonNodes().iterator().next();
284
        }else{
285
            BotanicalName name = BotanicalName.NewInstance(Rank.FAMILY());
286
            name.setGenusOrUninomial(familyStr);
287
            Reference<?> sec = null;
288
            Taxon taxon = Taxon.NewInstance(name, sec);
289
            Classification classification = getClassification(state);
290
            familyNode = classification.addChildTaxon(taxon, sec, null);
291
        }
292

    
293
        return familyNode;
294
    }
295

    
296

    
297
    /**
298
     * @param state
299
     * @return
300
     */
301
    private Classification getClassification(CubaImportState state) {
302
        Classification classification = state.getClassification();
303
        if (classification == null){
304
            String name = state.getConfig().getClassificationName();
305
            //TODO
306
            Reference<?> sec = null;
307
            Language language = Language.DEFAULT();
308
            classification = Classification.NewInstance(name, sec, language);
309
            state.setClassification(classification);
310
            getClassificationService().save(classification);
311
        }
312
        return classification;
313
    }
314

    
315

    
316
    /**
317
     * @param record
318
     * @param originalKey
319
     * @return
320
     */
321
    private String getValue(HashMap<String, String> record, String originalKey) {
322
        String value = record.get(originalKey);
323
        if (! StringUtils.isBlank(value)) {
324
        	if (logger.isDebugEnabled()) { logger.debug(originalKey + ": " + value); }
325
        	value = CdmUtils.removeDuplicateWhitespace(value.trim()).toString();
326
        	return value;
327
        }else{
328
        	return null;
329
        }
330
    }
331

    
332

    
333
	private Feature redBookCategory;
334
	private Feature endemism;
335

    
336

    
337

    
338
	/**
339
	 *  Stores taxa records in DB
340
	 */
341
	@Override
342
    protected void firstPass(CubaImportState state) {
343

    
344
		CyprusRow taxonLight = null; //state.getCyprusRow();
345
		Reference<?> citation = null;
346
		String microCitation = null;
347

    
348
//		//species name
349
//		String speciesStr = taxonLight.getSpecies();
350
//		String subSpeciesStr = taxonLight.getSubspecies();
351
//		String homotypicSynonymsString = taxonLight.getHomotypicSynonyms();
352
//		List<String> homotypicSynonymList = Arrays.asList(homotypicSynonymsString.split(";"));
353
//		String heterotypicSynonymsString = taxonLight.getHeterotypicSynonyms();
354
//		List<String> heterotypicSynonymList = Arrays.asList(heterotypicSynonymsString.split(";"));
355
//
356
//		String systematicsString = taxonLight.getSystematics();
357
//		String endemismString = taxonLight.getEndemism();
358
//		String statusString = taxonLight.getStatus();
359
//		String redBookCategory = taxonLight.getRedDataBookCategory();
360
//
361
//		if (StringUtils.isNotBlank(speciesStr)) {
362
//			boolean speciesIsExisting = false;
363
//			Taxon mainTaxon = null;
364
//			//species
365
//			Taxon speciesTaxon = (Taxon)createTaxon(state, Rank.SPECIES(), speciesStr, Taxon.class, nc);
366
//			mainTaxon = speciesTaxon;
367
//
368
//			//subspecies
369
//			if (StringUtils.isNotBlank(subSpeciesStr)){
370
//				Taxon existingSpecies = state.getHigherTaxon(speciesStr);
371
//				if (existingSpecies != null){
372
//					speciesIsExisting = true;
373
//					speciesTaxon = existingSpecies;
374
//				}
375
//
376
//				Taxon subSpeciesTaxon = (Taxon)createTaxon(state, Rank.SUBSPECIES(), subSpeciesStr, Taxon.class, nc);
377
//
378
//				if (subSpeciesTaxon != null){
379
//					makeParent(state, speciesTaxon, subSpeciesTaxon, citation, microCitation);
380
//				}
381
//				mainTaxon = subSpeciesTaxon;
382
//				state.putHigherTaxon(speciesStr, speciesTaxon);
383
//			}
384
//
385
//			if (! speciesIsExisting){
386
//				makeHigherTaxa(state, taxonLight, speciesTaxon, citation, microCitation);
387
//			}
388
//			makeHomotypicSynonyms(state, citation, microCitation, homotypicSynonymList, mainTaxon);
389
//			makeHeterotypicSynonyms(state, citation, microCitation, heterotypicSynonymList, mainTaxon);
390
//			makeSystematics(systematicsString, mainTaxon);
391
//			makeEndemism(endemismString, mainTaxon);
392
//			makeStatus(statusString, mainTaxon);
393
//			makeRedBookCategory(redBookCategory, mainTaxon);
394
//
395
////			state.putHigherTaxon(higherName, uuid);//(speciesStr, mainTaxon);
396
//			getTaxonService().save(mainTaxon);
397
//		}
398
		return;
399
    }
400

    
401

    
402
	private void makeHigherTaxa(CubaImportState state, CyprusRow taxonLight, Taxon speciesTaxon, Reference citation, String microCitation) {
403
		String divisionStr = taxonLight.getDivision();
404
		String genusStr = taxonLight.getGenus();
405
		String familyStr = taxonLight.getFamily();
406

    
407
		Taxon division = getTaxon(state, divisionStr, Rank.DIVISION(), null, citation, microCitation);
408
		Taxon family = getTaxon(state, familyStr, Rank.FAMILY(), division, citation, microCitation);
409
		Taxon genus = getTaxon(state, genusStr, Rank.GENUS(), family, citation, microCitation);
410
		makeParent(state, genus, speciesTaxon, citation, microCitation)	;
411
	}
412

    
413

    
414
	private Taxon getTaxon(CubaImportState state, String taxonNameStr, Rank rank, Taxon parent, Reference citation, String microCitation) {
415
		Taxon result;
416
		if (state.containsHigherTaxon(taxonNameStr)){
417
			result = state.getHigherTaxon(taxonNameStr);
418
		}else{
419
			result = (Taxon)createTaxon(state, rank, taxonNameStr, Taxon.class, nc);
420
			state.putHigherTaxon(taxonNameStr, result);
421
			if (parent == null){
422
				makeParent(state, null,result, citation, microCitation);
423
			}else{
424
				makeParent(state, parent, result, citation, microCitation);
425
			}
426

    
427
		}
428
		return result;
429
	}
430

    
431

    
432
	private void makeHomotypicSynonyms(CubaImportState state,
433
			Reference citation, String microCitation, List<String> homotypicSynonymList, Taxon mainTaxon) {
434
		for (String homotypicSynonym: homotypicSynonymList){
435
			if (StringUtils.isNotBlank(homotypicSynonym)){
436
				Synonym synonym = (Synonym)createTaxon(state, null, homotypicSynonym, Synonym.class, nc);
437
				mainTaxon.addHomotypicSynonym(synonym, citation, microCitation);
438
			}
439
		}
440
	}
441

    
442

    
443
	private void makeHeterotypicSynonyms(CubaImportState state, Reference citation, String microCitation, List<String> heterotypicSynonymList, Taxon mainTaxon) {
444
		for (String heterotypicSynonym: heterotypicSynonymList){
445
			if (StringUtils.isNotBlank(heterotypicSynonym)){
446
				Synonym synonym = (Synonym)createTaxon(state, null, heterotypicSynonym, Synonym.class, nc);
447
				mainTaxon.addSynonym(synonym, SynonymRelationshipType.HETEROTYPIC_SYNONYM_OF(), citation, microCitation);
448
			}
449
		}
450
	}
451

    
452

    
453
	private void makeSystematics(String systematicsString, Taxon mainTaxon) {
454
		//Systematics
455
		if (StringUtils.isNotBlank(systematicsString)){
456
			TaxonDescription td = this.getTaxonDescription(mainTaxon, false, true);
457
			TextData textData = TextData.NewInstance(Feature.SYSTEMATICS());
458
			textData.putText(Language.UNDETERMINED(), systematicsString);
459
			td.addElement(textData);
460
		}
461
	}
462

    
463

    
464
	private void makeEndemism(String endemismString, Taxon mainTaxon) {
465
		//endemism
466
		if (StringUtils.isNotBlank(endemismString)){
467
			//OLD - not wanted as marker
468
//			boolean flag;
469
//			if (endemismString.trim().equalsIgnoreCase("not endemic") || endemismString.trim().equalsIgnoreCase("ne?")){
470
//				flag = false;
471
//			}else if (endemismString.trim().equalsIgnoreCase("endemic")){
472
//				flag = true;
473
//			}else{
474
//				throw new RuntimeException(endemismString + " is not a valid value for endemism");
475
//			}
476
//			Marker marker = Marker.NewInstance(MarkerType.ENDEMIC(), flag);
477
//			mainTaxon.addMarker(marker);
478
			//text data
479
			TaxonDescription td = this.getTaxonDescription(mainTaxon, false, true);
480
			TextData textData = TextData.NewInstance(endemism);
481
			textData.putText(Language.ENGLISH(), endemismString);
482
			td.addElement(textData);
483
		}
484
	}
485

    
486

    
487
	private void makeRedBookCategory(String redBookCategory, Taxon mainTaxon) {
488
		//red data book category
489
		if (StringUtils.isNotBlank(redBookCategory)){
490
			TaxonDescription td = this.getTaxonDescription(mainTaxon, false, true);
491
			TextData textData = TextData.NewInstance(this.redBookCategory);
492
			textData.putText(Language.ENGLISH(), redBookCategory);
493
			td.addElement(textData);
494
		}
495
	}
496

    
497

    
498

    
499

    
500
	/**
501
	 *  Stores parent-child, synonym and common name relationships
502
	 */
503
	@Override
504
    protected void secondPass(CubaImportState state) {
505
//		CyprusRow cyprusRow = state.getCyprusRow();
506
		return;
507
	}
508

    
509

    
510

    
511
	/**
512
	 * @param state
513
	 * @param rank
514
	 * @param taxonNameStr
515
	 * @param authorStr
516
	 * @param nameStatus
517
	 * @param nc
518
	 * @return
519
	 */
520
	private TaxonBase createTaxon(CubaImportState state, Rank rank, String taxonNameStr,
521
			Class statusClass, NomenclaturalCode nc) {
522
		TaxonBase taxonBase;
523
		NonViralName taxonNameBase = null;
524
		if (nc == NomenclaturalCode.ICVCN){
525
			logger.warn("ICVCN not yet supported");
526

    
527
		}else{
528
			taxonNameBase =(NonViralName) nc.getNewTaxonNameInstance(rank);
529
			//NonViralName nonViralName = (NonViralName)taxonNameBase;
530
			INonViralNameParser parser = nameParser;//NonViralNameParserImpl.NewInstance();
531
			taxonNameBase = (NonViralName<BotanicalName>)parser.parseFullName(taxonNameStr, nc, rank);
532

    
533
			//taxonNameBase.setNameCache(taxonNameStr);
534

    
535
		}
536

    
537
		//Create the taxon
538
		Reference sec = state.getConfig().getSourceReference();
539
		// Create the status
540
		if (statusClass.equals(Taxon.class)){
541
			taxonBase = Taxon.NewInstance(taxonNameBase, sec);
542
		}else if (statusClass.equals(Synonym.class)){
543
			taxonBase = Synonym.NewInstance(taxonNameBase, sec);
544
		}else {
545
			Taxon taxon = Taxon.NewInstance(taxonNameBase, sec);
546
			taxon.setTaxonStatusUnknown(true);
547
			taxonBase = taxon;
548
		}
549
		return taxonBase;
550
	}
551

    
552
	private boolean makeParent(CubaImportState state, Taxon parentTaxon, Taxon childTaxon, Reference citation, String microCitation){
553
		boolean success = true;
554
		Reference sec = state.getConfig().getSourceReference();
555

    
556
//		Reference sec = parentTaxon.getSec();
557
		Classification tree = state.getTree(sec);
558
		if (tree == null){
559
			tree = makeTree(state, sec);
560
			tree.setTitleCache(state.getConfig().getSourceReferenceTitle(), true);
561
		}
562
		if (sec.equals(childTaxon.getSec())){
563
			success &=  (null !=  tree.addParentChild(parentTaxon, childTaxon, citation, microCitation));
564
		}else{
565
			logger.warn("No relationship added for child " + childTaxon.getTitleCache());
566
		}
567
		return success;
568
	}
569

    
570

    
571
    @Override
572
    protected boolean isIgnore(CubaImportState state) {
573
        return ! state.getConfig().isDoTaxa();
574
    }
575

    
576
    @Override
577
    protected boolean doCheck(CubaImportState state) {
578
        logger.warn("DoCheck not yet implemented for CubaExcelImport");
579
        return true;
580
    }
581

    
582
}
(1-1/5)