1
2
3
4
5
6
7
8
9
10 package eu.etaxonomy.cdm.io.berlinModel.in;
11
12 import java.sql.ResultSet;
13 import java.sql.SQLException;
14 import java.util.HashMap;
15 import java.util.HashSet;
16 import java.util.Map;
17 import java.util.Set;
18 import java.util.UUID;
19
20 import org.apache.log4j.Logger;
21 import org.springframework.stereotype.Component;
22
23 import eu.etaxonomy.cdm.common.CdmUtils;
24 import eu.etaxonomy.cdm.io.berlinModel.BerlinModelTransformer;
25 import eu.etaxonomy.cdm.io.berlinModel.in.validation.BerlinModelTaxonNameImportValidator;
26 import eu.etaxonomy.cdm.io.common.IImportConfigurator;
27 import eu.etaxonomy.cdm.io.common.IOValidator;
28 import eu.etaxonomy.cdm.io.common.ImportHelper;
29 import eu.etaxonomy.cdm.io.common.ResultSetPartitioner;
30 import eu.etaxonomy.cdm.io.common.Source;
31 import eu.etaxonomy.cdm.model.agent.Person;
32 import eu.etaxonomy.cdm.model.agent.Team;
33 import eu.etaxonomy.cdm.model.agent.TeamOrPersonBase;
34 import eu.etaxonomy.cdm.model.common.CdmBase;
35 import eu.etaxonomy.cdm.model.common.Extension;
36 import eu.etaxonomy.cdm.model.common.ExtensionType;
37 import eu.etaxonomy.cdm.model.name.BotanicalName;
38 import eu.etaxonomy.cdm.model.name.CultivarPlantName;
39 import eu.etaxonomy.cdm.model.name.NonViralName;
40 import eu.etaxonomy.cdm.model.name.Rank;
41 import eu.etaxonomy.cdm.model.name.TaxonNameBase;
42 import eu.etaxonomy.cdm.model.name.ZoologicalName;
43 import eu.etaxonomy.cdm.model.reference.INomenclaturalReference;
44 import eu.etaxonomy.cdm.model.reference.ReferenceBase;
45 import eu.etaxonomy.cdm.strategy.exceptions.UnknownCdmTypeException;
46
47
48
49
50
51
52 @Component
53 public class BerlinModelTaxonNameImport extends BerlinModelImportBase {
54 private static final Logger logger = Logger.getLogger(BerlinModelTaxonNameImport.class);
55
56 public static final String NAMESPACE = "TaxonName";
57
58 public static final UUID SOURCE_ACC_UUID = UUID.fromString("c3959b4f-d876-4b7a-a739-9260f4cafd1c");
59
60 private static int modCount = 5000;
61 private static final String pluralString = "TaxonNames";
62 private static final String dbTableName = "Name";
63
64
65 public BerlinModelTaxonNameImport(){
66 super();
67 }
68
69
70
71
72 @Override
73 protected String getRecordQuery(BerlinModelImportConfigurator config) {
74 Source source = config.getSource();
75
76 String facultativCols = "";
77 String strFacTable = "RefDetail";
78 String strFacColumn = "IdInSource";
79 String strColAlias = null;
80 if (checkSqlServerColumnExists(source, strFacTable, strFacColumn)){
81 facultativCols += ", " + strFacTable + "." + strFacColumn ;
82 if (! CdmUtils.Nz(strColAlias).equals("") ){
83 facultativCols += " AS " + strColAlias;
84 }
85 }
86
87 String strRecordQuery =
88 "SELECT Name.* , RefDetail.RefDetailId, RefDetail.RefFk, " +
89 " RefDetail.FullRefCache, RefDetail.FullNomRefCache, RefDetail.PreliminaryFlag AS RefDetailPrelim, RefDetail.Details, " +
90 " RefDetail.SecondarySources, Rank.RankAbbrev, Rank.Rank " +
91 facultativCols +
92 " FROM Name LEFT OUTER JOIN RefDetail ON Name.NomRefDetailFk = RefDetail.RefDetailId AND " +
93 " Name.NomRefFk = RefDetail.RefFk " +
94 " LEFT OUTER JOIN Rank ON Name.RankFk = Rank.rankID " +
95 " WHERE name.nameId IN ("+ID_LIST_TOKEN+") ";
96
97
98 return strRecordQuery;
99 }
100
101
102
103
104
105 public boolean doPartition(ResultSetPartitioner partitioner, BerlinModelImportState state) {
106 String dbAttrName;
107 String cdmAttrName;
108 boolean success = true ;
109 BerlinModelImportConfigurator config = state.getConfig();
110 Set<TaxonNameBase> namesToSave = new HashSet<TaxonNameBase>();
111 Map<String, Team> teamMap = (Map<String, Team>) partitioner.getObjectMap(BerlinModelAuthorTeamImport.NAMESPACE);
112
113 ResultSet rs = partitioner.getResultSet();
114
115 try {
116 int i = 0;
117
118 while (rs.next()){
119
120 if ((i++ % modCount) == 0 && i != 1 ){ logger.info("Names handled: " + (i-1));}
121
122
123 int nameId = rs.getInt("nameId");
124 Object authorFk = rs.getObject("AuthorTeamFk");
125 Object exAuthorFk = rs.getObject("ExAuthorTeamFk");
126 Object basAuthorFk = rs.getObject("BasAuthorTeamFk");
127 Object exBasAuthorFk = rs.getObject("ExBasAuthorTeamFk");
128 String strCultivarGroupName = rs.getString("CultivarGroupName");
129 String strCultivarName = rs.getString("CultivarName");
130
131 try {
132 boolean useUnknownRank = true;
133 Rank rank = BerlinModelTransformer.rankId2Rank(rs, useUnknownRank);
134 if (rank.getId() == 0){
135 getTermService().save(rank);
136 }
137
138 TaxonNameBase taxonNameBase;
139 if (config.getNomenclaturalCode() != null){
140 taxonNameBase = config.getNomenclaturalCode().getNewTaxonNameInstance(rank);
141
142 if (taxonNameBase instanceof BotanicalName){
143 if (CdmUtils.isNotEmpty(strCultivarGroupName) && CdmUtils.isNotEmpty(strCultivarName)){
144 taxonNameBase = CultivarPlantName.NewInstance(rank);
145 }
146 }
147 }else{
148 taxonNameBase = NonViralName.NewInstance(rank);
149 }
150
151 if (rank == null){
152
153 logger.warn("Rank is null. Genus epethiton was imported. May be wrong");
154 success = false;
155 }
156 if (rank != null && rank.isSupraGeneric()){
157 dbAttrName = "supraGenericName";
158 }else{
159 dbAttrName = "genus";
160 }
161 cdmAttrName = "genusOrUninomial";
162 success &= ImportHelper.addStringValue(rs, taxonNameBase, dbAttrName, cdmAttrName);
163
164 dbAttrName = "genusSubdivisionEpi";
165 cdmAttrName = "infraGenericEpithet";
166 success &= ImportHelper.addStringValue(rs, taxonNameBase, dbAttrName, cdmAttrName);
167
168 dbAttrName = "speciesEpi";
169 cdmAttrName = "specificEpithet";
170 success &= ImportHelper.addStringValue(rs, taxonNameBase, dbAttrName, cdmAttrName);
171
172
173 dbAttrName = "infraSpeciesEpi";
174 cdmAttrName = "infraSpecificEpithet";
175 success &= ImportHelper.addStringValue(rs, taxonNameBase, dbAttrName, cdmAttrName);
176
177 dbAttrName = "unnamedNamePhrase";
178 cdmAttrName = "appendedPhrase";
179 success &= ImportHelper.addStringValue(rs, taxonNameBase, dbAttrName, cdmAttrName);
180
181
182 dbAttrName = "details";
183 cdmAttrName = "nomenclaturalMicroReference";
184 success &= ImportHelper.addStringValue(rs, taxonNameBase, dbAttrName, cdmAttrName);
185
186
187 success &= makeNomenclaturalReference(config, taxonNameBase, nameId, rs, partitioner);
188
189
190 String sourceAcc = rs.getString("Source_Acc");
191 if (CdmUtils.isNotEmpty(sourceAcc)){
192 ExtensionType sourceAccExtensionType = getExtensionType(state, SOURCE_ACC_UUID, "Source_Acc","Source_Acc","Source_Acc");
193 Extension datesExtension = Extension.NewInstance(taxonNameBase, sourceAcc, sourceAccExtensionType);
194 }
195
196
197 success &= doIdCreatedUpdatedNotes(state, taxonNameBase, rs, nameId, NAMESPACE);
198
199
200 if (taxonNameBase instanceof NonViralName){
201 NonViralName nonViralName = (NonViralName)taxonNameBase;
202
203
204 if (teamMap != null ){
205 nonViralName.setCombinationAuthorTeam(getAuthorTeam(teamMap, authorFk, nameId, config));
206 nonViralName.setExCombinationAuthorTeam(getAuthorTeam(teamMap, exAuthorFk, nameId, config));
207 nonViralName.setBasionymAuthorTeam(getAuthorTeam(teamMap, basAuthorFk, nameId, config));
208 nonViralName.setExBasionymAuthorTeam(getAuthorTeam(teamMap, exBasAuthorFk, nameId, config));
209 }else{
210 logger.warn("TeamMap is null");
211 success = false;
212 }
213 }
214
215
216
217
218 if (taxonNameBase instanceof ZoologicalName){
219 ZoologicalName zooName = (ZoologicalName)taxonNameBase;
220 makeZoologialName(rs, zooName, nameId);
221 }
222
223 else if (taxonNameBase instanceof BotanicalName){
224 BotanicalName botName = (BotanicalName)taxonNameBase;
225 success &= makeBotanicalNamePart(rs, botName) ;
226
227 }
228
229
230 Boolean preliminaryFlag = rs.getBoolean("PreliminaryFlag");
231 if (preliminaryFlag == true){
232
233 taxonNameBase.setFullTitleCache(taxonNameBase.getFullTitleCache(), true);
234 taxonNameBase.setTitleCache(taxonNameBase.getTitleCache(), true);
235 if (taxonNameBase instanceof NonViralName){
236 NonViralName nvn = (NonViralName)taxonNameBase;
237 nvn.setNameCache(nvn.getNameCache(), true);
238 nvn.setAuthorshipCache(nvn.getAuthorshipCache(), true);
239 }
240 }
241 namesToSave.add(taxonNameBase);
242
243 }
244 catch (UnknownCdmTypeException e) {
245 logger.warn("Name with id " + nameId + " has unknown rankId " + " and could not be saved.");
246 success = false;
247 }
248
249 }
250 } catch (SQLException e) {
251 logger.error("SQLException:" + e);
252 return false;
253 }
254
255
256
257 getNameService().save(namesToSave);
258 return success;
259 }
260
261
262
263
264 public Map<Object, Map<String, ? extends CdmBase>> getRelatedObjectsForPartition(ResultSet rs) {
265 String nameSpace;
266 Class cdmClass;
267 Set<String> idSet;
268
269 Map<Object, Map<String, ? extends CdmBase>> result = new HashMap<Object, Map<String, ? extends CdmBase>>();
270
271 try{
272 Set<String> teamIdSet = new HashSet<String>();
273 Set<String> referenceIdSet = new HashSet<String>();
274 Set<String> refDetailIdSet = new HashSet<String>();
275 while (rs.next()){
276 handleForeignKey(rs, teamIdSet, "AuthorTeamFk");
277 handleForeignKey(rs, teamIdSet, "ExAuthorTeamFk");
278 handleForeignKey(rs, teamIdSet, "BasAuthorTeamFk");
279 handleForeignKey(rs, teamIdSet, "ExBasAuthorTeamFk");
280 handleForeignKey(rs, referenceIdSet, "nomRefFk");
281 handleForeignKey(rs, refDetailIdSet, "nomRefDetailFk");
282 }
283
284
285 nameSpace = BerlinModelAuthorTeamImport.NAMESPACE;
286 cdmClass = Team.class;
287 idSet = teamIdSet;
288 Map<String, Person> teamMap = (Map<String, Person>)getCommonService().getSourcedObjectsByIdInSource(cdmClass, idSet, nameSpace);
289 result.put(nameSpace, teamMap);
290
291
292 nameSpace = BerlinModelReferenceImport.NOM_REFERENCE_NAMESPACE;
293 cdmClass = ReferenceBase.class;
294 idSet = referenceIdSet;
295 Map<String, ReferenceBase> nomReferenceMap = (Map<String, ReferenceBase>)getCommonService().getSourcedObjectsByIdInSource(cdmClass, idSet, nameSpace);
296 result.put(nameSpace, nomReferenceMap);
297
298
299 nameSpace = BerlinModelReferenceImport.BIBLIO_REFERENCE_NAMESPACE;
300 cdmClass = ReferenceBase.class;
301 idSet = referenceIdSet;
302 Map<String, ReferenceBase> biblioReferenceMap = (Map<String, ReferenceBase>)getCommonService().getSourcedObjectsByIdInSource(cdmClass, idSet, nameSpace);
303 result.put(nameSpace, biblioReferenceMap);
304
305
306 nameSpace = BerlinModelRefDetailImport.NOM_REFDETAIL_NAMESPACE;
307 cdmClass = ReferenceBase.class;
308 idSet = refDetailIdSet;
309 Map<String, ReferenceBase> nomRefDetailMap= (Map<String, ReferenceBase>)getCommonService().getSourcedObjectsByIdInSource(cdmClass, idSet, nameSpace);
310 result.put(nameSpace, nomRefDetailMap);
311
312
313 nameSpace = BerlinModelRefDetailImport.BIBLIO_REFDETAIL_NAMESPACE;
314 cdmClass = ReferenceBase.class;
315 idSet = refDetailIdSet;
316 Map<String, ReferenceBase> biblioRefDetailMap= (Map<String, ReferenceBase>)getCommonService().getSourcedObjectsByIdInSource(cdmClass, idSet, nameSpace);
317 result.put(nameSpace, biblioRefDetailMap);
318
319 } catch (SQLException e) {
320 throw new RuntimeException(e);
321 }
322 return result;
323 }
324
325 private boolean makeZoologialName(ResultSet rs, ZoologicalName zooName, int nameId)
326 throws SQLException{
327 boolean success = true;
328
329 String authorTeamYear = rs.getString("authorTeamYear");
330 try {
331 if (! "".equals(CdmUtils.Nz(authorTeamYear).trim())){
332 Integer publicationYear = Integer.valueOf(authorTeamYear.trim());
333 zooName.setPublicationYear(publicationYear);
334 }
335 } catch (NumberFormatException e) {
336 logger.warn("authorTeamYear could not be parsed for taxonName: "+ nameId);
337 }
338
339 String basAuthorTeamYear = rs.getString("basAuthorTeamYear");
340 try {
341 if (! "".equals(CdmUtils.Nz(basAuthorTeamYear).trim())){
342 Integer OriginalPublicationYear = Integer.valueOf(basAuthorTeamYear.trim());
343 zooName.setOriginalPublicationYear(OriginalPublicationYear);
344 }
345 } catch (NumberFormatException e) {
346 logger.warn("basAuthorTeamYear could not be parsed for taxonName: "+ nameId);
347 }
348 return success;
349 }
350
351 private boolean makeBotanicalNamePart(ResultSet rs, BotanicalName botanicalName)throws SQLException{
352 boolean success = true;
353 String dbAttrName;
354 String cdmAttrName;
355
356 dbAttrName = "HybridFormulaFlag";
357 cdmAttrName = "isHybridFormula";
358 success &= ImportHelper.addBooleanValue(rs, botanicalName, dbAttrName, cdmAttrName);
359
360 dbAttrName = "MonomHybFlag";
361 cdmAttrName = "isMonomHybrid";
362 success &= ImportHelper.addBooleanValue(rs, botanicalName, dbAttrName, cdmAttrName);
363
364 dbAttrName = "BinomHybFlag";
365 cdmAttrName = "isBinomHybrid";
366 success &= ImportHelper.addBooleanValue(rs, botanicalName, dbAttrName, cdmAttrName);
367
368 dbAttrName = "TrinomHybFlag";
369 cdmAttrName = "isTrinomHybrid";
370 success &= ImportHelper.addBooleanValue(rs, botanicalName, dbAttrName, cdmAttrName);
371
372 try {
373 String strCultivarGroupName = rs.getString("CultivarGroupName");
374 String strCultivarName = rs.getString("CultivarName");
375 if (botanicalName instanceof CultivarPlantName){
376 CultivarPlantName cultivarName = (CultivarPlantName)botanicalName;
377 String concatCultivarName = CdmUtils.concat("-", strCultivarName, strCultivarGroupName);
378 if (CdmUtils.isNotEmpty(strCultivarGroupName) && CdmUtils.isNotEmpty(strCultivarName)){
379 logger.warn("CDM does not support cultivarGroupName and CultivarName together: " + concatCultivarName);
380 }
381 cultivarName.setCultivarName(strCultivarGroupName);
382 }
383 } catch (SQLException e) {
384 throw e;
385 }
386 return success;
387 }
388
389
390 private boolean makeNomenclaturalReference(IImportConfigurator config, TaxonNameBase taxonNameBase,
391 int nameId, ResultSet rs, ResultSetPartitioner partitioner) throws SQLException{
392 Map<String, ReferenceBase> biblioRefMap = partitioner.getObjectMap(BerlinModelReferenceImport.BIBLIO_REFERENCE_NAMESPACE);
393 Map<String, ReferenceBase> nomRefMap = partitioner.getObjectMap(BerlinModelReferenceImport.NOM_REFERENCE_NAMESPACE);
394 Map<String, ReferenceBase> biblioRefDetailMap = partitioner.getObjectMap(BerlinModelRefDetailImport.BIBLIO_REFDETAIL_NAMESPACE);
395 Map<String, ReferenceBase> nomRefDetailMap = partitioner.getObjectMap(BerlinModelRefDetailImport.NOM_REFDETAIL_NAMESPACE);
396
397 Object nomRefFkObj = rs.getObject("NomRefFk");
398 Object nomRefDetailFkObj = rs.getObject("NomRefDetailFk");
399 boolean refDetailPrelim = rs.getBoolean("RefDetailPrelim");
400
401 boolean success = true;
402
403 if (biblioRefMap != null){
404 if (nomRefFkObj != null){
405 String nomRefFk = String.valueOf(nomRefFkObj);
406 String nomRefDetailFk = String.valueOf(nomRefDetailFkObj);
407
408 ReferenceBase nomReference =
409 getReferenceFromMaps(nomRefDetailMap, biblioRefDetailMap,
410 nomRefMap, biblioRefMap, nomRefDetailFk, nomRefFk);
411
412
413
414 if (nomReference == null ){
415
416 if (! config.isIgnoreNull()){
417 logger.warn("Nomenclatural reference (nomRefFk = " + nomRefFk + ") for TaxonName (nameId = " + nameId + ")"+
418 " was not found in reference store. Nomenclatural reference was not set!!");
419 }
420 }else{
421 if (! INomenclaturalReference.class.isAssignableFrom(nomReference.getClass())){
422 logger.warn("Nomenclatural reference (nomRefFk = " + nomRefFk + ") for TaxonName (nameId = " + nameId + ")"+
423 " is not assignable from INomenclaturalReference. (Class = " + nomReference.getClass()+ ")");
424 }
425 nomReference.setNomenclaturallyRelevant(true);
426 taxonNameBase.setNomenclaturalReference(nomReference);
427 }
428 }
429 }
430 return success;
431 }
432
433 private static TeamOrPersonBase getAuthorTeam(Map<String, Team> teamMap, Object teamIdObject, int nameId, BerlinModelImportConfigurator bmiConfig){
434 if (teamIdObject == null){
435 return null;
436 }else {
437 String teamId = String.valueOf(teamIdObject);
438 TeamOrPersonBase author = teamMap.get(teamId);
439 if (author == null){
440
441 if (!bmiConfig.isIgnoreNull() && ! (teamId.equals(0) && bmiConfig.isIgnore0AuthorTeam()) ){
442 logger.warn("AuthorTeam (teamId = " + teamId + ") for TaxonName (nameId = " + nameId + ")"+
443 " was not found in authorTeam store. Relation was not set!!");}
444 return null;
445 }else{
446 return author;
447 }
448 }
449 }
450
451
452
453
454 @Override
455 protected boolean doCheck(BerlinModelImportState state){
456 IOValidator<BerlinModelImportState> validator = new BerlinModelTaxonNameImportValidator();
457 return validator.validate(state);
458 }
459
460
461
462
463 @Override
464 protected String getTableName() {
465 return dbTableName;
466 }
467
468
469
470
471 @Override
472 public String getPluralString() {
473 return pluralString;
474 }
475
476
477
478
479 protected boolean isIgnore(BerlinModelImportState state){
480 return ! state.getConfig().isDoTaxonNames();
481 }
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524 }