Project

General

Profile

Download (27.2 KB) Statistics
| Branch: | Revision:
1
/**
2
* Copyright (C) 2016 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
package eu.etaxonomy.cdm.io.greece;
10

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

    
18
import org.apache.log4j.Logger;
19
import org.springframework.stereotype.Component;
20

    
21
import eu.etaxonomy.cdm.common.CdmUtils;
22
import eu.etaxonomy.cdm.io.mexico.SimpleExcelTaxonImportState;
23
import eu.etaxonomy.cdm.model.common.Language;
24
import eu.etaxonomy.cdm.model.common.OrderedTermVocabulary;
25
import eu.etaxonomy.cdm.model.description.CategoricalData;
26
import eu.etaxonomy.cdm.model.description.DescriptionElementBase;
27
import eu.etaxonomy.cdm.model.description.Distribution;
28
import eu.etaxonomy.cdm.model.description.Feature;
29
import eu.etaxonomy.cdm.model.description.PresenceAbsenceTerm;
30
import eu.etaxonomy.cdm.model.description.State;
31
import eu.etaxonomy.cdm.model.description.TaxonDescription;
32
import eu.etaxonomy.cdm.model.location.NamedArea;
33
import eu.etaxonomy.cdm.model.name.BotanicalName;
34
import eu.etaxonomy.cdm.model.name.Rank;
35
import eu.etaxonomy.cdm.model.name.TaxonNameFactory;
36
import eu.etaxonomy.cdm.model.reference.Reference;
37
import eu.etaxonomy.cdm.model.taxon.Classification;
38
import eu.etaxonomy.cdm.model.taxon.ITaxonTreeNode;
39
import eu.etaxonomy.cdm.model.taxon.Taxon;
40
import eu.etaxonomy.cdm.model.taxon.TaxonNode;
41
import eu.etaxonomy.cdm.strategy.parser.NonViralNameParserImpl;
42

    
43
/**
44
 * @author a.mueller
45
 * @date 14.12.2016
46
 *
47
 */
48

    
49
@Component
50
public class FloraHellenicaTaxonImport<CONFIG extends FloraHellenicaImportConfigurator>
51
            extends FloraHellenicaImportBase<CONFIG>{
52

    
53
    private static final long serialVersionUID = -6291948918967763381L;
54
    private static final Logger logger = Logger.getLogger(FloraHellenicaTaxonImport.class);
55

    
56
    private static final String LIFE_FORM = "Life-form";
57
    private static final String STATUS = "Status";
58
    private static final String CHOROLOGICAL_CATEGOGY = "Chorological categogy";
59

    
60
    private static UUID rootUuid = UUID.fromString("aa667b0b-b417-470e-a9b0-ef9409a3431e");
61
    private static UUID plantaeUuid = UUID.fromString("4f151932-ab97-4d81-b88e-46fe82cd3e88");
62

    
63
    private Map<String, State> lifeformMap = new HashMap<>();
64
    private Map<String, State> chorologyMap = new HashMap<>();
65
    private PresenceAbsenceTerm rangeRestricted;
66
    private PresenceAbsenceTerm doubtfullyRangeRestricted;
67
    private OrderedTermVocabulary<State> habitatVoc;
68
    private OrderedTermVocabulary<State> statusVoc;
69

    
70

    
71

    
72
   private  static List<String> expectedKeys= Arrays.asList(new String[]{
73
            "Unique ID","uuid","Group","Family","Genus","Species","Species Author","Subspecies","Subspecies Author",
74
            "IoI","NPi","SPi","Pe","StE","EC","NC","NE","NAe","WAe","Kik","KK","EAe",
75
            STATUS,CHOROLOGICAL_CATEGOGY,LIFE_FORM,"A","C","G","H","M","P","R","W", "Taxon"
76
    });
77

    
78
    private String lastGenus;
79
    private String lastSpecies;
80
    private NonViralNameParserImpl parser = NonViralNameParserImpl.NewInstance();
81

    
82
    @Override
83
    protected String getWorksheetName() {
84
        return "valid taxa names";
85
    }
86

    
87
    /**
88
     * {@inheritDoc}
89
     */
90
    @Override
91
    protected void firstPass(SimpleExcelTaxonImportState<CONFIG> state) {
92
        initLifeFormMap();
93
        initChorologyMap();
94
        initOtherTerms(state);
95

    
96
        String line = state.getCurrentLine() + ": ";
97
        HashMap<String, String> record = state.getOriginalRecord();
98

    
99
        Set<String> keys = record.keySet();
100
        for (String key: keys) {
101
            if (! expectedKeys.contains(key)){
102
                logger.warn(line + "Unexpected Key: " + key);
103
            }
104
        }
105

    
106
        String noStr = getValue(record, "Unique ID");
107
        Taxon taxon = makeTaxon(state, line, record, noStr);
108

    
109
        //Distribution
110
        TaxonDescription desc = getTaxonDescription(taxon);
111
        makeDistribution(state, line, noStr, desc);
112

    
113
        makeChorologicalCategory(state, line, noStr, desc);
114

    
115
        //lifeform
116
        makeLifeform(state, line, noStr, desc);
117

    
118
        //habitat
119
        makeHabitat(state, line, noStr, desc);
120

    
121
        state.putTaxon(noStr, taxon);
122

    
123
    }
124

    
125

    
126
    /**
127
     * @param state
128
     *
129
     */
130
    private void initOtherTerms(SimpleExcelTaxonImportState<CONFIG> state) {
131
        if (state.getConfig().isStatusAsDistribution()){
132
            if (rangeRestricted == null){
133
                rangeRestricted = (PresenceAbsenceTerm)getTermService().find(FloraHellenicaTransformer.uuidStatusRangeRestricted);
134
            }
135
            if (this.doubtfullyRangeRestricted == null){
136
                doubtfullyRangeRestricted = (PresenceAbsenceTerm)getTermService().find(FloraHellenicaTransformer.uuidStatusRangeRestrictedDoubtfully);
137
            }
138
        }else{
139
            if (this.statusVoc == null){
140
                @SuppressWarnings("unchecked")
141
                OrderedTermVocabulary<State> voc = (OrderedTermVocabulary<State>) getVocabularyService().find(
142
                        FloraHellenicaTransformer.uuidFloraHellenicaStatusVoc);
143
                statusVoc = voc;
144
            }
145
        }
146
        if (this.habitatVoc == null){
147
            @SuppressWarnings("unchecked")
148
            OrderedTermVocabulary<State> voc = (OrderedTermVocabulary<State>) getVocabularyService().find(
149
                    FloraHellenicaTransformer.uuidFloraHellenicaHabitatVoc);
150
            habitatVoc = voc;
151
        }
152
    }
153

    
154

    
155
    private void initLifeFormMap() {
156
        if (lifeformMap.isEmpty()){
157
            UUID uuid = FloraHellenicaTransformer.uuidFloraHellenicaLifeformVoc;
158
            @SuppressWarnings("unchecked")
159
            OrderedTermVocabulary<State> lifeformVoc = (OrderedTermVocabulary<State>)this.getVocabularyService().find(uuid);
160
            for (State state : lifeformVoc.getTerms()){
161
                lifeformMap.put(state.getIdInVocabulary(), state);
162
            }
163
        }
164
    }
165

    
166
    private void initChorologyMap() {
167
        if (chorologyMap.isEmpty()){
168
            UUID uuid = FloraHellenicaTransformer.uuidFloraHellenicaChorologicalVoc;
169
            @SuppressWarnings("unchecked")
170
            OrderedTermVocabulary<State> voc = (OrderedTermVocabulary<State>)this.getVocabularyService().find(uuid);
171
            for (State state : voc.getTerms()){
172
                chorologyMap.put(state.getIdInVocabulary(), state);
173
            }
174
        }
175
    }
176

    
177

    
178

    
179
    /**
180
     * @param state
181
     * @param line
182
     * @param noStr
183
     * @param desc
184
     */
185
    private void makeChorologicalCategory(SimpleExcelTaxonImportState<CONFIG> state, String line, String noStr,
186
            TaxonDescription desc) {
187

    
188
        HashMap<String, String> record = state.getOriginalRecord();
189
        String valueStr = getValue(record, CHOROLOGICAL_CATEGOGY);
190

    
191
        String value = valueStr;
192
        if (value == null){
193
            return;
194
        }
195
        Feature choroFeature = getFeature(state, FloraHellenicaTransformer.uuidFloraHellenicaChorologyFeature,
196
                "Chorology", "The Chorological Category", "Choro", null);
197
        CategoricalData catData = CategoricalData.NewInstance(choroFeature);
198
        catData.setOrderRelevant(true);
199

    
200
        String[] splits = value.split(" & ");
201
        replaceDirection(splits, line);
202
        for (String split: splits){
203
            String[] splitsA = split.split("/");
204
            for (String splitA : splitsA){
205
                String[] splitsB = splitA.split(", ");
206
                for (String splitB : splitsB){
207
                    splitB = normalizeChorology(splitB);
208
                    State choroTerm = chorologyMap.get(splitB);
209
                    if (choroTerm == null){
210
                        logger.warn(line + "Some chorology could not be recognized in: " + value + "; Term was: " +splitB);
211
                    }else{
212
                        catData.addStateData(choroTerm);
213
                    }
214
                }
215
            }
216
        }
217
        if (catData.getStateData().size() > 1){
218
            catData.setOrderRelevant(true);
219
        }
220
        desc.addElement(catData);
221
    }
222

    
223
    /**
224
     * @param splitB
225
     * @return
226
     */
227
    private String normalizeChorology(String choroStr) {
228
        choroStr = choroStr.trim()
229
                .replace("BK", "Bk")
230
                .replace("Austral.", "Austr.")
231
                .replace("trop.As.", "trop. As.");
232
        if (choroStr.startsWith("[") && !choroStr.endsWith("]")){
233
            choroStr += "]";
234
        }else if (!choroStr.startsWith("[") && choroStr.endsWith("]")){
235
            choroStr = "[" + choroStr;
236
        }
237
        return choroStr;
238
    }
239

    
240
    /**
241
     * @param splits
242
     * @param line
243
     */
244
    private void replaceDirection(String[] splits, String line) {
245
        if (splits.length > 1){
246
            String[] divs = splits[1].split("-");
247
            if (divs.length == 2){
248
                splits[0] = splits[0] + "-" + divs[1];
249
            }else{
250
                logger.warn(line + "Splits[1] has not expected format: " + splits[1]);
251
            }
252
        }
253
    }
254

    
255
    /**
256
     * @param state
257
     * @param line
258
     * @param noStr
259
     * @param desc
260
     */
261
    private void makeLifeform(SimpleExcelTaxonImportState<CONFIG> state, String line, String noStr,
262
            TaxonDescription desc) {
263
        HashMap<String, String> record = state.getOriginalRecord();
264
        String value = getValue(record, LIFE_FORM);
265
        String[] splits = value.split("\\s+");
266
        if (splits.length > 2){
267
            logger.warn("Unexpected length of lifeform: " + value + " line: "  + line );
268
        }
269
        CategoricalData catData = CategoricalData.NewInstance(Feature.LIFEFORM());
270
        for (String split : splits){
271
            State lifeform = lifeformMap.get(split);
272
            if (lifeform == null){
273
                logger.warn(line + "Unexpected lifeform: " + value);
274
            }else{
275
                catData.addStateData(lifeform);
276
            }
277
        }
278
        desc.addElement(catData);
279

    
280
    }
281

    
282
    /**
283
     * @param state
284
     * @param line
285
     * @param noStr
286
     * @param desc
287
     */
288
    private void makeHabitat(SimpleExcelTaxonImportState<CONFIG> state, String line, String noStr,
289
            TaxonDescription desc) {
290
        CategoricalData catData = CategoricalData.NewInstance(Feature.HABITAT());
291
        handleHabitat(state, catData, "A", FloraHellenicaTransformer.uuidHabitatA, line, noStr);
292
        handleHabitat(state, catData, "C", FloraHellenicaTransformer.uuidHabitatC, line, noStr);
293
        handleHabitat(state, catData, "G", FloraHellenicaTransformer.uuidHabitatG, line, noStr);
294
        handleHabitat(state, catData, "H", FloraHellenicaTransformer.uuidHabitatH, line, noStr);
295
        handleHabitat(state, catData, "M", FloraHellenicaTransformer.uuidHabitatM, line, noStr);
296
        handleHabitat(state, catData, "P", FloraHellenicaTransformer.uuidHabitatP, line, noStr);
297
        handleHabitat(state, catData, "R", FloraHellenicaTransformer.uuidHabitatR, line, noStr);
298
        handleHabitat(state, catData, "W", FloraHellenicaTransformer.uuidHabitatW, line, noStr);
299
        desc.addElement(catData);
300
    }
301

    
302
    /**
303
     * @param state
304
     * @param catData
305
     * @param string
306
     * @param uuidhabitata
307
     * @param line
308
     * @param noStr
309
     */
310
    private void handleHabitat(SimpleExcelTaxonImportState<CONFIG> state, CategoricalData catData, String label,
311
            UUID uuidHabitat, String line, String noStr) {
312
        HashMap<String, String> record = state.getOriginalRecord();
313
        String value = getValue(record, "" + label);
314
        if (value == null){
315
            //do nothing
316
        }else if (value.matches("[ACGHMPRW]")){
317
            State habitatState = this.getStateTerm(state, uuidHabitat, null, null, null, habitatVoc);
318
            catData.addStateData(habitatState);
319
        }else{
320
            logger.warn(line + "Unrecognized habitat state '" + value + "' for " + label);
321
        }
322
    }
323

    
324
    /**
325
     * @param state
326
     * @param line
327
     * @param noStr
328
     * @param desc
329
     */
330
    private void makeDistribution(SimpleExcelTaxonImportState<CONFIG> state, String line, String noStr,
331
            TaxonDescription desc) {
332
        //TODO status Greece
333
        handleStatus(state, desc, STATUS, FloraHellenicaTransformer.uuidAreaGreece, line, noStr);
334

    
335
        handleDistribution(state, desc, "IoI", FloraHellenicaTransformer.uuidAreaIoI, line, noStr);
336
        handleDistribution(state, desc, "NPi", FloraHellenicaTransformer.uuidAreaNPi, line, noStr);
337
        handleDistribution(state, desc, "SPi", FloraHellenicaTransformer.uuidAreaSPi, line, noStr);
338
        handleDistribution(state, desc, "Pe", FloraHellenicaTransformer.uuidAreaPe, line, noStr);
339
        handleDistribution(state, desc, "StE", FloraHellenicaTransformer.uuidAreaStE, line, noStr);
340
        handleDistribution(state, desc, "EC", FloraHellenicaTransformer.uuidAreaEC, line, noStr);
341
        handleDistribution(state, desc, "NC", FloraHellenicaTransformer.uuidAreaNC, line, noStr);
342
        handleDistribution(state, desc, "NE", FloraHellenicaTransformer.uuidAreaNE, line, noStr);
343
        handleDistribution(state, desc, "NAe", FloraHellenicaTransformer.uuidAreaNAe, line, noStr);
344
        handleDistribution(state, desc, "WAe", FloraHellenicaTransformer.uuidAreaWAe, line, noStr);
345
        handleDistribution(state, desc, "Kik", FloraHellenicaTransformer.uuidAreaKik, line, noStr);
346
        handleDistribution(state, desc, "KK", FloraHellenicaTransformer.uuidAreaKK, line, noStr);
347
        handleDistribution(state, desc, "EAe", FloraHellenicaTransformer.uuidAreaEAe, line, noStr);
348
    }
349

    
350
    /**
351
     * @param state
352
     * @param line
353
     * @param record
354
     * @param noStr
355
     * @return
356
     */
357
    private Taxon makeTaxon(SimpleExcelTaxonImportState<CONFIG> state, String line, HashMap<String, String> record,
358
            String noStr) {
359

    
360
        TaxonNode familyTaxon = getFamilyTaxon(record, state);
361
        if (familyTaxon == null){
362
            logger.warn(line + "Family not created: " + record.get("Family"));
363
        }
364

    
365
        String genusStr = getValue(record, "Genus");
366
        String speciesStr = getValue(record, "Species");
367
        String speciesAuthorStr = getValue(record, "Species Author");
368
        String subSpeciesStr = getValue(record, "Subspecies");
369
        String subSpeciesAuthorStr = getValue(record, "Subspecies Author");
370
        String uuidStr = getValue(record, "uuid");
371
        UUID uuid = UUID.fromString(uuidStr);
372
        boolean isSubSpecies = isNotBlank(subSpeciesStr);
373
        boolean isAutonym = isSubSpecies && speciesStr.equals(subSpeciesStr);
374
        if (isSubSpecies && ! isAutonym && isBlank(subSpeciesAuthorStr)){
375
            logger.warn(line + "Non-Autonym subspecies has no auhtor");
376
        }else if (isSubSpecies && isAutonym && isNotBlank(subSpeciesAuthorStr)){
377
            logger.warn(line + "Autonym subspecies has subspecies auhtor");
378
        }
379

    
380
        String[] nameParts;
381
        if (!isSubSpecies){
382
            nameParts = new String[]{genusStr, speciesStr, speciesAuthorStr};
383
        }else if (!isAutonym){
384
            nameParts = new String[]{genusStr, speciesStr, "subsp. " + subSpeciesStr, subSpeciesAuthorStr};
385
        }else{
386
            nameParts = new String[]{genusStr, speciesStr, speciesAuthorStr, "subsp. " + subSpeciesStr};
387
        }
388

    
389
        String nameStr = CdmUtils.concat(" ", nameParts);
390
        boolean isSensuStrictu = false;
391
        if (nameStr.endsWith("s.str.")){
392
            isSensuStrictu = true;
393
            nameStr = nameStr.substring(0, nameStr.length() - "s.str.".length() ).trim();
394
        }
395
        Rank rank = isSubSpecies ? Rank.SUBSPECIES() : Rank.SPECIES();
396
        BotanicalName name = (BotanicalName)parser.parseFullName(nameStr, state.getConfig().getNomenclaturalCode(), rank);
397
        if (name.isProtectedTitleCache()){
398
            logger.warn(line + "Name could not be parsed: " + nameStr);
399
        }
400
        name = replaceNameAuthorsAndReferences(state, name);
401

    
402
        Taxon taxon = Taxon.NewInstance(name, getSecReference(state));
403
        taxon.addImportSource(noStr, getWorksheetName(), getSourceCitation(state), null);
404
        if (isSensuStrictu){
405
            taxon.setAppendedPhrase("s.str.");
406
        }
407
        String parentStr = isSubSpecies ?
408
                makeSpeciesKey(genusStr, speciesStr, speciesAuthorStr) : genusStr;
409
        taxon.setUuid(uuid);
410
        boolean genusAsBefore = genusStr.equals(lastGenus);
411
        boolean speciesAsBefore = speciesStr.equals(lastSpecies);
412
        TaxonNode parent = getParent(state, parentStr);
413
        if (parent != null){
414
            if (!isSubSpecies && genusAsBefore || isSubSpecies && speciesAsBefore){
415
//            if (genusAsBefore ){
416
                    //everything as expected
417
                TaxonNode newNode = parent.addChildTaxon(taxon, getSecReference(state), null);
418
                getTaxonNodeService().saveOrUpdate(newNode);
419
            }else{
420
                logger.warn(line + "Unexpected non-missing parent");
421
            }
422
        }else{
423
            if (isSubSpecies){
424
                logger.warn(line + "Subspecies should always have an existing parent");
425
            }else if (genusAsBefore){
426
                logger.warn(line + "Unexpected missing genus parent");
427
            }else{
428
                parent = makeGenusNode(state, record, genusStr);
429
                TaxonNode newNode = parent.addChildTaxon(taxon, getSecReference(state), null);
430
                getTaxonNodeService().save(newNode);
431
            }
432
        }
433
        if (!isSubSpecies){
434
            state.putHigherTaxon(makeSpeciesKey(genusStr, speciesStr, speciesAuthorStr), taxon);
435
        }
436

    
437
//        this.lastFamily = familyStr
438
        this.lastGenus = genusStr;
439
        this.lastSpecies = speciesStr;
440
        return taxon;
441
    }
442

    
443
    /**
444
     * @param genusStr
445
     * @param speciesStr
446
     * @param speciesAuthorStr
447
     * @return
448
     */
449
    private String makeSpeciesKey(String genusStr, String speciesStr, String speciesAuthorStr) {
450
        return CdmUtils.concat(" ", new String[]{genusStr, speciesStr, speciesAuthorStr});
451
    }
452

    
453
    /**
454
     * @param state
455
     * @param record
456
     * @param genusStr
457
     * @return
458
     */
459
    private TaxonNode makeGenusNode(SimpleExcelTaxonImportState<CONFIG> state,
460
            HashMap<String, String> record, String genusStr) {
461
        BotanicalName name = TaxonNameFactory.NewBotanicalInstance(Rank.GENUS());
462
        name.setGenusOrUninomial(genusStr);
463
        name = replaceNameAuthorsAndReferences(state, name);
464
        Taxon genus = Taxon.NewInstance(name, getSecReference(state));
465
        TaxonNode family = getFamilyTaxon(record, state);
466
        TaxonNode genusNode = family.addChildTaxon(genus, getSecReference(state), null);
467
        state.putHigherTaxon(genusStr, genus);
468
        genus.addSource(makeOriginalSource(state));
469
        getTaxonNodeService().save(genusNode);
470
        return genusNode;
471
    }
472

    
473
    /**
474
     * @param state
475
     * @param parentStr
476
     * @return
477
     */
478
    private TaxonNode getParent(SimpleExcelTaxonImportState<CONFIG> state, String parentStr) {
479
        Taxon taxon = state.getHigherTaxon(parentStr);
480

    
481
        return taxon == null ? null : taxon.getTaxonNodes().iterator().next();
482
    }
483

    
484
    /**
485
     * @param record
486
     * @param state
487
     * @return
488
     */
489
    private TaxonNode getFamilyTaxon(HashMap<String, String> record, SimpleExcelTaxonImportState<CONFIG> state) {
490
        String familyStr = getValue(record, "Family");
491
        if (familyStr == null){
492
            return null;
493
        }
494
        familyStr = familyStr.trim();
495

    
496
        Taxon family = state.getHigherTaxon(familyStr);
497
        TaxonNode familyNode;
498
        if (family != null){
499
            familyNode = family.getTaxonNodes().iterator().next();
500
        }else{
501
            BotanicalName name = makeFamilyName(state, familyStr);
502
            name = replaceNameAuthorsAndReferences(state, name);
503

    
504
            Reference sec = getSecReference(state);
505
            family = Taxon.NewInstance(name, sec);
506

    
507
            ITaxonTreeNode groupNode = getGroupTaxon(record, state);
508
            familyNode = groupNode.addChildTaxon(family, sec, null);
509
            state.putHigherTaxon(familyStr, family);
510
            getTaxonNodeService().save(familyNode);
511
        }
512

    
513
        return familyNode;
514
    }
515

    
516
    /**
517
     * @param record
518
     * @param state
519
     * @return
520
     */
521
    private TaxonNode getGroupTaxon(HashMap<String, String> record, SimpleExcelTaxonImportState<CONFIG> state) {
522
        String groupStr = getValue(record, "Group");
523
        if (groupStr == null){
524
            return null;
525
        }
526
        groupStr = groupStr.trim();
527

    
528
        Taxon group = state.getHigherTaxon(groupStr);
529
        TaxonNode groupNode;
530
        if (group != null){
531
            groupNode = group.getTaxonNodes().iterator().next();
532
        }else{
533
            BotanicalName name = makeFamilyName(state, groupStr);
534
            name = replaceNameAuthorsAndReferences(state, name);
535

    
536
            Reference sec = getSecReference(state);
537
            group = Taxon.NewInstance(name, sec);
538
            ITaxonTreeNode rootNode = getClassification(state);
539
            groupNode = rootNode.addChildTaxon(group, sec, null);
540
            state.putHigherTaxon(groupStr, group);
541
            getTaxonNodeService().save(groupNode);
542
        }
543

    
544
        return groupNode;
545
    }
546

    
547
    private TaxonNode rootNode;
548
    private TaxonNode getClassification(SimpleExcelTaxonImportState<CONFIG> state) {
549
        if (rootNode == null){
550
            Reference sec = getSecReference(state);
551
            String classificationName = state.getConfig().getClassificationName();
552
            Language language = Language.DEFAULT();
553
            Classification classification = Classification.NewInstance(classificationName, sec, language);
554
            classification.setUuid(state.getConfig().getClassificationUuid());
555
            classification.getRootNode().setUuid(rootUuid);
556

    
557
            BotanicalName plantaeName = TaxonNameFactory.NewBotanicalInstance(Rank.KINGDOM());
558
            plantaeName.setGenusOrUninomial("Plantae");
559
            plantaeName = replaceNameAuthorsAndReferences(state, plantaeName);
560

    
561
            Taxon plantae = Taxon.NewInstance(plantaeName, sec);
562
            TaxonNode plantaeNode = classification.addChildTaxon(plantae, null, null);
563
            plantaeNode.setUuid(plantaeUuid);
564
            getClassificationService().save(classification);
565

    
566
            rootNode = plantaeNode;
567
        }
568
        return rootNode;
569
    }
570

    
571
    /**
572
     * @param desc
573
     * @param string
574
     * @param uuidUserDefinedAnnotationTypeVocabulary
575
     */
576
    private void handleDistribution(SimpleExcelTaxonImportState<CONFIG> state,
577
                TaxonDescription desc, String key, UUID uuid, String line, String id) {
578
        HashMap<String, String> record = state.getOriginalRecord();
579
        String value = getValue(record, key);
580
        if (value == null || value.matches("[x\\.\\?]")){
581
            NamedArea area = getNamedArea(state, uuid, null, null, null, null, null);
582
            Distribution dist;
583
            if (".".equals(value)){
584
                logger.warn(line + "'.' Should not exist anmore as a distribution status: '" + value + "' for " + key);
585
                dist = Distribution.NewInstance(area, PresenceAbsenceTerm.ABSENT());
586
            }else if (value == null){
587
                //TODO is absent wanted
588
                dist = Distribution.NewInstance(area, PresenceAbsenceTerm.ABSENT());
589
            }else if ("x".equals(value)){
590
                dist = Distribution.NewInstance(area, PresenceAbsenceTerm.PRESENT());
591
            }else if ("?".equals(value)){
592
                dist = Distribution.NewInstance(area, PresenceAbsenceTerm.PRESENT_DOUBTFULLY());
593
            }else {
594
                logger.warn(line + "Not matching status. THis should not happpen '" + value + "' for " + key);
595
                return;
596
            }
597
            desc.addElement(dist);
598
            dist.addImportSource(id, getWorksheetName(), getSourceCitation(state), line);
599
        }else {
600
            logger.warn(line + "Unrecognized distribution status '" + value + "' for " + key);
601
        }
602
    }
603

    
604
    private void handleStatus(SimpleExcelTaxonImportState<CONFIG> state,
605
            TaxonDescription desc, String key, UUID uuid, String line, String id) {
606
        HashMap<String, String> record = state.getOriginalRecord();
607
        String value = getValue(record, key);
608
        DescriptionElementBase descEl;
609
        if (state.getConfig().isStatusAsDistribution()){
610
            NamedArea area = getNamedArea(state, uuid, null, null, null, null, null);
611
            if (value == null || ".".equals(value) ){
612
                descEl = Distribution.NewInstance(area, PresenceAbsenceTerm.NATIVE());
613
                if (".".equals(value)){
614
                    logger.warn(line + "'.' Should not exist anymore as a distribution status: '" + value + "' for " + key);
615
                }
616
            }else if ("Range-restricted".equals(value)){
617
                descEl = Distribution.NewInstance(area, rangeRestricted);
618
            }else if ("?Range-restricted".equals(value)){
619
                descEl = Distribution.NewInstance(area, doubtfullyRangeRestricted);
620
            }else if ("Xenophyte".equals(value)){
621
                descEl = Distribution.NewInstance(area, PresenceAbsenceTerm.INTRODUCED());
622
            }else if ("?Xenophyte".equals(value)){
623
                descEl = Distribution.NewInstance(area, PresenceAbsenceTerm.INTRODUCED_DOUBTFULLY_INTRODUCED());
624
            }else {
625
                logger.warn(line + "Not matching status. This should not happpen '" + value + "' for " + key);
626
                return;
627
            }
628
        }else{
629
            CategoricalData catData = CategoricalData.NewInstance(Feature.STATUS());
630
            descEl = catData;
631
            if (value == null || ".".equals(value) ){
632
                handleSingleStatus(state, catData, FloraHellenicaTransformer.uuidStatusNative, line);
633
                if (".".equals(value)){
634
                    logger.warn(line + "'.' Should not exist anymore as a status: '" + value + "' for " + key);
635
                }
636
            }else if ("Range-restricted".equals(value)){
637
                handleSingleStatus(state, catData, FloraHellenicaTransformer.uuidStatusRangeRestricted, line);
638
            }else if ("?Range-restricted".equals(value)){
639
                handleSingleStatus(state, catData, FloraHellenicaTransformer.uuidStatusRangeRestrictedDoubtfully, line);
640
            }else if ("Xenophyte".equals(value)){
641
                handleSingleStatus(state, catData, FloraHellenicaTransformer.uuidStatusXenophyte, line);
642
            }else if ("?Xenophyte".equals(value)){
643
                handleSingleStatus(state, catData, FloraHellenicaTransformer.uuidStatusXenophyteDoubtfully, line);
644
            }else {
645
                logger.warn(line + "Not matching status. This should not happpen '" + value + "' for " + key);
646
                return;
647
            }
648
        }
649

    
650
        desc.addElement(descEl);
651
        descEl.addImportSource(id, getWorksheetName(), getSourceCitation(state), line);
652
    }
653

    
654
    private void handleSingleStatus(SimpleExcelTaxonImportState<CONFIG> state, CategoricalData catData,
655
            UUID uuidStatus, String line) {
656

    
657
        HashMap<String, String> record = state.getOriginalRecord();
658
        String value = getValue(record, "Status");
659
        if (value == null || value.matches("(\\??Range-restricted|\\??Xenophyte)")){
660
            State statusState = this.getStateTerm(state, uuidStatus, null, null, null, statusVoc);
661
            catData.addStateData(statusState);
662
        }else{
663
            logger.warn(line + "Unrecognized status '" + value + "' for column 'Status'");
664
        }
665
    }
666

    
667

    
668
}
(9-9/11)