2 * Copyright (C) 2007 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
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.
10 package eu
.etaxonomy
.cdm
.io
.berlinModel
.in
;
12 import java
.sql
.ResultSet
;
13 import java
.sql
.SQLException
;
14 import java
.util
.HashMap
;
15 import java
.util
.HashSet
;
18 import java
.util
.UUID
;
20 import org
.apache
.commons
.lang
.StringUtils
;
21 import org
.apache
.log4j
.Logger
;
22 import org
.springframework
.stereotype
.Component
;
24 import eu
.etaxonomy
.cdm
.common
.CdmUtils
;
25 import eu
.etaxonomy
.cdm
.database
.update
.DatabaseTypeNotSupportedException
;
26 import eu
.etaxonomy
.cdm
.io
.berlinModel
.BerlinModelTransformer
;
27 import eu
.etaxonomy
.cdm
.io
.berlinModel
.in
.validation
.BerlinModelTaxonNameImportValidator
;
28 import eu
.etaxonomy
.cdm
.io
.common
.IImportConfigurator
;
29 import eu
.etaxonomy
.cdm
.io
.common
.IOValidator
;
30 import eu
.etaxonomy
.cdm
.io
.common
.ImportHelper
;
31 import eu
.etaxonomy
.cdm
.io
.common
.ResultSetPartitioner
;
32 import eu
.etaxonomy
.cdm
.io
.common
.Source
;
33 import eu
.etaxonomy
.cdm
.model
.agent
.Person
;
34 import eu
.etaxonomy
.cdm
.model
.agent
.Team
;
35 import eu
.etaxonomy
.cdm
.model
.agent
.TeamOrPersonBase
;
36 import eu
.etaxonomy
.cdm
.model
.common
.CdmBase
;
37 import eu
.etaxonomy
.cdm
.model
.common
.Extension
;
38 import eu
.etaxonomy
.cdm
.model
.common
.ExtensionType
;
39 import eu
.etaxonomy
.cdm
.model
.common
.Language
;
40 import eu
.etaxonomy
.cdm
.model
.common
.Representation
;
41 import eu
.etaxonomy
.cdm
.model
.name
.BotanicalName
;
42 import eu
.etaxonomy
.cdm
.model
.name
.CultivarPlantName
;
43 import eu
.etaxonomy
.cdm
.model
.name
.NonViralName
;
44 import eu
.etaxonomy
.cdm
.model
.name
.Rank
;
45 import eu
.etaxonomy
.cdm
.model
.name
.TaxonNameBase
;
46 import eu
.etaxonomy
.cdm
.model
.name
.ZoologicalName
;
47 import eu
.etaxonomy
.cdm
.model
.reference
.INomenclaturalReference
;
48 import eu
.etaxonomy
.cdm
.model
.reference
.Reference
;
49 import eu
.etaxonomy
.cdm
.strategy
.exceptions
.UnknownCdmTypeException
;
57 public class BerlinModelTaxonNameImport
extends BerlinModelImportBase
{
58 private static final boolean BLANK_TO_NULL
= true;
60 private static final Logger logger
= Logger
.getLogger(BerlinModelTaxonNameImport
.class);
62 public static final String NAMESPACE
= "TaxonName";
64 public static final UUID SOURCE_ACC_UUID
= UUID
.fromString("c3959b4f-d876-4b7a-a739-9260f4cafd1c");
66 private static int modCount
= 5000;
67 private static final String pluralString
= "TaxonNames";
68 private static final String dbTableName
= "Name";
71 public BerlinModelTaxonNameImport(){
72 super(dbTableName
, pluralString
);
77 * @see eu.etaxonomy.cdm.io.berlinModel.in.BerlinModelImportBase#getIdQuery(eu.etaxonomy.cdm.io.berlinModel.in.BerlinModelImportState)
80 protected String
getIdQuery(BerlinModelImportState state
) {
81 if (state
.getConfig().getNameIdTable()==null ){
82 return super.getIdQuery(state
);
84 return "SELECT nameId FROM " + state
.getConfig().getNameIdTable() + "";
90 * @see eu.etaxonomy.cdm.io.berlinModel.in.BerlinModelImportBase#getRecordQuery()
93 protected String
getRecordQuery(BerlinModelImportConfigurator config
) {
94 Source source
= config
.getSource();
96 String facultativCols
= "";
97 String strFacTable
= "RefDetail";
98 String strFacColumn
= "IdInSource";
99 String strColAlias
= null;
100 if (checkSqlServerColumnExists(source
, strFacTable
, strFacColumn
)){
101 facultativCols
+= ", " + strFacTable
+ "." + strFacColumn
;
102 if (! CdmUtils
.Nz(strColAlias
).equals("") ){
103 facultativCols
+= " AS " + strColAlias
;
107 String strRecordQuery
=
108 "SELECT Name.* , RefDetail.RefDetailId, RefDetail.RefFk, " +
109 " RefDetail.FullRefCache, RefDetail.FullNomRefCache, RefDetail.PreliminaryFlag AS RefDetailPrelim, RefDetail.Details, " +
110 " RefDetail.SecondarySources, Rank.RankAbbrev, Rank.Rank " +
112 " FROM Name LEFT OUTER JOIN RefDetail ON Name.NomRefDetailFk = RefDetail.RefDetailId AND " +
113 " Name.NomRefFk = RefDetail.RefFk " +
114 " LEFT OUTER JOIN Rank ON Name.RankFk = Rank.rankID " +
115 " WHERE name.nameId IN ("+ID_LIST_TOKEN
+") ";
116 //strQuery += " AND RefDetail.PreliminaryFlag = 1 ";
117 //strQuery += " AND Name.Created_When > '03.03.2004' ";
118 return strRecordQuery
+ "";
124 protected void doInvoke(BerlinModelImportState state
) {
125 //update rank labels if necessary
126 String strAbbrev
= state
.getConfig().getInfrGenericRankAbbrev();
127 Rank rank
= Rank
.INFRAGENERICTAXON();
128 testRankAbbrev(strAbbrev
, rank
);
130 strAbbrev
= state
.getConfig().getInfrSpecificRankAbbrev();
131 rank
= Rank
.INFRASPECIFICTAXON();
132 testRankAbbrev(strAbbrev
, rank
);
134 super.doInvoke(state
);
137 private void testRankAbbrev(String strAbbrev
, Rank rank
) {
138 if (strAbbrev
!= null){
139 Representation rep
= rank
.getRepresentation(Language
.ENGLISH());
140 rep
.setAbbreviatedLabel(strAbbrev
);
141 getTermService().saveOrUpdate(rank
);
147 * @see eu.etaxonomy.cdm.io.berlinModel.in.IPartitionedIO#doPartition(eu.etaxonomy.cdm.io.berlinModel.in.ResultSetPartitioner, eu.etaxonomy.cdm.io.berlinModel.in.BerlinModelImportState)
149 public boolean doPartition(ResultSetPartitioner partitioner
, BerlinModelImportState state
) {
152 boolean success
= true ;
153 BerlinModelImportConfigurator config
= state
.getConfig();
154 Set
<TaxonNameBase
> namesToSave
= new HashSet
<TaxonNameBase
>();
155 Map
<String
, Team
> teamMap
= (Map
<String
, Team
>) partitioner
.getObjectMap(BerlinModelAuthorTeamImport
.NAMESPACE
);
157 ResultSet rs
= partitioner
.getResultSet();
164 if ((i
++ % modCount
) == 0 && i
!= 1 ){ logger
.info("Names handled: " + (i
-1));}
166 //create TaxonName element
167 int nameId
= rs
.getInt("nameId");
168 Object authorFk
= rs
.getObject("AuthorTeamFk");
169 Object exAuthorFk
= rs
.getObject("ExAuthorTeamFk");
170 Object basAuthorFk
= rs
.getObject("BasAuthorTeamFk");
171 Object exBasAuthorFk
= rs
.getObject("ExBasAuthorTeamFk");
172 String strCultivarGroupName
= rs
.getString("CultivarGroupName");
173 String strCultivarName
= rs
.getString("CultivarName");
174 String nameCache
= rs
.getString("NameCache");
175 String fullNameCache
= rs
.getString("FullNameCache");
180 boolean useUnknownRank
= true;
181 Rank rank
= BerlinModelTransformer
.rankId2Rank(rs
, useUnknownRank
, config
.isSwitchSpeciesGroup());
183 boolean allowInfraSpecTaxonRank
= state
.getConfig().isAllowInfraSpecTaxonRank() ;
184 if (rank
== null || rank
.equals(Rank
.UNKNOWN_RANK()) || (rank
.equals(Rank
.INFRASPECIFICTAXON()) && ! allowInfraSpecTaxonRank
)){
185 rank
= handleProlesAndRaceSublusus(state
, rs
, rank
);
188 if (rank
.getId() == 0){
189 getTermService().save(rank
);
190 logger
.warn("Rank did not yet exist: " + rank
.getTitleCache());
193 //create TaxonNameBase
194 TaxonNameBase
<?
,?
> taxonNameBase
;
195 if (config
.getNomenclaturalCode() != null){
196 taxonNameBase
= config
.getNomenclaturalCode().getNewTaxonNameInstance(rank
);
198 if (taxonNameBase
instanceof BotanicalName
){
199 if (isNotBlank(strCultivarGroupName
) && isNotBlank(strCultivarName
)){
200 taxonNameBase
= CultivarPlantName
.NewInstance(rank
);
204 taxonNameBase
= NonViralName
.NewInstance(rank
);
208 //TODO rank should never be null or a more sophisticated algorithm has to be implemented for genus/supraGenericName
209 logger
.warn("Rank is null. Genus epethiton was imported. May be wrong");
214 if (rank
!= null && rank
.isSupraGeneric()){
215 dbAttrName
= "supraGenericName";
217 dbAttrName
= "genus";
219 cdmAttrName
= "genusOrUninomial";
220 success
&= ImportHelper
.addStringValue(rs
, taxonNameBase
, dbAttrName
, cdmAttrName
, BLANK_TO_NULL
);
222 dbAttrName
= "genusSubdivisionEpi";
223 cdmAttrName
= "infraGenericEpithet";
224 success
&= ImportHelper
.addStringValue(rs
, taxonNameBase
, dbAttrName
, cdmAttrName
, BLANK_TO_NULL
);
226 dbAttrName
= "speciesEpi";
227 cdmAttrName
= "specificEpithet";
228 success
&= ImportHelper
.addStringValue(rs
, taxonNameBase
, dbAttrName
, cdmAttrName
, BLANK_TO_NULL
);
231 dbAttrName
= "infraSpeciesEpi";
232 cdmAttrName
= "infraSpecificEpithet";
233 success
&= ImportHelper
.addStringValue(rs
, taxonNameBase
, dbAttrName
, cdmAttrName
, BLANK_TO_NULL
);
235 dbAttrName
= "unnamedNamePhrase";
236 cdmAttrName
= "appendedPhrase";
237 success
&= ImportHelper
.addStringValue(rs
, taxonNameBase
, dbAttrName
, cdmAttrName
, BLANK_TO_NULL
);
240 dbAttrName
= "details";
241 cdmAttrName
= "nomenclaturalMicroReference";
242 success
&= ImportHelper
.addStringValue(rs
, taxonNameBase
, dbAttrName
, cdmAttrName
, BLANK_TO_NULL
);
245 success
&= makeNomenclaturalReference(config
, taxonNameBase
, nameId
, rs
, partitioner
);
248 boolean colExists
= true;
250 colExists
= state
.getConfig().getSource().checkColumnExists("Name", "Source_Acc");
251 } catch (DatabaseTypeNotSupportedException e
) {
252 logger
.debug("Source does not support 'checkColumnExists'");
255 String sourceAcc
= rs
.getString("Source_Acc");
256 if (StringUtils
.isNotBlank(sourceAcc
)){
257 ExtensionType sourceAccExtensionType
= getExtensionType(state
, SOURCE_ACC_UUID
, "Source_Acc","Source_Acc","Source_Acc");
258 Extension datesExtension
= Extension
.NewInstance(taxonNameBase
, sourceAcc
, sourceAccExtensionType
);
263 boolean excludeUpdated
= true;
264 success
&= doIdCreatedUpdatedNotes(state
, taxonNameBase
, rs
, nameId
, NAMESPACE
, excludeUpdated
, false);
267 if (taxonNameBase
instanceof NonViralName
){
268 NonViralName
<?
> nonViralName
= (NonViralName
<?
>)taxonNameBase
;
271 if (teamMap
!= null ){
272 nonViralName
.setCombinationAuthorTeam(getAuthorTeam(teamMap
, authorFk
, nameId
, config
));
273 nonViralName
.setExCombinationAuthorTeam(getAuthorTeam(teamMap
, exAuthorFk
, nameId
, config
));
274 nonViralName
.setBasionymAuthorTeam(getAuthorTeam(teamMap
, basAuthorFk
, nameId
, config
));
275 nonViralName
.setExBasionymAuthorTeam(getAuthorTeam(teamMap
, exBasAuthorFk
, nameId
, config
));
277 logger
.warn("TeamMap is null");
285 if (taxonNameBase
instanceof ZoologicalName
){
286 ZoologicalName zooName
= (ZoologicalName
)taxonNameBase
;
287 makeZoologialName(rs
, zooName
, nameId
);
290 else if (taxonNameBase
instanceof BotanicalName
){
291 BotanicalName botName
= (BotanicalName
)taxonNameBase
;
292 success
&= makeBotanicalNamePart(rs
, botName
) ;
296 // dbAttrName = "preliminaryFlag";
297 Boolean preliminaryFlag
= rs
.getBoolean("PreliminaryFlag");
298 Boolean hybridFormulaFlag
= rs
.getBoolean("HybridFormulaFlag"); //hybrid flag does not lead to cache update in Berlin Model
299 if (preliminaryFlag
== true || hybridFormulaFlag
== true){
300 //Computes all caches and sets
301 taxonNameBase
.setTitleCache(fullNameCache
, true);
302 taxonNameBase
.setFullTitleCache(taxonNameBase
.getFullTitleCache(), true);
303 if (taxonNameBase
instanceof NonViralName
){
304 NonViralName
<?
> nvn
= (NonViralName
<?
>)taxonNameBase
;
305 nvn
.setNameCache(nameCache
, true);
306 nvn
.setAuthorshipCache(nvn
.getAuthorshipCache(), true);
309 namesToSave
.add(taxonNameBase
);
312 catch (UnknownCdmTypeException e
) {
313 logger
.warn("Name with id " + nameId
+ " has unknown rankId " + " and could not be saved.");
317 } //while rs.hasNext()
318 } catch (SQLException e
) {
319 logger
.error("SQLException:" + e
);
324 // logger.info( i + " names handled");
325 getNameService().save(namesToSave
);
330 private Rank
handleProlesAndRaceSublusus(BerlinModelImportState state
, ResultSet rs
, Rank rank
) throws SQLException
{
332 String rankAbbrev
= rs
.getString("RankAbbrev");
333 // String rankStr = rs.getString("Rank");
334 if (CdmUtils
.nullSafeEqual(rankAbbrev
, "prol.") ){
335 result
= Rank
.PROLES();
336 }else if(CdmUtils
.nullSafeEqual(rankAbbrev
, "race")){
337 result
= Rank
.RACE();
338 }else if(CdmUtils
.nullSafeEqual(rankAbbrev
, "sublusus")){
339 result
= Rank
.SUBLUSUS();
342 logger
.warn("Unhandled rank: " + rankAbbrev
);
347 public Map
<Object
, Map
<String
, ?
extends CdmBase
>> getRelatedObjectsForPartition(ResultSet rs
, BerlinModelImportState state
) {
352 Map
<Object
, Map
<String
, ?
extends CdmBase
>> result
= new HashMap
<Object
, Map
<String
, ?
extends CdmBase
>>();
355 Set
<String
> teamIdSet
= new HashSet
<String
>();
356 Set
<String
> referenceIdSet
= new HashSet
<String
>();
357 Set
<String
> refDetailIdSet
= new HashSet
<String
>();
359 handleForeignKey(rs
, teamIdSet
, "AuthorTeamFk");
360 handleForeignKey(rs
, teamIdSet
, "ExAuthorTeamFk");
361 handleForeignKey(rs
, teamIdSet
, "BasAuthorTeamFk");
362 handleForeignKey(rs
, teamIdSet
, "ExBasAuthorTeamFk");
363 handleForeignKey(rs
, referenceIdSet
, "nomRefFk");
364 handleForeignKey(rs
, refDetailIdSet
, "nomRefDetailFk");
368 nameSpace
= BerlinModelAuthorTeamImport
.NAMESPACE
;
369 cdmClass
= Team
.class;
371 Map
<String
, Person
> teamMap
= (Map
<String
, Person
>)getCommonService().getSourcedObjectsByIdInSource(cdmClass
, idSet
, nameSpace
);
372 result
.put(nameSpace
, teamMap
);
375 nameSpace
= BerlinModelReferenceImport
.REFERENCE_NAMESPACE
;
376 cdmClass
= Reference
.class;
377 idSet
= referenceIdSet
;
378 Map
<String
, Reference
> referenceMap
= (Map
<String
, Reference
>)getCommonService().getSourcedObjectsByIdInSource(cdmClass
, idSet
, nameSpace
);
379 result
.put(nameSpace
, referenceMap
);
382 nameSpace
= BerlinModelRefDetailImport
.REFDETAIL_NAMESPACE
;
383 cdmClass
= Reference
.class;
384 idSet
= refDetailIdSet
;
385 Map
<String
, Reference
> refDetailMap
= (Map
<String
, Reference
>)getCommonService().getSourcedObjectsByIdInSource(cdmClass
, idSet
, nameSpace
);
386 result
.put(nameSpace
, refDetailMap
);
388 } catch (SQLException e
) {
389 throw new RuntimeException(e
);
394 private boolean makeZoologialName(ResultSet rs
, ZoologicalName zooName
, int nameId
)
396 boolean success
= true;
398 String authorTeamYear
= rs
.getString("authorTeamYear");
400 if (! "".equals(CdmUtils
.Nz(authorTeamYear
).trim())){
401 Integer publicationYear
= Integer
.valueOf(authorTeamYear
.trim());
402 zooName
.setPublicationYear(publicationYear
);
404 } catch (NumberFormatException e
) {
405 logger
.warn("authorTeamYear could not be parsed for taxonName: "+ nameId
);
407 //original publication year
408 String basAuthorTeamYear
= rs
.getString("basAuthorTeamYear");
410 if (! "".equals(CdmUtils
.Nz(basAuthorTeamYear
).trim())){
411 Integer OriginalPublicationYear
= Integer
.valueOf(basAuthorTeamYear
.trim());
412 zooName
.setOriginalPublicationYear(OriginalPublicationYear
);
414 } catch (NumberFormatException e
) {
415 logger
.warn("basAuthorTeamYear could not be parsed for taxonName: "+ nameId
);
420 private boolean makeBotanicalNamePart(ResultSet rs
, BotanicalName botanicalName
)throws SQLException
{
421 boolean success
= true;
425 dbAttrName
= "HybridFormulaFlag";
426 cdmAttrName
= "isHybridFormula";
427 success
&= ImportHelper
.addBooleanValue(rs
, botanicalName
, dbAttrName
, cdmAttrName
);
429 dbAttrName
= "MonomHybFlag";
430 cdmAttrName
= "isMonomHybrid";
431 success
&= ImportHelper
.addBooleanValue(rs
, botanicalName
, dbAttrName
, cdmAttrName
);
433 dbAttrName
= "BinomHybFlag";
434 cdmAttrName
= "isBinomHybrid";
435 success
&= ImportHelper
.addBooleanValue(rs
, botanicalName
, dbAttrName
, cdmAttrName
);
437 dbAttrName
= "TrinomHybFlag";
438 cdmAttrName
= "isTrinomHybrid";
439 success
&= ImportHelper
.addBooleanValue(rs
, botanicalName
, dbAttrName
, cdmAttrName
);
442 String strCultivarGroupName
= rs
.getString("CultivarGroupName");
443 String strCultivarName
= rs
.getString("CultivarName");
444 if (botanicalName
instanceof CultivarPlantName
){
445 CultivarPlantName cultivarName
= (CultivarPlantName
)botanicalName
;
446 String concatCultivarName
= CdmUtils
.concat("-", strCultivarName
, strCultivarGroupName
);
447 if (CdmUtils
.isNotEmpty(strCultivarGroupName
) && CdmUtils
.isNotEmpty(strCultivarName
)){
448 logger
.warn("CDM does not support cultivarGroupName and CultivarName together: " + concatCultivarName
);
450 cultivarName
.setCultivarName(strCultivarGroupName
);
452 } catch (SQLException e
) {
459 private boolean makeNomenclaturalReference(IImportConfigurator config
, TaxonNameBase taxonNameBase
,
460 int nameId
, ResultSet rs
, ResultSetPartitioner partitioner
) throws SQLException
{
461 Map
<String
, Reference
> refMap
= partitioner
.getObjectMap(BerlinModelReferenceImport
.REFERENCE_NAMESPACE
);
462 Map
<String
, Reference
> refDetailMap
= partitioner
.getObjectMap(BerlinModelRefDetailImport
.REFDETAIL_NAMESPACE
);
464 Object nomRefFkObj
= rs
.getObject("NomRefFk");
465 Object nomRefDetailFkObj
= rs
.getObject("NomRefDetailFk");
466 boolean refDetailPrelim
= rs
.getBoolean("RefDetailPrelim");
468 boolean success
= true;
469 //nomenclatural Reference
471 if (nomRefFkObj
!= null){
472 String nomRefFk
= String
.valueOf(nomRefFkObj
);
473 String nomRefDetailFk
= String
.valueOf(nomRefDetailFkObj
);
475 Reference
<?
> nomReference
=
476 getReferenceFromMaps(refDetailMap
, refMap
, nomRefDetailFk
, nomRefFk
);
480 if (nomReference
== null ){
482 if (! config
.isIgnoreNull()){
483 logger
.warn("Nomenclatural reference (nomRefFk = " + nomRefFk
+ ") for TaxonName (nameId = " + nameId
+ ")"+
484 " was not found in reference store. Nomenclatural reference was not set!!");
487 if (! INomenclaturalReference
.class.isAssignableFrom(nomReference
.getClass())){
488 logger
.warn("Nomenclatural reference (nomRefFk = " + nomRefFk
+ ") for TaxonName (nameId = " + nameId
+ ")"+
489 " is not assignable from INomenclaturalReference. (Class = " + nomReference
.getClass()+ ")");
491 nomReference
.setNomenclaturallyRelevant(true);
492 taxonNameBase
.setNomenclaturalReference(nomReference
);
499 private static TeamOrPersonBase
getAuthorTeam(Map
<String
, Team
> teamMap
, Object teamIdObject
, int nameId
, BerlinModelImportConfigurator bmiConfig
){
500 if (teamIdObject
== null){
503 String teamId
= String
.valueOf(teamIdObject
);
504 TeamOrPersonBase author
= teamMap
.get(teamId
);
507 if (!bmiConfig
.isIgnoreNull() && ! (teamId
.equals(0) && bmiConfig
.isIgnore0AuthorTeam()) ){
508 logger
.warn("AuthorTeam (teamId = " + teamId
+ ") for TaxonName (nameId = " + nameId
+ ")"+
509 " was not found in authorTeam store. Relation was not set!!");}
518 * @see eu.etaxonomy.cdm.io.common.CdmIoBase#doCheck(eu.etaxonomy.cdm.io.common.IImportConfigurator)
521 protected boolean doCheck(BerlinModelImportState state
){
522 IOValidator
<BerlinModelImportState
> validator
= new BerlinModelTaxonNameImportValidator();
523 return validator
.validate(state
);
527 * @see eu.etaxonomy.cdm.io.common.CdmIoBase#isIgnore(eu.etaxonomy.cdm.io.common.IImportConfigurator)
529 protected boolean isIgnore(BerlinModelImportState state
){
530 return ! state
.getConfig().isDoTaxonNames();
538 //FOR FUTURE USE , DONT DELETE
539 // new CdmStringMapper("nameId", "nameId"),
540 // new CdmStringMapper("rankFk", "rankFk"),
541 // new CdmStringMapper("nameCache", "nameCache"),
542 // new CdmStringMapper("unnamedNamePhrase", "unnamedNamePhrase"),
543 // new CdmStringMapper("fullNameCache", "fullNameCache"),
544 // new CdmStringMapper("preliminaryFlag", "preliminaryFlag"),
545 // new CdmStringMapper("supragenericName", "supragenericName"),
546 // new CdmStringMapper("genus", "genus"),
547 // new CdmStringMapper("genusSubdivisionEpi", "genusSubdivisionEpi"),
548 // new CdmStringMapper("speciesEpi", "speciesEpi"),
549 // new CdmStringMapper("infraSpeciesEpi", "infraSpeciesEpi"),
550 // new CdmStringMapper("authorTeamFk", "authorTeamFk"),
551 // new CdmStringMapper("exAuthorTeamFk", "exAuthorTeamFk"),
552 // new CdmStringMapper("basAuthorTeamFk", "basAuthorTeamFk"),
553 // new CdmStringMapper("exBasAuthorTeamFk", "exBasAuthorTeamFk"),
554 // new CdmStringMapper("hybridFormulaFlag", "hybridFormulaFlag"),
555 // new CdmStringMapper("monomHybFlag", "monomHybFlag"),
556 // new CdmStringMapper("binomHybFlag", "binomHybFlag"),
557 // new CdmStringMapper("trinomHybFlag", "trinomHybFlag"),
558 // new CdmStringMapper("cultivarGroupName", "cultivarGroupName"),
559 // new CdmStringMapper("cultivarName", "cultivarName"),
560 // new CdmStringMapper("nomRefFk", "nomRefFk"),
561 // new CdmStringMapper("nomRefDetailFk", "nomRefDetailFk"),
562 // new CdmStringMapper("nameSourceRefFk", "nameSourceRefFk"),
563 // new CdmStringMapper("source_Acc", "source_Acc"),
564 // new CdmStringMapper("created_When", "created_When"),
565 // new CdmStringMapper("created_Who", "created_Who"),
566 // new CdmStringMapper("notes", "notes"),
567 // new CdmStringMapper("parsingComments", "parsingComments"),
568 // new CdmStringMapper("oldNomRefFk", "oldNomRefFk"),
569 // new CdmStringMapper("oldNomRefDetailFk", "oldNomRefDetailFk"),
570 // new CdmStringMapper("updated_Who", "updated_Who"),
571 // new CdmStringMapper("orthoProjection", "orthoProjection"),