Unifiy name and taxon creation
[cdmlib-apps.git] / app-import / src / main / java / eu / etaxonomy / cdm / io / cuba / CubaExcelImport.java
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 }