Project

General

Profile

Download (47.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.ArrayList;
13
import java.util.Arrays;
14
import java.util.HashMap;
15
import java.util.HashSet;
16
import java.util.List;
17
import java.util.Set;
18
import java.util.UUID;
19
import java.util.regex.Matcher;
20
import java.util.regex.Pattern;
21

    
22
import org.apache.commons.lang.StringUtils;
23
import org.apache.log4j.Logger;
24
import org.springframework.stereotype.Component;
25

    
26
import eu.etaxonomy.cdm.common.CdmUtils;
27
import eu.etaxonomy.cdm.io.common.mapping.UndefinedTransformerMethodException;
28
import eu.etaxonomy.cdm.io.excel.common.ExcelImporterBase;
29
import eu.etaxonomy.cdm.model.agent.Team;
30
import eu.etaxonomy.cdm.model.agent.TeamOrPersonBase;
31
import eu.etaxonomy.cdm.model.common.Annotation;
32
import eu.etaxonomy.cdm.model.common.AnnotationType;
33
import eu.etaxonomy.cdm.model.common.Language;
34
import eu.etaxonomy.cdm.model.common.OriginalSourceType;
35
import eu.etaxonomy.cdm.model.description.Distribution;
36
import eu.etaxonomy.cdm.model.description.Feature;
37
import eu.etaxonomy.cdm.model.description.PresenceAbsenceTerm;
38
import eu.etaxonomy.cdm.model.description.TaxonDescription;
39
import eu.etaxonomy.cdm.model.description.TaxonInteraction;
40
import eu.etaxonomy.cdm.model.description.TextData;
41
import eu.etaxonomy.cdm.model.location.NamedArea;
42
import eu.etaxonomy.cdm.model.name.BotanicalName;
43
import eu.etaxonomy.cdm.model.name.NameRelationshipType;
44
import eu.etaxonomy.cdm.model.name.NomenclaturalCode;
45
import eu.etaxonomy.cdm.model.name.NomenclaturalStatus;
46
import eu.etaxonomy.cdm.model.name.NomenclaturalStatusType;
47
import eu.etaxonomy.cdm.model.name.Rank;
48
import eu.etaxonomy.cdm.model.reference.Reference;
49
import eu.etaxonomy.cdm.model.reference.ReferenceFactory;
50
import eu.etaxonomy.cdm.model.taxon.Classification;
51
import eu.etaxonomy.cdm.model.taxon.ITaxonTreeNode;
52
import eu.etaxonomy.cdm.model.taxon.SynonymRelationship;
53
import eu.etaxonomy.cdm.model.taxon.SynonymRelationshipType;
54
import eu.etaxonomy.cdm.model.taxon.Taxon;
55
import eu.etaxonomy.cdm.model.taxon.TaxonNode;
56
import eu.etaxonomy.cdm.model.taxon.TaxonRelationshipType;
57
import eu.etaxonomy.cdm.strategy.parser.INonViralNameParser;
58
import eu.etaxonomy.cdm.strategy.parser.NonViralNameParserImpl;
59

    
60
/**
61
 * @author a.mueller
62
 * @created 05.01.2016
63
 */
64

    
65
@Component
66
public class CubaExcelImport extends ExcelImporterBase<CubaImportState> {
67
    private static final long serialVersionUID = -747486709409732371L;
68
    private static final Logger logger = Logger.getLogger(CubaExcelImport.class);
69

    
70
    private static final String HOMONYM_MARKER = "\\s+homon.?$";
71
    private static final String DOUBTFUL_MARKER = "^\\?\\s?";
72

    
73

    
74
    private static UUID rootUuid = UUID.fromString("206d42e4-ac32-4f20-a093-14826014e667");
75
    private static UUID plantaeUuid = UUID.fromString("139e7314-dd19-4286-a01d-8cc94ef77a09");
76

    
77
    private static INonViralNameParser<?> nameParser = NonViralNameParserImpl.NewInstance();
78
    private static NomenclaturalCode nc = NomenclaturalCode.ICNAFP;
79

    
80
    private  static List<String> expectedKeys= Arrays.asList(new String[]{
81
            "Fam. default","Fam. FRC","Fam. A&S","Fam. FC",
82
            "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"});
83

    
84
	@Override
85
    protected void analyzeRecord(HashMap<String, String> record, CubaImportState state) {
86
	    //we do everything in firstPass here
87
    	return;
88
    }
89

    
90

    
91
    /**
92
     * @param record
93
     * @param state
94
     * @param taxon
95
     */
96
    private void makeCubanDistribution(HashMap<String, String> record, CubaImportState state) {
97
        try {
98
            NamedArea cuba = getNamedArea(state, state.getTransformer().getNamedAreaUuid("C"), null, null, null, null, null);
99
            TaxonDescription desc = getTaxonDescription(state.getCurrentTaxon(), false, true);
100
            List<PresenceAbsenceTerm> statuss =  makeCubanStatuss(record, state);
101
            for (PresenceAbsenceTerm status : statuss){
102
                Distribution distribution = Distribution.NewInstance(cuba, status);
103
                desc.addElement(distribution);
104
            }
105
        } catch (UndefinedTransformerMethodException e) {
106
            e.printStackTrace();
107
        }
108
    }
109

    
110

    
111
    /**
112
     * @param record
113
     * @param state
114
     * @return
115
     * @throws UndefinedTransformerMethodException
116
     */
117
    private List<PresenceAbsenceTerm> makeCubanStatuss(HashMap<String, String> record, CubaImportState state) throws UndefinedTransformerMethodException {
118
        boolean isAbsent = false;  //TODO
119
        PresenceAbsenceTerm highestStatus = null;
120

    
121
        String line = state.getCurrentLine() + ": ";
122
        List<PresenceAbsenceTerm> result = new ArrayList<>();
123

    
124
        String endemicStr = getValue(record, "End");
125
        String indigenousStr = getValue(record, "Ind");
126
        String indigenousDoubtStr = getValue(record, "Ind? D");
127
        String naturalisedStr = getValue(record, "Nat");
128
        String dudStr = getValue(record, "Dud P");
129
        String advStr = getValue(record, "Adv");
130
        String cultStr = getValue(record, "Cult C");
131

    
132
        if (endemicStr != null){
133
            if(endemicStr.equals("+")){
134
                PresenceAbsenceTerm endemicState = state.getTransformer().getPresenceTermByKey("E");
135
                result.add(endemicState);
136
                highestStatus = endemicState;
137
            }else if(isMinus(endemicStr)){
138
                UUID endemicUuid = state.getTransformer().getPresenceTermUuid("-E");
139
                PresenceAbsenceTerm endemicState = getPresenceTerm(state, endemicUuid, null, null, null, false);
140
                result.add(endemicState);
141
                checkAbsentHighestState(highestStatus, line, "endemic", false);
142
            }else if(endemicStr.equals("?")){
143
                UUID endemicDoubtfulUuid = state.getTransformer().getPresenceTermUuid("?E");
144
                PresenceAbsenceTerm endemicState = getPresenceTerm(state, endemicDoubtfulUuid, null, null, null, false);
145
                result.add(endemicState);
146
                checkAbsentHighestState(highestStatus, line, "endemic", false);
147
            }else{
148
                logger.warn(line + "Endemic not recognized: " + endemicStr);
149
            }
150
        }
151
        if (indigenousStr != null){
152
            if(indigenousStr.equals("+")){
153
                UUID indigenousUuid = state.getTransformer().getPresenceTermUuid("Ind.");
154
                PresenceAbsenceTerm indigenousState = getPresenceTerm(state, indigenousUuid, null, null, null, false);
155
                result.add(indigenousState);
156
                highestStatus = highestStatus != null ? highestStatus : indigenousState;
157
            }else if(isMinus(indigenousStr)){
158
                PresenceAbsenceTerm indigenousState = state.getTransformer().getPresenceTermByKey("-Ind.");
159
                result.add(indigenousState);
160
                checkAbsentHighestState(highestStatus, line, "indigenous", false);
161
            }else if(indigenousStr.equals("?")){
162
                UUID indigenousDoubtUuid = state.getTransformer().getPresenceTermUuid("?Ind.");
163
                PresenceAbsenceTerm indigenousDoubtState = getPresenceTerm(state, indigenousDoubtUuid, null, null, null, false);
164
                result.add(indigenousDoubtState);
165
                checkAbsentHighestState(highestStatus, line, "indigenous", true);
166
            }else{
167
                logger.warn(line + "Indigenous not recognized: " + indigenousStr);
168
            }
169
        }
170
        if(indigenousDoubtStr != null){
171
            if(indigenousDoubtStr.equals("D")){
172
                UUID indigenousDoubtUuid = state.getTransformer().getPresenceTermUuid("Ind.?");
173
                PresenceAbsenceTerm indigenousDoubtState = getPresenceTerm(state, indigenousDoubtUuid, null, null, null, false);
174
                result.add(indigenousDoubtState);
175
                highestStatus = highestStatus != null ? highestStatus : indigenousDoubtState;
176
            }else{
177
                logger.warn(line + "Indigenous doubtful not recognized: " + indigenousDoubtStr);
178
            }
179
        }
180
        if(naturalisedStr != null){
181
            if(naturalisedStr.equals("N")){
182
                PresenceAbsenceTerm haturalizedState = state.getTransformer().getPresenceTermByKey("Nat.");
183
                result.add(haturalizedState);
184
                highestStatus = highestStatus != null ? highestStatus : haturalizedState;
185
            }else if(isMinus(naturalisedStr)){
186
                UUID naturalisedErrorUuid = state.getTransformer().getPresenceTermUuid("-Nat.");
187
                PresenceAbsenceTerm naturalisedErrorState = getPresenceTerm(state, naturalisedErrorUuid, null, null, null, false);
188
                result.add(naturalisedErrorState);
189
                checkAbsentHighestState(highestStatus, line, "naturalized", false);
190
            }else if(naturalisedStr.equals("?")){
191
                UUID naturalisedDoubtUuid = state.getTransformer().getPresenceTermUuid("?Nat.");
192
                PresenceAbsenceTerm naturalisedDoubtState = getPresenceTerm(state, naturalisedDoubtUuid, null, null, null, false);
193
                result.add(naturalisedDoubtState);
194
                checkAbsentHighestState(highestStatus, line, "naturalized", true);
195
            }else{
196
                logger.warn(line + "Naturalized not recognized: " + naturalisedStr);
197
            }
198
        }
199
        if(dudStr != null){
200
            if(dudStr.equals("P")){
201
                UUID dudUuid = state.getTransformer().getPresenceTermUuid("Dud.");
202
                PresenceAbsenceTerm dudState = getPresenceTerm(state, dudUuid, null, null, null, false);
203
                result.add(dudState);
204
                highestStatus = highestStatus != null ? highestStatus : dudState;
205
            }else if(isMinus(dudStr)){
206
                UUID nonNativeErrorUuid = state.getTransformer().getPresenceTermUuid("-Dud.");
207
                PresenceAbsenceTerm nonNativeErrorState = getPresenceTerm(state, nonNativeErrorUuid, null, null, null, false);
208
                result.add(nonNativeErrorState);
209
                checkAbsentHighestState(highestStatus, line, "non-native and doubtfully naturalised", false);
210
            }else if(dudStr.equals("?")){
211
                UUID naturalisedDoubtUuid = state.getTransformer().getPresenceTermUuid("?Dud.");
212
                PresenceAbsenceTerm naturalisedDoubtState = getPresenceTerm(state, naturalisedDoubtUuid, null, null, null, false);
213
                result.add(naturalisedDoubtState);
214
                checkAbsentHighestState(highestStatus, line, "non-native and doubtfully naturalised", true);
215
            }else{
216
                logger.warn(line + "non-native and doubtfully naturalised not recognized: " + dudStr);
217
            }
218
        }
219
        if(advStr != null){
220
            if(advStr.equals("A")){
221
                UUID advUuid = state.getTransformer().getPresenceTermUuid("Adv.");
222
                PresenceAbsenceTerm advState = getPresenceTerm(state, advUuid, null, null, null, false);
223
                result.add(advState);
224
                highestStatus = highestStatus != null ? highestStatus : advState;
225
            }else if(isMinus(advStr)){
226
                UUID advUuid = state.getTransformer().getPresenceTermUuid("-Adv.");
227
                PresenceAbsenceTerm advState = getPresenceTerm(state, advUuid, null, null, null, false);
228
                result.add(advState);
229
                checkAbsentHighestState(highestStatus, line, "adventive", false);
230
            }else{
231
                logger.warn(line + "'adventive (casual) alien' not recognized: " + advStr);
232
            }
233
        }else if(cultStr != null){
234
            if (! (cultStr.matches("(C|\\(C\\)|\\?|–)"))){
235
                logger.warn("'cultivated' not recognized: " + cultStr);
236
            }else if(cultStr.equals("C")){
237
                PresenceAbsenceTerm cultivatedState = state.getTransformer().getPresenceTermByKey("Cult.");
238
                result.add(cultivatedState);
239
                highestStatus = highestStatus != null ? highestStatus : cultivatedState;
240
            }else if(cultStr.equals("?")){
241
                PresenceAbsenceTerm cultivatedState = state.getTransformer().getPresenceTermByKey("?Cult.");
242
                result.add(cultivatedState);
243
                checkAbsentHighestState(highestStatus, line, "cultivated", true);
244
            }else if(cultStr.equals("(C)")){
245
                UUID ocassualCultUuid = state.getTransformer().getPresenceTermUuid("(C)");
246
                PresenceAbsenceTerm cultivatedState = getPresenceTerm(state, ocassualCultUuid, null, null, null, false);
247
                result.add(cultivatedState);
248
            }else if(isMinus(cultStr)){
249
                PresenceAbsenceTerm cultivatedState = state.getTransformer().getPresenceTermByKey("-Cult.");
250
                result.add(cultivatedState);
251
                checkAbsentHighestState(highestStatus, line, "cultivated", false);
252
            }else{
253
                logger.warn(line + "'cultivated' not recognized: " + cultStr);
254
            }
255
        }
256
        state.setHighestStatusForTaxon(highestStatus);
257
        return result;
258
    }
259

    
260

    
261
    /**
262
     * @param highestStatus
263
     * @param line
264
     */
265
    private void checkAbsentHighestState(PresenceAbsenceTerm highestStatus, String line, String stateLabel, boolean doubtful) {
266
        if (highestStatus == null){
267
            String absentStr = doubtful ? "doubtful" : "absent";
268
            logger.warn(line + "Highest cuban state is " + absentStr + " " + stateLabel);
269
        }
270

    
271
    }
272

    
273

    
274
    /**
275
     * @param indigenousStr
276
     * @return
277
     */
278
    private boolean isMinus(String str) {
279
        return str.equals("-") || str.equals("–");
280
    }
281

    
282

    
283
    /**
284
     * @param indigenousStr
285
     * @return
286
     */
287
    private boolean checkPlusMinusDoubt(String str) {
288
        return str.equals("+") || isMinus(str)|| str.equals("?");
289
    }
290

    
291

    
292
    /**
293
     * @param indigenousStr
294
     * @param indigenousDoubtStr
295
     * @param naturalisedStr
296
     * @param dudStr
297
     * @param advStr
298
     * @param cultStr
299
     */
300
    private boolean checkAllNull(String ... others) {
301
        for (String other : others){
302
            if (other != null){
303
                return false;
304
            }
305
        }
306
        return true;
307
    }
308

    
309

    
310
    private static final String acceptedRegExStr = "\\(([^\\[\\]“”]{6,})\\)";
311
//    String heterotypicRegExStr2 = "([^\\(]{5,}" +"(\\(.+\\))?" + "[^\\)\\(]{2,})" +
312
//                    + "(\\((.{6,})\\))?";
313
    private static final String heterotypicRegExStr = "([^\\(\\[\\]“”]{5,})"
314
                                                     +"(\\((.{6,})\\))?";
315
    private static final String heterotypicRegExStr_TEST = "([^\\(]{5,}" +"(\\(.+\\))?" + "[^\\)\\(]{2,})"
316
            +"(\\((.{6,})\\))?";
317
    private static final String auctRegExStr = "auct\\."
318
            +"((\\sFC(\\-S)?(\\s&\\sA&S)?)|(\\sA&S)|\\sSagra|\\sCombs|\\sBritton|\\sGriseb\\.|\\sWright"
319
            + "|\\sHammer|\\sEngl\\.||\\sMaza|\\sMiers|\\sRoig|\\sBorhidi|\\sFRC|\\sCoL"
320
            + "|\\sAckerman|\\sMújica|\\sDíaz|\\sUrb\\.)?(\\s+p\\.\\s*p\\.)?";
321

    
322

    
323
    private static final String missapliedRegExStr = "(\\?\\s)?“(.*{5,})”\\s+(" + auctRegExStr + "|sensu\\s+.{2,})";
324
    private static final String sphalmRegExStr = "“(.*{5,})”\\s+((FC-S|A&S)\\s)?sphalm\\.(\\s(FC(-S)?|A&S|inval\\.))?";
325
    private static final String nomInvalRegExStr = "“(.*{5,})”\\s+nom\\.\\s+inval\\.(\\s(West|Moldenke|FC|Jacq.))?";
326
    private static final String homonymRegExStr = "\\s*(\\[.*\\])*\\s*";
327

    
328
    private static final Pattern acceptedRegEx = Pattern.compile(acceptedRegExStr + homonymRegExStr);
329
    private static final Pattern heterotypicRegEx = Pattern.compile(heterotypicRegExStr + homonymRegExStr);
330
    private static final Pattern missapliedRegEx = Pattern.compile(missapliedRegExStr);
331
    private static final Pattern nomInvalRegEx = Pattern.compile(nomInvalRegExStr);
332
    private static final Pattern sphalmRegEx = Pattern.compile(sphalmRegExStr);
333

    
334
    /**
335
     * @param record
336
     * @param state
337
     * @param taxon
338
     */
339
    private void makeSynonyms(HashMap<String, String> record, CubaImportState state) {
340
//        boolean forAccepted = true;
341
        String synonymStr = record.get("Syn.");
342
        String line = state.getCurrentLine() + ": ";
343

    
344
        if (synonymStr == null){
345
            //TODO test that this is not a synonym only line
346
            return;
347
        }
348
        synonymStr = synonymStr.trim();
349

    
350
//        String heterotypicRegExStr = "([^\\(]{5,}(\\(.+\\))?[^\\)\\(]{2,})(\\((.{6,})\\))?";
351
//        String heterotypicRegExStr = "([^\\(]{5,})(\\((.{6,})\\))?";
352

    
353
//        Pattern heterotypicRegEx = Pattern.compile(heterotypicRegExStr + homonymRegExStr);
354

    
355
        Matcher missapliedMatcher = missapliedRegEx.matcher(synonymStr);
356
        Matcher nomInvalMatcher = nomInvalRegEx.matcher(synonymStr);
357
        Matcher acceptedMatcher = acceptedRegEx.matcher(synonymStr);
358
        Matcher heterotypicMatcher = heterotypicRegEx.matcher(synonymStr);
359
        Matcher sphalmMatcher = sphalmRegEx.matcher(synonymStr);
360

    
361
        List<BotanicalName> homonyms = new ArrayList<>();
362
        if (missapliedMatcher.matches()){
363
            boolean doubtful = missapliedMatcher.group(1) != null;
364
            String firstPart = missapliedMatcher.group(2);
365
            BotanicalName name = (BotanicalName)nameParser.parseSimpleName(firstPart, state.getConfig().getNomenclaturalCode(), Rank.SPECIES());
366

    
367
            String secondPart = missapliedMatcher.group(3);
368
            Taxon misappliedNameTaxon = Taxon.NewInstance(name, null);
369
            misappliedNameTaxon.setDoubtful(doubtful);
370
            if (secondPart.startsWith("sensu")){
371
                secondPart = secondPart.substring(5).trim();
372
                if (secondPart.contains(" ")){
373
                    logger.warn(line + "CHECK: Second part contains more than 1 word. Check if this is correct: " + secondPart);
374
                }
375
                Reference<?> sensu = ReferenceFactory.newGeneric();
376
                Team team = Team.NewTitledInstance(secondPart, null);
377
                sensu.setAuthorship(team);
378
                misappliedNameTaxon.setSec(sensu);
379
            }else if (secondPart.matches(auctRegExStr)){
380
                secondPart = secondPart.replace("p. p.", "p.p.");
381
                misappliedNameTaxon.setAppendedPhrase(secondPart);
382
            }else{
383
                logger.warn(line + "Misapplied second part not recognized: " + secondPart);
384
            }
385
            //TODO
386
            Reference<?> relRef = null;
387
            state.getCurrentTaxon().addMisappliedName(misappliedNameTaxon, relRef, null);
388
        }else if (nomInvalMatcher.matches()){
389
            String firstPart = nomInvalMatcher.group(1);
390
            String afterInval = nomInvalMatcher.group(2);
391
            if (StringUtils.isNotBlank(afterInval)){
392
                logger.warn(state.getCurrentLine() + ": After inval to be implemented: " + afterInval);
393
            }
394
            BotanicalName name = (BotanicalName)nameParser.parseSimpleName(firstPart, state.getConfig().getNomenclaturalCode(), Rank.SPECIES());
395
            NomenclaturalStatus status = NomenclaturalStatus.NewInstance( NomenclaturalStatusType.INVALID());
396
            name.addStatus(status);
397
            state.getCurrentTaxon().addSynonymName(name, SynonymRelationshipType.SYNONYM_OF());
398
        }else if (sphalmMatcher.matches()){
399
            String firstPart = sphalmMatcher.group(1);
400
            String sphalmPart = synonymStr.replace(firstPart, "").replace("“","").replace("”","").trim();
401
            BotanicalName name = (BotanicalName)nameParser.parseSimpleName(firstPart, state.getConfig().getNomenclaturalCode(), Rank.SPECIES());
402
//            NomenclaturalStatus status = NomenclaturalStatus.NewInstance( NomenclaturalStatusType.INVALID());
403
//            name.addStatus(status);
404
            SynonymRelationship sr = state.getCurrentTaxon().addSynonymName(name, SynonymRelationshipType.SYNONYM_OF());
405
            sr.getSynonym().setAppendedPhrase(sphalmPart);
406
            sr.getSynonym().setSec(null);
407
        }else if (acceptedMatcher.matches()){
408
            String firstPart = acceptedMatcher.group(1);
409
            String homonymPart = acceptedMatcher.groupCount() < 2 ? null : acceptedMatcher.group(2);
410
            handleHomotypicGroup(firstPart, state, (BotanicalName)state.getCurrentTaxon().getName(), false, homonyms, homonymPart, false);
411
        }else if(heterotypicMatcher.matches()){
412
            String firstPart = heterotypicMatcher.group(1).trim();
413
            String secondPart = heterotypicMatcher.groupCount() < 3 ? null : heterotypicMatcher.group(3);
414
            String homonymPart = heterotypicMatcher.groupCount() < 4 ? null : heterotypicMatcher.group(4);
415
            boolean isDoubtful = firstPart.matches("^\\?\\s*.*");
416
            firstPart = replaceHomonIlleg(firstPart);
417
            boolean isHomonym = firstPart.matches(".*" + HOMONYM_MARKER);
418
            BotanicalName synName = makeName(firstPart);
419
            if (synName.isProtectedTitleCache()){
420
                logger.warn(line + " heterotypic base synonym could not be parsed correctly:" + firstPart);
421
            }
422
            if (isHomonym){
423
                homonyms.add(synName);
424
            }
425
            SynonymRelationship sr = state.getCurrentTaxon().addHeterotypicSynonymName(synName);
426
            sr.getSynonym().setDoubtful(isDoubtful);
427
            handleHomotypicGroup(secondPart, state, synName, true, homonyms, homonymPart, isDoubtful);
428
        }else{
429
            logger.warn(line + "Synonym entry does not match: " + synonymStr);
430
        }
431
    }
432

    
433

    
434

    
435
    /**
436
     * @param synonymStr
437
     * @param state
438
     * @param homonyms
439
     * @param homonymPart
440
     * @param isDoubtful
441
     * @param taxon
442
     * @param homotypicalGroup
443
     */
444
    private void handleHomotypicGroup(String homotypicStr,
445
            CubaImportState state,
446
            BotanicalName homotypicName,
447
            boolean isHeterotypic,
448
            List<BotanicalName> homonyms,
449
            String homonymPart,
450
            boolean isDoubtful) {
451

    
452
        if (homotypicStr == null){
453
            return;
454
        }else if (homotypicStr.startsWith("(") && homotypicStr.endsWith("")){
455
            homotypicStr = homotypicStr.substring(1, homotypicStr.length() - 1);
456
        }
457

    
458
        BotanicalName currentBasionym = homotypicName;
459
        String[] splits = homotypicStr.split("\\s*,\\s*");
460
        for (String split : splits){
461
            split = replaceHomonIlleg(split);
462
            boolean isHomonym = split.matches(".*" + HOMONYM_MARKER);
463
            BotanicalName newName = makeName(split);
464
            if (newName.isProtectedTitleCache()){
465
                logger.warn(state.getCurrentLine() + ": homotypic name part could not be parsed: " + split);
466
            }
467
            if (isHomonym){
468
                homonyms.add(newName);
469
            }
470
            if (isHeterotypic){
471
                SynonymRelationship sr = state.getCurrentTaxon().addHeterotypicSynonymName(newName, homotypicName.getHomotypicalGroup(), null, null);
472
                sr.getSynonym().setDoubtful(isDoubtful);
473
//                newName.addBasionym(homotypicName);
474
                currentBasionym = handleBasionym(currentBasionym, newName);
475
            }else{
476
                state.getCurrentTaxon().addHomotypicSynonymName(newName, null, null);
477
                handleBasionym(currentBasionym, newName);
478
            }
479
        }
480
        makeHomonyms(homonyms, homonymPart, state, currentBasionym);
481
    }
482

    
483

    
484
    /**
485
     * @param split
486
     * @return
487
     */
488
    private String replaceHomonIlleg(String split) {
489
        String result = split.trim().replace("homon. illeg.", "nom. illeg. homon.").trim();
490
        return result;
491
    }
492

    
493

    
494
    /**
495
     * @param homonyms
496
     * @param homonymPart
497
     * @param state
498
     * @param currentBasionym
499
     */
500
    private void makeHomonyms(List<BotanicalName> homonyms, String homonymPartOrig, CubaImportState state,
501
            BotanicalName currentBasionym) {
502
        String line = state.getCurrentLine() + ": ";
503
        String homonymPart = homonymPartOrig == null ? "" : homonymPartOrig.trim();
504
        if (homonyms.isEmpty() && homonymPart.equals("")){
505
            return;
506
        }else if (homonymPart.equals("")){
507
            logger.warn(line + "SynonymPart has homonyms but homonymPart is empty");
508
            return;
509
        }
510
        homonymPart = homonymPart.substring(1, homonymPart.length() - 1);
511
        String[] splits = homonymPart.split("\\]\\s*\\[");
512
        if (splits.length != homonyms.size()){
513
            if(homonyms.size() == 0 && splits.length >= 1){
514
                handleSimpleBlockingNames(splits, state, currentBasionym);
515
            }else{
516
                logger.warn(line + "Number of homonyms (" + homonyms.size() + ") and homonymParts ("+splits.length+") does not match");
517
            }
518
            return;
519
        }
520
        int i = 0;
521
        for (String split : splits){
522
            split = split.replaceAll("^non\\s+", "");
523
            BotanicalName newName = makeName(split);
524
//            BotanicalName newName = (BotanicalName)nameParser.parseReferencedName(split, state.getConfig().getNomenclaturalCode(), Rank.SPECIES());
525
            if (newName.isProtectedTitleCache()){
526
                logger.warn(state.getCurrentLine() + ": homonym name could not be parsed: " + split);
527
            }
528
            newName.addRelationshipToName(homonyms.get(i), NameRelationshipType.LATER_HOMONYM(), null);
529
            i++;
530
        }
531
    }
532

    
533

    
534
    /**
535
     * @param homonymPart
536
     * @param state
537
     * @param currentBasionym
538
     */
539
    private void handleSimpleBlockingNames(String[] splitsi, CubaImportState state,
540
            BotanicalName currentBasionym) {
541
        for (String spliti : splitsi){
542

    
543
            String split = spliti.replaceAll("^non\\s+", "");
544
            BotanicalName newName = makeName(split);
545
            if (newName.isProtectedTitleCache()){
546
                logger.warn(state.getCurrentLine() + ": blocking name could not be parsed: " + split);
547
            }
548
            Set<BotanicalName> typifiedNames = (Set)currentBasionym.getHomotypicalGroup().getTypifiedNames();
549
            Set<BotanicalName> candidates = new HashSet<>();
550
            for (BotanicalName name : typifiedNames){
551
                if (name.getGenusOrUninomial() != null && name.getGenusOrUninomial().equals(newName.getGenusOrUninomial())){
552
                    if (name.getStatus().isEmpty() || ! name.getStatus().iterator().next().getType().equals(NomenclaturalStatusType.ILLEGITIMATE())){
553
                        candidates.add(name);
554
                    }
555
                }
556
            }
557
            if (candidates.size() == 1){
558
                newName.addRelationshipToName(candidates.iterator().next(), NameRelationshipType.BLOCKING_NAME_FOR(), null);
559
            }else{
560
                logger.warn(state.getCurrentLine() + ": Blocking name could not be handled. " + candidates.size() + " candidates.");
561
            }
562
        }
563
    }
564

    
565

    
566
    /**
567
     * @param newName
568
     * @param homotypicName
569
     * @return
570
     */
571
    private BotanicalName handleBasionym(BotanicalName currentBasionym, BotanicalName name2) {
572
        BotanicalName basionymName = currentBasionym;
573
        BotanicalName newCombination = name2;
574
        //switch if necessary
575
        if (basionymName.getBasionymAuthorship() != null && newCombination.getBasionymAuthorship() == null){
576
            basionymName = name2;
577
            newCombination = currentBasionym;
578
        }
579
//        newCombination.getHomotypicalGroup().removeGroupBasionym(xxx);
580
        if (matchAuthor(basionymName.getCombinationAuthorship(), newCombination.getBasionymAuthorship())){
581
            newCombination.getHomotypicalGroup().setGroupBasionym(basionymName);
582
        }
583
        return basionymName;
584
    }
585

    
586

    
587
    /**
588
     * @param combinationAuthorship
589
     * @param basi
590
     * @return
591
     */
592
    private boolean matchAuthor(TeamOrPersonBase<?> author1, TeamOrPersonBase<?> author2) {
593
        if (author1 == null || author2 == null){
594
            return false;
595
        }else {
596
            return author1.getNomenclaturalTitle().equals(author2.getNomenclaturalTitle());
597
        }
598
    }
599

    
600

    
601
    /**
602
     * @param record
603
     * @param state
604
     * @param taxon
605
     */
606
    private void makeNotes(HashMap<String, String> record, CubaImportState state) {
607
        String notesStr = getValue(record, "(Notas)");
608
        if (notesStr == null){
609
            return;
610
        }else{
611
            Annotation annotation = Annotation.NewDefaultLanguageInstance(notesStr);
612
            //TODO
613
            annotation.setAnnotationType(AnnotationType.TECHNICAL());
614
            state.getCurrentTaxon().addAnnotation(annotation);
615
        }
616
    }
617

    
618

    
619
    /**
620
     * @param record
621
     * @param state
622
     * @param familyTaxon
623
     * @return
624
     */
625
    private Taxon makeTaxon(HashMap<String, String> record, CubaImportState state, TaxonNode familyNode, boolean isSynonym) {
626
        String taxonStr = getValue(record, "Taxón");
627
        if (taxonStr == null){
628
            return isSynonym ? state.getCurrentTaxon() : null;
629
        }
630
        boolean isAbsent = false;
631
        if (taxonStr.startsWith("[") && taxonStr.endsWith("]")){
632
            taxonStr = taxonStr.substring(1, taxonStr.length() - 1);
633
            isAbsent = true;
634
        }
635

    
636
        BotanicalName botanicalName = makeName(taxonStr);
637
        Reference<?> sec = getSecReference(state);
638
        Taxon taxon = Taxon.NewInstance(botanicalName, sec);
639
        TaxonNode higherNode;
640
        if (botanicalName.isProtectedTitleCache()){
641
            logger.warn(state.getCurrentLine() + ": Taxon could not be parsed: " + taxonStr);
642
            higherNode = familyNode;
643
        }else{
644
            String genusStr = botanicalName.getGenusOrUninomial();
645
            Taxon genus = state.getHigherTaxon(genusStr);
646
            if (genus != null){
647
                higherNode = genus.getTaxonNodes().iterator().next();
648
            }else{
649
                BotanicalName name = BotanicalName.NewInstance(Rank.GENUS());
650
                name.setGenusOrUninomial(genusStr);
651
                genus = Taxon.NewInstance(name, sec);
652
                higherNode = familyNode.addChildTaxon(genus, null, null);
653
                state.putHigherTaxon(genusStr, genus);
654
            }
655
        }
656

    
657
        higherNode.addChildTaxon(taxon, null, null);
658

    
659
        return taxon;
660
    }
661

    
662
    private final String orthVarRegExStr = "[A-Z][a-z]+\\s[a-z]+\\s(\\(‘([a-z]){3,}’\\))\\s(\\([A-Z][a-z]+\\.?\\)\\s)?[A-Z][a-zó]+\\.?";
663
    private final Pattern orthVarRegEx = Pattern.compile(orthVarRegExStr);
664
    /**
665
     * @param taxonStr
666
     * @return
667
     */
668
    private BotanicalName makeName(String nameStrOrig) {
669
        //normalize
670
        String nameStr = normalizeStatus(nameStrOrig);
671
        //orthVar
672
        Matcher orthVarMatcher = orthVarRegEx.matcher(nameStr);
673
        String orthVar = null;
674
        if (orthVarMatcher.matches()) {
675
            orthVar = orthVarMatcher.group(1);
676
            nameStr = nameStr.replace(" " + orthVar, "").trim().replaceAll("\\s{2,}", " ");
677
            orthVar = orthVar.substring(2, orthVar.length() - 2);
678

    
679
        }
680
        BotanicalName result = (BotanicalName)nameParser.parseReferencedName(nameStr, nc, Rank.SPECIES());
681
        if (orthVar != null){
682
            BotanicalName orthVarName = (BotanicalName)result.clone();
683
            //TODO
684
            Reference<?> citation = null;
685
            orthVarName.addRelationshipToName(result, NameRelationshipType.ORTHOGRAPHIC_VARIANT(), citation, null, null);
686
            orthVarName.setSpecificEpithet(orthVar);
687
        }
688
        return result;
689

    
690
    }
691

    
692
    /**
693
     * @param state
694
     * @return
695
     */
696
    private Reference<?> getSecReference(CubaImportState state) {
697
        Reference<?> result = state.getSecReference();
698
        if (result == null){
699
            result = ReferenceFactory.newDatabase();
700
            result.setTitle("Flora of Cuba");
701
            state.setSecReference(result);
702
        }
703
        return result;
704
    }
705

    
706

    
707
    private static final String[] nomStatusStrings = new String[]{"nom. cons.", "ined.", "nom. illeg.",
708
            "nom. rej.","nom. cons. prop.","nom. altern.","nom. confus.","nom. dub.", "nom. nud."};
709
    /**
710
     * @param taxonStr
711
     * @return
712
     */
713
    private String normalizeStatus(String nameStr) {
714
        if (nameStr == null){
715
            return null;
716
        }
717
        String result = nameStr.replaceAll(HOMONYM_MARKER, "").trim();
718
        for (String nomStatusStr : nomStatusStrings){
719
            nomStatusStr = " " + nomStatusStr;
720
            if (result.endsWith(nomStatusStr)){
721
                result = result.replace(nomStatusStr, "," + nomStatusStr);
722
            }
723
        }
724
        result = result.replaceAll(DOUBTFUL_MARKER, "").trim();
725
        result = result.replace("[taxon]", "[infraspec.]");
726
        return result;
727

    
728

    
729
    }
730

    
731

    
732
    /**
733
     * @param record
734
     * @param state
735
     * @return
736
     */
737
    private TaxonNode getFamilyTaxon(HashMap<String, String> record, CubaImportState state) {
738
        String familyStr = getValue(record, "Fam. default");
739
        if (familyStr == null){
740
            return null;
741
        }
742
        Taxon family = state.getHigherTaxon(familyStr);
743
        TaxonNode familyNode;
744
        if (family != null){
745
            familyNode = family.getTaxonNodes().iterator().next();
746
        }else{
747
            BotanicalName name = state.getFamilyName(familyStr);
748
            if (name == null){
749
                name = BotanicalName.NewInstance(Rank.FAMILY());
750
                name.setGenusOrUninomial(familyStr);
751
                state.putFamilyName(familyStr, name);
752
            }
753
            Reference<?> sec = getSecReference(state);
754
            Taxon taxon = Taxon.NewInstance(name, sec);
755
            ITaxonTreeNode rootNode = getClassification(state);
756
            familyNode = rootNode.addChildTaxon(taxon, sec, null);
757
            state.putHigherTaxon(familyStr, taxon);
758
        }
759

    
760
        return familyNode;
761
    }
762

    
763
    /**
764
     * @param state
765
     * @param taxon
766
     * @param famStr
767
     * @param famRef
768
     * @return
769
     */
770
    private Taxon makeAlternativeFamilyTaxon(CubaImportState state, String famStr, Reference<?> famRef) {
771
        String key = famRef.getTitle() + ":"+ famStr;
772
        Taxon family = state.getHigherTaxon(key);
773
        if (family == null){
774
            BotanicalName name = state.getFamilyName(famStr);
775
            if (name == null){
776
                name = BotanicalName.NewInstance(Rank.FAMILY());
777
                name.setGenusOrUninomial(famStr);
778
                state.putFamilyName(famStr, name);
779
            }
780
            family = Taxon.NewInstance(name, famRef);
781
            state.putHigherTaxon(key, family);
782
        }
783

    
784
        return family;
785
    }
786

    
787

    
788
    /**
789
     * @param state
790
     * @return
791
     */
792
    private TaxonNode getClassification(CubaImportState state) {
793
        Classification classification = state.getClassification();
794
        if (classification == null){
795
            classification = getClassificationService().find(state.getConfig().getClassificationUuid());
796
        }
797
        TaxonNode rootNode = state.getRootNode();
798
        if (rootNode == null){
799
            rootNode = getTaxonNodeService().find(plantaeUuid);
800
        }
801
        if (rootNode == null){
802
            Reference<?> sec = getSecReference(state);
803
            if (classification == null){
804
                String classificationName = state.getConfig().getClassificationName();
805
                //TODO
806
                Language language = Language.DEFAULT();
807
                classification = Classification.NewInstance(classificationName, sec, language);
808
                state.setClassification(classification);
809
                classification.setUuid(state.getConfig().getClassificationUuid());
810
                classification.getRootNode().setUuid(rootUuid);
811
            }
812

    
813
            BotanicalName plantaeName = BotanicalName.NewInstance(Rank.KINGDOM());
814
            plantaeName.setGenusOrUninomial("Plantae");
815
            Taxon plantae = Taxon.NewInstance(plantaeName, sec);
816
            TaxonNode plantaeNode = classification.addChildTaxon(plantae, null, null);
817
            plantaeNode.setUuid(plantaeUuid);
818
            state.setRootNode(plantaeNode);
819
            getClassificationService().save(classification);
820

    
821
            rootNode = plantaeNode;
822
        }
823
        return rootNode;
824
    }
825

    
826

    
827
    /**
828
     * @param record
829
     * @param originalKey
830
     * @return
831
     */
832
    private String getValue(HashMap<String, String> record, String originalKey) {
833
        String value = record.get(originalKey);
834
        if (! StringUtils.isBlank(value)) {
835
        	if (logger.isDebugEnabled()) { logger.debug(originalKey + ": " + value); }
836
        	value = CdmUtils.removeDuplicateWhitespace(value.trim()).toString();
837
        	return value;
838
        }else{
839
        	return null;
840
        }
841
    }
842

    
843

    
844

    
845
	/**
846
	 *  Stores taxa records in DB
847
	 */
848
	@Override
849
    protected void firstPass(CubaImportState state) {
850
	    boolean isSynonym = false;
851

    
852
        String line = state.getCurrentLine() + ": ";
853
        HashMap<String, String> record = state.getOriginalRecord();
854

    
855
        Set<String> keys = record.keySet();
856
        for (String key: keys) {
857
            if (! expectedKeys.contains(key)){
858
                logger.warn(line + "Unexpected Key: " + key);
859
            }
860
        }
861

    
862
        if (record.get("Fam. default") == null && keys.size() == 2 && record.get("Syn.") == null && record.get("Nat") != null && record.get("Adv") != null){
863
            //second header line, don't handle
864
            return;
865
        }
866

    
867
        //Fam.
868
        TaxonNode familyTaxon = getFamilyTaxon(record, state);
869
        if (familyTaxon == null){
870
            if (record.get("Taxón") != null){
871
                logger.warn(line + "Family not recognized but taxon exists: " + record.get("Taxón"));
872
                return;
873
            }else if (record.get("Syn.") == null){
874
                logger.warn(line + "Family not recognized but also no synonym exists");
875
                return;
876
            }else{
877
                isSynonym = true;
878
            }
879
        }
880

    
881

    
882

    
883
        //Taxón
884
        Taxon taxon = makeTaxon(record, state, familyTaxon, isSynonym);
885
        if (taxon == null && ! isSynonym){
886
            logger.warn(line + "taxon could not be created and is null");
887
            return;
888
        }
889
        state.setCurrentTaxon(taxon);
890

    
891
        //Fam. ALT
892
        makeAlternativeFamilies(record, state, familyTaxon, taxon);
893

    
894
        //(Notas)
895
        makeNotes(record, state);
896

    
897
        //Syn.
898
        makeSynonyms(record, state);
899

    
900
        //End, Ind, Ind? D, Nat N, Dud P, Adv A, Cult C
901
        makeCubanDistribution(record, state);
902

    
903

    
904
//        "CuW","PR PR*","Art","Hab(*)","May","Mat","IJ",
905
//        "CuC","VC","Ci","SS","CA","Cam","LT",
906
//        "CuE","Gr","Ho","SC","Gu",
907
        makeProvincesDistribution(record, state);
908

    
909
//      "Esp","Ja","PR","Men","Bah","Cay",
910
//      "AmN","AmC","AmS","VM"});
911
        makeOtherAreasDistribution(record, state);
912

    
913

    
914
        state.setHighestStatusForTaxon(null);
915

    
916
		return;
917
    }
918

    
919

    
920

    
921
	/**
922
     * @param record
923
     * @param state
924
     * @param familyTaxon
925
     * @param taxon
926
     */
927
    private void makeAlternativeFamilies(HashMap<String, String> record,
928
            CubaImportState state,
929
            TaxonNode familyTaxon,
930
            Taxon taxon) {
931

    
932
        String famFRC = record.get("Fam. FRC");
933
        String famAS = record.get("Fam. A&S");
934
        String famFC = record.get("Fam. FC");
935

    
936
        Reference<?> refFRC = makeReference(state, CubaTransformer.uuidRefFRC);
937
        Reference<?> refAS = makeReference(state, CubaTransformer.uuidRefAS);
938
        Reference<?> refFC = makeReference(state, CubaTransformer.uuidRefFC);
939

    
940
        makeSingleAlternativeFamily(state, taxon, famFRC, refFRC);
941
        makeSingleAlternativeFamily(state, taxon, famAS, refAS);
942
        makeSingleAlternativeFamily(state, taxon, famFC, refFC);
943
    }
944

    
945

    
946
    /**
947
     * @param state
948
     * @param uuidreffrc
949
     * @return
950
     */
951
    private Reference<?> makeReference(CubaImportState state, UUID uuidRef) {
952
        Reference<?> ref = state.getReference(uuidRef);
953
        if (ref == null){
954
            ref = getReferenceService().find(uuidRef);
955
            state.putReference(uuidRef, ref);
956
        }
957
        return ref;
958
    }
959

    
960

    
961
    /**
962
     * @param state
963
     * @param taxon
964
     * @param famString
965
     * @param famRef
966
     */
967
    private void makeSingleAlternativeFamily(CubaImportState state, Taxon taxon, String famStr, Reference<?> famRef) {
968
        if (isBlank(famStr)){
969
            return;
970
        }
971

    
972
        TaxonDescription desc = getTaxonDescription(taxon, false, true);
973

    
974
        UUID altFamUuid1;
975
        UUID altFamUuid2;
976
        try {
977
            altFamUuid1 = state.getTransformer().getFeatureUuid("Alt.Fam.");
978
            altFamUuid2 = state.getTransformer().getFeatureUuid("Alt.Fam.2");
979
        } catch (UndefinedTransformerMethodException e) {
980
            throw new RuntimeException(e);
981
        }
982

    
983

    
984
        Taxon famTaxon = makeAlternativeFamilyTaxon(state, famStr, famRef);
985

    
986

    
987
        //TextData
988
        Feature feature1 = getFeature(state, altFamUuid1, "Family in other floras", "Family in other floras", "Other floras", null);
989
//        TextData textData = TextData.NewInstance(feature1, famStr, Language.DEFAULT(), null);
990
        TextData textData = TextData.NewInstance(feature1, null, Language.DEFAULT(), null);
991
        textData.addSource(OriginalSourceType.PrimaryTaxonomicSource, null,null, famRef, null, famTaxon.getName(),null);
992
        desc.addElement(textData);
993

    
994

    
995

    
996
        //TaxonInteraction
997
        Feature feature2 = getFeature(state, altFamUuid2, "Family in other floras(2)", "Family in other floras(2)", "Other floras(2)", null);
998
        feature2.setSupportsTaxonInteraction(true);
999
        TaxonInteraction taxInteract = TaxonInteraction.NewInstance(feature2);
1000
        taxInteract.setTaxon2(famTaxon);
1001
        taxInteract.addSource(OriginalSourceType.PrimaryTaxonomicSource, null,null, famRef, null);
1002
        desc.addElement(taxInteract);
1003

    
1004
        //Concept Relation
1005
        famTaxon.addTaxonRelation(taxon, TaxonRelationshipType.INCLUDES(), taxon.getSec(), null);
1006

    
1007
    }
1008

    
1009

    
1010

    
1011

    
1012

    
1013
    /**
1014
     * @param record
1015
     * @param state
1016
     * @param taxon
1017
     */
1018
    // "CuW","PR PR*","Art","Hab(*)","May","Mat","IJ",
1019
//  "CuC","VC","Ci","SS","CA","Cam","LT",
1020
//  "CuE","Gr","Ho","SC","Gu",
1021
    private void makeProvincesDistribution(HashMap<String, String> record, CubaImportState state) {
1022
        List<String> areaKeys = Arrays.asList(new String[]{
1023
                "CuW","PR PR*","Art","Hab(*)","May","Mat","IJ",
1024
                "CuC","VC","Ci","SS","CA","Cam","LT",
1025
                "CuE","Gr","Ho","SC","Gu",
1026
                });
1027
        for (String areaKey : areaKeys){
1028
            state.setCubanProvince(true);
1029
            makeSingleProvinceDistribution(areaKey, record, state);
1030
        }
1031
    }
1032

    
1033
    private void makeOtherAreasDistribution(HashMap<String, String> record, CubaImportState state) {
1034
        List<String> areaKeys = Arrays.asList(new String[]{
1035
                "Esp","Ja","PR","Men","Bah","Cay",
1036
                "AmN","AmC","AmS","VM"});
1037
        for (String areaKey : areaKeys){
1038
            state.setCubanProvince(false);
1039
            makeSingleProvinceDistribution(areaKey, record, state);
1040
        }
1041
    }
1042

    
1043

    
1044
    /**
1045
     * @param areaKey
1046
     * @param record
1047
     * @param state
1048
     * @param taxon
1049
     */
1050
    private void makeSingleProvinceDistribution(String areaKey,
1051
            HashMap<String, String> record,
1052
            CubaImportState state) {
1053
        try {
1054
            UUID areaUuid = state.getTransformer().getNamedAreaUuid(areaKey);
1055
            if (areaUuid == null){
1056
                logger.warn("Area not recognized: " + areaKey);
1057
                return;
1058
            }
1059
            if (record.get(areaKey)==null){
1060
                return; //no status defined
1061
            }
1062

    
1063
            NamedArea area = getNamedArea(state, areaUuid, null, null, null, null, null);
1064
            if (area == null){
1065
                logger.warn(state.getCurrentLine() + ": Area not recognized: " + area);
1066
            }
1067
            TaxonDescription desc = getTaxonDescription(state.getCurrentTaxon(), false, true);
1068
            PresenceAbsenceTerm status =  makeProvinceStatus(areaKey, record, state);
1069
            if (status == null){
1070
                logger.warn(state.getCurrentLine() + ": Province distribution status could not be defined: " + record.get(areaKey));
1071
            }
1072
            Distribution distribution = Distribution.NewInstance(area, status);
1073
            desc.addElement(distribution);
1074
        } catch (UndefinedTransformerMethodException e) {
1075
            e.printStackTrace();
1076
        }
1077

    
1078
    }
1079

    
1080

    
1081
    /**
1082
     * @param areaKey
1083
     * @param record
1084
     * @param state
1085
     * @param highestStatus
1086
     * @return
1087
     * @throws UndefinedTransformerMethodException
1088
     */
1089
    private PresenceAbsenceTerm makeProvinceStatus(String areaKey,
1090
            HashMap<String, String> record,
1091
            CubaImportState state) throws UndefinedTransformerMethodException {
1092

    
1093
        String statusStr = record.get(areaKey);
1094
        if (statusStr == null){
1095
            return null;
1096
        }
1097
        PresenceAbsenceTerm status = state.getTransformer().getPresenceTermByKey(statusStr);
1098
        if (status == null){
1099
            PresenceAbsenceTerm highestStatus = state.getHighestStatusForTaxon();
1100
            if (state.isCubanProvince() && isMinus(statusStr)){
1101
                getAbsenceTermForStatus(state, highestStatus);
1102
            }else if (! state.isCubanProvince() && isMinus(statusStr)){
1103
                status = state.getTransformer().getPresenceTermByKey("--");
1104
            }else{
1105
                UUID statusUuid = state.getTransformer().getPresenceTermUuid(statusStr);
1106
                status = getPresenceTerm(state, statusUuid, null, null, null, false);
1107
            }
1108
        }
1109

    
1110
        return status;
1111
    }
1112

    
1113

    
1114
    /**
1115
     * @param highestStatus
1116
     * @throws UndefinedTransformerMethodException
1117
     */
1118
    private PresenceAbsenceTerm getAbsenceTermForStatus(CubaImportState state, PresenceAbsenceTerm highestStatus) throws UndefinedTransformerMethodException {
1119
        if (highestStatus == null){
1120
            logger.warn(state.getCurrentLine() + ": Highest status not defined");
1121
            return null;
1122
        }
1123
        PresenceAbsenceTerm result = null;
1124
        if (highestStatus.equals(getStatus(state, "E"))){
1125
            result = getStatus(state, "-E");
1126
        }else if (highestStatus.getUuid().equals(state.getTransformer().getPresenceTermUuid("Ind.")) || highestStatus.equals(PresenceAbsenceTerm.NATIVE())){
1127
            result = getStatus(state, "-Ind.");
1128
        }else if (highestStatus.equals(getStatus(state, "Ind.?"))){
1129
            result = getStatus(state, "-Ind.?");  //TODO
1130
        }else if (highestStatus.equals(getStatus(state, "N"))){
1131
            result = getStatus(state, "-N");
1132
        }else if (highestStatus.equals(getStatus(state, "P"))){
1133
            result = getStatus(state, "-P");
1134
        }else if (highestStatus.equals(getStatus(state, "A"))){
1135
            result = getStatus(state, "-A");
1136
        }else if (highestStatus.equals(getStatus(state, "C"))){
1137
            result = getStatus(state, "-C");
1138
        }
1139
        logger.warn(state.getCurrentLine() + ": Absent province status could not be defined for highest status " + highestStatus.getTitleCache());
1140
        return result;
1141
    }
1142

    
1143

    
1144
    /**
1145
     * @param string
1146
     * @return
1147
     * @throws UndefinedTransformerMethodException
1148
     */
1149
    private PresenceAbsenceTerm getStatus(CubaImportState state, String key) throws UndefinedTransformerMethodException {
1150
        PresenceAbsenceTerm status = state.getTransformer().getPresenceTermByKey(key);
1151
        if (status == null){
1152
            UUID statusUuid = state.getTransformer().getPresenceTermUuid(key);
1153
            status = getPresenceTerm(state, statusUuid, null, null, null, false);
1154
        }
1155
        return status;
1156
    }
1157

    
1158

    
1159
    /**
1160
	 *  Stores parent-child, synonym and common name relationships
1161
	 */
1162
	@Override
1163
    protected void secondPass(CubaImportState state) {
1164
//		CyprusRow cyprusRow = state.getCyprusRow();
1165
		return;
1166
	}
1167

    
1168

    
1169
    @Override
1170
    protected boolean isIgnore(CubaImportState state) {
1171
        return ! state.getConfig().isDoTaxa();
1172
    }
1173

    
1174
    @Override
1175
    protected boolean doCheck(CubaImportState state) {
1176
        logger.warn("DoCheck not yet implemented for CubaExcelImport");
1177
        return true;
1178
    }
1179

    
1180
}
(1-1/5)