Project

General

Profile

Download (22.3 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.mexico;
10

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

    
19
import org.apache.commons.lang3.StringUtils;
20
import org.apache.logging.log4j.LogManager;
21
import org.apache.logging.log4j.Logger;
22
import org.springframework.stereotype.Component;
23

    
24
import eu.etaxonomy.cdm.io.common.mapping.UndefinedTransformerMethodException;
25
import eu.etaxonomy.cdm.model.agent.Person;
26
import eu.etaxonomy.cdm.model.agent.Team;
27
import eu.etaxonomy.cdm.model.agent.TeamOrPersonBase;
28
import eu.etaxonomy.cdm.model.common.Annotation;
29
import eu.etaxonomy.cdm.model.common.AnnotationType;
30
import eu.etaxonomy.cdm.model.common.CdmBase;
31
import eu.etaxonomy.cdm.model.common.Extension;
32
import eu.etaxonomy.cdm.model.common.ExtensionType;
33
import eu.etaxonomy.cdm.model.common.Language;
34
import eu.etaxonomy.cdm.model.common.VerbatimTimePeriod;
35
import eu.etaxonomy.cdm.model.name.IBotanicalName;
36
import eu.etaxonomy.cdm.model.name.NomenclaturalCode;
37
import eu.etaxonomy.cdm.model.name.NomenclaturalStatus;
38
import eu.etaxonomy.cdm.model.name.NomenclaturalStatusType;
39
import eu.etaxonomy.cdm.model.name.Rank;
40
import eu.etaxonomy.cdm.model.name.TaxonName;
41
import eu.etaxonomy.cdm.model.reference.INomenclaturalReference;
42
import eu.etaxonomy.cdm.model.reference.Reference;
43
import eu.etaxonomy.cdm.model.reference.ReferenceFactory;
44
import eu.etaxonomy.cdm.model.reference.ReferenceType;
45
import eu.etaxonomy.cdm.model.taxon.Classification;
46
import eu.etaxonomy.cdm.model.taxon.Synonym;
47
import eu.etaxonomy.cdm.model.taxon.SynonymType;
48
import eu.etaxonomy.cdm.model.taxon.Taxon;
49
import eu.etaxonomy.cdm.model.taxon.TaxonBase;
50
import eu.etaxonomy.cdm.model.taxon.TaxonRelationship;
51
import eu.etaxonomy.cdm.model.taxon.TaxonRelationshipType;
52
import eu.etaxonomy.cdm.model.term.DefinedTerm;
53
import eu.etaxonomy.cdm.strategy.exceptions.UnknownCdmTypeException;
54
import eu.etaxonomy.cdm.strategy.parser.TimePeriodParser;
55

    
56
/**
57
 * @author a.mueller
58
 * @since 16.06.2016
59
 */
60
@Component
61
public class MexicoConabioTaxonImport<CONFIG extends MexicoConabioImportConfigurator>
62
        extends SimpleExcelTaxonImport<CONFIG>{
63

    
64
    private static final long serialVersionUID = 3691221053127007258L;
65
    private static final Logger logger = LogManager.getLogger();
66

    
67
    public static final String TAXON_NAMESPACE = "Taxonomia";
68

    
69
    @Override
70
    protected String getWorksheetName(CONFIG  config) {
71
        return "Taxonomia";
72
    }
73

    
74
    //dirty I know, but who cares, needed by distribution and commmon name import
75
    protected static final Map<String, TaxonBase<?>> taxonIdMap = new HashMap<>();
76

    
77
    private Classification classification;
78

    
79

    
80
    private  static List<String> expectedKeys= Arrays.asList(new String[]{
81
            "IdCAT","IdCATRel","IdCAT_AscendenteInmediato"
82
            ,"IdCAT_AscendenteObligatorio","CategoriaTaxonomica","Nombre",
83
            "EstatusNombre","AutorNombre","AutorSinAnio","Anio",
84
            "ReferenciaNombre",
85
            "Division","AutorDivision","ReferenciaClasificacionDivision",
86
            "Clase","AutorClase","ReferenciaClasificacionClase",
87
            "Subclase","AutorSubclase","ReferenciaClasificacionSubclase",
88
            "Superorden","AutorSuperorden","ReferenciaClasificacionSuperorden",
89
            "Orden","AutorOrden","ReferenciaClasificacionOrden",
90
            "Familia",     "EstatusFamilia","AutorFamilia","ReferenciaClasificacionFamilia",
91
            "Tribu",  "EstatusTribu","AutorTribu","ReferenciaNombreTribu",
92
            "Genero","EstatusGenero","AutorGenero","","ReferenciaNombreGenero",
93
            "Epiteto_especifico","EstatusEspecie","AutorEpiteto_especifico","ReferenciaNombreEspecie",
94
            "CategoriaInfraespecifica","NombreInfraespecifico","EstatusInfraespecie","AutorInfraespecie","ReferenciaNombreInfraespecifico",
95
            "CitaNomenclatural","Anotacion al Taxon","Fuente_BDs",
96
            "FamAceptada","GenAceptado","CategoriaTaxAceptada","NombreAceptado","AutorNombreAceptado","AutorSinAnioAceptado","AnioAceptado",
97
            "TipoRelacion","ReferenciaSinonimia","ComentariosRevisor",
98
            "CompareID","IdCAT_OLD","Nombre_OLD","AutorSinAnio_OLD",
99
            "CitaNomenclatural_OLD","ReferenceType","IsUpdated",
100

    
101
            "Hibrido","ReferenciaNombreHibrido","AutorHibrido","EstatusHibrido",
102
            "Subgenero","ReferenciaNombreSubgenero","EstatusSubgenero","AutorSubgenero",
103
            "Subtribu","ReferenciaClasificacionSubtribu","AutorSubtribu","EstatusSubtribu",
104
            "Subfamilia","ReferenciaClasificacionSubfamilia","AutorSubfamilia","EstatusSubfamilia",
105
            "ReferenciaClasificacionTribu",
106
            "Supertribu","ReferenciaClasificacionSupertribu","AutorSupertribu","EstatusSupertribu",
107

    
108
        });
109

    
110

    
111
    @Override
112
    protected void firstPass(SimpleExcelTaxonImportState<CONFIG> state) {
113
        String line = state.getCurrentLine() + ": ";
114
        Map<String, String> record = state.getOriginalRecord();
115

    
116
        Set<String> keys = record.keySet();
117

    
118
        checkAllKeysExist(line, keys, expectedKeys);
119

    
120
        if (getValue(record, "Nombre") == null ){
121
            logger.warn("No FullnameNoAuthors given: " + line);
122
            return;
123
        }
124

    
125
        //Name
126
        IBotanicalName name = makeName(line, record, state);
127

    
128
        //sec
129
        String referenciaNombre = getValueNd(record, "ReferenciaNombre");
130

    
131
        //status
132
        String statusStr = getValue(record, "EstatusNombre");
133
        String originalInfo = null;
134
        TaxonBase<?> taxonBase;
135
        if ("aceptado".equals(statusStr)){
136
            Reference sec = getSecRef(state, referenciaNombre, line);
137
            taxonBase = Taxon.NewInstance(name, sec);
138
        }else if (statusStr.startsWith("sin")){
139
            String secRefStr = getValue(record, "ReferenciaSinonimia");
140

    
141
            Reference sec = getSynSec(state, secRefStr, referenciaNombre, line);
142
            taxonBase = Synonym.NewInstance(name, sec);
143
            if (isNotBlank(secRefStr)){
144
                originalInfo = "referenciaNombre: " + referenciaNombre;
145
            }
146
        }else{
147
            throw new RuntimeException(line + " Status not recognized: " + statusStr);
148
        }
149

    
150
        //annotation
151
        String annotation = getValue(record, "Anotacion al Taxon");
152
        if (annotation != null && (!annotation.equals("nom. illeg.") || !annotation.equals("nom. cons."))){
153
            taxonBase.addAnnotation(Annotation.NewInstance(annotation, AnnotationType.EDITORIAL(), Language.SPANISH_CASTILIAN()));
154
        }
155

    
156
        //id
157
        String idCat = getValue(record, "IdCAT");
158
        this.addOriginalSource(taxonBase, idCat, TAXON_NAMESPACE, state.getConfig().getSourceReference(), originalInfo);
159
        name.addIdentifier(idCat, getConabioIdIdentifierType(state));
160

    
161
//        checkSame(record, "EstatusHibrido", statusStr, line);
162
//        checkSame(record, "AutorHibrido", "AutorNombre", line);
163
//        checkSame(record, "ReferenciaNombreHibrido", "ReferenciaNombre", line);
164
//        checkSame(record, "Hibrido", "AutorNombre", line);
165

    
166
        //save
167
        getTaxonService().save(taxonBase);
168
        taxonIdMap.put(idCat, taxonBase);
169
    }
170

    
171
    private DefinedTerm getConabioIdIdentifierType(SimpleExcelTaxonImportState<CONFIG> state) {
172
        DefinedTerm conabioIdIdentifierType = getIdentiferType(state, MexicoConabioTransformer.uuidConabioTaxonIdIdentifierType, "Conabio name identifier", "Conabio name identifier", "CONABIO ID", null);
173
        return conabioIdIdentifierType;
174
    }
175

    
176
    private void checkSame(Map<String, String> record, String key, String compareValue, String line) {
177
        String value = getValue(record, key);
178
        if (value != null && !value.equals(compareValue)){
179
            logger.warn(line+ ": Value differs for "+ key +": " + value + "<->" + compareValue );
180
        }
181
    }
182

    
183
    private Reference getSynSec(SimpleExcelTaxonImportState<CONFIG> state, String secRefStr,
184
            String referenciaNombre, String line) {
185
        if (isBlank(secRefStr)){
186
            secRefStr = referenciaNombre;
187
        }
188
        if (isNotBlank(secRefStr)){
189
            Reference result = state.getReference(secRefStr);
190
            if (result == null){
191
                result = ReferenceFactory.newBook();
192
                result.setTitleCache(secRefStr, true);
193
                state.putReference(secRefStr, result);
194
            }
195
            return result;
196
        }else{
197
            return null;
198
        }
199
    }
200

    
201
    private Reference getSecRef(SimpleExcelTaxonImportState<CONFIG> state, String secRefStr, String line) {
202
        Reference result = state.getReference(secRefStr);
203
        if (result == null && secRefStr != null){
204
            result = ReferenceFactory.newBook();
205
            VerbatimTimePeriod tp = TimePeriodParser.parseStringVerbatim(secRefStr.substring(secRefStr.length()-4));
206
            String authorStrPart = secRefStr.substring(0, secRefStr.length()-6);
207
            if (! (authorStrPart + ", " + tp.getYear()).equals(secRefStr)){
208
                logger.warn(line + "Sec ref could not be parsed: " + secRefStr);
209
            }else{
210
                result.setDatePublished(tp);
211
            }
212
            TeamOrPersonBase<?> author = state.getAgentBase(authorStrPart);
213
            if (author == null){
214
                if (authorStrPart.contains("&")){
215
                    Team team = Team.NewInstance();
216
                    String[] authorSplit = authorStrPart.split("&");
217
                    String[] firstAuthorSplit = authorSplit[0].trim().split(",");
218
                    for (String authorStr : firstAuthorSplit){
219
                        addTeamMember(team, authorStr);
220
                    }
221
                    addTeamMember(team, authorSplit[1]);
222
                    result.setAuthorship(team);
223
                    state.putAgentBase(team.getTitleCache(), team);
224
                }else if (authorStrPart.equalsIgnoreCase("Tropicos") || authorStrPart.equalsIgnoreCase("The Plant List")
225
                        || authorStrPart.equalsIgnoreCase("APG IV")){
226
                    result.setTitle(authorStrPart);
227
                }else{
228
                    Person person = Person.NewInstance();
229
                    person.setFamilyName(authorStrPart);
230
                    result.setAuthorship(person);
231
                    state.putAgentBase(person.getTitleCache(), person);
232
                }
233
            }else{
234
                result.setAuthorship(author);
235
            }
236
            state.putReference(secRefStr, result);
237
        }else if(secRefStr == null){
238
            return state.getConfig().getSecReference();
239
        }
240

    
241
        return result;
242
    }
243

    
244
    private void addTeamMember(Team team, String author) {
245
        if (StringUtils.isNotBlank(author)){
246
            Person person = Person.NewInstance();
247
            person.setFamilyName(author.trim());
248
            team.addTeamMember(person);
249
        }
250
    }
251

    
252
    private IBotanicalName makeName(String line, Map<String, String> record, SimpleExcelTaxonImportState<CONFIG> state) {
253

    
254
        String authorStr = getValueNd(record, "AutorSinAnio");
255
        String nameStr = getValue(record, "Nombre");
256
        String nomRefStr = getValue(record, "CitaNomenclatural");
257
        String refType = getValue(record, "ReferenceType");
258
        String idCat = getValue(record, "IdCAT");
259
        String rankStr = getValue(record, "CategoriaTaxonomica");
260
        String annotation = getValue(record, "Anotacion al Taxon");
261

    
262
        //rank
263
        Rank rank = null;
264
        try {
265
            rank = state.getTransformer().getRankByKey(rankStr);
266
            if (Rank.SUBSPECIES().equals(rank) || Rank.VARIETY().equals(rank) || Rank.FORM().equals(rank) || Rank.RACE().equals(rank)){
267
                int i = nameStr.lastIndexOf(" ");
268
                nameStr = nameStr.substring(0, i) + " " + rank.getAbbreviation() + nameStr.substring(i);
269
            }
270
        } catch (UndefinedTransformerMethodException e) {
271
            logger.warn(line + "Rank not recognized: " + rankStr);
272
        }
273

    
274
        //name + author
275
        String fullNameStr = nameStr + (authorStr != null ? " " + authorStr : "");
276

    
277
        IBotanicalName fullName = (IBotanicalName)nameParser.parseFullName(fullNameStr, NomenclaturalCode.ICNAFP, rank);
278
        if (fullName.isProtectedTitleCache()){
279
            logger.warn(line + "Name could not be parsed: " + fullNameStr );
280
        }else{
281
            replaceAuthorNamesAndNomRef(state, fullName);
282
        }
283
        IBotanicalName existingName = getExistingName(state, fullName);
284

    
285
        //reference
286
        String refNameStr = getRefNameStr(nomRefStr, refType, fullNameStr);
287

    
288
        IBotanicalName referencedName = (IBotanicalName)nameParser.parseReferencedName(refNameStr, NomenclaturalCode.ICNAFP, rank);
289
        if (referencedName.isProtectedFullTitleCache() || referencedName.isProtectedTitleCache()){
290
            logger.warn(line + "Referenced name could not be parsed: " + refNameStr );
291
        }else{
292
            addSourcesToReferences(referencedName, state);
293
            replaceAuthorNamesAndNomRef(state, referencedName);
294
        }
295
        adaptRefTypeForGeneric(referencedName, refType);
296

    
297
        //compare nom. ref. with Borhidi
298
        IBotanicalName result= referencedName;
299
        Boolean equal = null;
300
        if (existingName != null){
301
            String existingRefTitle = existingName.getFullTitleCache();
302
            String conabioRefTitle = referencedName.getFullTitleCache();
303
            if (!existingRefTitle.equals(conabioRefTitle)){
304
                existingName.setNomenclaturalMicroReference(referencedName.getNomenclaturalMicroReference());
305
                existingName.setNomenclaturalReference(referencedName.getNomenclaturalReference());
306
                equal = false;
307
            }else{
308
                equal = true;
309
            }
310
            result = existingName;
311
        }
312
        addNomRefExtension(state, result, equal);
313

    
314
        //status
315
        if (annotation != null && (annotation.equals("nom. illeg.") || annotation.equals("nom. cons."))){
316
            try {
317
                NomenclaturalStatusType nomStatusType = NomenclaturalStatusType.getNomenclaturalStatusTypeByAbbreviation(annotation, result);
318
                result.addStatus(NomenclaturalStatus.NewInstance(nomStatusType));
319
            } catch (UnknownCdmTypeException e) {
320
                logger.warn(line + "nomStatusType not recognized: " + annotation);
321
            }
322
        }
323

    
324
        this.addOriginalSource(result, idCat, TAXON_NAMESPACE + "_Name", state.getConfig().getSourceReference());
325

    
326
        if(result.getNomenclaturalReference()!=null && result.getNomenclaturalReference().getTitleCache().equals("null")){
327
            logger.warn("null");
328
        }
329

    
330
        return result;
331
    }
332

    
333
    private void addSourcesToReferences(IBotanicalName name, SimpleExcelTaxonImportState<CONFIG> state) {
334
        Reference nomRef = name.getNomenclaturalReference();
335
        if (nomRef != null){
336
            nomRef.addSource(makeOriginalSource(state));
337
            if (nomRef.getInReference() != null){
338
                nomRef.getInReference().addSource(makeOriginalSource(state));
339
            }
340
        }
341
    }
342

    
343
    private void adaptRefTypeForGeneric(IBotanicalName referencedName, String refTypeStr) {
344
        INomenclaturalReference ref = referencedName.getNomenclaturalReference();
345
        if (ref == null){
346
            return;
347
        }
348
        ReferenceType refType = refTypeByRefTypeStr(refTypeStr);
349
        if (ref.getType() != refType && refType == ReferenceType.Book){
350
            ref.setType(refType);
351
        }
352
    }
353

    
354
    private ReferenceType refTypeByRefTypeStr(String refType){
355
        if ("A".equals(refType)){  //Article
356
            return ReferenceType.Article;
357
        }else if ("B".equals(refType)){   //Book
358
            return ReferenceType.Book;
359
        }else if (refType == null){   //Book
360
            return null;
361
        }else{
362
            throw new IllegalArgumentException("RefType not supported " + refType);
363
        }
364
    }
365

    
366
    private String getRefNameStr(String nomRefStr, String refTypeStr, String fullNameStr) {
367
        String refNameStr = fullNameStr;
368
        ReferenceType refType = refTypeByRefTypeStr(refTypeStr);
369
        if (nomRefStr == null){
370
            //do nothing
371
        }else if (refType == ReferenceType.Article){
372
            refNameStr = fullNameStr + " in " + nomRefStr;
373
        }else if (refType == ReferenceType.Book){
374
            refNameStr = fullNameStr + ", " + nomRefStr;
375
        }else if (refType == null && nomRefStr != null){
376
            logger.warn("RefType is null but nomRefStr exists");
377
        }
378
        return refNameStr;
379
    }
380

    
381
    private void addNomRefExtension(SimpleExcelTaxonImportState<CONFIG> state, IBotanicalName name, Boolean equal) {
382
        String equalStr = equal == null ? "" : equal == true ? "EQUAL\n" : "NOT EQUAL\n";
383
        name.setFullTitleCache(null, false);
384
        String newExtensionStr = name.getFullTitleCache() + " - CONABIO";
385
        UUID uuidNomRefExtension = MexicoConabioTransformer.uuidNomRefExtension;
386
        for (Extension extension : name.getExtensions()){
387
            if (extension.getType().getUuid().equals(uuidNomRefExtension)){
388
                extension.setValue(equalStr + extension.getValue() + "\n" + newExtensionStr);
389
                return;
390
            }
391
        }
392
        String label = "Nomenclatural reference in Sources";
393
        String abbrev = "Nom. ref. src.";
394
        ExtensionType extensionType = getExtensionType(state, uuidNomRefExtension, label, label, abbrev);
395
        Extension.NewInstance((TaxonName)name, newExtensionStr, extensionType);
396
    }
397

    
398
    boolean nameMapIsInitialized = false;
399
    private IBotanicalName getExistingName(SimpleExcelTaxonImportState<CONFIG> state, IBotanicalName fullName) {
400
        initExistinNames(state);
401
        return (IBotanicalName)state.getName(fullName.getTitleCache());
402
    }
403

    
404
    private void initExistinNames(SimpleExcelTaxonImportState<CONFIG> state) {
405
        if (!nameMapIsInitialized){
406
            List<String> propertyPaths = Arrays.asList("");
407
            List<TaxonName> existingNames = this.getNameService().list(null, null, null, null, propertyPaths);
408
            for (TaxonName tnb : existingNames){
409
                state.putName(tnb.getTitleCache(), tnb);
410
            }
411
            nameMapIsInitialized = true;
412
        }
413
    }
414

    
415
    /**
416
     * Same as {@link #getValue(eu.etaxonomy.cdm.io.excel.common.ExcelImportState, String)}
417
     * but "ND" return null.
418
     */
419
    private String getValueNd(Map<String, String> record, String string) {
420
        String value = getValue(record, string);
421
        if ("ND".equals(value)){
422
            return null;
423
        }else{
424
            return value;
425
        }
426
    }
427

    
428
    @Override
429
    protected void secondPass(SimpleExcelTaxonImportState<CONFIG> state) {
430
//        IdCAT_AscendenteInmediato, IdCATRel, TipoRelacion
431
        Map<String, String> record = state.getOriginalRecord();
432
        String line = state.getCurrentLine() + ": ";
433

    
434
        String parentStr = getValue(record, "IdCAT_AscendenteInmediato");
435
        String relStr = getValue(record, "IdCATRel");
436

    
437
        String statusStr = getValue(record, "EstatusNombre");
438

    
439
        Classification classification = getClassification(state);
440
        String idCat = getValue(record, "IdCAT");
441
        TaxonBase<?> taxonBase = taxonIdMap.get(idCat);
442
        Taxon parent;
443
        if(statusStr == null){
444
            logger.warn("No statusStr in line " +line);
445
        }else if ("aceptado".equals(statusStr)){
446
            parent = (Taxon)taxonIdMap.get(parentStr);
447
            if (parent == null){
448
                logger.warn(line + "Parent is missing: "+ parentStr);
449
            }else{
450
                Taxon taxon = (Taxon)taxonBase;
451
                Reference relRef = null;
452
                classification.addParentChild(parent, taxon, relRef, null);
453
//                makeConceptRelation(line, taxon.getName());
454
            }
455
        }else if (statusStr.startsWith("sin")){
456
            parent = (Taxon)taxonIdMap.get(relStr);
457
            if (parent == null){
458
                logger.warn(line + "Accepted taxon is missing: "+ relStr);
459
            }else{
460
                Synonym synonym = (Synonym)taxonBase;
461
                parent.addSynonym(synonym, SynonymType.SYNONYM_OF);
462
//                makeConceptRelation(line, synonym.getName());
463
            }
464
        }else{
465
            logger.warn("Unhandled statusStr in line " + line);
466
        }
467
    }
468

    
469
    private void makeConceptRelation(String line, TaxonName name) {
470
        if (name.getTaxonBases().size()==2){
471
            Iterator<TaxonBase> it = name.getTaxonBases().iterator();
472
            Taxon taxon1 = getAccepted(it.next());
473
            Taxon taxon2 = getAccepted(it.next());
474
            Reference citation = null;
475
            TaxonRelationship rel;
476
            if (taxon1.getSec().getUuid().equals(MexicoConabioTransformer.uuidReferenceBorhidi)){
477
                rel = taxon1.addTaxonRelation(taxon2, TaxonRelationshipType.CONGRUENT_TO(),
478
                        citation, null);
479
            }else{
480
                rel = taxon2.addTaxonRelation(taxon1, TaxonRelationshipType.CONGRUENT_TO(),
481
                        citation, null);
482
            }
483
            rel.setDoubtful(true);
484
        }else if (name.getTaxonBases().size()>2){
485
            logger.warn(line + "Names with more than 2 taxa not yet handled");
486
        }
487
    }
488

    
489
    private Taxon getAccepted(TaxonBase<?> taxonBase) {
490
        if (taxonBase.isInstanceOf(Taxon.class)){
491
            return CdmBase.deproxy(taxonBase, Taxon.class);
492
        }else{
493
            Synonym syn = CdmBase.deproxy(taxonBase, Synonym.class);
494
            return syn.getAcceptedTaxon();
495
        }
496
    }
497

    
498
    private Classification getClassification(SimpleExcelTaxonImportState<CONFIG> state) {
499
        if (classification == null){
500
            MexicoConabioImportConfigurator config = state.getConfig();
501
            classification = getClassificationService().find(config.getClassificationUuid());
502
            if (classification == null){
503
                classification = Classification.NewInstance(config.getClassificationName());
504
                classification.setUuid(config.getClassificationUuid());
505
                classification.setReference(config.getSecReference());
506
                getClassificationService().save(classification);
507
            }
508
        }
509
        return classification;
510
    }
511

    
512
    @Override
513
    protected boolean isIgnore(SimpleExcelTaxonImportState<CONFIG> state) {
514
        return ! state.getConfig().isDoTaxa();
515
    }
516
}
(6-6/26)