Project

General

Profile

Download (14.2 KB) Statistics
| Branch: | Revision:
1
// $Id$
2
/**
3
* Copyright (C) 2016 EDIT
4
* European Distributed Institute of Taxonomy
5
* http://www.e-taxonomy.eu
6
*
7
* The contents of this file are subject to the Mozilla Public License Version 1.1
8
* See LICENSE.TXT at the top of this package for the full license terms.
9
*/
10
package eu.etaxonomy.cdm.io.mexico;
11

    
12
import java.util.Arrays;
13
import java.util.HashMap;
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.log4j.Logger;
20
import org.springframework.stereotype.Component;
21

    
22
import eu.etaxonomy.cdm.io.common.mapping.UndefinedTransformerMethodException;
23
import eu.etaxonomy.cdm.model.agent.Person;
24
import eu.etaxonomy.cdm.model.agent.Team;
25
import eu.etaxonomy.cdm.model.common.Annotation;
26
import eu.etaxonomy.cdm.model.common.AnnotationType;
27
import eu.etaxonomy.cdm.model.common.Extension;
28
import eu.etaxonomy.cdm.model.common.ExtensionType;
29
import eu.etaxonomy.cdm.model.common.Language;
30
import eu.etaxonomy.cdm.model.common.TimePeriod;
31
import eu.etaxonomy.cdm.model.name.BotanicalName;
32
import eu.etaxonomy.cdm.model.name.NomenclaturalCode;
33
import eu.etaxonomy.cdm.model.name.NomenclaturalStatus;
34
import eu.etaxonomy.cdm.model.name.NomenclaturalStatusType;
35
import eu.etaxonomy.cdm.model.name.NonViralName;
36
import eu.etaxonomy.cdm.model.name.Rank;
37
import eu.etaxonomy.cdm.model.name.TaxonNameBase;
38
import eu.etaxonomy.cdm.model.reference.Reference;
39
import eu.etaxonomy.cdm.model.reference.ReferenceFactory;
40
import eu.etaxonomy.cdm.model.taxon.Classification;
41
import eu.etaxonomy.cdm.model.taxon.Synonym;
42
import eu.etaxonomy.cdm.model.taxon.SynonymRelationshipType;
43
import eu.etaxonomy.cdm.model.taxon.Taxon;
44
import eu.etaxonomy.cdm.model.taxon.TaxonBase;
45
import eu.etaxonomy.cdm.strategy.exceptions.UnknownCdmTypeException;
46
import eu.etaxonomy.cdm.strategy.parser.TimePeriodParser;
47

    
48
/**
49
 * @author a.mueller
50
 * @date 16.06.2016
51
 *
52
 */
53
@Component
54
public class MexicoConabioTaxonImport<CONFIG extends MexicoConabioImportConfigurator>
55
        extends SimpleExcelTaxonImport<CONFIG>{
56

    
57
    private static final long serialVersionUID = 3691221053127007258L;
58

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

    
61
    private final Map<String, TaxonBase<?>> taxonIdMap = new HashMap<>();
62

    
63
    private Classification classification;
64

    
65

    
66
    private  static List<String> expectedKeys= Arrays.asList(new String[]{
67
            "IdCAT","IdCATRel","IdCAT_AscendenteInmediato"
68
            ,"IdCAT_AscendenteObligatorio","CategoriaTaxonomica","Nombre",
69
            "EstatusNombre","AutorNombre","AutorSinAnio","Anio",
70
            "ReferenciaNombre",
71
            "Division","AutorDivision","ReferenciaClasificacionDivision",
72
            "Clase","AutorClase","ReferenciaClasificacionClase",
73
            "Subclase","AutorSubclase","ReferenciaClasificacionSubclase",
74
            "Superorden","AutorSuperorden","ReferenciaClasificacionSuperorden",
75
            "Orden","AutorOrden","ReferenciaClasificacionOrden",
76
            "Familia",     "EstatusFamilia","AutorFamilia","ReferenciaClasificacionFamilia",
77
            "Tribu",  "EstatusTribu","AutorTribu","ReferenciaNombreTribu",
78
            "Genero","EstatusGenero","AutorGenero","","ReferenciaNombreGenero",
79
            "Epiteto_especifico","EstatusEspecie","AutorEpiteto_especifico","ReferenciaNombreEspecie",
80
            "CategoriaInfraespecifica","NombreInfraespecifico","EstatusInfraespecie","AutorInfraespecie","ReferenciaNombreInfraespecifico",
81
            "CitaNomenclatural","Anotacion al Taxon","Fuente_BDs",
82
            "FamAceptada","GenAceptado","CategoriaTaxAceptada","NombreAceptado","AutorNombreAceptado","AutorSinAnioAceptado","AnioAceptado",
83
            "TipoRelacion","ReferenciaSinonimia","ComentariosRevisor",
84
            "CompareID","IdCAT_OLD","Nombre_OLD","AutorSinAnio_OLD",
85
            "CitaNomenclatural_OLD","ReferenceType","IsUpdated"
86
        });
87

    
88

    
89
    @Override
90
    protected void firstPass(SimpleExcelTaxonImportState<CONFIG> state) {
91
        String line = state.getCurrentLine() + ": ";
92
        HashMap<String, String> record = state.getOriginalRecord();
93

    
94
        Set<String> keys = record.keySet();
95

    
96
        checkAllKeysExist(line, keys, expectedKeys);
97

    
98
        if (getValue(record, "Nombre") == null ){
99
            logger.warn("No FullnameNoAuthors given: " + line);
100
            return;
101
        }
102

    
103
        //Name
104
        BotanicalName speciesName = makeName(line, record, state);
105
        String statusStr = getValue(record, "EstatusNombre");
106

    
107
        String secRefStr = getValueNd(record, "ReferenciaNombre");
108
        Reference sec = getSecRef(state, secRefStr, line);
109

    
110
        TaxonBase<?> taxonBase;
111
        if ("aceptado".equals(statusStr)){
112
            taxonBase = Taxon.NewInstance(speciesName, sec);
113
        }else if (statusStr.startsWith("sin")){
114
            taxonBase = Synonym.NewInstance(speciesName, sec);
115
        }else{
116
            throw new RuntimeException(line + " Status not recognized: " + statusStr);
117
        }
118

    
119
        String annotation = getValue(record, "Anotacion al Taxon");
120
        if (annotation != null && (!annotation.equals("nom. illeg.") || !annotation.equals("nom. cons."))){
121
            taxonBase.addAnnotation(Annotation.NewInstance(annotation, AnnotationType.EDITORIAL(), Language.SPANISH_CASTILIAN()));
122
        }
123

    
124
        String idCat = getValue(record, "IdCAT");
125
        this.addOriginalSource(taxonBase, idCat, "IdCAT", state.getConfig().getSourceReference());
126

    
127
        getTaxonService().save(taxonBase);
128
        taxonIdMap.put(idCat, taxonBase);
129
        if (taxonBase instanceof Taxon){
130
            state.putHigherTaxon(idCat, (Taxon)taxonBase);
131
        }
132

    
133
    }
134

    
135

    
136

    
137
    /**
138
     * @param state
139
     * @param secRefStr
140
     * @return
141
     */
142
    private Reference getSecRef(SimpleExcelTaxonImportState<CONFIG> state, String secRefStr, String line) {
143
        Reference result = state.getReference(secRefStr);
144
        if (result == null && secRefStr != null){
145
            result = ReferenceFactory.newBook();
146
            TimePeriod tp = TimePeriodParser.parseString(secRefStr.substring(secRefStr.length()-4));
147
            String authorStr = secRefStr.substring(0, secRefStr.length()-6);
148
            if (! (authorStr + ", " + tp.getYear()).equals(secRefStr)){
149
                logger.warn(line + "Sec ref could not be parsed: " + secRefStr);
150
            }else{
151
                result.setDatePublished(tp);
152
            }
153

    
154
            if (authorStr.contains(",") || authorStr.contains("&")){
155
                //TODO split
156
                Team team = Team.NewTitledInstance(authorStr, null);
157
                result.setAuthorship(team);
158
            }else if (authorStr.equals("Tropicos") || authorStr.equals("The plant list")
159
                    || authorStr.equals("APG IV")){
160
                result.setTitle(authorStr);
161

    
162
            }else{
163
                Person person = Person.NewTitledInstance(authorStr);
164
                result.setAuthorship(person);
165
            }
166

    
167
        }else if(secRefStr == null){
168
            logger.warn(line + "Empty secRefStr not yet implemented");
169
        }
170

    
171
        return result;
172
    }
173

    
174

    
175

    
176
    /**
177
     * @param record
178
     * @param state
179
     * @return
180
     */
181
    private BotanicalName makeName(String line, HashMap<String, String> record, SimpleExcelTaxonImportState<CONFIG> state) {
182

    
183
        String authorStr = getValueNd(record, "AutorSinAnio");
184
        String nameStr = getValue(record, "Nombre");
185
        String fullNameStr = nameStr + (authorStr != null ? " " + authorStr : "");
186
        String nomRefStr = getValue(record, "CitaNomenclatural");
187
        String refType = getValue(record, "ReferenceType");
188
        String idCat = getValue(record, "IdCAT");
189
        String rankStr = getValue(record, "CategoriaTaxonomica");
190
        String annotation = getValue(record, "Anotacion al Taxon");
191
        Rank rank = null;
192
        try {
193
            rank = state.getTransformer().getRankByKey(rankStr);
194
        } catch (UndefinedTransformerMethodException e) {
195
            logger.warn(line + "Rank not recognized: " + rankStr);
196
        }
197

    
198
        BotanicalName fullName = (BotanicalName)nameParser.parseFullName(fullNameStr, NomenclaturalCode.ICNAFP, rank);
199
        if (fullName.isProtectedTitleCache()){
200
            logger.warn(line + "Name could not be parsed: " + fullNameStr );
201
        }else{
202
            replaceAuthorNames(state, fullName);
203
        }
204
        BotanicalName existingName = getExistingName(state, fullName);
205

    
206
        String refNameStr = fullNameStr;
207
        if ("A".equals(refType)){  //Article
208
            refNameStr = fullNameStr + " in " + nomRefStr;
209
        }else if ("B".equals(refType)){   //Book
210
            refNameStr = fullNameStr + ", " + nomRefStr;
211
        }
212

    
213
        BotanicalName referencedName = (BotanicalName)nameParser.parseFullName(refNameStr, NomenclaturalCode.ICNAFP, rank);
214
        if (referencedName.isProtectedFullTitleCache() || referencedName.isProtectedTitleCache()){
215
            logger.warn(line + "Referenced name could not be parsed: " + refNameStr );
216
            BotanicalName tmp = (BotanicalName)nameParser.parseFullName(refNameStr, NomenclaturalCode.ICNAFP, rank);
217

    
218
        }else{
219
            replaceAuthorNames(state, referencedName);
220
        }
221

    
222
        BotanicalName result= referencedName;
223
        if (existingName != null){
224
            String existingRefTitle = existingName.getFullTitleCache();
225
            String conabioRefTitle = referencedName.getFullTitleCache();
226
            addNomRefExtension(state, referencedName);
227
            if (!existingRefTitle.equals(conabioRefTitle)){
228
                existingName.setNomenclaturalMicroReference(referencedName.getNomenclaturalMicroReference());
229
                existingName.setNomenclaturalReference(referencedName.getNomenclaturalReference());
230
                result = existingName;
231
            }
232
        }
233

    
234
        if (annotation != null && (annotation.equals("nom. illeg.") || annotation.equals("nom. cons."))){
235
            try {
236
                NomenclaturalStatusType nomStatusType = NomenclaturalStatusType.getNomenclaturalStatusTypeByAbbreviation(annotation, result);
237
                result.addStatus(NomenclaturalStatus.NewInstance(nomStatusType));
238
            } catch (UnknownCdmTypeException e) {
239
                logger.warn(line + "nomStatusType not recognized: " + annotation);
240
            }
241
        }
242

    
243
        this.addOriginalSource(result, idCat, "IdCAT", state.getConfig().getSourceReference());
244

    
245
        return result;
246
    }
247

    
248
    /**
249
     * @param state
250
     * @param referencedName
251
     */
252
    private void addNomRefExtension(SimpleExcelTaxonImportState<CONFIG> state, BotanicalName name) {
253
        String newExtensionStr = name.getFullTitleCache() + " - CONABIO";
254
        UUID uuidNomRefExtension = MexicoConabioTransformer.uuidNomRefExtension;
255
        for (Extension extension : name.getExtensions()){
256
            if (extension.getType().getUuid().equals(uuidNomRefExtension)){
257
                extension.setValue(extension.getValue() + "\n" + newExtensionStr);
258
                return;
259
            }
260
        }
261
        String label = "Nomenclatural reference in Sources";
262
        String abbrev = "Nom. ref. src.";
263
        ExtensionType extensionType = getExtensionType(state, uuidNomRefExtension, label, label, abbrev);
264
        Extension.NewInstance(name, newExtensionStr, extensionType);
265
    }
266

    
267
    boolean nameMapIsInitialized = false;
268
    /**
269
     * @param state
270
     * @param fullName
271
     * @return
272
     */
273
    @SuppressWarnings("rawtypes")
274
    private BotanicalName getExistingName(SimpleExcelTaxonImportState<CONFIG> state, BotanicalName fullName) {
275
        if (!nameMapIsInitialized){
276
            List<String> propertyPaths = Arrays.asList("");
277
            List<TaxonNameBase> existingNames = this.getNameService().list(null, null, null, null, propertyPaths);
278
            for (TaxonNameBase tnb : existingNames){
279
                state.putName(tnb.getTitleCache(), (NonViralName<?>)tnb);
280
            }
281
            nameMapIsInitialized = true;
282
        }
283
        return (BotanicalName)state.getName(fullName.getTitleCache());
284
    }
285

    
286
    /**
287
     * @param record
288
     * @param string
289
     * @return
290
     */
291
    private String getValueNd(HashMap<String, String> record, String string) {
292
        String value = getValue(record, string);
293
        if ("ND".equals(value)){
294
            return null;
295
        }else{
296
            return value;
297
        }
298
    }
299

    
300

    
301
    @Override
302
    protected void secondPass(SimpleExcelTaxonImportState<CONFIG> state) {
303
//        IdCAT_AscendenteInmediato, IdCATRel, TipoRelacion
304
        HashMap<String, String> record = state.getOriginalRecord();
305
        String line = state.getCurrentLine() + ": ";
306

    
307
        String parentStr = getValue(record, "IdCAT_AscendenteInmediato");
308
        String relStr = getValue(record, "IdCATRel");
309

    
310
        String statusStr = getValue(record, "EstatusNombre");
311

    
312
        Classification classification = getClassification(state);
313
        String idCat = getValue(record, "IdCAT");
314
        TaxonBase<?> taxonBase = taxonIdMap.get(idCat);
315
        Taxon parent;
316
        if ("aceptado".equals(statusStr)){
317
            parent = (Taxon)taxonIdMap.get(parentStr);
318
            if (parent == null){
319
                logger.warn(line + "Parent is missing: "+ parentStr);
320
            }else{
321
                Reference relRef = null;  //TODO
322
                classification.addParentChild(parent, (Taxon)taxonBase, relRef, null);
323
            }
324
        }else if (statusStr.startsWith("sin")){
325
            parent = (Taxon)taxonIdMap.get(relStr);
326
            if (parent == null){
327
                logger.warn(line + "Parent is missing: "+ relStr);
328
            }else{
329
                Reference synRef = null; //null
330
                parent.addSynonym((Synonym)taxonBase, SynonymRelationshipType.SYNONYM_OF(), synRef, null);
331
            }
332
        }
333
    }
334

    
335
     /**
336
     * @return
337
     */
338
    private Classification getClassification(SimpleExcelTaxonImportState<CONFIG> state) {
339
        if (classification == null){
340
            MexicoConabioImportConfigurator config = state.getConfig();
341
            classification = Classification.NewInstance(config.getClassificationName());
342
            classification.setUuid(config.getClassificationUuid());
343
            classification.setReference(config.getSourceReference());
344
            getClassificationService().save(classification);
345
        }
346
        return classification;
347
    }
348

    
349

    
350
    @Override
351
    protected boolean isIgnore(SimpleExcelTaxonImportState<CONFIG> state) {
352
        return ! state.getConfig().isDoTaxa();
353
    }
354
}
(8-8/11)