Project

General

Profile

Download (29.9 KB) Statistics
| Branch: | Revision:
1
/**
2
* Copyright (C) 2007 EDIT
3
* European Distributed Institute of Taxonomy
4
* http://www.e-taxonomy.eu
5
*
6
* The contents of this file are subject to the Mozilla Public License Version 1.1
7
* See LICENSE.TXT at the top of this package for the full license terms.
8
*/
9

    
10
package eu.etaxonomy.cdm.io.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.database.update.DatabaseTypeNotSupportedException;
25
import eu.etaxonomy.cdm.io.berlinModel.BerlinModelTransformer;
26
import eu.etaxonomy.cdm.io.berlinModel.in.validation.BerlinModelTaxonNameImportValidator;
27
import eu.etaxonomy.cdm.io.common.IImportConfigurator;
28
import eu.etaxonomy.cdm.io.common.IOValidator;
29
import eu.etaxonomy.cdm.io.common.ImportHelper;
30
import eu.etaxonomy.cdm.io.common.ResultSetPartitioner;
31
import eu.etaxonomy.cdm.io.common.Source;
32
import eu.etaxonomy.cdm.model.agent.Team;
33
import eu.etaxonomy.cdm.model.agent.TeamOrPersonBase;
34
import eu.etaxonomy.cdm.model.common.Annotation;
35
import eu.etaxonomy.cdm.model.common.CdmBase;
36
import eu.etaxonomy.cdm.model.common.Extension;
37
import eu.etaxonomy.cdm.model.common.ExtensionType;
38
import eu.etaxonomy.cdm.model.common.Language;
39
import eu.etaxonomy.cdm.model.common.Representation;
40
import eu.etaxonomy.cdm.model.name.IBotanicalName;
41
import eu.etaxonomy.cdm.model.name.ICultivarPlantName;
42
import eu.etaxonomy.cdm.model.name.INonViralName;
43
import eu.etaxonomy.cdm.model.name.IZoologicalName;
44
import eu.etaxonomy.cdm.model.name.Rank;
45
import eu.etaxonomy.cdm.model.name.TaxonName;
46
import eu.etaxonomy.cdm.model.name.TaxonNameFactory;
47
import eu.etaxonomy.cdm.model.reference.INomenclaturalReference;
48
import eu.etaxonomy.cdm.model.reference.Reference;
49
import eu.etaxonomy.cdm.model.reference.ReferenceFactory;
50
import eu.etaxonomy.cdm.strategy.exceptions.UnknownCdmTypeException;
51
import eu.etaxonomy.cdm.strategy.parser.INonViralNameParser;
52
import eu.etaxonomy.cdm.strategy.parser.NonViralNameParserImpl;
53

    
54
/**
55
 * @author a.mueller
56
 * @since 20.03.2008
57
 */
58
@Component
59
public class BerlinModelTaxonNameImport extends BerlinModelImportBase {
60
    private static final long serialVersionUID = -8860800694286602016L;
61

    
62
    private static final boolean BLANK_TO_NULL = true;
63

    
64
	private static final Logger logger = Logger.getLogger(BerlinModelTaxonNameImport.class);
65

    
66
	public static final String NAMESPACE = "TaxonName";
67

    
68
	public static final UUID SOURCE_ACC_UUID = UUID.fromString("c3959b4f-d876-4b7a-a739-9260f4cafd1c");
69

    
70
	private static int modCount = 5000;
71
	private static final String pluralString = "TaxonNames";
72
	private static final String dbTableName = "Name";
73

    
74

    
75
	public BerlinModelTaxonNameImport(){
76
		super(dbTableName, pluralString);
77
	}
78

    
79

    
80
	@Override
81
	protected String getIdQuery(BerlinModelImportState state) {
82
		if (state.getConfig().getNameIdTable()==null ){
83
			return super.getIdQuery(state);
84
		}else{
85
			return "SELECT nameId FROM " + state.getConfig().getNameIdTable() + "";
86
		}
87
	}
88

    
89
	@Override
90
	protected String getRecordQuery(BerlinModelImportConfigurator config) {
91
		Source source = config.getSource();
92

    
93
			String facultativCols = "";
94
			String strFacTable = "RefDetail";
95
			String strFacColumn = "IdInSource";
96
			String strColAlias = null;
97
			if (checkSqlServerColumnExists(source, strFacTable, strFacColumn)){
98
				facultativCols +=  ", " + strFacTable + "." + strFacColumn ;
99
				if (! CdmUtils.Nz(strColAlias).equals("") ){
100
					facultativCols += " AS " + strColAlias;
101
				}
102
			}
103

    
104
		String strRecordQuery =
105
					"SELECT Name.* , RefDetail.RefDetailId, RefDetail.RefFk, " +
106
                      		" RefDetail.FullRefCache, RefDetail.FullNomRefCache, RefDetail.PreliminaryFlag AS RefDetailPrelim, RefDetail.Details, " +
107
                      		" RefDetail.SecondarySources, Rank.RankAbbrev, Rank.Rank " +
108
                      		facultativCols +
109
                    " FROM Name LEFT OUTER JOIN RefDetail ON Name.NomRefDetailFk = RefDetail.RefDetailId AND  " +
110
                    	" Name.NomRefFk = RefDetail.RefFk " +
111
                    	" LEFT OUTER JOIN Rank ON Name.RankFk = Rank.rankID " +
112
                " WHERE name.nameId IN ("+ID_LIST_TOKEN+") ";
113
					//strQuery += " AND RefDetail.PreliminaryFlag = 1 ";
114
					//strQuery += " AND Name.Created_When > '03.03.2004' ";
115
		return strRecordQuery +  "";
116
	}
117

    
118

    
119

    
120
	@Override
121
	protected void doInvoke(BerlinModelImportState state) {
122
		//update rank labels if necessary
123
		String strAbbrev = state.getConfig().getInfrGenericRankAbbrev();
124
		Rank rank = Rank.INFRAGENERICTAXON();
125
		testRankAbbrev(strAbbrev, rank);
126

    
127
		strAbbrev = state.getConfig().getInfrSpecificRankAbbrev();
128
		rank = Rank.INFRASPECIFICTAXON();
129
		testRankAbbrev(strAbbrev, rank);
130

    
131
		super.doInvoke(state);
132
	}
133

    
134
	private void testRankAbbrev(String strAbbrev, Rank rank) {
135
		if (strAbbrev != null){
136
			Representation rep = rank.getRepresentation(Language.ENGLISH());
137
			rep.setAbbreviatedLabel(strAbbrev);
138
			getTermService().saveOrUpdate(rank);
139
		}
140
	}
141

    
142
	@Override
143
	public boolean doPartition(@SuppressWarnings("rawtypes") ResultSetPartitioner partitioner, BerlinModelImportState state) {
144
		String dbAttrName;
145
		String cdmAttrName;
146
		boolean success = true ;
147
		BerlinModelImportConfigurator config = state.getConfig();
148
		Set<TaxonName> namesToSave = new HashSet<>();
149
		@SuppressWarnings("unchecked")
150
        Map<String, Team> teamMap = partitioner.getObjectMap(BerlinModelAuthorTeamImport.NAMESPACE);
151

    
152
		ResultSet rs = partitioner.getResultSet();
153

    
154
		try {
155
			int i = 0;
156
			//for each reference
157
			while (rs.next()){
158

    
159
				if ((i++ % modCount) == 0 && i != 1 ){ logger.info("Names handled: " + (i-1));}
160

    
161
				//create TaxonName element
162
				int nameId = rs.getInt("nameId");
163
				Integer authorFk = nullSafeInt(rs, "AuthorTeamFk");
164
				Integer exAuthorFk = nullSafeInt(rs, "ExAuthorTeamFk");
165
				Integer basAuthorFk = nullSafeInt(rs, "BasAuthorTeamFk");
166
				Integer exBasAuthorFk = nullSafeInt(rs, "ExBasAuthorTeamFk");
167
				String strCultivarGroupName = rs.getString("CultivarGroupName");
168
				String strCultivarName = rs.getString("CultivarName");
169
				String nameCache = rs.getString("NameCache");
170
				String fullNameCache = rs.getString("FullNameCache");
171
				String uuid = null;
172
				if (resultSetHasColumn(rs,"UUID")){
173
					uuid = rs.getString("UUID");
174
				}
175

    
176
				try {
177

    
178
					//define rank
179
					boolean useUnknownRank = true;
180
					Rank rank = BerlinModelTransformer.rankId2Rank(rs, useUnknownRank, config.isSwitchSpeciesGroup());
181

    
182
					boolean allowInfraSpecTaxonRank = state.getConfig().isAllowInfraSpecTaxonRank() ;
183
					if (rank == null || rank.equals(Rank.UNKNOWN_RANK()) || (rank.equals(Rank.INFRASPECIFICTAXON()) && ! allowInfraSpecTaxonRank)){
184
						rank = handleProlesAndRaceSublusus(state, rs, rank);
185
					}
186

    
187
					if (rank.getId() == 0){
188
						getTermService().save(rank);
189
						logger.warn("Rank did not yet exist: " +  rank.getTitleCache());
190
					}
191

    
192
					//create TaxonName
193
					TaxonName taxonName;
194
					if (config.getNomenclaturalCode() != null){
195
						taxonName = config.getNomenclaturalCode().getNewTaxonNameInstance(rank);
196
						//check cultivar
197
						if (taxonName.isBotanical()){
198
							if (isNotBlank(strCultivarGroupName) && isNotBlank(strCultivarName)){
199
								taxonName = TaxonNameFactory.NewCultivarInstance(rank);
200
							}
201
						}
202
					}else{
203
						taxonName = TaxonNameFactory.NewNonViralInstance(rank);
204
					}
205
					if (uuid != null){
206
						taxonName.setUuid(UUID.fromString(uuid));
207
					}
208

    
209
					if (rank == null){
210
						//TODO rank should never be null or a more sophisticated algorithm has to be implemented for genus/supraGenericName
211
						logger.warn("Rank is null. Genus epithet was imported. May be wrong");
212
						success = false;
213
					}
214

    
215
					//epithets
216
					if (rank.isSupraGeneric()){
217
						dbAttrName = "supraGenericName";
218
					}else{
219
						dbAttrName = "genus";
220
					}
221
					cdmAttrName = "genusOrUninomial";
222
					success &= ImportHelper.addStringValue(rs, taxonName, dbAttrName, cdmAttrName, BLANK_TO_NULL);
223

    
224
					dbAttrName = "genusSubdivisionEpi";
225
					cdmAttrName = "infraGenericEpithet";
226
					success &= ImportHelper.addStringValue(rs, taxonName, dbAttrName, cdmAttrName, BLANK_TO_NULL);
227

    
228
					dbAttrName = "speciesEpi";
229
					cdmAttrName = "specificEpithet";
230
					success &= ImportHelper.addStringValue(rs, taxonName, dbAttrName, cdmAttrName, BLANK_TO_NULL);
231

    
232

    
233
					dbAttrName = "infraSpeciesEpi";
234
					cdmAttrName = "infraSpecificEpithet";
235
					success &= ImportHelper.addStringValue(rs, taxonName, dbAttrName, cdmAttrName, BLANK_TO_NULL);
236

    
237
					dbAttrName = "unnamedNamePhrase";
238
					cdmAttrName = "appendedPhrase";
239
					success &= ImportHelper.addStringValue(rs, taxonName, dbAttrName, cdmAttrName, BLANK_TO_NULL);
240

    
241
					//Details
242
					dbAttrName = "details";
243
					cdmAttrName = "nomenclaturalMicroReference";
244
					success &= ImportHelper.addStringValue(rs, taxonName, dbAttrName, cdmAttrName, BLANK_TO_NULL);
245

    
246
					//nomRef
247
					success &= makeNomenclaturalReference(config, taxonName, nameId, rs, partitioner);
248

    
249
					//Source_Acc
250
					boolean colExists = true;
251
					try {
252
						colExists = state.getConfig().getSource().checkColumnExists("Name", "Source_Acc");
253
					} catch (DatabaseTypeNotSupportedException e) {
254
						logger.debug("Source does not support 'checkColumnExists'");
255
					}
256
					if (colExists){
257
						String sourceAcc = rs.getString("Source_Acc");
258
						if (isNotBlank(sourceAcc)){
259
							ExtensionType sourceAccExtensionType = getExtensionType(state, SOURCE_ACC_UUID, "Source_Acc","Source_Acc","Source_Acc");
260
							Extension.NewInstance(taxonName, sourceAcc, sourceAccExtensionType);
261
						}
262
					}
263

    
264
					//created, notes
265
					boolean excludeUpdated = true;
266
					boolean excludeNotes = true;
267
					success &= doIdCreatedUpdatedNotes(state, taxonName, rs, nameId, NAMESPACE, excludeUpdated, excludeNotes);
268
					handleNameNotes(state, taxonName, rs, nameId);
269

    
270
					//NonViralName
271
					if (taxonName.isNonViral()){
272
						INonViralName nonViralName = taxonName;
273

    
274
						//authorTeams
275
						if (teamMap != null ){
276
							nonViralName.setCombinationAuthorship(getAuthorTeam(teamMap, authorFk, nameId, config));
277
							nonViralName.setExCombinationAuthorship(getAuthorTeam(teamMap, exAuthorFk, nameId, config));
278
							nonViralName.setBasionymAuthorship(getAuthorTeam(teamMap, basAuthorFk, nameId, config));
279
							nonViralName.setExBasionymAuthorship(getAuthorTeam(teamMap, exBasAuthorFk, nameId, config));
280
						}else{
281
							logger.warn("TeamMap is null");
282
							success = false;
283
						}
284
					}//nonviralName
285

    
286

    
287

    
288
					//zoologicalName
289
					if (taxonName.isZoological()){
290
						IZoologicalName zooName = taxonName;
291
						makeZoologialName(rs, zooName, nameId);
292
					}
293
					//botanicalName
294
					else if (taxonName.isBotanical()){
295
						IBotanicalName botName = taxonName;
296
						success &= makeBotanicalNamePart(rs, botName) ;
297

    
298
					}
299

    
300
	//				dbAttrName = "preliminaryFlag";
301
					Boolean preliminaryFlag = rs.getBoolean("PreliminaryFlag");
302
					Boolean hybridFormulaFlag = rs.getBoolean("HybridFormulaFlag");  //hybrid flag does not lead to cache update in Berlin Model
303
					if (preliminaryFlag == true || hybridFormulaFlag == true){
304
						//Computes all caches and sets
305
						taxonName.setTitleCache(fullNameCache, true);
306
						taxonName.setFullTitleCache(taxonName.getFullTitleCache(), true);
307
						taxonName.setNameCache(nameCache, true);
308
						taxonName.setAuthorshipCache(taxonName.getAuthorshipCache(), true);
309
					}
310
					namesToSave.add(taxonName);
311

    
312
				}
313
				catch (UnknownCdmTypeException e) {
314
					logger.warn("Name with id " + nameId + " has unknown rankId " + " and could not be saved.");
315
					success = false;
316
				}
317

    
318
			} //while rs.hasNext()
319
		} catch (SQLException e) {
320
			logger.error("SQLException:" +  e);
321
			return false;
322
		}
323

    
324

    
325
//		logger.info( i + " names handled");
326
		getNameService().save(namesToSave);
327
		return success;
328
	}
329

    
330

    
331
	/**
332
     * @param state
333
     * @param taxonName
334
     * @param rs
335
     * @param nameId
336
	 * @throws SQLException
337
     */
338
    private void handleNameNotes(BerlinModelImportState state, TaxonName taxonName, ResultSet rs, int nameId) throws SQLException {
339
        String notesOrig = rs.getString("notes");
340
        String notes = filterNotes(notesOrig, nameId);
341
        boolean isParentalSpecies = state.getConfig().isEuroMed() && isPostulatedParentalSpeciesNote(notes);
342
        if (isNotBlank(notes) && taxonName != null && !isParentalSpecies ){
343
            String notesString = String.valueOf(notes);
344
            if (notesString.length() > 65530 ){
345
                notesString = notesString.substring(0, 65530) + "...";
346
                logger.warn("Notes string is longer than 65530 and was truncated: " + taxonName);
347
            }
348
            Annotation notesAnnotation = Annotation.NewInstance(notesString, Language.DEFAULT());
349
            //notesAnnotation.setAnnotationType(AnnotationType.EDITORIAL());
350
            //notes.setCommentator(bmiConfig.getCommentator());
351
            taxonName.addAnnotation(notesAnnotation);
352
        }
353

    
354
    }
355

    
356
    private static final String MCL = "MCL\\s?[0-9]{1,3}(\\-[0-9]{1,4}(\\-[0-9]{1,4}(\\-[0-9]{1,4}(\\-[0-9]{1,3})?)?)?)?";
357
    /**
358
     * @param notes
359
     */
360
    protected static String filterNotes(String notes, int nameId) {
361
        String result;
362
        if (isBlank(notes)){
363
            result = null;
364
        }else if (notes.matches("Acc:.*")){
365
            if (notes.matches("Acc: .*\\$$") || (notes.matches("Acc: .*"+MCL))){
366
                result = null;
367
            }else if (notes.matches("Acc: .*(\\$|"+MCL+")\\s*\\{.*\\}")){
368
                notes = notes.substring(notes.indexOf("{")+1, notes.length()-1);
369
                result = notes;
370
            }else if (notes.matches("Acc: .*(\\$|"+MCL+")\\s*\\[.*\\]")){
371
                notes = notes.substring(notes.indexOf("[")+1, notes.length()-1);
372
                result = notes;
373
            }else{
374
                logger.warn("Name id: " + nameId + ". Namenote: " + notes);
375
                result = notes;
376
            }
377
        }else if (notes.matches("Syn:.*")){
378
            if (notes.matches("Syn: .*\\$$") || (notes.matches("Syn: .*"+MCL))){
379
                result = null;
380
            }else if (notes.matches("Syn: .*(\\$|"+MCL+")\\s*\\{.*\\}")){
381
                notes = notes.substring(notes.indexOf("{")+1, notes.length()-1);
382
                result = notes;
383
            }else if (notes.matches("Syn: .*(\\$|"+MCL+")\\s*\\[.*\\]")){
384
                notes = notes.substring(notes.indexOf("[")+1, notes.length()-1);
385
                result = notes;
386
            }else{
387
                logger.warn("Name id: " + nameId + ". Namenote: " + notes);
388
                result = notes;
389
            }
390
        }else{
391
            result = notes;
392
        }
393
        return result;
394
    }
395

    
396

    
397
    /**
398
     * @param nameNotes
399
     * @return
400
     */
401
    protected static boolean isPostulatedParentalSpeciesNote(String nameNotes) {
402
        if (nameNotes == null){
403
            return false;
404
        }else{
405
            return nameNotes.matches(".*<>.*");
406
        }
407
    }
408

    
409

    
410
    private Rank handleProlesAndRaceSublusus(BerlinModelImportState state, ResultSet rs, Rank rank) throws SQLException {
411
		Rank result;
412
		String rankAbbrev = rs.getString("RankAbbrev");
413
//		String rankStr = rs.getString("Rank");
414
		if (CdmUtils.nullSafeEqual(rankAbbrev, "prol.") ){
415
			result = Rank.PROLES();
416
		}else if(CdmUtils.nullSafeEqual(rankAbbrev, "race")){
417
			result = Rank.RACE();
418
		}else if(CdmUtils.nullSafeEqual(rankAbbrev, "sublusus")){
419
			result = Rank.SUBLUSUS();
420
		}else{
421
			result = rank;
422
			logger.warn("Unhandled rank: " + rankAbbrev);
423
		}
424
		return result;
425
	}
426

    
427
	@Override
428
	public Map<Object, Map<String, ? extends CdmBase>> getRelatedObjectsForPartition(ResultSet rs, BerlinModelImportState state) {
429
		String nameSpace;
430
		Class<?> cdmClass;
431
		Set<String> idSet;
432

    
433
		Map<Object, Map<String, ? extends CdmBase>> result = new HashMap<>();
434

    
435
		try{
436
			Set<String> teamIdSet = new HashSet<>();
437
			Set<String> referenceIdSet = new HashSet<>();
438
			Set<String> refDetailIdSet = new HashSet<>();
439
			while (rs.next()){
440
				handleForeignKey(rs, teamIdSet, "AuthorTeamFk");
441
				handleForeignKey(rs, teamIdSet, "ExAuthorTeamFk");
442
				handleForeignKey(rs, teamIdSet, "BasAuthorTeamFk");
443
				handleForeignKey(rs, teamIdSet, "ExBasAuthorTeamFk");
444
				handleForeignKey(rs, referenceIdSet, "nomRefFk");
445
				handleForeignKey(rs, refDetailIdSet, "nomRefDetailFk");
446
			}
447

    
448
			//team map
449
			nameSpace = BerlinModelAuthorTeamImport.NAMESPACE;
450
			cdmClass = TeamOrPersonBase.class;
451
			idSet = teamIdSet;
452
			@SuppressWarnings("unchecked")
453
            Map<String, TeamOrPersonBase<?>> teamMap = (Map<String, TeamOrPersonBase<?>>)getCommonService().getSourcedObjectsByIdInSource(cdmClass, idSet, nameSpace);
454
			result.put(nameSpace, teamMap);
455

    
456
			//reference map
457
			nameSpace = BerlinModelReferenceImport.REFERENCE_NAMESPACE;
458
			cdmClass = Reference.class;
459
			idSet = referenceIdSet;
460
			@SuppressWarnings("unchecked")
461
            Map<String, Reference> referenceMap = (Map<String, Reference>)getCommonService().getSourcedObjectsByIdInSource(cdmClass, idSet, nameSpace);
462
			result.put(nameSpace, referenceMap);
463

    
464
			//refDetail map
465
			nameSpace = BerlinModelRefDetailImport.REFDETAIL_NAMESPACE;
466
			cdmClass = Reference.class;
467
			idSet = refDetailIdSet;
468
			@SuppressWarnings("unchecked")
469
            Map<String, Reference> refDetailMap= (Map<String, Reference>)getCommonService().getSourcedObjectsByIdInSource(cdmClass, idSet, nameSpace);
470
			result.put(nameSpace, refDetailMap);
471

    
472
		} catch (SQLException e) {
473
			throw new RuntimeException(e);
474
		}
475
		return result;
476
	}
477

    
478
	private boolean makeZoologialName(ResultSet rs, IZoologicalName zooName, int nameId)
479
					throws SQLException{
480
		boolean success = true;
481
		//publicationYear
482
		String authorTeamYear = rs.getString("authorTeamYear");
483
		try {
484
			if (! "".equals(CdmUtils.Nz(authorTeamYear).trim())){
485
				Integer publicationYear  = Integer.valueOf(authorTeamYear.trim());
486
				zooName.setPublicationYear(publicationYear);
487
			}
488
		} catch (NumberFormatException e) {
489
			logger.warn("authorTeamYear could not be parsed for taxonName: "+ nameId);
490
		}
491
		//original publication year
492
		String basAuthorTeamYear = rs.getString("basAuthorTeamYear");
493
		try {
494
			if (! "".equals(CdmUtils.Nz(basAuthorTeamYear).trim())){
495
				Integer OriginalPublicationYear  = Integer.valueOf(basAuthorTeamYear.trim());
496
				zooName.setOriginalPublicationYear(OriginalPublicationYear);
497
			}
498
		} catch (NumberFormatException e) {
499
			logger.warn("basAuthorTeamYear could not be parsed for taxonName: "+ nameId);
500
		}
501
		return success;
502
	}
503

    
504
	private boolean makeBotanicalNamePart(ResultSet rs, IBotanicalName botanicalName)throws SQLException{
505
		boolean success = true;
506
		String dbAttrName;
507
		String cdmAttrName;
508

    
509
		dbAttrName = "HybridFormulaFlag";
510
		cdmAttrName = "isHybridFormula";
511
		success &= ImportHelper.addBooleanValue(rs, botanicalName, dbAttrName, cdmAttrName);
512

    
513
		dbAttrName = "MonomHybFlag";
514
		cdmAttrName = "isMonomHybrid";
515
		success &= ImportHelper.addBooleanValue(rs, botanicalName, dbAttrName, cdmAttrName);
516

    
517
		dbAttrName = "BinomHybFlag";
518
		cdmAttrName = "isBinomHybrid";
519
		success &= ImportHelper.addBooleanValue(rs, botanicalName, dbAttrName, cdmAttrName);
520

    
521
		dbAttrName = "TrinomHybFlag";
522
		cdmAttrName = "isTrinomHybrid";
523
		success &= ImportHelper.addBooleanValue(rs, botanicalName, dbAttrName, cdmAttrName);
524

    
525
		try {
526
			String strCultivarGroupName = rs.getString("CultivarGroupName");
527
			String strCultivarName = rs.getString("CultivarName");
528
			if (botanicalName.isCultivar()){
529
				ICultivarPlantName cultivarName = (ICultivarPlantName)botanicalName;
530
				String concatCultivarName = CdmUtils.concat("-", strCultivarName, strCultivarGroupName);
531
				if (isNotBlank(strCultivarGroupName) && isNotBlank(strCultivarName)){
532
					logger.warn("CDM does not support cultivarGroupName and CultivarName together: " + concatCultivarName);
533
				}
534
				cultivarName.setCultivarName(strCultivarGroupName);
535
			}
536
		} catch (SQLException e) {
537
			throw e;
538
		}
539
		return success;
540
	}
541

    
542

    
543
	private boolean makeNomenclaturalReference(BerlinModelImportConfigurator config, TaxonName taxonName,
544
					int nameId, ResultSet rs, @SuppressWarnings("rawtypes") ResultSetPartitioner partitioner) throws SQLException{
545

    
546
	    @SuppressWarnings("unchecked")
547
        Map<String, Reference> refMap = partitioner.getObjectMap(BerlinModelReferenceImport.REFERENCE_NAMESPACE);
548
		@SuppressWarnings("unchecked")
549
        Map<String, Reference> refDetailMap = partitioner.getObjectMap(BerlinModelRefDetailImport.REFDETAIL_NAMESPACE);
550

    
551
		Integer nomRefFkInt = nullSafeInt(rs, "NomRefFk");
552
		Integer nomRefDetailFkInt = nullSafeInt(rs, "NomRefDetailFk");
553
		boolean refDetailPrelim = rs.getBoolean("RefDetailPrelim");
554

    
555
		boolean success = true;
556
		//nomenclatural Reference
557
		if (refMap != null){
558
			if (nomRefFkInt != null){
559
				String nomRefFk = String.valueOf(nomRefFkInt);
560
				String nomRefDetailFk = String.valueOf(nomRefDetailFkInt);
561
				//get nomRef
562
				Reference nomReference =
563
					getReferenceFromMaps(refDetailMap, refMap, nomRefDetailFk, nomRefFk);
564

    
565
				if(config.isDoPreliminaryRefDetailsWithNames() && refDetailPrelim){
566
				    makePrelimRefDetailRef(config, rs, taxonName, nameId);
567
				}
568

    
569
				//setNomRef
570
				if (nomReference == null ){
571
					//TODO
572
					if (! config.isIgnoreNull()){
573
						logger.warn("Nomenclatural reference (nomRefFk = " + nomRefFk + ") for TaxonName (nameId = " + nameId + ")"+
574
							" was not found in reference store. Nomenclatural reference not set!!");
575
					}
576
				}else{
577
					if (! INomenclaturalReference.class.isAssignableFrom(nomReference.getClass())){
578
						logger.warn("Nomenclatural reference (nomRefFk = " + nomRefFk + ") for TaxonName (nameId = " + nameId + ")"+
579
								" is not assignable from INomenclaturalReference. (Class = " + nomReference.getClass()+ ")");
580
					}
581
					nomReference.setNomenclaturallyRelevant(true);
582
					taxonName.setNomenclaturalReference(nomReference);
583
				}
584
			}
585
		}
586
		return success;
587
	}
588

    
589

    
590
	private INonViralNameParser<?> parser = NonViralNameParserImpl.NewInstance();
591

    
592
	/**
593
     * @param config
594
     * @param rs
595
     * @param taxonName
596
     * @param nameId
597
	 * @throws SQLException
598
     */
599
    private void makePrelimRefDetailRef(IImportConfigurator config, ResultSet rs, TaxonName taxonName, int nameId) throws SQLException {
600
        String fullNomRefCache = rs.getString("FullNomRefCache");
601
        if (fullNomRefCache == null){
602
            logger.warn("fullNomRefCache is null for preliminary refDetail. NameId: " + nameId);
603
            return;
604
        }else if (fullNomRefCache.trim().startsWith(": ")){
605
            logger.warn("fullNomRefCache starts with for preliminary refDetail. NameId: " + nameId);
606
            return;
607
        }else if (fullNomRefCache.trim().startsWith("in ")){
608
            String fullStr = taxonName.getTitleCache()+ " " + fullNomRefCache;
609
            INonViralName newName = parser.parseReferencedName(fullStr, config.getNomenclaturalCode(), taxonName.getRank());
610
            if (newName.isProtectedFullTitleCache()){
611
                Reference nomRef = ReferenceFactory.newGeneric();
612
                nomRef.setAbbrevTitleCache(fullNomRefCache, true);
613
                taxonName.setNomenclaturalReference(nomRef);
614
                //check detail
615
            }else{
616
                Reference nomRef = newName.getNomenclaturalReference();
617
                taxonName.setNomenclaturalReference(nomRef);
618
                String detail = newName.getNomenclaturalMicroReference();
619
                String oldDetail = taxonName.getNomenclaturalMicroReference();
620
                if (isBlank(detail)){
621
                    if (isNotBlank(oldDetail)){
622
                        logger.warn("Detail could not be parsed but seems to exist. NameId: " + nameId);
623
                    }
624
                }else{
625
                    if (isNotBlank(oldDetail) && !detail.equals(oldDetail)){
626
                        logger.warn("Details differ: " +  detail + " <-> " + oldDetail + ". NameId: " + nameId);
627
                    }
628
                    taxonName.setNomenclaturalMicroReference(detail);
629
                }
630
            }
631
        }else{
632
            String fullStrComma = taxonName.getTitleCache()+ ", " + fullNomRefCache;
633
            String fullStrIn = taxonName.getTitleCache()+ " in " + fullNomRefCache;
634
            INonViralName newNameComma = parser.parseReferencedName(fullStrComma, config.getNomenclaturalCode(), taxonName.getRank());
635
            INonViralName newNameIn = parser.parseReferencedName(fullStrIn, config.getNomenclaturalCode(), taxonName.getRank());
636

    
637
            INonViralName newName;
638
            boolean commaProtected = newNameComma.isProtectedFullTitleCache() || (newNameComma.getNomenclaturalReference() != null
639
                    && newNameComma.getNomenclaturalReference().isProtectedTitleCache());
640
            boolean inProtected = newNameIn.isProtectedFullTitleCache() || (newNameIn.getNomenclaturalReference() != null
641
                    && newNameIn.getNomenclaturalReference().isProtectedTitleCache());
642
            if (commaProtected && !inProtected){
643
                newName = newNameIn;
644
            }else if (!commaProtected && inProtected){
645
                newName = newNameComma;
646
            }else if (commaProtected && inProtected){
647
                logger.warn("Can't parse preliminary refDetail: " +  fullNomRefCache + " for name " + taxonName.getTitleCache() + "; nameId: " + nameId );
648
                newName = newNameComma;
649
            }else{
650
                logger.warn("Can't decide ref type for preliminary refDetail: " +  fullNomRefCache + " for name " + taxonName.getTitleCache() + "; nameId: " + nameId );
651
                newName = newNameComma;
652
            }
653

    
654

    
655
            if (newName.isProtectedFullTitleCache()){
656
                Reference nomRef = ReferenceFactory.newGeneric();
657
                nomRef.setAbbrevTitleCache(fullNomRefCache, true);
658
                taxonName.setNomenclaturalReference(nomRef);
659
                //check detail
660
            }else{
661
                Reference nomRef = newName.getNomenclaturalReference();
662
                taxonName.setNomenclaturalReference(nomRef);
663
                String detail = newName.getNomenclaturalMicroReference();
664
                String oldDetail = taxonName.getNomenclaturalMicroReference();
665
                if (isBlank(detail)){
666
                    if (isNotBlank(oldDetail)){
667
                        logger.warn("Detail could not be parsed but seems to exist. NameId: " + nameId);
668
                    }
669
                }else{
670
                    if (isNotBlank(oldDetail) && !detail.equals(oldDetail)){
671
                        logger.warn("Details differ: " +  detail + " <-> " + oldDetail + ". NameId: " + nameId);
672
                    }
673
                    taxonName.setNomenclaturalMicroReference(detail);
674
                }
675
            }
676
        }
677
    }
678

    
679

    
680
    private static TeamOrPersonBase<?> getAuthorTeam(Map<String, Team> teamMap, Integer teamIdInt, int nameId, BerlinModelImportConfigurator config){
681
		if (teamIdInt == null){
682
			return null;
683
		}else {
684
			String teamIdStr = String.valueOf(teamIdInt);
685
			TeamOrPersonBase<?> author = teamMap.get(teamIdStr);
686
			if (author == null){
687
				//TODO
688
				if (!config.isIgnoreNull() && ! (teamIdStr.equals(0) && config.isIgnore0AuthorTeam()) ){
689
					logger.warn("AuthorTeam (teamId = " + teamIdStr + ") for TaxonName (nameId = " + nameId + ")"+
690
				        " was not found in authorTeam store. Relation was not set!");
691
				}
692
				return null;
693
			}else{
694
				return author;
695
			}
696
		}
697
	}
698

    
699
	@Override
700
	protected boolean doCheck(BerlinModelImportState state){
701
		IOValidator<BerlinModelImportState> validator = new BerlinModelTaxonNameImportValidator();
702
		return validator.validate(state);
703
	}
704

    
705
	@Override
706
    protected boolean isIgnore(BerlinModelImportState state){
707
		return ! state.getConfig().isDoTaxonNames();
708
	}
709

    
710

    
711

    
712

    
713

    
714

    
715
//FOR FUTURE USE , DONT DELETE
716
//	new CdmStringMapper("nameId", "nameId"),
717
//	new CdmStringMapper("rankFk", "rankFk"),
718
//	new CdmStringMapper("nameCache", "nameCache"),
719
//	new CdmStringMapper("unnamedNamePhrase", "unnamedNamePhrase"),
720
//	new CdmStringMapper("fullNameCache", "fullNameCache"),
721
//	new CdmStringMapper("preliminaryFlag", "preliminaryFlag"),
722
//	new CdmStringMapper("supragenericName", "supragenericName"),
723
//	new CdmStringMapper("genus", "genus"),
724
//	new CdmStringMapper("genusSubdivisionEpi", "genusSubdivisionEpi"),
725
//	new CdmStringMapper("speciesEpi", "speciesEpi"),
726
//	new CdmStringMapper("infraSpeciesEpi", "infraSpeciesEpi"),
727
//	new CdmStringMapper("authorTeamFk", "authorTeamFk"),
728
//	new CdmStringMapper("exAuthorTeamFk", "exAuthorTeamFk"),
729
//	new CdmStringMapper("basAuthorTeamFk", "basAuthorTeamFk"),
730
//	new CdmStringMapper("exBasAuthorTeamFk", "exBasAuthorTeamFk"),
731
//	new CdmStringMapper("hybridFormulaFlag", "hybridFormulaFlag"),
732
//	new CdmStringMapper("monomHybFlag", "monomHybFlag"),
733
//	new CdmStringMapper("binomHybFlag", "binomHybFlag"),
734
//	new CdmStringMapper("trinomHybFlag", "trinomHybFlag"),
735
//	new CdmStringMapper("cultivarGroupName", "cultivarGroupName"),
736
//	new CdmStringMapper("cultivarName", "cultivarName"),
737
//	new CdmStringMapper("nomRefFk", "nomRefFk"),
738
//	new CdmStringMapper("nomRefDetailFk", "nomRefDetailFk"),
739
//	new CdmStringMapper("nameSourceRefFk", "nameSourceRefFk"),
740
//	new CdmStringMapper("source_Acc", "source_Acc"),
741
//	new CdmStringMapper("created_When", "created_When"),
742
//	new CdmStringMapper("created_Who", "created_Who"),
743
//	new CdmStringMapper("notes", "notes"),
744
//	new CdmStringMapper("parsingComments", "parsingComments"),
745
//	new CdmStringMapper("oldNomRefFk", "oldNomRefFk"),
746
//	new CdmStringMapper("oldNomRefDetailFk", "oldNomRefDetailFk"),
747
//	new CdmStringMapper("updated_Who", "updated_Who"),
748
//	new CdmStringMapper("orthoProjection", "orthoProjection"),
749

    
750

    
751
}
(16-16/22)