fauna europaea import fix
[cdmlib.git] / cdmlib-io / src / main / java / eu / etaxonomy / cdm / io / faunaEuropaea / FaunaEuropaeaTaxonImport.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.faunaEuropaea;
11
12 import static eu.etaxonomy.cdm.io.faunaEuropaea.FaunaEuropaeaTransformer.A_AUCT;
13 import static eu.etaxonomy.cdm.io.faunaEuropaea.FaunaEuropaeaTransformer.P_PARENTHESIS;
14 import static eu.etaxonomy.cdm.io.faunaEuropaea.FaunaEuropaeaTransformer.Q_NO_RESTRICTION;
15 import static eu.etaxonomy.cdm.io.faunaEuropaea.FaunaEuropaeaTransformer.R_GENUS;
16 import static eu.etaxonomy.cdm.io.faunaEuropaea.FaunaEuropaeaTransformer.R_SUBGENUS;
17 import static eu.etaxonomy.cdm.io.faunaEuropaea.FaunaEuropaeaTransformer.R_SPECIES;
18 import static eu.etaxonomy.cdm.io.faunaEuropaea.FaunaEuropaeaTransformer.R_SUBSPECIES;
19 import static eu.etaxonomy.cdm.io.faunaEuropaea.FaunaEuropaeaTransformer.T_STATUS_ACCEPTED;
20 import static eu.etaxonomy.cdm.io.faunaEuropaea.FaunaEuropaeaTransformer.T_STATUS_NOT_ACCEPTED;
21
22 import java.sql.ResultSet;
23 import java.sql.SQLException;
24 import java.util.Collection;
25 import java.util.HashMap;
26 import java.util.List;
27 import java.util.Map;
28 import java.util.Set;
29 import java.util.UUID;
30
31 import org.apache.log4j.Logger;
32 import org.springframework.stereotype.Component;
33 import org.springframework.transaction.TransactionStatus;
34
35 import eu.etaxonomy.cdm.common.CdmUtils;
36 import eu.etaxonomy.cdm.io.berlinModel.CdmOneToManyMapper;
37 import eu.etaxonomy.cdm.io.berlinModel.CdmStringMapper;
38 import eu.etaxonomy.cdm.io.berlinModel.in.BerlinModelImportState;
39 import eu.etaxonomy.cdm.io.common.CdmAttributeMapperBase;
40 import eu.etaxonomy.cdm.io.common.CdmSingleAttributeMapperBase;
41 import eu.etaxonomy.cdm.io.common.ICdmIO;
42 import eu.etaxonomy.cdm.io.common.IImportConfigurator;
43 import eu.etaxonomy.cdm.io.common.ImportHelper;
44 import eu.etaxonomy.cdm.io.common.MapWrapper;
45 import eu.etaxonomy.cdm.io.common.Source;
46 import eu.etaxonomy.cdm.io.tcsxml.in.TcsXmlImportState;
47 import eu.etaxonomy.cdm.model.agent.TeamOrPersonBase;
48 import eu.etaxonomy.cdm.model.common.CdmBase;
49 import eu.etaxonomy.cdm.model.common.ISourceable;
50 import eu.etaxonomy.cdm.model.common.IdentifiableEntity;
51 import eu.etaxonomy.cdm.model.common.OriginalSource;
52 import eu.etaxonomy.cdm.model.name.Rank;
53 import eu.etaxonomy.cdm.model.name.TaxonNameBase;
54 import eu.etaxonomy.cdm.model.name.ZoologicalName;
55 import eu.etaxonomy.cdm.model.reference.Database;
56 import eu.etaxonomy.cdm.model.reference.Generic;
57 import eu.etaxonomy.cdm.model.reference.PublicationBase;
58 import eu.etaxonomy.cdm.model.reference.Publisher;
59 import eu.etaxonomy.cdm.model.reference.ReferenceBase;
60 import eu.etaxonomy.cdm.model.taxon.Synonym;
61 import eu.etaxonomy.cdm.model.taxon.SynonymRelationshipType;
62 import eu.etaxonomy.cdm.model.taxon.Taxon;
63 import eu.etaxonomy.cdm.model.taxon.TaxonBase;
64 import eu.etaxonomy.cdm.model.taxon.TaxonomicTree;
65 import eu.etaxonomy.cdm.strategy.exceptions.UnknownCdmTypeException;
66
67
68 /**
69 * @author a.babadshanjan
70 * @created 12.05.2009
71 * @version 1.0
72 */
73 @Component
74 public class FaunaEuropaeaTaxonImport extends FaunaEuropaeaImportBase {
75
76 public static final String OS_NAMESPACE_TAXON = "Taxon";
77 private static final Logger logger = Logger.getLogger(FaunaEuropaeaTaxonImport.class);
78
79 /* Max number of taxa to retrieve (for test purposes) */
80 private int maxTaxa = 0;
81 /* Max number of taxa to be saved in CDM DB with one service call */
82 private int limit = 1000; // TODO: Make configurable
83 /* Max number of taxa to be retrieved from CDM DB with one service call */
84 private int limitRetrieve = 10000; // TODO: Make configurable
85 /* Interval for progress info message when retrieving taxa */
86 private int modCount = 10000;
87 /* Highest taxon index in the FauEu database */
88 private int highestTaxonIndex = 0;
89 /* Number of times method buildParentName() has been called for one taxon */
90 private int callCount = 0;
91 private Map<Integer, FaunaEuropaeaTaxon> fauEuTaxonMap = new HashMap();
92
93
94 /* (non-Javadoc)
95 * @see eu.etaxonomy.cdm.io.common.CdmIoBase#doCheck(eu.etaxonomy.cdm.io.common.IImportConfigurator)
96 */
97 @Override
98 protected boolean doCheck(FaunaEuropaeaImportState state) {
99 boolean result = true;
100 FaunaEuropaeaImportConfigurator fauEuConfig = state.getConfig();
101 logger.warn("Checking for Taxa not yet fully implemented");
102 result &= checkTaxonStatus(fauEuConfig);
103
104 return result;
105 }
106
107 /* (non-Javadoc)
108 * @see eu.etaxonomy.cdm.io.common.CdmIoBase#isIgnore(eu.etaxonomy.cdm.io.common.IImportConfigurator)
109 */
110 protected boolean isIgnore(FaunaEuropaeaImportState state) {
111 return ! state.getConfig().isDoTaxa();
112 }
113
114 private boolean checkTaxonStatus(FaunaEuropaeaImportConfigurator fauEuConfig) {
115 boolean result = true;
116 // try {
117 Source source = fauEuConfig.getSource();
118 String sqlStr = "";
119 ResultSet rs = source.getResultSet(sqlStr);
120 return result;
121 // } catch (SQLException e) {
122 // e.printStackTrace();
123 // return false;
124 // }
125 }
126
127 /* (non-Javadoc)
128 * @see eu.etaxonomy.cdm.io.common.CdmIoBase#doInvoke(eu.etaxonomy.cdm.io.common.IImportConfigurator, eu.etaxonomy.cdm.api.application.CdmApplicationController, java.util.Map)
129 */
130 protected boolean doInvoke(FaunaEuropaeaImportState state) {
131
132 boolean success = true;
133
134 if(logger.isInfoEnabled()) { logger.info("Start making taxa..."); }
135
136 TransactionStatus txStatus = startTransaction();
137
138 success = retrieveTaxa(state, fauEuTaxonMap, Q_NO_RESTRICTION);
139 // success = processTaxa(state);
140 // ProfilerController.memorySnapshot();
141 success = processTaxaFromDatabase(state, fauEuTaxonMap);
142
143 commitTransaction(txStatus);
144
145 logger.info("End making taxa...");
146 return success;
147 }
148
149
150 protected boolean doInvokeAlter(FaunaEuropaeaImportState state) {
151
152 Map<String, MapWrapper<? extends CdmBase>> stores = state.getStores();
153 MapWrapper<TaxonBase<?>> taxonStore = (MapWrapper<TaxonBase<?>>)stores.get(ICdmIO.TAXON_STORE);
154 // MapWrapper<TaxonNameBase<?,?>> taxonNamesStore = (MapWrapper<TaxonNameBase<?,?>>)stores.get(ICdmIO.TAXONNAME_STORE);
155 MapWrapper<TeamOrPersonBase> authorStore = (MapWrapper<TeamOrPersonBase>)stores.get(ICdmIO.TEAM_STORE);
156 // authorStore = null;
157 // Map<Integer, FaunaEuropaeaTaxon> fauEuTaxonMap = new HashMap();
158 FaunaEuropaeaImportConfigurator fauEuConfig = state.getConfig();
159 boolean success = true;
160
161 if(logger.isInfoEnabled()) { logger.info("Start making taxa..."); }
162
163 success = retrieveTaxa(state, fauEuTaxonMap, Q_NO_RESTRICTION);
164 success = processTaxaSecondPass(state, fauEuTaxonMap);
165 success = saveTaxa(state, highestTaxonIndex, state.getConfig().getLimitSave());
166 // success = saveTaxa(stores);
167
168 logger.info("End making taxa...");
169 return success;
170 }
171
172
173 /** Retrieve tax from FauEu DB and build FauEuTaxonMap only */
174 private boolean retrieveTaxa(FaunaEuropaeaImportState state,
175 Map<Integer, FaunaEuropaeaTaxon> fauEuTaxonMap, int valid) {
176
177 Map<String, MapWrapper<? extends CdmBase>> stores = state.getStores();
178 MapWrapper<TaxonBase> taxonStore = (MapWrapper<TaxonBase>)stores.get(ICdmIO.TAXON_STORE);
179 FaunaEuropaeaImportConfigurator fauEuConfig = state.getConfig();
180 ReferenceBase<?> sourceRef = fauEuConfig.getSourceReference();
181 MapWrapper<TeamOrPersonBase> authorStore = (MapWrapper<TeamOrPersonBase>)stores.get(ICdmIO.TEAM_STORE);
182
183 Source source = fauEuConfig.getSource();
184 // String namespace = "Taxon";
185 int i = 0;
186 boolean success = true;
187
188 try {
189
190 String strQuery =
191 " SELECT MAX(TAX_ID) AS TAX_ID FROM dbo.Taxon ";
192
193 ResultSet rs = source.getResultSet(strQuery);
194 while (rs.next()) {
195 int maxTaxonId = rs.getInt("TAX_ID");
196 highestTaxonIndex = maxTaxonId;
197 }
198
199 String top = "";
200 if (maxTaxa > 0) {
201 top = "TOP " + maxTaxa;
202 }
203
204 String validClause = "";
205 if (valid == T_STATUS_ACCEPTED || valid == T_STATUS_NOT_ACCEPTED) {
206 validClause = " AND " + " TAX_VALID = " + valid;
207 }
208
209 strQuery =
210 " SELECT " + top + " Taxon.*, rank.*, author.* " +
211 " FROM dbo.Taxon " +
212 " LEFT OUTER JOIN dbo.author ON dbo.Taxon.TAX_AUT_ID = dbo.author.aut_id " +
213 " LEFT OUTER JOIN dbo.rank ON dbo.Taxon.TAX_RNK_ID = dbo.rank.rnk_id " +
214 " WHERE (1=1)" +
215 validClause;
216
217 if (logger.isDebugEnabled()) {
218 logger.debug("Query: " + strQuery);
219 }
220 rs = source.getResultSet(strQuery);
221
222 while (rs.next()) {
223
224 if ((i++ % modCount) == 0 && i != 1 ) {
225 if(logger.isInfoEnabled()) {
226 logger.info("Taxa retrieved: " + (i-1));
227 }
228 }
229
230 int taxonId = rs.getInt("TAX_ID");
231 String localName = rs.getString("TAX_NAME");
232 int rankId = rs.getInt("TAX_RNK_ID");
233 int parentId = rs.getInt("TAX_TAX_IDPARENT");
234 int familyId = rs.getInt("TAX_TAX_IDFAMILY");
235 int originalGenusId = rs.getInt("TAX_TAX_IDGENUS");
236 int autId = rs.getInt("TAX_AUT_ID");
237 int status = rs.getInt("TAX_VALID");
238 int year = rs.getInt("TAX_YEAR");
239 int parenthesis = rs.getInt("TAX_PARENTHESIS");
240 String autName = rs.getString("aut_name");
241 Rank rank = null;
242 // UUID taxonBaseUuid = UUID.randomUUID();
243
244 FaunaEuropaeaTaxon fauEuTaxon = new FaunaEuropaeaTaxon();
245 // fauEuTaxon.setUuid(taxonBaseUuid);
246 fauEuTaxon.setLocalName(localName);
247 fauEuTaxon.setParentId(parentId);
248 fauEuTaxon.setOriginalGenusId(originalGenusId);
249 fauEuTaxon.setId(taxonId);
250 fauEuTaxon.setRankId(rankId);
251 fauEuTaxon.setYear(year);
252 fauEuTaxon.setAuthor(autName);
253 if (parenthesis == P_PARENTHESIS) {
254 fauEuTaxon.setParenthesis(true);
255 } else {
256 fauEuTaxon.setParenthesis(false);
257 }
258 if (status == T_STATUS_ACCEPTED) {
259 fauEuTaxon.setValid(true);
260 } else {
261 fauEuTaxon.setValid(false);
262 }
263
264 try {
265 rank = FaunaEuropaeaTransformer.rankId2Rank(rs, false);
266 } catch (UnknownCdmTypeException e) {
267 logger.warn("Taxon (" + taxonId + ") has unknown rank (" + rankId + ") and could not be saved.");
268 continue;
269 } catch (NullPointerException e) {
270 logger.warn("Taxon (" + taxonId + ") has rank null and can not be saved.");
271 continue;
272 }
273
274 try {
275
276 // ReferenceBase<?> sourceReference = fauEuConfig.getSourceReference();
277 // ReferenceBase<?> auctReference = fauEuConfig.getAuctReference();
278 //
279 // ZoologicalName zooName = ZoologicalName.NewInstance(rank);
280 // // set local name cache
281 // zooName.setNameCache(localName);
282 //
283 // TaxonBase<?> taxonBase;
284 //
285 // Synonym synonym;
286 // Taxon taxon;
287 // try {
288 // if ((status == T_STATUS_ACCEPTED) || (autId == A_AUCT)) { // taxon
289 // if (autId == A_AUCT) { // misapplied name
290 // taxon = Taxon.NewInstance(zooName, auctReference);
291 // if (logger.isDebugEnabled()) {
292 // logger.debug("Misapplied name created (" + taxonId + ")");
293 // }
294 // } else { // regular taxon
295 // taxon = Taxon.NewInstance(zooName, sourceReference);
296 // if (logger.isDebugEnabled()) {
297 // logger.debug("Taxon created (" + taxonId + ")");
298 // }
299 //
300 // if (fauEuTaxon.isParenthesis() && (fauEuTaxon.getOriginalGenusId() != 0)
301 // && (fauEuTaxon.getParentId() != fauEuTaxon.getOriginalGenusId())) {
302 //
303 // // create basionym
304 // TeamOrPersonBase<?> author = authorStore.get(autId);
305 // ZoologicalName basionym = ZoologicalName.NewInstance(rank);
306 // basionym.setNameCache(localName);
307 // basionym.setCombinationAuthorTeam(author);
308 // basionym.setPublicationYear(year);
309 // zooName.addBasionym(basionym, sourceReference, null, null);
310 // zooName.setBasionymAuthorTeam(author);
311 // if (logger.isDebugEnabled()) {
312 // logger.debug("Basionym created (" + taxonId + ")");
313 // }
314 //
315 // // create homotypic synonym
316 // Synonym homotypicSynonym = Synonym.NewInstance(basionym, sourceReference);
317 // taxon.addSynonym(homotypicSynonym, SynonymRelationshipType.HOMOTYPIC_SYNONYM_OF(),
318 // sourceReference, null);
319 // if (logger.isDebugEnabled()) {
320 // logger.debug("Homotypic synonym created (" + taxonId + ")");
321 // }
322 //
323 // }
324 //
325 // }
326 // taxonBase = taxon;
327 // } else if ((status == T_STATUS_NOT_ACCEPTED) && (autId != A_AUCT)) { // synonym
328 // synonym = Synonym.NewInstance(zooName, sourceReference);
329 // if (logger.isDebugEnabled()) {
330 // logger.debug("Synonym created (" + taxonId + ")");
331 // }
332 // taxonBase = synonym;
333 // } else {
334 // logger.warn("Unknown taxon status " + status + ". Taxon (" + taxonId + ") ignored.");
335 // continue;
336 // }
337 //
338 // taxonBase.setUuid(taxonBaseUuid);
339 //
340 // ImportHelper.setOriginalSource(taxonBase, fauEuConfig.getSourceReference(), taxonId, namespace);
341 //
342
343 // if (!taxonStore.containsId(taxonId)) {
344 // if (taxonBase == null) {
345 // if (logger.isDebugEnabled()) {
346 // logger.debug("Taxon base is null. Taxon (" + taxonId + ") ignored.");
347 // }
348 // continue;
349 // }
350
351 if (!fauEuTaxonMap.containsKey(taxonId)) {
352 if (fauEuTaxon == null) {
353 if (logger.isDebugEnabled()) {
354 logger.debug("Taxon base is null. Taxon (" + taxonId + ") ignored.");
355 }
356 continue;
357 }
358
359
360 // taxonStore.put(taxonId, taxonBase);
361
362 fauEuTaxonMap.put(taxonId, fauEuTaxon);
363
364 // if (logger.isDebugEnabled()) {
365 // logger.debug("Stored taxon base (" + taxonId + ") " + localName);
366 // }
367 } else {
368 logger.warn("Not imported taxon base with duplicated TAX_ID (" + taxonId +
369 ") " + localName);
370 }
371 } catch (Exception e) {
372 logger.warn("An exception occurred when creating taxon base with id " + taxonId +
373 ". Taxon base could not be saved.");
374 }
375 }
376 } catch (SQLException e) {
377 logger.error("SQLException:" + e);
378 success = false;
379 }
380
381 return success;
382 }
383
384
385 /** Retrieve tax from FauEu DB, build TaxonStore andFauEuTaxonMap */
386 private boolean retrieveTaxa_(FaunaEuropaeaImportState state,
387 Map<Integer, FaunaEuropaeaTaxon> fauEuTaxonMap, int valid) {
388
389 Map<String, MapWrapper<? extends CdmBase>> stores = state.getStores();
390 MapWrapper<TaxonBase> taxonStore = (MapWrapper<TaxonBase>)stores.get(ICdmIO.TAXON_STORE);
391 FaunaEuropaeaImportConfigurator fauEuConfig = state.getConfig();
392 ReferenceBase<?> sourceRef = fauEuConfig.getSourceReference();
393 MapWrapper<TeamOrPersonBase> authorStore = (MapWrapper<TeamOrPersonBase>)stores.get(ICdmIO.TEAM_STORE);
394
395 Source source = fauEuConfig.getSource();
396 // String namespace = "Taxon";
397 int i = 0;
398 boolean success = true;
399
400 try {
401
402 String strQuery =
403 " SELECT MAX(TAX_ID) AS TAX_ID FROM dbo.Taxon ";
404
405 ResultSet rs = source.getResultSet(strQuery);
406 while (rs.next()) {
407 int maxTaxonId = rs.getInt("TAX_ID");
408 highestTaxonIndex = maxTaxonId;
409 }
410
411 String top = "";
412 if (maxTaxa > 0) {
413 top = "TOP " + maxTaxa;
414 }
415
416 String validClause = "";
417 if (valid == T_STATUS_ACCEPTED || valid == T_STATUS_NOT_ACCEPTED) {
418 validClause = " AND " + " TAX_VALID = " + valid;
419 }
420
421 strQuery =
422 " SELECT " + top + " Taxon.*, rank.*, author.* " +
423 " FROM dbo.Taxon " +
424 " LEFT OUTER JOIN dbo.author ON dbo.Taxon.TAX_AUT_ID = dbo.author.aut_id " +
425 " LEFT OUTER JOIN dbo.rank ON dbo.Taxon.TAX_RNK_ID = dbo.rank.rnk_id " +
426 " WHERE (1=1)" +
427 validClause;
428
429 if (logger.isDebugEnabled()) {
430 logger.debug("Query: " + strQuery);
431 }
432 rs = source.getResultSet(strQuery);
433
434 while (rs.next()) {
435
436 if ((i++ % modCount) == 0 && i != 1 ) {
437 if(logger.isInfoEnabled()) {
438 logger.info("Taxa retrieved: " + (i-1));
439 }
440 }
441
442 int taxonId = rs.getInt("TAX_ID");
443 String localName = rs.getString("TAX_NAME");
444 int rankId = rs.getInt("TAX_RNK_ID");
445 int parentId = rs.getInt("TAX_TAX_IDPARENT");
446 int familyId = rs.getInt("TAX_TAX_IDFAMILY");
447 int originalGenusId = rs.getInt("TAX_TAX_IDGENUS");
448 int autId = rs.getInt("TAX_AUT_ID");
449 int status = rs.getInt("TAX_VALID");
450 int year = rs.getInt("TAX_YEAR");
451 int parenthesis = rs.getInt("TAX_PARENTHESIS");
452 String autName = rs.getString("aut_name");
453 Rank rank = null;
454 UUID taxonBaseUuid = UUID.randomUUID();
455
456 FaunaEuropaeaTaxon fauEuTaxon = new FaunaEuropaeaTaxon();
457 fauEuTaxon.setUuid(taxonBaseUuid);
458 fauEuTaxon.setLocalName(localName);
459 fauEuTaxon.setParentId(parentId);
460 fauEuTaxon.setOriginalGenusId(originalGenusId);
461 fauEuTaxon.setId(taxonId);
462 fauEuTaxon.setRankId(rankId);
463 fauEuTaxon.setYear(year);
464 fauEuTaxon.setAuthor(autName);
465 if (parenthesis == P_PARENTHESIS) {
466 fauEuTaxon.setParenthesis(true);
467 } else {
468 fauEuTaxon.setParenthesis(false);
469 }
470 if (status == T_STATUS_ACCEPTED) {
471 fauEuTaxon.setValid(true);
472 } else {
473 fauEuTaxon.setValid(false);
474 }
475
476 try {
477 rank = FaunaEuropaeaTransformer.rankId2Rank(rs, false);
478 } catch (UnknownCdmTypeException e) {
479 logger.warn("Taxon (" + taxonId + ") has unknown rank (" + rankId + ") and could not be saved.");
480 continue;
481 } catch (NullPointerException e) {
482 logger.warn("Taxon (" + taxonId + ") has rank null and can not be saved.");
483 continue;
484 }
485
486 ReferenceBase<?> sourceReference = fauEuConfig.getSourceReference();
487 ReferenceBase<?> auctReference = fauEuConfig.getAuctReference();
488
489 ZoologicalName zooName = ZoologicalName.NewInstance(rank);
490 // set local name cache
491 zooName.setNameCache(localName);
492
493 TaxonBase<?> taxonBase;
494
495 Synonym synonym;
496 Taxon taxon;
497 try {
498 if ((status == T_STATUS_ACCEPTED) || (autId == A_AUCT)) { // taxon
499 if (autId == A_AUCT) { // misapplied name
500 taxon = Taxon.NewInstance(zooName, auctReference);
501 if (logger.isDebugEnabled()) {
502 logger.debug("Misapplied name created (" + taxonId + ")");
503 }
504 } else { // regular taxon
505 taxon = Taxon.NewInstance(zooName, sourceReference);
506 if (logger.isDebugEnabled()) {
507 logger.debug("Taxon created (" + taxonId + ")");
508 }
509
510 if (fauEuTaxon.isParenthesis() && (fauEuTaxon.getOriginalGenusId() != 0)
511 && (fauEuTaxon.getParentId() != fauEuTaxon.getOriginalGenusId())) {
512
513 // create basionym
514 TeamOrPersonBase<?> author = authorStore.get(autId);
515 ZoologicalName basionym = ZoologicalName.NewInstance(rank);
516 basionym.setNameCache(localName);
517 basionym.setCombinationAuthorTeam(author);
518 basionym.setPublicationYear(year);
519 zooName.addBasionym(basionym, sourceReference, null, null);
520 zooName.setBasionymAuthorTeam(author);
521 if (logger.isDebugEnabled()) {
522 logger.debug("Basionym created (" + taxonId + ")");
523 }
524
525 // create homotypic synonym
526 Synonym homotypicSynonym = Synonym.NewInstance(basionym, sourceReference);
527 taxon.addSynonym(homotypicSynonym, SynonymRelationshipType.HOMOTYPIC_SYNONYM_OF(),
528 sourceReference, null);
529 if (logger.isDebugEnabled()) {
530 logger.debug("Homotypic synonym created (" + taxonId + ")");
531 }
532
533 }
534
535 }
536 taxonBase = taxon;
537 } else if ((status == T_STATUS_NOT_ACCEPTED) && (autId != A_AUCT)) { // synonym
538 synonym = Synonym.NewInstance(zooName, sourceReference);
539 if (logger.isDebugEnabled()) {
540 logger.debug("Synonym created (" + taxonId + ")");
541 }
542 taxonBase = synonym;
543 } else {
544 logger.warn("Unknown taxon status " + status + ". Taxon (" + taxonId + ") ignored.");
545 continue;
546 }
547
548 taxonBase.setUuid(taxonBaseUuid);
549
550 ImportHelper.setOriginalSource(taxonBase, fauEuConfig.getSourceReference(), taxonId, OS_NAMESPACE_TAXON);
551
552
553 if (!taxonStore.containsId(taxonId)) {
554 if (taxonBase == null) {
555 if (logger.isDebugEnabled()) {
556 logger.debug("Taxon base is null. Taxon (" + taxonId + ") ignored.");
557 }
558 continue;
559 }
560 taxonStore.put(taxonId, taxonBase);
561 fauEuTaxonMap.put(taxonId, fauEuTaxon);
562 // if (logger.isDebugEnabled()) {
563 // logger.debug("Stored taxon base (" + taxonId + ") " + localName);
564 // }
565 } else {
566 logger.warn("Not imported taxon base with duplicated TAX_ID (" + taxonId +
567 ") " + localName);
568 }
569 } catch (Exception e) {
570 logger.warn("An exception occurred when creating taxon base with id " + taxonId +
571 ". Taxon base could not be saved.");
572 }
573 }
574 } catch (SQLException e) {
575 logger.error("SQLException:" + e);
576 success = false;
577 }
578
579 return success;
580 }
581
582
583 // private boolean createAdditionalObjects(FaunaEuropaeaTaxon fauEuTaxon,
584 // TaxonBase<?> taxonBase, ZoologicalName zooName,
585 // FaunaEuropaeaImportState state) {
586 //
587 // Map<String, MapWrapper<? extends CdmBase>> stores = state.getStores();
588 // MapWrapper<TaxonBase> taxonStore = (MapWrapper<TaxonBase>)stores.get(ICdmIO.TAXON_STORE);
589 // FaunaEuropaeaImportConfigurator fauEuConfig = state.getConfig();
590 // ReferenceBase<?> sourceRef = fauEuConfig.getSourceReference();
591 // MapWrapper<TeamOrPersonBase> authorStore = (MapWrapper<TeamOrPersonBase>)stores.get(ICdmIO.TEAM_STORE);
592 //
593 // // create basionym
594 // if (fauEuTaxon.isParenthesis() && (fauEuTaxon.getOriginalGenusId() != 0)
595 // && (fauEuTaxon.getParentId() != fauEuTaxon.getOriginalGenusId())) {
596 // TeamOrPersonBase<?> author = authorStore.get(fauEuTaxon.getAuthorId());
597 // ZoologicalName basionym = ZoologicalName.NewInstance(fauEuTaxon.getRankId());
598 // basionym.setNameCache(fauEuTaxon.getLocalName());
599 // basionym.setCombinationAuthorTeam(author);
600 // basionym.setPublicationYear(fauEuTaxon.getYear());
601 // // TODO: add microcitation, rule considered
602 // zooName.addBasionym(basionym, sourceRef, null, null);
603 // zooName.setBasionymAuthorTeam(author);
604 // }
605 // }
606
607
608 private boolean processTaxaSecondPass_(FaunaEuropaeaImportState state,
609 Map<Integer, FaunaEuropaeaTaxon> fauEuTaxonMap) {
610
611 if(logger.isInfoEnabled()) { logger.info("Processing taxa second pass..."); }
612
613 Map<String, MapWrapper<? extends CdmBase>> stores = state.getStores();
614 // MapWrapper<TaxonNameBase<?,?>> taxonNamesStore = (MapWrapper<TaxonNameBase<?,?>>)stores.get(ICdmIO.TAXONNAME_STORE);
615 MapWrapper<TaxonBase> taxonStore = (MapWrapper<TaxonBase>)stores.get(ICdmIO.TAXON_STORE);
616 FaunaEuropaeaImportConfigurator fauEuConfig = state.getConfig();
617 ReferenceBase<?> sourceRef = fauEuConfig.getSourceReference();
618
619 boolean success = true;
620
621 for (int id : taxonStore.keySet())
622 {
623 TaxonBase<?> taxonBase = taxonStore.get(id);
624 TaxonNameBase<?,?> taxonName = taxonBase.getName();
625 FaunaEuropaeaTaxon fauEuTaxon = fauEuTaxonMap.get(id);
626
627 if (logger.isDebugEnabled()) { logger.debug("Taxon # " + id); }
628 String nameString = calculateTaxonName_(fauEuTaxon, taxonBase, taxonName, taxonStore, fauEuTaxonMap);
629 createRelationships__(fauEuTaxon, taxonBase, taxonName, fauEuTaxonMap, state);
630 setTaxonName(nameString, fauEuTaxon, taxonBase, fauEuConfig);
631 }
632 return success;
633 }
634
635
636 private boolean processTaxaSecondPass(FaunaEuropaeaImportState state,
637 Map<Integer, FaunaEuropaeaTaxon> fauEuTaxonMap) {
638
639 if(logger.isInfoEnabled()) { logger.info("Processing taxa second pass..."); }
640
641 Map<String, MapWrapper<? extends CdmBase>> stores = state.getStores();
642 // MapWrapper<TaxonNameBase<?,?>> taxonNamesStore = (MapWrapper<TaxonNameBase<?,?>>)stores.get(ICdmIO.TAXONNAME_STORE);
643 MapWrapper<TaxonBase> taxonStore = (MapWrapper<TaxonBase>)stores.get(ICdmIO.TAXON_STORE);
644 FaunaEuropaeaImportConfigurator fauEuConfig = state.getConfig();
645 ReferenceBase<?> sourceRef = fauEuConfig.getSourceReference();
646
647 boolean success = true;
648
649 for (int id : fauEuTaxonMap.keySet())
650 //for (int id : taxonStore.keySet())
651 {
652 TaxonBase<?> taxonBase = taxonStore.get(id);
653 if (taxonBase == null) {
654 continue;
655 }
656 TaxonNameBase<?,?> taxonName = taxonBase.getName();
657 FaunaEuropaeaTaxon fauEuTaxon = fauEuTaxonMap.get(id);
658
659 if (logger.isDebugEnabled()) { logger.debug("Taxon # " + id); }
660 String nameString = calculateTaxonName_(fauEuTaxon, taxonBase, taxonName, taxonStore, fauEuTaxonMap);
661 createRelationships__(fauEuTaxon, taxonBase, taxonName, fauEuTaxonMap, state);
662 setTaxonName(nameString, fauEuTaxon, taxonBase, fauEuConfig);
663 }
664 return success;
665 }
666
667
668 /* Remove last part of name */
669 private String removeEpithet(String nameString) {
670
671 String subString = nameString;
672 int index = nameString.lastIndexOf(" ");
673 if (index > 0) {
674 subString = nameString.substring(0, index);
675 }
676 return subString;
677 }
678
679
680 /* Build name title cache */
681 private String buildNameTitleCache(String nameString, FaunaEuropaeaTaxon fauEuTaxon) {
682
683 StringBuilder titleCacheStringBuilder = new StringBuilder(nameString);
684 int year = fauEuTaxon.getYear();
685 if (year != 0) { // TODO: Ignore authors like xp, xf, etc?
686 titleCacheStringBuilder.append(" ");
687 if (fauEuTaxon.isParenthesis() == true) {
688 titleCacheStringBuilder.append("(");
689 }
690 titleCacheStringBuilder.append(fauEuTaxon.getAuthor());
691 titleCacheStringBuilder.append(" ");
692 titleCacheStringBuilder.append(year);
693 if (fauEuTaxon.isParenthesis() == true) {
694 titleCacheStringBuilder.append(")");
695 }
696 }
697 return titleCacheStringBuilder.toString();
698 }
699
700
701 /* Build name full title cache */
702 private String buildNameFullTitleCache(String titleCache, FaunaEuropaeaImportConfigurator fauEuConfig) {
703
704 StringBuilder fullTitleCacheStringBuilder = new StringBuilder(titleCache);
705 fullTitleCacheStringBuilder.append(" ");
706 fullTitleCacheStringBuilder.append(fauEuConfig.getSourceReferenceTitle());
707 return fullTitleCacheStringBuilder.toString();
708 }
709
710
711 /* For a given rank, returns max number of recurse calls of buildParentName() */
712 public static int maxCallsPerRank(int rankId) {
713
714 int result;
715 switch(rankId) {
716 case R_GENUS:
717 result = 1;
718 break;
719 case R_SUBGENUS:
720 result = 2;
721 break;
722 case R_SPECIES:
723 result = 3;
724 break;
725 case R_SUBSPECIES:
726 result = 4;
727 break;
728 default:
729 result = 1;
730 }
731 return result;
732 }
733
734
735 /** Creates relationships if taxon bases are retrieved in chunks from CDM DB */
736 private boolean createRelationships(FaunaEuropaeaTaxon fauEuTaxon,
737 TaxonBase<?> taxonBase, TaxonNameBase<?,?> taxonName, List<TaxonBase> taxonBases,
738 Map<Integer, FaunaEuropaeaTaxon> fauEuTaxonMap, FaunaEuropaeaImportState state) {
739
740 int parentId = fauEuTaxon.getParentId();
741 int taxonId = fauEuTaxon.getId();
742 FaunaEuropaeaTaxon parentFauEuTaxon = fauEuTaxonMap.get(parentId);
743 if (parentFauEuTaxon == null) {
744 if (logger.isInfoEnabled()) {
745 logger.info("Parent taxon is null (" + parentId + ")");
746 }
747 return false;
748 }
749 // UUID parentUuid = parentFauEuTaxon.getUuid();
750 Map<String, MapWrapper<? extends CdmBase>> stores = state.getStores();
751 MapWrapper<TaxonBase> parentTaxonStore = (MapWrapper<TaxonBase>)stores.get(ICdmIO.TAXON_STORE);
752 ReferenceBase<?> sourceRef = state.getConfig().getSourceReference();
753
754 TaxonBase<?> parentTaxonBase = null;
755
756 // for (TaxonBase<?> potentialParentTaxon : taxonBases) {
757 // if(potentialParentTaxon.getUuid().equals(parentUuid)) {
758 // parentTaxonBase = potentialParentTaxon;
759 // break;
760 // }
761 // }
762 // if (parentTaxonBase == null) {
763 // parentTaxonBase = getTaxonService().getTaxonByUuid(parentUuid);
764 // }
765
766 // TODO: Copy parents from taxonBases to parentTaxonStore
767
768 if (parentTaxonStore.containsId(parentId)) {
769 parentTaxonBase = parentTaxonStore.get(parentId);
770 if (logger.isInfoEnabled()) {
771 logger.info("Parent (" + parentId + ") found in parent taxon store");
772 }
773 // } else {
774 // for (TaxonBase<?> potentialParentTaxon : taxonBases) {
775 // if(potentialParentTaxon.getId() == parentId) {
776 // parentTaxonBase = potentialParentTaxon;
777 // if (logger.isInfoEnabled()) {
778 // logger.info("Parent (" + parentId + ") found in taxon base list");
779 // }
780 // break;
781 // }
782 // }
783 }
784 if (parentTaxonBase == null) {
785 ISourceable sourceable =
786 getCommonService().getSourcedObjectByIdInSource(TaxonBase.class, Integer.toString(parentId), OS_NAMESPACE_TAXON);
787 parentTaxonBase = ((IdentifiableEntity)sourceable).deproxy(sourceable, TaxonBase.class);
788 if (logger.isInfoEnabled()) {
789 logger.info("Parent (" + parentId + ") retrieved from DB via original source id");
790 }
791 }
792
793 if (!parentTaxonStore.containsId(parentId)) {
794 parentTaxonStore.put(parentId, parentTaxonBase);
795 }
796
797
798
799 Taxon parentTaxon = parentTaxonBase.deproxy(parentTaxonBase, Taxon.class);
800
801 boolean success = true;
802
803 if (!fauEuTaxon.isValid()) { // FauEu Synonym
804
805 // if (fauEuTaxon.getAuthor() != null && fauEuTaxon.getAuthor().equals("A_AUCT_NAME")) {
806 // try {
807 // // add misapplied name relationship from this taxon to parent
808 // Taxon taxon = taxonBase.deproxy(taxonBase, Taxon.class);
809 // taxon.addMisappliedName(parentTaxon, sourceRef, null);
810 // if (logger.isDebugEnabled()) {
811 // logger.debug("Misapplied name created " + taxon.getUuid());
812 // }
813 //
814 // } catch (Exception e) {
815 // logger.error("Error creating misapplied name relationship for taxon (" +
816 // parentId + ")");
817 // }
818 // }
819 //
820 // else if((fauEuTaxon.getAuthor() == null)
821 // || (fauEuTaxon.getAuthor() != null && !fauEuTaxon.getAuthor().equals("A_AUCT_NAME"))) {
822 // try {
823 // // add this synonym as heterotypic synonym to parent
824 // Synonym synonym = taxonBase.deproxy(taxonBase, Synonym.class);
825 // parentTaxon.addSynonym(synonym, SynonymRelationshipType.HETEROTYPIC_SYNONYM_OF());
826 // if (logger.isDebugEnabled()) {
827 // logger.debug("Heterotypic synonym created " + synonym.getUuid());
828 // }
829 //
830 // } catch (Exception e) {
831 // logger.error("Error creating heterotypic synonym for taxon (" + parentId + ")");
832 //// e.printStackTrace();
833 // }
834 // }
835
836 } else if (fauEuTaxon.isValid()) { // FauEu Taxon
837 Taxon taxon = taxonBase.deproxy(taxonBase, Taxon.class);
838
839 try {
840 // add this taxon as child to parent
841 if (parentTaxon != null) {
842 makeTaxonomicallyIncluded(state, parentTaxon, taxon, sourceRef, null);
843 if (logger.isDebugEnabled()) {
844 logger.debug("Parent-child (" + parentId + "-" + taxonId +
845 ") relationship created");
846 }
847 }
848
849 } catch (Exception e) {
850 logger.error("Error creating taxonomically included relationship Parent-child (" +
851 parentId + "-" + taxonId + ")");
852 }
853
854 // TODO: build name and title caches of additional created objects
855 // (basionyms, homotypic synonyms)
856
857 // if (fauEuTaxon.isParenthesis() && (fauEuTaxon.getOriginalGenusId() != 0)
858 // && (fauEuTaxon.getParentId() != fauEuTaxon.getOriginalGenusId())) {
859 // calculateTaxonName(fauEuTaxon, true, taxonBase, taxonName, taxonStore, fauEuTaxonMap);
860 // }
861
862 }
863
864 return success;
865 }
866
867 /** Creates relationships for existing taxon store in memory */
868 private boolean createRelationships_(FaunaEuropaeaTaxon fauEuTaxon,
869 TaxonBase<?> taxonBase, TaxonNameBase<?,?> taxonName, List<TaxonBase> taxonBases,
870 Map<Integer, FaunaEuropaeaTaxon> fauEuTaxonMap, FaunaEuropaeaImportState state) {
871
872 int parentId = fauEuTaxon.getParentId();
873 int taxonId = fauEuTaxon.getId();
874 FaunaEuropaeaTaxon parentFauEuTaxon = fauEuTaxonMap.get(parentId);
875 if (parentFauEuTaxon == null) {
876 if (logger.isInfoEnabled()) {
877 logger.info("Parent taxon is null (" + parentId + ")");
878 }
879 return false;
880 }
881 UUID parentUuid = parentFauEuTaxon.getUuid();
882 Map<String, MapWrapper<? extends CdmBase>> stores = state.getStores();
883 MapWrapper<TaxonBase> taxonStore = (MapWrapper<TaxonBase>)stores.get(ICdmIO.TAXON_STORE);
884 ReferenceBase<?> sourceRef = state.getConfig().getSourceReference();
885
886 TaxonBase<?> parentTaxonBase = null;
887
888 for (TaxonBase<?> potentialParentTaxon : taxonBases) {
889 if(potentialParentTaxon.getUuid().equals(parentUuid)) {
890 parentTaxonBase = potentialParentTaxon;
891 break;
892 }
893 }
894 if (parentTaxonBase == null) {
895 parentTaxonBase = getTaxonService().getTaxonByUuid(parentUuid);
896 }
897
898 // TaxonBase<?> parentTaxonBase = taxonStore.get(parentId);
899 Taxon parentTaxon = parentTaxonBase.deproxy(parentTaxonBase, Taxon.class);
900 // FaunaEuropaeaTaxon parent = fauEuTaxonMap.get(parentId);
901 boolean success = true;
902
903 if (!fauEuTaxon.isValid()) { // FauEu Synonym
904
905 if (fauEuTaxon.getAuthor() != null && fauEuTaxon.getAuthor().equals("A_AUCT_NAME")) {
906 try {
907 // add misapplied name relationship from this taxon to parent
908 Taxon taxon = taxonBase.deproxy(taxonBase, Taxon.class);
909 taxon.addMisappliedName(parentTaxon, sourceRef, null);
910 if (logger.isDebugEnabled()) {
911 logger.debug("Misapplied name created " + taxon.getUuid());
912 }
913
914 } catch (Exception e) {
915 logger.error("Error creating misapplied name relationship for taxon (" +
916 parentId + ")");
917 }
918 }
919
920 else if((fauEuTaxon.getAuthor() == null)
921 || (fauEuTaxon.getAuthor() != null && !fauEuTaxon.getAuthor().equals("A_AUCT_NAME"))) {
922 try {
923 // add this synonym as heterotypic synonym to parent
924 Synonym synonym = taxonBase.deproxy(taxonBase, Synonym.class);
925 parentTaxon.addSynonym(synonym, SynonymRelationshipType.HETEROTYPIC_SYNONYM_OF());
926 if (logger.isDebugEnabled()) {
927 logger.debug("Heterotypic synonym created " + synonym.getUuid());
928 }
929
930 } catch (Exception e) {
931 logger.error("Error creating heterotypic synonym for taxon (" + parentId + ")");
932 // e.printStackTrace();
933 }
934 }
935
936 } else if (fauEuTaxon.isValid()) { // FauEu Taxon
937 Taxon taxon = taxonBase.deproxy(taxonBase, Taxon.class);
938
939 try {
940 // add this taxon as child to parent
941 if (parentTaxon != null) {
942 makeTaxonomicallyIncluded(state, parentTaxon, taxon, sourceRef, null);
943 if (logger.isDebugEnabled()) {
944 logger.debug("Parent-child (" + parentId + "-" + taxonId +
945 ") relationship created");
946 }
947 }
948
949 } catch (Exception e) {
950 logger.error("Error creating taxonomically included relationship Parent-child (" +
951 parentId + "-" + taxonId + ")");
952 }
953
954 // TODO: build name and title caches of additional created objects
955 // (basionyms, homotypic synonyms)
956
957 // if (fauEuTaxon.isParenthesis() && (fauEuTaxon.getOriginalGenusId() != 0)
958 // && (fauEuTaxon.getParentId() != fauEuTaxon.getOriginalGenusId())) {
959 // }
960
961 }
962
963 return success;
964 }
965
966
967 private boolean createRelationships__(FaunaEuropaeaTaxon fauEuTaxon,
968 TaxonBase<?> taxonBase, TaxonNameBase<?,?> taxonName,
969 Map<Integer, FaunaEuropaeaTaxon> fauEuTaxonMap, FaunaEuropaeaImportState state) {
970
971 int parentId = fauEuTaxon.getParentId();
972 int taxonId = fauEuTaxon.getId();
973 Map<String, MapWrapper<? extends CdmBase>> stores = state.getStores();
974 MapWrapper<TaxonBase> taxonStore = (MapWrapper<TaxonBase>)stores.get(ICdmIO.TAXON_STORE);
975 ReferenceBase<?> sourceRef = state.getConfig().getSourceReference();
976 TaxonBase<?> parentTaxonBase = taxonStore.get(parentId);
977 Taxon parentTaxon = parentTaxonBase.deproxy(parentTaxonBase, Taxon.class);
978 // FaunaEuropaeaTaxon parent = fauEuTaxonMap.get(parentId);
979 boolean success = true;
980
981 if (!fauEuTaxon.isValid()) { // FauEu Synonym
982
983 if (fauEuTaxon.getAuthor() != null && fauEuTaxon.getAuthor().equals("A_AUCT_NAME")) {
984 try {
985 // add misapplied name relationship from this taxon to parent
986 Taxon taxon = taxonBase.deproxy(taxonBase, Taxon.class);
987 taxon.addMisappliedName(parentTaxon, sourceRef, null);
988 if (logger.isInfoEnabled()) {
989 logger.info("Misapplied name created " + taxon.getUuid());
990 }
991
992 } catch (Exception e) {
993 logger.error("Error creating misapplied name relationship for taxon (" +
994 parentId + ")");
995 }
996 }
997
998 else if((fauEuTaxon.getAuthor() == null)
999 || (fauEuTaxon.getAuthor() != null && !fauEuTaxon.getAuthor().equals("A_AUCT_NAME"))) {
1000 try {
1001 // add this synonym as heterotypic synonym to parent
1002 Synonym synonym = taxonBase.deproxy(taxonBase, Synonym.class);
1003 parentTaxon.addSynonym(synonym, SynonymRelationshipType.HETEROTYPIC_SYNONYM_OF());
1004 if (logger.isDebugEnabled()) {
1005 logger.debug("Heterotypic synonym created " + synonym.getUuid());
1006 }
1007
1008 } catch (Exception e) {
1009 logger.error("Error creating heterotypic synonym for taxon (" + parentId + ")");
1010 // e.printStackTrace();
1011 }
1012 }
1013
1014 } else if (fauEuTaxon.isValid()) { // FauEu Taxon
1015 Taxon taxon = taxonBase.deproxy(taxonBase, Taxon.class);
1016
1017 try {
1018 // add this taxon as child to parent
1019 if (parentTaxon != null) {
1020 makeTaxonomicallyIncluded(state, parentTaxon, taxon, sourceRef, null);
1021 if (logger.isDebugEnabled()) {
1022 logger.debug("Parent-child (" + parentId + "-" + taxonId +
1023 ") relationship created");
1024 }
1025 }
1026
1027 } catch (Exception e) {
1028 logger.error("Error creating taxonomically included relationship Parent-child (" +
1029 parentId + "-" + taxonId + ")");
1030 }
1031
1032 // TODO: build name and title caches of additional created objects
1033 // (basionyms, homotypic synonyms)
1034
1035 // if (fauEuTaxon.isParenthesis() && (fauEuTaxon.getOriginalGenusId() != 0)
1036 // && (fauEuTaxon.getParentId() != fauEuTaxon.getOriginalGenusId())) {
1037 // }
1038
1039 }
1040
1041 return success;
1042 }
1043
1044
1045 private boolean makeTaxonomicallyIncluded(FaunaEuropaeaImportState state, Taxon toTaxon, Taxon fromTaxon, ReferenceBase citation, String microCitation){
1046 boolean success = true;
1047 ReferenceBase sec = toTaxon.getSec();
1048 TaxonomicTree tree = state.getTree(sec);
1049 if (tree == null){
1050 tree = makeTree(state, sec);
1051 }
1052 success = tree.addParentChild(toTaxon, fromTaxon, citation, microCitation);
1053 return success;
1054 }
1055
1056
1057 /* Build parent's taxon name for taxa directly imported from FauEu DB
1058 * and additionally created taxa and names */
1059 private String buildParentName(int maxCalls, String concatString, boolean useOriginalGenus,
1060 FaunaEuropaeaTaxon fauEuTaxon, MapWrapper<TaxonBase> taxonStore) {
1061
1062 callCount++;
1063 if (logger.isDebugEnabled()) {
1064 logger.debug("Call counter: " + callCount);
1065 }
1066
1067 /* Concatenated name string of parent */
1068 String parentConcatString = concatString;
1069
1070 StringBuilder parentConcatStringBuilder = new StringBuilder();
1071 /* Local name of parent */
1072 String parentString = null;
1073
1074 int parentId = fauEuTaxon.getParentId();
1075 int rankId = fauEuTaxon.getRankId();
1076 FaunaEuropaeaTaxon parent = fauEuTaxonMap.get(parentId);
1077
1078 if (parent == null) {
1079 if (logger.isDebugEnabled()) {
1080 logger.debug("Parent of taxon (" + fauEuTaxon.getId() + ") is null");
1081 }
1082 return parentConcatString;
1083 }
1084 if (logger.isDebugEnabled()) {
1085 logger.debug("Concat string: " + concatString);
1086 }
1087
1088 if ((rankId == R_SPECIES || rankId == R_SUBSPECIES) || (rankId == R_SUBGENUS && callCount > 1)) {
1089 UUID parentUuid = parent.getUuid();
1090 if (parentUuid != null) {
1091
1092 parentString = parent.getLocalName();
1093
1094 if (logger.isDebugEnabled()) {
1095 logger.debug("Parent string: " + parentString);
1096 }
1097 if (!fauEuTaxon.isValid()) {
1098 // parentString = exchangeEpithet(parentString);
1099 parentString = "";
1100 if (logger.isDebugEnabled()) {
1101 logger.debug("Emptied synonym's parent string");
1102 }
1103 }
1104
1105 if (parent.getRankId() == R_SUBGENUS) {
1106 parentConcatStringBuilder.append("(");
1107 }
1108
1109 // if (parent.getOriginalGenusId() != 0) {
1110 // originalGenusId = parent.getOriginalGenusId();
1111 // }
1112
1113 parentConcatStringBuilder.append(parentString);
1114
1115 if (parent.getRankId() == R_SUBGENUS) {
1116 parentConcatStringBuilder.append(")");
1117 }
1118 parentConcatStringBuilder.append(" ");
1119 parentConcatStringBuilder.append(concatString);
1120 parentConcatString = parentConcatStringBuilder.toString();
1121
1122 if (logger.isDebugEnabled()) {
1123 logger.debug("Concatenated name: " + parentConcatString);
1124 }
1125 } else {
1126 logger.warn("Parent uuid of " + parentId + " is null");
1127 }
1128
1129 } else { // Higher ranks
1130 if (logger.isDebugEnabled()) {
1131 logger.debug("Name complete for taxon rank (" + rankId + ")");
1132 }
1133 return parentConcatString;
1134 }
1135
1136 if (callCount <= maxCalls) {
1137 if ((rankId == R_SPECIES || rankId == R_SUBSPECIES) || (rankId == R_SUBGENUS && callCount > 1)) {
1138 parentConcatString = buildParentName(maxCalls, parentConcatString, true, parent, taxonStore);
1139 }
1140 }
1141
1142 return parentConcatString;
1143 }
1144
1145
1146 /* Build parent's taxon name for taxa directly imported from FauEu DB*/
1147 private String buildParentName_(int maxCalls, String concatString, FaunaEuropaeaTaxon fauEuTaxon,
1148 // private String buildParentName(int originalTaxonRank, String concatString, FaunaEuropaeaTaxon fauEuTaxon,
1149 MapWrapper<TaxonBase> taxonStore) {
1150
1151 callCount++;
1152 if (logger.isDebugEnabled()) {
1153 logger.debug("Call counter: " + callCount);
1154 }
1155
1156 /* Concatenated name string of parent */
1157 // String parentConcatString = "";
1158 String parentConcatString = concatString;
1159
1160 StringBuilder parentConcatStringBuilder = new StringBuilder();
1161 /* Local name of parent */
1162 String parentString = null;
1163
1164 int parentId = fauEuTaxon.getParentId();
1165 int rankId = fauEuTaxon.getRankId();
1166 FaunaEuropaeaTaxon parent = fauEuTaxonMap.get(parentId);
1167 // TaxonBase<?> parentTaxonBase = null;
1168 // TaxonNameBase<?,?> parentName = null;
1169
1170 if (parent == null) {
1171 if (logger.isDebugEnabled()) {
1172 logger.debug("Parent of taxon (" + fauEuTaxon.getId() + ") is null");
1173 }
1174 return parentConcatString;
1175 }
1176 if (logger.isDebugEnabled()) {
1177 logger.debug("Concat string: " + concatString);
1178 }
1179
1180 if ((rankId == R_SPECIES || rankId == R_SUBSPECIES) || (rankId == R_SUBGENUS && callCount > 1)) {
1181 UUID parentUuid = parent.getUuid();
1182 if (parentUuid != null) {
1183 // parentTaxonBase = taxonStore.get(parentId);
1184 // if (parentTaxonBase != null) {
1185 // parentName = parentTaxonBase.getName();
1186 // if(parentName != null) {
1187 // parentString = ((ZoologicalName)parentName).getNameCache();
1188
1189
1190 parentString = parent.getLocalName();
1191
1192
1193 // if (fauEuTaxon.isValid()) {
1194 // parentString = parent.getLocalName();
1195 // } else {
1196 // parentString = fauEuTaxon.get
1197 // }
1198
1199 // parentString is either already complete or just local, depending on whether the
1200 // parent taxon has already processed
1201 if (logger.isDebugEnabled()) {
1202 logger.debug("Parent string: " + parentString);
1203 }
1204 if (!fauEuTaxon.isValid()) {
1205 // parentString = exchangeEpithet(parentString);
1206 parentString = "";
1207 if (logger.isDebugEnabled()) {
1208 logger.debug("Emptied synonym's parent string");
1209 }
1210 }
1211 // } else {
1212 // logger.warn("Parent taxon name of taxon (uuid= " + parentUuid.toString() + "), id = " +
1213 // parent.getId() + ") is null");
1214 // }
1215 // } else {
1216 // logger.warn("Parent taxon (uuid= " + parentUuid.toString() + "), id = " +
1217 // parent.getId() + ") is null");
1218 // }
1219 // if (parent.isNameComplete()) {
1220 // // make sure to stop parent name building
1221 // callCount = 1000;
1222 // }
1223 // if (parent.getRankId() == R_SUBGENUS && !parent.isNameComplete()) {
1224
1225 if (parent.getRankId() == R_SUBGENUS) {
1226 parentConcatStringBuilder.append("(");
1227 }
1228 parentConcatStringBuilder.append(parentString);
1229 // if (parent.getRankId() == R_SUBGENUS && !parent.isNameComplete()) {
1230 if (parent.getRankId() == R_SUBGENUS) {
1231 parentConcatStringBuilder.append(")");
1232 }
1233 parentConcatStringBuilder.append(" ");
1234 parentConcatStringBuilder.append(concatString);
1235 parentConcatString = parentConcatStringBuilder.toString();
1236
1237 if (logger.isDebugEnabled()) {
1238 logger.debug("Concatenated name: " + parentConcatString);
1239 }
1240 } else {
1241 logger.warn("Parent uuid of " + parentId + " is null");
1242 }
1243
1244 } else { // Higher ranks
1245 if (logger.isDebugEnabled()) {
1246 logger.debug("Name complete for taxon rank (" + rankId + ")");
1247 }
1248 return parentConcatString;
1249 }
1250 // int maxCalls = maxCallsPerRank(originalTaxonRank);
1251 // if (logger.isDebugEnabled()) {
1252 // logger.debug("Call counter: " + callCount);
1253 // logger.debug("Max calls: " + maxCalls);
1254 // }
1255 if (callCount <= maxCalls) {
1256 if ((rankId == R_SPECIES || rankId == R_SUBSPECIES) || (rankId == R_SUBGENUS && callCount > 1)) {
1257 parentConcatString = buildParentName_(maxCalls, parentConcatString, parent, taxonStore);
1258 // parentConcatString = buildParentName(originalTaxonRank, parentConcatString, parent, taxonStore);
1259 }
1260 }
1261
1262 return parentConcatString;
1263 }
1264
1265
1266 /* Build taxon's concatenated name string for taxa directly imported from FauEU DB
1267 * and additionally created taxa */
1268 private String calculateTaxonName(FaunaEuropaeaTaxon fauEuTaxon, boolean useOriginalGenus,
1269 TaxonBase<?> taxonBase, TaxonNameBase<?,?>taxonName, MapWrapper<TaxonBase> taxonStore,
1270 Map<Integer, FaunaEuropaeaTaxon> fauEuTaxonMap) {
1271
1272 /* Local name string */
1273 String localString = "";
1274 /* Concatenated parent's name string */
1275 String parentString = "";
1276
1277 // TaxonNameBase<?,?> taxonName = taxonBase.getName();
1278 ZoologicalName zooName = (ZoologicalName)taxonName;
1279
1280 if (zooName != null) {
1281 localString = zooName.getNameCache();
1282 }
1283
1284 int rank = fauEuTaxon.getRankId();
1285
1286 if(logger.isDebugEnabled()) {
1287 logger.debug("Local taxon name (rank = " + rank + "): " + localString);
1288 }
1289
1290 callCount = 0;
1291 int maxCalls = maxCallsPerRank(rank);
1292 if (logger.isDebugEnabled()) {
1293 logger.debug("Max calls: " + maxCalls);
1294 }
1295 parentString = buildParentName(maxCalls, localString, useOriginalGenus, fauEuTaxon, taxonStore);
1296 // parentString = buildParentName(rank, localString, fauEuTaxon, taxonStore);
1297 parentString = (String) CdmUtils.removeDuplicateWhitespace(parentString.trim());
1298 return parentString;
1299 }
1300
1301
1302 /* Build taxon's concatenated name string for taxa directly imported from FauEU DB */
1303 private String calculateTaxonName_(FaunaEuropaeaTaxon fauEuTaxon,
1304 TaxonBase<?> taxonBase, TaxonNameBase<?,?>taxonName, MapWrapper<TaxonBase> taxonStore,
1305 Map<Integer, FaunaEuropaeaTaxon> fauEuTaxonMap) {
1306
1307 /* Local name string */
1308 String localString = "";
1309 /* Concatenated parent's name string */
1310 String parentString = "";
1311
1312 // TaxonNameBase<?,?> taxonName = taxonBase.getName();
1313 ZoologicalName zooName = (ZoologicalName)taxonName;
1314
1315 if (zooName != null) {
1316 localString = zooName.getNameCache();
1317 }
1318
1319 int rank = fauEuTaxon.getRankId();
1320
1321 if(logger.isDebugEnabled()) {
1322 logger.debug("Local taxon name (rank = " + rank + "): " + localString);
1323 }
1324
1325 callCount = 0;
1326 int maxCalls = maxCallsPerRank(rank);
1327 if (logger.isDebugEnabled()) {
1328 logger.debug("Max calls: " + maxCalls);
1329 }
1330 parentString = buildParentName(maxCalls, localString, false, fauEuTaxon, taxonStore);
1331 // parentString = buildParentName(rank, localString, fauEuTaxon, taxonStore);
1332 parentString = (String) CdmUtils.removeDuplicateWhitespace(parentString.trim());
1333 return parentString;
1334 }
1335
1336
1337 /* Build taxon name */
1338 private boolean setTaxonName(String concatString, FaunaEuropaeaTaxon fauEuTaxon,
1339 TaxonBase<?> taxonBase, FaunaEuropaeaImportConfigurator fauEuConfig) {
1340
1341 boolean success = true;
1342
1343 TaxonNameBase<?,?> taxonName = taxonBase.getName();
1344 ZoologicalName zooName = (ZoologicalName)taxonName;
1345
1346 zooName.setNameCache(concatString);
1347 String titleCache = buildNameTitleCache(concatString, fauEuTaxon);
1348 zooName.setTitleCache(titleCache);
1349 //titleCache = buildNameFullTitleCache(concatString, fauEuConfig);
1350 zooName.setFullTitleCache(titleCache); // TODO: Add reference, NC status
1351
1352 ImportHelper.setOriginalSource(taxonName, fauEuConfig.getSourceReference(),
1353 fauEuTaxon.getId(), "TaxonName");
1354
1355 // Set the complete scientific name in FaunaEuropaeaTaxon,
1356 // including parent(s) parts.
1357 // fauEuTaxon.setScientificName(concatString);
1358 // fauEuTaxon.setNameComplete(true);
1359
1360 if (logger.isDebugEnabled()) {
1361 logger.debug("Name stored: " + concatString);
1362 }
1363 return success;
1364 }
1365
1366
1367 private boolean processTaxaFromDatabase(FaunaEuropaeaImportState state,
1368 Map<Integer, FaunaEuropaeaTaxon> fauEuTaxonMap) {
1369
1370 if(logger.isInfoEnabled()) { logger.info("Processing taxa second pass..."); }
1371
1372 MapWrapper<TaxonBase> taxonBaseMap = new MapWrapper<TaxonBase>(null);
1373
1374 int nbrOfTaxa = getTaxonService().count(TaxonBase.class);
1375 int n = 0;
1376
1377 boolean success = true;
1378
1379 if (nbrOfTaxa < limit) { // TODO: test with critical values
1380 limit = nbrOfTaxa;
1381 } else {
1382 n = nbrOfTaxa / limit;
1383 }
1384
1385 if(logger.isInfoEnabled()) {
1386 logger.info("number of taxa = " + nbrOfTaxa
1387 + ", limit = " + limit
1388 + ", n = " + n);
1389 }
1390
1391 // process taxa in chunks of <=limit
1392
1393 for (int j = 1; j <= n + 1; j++)
1394 {
1395
1396 int offset = j - 1;
1397 int start = offset * limit;
1398
1399 if(logger.isInfoEnabled()) { logger.info("Processing taxa: " + start + " - " + (start + limit - 1)); }
1400
1401 if(logger.isInfoEnabled()) {
1402 logger.info("index = " + j
1403 + ", offset = " + offset
1404 + ", start = " + start);
1405 }
1406
1407 if (j == n + 1) {
1408 limit = nbrOfTaxa - n * limit;
1409 if(logger.isInfoEnabled()) { logger.info("n = " + n + " limit = " + limit); }
1410 }
1411
1412 TransactionStatus txStatus = startTransaction();
1413
1414 List<TaxonBase> taxonBases = getTaxonService().getAllTaxonBases(limit, start);
1415 if(logger.isInfoEnabled()) {
1416 logger.info(taxonBases.size() + " taxa retrieved from CDM DB");
1417 }
1418
1419 for (TaxonBase taxonBase : taxonBases) {
1420
1421 TaxonNameBase<?,?> taxonName = taxonBase.getName();
1422
1423 FaunaEuropaeaTaxon fauEuTaxon = findFauEuTaxonByOriginalSourceId(taxonBase, fauEuTaxonMap);
1424
1425
1426 if (logger.isDebugEnabled()) {
1427 logger.debug("Taxon # " + fauEuTaxon.getId());
1428 }
1429 createRelationships(fauEuTaxon, taxonBase, taxonName, taxonBases, fauEuTaxonMap, state);
1430 }
1431
1432 getTaxonService().saveTaxonAll(taxonBases);
1433 taxonBases = null;
1434
1435 commitTransaction(txStatus);
1436
1437 // empty parent taxon store
1438 // Map<String, MapWrapper<? extends CdmBase>> stores = state.getStores();
1439 // MapWrapper<TaxonBase> parentTaxonStore = (MapWrapper<TaxonBase>)stores.get(ICdmIO.TAXON_STORE);
1440 // parentTaxonStore.makeEmpty();
1441 }
1442 return success;
1443 }
1444
1445
1446 private FaunaEuropaeaTaxon findFauEuTaxonByOriginalSourceId(TaxonBase<?> taxonBase,
1447 Map<Integer, FaunaEuropaeaTaxon> fauEuTaxonMap) {
1448
1449 Set set = taxonBase.getSources();
1450 Object[] array = set.toArray();
1451 if (array.length == 0) { return null; }
1452 OriginalSource os = (OriginalSource) taxonBase.getSources().toArray()[0];
1453 String taxonBaseIdStr = os.getIdInSource();
1454 int taxonBaseId = Integer.parseInt(taxonBaseIdStr);
1455 FaunaEuropaeaTaxon fauEuTaxon = fauEuTaxonMap.get(taxonBaseId);
1456
1457 return fauEuTaxon;
1458 }
1459
1460
1461 private boolean processTaxa(FaunaEuropaeaImportState state) {
1462
1463 if(logger.isInfoEnabled()) { logger.info("Processing taxa first pass..."); }
1464
1465 Map<String, MapWrapper<? extends CdmBase>> stores = state.getStores();
1466 MapWrapper<TaxonBase> taxonStore = (MapWrapper<TaxonBase>)stores.get(ICdmIO.TAXON_STORE);
1467 FaunaEuropaeaImportConfigurator fauEuConfig = state.getConfig();
1468 ReferenceBase<?> sourceRef = fauEuConfig.getSourceReference();
1469
1470 int n = 0;
1471 int nbrOfTaxa = highestTaxonIndex;
1472 // int nbrOfTaxa = taxonStore.size();
1473 boolean success = true;
1474
1475 if (nbrOfTaxa < limit) { // TODO: test with critical values
1476 limit = nbrOfTaxa;
1477 } else {
1478 n = nbrOfTaxa / limit;
1479 }
1480
1481 if(logger.isInfoEnabled()) {
1482 logger.info("number of taxa = " + taxonStore.size()
1483 + ", highest taxon index = " + highestTaxonIndex
1484 + ", limit = " + limit
1485 + ", n = " + n);
1486 }
1487
1488 // process taxa in chunks of <=limit
1489
1490 for (int j = 1; j <= n + 1; j++)
1491 {
1492 int offset = j - 1;
1493 int start = offset * limit;
1494
1495 if(logger.isInfoEnabled()) { logger.info("Saving taxa: " + start + " - " + (start + limit - 1)); }
1496
1497 if(logger.isInfoEnabled()) {
1498 logger.info("index = " + j
1499 + ", offset = " + offset
1500 + ", start = " + start);
1501 }
1502
1503 if (j == n + 1) {
1504 limit = nbrOfTaxa - n * limit;
1505 if(logger.isInfoEnabled()) { logger.info("n = " + n + " limit = " + limit); }
1506 }
1507
1508 Collection<TaxonBase> taxonBases = taxonStore.objects(start, limit);
1509
1510 for (TaxonBase taxonBase : taxonBases) {
1511
1512 TaxonNameBase<?,?> taxonName = taxonBase.getName();
1513
1514 // OriginalSource os = (OriginalSource) taxonBase.getSources().toArray()[0];
1515 // String taxonBaseIdStr = os.getIdInSource();
1516 // int taxonBaseId = Integer.parseInt(taxonBaseIdStr);
1517 // FaunaEuropaeaTaxon fauEuTaxon = fauEuTaxonMap.get(taxonBaseId);
1518
1519 FaunaEuropaeaTaxon fauEuTaxon = findFauEuTaxonByOriginalSourceId(taxonBase, fauEuTaxonMap);
1520
1521 if (logger.isDebugEnabled()) {
1522 logger.debug("Taxon # " + fauEuTaxon.getId());
1523 }
1524 String nameString = calculateTaxonName(fauEuTaxon, false, taxonBase, taxonName, taxonStore, fauEuTaxonMap);
1525 setTaxonName(nameString, fauEuTaxon, taxonBase, fauEuConfig);
1526
1527 }
1528
1529 getTaxonService().saveTaxonAll(taxonBases);
1530 taxonStore.removeObjects(start, limit);
1531 taxonBases = null;
1532 }
1533
1534 return success;
1535 }
1536
1537
1538 private boolean saveTaxa(Map<String, MapWrapper<? extends CdmBase>> stores) {
1539
1540 MapWrapper<TaxonBase> taxonStore = (MapWrapper<TaxonBase>)stores.get(ICdmIO.TAXON_STORE);
1541
1542 int n = 0;
1543 int nbrOfTaxa = highestTaxonIndex;
1544 // int nbrOfTaxa = taxonStore.size();
1545 boolean success = true;
1546
1547 if(logger.isInfoEnabled()) { logger.info("Saving taxa ..."); }
1548
1549 if (nbrOfTaxa < limit) { // TODO: test with critical values
1550 limit = nbrOfTaxa;
1551 } else {
1552 n = nbrOfTaxa / limit;
1553 }
1554
1555 if(logger.isInfoEnabled()) {
1556 logger.info("number of taxa = " + taxonStore.size()
1557 + ", highest taxon index = " + highestTaxonIndex
1558 + ", limit = " + limit
1559 + ", n = " + n);
1560 }
1561
1562 // save taxa in chunks of <=limit
1563
1564 for (int j = 1; j <= n + 1; j++)
1565 {
1566 int offset = j - 1;
1567 int start = offset * limit;
1568
1569 if(logger.isInfoEnabled()) { logger.info("Saving taxa: " + start + " - " + (start + limit - 1)); }
1570
1571 if(logger.isInfoEnabled()) {
1572 logger.info("index = " + j
1573 + ", offset = " + offset
1574 + ", start = " + start);
1575 }
1576
1577 if (j == n + 1) {
1578 limit = nbrOfTaxa - n * limit;
1579 if(logger.isInfoEnabled()) { logger.info("n = " + n + " limit = " + limit); }
1580 }
1581
1582 Collection<TaxonBase> taxonMapPart = taxonStore.objects(start, limit);
1583 getTaxonService().saveTaxonAll(taxonMapPart);
1584 taxonMapPart = null;
1585 //taxonStore.removeObjects(start, limit);
1586 }
1587
1588 return success;
1589 }
1590 }