Project

General

Profile

Download (15.9 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.redlist.gefaesspflanzen;
11

    
12
import java.sql.ResultSet;
13
import java.sql.SQLException;
14
import java.util.HashMap;
15
import java.util.HashSet;
16
import java.util.Map;
17
import java.util.Set;
18

    
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.DbImportBase;
24
import eu.etaxonomy.cdm.io.common.IPartitionedIO;
25
import eu.etaxonomy.cdm.io.common.ImportHelper;
26
import eu.etaxonomy.cdm.io.common.ResultSetPartitioner;
27
import eu.etaxonomy.cdm.io.common.mapping.UndefinedTransformerMethodException;
28
import eu.etaxonomy.cdm.model.agent.AgentBase;
29
import eu.etaxonomy.cdm.model.agent.TeamOrPersonBase;
30
import eu.etaxonomy.cdm.model.common.CdmBase;
31
import eu.etaxonomy.cdm.model.name.BotanicalName;
32
import eu.etaxonomy.cdm.model.name.NomenclaturalStatus;
33
import eu.etaxonomy.cdm.model.name.NomenclaturalStatusType;
34
import eu.etaxonomy.cdm.model.name.Rank;
35
import eu.etaxonomy.cdm.model.name.TaxonNameBase;
36
import eu.etaxonomy.cdm.model.taxon.Synonym;
37
import eu.etaxonomy.cdm.model.taxon.Taxon;
38
import eu.etaxonomy.cdm.model.taxon.TaxonBase;
39
import eu.etaxonomy.cdm.model.taxon.TaxonRelationship;
40
import eu.etaxonomy.cdm.model.taxon.TaxonRelationshipType;
41

    
42
/**
43
 *
44
 * @author pplitzner
45
 * @date Mar 1, 2016
46
 *
47
 */
48

    
49
@Component
50
@SuppressWarnings("serial")
51
public class RedListGefaesspflanzenImportNames extends DbImportBase<RedListGefaesspflanzenImportState, RedListGefaesspflanzenImportConfigurator> {
52

    
53
    private static final Logger logger = Logger.getLogger(RedListGefaesspflanzenImportNames.class);
54

    
55
    private static final String tableName = "Rote Liste Gefäßpflanzen";
56

    
57
    private static final String pluralString = "names";
58

    
59
    public RedListGefaesspflanzenImportNames() {
60
        super(tableName, pluralString);
61
    }
62

    
63
    @Override
64
    protected String getIdQuery(RedListGefaesspflanzenImportState state) {
65
        return "SELECT NAMNR "
66
                + "FROM V_TAXATLAS_D20_EXPORT t "
67
                + " ORDER BY NAMNR";
68
    }
69

    
70
    @Override
71
    protected String getRecordQuery(RedListGefaesspflanzenImportConfigurator config) {
72
        String result = " SELECT * "
73
                + " FROM V_TAXATLAS_D20_EXPORT t "
74
                + " WHERE t.NAMNR IN (@IDSET)";
75
        result = result.replace("@IDSET", IPartitionedIO.ID_LIST_TOKEN);
76
        return result;
77
    }
78

    
79
    @Override
80
    protected void doInvoke(RedListGefaesspflanzenImportState state) {
81
        super.doInvoke(state);
82
    }
83

    
84

    
85
    @Override
86
    public boolean doPartition(ResultSetPartitioner partitioner, RedListGefaesspflanzenImportState state) {
87
        ResultSet rs = partitioner.getResultSet();
88
        Set<TaxonNameBase> namesToSave = new HashSet<TaxonNameBase>();
89
        Set<TaxonBase> taxaToSave = new HashSet<TaxonBase>();
90
        try {
91
            while (rs.next()){
92
                makeSingleNameAndTaxon(state, rs, namesToSave, taxaToSave);
93

    
94
            }
95
        } catch (SQLException e) {
96
            e.printStackTrace();
97
        }
98

    
99
        getNameService().saveOrUpdate(namesToSave);
100
        getTaxonService().saveOrUpdate(taxaToSave);
101
        return true;
102
    }
103

    
104
    private void makeSingleNameAndTaxon(RedListGefaesspflanzenImportState state, ResultSet rs, Set<TaxonNameBase> namesToSave, Set<TaxonBase> taxaToSave)
105
            throws SQLException {
106
        long id = rs.getLong(RedListUtil.NAMNR);
107
        String taxNameString = rs.getString(RedListUtil.TAXNAME);
108
        String gueltString = rs.getString(RedListUtil.GUELT);
109
        String rangString = rs.getString(RedListUtil.RANG);
110
        String ep1String = rs.getString(RedListUtil.EPI1);
111
        String ep2String = rs.getString(RedListUtil.EPI2);
112
        String ep3String = rs.getString(RedListUtil.EPI3);
113
        String nomZusatzString = rs.getString(RedListUtil.NOM_ZUSATZ);
114
        String taxZusatzString = rs.getString(RedListUtil.TAX_ZUSATZ);
115
        String zusatzString = rs.getString(RedListUtil.ZUSATZ);
116
        String authorKombString = rs.getString(RedListUtil.AUTOR_KOMB);
117
        String authorBasiString = rs.getString(RedListUtil.AUTOR_BASI);
118
        String hybString = rs.getString(RedListUtil.HYB);
119

    
120
        //---NAME---
121
        if(CdmUtils.isBlank(taxNameString) && CdmUtils.isBlank(ep1String)){
122
            RedListUtil.logMessage(id, "No name found!", logger);
123
        }
124

    
125
        Rank rank = makeRank(id, state, rangString);
126
        BotanicalName name = BotanicalName.NewInstance(rank);
127

    
128
        //ep1 should always be present
129
        if(CdmUtils.isBlank(ep1String)){
130
            RedListUtil.logMessage(id, RedListUtil.EPI1+" is empty!", logger);
131
        }
132
        name.setGenusOrUninomial(ep1String);
133
        if(CdmUtils.isNotBlank(ep2String)){
134
            name.setSpecificEpithet(ep2String);
135
        }
136
        if(CdmUtils.isNotBlank(ep3String)){
137
            if(rank==Rank.SUBSPECIES() ||
138
                    rank==Rank.VARIETY()){
139
                name.setInfraSpecificEpithet(ep3String);
140
            }
141
        }
142
        //nomenclatural status
143
        if(CdmUtils.isNotBlank(nomZusatzString)){
144
            NomenclaturalStatusType status = makeNomenclaturalStatus(id, state, nomZusatzString);
145
            if(status!=null){
146
                name.addStatus(NomenclaturalStatus.NewInstance(status));
147
            }
148
        }
149
        //hybrid
150
        if(hybString.equals(RedListUtil.HYB_X)){
151
            name.setBinomHybrid(true);
152
        }
153
        else if(hybString.equals(RedListUtil.HYB_XF)){
154
            name.setTrinomHybrid(true);
155
        }
156

    
157

    
158
        //--- AUTHORS ---
159
        //combination author
160
        if(authorKombString.contains(RedListUtil.EX)){
161
            //TODO: what happens with multiple ex authors??
162
            String[] kombSplit = authorKombString.split(RedListUtil.EX);
163
            if(kombSplit.length!=2){
164
                RedListUtil.logMessage(id, "Multiple ex combination authors found", logger);
165
            }
166
            for (int i = 0; i < kombSplit.length; i++) {
167
                if(i==0){
168
                    //first author is ex author
169
                    TeamOrPersonBase authorKomb = (TeamOrPersonBase) state.getRelatedObject(RedListUtil.AUTHOR_NAMESPACE, kombSplit[i]);
170
                    name.setExCombinationAuthorship(authorKomb);
171
                }
172
                else{
173
                    TeamOrPersonBase authorKomb = (TeamOrPersonBase) state.getRelatedObject(RedListUtil.AUTHOR_NAMESPACE, kombSplit[i]);
174
                    name.setCombinationAuthorship(authorKomb);
175
                }
176
            }
177
        }
178
        else if(authorKombString.trim().contains(RedListUtil.AUCT)){
179
            RedListUtil.logMessage(id, "AUCT information in "+RedListUtil.AUTOR_KOMB+" column", logger);
180
        }
181
        else if(CdmUtils.isNotBlank(authorKombString)){
182
            TeamOrPersonBase authorKomb = (TeamOrPersonBase) state.getRelatedObject(RedListUtil.AUTHOR_NAMESPACE, authorKombString);
183
            name.setCombinationAuthorship(authorKomb);
184
        }
185
        //basionym author
186
        if(authorBasiString.contains(RedListUtil.EX)){
187
            String[] basiSplit = authorBasiString.split(RedListUtil.EX);
188
            for (int i = 0; i < basiSplit.length; i++) {
189
                if(basiSplit.length!=2){
190
                    RedListUtil.logMessage(id, "Multiple ex basionymn authors found", logger);
191
                }
192
                if(i==0){
193
                    TeamOrPersonBase authorBasi= (TeamOrPersonBase) state.getRelatedObject(RedListUtil.AUTHOR_NAMESPACE, basiSplit[i]);
194
                    if(CdmUtils.isBlank(authorKombString)){
195
                        name.setExCombinationAuthorship(authorBasi);
196
                    }
197
                    else{
198
                        name.setExBasionymAuthorship(authorBasi);
199
                    }
200
                }
201
                else{
202
                    TeamOrPersonBase authorBasi= (TeamOrPersonBase) state.getRelatedObject(RedListUtil.AUTHOR_NAMESPACE, basiSplit[i]);
203
                    if(CdmUtils.isBlank(authorKombString)){
204
                        name.setCombinationAuthorship(authorBasi);
205
                    }
206
                    else{
207
                        name.setBasionymAuthorship(authorBasi);
208
                    }
209
                }
210
            }
211
        }
212
        else if(CdmUtils.isNotBlank(authorBasiString)){
213
            //this seems to be a convention in the source database: When there is only a single author then only the "AUTOR_BASI" column is used
214
            TeamOrPersonBase authorBasi= (TeamOrPersonBase) state.getRelatedObject(RedListUtil.AUTHOR_NAMESPACE, authorBasiString);
215
            if(CdmUtils.isBlank(authorKombString)){
216
                name.setCombinationAuthorship(authorBasi);
217
            }
218
            else{
219
                name.setBasionymAuthorship(authorBasi);
220
            }
221
        }
222

    
223
        //check authorship consistency
224
        String authorString = rs.getString(RedListUtil.AUTOR);
225
        String authorshipCache = name.getAuthorshipCache();
226

    
227
        if(CdmUtils.isNotBlank(zusatzString)){
228
            authorString = authorString.replace(", "+zusatzString, "");
229
        }
230
        if(CdmUtils.isNotBlank(nomZusatzString)){
231
            authorString = authorString.replace(", "+nomZusatzString, "");
232
        }
233
        if(CdmUtils.isNotBlank(taxZusatzString)){
234
            authorString = authorString.replace(", "+taxZusatzString, "");
235
        }
236
        if(authorString.equals(RedListUtil.AUCT)){
237
            authorString = "";
238
        }
239
        if(!authorString.equals(authorshipCache)){
240
            RedListUtil.logMessage(id, "Authorship inconsistent! name.authorhshipCache <-> Column "+RedListUtil.AUTOR+": "+authorshipCache+" <-> "+authorString, logger);
241
        }
242

    
243
        //id
244
        ImportHelper.setOriginalSource(name, state.getTransactionalSourceReference(), id, RedListUtil.NAME_NAMESPACE);
245
        state.getNameMap().put(id, name.getUuid());
246

    
247
        namesToSave.add(name);
248

    
249
        //---TAXON---
250
        TaxonBase taxonBase = null;
251
        if(authorBasiString.trim().contains(RedListUtil.AUCT)){
252
            taxonBase = Taxon.NewInstance(name, null);
253
            taxonBase.setAppendedPhrase(RedListUtil.AUCT);
254
        }
255
        else if(gueltString.equals(RedListUtil.GUELT_ACCEPTED_TAXON)){
256
            taxonBase = Taxon.NewInstance(name, null);
257
        }
258
        else if(gueltString.equals(RedListUtil.GUELT_SYNONYM) || gueltString.equals(RedListUtil.GUELT_BASIONYM)){
259
            taxonBase = Synonym.NewInstance(name, null);
260
        }
261
        if(taxonBase==null){
262
            RedListUtil.logMessage(id, "Taxon for name "+name+" could not be created.", logger);
263
            return;
264
        }
265

    
266
        //check taxon name consistency
267
        if(taxNameString.endsWith("agg.")){
268
            taxNameString = taxNameString.replace("agg.", "aggr.");
269
        }
270
        if(hybString.equalsIgnoreCase(RedListUtil.HYB_X)){
271
            taxNameString = taxNameString.replace("× ", "×");//hybrid sign has no space after it in titleCache for binomial hybrids
272
        }
273
        String nameCache = ((BotanicalName)taxonBase.getName()).getNameCache().trim();
274
        if(!taxNameString.trim().equals(nameCache)){
275
            RedListUtil.logMessage(id, "Taxon name inconsistent! taxon.titleCache <-> Column "+RedListUtil.TAXNAME+": "+nameCache+" <-> "+taxNameString, logger);
276
        }
277

    
278
        /*check if taxon/synonym is also in checklist
279
         * 1. create new taxon with the same name (in the checklist classification)
280
         * 2. create congruent concept relationship between both
281
         */
282
        String clTaxonString = rs.getString(RedListUtil.CL_TAXON);
283
        if(CdmUtils.isNotBlank(clTaxonString) && !clTaxonString.trim().equals("-")){
284
            TaxonBase clone = (TaxonBase) taxonBase.clone();
285
            clone.setName(name);
286
            if(taxonBase.isInstanceOf(Taxon.class)){
287
                TaxonRelationship taxonRelation = ((Taxon) taxonBase).addTaxonRelation((Taxon) clone, TaxonRelationshipType.CONGRUENT_TO(), null, null);
288
                taxonRelation.setDoubtful(true);//TODO Ist das mit " mit Fragezeichen" gemeint?
289
            }
290
            ImportHelper.setOriginalSource(clone, state.getTransactionalSourceReference(), id, RedListUtil.TAXON_CHECKLISTE_NAMESPACE);
291
            taxaToSave.add(clone);
292
        }
293

    
294
        //NOTE: the source has to be added after cloning or otherwise the clone would also get the source
295
        ImportHelper.setOriginalSource(taxonBase, state.getTransactionalSourceReference(), id, RedListUtil.TAXON_GESAMTLISTE_NAMESPACE);
296
        taxaToSave.add(taxonBase);
297

    
298
    }
299

    
300
    private Rank makeRank(long id, RedListGefaesspflanzenImportState state, String rankStr) {
301
        Rank rank = null;
302
        try {
303
            rank = state.getTransformer().getRankByKey(rankStr);
304
        } catch (UndefinedTransformerMethodException e) {
305
            e.printStackTrace();
306
        }
307
        if(rank==null){
308
            RedListUtil.logMessage(id, rankStr+" could not be associated to a known rank.", logger);
309
        }
310
        return rank;
311
    }
312

    
313
    private NomenclaturalStatusType makeNomenclaturalStatus(long id, RedListGefaesspflanzenImportState state, String nomZusatzString) {
314
        NomenclaturalStatusType status = null;
315
        try {
316
            status = state.getTransformer().getNomenclaturalStatusByKey(nomZusatzString);
317
        } catch (UndefinedTransformerMethodException e) {
318
            e.printStackTrace();
319
        }
320
        if(status==null){
321
            RedListUtil.logMessage(id, nomZusatzString+" could not be associated to a known nomenclatural status.", logger);
322
        }
323
        return status;
324
    }
325

    
326

    
327

    
328
    @Override
329
    public Map<Object, Map<String, ? extends CdmBase>> getRelatedObjectsForPartition(ResultSet rs,
330
            RedListGefaesspflanzenImportState state) {
331
        Map<Object, Map<String, ? extends CdmBase>> result = new HashMap<>();
332
        Map<String, AgentBase<?>> authorMap = new HashMap<String, AgentBase<?>>();
333

    
334
        try {
335
            while (rs.next()){
336
                String authorKombString = rs.getString(RedListUtil.AUTOR_KOMB);
337

    
338
                if(authorKombString.contains(RedListUtil.EX)){
339
                    String[] kombSplit = authorKombString.split(RedListUtil.EX);
340
                    for (int i = 0; i < kombSplit.length; i++) {
341
                        if(!authorMap.containsKey(kombSplit[i])){
342
                            authorMap.put(kombSplit[i], getAgentService().load(state.getAuthorMap().get(kombSplit[i])));
343
                        }
344
                    }
345
                }
346
                else if(CdmUtils.isNotBlank(authorKombString) && !authorMap.containsKey(authorKombString)){
347
                    authorMap.put(authorKombString, getAgentService().load(state.getAuthorMap().get(authorKombString)));
348
                }
349

    
350
                String authorBasiString = rs.getString(RedListUtil.AUTOR_BASI);
351
                //basionym author
352
                if(authorBasiString.contains(RedListUtil.EX)){
353
                    String[] basiSplit = authorBasiString.split(RedListUtil.EX);
354
                    for (int i = 0; i < basiSplit.length; i++) {
355
                        if(!authorMap.containsKey(basiSplit[i])){
356
                            authorMap.put(basiSplit[i], getAgentService().load(state.getAuthorMap().get(basiSplit[i])));
357
                        }
358
                    }
359
                }
360
                else if(CdmUtils.isNotBlank(authorBasiString) && !authorMap.containsKey(authorBasiString)){
361
                    authorMap.put(authorBasiString, getAgentService().load(state.getAuthorMap().get(authorBasiString)));
362
                }
363
            }
364
        } catch (SQLException e) {
365
            e.printStackTrace();
366
        }
367
        result.put(RedListUtil.AUTHOR_NAMESPACE, authorMap);
368

    
369
        return result;
370
    }
371

    
372
    @Override
373
    protected boolean doCheck(RedListGefaesspflanzenImportState state) {
374
        return false;
375
    }
376

    
377
    @Override
378
    protected boolean isIgnore(RedListGefaesspflanzenImportState state) {
379
        return false;
380
    }
381

    
382
}
(4-4/7)